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 <linux/posix_acl.h> 40 #include <net/9p/9p.h> 41 #include <net/9p/client.h> 42 43 #include "v9fs.h" 44 #include "v9fs_vfs.h" 45 #include "fid.h" 46 #include "cache.h" 47 #include "xattr.h" 48 #include "acl.h" 49 50 static const struct inode_operations v9fs_dir_inode_operations; 51 static const struct inode_operations v9fs_dir_inode_operations_dotu; 52 static const struct inode_operations v9fs_file_inode_operations; 53 static const struct inode_operations v9fs_symlink_inode_operations; 54 55 /** 56 * unixmode2p9mode - convert unix mode bits to plan 9 57 * @v9ses: v9fs session information 58 * @mode: mode to convert 59 * 60 */ 61 62 static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode) 63 { 64 int res; 65 res = mode & 0777; 66 if (S_ISDIR(mode)) 67 res |= P9_DMDIR; 68 if (v9fs_proto_dotu(v9ses)) { 69 if (S_ISLNK(mode)) 70 res |= P9_DMSYMLINK; 71 if (v9ses->nodev == 0) { 72 if (S_ISSOCK(mode)) 73 res |= P9_DMSOCKET; 74 if (S_ISFIFO(mode)) 75 res |= P9_DMNAMEDPIPE; 76 if (S_ISBLK(mode)) 77 res |= P9_DMDEVICE; 78 if (S_ISCHR(mode)) 79 res |= P9_DMDEVICE; 80 } 81 82 if ((mode & S_ISUID) == S_ISUID) 83 res |= P9_DMSETUID; 84 if ((mode & S_ISGID) == S_ISGID) 85 res |= P9_DMSETGID; 86 if ((mode & S_ISVTX) == S_ISVTX) 87 res |= P9_DMSETVTX; 88 if ((mode & P9_DMLINK)) 89 res |= P9_DMLINK; 90 } 91 92 return res; 93 } 94 95 /** 96 * p9mode2unixmode- convert plan9 mode bits to unix mode bits 97 * @v9ses: v9fs session information 98 * @mode: mode to convert 99 * 100 */ 101 102 static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) 103 { 104 int res; 105 106 res = mode & 0777; 107 108 if ((mode & P9_DMDIR) == P9_DMDIR) 109 res |= S_IFDIR; 110 else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses))) 111 res |= S_IFLNK; 112 else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses)) 113 && (v9ses->nodev == 0)) 114 res |= S_IFSOCK; 115 else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses)) 116 && (v9ses->nodev == 0)) 117 res |= S_IFIFO; 118 else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses)) 119 && (v9ses->nodev == 0)) 120 res |= S_IFBLK; 121 else 122 res |= S_IFREG; 123 124 if (v9fs_proto_dotu(v9ses)) { 125 if ((mode & P9_DMSETUID) == P9_DMSETUID) 126 res |= S_ISUID; 127 128 if ((mode & P9_DMSETGID) == P9_DMSETGID) 129 res |= S_ISGID; 130 131 if ((mode & P9_DMSETVTX) == P9_DMSETVTX) 132 res |= S_ISVTX; 133 } 134 135 return res; 136 } 137 138 /** 139 * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits 140 * @uflags: flags to convert 141 * @extended: if .u extensions are active 142 */ 143 144 int v9fs_uflags2omode(int uflags, int extended) 145 { 146 int ret; 147 148 ret = 0; 149 switch (uflags&3) { 150 default: 151 case O_RDONLY: 152 ret = P9_OREAD; 153 break; 154 155 case O_WRONLY: 156 ret = P9_OWRITE; 157 break; 158 159 case O_RDWR: 160 ret = P9_ORDWR; 161 break; 162 } 163 164 if (uflags & O_TRUNC) 165 ret |= P9_OTRUNC; 166 167 if (extended) { 168 if (uflags & O_EXCL) 169 ret |= P9_OEXCL; 170 171 if (uflags & O_APPEND) 172 ret |= P9_OAPPEND; 173 } 174 175 return ret; 176 } 177 178 /** 179 * v9fs_blank_wstat - helper function to setup a 9P stat structure 180 * @wstat: structure to initialize 181 * 182 */ 183 184 void 185 v9fs_blank_wstat(struct p9_wstat *wstat) 186 { 187 wstat->type = ~0; 188 wstat->dev = ~0; 189 wstat->qid.type = ~0; 190 wstat->qid.version = ~0; 191 *((long long *)&wstat->qid.path) = ~0; 192 wstat->mode = ~0; 193 wstat->atime = ~0; 194 wstat->mtime = ~0; 195 wstat->length = ~0; 196 wstat->name = NULL; 197 wstat->uid = NULL; 198 wstat->gid = NULL; 199 wstat->muid = NULL; 200 wstat->n_uid = ~0; 201 wstat->n_gid = ~0; 202 wstat->n_muid = ~0; 203 wstat->extension = NULL; 204 } 205 206 /** 207 * v9fs_alloc_inode - helper function to allocate an inode 208 * 209 */ 210 struct inode *v9fs_alloc_inode(struct super_block *sb) 211 { 212 struct v9fs_inode *v9inode; 213 v9inode = (struct v9fs_inode *)kmem_cache_alloc(v9fs_inode_cache, 214 GFP_KERNEL); 215 if (!v9inode) 216 return NULL; 217 #ifdef CONFIG_9P_FSCACHE 218 v9inode->fscache = NULL; 219 v9inode->fscache_key = NULL; 220 spin_lock_init(&v9inode->fscache_lock); 221 #endif 222 v9inode->writeback_fid = NULL; 223 v9inode->cache_validity = 0; 224 mutex_init(&v9inode->v_mutex); 225 return &v9inode->vfs_inode; 226 } 227 228 /** 229 * v9fs_destroy_inode - destroy an inode 230 * 231 */ 232 233 static void v9fs_i_callback(struct rcu_head *head) 234 { 235 struct inode *inode = container_of(head, struct inode, i_rcu); 236 INIT_LIST_HEAD(&inode->i_dentry); 237 kmem_cache_free(v9fs_inode_cache, V9FS_I(inode)); 238 } 239 240 void v9fs_destroy_inode(struct inode *inode) 241 { 242 call_rcu(&inode->i_rcu, v9fs_i_callback); 243 } 244 245 int v9fs_init_inode(struct v9fs_session_info *v9ses, 246 struct inode *inode, int mode) 247 { 248 int err = 0; 249 250 inode_init_owner(inode, NULL, mode); 251 inode->i_blocks = 0; 252 inode->i_rdev = 0; 253 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 254 inode->i_mapping->a_ops = &v9fs_addr_operations; 255 256 switch (mode & S_IFMT) { 257 case S_IFIFO: 258 case S_IFBLK: 259 case S_IFCHR: 260 case S_IFSOCK: 261 if (v9fs_proto_dotl(v9ses)) { 262 inode->i_op = &v9fs_file_inode_operations_dotl; 263 inode->i_fop = &v9fs_file_operations_dotl; 264 } else if (v9fs_proto_dotu(v9ses)) { 265 inode->i_op = &v9fs_file_inode_operations; 266 inode->i_fop = &v9fs_file_operations; 267 } else { 268 P9_DPRINTK(P9_DEBUG_ERROR, 269 "special files without extended mode\n"); 270 err = -EINVAL; 271 goto error; 272 } 273 init_special_inode(inode, inode->i_mode, inode->i_rdev); 274 break; 275 case S_IFREG: 276 if (v9fs_proto_dotl(v9ses)) { 277 inode->i_op = &v9fs_file_inode_operations_dotl; 278 if (v9ses->cache) 279 inode->i_fop = 280 &v9fs_cached_file_operations_dotl; 281 else 282 inode->i_fop = &v9fs_file_operations_dotl; 283 } else { 284 inode->i_op = &v9fs_file_inode_operations; 285 if (v9ses->cache) 286 inode->i_fop = &v9fs_cached_file_operations; 287 else 288 inode->i_fop = &v9fs_file_operations; 289 } 290 291 break; 292 case S_IFLNK: 293 if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) { 294 P9_DPRINTK(P9_DEBUG_ERROR, "extended modes used with " 295 "legacy protocol.\n"); 296 err = -EINVAL; 297 goto error; 298 } 299 300 if (v9fs_proto_dotl(v9ses)) 301 inode->i_op = &v9fs_symlink_inode_operations_dotl; 302 else 303 inode->i_op = &v9fs_symlink_inode_operations; 304 305 break; 306 case S_IFDIR: 307 inc_nlink(inode); 308 if (v9fs_proto_dotl(v9ses)) 309 inode->i_op = &v9fs_dir_inode_operations_dotl; 310 else if (v9fs_proto_dotu(v9ses)) 311 inode->i_op = &v9fs_dir_inode_operations_dotu; 312 else 313 inode->i_op = &v9fs_dir_inode_operations; 314 315 if (v9fs_proto_dotl(v9ses)) 316 inode->i_fop = &v9fs_dir_operations_dotl; 317 else 318 inode->i_fop = &v9fs_dir_operations; 319 320 break; 321 default: 322 P9_DPRINTK(P9_DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n", 323 mode, mode & S_IFMT); 324 err = -EINVAL; 325 goto error; 326 } 327 error: 328 return err; 329 330 } 331 332 /** 333 * v9fs_get_inode - helper function to setup an inode 334 * @sb: superblock 335 * @mode: mode to setup inode with 336 * 337 */ 338 339 struct inode *v9fs_get_inode(struct super_block *sb, int mode) 340 { 341 int err; 342 struct inode *inode; 343 struct v9fs_session_info *v9ses = sb->s_fs_info; 344 345 P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); 346 347 inode = new_inode(sb); 348 if (!inode) { 349 P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); 350 return ERR_PTR(-ENOMEM); 351 } 352 err = v9fs_init_inode(v9ses, inode, mode); 353 if (err) { 354 iput(inode); 355 return ERR_PTR(err); 356 } 357 return inode; 358 } 359 360 /* 361 static struct v9fs_fid* 362 v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) 363 { 364 int err; 365 int nfid; 366 struct v9fs_fid *ret; 367 struct v9fs_fcall *fcall; 368 369 nfid = v9fs_get_idpool(&v9ses->fidpool); 370 if (nfid < 0) { 371 eprintk(KERN_WARNING, "no free fids available\n"); 372 return ERR_PTR(-ENOSPC); 373 } 374 375 err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name, 376 &fcall); 377 378 if (err < 0) { 379 if (fcall && fcall->id == RWALK) 380 goto clunk_fid; 381 382 PRINT_FCALL_ERROR("walk error", fcall); 383 v9fs_put_idpool(nfid, &v9ses->fidpool); 384 goto error; 385 } 386 387 kfree(fcall); 388 fcall = NULL; 389 ret = v9fs_fid_create(v9ses, nfid); 390 if (!ret) { 391 err = -ENOMEM; 392 goto clunk_fid; 393 } 394 395 err = v9fs_fid_insert(ret, dentry); 396 if (err < 0) { 397 v9fs_fid_destroy(ret); 398 goto clunk_fid; 399 } 400 401 return ret; 402 403 clunk_fid: 404 v9fs_t_clunk(v9ses, nfid); 405 406 error: 407 kfree(fcall); 408 return ERR_PTR(err); 409 } 410 */ 411 412 413 /** 414 * v9fs_clear_inode - release an inode 415 * @inode: inode to release 416 * 417 */ 418 void v9fs_evict_inode(struct inode *inode) 419 { 420 struct v9fs_inode *v9inode = V9FS_I(inode); 421 422 truncate_inode_pages(inode->i_mapping, 0); 423 end_writeback(inode); 424 filemap_fdatawrite(inode->i_mapping); 425 426 #ifdef CONFIG_9P_FSCACHE 427 v9fs_cache_inode_put_cookie(inode); 428 #endif 429 /* clunk the fid stashed in writeback_fid */ 430 if (v9inode->writeback_fid) { 431 p9_client_clunk(v9inode->writeback_fid); 432 v9inode->writeback_fid = NULL; 433 } 434 } 435 436 static struct inode *v9fs_qid_iget(struct super_block *sb, 437 struct p9_qid *qid, 438 struct p9_wstat *st) 439 { 440 int retval, umode; 441 unsigned long i_ino; 442 struct inode *inode; 443 struct v9fs_session_info *v9ses = sb->s_fs_info; 444 445 i_ino = v9fs_qid2ino(qid); 446 inode = iget_locked(sb, i_ino); 447 if (!inode) 448 return ERR_PTR(-ENOMEM); 449 if (!(inode->i_state & I_NEW)) 450 return inode; 451 /* 452 * initialize the inode with the stat info 453 * FIXME!! we may need support for stale inodes 454 * later. 455 */ 456 umode = p9mode2unixmode(v9ses, st->mode); 457 retval = v9fs_init_inode(v9ses, inode, umode); 458 if (retval) 459 goto error; 460 461 v9fs_stat2inode(st, inode, sb); 462 #ifdef CONFIG_9P_FSCACHE 463 v9fs_fscache_set_key(inode, &st->qid); 464 v9fs_cache_inode_get_cookie(inode); 465 #endif 466 unlock_new_inode(inode); 467 return inode; 468 error: 469 unlock_new_inode(inode); 470 iput(inode); 471 return ERR_PTR(retval); 472 473 } 474 475 struct inode * 476 v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, 477 struct super_block *sb) 478 { 479 struct p9_wstat *st; 480 struct inode *inode = NULL; 481 482 st = p9_client_stat(fid); 483 if (IS_ERR(st)) 484 return ERR_CAST(st); 485 486 inode = v9fs_qid_iget(sb, &st->qid, st); 487 p9stat_free(st); 488 kfree(st); 489 return inode; 490 } 491 492 /** 493 * v9fs_remove - helper function to remove files and directories 494 * @dir: directory inode that is being deleted 495 * @file: dentry that is being deleted 496 * @rmdir: removing a directory 497 * 498 */ 499 500 static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) 501 { 502 int retval; 503 struct p9_fid *v9fid; 504 struct inode *file_inode; 505 506 P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, 507 rmdir); 508 509 file_inode = file->d_inode; 510 v9fid = v9fs_fid_clone(file); 511 if (IS_ERR(v9fid)) 512 return PTR_ERR(v9fid); 513 514 retval = p9_client_remove(v9fid); 515 if (!retval) { 516 /* 517 * directories on unlink should have zero 518 * link count 519 */ 520 if (rmdir) { 521 clear_nlink(file_inode); 522 drop_nlink(dir); 523 } else 524 drop_nlink(file_inode); 525 526 v9fs_invalidate_inode_attr(file_inode); 527 v9fs_invalidate_inode_attr(dir); 528 } 529 return retval; 530 } 531 532 /** 533 * v9fs_create - Create a file 534 * @v9ses: session information 535 * @dir: directory that dentry is being created in 536 * @dentry: dentry that is being created 537 * @extension: 9p2000.u extension string to support devices, etc. 538 * @perm: create permissions 539 * @mode: open mode 540 * 541 */ 542 static struct p9_fid * 543 v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, 544 struct dentry *dentry, char *extension, u32 perm, u8 mode) 545 { 546 int err; 547 char *name; 548 struct p9_fid *dfid, *ofid, *fid; 549 struct inode *inode; 550 551 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 552 553 err = 0; 554 ofid = NULL; 555 fid = NULL; 556 name = (char *) dentry->d_name.name; 557 dfid = v9fs_fid_lookup(dentry->d_parent); 558 if (IS_ERR(dfid)) { 559 err = PTR_ERR(dfid); 560 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 561 return ERR_PTR(err); 562 } 563 564 /* clone a fid to use for creation */ 565 ofid = p9_client_walk(dfid, 0, NULL, 1); 566 if (IS_ERR(ofid)) { 567 err = PTR_ERR(ofid); 568 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 569 return ERR_PTR(err); 570 } 571 572 err = p9_client_fcreate(ofid, name, perm, mode, extension); 573 if (err < 0) { 574 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err); 575 goto error; 576 } 577 578 /* now walk from the parent so we can get unopened fid */ 579 fid = p9_client_walk(dfid, 1, &name, 1); 580 if (IS_ERR(fid)) { 581 err = PTR_ERR(fid); 582 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 583 fid = NULL; 584 goto error; 585 } 586 587 /* instantiate inode and assign the unopened fid to the dentry */ 588 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 589 if (IS_ERR(inode)) { 590 err = PTR_ERR(inode); 591 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 592 goto error; 593 } 594 d_instantiate(dentry, inode); 595 err = v9fs_fid_add(dentry, fid); 596 if (err < 0) 597 goto error; 598 599 return ofid; 600 601 error: 602 if (ofid) 603 p9_client_clunk(ofid); 604 605 if (fid) 606 p9_client_clunk(fid); 607 608 return ERR_PTR(err); 609 } 610 611 /** 612 * v9fs_vfs_create - VFS hook to create files 613 * @dir: directory inode that is being created 614 * @dentry: dentry that is being deleted 615 * @mode: create permissions 616 * @nd: path information 617 * 618 */ 619 620 static int 621 v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, 622 struct nameidata *nd) 623 { 624 int err; 625 u32 perm; 626 int flags; 627 struct file *filp; 628 struct v9fs_inode *v9inode; 629 struct v9fs_session_info *v9ses; 630 struct p9_fid *fid, *inode_fid; 631 632 err = 0; 633 fid = NULL; 634 v9ses = v9fs_inode2v9ses(dir); 635 perm = unixmode2p9mode(v9ses, mode); 636 if (nd && nd->flags & LOOKUP_OPEN) 637 flags = nd->intent.open.flags - 1; 638 else 639 flags = O_RDWR; 640 641 fid = v9fs_create(v9ses, dir, dentry, NULL, perm, 642 v9fs_uflags2omode(flags, 643 v9fs_proto_dotu(v9ses))); 644 if (IS_ERR(fid)) { 645 err = PTR_ERR(fid); 646 fid = NULL; 647 goto error; 648 } 649 650 v9fs_invalidate_inode_attr(dir); 651 /* if we are opening a file, assign the open fid to the file */ 652 if (nd && nd->flags & LOOKUP_OPEN) { 653 v9inode = V9FS_I(dentry->d_inode); 654 mutex_lock(&v9inode->v_mutex); 655 if (v9ses->cache && !v9inode->writeback_fid && 656 ((flags & O_ACCMODE) != O_RDONLY)) { 657 /* 658 * clone a fid and add it to writeback_fid 659 * we do it during open time instead of 660 * page dirty time via write_begin/page_mkwrite 661 * because we want write after unlink usecase 662 * to work. 663 */ 664 inode_fid = v9fs_writeback_fid(dentry); 665 if (IS_ERR(inode_fid)) { 666 err = PTR_ERR(inode_fid); 667 mutex_unlock(&v9inode->v_mutex); 668 goto error; 669 } 670 v9inode->writeback_fid = (void *) inode_fid; 671 } 672 mutex_unlock(&v9inode->v_mutex); 673 filp = lookup_instantiate_filp(nd, dentry, generic_file_open); 674 if (IS_ERR(filp)) { 675 err = PTR_ERR(filp); 676 goto error; 677 } 678 679 filp->private_data = fid; 680 #ifdef CONFIG_9P_FSCACHE 681 if (v9ses->cache) 682 v9fs_cache_inode_set_cookie(dentry->d_inode, filp); 683 #endif 684 } else 685 p9_client_clunk(fid); 686 687 return 0; 688 689 error: 690 if (fid) 691 p9_client_clunk(fid); 692 693 return err; 694 } 695 696 /** 697 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory 698 * @dir: inode that is being unlinked 699 * @dentry: dentry that is being unlinked 700 * @mode: mode for new directory 701 * 702 */ 703 704 static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 705 { 706 int err; 707 u32 perm; 708 struct p9_fid *fid; 709 struct v9fs_session_info *v9ses; 710 711 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 712 err = 0; 713 v9ses = v9fs_inode2v9ses(dir); 714 perm = unixmode2p9mode(v9ses, mode | S_IFDIR); 715 fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD); 716 if (IS_ERR(fid)) { 717 err = PTR_ERR(fid); 718 fid = NULL; 719 } else { 720 inc_nlink(dir); 721 v9fs_invalidate_inode_attr(dir); 722 } 723 724 if (fid) 725 p9_client_clunk(fid); 726 727 return err; 728 } 729 730 /** 731 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode 732 * @dir: inode that is being walked from 733 * @dentry: dentry that is being walked to? 734 * @nameidata: path data 735 * 736 */ 737 738 struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, 739 struct nameidata *nameidata) 740 { 741 struct super_block *sb; 742 struct v9fs_session_info *v9ses; 743 struct p9_fid *dfid, *fid; 744 struct inode *inode; 745 char *name; 746 int result = 0; 747 748 P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", 749 dir, dentry->d_name.name, dentry, nameidata); 750 751 if (dentry->d_name.len > NAME_MAX) 752 return ERR_PTR(-ENAMETOOLONG); 753 754 sb = dir->i_sb; 755 v9ses = v9fs_inode2v9ses(dir); 756 /* We can walk d_parent because we hold the dir->i_mutex */ 757 dfid = v9fs_fid_lookup(dentry->d_parent); 758 if (IS_ERR(dfid)) 759 return ERR_CAST(dfid); 760 761 name = (char *) dentry->d_name.name; 762 fid = p9_client_walk(dfid, 1, &name, 1); 763 if (IS_ERR(fid)) { 764 result = PTR_ERR(fid); 765 if (result == -ENOENT) { 766 inode = NULL; 767 goto inst_out; 768 } 769 770 return ERR_PTR(result); 771 } 772 773 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 774 if (IS_ERR(inode)) { 775 result = PTR_ERR(inode); 776 inode = NULL; 777 goto error; 778 } 779 780 result = v9fs_fid_add(dentry, fid); 781 if (result < 0) 782 goto error_iput; 783 784 inst_out: 785 d_add(dentry, inode); 786 return NULL; 787 788 error_iput: 789 iput(inode); 790 error: 791 p9_client_clunk(fid); 792 793 return ERR_PTR(result); 794 } 795 796 /** 797 * v9fs_vfs_unlink - VFS unlink hook to delete an inode 798 * @i: inode that is being unlinked 799 * @d: dentry that is being unlinked 800 * 801 */ 802 803 int v9fs_vfs_unlink(struct inode *i, struct dentry *d) 804 { 805 return v9fs_remove(i, d, 0); 806 } 807 808 /** 809 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory 810 * @i: inode that is being unlinked 811 * @d: dentry that is being unlinked 812 * 813 */ 814 815 int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) 816 { 817 return v9fs_remove(i, d, 1); 818 } 819 820 /** 821 * v9fs_vfs_rename - VFS hook to rename an inode 822 * @old_dir: old dir inode 823 * @old_dentry: old dentry 824 * @new_dir: new dir inode 825 * @new_dentry: new dentry 826 * 827 */ 828 829 int 830 v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, 831 struct inode *new_dir, struct dentry *new_dentry) 832 { 833 int retval; 834 struct inode *old_inode; 835 struct inode *new_inode; 836 struct v9fs_session_info *v9ses; 837 struct p9_fid *oldfid; 838 struct p9_fid *olddirfid; 839 struct p9_fid *newdirfid; 840 struct p9_wstat wstat; 841 842 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 843 retval = 0; 844 old_inode = old_dentry->d_inode; 845 new_inode = new_dentry->d_inode; 846 v9ses = v9fs_inode2v9ses(old_inode); 847 oldfid = v9fs_fid_lookup(old_dentry); 848 if (IS_ERR(oldfid)) 849 return PTR_ERR(oldfid); 850 851 olddirfid = v9fs_fid_clone(old_dentry->d_parent); 852 if (IS_ERR(olddirfid)) { 853 retval = PTR_ERR(olddirfid); 854 goto done; 855 } 856 857 newdirfid = v9fs_fid_clone(new_dentry->d_parent); 858 if (IS_ERR(newdirfid)) { 859 retval = PTR_ERR(newdirfid); 860 goto clunk_olddir; 861 } 862 863 down_write(&v9ses->rename_sem); 864 if (v9fs_proto_dotl(v9ses)) { 865 retval = p9_client_rename(oldfid, newdirfid, 866 (char *) new_dentry->d_name.name); 867 if (retval != -ENOSYS) 868 goto clunk_newdir; 869 } 870 if (old_dentry->d_parent != new_dentry->d_parent) { 871 /* 872 * 9P .u can only handle file rename in the same directory 873 */ 874 875 P9_DPRINTK(P9_DEBUG_ERROR, 876 "old dir and new dir are different\n"); 877 retval = -EXDEV; 878 goto clunk_newdir; 879 } 880 v9fs_blank_wstat(&wstat); 881 wstat.muid = v9ses->uname; 882 wstat.name = (char *) new_dentry->d_name.name; 883 retval = p9_client_wstat(oldfid, &wstat); 884 885 clunk_newdir: 886 if (!retval) { 887 if (new_inode) { 888 if (S_ISDIR(new_inode->i_mode)) 889 clear_nlink(new_inode); 890 else 891 drop_nlink(new_inode); 892 /* 893 * Work around vfs rename rehash bug with 894 * FS_RENAME_DOES_D_MOVE 895 */ 896 v9fs_invalidate_inode_attr(new_inode); 897 } 898 if (S_ISDIR(old_inode->i_mode)) { 899 if (!new_inode) 900 inc_nlink(new_dir); 901 drop_nlink(old_dir); 902 } 903 v9fs_invalidate_inode_attr(old_inode); 904 v9fs_invalidate_inode_attr(old_dir); 905 v9fs_invalidate_inode_attr(new_dir); 906 907 /* successful rename */ 908 d_move(old_dentry, new_dentry); 909 } 910 up_write(&v9ses->rename_sem); 911 p9_client_clunk(newdirfid); 912 913 clunk_olddir: 914 p9_client_clunk(olddirfid); 915 916 done: 917 return retval; 918 } 919 920 /** 921 * v9fs_vfs_getattr - retrieve file metadata 922 * @mnt: mount information 923 * @dentry: file to get attributes on 924 * @stat: metadata structure to populate 925 * 926 */ 927 928 static int 929 v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 930 struct kstat *stat) 931 { 932 int err; 933 struct v9fs_session_info *v9ses; 934 struct p9_fid *fid; 935 struct p9_wstat *st; 936 937 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 938 err = -EPERM; 939 v9ses = v9fs_dentry2v9ses(dentry); 940 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 941 generic_fillattr(dentry->d_inode, stat); 942 return 0; 943 } 944 fid = v9fs_fid_lookup(dentry); 945 if (IS_ERR(fid)) 946 return PTR_ERR(fid); 947 948 st = p9_client_stat(fid); 949 if (IS_ERR(st)) 950 return PTR_ERR(st); 951 952 v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); 953 generic_fillattr(dentry->d_inode, stat); 954 955 p9stat_free(st); 956 kfree(st); 957 return 0; 958 } 959 960 /** 961 * v9fs_vfs_setattr - set file metadata 962 * @dentry: file whose metadata to set 963 * @iattr: metadata assignment structure 964 * 965 */ 966 967 static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) 968 { 969 int retval; 970 struct v9fs_session_info *v9ses; 971 struct p9_fid *fid; 972 struct p9_wstat wstat; 973 974 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 975 retval = inode_change_ok(dentry->d_inode, iattr); 976 if (retval) 977 return retval; 978 979 retval = -EPERM; 980 v9ses = v9fs_dentry2v9ses(dentry); 981 fid = v9fs_fid_lookup(dentry); 982 if(IS_ERR(fid)) 983 return PTR_ERR(fid); 984 985 v9fs_blank_wstat(&wstat); 986 if (iattr->ia_valid & ATTR_MODE) 987 wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode); 988 989 if (iattr->ia_valid & ATTR_MTIME) 990 wstat.mtime = iattr->ia_mtime.tv_sec; 991 992 if (iattr->ia_valid & ATTR_ATIME) 993 wstat.atime = iattr->ia_atime.tv_sec; 994 995 if (iattr->ia_valid & ATTR_SIZE) 996 wstat.length = iattr->ia_size; 997 998 if (v9fs_proto_dotu(v9ses)) { 999 if (iattr->ia_valid & ATTR_UID) 1000 wstat.n_uid = iattr->ia_uid; 1001 1002 if (iattr->ia_valid & ATTR_GID) 1003 wstat.n_gid = iattr->ia_gid; 1004 } 1005 1006 /* Write all dirty data */ 1007 if (S_ISREG(dentry->d_inode->i_mode)) 1008 filemap_write_and_wait(dentry->d_inode->i_mapping); 1009 1010 retval = p9_client_wstat(fid, &wstat); 1011 if (retval < 0) 1012 return retval; 1013 1014 if ((iattr->ia_valid & ATTR_SIZE) && 1015 iattr->ia_size != i_size_read(dentry->d_inode)) 1016 truncate_setsize(dentry->d_inode, iattr->ia_size); 1017 1018 v9fs_invalidate_inode_attr(dentry->d_inode); 1019 1020 setattr_copy(dentry->d_inode, iattr); 1021 mark_inode_dirty(dentry->d_inode); 1022 return 0; 1023 } 1024 1025 /** 1026 * v9fs_stat2inode - populate an inode structure with mistat info 1027 * @stat: Plan 9 metadata (mistat) structure 1028 * @inode: inode to populate 1029 * @sb: superblock of filesystem 1030 * 1031 */ 1032 1033 void 1034 v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode, 1035 struct super_block *sb) 1036 { 1037 char ext[32]; 1038 char tag_name[14]; 1039 unsigned int i_nlink; 1040 struct v9fs_session_info *v9ses = sb->s_fs_info; 1041 struct v9fs_inode *v9inode = V9FS_I(inode); 1042 1043 inode->i_nlink = 1; 1044 1045 inode->i_atime.tv_sec = stat->atime; 1046 inode->i_mtime.tv_sec = stat->mtime; 1047 inode->i_ctime.tv_sec = stat->mtime; 1048 1049 inode->i_uid = v9ses->dfltuid; 1050 inode->i_gid = v9ses->dfltgid; 1051 1052 if (v9fs_proto_dotu(v9ses)) { 1053 inode->i_uid = stat->n_uid; 1054 inode->i_gid = stat->n_gid; 1055 } 1056 if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) { 1057 if (v9fs_proto_dotu(v9ses) && (stat->extension[0] != '\0')) { 1058 /* 1059 * Hadlink support got added later to 1060 * to the .u extension. So there can be 1061 * server out there that doesn't support 1062 * this even with .u extension. So check 1063 * for non NULL stat->extension 1064 */ 1065 strncpy(ext, stat->extension, sizeof(ext)); 1066 /* HARDLINKCOUNT %u */ 1067 sscanf(ext, "%13s %u", tag_name, &i_nlink); 1068 if (!strncmp(tag_name, "HARDLINKCOUNT", 13)) 1069 inode->i_nlink = i_nlink; 1070 } 1071 } 1072 inode->i_mode = p9mode2unixmode(v9ses, stat->mode); 1073 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) { 1074 char type = 0; 1075 int major = -1; 1076 int minor = -1; 1077 1078 strncpy(ext, stat->extension, sizeof(ext)); 1079 sscanf(ext, "%c %u %u", &type, &major, &minor); 1080 switch (type) { 1081 case 'c': 1082 inode->i_mode &= ~S_IFBLK; 1083 inode->i_mode |= S_IFCHR; 1084 break; 1085 case 'b': 1086 break; 1087 default: 1088 P9_DPRINTK(P9_DEBUG_ERROR, 1089 "Unknown special type %c %s\n", type, 1090 stat->extension); 1091 }; 1092 inode->i_rdev = MKDEV(major, minor); 1093 init_special_inode(inode, inode->i_mode, inode->i_rdev); 1094 } else 1095 inode->i_rdev = 0; 1096 1097 i_size_write(inode, stat->length); 1098 1099 /* not real number of blocks, but 512 byte ones ... */ 1100 inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9; 1101 v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR; 1102 } 1103 1104 /** 1105 * v9fs_qid2ino - convert qid into inode number 1106 * @qid: qid to hash 1107 * 1108 * BUG: potential for inode number collisions? 1109 */ 1110 1111 ino_t v9fs_qid2ino(struct p9_qid *qid) 1112 { 1113 u64 path = qid->path + 2; 1114 ino_t i = 0; 1115 1116 if (sizeof(ino_t) == sizeof(path)) 1117 memcpy(&i, &path, sizeof(ino_t)); 1118 else 1119 i = (ino_t) (path ^ (path >> 32)); 1120 1121 return i; 1122 } 1123 1124 /** 1125 * v9fs_readlink - read a symlink's location (internal version) 1126 * @dentry: dentry for symlink 1127 * @buffer: buffer to load symlink location into 1128 * @buflen: length of buffer 1129 * 1130 */ 1131 1132 static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) 1133 { 1134 int retval; 1135 1136 struct v9fs_session_info *v9ses; 1137 struct p9_fid *fid; 1138 struct p9_wstat *st; 1139 1140 P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); 1141 retval = -EPERM; 1142 v9ses = v9fs_dentry2v9ses(dentry); 1143 fid = v9fs_fid_lookup(dentry); 1144 if (IS_ERR(fid)) 1145 return PTR_ERR(fid); 1146 1147 if (!v9fs_proto_dotu(v9ses)) 1148 return -EBADF; 1149 1150 st = p9_client_stat(fid); 1151 if (IS_ERR(st)) 1152 return PTR_ERR(st); 1153 1154 if (!(st->mode & P9_DMSYMLINK)) { 1155 retval = -EINVAL; 1156 goto done; 1157 } 1158 1159 /* copy extension buffer into buffer */ 1160 strncpy(buffer, st->extension, buflen); 1161 1162 P9_DPRINTK(P9_DEBUG_VFS, 1163 "%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer); 1164 1165 retval = strnlen(buffer, buflen); 1166 done: 1167 p9stat_free(st); 1168 kfree(st); 1169 return retval; 1170 } 1171 1172 /** 1173 * v9fs_vfs_follow_link - follow a symlink path 1174 * @dentry: dentry for symlink 1175 * @nd: nameidata 1176 * 1177 */ 1178 1179 static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) 1180 { 1181 int len = 0; 1182 char *link = __getname(); 1183 1184 P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name); 1185 1186 if (!link) 1187 link = ERR_PTR(-ENOMEM); 1188 else { 1189 len = v9fs_readlink(dentry, link, PATH_MAX); 1190 1191 if (len < 0) { 1192 __putname(link); 1193 link = ERR_PTR(len); 1194 } else 1195 link[min(len, PATH_MAX-1)] = 0; 1196 } 1197 nd_set_link(nd, link); 1198 1199 return NULL; 1200 } 1201 1202 /** 1203 * v9fs_vfs_put_link - release a symlink path 1204 * @dentry: dentry for symlink 1205 * @nd: nameidata 1206 * @p: unused 1207 * 1208 */ 1209 1210 void 1211 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) 1212 { 1213 char *s = nd_get_link(nd); 1214 1215 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, 1216 IS_ERR(s) ? "<error>" : s); 1217 if (!IS_ERR(s)) 1218 __putname(s); 1219 } 1220 1221 /** 1222 * v9fs_vfs_mkspecial - create a special file 1223 * @dir: inode to create special file in 1224 * @dentry: dentry to create 1225 * @mode: mode to create special file 1226 * @extension: 9p2000.u format extension string representing special file 1227 * 1228 */ 1229 1230 static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, 1231 int mode, const char *extension) 1232 { 1233 u32 perm; 1234 struct p9_fid *fid; 1235 struct v9fs_session_info *v9ses; 1236 1237 v9ses = v9fs_inode2v9ses(dir); 1238 if (!v9fs_proto_dotu(v9ses)) { 1239 P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n"); 1240 return -EPERM; 1241 } 1242 1243 perm = unixmode2p9mode(v9ses, mode); 1244 fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm, 1245 P9_OREAD); 1246 if (IS_ERR(fid)) 1247 return PTR_ERR(fid); 1248 1249 v9fs_invalidate_inode_attr(dir); 1250 p9_client_clunk(fid); 1251 return 0; 1252 } 1253 1254 /** 1255 * v9fs_vfs_symlink - helper function to create symlinks 1256 * @dir: directory inode containing symlink 1257 * @dentry: dentry for symlink 1258 * @symname: symlink data 1259 * 1260 * See Also: 9P2000.u RFC for more information 1261 * 1262 */ 1263 1264 static int 1265 v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) 1266 { 1267 P9_DPRINTK(P9_DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, 1268 dentry->d_name.name, symname); 1269 1270 return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname); 1271 } 1272 1273 /** 1274 * v9fs_vfs_link - create a hardlink 1275 * @old_dentry: dentry for file to link to 1276 * @dir: inode destination for new link 1277 * @dentry: dentry for link 1278 * 1279 */ 1280 1281 static int 1282 v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, 1283 struct dentry *dentry) 1284 { 1285 int retval; 1286 char *name; 1287 struct p9_fid *oldfid; 1288 1289 P9_DPRINTK(P9_DEBUG_VFS, 1290 " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 1291 old_dentry->d_name.name); 1292 1293 oldfid = v9fs_fid_clone(old_dentry); 1294 if (IS_ERR(oldfid)) 1295 return PTR_ERR(oldfid); 1296 1297 name = __getname(); 1298 if (unlikely(!name)) { 1299 retval = -ENOMEM; 1300 goto clunk_fid; 1301 } 1302 1303 sprintf(name, "%d\n", oldfid->fid); 1304 retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name); 1305 __putname(name); 1306 if (!retval) { 1307 v9fs_refresh_inode(oldfid, old_dentry->d_inode); 1308 v9fs_invalidate_inode_attr(dir); 1309 } 1310 clunk_fid: 1311 p9_client_clunk(oldfid); 1312 return retval; 1313 } 1314 1315 /** 1316 * v9fs_vfs_mknod - create a special file 1317 * @dir: inode destination for new link 1318 * @dentry: dentry for file 1319 * @mode: mode for creation 1320 * @rdev: device associated with special file 1321 * 1322 */ 1323 1324 static int 1325 v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) 1326 { 1327 int retval; 1328 char *name; 1329 1330 P9_DPRINTK(P9_DEBUG_VFS, 1331 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1332 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); 1333 1334 if (!new_valid_dev(rdev)) 1335 return -EINVAL; 1336 1337 name = __getname(); 1338 if (!name) 1339 return -ENOMEM; 1340 /* build extension */ 1341 if (S_ISBLK(mode)) 1342 sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev)); 1343 else if (S_ISCHR(mode)) 1344 sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev)); 1345 else if (S_ISFIFO(mode)) 1346 *name = 0; 1347 else if (S_ISSOCK(mode)) 1348 *name = 0; 1349 else { 1350 __putname(name); 1351 return -EINVAL; 1352 } 1353 1354 retval = v9fs_vfs_mkspecial(dir, dentry, mode, name); 1355 __putname(name); 1356 1357 return retval; 1358 } 1359 1360 int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode) 1361 { 1362 loff_t i_size; 1363 struct p9_wstat *st; 1364 struct v9fs_session_info *v9ses; 1365 1366 v9ses = v9fs_inode2v9ses(inode); 1367 st = p9_client_stat(fid); 1368 if (IS_ERR(st)) 1369 return PTR_ERR(st); 1370 1371 spin_lock(&inode->i_lock); 1372 /* 1373 * We don't want to refresh inode->i_size, 1374 * because we may have cached data 1375 */ 1376 i_size = inode->i_size; 1377 v9fs_stat2inode(st, inode, inode->i_sb); 1378 if (v9ses->cache) 1379 inode->i_size = i_size; 1380 spin_unlock(&inode->i_lock); 1381 p9stat_free(st); 1382 kfree(st); 1383 return 0; 1384 } 1385 1386 static const struct inode_operations v9fs_dir_inode_operations_dotu = { 1387 .create = v9fs_vfs_create, 1388 .lookup = v9fs_vfs_lookup, 1389 .symlink = v9fs_vfs_symlink, 1390 .link = v9fs_vfs_link, 1391 .unlink = v9fs_vfs_unlink, 1392 .mkdir = v9fs_vfs_mkdir, 1393 .rmdir = v9fs_vfs_rmdir, 1394 .mknod = v9fs_vfs_mknod, 1395 .rename = v9fs_vfs_rename, 1396 .getattr = v9fs_vfs_getattr, 1397 .setattr = v9fs_vfs_setattr, 1398 }; 1399 1400 static const struct inode_operations v9fs_dir_inode_operations = { 1401 .create = v9fs_vfs_create, 1402 .lookup = v9fs_vfs_lookup, 1403 .unlink = v9fs_vfs_unlink, 1404 .mkdir = v9fs_vfs_mkdir, 1405 .rmdir = v9fs_vfs_rmdir, 1406 .mknod = v9fs_vfs_mknod, 1407 .rename = v9fs_vfs_rename, 1408 .getattr = v9fs_vfs_getattr, 1409 .setattr = v9fs_vfs_setattr, 1410 }; 1411 1412 static const struct inode_operations v9fs_file_inode_operations = { 1413 .getattr = v9fs_vfs_getattr, 1414 .setattr = v9fs_vfs_setattr, 1415 }; 1416 1417 static const struct inode_operations v9fs_symlink_inode_operations = { 1418 .readlink = generic_readlink, 1419 .follow_link = v9fs_vfs_follow_link, 1420 .put_link = v9fs_vfs_put_link, 1421 .getattr = v9fs_vfs_getattr, 1422 .setattr = v9fs_vfs_setattr, 1423 }; 1424 1425