1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * (C) 2001 Clemson University and The University of Chicago 4 * 5 * See COPYING in top-level directory. 6 */ 7 8 /* 9 * Linux VFS namei operations. 10 */ 11 12 #include "protocol.h" 13 #include "orangefs-kernel.h" 14 15 /* 16 * Get a newly allocated inode to go with a negative dentry. 17 */ 18 static int orangefs_create(struct inode *dir, 19 struct dentry *dentry, 20 umode_t mode, 21 bool exclusive) 22 { 23 struct orangefs_inode_s *parent = ORANGEFS_I(dir); 24 struct orangefs_kernel_op_s *new_op; 25 struct orangefs_object_kref ref; 26 struct inode *inode; 27 struct iattr iattr; 28 int ret; 29 30 gossip_debug(GOSSIP_NAME_DEBUG, "%s: %pd\n", 31 __func__, 32 dentry); 33 34 new_op = op_alloc(ORANGEFS_VFS_OP_CREATE); 35 if (!new_op) 36 return -ENOMEM; 37 38 new_op->upcall.req.create.parent_refn = parent->refn; 39 40 fill_default_sys_attrs(new_op->upcall.req.create.attributes, 41 ORANGEFS_TYPE_METAFILE, mode); 42 43 strncpy(new_op->upcall.req.create.d_name, 44 dentry->d_name.name, ORANGEFS_NAME_MAX - 1); 45 46 ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 47 48 gossip_debug(GOSSIP_NAME_DEBUG, 49 "%s: %pd: handle:%pU: fsid:%d: new_op:%p: ret:%d:\n", 50 __func__, 51 dentry, 52 &new_op->downcall.resp.create.refn.khandle, 53 new_op->downcall.resp.create.refn.fs_id, 54 new_op, 55 ret); 56 57 if (ret < 0) 58 goto out; 59 60 ref = new_op->downcall.resp.create.refn; 61 op_release(new_op); 62 63 inode = orangefs_new_inode(dir->i_sb, dir, S_IFREG | mode, 0, &ref); 64 if (IS_ERR(inode)) { 65 gossip_err("%s: Failed to allocate inode for file :%pd:\n", 66 __func__, 67 dentry); 68 ret = PTR_ERR(inode); 69 goto out; 70 } 71 72 gossip_debug(GOSSIP_NAME_DEBUG, 73 "%s: Assigned inode :%pU: for file :%pd:\n", 74 __func__, 75 get_khandle_from_ino(inode), 76 dentry); 77 78 d_instantiate(dentry, inode); 79 unlock_new_inode(inode); 80 orangefs_set_timeout(dentry); 81 ORANGEFS_I(inode)->getattr_time = jiffies - 1; 82 ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS; 83 84 gossip_debug(GOSSIP_NAME_DEBUG, 85 "%s: dentry instantiated for %pd\n", 86 __func__, 87 dentry); 88 89 dir->i_mtime = dir->i_ctime = current_time(dir); 90 memset(&iattr, 0, sizeof iattr); 91 iattr.ia_valid |= ATTR_MTIME; 92 orangefs_inode_setattr(dir, &iattr); 93 mark_inode_dirty_sync(dir); 94 ret = 0; 95 out: 96 gossip_debug(GOSSIP_NAME_DEBUG, 97 "%s: %pd: returning %d\n", 98 __func__, 99 dentry, 100 ret); 101 return ret; 102 } 103 104 /* 105 * Attempt to resolve an object name (dentry->d_name), parent handle, and 106 * fsid into a handle for the object. 107 */ 108 static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry, 109 unsigned int flags) 110 { 111 struct orangefs_inode_s *parent = ORANGEFS_I(dir); 112 struct orangefs_kernel_op_s *new_op; 113 struct inode *inode; 114 struct dentry *res; 115 int ret = -EINVAL; 116 117 /* 118 * in theory we could skip a lookup here (if the intent is to 119 * create) in order to avoid a potentially failed lookup, but 120 * leaving it in can skip a valid lookup and try to create a file 121 * that already exists (e.g. the vfs already handles checking for 122 * -EEXIST on O_EXCL opens, which is broken if we skip this lookup 123 * in the create path) 124 */ 125 gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %pd\n", 126 __func__, dentry); 127 128 if (dentry->d_name.len > (ORANGEFS_NAME_MAX - 1)) 129 return ERR_PTR(-ENAMETOOLONG); 130 131 new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP); 132 if (!new_op) 133 return ERR_PTR(-ENOMEM); 134 135 new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW; 136 137 gossip_debug(GOSSIP_NAME_DEBUG, "%s:%s:%d using parent %pU\n", 138 __FILE__, 139 __func__, 140 __LINE__, 141 &parent->refn.khandle); 142 new_op->upcall.req.lookup.parent_refn = parent->refn; 143 144 strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name, 145 ORANGEFS_NAME_MAX - 1); 146 147 gossip_debug(GOSSIP_NAME_DEBUG, 148 "%s: doing lookup on %s under %pU,%d\n", 149 __func__, 150 new_op->upcall.req.lookup.d_name, 151 &new_op->upcall.req.lookup.parent_refn.khandle, 152 new_op->upcall.req.lookup.parent_refn.fs_id); 153 154 ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 155 156 gossip_debug(GOSSIP_NAME_DEBUG, 157 "Lookup Got %pU, fsid %d (ret=%d)\n", 158 &new_op->downcall.resp.lookup.refn.khandle, 159 new_op->downcall.resp.lookup.refn.fs_id, 160 ret); 161 162 if (ret < 0) { 163 if (ret == -ENOENT) { 164 /* 165 * if no inode was found, add a negative dentry to 166 * dcache anyway; if we don't, we don't hold expected 167 * lookup semantics and we most noticeably break 168 * during directory renames. 169 * 170 * however, if the operation failed or exited, do not 171 * add the dentry (e.g. in the case that a touch is 172 * issued on a file that already exists that was 173 * interrupted during this lookup -- no need to add 174 * another negative dentry for an existing file) 175 */ 176 177 gossip_debug(GOSSIP_NAME_DEBUG, 178 "orangefs_lookup: Adding *negative* dentry " 179 "%p for %pd\n", 180 dentry, 181 dentry); 182 183 d_add(dentry, NULL); 184 res = NULL; 185 goto out; 186 } 187 188 /* must be a non-recoverable error */ 189 res = ERR_PTR(ret); 190 goto out; 191 } 192 193 orangefs_set_timeout(dentry); 194 195 inode = orangefs_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn); 196 if (IS_ERR(inode)) { 197 gossip_debug(GOSSIP_NAME_DEBUG, 198 "error %ld from iget\n", PTR_ERR(inode)); 199 res = ERR_CAST(inode); 200 goto out; 201 } 202 203 gossip_debug(GOSSIP_NAME_DEBUG, 204 "%s:%s:%d " 205 "Found good inode [%lu] with count [%d]\n", 206 __FILE__, 207 __func__, 208 __LINE__, 209 inode->i_ino, 210 (int)atomic_read(&inode->i_count)); 211 212 /* update dentry/inode pair into dcache */ 213 res = d_splice_alias(inode, dentry); 214 215 gossip_debug(GOSSIP_NAME_DEBUG, 216 "Lookup success (inode ct = %d)\n", 217 (int)atomic_read(&inode->i_count)); 218 out: 219 op_release(new_op); 220 return res; 221 } 222 223 /* return 0 on success; non-zero otherwise */ 224 static int orangefs_unlink(struct inode *dir, struct dentry *dentry) 225 { 226 struct inode *inode = dentry->d_inode; 227 struct orangefs_inode_s *parent = ORANGEFS_I(dir); 228 struct orangefs_kernel_op_s *new_op; 229 struct iattr iattr; 230 int ret; 231 232 gossip_debug(GOSSIP_NAME_DEBUG, 233 "%s: called on %pd\n" 234 " (inode %pU): Parent is %pU | fs_id %d\n", 235 __func__, 236 dentry, 237 get_khandle_from_ino(inode), 238 &parent->refn.khandle, 239 parent->refn.fs_id); 240 241 new_op = op_alloc(ORANGEFS_VFS_OP_REMOVE); 242 if (!new_op) 243 return -ENOMEM; 244 245 new_op->upcall.req.remove.parent_refn = parent->refn; 246 strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name, 247 ORANGEFS_NAME_MAX - 1); 248 249 ret = service_operation(new_op, "orangefs_unlink", 250 get_interruptible_flag(inode)); 251 252 gossip_debug(GOSSIP_NAME_DEBUG, 253 "%s: service_operation returned:%d:\n", 254 __func__, 255 ret); 256 257 op_release(new_op); 258 259 if (!ret) { 260 drop_nlink(inode); 261 262 dir->i_mtime = dir->i_ctime = current_time(dir); 263 memset(&iattr, 0, sizeof iattr); 264 iattr.ia_valid |= ATTR_MTIME; 265 orangefs_inode_setattr(dir, &iattr); 266 mark_inode_dirty_sync(dir); 267 } 268 return ret; 269 } 270 271 static int orangefs_symlink(struct inode *dir, 272 struct dentry *dentry, 273 const char *symname) 274 { 275 struct orangefs_inode_s *parent = ORANGEFS_I(dir); 276 struct orangefs_kernel_op_s *new_op; 277 struct orangefs_object_kref ref; 278 struct inode *inode; 279 struct iattr iattr; 280 int mode = 755; 281 int ret; 282 283 gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__); 284 285 if (!symname) 286 return -EINVAL; 287 288 if (strlen(symname)+1 > ORANGEFS_NAME_MAX) 289 return -ENAMETOOLONG; 290 291 new_op = op_alloc(ORANGEFS_VFS_OP_SYMLINK); 292 if (!new_op) 293 return -ENOMEM; 294 295 new_op->upcall.req.sym.parent_refn = parent->refn; 296 297 fill_default_sys_attrs(new_op->upcall.req.sym.attributes, 298 ORANGEFS_TYPE_SYMLINK, 299 mode); 300 301 strncpy(new_op->upcall.req.sym.entry_name, 302 dentry->d_name.name, 303 ORANGEFS_NAME_MAX - 1); 304 strncpy(new_op->upcall.req.sym.target, symname, ORANGEFS_NAME_MAX - 1); 305 306 ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 307 308 gossip_debug(GOSSIP_NAME_DEBUG, 309 "Symlink Got ORANGEFS handle %pU on fsid %d (ret=%d)\n", 310 &new_op->downcall.resp.sym.refn.khandle, 311 new_op->downcall.resp.sym.refn.fs_id, ret); 312 313 if (ret < 0) { 314 gossip_debug(GOSSIP_NAME_DEBUG, 315 "%s: failed with error code %d\n", 316 __func__, ret); 317 goto out; 318 } 319 320 ref = new_op->downcall.resp.sym.refn; 321 op_release(new_op); 322 323 inode = orangefs_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0, &ref); 324 if (IS_ERR(inode)) { 325 gossip_err 326 ("*** Failed to allocate orangefs symlink inode\n"); 327 ret = PTR_ERR(inode); 328 goto out; 329 } 330 331 gossip_debug(GOSSIP_NAME_DEBUG, 332 "Assigned symlink inode new number of %pU\n", 333 get_khandle_from_ino(inode)); 334 335 d_instantiate(dentry, inode); 336 unlock_new_inode(inode); 337 orangefs_set_timeout(dentry); 338 ORANGEFS_I(inode)->getattr_time = jiffies - 1; 339 ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS; 340 341 gossip_debug(GOSSIP_NAME_DEBUG, 342 "Inode (Symlink) %pU -> %pd\n", 343 get_khandle_from_ino(inode), 344 dentry); 345 346 dir->i_mtime = dir->i_ctime = current_time(dir); 347 memset(&iattr, 0, sizeof iattr); 348 iattr.ia_valid |= ATTR_MTIME; 349 orangefs_inode_setattr(dir, &iattr); 350 mark_inode_dirty_sync(dir); 351 ret = 0; 352 out: 353 return ret; 354 } 355 356 static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 357 { 358 struct orangefs_inode_s *parent = ORANGEFS_I(dir); 359 struct orangefs_kernel_op_s *new_op; 360 struct orangefs_object_kref ref; 361 struct inode *inode; 362 struct iattr iattr; 363 int ret; 364 365 new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR); 366 if (!new_op) 367 return -ENOMEM; 368 369 new_op->upcall.req.mkdir.parent_refn = parent->refn; 370 371 fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes, 372 ORANGEFS_TYPE_DIRECTORY, mode); 373 374 strncpy(new_op->upcall.req.mkdir.d_name, 375 dentry->d_name.name, ORANGEFS_NAME_MAX - 1); 376 377 ret = service_operation(new_op, __func__, get_interruptible_flag(dir)); 378 379 gossip_debug(GOSSIP_NAME_DEBUG, 380 "Mkdir Got ORANGEFS handle %pU on fsid %d\n", 381 &new_op->downcall.resp.mkdir.refn.khandle, 382 new_op->downcall.resp.mkdir.refn.fs_id); 383 384 if (ret < 0) { 385 gossip_debug(GOSSIP_NAME_DEBUG, 386 "%s: failed with error code %d\n", 387 __func__, ret); 388 goto out; 389 } 390 391 ref = new_op->downcall.resp.mkdir.refn; 392 op_release(new_op); 393 394 inode = orangefs_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0, &ref); 395 if (IS_ERR(inode)) { 396 gossip_err("*** Failed to allocate orangefs dir inode\n"); 397 ret = PTR_ERR(inode); 398 goto out; 399 } 400 401 gossip_debug(GOSSIP_NAME_DEBUG, 402 "Assigned dir inode new number of %pU\n", 403 get_khandle_from_ino(inode)); 404 405 d_instantiate(dentry, inode); 406 unlock_new_inode(inode); 407 orangefs_set_timeout(dentry); 408 ORANGEFS_I(inode)->getattr_time = jiffies - 1; 409 ORANGEFS_I(inode)->getattr_mask = STATX_BASIC_STATS; 410 411 gossip_debug(GOSSIP_NAME_DEBUG, 412 "Inode (Directory) %pU -> %pd\n", 413 get_khandle_from_ino(inode), 414 dentry); 415 416 /* 417 * NOTE: we have no good way to keep nlink consistent for directories 418 * across clients; keep constant at 1. 419 */ 420 dir->i_mtime = dir->i_ctime = current_time(dir); 421 memset(&iattr, 0, sizeof iattr); 422 iattr.ia_valid |= ATTR_MTIME; 423 orangefs_inode_setattr(dir, &iattr); 424 mark_inode_dirty_sync(dir); 425 out: 426 return ret; 427 } 428 429 static int orangefs_rename(struct inode *old_dir, 430 struct dentry *old_dentry, 431 struct inode *new_dir, 432 struct dentry *new_dentry, 433 unsigned int flags) 434 { 435 struct orangefs_kernel_op_s *new_op; 436 int ret; 437 438 if (flags) 439 return -EINVAL; 440 441 gossip_debug(GOSSIP_NAME_DEBUG, 442 "orangefs_rename: called (%pd2 => %pd2) ct=%d\n", 443 old_dentry, new_dentry, d_count(new_dentry)); 444 445 ORANGEFS_I(new_dentry->d_parent->d_inode)->getattr_time = jiffies - 1; 446 447 new_op = op_alloc(ORANGEFS_VFS_OP_RENAME); 448 if (!new_op) 449 return -EINVAL; 450 451 new_op->upcall.req.rename.old_parent_refn = ORANGEFS_I(old_dir)->refn; 452 new_op->upcall.req.rename.new_parent_refn = ORANGEFS_I(new_dir)->refn; 453 454 strncpy(new_op->upcall.req.rename.d_old_name, 455 old_dentry->d_name.name, 456 ORANGEFS_NAME_MAX - 1); 457 strncpy(new_op->upcall.req.rename.d_new_name, 458 new_dentry->d_name.name, 459 ORANGEFS_NAME_MAX - 1); 460 461 ret = service_operation(new_op, 462 "orangefs_rename", 463 get_interruptible_flag(old_dentry->d_inode)); 464 465 gossip_debug(GOSSIP_NAME_DEBUG, 466 "orangefs_rename: got downcall status %d\n", 467 ret); 468 469 if (new_dentry->d_inode) 470 new_dentry->d_inode->i_ctime = current_time(new_dentry->d_inode); 471 472 op_release(new_op); 473 return ret; 474 } 475 476 /* ORANGEFS implementation of VFS inode operations for directories */ 477 const struct inode_operations orangefs_dir_inode_operations = { 478 .lookup = orangefs_lookup, 479 .get_acl = orangefs_get_acl, 480 .set_acl = orangefs_set_acl, 481 .create = orangefs_create, 482 .unlink = orangefs_unlink, 483 .symlink = orangefs_symlink, 484 .mkdir = orangefs_mkdir, 485 .rmdir = orangefs_unlink, 486 .rename = orangefs_rename, 487 .setattr = orangefs_setattr, 488 .getattr = orangefs_getattr, 489 .listxattr = orangefs_listxattr, 490 .permission = orangefs_permission, 491 .update_time = orangefs_update_time, 492 }; 493