spin_lock(&_lock);
if (type->use_count)
- DMWARN("Unregister failed: log type '%s' still in use",
- type->name);
+ DMWARN("Attempt to unregister a log type that is still in use");
else
list_del(&type->list);
unsigned bitset_uint32_count;
uint32_t *clean_bits;
uint32_t *sync_bits;
- uint32_t *recovering_bits;
+ uint32_t *recovering_bits; /* FIXME: this seems excessive */
int sync_search;
FORCESYNC, /* Force a sync to happen */
} sync;
- int failure_response;
-
/*
* Disk log fields
*/
- int log_dev_failed;
struct dm_dev *log_dev;
struct log_header header;
/*----------------------------------------------------------------
* core log constructor/destructor
*
- * argv contains 1 - 3 arguments:
- * <region_size> [[no]sync] [block_on_error]
+ * argv contains region_size followed optionally by [no]sync
*--------------------------------------------------------------*/
#define BYTE_SHIFT 3
static int create_log_context(struct dirty_log *log, struct dm_target *ti,
unsigned int argc, char **argv,
struct dm_dev *dev)
{
- int i;
enum sync sync = DEFAULTSYNC;
- int failure_response = DMLOG_IOERR_IGNORE;
+
struct log_c *lc;
uint32_t region_size;
unsigned int region_count;
size_t bitset_size, buf_size;
- if (argc < 1 || argc > 3) {
+ if (argc < 1 || argc > 2) {
DMWARN("wrong number of arguments to mirror log");
return -EINVAL;
}
- for (i = 1; i < argc; i++) {
- if (!strcmp(argv[i], "sync"))
+ if (argc > 1) {
+ if (!strcmp(argv[1], "sync"))
sync = FORCESYNC;
- else if (!strcmp(argv[i], "nosync"))
+ else if (!strcmp(argv[1], "nosync"))
sync = NOSYNC;
- else if (!strcmp(argv[i], "block_on_error"))
- failure_response = DMLOG_IOERR_BLOCK;
else {
DMWARN("unrecognised sync argument to mirror log: %s",
- argv[i]);
+ argv[1]);
return -EINVAL;
}
}
lc->region_size = region_size;
lc->region_count = region_count;
lc->sync = sync;
- lc->failure_response = failure_response;
/*
* Work out how many "unsigned long"s we need to hold the bitset.
lc->disk_header = NULL;
} else {
lc->log_dev = dev;
- lc->log_dev_failed = 0;
lc->header_location.bdev = lc->log_dev->bdev;
lc->header_location.sector = 0;
lc->recovering_bits = vmalloc(bitset_size);
if (!lc->recovering_bits) {
- DMWARN("couldn't allocate recovering bitset");
+ DMWARN("couldn't allocate sync bitset");
vfree(lc->sync_bits);
if (!dev)
vfree(lc->clean_bits);
/*----------------------------------------------------------------
* disk log constructor/destructor
*
- * argv contains 2 - 4 arguments:
- * <log_device> <region_size> [[no]sync] [block_on_error]
+ * argv contains log_device region_size followed optionally by [no]sync
*--------------------------------------------------------------*/
static int disk_ctr(struct dirty_log *log, struct dm_target *ti,
unsigned int argc, char **argv)
int r;
struct dm_dev *dev;
- if (argc < 2 || argc > 4) {
+ if (argc < 2 || argc > 3) {
DMWARN("wrong number of arguments to disk mirror log");
return -EINVAL;
}
return count;
}
-static void fail_log_device(struct log_c *lc)
-{
- if (lc->log_dev_failed)
- return;
-
- lc->log_dev_failed = 1;
- if (lc->failure_response == DMLOG_IOERR_BLOCK)
- dm_table_event(lc->ti->table);
-}
-
-static void restore_log_device(struct log_c *lc)
-{
- lc->log_dev_failed = 0;
-}
-
static int disk_resume(struct dirty_log *log)
{
int r;
struct log_c *lc = (struct log_c *) log->context;
size_t size = lc->bitset_uint32_count * sizeof(uint32_t);
- /*
- * Read the disk header, but only if we know it is good.
- * Assume the worst in the event of failure.
- */
- if (!lc->log_dev_failed && read_header(lc)) {
- DMWARN("Failed to read header on mirror log device, %s",
- lc->log_dev->name);
- fail_log_device(lc);
- lc->header.nr_regions = 0;
- }
+ /* read the disk header */
+ r = read_header(lc);
+ if (r)
+ return r;
/* set or clear any new bits -- device has grown */
if (lc->sync == NOSYNC)
lc->header.nr_regions = lc->region_count;
/* write the new header */
- r = write_header(lc);
- if (r) {
- DMWARN("Failed to write header on mirror log device, %s",
- lc->log_dev->name);
- fail_log_device(lc);
- } else
- restore_log_device(lc);
-
- return r;
+ return write_header(lc);
}
static uint32_t core_get_region_size(struct dirty_log *log)
return 0;
}
-static int disk_presuspend(struct dirty_log *log)
-{
- return 0;
-}
-
static int disk_flush(struct dirty_log *log)
{
int r;
return 0;
r = write_header(lc);
- if (r)
- fail_log_device(lc);
- else {
+ if (!r)
lc->touched = 0;
- restore_log_device(lc);
- }
+
return r;
}
char *result, unsigned int maxlen)
{
int sz = 0;
- int params;
struct log_c *lc = log->context;
switch(status) {
case STATUSTYPE_INFO:
- DMEMIT("1 core");
break;
case STATUSTYPE_TABLE:
- params = (lc->sync == DEFAULTSYNC) ? 1 : 2;
- params += (lc->failure_response == DMLOG_IOERR_BLOCK) ? 1 : 0;
-
- DMEMIT("%s %d %u ", log->type->name, params, lc->region_size);
+ DMEMIT("%s %u %u ", log->type->name,
+ lc->sync == DEFAULTSYNC ? 1 : 2, lc->region_size);
DMEMIT_SYNC;
- if (lc->failure_response == DMLOG_IOERR_BLOCK)
- DMEMIT("block_on_error ");
}
return sz;
char *result, unsigned int maxlen)
{
int sz = 0;
- int params;
+ char buffer[16];
struct log_c *lc = log->context;
switch(status) {
case STATUSTYPE_INFO:
- DMEMIT("3 disk %s %c", lc->log_dev->name,
- lc->log_dev_failed ? 'D' : 'A');
break;
case STATUSTYPE_TABLE:
- params = (lc->sync == DEFAULTSYNC) ? 2 : 3;
- params += (lc->failure_response == DMLOG_IOERR_BLOCK) ? 1 : 0;
-
- DMEMIT("%s %d %s %u ", log->type->name,
- params,
- lc->log_dev->name,
+ format_dev_t(buffer, lc->log_dev->bdev->bd_dev);
+ DMEMIT("%s %u %s %u ", log->type->name,
+ lc->sync == DEFAULTSYNC ? 2 : 3, buffer,
lc->region_size);
DMEMIT_SYNC;
- if (lc->failure_response == DMLOG_IOERR_BLOCK)
- DMEMIT("block_on_error ");
}
return sz;
}
-static int core_get_failure_response(struct dirty_log *log)
-{
- struct log_c *lc = log->context;
-
- return lc->failure_response;
-}
-
static struct dirty_log_type _core_type = {
.name = "core",
.module = THIS_MODULE,
.set_region_sync = core_set_region_sync,
.get_sync_count = core_get_sync_count,
.status = core_status,
- .get_failure_response = core_get_failure_response,
};
static struct dirty_log_type _disk_type = {
.module = THIS_MODULE,
.ctr = disk_ctr,
.dtr = disk_dtr,
- .presuspend = disk_presuspend,
- .postsuspend = disk_flush,
+ .suspend = disk_flush,
.resume = disk_resume,
.get_region_size = core_get_region_size,
.is_clean = core_is_clean,
.set_region_sync = core_set_region_sync,
.get_sync_count = core_get_sync_count,
.status = disk_status,
- .get_failure_response = core_get_failure_response,
};
int __init dm_dirty_log_init(void)