Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
ceph: try to send partial cap release on cap message on missing inode
ceph: release cap on import if we don't have the inode
ceph: fix misleading/incorrect debug message
ceph: fix atomic64_t initialization on ia64
ceph: fix lease revocation when seq doesn't match
ceph: fix f_namelen reported by statfs
ceph: fix memory leak in statfs
ceph: fix d_subdirs ordering problem

+84 -51
+57 -36
fs/ceph/caps.c
··· 981 981 return 0; 982 982 } 983 983 984 + static void __queue_cap_release(struct ceph_mds_session *session, 985 + u64 ino, u64 cap_id, u32 migrate_seq, 986 + u32 issue_seq) 987 + { 988 + struct ceph_msg *msg; 989 + struct ceph_mds_cap_release *head; 990 + struct ceph_mds_cap_item *item; 991 + 992 + spin_lock(&session->s_cap_lock); 993 + BUG_ON(!session->s_num_cap_releases); 994 + msg = list_first_entry(&session->s_cap_releases, 995 + struct ceph_msg, list_head); 996 + 997 + dout(" adding %llx release to mds%d msg %p (%d left)\n", 998 + ino, session->s_mds, msg, session->s_num_cap_releases); 999 + 1000 + BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE); 1001 + head = msg->front.iov_base; 1002 + head->num = cpu_to_le32(le32_to_cpu(head->num) + 1); 1003 + item = msg->front.iov_base + msg->front.iov_len; 1004 + item->ino = cpu_to_le64(ino); 1005 + item->cap_id = cpu_to_le64(cap_id); 1006 + item->migrate_seq = cpu_to_le32(migrate_seq); 1007 + item->seq = cpu_to_le32(issue_seq); 1008 + 1009 + session->s_num_cap_releases--; 1010 + 1011 + msg->front.iov_len += sizeof(*item); 1012 + if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) { 1013 + dout(" release msg %p full\n", msg); 1014 + list_move_tail(&msg->list_head, &session->s_cap_releases_done); 1015 + } else { 1016 + dout(" release msg %p at %d/%d (%d)\n", msg, 1017 + (int)le32_to_cpu(head->num), 1018 + (int)CEPH_CAPS_PER_RELEASE, 1019 + (int)msg->front.iov_len); 1020 + } 1021 + spin_unlock(&session->s_cap_lock); 1022 + } 1023 + 984 1024 /* 985 1025 * Queue cap releases when an inode is dropped from our cache. Since 986 1026 * inode is about to be destroyed, there is no need for i_lock. ··· 1034 994 while (p) { 1035 995 struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node); 1036 996 struct ceph_mds_session *session = cap->session; 1037 - struct ceph_msg *msg; 1038 - struct ceph_mds_cap_release *head; 1039 - struct ceph_mds_cap_item *item; 1040 997 1041 - spin_lock(&session->s_cap_lock); 1042 - BUG_ON(!session->s_num_cap_releases); 1043 - msg = list_first_entry(&session->s_cap_releases, 1044 - struct ceph_msg, list_head); 1045 - 1046 - dout(" adding %p release to mds%d msg %p (%d left)\n", 1047 - inode, session->s_mds, msg, session->s_num_cap_releases); 1048 - 1049 - BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE); 1050 - head = msg->front.iov_base; 1051 - head->num = cpu_to_le32(le32_to_cpu(head->num) + 1); 1052 - item = msg->front.iov_base + msg->front.iov_len; 1053 - item->ino = cpu_to_le64(ceph_ino(inode)); 1054 - item->cap_id = cpu_to_le64(cap->cap_id); 1055 - item->migrate_seq = cpu_to_le32(cap->mseq); 1056 - item->seq = cpu_to_le32(cap->issue_seq); 1057 - 1058 - session->s_num_cap_releases--; 1059 - 1060 - msg->front.iov_len += sizeof(*item); 1061 - if (le32_to_cpu(head->num) == CEPH_CAPS_PER_RELEASE) { 1062 - dout(" release msg %p full\n", msg); 1063 - list_move_tail(&msg->list_head, 1064 - &session->s_cap_releases_done); 1065 - } else { 1066 - dout(" release msg %p at %d/%d (%d)\n", msg, 1067 - (int)le32_to_cpu(head->num), 1068 - (int)CEPH_CAPS_PER_RELEASE, 1069 - (int)msg->front.iov_len); 1070 - } 1071 - spin_unlock(&session->s_cap_lock); 998 + __queue_cap_release(session, ceph_ino(inode), cap->cap_id, 999 + cap->mseq, cap->issue_seq); 1072 1000 p = rb_next(p); 1073 1001 __ceph_remove_cap(cap); 1074 1002 } ··· 2663 2655 struct ceph_mds_caps *h; 2664 2656 int mds = session->s_mds; 2665 2657 int op; 2666 - u32 seq; 2658 + u32 seq, mseq; 2667 2659 struct ceph_vino vino; 2668 2660 u64 cap_id; 2669 2661 u64 size, max_size; ··· 2683 2675 vino.snap = CEPH_NOSNAP; 2684 2676 cap_id = le64_to_cpu(h->cap_id); 2685 2677 seq = le32_to_cpu(h->seq); 2678 + mseq = le32_to_cpu(h->migrate_seq); 2686 2679 size = le64_to_cpu(h->size); 2687 2680 max_size = le64_to_cpu(h->max_size); 2688 2681 ··· 2698 2689 vino.snap, inode); 2699 2690 if (!inode) { 2700 2691 dout(" i don't have ino %llx\n", vino.ino); 2692 + 2693 + if (op == CEPH_CAP_OP_IMPORT) 2694 + __queue_cap_release(session, vino.ino, cap_id, 2695 + mseq, seq); 2696 + 2697 + /* 2698 + * send any full release message to try to move things 2699 + * along for the mds (who clearly thinks we still have this 2700 + * cap). 2701 + */ 2702 + ceph_add_cap_releases(mdsc, session, -1); 2703 + ceph_send_cap_releases(mdsc, session); 2701 2704 goto done; 2702 2705 } 2703 2706 ··· 2735 2714 spin_lock(&inode->i_lock); 2736 2715 cap = __get_cap_for_mds(ceph_inode(inode), mds); 2737 2716 if (!cap) { 2738 - dout("no cap on %p ino %llx.%llx from mds%d, releasing\n", 2717 + dout(" no cap on %p ino %llx.%llx from mds%d\n", 2739 2718 inode, ceph_ino(inode), ceph_snap(inode), mds); 2740 2719 spin_unlock(&inode->i_lock); 2741 2720 goto done;
+1 -1
fs/ceph/inode.c
··· 827 827 828 828 spin_lock(&dcache_lock); 829 829 spin_lock(&dn->d_lock); 830 - list_move_tail(&dir->d_subdirs, &dn->d_u.d_child); 830 + list_move(&dn->d_u.d_child, &dir->d_subdirs); 831 831 dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset, 832 832 dn->d_u.d_child.prev, dn->d_u.d_child.next); 833 833 spin_unlock(&dn->d_lock);
+16 -12
fs/ceph/mds_client.c
··· 1066 1066 * 1067 1067 * Called under s_mutex. 1068 1068 */ 1069 - static int add_cap_releases(struct ceph_mds_client *mdsc, 1070 - struct ceph_mds_session *session, 1071 - int extra) 1069 + int ceph_add_cap_releases(struct ceph_mds_client *mdsc, 1070 + struct ceph_mds_session *session, 1071 + int extra) 1072 1072 { 1073 1073 struct ceph_msg *msg; 1074 1074 struct ceph_mds_cap_release *head; ··· 1176 1176 /* 1177 1177 * called under s_mutex 1178 1178 */ 1179 - static void send_cap_releases(struct ceph_mds_client *mdsc, 1180 - struct ceph_mds_session *session) 1179 + void ceph_send_cap_releases(struct ceph_mds_client *mdsc, 1180 + struct ceph_mds_session *session) 1181 1181 { 1182 1182 struct ceph_msg *msg; 1183 1183 ··· 1980 1980 } 1981 1981 mutex_unlock(&mdsc->mutex); 1982 1982 1983 - add_cap_releases(mdsc, req->r_session, -1); 1983 + ceph_add_cap_releases(mdsc, req->r_session, -1); 1984 1984 mutex_unlock(&session->s_mutex); 1985 1985 1986 1986 /* kick calling process */ ··· 2433 2433 struct ceph_dentry_info *di; 2434 2434 int mds = session->s_mds; 2435 2435 struct ceph_mds_lease *h = msg->front.iov_base; 2436 + u32 seq; 2436 2437 struct ceph_vino vino; 2437 2438 int mask; 2438 2439 struct qstr dname; ··· 2447 2446 vino.ino = le64_to_cpu(h->ino); 2448 2447 vino.snap = CEPH_NOSNAP; 2449 2448 mask = le16_to_cpu(h->mask); 2449 + seq = le32_to_cpu(h->seq); 2450 2450 dname.name = (void *)h + sizeof(*h) + sizeof(u32); 2451 2451 dname.len = msg->front.iov_len - sizeof(*h) - sizeof(u32); 2452 2452 if (dname.len != get_unaligned_le32(h+1)) ··· 2458 2456 2459 2457 /* lookup inode */ 2460 2458 inode = ceph_find_inode(sb, vino); 2461 - dout("handle_lease '%s', mask %d, ino %llx %p\n", 2462 - ceph_lease_op_name(h->action), mask, vino.ino, inode); 2459 + dout("handle_lease %s, mask %d, ino %llx %p %.*s\n", 2460 + ceph_lease_op_name(h->action), mask, vino.ino, inode, 2461 + dname.len, dname.name); 2463 2462 if (inode == NULL) { 2464 2463 dout("handle_lease no inode %llx\n", vino.ino); 2465 2464 goto release; ··· 2485 2482 switch (h->action) { 2486 2483 case CEPH_MDS_LEASE_REVOKE: 2487 2484 if (di && di->lease_session == session) { 2488 - h->seq = cpu_to_le32(di->lease_seq); 2485 + if (ceph_seq_cmp(di->lease_seq, seq) > 0) 2486 + h->seq = cpu_to_le32(di->lease_seq); 2489 2487 __ceph_mdsc_drop_dentry_lease(dentry); 2490 2488 } 2491 2489 release = 1; ··· 2500 2496 unsigned long duration = 2501 2497 le32_to_cpu(h->duration_ms) * HZ / 1000; 2502 2498 2503 - di->lease_seq = le32_to_cpu(h->seq); 2499 + di->lease_seq = seq; 2504 2500 dentry->d_time = di->lease_renew_from + duration; 2505 2501 di->lease_renew_after = di->lease_renew_from + 2506 2502 (duration >> 1); ··· 2690 2686 send_renew_caps(mdsc, s); 2691 2687 else 2692 2688 ceph_con_keepalive(&s->s_con); 2693 - add_cap_releases(mdsc, s, -1); 2689 + ceph_add_cap_releases(mdsc, s, -1); 2694 2690 if (s->s_state == CEPH_MDS_SESSION_OPEN || 2695 2691 s->s_state == CEPH_MDS_SESSION_HUNG) 2696 - send_cap_releases(mdsc, s); 2692 + ceph_send_cap_releases(mdsc, s); 2697 2693 mutex_unlock(&s->s_mutex); 2698 2694 ceph_put_mds_session(s); 2699 2695
+6
fs/ceph/mds_client.h
··· 322 322 kref_put(&req->r_kref, ceph_mdsc_release_request); 323 323 } 324 324 325 + extern int ceph_add_cap_releases(struct ceph_mds_client *mdsc, 326 + struct ceph_mds_session *session, 327 + int extra); 328 + extern void ceph_send_cap_releases(struct ceph_mds_client *mdsc, 329 + struct ceph_mds_session *session); 330 + 325 331 extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc); 326 332 327 333 extern char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base,
+2
fs/ceph/mon_client.c
··· 400 400 ceph_msg_put(req->reply); 401 401 if (req->request) 402 402 ceph_msg_put(req->request); 403 + 404 + kfree(req); 403 405 } 404 406 405 407 static void put_generic_request(struct ceph_mon_generic_request *req)
+2 -2
fs/ceph/super.c
··· 89 89 90 90 buf->f_files = le64_to_cpu(st.num_objects); 91 91 buf->f_ffree = -1; 92 - buf->f_namelen = PATH_MAX; 92 + buf->f_namelen = NAME_MAX; 93 93 buf->f_frsize = PAGE_CACHE_SIZE; 94 94 95 95 /* leave fsid little-endian, regardless of host endianness */ ··· 926 926 /* 927 927 * construct our own bdi so we can control readahead, etc. 928 928 */ 929 - static atomic_long_t bdi_seq = ATOMIC_INIT(0); 929 + static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); 930 930 931 931 static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client) 932 932 {