aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorWendy Cheng <wcheng@redhat.com>2007-06-27 17:07:53 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-07-09 03:24:11 -0400
commit35dcc52e3a916184b145fd840250244b81004200 (patch)
treef3ab5a4094a676967e668fb407c0296a1150264a /fs
parentbb9bcf061660661c57ddcf31337529f82414b937 (diff)
[GFS2] Remove i_mode passing from NFS File Handle
GFS2 has been passing i_mode within NFS File Handle. Other than the wrong assumption that there is always room for this extra 16 bit value, the current gfs2_get_dentry doesn't really need the i_mode to work correctly. Note that GFS2 NFS code does go thru the same lookup code path as direct file access route (where the mode is obtained from name lookup) but gfs2_get_dentry() is coded for different purpose. It is not used during lookup time. It is part of the file access procedure call. When the call is invoked, if on-disk inode is not in-memory, it has to be read-in. This makes i_mode passing a useless overhead. Signed-off-by: S. Wendy Cheng <wcheng@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/inode.c54
-rw-r--r--fs/gfs2/inode.h1
-rw-r--r--fs/gfs2/ops_export.c38
-rw-r--r--fs/gfs2/rgrp.c2
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
90void 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
178gfs2_nfsbypass:
159 return inode; 179 return inode;
160fail_glock: 180fail_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
49void gfs2_inode_attr_in(struct gfs2_inode *ip); 49void gfs2_inode_attr_in(struct gfs2_inode *ip);
50void gfs2_set_iop(struct inode *inode);
50struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, 51struct 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);
52struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); 53struct 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
32struct gfs2_fh_obj {
33 struct gfs2_inum_host this;
34 u32 imode;
35};
36 31
37static struct dentry *gfs2_decode_fh(struct super_block *sb, 32static 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)
201static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) 189static 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 }