public inbox for linux-ext4@vger.kernel.org
 help / color / mirror / Atom feed
From: Andreas Dilger <adilger@dilger.ca>
To: Lukas Czerner <lczerner@redhat.com>
Cc: linux-ext4 <linux-ext4@vger.kernel.org>, tytso@mit.edu
Subject: Re: [PATCH] tune2fs: implement support for set/get label iocts
Date: Sat, 27 Nov 2021 14:23:32 -0700	[thread overview]
Message-ID: <1563F233-9CCB-486E-AC87-7B752EED8ABA@dilger.ca> (raw)
In-Reply-To: <20211124134542.22270-1-lczerner@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 7163 bytes --]

On Nov 24, 2021, at 6:45 AM, Lukas Czerner <lczerner@redhat.com> wrote:
> 
> 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>
> ---
> lib/ext2fs/ext2fs.h    |  1 +
> lib/ext2fs/ismounted.c |  5 +++
> misc/e2label.8.in      |  7 ++-
> misc/tune2fs.8.in      |  8 +++-
> misc/tune2fs.c         | 96 ++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 114 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
> index 0ee0e7d0..68f9c1fe 100644
> --- a/lib/ext2fs/ext2fs.h
> +++ b/lib/ext2fs/ext2fs.h
> @@ -531,6 +531,7 @@ typedef struct ext2_struct_inode_scan *ext2_inode_scan;
> #define EXT2_MF_READONLY	4
> #define EXT2_MF_SWAP		8
> #define EXT2_MF_BUSY		16
> +#define EXT2_MF_EXTFS		32
> 
> /*
>  * Ext2/linux mode flags.  We define them here so that we don't need
> diff --git a/lib/ext2fs/ismounted.c b/lib/ext2fs/ismounted.c
> index aee7d726..c73273b8 100644
> --- a/lib/ext2fs/ismounted.c
> +++ b/lib/ext2fs/ismounted.c
> @@ -207,6 +207,11 @@ is_root:
> 			close(fd);
> 		(void) unlink(TEST_FILE);
> 	}
> +
> +	if (!strcmp(mnt->mnt_type, "ext4") ||
> +	    !strcmp(mnt->mnt_type, "ext3") ||
> +	    !strcmp(mnt->mnt_type, "ext2"))

IMHO, using "!strcmp(...)" reads like "not matching the string ...", so I prefer
to use "strcmp(...) == 0".

> +		*mount_flags |= EXT2_MF_EXTFS;
> 	retval = 0;
> errout:
> 	endmntent (f);
> diff --git a/misc/e2label.8.in b/misc/e2label.8.in
> index 1dc96199..fa5294c4 100644
> --- a/misc/e2label.8.in
> +++ b/misc/e2label.8.in
> @@ -33,7 +33,12 @@ Ext2 volume labels can be at most 16 characters long; if
> .I volume-label
> is longer than 16 characters,
> .B e2label
> -will truncate it and print a warning message.
> +will truncate it and print a warning message.  For other file systems that
> +support online label manipulation and are mounted
> +.B e2label
> +will work as well, but it will not attempt to truncate the
> +.I volume-label
> +at all.
> .PP
> It is also possible to set the volume label using the
> .B \-L
> diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in
> index 1e026e5f..628dcdc0 100644
> --- a/misc/tune2fs.8.in
> +++ b/misc/tune2fs.8.in
> @@ -457,8 +457,12 @@ Ext2 file system labels can be at most 16 characters long; if
> .I volume-label
> is longer than 16 characters,
> .B tune2fs
> -will truncate it and print a warning.  The volume label can be used
> -by
> +will truncate it and print a warning.  For other file systems that
> +support online label manipulation and are mounted
> +.B tune2fs
> +will work as well, but it will not attempt to truncate the
> +.I volume-label
> +at all.  The volume label can be used by
> .BR mount (8),
> .BR fsck (8),
> and
> 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);

Opening read-only to change the label is a bit strange?  It would be better
to open in write mode, and verify in the kernel that this is the case:

	fd = open(mntpt, setlabel ? O_WRONLY : 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;
> --
> 2.31.1
> 


Cheers, Andreas






[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 873 bytes --]

  reply	other threads:[~2021-11-27 21:25 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-24 13:45 [PATCH] tune2fs: implement support for set/get label iocts Lukas Czerner
2021-11-27 21:23 ` Andreas Dilger [this message]
2021-11-29  9:36   ` Lukas Czerner
2021-11-29 20:19     ` Andreas Dilger
2022-01-05  3:14 ` Theodore Ts'o

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1563F233-9CCB-486E-AC87-7B752EED8ABA@dilger.ca \
    --to=adilger@dilger.ca \
    --cc=lczerner@redhat.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox