Commit fabf2b34 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Separate tracking of file nlinks cache validity from the mode/uid/gid



Rename can cause us to revalidate the access cache, so lets track the
nlinks separately from the mode/uid/gid.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent a71029b8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1711,7 +1711,7 @@ static void nfs_drop_nlink(struct inode *inode)
	NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter();
	nfs_set_cache_invalid(
		inode, NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME |
			       NFS_INO_INVALID_OTHER | NFS_INO_REVAL_FORCED);
			       NFS_INO_INVALID_NLINK | NFS_INO_REVAL_FORCED);
	spin_unlock(&inode->i_lock);
}

+10 −5
Original line number Diff line number Diff line
@@ -538,7 +538,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
		if (fattr->valid & NFS_ATTR_FATTR_NLINK)
			set_nlink(inode, fattr->nlink);
		else if (nfs_server_capable(inode, NFS_CAP_NLINK))
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
			nfs_set_cache_invalid(inode, NFS_INO_INVALID_NLINK);
		if (fattr->valid & NFS_ATTR_FATTR_OWNER)
			inode->i_uid = fattr->uid;
		else if (nfs_server_capable(inode, NFS_CAP_OWNER))
@@ -801,8 +801,10 @@ static u32 nfs_get_valid_attrmask(struct inode *inode)
		reply_mask |= STATX_MTIME;
	if (!(cache_validity & NFS_INO_INVALID_SIZE))
		reply_mask |= STATX_SIZE;
	if (!(cache_validity & NFS_INO_INVALID_NLINK))
		reply_mask |= STATX_NLINK;
	if (!(cache_validity & NFS_INO_INVALID_OTHER))
		reply_mask |= STATX_UID | STATX_GID | STATX_MODE | STATX_NLINK;
		reply_mask |= STATX_UID | STATX_GID | STATX_MODE;
	if (!(cache_validity & NFS_INO_INVALID_BLOCKS))
		reply_mask |= STATX_BLOCKS;
	return reply_mask;
@@ -868,7 +870,9 @@ int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
		do_update |= cache_validity & NFS_INO_INVALID_MTIME;
	if (request_mask & STATX_SIZE)
		do_update |= cache_validity & NFS_INO_INVALID_SIZE;
	if (request_mask & (STATX_UID | STATX_GID | STATX_MODE | STATX_NLINK))
	if (request_mask & STATX_NLINK)
		do_update |= cache_validity & NFS_INO_INVALID_NLINK;
	if (request_mask & (STATX_UID | STATX_GID | STATX_MODE))
		do_update |= cache_validity & NFS_INO_INVALID_OTHER;
	if (request_mask & STATX_BLOCKS)
		do_update |= cache_validity & NFS_INO_INVALID_BLOCKS;
@@ -1518,7 +1522,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat

	/* Has the link count changed? */
	if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink)
		invalid |= NFS_INO_INVALID_OTHER;
		invalid |= NFS_INO_INVALID_NLINK;

	ts = inode->i_atime;
	if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec64_equal(&ts, &fattr->atime))
@@ -1942,6 +1946,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
					| NFS_INO_INVALID_MTIME
					| NFS_INO_INVALID_SIZE
					| NFS_INO_INVALID_BLOCKS
					| NFS_INO_INVALID_NLINK
					| NFS_INO_INVALID_OTHER;
				if (S_ISDIR(inode->i_mode))
					nfs_force_lookup_revalidate(inode);
@@ -2074,7 +2079,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
		}
	} else if (server->caps & NFS_CAP_NLINK) {
		nfsi->cache_validity |= save_cache_validity &
				(NFS_INO_INVALID_OTHER
				(NFS_INO_INVALID_NLINK
				| NFS_INO_REVAL_FORCED);
		cache_revalidated = false;
	}
+7 −6
Original line number Diff line number Diff line
@@ -1167,14 +1167,14 @@ int nfs4_call_sync(struct rpc_clnt *clnt,
static void
nfs4_inc_nlink_locked(struct inode *inode)
{
	nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
	nfs_set_cache_invalid(inode, NFS_INO_INVALID_NLINK);
	inc_nlink(inode);
}

static void
nfs4_dec_nlink_locked(struct inode *inode)
{
	nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
	nfs_set_cache_invalid(inode, NFS_INO_INVALID_NLINK);
	drop_nlink(inode);
}

@@ -4717,11 +4717,11 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
			/* Note: If we moved a directory, nlink will change */
			nfs4_update_changeattr(old_dir, &res->old_cinfo,
					res->old_fattr->time_start,
					NFS_INO_INVALID_OTHER |
					NFS_INO_INVALID_NLINK |
					    NFS_INO_INVALID_DATA);
			nfs4_update_changeattr(new_dir, &res->new_cinfo,
					res->new_fattr->time_start,
					NFS_INO_INVALID_OTHER |
					NFS_INO_INVALID_NLINK |
					    NFS_INO_INVALID_DATA);
		} else
			nfs4_update_changeattr(old_dir, &res->old_cinfo,
@@ -5433,8 +5433,9 @@ static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ], const __u32 *src,
		bitmask[1] |= FATTR4_WORD1_TIME_ACCESS;
	if (cache_validity & NFS_INO_INVALID_OTHER)
		bitmask[1] |= FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER |
				FATTR4_WORD1_OWNER_GROUP |
				FATTR4_WORD1_NUMLINKS;
				FATTR4_WORD1_OWNER_GROUP;
	if (cache_validity & NFS_INO_INVALID_NLINK)
		bitmask[1] |= FATTR4_WORD1_NUMLINKS;
	if (label && label->len && cache_validity & NFS_INO_INVALID_LABEL)
		bitmask[2] |= FATTR4_WORD2_SECURITY_LABEL;
	if (cache_validity & NFS_INO_INVALID_CTIME)
+3 −1
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_OTHER);
TRACE_DEFINE_ENUM(NFS_INO_DATA_INVAL_DEFER);
TRACE_DEFINE_ENUM(NFS_INO_INVALID_BLOCKS);
TRACE_DEFINE_ENUM(NFS_INO_INVALID_XATTR);
TRACE_DEFINE_ENUM(NFS_INO_INVALID_NLINK);

#define nfs_show_cache_validity(v) \
	__print_flags(v, "|", \
@@ -65,7 +66,8 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_XATTR);
			{ NFS_INO_INVALID_OTHER, "INVALID_OTHER" }, \
			{ NFS_INO_DATA_INVAL_DEFER, "DATA_INVAL_DEFER" }, \
			{ NFS_INO_INVALID_BLOCKS, "INVALID_BLOCKS" }, \
			{ NFS_INO_INVALID_XATTR, "INVALID_XATTR" })
			{ NFS_INO_INVALID_XATTR, "INVALID_XATTR" }, \
			{ NFS_INO_INVALID_NLINK, "INVALID_NLINK" })

TRACE_DEFINE_ENUM(NFS_INO_ADVISE_RDPLUS);
TRACE_DEFINE_ENUM(NFS_INO_STALE);
+2 −0
Original line number Diff line number Diff line
@@ -246,11 +246,13 @@ struct nfs4_copy_state {
				BIT(13)		/* Deferred cache invalidation */
#define NFS_INO_INVALID_BLOCKS	BIT(14)         /* cached blocks are invalid */
#define NFS_INO_INVALID_XATTR	BIT(15)		/* xattrs are invalid */
#define NFS_INO_INVALID_NLINK	BIT(16)		/* cached nlinks is invalid */

#define NFS_INO_INVALID_ATTR	(NFS_INO_INVALID_CHANGE \
		| NFS_INO_INVALID_CTIME \
		| NFS_INO_INVALID_MTIME \
		| NFS_INO_INVALID_SIZE \
		| NFS_INO_INVALID_NLINK \
		| NFS_INO_INVALID_OTHER)	/* inode metadata is invalid */

/*