aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ceph/caps.c58
-rw-r--r--fs/ceph/inode.c70
-rw-r--r--include/linux/ceph/ceph_fs.h2
3 files changed, 73 insertions, 57 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index de39a03f5b71..5f6d24ede794 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2476,7 +2476,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2476 2476
2477 __check_cap_issue(ci, cap, newcaps); 2477 __check_cap_issue(ci, cap, newcaps);
2478 2478
2479 if ((issued & CEPH_CAP_AUTH_EXCL) == 0) { 2479 if ((newcaps & CEPH_CAP_AUTH_SHARED) &&
2480 (issued & CEPH_CAP_AUTH_EXCL) == 0) {
2480 inode->i_mode = le32_to_cpu(grant->mode); 2481 inode->i_mode = le32_to_cpu(grant->mode);
2481 inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid)); 2482 inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid));
2482 inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid)); 2483 inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid));
@@ -2485,7 +2486,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2485 from_kgid(&init_user_ns, inode->i_gid)); 2486 from_kgid(&init_user_ns, inode->i_gid));
2486 } 2487 }
2487 2488
2488 if ((issued & CEPH_CAP_LINK_EXCL) == 0) { 2489 if ((newcaps & CEPH_CAP_AUTH_SHARED) &&
2490 (issued & CEPH_CAP_LINK_EXCL) == 0) {
2489 set_nlink(inode, le32_to_cpu(grant->nlink)); 2491 set_nlink(inode, le32_to_cpu(grant->nlink));
2490 if (inode->i_nlink == 0 && 2492 if (inode->i_nlink == 0 &&
2491 (newcaps & (CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL))) 2493 (newcaps & (CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL)))
@@ -2512,31 +2514,35 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2512 if ((issued & CEPH_CAP_FILE_CACHE) && ci->i_rdcache_gen > 1) 2514 if ((issued & CEPH_CAP_FILE_CACHE) && ci->i_rdcache_gen > 1)
2513 queue_revalidate = 1; 2515 queue_revalidate = 1;
2514 2516
2515 /* size/ctime/mtime/atime? */ 2517 if (newcaps & CEPH_CAP_ANY_RD) {
2516 queue_trunc = ceph_fill_file_size(inode, issued, 2518 /* ctime/mtime/atime? */
2517 le32_to_cpu(grant->truncate_seq), 2519 ceph_decode_timespec(&mtime, &grant->mtime);
2518 le64_to_cpu(grant->truncate_size), 2520 ceph_decode_timespec(&atime, &grant->atime);
2519 size); 2521 ceph_decode_timespec(&ctime, &grant->ctime);
2520 ceph_decode_timespec(&mtime, &grant->mtime); 2522 ceph_fill_file_time(inode, issued,
2521 ceph_decode_timespec(&atime, &grant->atime); 2523 le32_to_cpu(grant->time_warp_seq),
2522 ceph_decode_timespec(&ctime, &grant->ctime); 2524 &ctime, &mtime, &atime);
2523 ceph_fill_file_time(inode, issued, 2525 }
2524 le32_to_cpu(grant->time_warp_seq), &ctime, &mtime, 2526
2525 &atime); 2527 if (newcaps & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR)) {
2526 2528 /* file layout may have changed */
2527 2529 ci->i_layout = grant->layout;
2528 /* file layout may have changed */ 2530 /* size/truncate_seq? */
2529 ci->i_layout = grant->layout; 2531 queue_trunc = ceph_fill_file_size(inode, issued,
2530 2532 le32_to_cpu(grant->truncate_seq),
2531 /* max size increase? */ 2533 le64_to_cpu(grant->truncate_size),
2532 if (ci->i_auth_cap == cap && max_size != ci->i_max_size) { 2534 size);
2533 dout("max_size %lld -> %llu\n", ci->i_max_size, max_size); 2535 /* max size increase? */
2534 ci->i_max_size = max_size; 2536 if (ci->i_auth_cap == cap && max_size != ci->i_max_size) {
2535 if (max_size >= ci->i_wanted_max_size) { 2537 dout("max_size %lld -> %llu\n",
2536 ci->i_wanted_max_size = 0; /* reset */ 2538 ci->i_max_size, max_size);
2537 ci->i_requested_max_size = 0; 2539 ci->i_max_size = max_size;
2540 if (max_size >= ci->i_wanted_max_size) {
2541 ci->i_wanted_max_size = 0; /* reset */
2542 ci->i_requested_max_size = 0;
2543 }
2544 wake = 1;
2538 } 2545 }
2539 wake = 1;
2540 } 2546 }
2541 2547
2542 /* check cap bits */ 2548 /* check cap bits */
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 233c6f96910a..f9e7399877d6 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -585,14 +585,15 @@ static int fill_inode(struct inode *inode,
585 struct ceph_mds_reply_inode *info = iinfo->in; 585 struct ceph_mds_reply_inode *info = iinfo->in;
586 struct ceph_inode_info *ci = ceph_inode(inode); 586 struct ceph_inode_info *ci = ceph_inode(inode);
587 int i; 587 int i;
588 int issued = 0, implemented; 588 int issued = 0, implemented, new_issued;
589 struct timespec mtime, atime, ctime; 589 struct timespec mtime, atime, ctime;
590 u32 nsplits; 590 u32 nsplits;
591 struct ceph_inode_frag *frag; 591 struct ceph_inode_frag *frag;
592 struct rb_node *rb_node; 592 struct rb_node *rb_node;
593 struct ceph_buffer *xattr_blob = NULL; 593 struct ceph_buffer *xattr_blob = NULL;
594 int err = 0; 594 int err = 0;
595 int queue_trunc = 0; 595 bool queue_trunc = false;
596 bool new_version = false;
596 597
597 dout("fill_inode %p ino %llx.%llx v %llu had %llu\n", 598 dout("fill_inode %p ino %llx.%llx v %llu had %llu\n",
598 inode, ceph_vinop(inode), le64_to_cpu(info->version), 599 inode, ceph_vinop(inode), le64_to_cpu(info->version),
@@ -623,19 +624,23 @@ static int fill_inode(struct inode *inode,
623 * 3 2 skip 624 * 3 2 skip
624 * 3 3 update 625 * 3 3 update
625 */ 626 */
626 if (le64_to_cpu(info->version) > 0 && 627 if (ci->i_version == 0 ||
627 (ci->i_version & ~1) >= le64_to_cpu(info->version)) 628 ((info->cap.flags & CEPH_CAP_FLAG_AUTH) &&
628 goto no_change; 629 le64_to_cpu(info->version) > (ci->i_version & ~1)))
629 630 new_version = true;
631
630 issued = __ceph_caps_issued(ci, &implemented); 632 issued = __ceph_caps_issued(ci, &implemented);
631 issued |= implemented | __ceph_caps_dirty(ci); 633 issued |= implemented | __ceph_caps_dirty(ci);
634 new_issued = ~issued & le32_to_cpu(info->cap.caps);
632 635
633 /* update inode */ 636 /* update inode */
634 ci->i_version = le64_to_cpu(info->version); 637 ci->i_version = le64_to_cpu(info->version);
635 inode->i_version++; 638 inode->i_version++;
636 inode->i_rdev = le32_to_cpu(info->rdev); 639 inode->i_rdev = le32_to_cpu(info->rdev);
640 inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
637 641
638 if ((issued & CEPH_CAP_AUTH_EXCL) == 0) { 642 if ((new_version || (new_issued & CEPH_CAP_AUTH_SHARED)) &&
643 (issued & CEPH_CAP_AUTH_EXCL) == 0) {
639 inode->i_mode = le32_to_cpu(info->mode); 644 inode->i_mode = le32_to_cpu(info->mode);
640 inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(info->uid)); 645 inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(info->uid));
641 inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(info->gid)); 646 inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(info->gid));
@@ -644,23 +649,35 @@ static int fill_inode(struct inode *inode,
644 from_kgid(&init_user_ns, inode->i_gid)); 649 from_kgid(&init_user_ns, inode->i_gid));
645 } 650 }
646 651
647 if ((issued & CEPH_CAP_LINK_EXCL) == 0) 652 if ((new_version || (new_issued & CEPH_CAP_LINK_SHARED)) &&
653 (issued & CEPH_CAP_LINK_EXCL) == 0)
648 set_nlink(inode, le32_to_cpu(info->nlink)); 654 set_nlink(inode, le32_to_cpu(info->nlink));
649 655
650 /* be careful with mtime, atime, size */ 656 if (new_version || (new_issued & CEPH_CAP_ANY_RD)) {
651 ceph_decode_timespec(&atime, &info->atime); 657 /* be careful with mtime, atime, size */
652 ceph_decode_timespec(&mtime, &info->mtime); 658 ceph_decode_timespec(&atime, &info->atime);
653 ceph_decode_timespec(&ctime, &info->ctime); 659 ceph_decode_timespec(&mtime, &info->mtime);
654 queue_trunc = ceph_fill_file_size(inode, issued, 660 ceph_decode_timespec(&ctime, &info->ctime);
655 le32_to_cpu(info->truncate_seq), 661 ceph_fill_file_time(inode, issued,
656 le64_to_cpu(info->truncate_size), 662 le32_to_cpu(info->time_warp_seq),
657 le64_to_cpu(info->size)); 663 &ctime, &mtime, &atime);
658 ceph_fill_file_time(inode, issued, 664 }
659 le32_to_cpu(info->time_warp_seq), 665
660 &ctime, &mtime, &atime); 666 if (new_version ||
661 667 (new_issued & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR))) {
662 ci->i_layout = info->layout; 668 ci->i_layout = info->layout;
663 inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1; 669 queue_trunc = ceph_fill_file_size(inode, issued,
670 le32_to_cpu(info->truncate_seq),
671 le64_to_cpu(info->truncate_size),
672 le64_to_cpu(info->size));
673 /* only update max_size on auth cap */
674 if ((info->cap.flags & CEPH_CAP_FLAG_AUTH) &&
675 ci->i_max_size != le64_to_cpu(info->max_size)) {
676 dout("max_size %lld -> %llu\n", ci->i_max_size,
677 le64_to_cpu(info->max_size));
678 ci->i_max_size = le64_to_cpu(info->max_size);
679 }
680 }
664 681
665 /* xattrs */ 682 /* xattrs */
666 /* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */ 683 /* note that if i_xattrs.len <= 4, i_xattrs.data will still be NULL. */
@@ -745,15 +762,6 @@ static int fill_inode(struct inode *inode,
745 dout(" marking %p complete (empty)\n", inode); 762 dout(" marking %p complete (empty)\n", inode);
746 __ceph_dir_set_complete(ci, atomic_read(&ci->i_release_count)); 763 __ceph_dir_set_complete(ci, atomic_read(&ci->i_release_count));
747 } 764 }
748no_change:
749 /* only update max_size on auth cap */
750 if ((info->cap.flags & CEPH_CAP_FLAG_AUTH) &&
751 ci->i_max_size != le64_to_cpu(info->max_size)) {
752 dout("max_size %lld -> %llu\n", ci->i_max_size,
753 le64_to_cpu(info->max_size));
754 ci->i_max_size = le64_to_cpu(info->max_size);
755 }
756
757 spin_unlock(&ci->i_ceph_lock); 765 spin_unlock(&ci->i_ceph_lock);
758 766
759 /* queue truncate if we saw i_size decrease */ 767 /* queue truncate if we saw i_size decrease */
diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h
index 5f6db18d72e8..3c97d5e9b951 100644
--- a/include/linux/ceph/ceph_fs.h
+++ b/include/linux/ceph/ceph_fs.h
@@ -625,6 +625,8 @@ int ceph_flags_to_mode(int flags);
625 CEPH_CAP_LINK_EXCL | \ 625 CEPH_CAP_LINK_EXCL | \
626 CEPH_CAP_XATTR_EXCL | \ 626 CEPH_CAP_XATTR_EXCL | \
627 CEPH_CAP_FILE_EXCL) 627 CEPH_CAP_FILE_EXCL)
628#define CEPH_CAP_ANY_FILE_RD (CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE | \
629 CEPH_CAP_FILE_SHARED)
628#define CEPH_CAP_ANY_FILE_WR (CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER | \ 630#define CEPH_CAP_ANY_FILE_WR (CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER | \
629 CEPH_CAP_FILE_EXCL) 631 CEPH_CAP_FILE_EXCL)
630#define CEPH_CAP_ANY_WR (CEPH_CAP_ANY_EXCL | CEPH_CAP_ANY_FILE_WR) 632#define CEPH_CAP_ANY_WR (CEPH_CAP_ANY_EXCL | CEPH_CAP_ANY_FILE_WR)