Sophie

Sophie

distrib > CentOS > 5 > x86_64 > by-pkgid > ea32411352494358b8d75a78402a4713 > files > 1135

kernel-2.6.18-238.19.1.el5.centos.plus.src.rpm

From: J. Bruce Fields <bfields@redhat.com>
Date: Fri, 4 Feb 2011 22:13:53 -0500
Subject: [fs] nfs: break lease on nfsd v4 setattr
Message-id: <1296857634-4533-1-git-send-email-bfields@redhat.com>
Patchwork-id: 33080
O-Subject: [RHEL5.7 PATCH 1/2] nfsd4: break lease on nfsd setattr
Bugzilla: 610093
RH-Acked-by: Jeff Layton <jlayton@redhat.com>

Leases (delegations) should really be broken on any metadata change, not
just on size change.

Bugzilla 610093
Upstream commit 6a76bebefe15d9a08864f824d7f8d5beaf37c997

(Note RHEL5 backport uses FMODE_WRITE rather than O_WRONLY as RHEL5 is
missing upstream 8737c9305bd5602b11f7eb4655d5695d4a42a0c6 "Switch
may_open() and break_lease() to passing O_...".)

Signed-off-by: J. Bruce Fields <bfields@redhat.com>

diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index bc4c754..7667f30 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -258,6 +258,16 @@ out:
 	return err;
 }
 
+static int nfsd_break_lease(struct inode *inode)
+{
+	int err;
+
+	err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);
+	if (err == -EWOULDBLOCK)
+		err = -ETIMEDOUT;
+	return err;
+}
+
 /*
  * Set various file attributes.
  * N.B. After this call fhp needs an fh_put
@@ -332,16 +342,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
 				goto out;
 		}
 
-		/*
-		 * If we are changing the size of the file, then
-		 * we need to break all leases.
-		 */
-		err = break_lease(inode, FMODE_WRITE | O_NONBLOCK);
-		if (err == -EWOULDBLOCK)
-			err = -ETIMEDOUT;
-		if (err) /* ENOMEM or EWOULDBLOCK */
-			goto out_nfserr;
-
 		err = get_write_access(inode);
 		if (err)
 			goto out_nfserr;
@@ -382,6 +382,10 @@ 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) {
+		err = nfsd_break_lease(inode);
+		if (err) /* ENOMEM or EWOULDBLOCK */
+			goto out_nfserr;
+
 		fh_lock(fhp);
 		err = notify_change(dentry, iap);
 		err = nfserrno(err);