1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * This file contains vfs inode ops for the 9P2000.L protocol. 4 * 5 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 6 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 7 */ 8 9 #include <linux/module.h> 10 #include <linux/errno.h> 11 #include <linux/fs.h> 12 #include <linux/file.h> 13 #include <linux/pagemap.h> 14 #include <linux/stat.h> 15 #include <linux/string.h> 16 #include <linux/namei.h> 17 #include <linux/sched.h> 18 #include <linux/slab.h> 19 #include <linux/xattr.h> 20 #include <linux/posix_acl.h> 21 #include <net/9p/9p.h> 22 #include <net/9p/client.h> 23 24 #include "v9fs.h" 25 #include "v9fs_vfs.h" 26 #include "fid.h" 27 #include "cache.h" 28 #include "xattr.h" 29 #include "acl.h" 30 31 static int 32 v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir, 33 struct dentry *dentry, umode_t omode, dev_t rdev); 34 35 /** 36 * v9fs_get_fsgid_for_create - Helper function to get the gid for a new object 37 * @dir_inode: The directory inode 38 * 39 * Helper function to get the gid for creating a 40 * new file system object. This checks the S_ISGID to determine the owning 41 * group of the new file system object. 42 */ 43 44 static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) 45 { 46 BUG_ON(dir_inode == NULL); 47 48 if (dir_inode->i_mode & S_ISGID) { 49 /* set_gid bit is set.*/ 50 return dir_inode->i_gid; 51 } 52 return current_fsgid(); 53 } 54 55 struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid) 56 { 57 int retval; 58 struct inode *inode; 59 struct p9_stat_dotl *st; 60 struct v9fs_session_info *v9ses = sb->s_fs_info; 61 62 inode = iget_locked(sb, QID2INO(&fid->qid)); 63 if (unlikely(!inode)) 64 return ERR_PTR(-ENOMEM); 65 if (!(inode->i_state & I_NEW)) 66 return inode; 67 68 /* 69 * initialize the inode with the stat info 70 * FIXME!! we may need support for stale inodes 71 * later. 72 */ 73 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN); 74 if (IS_ERR(st)) { 75 retval = PTR_ERR(st); 76 goto error; 77 } 78 79 retval = v9fs_init_inode(v9ses, inode, &fid->qid, 80 st->st_mode, new_decode_dev(st->st_rdev)); 81 kfree(st); 82 if (retval) 83 goto error; 84 85 v9fs_stat2inode_dotl(st, inode, 0); 86 v9fs_set_netfs_context(inode); 87 v9fs_cache_inode_get_cookie(inode); 88 retval = v9fs_get_acl(inode, fid); 89 if (retval) 90 goto error; 91 92 unlock_new_inode(inode); 93 94 return inode; 95 error: 96 iget_failed(inode); 97 return ERR_PTR(retval); 98 99 } 100 101 struct dotl_openflag_map { 102 int open_flag; 103 int dotl_flag; 104 }; 105 106 static int v9fs_mapped_dotl_flags(int flags) 107 { 108 int i; 109 int rflags = 0; 110 struct dotl_openflag_map dotl_oflag_map[] = { 111 { O_CREAT, P9_DOTL_CREATE }, 112 { O_EXCL, P9_DOTL_EXCL }, 113 { O_NOCTTY, P9_DOTL_NOCTTY }, 114 { O_APPEND, P9_DOTL_APPEND }, 115 { O_NONBLOCK, P9_DOTL_NONBLOCK }, 116 { O_DSYNC, P9_DOTL_DSYNC }, 117 { FASYNC, P9_DOTL_FASYNC }, 118 { O_DIRECT, P9_DOTL_DIRECT }, 119 { O_LARGEFILE, P9_DOTL_LARGEFILE }, 120 { O_DIRECTORY, P9_DOTL_DIRECTORY }, 121 { O_NOFOLLOW, P9_DOTL_NOFOLLOW }, 122 { O_NOATIME, P9_DOTL_NOATIME }, 123 { O_CLOEXEC, P9_DOTL_CLOEXEC }, 124 { O_SYNC, P9_DOTL_SYNC}, 125 }; 126 for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) { 127 if (flags & dotl_oflag_map[i].open_flag) 128 rflags |= dotl_oflag_map[i].dotl_flag; 129 } 130 return rflags; 131 } 132 133 /** 134 * v9fs_open_to_dotl_flags- convert Linux specific open flags to 135 * plan 9 open flag. 136 * @flags: flags to convert 137 */ 138 int v9fs_open_to_dotl_flags(int flags) 139 { 140 int rflags = 0; 141 142 /* 143 * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY 144 * and P9_DOTL_NOACCESS 145 */ 146 rflags |= flags & O_ACCMODE; 147 rflags |= v9fs_mapped_dotl_flags(flags); 148 149 return rflags; 150 } 151 152 /** 153 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol. 154 * @idmap: The user namespace of the mount 155 * @dir: directory inode that is being created 156 * @dentry: dentry that is being deleted 157 * @omode: create permissions 158 * @excl: True if the file must not yet exist 159 * 160 */ 161 static int 162 v9fs_vfs_create_dotl(struct mnt_idmap *idmap, struct inode *dir, 163 struct dentry *dentry, umode_t omode, bool excl) 164 { 165 return v9fs_vfs_mknod_dotl(idmap, dir, dentry, omode, 0); 166 } 167 168 static int 169 v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, 170 struct file *file, unsigned int flags, umode_t omode) 171 { 172 int err = 0; 173 kgid_t gid; 174 umode_t mode; 175 int p9_omode = v9fs_open_to_dotl_flags(flags); 176 const unsigned char *name = NULL; 177 struct p9_qid qid; 178 struct inode *inode; 179 struct p9_fid *fid = NULL; 180 struct p9_fid *dfid = NULL, *ofid = NULL; 181 struct v9fs_session_info *v9ses; 182 struct posix_acl *pacl = NULL, *dacl = NULL; 183 struct dentry *res = NULL; 184 185 if (d_in_lookup(dentry)) { 186 res = v9fs_vfs_lookup(dir, dentry, 0); 187 if (IS_ERR(res)) 188 return PTR_ERR(res); 189 190 if (res) 191 dentry = res; 192 } 193 194 /* Only creates */ 195 if (!(flags & O_CREAT) || d_really_is_positive(dentry)) 196 return finish_no_open(file, res); 197 198 v9ses = v9fs_inode2v9ses(dir); 199 200 name = dentry->d_name.name; 201 p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%x\n", 202 name, flags, omode); 203 204 dfid = v9fs_parent_fid(dentry); 205 if (IS_ERR(dfid)) { 206 err = PTR_ERR(dfid); 207 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 208 goto out; 209 } 210 211 /* clone a fid to use for creation */ 212 ofid = clone_fid(dfid); 213 if (IS_ERR(ofid)) { 214 err = PTR_ERR(ofid); 215 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 216 goto out; 217 } 218 219 gid = v9fs_get_fsgid_for_create(dir); 220 221 mode = omode; 222 /* Update mode based on ACL value */ 223 err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); 224 if (err) { 225 p9_debug(P9_DEBUG_VFS, "Failed to get acl values in create %d\n", 226 err); 227 goto out; 228 } 229 230 if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { 231 p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; 232 p9_debug(P9_DEBUG_CACHE, 233 "write-only file with writeback enabled, creating w/ O_RDWR\n"); 234 } 235 err = p9_client_create_dotl(ofid, name, p9_omode, mode, gid, &qid); 236 if (err < 0) { 237 p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in create %d\n", 238 err); 239 goto out; 240 } 241 v9fs_invalidate_inode_attr(dir); 242 243 /* instantiate inode and assign the unopened fid to the dentry */ 244 fid = p9_client_walk(dfid, 1, &name, 1); 245 if (IS_ERR(fid)) { 246 err = PTR_ERR(fid); 247 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 248 goto out; 249 } 250 inode = v9fs_fid_iget_dotl(dir->i_sb, fid); 251 if (IS_ERR(inode)) { 252 err = PTR_ERR(inode); 253 p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err); 254 goto out; 255 } 256 /* Now set the ACL based on the default value */ 257 v9fs_set_create_acl(inode, fid, dacl, pacl); 258 259 v9fs_fid_add(dentry, &fid); 260 d_instantiate(dentry, inode); 261 262 /* Since we are opening a file, assign the open fid to the file */ 263 err = finish_open(file, dentry, generic_file_open); 264 if (err) 265 goto out; 266 file->private_data = ofid; 267 #ifdef CONFIG_9P_FSCACHE 268 if (v9ses->cache & CACHE_FSCACHE) { 269 struct v9fs_inode *v9inode = V9FS_I(inode); 270 fscache_use_cookie(v9fs_inode_cookie(v9inode), 271 file->f_mode & FMODE_WRITE); 272 } 273 #endif 274 v9fs_fid_add_modes(ofid, v9ses->flags, v9ses->cache, flags); 275 v9fs_open_fid_add(inode, &ofid); 276 file->f_mode |= FMODE_CREATED; 277 out: 278 p9_fid_put(dfid); 279 p9_fid_put(ofid); 280 p9_fid_put(fid); 281 v9fs_put_acl(dacl, pacl); 282 dput(res); 283 return err; 284 } 285 286 /** 287 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory 288 * @idmap: The idmap of the mount 289 * @dir: inode that is being unlinked 290 * @dentry: dentry that is being unlinked 291 * @omode: mode for new directory 292 * 293 */ 294 295 static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap, 296 struct inode *dir, struct dentry *dentry, 297 umode_t omode) 298 { 299 int err; 300 struct v9fs_session_info *v9ses; 301 struct p9_fid *fid = NULL, *dfid = NULL; 302 kgid_t gid; 303 const unsigned char *name; 304 umode_t mode; 305 struct inode *inode; 306 struct p9_qid qid; 307 struct posix_acl *dacl = NULL, *pacl = NULL; 308 309 p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry); 310 v9ses = v9fs_inode2v9ses(dir); 311 312 omode |= S_IFDIR; 313 if (dir->i_mode & S_ISGID) 314 omode |= S_ISGID; 315 316 dfid = v9fs_parent_fid(dentry); 317 if (IS_ERR(dfid)) { 318 err = PTR_ERR(dfid); 319 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 320 goto error; 321 } 322 323 gid = v9fs_get_fsgid_for_create(dir); 324 mode = omode; 325 /* Update mode based on ACL value */ 326 err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); 327 if (err) { 328 p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mkdir %d\n", 329 err); 330 goto error; 331 } 332 name = dentry->d_name.name; 333 err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid); 334 if (err < 0) 335 goto error; 336 fid = p9_client_walk(dfid, 1, &name, 1); 337 if (IS_ERR(fid)) { 338 err = PTR_ERR(fid); 339 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 340 err); 341 goto error; 342 } 343 344 /* instantiate inode and assign the unopened fid to the dentry */ 345 inode = v9fs_fid_iget_dotl(dir->i_sb, fid); 346 if (IS_ERR(inode)) { 347 err = PTR_ERR(inode); 348 p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", 349 err); 350 goto error; 351 } 352 v9fs_fid_add(dentry, &fid); 353 v9fs_set_create_acl(inode, fid, dacl, pacl); 354 d_instantiate(dentry, inode); 355 err = 0; 356 inc_nlink(dir); 357 v9fs_invalidate_inode_attr(dir); 358 error: 359 p9_fid_put(fid); 360 v9fs_put_acl(dacl, pacl); 361 p9_fid_put(dfid); 362 return err; 363 } 364 365 static int 366 v9fs_vfs_getattr_dotl(struct mnt_idmap *idmap, 367 const struct path *path, struct kstat *stat, 368 u32 request_mask, unsigned int flags) 369 { 370 struct dentry *dentry = path->dentry; 371 struct v9fs_session_info *v9ses; 372 struct p9_fid *fid; 373 struct inode *inode = d_inode(dentry); 374 struct p9_stat_dotl *st; 375 376 p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry); 377 v9ses = v9fs_dentry2v9ses(dentry); 378 if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) { 379 generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat); 380 return 0; 381 } else if (v9ses->cache) { 382 if (S_ISREG(inode->i_mode)) { 383 int retval = filemap_fdatawrite(inode->i_mapping); 384 385 if (retval) 386 p9_debug(P9_DEBUG_ERROR, 387 "flushing writeback during getattr returned %d\n", retval); 388 } 389 } 390 fid = v9fs_fid_lookup(dentry); 391 if (IS_ERR(fid)) 392 return PTR_ERR(fid); 393 394 /* Ask for all the fields in stat structure. Server will return 395 * whatever it supports 396 */ 397 398 st = p9_client_getattr_dotl(fid, P9_STATS_ALL); 399 p9_fid_put(fid); 400 if (IS_ERR(st)) 401 return PTR_ERR(st); 402 403 v9fs_stat2inode_dotl(st, d_inode(dentry), 0); 404 generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(dentry), stat); 405 /* Change block size to what the server returned */ 406 stat->blksize = st->st_blksize; 407 408 kfree(st); 409 return 0; 410 } 411 412 /* 413 * Attribute flags. 414 */ 415 #define P9_ATTR_MODE (1 << 0) 416 #define P9_ATTR_UID (1 << 1) 417 #define P9_ATTR_GID (1 << 2) 418 #define P9_ATTR_SIZE (1 << 3) 419 #define P9_ATTR_ATIME (1 << 4) 420 #define P9_ATTR_MTIME (1 << 5) 421 #define P9_ATTR_CTIME (1 << 6) 422 #define P9_ATTR_ATIME_SET (1 << 7) 423 #define P9_ATTR_MTIME_SET (1 << 8) 424 425 struct dotl_iattr_map { 426 int iattr_valid; 427 int p9_iattr_valid; 428 }; 429 430 static int v9fs_mapped_iattr_valid(int iattr_valid) 431 { 432 int i; 433 int p9_iattr_valid = 0; 434 struct dotl_iattr_map dotl_iattr_map[] = { 435 { ATTR_MODE, P9_ATTR_MODE }, 436 { ATTR_UID, P9_ATTR_UID }, 437 { ATTR_GID, P9_ATTR_GID }, 438 { ATTR_SIZE, P9_ATTR_SIZE }, 439 { ATTR_ATIME, P9_ATTR_ATIME }, 440 { ATTR_MTIME, P9_ATTR_MTIME }, 441 { ATTR_CTIME, P9_ATTR_CTIME }, 442 { ATTR_ATIME_SET, P9_ATTR_ATIME_SET }, 443 { ATTR_MTIME_SET, P9_ATTR_MTIME_SET }, 444 }; 445 for (i = 0; i < ARRAY_SIZE(dotl_iattr_map); i++) { 446 if (iattr_valid & dotl_iattr_map[i].iattr_valid) 447 p9_iattr_valid |= dotl_iattr_map[i].p9_iattr_valid; 448 } 449 return p9_iattr_valid; 450 } 451 452 /** 453 * v9fs_vfs_setattr_dotl - set file metadata 454 * @idmap: idmap of the mount 455 * @dentry: file whose metadata to set 456 * @iattr: metadata assignment structure 457 * 458 */ 459 460 int v9fs_vfs_setattr_dotl(struct mnt_idmap *idmap, 461 struct dentry *dentry, struct iattr *iattr) 462 { 463 int retval, use_dentry = 0; 464 struct inode *inode = d_inode(dentry); 465 struct v9fs_session_info __maybe_unused *v9ses; 466 struct p9_fid *fid = NULL; 467 struct p9_iattr_dotl p9attr = { 468 .uid = INVALID_UID, 469 .gid = INVALID_GID, 470 }; 471 472 p9_debug(P9_DEBUG_VFS, "\n"); 473 474 retval = setattr_prepare(&nop_mnt_idmap, dentry, iattr); 475 if (retval) 476 return retval; 477 478 v9ses = v9fs_dentry2v9ses(dentry); 479 480 p9attr.valid = v9fs_mapped_iattr_valid(iattr->ia_valid); 481 if (iattr->ia_valid & ATTR_MODE) 482 p9attr.mode = iattr->ia_mode; 483 if (iattr->ia_valid & ATTR_UID) 484 p9attr.uid = iattr->ia_uid; 485 if (iattr->ia_valid & ATTR_GID) 486 p9attr.gid = iattr->ia_gid; 487 if (iattr->ia_valid & ATTR_SIZE) 488 p9attr.size = iattr->ia_size; 489 if (iattr->ia_valid & ATTR_ATIME_SET) { 490 p9attr.atime_sec = iattr->ia_atime.tv_sec; 491 p9attr.atime_nsec = iattr->ia_atime.tv_nsec; 492 } 493 if (iattr->ia_valid & ATTR_MTIME_SET) { 494 p9attr.mtime_sec = iattr->ia_mtime.tv_sec; 495 p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec; 496 } 497 498 if (iattr->ia_valid & ATTR_FILE) { 499 fid = iattr->ia_file->private_data; 500 WARN_ON(!fid); 501 } 502 if (!fid) { 503 fid = v9fs_fid_lookup(dentry); 504 use_dentry = 1; 505 } 506 if (IS_ERR(fid)) 507 return PTR_ERR(fid); 508 509 /* Write all dirty data */ 510 if (S_ISREG(inode->i_mode)) { 511 retval = filemap_fdatawrite(inode->i_mapping); 512 if (retval < 0) 513 p9_debug(P9_DEBUG_ERROR, 514 "Flushing file prior to setattr failed: %d\n", retval); 515 } 516 517 retval = p9_client_setattr(fid, &p9attr); 518 if (retval < 0) { 519 if (use_dentry) 520 p9_fid_put(fid); 521 return retval; 522 } 523 524 if ((iattr->ia_valid & ATTR_SIZE) && iattr->ia_size != 525 i_size_read(inode)) { 526 truncate_setsize(inode, iattr->ia_size); 527 netfs_resize_file(netfs_inode(inode), iattr->ia_size, true); 528 529 #ifdef CONFIG_9P_FSCACHE 530 if (v9ses->cache & CACHE_FSCACHE) 531 fscache_resize_cookie(v9fs_inode_cookie(V9FS_I(inode)), 532 iattr->ia_size); 533 #endif 534 } 535 536 v9fs_invalidate_inode_attr(inode); 537 setattr_copy(&nop_mnt_idmap, inode, iattr); 538 mark_inode_dirty(inode); 539 if (iattr->ia_valid & ATTR_MODE) { 540 /* We also want to update ACL when we update mode bits */ 541 retval = v9fs_acl_chmod(inode, fid); 542 if (retval < 0) { 543 if (use_dentry) 544 p9_fid_put(fid); 545 return retval; 546 } 547 } 548 if (use_dentry) 549 p9_fid_put(fid); 550 551 return 0; 552 } 553 554 /** 555 * v9fs_stat2inode_dotl - populate an inode structure with stat info 556 * @stat: stat structure 557 * @inode: inode to populate 558 * @flags: ctrl flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE) 559 * 560 */ 561 562 void 563 v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode, 564 unsigned int flags) 565 { 566 umode_t mode; 567 struct v9fs_inode *v9inode = V9FS_I(inode); 568 569 if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) { 570 inode_set_atime(inode, stat->st_atime_sec, 571 stat->st_atime_nsec); 572 inode_set_mtime(inode, stat->st_mtime_sec, 573 stat->st_mtime_nsec); 574 inode_set_ctime(inode, stat->st_ctime_sec, 575 stat->st_ctime_nsec); 576 inode->i_uid = stat->st_uid; 577 inode->i_gid = stat->st_gid; 578 set_nlink(inode, stat->st_nlink); 579 580 mode = stat->st_mode & S_IALLUGO; 581 mode |= inode->i_mode & ~S_IALLUGO; 582 inode->i_mode = mode; 583 584 v9inode->netfs.remote_i_size = stat->st_size; 585 if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE)) 586 v9fs_i_size_write(inode, stat->st_size); 587 inode->i_blocks = stat->st_blocks; 588 } else { 589 if (stat->st_result_mask & P9_STATS_ATIME) { 590 inode_set_atime(inode, stat->st_atime_sec, 591 stat->st_atime_nsec); 592 } 593 if (stat->st_result_mask & P9_STATS_MTIME) { 594 inode_set_mtime(inode, stat->st_mtime_sec, 595 stat->st_mtime_nsec); 596 } 597 if (stat->st_result_mask & P9_STATS_CTIME) { 598 inode_set_ctime(inode, stat->st_ctime_sec, 599 stat->st_ctime_nsec); 600 } 601 if (stat->st_result_mask & P9_STATS_UID) 602 inode->i_uid = stat->st_uid; 603 if (stat->st_result_mask & P9_STATS_GID) 604 inode->i_gid = stat->st_gid; 605 if (stat->st_result_mask & P9_STATS_NLINK) 606 set_nlink(inode, stat->st_nlink); 607 if (stat->st_result_mask & P9_STATS_MODE) { 608 mode = stat->st_mode & S_IALLUGO; 609 mode |= inode->i_mode & ~S_IALLUGO; 610 inode->i_mode = mode; 611 } 612 if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE) && 613 stat->st_result_mask & P9_STATS_SIZE) { 614 v9inode->netfs.remote_i_size = stat->st_size; 615 v9fs_i_size_write(inode, stat->st_size); 616 } 617 if (stat->st_result_mask & P9_STATS_BLOCKS) 618 inode->i_blocks = stat->st_blocks; 619 } 620 if (stat->st_result_mask & P9_STATS_GEN) 621 inode->i_generation = stat->st_gen; 622 623 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION 624 * because the inode structure does not have fields for them. 625 */ 626 v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR; 627 } 628 629 static int 630 v9fs_vfs_symlink_dotl(struct mnt_idmap *idmap, struct inode *dir, 631 struct dentry *dentry, const char *symname) 632 { 633 int err; 634 kgid_t gid; 635 const unsigned char *name; 636 struct p9_qid qid; 637 struct p9_fid *dfid; 638 struct p9_fid *fid = NULL; 639 640 name = dentry->d_name.name; 641 p9_debug(P9_DEBUG_VFS, "%lu,%s,%s\n", dir->i_ino, name, symname); 642 643 dfid = v9fs_parent_fid(dentry); 644 if (IS_ERR(dfid)) { 645 err = PTR_ERR(dfid); 646 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 647 return err; 648 } 649 650 gid = v9fs_get_fsgid_for_create(dir); 651 652 /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */ 653 err = p9_client_symlink(dfid, name, symname, gid, &qid); 654 655 if (err < 0) { 656 p9_debug(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err); 657 goto error; 658 } 659 660 v9fs_invalidate_inode_attr(dir); 661 662 error: 663 p9_fid_put(fid); 664 p9_fid_put(dfid); 665 return err; 666 } 667 668 /** 669 * v9fs_vfs_link_dotl - create a hardlink for dotl 670 * @old_dentry: dentry for file to link to 671 * @dir: inode destination for new link 672 * @dentry: dentry for link 673 * 674 */ 675 676 static int 677 v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, 678 struct dentry *dentry) 679 { 680 int err; 681 struct p9_fid *dfid, *oldfid; 682 struct v9fs_session_info *v9ses; 683 684 p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %pd, new_name: %pd\n", 685 dir->i_ino, old_dentry, dentry); 686 687 v9ses = v9fs_inode2v9ses(dir); 688 dfid = v9fs_parent_fid(dentry); 689 if (IS_ERR(dfid)) 690 return PTR_ERR(dfid); 691 692 oldfid = v9fs_fid_lookup(old_dentry); 693 if (IS_ERR(oldfid)) { 694 p9_fid_put(dfid); 695 return PTR_ERR(oldfid); 696 } 697 698 err = p9_client_link(dfid, oldfid, dentry->d_name.name); 699 700 p9_fid_put(dfid); 701 p9_fid_put(oldfid); 702 if (err < 0) { 703 p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err); 704 return err; 705 } 706 707 v9fs_invalidate_inode_attr(dir); 708 if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) { 709 /* Get the latest stat info from server. */ 710 struct p9_fid *fid; 711 712 fid = v9fs_fid_lookup(old_dentry); 713 if (IS_ERR(fid)) 714 return PTR_ERR(fid); 715 716 v9fs_refresh_inode_dotl(fid, d_inode(old_dentry)); 717 p9_fid_put(fid); 718 } 719 ihold(d_inode(old_dentry)); 720 d_instantiate(dentry, d_inode(old_dentry)); 721 722 return err; 723 } 724 725 /** 726 * v9fs_vfs_mknod_dotl - create a special file 727 * @idmap: The idmap of the mount 728 * @dir: inode destination for new link 729 * @dentry: dentry for file 730 * @omode: mode for creation 731 * @rdev: device associated with special file 732 * 733 */ 734 static int 735 v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir, 736 struct dentry *dentry, umode_t omode, dev_t rdev) 737 { 738 int err; 739 kgid_t gid; 740 const unsigned char *name; 741 umode_t mode; 742 struct v9fs_session_info *v9ses; 743 struct p9_fid *fid = NULL, *dfid = NULL; 744 struct inode *inode; 745 struct p9_qid qid; 746 struct posix_acl *dacl = NULL, *pacl = NULL; 747 748 p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %x MAJOR: %u MINOR: %u\n", 749 dir->i_ino, dentry, omode, 750 MAJOR(rdev), MINOR(rdev)); 751 752 v9ses = v9fs_inode2v9ses(dir); 753 dfid = v9fs_parent_fid(dentry); 754 if (IS_ERR(dfid)) { 755 err = PTR_ERR(dfid); 756 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 757 goto error; 758 } 759 760 gid = v9fs_get_fsgid_for_create(dir); 761 mode = omode; 762 /* Update mode based on ACL value */ 763 err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); 764 if (err) { 765 p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mknod %d\n", 766 err); 767 goto error; 768 } 769 name = dentry->d_name.name; 770 771 err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid); 772 if (err < 0) 773 goto error; 774 775 v9fs_invalidate_inode_attr(dir); 776 fid = p9_client_walk(dfid, 1, &name, 1); 777 if (IS_ERR(fid)) { 778 err = PTR_ERR(fid); 779 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 780 err); 781 goto error; 782 } 783 inode = v9fs_fid_iget_dotl(dir->i_sb, fid); 784 if (IS_ERR(inode)) { 785 err = PTR_ERR(inode); 786 p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", 787 err); 788 goto error; 789 } 790 v9fs_set_create_acl(inode, fid, dacl, pacl); 791 v9fs_fid_add(dentry, &fid); 792 d_instantiate(dentry, inode); 793 err = 0; 794 error: 795 p9_fid_put(fid); 796 v9fs_put_acl(dacl, pacl); 797 p9_fid_put(dfid); 798 799 return err; 800 } 801 802 /** 803 * v9fs_vfs_get_link_dotl - follow a symlink path 804 * @dentry: dentry for symlink 805 * @inode: inode for symlink 806 * @done: destructor for return value 807 */ 808 809 static const char * 810 v9fs_vfs_get_link_dotl(struct dentry *dentry, 811 struct inode *inode, 812 struct delayed_call *done) 813 { 814 struct p9_fid *fid; 815 char *target; 816 int retval; 817 818 if (!dentry) 819 return ERR_PTR(-ECHILD); 820 821 p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); 822 823 fid = v9fs_fid_lookup(dentry); 824 if (IS_ERR(fid)) 825 return ERR_CAST(fid); 826 retval = p9_client_readlink(fid, &target); 827 p9_fid_put(fid); 828 if (retval) 829 return ERR_PTR(retval); 830 set_delayed_call(done, kfree_link, target); 831 return target; 832 } 833 834 int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode) 835 { 836 struct p9_stat_dotl *st; 837 struct v9fs_session_info *v9ses; 838 unsigned int flags; 839 840 v9ses = v9fs_inode2v9ses(inode); 841 st = p9_client_getattr_dotl(fid, P9_STATS_ALL); 842 if (IS_ERR(st)) 843 return PTR_ERR(st); 844 /* 845 * Don't update inode if the file type is different 846 */ 847 if (inode_wrong_type(inode, st->st_mode)) 848 goto out; 849 850 /* 851 * We don't want to refresh inode->i_size, 852 * because we may have cached data 853 */ 854 flags = (v9ses->cache & CACHE_LOOSE) ? 855 V9FS_STAT2INODE_KEEP_ISIZE : 0; 856 v9fs_stat2inode_dotl(st, inode, flags); 857 out: 858 kfree(st); 859 return 0; 860 } 861 862 const struct inode_operations v9fs_dir_inode_operations_dotl = { 863 .create = v9fs_vfs_create_dotl, 864 .atomic_open = v9fs_vfs_atomic_open_dotl, 865 .lookup = v9fs_vfs_lookup, 866 .link = v9fs_vfs_link_dotl, 867 .symlink = v9fs_vfs_symlink_dotl, 868 .unlink = v9fs_vfs_unlink, 869 .mkdir = v9fs_vfs_mkdir_dotl, 870 .rmdir = v9fs_vfs_rmdir, 871 .mknod = v9fs_vfs_mknod_dotl, 872 .rename = v9fs_vfs_rename, 873 .getattr = v9fs_vfs_getattr_dotl, 874 .setattr = v9fs_vfs_setattr_dotl, 875 .listxattr = v9fs_listxattr, 876 .get_inode_acl = v9fs_iop_get_inode_acl, 877 .get_acl = v9fs_iop_get_acl, 878 .set_acl = v9fs_iop_set_acl, 879 }; 880 881 const struct inode_operations v9fs_file_inode_operations_dotl = { 882 .getattr = v9fs_vfs_getattr_dotl, 883 .setattr = v9fs_vfs_setattr_dotl, 884 .listxattr = v9fs_listxattr, 885 .get_inode_acl = v9fs_iop_get_inode_acl, 886 .get_acl = v9fs_iop_get_acl, 887 .set_acl = v9fs_iop_set_acl, 888 }; 889 890 const struct inode_operations v9fs_symlink_inode_operations_dotl = { 891 .get_link = v9fs_vfs_get_link_dotl, 892 .getattr = v9fs_vfs_getattr_dotl, 893 .setattr = v9fs_vfs_setattr_dotl, 894 .listxattr = v9fs_listxattr, 895 }; 896