diff options
author | David S. Miller <davem@davemloft.net> | 2011-01-24 16:17:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-24 16:17:06 -0500 |
commit | e92427b289d252cfbd4cb5282d92f4ce1a5bb1fb (patch) | |
tree | 6d30e5e7b7f8e9aaa51d43b7128ac56860fa03bb /fs/gfs2/inode.c | |
parent | c506653d35249bb4738bb139c24362e1ae724bc1 (diff) | |
parent | ec30f343d61391ab23705e50a525da1d55395780 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 72 |
1 files changed, 22 insertions, 50 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 2232b3c780bd..7aa7d4f8984a 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -74,16 +74,14 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) | |||
74 | } | 74 | } |
75 | 75 | ||
76 | /** | 76 | /** |
77 | * GFS2 lookup code fills in vfs inode contents based on info obtained | 77 | * gfs2_set_iop - Sets inode operations |
78 | * from directory entry inside gfs2_inode_lookup(). This has caused issues | 78 | * @inode: The inode with correct i_mode filled in |
79 | * with NFS code path since its get_dentry routine doesn't have the relevant | ||
80 | * directory entry when gfs2_inode_lookup() is invoked. Part of the code | ||
81 | * segment inside gfs2_inode_lookup code needs to get moved around. | ||
82 | * | 79 | * |
83 | * Clears I_NEW as well. | 80 | * GFS2 lookup code fills in vfs inode contents based on info obtained |
84 | **/ | 81 | * from directory entry inside gfs2_inode_lookup(). |
82 | */ | ||
85 | 83 | ||
86 | void gfs2_set_iop(struct inode *inode) | 84 | static void gfs2_set_iop(struct inode *inode) |
87 | { | 85 | { |
88 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 86 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
89 | umode_t mode = inode->i_mode; | 87 | umode_t mode = inode->i_mode; |
@@ -106,8 +104,6 @@ void gfs2_set_iop(struct inode *inode) | |||
106 | inode->i_op = &gfs2_file_iops; | 104 | inode->i_op = &gfs2_file_iops; |
107 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | 105 | init_special_inode(inode, inode->i_mode, inode->i_rdev); |
108 | } | 106 | } |
109 | |||
110 | unlock_new_inode(inode); | ||
111 | } | 107 | } |
112 | 108 | ||
113 | /** | 109 | /** |
@@ -119,10 +115,8 @@ void gfs2_set_iop(struct inode *inode) | |||
119 | * Returns: A VFS inode, or an error | 115 | * Returns: A VFS inode, or an error |
120 | */ | 116 | */ |
121 | 117 | ||
122 | struct inode *gfs2_inode_lookup(struct super_block *sb, | 118 | struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, |
123 | unsigned int type, | 119 | u64 no_addr, u64 no_formal_ino) |
124 | u64 no_addr, | ||
125 | u64 no_formal_ino) | ||
126 | { | 120 | { |
127 | struct inode *inode; | 121 | struct inode *inode; |
128 | struct gfs2_inode *ip; | 122 | struct gfs2_inode *ip; |
@@ -152,51 +146,37 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, | |||
152 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | 146 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
153 | if (unlikely(error)) | 147 | if (unlikely(error)) |
154 | goto fail_iopen; | 148 | goto fail_iopen; |
155 | ip->i_iopen_gh.gh_gl->gl_object = ip; | ||
156 | 149 | ||
150 | ip->i_iopen_gh.gh_gl->gl_object = ip; | ||
157 | gfs2_glock_put(io_gl); | 151 | gfs2_glock_put(io_gl); |
158 | io_gl = NULL; | 152 | io_gl = NULL; |
159 | 153 | ||
160 | if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) | ||
161 | goto gfs2_nfsbypass; | ||
162 | |||
163 | inode->i_mode = DT2IF(type); | ||
164 | |||
165 | /* | ||
166 | * We must read the inode in order to work out its type in | ||
167 | * this case. Note that this doesn't happen often as we normally | ||
168 | * know the type beforehand. This code path only occurs during | ||
169 | * unlinked inode recovery (where it is safe to do this glock, | ||
170 | * which is not true in the general case). | ||
171 | */ | ||
172 | if (type == DT_UNKNOWN) { | 154 | if (type == DT_UNKNOWN) { |
173 | struct gfs2_holder gh; | 155 | /* Inode glock must be locked already */ |
174 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 156 | error = gfs2_inode_refresh(GFS2_I(inode)); |
175 | if (unlikely(error)) | 157 | if (error) |
176 | goto fail_glock; | 158 | goto fail_refresh; |
177 | /* Inode is now uptodate */ | 159 | } else { |
178 | gfs2_glock_dq_uninit(&gh); | 160 | inode->i_mode = DT2IF(type); |
179 | } | 161 | } |
180 | 162 | ||
181 | gfs2_set_iop(inode); | 163 | gfs2_set_iop(inode); |
164 | unlock_new_inode(inode); | ||
182 | } | 165 | } |
183 | 166 | ||
184 | gfs2_nfsbypass: | ||
185 | return inode; | 167 | return inode; |
186 | fail_glock: | 168 | |
187 | gfs2_glock_dq(&ip->i_iopen_gh); | 169 | fail_refresh: |
170 | ip->i_iopen_gh.gh_gl->gl_object = NULL; | ||
171 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | ||
188 | fail_iopen: | 172 | fail_iopen: |
189 | if (io_gl) | 173 | if (io_gl) |
190 | gfs2_glock_put(io_gl); | 174 | gfs2_glock_put(io_gl); |
191 | fail_put: | 175 | fail_put: |
192 | if (inode->i_state & I_NEW) | 176 | ip->i_gl->gl_object = NULL; |
193 | ip->i_gl->gl_object = NULL; | ||
194 | gfs2_glock_put(ip->i_gl); | 177 | gfs2_glock_put(ip->i_gl); |
195 | fail: | 178 | fail: |
196 | if (inode->i_state & I_NEW) | 179 | iget_failed(inode); |
197 | iget_failed(inode); | ||
198 | else | ||
199 | iput(inode); | ||
200 | return ERR_PTR(error); | 180 | return ERR_PTR(error); |
201 | } | 181 | } |
202 | 182 | ||
@@ -221,14 +201,6 @@ struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, | |||
221 | if (IS_ERR(inode)) | 201 | if (IS_ERR(inode)) |
222 | goto fail; | 202 | goto fail; |
223 | 203 | ||
224 | error = gfs2_inode_refresh(GFS2_I(inode)); | ||
225 | if (error) | ||
226 | goto fail_iput; | ||
227 | |||
228 | /* Pick up the works we bypass in gfs2_inode_lookup */ | ||
229 | if (inode->i_state & I_NEW) | ||
230 | gfs2_set_iop(inode); | ||
231 | |||
232 | /* Two extra checks for NFS only */ | 204 | /* Two extra checks for NFS only */ |
233 | if (no_formal_ino) { | 205 | if (no_formal_ino) { |
234 | error = -ESTALE; | 206 | error = -ESTALE; |