Skip to content

Commit 6487a13

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 b910544 commit 6487a13

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
@@ -85,7 +85,21 @@ static void encode_uint32(struct xdr_stream *xdr, u32 n)
8585
static void encode_bitmap4(struct xdr_stream *xdr, const __u32 *bitmap,
8686
size_t len)
8787
{
88-
WARN_ON_ONCE(xdr_stream_encode_uint32_array(xdr, bitmap, len) < 0);
88+
xdr_stream_encode_uint32_array(xdr, bitmap, len);
89+
}
90+
91+
static int decode_cb_fattr4(struct xdr_stream *xdr, uint32_t *bitmap,
92+
struct nfs4_cb_fattr *fattr)
93+
{
94+
fattr->ncf_cb_change = 0;
95+
fattr->ncf_cb_fsize = 0;
96+
if (bitmap[0] & FATTR4_WORD0_CHANGE)
97+
if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_change) < 0)
98+
return -NFSERR_BAD_XDR;
99+
if (bitmap[0] & FATTR4_WORD0_SIZE)
100+
if (xdr_stream_decode_u64(xdr, &fattr->ncf_cb_fsize) < 0)
101+
return -NFSERR_BAD_XDR;
102+
return 0;
89103
}
90104

91105
static void encode_nfs_cb_opnum4(struct xdr_stream *xdr, enum nfs_cb_opnum4 op)
@@ -333,6 +347,30 @@ encode_cb_recallany4args(struct xdr_stream *xdr,
333347
hdr->nops++;
334348
}
335349

350+
/*
351+
* CB_GETATTR4args
352+
* struct CB_GETATTR4args {
353+
* nfs_fh4 fh;
354+
* bitmap4 attr_request;
355+
* };
356+
*
357+
* The size and change attributes are the only one
358+
* guaranteed to be serviced by the client.
359+
*/
360+
static void
361+
encode_cb_getattr4args(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr,
362+
struct nfs4_cb_fattr *fattr)
363+
{
364+
struct nfs4_delegation *dp =
365+
container_of(fattr, struct nfs4_delegation, dl_cb_fattr);
366+
struct knfsd_fh *fh = &dp->dl_stid.sc_file->fi_fhandle;
367+
368+
encode_nfs_cb_opnum4(xdr, OP_CB_GETATTR);
369+
encode_nfs_fh4(xdr, fh);
370+
encode_bitmap4(xdr, fattr->ncf_cb_bmap, ARRAY_SIZE(fattr->ncf_cb_bmap));
371+
hdr->nops++;
372+
}
373+
336374
/*
337375
* CB_SEQUENCE4args
338376
*
@@ -468,6 +506,26 @@ static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
468506
xdr_reserve_space(xdr, 0);
469507
}
470508

509+
/*
510+
* 20.1. Operation 3: CB_GETATTR - Get Attributes
511+
*/
512+
static void nfs4_xdr_enc_cb_getattr(struct rpc_rqst *req,
513+
struct xdr_stream *xdr, const void *data)
514+
{
515+
const struct nfsd4_callback *cb = data;
516+
struct nfs4_cb_fattr *ncf =
517+
container_of(cb, struct nfs4_cb_fattr, ncf_getattr);
518+
struct nfs4_cb_compound_hdr hdr = {
519+
.ident = cb->cb_clp->cl_cb_ident,
520+
.minorversion = cb->cb_clp->cl_minorversion,
521+
};
522+
523+
encode_cb_compound4args(xdr, &hdr);
524+
encode_cb_sequence4args(xdr, cb, &hdr);
525+
encode_cb_getattr4args(xdr, &hdr, ncf);
526+
encode_cb_nops(&hdr);
527+
}
528+
471529
/*
472530
* 20.2. Operation 4: CB_RECALL - Recall a Delegation
473531
*/
@@ -523,6 +581,42 @@ static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
523581
return 0;
524582
}
525583

584+
/*
585+
* 20.1. Operation 3: CB_GETATTR - Get Attributes
586+
*/
587+
static int nfs4_xdr_dec_cb_getattr(struct rpc_rqst *rqstp,
588+
struct xdr_stream *xdr,
589+
void *data)
590+
{
591+
struct nfsd4_callback *cb = data;
592+
struct nfs4_cb_compound_hdr hdr;
593+
int status;
594+
u32 bitmap[3] = {0};
595+
u32 attrlen;
596+
struct nfs4_cb_fattr *ncf =
597+
container_of(cb, struct nfs4_cb_fattr, ncf_getattr);
598+
599+
status = decode_cb_compound4res(xdr, &hdr);
600+
if (unlikely(status))
601+
return status;
602+
603+
status = decode_cb_sequence4res(xdr, cb);
604+
if (unlikely(status || cb->cb_seq_status))
605+
return status;
606+
607+
status = decode_cb_op_status(xdr, OP_CB_GETATTR, &cb->cb_status);
608+
if (status)
609+
return status;
610+
if (xdr_stream_decode_uint32_array(xdr, bitmap, 3) < 0)
611+
return -NFSERR_BAD_XDR;
612+
if (xdr_stream_decode_u32(xdr, &attrlen) < 0)
613+
return -NFSERR_BAD_XDR;
614+
if (attrlen > (sizeof(ncf->ncf_cb_change) + sizeof(ncf->ncf_cb_fsize)))
615+
return -NFSERR_BAD_XDR;
616+
status = decode_cb_fattr4(xdr, bitmap, ncf);
617+
return status;
618+
}
619+
526620
/*
527621
* 20.2. Operation 4: CB_RECALL - Recall a Delegation
528622
*/
@@ -831,6 +925,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = {
831925
PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock),
832926
PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload),
833927
PROC(CB_RECALL_ANY, COMPOUND, cb_recall_any, cb_recall_any),
928+
PROC(CB_GETATTR, COMPOUND, cb_getattr, cb_getattr),
834929
};
835930

836931
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
@@ -134,6 +134,16 @@ struct nfs4_cpntf_state {
134134
time64_t cpntf_time; /* last time stateid used */
135135
};
136136

137+
struct nfs4_cb_fattr {
138+
struct nfsd4_callback ncf_getattr;
139+
u32 ncf_cb_status;
140+
u32 ncf_cb_bmap[1];
141+
142+
/* from CB_GETATTR reply */
143+
u64 ncf_cb_change;
144+
u64 ncf_cb_fsize;
145+
};
146+
137147
/*
138148
* Represents a delegation stateid. The nfs4_client holds references to these
139149
* and they are put when it is being destroyed or when the delegation is
@@ -167,6 +177,9 @@ struct nfs4_delegation {
167177
int dl_retries;
168178
struct nfsd4_callback dl_recall;
169179
bool dl_recalled;
180+
181+
/* for CB_GETATTR */
182+
struct nfs4_cb_fattr dl_cb_fattr;
170183
};
171184

172185
#define cb_to_delegation(cb) \
@@ -659,6 +672,7 @@ enum nfsd4_cb_op {
659672
NFSPROC4_CLNT_CB_SEQUENCE,
660673
NFSPROC4_CLNT_CB_NOTIFY_LOCK,
661674
NFSPROC4_CLNT_CB_RECALL_ANY,
675+
NFSPROC4_CLNT_CB_GETATTR,
662676
};
663677

664678
/* 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)