aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 1727f5012efe..e857f405353b 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
4 * 4 *
5 * This copyrighted material is made available to anyone wishing to use, 5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions 6 * modify, copy, or redistribute it subject to the terms and conditions
@@ -431,6 +431,38 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
431} 431}
432 432
433/** 433/**
434 * gfs2_ri_total - Total up the file system space, according to the rindex.
435 *
436 */
437u64 gfs2_ri_total(struct gfs2_sbd *sdp)
438{
439 u64 total_data = 0;
440 struct inode *inode = sdp->sd_rindex;
441 struct gfs2_inode *ip = GFS2_I(inode);
442 struct gfs2_rindex_host ri;
443 char buf[sizeof(struct gfs2_rindex)];
444 struct file_ra_state ra_state;
445 int error, rgrps;
446
447 mutex_lock(&sdp->sd_rindex_mutex);
448 file_ra_state_init(&ra_state, inode->i_mapping);
449 for (rgrps = 0;; rgrps++) {
450 loff_t pos = rgrps * sizeof(struct gfs2_rindex);
451
452 if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size)
453 break;
454 error = gfs2_internal_read(ip, &ra_state, buf, &pos,
455 sizeof(struct gfs2_rindex));
456 if (error != sizeof(struct gfs2_rindex))
457 break;
458 gfs2_rindex_in(&ri, buf);
459 total_data += ri.ri_data;
460 }
461 mutex_unlock(&sdp->sd_rindex_mutex);
462 return total_data;
463}
464
465/**
434 * gfs2_ri_update - Pull in a new resource index from the disk 466 * gfs2_ri_update - Pull in a new resource index from the disk
435 * @gl: The glock covering the rindex inode 467 * @gl: The glock covering the rindex inode
436 * 468 *
@@ -447,7 +479,12 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
447 u64 junk = ip->i_di.di_size; 479 u64 junk = ip->i_di.di_size;
448 int error; 480 int error;
449 481
450 if (do_div(junk, sizeof(struct gfs2_rindex))) { 482 /* If someone is holding the rindex file with a glock, they must
483 be updating it, in which case we may have partial entries.
484 In this case, we ignore the partials. */
485 if (!gfs2_glock_is_held_excl(ip->i_gl) &&
486 !gfs2_glock_is_held_shrd(ip->i_gl) &&
487 do_div(junk, sizeof(struct gfs2_rindex))) {
451 gfs2_consist_inode(ip); 488 gfs2_consist_inode(ip);
452 return -EIO; 489 return -EIO;
453 } 490 }
@@ -457,6 +494,9 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
457 file_ra_state_init(&ra_state, inode->i_mapping); 494 file_ra_state_init(&ra_state, inode->i_mapping);
458 for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { 495 for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) {
459 loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex); 496 loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
497
498 if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size)
499 break;
460 error = gfs2_internal_read(ip, &ra_state, buf, &pos, 500 error = gfs2_internal_read(ip, &ra_state, buf, &pos,
461 sizeof(struct gfs2_rindex)); 501 sizeof(struct gfs2_rindex));
462 if (!error) 502 if (!error)
@@ -978,18 +1018,25 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
978{ 1018{
979 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1019 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
980 struct gfs2_alloc *al = &ip->i_alloc; 1020 struct gfs2_alloc *al = &ip->i_alloc;
981 int error; 1021 int error = 0;
982 1022
983 if (gfs2_assert_warn(sdp, al->al_requested)) 1023 if (gfs2_assert_warn(sdp, al->al_requested))
984 return -EINVAL; 1024 return -EINVAL;
985 1025
986 error = gfs2_rindex_hold(sdp, &al->al_ri_gh); 1026 /* We need to hold the rindex unless the inode we're using is
1027 the rindex itself, in which case it's already held. */
1028 if (ip != GFS2_I(sdp->sd_rindex))
1029 error = gfs2_rindex_hold(sdp, &al->al_ri_gh);
1030 else if (!sdp->sd_rgrps) /* We may not have the rindex read in, so: */
1031 error = gfs2_ri_update(ip);
1032
987 if (error) 1033 if (error)
988 return error; 1034 return error;
989 1035
990 error = get_local_rgrp(ip); 1036 error = get_local_rgrp(ip);
991 if (error) { 1037 if (error) {
992 gfs2_glock_dq_uninit(&al->al_ri_gh); 1038 if (ip != GFS2_I(sdp->sd_rindex))
1039 gfs2_glock_dq_uninit(&al->al_ri_gh);
993 return error; 1040 return error;
994 } 1041 }
995 1042
@@ -1019,7 +1066,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
1019 1066
1020 al->al_rgd = NULL; 1067 al->al_rgd = NULL;
1021 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1068 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1022 gfs2_glock_dq_uninit(&al->al_ri_gh); 1069 if (ip != GFS2_I(sdp->sd_rindex))
1070 gfs2_glock_dq_uninit(&al->al_ri_gh);
1023} 1071}
1024 1072
1025/** 1073/**