summaryrefslogtreecommitdiffstats
path: root/fs/afs/xdr_fs.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-01-05 11:55:46 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2021-01-05 11:55:46 -0800
commit6207214a70bfaec7b41f39502353fd3ca89df68c (patch)
tree547beaa1e89ca94318ec2854fe3beeb17637b389 /fs/afs/xdr_fs.h
parentc2407cf7d22d0c0d94cf20342b3b8f06f1d904e7 (diff)
parent366911cd762db02c2dd32fad1be96b72a66f205d (diff)
Merge tag 'afs-fixes-04012021' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull AFS fixes from David Howells: "Two fixes. The first is the fix for the strnlen() array limit check and the second fixes the calculation of the number of dirent records used to represent any particular filename length" * tag 'afs-fixes-04012021' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: afs: Fix directory entry size calculation afs: Work around strnlen() oops with CONFIG_FORTIFIED_SOURCE=y
Diffstat (limited to 'fs/afs/xdr_fs.h')
-rw-r--r--fs/afs/xdr_fs.h25
1 files changed, 21 insertions, 4 deletions
diff --git a/fs/afs/xdr_fs.h b/fs/afs/xdr_fs.h
index 94f1f398eefa..8ca868164507 100644
--- a/fs/afs/xdr_fs.h
+++ b/fs/afs/xdr_fs.h
@@ -54,10 +54,16 @@ union afs_xdr_dirent {
__be16 hash_next;
__be32 vnode;
__be32 unique;
- u8 name[16];
- u8 overflow[4]; /* if any char of the name (inc
- * NUL) reaches here, consume
- * the next dirent too */
+ u8 name[];
+ /* When determining the number of dirent slots needed to
+ * represent a directory entry, name should be assumed to be 16
+ * bytes, due to a now-standardised (mis)calculation, but it is
+ * in fact 20 bytes in size. afs_dir_calc_slots() should be
+ * used for this.
+ *
+ * For names longer than (16 or) 20 bytes, extra slots should
+ * be annexed to this one using the extended_name format.
+ */
} u;
u8 extended_name[32];
} __packed;
@@ -96,4 +102,15 @@ struct afs_xdr_dir_page {
union afs_xdr_dir_block blocks[AFS_DIR_BLOCKS_PER_PAGE];
};
+/*
+ * Calculate the number of dirent slots required for any given name length.
+ * The calculation is made assuming the part of the name in the first slot is
+ * 16 bytes, rather than 20, but this miscalculation is now standardised.
+ */
+static inline unsigned int afs_dir_calc_slots(size_t name_len)
+{
+ name_len++; /* NUL-terminated */
+ return 1 + ((name_len + 15) / AFS_DIR_DIRENT_SIZE);
+}
+
#endif /* XDR_FS_H */