aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ceph/caps.c75
-rw-r--r--fs/ceph/inode.c60
-rw-r--r--fs/ceph/mds_client.c129
-rw-r--r--fs/ceph/mds_client.h16
-rw-r--r--fs/ceph/mdsmap.c1
-rw-r--r--net/ceph/messenger.c55
6 files changed, 174 insertions, 162 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index f3496db4bb3e..94c026bba2c2 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -657,6 +657,9 @@ void ceph_add_cap(struct inode *inode,
657 session->s_nr_caps++; 657 session->s_nr_caps++;
658 spin_unlock(&session->s_cap_lock); 658 spin_unlock(&session->s_cap_lock);
659 } else { 659 } else {
660 if (cap->cap_gen < session->s_cap_gen)
661 cap->issued = cap->implemented = CEPH_CAP_PIN;
662
660 /* 663 /*
661 * auth mds of the inode changed. we received the cap export 664 * auth mds of the inode changed. we received the cap export
662 * message, but still haven't received the cap import message. 665 * message, but still haven't received the cap import message.
@@ -1855,14 +1858,17 @@ retry_locked:
1855 retain |= CEPH_CAP_ANY; /* be greedy */ 1858 retain |= CEPH_CAP_ANY; /* be greedy */
1856 } else if (S_ISDIR(inode->i_mode) && 1859 } else if (S_ISDIR(inode->i_mode) &&
1857 (issued & CEPH_CAP_FILE_SHARED) && 1860 (issued & CEPH_CAP_FILE_SHARED) &&
1858 __ceph_dir_is_complete(ci)) { 1861 __ceph_dir_is_complete(ci)) {
1859 /* 1862 /*
1860 * If a directory is complete, we want to keep 1863 * If a directory is complete, we want to keep
1861 * the exclusive cap. So that MDS does not end up 1864 * the exclusive cap. So that MDS does not end up
1862 * revoking the shared cap on every create/unlink 1865 * revoking the shared cap on every create/unlink
1863 * operation. 1866 * operation.
1864 */ 1867 */
1865 want = CEPH_CAP_ANY_SHARED | CEPH_CAP_FILE_EXCL; 1868 if (IS_RDONLY(inode))
1869 want = CEPH_CAP_ANY_SHARED;
1870 else
1871 want = CEPH_CAP_ANY_SHARED | CEPH_CAP_FILE_EXCL;
1866 retain |= want; 1872 retain |= want;
1867 } else { 1873 } else {
1868 1874
@@ -1970,8 +1976,7 @@ retry_locked:
1970 goto ack; 1976 goto ack;
1971 1977
1972 /* things we might delay */ 1978 /* things we might delay */
1973 if ((cap->issued & ~retain) == 0 && 1979 if ((cap->issued & ~retain) == 0)
1974 cap->mds_wanted == want)
1975 continue; /* nope, all good */ 1980 continue; /* nope, all good */
1976 1981
1977 if (no_delay) 1982 if (no_delay)
@@ -3048,7 +3053,8 @@ static void handle_cap_grant(struct inode *inode,
3048 int used, wanted, dirty; 3053 int used, wanted, dirty;
3049 u64 size = le64_to_cpu(grant->size); 3054 u64 size = le64_to_cpu(grant->size);
3050 u64 max_size = le64_to_cpu(grant->max_size); 3055 u64 max_size = le64_to_cpu(grant->max_size);
3051 int check_caps = 0; 3056 unsigned char check_caps = 0;
3057 bool was_stale = cap->cap_gen < session->s_cap_gen;
3052 bool wake = false; 3058 bool wake = false;
3053 bool writeback = false; 3059 bool writeback = false;
3054 bool queue_trunc = false; 3060 bool queue_trunc = false;
@@ -3063,21 +3069,6 @@ static void handle_cap_grant(struct inode *inode,
3063 3069
3064 3070
3065 /* 3071 /*
3066 * auth mds of the inode changed. we received the cap export message,
3067 * but still haven't received the cap import message. handle_cap_export
3068 * updated the new auth MDS' cap.
3069 *
3070 * "ceph_seq_cmp(seq, cap->seq) <= 0" means we are processing a message
3071 * that was sent before the cap import message. So don't remove caps.
3072 */
3073 if (ceph_seq_cmp(seq, cap->seq) <= 0) {
3074 WARN_ON(cap != ci->i_auth_cap);
3075 WARN_ON(cap->cap_id != le64_to_cpu(grant->cap_id));
3076 seq = cap->seq;
3077 newcaps |= cap->issued;
3078 }
3079
3080 /*
3081 * If CACHE is being revoked, and we have no dirty buffers, 3072 * If CACHE is being revoked, and we have no dirty buffers,
3082 * try to invalidate (once). (If there are dirty buffers, we 3073 * try to invalidate (once). (If there are dirty buffers, we
3083 * will invalidate _after_ writeback.) 3074 * will invalidate _after_ writeback.)
@@ -3096,6 +3087,24 @@ static void handle_cap_grant(struct inode *inode,
3096 } 3087 }
3097 } 3088 }
3098 3089
3090 if (was_stale)
3091 cap->issued = cap->implemented = CEPH_CAP_PIN;
3092
3093 /*
3094 * auth mds of the inode changed. we received the cap export message,
3095 * but still haven't received the cap import message. handle_cap_export
3096 * updated the new auth MDS' cap.
3097 *
3098 * "ceph_seq_cmp(seq, cap->seq) <= 0" means we are processing a message
3099 * that was sent before the cap import message. So don't remove caps.
3100 */
3101 if (ceph_seq_cmp(seq, cap->seq) <= 0) {
3102 WARN_ON(cap != ci->i_auth_cap);
3103 WARN_ON(cap->cap_id != le64_to_cpu(grant->cap_id));
3104 seq = cap->seq;
3105 newcaps |= cap->issued;
3106 }
3107
3099 /* side effects now are allowed */ 3108 /* side effects now are allowed */
3100 cap->cap_gen = session->s_cap_gen; 3109 cap->cap_gen = session->s_cap_gen;
3101 cap->seq = seq; 3110 cap->seq = seq;
@@ -3200,13 +3209,20 @@ static void handle_cap_grant(struct inode *inode,
3200 ceph_cap_string(wanted), 3209 ceph_cap_string(wanted),
3201 ceph_cap_string(used), 3210 ceph_cap_string(used),
3202 ceph_cap_string(dirty)); 3211 ceph_cap_string(dirty));
3203 if (wanted != le32_to_cpu(grant->wanted)) { 3212
3204 dout("mds wanted %s -> %s\n", 3213 if ((was_stale || le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) &&
3205 ceph_cap_string(le32_to_cpu(grant->wanted)), 3214 (wanted & ~(cap->mds_wanted | newcaps))) {
3206 ceph_cap_string(wanted)); 3215 /*
3207 /* imported cap may not have correct mds_wanted */ 3216 * If mds is importing cap, prior cap messages that update
3208 if (le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) 3217 * 'wanted' may get dropped by mds (migrate seq mismatch).
3209 check_caps = 1; 3218 *
3219 * We don't send cap message to update 'wanted' if what we
3220 * want are already issued. If mds revokes caps, cap message
3221 * that releases caps also tells mds what we want. But if
3222 * caps got revoked by mds forcedly (session stale). We may
3223 * haven't told mds what we want.
3224 */
3225 check_caps = 1;
3210 } 3226 }
3211 3227
3212 /* revocation, grant, or no-op? */ 3228 /* revocation, grant, or no-op? */
@@ -3539,9 +3555,9 @@ retry:
3539 goto out_unlock; 3555 goto out_unlock;
3540 3556
3541 if (target < 0) { 3557 if (target < 0) {
3542 __ceph_remove_cap(cap, false); 3558 if (cap->mds_wanted | cap->issued)
3543 if (!ci->i_auth_cap)
3544 ci->i_ceph_flags |= CEPH_I_CAP_DROPPED; 3559 ci->i_ceph_flags |= CEPH_I_CAP_DROPPED;
3560 __ceph_remove_cap(cap, false);
3545 goto out_unlock; 3561 goto out_unlock;
3546 } 3562 }
3547 3563
@@ -3569,7 +3585,6 @@ retry:
3569 tcap->cap_id = t_cap_id; 3585 tcap->cap_id = t_cap_id;
3570 tcap->seq = t_seq - 1; 3586 tcap->seq = t_seq - 1;
3571 tcap->issue_seq = t_seq - 1; 3587 tcap->issue_seq = t_seq - 1;
3572 tcap->mseq = t_mseq;
3573 tcap->issued |= issued; 3588 tcap->issued |= issued;
3574 tcap->implemented |= issued; 3589 tcap->implemented |= issued;
3575 if (cap == ci->i_auth_cap) 3590 if (cap == ci->i_auth_cap)
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 79dd5e6ed755..9d1f34d46627 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -1098,8 +1098,9 @@ out_unlock:
1098 * splice a dentry to an inode. 1098 * splice a dentry to an inode.
1099 * caller must hold directory i_mutex for this to be safe. 1099 * caller must hold directory i_mutex for this to be safe.
1100 */ 1100 */
1101static struct dentry *splice_dentry(struct dentry *dn, struct inode *in) 1101static int splice_dentry(struct dentry **pdn, struct inode *in)
1102{ 1102{
1103 struct dentry *dn = *pdn;
1103 struct dentry *realdn; 1104 struct dentry *realdn;
1104 1105
1105 BUG_ON(d_inode(dn)); 1106 BUG_ON(d_inode(dn));
@@ -1132,28 +1133,23 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in)
1132 if (IS_ERR(realdn)) { 1133 if (IS_ERR(realdn)) {
1133 pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n", 1134 pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n",
1134 PTR_ERR(realdn), dn, in, ceph_vinop(in)); 1135 PTR_ERR(realdn), dn, in, ceph_vinop(in));
1135 dn = realdn; 1136 return PTR_ERR(realdn);
1136 /* 1137 }
1137 * Caller should release 'dn' in the case of error. 1138
1138 * If 'req->r_dentry' is passed to this function, 1139 if (realdn) {
1139 * caller should leave 'req->r_dentry' untouched.
1140 */
1141 goto out;
1142 } else if (realdn) {
1143 dout("dn %p (%d) spliced with %p (%d) " 1140 dout("dn %p (%d) spliced with %p (%d) "
1144 "inode %p ino %llx.%llx\n", 1141 "inode %p ino %llx.%llx\n",
1145 dn, d_count(dn), 1142 dn, d_count(dn),
1146 realdn, d_count(realdn), 1143 realdn, d_count(realdn),
1147 d_inode(realdn), ceph_vinop(d_inode(realdn))); 1144 d_inode(realdn), ceph_vinop(d_inode(realdn)));
1148