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
This commit is contained in:
Коммит
8bd89ca220
|
@ -60,6 +60,7 @@ int ceph_init_dentry(struct dentry *dentry)
|
|||
}
|
||||
di->dentry = dentry;
|
||||
di->lease_session = NULL;
|
||||
di->parent_inode = igrab(dentry->d_parent->d_inode);
|
||||
dentry->d_fsdata = di;
|
||||
dentry->d_time = jiffies;
|
||||
ceph_dentry_lru_add(dentry);
|
||||
|
@ -1033,7 +1034,7 @@ static void ceph_dentry_release(struct dentry *dentry)
|
|||
u64 snapid = CEPH_NOSNAP;
|
||||
|
||||
if (!IS_ROOT(dentry)) {
|
||||
parent_inode = dentry->d_parent->d_inode;
|
||||
parent_inode = di->parent_inode;
|
||||
if (parent_inode)
|
||||
snapid = ceph_snap(parent_inode);
|
||||
}
|
||||
|
@ -1058,6 +1059,8 @@ static void ceph_dentry_release(struct dentry *dentry)
|
|||
kmem_cache_free(ceph_dentry_cachep, di);
|
||||
dentry->d_fsdata = NULL;
|
||||
}
|
||||
if (parent_inode)
|
||||
iput(parent_inode);
|
||||
}
|
||||
|
||||
static int ceph_snapdir_d_revalidate(struct dentry *dentry,
|
||||
|
|
|
@ -584,10 +584,14 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm)
|
|||
if (lastinode)
|
||||
iput(lastinode);
|
||||
|
||||
dout("queue_realm_cap_snaps %p %llx children\n", realm, realm->ino);
|
||||
list_for_each_entry(child, &realm->children, child_item)
|
||||
queue_realm_cap_snaps(child);
|
||||
list_for_each_entry(child, &realm->children, child_item) {
|
||||
dout("queue_realm_cap_snaps %p %llx queue child %p %llx\n",
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -683,7 +687,9 @@ more:
|
|||
* queue cap snaps _after_ we've built the new snap contexts,
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -207,6 +207,7 @@ struct ceph_dentry_info {
|
|||
struct dentry *dentry;
|
||||
u64 time;
|
||||
u64 offset;
|
||||
struct inode *parent_inode;
|
||||
};
|
||||
|
||||
struct ceph_inode_xattrs_info {
|
||||
|
|
|
@ -252,8 +252,12 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len)
|
|||
{
|
||||
struct kvec iov = {buf, len};
|
||||
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,
|
|||
size_t kvlen, size_t len, int more)
|
||||
{
|
||||
struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL };
|
||||
int r;
|
||||
|
||||
if (more)
|
||||
msg.msg_flags |= MSG_MORE;
|
||||
else
|
||||
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)
|
|||
(msg->pages || msg->pagelist || msg->bio || in_trail))
|
||||
kunmap(page);
|
||||
|
||||
if (ret == -EAGAIN)
|
||||
ret = 0;
|
||||
if (ret <= 0)
|
||||
goto out;
|
||||
|
||||
|
@ -1737,16 +1747,12 @@ more_kvec:
|
|||
if (con->out_skip) {
|
||||
ret = write_partial_skip(con);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
if (ret < 0) {
|
||||
dout("try_write write_partial_skip err %d\n", ret);
|
||||
goto done;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
if (con->out_kvec_left) {
|
||||
ret = write_partial_kvec(con);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* msg pages? */
|
||||
|
@ -1761,11 +1767,11 @@ more_kvec:
|
|||
if (ret == 1)
|
||||
goto more_kvec; /* we need to send the footer, too! */
|
||||
if (ret == 0)
|
||||
goto done;
|
||||
goto out;
|
||||
if (ret < 0) {
|
||||
dout("try_write write_partial_msg_pages err %d\n",
|
||||
ret);
|
||||
goto done;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1789,10 +1795,9 @@ do_next:
|
|||
/* Nothing to do! */
|
||||
clear_bit(WRITE_PENDING, &con->state);
|
||||
dout("try_write nothing else to write.\n");
|
||||
done:
|
||||
ret = 0;
|
||||
out:
|
||||
dout("try_write done on %p\n", con);
|
||||
dout("try_write done on %p ret %d\n", con, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1821,19 +1826,17 @@ more:
|
|||
dout("try_read connecting\n");
|
||||
ret = read_partial_banner(con);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
if (process_banner(con) < 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
ret = process_banner(con);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
ret = read_partial_connect(con);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
if (process_connect(con) < 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
ret = process_connect(con);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
goto more;
|
||||
}
|
||||
|
||||
|
@ -1848,7 +1851,7 @@ more:
|
|||
dout("skipping %d / %d bytes\n", skip, -con->in_base_pos);
|
||||
ret = ceph_tcp_recvmsg(con->sock, buf, skip);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
goto out;
|
||||
con->in_base_pos += ret;
|
||||
if (con->in_base_pos)
|
||||
goto more;
|
||||
|
@ -1859,7 +1862,7 @@ more:
|
|||
*/
|
||||
ret = ceph_tcp_recvmsg(con->sock, &con->in_tag, 1);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
goto out;
|
||||
dout("try_read got tag %d\n", (int)con->in_tag);
|
||||
switch (con->in_tag) {
|
||||
case CEPH_MSGR_TAG_MSG:
|
||||
|
@ -1870,7 +1873,7 @@ more:
|
|||
break;
|
||||
case CEPH_MSGR_TAG_CLOSE:
|
||||
set_bit(CLOSED, &con->state); /* fixme */
|
||||
goto done;
|
||||
goto out;
|
||||
default:
|
||||
goto bad_tag;
|
||||
}
|
||||
|
@ -1882,13 +1885,12 @@ more:
|
|||
case -EBADMSG:
|
||||
con->error_msg = "bad crc";
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
break;
|
||||
case -EIO:
|
||||
con->error_msg = "io error";
|
||||
goto out;
|
||||
default:
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
if (con->in_tag == CEPH_MSGR_TAG_READY)
|
||||
goto more;
|
||||
|
@ -1898,15 +1900,13 @@ more:
|
|||
if (con->in_tag == CEPH_MSGR_TAG_ACK) {
|
||||
ret = read_partial_ack(con);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
goto out;
|
||||
process_ack(con);
|
||||
goto more;
|
||||
}
|
||||
|
||||
done:
|
||||
ret = 0;
|
||||
out:
|
||||
dout("try_read done on %p\n", con);
|
||||
dout("try_read done on %p ret %d\n", con, ret);
|
||||
return ret;
|
||||
|
||||
bad_tag:
|
||||
|
|
Загрузка…
Ссылка в новой задаче