Commit 6c50e1a4 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: use complete_all and wake_up_all
  ceph: Correct obvious typo of Kconfig variable "CRYPTO_AES"
  ceph: fix dentry lease release
  ceph: fix leak of dentry in ceph_init_dentry() error path
  ceph: fix pg_mapping leak on pg_temp updates
  ceph: fix d_release dop for snapdir, snapped dentries
  ceph: avoid dcache readdir for snapdir
parents d2a97a4e 03066f23
...@@ -2,7 +2,7 @@ config CEPH_FS ...@@ -2,7 +2,7 @@ config CEPH_FS
tristate "Ceph distributed file system (EXPERIMENTAL)" tristate "Ceph distributed file system (EXPERIMENTAL)"
depends on INET && EXPERIMENTAL depends on INET && EXPERIMENTAL
select LIBCRC32C select LIBCRC32C
select CONFIG_CRYPTO_AES select CRYPTO_AES
help help
Choose Y or M here to include support for mounting the Choose Y or M here to include support for mounting the
experimental Ceph distributed file system. Ceph is an extremely experimental Ceph distributed file system. Ceph is an extremely
......
...@@ -627,7 +627,7 @@ int ceph_add_cap(struct inode *inode, ...@@ -627,7 +627,7 @@ int ceph_add_cap(struct inode *inode,
if (fmode >= 0) if (fmode >= 0)
__ceph_get_fmode(ci, fmode); __ceph_get_fmode(ci, fmode);
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
wake_up(&ci->i_cap_wq); wake_up_all(&ci->i_cap_wq);
return 0; return 0;
} }
...@@ -1181,7 +1181,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, ...@@ -1181,7 +1181,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
} }
if (wake) if (wake)
wake_up(&ci->i_cap_wq); wake_up_all(&ci->i_cap_wq);
return delayed; return delayed;
} }
...@@ -2153,7 +2153,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) ...@@ -2153,7 +2153,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
else if (flushsnaps) else if (flushsnaps)
ceph_flush_snaps(ci); ceph_flush_snaps(ci);
if (wake) if (wake)
wake_up(&ci->i_cap_wq); wake_up_all(&ci->i_cap_wq);
if (put) if (put)
iput(inode); iput(inode);
} }
...@@ -2229,7 +2229,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, ...@@ -2229,7 +2229,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
iput(inode); iput(inode);
} else if (complete_capsnap) { } else if (complete_capsnap) {
ceph_flush_snaps(ci); ceph_flush_snaps(ci);
wake_up(&ci->i_cap_wq); wake_up_all(&ci->i_cap_wq);
} }
if (drop_capsnap) if (drop_capsnap)
iput(inode); iput(inode);
...@@ -2405,7 +2405,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, ...@@ -2405,7 +2405,7 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
if (queue_invalidate) if (queue_invalidate)
ceph_queue_invalidate(inode); ceph_queue_invalidate(inode);
if (wake) if (wake)
wake_up(&ci->i_cap_wq); wake_up_all(&ci->i_cap_wq);
if (check_caps == 1) if (check_caps == 1)
ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY, ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_AUTHONLY,
...@@ -2460,7 +2460,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, ...@@ -2460,7 +2460,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
struct ceph_inode_info, struct ceph_inode_info,
i_flushing_item)->vfs_inode); i_flushing_item)->vfs_inode);
mdsc->num_cap_flushing--; mdsc->num_cap_flushing--;
wake_up(&mdsc->cap_flushing_wq); wake_up_all(&mdsc->cap_flushing_wq);
dout(" inode %p now !flushing\n", inode); dout(" inode %p now !flushing\n", inode);
if (ci->i_dirty_caps == 0) { if (ci->i_dirty_caps == 0) {
...@@ -2472,7 +2472,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid, ...@@ -2472,7 +2472,7 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
} }
} }
spin_unlock(&mdsc->cap_dirty_lock); spin_unlock(&mdsc->cap_dirty_lock);
wake_up(&ci->i_cap_wq); wake_up_all(&ci->i_cap_wq);
out: out:
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
...@@ -2984,6 +2984,7 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry, ...@@ -2984,6 +2984,7 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry,
memcpy(*p, dentry->d_name.name, dentry->d_name.len); memcpy(*p, dentry->d_name.name, dentry->d_name.len);
*p += dentry->d_name.len; *p += dentry->d_name.len;
rel->dname_seq = cpu_to_le32(di->lease_seq); rel->dname_seq = cpu_to_le32(di->lease_seq);
__ceph_mdsc_drop_dentry_lease(dentry);
} }
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);
return ret; return ret;
......
...@@ -266,6 +266,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir) ...@@ -266,6 +266,7 @@ static int ceph_readdir(struct file *filp, void *dirent, filldir_t filldir)
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
if ((filp->f_pos == 2 || fi->dentry) && if ((filp->f_pos == 2 || fi->dentry) &&
!ceph_test_opt(client, NOASYNCREADDIR) && !ceph_test_opt(client, NOASYNCREADDIR) &&
ceph_snap(inode) != CEPH_SNAPDIR &&
(ci->i_ceph_flags & CEPH_I_COMPLETE) && (ci->i_ceph_flags & CEPH_I_COMPLETE) &&
__ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) { __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
err = __dcache_readdir(filp, dirent, filldir); err = __dcache_readdir(filp, dirent, filldir);
...@@ -1013,18 +1014,22 @@ static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -1013,18 +1014,22 @@ static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd)
/* /*
* When a dentry is released, clear the dir I_COMPLETE if it was part * When a dentry is released, clear the dir I_COMPLETE if it was part
* of the current dir gen. * of the current dir gen or if this is in the snapshot namespace.
*/ */
static void ceph_dentry_release(struct dentry *dentry) static void ceph_dentry_release(struct dentry *dentry)
{ {
struct ceph_dentry_info *di = ceph_dentry(dentry); struct ceph_dentry_info *di = ceph_dentry(dentry);
struct inode *parent_inode = dentry->d_parent->d_inode; struct inode *parent_inode = dentry->d_parent->d_inode;
u64 snapid = ceph_snap(parent_inode);
if (parent_inode) { dout("dentry_release %p parent %p\n", dentry, parent_inode);
if (parent_inode && snapid != CEPH_SNAPDIR) {
struct ceph_inode_info *ci = ceph_inode(parent_inode); struct ceph_inode_info *ci = ceph_inode(parent_inode);
spin_lock(&parent_inode->i_lock); spin_lock(&parent_inode->i_lock);
if (ci->i_shared_gen == di->lease_shared_gen) { if (ci->i_shared_gen == di->lease_shared_gen ||
snapid <= CEPH_MAXSNAP) {
dout(" clearing %p complete (d_release)\n", dout(" clearing %p complete (d_release)\n",
parent_inode); parent_inode);
ci->i_ceph_flags &= ~CEPH_I_COMPLETE; ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
...@@ -1241,7 +1246,9 @@ struct dentry_operations ceph_dentry_ops = { ...@@ -1241,7 +1246,9 @@ struct dentry_operations ceph_dentry_ops = {
struct dentry_operations ceph_snapdir_dentry_ops = { struct dentry_operations ceph_snapdir_dentry_ops = {
.d_revalidate = ceph_snapdir_d_revalidate, .d_revalidate = ceph_snapdir_d_revalidate,
.d_release = ceph_dentry_release,
}; };
struct dentry_operations ceph_snap_dentry_ops = { struct dentry_operations ceph_snap_dentry_ops = {
.d_release = ceph_dentry_release,
}; };
...@@ -265,7 +265,7 @@ int ceph_release(struct inode *inode, struct file *file) ...@@ -265,7 +265,7 @@ int ceph_release(struct inode *inode, struct file *file)
kmem_cache_free(ceph_file_cachep, cf); kmem_cache_free(ceph_file_cachep, cf);
/* wake up anyone waiting for caps on this inode */ /* wake up anyone waiting for caps on this inode */
wake_up(&ci->i_cap_wq); wake_up_all(&ci->i_cap_wq);
return 0; return 0;
} }
......
...@@ -1199,8 +1199,10 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, ...@@ -1199,8 +1199,10 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
goto out; goto out;
} }
err = ceph_init_dentry(dn); err = ceph_init_dentry(dn);
if (err < 0) if (err < 0) {
dput(dn);
goto out; goto out;
}
} else if (dn->d_inode && } else if (dn->d_inode &&
(ceph_ino(dn->d_inode) != vino.ino || (ceph_ino(dn->d_inode) != vino.ino ||
ceph_snap(dn->d_inode) != vino.snap)) { ceph_snap(dn->d_inode) != vino.snap)) {
...@@ -1499,7 +1501,7 @@ void __ceph_do_pending_vmtruncate(struct inode *inode) ...@@ -1499,7 +1501,7 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
if (wrbuffer_refs == 0) if (wrbuffer_refs == 0)
ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL); ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
if (wake) if (wake)
wake_up(&ci->i_cap_wq); wake_up_all(&ci->i_cap_wq);
} }
......
...@@ -868,7 +868,7 @@ static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap, ...@@ -868,7 +868,7 @@ static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
{ {
struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_inode_info *ci = ceph_inode(inode);
wake_up(&ci->i_cap_wq); wake_up_all(&ci->i_cap_wq);
if (arg) { if (arg) {
spin_lock(&inode->i_lock); spin_lock(&inode->i_lock);
ci->i_wanted_max_size = 0; ci->i_wanted_max_size = 0;
...@@ -1564,7 +1564,7 @@ static void complete_request(struct ceph_mds_client *mdsc, ...@@ -1564,7 +1564,7 @@ static void complete_request(struct ceph_mds_client *mdsc,
if (req->r_callback) if (req->r_callback)
req->r_callback(mdsc, req); req->r_callback(mdsc, req);
else else
complete(&req->r_completion); complete_all(&req->r_completion);
} }
/* /*
...@@ -1932,7 +1932,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) ...@@ -1932,7 +1932,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
if (head->safe) { if (head->safe) {
req->r_got_safe = true; req->r_got_safe = true;
__unregister_request(mdsc, req); __unregister_request(mdsc, req);
complete(&req->r_safe_completion); complete_all(&req->r_safe_completion);
if (req->r_got_unsafe) { if (req->r_got_unsafe) {
/* /*
...@@ -1947,7 +1947,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) ...@@ -1947,7 +1947,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
/* last unsafe request during umount? */ /* last unsafe request during umount? */
if (mdsc->stopping && !__get_oldest_req(mdsc)) if (mdsc->stopping && !__get_oldest_req(mdsc))
complete(&mdsc->safe_umount_waiters); complete_all(&mdsc->safe_umount_waiters);
mutex_unlock(&mdsc->mutex); mutex_unlock(&mdsc->mutex);
goto out; goto out;
} }
...@@ -2126,7 +2126,7 @@ static void handle_session(struct ceph_mds_session *session, ...@@ -2126,7 +2126,7 @@ static void handle_session(struct ceph_mds_session *session,
pr_info("mds%d reconnect denied\n", session->s_mds); pr_info("mds%d reconnect denied\n", session->s_mds);
remove_session_caps(session); remove_session_caps(session);
wake = 1; /* for good measure */ wake = 1; /* for good measure */
complete(&mdsc->session_close_waiters); complete_all(&mdsc->session_close_waiters);
kick_requests(mdsc, mds); kick_requests(mdsc, mds);
break; break;
......
...@@ -345,7 +345,7 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc, ...@@ -345,7 +345,7 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc,
out: out:
mutex_unlock(&monc->mutex); mutex_unlock(&monc->mutex);
wake_up(&client->auth_wq); wake_up_all(&client->auth_wq);
} }
/* /*
...@@ -462,7 +462,7 @@ static void handle_statfs_reply(struct ceph_mon_client *monc, ...@@ -462,7 +462,7 @@ static void handle_statfs_reply(struct ceph_mon_client *monc,
} }
mutex_unlock(&monc->mutex); mutex_unlock(&monc->mutex);
if (req) { if (req) {
complete(&req->completion); complete_all(&req->completion);
put_generic_request(req); put_generic_request(req);
} }
return; return;
...@@ -718,7 +718,7 @@ static void handle_auth_reply(struct ceph_mon_client *monc, ...@@ -718,7 +718,7 @@ static void handle_auth_reply(struct ceph_mon_client *monc,
monc->m_auth->front_max); monc->m_auth->front_max);
if (ret < 0) { if (ret < 0) {
monc->client->auth_err = ret; monc->client->auth_err = ret;
wake_up(&monc->client->auth_wq); wake_up_all(&monc->client->auth_wq);
} else if (ret > 0) { } else if (ret > 0) {
__send_prepared_auth_request(monc, ret); __send_prepared_auth_request(monc, ret);
} else if (!was_auth && monc->auth->ops->is_authenticated(monc->auth)) { } else if (!was_auth && monc->auth->ops->is_authenticated(monc->auth)) {
......
...@@ -862,12 +862,12 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, ...@@ -862,12 +862,12 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
if (req->r_callback) if (req->r_callback)
req->r_callback(req, msg); req->r_callback(req, msg);
else else
complete(&req->r_completion); complete_all(&req->r_completion);
if (flags & CEPH_OSD_FLAG_ONDISK) { if (flags & CEPH_OSD_FLAG_ONDISK) {
if (req->r_safe_callback) if (req->r_safe_callback)
req->r_safe_callback(req, msg); req->r_safe_callback(req, msg);
complete(&req->r_safe_completion); /* fsync waiter */ complete_all(&req->r_safe_completion); /* fsync waiter */
} }
done: done:
...@@ -1083,7 +1083,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg) ...@@ -1083,7 +1083,7 @@ void ceph_osdc_handle_map(struct ceph_osd_client *osdc, struct ceph_msg *msg)
if (newmap) if (newmap)
kick_requests(osdc, NULL); kick_requests(osdc, NULL);
up_read(&osdc->map_sem); up_read(&osdc->map_sem);
wake_up(&osdc->client->auth_wq); wake_up_all(&osdc->client->auth_wq);
return; return;
bad: bad:
......
...@@ -831,12 +831,13 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, ...@@ -831,12 +831,13 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
/* remove any? */ /* remove any? */
while (rbp && pgid_cmp(rb_entry(rbp, struct ceph_pg_mapping, while (rbp && pgid_cmp(rb_entry(rbp, struct ceph_pg_mapping,
node)->pgid, pgid) <= 0) { node)->pgid, pgid) <= 0) {
struct rb_node *cur = rbp; struct ceph_pg_mapping *cur =
rb_entry(rbp, struct ceph_pg_mapping, node);
rbp = rb_next(rbp); rbp = rb_next(rbp);
dout(" removed pg_temp %llx\n", dout(" removed pg_temp %llx\n", *(u64 *)&cur->pgid);
*(u64 *)&rb_entry(cur, struct ceph_pg_mapping, rb_erase(&cur->node, &map->pg_temp);
node)->pgid); kfree(cur);
rb_erase(cur, &map->pg_temp);
} }
if (pglen) { if (pglen) {
...@@ -852,19 +853,22 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, ...@@ -852,19 +853,22 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
for (j = 0; j < pglen; j++) for (j = 0; j < pglen; j++)
pg->osds[j] = ceph_decode_32(p); pg->osds[j] = ceph_decode_32(p);
err = __insert_pg_mapping(pg, &map->pg_temp); err = __insert_pg_mapping(pg, &map->pg_temp);
if (err) if (err) {
kfree(pg);
goto bad; goto bad;
}
dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid, dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid,
pglen); pglen);
} }
} }
while (rbp) { while (rbp) {
struct rb_node *cur = rbp; struct ceph_pg_mapping *cur =
rb_entry(rbp, struct ceph_pg_mapping, node);
rbp = rb_next(rbp); rbp = rb_next(rbp);
dout(" removed pg_temp %llx\n", dout(" removed pg_temp %llx\n", *(u64 *)&cur->pgid);
*(u64 *)&rb_entry(cur, struct ceph_pg_mapping, rb_erase(&cur->node, &map->pg_temp);
node)->pgid); kfree(cur);
rb_erase(cur, &map->pg_temp);
} }
/* ignore the rest */ /* ignore the rest */
......
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