]> git.ipfire.org Git - thirdparty/util-linux.git/blame - libblkid/src/superblocks/superblocks.c
libblkid: try LUKS2 first when probing
[thirdparty/util-linux.git] / libblkid / src / superblocks / superblocks.c
CommitLineData
0e89abac
KZ
1/*
2 * superblocks.c - reads information from filesystem and raid superblocks
3 *
4 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
5 *
6 * This file may be redistributed under the terms of the
7 * GNU Lesser General Public License.
8 */
9
ad08ae0a 10#include <inttypes.h>
0e89abac
KZ
11#include <stdio.h>
12#include <string.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <fcntl.h>
16#include <ctype.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <errno.h>
20#include <stdint.h>
21#include <stdarg.h>
22
0e89abac
KZ
23#include "superblocks.h"
24
25/**
26 * SECTION:superblocks
27 * @title: Superblocks probing
28 * @short_description: filesystems and raids superblocks probing.
29 *
455fe9a0 30 * The library API has been originally designed for superblocks probing only.
0e89abac
KZ
31 * This is reason why some *deprecated* superblock specific functions don't use
32 * '_superblocks_' namespace in the function name. Please, don't use these
33 * functions in new code.
34 *
35 * The 'superblocks' probers support NAME=value (tags) interface only. The
455fe9a0 36 * superblocks probing is enabled by default (and controlled by
0e89abac
KZ
37 * blkid_probe_enable_superblocks()).
38 *
39 * Currently supported tags:
40 *
41 * @TYPE: filesystem type
42 *
43 * @SEC_TYPE: secondary filesystem type
44 *
45 * @LABEL: filesystem label
46 *
47 * @LABEL_RAW: raw label from FS superblock
48 *
49 * @UUID: filesystem UUID (lower case)
50 *
b5d8aac1
KZ
51 * @UUID_SUB: subvolume uuid (e.g. btrfs)
52 *
c57e6f52 53 * @LOGUUID: external log UUID (e.g. xfs)
0a200255 54 *
0e89abac
KZ
55 * @UUID_RAW: raw UUID from FS superblock
56 *
57 * @EXT_JOURNAL: external journal UUID
58 *
59 * @USAGE: usage string: "raid", "filesystem", ...
60 *
61 * @VERSION: filesystem version
62 *
63 * @MOUNT: cluster mount name (?) -- ocfs only
64 *
92838067 65 * @SBMAGIC: super block magic string
0e89abac 66 *
92838067 67 * @SBMAGIC_OFFSET: offset of SBMAGIC
0e89abac 68 *
d9d9a709 69 * @FSSIZE: size of filesystem (implemented for XFS/BTRFS/Ext only)
fafe46bc 70 *
b7cb26ec
AA
71 * @FSLASTBLOCK: last fsblock/total number of fsblocks
72 *
0f447d49
AA
73 * @FSBLOCKSIZE: file system block size
74 *
fafe46bc
ZAK
75 * @SYSTEM_ID: ISO9660 system identifier
76 *
77 * @PUBLISHER_ID: ISO9660 publisher identifier
78 *
79 * @APPLICATION_ID: ISO9660 application identifier
80 *
81 * @BOOT_SYSTEM_ID: ISO9660 boot system identifier
cd129b7d 82 *
895f0b60 83 * @BLOCK_SIZE: minimal block size accessible by file system
0e89abac
KZ
84 */
85
86static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn);
87static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn);
88
89static int blkid_probe_set_usage(blkid_probe pr, int usage);
90
91
92/*
93 * Superblocks chains probing functions
94 */
95static const struct blkid_idinfo *idinfos[] =
96{
b8889c0a
LB
97 /* In case the volume is locked with OPAL we are going to get
98 * an I/O error when reading past the LUKS header, so try it
99 * first. */
100 &luks_idinfo,
101
0e89abac
KZ
102 /* RAIDs */
103 &linuxraid_idinfo,
104 &ddfraid_idinfo,
105 &iswraid_idinfo,
106 &lsiraid_idinfo,
107 &viaraid_idinfo,
108 &silraid_idinfo,
109 &nvraid_idinfo,
110 &pdcraid_idinfo,
111 &highpoint45x_idinfo,
112 &highpoint37x_idinfo,
113 &adraid_idinfo,
114 &jmraid_idinfo,
048c6291 115
a083b725 116 &bcache_idinfo,
64094168 117 &bcachefs_idinfo,
41254972 118 &bluestore_idinfo,
0834e00a 119 &drbd_idinfo,
2dc8cfb9 120 &drbdmanage_idinfo,
1e03bc3b 121 &drbdproxy_datalog_idinfo,
0e89abac
KZ
122 &lvm2_idinfo,
123 &lvm1_idinfo,
124 &snapcow_idinfo,
cbc729f0 125 &verity_hash_idinfo,
78f9ecb9 126 &integrity_idinfo,
3a1e412f 127 &vmfs_volume_idinfo,
1266fcf9 128 &ubi_idinfo,
6418cba4 129 &vdo_idinfo,
f82b085c 130 &stratis_idinfo,
136f89ce 131 &bitlocker_idinfo,
773a1fe3 132 &cs_fvault2_idinfo,
0e89abac
KZ
133
134 /* Filesystems */
135 &vfat_idinfo,
136 &swsuspend_idinfo,
137 &swap_idinfo,
138 &xfs_idinfo,
0a200255 139 &xfs_log_idinfo,
aaf13326 140 &exfs_idinfo,
0e89abac
KZ
141 &ext4dev_idinfo,
142 &ext4_idinfo,
143 &ext3_idinfo,
144 &ext2_idinfo,
145 &jbd_idinfo,
146 &reiser_idinfo,
147 &reiser4_idinfo,
148 &jfs_idinfo,
149 &udf_idinfo,
150 &iso9660_idinfo,
151 &zfs_idinfo,
152 &hfsplus_idinfo,
153 &hfs_idinfo,
154 &ufs_idinfo,
155 &hpfs_idinfo,
156 &sysv_idinfo,
157 &xenix_idinfo,
158 &ntfs_idinfo,
84992b8a 159 &refs_idinfo,
0e89abac
KZ
160 &cramfs_idinfo,
161 &romfs_idinfo,
162 &minix_idinfo,
163 &gfs_idinfo,
164 &gfs2_idinfo,
165 &ocfs_idinfo,
166 &ocfs2_idinfo,
167 &oracleasm_idinfo,
168 &vxfs_idinfo,
169 &squashfs_idinfo,
11402f5e 170 &squashfs3_idinfo,
0e89abac 171 &netware_idinfo,
4b297604 172 &btrfs_idinfo,
e38ccfcd 173 &ubifs_idinfo,
3a1e412f 174 &bfs_idinfo,
5f9fb168 175 &vmfs_fs_idinfo,
8604c255 176 &befs_idinfo,
b44b8600 177 &nilfs2_idinfo,
7dcfc89e 178 &exfat_idinfo,
b0a89709 179 &f2fs_idinfo,
084f092a 180 &mpool_idinfo,
9d691cbc 181 &apfs_idinfo,
7b2a874e 182 &zonefs_idinfo,
0945f02e 183 &erofs_idinfo,
0e89abac
KZ
184};
185
186/*
187 * Driver definition
188 */
189const struct blkid_chaindrv superblocks_drv = {
190 .id = BLKID_CHAIN_SUBLKS,
191 .name = "superblocks",
192 .dflt_enabled = TRUE,
193 .dflt_flags = BLKID_SUBLKS_DEFAULT,
194 .idinfos = idinfos,
195 .nidinfos = ARRAY_SIZE(idinfos),
196 .has_fltr = TRUE,
197 .probe = superblocks_probe,
861902b5 198 .safeprobe = superblocks_safeprobe,
0e89abac
KZ
199};
200
b7f9a38d
KZ
201/**
202 * blkid_probe_enable_superblocks:
203 * @pr: probe
204 * @enable: TRUE/FALSE
205 *
206 * Enables/disables the superblocks probing for non-binary interface.
207 *
208 * Returns: 0 on success, or -1 in case of error.
209 */
210int blkid_probe_enable_superblocks(blkid_probe pr, int enable)
211{
b7f9a38d
KZ
212 pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable;
213 return 0;
214}
215
216/**
217 * blkid_probe_set_superblocks_flags:
218 * @pr: prober
219 * @flags: BLKID_SUBLKS_* flags
220 *
221 * Sets probing flags to the superblocks prober. This function is optional, the
222 * default are BLKID_SUBLKS_DEFAULTS flags.
223 *
224 * Returns: 0 on success, or -1 in case of error.
225 */
226int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags)
227{
b7f9a38d
KZ
228 pr->chains[BLKID_CHAIN_SUBLKS].flags = flags;
229 return 0;
230}
231
232/**
233 * blkid_probe_reset_superblocks_filter:
234 * @pr: prober
235 *
236 * Resets superblocks probing filter
237 *
238 * Returns: 0 on success, or -1 in case of error.
239 */
240int blkid_probe_reset_superblocks_filter(blkid_probe pr)
241{
242 return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
243}
244
245/**
246 * blkid_probe_invert_superblocks_filter:
247 * @pr: prober
248 *
249 * Inverts superblocks probing filter
250 *
251 * Returns: 0 on success, or -1 in case of error.
252 */
253int blkid_probe_invert_superblocks_filter(blkid_probe pr)
254{
255 return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
256}
257
258/**
259 * blkid_probe_filter_superblocks_type:
260 * @pr: prober
261 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
262 * @names: NULL terminated array of probing function names (e.g. "vfat").
263 *
fd7c9e35
KZ
264 * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @names;
265 *
266 * %BLKID_FLTR_ONLYIN - probe for items which are IN @names
b7f9a38d
KZ
267 *
268 * Returns: 0 on success, or -1 in case of error.
269 */
270int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[])
271{
272 return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
273}
274
275/**
276 * blkid_probe_filter_superblocks_usage:
277 * @pr: prober
278 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
279 * @usage: BLKID_USAGE_* flags
280 *
fd7c9e35
KZ
281 * %BLKID_FLTR_NOTIN - probe for all items which are NOT IN @usage;
282 *
283 * %BLKID_FLTR_ONLYIN - probe for items which are IN @usage
b7f9a38d
KZ
284 *
285 * Returns: 0 on success, or -1 in case of error.
286 */
287int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage)
288{
289 unsigned long *fltr;
290 struct blkid_chain *chn;
538a2fe9 291 size_t i;
b7f9a38d 292
b7f9a38d
KZ
293 fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE);
294 if (!fltr)
295 return -1;
296
297 chn = &pr->chains[BLKID_CHAIN_SUBLKS];
298
299 for (i = 0; i < chn->driver->nidinfos; i++) {
300 const struct blkid_idinfo *id = chn->driver->idinfos[i];
301
302 if (id->usage & usage) {
303 if (flag & BLKID_FLTR_NOTIN)
304 blkid_bmp_set_item(chn->fltr, i);
305 } else if (flag & BLKID_FLTR_ONLYIN)
306 blkid_bmp_set_item(chn->fltr, i);
307 }
c62a6311 308 DBG(LOWPROBE, ul_debug("a new probing usage-filter initialized"));
b7f9a38d
KZ
309 return 0;
310}
311
8287d790
KZ
312/**
313 * blkid_known_fstype:
314 * @fstype: filesystem name
315 *
9e930041 316 * Returns: 1 for known filesystems, or 0 for unknown filesystem.
8287d790
KZ
317 */
318int blkid_known_fstype(const char *fstype)
319{
538a2fe9 320 size_t i;
8287d790 321
8287d790
KZ
322 for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
323 const struct blkid_idinfo *id = idinfos[i];
324 if (strcmp(id->name, fstype) == 0)
325 return 1;
326 }
327 return 0;
328}
329
70db6c7e
KZ
330/**
331 * blkid_superblocks_get_name:
332 * @idx: number >= 0
333 * @name: returns name of supported filesystem/raid (optional)
334 * @usage: returns BLKID_USAGE_* flags, (optional)
335 *
336 * Returns: -1 if @idx is out of range, or 0 on success.
337 */
338int blkid_superblocks_get_name(size_t idx, const char **name, int *usage)
339{
538a2fe9 340 if (idx < ARRAY_SIZE(idinfos)) {
70db6c7e
KZ
341 if (name)
342 *name = idinfos[idx]->name;
343 if (usage)
344 *usage = idinfos[idx]->usage;
345 return 0;
346 }
347 return -1;
348}
349
0e89abac
KZ
350/*
351 * The blkid_do_probe() backend.
352 */
353static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
354{
538a2fe9 355 size_t i;
296d96e2 356 int rc = BLKID_PROBE_NONE;
0e89abac 357
7f787ced 358 if (chn->idx < -1)
296d96e2 359 return -EINVAL;
20e1c3dc 360
af17d349 361 blkid_probe_chain_reset_values(pr, chn);
0e89abac 362
b480afca
KZ
363 if (pr->flags & BLKID_FL_NOSCAN_DEV) {
364 DBG(LOWPROBE, ul_debug("*** ignore (noscan flag)"));
d2a8b8d1 365 return BLKID_PROBE_NONE;
b480afca 366 }
0e89abac 367
b480afca 368 if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode))) {
108013b4
KZ
369 /* Ignore very very small block devices or regular files (e.g.
370 * extended partitions). Note that size of the UBI char devices
371 * is 1 byte */
b480afca 372 DBG(LOWPROBE, ul_debug("*** ignore (size <= 1024)"));
d2a8b8d1 373 return BLKID_PROBE_NONE;
b480afca 374 }
d2a8b8d1
KZ
375
376 DBG(LOWPROBE, ul_debug("--> starting probing loop [SUBLKS idx=%d]",
377 chn->idx));
108013b4 378
538a2fe9 379 i = chn->idx < 0 ? 0 : chn->idx + 1U;
0e89abac
KZ
380
381 for ( ; i < ARRAY_SIZE(idinfos); i++) {
382 const struct blkid_idinfo *id;
c76e710b 383 const struct blkid_idmag *mag = NULL;
f12cd8d1 384 uint64_t off = 0;
92838067 385
0e89abac 386 chn->idx = i;
f3464ff4 387 id = idinfos[i];
0e89abac 388
f3464ff4 389 if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) {
c62a6311 390 DBG(LOWPROBE, ul_debug("filter out: %s", id->name));
296d96e2 391 rc = BLKID_PROBE_NONE;
0e89abac 392 continue;
f3464ff4 393 }
8c2b156e 394
b9710f1f 395 if (id->minsz && (unsigned)id->minsz > pr->size) {
296d96e2 396 rc = BLKID_PROBE_NONE;
8c2b156e 397 continue; /* the device is too small */
296d96e2 398 }
8c2b156e 399
69b3afc0 400 /* don't probe for RAIDs, swap or journal on CD/DVDs */
8c2b156e 401 if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) &&
296d96e2
HR
402 blkid_probe_is_cdrom(pr)) {
403 rc = BLKID_PROBE_NONE;
108013b4 404 continue;
296d96e2 405 }
108013b4 406
69b3afc0 407 /* don't probe for RAIDs on floppies */
296d96e2
HR
408 if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr)) {
409 rc = BLKID_PROBE_NONE;
55113b15 410 continue;
296d96e2 411 }
55113b15 412
c62a6311 413 DBG(LOWPROBE, ul_debug("[%zd] %s:", i, id->name));
108013b4 414
296d96e2
HR
415 rc = blkid_probe_get_idmag(pr, id, &off, &mag);
416 if (rc < 0)
417 break;
418 if (rc != BLKID_PROBE_OK)
0e89abac
KZ
419 continue;
420
421 /* final check by probing function */
422 if (id->probefunc) {
c62a6311 423 DBG(LOWPROBE, ul_debug("\tcall probefunc()"));
296d96e2
HR
424 rc = id->probefunc(pr, mag);
425 if (rc != BLKID_PROBE_OK) {
af17d349 426 blkid_probe_chain_reset_values(pr, chn);
296d96e2
HR
427 if (rc < 0)
428 break;
0e89abac 429 continue;
0e753e3e 430 }
0e89abac
KZ
431 }
432
9e930041 433 /* all checks passed */
0e89abac 434 if (chn->flags & BLKID_SUBLKS_TYPE)
a2b9ff9a 435 rc = blkid_probe_set_value(pr, "TYPE",
47afae0c 436 (const unsigned char *) id->name,
0e89abac 437 strlen(id->name) + 1);
92838067 438
a2b9ff9a
KZ
439 if (!rc)
440 rc = blkid_probe_set_usage(pr, id->usage);
0e89abac 441
a2b9ff9a
KZ
442 if (!rc && mag)
443 rc = blkid_probe_set_magic(pr, off, mag->len,
47afae0c 444 (const unsigned char *) mag->magic);
a2b9ff9a 445 if (rc) {
af17d349 446 blkid_probe_chain_reset_values(pr, chn);
d2a8b8d1 447 DBG(LOWPROBE, ul_debug("failed to set result -- ignore"));
a2b9ff9a
KZ
448 continue;
449 }
92838067 450
c62a6311 451 DBG(LOWPROBE, ul_debug("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]",
0e89abac 452 id->name, chn->idx));
296d96e2 453 return BLKID_PROBE_OK;
0e89abac 454 }
046959cc 455
c62a6311 456 DBG(LOWPROBE, ul_debug("<-- leaving probing loop (failed=%d) [SUBLKS idx=%d]",
296d96e2
HR
457 rc, chn->idx));
458 return rc;
0e89abac
KZ
459}
460
461/*
462 * This is the same function as blkid_do_probe(), but returns only one result
9e930041 463 * (cannot be used in while()) and checks for ambivalent results (more
0e89abac
KZ
464 * filesystems on the device) -- in such case returns -2.
465 *
048c6291
SJR
466 * The function does not check for filesystems when a RAID or crypto signature
467 * is detected. The function also does not check for collision between RAIDs
468 * and crypto devices. The first detected RAID or crypto device is returned.
108013b4
KZ
469 *
470 * The function does not probe for ambivalent results on very small devices
471 * (e.g. floppies), on small devices the first detected filesystem is returned.
0e89abac
KZ
472 */
473static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
474{
6c4a7811 475 struct list_head vals;
0e89abac
KZ
476 int idx = -1;
477 int count = 0;
478 int intol = 0;
90a2086e 479 int rc;
0e89abac 480
6c4a7811
OO
481 INIT_LIST_HEAD(&vals);
482
20e1c3dc 483 if (pr->flags & BLKID_FL_NOSCAN_DEV)
d2a8b8d1 484 return BLKID_PROBE_NONE;
20e1c3dc 485
0e89abac 486 while ((rc = superblocks_probe(pr, chn)) == 0) {
108013b4 487
90a2086e 488 if (blkid_probe_is_tiny(pr) && !count)
d2a8b8d1 489 return BLKID_PROBE_OK; /* floppy or so -- returns the first result. */
90a2086e 490
0e89abac
KZ
491 count++;
492
3be35981
KZ
493 if (chn->idx >= 0 &&
494 idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO))
0e89abac 495 break;
90a2086e 496
3be35981
KZ
497 if (chn->idx >= 0 &&
498 !(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT))
0e89abac 499 intol++;
c81e7008 500
90a2086e
KZ
501 if (count == 1) {
502 /* save the first result */
af17d349 503 blkid_probe_chain_save_values(pr, chn, &vals);
90a2086e
KZ
504 idx = chn->idx;
505 }
506 }
c81e7008 507
0e89abac 508 if (rc < 0)
af17d349 509 goto done; /* error */
90a2086e 510
0e89abac 511 if (count > 1 && intol) {
c62a6311 512 DBG(LOWPROBE, ul_debug("ERROR: superblocks chain: "
0540ea54 513 "ambivalent result detected (%d filesystems)!",
0e89abac 514 count));
2bd739c9 515 rc = BLKID_PROBE_AMBIGUOUS; /* error, ambivalent result (more FS) */
af17d349
KZ
516 goto done;
517 }
518 if (!count) {
519 rc = BLKID_PROBE_NONE;
520 goto done;
0e89abac 521 }
0e89abac 522
90a2086e
KZ
523 if (idx != -1) {
524 /* restore the first result */
af17d349
KZ
525 blkid_probe_chain_reset_values(pr, chn);
526 blkid_probe_append_values_list(pr, &vals);
90a2086e
KZ
527 chn->idx = idx;
528 }
0e89abac 529
c81e7008
KZ
530 /*
531 * The RAID device could be partitioned. The problem are RAID1 devices
9e930041 532 * where the partition table is visible from underlying devices. We
c81e7008
KZ
533 * have to ignore such partition tables.
534 */
90a2086e 535 if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID)
a9eef56c 536 pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT;
c81e7008 537
af17d349
KZ
538 rc = BLKID_PROBE_OK;
539done:
540 blkid_probe_free_values_list(&vals);
541 return rc;
0e89abac
KZ
542}
543
1c1726a7
KZ
544int blkid_probe_set_version(blkid_probe pr, const char *version)
545{
546 struct blkid_chain *chn = blkid_probe_get_chain(pr);
547
548 if (chn->flags & BLKID_SUBLKS_VERSION)
549 return blkid_probe_set_value(pr, "VERSION",
47afae0c
KZ
550 (const unsigned char *) version,
551 strlen(version) + 1);
1c1726a7
KZ
552 return 0;
553}
554
fafe46bc 555
1c1726a7
KZ
556int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
557{
558 struct blkid_chain *chn = blkid_probe_get_chain(pr);
559 int rc = 0;
560
561 if (chn->flags & BLKID_SUBLKS_VERSION) {
562 va_list ap;
563
564 va_start(ap, fmt);
565 rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap);
566 va_end(ap);
567 }
568 return rc;
569}
570
cd129b7d
MP
571int blkid_probe_set_block_size(blkid_probe pr, unsigned block_size)
572{
573 return blkid_probe_sprintf_value(pr, "BLOCK_SIZE", "%u", block_size);
574}
575
0e89abac
KZ
576static int blkid_probe_set_usage(blkid_probe pr, int usage)
577{
861902b5 578 struct blkid_chain *chn = blkid_probe_get_chain(pr);
92385aaf 579 const char *u = NULL;
0e89abac 580
861902b5
KZ
581 if (!(chn->flags & BLKID_SUBLKS_USAGE))
582 return 0;
583
0e89abac
KZ
584 if (usage & BLKID_USAGE_FILESYSTEM)
585 u = "filesystem";
586 else if (usage & BLKID_USAGE_RAID)
587 u = "raid";
588 else if (usage & BLKID_USAGE_CRYPTO)
589 u = "crypto";
590 else if (usage & BLKID_USAGE_OTHER)
591 u = "other";
592 else
593 u = "unknown";
594
92385aaf
KZ
595 return blkid_probe_set_value(pr, "USAGE",
596 (const unsigned char *) u, strlen(u) + 1);
0e89abac 597}
305ad223 598
ad08ae0a
AA
599int blkid_probe_set_fssize(blkid_probe pr, uint64_t size)
600{
601 struct blkid_chain *chn = blkid_probe_get_chain(pr);
602
c9b2297e 603 if (!(chn->flags & BLKID_SUBLKS_FSINFO))
ad08ae0a
AA
604 return 0;
605
606 return blkid_probe_sprintf_value(pr, "FSSIZE", "%" PRIu64, size);
607}
608
b7cb26ec
AA
609int blkid_probe_set_fslastblock(blkid_probe pr, uint64_t lastblock)
610{
611 struct blkid_chain *chn = blkid_probe_get_chain(pr);
612
c9b2297e 613 if (!(chn->flags & BLKID_SUBLKS_FSINFO))
b7cb26ec
AA
614 return 0;
615
616 return blkid_probe_sprintf_value(pr, "FSLASTBLOCK", "%" PRIu64,
617 lastblock);
618}
619
0f447d49
AA
620int blkid_probe_set_fsblocksize(blkid_probe pr, uint32_t block_size)
621{
622 struct blkid_chain *chn = blkid_probe_get_chain(pr);
623
624 if (!(chn->flags & BLKID_SUBLKS_FSINFO))
625 return 0;
626
627 return blkid_probe_sprintf_value(pr, "FSBLOCKSIZE", "%" PRIu32,
628 block_size);
629}
630
8ace285b
TW
631int blkid_probe_set_fsendianness(blkid_probe pr, enum BLKID_ENDIANNESS endianness)
632{
633 struct blkid_chain *chn = blkid_probe_get_chain(pr);
92385aaf 634 const char *value;
8ace285b
TW
635
636 if (!(chn->flags & BLKID_SUBLKS_FSINFO))
637 return 0;
638
8ace285b
TW
639 switch (endianness) {
640 case BLKID_ENDIANNESS_LITTLE:
641 value = "LITTLE";
642 break;
643 case BLKID_ENDIANNESS_BIG:
644 value = "BIG";
645 break;
646 default:
647 return -EINVAL;
648 }
649
92385aaf
KZ
650 return blkid_probe_set_value(pr, "ENDIANNESS",
651 (const unsigned char *) value, strlen(value) + 1);
652
8ace285b
TW
653}
654
fafe46bc 655int blkid_probe_set_id_label(blkid_probe pr, const char *name,
47afae0c 656 const unsigned char *data, size_t len)
fafe46bc
ZAK
657{
658 struct blkid_chain *chn = blkid_probe_get_chain(pr);
659 struct blkid_prval *v;
6c4a7811 660 int rc = 0;
fafe46bc
ZAK
661
662 if (!(chn->flags & BLKID_SUBLKS_LABEL))
663 return 0;
664
665 v = blkid_probe_assign_value(pr, name);
666 if (!v)
6c4a7811 667 return -ENOMEM;
fafe46bc 668
6c4a7811
OO
669 rc = blkid_probe_value_set_data(v, data, len);
670 if (!rc) {
671 /* remove white spaces */
672 v->len = blkid_rtrim_whitespace(v->data) + 1;
673 if (v->len > 1)
674 v->len = blkid_ltrim_whitespace(v->data) + 1;
675 if (v->len > 1)
676 return 0;
677 }
fafe46bc 678
af17d349 679 blkid_probe_free_value(v);
6c4a7811 680 return rc;
fafe46bc 681
fafe46bc
ZAK
682}
683
1e9d4d4a 684int blkid_probe_set_utf8_id_label(blkid_probe pr, const char *name,
47afae0c 685 const unsigned char *data, size_t len, int enc)
1e9d4d4a
PR
686{
687 struct blkid_chain *chn = blkid_probe_get_chain(pr);
688 struct blkid_prval *v;
6c4a7811 689 int rc = 0;
1e9d4d4a
PR
690
691 if (!(chn->flags & BLKID_SUBLKS_LABEL))
692 return 0;
693
694 v = blkid_probe_assign_value(pr, name);
695 if (!v)
6c4a7811 696 return -ENOMEM;
1e9d4d4a 697
35c6ed61
KZ
698 v->len = (len * 3) + 1;
699 v->data = calloc(1, v->len);
6c4a7811
OO
700 if (!v->data)
701 rc = -ENOMEM;
1e9d4d4a 702
6c4a7811 703 if (!rc) {
35c6ed61 704 ul_encode_to_utf8(enc, v->data, v->len, data, len);
6c4a7811
OO
705 v->len = blkid_rtrim_whitespace(v->data) + 1;
706 if (v->len > 1)
707 v->len = blkid_ltrim_whitespace(v->data) + 1;
708 if (v->len > 1)
709 return 0;
710 }
711
af17d349 712 blkid_probe_free_value(v);
6c4a7811 713 return rc;
1e9d4d4a
PR
714}
715
47afae0c 716int blkid_probe_set_label(blkid_probe pr, const unsigned char *label, size_t len)
1c1726a7
KZ
717{
718 struct blkid_chain *chn = blkid_probe_get_chain(pr);
719 struct blkid_prval *v;
6c4a7811 720 int rc = 0;
1c1726a7
KZ
721
722 if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
6c4a7811
OO
723 (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0)
724 return rc;
725
1c1726a7
KZ
726 if (!(chn->flags & BLKID_SUBLKS_LABEL))
727 return 0;
6c4a7811 728
1c1726a7
KZ
729 v = blkid_probe_assign_value(pr, "LABEL");
730 if (!v)
6c4a7811 731 return -ENOMEM;
1c1726a7 732
6c4a7811
OO
733 rc = blkid_probe_value_set_data(v, label, len);
734 if (!rc) {
735 v->len = blkid_rtrim_whitespace(v->data) + 1;
736 if (v->len > 1)
737 return 0;
738 }
1c1726a7 739
af17d349 740 blkid_probe_free_value(v);
6c4a7811 741 return rc;
1c1726a7
KZ
742}
743
47afae0c 744int blkid_probe_set_utf8label(blkid_probe pr, const unsigned char *label,
1c1726a7
KZ
745 size_t len, int enc)
746{
747 struct blkid_chain *chn = blkid_probe_get_chain(pr);
748 struct blkid_prval *v;
6c4a7811 749 int rc = 0;
1c1726a7
KZ
750
751 if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
6c4a7811
OO
752 (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0)
753 return rc;
754
1c1726a7
KZ
755 if (!(chn->flags & BLKID_SUBLKS_LABEL))
756 return 0;
6c4a7811 757
1c1726a7
KZ
758 v = blkid_probe_assign_value(pr, "LABEL");
759 if (!v)
6c4a7811 760 return -ENOMEM;
1c1726a7 761
35c6ed61
KZ
762 v->len = (len * 3) + 1;
763 v->data = calloc(1, v->len);
6c4a7811
OO
764 if (!v->data)
765 rc = -ENOMEM;
766 if (!rc) {
35c6ed61 767 ul_encode_to_utf8(enc, v->data, v->len, label, len);
6c4a7811
OO
768 v->len = blkid_rtrim_whitespace(v->data) + 1;
769 if (v->len > 1)
770 return 0;
771 }
772
af17d349 773 blkid_probe_free_value(v);
6c4a7811 774 return rc;
1c1726a7
KZ
775}
776
47afae0c 777int blkid_probe_sprintf_uuid(blkid_probe pr, const unsigned char *uuid,
1c1726a7
KZ
778 size_t len, const char *fmt, ...)
779{
780 struct blkid_chain *chn = blkid_probe_get_chain(pr);
1c1726a7 781 va_list ap;
6c4a7811 782 int rc = 0;
1c1726a7 783
9c06cdbf 784 if (blkid_uuid_is_empty(uuid, len))
1c1726a7
KZ
785 return 0;
786
787 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
6c4a7811
OO
788 (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, len)) < 0)
789 return rc;
790
1c1726a7
KZ
791 if (!(chn->flags & BLKID_SUBLKS_UUID))
792 return 0;
793
794 va_start(ap, fmt);
795 rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap);
796 va_end(ap);
797
1c1726a7
KZ
798 return rc;
799}
800
9e930041 801/* function to set UUIDs that are in superblocks stored as strings */
47afae0c 802int blkid_probe_strncpy_uuid(blkid_probe pr, const unsigned char *str, size_t len)
1c1726a7
KZ
803{
804 struct blkid_chain *chn = blkid_probe_get_chain(pr);
805 struct blkid_prval *v;
6c4a7811 806 int rc = 0;
1c1726a7
KZ
807
808 if (str == NULL || *str == '\0')
6c4a7811
OO
809 return -EINVAL;
810
1c1726a7 811 if (!len)
47afae0c 812 len = strlen((const char *) str);
1c1726a7
KZ
813
814 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
6c4a7811
OO
815 (rc = blkid_probe_set_value(pr, "UUID_RAW", str, len)) < 0)
816 return rc;
817
1c1726a7
KZ
818 if (!(chn->flags & BLKID_SUBLKS_UUID))
819 return 0;
820
821 v = blkid_probe_assign_value(pr, "UUID");
6c4a7811
OO
822 if (!v)
823 rc= -ENOMEM;
824 if (!rc)
825 rc = blkid_probe_value_set_data(v, str, len);
826 if (!rc) {
827 v->len = blkid_rtrim_whitespace(v->data) + 1;
828 if (v->len > 1)
829 return 0;
1c1726a7 830 }
6c4a7811 831
af17d349 832 blkid_probe_free_value(v);
6c4a7811 833 return rc;
1c1726a7
KZ
834}
835
836/* default _set_uuid function to set DCE UUIDs */
47afae0c 837int blkid_probe_set_uuid_as(blkid_probe pr, const unsigned char *uuid, const char *name)
1c1726a7
KZ
838{
839 struct blkid_chain *chn = blkid_probe_get_chain(pr);
840 struct blkid_prval *v;
6c4a7811 841 int rc = 0;
1c1726a7 842
9c06cdbf 843 if (blkid_uuid_is_empty(uuid, 16))
1c1726a7
KZ
844 return 0;
845
846 if (!name) {
847 if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
6c4a7811
OO
848 (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, 16)) < 0)
849 return rc;
850
1c1726a7
KZ
851 if (!(chn->flags & BLKID_SUBLKS_UUID))
852 return 0;
853
854 v = blkid_probe_assign_value(pr, "UUID");
855 } else
856 v = blkid_probe_assign_value(pr, name);
857
6c4a7811
OO
858 if (!v)
859 return -ENOMEM;
860
b443c177 861 v->len = UUID_STR_LEN;
6c4a7811
OO
862 v->data = calloc(1, v->len);
863 if (!v->data)
864 rc = -ENOMEM;
1c1726a7 865
6c4a7811
OO
866 if (!rc) {
867 blkid_unparse_uuid(uuid, (char *) v->data, v->len);
868 return 0;
869 }
870
af17d349 871 blkid_probe_free_value(v);
6c4a7811 872 return rc;
1c1726a7
KZ
873}
874
47afae0c 875int blkid_probe_set_uuid(blkid_probe pr, const unsigned char *uuid)
1c1726a7
KZ
876{
877 return blkid_probe_set_uuid_as(pr, uuid, NULL);
878}
305ad223 879
305ad223
KZ
880/**
881 * blkid_probe_set_request:
882 * @pr: probe
883 * @flags: BLKID_PROBREQ_* (deprecated) or BLKID_SUBLKS_* flags
884 *
885 * Returns: 0 on success, or -1 in case of error.
886 *
887 * Deprecated: Use blkid_probe_set_superblocks_flags().
888 */
889int blkid_probe_set_request(blkid_probe pr, int flags)
890{
891 return blkid_probe_set_superblocks_flags(pr, flags);
892}
893
894/**
895 * blkid_probe_reset_filter:
896 * @pr: prober
897 *
898 * Returns: 0 on success, or -1 in case of error.
899 *
900 * Deprecated: Use blkid_probe_reset_superblocks_filter().
901 */
902int blkid_probe_reset_filter(blkid_probe pr)
903{
904 return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
905}
906
907/**
908 * blkid_probe_invert_filter:
909 * @pr: prober
910 *
911 * Returns: 0 on success, or -1 in case of error.
912 *
913 * Deprecated: Use blkid_probe_invert_superblocks_filter().
914 */
915int blkid_probe_invert_filter(blkid_probe pr)
916{
917 return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
918}
919
920/**
921 * blkid_probe_filter_types
922 * @pr: prober
923 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
924 * @names: NULL terminated array of probing function names (e.g. "vfat").
925 *
926 * Returns: 0 on success, or -1 in case of error.
927 *
bd64c5a3 928 * Deprecated: Use blkid_probe_filter_superblocks_type().
305ad223
KZ
929 */
930int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[])
931{
932 return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
933}
934
935/**
936 * blkid_probe_filter_usage
937 * @pr: prober
938 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
939 * @usage: BLKID_USAGE_* flags
940 *
941 * Returns: 0 on success, or -1 in case of error.
942 *
943 * Deprecated: Use blkid_probe_filter_superblocks_usage().
944 */
945int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
946{
947 return blkid_probe_filter_superblocks_usage(pr, flag, usage);
948}
949
fd7c9e35 950