LCOV - code coverage report
Current view: top level - plugins/fs - vfat.c (source / functions) Coverage Total Hit
Test: libblockdev Coverage Report Lines: 78.5 % 195 153
Test Date: 2026-01-23 09:12:16 Functions: 85.7 % 14 12
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2017  Red Hat, Inc.
       3              :  *
       4              :  * This library is free software; you can redistribute it and/or
       5              :  * modify it under the terms of the GNU Lesser General Public
       6              :  * License as published by the Free Software Foundation; either
       7              :  * version 2.1 of the License, or (at your option) any later version.
       8              :  *
       9              :  * This library is distributed in the hope that it will be useful,
      10              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12              :  * Lesser General Public License for more details.
      13              :  *
      14              :  * You should have received a copy of the GNU Lesser General Public
      15              :  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      16              :  *
      17              :  * Author: Vratislav Podzimek <vpodzime@redhat.com>
      18              :  */
      19              : 
      20              : #include <blockdev/utils.h>
      21              : #include <check_deps.h>
      22              : #include <sys/types.h>
      23              : #include <sys/stat.h>
      24              : #include <fcntl.h>
      25              : #include <stdio.h>
      26              : 
      27              : #include "vfat.h"
      28              : #include "fs.h"
      29              : #include "common.h"
      30              : 
      31              : static volatile guint avail_deps = 0;
      32              : static GMutex deps_check_lock;
      33              : 
      34              : #define DEPS_MKFSVFAT 0
      35              : #define DEPS_MKFSVFAT_MASK (1 << DEPS_MKFSVFAT)
      36              : #define DEPS_FATLABEL 1
      37              : #define DEPS_FATLABEL_MASK (1 << DEPS_FATLABEL)
      38              : #define DEPS_FSCKVFAT 2
      39              : #define DEPS_FSCKVFAT_MASK (1 << DEPS_FSCKVFAT)
      40              : #define DEPS_RESIZEVFAT 3
      41              : #define DEPS_RESIZEVFAT_MASK (1 << DEPS_RESIZEVFAT)
      42              : #define DEPS_FATLABELUUID 4
      43              : #define DEPS_FATLABELUUID_MASK (1 << DEPS_FATLABELUUID)
      44              : 
      45              : #define DEPS_LAST 5
      46              : 
      47              : static const UtilDep deps[DEPS_LAST] = {
      48              :     {"mkfs.vfat", NULL, NULL, NULL},
      49              :     {"fatlabel", NULL, NULL, NULL},
      50              :     {"fsck.vfat", NULL, NULL, NULL},
      51              :     {"vfat-resize", NULL, NULL, NULL},
      52              :     {"fatlabel", "4.2", "--version", "fatlabel\\s+([\\d\\.]+).+"},
      53              : };
      54              : 
      55              : static guint32 fs_mode_util[BD_FS_MODE_LAST+1] = {
      56              :     DEPS_MKFSVFAT_MASK,     /* mkfs */
      57              :     0,                      /* wipe */
      58              :     DEPS_FSCKVFAT_MASK,     /* check */
      59              :     DEPS_FSCKVFAT_MASK,     /* repair */
      60              :     DEPS_FATLABEL_MASK,     /* set-label */
      61              :     DEPS_FSCKVFAT_MASK,     /* query */
      62              :     DEPS_RESIZEVFAT_MASK,   /* resize */
      63              :     DEPS_FATLABELUUID_MASK, /* set-uuid */
      64              : };
      65              : 
      66              : 
      67              : #ifdef __clang__
      68              : #define ZERO_INIT {}
      69              : #else
      70              : #define ZERO_INIT {0}
      71              : #endif
      72              : 
      73              : /**
      74              :  * bd_fs_vfat_is_tech_avail:
      75              :  * @tech: the queried tech
      76              :  * @mode: a bit mask of queried modes of operation (#BDFSTechMode) for @tech
      77              :  * @error: (out) (optional): place to store error (details about why the @tech-@mode combination is not available)
      78              :  *
      79              :  * Returns: whether the @tech-@mode combination is available -- supported by the
      80              :  *          plugin implementation and having all the runtime dependencies available
      81              :  */
      82              : G_GNUC_INTERNAL gboolean
      83            9 : bd_fs_vfat_is_tech_avail (BDFSTech tech G_GNUC_UNUSED, guint64 mode, GError **error) {
      84            9 :     guint32 required = 0;
      85            9 :     guint i = 0;
      86              : 
      87           81 :     for (i = 0; i <= BD_FS_MODE_LAST; i++)
      88           72 :         if (mode & (1 << i))
      89           14 :             required |= fs_mode_util[i];
      90              : 
      91            9 :     return check_deps (&avail_deps, required, deps, DEPS_LAST, &deps_check_lock, error);
      92              : }
      93              : 
      94              : /**
      95              :  * bd_fs_vfat_info_copy: (skip)
      96              :  *
      97              :  * Creates a new copy of @data.
      98              :  */
      99            0 : BDFSVfatInfo* bd_fs_vfat_info_copy (BDFSVfatInfo *data) {
     100            0 :     if (data == NULL)
     101            0 :         return NULL;
     102              : 
     103            0 :     BDFSVfatInfo *ret = g_new0 (BDFSVfatInfo, 1);
     104              : 
     105            0 :     ret->label = g_strdup (data->label);
     106            0 :     ret->uuid = g_strdup (data->uuid);
     107            0 :     ret->cluster_size = data->cluster_size;
     108            0 :     ret->cluster_count = data->cluster_count;
     109            0 :     ret->free_cluster_count = data->free_cluster_count;
     110              : 
     111            0 :     return ret;
     112              : }
     113              : 
     114              : /**
     115              :  * bd_fs_vfat_info_free: (skip)
     116              :  *
     117              :  * Frees @data.
     118              :  */
     119            0 : void bd_fs_vfat_info_free (BDFSVfatInfo *data) {
     120            0 :     if (data == NULL)
     121            0 :         return;
     122              : 
     123            0 :     g_free (data->label);
     124            0 :     g_free (data->uuid);
     125            0 :     g_free (data);
     126              : }
     127              : 
     128              : /* we want to support vol ID in the "udev format", e.g. "2E24-EC82" */
     129           11 : static gchar *_fix_uuid (const gchar *uuid) {
     130           11 :     gchar *new_uuid = NULL;
     131           11 :     size_t len = 0;
     132              : 
     133           11 :     len = strlen (uuid);
     134           11 :     if (len == 9 && uuid[4] == '-') {
     135            4 :         new_uuid = g_new0 (gchar, 9);
     136            4 :         memcpy (new_uuid, uuid, 4);
     137            4 :         memcpy (new_uuid + 4, uuid + 5, 4);
     138              :     } else
     139            7 :         new_uuid = g_strdup (uuid);
     140              : 
     141           11 :     return new_uuid;
     142              : }
     143              : 
     144              : G_GNUC_INTERNAL BDExtraArg **
     145            4 : bd_fs_vfat_mkfs_options (BDFSMkfsOptions *options, const BDExtraArg **extra) {
     146            4 :     GPtrArray *options_array = g_ptr_array_new ();
     147            4 :     const BDExtraArg **extra_p = NULL;
     148              :     gchar *label;
     149            4 :     UtilDep dep = {"mkfs.vfat", "4.2", "--help", "mkfs.fat\\s+([\\d\\.]+).+"};
     150            4 :     gboolean new_vfat = FALSE;
     151            4 :     gchar *new_uuid = NULL;
     152              : 
     153            4 :     if (options->label && g_strcmp0 (options->label, "") != 0) {
     154              :         /* convert the label uppercase */
     155            1 :         label = g_ascii_strup (options->label, -1);
     156            1 :         g_ptr_array_add (options_array, bd_extra_arg_new ("-n", label));
     157            1 :         g_free (label);
     158              :     }
     159              : 
     160            4 :     if (options->uuid && g_strcmp0 (options->uuid, "") != 0) {
     161            1 :         new_uuid = _fix_uuid (options->uuid);
     162            1 :         g_ptr_array_add (options_array, bd_extra_arg_new ("-i", new_uuid));
     163            1 :         g_free (new_uuid);
     164              :     }
     165              : 
     166            4 :     if (options->force)
     167            0 :         g_ptr_array_add (options_array, bd_extra_arg_new ("-I", ""));
     168              : 
     169            4 :     if (options->no_pt) {
     170              :         /* only mkfs.vfat >= 4.2 (sometimes) creates the partition table */
     171            1 :         new_vfat = bd_utils_check_util_version (dep.name, dep.version,
     172              :                                                 dep.ver_arg, dep.ver_regexp,
     173              :                                                 NULL);
     174            1 :         if (new_vfat)
     175            1 :             g_ptr_array_add (options_array, bd_extra_arg_new ("--mbr=no", ""));
     176              :     }
     177              : 
     178            4 :     if (extra) {
     179            6 :         for (extra_p = extra; *extra_p; extra_p++)
     180            3 :             g_ptr_array_add (options_array, bd_extra_arg_copy ((BDExtraArg *) *extra_p));
     181              :     }
     182              : 
     183            4 :     g_ptr_array_add (options_array, NULL);
     184              : 
     185            4 :     return (BDExtraArg **) g_ptr_array_free (options_array, FALSE);
     186              : }
     187              : 
     188              : /**
     189              :  * bd_fs_vfat_mkfs:
     190              :  * @device: the device to create a new vfat fs on
     191              :  * @extra: (nullable) (array zero-terminated=1): extra options for the creation (right now
     192              :  *                                                 passed to the 'mkfs.vfat' utility)
     193              :  * @error: (out) (optional): place to store error (if any)
     194              :  *
     195              :  * Please remember that FAT labels should always be uppercase.
     196              :  *
     197              :  * Returns: whether a new vfat fs was successfully created on @device or not
     198              :  *
     199              :  * Tech category: %BD_FS_TECH_VFAT-%BD_FS_TECH_MODE_MKFS
     200              :  */
     201           20 : gboolean bd_fs_vfat_mkfs (const gchar *device, const BDExtraArg **extra, GError **error) {
     202           20 :     const gchar *args[3] = {"mkfs.vfat", device, NULL};
     203              : 
     204           20 :     if (!check_deps (&avail_deps, DEPS_MKFSVFAT_MASK, deps, DEPS_LAST, &deps_check_lock, error))
     205            0 :         return FALSE;
     206              : 
     207           20 :     return bd_utils_exec_and_report_error (args, extra, error);
     208              : }
     209              : 
     210              : /**
     211              :  * bd_fs_vfat_check:
     212              :  * @device: the device containing the file system to check
     213              :  * @extra: (nullable) (array zero-terminated=1): extra options for the repair (right now
     214              :  *                                                 passed to the 'fsck.vfat' utility)
     215              :  * @error: (out) (optional): place to store error (if any)
     216              :  *
     217              :  * Returns: whether an vfat file system on the @device is clean or not
     218              :  *
     219              :  * Tech category: %BD_FS_TECH_VFAT-%BD_FS_TECH_MODE_CHECK
     220              :  */
     221            2 : gboolean bd_fs_vfat_check (const gchar *device, const BDExtraArg **extra, GError **error) {
     222            2 :     const gchar *args[4] = {"fsck.vfat", "-n", device, NULL};
     223            2 :     gint status = 0;
     224            2 :     gboolean ret = FALSE;
     225              : 
     226            2 :     if (!check_deps (&avail_deps, DEPS_FSCKVFAT_MASK, deps, DEPS_LAST, &deps_check_lock, error))
     227            0 :         return FALSE;
     228              : 
     229            2 :     ret = bd_utils_exec_and_report_status_error (args, extra, &status, error);
     230            2 :     if (!ret && (status == 1)) {
     231              :         /* no error should be reported for exit code 1 -- Recoverable errors have been detected */
     232            0 :         g_clear_error (error);
     233              :     }
     234            2 :     return ret;
     235              : }
     236              : 
     237              : /**
     238              :  * bd_fs_vfat_repair:
     239              :  * @device: the device containing the file system to repair
     240              :  * @extra: (nullable) (array zero-terminated=1): extra options for the repair (right now
     241              :  *                                                 passed to the 'fsck.vfat' utility)
     242              :  * @error: (out) (optional): place to store error (if any)
     243              :  *
     244              :  * Returns: whether an vfat file system on the @device was successfully repaired
     245              :  *          (if needed) or not (error is set in that case)
     246              :  *
     247              :  * Tech category: %BD_FS_TECH_VFAT-%BD_FS_TECH_MODE_REPAIR
     248              :  */
     249            1 : gboolean bd_fs_vfat_repair (const gchar *device, const BDExtraArg **extra, GError **error) {
     250            1 :     const gchar *args[4] = {"fsck.vfat", "-a", device, NULL};
     251            1 :     gint status = 0;
     252            1 :     gboolean ret = FALSE;
     253              : 
     254            1 :     if (!check_deps (&avail_deps, DEPS_FSCKVFAT_MASK, deps, DEPS_LAST, &deps_check_lock, error))
     255            0 :         return FALSE;
     256              : 
     257            1 :     ret = bd_utils_exec_and_report_status_error (args, extra, &status, error);
     258            1 :     if (!ret) {
     259            0 :         if (status == 1) {
     260              :             /* exit code 1 can also mean "errors have been detected and corrected" so we need
     261              :                to run fsck again to make sure the filesystem is now clean */
     262            0 :             g_clear_error (error);
     263            0 :             ret = bd_utils_exec_and_report_status_error (args, extra, &status, error);
     264              :         } else
     265              :             /* FALSE and exit code other than 1 always means error  */
     266            0 :             ret = FALSE;
     267              :     }
     268              : 
     269            1 :     return ret;
     270              : }
     271              : 
     272              : /**
     273              :  * bd_fs_vfat_set_label:
     274              :  * @device: the device containing the file system to set label for
     275              :  * @label: label to set
     276              :  * @error: (out) (optional): place to store error (if any)
     277              :  *
     278              :  * Returns: whether the label of vfat file system on the @device was
     279              :  *          successfully set or not
     280              :  *
     281              :  * Tech category: %BD_FS_TECH_VFAT-%BD_FS_TECH_MODE_SET_LABEL
     282              :  */
     283            3 : gboolean bd_fs_vfat_set_label (const gchar *device, const gchar *label, GError **error) {
     284            3 :     const gchar *args[4] = {"fatlabel", device, NULL, NULL};
     285            3 :     UtilDep dep = {"fatlabel", "4.2", "--version", "fatlabel\\s+([\\d\\.]+).+"};
     286            3 :     gchar *label_up = NULL;
     287            3 :     gboolean new_vfat = FALSE;
     288              :     gboolean ret;
     289              : 
     290            3 :     if (!check_deps (&avail_deps, DEPS_FATLABEL_MASK, deps, DEPS_LAST, &deps_check_lock, error))
     291            0 :         return FALSE;
     292              : 
     293            3 :     if (!label || g_strcmp0 (label, "") == 0) {
     294              :         /* fatlabel >= 4.2 refuses to set empty label */
     295            1 :         new_vfat = bd_utils_check_util_version (dep.name, dep.version,
     296              :                                                 dep.ver_arg, dep.ver_regexp,
     297              :                                                 NULL);
     298            1 :         if (new_vfat)
     299            1 :             args[2] = "--reset";
     300              :     }
     301              : 
     302              :     /* forcefully convert the label uppercase in case no reset was requested */
     303            3 :     if (label && args[2] == NULL) {
     304            2 :         label_up = g_ascii_strup (label, -1);
     305            2 :         args[2] = label_up;
     306              :     }
     307            3 :     ret = bd_utils_exec_and_report_error (args, NULL, error);
     308            3 :     g_free (label_up);
     309              : 
     310            3 :     return ret;
     311              : }
     312              : 
     313              : /**
     314              :  * bd_fs_vfat_check_label:
     315              :  * @label: label to check
     316              :  * @error: (out) (optional): place to store error
     317              :  *
     318              :  * Returns: whether @label is a valid label for the vfat file system or not
     319              :  *          (reason is provided in @error)
     320              :  *
     321              :  * Tech category: always available
     322              :  */
     323            2 : gboolean bd_fs_vfat_check_label (const gchar *label, GError **error) {
     324            2 :     const gchar *forbidden = "\"*/:<>?\\|";
     325              :     guint n;
     326              : 
     327            2 :     if (strlen (label) > 11) {
     328            1 :         g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_LABEL_INVALID,
     329              :                      "Label for VFAT filesystem must be at most 11 characters long.");
     330            1 :         return FALSE;
     331              :     }
     332              : 
     333              :     /* VFAT does not allow some characters; as dosfslabel does not enforce this,
     334              :      * check in advance; also, VFAT only knows upper-case characters, dosfslabel
     335              :      * enforces this */
     336           10 :     for (n = 0; forbidden[n] != 0; n++)
     337            9 :         if (strchr (label, forbidden[n]) != NULL) {
     338            0 :             g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_LABEL_INVALID,
     339              :                          "Invalid label: character '%c' not supported in VFAT labels.",
     340            0 :                          forbidden[n]);
     341            0 :             return FALSE;
     342              :         }
     343              : 
     344            1 :     return TRUE;
     345              : }
     346              : 
     347              : /**
     348              :  * bd_fs_vfat_set_uuid:
     349              :  * @device: the device containing the file system to set uuid for
     350              :  * @uuid: (nullable): volume ID to set or %NULL to generate a new one
     351              :  * @error: (out) (optional): place to store error (if any)
     352              :  *
     353              :  * Returns: whether the volume ID of vfat file system on the @device was
     354              :  *          successfully set or not
     355              :  *
     356              :  * Tech category: %BD_FS_TECH_VFAT-%BD_FS_TECH_MODE_SET_UUID
     357              :  */
     358            5 : gboolean bd_fs_vfat_set_uuid (const gchar *device, const gchar *uuid, GError **error) {
     359            5 :     const gchar *args[5] = {"fatlabel", "-i", device, NULL, NULL};
     360            5 :     g_autofree gchar *new_uuid = NULL;
     361              : 
     362            5 :     if (!check_deps (&avail_deps, DEPS_FATLABELUUID_MASK, deps, DEPS_LAST, &deps_check_lock, error))
     363            0 :         return FALSE;
     364              : 
     365            5 :     if (!uuid || g_strcmp0 (uuid, "") == 0)
     366            2 :         args[3] = "--reset";
     367              :     else {
     368            3 :         new_uuid = _fix_uuid (uuid);
     369            3 :         args[3] = new_uuid;
     370              :     }
     371              : 
     372            5 :     return bd_utils_exec_and_report_error (args, NULL, error);
     373              : }
     374              : 
     375              : /**
     376              :  * bd_fs_vfat_check_uuid:
     377              :  * @uuid: UUID to check
     378              :  * @error: (out) (optional): place to store error
     379              :  *
     380              :  * Returns: whether @uuid is a valid UUID for the vfat file system or not
     381              :  *          (reason is provided in @error)
     382              :  *
     383              :  * Tech category: always available
     384              :  */
     385            7 : gboolean bd_fs_vfat_check_uuid (const gchar *uuid, GError **error) {
     386              :     guint64 vol_id;
     387            7 :     gchar *new_uuid = NULL;
     388            7 :     gchar *endptr = NULL;
     389              : 
     390            7 :     if (!uuid)
     391            0 :         return TRUE;
     392              : 
     393            7 :     new_uuid = _fix_uuid (uuid);
     394              : 
     395            7 :     vol_id = g_ascii_strtoull (new_uuid, &endptr, 16);
     396            7 :     if ((vol_id == 0 && endptr == new_uuid) || (endptr && *endptr)) {
     397            2 :         g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_UUID_INVALID,
     398              :                      "UUID for VFAT filesystem must be a hexadecimal number.");
     399            2 :         g_free (new_uuid);
     400            2 :         return FALSE;
     401              :     }
     402              : 
     403            5 :     if (vol_id > G_MAXUINT32) {
     404            1 :         g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_UUID_INVALID,
     405              :                      "UUID for VFAT filesystem must fit into 32 bits.");
     406            1 :         g_free (new_uuid);
     407            1 :         return FALSE;
     408              :     }
     409              : 
     410            4 :     g_free (new_uuid);
     411            4 :     return TRUE;
     412              : }
     413              : 
     414              : /**
     415              :  * bd_fs_vfat_get_info:
     416              :  * @device: the device containing the file system to get info for
     417              :  * @error: (out) (optional): place to store error (if any)
     418              :  *
     419              :  * Returns: (transfer full): information about the file system on @device or
     420              :  *                           %NULL in case of error
     421              :  *
     422              :  * Tech category: %BD_FS_TECH_VFAT-%BD_FS_TECH_MODE_QUERY
     423              :  */
     424           19 : BDFSVfatInfo* bd_fs_vfat_get_info (const gchar *device, GError **error) {
     425           19 :     const gchar *args[4] = {"fsck.vfat", "-nv", device, NULL};
     426           19 :     gboolean success = FALSE;
     427           19 :     BDFSVfatInfo *ret = NULL;
     428           19 :     gchar *output = NULL;
     429           19 :     gchar **lines = NULL;
     430           19 :     gchar **line_p = NULL;
     431           19 :     gboolean have_cluster_size = FALSE;
     432           19 :     gboolean have_cluster_count = FALSE;
     433           19 :     guint64 full_cluster_count = 0;
     434           19 :     guint64 cluster_count = 0;
     435           19 :     gchar **key_val = NULL;
     436           19 :     gint scanned = 0;
     437              : 
     438           19 :     if (!check_deps (&avail_deps, DEPS_FSCKVFAT_MASK, deps, DEPS_LAST, &deps_check_lock, error))
     439            0 :         return NULL;
     440              : 
     441           19 :     ret = g_new0 (BDFSVfatInfo, 1);
     442              : 
     443           19 :     success = get_uuid_label (device, &(ret->uuid), &(ret->label), error);
     444           19 :     if (!success) {
     445              :         /* error is already populated */
     446            0 :         bd_fs_vfat_info_free (ret);
     447            0 :         return NULL;
     448              :     }
     449              : 
     450           19 :     success = bd_utils_exec_and_capture_output (args, NULL, &output, error);
     451           19 :     if (!success) {
     452              :         /* error is already populated */
     453            0 :         bd_fs_vfat_info_free (ret);
     454            0 :         return NULL;
     455              :     }
     456              : 
     457           19 :     lines = g_strsplit (output, "\n", 0);
     458           19 :     g_free (output);
     459          399 :     for (line_p=lines; *line_p && (!have_cluster_size || !have_cluster_count); line_p++) {
     460          380 :         if (!have_cluster_size && g_str_has_suffix (*line_p, "bytes per cluster")) {
     461           19 :             ret->cluster_size = g_ascii_strtoull (*line_p, NULL, 0);
     462           19 :             have_cluster_size = TRUE;
     463          361 :         } else if (!have_cluster_count && g_str_has_prefix (*line_p, device)) {
     464           19 :             key_val = g_strsplit (*line_p, ",", 2);
     465           19 :             scanned = sscanf (key_val[1], " %" G_GUINT64_FORMAT "/" "%" G_GUINT64_FORMAT " clusters",
     466              :                               &full_cluster_count, &cluster_count);
     467           19 :             if (scanned != 2) {
     468            0 :                 g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_FAIL,
     469              :                              "Failed to get number of FAT clusters for '%s'", device);
     470            0 :                 bd_fs_vfat_info_free (ret);
     471            0 :                 g_strfreev (key_val);
     472            0 :                 g_strfreev (lines);
     473            0 :                 return NULL;
     474              :             }
     475           19 :             ret->cluster_count = cluster_count;
     476           19 :             ret->free_cluster_count = cluster_count - full_cluster_count;
     477           19 :             have_cluster_count = TRUE;
     478           19 :             g_strfreev (key_val);
     479              :         }
     480              :     }
     481           19 :     g_strfreev (lines);
     482              : 
     483           19 :     return ret;
     484              : }
     485              : 
     486              : /**
     487              :  * bd_fs_vfat_resize:
     488              :  * @device: the device the file system of which to resize
     489              :  * @new_size: new requested size for the file system (if 0, the file system is
     490              :  *            adapted to the underlying block device)
     491              :  * @error: (out) (optional): place to store error (if any)
     492              :  *
     493              :  * Returns: whether the file system on @device was successfully resized or not
     494              :  *
     495              :  * Tech category: %BD_FS_TECH_VFAT-%BD_FS_TECH_MODE_RESIZE
     496              :  */
     497            6 : gboolean bd_fs_vfat_resize (const gchar *device, guint64 new_size, GError **error) {
     498            6 :     g_autofree gchar *size_str = NULL;
     499            6 :     const gchar *args[4] = {"vfat-resize", device, NULL, NULL};
     500              : 
     501            6 :     if (!check_deps (&avail_deps, DEPS_RESIZEVFAT_MASK, deps, DEPS_LAST, &deps_check_lock, error))
     502            0 :         return FALSE;
     503              : 
     504            6 :     if (new_size != 0) {
     505            4 :         size_str = g_strdup_printf ("%"G_GUINT64_FORMAT, new_size);
     506            4 :         args[2] = size_str;
     507              :     }
     508              : 
     509            6 :     return bd_utils_exec_and_report_error (args, NULL, error);
     510              : }
        

Generated by: LCOV version 2.0-1