| /* SPDX-License-Identifier: GPL-2.0 */ |
| /* |
| * NFSv4 file attributes supported by this implementation |
| */ |
| |
| #ifndef _LINUX_NFSD_ATTR4_H |
| #define _LINUX_NFSD_ATTR4_H |
| |
| #include <linux/types.h> |
| #include <linux/nfs4.h> |
| |
| /* |
| * The following attributes are not implemented by NFSD: |
| * ARCHIVE (deprecated anyway) |
| * HIDDEN (unlikely to be supported any time soon) |
| * MIMETYPE (unlikely to be supported any time soon) |
| * QUOTA_* (unlikely to be supported any time soon) |
| * SYSTEM (unlikely to be supported any time soon) |
| * TIME_BACKUP (unlikely to be supported any time soon) |
| */ |
| #define NFSD4_SUPPORTED_ATTRS_WORD0 \ |
| (FATTR4_WORD0_SUPPORTED_ATTRS | FATTR4_WORD0_TYPE | FATTR4_WORD0_FH_EXPIRE_TYPE \ |
| | FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE | FATTR4_WORD0_LINK_SUPPORT \ |
| | FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR | FATTR4_WORD0_FSID \ |
| | FATTR4_WORD0_UNIQUE_HANDLES | FATTR4_WORD0_LEASE_TIME | FATTR4_WORD0_RDATTR_ERROR \ |
| | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_CANSETTIME | FATTR4_WORD0_CASE_INSENSITIVE \ |
| | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED \ |
| | FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FILEID | FATTR4_WORD0_FILES_AVAIL \ |
| | FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_HOMOGENEOUS \ |
| | FATTR4_WORD0_MAXFILESIZE | FATTR4_WORD0_MAXLINK | FATTR4_WORD0_MAXNAME \ |
| | FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE | FATTR4_WORD0_ACL) |
| |
| #define NFSD4_SUPPORTED_ATTRS_WORD1 \ |
| (FATTR4_WORD1_MODE | FATTR4_WORD1_NO_TRUNC | FATTR4_WORD1_NUMLINKS \ |
| | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV \ |
| | FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL \ |
| | FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | FATTR4_WORD1_TIME_ACCESS_SET \ |
| | FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_CREATE \ |
| | FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID) |
| |
| #define NFSD4_SUPPORTED_ATTRS_WORD2 0 |
| |
| /* 4.1 */ |
| #ifdef CONFIG_NFSD_PNFS |
| #define PNFSD_SUPPORTED_ATTRS_WORD1 FATTR4_WORD1_FS_LAYOUT_TYPES |
| #define PNFSD_SUPPORTED_ATTRS_WORD2 \ |
| (FATTR4_WORD2_LAYOUT_BLKSIZE | FATTR4_WORD2_LAYOUT_TYPES) |
| #else |
| #define PNFSD_SUPPORTED_ATTRS_WORD1 0 |
| #define PNFSD_SUPPORTED_ATTRS_WORD2 0 |
| #endif /* CONFIG_NFSD_PNFS */ |
| |
| #define NFSD4_1_SUPPORTED_ATTRS_WORD0 \ |
| NFSD4_SUPPORTED_ATTRS_WORD0 |
| |
| #define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ |
| (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1) |
| |
| #define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ |
| (NFSD4_SUPPORTED_ATTRS_WORD2 | PNFSD_SUPPORTED_ATTRS_WORD2 | \ |
| FATTR4_WORD2_SUPPATTR_EXCLCREAT) |
| |
| /* 4.2 */ |
| #ifdef CONFIG_NFSD_V4_SECURITY_LABEL |
| #define NFSD4_2_SECURITY_ATTRS FATTR4_WORD2_SECURITY_LABEL |
| #else |
| #define NFSD4_2_SECURITY_ATTRS 0 |
| #endif |
| |
| #ifdef CONFIG_NFSD_V4_POSIX_ACLS |
| #define NFSD4_2_POSIX_ACL_ATTRS \ |
| (FATTR4_WORD2_ACL_TRUEFORM | \ |
| FATTR4_WORD2_ACL_TRUEFORM_SCOPE | \ |
| FATTR4_WORD2_POSIX_DEFAULT_ACL | \ |
| FATTR4_WORD2_POSIX_ACCESS_ACL) |
| #else |
| #define NFSD4_2_POSIX_ACL_ATTRS 0 |
| #endif |
| |
| #define NFSD4_2_SUPPORTED_ATTRS_WORD2 \ |
| (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \ |
| FATTR4_WORD2_MODE_UMASK | \ |
| FATTR4_WORD2_CLONE_BLKSIZE | \ |
| NFSD4_2_SECURITY_ATTRS | \ |
| FATTR4_WORD2_XATTR_SUPPORT | \ |
| FATTR4_WORD2_TIME_DELEG_ACCESS | \ |
| FATTR4_WORD2_TIME_DELEG_MODIFY | \ |
| FATTR4_WORD2_OPEN_ARGUMENTS | \ |
| NFSD4_2_POSIX_ACL_ATTRS) |
| |
| /* These will return ERR_INVAL if specified in GETATTR or READDIR. */ |
| #define NFSD_WRITEONLY_ATTRS_WORD1 \ |
| (FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) |
| |
| /* |
| * These are the only attrs allowed in CREATE/OPEN/SETATTR. Don't add |
| * a writeable attribute here without also adding code to parse it to |
| * nfsd4_decode_fattr4(). |
| */ |
| #define NFSD_WRITEABLE_ATTRS_WORD0 \ |
| (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL) |
| #define NFSD_WRITEABLE_ATTRS_WORD1 \ |
| (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ |
| | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_CREATE \ |
| | FATTR4_WORD1_TIME_MODIFY_SET) |
| #ifdef CONFIG_NFSD_V4_SECURITY_LABEL |
| #define MAYBE_FATTR4_WORD2_SECURITY_LABEL \ |
| FATTR4_WORD2_SECURITY_LABEL |
| #else |
| #define MAYBE_FATTR4_WORD2_SECURITY_LABEL 0 |
| #endif |
| #ifdef CONFIG_NFSD_V4_POSIX_ACLS |
| #define MAYBE_FATTR4_WORD2_POSIX_ACL_ATTRS \ |
| FATTR4_WORD2_POSIX_DEFAULT_ACL | FATTR4_WORD2_POSIX_ACCESS_ACL |
| #else |
| #define MAYBE_FATTR4_WORD2_POSIX_ACL_ATTRS 0 |
| #endif |
| #define NFSD_WRITEABLE_ATTRS_WORD2 \ |
| (FATTR4_WORD2_MODE_UMASK \ |
| | MAYBE_FATTR4_WORD2_SECURITY_LABEL \ |
| | FATTR4_WORD2_TIME_DELEG_ACCESS \ |
| | FATTR4_WORD2_TIME_DELEG_MODIFY \ |
| | MAYBE_FATTR4_WORD2_POSIX_ACL_ATTRS \ |
| ) |
| |
| #define NFSD_SUPPATTR_EXCLCREAT_WORD0 \ |
| NFSD_WRITEABLE_ATTRS_WORD0 |
| /* |
| * we currently store the exclusive create verifier in the v_{a,m}time |
| * attributes so the client can't set these at create time using EXCLUSIVE4_1 |
| */ |
| #define NFSD_SUPPATTR_EXCLCREAT_WORD1 \ |
| (NFSD_WRITEABLE_ATTRS_WORD1 & \ |
| ~(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)) |
| /* |
| * The FATTR4_WORD2_TIME_DELEG attributes are not to be allowed for |
| * OPEN(create) with EXCLUSIVE4_1. It doesn't make sense to set a |
| * delegated timestamp on a new file. |
| * |
| * This mask includes NFSv4.2-only attributes (e.g., POSIX ACLs). |
| * Version filtering occurs via nfsd_suppattrs[] before this mask |
| * is applied, so pre-4.2 clients never see unsupported attributes. |
| */ |
| #define NFSD_SUPPATTR_EXCLCREAT_WORD2 \ |
| (NFSD_WRITEABLE_ATTRS_WORD2 & \ |
| ~(FATTR4_WORD2_TIME_DELEG_ACCESS | FATTR4_WORD2_TIME_DELEG_MODIFY)) |
| |
| extern const u32 nfsd_suppattrs[3][3]; |
| |
| static inline bool bmval_is_subset(const u32 *bm1, const u32 *bm2) |
| { |
| return !((bm1[0] & ~bm2[0]) || |
| (bm1[1] & ~bm2[1]) || |
| (bm1[2] & ~bm2[2])); |
| } |
| |
| static inline bool nfsd_attrs_supported(u32 minorversion, const u32 *bmval) |
| { |
| return bmval_is_subset(bmval, nfsd_suppattrs[minorversion]); |
| } |
| |
| #endif /* _LINUX_NFSD_ATTR4_H */ |