Skip to content

Commit 3819bb0

Browse files
author
Al Viro
committed
nfsd: vfs_mkdir() might succeed leaving dentry negative unhashed
That can (and does, on some filesystems) happen - ->mkdir() (and thus vfs_mkdir()) can legitimately leave its argument negative and just unhash it, counting upon the lookup to pick the object we'd created next time we try to look at that name. Some vfs_mkdir() callers forget about that possibility... Acked-by: J. Bruce Fields <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent 9c3e902 commit 3819bb0

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

fs/nfsd/vfs.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,28 @@ nfsd_create_locked(struct svc_rqst *rqstp, struct svc_fh *fhp,
12011201
break;
12021202
case S_IFDIR:
12031203
host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
1204+
if (!host_err && unlikely(d_unhashed(dchild))) {
1205+
struct dentry *d;
1206+
d = lookup_one_len(dchild->d_name.name,
1207+
dchild->d_parent,
1208+
dchild->d_name.len);
1209+
if (IS_ERR(d)) {
1210+
host_err = PTR_ERR(d);
1211+
break;
1212+
}
1213+
if (unlikely(d_is_negative(d))) {
1214+
dput(d);
1215+
err = nfserr_serverfault;
1216+
goto out;
1217+
}
1218+
dput(resfhp->fh_dentry);
1219+
resfhp->fh_dentry = dget(d);
1220+
err = fh_update(resfhp);
1221+
dput(dchild);
1222+
dchild = d;
1223+
if (err)
1224+
goto out;
1225+
}
12041226
break;
12051227
case S_IFCHR:
12061228
case S_IFBLK:

0 commit comments

Comments
 (0)