diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2011-08-31 11:38:29 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2011-10-21 07:39:33 -0400 |
commit | 8339ee543ece6e2dcc1bbd97d5350163c198cf00 (patch) | |
tree | 80b3d4b990a8ab5f8b7c28945f694b01301c05c6 | |
parent | 7c9ca621137cde26be05448133fc1a554345f4f8 (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.c | 7 | ||||
-rw-r--r-- | fs/gfs2/dir.c | 6 | ||||
-rw-r--r-- | fs/gfs2/glops.c | 16 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 1 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 15 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 168 | ||||
-rw-r--r-- | fs/gfs2/rgrp.h | 17 | ||||
-rw-r--r-- | fs/gfs2/super.c | 22 | ||||
-rw-r--r-- | fs/gfs2/xattr.c | 17 |
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: | |||
887 | out_rlist: | 882 | out_rlist: |
888 | gfs2_rlist_free(&rlist); | 883 | gfs2_rlist_free(&rlist); |
889 | out: | 884 | out: |
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); |
1890 | out_rlist: | 1886 | out_rlist: |
1891 | gfs2_rlist_free(&rlist); | 1887 | gfs2_rlist_free(&rlist); |
1892 | gfs2_glock_dq_uninit(&dip->i_alloc->al_ri_gh); | ||
1893 | out_qs: | ||
1894 | gfs2_quota_unhold(dip); | 1888 | gfs2_quota_unhold(dip); |
1895 | out_put: | 1889 | out_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) | |||
134 | static void rgrp_go_sync(struct gfs2_glock *gl) | 134 | static 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); |
1105 | out_parent: | 1100 | out_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); |
1449 | out: | 1439 | out: |
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 | ||
403 | static void clear_rgrpdi(struct gfs2_sbd *sdp) | 400 | void 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 | |||
411 | void 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 | ||
426 | void 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 | |||
433 | static void gfs2_rindex_print(const struct gfs2_rgrpd *rgd) | 437 | static 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 | ||
549 | static 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 | |||
560 | static void rgd_insert(struct gfs2_rgrpd *rgd) | 553 | static 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 | ||
590 | static int read_rindex_entry(struct gfs2_inode *ip, | 583 | static 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 | |||
632 | fail: | ||
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 | ||
642 | int gfs2_ri_update(struct gfs2_inode *ip) | 645 | static 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 | ||
684 | int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh) | 681 | int 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 | ||
874 | struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) | 870 | struct 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 | ||
1032 | int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, | 1033 | int 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 | |||
1056 | try_again: | 1045 | try_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) | |||
1558 | int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type) | 1542 | int 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); |
1586 | fail_rindex: | ||
1587 | if (ri_locked) | ||
1588 | gfs2_glock_dq_uninit(&ri_gh); | ||
1589 | fail: | 1565 | fail: |
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 | ||
19 | extern void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd); | 19 | extern void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd); |
20 | 20 | ||
21 | struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk); | 21 | extern struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk); |
22 | struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp); | 22 | extern struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp); |
23 | struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd); | 23 | extern struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd); |
24 | 24 | ||
25 | extern void gfs2_clear_rgrpd(struct gfs2_sbd *sdp); | 25 | extern void gfs2_clear_rgrpd(struct gfs2_sbd *sdp); |
26 | extern int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh); | 26 | extern int gfs2_rindex_update(struct gfs2_sbd *sdp); |
27 | 27 | extern void gfs2_free_clones(struct gfs2_rgrpd *rgd); | |
28 | extern int gfs2_rgrp_go_lock(struct gfs2_holder *gh); | 28 | extern int gfs2_rgrp_go_lock(struct gfs2_holder *gh); |
29 | extern void gfs2_rgrp_go_unlock(struct gfs2_holder *gh); | 29 | extern 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 | ||
39 | extern int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, | 39 | extern 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 | ||
46 | extern void gfs2_inplace_release(struct gfs2_inode *ip); | 44 | extern void gfs2_inplace_release(struct gfs2_inode *ip); |
47 | 45 | ||
48 | extern int gfs2_ri_update(struct gfs2_inode *ip); | ||
49 | extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); | 46 | extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); |
50 | extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation); | 47 | extern 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 | ||
1038 | static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | 1038 | static 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 | |||
1101 | out: | ||
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 | ||
1450 | out_rg_gunlock: | 1442 | out_rg_gunlock: |
1451 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1443 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
1452 | out_rindex_relse: | ||
1453 | gfs2_glock_dq_uninit(&al->al_ri_gh); | ||
1454 | out_qs: | 1444 | out_qs: |
1455 | gfs2_quota_unhold(ip); | 1445 | gfs2_quota_unhold(ip); |
1456 | out: | 1446 | out: |
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 | |||
343 | out_quota: | ||
344 | gfs2_quota_unhold(ip); | 337 | gfs2_quota_unhold(ip); |
345 | out_alloc: | 338 | out_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 | ||
1521 | out_rindex: | ||
1522 | gfs2_glock_dq_uninit(&al->al_ri_gh); | ||
1523 | out_quota: | 1510 | out_quota: |
1524 | gfs2_quota_unhold(ip); | 1511 | gfs2_quota_unhold(ip); |
1525 | out_alloc: | 1512 | out_alloc: |