Skip to content

Commit 91dc464

Browse files
committed
Add RPC language definition of NFSv4 POSIX ACL extension
The language definition was extracted from the new draft-ietf-nfsv4-posix-acls specification. This ensures good constant and type name alignment between the spec and the Linux kernel source code, and brings in some basic XDR utilities for handling NFSv4 POSIX draft ACLs. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent feb8a46 commit 91dc464

5 files changed

Lines changed: 410 additions & 3 deletions

File tree

Documentation/sunrpc/xdr/nfs4_1.x

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ typedef unsigned int uint32_t;
5353
*/
5454
typedef uint32_t bitmap4<>;
5555

56+
typedef opaque utf8string<>;
57+
typedef utf8string utf8str_cis;
58+
typedef utf8string utf8str_cs;
59+
typedef utf8string utf8str_mixed;
60+
5661
/*
5762
* Timeval
5863
*/
@@ -184,3 +189,59 @@ enum open_delegation_type4 {
184189
OPEN_DELEGATE_READ_ATTRS_DELEG = 4,
185190
OPEN_DELEGATE_WRITE_ATTRS_DELEG = 5
186191
};
192+
193+
194+
/*
195+
* The following content was extracted from draft-ietf-nfsv4-posix-acls
196+
*/
197+
198+
enum aclmodel4 {
199+
ACL_MODEL_NFS4 = 1,
200+
ACL_MODEL_POSIX_DRAFT = 2,
201+
ACL_MODEL_NONE = 3
202+
};
203+
pragma public aclmodel4;
204+
205+
enum aclscope4 {
206+
ACL_SCOPE_FILE_OBJECT = 1,
207+
ACL_SCOPE_FILE_SYSTEM = 2,
208+
ACL_SCOPE_SERVER = 3
209+
};
210+
pragma public aclscope4;
211+
212+
enum posixacetag4 {
213+
POSIXACE4_TAG_USER_OBJ = 1,
214+
POSIXACE4_TAG_USER = 2,
215+
POSIXACE4_TAG_GROUP_OBJ = 3,
216+
POSIXACE4_TAG_GROUP = 4,
217+
POSIXACE4_TAG_MASK = 5,
218+
POSIXACE4_TAG_OTHER = 6
219+
};
220+
pragma public posixacetag4;
221+
222+
typedef uint32_t posixaceperm4;
223+
pragma public posixaceperm4;
224+
225+
/* Bit definitions for posixaceperm4. */
226+
const POSIXACE4_PERM_EXECUTE = 0x00000001;
227+
const POSIXACE4_PERM_WRITE = 0x00000002;
228+
const POSIXACE4_PERM_READ = 0x00000004;
229+
230+
struct posixace4 {
231+
posixacetag4 tag;
232+
posixaceperm4 perm;
233+
utf8str_mixed who;
234+
};
235+
236+
typedef aclmodel4 fattr4_acl_trueform;
237+
typedef aclscope4 fattr4_acl_trueform_scope;
238+
typedef posixace4 fattr4_posix_default_acl<>;
239+
typedef posixace4 fattr4_posix_access_acl<>;
240+
241+
%/*
242+
% * New for POSIX ACL extension
243+
% */
244+
const FATTR4_ACL_TRUEFORM = 89;
245+
const FATTR4_ACL_TRUEFORM_SCOPE = 90;
246+
const FATTR4_POSIX_DEFAULT_ACL = 91;
247+
const FATTR4_POSIX_ACCESS_ACL = 92;

fs/nfsd/nfs4xdr_gen.c

Lines changed: 238 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: GPL-2.0
22
// Generated by xdrgen. Manual edits will be lost.
33
// XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x
4-
// XDR specification modification time: Thu Jan 8 23:11:48 2026
4+
// XDR specification modification time: Thu Jan 8 23:12:07 2026
55

66
#include <linux/sunrpc/svc.h>
77

@@ -30,6 +30,30 @@ xdrgen_decode_bitmap4(struct xdr_stream *xdr, bitmap4 *ptr)
3030
return true;
3131
}
3232

33+
static bool __maybe_unused
34+
xdrgen_decode_utf8string(struct xdr_stream *xdr, utf8string *ptr)
35+
{
36+
return xdrgen_decode_opaque(xdr, ptr, 0);
37+
}
38+
39+
static bool __maybe_unused
40+
xdrgen_decode_utf8str_cis(struct xdr_stream *xdr, utf8str_cis *ptr)
41+
{
42+
return xdrgen_decode_utf8string(xdr, ptr);
43+
}
44+
45+
static bool __maybe_unused
46+
xdrgen_decode_utf8str_cs(struct xdr_stream *xdr, utf8str_cs *ptr)
47+
{
48+
return xdrgen_decode_utf8string(xdr, ptr);
49+
}
50+
51+
static bool __maybe_unused
52+
xdrgen_decode_utf8str_mixed(struct xdr_stream *xdr, utf8str_mixed *ptr)
53+
{
54+
return xdrgen_decode_utf8string(xdr, ptr);
55+
}
56+
3357
static bool __maybe_unused
3458
xdrgen_decode_nfstime4(struct xdr_stream *xdr, struct nfstime4 *ptr)
3559
{
@@ -222,6 +246,125 @@ xdrgen_decode_open_delegation_type4(struct xdr_stream *xdr, open_delegation_type
222246
return true;
223247
}
224248

249+
bool
250+
xdrgen_decode_aclmodel4(struct xdr_stream *xdr, aclmodel4 *ptr)
251+
{
252+
u32 val;
253+
254+
if (xdr_stream_decode_u32(xdr, &val) < 0)
255+
return false;
256+
/* Compiler may optimize to a range check for dense enums */
257+
switch (val) {
258+
case ACL_MODEL_NFS4:
259+
case ACL_MODEL_POSIX_DRAFT:
260+
case ACL_MODEL_NONE:
261+
break;
262+
default:
263+
return false;
264+
}
265+
*ptr = val;
266+
return true;
267+
}
268+
269+
bool
270+
xdrgen_decode_aclscope4(struct xdr_stream *xdr, aclscope4 *ptr)
271+
{
272+
u32 val;
273+
274+
if (xdr_stream_decode_u32(xdr, &val) < 0)
275+
return false;
276+
/* Compiler may optimize to a range check for dense enums */
277+
switch (val) {
278+
case ACL_SCOPE_FILE_OBJECT:
279+
case ACL_SCOPE_FILE_SYSTEM:
280+
case ACL_SCOPE_SERVER:
281+
break;
282+
default:
283+
return false;
284+
}
285+
*ptr = val;
286+
return true;
287+
}
288+
289+
bool
290+
xdrgen_decode_posixacetag4(struct xdr_stream *xdr, posixacetag4 *ptr)
291+
{
292+
u32 val;
293+
294+
if (xdr_stream_decode_u32(xdr, &val) < 0)
295+
return false;
296+
/* Compiler may optimize to a range check for dense enums */
297+
switch (val) {
298+
case POSIXACE4_TAG_USER_OBJ:
299+
case POSIXACE4_TAG_USER:
300+
case POSIXACE4_TAG_GROUP_OBJ:
301+
case POSIXACE4_TAG_GROUP:
302+
case POSIXACE4_TAG_MASK:
303+
case POSIXACE4_TAG_OTHER:
304+
break;
305+
default:
306+
return false;
307+
}
308+
*ptr = val;
309+
return true;
310+
}
311+
312+
bool
313+
xdrgen_decode_posixaceperm4(struct xdr_stream *xdr, posixaceperm4 *ptr)
314+
{
315+
return xdrgen_decode_uint32_t(xdr, ptr);
316+
}
317+
318+
static bool __maybe_unused
319+
xdrgen_decode_posixace4(struct xdr_stream *xdr, struct posixace4 *ptr)
320+
{
321+
if (!xdrgen_decode_posixacetag4(xdr, &ptr->tag))
322+
return false;
323+
if (!xdrgen_decode_posixaceperm4(xdr, &ptr->perm))
324+
return false;
325+
if (!xdrgen_decode_utf8str_mixed(xdr, &ptr->who))
326+
return false;
327+
return true;
328+
}
329+
330+
static bool __maybe_unused
331+
xdrgen_decode_fattr4_acl_trueform(struct xdr_stream *xdr, fattr4_acl_trueform *ptr)
332+
{
333+
return xdrgen_decode_aclmodel4(xdr, ptr);
334+
}
335+
336+
static bool __maybe_unused
337+
xdrgen_decode_fattr4_acl_trueform_scope(struct xdr_stream *xdr, fattr4_acl_trueform_scope *ptr)
338+
{
339+
return xdrgen_decode_aclscope4(xdr, ptr);
340+
}
341+
342+
static bool __maybe_unused
343+
xdrgen_decode_fattr4_posix_default_acl(struct xdr_stream *xdr, fattr4_posix_default_acl *ptr)
344+
{
345+
if (xdr_stream_decode_u32(xdr, &ptr->count) < 0)
346+
return false;
347+
for (u32 i = 0; i < ptr->count; i++)
348+
if (!xdrgen_decode_posixace4(xdr, &ptr->element[i]))
349+
return false;
350+
return true;
351+
}
352+
353+
static bool __maybe_unused
354+
xdrgen_decode_fattr4_posix_access_acl(struct xdr_stream *xdr, fattr4_posix_access_acl *ptr)
355+
{
356+
if (xdr_stream_decode_u32(xdr, &ptr->count) < 0)
357+
return false;
358+
for (u32 i = 0; i < ptr->count; i++)
359+
if (!xdrgen_decode_posixace4(xdr, &ptr->element[i]))
360+
return false;
361+
return true;
362+
}
363+
364+
/*
365+
* New for POSIX ACL extension
366+
*/
367+
225368
static bool __maybe_unused
226369
xdrgen_encode_int64_t(struct xdr_stream *xdr, const int64_t value)
227370
{
@@ -245,6 +388,30 @@ xdrgen_encode_bitmap4(struct xdr_stream *xdr, const bitmap4 value)
245388
return true;
246389
}
247390

391+
static bool __maybe_unused
392+
xdrgen_encode_utf8string(struct xdr_stream *xdr, const utf8string value)
393+
{
394+
return xdr_stream_encode_opaque(xdr, value.data, value.len) >= 0;
395+
}
396+
397+
static bool __maybe_unused
398+
xdrgen_encode_utf8str_cis(struct xdr_stream *xdr, const utf8str_cis value)
399+
{
400+
return xdrgen_encode_utf8string(xdr, value);
401+
}
402+
403+
static bool __maybe_unused
404+
xdrgen_encode_utf8str_cs(struct xdr_stream *xdr, const utf8str_cs value)
405+
{
406+
return xdrgen_encode_utf8string(xdr, value);
407+
}
408+
409+
static bool __maybe_unused
410+
xdrgen_encode_utf8str_mixed(struct xdr_stream *xdr, const utf8str_mixed value)
411+
{
412+
return xdrgen_encode_utf8string(xdr, value);
413+
}
414+
248415
static bool __maybe_unused
249416
xdrgen_encode_nfstime4(struct xdr_stream *xdr, const struct nfstime4 *value)
250417
{
@@ -330,3 +497,73 @@ xdrgen_encode_open_delegation_type4(struct xdr_stream *xdr, open_delegation_type
330497
{
331498
return xdr_stream_encode_u32(xdr, value) == XDR_UNIT;
332499
}
500+
501+
bool
502+
xdrgen_encode_aclmodel4(struct xdr_stream *xdr, aclmodel4 value)
503+
{
504+
return xdr_stream_encode_u32(xdr, value) == XDR_UNIT;
505+
}
506+
507+
bool
508+
xdrgen_encode_aclscope4(struct xdr_stream *xdr, aclscope4 value)
509+
{
510+
return xdr_stream_encode_u32(xdr, value) == XDR_UNIT;
511+
}
512+
513+
bool
514+
xdrgen_encode_posixacetag4(struct xdr_stream *xdr, posixacetag4 value)
515+
{
516+
return xdr_stream_encode_u32(xdr, value) == XDR_UNIT;
517+
}
518+
519+
bool
520+
xdrgen_encode_posixaceperm4(struct xdr_stream *xdr, const posixaceperm4 value)
521+
{
522+
return xdrgen_encode_uint32_t(xdr, value);
523+
}
524+
525+
static bool __maybe_unused
526+
xdrgen_encode_posixace4(struct xdr_stream *xdr, const struct posixace4 *value)
527+
{
528+
if (!xdrgen_encode_posixacetag4(xdr, value->tag))
529+
return false;
530+
if (!xdrgen_encode_posixaceperm4(xdr, value->perm))
531+
return false;
532+
if (!xdrgen_encode_utf8str_mixed(xdr, value->who))
533+
return false;
534+
return true;
535+
}
536+
537+
static bool __maybe_unused
538+
xdrgen_encode_fattr4_acl_trueform(struct xdr_stream *xdr, const fattr4_acl_trueform value)
539+
{
540+
return xdrgen_encode_aclmodel4(xdr, value);
541+
}
542+
543+
static bool __maybe_unused
544+
xdrgen_encode_fattr4_acl_trueform_scope(struct xdr_stream *xdr, const fattr4_acl_trueform_scope value)
545+
{
546+
return xdrgen_encode_aclscope4(xdr, value);
547+
}
548+
549+
static bool __maybe_unused
550+
xdrgen_encode_fattr4_posix_default_acl(struct xdr_stream *xdr, const fattr4_posix_default_acl value)
551+
{
552+
if (xdr_stream_encode_u32(xdr, value.count) != XDR_UNIT)
553+
return false;
554+
for (u32 i = 0; i < value.count; i++)
555+
if (!xdrgen_encode_posixace4(xdr, &value.element[i]))
556+
return false;
557+
return true;
558+
}
559+
560+
static bool __maybe_unused
561+
xdrgen_encode_fattr4_posix_access_acl(struct xdr_stream *xdr, const fattr4_posix_access_acl value)
562+
{
563+
if (xdr_stream_encode_u32(xdr, value.count) != XDR_UNIT)
564+
return false;
565+
for (u32 i = 0; i < value.count; i++)
566+
if (!xdrgen_encode_posixace4(xdr, &value.element[i]))
567+
return false;
568+
return true;
569+
}

fs/nfsd/nfs4xdr_gen.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
22
/* Generated by xdrgen. Manual edits will be lost. */
33
/* XDR specification file: ../../Documentation/sunrpc/xdr/nfs4_1.x */
4-
/* XDR specification modification time: Thu Jan 8 23:11:48 2026 */
4+
/* XDR specification modification time: Thu Jan 8 23:12:07 2026 */
55

66
#ifndef _LINUX_XDRGEN_NFS4_1_DECL_H
77
#define _LINUX_XDRGEN_NFS4_1_DECL_H
@@ -21,5 +21,15 @@ bool xdrgen_encode_fattr4_time_deleg_access(struct xdr_stream *xdr, const fattr4
2121

2222
bool xdrgen_decode_fattr4_time_deleg_modify(struct xdr_stream *xdr, fattr4_time_deleg_modify *ptr);
2323
bool xdrgen_encode_fattr4_time_deleg_modify(struct xdr_stream *xdr, const fattr4_time_deleg_modify *value);
24+
bool xdrgen_decode_aclmodel4(struct xdr_stream *xdr, aclmodel4 *ptr);
25+
bool xdrgen_encode_aclmodel4(struct xdr_stream *xdr, aclmodel4 value);
26+
bool xdrgen_decode_aclscope4(struct xdr_stream *xdr, aclscope4 *ptr);
27+
bool xdrgen_encode_aclscope4(struct xdr_stream *xdr, aclscope4 value);
28+
bool xdrgen_decode_posixacetag4(struct xdr_stream *xdr, posixacetag4 *ptr);
29+
bool xdrgen_encode_posixacetag4(struct xdr_stream *xdr, posixacetag4 value);
30+
31+
bool xdrgen_decode_posixaceperm4(struct xdr_stream *xdr, posixaceperm4 *ptr);
32+
bool xdrgen_encode_posixaceperm4(struct xdr_stream *xdr, const posixaceperm4 value);
33+
2434

2535
#endif /* _LINUX_XDRGEN_NFS4_1_DECL_H */

include/linux/nfs4.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,10 @@ enum {
598598
#define FATTR4_WORD2_TIME_DELEG_ACCESS BIT(FATTR4_TIME_DELEG_ACCESS - 64)
599599
#define FATTR4_WORD2_TIME_DELEG_MODIFY BIT(FATTR4_TIME_DELEG_MODIFY - 64)
600600
#define FATTR4_WORD2_OPEN_ARGUMENTS BIT(FATTR4_OPEN_ARGUMENTS - 64)
601+
#define FATTR4_WORD2_ACL_TRUEFORM BIT(FATTR4_ACL_TRUEFORM - 64)
602+
#define FATTR4_WORD2_ACL_TRUEFORM_SCOPE BIT(FATTR4_ACL_TRUEFORM_SCOPE - 64)
603+
#define FATTR4_WORD2_POSIX_DEFAULT_ACL BIT(FATTR4_POSIX_DEFAULT_ACL - 64)
604+
#define FATTR4_WORD2_POSIX_ACCESS_ACL BIT(FATTR4_POSIX_ACCESS_ACL - 64)
601605

602606
/* MDS threshold bitmap bits */
603607
#define THRESHOLD_RD (1UL << 0)

0 commit comments

Comments
 (0)