1818int open_cached_dir (unsigned int xid , struct cifs_tcon * tcon ,
1919 const char * path ,
2020 struct cifs_sb_info * cifs_sb ,
21- struct cached_fid * * cfid )
21+ struct cached_fid * * ret_cfid )
2222{
2323 struct cifs_ses * ses ;
2424 struct TCP_Server_Info * server ;
@@ -35,6 +35,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
3535 u8 oplock = SMB2_OPLOCK_LEVEL_II ;
3636 struct cifs_fid * pfid ;
3737 struct dentry * dentry ;
38+ struct cached_fid * cfid ;
3839
3940 if (tcon == NULL || tcon -> nohandlecache ||
4041 is_smb1_server (tcon -> ses -> server ))
@@ -51,12 +52,13 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
5152
5253 dentry = cifs_sb -> root ;
5354
54- mutex_lock (& tcon -> cfid .fid_mutex );
55- if (tcon -> cfid .is_valid ) {
55+ cfid = tcon -> cfid ;
56+ mutex_lock (& cfid -> fid_mutex );
57+ if (cfid -> is_valid ) {
5658 cifs_dbg (FYI , "found a cached root file handle\n" );
57- * cfid = & tcon -> cfid ;
58- kref_get (& tcon -> cfid . refcount );
59- mutex_unlock (& tcon -> cfid . fid_mutex );
59+ * ret_cfid = cfid ;
60+ kref_get (& cfid -> refcount );
61+ mutex_unlock (& cfid -> fid_mutex );
6062 return 0 ;
6163 }
6264
@@ -67,15 +69,15 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
6769 * thus causing a deadlock
6870 */
6971
70- mutex_unlock (& tcon -> cfid . fid_mutex );
72+ mutex_unlock (& cfid -> fid_mutex );
7173
7274 if (smb3_encryption_required (tcon ))
7375 flags |= CIFS_TRANSFORM_REQ ;
7476
7577 if (!server -> ops -> new_lease_key )
7678 return - EIO ;
7779
78- pfid = tcon -> cfid . fid ;
80+ pfid = & cfid -> fid ;
7981 server -> ops -> new_lease_key (pfid );
8082
8183 memset (rqst , 0 , sizeof (rqst ));
@@ -118,14 +120,14 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
118120 rc = compound_send_recv (xid , ses , server ,
119121 flags , 2 , rqst ,
120122 resp_buftype , rsp_iov );
121- mutex_lock (& tcon -> cfid . fid_mutex );
123+ mutex_lock (& cfid -> fid_mutex );
122124
123125 /*
124126 * Now we need to check again as the cached root might have
125127 * been successfully re-opened from a concurrent process
126128 */
127129
128- if (tcon -> cfid . is_valid ) {
130+ if (cfid -> is_valid ) {
129131 /* work was already done */
130132
131133 /* stash fids for close() later */
@@ -138,9 +140,9 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
138140 * caller expects this func to set the fid in cfid to valid
139141 * cached root, so increment the refcount.
140142 */
141- kref_get (& tcon -> cfid . refcount );
143+ kref_get (& cfid -> refcount );
142144
143- mutex_unlock (& tcon -> cfid . fid_mutex );
145+ mutex_unlock (& cfid -> fid_mutex );
144146
145147 if (rc == 0 ) {
146148 /* close extra handle outside of crit sec */
@@ -170,20 +172,20 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
170172 oparms .fid -> mid = le64_to_cpu (o_rsp -> hdr .MessageId );
171173#endif /* CIFS_DEBUG2 */
172174
173- tcon -> cfid . tcon = tcon ;
174- tcon -> cfid . is_valid = true;
175- tcon -> cfid . dentry = dentry ;
175+ cfid -> tcon = tcon ;
176+ cfid -> is_valid = true;
177+ cfid -> dentry = dentry ;
176178 dget (dentry );
177- kref_init (& tcon -> cfid . refcount );
179+ kref_init (& cfid -> refcount );
178180
179181 /* BB TBD check to see if oplock level check can be removed below */
180182 if (o_rsp -> OplockLevel == SMB2_OPLOCK_LEVEL_LEASE ) {
181183 /*
182184 * See commit 2f94a3125b87. Increment the refcount when we
183185 * get a lease for root, release it if lease break occurs
184186 */
185- kref_get (& tcon -> cfid . refcount );
186- tcon -> cfid . has_lease = true;
187+ kref_get (& cfid -> refcount );
188+ cfid -> has_lease = true;
187189 smb2_parse_contexts (server , o_rsp ,
188190 & oparms .fid -> epoch ,
189191 oparms .fid -> lease_key , & oplock ,
@@ -198,37 +200,41 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
198200 le16_to_cpu (qi_rsp -> OutputBufferOffset ),
199201 sizeof (struct smb2_file_all_info ),
200202 & rsp_iov [1 ], sizeof (struct smb2_file_all_info ),
201- (char * )& tcon -> cfid .file_all_info ))
202- tcon -> cfid .file_all_info_is_valid = true;
203- tcon -> cfid .time = jiffies ;
203+ (char * )& cfid -> file_all_info ))
204+ cfid -> file_all_info_is_valid = true;
204205
206+ cfid -> time = jiffies ;
205207
206208oshr_exit :
207- mutex_unlock (& tcon -> cfid . fid_mutex );
209+ mutex_unlock (& cfid -> fid_mutex );
208210oshr_free :
209211 SMB2_open_free (& rqst [0 ]);
210212 SMB2_query_info_free (& rqst [1 ]);
211213 free_rsp_buf (resp_buftype [0 ], rsp_iov [0 ].iov_base );
212214 free_rsp_buf (resp_buftype [1 ], rsp_iov [1 ].iov_base );
213215 if (rc == 0 )
214- * cfid = & tcon -> cfid ;
216+ * ret_cfid = cfid ;
215217
216218 return rc ;
217219}
218220
219221int open_cached_dir_by_dentry (struct cifs_tcon * tcon ,
220222 struct dentry * dentry ,
221- struct cached_fid * * cfid )
223+ struct cached_fid * * ret_cfid )
222224{
223- mutex_lock (& tcon -> cfid .fid_mutex );
224- if (tcon -> cfid .dentry == dentry ) {
225+ struct cached_fid * cfid ;
226+
227+ cfid = tcon -> cfid ;
228+
229+ mutex_lock (& cfid -> fid_mutex );
230+ if (cfid -> dentry == dentry ) {
225231 cifs_dbg (FYI , "found a cached root file handle by dentry\n" );
226- * cfid = & tcon -> cfid ;
227- kref_get (& tcon -> cfid . refcount );
228- mutex_unlock (& tcon -> cfid . fid_mutex );
232+ * ret_cfid = cfid ;
233+ kref_get (& cfid -> refcount );
234+ mutex_unlock (& cfid -> fid_mutex );
229235 return 0 ;
230236 }
231- mutex_unlock (& tcon -> cfid . fid_mutex );
237+ mutex_unlock (& cfid -> fid_mutex );
232238 return - ENOENT ;
233239}
234240
@@ -241,8 +247,8 @@ smb2_close_cached_fid(struct kref *ref)
241247
242248 if (cfid -> is_valid ) {
243249 cifs_dbg (FYI , "clear cached root file handle\n" );
244- SMB2_close (0 , cfid -> tcon , cfid -> fid -> persistent_fid ,
245- cfid -> fid -> volatile_fid );
250+ SMB2_close (0 , cfid -> tcon , cfid -> fid . persistent_fid ,
251+ cfid -> fid . volatile_fid );
246252 }
247253
248254 /*
@@ -312,7 +318,7 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
312318 tcon = tlink_tcon (tlink );
313319 if (IS_ERR (tcon ))
314320 continue ;
315- cfid = & tcon -> cfid ;
321+ cfid = tcon -> cfid ;
316322 mutex_lock (& cfid -> fid_mutex );
317323 if (cfid -> dentry ) {
318324 dput (cfid -> dentry );
@@ -328,12 +334,12 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
328334 */
329335void invalidate_all_cached_dirs (struct cifs_tcon * tcon )
330336{
331- mutex_lock (& tcon -> cfid . fid_mutex );
332- tcon -> cfid . is_valid = false;
337+ mutex_lock (& tcon -> cfid -> fid_mutex );
338+ tcon -> cfid -> is_valid = false;
333339 /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
334- close_cached_dir_lease_locked (& tcon -> cfid );
335- memset (tcon -> cfid . fid , 0 , sizeof (struct cifs_fid ));
336- mutex_unlock (& tcon -> cfid . fid_mutex );
340+ close_cached_dir_lease_locked (tcon -> cfid );
341+ memset (& tcon -> cfid -> fid , 0 , sizeof (struct cifs_fid ));
342+ mutex_unlock (& tcon -> cfid -> fid_mutex );
337343}
338344
339345static void
@@ -347,16 +353,34 @@ smb2_cached_lease_break(struct work_struct *work)
347353
348354int cached_dir_lease_break (struct cifs_tcon * tcon , __u8 lease_key [16 ])
349355{
350- if (tcon -> cfid . is_valid &&
356+ if (tcon -> cfid -> is_valid &&
351357 !memcmp (lease_key ,
352- tcon -> cfid . fid -> lease_key ,
358+ tcon -> cfid -> fid . lease_key ,
353359 SMB2_LEASE_KEY_SIZE )) {
354- tcon -> cfid . time = 0 ;
355- INIT_WORK (& tcon -> cfid . lease_break ,
360+ tcon -> cfid -> time = 0 ;
361+ INIT_WORK (& tcon -> cfid -> lease_break ,
356362 smb2_cached_lease_break );
357363 queue_work (cifsiod_wq ,
358- & tcon -> cfid . lease_break );
364+ & tcon -> cfid -> lease_break );
359365 return true;
360366 }
361367 return false;
362368}
369+
370+ struct cached_fid * init_cached_dir (void )
371+ {
372+ struct cached_fid * cfid ;
373+
374+ cfid = kzalloc (sizeof (* cfid ), GFP_KERNEL );
375+ if (!cfid )
376+ return NULL ;
377+ INIT_LIST_HEAD (& cfid -> dirents .entries );
378+ mutex_init (& cfid -> dirents .de_mutex );
379+ mutex_init (& cfid -> fid_mutex );
380+ return cfid ;
381+ }
382+
383+ void free_cached_dir (struct cifs_tcon * tcon )
384+ {
385+ kfree (tcon -> cfid );
386+ }
0 commit comments