dir.c (14682B)
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 */ 33static 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 */ 41static 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 76int coda_permission(struct user_namespace *mnt_userns, 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 104static 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 dir->i_mtime = dir->i_ctime = current_time(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 */ 123static inline void coda_dir_inc_nlink(struct inode *dir) 124{ 125 if (dir->i_nlink >= 2) 126 inc_nlink(dir); 127} 128 129static 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 */ 136static int coda_create(struct user_namespace *mnt_userns, 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; 164err_out: 165 d_drop(de); 166 return error; 167} 168 169static int coda_mkdir(struct user_namespace *mnt_userns, 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; 199err_out: 200 d_drop(de); 201 return error; 202} 203 204/* try to make de an entry in dir_inodde linked to source_de */ 205static 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 231static int coda_symlink(struct user_namespace *mnt_userns, 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 */ 263static 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 278static 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 */ 298static int coda_rename(struct user_namespace *mnt_userns, 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 328static 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 */ 348static 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 } 417out: 418 kfree(vdir); 419 return 0; 420} 421 422/* file operations for directories */ 423static 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 || 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 if (host_file->f_op->iterate_shared) { 437 inode_lock_shared(host_inode); 438 ret = host_file->f_op->iterate_shared(host_file, ctx); 439 file_accessed(host_file); 440 inode_unlock_shared(host_inode); 441 } else { 442 inode_lock(host_inode); 443 ret = host_file->f_op->iterate(host_file, ctx); 444 file_accessed(host_file); 445 inode_unlock(host_inode); 446 } 447 } 448 return ret; 449 } 450 /* Venus: we must read Venus dirents from a file */ 451 return coda_venus_readdir(coda_file, ctx); 452} 453 454/* called when a cache lookup succeeds */ 455static int coda_dentry_revalidate(struct dentry *de, unsigned int flags) 456{ 457 struct inode *inode; 458 struct coda_inode_info *cii; 459 460 if (flags & LOOKUP_RCU) 461 return -ECHILD; 462 463 inode = d_inode(de); 464 if (!inode || is_root_inode(inode)) 465 goto out; 466 if (is_bad_inode(inode)) 467 goto bad; 468 469 cii = ITOC(d_inode(de)); 470 if (!(cii->c_flags & (C_PURGE | C_FLUSH))) 471 goto out; 472 473 shrink_dcache_parent(de); 474 475 /* propagate for a flush */ 476 if (cii->c_flags & C_FLUSH) 477 coda_flag_inode_children(inode, C_FLUSH); 478 479 if (d_count(de) > 1) 480 /* pretend it's valid, but don't change the flags */ 481 goto out; 482 483 /* clear the flags. */ 484 spin_lock(&cii->c_lock); 485 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 486 spin_unlock(&cii->c_lock); 487bad: 488 return 0; 489out: 490 return 1; 491} 492 493/* 494 * This is the callback from dput() when d_count is going to 0. 495 * We use this to unhash dentries with bad inodes. 496 */ 497static int coda_dentry_delete(const struct dentry * dentry) 498{ 499 struct inode *inode; 500 struct coda_inode_info *cii; 501 502 if (d_really_is_negative(dentry)) 503 return 0; 504 505 inode = d_inode(dentry); 506 if (!inode || is_bad_inode(inode)) 507 return 1; 508 509 cii = ITOC(inode); 510 if (cii->c_flags & C_PURGE) 511 return 1; 512 513 return 0; 514} 515 516 517 518/* 519 * This is called when we want to check if the inode has 520 * changed on the server. Coda makes this easy since the 521 * cache manager Venus issues a downcall to the kernel when this 522 * happens 523 */ 524int coda_revalidate_inode(struct inode *inode) 525{ 526 struct coda_vattr attr; 527 int error; 528 int old_mode; 529 ino_t old_ino; 530 struct coda_inode_info *cii = ITOC(inode); 531 532 if (!cii->c_flags) 533 return 0; 534 535 if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) { 536 error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr); 537 if (error) 538 return -EIO; 539 540 /* this inode may be lost if: 541 - it's ino changed 542 - type changes must be permitted for repair and 543 missing mount points. 544 */ 545 old_mode = inode->i_mode; 546 old_ino = inode->i_ino; 547 coda_vattr_to_iattr(inode, &attr); 548 549 if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) { 550 pr_warn("inode %ld, fid %s changed type!\n", 551 inode->i_ino, coda_f2s(&(cii->c_fid))); 552 } 553 554 /* the following can happen when a local fid is replaced 555 with a global one, here we lose and declare the inode bad */ 556 if (inode->i_ino != old_ino) 557 return -EIO; 558 559 coda_flag_inode_children(inode, C_FLUSH); 560 561 spin_lock(&cii->c_lock); 562 cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH); 563 spin_unlock(&cii->c_lock); 564 } 565 return 0; 566} 567 568const struct dentry_operations coda_dentry_operations = { 569 .d_revalidate = coda_dentry_revalidate, 570 .d_delete = coda_dentry_delete, 571}; 572 573const struct inode_operations coda_dir_inode_operations = { 574 .create = coda_create, 575 .lookup = coda_lookup, 576 .link = coda_link, 577 .unlink = coda_unlink, 578 .symlink = coda_symlink, 579 .mkdir = coda_mkdir, 580 .rmdir = coda_rmdir, 581 .mknod = CODA_EIO_ERROR, 582 .rename = coda_rename, 583 .permission = coda_permission, 584 .getattr = coda_getattr, 585 .setattr = coda_setattr, 586}; 587 588const struct file_operations coda_dir_operations = { 589 .llseek = generic_file_llseek, 590 .read = generic_read_dir, 591 .iterate = coda_readdir, 592 .open = coda_open, 593 .release = coda_release, 594 .fsync = coda_fsync, 595};