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 <linux/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 (%*s)\n", 51 coda_i2s(dir), (int)length, name); 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 inode *inode, int mask) 77 { 78 int error; 79 80 if (mask & MAY_NOT_BLOCK) 81 return -ECHILD; 82 83 mask &= MAY_READ | MAY_WRITE | MAY_EXEC; 84 85 if (!mask) 86 return 0; 87 88 if ((mask & MAY_EXEC) && !execute_ok(inode)) 89 return -EACCES; 90 91 if (coda_cache_check(inode, mask)) 92 return 0; 93 94 error = venus_access(inode->i_sb, coda_i2f(inode), mask); 95 96 if (!error) 97 coda_cache_enter(inode, mask); 98 99 return error; 100 } 101 102 103 static inline void coda_dir_update_mtime(struct inode *dir) 104 { 105 #ifdef REQUERY_VENUS_FOR_MTIME 106 /* invalidate the directory cnode's attributes so we refetch the 107 * attributes from venus next time the inode is referenced */ 108 coda_flag_inode(dir, C_VATTR); 109 #else 110 /* optimistically we can also act as if our nose bleeds. The 111 * granularity of the mtime is coarse anyways so we might actually be 112 * right most of the time. Note: we only do this for directories. */ 113 dir->i_mtime = dir->i_ctime = current_time(dir); 114 #endif 115 } 116 117 /* we have to wrap inc_nlink/drop_nlink because sometimes userspace uses a 118 * trick to fool GNU find's optimizations. If we can't be sure of the link 119 * (because of volume mount points) we set i_nlink to 1 which forces find 120 * to consider every child as a possible directory. We should also never 121 * see an increment or decrement for deleted directories where i_nlink == 0 */ 122 static inline void coda_dir_inc_nlink(struct inode *dir) 123 { 124 if (dir->i_nlink >= 2) 125 inc_nlink(dir); 126 } 127 128 static inline void coda_dir_drop_nlink(struct inode *dir) 129 { 130 if (dir->i_nlink > 2) 131 drop_nlink(dir); 132 } 133 134 /* creation routines: create, mknod, mkdir, link, symlink */ 135 static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, bool excl) 136 { 137 int error; 138 const char *name=de->d_name.name; 139 int length=de->d_name.len; 140 struct inode *inode; 141 struct CodaFid newfid; 142 struct coda_vattr attrs; 143 144 if (is_root_inode(dir) && coda_iscontrol(name, length)) 145 return -EPERM; 146 147 error = venus_create(dir->i_sb, coda_i2f(dir), name, length, 148 0, mode, &newfid, &attrs); 149 if (error) 150 goto err_out; 151 152 inode = coda_iget(dir->i_sb, &newfid, &attrs); 153 if (IS_ERR(inode)) { 154 error = PTR_ERR(inode); 155 goto err_out; 156 } 157 158 /* invalidate the directory cnode's attributes */ 159 coda_dir_update_mtime(dir); 160 d_instantiate(de, inode); 161 return 0; 162 err_out: 163 d_drop(de); 164 return error; 165 } 166 167 static int coda_mkdir(struct inode *dir, struct dentry *de, umode_t mode) 168 { 169 struct inode *inode; 170 struct coda_vattr attrs; 171 const char *name = de->d_name.name; 172 int len = de->d_name.len; 173 int error; 174 struct CodaFid newfid; 175 176 if (is_root_inode(dir) && coda_iscontrol(name, len)) 177 return -EPERM; 178 179 attrs.va_mode = mode; 180 error = venus_mkdir(dir->i_sb, coda_i2f(dir), 181 name, len, &newfid, &attrs); 182 if (error) 183 goto err_out; 184 185 inode = coda_iget(dir->i_sb, &newfid, &attrs); 186 if (IS_ERR(inode)) { 187 error = PTR_ERR(inode); 188 goto err_out; 189 } 190 191 /* invalidate the directory cnode's attributes */ 192 coda_dir_inc_nlink(dir); 193 coda_dir_update_mtime(dir); 194 d_instantiate(de, inode); 195 return 0; 196 err_out: 197 d_drop(de); 198 return error; 199 } 200 201 /* try to make de an entry in dir_inodde linked to source_de */ 202 static int coda_link(struct dentry *source_de, struct inode *dir_inode, 203 struct dentry *de) 204 { 205 struct inode *inode = d_inode(source_de); 206 const char * name = de->d_name.name; 207 int len = de->d_name.len; 208 int error; 209 210 if (is_root_inode(dir_inode) && coda_iscontrol(name, len)) 211 return -EPERM; 212 213 error = venus_link(dir_inode->i_sb, coda_i2f(inode), 214 coda_i2f(dir_inode), (const char *)name, len); 215 if (error) { 216 d_drop(de); 217 return error; 218 } 219 220 coda_dir_update_mtime(dir_inode); 221 ihold(inode); 222 d_instantiate(de, inode); 223 inc_nlink(inode); 224 return 0; 225 } 226 227 228 static int coda_symlink(struct inode *dir_inode, struct dentry *de, 229 const char *symname) 230 { 231 const char *name = de->d_name.name; 232 int len = de->d_name.len; 233 int symlen; 234 int error; 235 236 if (is_root_inode(dir_inode) && coda_iscontrol(name, len)) 237 return -EPERM; 238 239 symlen = strlen(symname); 240 if (symlen > CODA_MAXPATHLEN) 241 return -ENAMETOOLONG; 242 243 /* 244 * This entry is now negative. Since we do not create 245 * an inode for the entry we have to drop it. 246 */ 247 d_drop(de); 248 error = venus_symlink(dir_inode->i_sb, coda_i2f(dir_inode), name, len, 249 symname, symlen); 250 251 /* mtime is no good anymore */ 252 if (!error) 253 coda_dir_update_mtime(dir_inode); 254 255 return error; 256 } 257 258 /* destruction routines: unlink, rmdir */ 259 static int coda_unlink(struct inode *dir, struct dentry *de) 260 { 261 int error; 262 const char *name = de->d_name.name; 263 int len = de->d_name.len; 264 265 error = venus_remove(dir->i_sb, coda_i2f(dir), name, len); 266 if (error) 267 return error; 268 269 coda_dir_update_mtime(dir); 270 drop_nlink(d_inode(de)); 271 return 0; 272 } 273 274 static int coda_rmdir(struct inode *dir, struct dentry *de) 275 { 276 const char *name = de->d_name.name; 277 int len = de->d_name.len; 278 int error; 279 280 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); 281 if (!error) { 282 /* VFS may delete the child */ 283 if (d_really_is_positive(de)) 284 clear_nlink(d_inode(de)); 285 286 /* fix the link count of the parent */ 287 coda_dir_drop_nlink(dir); 288 coda_dir_update_mtime(dir); 289 } 290 return error; 291 } 292 293 /* rename */ 294 static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, 295 struct inode *new_dir, struct dentry *new_dentry, 296 unsigned int flags) 297 { 298 const char *old_name = old_dentry->d_name.name; 299 const char *new_name = new_dentry->d_name.name; 300 int old_length = old_dentry->d_name.len; 301 int new_length = new_dentry->d_name.len; 302 int error; 303 304 if (flags) 305 return -EINVAL; 306 307 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), 308 coda_i2f(new_dir), old_length, new_length, 309 (const char *) old_name, (const char *)new_name); 310 if (!error) { 311 if (d_really_is_positive(new_dentry)) { 312 if (d_is_dir(new_dentry)) { 313 coda_dir_drop_nlink(old_dir); 314 coda_dir_inc_nlink(new_dir); 315 } 316 coda_dir_update_mtime(old_dir); 317 coda_dir_update_mtime(new_dir); 318 coda_flag_inode(d_inode(new_dentry), C_VATTR); 319 } else { 320 coda_flag_inode(old_dir, C_VATTR); 321 coda_flag_inode(new_dir, C_VATTR); 322 } 323 } 324 return error; 325 } 326 327 static inline unsigned int CDT2DT(unsigned char cdt) 328 { 329 unsigned int dt; 330 331 switch(cdt) { 332 case CDT_UNKNOWN: dt = DT_UNKNOWN; break; 333 case CDT_FIFO: dt = DT_FIFO; break; 334 case CDT_CHR: dt = DT_CHR; break; 335 case CDT_DIR: dt = DT_DIR; break; 336 case CDT_BLK: dt = DT_BLK; break; 337 case CDT_REG: dt = DT_REG; break; 338 case CDT_LNK: dt = DT_LNK; break; 339 case CDT_SOCK: dt = DT_SOCK; break; 340 case CDT_WHT: dt = DT_WHT; break; 341 default: dt = DT_UNKNOWN; break; 342 } 343 return dt; 344 } 345 346 /* support routines */ 347 static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx) 348 { 349 struct coda_file_info *cfi; 350 struct coda_inode_info *cii; 351 struct file *host_file; 352 struct venus_dirent *vdir; 353 unsigned long vdir_size = offsetof(struct venus_dirent, d_name); 354 unsigned int type; 355 struct qstr name; 356 ino_t ino; 357 int ret; 358 359 cfi = CODA_FTOC(coda_file); 360 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); 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 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); 431 host_file = cfi->cfi_container; 432 433 if (host_file->f_op->iterate || host_file->f_op->iterate_shared) { 434 struct inode *host_inode = file_inode(host_file); 435 ret = -ENOENT; 436 if (!IS_DEADDIR(host_inode)) { 437 if (host_file->f_op->iterate_shared) { 438 inode_lock_shared(host_inode); 439 ret = host_file->f_op->iterate_shared(host_file, ctx); 440 file_accessed(host_file); 441 inode_unlock_shared(host_inode); 442 } else { 443 inode_lock(host_inode); 444 ret = host_file->f_op->iterate(host_file, ctx); 445 file_accessed(host_file); 446 inode_unlock(host_inode); 447 } 448 } 449 return ret; 450 } 451 /* Venus: we must read Venus dirents from a file */ 452 return coda_venus_readdir(coda_file, ctx); 453 } 454 455 /* called when a cache lookup succeeds */ 456 static int coda_dentry_revalidate(struct dentry *de, unsigned int flags) 457 { 458 struct inode *inode; 459 struct coda_inode_info *cii; 460 461 if (flags & LOOKUP_RCU) 462 return -ECHILD; 463 464 inode = d_inode(de); 465 if (!inode || is_root_inode(inode)) 466 goto out; 467 if (is_bad_inode(inode)) 468 goto bad; 469 470 cii = ITOC(d_inode(de)); 471 if (!(cii->c_flags & (C_PURGE | C_FLUSH))) 472 goto out; 473 474 shrink_dcache_parent(de); 475 476 /* propagate for a flush */ 477 if (cii->c_flags & C_FLUSH) 478 coda_flag_inode_children(inode, C_FLUSH); 479 480 if (d_count(de) > 1) 481 /* pretend it's valid, but don't change the flags */ 482 goto out; 483 484 /* clear the flags. */ 485 spin_lock(&cii->c_lock); 486 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 487 spin_unlock(&cii->c_lock); 488 bad: 489 return 0; 490 out: 491 return 1; 492 } 493 494 /* 495 * This is the callback from dput() when d_count is going to 0. 496 * We use this to unhash dentries with bad inodes. 497 */ 498 static int coda_dentry_delete(const struct dentry * dentry) 499 { 500 int flags; 501 502 if (d_really_is_negative(dentry)) 503 return 0; 504 505 flags = (ITOC(d_inode(dentry))->c_flags) & C_PURGE; 506 if (is_bad_inode(d_inode(dentry)) || flags) { 507 return 1; 508 } 509 return 0; 510 } 511 512 513 514 /* 515 * This is called when we want to check if the inode has 516 * changed on the server. Coda makes this easy since the 517 * cache manager Venus issues a downcall to the kernel when this 518 * happens 519 */ 520 int coda_revalidate_inode(struct inode *inode) 521 { 522 struct coda_vattr attr; 523 int error; 524 int old_mode; 525 ino_t old_ino; 526 struct coda_inode_info *cii = ITOC(inode); 527 528 if (!cii->c_flags) 529 return 0; 530 531 if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) { 532 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr); 533 if (error) 534 return -EIO; 535 536 /* this inode may be lost if: 537 - it's ino changed 538 - type changes must be permitted for repair and 539 missing mount points. 540 */ 541 old_mode = inode->i_mode; 542 old_ino = inode->i_ino; 543 coda_vattr_to_iattr(inode, &attr); 544 545 if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) { 546 pr_warn("inode %ld, fid %s changed type!\n", 547 inode->i_ino, coda_f2s(&(cii->c_fid))); 548 } 549 550 /* the following can happen when a local fid is replaced 551 with a global one, here we lose and declare the inode bad */ 552 if (inode->i_ino != old_ino) 553 return -EIO; 554 555 coda_flag_inode_children(inode, C_FLUSH); 556 557 spin_lock(&cii->c_lock); 558 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 559 spin_unlock(&cii->c_lock); 560 } 561 return 0; 562 } 563 564 const struct dentry_operations coda_dentry_operations = { 565 .d_revalidate = coda_dentry_revalidate, 566 .d_delete = coda_dentry_delete, 567 }; 568 569 const struct inode_operations coda_dir_inode_operations = { 570 .create = coda_create, 571 .lookup = coda_lookup, 572 .link = coda_link, 573 .unlink = coda_unlink, 574 .symlink = coda_symlink, 575 .mkdir = coda_mkdir, 576 .rmdir = coda_rmdir, 577 .mknod = CODA_EIO_ERROR, 578 .rename = coda_rename, 579 .permission = coda_permission, 580 .getattr = coda_getattr, 581 .setattr = coda_setattr, 582 }; 583 584 const struct file_operations coda_dir_operations = { 585 .llseek = generic_file_llseek, 586 .read = generic_read_dir, 587 .iterate = coda_readdir, 588 .open = coda_open, 589 .release = coda_release, 590 .fsync = coda_fsync, 591 }; 592