aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/rgrp.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 09848aac45f6..e0ee195558d3 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1063,22 +1063,30 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1063 int flags = LM_FLAG_TRY; 1063 int flags = LM_FLAG_TRY;
1064 int skipped = 0; 1064 int skipped = 0;
1065 int loops = 0; 1065 int loops = 0;
1066 int error; 1066 int error, rg_locked;
1067 1067
1068 /* Try recently successful rgrps */ 1068 /* Try recently successful rgrps */
1069 1069
1070 rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc); 1070 rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc);
1071 1071
1072 while (rgd) { 1072 while (rgd) {
1073 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 1073 rg_locked = 0;
1074 LM_FLAG_TRY, &al->al_rgd_gh); 1074
1075 if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) {
1076 rg_locked = 1;
1077 error = 0;
1078 } else {
1079 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
1080 LM_FLAG_TRY, &al->al_rgd_gh);
1081 }
1075 switch (error) { 1082 switch (error) {
1076 case 0: 1083 case 0:
1077 if (try_rgrp_fit(rgd, al)) 1084 if (try_rgrp_fit(rgd, al))
1078 goto out; 1085 goto out;
1079 if (rgd->rd_flags & GFS2_RDF_CHECK) 1086 if (rgd->rd_flags & GFS2_RDF_CHECK)
1080 inode = try_rgrp_unlink(rgd, last_unlinked); 1087 inode = try_rgrp_unlink(rgd, last_unlinked);
1081 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1088 if (!rg_locked)
1089 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1082 if (inode) 1090 if (inode)
1083 return inode; 1091 return inode;
1084 rgd = recent_rgrp_next(rgd, 1); 1092 rgd = recent_rgrp_next(rgd, 1);
@@ -1098,15 +1106,23 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1098 begin = rgd = forward_rgrp_get(sdp); 1106 begin = rgd = forward_rgrp_get(sdp);
1099 1107
1100 for (;;) { 1108 for (;;) {
1101 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags, 1109 rg_locked = 0;
1102 &al->al_rgd_gh); 1110
1111 if (gfs2_glock_is_locked_by_me(rgd->rd_gl)) {
1112 rg_locked = 1;
1113 error = 0;
1114 } else {
1115 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, flags,
1116 &al->al_rgd_gh);
1117 }
1103 switch (error) { 1118 switch (error) {
1104 case 0: 1119 case 0:
1105 if (try_rgrp_fit(rgd, al)) 1120 if (try_rgrp_fit(rgd, al))
1106 goto out; 1121 goto out;
1107 if (rgd->rd_flags & GFS2_RDF_CHECK) 1122 if (rgd->rd_flags & GFS2_RDF_CHECK)
1108 inode = try_rgrp_unlink(rgd, last_unlinked); 1123 inode = try_rgrp_unlink(rgd, last_unlinked);
1109 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1124 if (!rg_locked)
1125 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1110 if (inode) 1126 if (inode)
1111 return inode; 1127 return inode;
1112 break; 1128 break;
@@ -1213,7 +1229,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
1213 al->al_line); 1229 al->al_line);
1214 1230
1215 al->al_rgd = NULL; 1231 al->al_rgd = NULL;
1216 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1232 if (al->al_rgd_gh.gh_gl)
1233 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1217 if (ip != GFS2_I(sdp->sd_rindex)) 1234 if (ip != GFS2_I(sdp->sd_rindex))
1218 gfs2_glock_dq_uninit(&al->al_ri_gh); 1235 gfs2_glock_dq_uninit(&al->al_ri_gh);
1219} 1236}