diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/inode.c | 54 | ||||
-rw-r--r-- | fs/gfs2/inode.h | 1 | ||||
-rw-r--r-- | fs/gfs2/ops_export.c | 38 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 2 |
4 files changed, 54 insertions, 41 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 26aaf54959d9..34f7bcdea1e9 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -78,6 +78,36 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | /** | 80 | /** |
81 | * GFS2 lookup code fills in vfs inode contents based on info obtained | ||
82 | * from directory entry inside gfs2_inode_lookup(). This has caused issues | ||
83 | * with NFS code path since its get_dentry routine doesn't have the relevant | ||
84 | * directory entry when gfs2_inode_lookup() is invoked. Part of the code | ||
85 | * segment inside gfs2_inode_lookup code needs to get moved around. | ||
86 | * | ||
87 | * Clean up I_LOCK and I_NEW as well. | ||
88 | **/ | ||
89 | |||
90 | void gfs2_set_iop(struct inode *inode) | ||
91 | { | ||
92 | umode_t mode = inode->i_mode; | ||
93 | |||
94 | if (S_ISREG(mode)) { | ||
95 | inode->i_op = &gfs2_file_iops; | ||
96 | inode->i_fop = &gfs2_file_fops; | ||
97 | inode->i_mapping->a_ops = &gfs2_file_aops; | ||
98 | } else if (S_ISDIR(mode)) { | ||
99 | inode->i_op = &gfs2_dir_iops; | ||
100 | inode->i_fop = &gfs2_dir_fops; | ||
101 | } else if (S_ISLNK(mode)) { | ||
102 | inode->i_op = &gfs2_symlink_iops; | ||
103 | } else { | ||
104 | inode->i_op = &gfs2_dev_iops; | ||
105 | } | ||
106 | |||
107 | unlock_new_inode(inode); | ||
108 | } | ||
109 | |||
110 | /** | ||
81 | * gfs2_inode_lookup - Lookup an inode | 111 | * gfs2_inode_lookup - Lookup an inode |
82 | * @sb: The super block | 112 | * @sb: The super block |
83 | * @no_addr: The inode number | 113 | * @no_addr: The inode number |
@@ -101,7 +131,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, | |||
101 | 131 | ||
102 | if (inode->i_state & I_NEW) { | 132 | if (inode->i_state & I_NEW) { |
103 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 133 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
104 | umode_t mode; | ||
105 | inode->i_private = ip; | 134 | inode->i_private = ip; |
106 | ip->i_no_formal_ino = no_formal_ino; | 135 | ip->i_no_formal_ino = no_formal_ino; |
107 | 136 | ||
@@ -122,6 +151,11 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, | |||
122 | 151 | ||
123 | gfs2_glock_put(io_gl); | 152 | gfs2_glock_put(io_gl); |
124 | 153 | ||
154 | if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) | ||
155 | goto gfs2_nfsbypass; | ||
156 | |||
157 | inode->i_mode = DT2IF(type); | ||
158 | |||
125 | /* | 159 | /* |
126 | * We must read the inode in order to work out its type in | 160 | * We must read the inode in order to work out its type in |
127 | * this case. Note that this doesn't happen often as we normally | 161 | * this case. Note that this doesn't happen often as we normally |
@@ -129,33 +163,19 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, | |||
129 | * unlinked inode recovery (where it is safe to do this glock, | 163 | * unlinked inode recovery (where it is safe to do this glock, |
130 | * which is not true in the general case). | 164 | * which is not true in the general case). |
131 | */ | 165 | */ |
132 | inode->i_mode = mode = DT2IF(type); | ||
133 | if (type == DT_UNKNOWN) { | 166 | if (type == DT_UNKNOWN) { |
134 | struct gfs2_holder gh; | 167 | struct gfs2_holder gh; |
135 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 168 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
136 | if (unlikely(error)) | 169 | if (unlikely(error)) |
137 | goto fail_glock; | 170 | goto fail_glock; |
138 | /* Inode is now uptodate */ | 171 | /* Inode is now uptodate */ |
139 | mode = inode->i_mode; | ||
140 | gfs2_glock_dq_uninit(&gh); | 172 | gfs2_glock_dq_uninit(&gh); |
141 | } | 173 | } |
142 | 174 | ||
143 | if (S_ISREG(mode)) { | 175 | gfs2_set_iop(inode); |
144 | inode->i_op = &gfs2_file_iops; | ||
145 | inode->i_fop = &gfs2_file_fops; | ||
146 | inode->i_mapping->a_ops = &gfs2_file_aops; | ||
147 | } else if (S_ISDIR(mode)) { | ||
148 | inode->i_op = &gfs2_dir_iops; | ||
149 | inode->i_fop = &gfs2_dir_fops; | ||
150 | } else if (S_ISLNK(mode)) { | ||
151 | inode->i_op = &gfs2_symlink_iops; | ||
152 | } else { | ||
153 | inode->i_op = &gfs2_dev_iops; | ||
154 | } | ||
155 | |||
156 | unlock_new_inode(inode); | ||
157 | } | 176 | } |
158 | 177 | ||
178 | gfs2_nfsbypass: | ||
159 | return inode; | 179 | return inode; |
160 | fail_glock: | 180 | fail_glock: |
161 | gfs2_glock_dq(&ip->i_iopen_gh); | 181 | gfs2_glock_dq(&ip->i_iopen_gh); |
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 3268a2fed672..4517ac82c01c 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -47,6 +47,7 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip, | |||
47 | 47 | ||
48 | 48 | ||
49 | void gfs2_inode_attr_in(struct gfs2_inode *ip); | 49 | void gfs2_inode_attr_in(struct gfs2_inode *ip); |
50 | void gfs2_set_iop(struct inode *inode); | ||
50 | struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, | 51 | struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, |
51 | u64 no_addr, u64 no_formal_ino); | 52 | u64 no_addr, u64 no_formal_ino); |
52 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); | 53 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); |
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index 0fe14478a54d..e317db2a5548 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c | |||
@@ -27,12 +27,7 @@ | |||
27 | #include "util.h" | 27 | #include "util.h" |
28 | 28 | ||
29 | #define GFS2_SMALL_FH_SIZE 4 | 29 | #define GFS2_SMALL_FH_SIZE 4 |
30 | #define GFS2_LARGE_FH_SIZE 10 | 30 | #define GFS2_LARGE_FH_SIZE 8 |
31 | |||
32 | struct gfs2_fh_obj { | ||
33 | struct gfs2_inum_host this; | ||
34 | u32 imode; | ||
35 | }; | ||
36 | 31 | ||
37 | static struct dentry *gfs2_decode_fh(struct super_block *sb, | 32 | static struct dentry *gfs2_decode_fh(struct super_block *sb, |
38 | __u32 *p, | 33 | __u32 *p, |
@@ -43,11 +38,8 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, | |||
43 | void *context) | 38 | void *context) |
44 | { | 39 | { |
45 | __be32 *fh = (__force __be32 *)p; | 40 | __be32 *fh = (__force __be32 *)p; |
46 | struct gfs2_fh_obj fh_obj; | 41 | struct gfs2_inum_host inum, parent; |
47 | struct gfs2_inum_host *this, parent; | ||
48 | 42 | ||
49 | this = &fh_obj.this; | ||
50 | fh_obj.imode = DT_UNKNOWN; | ||
51 | memset(&parent, 0, sizeof(struct gfs2_inum)); | 43 | memset(&parent, 0, sizeof(struct gfs2_inum)); |
52 | 44 | ||
53 | switch (fh_len) { | 45 | switch (fh_len) { |
@@ -56,18 +48,17 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, | |||
56 | parent.no_formal_ino |= be32_to_cpu(fh[5]); | 48 | parent.no_formal_ino |= be32_to_cpu(fh[5]); |
57 | parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; | 49 | parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32; |
58 | parent.no_addr |= be32_to_cpu(fh[7]); | 50 | parent.no_addr |= be32_to_cpu(fh[7]); |
59 | fh_obj.imode = be32_to_cpu(fh[8]); | ||
60 | case GFS2_SMALL_FH_SIZE: | 51 | case GFS2_SMALL_FH_SIZE: |
61 | this->no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; | 52 | inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32; |
62 | this->no_formal_ino |= be32_to_cpu(fh[1]); | 53 | inum.no_formal_ino |= be32_to_cpu(fh[1]); |
63 | this->no_addr = ((u64)be32_to_cpu(fh[2])) << 32; | 54 | inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32; |
64 | this->no_addr |= be32_to_cpu(fh[3]); | 55 | inum.no_addr |= be32_to_cpu(fh[3]); |
65 | break; | 56 | break; |
66 | default: | 57 | default: |
67 | return NULL; | 58 | return NULL; |
68 | } | 59 | } |
69 | 60 | ||
70 | return gfs2_export_ops.find_exported_dentry(sb, &fh_obj, &parent, | 61 | return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent, |
71 | acceptable, context); | 62 | acceptable, context); |
72 | } | 63 | } |
73 | 64 | ||
@@ -102,9 +93,6 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, | |||
102 | fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); | 93 | fh[5] = cpu_to_be32(ip->i_no_formal_ino & 0xFFFFFFFF); |
103 | fh[6] = cpu_to_be32(ip->i_no_addr >> 32); | 94 | fh[6] = cpu_to_be32(ip->i_no_addr >> 32); |
104 | fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); | 95 | fh[7] = cpu_to_be32(ip->i_no_addr & 0xFFFFFFFF); |
105 | |||
106 | fh[8] = cpu_to_be32(inode->i_mode); | ||
107 | fh[9] = 0; /* pad to double word */ | ||
108 | *len = GFS2_LARGE_FH_SIZE; | 96 | *len = GFS2_LARGE_FH_SIZE; |
109 | 97 | ||
110 | iput(inode); | 98 | iput(inode); |
@@ -201,8 +189,7 @@ static struct dentry *gfs2_get_parent(struct dentry *child) | |||
201 | static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | 189 | static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) |
202 | { | 190 | { |
203 | struct gfs2_sbd *sdp = sb->s_fs_info; | 191 | struct gfs2_sbd *sdp = sb->s_fs_info; |
204 | struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; | 192 | struct gfs2_inum_host *inum = inum_obj; |
205 | struct gfs2_inum_host *inum = &fh_obj->this; | ||
206 | struct gfs2_holder i_gh, ri_gh, rgd_gh; | 193 | struct gfs2_holder i_gh, ri_gh, rgd_gh; |
207 | struct gfs2_rgrpd *rgd; | 194 | struct gfs2_rgrpd *rgd; |
208 | struct inode *inode; | 195 | struct inode *inode; |
@@ -245,9 +232,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
245 | gfs2_glock_dq_uninit(&rgd_gh); | 232 | gfs2_glock_dq_uninit(&rgd_gh); |
246 | gfs2_glock_dq_uninit(&ri_gh); | 233 | gfs2_glock_dq_uninit(&ri_gh); |
247 | 234 | ||
248 | inode = gfs2_inode_lookup(sb, fh_obj->imode, | 235 | inode = gfs2_inode_lookup(sb, DT_UNKNOWN, |
249 | inum->no_addr, | 236 | inum->no_addr, |
250 | inum->no_formal_ino); | 237 | 0); |
251 | if (!inode) | 238 | if (!inode) |
252 | goto fail; | 239 | goto fail; |
253 | if (IS_ERR(inode)) { | 240 | if (IS_ERR(inode)) { |
@@ -260,6 +247,11 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
260 | iput(inode); | 247 | iput(inode); |
261 | goto fail; | 248 | goto fail; |
262 | } | 249 | } |
250 | |||
251 | /* Pick up the works we bypass in gfs2_inode_lookup */ | ||
252 | if (inode->i_state & I_NEW) | ||
253 | gfs2_set_iop(inode); | ||
254 | |||
263 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { | 255 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { |
264 | iput(inode); | 256 | iput(inode); |
265 | goto fail; | 257 | goto fail; |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 7fb74484af63..e4e040625153 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -872,7 +872,7 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) | |||
872 | continue; | 872 | continue; |
873 | *last_unlinked = no_addr; | 873 | *last_unlinked = no_addr; |
874 | inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, | 874 | inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, |
875 | no_addr, 0); | 875 | no_addr, -1); |
876 | if (!IS_ERR(inode)) | 876 | if (!IS_ERR(inode)) |
877 | return inode; | 877 | return inode; |
878 | } | 878 | } |