public inbox for linux-fsdevel@vger.kernel.org
 help / color / mirror / Atom feed
From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
To: Ethan Ferguson <ethan.ferguson@zetier.com>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 2/2] fat: Add FS_IOC_SETFSLABEL ioctl
Date: Wed, 18 Feb 2026 16:22:35 +0900	[thread overview]
Message-ID: <871piifrd0.fsf@mail.parknet.co.jp> (raw)
In-Reply-To: <20260217230628.719475-3-ethan.ferguson@zetier.com>

Ethan Ferguson <ethan.ferguson@zetier.com> writes:

> Add support for writing to the volume label of a FAT filesystem via the
> FS_IOC_SETFSLABEL ioctl.
>
> Signed-off-by: Ethan Ferguson <ethan.ferguson@zetier.com>
> ---
>  fs/fat/dir.c         | 51 +++++++++++++++++++++++++++++++++++
>  fs/fat/fat.h         |  6 +++++
>  fs/fat/file.c        | 63 ++++++++++++++++++++++++++++++++++++++++++++
>  fs/fat/inode.c       | 15 +++++++++++
>  fs/fat/namei_msdos.c |  4 +--
>  5 files changed, 137 insertions(+), 2 deletions(-)
>
> diff --git a/fs/fat/dir.c b/fs/fat/dir.c
> index 07d95f1442c8..1b11713309ae 100644
> --- a/fs/fat/dir.c
> +++ b/fs/fat/dir.c
> @@ -1425,3 +1425,54 @@ int fat_add_entries(struct inode *dir, void *slots, int nr_slots,
>  	return err;
>  }
>  EXPORT_SYMBOL_GPL(fat_add_entries);
> +
> +static int fat_create_volume_label_dentry(struct super_block *sb, char *vol_label)
> +{
> +	struct msdos_sb_info *sbi = MSDOS_SB(sb);
> +	struct inode *root_inode = sb->s_root->d_inode;
> +	struct msdos_dir_entry de;
> +	struct fat_slot_info sinfo;
> +	struct timespec64 ts = current_time(root_inode);
> +	__le16 date, time;
> +	u8 time_cs;
> +
> +	memcpy(de.name, vol_label, MSDOS_NAME);
> +	de.attr = ATTR_VOLUME;
> +	de.starthi = de.start = de.size = de.lcase = 0;
> +
> +	fat_time_unix2fat(sbi, &ts, &time, &date, &time_cs);
> +	de.time = time;
> +	de.date = date;
> +	if (sbi->options.isvfat) {
> +		de.cdate = de.adate = date;
> +		de.ctime = time;
> +		de.ctime_cs = time_cs;
> +	} else
> +		de.cdate = de.adate = de.ctime = de.ctime_cs = 0;
> +
> +	return fat_add_entries(root_inode, &de, 1, &sinfo);
> +}
> +
> +int fat_rename_volume_label_dentry(struct super_block *sb, char *vol_label)
> +{
> +	struct inode *root_inode = sb->s_root->d_inode;
> +	struct buffer_head *bh = NULL;
> +	struct msdos_dir_entry *de;
> +	loff_t cpos = 0;
> +	int err = 0;
> +
> +	while (1) {
> +		if (fat_get_entry(root_inode, &cpos, &bh, &de) == -1)
> +			return fat_create_volume_label_dentry(sb, vol_label);
> +
> +		if (de->attr == ATTR_VOLUME) {
> +			memcpy(de->name, vol_label, MSDOS_NAME);
> +			mark_buffer_dirty_inode(bh, root_inode);
> +			if (IS_DIRSYNC(root_inode))
> +				err = sync_dirty_buffer(bh);
> +			brelse(bh);
> +			return err;
> +		}
> +	}

I didn't check how to know the label though, the label is only if
ATTR_VOLUME? IOW, any other attributes are disallowed?

What if label is marked as deleted?

I'm not sure though, no need to update timestamps? (need to investigate
spec or windows behavior)

> +static int fat_convert_volume_label_str(struct msdos_sb_info *sbi, char *in,
> +					char *out)
> +{
> +	int ret, in_len = max(strnlen(in, FSLABEL_MAX), 11);
> +	char *needle;

Silently truncate is the common way for this ioctl?

> +	/*
> +	 * '.' is not included in any bad_chars list in this driver,
> +	 * but it is specifically not allowed for volume labels
> +	 */
> +	for (needle = in; needle - in < in_len; needle++)
> +		if (*needle == '.')
> +			return -EINVAL;

memchr() or such?

> +	ret = msdos_format_name(in, in_len, out, &sbi->options);
> +	if (ret)
> +		return ret;

> +	/*
> +	 * msdos_format_name assumes we're translating an 8.3 name, but
> +	 * we can handle 11 chars
> +	 */
> +	if (in_len > 8)
> +		ret = msdos_format_name(in + 8, in_len - 8, out + 8,
> +					&sbi->options);
> +	return ret;

fat module should not import msdos module.

> +static int fat_ioctl_set_volume_label(struct super_block *sb, char __user *arg)
> +{
> +	struct msdos_sb_info *sbi = MSDOS_SB(sb);
> +	struct inode *root_inode = sb->s_root->d_inode;
> +	char from_user[FSLABEL_MAX];
> +	char new_vol_label[MSDOS_NAME];
> +	int ret;
> +
> +	if (!capable(CAP_SYS_ADMIN))
> +		return -EPERM;
> +
> +	if (sb_rdonly(sb))
> +		return -EROFS;
> +
> +	if (copy_from_user(from_user, arg, FSLABEL_MAX))
> +		return -EFAULT;
> +
> +	ret = fat_convert_volume_label_str(sbi, from_user, new_vol_label);
> +	if (ret)
> +		return ret;
> +
> +	inode_lock(root_inode);
> +	ret = fat_rename_volume_label_dentry(sb, new_vol_label);
> +	inode_unlock(root_inode);
> +	if (ret)
> +		return ret;

This rename will have to take same or similar locks with rename(2)?

> diff --git a/fs/fat/inode.c b/fs/fat/inode.c
> index 6f9a8cc1ad2a..a7528937383b 100644
> --- a/fs/fat/inode.c
> +++ b/fs/fat/inode.c
> @@ -736,6 +736,21 @@ static void delayed_free(struct rcu_head *p)
>  static void fat_put_super(struct super_block *sb)
>  {
>  	struct msdos_sb_info *sbi = MSDOS_SB(sb);
> +	struct buffer_head *bh = NULL;
> +	struct fat_boot_sector *bs;
> +
> +	bh = sb_bread(sb, 0);
> +	if (bh == NULL)
> +		fat_msg(sb, KERN_ERR, "unable to read boot sector");
> +	else if (!sb_rdonly(sb)) {
> +		bs = (struct fat_boot_sector *)bh->b_data;
> +		if (is_fat32(sbi))
> +			memcpy(bs->fat32.vol_label, sbi->vol_label, MSDOS_NAME);
> +		else
> +			memcpy(bs->fat16.vol_label, sbi->vol_label, MSDOS_NAME);
> +		mark_buffer_dirty(bh);
> +	}
> +	brelse(bh);

Why this unconditionally update the vol_label at unmount?

Thanks.
-- 
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

  parent reply	other threads:[~2026-02-18  7:22 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-17 23:06 [PATCH v2 0/2] fat: Add FS_IOC_GETFSLABEL / FS_IOC_SETFSLABEL ioctls Ethan Ferguson
2026-02-17 23:06 ` [PATCH v2 1/2] fat: Add FS_IOC_GETFSLABEL ioctl Ethan Ferguson
2026-02-17 23:06 ` [PATCH v2 2/2] fat: Add FS_IOC_SETFSLABEL ioctl Ethan Ferguson
2026-02-18  6:50   ` kernel test robot
2026-02-18  7:21   ` kernel test robot
2026-02-18  7:22   ` OGAWA Hirofumi [this message]
2026-02-18 10:22   ` kernel test robot
2026-02-18 16:26   ` kernel test robot
2026-02-18  8:46 ` [syzbot ci] Re: fat: Add FS_IOC_GETFSLABEL / FS_IOC_SETFSLABEL ioctls syzbot ci
  -- strict thread matches above, loose matches on Subject: below --
2026-02-18 16:01 [PATCH v2 2/2] fat: Add FS_IOC_SETFSLABEL ioctl Ethan Ferguson
2026-02-18 18:42 ` OGAWA Hirofumi

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=871piifrd0.fsf@mail.parknet.co.jp \
    --to=hirofumi@mail.parknet.co.jp \
    --cc=ethan.ferguson@zetier.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /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