Commit fabf2b34 authored by Trond Myklebust's avatar Trond Myklebust

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
...@@ -1711,7 +1711,7 @@ static void nfs_drop_nlink(struct inode *inode) ...@@ -1711,7 +1711,7 @@ static void nfs_drop_nlink(struct inode *inode)
NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter(); NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter();
nfs_set_cache_invalid( nfs_set_cache_invalid(
inode, NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME | 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); spin_unlock(&inode->i_lock);
} }
......
...@@ -538,7 +538,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st ...@@ -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) if (fattr->valid & NFS_ATTR_FATTR_NLINK)
set_nlink(inode, fattr->nlink); set_nlink(inode, fattr->nlink);
else if (nfs_server_capable(inode, NFS_CAP_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) if (fattr->valid & NFS_ATTR_FATTR_OWNER)
inode->i_uid = fattr->uid; inode->i_uid = fattr->uid;
else if (nfs_server_capable(inode, NFS_CAP_OWNER)) else if (nfs_server_capable(inode, NFS_CAP_OWNER))
...@@ -801,8 +801,10 @@ static u32 nfs_get_valid_attrmask(struct inode *inode) ...@@ -801,8 +801,10 @@ static u32 nfs_get_valid_attrmask(struct inode *inode)
reply_mask |= STATX_MTIME; reply_mask |= STATX_MTIME;
if (!(cache_validity & NFS_INO_INVALID_SIZE)) if (!(cache_validity & NFS_INO_INVALID_SIZE))
reply_mask |= STATX_SIZE; reply_mask |= STATX_SIZE;
if (!(cache_validity & NFS_INO_INVALID_NLINK))
reply_mask |= STATX_NLINK;
if (!(cache_validity & NFS_INO_INVALID_OTHER)) 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)) if (!(cache_validity & NFS_INO_INVALID_BLOCKS))
reply_mask |= STATX_BLOCKS; reply_mask |= STATX_BLOCKS;
return reply_mask; return reply_mask;
...@@ -868,7 +870,9 @@ int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path, ...@@ -868,7 +870,9 @@ int nfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
do_update |= cache_validity & NFS_INO_INVALID_MTIME; do_update |= cache_validity & NFS_INO_INVALID_MTIME;
if (request_mask & STATX_SIZE) if (request_mask & STATX_SIZE)
do_update |= cache_validity & NFS_INO_INVALID_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; do_update |= cache_validity & NFS_INO_INVALID_OTHER;
if (request_mask & STATX_BLOCKS) if (request_mask & STATX_BLOCKS)
do_update |= cache_validity & NFS_INO_INVALID_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 ...@@ -1518,7 +1522,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
/* Has the link count changed? */ /* Has the link count changed? */
if ((fattr->valid & NFS_ATTR_FATTR_NLINK) && inode->i_nlink != fattr->nlink) 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; ts = inode->i_atime;
if ((fattr->valid & NFS_ATTR_FATTR_ATIME) && !timespec64_equal(&ts, &fattr->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) ...@@ -1942,6 +1946,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
| NFS_INO_INVALID_MTIME | NFS_INO_INVALID_MTIME
| NFS_INO_INVALID_SIZE | NFS_INO_INVALID_SIZE
| NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_BLOCKS
| NFS_INO_INVALID_NLINK
| NFS_INO_INVALID_OTHER; | NFS_INO_INVALID_OTHER;
if (S_ISDIR(inode->i_mode)) if (S_ISDIR(inode->i_mode))
nfs_force_lookup_revalidate(inode); nfs_force_lookup_revalidate(inode);
...@@ -2074,7 +2079,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -2074,7 +2079,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
} }
} else if (server->caps & NFS_CAP_NLINK) { } else if (server->caps & NFS_CAP_NLINK) {
nfsi->cache_validity |= save_cache_validity & nfsi->cache_validity |= save_cache_validity &
(NFS_INO_INVALID_OTHER (NFS_INO_INVALID_NLINK
| NFS_INO_REVAL_FORCED); | NFS_INO_REVAL_FORCED);
cache_revalidated = false; cache_revalidated = false;
} }
......
...@@ -1167,14 +1167,14 @@ int nfs4_call_sync(struct rpc_clnt *clnt, ...@@ -1167,14 +1167,14 @@ int nfs4_call_sync(struct rpc_clnt *clnt,
static void static void
nfs4_inc_nlink_locked(struct inode *inode) 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); inc_nlink(inode);
} }
static void static void
nfs4_dec_nlink_locked(struct inode *inode) 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); drop_nlink(inode);
} }
...@@ -4717,11 +4717,11 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir, ...@@ -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 */ /* Note: If we moved a directory, nlink will change */
nfs4_update_changeattr(old_dir, &res->old_cinfo, nfs4_update_changeattr(old_dir, &res->old_cinfo,
res->old_fattr->time_start, res->old_fattr->time_start,
NFS_INO_INVALID_OTHER | NFS_INO_INVALID_NLINK |
NFS_INO_INVALID_DATA); NFS_INO_INVALID_DATA);
nfs4_update_changeattr(new_dir, &res->new_cinfo, nfs4_update_changeattr(new_dir, &res->new_cinfo,
res->new_fattr->time_start, res->new_fattr->time_start,
NFS_INO_INVALID_OTHER | NFS_INO_INVALID_NLINK |
NFS_INO_INVALID_DATA); NFS_INO_INVALID_DATA);
} else } else
nfs4_update_changeattr(old_dir, &res->old_cinfo, 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, ...@@ -5433,8 +5433,9 @@ static void nfs4_bitmask_set(__u32 bitmask[NFS4_BITMASK_SZ], const __u32 *src,
bitmask[1] |= FATTR4_WORD1_TIME_ACCESS; bitmask[1] |= FATTR4_WORD1_TIME_ACCESS;
if (cache_validity & NFS_INO_INVALID_OTHER) if (cache_validity & NFS_INO_INVALID_OTHER)
bitmask[1] |= FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | bitmask[1] |= FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER |
FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_OWNER_GROUP;
FATTR4_WORD1_NUMLINKS; if (cache_validity & NFS_INO_INVALID_NLINK)
bitmask[1] |= FATTR4_WORD1_NUMLINKS;
if (label && label->len && cache_validity & NFS_INO_INVALID_LABEL) if (label && label->len && cache_validity & NFS_INO_INVALID_LABEL)
bitmask[2] |= FATTR4_WORD2_SECURITY_LABEL; bitmask[2] |= FATTR4_WORD2_SECURITY_LABEL;
if (cache_validity & NFS_INO_INVALID_CTIME) if (cache_validity & NFS_INO_INVALID_CTIME)
......
...@@ -48,6 +48,7 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_OTHER); ...@@ -48,6 +48,7 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_OTHER);
TRACE_DEFINE_ENUM(NFS_INO_DATA_INVAL_DEFER); TRACE_DEFINE_ENUM(NFS_INO_DATA_INVAL_DEFER);
TRACE_DEFINE_ENUM(NFS_INO_INVALID_BLOCKS); TRACE_DEFINE_ENUM(NFS_INO_INVALID_BLOCKS);
TRACE_DEFINE_ENUM(NFS_INO_INVALID_XATTR); TRACE_DEFINE_ENUM(NFS_INO_INVALID_XATTR);
TRACE_DEFINE_ENUM(NFS_INO_INVALID_NLINK);
#define nfs_show_cache_validity(v) \ #define nfs_show_cache_validity(v) \
__print_flags(v, "|", \ __print_flags(v, "|", \
...@@ -65,7 +66,8 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_XATTR); ...@@ -65,7 +66,8 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_XATTR);
{ NFS_INO_INVALID_OTHER, "INVALID_OTHER" }, \ { NFS_INO_INVALID_OTHER, "INVALID_OTHER" }, \
{ NFS_INO_DATA_INVAL_DEFER, "DATA_INVAL_DEFER" }, \ { NFS_INO_DATA_INVAL_DEFER, "DATA_INVAL_DEFER" }, \
{ NFS_INO_INVALID_BLOCKS, "INVALID_BLOCKS" }, \ { 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_ADVISE_RDPLUS);
TRACE_DEFINE_ENUM(NFS_INO_STALE); TRACE_DEFINE_ENUM(NFS_INO_STALE);
......
...@@ -246,11 +246,13 @@ struct nfs4_copy_state { ...@@ -246,11 +246,13 @@ struct nfs4_copy_state {
BIT(13) /* Deferred cache invalidation */ BIT(13) /* Deferred cache invalidation */
#define NFS_INO_INVALID_BLOCKS BIT(14) /* cached blocks are invalid */ #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_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 \ #define NFS_INO_INVALID_ATTR (NFS_INO_INVALID_CHANGE \
| NFS_INO_INVALID_CTIME \ | NFS_INO_INVALID_CTIME \
| NFS_INO_INVALID_MTIME \ | NFS_INO_INVALID_MTIME \
| NFS_INO_INVALID_SIZE \ | NFS_INO_INVALID_SIZE \
| NFS_INO_INVALID_NLINK \
| NFS_INO_INVALID_OTHER) /* inode metadata is invalid */ | NFS_INO_INVALID_OTHER) /* inode metadata is invalid */
/* /*
......
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