Skip to content

Commit 0f70f5b

Browse files
committed
Merge tag 'pull-automount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull automount updates from Al Viro: "Automount wart removal A bunch of odd boilerplate gone from instances - the reason for those was the need to protect the yet-to-be-attched mount from mark_mounts_for_expiry() deciding to take it out. But that's easy to detect and take care of in mark_mounts_for_expiry() itself; no need to have every instance simulate mount being busy by grabbing an extra reference to it, with finish_automount() undoing that once it attaches that mount. Should've done it that way from the very beginning... This is a flagday change, thankfully there are very few instances. vfs_submount() is gone - its sole remaining user (trace_automount) had been switched to saner primitives" * tag 'pull-automount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: kill vfs_submount() saner calling conventions for ->d_automount()
2 parents edb9448 + 2dbf6e0 commit 0f70f5b

File tree

11 files changed

+26
-46
lines changed

11 files changed

+26
-46
lines changed

Documentation/filesystems/porting.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,3 +1243,9 @@ arguments in the opposite order but is otherwise identical.
12431243

12441244
Using try_lookup_noperm() will require linux/namei.h to be included.
12451245

1246+
---
1247+
1248+
**mandatory**
1249+
1250+
Calling conventions for ->d_automount() have changed; we should *not* grab
1251+
an extra reference to new mount - it should be returned with refcount 1.

Documentation/filesystems/vfs.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,9 +1390,7 @@ defined:
13901390

13911391
If a vfsmount is returned, the caller will attempt to mount it
13921392
on the mountpoint and will remove the vfsmount from its
1393-
expiration list in the case of failure. The vfsmount should be
1394-
returned with 2 refs on it to prevent automatic expiration - the
1395-
caller will clean up the additional ref.
1393+
expiration list in the case of failure.
13961394

13971395
This function is only used if DCACHE_NEED_AUTOMOUNT is set on
13981396
the dentry. This is set by __d_instantiate() if S_AUTOMOUNT is

fs/afs/mntpt.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ struct vfsmount *afs_d_automount(struct path *path)
189189
if (IS_ERR(newmnt))
190190
return newmnt;
191191

192-
mntget(newmnt); /* prevent immediate expiration */
193192
mnt_set_expiry(newmnt, &afs_vfsmounts);
194193
queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer,
195194
afs_mntpt_expiry_timeout * HZ);

fs/fuse/dir.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,6 @@ static struct vfsmount *fuse_dentry_automount(struct path *path)
319319

320320
/* Create the submount */
321321
mnt = fc_mount(fsc);
322-
if (!IS_ERR(mnt))
323-
mntget(mnt);
324-
325322
put_fs_context(fsc);
326323
return mnt;
327324
}

fs/namespace.c

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,21 +1326,6 @@ struct vfsmount *vfs_kern_mount(struct file_system_type *type,
13261326
}
13271327
EXPORT_SYMBOL_GPL(vfs_kern_mount);
13281328

1329-
struct vfsmount *
1330-
vfs_submount(const struct dentry *mountpoint, struct file_system_type *type,
1331-
const char *name, void *data)
1332-
{
1333-
/* Until it is worked out how to pass the user namespace
1334-
* through from the parent mount to the submount don't support
1335-
* unprivileged mounts with submounts.
1336-
*/
1337-
if (mountpoint->d_sb->s_user_ns != &init_user_ns)
1338-
return ERR_PTR(-EPERM);
1339-
1340-
return vfs_kern_mount(type, SB_SUBMOUNT, name, data);
1341-
}
1342-
EXPORT_SYMBOL_GPL(vfs_submount);
1343-
13441329
static struct mount *clone_mnt(struct mount *old, struct dentry *root,
13451330
int flag)
13461331
{
@@ -3889,10 +3874,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
38893874
return PTR_ERR(m);
38903875

38913876
mnt = real_mount(m);
3892-
/* The new mount record should have at least 2 refs to prevent it being
3893-
* expired before we get a chance to add it
3894-
*/
3895-
BUG_ON(mnt_get_count(mnt) < 2);
38963877

38973878
if (m->mnt_sb == path->mnt->mnt_sb &&
38983879
m->mnt_root == dentry) {
@@ -3925,7 +3906,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
39253906
unlock_mount(mp);
39263907
if (unlikely(err))
39273908
goto discard;
3928-
mntput(m);
39293909
return 0;
39303910

39313911
discard_locked:
@@ -3939,7 +3919,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
39393919
namespace_unlock();
39403920
}
39413921
mntput(m);
3942-
mntput(m);
39433922
return err;
39443923
}
39453924

@@ -3976,11 +3955,14 @@ void mark_mounts_for_expiry(struct list_head *mounts)
39763955

39773956
/* extract from the expiration list every vfsmount that matches the
39783957
* following criteria:
3958+
* - already mounted
39793959
* - only referenced by its parent vfsmount
39803960
* - still marked for expiry (marked on the last call here; marks are
39813961
* cleared by mntput())
39823962
*/
39833963
list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
3964+
if (!is_mounted(&mnt->mnt))
3965+
continue;
39843966
if (!xchg(&mnt->mnt_expiry_mark, 1) ||
39853967
propagate_mount_busy(mnt, 1))
39863968
continue;

fs/nfs/namespace.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,6 @@ struct vfsmount *nfs_d_automount(struct path *path)
195195
if (IS_ERR(mnt))
196196
goto out_fc;
197197

198-
mntget(mnt); /* prevent immediate expiration */
199198
if (timeout <= 0)
200199
goto out_fc;
201200

fs/smb/client/namespace.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,6 @@ struct vfsmount *cifs_d_automount(struct path *path)
283283
return newmnt;
284284
}
285285

286-
mntget(newmnt); /* prevent immediate expiration */
287286
mnt_set_expiry(newmnt, &cifs_automount_list);
288287
schedule_delayed_work(&cifs_automount_task,
289288
cifs_mountpoint_expiry_timeout);

fs/super.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -824,13 +824,6 @@ struct super_block *sget(struct file_system_type *type,
824824
struct super_block *old;
825825
int err;
826826

827-
/* We don't yet pass the user namespace of the parent
828-
* mount through to here so always use &init_user_ns
829-
* until that changes.
830-
*/
831-
if (flags & SB_SUBMOUNT)
832-
user_ns = &init_user_ns;
833-
834827
retry:
835828
spin_lock(&sb_lock);
836829
if (test) {
@@ -850,7 +843,7 @@ struct super_block *sget(struct file_system_type *type,
850843
}
851844
if (!s) {
852845
spin_unlock(&sb_lock);
853-
s = alloc_super(type, (flags & ~SB_SUBMOUNT), user_ns);
846+
s = alloc_super(type, flags, user_ns);
854847
if (!s)
855848
return ERR_PTR(-ENOMEM);
856849
goto retry;

include/linux/fs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1250,7 +1250,6 @@ extern int send_sigurg(struct file *file);
12501250
/* These sb flags are internal to the kernel */
12511251
#define SB_DEAD BIT(21)
12521252
#define SB_DYING BIT(24)
1253-
#define SB_SUBMOUNT BIT(26)
12541253
#define SB_FORCE BIT(27)
12551254
#define SB_NOSEC BIT(28)
12561255
#define SB_BORN BIT(29)

include/linux/mount.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ extern struct vfsmount *vfs_create_mount(struct fs_context *fc);
101101
extern struct vfsmount *vfs_kern_mount(struct file_system_type *type,
102102
int flags, const char *name,
103103
void *data);
104-
extern struct vfsmount *vfs_submount(const struct dentry *mountpoint,
105-
struct file_system_type *type,
106-
const char *name, void *data);
107104

108105
extern void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list);
109106
extern void mark_mounts_for_expiry(struct list_head *mounts);

kernel/trace/trace.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include <linux/workqueue.h>
5252
#include <linux/sort.h>
5353
#include <linux/io.h> /* vmap_page_range() */
54+
#include <linux/fs_context.h>
5455

5556
#include <asm/setup.h> /* COMMAND_LINE_SIZE */
5657

@@ -10241,6 +10242,8 @@ static struct vfsmount *trace_automount(struct dentry *mntpt, void *ingore)
1024110242
{
1024210243
struct vfsmount *mnt;
1024310244
struct file_system_type *type;
10245+
struct fs_context *fc;
10246+
int ret;
1024410247

1024510248
/*
1024610249
* To maintain backward compatibility for tools that mount
@@ -10250,12 +10253,20 @@ static struct vfsmount *trace_automount(struct dentry *mntpt, void *ingore)
1025010253
type = get_fs_type("tracefs");
1025110254
if (!type)
1025210255
return NULL;
10253-
mnt = vfs_submount(mntpt, type, "tracefs", NULL);
10256+
10257+
fc = fs_context_for_submount(type, mntpt);
1025410258
put_filesystem(type);
10255-
if (IS_ERR(mnt))
10256-
return NULL;
10257-
mntget(mnt);
10259+
if (IS_ERR(fc))
10260+
return ERR_CAST(fc);
10261+
10262+
ret = vfs_parse_fs_string(fc, "source",
10263+
"tracefs", strlen("tracefs"));
10264+
if (!ret)
10265+
mnt = fc_mount(fc);
10266+
else
10267+
mnt = ERR_PTR(ret);
1025810268

10269+
put_fs_context(fc);
1025910270
return mnt;
1026010271
}
1026110272

0 commit comments

Comments
 (0)