Skip to content

Commit ae62bcb

Browse files
amir73ilbrauner
authored andcommitted
fs: report f_fsid from s_dev for "simple" filesystems
There are many "simple" filesystems (*) that report null f_fsid in statfs(2). Those "simple" filesystems report sb->s_dev as the st_dev field of the stat syscalls for all inodes of the filesystem (**). In order to enable fanotify reporting of events with fsid on those "simple" filesystems, report the sb->s_dev number in f_fsid field of statfs(2). (*) For most of the "simple" filesystem refered to in this commit, the ->statfs() operation is simple_statfs(). Some of those fs assign the simple_statfs() method directly in their ->s_op struct and some assign it indirectly via a call to simple_fill_super() or to pseudo_fs_fill_super() with either custom or "simple" s_op. We also make the same change to efivarfs and hugetlbfs, although they do not use simple_statfs(), because they use the simple_* inode opreations (e.g. simple_lookup()). (**) For most of the "simple" filesystems, the ->getattr() method is not assigned, so stat() is implemented by generic_fillattr(). A few "simple" filesystem use the simple_getattr() method which also calls generic_fillattr() to fill most of the stat struct. The two exceptions are procfs and 9p. procfs implements several different ->getattr() methods, but they all end up calling generic_fillattr() to fill the st_dev field from sb->s_dev. 9p has more complicated ->getattr() methods, but they too, end up calling generic_fillattr() to fill the st_dev field from sb->s_dev. Note that 9p and kernfs also call simple_statfs() from custom ->statfs() methods which already fill the f_fsid field, but v9fs_statfs() calls simple_statfs() only in case f_fsid was not filled and kenrfs_statfs() overwrites f_fsid after calling simple_statfs(). Link: https://lore.kernel.org/r/20230919094820.g5bwharbmy2dq46w@quack3/ Signed-off-by: Amir Goldstein <amir73il@gmail.com> Link: https://lore.kernel.org/r/20231023143049.2944970-1-amir73il@gmail.com Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 6434311 commit ae62bcb

File tree

3 files changed

+7
-0
lines changed

3 files changed

+7
-0
lines changed

fs/efivarfs/super.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
3030
EFI_VARIABLE_BOOTSERVICE_ACCESS |
3131
EFI_VARIABLE_RUNTIME_ACCESS;
3232
u64 storage_space, remaining_space, max_variable_size;
33+
u64 id = huge_encode_dev(dentry->d_sb->s_dev);
3334
efi_status_t status;
3435

3536
/* Some UEFI firmware does not implement QueryVariableInfo() */
@@ -53,6 +54,7 @@ static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
5354
buf->f_blocks = storage_space;
5455
buf->f_bfree = remaining_space;
5556
buf->f_type = dentry->d_sb->s_magic;
57+
buf->f_fsid = u64_to_fsid(id);
5658

5759
/*
5860
* In f_bavail we declare the free space that the kernel will allow writing

fs/hugetlbfs/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,9 @@ static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
12041204
{
12051205
struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
12061206
struct hstate *h = hstate_inode(d_inode(dentry));
1207+
u64 id = huge_encode_dev(dentry->d_sb->s_dev);
12071208

1209+
buf->f_fsid = u64_to_fsid(id);
12081210
buf->f_type = HUGETLBFS_MAGIC;
12091211
buf->f_bsize = huge_page_size(h);
12101212
if (sbinfo) {

fs/libfs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ EXPORT_SYMBOL(simple_getattr);
4141

4242
int simple_statfs(struct dentry *dentry, struct kstatfs *buf)
4343
{
44+
u64 id = huge_encode_dev(dentry->d_sb->s_dev);
45+
46+
buf->f_fsid = u64_to_fsid(id);
4447
buf->f_type = dentry->d_sb->s_magic;
4548
buf->f_bsize = PAGE_SIZE;
4649
buf->f_namelen = NAME_MAX;

0 commit comments

Comments
 (0)