summaryrefslogtreecommitdiff
path: root/fs/gfs2/log.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-15 22:40:03 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-15 22:40:03 -0700
commit2b2f2aedba985108cbc92a761ac0d9fc4c774616 (patch)
tree183ebc740d0e3217f4522e9669a2742833b29e7d /fs/gfs2/log.c
parent72f02ba66bd83b54054da20eae550123de84da6f (diff)
parentf5580d0f8bf60993a5fbc73ee04678070ffbba57 (diff)
Merge tag 'gfs2-4.19.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Andreas Gruenbacher: - iomap support for buffered writes and for direct I/O - two patches that reduce the size of struct gfs2_inode - lots of fixes and cleanups * tag 'gfs2-4.19.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: (25 commits) gfs2: eliminate update_rgrp_lvb_unlinked gfs2: Fix gfs2_testbit to use clone bitmaps gfs2: Get rid of gfs2_ea_strlen gfs2: cleanup: call gfs2_rgrp_ondisk2lvb from gfs2_rgrp_out gfs2: Special-case rindex for gfs2_grow GFS2: rgrp free blocks used incorrectly gfs2: remove redundant variable 'moved' gfs2: use iomap_readpage for blocksize == PAGE_SIZE gfs2: Use iomap for stuffed direct I/O reads gfs2: fallocate_chunk: Always initialize struct iomap GFS2: Fix recovery issues for spectators fs: gfs2: Adding new return type vm_fault_t gfs2: using posix_acl_xattr_size instead of posix_acl_to_xattr gfs2: Don't reject a supposedly full bitmap if we have blocks reserved gfs2: Eliminate redundant ip->i_rgd gfs2: Stop messing with ip->i_rgd in the rlist code gfs2: Remove gfs2_write_{begin,end} gfs2: iomap direct I/O support gfs2: gfs2_extent_length cleanup gfs2: iomap buffered write support ...
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r--fs/gfs2/log.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 0248835625f1..ee20ea42e7b5 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -92,7 +92,8 @@ static void gfs2_remove_from_ail(struct gfs2_bufdata *bd)
static int gfs2_ail1_start_one(struct gfs2_sbd *sdp,
struct writeback_control *wbc,
- struct gfs2_trans *tr)
+ struct gfs2_trans *tr,
+ bool *withdraw)
__releases(&sdp->sd_ail_lock)
__acquires(&sdp->sd_ail_lock)
{
@@ -107,8 +108,10 @@ __acquires(&sdp->sd_ail_lock)
gfs2_assert(sdp, bd->bd_tr == tr);
if (!buffer_busy(bh)) {
- if (!buffer_uptodate(bh))
+ if (!buffer_uptodate(bh)) {
gfs2_io_error_bh(sdp, bh);
+ *withdraw = true;
+ }
list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list);
continue;
}
@@ -148,6 +151,7 @@ void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc)
struct list_head *head = &sdp->sd_ail1_list;
struct gfs2_trans *tr;
struct blk_plug plug;
+ bool withdraw = false;
trace_gfs2_ail_flush(sdp, wbc, 1);
blk_start_plug(&plug);
@@ -156,11 +160,13 @@ restart:
list_for_each_entry_reverse(tr, head, tr_list) {
if (wbc->nr_to_write <= 0)
break;
- if (gfs2_ail1_start_one(sdp, wbc, tr))
+ if (gfs2_ail1_start_one(sdp, wbc, tr, &withdraw))
goto restart;
}
spin_unlock(&sdp->sd_ail_lock);
blk_finish_plug(&plug);
+ if (withdraw)
+ gfs2_lm_withdraw(sdp, NULL);
trace_gfs2_ail_flush(sdp, wbc, 0);
}
@@ -188,7 +194,8 @@ static void gfs2_ail1_start(struct gfs2_sbd *sdp)
*
*/
-static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
+static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr,
+ bool *withdraw)
{
struct gfs2_bufdata *bd, *s;
struct buffer_head *bh;
@@ -199,11 +206,12 @@ static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
gfs2_assert(sdp, bd->bd_tr == tr);
if (buffer_busy(bh))
continue;
- if (!buffer_uptodate(bh))
+ if (!buffer_uptodate(bh)) {
gfs2_io_error_bh(sdp, bh);
+ *withdraw = true;
+ }
list_move(&bd->bd_ail_st_list, &tr->tr_ail2_list);
}
-
}
/**
@@ -218,10 +226,11 @@ static int gfs2_ail1_empty(struct gfs2_sbd *sdp)
struct gfs2_trans *tr, *s;
int oldest_tr = 1;
int ret;
+ bool withdraw = false;
spin_lock(&sdp->sd_ail_lock);
list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) {
- gfs2_ail1_empty_one(sdp, tr);
+ gfs2_ail1_empty_one(sdp, tr, &withdraw);
if (list_empty(&tr->tr_ail1_list) && oldest_tr)
list_move(&tr->tr_list, &sdp->sd_ail2_list);
else
@@ -230,6 +239,9 @@ static int gfs2_ail1_empty(struct gfs2_sbd *sdp)
ret = list_empty(&sdp->sd_ail1_list);
spin_unlock(&sdp->sd_ail_lock);
+ if (withdraw)
+ gfs2_lm_withdraw(sdp, "fatal: I/O error(s)\n");
+
return ret;
}
@@ -689,7 +701,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
hash = ~crc32(~0, lh, LH_V1_SIZE);
lh->lh_hash = cpu_to_be32(hash);
- tv = current_kernel_time64();
+ ktime_get_coarse_real_ts64(&tv);
lh->lh_nsec = cpu_to_be32(tv.tv_nsec);
lh->lh_sec = cpu_to_be64(tv.tv_sec);
addr = gfs2_log_bmap(sdp);