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