statx: Include a mask for stx_attributes in struct statx

Include a mask in struct stat to indicate which bits of stx_attributes the
filesystem actually supports.

This would also be useful if we add another system call that allows you to
do a 'bulk attribute set' and pass in a statx struct with the masks
appropriately set to say what you want to set.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by David Howells and committed by Al Viro 3209f68b 47071aee

+18 -6
+6
fs/ext4/inode.c
··· 5413 5413 if (flags & EXT4_NODUMP_FL) 5414 5414 stat->attributes |= STATX_ATTR_NODUMP; 5415 5415 5416 + stat->attributes_mask |= (STATX_ATTR_APPEND | 5417 + STATX_ATTR_COMPRESSED | 5418 + STATX_ATTR_ENCRYPTED | 5419 + STATX_ATTR_IMMUTABLE | 5420 + STATX_ATTR_NODUMP); 5421 + 5416 5422 generic_fillattr(inode, stat); 5417 5423 return 0; 5418 5424 }
+1
fs/stat.c
··· 527 527 tmp.stx_ino = stat->ino; 528 528 tmp.stx_size = stat->size; 529 529 tmp.stx_blocks = stat->blocks; 530 + tmp.stx_attributes_mask = stat->attributes_mask; 530 531 tmp.stx_atime.tv_sec = stat->atime.tv_sec; 531 532 tmp.stx_atime.tv_nsec = stat->atime.tv_nsec; 532 533 tmp.stx_btime.tv_sec = stat->btime.tv_sec;
+1
include/linux/stat.h
··· 26 26 unsigned int nlink; 27 27 uint32_t blksize; /* Preferred I/O size */ 28 28 u64 attributes; 29 + u64 attributes_mask; 29 30 #define KSTAT_ATTR_FS_IOC_FLAGS \ 30 31 (STATX_ATTR_COMPRESSED | \ 31 32 STATX_ATTR_IMMUTABLE | \
+2 -2
include/uapi/linux/stat.h
··· 114 114 __u64 stx_ino; /* Inode number */ 115 115 __u64 stx_size; /* File size */ 116 116 __u64 stx_blocks; /* Number of 512-byte blocks allocated */ 117 - __u64 __spare1[1]; 117 + __u64 stx_attributes_mask; /* Mask to show what's supported in stx_attributes */ 118 118 /* 0x40 */ 119 119 struct statx_timestamp stx_atime; /* Last access time */ 120 120 struct statx_timestamp stx_btime; /* File creation time */ ··· 155 155 #define STATX__RESERVED 0x80000000U /* Reserved for future struct statx expansion */ 156 156 157 157 /* 158 - * Attributes to be found in stx_attributes 158 + * Attributes to be found in stx_attributes and masked in stx_attributes_mask. 159 159 * 160 160 * These give information about the features or the state of a file that might 161 161 * be of use to ordinary userspace programs such as GUIs or ls rather than
+8 -4
samples/statx/test-statx.c
··· 141 141 if (stx->stx_mask & STATX_BTIME) 142 142 print_time(" Birth: ", &stx->stx_btime); 143 143 144 - if (stx->stx_attributes) { 145 - unsigned char bits; 144 + if (stx->stx_attributes_mask) { 145 + unsigned char bits, mbits; 146 146 int loop, byte; 147 147 148 148 static char attr_representation[64 + 1] = ··· 160 160 printf("Attributes: %016llx (", stx->stx_attributes); 161 161 for (byte = 64 - 8; byte >= 0; byte -= 8) { 162 162 bits = stx->stx_attributes >> byte; 163 + mbits = stx->stx_attributes_mask >> byte; 163 164 for (loop = 7; loop >= 0; loop--) { 164 165 int bit = byte + loop; 165 166 166 - if (bits & 0x80) 167 + if (!(mbits & 0x80)) 168 + putchar('.'); /* Not supported */ 169 + else if (bits & 0x80) 167 170 putchar(attr_representation[63 - bit]); 168 171 else 169 - putchar('-'); 172 + putchar('-'); /* Not set */ 170 173 bits <<= 1; 174 + mbits <<= 1; 171 175 } 172 176 if (byte) 173 177 putchar(' ');