Skip to content

Commit ea0c392

Browse files
committed
Merge tag '9p-for-5.20' of https://github.com/martinetd/linux
Pull 9p updates from Dominique Martinet: - a couple of fixes - add a tracepoint for fid refcounting - some cleanup/followup on fid lookup - some cleanup around req refcounting * tag '9p-for-5.20' of https://github.com/martinetd/linux: net/9p: Initialize the iounit field during fid creation net: 9p: fix refcount leak in p9_read_work() error handling 9p: roll p9_tag_remove into p9_req_put 9p: Add client parameter to p9_req_put() 9p: Drop kref usage 9p: Fix some kernel-doc comments 9p fid refcount: cleanup p9_fid_put calls 9p fid refcount: add a 9p_fid_ref tracepoint 9p fid refcount: add p9_fid_get/put wrappers 9p: Fix minor typo in code comment 9p: Remove unnecessary variable for old fids while walking from d_parent 9p: Make the path walk logic more clear about when cloning is required 9p: Track the root fid with its own variable during lookups
2 parents c42b729 + aa7aeee commit ea0c392

File tree

17 files changed

+314
-245
lines changed

17 files changed

+314
-245
lines changed

fs/9p/fid.c

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
2828
/**
2929
* v9fs_fid_add - add a fid to a dentry
3030
* @dentry: dentry that the fid is being added to
31-
* @fid: fid to add
31+
* @pfid: fid to add, NULLed out
3232
*
3333
*/
34-
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
34+
void v9fs_fid_add(struct dentry *dentry, struct p9_fid **pfid)
3535
{
36+
struct p9_fid *fid = *pfid;
37+
3638
spin_lock(&dentry->d_lock);
3739
__add_fid(dentry, fid);
3840
spin_unlock(&dentry->d_lock);
41+
42+
*pfid = NULL;
3943
}
4044

4145
/**
@@ -56,7 +60,7 @@ static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
5660
h = (struct hlist_head *)&inode->i_private;
5761
hlist_for_each_entry(fid, h, ilist) {
5862
if (uid_eq(fid->uid, uid)) {
59-
refcount_inc(&fid->count);
63+
p9_fid_get(fid);
6064
ret = fid;
6165
break;
6266
}
@@ -68,15 +72,19 @@ static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
6872
/**
6973
* v9fs_open_fid_add - add an open fid to an inode
7074
* @inode: inode that the fid is being added to
71-
* @fid: fid to add
75+
* @pfid: fid to add, NULLed out
7276
*
7377
*/
7478

75-
void v9fs_open_fid_add(struct inode *inode, struct p9_fid *fid)
79+
void v9fs_open_fid_add(struct inode *inode, struct p9_fid **pfid)
7680
{
81+
struct p9_fid *fid = *pfid;
82+
7783
spin_lock(&inode->i_lock);
7884
hlist_add_head(&fid->ilist, (struct hlist_head *)&inode->i_private);
7985
spin_unlock(&inode->i_lock);
86+
87+
*pfid = NULL;
8088
}
8189

8290

@@ -104,7 +112,7 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
104112
hlist_for_each_entry(fid, h, dlist) {
105113
if (any || uid_eq(fid->uid, uid)) {
106114
ret = fid;
107-
refcount_inc(&ret->count);
115+
p9_fid_get(ret);
108116
break;
109117
}
110118
}
@@ -150,9 +158,9 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
150158
{
151159
struct dentry *ds;
152160
const unsigned char **wnames, *uname;
153-
int i, n, l, clone, access;
161+
int i, n, l, access;
154162
struct v9fs_session_info *v9ses;
155-
struct p9_fid *fid, *old_fid;
163+
struct p9_fid *fid, *root_fid, *old_fid;
156164

157165
v9ses = v9fs_dentry2v9ses(dentry);
158166
access = v9ses->flags & V9FS_ACCESS_MASK;
@@ -169,17 +177,17 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
169177
fid = v9fs_fid_find(ds, uid, any);
170178
if (fid) {
171179
/* Found the parent fid do a lookup with that */
172-
struct p9_fid *ofid = fid;
180+
old_fid = fid;
173181

174-
fid = p9_client_walk(ofid, 1, &dentry->d_name.name, 1);
175-
p9_client_clunk(ofid);
182+
fid = p9_client_walk(old_fid, 1, &dentry->d_name.name, 1);
183+
p9_fid_put(old_fid);
176184
goto fid_out;
177185
}
178186
up_read(&v9ses->rename_sem);
179187

180188
/* start from the root and try to do a lookup */
181-
fid = v9fs_fid_find(dentry->d_sb->s_root, uid, any);
182-
if (!fid) {
189+
root_fid = v9fs_fid_find(dentry->d_sb->s_root, uid, any);
190+
if (!root_fid) {
183191
/* the user is not attached to the fs yet */
184192
if (access == V9FS_ACCESS_SINGLE)
185193
return ERR_PTR(-EPERM);
@@ -194,12 +202,13 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
194202
if (IS_ERR(fid))
195203
return fid;
196204

197-
refcount_inc(&fid->count);
198-
v9fs_fid_add(dentry->d_sb->s_root, fid);
205+
root_fid = p9_fid_get(fid);
206+
v9fs_fid_add(dentry->d_sb->s_root, &fid);
199207
}
200208
/* If we are root ourself just return that */
201209
if (dentry->d_sb->s_root == dentry)
202-
return fid;
210+
return root_fid;
211+
203212
/*
204213
* Do a multipath walk with attached root.
205214
* When walking parent we need to make sure we
@@ -211,39 +220,39 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
211220
fid = ERR_PTR(n);
212221
goto err_out;
213222
}
214-
old_fid = fid;
215-
clone = 1;
223+
fid = root_fid;
224+
old_fid = root_fid;
216225
i = 0;
217226
while (i < n) {
218227
l = min(n - i, P9_MAXWELEM);
219228
/*
220229
* We need to hold rename lock when doing a multipath
221-
* walk to ensure none of the patch component change
230+
* walk to ensure none of the path components change
222231
*/
223-
fid = p9_client_walk(fid, l, &wnames[i], clone);
232+
fid = p9_client_walk(old_fid, l, &wnames[i],
233+
old_fid == root_fid /* clone */);
224234
/* non-cloning walk will return the same fid */
225235
if (fid != old_fid) {
226-
p9_client_clunk(old_fid);
236+
p9_fid_put(old_fid);
227237
old_fid = fid;
228238
}
229239
if (IS_ERR(fid)) {
230240
kfree(wnames);
231241
goto err_out;
232242
}
233243
i += l;
234-
clone = 0;
235244
}
236245
kfree(wnames);
237246
fid_out:
238247
if (!IS_ERR(fid)) {
239248
spin_lock(&dentry->d_lock);
240249
if (d_unhashed(dentry)) {
241250
spin_unlock(&dentry->d_lock);
242-
p9_client_clunk(fid);
251+
p9_fid_put(fid);
243252
fid = ERR_PTR(-ENOENT);
244253
} else {
245254
__add_fid(dentry, fid);
246-
refcount_inc(&fid->count);
255+
p9_fid_get(fid);
247256
spin_unlock(&dentry->d_lock);
248257
}
249258
}
@@ -300,7 +309,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
300309
fid = clone_fid(ofid);
301310
if (IS_ERR(fid))
302311
goto error_out;
303-
p9_client_clunk(ofid);
312+
p9_fid_put(ofid);
304313
/*
305314
* writeback fid will only be used to write back the
306315
* dirty pages. We always request for the open fid in read-write
@@ -309,7 +318,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
309318
*/
310319
err = p9_client_open(fid, O_RDWR);
311320
if (err < 0) {
312-
p9_client_clunk(fid);
321+
p9_fid_put(fid);
313322
fid = ERR_PTR(err);
314323
goto error_out;
315324
}

fs/9p/fid.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ static inline struct p9_fid *v9fs_parent_fid(struct dentry *dentry)
1313
{
1414
return v9fs_fid_lookup(dentry->d_parent);
1515
}
16-
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
16+
void v9fs_fid_add(struct dentry *dentry, struct p9_fid **fid);
1717
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
18-
void v9fs_open_fid_add(struct inode *inode, struct p9_fid *fid);
18+
void v9fs_open_fid_add(struct inode *inode, struct p9_fid **fid);
1919
static inline struct p9_fid *clone_fid(struct p9_fid *fid)
2020
{
2121
return IS_ERR(fid) ? fid : p9_client_walk(fid, 0, NULL, 1);
@@ -29,7 +29,7 @@ static inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
2929
return fid;
3030

3131
nfid = clone_fid(fid);
32-
p9_client_clunk(fid);
32+
p9_fid_put(fid);
3333
return nfid;
3434
}
3535
#endif

fs/9p/vfs_addr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
7373
BUG_ON(!fid);
7474
}
7575

76-
refcount_inc(&fid->count);
76+
p9_fid_get(fid);
7777
rreq->netfs_priv = fid;
7878
return 0;
7979
}
@@ -86,7 +86,7 @@ static void v9fs_free_request(struct netfs_io_request *rreq)
8686
{
8787
struct p9_fid *fid = rreq->netfs_priv;
8888

89-
p9_client_clunk(fid);
89+
p9_fid_put(fid);
9090
}
9191

9292
/**

fs/9p/vfs_dentry.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static void v9fs_dentry_release(struct dentry *dentry)
5454
p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",
5555
dentry, dentry);
5656
hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata)
57-
p9_client_clunk(hlist_entry(p, struct p9_fid, dlist));
57+
p9_fid_put(hlist_entry(p, struct p9_fid, dlist));
5858
dentry->d_fsdata = NULL;
5959
}
6060

@@ -85,7 +85,7 @@ static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
8585
retval = v9fs_refresh_inode_dotl(fid, inode);
8686
else
8787
retval = v9fs_refresh_inode(fid, inode);
88-
p9_client_clunk(fid);
88+
p9_fid_put(fid);
8989

9090
if (retval == -ENOENT)
9191
return 0;

fs/9p/vfs_dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
218218
spin_lock(&inode->i_lock);
219219
hlist_del(&fid->ilist);
220220
spin_unlock(&inode->i_lock);
221-
p9_client_clunk(fid);
221+
p9_fid_put(fid);
222222
}
223223

224224
if ((filp->f_mode & FMODE_WRITE)) {

fs/9p/vfs_file.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,16 @@ int v9fs_file_open(struct inode *inode, struct file *file)
6363

6464
err = p9_client_open(fid, omode);
6565
if (err < 0) {
66-
p9_client_clunk(fid);
66+
p9_fid_put(fid);
6767
return err;
6868
}
6969
if ((file->f_flags & O_APPEND) &&
7070
(!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))
7171
generic_file_llseek(file, 0, SEEK_END);
72+
73+
file->private_data = fid;
7274
}
7375

74-
file->private_data = fid;
7576
mutex_lock(&v9inode->v_mutex);
7677
if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
7778
!v9inode->writeback_fid &&
@@ -95,10 +96,10 @@ int v9fs_file_open(struct inode *inode, struct file *file)
9596
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
9697
fscache_use_cookie(v9fs_inode_cookie(v9inode),
9798
file->f_mode & FMODE_WRITE);
98-
v9fs_open_fid_add(inode, fid);
99+
v9fs_open_fid_add(inode, &fid);
99100
return 0;
100101
out_error:
101-
p9_client_clunk(file->private_data);
102+
p9_fid_put(file->private_data);
102103
file->private_data = NULL;
103104
return err;
104105
}

0 commit comments

Comments
 (0)