aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-01-11 13:55:46 -0500
committerJ. Bruce Fields <bfields@redhat.com>2011-01-13 21:04:09 -0500
commit4795bb37effb7b8fe77e2d2034545d062d3788a8 (patch)
tree1c87d2880d5552005cd7e845594672d0b4babc7f
parent6a76bebefe15d9a08864f824d7f8d5beaf37c997 (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>
-rw-r--r--fs/nfsd/vfs.c27
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
275static 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 }
1666out_drop_write:
1653 mnt_drop_write(tfhp->fh_export->ex_path.mnt); 1667 mnt_drop_write(tfhp->fh_export->ex_path.mnt);
1654out_dput: 1668out_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 1757out_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 1828out_put:
1810 dput(rdentry); 1829 dput(rdentry);
1811 1830
1812 if (!host_err) 1831 if (!host_err)