Loading fs/nfsd/vfs.c +16 −23 Original line number Diff line number Diff line Loading @@ -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; } /* Loading Loading
fs/nfsd/vfs.c +16 −23 Original line number Diff line number Diff line Loading @@ -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; } /* Loading