diff options
Diffstat (limited to 'net/ceph/messenger.c')
| -rw-r--r-- | net/ceph/messenger.c | 47 | 
1 files changed, 33 insertions, 14 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 1948d592aa54..b2f571dd933d 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -174,6 +174,7 @@ static struct lock_class_key socket_class;  #define SKIP_BUF_SIZE	1024  static void queue_con(struct ceph_connection *con); +static void cancel_con(struct ceph_connection *con);  static void con_work(struct work_struct *);  static void con_fault(struct ceph_connection *con); @@ -680,7 +681,7 @@ void ceph_con_close(struct ceph_connection *con)  	reset_connection(con);  	con->peer_global_seq = 0; -	cancel_delayed_work(&con->work); +	cancel_con(con);  	con_close_socket(con);  	mutex_unlock(&con->mutex);  } @@ -900,7 +901,7 @@ static void ceph_msg_data_pages_cursor_init(struct ceph_msg_data_cursor *cursor,  	BUG_ON(page_count > (int)USHRT_MAX);  	cursor->page_count = (unsigned short)page_count;  	BUG_ON(length > SIZE_MAX - cursor->page_offset); -	cursor->last_piece = (size_t)cursor->page_offset + length <= PAGE_SIZE; +	cursor->last_piece = cursor->page_offset + cursor->resid <= PAGE_SIZE;  }  static struct page * @@ -2667,19 +2668,16 @@ static int queue_con_delay(struct ceph_connection *con, unsigned long delay)  {  	if (!con->ops->get(con)) {  		dout("%s %p ref count 0\n", __func__, con); -  		return -ENOENT;  	}  	if (!queue_delayed_work(ceph_msgr_wq, &con->work, delay)) {  		dout("%s %p - already queued\n", __func__, con);  		con->ops->put(con); -  		return -EBUSY;  	}  	dout("%s %p %lu\n", __func__, con, delay); -  	return 0;  } @@ -2688,6 +2686,14 @@ static void queue_con(struct ceph_connection *con)  	(void) queue_con_delay(con, 0);  } +static void cancel_con(struct ceph_connection *con) +{ +	if (cancel_delayed_work(&con->work)) { +		dout("%s %p\n", __func__, con); +		con->ops->put(con); +	} +} +  static bool con_sock_closed(struct ceph_connection *con)  {  	if (!con_flag_test_and_clear(con, CON_FLAG_SOCK_CLOSED)) @@ -3269,24 +3275,21 @@ static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip)  /*   * Free a generically kmalloc'd message.   */ -void ceph_msg_kfree(struct ceph_msg *m) +static void ceph_msg_free(struct ceph_msg *m)  { -	dout("msg_kfree %p\n", m); +	dout("%s %p\n", __func__, m);  	ceph_kvfree(m->front.iov_base);  	kmem_cache_free(ceph_msg_cache, m);  } -/* - * Drop a msg ref.  Destroy as needed. - */ -void ceph_msg_last_put(struct kref *kref) +static void ceph_msg_release(struct kref *kref)  {  	struct ceph_msg *m = container_of(kref, struct ceph_msg, kref);  	LIST_HEAD(data);  	struct list_head *links;  	struct list_head *next; -	dout("ceph_msg_put last one on %p\n", m); +	dout("%s %p\n", __func__, m);  	WARN_ON(!list_empty(&m->list_head));  	/* drop middle, data, if any */ @@ -3308,9 +3311,25 @@ void ceph_msg_last_put(struct kref *kref)  	if (m->pool)  		ceph_msgpool_put(m->pool, m);  	else -		ceph_msg_kfree(m); +		ceph_msg_free(m); +} + +struct ceph_msg *ceph_msg_get(struct ceph_msg *msg) +{ +	dout("%s %p (was %d)\n", __func__, msg, +	     atomic_read(&msg->kref.refcount)); +	kref_get(&msg->kref); +	return msg; +} +EXPORT_SYMBOL(ceph_msg_get); + +void ceph_msg_put(struct ceph_msg *msg) +{ +	dout("%s %p (was %d)\n", __func__, msg, +	     atomic_read(&msg->kref.refcount)); +	kref_put(&msg->kref, ceph_msg_release);  } -EXPORT_SYMBOL(ceph_msg_last_put); +EXPORT_SYMBOL(ceph_msg_put);  void ceph_msg_dump(struct ceph_msg *msg)  {  |