aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/export.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/export.c')
-rw-r--r--fs/gfs2/export.c76
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
127static struct dentry *gfs2_get_parent(struct dentry *child) 131static 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
144static struct dentry *gfs2_get_dentry(struct super_block *sb, 136static 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
200out_inode: 156out_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;
205fail:
206 gfs2_glock_dq_uninit(&i_gh);
207 return ERR_PTR(error);
208} 158}
209 159
210static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid, 160static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid,