1 /* 2 * linux/fs/9p/vfs_inode_dotl.c 3 * 4 * This file contains vfs inode ops for the 9P2000.L 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 int 51 v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode, 52 dev_t rdev); 53 54 /** 55 * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a 56 * new file system object. This checks the S_ISGID to determine the owning 57 * group of the new file system object. 58 */ 59 60 static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) 61 { 62 BUG_ON(dir_inode == NULL); 63 64 if (dir_inode->i_mode & S_ISGID) { 65 /* set_gid bit is set.*/ 66 return dir_inode->i_gid; 67 } 68 return current_fsgid(); 69 } 70 71 /** 72 * v9fs_dentry_from_dir_inode - helper function to get the dentry from 73 * dir inode. 74 * 75 */ 76 77 static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode) 78 { 79 struct dentry *dentry; 80 81 spin_lock(&inode->i_lock); 82 /* Directory should have only one entry. */ 83 BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry)); 84 dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias); 85 spin_unlock(&inode->i_lock); 86 return dentry; 87 } 88 89 static int v9fs_test_inode_dotl(struct inode *inode, void *data) 90 { 91 struct v9fs_inode *v9inode = V9FS_I(inode); 92 struct p9_stat_dotl *st = (struct p9_stat_dotl *)data; 93 94 /* don't match inode of different type */ 95 if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT)) 96 return 0; 97 98 if (inode->i_generation != st->st_gen) 99 return 0; 100 101 /* compare qid details */ 102 if (memcmp(&v9inode->qid.version, 103 &st->qid.version, sizeof(v9inode->qid.version))) 104 return 0; 105 106 if (v9inode->qid.type != st->qid.type) 107 return 0; 108 return 1; 109 } 110 111 /* Always get a new inode */ 112 static int v9fs_test_new_inode_dotl(struct inode *inode, void *data) 113 { 114 return 0; 115 } 116 117 static int v9fs_set_inode_dotl(struct inode *inode, void *data) 118 { 119 struct v9fs_inode *v9inode = V9FS_I(inode); 120 struct p9_stat_dotl *st = (struct p9_stat_dotl *)data; 121 122 memcpy(&v9inode->qid, &st->qid, sizeof(st->qid)); 123 inode->i_generation = st->st_gen; 124 return 0; 125 } 126 127 static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, 128 struct p9_qid *qid, 129 struct p9_fid *fid, 130 struct p9_stat_dotl *st, 131 int new) 132 { 133 int retval; 134 unsigned long i_ino; 135 struct inode *inode; 136 struct v9fs_session_info *v9ses = sb->s_fs_info; 137 int (*test)(struct inode *, void *); 138 139 if (new) 140 test = v9fs_test_new_inode_dotl; 141 else 142 test = v9fs_test_inode_dotl; 143 144 i_ino = v9fs_qid2ino(qid); 145 inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st); 146 if (!inode) 147 return ERR_PTR(-ENOMEM); 148 if (!(inode->i_state & I_NEW)) 149 return inode; 150 /* 151 * initialize the inode with the stat info 152 * FIXME!! we may need support for stale inodes 153 * later. 154 */ 155 inode->i_ino = i_ino; 156 retval = v9fs_init_inode(v9ses, inode, 157 st->st_mode, new_decode_dev(st->st_rdev)); 158 if (retval) 159 goto error; 160 161 v9fs_stat2inode_dotl(st, inode); 162 #ifdef CONFIG_9P_FSCACHE 163 v9fs_cache_inode_get_cookie(inode); 164 #endif 165 retval = v9fs_get_acl(inode, fid); 166 if (retval) 167 goto error; 168 169 unlock_new_inode(inode); 170 return inode; 171 error: 172 unlock_new_inode(inode); 173 iput(inode); 174 return ERR_PTR(retval); 175 176 } 177 178 struct inode * 179 v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, 180 struct super_block *sb, int new) 181 { 182 struct p9_stat_dotl *st; 183 struct inode *inode = NULL; 184 185 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN); 186 if (IS_ERR(st)) 187 return ERR_CAST(st); 188 189 inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new); 190 kfree(st); 191 return inode; 192 } 193 194 struct dotl_openflag_map { 195 int open_flag; 196 int dotl_flag; 197 }; 198 199 static int v9fs_mapped_dotl_flags(int flags) 200 { 201 int i; 202 int rflags = 0; 203 struct dotl_openflag_map dotl_oflag_map[] = { 204 { O_CREAT, P9_DOTL_CREATE }, 205 { O_EXCL, P9_DOTL_EXCL }, 206 { O_NOCTTY, P9_DOTL_NOCTTY }, 207 { O_TRUNC, P9_DOTL_TRUNC }, 208 { O_APPEND, P9_DOTL_APPEND }, 209 { O_NONBLOCK, P9_DOTL_NONBLOCK }, 210 { O_DSYNC, P9_DOTL_DSYNC }, 211 { FASYNC, P9_DOTL_FASYNC }, 212 { O_DIRECT, P9_DOTL_DIRECT }, 213 { O_LARGEFILE, P9_DOTL_LARGEFILE }, 214 { O_DIRECTORY, P9_DOTL_DIRECTORY }, 215 { O_NOFOLLOW, P9_DOTL_NOFOLLOW }, 216 { O_NOATIME, P9_DOTL_NOATIME }, 217 { O_CLOEXEC, P9_DOTL_CLOEXEC }, 218 { O_SYNC, P9_DOTL_SYNC}, 219 }; 220 for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) { 221 if (flags & dotl_oflag_map[i].open_flag) 222 rflags |= dotl_oflag_map[i].dotl_flag; 223 } 224 return rflags; 225 } 226 227 /** 228 * v9fs_open_to_dotl_flags- convert Linux specific open flags to 229 * plan 9 open flag. 230 * @flags: flags to convert 231 */ 232 int v9fs_open_to_dotl_flags(int flags) 233 { 234 int rflags = 0; 235 236 /* 237 * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY 238 * and P9_DOTL_NOACCESS 239 */ 240 rflags |= flags & O_ACCMODE; 241 rflags |= v9fs_mapped_dotl_flags(flags); 242 243 return rflags; 244 } 245 246 /** 247 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol. 248 * @dir: directory inode that is being created 249 * @dentry: dentry that is being deleted 250 * @mode: create permissions 251 * @nd: path information 252 * 253 */ 254 255 static int 256 v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, 257 struct nameidata *nd) 258 { 259 int err = 0; 260 gid_t gid; 261 int flags; 262 umode_t mode; 263 char *name = NULL; 264 struct file *filp; 265 struct p9_qid qid; 266 struct inode *inode; 267 struct p9_fid *fid = NULL; 268 struct v9fs_inode *v9inode; 269 struct p9_fid *dfid, *ofid, *inode_fid; 270 struct v9fs_session_info *v9ses; 271 struct posix_acl *pacl = NULL, *dacl = NULL; 272 273 v9ses = v9fs_inode2v9ses(dir); 274 if (nd) 275 flags = nd->intent.open.flags; 276 else { 277 /* 278 * create call without LOOKUP_OPEN is due 279 * to mknod of regular files. So use mknod 280 * operation. 281 */ 282 return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0); 283 } 284 285 name = (char *) dentry->d_name.name; 286 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x " 287 "mode:0x%x\n", name, flags, omode); 288 289 dfid = v9fs_fid_lookup(dentry->d_parent); 290 if (IS_ERR(dfid)) { 291 err = PTR_ERR(dfid); 292 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 293 return err; 294 } 295 296 /* clone a fid to use for creation */ 297 ofid = p9_client_walk(dfid, 0, NULL, 1); 298 if (IS_ERR(ofid)) { 299 err = PTR_ERR(ofid); 300 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 301 return err; 302 } 303 304 gid = v9fs_get_fsgid_for_create(dir); 305 306 mode = omode; 307 /* Update mode based on ACL value */ 308 err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); 309 if (err) { 310 P9_DPRINTK(P9_DEBUG_VFS, 311 "Failed to get acl values in creat %d\n", err); 312 goto error; 313 } 314 err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags), 315 mode, gid, &qid); 316 if (err < 0) { 317 P9_DPRINTK(P9_DEBUG_VFS, 318 "p9_client_open_dotl failed in creat %d\n", 319 err); 320 goto error; 321 } 322 v9fs_invalidate_inode_attr(dir); 323 324 /* instantiate inode and assign the unopened fid to the dentry */ 325 fid = p9_client_walk(dfid, 1, &name, 1); 326 if (IS_ERR(fid)) { 327 err = PTR_ERR(fid); 328 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 329 fid = NULL; 330 goto error; 331 } 332 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 333 if (IS_ERR(inode)) { 334 err = PTR_ERR(inode); 335 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 336 goto error; 337 } 338 err = v9fs_fid_add(dentry, fid); 339 if (err < 0) 340 goto error; 341 d_instantiate(dentry, inode); 342 343 /* Now set the ACL based on the default value */ 344 v9fs_set_create_acl(dentry, &dacl, &pacl); 345 346 v9inode = V9FS_I(inode); 347 mutex_lock(&v9inode->v_mutex); 348 if (v9ses->cache && !v9inode->writeback_fid && 349 ((flags & O_ACCMODE) != O_RDONLY)) { 350 /* 351 * clone a fid and add it to writeback_fid 352 * we do it during open time instead of 353 * page dirty time via write_begin/page_mkwrite 354 * because we want write after unlink usecase 355 * to work. 356 */ 357 inode_fid = v9fs_writeback_fid(dentry); 358 if (IS_ERR(inode_fid)) { 359 err = PTR_ERR(inode_fid); 360 mutex_unlock(&v9inode->v_mutex); 361 goto err_clunk_old_fid; 362 } 363 v9inode->writeback_fid = (void *) inode_fid; 364 } 365 mutex_unlock(&v9inode->v_mutex); 366 /* Since we are opening a file, assign the open fid to the file */ 367 filp = lookup_instantiate_filp(nd, dentry, generic_file_open); 368 if (IS_ERR(filp)) { 369 err = PTR_ERR(filp); 370 goto err_clunk_old_fid; 371 } 372 filp->private_data = ofid; 373 #ifdef CONFIG_9P_FSCACHE 374 if (v9ses->cache) 375 v9fs_cache_inode_set_cookie(inode, filp); 376 #endif 377 return 0; 378 379 error: 380 if (fid) 381 p9_client_clunk(fid); 382 err_clunk_old_fid: 383 if (ofid) 384 p9_client_clunk(ofid); 385 v9fs_set_create_acl(NULL, &dacl, &pacl); 386 return err; 387 } 388 389 /** 390 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory 391 * @dir: inode that is being unlinked 392 * @dentry: dentry that is being unlinked 393 * @mode: mode for new directory 394 * 395 */ 396 397 static int v9fs_vfs_mkdir_dotl(struct inode *dir, 398 struct dentry *dentry, int omode) 399 { 400 int err; 401 struct v9fs_session_info *v9ses; 402 struct p9_fid *fid = NULL, *dfid = NULL; 403 gid_t gid; 404 char *name; 405 umode_t mode; 406 struct inode *inode; 407 struct p9_qid qid; 408 struct dentry *dir_dentry; 409 struct posix_acl *dacl = NULL, *pacl = NULL; 410 411 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); 412 err = 0; 413 v9ses = v9fs_inode2v9ses(dir); 414 415 omode |= S_IFDIR; 416 if (dir->i_mode & S_ISGID) 417 omode |= S_ISGID; 418 419 dir_dentry = v9fs_dentry_from_dir_inode(dir); 420 dfid = v9fs_fid_lookup(dir_dentry); 421 if (IS_ERR(dfid)) { 422 err = PTR_ERR(dfid); 423 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 424 dfid = NULL; 425 goto error; 426 } 427 428 gid = v9fs_get_fsgid_for_create(dir); 429 mode = omode; 430 /* Update mode based on ACL value */ 431 err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); 432 if (err) { 433 P9_DPRINTK(P9_DEBUG_VFS, 434 "Failed to get acl values in mkdir %d\n", err); 435 goto error; 436 } 437 name = (char *) dentry->d_name.name; 438 err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid); 439 if (err < 0) 440 goto error; 441 442 /* instantiate inode and assign the unopened fid to the dentry */ 443 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 444 fid = p9_client_walk(dfid, 1, &name, 1); 445 if (IS_ERR(fid)) { 446 err = PTR_ERR(fid); 447 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 448 err); 449 fid = NULL; 450 goto error; 451 } 452 453 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 454 if (IS_ERR(inode)) { 455 err = PTR_ERR(inode); 456 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 457 err); 458 goto error; 459 } 460 err = v9fs_fid_add(dentry, fid); 461 if (err < 0) 462 goto error; 463 d_instantiate(dentry, inode); 464 fid = NULL; 465 } else { 466 /* 467 * Not in cached mode. No need to populate 468 * inode with stat. We need to get an inode 469 * so that we can set the acl with dentry 470 */ 471 inode = v9fs_get_inode(dir->i_sb, mode, 0); 472 if (IS_ERR(inode)) { 473 err = PTR_ERR(inode); 474 goto error; 475 } 476 d_instantiate(dentry, inode); 477 } 478 /* Now set the ACL based on the default value */ 479 v9fs_set_create_acl(dentry, &dacl, &pacl); 480 inc_nlink(dir); 481 v9fs_invalidate_inode_attr(dir); 482 error: 483 if (fid) 484 p9_client_clunk(fid); 485 v9fs_set_create_acl(NULL, &dacl, &pacl); 486 return err; 487 } 488 489 static int 490 v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry, 491 struct kstat *stat) 492 { 493 int err; 494 struct v9fs_session_info *v9ses; 495 struct p9_fid *fid; 496 struct p9_stat_dotl *st; 497 498 P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); 499 err = -EPERM; 500 v9ses = v9fs_dentry2v9ses(dentry); 501 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 502 generic_fillattr(dentry->d_inode, stat); 503 return 0; 504 } 505 fid = v9fs_fid_lookup(dentry); 506 if (IS_ERR(fid)) 507 return PTR_ERR(fid); 508 509 /* Ask for all the fields in stat structure. Server will return 510 * whatever it supports 511 */ 512 513 st = p9_client_getattr_dotl(fid, P9_STATS_ALL); 514 if (IS_ERR(st)) 515 return PTR_ERR(st); 516 517 v9fs_stat2inode_dotl(st, dentry->d_inode); 518 generic_fillattr(dentry->d_inode, stat); 519 /* Change block size to what the server returned */ 520 stat->blksize = st->st_blksize; 521 522 kfree(st); 523 return 0; 524 } 525 526 /** 527 * v9fs_vfs_setattr_dotl - set file metadata 528 * @dentry: file whose metadata to set 529 * @iattr: metadata assignment structure 530 * 531 */ 532 533 int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr) 534 { 535 int retval; 536 struct v9fs_session_info *v9ses; 537 struct p9_fid *fid; 538 struct p9_iattr_dotl p9attr; 539 540 P9_DPRINTK(P9_DEBUG_VFS, "\n"); 541 542 retval = inode_change_ok(dentry->d_inode, iattr); 543 if (retval) 544 return retval; 545 546 p9attr.valid = iattr->ia_valid; 547 p9attr.mode = iattr->ia_mode; 548 p9attr.uid = iattr->ia_uid; 549 p9attr.gid = iattr->ia_gid; 550 p9attr.size = iattr->ia_size; 551 p9attr.atime_sec = iattr->ia_atime.tv_sec; 552 p9attr.atime_nsec = iattr->ia_atime.tv_nsec; 553 p9attr.mtime_sec = iattr->ia_mtime.tv_sec; 554 p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec; 555 556 retval = -EPERM; 557 v9ses = v9fs_dentry2v9ses(dentry); 558 fid = v9fs_fid_lookup(dentry); 559 if (IS_ERR(fid)) 560 return PTR_ERR(fid); 561 562 /* Write all dirty data */ 563 if (S_ISREG(dentry->d_inode->i_mode)) 564 filemap_write_and_wait(dentry->d_inode->i_mapping); 565 566 retval = p9_client_setattr(fid, &p9attr); 567 if (retval < 0) 568 return retval; 569 570 if ((iattr->ia_valid & ATTR_SIZE) && 571 iattr->ia_size != i_size_read(dentry->d_inode)) 572 truncate_setsize(dentry->d_inode, iattr->ia_size); 573 574 v9fs_invalidate_inode_attr(dentry->d_inode); 575 setattr_copy(dentry->d_inode, iattr); 576 mark_inode_dirty(dentry->d_inode); 577 if (iattr->ia_valid & ATTR_MODE) { 578 /* We also want to update ACL when we update mode bits */ 579 retval = v9fs_acl_chmod(dentry); 580 if (retval < 0) 581 return retval; 582 } 583 return 0; 584 } 585 586 /** 587 * v9fs_stat2inode_dotl - populate an inode structure with stat info 588 * @stat: stat structure 589 * @inode: inode to populate 590 * @sb: superblock of filesystem 591 * 592 */ 593 594 void 595 v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode) 596 { 597 mode_t mode; 598 struct v9fs_inode *v9inode = V9FS_I(inode); 599 600 if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) { 601 inode->i_atime.tv_sec = stat->st_atime_sec; 602 inode->i_atime.tv_nsec = stat->st_atime_nsec; 603 inode->i_mtime.tv_sec = stat->st_mtime_sec; 604 inode->i_mtime.tv_nsec = stat->st_mtime_nsec; 605 inode->i_ctime.tv_sec = stat->st_ctime_sec; 606 inode->i_ctime.tv_nsec = stat->st_ctime_nsec; 607 inode->i_uid = stat->st_uid; 608 inode->i_gid = stat->st_gid; 609 set_nlink(inode, stat->st_nlink); 610 611 mode = stat->st_mode & S_IALLUGO; 612 mode |= inode->i_mode & ~S_IALLUGO; 613 inode->i_mode = mode; 614 615 i_size_write(inode, stat->st_size); 616 inode->i_blocks = stat->st_blocks; 617 } else { 618 if (stat->st_result_mask & P9_STATS_ATIME) { 619 inode->i_atime.tv_sec = stat->st_atime_sec; 620 inode->i_atime.tv_nsec = stat->st_atime_nsec; 621 } 622 if (stat->st_result_mask & P9_STATS_MTIME) { 623 inode->i_mtime.tv_sec = stat->st_mtime_sec; 624 inode->i_mtime.tv_nsec = stat->st_mtime_nsec; 625 } 626 if (stat->st_result_mask & P9_STATS_CTIME) { 627 inode->i_ctime.tv_sec = stat->st_ctime_sec; 628 inode->i_ctime.tv_nsec = stat->st_ctime_nsec; 629 } 630 if (stat->st_result_mask & P9_STATS_UID) 631 inode->i_uid = stat->st_uid; 632 if (stat->st_result_mask & P9_STATS_GID) 633 inode->i_gid = stat->st_gid; 634 if (stat->st_result_mask & P9_STATS_NLINK) 635 set_nlink(inode, stat->st_nlink); 636 if (stat->st_result_mask & P9_STATS_MODE) { 637 inode->i_mode = stat->st_mode; 638 if ((S_ISBLK(inode->i_mode)) || 639 (S_ISCHR(inode->i_mode))) 640 init_special_inode(inode, inode->i_mode, 641 inode->i_rdev); 642 } 643 if (stat->st_result_mask & P9_STATS_RDEV) 644 inode->i_rdev = new_decode_dev(stat->st_rdev); 645 if (stat->st_result_mask & P9_STATS_SIZE) 646 i_size_write(inode, stat->st_size); 647 if (stat->st_result_mask & P9_STATS_BLOCKS) 648 inode->i_blocks = stat->st_blocks; 649 } 650 if (stat->st_result_mask & P9_STATS_GEN) 651 inode->i_generation = stat->st_gen; 652 653 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION 654 * because the inode structure does not have fields for them. 655 */ 656 v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR; 657 } 658 659 static int 660 v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, 661 const char *symname) 662 { 663 int err; 664 gid_t gid; 665 char *name; 666 struct p9_qid qid; 667 struct inode *inode; 668 struct p9_fid *dfid; 669 struct p9_fid *fid = NULL; 670 struct v9fs_session_info *v9ses; 671 672 name = (char *) dentry->d_name.name; 673 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n", 674 dir->i_ino, name, symname); 675 v9ses = v9fs_inode2v9ses(dir); 676 677 dfid = v9fs_fid_lookup(dentry->d_parent); 678 if (IS_ERR(dfid)) { 679 err = PTR_ERR(dfid); 680 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 681 return err; 682 } 683 684 gid = v9fs_get_fsgid_for_create(dir); 685 686 /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */ 687 err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid); 688 689 if (err < 0) { 690 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err); 691 goto error; 692 } 693 694 v9fs_invalidate_inode_attr(dir); 695 if (v9ses->cache) { 696 /* Now walk from the parent so we can get an unopened fid. */ 697 fid = p9_client_walk(dfid, 1, &name, 1); 698 if (IS_ERR(fid)) { 699 err = PTR_ERR(fid); 700 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 701 err); 702 fid = NULL; 703 goto error; 704 } 705 706 /* instantiate inode and assign the unopened fid to dentry */ 707 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 708 if (IS_ERR(inode)) { 709 err = PTR_ERR(inode); 710 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 711 err); 712 goto error; 713 } 714 err = v9fs_fid_add(dentry, fid); 715 if (err < 0) 716 goto error; 717 d_instantiate(dentry, inode); 718 fid = NULL; 719 } else { 720 /* Not in cached mode. No need to populate inode with stat */ 721 inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0); 722 if (IS_ERR(inode)) { 723 err = PTR_ERR(inode); 724 goto error; 725 } 726 d_instantiate(dentry, inode); 727 } 728 729 error: 730 if (fid) 731 p9_client_clunk(fid); 732 733 return err; 734 } 735 736 /** 737 * v9fs_vfs_link_dotl - create a hardlink for dotl 738 * @old_dentry: dentry for file to link to 739 * @dir: inode destination for new link 740 * @dentry: dentry for link 741 * 742 */ 743 744 static int 745 v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, 746 struct dentry *dentry) 747 { 748 int err; 749 char *name; 750 struct dentry *dir_dentry; 751 struct p9_fid *dfid, *oldfid; 752 struct v9fs_session_info *v9ses; 753 754 P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n", 755 dir->i_ino, old_dentry->d_name.name, 756 dentry->d_name.name); 757 758 v9ses = v9fs_inode2v9ses(dir); 759 dir_dentry = v9fs_dentry_from_dir_inode(dir); 760 dfid = v9fs_fid_lookup(dir_dentry); 761 if (IS_ERR(dfid)) 762 return PTR_ERR(dfid); 763 764 oldfid = v9fs_fid_lookup(old_dentry); 765 if (IS_ERR(oldfid)) 766 return PTR_ERR(oldfid); 767 768 name = (char *) dentry->d_name.name; 769 770 err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name); 771 772 if (err < 0) { 773 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err); 774 return err; 775 } 776 777 v9fs_invalidate_inode_attr(dir); 778 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 779 /* Get the latest stat info from server. */ 780 struct p9_fid *fid; 781 fid = v9fs_fid_lookup(old_dentry); 782 if (IS_ERR(fid)) 783 return PTR_ERR(fid); 784 785 v9fs_refresh_inode_dotl(fid, old_dentry->d_inode); 786 } 787 ihold(old_dentry->d_inode); 788 d_instantiate(dentry, old_dentry->d_inode); 789 790 return err; 791 } 792 793 /** 794 * v9fs_vfs_mknod_dotl - create a special file 795 * @dir: inode destination for new link 796 * @dentry: dentry for file 797 * @mode: mode for creation 798 * @rdev: device associated with special file 799 * 800 */ 801 static int 802 v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode, 803 dev_t rdev) 804 { 805 int err; 806 gid_t gid; 807 char *name; 808 umode_t mode; 809 struct v9fs_session_info *v9ses; 810 struct p9_fid *fid = NULL, *dfid = NULL; 811 struct inode *inode; 812 struct p9_qid qid; 813 struct dentry *dir_dentry; 814 struct posix_acl *dacl = NULL, *pacl = NULL; 815 816 P9_DPRINTK(P9_DEBUG_VFS, 817 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 818 dentry->d_name.name, omode, MAJOR(rdev), MINOR(rdev)); 819 820 if (!new_valid_dev(rdev)) 821 return -EINVAL; 822 823 v9ses = v9fs_inode2v9ses(dir); 824 dir_dentry = v9fs_dentry_from_dir_inode(dir); 825 dfid = v9fs_fid_lookup(dir_dentry); 826 if (IS_ERR(dfid)) { 827 err = PTR_ERR(dfid); 828 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 829 dfid = NULL; 830 goto error; 831 } 832 833 gid = v9fs_get_fsgid_for_create(dir); 834 mode = omode; 835 /* Update mode based on ACL value */ 836 err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); 837 if (err) { 838 P9_DPRINTK(P9_DEBUG_VFS, 839 "Failed to get acl values in mknod %d\n", err); 840 goto error; 841 } 842 name = (char *) dentry->d_name.name; 843 844 err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid); 845 if (err < 0) 846 goto error; 847 848 v9fs_invalidate_inode_attr(dir); 849 /* instantiate inode and assign the unopened fid to the dentry */ 850 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 851 fid = p9_client_walk(dfid, 1, &name, 1); 852 if (IS_ERR(fid)) { 853 err = PTR_ERR(fid); 854 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 855 err); 856 fid = NULL; 857 goto error; 858 } 859 860 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 861 if (IS_ERR(inode)) { 862 err = PTR_ERR(inode); 863 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 864 err); 865 goto error; 866 } 867 err = v9fs_fid_add(dentry, fid); 868 if (err < 0) 869 goto error; 870 d_instantiate(dentry, inode); 871 fid = NULL; 872 } else { 873 /* 874 * Not in cached mode. No need to populate inode with stat. 875 * socket syscall returns a fd, so we need instantiate 876 */ 877 inode = v9fs_get_inode(dir->i_sb, mode, rdev); 878 if (IS_ERR(inode)) { 879 err = PTR_ERR(inode); 880 goto error; 881 } 882 d_instantiate(dentry, inode); 883 } 884 /* Now set the ACL based on the default value */ 885 v9fs_set_create_acl(dentry, &dacl, &pacl); 886 error: 887 if (fid) 888 p9_client_clunk(fid); 889 v9fs_set_create_acl(NULL, &dacl, &pacl); 890 return err; 891 } 892 893 /** 894 * v9fs_vfs_follow_link_dotl - follow a symlink path 895 * @dentry: dentry for symlink 896 * @nd: nameidata 897 * 898 */ 899 900 static void * 901 v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd) 902 { 903 int retval; 904 struct p9_fid *fid; 905 char *link = __getname(); 906 char *target; 907 908 P9_DPRINTK(P9_DEBUG_VFS, "%s\n", dentry->d_name.name); 909 910 if (!link) { 911 link = ERR_PTR(-ENOMEM); 912 goto ndset; 913 } 914 fid = v9fs_fid_lookup(dentry); 915 if (IS_ERR(fid)) { 916 __putname(link); 917 link = ERR_CAST(fid); 918 goto ndset; 919 } 920 retval = p9_client_readlink(fid, &target); 921 if (!retval) { 922 strcpy(link, target); 923 kfree(target); 924 goto ndset; 925 } 926 __putname(link); 927 link = ERR_PTR(retval); 928 ndset: 929 nd_set_link(nd, link); 930 return NULL; 931 } 932 933 int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode) 934 { 935 loff_t i_size; 936 struct p9_stat_dotl *st; 937 struct v9fs_session_info *v9ses; 938 939 v9ses = v9fs_inode2v9ses(inode); 940 st = p9_client_getattr_dotl(fid, P9_STATS_ALL); 941 if (IS_ERR(st)) 942 return PTR_ERR(st); 943 /* 944 * Don't update inode if the file type is different 945 */ 946 if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT)) 947 goto out; 948 949 spin_lock(&inode->i_lock); 950 /* 951 * We don't want to refresh inode->i_size, 952 * because we may have cached data 953 */ 954 i_size = inode->i_size; 955 v9fs_stat2inode_dotl(st, inode); 956 if (v9ses->cache) 957 inode->i_size = i_size; 958 spin_unlock(&inode->i_lock); 959 out: 960 kfree(st); 961 return 0; 962 } 963 964 const struct inode_operations v9fs_dir_inode_operations_dotl = { 965 .create = v9fs_vfs_create_dotl, 966 .lookup = v9fs_vfs_lookup, 967 .link = v9fs_vfs_link_dotl, 968 .symlink = v9fs_vfs_symlink_dotl, 969 .unlink = v9fs_vfs_unlink, 970 .mkdir = v9fs_vfs_mkdir_dotl, 971 .rmdir = v9fs_vfs_rmdir, 972 .mknod = v9fs_vfs_mknod_dotl, 973 .rename = v9fs_vfs_rename, 974 .getattr = v9fs_vfs_getattr_dotl, 975 .setattr = v9fs_vfs_setattr_dotl, 976 .setxattr = generic_setxattr, 977 .getxattr = generic_getxattr, 978 .removexattr = generic_removexattr, 979 .listxattr = v9fs_listxattr, 980 .get_acl = v9fs_iop_get_acl, 981 }; 982 983 const struct inode_operations v9fs_file_inode_operations_dotl = { 984 .getattr = v9fs_vfs_getattr_dotl, 985 .setattr = v9fs_vfs_setattr_dotl, 986 .setxattr = generic_setxattr, 987 .getxattr = generic_getxattr, 988 .removexattr = generic_removexattr, 989 .listxattr = v9fs_listxattr, 990 .get_acl = v9fs_iop_get_acl, 991 }; 992 993 const struct inode_operations v9fs_symlink_inode_operations_dotl = { 994 .readlink = generic_readlink, 995 .follow_link = v9fs_vfs_follow_link_dotl, 996 .put_link = v9fs_vfs_put_link, 997 .getattr = v9fs_vfs_getattr_dotl, 998 .setattr = v9fs_vfs_setattr_dotl, 999 .setxattr = generic_setxattr, 1000 .getxattr = generic_getxattr, 1001 .removexattr = generic_removexattr, 1002 .listxattr = v9fs_listxattr, 1003 }; 1004