1 /* 2 * linux/fs/9p/vfs_inode.c 3 * 4 * This file contains vfs inode ops for the 9P2000 protocol. 5 * 6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 11 * as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to: 20 * Free Software Foundation 21 * 51 Franklin Street, Fifth Floor 22 * Boston, MA 02111-1301 USA 23 * 24 */ 25 26 #include <linux/module.h> 27 #include <linux/errno.h> 28 #include <linux/fs.h> 29 #include <linux/file.h> 30 #include <linux/pagemap.h> 31 #include <linux/stat.h> 32 #include <linux/string.h> 33 #include <linux/inet.h> 34 #include <linux/namei.h> 35 #include <linux/idr.h> 36 #include <linux/sched.h> 37 #include <linux/slab.h> 38 #include <linux/xattr.h> 39 #include <net/9p/9p.h> 40 #include <net/9p/client.h> 41 42 #include "v9fs.h" 43 #include "v9fs_vfs.h" 44 #include "fid.h" 45 #include "cache.h" 46 #include "xattr.h" 47 48 static const struct inode_operations v9fs_dir_inode_operations; 49 static const struct inode_operations v9fs_dir_inode_operations_dotu; 50 static const struct inode_operations v9fs_dir_inode_operations_dotl; 51 static const struct inode_operations v9fs_file_inode_operations; 52 static const struct inode_operations v9fs_file_inode_operations_dotl; 53 static const struct inode_operations v9fs_symlink_inode_operations; 54 static const struct inode_operations v9fs_symlink_inode_operations_dotl; 55 56 /** 57 * unixmode2p9mode - convert unix mode bits to plan 9 58 * @v9ses: v9fs session information 59 * @mode: mode to convert 60 * 61 */ 62 63 static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode) 64 { 65 int res; 66 res = mode & 0777; 67 if (S_ISDIR(mode)) 68 res |= P9_DMDIR; 69 if (v9fs_proto_dotu(v9ses)) { 70 if (S_ISLNK(mode)) 71 res |= P9_DMSYMLINK; 72 if (v9ses->nodev == 0) { 73 if (S_ISSOCK(mode)) 74 res |= P9_DMSOCKET; 75 if (S_ISFIFO(mode)) 76 res |= P9_DMNAMEDPIPE; 77 if (S_ISBLK(mode)) 78 res |= P9_DMDEVICE; 79 if (S_ISCHR(mode)) 80 res |= P9_DMDEVICE; 81 } 82 83 if ((mode & S_ISUID) == S_ISUID) 84 res |= P9_DMSETUID; 85 if ((mode & S_ISGID) == S_ISGID) 86 res |= P9_DMSETGID; 87 if ((mode & S_ISVTX) == S_ISVTX) 88 res |= P9_DMSETVTX; 89 if ((mode & P9_DMLINK)) 90 res |= P9_DMLINK; 91 } 92 93 return res; 94 } 95 96 /** 97 * p9mode2unixmode- convert plan9 mode bits to unix mode bits 98 * @v9ses: v9fs session information 99 * @mode: mode to convert 100 * 101 */ 102 103 static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) 104 { 105 int res; 106 107 res = mode & 0777; 108 109 if ((mode & P9_DMDIR) == P9_DMDIR) 110 res |= S_IFDIR; 111 else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses))) 112 res |= S_IFLNK; 113 else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses)) 114 && (v9ses->nodev == 0)) 115 res |= S_IFSOCK; 116 else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses)) 117 && (v9ses->nodev == 0)) 118 res |= S_IFIFO; 119 else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses)) 120 && (v9ses->nodev == 0)) 121 res |= S_IFBLK; 122 else 123 res |= S_IFREG; 124 125 if (v9fs_proto_dotu(v9ses)) { 126 if ((mode & P9_DMSETUID) == P9_DMSETUID) 127 res |= S_ISUID; 128 129 if ((mode & P9_DMSETGID) == P9_DMSETGID) 130 res |= S_ISGID; 131 132 if ((mode & P9_DMSETVTX) == P9_DMSETVTX) 133 res |= S_ISVTX; 134 } 135 136 return res; 137 } 138 139 /** 140 * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits 141 * @uflags: flags to convert 142 * @extended: if .u extensions are active 143 */ 144 145 int v9fs_uflags2omode(int uflags, int extended) 146 { 147 int ret; 148 149 ret = 0; 150 switch (uflags&3) { 151 default: 152 case O_RDONLY: 153 ret = P9_OREAD; 154 break; 155 156 case O_WRONLY: 157 ret = P9_OWRITE; 158 break; 159 160 case O_RDWR: 161 ret = P9_ORDWR; 162 break; 163 } 164 165 if (uflags & O_TRUNC) 166 ret |= P9_OTRUNC; 167 168 if (extended) { 169 if (uflags & O_EXCL) 170 ret |= P9_OEXCL; 171 172 if (uflags & O_APPEND) 173 ret |= P9_OAPPEND; 174 } 175 176 return ret; 177 } 178 179 /** 180 * v9fs_blank_wstat - helper function to setup a 9P stat structure 181 * @wstat: structure to initialize 182 * 183 */ 184 185 void 186 v9fs_blank_wstat(struct p9_wstat *wstat) 187 { 188 wstat->type = ~0; 189 wstat->dev = ~0; 190 wstat->qid.type = ~0; 191 wstat->qid.version = ~0; 192 *((long long *)&wstat->qid.path) = ~0; 193 wstat->mode = ~0; 194 wstat->atime = ~0; 195 wstat->mtime = ~0; 196 wstat->length = ~0; 197 wstat->name = NULL; 198 wstat->uid = NULL; 199 wstat->gid = NULL; 200 wstat->muid = NULL; 201 wstat->n_uid = ~0; 202 wstat->n_gid = ~0; 203 wstat->n_muid = ~0; 204 wstat->extension = NULL; 205 } 206 207 #ifdef CONFIG_9P_FSCACHE 208 /** 209 * v9fs_alloc_inode - helper function to allocate an inode 210 * This callback is executed before setting up the inode so that we 211 * can associate a vcookie with each inode. 212 * 213 */ 214 215 struct inode *v9fs_alloc_inode(struct super_block *sb) 216 { 217 struct v9fs_cookie *vcookie; 218 vcookie = (struct v9fs_cookie *)kmem_cache_alloc(vcookie_cache, 219 GFP_KERNEL); 220 if (!vcookie) 221 return NULL; 222 223 vcookie->fscache = NULL; 224 vcookie->qid = NULL; 225 spin_lock_init(&vcookie->lock); 226 return &vcookie->inode; 227 } 228 229 /** 230 * v9fs_destroy_inode - destroy an inode 231 * 232 */ 233 234 void v9fs_destroy_inode(struct inode *inode) 235 { 236 kmem_cache_free(vcookie_cache, v9fs_inode2cookie(inode)); 237 } 238 #endif 239 240 /** 241 * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a 242 * new file system object. This checks the S_ISGID to determine the owning 243 * group of the new file system object. 244 */ 245 246 static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) 247 { 248 BUG_ON(dir_inode == NULL); 249 250 if (dir_inode->i_mode & S_ISGID) { 251 /* set_gid bit is set.*/ 252 return dir_inode->i_gid; 253 } 254 return current_fsgid(); 255 } 256 257 /** 258 * v9fs_dentry_from_dir_inode - helper function to get the dentry from 259 * dir inode. 260 * 261 */ 262 263 static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode) 264 { 265 struct dentry *dentry; 266 267 spin_lock(&dcache_lock); 268 /* Directory should have only one entry. */ 269 BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry)); 270 dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias); 271 spin_unlock(&dcache_lock); 272 return dentry; 273 } 274 275 /** 276 * v9fs_get_inode - helper function to setup an inode 277 * @sb: superblock 278 * @mode: mode to setup inode with 279 * 280 */ 281 282 struct inode *v9fs_get_inode(struct super_block *sb, int mode) 283 { 284 int err; 285 struct inode *inode; 286 struct v9fs_session_info *v9ses = sb->s_fs_info; 287 288 P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); 289 290 inode = new_inode(sb); 291 if (!inode) { 292 P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); 293 return ERR_PTR(-ENOMEM); 294 } 295 296 inode_init_owner(inode, NULL, mode); 297 inode->i_blocks = 0; 298 inode->i_rdev = 0; 299 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 300 inode->i_mapping->a_ops = &v9fs_addr_operations; 301 302 switch (mode & S_IFMT) { 303 case S_IFIFO: 304 case S_IFBLK: 305 case S_IFCHR: 306 case S_IFSOCK: 307 if (v9fs_proto_dotl(v9ses)) { 308 inode->i_op = &v9fs_file_inode_operations_dotl; 309 inode->i_fop = &v9fs_file_operations_dotl; 310 } else if (v9fs_proto_dotu(v9ses)) { 311 inode->i_op = &v9fs_file_inode_operations; 312 inode->i_fop = &v9fs_file_operations; 313 } else { 314 P9_DPRINTK(P9_DEBUG_ERROR, 315 "special files without extended mode\n"); 316 err = -EINVAL; 317 goto error; 318 } 319 init_special_inode(inode, inode->i_mode, inode->i_rdev); 320 break; 321 case S_IFREG: 322 if (v9fs_proto_dotl(v9ses)) { 323 inode->i_op = &v9fs_file_inode_operations_dotl; 324 inode->i_fop = &v9fs_file_operations_dotl; 325 } else { 326 inode->i_op = &v9fs_file_inode_operations; 327 inode->i_fop = &v9fs_file_operations; 328 } 329 330 break; 331 332 case S_IFLNK: 333 if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) { 334 P9_DPRINTK(P9_DEBUG_ERROR, "extended modes used with " 335 "legacy protocol.\n"); 336 err = -EINVAL; 337 goto error; 338 } 339 340 if (v9fs_proto_dotl(v9ses)) 341 inode->i_op = &v9fs_symlink_inode_operations_dotl; 342 else 343 inode->i_op = &v9fs_symlink_inode_operations; 344 345 break; 346 case S_IFDIR: 347 inc_nlink(inode); 348 if (v9fs_proto_dotl(v9ses)) 349 inode->i_op = &v9fs_dir_inode_operations_dotl; 350 else if (v9fs_proto_dotu(v9ses)) 351 inode->i_op = &v9fs_dir_inode_operations_dotu; 352 else 353 inode->i_op = &v9fs_dir_inode_operations; 354 355 if (v9fs_proto_dotl(v9ses)) 356 inode->i_fop = &v9fs_dir_operations_dotl; 357 else 358 inode->i_fop = &v9fs_dir_operations; 359 360 break; 361 default: 362 P9_DPRINTK(P9_DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n", 363 mode, mode & S_IFMT); 364 err = -EINVAL; 365 goto error; 366 } 367 368 return inode; 369 370 error: 371 iput(inode); 372 return ERR_PTR(err); 373 } 374 375 /* 376 static struct v9fs_fid* 377 v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) 378 { 379 int err; 380 int nfid; 381 struct v9fs_fid *ret; 382 struct v9fs_fcall *fcall; 383 384 nfid = v9fs_get_idpool(&v9ses->fidpool); 385 if (nfid < 0) { 386 eprintk(KERN_WARNING, "no free fids available\n"); 387 return ERR_PTR(-ENOSPC); 388 } 389 390 err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name, 391 &fcall); 392 393 if (err < 0) { 394 if (fcall && fcall->id == RWALK) 395 goto clunk_fid; 396 397 PRINT_FCALL_ERROR("walk error", fcall); 398 v9fs_put_idpool(nfid, &v9ses->fidpool); 399 goto error; 400 } 401 402 kfree(fcall); 403 fcall = NULL; 404 ret = v9fs_fid_create(v9ses, nfid); 405 if (!ret) { 406 err = -ENOMEM; 407 goto clunk_fid; 408 } 409 410 err = v9fs_fid_insert(ret, dentry); 411 if (err < 0) { 412 v9fs_fid_destroy(ret); 413 goto clunk_fid; 414 } 415 416 return ret; 417 418 clunk_fid: 419 v9fs_t_clunk(v9ses, nfid); 420 421 error: 422 kfree(fcall); 423 return ERR_PTR(err); 424 } 425 */ 426 427 428 /** 429 * v9fs_clear_inode - release an inode 430 * @inode: inode to release 431 * 432 */ 433 void v9fs_evict_inode(struct inode *inode) 434 { 435 truncate_inode_pages(inode->i_mapping, 0); 436 end_writeback(inode); 437 filemap_fdatawrite(inode->i_mapping); 438 439 #ifdef CONFIG_9P_FSCACHE 440 v9fs_cache_inode_put_cookie(inode); 441 #endif 442 } 443 444 static struct inode * 445 v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid, 446 struct super_block *sb) 447 { 448 int err, umode; 449 struct inode *ret = NULL; 450 struct p9_wstat *st; 451 452 st = p9_client_stat(fid); 453 if (IS_ERR(st)) 454 return ERR_CAST(st); 455 456 umode = p9mode2unixmode(v9ses, st->mode); 457 ret = v9fs_get_inode(sb, umode); 458 if (IS_ERR(ret)) { 459 err = PTR_ERR(ret); 460 goto error; 461 } 462 463 v9fs_stat2inode(st, ret, sb); 464 ret->i_ino = v9fs_qid2ino(&st->qid); 465 466 #ifdef CONFIG_9P_FSCACHE 467 v9fs_vcookie_set_qid(ret, &st->qid); 468 v9fs_cache_inode_get_cookie(ret); 469 #endif 470 p9stat_free(st); 471 kfree(st); 472 return ret; 473 error: 474 p9stat_free(st); 475 kfree(st); 476 return ERR_PTR(err); 477 } 478 479 static struct inode * 480 v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, 481 struct super_block *sb) 482 { 483 struct inode *ret = NULL; 484 int err; 485 struct p9_stat_dotl *st; 486 487 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); 488 if (IS_ERR(st)) 489 return ERR_CAST(st); 490 491 ret = v9fs_get_inode(sb, st->st_mode); 492 if (IS_ERR(ret)) { 493 err = PTR_ERR(ret); 494 goto error; 495 } 496 497 v9fs_stat2inode_dotl(st, ret); 498 ret->i_ino = v9fs_qid2ino(&st->qid); 499 #ifdef CONFIG_9P_FSCACHE 500 v9fs_vcookie_set_qid(ret, &st->qid); 501 v9fs_cache_inode_get_cookie(ret); 502 #endif 503 kfree(st); 504 return ret; 505 error: 506 kfree(st); 507 return ERR_PTR(err); 508 } 509 510 /** 511 * v9fs_inode_from_fid - Helper routine to populate an inode by 512 * issuing a attribute request 513 * @v9ses: session information 514 * @fid: fid to issue attribute request for 515 * @sb: superblock on which to create inode 516 * 517 */ 518 static inline struct inode * 519 v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, 520 struct super_block *sb) 521 { 522 if (v9fs_proto_dotl(v9ses)) 523 return v9fs_inode_dotl(v9ses, fid, sb); 524 else 525 return v9fs_inode(v9ses, fid, sb); 526 } 527 528 /** 529 * v9fs_remove - helper function to remove files and directories 530 * @dir: directory inode that is being deleted 531 * @file: dentry that is being deleted 532 * @rmdir: removing a directory 533 * 534 */ 535 536 static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) 537 { 538 int retval; 539 struct inode *file_inode; 540 struct p9_fid *v9fid; 541 542 P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, 543 rmdir); 544 545 file_inode = file->d_inode; 546 v9fid = v9fs_fid_clone(file); 547 if (IS_ERR(v9fid)) 548 return PTR_ERR(v9fid); 549 550 retval = p9_client_remove(v9fid); 551 if (!retval) 552 drop_nlink(file_inode); 553 return retval; 554 } 555 556 static int 557 v9fs_open_created(struct inode *inode, struct file *file) 558 { 559 return 0; 560 } 561 562 563 /** 564 * v9fs_create - Create a file 565 * @v9ses: session information 566 * @dir: directory that dentry is being created in 567 * @dentry: dentry that is being created 568 * @extension: 9p2000.u extension string to support devices, etc. 569 * @perm: create permissions 570 * @mode: open mode 571 * 572 */ 573 static struct p9_fid * 574 v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, 575 struct dentry *dentry, char *extension, u32 perm, u8 mode) 576 { 577 int err; 578 char *name; 579 struct p9_fid *dfid, *ofid, *fid; 580 struct inode *inode; 581 582 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 583 584 err = 0; 585 ofid = NULL; 586 fid = NULL; 587 name = (char *) dentry->d_name.name; 588 dfid = v9fs_fid_lookup(dentry->d_parent); 589 if (IS_ERR(dfid)) { 590 err = PTR_ERR(dfid); 591 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 592 return ERR_PTR(err); 593 } 594 595 /* clone a fid to use for creation */ 596 ofid = p9_client_walk(dfid, 0, NULL, 1); 597 if (IS_ERR(ofid)) { 598 err = PTR_ERR(ofid); 599 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 600 return ERR_PTR(err); 601 } 602 603 err = p9_client_fcreate(ofid, name, perm, mode, extension); 604 if (err < 0) { 605 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err); 606 goto error; 607 } 608 609 /* now walk from the parent so we can get unopened fid */ 610 fid = p9_client_walk(dfid, 1, &name, 1); 611 if (IS_ERR(fid)) { 612 err = PTR_ERR(fid); 613 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 614 fid = NULL; 615 goto error; 616 } 617 618 /* instantiate inode and assign the unopened fid to the dentry */ 619 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 620 if (IS_ERR(inode)) { 621 err = PTR_ERR(inode); 622 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 623 goto error; 624 } 625 626 if (v9ses->cache) 627 dentry->d_op = &v9fs_cached_dentry_operations; 628 else 629 dentry->d_op = &v9fs_dentry_operations; 630 631 d_instantiate(dentry, inode); 632 err = v9fs_fid_add(dentry, fid); 633 if (err < 0) 634 goto error; 635 636 return ofid; 637 638 error: 639 if (ofid) 640 p9_client_clunk(ofid); 641 642 if (fid) 643 p9_client_clunk(fid); 644 645 return ERR_PTR(err); 646 } 647 648 /** 649 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol. 650 * @dir: directory inode that is being created 651 * @dentry: dentry that is being deleted 652 * @mode: create permissions 653 * @nd: path information 654 * 655 */ 656 657 static int 658 v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode, 659 struct nameidata *nd) 660 { 661 int err = 0; 662 char *name = NULL; 663 gid_t gid; 664 int flags; 665 struct v9fs_session_info *v9ses; 666 struct p9_fid *fid = NULL; 667 struct p9_fid *dfid, *ofid; 668 struct file *filp; 669 struct p9_qid qid; 670 struct inode *inode; 671 672 v9ses = v9fs_inode2v9ses(dir); 673 if (nd && nd->flags & LOOKUP_OPEN) 674 flags = nd->intent.open.flags - 1; 675 else 676 flags = O_RDWR; 677 678 name = (char *) dentry->d_name.name; 679 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x " 680 "mode:0x%x\n", name, flags, mode); 681 682 dfid = v9fs_fid_lookup(dentry->d_parent); 683 if (IS_ERR(dfid)) { 684 err = PTR_ERR(dfid); 685 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 686 return err; 687 } 688 689 /* clone a fid to use for creation */ 690 ofid = p9_client_walk(dfid, 0, NULL, 1); 691 if (IS_ERR(ofid)) { 692 err = PTR_ERR(ofid); 693 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 694 return err; 695 } 696 697 gid = v9fs_get_fsgid_for_create(dir); 698 err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid); 699 if (err < 0) { 700 P9_DPRINTK(P9_DEBUG_VFS, 701 "p9_client_open_dotl failed in creat %d\n", 702 err); 703 goto error; 704 } 705 706 /* No need to populate the inode if we are not opening the file AND 707 * not in cached mode. 708 */ 709 if (!v9ses->cache && !(nd && nd->flags & LOOKUP_OPEN)) { 710 /* Not in cached mode. No need to populate inode with stat */ 711 dentry->d_op = &v9fs_dentry_operations; 712 p9_client_clunk(ofid); 713 d_instantiate(dentry, NULL); 714 return 0; 715 } 716 717 /* Now walk from the parent so we can get an unopened fid. */ 718 fid = p9_client_walk(dfid, 1, &name, 1); 719 if (IS_ERR(fid)) { 720 err = PTR_ERR(fid); 721 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 722 fid = NULL; 723 goto error; 724 } 725 726 /* instantiate inode and assign the unopened fid to dentry */ 727 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 728 if (IS_ERR(inode)) { 729 err = PTR_ERR(inode); 730 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 731 goto error; 732 } 733 dentry->d_op = &v9fs_cached_dentry_operations; 734 d_instantiate(dentry, inode); 735 err = v9fs_fid_add(dentry, fid); 736 if (err < 0) 737 goto error; 738 739 /* if we are opening a file, assign the open fid to the file */ 740 if (nd && nd->flags & LOOKUP_OPEN) { 741 filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); 742 if (IS_ERR(filp)) { 743 p9_client_clunk(ofid); 744 return PTR_ERR(filp); 745 } 746 filp->private_data = ofid; 747 } else 748 p9_client_clunk(ofid); 749 750 return 0; 751 752 error: 753 if (ofid) 754 p9_client_clunk(ofid); 755 if (fid) 756 p9_client_clunk(fid); 757 return err; 758 } 759 760 /** 761 * v9fs_vfs_create - VFS hook to create files 762 * @dir: directory inode that is being created 763 * @dentry: dentry that is being deleted 764 * @mode: create permissions 765 * @nd: path information 766 * 767 */ 768 769 static int 770 v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, 771 struct nameidata *nd) 772 { 773 int err; 774 u32 perm; 775 int flags; 776 struct v9fs_session_info *v9ses; 777 struct p9_fid *fid; 778 struct file *filp; 779 780 err = 0; 781 fid = NULL; 782 v9ses = v9fs_inode2v9ses(dir); 783 perm = unixmode2p9mode(v9ses, mode); 784 if (nd && nd->flags & LOOKUP_OPEN) 785 flags = nd->intent.open.flags - 1; 786 else 787 flags = O_RDWR; 788 789 fid = v9fs_create(v9ses, dir, dentry, NULL, perm, 790 v9fs_uflags2omode(flags, 791 v9fs_proto_dotu(v9ses))); 792 if (IS_ERR(fid)) { 793 err = PTR_ERR(fid); 794 fid = NULL; 795 goto error; 796 } 797 798 /* if we are opening a file, assign the open fid to the file */ 799 if (nd && nd->flags & LOOKUP_OPEN) { 800 filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); 801 if (IS_ERR(filp)) { 802 err = PTR_ERR(filp); 803 goto error; 804 } 805 806 filp->private_data = fid; 807 } else 808 p9_client_clunk(fid); 809 810 return 0; 811 812 error: 813 if (fid) 814 p9_client_clunk(fid); 815 816 return err; 817 } 818 819 /** 820 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory 821 * @dir: inode that is being unlinked 822 * @dentry: dentry that is being unlinked 823 * @mode: mode for new directory 824 * 825 */ 826 827 static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 828 { 829 int err; 830 u32 perm; 831 struct v9fs_session_info *v9ses; 832 struct p9_fid *fid; 833 834 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 835 err = 0; 836 v9ses = v9fs_inode2v9ses(dir); 837 perm = unixmode2p9mode(v9ses, mode | S_IFDIR); 838 fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD); 839 if (IS_ERR(fid)) { 840 err = PTR_ERR(fid); 841 fid = NULL; 842 } 843 844 if (fid) 845 p9_client_clunk(fid); 846 847 return err; 848 } 849 850 851 /** 852 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory 853 * @dir: inode that is being unlinked 854 * @dentry: dentry that is being unlinked 855 * @mode: mode for new directory 856 * 857 */ 858 859 static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry, 860 int mode) 861 { 862 int err; 863 struct v9fs_session_info *v9ses; 864 struct p9_fid *fid = NULL, *dfid = NULL; 865 gid_t gid; 866 char *name; 867 struct inode *inode; 868 struct p9_qid qid; 869 struct dentry *dir_dentry; 870 871 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 872 err = 0; 873 v9ses = v9fs_inode2v9ses(dir); 874 875 mode |= S_IFDIR; 876 dir_dentry = v9fs_dentry_from_dir_inode(dir); 877 dfid = v9fs_fid_lookup(dir_dentry); 878 if (IS_ERR(dfid)) { 879 err = PTR_ERR(dfid); 880 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 881 dfid = NULL; 882 goto error; 883 } 884 885 gid = v9fs_get_fsgid_for_create(dir); 886 if (gid < 0) { 887 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_fsgid_for_create failed\n"); 888 goto error; 889 } 890 891 name = (char *) dentry->d_name.name; 892 err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid); 893 if (err < 0) 894 goto error; 895 896 /* instantiate inode and assign the unopened fid to the dentry */ 897 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 898 fid = p9_client_walk(dfid, 1, &name, 1); 899 if (IS_ERR(fid)) { 900 err = PTR_ERR(fid); 901 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 902 err); 903 fid = NULL; 904 goto error; 905 } 906 907 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 908 if (IS_ERR(inode)) { 909 err = PTR_ERR(inode); 910 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 911 err); 912 goto error; 913 } 914 dentry->d_op = &v9fs_cached_dentry_operations; 915 d_instantiate(dentry, inode); 916 err = v9fs_fid_add(dentry, fid); 917 if (err < 0) 918 goto error; 919 fid = NULL; 920 } 921 error: 922 if (fid) 923 p9_client_clunk(fid); 924 return err; 925 } 926 927 /** 928 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode 929 * @dir: inode that is being walked from 930 * @dentry: dentry that is being walked to? 931 * @nameidata: path data 932 * 933 */ 934 935 static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, 936 struct nameidata *nameidata) 937 { 938 struct super_block *sb; 939 struct v9fs_session_info *v9ses; 940 struct p9_fid *dfid, *fid; 941 struct inode *inode; 942 char *name; 943 int result = 0; 944 945 P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", 946 dir, dentry->d_name.name, dentry, nameidata); 947 948 if (dentry->d_name.len > NAME_MAX) 949 return ERR_PTR(-ENAMETOOLONG); 950 951 sb = dir->i_sb; 952 v9ses = v9fs_inode2v9ses(dir); 953 /* We can walk d_parent because we hold the dir->i_mutex */ 954 dfid = v9fs_fid_lookup(dentry->d_parent); 955 if (IS_ERR(dfid)) 956 return ERR_CAST(dfid); 957 958 name = (char *) dentry->d_name.name; 959 fid = p9_client_walk(dfid, 1, &name, 1); 960 if (IS_ERR(fid)) { 961 result = PTR_ERR(fid); 962 if (result == -ENOENT) { 963 inode = NULL; 964 goto inst_out; 965 } 966 967 return ERR_PTR(result); 968 } 969 970 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 971 if (IS_ERR(inode)) { 972 result = PTR_ERR(inode); 973 inode = NULL; 974 goto error; 975 } 976 977 result = v9fs_fid_add(dentry, fid); 978 if (result < 0) 979 goto error; 980 981 inst_out: 982 if (v9ses->cache) 983 dentry->d_op = &v9fs_cached_dentry_operations; 984 else 985 dentry->d_op = &v9fs_dentry_operations; 986 987 d_add(dentry, inode); 988 return NULL; 989 990 error: 991 p9_client_clunk(fid); 992 993 return ERR_PTR(result); 994 } 995 996 /** 997 * v9fs_vfs_unlink - VFS unlink hook to delete an inode 998 * @i: inode that is being unlinked 999 * @d: dentry that is being unlinked 1000 * 1001 */ 1002 1003 static int v9fs_vfs_unlink(struct inode *i, struct dentry *d) 1004 { 1005 return v9fs_remove(i, d, 0); 1006 } 1007 1008 /** 1009 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory 1010 * @i: inode that is being unlinked 1011 * @d: dentry that is being unlinked 1012 * 1013 */ 1014 1015 static int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) 1016 { 1017 return v9fs_remove(i, d, 1); 1018 } 1019 1020 /** 1021 * v9fs_vfs_rename - VFS hook to rename an inode 1022 * @old_dir: old dir inode 1023 * @old_dentry: old dentry 1024 * @new_dir: new dir inode 1025 * @new_dentry: new dentry 1026 * 1027 */ 1028 1029 static int 1030 v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, 1031 struct inode *new_dir, struct dentry *new_dentry) 1032 { 1033 struct inode *old_inode; 1034 struct v9fs_session_info *v9ses; 1035 struct p9_fid *oldfid; 1036 struct p9_fid *olddirfid; 1037 struct p9_fid *newdirfid; 1038 struct p9_wstat wstat; 1039 int retval; 1040 1041 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 1042 retval = 0; 1043 old_inode = old_dentry->d_inode; 1044 v9ses = v9fs_inode2v9ses(old_inode); 1045 oldfid = v9fs_fid_lookup(old_dentry); 1046 if (IS_ERR(oldfid)) 1047 return PTR_ERR(oldfid); 1048 1049 olddirfid = v9fs_fid_clone(old_dentry->d_parent); 1050 if (IS_ERR(olddirfid)) { 1051 retval = PTR_ERR(olddirfid); 1052 goto done; 1053 } 1054 1055 newdirfid = v9fs_fid_clone(new_dentry->d_parent); 1056 if (IS_ERR(newdirfid)) { 1057 retval = PTR_ERR(newdirfid); 1058 goto clunk_olddir; 1059 } 1060 1061 down_write(&v9ses->rename_sem); 1062 if (v9fs_proto_dotl(v9ses)) { 1063 retval = p9_client_rename(oldfid, newdirfid, 1064 (char *) new_dentry->d_name.name); 1065 if (retval != -ENOSYS) 1066 goto clunk_newdir; 1067 } 1068 if (old_dentry->d_parent != new_dentry->d_parent) { 1069 /* 1070 * 9P .u can only handle file rename in the same directory 1071 */ 1072 1073 P9_DPRINTK(P9_DEBUG_ERROR, 1074 "old dir and new dir are different\n"); 1075 retval = -EXDEV; 1076 goto clunk_newdir; 1077 } 1078 v9fs_blank_wstat(&wstat); 1079 wstat.muid = v9ses->uname; 1080 wstat.name = (char *) new_dentry->d_name.name; 1081 retval = p9_client_wstat(oldfid, &wstat); 1082 1083 clunk_newdir: 1084 if (!retval) 1085 /* successful rename */ 1086 d_move(old_dentry, new_dentry); 1087 up_write(&v9ses->rename_sem); 1088 p9_client_clunk(newdirfid); 1089 1090 clunk_olddir: 1091 p9_client_clunk(olddirfid); 1092 1093 done: 1094 return retval; 1095 } 1096 1097 /** 1098 * v9fs_vfs_getattr - retrieve file metadata 1099 * @mnt: mount information 1100 * @dentry: file to get attributes on 1101 * @stat: metadata structure to populate 1102 * 1103 */ 1104 1105 static int 1106 v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 1107 struct kstat *stat) 1108 { 1109 int err; 1110 struct v9fs_session_info *v9ses; 1111 struct p9_fid *fid; 1112 struct p9_wstat *st; 1113 1114 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 1115 err = -EPERM; 1116 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1117 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) 1118 return simple_getattr(mnt, dentry, stat); 1119 1120 fid = v9fs_fid_lookup(dentry); 1121 if (IS_ERR(fid)) 1122 return PTR_ERR(fid); 1123 1124 st = p9_client_stat(fid); 1125 if (IS_ERR(st)) 1126 return PTR_ERR(st); 1127 1128 v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); 1129 generic_fillattr(dentry->d_inode, stat); 1130 1131 kfree(st); 1132 return 0; 1133 } 1134 1135 static int 1136 v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry, 1137 struct kstat *stat) 1138 { 1139 int err; 1140 struct v9fs_session_info *v9ses; 1141 struct p9_fid *fid; 1142 struct p9_stat_dotl *st; 1143 1144 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 1145 err = -EPERM; 1146 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1147 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) 1148 return simple_getattr(mnt, dentry, stat); 1149 1150 fid = v9fs_fid_lookup(dentry); 1151 if (IS_ERR(fid)) 1152 return PTR_ERR(fid); 1153 1154 /* Ask for all the fields in stat structure. Server will return 1155 * whatever it supports 1156 */ 1157 1158 st = p9_client_getattr_dotl(fid, P9_STATS_ALL); 1159 if (IS_ERR(st)) 1160 return PTR_ERR(st); 1161 1162 v9fs_stat2inode_dotl(st, dentry->d_inode); 1163 generic_fillattr(dentry->d_inode, stat); 1164 /* Change block size to what the server returned */ 1165 stat->blksize = st->st_blksize; 1166 1167 kfree(st); 1168 return 0; 1169 } 1170 1171 /** 1172 * v9fs_vfs_setattr - set file metadata 1173 * @dentry: file whose metadata to set 1174 * @iattr: metadata assignment structure 1175 * 1176 */ 1177 1178 static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) 1179 { 1180 int retval; 1181 struct v9fs_session_info *v9ses; 1182 struct p9_fid *fid; 1183 struct p9_wstat wstat; 1184 1185 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 1186 retval = -EPERM; 1187 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1188 fid = v9fs_fid_lookup(dentry); 1189 if(IS_ERR(fid)) 1190 return PTR_ERR(fid); 1191 1192 v9fs_blank_wstat(&wstat); 1193 if (iattr->ia_valid & ATTR_MODE) 1194 wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode); 1195 1196 if (iattr->ia_valid & ATTR_MTIME) 1197 wstat.mtime = iattr->ia_mtime.tv_sec; 1198 1199 if (iattr->ia_valid & ATTR_ATIME) 1200 wstat.atime = iattr->ia_atime.tv_sec; 1201 1202 if (iattr->ia_valid & ATTR_SIZE) 1203 wstat.length = iattr->ia_size; 1204 1205 if (v9fs_proto_dotu(v9ses)) { 1206 if (iattr->ia_valid & ATTR_UID) 1207 wstat.n_uid = iattr->ia_uid; 1208 1209 if (iattr->ia_valid & ATTR_GID) 1210 wstat.n_gid = iattr->ia_gid; 1211 } 1212 1213 retval = p9_client_wstat(fid, &wstat); 1214 if (retval < 0) 1215 return retval; 1216 1217 if ((iattr->ia_valid & ATTR_SIZE) && 1218 iattr->ia_size != i_size_read(dentry->d_inode)) { 1219 retval = vmtruncate(dentry->d_inode, iattr->ia_size); 1220 if (retval) 1221 return retval; 1222 } 1223 1224 setattr_copy(dentry->d_inode, iattr); 1225 mark_inode_dirty(dentry->d_inode); 1226 return 0; 1227 } 1228 1229 /** 1230 * v9fs_vfs_setattr_dotl - set file metadata 1231 * @dentry: file whose metadata to set 1232 * @iattr: metadata assignment structure 1233 * 1234 */ 1235 1236 static int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr) 1237 { 1238 int retval; 1239 struct v9fs_session_info *v9ses; 1240 struct p9_fid *fid; 1241 struct p9_iattr_dotl p9attr; 1242 1243 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 1244 1245 retval = inode_change_ok(dentry->d_inode, iattr); 1246 if (retval) 1247 return retval; 1248 1249 p9attr.valid = iattr->ia_valid; 1250 p9attr.mode = iattr->ia_mode; 1251 p9attr.uid = iattr->ia_uid; 1252 p9attr.gid = iattr->ia_gid; 1253 p9attr.size = iattr->ia_size; 1254 p9attr.atime_sec = iattr->ia_atime.tv_sec; 1255 p9attr.atime_nsec = iattr->ia_atime.tv_nsec; 1256 p9attr.mtime_sec = iattr->ia_mtime.tv_sec; 1257 p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec; 1258 1259 retval = -EPERM; 1260 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1261 fid = v9fs_fid_lookup(dentry); 1262 if (IS_ERR(fid)) 1263 return PTR_ERR(fid); 1264 1265 retval = p9_client_setattr(fid, &p9attr); 1266 if (retval < 0) 1267 return retval; 1268 1269 if ((iattr->ia_valid & ATTR_SIZE) && 1270 iattr->ia_size != i_size_read(dentry->d_inode)) { 1271 retval = vmtruncate(dentry->d_inode, iattr->ia_size); 1272 if (retval) 1273 return retval; 1274 } 1275 1276 setattr_copy(dentry->d_inode, iattr); 1277 mark_inode_dirty(dentry->d_inode); 1278 return 0; 1279 } 1280 1281 /** 1282 * v9fs_stat2inode - populate an inode structure with mistat info 1283 * @stat: Plan 9 metadata (mistat) structure 1284 * @inode: inode to populate 1285 * @sb: superblock of filesystem 1286 * 1287 */ 1288 1289 void 1290 v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode, 1291 struct super_block *sb) 1292 { 1293 char ext[32]; 1294 char tag_name[14]; 1295 unsigned int i_nlink; 1296 struct v9fs_session_info *v9ses = sb->s_fs_info; 1297 1298 inode->i_nlink = 1; 1299 1300 inode->i_atime.tv_sec = stat->atime; 1301 inode->i_mtime.tv_sec = stat->mtime; 1302 inode->i_ctime.tv_sec = stat->mtime; 1303 1304 inode->i_uid = v9ses->dfltuid; 1305 inode->i_gid = v9ses->dfltgid; 1306 1307 if (v9fs_proto_dotu(v9ses)) { 1308 inode->i_uid = stat->n_uid; 1309 inode->i_gid = stat->n_gid; 1310 } 1311 if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) { 1312 if (v9fs_proto_dotu(v9ses) && (stat->extension[0] != '\0')) { 1313 /* 1314 * Hadlink support got added later to 1315 * to the .u extension. So there can be 1316 * server out there that doesn't support 1317 * this even with .u extension. So check 1318 * for non NULL stat->extension 1319 */ 1320 strncpy(ext, stat->extension, sizeof(ext)); 1321 /* HARDLINKCOUNT %u */ 1322 sscanf(ext, "%13s %u", tag_name, &i_nlink); 1323 if (!strncmp(tag_name, "HARDLINKCOUNT", 13)) 1324 inode->i_nlink = i_nlink; 1325 } 1326 } 1327 inode->i_mode = p9mode2unixmode(v9ses, stat->mode); 1328 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) { 1329 char type = 0; 1330 int major = -1; 1331 int minor = -1; 1332 1333 strncpy(ext, stat->extension, sizeof(ext)); 1334 sscanf(ext, "%c %u %u", &type, &major, &minor); 1335 switch (type) { 1336 case 'c': 1337 inode->i_mode &= ~S_IFBLK; 1338 inode->i_mode |= S_IFCHR; 1339 break; 1340 case 'b': 1341 break; 1342 default: 1343 P9_DPRINTK(P9_DEBUG_ERROR, 1344 "Unknown special type %c %s\n", type, 1345 stat->extension); 1346 }; 1347 inode->i_rdev = MKDEV(major, minor); 1348 init_special_inode(inode, inode->i_mode, inode->i_rdev); 1349 } else 1350 inode->i_rdev = 0; 1351 1352 i_size_write(inode, stat->length); 1353 1354 /* not real number of blocks, but 512 byte ones ... */ 1355 inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9; 1356 } 1357 1358 /** 1359 * v9fs_stat2inode_dotl - populate an inode structure with stat info 1360 * @stat: stat structure 1361 * @inode: inode to populate 1362 * @sb: superblock of filesystem 1363 * 1364 */ 1365 1366 void 1367 v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode) 1368 { 1369 1370 if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) { 1371 inode->i_atime.tv_sec = stat->st_atime_sec; 1372 inode->i_atime.tv_nsec = stat->st_atime_nsec; 1373 inode->i_mtime.tv_sec = stat->st_mtime_sec; 1374 inode->i_mtime.tv_nsec = stat->st_mtime_nsec; 1375 inode->i_ctime.tv_sec = stat->st_ctime_sec; 1376 inode->i_ctime.tv_nsec = stat->st_ctime_nsec; 1377 inode->i_uid = stat->st_uid; 1378 inode->i_gid = stat->st_gid; 1379 inode->i_nlink = stat->st_nlink; 1380 inode->i_mode = stat->st_mode; 1381 inode->i_rdev = new_decode_dev(stat->st_rdev); 1382 1383 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) 1384 init_special_inode(inode, inode->i_mode, inode->i_rdev); 1385 1386 i_size_write(inode, stat->st_size); 1387 inode->i_blocks = stat->st_blocks; 1388 } else { 1389 if (stat->st_result_mask & P9_STATS_ATIME) { 1390 inode->i_atime.tv_sec = stat->st_atime_sec; 1391 inode->i_atime.tv_nsec = stat->st_atime_nsec; 1392 } 1393 if (stat->st_result_mask & P9_STATS_MTIME) { 1394 inode->i_mtime.tv_sec = stat->st_mtime_sec; 1395 inode->i_mtime.tv_nsec = stat->st_mtime_nsec; 1396 } 1397 if (stat->st_result_mask & P9_STATS_CTIME) { 1398 inode->i_ctime.tv_sec = stat->st_ctime_sec; 1399 inode->i_ctime.tv_nsec = stat->st_ctime_nsec; 1400 } 1401 if (stat->st_result_mask & P9_STATS_UID) 1402 inode->i_uid = stat->st_uid; 1403 if (stat->st_result_mask & P9_STATS_GID) 1404 inode->i_gid = stat->st_gid; 1405 if (stat->st_result_mask & P9_STATS_NLINK) 1406 inode->i_nlink = stat->st_nlink; 1407 if (stat->st_result_mask & P9_STATS_MODE) { 1408 inode->i_mode = stat->st_mode; 1409 if ((S_ISBLK(inode->i_mode)) || 1410 (S_ISCHR(inode->i_mode))) 1411 init_special_inode(inode, inode->i_mode, 1412 inode->i_rdev); 1413 } 1414 if (stat->st_result_mask & P9_STATS_RDEV) 1415 inode->i_rdev = new_decode_dev(stat->st_rdev); 1416 if (stat->st_result_mask & P9_STATS_SIZE) 1417 i_size_write(inode, stat->st_size); 1418 if (stat->st_result_mask & P9_STATS_BLOCKS) 1419 inode->i_blocks = stat->st_blocks; 1420 } 1421 if (stat->st_result_mask & P9_STATS_GEN) 1422 inode->i_generation = stat->st_gen; 1423 1424 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION 1425 * because the inode structure does not have fields for them. 1426 */ 1427 } 1428 1429 /** 1430 * v9fs_qid2ino - convert qid into inode number 1431 * @qid: qid to hash 1432 * 1433 * BUG: potential for inode number collisions? 1434 */ 1435 1436 ino_t v9fs_qid2ino(struct p9_qid *qid) 1437 { 1438 u64 path = qid->path + 2; 1439 ino_t i = 0; 1440 1441 if (sizeof(ino_t) == sizeof(path)) 1442 memcpy(&i, &path, sizeof(ino_t)); 1443 else 1444 i = (ino_t) (path ^ (path >> 32)); 1445 1446 return i; 1447 } 1448 1449 /** 1450 * v9fs_readlink - read a symlink's location (internal version) 1451 * @dentry: dentry for symlink 1452 * @buffer: buffer to load symlink location into 1453 * @buflen: length of buffer 1454 * 1455 */ 1456 1457 static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) 1458 { 1459 int retval; 1460 1461 struct v9fs_session_info *v9ses; 1462 struct p9_fid *fid; 1463 struct p9_wstat *st; 1464 1465 P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); 1466 retval = -EPERM; 1467 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1468 fid = v9fs_fid_lookup(dentry); 1469 if (IS_ERR(fid)) 1470 return PTR_ERR(fid); 1471 1472 if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) 1473 return -EBADF; 1474 1475 st = p9_client_stat(fid); 1476 if (IS_ERR(st)) 1477 return PTR_ERR(st); 1478 1479 if (!(st->mode & P9_DMSYMLINK)) { 1480 retval = -EINVAL; 1481 goto done; 1482 } 1483 1484 /* copy extension buffer into buffer */ 1485 strncpy(buffer, st->extension, buflen); 1486 1487 P9_DPRINTK(P9_DEBUG_VFS, 1488 "%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer); 1489 1490 retval = strnlen(buffer, buflen); 1491 done: 1492 kfree(st); 1493 return retval; 1494 } 1495 1496 /** 1497 * v9fs_vfs_follow_link - follow a symlink path 1498 * @dentry: dentry for symlink 1499 * @nd: nameidata 1500 * 1501 */ 1502 1503 static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) 1504 { 1505 int len = 0; 1506 char *link = __getname(); 1507 1508 P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name); 1509 1510 if (!link) 1511 link = ERR_PTR(-ENOMEM); 1512 else { 1513 len = v9fs_readlink(dentry, link, PATH_MAX); 1514 1515 if (len < 0) { 1516 __putname(link); 1517 link = ERR_PTR(len); 1518 } else 1519 link[min(len, PATH_MAX-1)] = 0; 1520 } 1521 nd_set_link(nd, link); 1522 1523 return NULL; 1524 } 1525 1526 /** 1527 * v9fs_vfs_put_link - release a symlink path 1528 * @dentry: dentry for symlink 1529 * @nd: nameidata 1530 * @p: unused 1531 * 1532 */ 1533 1534 static void 1535 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) 1536 { 1537 char *s = nd_get_link(nd); 1538 1539 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, 1540 IS_ERR(s) ? "<error>" : s); 1541 if (!IS_ERR(s)) 1542 __putname(s); 1543 } 1544 1545 /** 1546 * v9fs_vfs_mkspecial - create a special file 1547 * @dir: inode to create special file in 1548 * @dentry: dentry to create 1549 * @mode: mode to create special file 1550 * @extension: 9p2000.u format extension string representing special file 1551 * 1552 */ 1553 1554 static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, 1555 int mode, const char *extension) 1556 { 1557 u32 perm; 1558 struct v9fs_session_info *v9ses; 1559 struct p9_fid *fid; 1560 1561 v9ses = v9fs_inode2v9ses(dir); 1562 if (!v9fs_proto_dotu(v9ses)) { 1563 P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n"); 1564 return -EPERM; 1565 } 1566 1567 perm = unixmode2p9mode(v9ses, mode); 1568 fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm, 1569 P9_OREAD); 1570 if (IS_ERR(fid)) 1571 return PTR_ERR(fid); 1572 1573 p9_client_clunk(fid); 1574 return 0; 1575 } 1576 1577 /** 1578 * v9fs_vfs_symlink_dotl - helper function to create symlinks 1579 * @dir: directory inode containing symlink 1580 * @dentry: dentry for symlink 1581 * @symname: symlink data 1582 * 1583 * See Also: 9P2000.L RFC for more information 1584 * 1585 */ 1586 1587 static int 1588 v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, 1589 const char *symname) 1590 { 1591 struct v9fs_session_info *v9ses; 1592 struct p9_fid *dfid; 1593 struct p9_fid *fid = NULL; 1594 struct inode *inode; 1595 struct p9_qid qid; 1596 char *name; 1597 int err; 1598 gid_t gid; 1599 1600 name = (char *) dentry->d_name.name; 1601 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n", 1602 dir->i_ino, name, symname); 1603 v9ses = v9fs_inode2v9ses(dir); 1604 1605 dfid = v9fs_fid_lookup(dentry->d_parent); 1606 if (IS_ERR(dfid)) { 1607 err = PTR_ERR(dfid); 1608 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 1609 return err; 1610 } 1611 1612 gid = v9fs_get_fsgid_for_create(dir); 1613 1614 if (gid < 0) { 1615 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_egid failed %d\n", gid); 1616 goto error; 1617 } 1618 1619 /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */ 1620 err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid); 1621 1622 if (err < 0) { 1623 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err); 1624 goto error; 1625 } 1626 1627 if (v9ses->cache) { 1628 /* Now walk from the parent so we can get an unopened fid. */ 1629 fid = p9_client_walk(dfid, 1, &name, 1); 1630 if (IS_ERR(fid)) { 1631 err = PTR_ERR(fid); 1632 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 1633 err); 1634 fid = NULL; 1635 goto error; 1636 } 1637 1638 /* instantiate inode and assign the unopened fid to dentry */ 1639 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 1640 if (IS_ERR(inode)) { 1641 err = PTR_ERR(inode); 1642 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 1643 err); 1644 goto error; 1645 } 1646 dentry->d_op = &v9fs_cached_dentry_operations; 1647 d_instantiate(dentry, inode); 1648 err = v9fs_fid_add(dentry, fid); 1649 if (err < 0) 1650 goto error; 1651 fid = NULL; 1652 } else { 1653 /* Not in cached mode. No need to populate inode with stat */ 1654 inode = v9fs_get_inode(dir->i_sb, S_IFLNK); 1655 if (IS_ERR(inode)) { 1656 err = PTR_ERR(inode); 1657 goto error; 1658 } 1659 dentry->d_op = &v9fs_dentry_operations; 1660 d_instantiate(dentry, inode); 1661 } 1662 1663 error: 1664 if (fid) 1665 p9_client_clunk(fid); 1666 1667 return err; 1668 } 1669 1670 /** 1671 * v9fs_vfs_symlink - helper function to create symlinks 1672 * @dir: directory inode containing symlink 1673 * @dentry: dentry for symlink 1674 * @symname: symlink data 1675 * 1676 * See Also: 9P2000.u RFC for more information 1677 * 1678 */ 1679 1680 static int 1681 v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) 1682 { 1683 P9_DPRINTK(P9_DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, 1684 dentry->d_name.name, symname); 1685 1686 return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname); 1687 } 1688 1689 /** 1690 * v9fs_vfs_link - create a hardlink 1691 * @old_dentry: dentry for file to link to 1692 * @dir: inode destination for new link 1693 * @dentry: dentry for link 1694 * 1695 */ 1696 1697 static int 1698 v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, 1699 struct dentry *dentry) 1700 { 1701 int retval; 1702 struct p9_fid *oldfid; 1703 char *name; 1704 1705 P9_DPRINTK(P9_DEBUG_VFS, 1706 " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 1707 old_dentry->d_name.name); 1708 1709 oldfid = v9fs_fid_clone(old_dentry); 1710 if (IS_ERR(oldfid)) 1711 return PTR_ERR(oldfid); 1712 1713 name = __getname(); 1714 if (unlikely(!name)) { 1715 retval = -ENOMEM; 1716 goto clunk_fid; 1717 } 1718 1719 sprintf(name, "%d\n", oldfid->fid); 1720 retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name); 1721 __putname(name); 1722 1723 clunk_fid: 1724 p9_client_clunk(oldfid); 1725 return retval; 1726 } 1727 1728 /** 1729 * v9fs_vfs_link_dotl - create a hardlink for dotl 1730 * @old_dentry: dentry for file to link to 1731 * @dir: inode destination for new link 1732 * @dentry: dentry for link 1733 * 1734 */ 1735 1736 static int 1737 v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, 1738 struct dentry *dentry) 1739 { 1740 int err; 1741 struct p9_fid *dfid, *oldfid; 1742 char *name; 1743 struct v9fs_session_info *v9ses; 1744 struct dentry *dir_dentry; 1745 1746 P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n", 1747 dir->i_ino, old_dentry->d_name.name, 1748 dentry->d_name.name); 1749 1750 v9ses = v9fs_inode2v9ses(dir); 1751 dir_dentry = v9fs_dentry_from_dir_inode(dir); 1752 dfid = v9fs_fid_lookup(dir_dentry); 1753 if (IS_ERR(dfid)) 1754 return PTR_ERR(dfid); 1755 1756 oldfid = v9fs_fid_lookup(old_dentry); 1757 if (IS_ERR(oldfid)) 1758 return PTR_ERR(oldfid); 1759 1760 name = (char *) dentry->d_name.name; 1761 1762 err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name); 1763 1764 if (err < 0) { 1765 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err); 1766 return err; 1767 } 1768 1769 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 1770 /* Get the latest stat info from server. */ 1771 struct p9_fid *fid; 1772 struct p9_stat_dotl *st; 1773 1774 fid = v9fs_fid_lookup(old_dentry); 1775 if (IS_ERR(fid)) 1776 return PTR_ERR(fid); 1777 1778 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); 1779 if (IS_ERR(st)) 1780 return PTR_ERR(st); 1781 1782 v9fs_stat2inode_dotl(st, old_dentry->d_inode); 1783 1784 kfree(st); 1785 } else { 1786 /* Caching disabled. No need to get upto date stat info. 1787 * This dentry will be released immediately. So, just i_count++ 1788 */ 1789 atomic_inc(&old_dentry->d_inode->i_count); 1790 } 1791 1792 dentry->d_op = old_dentry->d_op; 1793 d_instantiate(dentry, old_dentry->d_inode); 1794 1795 return err; 1796 } 1797 1798 /** 1799 * v9fs_vfs_mknod - create a special file 1800 * @dir: inode destination for new link 1801 * @dentry: dentry for file 1802 * @mode: mode for creation 1803 * @rdev: device associated with special file 1804 * 1805 */ 1806 1807 static int 1808 v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) 1809 { 1810 int retval; 1811 char *name; 1812 1813 P9_DPRINTK(P9_DEBUG_VFS, 1814 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1815 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); 1816 1817 if (!new_valid_dev(rdev)) 1818 return -EINVAL; 1819 1820 name = __getname(); 1821 if (!name) 1822 return -ENOMEM; 1823 /* build extension */ 1824 if (S_ISBLK(mode)) 1825 sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev)); 1826 else if (S_ISCHR(mode)) 1827 sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev)); 1828 else if (S_ISFIFO(mode)) 1829 *name = 0; 1830 else if (S_ISSOCK(mode)) 1831 *name = 0; 1832 else { 1833 __putname(name); 1834 return -EINVAL; 1835 } 1836 1837 retval = v9fs_vfs_mkspecial(dir, dentry, mode, name); 1838 __putname(name); 1839 1840 return retval; 1841 } 1842 1843 /** 1844 * v9fs_vfs_mknod_dotl - create a special file 1845 * @dir: inode destination for new link 1846 * @dentry: dentry for file 1847 * @mode: mode for creation 1848 * @rdev: device associated with special file 1849 * 1850 */ 1851 static int 1852 v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode, 1853 dev_t rdev) 1854 { 1855 int err; 1856 char *name; 1857 struct v9fs_session_info *v9ses; 1858 struct p9_fid *fid = NULL, *dfid = NULL; 1859 struct inode *inode; 1860 gid_t gid; 1861 struct p9_qid qid; 1862 struct dentry *dir_dentry; 1863 1864 P9_DPRINTK(P9_DEBUG_VFS, 1865 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1866 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); 1867 1868 if (!new_valid_dev(rdev)) 1869 return -EINVAL; 1870 1871 v9ses = v9fs_inode2v9ses(dir); 1872 dir_dentry = v9fs_dentry_from_dir_inode(dir); 1873 dfid = v9fs_fid_lookup(dir_dentry); 1874 if (IS_ERR(dfid)) { 1875 err = PTR_ERR(dfid); 1876 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 1877 dfid = NULL; 1878 goto error; 1879 } 1880 1881 gid = v9fs_get_fsgid_for_create(dir); 1882 if (gid < 0) { 1883 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_fsgid_for_create failed\n"); 1884 goto error; 1885 } 1886 1887 name = (char *) dentry->d_name.name; 1888 1889 err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid); 1890 if (err < 0) 1891 goto error; 1892 1893 /* instantiate inode and assign the unopened fid to the dentry */ 1894 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 1895 fid = p9_client_walk(dfid, 1, &name, 1); 1896 if (IS_ERR(fid)) { 1897 err = PTR_ERR(fid); 1898 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 1899 err); 1900 fid = NULL; 1901 goto error; 1902 } 1903 1904 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 1905 if (IS_ERR(inode)) { 1906 err = PTR_ERR(inode); 1907 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 1908 err); 1909 goto error; 1910 } 1911 dentry->d_op = &v9fs_cached_dentry_operations; 1912 d_instantiate(dentry, inode); 1913 err = v9fs_fid_add(dentry, fid); 1914 if (err < 0) 1915 goto error; 1916 fid = NULL; 1917 } else { 1918 /* 1919 * Not in cached mode. No need to populate inode with stat. 1920 * socket syscall returns a fd, so we need instantiate 1921 */ 1922 inode = v9fs_get_inode(dir->i_sb, mode); 1923 if (IS_ERR(inode)) { 1924 err = PTR_ERR(inode); 1925 goto error; 1926 } 1927 dentry->d_op = &v9fs_dentry_operations; 1928 d_instantiate(dentry, inode); 1929 } 1930 1931 error: 1932 if (fid) 1933 p9_client_clunk(fid); 1934 return err; 1935 } 1936 1937 static const struct inode_operations v9fs_dir_inode_operations_dotu = { 1938 .create = v9fs_vfs_create, 1939 .lookup = v9fs_vfs_lookup, 1940 .symlink = v9fs_vfs_symlink, 1941 .link = v9fs_vfs_link, 1942 .unlink = v9fs_vfs_unlink, 1943 .mkdir = v9fs_vfs_mkdir, 1944 .rmdir = v9fs_vfs_rmdir, 1945 .mknod = v9fs_vfs_mknod_dotl, 1946 .rename = v9fs_vfs_rename, 1947 .getattr = v9fs_vfs_getattr, 1948 .setattr = v9fs_vfs_setattr, 1949 }; 1950 1951 static const struct inode_operations v9fs_dir_inode_operations_dotl = { 1952 .create = v9fs_vfs_create_dotl, 1953 .lookup = v9fs_vfs_lookup, 1954 .link = v9fs_vfs_link_dotl, 1955 .symlink = v9fs_vfs_symlink_dotl, 1956 .unlink = v9fs_vfs_unlink, 1957 .mkdir = v9fs_vfs_mkdir_dotl, 1958 .rmdir = v9fs_vfs_rmdir, 1959 .mknod = v9fs_vfs_mknod_dotl, 1960 .rename = v9fs_vfs_rename, 1961 .getattr = v9fs_vfs_getattr_dotl, 1962 .setattr = v9fs_vfs_setattr_dotl, 1963 .setxattr = generic_setxattr, 1964 .getxattr = generic_getxattr, 1965 .removexattr = generic_removexattr, 1966 .listxattr = v9fs_listxattr, 1967 1968 }; 1969 1970 static const struct inode_operations v9fs_dir_inode_operations = { 1971 .create = v9fs_vfs_create, 1972 .lookup = v9fs_vfs_lookup, 1973 .unlink = v9fs_vfs_unlink, 1974 .mkdir = v9fs_vfs_mkdir, 1975 .rmdir = v9fs_vfs_rmdir, 1976 .mknod = v9fs_vfs_mknod, 1977 .rename = v9fs_vfs_rename, 1978 .getattr = v9fs_vfs_getattr, 1979 .setattr = v9fs_vfs_setattr, 1980 }; 1981 1982 static const struct inode_operations v9fs_file_inode_operations = { 1983 .getattr = v9fs_vfs_getattr, 1984 .setattr = v9fs_vfs_setattr, 1985 }; 1986 1987 static const struct inode_operations v9fs_file_inode_operations_dotl = { 1988 .getattr = v9fs_vfs_getattr_dotl, 1989 .setattr = v9fs_vfs_setattr_dotl, 1990 .setxattr = generic_setxattr, 1991 .getxattr = generic_getxattr, 1992 .removexattr = generic_removexattr, 1993 .listxattr = v9fs_listxattr, 1994 }; 1995 1996 static const struct inode_operations v9fs_symlink_inode_operations = { 1997 .readlink = generic_readlink, 1998 .follow_link = v9fs_vfs_follow_link, 1999 .put_link = v9fs_vfs_put_link, 2000 .getattr = v9fs_vfs_getattr, 2001 .setattr = v9fs_vfs_setattr, 2002 }; 2003 2004 static const struct inode_operations v9fs_symlink_inode_operations_dotl = { 2005 .readlink = generic_readlink, 2006 .follow_link = v9fs_vfs_follow_link, 2007 .put_link = v9fs_vfs_put_link, 2008 .getattr = v9fs_vfs_getattr_dotl, 2009 .setattr = v9fs_vfs_setattr_dotl, 2010 .setxattr = generic_setxattr, 2011 .getxattr = generic_getxattr, 2012 .removexattr = generic_removexattr, 2013 .listxattr = v9fs_listxattr, 2014 }; 2015