@@ -3,9 +3,11 @@ package smb
33import (
44 "context"
55 "errors"
6+ "net"
67 "path"
78 "path/filepath"
89 "strings"
10+ "sync"
911
1012 "github.com/OpenListTeam/OpenList/v4/internal/driver"
1113 "github.com/OpenListTeam/OpenList/v4/internal/model"
@@ -19,7 +21,11 @@ type SMB struct {
1921 lastConnTime int64
2022 model.Storage
2123 Addition
22- fs * smb2.Share
24+ connMu sync.Mutex
25+ activeOps int
26+ conn net.Conn
27+ session * smb2.Session
28+ fs * smb2.Share
2329}
2430
2531func (d * SMB ) Config () driver.Config {
@@ -38,18 +44,17 @@ func (d *SMB) Init(ctx context.Context) error {
3844}
3945
4046func (d * SMB ) Drop (ctx context.Context ) error {
41- if d .fs != nil {
42- _ = d .fs .Umount ()
43- }
44- return nil
47+ return d .closeFS ()
4548}
4649
4750func (d * SMB ) List (ctx context.Context , dir model.Obj , args model.ListArgs ) ([]model.Obj , error ) {
48- if err := d .checkConn (ctx ); err != nil {
51+ fs , release , err := d .acquireConn (ctx )
52+ if err != nil {
4953 return nil , err
5054 }
55+ defer release ()
5156 fullPath := dir .GetPath ()
52- rawFiles , err := d . fs .ReadDir (fullPath )
57+ rawFiles , err := fs .ReadDir (fullPath )
5358 if err != nil {
5459 d .cleanLastConnTime ()
5560 return nil , err
@@ -72,11 +77,18 @@ func (d *SMB) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]m
7277}
7378
7479func (d * SMB ) Link (ctx context.Context , file model.Obj , args model.LinkArgs ) (* model.Link , error ) {
75- if err := d .checkConn (ctx ); err != nil {
80+ fs , release , err := d .acquireConn (ctx )
81+ if err != nil {
7682 return nil , err
7783 }
84+ needRelease := true
85+ defer func () {
86+ if needRelease {
87+ release ()
88+ }
89+ }()
7890 fullPath := file .GetPath ()
79- remoteFile , err := d . fs .Open (fullPath )
91+ remoteFile , err := fs .Open (fullPath )
8092 if err != nil {
8193 d .cleanLastConnTime ()
8294 return nil , err
@@ -87,19 +99,25 @@ func (d *SMB) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*m
8799 Limiter : stream .ServerDownloadLimit ,
88100 Ctx : ctx ,
89101 }
102+ needRelease = false
90103 return & model.Link {
91- RangeReader : stream .GetRangeReaderFromMFile (file .GetSize (), mFile ),
92- SyncClosers : utils .NewSyncClosers (remoteFile ),
104+ RangeReader : stream .GetRangeReaderFromMFile (file .GetSize (), mFile ),
105+ SyncClosers : utils .NewSyncClosers (remoteFile , utils .CloseFunc (func () error {
106+ release ()
107+ return nil
108+ })),
93109 RequireReference : true ,
94110 }, nil
95111}
96112
97113func (d * SMB ) MakeDir (ctx context.Context , parentDir model.Obj , dirName string ) error {
98- if err := d .checkConn (ctx ); err != nil {
114+ fs , release , err := d .acquireConn (ctx )
115+ if err != nil {
99116 return err
100117 }
118+ defer release ()
101119 fullPath := filepath .Join (parentDir .GetPath (), dirName )
102- err := d . fs .MkdirAll (fullPath , 0700 )
120+ err = fs .MkdirAll (fullPath , 0700 )
103121 if err != nil {
104122 d .cleanLastConnTime ()
105123 return err
@@ -109,12 +127,14 @@ func (d *SMB) MakeDir(ctx context.Context, parentDir model.Obj, dirName string)
109127}
110128
111129func (d * SMB ) Move (ctx context.Context , srcObj , dstDir model.Obj ) error {
112- if err := d .checkConn (ctx ); err != nil {
130+ fs , release , err := d .acquireConn (ctx )
131+ if err != nil {
113132 return err
114133 }
134+ defer release ()
115135 srcPath := srcObj .GetPath ()
116136 dstPath := filepath .Join (dstDir .GetPath (), srcObj .GetName ())
117- err := d . fs .Rename (srcPath , dstPath )
137+ err = fs .Rename (srcPath , dstPath )
118138 if err != nil {
119139 d .cleanLastConnTime ()
120140 return err
@@ -124,12 +144,14 @@ func (d *SMB) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
124144}
125145
126146func (d * SMB ) Rename (ctx context.Context , srcObj model.Obj , newName string ) error {
127- if err := d .checkConn (ctx ); err != nil {
147+ fs , release , err := d .acquireConn (ctx )
148+ if err != nil {
128149 return err
129150 }
151+ defer release ()
130152 srcPath := srcObj .GetPath ()
131153 dstPath := filepath .Join (filepath .Dir (srcPath ), newName )
132- err := d . fs .Rename (srcPath , dstPath )
154+ err = fs .Rename (srcPath , dstPath )
133155 if err != nil {
134156 d .cleanLastConnTime ()
135157 return err
@@ -139,12 +161,13 @@ func (d *SMB) Rename(ctx context.Context, srcObj model.Obj, newName string) erro
139161}
140162
141163func (d * SMB ) Copy (ctx context.Context , srcObj , dstDir model.Obj ) error {
142- if err := d .checkConn (ctx ); err != nil {
164+ _ , release , err := d .acquireConn (ctx )
165+ if err != nil {
143166 return err
144167 }
168+ defer release ()
145169 srcPath := srcObj .GetPath ()
146170 dstPath := filepath .Join (dstDir .GetPath (), srcObj .GetName ())
147- var err error
148171 if srcObj .IsDir () {
149172 err = d .CopyDir (srcPath , dstPath )
150173 } else {
@@ -159,15 +182,16 @@ func (d *SMB) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
159182}
160183
161184func (d * SMB ) Remove (ctx context.Context , obj model.Obj ) error {
162- if err := d .checkConn (ctx ); err != nil {
185+ fs , release , err := d .acquireConn (ctx )
186+ if err != nil {
163187 return err
164188 }
165- var err error
189+ defer release ()
166190 fullPath := obj .GetPath ()
167191 if obj .IsDir () {
168- err = d . fs .RemoveAll (fullPath )
192+ err = fs .RemoveAll (fullPath )
169193 } else {
170- err = d . fs .Remove (fullPath )
194+ err = fs .Remove (fullPath )
171195 }
172196 if err != nil {
173197 d .cleanLastConnTime ()
@@ -178,11 +202,13 @@ func (d *SMB) Remove(ctx context.Context, obj model.Obj) error {
178202}
179203
180204func (d * SMB ) Put (ctx context.Context , dstDir model.Obj , stream model.FileStreamer , up driver.UpdateProgress ) error {
181- if err := d .checkConn (ctx ); err != nil {
205+ fs , release , err := d .acquireConn (ctx )
206+ if err != nil {
182207 return err
183208 }
209+ defer release ()
184210 fullPath := filepath .Join (dstDir .GetPath (), stream .GetName ())
185- out , err := d . fs .Create (fullPath )
211+ out , err := fs .Create (fullPath )
186212 if err != nil {
187213 d .cleanLastConnTime ()
188214 return err
@@ -191,7 +217,7 @@ func (d *SMB) Put(ctx context.Context, dstDir model.Obj, stream model.FileStream
191217 defer func () {
192218 _ = out .Close ()
193219 if errors .Is (err , context .Canceled ) {
194- _ = d . fs .Remove (fullPath )
220+ _ = fs .Remove (fullPath )
195221 }
196222 }()
197223 err = utils .CopyWithCtx (ctx , out , driver .NewLimitedUploadStream (ctx , stream ), stream .GetSize (), up )
@@ -202,13 +228,16 @@ func (d *SMB) Put(ctx context.Context, dstDir model.Obj, stream model.FileStream
202228}
203229
204230func (d * SMB ) GetDetails (ctx context.Context ) (* model.StorageDetails , error ) {
205- if err := d .checkConn (ctx ); err != nil {
231+ fs , release , err := d .acquireConn (ctx )
232+ if err != nil {
206233 return nil , err
207234 }
208- stat , err := d .fs .Statfs (d .RootFolderPath )
235+ defer release ()
236+ stat , err := fs .Statfs (d .RootFolderPath )
209237 if err != nil {
210238 return nil , err
211239 }
240+ d .updateLastConnTime ()
212241 total := int64 (stat .BlockSize () * stat .TotalBlockCount ())
213242 free := int64 (stat .BlockSize () * stat .AvailableBlockCount ())
214243 return & model.StorageDetails {
0 commit comments