diff options
-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: |