nfsd4: add max size for response
Subsystems (2)
RFC PATCH 1/2 nfsd4: add max size for response
For checking the size of reply before calling a operation, we need try to get maxsize of the operation's reply.
Make a struct named nfsd4_enc_op, and add enc_size for a operation, we can set the a operation's fixed size at enc_size, but except dynamic data as payload for some especial operation such as READ, READDIR, READLINK.
Signed-off-by Mi Jinlong <[email protected]>
--- fs/nfsd/nfs4xdr.c | 241 +++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 180 insertions(+), 61 deletions(-)
fs/nfsd/nfs4xdr.c +180 -61
@@ -3146,70 +3146,189 @@ nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)typedef __be32 (*nfsd4_enc )(struct nfsd4_compoundres *,__be32 ,void *); +struct nfsd4_enc_op { +nfsd4_enc enc_func; + +/* size except dynamic data as payload for READ, READDIR, READLINK */ +u32 enc_size; +}; +/* * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1 * since we don't need to filter out obsolete ops as this is * done in the decoding phase. */ -static nfsd4_enc nfsd4_enc_ops[] = { - [OP_ACCESS ] = (nfsd4_enc )nfsd4_encode_access, - [OP_CLOSE ] = (nfsd4_enc )nfsd4_encode_close, - [OP_COMMIT ] = (nfsd4_enc )nfsd4_encode_commit, - [OP_CREATE ] = (nfsd4_enc )nfsd4_encode_create, - [OP_DELEGPURGE ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_DELEGRETURN ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_GETATTR ] = (nfsd4_enc )nfsd4_encode_getattr, - [OP_GETFH ] = (nfsd4_enc )nfsd4_encode_getfh, - [OP_LINK ] = (nfsd4_enc )nfsd4_encode_link, - [OP_LOCK ] = (nfsd4_enc )nfsd4_encode_lock, - [OP_LOCKT ] = (nfsd4_enc )nfsd4_encode_lockt, - [OP_LOCKU ] = (nfsd4_enc )nfsd4_encode_locku, - [OP_LOOKUP ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_LOOKUPP ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_NVERIFY ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_OPEN ] = (nfsd4_enc )nfsd4_encode_open, - [OP_OPENATTR ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_OPEN_CONFIRM ] = (nfsd4_enc )nfsd4_encode_open_confirm, - [OP_OPEN_DOWNGRADE ] = (nfsd4_enc )nfsd4_encode_open_downgrade, - [OP_PUTFH ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_PUTPUBFH ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_PUTROOTFH ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_READ ] = (nfsd4_enc )nfsd4_encode_read, - [OP_READDIR ] = (nfsd4_enc )nfsd4_encode_readdir, - [OP_READLINK ] = (nfsd4_enc )nfsd4_encode_readlink, - [OP_REMOVE ] = (nfsd4_enc )nfsd4_encode_remove, - [OP_RENAME ] = (nfsd4_enc )nfsd4_encode_rename, - [OP_RENEW ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_RESTOREFH ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_SAVEFH ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_SECINFO ] = (nfsd4_enc )nfsd4_encode_secinfo, - [OP_SETATTR ] = (nfsd4_enc )nfsd4_encode_setattr, - [OP_SETCLIENTID ] = (nfsd4_enc )nfsd4_encode_setclientid, - [OP_SETCLIENTID_CONFIRM ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_VERIFY ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_WRITE ] = (nfsd4_enc )nfsd4_encode_write, - [OP_RELEASE_LOCKOWNER ] = (nfsd4_enc )nfsd4_encode_noop, - -/* NFSv4.1 operations */ - [OP_BACKCHANNEL_CTL ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_BIND_CONN_TO_SESSION ] = (nfsd4_enc )nfsd4_encode_bind_conn_to_session, - [OP_EXCHANGE_ID ] = (nfsd4_enc )nfsd4_encode_exchange_id, - [OP_CREATE_SESSION ] = (nfsd4_enc )nfsd4_encode_create_session, - [OP_DESTROY_SESSION ] = (nfsd4_enc )nfsd4_encode_destroy_session, - [OP_FREE_STATEID ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_GET_DIR_DELEGATION ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_GETDEVICEINFO ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_GETDEVICELIST ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_LAYOUTCOMMIT ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_LAYOUTGET ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_LAYOUTRETURN ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_SECINFO_NO_NAME ] = (nfsd4_enc )nfsd4_encode_secinfo_no_name, - [OP_SEQUENCE ] = (nfsd4_enc )nfsd4_encode_sequence, - [OP_SET_SSV ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_TEST_STATEID ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_WANT_DELEGATION ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_DESTROY_CLIENTID ] = (nfsd4_enc )nfsd4_encode_noop, - [OP_RECLAIM_COMPLETE ] = (nfsd4_enc )nfsd4_encode_noop, +static struct nfsd4_enc_op nfsd4_enc_ops[] = { + [OP_ACCESS ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_access, + }, + [OP_CLOSE ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_close, + }, + [OP_COMMIT ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_commit, + }, + [OP_CREATE ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_create, + }, + [OP_DELEGPURGE ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_DELEGRETURN ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_GETATTR ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_getattr, + }, + [OP_GETFH ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_getfh, + }, + [OP_LINK ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_link, + }, + [OP_LOCK ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_lock, + }, + [OP_LOCKT ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_lockt, + }, + [OP_LOCKU ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_locku, + }, + [OP_LOOKUP ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_LOOKUPP ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_NVERIFY ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_OPEN ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_open, + }, + [OP_OPENATTR ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_OPEN_CONFIRM ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_open_confirm, + }, + [OP_OPEN_DOWNGRADE ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_open_downgrade, + }, + [OP_PUTFH ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_PUTPUBFH ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_PUTROOTFH ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_READ ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_read, + }, + [OP_READDIR ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_readdir, + }, + [OP_READLINK ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_readlink, + }, + [OP_REMOVE ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_remove, + }, + [OP_RENAME ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_rename, + }, + [OP_RENEW ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_RESTOREFH ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_SAVEFH ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_SECINFO ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_secinfo, + }, + [OP_SETATTR ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_setattr, + }, + [OP_SETCLIENTID ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_setclientid, + }, + [OP_SETCLIENTID_CONFIRM ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_VERIFY ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_WRITE ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_write, + }, + [OP_RELEASE_LOCKOWNER ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + +/* NFSv4.1 operations */ + [OP_BACKCHANNEL_CTL ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_BIND_CONN_TO_SESSION ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_bind_conn_to_session, + }, + [OP_EXCHANGE_ID ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_exchange_id, + }, + [OP_CREATE_SESSION ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_create_session, + }, + [OP_DESTROY_SESSION ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_destroy_session, + }, + [OP_FREE_STATEID ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_GET_DIR_DELEGATION ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_GETDEVICEINFO ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_GETDEVICELIST ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_LAYOUTCOMMIT ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_LAYOUTGET ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_LAYOUTRETURN ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_SECINFO_NO_NAME ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_secinfo_no_name, + }, + [OP_SEQUENCE ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_sequence, + }, + [OP_SET_SSV ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_TEST_STATEID ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_WANT_DELEGATION ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_DESTROY_CLIENTID ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, + [OP_RECLAIM_COMPLETE ] = { + .enc_func = (nfsd4_enc )nfsd4_encode_noop, + }, };/*
@@ -3274,8 +3393,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)if (op->opnum ==OP_ILLEGAL ) goto status;BUG_ON (op->opnum <0 || op->opnum >=ARRAY_SIZE (nfsd4_enc_ops) || - !nfsd4_enc_ops[op->opnum]); - op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u); + !nfsd4_enc_ops[op->opnum].enc_func); + op->status = nfsd4_enc_ops[op->opnum].enc_func (resp, op->status, &op->u);/* nfsd4_check_drc_limit guarantees enough room for error status */ if (!op->status &&nfsd4_check_drc_limit (resp)) op->status = nfserr_rep_too_big_to_cache;
Signature · 1 line
1.7.5.4