diff options
Diffstat (limited to 'fs/gfs2/export.c')
-rw-r--r-- | fs/gfs2/export.c | 76 |
1 files changed, 13 insertions, 63 deletions
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index dfe237a3f8ad..fe9945f2ff72 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c | |||
@@ -36,9 +36,13 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | |||
36 | struct super_block *sb = inode->i_sb; | 36 | struct super_block *sb = inode->i_sb; |
37 | struct gfs2_inode *ip = GFS2_I(inode); | 37 | struct gfs2_inode *ip = GFS2_I(inode); |
38 | 38 | ||
39 | if (*len < GFS2_SMALL_FH_SIZE || | 39 | if (connectable && (*len < GFS2_LARGE_FH_SIZE)) { |
40 | (connectable && *len < GFS2_LARGE_FH_SIZE)) | 40 | *len = GFS2_LARGE_FH_SIZE; |
41 | return 255; | 41 | return 255; |
42 | } else if (*len < GFS2_SMALL_FH_SIZE) { | ||
43 | *len = GFS2_SMALL_FH_SIZE; | ||
44 | return 255; | ||
45 | } | ||
42 | 46 | ||
43 | fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); | 47 | fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); |
44 | fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); | 48 | fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); |
@@ -126,31 +130,16 @@ static int gfs2_get_name(struct dentry *parent, char *name, | |||
126 | 130 | ||
127 | static struct dentry *gfs2_get_parent(struct dentry *child) | 131 | static struct dentry *gfs2_get_parent(struct dentry *child) |
128 | { | 132 | { |
129 | struct qstr dotdot; | 133 | return d_obtain_alias(gfs2_lookupi(child->d_inode, &gfs2_qdotdot, 1)); |
130 | struct dentry *dentry; | ||
131 | |||
132 | /* | ||
133 | * XXX(hch): it would be a good idea to keep this around as a | ||
134 | * static variable. | ||
135 | */ | ||
136 | gfs2_str2qstr(&dotdot, ".."); | ||
137 | |||
138 | dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &dotdot, 1)); | ||
139 | if (!IS_ERR(dentry)) | ||
140 | dentry->d_op = &gfs2_dops; | ||
141 | return dentry; | ||
142 | } | 134 | } |
143 | 135 | ||
144 | static struct dentry *gfs2_get_dentry(struct super_block *sb, | 136 | static struct dentry *gfs2_get_dentry(struct super_block *sb, |
145 | struct gfs2_inum_host *inum) | 137 | struct gfs2_inum_host *inum) |
146 | { | 138 | { |
147 | struct gfs2_sbd *sdp = sb->s_fs_info; | 139 | struct gfs2_sbd *sdp = sb->s_fs_info; |
148 | struct gfs2_holder i_gh; | ||
149 | struct inode *inode; | 140 | struct inode *inode; |
150 | struct dentry *dentry; | ||
151 | int error; | ||
152 | 141 | ||
153 | inode = gfs2_ilookup(sb, inum->no_addr); | 142 | inode = gfs2_ilookup(sb, inum->no_addr, 0); |
154 | if (inode) { | 143 | if (inode) { |
155 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { | 144 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { |
156 | iput(inode); | 145 | iput(inode); |
@@ -159,52 +148,13 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, | |||
159 | goto out_inode; | 148 | goto out_inode; |
160 | } | 149 | } |
161 | 150 | ||
162 | error = gfs2_glock_nq_num(sdp, inum->no_addr, &gfs2_inode_glops, | 151 | inode = gfs2_lookup_by_inum(sdp, inum->no_addr, &inum->no_formal_ino, |
163 | LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | 152 | GFS2_BLKST_DINODE); |
164 | if (error) | 153 | if (IS_ERR(inode)) |
165 | return ERR_PTR(error); | 154 | return ERR_CAST(inode); |
166 | |||
167 | error = gfs2_check_blk_type(sdp, inum->no_addr, GFS2_BLKST_DINODE); | ||
168 | if (error) | ||
169 | goto fail; | ||
170 | |||
171 | inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0); | ||
172 | if (IS_ERR(inode)) { | ||
173 | error = PTR_ERR(inode); | ||
174 | goto fail; | ||
175 | } | ||
176 | |||
177 | error = gfs2_inode_refresh(GFS2_I(inode)); | ||
178 | if (error) { | ||
179 | iput(inode); | ||
180 | goto fail; | ||
181 | } | ||
182 | |||
183 | /* Pick up the works we bypass in gfs2_inode_lookup */ | ||
184 | if (inode->i_state & I_NEW) | ||
185 | gfs2_set_iop(inode); | ||
186 | |||
187 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { | ||
188 | iput(inode); | ||
189 | goto fail; | ||
190 | } | ||
191 | |||
192 | error = -EIO; | ||
193 | if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) { | ||
194 | iput(inode); | ||
195 | goto fail; | ||
196 | } | ||
197 | |||
198 | gfs2_glock_dq_uninit(&i_gh); | ||
199 | 155 | ||
200 | out_inode: | 156 | out_inode: |
201 | dentry = d_obtain_alias(inode); | 157 | return d_obtain_alias(inode); |
202 | if (!IS_ERR(dentry)) | ||
203 | dentry->d_op = &gfs2_dops; | ||
204 | return dentry; | ||
205 | fail: | ||
206 | gfs2_glock_dq_uninit(&i_gh); | ||
207 | return ERR_PTR(error); | ||
208 | } | 158 | } |
209 | 159 | ||
210 | static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, | 160 | static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, |