diff options
author | Bob Peterson <rpeterso@redhat.com> | 2012-06-13 23:03:56 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2012-06-14 04:58:40 -0400 |
commit | 666d1d8ad201803862514317c17695925e61316b (patch) | |
tree | 3003e301e0b7ef73299204abd64883b4dbc2cb12 /fs/gfs2 | |
parent | 0d515210b6969ecfc161f71a4515831d9a6e58f4 (diff) |
GFS2: Combine functions get_local_rgrp and gfs2_inplace_reserve
This function combines rgrp functions get_local_rgrp and
gfs2_inplace_reserve so that the double retry loop is gone.
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/rgrp.c | 82 |
1 files changed, 29 insertions, 53 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 3c6f7ed16a3b..e53d0a1c234f 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -1207,25 +1207,30 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip | |||
1207 | } | 1207 | } |
1208 | 1208 | ||
1209 | /** | 1209 | /** |
1210 | * get_local_rgrp - Choose and lock a rgrp for allocation | 1210 | * gfs2_inplace_reserve - Reserve space in the filesystem |
1211 | * @ip: the inode to reserve space for | 1211 | * @ip: the inode to reserve space for |
1212 | * @last_unlinked: the last unlinked block | 1212 | * @requested: the number of blocks to be reserved |
1213 | * | ||
1214 | * Try to acquire rgrp in way which avoids contending with others. | ||
1215 | * | 1213 | * |
1216 | * Returns: errno | 1214 | * Returns: errno |
1217 | */ | 1215 | */ |
1218 | 1216 | ||
1219 | static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | 1217 | int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) |
1220 | { | 1218 | { |
1221 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1219 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1222 | struct gfs2_rgrpd *rgd, *begin = NULL; | 1220 | struct gfs2_rgrpd *rgd, *begin = NULL; |
1223 | struct gfs2_blkreserv *rs = ip->i_res; | 1221 | struct gfs2_blkreserv *rs = ip->i_res; |
1224 | int error, rg_locked, flags = LM_FLAG_TRY; | 1222 | int error = 0, rg_locked, flags = LM_FLAG_TRY; |
1223 | u64 last_unlinked = NO_BLOCK; | ||
1225 | int loops = 0; | 1224 | int loops = 0; |
1226 | 1225 | ||
1227 | if (sdp->sd_args.ar_rgrplvb) | 1226 | if (sdp->sd_args.ar_rgrplvb) |
1228 | flags |= GL_SKIP; | 1227 | flags |= GL_SKIP; |
1228 | rs = ip->i_res; | ||
1229 | rs->rs_requested = requested; | ||
1230 | if (gfs2_assert_warn(sdp, requested)) { | ||
1231 | error = -EINVAL; | ||
1232 | goto out; | ||
1233 | } | ||
1229 | 1234 | ||
1230 | if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) | 1235 | if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) |
1231 | rgd = begin = ip->i_rgd; | 1236 | rgd = begin = ip->i_rgd; |
@@ -1263,63 +1268,34 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1263 | if (rgd->rd_flags & GFS2_RDF_CHECK) { | 1268 | if (rgd->rd_flags & GFS2_RDF_CHECK) { |
1264 | if (sdp->sd_args.ar_rgrplvb) | 1269 | if (sdp->sd_args.ar_rgrplvb) |
1265 | gfs2_rgrp_bh_get(rgd); | 1270 | gfs2_rgrp_bh_get(rgd); |
1266 | try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | 1271 | try_rgrp_unlink(rgd, &last_unlinked, |
1272 | ip->i_no_addr); | ||
1267 | } | 1273 | } |
1268 | if (!rg_locked) | 1274 | if (!rg_locked) |
1269 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); | 1275 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); |
1270 | /* fall through */ | 1276 | /* fall through */ |
1271 | case GLR_TRYFAILED: | 1277 | case GLR_TRYFAILED: |
1272 | rgd = gfs2_rgrpd_get_next(rgd); | 1278 | rgd = gfs2_rgrpd_get_next(rgd); |
1273 | if (rgd == begin) { | 1279 | if (rgd != begin) /* If we didn't wrap */ |
1274 | flags &= ~LM_FLAG_TRY; | 1280 | break; |
1275 | loops++; | 1281 | |
1276 | } | 1282 | flags &= ~LM_FLAG_TRY; |
1283 | loops++; | ||
1284 | /* Check that fs hasn't grown if writing to rindex */ | ||
1285 | if (ip == GFS2_I(sdp->sd_rindex) && | ||
1286 | !sdp->sd_rindex_uptodate) { | ||
1287 | error = gfs2_ri_update(ip); | ||
1288 | if (error) | ||
1289 | goto out; | ||
1290 | } else if (loops == 2) | ||
1291 | /* Flushing the log may release space */ | ||
1292 | gfs2_log_flush(sdp, NULL); | ||
1277 | break; | 1293 | break; |
1278 | default: | 1294 | default: |
1279 | return error; | 1295 | goto out; |
1280 | } | 1296 | } |
1281 | } | 1297 | } |
1282 | 1298 | error = -ENOSPC; | |
1283 | return -ENOSPC; | ||
1284 | } | ||
1285 | |||
1286 | /** | ||
1287 | * gfs2_inplace_reserve - Reserve space in the filesystem | ||
1288 | * @ip: the inode to reserve space for | ||
1289 | * @requested: the number of blocks to be reserved | ||
1290 | * | ||
1291 | * Returns: errno | ||
1292 | */ | ||
1293 | |||
1294 | int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) | ||
1295 | { | ||
1296 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1297 | struct gfs2_blkreserv *rs; | ||
1298 | int error = 0; | ||
1299 | u64 last_unlinked = NO_BLOCK; | ||
1300 | int tries = 0; | ||
1301 | |||
1302 | rs = ip->i_res; | ||
1303 | rs->rs_requested = requested; | ||
1304 | if (gfs2_assert_warn(sdp, requested)) { | ||
1305 | error = -EINVAL; | ||
1306 | goto out; | ||
1307 | } | ||
1308 | |||
1309 | do { | ||
1310 | error = get_local_rgrp(ip, &last_unlinked); | ||
1311 | if (error != -ENOSPC) | ||
1312 | break; | ||
1313 | /* Check that fs hasn't grown if writing to rindex */ | ||
1314 | if (ip == GFS2_I(sdp->sd_rindex) && !sdp->sd_rindex_uptodate) { | ||
1315 | error = gfs2_ri_update(ip); | ||
1316 | if (error) | ||
1317 | break; | ||
1318 | continue; | ||
1319 | } | ||
1320 | /* Flushing the log may release space */ | ||
1321 | gfs2_log_flush(sdp, NULL); | ||
1322 | } while (tries++ < 3); | ||
1323 | 1299 | ||
1324 | out: | 1300 | out: |
1325 | if (error) | 1301 | if (error) |