aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r--fs/gfs2/glops.c138
1 files changed, 35 insertions, 103 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 41a6b6818a50..b068d10bcb6e 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -92,7 +92,7 @@ static void gfs2_pte_inval(struct gfs2_glock *gl)
92 92
93 ip = gl->gl_object; 93 ip = gl->gl_object;
94 inode = &ip->i_inode; 94 inode = &ip->i_inode;
95 if (!ip || !S_ISREG(ip->i_di.di_mode)) 95 if (!ip || !S_ISREG(inode->i_mode))
96 return; 96 return;
97 97
98 if (!test_bit(GIF_PAGED, &ip->i_flags)) 98 if (!test_bit(GIF_PAGED, &ip->i_flags))
@@ -107,89 +107,20 @@ static void gfs2_pte_inval(struct gfs2_glock *gl)
107} 107}
108 108
109/** 109/**
110 * gfs2_page_inval - Invalidate all pages associated with a glock
111 * @gl: the glock
112 *
113 */
114
115static void gfs2_page_inval(struct gfs2_glock *gl)
116{
117 struct gfs2_inode *ip;
118 struct inode *inode;
119
120 ip = gl->gl_object;
121 inode = &ip->i_inode;
122 if (!ip || !S_ISREG(ip->i_di.di_mode))
123 return;
124
125 truncate_inode_pages(inode->i_mapping, 0);
126 gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !inode->i_mapping->nrpages);
127 clear_bit(GIF_PAGED, &ip->i_flags);
128}
129
130/**
131 * gfs2_page_wait - Wait for writeback of data
132 * @gl: the glock
133 *
134 * Syncs data (not metadata) for a regular file.
135 * No-op for all other types.
136 */
137
138static void gfs2_page_wait(struct gfs2_glock *gl)
139{
140 struct gfs2_inode *ip = gl->gl_object;
141 struct inode *inode = &ip->i_inode;
142 struct address_space *mapping = inode->i_mapping;
143 int error;
144
145 if (!S_ISREG(ip->i_di.di_mode))
146 return;
147
148 error = filemap_fdatawait(mapping);
149
150 /* Put back any errors cleared by filemap_fdatawait()
151 so they can be caught by someone who can pass them
152 up to user space. */
153
154 if (error == -ENOSPC)
155 set_bit(AS_ENOSPC, &mapping->flags);
156 else if (error)
157 set_bit(AS_EIO, &mapping->flags);
158
159}
160
161static void gfs2_page_writeback(struct gfs2_glock *gl)
162{
163 struct gfs2_inode *ip = gl->gl_object;
164 struct inode *inode = &ip->i_inode;
165 struct address_space *mapping = inode->i_mapping;
166
167 if (!S_ISREG(ip->i_di.di_mode))
168 return;
169
170 filemap_fdatawrite(mapping);
171}
172
173/**
174 * meta_go_sync - sync out the metadata for this glock 110 * meta_go_sync - sync out the metadata for this glock
175 * @gl: the glock 111 * @gl: the glock
176 * @flags: DIO_*
177 * 112 *
178 * Called when demoting or unlocking an EX glock. We must flush 113 * Called when demoting or unlocking an EX glock. We must flush
179 * to disk all dirty buffers/pages relating to this glock, and must not 114 * to disk all dirty buffers/pages relating to this glock, and must not
180 * not return to caller to demote/unlock the glock until I/O is complete. 115 * not return to caller to demote/unlock the glock until I/O is complete.
181 */ 116 */
182 117
183static void meta_go_sync(struct gfs2_glock *gl, int flags) 118static void meta_go_sync(struct gfs2_glock *gl)
184{ 119{
185 if (!(flags & DIO_METADATA))
186 return;
187
188 if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { 120 if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) {
189 gfs2_log_flush(gl->gl_sbd, gl); 121 gfs2_log_flush(gl->gl_sbd, gl);
190 gfs2_meta_sync(gl); 122 gfs2_meta_sync(gl);
191 if (flags & DIO_RELEASE) 123 gfs2_ail_empty_gl(gl);
192 gfs2_ail_empty_gl(gl);
193 } 124 }
194 125
195} 126}
@@ -264,31 +195,31 @@ static void inode_go_drop_th(struct gfs2_glock *gl)
264/** 195/**
265 * inode_go_sync - Sync the dirty data and/or metadata for an inode glock 196 * inode_go_sync - Sync the dirty data and/or metadata for an inode glock
266 * @gl: the glock protecting the inode 197 * @gl: the glock protecting the inode
267 * @flags:
268 * 198 *
269 */ 199 */
270 200
271static void inode_go_sync(struct gfs2_glock *gl, int flags) 201static void inode_go_sync(struct gfs2_glock *gl)
272{ 202{
273 int meta = (flags & DIO_METADATA); 203 struct gfs2_inode *ip = gl->gl_object;
274 int data = (flags & DIO_DATA); 204
205 if (ip && !S_ISREG(ip->i_inode.i_mode))
206 ip = NULL;
275 207
276 if (test_bit(GLF_DIRTY, &gl->gl_flags)) { 208 if (test_bit(GLF_DIRTY, &gl->gl_flags)) {
277 if (meta && data) { 209 gfs2_log_flush(gl->gl_sbd, gl);
278 gfs2_page_writeback(gl); 210 if (ip)
279 gfs2_log_flush(gl->gl_sbd, gl); 211 filemap_fdatawrite(ip->i_inode.i_mapping);
280 gfs2_meta_sync(gl); 212 gfs2_meta_sync(gl);
281 gfs2_page_wait(gl); 213 if (ip) {
282 clear_bit(GLF_DIRTY, &gl->gl_flags); 214 struct address_space *mapping = ip->i_inode.i_mapping;
283 } else if (meta) { 215 int error = filemap_fdatawait(mapping);
284 gfs2_log_flush(gl->gl_sbd, gl); 216 if (error == -ENOSPC)
285 gfs2_meta_sync(gl); 217 set_bit(AS_ENOSPC, &mapping->flags);
286 } else if (data) { 218 else if (error)
287 gfs2_page_writeback(gl); 219 set_bit(AS_EIO, &mapping->flags);
288 gfs2_page_wait(gl);
289 } 220 }
290 if (flags & DIO_RELEASE) 221 clear_bit(GLF_DIRTY, &gl->gl_flags);
291 gfs2_ail_empty_gl(gl); 222 gfs2_ail_empty_gl(gl);
292 } 223 }
293} 224}
294 225
@@ -301,15 +232,20 @@ static void inode_go_sync(struct gfs2_glock *gl, int flags)
301 232
302static void inode_go_inval(struct gfs2_glock *gl, int flags) 233static void inode_go_inval(struct gfs2_glock *gl, int flags)
303{ 234{
235 struct gfs2_inode *ip = gl->gl_object;
304 int meta = (flags & DIO_METADATA); 236 int meta = (flags & DIO_METADATA);
305 int data = (flags & DIO_DATA);
306 237
307 if (meta) { 238 if (meta) {
308 gfs2_meta_inval(gl); 239 gfs2_meta_inval(gl);
309 gl->gl_vn++; 240 if (ip)
241 set_bit(GIF_INVALID, &ip->i_flags);
242 }
243
244 if (ip && S_ISREG(ip->i_inode.i_mode)) {
245 truncate_inode_pages(ip->i_inode.i_mapping, 0);
246 gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !ip->i_inode.i_mapping->nrpages);
247 clear_bit(GIF_PAGED, &ip->i_flags);
310 } 248 }
311 if (data)
312 gfs2_page_inval(gl);
313} 249}
314 250
315/** 251/**
@@ -351,11 +287,10 @@ static int inode_go_lock(struct gfs2_holder *gh)
351 if (!ip) 287 if (!ip)
352 return 0; 288 return 0;
353 289
354 if (ip->i_vn != gl->gl_vn) { 290 if (test_bit(GIF_INVALID, &ip->i_flags)) {
355 error = gfs2_inode_refresh(ip); 291 error = gfs2_inode_refresh(ip);
356 if (error) 292 if (error)
357 return error; 293 return error;
358 gfs2_inode_attr_in(ip);
359 } 294 }
360 295
361 if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) && 296 if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) &&
@@ -379,11 +314,8 @@ static void inode_go_unlock(struct gfs2_holder *gh)
379 struct gfs2_glock *gl = gh->gh_gl; 314 struct gfs2_glock *gl = gh->gh_gl;
380 struct gfs2_inode *ip = gl->gl_object; 315 struct gfs2_inode *ip = gl->gl_object;
381 316
382 if (ip == NULL) 317 if (ip)
383 return; 318 gfs2_meta_cache_flush(ip);
384 if (test_bit(GLF_DIRTY, &gl->gl_flags))
385 gfs2_inode_attr_in(ip);
386 gfs2_meta_cache_flush(ip);
387} 319}
388 320
389/** 321/**
@@ -491,13 +423,13 @@ static void trans_go_xmote_bh(struct gfs2_glock *gl)
491 struct gfs2_sbd *sdp = gl->gl_sbd; 423 struct gfs2_sbd *sdp = gl->gl_sbd;
492 struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); 424 struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
493 struct gfs2_glock *j_gl = ip->i_gl; 425 struct gfs2_glock *j_gl = ip->i_gl;
494 struct gfs2_log_header head; 426 struct gfs2_log_header_host head;
495 int error; 427 int error;
496 428
497 if (gl->gl_state != LM_ST_UNLOCKED && 429 if (gl->gl_state != LM_ST_UNLOCKED &&
498 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { 430 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
499 gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode)); 431 gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode));
500 j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); 432 j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
501 433
502 error = gfs2_find_jhead(sdp->sd_jdesc, &head); 434 error = gfs2_find_jhead(sdp->sd_jdesc, &head);
503 if (error) 435 if (error)