diff options
-rw-r--r-- | fs/gfs2/glops.c | 21 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 2 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 13 | ||||
-rw-r--r-- | fs/gfs2/log.c | 6 | ||||
-rw-r--r-- | fs/gfs2/log.h | 2 | ||||
-rw-r--r-- | fs/gfs2/main.c | 1 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 81 | ||||
-rw-r--r-- | fs/gfs2/meta_io.h | 1 | ||||
-rw-r--r-- | fs/gfs2/ops_address.c | 1 | ||||
-rw-r--r-- | fs/gfs2/super.c | 1 |
10 files changed, 19 insertions, 110 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 110f03d66f4b..ba124230393b 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -56,7 +56,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
56 | bd = list_entry(head->next, struct gfs2_bufdata, | 56 | bd = list_entry(head->next, struct gfs2_bufdata, |
57 | bd_ail_gl_list); | 57 | bd_ail_gl_list); |
58 | bh = bd->bd_bh; | 58 | bh = bd->bd_bh; |
59 | gfs2_remove_from_ail(NULL, bd); | 59 | gfs2_remove_from_ail(bd); |
60 | bd->bd_bh = NULL; | 60 | bd->bd_bh = NULL; |
61 | bh->b_private = NULL; | 61 | bh->b_private = NULL; |
62 | bd->bd_blkno = bh->b_blocknr; | 62 | bd->bd_blkno = bh->b_blocknr; |
@@ -287,23 +287,6 @@ static int inode_go_lock(struct gfs2_holder *gh) | |||
287 | } | 287 | } |
288 | 288 | ||
289 | /** | 289 | /** |
290 | * inode_go_unlock - operation done before an inode lock is unlocked by a | ||
291 | * process | ||
292 | * @gl: the glock | ||
293 | * @flags: | ||
294 | * | ||
295 | */ | ||
296 | |||
297 | static void inode_go_unlock(struct gfs2_holder *gh) | ||
298 | { | ||
299 | struct gfs2_glock *gl = gh->gh_gl; | ||
300 | struct gfs2_inode *ip = gl->gl_object; | ||
301 | |||
302 | if (ip) | ||
303 | gfs2_meta_cache_flush(ip); | ||
304 | } | ||
305 | |||
306 | /** | ||
307 | * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock | 290 | * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock |
308 | * @gl: the glock | 291 | * @gl: the glock |
309 | * | 292 | * |
@@ -377,7 +360,6 @@ static void trans_go_xmote_bh(struct gfs2_glock *gl) | |||
377 | 360 | ||
378 | if (gl->gl_state != LM_ST_UNLOCKED && | 361 | if (gl->gl_state != LM_ST_UNLOCKED && |
379 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { | 362 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
380 | gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode)); | ||
381 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); | 363 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
382 | 364 | ||
383 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 365 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
@@ -437,7 +419,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = { | |||
437 | .go_inval = inode_go_inval, | 419 | .go_inval = inode_go_inval, |
438 | .go_demote_ok = inode_go_demote_ok, | 420 | .go_demote_ok = inode_go_demote_ok, |
439 | .go_lock = inode_go_lock, | 421 | .go_lock = inode_go_lock, |
440 | .go_unlock = inode_go_unlock, | ||
441 | .go_type = LM_TYPE_INODE, | 422 | .go_type = LM_TYPE_INODE, |
442 | .go_min_hold_time = HZ / 10, | 423 | .go_min_hold_time = HZ / 10, |
443 | }; | 424 | }; |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 55c72f01cf31..5662ff9f86e1 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -275,8 +275,6 @@ struct gfs2_inode { | |||
275 | spinlock_t i_spin; | 275 | spinlock_t i_spin; |
276 | struct rw_semaphore i_rw_mutex; | 276 | struct rw_semaphore i_rw_mutex; |
277 | unsigned long i_last_pfault; | 277 | unsigned long i_last_pfault; |
278 | |||
279 | struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT]; | ||
280 | }; | 278 | }; |
281 | 279 | ||
282 | /* | 280 | /* |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index ad0fe373dca5..af493fc6c8ce 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -293,11 +293,6 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
293 | return 0; | 293 | return 0; |
294 | } | 294 | } |
295 | 295 | ||
296 | static void gfs2_inode_bh(struct gfs2_inode *ip, struct buffer_head *bh) | ||
297 | { | ||
298 | ip->i_cache[0] = bh; | ||
299 | } | ||
300 | |||
301 | /** | 296 | /** |
302 | * gfs2_inode_refresh - Refresh the incore copy of the dinode | 297 | * gfs2_inode_refresh - Refresh the incore copy of the dinode |
303 | * @ip: The GFS2 inode | 298 | * @ip: The GFS2 inode |
@@ -965,7 +960,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
965 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; | 960 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; |
966 | int error; | 961 | int error; |
967 | u64 generation; | 962 | u64 generation; |
968 | struct buffer_head *bh=NULL; | 963 | struct buffer_head *bh = NULL; |
969 | 964 | ||
970 | if (!name->len || name->len > GFS2_FNAMESIZE) | 965 | if (!name->len || name->len > GFS2_FNAMESIZE) |
971 | return ERR_PTR(-ENAMETOOLONG); | 966 | return ERR_PTR(-ENAMETOOLONG); |
@@ -1002,8 +997,6 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
1002 | if (IS_ERR(inode)) | 997 | if (IS_ERR(inode)) |
1003 | goto fail_gunlock2; | 998 | goto fail_gunlock2; |
1004 | 999 | ||
1005 | gfs2_inode_bh(GFS2_I(inode), bh); | ||
1006 | |||
1007 | error = gfs2_inode_refresh(GFS2_I(inode)); | 1000 | error = gfs2_inode_refresh(GFS2_I(inode)); |
1008 | if (error) | 1001 | if (error) |
1009 | goto fail_gunlock2; | 1002 | goto fail_gunlock2; |
@@ -1020,6 +1013,8 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
1020 | if (error) | 1013 | if (error) |
1021 | goto fail_gunlock2; | 1014 | goto fail_gunlock2; |
1022 | 1015 | ||
1016 | if (bh) | ||
1017 | brelse(bh); | ||
1023 | if (!inode) | 1018 | if (!inode) |
1024 | return ERR_PTR(-ENOMEM); | 1019 | return ERR_PTR(-ENOMEM); |
1025 | return inode; | 1020 | return inode; |
@@ -1031,6 +1026,8 @@ fail_gunlock2: | |||
1031 | fail_gunlock: | 1026 | fail_gunlock: |
1032 | gfs2_glock_dq(ghs); | 1027 | gfs2_glock_dq(ghs); |
1033 | fail: | 1028 | fail: |
1029 | if (bh) | ||
1030 | brelse(bh); | ||
1034 | return ERR_PTR(error); | 1031 | return ERR_PTR(error); |
1035 | } | 1032 | } |
1036 | 1033 | ||
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 7df702473252..70b404d2774b 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -68,14 +68,12 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | |||
68 | * | 68 | * |
69 | */ | 69 | */ |
70 | 70 | ||
71 | void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd) | 71 | void gfs2_remove_from_ail(struct gfs2_bufdata *bd) |
72 | { | 72 | { |
73 | bd->bd_ail = NULL; | 73 | bd->bd_ail = NULL; |
74 | list_del_init(&bd->bd_ail_st_list); | 74 | list_del_init(&bd->bd_ail_st_list); |
75 | list_del_init(&bd->bd_ail_gl_list); | 75 | list_del_init(&bd->bd_ail_gl_list); |
76 | atomic_dec(&bd->bd_gl->gl_ail_count); | 76 | atomic_dec(&bd->bd_gl->gl_ail_count); |
77 | if (mapping) | ||
78 | gfs2_meta_cache_flush(GFS2_I(mapping->host)); | ||
79 | brelse(bd->bd_bh); | 77 | brelse(bd->bd_bh); |
80 | } | 78 | } |
81 | 79 | ||
@@ -248,7 +246,7 @@ static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
248 | bd = list_entry(head->prev, struct gfs2_bufdata, | 246 | bd = list_entry(head->prev, struct gfs2_bufdata, |
249 | bd_ail_st_list); | 247 | bd_ail_st_list); |
250 | gfs2_assert(sdp, bd->bd_ail == ai); | 248 | gfs2_assert(sdp, bd->bd_ail == ai); |
251 | gfs2_remove_from_ail(bd->bd_bh->b_page->mapping, bd); | 249 | gfs2_remove_from_ail(bd); |
252 | } | 250 | } |
253 | } | 251 | } |
254 | 252 | ||
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index dae282400627..24e7161486e2 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h | |||
@@ -59,7 +59,7 @@ struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, | |||
59 | struct buffer_head *real); | 59 | struct buffer_head *real); |
60 | void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); | 60 | void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); |
61 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); | 61 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); |
62 | void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd); | 62 | void gfs2_remove_from_ail(struct gfs2_bufdata *bd); |
63 | 63 | ||
64 | void gfs2_log_shutdown(struct gfs2_sbd *sdp); | 64 | void gfs2_log_shutdown(struct gfs2_sbd *sdp); |
65 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | 65 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp); |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 7ecfe0d3a491..653fd5a6203a 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -31,7 +31,6 @@ static void gfs2_init_inode_once(struct kmem_cache *cachep, void *foo) | |||
31 | inode_init_once(&ip->i_inode); | 31 | inode_init_once(&ip->i_inode); |
32 | spin_lock_init(&ip->i_spin); | 32 | spin_lock_init(&ip->i_spin); |
33 | init_rwsem(&ip->i_rw_mutex); | 33 | init_rwsem(&ip->i_rw_mutex); |
34 | memset(ip->i_cache, 0, sizeof(ip->i_cache)); | ||
35 | } | 34 | } |
36 | 35 | ||
37 | static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo) | 36 | static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo) |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 4da423985e4f..01ef90253ed1 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -317,7 +317,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int | |||
317 | } | 317 | } |
318 | if (bd) { | 318 | if (bd) { |
319 | if (bd->bd_ail) { | 319 | if (bd->bd_ail) { |
320 | gfs2_remove_from_ail(NULL, bd); | 320 | gfs2_remove_from_ail(bd); |
321 | bh->b_private = NULL; | 321 | bh->b_private = NULL; |
322 | bd->bd_bh = NULL; | 322 | bd->bd_bh = NULL; |
323 | bd->bd_blkno = bh->b_blocknr; | 323 | bd->bd_blkno = bh->b_blocknr; |
@@ -358,32 +358,6 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
358 | } | 358 | } |
359 | 359 | ||
360 | /** | 360 | /** |
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 | 361 | * gfs2_meta_indirect_buffer - Get a metadata buffer |
388 | * @ip: The GFS2 inode | 362 | * @ip: The GFS2 inode |
389 | * @height: The level of this buf in the metadata (indir addr) tree (if any) | 363 | * @height: The level of this buf in the metadata (indir addr) tree (if any) |
@@ -391,8 +365,6 @@ void gfs2_meta_cache_flush(struct gfs2_inode *ip) | |||
391 | * @new: Non-zero if we may create a new buffer | 365 | * @new: Non-zero if we may create a new buffer |
392 | * @bhp: the buffer is returned here | 366 | * @bhp: the buffer is returned here |
393 | * | 367 | * |
394 | * Try to use the gfs2_inode's MRU metadata tree cache. | ||
395 | * | ||
396 | * Returns: errno | 368 | * Returns: errno |
397 | */ | 369 | */ |
398 | 370 | ||
@@ -401,58 +373,25 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
401 | { | 373 | { |
402 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 374 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
403 | struct gfs2_glock *gl = ip->i_gl; | 375 | struct gfs2_glock *gl = ip->i_gl; |
404 | struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; | 376 | struct buffer_head *bh; |
405 | int in_cache = 0; | 377 | 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 | 378 | ||
424 | if (new) { | 379 | if (new) { |
425 | if (gfs2_assert_warn(sdp, height)) | 380 | BUG_ON(height == 0); |
426 | goto err; | 381 | bh = gfs2_meta_new(gl, num); |
427 | meta_prep_new(bh); | ||
428 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 382 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
429 | gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); | 383 | gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); |
430 | gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); | 384 | gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); |
431 | } else { | 385 | } else { |
432 | u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; | 386 | u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; |
433 | if (!buffer_uptodate(bh)) { | 387 | ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh); |
434 | ll_rw_block(READ_META, 1, &bh); | 388 | if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { |
435 | if (gfs2_meta_wait(sdp, bh)) | 389 | brelse(bh); |
436 | goto err; | 390 | ret = -EIO; |
437 | } | 391 | } |
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 | } | 392 | } |
450 | |||
451 | *bhp = bh; | 393 | *bhp = bh; |
452 | return 0; | 394 | return ret; |
453 | err: | ||
454 | brelse(bh); | ||
455 | return -EIO; | ||
456 | } | 395 | } |
457 | 396 | ||
458 | /** | 397 | /** |
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h index b7048222ebb4..73e3b1c76fe1 100644 --- a/fs/gfs2/meta_io.h +++ b/fs/gfs2/meta_io.h | |||
@@ -56,7 +56,6 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, | |||
56 | 56 | ||
57 | void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen); | 57 | void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen); |
58 | 58 | ||
59 | void gfs2_meta_cache_flush(struct gfs2_inode *ip); | ||
60 | int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | 59 | int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, |
61 | int new, struct buffer_head **bhp); | 60 | int new, struct buffer_head **bhp); |
62 | 61 | ||
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 1696e5d9d112..4c4ef7f59909 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -154,7 +154,6 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc) | |||
154 | error = block_write_full_page(page, gfs2_get_block_noalloc, wbc); | 154 | error = block_write_full_page(page, gfs2_get_block_noalloc, wbc); |
155 | if (done_trans) | 155 | if (done_trans) |
156 | gfs2_trans_end(sdp); | 156 | gfs2_trans_end(sdp); |
157 | gfs2_meta_cache_flush(ip); | ||
158 | return error; | 157 | return error; |
159 | 158 | ||
160 | out_ignore: | 159 | out_ignore: |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index dd3e737f528e..5183dfb9342a 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -543,7 +543,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
543 | if (error) | 543 | if (error) |
544 | return error; | 544 | return error; |
545 | 545 | ||
546 | gfs2_meta_cache_flush(ip); | ||
547 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); | 546 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
548 | 547 | ||
549 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 548 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |