aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/rgrp.c76
1 files changed, 51 insertions, 25 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index f1d19603d237..6b6cc096756a 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -65,8 +65,8 @@ static const char valid_change[16] = {
65}; 65};
66 66
67static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, 67static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
68 unsigned char old_state, bool dinode, 68 unsigned char old_state, bool dinode,
69 unsigned int *ndata); 69 struct gfs2_bitmap **rbi);
70 70
71/** 71/**
72 * gfs2_setbit - Set a bit in the bitmaps 72 * gfs2_setbit - Set a bit in the bitmaps
@@ -899,6 +899,11 @@ static int try_rgrp_fit(const struct gfs2_rgrpd *rgd, const struct gfs2_inode *i
899 return 0; 899 return 0;
900} 900}
901 901
902static inline u32 gfs2_bi2rgd_blk(struct gfs2_bitmap *bi, u32 blk)
903{
904 return (bi->bi_start * GFS2_NBBY) + blk;
905}
906
902/** 907/**
903 * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes 908 * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes
904 * @rgd: The rgrp 909 * @rgd: The rgrp
@@ -912,19 +917,20 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip
912 u32 goal = 0, block; 917 u32 goal = 0, block;
913 u64 no_addr; 918 u64 no_addr;
914 struct gfs2_sbd *sdp = rgd->rd_sbd; 919 struct gfs2_sbd *sdp = rgd->rd_sbd;
915 unsigned int n;
916 struct gfs2_glock *gl; 920 struct gfs2_glock *gl;
917 struct gfs2_inode *ip; 921 struct gfs2_inode *ip;
918 int error; 922 int error;
919 int found = 0; 923 int found = 0;
924 struct gfs2_bitmap *bi;
920 925
921 while (goal < rgd->rd_data) { 926 while (goal < rgd->rd_data) {
922 down_write(&sdp->sd_log_flush_lock); 927 down_write(&sdp->sd_log_flush_lock);
923 n = 1; 928 block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, 0, &bi);
924 block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, 0, &n);
925 up_write(&sdp->sd_log_flush_lock); 929 up_write(&sdp->sd_log_flush_lock);
926 if (block == BFITNOENT) 930 if (block == BFITNOENT)
927 break; 931 break;
932
933 block = gfs2_bi2rgd_blk(bi, block);
928 /* rgblk_search can return a block < goal, so we need to 934 /* rgblk_search can return a block < goal, so we need to
929 keep it marching forward. */ 935 keep it marching forward. */
930 no_addr = block + rgd->rd_data0; 936 no_addr = block + rgd->rd_data0;
@@ -1109,38 +1115,35 @@ static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
1109} 1115}
1110 1116
1111/** 1117/**
1112 * rgblk_search - find a block in @old_state, change allocation 1118 * rgblk_search - find a block in @old_state
1113 * state to @new_state
1114 * @rgd: the resource group descriptor 1119 * @rgd: the resource group descriptor
1115 * @goal: the goal block within the RG (start here to search for avail block) 1120 * @goal: the goal block within the RG (start here to search for avail block)
1116 * @old_state: GFS2_BLKST_XXX the before-allocation state to find 1121 * @old_state: GFS2_BLKST_XXX the before-allocation state to find
1117 * @dinode: TRUE if the first block we allocate is for a dinode 1122 * @dinode: TRUE if the first block we allocate is for a dinode
1118 * @n: The extent length 1123 * @rbi: address of the pointer to the bitmap containing the block found
1119 * 1124 *
1120 * Walk rgrp's bitmap to find bits that represent a block in @old_state. 1125 * Walk rgrp's bitmap to find bits that represent a block in @old_state.
1121 * Add the found bitmap buffer to the transaction.
1122 * Set the found bits to @new_state to change block's allocation state.
1123 * 1126 *
1124 * This function never fails, because we wouldn't call it unless we 1127 * This function never fails, because we wouldn't call it unless we
1125 * know (from reservation results, etc.) that a block is available. 1128 * know (from reservation results, etc.) that a block is available.
1126 * 1129 *
1127 * Scope of @goal and returned block is just within rgrp, not the whole 1130 * Scope of @goal is just within rgrp, not the whole filesystem.
1128 * filesystem. 1131 * Scope of @returned block is just within bitmap, not the whole filesystem.
1129 * 1132 *
1130 * Returns: the block number allocated 1133 * Returns: the block number found relative to the bitmap rbi
1131 */ 1134 */
1132 1135
1133static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, 1136static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
1134 unsigned char old_state, bool dinode, unsigned int *n) 1137 unsigned char old_state, bool dinode,
1138 struct gfs2_bitmap **rbi)
1135{ 1139{
1136 struct gfs2_bitmap *bi = NULL; 1140 struct gfs2_bitmap *bi = NULL;
1137 const u32 length = rgd->rd_length; 1141 const u32 length = rgd->rd_length;
1138 u32 blk = BFITNOENT; 1142 u32 blk = BFITNOENT;
1139 unsigned int buf, x; 1143 unsigned int buf, x;
1140 const unsigned int elen = *n;
1141 const u8 *buffer = NULL; 1144 const u8 *buffer = NULL;
1142 1145
1143 *n = 0; 1146 *rbi = NULL;
1144 /* Find bitmap block that contains bits for goal block */ 1147 /* Find bitmap block that contains bits for goal block */
1145 for (buf = 0; buf < length; buf++) { 1148 for (buf = 0; buf < length; buf++) {
1146 bi = rgd->rd_bits + buf; 1149 bi = rgd->rd_bits + buf;
@@ -1187,12 +1190,32 @@ skip:
1187 goal = 0; 1190 goal = 0;
1188 } 1191 }
1189 1192
1190 if (blk == BFITNOENT) 1193 if (blk != BFITNOENT)
1191 return blk; 1194 *rbi = bi;
1192 1195
1193 if (old_state == GFS2_BLKST_UNLINKED) 1196 return blk;
1194 goto out; 1197}
1195 1198
1199/**
1200 * gfs2_alloc_extent - allocate an extent from a given bitmap
1201 * @rgd: the resource group descriptor
1202 * @bi: the bitmap within the rgrp
1203 * @blk: the block within the bitmap
1204 * @dinode: TRUE if the first block we allocate is for a dinode
1205 * @n: The extent length
1206 *
1207 * Add the found bitmap buffer to the transaction.
1208 * Set the found bits to @new_state to change block's allocation state.
1209 * Returns: starting block number of the extent (fs scope)
1210 */
1211static u64 gfs2_alloc_extent(struct gfs2_rgrpd *rgd, struct gfs2_bitmap *bi,
1212 u32 blk, bool dinode, unsigned int *n)
1213{
1214 const unsigned int elen = *n;
1215 u32 goal;
1216 const u8 *buffer = NULL;
1217
1218 buffer = bi->bi_bh->b_data + bi->bi_offset;
1196 gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); 1219 gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
1197 gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, 1220 gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset,
1198 bi, blk, dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); 1221 bi, blk, dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);
@@ -1210,8 +1233,9 @@ skip:
1210 bi, goal, GFS2_BLKST_USED); 1233 bi, goal, GFS2_BLKST_USED);
1211 (*n)++; 1234 (*n)++;
1212 } 1235 }
1213out: 1236 blk = gfs2_bi2rgd_blk(bi, blk);
1214 return (bi->bi_start * GFS2_NBBY) + blk; 1237 rgd->rd_last_alloc = blk;
1238 return rgd->rd_data0 + blk;
1215} 1239}
1216 1240
1217/** 1241/**
@@ -1319,6 +1343,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *ndata,
1319 u32 goal, extlen, blk; /* block, within the rgrp scope */ 1343 u32 goal, extlen, blk; /* block, within the rgrp scope */
1320 u64 block; /* block, within the file system scope */ 1344 u64 block; /* block, within the file system scope */
1321 int error; 1345 int error;
1346 struct gfs2_bitmap *bi;
1322 1347
1323 /* Only happens if there is a bug in gfs2, return something distinctive 1348 /* Only happens if there is a bug in gfs2, return something distinctive
1324 * to ensure that it is noticed. 1349 * to ensure that it is noticed.
@@ -1333,14 +1358,15 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *ndata,
1333 else 1358 else
1334 goal = rgd->rd_last_alloc; 1359 goal = rgd->rd_last_alloc;
1335 1360
1336 blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, dinode, ndata); 1361 blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, dinode, &bi);
1337 1362
1363 *ndata = 0;
1338 /* Since all blocks are reserved in advance, this shouldn't happen */ 1364 /* Since all blocks are reserved in advance, this shouldn't happen */
1339 if (blk == BFITNOENT) 1365 if (blk == BFITNOENT)
1340 goto rgrp_error; 1366 goto rgrp_error;
1341 1367
1342 rgd->rd_last_alloc = blk; 1368 block = gfs2_alloc_extent(rgd, bi, blk, dinode, ndata);
1343 block = rgd->rd_data0 + blk; 1369
1344 if (!dinode) { 1370 if (!dinode) {
1345 ip->i_goal = block + *ndata - 1; 1371 ip->i_goal = block + *ndata - 1;
1346 error = gfs2_meta_inode_buffer(ip, &dibh); 1372 error = gfs2_meta_inode_buffer(ip, &dibh);