Coverage Report

Created: 2025-11-25 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/util-linux/libblkid/src/superblocks/superblocks.c
Line
Count
Source
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
10
#include <inttypes.h>
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
23
#include "superblocks.h"
24
25
/**
26
 * SECTION:superblocks
27
 * @title: Superblocks probing
28
 * @short_description: filesystems and raids superblocks probing.
29
 *
30
 * The library API has been originally designed for superblocks probing only.
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
36
 * superblocks probing is enabled by default (and controlled by
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
 *
51
 * @UUID_SUB: pool member UUID or device item UUID, etc. (e.g., zfs, btrfs, ...)
52
 *
53
 * @LOGUUID: external log UUID (e.g. xfs)
54
 *
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
 *
65
 * @SBMAGIC: super block magic string
66
 *
67
 * @SBMAGIC_OFFSET: offset of SBMAGIC
68
 *
69
 * @FSSIZE: size of filesystem (implemented for XFS/BTRFS/Ext only)
70
 *
71
 * @FSLASTBLOCK: last fsblock/total number of fsblocks
72
 *
73
 * @FSBLOCKSIZE: file system block size
74
 *
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
82
 *
83
 * @BLOCK_SIZE: minimal block size accessible by file system
84
 */
85
86
static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn);
87
static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn);
88
89
static int blkid_probe_set_usage(blkid_probe pr, int usage);
90
91
92
/*
93
 * Superblocks chains probing functions
94
 */
95
static const struct blkid_idinfo *idinfos[] =
96
{
97
  /* First, as access to locked OPAL region triggers IO errors */
98
  &luks_opal_idinfo,
99
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,
113
114
  &bcache_idinfo,
115
  &bcachefs_idinfo,
116
  &bluestore_idinfo,
117
  &drbd_idinfo,
118
  &drbdmanage_idinfo,
119
  &drbdproxy_datalog_idinfo,
120
  &lvm2_idinfo,
121
  &lvm1_idinfo,
122
  &snapcow_idinfo,
123
  &verity_hash_idinfo,
124
  &integrity_idinfo,
125
  &luks_idinfo,
126
  &vmfs_volume_idinfo,
127
  &ubi_idinfo,
128
  &vdo_idinfo,
129
  &stratis_idinfo,
130
  &bitlocker_idinfo,
131
  &cs_fvault2_idinfo,
132
133
  /* Filesystems */
134
  &vfat_idinfo,
135
  &swsuspend_idinfo,
136
  &swap_idinfo,
137
  &xfs_idinfo,
138
  &xfs_log_idinfo,
139
  &exfs_idinfo,
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,
158
  &refs_idinfo,
159
  &cramfs_idinfo,
160
  &romfs_idinfo,
161
  &scoutfs_meta_idinfo,
162
  &scoutfs_data_idinfo,
163
  &minix_idinfo,
164
  &gfs_idinfo,
165
  &gfs2_idinfo,
166
  &ocfs_idinfo,
167
  &ocfs2_idinfo,
168
  &oracleasm_idinfo,
169
  &vxfs_idinfo,
170
  &squashfs_idinfo,
171
  &squashfs3_idinfo,
172
  &netware_idinfo,
173
  &btrfs_idinfo,
174
  &ubifs_idinfo,
175
  &bfs_idinfo,
176
  &vmfs_fs_idinfo,
177
  &befs_idinfo,
178
  &nilfs2_idinfo,
179
  &exfat_idinfo,
180
  &f2fs_idinfo,
181
  &mpool_idinfo,
182
  &apfs_idinfo,
183
  &zonefs_idinfo,
184
  &erofs_idinfo,
185
};
186
187
/*
188
 * Driver definition
189
 */
190
const 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,
199
  .safeprobe    = superblocks_safeprobe,
200
};
201
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
 */
211
int blkid_probe_enable_superblocks(blkid_probe pr, int enable)
212
5.27k
{
213
5.27k
  pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable;
214
5.27k
  return 0;
215
5.27k
}
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
 */
227
int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags)
228
5.27k
{
229
5.27k
  pr->chains[BLKID_CHAIN_SUBLKS].flags = flags;
230
5.27k
  return 0;
231
5.27k
}
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
 */
241
int blkid_probe_reset_superblocks_filter(blkid_probe pr)
242
0
{
243
0
  return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
244
0
}
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
 */
254
int blkid_probe_invert_superblocks_filter(blkid_probe pr)
255
0
{
256
0
  return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
257
0
}
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
 *
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
268
 *
269
 * Returns: 0 on success, or -1 in case of error.
270
 */
271
int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[])
272
5.27k
{
273
5.27k
  return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
274
5.27k
}
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
 *
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
285
 *
286
 * Returns: 0 on success, or -1 in case of error.
287
 */
288
int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage)
289
0
{
290
0
  unsigned long *fltr;
291
0
  struct blkid_chain *chn;
292
0
  size_t i;
293
294
0
  fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE);
295
0
  if (!fltr)
296
0
    return -1;
297
298
0
  chn = &pr->chains[BLKID_CHAIN_SUBLKS];
299
300
0
  for (i = 0; i < chn->driver->nidinfos; i++) {
301
0
    const struct blkid_idinfo *id = chn->driver->idinfos[i];
302
303
0
    if (id->usage & usage) {
304
0
      if (flag & BLKID_FLTR_NOTIN)
305
0
        blkid_bmp_set_item(chn->fltr, i);
306
0
    } else if (flag & BLKID_FLTR_ONLYIN)
307
0
      blkid_bmp_set_item(chn->fltr, i);
308
0
  }
309
0
  DBG(LOWPROBE, ul_debug("a new probing usage-filter initialized"));
310
0
  return 0;
311
0
}
312
313
/**
314
 * blkid_known_fstype:
315
 * @fstype: filesystem name
316
 *
317
 * Returns: 1 for known filesystems, or 0 for unknown filesystem.
318
 */
319
int blkid_known_fstype(const char *fstype)
320
0
{
321
0
  size_t i;
322
323
0
  for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
324
0
    const struct blkid_idinfo *id = idinfos[i];
325
0
    if (strcmp(id->name, fstype) == 0)
326
0
      return 1;
327
0
  }
328
0
  return 0;
329
0
}
330
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
 */
339
int blkid_superblocks_get_name(size_t idx, const char **name, int *usage)
340
0
{
341
0
  if (idx < ARRAY_SIZE(idinfos)) {
342
0
    if (name)
343
0
      *name = idinfos[idx]->name;
344
0
    if (usage)
345
0
      *usage = idinfos[idx]->usage;
346
0
    return 0;
347
0
  }
348
0
  return -1;
349
0
}
350
351
/*
352
 * The blkid_do_probe() backend.
353
 */
354
static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
355
7.48k
{
356
7.48k
  size_t i;
357
7.48k
  int rc = BLKID_PROBE_NONE;
358
359
7.48k
  if (chn->idx < -1)
360
0
    return -EINVAL;
361
362
7.48k
  blkid_probe_chain_reset_values(pr, chn);
363
364
7.48k
  if (pr->flags & BLKID_FL_NOSCAN_DEV) {
365
0
    DBG(LOWPROBE, ul_debug("*** ignore (noscan flag)"));
366
0
    return BLKID_PROBE_NONE;
367
0
  }
368
369
7.48k
  if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode))) {
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 */
373
0
    DBG(LOWPROBE, ul_debug("*** ignore (size <= 1024)"));
374
0
    return BLKID_PROBE_NONE;
375
0
  }
376
377
7.48k
  DBG(LOWPROBE, ul_debug("--> starting probing loop [SUBLKS idx=%d]",
378
7.48k
    chn->idx));
379
380
7.48k
  i = chn->idx < 0 ? 0 : chn->idx + 1U;
381
382
433k
  for ( ; i < ARRAY_SIZE(idinfos); i++) {
383
428k
    const struct blkid_idinfo *id;
384
428k
    const struct blkid_idmag *mag = NULL;
385
428k
    uint64_t off = 0;
386
387
428k
    chn->idx = i;
388
428k
    id = idinfos[i];
389
390
428k
    if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) {
391
10.5k
      DBG(LOWPROBE, ul_debug("filter out: %s", id->name));
392
10.5k
      rc = BLKID_PROBE_NONE;
393
10.5k
      continue;
394
10.5k
    }
395
396
418k
    if (id->minsz && (unsigned)id->minsz > pr->size) {
397
15.6k
      rc = BLKID_PROBE_NONE;
398
15.6k
      continue; /* the device is too small */
399
15.6k
    }
400
401
    /* don't probe for RAIDs, swap or journal on CD/DVDs */
402
402k
    if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) &&
403
141k
        blkid_probe_is_cdrom(pr)) {
404
0
      rc = BLKID_PROBE_NONE;
405
0
      continue;
406
0
    }
407
408
    /* don't probe for RAIDs on floppies */
409
402k
    if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr)) {
410
0
      rc = BLKID_PROBE_NONE;
411
0
      continue;
412
0
    }
413
414
402k
    DBG(LOWPROBE, ul_debug("[%zd] %s:", i, id->name));
415
416
402k
    rc = blkid_probe_get_idmag(pr, id, &off, &mag);
417
402k
    if (rc < 0)
418
0
      break;
419
402k
    if (rc != BLKID_PROBE_OK)
420
305k
      continue;
421
422
    /* final check by probing function */
423
96.8k
    if (id->probefunc) {
424
96.8k
      DBG(LOWPROBE, ul_debug("\tcall probefunc()"));
425
96.8k
      errno = 0;
426
96.8k
      rc = id->probefunc(pr, mag);
427
96.8k
      blkid_probe_prune_buffers(pr);
428
96.8k
      if (rc != BLKID_PROBE_OK) {
429
94.5k
        blkid_probe_chain_reset_values(pr, chn);
430
94.5k
        if (rc < 0)
431
34
          break;
432
94.5k
        continue;
433
94.5k
      }
434
96.8k
    }
435
436
    /* all checks passed */
437
2.23k
    if (chn->flags & BLKID_SUBLKS_TYPE)
438
2.23k
      rc = blkid_probe_set_value(pr, "TYPE",
439
2.23k
        (const unsigned char *) id->name,
440
2.23k
        strlen(id->name) + 1);
441
442
2.23k
    if (!rc)
443
2.23k
      rc = blkid_probe_set_usage(pr, id->usage);
444
445
2.23k
    if (!rc && mag)
446
2.01k
      rc = blkid_probe_set_magic(pr, off, mag->len,
447
2.01k
          (const unsigned char *) mag->magic);
448
2.23k
    if (rc) {
449
0
      blkid_probe_chain_reset_values(pr, chn);
450
0
      DBG(LOWPROBE, ul_debug("failed to set result -- ignore"));
451
0
      continue;
452
0
    }
453
454
2.23k
    DBG(LOWPROBE, ul_debug("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]",
455
2.23k
      id->name, chn->idx));
456
2.23k
    return BLKID_PROBE_OK;
457
2.23k
  }
458
459
5.24k
  DBG(LOWPROBE, ul_debug("<-- leaving probing loop (failed=%d) [SUBLKS idx=%d]",
460
5.24k
      rc, chn->idx));
461
5.24k
  return rc;
462
7.48k
}
463
464
/*
465
 * This is the same function as blkid_do_probe(), but returns only one result
466
 * (cannot be used in while()) and checks for ambivalent results (more
467
 * filesystems on the device) -- in such case returns -2.
468
 *
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.
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.
475
 */
476
static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
477
5.27k
{
478
5.27k
  struct list_head vals;
479
5.27k
  int idx = -1;
480
5.27k
  int count = 0;
481
5.27k
  int intol = 0;
482
5.27k
  int rc;
483
484
5.27k
  INIT_LIST_HEAD(&vals);
485
486
5.27k
  if (pr->flags & BLKID_FL_NOSCAN_DEV)
487
0
    return BLKID_PROBE_NONE;
488
489
7.48k
  while ((rc = superblocks_probe(pr, chn)) == 0) {
490
491
2.23k
    if (blkid_probe_is_tiny(pr) && !count)
492
0
      return BLKID_PROBE_OK; /* floppy or so -- returns the first result. */
493
494
2.23k
    count++;
495
496
2.23k
    if (chn->idx >= 0 &&
497
2.23k
        idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO))
498
29
      break;
499
500
2.21k
    if (chn->idx >= 0 &&
501
2.21k
        !(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT))
502
1.95k
      intol++;
503
504
2.21k
    if (count == 1) {
505
      /* save the first result */
506
1.40k
      blkid_probe_chain_save_values(pr, chn, &vals);
507
1.40k
      idx = chn->idx;
508
1.40k
    }
509
2.21k
  }
510
511
5.27k
  if (rc < 0)
512
34
    goto done;    /* error */
513
514
5.23k
  if (count > 1 && intol) {
515
406
    DBG(LOWPROBE, ul_debug("ERROR: superblocks chain: "
516
406
             "ambivalent result detected (%d filesystems)!",
517
406
             count));
518
406
    rc = BLKID_PROBE_AMBIGUOUS; /* error, ambivalent result (more FS) */
519
406
    goto done;
520
406
  }
521
4.83k
  if (!count) {
522
3.81k
    rc = BLKID_PROBE_NONE;
523
3.81k
    goto done;
524
3.81k
  }
525
526
1.01k
  if (idx != -1) {
527
    /* restore the first result */
528
989
    blkid_probe_chain_reset_values(pr, chn);
529
989
    blkid_probe_append_values_list(pr, &vals);
530
989
    chn->idx = idx;
531
989
  }
532
533
  /*
534
   * The RAID device could be partitioned. The problem are RAID1 devices
535
   * where the partition table is visible from underlying devices. We
536
   * have to ignore such partition tables.
537
   */
538
1.01k
  if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID)
539
11
    pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT;
540
541
1.01k
  rc = BLKID_PROBE_OK;
542
5.27k
done:
543
5.27k
  blkid_probe_free_values_list(&vals);
544
5.27k
  return rc;
545
1.01k
}
546
547
int blkid_probe_set_version(blkid_probe pr, const char *version)
548
789
{
549
789
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
550
551
789
  if (chn->flags & BLKID_SUBLKS_VERSION)
552
0
    return blkid_probe_set_value(pr, "VERSION",
553
0
        (const unsigned char *) version,
554
0
        strlen(version) + 1);
555
789
  return 0;
556
789
}
557
558
559
int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
560
890
{
561
890
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
562
890
  int rc = 0;
563
564
890
  if (chn->flags & BLKID_SUBLKS_VERSION) {
565
0
    va_list ap;
566
567
0
    va_start(ap, fmt);
568
0
    rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap);
569
0
    va_end(ap);
570
0
  }
571
890
  return rc;
572
890
}
573
574
int blkid_probe_set_block_size(blkid_probe pr, unsigned block_size)
575
1.16k
{
576
1.16k
  return blkid_probe_sprintf_value(pr, "BLOCK_SIZE", "%u", block_size);
577
1.16k
}
578
579
static int blkid_probe_set_usage(blkid_probe pr, int usage)
580
2.23k
{
581
2.23k
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
582
2.23k
  const char *u = NULL;
583
584
2.23k
  if (!(chn->flags & BLKID_SUBLKS_USAGE))
585
2.23k
    return 0;
586
587
0
  if (usage & BLKID_USAGE_FILESYSTEM)
588
0
    u = "filesystem";
589
0
  else if (usage & BLKID_USAGE_RAID)
590
0
    u = "raid";
591
0
  else if (usage & BLKID_USAGE_CRYPTO)
592
0
    u = "crypto";
593
0
  else if (usage & BLKID_USAGE_OTHER)
594
0
    u = "other";
595
0
  else
596
0
    u = "unknown";
597
598
0
  return blkid_probe_set_value(pr, "USAGE",
599
0
      (const unsigned char *) u, strlen(u) + 1);
600
2.23k
}
601
602
/* size used by filesystem for data */
603
int blkid_probe_set_fssize(blkid_probe pr, uint64_t size)
604
589
{
605
589
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
606
607
589
  if (!(chn->flags & BLKID_SUBLKS_FSINFO))
608
589
    return 0;
609
610
0
  return blkid_probe_sprintf_value(pr, "FSSIZE", "%" PRIu64, size);
611
589
}
612
613
int blkid_probe_set_fslastblock(blkid_probe pr, uint64_t lastblock)
614
100
{
615
100
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
616
617
100
  if (!(chn->flags & BLKID_SUBLKS_FSINFO))
618
100
    return 0;
619
620
0
  return blkid_probe_sprintf_value(pr, "FSLASTBLOCK", "%" PRIu64,
621
0
      lastblock);
622
100
}
623
624
int blkid_probe_set_fsblocksize(blkid_probe pr, uint32_t block_size)
625
1.18k
{
626
1.18k
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
627
628
1.18k
  if (!(chn->flags & BLKID_SUBLKS_FSINFO))
629
1.18k
    return 0;
630
631
0
  return blkid_probe_sprintf_value(pr, "FSBLOCKSIZE", "%" PRIu32,
632
0
      block_size);
633
1.18k
}
634
635
int blkid_probe_set_fsendianness(blkid_probe pr, enum blkid_endianness endianness)
636
410
{
637
410
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
638
410
  const char *value;
639
640
410
  if (!(chn->flags & BLKID_SUBLKS_FSINFO))
641
410
    return 0;
642
643
0
  switch (endianness) {
644
0
    case BLKID_ENDIANNESS_LITTLE:
645
0
      value = "LITTLE";
646
0
      break;
647
0
    case BLKID_ENDIANNESS_BIG:
648
0
      value = "BIG";
649
0
      break;
650
0
    default:
651
0
      return -EINVAL;
652
0
  }
653
654
0
  return blkid_probe_set_value(pr, "ENDIANNESS",
655
0
      (const unsigned char *) value, strlen(value) + 1);
656
657
0
}
658
659
int blkid_probe_set_id_label(blkid_probe pr, const char *name,
660
           const unsigned char *data, size_t len)
661
915
{
662
915
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
663
915
  struct blkid_prval *v;
664
915
  int rc = 0;
665
666
915
  if (!(chn->flags & BLKID_SUBLKS_LABEL))
667
915
    return 0;
668
669
0
  v = blkid_probe_assign_value(pr, name);
670
0
  if (!v)
671
0
    return -ENOMEM;
672
673
0
  rc = blkid_probe_value_set_data(v, data, len);
674
0
  if (!rc) {
675
    /* remove white spaces */
676
0
    v->len = blkid_rtrim_whitespace(v->data) + 1;
677
0
    if (v->len > 1)
678
0
      v->len = blkid_ltrim_whitespace(v->data) + 1;
679
0
    if (v->len > 1)
680
0
      return 0;
681
0
  }
682
683
0
  blkid_probe_free_value(v);
684
0
  return rc;
685
686
0
}
687
688
int blkid_probe_set_utf8_id_label(blkid_probe pr, const char *name,
689
           const unsigned char *data, size_t len, int enc)
690
370
{
691
370
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
692
370
  struct blkid_prval *v;
693
370
  int rc = 0;
694
695
370
  if (!(chn->flags & BLKID_SUBLKS_LABEL))
696
370
    return 0;
697
698
0
  v = blkid_probe_assign_value(pr, name);
699
0
  if (!v)
700
0
    return -ENOMEM;
701
702
0
  v->len = (len * 3) + 1;
703
0
  v->data = calloc(1, v->len);
704
0
  if (!v->data)
705
0
    rc = -ENOMEM;
706
707
0
  if (!rc) {
708
0
    ul_encode_to_utf8(enc, v->data, v->len, data, len);
709
0
    v->len = blkid_rtrim_whitespace(v->data) + 1;
710
0
    if (v->len > 1)
711
0
      v->len = blkid_ltrim_whitespace(v->data) + 1;
712
0
    if (v->len > 1)
713
0
      return 0;
714
0
  }
715
716
0
  blkid_probe_free_value(v);
717
0
  return rc;
718
0
}
719
720
int blkid_probe_set_label(blkid_probe pr, const unsigned char *label, size_t len)
721
887
{
722
887
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
723
887
  struct blkid_prval *v;
724
887
  int rc = 0;
725
726
887
  if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
727
0
      (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0)
728
0
    return rc;
729
730
887
  if (!(chn->flags & BLKID_SUBLKS_LABEL))
731
887
    return 0;
732
733
0
  v = blkid_probe_assign_value(pr, "LABEL");
734
0
  if (!v)
735
0
    return -ENOMEM;
736
737
0
  rc = blkid_probe_value_set_data(v, label, len);
738
0
  if (!rc) {
739
0
    v->len = blkid_rtrim_whitespace(v->data) + 1;
740
0
    if (v->len > 1)
741
0
      return 0;
742
0
  }
743
744
0
  blkid_probe_free_value(v);
745
0
  return rc;
746
0
}
747
748
int blkid_probe_set_utf8label(blkid_probe pr, const unsigned char *label,
749
        size_t len, int enc)
750
151
{
751
151
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
752
151
  struct blkid_prval *v;
753
151
  int rc = 0;
754
755
151
  if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
756
0
      (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0)
757
0
    return rc;
758
759
151
  if (!(chn->flags & BLKID_SUBLKS_LABEL))
760
151
    return 0;
761
762
0
  v = blkid_probe_assign_value(pr, "LABEL");
763
0
  if (!v)
764
0
    return -ENOMEM;
765
766
0
  v->len = (len * 3) + 1;
767
0
  v->data = calloc(1, v->len);
768
0
  if (!v->data)
769
0
    rc = -ENOMEM;
770
0
  if (!rc) {
771
0
    ul_encode_to_utf8(enc, v->data, v->len, label, len);
772
0
    v->len = blkid_rtrim_whitespace(v->data) + 1;
773
0
    if (v->len > 1)
774
0
      return 0;
775
0
  }
776
777
0
  blkid_probe_free_value(v);
778
0
  return rc;
779
0
}
780
781
int blkid_probe_sprintf_uuid(blkid_probe pr, const unsigned char *uuid,
782
        size_t len, const char *fmt, ...)
783
525
{
784
525
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
785
525
  va_list ap;
786
525
  int rc = 0;
787
788
525
  if (blkid_uuid_is_empty(uuid, len))
789
38
    return 0;
790
791
487
  if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
792
0
      (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, len)) < 0)
793
0
    return rc;
794
795
487
  if (!(chn->flags & BLKID_SUBLKS_UUID))
796
487
    return 0;
797
798
487
  va_start(ap, fmt);
799
0
  rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap);
800
0
  va_end(ap);
801
802
0
  return rc;
803
487
}
804
805
/* function to set UUIDs that are in superblocks stored as strings */
806
int blkid_probe_strncpy_uuid(blkid_probe pr, const unsigned char *str, size_t len)
807
2
{
808
2
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
809
2
  struct blkid_prval *v;
810
2
  int rc = 0;
811
812
2
  if (str == NULL || *str == '\0')
813
0
    return -EINVAL;
814
815
2
  if (!len)
816
0
    len = strlen((const char *) str);
817
818
2
  if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
819
0
      (rc = blkid_probe_set_value(pr, "UUID_RAW", str, len)) < 0)
820
0
    return rc;
821
822
2
  if (!(chn->flags & BLKID_SUBLKS_UUID))
823
2
    return 0;
824
825
0
  v = blkid_probe_assign_value(pr, "UUID");
826
0
  if (!v)
827
0
    rc= -ENOMEM;
828
0
  if (!rc)
829
0
    rc = blkid_probe_value_set_data(v, str, len);
830
0
  if (!rc) {
831
0
    v->len = blkid_rtrim_whitespace(v->data) + 1;
832
0
    if (v->len > 1)
833
0
      return 0;
834
0
  }
835
836
0
  blkid_probe_free_value(v);
837
0
  return rc;
838
0
}
839
840
/* default _set_uuid function to set DCE UUIDs */
841
int blkid_probe_set_uuid_as(blkid_probe pr, const unsigned char *uuid, const char *name)
842
851
{
843
851
  struct blkid_chain *chn = blkid_probe_get_chain(pr);
844
851
  struct blkid_prval *v;
845
851
  int rc = 0;
846
847
851
  if (blkid_uuid_is_empty(uuid, 16))
848
96
    return 0;
849
850
755
  if (!name) {
851
723
    if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
852
0
        (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, 16)) < 0)
853
0
      return rc;
854
855
723
    if (!(chn->flags & BLKID_SUBLKS_UUID))
856
723
      return 0;
857
858
0
    v = blkid_probe_assign_value(pr, "UUID");
859
0
  } else
860
32
    v = blkid_probe_assign_value(pr, name);
861
862
32
  if (!v)
863
0
    return -ENOMEM;
864
865
32
  v->len = UUID_STR_LEN;
866
32
  v->data = calloc(1, v->len);
867
32
  if (!v->data)
868
0
    rc = -ENOMEM;
869
870
32
  if (!rc) {
871
32
    blkid_unparse_uuid(uuid, (char *) v->data, v->len);
872
32
    return 0;
873
32
  }
874
875
0
  blkid_probe_free_value(v);
876
0
  return rc;
877
32
}
878
879
int blkid_probe_set_uuid(blkid_probe pr, const unsigned char *uuid)
880
804
{
881
804
  return blkid_probe_set_uuid_as(pr, uuid, NULL);
882
804
}
883
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
 */
893
int blkid_probe_set_request(blkid_probe pr, int flags)
894
0
{
895
0
  return blkid_probe_set_superblocks_flags(pr, flags);
896
0
}
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
 */
906
int blkid_probe_reset_filter(blkid_probe pr)
907
0
{
908
0
  return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
909
0
}
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
 */
919
int blkid_probe_invert_filter(blkid_probe pr)
920
0
{
921
0
  return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
922
0
}
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
 *
932
 * Deprecated: Use blkid_probe_filter_superblocks_type().
933
 */
934
int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[])
935
0
{
936
0
  return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
937
0
}
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
 */
949
int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
950
0
{
951
0
  return blkid_probe_filter_superblocks_usage(pr, flag, usage);
952
0
}
953
954