From 2a27b755ed244527df845f07f4dd83988a90f2e4 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Thu, 16 May 2019 22:46:30 +0100 Subject: gfs2: Clean up freeing struct gfs2_sbd Add a free_sbd function for freeing a struct gfs2_sbd. Use that for freeing a super-block descriptor, either directly or via kobject_put. Free sd_lkstats inside the kobject release function: that way, gfs2_put_super will no longer leak sd_lkstats. Signed-off-by: Andreas Gruenbacher --- fs/gfs2/ops_fstype.c | 23 ++++++++++++++--------- fs/gfs2/super.h | 2 ++ fs/gfs2/sys.c | 3 +-- 3 files changed, 17 insertions(+), 11 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 08823bb3b2d0..8d614f599065 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -61,6 +61,13 @@ static void gfs2_tune_init(struct gfs2_tune *gt) gt->gt_complain_secs = 10; } +void free_sbd(struct gfs2_sbd *sdp) +{ + if (sdp->sd_lkstats) + free_percpu(sdp->sd_lkstats); + kfree(sdp); +} + static struct gfs2_sbd *init_sbd(struct super_block *sb) { struct gfs2_sbd *sdp; @@ -72,10 +79,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) sdp->sd_vfs = sb; sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats); - if (!sdp->sd_lkstats) { - kfree(sdp); - return NULL; - } + if (!sdp->sd_lkstats) + goto fail; sb->s_fs_info = sdp; set_bit(SDF_NOJOURNALID, &sdp->sd_flags); @@ -134,8 +139,11 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) mutex_init(&sdp->sd_freeze_mutex); return sdp; -} +fail: + free_sbd(sdp); + return NULL; +} /** * gfs2_check_sb - Check superblock @@ -1086,8 +1094,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent if (error) { /* In this case, we haven't initialized sysfs, so we have to manually free the sdp. */ - free_percpu(sdp->sd_lkstats); - kfree(sdp); + free_sbd(sdp); sb->s_fs_info = NULL; return error; } @@ -1190,7 +1197,6 @@ fail_lm: gfs2_lm_unmount(sdp); fail_debug: gfs2_delete_debugfs_file(sdp); - free_percpu(sdp->sd_lkstats); /* gfs2_sys_fs_del must be the last thing we do, since it causes * sysfs to call function gfs2_sbd_release, which frees sdp. */ gfs2_sys_fs_del(sdp); @@ -1370,7 +1376,6 @@ static void gfs2_kill_sb(struct super_block *sb) sdp->sd_root_dir = NULL; sdp->sd_master_dir = NULL; shrink_dcache_sb(sb); - free_percpu(sdp->sd_lkstats); kill_block_super(sb); } diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index c5f42f0c503b..9d49eaadb9d9 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h @@ -44,6 +44,8 @@ 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_sbd(struct gfs2_sbd *sdp); + extern struct file_system_type gfs2_fs_type; extern struct file_system_type gfs2meta_fs_type; extern const struct export_operations gfs2_export_ops; diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 159aedf63c2a..325612ce1c6b 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -301,7 +301,7 @@ static void gfs2_sbd_release(struct kobject *kobj) { struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); - kfree(sdp); + free_sbd(sdp); } static struct kobj_type gfs2_ktype = { @@ -679,7 +679,6 @@ fail_lock_module: fail_tune: sysfs_remove_group(&sdp->sd_kobj, &tune_group); fail_reg: - free_percpu(sdp->sd_lkstats); fs_err(sdp, "error %d adding sysfs files\n", error); kobject_put(&sdp->sd_kobj); sb->s_fs_info = NULL; -- cgit v1.2.3-55-g7522 From 15a798f7deb3931dd569f5734a04be47b97435cc Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Wed, 5 Jun 2019 22:24:24 +0800 Subject: gfs2: Use IS_ERR_OR_NULL Use IS_ERR_OR_NULL where appropriate. (Several more places converted by Andreas.) Signed-off-by: Kefeng Wang Signed-off-by: Andreas Gruenbacher --- fs/gfs2/dir.c | 4 ++-- fs/gfs2/glock.c | 2 +- fs/gfs2/inode.c | 2 +- fs/gfs2/ops_fstype.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 88e4f955c518..6f35d19eec25 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -750,7 +750,7 @@ static struct gfs2_dirent *gfs2_dirent_split_alloc(struct inode *inode, struct gfs2_dirent *dent; dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, gfs2_dirent_find_offset, name, ptr); - if (!dent || IS_ERR(dent)) + if (IS_ERR_OR_NULL(dent)) return dent; return do_init_dirent(inode, dent, name, bh, (unsigned)(ptr - (void *)dent)); @@ -854,7 +854,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode, return ERR_PTR(error); dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, scan, name, NULL); got_dent: - if (unlikely(dent == NULL || IS_ERR(dent))) { + if (IS_ERR_OR_NULL(dent)) { brelse(bh); bh = NULL; } diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f1ebcb42cbf5..44718098cc60 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -681,7 +681,7 @@ static void delete_work_func(struct work_struct *work) goto out; inode = gfs2_lookup_by_inum(sdp, no_addr, NULL, GFS2_BLKST_UNLINKED); - if (inode && !IS_ERR(inode)) { + if (!IS_ERR_OR_NULL(inode)) { d_prune_aliases(inode); iput(inode); } diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index b296c59832a7..2e2a8a2fb51d 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -793,7 +793,7 @@ fail_free_acls: fail_gunlock: gfs2_dir_no_add(&da); gfs2_glock_dq_uninit(ghs); - if (inode && !IS_ERR(inode)) { + if (!IS_ERR_OR_NULL(inode)) { clear_nlink(inode); if (!free_vfs_inode) mark_inode_dirty(inode); diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 8d614f599065..c199d1d813fc 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -576,7 +576,7 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) INIT_WORK(&jd->jd_work, gfs2_recover_func); jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1); - if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { + if (IS_ERR_OR_NULL(jd->jd_inode)) { if (!jd->jd_inode) error = -ENOENT; else -- cgit v1.2.3-55-g7522 From 5b3a9f348bc58f0e13cebcf3e583c7d2f2499d6a Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Fri, 26 Apr 2019 08:11:27 -0600 Subject: gfs2: kthread and remount improvements Before this patch, gfs2 saved the pointers to the two daemon threads (logd and quotad) in the superblock, but they were never cleared, even if the threads were stopped (e.g. on remount -o ro). That meant that certain error conditions (like a withdrawn file system) could race. For example, xfstests generic/361 caused an IO error during remount -o ro, which caused the kthreads to be stopped, then the error flagged. Later, when the test unmounted the file system, it would try to stop the threads a second time with kthread_stop. This patch does two things: First, every time it stops the threads it zeroes out the thread pointer, and also checks whether it's NULL before trying to stop it. Second, in function gfs2_remount_fs, it was returning if an error was logged by either of the two functions for gfs2_make_fs_ro and _rw, which caused it to bypass the online uevent at the bottom of the function. This removes that bypass in favor of just running the whole function, then returning the error. That way, unmounts and remounts won't hang forever. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/super.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index b70cea5c8c59..31147d89399d 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -394,6 +394,7 @@ static int init_threads(struct gfs2_sbd *sdp) fail: kthread_stop(sdp->sd_logd_process); + sdp->sd_logd_process = NULL; return error; } @@ -451,8 +452,12 @@ fail: freeze_gh.gh_flags |= GL_NOCACHE; gfs2_glock_dq_uninit(&freeze_gh); fail_threads: - kthread_stop(sdp->sd_quotad_process); - kthread_stop(sdp->sd_logd_process); + if (sdp->sd_quotad_process) + kthread_stop(sdp->sd_quotad_process); + sdp->sd_quotad_process = NULL; + if (sdp->sd_logd_process) + kthread_stop(sdp->sd_logd_process); + sdp->sd_logd_process = NULL; return error; } @@ -853,8 +858,12 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) return error; flush_workqueue(gfs2_delete_workqueue); - kthread_stop(sdp->sd_quotad_process); - kthread_stop(sdp->sd_logd_process); + if (sdp->sd_quotad_process) + kthread_stop(sdp->sd_quotad_process); + sdp->sd_quotad_process = NULL; + if (sdp->sd_logd_process) + kthread_stop(sdp->sd_logd_process); + sdp->sd_logd_process = NULL; gfs2_quota_sync(sdp->sd_vfs, 0); gfs2_statfs_sync(sdp->sd_vfs, 0); @@ -1273,8 +1282,6 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) error = gfs2_make_fs_ro(sdp); else error = gfs2_make_fs_rw(sdp); - if (error) - return error; } sdp->sd_args = args; @@ -1300,7 +1307,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) spin_unlock(>->gt_spin); gfs2_online_uevent(sdp); - return 0; + return error; } /** -- cgit v1.2.3-55-g7522 From e955537e3262de8e56f070b13817f525f472fa00 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Tue, 26 Mar 2019 13:51:48 -0600 Subject: gfs2: eliminate tr_num_revoke_rm For its journal processing, gfs2 kept track of the number of buffers added and removed on a per-transaction basis. These values are used to calculate space needed in the journal. But while these calculations make sense for the number of buffers, they make no sense for revokes. Revokes are managed in their own list, linked from the superblock. So it's entirely unnecessary to keep separate per-transaction counts for revokes added and removed. A single count will do the same job. Therefore, this patch combines the transaction revokes into a single count. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/incore.h | 1 - fs/gfs2/log.c | 3 +-- fs/gfs2/trans.c | 6 +++--- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index c9af93ac6c73..6b7cfc278ce2 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -504,7 +504,6 @@ struct gfs2_trans { unsigned int tr_num_buf_rm; unsigned int tr_num_databuf_rm; unsigned int tr_num_revoke; - unsigned int tr_num_revoke_rm; struct list_head tr_list; struct list_head tr_databuf; diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index c4c9700c366e..58e237fba565 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -882,7 +882,6 @@ static void gfs2_merge_trans(struct gfs2_trans *old, struct gfs2_trans *new) old->tr_num_buf_rm += new->tr_num_buf_rm; old->tr_num_databuf_rm += new->tr_num_databuf_rm; old->tr_num_revoke += new->tr_num_revoke; - old->tr_num_revoke_rm += new->tr_num_revoke_rm; list_splice_tail_init(&new->tr_databuf, &old->tr_databuf); list_splice_tail_init(&new->tr_buf, &old->tr_buf); @@ -904,7 +903,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) set_bit(TR_ATTACHED, &tr->tr_flags); } - sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; + sdp->sd_log_commited_revoke += tr->tr_num_revoke; reserved = calc_reserved(sdp); maxres = sdp->sd_log_blks_reserved + tr->tr_reserved; gfs2_assert_withdraw(sdp, maxres >= reserved); diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 6f67ef7aa412..35e3059255fe 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c @@ -77,10 +77,10 @@ static void gfs2_print_trans(struct gfs2_sbd *sdp, const struct gfs2_trans *tr) fs_warn(sdp, "blocks=%u revokes=%u reserved=%u touched=%u\n", tr->tr_blocks, tr->tr_revokes, tr->tr_reserved, test_bit(TR_TOUCHED, &tr->tr_flags)); - fs_warn(sdp, "Buf %u/%u Databuf %u/%u Revoke %u/%u\n", + fs_warn(sdp, "Buf %u/%u Databuf %u/%u Revoke %u\n", tr->tr_num_buf_new, tr->tr_num_buf_rm, tr->tr_num_databuf_new, tr->tr_num_databuf_rm, - tr->tr_num_revoke, tr->tr_num_revoke_rm); + tr->tr_num_revoke); } void gfs2_trans_end(struct gfs2_sbd *sdp) @@ -263,7 +263,7 @@ void gfs2_trans_remove_revoke(struct gfs2_sbd *sdp, u64 blkno, unsigned int len) gfs2_assert_withdraw(sdp, sdp->sd_log_num_revoke); sdp->sd_log_num_revoke--; kmem_cache_free(gfs2_bufdata_cachep, bd); - tr->tr_num_revoke_rm++; + tr->tr_num_revoke--; if (--n == 0) break; } -- cgit v1.2.3-55-g7522 From 49eb776ed9d92a91d3b1a24d83755e051bce96ff Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 27 Feb 2019 13:32:36 -0700 Subject: gfs2: log which portion of the journal is replayed When a journal is replayed, gfs2 logs a message similar to: jid=X: Replaying journal... This patch adds the tail and block number so that the range of the replayed block is also printed. These values will match the values shown if the journal is dumped with gfs2_edit -p journalX. The resulting output looks something like this: jid=1: Replaying journal...0x28b7 to 0x2beb This will allow us to better debug file system corruption problems. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/recovery.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 2299a3fa1911..c529f8749a89 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c @@ -388,7 +388,8 @@ void gfs2_recover_func(struct work_struct *work) } t_tlck = ktime_get(); - fs_info(sdp, "jid=%u: Replaying journal...\n", jd->jd_jid); + fs_info(sdp, "jid=%u: Replaying journal...0x%x to 0x%x\n", + jd->jd_jid, head.lh_tail, head.lh_blkno); for (pass = 0; pass < 2; pass++) { lops_before_scan(jd, &head, pass); -- cgit v1.2.3-55-g7522 From d14e1ca305fc27dbceabad64bf5158b35d8864c8 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 27 Feb 2019 13:26:59 -0700 Subject: gfs2: Warn when a journal replay overwrites a rgrp with buffers This patch adds some instrumentation in gfs2's journal replay that indicates when we're about to overwrite a rgrp for which we already have a valid buffer_head. When this problem occurs, it's a situation in which this node has been granted a rgrp glock and subsequently read in buffer_heads for it, and possibly even made changes to the rgrp bits and/or allocation values. But now another node has failed and forced us to replay its journal, but its journal contains a copy of the same rgrp, without a revoke, which means we're about to overwrite a rgrp that we now rightfully own, with an obsolete copy. That is always a problem. It means the other node (which failed and left its journal to be replayed) failed to flush out its rgrp buffers, write out the revoke, and invalidate its copy before it released the glock to our possession. No node should ever release a glock until its metadata has been written to the journal and revoked and invalidated.. We also kludge around the problem and refuse to replace our good copy with the journals bad copy by not marking the buffer dirty, but never do it silently. That's wallpapering over a larger problem that still exists. IOW, if this situation can happen to this node, it can also happen to a different node and we wouldn't even know it or be able to circumvent it: Suppose we have a 3-node cluster: Node 1 fails, leaving an obsolete rgrp block in its journal without a revoke. Node 2 grabs the rgrp as soon as the rgrp glock is released and starts making changes, allocating and freeing blocks from the rgrp, etc. Node 3 replays the journal from node 1, oblivious and unaware that it's about to overwrite node 2's changes. So we still need to be vocal and log the error to make it apparent that a corruption path still exists in gfs2. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/lops.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 1921cda034fd..8c3678f42746 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -759,9 +759,27 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start, if (gfs2_meta_check(sdp, bh_ip)) error = -EIO; - else + else { + struct gfs2_meta_header *mh = + (struct gfs2_meta_header *)bh_ip->b_data; + + if (mh->mh_type == cpu_to_be32(GFS2_METATYPE_RG)) { + struct gfs2_rgrpd *rgd; + + rgd = gfs2_blk2rgrpd(sdp, blkno, false); + if (rgd && rgd->rd_addr == blkno && + rgd->rd_bits && rgd->rd_bits->bi_bh) { + fs_info(sdp, "Replaying 0x%llx but we " + "already have a bh!\n", + (unsigned long long)blkno); + fs_info(sdp, "busy:%d, pinned:%d\n", + buffer_busy(rgd->rd_bits->bi_bh) ? 1 : 0, + buffer_pinned(rgd->rd_bits->bi_bh)); + gfs2_dump_glock(NULL, rgd->rd_gl); + } + } mark_buffer_dirty(bh_ip); - + } brelse(bh_log); brelse(bh_ip); -- cgit v1.2.3-55-g7522 From 04aea0ca14f025828c22d8ef586ff59d0be2f98b Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Tue, 7 May 2019 13:27:44 -0500 Subject: gfs2: Rename SDF_SHUTDOWN to SDF_WITHDRAWN Before this patch, the superblock flag indicating when a file system is withdrawn was called SDF_SHUTDOWN. This patch simply renames it to the more obvious SDF_WITHDRAWN. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/aops.c | 4 ++-- fs/gfs2/file.c | 2 +- fs/gfs2/glock.c | 6 +++--- fs/gfs2/glops.c | 2 +- fs/gfs2/incore.h | 2 +- fs/gfs2/meta_io.c | 6 +++--- fs/gfs2/ops_fstype.c | 2 +- fs/gfs2/quota.c | 2 +- fs/gfs2/super.c | 6 +++--- fs/gfs2/sys.c | 2 +- fs/gfs2/util.c | 4 ++-- 11 files changed, 19 insertions(+), 19 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index abeac61cfed3..1463b399285c 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -518,7 +518,7 @@ static int __gfs2_readpage(void *file, struct page *page) error = mpage_readpage(page, gfs2_block_map); } - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) return -EIO; return error; @@ -635,7 +635,7 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping, gfs2_glock_dq(&gh); out_uninit: gfs2_holder_uninit(&gh); - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) ret = -EIO; return ret; } diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index d174b1f8fd08..28bdbeb11030 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -1166,7 +1166,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) cmd = F_SETLK; fl->fl_type = F_UNLCK; } - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { + if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) { if (fl->fl_type == F_UNLCK) locks_lock_file_wait(file, fl); return -EIO; diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 44718098cc60..f114a4045fcc 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -544,7 +544,7 @@ __acquires(&gl->gl_lockref.lock) unsigned int lck_flags = (unsigned int)(gh ? gh->gh_flags : 0); int ret; - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) && + if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) && target != LM_ST_UNLOCKED) return; lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | @@ -581,7 +581,7 @@ __acquires(&gl->gl_lockref.lock) } else if (ret) { fs_err(sdp, "lm_lock ret %d\n", ret); - GLOCK_BUG_ON(gl, !test_bit(SDF_SHUTDOWN, + GLOCK_BUG_ON(gl, !test_bit(SDF_WITHDRAWN, &sdp->sd_flags)); } } else { /* lock_nolock */ @@ -1094,7 +1094,7 @@ int gfs2_glock_nq(struct gfs2_holder *gh) struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; int error = 0; - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) return -EIO; if (test_bit(GLF_LRU, &gl->gl_flags)) diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index cf4c767005b1..ade4b45a36ca 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -536,7 +536,7 @@ static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) gfs2_consist(sdp); /* Initialize some head of the log stuff */ - if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { + if (!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) { sdp->sd_log_sequence = head.lh_sequence + 1; gfs2_log_pointers_init(sdp, head.lh_blkno); } diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 6b7cfc278ce2..3ac57afa694a 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -608,7 +608,7 @@ struct gfs2_tune { enum { SDF_JOURNAL_CHECKED = 0, SDF_JOURNAL_LIVE = 1, - SDF_SHUTDOWN = 2, + SDF_WITHDRAWN = 2, SDF_NOBARRIERS = 3, SDF_NORECOVERY = 4, SDF_DEMOTE = 5, diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 456763e18def..662ef36c1874 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c @@ -251,7 +251,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, struct buffer_head *bh, *bhs[2]; int num = 0; - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { + if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) { *bhp = NULL; return -EIO; } @@ -309,7 +309,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh) { - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) return -EIO; wait_on_buffer(bh); @@ -320,7 +320,7 @@ int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh) gfs2_io_error_bh_wd(sdp, bh); return -EIO; } - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) return -EIO; return 0; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index c199d1d813fc..4a8e5a7310f0 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1004,7 +1004,7 @@ hostdata_error: void gfs2_lm_unmount(struct gfs2_sbd *sdp) { const struct lm_lockops *lm = sdp->sd_lockstruct.ls_ops; - if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) && + if (likely(!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) && lm->lm_unmount) lm->lm_unmount(sdp); } diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 8189b581236d..69c4b77f127b 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -1475,7 +1475,7 @@ static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error) { if (error == 0 || error == -EROFS) return; - if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { + if (!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) { fs_err(sdp, "gfs2_quotad: %s error %d\n", msg, error); sdp->sd_log_error = error; wake_up(&sdp->sd_logd_waitq); diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 31147d89399d..129ae4376af4 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -805,7 +805,7 @@ static void gfs2_dirty_inode(struct inode *inode, int flags) if (!(flags & I_DIRTY_INODE)) return; - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + if (unlikely(test_bit(SDF_WITHDRAWN, &sdp->sd_flags))) return; if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); @@ -854,7 +854,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, GL_NOCACHE, &freeze_gh); - if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + if (error && !test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) return error; flush_workqueue(gfs2_delete_workqueue); @@ -1013,7 +1013,7 @@ static int gfs2_freeze(struct super_block *sb) if (atomic_read(&sdp->sd_freeze_state) != SFS_UNFROZEN) goto out; - if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { + if (test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) { error = -EINVAL; goto out; } diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 325612ce1c6b..289328831e24 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c @@ -118,7 +118,7 @@ static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len) static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf) { - unsigned int b = test_bit(SDF_SHUTDOWN, &sdp->sd_flags); + unsigned int b = test_bit(SDF_WITHDRAWN, &sdp->sd_flags); return snprintf(buf, PAGE_SIZE, "%u\n", b); } diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index a7e55234211f..6aea0146e0c8 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c @@ -41,7 +41,7 @@ int gfs2_lm_withdraw(struct gfs2_sbd *sdp, const char *fmt, ...) struct va_format vaf; if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW && - test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + test_and_set_bit(SDF_WITHDRAWN, &sdp->sd_flags)) return 0; if (fmt) { @@ -256,7 +256,7 @@ void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh, const char *function, char *file, unsigned int line, bool withdraw) { - if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + if (!test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) fs_err(sdp, "fatal: I/O error\n" " block = %llu\n" -- cgit v1.2.3-55-g7522 From 55317f5b00f0dc0c807979292362ddc568b5bcc9 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Mon, 29 Apr 2019 09:36:23 -0600 Subject: gfs2: simplify gfs2_freeze by removing case Function gfs2_freeze had a case statement that simply checked the error code, but the break statements just made the logic hard to read. This patch simplifies the logic in favor of a simple if. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/super.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 129ae4376af4..3eae973d525f 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1023,20 +1023,14 @@ static int gfs2_freeze(struct super_block *sb) if (!error) break; - switch (error) { - case -EBUSY: + if (error == -EBUSY) fs_err(sdp, "waiting for recovery before freeze\n"); - break; - - default: + else fs_err(sdp, "error freezing FS: %d\n", error); - break; - } fs_err(sdp, "retrying...\n"); msleep(1000); } - error = 0; set_bit(SDF_FS_FROZEN, &sdp->sd_flags); out: mutex_unlock(&sdp->sd_freeze_mutex); -- cgit v1.2.3-55-g7522 From 3792ce973f07a2644fd81424b9acacb12530a3cf Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Thu, 9 May 2019 09:21:48 -0500 Subject: gfs2: dump fsid when dumping glock problems Before this patch, if a glock error was encountered, the glock with the problem was dumped. But sometimes you may have lots of file systems mounted, and that doesn't tell you which file system it was for. This patch adds a new boolean parameter fsid to the dump_glock family of functions. For non-error cases, such as dumping the glocks debugfs file, the fsid is not dumped in order to keep lock dumps and glocktop as clean as possible. For all error cases, such as GLOCK_BUG_ON, the file system id is now printed. This will make it easier to debug. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/glock.c | 34 +++++++++++++++++++++------------- fs/gfs2/glock.h | 11 +++++++---- fs/gfs2/glops.c | 7 +++++-- fs/gfs2/incore.h | 3 ++- fs/gfs2/lops.c | 2 +- fs/gfs2/rgrp.c | 21 ++++++++++++++------- fs/gfs2/rgrp.h | 3 ++- fs/gfs2/util.c | 4 +++- 8 files changed, 55 insertions(+), 30 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index f114a4045fcc..e23fb8b7b020 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1075,7 +1075,7 @@ trap_recursive: fs_err(sdp, "pid: %d\n", pid_nr(gh->gh_owner_pid)); fs_err(sdp, "lock type: %d req lock state : %d\n", gh->gh_gl->gl_name.ln_type, gh->gh_state); - gfs2_dump_glock(NULL, gl); + gfs2_dump_glock(NULL, gl, true); BUG(); } @@ -1610,16 +1610,16 @@ void gfs2_glock_thaw(struct gfs2_sbd *sdp) glock_hash_walk(thaw_glock, sdp); } -static void dump_glock(struct seq_file *seq, struct gfs2_glock *gl) +static void dump_glock(struct seq_file *seq, struct gfs2_glock *gl, bool fsid) { spin_lock(&gl->gl_lockref.lock); - gfs2_dump_glock(seq, gl); + gfs2_dump_glock(seq, gl, fsid); spin_unlock(&gl->gl_lockref.lock); } static void dump_glock_func(struct gfs2_glock *gl) { - dump_glock(NULL, gl); + dump_glock(NULL, gl, true); } /** @@ -1704,10 +1704,12 @@ static const char *hflags2str(char *buf, u16 flags, unsigned long iflags) * dump_holder - print information about a glock holder * @seq: the seq_file struct * @gh: the glock holder + * @fs_id_buf: pointer to file system id (if requested) * */ -static void dump_holder(struct seq_file *seq, const struct gfs2_holder *gh) +static void dump_holder(struct seq_file *seq, const struct gfs2_holder *gh, + const char *fs_id_buf) { struct task_struct *gh_owner = NULL; char flags_buf[32]; @@ -1715,8 +1717,8 @@ static void dump_holder(struct seq_file *seq, const struct gfs2_holder *gh) rcu_read_lock(); if (gh->gh_owner_pid) gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID); - gfs2_print_dbg(seq, " H: s:%s f:%s e:%d p:%ld [%s] %pS\n", - state2str(gh->gh_state), + gfs2_print_dbg(seq, "%s H: s:%s f:%s e:%d p:%ld [%s] %pS\n", + fs_id_buf, state2str(gh->gh_state), hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags), gh->gh_error, gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1, @@ -1766,6 +1768,7 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl) * gfs2_dump_glock - print information about a glock * @seq: The seq_file struct * @gl: the glock + * @fsid: If true, also dump the file system id * * The file format is as follows: * One line per object, capital letters are used to indicate objects @@ -1779,19 +1782,24 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl) * */ -void gfs2_dump_glock(struct seq_file *seq, struct gfs2_glock *gl) +void gfs2_dump_glock(struct seq_file *seq, struct gfs2_glock *gl, bool fsid) { const struct gfs2_glock_operations *glops = gl->gl_ops; unsigned long long dtime; const struct gfs2_holder *gh; char gflags_buf[32]; + char fs_id_buf[GFS2_FSNAME_LEN + 3 * sizeof(int) + 2]; + struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; + memset(fs_id_buf, 0, sizeof(fs_id_buf)); + if (fsid && sdp) /* safety precaution */ + sprintf(fs_id_buf, "fsid=%s: ", sdp->sd_fsname); dtime = jiffies - gl->gl_demote_time; dtime *= 1000000/HZ; /* demote time in uSec */ if (!test_bit(GLF_DEMOTE, &gl->gl_flags)) dtime = 0; - gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d v:%d r:%d m:%ld\n", - state2str(gl->gl_state), + gfs2_print_dbg(seq, "%sG: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d " + "v:%d r:%d m:%ld\n", fs_id_buf, state2str(gl->gl_state), gl->gl_name.ln_type, (unsigned long long)gl->gl_name.ln_number, gflags2str(gflags_buf, gl), @@ -1802,10 +1810,10 @@ void gfs2_dump_glock(struct seq_file *seq, struct gfs2_glock *gl) (int)gl->gl_lockref.count, gl->gl_hold_time); list_for_each_entry(gh, &gl->gl_holders, gh_list) - dump_holder(seq, gh); + dump_holder(seq, gh, fs_id_buf); if (gl->gl_state != LM_ST_UNLOCKED && glops->go_dump) - glops->go_dump(seq, gl); + glops->go_dump(seq, gl, fs_id_buf); } static int gfs2_glstats_seq_show(struct seq_file *seq, void *iter_ptr) @@ -2006,7 +2014,7 @@ static void gfs2_glock_seq_stop(struct seq_file *seq, void *iter_ptr) static int gfs2_glock_seq_show(struct seq_file *seq, void *iter_ptr) { - dump_glock(seq, iter_ptr); + dump_glock(seq, iter_ptr, false); return 0; } diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 149d7f6af085..e4e0bed5257c 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h @@ -199,8 +199,11 @@ extern int gfs2_glock_nq_num(struct gfs2_sbd *sdp, u64 number, struct gfs2_holder *gh); extern int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs); extern void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs); -extern void gfs2_dump_glock(struct seq_file *seq, struct gfs2_glock *gl); -#define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { gfs2_dump_glock(NULL, gl); BUG(); } } while(0) +extern void gfs2_dump_glock(struct seq_file *seq, struct gfs2_glock *gl, + bool fsid); +#define GLOCK_BUG_ON(gl,x) do { if (unlikely(x)) { \ + gfs2_dump_glock(NULL, gl, true); \ + BUG(); } } while(0) extern __printf(2, 3) void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...); @@ -266,7 +269,7 @@ static inline void glock_set_object(struct gfs2_glock *gl, void *object) { spin_lock(&gl->gl_lockref.lock); if (gfs2_assert_warn(gl->gl_name.ln_sbd, gl->gl_object == NULL)) - gfs2_dump_glock(NULL, gl); + gfs2_dump_glock(NULL, gl, true); gl->gl_object = object; spin_unlock(&gl->gl_lockref.lock); } @@ -278,7 +281,7 @@ static inline void glock_set_object(struct gfs2_glock *gl, void *object) * * I'd love to similarly add this: * else if (gfs2_assert_warn(gl->gl_sbd, gl->gl_object == object)) - * gfs2_dump_glock(NULL, gl); + * gfs2_dump_glock(NULL, gl, true); * Unfortunately, that's not possible because as soon as gfs2_delete_inode * frees the block in the rgrp, another process can reassign it for an I_NEW * inode in gfs2_create_inode because that calls new_inode, not gfs2_iget. diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index ade4b45a36ca..68e2a2d4e6a6 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -461,10 +461,12 @@ static int inode_go_lock(struct gfs2_holder *gh) * inode_go_dump - print information about an inode * @seq: The iterator * @ip: the inode + * @fs_id_buf: file system id (may be empty) * */ -static void inode_go_dump(struct seq_file *seq, struct gfs2_glock *gl) +static void inode_go_dump(struct seq_file *seq, struct gfs2_glock *gl, + const char *fs_id_buf) { struct gfs2_inode *ip = gl->gl_object; struct inode *inode = &ip->i_inode; @@ -477,7 +479,8 @@ static void inode_go_dump(struct seq_file *seq, struct gfs2_glock *gl) nrpages = inode->i_data.nrpages; xa_unlock_irq(&inode->i_data.i_pages); - gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu p:%lu\n", + gfs2_print_dbg(seq, "%s I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu " + "p:%lu\n", fs_id_buf, (unsigned long long)ip->i_no_formal_ino, (unsigned long long)ip->i_no_addr, IF2DT(ip->i_inode.i_mode), ip->i_flags, diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 3ac57afa694a..7a993d7c022e 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -240,7 +240,8 @@ struct gfs2_glock_operations { int (*go_demote_ok) (const struct gfs2_glock *gl); int (*go_lock) (struct gfs2_holder *gh); void (*go_unlock) (struct gfs2_holder *gh); - void (*go_dump)(struct seq_file *seq, struct gfs2_glock *gl); + void (*go_dump)(struct seq_file *seq, struct gfs2_glock *gl, + const char *fs_id_buf); void (*go_callback)(struct gfs2_glock *gl, bool remote); const int go_type; const unsigned long go_flags; diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 8c3678f42746..5b17979af539 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -775,7 +775,7 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start, fs_info(sdp, "busy:%d, pinned:%d\n", buffer_busy(rgd->rd_bits->bi_bh) ? 1 : 0, buffer_pinned(rgd->rd_bits->bi_bh)); - gfs2_dump_glock(NULL, rgd->rd_gl); + gfs2_dump_glock(NULL, rgd->rd_gl, true); } } mark_buffer_dirty(bh_ip); diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 36f20a89d0c2..a60b36fdbdd6 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -610,11 +610,12 @@ int gfs2_rsqa_alloc(struct gfs2_inode *ip) return gfs2_qa_alloc(ip); } -static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) +static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs, + const char *fs_id_buf) { struct gfs2_inode *ip = container_of(rs, struct gfs2_inode, i_res); - gfs2_print_dbg(seq, " B: n:%llu s:%llu b:%u f:%u\n", + gfs2_print_dbg(seq, "%s B: n:%llu s:%llu b:%u f:%u\n", fs_id_buf, (unsigned long long)ip->i_no_addr, (unsigned long long)gfs2_rbm_to_block(&rs->rs_rbm), rs->rs_rbm.offset, rs->rs_free); @@ -2246,10 +2247,12 @@ static void rgblk_free(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd, * gfs2_rgrp_dump - print out an rgrp * @seq: The iterator * @gl: The glock in question + * @fs_id_buf: pointer to file system id (if requested) * */ -void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_glock *gl) +void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_glock *gl, + const char *fs_id_buf) { struct gfs2_rgrpd *rgd = gl->gl_object; struct gfs2_blkreserv *trs; @@ -2257,14 +2260,15 @@ void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_glock *gl) if (rgd == NULL) return; - gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u r:%u e:%u\n", + gfs2_print_dbg(seq, "%s R: n:%llu f:%02x b:%u/%u i:%u r:%u e:%u\n", + fs_id_buf, (unsigned long long)rgd->rd_addr, rgd->rd_flags, rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes, rgd->rd_reserved, rgd->rd_extfail_pt); if (rgd->rd_sbd->sd_args.ar_rgrplvb) { struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; - gfs2_print_dbg(seq, " L: f:%02x b:%u i:%u\n", + gfs2_print_dbg(seq, "%s L: f:%02x b:%u i:%u\n", fs_id_buf, be32_to_cpu(rgl->rl_flags), be32_to_cpu(rgl->rl_free), be32_to_cpu(rgl->rl_dinodes)); @@ -2272,7 +2276,7 @@ void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_glock *gl) spin_lock(&rgd->rd_rsspin); for (n = rb_first(&rgd->rd_rstree); n; n = rb_next(&trs->rs_node)) { trs = rb_entry(n, struct gfs2_blkreserv, rs_node); - dump_rs(seq, trs); + dump_rs(seq, trs, fs_id_buf); } spin_unlock(&rgd->rd_rsspin); } @@ -2280,10 +2284,13 @@ void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_glock *gl) static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd) { struct gfs2_sbd *sdp = rgd->rd_sbd; + char fs_id_buf[GFS2_FSNAME_LEN + 3 * sizeof(int) + 2]; + fs_warn(sdp, "rgrp %llu has an error, marking it readonly until umount\n", (unsigned long long)rgd->rd_addr); fs_warn(sdp, "umount on all nodes and run fsck.gfs2 to fix the error\n"); - gfs2_rgrp_dump(NULL, rgd->rd_gl); + sprintf(fs_id_buf, "fsid=%s: ", sdp->sd_fsname); + gfs2_rgrp_dump(NULL, rgd->rd_gl, fs_id_buf); rgd->rd_flags |= GFS2_RDF_ERROR; } diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index 6a3adf0ee0b7..c14a673ae36f 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h @@ -69,7 +69,8 @@ extern void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist, extern void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist); extern void gfs2_rlist_free(struct gfs2_rgrp_list *rlist); extern u64 gfs2_ri_total(struct gfs2_sbd *sdp); -extern void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_glock *gl); +extern void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_glock *gl, + const char *fs_id_buf); extern int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, struct buffer_head *bh, const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed); diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 6aea0146e0c8..83f6c582773a 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c @@ -178,9 +178,11 @@ int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide, const char *function, char *file, unsigned int line) { struct gfs2_sbd *sdp = rgd->rd_sbd; + char fs_id_buf[GFS2_FSNAME_LEN + 3 * sizeof(int) + 2]; int rv; - gfs2_rgrp_dump(NULL, rgd->rd_gl); + sprintf(fs_id_buf, "fsid=%s: ", sdp->sd_fsname); + gfs2_rgrp_dump(NULL, rgd->rd_gl, fs_id_buf); rv = gfs2_lm_withdraw(sdp, "fatal: filesystem consistency error\n" " RG = %llu\n" -- cgit v1.2.3-55-g7522 From f29e62eed261f01431d348d8b22a6f275d553a51 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Mon, 13 May 2019 09:42:18 -0500 Subject: gfs2: replace more printk with calls to fs_info and friends This patch replaces a few leftover printk errors with calls to fs_info and similar, so that the file system having the error is properly logged. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/bmap.c | 5 ++--- fs/gfs2/glops.c | 3 ++- fs/gfs2/rgrp.c | 27 ++++++++++++++------------- fs/gfs2/super.c | 6 +++--- 4 files changed, 21 insertions(+), 20 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 93ea1d529aa3..3b761a0ba6ab 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1862,9 +1862,8 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length) gfs2_assert_withdraw(sdp, bh); if (gfs2_assert_withdraw(sdp, prev_bnr != bh->b_blocknr)) { - printk(KERN_EMERG "GFS2: fsid=%s:inode %llu, " - "block:%llu, i_h:%u, s_h:%u, mp_h:%u\n", - sdp->sd_fsname, + fs_emerg(sdp, "inode %llu, block:%llu, i_h:%u," + "s_h:%u, mp_h:%u\n", (unsigned long long)ip->i_no_addr, prev_bnr, ip->i_height, strip_h, mp_h); } diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 68e2a2d4e6a6..ff213690e364 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -506,7 +506,8 @@ static void freeze_go_sync(struct gfs2_glock *gl) atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE); error = freeze_super(sdp->sd_vfs); if (error) { - printk(KERN_INFO "GFS2: couldn't freeze filesystem: %d\n", error); + fs_info(sdp, "GFS2: couldn't freeze filesystem: %d\n", + error); gfs2_assert_withdraw(sdp, 0); } queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work); diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index a60b36fdbdd6..49ac0a5e74ea 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1112,32 +1112,33 @@ static int gfs2_rgrp_lvb_valid(struct gfs2_rgrpd *rgd) { struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl; struct gfs2_rgrp *str = (struct gfs2_rgrp *)rgd->rd_bits[0].bi_bh->b_data; + struct gfs2_sbd *sdp = rgd->rd_sbd; int valid = 1; if (rgl->rl_flags != str->rg_flags) { - printk(KERN_WARNING "GFS2: rgd: %llu lvb flag mismatch %u/%u", - (unsigned long long)rgd->rd_addr, + fs_warn(sdp, "GFS2: rgd: %llu lvb flag mismatch %u/%u", + (unsigned long long)rgd->rd_addr, be32_to_cpu(rgl->rl_flags), be32_to_cpu(str->rg_flags)); valid = 0; } if (rgl->rl_free != str->rg_free) { - printk(KERN_WARNING "GFS2: rgd: %llu lvb free mismatch %u/%u", - (unsigned long long)rgd->rd_addr, - be32_to_cpu(rgl->rl_free), be32_to_cpu(str->rg_free)); + fs_warn(sdp, "GFS2: rgd: %llu lvb free mismatch %u/%u", + (unsigned long long)rgd->rd_addr, + be32_to_cpu(rgl->rl_free), be32_to_cpu(str->rg_free)); valid = 0; } if (rgl->rl_dinodes != str->rg_dinodes) { - printk(KERN_WARNING "GFS2: rgd: %llu lvb dinode mismatch %u/%u", - (unsigned long long)rgd->rd_addr, - be32_to_cpu(rgl->rl_dinodes), - be32_to_cpu(str->rg_dinodes)); + fs_warn(sdp, "GFS2: rgd: %llu lvb dinode mismatch %u/%u", + (unsigned long long)rgd->rd_addr, + be32_to_cpu(rgl->rl_dinodes), + be32_to_cpu(str->rg_dinodes)); valid = 0; } if (rgl->rl_igeneration != str->rg_igeneration) { - printk(KERN_WARNING "GFS2: rgd: %llu lvb igen mismatch " - "%llu/%llu", (unsigned long long)rgd->rd_addr, - (unsigned long long)be64_to_cpu(rgl->rl_igeneration), - (unsigned long long)be64_to_cpu(str->rg_igeneration)); + fs_warn(sdp, "GFS2: rgd: %llu lvb igen mismatch %llu/%llu", + (unsigned long long)rgd->rd_addr, + (unsigned long long)be64_to_cpu(rgl->rl_igeneration), + (unsigned long long)be64_to_cpu(str->rg_igeneration)); valid = 0; } return valid; diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 3eae973d525f..0acc5834f653 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -978,14 +978,14 @@ void gfs2_freeze_func(struct work_struct *work) error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, 0, &freeze_gh); if (error) { - printk(KERN_INFO "GFS2: couldn't get freeze lock : %d\n", error); + fs_info(sdp, "GFS2: couldn't get freeze lock : %d\n", error); gfs2_assert_withdraw(sdp, 0); } else { atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN); error = thaw_super(sb); if (error) { - printk(KERN_INFO "GFS2: couldn't thaw filesystem: %d\n", - error); + fs_info(sdp, "GFS2: couldn't thaw filesystem: %d\n", + error); gfs2_assert_withdraw(sdp, 0); } if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) -- cgit v1.2.3-55-g7522 From f3915f83e84c1f14358aaa91e8785d6169092176 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 1 Jul 2019 23:54:31 +0200 Subject: gfs2: use page_offset in gfs2_page_mkwrite Without casting page->index to a guaranteed 64-bit type, the value might be treated as 32-bit on 32-bit platforms and thus get truncated. Signed-off-by: Christoph Hellwig Signed-off-by: Andreas Gruenbacher --- fs/gfs2/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 28bdbeb11030..5d61113b3f50 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -408,7 +408,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf) struct gfs2_sbd *sdp = GFS2_SB(inode); struct gfs2_alloc_parms ap = { .aflags = 0, }; unsigned long last_index; - u64 pos = page->index << PAGE_SHIFT; + u64 pos = page_offset(page); unsigned int data_blocks, ind_blocks, rblocks; struct gfs2_holder gh; loff_t size; -- cgit v1.2.3-55-g7522 From e0ec0a6ba6574594f444383efbc09e621d1d8dee Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 1 Jul 2019 23:54:32 +0200 Subject: gfs2: remove the unused gfs2_stuffed_write_end function This function was overlooked when the write_begin and write_end address space operations were removed as part of gfs2's iomap conversion. Signed-off-by: Christoph Hellwig Signed-off-by: Andreas Gruenbacher --- fs/gfs2/aops.c | 41 ----------------------------------------- fs/gfs2/aops.h | 3 --- 2 files changed, 44 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 1463b399285c..d82b919ce70f 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -685,47 +685,6 @@ out: gfs2_trans_end(sdp); } -/** - * gfs2_stuffed_write_end - Write end for stuffed files - * @inode: The inode - * @dibh: The buffer_head containing the on-disk inode - * @pos: The file position - * @copied: How much was actually copied by the VFS - * @page: The page - * - * This copies the data from the page into the inode block after - * the inode data structure itself. - * - * Returns: copied bytes or errno - */ -int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh, - loff_t pos, unsigned copied, - struct page *page) -{ - struct gfs2_inode *ip = GFS2_I(inode); - u64 to = pos + copied; - void *kaddr; - unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode); - - BUG_ON(pos + copied > gfs2_max_stuffed_size(ip)); - - kaddr = kmap_atomic(page); - memcpy(buf + pos, kaddr + pos, copied); - flush_dcache_page(page); - kunmap_atomic(kaddr); - - WARN_ON(!PageUptodate(page)); - unlock_page(page); - put_page(page); - - if (copied) { - if (inode->i_size < to) - i_size_write(inode, to); - mark_inode_dirty(inode); - } - return copied; -} - /** * jdata_set_page_dirty - Page dirtying function * @page: The page to dirty diff --git a/fs/gfs2/aops.h b/fs/gfs2/aops.h index fa8e5d0144dd..3a6d8a90d99e 100644 --- a/fs/gfs2/aops.h +++ b/fs/gfs2/aops.h @@ -9,9 +9,6 @@ #include "incore.h" extern int stuffed_readpage(struct gfs2_inode *ip, struct page *page); -extern int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh, - loff_t pos, unsigned copied, - struct page *page); extern void adjust_fs_space(struct inode *inode); extern void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, unsigned int from, unsigned int len); -- cgit v1.2.3-55-g7522 From eadd753580469f281912e28114a80e5822622cbe Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 1 Jul 2019 23:54:33 +0200 Subject: gfs2: merge gfs2_writeback_aops and gfs2_ordered_aops The only difference between the two is that gfs2_ordered_aops sets the set_page_dirty method to __set_page_dirty_buffers, but given that __set_page_dirty_buffers is the default, if no method is set, there is no need to to do that. Merge the two sets of operations into one. Signed-off-by: Christoph Hellwig Signed-off-by: Andreas Gruenbacher --- fs/gfs2/aops.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index d82b919ce70f..210e4a8d4e7b 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -847,7 +847,7 @@ cannot_release: return 0; } -static const struct address_space_operations gfs2_writeback_aops = { +static const struct address_space_operations gfs2_aops = { .writepage = gfs2_writepage, .writepages = gfs2_writepages, .readpage = gfs2_readpage, @@ -861,21 +861,6 @@ static const struct address_space_operations gfs2_writeback_aops = { .error_remove_page = generic_error_remove_page, }; -static const struct address_space_operations gfs2_ordered_aops = { - .writepage = gfs2_writepage, - .writepages = gfs2_writepages, - .readpage = gfs2_readpage, - .readpages = gfs2_readpages, - .set_page_dirty = __set_page_dirty_buffers, - .bmap = gfs2_bmap, - .invalidatepage = gfs2_invalidatepage, - .releasepage = gfs2_releasepage, - .direct_IO = noop_direct_IO, - .migratepage = buffer_migrate_page, - .is_partially_uptodate = block_is_partially_uptodate, - .error_remove_page = generic_error_remove_page, -}; - static const struct address_space_operations gfs2_jdata_aops = { .writepage = gfs2_jdata_writepage, .writepages = gfs2_jdata_writepages, @@ -891,15 +876,8 @@ static const struct address_space_operations gfs2_jdata_aops = { void gfs2_set_aops(struct inode *inode) { - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_sbd *sdp = GFS2_SB(inode); - - if (gfs2_is_jdata(ip)) + if (gfs2_is_jdata(GFS2_I(inode))) inode->i_mapping->a_ops = &gfs2_jdata_aops; - else if (gfs2_is_writeback(sdp)) - inode->i_mapping->a_ops = &gfs2_writeback_aops; - else if (gfs2_is_ordered(sdp)) - inode->i_mapping->a_ops = &gfs2_ordered_aops; else - BUG(); + inode->i_mapping->a_ops = &gfs2_aops; } -- cgit v1.2.3-55-g7522 From 59c01c5046cc0cf567d58cc7b59a704a36a06899 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 1 Jul 2019 23:54:34 +0200 Subject: gfs2: merge gfs2_writepage_common into gfs2_writepage There is no need to keep these two functions separate. Signed-off-by: Christoph Hellwig Signed-off-by: Andreas Gruenbacher --- fs/gfs2/aops.c | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 210e4a8d4e7b..4edf917752af 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -82,15 +82,11 @@ static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock, } /** - * gfs2_writepage_common - Common bits of writepage - * @page: The page to be written + * gfs2_writepage - Write page for writeback mappings + * @page: The page * @wbc: The writeback control - * - * Returns: 1 if writepage is ok, otherwise an error code or zero if no error. */ - -static int gfs2_writepage_common(struct page *page, - struct writeback_control *wbc) +static int gfs2_writepage(struct page *page, struct writeback_control *wbc) { struct inode *inode = page->mapping->host; struct gfs2_inode *ip = GFS2_I(inode); @@ -109,7 +105,9 @@ static int gfs2_writepage_common(struct page *page, page->mapping->a_ops->invalidatepage(page, 0, PAGE_SIZE); goto out; } - return 1; + + return nobh_writepage(page, gfs2_get_block_noalloc, wbc); + redirty: redirty_page_for_writepage(wbc, page); out: @@ -117,24 +115,6 @@ out: return 0; } -/** - * gfs2_writepage - Write page for writeback mappings - * @page: The page - * @wbc: The writeback control - * - */ - -static int gfs2_writepage(struct page *page, struct writeback_control *wbc) -{ - int ret; - - ret = gfs2_writepage_common(page, wbc); - if (ret <= 0) - return ret; - - return nobh_writepage(page, gfs2_get_block_noalloc, wbc); -} - /* This is the same as calling block_write_full_page, but it also * writes pages outside of i_size */ -- cgit v1.2.3-55-g7522 From 378b6cbfb82f2a8bb47ae3b1dac0419b57d84a36 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 1 Jul 2019 23:54:35 +0200 Subject: gfs2: mark stuffed_readpage static Signed-off-by: Christoph Hellwig Signed-off-by: Andreas Gruenbacher --- fs/gfs2/aops.c | 3 +-- fs/gfs2/aops.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 4edf917752af..8f90d98a0aee 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -434,8 +434,7 @@ static int gfs2_jdata_writepages(struct address_space *mapping, * * Returns: errno */ - -int stuffed_readpage(struct gfs2_inode *ip, struct page *page) +static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) { struct buffer_head *dibh; u64 dsize = i_size_read(&ip->i_inode); diff --git a/fs/gfs2/aops.h b/fs/gfs2/aops.h index 3a6d8a90d99e..ff9877a68780 100644 --- a/fs/gfs2/aops.h +++ b/fs/gfs2/aops.h @@ -8,7 +8,6 @@ #include "incore.h" -extern int stuffed_readpage(struct gfs2_inode *ip, struct page *page); extern void adjust_fs_space(struct inode *inode); extern void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, unsigned int from, unsigned int len); -- cgit v1.2.3-55-g7522 From 7770c93a46e6d2dc6e7c2172d83f2f5aca947cf7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 1 Jul 2019 23:54:36 +0200 Subject: gfs2: use iomap_bmap instead of generic_block_bmap No need to indirect through get_blocks and buffer_heads when we can just use the iomap version. Signed-off-by: Christoph Hellwig Signed-off-by: Andreas Gruenbacher --- fs/gfs2/aops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 8f90d98a0aee..f42048cc5454 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -697,7 +697,7 @@ static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock) return 0; if (!gfs2_is_stuffed(ip)) - dblock = generic_block_bmap(mapping, lblock, gfs2_block_map); + dblock = iomap_bmap(mapping, lblock, &gfs2_iomap_ops); gfs2_glock_dq_uninit(&i_gh); -- cgit v1.2.3-55-g7522 From 35af80aef99b34993783c34029d2196717e693c8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 1 Jul 2019 23:54:38 +0200 Subject: gfs2: don't use buffer_heads in gfs2_allocate_page_backing Rewrite gfs2_allocate_page_backing to call gfs2_iomap_get_alloc and operate on struct iomap directly. Signed-off-by: Christoph Hellwig Signed-off-by: Andreas Gruenbacher --- fs/gfs2/file.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 5d61113b3f50..8b0c2bfa90c1 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -363,31 +363,30 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) } /** - * gfs2_allocate_page_backing - Use bmap to allocate blocks + * gfs2_allocate_page_backing - Allocate blocks for a write fault * @page: The (locked) page to allocate backing for * - * We try to allocate all the blocks required for the page in - * one go. This might fail for various reasons, so we keep - * trying until all the blocks to back this page are allocated. - * If some of the blocks are already allocated, thats ok too. + * We try to allocate all the blocks required for the page in one go. This + * might fail for various reasons, so we keep trying until all the blocks to + * back this page are allocated. If some of the blocks are already allocated, + * that is ok too. */ - static int gfs2_allocate_page_backing(struct page *page) { - struct inode *inode = page->mapping->host; - struct buffer_head bh; - unsigned long size = PAGE_SIZE; - u64 lblock = page->index << (PAGE_SHIFT - inode->i_blkbits); + u64 pos = page_offset(page); + u64 size = PAGE_SIZE; do { - bh.b_state = 0; - bh.b_size = size; - gfs2_block_map(inode, lblock, &bh, 1); - if (!buffer_mapped(&bh)) + struct iomap iomap = { }; + + if (gfs2_iomap_get_alloc(page->mapping->host, pos, 1, &iomap)) return -EIO; - size -= bh.b_size; - lblock += (bh.b_size >> inode->i_blkbits); - } while(size > 0); + + iomap.length = min(iomap.length, size); + size -= iomap.length; + pos += iomap.length; + } while (size > 0); + return 0; } -- cgit v1.2.3-55-g7522 From bb4cb25dd319fa5630cc304c5bfa926266736935 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Wed, 3 Jul 2019 22:12:13 +0200 Subject: gfs2: Remove unused gfs2_iomap_alloc argument Remove the unused flags argument of gfs2_iomap_alloc. Signed-off-by: Andreas Gruenbacher --- fs/gfs2/bmap.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'fs/gfs2') diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 3b761a0ba6ab..bd0b0cd38dbe 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -595,7 +595,6 @@ enum alloc_state { * gfs2_iomap_alloc - Build a metadata tree of the requested height * @inode: The GFS2 inode * @iomap: The iomap structure - * @flags: iomap flags * @mp: The metapath, with proper height information calculated * * In this routine we may have to alloc: @@ -622,7 +621,7 @@ enum alloc_state { */ static int gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap, - unsigned flags, struct metapath *mp) + struct metapath *mp) { struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); @@ -1088,7 +1087,7 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, } if (iomap->type == IOMAP_HOLE) { - ret = gfs2_iomap_alloc(inode, iomap, flags, mp); + ret = gfs2_iomap_alloc(inode, iomap, mp); if (ret) { gfs2_trans_end(sdp); gfs2_inplace_release(ip); @@ -1232,7 +1231,7 @@ int gfs2_block_map(struct inode *inode, sector_t lblock, if (create) { ret = gfs2_iomap_get(inode, pos, length, IOMAP_WRITE, &iomap, &mp); if (!ret && iomap.type == IOMAP_HOLE) - ret = gfs2_iomap_alloc(inode, &iomap, IOMAP_WRITE, &mp); + ret = gfs2_iomap_alloc(inode, &iomap, &mp); release_metapath(&mp); } else { ret = gfs2_iomap_get(inode, pos, length, 0, &iomap, &mp); @@ -1462,7 +1461,7 @@ int gfs2_iomap_get_alloc(struct inode *inode, loff_t pos, loff_t length, ret = gfs2_iomap_get(inode, pos, length, IOMAP_WRITE, iomap, &mp); if (!ret && iomap->type == IOMAP_HOLE) - ret = gfs2_iomap_alloc(inode, iomap, IOMAP_WRITE, &mp); + ret = gfs2_iomap_alloc(inode, iomap, &mp); release_metapath(&mp); return ret; } -- cgit v1.2.3-55-g7522