diff options
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 54 |
1 files changed, 37 insertions, 17 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); |