Add support for reading the volume label of a FAT filesystem via the FS_IOC_GETFSLABEL ioctl. Signed-off-by: Ethan Ferguson --- fs/fat/fat.h | 1 + fs/fat/file.c | 9 +++++++++ fs/fat/inode.c | 11 +++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/fs/fat/fat.h b/fs/fat/fat.h index d3e426de5f01..db9c854ddef8 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -89,6 +89,7 @@ struct msdos_sb_info { int dir_per_block; /* dir entries per block */ int dir_per_block_bits; /* log2(dir_per_block) */ unsigned int vol_id; /*volume ID*/ + char vol_label[MSDOS_NAME]; /* volume label */ int fatent_shift; const struct fatent_operations *fatent_ops; diff --git a/fs/fat/file.c b/fs/fat/file.c index 4fc49a614fb8..c55a99009a9c 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -153,6 +153,13 @@ static int fat_ioctl_fitrim(struct inode *inode, unsigned long arg) return 0; } +static int fat_ioctl_get_volume_label(struct inode *inode, char __user *arg) +{ + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); + + return copy_to_user(arg, sbi->vol_label, MSDOS_NAME); +} + long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(filp); @@ -165,6 +172,8 @@ long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return fat_ioctl_set_attributes(filp, user_attr); case FAT_IOCTL_GET_VOLUME_ID: return fat_ioctl_get_volume_id(inode, user_attr); + case FS_IOC_GETFSLABEL: + return fat_ioctl_get_volume_label(inode, (char __user *) arg); case FITRIM: return fat_ioctl_fitrim(inode, arg); default: diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 0b6009cd1844..f6bd3f079e74 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -53,12 +53,14 @@ struct fat_bios_param_block { u8 fat16_state; u32 fat16_vol_id; + u8 fat16_vol_label[MSDOS_NAME]; u32 fat32_length; u32 fat32_root_cluster; u16 fat32_info_sector; u8 fat32_state; u32 fat32_vol_id; + u8 fat32_vol_label[MSDOS_NAME]; }; static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE; @@ -1406,12 +1408,14 @@ static int fat_read_bpb(struct super_block *sb, struct fat_boot_sector *b, bpb->fat16_state = b->fat16.state; bpb->fat16_vol_id = get_unaligned_le32(b->fat16.vol_id); + memcpy(bpb->fat16_vol_label, b->fat16.vol_label, MSDOS_NAME); bpb->fat32_length = le32_to_cpu(b->fat32.length); bpb->fat32_root_cluster = le32_to_cpu(b->fat32.root_cluster); bpb->fat32_info_sector = le16_to_cpu(b->fat32.info_sector); bpb->fat32_state = b->fat32.state; bpb->fat32_vol_id = get_unaligned_le32(b->fat32.vol_id); + memcpy(bpb->fat32_vol_label, b->fat32.vol_label, MSDOS_NAME); /* Validate this looks like a FAT filesystem BPB */ if (!bpb->fat_reserved) { @@ -1708,10 +1712,13 @@ int fat_fill_super(struct super_block *sb, struct fs_context *fc, } /* interpret volume ID as a little endian 32 bit integer */ - if (is_fat32(sbi)) + if (is_fat32(sbi)) { sbi->vol_id = bpb.fat32_vol_id; - else /* fat 16 or 12 */ + memcpy(sbi->vol_label, bpb.fat32_vol_label, MSDOS_NAME); + } else { /* fat 16 or 12 */ sbi->vol_id = bpb.fat16_vol_id; + memcpy(sbi->vol_label, bpb.fat16_vol_label, MSDOS_NAME); + } __le32 vol_id_le = cpu_to_le32(sbi->vol_id); super_set_uuid(sb, (void *) &vol_id_le, sizeof(vol_id_le)); -- 2.53.0