Skip to content

Commit 26d8e43

Browse files
committed
Merge tag 'vfs-6.15-rc1.async.dir' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs async dir updates from Christian Brauner: "This contains cleanups that fell out of the work from async directory handling: - Change kern_path_locked() and user_path_locked_at() to never return a negative dentry. This simplifies the usability of these helpers in various places - Drop d_exact_alias() from the remaining place in NFS where it is still used. This also allows us to drop the d_exact_alias() helper completely - Drop an unnecessary call to fh_update() from nfsd_create_locked() - Change i_op->mkdir() to return a struct dentry Change vfs_mkdir() to return a dentry provided by the filesystems which is hashed and positive. This allows us to reduce the number of cases where the resulting dentry is not positive to very few cases. The code in these places becomes simpler and easier to understand. - Repack DENTRY_* and LOOKUP_* flags" * tag 'vfs-6.15-rc1.async.dir' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: doc: fix inline emphasis warning VFS: Change vfs_mkdir() to return the dentry. nfs: change mkdir inode_operation to return alternate dentry if needed. fuse: return correct dentry for ->mkdir ceph: return the correct dentry on mkdir hostfs: store inode in dentry after mkdir if possible. Change inode_operations.mkdir to return struct dentry * nfsd: drop fh_update() from S_IFDIR branch of nfsd_create_locked() nfs/vfs: discard d_exact_alias() VFS: add common error checks to lookup_one_qstr_excl() VFS: change kern_path_locked() and user_path_locked_at() to never return negative dentry VFS: repack LOOKUP_ bit flags. VFS: repack DENTRY_ flags.
2 parents 804382d + be66901 commit 26d8e43

File tree

75 files changed

+618
-599
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+618
-599
lines changed

Documentation/filesystems/locking.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ prototypes::
6666
int (*link) (struct dentry *,struct inode *,struct dentry *);
6767
int (*unlink) (struct inode *,struct dentry *);
6868
int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,const char *);
69-
int (*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
69+
struct dentry *(*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
7070
int (*rmdir) (struct inode *,struct dentry *);
7171
int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t,dev_t);
7272
int (*rename) (struct mnt_idmap *, struct inode *, struct dentry *,

Documentation/filesystems/porting.rst

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,7 @@ and it *must* be opened exclusive.
11441144

11451145
---
11461146

1147-
** mandatory**
1147+
**mandatory**
11481148

11491149
->d_revalidate() gets two extra arguments - inode of parent directory and
11501150
name our dentry is expected to have. Both are stable (dir is pinned in
@@ -1160,5 +1160,46 @@ magic.
11601160

11611161
---
11621162

1163-
** mandatory **
1163+
**recommended**
1164+
1165+
kern_path_locked() and user_path_locked() no longer return a negative
1166+
dentry so this doesn't need to be checked. If the name cannot be found,
1167+
ERR_PTR(-ENOENT) is returned.
1168+
1169+
---
1170+
1171+
**recommended**
1172+
1173+
lookup_one_qstr_excl() is changed to return errors in more cases, so
1174+
these conditions don't require explicit checks:
1175+
1176+
- if LOOKUP_CREATE is NOT given, then the dentry won't be negative,
1177+
ERR_PTR(-ENOENT) is returned instead
1178+
- if LOOKUP_EXCL IS given, then the dentry won't be positive,
1179+
ERR_PTR(-EEXIST) is rreturned instread
1180+
1181+
LOOKUP_EXCL now means "target must not exist". It can be combined with
1182+
LOOK_CREATE or LOOKUP_RENAME_TARGET.
1183+
1184+
---
1185+
1186+
**mandatory**
11641187
invalidate_inodes() is gone use evict_inodes() instead.
1188+
1189+
---
1190+
1191+
**mandatory**
1192+
1193+
->mkdir() now returns a dentry. If the created inode is found to
1194+
already be in cache and have a dentry (often IS_ROOT()), it will need to
1195+
be spliced into the given name in place of the given dentry. That dentry
1196+
now needs to be returned. If the original dentry is used, NULL should
1197+
be returned. Any error should be returned with ERR_PTR().
1198+
1199+
In general, filesystems which use d_instantiate_new() to install the new
1200+
inode can safely return NULL. Filesystems which may not have an I_NEW inode
1201+
should use d_drop();d_splice_alias() and return the result of the latter.
1202+
1203+
If a positive dentry cannot be returned for some reason, in-kernel
1204+
clients such as cachefiles, nfsd, smb/server may not perform ideally but
1205+
will fail-safe.

Documentation/filesystems/vfs.rst

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ As of kernel 2.6.22, the following members are defined:
495495
int (*link) (struct dentry *,struct inode *,struct dentry *);
496496
int (*unlink) (struct inode *,struct dentry *);
497497
int (*symlink) (struct mnt_idmap *, struct inode *,struct dentry *,const char *);
498-
int (*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
498+
struct dentry *(*mkdir) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t);
499499
int (*rmdir) (struct inode *,struct dentry *);
500500
int (*mknod) (struct mnt_idmap *, struct inode *,struct dentry *,umode_t,dev_t);
501501
int (*rename) (struct mnt_idmap *, struct inode *, struct dentry *,
@@ -562,7 +562,26 @@ otherwise noted.
562562
``mkdir``
563563
called by the mkdir(2) system call. Only required if you want
564564
to support creating subdirectories. You will probably need to
565-
call d_instantiate() just as you would in the create() method
565+
call d_instantiate_new() just as you would in the create() method.
566+
567+
If d_instantiate_new() is not used and if the fh_to_dentry()
568+
export operation is provided, or if the storage might be
569+
accessible by another path (e.g. with a network filesystem)
570+
then more care may be needed. Importantly d_instantate()
571+
should not be used with an inode that is no longer I_NEW if there
572+
any chance that the inode could already be attached to a dentry.
573+
This is because of a hard rule in the VFS that a directory must
574+
only ever have one dentry.
575+
576+
For example, if an NFS filesystem is mounted twice the new directory
577+
could be visible on the other mount before it is on the original
578+
mount, and a pair of name_to_handle_at(), open_by_handle_at()
579+
calls could instantiate the directory inode with an IS_ROOT()
580+
dentry before the first mkdir returns.
581+
582+
If there is any chance this could happen, then the new inode
583+
should be d_drop()ed and attached with d_splice_alias(). The
584+
returned dentry (if any) should be returned by ->mkdir().
566585

567586
``rmdir``
568587
called by the rmdir(2) system call. Only required if you want

drivers/base/devtmpfs.c

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -175,18 +175,17 @@ static int dev_mkdir(const char *name, umode_t mode)
175175
{
176176
struct dentry *dentry;
177177
struct path path;
178-
int err;
179178

180179
dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_DIRECTORY);
181180
if (IS_ERR(dentry))
182181
return PTR_ERR(dentry);
183182

184-
err = vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode);
185-
if (!err)
183+
dentry = vfs_mkdir(&nop_mnt_idmap, d_inode(path.dentry), dentry, mode);
184+
if (!IS_ERR(dentry))
186185
/* mark as kernel-created inode */
187186
d_inode(dentry)->i_private = &thread;
188187
done_path_create(&path, dentry);
189-
return err;
188+
return PTR_ERR_OR_ZERO(dentry);
190189
}
191190

192191
static int create_path(const char *nodepath)
@@ -260,15 +259,12 @@ static int dev_rmdir(const char *name)
260259
dentry = kern_path_locked(name, &parent);
261260
if (IS_ERR(dentry))
262261
return PTR_ERR(dentry);
263-
if (d_really_is_positive(dentry)) {
264-
if (d_inode(dentry)->i_private == &thread)
265-
err = vfs_rmdir(&nop_mnt_idmap, d_inode(parent.dentry),
266-
dentry);
267-
else
268-
err = -EPERM;
269-
} else {
270-
err = -ENOENT;
271-
}
262+
if (d_inode(dentry)->i_private == &thread)
263+
err = vfs_rmdir(&nop_mnt_idmap, d_inode(parent.dentry),
264+
dentry);
265+
else
266+
err = -EPERM;
267+
272268
dput(dentry);
273269
inode_unlock(d_inode(parent.dentry));
274270
path_put(&parent);
@@ -325,39 +321,37 @@ static int handle_remove(const char *nodename, struct device *dev)
325321
{
326322
struct path parent;
327323
struct dentry *dentry;
324+
struct kstat stat;
325+
struct path p;
328326
int deleted = 0;
329327
int err;
330328

331329
dentry = kern_path_locked(nodename, &parent);
332330
if (IS_ERR(dentry))
333331
return PTR_ERR(dentry);
334332

335-
if (d_really_is_positive(dentry)) {
336-
struct kstat stat;
337-
struct path p = {.mnt = parent.mnt, .dentry = dentry};
338-
err = vfs_getattr(&p, &stat, STATX_TYPE | STATX_MODE,
339-
AT_STATX_SYNC_AS_STAT);
340-
if (!err && dev_mynode(dev, d_inode(dentry), &stat)) {
341-
struct iattr newattrs;
342-
/*
343-
* before unlinking this node, reset permissions
344-
* of possible references like hardlinks
345-
*/
346-
newattrs.ia_uid = GLOBAL_ROOT_UID;
347-
newattrs.ia_gid = GLOBAL_ROOT_GID;
348-
newattrs.ia_mode = stat.mode & ~0777;
349-
newattrs.ia_valid =
350-
ATTR_UID|ATTR_GID|ATTR_MODE;
351-
inode_lock(d_inode(dentry));
352-
notify_change(&nop_mnt_idmap, dentry, &newattrs, NULL);
353-
inode_unlock(d_inode(dentry));
354-
err = vfs_unlink(&nop_mnt_idmap, d_inode(parent.dentry),
355-
dentry, NULL);
356-
if (!err || err == -ENOENT)
357-
deleted = 1;
358-
}
359-
} else {
360-
err = -ENOENT;
333+
p.mnt = parent.mnt;
334+
p.dentry = dentry;
335+
err = vfs_getattr(&p, &stat, STATX_TYPE | STATX_MODE,
336+
AT_STATX_SYNC_AS_STAT);
337+
if (!err && dev_mynode(dev, d_inode(dentry), &stat)) {
338+
struct iattr newattrs;
339+
/*
340+
* before unlinking this node, reset permissions
341+
* of possible references like hardlinks
342+
*/
343+
newattrs.ia_uid = GLOBAL_ROOT_UID;
344+
newattrs.ia_gid = GLOBAL_ROOT_GID;
345+
newattrs.ia_mode = stat.mode & ~0777;
346+
newattrs.ia_valid =
347+
ATTR_UID|ATTR_GID|ATTR_MODE;
348+
inode_lock(d_inode(dentry));
349+
notify_change(&nop_mnt_idmap, dentry, &newattrs, NULL);
350+
inode_unlock(d_inode(dentry));
351+
err = vfs_unlink(&nop_mnt_idmap, d_inode(parent.dentry),
352+
dentry, NULL);
353+
if (!err || err == -ENOENT)
354+
deleted = 1;
361355
}
362356
dput(dentry);
363357
inode_unlock(d_inode(parent.dentry));

fs/9p/vfs_inode.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,8 @@ v9fs_vfs_create(struct mnt_idmap *idmap, struct inode *dir,
669669
*
670670
*/
671671

672-
static int v9fs_vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
673-
struct dentry *dentry, umode_t mode)
672+
static struct dentry *v9fs_vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
673+
struct dentry *dentry, umode_t mode)
674674
{
675675
int err;
676676
u32 perm;
@@ -692,8 +692,7 @@ static int v9fs_vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
692692

693693
if (fid)
694694
p9_fid_put(fid);
695-
696-
return err;
695+
return ERR_PTR(err);
697696
}
698697

699698
/**

fs/9p/vfs_inode_dotl.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,9 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
350350
*
351351
*/
352352

353-
static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
354-
struct inode *dir, struct dentry *dentry,
355-
umode_t omode)
353+
static struct dentry *v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
354+
struct inode *dir, struct dentry *dentry,
355+
umode_t omode)
356356
{
357357
int err;
358358
struct v9fs_session_info *v9ses;
@@ -417,7 +417,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
417417
p9_fid_put(fid);
418418
v9fs_put_acl(dacl, pacl);
419419
p9_fid_put(dfid);
420-
return err;
420+
return ERR_PTR(err);
421421
}
422422

423423
static int

fs/affs/affs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry, unsi
168168
extern int affs_unlink(struct inode *dir, struct dentry *dentry);
169169
extern int affs_create(struct mnt_idmap *idmap, struct inode *dir,
170170
struct dentry *dentry, umode_t mode, bool);
171-
extern int affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
171+
extern struct dentry *affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
172172
struct dentry *dentry, umode_t mode);
173173
extern int affs_rmdir(struct inode *dir, struct dentry *dentry);
174174
extern int affs_link(struct dentry *olddentry, struct inode *dir,

fs/affs/namei.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ affs_create(struct mnt_idmap *idmap, struct inode *dir,
273273
return 0;
274274
}
275275

276-
int
276+
struct dentry *
277277
affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
278278
struct dentry *dentry, umode_t mode)
279279
{
@@ -285,7 +285,7 @@ affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
285285

286286
inode = affs_new_inode(dir);
287287
if (!inode)
288-
return -ENOSPC;
288+
return ERR_PTR(-ENOSPC);
289289

290290
inode->i_mode = S_IFDIR | mode;
291291
affs_mode_to_prot(inode);
@@ -298,9 +298,9 @@ affs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
298298
clear_nlink(inode);
299299
mark_inode_dirty(inode);
300300
iput(inode);
301-
return error;
301+
return ERR_PTR(error);
302302
}
303-
return 0;
303+
return NULL;
304304
}
305305

306306
int

fs/afs/dir.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ static bool afs_lookup_filldir(struct dir_context *ctx, const char *name, int nl
3333
loff_t fpos, u64 ino, unsigned dtype);
3434
static int afs_create(struct mnt_idmap *idmap, struct inode *dir,
3535
struct dentry *dentry, umode_t mode, bool excl);
36-
static int afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
37-
struct dentry *dentry, umode_t mode);
36+
static struct dentry *afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
37+
struct dentry *dentry, umode_t mode);
3838
static int afs_rmdir(struct inode *dir, struct dentry *dentry);
3939
static int afs_unlink(struct inode *dir, struct dentry *dentry);
4040
static int afs_link(struct dentry *from, struct inode *dir,
@@ -1315,8 +1315,8 @@ static const struct afs_operation_ops afs_mkdir_operation = {
13151315
/*
13161316
* create a directory on an AFS filesystem
13171317
*/
1318-
static int afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
1319-
struct dentry *dentry, umode_t mode)
1318+
static struct dentry *afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
1319+
struct dentry *dentry, umode_t mode)
13201320
{
13211321
struct afs_operation *op;
13221322
struct afs_vnode *dvnode = AFS_FS_I(dir);
@@ -1328,7 +1328,7 @@ static int afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
13281328
op = afs_alloc_operation(NULL, dvnode->volume);
13291329
if (IS_ERR(op)) {
13301330
d_drop(dentry);
1331-
return PTR_ERR(op);
1331+
return ERR_CAST(op);
13321332
}
13331333

13341334
fscache_use_cookie(afs_vnode_cache(dvnode), true);
@@ -1344,7 +1344,7 @@ static int afs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
13441344
op->ops = &afs_mkdir_operation;
13451345
ret = afs_do_sync_operation(op);
13461346
afs_dir_unuse_cookie(dvnode, ret);
1347-
return ret;
1347+
return ERR_PTR(ret);
13481348
}
13491349

13501350
/*

fs/autofs/root.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ static int autofs_dir_symlink(struct mnt_idmap *, struct inode *,
1515
struct dentry *, const char *);
1616
static int autofs_dir_unlink(struct inode *, struct dentry *);
1717
static int autofs_dir_rmdir(struct inode *, struct dentry *);
18-
static int autofs_dir_mkdir(struct mnt_idmap *, struct inode *,
19-
struct dentry *, umode_t);
18+
static struct dentry *autofs_dir_mkdir(struct mnt_idmap *, struct inode *,
19+
struct dentry *, umode_t);
2020
static long autofs_root_ioctl(struct file *, unsigned int, unsigned long);
2121
#ifdef CONFIG_COMPAT
2222
static long autofs_root_compat_ioctl(struct file *,
@@ -720,9 +720,9 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
720720
return 0;
721721
}
722722

723-
static int autofs_dir_mkdir(struct mnt_idmap *idmap,
724-
struct inode *dir, struct dentry *dentry,
725-
umode_t mode)
723+
static struct dentry *autofs_dir_mkdir(struct mnt_idmap *idmap,
724+
struct inode *dir, struct dentry *dentry,
725+
umode_t mode)
726726
{
727727
struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
728728
struct autofs_info *ino = autofs_dentry_ino(dentry);
@@ -739,7 +739,7 @@ static int autofs_dir_mkdir(struct mnt_idmap *idmap,
739739

740740
inode = autofs_get_inode(dir->i_sb, S_IFDIR | mode);
741741
if (!inode)
742-
return -ENOMEM;
742+
return ERR_PTR(-ENOMEM);
743743
d_add(dentry, inode);
744744

745745
if (sbi->version < 5)
@@ -751,7 +751,7 @@ static int autofs_dir_mkdir(struct mnt_idmap *idmap,
751751
inc_nlink(dir);
752752
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
753753

754-
return 0;
754+
return NULL;
755755
}
756756

757757
/* Get/set timeout ioctl() operation */

0 commit comments

Comments
 (0)