},
[OP_LOCK] = {
.op_func = nfsd4_lock,
- .op_flags = OP_MODIFIES_SOMETHING,
+ .op_flags = OP_MODIFIES_SOMETHING |
+ OP_NONTRIVIAL_ERROR_ENCODE,
.op_name = "OP_LOCK",
.op_rsize_bop = nfsd4_lock_rsize,
.op_set_currentstateid = nfsd4_set_lockstateid,
},
[OP_LOCKT] = {
.op_func = nfsd4_lockt,
+ .op_flags = OP_NONTRIVIAL_ERROR_ENCODE,
.op_name = "OP_LOCKT",
.op_rsize_bop = nfsd4_lock_rsize,
},
[OP_SETATTR] = {
.op_func = nfsd4_setattr,
.op_name = "OP_SETATTR",
- .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
+ .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME
+ | OP_NONTRIVIAL_ERROR_ENCODE,
.op_rsize_bop = nfsd4_setattr_rsize,
.op_get_currentstateid = nfsd4_get_setattrstateid,
},
[OP_SETCLIENTID] = {
.op_func = nfsd4_setclientid,
.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
- | OP_MODIFIES_SOMETHING | OP_CACHEME,
+ | OP_MODIFIES_SOMETHING | OP_CACHEME
+ | OP_NONTRIVIAL_ERROR_ENCODE,
.op_name = "OP_SETCLIENTID",
.op_rsize_bop = nfsd4_setclientid_rsize,
},
if (op->opnum == OP_ILLEGAL)
goto status;
+ if (op->status && opdesc &&
+ !(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE))
+ goto status;
BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
!nfsd4_enc_ops[op->opnum]);
encoder = nfsd4_enc_ops[op->opnum];
* These are ops which clear current state id.
*/
OP_CLEAR_STATEID = 1 << 7,
+ /* Most ops return only an error on failure; some may do more: */
+ OP_NONTRIVIAL_ERROR_ENCODE = 1 << 8,
};
struct nfsd4_operation {