18
18
int open_cached_dir (unsigned int xid , struct cifs_tcon * tcon ,
19
19
const char * path ,
20
20
struct cifs_sb_info * cifs_sb ,
21
- struct cached_fid * * cfid )
21
+ struct cached_fid * * ret_cfid )
22
22
{
23
23
struct cifs_ses * ses ;
24
24
struct TCP_Server_Info * server ;
@@ -35,6 +35,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
35
35
u8 oplock = SMB2_OPLOCK_LEVEL_II ;
36
36
struct cifs_fid * pfid ;
37
37
struct dentry * dentry ;
38
+ struct cached_fid * cfid ;
38
39
39
40
if (tcon == NULL || tcon -> nohandlecache ||
40
41
is_smb1_server (tcon -> ses -> server ))
@@ -51,12 +52,13 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
51
52
52
53
dentry = cifs_sb -> root ;
53
54
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 ) {
56
58
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 );
60
62
return 0 ;
61
63
}
62
64
@@ -67,15 +69,15 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
67
69
* thus causing a deadlock
68
70
*/
69
71
70
- mutex_unlock (& tcon -> cfid . fid_mutex );
72
+ mutex_unlock (& cfid -> fid_mutex );
71
73
72
74
if (smb3_encryption_required (tcon ))
73
75
flags |= CIFS_TRANSFORM_REQ ;
74
76
75
77
if (!server -> ops -> new_lease_key )
76
78
return - EIO ;
77
79
78
- pfid = tcon -> cfid . fid ;
80
+ pfid = & cfid -> fid ;
79
81
server -> ops -> new_lease_key (pfid );
80
82
81
83
memset (rqst , 0 , sizeof (rqst ));
@@ -118,14 +120,14 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
118
120
rc = compound_send_recv (xid , ses , server ,
119
121
flags , 2 , rqst ,
120
122
resp_buftype , rsp_iov );
121
- mutex_lock (& tcon -> cfid . fid_mutex );
123
+ mutex_lock (& cfid -> fid_mutex );
122
124
123
125
/*
124
126
* Now we need to check again as the cached root might have
125
127
* been successfully re-opened from a concurrent process
126
128
*/
127
129
128
- if (tcon -> cfid . is_valid ) {
130
+ if (cfid -> is_valid ) {
129
131
/* work was already done */
130
132
131
133
/* stash fids for close() later */
@@ -138,9 +140,9 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
138
140
* caller expects this func to set the fid in cfid to valid
139
141
* cached root, so increment the refcount.
140
142
*/
141
- kref_get (& tcon -> cfid . refcount );
143
+ kref_get (& cfid -> refcount );
142
144
143
- mutex_unlock (& tcon -> cfid . fid_mutex );
145
+ mutex_unlock (& cfid -> fid_mutex );
144
146
145
147
if (rc == 0 ) {
146
148
/* close extra handle outside of crit sec */
@@ -170,20 +172,20 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
170
172
oparms .fid -> mid = le64_to_cpu (o_rsp -> hdr .MessageId );
171
173
#endif /* CIFS_DEBUG2 */
172
174
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 ;
176
178
dget (dentry );
177
- kref_init (& tcon -> cfid . refcount );
179
+ kref_init (& cfid -> refcount );
178
180
179
181
/* BB TBD check to see if oplock level check can be removed below */
180
182
if (o_rsp -> OplockLevel == SMB2_OPLOCK_LEVEL_LEASE ) {
181
183
/*
182
184
* See commit 2f94a3125b87. Increment the refcount when we
183
185
* get a lease for root, release it if lease break occurs
184
186
*/
185
- kref_get (& tcon -> cfid . refcount );
186
- tcon -> cfid . has_lease = true;
187
+ kref_get (& cfid -> refcount );
188
+ cfid -> has_lease = true;
187
189
smb2_parse_contexts (server , o_rsp ,
188
190
& oparms .fid -> epoch ,
189
191
oparms .fid -> lease_key , & oplock ,
@@ -198,37 +200,41 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
198
200
le16_to_cpu (qi_rsp -> OutputBufferOffset ),
199
201
sizeof (struct smb2_file_all_info ),
200
202
& 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;
204
205
206
+ cfid -> time = jiffies ;
205
207
206
208
oshr_exit :
207
- mutex_unlock (& tcon -> cfid . fid_mutex );
209
+ mutex_unlock (& cfid -> fid_mutex );
208
210
oshr_free :
209
211
SMB2_open_free (& rqst [0 ]);
210
212
SMB2_query_info_free (& rqst [1 ]);
211
213
free_rsp_buf (resp_buftype [0 ], rsp_iov [0 ].iov_base );
212
214
free_rsp_buf (resp_buftype [1 ], rsp_iov [1 ].iov_base );
213
215
if (rc == 0 )
214
- * cfid = & tcon -> cfid ;
216
+ * ret_cfid = cfid ;
215
217
216
218
return rc ;
217
219
}
218
220
219
221
int open_cached_dir_by_dentry (struct cifs_tcon * tcon ,
220
222
struct dentry * dentry ,
221
- struct cached_fid * * cfid )
223
+ struct cached_fid * * ret_cfid )
222
224
{
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 ) {
225
231
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 );
229
235
return 0 ;
230
236
}
231
- mutex_unlock (& tcon -> cfid . fid_mutex );
237
+ mutex_unlock (& cfid -> fid_mutex );
232
238
return - ENOENT ;
233
239
}
234
240
@@ -241,8 +247,8 @@ smb2_close_cached_fid(struct kref *ref)
241
247
242
248
if (cfid -> is_valid ) {
243
249
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 );
246
252
}
247
253
248
254
/*
@@ -312,7 +318,7 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
312
318
tcon = tlink_tcon (tlink );
313
319
if (IS_ERR (tcon ))
314
320
continue ;
315
- cfid = & tcon -> cfid ;
321
+ cfid = tcon -> cfid ;
316
322
mutex_lock (& cfid -> fid_mutex );
317
323
if (cfid -> dentry ) {
318
324
dput (cfid -> dentry );
@@ -328,12 +334,12 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
328
334
*/
329
335
void invalidate_all_cached_dirs (struct cifs_tcon * tcon )
330
336
{
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;
333
339
/* 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 );
337
343
}
338
344
339
345
static void
@@ -347,16 +353,34 @@ smb2_cached_lease_break(struct work_struct *work)
347
353
348
354
int cached_dir_lease_break (struct cifs_tcon * tcon , __u8 lease_key [16 ])
349
355
{
350
- if (tcon -> cfid . is_valid &&
356
+ if (tcon -> cfid -> is_valid &&
351
357
!memcmp (lease_key ,
352
- tcon -> cfid . fid -> lease_key ,
358
+ tcon -> cfid -> fid . lease_key ,
353
359
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 ,
356
362
smb2_cached_lease_break );
357
363
queue_work (cifsiod_wq ,
358
- & tcon -> cfid . lease_break );
364
+ & tcon -> cfid -> lease_break );
359
365
return true;
360
366
}
361
367
return false;
362
368
}
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