aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r--fs/gfs2/log.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index b8830fda51e8..a2e1df488df0 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -551,9 +551,9 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp)
LIST_HEAD(written);
spin_lock(&sdp->sd_ordered_lock);
- list_sort(NULL, &sdp->sd_log_le_ordered, &ip_cmp);
- while (!list_empty(&sdp->sd_log_le_ordered)) {
- ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered);
+ list_sort(NULL, &sdp->sd_log_ordered, &ip_cmp);
+ while (!list_empty(&sdp->sd_log_ordered)) {
+ ip = list_entry(sdp->sd_log_ordered.next, struct gfs2_inode, i_ordered);
if (ip->i_inode.i_mapping->nrpages == 0) {
test_and_clear_bit(GIF_ORDERED, &ip->i_flags);
list_del(&ip->i_ordered);
@@ -564,7 +564,7 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp)
filemap_fdatawrite(ip->i_inode.i_mapping);
spin_lock(&sdp->sd_ordered_lock);
}
- list_splice(&written, &sdp->sd_log_le_ordered);
+ list_splice(&written, &sdp->sd_log_ordered);
spin_unlock(&sdp->sd_ordered_lock);
}
@@ -573,8 +573,8 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
struct gfs2_inode *ip;
spin_lock(&sdp->sd_ordered_lock);
- while (!list_empty(&sdp->sd_log_le_ordered)) {
- ip = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_inode, i_ordered);
+ while (!list_empty(&sdp->sd_log_ordered)) {
+ ip = list_entry(sdp->sd_log_ordered.next, struct gfs2_inode, i_ordered);
list_del(&ip->i_ordered);
WARN_ON(!test_and_clear_bit(GIF_ORDERED, &ip->i_flags));
if (ip->i_inode.i_mapping->nrpages == 0)
@@ -606,9 +606,12 @@ void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
gfs2_remove_from_ail(bd); /* drops ref on bh */
bd->bd_bh = NULL;
sdp->sd_log_num_revoke++;
- atomic_inc(&gl->gl_revokes);
+ if (!test_bit(GLF_REVOKES, &gl->gl_flags)) {
+ set_bit(GLF_REVOKES, &gl->gl_flags);
+ gfs2_glock_hold(gl);
+ }
set_bit(GLF_LFLUSH, &gl->gl_flags);
- list_add(&bd->bd_list, &sdp->sd_log_le_revoke);
+ list_add(&bd->bd_list, &sdp->sd_log_revokes);
}
void gfs2_write_revokes(struct gfs2_sbd *sdp)
@@ -666,11 +669,12 @@ out_of_blocks:
}
/**
- * write_log_header - Write a journal log header buffer at sd_log_flush_head
+ * gfs2_write_log_header - Write a journal log header buffer at lblock
* @sdp: The GFS2 superblock
* @jd: journal descriptor of the journal to which we are writing
* @seq: sequence number
* @tail: tail of the log
+ * @lblock: value for lh_blkno (block number relative to start of journal)
* @flags: log header flags GFS2_LOG_HEAD_*
* @op_flags: flags to pass to the bio
*
@@ -678,7 +682,8 @@ out_of_blocks:
*/
void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
- u64 seq, u32 tail, u32 flags, int op_flags)
+ u64 seq, u32 tail, u32 lblock, u32 flags,
+ int op_flags)
{
struct gfs2_log_header *lh;
u32 hash, crc;
@@ -686,7 +691,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
struct timespec64 tv;
struct super_block *sb = sdp->sd_vfs;
- u64 addr;
+ u64 dblock;
lh = page_address(page);
clear_page(lh);
@@ -699,15 +704,21 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
lh->lh_sequence = cpu_to_be64(seq);
lh->lh_flags = cpu_to_be32(flags);
lh->lh_tail = cpu_to_be32(tail);
- lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head);
+ lh->lh_blkno = cpu_to_be32(lblock);
hash = ~crc32(~0, lh, LH_V1_SIZE);
lh->lh_hash = cpu_to_be32(hash);
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);
- lh->lh_addr = cpu_to_be64(addr);
+ if (!list_empty(&jd->extent_list))
+ dblock = gfs2_log_bmap(sdp);
+ else {
+ int ret = gfs2_lblk_to_dblk(jd->jd_inode, lblock, &dblock);
+ if (gfs2_assert_withdraw(sdp, ret == 0))
+ return;
+ }
+ lh->lh_addr = cpu_to_be64(dblock);
lh->lh_jinode = cpu_to_be64(GFS2_I(jd->jd_inode)->i_no_addr);
/* We may only write local statfs, quota, etc., when writing to our
@@ -732,8 +743,8 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
sb->s_blocksize - LH_V1_SIZE - 4);
lh->lh_crc = cpu_to_be32(crc);
- gfs2_log_write(sdp, page, sb->s_blocksize, 0, addr);
- gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE, op_flags);
+ gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock);
+ gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE | op_flags);
log_flush_wait(sdp);
}
@@ -761,7 +772,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
}
sdp->sd_log_idle = (tail == sdp->sd_log_flush_head);
gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail,
- flags, op_flags);
+ sdp->sd_log_flush_head, flags, op_flags);
if (sdp->sd_log_tail != tail)
log_pull_tail(sdp, tail);
@@ -810,7 +821,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
gfs2_ordered_write(sdp);
lops_before_commit(sdp, tr);
- gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE, 0);
+ gfs2_log_submit_bio(&sdp->sd_log_bio, REQ_OP_WRITE);
if (sdp->sd_log_head != sdp->sd_log_flush_head) {
log_flush_wait(sdp);