aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/inode.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2014-04-16 20:55:50 -0400
committerYan, Zheng <zheng.z.yan@intel.com>2014-06-05 21:29:52 -0400
commitf98a128a55ff85d0087de89f304f10bd75e792aa (patch)
treebdaa64075f36354d7f221a8b7d93fbc4bdb8f322 /fs/ceph/inode.c
parent461f758ac0bad40fe8e0959f415dae38efa16c12 (diff)
ceph: update inode fields according to issued caps
Cap message and request reply from non-auth MDS may carry stale information (corresponding locks are in LOCK states) even they have the newest inode version. So client should update inode fields according to issued caps. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r--fs/ceph/inode.c70
1 files changed, 39 insertions, 31 deletions
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 */