Skip to content

Commit a63ec83

Browse files
Ronnie SahlbergSteve French
authored andcommitted
cifs: Add constructor/destructors for tcon->cfid
and move the structure definitions into cached_dir.h Reviewed-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Ronnie Sahlberg <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 9e31678 commit a63ec83

File tree

6 files changed

+121
-97
lines changed

6 files changed

+121
-97
lines changed

fs/cifs/cached_dir.c

Lines changed: 67 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
int 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

206208
oshr_exit:
207-
mutex_unlock(&tcon->cfid.fid_mutex);
209+
mutex_unlock(&cfid->fid_mutex);
208210
oshr_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

219221
int 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
*/
329335
void 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

339345
static void
@@ -347,16 +353,34 @@ smb2_cached_lease_break(struct work_struct *work)
347353

348354
int 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+
}

fs/cifs/cached_dir.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,44 @@
99
#define _CACHED_DIR_H
1010

1111

12+
struct cached_dirent {
13+
struct list_head entry;
14+
char *name;
15+
int namelen;
16+
loff_t pos;
17+
18+
struct cifs_fattr fattr;
19+
};
20+
21+
struct cached_dirents {
22+
bool is_valid:1;
23+
bool is_failed:1;
24+
struct dir_context *ctx; /*
25+
* Only used to make sure we only take entries
26+
* from a single context. Never dereferenced.
27+
*/
28+
struct mutex de_mutex;
29+
int pos; /* Expected ctx->pos */
30+
struct list_head entries;
31+
};
32+
33+
struct cached_fid {
34+
bool is_valid:1; /* Do we have a useable root fid */
35+
bool file_all_info_is_valid:1;
36+
bool has_lease:1;
37+
unsigned long time; /* jiffies of when lease was taken */
38+
struct kref refcount;
39+
struct cifs_fid fid;
40+
struct mutex fid_mutex;
41+
struct cifs_tcon *tcon;
42+
struct dentry *dentry;
43+
struct work_struct lease_break;
44+
struct smb2_file_all_info file_all_info;
45+
struct cached_dirents dirents;
46+
};
47+
48+
extern struct cached_fid *init_cached_dir(void);
49+
extern void free_cached_dir(struct cifs_tcon *tcon);
1250
extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
1351
const char *path,
1452
struct cifs_sb_info *cifs_sb,

fs/cifs/cifsglob.h

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,42 +1128,6 @@ struct cifs_fattr {
11281128
u32 cf_cifstag;
11291129
};
11301130

1131-
struct cached_dirent {
1132-
struct list_head entry;
1133-
char *name;
1134-
int namelen;
1135-
loff_t pos;
1136-
1137-
struct cifs_fattr fattr;
1138-
};
1139-
1140-
struct cached_dirents {
1141-
bool is_valid:1;
1142-
bool is_failed:1;
1143-
struct dir_context *ctx; /*
1144-
* Only used to make sure we only take entries
1145-
* from a single context. Never dereferenced.
1146-
*/
1147-
struct mutex de_mutex;
1148-
int pos; /* Expected ctx->pos */
1149-
struct list_head entries;
1150-
};
1151-
1152-
struct cached_fid {
1153-
bool is_valid:1; /* Do we have a useable root fid */
1154-
bool file_all_info_is_valid:1;
1155-
bool has_lease:1;
1156-
unsigned long time; /* jiffies of when lease was taken */
1157-
struct kref refcount;
1158-
struct cifs_fid *fid;
1159-
struct mutex fid_mutex;
1160-
struct cifs_tcon *tcon;
1161-
struct dentry *dentry;
1162-
struct work_struct lease_break;
1163-
struct smb2_file_all_info file_all_info;
1164-
struct cached_dirents dirents;
1165-
};
1166-
11671131
/*
11681132
* there is one of these for each connection to a resource on a particular
11691133
* session
@@ -1257,7 +1221,7 @@ struct cifs_tcon {
12571221
struct fscache_volume *fscache; /* cookie for share */
12581222
#endif
12591223
struct list_head pending_opens; /* list of incomplete opens */
1260-
struct cached_fid cfid; /* Cached root fid */
1224+
struct cached_fid *cfid; /* Cached root fid */
12611225
/* BB add field for back pointer to sb struct(s)? */
12621226
#ifdef CONFIG_CIFS_DFS_UPCALL
12631227
struct list_head ulist; /* cache update list */

fs/cifs/misc.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "dns_resolve.h"
2424
#endif
2525
#include "fs_context.h"
26+
#include "cached_dir.h"
2627

2728
extern mempool_t *cifs_sm_req_poolp;
2829
extern mempool_t *cifs_req_poolp;
@@ -116,13 +117,11 @@ tconInfoAlloc(void)
116117
ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL);
117118
if (!ret_buf)
118119
return NULL;
119-
ret_buf->cfid.fid = kzalloc(sizeof(*ret_buf->cfid.fid), GFP_KERNEL);
120-
if (!ret_buf->cfid.fid) {
120+
ret_buf->cfid = init_cached_dir();
121+
if (!ret_buf->cfid) {
121122
kfree(ret_buf);
122123
return NULL;
123124
}
124-
INIT_LIST_HEAD(&ret_buf->cfid.dirents.entries);
125-
mutex_init(&ret_buf->cfid.dirents.de_mutex);
126125

127126
atomic_inc(&tconInfoAllocCount);
128127
ret_buf->status = TID_NEW;
@@ -131,7 +130,6 @@ tconInfoAlloc(void)
131130
INIT_LIST_HEAD(&ret_buf->openFileList);
132131
INIT_LIST_HEAD(&ret_buf->tcon_list);
133132
spin_lock_init(&ret_buf->open_file_lock);
134-
mutex_init(&ret_buf->cfid.fid_mutex);
135133
spin_lock_init(&ret_buf->stat_lock);
136134
atomic_set(&ret_buf->num_local_opens, 0);
137135
atomic_set(&ret_buf->num_remote_opens, 0);
@@ -140,17 +138,17 @@ tconInfoAlloc(void)
140138
}
141139

142140
void
143-
tconInfoFree(struct cifs_tcon *buf_to_free)
141+
tconInfoFree(struct cifs_tcon *tcon)
144142
{
145-
if (buf_to_free == NULL) {
143+
if (tcon == NULL) {
146144
cifs_dbg(FYI, "Null buffer passed to tconInfoFree\n");
147145
return;
148146
}
147+
free_cached_dir(tcon);
149148
atomic_dec(&tconInfoAllocCount);
150-
kfree(buf_to_free->nativeFileSystem);
151-
kfree_sensitive(buf_to_free->password);
152-
kfree(buf_to_free->cfid.fid);
153-
kfree(buf_to_free);
149+
kfree(tcon->nativeFileSystem);
150+
kfree_sensitive(tcon->password);
151+
kfree(tcon);
154152
}
155153

156154
struct smb_hdr *

0 commit comments

Comments
 (0)