Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a63bb996 authored by Al Viro's avatar Al Viro
Browse files

[PATCH] switch nfsd to kern_path()



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent c1a2a475
Loading
Loading
Loading
Loading
+23 −25
Original line number Original line Diff line number Diff line
@@ -162,20 +162,18 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
			cache_put(&ek->h, &svc_expkey_cache);
			cache_put(&ek->h, &svc_expkey_cache);
		else err = -ENOMEM;
		else err = -ENOMEM;
	} else {
	} else {
		struct nameidata nd;
		err = kern_path(buf, 0, &key.ek_path);
		err = path_lookup(buf, 0, &nd);
		if (err)
		if (err)
			goto out;
			goto out;


		dprintk("Found the path %s\n", buf);
		dprintk("Found the path %s\n", buf);
		key.ek_path = nd.path;


		ek = svc_expkey_update(&key, ek);
		ek = svc_expkey_update(&key, ek);
		if (ek)
		if (ek)
			cache_put(&ek->h, &svc_expkey_cache);
			cache_put(&ek->h, &svc_expkey_cache);
		else
		else
			err = -ENOMEM;
			err = -ENOMEM;
		path_put(&nd.path);
		path_put(&key.ek_path);
	}
	}
	cache_flush();
	cache_flush();
 out:
 out:
@@ -991,7 +989,7 @@ exp_export(struct nfsctl_export *nxp)
	struct svc_export	*exp = NULL;
	struct svc_export	*exp = NULL;
	struct svc_export	new;
	struct svc_export	new;
	struct svc_expkey	*fsid_key = NULL;
	struct svc_expkey	*fsid_key = NULL;
	struct nameidata nd;
	struct path path;
	int		err;
	int		err;


	/* Consistency check */
	/* Consistency check */
@@ -1014,12 +1012,12 @@ exp_export(struct nfsctl_export *nxp)




	/* Look up the dentry */
	/* Look up the dentry */
	err = path_lookup(nxp->ex_path, 0, &nd);
	err = kern_path(nxp->ex_path, 0, &path);
	if (err)
	if (err)
		goto out_put_clp;
		goto out_put_clp;
	err = -EINVAL;
	err = -EINVAL;


	exp = exp_get_by_name(clp, nd.path.mnt, nd.path.dentry, NULL);
	exp = exp_get_by_name(clp, path.mnt, path.dentry, NULL);


	memset(&new, 0, sizeof(new));
	memset(&new, 0, sizeof(new));


@@ -1027,8 +1025,8 @@ exp_export(struct nfsctl_export *nxp)
	if ((nxp->ex_flags & NFSEXP_FSID) &&
	if ((nxp->ex_flags & NFSEXP_FSID) &&
	    (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
	    (!IS_ERR(fsid_key = exp_get_fsid_key(clp, nxp->ex_dev))) &&
	    fsid_key->ek_path.mnt &&
	    fsid_key->ek_path.mnt &&
	    (fsid_key->ek_path.mnt != nd.path.mnt ||
	    (fsid_key->ek_path.mnt != path.mnt ||
	     fsid_key->ek_path.dentry != nd.path.dentry))
	     fsid_key->ek_path.dentry != path.dentry))
		goto finish;
		goto finish;


	if (!IS_ERR(exp)) {
	if (!IS_ERR(exp)) {
@@ -1044,7 +1042,7 @@ exp_export(struct nfsctl_export *nxp)
		goto finish;
		goto finish;
	}
	}


	err = check_export(nd.path.dentry->d_inode, nxp->ex_flags, NULL);
	err = check_export(path.dentry->d_inode, nxp->ex_flags, NULL);
	if (err) goto finish;
	if (err) goto finish;


	err = -ENOMEM;
	err = -ENOMEM;
@@ -1057,7 +1055,7 @@ exp_export(struct nfsctl_export *nxp)
	if (!new.ex_pathname)
	if (!new.ex_pathname)
		goto finish;
		goto finish;
	new.ex_client = clp;
	new.ex_client = clp;
	new.ex_path = nd.path;
	new.ex_path = path;
	new.ex_flags = nxp->ex_flags;
	new.ex_flags = nxp->ex_flags;
	new.ex_anon_uid = nxp->ex_anon_uid;
	new.ex_anon_uid = nxp->ex_anon_uid;
	new.ex_anon_gid = nxp->ex_anon_gid;
	new.ex_anon_gid = nxp->ex_anon_gid;
@@ -1083,7 +1081,7 @@ exp_export(struct nfsctl_export *nxp)
		exp_put(exp);
		exp_put(exp);
	if (fsid_key && !IS_ERR(fsid_key))
	if (fsid_key && !IS_ERR(fsid_key))
		cache_put(&fsid_key->h, &svc_expkey_cache);
		cache_put(&fsid_key->h, &svc_expkey_cache);
	path_put(&nd.path);
	path_put(&path);
out_put_clp:
out_put_clp:
	auth_domain_put(clp);
	auth_domain_put(clp);
out_unlock:
out_unlock:
@@ -1114,7 +1112,7 @@ exp_unexport(struct nfsctl_export *nxp)
{
{
	struct auth_domain *dom;
	struct auth_domain *dom;
	svc_export *exp;
	svc_export *exp;
	struct nameidata nd;
	struct path path;
	int		err;
	int		err;


	/* Consistency check */
	/* Consistency check */
@@ -1131,13 +1129,13 @@ exp_unexport(struct nfsctl_export *nxp)
		goto out_unlock;
		goto out_unlock;
	}
	}


	err = path_lookup(nxp->ex_path, 0, &nd);
	err = kern_path(nxp->ex_path, 0, &path);
	if (err)
	if (err)
		goto out_domain;
		goto out_domain;


	err = -EINVAL;
	err = -EINVAL;
	exp = exp_get_by_name(dom, nd.path.mnt, nd.path.dentry, NULL);
	exp = exp_get_by_name(dom, path.mnt, path.dentry, NULL);
	path_put(&nd.path);
	path_put(&path);
	if (IS_ERR(exp))
	if (IS_ERR(exp))
		goto out_domain;
		goto out_domain;


@@ -1159,26 +1157,26 @@ exp_unexport(struct nfsctl_export *nxp)
 * since its harder to fool a kernel module than a user space program.
 * since its harder to fool a kernel module than a user space program.
 */
 */
int
int
exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
exp_rootfh(svc_client *clp, char *name, struct knfsd_fh *f, int maxsize)
{
{
	struct svc_export	*exp;
	struct svc_export	*exp;
	struct nameidata	nd;
	struct path		path;
	struct inode		*inode;
	struct inode		*inode;
	struct svc_fh		fh;
	struct svc_fh		fh;
	int			err;
	int			err;


	err = -EPERM;
	err = -EPERM;
	/* NB: we probably ought to check that it's NUL-terminated */
	/* NB: we probably ought to check that it's NUL-terminated */
	if (path_lookup(path, 0, &nd)) {
	if (kern_path(name, 0, &path)) {
		printk("nfsd: exp_rootfh path not found %s", path);
		printk("nfsd: exp_rootfh path not found %s", name);
		return err;
		return err;
	}
	}
	inode = nd.path.dentry->d_inode;
	inode = path.dentry->d_inode;


	dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
	dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
		 path, nd.path.dentry, clp->name,
		 name, path.dentry, clp->name,
		 inode->i_sb->s_id, inode->i_ino);
		 inode->i_sb->s_id, inode->i_ino);
	exp = exp_parent(clp, nd.path.mnt, nd.path.dentry, NULL);
	exp = exp_parent(clp, path.mnt, path.dentry, NULL);
	if (IS_ERR(exp)) {
	if (IS_ERR(exp)) {
		err = PTR_ERR(exp);
		err = PTR_ERR(exp);
		goto out;
		goto out;
@@ -1188,7 +1186,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
	 * fh must be initialized before calling fh_compose
	 * fh must be initialized before calling fh_compose
	 */
	 */
	fh_init(&fh, maxsize);
	fh_init(&fh, maxsize);
	if (fh_compose(&fh, exp, nd.path.dentry, NULL))
	if (fh_compose(&fh, exp, path.dentry, NULL))
		err = -EINVAL;
		err = -EINVAL;
	else
	else
		err = 0;
		err = 0;
@@ -1196,7 +1194,7 @@ exp_rootfh(svc_client *clp, char *path, struct knfsd_fh *f, int maxsize)
	fh_put(&fh);
	fh_put(&fh);
	exp_put(exp);
	exp_put(exp);
out:
out:
	path_put(&nd.path);
	path_put(&path);
	return err;
	return err;
}
}


+25 −25
Original line number Original line Diff line number Diff line
@@ -51,7 +51,7 @@
#define NFSDDBG_FACILITY                NFSDDBG_PROC
#define NFSDDBG_FACILITY                NFSDDBG_PROC


/* Globals */
/* Globals */
static struct nameidata rec_dir;
static struct path rec_dir;
static int rec_dir_init = 0;
static int rec_dir_init = 0;


static void
static void
@@ -121,9 +121,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
static void
static void
nfsd4_sync_rec_dir(void)
nfsd4_sync_rec_dir(void)
{
{
	mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
	nfsd_sync_dir(rec_dir.path.dentry);
	nfsd_sync_dir(rec_dir.dentry);
	mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
}
}


int
int
@@ -143,9 +143,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
	nfs4_save_user(&uid, &gid);
	nfs4_save_user(&uid, &gid);


	/* lock the parent */
	/* lock the parent */
	mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);


	dentry = lookup_one_len(dname, rec_dir.path.dentry, HEXDIR_LEN-1);
	dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
	if (IS_ERR(dentry)) {
	if (IS_ERR(dentry)) {
		status = PTR_ERR(dentry);
		status = PTR_ERR(dentry);
		goto out_unlock;
		goto out_unlock;
@@ -155,15 +155,15 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
		dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
		dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
		goto out_put;
		goto out_put;
	}
	}
	status = mnt_want_write(rec_dir.path.mnt);
	status = mnt_want_write(rec_dir.mnt);
	if (status)
	if (status)
		goto out_put;
		goto out_put;
	status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU);
	status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
	mnt_drop_write(rec_dir.path.mnt);
	mnt_drop_write(rec_dir.mnt);
out_put:
out_put:
	dput(dentry);
	dput(dentry);
out_unlock:
out_unlock:
	mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
	if (status == 0) {
	if (status == 0) {
		clp->cl_firststate = 1;
		clp->cl_firststate = 1;
		nfsd4_sync_rec_dir();
		nfsd4_sync_rec_dir();
@@ -226,7 +226,7 @@ nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)


	nfs4_save_user(&uid, &gid);
	nfs4_save_user(&uid, &gid);


	filp = dentry_open(dget(dir), mntget(rec_dir.path.mnt), O_RDONLY);
	filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
	status = PTR_ERR(filp);
	status = PTR_ERR(filp);
	if (IS_ERR(filp))
	if (IS_ERR(filp))
		goto out;
		goto out;
@@ -291,9 +291,9 @@ nfsd4_unlink_clid_dir(char *name, int namlen)


	dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
	dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);


	mutex_lock(&rec_dir.path.dentry->d_inode->i_mutex);
	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
	dentry = lookup_one_len(name, rec_dir.path.dentry, namlen);
	dentry = lookup_one_len(name, rec_dir.dentry, namlen);
	mutex_unlock(&rec_dir.path.dentry->d_inode->i_mutex);
	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
	if (IS_ERR(dentry)) {
	if (IS_ERR(dentry)) {
		status = PTR_ERR(dentry);
		status = PTR_ERR(dentry);
		return status;
		return status;
@@ -302,7 +302,7 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
	if (!dentry->d_inode)
	if (!dentry->d_inode)
		goto out;
		goto out;


	status = nfsd4_clear_clid_dir(rec_dir.path.dentry, dentry);
	status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
out:
out:
	dput(dentry);
	dput(dentry);
	return status;
	return status;
@@ -318,7 +318,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
	if (!rec_dir_init || !clp->cl_firststate)
	if (!rec_dir_init || !clp->cl_firststate)
		return;
		return;


	status = mnt_want_write(rec_dir.path.mnt);
	status = mnt_want_write(rec_dir.mnt);
	if (status)
	if (status)
		goto out;
		goto out;
	clp->cl_firststate = 0;
	clp->cl_firststate = 0;
@@ -327,7 +327,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
	nfs4_reset_user(uid, gid);
	nfs4_reset_user(uid, gid);
	if (status == 0)
	if (status == 0)
		nfsd4_sync_rec_dir();
		nfsd4_sync_rec_dir();
	mnt_drop_write(rec_dir.path.mnt);
	mnt_drop_write(rec_dir.mnt);
out:
out:
	if (status)
	if (status)
		printk("NFSD: Failed to remove expired client state directory"
		printk("NFSD: Failed to remove expired client state directory"
@@ -357,17 +357,17 @@ nfsd4_recdir_purge_old(void) {


	if (!rec_dir_init)
	if (!rec_dir_init)
		return;
		return;
	status = mnt_want_write(rec_dir.path.mnt);
	status = mnt_want_write(rec_dir.mnt);
	if (status)
	if (status)
		goto out;
		goto out;
	status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old);
	status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
	if (status == 0)
	if (status == 0)
		nfsd4_sync_rec_dir();
		nfsd4_sync_rec_dir();
	mnt_drop_write(rec_dir.path.mnt);
	mnt_drop_write(rec_dir.mnt);
out:
out:
	if (status)
	if (status)
		printk("nfsd4: failed to purge old clients from recovery"
		printk("nfsd4: failed to purge old clients from recovery"
			" directory %s\n", rec_dir.path.dentry->d_name.name);
			" directory %s\n", rec_dir.dentry->d_name.name);
}
}


static int
static int
@@ -387,10 +387,10 @@ int
nfsd4_recdir_load(void) {
nfsd4_recdir_load(void) {
	int status;
	int status;


	status = nfsd4_list_rec_dir(rec_dir.path.dentry, load_recdir);
	status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir);
	if (status)
	if (status)
		printk("nfsd4: failed loading clients from recovery"
		printk("nfsd4: failed loading clients from recovery"
			" directory %s\n", rec_dir.path.dentry->d_name.name);
			" directory %s\n", rec_dir.dentry->d_name.name);
	return status;
	return status;
}
}


@@ -412,7 +412,7 @@ nfsd4_init_recdir(char *rec_dirname)


	nfs4_save_user(&uid, &gid);
	nfs4_save_user(&uid, &gid);


	status = path_lookup(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
	status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
			&rec_dir);
			&rec_dir);
	if (status)
	if (status)
		printk("NFSD: unable to find recovery directory %s\n",
		printk("NFSD: unable to find recovery directory %s\n",
@@ -429,5 +429,5 @@ nfsd4_shutdown_recdir(void)
	if (!rec_dir_init)
	if (!rec_dir_init)
		return;
		return;
	rec_dir_init = 0;
	rec_dir_init = 0;
	path_put(&rec_dir.path);
	path_put(&rec_dir);
}
}
+4 −4
Original line number Original line Diff line number Diff line
@@ -3284,17 +3284,17 @@ int
nfs4_reset_recoverydir(char *recdir)
nfs4_reset_recoverydir(char *recdir)
{
{
	int status;
	int status;
	struct nameidata nd;
	struct path path;


	status = path_lookup(recdir, LOOKUP_FOLLOW, &nd);
	status = kern_path(recdir, LOOKUP_FOLLOW, &path);
	if (status)
	if (status)
		return status;
		return status;
	status = -ENOTDIR;
	status = -ENOTDIR;
	if (S_ISDIR(nd.path.dentry->d_inode->i_mode)) {
	if (S_ISDIR(path.dentry->d_inode->i_mode)) {
		nfs4_set_recdir(recdir);
		nfs4_set_recdir(recdir);
		status = 0;
		status = 0;
	}
	}
	path_put(&nd.path);
	path_put(&path);
	return status;
	return status;
}
}


+4 −4
Original line number Original line Diff line number Diff line
@@ -341,7 +341,7 @@ static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)


static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
{
{
	struct nameidata nd;
	struct path path;
	char *fo_path;
	char *fo_path;
	int error;
	int error;


@@ -356,13 +356,13 @@ static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
	if (qword_get(&buf, fo_path, size) < 0)
	if (qword_get(&buf, fo_path, size) < 0)
		return -EINVAL;
		return -EINVAL;


	error = path_lookup(fo_path, 0, &nd);
	error = kern_path(fo_path, 0, &path);
	if (error)
	if (error)
		return error;
		return error;


	error = nlmsvc_unlock_all_by_sb(nd.path.mnt->mnt_sb);
	error = nlmsvc_unlock_all_by_sb(path.mnt->mnt_sb);


	path_put(&nd.path);
	path_put(&path);
	return error;
	return error;
}
}