Skip to content

Commit 318579c

Browse files
rmacklemchucklever
authored andcommitted
NFSD: Add POSIX draft ACL support to the NFSv4 SETATTR operation
The POSIX ACL extension to NFSv4 enables clients to set access and default ACLs via FATTR4_POSIX_ACCESS_ACL and FATTR4_POSIX_DEFAULT_ACL attributes. Integration of these attributes into SETATTR processing requires wiring them through the nfsd_attrs structure and ensuring proper cleanup on all code paths. This patch connects the na_pacl and na_dpacl fields in nfsd_attrs to the decoded ACL pointers from the NFSv4 SETATTR decoder. Ownership of these ACL references transfers to attrs immediately after initialization, with the decoder's pointers cleared to NULL. This transfer ensures nfsd_attrs_free() releases the ACLs on normal completion, while new error paths call posix_acl_release() directly when cleanup occurs before nfsd_attrs_free() runs. Early returns in the nfsd4_setattr() function gain conversions to goto statements that branch to proper cleanup handlers. Error paths before fh_want_write() branch to out_err for ACL release only; paths after fh_want_write() use the existing out label for full cleanup via nfsd_attrs_free(). The patch adds mutual exclusion between NFSv4 ACLs (sa_acl) and POSIX ACLs. Setting both types simultaneously returns nfserr_inval because these ACL models cannot coexist on the same file object. Signed-off-by: Rick Macklem <rmacklem@uoguelph.ca> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent d2ca506 commit 318579c

1 file changed

Lines changed: 19 additions & 5 deletions

File tree

fs/nfsd/nfs4proc.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,13 +1214,19 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
12141214
struct nfsd_attrs attrs = {
12151215
.na_iattr = &setattr->sa_iattr,
12161216
.na_seclabel = &setattr->sa_label,
1217+
.na_pacl = setattr->sa_pacl,
1218+
.na_dpacl = setattr->sa_dpacl,
12171219
};
12181220
bool save_no_wcc, deleg_attrs;
12191221
struct nfs4_stid *st = NULL;
12201222
struct inode *inode;
12211223
__be32 status = nfs_ok;
12221224
int err;
12231225

1226+
/* Transfer ownership to attrs for cleanup via nfsd_attrs_free() */
1227+
setattr->sa_pacl = NULL;
1228+
setattr->sa_dpacl = NULL;
1229+
12241230
deleg_attrs = setattr->sa_bmval[2] & (FATTR4_WORD2_TIME_DELEG_ACCESS |
12251231
FATTR4_WORD2_TIME_DELEG_MODIFY);
12261232

@@ -1234,7 +1240,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
12341240
&cstate->current_fh, &setattr->sa_stateid,
12351241
flags, NULL, &st);
12361242
if (status)
1237-
return status;
1243+
goto out_err;
12381244
}
12391245

12401246
if (deleg_attrs) {
@@ -1252,17 +1258,24 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
12521258
if (st)
12531259
nfs4_put_stid(st);
12541260
if (status)
1255-
return status;
1261+
goto out_err;
12561262

12571263
err = fh_want_write(&cstate->current_fh);
1258-
if (err)
1259-
return nfserrno(err);
1264+
if (err) {
1265+
status = nfserrno(err);
1266+
goto out_err;
1267+
}
12601268
status = nfs_ok;
12611269

12621270
status = check_attr_support(cstate, setattr->sa_bmval, nfsd_attrmask);
12631271
if (status)
12641272
goto out;
12651273

1274+
if (setattr->sa_acl && (attrs.na_dpacl || attrs.na_pacl)) {
1275+
status = nfserr_inval;
1276+
goto out;
1277+
}
1278+
12661279
inode = cstate->current_fh.fh_dentry->d_inode;
12671280
status = nfsd4_acl_to_attr(S_ISDIR(inode->i_mode) ? NF4DIR : NF4REG,
12681281
setattr->sa_acl, &attrs);
@@ -1280,8 +1293,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
12801293
if (!status)
12811294
status = nfserrno(attrs.na_paclerr);
12821295
out:
1283-
nfsd_attrs_free(&attrs);
12841296
fh_drop_write(&cstate->current_fh);
1297+
out_err:
1298+
nfsd_attrs_free(&attrs);
12851299
return status;
12861300
}
12871301

0 commit comments

Comments
 (0)