aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_inode.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-02-13 07:27:43 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-02-13 07:27:43 -0500
commit7359a19cc758946aba0e45233b8641256b194884 (patch)
treed96aaeb2fb239efe6fdb0b4698eb94108719f423 /fs/gfs2/ops_inode.c
parent18ec7d5c3f434aed9661ed10a9e1f48cdeb4981d (diff)
[GFS2] Fix for root inode ref count bug
Umount is now working correctly again. The bug was due to not getting an extra ref count when mounting the fs. We should have bumped it by two (once for the internal pointer to the root inode from the super block and once for the inode hanging off the dcache entry for root). Also this patch tidys up the code dealing with looking up and creating inodes. We now pass Linux inodes (with gfs2_inodes attached) rather than the other way around and this reduces code duplication in various places. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/ops_inode.c')
-rw-r--r--fs/gfs2/ops_inode.c67
1 files changed, 18 insertions, 49 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 6fff30ef8b70..9fb9490eb67a 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -49,7 +49,7 @@
49static int gfs2_create(struct inode *dir, struct dentry *dentry, 49static int gfs2_create(struct inode *dir, struct dentry *dentry,
50 int mode, struct nameidata *nd) 50 int mode, struct nameidata *nd)
51{ 51{
52 struct gfs2_inode *dip = get_v2ip(dir), *ip; 52 struct gfs2_inode *dip = get_v2ip(dir);
53 struct gfs2_sbd *sdp = dip->i_sbd; 53 struct gfs2_sbd *sdp = dip->i_sbd;
54 struct gfs2_holder ghs[2]; 54 struct gfs2_holder ghs[2];
55 struct inode *inode; 55 struct inode *inode;
@@ -61,9 +61,8 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
61 gfs2_holder_init(dip->i_gl, 0, 0, ghs); 61 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
62 62
63 for (;;) { 63 for (;;) {
64 error = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode); 64 inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode);
65 if (!error) { 65 if (!IS_ERR(inode)) {
66 ip = get_gl2ip(ghs[1].gh_gl);
67 gfs2_trans_end(sdp); 66 gfs2_trans_end(sdp);
68 if (dip->i_alloc.al_rgd) 67 if (dip->i_alloc.al_rgd)
69 gfs2_inplace_release(dip); 68 gfs2_inplace_release(dip);
@@ -71,13 +70,13 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
71 gfs2_alloc_put(dip); 70 gfs2_alloc_put(dip);
72 gfs2_glock_dq_uninit_m(2, ghs); 71 gfs2_glock_dq_uninit_m(2, ghs);
73 break; 72 break;
74 } else if (error != -EEXIST || 73 } else if (PTR_ERR(inode) != -EEXIST ||
75 (nd->intent.open.flags & O_EXCL)) { 74 (nd->intent.open.flags & O_EXCL)) {
76 gfs2_holder_uninit(ghs); 75 gfs2_holder_uninit(ghs);
77 return error; 76 return PTR_ERR(inode);
78 } 77 }
79 78
80 error = gfs2_lookupi(dip, &dentry->d_name, 0, &ip); 79 error = gfs2_lookupi(dir, &dentry->d_name, 0, &inode);
81 if (!error) { 80 if (!error) {
82 new = 0; 81 new = 0;
83 gfs2_holder_uninit(ghs); 82 gfs2_holder_uninit(ghs);
@@ -88,12 +87,6 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
88 } 87 }
89 } 88 }
90 89
91 inode = gfs2_ip2v(ip);
92 gfs2_inode_put(ip);
93
94 if (!inode)
95 return -ENOMEM;
96
97 d_instantiate(dentry, inode); 90 d_instantiate(dentry, inode);
98 if (new) 91 if (new)
99 mark_inode_dirty(inode); 92 mark_inode_dirty(inode);
@@ -115,7 +108,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
115static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, 108static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
116 struct nameidata *nd) 109 struct nameidata *nd)
117{ 110{
118 struct gfs2_inode *dip = get_v2ip(dir), *ip; 111 struct gfs2_inode *dip = get_v2ip(dir);
119 struct gfs2_sbd *sdp = dip->i_sbd; 112 struct gfs2_sbd *sdp = dip->i_sbd;
120 struct inode *inode = NULL; 113 struct inode *inode = NULL;
121 int error; 114 int error;
@@ -125,14 +118,8 @@ static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
125 if (!sdp->sd_args.ar_localcaching) 118 if (!sdp->sd_args.ar_localcaching)
126 dentry->d_op = &gfs2_dops; 119 dentry->d_op = &gfs2_dops;
127 120
128 error = gfs2_lookupi(dip, &dentry->d_name, 0, &ip); 121 error = gfs2_lookupi(dir, &dentry->d_name, 0, &inode);
129 if (!error) { 122 if (error && error != -ENOENT)
130 inode = gfs2_ip2v(ip);
131 gfs2_inode_put(ip);
132 if (!inode)
133 return ERR_PTR(-ENOMEM);
134
135 } else if (error != -ENOENT)
136 return ERR_PTR(error); 123 return ERR_PTR(error);
137 124
138 if (inode) 125 if (inode)
@@ -367,10 +354,10 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
367 354
368 gfs2_holder_init(dip->i_gl, 0, 0, ghs); 355 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
369 356
370 error = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO); 357 inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO);
371 if (error) { 358 if (IS_ERR(inode)) {
372 gfs2_holder_uninit(ghs); 359 gfs2_holder_uninit(ghs);
373 return error; 360 return PTR_ERR(inode);
374 } 361 }
375 362
376 ip = get_gl2ip(ghs[1].gh_gl); 363 ip = get_gl2ip(ghs[1].gh_gl);
@@ -394,12 +381,6 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
394 381
395 gfs2_glock_dq_uninit_m(2, ghs); 382 gfs2_glock_dq_uninit_m(2, ghs);
396 383
397 inode = gfs2_ip2v(ip);
398 gfs2_inode_put(ip);
399
400 if (!inode)
401 return -ENOMEM;
402
403 d_instantiate(dentry, inode); 384 d_instantiate(dentry, inode);
404 mark_inode_dirty(inode); 385 mark_inode_dirty(inode);
405 386
@@ -428,10 +409,10 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
428 409
429 gfs2_holder_init(dip->i_gl, 0, 0, ghs); 410 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
430 411
431 error = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode); 412 inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode);
432 if (error) { 413 if (IS_ERR(inode)) {
433 gfs2_holder_uninit(ghs); 414 gfs2_holder_uninit(ghs);
434 return error; 415 return PTR_ERR(inode);
435 } 416 }
436 417
437 ip = get_gl2ip(ghs[1].gh_gl); 418 ip = get_gl2ip(ghs[1].gh_gl);
@@ -481,12 +462,6 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
481 462
482 gfs2_glock_dq_uninit_m(2, ghs); 463 gfs2_glock_dq_uninit_m(2, ghs);
483 464
484 inode = gfs2_ip2v(ip);
485 gfs2_inode_put(ip);
486
487 if (!inode)
488 return -ENOMEM;
489
490 d_instantiate(dentry, inode); 465 d_instantiate(dentry, inode);
491 mark_inode_dirty(inode); 466 mark_inode_dirty(inode);
492 467
@@ -598,10 +573,10 @@ static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
598 573
599 gfs2_holder_init(dip->i_gl, 0, 0, ghs); 574 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
600 575
601 error = gfs2_createi(ghs, &dentry->d_name, mode); 576 inode = gfs2_createi(ghs, &dentry->d_name, mode);
602 if (error) { 577 if (IS_ERR(inode)) {
603 gfs2_holder_uninit(ghs); 578 gfs2_holder_uninit(ghs);
604 return error; 579 return PTR_ERR(inode);
605 } 580 }
606 581
607 ip = get_gl2ip(ghs[1].gh_gl); 582 ip = get_gl2ip(ghs[1].gh_gl);
@@ -624,12 +599,6 @@ static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
624 599
625 gfs2_glock_dq_uninit_m(2, ghs); 600 gfs2_glock_dq_uninit_m(2, ghs);
626 601
627 inode = gfs2_ip2v(ip);
628 gfs2_inode_put(ip);
629
630 if (!inode)
631 return -ENOMEM;
632
633 d_instantiate(dentry, inode); 602 d_instantiate(dentry, inode);
634 mark_inode_dirty(inode); 603 mark_inode_dirty(inode);
635 604