diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2007-08-26 09:23:56 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-10-10 03:55:53 -0400 |
commit | 8497a46e178addb27ad1c981befaa17ca788b5c3 (patch) | |
tree | a2793792fb63da1aa582b66e9ae1f05dbb90c00c /fs/gfs2 | |
parent | e9bd2b3bafd29bf75522546207f0bba0ec4515c2 (diff) |
[GFS2] Correct lock ordering in unlink
This patch corrects the lock ordering in unlink to be the same as
that in the rest of GFS2, i.e. parent -> child -> rgrp.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/ops_inode.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 5b8b994b9912..2cbe5a321e89 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -278,17 +278,25 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) | |||
278 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | 278 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); |
279 | 279 | ||
280 | 280 | ||
281 | error = gfs2_glock_nq_m(3, ghs); | 281 | error = gfs2_glock_nq(ghs); /* parent */ |
282 | if (error) | 282 | if (error) |
283 | goto out; | 283 | goto out_parent; |
284 | |||
285 | error = gfs2_glock_nq(ghs + 1); /* child */ | ||
286 | if (error) | ||
287 | goto out_child; | ||
288 | |||
289 | error = gfs2_glock_nq(ghs + 2); /* rgrp */ | ||
290 | if (error) | ||
291 | goto out_rgrp; | ||
284 | 292 | ||
285 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); | 293 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); |
286 | if (error) | 294 | if (error) |
287 | goto out_gunlock; | 295 | goto out_rgrp; |
288 | 296 | ||
289 | error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0); | 297 | error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0); |
290 | if (error) | 298 | if (error) |
291 | goto out_gunlock; | 299 | goto out_rgrp; |
292 | 300 | ||
293 | error = gfs2_dir_del(dip, &dentry->d_name); | 301 | error = gfs2_dir_del(dip, &dentry->d_name); |
294 | if (error) | 302 | if (error) |
@@ -298,12 +306,15 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) | |||
298 | 306 | ||
299 | out_end_trans: | 307 | out_end_trans: |
300 | gfs2_trans_end(sdp); | 308 | gfs2_trans_end(sdp); |
301 | out_gunlock: | 309 | gfs2_glock_dq(ghs + 2); |
302 | gfs2_glock_dq_m(3, ghs); | 310 | out_rgrp: |
303 | out: | ||
304 | gfs2_holder_uninit(ghs); | ||
305 | gfs2_holder_uninit(ghs + 1); | ||
306 | gfs2_holder_uninit(ghs + 2); | 311 | gfs2_holder_uninit(ghs + 2); |
312 | gfs2_glock_dq(ghs + 1); | ||
313 | out_child: | ||
314 | gfs2_holder_uninit(ghs + 1); | ||
315 | gfs2_glock_dq(ghs); | ||
316 | out_parent: | ||
317 | gfs2_holder_uninit(ghs); | ||
307 | gfs2_glock_dq_uninit(&ri_gh); | 318 | gfs2_glock_dq_uninit(&ri_gh); |
308 | return error; | 319 | return error; |
309 | } | 320 | } |