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.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 565038243fa2..fbacf09ee34e 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -701,10 +701,7 @@ static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf)
701 u32 rg_flags; 701 u32 rg_flags;
702 702
703 rg_flags = be32_to_cpu(str->rg_flags); 703 rg_flags = be32_to_cpu(str->rg_flags);
704 if (rg_flags & GFS2_RGF_NOALLOC) 704 rg_flags &= ~GFS2_RDF_MASK;
705 rgd->rd_flags |= GFS2_RDF_NOALLOC;
706 else
707 rgd->rd_flags &= ~GFS2_RDF_NOALLOC;
708 rgd->rd_free = be32_to_cpu(str->rg_free); 705 rgd->rd_free = be32_to_cpu(str->rg_free);
709 rgd->rd_dinodes = be32_to_cpu(str->rg_dinodes); 706 rgd->rd_dinodes = be32_to_cpu(str->rg_dinodes);
710 rgd->rd_igeneration = be64_to_cpu(str->rg_igeneration); 707 rgd->rd_igeneration = be64_to_cpu(str->rg_igeneration);
@@ -713,11 +710,8 @@ static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf)
713static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) 710static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf)
714{ 711{
715 struct gfs2_rgrp *str = buf; 712 struct gfs2_rgrp *str = buf;
716 u32 rg_flags = 0;
717 713
718 if (rgd->rd_flags & GFS2_RDF_NOALLOC) 714 str->rg_flags = cpu_to_be32(rgd->rd_flags & ~GFS2_RDF_MASK);
719 rg_flags |= GFS2_RGF_NOALLOC;
720 str->rg_flags = cpu_to_be32(rg_flags);
721 str->rg_free = cpu_to_be32(rgd->rd_free); 715 str->rg_free = cpu_to_be32(rgd->rd_free);
722 str->rg_dinodes = cpu_to_be32(rgd->rd_dinodes); 716 str->rg_dinodes = cpu_to_be32(rgd->rd_dinodes);
723 str->__pad = cpu_to_be32(0); 717 str->__pad = cpu_to_be32(0);
@@ -942,7 +936,7 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
942 struct gfs2_sbd *sdp = rgd->rd_sbd; 936 struct gfs2_sbd *sdp = rgd->rd_sbd;
943 int ret = 0; 937 int ret = 0;
944 938
945 if (rgd->rd_flags & GFS2_RDF_NOALLOC) 939 if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR))
946 return 0; 940 return 0;
947 941
948 spin_lock(&sdp->sd_rindex_spin); 942 spin_lock(&sdp->sd_rindex_spin);
@@ -1435,13 +1429,33 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
1435} 1429}
1436 1430
1437/** 1431/**
1438 * gfs2_alloc_block - Allocate a block 1432 * gfs2_rgrp_dump - print out an rgrp
1433 * @seq: The iterator
1434 * @gl: The glock in question
1435 *
1436 */
1437
1438int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl)
1439{
1440 const struct gfs2_rgrpd *rgd = gl->gl_object;
1441 if (rgd == NULL)
1442 return 0;
1443 gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u\n",
1444 (unsigned long long)rgd->rd_addr, rgd->rd_flags,
1445 rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes);
1446 return 0;
1447}
1448
1449/**
1450 * gfs2_alloc_block - Allocate one or more blocks
1439 * @ip: the inode to allocate the block for 1451 * @ip: the inode to allocate the block for
1452 * @bn: Used to return the starting block number
1453 * @n: requested number of blocks/extent length (value/result)
1440 * 1454 *
1441 * Returns: the allocated block 1455 * Returns: 0 or error
1442 */ 1456 */
1443 1457
1444u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n) 1458int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n)
1445{ 1459{
1446 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1460 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1447 struct buffer_head *dibh; 1461 struct buffer_head *dibh;
@@ -1457,7 +1471,10 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n)
1457 goal = rgd->rd_last_alloc; 1471 goal = rgd->rd_last_alloc;
1458 1472
1459 blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED, n); 1473 blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED, n);
1460 BUG_ON(blk == BFITNOENT); 1474
1475 /* Since all blocks are reserved in advance, this shouldn't happen */
1476 if (blk == BFITNOENT)
1477 goto rgrp_error;
1461 1478
1462 rgd->rd_last_alloc = blk; 1479 rgd->rd_last_alloc = blk;
1463 block = rgd->rd_data0 + blk; 1480 block = rgd->rd_data0 + blk;
@@ -1469,7 +1486,9 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n)
1469 di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_goal); 1486 di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_goal);
1470 brelse(dibh); 1487 brelse(dibh);
1471 } 1488 }
1472 gfs2_assert_withdraw(sdp, rgd->rd_free >= *n); 1489 if (rgd->rd_free < *n)
1490 goto rgrp_error;
1491
1473 rgd->rd_free -= *n; 1492 rgd->rd_free -= *n;
1474 1493
1475 gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); 1494 gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1);
@@ -1484,7 +1503,16 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n)
1484 rgd->rd_free_clone -= *n; 1503 rgd->rd_free_clone -= *n;
1485 spin_unlock(&sdp->sd_rindex_spin); 1504 spin_unlock(&sdp->sd_rindex_spin);
1486 1505
1487 return block; 1506 *bn = block;
1507 return 0;
1508
1509rgrp_error:
1510 fs_warn(sdp, "rgrp %llu has an error, marking it readonly until umount\n",
1511 (unsigned long long)rgd->rd_addr);
1512 fs_warn(sdp, "umount on all nodes and run fsck.gfs2 to fix the error\n");
1513 gfs2_rgrp_dump(NULL, rgd->rd_gl);
1514 rgd->rd_flags |= GFS2_RDF_ERROR;
1515 return -EIO;
1488} 1516}
1489 1517
1490/** 1518/**