aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2010-05-21 15:27:26 -0400
committerJens Axboe <jens.axboe@oracle.com>2010-05-21 15:27:26 -0400
commitee9a3607fb03e804ddf624544105f4e34260c380 (patch)
treece41b6e0fa10982a306f6c142a92dbf3c9961284 /fs/gfs2/rgrp.c
parentb492e95be0ae672922f4734acf3f5d35c30be948 (diff)
parentd515e86e639890b33a09390d062b0831664f04a2 (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.c68
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
955static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, 956static 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
1073static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) 1071static 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