diff options
author | Eric Van Hensbergen <ericvh@gmail.com> | 2005-09-09 16:04:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 16:57:58 -0400 |
commit | b501611a6f78558eafcf09b228abd866d4ea5d9f (patch) | |
tree | d1d78694f54cd563f99a071eb29d8a40ad30d154 /fs | |
parent | 5d58bec5b7a8b8303df0a4dcb9a18feeefac6091 (diff) |
[PATCH] v9fs: readlink extended mode check
LANL reported some issues with random crashes during mount of legacy protocol
servers (9P2000 versus 9P2000.u) -- crash was always happening in readlink
(which should never happen in legacy mode). Added some sanity conditionals to
the get_inode code which should prevent the errors LANL was seeing. Code
tested benign through regression.
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/vfs_inode.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 36fff087167f..0c13fc600049 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "fid.h" | 44 | #include "fid.h" |
45 | 45 | ||
46 | static struct inode_operations v9fs_dir_inode_operations; | 46 | static struct inode_operations v9fs_dir_inode_operations; |
47 | static struct inode_operations v9fs_dir_inode_operations_ext; | ||
47 | static struct inode_operations v9fs_file_inode_operations; | 48 | static struct inode_operations v9fs_file_inode_operations; |
48 | static struct inode_operations v9fs_symlink_inode_operations; | 49 | static struct inode_operations v9fs_symlink_inode_operations; |
49 | 50 | ||
@@ -232,6 +233,7 @@ v9fs_mistat2unix(struct v9fs_stat *mistat, struct stat *buf, | |||
232 | struct inode *v9fs_get_inode(struct super_block *sb, int mode) | 233 | struct inode *v9fs_get_inode(struct super_block *sb, int mode) |
233 | { | 234 | { |
234 | struct inode *inode = NULL; | 235 | struct inode *inode = NULL; |
236 | struct v9fs_session_info *v9ses = sb->s_fs_info; | ||
235 | 237 | ||
236 | dprintk(DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); | 238 | dprintk(DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); |
237 | 239 | ||
@@ -250,6 +252,10 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
250 | case S_IFBLK: | 252 | case S_IFBLK: |
251 | case S_IFCHR: | 253 | case S_IFCHR: |
252 | case S_IFSOCK: | 254 | case S_IFSOCK: |
255 | if(!v9ses->extended) { | ||
256 | dprintk(DEBUG_ERROR, "special files without extended mode\n"); | ||
257 | return ERR_PTR(-EINVAL); | ||
258 | } | ||
253 | init_special_inode(inode, inode->i_mode, | 259 | init_special_inode(inode, inode->i_mode, |
254 | inode->i_rdev); | 260 | inode->i_rdev); |
255 | break; | 261 | break; |
@@ -257,14 +263,21 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
257 | inode->i_op = &v9fs_file_inode_operations; | 263 | inode->i_op = &v9fs_file_inode_operations; |
258 | inode->i_fop = &v9fs_file_operations; | 264 | inode->i_fop = &v9fs_file_operations; |
259 | break; | 265 | break; |
266 | case S_IFLNK: | ||
267 | if(!v9ses->extended) { | ||
268 | dprintk(DEBUG_ERROR, "extended modes used w/o 9P2000.u\n"); | ||
269 | return ERR_PTR(-EINVAL); | ||
270 | } | ||
271 | inode->i_op = &v9fs_symlink_inode_operations; | ||
272 | break; | ||
260 | case S_IFDIR: | 273 | case S_IFDIR: |
261 | inode->i_nlink++; | 274 | inode->i_nlink++; |
262 | inode->i_op = &v9fs_dir_inode_operations; | 275 | if(v9ses->extended) |
276 | inode->i_op = &v9fs_dir_inode_operations_ext; | ||
277 | else | ||
278 | inode->i_op = &v9fs_dir_inode_operations; | ||
263 | inode->i_fop = &v9fs_dir_operations; | 279 | inode->i_fop = &v9fs_dir_operations; |
264 | break; | 280 | break; |
265 | case S_IFLNK: | ||
266 | inode->i_op = &v9fs_symlink_inode_operations; | ||
267 | break; | ||
268 | default: | 281 | default: |
269 | dprintk(DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n", | 282 | dprintk(DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n", |
270 | mode, mode & S_IFMT); | 283 | mode, mode & S_IFMT); |
@@ -1284,7 +1297,7 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
1284 | return retval; | 1297 | return retval; |
1285 | } | 1298 | } |
1286 | 1299 | ||
1287 | static struct inode_operations v9fs_dir_inode_operations = { | 1300 | static struct inode_operations v9fs_dir_inode_operations_ext = { |
1288 | .create = v9fs_vfs_create, | 1301 | .create = v9fs_vfs_create, |
1289 | .lookup = v9fs_vfs_lookup, | 1302 | .lookup = v9fs_vfs_lookup, |
1290 | .symlink = v9fs_vfs_symlink, | 1303 | .symlink = v9fs_vfs_symlink, |
@@ -1299,6 +1312,18 @@ static struct inode_operations v9fs_dir_inode_operations = { | |||
1299 | .setattr = v9fs_vfs_setattr, | 1312 | .setattr = v9fs_vfs_setattr, |
1300 | }; | 1313 | }; |
1301 | 1314 | ||
1315 | static struct inode_operations v9fs_dir_inode_operations = { | ||
1316 | .create = v9fs_vfs_create, | ||
1317 | .lookup = v9fs_vfs_lookup, | ||
1318 | .unlink = v9fs_vfs_unlink, | ||
1319 | .mkdir = v9fs_vfs_mkdir, | ||
1320 | .rmdir = v9fs_vfs_rmdir, | ||
1321 | .mknod = v9fs_vfs_mknod, | ||
1322 | .rename = v9fs_vfs_rename, | ||
1323 | .getattr = v9fs_vfs_getattr, | ||
1324 | .setattr = v9fs_vfs_setattr, | ||
1325 | }; | ||
1326 | |||
1302 | static struct inode_operations v9fs_file_inode_operations = { | 1327 | static struct inode_operations v9fs_file_inode_operations = { |
1303 | .getattr = v9fs_vfs_getattr, | 1328 | .getattr = v9fs_vfs_getattr, |
1304 | .setattr = v9fs_vfs_setattr, | 1329 | .setattr = v9fs_vfs_setattr, |