diff options
Diffstat (limited to 'fs/gfs2/meta_io.c')
-rw-r--r-- | fs/gfs2/meta_io.c | 97 |
1 files changed, 19 insertions, 78 deletions
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 4da423985e4f..85aea27b4a86 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -50,6 +50,7 @@ static int gfs2_aspace_writepage(struct page *page, | |||
50 | static const struct address_space_operations aspace_aops = { | 50 | static const struct address_space_operations aspace_aops = { |
51 | .writepage = gfs2_aspace_writepage, | 51 | .writepage = gfs2_aspace_writepage, |
52 | .releasepage = gfs2_releasepage, | 52 | .releasepage = gfs2_releasepage, |
53 | .sync_page = block_sync_page, | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | /** | 56 | /** |
@@ -221,13 +222,14 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | |||
221 | struct buffer_head **bhp) | 222 | struct buffer_head **bhp) |
222 | { | 223 | { |
223 | *bhp = getbuf(gl, blkno, CREATE); | 224 | *bhp = getbuf(gl, blkno, CREATE); |
224 | if (!buffer_uptodate(*bhp)) | 225 | if (!buffer_uptodate(*bhp)) { |
225 | ll_rw_block(READ_META, 1, bhp); | 226 | ll_rw_block(READ_META, 1, bhp); |
226 | if (flags & DIO_WAIT) { | 227 | if (flags & DIO_WAIT) { |
227 | int error = gfs2_meta_wait(gl->gl_sbd, *bhp); | 228 | int error = gfs2_meta_wait(gl->gl_sbd, *bhp); |
228 | if (error) { | 229 | if (error) { |
229 | brelse(*bhp); | 230 | brelse(*bhp); |
230 | return error; | 231 | return error; |
232 | } | ||
231 | } | 233 | } |
232 | } | 234 | } |
233 | 235 | ||
@@ -282,7 +284,7 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh, | |||
282 | return; | 284 | return; |
283 | } | 285 | } |
284 | 286 | ||
285 | bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL), | 287 | bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL); |
286 | bd->bd_bh = bh; | 288 | bd->bd_bh = bh; |
287 | bd->bd_gl = gl; | 289 | bd->bd_gl = gl; |
288 | 290 | ||
@@ -317,7 +319,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int | |||
317 | } | 319 | } |
318 | if (bd) { | 320 | if (bd) { |
319 | if (bd->bd_ail) { | 321 | if (bd->bd_ail) { |
320 | gfs2_remove_from_ail(NULL, bd); | 322 | gfs2_remove_from_ail(bd); |
321 | bh->b_private = NULL; | 323 | bh->b_private = NULL; |
322 | bd->bd_bh = NULL; | 324 | bd->bd_bh = NULL; |
323 | bd->bd_blkno = bh->b_blocknr; | 325 | bd->bd_blkno = bh->b_blocknr; |
@@ -358,32 +360,6 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
358 | } | 360 | } |
359 | 361 | ||
360 | /** | 362 | /** |
361 | * gfs2_meta_cache_flush - get rid of any references on buffers for this inode | ||
362 | * @ip: The GFS2 inode | ||
363 | * | ||
364 | * This releases buffers that are in the most-recently-used array of | ||
365 | * blocks used for indirect block addressing for this inode. | ||
366 | */ | ||
367 | |||
368 | void gfs2_meta_cache_flush(struct gfs2_inode *ip) | ||
369 | { | ||
370 | struct buffer_head **bh_slot; | ||
371 | unsigned int x; | ||
372 | |||
373 | spin_lock(&ip->i_spin); | ||
374 | |||
375 | for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) { | ||
376 | bh_slot = &ip->i_cache[x]; | ||
377 | if (*bh_slot) { | ||
378 | brelse(*bh_slot); | ||
379 | *bh_slot = NULL; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | spin_unlock(&ip->i_spin); | ||
384 | } | ||
385 | |||
386 | /** | ||
387 | * gfs2_meta_indirect_buffer - Get a metadata buffer | 363 | * gfs2_meta_indirect_buffer - Get a metadata buffer |
388 | * @ip: The GFS2 inode | 364 | * @ip: The GFS2 inode |
389 | * @height: The level of this buf in the metadata (indir addr) tree (if any) | 365 | * @height: The level of this buf in the metadata (indir addr) tree (if any) |
@@ -391,8 +367,6 @@ void gfs2_meta_cache_flush(struct gfs2_inode *ip) | |||
391 | * @new: Non-zero if we may create a new buffer | 367 | * @new: Non-zero if we may create a new buffer |
392 | * @bhp: the buffer is returned here | 368 | * @bhp: the buffer is returned here |
393 | * | 369 | * |
394 | * Try to use the gfs2_inode's MRU metadata tree cache. | ||
395 | * | ||
396 | * Returns: errno | 370 | * Returns: errno |
397 | */ | 371 | */ |
398 | 372 | ||
@@ -401,58 +375,25 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
401 | { | 375 | { |
402 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 376 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
403 | struct gfs2_glock *gl = ip->i_gl; | 377 | struct gfs2_glock *gl = ip->i_gl; |
404 | struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; | 378 | struct buffer_head *bh; |
405 | int in_cache = 0; | 379 | int ret = 0; |
406 | |||
407 | BUG_ON(!gl); | ||
408 | BUG_ON(!sdp); | ||
409 | |||
410 | spin_lock(&ip->i_spin); | ||
411 | if (*bh_slot && (*bh_slot)->b_blocknr == num) { | ||
412 | bh = *bh_slot; | ||
413 | get_bh(bh); | ||
414 | in_cache = 1; | ||
415 | } | ||
416 | spin_unlock(&ip->i_spin); | ||
417 | |||
418 | if (!bh) | ||
419 | bh = getbuf(gl, num, CREATE); | ||
420 | |||
421 | if (!bh) | ||
422 | return -ENOBUFS; | ||
423 | 380 | ||
424 | if (new) { | 381 | if (new) { |
425 | if (gfs2_assert_warn(sdp, height)) | 382 | BUG_ON(height == 0); |
426 | goto err; | 383 | bh = gfs2_meta_new(gl, num); |
427 | meta_prep_new(bh); | ||
428 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 384 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
429 | gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); | 385 | gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); |
430 | gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); | 386 | gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); |
431 | } else { | 387 | } else { |
432 | u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; | 388 | u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; |
433 | if (!buffer_uptodate(bh)) { | 389 | ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh); |
434 | ll_rw_block(READ_META, 1, &bh); | 390 | if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { |
435 | if (gfs2_meta_wait(sdp, bh)) | 391 | brelse(bh); |
436 | goto err; | 392 | ret = -EIO; |
437 | } | 393 | } |
438 | if (gfs2_metatype_check(sdp, bh, mtype)) | ||
439 | goto err; | ||
440 | } | ||
441 | |||
442 | if (!in_cache) { | ||
443 | spin_lock(&ip->i_spin); | ||
444 | if (*bh_slot) | ||
445 | brelse(*bh_slot); | ||
446 | *bh_slot = bh; | ||
447 | get_bh(bh); | ||
448 | spin_unlock(&ip->i_spin); | ||
449 | } | 394 | } |
450 | |||
451 | *bhp = bh; | 395 | *bhp = bh; |
452 | return 0; | 396 | return ret; |
453 | err: | ||
454 | brelse(bh); | ||
455 | return -EIO; | ||
456 | } | 397 | } |
457 | 398 | ||
458 | /** | 399 | /** |