diff options
author | Mike Lockwood <lockwood@android.com> | 2008-03-15 13:29:36 -0400 |
---|---|---|
committer | mgross <mark.gross@intel.com> | 2011-11-09 12:01:59 -0800 |
commit | 109f68da1bbcae5e8d0a11bbbbbf9508251aab16 (patch) | |
tree | aae43fcc86fc7353d89107ce37e8ea459b4ac7a2 | |
parent | 759e25bf5530ffac18138c2e36483e142e77b09c (diff) | |
download | kernel-mfld-blackbay-109f68da1bbcae5e8d0a11bbbbbf9508251aab16.tar.gz kernel-mfld-blackbay-109f68da1bbcae5e8d0a11bbbbbf9508251aab16.tar.bz2 kernel-mfld-blackbay-109f68da1bbcae5e8d0a11bbbbbf9508251aab16.zip |
FAT: Add new ioctl VFAT_IOCTL_GET_VOLUME_ID for reading the volume ID.
Signed-off-by: Brian Swetland <swetland@google.com>
-rw-r--r-- | fs/fat/dir.c | 9 | ||||
-rw-r--r-- | fs/fat/fat.h | 1 | ||||
-rw-r--r-- | fs/fat/inode.c | 9 | ||||
-rw-r--r-- | include/linux/msdos_fs.h | 12 |
4 files changed, 31 insertions, 0 deletions
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 4ad64732cbc..dc563788fa8 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -754,6 +754,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 long fat_dir_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -770,6 +777,8 @@ static long fat_dir_ioctl(struct file *filp, unsigned int cmd, short_only = 0; both = 1; break; + case VFAT_IOCTL_GET_VOLUME_ID: + return fat_ioctl_volume_id(inode); default: return fat_generic_ioctl(filp, cmd, arg); } diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 8276cc282de..74fe5d3ed01 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -78,6 +78,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 cb8d8391ac0..9836839e0eb 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1245,6 +1245,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, struct inode *root_inode = NULL, *fat_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; @@ -1390,6 +1391,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, 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)) { fat_msg(sb, KERN_WARNING, "Invalid FSINFO signature: " @@ -1405,8 +1408,14 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, } 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; diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index 34066e65fde..f38d4f0a5ae 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -101,6 +101,7 @@ struct __fat_dirent { /* <linux/videotext.h> has used 0x72 ('r') in collision, so skip a few */ #define FAT_IOCTL_GET_ATTRIBUTES _IOR('r', 0x10, __u32) #define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32) +#define VFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32) struct fat_boot_sector { __u8 ignored[3]; /* Boot strap short or near jump */ @@ -138,6 +139,17 @@ struct fat_boot_fsinfo { __le32 reserved2[4]; }; +struct fat_boot_bsx { + __u8 drive; /* drive number */ + __u8 reserved1; + __u8 signature; /* extended boot signature */ + __u8 vol_id[4]; /* volume ID */ + __u8 vol_label[11]; /* volume label */ + __u8 type[8]; /* file system type */ +}; +#define FAT16_BSX_OFFSET 36 /* offset of fat_boot_bsx in FAT12 and FAT16 */ +#define FAT32_BSX_OFFSET 64 /* offset of fat_boot_bsx in FAT32 */ + struct msdos_dir_entry { __u8 name[MSDOS_NAME];/* name and extension */ __u8 attr; /* attribute bits */ |