aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r--fs/gfs2/inode.c71
1 files changed, 12 insertions, 59 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 352f958769e1..bb30f9a72c65 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -37,61 +37,9 @@
37#include "super.h" 37#include "super.h"
38#include "glops.h" 38#include "glops.h"
39 39
40struct gfs2_skip_data { 40struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr)
41 u64 no_addr;
42 int skipped;
43 int non_block;
44};
45
46static int iget_test(struct inode *inode, void *opaque)
47{
48 struct gfs2_inode *ip = GFS2_I(inode);
49 struct gfs2_skip_data *data = opaque;
50
51 if (ip->i_no_addr == data->no_addr) {
52 if (data->non_block &&
53 inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
54 data->skipped = 1;
55 return 0;
56 }
57 return 1;
58 }
59 return 0;
60}
61
62static int iget_set(struct inode *inode, void *opaque)
63{
64 struct gfs2_inode *ip = GFS2_I(inode);
65 struct gfs2_skip_data *data = opaque;
66
67 if (data->skipped)
68 return -ENOENT;
69 inode->i_ino = (unsigned long)(data->no_addr);
70 ip->i_no_addr = data->no_addr;
71 return 0;
72}
73
74struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr, int non_block)
75{ 41{
76 unsigned long hash = (unsigned long)no_addr; 42 return ilookup(sb, (unsigned long)no_addr);
77 struct gfs2_skip_data data;
78
79 data.no_addr = no_addr;
80 data.skipped = 0;
81 data.non_block = non_block;
82 return ilookup5(sb, hash, iget_test, &data);
83}
84
85static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr,
86 int non_block)
87{
88 struct gfs2_skip_data data;
89 unsigned long hash = (unsigned long)no_addr;
90
91 data.no_addr = no_addr;
92 data.skipped = 0;
93 data.non_block = non_block;
94 return iget5_locked(sb, hash, iget_test, iget_set, &data);
95} 43}
96 44
97/** 45/**
@@ -132,21 +80,21 @@ static void gfs2_set_iop(struct inode *inode)
132 * @sb: The super block 80 * @sb: The super block
133 * @no_addr: The inode number 81 * @no_addr: The inode number
134 * @type: The type of the inode 82 * @type: The type of the inode
135 * non_block: Can we block on inodes that are being freed?
136 * 83 *
137 * Returns: A VFS inode, or an error 84 * Returns: A VFS inode, or an error
138 */ 85 */
139 86
140struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, 87struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
141 u64 no_addr, u64 no_formal_ino, int non_block) 88 u64 no_addr, u64 no_formal_ino)
142{ 89{
143 struct inode *inode; 90 struct inode *inode;
144 struct gfs2_inode *ip; 91 struct gfs2_inode *ip;
145 struct gfs2_glock *io_gl = NULL; 92 struct gfs2_glock *io_gl = NULL;
146 int error; 93 int error;
147 94
148 inode = gfs2_iget(sb, no_addr, non_block); 95 inode = iget_locked(sb, (unsigned long)no_addr);
149 ip = GFS2_I(inode); 96 ip = GFS2_I(inode);
97 ip->i_no_addr = no_addr;
150 98
151 if (!inode) 99 if (!inode)
152 return ERR_PTR(-ENOMEM); 100 return ERR_PTR(-ENOMEM);
@@ -221,7 +169,7 @@ struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
221 if (error) 169 if (error)
222 goto fail; 170 goto fail;
223 171
224 inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0, 1); 172 inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0);
225 if (IS_ERR(inode)) 173 if (IS_ERR(inode))
226 goto fail; 174 goto fail;
227 175
@@ -592,7 +540,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
592 struct inode *inode = NULL; 540 struct inode *inode = NULL;
593 struct gfs2_inode *dip = GFS2_I(dir), *ip; 541 struct gfs2_inode *dip = GFS2_I(dir), *ip;
594 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 542 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
595 struct gfs2_glock *io_gl; 543 struct gfs2_glock *io_gl = NULL;
596 int error, free_vfs_inode = 1; 544 int error, free_vfs_inode = 1;
597 u32 aflags = 0; 545 u32 aflags = 0;
598 unsigned blocks = 1; 546 unsigned blocks = 1;
@@ -729,6 +677,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
729 if (error) 677 if (error)
730 goto fail_gunlock2; 678 goto fail_gunlock2;
731 679
680 BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags));
681
732 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); 682 error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
733 if (error) 683 if (error)
734 goto fail_gunlock2; 684 goto fail_gunlock2;
@@ -771,12 +721,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
771 } 721 }
772 gfs2_glock_dq_uninit(ghs); 722 gfs2_glock_dq_uninit(ghs);
773 gfs2_glock_dq_uninit(ghs + 1); 723 gfs2_glock_dq_uninit(ghs + 1);
724 clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
774 return error; 725 return error;
775 726
776fail_gunlock3: 727fail_gunlock3:
777 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 728 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
778 gfs2_glock_put(io_gl); 729 gfs2_glock_put(io_gl);
779fail_gunlock2: 730fail_gunlock2:
731 if (io_gl)
732 clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
780 gfs2_glock_dq_uninit(ghs + 1); 733 gfs2_glock_dq_uninit(ghs + 1);
781fail_free_inode: 734fail_free_inode:
782 if (ip->i_gl) 735 if (ip->i_gl)