Esempio n. 1
0
/*
 * follow a link from a mountpoint directory, thus causing it to be mounted
 */
static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
{
	struct vfsmount *newmnt;
	int err;

	_enter("%p{%s},{%s:%p{%s},}",
	       dentry,
	       dentry->d_name.name,
	       nd->mnt->mnt_devname,
	       dentry,
	       nd->dentry->d_name.name);

	dput(nd->dentry);
	nd->dentry = dget(dentry);

	newmnt = afs_mntpt_do_automount(nd->dentry);
	if (IS_ERR(newmnt)) {
		path_release(nd);
		return (void *)newmnt;
	}

	mntget(newmnt);
	err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts);
	switch (err) {
	case 0:
		mntput(nd->mnt);
		dput(nd->dentry);
		nd->mnt = newmnt;
		nd->dentry = dget(newmnt->mnt_root);
		schedule_delayed_work(&afs_mntpt_expiry_timer,
				      afs_mntpt_expiry_timeout * HZ);
		break;
	case -EBUSY:
		/* someone else made a mount here whilst we were busy */
		while (d_mountpoint(nd->dentry) &&
		       follow_down(&nd->mnt, &nd->dentry))
			;
		err = 0;
	default:
		mntput(newmnt);
		break;
	}

	_leave(" = %d", err);
	return ERR_PTR(err);
}
Esempio n. 2
0
/*
 * handle an automount point
 */
struct vfsmount *afs_d_automount(struct path *path)
{
	struct vfsmount *newmnt;

	_enter("{%pd}", path->dentry);

	newmnt = afs_mntpt_do_automount(path->dentry);
	if (IS_ERR(newmnt))
		return newmnt;

	mntget(newmnt); /* prevent immediate expiration */
	mnt_set_expiry(newmnt, &afs_vfsmounts);
	queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer,
			   afs_mntpt_expiry_timeout * HZ);
	_leave(" = %p", newmnt);
	return newmnt;
}
Esempio n. 3
0
/*
 * follow a link from a mountpoint directory, thus causing it to be mounted
 */
static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
{
	struct vfsmount *newmnt;
	struct dentry *old_dentry;
	int err;

	kenter("%p{%s},{%s:%p{%s}}",
	       dentry,
	       dentry->d_name.name,
	       nd->mnt->mnt_devname,
	       dentry,
	       nd->dentry->d_name.name);

	newmnt = afs_mntpt_do_automount(dentry);
	if (IS_ERR(newmnt)) {
		path_release(nd);
		return (void *)newmnt;
	}

	old_dentry = nd->dentry;
	nd->dentry = dentry;
	err = do_add_mount(newmnt, nd, 0, &afs_vfsmounts);
	nd->dentry = old_dentry;

	path_release(nd);

	if (!err) {
		mntget(newmnt);
		nd->mnt = newmnt;
		dget(newmnt->mnt_root);
		nd->dentry = newmnt->mnt_root;
	}

	kleave(" = %d", err);
	return ERR_PTR(err);
} /* end afs_mntpt_follow_link() */