diff options
Diffstat (limited to 'fs/9p/vfs_inode.c')
| -rw-r--r-- | fs/9p/vfs_inode.c | 126 |
1 files changed, 65 insertions, 61 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 81f8bbf12f9f..06a223d50a81 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -171,7 +171,6 @@ int v9fs_uflags2omode(int uflags, int extended) | |||
| 171 | 171 | ||
| 172 | /** | 172 | /** |
| 173 | * v9fs_blank_wstat - helper function to setup a 9P stat structure | 173 | * v9fs_blank_wstat - helper function to setup a 9P stat structure |
| 174 | * @v9ses: 9P session info (for determining extended mode) | ||
| 175 | * @wstat: structure to initialize | 174 | * @wstat: structure to initialize |
| 176 | * | 175 | * |
| 177 | */ | 176 | */ |
| @@ -207,65 +206,72 @@ v9fs_blank_wstat(struct p9_wstat *wstat) | |||
| 207 | 206 | ||
| 208 | struct inode *v9fs_get_inode(struct super_block *sb, int mode) | 207 | struct inode *v9fs_get_inode(struct super_block *sb, int mode) |
| 209 | { | 208 | { |
| 209 | int err; | ||
| 210 | struct inode *inode; | 210 | struct inode *inode; |
| 211 | struct v9fs_session_info *v9ses = sb->s_fs_info; | 211 | struct v9fs_session_info *v9ses = sb->s_fs_info; |
| 212 | 212 | ||
| 213 | P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); | 213 | P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); |
| 214 | 214 | ||
| 215 | inode = new_inode(sb); | 215 | inode = new_inode(sb); |
| 216 | if (inode) { | 216 | if (!inode) { |
| 217 | inode->i_mode = mode; | ||
| 218 | inode->i_uid = current_fsuid(); | ||
| 219 | inode->i_gid = current_fsgid(); | ||
| 220 | inode->i_blocks = 0; | ||
| 221 | inode->i_rdev = 0; | ||
| 222 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 223 | inode->i_mapping->a_ops = &v9fs_addr_operations; | ||
| 224 | |||
| 225 | switch (mode & S_IFMT) { | ||
| 226 | case S_IFIFO: | ||
| 227 | case S_IFBLK: | ||
| 228 | case S_IFCHR: | ||
| 229 | case S_IFSOCK: | ||
| 230 | if (!v9fs_extended(v9ses)) { | ||
| 231 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
| 232 | "special files without extended mode\n"); | ||
| 233 | return ERR_PTR(-EINVAL); | ||
| 234 | } | ||
| 235 | init_special_inode(inode, inode->i_mode, | ||
| 236 | inode->i_rdev); | ||
| 237 | break; | ||
| 238 | case S_IFREG: | ||
| 239 | inode->i_op = &v9fs_file_inode_operations; | ||
| 240 | inode->i_fop = &v9fs_file_operations; | ||
| 241 | break; | ||
| 242 | case S_IFLNK: | ||
| 243 | if (!v9fs_extended(v9ses)) { | ||
| 244 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
| 245 | "extended modes used w/o 9P2000.u\n"); | ||
| 246 | return ERR_PTR(-EINVAL); | ||
| 247 | } | ||
| 248 | inode->i_op = &v9fs_symlink_inode_operations; | ||
| 249 | break; | ||
| 250 | case S_IFDIR: | ||
| 251 | inc_nlink(inode); | ||
| 252 | if (v9fs_extended(v9ses)) | ||
| 253 | inode->i_op = &v9fs_dir_inode_operations_ext; | ||
| 254 | else | ||
| 255 | inode->i_op = &v9fs_dir_inode_operations; | ||
| 256 | inode->i_fop = &v9fs_dir_operations; | ||
| 257 | break; | ||
| 258 | default: | ||
| 259 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
| 260 | "BAD mode 0x%x S_IFMT 0x%x\n", | ||
| 261 | mode, mode & S_IFMT); | ||
| 262 | return ERR_PTR(-EINVAL); | ||
| 263 | } | ||
| 264 | } else { | ||
| 265 | P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); | 217 | P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); |
| 266 | return ERR_PTR(-ENOMEM); | 218 | return ERR_PTR(-ENOMEM); |
| 267 | } | 219 | } |
| 220 | |||
| 221 | inode->i_mode = mode; | ||
| 222 | inode->i_uid = current_fsuid(); | ||
| 223 | inode->i_gid = current_fsgid(); | ||
| 224 | inode->i_blocks = 0; | ||
| 225 | inode->i_rdev = 0; | ||
| 226 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 227 | inode->i_mapping->a_ops = &v9fs_addr_operations; | ||
| 228 | |||
| 229 | switch (mode & S_IFMT) { | ||
| 230 | case S_IFIFO: | ||
| 231 | case S_IFBLK: | ||
| 232 | case S_IFCHR: | ||
| 233 | case S_IFSOCK: | ||
| 234 | if (!v9fs_extended(v9ses)) { | ||
| 235 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
| 236 | "special files without extended mode\n"); | ||
| 237 | err = -EINVAL; | ||
| 238 | goto error; | ||
| 239 | } | ||
| 240 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | ||
| 241 | break; | ||
| 242 | case S_IFREG: | ||
| 243 | inode->i_op = &v9fs_file_inode_operations; | ||
| 244 | inode->i_fop = &v9fs_file_operations; | ||
| 245 | break; | ||
| 246 | case S_IFLNK: | ||
| 247 | if (!v9fs_extended(v9ses)) { | ||
| 248 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
| 249 | "extended modes used w/o 9P2000.u\n"); | ||
| 250 | err = -EINVAL; | ||
| 251 | goto error; | ||
| 252 | } | ||
| 253 | inode->i_op = &v9fs_symlink_inode_operations; | ||
| 254 | break; | ||
| 255 | case S_IFDIR: | ||
| 256 | inc_nlink(inode); | ||
| 257 | if (v9fs_extended(v9ses)) | ||
| 258 | inode->i_op = &v9fs_dir_inode_operations_ext; | ||
| 259 | else | ||
| 260 | inode->i_op = &v9fs_dir_inode_operations; | ||
| 261 | inode->i_fop = &v9fs_dir_operations; | ||
| 262 | break; | ||
| 263 | default: | ||
| 264 | P9_DPRINTK(P9_DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n", | ||
| 265 | mode, mode & S_IFMT); | ||
| 266 | err = -EINVAL; | ||
| 267 | goto error; | ||
| 268 | } | ||
| 269 | |||
| 268 | return inode; | 270 | return inode; |
| 271 | |||
| 272 | error: | ||
| 273 | iput(inode); | ||
| 274 | return ERR_PTR(err); | ||
| 269 | } | 275 | } |
| 270 | 276 | ||
| 271 | /* | 277 | /* |
| @@ -338,30 +344,25 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | |||
| 338 | 344 | ||
| 339 | ret = NULL; | 345 | ret = NULL; |
| 340 | st = p9_client_stat(fid); | 346 | st = p9_client_stat(fid); |
| 341 | if (IS_ERR(st)) { | 347 | if (IS_ERR(st)) |
| 342 | err = PTR_ERR(st); | 348 | return ERR_CAST(st); |
| 343 | st = NULL; | ||
| 344 | goto error; | ||
| 345 | } | ||
| 346 | 349 | ||
| 347 | umode = p9mode2unixmode(v9ses, st->mode); | 350 | umode = p9mode2unixmode(v9ses, st->mode); |
| 348 | ret = v9fs_get_inode(sb, umode); | 351 | ret = v9fs_get_inode(sb, umode); |
| 349 | if (IS_ERR(ret)) { | 352 | if (IS_ERR(ret)) { |
| 350 | err = PTR_ERR(ret); | 353 | err = PTR_ERR(ret); |
| 351 | ret = NULL; | ||
| 352 | goto error; | 354 | goto error; |
| 353 | } | 355 | } |
| 354 | 356 | ||
| 355 | v9fs_stat2inode(st, ret, sb); | 357 | v9fs_stat2inode(st, ret, sb); |
| 356 | ret->i_ino = v9fs_qid2ino(&st->qid); | 358 | ret->i_ino = v9fs_qid2ino(&st->qid); |
| 359 | p9stat_free(st); | ||
| 357 | kfree(st); | 360 | kfree(st); |
| 358 | return ret; | 361 | return ret; |
| 359 | 362 | ||
| 360 | error: | 363 | error: |
| 364 | p9stat_free(st); | ||
| 361 | kfree(st); | 365 | kfree(st); |
| 362 | if (ret) | ||
| 363 | iput(ret); | ||
| 364 | |||
| 365 | return ERR_PTR(err); | 366 | return ERR_PTR(err); |
| 366 | } | 367 | } |
| 367 | 368 | ||
| @@ -403,9 +404,9 @@ v9fs_open_created(struct inode *inode, struct file *file) | |||
| 403 | * @v9ses: session information | 404 | * @v9ses: session information |
| 404 | * @dir: directory that dentry is being created in | 405 | * @dir: directory that dentry is being created in |
| 405 | * @dentry: dentry that is being created | 406 | * @dentry: dentry that is being created |
| 407 | * @extension: 9p2000.u extension string to support devices, etc. | ||
| 406 | * @perm: create permissions | 408 | * @perm: create permissions |
| 407 | * @mode: open mode | 409 | * @mode: open mode |
| 408 | * @extension: 9p2000.u extension string to support devices, etc. | ||
| 409 | * | 410 | * |
| 410 | */ | 411 | */ |
| 411 | static struct p9_fid * | 412 | static struct p9_fid * |
| @@ -470,7 +471,10 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
| 470 | dentry->d_op = &v9fs_dentry_operations; | 471 | dentry->d_op = &v9fs_dentry_operations; |
| 471 | 472 | ||
| 472 | d_instantiate(dentry, inode); | 473 | d_instantiate(dentry, inode); |
| 473 | v9fs_fid_add(dentry, fid); | 474 | err = v9fs_fid_add(dentry, fid); |
| 475 | if (err < 0) | ||
| 476 | goto error; | ||
| 477 | |||
| 474 | return ofid; | 478 | return ofid; |
| 475 | 479 | ||
| 476 | error: | 480 | error: |
