diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2011-04-14 04:54:02 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2011-04-20 04:00:41 -0400 |
commit | dba898b02defa66e5fe493d58ec0293a940f9c93 (patch) | |
tree | 68ef0414a4c0ba677c23dbca6ecab957e9f11c35 /fs/gfs2/glops.c | |
parent | efc1a9c2a70e4e49f4cf179a7ed8064b7a406e4a (diff) |
GFS2: Clean up fsync()
This patch is designed to clean up GFS2's fsync
implementation and ensure that it really does get everything on
disk. Since ->write_inode() has been updated, we can call that
via the vfs library function sync_inode_metadata() and the only
remaining thing that has to be done is to ensure that we get
any revoke records in the log after the inode has been written back.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r-- | fs/gfs2/glops.c | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 25eeb2bcee47..7c1b08f63ddb 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -28,33 +28,18 @@ | |||
28 | #include "trans.h" | 28 | #include "trans.h" |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * ail_empty_gl - remove all buffers for a given lock from the AIL | 31 | * __gfs2_ail_flush - remove all buffers for a given lock from the AIL |
32 | * @gl: the glock | 32 | * @gl: the glock |
33 | * | 33 | * |
34 | * None of the buffers should be dirty, locked, or pinned. | 34 | * None of the buffers should be dirty, locked, or pinned. |
35 | */ | 35 | */ |
36 | 36 | ||
37 | static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | 37 | static void __gfs2_ail_flush(struct gfs2_glock *gl) |
38 | { | 38 | { |
39 | struct gfs2_sbd *sdp = gl->gl_sbd; | 39 | struct gfs2_sbd *sdp = gl->gl_sbd; |
40 | struct list_head *head = &gl->gl_ail_list; | 40 | struct list_head *head = &gl->gl_ail_list; |
41 | struct gfs2_bufdata *bd; | 41 | struct gfs2_bufdata *bd; |
42 | struct buffer_head *bh; | 42 | struct buffer_head *bh; |
43 | struct gfs2_trans tr; | ||
44 | |||
45 | memset(&tr, 0, sizeof(tr)); | ||
46 | tr.tr_revokes = atomic_read(&gl->gl_ail_count); | ||
47 | |||
48 | if (!tr.tr_revokes) | ||
49 | return; | ||
50 | |||
51 | /* A shortened, inline version of gfs2_trans_begin() */ | ||
52 | tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); | ||
53 | tr.tr_ip = (unsigned long)__builtin_return_address(0); | ||
54 | INIT_LIST_HEAD(&tr.tr_list_buf); | ||
55 | gfs2_log_reserve(sdp, tr.tr_reserved); | ||
56 | BUG_ON(current->journal_info); | ||
57 | current->journal_info = &tr; | ||
58 | 43 | ||
59 | spin_lock(&sdp->sd_ail_lock); | 44 | spin_lock(&sdp->sd_ail_lock); |
60 | while (!list_empty(head)) { | 45 | while (!list_empty(head)) { |
@@ -76,7 +61,47 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
76 | } | 61 | } |
77 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); | 62 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); |
78 | spin_unlock(&sdp->sd_ail_lock); | 63 | spin_unlock(&sdp->sd_ail_lock); |
64 | } | ||
65 | |||
66 | |||
67 | static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | ||
68 | { | ||
69 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
70 | struct gfs2_trans tr; | ||
71 | |||
72 | memset(&tr, 0, sizeof(tr)); | ||
73 | tr.tr_revokes = atomic_read(&gl->gl_ail_count); | ||
74 | |||
75 | if (!tr.tr_revokes) | ||
76 | return; | ||
77 | |||
78 | /* A shortened, inline version of gfs2_trans_begin() */ | ||
79 | tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); | ||
80 | tr.tr_ip = (unsigned long)__builtin_return_address(0); | ||
81 | INIT_LIST_HEAD(&tr.tr_list_buf); | ||
82 | gfs2_log_reserve(sdp, tr.tr_reserved); | ||
83 | BUG_ON(current->journal_info); | ||
84 | current->journal_info = &tr; | ||
85 | |||
86 | __gfs2_ail_flush(gl); | ||
87 | |||
88 | gfs2_trans_end(sdp); | ||
89 | gfs2_log_flush(sdp, NULL); | ||
90 | } | ||
79 | 91 | ||
92 | void gfs2_ail_flush(struct gfs2_glock *gl) | ||
93 | { | ||
94 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
95 | unsigned int revokes = atomic_read(&gl->gl_ail_count); | ||
96 | int ret; | ||
97 | |||
98 | if (!revokes) | ||
99 | return; | ||
100 | |||
101 | ret = gfs2_trans_begin(sdp, 0, revokes); | ||
102 | if (ret) | ||
103 | return; | ||
104 | __gfs2_ail_flush(gl); | ||
80 | gfs2_trans_end(sdp); | 105 | gfs2_trans_end(sdp); |
81 | gfs2_log_flush(sdp, NULL); | 106 | gfs2_log_flush(sdp, NULL); |
82 | } | 107 | } |