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 48static const struct inode_operations v9fs_dir_inode_operations; 49static const struct inode_operations v9fs_dir_inode_operations_dotu; 50static const struct inode_operations v9fs_dir_inode_operations_dotl; 51static const struct inode_operations v9fs_file_inode_operations; 52static const struct inode_operations v9fs_file_inode_operations_dotl; 53static const struct inode_operations v9fs_symlink_inode_operations; 54static 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 63static 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 103static 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 145int 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 185void 186v9fs_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 215struct 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 234void 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 246static 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 263static 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 282struct 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 370error: 371 iput(inode); 372 return ERR_PTR(err); 373} 374 375/* 376static struct v9fs_fid* 377v9fs_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 418clunk_fid: 419 v9fs_t_clunk(v9ses, nfid); 420 421error: 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 */ 433void 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 444static struct inode * 445v9fs_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; 473error: 474 p9stat_free(st); 475 kfree(st); 476 return ERR_PTR(err); 477} 478 479static struct inode * 480v9fs_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; 505error: 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 */ 518static inline struct inode * 519v9fs_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 536static 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 556static int 557v9fs_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 */ 573static struct p9_fid * 574v9fs_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 638error: 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 657static int 658v9fs_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 if (v9ses->cache) 734 dentry->d_op = &v9fs_cached_dentry_operations; 735 else 736 dentry->d_op = &v9fs_dentry_operations; 737 d_instantiate(dentry, inode); 738 err = v9fs_fid_add(dentry, fid); 739 if (err < 0) 740 goto error; 741 742 /* if we are opening a file, assign the open fid to the file */ 743 if (nd && nd->flags & LOOKUP_OPEN) { 744 filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); 745 if (IS_ERR(filp)) { 746 p9_client_clunk(ofid); 747 return PTR_ERR(filp); 748 } 749 filp->private_data = ofid; 750 } else 751 p9_client_clunk(ofid); 752 753 return 0; 754 755error: 756 if (ofid) 757 p9_client_clunk(ofid); 758 if (fid) 759 p9_client_clunk(fid); 760 return err; 761} 762 763/** 764 * v9fs_vfs_create - VFS hook to create files 765 * @dir: directory inode that is being created 766 * @dentry: dentry that is being deleted 767 * @mode: create permissions 768 * @nd: path information 769 * 770 */ 771 772static int 773v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, 774 struct nameidata *nd) 775{ 776 int err; 777 u32 perm; 778 int flags; 779 struct v9fs_session_info *v9ses; 780 struct p9_fid *fid; 781 struct file *filp; 782 783 err = 0; 784 fid = NULL; 785 v9ses = v9fs_inode2v9ses(dir); 786 perm = unixmode2p9mode(v9ses, mode); 787 if (nd && nd->flags & LOOKUP_OPEN) 788 flags = nd->intent.open.flags - 1; 789 else 790 flags = O_RDWR; 791 792 fid = v9fs_create(v9ses, dir, dentry, NULL, perm, 793 v9fs_uflags2omode(flags, 794 v9fs_proto_dotu(v9ses))); 795 if (IS_ERR(fid)) { 796 err = PTR_ERR(fid); 797 fid = NULL; 798 goto error; 799 } 800 801 /* if we are opening a file, assign the open fid to the file */ 802 if (nd && nd->flags & LOOKUP_OPEN) { 803 filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); 804 if (IS_ERR(filp)) { 805 err = PTR_ERR(filp); 806 goto error; 807 } 808 809 filp->private_data = fid; 810 } else 811 p9_client_clunk(fid); 812 813 return 0; 814 815error: 816 if (fid) 817 p9_client_clunk(fid); 818 819 return err; 820} 821 822/** 823 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory 824 * @dir: inode that is being unlinked 825 * @dentry: dentry that is being unlinked 826 * @mode: mode for new directory 827 * 828 */ 829 830static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 831{ 832 int err; 833 u32 perm; 834 struct v9fs_session_info *v9ses; 835 struct p9_fid *fid; 836 837 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 838 err = 0; 839 v9ses = v9fs_inode2v9ses(dir); 840 perm = unixmode2p9mode(v9ses, mode | S_IFDIR); 841 fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD); 842 if (IS_ERR(fid)) { 843 err = PTR_ERR(fid); 844 fid = NULL; 845 } 846 847 if (fid) 848 p9_client_clunk(fid); 849 850 return err; 851} 852 853 854/** 855 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory 856 * @dir: inode that is being unlinked 857 * @dentry: dentry that is being unlinked 858 * @mode: mode for new directory 859 * 860 */ 861 862static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry, 863 int mode) 864{ 865 int err; 866 struct v9fs_session_info *v9ses; 867 struct p9_fid *fid = NULL, *dfid = NULL; 868 gid_t gid; 869 char *name; 870 struct inode *inode; 871 struct p9_qid qid; 872 struct dentry *dir_dentry; 873 874 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 875 err = 0; 876 v9ses = v9fs_inode2v9ses(dir); 877 878 mode |= S_IFDIR; 879 dir_dentry = v9fs_dentry_from_dir_inode(dir); 880 dfid = v9fs_fid_lookup(dir_dentry); 881 if (IS_ERR(dfid)) { 882 err = PTR_ERR(dfid); 883 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 884 dfid = NULL; 885 goto error; 886 } 887 888 gid = v9fs_get_fsgid_for_create(dir); 889 if (gid < 0) { 890 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_fsgid_for_create failed\n"); 891 goto error; 892 } 893 894 name = (char *) dentry->d_name.name; 895 err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid); 896 if (err < 0) 897 goto error; 898 899 /* instantiate inode and assign the unopened fid to the dentry */ 900 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 901 fid = p9_client_walk(dfid, 1, &name, 1); 902 if (IS_ERR(fid)) { 903 err = PTR_ERR(fid); 904 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 905 err); 906 fid = NULL; 907 goto error; 908 } 909 910 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 911 if (IS_ERR(inode)) { 912 err = PTR_ERR(inode); 913 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 914 err); 915 goto error; 916 } 917 dentry->d_op = &v9fs_cached_dentry_operations; 918 d_instantiate(dentry, inode); 919 err = v9fs_fid_add(dentry, fid); 920 if (err < 0) 921 goto error; 922 fid = NULL; 923 } 924error: 925 if (fid) 926 p9_client_clunk(fid); 927 return err; 928} 929 930/** 931 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode 932 * @dir: inode that is being walked from 933 * @dentry: dentry that is being walked to? 934 * @nameidata: path data 935 * 936 */ 937 938static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, 939 struct nameidata *nameidata) 940{ 941 struct super_block *sb; 942 struct v9fs_session_info *v9ses; 943 struct p9_fid *dfid, *fid; 944 struct inode *inode; 945 char *name; 946 int result = 0; 947 948 P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", 949 dir, dentry->d_name.name, dentry, nameidata); 950 951 if (dentry->d_name.len > NAME_MAX) 952 return ERR_PTR(-ENAMETOOLONG); 953 954 sb = dir->i_sb; 955 v9ses = v9fs_inode2v9ses(dir); 956 /* We can walk d_parent because we hold the dir->i_mutex */ 957 dfid = v9fs_fid_lookup(dentry->d_parent); 958 if (IS_ERR(dfid)) 959 return ERR_CAST(dfid); 960 961 name = (char *) dentry->d_name.name; 962 fid = p9_client_walk(dfid, 1, &name, 1); 963 if (IS_ERR(fid)) { 964 result = PTR_ERR(fid); 965 if (result == -ENOENT) { 966 inode = NULL; 967 goto inst_out; 968 } 969 970 return ERR_PTR(result); 971 } 972 973 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 974 if (IS_ERR(inode)) { 975 result = PTR_ERR(inode); 976 inode = NULL; 977 goto error; 978 } 979 980 result = v9fs_fid_add(dentry, fid); 981 if (result < 0) 982 goto error; 983 984inst_out: 985 if (v9ses->cache) 986 dentry->d_op = &v9fs_cached_dentry_operations; 987 else 988 dentry->d_op = &v9fs_dentry_operations; 989 990 d_add(dentry, inode); 991 return NULL; 992 993error: 994 p9_client_clunk(fid); 995 996 return ERR_PTR(result); 997} 998 999/** 1000 * v9fs_vfs_unlink - VFS unlink hook to delete an inode 1001 * @i: inode that is being unlinked 1002 * @d: dentry that is being unlinked 1003 * 1004 */ 1005 1006static int v9fs_vfs_unlink(struct inode *i, struct dentry *d) 1007{ 1008 return v9fs_remove(i, d, 0); 1009} 1010 1011/** 1012 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory 1013 * @i: inode that is being unlinked 1014 * @d: dentry that is being unlinked 1015 * 1016 */ 1017 1018static int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) 1019{ 1020 return v9fs_remove(i, d, 1); 1021} 1022 1023/** 1024 * v9fs_vfs_rename - VFS hook to rename an inode 1025 * @old_dir: old dir inode 1026 * @old_dentry: old dentry 1027 * @new_dir: new dir inode 1028 * @new_dentry: new dentry 1029 * 1030 */ 1031 1032static int 1033v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, 1034 struct inode *new_dir, struct dentry *new_dentry) 1035{ 1036 struct inode *old_inode; 1037 struct v9fs_session_info *v9ses; 1038 struct p9_fid *oldfid; 1039 struct p9_fid *olddirfid; 1040 struct p9_fid *newdirfid; 1041 struct p9_wstat wstat; 1042 int retval; 1043 1044 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 1045 retval = 0; 1046 old_inode = old_dentry->d_inode; 1047 v9ses = v9fs_inode2v9ses(old_inode); 1048 oldfid = v9fs_fid_lookup(old_dentry); 1049 if (IS_ERR(oldfid)) 1050 return PTR_ERR(oldfid); 1051 1052 olddirfid = v9fs_fid_clone(old_dentry->d_parent); 1053 if (IS_ERR(olddirfid)) { 1054 retval = PTR_ERR(olddirfid); 1055 goto done; 1056 } 1057 1058 newdirfid = v9fs_fid_clone(new_dentry->d_parent); 1059 if (IS_ERR(newdirfid)) { 1060 retval = PTR_ERR(newdirfid); 1061 goto clunk_olddir; 1062 } 1063 1064 down_write(&v9ses->rename_sem); 1065 if (v9fs_proto_dotl(v9ses)) { 1066 retval = p9_client_rename(oldfid, newdirfid, 1067 (char *) new_dentry->d_name.name); 1068 if (retval != -ENOSYS) 1069 goto clunk_newdir; 1070 } 1071 if (old_dentry->d_parent != new_dentry->d_parent) { 1072 /* 1073 * 9P .u can only handle file rename in the same directory 1074 */ 1075 1076 P9_DPRINTK(P9_DEBUG_ERROR, 1077 "old dir and new dir are different\n"); 1078 retval = -EXDEV; 1079 goto clunk_newdir; 1080 } 1081 v9fs_blank_wstat(&wstat); 1082 wstat.muid = v9ses->uname; 1083 wstat.name = (char *) new_dentry->d_name.name; 1084 retval = p9_client_wstat(oldfid, &wstat); 1085 1086clunk_newdir: 1087 if (!retval) 1088 /* successful rename */ 1089 d_move(old_dentry, new_dentry); 1090 up_write(&v9ses->rename_sem); 1091 p9_client_clunk(newdirfid); 1092 1093clunk_olddir: 1094 p9_client_clunk(olddirfid); 1095 1096done: 1097 return retval; 1098} 1099 1100/** 1101 * v9fs_vfs_getattr - retrieve file metadata 1102 * @mnt: mount information 1103 * @dentry: file to get attributes on 1104 * @stat: metadata structure to populate 1105 * 1106 */ 1107 1108static int 1109v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 1110 struct kstat *stat) 1111{ 1112 int err; 1113 struct v9fs_session_info *v9ses; 1114 struct p9_fid *fid; 1115 struct p9_wstat *st; 1116 1117 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 1118 err = -EPERM; 1119 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1120 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) 1121 return simple_getattr(mnt, dentry, stat); 1122 1123 fid = v9fs_fid_lookup(dentry); 1124 if (IS_ERR(fid)) 1125 return PTR_ERR(fid); 1126 1127 st = p9_client_stat(fid); 1128 if (IS_ERR(st)) 1129 return PTR_ERR(st); 1130 1131 v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); 1132 generic_fillattr(dentry->d_inode, stat); 1133 1134 p9stat_free(st); 1135 kfree(st); 1136 return 0; 1137} 1138 1139static int 1140v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry, 1141 struct kstat *stat) 1142{ 1143 int err; 1144 struct v9fs_session_info *v9ses; 1145 struct p9_fid *fid; 1146 struct p9_stat_dotl *st; 1147 1148 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 1149 err = -EPERM; 1150 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1151 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) 1152 return simple_getattr(mnt, dentry, stat); 1153 1154 fid = v9fs_fid_lookup(dentry); 1155 if (IS_ERR(fid)) 1156 return PTR_ERR(fid); 1157 1158 /* Ask for all the fields in stat structure. Server will return 1159 * whatever it supports 1160 */ 1161 1162 st = p9_client_getattr_dotl(fid, P9_STATS_ALL); 1163 if (IS_ERR(st)) 1164 return PTR_ERR(st); 1165 1166 v9fs_stat2inode_dotl(st, dentry->d_inode); 1167 generic_fillattr(dentry->d_inode, stat); 1168 /* Change block size to what the server returned */ 1169 stat->blksize = st->st_blksize; 1170 1171 kfree(st); 1172 return 0; 1173} 1174 1175/** 1176 * v9fs_vfs_setattr - set file metadata 1177 * @dentry: file whose metadata to set 1178 * @iattr: metadata assignment structure 1179 * 1180 */ 1181 1182static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) 1183{ 1184 int retval; 1185 struct v9fs_session_info *v9ses; 1186 struct p9_fid *fid; 1187 struct p9_wstat wstat; 1188 1189 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 1190 retval = -EPERM; 1191 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1192 fid = v9fs_fid_lookup(dentry); 1193 if(IS_ERR(fid)) 1194 return PTR_ERR(fid); 1195 1196 v9fs_blank_wstat(&wstat); 1197 if (iattr->ia_valid & ATTR_MODE) 1198 wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode); 1199 1200 if (iattr->ia_valid & ATTR_MTIME) 1201 wstat.mtime = iattr->ia_mtime.tv_sec; 1202 1203 if (iattr->ia_valid & ATTR_ATIME) 1204 wstat.atime = iattr->ia_atime.tv_sec; 1205 1206 if (iattr->ia_valid & ATTR_SIZE) 1207 wstat.length = iattr->ia_size; 1208 1209 if (v9fs_proto_dotu(v9ses)) { 1210 if (iattr->ia_valid & ATTR_UID) 1211 wstat.n_uid = iattr->ia_uid; 1212 1213 if (iattr->ia_valid & ATTR_GID) 1214 wstat.n_gid = iattr->ia_gid; 1215 } 1216 1217 retval = p9_client_wstat(fid, &wstat); 1218 if (retval < 0) 1219 return retval; 1220 1221 if ((iattr->ia_valid & ATTR_SIZE) && 1222 iattr->ia_size != i_size_read(dentry->d_inode)) { 1223 retval = vmtruncate(dentry->d_inode, iattr->ia_size); 1224 if (retval) 1225 return retval; 1226 } 1227 1228 setattr_copy(dentry->d_inode, iattr); 1229 mark_inode_dirty(dentry->d_inode); 1230 return 0; 1231} 1232 1233/** 1234 * v9fs_vfs_setattr_dotl - set file metadata 1235 * @dentry: file whose metadata to set 1236 * @iattr: metadata assignment structure 1237 * 1238 */ 1239 1240static int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr) 1241{ 1242 int retval; 1243 struct v9fs_session_info *v9ses; 1244 struct p9_fid *fid; 1245 struct p9_iattr_dotl p9attr; 1246 1247 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 1248 1249 retval = inode_change_ok(dentry->d_inode, iattr); 1250 if (retval) 1251 return retval; 1252 1253 p9attr.valid = iattr->ia_valid; 1254 p9attr.mode = iattr->ia_mode; 1255 p9attr.uid = iattr->ia_uid; 1256 p9attr.gid = iattr->ia_gid; 1257 p9attr.size = iattr->ia_size; 1258 p9attr.atime_sec = iattr->ia_atime.tv_sec; 1259 p9attr.atime_nsec = iattr->ia_atime.tv_nsec; 1260 p9attr.mtime_sec = iattr->ia_mtime.tv_sec; 1261 p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec; 1262 1263 retval = -EPERM; 1264 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1265 fid = v9fs_fid_lookup(dentry); 1266 if (IS_ERR(fid)) 1267 return PTR_ERR(fid); 1268 1269 retval = p9_client_setattr(fid, &p9attr); 1270 if (retval < 0) 1271 return retval; 1272 1273 if ((iattr->ia_valid & ATTR_SIZE) && 1274 iattr->ia_size != i_size_read(dentry->d_inode)) { 1275 retval = vmtruncate(dentry->d_inode, iattr->ia_size); 1276 if (retval) 1277 return retval; 1278 } 1279 1280 setattr_copy(dentry->d_inode, iattr); 1281 mark_inode_dirty(dentry->d_inode); 1282 return 0; 1283} 1284 1285/** 1286 * v9fs_stat2inode - populate an inode structure with mistat info 1287 * @stat: Plan 9 metadata (mistat) structure 1288 * @inode: inode to populate 1289 * @sb: superblock of filesystem 1290 * 1291 */ 1292 1293void 1294v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode, 1295 struct super_block *sb) 1296{ 1297 char ext[32]; 1298 char tag_name[14]; 1299 unsigned int i_nlink; 1300 struct v9fs_session_info *v9ses = sb->s_fs_info; 1301 1302 inode->i_nlink = 1; 1303 1304 inode->i_atime.tv_sec = stat->atime; 1305 inode->i_mtime.tv_sec = stat->mtime; 1306 inode->i_ctime.tv_sec = stat->mtime; 1307 1308 inode->i_uid = v9ses->dfltuid; 1309 inode->i_gid = v9ses->dfltgid; 1310 1311 if (v9fs_proto_dotu(v9ses)) { 1312 inode->i_uid = stat->n_uid; 1313 inode->i_gid = stat->n_gid; 1314 } 1315 if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) { 1316 if (v9fs_proto_dotu(v9ses) && (stat->extension[0] != '\0')) { 1317 /* 1318 * Hadlink support got added later to 1319 * to the .u extension. So there can be 1320 * server out there that doesn't support 1321 * this even with .u extension. So check 1322 * for non NULL stat->extension 1323 */ 1324 strncpy(ext, stat->extension, sizeof(ext)); 1325 /* HARDLINKCOUNT %u */ 1326 sscanf(ext, "%13s %u", tag_name, &i_nlink); 1327 if (!strncmp(tag_name, "HARDLINKCOUNT", 13)) 1328 inode->i_nlink = i_nlink; 1329 } 1330 } 1331 inode->i_mode = p9mode2unixmode(v9ses, stat->mode); 1332 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) { 1333 char type = 0; 1334 int major = -1; 1335 int minor = -1; 1336 1337 strncpy(ext, stat->extension, sizeof(ext)); 1338 sscanf(ext, "%c %u %u", &type, &major, &minor); 1339 switch (type) { 1340 case 'c': 1341 inode->i_mode &= ~S_IFBLK; 1342 inode->i_mode |= S_IFCHR; 1343 break; 1344 case 'b': 1345 break; 1346 default: 1347 P9_DPRINTK(P9_DEBUG_ERROR, 1348 "Unknown special type %c %s\n", type, 1349 stat->extension); 1350 }; 1351 inode->i_rdev = MKDEV(major, minor); 1352 init_special_inode(inode, inode->i_mode, inode->i_rdev); 1353 } else 1354 inode->i_rdev = 0; 1355 1356 i_size_write(inode, stat->length); 1357 1358 /* not real number of blocks, but 512 byte ones ... */ 1359 inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9; 1360} 1361 1362/** 1363 * v9fs_stat2inode_dotl - populate an inode structure with stat info 1364 * @stat: stat structure 1365 * @inode: inode to populate 1366 * @sb: superblock of filesystem 1367 * 1368 */ 1369 1370void 1371v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode) 1372{ 1373 1374 if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) { 1375 inode->i_atime.tv_sec = stat->st_atime_sec; 1376 inode->i_atime.tv_nsec = stat->st_atime_nsec; 1377 inode->i_mtime.tv_sec = stat->st_mtime_sec; 1378 inode->i_mtime.tv_nsec = stat->st_mtime_nsec; 1379 inode->i_ctime.tv_sec = stat->st_ctime_sec; 1380 inode->i_ctime.tv_nsec = stat->st_ctime_nsec; 1381 inode->i_uid = stat->st_uid; 1382 inode->i_gid = stat->st_gid; 1383 inode->i_nlink = stat->st_nlink; 1384 inode->i_mode = stat->st_mode; 1385 inode->i_rdev = new_decode_dev(stat->st_rdev); 1386 1387 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) 1388 init_special_inode(inode, inode->i_mode, inode->i_rdev); 1389 1390 i_size_write(inode, stat->st_size); 1391 inode->i_blocks = stat->st_blocks; 1392 } else { 1393 if (stat->st_result_mask & P9_STATS_ATIME) { 1394 inode->i_atime.tv_sec = stat->st_atime_sec; 1395 inode->i_atime.tv_nsec = stat->st_atime_nsec; 1396 } 1397 if (stat->st_result_mask & P9_STATS_MTIME) { 1398 inode->i_mtime.tv_sec = stat->st_mtime_sec; 1399 inode->i_mtime.tv_nsec = stat->st_mtime_nsec; 1400 } 1401 if (stat->st_result_mask & P9_STATS_CTIME) { 1402 inode->i_ctime.tv_sec = stat->st_ctime_sec; 1403 inode->i_ctime.tv_nsec = stat->st_ctime_nsec; 1404 } 1405 if (stat->st_result_mask & P9_STATS_UID) 1406 inode->i_uid = stat->st_uid; 1407 if (stat->st_result_mask & P9_STATS_GID) 1408 inode->i_gid = stat->st_gid; 1409 if (stat->st_result_mask & P9_STATS_NLINK) 1410 inode->i_nlink = stat->st_nlink; 1411 if (stat->st_result_mask & P9_STATS_MODE) { 1412 inode->i_mode = stat->st_mode; 1413 if ((S_ISBLK(inode->i_mode)) || 1414 (S_ISCHR(inode->i_mode))) 1415 init_special_inode(inode, inode->i_mode, 1416 inode->i_rdev); 1417 } 1418 if (stat->st_result_mask & P9_STATS_RDEV) 1419 inode->i_rdev = new_decode_dev(stat->st_rdev); 1420 if (stat->st_result_mask & P9_STATS_SIZE) 1421 i_size_write(inode, stat->st_size); 1422 if (stat->st_result_mask & P9_STATS_BLOCKS) 1423 inode->i_blocks = stat->st_blocks; 1424 } 1425 if (stat->st_result_mask & P9_STATS_GEN) 1426 inode->i_generation = stat->st_gen; 1427 1428 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION 1429 * because the inode structure does not have fields for them. 1430 */ 1431} 1432 1433/** 1434 * v9fs_qid2ino - convert qid into inode number 1435 * @qid: qid to hash 1436 * 1437 * BUG: potential for inode number collisions? 1438 */ 1439 1440ino_t v9fs_qid2ino(struct p9_qid *qid) 1441{ 1442 u64 path = qid->path + 2; 1443 ino_t i = 0; 1444 1445 if (sizeof(ino_t) == sizeof(path)) 1446 memcpy(&i, &path, sizeof(ino_t)); 1447 else 1448 i = (ino_t) (path ^ (path >> 32)); 1449 1450 return i; 1451} 1452 1453/** 1454 * v9fs_readlink - read a symlink's location (internal version) 1455 * @dentry: dentry for symlink 1456 * @buffer: buffer to load symlink location into 1457 * @buflen: length of buffer 1458 * 1459 */ 1460 1461static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) 1462{ 1463 int retval; 1464 1465 struct v9fs_session_info *v9ses; 1466 struct p9_fid *fid; 1467 struct p9_wstat *st; 1468 1469 P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); 1470 retval = -EPERM; 1471 v9ses = v9fs_inode2v9ses(dentry->d_inode); 1472 fid = v9fs_fid_lookup(dentry); 1473 if (IS_ERR(fid)) 1474 return PTR_ERR(fid); 1475 1476 if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) 1477 return -EBADF; 1478 1479 st = p9_client_stat(fid); 1480 if (IS_ERR(st)) 1481 return PTR_ERR(st); 1482 1483 if (!(st->mode & P9_DMSYMLINK)) { 1484 retval = -EINVAL; 1485 goto done; 1486 } 1487 1488 /* copy extension buffer into buffer */ 1489 strncpy(buffer, st->extension, buflen); 1490 1491 P9_DPRINTK(P9_DEBUG_VFS, 1492 "%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer); 1493 1494 retval = strnlen(buffer, buflen); 1495done: 1496 p9stat_free(st); 1497 kfree(st); 1498 return retval; 1499} 1500 1501/** 1502 * v9fs_vfs_follow_link - follow a symlink path 1503 * @dentry: dentry for symlink 1504 * @nd: nameidata 1505 * 1506 */ 1507 1508static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) 1509{ 1510 int len = 0; 1511 char *link = __getname(); 1512 1513 P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name); 1514 1515 if (!link) 1516 link = ERR_PTR(-ENOMEM); 1517 else { 1518 len = v9fs_readlink(dentry, link, PATH_MAX); 1519 1520 if (len < 0) { 1521 __putname(link); 1522 link = ERR_PTR(len); 1523 } else 1524 link[min(len, PATH_MAX-1)] = 0; 1525 } 1526 nd_set_link(nd, link); 1527 1528 return NULL; 1529} 1530 1531/** 1532 * v9fs_vfs_put_link - release a symlink path 1533 * @dentry: dentry for symlink 1534 * @nd: nameidata 1535 * @p: unused 1536 * 1537 */ 1538 1539static void 1540v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) 1541{ 1542 char *s = nd_get_link(nd); 1543 1544 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, 1545 IS_ERR(s) ? "<error>" : s); 1546 if (!IS_ERR(s)) 1547 __putname(s); 1548} 1549 1550/** 1551 * v9fs_vfs_mkspecial - create a special file 1552 * @dir: inode to create special file in 1553 * @dentry: dentry to create 1554 * @mode: mode to create special file 1555 * @extension: 9p2000.u format extension string representing special file 1556 * 1557 */ 1558 1559static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, 1560 int mode, const char *extension) 1561{ 1562 u32 perm; 1563 struct v9fs_session_info *v9ses; 1564 struct p9_fid *fid; 1565 1566 v9ses = v9fs_inode2v9ses(dir); 1567 if (!v9fs_proto_dotu(v9ses)) { 1568 P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n"); 1569 return -EPERM; 1570 } 1571 1572 perm = unixmode2p9mode(v9ses, mode); 1573 fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm, 1574 P9_OREAD); 1575 if (IS_ERR(fid)) 1576 return PTR_ERR(fid); 1577 1578 p9_client_clunk(fid); 1579 return 0; 1580} 1581 1582/** 1583 * v9fs_vfs_symlink_dotl - helper function to create symlinks 1584 * @dir: directory inode containing symlink 1585 * @dentry: dentry for symlink 1586 * @symname: symlink data 1587 * 1588 * See Also: 9P2000.L RFC for more information 1589 * 1590 */ 1591 1592static int 1593v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, 1594 const char *symname) 1595{ 1596 struct v9fs_session_info *v9ses; 1597 struct p9_fid *dfid; 1598 struct p9_fid *fid = NULL; 1599 struct inode *inode; 1600 struct p9_qid qid; 1601 char *name; 1602 int err; 1603 gid_t gid; 1604 1605 name = (char *) dentry->d_name.name; 1606 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n", 1607 dir->i_ino, name, symname); 1608 v9ses = v9fs_inode2v9ses(dir); 1609 1610 dfid = v9fs_fid_lookup(dentry->d_parent); 1611 if (IS_ERR(dfid)) { 1612 err = PTR_ERR(dfid); 1613 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 1614 return err; 1615 } 1616 1617 gid = v9fs_get_fsgid_for_create(dir); 1618 1619 if (gid < 0) { 1620 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_egid failed %d\n", gid); 1621 goto error; 1622 } 1623 1624 /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */ 1625 err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid); 1626 1627 if (err < 0) { 1628 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err); 1629 goto error; 1630 } 1631 1632 if (v9ses->cache) { 1633 /* Now walk from the parent so we can get an unopened fid. */ 1634 fid = p9_client_walk(dfid, 1, &name, 1); 1635 if (IS_ERR(fid)) { 1636 err = PTR_ERR(fid); 1637 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 1638 err); 1639 fid = NULL; 1640 goto error; 1641 } 1642 1643 /* instantiate inode and assign the unopened fid to dentry */ 1644 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 1645 if (IS_ERR(inode)) { 1646 err = PTR_ERR(inode); 1647 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 1648 err); 1649 goto error; 1650 } 1651 dentry->d_op = &v9fs_cached_dentry_operations; 1652 d_instantiate(dentry, inode); 1653 err = v9fs_fid_add(dentry, fid); 1654 if (err < 0) 1655 goto error; 1656 fid = NULL; 1657 } else { 1658 /* Not in cached mode. No need to populate inode with stat */ 1659 inode = v9fs_get_inode(dir->i_sb, S_IFLNK); 1660 if (IS_ERR(inode)) { 1661 err = PTR_ERR(inode); 1662 goto error; 1663 } 1664 dentry->d_op = &v9fs_dentry_operations; 1665 d_instantiate(dentry, inode); 1666 } 1667 1668error: 1669 if (fid) 1670 p9_client_clunk(fid); 1671 1672 return err; 1673} 1674 1675/** 1676 * v9fs_vfs_symlink - helper function to create symlinks 1677 * @dir: directory inode containing symlink 1678 * @dentry: dentry for symlink 1679 * @symname: symlink data 1680 * 1681 * See Also: 9P2000.u RFC for more information 1682 * 1683 */ 1684 1685static int 1686v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) 1687{ 1688 P9_DPRINTK(P9_DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, 1689 dentry->d_name.name, symname); 1690 1691 return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname); 1692} 1693 1694/** 1695 * v9fs_vfs_link - create a hardlink 1696 * @old_dentry: dentry for file to link to 1697 * @dir: inode destination for new link 1698 * @dentry: dentry for link 1699 * 1700 */ 1701 1702static int 1703v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, 1704 struct dentry *dentry) 1705{ 1706 int retval; 1707 struct p9_fid *oldfid; 1708 char *name; 1709 1710 P9_DPRINTK(P9_DEBUG_VFS, 1711 " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 1712 old_dentry->d_name.name); 1713 1714 oldfid = v9fs_fid_clone(old_dentry); 1715 if (IS_ERR(oldfid)) 1716 return PTR_ERR(oldfid); 1717 1718 name = __getname(); 1719 if (unlikely(!name)) { 1720 retval = -ENOMEM; 1721 goto clunk_fid; 1722 } 1723 1724 sprintf(name, "%d\n", oldfid->fid); 1725 retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name); 1726 __putname(name); 1727 1728clunk_fid: 1729 p9_client_clunk(oldfid); 1730 return retval; 1731} 1732 1733/** 1734 * v9fs_vfs_link_dotl - create a hardlink for dotl 1735 * @old_dentry: dentry for file to link to 1736 * @dir: inode destination for new link 1737 * @dentry: dentry for link 1738 * 1739 */ 1740 1741static int 1742v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, 1743 struct dentry *dentry) 1744{ 1745 int err; 1746 struct p9_fid *dfid, *oldfid; 1747 char *name; 1748 struct v9fs_session_info *v9ses; 1749 struct dentry *dir_dentry; 1750 1751 P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n", 1752 dir->i_ino, old_dentry->d_name.name, 1753 dentry->d_name.name); 1754 1755 v9ses = v9fs_inode2v9ses(dir); 1756 dir_dentry = v9fs_dentry_from_dir_inode(dir); 1757 dfid = v9fs_fid_lookup(dir_dentry); 1758 if (IS_ERR(dfid)) 1759 return PTR_ERR(dfid); 1760 1761 oldfid = v9fs_fid_lookup(old_dentry); 1762 if (IS_ERR(oldfid)) 1763 return PTR_ERR(oldfid); 1764 1765 name = (char *) dentry->d_name.name; 1766 1767 err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name); 1768 1769 if (err < 0) { 1770 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err); 1771 return err; 1772 } 1773 1774 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 1775 /* Get the latest stat info from server. */ 1776 struct p9_fid *fid; 1777 struct p9_stat_dotl *st; 1778 1779 fid = v9fs_fid_lookup(old_dentry); 1780 if (IS_ERR(fid)) 1781 return PTR_ERR(fid); 1782 1783 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC); 1784 if (IS_ERR(st)) 1785 return PTR_ERR(st); 1786 1787 v9fs_stat2inode_dotl(st, old_dentry->d_inode); 1788 1789 kfree(st); 1790 } else { 1791 /* Caching disabled. No need to get upto date stat info. 1792 * This dentry will be released immediately. So, just i_count++ 1793 */ 1794 atomic_inc(&old_dentry->d_inode->i_count); 1795 } 1796 1797 dentry->d_op = old_dentry->d_op; 1798 d_instantiate(dentry, old_dentry->d_inode); 1799 1800 return err; 1801} 1802 1803/** 1804 * v9fs_vfs_mknod - create a special file 1805 * @dir: inode destination for new link 1806 * @dentry: dentry for file 1807 * @mode: mode for creation 1808 * @rdev: device associated with special file 1809 * 1810 */ 1811 1812static int 1813v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) 1814{ 1815 int retval; 1816 char *name; 1817 1818 P9_DPRINTK(P9_DEBUG_VFS, 1819 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1820 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); 1821 1822 if (!new_valid_dev(rdev)) 1823 return -EINVAL; 1824 1825 name = __getname(); 1826 if (!name) 1827 return -ENOMEM; 1828 /* build extension */ 1829 if (S_ISBLK(mode)) 1830 sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev)); 1831 else if (S_ISCHR(mode)) 1832 sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev)); 1833 else if (S_ISFIFO(mode)) 1834 *name = 0; 1835 else if (S_ISSOCK(mode)) 1836 *name = 0; 1837 else { 1838 __putname(name); 1839 return -EINVAL; 1840 } 1841 1842 retval = v9fs_vfs_mkspecial(dir, dentry, mode, name); 1843 __putname(name); 1844 1845 return retval; 1846} 1847 1848/** 1849 * v9fs_vfs_mknod_dotl - create a special file 1850 * @dir: inode destination for new link 1851 * @dentry: dentry for file 1852 * @mode: mode for creation 1853 * @rdev: device associated with special file 1854 * 1855 */ 1856static int 1857v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode, 1858 dev_t rdev) 1859{ 1860 int err; 1861 char *name; 1862 struct v9fs_session_info *v9ses; 1863 struct p9_fid *fid = NULL, *dfid = NULL; 1864 struct inode *inode; 1865 gid_t gid; 1866 struct p9_qid qid; 1867 struct dentry *dir_dentry; 1868 1869 P9_DPRINTK(P9_DEBUG_VFS, 1870 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1871 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); 1872 1873 if (!new_valid_dev(rdev)) 1874 return -EINVAL; 1875 1876 v9ses = v9fs_inode2v9ses(dir); 1877 dir_dentry = v9fs_dentry_from_dir_inode(dir); 1878 dfid = v9fs_fid_lookup(dir_dentry); 1879 if (IS_ERR(dfid)) { 1880 err = PTR_ERR(dfid); 1881 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 1882 dfid = NULL; 1883 goto error; 1884 } 1885 1886 gid = v9fs_get_fsgid_for_create(dir); 1887 if (gid < 0) { 1888 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_fsgid_for_create failed\n"); 1889 goto error; 1890 } 1891 1892 name = (char *) dentry->d_name.name; 1893 1894 err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid); 1895 if (err < 0) 1896 goto error; 1897 1898 /* instantiate inode and assign the unopened fid to the dentry */ 1899 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 1900 fid = p9_client_walk(dfid, 1, &name, 1); 1901 if (IS_ERR(fid)) { 1902 err = PTR_ERR(fid); 1903 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 1904 err); 1905 fid = NULL; 1906 goto error; 1907 } 1908 1909 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); 1910 if (IS_ERR(inode)) { 1911 err = PTR_ERR(inode); 1912 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 1913 err); 1914 goto error; 1915 } 1916 dentry->d_op = &v9fs_cached_dentry_operations; 1917 d_instantiate(dentry, inode); 1918 err = v9fs_fid_add(dentry, fid); 1919 if (err < 0) 1920 goto error; 1921 fid = NULL; 1922 } else { 1923 /* 1924 * Not in cached mode. No need to populate inode with stat. 1925 * socket syscall returns a fd, so we need instantiate 1926 */ 1927 inode = v9fs_get_inode(dir->i_sb, mode); 1928 if (IS_ERR(inode)) { 1929 err = PTR_ERR(inode); 1930 goto error; 1931 } 1932 dentry->d_op = &v9fs_dentry_operations; 1933 d_instantiate(dentry, inode); 1934 } 1935 1936error: 1937 if (fid) 1938 p9_client_clunk(fid); 1939 return err; 1940} 1941 1942static const struct inode_operations v9fs_dir_inode_operations_dotu = { 1943 .create = v9fs_vfs_create, 1944 .lookup = v9fs_vfs_lookup, 1945 .symlink = v9fs_vfs_symlink, 1946 .link = v9fs_vfs_link, 1947 .unlink = v9fs_vfs_unlink, 1948 .mkdir = v9fs_vfs_mkdir, 1949 .rmdir = v9fs_vfs_rmdir, 1950 .mknod = v9fs_vfs_mknod, 1951 .rename = v9fs_vfs_rename, 1952 .getattr = v9fs_vfs_getattr, 1953 .setattr = v9fs_vfs_setattr, 1954}; 1955 1956static const struct inode_operations v9fs_dir_inode_operations_dotl = { 1957 .create = v9fs_vfs_create_dotl, 1958 .lookup = v9fs_vfs_lookup, 1959 .link = v9fs_vfs_link_dotl, 1960 .symlink = v9fs_vfs_symlink_dotl, 1961 .unlink = v9fs_vfs_unlink, 1962 .mkdir = v9fs_vfs_mkdir_dotl, 1963 .rmdir = v9fs_vfs_rmdir, 1964 .mknod = v9fs_vfs_mknod_dotl, 1965 .rename = v9fs_vfs_rename, 1966 .getattr = v9fs_vfs_getattr_dotl, 1967 .setattr = v9fs_vfs_setattr_dotl, 1968 .setxattr = generic_setxattr, 1969 .getxattr = generic_getxattr, 1970 .removexattr = generic_removexattr, 1971 .listxattr = v9fs_listxattr, 1972 1973}; 1974 1975static const struct inode_operations v9fs_dir_inode_operations = { 1976 .create = v9fs_vfs_create, 1977 .lookup = v9fs_vfs_lookup, 1978 .unlink = v9fs_vfs_unlink, 1979 .mkdir = v9fs_vfs_mkdir, 1980 .rmdir = v9fs_vfs_rmdir, 1981 .mknod = v9fs_vfs_mknod, 1982 .rename = v9fs_vfs_rename, 1983 .getattr = v9fs_vfs_getattr, 1984 .setattr = v9fs_vfs_setattr, 1985}; 1986 1987static const struct inode_operations v9fs_file_inode_operations = { 1988 .getattr = v9fs_vfs_getattr, 1989 .setattr = v9fs_vfs_setattr, 1990}; 1991 1992static const struct inode_operations v9fs_file_inode_operations_dotl = { 1993 .getattr = v9fs_vfs_getattr_dotl, 1994 .setattr = v9fs_vfs_setattr_dotl, 1995 .setxattr = generic_setxattr, 1996 .getxattr = generic_getxattr, 1997 .removexattr = generic_removexattr, 1998 .listxattr = v9fs_listxattr, 1999}; 2000 2001static const struct inode_operations v9fs_symlink_inode_operations = { 2002 .readlink = generic_readlink, 2003 .follow_link = v9fs_vfs_follow_link, 2004 .put_link = v9fs_vfs_put_link, 2005 .getattr = v9fs_vfs_getattr, 2006 .setattr = v9fs_vfs_setattr, 2007}; 2008 2009static const struct inode_operations v9fs_symlink_inode_operations_dotl = { 2010 .readlink = generic_readlink, 2011 .follow_link = v9fs_vfs_follow_link, 2012 .put_link = v9fs_vfs_put_link, 2013 .getattr = v9fs_vfs_getattr_dotl, 2014 .setattr = v9fs_vfs_setattr_dotl, 2015 .setxattr = generic_setxattr, 2016 .getxattr = generic_getxattr, 2017 .removexattr = generic_removexattr, 2018 .listxattr = v9fs_listxattr, 2019}; 2020