aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2011-08-31 11:38:29 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2011-10-21 07:39:33 -0400
commit8339ee543ece6e2dcc1bbd97d5350163c198cf00 (patch)
tree80b3d4b990a8ab5f8b7c28945f694b01301c05c6
parent7c9ca621137cde26be05448133fc1a554345f4f8 (diff)
GFS2: Make resource groups "append only" during life of fs
Since we have ruled out supporting online filesystem shrink, it is possible to make the resource group list append only during the life of a super block. This gives several benefits: Firstly, we only need to read new rindex elements as they are added rather than needing to reread the whole rindex file each time one element is added. Secondly, the rindex glock can be held for much shorter periods of time, and is completely removed from the fast path for allocations. The lock is taken in shared mode only when updating the resource groups when the first allocation occurs, and after a grow has taken place. Thirdly, this results in a reduction in code size, and everything gets a lot simpler to understand in this area. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/bmap.c7
-rw-r--r--fs/gfs2/dir.c6
-rw-r--r--fs/gfs2/glops.c16
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/inode.c15
-rw-r--r--fs/gfs2/rgrp.c168
-rw-r--r--fs/gfs2/rgrp.h17
-rw-r--r--fs/gfs2/super.c22
-rw-r--r--fs/gfs2/xattr.c17
9 files changed, 95 insertions, 174 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 7878c473ae62..e60296137707 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -783,11 +783,6 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
783 else if (ip->i_depth) 783 else if (ip->i_depth)
784 revokes = sdp->sd_inptrs; 784 revokes = sdp->sd_inptrs;
785 785
786 if (ip != GFS2_I(sdp->sd_rindex))
787 error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh);
788 else if (!sdp->sd_rgrps)
789 error = gfs2_ri_update(ip);
790
791 if (error) 786 if (error)
792 return error; 787 return error;
793 788
@@ -887,8 +882,6 @@ out_rg_gunlock:
887out_rlist: 882out_rlist:
888 gfs2_rlist_free(&rlist); 883 gfs2_rlist_free(&rlist);
889out: 884out:
890 if (ip != GFS2_I(sdp->sd_rindex))
891 gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh);
892 return error; 885 return error;
893} 886}
894 887
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 898e62ed5b85..90b877b464ca 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1807,10 +1807,6 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
1807 if (error) 1807 if (error)
1808 goto out_put; 1808 goto out_put;
1809 1809
1810 error = gfs2_rindex_hold(sdp, &dip->i_alloc->al_ri_gh);
1811 if (error)
1812 goto out_qs;
1813
1814 /* Count the number of leaves */ 1810 /* Count the number of leaves */
1815 bh = leaf_bh; 1811 bh = leaf_bh;
1816 1812
@@ -1889,8 +1885,6 @@ out_rg_gunlock:
1889 gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); 1885 gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
1890out_rlist: 1886out_rlist:
1891 gfs2_rlist_free(&rlist); 1887 gfs2_rlist_free(&rlist);
1892 gfs2_glock_dq_uninit(&dip->i_alloc->al_ri_gh);
1893out_qs:
1894 gfs2_quota_unhold(dip); 1888 gfs2_quota_unhold(dip);
1895out_put: 1889out_put:
1896 gfs2_alloc_put(dip); 1890 gfs2_alloc_put(dip);
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 6f82aac9b0ee..951541b6234c 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -134,8 +134,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl)
134static void rgrp_go_sync(struct gfs2_glock *gl) 134static void rgrp_go_sync(struct gfs2_glock *gl)
135{ 135{
136 struct address_space *metamapping = gfs2_glock2aspace(gl); 136 struct address_space *metamapping = gfs2_glock2aspace(gl);
137 struct gfs2_rgrpd *rgd = gl->gl_object; 137 struct gfs2_rgrpd *rgd;
138 unsigned int x;
139 int error; 138 int error;
140 139
141 if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) 140 if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
@@ -148,14 +147,11 @@ static void rgrp_go_sync(struct gfs2_glock *gl)
148 mapping_set_error(metamapping, error); 147 mapping_set_error(metamapping, error);
149 gfs2_ail_empty_gl(gl); 148 gfs2_ail_empty_gl(gl);
150 149
151 if (!rgd) 150 spin_lock(&gl->gl_spin);
152 return; 151 rgd = gl->gl_object;
153 152 if (rgd)
154 for (x = 0; x < rgd->rd_length; x++) { 153 gfs2_free_clones(rgd);
155 struct gfs2_bitmap *bi = rgd->rd_bits + x; 154 spin_unlock(&gl->gl_spin);
156 kfree(bi->bi_clone);
157 bi->bi_clone = NULL;
158 }
159} 155}
160 156
161/** 157/**
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 9e753fc9e6a5..56847f5903ae 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -255,7 +255,6 @@ struct gfs2_alloc {
255 255
256 unsigned int al_line; 256 unsigned int al_line;
257 char *al_file; 257 char *al_file;
258 struct gfs2_holder al_ri_gh;
259 struct gfs2_holder al_rgd_gh; 258 struct gfs2_holder al_rgd_gh;
260 struct gfs2_rgrpd *al_rgd; 259 struct gfs2_rgrpd *al_rgd;
261 260
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 2af69056a9fd..29703dd97dc9 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1041,13 +1041,8 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
1041 struct buffer_head *bh; 1041 struct buffer_head *bh;
1042 struct gfs2_holder ghs[3]; 1042 struct gfs2_holder ghs[3];
1043 struct gfs2_rgrpd *rgd; 1043 struct gfs2_rgrpd *rgd;
1044 struct gfs2_holder ri_gh;
1045 int error; 1044 int error;
1046 1045
1047 error = gfs2_rindex_hold(sdp, &ri_gh);
1048 if (error)
1049 return error;
1050
1051 gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); 1046 gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
1052 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); 1047 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
1053 1048
@@ -1104,7 +1099,6 @@ out_child:
1104 gfs2_glock_dq(ghs); 1099 gfs2_glock_dq(ghs);
1105out_parent: 1100out_parent:
1106 gfs2_holder_uninit(ghs); 1101 gfs2_holder_uninit(ghs);
1107 gfs2_glock_dq_uninit(&ri_gh);
1108 return error; 1102 return error;
1109} 1103}
1110 1104
@@ -1222,7 +1216,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
1222 struct gfs2_inode *ip = GFS2_I(odentry->d_inode); 1216 struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
1223 struct gfs2_inode *nip = NULL; 1217 struct gfs2_inode *nip = NULL;
1224 struct gfs2_sbd *sdp = GFS2_SB(odir); 1218 struct gfs2_sbd *sdp = GFS2_SB(odir);
1225 struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, }, ri_gh; 1219 struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, };
1226 struct gfs2_rgrpd *nrgd; 1220 struct gfs2_rgrpd *nrgd;
1227 unsigned int num_gh; 1221 unsigned int num_gh;
1228 int dir_rename = 0; 1222 int dir_rename = 0;
@@ -1236,10 +1230,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
1236 return 0; 1230 return 0;
1237 } 1231 }
1238 1232
1239 error = gfs2_rindex_hold(sdp, &ri_gh);
1240 if (error)
1241 return error;
1242
1243 if (odip != ndip) { 1233 if (odip != ndip) {
1244 error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 1234 error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE,
1245 0, &r_gh); 1235 0, &r_gh);
@@ -1376,7 +1366,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
1376 1366
1377 al->al_requested = sdp->sd_max_dirres; 1367 al->al_requested = sdp->sd_max_dirres;
1378 1368
1379 error = gfs2_inplace_reserve_ri(ndip); 1369 error = gfs2_inplace_reserve(ndip);
1380 if (error) 1370 if (error)
1381 goto out_gunlock_q; 1371 goto out_gunlock_q;
1382 1372
@@ -1447,7 +1437,6 @@ out_gunlock_r:
1447 if (r_gh.gh_gl) 1437 if (r_gh.gh_gl)
1448 gfs2_glock_dq_uninit(&r_gh); 1438 gfs2_glock_dq_uninit(&r_gh);
1449out: 1439out:
1450 gfs2_glock_dq_uninit(&ri_gh);
1451 return error; 1440 return error;
1452} 1441}
1453 1442
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 00f6e3d62c22..88d5b75067a8 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -332,14 +332,10 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk)
332 struct rb_node **newn, *parent = NULL; 332 struct rb_node **newn, *parent = NULL;
333 333
334 spin_lock(&sdp->sd_rindex_spin); 334 spin_lock(&sdp->sd_rindex_spin);
335
336 newn = &sdp->sd_rindex_tree.rb_node; 335 newn = &sdp->sd_rindex_tree.rb_node;
337
338 /* Figure out where to put new node */
339 while (*newn) { 336 while (*newn) {
340 struct gfs2_rgrpd *cur = rb_entry(*newn, struct gfs2_rgrpd, 337 struct gfs2_rgrpd *cur = rb_entry(*newn, struct gfs2_rgrpd,
341 rd_node); 338 rd_node);
342
343 parent = *newn; 339 parent = *newn;
344 if (blk < cur->rd_addr) 340 if (blk < cur->rd_addr)
345 newn = &((*newn)->rb_left); 341 newn = &((*newn)->rb_left);
@@ -350,7 +346,6 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk)
350 return cur; 346 return cur;
351 } 347 }
352 } 348 }
353
354 spin_unlock(&sdp->sd_rindex_spin); 349 spin_unlock(&sdp->sd_rindex_spin);
355 350
356 return NULL; 351 return NULL;
@@ -368,8 +363,10 @@ struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp)
368 const struct rb_node *n; 363 const struct rb_node *n;
369 struct gfs2_rgrpd *rgd; 364 struct gfs2_rgrpd *rgd;
370 365
366 spin_lock(&sdp->sd_rindex_spin);
371 n = rb_first(&sdp->sd_rindex_tree); 367 n = rb_first(&sdp->sd_rindex_tree);
372 rgd = rb_entry(n, struct gfs2_rgrpd, rd_node); 368 rgd = rb_entry(n, struct gfs2_rgrpd, rd_node);
369 spin_unlock(&sdp->sd_rindex_spin);
373 370
374 return rgd; 371 return rgd;
375} 372}
@@ -400,7 +397,18 @@ struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd)
400 return rgd; 397 return rgd;
401} 398}
402 399
403static void clear_rgrpdi(struct gfs2_sbd *sdp) 400void gfs2_free_clones(struct gfs2_rgrpd *rgd)
401{
402 int x;
403
404 for (x = 0; x < rgd->rd_length; x++) {
405 struct gfs2_bitmap *bi = rgd->rd_bits + x;
406 kfree(bi->bi_clone);
407 bi->bi_clone = NULL;
408 }
409}
410
411void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
404{ 412{
405 struct rb_node *n; 413 struct rb_node *n;
406 struct gfs2_rgrpd *rgd; 414 struct gfs2_rgrpd *rgd;
@@ -413,23 +421,19 @@ static void clear_rgrpdi(struct gfs2_sbd *sdp)
413 rb_erase(n, &sdp->sd_rindex_tree); 421 rb_erase(n, &sdp->sd_rindex_tree);
414 422
415 if (gl) { 423 if (gl) {
424 spin_lock(&gl->gl_spin);
416 gl->gl_object = NULL; 425 gl->gl_object = NULL;
426 spin_unlock(&gl->gl_spin);
417 gfs2_glock_add_to_lru(gl); 427 gfs2_glock_add_to_lru(gl);
418 gfs2_glock_put(gl); 428 gfs2_glock_put(gl);
419 } 429 }
420 430
431 gfs2_free_clones(rgd);
421 kfree(rgd->rd_bits); 432 kfree(rgd->rd_bits);
422 kmem_cache_free(gfs2_rgrpd_cachep, rgd); 433 kmem_cache_free(gfs2_rgrpd_cachep, rgd);
423 } 434 }
424} 435}
425 436
426void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
427{
428 mutex_lock(&sdp->sd_rindex_mutex);
429 clear_rgrpdi(sdp);
430 mutex_unlock(&sdp->sd_rindex_mutex);
431}
432
433static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd) 437static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd)
434{ 438{
435 printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)rgd->rd_addr); 439 printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)rgd->rd_addr);
@@ -546,17 +550,6 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp)
546 return total_data; 550 return total_data;
547} 551}
548 552
549static void gfs2_rindex_in(struct gfs2_rgrpd *rgd, const void *buf)
550{
551 const struct gfs2_rindex *str = buf;
552
553 rgd->rd_addr = be64_to_cpu(str->ri_addr);
554 rgd->rd_length = be32_to_cpu(str->ri_length);
555 rgd->rd_data0 = be64_to_cpu(str->ri_data0);
556 rgd->rd_data = be32_to_cpu(str->ri_data);
557 rgd->rd_bitbytes = be32_to_cpu(str->ri_bitbytes);
558}
559
560static void rgd_insert(struct gfs2_rgrpd *rgd) 553static void rgd_insert(struct gfs2_rgrpd *rgd)
561{ 554{
562 struct gfs2_sbd *sdp = rgd->rd_sbd; 555 struct gfs2_sbd *sdp = rgd->rd_sbd;
@@ -584,7 +577,7 @@ static void rgd_insert(struct gfs2_rgrpd *rgd)
584 * read_rindex_entry - Pull in a new resource index entry from the disk 577 * read_rindex_entry - Pull in a new resource index entry from the disk
585 * @gl: The glock covering the rindex inode 578 * @gl: The glock covering the rindex inode
586 * 579 *
587 * Returns: 0 on success, error code otherwise 580 * Returns: 0 on success, > 0 on EOF, error code otherwise
588 */ 581 */
589 582
590static int read_rindex_entry(struct gfs2_inode *ip, 583static int read_rindex_entry(struct gfs2_inode *ip,
@@ -592,19 +585,18 @@ static int read_rindex_entry(struct gfs2_inode *ip,
592{ 585{
593 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 586 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
594 loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); 587 loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
595 char buf[sizeof(struct gfs2_rindex)]; 588 struct gfs2_rindex buf;
596 int error; 589 int error;
597 struct gfs2_rgrpd *rgd; 590 struct gfs2_rgrpd *rgd;
598 591
599 error = gfs2_internal_read(ip, ra_state, buf, &pos, 592 if (pos >= i_size_read(&ip->i_inode))
593 return 1;
594
595 error = gfs2_internal_read(ip, ra_state, (char *)&buf, &pos,
600 sizeof(struct gfs2_rindex)); 596 sizeof(struct gfs2_rindex));
601 if (!error) 597
602 return 0; 598 if (error != sizeof(struct gfs2_rindex))
603 if (error != sizeof(struct gfs2_rindex)) { 599 return (error == 0) ? 1 : error;
604 if (error > 0)
605 error = -EIO;
606 return error;
607 }
608 600
609 rgd = kmem_cache_zalloc(gfs2_rgrpd_cachep, GFP_NOFS); 601 rgd = kmem_cache_zalloc(gfs2_rgrpd_cachep, GFP_NOFS);
610 error = -ENOMEM; 602 error = -ENOMEM;
@@ -612,23 +604,34 @@ static int read_rindex_entry(struct gfs2_inode *ip,
612 return error; 604 return error;
613 605
614 rgd->rd_sbd = sdp; 606 rgd->rd_sbd = sdp;
615 607 rgd->rd_addr = be64_to_cpu(buf.ri_addr);
616 gfs2_rindex_in(rgd, buf); 608 rgd->rd_length = be32_to_cpu(buf.ri_length);
617 rgd_insert(rgd); 609 rgd->rd_data0 = be64_to_cpu(buf.ri_data0);
610 rgd->rd_data = be32_to_cpu(buf.ri_data);
611 rgd->rd_bitbytes = be32_to_cpu(buf.ri_bitbytes);
618 612
619 error = compute_bitstructs(rgd); 613 error = compute_bitstructs(rgd);
620 if (error) 614 if (error)
621 return error; 615 goto fail;
622 616
623 error = gfs2_glock_get(sdp, rgd->rd_addr, 617 error = gfs2_glock_get(sdp, rgd->rd_addr,
624 &gfs2_rgrp_glops, CREATE, &rgd->rd_gl); 618 &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
625 if (error) 619 if (error)
626 return error; 620 goto fail;
627 621
628 rgd->rd_gl->gl_object = rgd; 622 rgd->rd_gl->gl_object = rgd;
629 rgd->rd_flags &= ~GFS2_RDF_UPTODATE; 623 rgd->rd_flags &= ~GFS2_RDF_UPTODATE;
630 if (rgd->rd_data > sdp->sd_max_rg_data) 624 if (rgd->rd_data > sdp->sd_max_rg_data)
631 sdp->sd_max_rg_data = rgd->rd_data; 625 sdp->sd_max_rg_data = rgd->rd_data;
626 spin_lock(&sdp->sd_rindex_spin);
627 rgd_insert(rgd);
628 sdp->sd_rgrps++;
629 spin_unlock(&sdp->sd_rindex_spin);
630 return error;
631
632fail:
633 kfree(rgd->rd_bits);
634 kmem_cache_free(gfs2_rgrpd_cachep, rgd);
632 return error; 635 return error;
633} 636}
634 637
@@ -639,34 +642,28 @@ static int read_rindex_entry(struct gfs2_inode *ip,
639 * Returns: 0 on successful update, error code otherwise 642 * Returns: 0 on successful update, error code otherwise
640 */ 643 */
641 644
642int gfs2_ri_update(struct gfs2_inode *ip) 645static int gfs2_ri_update(struct gfs2_inode *ip)
643{ 646{
644 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 647 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
645 struct inode *inode = &ip->i_inode; 648 struct inode *inode = &ip->i_inode;
646 struct file_ra_state ra_state; 649 struct file_ra_state ra_state;
647 u64 rgrp_count = i_size_read(inode);
648 int error; 650 int error;
649 651
650 do_div(rgrp_count, sizeof(struct gfs2_rindex));
651 clear_rgrpdi(sdp);
652
653 file_ra_state_init(&ra_state, inode->i_mapping); 652 file_ra_state_init(&ra_state, inode->i_mapping);
654 for (sdp->sd_rgrps = 0; sdp->sd_rgrps < rgrp_count; sdp->sd_rgrps++) { 653 do {
655 error = read_rindex_entry(ip, &ra_state); 654 error = read_rindex_entry(ip, &ra_state);
656 if (error) { 655 } while (error == 0);
657 clear_rgrpdi(sdp); 656
658 return error; 657 if (error < 0)
659 } 658 return error;
660 }
661 659
662 sdp->sd_rindex_uptodate = 1; 660 sdp->sd_rindex_uptodate = 1;
663 return 0; 661 return 0;
664} 662}
665 663
666/** 664/**
667 * gfs2_rindex_hold - Grab a lock on the rindex 665 * gfs2_rindex_update - Update the rindex if required
668 * @sdp: The GFS2 superblock 666 * @sdp: The GFS2 superblock
669 * @ri_gh: the glock holder
670 * 667 *
671 * We grab a lock on the rindex inode to make sure that it doesn't 668 * We grab a lock on the rindex inode to make sure that it doesn't
672 * change whilst we are performing an operation. We keep this lock 669 * change whilst we are performing an operation. We keep this lock
@@ -678,30 +675,29 @@ int gfs2_ri_update(struct gfs2_inode *ip)
678 * special file, which might have been updated if someone expanded the 675 * special file, which might have been updated if someone expanded the
679 * filesystem (via gfs2_grow utility), which adds new resource groups. 676 * filesystem (via gfs2_grow utility), which adds new resource groups.
680 * 677 *
681 * Returns: 0 on success, error code otherwise 678 * Returns: 0 on succeess, error code otherwise
682 */ 679 */
683 680
684int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh) 681int gfs2_rindex_update(struct gfs2_sbd *sdp)
685{ 682{
686 struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex); 683 struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex);
687 struct gfs2_glock *gl = ip->i_gl; 684 struct gfs2_glock *gl = ip->i_gl;
688 int error; 685 struct gfs2_holder ri_gh;
689 686 int error = 0;
690 error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, ri_gh);
691 if (error)
692 return error;
693 687
694 /* Read new copy from disk if we don't have the latest */ 688 /* Read new copy from disk if we don't have the latest */
695 if (!sdp->sd_rindex_uptodate) { 689 if (!sdp->sd_rindex_uptodate) {
696 mutex_lock(&sdp->sd_rindex_mutex); 690 mutex_lock(&sdp->sd_rindex_mutex);
697 if (!sdp->sd_rindex_uptodate) { 691 error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh);
692 if (error)
693 return error;
694 if (!sdp->sd_rindex_uptodate)
698 error = gfs2_ri_update(ip); 695 error = gfs2_ri_update(ip);
699 if (error) 696 gfs2_glock_dq_uninit(&ri_gh);
700 gfs2_glock_dq_uninit(ri_gh);
701 }
702 mutex_unlock(&sdp->sd_rindex_mutex); 697 mutex_unlock(&sdp->sd_rindex_mutex);
703 } 698 }
704 699
700
705 return error; 701 return error;
706} 702}
707 703
@@ -873,8 +869,13 @@ fail:
873 869
874struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) 870struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip)
875{ 871{
872 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
873 int error;
876 BUG_ON(ip->i_alloc != NULL); 874 BUG_ON(ip->i_alloc != NULL);
877 ip->i_alloc = kzalloc(sizeof(struct gfs2_alloc), GFP_NOFS); 875 ip->i_alloc = kzalloc(sizeof(struct gfs2_alloc), GFP_NOFS);
876 error = gfs2_rindex_update(sdp);
877 if (error)
878 fs_warn(sdp, "rindex update returns %d\n", error);
878 return ip->i_alloc; 879 return ip->i_alloc;
879} 880}
880 881
@@ -1029,7 +1030,7 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1029 * Returns: errno 1030 * Returns: errno
1030 */ 1031 */
1031 1032
1032int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, 1033int gfs2_inplace_reserve_i(struct gfs2_inode *ip,
1033 char *file, unsigned int line) 1034 char *file, unsigned int line)
1034{ 1035{
1035 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1036 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
@@ -1041,18 +1042,6 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex,
1041 if (gfs2_assert_warn(sdp, al->al_requested)) 1042 if (gfs2_assert_warn(sdp, al->al_requested))
1042 return -EINVAL; 1043 return -EINVAL;
1043 1044
1044 if (hold_rindex) {
1045 /* We need to hold the rindex unless the inode we're using is
1046 the rindex itself, in which case it's already held. */
1047 if (ip != GFS2_I(sdp->sd_rindex))
1048 error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
1049 else if (!sdp->sd_rgrps) /* We may not have the rindex read
1050 in, so: */
1051 error = gfs2_ri_update(ip);
1052 if (error)
1053 return error;
1054 }
1055
1056try_again: 1045try_again:
1057 do { 1046 do {
1058 error = get_local_rgrp(ip, &last_unlinked); 1047 error = get_local_rgrp(ip, &last_unlinked);
@@ -1069,11 +1058,8 @@ try_again:
1069 } 1058 }
1070 } while (error && tries++ < 3); 1059 } while (error && tries++ < 3);
1071 1060
1072 if (error) { 1061 if (error)
1073 if (hold_rindex && ip != GFS2_I(sdp->sd_rindex))
1074 gfs2_glock_dq_uninit(&al->al_ri_gh);
1075 return error; 1062 return error;
1076 }
1077 1063
1078 /* no error, so we have the rgrp set in the inode's allocation. */ 1064 /* no error, so we have the rgrp set in the inode's allocation. */
1079 al->al_file = file; 1065 al->al_file = file;
@@ -1103,8 +1089,6 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
1103 al->al_rgd = NULL; 1089 al->al_rgd = NULL;
1104 if (al->al_rgd_gh.gh_gl) 1090 if (al->al_rgd_gh.gh_gl)
1105 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1091 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1106 if (ip != GFS2_I(sdp->sd_rindex) && al->al_ri_gh.gh_gl)
1107 gfs2_glock_dq_uninit(&al->al_ri_gh);
1108} 1092}
1109 1093
1110/** 1094/**
@@ -1558,34 +1542,26 @@ void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
1558int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type) 1542int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type)
1559{ 1543{
1560 struct gfs2_rgrpd *rgd; 1544 struct gfs2_rgrpd *rgd;
1561 struct gfs2_holder ri_gh, rgd_gh; 1545 struct gfs2_holder rgd_gh;
1562 struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex);
1563 int ri_locked = 0;
1564 int error; 1546 int error;
1565 1547
1566 if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { 1548 error = gfs2_rindex_update(sdp);
1567 error = gfs2_rindex_hold(sdp, &ri_gh); 1549 if (error)
1568 if (error) 1550 return error;
1569 goto fail;
1570 ri_locked = 1;
1571 }
1572 1551
1573 error = -EINVAL; 1552 error = -EINVAL;
1574 rgd = gfs2_blk2rgrpd(sdp, no_addr); 1553 rgd = gfs2_blk2rgrpd(sdp, no_addr);
1575 if (!rgd) 1554 if (!rgd)
1576 goto fail_rindex; 1555 goto fail;
1577 1556
1578 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh); 1557 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh);
1579 if (error) 1558 if (error)
1580 goto fail_rindex; 1559 goto fail;
1581 1560
1582 if (gfs2_get_block_type(rgd, no_addr) != type) 1561 if (gfs2_get_block_type(rgd, no_addr) != type)
1583 error = -ESTALE; 1562 error = -ESTALE;
1584 1563
1585 gfs2_glock_dq_uninit(&rgd_gh); 1564 gfs2_glock_dq_uninit(&rgd_gh);
1586fail_rindex:
1587 if (ri_locked)
1588 gfs2_glock_dq_uninit(&ri_gh);
1589fail: 1565fail:
1590 return error; 1566 return error;
1591} 1567}
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index 59b950f43ccf..0439fca18f08 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -18,13 +18,13 @@ struct gfs2_holder;
18 18
19extern void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd); 19extern void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd);
20 20
21struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk); 21extern struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk);
22struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp); 22extern struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp);
23struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd); 23extern struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd);
24 24
25extern void gfs2_clear_rgrpd(struct gfs2_sbd *sdp); 25extern void gfs2_clear_rgrpd(struct gfs2_sbd *sdp);
26extern int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh); 26extern int gfs2_rindex_update(struct gfs2_sbd *sdp);
27 27extern void gfs2_free_clones(struct gfs2_rgrpd *rgd);
28extern int gfs2_rgrp_go_lock(struct gfs2_holder *gh); 28extern int gfs2_rgrp_go_lock(struct gfs2_holder *gh);
29extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh); 29extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh);
30 30
@@ -36,16 +36,13 @@ static inline void gfs2_alloc_put(struct gfs2_inode *ip)
36 ip->i_alloc = NULL; 36 ip->i_alloc = NULL;
37} 37}
38 38
39extern int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, 39extern int gfs2_inplace_reserve_i(struct gfs2_inode *ip,
40 char *file, unsigned int line); 40 char *file, unsigned int line);
41#define gfs2_inplace_reserve(ip) \ 41#define gfs2_inplace_reserve(ip) \
42 gfs2_inplace_reserve_i((ip), 1, __FILE__, __LINE__) 42 gfs2_inplace_reserve_i((ip), __FILE__, __LINE__)
43#define gfs2_inplace_reserve_ri(ip) \
44 gfs2_inplace_reserve_i((ip), 0, __FILE__, __LINE__)
45 43
46extern void gfs2_inplace_release(struct gfs2_inode *ip); 44extern void gfs2_inplace_release(struct gfs2_inode *ip);
47 45
48extern int gfs2_ri_update(struct gfs2_inode *ip);
49extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); 46extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n);
50extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation); 47extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation);
51 48
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index b05fa5954550..f716c4f8b252 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1037,7 +1037,6 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd,
1037 1037
1038static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) 1038static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc)
1039{ 1039{
1040 struct gfs2_holder ri_gh;
1041 struct gfs2_rgrpd *rgd_next; 1040 struct gfs2_rgrpd *rgd_next;
1042 struct gfs2_holder *gha, *gh; 1041 struct gfs2_holder *gha, *gh;
1043 unsigned int slots = 64; 1042 unsigned int slots = 64;
@@ -1050,10 +1049,6 @@ static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host
1050 if (!gha) 1049 if (!gha)
1051 return -ENOMEM; 1050 return -ENOMEM;
1052 1051
1053 error = gfs2_rindex_hold(sdp, &ri_gh);
1054 if (error)
1055 goto out;
1056
1057 rgd_next = gfs2_rgrpd_get_first(sdp); 1052 rgd_next = gfs2_rgrpd_get_first(sdp);
1058 1053
1059 for (;;) { 1054 for (;;) {
@@ -1096,9 +1091,6 @@ static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host
1096 yield(); 1091 yield();
1097 } 1092 }
1098 1093
1099 gfs2_glock_dq_uninit(&ri_gh);
1100
1101out:
1102 kfree(gha); 1094 kfree(gha);
1103 return error; 1095 return error;
1104} 1096}
@@ -1150,6 +1142,10 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
1150 struct gfs2_statfs_change_host sc; 1142 struct gfs2_statfs_change_host sc;
1151 int error; 1143 int error;
1152 1144
1145 error = gfs2_rindex_update(sdp);
1146 if (error)
1147 return error;
1148
1153 if (gfs2_tune_get(sdp, gt_statfs_slow)) 1149 if (gfs2_tune_get(sdp, gt_statfs_slow))
1154 error = gfs2_statfs_slow(sdp, &sc); 1150 error = gfs2_statfs_slow(sdp, &sc);
1155 else 1151 else
@@ -1420,21 +1416,17 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip)
1420 if (error) 1416 if (error)
1421 goto out; 1417 goto out;
1422 1418
1423 error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
1424 if (error)
1425 goto out_qs;
1426
1427 rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); 1419 rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
1428 if (!rgd) { 1420 if (!rgd) {
1429 gfs2_consist_inode(ip); 1421 gfs2_consist_inode(ip);
1430 error = -EIO; 1422 error = -EIO;
1431 goto out_rindex_relse; 1423 goto out_qs;
1432 } 1424 }
1433 1425
1434 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, 1426 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0,
1435 &al->al_rgd_gh); 1427 &al->al_rgd_gh);
1436 if (error) 1428 if (error)
1437 goto out_rindex_relse; 1429 goto out_qs;
1438 1430
1439 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 1431 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA,
1440 sdp->sd_jdesc->jd_blocks); 1432 sdp->sd_jdesc->jd_blocks);
@@ -1449,8 +1441,6 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip)
1449 1441
1450out_rg_gunlock: 1442out_rg_gunlock:
1451 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1443 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1452out_rindex_relse:
1453 gfs2_glock_dq_uninit(&al->al_ri_gh);
1454out_qs: 1444out_qs:
1455 gfs2_quota_unhold(ip); 1445 gfs2_quota_unhold(ip);
1456out: 1446out:
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 695304cf01cc..167f4af53b1d 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -332,15 +332,8 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
332 if (error) 332 if (error)
333 goto out_alloc; 333 goto out_alloc;
334 334
335 error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
336 if (error)
337 goto out_quota;
338
339 error = ea_dealloc_unstuffed(ip, bh, ea, prev, (leave) ? &error : NULL); 335 error = ea_dealloc_unstuffed(ip, bh, ea, prev, (leave) ? &error : NULL);
340 336
341 gfs2_glock_dq_uninit(&al->al_ri_gh);
342
343out_quota:
344 gfs2_quota_unhold(ip); 337 gfs2_quota_unhold(ip);
345out_alloc: 338out_alloc:
346 gfs2_alloc_put(ip); 339 gfs2_alloc_put(ip);
@@ -1502,24 +1495,18 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip)
1502 if (error) 1495 if (error)
1503 goto out_alloc; 1496 goto out_alloc;
1504 1497
1505 error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
1506 if (error)
1507 goto out_quota;
1508
1509 error = ea_foreach(ip, ea_dealloc_unstuffed, NULL); 1498 error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
1510 if (error) 1499 if (error)
1511 goto out_rindex; 1500 goto out_quota;
1512 1501
1513 if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) { 1502 if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
1514 error = ea_dealloc_indirect(ip); 1503 error = ea_dealloc_indirect(ip);
1515 if (error) 1504 if (error)
1516 goto out_rindex; 1505 goto out_quota;
1517 } 1506 }
1518 1507
1519 error = ea_dealloc_block(ip); 1508 error = ea_dealloc_block(ip);
1520 1509
1521out_rindex:
1522 gfs2_glock_dq_uninit(&al->al_ri_gh);
1523out_quota: 1510out_quota:
1524 gfs2_quota_unhold(ip); 1511 gfs2_quota_unhold(ip);
1525out_alloc: 1512out_alloc: