diff options
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r-- | fs/gfs2/glops.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 9c046dbf4729..ef1492e2d445 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -77,32 +77,24 @@ static void gfs2_page_inval(struct gfs2_glock *gl) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * gfs2_page_sync - Sync the data pages (not metadata) associated with a glock | 80 | * gfs2_page_wait - Wait for writeback of data |
81 | * @gl: the glock | 81 | * @gl: the glock |
82 | * @flags: DIO_START | DIO_WAIT | ||
83 | * | 82 | * |
84 | * Syncs data (not metadata) for a regular file. | 83 | * Syncs data (not metadata) for a regular file. |
85 | * No-op for all other types. | 84 | * No-op for all other types. |
86 | */ | 85 | */ |
87 | 86 | ||
88 | static void gfs2_page_sync(struct gfs2_glock *gl, int flags) | 87 | static void gfs2_page_wait(struct gfs2_glock *gl) |
89 | { | 88 | { |
90 | struct gfs2_inode *ip; | 89 | struct gfs2_inode *ip = gl->gl_object; |
91 | struct inode *inode; | 90 | struct inode *inode = &ip->i_inode; |
92 | struct address_space *mapping; | 91 | struct address_space *mapping = inode->i_mapping; |
93 | int error = 0; | 92 | int error; |
94 | 93 | ||
95 | ip = gl->gl_object; | 94 | if (!S_ISREG(ip->i_di.di_mode)) |
96 | inode = &ip->i_inode; | ||
97 | if (!ip || !S_ISREG(ip->i_di.di_mode)) | ||
98 | return; | 95 | return; |
99 | 96 | ||
100 | mapping = inode->i_mapping; | 97 | error = filemap_fdatawait(mapping); |
101 | |||
102 | if (flags & DIO_START) | ||
103 | filemap_fdatawrite(mapping); | ||
104 | if (!error && (flags & DIO_WAIT)) | ||
105 | error = filemap_fdatawait(mapping); | ||
106 | 98 | ||
107 | /* Put back any errors cleared by filemap_fdatawait() | 99 | /* Put back any errors cleared by filemap_fdatawait() |
108 | so they can be caught by someone who can pass them | 100 | so they can be caught by someone who can pass them |
@@ -115,6 +107,18 @@ static void gfs2_page_sync(struct gfs2_glock *gl, int flags) | |||
115 | 107 | ||
116 | } | 108 | } |
117 | 109 | ||
110 | static void gfs2_page_writeback(struct gfs2_glock *gl) | ||
111 | { | ||
112 | struct gfs2_inode *ip = gl->gl_object; | ||
113 | struct inode *inode = &ip->i_inode; | ||
114 | struct address_space *mapping = inode->i_mapping; | ||
115 | |||
116 | if (!S_ISREG(ip->i_di.di_mode)) | ||
117 | return; | ||
118 | |||
119 | filemap_fdatawrite(mapping); | ||
120 | } | ||
121 | |||
118 | /** | 122 | /** |
119 | * meta_go_sync - sync out the metadata for this glock | 123 | * meta_go_sync - sync out the metadata for this glock |
120 | * @gl: the glock | 124 | * @gl: the glock |
@@ -132,7 +136,7 @@ static void meta_go_sync(struct gfs2_glock *gl, int flags) | |||
132 | 136 | ||
133 | if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { | 137 | if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { |
134 | gfs2_log_flush(gl->gl_sbd, gl); | 138 | gfs2_log_flush(gl->gl_sbd, gl); |
135 | gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT); | 139 | gfs2_meta_sync(gl); |
136 | if (flags & DIO_RELEASE) | 140 | if (flags & DIO_RELEASE) |
137 | gfs2_ail_empty_gl(gl); | 141 | gfs2_ail_empty_gl(gl); |
138 | } | 142 | } |
@@ -185,8 +189,7 @@ static void inode_go_xmote_bh(struct gfs2_glock *gl) | |||
185 | 189 | ||
186 | if (gl->gl_state != LM_ST_UNLOCKED && | 190 | if (gl->gl_state != LM_ST_UNLOCKED && |
187 | (!gh || !(gh->gh_flags & GL_SKIP))) { | 191 | (!gh || !(gh->gh_flags & GL_SKIP))) { |
188 | error = gfs2_meta_read(gl, gl->gl_name.ln_number, DIO_START, | 192 | error = gfs2_meta_read(gl, gl->gl_name.ln_number, 0, &bh); |
189 | &bh); | ||
190 | if (!error) | 193 | if (!error) |
191 | brelse(bh); | 194 | brelse(bh); |
192 | } | 195 | } |
@@ -221,16 +224,18 @@ static void inode_go_sync(struct gfs2_glock *gl, int flags) | |||
221 | 224 | ||
222 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { | 225 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { |
223 | if (meta && data) { | 226 | if (meta && data) { |
224 | gfs2_page_sync(gl, flags | DIO_START); | 227 | gfs2_page_writeback(gl); |
225 | gfs2_log_flush(gl->gl_sbd, gl); | 228 | gfs2_log_flush(gl->gl_sbd, gl); |
226 | gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT); | 229 | gfs2_meta_sync(gl); |
227 | gfs2_page_sync(gl, flags | DIO_WAIT); | 230 | gfs2_page_wait(gl); |
228 | clear_bit(GLF_DIRTY, &gl->gl_flags); | 231 | clear_bit(GLF_DIRTY, &gl->gl_flags); |
229 | } else if (meta) { | 232 | } else if (meta) { |
230 | gfs2_log_flush(gl->gl_sbd, gl); | 233 | gfs2_log_flush(gl->gl_sbd, gl); |
231 | gfs2_meta_sync(gl, flags | DIO_START | DIO_WAIT); | 234 | gfs2_meta_sync(gl); |
232 | } else if (data) | 235 | } else if (data) { |
233 | gfs2_page_sync(gl, flags | DIO_START | DIO_WAIT); | 236 | gfs2_page_writeback(gl); |
237 | gfs2_page_wait(gl); | ||
238 | } | ||
234 | if (flags & DIO_RELEASE) | 239 | if (flags & DIO_RELEASE) |
235 | gfs2_ail_empty_gl(gl); | 240 | gfs2_ail_empty_gl(gl); |
236 | } | 241 | } |