1 #include <linux/ceph/ceph_debug.h> 2 3 #include <linux/spinlock.h> 4 #include <linux/fs_struct.h> 5 #include <linux/namei.h> 6 #include <linux/slab.h> 7 #include <linux/sched.h> 8 9 #include "super.h" 10 #include "mds_client.h" 11 12 /* 13 * Directory operations: readdir, lookup, create, link, unlink, 14 * rename, etc. 15 */ 16 17 /* 18 * Ceph MDS operations are specified in terms of a base ino and 19 * relative path. Thus, the client can specify an operation on a 20 * specific inode (e.g., a getattr due to fstat(2)), or as a path 21 * relative to, say, the root directory. 22 * 23 * Normally, we limit ourselves to strict inode ops (no path component) 24 * or dentry operations (a single path component relative to an ino). The 25 * exception to this is open_root_dentry(), which will open the mount 26 * point by name. 27 */ 28 29 const struct inode_operations ceph_dir_iops; 30 const struct file_operations ceph_dir_fops; 31 const struct dentry_operations ceph_dentry_ops; 32 33 /* 34 * Initialize ceph dentry state. 35 */ 36 int ceph_init_dentry(struct dentry *dentry) 37 { 38 struct ceph_dentry_info *di; 39 40 if (dentry->d_fsdata) 41 return 0; 42 43 di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS | __GFP_ZERO); 44 if (!di) 45 return -ENOMEM; /* oh well */ 46 47 spin_lock(&dentry->d_lock); 48 if (dentry->d_fsdata) { 49 /* lost a race */ 50 kmem_cache_free(ceph_dentry_cachep, di); 51 goto out_unlock; 52 } 53 54 if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) 55 d_set_d_op(dentry, &ceph_dentry_ops); 56 else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR) 57 d_set_d_op(dentry, &ceph_snapdir_dentry_ops); 58 else 59 d_set_d_op(dentry, &ceph_snap_dentry_ops); 60 61 di->dentry = dentry; 62 di->lease_session = NULL; 63 dentry->d_time = jiffies; 64 /* avoid reordering d_fsdata setup so that the check above is safe */ 65 smp_mb(); 66 dentry->d_fsdata = di; 67 ceph_dentry_lru_add(dentry); 68 out_unlock: 69 spin_unlock(&dentry->d_lock); 70 return 0; 71 } 72 73 struct inode *ceph_get_dentry_parent_inode(struct dentry *dentry) 74 { 75 struct inode *inode = NULL; 76 77 if (!dentry) 78 return NULL; 79 80 spin_lock(&dentry->d_lock); 81 if (!IS_ROOT(dentry)) { 82 inode = dentry->d_parent->d_inode; 83 ihold(inode); 84 } 85 spin_unlock(&dentry->d_lock); 86 return inode; 87 } 88 89 90 /* 91 * for readdir, we encode the directory frag and offset within that 92 * frag into f_pos. 93 */ 94 static unsigned fpos_frag(loff_t p) 95 { 96 return p >> 32; 97 } 98 static unsigned fpos_off(loff_t p) 99 { 100 return p & 0xffffffff; 101 } 102 103 static int fpos_cmp(loff_t l, loff_t r) 104 { 105 int v = ceph_frag_compare(fpos_frag(l), fpos_frag(r)); 106 if (v) 107 return v; 108 return (int)(fpos_off(l) - fpos_off(r)); 109 } 110 111 /* 112 * When possible, we try to satisfy a readdir by peeking at the 113 * dcache. We make this work by carefully ordering dentries on 114 * d_child when we initially get results back from the MDS, and 115 * falling back to a "normal" sync readdir if any dentries in the dir 116 * are dropped. 117 * 118 * Complete dir indicates that we have all dentries in the dir. It is 119 * defined IFF we hold CEPH_CAP_FILE_SHARED (which will be revoked by 120 * the MDS if/when the directory is modified). 121 */ 122 static int __dcache_readdir(struct file *file, struct dir_context *ctx, 123 u32 shared_gen) 124 { 125 struct ceph_file_info *fi = file->private_data; 126 struct dentry *parent = file->f_path.dentry; 127 struct inode *dir = parent->d_inode; 128 struct list_head *p; 129 struct dentry *dentry, *last; 130 struct ceph_dentry_info *di; 131 int err = 0; 132 133 /* claim ref on last dentry we returned */ 134 last = fi->dentry; 135 fi->dentry = NULL; 136 137 dout("__dcache_readdir %p v%u at %llu (last %p)\n", 138 dir, shared_gen, ctx->pos, last); 139 140 spin_lock(&parent->d_lock); 141 142 /* start at beginning? */ 143 if (ctx->pos == 2 || last == NULL || 144 fpos_cmp(ctx->pos, ceph_dentry(last)->offset) < 0) { 145 if (list_empty(&parent->d_subdirs)) 146 goto out_unlock; 147 p = parent->d_subdirs.prev; 148 dout(" initial p %p/%p\n", p->prev, p->next); 149 } else { 150 p = last->d_child.prev; 151 } 152 153 more: 154 dentry = list_entry(p, struct dentry, d_child); 155 di = ceph_dentry(dentry); 156 while (1) { 157 dout(" p %p/%p %s d_subdirs %p/%p\n", p->prev, p->next, 158 d_unhashed(dentry) ? "!hashed" : "hashed", 159 parent->d_subdirs.prev, parent->d_subdirs.next); 160 if (p == &parent->d_subdirs) { 161 fi->flags |= CEPH_F_ATEND; 162 goto out_unlock; 163 } 164 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); 165 if (di->lease_shared_gen == shared_gen && 166 !d_unhashed(dentry) && dentry->d_inode && 167 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && 168 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && 169 fpos_cmp(ctx->pos, di->offset) <= 0) 170 break; 171 dout(" skipping %p %pd at %llu (%llu)%s%s\n", dentry, 172 dentry, di->offset, 173 ctx->pos, d_unhashed(dentry) ? " unhashed" : "", 174 !dentry->d_inode ? " null" : ""); 175 spin_unlock(&dentry->d_lock); 176 p = p->prev; 177 dentry = list_entry(p, struct dentry, d_child); 178 di = ceph_dentry(dentry); 179 } 180 181 dget_dlock(dentry); 182 spin_unlock(&dentry->d_lock); 183 spin_unlock(&parent->d_lock); 184 185 /* make sure a dentry wasn't dropped while we didn't have parent lock */ 186 if (!ceph_dir_is_complete_ordered(dir)) { 187 dout(" lost dir complete on %p; falling back to mds\n", dir); 188 dput(dentry); 189 err = -EAGAIN; 190 goto out; 191 } 192 193 dout(" %llu (%llu) dentry %p %pd %p\n", di->offset, ctx->pos, 194 dentry, dentry, dentry->d_inode); 195 if (!dir_emit(ctx, dentry->d_name.name, 196 dentry->d_name.len, 197 ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), 198 dentry->d_inode->i_mode >> 12)) { 199 if (last) { 200 /* remember our position */ 201 fi->dentry = last; 202 fi->next_offset = fpos_off(di->offset); 203 } 204 dput(dentry); 205 return 0; 206 } 207 208 ctx->pos = di->offset + 1; 209 210 if (last) 211 dput(last); 212 last = dentry; 213 214 spin_lock(&parent->d_lock); 215 p = p->prev; /* advance to next dentry */ 216 goto more; 217 218 out_unlock: 219 spin_unlock(&parent->d_lock); 220 out: 221 if (last) 222 dput(last); 223 return err; 224 } 225 226 /* 227 * make note of the last dentry we read, so we can 228 * continue at the same lexicographical point, 229 * regardless of what dir changes take place on the 230 * server. 231 */ 232 static int note_last_dentry(struct ceph_file_info *fi, const char *name, 233 int len) 234 { 235 kfree(fi->last_name); 236 fi->last_name = kmalloc(len+1, GFP_NOFS); 237 if (!fi->last_name) 238 return -ENOMEM; 239 memcpy(fi->last_name, name, len); 240 fi->last_name[len] = 0; 241 dout("note_last_dentry '%s'\n", fi->last_name); 242 return 0; 243 } 244 245 static int ceph_readdir(struct file *file, struct dir_context *ctx) 246 { 247 struct ceph_file_info *fi = file->private_data; 248 struct inode *inode = file_inode(file); 249 struct ceph_inode_info *ci = ceph_inode(inode); 250 struct ceph_fs_client *fsc = ceph_inode_to_client(inode); 251 struct ceph_mds_client *mdsc = fsc->mdsc; 252 unsigned frag = fpos_frag(ctx->pos); 253 int off = fpos_off(ctx->pos); 254 int err; 255 u32 ftype; 256 struct ceph_mds_reply_info_parsed *rinfo; 257 258 dout("readdir %p file %p frag %u off %u\n", inode, file, frag, off); 259 if (fi->flags & CEPH_F_ATEND) 260 return 0; 261 262 /* always start with . and .. */ 263 if (ctx->pos == 0) { 264 dout("readdir off 0 -> '.'\n"); 265 if (!dir_emit(ctx, ".", 1, 266 ceph_translate_ino(inode->i_sb, inode->i_ino), 267 inode->i_mode >> 12)) 268 return 0; 269 ctx->pos = 1; 270 off = 1; 271 } 272 if (ctx->pos == 1) { 273 ino_t ino = parent_ino(file->f_path.dentry); 274 dout("readdir off 1 -> '..'\n"); 275 if (!dir_emit(ctx, "..", 2, 276 ceph_translate_ino(inode->i_sb, ino), 277 inode->i_mode >> 12)) 278 return 0; 279 ctx->pos = 2; 280 off = 2; 281 } 282 283 /* can we use the dcache? */ 284 spin_lock(&ci->i_ceph_lock); 285 if ((ctx->pos == 2 || fi->dentry) && 286 !ceph_test_mount_opt(fsc, NOASYNCREADDIR) && 287 ceph_snap(inode) != CEPH_SNAPDIR && 288 __ceph_dir_is_complete_ordered(ci) && 289 __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) { 290 u32 shared_gen = ci->i_shared_gen; 291 spin_unlock(&ci->i_ceph_lock); 292 err = __dcache_readdir(file, ctx, shared_gen); 293 if (err != -EAGAIN) 294 return err; 295 frag = fpos_frag(ctx->pos); 296 off = fpos_off(ctx->pos); 297 } else { 298 spin_unlock(&ci->i_ceph_lock); 299 } 300 if (fi->dentry) { 301 err = note_last_dentry(fi, fi->dentry->d_name.name, 302 fi->dentry->d_name.len); 303 if (err) 304 return err; 305 dput(fi->dentry); 306 fi->dentry = NULL; 307 } 308 309 /* proceed with a normal readdir */ 310 311 if (ctx->pos == 2) { 312 /* note dir version at start of readdir so we can tell 313 * if any dentries get dropped */ 314 fi->dir_release_count = atomic_read(&ci->i_release_count); 315 fi->dir_ordered_count = ci->i_ordered_count; 316 } 317 318 more: 319 /* do we have the correct frag content buffered? */ 320 if (fi->frag != frag || fi->last_readdir == NULL) { 321 struct ceph_mds_request *req; 322 int op = ceph_snap(inode) == CEPH_SNAPDIR ? 323 CEPH_MDS_OP_LSSNAP : CEPH_MDS_OP_READDIR; 324 325 /* discard old result, if any */ 326 if (fi->last_readdir) { 327 ceph_mdsc_put_request(fi->last_readdir); 328 fi->last_readdir = NULL; 329 } 330 331 dout("readdir fetching %llx.%llx frag %x offset '%s'\n", 332 ceph_vinop(inode), frag, fi->last_name); 333 req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); 334 if (IS_ERR(req)) 335 return PTR_ERR(req); 336 err = ceph_alloc_readdir_reply_buffer(req, inode); 337 if (err) { 338 ceph_mdsc_put_request(req); 339 return err; 340 } 341 req->r_inode = inode; 342 ihold(inode); 343 req->r_dentry = dget(file->f_path.dentry); 344 /* hints to request -> mds selection code */ 345 req->r_direct_mode = USE_AUTH_MDS; 346 req->r_direct_hash = ceph_frag_value(frag); 347 req->r_direct_is_hash = true; 348 req->r_path2 = kstrdup(fi->last_name, GFP_NOFS); 349 req->r_readdir_offset = fi->next_offset; 350 req->r_args.readdir.frag = cpu_to_le32(frag); 351 err = ceph_mdsc_do_request(mdsc, NULL, req); 352 if (err < 0) { 353 ceph_mdsc_put_request(req); 354 return err; 355 } 356 dout("readdir got and parsed readdir result=%d" 357 " on frag %x, end=%d, complete=%d\n", err, frag, 358 (int)req->r_reply_info.dir_end, 359 (int)req->r_reply_info.dir_complete); 360 361 if (!req->r_did_prepopulate) { 362 dout("readdir !did_prepopulate"); 363 /* preclude from marking dir complete */ 364 fi->dir_release_count--; 365 } 366 367 /* note next offset and last dentry name */ 368 rinfo = &req->r_reply_info; 369 if (le32_to_cpu(rinfo->dir_dir->frag) != frag) { 370 frag = le32_to_cpu(rinfo->dir_dir->frag); 371 if (ceph_frag_is_leftmost(frag)) 372 fi->next_offset = 2; 373 else 374 fi->next_offset = 0; 375 off = fi->next_offset; 376 } 377 fi->frag = frag; 378 fi->offset = fi->next_offset; 379 fi->last_readdir = req; 380 381 if (req->r_reply_info.dir_end) { 382 kfree(fi->last_name); 383 fi->last_name = NULL; 384 if (ceph_frag_is_rightmost(frag)) 385 fi->next_offset = 2; 386 else 387 fi->next_offset = 0; 388 } else { 389 err = note_last_dentry(fi, 390 rinfo->dir_dname[rinfo->dir_nr-1], 391 rinfo->dir_dname_len[rinfo->dir_nr-1]); 392 if (err) 393 return err; 394 fi->next_offset += rinfo->dir_nr; 395 } 396 } 397 398 rinfo = &fi->last_readdir->r_reply_info; 399 dout("readdir frag %x num %d off %d chunkoff %d\n", frag, 400 rinfo->dir_nr, off, fi->offset); 401 402 ctx->pos = ceph_make_fpos(frag, off); 403 while (off >= fi->offset && off - fi->offset < rinfo->dir_nr) { 404 struct ceph_mds_reply_inode *in = 405 rinfo->dir_in[off - fi->offset].in; 406 struct ceph_vino vino; 407 ino_t ino; 408 409 dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n", 410 off, off - fi->offset, rinfo->dir_nr, ctx->pos, 411 rinfo->dir_dname_len[off - fi->offset], 412 rinfo->dir_dname[off - fi->offset], in); 413 BUG_ON(!in); 414 ftype = le32_to_cpu(in->mode) >> 12; 415 vino.ino = le64_to_cpu(in->ino); 416 vino.snap = le64_to_cpu(in->snapid); 417 ino = ceph_vino_to_ino(vino); 418 if (!dir_emit(ctx, 419 rinfo->dir_dname[off - fi->offset], 420 rinfo->dir_dname_len[off - fi->offset], 421 ceph_translate_ino(inode->i_sb, ino), ftype)) { 422 dout("filldir stopping us...\n"); 423 return 0; 424 } 425 off++; 426 ctx->pos++; 427 } 428 429 if (fi->last_name) { 430 ceph_mdsc_put_request(fi->last_readdir); 431 fi->last_readdir = NULL; 432 goto more; 433 } 434 435 /* more frags? */ 436 if (!ceph_frag_is_rightmost(frag)) { 437 frag = ceph_frag_next(frag); 438 off = 0; 439 ctx->pos = ceph_make_fpos(frag, off); 440 dout("readdir next frag is %x\n", frag); 441 goto more; 442 } 443 fi->flags |= CEPH_F_ATEND; 444 445 /* 446 * if dir_release_count still matches the dir, no dentries 447 * were released during the whole readdir, and we should have 448 * the complete dir contents in our cache. 449 */ 450 spin_lock(&ci->i_ceph_lock); 451 if (atomic_read(&ci->i_release_count) == fi->dir_release_count) { 452 if (ci->i_ordered_count == fi->dir_ordered_count) 453 dout(" marking %p complete and ordered\n", inode); 454 else 455 dout(" marking %p complete\n", inode); 456 __ceph_dir_set_complete(ci, fi->dir_release_count, 457 fi->dir_ordered_count); 458 } 459 spin_unlock(&ci->i_ceph_lock); 460 461 dout("readdir %p file %p done.\n", inode, file); 462 return 0; 463 } 464 465 static void reset_readdir(struct ceph_file_info *fi, unsigned frag) 466 { 467 if (fi->last_readdir) { 468 ceph_mdsc_put_request(fi->last_readdir); 469 fi->last_readdir = NULL; 470 } 471 kfree(fi->last_name); 472 fi->last_name = NULL; 473 if (ceph_frag_is_leftmost(frag)) 474 fi->next_offset = 2; /* compensate for . and .. */ 475 else 476 fi->next_offset = 0; 477 if (fi->dentry) { 478 dput(fi->dentry); 479 fi->dentry = NULL; 480 } 481 fi->flags &= ~CEPH_F_ATEND; 482 } 483 484 static loff_t ceph_dir_llseek(struct file *file, loff_t offset, int whence) 485 { 486 struct ceph_file_info *fi = file->private_data; 487 struct inode *inode = file->f_mapping->host; 488 loff_t old_offset = ceph_make_fpos(fi->frag, fi->next_offset); 489 loff_t retval; 490 491 mutex_lock(&inode->i_mutex); 492 retval = -EINVAL; 493 switch (whence) { 494 case SEEK_END: 495 offset += inode->i_size + 2; /* FIXME */ 496 break; 497 case SEEK_CUR: 498 offset += file->f_pos; 499 case SEEK_SET: 500 break; 501 default: 502 goto out; 503 } 504 505 if (offset >= 0) { 506 if (offset != file->f_pos) { 507 file->f_pos = offset; 508 file->f_version = 0; 509 fi->flags &= ~CEPH_F_ATEND; 510 } 511 retval = offset; 512 513 /* 514 * discard buffered readdir content on seekdir(0), or 515 * seek to new frag, or seek prior to current chunk. 516 */ 517 if (offset == 0 || 518 fpos_frag(offset) != fi->frag || 519 fpos_off(offset) < fi->offset) { 520 dout("dir_llseek dropping %p content\n", file); 521 reset_readdir(fi, fpos_frag(offset)); 522 } 523 524 /* bump dir_release_count if we did a forward seek */ 525 if (fpos_cmp(offset, old_offset) > 0) 526 fi->dir_release_count--; 527 } 528 out: 529 mutex_unlock(&inode->i_mutex); 530 return retval; 531 } 532 533 /* 534 * Handle lookups for the hidden .snap directory. 535 */ 536 int ceph_handle_snapdir(struct ceph_mds_request *req, 537 struct dentry *dentry, int err) 538 { 539 struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); 540 struct inode *parent = dentry->d_parent->d_inode; /* we hold i_mutex */ 541 542 /* .snap dir? */ 543 if (err == -ENOENT && 544 ceph_snap(parent) == CEPH_NOSNAP && 545 strcmp(dentry->d_name.name, 546 fsc->mount_options->snapdir_name) == 0) { 547 struct inode *inode = ceph_get_snapdir(parent); 548 dout("ENOENT on snapdir %p '%pd', linking to snapdir %p\n", 549 dentry, dentry, inode); 550 BUG_ON(!d_unhashed(dentry)); 551 d_add(dentry, inode); 552 err = 0; 553 } 554 return err; 555 } 556 557 /* 558 * Figure out final result of a lookup/open request. 559 * 560 * Mainly, make sure we return the final req->r_dentry (if it already 561 * existed) in place of the original VFS-provided dentry when they 562 * differ. 563 * 564 * Gracefully handle the case where the MDS replies with -ENOENT and 565 * no trace (which it may do, at its discretion, e.g., if it doesn't 566 * care to issue a lease on the negative dentry). 567 */ 568 struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, 569 struct dentry *dentry, int err) 570 { 571 if (err == -ENOENT) { 572 /* no trace? */ 573 err = 0; 574 if (!req->r_reply_info.head->is_dentry) { 575 dout("ENOENT and no trace, dentry %p inode %p\n", 576 dentry, dentry->d_inode); 577 if (dentry->d_inode) { 578 d_drop(dentry); 579 err = -ENOENT; 580 } else { 581 d_add(dentry, NULL); 582 } 583 } 584 } 585 if (err) 586 dentry = ERR_PTR(err); 587 else if (dentry != req->r_dentry) 588 dentry = dget(req->r_dentry); /* we got spliced */ 589 else 590 dentry = NULL; 591 return dentry; 592 } 593 594 static int is_root_ceph_dentry(struct inode *inode, struct dentry *dentry) 595 { 596 return ceph_ino(inode) == CEPH_INO_ROOT && 597 strncmp(dentry->d_name.name, ".ceph", 5) == 0; 598 } 599 600 /* 601 * Look up a single dir entry. If there is a lookup intent, inform 602 * the MDS so that it gets our 'caps wanted' value in a single op. 603 */ 604 static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, 605 unsigned int flags) 606 { 607 struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); 608 struct ceph_mds_client *mdsc = fsc->mdsc; 609 struct ceph_mds_request *req; 610 int op; 611 int err; 612 613 dout("lookup %p dentry %p '%pd'\n", 614 dir, dentry, dentry); 615 616 if (dentry->d_name.len > NAME_MAX) 617 return ERR_PTR(-ENAMETOOLONG); 618 619 err = ceph_init_dentry(dentry); 620 if (err < 0) 621 return ERR_PTR(err); 622 623 /* can we conclude ENOENT locally? */ 624 if (dentry->d_inode == NULL) { 625 struct ceph_inode_info *ci = ceph_inode(dir); 626 struct ceph_dentry_info *di = ceph_dentry(dentry); 627 628 spin_lock(&ci->i_ceph_lock); 629 dout(" dir %p flags are %d\n", dir, ci->i_ceph_flags); 630 if (strncmp(dentry->d_name.name, 631 fsc->mount_options->snapdir_name, 632 dentry->d_name.len) && 633 !is_root_ceph_dentry(dir, dentry) && 634 __ceph_dir_is_complete(ci) && 635 (__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1))) { 636 spin_unlock(&ci->i_ceph_lock); 637 dout(" dir %p complete, -ENOENT\n", dir); 638 d_add(dentry, NULL); 639 di->lease_shared_gen = ci->i_shared_gen; 640 return NULL; 641 } 642 spin_unlock(&ci->i_ceph_lock); 643 } 644 645 op = ceph_snap(dir) == CEPH_SNAPDIR ? 646 CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP; 647 req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS); 648 if (IS_ERR(req)) 649 return ERR_CAST(req); 650 req->r_dentry = dget(dentry); 651 req->r_num_caps = 2; 652 /* we only need inode linkage */ 653 req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); 654 req->r_locked_dir = dir; 655 err = ceph_mdsc_do_request(mdsc, NULL, req); 656 err = ceph_handle_snapdir(req, dentry, err); 657 dentry = ceph_finish_lookup(req, dentry, err); 658 ceph_mdsc_put_request(req); /* will dput(dentry) */ 659 dout("lookup result=%p\n", dentry); 660 return dentry; 661 } 662 663 /* 664 * If we do a create but get no trace back from the MDS, follow up with 665 * a lookup (the VFS expects us to link up the provided dentry). 666 */ 667 int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry) 668 { 669 struct dentry *result = ceph_lookup(dir, dentry, 0); 670 671 if (result && !IS_ERR(result)) { 672 /* 673 * We created the item, then did a lookup, and found 674 * it was already linked to another inode we already 675 * had in our cache (and thus got spliced). Link our 676 * dentry to that inode, but don't hash it, just in 677 * case the VFS wants to dereference it. 678 */ 679 BUG_ON(!result->d_inode); 680 d_instantiate(dentry, result->d_inode); 681 return 0; 682 } 683 return PTR_ERR(result); 684 } 685 686 static int ceph_mknod(struct inode *dir, struct dentry *dentry, 687 umode_t mode, dev_t rdev) 688 { 689 struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); 690 struct ceph_mds_client *mdsc = fsc->mdsc; 691 struct ceph_mds_request *req; 692 struct ceph_acls_info acls = {}; 693 int err; 694 695 if (ceph_snap(dir) != CEPH_NOSNAP) 696 return -EROFS; 697 698 err = ceph_pre_init_acls(dir, &mode, &acls); 699 if (err < 0) 700 return err; 701 702 dout("mknod in dir %p dentry %p mode 0%ho rdev %d\n", 703 dir, dentry, mode, rdev); 704 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, USE_AUTH_MDS); 705 if (IS_ERR(req)) { 706 err = PTR_ERR(req); 707 goto out; 708 } 709 req->r_dentry = dget(dentry); 710 req->r_num_caps = 2; 711 req->r_locked_dir = dir; 712 req->r_args.mknod.mode = cpu_to_le32(mode); 713 req->r_args.mknod.rdev = cpu_to_le32(rdev); 714 req->r_dentry_drop = CEPH_CAP_FILE_SHARED; 715 req->r_dentry_unless = CEPH_CAP_FILE_EXCL; 716 if (acls.pagelist) { 717 req->r_pagelist = acls.pagelist; 718 acls.pagelist = NULL; 719 } 720 err = ceph_mdsc_do_request(mdsc, dir, req); 721 if (!err && !req->r_reply_info.head->is_dentry) 722 err = ceph_handle_notrace_create(dir, dentry); 723 ceph_mdsc_put_request(req); 724 out: 725 if (!err) 726 ceph_init_inode_acls(dentry->d_inode, &acls); 727 else 728 d_drop(dentry); 729 ceph_release_acls_info(&acls); 730 return err; 731 } 732 733 static int ceph_create(struct inode *dir, struct dentry *dentry, umode_t mode, 734 bool excl) 735 { 736 return ceph_mknod(dir, dentry, mode, 0); 737 } 738 739 static int ceph_symlink(struct inode *dir, struct dentry *dentry, 740 const char *dest) 741 { 742 struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); 743 struct ceph_mds_client *mdsc = fsc->mdsc; 744 struct ceph_mds_request *req; 745 int err; 746 747 if (ceph_snap(dir) != CEPH_NOSNAP) 748 return -EROFS; 749 750 dout("symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest); 751 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS); 752 if (IS_ERR(req)) { 753 err = PTR_ERR(req); 754 goto out; 755 } 756 req->r_dentry = dget(dentry); 757 req->r_num_caps = 2; 758 req->r_path2 = kstrdup(dest, GFP_NOFS); 759 req->r_locked_dir = dir; 760 req->r_dentry_drop = CEPH_CAP_FILE_SHARED; 761 req->r_dentry_unless = CEPH_CAP_FILE_EXCL; 762 err = ceph_mdsc_do_request(mdsc, dir, req); 763 if (!err && !req->r_reply_info.head->is_dentry) 764 err = ceph_handle_notrace_create(dir, dentry); 765 ceph_mdsc_put_request(req); 766 out: 767 if (err) 768 d_drop(dentry); 769 return err; 770 } 771 772 static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 773 { 774 struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); 775 struct ceph_mds_client *mdsc = fsc->mdsc; 776 struct ceph_mds_request *req; 777 struct ceph_acls_info acls = {}; 778 int err = -EROFS; 779 int op; 780 781 if (ceph_snap(dir) == CEPH_SNAPDIR) { 782 /* mkdir .snap/foo is a MKSNAP */ 783 op = CEPH_MDS_OP_MKSNAP; 784 dout("mksnap dir %p snap '%pd' dn %p\n", dir, 785 dentry, dentry); 786 } else if (ceph_snap(dir) == CEPH_NOSNAP) { 787 dout("mkdir dir %p dn %p mode 0%ho\n", dir, dentry, mode); 788 op = CEPH_MDS_OP_MKDIR; 789 } else { 790 goto out; 791 } 792 793 mode |= S_IFDIR; 794 err = ceph_pre_init_acls(dir, &mode, &acls); 795 if (err < 0) 796 goto out; 797 798 req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); 799 if (IS_ERR(req)) { 800 err = PTR_ERR(req); 801 goto out; 802 } 803 804 req->r_dentry = dget(dentry); 805 req->r_num_caps = 2; 806 req->r_locked_dir = dir; 807 req->r_args.mkdir.mode = cpu_to_le32(mode); 808 req->r_dentry_drop = CEPH_CAP_FILE_SHARED; 809 req->r_dentry_unless = CEPH_CAP_FILE_EXCL; 810 if (acls.pagelist) { 811 req->r_pagelist = acls.pagelist; 812 acls.pagelist = NULL; 813 } 814 err = ceph_mdsc_do_request(mdsc, dir, req); 815 if (!err && 816 !req->r_reply_info.head->is_target && 817 !req->r_reply_info.head->is_dentry) 818 err = ceph_handle_notrace_create(dir, dentry); 819 ceph_mdsc_put_request(req); 820 out: 821 if (!err) 822 ceph_init_inode_acls(dentry->d_inode, &acls); 823 else 824 d_drop(dentry); 825 ceph_release_acls_info(&acls); 826 return err; 827 } 828 829 static int ceph_link(struct dentry *old_dentry, struct inode *dir, 830 struct dentry *dentry) 831 { 832 struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); 833 struct ceph_mds_client *mdsc = fsc->mdsc; 834 struct ceph_mds_request *req; 835 int err; 836 837 if (ceph_snap(dir) != CEPH_NOSNAP) 838 return -EROFS; 839 840 dout("link in dir %p old_dentry %p dentry %p\n", dir, 841 old_dentry, dentry); 842 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LINK, USE_AUTH_MDS); 843 if (IS_ERR(req)) { 844 d_drop(dentry); 845 return PTR_ERR(req); 846 } 847 req->r_dentry = dget(dentry); 848 req->r_num_caps = 2; 849 req->r_old_dentry = dget(old_dentry); 850 req->r_locked_dir = dir; 851 req->r_dentry_drop = CEPH_CAP_FILE_SHARED; 852 req->r_dentry_unless = CEPH_CAP_FILE_EXCL; 853 /* release LINK_SHARED on source inode (mds will lock it) */ 854 req->r_old_inode_drop = CEPH_CAP_LINK_SHARED; 855 err = ceph_mdsc_do_request(mdsc, dir, req); 856 if (err) { 857 d_drop(dentry); 858 } else if (!req->r_reply_info.head->is_dentry) { 859 ihold(old_dentry->d_inode); 860 d_instantiate(dentry, old_dentry->d_inode); 861 } 862 ceph_mdsc_put_request(req); 863 return err; 864 } 865 866 /* 867 * For a soon-to-be unlinked file, drop the AUTH_RDCACHE caps. If it 868 * looks like the link count will hit 0, drop any other caps (other 869 * than PIN) we don't specifically want (due to the file still being 870 * open). 871 */ 872 static int drop_caps_for_unlink(struct inode *inode) 873 { 874 struct ceph_inode_info *ci = ceph_inode(inode); 875 int drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL; 876 877 spin_lock(&ci->i_ceph_lock); 878 if (inode->i_nlink == 1) { 879 drop |= ~(__ceph_caps_wanted(ci) | CEPH_CAP_PIN); 880 ci->i_ceph_flags |= CEPH_I_NODELAY; 881 } 882 spin_unlock(&ci->i_ceph_lock); 883 return drop; 884 } 885 886 /* 887 * rmdir and unlink are differ only by the metadata op code 888 */ 889 static int ceph_unlink(struct inode *dir, struct dentry *dentry) 890 { 891 struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); 892 struct ceph_mds_client *mdsc = fsc->mdsc; 893 struct inode *inode = dentry->d_inode; 894 struct ceph_mds_request *req; 895 int err = -EROFS; 896 int op; 897 898 if (ceph_snap(dir) == CEPH_SNAPDIR) { 899 /* rmdir .snap/foo is RMSNAP */ 900 dout("rmsnap dir %p '%pd' dn %p\n", dir, dentry, dentry); 901 op = CEPH_MDS_OP_RMSNAP; 902 } else if (ceph_snap(dir) == CEPH_NOSNAP) { 903 dout("unlink/rmdir dir %p dn %p inode %p\n", 904 dir, dentry, inode); 905 op = S_ISDIR(dentry->d_inode->i_mode) ? 906 CEPH_MDS_OP_RMDIR : CEPH_MDS_OP_UNLINK; 907 } else 908 goto out; 909 req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); 910 if (IS_ERR(req)) { 911 err = PTR_ERR(req); 912 goto out; 913 } 914 req->r_dentry = dget(dentry); 915 req->r_num_caps = 2; 916 req->r_locked_dir = dir; 917 req->r_dentry_drop = CEPH_CAP_FILE_SHARED; 918 req->r_dentry_unless = CEPH_CAP_FILE_EXCL; 919 req->r_inode_drop = drop_caps_for_unlink(inode); 920 err = ceph_mdsc_do_request(mdsc, dir, req); 921 if (!err && !req->r_reply_info.head->is_dentry) 922 d_delete(dentry); 923 ceph_mdsc_put_request(req); 924 out: 925 return err; 926 } 927 928 static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry, 929 struct inode *new_dir, struct dentry *new_dentry) 930 { 931 struct ceph_fs_client *fsc = ceph_sb_to_client(old_dir->i_sb); 932 struct ceph_mds_client *mdsc = fsc->mdsc; 933 struct ceph_mds_request *req; 934 int err; 935 936 if (ceph_snap(old_dir) != ceph_snap(new_dir)) 937 return -EXDEV; 938 if (ceph_snap(old_dir) != CEPH_NOSNAP || 939 ceph_snap(new_dir) != CEPH_NOSNAP) 940 return -EROFS; 941 dout("rename dir %p dentry %p to dir %p dentry %p\n", 942 old_dir, old_dentry, new_dir, new_dentry); 943 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, USE_AUTH_MDS); 944 if (IS_ERR(req)) 945 return PTR_ERR(req); 946 ihold(old_dir); 947 req->r_dentry = dget(new_dentry); 948 req->r_num_caps = 2; 949 req->r_old_dentry = dget(old_dentry); 950 req->r_old_dentry_dir = old_dir; 951 req->r_locked_dir = new_dir; 952 req->r_old_dentry_drop = CEPH_CAP_FILE_SHARED; 953 req->r_old_dentry_unless = CEPH_CAP_FILE_EXCL; 954 req->r_dentry_drop = CEPH_CAP_FILE_SHARED; 955 req->r_dentry_unless = CEPH_CAP_FILE_EXCL; 956 /* release LINK_RDCACHE on source inode (mds will lock it) */ 957 req->r_old_inode_drop = CEPH_CAP_LINK_SHARED; 958 if (new_dentry->d_inode) 959 req->r_inode_drop = drop_caps_for_unlink(new_dentry->d_inode); 960 err = ceph_mdsc_do_request(mdsc, old_dir, req); 961 if (!err && !req->r_reply_info.head->is_dentry) { 962 /* 963 * Normally d_move() is done by fill_trace (called by 964 * do_request, above). If there is no trace, we need 965 * to do it here. 966 */ 967 968 d_move(old_dentry, new_dentry); 969 970 /* ensure target dentry is invalidated, despite 971 rehashing bug in vfs_rename_dir */ 972 ceph_invalidate_dentry_lease(new_dentry); 973 974 /* d_move screws up sibling dentries' offsets */ 975 ceph_dir_clear_complete(old_dir); 976 ceph_dir_clear_complete(new_dir); 977 978 } 979 ceph_mdsc_put_request(req); 980 return err; 981 } 982 983 /* 984 * Ensure a dentry lease will no longer revalidate. 985 */ 986 void ceph_invalidate_dentry_lease(struct dentry *dentry) 987 { 988 spin_lock(&dentry->d_lock); 989 dentry->d_time = jiffies; 990 ceph_dentry(dentry)->lease_shared_gen = 0; 991 spin_unlock(&dentry->d_lock); 992 } 993 994 /* 995 * Check if dentry lease is valid. If not, delete the lease. Try to 996 * renew if the least is more than half up. 997 */ 998 static int dentry_lease_is_valid(struct dentry *dentry) 999 { 1000 struct ceph_dentry_info *di; 1001 struct ceph_mds_session *s; 1002 int valid = 0; 1003 u32 gen; 1004 unsigned long ttl; 1005 struct ceph_mds_session *session = NULL; 1006 struct inode *dir = NULL; 1007 u32 seq = 0; 1008 1009 spin_lock(&dentry->d_lock); 1010 di = ceph_dentry(dentry); 1011 if (di->lease_session) { 1012 s = di->lease_session; 1013 spin_lock(&s->s_gen_ttl_lock); 1014 gen = s->s_cap_gen; 1015 ttl = s->s_cap_ttl; 1016 spin_unlock(&s->s_gen_ttl_lock); 1017 1018 if (di->lease_gen == gen && 1019 time_before(jiffies, dentry->d_time) && 1020 time_before(jiffies, ttl)) { 1021 valid = 1; 1022 if (di->lease_renew_after && 1023 time_after(jiffies, di->lease_renew_after)) { 1024 /* we should renew */ 1025 dir = dentry->d_parent->d_inode; 1026 session = ceph_get_mds_session(s); 1027 seq = di->lease_seq; 1028 di->lease_renew_after = 0; 1029 di->lease_renew_from = jiffies; 1030 } 1031 } 1032 } 1033 spin_unlock(&dentry->d_lock); 1034 1035 if (session) { 1036 ceph_mdsc_lease_send_msg(session, dir, dentry, 1037 CEPH_MDS_LEASE_RENEW, seq); 1038 ceph_put_mds_session(session); 1039 } 1040 dout("dentry_lease_is_valid - dentry %p = %d\n", dentry, valid); 1041 return valid; 1042 } 1043 1044 /* 1045 * Check if directory-wide content lease/cap is valid. 1046 */ 1047 static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry) 1048 { 1049 struct ceph_inode_info *ci = ceph_inode(dir); 1050 struct ceph_dentry_info *di = ceph_dentry(dentry); 1051 int valid = 0; 1052 1053 spin_lock(&ci->i_ceph_lock); 1054 if (ci->i_shared_gen == di->lease_shared_gen) 1055 valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1); 1056 spin_unlock(&ci->i_ceph_lock); 1057 dout("dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n", 1058 dir, (unsigned)ci->i_shared_gen, dentry, 1059 (unsigned)di->lease_shared_gen, valid); 1060 return valid; 1061 } 1062 1063 /* 1064 * Check if cached dentry can be trusted. 1065 */ 1066 static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) 1067 { 1068 int valid = 0; 1069 struct inode *dir; 1070 1071 if (flags & LOOKUP_RCU) 1072 return -ECHILD; 1073 1074 dout("d_revalidate %p '%pd' inode %p offset %lld\n", dentry, 1075 dentry, dentry->d_inode, ceph_dentry(dentry)->offset); 1076 1077 dir = ceph_get_dentry_parent_inode(dentry); 1078 1079 /* always trust cached snapped dentries, snapdir dentry */ 1080 if (ceph_snap(dir) != CEPH_NOSNAP) { 1081 dout("d_revalidate %p '%pd' inode %p is SNAPPED\n", dentry, 1082 dentry, dentry->d_inode); 1083 valid = 1; 1084 } else if (dentry->d_inode && 1085 ceph_snap(dentry->d_inode) == CEPH_SNAPDIR) { 1086 valid = 1; 1087 } else if (dentry_lease_is_valid(dentry) || 1088 dir_lease_is_valid(dir, dentry)) { 1089 if (dentry->d_inode) 1090 valid = ceph_is_any_caps(dentry->d_inode); 1091 else 1092 valid = 1; 1093 } 1094 1095 dout("d_revalidate %p %s\n", dentry, valid ? "valid" : "invalid"); 1096 if (valid) { 1097 ceph_dentry_lru_touch(dentry); 1098 } else { 1099 ceph_dir_clear_complete(dir); 1100 } 1101 iput(dir); 1102 return valid; 1103 } 1104 1105 /* 1106 * Release our ceph_dentry_info. 1107 */ 1108 static void ceph_d_release(struct dentry *dentry) 1109 { 1110 struct ceph_dentry_info *di = ceph_dentry(dentry); 1111 1112 dout("d_release %p\n", dentry); 1113 ceph_dentry_lru_del(dentry); 1114 if (di->lease_session) 1115 ceph_put_mds_session(di->lease_session); 1116 kmem_cache_free(ceph_dentry_cachep, di); 1117 dentry->d_fsdata = NULL; 1118 } 1119 1120 static int ceph_snapdir_d_revalidate(struct dentry *dentry, 1121 unsigned int flags) 1122 { 1123 /* 1124 * Eventually, we'll want to revalidate snapped metadata 1125 * too... probably... 1126 */ 1127 return 1; 1128 } 1129 1130 /* 1131 * When the VFS prunes a dentry from the cache, we need to clear the 1132 * complete flag on the parent directory. 1133 * 1134 * Called under dentry->d_lock. 1135 */ 1136 static void ceph_d_prune(struct dentry *dentry) 1137 { 1138 dout("ceph_d_prune %p\n", dentry); 1139 1140 /* do we have a valid parent? */ 1141 if (IS_ROOT(dentry)) 1142 return; 1143 1144 /* if we are not hashed, we don't affect dir's completeness */ 1145 if (d_unhashed(dentry)) 1146 return; 1147 1148 /* 1149 * we hold d_lock, so d_parent is stable, and d_fsdata is never 1150 * cleared until d_release 1151 */ 1152 ceph_dir_clear_complete(dentry->d_parent->d_inode); 1153 } 1154 1155 /* 1156 * read() on a dir. This weird interface hack only works if mounted 1157 * with '-o dirstat'. 1158 */ 1159 static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size, 1160 loff_t *ppos) 1161 { 1162 struct ceph_file_info *cf = file->private_data; 1163 struct inode *inode = file_inode(file); 1164 struct ceph_inode_info *ci = ceph_inode(inode); 1165 int left; 1166 const int bufsize = 1024; 1167 1168 if (!ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb), DIRSTAT)) 1169 return -EISDIR; 1170 1171 if (!cf->dir_info) { 1172 cf->dir_info = kmalloc(bufsize, GFP_NOFS); 1173 if (!cf->dir_info) 1174 return -ENOMEM; 1175 cf->dir_info_len = 1176 snprintf(cf->dir_info, bufsize, 1177 "entries: %20lld\n" 1178 " files: %20lld\n" 1179 " subdirs: %20lld\n" 1180 "rentries: %20lld\n" 1181 " rfiles: %20lld\n" 1182 " rsubdirs: %20lld\n" 1183 "rbytes: %20lld\n" 1184 "rctime: %10ld.%09ld\n", 1185 ci->i_files + ci->i_subdirs, 1186 ci->i_files, 1187 ci->i_subdirs, 1188 ci->i_rfiles + ci->i_rsubdirs, 1189 ci->i_rfiles, 1190 ci->i_rsubdirs, 1191 ci->i_rbytes, 1192 (long)ci->i_rctime.tv_sec, 1193 (long)ci->i_rctime.tv_nsec); 1194 } 1195 1196 if (*ppos >= cf->dir_info_len) 1197 return 0; 1198 size = min_t(unsigned, size, cf->dir_info_len-*ppos); 1199 left = copy_to_user(buf, cf->dir_info + *ppos, size); 1200 if (left == size) 1201 return -EFAULT; 1202 *ppos += (size - left); 1203 return size - left; 1204 } 1205 1206 /* 1207 * an fsync() on a dir will wait for any uncommitted directory 1208 * operations to commit. 1209 */ 1210 static int ceph_dir_fsync(struct file *file, loff_t start, loff_t end, 1211 int datasync) 1212 { 1213 struct inode *inode = file_inode(file); 1214 struct ceph_inode_info *ci = ceph_inode(inode); 1215 struct list_head *head = &ci->i_unsafe_dirops; 1216 struct ceph_mds_request *req; 1217 u64 last_tid; 1218 int ret = 0; 1219 1220 dout("dir_fsync %p\n", inode); 1221 ret = filemap_write_and_wait_range(inode->i_mapping, start, end); 1222 if (ret) 1223 return ret; 1224 mutex_lock(&inode->i_mutex); 1225 1226 spin_lock(&ci->i_unsafe_lock); 1227 if (list_empty(head)) 1228 goto out; 1229 1230 req = list_entry(head->prev, 1231 struct ceph_mds_request, r_unsafe_dir_item); 1232 last_tid = req->r_tid; 1233 1234 do { 1235 ceph_mdsc_get_request(req); 1236 spin_unlock(&ci->i_unsafe_lock); 1237 1238 dout("dir_fsync %p wait on tid %llu (until %llu)\n", 1239 inode, req->r_tid, last_tid); 1240 if (req->r_timeout) { 1241 ret = wait_for_completion_timeout( 1242 &req->r_safe_completion, req->r_timeout); 1243 if (ret > 0) 1244 ret = 0; 1245 else if (ret == 0) 1246 ret = -EIO; /* timed out */ 1247 } else { 1248 wait_for_completion(&req->r_safe_completion); 1249 } 1250 ceph_mdsc_put_request(req); 1251 1252 spin_lock(&ci->i_unsafe_lock); 1253 if (ret || list_empty(head)) 1254 break; 1255 req = list_entry(head->next, 1256 struct ceph_mds_request, r_unsafe_dir_item); 1257 } while (req->r_tid < last_tid); 1258 out: 1259 spin_unlock(&ci->i_unsafe_lock); 1260 mutex_unlock(&inode->i_mutex); 1261 1262 return ret; 1263 } 1264 1265 /* 1266 * We maintain a private dentry LRU. 1267 * 1268 * FIXME: this needs to be changed to a per-mds lru to be useful. 1269 */ 1270 void ceph_dentry_lru_add(struct dentry *dn) 1271 { 1272 struct ceph_dentry_info *di = ceph_dentry(dn); 1273 struct ceph_mds_client *mdsc; 1274 1275 dout("dentry_lru_add %p %p '%pd'\n", di, dn, dn); 1276 mdsc = ceph_sb_to_client(dn->d_sb)->mdsc; 1277 spin_lock(&mdsc->dentry_lru_lock); 1278 list_add_tail(&di->lru, &mdsc->dentry_lru); 1279 mdsc->num_dentry++; 1280 spin_unlock(&mdsc->dentry_lru_lock); 1281 } 1282 1283 void ceph_dentry_lru_touch(struct dentry *dn) 1284 { 1285 struct ceph_dentry_info *di = ceph_dentry(dn); 1286 struct ceph_mds_client *mdsc; 1287 1288 dout("dentry_lru_touch %p %p '%pd' (offset %lld)\n", di, dn, dn, 1289 di->offset); 1290 mdsc = ceph_sb_to_client(dn->d_sb)->mdsc; 1291 spin_lock(&mdsc->dentry_lru_lock); 1292 list_move_tail(&di->lru, &mdsc->dentry_lru); 1293 spin_unlock(&mdsc->dentry_lru_lock); 1294 } 1295 1296 void ceph_dentry_lru_del(struct dentry *dn) 1297 { 1298 struct ceph_dentry_info *di = ceph_dentry(dn); 1299 struct ceph_mds_client *mdsc; 1300 1301 dout("dentry_lru_del %p %p '%pd'\n", di, dn, dn); 1302 mdsc = ceph_sb_to_client(dn->d_sb)->mdsc; 1303 spin_lock(&mdsc->dentry_lru_lock); 1304 list_del_init(&di->lru); 1305 mdsc->num_dentry--; 1306 spin_unlock(&mdsc->dentry_lru_lock); 1307 } 1308 1309 /* 1310 * Return name hash for a given dentry. This is dependent on 1311 * the parent directory's hash function. 1312 */ 1313 unsigned ceph_dentry_hash(struct inode *dir, struct dentry *dn) 1314 { 1315 struct ceph_inode_info *dci = ceph_inode(dir); 1316 1317 switch (dci->i_dir_layout.dl_dir_hash) { 1318 case 0: /* for backward compat */ 1319 case CEPH_STR_HASH_LINUX: 1320 return dn->d_name.hash; 1321 1322 default: 1323 return ceph_str_hash(dci->i_dir_layout.dl_dir_hash, 1324 dn->d_name.name, dn->d_name.len); 1325 } 1326 } 1327 1328 const struct file_operations ceph_dir_fops = { 1329 .read = ceph_read_dir, 1330 .iterate = ceph_readdir, 1331 .llseek = ceph_dir_llseek, 1332 .open = ceph_open, 1333 .release = ceph_release, 1334 .unlocked_ioctl = ceph_ioctl, 1335 .fsync = ceph_dir_fsync, 1336 }; 1337 1338 const struct inode_operations ceph_dir_iops = { 1339 .lookup = ceph_lookup, 1340 .permission = ceph_permission, 1341 .getattr = ceph_getattr, 1342 .setattr = ceph_setattr, 1343 .setxattr = ceph_setxattr, 1344 .getxattr = ceph_getxattr, 1345 .listxattr = ceph_listxattr, 1346 .removexattr = ceph_removexattr, 1347 .get_acl = ceph_get_acl, 1348 .set_acl = ceph_set_acl, 1349 .mknod = ceph_mknod, 1350 .symlink = ceph_symlink, 1351 .mkdir = ceph_mkdir, 1352 .link = ceph_link, 1353 .unlink = ceph_unlink, 1354 .rmdir = ceph_unlink, 1355 .rename = ceph_rename, 1356 .create = ceph_create, 1357 .atomic_open = ceph_atomic_open, 1358 }; 1359 1360 const struct dentry_operations ceph_dentry_ops = { 1361 .d_revalidate = ceph_d_revalidate, 1362 .d_release = ceph_d_release, 1363 .d_prune = ceph_d_prune, 1364 }; 1365 1366 const struct dentry_operations ceph_snapdir_dentry_ops = { 1367 .d_revalidate = ceph_snapdir_d_revalidate, 1368 .d_release = ceph_d_release, 1369 }; 1370 1371 const struct dentry_operations ceph_snap_dentry_ops = { 1372 .d_release = ceph_d_release, 1373 .d_prune = ceph_d_prune, 1374 }; 1375