1111#include "smb2proto.h"
1212#include "cached_dir.h"
1313
14+ struct cached_fid * init_cached_dir (const char * path );
15+
1416/*
1517 * Open the and cache a directory handle.
1618 * If error then *cfid is not initialized.
@@ -52,7 +54,14 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
5254 else
5355 return - ENOENT ;
5456
55- cfid = & tcon -> cfids -> cfid ;
57+ cfid = tcon -> cfids -> cfid ;
58+ if (cfid == NULL ) {
59+ cfid = init_cached_dir (path );
60+ tcon -> cfids -> cfid = cfid ;
61+ }
62+ if (cfid == NULL )
63+ return - ENOMEM ;
64+
5665 mutex_lock (& cfid -> fid_mutex );
5766 if (cfid -> is_valid ) {
5867 cifs_dbg (FYI , "found a cached root file handle\n" );
@@ -227,7 +236,9 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
227236{
228237 struct cached_fid * cfid ;
229238
230- cfid = & tcon -> cfids -> cfid ;
239+ cfid = tcon -> cfids -> cfid ;
240+ if (cfid == NULL )
241+ return - ENOENT ;
231242
232243 mutex_lock (& cfid -> fid_mutex );
233244 if (cfid -> dentry == dentry ) {
@@ -321,7 +332,9 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
321332 tcon = tlink_tcon (tlink );
322333 if (IS_ERR (tcon ))
323334 continue ;
324- cfid = & tcon -> cfids -> cfid ;
335+ cfid = tcon -> cfids -> cfid ;
336+ if (cfid == NULL )
337+ continue ;
325338 mutex_lock (& cfid -> fid_mutex );
326339 if (cfid -> dentry ) {
327340 dput (cfid -> dentry );
@@ -337,7 +350,10 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
337350 */
338351void invalidate_all_cached_dirs (struct cifs_tcon * tcon )
339352{
340- struct cached_fid * cfid = & tcon -> cfids -> cfid ;
353+ struct cached_fid * cfid = tcon -> cfids -> cfid ;
354+
355+ if (cfid == NULL )
356+ return ;
341357
342358 mutex_lock (& cfid -> fid_mutex );
343359 cfid -> is_valid = false;
@@ -358,7 +374,10 @@ smb2_cached_lease_break(struct work_struct *work)
358374
359375int cached_dir_lease_break (struct cifs_tcon * tcon , __u8 lease_key [16 ])
360376{
361- struct cached_fid * cfid = & tcon -> cfids -> cfid ;
377+ struct cached_fid * cfid = tcon -> cfids -> cfid ;
378+
379+ if (cfid == NULL )
380+ return false;
362381
363382 if (cfid -> is_valid &&
364383 !memcmp (lease_key ,
@@ -374,20 +393,48 @@ int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
374393 return false;
375394}
376395
396+ struct cached_fid * init_cached_dir (const char * path )
397+ {
398+ struct cached_fid * cfid ;
399+
400+ cfid = kzalloc (sizeof (* cfid ), GFP_KERNEL );
401+ if (!cfid )
402+ return NULL ;
403+ cfid -> path = kstrdup (path , GFP_KERNEL );
404+ if (!cfid -> path ) {
405+ kfree (cfid );
406+ return NULL ;
407+ }
408+
409+ INIT_LIST_HEAD (& cfid -> dirents .entries );
410+ mutex_init (& cfid -> dirents .de_mutex );
411+ mutex_init (& cfid -> fid_mutex );
412+ return cfid ;
413+ }
414+
415+ void free_cached_dir (struct cached_fid * cfid )
416+ {
417+ kfree (cfid -> path );
418+ cfid -> path = NULL ;
419+ kfree (cfid );
420+ }
421+
377422struct cached_fids * init_cached_dirs (void )
378423{
379424 struct cached_fids * cfids ;
380425
381426 cfids = kzalloc (sizeof (* cfids ), GFP_KERNEL );
382427 if (!cfids )
383428 return NULL ;
384- INIT_LIST_HEAD (& cfids -> cfid .dirents .entries );
385- mutex_init (& cfids -> cfid .dirents .de_mutex );
386- mutex_init (& cfids -> cfid .fid_mutex );
429+ mutex_init (& cfids -> cfid_list_mutex );
387430 return cfids ;
388431}
389432
390433void free_cached_dirs (struct cached_fids * cfids )
391434{
435+ if (cfids -> cfid ) {
436+ free_cached_dir (cfids -> cfid );
437+ cfids -> cfid = NULL ;
438+ }
392439 kfree (cfids );
393440}
0 commit comments