diff options
-rw-r--r-- | fs/fat/fat.h | 1 | ||||
-rw-r--r-- | fs/fat/file.c | 8 | ||||
-rw-r--r-- | fs/fat/inode.c | 12 | ||||
-rw-r--r-- | include/uapi/linux/msdos_fs.h | 10 |
4 files changed, 31 insertions, 0 deletions
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 21664fcf3616..4241e6f39e86 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
@@ -86,6 +86,7 @@ struct msdos_sb_info { | |||
86 | const void *dir_ops; /* Opaque; default directory operations */ | 86 | const void *dir_ops; /* Opaque; default directory operations */ |
87 | int dir_per_block; /* dir entries per block */ | 87 | int dir_per_block; /* dir entries per block */ |
88 | int dir_per_block_bits; /* log2(dir_per_block) */ | 88 | int dir_per_block_bits; /* log2(dir_per_block) */ |
89 | unsigned int vol_id; /*volume ID*/ | ||
89 | 90 | ||
90 | int fatent_shift; | 91 | int fatent_shift; |
91 | struct fatent_operations *fatent_ops; | 92 | struct fatent_operations *fatent_ops; |
diff --git a/fs/fat/file.c b/fs/fat/file.c index b0b632e50ddb..9b104f543056 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -114,6 +114,12 @@ out: | |||
114 | return err; | 114 | return err; |
115 | } | 115 | } |
116 | 116 | ||
117 | static int fat_ioctl_get_volume_id(struct inode *inode, u32 __user *user_attr) | ||
118 | { | ||
119 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); | ||
120 | return put_user(sbi->vol_id, user_attr); | ||
121 | } | ||
122 | |||
117 | long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 123 | long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
118 | { | 124 | { |
119 | struct inode *inode = file_inode(filp); | 125 | struct inode *inode = file_inode(filp); |
@@ -124,6 +130,8 @@ long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
124 | return fat_ioctl_get_attributes(inode, user_attr); | 130 | return fat_ioctl_get_attributes(inode, user_attr); |
125 | case FAT_IOCTL_SET_ATTRIBUTES: | 131 | case FAT_IOCTL_SET_ATTRIBUTES: |
126 | return fat_ioctl_set_attributes(filp, user_attr); | 132 | return fat_ioctl_set_attributes(filp, user_attr); |
133 | case FAT_IOCTL_GET_VOLUME_ID: | ||
134 | return fat_ioctl_get_volume_id(inode, user_attr); | ||
127 | default: | 135 | default: |
128 | return -ENOTTY; /* Inappropriate ioctl for device */ | 136 | return -ENOTTY; /* Inappropriate ioctl for device */ |
129 | } | 137 | } |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 5d4513cb1b3c..11b51bb55b42 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -1415,6 +1415,18 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1415 | brelse(fsinfo_bh); | 1415 | brelse(fsinfo_bh); |
1416 | } | 1416 | } |
1417 | 1417 | ||
1418 | /* interpret volume ID as a little endian 32 bit integer */ | ||
1419 | if (sbi->fat_bits == 32) | ||
1420 | sbi->vol_id = (((u32)b->fat32.vol_id[0]) | | ||
1421 | ((u32)b->fat32.vol_id[1] << 8) | | ||
1422 | ((u32)b->fat32.vol_id[2] << 16) | | ||
1423 | ((u32)b->fat32.vol_id[3] << 24)); | ||
1424 | else /* fat 16 or 12 */ | ||
1425 | sbi->vol_id = (((u32)b->fat16.vol_id[0]) | | ||
1426 | ((u32)b->fat16.vol_id[1] << 8) | | ||
1427 | ((u32)b->fat16.vol_id[2] << 16) | | ||
1428 | ((u32)b->fat16.vol_id[3] << 24)); | ||
1429 | |||
1418 | sbi->dir_per_block = sb->s_blocksize / sizeof(struct msdos_dir_entry); | 1430 | sbi->dir_per_block = sb->s_blocksize / sizeof(struct msdos_dir_entry); |
1419 | sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1; | 1431 | sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1; |
1420 | 1432 | ||
diff --git a/include/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h index f055e58b3147..e284ff919d6e 100644 --- a/include/uapi/linux/msdos_fs.h +++ b/include/uapi/linux/msdos_fs.h | |||
@@ -104,6 +104,8 @@ struct __fat_dirent { | |||
104 | /* <linux/videotext.h> has used 0x72 ('r') in collision, so skip a few */ | 104 | /* <linux/videotext.h> has used 0x72 ('r') in collision, so skip a few */ |
105 | #define FAT_IOCTL_GET_ATTRIBUTES _IOR('r', 0x10, __u32) | 105 | #define FAT_IOCTL_GET_ATTRIBUTES _IOR('r', 0x10, __u32) |
106 | #define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32) | 106 | #define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32) |
107 | /*Android kernel has used 0x12, so we use 0x13*/ | ||
108 | #define FAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x13, __u32) | ||
107 | 109 | ||
108 | struct fat_boot_sector { | 110 | struct fat_boot_sector { |
109 | __u8 ignored[3]; /* Boot strap short or near jump */ | 111 | __u8 ignored[3]; /* Boot strap short or near jump */ |
@@ -128,6 +130,10 @@ struct fat_boot_sector { | |||
128 | __u8 drive_number; /* Physical drive number */ | 130 | __u8 drive_number; /* Physical drive number */ |
129 | __u8 state; /* undocumented, but used | 131 | __u8 state; /* undocumented, but used |
130 | for mount state. */ | 132 | for mount state. */ |
133 | __u8 signature; /* extended boot signature */ | ||
134 | __u8 vol_id[4]; /* volume ID */ | ||
135 | __u8 vol_label[11]; /* volume label */ | ||
136 | __u8 fs_type[8]; /* file system type */ | ||
131 | /* other fiealds are not added here */ | 137 | /* other fiealds are not added here */ |
132 | } fat16; | 138 | } fat16; |
133 | 139 | ||
@@ -147,6 +153,10 @@ struct fat_boot_sector { | |||
147 | __u8 drive_number; /* Physical drive number */ | 153 | __u8 drive_number; /* Physical drive number */ |
148 | __u8 state; /* undocumented, but used | 154 | __u8 state; /* undocumented, but used |
149 | for mount state. */ | 155 | for mount state. */ |
156 | __u8 signature; /* extended boot signature */ | ||
157 | __u8 vol_id[4]; /* volume ID */ | ||
158 | __u8 vol_label[11]; /* volume label */ | ||
159 | __u8 fs_type[8]; /* file system type */ | ||
150 | /* other fiealds are not added here */ | 160 | /* other fiealds are not added here */ |
151 | } fat32; | 161 | } fat32; |
152 | }; | 162 | }; |