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