From mboxrd@z Thu Jan 1 00:00:00 1970 From: Abhi Das Date: Thu, 24 Sep 2020 22:46:24 -0500 Subject: [Cluster-devel] [PATCH v2 2/3] gfs2: lookup local statfs inodes at mount time In-Reply-To: <20200925034625.56517-1-adas@redhat.com> References: <20200925034625.56517-1-adas@redhat.com> Message-ID: <20200925034625.56517-3-adas@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit We require these inodes during journal recovery when we attempt to recover the statfs file. We are not able to lookup inodes at that time due to locks being blocked so we pre-lookup these inodes and save them in a linked list. Signed-off-by: Abhi Das --- fs/gfs2/incore.h | 7 +++++++ fs/gfs2/ops_fstype.c | 32 ++++++++++++++++++++++++-------- fs/gfs2/super.c | 28 +++++++++++++++++++++++++++- fs/gfs2/super.h | 3 +++ 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 9fc12206a3ad..313e35c14860 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -705,6 +705,12 @@ struct gfs2_pcpu_lkstats { struct gfs2_lkstats lkstats[10]; }; +struct lcl_statfs_inode { + struct list_head si_list; + struct inode *si_sc_inode; + unsigned int si_jid; +}; + struct gfs2_sbd { struct super_block *sd_vfs; struct gfs2_pcpu_lkstats __percpu *sd_lkstats; @@ -755,6 +761,7 @@ struct gfs2_sbd { struct inode *sd_jindex; struct inode *sd_statfs_inode; struct inode *sd_sc_inode; + struct list_head sd_sc_inodes_list; struct inode *sd_qc_inode; struct inode *sd_rindex; struct inode *sd_quota_inode; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 6d18d2c91add..042f3de79789 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -110,6 +110,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) spin_lock_init(&sdp->sd_trunc_lock); spin_lock_init(&sdp->sd_bitmap_lock); + INIT_LIST_HEAD(&sdp->sd_sc_inodes_list); + mapping = &sdp->sd_aspace; address_space_init_once(mapping); @@ -814,6 +816,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo) char buf[30]; int error = 0; struct gfs2_inode *ip; + struct gfs2_jdesc *jd; struct inode *master = d_inode(sdp->sd_master_dir); if (sdp->sd_args.ar_spectator) @@ -829,12 +832,26 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo) return error; } - sprintf(buf, "statfs_change%u", sdp->sd_jdesc->jd_jid); - sdp->sd_sc_inode = gfs2_lookup_simple(pn, buf); - if (IS_ERR(sdp->sd_sc_inode)) { - error = PTR_ERR(sdp->sd_sc_inode); - fs_err(sdp, "can't find local \"sc\" file: %d\n", error); - goto fail; + list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { + struct lcl_statfs_inode *lsi = + kmalloc(sizeof(struct lcl_statfs_inode), GFP_NOFS); + if (!lsi) { + error = -ENOMEM; + goto fail_ut_i; + } + sprintf(buf, "statfs_change%u", jd->jd_jid); + lsi->si_sc_inode = gfs2_lookup_simple(pn, buf); + if (IS_ERR(lsi->si_sc_inode)) { + error = PTR_ERR(lsi->si_sc_inode); + fs_err(sdp, "can't find local \"sc\" file #%u: %d\n", + jd->jd_jid, error); + goto fail_ut_i; + } + lsi->si_jid = jd->jd_jid; + if (jd->jd_jid == sdp->sd_jdesc->jd_jid) + sdp->sd_sc_inode = lsi->si_sc_inode; + + list_add_tail(&lsi->si_list, &sdp->sd_sc_inodes_list); } sprintf(buf, "quota_change%u", sdp->sd_jdesc->jd_jid); @@ -873,8 +890,7 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo) fail_qc_i: iput(sdp->sd_qc_inode); fail_ut_i: - iput(sdp->sd_sc_inode); -fail: + free_lcl_statfs_inodes(sdp); iput(pn); return error; } diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 20554db4ccab..ac5ad16e5c96 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -729,7 +729,7 @@ static void gfs2_put_super(struct super_block *sb) gfs2_glock_dq_uninit(&sdp->sd_jinode_gh); gfs2_glock_dq_uninit(&sdp->sd_sc_gh); gfs2_glock_dq_uninit(&sdp->sd_qc_gh); - iput(sdp->sd_sc_inode); + free_lcl_statfs_inodes(sdp); iput(sdp->sd_qc_inode); } @@ -1560,6 +1560,32 @@ static void gfs2_free_inode(struct inode *inode) kmem_cache_free(gfs2_inode_cachep, GFS2_I(inode)); } +extern void free_lcl_statfs_inodes(struct gfs2_sbd *sdp) +{ + struct lcl_statfs_inode *lsi, *safe; + + list_for_each_entry_safe(lsi, safe, &sdp->sd_sc_inodes_list, si_list) { + if (lsi->si_jid == sdp->sd_jdesc->jd_jid) + sdp->sd_sc_inode = NULL; + if (lsi->si_sc_inode) + iput(lsi->si_sc_inode); + list_del(&lsi->si_list); + kfree(lsi); + } +} + +extern struct inode *find_lcl_statfs_inode(struct gfs2_sbd *sdp, + unsigned int index) +{ + struct lcl_statfs_inode *lsi; + + list_for_each_entry(lsi, &sdp->sd_sc_inodes_list, si_list) { + if (lsi->si_jid == index) + return lsi->si_sc_inode; + } + return NULL; +} + const struct super_operations gfs2_super_ops = { .alloc_inode = gfs2_alloc_inode, .free_inode = gfs2_free_inode, diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index ed4f5cb29074..b3e6ce502108 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h @@ -44,6 +44,9 @@ extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, extern int gfs2_statfs_sync(struct super_block *sb, int type); extern void gfs2_freeze_func(struct work_struct *work); +extern void free_lcl_statfs_inodes(struct gfs2_sbd *sdp); +extern struct inode *find_lcl_statfs_inode(struct gfs2_sbd *sdp, + unsigned int index); extern void free_sbd(struct gfs2_sbd *sdp); extern struct file_system_type gfs2_fs_type; -- 2.20.1