Commit 4795bb37 authored by J. Bruce Fields's avatar J. Bruce Fields

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: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 6a76bebe
...@@ -272,6 +272,13 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name, ...@@ -272,6 +272,13 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
return err; return err;
} }
static int nfsd_break_lease(struct inode *inode)
{
if (!S_ISREG(inode->i_mode))
return 0;
return break_lease(inode, O_WRONLY | O_NONBLOCK);
}
/* /*
* Commit metadata changes to stable storage. * Commit metadata changes to stable storage.
*/ */
...@@ -414,7 +421,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, ...@@ -414,7 +421,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
err = nfserr_notsync; err = nfserr_notsync;
if (!check_guard || guardtime == inode->i_ctime.tv_sec) { if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
host_err = break_lease(inode, O_WRONLY | O_NONBLOCK); host_err = nfsd_break_lease(inode);
if (host_err) if (host_err)
goto out_nfserr; goto out_nfserr;
fh_lock(fhp); fh_lock(fhp);
...@@ -1639,6 +1646,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, ...@@ -1639,6 +1646,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
err = nfserrno(host_err); err = nfserrno(host_err);
goto out_dput; goto out_dput;
} }
err = nfserr_noent;
if (!dold->d_inode)
goto out_drop_write;
host_err = nfsd_break_lease(dold->d_inode);
if (host_err)
goto out_drop_write;
host_err = vfs_link(dold, dirp, dnew); host_err = vfs_link(dold, dirp, dnew);
if (!host_err) { if (!host_err) {
err = nfserrno(commit_metadata(ffhp)); err = nfserrno(commit_metadata(ffhp));
...@@ -1650,6 +1663,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, ...@@ -1650,6 +1663,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
else else
err = nfserrno(host_err); err = nfserrno(host_err);
} }
out_drop_write:
mnt_drop_write(tfhp->fh_export->ex_path.mnt); mnt_drop_write(tfhp->fh_export->ex_path.mnt);
out_dput: out_dput:
dput(dnew); dput(dnew);
...@@ -1731,15 +1745,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, ...@@ -1731,15 +1745,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
if (host_err) if (host_err)
goto out_dput_new; goto out_dput_new;
host_err = nfsd_break_lease(odentry->d_inode);
if (host_err)
goto out_drop_write;
host_err = vfs_rename(fdir, odentry, tdir, ndentry); host_err = vfs_rename(fdir, odentry, tdir, ndentry);
if (!host_err) { if (!host_err) {
host_err = commit_metadata(tfhp); host_err = commit_metadata(tfhp);
if (!host_err) if (!host_err)
host_err = commit_metadata(ffhp); host_err = commit_metadata(ffhp);
} }
out_drop_write:
mnt_drop_write(ffhp->fh_export->ex_path.mnt); mnt_drop_write(ffhp->fh_export->ex_path.mnt);
out_dput_new: out_dput_new:
dput(ndentry); dput(ndentry);
out_dput_old: out_dput_old:
...@@ -1802,11 +1818,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, ...@@ -1802,11 +1818,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
if (host_err) if (host_err)
goto out_nfserr; goto out_nfserr;
host_err = nfsd_break_lease(rdentry->d_inode);
if (host_err)
goto out_put;
if (type != S_IFDIR) if (type != S_IFDIR)
host_err = vfs_unlink(dirp, rdentry); host_err = vfs_unlink(dirp, rdentry);
else else
host_err = vfs_rmdir(dirp, rdentry); host_err = vfs_rmdir(dirp, rdentry);
out_put:
dput(rdentry); dput(rdentry);
if (!host_err) if (!host_err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment