aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/glops.c21
-rw-r--r--fs/gfs2/incore.h2
-rw-r--r--fs/gfs2/inode.c13
-rw-r--r--fs/gfs2/log.c6
-rw-r--r--fs/gfs2/log.h2
-rw-r--r--fs/gfs2/main.c1
-rw-r--r--fs/gfs2/meta_io.c81
-rw-r--r--fs/gfs2/meta_io.h1
-rw-r--r--fs/gfs2/ops_address.c1
-rw-r--r--fs/gfs2/super.c1
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
297static 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
296static 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:
1031fail_gunlock: 1026fail_gunlock:
1032 gfs2_glock_dq(ghs); 1027 gfs2_glock_dq(ghs);
1033fail: 1028fail:
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
71void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd) 71void 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);
60void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); 60void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl);
61void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); 61void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
62void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd); 62void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
63 63
64void gfs2_log_shutdown(struct gfs2_sbd *sdp); 64void gfs2_log_shutdown(struct gfs2_sbd *sdp);
65void gfs2_meta_syncfs(struct gfs2_sbd *sdp); 65void 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
37static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo) 36static 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
368void 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;
453err:
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
57void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen); 57void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen);
58 58
59void gfs2_meta_cache_flush(struct gfs2_inode *ip);
60int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, 59int 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
160out_ignore: 159out_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);