Commit 8bd89ca2 authored by Linus Torvalds's avatar Linus Torvalds

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: keep reference to parent inode on ceph_dentry
  ceph: queue cap_snaps once per realm
  libceph: fix socket write error handling
  libceph: fix socket read error handling
parents b08b69a1 97d79b40
...@@ -60,6 +60,7 @@ int ceph_init_dentry(struct dentry *dentry) ...@@ -60,6 +60,7 @@ int ceph_init_dentry(struct dentry *dentry)
} }
di->dentry = dentry; di->dentry = dentry;
di->lease_session = NULL; di->lease_session = NULL;
di->parent_inode = igrab(dentry->d_parent->d_inode);
dentry->d_fsdata = di; dentry->d_fsdata = di;
dentry->d_time = jiffies; dentry->d_time = jiffies;
ceph_dentry_lru_add(dentry); ceph_dentry_lru_add(dentry);
...@@ -1033,7 +1034,7 @@ static void ceph_dentry_release(struct dentry *dentry) ...@@ -1033,7 +1034,7 @@ static void ceph_dentry_release(struct dentry *dentry)
u64 snapid = CEPH_NOSNAP; u64 snapid = CEPH_NOSNAP;
if (!IS_ROOT(dentry)) { if (!IS_ROOT(dentry)) {
parent_inode = dentry->d_parent->d_inode; parent_inode = di->parent_inode;
if (parent_inode) if (parent_inode)
snapid = ceph_snap(parent_inode); snapid = ceph_snap(parent_inode);
} }
...@@ -1058,6 +1059,8 @@ static void ceph_dentry_release(struct dentry *dentry) ...@@ -1058,6 +1059,8 @@ static void ceph_dentry_release(struct dentry *dentry)
kmem_cache_free(ceph_dentry_cachep, di); kmem_cache_free(ceph_dentry_cachep, di);
dentry->d_fsdata = NULL; dentry->d_fsdata = NULL;
} }
if (parent_inode)
iput(parent_inode);
} }
static int ceph_snapdir_d_revalidate(struct dentry *dentry, static int ceph_snapdir_d_revalidate(struct dentry *dentry,
......
...@@ -584,10 +584,14 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) ...@@ -584,10 +584,14 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
if (lastinode) if (lastinode)
iput(lastinode); iput(lastinode);
dout("queue_realm_cap_snaps %p %llx children\n", realm, realm->ino); list_for_each_entry(child, &realm->children, child_item) {
list_for_each_entry(child, &realm->children, child_item) dout("queue_realm_cap_snaps %p %llx queue child %p %llx\n",
queue_realm_cap_snaps(child); realm, realm->ino, child, child->ino);
list_del_init(&child->dirty_item);
list_add(&child->dirty_item, &realm->dirty_item);
}
list_del_init(&realm->dirty_item);
dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino); dout("queue_realm_cap_snaps %p %llx done\n", realm, realm->ino);
} }
...@@ -683,7 +687,9 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, ...@@ -683,7 +687,9 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
* queue cap snaps _after_ we've built the new snap contexts, * queue cap snaps _after_ we've built the new snap contexts,
* so that i_head_snapc can be set appropriately. * so that i_head_snapc can be set appropriately.
*/ */
list_for_each_entry(realm, &dirty_realms, dirty_item) { while (!list_empty(&dirty_realms)) {
realm = list_first_entry(&dirty_realms, struct ceph_snap_realm,
dirty_item);
queue_realm_cap_snaps(realm); queue_realm_cap_snaps(realm);
} }
......
...@@ -207,6 +207,7 @@ struct ceph_dentry_info { ...@@ -207,6 +207,7 @@ struct ceph_dentry_info {
struct dentry *dentry; struct dentry *dentry;
u64 time; u64 time;
u64 offset; u64 offset;
struct inode *parent_inode;
}; };
struct ceph_inode_xattrs_info { struct ceph_inode_xattrs_info {
......
...@@ -252,8 +252,12 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len) ...@@ -252,8 +252,12 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len)
{ {
struct kvec iov = {buf, len}; struct kvec iov = {buf, len};
struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL }; struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
int r;
return kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags); r = kernel_recvmsg(sock, &msg, &iov, 1, len, msg.msg_flags);
if (r == -EAGAIN)
r = 0;
return r;
} }
/* /*
...@@ -264,13 +268,17 @@ static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov, ...@@ -264,13 +268,17 @@ static int ceph_tcp_sendmsg(struct socket *sock, struct kvec *iov,
size_t kvlen, size_t len, int more) size_t kvlen, size_t len, int more)
{ {
struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL }; struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
int r;
if (more) if (more)
msg.msg_flags |= MSG_MORE; msg.msg_flags |= MSG_MORE;
else else
msg.msg_flags |= MSG_EOR; /* superfluous, but what the hell */ msg.msg_flags |= MSG_EOR; /* superfluous, but what the hell */
return kernel_sendmsg(sock, &msg, iov, kvlen, len); r = kernel_sendmsg(sock, &msg, iov, kvlen, len);
if (r == -EAGAIN)
r = 0;
return r;
} }
...@@ -847,6 +855,8 @@ static int write_partial_msg_pages(struct ceph_connection *con) ...@@ -847,6 +855,8 @@ static int write_partial_msg_pages(struct ceph_connection *con)
(msg->pages || msg->pagelist || msg->bio || in_trail)) (msg->pages || msg->pagelist || msg->bio || in_trail))
kunmap(page); kunmap(page);
if (ret == -EAGAIN)
ret = 0;
if (ret <= 0) if (ret <= 0)
goto out; goto out;
...@@ -1737,16 +1747,12 @@ static int try_write(struct ceph_connection *con) ...@@ -1737,16 +1747,12 @@ static int try_write(struct ceph_connection *con)
if (con->out_skip) { if (con->out_skip) {
ret = write_partial_skip(con); ret = write_partial_skip(con);
if (ret <= 0) if (ret <= 0)
goto done; goto out;
if (ret < 0) {
dout("try_write write_partial_skip err %d\n", ret);
goto done;
}
} }
if (con->out_kvec_left) { if (con->out_kvec_left) {
ret = write_partial_kvec(con); ret = write_partial_kvec(con);
if (ret <= 0) if (ret <= 0)
goto done; goto out;
} }
/* msg pages? */ /* msg pages? */
...@@ -1761,11 +1767,11 @@ static int try_write(struct ceph_connection *con) ...@@ -1761,11 +1767,11 @@ static int try_write(struct ceph_connection *con)
if (ret == 1) if (ret == 1)
goto more_kvec; /* we need to send the footer, too! */ goto more_kvec; /* we need to send the footer, too! */
if (ret == 0) if (ret == 0)
goto done; goto out;
if (ret < 0) { if (ret < 0) {
dout("try_write write_partial_msg_pages err %d\n", dout("try_write write_partial_msg_pages err %d\n",
ret); ret);
goto done; goto out;
} }
} }
...@@ -1789,10 +1795,9 @@ static int try_write(struct ceph_connection *con) ...@@ -1789,10 +1795,9 @@ static int try_write(struct ceph_connection *con)
/* Nothing to do! */ /* Nothing to do! */
clear_bit(WRITE_PENDING, &con->state); clear_bit(WRITE_PENDING, &con->state);
dout("try_write nothing else to write.\n"); dout("try_write nothing else to write.\n");
done:
ret = 0; ret = 0;
out: out:
dout("try_write done on %p\n", con); dout("try_write done on %p ret %d\n", con, ret);
return ret; return ret;
} }
...@@ -1821,19 +1826,17 @@ static int try_read(struct ceph_connection *con) ...@@ -1821,19 +1826,17 @@ static int try_read(struct ceph_connection *con)
dout("try_read connecting\n"); dout("try_read connecting\n");
ret = read_partial_banner(con); ret = read_partial_banner(con);
if (ret <= 0) if (ret <= 0)
goto done;
if (process_banner(con) < 0) {
ret = -1;
goto out; goto out;
} ret = process_banner(con);
if (ret < 0)
goto out;
} }
ret = read_partial_connect(con); ret = read_partial_connect(con);
if (ret <= 0) if (ret <= 0)
goto done;
if (process_connect(con) < 0) {
ret = -1;
goto out; goto out;
} ret = process_connect(con);
if (ret < 0)
goto out;
goto more; goto more;
} }
...@@ -1848,7 +1851,7 @@ static int try_read(struct ceph_connection *con) ...@@ -1848,7 +1851,7 @@ static int try_read(struct ceph_connection *con)
dout("skipping %d / %d bytes\n", skip, -con->in_base_pos); dout("skipping %d / %d bytes\n", skip, -con->in_base_pos);
ret = ceph_tcp_recvmsg(con->sock, buf, skip); ret = ceph_tcp_recvmsg(con->sock, buf, skip);
if (ret <= 0) if (ret <= 0)
goto done; goto out;
con->in_base_pos += ret; con->in_base_pos += ret;
if (con->in_base_pos) if (con->in_base_pos)
goto more; goto more;
...@@ -1859,7 +1862,7 @@ static int try_read(struct ceph_connection *con) ...@@ -1859,7 +1862,7 @@ static int try_read(struct ceph_connection *con)
*/ */
ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1); ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1);
if (ret <= 0) if (ret <= 0)
goto done; goto out;
dout("try_read got tag %d\n", (int)con->in_tag); dout("try_read got tag %d\n", (int)con->in_tag);
switch (con->in_tag) { switch (con->in_tag) {
case CEPH_MSGR_TAG_MSG: case CEPH_MSGR_TAG_MSG:
...@@ -1870,7 +1873,7 @@ static int try_read(struct ceph_connection *con) ...@@ -1870,7 +1873,7 @@ static int try_read(struct ceph_connection *con)
break; break;
case CEPH_MSGR_TAG_CLOSE: case CEPH_MSGR_TAG_CLOSE:
set_bit(CLOSED, &con->state); /* fixme */ set_bit(CLOSED, &con->state); /* fixme */
goto done; goto out;
default: default:
goto bad_tag; goto bad_tag;
} }
...@@ -1882,13 +1885,12 @@ static int try_read(struct ceph_connection *con) ...@@ -1882,13 +1885,12 @@ static int try_read(struct ceph_connection *con)
case -EBADMSG: case -EBADMSG:
con->error_msg = "bad crc"; con->error_msg = "bad crc";
ret = -EIO; ret = -EIO;
goto out; break;
case -EIO: case -EIO:
con->error_msg = "io error"; con->error_msg = "io error";
goto out; break;
default:
goto done;
} }
goto out;
} }
if (con->in_tag == CEPH_MSGR_TAG_READY) if (con->in_tag == CEPH_MSGR_TAG_READY)
goto more; goto more;
...@@ -1898,15 +1900,13 @@ static int try_read(struct ceph_connection *con) ...@@ -1898,15 +1900,13 @@ static int try_read(struct ceph_connection *con)
if (con->in_tag == CEPH_MSGR_TAG_ACK) { if (con->in_tag == CEPH_MSGR_TAG_ACK) {
ret = read_partial_ack(con); ret = read_partial_ack(con);
if (ret <= 0) if (ret <= 0)
goto done; goto out;
process_ack(con); process_ack(con);
goto more; goto more;
} }
done:
ret = 0;
out: out:
dout("try_read done on %p\n", con); dout("try_read done on %p ret %d\n", con, ret);
return ret; return ret;
bad_tag: bad_tag:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment