diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2010-05-21 15:27:26 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2010-05-21 15:27:26 -0400 |
commit | ee9a3607fb03e804ddf624544105f4e34260c380 (patch) | |
tree | ce41b6e0fa10982a306f6c142a92dbf3c9961284 /fs/gfs2/rgrp.c | |
parent | b492e95be0ae672922f4734acf3f5d35c30be948 (diff) | |
parent | d515e86e639890b33a09390d062b0831664f04a2 (diff) |
Merge branch 'master' into for-2.6.35
Conflicts:
fs/ext3/fsync.c
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r-- | fs/gfs2/rgrp.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index bf011dc63471..117fa4171f62 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -949,13 +949,13 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) | |||
949 | * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes | 949 | * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes |
950 | * @rgd: The rgrp | 950 | * @rgd: The rgrp |
951 | * | 951 | * |
952 | * Returns: The inode, if one has been found | 952 | * Returns: 0 if no error |
953 | * The inode, if one has been found, in inode. | ||
953 | */ | 954 | */ |
954 | 955 | ||
955 | static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, | 956 | static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, |
956 | u64 skip) | 957 | u64 skip) |
957 | { | 958 | { |
958 | struct inode *inode; | ||
959 | u32 goal = 0, block; | 959 | u32 goal = 0, block; |
960 | u64 no_addr; | 960 | u64 no_addr; |
961 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 961 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
@@ -980,14 +980,11 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, | |||
980 | if (no_addr == skip) | 980 | if (no_addr == skip) |
981 | continue; | 981 | continue; |
982 | *last_unlinked = no_addr; | 982 | *last_unlinked = no_addr; |
983 | inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, | 983 | return no_addr; |
984 | no_addr, -1, 1); | ||
985 | if (!IS_ERR(inode)) | ||
986 | return inode; | ||
987 | } | 984 | } |
988 | 985 | ||
989 | rgd->rd_flags &= ~GFS2_RDF_CHECK; | 986 | rgd->rd_flags &= ~GFS2_RDF_CHECK; |
990 | return NULL; | 987 | return 0; |
991 | } | 988 | } |
992 | 989 | ||
993 | /** | 990 | /** |
@@ -1068,11 +1065,12 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd) | |||
1068 | * Try to acquire rgrp in way which avoids contending with others. | 1065 | * Try to acquire rgrp in way which avoids contending with others. |
1069 | * | 1066 | * |
1070 | * Returns: errno | 1067 | * Returns: errno |
1068 | * unlinked: the block address of an unlinked block to be reclaimed | ||
1071 | */ | 1069 | */ |
1072 | 1070 | ||
1073 | static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | 1071 | static int get_local_rgrp(struct gfs2_inode *ip, u64 *unlinked, |
1072 | u64 *last_unlinked) | ||
1074 | { | 1073 | { |
1075 | struct inode *inode = NULL; | ||
1076 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1074 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1077 | struct gfs2_rgrpd *rgd, *begin = NULL; | 1075 | struct gfs2_rgrpd *rgd, *begin = NULL; |
1078 | struct gfs2_alloc *al = ip->i_alloc; | 1076 | struct gfs2_alloc *al = ip->i_alloc; |
@@ -1081,6 +1079,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1081 | int loops = 0; | 1079 | int loops = 0; |
1082 | int error, rg_locked; | 1080 | int error, rg_locked; |
1083 | 1081 | ||
1082 | *unlinked = 0; | ||
1084 | rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); | 1083 | rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); |
1085 | 1084 | ||
1086 | while (rgd) { | 1085 | while (rgd) { |
@@ -1097,19 +1096,24 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1097 | case 0: | 1096 | case 0: |
1098 | if (try_rgrp_fit(rgd, al)) | 1097 | if (try_rgrp_fit(rgd, al)) |
1099 | goto out; | 1098 | goto out; |
1100 | if (rgd->rd_flags & GFS2_RDF_CHECK) | 1099 | /* If the rg came in already locked, there's no |
1101 | inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | 1100 | way we can recover from a failed try_rgrp_unlink |
1101 | because that would require an iput which can only | ||
1102 | happen after the rgrp is unlocked. */ | ||
1103 | if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) | ||
1104 | *unlinked = try_rgrp_unlink(rgd, last_unlinked, | ||
1105 | ip->i_no_addr); | ||
1102 | if (!rg_locked) | 1106 | if (!rg_locked) |
1103 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1107 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
1104 | if (inode) | 1108 | if (*unlinked) |
1105 | return inode; | 1109 | return -EAGAIN; |
1106 | /* fall through */ | 1110 | /* fall through */ |
1107 | case GLR_TRYFAILED: | 1111 | case GLR_TRYFAILED: |
1108 | rgd = recent_rgrp_next(rgd); | 1112 | rgd = recent_rgrp_next(rgd); |
1109 | break; | 1113 | break; |
1110 | 1114 | ||
1111 | default: | 1115 | default: |
1112 | return ERR_PTR(error); | 1116 | return error; |
1113 | } | 1117 | } |
1114 | } | 1118 | } |
1115 | 1119 | ||
@@ -1131,12 +1135,13 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1131 | case 0: | 1135 | case 0: |
1132 | if (try_rgrp_fit(rgd, al)) | 1136 | if (try_rgrp_fit(rgd, al)) |
1133 | goto out; | 1137 | goto out; |
1134 | if (rgd->rd_flags & GFS2_RDF_CHECK) | 1138 | if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) |
1135 | inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | 1139 | *unlinked = try_rgrp_unlink(rgd, last_unlinked, |
1140 | ip->i_no_addr); | ||
1136 | if (!rg_locked) | 1141 | if (!rg_locked) |
1137 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1142 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
1138 | if (inode) | 1143 | if (*unlinked) |
1139 | return inode; | 1144 | return -EAGAIN; |
1140 | break; | 1145 | break; |
1141 | 1146 | ||
1142 | case GLR_TRYFAILED: | 1147 | case GLR_TRYFAILED: |
@@ -1144,7 +1149,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1144 | break; | 1149 | break; |
1145 | 1150 | ||
1146 | default: | 1151 | default: |
1147 | return ERR_PTR(error); | 1152 | return error; |
1148 | } | 1153 | } |
1149 | 1154 | ||
1150 | rgd = gfs2_rgrpd_get_next(rgd); | 1155 | rgd = gfs2_rgrpd_get_next(rgd); |
@@ -1153,7 +1158,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
1153 | 1158 | ||
1154 | if (rgd == begin) { | 1159 | if (rgd == begin) { |
1155 | if (++loops >= 3) | 1160 | if (++loops >= 3) |
1156 | return ERR_PTR(-ENOSPC); | 1161 | return -ENOSPC; |
1157 | if (!skipped) | 1162 | if (!skipped) |
1158 | loops++; | 1163 | loops++; |
1159 | flags = 0; | 1164 | flags = 0; |
@@ -1173,7 +1178,7 @@ out: | |||
1173 | forward_rgrp_set(sdp, rgd); | 1178 | forward_rgrp_set(sdp, rgd); |
1174 | } | 1179 | } |
1175 | 1180 | ||
1176 | return NULL; | 1181 | return 0; |
1177 | } | 1182 | } |
1178 | 1183 | ||
1179 | /** | 1184 | /** |
@@ -1189,7 +1194,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) | |||
1189 | struct gfs2_alloc *al = ip->i_alloc; | 1194 | struct gfs2_alloc *al = ip->i_alloc; |
1190 | struct inode *inode; | 1195 | struct inode *inode; |
1191 | int error = 0; | 1196 | int error = 0; |
1192 | u64 last_unlinked = NO_BLOCK; | 1197 | u64 last_unlinked = NO_BLOCK, unlinked; |
1193 | 1198 | ||
1194 | if (gfs2_assert_warn(sdp, al->al_requested)) | 1199 | if (gfs2_assert_warn(sdp, al->al_requested)) |
1195 | return -EINVAL; | 1200 | return -EINVAL; |
@@ -1205,14 +1210,19 @@ try_again: | |||
1205 | if (error) | 1210 | if (error) |
1206 | return error; | 1211 | return error; |
1207 | 1212 | ||
1208 | inode = get_local_rgrp(ip, &last_unlinked); | 1213 | error = get_local_rgrp(ip, &unlinked, &last_unlinked); |
1209 | if (inode) { | 1214 | if (error) { |
1210 | if (ip != GFS2_I(sdp->sd_rindex)) | 1215 | if (ip != GFS2_I(sdp->sd_rindex)) |
1211 | gfs2_glock_dq_uninit(&al->al_ri_gh); | 1216 | gfs2_glock_dq_uninit(&al->al_ri_gh); |
1212 | if (IS_ERR(inode)) | 1217 | if (error != -EAGAIN) |
1213 | return PTR_ERR(inode); | 1218 | return error; |
1214 | iput(inode); | 1219 | error = gfs2_unlinked_inode_lookup(ip->i_inode.i_sb, |
1220 | unlinked, &inode); | ||
1221 | if (inode) | ||
1222 | iput(inode); | ||
1215 | gfs2_log_flush(sdp, NULL); | 1223 | gfs2_log_flush(sdp, NULL); |
1224 | if (error == GLR_TRYFAILED) | ||
1225 | error = 0; | ||
1216 | goto try_again; | 1226 | goto try_again; |
1217 | } | 1227 | } |
1218 | 1228 | ||