aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c81
1 files changed, 48 insertions, 33 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 503b842f3ba2..171a744f8e45 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -854,7 +854,8 @@ static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
854 if ((start + nr_sects) != blk) { 854 if ((start + nr_sects) != blk) {
855 rv = blkdev_issue_discard(bdev, start, 855 rv = blkdev_issue_discard(bdev, start,
856 nr_sects, GFP_NOFS, 856 nr_sects, GFP_NOFS,
857 DISCARD_FL_BARRIER); 857 BLKDEV_IFL_WAIT |
858 BLKDEV_IFL_BARRIER);
858 if (rv) 859 if (rv)
859 goto fail; 860 goto fail;
860 nr_sects = 0; 861 nr_sects = 0;
@@ -869,7 +870,7 @@ start_new_extent:
869 } 870 }
870 if (nr_sects) { 871 if (nr_sects) {
871 rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 872 rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS,
872 DISCARD_FL_BARRIER); 873 BLKDEV_IFL_WAIT | BLKDEV_IFL_BARRIER);
873 if (rv) 874 if (rv)
874 goto fail; 875 goto fail;
875 } 876 }
@@ -948,13 +949,13 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
948 * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes 949 * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes
949 * @rgd: The rgrp 950 * @rgd: The rgrp
950 * 951 *
951 * Returns: The inode, if one has been found 952 * Returns: 0 if no error
953 * The inode, if one has been found, in inode.
952 */ 954 */
953 955
954static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, 956static u64 try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
955 u64 skip) 957 u64 skip)
956{ 958{
957 struct inode *inode;
958 u32 goal = 0, block; 959 u32 goal = 0, block;
959 u64 no_addr; 960 u64 no_addr;
960 struct gfs2_sbd *sdp = rgd->rd_sbd; 961 struct gfs2_sbd *sdp = rgd->rd_sbd;
@@ -979,14 +980,11 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
979 if (no_addr == skip) 980 if (no_addr == skip)
980 continue; 981 continue;
981 *last_unlinked = no_addr; 982 *last_unlinked = no_addr;
982 inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, 983 return no_addr;
983 no_addr, -1, 1);
984 if (!IS_ERR(inode))
985 return inode;
986 } 984 }
987 985
988 rgd->rd_flags &= ~GFS2_RDF_CHECK; 986 rgd->rd_flags &= ~GFS2_RDF_CHECK;
989 return NULL; 987 return 0;
990} 988}
991 989
992/** 990/**
@@ -1067,11 +1065,12 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd)
1067 * Try to acquire rgrp in way which avoids contending with others. 1065 * Try to acquire rgrp in way which avoids contending with others.
1068 * 1066 *
1069 * Returns: errno 1067 * Returns: errno
1068 * unlinked: the block address of an unlinked block to be reclaimed
1070 */ 1069 */
1071 1070
1072static 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)
1073{ 1073{
1074 struct inode *inode = NULL;
1075 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1074 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1076 struct gfs2_rgrpd *rgd, *begin = NULL; 1075 struct gfs2_rgrpd *rgd, *begin = NULL;
1077 struct gfs2_alloc *al = ip->i_alloc; 1076 struct gfs2_alloc *al = ip->i_alloc;
@@ -1080,6 +1079,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1080 int loops = 0; 1079 int loops = 0;
1081 int error, rg_locked; 1080 int error, rg_locked;
1082 1081
1082 *unlinked = 0;
1083 rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); 1083 rgd = gfs2_blk2rgrpd(sdp, ip->i_goal);
1084 1084
1085 while (rgd) { 1085 while (rgd) {
@@ -1096,19 +1096,24 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1096 case 0: 1096 case 0:
1097 if (try_rgrp_fit(rgd, al)) 1097 if (try_rgrp_fit(rgd, al))
1098 goto out; 1098 goto out;
1099 if (rgd->rd_flags & GFS2_RDF_CHECK) 1099 /* If the rg came in already locked, there's no
1100 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);
1101 if (!rg_locked) 1106 if (!rg_locked)
1102 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1107 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1103 if (inode) 1108 if (*unlinked)
1104 return inode; 1109 return -EAGAIN;
1105 /* fall through */ 1110 /* fall through */
1106 case GLR_TRYFAILED: 1111 case GLR_TRYFAILED:
1107 rgd = recent_rgrp_next(rgd); 1112 rgd = recent_rgrp_next(rgd);
1108 break; 1113 break;
1109 1114
1110 default: 1115 default:
1111 return ERR_PTR(error); 1116 return error;
1112 } 1117 }
1113 } 1118 }
1114 1119
@@ -1130,12 +1135,13 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1130 case 0: 1135 case 0:
1131 if (try_rgrp_fit(rgd, al)) 1136 if (try_rgrp_fit(rgd, al))
1132 goto out; 1137 goto out;
1133 if (rgd->rd_flags & GFS2_RDF_CHECK) 1138 if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK)
1134 inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); 1139 *unlinked = try_rgrp_unlink(rgd, last_unlinked,
1140 ip->i_no_addr);
1135 if (!rg_locked) 1141 if (!rg_locked)
1136 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1142 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1137 if (inode) 1143 if (*unlinked)
1138 return inode; 1144 return -EAGAIN;
1139 break; 1145 break;
1140 1146
1141 case GLR_TRYFAILED: 1147 case GLR_TRYFAILED:
@@ -1143,7 +1149,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1143 break; 1149 break;
1144 1150
1145 default: 1151 default:
1146 return ERR_PTR(error); 1152 return error;
1147 } 1153 }
1148 1154
1149 rgd = gfs2_rgrpd_get_next(rgd); 1155 rgd = gfs2_rgrpd_get_next(rgd);
@@ -1152,7 +1158,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1152 1158
1153 if (rgd == begin) { 1159 if (rgd == begin) {
1154 if (++loops >= 3) 1160 if (++loops >= 3)
1155 return ERR_PTR(-ENOSPC); 1161 return -ENOSPC;
1156 if (!skipped) 1162 if (!skipped)
1157 loops++; 1163 loops++;
1158 flags = 0; 1164 flags = 0;
@@ -1172,7 +1178,7 @@ out:
1172 forward_rgrp_set(sdp, rgd); 1178 forward_rgrp_set(sdp, rgd);
1173 } 1179 }
1174 1180
1175 return NULL; 1181 return 0;
1176} 1182}
1177 1183
1178/** 1184/**
@@ -1186,9 +1192,8 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
1186{ 1192{
1187 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1193 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1188 struct gfs2_alloc *al = ip->i_alloc; 1194 struct gfs2_alloc *al = ip->i_alloc;
1189 struct inode *inode;
1190 int error = 0; 1195 int error = 0;
1191 u64 last_unlinked = NO_BLOCK; 1196 u64 last_unlinked = NO_BLOCK, unlinked;
1192 1197
1193 if (gfs2_assert_warn(sdp, al->al_requested)) 1198 if (gfs2_assert_warn(sdp, al->al_requested))
1194 return -EINVAL; 1199 return -EINVAL;
@@ -1204,17 +1209,27 @@ try_again:
1204 if (error) 1209 if (error)
1205 return error; 1210 return error;
1206 1211
1207 inode = get_local_rgrp(ip, &last_unlinked); 1212 /* Find an rgrp suitable for allocation. If it encounters any unlinked
1208 if (inode) { 1213 dinodes along the way, error will equal -EAGAIN and unlinked will
1214 contains it block address. We then need to look up that inode and
1215 try to free it, and try the allocation again. */
1216 error = get_local_rgrp(ip, &unlinked, &last_unlinked);
1217 if (error) {
1209 if (ip != GFS2_I(sdp->sd_rindex)) 1218 if (ip != GFS2_I(sdp->sd_rindex))
1210 gfs2_glock_dq_uninit(&al->al_ri_gh); 1219 gfs2_glock_dq_uninit(&al->al_ri_gh);
1211 if (IS_ERR(inode)) 1220 if (error != -EAGAIN)
1212 return PTR_ERR(inode); 1221 return error;
1213 iput(inode); 1222
1223 gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked);
1224 /* regardless of whether or not gfs2_process_unlinked_inode
1225 was successful, we don't want to repeat it again. */
1226 last_unlinked = unlinked;
1214 gfs2_log_flush(sdp, NULL); 1227 gfs2_log_flush(sdp, NULL);
1228 error = 0;
1229
1215 goto try_again; 1230 goto try_again;
1216 } 1231 }
1217 1232 /* no error, so we have the rgrp set in the inode's allocation. */
1218 al->al_file = file; 1233 al->al_file = file;
1219 al->al_line = line; 1234 al->al_line = line;
1220 1235