diff options
-rw-r--r-- | fs/gfs2/file.c | 8 | ||||
-rw-r--r-- | fs/gfs2/glops.c | 32 | ||||
-rw-r--r-- | fs/gfs2/glops.h | 2 | ||||
-rw-r--r-- | fs/gfs2/super.c | 2 |
4 files changed, 20 insertions, 24 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 3467f3662149..3b65f67bb38e 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -593,16 +593,12 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end, | |||
593 | sync_state &= ~I_DIRTY_SYNC; | 593 | sync_state &= ~I_DIRTY_SYNC; |
594 | 594 | ||
595 | if (sync_state) { | 595 | if (sync_state) { |
596 | mutex_lock(&inode->i_mutex); | ||
597 | ret = sync_inode_metadata(inode, 1); | 596 | ret = sync_inode_metadata(inode, 1); |
598 | if (ret) { | 597 | if (ret) |
599 | mutex_unlock(&inode->i_mutex); | ||
600 | return ret; | 598 | return ret; |
601 | } | ||
602 | if (gfs2_is_jdata(ip)) | 599 | if (gfs2_is_jdata(ip)) |
603 | filemap_write_and_wait(mapping); | 600 | filemap_write_and_wait(mapping); |
604 | gfs2_ail_flush(ip->i_gl); | 601 | gfs2_ail_flush(ip->i_gl, 1); |
605 | mutex_unlock(&inode->i_mutex); | ||
606 | } | 602 | } |
607 | 603 | ||
608 | if (mapping->nrpages) | 604 | if (mapping->nrpages) |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 951541b6234c..78418b4fa857 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -42,41 +42,41 @@ static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh) | |||
42 | /** | 42 | /** |
43 | * __gfs2_ail_flush - remove all buffers for a given lock from the AIL | 43 | * __gfs2_ail_flush - remove all buffers for a given lock from the AIL |
44 | * @gl: the glock | 44 | * @gl: the glock |
45 | * @fsync: set when called from fsync (not all buffers will be clean) | ||
45 | * | 46 | * |
46 | * None of the buffers should be dirty, locked, or pinned. | 47 | * None of the buffers should be dirty, locked, or pinned. |
47 | */ | 48 | */ |
48 | 49 | ||
49 | static void __gfs2_ail_flush(struct gfs2_glock *gl, unsigned long b_state) | 50 | static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) |
50 | { | 51 | { |
51 | struct gfs2_sbd *sdp = gl->gl_sbd; | 52 | struct gfs2_sbd *sdp = gl->gl_sbd; |
52 | struct list_head *head = &gl->gl_ail_list; | 53 | struct list_head *head = &gl->gl_ail_list; |
53 | struct gfs2_bufdata *bd; | 54 | struct gfs2_bufdata *bd, *tmp; |
54 | struct buffer_head *bh; | 55 | struct buffer_head *bh; |
56 | const unsigned long b_state = (1UL << BH_Dirty)|(1UL << BH_Pinned)|(1UL << BH_Lock); | ||
55 | sector_t blocknr; | 57 | sector_t blocknr; |
56 | 58 | ||
59 | gfs2_log_lock(sdp); | ||
57 | spin_lock(&sdp->sd_ail_lock); | 60 | spin_lock(&sdp->sd_ail_lock); |
58 | while (!list_empty(head)) { | 61 | list_for_each_entry_safe(bd, tmp, head, bd_ail_gl_list) { |
59 | bd = list_entry(head->next, struct gfs2_bufdata, | ||
60 | bd_ail_gl_list); | ||
61 | bh = bd->bd_bh; | 62 | bh = bd->bd_bh; |
62 | blocknr = bh->b_blocknr; | 63 | if (bh->b_state & b_state) { |
63 | if (bh->b_state & b_state) | 64 | if (fsync) |
65 | continue; | ||
64 | gfs2_ail_error(gl, bh); | 66 | gfs2_ail_error(gl, bh); |
67 | } | ||
68 | blocknr = bh->b_blocknr; | ||
65 | bh->b_private = NULL; | 69 | bh->b_private = NULL; |
66 | gfs2_remove_from_ail(bd); /* drops ref on bh */ | 70 | gfs2_remove_from_ail(bd); /* drops ref on bh */ |
67 | spin_unlock(&sdp->sd_ail_lock); | ||
68 | 71 | ||
69 | bd->bd_bh = NULL; | 72 | bd->bd_bh = NULL; |
70 | bd->bd_blkno = blocknr; | 73 | bd->bd_blkno = blocknr; |
71 | 74 | ||
72 | gfs2_log_lock(sdp); | ||
73 | gfs2_trans_add_revoke(sdp, bd); | 75 | gfs2_trans_add_revoke(sdp, bd); |
74 | gfs2_log_unlock(sdp); | ||
75 | |||
76 | spin_lock(&sdp->sd_ail_lock); | ||
77 | } | 76 | } |
78 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); | 77 | BUG_ON(!fsync && atomic_read(&gl->gl_ail_count)); |
79 | spin_unlock(&sdp->sd_ail_lock); | 78 | spin_unlock(&sdp->sd_ail_lock); |
79 | gfs2_log_unlock(sdp); | ||
80 | } | 80 | } |
81 | 81 | ||
82 | 82 | ||
@@ -99,13 +99,13 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
99 | BUG_ON(current->journal_info); | 99 | BUG_ON(current->journal_info); |
100 | current->journal_info = &tr; | 100 | current->journal_info = &tr; |
101 | 101 | ||
102 | __gfs2_ail_flush(gl, (1ul << BH_Dirty)|(1ul << BH_Pinned)|(1ul << BH_Lock)); | 102 | __gfs2_ail_flush(gl, 0); |
103 | 103 | ||
104 | gfs2_trans_end(sdp); | 104 | gfs2_trans_end(sdp); |
105 | gfs2_log_flush(sdp, NULL); | 105 | gfs2_log_flush(sdp, NULL); |
106 | } | 106 | } |
107 | 107 | ||
108 | void gfs2_ail_flush(struct gfs2_glock *gl) | 108 | void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) |
109 | { | 109 | { |
110 | struct gfs2_sbd *sdp = gl->gl_sbd; | 110 | struct gfs2_sbd *sdp = gl->gl_sbd; |
111 | unsigned int revokes = atomic_read(&gl->gl_ail_count); | 111 | unsigned int revokes = atomic_read(&gl->gl_ail_count); |
@@ -117,7 +117,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl) | |||
117 | ret = gfs2_trans_begin(sdp, 0, revokes); | 117 | ret = gfs2_trans_begin(sdp, 0, revokes); |
118 | if (ret) | 118 | if (ret) |
119 | return; | 119 | return; |
120 | __gfs2_ail_flush(gl, (1ul << BH_Dirty)|(1ul << BH_Pinned)); | 120 | __gfs2_ail_flush(gl, fsync); |
121 | gfs2_trans_end(sdp); | 121 | gfs2_trans_end(sdp); |
122 | gfs2_log_flush(sdp, NULL); | 122 | gfs2_log_flush(sdp, NULL); |
123 | } | 123 | } |
diff --git a/fs/gfs2/glops.h b/fs/gfs2/glops.h index 6fce409b5a50..bf95a2dc1662 100644 --- a/fs/gfs2/glops.h +++ b/fs/gfs2/glops.h | |||
@@ -23,6 +23,6 @@ extern const struct gfs2_glock_operations gfs2_quota_glops; | |||
23 | extern const struct gfs2_glock_operations gfs2_journal_glops; | 23 | extern const struct gfs2_glock_operations gfs2_journal_glops; |
24 | extern const struct gfs2_glock_operations *gfs2_glops_list[]; | 24 | extern const struct gfs2_glock_operations *gfs2_glops_list[]; |
25 | 25 | ||
26 | extern void gfs2_ail_flush(struct gfs2_glock *gl); | 26 | extern void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync); |
27 | 27 | ||
28 | #endif /* __GLOPS_DOT_H__ */ | 28 | #endif /* __GLOPS_DOT_H__ */ |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 87e9141a4def..71e420989f77 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -1533,7 +1533,7 @@ static void gfs2_evict_inode(struct inode *inode) | |||
1533 | out_truncate: | 1533 | out_truncate: |
1534 | gfs2_log_flush(sdp, ip->i_gl); | 1534 | gfs2_log_flush(sdp, ip->i_gl); |
1535 | write_inode_now(inode, 1); | 1535 | write_inode_now(inode, 1); |
1536 | gfs2_ail_flush(ip->i_gl); | 1536 | gfs2_ail_flush(ip->i_gl, 0); |
1537 | 1537 | ||
1538 | /* Case 2 starts here */ | 1538 | /* Case 2 starts here */ |
1539 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 1539 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |