@@ -952,16 +952,14 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
952
952
* The inode, if one has been found, in inode.
953
953
*/
954
954
955
- static int try_rgrp_unlink (struct gfs2_rgrpd * rgd , u64 * last_unlinked ,
956
- u64 skip , struct inode * * inode )
955
+ static u64 try_rgrp_unlink (struct gfs2_rgrpd * rgd , u64 * last_unlinked ,
956
+ u64 skip )
957
957
{
958
958
u32 goal = 0 , block ;
959
959
u64 no_addr ;
960
960
struct gfs2_sbd * sdp = rgd -> rd_sbd ;
961
961
unsigned int n ;
962
- int error = 0 ;
963
962
964
- * inode = NULL ;
965
963
for (;;) {
966
964
if (goal >= rgd -> rd_data )
967
965
break ;
@@ -981,10 +979,7 @@ static int try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
981
979
if (no_addr == skip )
982
980
continue ;
983
981
* last_unlinked = no_addr ;
984
- error = gfs2_unlinked_inode_lookup (rgd -> rd_sbd -> sd_vfs ,
985
- no_addr , inode );
986
- if (* inode || error )
987
- return error ;
982
+ return no_addr ;
988
983
}
989
984
990
985
rgd -> rd_flags &= ~GFS2_RDF_CHECK ;
@@ -1069,11 +1064,12 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd)
1069
1064
* Try to acquire rgrp in way which avoids contending with others.
1070
1065
*
1071
1066
* Returns: errno
1067
+ * unlinked: the block address of an unlinked block to be reclaimed
1072
1068
*/
1073
1069
1074
- static struct inode * get_local_rgrp (struct gfs2_inode * ip , u64 * last_unlinked )
1070
+ static int get_local_rgrp (struct gfs2_inode * ip , u64 * unlinked ,
1071
+ u64 * last_unlinked )
1075
1072
{
1076
- struct inode * inode = NULL ;
1077
1073
struct gfs2_sbd * sdp = GFS2_SB (& ip -> i_inode );
1078
1074
struct gfs2_rgrpd * rgd , * begin = NULL ;
1079
1075
struct gfs2_alloc * al = ip -> i_alloc ;
@@ -1082,6 +1078,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1082
1078
int loops = 0 ;
1083
1079
int error , rg_locked ;
1084
1080
1081
+ * unlinked = 0 ;
1085
1082
rgd = gfs2_blk2rgrpd (sdp , ip -> i_goal );
1086
1083
1087
1084
while (rgd ) {
@@ -1103,29 +1100,19 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1103
1100
because that would require an iput which can only
1104
1101
happen after the rgrp is unlocked. */
1105
1102
if (!rg_locked && rgd -> rd_flags & GFS2_RDF_CHECK )
1106
- error = try_rgrp_unlink (rgd , last_unlinked ,
1107
- ip -> i_no_addr , & inode );
1103
+ * unlinked = try_rgrp_unlink (rgd , last_unlinked ,
1104
+ ip -> i_no_addr );
1108
1105
if (!rg_locked )
1109
1106
gfs2_glock_dq_uninit (& al -> al_rgd_gh );
1110
- if (inode ) {
1111
- if (error ) {
1112
- if (inode -> i_state & I_NEW )
1113
- iget_failed (inode );
1114
- else
1115
- iput (inode );
1116
- return ERR_PTR (error );
1117
- }
1118
- return inode ;
1119
- }
1120
- if (error )
1121
- return ERR_PTR (error );
1107
+ if (* unlinked )
1108
+ return - EAGAIN ;
1122
1109
/* fall through */
1123
1110
case GLR_TRYFAILED :
1124
1111
rgd = recent_rgrp_next (rgd );
1125
1112
break ;
1126
1113
1127
1114
default :
1128
- return ERR_PTR ( error ) ;
1115
+ return error ;
1129
1116
}
1130
1117
}
1131
1118
@@ -1148,30 +1135,20 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1148
1135
if (try_rgrp_fit (rgd , al ))
1149
1136
goto out ;
1150
1137
if (!rg_locked && rgd -> rd_flags & GFS2_RDF_CHECK )
1151
- error = try_rgrp_unlink (rgd , last_unlinked ,
1152
- ip -> i_no_addr , & inode );
1138
+ * unlinked = try_rgrp_unlink (rgd , last_unlinked ,
1139
+ ip -> i_no_addr );
1153
1140
if (!rg_locked )
1154
1141
gfs2_glock_dq_uninit (& al -> al_rgd_gh );
1155
- if (inode ) {
1156
- if (error ) {
1157
- if (inode -> i_state & I_NEW )
1158
- iget_failed (inode );
1159
- else
1160
- iput (inode );
1161
- return ERR_PTR (error );
1162
- }
1163
- return inode ;
1164
- }
1165
- if (error )
1166
- return ERR_PTR (error );
1142
+ if (* unlinked )
1143
+ return - EAGAIN ;
1167
1144
break ;
1168
1145
1169
1146
case GLR_TRYFAILED :
1170
1147
skipped ++ ;
1171
1148
break ;
1172
1149
1173
1150
default :
1174
- return ERR_PTR ( error ) ;
1151
+ return error ;
1175
1152
}
1176
1153
1177
1154
rgd = gfs2_rgrpd_get_next (rgd );
@@ -1180,7 +1157,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1180
1157
1181
1158
if (rgd == begin ) {
1182
1159
if (++ loops >= 3 )
1183
- return ERR_PTR ( - ENOSPC ) ;
1160
+ return - ENOSPC ;
1184
1161
if (!skipped )
1185
1162
loops ++ ;
1186
1163
flags = 0 ;
@@ -1200,7 +1177,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1200
1177
forward_rgrp_set (sdp , rgd );
1201
1178
}
1202
1179
1203
- return NULL ;
1180
+ return 0 ;
1204
1181
}
1205
1182
1206
1183
/**
@@ -1216,7 +1193,7 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
1216
1193
struct gfs2_alloc * al = ip -> i_alloc ;
1217
1194
struct inode * inode ;
1218
1195
int error = 0 ;
1219
- u64 last_unlinked = NO_BLOCK ;
1196
+ u64 last_unlinked = NO_BLOCK , unlinked ;
1220
1197
1221
1198
if (gfs2_assert_warn (sdp , al -> al_requested ))
1222
1199
return - EINVAL ;
@@ -1232,14 +1209,19 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
1232
1209
if (error )
1233
1210
return error ;
1234
1211
1235
- inode = get_local_rgrp (ip , & last_unlinked );
1236
- if (inode ) {
1212
+ error = get_local_rgrp (ip , & unlinked , & last_unlinked );
1213
+ if (error ) {
1237
1214
if (ip != GFS2_I (sdp -> sd_rindex ))
1238
1215
gfs2_glock_dq_uninit (& al -> al_ri_gh );
1239
- if (IS_ERR (inode ))
1240
- return PTR_ERR (inode );
1241
- iput (inode );
1216
+ if (error != - EAGAIN )
1217
+ return error ;
1218
+ error = gfs2_unlinked_inode_lookup (ip -> i_inode .i_sb ,
1219
+ unlinked , & inode );
1220
+ if (inode )
1221
+ iput (inode );
1242
1222
gfs2_log_flush (sdp , NULL );
1223
+ if (error == GLR_TRYFAILED )
1224
+ error = 0 ;
1243
1225
goto try_again ;
1244
1226
}
1245
1227
0 commit comments