diff options
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r-- | fs/gfs2/rgrp.c | 97 |
1 files changed, 48 insertions, 49 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index fb67f593f408..33c8407b876f 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -866,8 +866,7 @@ static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
866 | if ((start + nr_sects) != blk) { | 866 | if ((start + nr_sects) != blk) { |
867 | rv = blkdev_issue_discard(bdev, start, | 867 | rv = blkdev_issue_discard(bdev, start, |
868 | nr_sects, GFP_NOFS, | 868 | nr_sects, GFP_NOFS, |
869 | BLKDEV_IFL_WAIT | | 869 | 0); |
870 | BLKDEV_IFL_BARRIER); | ||
871 | if (rv) | 870 | if (rv) |
872 | goto fail; | 871 | goto fail; |
873 | nr_sects = 0; | 872 | nr_sects = 0; |
@@ -881,8 +880,7 @@ start_new_extent: | |||
881 | } | 880 | } |
882 | } | 881 | } |
883 | if (nr_sects) { | 882 | if (nr_sects) { |
884 | rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, | 883 | rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0); |
885 | BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER); | ||
886 | if (rv) | 884 | if (rv) |
887 | goto fail; | 885 | goto fail; |
888 | } | 886 | } |
@@ -965,17 +963,18 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) | |||
965 | * The inode, if one has been found, in inode. | 963 | * The inode, if one has been found, in inode. |
966 | */ | 964 | */ |
967 | 965 | ||
968 | static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, | 966 | static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip) |
969 | u64 skip) | ||
970 | { | 967 | { |
971 | u32 goal = 0, block; | 968 | u32 goal = 0, block; |
972 | u64 no_addr; | 969 | u64 no_addr; |
973 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 970 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
974 | unsigned int n; | 971 | unsigned int n; |
972 | struct gfs2_glock *gl; | ||
973 | struct gfs2_inode *ip; | ||
974 | int error; | ||
975 | int found = 0; | ||
975 | 976 | ||
976 | for(;;) { | 977 | while (goal < rgd->rd_data) { |
977 | if (goal >= rgd->rd_data) | ||
978 | break; | ||
979 | down_write(&sdp->sd_log_flush_lock); | 978 | down_write(&sdp->sd_log_flush_lock); |
980 | n = 1; | 979 | n = 1; |
981 | block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, | 980 | block = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, |
@@ -992,11 +991,32 @@ static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, | |||
992 | if (no_addr == skip) | 991 | if (no_addr == skip) |
993 | continue; | 992 | continue; |
994 | *last_unlinked = no_addr; | 993 | *last_unlinked = no_addr; |
995 | return no_addr; | 994 | |
995 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &gl); | ||
996 | if (error) | ||
997 | continue; | ||
998 | |||
999 | /* If the inode is already in cache, we can ignore it here | ||
1000 | * because the existing inode disposal code will deal with | ||
1001 | * it when all refs have gone away. Accessing gl_object like | ||
1002 | * this is not safe in general. Here it is ok because we do | ||
1003 | * not dereference the pointer, and we only need an approx | ||
1004 | * answer to whether it is NULL or not. | ||
1005 | */ | ||
1006 | ip = gl->gl_object; | ||
1007 | |||
1008 | if (ip || queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0) | ||
1009 | gfs2_glock_put(gl); | ||
1010 | else | ||
1011 | found++; | ||
1012 | |||
1013 | /* Limit reclaim to sensible number of tasks */ | ||
1014 | if (found > 2*NR_CPUS) | ||
1015 | return; | ||
996 | } | 1016 | } |
997 | 1017 | ||
998 | rgd->rd_flags &= ~GFS2_RDF_CHECK; | 1018 | rgd->rd_flags &= ~GFS2_RDF_CHECK; |
999 | return 0; | 1019 | return; |
1000 | } | 1020 | } |
1001 | 1021 | ||
1002 | /** | 1022 | /** |
@@ -1077,11 +1097,9 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd) | |||
1077 | * Try to acquire rgrp in way which avoids contending with others. | 1097 | * Try to acquire rgrp in way which avoids contending with others. |
1078 | * | 1098 | * |
1079 | * Returns: errno | 1099 | * Returns: errno |
1080 | * unlinked: the block address of an unlinked block to be reclaimed | ||
1081 | */ | 1100 | */ |
1082 | 1101 | ||
1083 | static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, | 1102 | static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) |
1084 | u64 *last_unlinked) | ||
1085 | { | 1103 | { |
1086 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1104 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1087 | struct gfs2_rgrpd *rgd, *begin = NULL; | 1105 | struct gfs2_rgrpd *rgd, *begin = NULL; |
@@ -1091,7 +1109,6 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, | |||
1091 | int loops = 0; | 1109 | int loops = 0; |
1092 | int error, rg_locked; | 1110 | int error, rg_locked; |
1093 | 1111 | ||
1094 | *unlinked = 0; | ||
1095 | rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); | 1112 | rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); |
1096 | 1113 | ||
1097 | while (rgd) { | 1114 | while (rgd) { |
@@ -1108,17 +1125,10 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, | |||
1108 | case 0: | 1125 | case 0: |
1109 | if (try_rgrp_fit(rgd, al)) | 1126 | if (try_rgrp_fit(rgd, al)) |
1110 | goto out; | 1127 | goto out; |
1111 | /* If the rg came in already locked, there's no | 1128 | if (rgd->rd_flags & GFS2_RDF_CHECK) |
1112 | way we can recover from a failed try_rgrp_unlink | 1129 | try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); |
1113 | because that would require an iput which can only | ||
1114 | happen after the rgrp is unlocked. */ | ||
1115 | if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) | ||
1116 | *unlinked = try_rgrp_unlink(rgd, last_unlinked, | ||
1117 | ip->i_no_addr); | ||
1118 | if (!rg_locked) | 1130 | if (!rg_locked) |
1119 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1131 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
1120 | if (*unlinked) | ||
1121 | return -EAGAIN; | ||
1122 | /* fall through */ | 1132 | /* fall through */ |
1123 | case GLR_TRYFAILED: | 1133 | case GLR_TRYFAILED: |
1124 | rgd = recent_rgrp_next(rgd); | 1134 | rgd = recent_rgrp_next(rgd); |
@@ -1147,13 +1157,10 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, | |||
1147 | case 0: | 1157 | case 0: |
1148 | if (try_rgrp_fit(rgd, al)) | 1158 | if (try_rgrp_fit(rgd, al)) |
1149 | goto out; | 1159 | goto out; |
1150 | if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) | 1160 | if (rgd->rd_flags & GFS2_RDF_CHECK) |
1151 | *unlinked = try_rgrp_unlink(rgd, last_unlinked, | 1161 | try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); |
1152 | ip->i_no_addr); | ||
1153 | if (!rg_locked) | 1162 | if (!rg_locked) |
1154 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1163 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
1155 | if (*unlinked) | ||
1156 | return -EAGAIN; | ||
1157 | break; | 1164 | break; |
1158 | 1165 | ||
1159 | case GLR_TRYFAILED: | 1166 | case GLR_TRYFAILED: |
@@ -1206,12 +1213,12 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, | |||
1206 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1213 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1207 | struct gfs2_alloc *al = ip->i_alloc; | 1214 | struct gfs2_alloc *al = ip->i_alloc; |
1208 | int error = 0; | 1215 | int error = 0; |
1209 | u64 last_unlinked = NO_BLOCK, unlinked; | 1216 | u64 last_unlinked = NO_BLOCK; |
1217 | int tries = 0; | ||
1210 | 1218 | ||
1211 | if (gfs2_assert_warn(sdp, al->al_requested)) | 1219 | if (gfs2_assert_warn(sdp, al->al_requested)) |
1212 | return -EINVAL; | 1220 | return -EINVAL; |
1213 | 1221 | ||
1214 | try_again: | ||
1215 | if (hold_rindex) { | 1222 | if (hold_rindex) { |
1216 | /* We need to hold the rindex unless the inode we're using is | 1223 | /* We need to hold the rindex unless the inode we're using is |
1217 | the rindex itself, in which case it's already held. */ | 1224 | the rindex itself, in which case it's already held. */ |
@@ -1220,31 +1227,23 @@ try_again: | |||
1220 | else if (!sdp->sd_rgrps) /* We may not have the rindex read | 1227 | else if (!sdp->sd_rgrps) /* We may not have the rindex read |
1221 | in, so: */ | 1228 | in, so: */ |
1222 | error = gfs2_ri_update_special(ip); | 1229 | error = gfs2_ri_update_special(ip); |
1230 | if (error) | ||
1231 | return error; | ||
1223 | } | 1232 | } |
1224 | 1233 | ||
1225 | if (error) | 1234 | do { |
1226 | return error; | 1235 | error = get_local_rgrp(ip, &last_unlinked); |
1236 | /* If there is no space, flushing the log may release some */ | ||
1237 | if (error) | ||
1238 | gfs2_log_flush(sdp, NULL); | ||
1239 | } while (error && tries++ < 3); | ||
1227 | 1240 | ||
1228 | /* Find an rgrp suitable for allocation. If it encounters any unlinked | ||
1229 | dinodes along the way, error will equal -EAGAIN and unlinked will | ||
1230 | contains it block address. We then need to look up that inode and | ||
1231 | try to free it, and try the allocation again. */ | ||
1232 | error = get_local_rgrp(ip, &unlinked, &last_unlinked); | ||
1233 | if (error) { | 1241 | if (error) { |
1234 | if (hold_rindex && ip != GFS2_I(sdp->sd_rindex)) | 1242 | if (hold_rindex && ip != GFS2_I(sdp->sd_rindex)) |
1235 | gfs2_glock_dq_uninit(&al->al_ri_gh); | 1243 | gfs2_glock_dq_uninit(&al->al_ri_gh); |
1236 | if (error != -EAGAIN) | 1244 | return error; |
1237 | return error; | ||
1238 | |||
1239 | gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked); | ||
1240 | /* regardless of whether or not gfs2_process_unlinked_inode | ||
1241 | was successful, we don't want to repeat it again. */ | ||
1242 | last_unlinked = unlinked; | ||
1243 | gfs2_log_flush(sdp, NULL); | ||
1244 | error = 0; | ||
1245 | |||
1246 | goto try_again; | ||
1247 | } | 1245 | } |
1246 | |||
1248 | /* no error, so we have the rgrp set in the inode's allocation. */ | 1247 | /* no error, so we have the rgrp set in the inode's allocation. */ |
1249 | al->al_file = file; | 1248 | al->al_file = file; |
1250 | al->al_line = line; | 1249 | al->al_line = line; |