Skip to content

Commit 738401a

Browse files
daimngochucklever
authored andcommitted
NFSD: add support for CB_GETATTR callback
Includes: . CB_GETATTR proc for nfs4_cb_procedures[] . XDR encoding and decoding function for CB_GETATTR request/reply . add nfs4_cb_fattr to nfs4_delegation for sending CB_GETATTR and store file attributes from client's reply. Signed-off-by: Dai Ngo <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 15d3988 commit 738401a

File tree

3 files changed

+128
-1
lines changed

3 files changed

+128
-1
lines changed

fs/nfsd/nfs4callback.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,21 @@ static void encode_uint32(struct xdr_stream *xdr, u32 n)
8484
static void encode_bitmap4(struct xdr_stream *xdr, const __u32 *bitmap,
8585
size_t len)
8686
{
87-
WARN_ON_ONCE(xdr_stream_encode_uint32_array(xdr, bitmap, len) < 0);
87+
xdr_stream_encode_uint32_array(xdr, bitmap, len);
88+
}
89+
90+
static int decode_cb_fattr4(struct xdr_stream *xdr, uint32_t *bitmap,
91+
struct nfs4_cb_fattr *fattr)
92+
{
93+
fattr->ncf_cb_change = 0;
94+
fattr->ncf_cb_fsize = 0;
95+
if (bitmap[0] & FATTR4_WORD0_CHANGE)
96+
if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_change) < 0)
97+
return -NFSERR_BAD_XDR;
98+
if (bitmap[0] & FATTR4_WORD0_SIZE)
99+
if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_fsize) < 0)
100+
return -NFSERR_BAD_XDR;
101+
return 0;
88102
}
89103

90104
/*
@@ -357,6 +371,30 @@ encode_cb_recallany4args(struct xdr_stream *xdr,
357371
hdr->nops++;
358372
}
359373

374+
/*
375+
* CB_GETATTR4args
376+
* struct CB_GETATTR4args {
377+
* nfs_fh4 fh;
378+
* bitmap4 attr_request;
379+
* };
380+
*
381+
* The size and change attributes are the only one
382+
* guaranteed to be serviced by the client.
383+
*/
384+
static void
385+
encode_cb_getattr4args(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr,
386+
struct nfs4_cb_fattr *fattr)
387+
{
388+
struct nfs4_delegation *dp =
389+
container_of(fattr, struct nfs4_delegation, dl_cb_fattr);
390+
struct knfsd_fh *fh = &dp->dl_stid.sc_file->fi_fhandle;
391+
392+
encode_nfs_cb_opnum4(xdr, OP_CB_GETATTR);
393+
encode_nfs_fh4(xdr, fh);
394+
encode_bitmap4(xdr, fattr->ncf_cb_bmap, ARRAY_SIZE(fattr->ncf_cb_bmap));
395+
hdr->nops++;
396+
}
397+
360398
/*
361399
* CB_SEQUENCE4args
362400
*
@@ -492,6 +530,26 @@ static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
492530
xdr_reserve_space(xdr, 0);
493531
}
494532

533+
/*
534+
* 20.1. Operation 3: CB_GETATTR - Get Attributes
535+
*/
536+
static void nfs4_xdr_enc_cb_getattr(struct rpc_rqst *req,
537+
struct xdr_stream *xdr, const void *data)
538+
{
539+
const struct nfsd4_callback *cb = data;
540+
struct nfs4_cb_fattr *ncf =
541+
container_of(cb, struct nfs4_cb_fattr, ncf_getattr);
542+
struct nfs4_cb_compound_hdr hdr = {
543+
.ident = cb->cb_clp->cl_cb_ident,
544+
.minorversion = cb->cb_clp->cl_minorversion,
545+
};
546+
547+
encode_cb_compound4args(xdr, &hdr);
548+
encode_cb_sequence4args(xdr, cb, &hdr);
549+
encode_cb_getattr4args(xdr, &hdr, ncf);
550+
encode_cb_nops(&hdr);
551+
}
552+
495553
/*
496554
* 20.2. Operation 4: CB_RECALL - Recall a Delegation
497555
*/
@@ -547,6 +605,42 @@ static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
547605
return 0;
548606
}
549607

608+
/*
609+
* 20.1. Operation 3: CB_GETATTR - Get Attributes
610+
*/
611+
static int nfs4_xdr_dec_cb_getattr(struct rpc_rqst *rqstp,
612+
struct xdr_stream *xdr,
613+
void *data)
614+
{
615+
struct nfsd4_callback *cb = data;
616+
struct nfs4_cb_compound_hdr hdr;
617+
int status;
618+
u32 bitmap[3] = {0};
619+
u32 attrlen;
620+
struct nfs4_cb_fattr *ncf =
621+
container_of(cb, struct nfs4_cb_fattr, ncf_getattr);
622+
623+
status = decode_cb_compound4res(xdr, &hdr);
624+
if (unlikely(status))
625+
return status;
626+
627+
status = decode_cb_sequence4res(xdr, cb);
628+
if (unlikely(status || cb->cb_seq_status))
629+
return status;
630+
631+
status = decode_cb_op_status(xdr, OP_CB_GETATTR, &cb->cb_status);
632+
if (status)
633+
return status;
634+
if (xdr_stream_decode_uint32_array(xdr, bitmap, 3) < 0)
635+
return -NFSERR_BAD_XDR;
636+
if (xdr_stream_decode_u32(xdr, &attrlen) < 0)
637+
return -NFSERR_BAD_XDR;
638+
if (attrlen > (sizeof(ncf->ncf_cb_change) + sizeof(ncf->ncf_cb_fsize)))
639+
return -NFSERR_BAD_XDR;
640+
status = decode_cb_fattr4(xdr, bitmap, ncf);
641+
return status;
642+
}
643+
550644
/*
551645
* 20.2. Operation 4: CB_RECALL - Recall a Delegation
552646
*/
@@ -855,6 +949,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = {
855949
PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock),
856950
PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload),
857951
PROC(CB_RECALL_ANY, COMPOUND, cb_recall_any, cb_recall_any),
952+
PROC(CB_GETATTR, COMPOUND, cb_getattr, cb_getattr),
858953
};
859954

860955
static unsigned int nfs4_cb_counts[ARRAY_SIZE(nfs4_cb_procedures)];

fs/nfsd/state.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,16 @@ struct nfs4_cpntf_state {
117117
time64_t cpntf_time; /* last time stateid used */
118118
};
119119

120+
struct nfs4_cb_fattr {
121+
struct nfsd4_callback ncf_getattr;
122+
u32 ncf_cb_status;
123+
u32 ncf_cb_bmap[1];
124+
125+
/* from CB_GETATTR reply */
126+
u64 ncf_cb_change;
127+
u64 ncf_cb_fsize;
128+
};
129+
120130
/*
121131
* Represents a delegation stateid. The nfs4_client holds references to these
122132
* and they are put when it is being destroyed or when the delegation is
@@ -150,6 +160,9 @@ struct nfs4_delegation {
150160
int dl_retries;
151161
struct nfsd4_callback dl_recall;
152162
bool dl_recalled;
163+
164+
/* for CB_GETATTR */
165+
struct nfs4_cb_fattr dl_cb_fattr;
153166
};
154167

155168
#define cb_to_delegation(cb) \
@@ -642,6 +655,7 @@ enum nfsd4_cb_op {
642655
NFSPROC4_CLNT_CB_SEQUENCE,
643656
NFSPROC4_CLNT_CB_NOTIFY_LOCK,
644657
NFSPROC4_CLNT_CB_RECALL_ANY,
658+
NFSPROC4_CLNT_CB_GETATTR,
645659
};
646660

647661
/* Returns true iff a is later than b: */

fs/nfsd/xdr4cb.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,21 @@
5454
#define NFS4_dec_cb_recall_any_sz (cb_compound_dec_hdr_sz + \
5555
cb_sequence_dec_sz + \
5656
op_dec_sz)
57+
58+
/*
59+
* 1: CB_GETATTR opcode (32-bit)
60+
* N: file_handle
61+
* 1: number of entry in attribute array (32-bit)
62+
* 1: entry 0 in attribute array (32-bit)
63+
*/
64+
#define NFS4_enc_cb_getattr_sz (cb_compound_enc_hdr_sz + \
65+
cb_sequence_enc_sz + \
66+
1 + enc_nfs4_fh_sz + 1 + 1)
67+
/*
68+
* 4: fattr_bitmap_maxsz
69+
* 1: attribute array len
70+
* 2: change attr (64-bit)
71+
* 2: size (64-bit)
72+
*/
73+
#define NFS4_dec_cb_getattr_sz (cb_compound_dec_hdr_sz + \
74+
cb_sequence_dec_sz + 4 + 1 + 2 + 2 + op_dec_sz)

0 commit comments

Comments
 (0)