diff options
author | Dave Hansen <haveblue@us.ibm.com> | 2008-02-15 17:37:45 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-19 00:25:34 -0400 |
commit | 75c3f29de7451677c59580b0a959f694f36aac28 (patch) | |
tree | c82ad50102bfa38f2dc6bb0f763cde9f3dff3790 | |
parent | 463c3197263bd26ac59a00d2484990e17e35c50e (diff) |
[PATCH] r/o bind mounts: write counts for link/symlink
[AV: add missing nfsd pieces]
Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/namei.c | 10 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 14 |
2 files changed, 23 insertions, 1 deletions
diff --git a/fs/namei.c b/fs/namei.c index 3fbcf2021a2e..00df735fb509 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2387,7 +2387,12 @@ asmlinkage long sys_symlinkat(const char __user *oldname, | |||
2387 | if (IS_ERR(dentry)) | 2387 | if (IS_ERR(dentry)) |
2388 | goto out_unlock; | 2388 | goto out_unlock; |
2389 | 2389 | ||
2390 | error = mnt_want_write(nd.path.mnt); | ||
2391 | if (error) | ||
2392 | goto out_dput; | ||
2390 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); | 2393 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); |
2394 | mnt_drop_write(nd.path.mnt); | ||
2395 | out_dput: | ||
2391 | dput(dentry); | 2396 | dput(dentry); |
2392 | out_unlock: | 2397 | out_unlock: |
2393 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2398 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
@@ -2482,7 +2487,12 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, | |||
2482 | error = PTR_ERR(new_dentry); | 2487 | error = PTR_ERR(new_dentry); |
2483 | if (IS_ERR(new_dentry)) | 2488 | if (IS_ERR(new_dentry)) |
2484 | goto out_unlock; | 2489 | goto out_unlock; |
2490 | error = mnt_want_write(nd.path.mnt); | ||
2491 | if (error) | ||
2492 | goto out_dput; | ||
2485 | error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); | 2493 | error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); |
2494 | mnt_drop_write(nd.path.mnt); | ||
2495 | out_dput: | ||
2486 | dput(new_dentry); | 2496 | dput(new_dentry); |
2487 | out_unlock: | 2497 | out_unlock: |
2488 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2498 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 14d582467029..71f899482306 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1542,6 +1542,10 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1542 | if (iap && (iap->ia_valid & ATTR_MODE)) | 1542 | if (iap && (iap->ia_valid & ATTR_MODE)) |
1543 | mode = iap->ia_mode & S_IALLUGO; | 1543 | mode = iap->ia_mode & S_IALLUGO; |
1544 | 1544 | ||
1545 | host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); | ||
1546 | if (host_err) | ||
1547 | goto out_nfserr; | ||
1548 | |||
1545 | if (unlikely(path[plen] != 0)) { | 1549 | if (unlikely(path[plen] != 0)) { |
1546 | char *path_alloced = kmalloc(plen+1, GFP_KERNEL); | 1550 | char *path_alloced = kmalloc(plen+1, GFP_KERNEL); |
1547 | if (path_alloced == NULL) | 1551 | if (path_alloced == NULL) |
@@ -1562,6 +1566,8 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1562 | err = nfserrno(host_err); | 1566 | err = nfserrno(host_err); |
1563 | fh_unlock(fhp); | 1567 | fh_unlock(fhp); |
1564 | 1568 | ||
1569 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | ||
1570 | |||
1565 | cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); | 1571 | cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); |
1566 | dput(dnew); | 1572 | dput(dnew); |
1567 | if (err==0) err = cerr; | 1573 | if (err==0) err = cerr; |
@@ -1612,6 +1618,11 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
1612 | dold = tfhp->fh_dentry; | 1618 | dold = tfhp->fh_dentry; |
1613 | dest = dold->d_inode; | 1619 | dest = dold->d_inode; |
1614 | 1620 | ||
1621 | host_err = mnt_want_write(tfhp->fh_export->ex_path.mnt); | ||
1622 | if (host_err) { | ||
1623 | err = nfserrno(host_err); | ||
1624 | goto out_dput; | ||
1625 | } | ||
1615 | host_err = vfs_link(dold, dirp, dnew); | 1626 | host_err = vfs_link(dold, dirp, dnew); |
1616 | if (!host_err) { | 1627 | if (!host_err) { |
1617 | if (EX_ISSYNC(ffhp->fh_export)) { | 1628 | if (EX_ISSYNC(ffhp->fh_export)) { |
@@ -1625,7 +1636,8 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
1625 | else | 1636 | else |
1626 | err = nfserrno(host_err); | 1637 | err = nfserrno(host_err); |
1627 | } | 1638 | } |
1628 | 1639 | mnt_drop_write(tfhp->fh_export->ex_path.mnt); | |
1640 | out_dput: | ||
1629 | dput(dnew); | 1641 | dput(dnew); |
1630 | out_unlock: | 1642 | out_unlock: |
1631 | fh_unlock(ffhp); | 1643 | fh_unlock(ffhp); |