1 // SPDX-License-Identifier: GPL-2.0 2 3 /* 4 * Directory operations for Coda filesystem 5 * Original version: (C) 1996 P. Braam and M. Callahan 6 * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University 7 * 8 * Carnegie Mellon encourages users to contribute improvements to 9 * the Coda project. Contact Peter Braam (coda@cs.cmu.edu). 10 */ 11 12 #include <linux/types.h> 13 #include <linux/kernel.h> 14 #include <linux/time.h> 15 #include <linux/fs.h> 16 #include <linux/slab.h> 17 #include <linux/file.h> 18 #include <linux/stat.h> 19 #include <linux/errno.h> 20 #include <linux/string.h> 21 #include <linux/spinlock.h> 22 #include <linux/namei.h> 23 #include <linux/uaccess.h> 24 25 #include <linux/coda.h> 26 #include "coda_psdev.h" 27 #include "coda_linux.h" 28 #include "coda_cache.h" 29 30 #include "coda_int.h" 31 32 /* same as fs/bad_inode.c */ 33 static int coda_return_EIO(void) 34 { 35 return -EIO; 36 } 37 #define CODA_EIO_ERROR ((void *) (coda_return_EIO)) 38 39 /* inode operations for directories */ 40 /* access routines: lookup, readlink, permission */ 41 static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsigned int flags) 42 { 43 struct super_block *sb = dir->i_sb; 44 const char *name = entry->d_name.name; 45 size_t length = entry->d_name.len; 46 struct inode *inode; 47 int type = 0; 48 49 if (length > CODA_MAXNAMLEN) { 50 pr_err("name too long: lookup, %s %zu\n", 51 coda_i2s(dir), length); 52 return ERR_PTR(-ENAMETOOLONG); 53 } 54 55 /* control object, create inode on the fly */ 56 if (is_root_inode(dir) && coda_iscontrol(name, length)) { 57 inode = coda_cnode_makectl(sb); 58 type = CODA_NOCACHE; 59 } else { 60 struct CodaFid fid = { { 0, } }; 61 int error = venus_lookup(sb, coda_i2f(dir), name, length, 62 &type, &fid); 63 inode = !error ? coda_cnode_make(&fid, sb) : ERR_PTR(error); 64 } 65 66 if (!IS_ERR(inode) && (type & CODA_NOCACHE)) 67 coda_flag_inode(inode, C_VATTR | C_PURGE); 68 69 if (inode == ERR_PTR(-ENOENT)) 70 inode = NULL; 71 72 return d_splice_alias(inode, entry); 73 } 74 75 76 int coda_permission(struct mnt_idmap *idmap, struct inode *inode, 77 int mask) 78 { 79 int error; 80 81 if (mask & MAY_NOT_BLOCK) 82 return -ECHILD; 83 84 mask &= MAY_READ | MAY_WRITE | MAY_EXEC; 85 86 if (!mask) 87 return 0; 88 89 if ((mask & MAY_EXEC) && !execute_ok(inode)) 90 return -EACCES; 91 92 if (coda_cache_check(inode, mask)) 93 return 0; 94 95 error = venus_access(inode->i_sb, coda_i2f(inode), mask); 96 97 if (!error) 98 coda_cache_enter(inode, mask); 99 100 return error; 101 } 102 103 104 static inline void coda_dir_update_mtime(struct inode *dir) 105 { 106 #ifdef REQUERY_VENUS_FOR_MTIME 107 /* invalidate the directory cnode's attributes so we refetch the 108 * attributes from venus next time the inode is referenced */ 109 coda_flag_inode(dir, C_VATTR); 110 #else 111 /* optimistically we can also act as if our nose bleeds. The 112 * granularity of the mtime is coarse anyways so we might actually be 113 * right most of the time. Note: we only do this for directories. */ 114 inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); 115 #endif 116 } 117 118 /* we have to wrap inc_nlink/drop_nlink because sometimes userspace uses a 119 * trick to fool GNU find's optimizations. If we can't be sure of the link 120 * (because of volume mount points) we set i_nlink to 1 which forces find 121 * to consider every child as a possible directory. We should also never 122 * see an increment or decrement for deleted directories where i_nlink == 0 */ 123 static inline void coda_dir_inc_nlink(struct inode *dir) 124 { 125 if (dir->i_nlink >= 2) 126 inc_nlink(dir); 127 } 128 129 static inline void coda_dir_drop_nlink(struct inode *dir) 130 { 131 if (dir->i_nlink > 2) 132 drop_nlink(dir); 133 } 134 135 /* creation routines: create, mknod, mkdir, link, symlink */ 136 static int coda_create(struct mnt_idmap *idmap, struct inode *dir, 137 struct dentry *de, umode_t mode, bool excl) 138 { 139 int error; 140 const char *name=de->d_name.name; 141 int length=de->d_name.len; 142 struct inode *inode; 143 struct CodaFid newfid; 144 struct coda_vattr attrs; 145 146 if (is_root_inode(dir) && coda_iscontrol(name, length)) 147 return -EPERM; 148 149 error = venus_create(dir->i_sb, coda_i2f(dir), name, length, 150 0, mode, &newfid, &attrs); 151 if (error) 152 goto err_out; 153 154 inode = coda_iget(dir->i_sb, &newfid, &attrs); 155 if (IS_ERR(inode)) { 156 error = PTR_ERR(inode); 157 goto err_out; 158 } 159 160 /* invalidate the directory cnode's attributes */ 161 coda_dir_update_mtime(dir); 162 d_instantiate(de, inode); 163 return 0; 164 err_out: 165 d_drop(de); 166 return error; 167 } 168 169 static int coda_mkdir(struct mnt_idmap *idmap, struct inode *dir, 170 struct dentry *de, umode_t mode) 171 { 172 struct inode *inode; 173 struct coda_vattr attrs; 174 const char *name = de->d_name.name; 175 int len = de->d_name.len; 176 int error; 177 struct CodaFid newfid; 178 179 if (is_root_inode(dir) && coda_iscontrol(name, len)) 180 return -EPERM; 181 182 attrs.va_mode = mode; 183 error = venus_mkdir(dir->i_sb, coda_i2f(dir), 184 name, len, &newfid, &attrs); 185 if (error) 186 goto err_out; 187 188 inode = coda_iget(dir->i_sb, &newfid, &attrs); 189 if (IS_ERR(inode)) { 190 error = PTR_ERR(inode); 191 goto err_out; 192 } 193 194 /* invalidate the directory cnode's attributes */ 195 coda_dir_inc_nlink(dir); 196 coda_dir_update_mtime(dir); 197 d_instantiate(de, inode); 198 return 0; 199 err_out: 200 d_drop(de); 201 return error; 202 } 203 204 /* try to make de an entry in dir_inodde linked to source_de */ 205 static int coda_link(struct dentry *source_de, struct inode *dir_inode, 206 struct dentry *de) 207 { 208 struct inode *inode = d_inode(source_de); 209 const char * name = de->d_name.name; 210 int len = de->d_name.len; 211 int error; 212 213 if (is_root_inode(dir_inode) && coda_iscontrol(name, len)) 214 return -EPERM; 215 216 error = venus_link(dir_inode->i_sb, coda_i2f(inode), 217 coda_i2f(dir_inode), (const char *)name, len); 218 if (error) { 219 d_drop(de); 220 return error; 221 } 222 223 coda_dir_update_mtime(dir_inode); 224 ihold(inode); 225 d_instantiate(de, inode); 226 inc_nlink(inode); 227 return 0; 228 } 229 230 231 static int coda_symlink(struct mnt_idmap *idmap, 232 struct inode *dir_inode, struct dentry *de, 233 const char *symname) 234 { 235 const char *name = de->d_name.name; 236 int len = de->d_name.len; 237 int symlen; 238 int error; 239 240 if (is_root_inode(dir_inode) && coda_iscontrol(name, len)) 241 return -EPERM; 242 243 symlen = strlen(symname); 244 if (symlen > CODA_MAXPATHLEN) 245 return -ENAMETOOLONG; 246 247 /* 248 * This entry is now negative. Since we do not create 249 * an inode for the entry we have to drop it. 250 */ 251 d_drop(de); 252 error = venus_symlink(dir_inode->i_sb, coda_i2f(dir_inode), name, len, 253 symname, symlen); 254 255 /* mtime is no good anymore */ 256 if (!error) 257 coda_dir_update_mtime(dir_inode); 258 259 return error; 260 } 261 262 /* destruction routines: unlink, rmdir */ 263 static int coda_unlink(struct inode *dir, struct dentry *de) 264 { 265 int error; 266 const char *name = de->d_name.name; 267 int len = de->d_name.len; 268 269 error = venus_remove(dir->i_sb, coda_i2f(dir), name, len); 270 if (error) 271 return error; 272 273 coda_dir_update_mtime(dir); 274 drop_nlink(d_inode(de)); 275 return 0; 276 } 277 278 static int coda_rmdir(struct inode *dir, struct dentry *de) 279 { 280 const char *name = de->d_name.name; 281 int len = de->d_name.len; 282 int error; 283 284 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); 285 if (!error) { 286 /* VFS may delete the child */ 287 if (d_really_is_positive(de)) 288 clear_nlink(d_inode(de)); 289 290 /* fix the link count of the parent */ 291 coda_dir_drop_nlink(dir); 292 coda_dir_update_mtime(dir); 293 } 294 return error; 295 } 296 297 /* rename */ 298 static int coda_rename(struct mnt_idmap *idmap, struct inode *old_dir, 299 struct dentry *old_dentry, struct inode *new_dir, 300 struct dentry *new_dentry, unsigned int flags) 301 { 302 const char *old_name = old_dentry->d_name.name; 303 const char *new_name = new_dentry->d_name.name; 304 int old_length = old_dentry->d_name.len; 305 int new_length = new_dentry->d_name.len; 306 int error; 307 308 if (flags) 309 return -EINVAL; 310 311 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), 312 coda_i2f(new_dir), old_length, new_length, 313 (const char *) old_name, (const char *)new_name); 314 if (!error) { 315 if (d_really_is_positive(new_dentry)) { 316 if (d_is_dir(new_dentry)) { 317 coda_dir_drop_nlink(old_dir); 318 coda_dir_inc_nlink(new_dir); 319 } 320 coda_flag_inode(d_inode(new_dentry), C_VATTR); 321 } 322 coda_dir_update_mtime(old_dir); 323 coda_dir_update_mtime(new_dir); 324 } 325 return error; 326 } 327 328 static inline unsigned int CDT2DT(unsigned char cdt) 329 { 330 unsigned int dt; 331 332 switch(cdt) { 333 case CDT_UNKNOWN: dt = DT_UNKNOWN; break; 334 case CDT_FIFO: dt = DT_FIFO; break; 335 case CDT_CHR: dt = DT_CHR; break; 336 case CDT_DIR: dt = DT_DIR; break; 337 case CDT_BLK: dt = DT_BLK; break; 338 case CDT_REG: dt = DT_REG; break; 339 case CDT_LNK: dt = DT_LNK; break; 340 case CDT_SOCK: dt = DT_SOCK; break; 341 case CDT_WHT: dt = DT_WHT; break; 342 default: dt = DT_UNKNOWN; break; 343 } 344 return dt; 345 } 346 347 /* support routines */ 348 static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx) 349 { 350 struct coda_file_info *cfi; 351 struct coda_inode_info *cii; 352 struct file *host_file; 353 struct venus_dirent *vdir; 354 unsigned long vdir_size = offsetof(struct venus_dirent, d_name); 355 unsigned int type; 356 struct qstr name; 357 ino_t ino; 358 int ret; 359 360 cfi = coda_ftoc(coda_file); 361 host_file = cfi->cfi_container; 362 363 cii = ITOC(file_inode(coda_file)); 364 365 vdir = kmalloc(sizeof(*vdir), GFP_KERNEL); 366 if (!vdir) return -ENOMEM; 367 368 if (!dir_emit_dots(coda_file, ctx)) 369 goto out; 370 371 while (1) { 372 loff_t pos = ctx->pos - 2; 373 374 /* read entries from the directory file */ 375 ret = kernel_read(host_file, vdir, sizeof(*vdir), &pos); 376 if (ret < 0) { 377 pr_err("%s: read dir %s failed %d\n", 378 __func__, coda_f2s(&cii->c_fid), ret); 379 break; 380 } 381 if (ret == 0) break; /* end of directory file reached */ 382 383 /* catch truncated reads */ 384 if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) { 385 pr_err("%s: short read on %s\n", 386 __func__, coda_f2s(&cii->c_fid)); 387 ret = -EBADF; 388 break; 389 } 390 /* validate whether the directory file actually makes sense */ 391 if (vdir->d_reclen < vdir_size + vdir->d_namlen) { 392 pr_err("%s: invalid dir %s\n", 393 __func__, coda_f2s(&cii->c_fid)); 394 ret = -EBADF; 395 break; 396 } 397 398 name.len = vdir->d_namlen; 399 name.name = vdir->d_name; 400 401 /* Make sure we skip '.' and '..', we already got those */ 402 if (name.name[0] == '.' && (name.len == 1 || 403 (name.name[1] == '.' && name.len == 2))) 404 vdir->d_fileno = name.len = 0; 405 406 /* skip null entries */ 407 if (vdir->d_fileno && name.len) { 408 ino = vdir->d_fileno; 409 type = CDT2DT(vdir->d_type); 410 if (!dir_emit(ctx, name.name, name.len, ino, type)) 411 break; 412 } 413 /* we'll always have progress because d_reclen is unsigned and 414 * we've already established it is non-zero. */ 415 ctx->pos += vdir->d_reclen; 416 } 417 out: 418 kfree(vdir); 419 return 0; 420 } 421 422 /* file operations for directories */ 423 static int coda_readdir(struct file *coda_file, struct dir_context *ctx) 424 { 425 struct coda_file_info *cfi; 426 struct file *host_file; 427 int ret; 428 429 cfi = coda_ftoc(coda_file); 430 host_file = cfi->cfi_container; 431 432 if (host_file->f_op->iterate_shared) { 433 struct inode *host_inode = file_inode(host_file); 434 ret = -ENOENT; 435 if (!IS_DEADDIR(host_inode)) { 436 inode_lock_shared(host_inode); 437 ret = host_file->f_op->iterate_shared(host_file, ctx); 438 file_accessed(host_file); 439 inode_unlock_shared(host_inode); 440 } 441 return ret; 442 } 443 /* Venus: we must read Venus dirents from a file */ 444 return coda_venus_readdir(coda_file, ctx); 445 } 446 447 /* called when a cache lookup succeeds */ 448 static int coda_dentry_revalidate(struct dentry *de, unsigned int flags) 449 { 450 struct inode *inode; 451 struct coda_inode_info *cii; 452 453 if (flags & LOOKUP_RCU) 454 return -ECHILD; 455 456 inode = d_inode(de); 457 if (!inode || is_root_inode(inode)) 458 goto out; 459 if (is_bad_inode(inode)) 460 goto bad; 461 462 cii = ITOC(d_inode(de)); 463 if (!(cii->c_flags & (C_PURGE | C_FLUSH))) 464 goto out; 465 466 shrink_dcache_parent(de); 467 468 /* propagate for a flush */ 469 if (cii->c_flags & C_FLUSH) 470 coda_flag_inode_children(inode, C_FLUSH); 471 472 if (d_count(de) > 1) 473 /* pretend it's valid, but don't change the flags */ 474 goto out; 475 476 /* clear the flags. */ 477 spin_lock(&cii->c_lock); 478 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 479 spin_unlock(&cii->c_lock); 480 bad: 481 return 0; 482 out: 483 return 1; 484 } 485 486 /* 487 * This is the callback from dput() when d_count is going to 0. 488 * We use this to unhash dentries with bad inodes. 489 */ 490 static int coda_dentry_delete(const struct dentry * dentry) 491 { 492 struct inode *inode; 493 struct coda_inode_info *cii; 494 495 if (d_really_is_negative(dentry)) 496 return 0; 497 498 inode = d_inode(dentry); 499 if (!inode || is_bad_inode(inode)) 500 return 1; 501 502 cii = ITOC(inode); 503 if (cii->c_flags & C_PURGE) 504 return 1; 505 506 return 0; 507 } 508 509 510 511 /* 512 * This is called when we want to check if the inode has 513 * changed on the server. Coda makes this easy since the 514 * cache manager Venus issues a downcall to the kernel when this 515 * happens 516 */ 517 int coda_revalidate_inode(struct inode *inode) 518 { 519 struct coda_vattr attr; 520 int error; 521 int old_mode; 522 ino_t old_ino; 523 struct coda_inode_info *cii = ITOC(inode); 524 525 if (!cii->c_flags) 526 return 0; 527 528 if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) { 529 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr); 530 if (error) 531 return -EIO; 532 533 /* this inode may be lost if: 534 - it's ino changed 535 - type changes must be permitted for repair and 536 missing mount points. 537 */ 538 old_mode = inode->i_mode; 539 old_ino = inode->i_ino; 540 coda_vattr_to_iattr(inode, &attr); 541 542 if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) { 543 pr_warn("inode %ld, fid %s changed type!\n", 544 inode->i_ino, coda_f2s(&(cii->c_fid))); 545 } 546 547 /* the following can happen when a local fid is replaced 548 with a global one, here we lose and declare the inode bad */ 549 if (inode->i_ino != old_ino) 550 return -EIO; 551 552 coda_flag_inode_children(inode, C_FLUSH); 553 554 spin_lock(&cii->c_lock); 555 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 556 spin_unlock(&cii->c_lock); 557 } 558 return 0; 559 } 560 561 const struct dentry_operations coda_dentry_operations = { 562 .d_revalidate = coda_dentry_revalidate, 563 .d_delete = coda_dentry_delete, 564 }; 565 566 const struct inode_operations coda_dir_inode_operations = { 567 .create = coda_create, 568 .lookup = coda_lookup, 569 .link = coda_link, 570 .unlink = coda_unlink, 571 .symlink = coda_symlink, 572 .mkdir = coda_mkdir, 573 .rmdir = coda_rmdir, 574 .mknod = CODA_EIO_ERROR, 575 .rename = coda_rename, 576 .permission = coda_permission, 577 .getattr = coda_getattr, 578 .setattr = coda_setattr, 579 }; 580 581 WRAP_DIR_ITER(coda_readdir) // FIXME! 582 const struct file_operations coda_dir_operations = { 583 .llseek = generic_file_llseek, 584 .read = generic_read_dir, 585 .iterate_shared = shared_coda_readdir, 586 .open = coda_open, 587 .release = coda_release, 588 .fsync = coda_fsync, 589 }; 590
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.