bcacheadm: fix status and query-devs

Previously we were reading old superblocks stuck in the cache.
Pass in O_DIRECT when opening the device. This requires that
the dest buffer be memaligned.
If we are unable to read the entire superblock then increase
the buffer and try again.

Also since we now have to alloc the sb, make sure it is freed
everywhere in bcacheadm.

Fixes DAT-1609 DAT-1626

Change-Id: I04b5337b992a8569809835b5826a2656df753214
Signed-off-by: Jacob Malevich <jam@daterainc.com>
This commit is contained in:
Jacob Malevich 2014-12-18 19:19:21 -08:00 committed by Raghu Krishnamurthy
parent 45d1cb0527
commit 474f0889f0
2 changed files with 31 additions and 15 deletions

View File

@ -906,30 +906,39 @@ void sysfs_attr_list() {
struct cache_sb *query_dev(char *dev, bool force_csum,
bool print_sb, bool uuid_only, char *dev_uuid)
{
struct cache_sb sb_stack, *sb = &sb_stack;
size_t bytes = sizeof(*sb);
size_t bytes = 4096;
struct cache_sb *sb = aligned_alloc(bytes, bytes);
int fd = open(dev, O_RDONLY);
int fd = open(dev, O_RDONLY|O_DIRECT);
if (fd < 0) {
printf("Can't open dev %s: %s\n", dev, strerror(errno));
return NULL;
}
if (pread(fd, sb, bytes, SB_START) != bytes) {
fprintf(stderr, "Couldn't read\n");
return NULL;
}
if (sb->keys) {
bytes = sizeof(*sb) + sb->keys * sizeof(uint64_t);
sb = malloc(bytes);
if (pread(fd, sb, bytes, SB_START) != bytes) {
fprintf(stderr, "Couldn't read\n");
while (true) {
int ret = pread(fd, sb, bytes, SB_START);
if (ret < 0) {
fprintf(stderr, "Couldn't read superblock: %s\n",
strerror(errno));
close(fd);
free(sb);
return NULL;
} else if (bytes > sizeof(sb) + sb->keys * sizeof(u64)) {
/* We read the whole superblock */
break;
}
/*
* otherwise double the size of our dest
* and read again
*/
free(sb);
bytes *= 2;
sb = aligned_alloc(4096, bytes);
}
close(fd);
if(uuid_only) {
show_uuid_only(sb, dev_uuid);
return sb;
@ -1061,6 +1070,8 @@ char *find_matching_uuid(char *stats_dir, char *subdir, const char *stats_dev_uu
sb = query_dev(devname, false, false, true, dev_uuid);
if(!sb)
return err;
else
free(sb);
if(!strcmp(stats_dev_uuid, dev_uuid)) {
strcat(subdir, intbuf);

View File

@ -562,6 +562,7 @@ int bcache_query_devs(NihCommand *command, char *const *args)
set_uuid_str,
clus_uuid);
}
free(sb);
}
return 0;
@ -585,7 +586,8 @@ int bcache_status(NihCommand *command, char *const *args)
seq = sb->seq;
seq_sb = sb;
nr_in_set = sb->nr_in_set;
}
} else
free(sb);
}
if(!seq_sb)
@ -604,6 +606,9 @@ int bcache_status(NihCommand *command, char *const *args)
CACHE_TIER(m));
}
if(seq_sb)
free(seq_sb);
return 0;
}