Message ID | 20220418213713.273050-3-krisman@collabora.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | shmem: Allow userspace monitoring of tmpfs for lack of space. | expand |
Hi Gabriel, url: https://github.com/intel-lab-lkp/linux/commits/Gabriel-Krisman-Bertazi/shmem-Allow-userspace-monitoring-of-tmpfs-for-lack-of-space/20220419-054011 base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git b2d229d4ddb17db541098b83524d901257e93845 config: ia64-randconfig-m031-20220418 (https://download.01.org/0day-ci/archive/20220420/202204200819.72S8HjcF-lkp@intel.com/config) compiler: ia64-linux-gcc (GCC) 11.2.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> smatch warnings: mm/shmem.c:3965 shmem_init() warn: passing zero to 'ERR_PTR' vim +/ERR_PTR +3965 mm/shmem.c 41ffe5d5ceef7f Hugh Dickins 2011-08-03 3928 int __init shmem_init(void) ^1da177e4c3f41 Linus Torvalds 2005-04-16 3929 { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3930 int error; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3931 9a8ec03ed022b7 weiping zhang 2017-11-15 3932 shmem_init_inodecache(); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3933 41ffe5d5ceef7f Hugh Dickins 2011-08-03 3934 error = register_filesystem(&shmem_fs_type); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3935 if (error) { 1170532bb49f94 Joe Perches 2016-03-17 3936 pr_err("Could not register tmpfs\n"); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3937 goto out2; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3938 } 95dc112a5770dc Greg Kroah-Hartman 2005-06-20 3939 e43933b9793ad3 Gabriel Krisman Bertazi 2022-04-18 3940 shmem_root = kobject_create_and_add("tmpfs", fs_kobj); e43933b9793ad3 Gabriel Krisman Bertazi 2022-04-18 3941 if (!shmem_root) e43933b9793ad3 Gabriel Krisman Bertazi 2022-04-18 3942 goto out1; error = -ENOMEM; e43933b9793ad3 Gabriel Krisman Bertazi 2022-04-18 3943 ca4e05195dbc25 Al Viro 2013-08-31 3944 shm_mnt = kern_mount(&shmem_fs_type); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3945 if (IS_ERR(shm_mnt)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 3946 error = PTR_ERR(shm_mnt); 1170532bb49f94 Joe Perches 2016-03-17 3947 pr_err("Could not kern_mount tmpfs\n"); e43933b9793ad3 Gabriel Krisman Bertazi 2022-04-18 3948 goto put_kobj; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3949 } 5a6e75f8110c97 Kirill A. Shutemov 2016-07-26 3950 396bcc5299c281 Matthew Wilcox (Oracle 2020-04-06 3951) #ifdef CONFIG_TRANSPARENT_HUGEPAGE 435c0b87d661da Kirill A. Shutemov 2017-08-25 3952 if (has_transparent_hugepage() && shmem_huge > SHMEM_HUGE_DENY) 5a6e75f8110c97 Kirill A. Shutemov 2016-07-26 3953 SHMEM_SB(shm_mnt->mnt_sb)->huge = shmem_huge; 5a6e75f8110c97 Kirill A. Shutemov 2016-07-26 3954 else 5e6e5a12a44ca5 Hugh Dickins 2021-09-02 3955 shmem_huge = SHMEM_HUGE_NEVER; /* just in case it was patched */ 5a6e75f8110c97 Kirill A. Shutemov 2016-07-26 3956 #endif ^1da177e4c3f41 Linus Torvalds 2005-04-16 3957 return 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3958 e43933b9793ad3 Gabriel Krisman Bertazi 2022-04-18 3959 put_kobj: e43933b9793ad3 Gabriel Krisman Bertazi 2022-04-18 3960 kobject_put(shmem_root); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3961 out1: 41ffe5d5ceef7f Hugh Dickins 2011-08-03 3962 unregister_filesystem(&shmem_fs_type); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3963 out2: 41ffe5d5ceef7f Hugh Dickins 2011-08-03 3964 shmem_destroy_inodecache(); ^1da177e4c3f41 Linus Torvalds 2005-04-16 @3965 shm_mnt = ERR_PTR(error); ^1da177e4c3f41 Linus Torvalds 2005-04-16 3966 return error; ^1da177e4c3f41 Linus Torvalds 2005-04-16 3967 }
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 1a7cd9ea9107..6c1f3a4b8c46 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -47,6 +47,8 @@ struct shmem_sb_info { unsigned long acct_errors; unsigned long space_errors; + + struct kobject kobj; }; static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) diff --git a/mm/shmem.c b/mm/shmem.c index c350fa0a0fff..8fe4a22e83a6 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -250,6 +250,7 @@ static const struct inode_operations shmem_dir_inode_operations; static const struct inode_operations shmem_special_inode_operations; static const struct vm_operations_struct shmem_vm_ops; static struct file_system_type shmem_fs_type; +static struct kobject *shmem_root; bool vma_is_shmem(struct vm_area_struct *vma) { @@ -3582,17 +3583,44 @@ static int shmem_show_options(struct seq_file *seq, struct dentry *root) return 0; } +#if defined(CONFIG_SYSFS) +#define TMPFS_SB_ATTR_RO(name) \ + static struct kobj_attribute tmpfs_sb_attr_##name = __ATTR_RO(name) + +static struct attribute *tmpfs_attrs[] = { + NULL +}; +ATTRIBUTE_GROUPS(tmpfs); +#endif /* CONFIG_SYSFS */ + #endif /* CONFIG_TMPFS */ -static void shmem_put_super(struct super_block *sb) +static void tmpfs_sb_release(struct kobject *kobj) { - struct shmem_sb_info *sbinfo = SHMEM_SB(sb); + struct shmem_sb_info *sbinfo = + container_of(kobj, struct shmem_sb_info, kobj); free_percpu(sbinfo->ino_batch); percpu_counter_destroy(&sbinfo->used_blocks); mpol_put(sbinfo->mpol); kfree(sbinfo); +} + +static struct kobj_type tmpfs_sb_ktype = { +#if defined(CONFIG_TMPFS) && defined(CONFIG_SYSFS) + .default_groups = tmpfs_groups, +#endif + .sysfs_ops = &kobj_sysfs_ops, + .release = tmpfs_sb_release, +}; + +static void shmem_put_super(struct super_block *sb) +{ + struct shmem_sb_info *sbinfo = SHMEM_SB(sb); + sb->s_fs_info = NULL; + + kobject_put(&sbinfo->kobj); } static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) @@ -3608,6 +3636,7 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) return -ENOMEM; sb->s_fs_info = sbinfo; + kobject_init(&sbinfo->kobj, &tmpfs_sb_ktype); #ifdef CONFIG_TMPFS /* @@ -3673,6 +3702,11 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_root = d_make_root(inode); if (!sb->s_root) goto failed; + + if (!(sb->s_flags & SB_NOUSER) && + kobject_add(&sbinfo->kobj, shmem_root, "%d", MINOR(sb->s_dev))) + goto failed; + return 0; failed: @@ -3889,11 +3923,15 @@ int __init shmem_init(void) goto out2; } + shmem_root = kobject_create_and_add("tmpfs", fs_kobj); + if (!shmem_root) + goto out1; + shm_mnt = kern_mount(&shmem_fs_type); if (IS_ERR(shm_mnt)) { error = PTR_ERR(shm_mnt); pr_err("Could not kern_mount tmpfs\n"); - goto out1; + goto put_kobj; } #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -3904,6 +3942,8 @@ int __init shmem_init(void) #endif return 0; +put_kobj: + kobject_put(shmem_root); out1: unregister_filesystem(&shmem_fs_type); out2:
In order to expose tmpfs statistics on sysfs, add the boilerplate code to create the /sys/fs/tmpfs structure. As suggested on a previous review, this uses the minor as the volume directory in /sys/fs/. This takes care of not exposing SB_NOUSER mounts. I don't think we have a usecase for showing them and, since they don't appear elsewhere, they might be confusing to users. Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com> --- Changes since v2: - Use kobject to release sbinfo (Viro) Changes since v1: - Use minor instead of fsid for directory in sysfs. (Amir) --- include/linux/shmem_fs.h | 2 ++ mm/shmem.c | 46 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-)