aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@gmail.com>2005-09-09 16:04:27 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:58 -0400
commitb501611a6f78558eafcf09b228abd866d4ea5d9f (patch)
treed1d78694f54cd563f99a071eb29d8a40ad30d154 /fs/9p
parent5d58bec5b7a8b8303df0a4dcb9a18feeefac6091 (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/9p')
-rw-r--r--fs/9p/vfs_inode.c35
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
46static struct inode_operations v9fs_dir_inode_operations; 46static struct inode_operations v9fs_dir_inode_operations;
47static struct inode_operations v9fs_dir_inode_operations_ext;
47static struct inode_operations v9fs_file_inode_operations; 48static struct inode_operations v9fs_file_inode_operations;
48static struct inode_operations v9fs_symlink_inode_operations; 49static struct inode_operations v9fs_symlink_inode_operations;
49 50
@@ -232,6 +233,7 @@ v9fs_mistat2unix(struct v9fs_stat *mistat, struct stat *buf,
232struct inode *v9fs_get_inode(struct super_block *sb, int mode) 233struct 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
1287static struct inode_operations v9fs_dir_inode_operations = { 1300static 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
1315static 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
1302static struct inode_operations v9fs_file_inode_operations = { 1327static 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,