aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_inode.c
diff options
context:
space:
mode:
authorS. Wendy Cheng <wcheng@redhat.com>2007-01-18 16:07:03 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2007-02-05 13:36:31 -0500
commit87d21e07f3880b8d489f0b4a639deb1362101838 (patch)
tree20b41fc6dad45363b81a9e44daf5b278f532f183 /fs/gfs2/ops_inode.c
parent6c93fd1e578669364e026a0d44c669b871e2a8c4 (diff)
[GFS2] Fix gfs2_rename deadlock
Second round of gfs2_rename lock re-ordering to allow Anaconda adding root partition on top of gfs2. Previous to this patch the recursive lock detector in glock.c can be triggered due to attempting to lock the rgrp twice. This fixes it by checking to see whether the rgrp is already locked. This fixes Red Hat bugzilla #221237 Signed-off-by: S. Wendy Cheng <wcheng@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/ops_inode.c')
-rw-r--r--fs/gfs2/ops_inode.c25
1 files changed, 3 insertions, 22 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 919e8947e710..b2a12f44f59d 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -553,7 +553,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
553 int alloc_required; 553 int alloc_required;
554 unsigned int x; 554 unsigned int x;
555 int error; 555 int error;
556 struct gfs2_rgrpd *rgd;
557 556
558 if (ndentry->d_inode) { 557 if (ndentry->d_inode) {
559 nip = GFS2_I(ndentry->d_inode); 558 nip = GFS2_I(ndentry->d_inode);
@@ -685,12 +684,12 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
685 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + 684 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
686 al->al_rgd->rd_ri.ri_length + 685 al->al_rgd->rd_ri.ri_length +
687 4 * RES_DINODE + 4 * RES_LEAF + 686 4 * RES_DINODE + 4 * RES_LEAF +
688 RES_STATFS + RES_QUOTA + 1, 0); 687 RES_STATFS + RES_QUOTA + 4, 0);
689 if (error) 688 if (error)
690 goto out_ipreserv; 689 goto out_ipreserv;
691 } else { 690 } else {
692 error = gfs2_trans_begin(sdp, 4 * RES_DINODE + 691 error = gfs2_trans_begin(sdp, 4 * RES_DINODE +
693 5 * RES_LEAF + 1, 0); 692 5 * RES_LEAF + 4, 0);
694 if (error) 693 if (error)
695 goto out_gunlock; 694 goto out_gunlock;
696 } 695 }
@@ -704,25 +703,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
704 error = gfs2_dir_del(ndip, &ndentry->d_name); 703 error = gfs2_dir_del(ndip, &ndentry->d_name);
705 if (error) 704 if (error)
706 goto out_end_trans; 705 goto out_end_trans;
707 error = gfs2_change_nlink_i(nip, -1); 706 error = gfs2_change_nlink(nip, -1);
708 if ((!error) && (nip->i_inode.i_nlink == 0)) {
709 error = -EIO;
710 rgd = gfs2_blk2rgrpd(sdp, nip->i_num.no_addr);
711 if (rgd) {
712 struct gfs2_holder nlink_rg_gh;
713 if (rgd != nip->i_alloc.al_rgd)
714 error = gfs2_glock_nq_init(
715 rgd->rd_gl, LM_ST_EXCLUSIVE,
716 0, &nlink_rg_gh);
717 else
718 error = 0;
719 if (!error) {
720 gfs2_unlink_di(&nip->i_inode);
721 if (rgd != nip->i_alloc.al_rgd)
722 gfs2_glock_dq_uninit(&nlink_rg_gh);
723 }
724 }
725 }
726 } 707 }
727 if (error) 708 if (error)
728 goto out_end_trans; 709 goto out_end_trans;