Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -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)