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