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