Implement mount options cache_pages and sync
Also fixup kernel arg parsing.
This commit is contained in:
parent
be3d28a255
commit
c6fe92715c
41
cbd/cbd.c
41
cbd/cbd.c
|
@ -150,6 +150,8 @@ usage(void)
|
|||
" archive: 4k pblk, 256k lblk, zlib level 9\n"
|
||||
"\n"
|
||||
" open [opts] <device> <name> Open an existing compressed device\n"
|
||||
" -c --cache-pages Set cache pages\n"
|
||||
" -s --sync Open in synchronous mode\n"
|
||||
" create [opts] <device> <name> Alias for open\n"
|
||||
" close [opts] <name> Close an opened compressed device\n"
|
||||
" check [opts] <device> Check and repair a compressed device\n"
|
||||
|
@ -295,19 +297,48 @@ do_format(int argc, char** argv)
|
|||
static int
|
||||
do_open(int argc, char** argv)
|
||||
{
|
||||
static const char short_opts[] = "c:s";
|
||||
static const struct option long_opts[] = {
|
||||
{ "cache-pages", required_argument, NULL, 'c' },
|
||||
{ "sync", no_argument, NULL, 's' },
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
char opt;
|
||||
uint64_t optval;
|
||||
uint64_t cache_pages = 0;
|
||||
bool sync = false;
|
||||
char dev[PATH_MAX];
|
||||
const char* name;
|
||||
|
||||
if (argc != 3) {
|
||||
while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
if (!parse_numeric_arg(optarg, &optval)) {
|
||||
error("Failed to parse \"%s\"\n", optarg);
|
||||
}
|
||||
if (optval < 1) {
|
||||
error("Size \"%s\" is not a valid cache size\n", optarg);
|
||||
}
|
||||
cache_pages = optval;
|
||||
break;
|
||||
case 's':
|
||||
sync = true;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if (argc - optind != 2) {
|
||||
usage();
|
||||
}
|
||||
strcpy(dev, argv[1]);
|
||||
strcpy(dev, argv[optind]);
|
||||
if (dev[0] != '/') {
|
||||
sprintf(dev, "/dev/mapper/%s", argv[1]);
|
||||
sprintf(dev, "/dev/mapper/%s", argv[optind]);
|
||||
}
|
||||
name = argv[2];
|
||||
++optind;
|
||||
name = argv[optind++];
|
||||
|
||||
cbd_open(dev, name);
|
||||
cbd_open(dev, name, cache_pages, sync);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -499,6 +499,7 @@ compress_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
int ret;
|
||||
unsigned int argn;
|
||||
u32 cache_pages = 0;
|
||||
bool sync = false;
|
||||
struct compress *c = NULL;
|
||||
u64 target_nr_pblks;
|
||||
|
||||
|
@ -513,15 +514,16 @@ compress_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
|
||||
argn = 1;
|
||||
while (argn < argc) {
|
||||
const char* arg = argv[argn++];
|
||||
const char* val = NULL;
|
||||
const char* eq = strchr(arg, '=');
|
||||
char* arg = argv[argn++];
|
||||
char* val = NULL;
|
||||
char* eq = strchr(arg, '=');
|
||||
int err;
|
||||
if (eq) {
|
||||
*eq = '\0';
|
||||
val = eq + 1;
|
||||
}
|
||||
/* XXX: Parse suffixes */
|
||||
if (!memcmp(arg, "cache_pages", 7)) {
|
||||
if (!strcmp(arg, "cache_pages")) {
|
||||
err = kstrtouint(eq + 1, 0, &cache_pages);
|
||||
if (err) {
|
||||
ti->error = "Failed to parse cache_pages";
|
||||
|
@ -529,6 +531,9 @@ compress_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "sync")) {
|
||||
sync = true;
|
||||
}
|
||||
ti->error = "Unrecognized argument";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -606,7 +611,7 @@ compress_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
if (!lbdcache_ctr(c->lc, &c->kparams, &c->kstats, cache_pages)) {
|
||||
if (!lbdcache_ctr(c->lc, &c->kparams, &c->kstats, cache_pages, sync)) {
|
||||
ti->error = "Failed to init logical block cache";
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
|
|
|
@ -533,6 +533,7 @@ lbd_data_write(struct lbd* lbd, u32 off, u32 len, const u8* buf)
|
|||
struct lbdcache
|
||||
{
|
||||
struct cbd_params* params;
|
||||
bool sync;
|
||||
void* percpu;
|
||||
struct lbatviewcache* lvc;
|
||||
struct mutex cache_lock;
|
||||
|
@ -628,7 +629,7 @@ lbdcache_free_compress_state(void* percpu, const struct cbd_params* params, int
|
|||
bool
|
||||
lbdcache_ctr(struct lbdcache* lc,
|
||||
struct compress_params* kparams, struct compress_stats* kstats,
|
||||
u32 cache_pages)
|
||||
bool sync, u32 cache_pages)
|
||||
{
|
||||
int cpu;
|
||||
struct lbd* cache;
|
||||
|
@ -637,6 +638,7 @@ lbdcache_ctr(struct lbdcache* lc,
|
|||
|
||||
memset(lc, 0, sizeof(struct lbdcache));
|
||||
lc->params = &kparams->params;
|
||||
lc->sync = sync;
|
||||
lc->percpu = alloc_percpu(void*);
|
||||
for (cpu = 0; cpu < num_online_cpus(); ++cpu) {
|
||||
if (!lbdcache_alloc_compress_state(lc->percpu, lc->params, cpu)) {
|
||||
|
@ -849,11 +851,19 @@ lbdcache_put(struct lbdcache* lc, struct lbd* lbd)
|
|||
mutex_lock(&lc->flush_lock);
|
||||
mutex_lock(&lbd->reflock);
|
||||
if (--lbd->ref == 0) {
|
||||
lbd->flush_jiffies = jiffies + COMPRESS_FLUSH_DELAY;
|
||||
lbd->ref = 1;
|
||||
list_add_tail(&lbd->flush_list, &lc->flush_head);
|
||||
if (!delayed_work_pending(&lc->flush_dwork)) {
|
||||
schedule_delayed_work(&lc->flush_dwork, COMPRESS_FLUSH_DELAY);
|
||||
if (lc->sync) {
|
||||
ret = lbd_flush(lbd);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: lbd_flush failed\n", __func__);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lbd->flush_jiffies = jiffies + COMPRESS_FLUSH_DELAY;
|
||||
lbd->ref = 1;
|
||||
list_add_tail(&lbd->flush_list, &lc->flush_head);
|
||||
if (!delayed_work_pending(&lc->flush_dwork)) {
|
||||
schedule_delayed_work(&lc->flush_dwork, COMPRESS_FLUSH_DELAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&lbd->reflock);
|
||||
|
|
|
@ -71,7 +71,8 @@ int cbd_format(const char* dev,
|
|||
uint8_t pbatshift,
|
||||
uint64_t psize, uint64_t lsize);
|
||||
int cbd_open(const char* dev,
|
||||
const char* name);
|
||||
const char* name,
|
||||
uint64_t cache_pages, bool sync);
|
||||
int cbd_close(const char* name);
|
||||
|
||||
int cbd_stats(const char* dev, struct cbd_stats* stats);
|
||||
|
|
|
@ -648,7 +648,7 @@ struct lbdcache;
|
|||
size_t lbdcache_size(void);
|
||||
bool lbdcache_ctr(struct lbdcache* lc,
|
||||
struct compress_params* kparams, struct compress_stats* kstats,
|
||||
u32 cache_pages);
|
||||
bool sync, u32 cache_pages);
|
||||
void lbdcache_dtr(struct lbdcache* lc);
|
||||
struct lbd*
|
||||
lbdcache_get(struct lbdcache* lc, u64 lblk);
|
||||
|
|
|
@ -31,11 +31,14 @@ device_logical_size(const char* dev)
|
|||
|
||||
int
|
||||
cbd_open(const char* dev,
|
||||
const char* name)
|
||||
const char* name,
|
||||
uint64_t cache_pages, bool sync)
|
||||
{
|
||||
int ret;
|
||||
struct stat st;
|
||||
uint64_t lsize;
|
||||
char optbuf[80];
|
||||
char params[256];
|
||||
struct dm_task* dmt;
|
||||
uint32_t cookie = 0;
|
||||
|
||||
|
@ -48,6 +51,15 @@ cbd_open(const char* dev,
|
|||
}
|
||||
lsize = device_logical_size(dev);
|
||||
|
||||
strcpy(params, dev);
|
||||
if (cache_pages) {
|
||||
sprintf(optbuf, " cache_pages=%lu", (unsigned long)cache_pages);
|
||||
strcat(params, optbuf);
|
||||
}
|
||||
if (sync) {
|
||||
strcat(params, " sync");
|
||||
}
|
||||
|
||||
dmt = dm_task_create(DM_DEVICE_CREATE);
|
||||
if (!dmt) {
|
||||
error("dm_task_create failed\n");
|
||||
|
@ -62,7 +74,7 @@ cbd_open(const char* dev,
|
|||
0,
|
||||
lsize / SECTOR_SIZE,
|
||||
"compress",
|
||||
dev);
|
||||
params);
|
||||
if (ret == 0) {
|
||||
error("dm_task_add_target failed\n");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue