case -EBUSY:
/* someone else made a mount here whilst we were busy */
while (d_mountpoint(nd->path.dentry) &&
- follow_down(&nd->path.mnt, &nd->path.dentry))
+ follow_down(&nd->path))
;
err = 0;
default:
}
path.mnt = mnt;
path_get(&path);
- if (!follow_down(&path.mnt, &path.dentry)) {
+ if (!follow_down(&path)) {
path_put(&path);
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
continue;
}
- while (d_mountpoint(path.dentry) &&
- follow_down(&path.mnt, &path.dentry))
+ while (d_mountpoint(path.dentry) && follow_down(&path));
;
umount_ok = may_umount(path.mnt);
path_put(&path);
int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
void autofs4_catatonic_mode(struct autofs_sb_info *);
-static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+static inline int autofs4_follow_mount(struct path *path)
{
int res = 0;
- while (d_mountpoint(*dentry)) {
- int followed = follow_down(mnt, dentry);
+ while (d_mountpoint(path->dentry)) {
+ int followed = follow_down(path);
if (!followed)
break;
res = 1;
err = have_submounts(path.dentry);
if (path.mnt->mnt_mountpoint != path.mnt->mnt_root) {
- if (follow_down(&path.mnt, &path.dentry))
+ if (follow_down(&path))
magic = path.mnt->mnt_sb->s_magic;
}
}
static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
{
struct dentry *top = dentry;
+ struct path path = {.mnt = mnt, .dentry = dentry};
int status = 1;
DPRINTK("dentry %p %.*s",
dentry, (int)dentry->d_name.len, dentry->d_name.name);
- mntget(mnt);
- dget(dentry);
+ path_get(&path);
- if (!follow_down(&mnt, &dentry))
+ if (!follow_down(&path))
goto done;
- if (is_autofs4_dentry(dentry)) {
- struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
+ if (is_autofs4_dentry(path.dentry)) {
+ struct autofs_sb_info *sbi = autofs4_sbi(path.dentry->d_sb);
/* This is an autofs submount, we can't expire it */
if (autofs_type_indirect(sbi->type))
* Otherwise it's an offset mount and we need to check
* if we can umount its mount, if there is one.
*/
- if (!d_mountpoint(dentry)) {
+ if (!d_mountpoint(path.dentry)) {
status = 0;
goto done;
}
status = 0;
done:
DPRINTK("returning = %d", status);
- dput(dentry);
- mntput(mnt);
+ path_put(&path);
return status;
}
nd->flags);
/*
* For an expire of a covered direct or offset mount we need
- * to beeak out of follow_down() at the autofs mount trigger
+ * to break out of follow_down() at the autofs mount trigger
* (d_mounted--), so we can see the expiring flag, and manage
* the blocking and following here until the expire is completed.
*/
if (ino->flags & AUTOFS_INF_EXPIRING) {
spin_unlock(&sbi->fs_lock);
/* Follow down to our covering mount. */
- if (!follow_down(&nd->path.mnt, &nd->path.dentry))
+ if (!follow_down(&nd->path))
goto done;
goto follow;
}
* to follow it.
*/
if (d_mountpoint(dentry)) {
- if (!autofs4_follow_mount(&nd->path.mnt,
- &nd->path.dentry)) {
+ if (!autofs4_follow_mount(&nd->path)) {
status = -ENOENT;
goto out_error;
}
case -EBUSY:
/* someone else made a mount here whilst we were busy */
while (d_mountpoint(nd->path.dentry) &&
- follow_down(&nd->path.mnt, &nd->path.dentry))
+ follow_down(&nd->path))
;
err = 0;
default:
/* no need for dcache_lock, as serialization is taken care in
* namespace.c
*/
-int follow_down(struct vfsmount **mnt, struct dentry **dentry)
+int follow_down(struct path *path)
{
struct vfsmount *mounted;
- mounted = lookup_mnt(*mnt, *dentry);
+ mounted = lookup_mnt(path->mnt, path->dentry);
if (mounted) {
- dput(*dentry);
- mntput(*mnt);
- *mnt = mounted;
- *dentry = dget(mounted->mnt_root);
+ dput(path->dentry);
+ mntput(path->mnt);
+ path->mnt = mounted;
+ path->dentry = dget(mounted->mnt_root);
return 1;
}
return 0;
down_write(&namespace_sem);
while (d_mountpoint(path->dentry) &&
- follow_down(&path->mnt, &path->dentry))
+ follow_down(path))
;
err = -EINVAL;
if (!check_mnt(path->mnt) || !check_mnt(old_path.mnt))
down_write(&namespace_sem);
/* Something was mounted here while we slept */
while (d_mountpoint(path->dentry) &&
- follow_down(&path->mnt, &path->dentry))
+ follow_down(path))
;
err = -EINVAL;
if (!(mnt_flags & MNT_SHRINKABLE) && !check_mnt(path->mnt))
goto out;
out_follow:
while (d_mountpoint(nd->path.dentry) &&
- follow_down(&nd->path.mnt, &nd->path.dentry))
+ follow_down(&nd->path))
;
err = 0;
goto out;
.dentry = dget(dentry)};
int err = 0;
- while (follow_down(&path.mnt, &path.dentry) &&
- d_mountpoint(path.dentry))
+ while (d_mountpoint(path.dentry) && follow_down(&path))
;
exp2 = rqst_exp_get_by_name(rqstp, &path);
extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
extern struct dentry *lookup_one_noperm(const char *, struct dentry *);
-extern int follow_down(struct vfsmount **, struct dentry **);
+extern int follow_down(struct path *);
extern int follow_up(struct path *);
extern struct dentry *lock_rename(struct dentry *, struct dentry *);