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

Commit 4d7edbc3 authored by Al Viro's avatar Al Viro
Browse files

nfsd_readlink(): switch to vfs_get_link()



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 10428957
Loading
Loading
Loading
Loading
+16 −23
Original line number Diff line number Diff line
@@ -1464,41 +1464,34 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
__be32
nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
{
	mm_segment_t	oldfs;
	__be32		err;
	int		host_err;
	const char *link;
	struct path path;
	DEFINE_DELAYED_CALL(done);
	int len;

	err = fh_verify(rqstp, fhp, S_IFLNK, NFSD_MAY_NOP);
	if (err)
		goto out;
	if (unlikely(err))
		return err;

	path.mnt = fhp->fh_export->ex_path.mnt;
	path.dentry = fhp->fh_dentry;

	err = nfserr_inval;
	if (!d_is_symlink(path.dentry))
		goto out;
	if (unlikely(!d_is_symlink(path.dentry)))
		return nfserr_inval;

	touch_atime(&path);
	/* N.B. Why does this call need a get_fs()??
	 * Remove the set_fs and watch the fireworks:-) --okir
	 */

	oldfs = get_fs(); set_fs(KERNEL_DS);
	host_err = vfs_readlink(path.dentry, (char __user *)buf, *lenp);
	set_fs(oldfs);

	if (host_err < 0)
		goto out_nfserr;
	*lenp = host_err;
	err = 0;
out:
	return err;
	link = vfs_get_link(path.dentry, &done);
	if (IS_ERR(link))
		return nfserrno(PTR_ERR(link));

out_nfserr:
	err = nfserrno(host_err);
	goto out;
	len = strlen(link);
	if (len < *lenp)
		*lenp = len;
	memcpy(buf, link, *lenp);
	do_delayed_call(&done);
	return 0;
}

/*