diff options
author | J. Bruce Fields <bfields@redhat.com> | 2011-01-11 13:55:46 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2011-01-13 21:04:09 -0500 |
commit | 4795bb37effb7b8fe77e2d2034545d062d3788a8 (patch) | |
tree | 1c87d2880d5552005cd7e845594672d0b4babc7f /fs/nfsd/vfs.c | |
parent | 6a76bebefe15d9a08864f824d7f8d5beaf37c997 (diff) |
nfsd: break lease on unlink, link, and rename
Any change to any of the links pointing to an entry should also break
delegations.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r-- | fs/nfsd/vfs.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index f97d4356431b..a110adbb3673 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -272,6 +272,13 @@ out: | |||
272 | return err; | 272 | return err; |
273 | } | 273 | } |
274 | 274 | ||
275 | static int nfsd_break_lease(struct inode *inode) | ||
276 | { | ||
277 | if (!S_ISREG(inode->i_mode)) | ||
278 | return 0; | ||
279 | return break_lease(inode, O_WRONLY | O_NONBLOCK); | ||
280 | } | ||
281 | |||
275 | /* | 282 | /* |
276 | * Commit metadata changes to stable storage. | 283 | * Commit metadata changes to stable storage. |
277 | */ | 284 | */ |
@@ -414,7 +421,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, | |||
414 | 421 | ||
415 | err = nfserr_notsync; | 422 | err = nfserr_notsync; |
416 | if (!check_guard || guardtime == inode->i_ctime.tv_sec) { | 423 | if (!check_guard || guardtime == inode->i_ctime.tv_sec) { |
417 | host_err = break_lease(inode, O_WRONLY | O_NONBLOCK); | 424 | host_err = nfsd_break_lease(inode); |
418 | if (host_err) | 425 | if (host_err) |
419 | goto out_nfserr; | 426 | goto out_nfserr; |
420 | fh_lock(fhp); | 427 | fh_lock(fhp); |
@@ -1639,6 +1646,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
1639 | err = nfserrno(host_err); | 1646 | err = nfserrno(host_err); |
1640 | goto out_dput; | 1647 | goto out_dput; |
1641 | } | 1648 | } |
1649 | err = nfserr_noent; | ||
1650 | if (!dold->d_inode) | ||
1651 | goto out_drop_write; | ||
1652 | host_err = nfsd_break_lease(dold->d_inode); | ||
1653 | if (host_err) | ||
1654 | goto out_drop_write; | ||
1642 | host_err = vfs_link(dold, dirp, dnew); | 1655 | host_err = vfs_link(dold, dirp, dnew); |
1643 | if (!host_err) { | 1656 | if (!host_err) { |
1644 | err = nfserrno(commit_metadata(ffhp)); | 1657 | err = nfserrno(commit_metadata(ffhp)); |
@@ -1650,6 +1663,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
1650 | else | 1663 | else |
1651 | err = nfserrno(host_err); | 1664 | err = nfserrno(host_err); |
1652 | } | 1665 | } |
1666 | out_drop_write: | ||
1653 | mnt_drop_write(tfhp->fh_export->ex_path.mnt); | 1667 | mnt_drop_write(tfhp->fh_export->ex_path.mnt); |
1654 | out_dput: | 1668 | out_dput: |
1655 | dput(dnew); | 1669 | dput(dnew); |
@@ -1731,15 +1745,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, | |||
1731 | if (host_err) | 1745 | if (host_err) |
1732 | goto out_dput_new; | 1746 | goto out_dput_new; |
1733 | 1747 | ||
1748 | host_err = nfsd_break_lease(odentry->d_inode); | ||
1749 | if (host_err) | ||
1750 | goto out_drop_write; | ||
1734 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); | 1751 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); |
1735 | if (!host_err) { | 1752 | if (!host_err) { |
1736 | host_err = commit_metadata(tfhp); | 1753 | host_err = commit_metadata(tfhp); |
1737 | if (!host_err) | 1754 | if (!host_err) |
1738 | host_err = commit_metadata(ffhp); | 1755 | host_err = commit_metadata(ffhp); |
1739 | } | 1756 | } |
1740 | 1757 | out_drop_write: | |
1741 | mnt_drop_write(ffhp->fh_export->ex_path.mnt); | 1758 | mnt_drop_write(ffhp->fh_export->ex_path.mnt); |
1742 | |||
1743 | out_dput_new: | 1759 | out_dput_new: |
1744 | dput(ndentry); | 1760 | dput(ndentry); |
1745 | out_dput_old: | 1761 | out_dput_old: |
@@ -1802,11 +1818,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
1802 | if (host_err) | 1818 | if (host_err) |
1803 | goto out_nfserr; | 1819 | goto out_nfserr; |
1804 | 1820 | ||
1821 | host_err = nfsd_break_lease(rdentry->d_inode); | ||
1822 | if (host_err) | ||
1823 | goto out_put; | ||
1805 | if (type != S_IFDIR) | 1824 | if (type != S_IFDIR) |
1806 | host_err = vfs_unlink(dirp, rdentry); | 1825 | host_err = vfs_unlink(dirp, rdentry); |
1807 | else | 1826 | else |
1808 | host_err = vfs_rmdir(dirp, rdentry); | 1827 | host_err = vfs_rmdir(dirp, rdentry); |
1809 | 1828 | out_put: | |
1810 | dput(rdentry); | 1829 | dput(rdentry); |
1811 | 1830 | ||
1812 | if (!host_err) | 1831 | if (!host_err) |