Skip to content

Commit 76bd5c0

Browse files
olgakorn1amschuma-ntap
authored andcommitted
NFSv4: make cache consistency bitmask dynamic
Client uses static bitmask for GETATTR on CLOSE/WRITE/DELEGRETURN and ignores the fact that it might have some attributes marked invalid in its cache. Compared to v3 where all attributes are retrieved in postop attributes, v4's cache is frequently out of sync and leads to standalone GETATTRs being sent to the server. Instead, in addition to the minimum cache consistency attributes also check cache_validity and adjust the GETATTR request accordingly. Signed-off-by: Olga Kornievskaia <kolga@netapp.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent 9f26645 commit 76bd5c0

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

fs/nfs/nfs4proc.c

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *,
107107
static int nfs41_free_stateid(struct nfs_server *, const nfs4_stateid *,
108108
const struct cred *, bool);
109109
#endif
110+
static void nfs4_bitmask_adjust(__u32 *bitmask, struct inode *inode,
111+
struct nfs_server *server,
112+
struct nfs4_label *label);
110113

111114
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
112115
static inline struct nfs4_label *
@@ -3632,9 +3635,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
36323635

36333636
if (calldata->arg.fmode == 0 || calldata->arg.fmode == FMODE_READ) {
36343637
/* Close-to-open cache consistency revalidation */
3635-
if (!nfs4_have_delegation(inode, FMODE_READ))
3638+
if (!nfs4_have_delegation(inode, FMODE_READ)) {
36363639
calldata->arg.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
3637-
else
3640+
nfs4_bitmask_adjust(calldata->arg.bitmask, inode, NFS_SERVER(inode), NULL);
3641+
} else
36383642
calldata->arg.bitmask = NULL;
36393643
}
36403644

@@ -5360,6 +5364,38 @@ bool nfs4_write_need_cache_consistency_data(struct nfs_pgio_header *hdr)
53605364
return nfs4_have_delegation(hdr->inode, FMODE_READ) == 0;
53615365
}
53625366

5367+
static void nfs4_bitmask_adjust(__u32 *bitmask, struct inode *inode,
5368+
struct nfs_server *server,
5369+
struct nfs4_label *label)
5370+
{
5371+
5372+
unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
5373+
5374+
if ((cache_validity & NFS_INO_INVALID_DATA) ||
5375+
(cache_validity & NFS_INO_REVAL_PAGECACHE) ||
5376+
(cache_validity & NFS_INO_REVAL_FORCED) ||
5377+
(cache_validity & NFS_INO_INVALID_OTHER))
5378+
nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode);
5379+
5380+
if (cache_validity & NFS_INO_INVALID_ATIME)
5381+
bitmask[1] |= FATTR4_WORD1_TIME_ACCESS;
5382+
if (cache_validity & NFS_INO_INVALID_ACCESS)
5383+
bitmask[0] |= FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER |
5384+
FATTR4_WORD1_OWNER_GROUP;
5385+
if (cache_validity & NFS_INO_INVALID_ACL)
5386+
bitmask[0] |= FATTR4_WORD0_ACL;
5387+
if (cache_validity & NFS_INO_INVALID_LABEL)
5388+
bitmask[2] |= FATTR4_WORD2_SECURITY_LABEL;
5389+
if (cache_validity & NFS_INO_INVALID_CTIME)
5390+
bitmask[0] |= FATTR4_WORD0_CHANGE;
5391+
if (cache_validity & NFS_INO_INVALID_MTIME)
5392+
bitmask[1] |= FATTR4_WORD1_TIME_MODIFY;
5393+
if (cache_validity & NFS_INO_INVALID_SIZE)
5394+
bitmask[0] |= FATTR4_WORD0_SIZE;
5395+
if (cache_validity & NFS_INO_INVALID_BLOCKS)
5396+
bitmask[1] |= FATTR4_WORD1_SPACE_USED;
5397+
}
5398+
53635399
static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr,
53645400
struct rpc_message *msg,
53655401
struct rpc_clnt **clnt)
@@ -5369,8 +5405,10 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr,
53695405
if (!nfs4_write_need_cache_consistency_data(hdr)) {
53705406
hdr->args.bitmask = NULL;
53715407
hdr->res.fattr = NULL;
5372-
} else
5408+
} else {
53735409
hdr->args.bitmask = server->cache_consistency_bitmask;
5410+
nfs4_bitmask_adjust(hdr->args.bitmask, hdr->inode, server, NULL);
5411+
}
53745412

53755413
if (!hdr->pgio_done_cb)
53765414
hdr->pgio_done_cb = nfs4_write_done_cb;
@@ -6406,6 +6444,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred,
64066444
data->args.fhandle = &data->fh;
64076445
data->args.stateid = &data->stateid;
64086446
data->args.bitmask = server->cache_consistency_bitmask;
6447+
nfs4_bitmask_adjust(data->args.bitmask, inode, server, NULL);
64096448
nfs_copy_fh(&data->fh, NFS_FH(inode));
64106449
nfs4_stateid_copy(&data->stateid, stateid);
64116450
data->res.fattr = &data->fattr;

include/linux/nfs_xdr.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ struct nfs_closeargs {
525525
struct nfs_seqid * seqid;
526526
fmode_t fmode;
527527
u32 share_access;
528-
const u32 * bitmask;
528+
u32 * bitmask;
529529
struct nfs4_layoutreturn_args *lr_args;
530530
};
531531

@@ -608,7 +608,7 @@ struct nfs4_delegreturnargs {
608608
struct nfs4_sequence_args seq_args;
609609
const struct nfs_fh *fhandle;
610610
const nfs4_stateid *stateid;
611-
const u32 * bitmask;
611+
u32 * bitmask;
612612
struct nfs4_layoutreturn_args *lr_args;
613613
};
614614

@@ -648,7 +648,7 @@ struct nfs_pgio_args {
648648
union {
649649
unsigned int replen; /* used by read */
650650
struct {
651-
const u32 * bitmask; /* used by write */
651+
u32 * bitmask; /* used by write */
652652
enum nfs3_stable_how stable; /* used by write */
653653
};
654654
};

0 commit comments

Comments
 (0)