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