/- respond to control-c on slow/hung mount
v0.12
+- mapping_set_error on failed writepage
+- document correct debugfs mount point
+- clean up layout ioctls
+- fix bad kmalloc
+- use mempool for write path allocations where appropriate
+
+
- osdmap: allow explicit pg 'override' mappings
- http gw
snapc, do_sync,
ci->i_truncate_seq,
ci->i_truncate_size,
- &inode->i_mtime);
+ &inode->i_mtime, true);
max_pages = req->r_num_pages;
rc = alloc_page_vec(client, req);
ci->i_snap_realm->cached_context,
do_sync,
ci->i_truncate_seq, ci->i_truncate_size,
- &mtime);
+ &mtime, false);
if (IS_ERR(req))
return PTR_ERR(req);
ceph_release_page_vector(req->r_pages,
req->r_num_pages);
ceph_put_snap_context(req->r_snapc);
- kfree(req);
+ if (req->r_mempool)
+ mempool_free(req, req->r_osdc->req_mempool);
+ else
+ kfree(req);
}
}
int do_sync,
u32 truncate_seq,
u64 truncate_size,
- struct timespec *mtime)
+ struct timespec *mtime,
+ bool use_mempool)
{
struct ceph_osd_request *req;
struct ceph_msg *msg;
int i;
u64 prevofs;
- req = kzalloc(sizeof(*req), GFP_NOFS);
+ if (use_mempool) {
+ req = mempool_alloc(osdc->req_mempool, GFP_NOFS);
+ memset(req, 0, sizeof(*req));
+ } else {
+ req = kzalloc(sizeof(*req), GFP_NOFS);
+ }
if (req == NULL)
return ERR_PTR(-ENOMEM);
+ req->r_osdc = osdc;
+ req->r_mempool = use_mempool;
atomic_set(&req->r_ref, 1);
init_completion(&req->r_completion);
init_completion(&req->r_safe_completion);
/*
* init, shutdown
*/
-void ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
+int ceph_osdc_init(struct ceph_osd_client *osdc, struct ceph_client *client)
{
dout("init\n");
osdc->client = client;
osdc->requests = RB_ROOT;
osdc->num_requests = 0;
INIT_DELAYED_WORK(&osdc->timeout_work, handle_timeout);
+
+ osdc->req_mempool = mempool_create_kmalloc_pool(10,
+ sizeof(struct ceph_osd_request));
+ if (!osdc->req_mempool)
+ return -ENOMEM;
+ return 0;
}
void ceph_osdc_stop(struct ceph_osd_client *osdc)
ceph_osdmap_destroy(osdc->osdmap);
osdc->osdmap = NULL;
}
+ mempool_destroy(osdc->req_mempool);
}
/*
vino.snap, off, len);
req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
- NULL, 0, truncate_seq, truncate_size, NULL);
+ NULL, 0, truncate_seq, truncate_size, NULL,
+ false);
if (IS_ERR(req))
return PTR_ERR(req);
flags | CEPH_OSD_FLAG_ONDISK |
CEPH_OSD_FLAG_WRITE,
snapc, do_sync,
- truncate_seq, truncate_size, mtime);
+ truncate_seq, truncate_size, mtime,
+ true);
if (IS_ERR(req))
return PTR_ERR(req);
#include <linux/radix-tree.h>
#include <linux/completion.h>
+#include <linux/mempool.h>
#include "types.h"
#include "osdmap.h"
struct ceph_msg;
struct ceph_snap_context;
struct ceph_osd_request;
+struct ceph_osd_client;
/*
* completion callback for async writepages
int r_flags; /* any additional flags for the osd */
int r_aborted; /* set if we cancel this request */
+ struct ceph_osd_client *r_osdc;
atomic_t r_ref;
+ bool r_mempool;
struct completion r_completion, r_safe_completion;
ceph_osdc_callback_t r_callback, r_safe_callback;
struct ceph_eversion r_reassert_version;
int num_requests;
struct delayed_work timeout_work;
struct dentry *debugfs_file;
+
+ mempool_t *req_mempool;
};
-extern void ceph_osdc_init(struct ceph_osd_client *osdc,
- struct ceph_client *client);
+extern int ceph_osdc_init(struct ceph_osd_client *osdc,
+ struct ceph_client *client);
extern void ceph_osdc_stop(struct ceph_osd_client *osdc);
extern void ceph_osdc_handle_reset(struct ceph_osd_client *osdc,
struct ceph_snap_context *snapc,
int do_sync, u32 truncate_seq,
u64 truncate_size,
- struct timespec *mtime);
+ struct timespec *mtime,
+ bool use_mempool);
static inline void ceph_osdc_get_request(struct ceph_osd_request *req)
{
client->signed_ticket = NULL;
client->signed_ticket_len = 0;
+ err = -ENOMEM;
client->wb_wq = create_workqueue("ceph-writeback");
if (client->wb_wq == NULL)
goto fail;
/* subsystems */
err = ceph_monc_init(&client->monc, client);
if (err < 0)
- return ERR_PTR(err);
+ goto fail;
+ err = ceph_osdc_init(&client->osdc, client);
+ if (err < 0)
+ goto fail;
ceph_mdsc_init(&client->mdsc, client);
- ceph_osdc_init(&client->osdc, client);
-
return client;
fail:
- return ERR_PTR(-ENOMEM);
+ return ERR_PTR(err);
}
static void ceph_destroy_client(struct ceph_client *client)