diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2025-11-19 19:45:04 -0500 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2026-01-13 15:16:44 -0500 |
| commit | 8c888b31903cc2acfbf054c23d702caf68857810 (patch) | |
| tree | b8677601b8a43f4fec6990d12ca1a07fbcd74a60 /include/linux | |
| parent | c3a3577cdb351e74d6ff6bc328c3bee18ce69298 (diff) | |
struct filename: saner handling of long names
Always allocate struct filename from names_cachep, long name or short;
short names would be embedded into struct filename. Longer ones do
not cannibalize the original struct filename - put them into kmalloc'ed
buffers (PATH_MAX-sized for import from userland, strlen() + 1 - for
ones originating kernel-side, where we know the length beforehand).
Cutoff length for short names is chosen so that struct filename would be
192 bytes long - that's both a multiple of 64 and large enough to cover
the majority of real-world uses.
Simplifies logics in getname()/putname() and friends.
[fixed an embarrassing braino in EMBEDDED_NAME_MAX, first reported by
Dan Carpenter]
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/fs.h | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index 997d515bab32..f0f1e8034539 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2409,13 +2409,19 @@ extern struct kobject *fs_kobj; /* fs/open.c */ struct audit_names; -struct filename { + +struct __filename_head { const char *name; /* pointer to actual string */ atomic_t refcnt; struct audit_names *aname; - const char iname[]; +}; +#define EMBEDDED_NAME_MAX (192 - sizeof(struct __filename_head)) +struct filename { + struct __filename_head; + const char iname[EMBEDDED_NAME_MAX]; }; static_assert(offsetof(struct filename, iname) % sizeof(long) == 0); +static_assert(sizeof(struct filename) % 64 == 0); static inline struct mnt_idmap *file_mnt_idmap(const struct file *file) { |
