blkid: retport block size of a filesystem
This patch extends libblkid, so that it reports filesystem block size. When blkid returns a specific number in the BLOCK_SIZE attribute, it guarantees that all the bios submitted by the filesystem are aligned on this boundary. We need this because when we want to enable dm-integrity or dm-writecache on an existing filesystem, we need to know filesystem block size, so that dm-integrity or dm-writecache is initialized with matching block size. We could always use block size 512 for dm-integrity and dm-writecache, but that would cause metadata overhead and performance degradation. On the other hand, if we used block size 4096, it would fail if the filesystem has smaller blocksize. [kzak@redhat.com: - move vfat BLOCK_SIZE to probing function - remove unwanted debug fprintf from ZFS prober] Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
530220b6bf
commit
cd129b7d2f
|
@ -65,6 +65,8 @@ static int probe_apfs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
if (blkid_probe_set_uuid(pr, sb->uuid) < 0)
|
||||
return BLKID_PROBE_NONE;
|
||||
|
||||
blkid_probe_set_block_size(pr, le32_to_cpu(sb->block_size));
|
||||
|
||||
return BLKID_PROBE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -519,6 +519,9 @@ static int probe_befs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
blkid_probe_sprintf_uuid(pr, (unsigned char *) &volume_id,
|
||||
sizeof(volume_id), "%016" PRIx64,
|
||||
FS64_TO_CPU(volume_id, fs_le));
|
||||
|
||||
blkid_probe_set_block_size(pr, block_size);
|
||||
|
||||
return BLKID_PROBE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ static int probe_btrfs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
|
||||
blkid_probe_set_uuid(pr, bfs->fsid);
|
||||
blkid_probe_set_uuid_as(pr, bfs->dev_item.uuid, "UUID_SUB");
|
||||
blkid_probe_set_block_size(pr, le32_to_cpu(bfs->sectorsize));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -137,6 +137,8 @@ static int probe_exfat(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
blkid_probe_sprintf_version(pr, "%u.%u",
|
||||
sb->version.vermaj, sb->version.vermin);
|
||||
|
||||
blkid_probe_set_block_size(pr, BLOCK_SIZE(sb));
|
||||
|
||||
return BLKID_PROBE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,7 +170,11 @@ static int probe_exfs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
if (*xs->sb_fname != '\0')
|
||||
blkid_probe_set_label(pr, (unsigned char *) xs->sb_fname,
|
||||
sizeof(xs->sb_fname));
|
||||
|
||||
blkid_probe_set_uuid(pr, xs->sb_uuid);
|
||||
|
||||
blkid_probe_set_block_size(pr, be32_to_cpu(xs->sb_blocksize));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,9 @@ static void ext_get_info(blkid_probe pr, int ver, struct ext2_super_block *es)
|
|||
blkid_probe_sprintf_version(pr, "%u.%u",
|
||||
le32_to_cpu(es->s_rev_level),
|
||||
le16_to_cpu(es->s_minor_rev_level));
|
||||
|
||||
if (le32_to_cpu(es->s_log_block_size) < 32)
|
||||
blkid_probe_set_block_size(pr, 1024U << le32_to_cpu(es->s_log_block_size));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ static int probe_f2fs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
|
||||
blkid_probe_set_uuid(pr, sb->uuid);
|
||||
blkid_probe_sprintf_version(pr, "%u.%u", vermaj, vermin);
|
||||
if (le32_to_cpu(sb->log_blocksize) < 32)
|
||||
blkid_probe_set_block_size(pr, 1U << le32_to_cpu(sb->log_blocksize));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ static int probe_gfs2(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
sizeof(sbd->sb_locktable));
|
||||
blkid_probe_set_uuid(pr, sbd->sb_uuid);
|
||||
blkid_probe_set_version(pr, "1");
|
||||
blkid_probe_set_block_size(pr, be32_to_cpu(sbd->sb_bsize));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -241,6 +241,8 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
if (blocksize < HFSPLUS_SECTOR_SIZE)
|
||||
return 1;
|
||||
|
||||
blkid_probe_set_block_size(pr, blocksize);
|
||||
|
||||
memcpy(extents, hfsplus->cat_file.extents, sizeof(extents));
|
||||
cat_block = be32_to_cpu(extents[0].start_block);
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ static int probe_hpfs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
hbb->vol_serno[1], hbb->vol_serno[0]);
|
||||
}
|
||||
blkid_probe_sprintf_version(pr, "%u", version);
|
||||
blkid_probe_set_block_size(pr, 512);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -182,6 +182,8 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
|
||||
memcpy(label, iso->volume_id, sizeof(label));
|
||||
|
||||
blkid_probe_set_block_size(pr, 2048);
|
||||
|
||||
if (!is_str_empty(iso->system_id, sizeof(iso->system_id)))
|
||||
blkid_probe_set_id_label(pr, "SYSTEM_ID",
|
||||
iso->system_id, sizeof(iso->system_id));
|
||||
|
|
|
@ -52,6 +52,7 @@ static int probe_jfs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
if (*((char *) js->js_label) != '\0')
|
||||
blkid_probe_set_label(pr, js->js_label, sizeof(js->js_label));
|
||||
blkid_probe_set_uuid(pr, js->js_uuid);
|
||||
blkid_probe_set_block_size(pr, le32_to_cpu(js->js_bsize));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ static int probe_minix(blkid_probe pr,
|
|||
unsigned long zones, ninodes, imaps, zmaps;
|
||||
off_t firstz;
|
||||
size_t zone_size;
|
||||
unsigned block_size;
|
||||
|
||||
data = blkid_probe_get_buffer(pr, 1024,
|
||||
max(sizeof(struct minix_super_block),
|
||||
|
@ -103,6 +104,7 @@ static int probe_minix(blkid_probe pr,
|
|||
zmaps = minix_swab16(swabme, sb->s_zmap_blocks);
|
||||
firstz = minix_swab16(swabme, sb->s_firstdatazone);
|
||||
zone_size = sb->s_log_zone_size;
|
||||
block_size = 1024;
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
|
@ -114,6 +116,8 @@ static int probe_minix(blkid_probe pr,
|
|||
zmaps = minix_swab16(swabme, sb->s_zmap_blocks);
|
||||
firstz = minix_swab16(swabme, sb->s_firstdatazone);
|
||||
zone_size = sb->s_log_zone_size;
|
||||
block_size = minix_swab16(swabme, sb->s_blocksize);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -143,6 +147,7 @@ static int probe_minix(blkid_probe pr,
|
|||
return 1;
|
||||
|
||||
blkid_probe_sprintf_version(pr, "%d", version);
|
||||
blkid_probe_set_block_size(pr, block_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,6 +157,9 @@ static int probe_nilfs2(blkid_probe pr,
|
|||
(unsigned char *) &sb->s_magic))
|
||||
return 1;
|
||||
|
||||
if (le32_to_cpu(sb->s_log_block_size) < 32)
|
||||
blkid_probe_set_block_size(pr, 1024U << le32_to_cpu(sb->s_log_block_size));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -208,6 +208,8 @@ static int __probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag, int save_
|
|||
attr_off += attr_len;
|
||||
}
|
||||
|
||||
blkid_probe_set_block_size(pr, sector_size);
|
||||
|
||||
blkid_probe_sprintf_uuid(pr,
|
||||
(unsigned char *) &ns->volume_serial,
|
||||
sizeof(ns->volume_serial),
|
||||
|
|
|
@ -153,6 +153,9 @@ static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
le16_to_cpu(osb->s_major_rev_level),
|
||||
le16_to_cpu(osb->s_minor_rev_level));
|
||||
|
||||
if (le32_to_cpu(osb->s_blocksize_bits) < 32)
|
||||
blkid_probe_set_block_size(pr, 1U << le32_to_cpu(osb->s_blocksize_bits));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,8 @@ struct reiserfs_super_block {
|
|||
|
||||
struct reiser4_super_block {
|
||||
unsigned char rs4_magic[16];
|
||||
uint16_t rs4_dummy[2];
|
||||
uint8_t rs4_dummy[3];
|
||||
uint8_t rs4_blocksize;
|
||||
unsigned char rs4_uuid[16];
|
||||
unsigned char rs4_label[16];
|
||||
uint64_t rs4_dummy2;
|
||||
|
@ -73,22 +74,29 @@ static int probe_reiser(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
else
|
||||
blkid_probe_set_version(pr, "3.5");
|
||||
|
||||
blkid_probe_set_block_size(pr, blocksize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int probe_reiser4(blkid_probe pr, const struct blkid_idmag *mag)
|
||||
{
|
||||
struct reiser4_super_block *rs4;
|
||||
unsigned int blocksize;
|
||||
|
||||
rs4 = blkid_probe_get_sb(pr, mag, struct reiser4_super_block);
|
||||
if (!rs4)
|
||||
return errno ? -errno : 1;
|
||||
|
||||
blocksize = rs4->rs4_blocksize * 256;
|
||||
|
||||
if (*rs4->rs4_label)
|
||||
blkid_probe_set_label(pr, rs4->rs4_label, sizeof(rs4->rs4_label));
|
||||
blkid_probe_set_uuid(pr, rs4->rs4_uuid);
|
||||
blkid_probe_set_version(pr, "4");
|
||||
|
||||
blkid_probe_set_block_size(pr, blocksize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ static int probe_romfs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
if (*((char *) ros->ros_volume) != '\0')
|
||||
blkid_probe_set_label(pr, ros->ros_volume,
|
||||
sizeof(ros->ros_volume));
|
||||
|
||||
blkid_probe_set_block_size(pr, 1024);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@ static int probe_squashfs3(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
|
||||
blkid_probe_sprintf_version(pr, "%u.%u", vermaj, vermin);
|
||||
|
||||
blkid_probe_set_block_size(pr, 1024);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
* @APPLICATION_ID: ISO9660 application identifier
|
||||
*
|
||||
* @BOOT_SYSTEM_ID: ISO9660 boot system identifier
|
||||
*
|
||||
* @BLOCK_SIZE: block size
|
||||
*/
|
||||
|
||||
static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn);
|
||||
|
@ -553,6 +555,11 @@ int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int blkid_probe_set_block_size(blkid_probe pr, unsigned block_size)
|
||||
{
|
||||
return blkid_probe_sprintf_value(pr, "BLOCK_SIZE", "%u", block_size);
|
||||
}
|
||||
|
||||
static int blkid_probe_set_usage(blkid_probe pr, int usage)
|
||||
{
|
||||
struct blkid_chain *chn = blkid_probe_get_chain(pr);
|
||||
|
|
|
@ -108,6 +108,8 @@ extern int blkid_probe_set_id_label(blkid_probe pr, const char *name,
|
|||
extern int blkid_probe_set_utf8_id_label(blkid_probe pr, const char *name,
|
||||
const unsigned char *data, size_t len, int enc);
|
||||
|
||||
int blkid_probe_set_block_size(blkid_probe pr, unsigned block_size);
|
||||
|
||||
extern int blkid_probe_is_bitlocker(blkid_probe pr);
|
||||
extern int blkid_probe_is_ntfs(blkid_probe pr);
|
||||
|
||||
|
|
|
@ -464,6 +464,8 @@ real_blksz:
|
|||
* E.g. number 0x0150 is revision 1.50, number 0x0201 is revision 2.01. */
|
||||
blkid_probe_sprintf_version(pr, "%x.%02x", (unsigned int)(udf_rev >> 8), (unsigned int)(udf_rev & 0xFF));
|
||||
|
||||
blkid_probe_set_block_size(pr, bs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -233,6 +233,11 @@ found:
|
|||
(unsigned char *) &ufs->fs_magic))
|
||||
return 1;
|
||||
|
||||
if (!is_be)
|
||||
blkid_probe_set_block_size(pr, le32_to_cpu(ufs->fs_fsize));
|
||||
else
|
||||
blkid_probe_set_block_size(pr, be32_to_cpu(ufs->fs_fsize));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -438,6 +438,8 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
if (version)
|
||||
blkid_probe_set_version(pr, version);
|
||||
|
||||
blkid_probe_set_block_size(pr, sector_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,15 @@
|
|||
struct vxfs_super_block {
|
||||
uint32_t vs_magic;
|
||||
int32_t vs_version;
|
||||
uint32_t vs_ctime;
|
||||
uint32_t vs_cutime;
|
||||
uint32_t __unused1;
|
||||
uint32_t __unused2;
|
||||
uint32_t vs_old_logstart;
|
||||
uint32_t vs_old_logend;
|
||||
uint32_t vs_bsize;
|
||||
uint32_t vs_size;
|
||||
uint32_t vs_dsize;
|
||||
};
|
||||
|
||||
static int probe_vxfs(blkid_probe pr, const struct blkid_idmag *mag)
|
||||
|
@ -22,7 +31,13 @@ static int probe_vxfs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
if (!vxs)
|
||||
return errno ? -errno : 1;
|
||||
|
||||
blkid_probe_sprintf_version(pr, "%u", (unsigned int) vxs->vs_version);
|
||||
if (le32_to_cpu(vxs->vs_magic) == 0xa501fcf5) {
|
||||
blkid_probe_sprintf_version(pr, "%u", (unsigned int)le32_to_cpu(vxs->vs_version));
|
||||
blkid_probe_set_block_size(pr, le32_to_cpu(vxs->vs_bsize));
|
||||
} else if (be32_to_cpu(vxs->vs_magic) == 0xa501fcf5) {
|
||||
blkid_probe_sprintf_version(pr, "%u", (unsigned int)be32_to_cpu(vxs->vs_version));
|
||||
blkid_probe_set_block_size(pr, be32_to_cpu(vxs->vs_bsize));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -35,6 +50,7 @@ const struct blkid_idinfo vxfs_idinfo =
|
|||
.magics =
|
||||
{
|
||||
{ .magic = "\365\374\001\245", .len = 4, .kboff = 1 },
|
||||
{ .magic = "\245\001\374\365", .len = 4, .kboff = 8 },
|
||||
{ NULL }
|
||||
}
|
||||
};
|
||||
|
|
|
@ -173,6 +173,7 @@ static int probe_xfs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
blkid_probe_set_label(pr, (unsigned char *) xs->sb_fname,
|
||||
sizeof(xs->sb_fname));
|
||||
blkid_probe_set_uuid(pr, xs->sb_uuid);
|
||||
blkid_probe_set_block_size(pr, xs->sb_sectsize * 256);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ struct zfs_uberblock {
|
|||
|
||||
#define DATA_TYPE_UINT64 8
|
||||
#define DATA_TYPE_STRING 9
|
||||
#define DATA_TYPE_DIRECTORY 19
|
||||
|
||||
struct nvpair {
|
||||
uint32_t nvp_size;
|
||||
|
@ -60,32 +61,37 @@ struct nvuint64 {
|
|||
uint64_t nvu_value;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct nvdirectory {
|
||||
uint32_t nvd_type;
|
||||
uint32_t nvd_unknown[3];
|
||||
};
|
||||
|
||||
struct nvlist {
|
||||
uint32_t nvl_unknown[3];
|
||||
struct nvpair nvl_nvpair;
|
||||
};
|
||||
|
||||
static int zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
||||
void *value, size_t max_value_size)
|
||||
static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
||||
void *value, size_t max_value_size, unsigned directory_level)
|
||||
{
|
||||
if (strncmp(name, "name", namelen) == 0 &&
|
||||
sizeof(struct nvstring) <= max_value_size) {
|
||||
sizeof(struct nvstring) <= max_value_size &&
|
||||
!directory_level) {
|
||||
struct nvstring *nvs = value;
|
||||
uint32_t nvs_type = be32_to_cpu(nvs->nvs_type);
|
||||
uint32_t nvs_strlen = be32_to_cpu(nvs->nvs_strlen);
|
||||
|
||||
if (nvs_type != DATA_TYPE_STRING ||
|
||||
(uint64_t)nvs_strlen + sizeof(*nvs) > max_value_size)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
DBG(LOWPROBE, ul_debug("nvstring: type %u string %*s\n",
|
||||
nvs_type, nvs_strlen, nvs->nvs_string));
|
||||
|
||||
blkid_probe_set_label(pr, nvs->nvs_string, nvs_strlen);
|
||||
|
||||
return 1;
|
||||
} else if (strncmp(name, "guid", namelen) == 0 &&
|
||||
sizeof(struct nvuint64) <= max_value_size) {
|
||||
sizeof(struct nvuint64) <= max_value_size &&
|
||||
!directory_level) {
|
||||
struct nvuint64 *nvu = value;
|
||||
uint32_t nvu_type = be32_to_cpu(nvu->nvu_type);
|
||||
uint64_t nvu_value;
|
||||
|
@ -94,17 +100,16 @@ static int zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
|||
nvu_value = be64_to_cpu(nvu_value);
|
||||
|
||||
if (nvu_type != DATA_TYPE_UINT64)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
DBG(LOWPROBE, ul_debug("nvuint64: type %u value %"PRIu64"\n",
|
||||
nvu_type, nvu_value));
|
||||
|
||||
blkid_probe_sprintf_value(pr, "UUID_SUB",
|
||||
"%"PRIu64, nvu_value);
|
||||
|
||||
return 1;
|
||||
} else if (strncmp(name, "pool_guid", namelen) == 0 &&
|
||||
sizeof(struct nvuint64) <= max_value_size) {
|
||||
sizeof(struct nvuint64) <= max_value_size &&
|
||||
!directory_level) {
|
||||
struct nvuint64 *nvu = value;
|
||||
uint32_t nvu_type = be32_to_cpu(nvu->nvu_type);
|
||||
uint64_t nvu_value;
|
||||
|
@ -113,7 +118,7 @@ static int zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
|||
nvu_value = be64_to_cpu(nvu_value);
|
||||
|
||||
if (nvu_type != DATA_TYPE_UINT64)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
DBG(LOWPROBE, ul_debug("nvuint64: type %u value %"PRIu64"\n",
|
||||
nvu_type, nvu_value));
|
||||
|
@ -121,10 +126,21 @@ static int zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
|||
blkid_probe_sprintf_uuid(pr, (unsigned char *) &nvu_value,
|
||||
sizeof(nvu_value),
|
||||
"%"PRIu64, nvu_value);
|
||||
return 1;
|
||||
}
|
||||
} else if (strncmp(name, "ashift", namelen) == 0 &&
|
||||
sizeof(struct nvuint64) <= max_value_size) {
|
||||
struct nvuint64 *nvu = value;
|
||||
uint32_t nvu_type = be32_to_cpu(nvu->nvu_type);
|
||||
uint64_t nvu_value;
|
||||
|
||||
return 0;
|
||||
memcpy(&nvu_value, &nvu->nvu_value, sizeof(nvu_value));
|
||||
nvu_value = be64_to_cpu(nvu_value);
|
||||
|
||||
if (nvu_type != DATA_TYPE_UINT64)
|
||||
return;
|
||||
|
||||
if (nvu_value < 32)
|
||||
blkid_probe_set_block_size(pr, 1U << nvu_value);
|
||||
}
|
||||
}
|
||||
|
||||
static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
|
||||
|
@ -133,7 +149,7 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
|
|||
struct nvlist *nvl;
|
||||
struct nvpair *nvp;
|
||||
size_t left = 4096;
|
||||
int found = 0;
|
||||
unsigned directory_level = 0;
|
||||
|
||||
offset = (offset & ~(VDEV_LABEL_SIZE - 1)) + VDEV_LABEL_NVPAIR;
|
||||
|
||||
|
@ -152,13 +168,21 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
|
|||
nvp = &nvl->nvl_nvpair;
|
||||
left -= (unsigned char *)nvp - p; /* Already used up 12 bytes */
|
||||
|
||||
while (left > sizeof(*nvp) && nvp->nvp_size != 0 && found < 3) {
|
||||
while (left > sizeof(*nvp)) {
|
||||
uint32_t nvp_size = be32_to_cpu(nvp->nvp_size);
|
||||
uint32_t nvp_namelen = be32_to_cpu(nvp->nvp_namelen);
|
||||
uint64_t namesize = ((uint64_t)nvp_namelen + 3) & ~3;
|
||||
size_t max_value_size;
|
||||
void *value;
|
||||
|
||||
if (!nvp->nvp_size) {
|
||||
if (!directory_level)
|
||||
break;
|
||||
directory_level--;
|
||||
nvp_size = 8;
|
||||
goto cont;
|
||||
}
|
||||
|
||||
DBG(LOWPROBE, ul_debug("left %zd nvp_size %u\n",
|
||||
left, nvp_size));
|
||||
|
||||
|
@ -174,9 +198,21 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
|
|||
max_value_size = nvp_size - (namesize + sizeof(*nvp));
|
||||
value = nvp->nvp_name + namesize;
|
||||
|
||||
found += zfs_process_value(pr, nvp->nvp_name, nvp_namelen,
|
||||
value, max_value_size);
|
||||
if (sizeof(struct nvdirectory) <= max_value_size) {
|
||||
struct nvdirectory *nvu = value;
|
||||
if (be32_to_cpu(nvu->nvd_type) == DATA_TYPE_DIRECTORY) {
|
||||
nvp_size = sizeof(*nvp) + namesize + sizeof(*nvu);
|
||||
directory_level++;
|
||||
goto cont;
|
||||
}
|
||||
}
|
||||
|
||||
zfs_process_value(pr, nvp->nvp_name, nvp_namelen,
|
||||
value, max_value_size, directory_level);
|
||||
|
||||
cont:
|
||||
if (nvp_size > left)
|
||||
break;
|
||||
left -= nvp_size;
|
||||
|
||||
nvp = (struct nvpair *)((char *)nvp + nvp_size);
|
||||
|
|
Loading…
Reference in New Issue