Skip to content

Commit dafbe68

Browse files
committed
9p fid refcount: cleanup p9_fid_put calls
Simplify p9_fid_put cleanup path in many 9p functions since the function is noop on null or error fids. Also make the *_add_fid() helpers "steal" the fid by nulling its pointer, so put after them will be noop. This should lead to no change of behaviour Link: https://lkml.kernel.org/r/20220612085330.1451496-7-asmadeus@codewreck.org Reviewed-by: Tyler Hicks <tyhicks@linux.microsoft.com> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
1 parent 286c171 commit dafbe68

6 files changed

Lines changed: 64 additions & 90 deletions

File tree

fs/9p/fid.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@ static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
3131
* @fid: fid to add
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
/**
@@ -72,11 +76,15 @@ static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
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

@@ -189,13 +197,13 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
189197
else
190198
uname = v9ses->uname;
191199

192-
root_fid = p9_client_attach(v9ses->clnt, NULL, uname, uid,
193-
v9ses->aname);
194-
if (IS_ERR(root_fid))
195-
return root_fid;
200+
fid = p9_client_attach(v9ses->clnt, NULL, uname, uid,
201+
v9ses->aname);
202+
if (IS_ERR(fid))
203+
return fid;
196204

197-
p9_fid_get(root_fid);
198-
v9fs_fid_add(dentry->d_sb->s_root, 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)

fs/9p/fid.h

Lines changed: 2 additions & 2 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);

fs/9p/vfs_file.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ int v9fs_file_open(struct inode *inode, struct file *file)
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,7 +96,7 @@ 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:
101102
p9_fid_put(file->private_data);

fs/9p/vfs_inode.c

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,8 @@ void v9fs_evict_inode(struct inode *inode)
399399

400400
fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false);
401401
/* clunk the fid stashed in writeback_fid */
402-
if (v9inode->writeback_fid) {
403-
p9_fid_put(v9inode->writeback_fid);
404-
v9inode->writeback_fid = NULL;
405-
}
402+
p9_fid_put(v9inode->writeback_fid);
403+
v9inode->writeback_fid = NULL;
406404
}
407405

408406
static int v9fs_test_inode(struct inode *inode, void *data)
@@ -633,14 +631,12 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
633631
if (IS_ERR(ofid)) {
634632
err = PTR_ERR(ofid);
635633
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
636-
p9_fid_put(dfid);
637-
return ERR_PTR(err);
634+
goto error;
638635
}
639636

640637
err = p9_client_fcreate(ofid, name, perm, mode, extension);
641638
if (err < 0) {
642639
p9_debug(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err);
643-
p9_fid_put(dfid);
644640
goto error;
645641
}
646642

@@ -651,8 +647,6 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
651647
err = PTR_ERR(fid);
652648
p9_debug(P9_DEBUG_VFS,
653649
"p9_client_walk failed %d\n", err);
654-
fid = NULL;
655-
p9_fid_put(dfid);
656650
goto error;
657651
}
658652
/*
@@ -663,21 +657,17 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
663657
err = PTR_ERR(inode);
664658
p9_debug(P9_DEBUG_VFS,
665659
"inode creation failed %d\n", err);
666-
p9_fid_put(dfid);
667660
goto error;
668661
}
669-
v9fs_fid_add(dentry, fid);
662+
v9fs_fid_add(dentry, &fid);
670663
d_instantiate(dentry, inode);
671664
}
672665
p9_fid_put(dfid);
673666
return ofid;
674667
error:
675-
if (ofid)
676-
p9_fid_put(ofid);
677-
678-
if (fid)
679-
p9_fid_put(fid);
680-
668+
p9_fid_put(dfid);
669+
p9_fid_put(ofid);
670+
p9_fid_put(fid);
681671
return ERR_PTR(err);
682672
}
683673

@@ -804,9 +794,9 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
804794
res = d_splice_alias(inode, dentry);
805795
if (!IS_ERR(fid)) {
806796
if (!res)
807-
v9fs_fid_add(dentry, fid);
797+
v9fs_fid_add(dentry, &fid);
808798
else if (!IS_ERR(res))
809-
v9fs_fid_add(res, fid);
799+
v9fs_fid_add(res, &fid);
810800
else
811801
p9_fid_put(fid);
812802
}
@@ -847,7 +837,6 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
847837
v9fs_proto_dotu(v9ses)));
848838
if (IS_ERR(fid)) {
849839
err = PTR_ERR(fid);
850-
fid = NULL;
851840
goto error;
852841
}
853842

@@ -882,16 +871,15 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
882871
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
883872
fscache_use_cookie(v9fs_inode_cookie(v9inode),
884873
file->f_mode & FMODE_WRITE);
885-
v9fs_open_fid_add(inode, fid);
874+
v9fs_open_fid_add(inode, &fid);
886875

887876
file->f_mode |= FMODE_CREATED;
888877
out:
889878
dput(res);
890879
return err;
891880

892881
error:
893-
if (fid)
894-
p9_fid_put(fid);
882+
p9_fid_put(fid);
895883
goto out;
896884
}
897885

@@ -939,9 +927,9 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
939927
struct inode *old_inode;
940928
struct inode *new_inode;
941929
struct v9fs_session_info *v9ses;
942-
struct p9_fid *oldfid, *dfid;
943-
struct p9_fid *olddirfid;
944-
struct p9_fid *newdirfid;
930+
struct p9_fid *oldfid = NULL, *dfid = NULL;
931+
struct p9_fid *olddirfid = NULL;
932+
struct p9_fid *newdirfid = NULL;
945933
struct p9_wstat wstat;
946934

947935
if (flags)
@@ -958,21 +946,22 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
958946

959947
dfid = v9fs_parent_fid(old_dentry);
960948
olddirfid = clone_fid(dfid);
961-
if (dfid && !IS_ERR(dfid))
962-
p9_fid_put(dfid);
949+
p9_fid_put(dfid);
950+
dfid = NULL;
963951

964952
if (IS_ERR(olddirfid)) {
965953
retval = PTR_ERR(olddirfid);
966-
goto done;
954+
goto error;
967955
}
968956

969957
dfid = v9fs_parent_fid(new_dentry);
970958
newdirfid = clone_fid(dfid);
971959
p9_fid_put(dfid);
960+
dfid = NULL;
972961

973962
if (IS_ERR(newdirfid)) {
974963
retval = PTR_ERR(newdirfid);
975-
goto clunk_olddir;
964+
goto error;
976965
}
977966

978967
down_write(&v9ses->rename_sem);
@@ -983,7 +972,7 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
983972
retval = p9_client_rename(oldfid, newdirfid,
984973
new_dentry->d_name.name);
985974
if (retval != -EOPNOTSUPP)
986-
goto clunk_newdir;
975+
goto error_locked;
987976
}
988977
if (old_dentry->d_parent != new_dentry->d_parent) {
989978
/*
@@ -992,14 +981,14 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
992981

993982
p9_debug(P9_DEBUG_ERROR, "old dir and new dir are different\n");
994983
retval = -EXDEV;
995-
goto clunk_newdir;
984+
goto error_locked;
996985
}
997986
v9fs_blank_wstat(&wstat);
998987
wstat.muid = v9ses->uname;
999988
wstat.name = new_dentry->d_name.name;
1000989
retval = p9_client_wstat(oldfid, &wstat);
1001990

1002-
clunk_newdir:
991+
error_locked:
1003992
if (!retval) {
1004993
if (new_inode) {
1005994
if (S_ISDIR(new_inode->i_mode))
@@ -1020,12 +1009,10 @@ v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
10201009
d_move(old_dentry, new_dentry);
10211010
}
10221011
up_write(&v9ses->rename_sem);
1023-
p9_fid_put(newdirfid);
10241012

1025-
clunk_olddir:
1013+
error:
1014+
p9_fid_put(newdirfid);
10261015
p9_fid_put(olddirfid);
1027-
1028-
done:
10291016
p9_fid_put(oldfid);
10301017
return retval;
10311018
}

0 commit comments

Comments
 (0)