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,
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.
*/
......@@ -414,7 +421,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
err = nfserr_notsync;
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)
goto out_nfserr;
fh_lock(fhp);
......@@ -1639,6 +1646,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
err = nfserrno(host_err);
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);
if (!host_err) {
err = nfserrno(commit_metadata(ffhp));
......@@ -1650,6 +1663,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
else
err = nfserrno(host_err);
}
out_drop_write:
mnt_drop_write(tfhp->fh_export->ex_path.mnt);
out_dput:
dput(dnew);
......@@ -1731,15 +1745,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
if (host_err)
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);
if (!host_err) {
host_err = commit_metadata(tfhp);
if (!host_err)
host_err = commit_metadata(ffhp);
}
out_drop_write:
mnt_drop_write(ffhp->fh_export->ex_path.mnt);
out_dput_new:
dput(ndentry);
out_dput_old:
......@@ -1802,11 +1818,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
if (host_err)
goto out_nfserr;
host_err = nfsd_break_lease(rdentry->d_inode);
if (host_err)
goto out_put;
if (type != S_IFDIR)
host_err = vfs_unlink(dirp, rdentry);
else
host_err = vfs_rmdir(dirp, rdentry);
out_put:
dput(rdentry);
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