diff options
Diffstat (limited to 'fs/gfs2/ops_export.c')
-rw-r--r-- | fs/gfs2/ops_export.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index aad918337a46..99ea5659bc2c 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c | |||
@@ -22,10 +22,14 @@ | |||
22 | #include "glops.h" | 22 | #include "glops.h" |
23 | #include "inode.h" | 23 | #include "inode.h" |
24 | #include "ops_dentry.h" | 24 | #include "ops_dentry.h" |
25 | #include "ops_export.h" | 25 | #include "ops_fstype.h" |
26 | #include "rgrp.h" | 26 | #include "rgrp.h" |
27 | #include "util.h" | 27 | #include "util.h" |
28 | 28 | ||
29 | #define GFS2_SMALL_FH_SIZE 4 | ||
30 | #define GFS2_LARGE_FH_SIZE 8 | ||
31 | #define GFS2_OLD_FH_SIZE 10 | ||
32 | |||
29 | static struct dentry *gfs2_decode_fh(struct super_block *sb, | 33 | static struct dentry *gfs2_decode_fh(struct super_block *sb, |
30 | __u32 *p, | 34 | __u32 *p, |
31 | int fh_len, | 35 | int fh_len, |
@@ -35,31 +39,28 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, | |||
35 | void *context) | 39 | void *context) |
36 | { | 40 | { |
37 | __be32 *fh = (__force __be32 *)p; | 41 | __be32 *fh = (__force __be32 *)p; |
38 | struct gfs2_fh_obj fh_obj; | 42 | struct gfs2_inum_host inum, parent; |
39 | struct gfs2_inum_host *this, parent; | ||
40 | 43 | ||
41 | this = &fh_obj.this; | ||
42 | fh_obj.imode = DT_UNKNOWN; | ||
43 | memset(&parent, 0, sizeof(struct gfs2_inum)); | 44 | memset(&parent, 0, sizeof(struct gfs2_inum)); |
44 | 45 | ||
45 | switch (fh_len) { | 46 | switch (fh_len) { |
46 | case GFS2_LARGE_FH_SIZE: | 47 | case GFS2_LARGE_FH_SIZE: |
48 | case GFS2_OLD_FH_SIZE: | ||
47 | parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; | 49 | parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; |
48 | parent.no_formal_ino |= be32_to_cpu(fh[5]); | 50 | parent.no_formal_ino |= be32_to_cpu(fh[5]); |
49 | parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; | 51 | parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; |
50 | parent.no_addr |= be32_to_cpu(fh[7]); | 52 | parent.no_addr |= be32_to_cpu(fh[7]); |
51 | fh_obj.imode = be32_to_cpu(fh[8]); | ||
52 | case GFS2_SMALL_FH_SIZE: | 53 | case GFS2_SMALL_FH_SIZE: |
53 | this->no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; | 54 | inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; |
54 | this->no_formal_ino |= be32_to_cpu(fh[1]); | 55 | inum.no_formal_ino |= be32_to_cpu(fh[1]); |
55 | this->no_addr = ((u64)be32_to_cpu(fh[2])) << 32; | 56 | inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32; |
56 | this->no_addr |= be32_to_cpu(fh[3]); | 57 | inum.no_addr |= be32_to_cpu(fh[3]); |
57 | break; | 58 | break; |
58 | default: | 59 | default: |
59 | return NULL; | 60 | return NULL; |
60 | } | 61 | } |
61 | 62 | ||
62 | return gfs2_export_ops.find_exported_dentry(sb, &fh_obj, &parent, | 63 | return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent, |
63 | acceptable, context); | 64 | acceptable, context); |
64 | } | 65 | } |
65 | 66 | ||
@@ -75,10 +76,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | |||
75 | (connectable && *len < GFS2_LARGE_FH_SIZE)) | 76 | (connectable && *len < GFS2_LARGE_FH_SIZE)) |
76 | return 255; | 77 | return 255; |
77 | 78 | ||
78 | fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); | 79 | fh[0] = cpu_to_be32(ip->i_no_formal_ino >> 32); |
79 | fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); | 80 | fh[1] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); |
80 | fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32); | 81 | fh[2] = cpu_to_be32(ip->i_no_addr >> 32); |
81 | fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); | 82 | fh[3] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); |
82 | *len = GFS2_SMALL_FH_SIZE; | 83 | *len = GFS2_SMALL_FH_SIZE; |
83 | 84 | ||
84 | if (!connectable || inode == sb->s_root->d_inode) | 85 | if (!connectable || inode == sb->s_root->d_inode) |
@@ -90,13 +91,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | |||
90 | igrab(inode); | 91 | igrab(inode); |
91 | spin_unlock(&dentry->d_lock); | 92 | spin_unlock(&dentry->d_lock); |
92 | 93 | ||
93 | fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); | 94 | fh[4] = cpu_to_be32(ip->i_no_formal_ino >> 32); |
94 | fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); | 95 | fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); |
95 | fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32); | 96 | fh[6] = cpu_to_be32(ip->i_no_addr >> 32); |
96 | fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); | 97 | fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); |
97 | |||
98 | fh[8] = cpu_to_be32(inode->i_mode); | ||
99 | fh[9] = 0; /* pad to double word */ | ||
100 | *len = GFS2_LARGE_FH_SIZE; | 98 | *len = GFS2_LARGE_FH_SIZE; |
101 | 99 | ||
102 | iput(inode); | 100 | iput(inode); |
@@ -144,7 +142,8 @@ static int gfs2_get_name(struct dentry *parent, char *name, | |||
144 | ip = GFS2_I(inode); | 142 | ip = GFS2_I(inode); |
145 | 143 | ||
146 | *name = 0; | 144 | *name = 0; |
147 | gnfd.inum = ip->i_num; | 145 | gnfd.inum.no_addr = ip->i_no_addr; |
146 | gnfd.inum.no_formal_ino = ip->i_no_formal_ino; | ||
148 | gnfd.name = name; | 147 | gnfd.name = name; |
149 | 148 | ||
150 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); | 149 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); |
@@ -192,8 +191,7 @@ static struct dentry *gfs2_get_parent(struct dentry *child) | |||
192 | static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | 191 | static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) |
193 | { | 192 | { |
194 | struct gfs2_sbd *sdp = sb->s_fs_info; | 193 | struct gfs2_sbd *sdp = sb->s_fs_info; |
195 | struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; | 194 | struct gfs2_inum_host *inum = inum_obj; |
196 | struct gfs2_inum_host *inum = &fh_obj->this; | ||
197 | struct gfs2_holder i_gh, ri_gh, rgd_gh; | 195 | struct gfs2_holder i_gh, ri_gh, rgd_gh; |
198 | struct gfs2_rgrpd *rgd; | 196 | struct gfs2_rgrpd *rgd; |
199 | struct inode *inode; | 197 | struct inode *inode; |
@@ -202,9 +200,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
202 | 200 | ||
203 | /* System files? */ | 201 | /* System files? */ |
204 | 202 | ||
205 | inode = gfs2_ilookup(sb, inum); | 203 | inode = gfs2_ilookup(sb, inum->no_addr); |
206 | if (inode) { | 204 | if (inode) { |
207 | if (GFS2_I(inode)->i_num.no_formal_ino != inum->no_formal_ino) { | 205 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { |
208 | iput(inode); | 206 | iput(inode); |
209 | return ERR_PTR(-ESTALE); | 207 | return ERR_PTR(-ESTALE); |
210 | } | 208 | } |
@@ -236,7 +234,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
236 | gfs2_glock_dq_uninit(&rgd_gh); | 234 | gfs2_glock_dq_uninit(&rgd_gh); |
237 | gfs2_glock_dq_uninit(&ri_gh); | 235 | gfs2_glock_dq_uninit(&ri_gh); |
238 | 236 | ||
239 | inode = gfs2_inode_lookup(sb, inum, fh_obj->imode); | 237 | inode = gfs2_inode_lookup(sb, DT_UNKNOWN, |
238 | inum->no_addr, | ||
239 | 0); | ||
240 | if (!inode) | 240 | if (!inode) |
241 | goto fail; | 241 | goto fail; |
242 | if (IS_ERR(inode)) { | 242 | if (IS_ERR(inode)) { |
@@ -250,6 +250,15 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
250 | goto fail; | 250 | goto fail; |
251 | } | 251 | } |
252 | 252 | ||
253 | /* Pick up the works we bypass in gfs2_inode_lookup */ | ||
254 | if (inode->i_state & I_NEW) | ||
255 | gfs2_set_iop(inode); | ||
256 | |||
257 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { | ||
258 | iput(inode); | ||
259 | goto fail; | ||
260 | } | ||
261 | |||
253 | error = -EIO; | 262 | error = -EIO; |
254 | if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) { | 263 | if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) { |
255 | iput(inode); | 264 | iput(inode); |