aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-09 15:03:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-09 15:03:46 -0400
commit8dc54e49ce67e5628bf4668c64203c22cbac7fc5 (patch)
tree12f25a8dd312683abc3deafe4e41301e04b66ad3
parent267aeb6c142b1fbad1e6ed49f46d82113339141a (diff)
parentd91f2438d881514e4a923fd786dbd94b764a9440 (diff)
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: update issue_seq on cap grant ceph: send cap release message early on failed revoke. ceph: Update max_len with minimum required size ceph: Fix return value of encode_fh function ceph: avoid null deref in osd request error path ceph: fix list_add usage on unsafe_writes list
-rw-r--r--fs/ceph/caps.c31
-rw-r--r--fs/ceph/export.c21
-rw-r--r--fs/ceph/file.c2
-rw-r--r--fs/ceph/osd_client.c2
4 files changed, 33 insertions, 23 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 73c153092f72..5e9da996a151 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2283,7 +2283,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2283{ 2283{
2284 struct ceph_inode_info *ci = ceph_inode(inode); 2284 struct ceph_inode_info *ci = ceph_inode(inode);
2285 int mds = session->s_mds; 2285 int mds = session->s_mds;
2286 int seq = le32_to_cpu(grant->seq); 2286 unsigned seq = le32_to_cpu(grant->seq);
2287 unsigned issue_seq = le32_to_cpu(grant->issue_seq);
2287 int newcaps = le32_to_cpu(grant->caps); 2288 int newcaps = le32_to_cpu(grant->caps);
2288 int issued, implemented, used, wanted, dirty; 2289 int issued, implemented, used, wanted, dirty;
2289 u64 size = le64_to_cpu(grant->size); 2290 u64 size = le64_to_cpu(grant->size);
@@ -2295,8 +2296,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2295 int revoked_rdcache = 0; 2296 int revoked_rdcache = 0;
2296 int queue_invalidate = 0; 2297 int queue_invalidate = 0;
2297 2298
2298 dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n", 2299 dout("handle_cap_grant inode %p cap %p mds%d seq %u/%u %s\n",
2299 inode, cap, mds, seq, ceph_cap_string(newcaps)); 2300 inode, cap, mds, seq, issue_seq, ceph_cap_string(newcaps));
2300 dout(" size %llu max_size %llu, i_size %llu\n", size, max_size, 2301 dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
2301 inode->i_size); 2302 inode->i_size);
2302 2303
@@ -2392,6 +2393,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2392 } 2393 }
2393 2394
2394 cap->seq = seq; 2395 cap->seq = seq;
2396 cap->issue_seq = issue_seq;
2395 2397
2396 /* file layout may have changed */ 2398 /* file layout may have changed */
2397 ci->i_layout = grant->layout; 2399 ci->i_layout = grant->layout;
@@ -2774,15 +2776,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
2774 if (op == CEPH_CAP_OP_IMPORT) 2776 if (op == CEPH_CAP_OP_IMPORT)
2775 __queue_cap_release(session, vino.ino, cap_id, 2777 __queue_cap_release(session, vino.ino, cap_id,
2776 mseq, seq); 2778 mseq, seq);
2777 2779 goto flush_cap_releases;
2778 /*
2779 * send any full release message to try to move things
2780 * along for the mds (who clearly thinks we still have this
2781 * cap).
2782 */
2783 ceph_add_cap_releases(mdsc, session);
2784 ceph_send_cap_releases(mdsc, session);
2785 goto done;
2786 } 2780 }
2787 2781
2788 /* these will work even if we don't have a cap yet */ 2782 /* these will work even if we don't have a cap yet */
@@ -2810,7 +2804,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
2810 dout(" no cap on %p ino %llx.%llx from mds%d\n", 2804 dout(" no cap on %p ino %llx.%llx from mds%d\n",
2811 inode, ceph_ino(inode), ceph_snap(inode), mds); 2805 inode, ceph_ino(inode), ceph_snap(inode), mds);
2812 spin_unlock(&inode->i_lock); 2806 spin_unlock(&inode->i_lock);
2813 goto done; 2807 goto flush_cap_releases;
2814 } 2808 }
2815 2809
2816 /* note that each of these drops i_lock for us */ 2810 /* note that each of these drops i_lock for us */
@@ -2834,6 +2828,17 @@ void ceph_handle_caps(struct ceph_mds_session *session,
2834 ceph_cap_op_name(op)); 2828 ceph_cap_op_name(op));
2835 } 2829 }
2836 2830
2831 goto done;
2832
2833flush_cap_releases:
2834 /*
2835 * send any full release message to try to move things
2836 * along for the mds (who clearly thinks we still have this
2837 * cap).
2838 */
2839 ceph_add_cap_releases(mdsc, session);
2840 ceph_send_cap_releases(mdsc, session);
2841
2837done: 2842done:
2838 mutex_unlock(&session->s_mutex); 2843 mutex_unlock(&session->s_mutex);
2839done_unlocked: 2844done_unlocked:
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index 4480cb1c63e7..e38423e82f2e 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -42,32 +42,37 @@ struct ceph_nfs_confh {
42static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len, 42static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
43 int connectable) 43 int connectable)
44{ 44{
45 int type;
45 struct ceph_nfs_fh *fh = (void *)rawfh; 46 struct ceph_nfs_fh *fh = (void *)rawfh;
46 struct ceph_nfs_confh *cfh = (void *)rawfh; 47 struct ceph_nfs_confh *cfh = (void *)rawfh;
47 struct dentry *parent = dentry->d_parent; 48 struct dentry *parent = dentry->d_parent;
48 struct inode *inode = dentry->d_inode; 49 struct inode *inode = dentry->d_inode;
49 int type; 50 int connected_handle_length = sizeof(*cfh)/4;
51 int handle_length = sizeof(*fh)/4;
50 52
51 /* don't re-export snaps */ 53 /* don't re-export snaps */
52 if (ceph_snap(inode) != CEPH_NOSNAP) 54 if (ceph_snap(inode) != CEPH_NOSNAP)
53 return -EINVAL; 55 return -EINVAL;
54 56
55 if (*max_len >= sizeof(*cfh)) { 57 if (*max_len >= connected_handle_length) {
56 dout("encode_fh %p connectable\n", dentry); 58 dout("encode_fh %p connectable\n", dentry);
57 cfh->ino = ceph_ino(dentry->d_inode); 59 cfh->ino = ceph_ino(dentry->d_inode);
58 cfh->parent_ino = ceph_ino(parent->d_inode); 60 cfh->parent_ino = ceph_ino(parent->d_inode);
59 cfh->parent_name_hash = parent->d_name.hash; 61 cfh->parent_name_hash = parent->d_name.hash;
60 *max_len = sizeof(*cfh); 62 *max_len = connected_handle_length;
61 type = 2; 63 type = 2;
62 } else if (*max_len > sizeof(*fh)) { 64 } else if (*max_len >= handle_length) {
63 if (connectable) 65 if (connectable) {
64 return -ENOSPC; 66 *max_len = connected_handle_length;
67 return 255;
68 }
65 dout("encode_fh %p\n", dentry); 69 dout("encode_fh %p\n", dentry);
66 fh->ino = ceph_ino(dentry->d_inode); 70 fh->ino = ceph_ino(dentry->d_inode);
67 *max_len = sizeof(*fh); 71 *max_len = handle_length;
68 type = 1; 72 type = 1;
69 } else { 73 } else {
70 return -ENOSPC; 74 *max_len = handle_length;
75 return 255;
71 } 76 }
72 return type; 77 return type;
73} 78}
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 8c044a4f0457..66e4da6dba22 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -697,7 +697,7 @@ more:
697 * start_request so that a tid has been assigned. 697 * start_request so that a tid has been assigned.
698 */ 698 */
699 spin_lock(&ci->i_unsafe_lock); 699 spin_lock(&ci->i_unsafe_lock);
700 list_add(&ci->i_unsafe_writes, &req->r_unsafe_item); 700 list_add(&req->r_unsafe_item, &ci->i_unsafe_writes);
701 spin_unlock(&ci->i_unsafe_lock); 701 spin_unlock(&ci->i_unsafe_lock);
702 ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR); 702 ceph_get_cap_refs(ci, CEPH_CAP_FILE_WR);
703 } 703 }
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c
index dfced1dacbcd..3b5571b8ce22 100644
--- a/fs/ceph/osd_client.c
+++ b/fs/ceph/osd_client.c
@@ -549,7 +549,7 @@ static void __unregister_request(struct ceph_osd_client *osdc,
549 */ 549 */
550static void __cancel_request(struct ceph_osd_request *req) 550static void __cancel_request(struct ceph_osd_request *req)
551{ 551{
552 if (req->r_sent) { 552 if (req->r_sent && req->r_osd) {
553 ceph_con_revoke(&req->r_osd->o_con, req->r_request); 553 ceph_con_revoke(&req->r_osd->o_con, req->r_request);
554 req->r_sent = 0; 554 req->r_sent = 0;
555 } 555 }