History

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: no .snap inside of snapped namespace libceph: fix msgr standby handling libceph: fix msgr keepalive flag libceph: fix msgr backoff libceph: retry after authorization failure libceph: fix handling of short returns from get_user_pages ceph: do not clear I_COMPLETE from d_release ceph: do not set I_COMPLETE Revert "ceph: keep reference to parent inode on ceph_dentry"

Linus Torvalds committed 15 years ago

Commit fb62c002 parents 5c4b4be 455cec06 files · +72 −50Browse files

Unified · Split

6 files
  1. fs/ceph/dir.c +3 −25
  2. fs/ceph/inode.c +1 −1
  3. fs/ceph/super.h +0 −1
  4. include/linux/ceph/messenger.h +1 −1
  5. net/ceph/messenger.c +54 −17
  6. net/ceph/pagevec.c +13 −5
fs/ceph/dir.c+3−25
@@ -60,7 +60,6 @@ int ceph_init_dentry(struct dentry *dentry) · 59 unmodified lines
6060 }
6161 di->dentry = dentry;
6262 di->lease_session = NULL;
63− di->parent_inode = igrab(dentry->d_parent->d_inode);
6463 dentry->d_fsdata = di;
6564 dentry->d_time = jiffies;
6665 ceph_dentry_lru_add(dentry);
@@ -410,7 +409,7 @@ more: · 343 unmodified lines
410409 spin_lock(&inode->i_lock);
411410 if (ci->i_release_count == fi->dir_release_count) {
412411 dout(" marking %p complete\n", inode);
413− ci->i_ceph_flags |= CEPH_I_COMPLETE;
412+ /* ci->i_ceph_flags |= CEPH_I_COMPLETE; */
414413 ci->i_max_offset = filp->f_pos;
415414 }
416415 spin_unlock(&inode->i_lock);
@@ -497,6 +496,7 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, · 80 unmodified lines
497496
498497 /* .snap dir? */
499498 if (err == -ENOENT &&
499+ ceph_snap(parent) == CEPH_NOSNAP &&
500500 strcmp(dentry->d_name.name,
501501 fsc->mount_options->snapdir_name) == 0) {
502502 struct inode *inode = ceph_get_snapdir(parent);
@@ -1030,28 +1030,8 @@ out_touch: · 527 unmodified lines
10301030 static void ceph_dentry_release(struct dentry *dentry)
10311031 {
10321032 struct ceph_dentry_info *di = ceph_dentry(dentry);
1033− struct inode *parent_inode = NULL;
1034− u64 snapid = CEPH_NOSNAP;
10351033
1036− if (!IS_ROOT(dentry)) {
1037− parent_inode = di->parent_inode;
1038− if (parent_inode)
1039− snapid = ceph_snap(parent_inode);
1040− }
1041− dout("dentry_release %p parent %p\n", dentry, parent_inode);
1042− if (parent_inode && snapid != CEPH_SNAPDIR) {
1043− struct ceph_inode_info *ci = ceph_inode(parent_inode);
1044−
1045− spin_lock(&parent_inode->i_lock);
1046− if (ci->i_shared_gen == di->lease_shared_gen ||
1047− snapid <= CEPH_MAXSNAP) {
1048− dout(" clearing %p complete (d_release)\n",
1049− parent_inode);
1050− ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
1051− ci->i_release_count++;
1052− }
1053− spin_unlock(&parent_inode->i_lock);
1054− }
1034+ dout("dentry_release %p\n", dentry);
10551035 if (di) {
10561036 ceph_dentry_lru_del(dentry);
10571037 if (di->lease_session)
@@ -1059,8 +1039,6 @@ static void ceph_dentry_release(struct dentry *dentry) · 1 unmodified line
10591039 kmem_cache_free(ceph_dentry_cachep, di);
10601040 dentry->d_fsdata = NULL;
10611041 }
1062− if (parent_inode)
1063− iput(parent_inode);
10641042 }
10651043
10661044 static int ceph_snapdir_d_revalidate(struct dentry *dentry,
fs/ceph/inode.c+1−1
@@ -707,7 +707,7 @@ static int fill_inode(struct inode *inode, · 706 unmodified lines
707707 (issued & CEPH_CAP_FILE_EXCL) == 0 &&
708708 (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
709709 dout(" marking %p complete (empty)\n", inode);
710− ci->i_ceph_flags |= CEPH_I_COMPLETE;
710+ /* ci->i_ceph_flags |= CEPH_I_COMPLETE; */
711711 ci->i_max_offset = 2;
712712 }
713713 break;
fs/ceph/super.h+0−1
@@ -207,7 +207,6 @@ struct ceph_dentry_info { · 206 unmodified lines
207207 struct dentry *dentry;
208208 u64 time;
209209 u64 offset;
210− struct inode *parent_inode;
211210 };
212211
213212 struct ceph_inode_xattrs_info {
include/linux/ceph/messenger.h+1−1
@@ -123,6 +123,7 @@ struct ceph_msg_pos { · 122 unmodified lines
123123 #define SOCK_CLOSED 11 /* socket state changed to closed */
124124 #define OPENING 13 /* open connection w/ (possibly new) peer */
125125 #define DEAD 14 /* dead, about to kfree */
126+#define BACKOFF 15
126127
127128 /*
128129 * A single connection with another host.
@@ -160,7 +161,6 @@ struct ceph_connection { · 31 unmodified lines
160161 struct list_head out_queue;
161162 struct list_head out_sent; /* sending or sent but unacked */
162163 u64 out_seq; /* last message queued for send */
163− bool out_keepalive_pending;
164164
165165 u64 in_seq, in_seq_acked; /* last message received, acked */
166166
net/ceph/messenger.c+54−17
@@ -336,7 +336,6 @@ static void reset_connection(struct ceph_connection *con) · 335 unmodified lines
336336 ceph_msg_put(con->out_msg);
337337 con->out_msg = NULL;
338338 }
339− con->out_keepalive_pending = false;
340339 con->in_seq = 0;
341340 con->in_seq_acked = 0;
342341 }
@@ -1248,8 +1247,6 @@ static int process_connect(struct ceph_connection *con) · 905 unmodified lines
12481247 con->auth_retry);
12491248 if (con->auth_retry == 2) {
12501249 con->error_msg = "connect authorization failure";
1251− reset_connection(con);
1252− set_bit(CLOSED, &con->state);
12531250 return -1;
12541251 }
12551252 con->auth_retry = 1;
@@ -1715,14 +1712,6 @@ more: · 459 unmodified lines
17151712
17161713 /* open the socket first? */
17171714 if (con->sock == NULL) {
1718− /*
1719− * if we were STANDBY and are reconnecting _this_
1720− * connection, bump connect_seq now. Always bump
1721− * global_seq.
1722− */
1723− if (test_and_clear_bit(STANDBY, &con->state))
1724− con->connect_seq++;
1725−
17261715 prepare_write_banner(msgr, con);
17271716 prepare_write_connect(msgr, con, 1);
17281717 prepare_read_banner(con);
@@ -1951,7 +1940,24 @@ static void con_work(struct work_struct *work) · 222 unmodified lines
19511940 work.work);
19521941
19531942 mutex_lock(&con->mutex);
1943+ if (test_and_clear_bit(BACKOFF, &con->state)) {
1944+ dout("con_work %p backing off\n", con);
1945+ if (queue_delayed_work(ceph_msgr_wq, &con->work,
1946+ round_jiffies_relative(con->delay))) {
1947+ dout("con_work %p backoff %lu\n", con, con->delay);
1948+ mutex_unlock(&con->mutex);
1949+ return;
1950+ } else {
1951+ con->ops->put(con);
1952+ dout("con_work %p FAILED to back off %lu\n", con,
1953+ con->delay);
1954+ }
1955+ }
19541956
1957+ if (test_bit(STANDBY, &con->state)) {
1958+ dout("con_work %p STANDBY\n", con);
1959+ goto done;
1960+ }
19551961 if (test_bit(CLOSED, &con->state)) { /* e.g. if we are replaced */
19561962 dout("con_work CLOSED\n");
19571963 con_close_socket(con);
@@ -2008,10 +2014,12 @@ static void ceph_fault(struct ceph_connection *con) · 50 unmodified lines
20082014 /* Requeue anything that hasn't been acked */
20092015 list_splice_init(&con->out_sent, &con->out_queue);
20102016
2011− /* If there are no messages in the queue, place the connection
2012− * in a STANDBY state (i.e., don't try to reconnect just yet). */
2013− if (list_empty(&con->out_queue) && !con->out_keepalive_pending) {
2014− dout("fault setting STANDBY\n");
2017+ /* If there are no messages queued or keepalive pending, place
2018+ * the connection in a STANDBY state */
2019+ if (list_empty(&con->out_queue) &&
2020+ !test_bit(KEEPALIVE_PENDING, &con->state)) {
2021+ dout("fault %p setting STANDBY clearing WRITE_PENDING\n", con);
2022+ clear_bit(WRITE_PENDING, &con->state);
20152023 set_bit(STANDBY, &con->state);
20162024 } else {
20172025 /* retry after a delay. */
@@ -2019,11 +2027,24 @@ static void ceph_fault(struct ceph_connection *con) · 1 unmodified line
20192027 con->delay = BASE_DELAY_INTERVAL;
20202028 else if (con->delay < MAX_DELAY_INTERVAL)
20212029 con->delay *= 2;
2022− dout("fault queueing %p delay %lu\n", con, con->delay);
20232030 con->ops->get(con);
20242031 if (queue_delayed_work(ceph_msgr_wq, &con->work,
2025− round_jiffies_relative(con->delay)) == 0)
2032+ round_jiffies_relative(con->delay))) {
2033+ dout("fault queued %p delay %lu\n", con, con->delay);
2034+ } else {
20262035 con->ops->put(con);
2036+ dout("fault failed to queue %p delay %lu, backoff\n",
2037+ con, con->delay);
2038+ /*
2039+ * In many cases we see a socket state change
2040+ * while con_work is running and end up
2041+ * queuing (non-delayed) work, such that we
2042+ * can't backoff with a delay. Set a flag so
2043+ * that when con_work restarts we schedule the
2044+ * delay then.
2045+ */
2046+ set_bit(BACKOFF, &con->state);
2047+ }
20272048 }
20282049
20292050 out_unlock:
@@ -2094,6 +2115,19 @@ void ceph_messenger_destroy(struct ceph_messenger *msgr) · 64 unmodified lines
20942115 }
20952116 EXPORT_SYMBOL(ceph_messenger_destroy);
20962117
2118+static void clear_standby(struct ceph_connection *con)
2119+{
2120+ /* come back from STANDBY? */
2121+ if (test_and_clear_bit(STANDBY, &con->state)) {
2122+ mutex_lock(&con->mutex);
2123+ dout("clear_standby %p and ++connect_seq\n", con);
2124+ con->connect_seq++;
2125+ WARN_ON(test_bit(WRITE_PENDING, &con->state));
2126+ WARN_ON(test_bit(KEEPALIVE_PENDING, &con->state));
2127+ mutex_unlock(&con->mutex);
2128+ }
2129+}
2130+
20972131 /*
20982132 * Queue up an outgoing message on the given connection.
20992133 */
@@ -2126,6 +2160,7 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) · 26 unmodified lines
21262160
21272161 /* if there wasn't anything waiting to send before, queue
21282162 * new work */
2163+ clear_standby(con);
21292164 if (test_and_set_bit(WRITE_PENDING, &con->state) == 0)
21302165 queue_con(con);
21312166 }
@@ -2191,6 +2226,8 @@ void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg) · 59 unmodified lines
21912226 */
21922227 void ceph_con_keepalive(struct ceph_connection *con)
21932228 {
2229+ dout("con_keepalive %p\n", con);
2230+ clear_standby(con);
21942231 if (test_and_set_bit(KEEPALIVE_PENDING, &con->state) == 0 &&
21952232 test_and_set_bit(WRITE_PENDING, &con->state) == 0)
21962233 queue_con(con);
net/ceph/pagevec.c+13−5
@@ -16,22 +16,30 @@ struct page **ceph_get_direct_page_vector(const char __user *data, · 15 unmodified lines
1616 int num_pages, bool write_page)
1717 {
1818 struct page **pages;
19− int rc;
19+ int got = 0;
20+ int rc = 0;
2021
2122 pages = kmalloc(sizeof(*pages) * num_pages, GFP_NOFS);
2223 if (!pages)
2324 return ERR_PTR(-ENOMEM);
2425
2526 down_read(&current->mm->mmap_sem);
26− rc = get_user_pages(current, current->mm, (unsigned long)data,
27− num_pages, write_page, 0, pages, NULL);
27+ while (got < num_pages) {
28+ rc = get_user_pages(current, current->mm,
29+ (unsigned long)data + ((unsigned long)got * PAGE_SIZE),
30+ num_pages - got, write_page, 0, pages + got, NULL);
31+ if (rc < 0)
32+ break;
33+ BUG_ON(rc == 0);
34+ got += rc;
35+ }
2836 up_read(&current->mm->mmap_sem);
29− if (rc < num_pages)
37+ if (rc < 0)
3038 goto fail;
3139 return pages;
3240
3341 fail:
34− ceph_put_page_vector(pages, rc > 0 ? rc : 0, false);
42+ ceph_put_page_vector(pages, got, false);
3543 return ERR_PTR(rc);
3644 }
3745 EXPORT_SYMBOL(ceph_get_direct_page_vector);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t