diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-05-27 16:11:23 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-05-27 16:11:23 -0400 |
commit | 4d7edbc34cccfc5a20c9c429c7757c34444a5fe2 (patch) | |
tree | c5f8696f43d73ed9cdb1dec0b1324c56bfb9b1f1 /fs/nfsd/vfs.c | |
parent | 104289576b33403a2c01097202a07dab74a5c231 (diff) |
nfsd_readlink(): switch to vfs_get_link()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 39 |
1 files changed, 16 insertions, 23 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 2be32955d7f2..6eef95c585e3 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1464,41 +1464,34 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1464 | __be32 | 1464 | __be32 |
1465 | nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) | 1465 | nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp) |
1466 | { | 1466 | { |
1467 | mm_segment_t oldfs; | ||
1468 | __be32 err; | 1467 | __be32 err; |
1469 | int host_err; | 1468 | const char *link; |
1470 | struct path path; | 1469 | struct path path; |
1470 | DEFINE_DELAYED_CALL(done); | ||
1471 | int len; | ||
1471 | 1472 | ||
1472 | err = fh_verify(rqstp, fhp, S_IFLNK, NFSD_MAY_NOP); | 1473 | err = fh_verify(rqstp, fhp, S_IFLNK, NFSD_MAY_NOP); |
1473 | if (err) | 1474 | if (unlikely(err)) |
1474 | goto out; | 1475 | return err; |
1475 | 1476 | ||
1476 | path.mnt = fhp->fh_export->ex_path.mnt; | 1477 | path.mnt = fhp->fh_export->ex_path.mnt; |
1477 | path.dentry = fhp->fh_dentry; | 1478 | path.dentry = fhp->fh_dentry; |
1478 | 1479 | ||
1479 | err = nfserr_inval; | 1480 | if (unlikely(!d_is_symlink(path.dentry))) |
1480 | if (!d_is_symlink(path.dentry)) | 1481 | return nfserr_inval; |
1481 | goto out; | ||
1482 | 1482 | ||
1483 | touch_atime(&path); | 1483 | touch_atime(&path); |
1484 | /* N.B. Why does this call need a get_fs()?? | ||
1485 | * Remove the set_fs and watch the fireworks:-) --okir | ||
1486 | */ | ||
1487 | 1484 | ||
1488 | oldfs = get_fs(); set_fs(KERNEL_DS); | 1485 | link = vfs_get_link(path.dentry, &done); |
1489 | host_err = vfs_readlink(path.dentry, (char __user *)buf, *lenp); | 1486 | if (IS_ERR(link)) |
1490 | set_fs(oldfs); | 1487 | return nfserrno(PTR_ERR(link)); |
1491 | 1488 | ||
1492 | if (host_err < 0) | 1489 | len = strlen(link); |
1493 | goto out_nfserr; | 1490 | if (len < *lenp) |
1494 | *lenp = host_err; | 1491 | *lenp = len; |
1495 | err = 0; | 1492 | memcpy(buf, link, *lenp); |
1496 | out: | 1493 | do_delayed_call(&done); |
1497 | return err; | 1494 | return 0; |
1498 | |||
1499 | out_nfserr: | ||
1500 | err = nfserrno(host_err); | ||
1501 | goto out; | ||
1502 | } | 1495 | } |
1503 | 1496 | ||
1504 | /* | 1497 | /* |