From 82e4ab6ebfb388e9fc2dffc9fa25639d5c817212 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Sat, 15 Mar 2008 13:29:36 -0400 Subject: FAT: Add new ioctl VFAT_IOCTL_GET_VOLUME_ID for reading the volume ID. Signed-off-by: Brian Swetland --- fs/fat/dir.c | 9 +++++++++ fs/fat/fat.h | 1 + fs/fat/inode.c | 9 +++++++++ 3 files changed, 19 insertions(+) (limited to 'fs') diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 3a7f603b6982..cc27b195b709 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -758,6 +758,13 @@ static int fat_ioctl_readdir(struct inode *inode, struct file *filp, return ret; } +static int fat_ioctl_volume_id(struct inode *dir) +{ + struct super_block *sb = dir->i_sb; + struct msdos_sb_info *sbi = MSDOS_SB(sb); + return sbi->vol_id; +} + static int fat_dir_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { @@ -773,6 +780,8 @@ static int fat_dir_ioctl(struct inode *inode, struct file *filp, short_only = 0; both = 1; break; + case VFAT_IOCTL_GET_VOLUME_ID: + return fat_ioctl_volume_id(inode); default: return fat_generic_ioctl(inode, filp, cmd, arg); } diff --git a/fs/fat/fat.h b/fs/fat/fat.h index ea440d65819c..5ba287715146 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -71,6 +71,7 @@ struct msdos_sb_info { const void *dir_ops; /* Opaque; default directory operations */ int dir_per_block; /* dir entries per block */ int dir_per_block_bits; /* log2(dir_per_block) */ + unsigned long vol_id; /* volume ID */ int fatent_shift; struct fatent_operations *fatent_ops; diff --git a/fs/fat/inode.c b/fs/fat/inode.c index de0004fe6e00..e8456c6637ca 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1173,6 +1173,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, struct inode *root_inode = NULL; struct buffer_head *bh; struct fat_boot_sector *b; + struct fat_boot_bsx *bsx; struct msdos_sb_info *sbi; u16 logical_sector_size; u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors; @@ -1315,6 +1316,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, goto out_fail; } + bsx = (struct fat_boot_bsx *)(bh->b_data + FAT32_BSX_OFFSET); + fsinfo = (struct fat_boot_fsinfo *)fsinfo_bh->b_data; if (!IS_FSINFO(fsinfo)) { printk(KERN_WARNING "FAT: Invalid FSINFO signature: " @@ -1330,8 +1333,14 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, } brelse(fsinfo_bh); + } else { + bsx = (struct fat_boot_bsx *)(bh->b_data + FAT16_BSX_OFFSET); } + /* interpret volume ID as a little endian 32 bit integer */ + sbi->vol_id = (((u32)bsx->vol_id[0]) | ((u32)bsx->vol_id[1] << 8) | + ((u32)bsx->vol_id[2] << 16) | ((u32)bsx->vol_id[3] << 24)); + sbi->dir_per_block = sb->s_blocksize / sizeof(struct msdos_dir_entry); sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1; -- cgit v1.2.3