diff options
-rw-r--r-- | fs/zonefs/super.c | 48 | ||||
-rw-r--r-- | fs/zonefs/zonefs.h | 1 |
2 files changed, 49 insertions, 0 deletions
diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index 7d70c327883e..010b53545e5b 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -1199,6 +1199,42 @@ static const struct super_operations zonefs_sops = { .show_options = zonefs_show_options, }; +static int zonefs_get_zgroup_inodes(struct super_block *sb) +{ + struct zonefs_sb_info *sbi = ZONEFS_SB(sb); + struct inode *dir_inode; + enum zonefs_ztype ztype; + + for (ztype = 0; ztype < ZONEFS_ZTYPE_MAX; ztype++) { + if (!sbi->s_zgroup[ztype].g_nr_zones) + continue; + + dir_inode = zonefs_get_zgroup_inode(sb, ztype); + if (IS_ERR(dir_inode)) + return PTR_ERR(dir_inode); + + sbi->s_zgroup[ztype].g_inode = dir_inode; + } + + return 0; +} + +static void zonefs_release_zgroup_inodes(struct super_block *sb) +{ + struct zonefs_sb_info *sbi = ZONEFS_SB(sb); + enum zonefs_ztype ztype; + + if (!sbi) + return; + + for (ztype = 0; ztype < ZONEFS_ZTYPE_MAX; ztype++) { + if (sbi->s_zgroup[ztype].g_inode) { + iput(sbi->s_zgroup[ztype].g_inode); + sbi->s_zgroup[ztype].g_inode = NULL; + } + } +} + /* * Check that the device is zoned. If it is, get the list of zones and create * sub-directories and files according to the device zone configuration and @@ -1297,6 +1333,14 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent) if (!sb->s_root) goto cleanup; + /* + * Take a reference on the zone groups directory inodes + * to keep them in the inode cache. + */ + ret = zonefs_get_zgroup_inodes(sb); + if (ret) + goto cleanup; + ret = zonefs_sysfs_register(sb); if (ret) goto cleanup; @@ -1304,6 +1348,7 @@ static int zonefs_fill_super(struct super_block *sb, void *data, int silent) return 0; cleanup: + zonefs_release_zgroup_inodes(sb); zonefs_free_zgroups(sb); return ret; @@ -1319,6 +1364,9 @@ static void zonefs_kill_super(struct super_block *sb) { struct zonefs_sb_info *sbi = ZONEFS_SB(sb); + /* Release the reference on the zone group directory inodes */ + zonefs_release_zgroup_inodes(sb); + kill_block_super(sb); zonefs_sysfs_unregister(sb); diff --git a/fs/zonefs/zonefs.h b/fs/zonefs/zonefs.h index f88466a4158b..8175652241b5 100644 --- a/fs/zonefs/zonefs.h +++ b/fs/zonefs/zonefs.h @@ -76,6 +76,7 @@ struct zonefs_zone { * as files, one file per zone. */ struct zonefs_zone_group { + struct inode *g_inode; unsigned int g_nr_zones; struct zonefs_zone *g_zones; }; |