Skip to content

Commit 006ff74

Browse files
author
Al Viro
committed
saner calling conventions for ->d_automount()
Currently the calling conventions for ->d_automount() instances have an odd wart - returned new mount to be attached is expected to have refcount 2. That kludge is intended to make sure that mark_mounts_for_expiry() called before we get around to attaching that new mount to the tree won't decide to take it out. finish_automount() drops the extra reference after it's done with attaching mount to the tree - or drops the reference twice in case of error. ->d_automount() instances have rather counterintuitive boilerplate in them. There's a much simpler approach: have mark_mounts_for_expiry() skip the mounts that are yet to be mounted. And to hell with grabbing/dropping those extra references. Makes for simpler correctness analysis, at that... Reviewed-by: Christian Brauner <brauner@kernel.org> Reviewed-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com> Acked-by: David Howells <dhowells@redhat.com> Tested-by: David Howells <dhowells@redhat.com> Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 92a09c4 commit 006ff74

File tree

8 files changed

+11
-17
lines changed

8 files changed

+11
-17
lines changed

Documentation/filesystems/porting.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,3 +1203,10 @@ should use d_drop();d_splice_alias() and return the result of the latter.
12031203
If a positive dentry cannot be returned for some reason, in-kernel
12041204
clients such as cachefiles, nfsd, smb/server may not perform ideally but
12051205
will fail-safe.
1206+
1207+
---
1208+
1209+
**mandatory**
1210+
1211+
Calling conventions for ->d_automount() have changed; we should *not* grab
1212+
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
@@ -1411,9 +1411,7 @@ defined:
14111411

14121412
If a vfsmount is returned, the caller will attempt to mount it
14131413
on the mountpoint and will remove the vfsmount from its
1414-
expiration list in the case of failure. The vfsmount should be
1415-
returned with 2 refs on it to prevent automatic expiration - the
1416-
caller will clean up the additional ref.
1414+
expiration list in the case of failure.
14171415

14181416
This function is only used if DCACHE_NEED_AUTOMOUNT is set on
14191417
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 & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3902,10 +3902,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
39023902
return PTR_ERR(m);
39033903

39043904
mnt = real_mount(m);
3905-
/* The new mount record should have at least 2 refs to prevent it being
3906-
* expired before we get a chance to add it
3907-
*/
3908-
BUG_ON(mnt_get_count(mnt) < 2);
39093905

39103906
if (m->mnt_sb == path->mnt->mnt_sb &&
39113907
m->mnt_root == dentry) {
@@ -3938,7 +3934,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
39383934
unlock_mount(mp);
39393935
if (unlikely(err))
39403936
goto discard;
3941-
mntput(m);
39423937
return 0;
39433938

39443939
discard_locked:
@@ -3952,7 +3947,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
39523947
namespace_unlock();
39533948
}
39543949
mntput(m);
3955-
mntput(m);
39563950
return err;
39573951
}
39583952

@@ -3989,11 +3983,14 @@ void mark_mounts_for_expiry(struct list_head *mounts)
39893983

39903984
/* extract from the expiration list every vfsmount that matches the
39913985
* following criteria:
3986+
* - already mounted
39923987
* - only referenced by its parent vfsmount
39933988
* - still marked for expiry (marked on the last call here; marks are
39943989
* cleared by mntput())
39953990
*/
39963991
list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
3992+
if (!is_mounted(&mnt->mnt))
3993+
continue;
39973994
if (!xchg(&mnt->mnt_expiry_mark, 1) ||
39983995
propagate_mount_busy(mnt, 1))
39993996
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);

kernel/trace/trace.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10088,8 +10088,6 @@ static struct vfsmount *trace_automount(struct dentry *mntpt, void *ingore)
1008810088
put_filesystem(type);
1008910089
if (IS_ERR(mnt))
1009010090
return NULL;
10091-
mntget(mnt);
10092-
1009310091
return mnt;
1009410092
}
1009510093

0 commit comments

Comments
 (0)