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