summaryrefslogtreecommitdiff
path: root/misc/tune2fs.c
diff options
context:
space:
mode:
authorLukas Czerner <lczerner@redhat.com>2021-11-24 14:45:42 +0100
committerTheodore Ts'o <tytso@mit.edu>2021-12-31 00:34:29 -0500
commitf85b4526f60b1edf143a9c2657a8f04fb9f7ccb7 (patch)
treecc29e941cf5208851a57ff6c49423df203a4ed5a /misc/tune2fs.c
parent8adeabeec715adcc2f32caff8d33b0e9ca9d7d8a (diff)
downloade2fsprogs-f85b4526f60b1edf143a9c2657a8f04fb9f7ccb7.tar.gz
tune2fs: implement support for set/get label iocts
Implement support for FS_IOC_SETFSLABEL and FS_IOC_GETFSLABEL ioctls. Try to use the ioctls if possible even before we open the file system since we don't need it. Only fall back to the old method in the case the file system is not mounted, is mounted read only in the set label case, or the ioctls are not suppported by the kernel. The new ioctls can also be supported by file system drivers other than ext4. As a result tune2fs and e2label will work for those file systems as well as long as the file system is mounted. Note that we still truncate the label exceeds the supported lenghth on extN file system family, while we keep the label intact for others. Update tune2fs and e2label as well. Signed-off-by: Lukas Czerner <lczerner@redhat.com> Reviewed-by: Andreas Dilger <adilger@dilger.ca> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'misc/tune2fs.c')
-rw-r--r--misc/tune2fs.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index 71a8e99b..6c162ba5 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -52,6 +52,9 @@ extern int optind;
#include <sys/types.h>
#include <libgen.h>
#include <limits.h>
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fs.h"
@@ -70,6 +73,15 @@ extern int optind;
#define QOPT_ENABLE (1)
#define QOPT_DISABLE (-1)
+#ifndef FS_IOC_SETFSLABEL
+#define FSLABEL_MAX 256
+#define FS_IOC_SETFSLABEL _IOW(0x94, 50, char[FSLABEL_MAX])
+#endif
+
+#ifndef FS_IOC_GETFSLABEL
+#define FS_IOC_GETFSLABEL _IOR(0x94, 49, char[FSLABEL_MAX])
+#endif
+
extern int ask_yn(const char *string, int def);
const char *program_name = "tune2fs";
@@ -2997,6 +3009,75 @@ fs_update_journal_user(struct ext2_super_block *sb, __u8 old_uuid[UUID_SIZE])
return 0;
}
+/*
+ * Use FS_IOC_SETFSLABEL or FS_IOC_GETFSLABEL to set/get file system label
+ * Return: 0 on success
+ * 1 on error
+ * -1 when the old method should be used
+ */
+int handle_fslabel(int setlabel) {
+ errcode_t ret;
+ int mnt_flags, fd;
+ char label[FSLABEL_MAX];
+ int maxlen = FSLABEL_MAX - 1;
+ char mntpt[PATH_MAX + 1];
+
+ ret = ext2fs_check_mount_point(device_name, &mnt_flags,
+ mntpt, sizeof(mntpt));
+ if (ret) {
+ com_err(device_name, ret, _("while checking mount status"));
+ return 1;
+ }
+ if (!(mnt_flags & EXT2_MF_MOUNTED) ||
+ (setlabel && (mnt_flags & EXT2_MF_READONLY)))
+ return -1;
+
+ if (!mntpt[0]) {
+ fprintf(stderr,_("Unknown mount point for %s\n"), device_name);
+ return 1;
+ }
+
+ fd = open(mntpt, O_RDONLY);
+ if (fd < 0) {
+ com_err(mntpt, errno, _("while opening mount point"));
+ return 1;
+ }
+
+ /* Get fs label */
+ if (!setlabel) {
+ if (ioctl(fd, FS_IOC_GETFSLABEL, &label)) {
+ close(fd);
+ if (errno == ENOTTY)
+ return -1;
+ com_err(mntpt, errno, _("while trying to get fs label"));
+ return 1;
+ }
+ close(fd);
+ printf("%.*s\n", EXT2_LEN_STR(label));
+ return 0;
+ }
+
+ /* If it's extN file system, truncate the label to appropriate size */
+ if (mnt_flags & EXT2_MF_EXTFS)
+ maxlen = EXT2_LABEL_LEN;
+ if (strlen(new_label) > maxlen) {
+ fputs(_("Warning: label too long, truncating.\n"),
+ stderr);
+ new_label[maxlen] = '\0';
+ }
+
+ /* Set fs label */
+ if (ioctl(fd, FS_IOC_SETFSLABEL, new_label)) {
+ close(fd);
+ if (errno == ENOTTY)
+ return -1;
+ com_err(mntpt, errno, _("while trying to set fs label"));
+ return 1;
+ }
+ close(fd);
+ return 0;
+}
+
#ifndef BUILD_AS_LIB
int main(int argc, char **argv)
#else
@@ -3038,6 +3119,21 @@ int tune2fs_main(int argc, char **argv)
#endif
io_ptr = unix_io_manager;
+ /*
+ * Try the get/set fs label using ioctls before we even attempt
+ * to open the file system.
+ */
+ if (L_flag || print_label) {
+ rc = handle_fslabel(L_flag);
+ if (rc != -1) {
+#ifndef BUILD_AS_LIB
+ exit(rc);
+#endif
+ return rc;
+ }
+ rc = 0;
+ }
+
retry_open:
if ((open_flag & EXT2_FLAG_RW) == 0 || f_flag)
open_flag |= EXT2_FLAG_SKIP_MMP;