[4.2.y-ckt stable] Patch "NFS: Fix attribute cache revalidation" has been added to the 4.2.y-ckt tree

Luis Henriques luis.henriques at canonical.com
Mon Feb 1 19:12:03 UTC 2016


On Wed, Jan 27, 2016 at 08:26:45AM +0100, Donald Buczek wrote:
> On 01/27/16 01:10, Kamal Mostafa wrote:
> >This is a note to let you know that I have just added a patch titled
> >
> >     NFS: Fix attribute cache revalidation
> >
> >to the linux-4.2.y-queue branch of the 4.2.y-ckt extended stable tree
> >which can be found at:
> >
> >     http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-4.2.y-queue
> >
> >This patch is scheduled to be released in version 4.2.8-ckt3.
> >
> >If you, or anyone else, feels it should not be added to this tree, please
> >reply to this email.
> 
> You might consider to include
> 
>   NFS: Ensure we revalidate attributes before using execute_ok()
>   NFSv4: Don't perform cached access checks before we've OPENed the file
> 
> as well, as in combination they fix
> https://bugzilla.kernel.org/show_bug.cgi?id=109771
>

These 2 extra commits seem relevant to the 3.16 kernel as well.  I'll
queue them for the next release.

Cheers,
--
Luís


> Regards
> 
>   Donald
> 
> 
> >
> >For more information about the 4.2.y-ckt tree, see
> >https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
> >
> >Thanks.
> >-Kamal
> >
> >---8<------------------------------------------------------------
> >
> > From 37c95c36efa1173b25a53241362f100ed2e3baa8 Mon Sep 17 00:00:00 2001
> >From: Trond Myklebust <trond.myklebust at primarydata.com>
> >Date: Tue, 29 Dec 2015 18:55:19 -0500
> >Subject: NFS: Fix attribute cache revalidation
> >
> >commit ade14a7df796d4e86bd9d181193c883a57b13db0 upstream.
> >
> >If a NFSv4 client uses the cache_consistency_bitmask in order to
> >request only information about the change attribute, timestamps and
> >size, then it has not revalidated all attributes, and hence the
> >attribute timeout timestamp should not be updated.
> >
> >Reported-by: Donald Buczek <buczek at molgen.mpg.de>
> >Signed-off-by: Trond Myklebust <trond.myklebust at primarydata.com>
> >Signed-off-by: Kamal Mostafa <kamal at canonical.com>
> >---
> >  fs/nfs/inode.c | 54 +++++++++++++++++++++++++++++++++++++++---------------
> >  1 file changed, 39 insertions(+), 15 deletions(-)
> >
> >diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
> >index 1c65e3f..7bf2c65 100644
> >--- a/fs/nfs/inode.c
> >+++ b/fs/nfs/inode.c
> >@@ -1630,6 +1630,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
> >  	unsigned long invalid = 0;
> >  	unsigned long now = jiffies;
> >  	unsigned long save_cache_validity;
> >+	bool cache_revalidated = true;
> >
> >  	dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
> >  			__func__, inode->i_sb->s_id, inode->i_ino,
> >@@ -1691,22 +1692,28 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
> >  				nfs_force_lookup_revalidate(inode);
> >  			inode->i_version = fattr->change_attr;
> >  		}
> >-	} else
> >+	} else {
> >  		nfsi->cache_validity |= save_cache_validity;
> >+		cache_revalidated = false;
> >+	}
> >
> >  	if (fattr->valid & NFS_ATTR_FATTR_MTIME) {
> >  		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
> >-	} else if (server->caps & NFS_CAP_MTIME)
> >+	} else if (server->caps & NFS_CAP_MTIME) {
> >  		nfsi->cache_validity |= save_cache_validity &
> >  				(NFS_INO_INVALID_ATTR
> >  				| NFS_INO_REVAL_FORCED);
> >+		cache_revalidated = false;
> >+	}
> >
> >  	if (fattr->valid & NFS_ATTR_FATTR_CTIME) {
> >  		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
> >-	} else if (server->caps & NFS_CAP_CTIME)
> >+	} else if (server->caps & NFS_CAP_CTIME) {
> >  		nfsi->cache_validity |= save_cache_validity &
> >  				(NFS_INO_INVALID_ATTR
> >  				| NFS_INO_REVAL_FORCED);
> >+		cache_revalidated = false;
> >+	}
> >
> >  	/* Check if our cached file size is stale */
> >  	if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
> >@@ -1726,19 +1733,23 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
> >  					(long long)cur_isize,
> >  					(long long)new_isize);
> >  		}
> >-	} else
> >+	} else {
> >  		nfsi->cache_validity |= save_cache_validity &
> >  				(NFS_INO_INVALID_ATTR
> >  				| NFS_INO_REVAL_PAGECACHE
> >  				| NFS_INO_REVAL_FORCED);
> >+		cache_revalidated = false;
> >+	}
> >
> >
> >  	if (fattr->valid & NFS_ATTR_FATTR_ATIME)
> >  		memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
> >-	else if (server->caps & NFS_CAP_ATIME)
> >+	else if (server->caps & NFS_CAP_ATIME) {
> >  		nfsi->cache_validity |= save_cache_validity &
> >  				(NFS_INO_INVALID_ATIME
> >  				| NFS_INO_REVAL_FORCED);
> >+		cache_revalidated = false;
> >+	}
> >
> >  	if (fattr->valid & NFS_ATTR_FATTR_MODE) {
> >  		if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)) {
> >@@ -1747,36 +1758,42 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
> >  			inode->i_mode = newmode;
> >  			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
> >  		}
> >-	} else if (server->caps & NFS_CAP_MODE)
> >+	} else if (server->caps & NFS_CAP_MODE) {
> >  		nfsi->cache_validity |= save_cache_validity &
> >  				(NFS_INO_INVALID_ATTR
> >  				| NFS_INO_INVALID_ACCESS
> >  				| NFS_INO_INVALID_ACL
> >  				| NFS_INO_REVAL_FORCED);
> >+		cache_revalidated = false;
> >+	}
> >
> >  	if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
> >  		if (!uid_eq(inode->i_uid, fattr->uid)) {
> >  			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
> >  			inode->i_uid = fattr->uid;
> >  		}
> >-	} else if (server->caps & NFS_CAP_OWNER)
> >+	} else if (server->caps & NFS_CAP_OWNER) {
> >  		nfsi->cache_validity |= save_cache_validity &
> >  				(NFS_INO_INVALID_ATTR
> >  				| NFS_INO_INVALID_ACCESS
> >  				| NFS_INO_INVALID_ACL
> >  				| NFS_INO_REVAL_FORCED);
> >+		cache_revalidated = false;
> >+	}
> >
> >  	if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
> >  		if (!gid_eq(inode->i_gid, fattr->gid)) {
> >  			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
> >  			inode->i_gid = fattr->gid;
> >  		}
> >-	} else if (server->caps & NFS_CAP_OWNER_GROUP)
> >+	} else if (server->caps & NFS_CAP_OWNER_GROUP) {
> >  		nfsi->cache_validity |= save_cache_validity &
> >  				(NFS_INO_INVALID_ATTR
> >  				| NFS_INO_INVALID_ACCESS
> >  				| NFS_INO_INVALID_ACL
> >  				| NFS_INO_REVAL_FORCED);
> >+		cache_revalidated = false;
> >+	}
> >
> >  	if (fattr->valid & NFS_ATTR_FATTR_NLINK) {
> >  		if (inode->i_nlink != fattr->nlink) {
> >@@ -1785,19 +1802,22 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
> >  				invalid |= NFS_INO_INVALID_DATA;
> >  			set_nlink(inode, fattr->nlink);
> >  		}
> >-	} else if (server->caps & NFS_CAP_NLINK)
> >+	} else if (server->caps & NFS_CAP_NLINK) {
> >  		nfsi->cache_validity |= save_cache_validity &
> >  				(NFS_INO_INVALID_ATTR
> >  				| NFS_INO_REVAL_FORCED);
> >+		cache_revalidated = false;
> >+	}
> >
> >  	if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
> >  		/*
> >  		 * report the blocks in 512byte units
> >  		 */
> >  		inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used);
> >- 	}
> >-	if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
> >+	} else if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
> >  		inode->i_blocks = fattr->du.nfs2.blocks;
> >+	else
> >+		cache_revalidated = false;
> >
> >  	/* Update attrtimeo value if we're out of the unstable period */
> >  	if (invalid & NFS_INO_INVALID_ATTR) {
> >@@ -1807,9 +1827,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
> >  		/* Set barrier to be more recent than all outstanding updates */
> >  		nfsi->attr_gencount = nfs_inc_attr_generation_counter();
> >  	} else {
> >-		if (!time_in_range_open(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
> >-			if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
> >-				nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
> >+		if (cache_revalidated) {
> >+			if (!time_in_range_open(now, nfsi->attrtimeo_timestamp,
> >+				nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
> >+				nfsi->attrtimeo <<= 1;
> >+				if (nfsi->attrtimeo > NFS_MAXATTRTIMEO(inode))
> >+					nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
> >+			}
> >  			nfsi->attrtimeo_timestamp = now;
> >  		}
> >  		/* Set the barrier to be more recent than this fattr */
> >@@ -1818,7 +1842,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
> >  	}
> >
> >  	/* Don't declare attrcache up to date if there were no attrs! */
> >-	if (fattr->valid != 0)
> >+	if (cache_revalidated)
> >  		invalid &= ~NFS_INO_INVALID_ATTR;
> >
> >  	/* Don't invalidate the data if we were to blame */
> >--
> >1.9.1
> >
> 
> 
> -- 
> Donald Buczek
> buczek at molgen.mpg.de
> Tel: +49 30 8413 1433
> 
> 
> -- 
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team




More information about the kernel-team mailing list