diff options
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r-- | fs/gfs2/rgrp.c | 33 |
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 | } |