* [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID
@ 2013-07-01 2:39 bintian.wang
2013-07-01 6:12 ` OGAWA Hirofumi
0 siblings, 1 reply; 9+ messages in thread
From: bintian.wang @ 2013-07-01 2:39 UTC (permalink / raw)
To: linux-kernel
Cc: Mike Lockwood, dmitry pervushin, Colin Cross,
Android Kernel Team, OGAWA Hirofumi, Andrew Morton, John Stultz,
Bintian Wang
From: Mike Lockwood <lockwood@android.com>
This patch, originally from Android kernel, adds vfat directory ioctl command
FAT_IOCTL_GET_VOLUME_ID, with this command we can get the vfat volume ID using
following code:
ioctl(dirfd(dir), FAT_IOCTL_GET_VOLUME_ID, &volume_ID)
This patch is a modified version of the patch by Mike Lockwood, with changes
from Dmitry Pervushin, who noticed the original patch makes some volume IDs
abiguous with error returns: for example, if volume id is 0xFFFFFDAD, that
matches -ENOIOCTLCMD, we get "FFFFFFFF" from the user space.
So add a parameter to ioctl to get the correct volume ID.
Cc: dmitry pervushin <dpervushin@gmail.com>
Cc: Mike Lockwood <lockwood@android.com>
Cc: Colin Cross <ccross@android.com>
Cc: Android Kernel Team <kernel-team@android.com>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: Bintian Wang <bintian.wang@linaro.org>
---
fs/fat/dir.c | 14 ++++++++++++++
fs/fat/fat.h | 1 +
fs/fat/inode.c | 9 +++++++++
include/uapi/linux/msdos_fs.h | 13 +++++++++++++
4 files changed, 37 insertions(+)
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 7a6f02c..4c59108 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -776,12 +776,19 @@ static int fat_ioctl_readdir(struct inode *inode, struct file *filp,
return ret;
}
+static unsigned int fat_ioctl_volume_id(struct inode *inode)
+{
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+ return sbi->vol_id;
+}
+
static long fat_dir_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct inode *inode = file_inode(filp);
struct __fat_dirent __user *d1 = (struct __fat_dirent __user *)arg;
int short_only, both;
+ unsigned int id;
switch (cmd) {
case VFAT_IOCTL_READDIR_SHORT:
@@ -792,6 +799,9 @@ static long fat_dir_ioctl(struct file *filp, unsigned int cmd,
short_only = 0;
both = 1;
break;
+ case FAT_IOCTL_GET_VOLUME_ID:
+ id = fat_ioctl_volume_id(inode);
+ return copy_to_user((unsigned int *)arg, &id, sizeof(id));
default:
return fat_generic_ioctl(filp, cmd, arg);
}
@@ -822,6 +832,7 @@ static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd,
struct inode *inode = file_inode(filp);
struct compat_dirent __user *d1 = compat_ptr(arg);
int short_only, both;
+ unsigned int id;
switch (cmd) {
case VFAT_IOCTL_READDIR_SHORT32:
@@ -832,6 +843,9 @@ static long fat_compat_dir_ioctl(struct file *filp, unsigned cmd,
short_only = 0;
both = 1;
break;
+ case FAT_IOCTL_GET_VOLUME_ID:
+ id = fat_ioctl_volume_id(inode);
+ return copy_to_user((unsigned int *)arg, &id, sizeof(id));
default:
return fat_generic_ioctl(filp, cmd, (unsigned long)arg);
}
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 21664fc..4241e6f 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -86,6 +86,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 int 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 5d4513c..a14dd4c 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -1252,6 +1252,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
struct inode *fsinfo_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;
@@ -1398,6 +1399,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: "
@@ -1413,8 +1416,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/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h
index f055e58..be142ee 100644
--- a/include/uapi/linux/msdos_fs.h
+++ b/include/uapi/linux/msdos_fs.h
@@ -104,6 +104,8 @@ 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)
+/*Android kernel has used 0x12, so we use 0x13*/
+#define FAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x13, __u32)
struct fat_boot_sector {
__u8 ignored[3]; /* Boot strap short or near jump */
@@ -161,6 +163,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 */
--
1.7.9.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID
2013-07-01 2:39 [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID bintian.wang
@ 2013-07-01 6:12 ` OGAWA Hirofumi
2013-07-01 6:19 ` OGAWA Hirofumi
0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2013-07-01 6:12 UTC (permalink / raw)
To: bintian.wang
Cc: linux-kernel, Mike Lockwood, dmitry pervushin, Colin Cross,
Android Kernel Team, Andrew Morton, John Stultz
bintian.wang@linaro.org writes:
> This patch, originally from Android kernel, adds vfat directory ioctl command
> FAT_IOCTL_GET_VOLUME_ID, with this command we can get the vfat volume ID using
> following code:
>
> ioctl(dirfd(dir), FAT_IOCTL_GET_VOLUME_ID, &volume_ID)
>
> This patch is a modified version of the patch by Mike Lockwood, with changes
> from Dmitry Pervushin, who noticed the original patch makes some volume IDs
> abiguous with error returns: for example, if volume id is 0xFFFFFDAD, that
> matches -ENOIOCTLCMD, we get "FFFFFFFF" from the user space.
>
> So add a parameter to ioctl to get the correct volume ID.
Adding more specific usage example to changelog would help for
understanding this.
> + case FAT_IOCTL_GET_VOLUME_ID:
> + id = fat_ioctl_volume_id(inode);
> + return copy_to_user((unsigned int *)arg, &id, sizeof(id));
> + case FAT_IOCTL_GET_VOLUME_ID:
> + id = fat_ioctl_volume_id(inode);
> + return copy_to_user((unsigned int *)arg, &id, sizeof(id));
This pattern seems to from put_user().
Unnecessary cast of 1st arg. And copy_to_user() returns remaining bytes
when fail (not error code).
> +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 */
There is any issue to merge those to "struct fat_boot_sector"? I guess,
merging it is cleaner way.
Thanks.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID
2013-07-01 6:12 ` OGAWA Hirofumi
@ 2013-07-01 6:19 ` OGAWA Hirofumi
[not found] ` <CAJ2TvK=SVMfuFw+U46z-iCS1sYZgnmdk+sr30NeNFTayot7g8g@mail.gmail.com>
0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2013-07-01 6:19 UTC (permalink / raw)
To: bintian.wang
Cc: linux-kernel, Mike Lockwood, dmitry pervushin, Colin Cross,
Android Kernel Team, Andrew Morton, John Stultz
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> writes:
>> + case FAT_IOCTL_GET_VOLUME_ID:
>> + id = fat_ioctl_volume_id(inode);
>> + return copy_to_user((unsigned int *)arg, &id, sizeof(id));
>
>> + case FAT_IOCTL_GET_VOLUME_ID:
>> + id = fat_ioctl_volume_id(inode);
>> + return copy_to_user((unsigned int *)arg, &id, sizeof(id));
>
> This pattern seems to from put_user().
>
> Unnecessary cast of 1st arg. And copy_to_user() returns remaining bytes
> when fail (not error code).
Ah, actually, this needs cast, but it is to annotate for sparse. Well,
is there any reason to restrict this only on the directory?
For now, fat_generic_ioctl() looks easier way to do this.
(fat_generic_ioctl() should work for the both of compat code and dir/file)
Thanks.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID
[not found] ` <CAO+d-qrq9XD2d0FtoA7ZkCsSkka0sfgERb-OeNoU2kLXpF+PVA@mail.gmail.com>
@ 2013-07-01 9:29 ` OGAWA Hirofumi
[not found] ` <CAO+d-qqs0uUqNcmOhgZdKeaJQxd5y+TyKVFSpgknoUkX2YidfQ@mail.gmail.com>
0 siblings, 1 reply; 9+ messages in thread
From: OGAWA Hirofumi @ 2013-07-01 9:29 UTC (permalink / raw)
To: dmitry pervushin
Cc: Bintian Wang, linux-kernel, Mike Lockwood, Colin Cross,
Android Kernel Team, Andrew Morton, John Stultz
dmitry pervushin <dpervushin@gmail.com> writes:
> Hello Bintian,
>
> The original idea discussed with John was to allow
> FAT_IOCTL_GET_VOLUME_ID (broken or not) only on directory nodes, and
> even on the root directory node. That's why it is should be *not* in
> fat_generic_ioctl.
The question would be, why do we have to limit only on directory?
When I'm reviewing this, I recalled fstatvfs(2) as referenced one. The
both get the info of fs. fstatvfs(2) doesn't limit only on
directory. But, in the FAT_IOCTL_GET_VOLUME_ID case, it limits.
I wonder why?
Thanks.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID
[not found] ` <CAO+d-qqs0uUqNcmOhgZdKeaJQxd5y+TyKVFSpgknoUkX2YidfQ@mail.gmail.com>
@ 2013-07-01 11:43 ` OGAWA Hirofumi
0 siblings, 0 replies; 9+ messages in thread
From: OGAWA Hirofumi @ 2013-07-01 11:43 UTC (permalink / raw)
To: dmitry pervushin
Cc: Bintian Wang, linux-kernel, Mike Lockwood, Colin Cross,
Android Kernel Team, Andrew Morton, John Stultz
dmitry pervushin <dpervushin@gmail.com> writes:
> Honestly, I do not understand why getting volume id might be the
> function of the mounted filesystem. I'd rather think about generic
> function "filesystem id" of the block device.
I see. Yes, I have same question too.
> But if we decided to implement getting volume id from the filesystem,
> then getting it from the root of the filesystem (but not from any
> subdirectory of it and even not from files) makes sense for me.
Hm, finding the mount point and open fd (for only this) would be
inconvenient, and need some costs. Especially, if user is using the
bind mount.
Thanks.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID
2013-07-03 2:19 bintian.wang
@ 2013-07-03 3:22 ` OGAWA Hirofumi
0 siblings, 0 replies; 9+ messages in thread
From: OGAWA Hirofumi @ 2013-07-03 3:22 UTC (permalink / raw)
To: bintian.wang
Cc: linux-kernel, Mike Lockwood, dmitry pervushin, Colin Cross,
Android Kernel Team, Andrew Morton, John Stultz, Sean McNeil
bintian.wang@linaro.org writes:
> From: Mike Lockwood <lockwood@android.com>
>
> This patch, originally from Android kernel, adds vfat ioctl command
> FAT_IOCTL_GET_VOLUME_ID, with this command we can get the vfat volume ID using
> following code:
>
> ioctl(fd, FAT_IOCTL_GET_VOLUME_ID, &volume_ID)
>
> This patch is a modified version of the patch by Mike Lockwood, with changes
> from Dmitry Pervushin, who noticed the original patch makes some volume IDs
> abiguous with error returns: for example, if volume id is 0xFFFFFDAD, that
> matches -ENOIOCTLCMD, we get "FFFFFFFF" from the user space.
>
> So add a parameter to ioctl to get the correct volume ID.
>
> Android uses vfat volume ID to identify different sd card, when a new sd card
> is inserted to device, android can scan the media on it and pop up new contents.
Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Thanks.
> Cc: dmitry pervushin <dpervushin@gmail.com>
> Cc: Mike Lockwood <lockwood@android.com>
> Cc: Colin Cross <ccross@android.com>
> Cc: Android Kernel Team <kernel-team@android.com>
> Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: John Stultz <john.stultz@linaro.org>
> Cc: Sean McNeil <sean@mcneil.com>
>
> Signed-off-by: Bintian Wang <bintian.wang@linaro.org>
> ---
> fs/fat/fat.h | 1 +
> fs/fat/file.c | 8 ++++++++
> fs/fat/inode.c | 12 ++++++++++++
> include/uapi/linux/msdos_fs.h | 10 ++++++++++
> 4 files changed, 31 insertions(+)
>
> diff --git a/fs/fat/fat.h b/fs/fat/fat.h
> index 21664fc..4241e6f 100644
> --- a/fs/fat/fat.h
> +++ b/fs/fat/fat.h
> @@ -86,6 +86,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 int vol_id; /*volume ID*/
>
> int fatent_shift;
> struct fatent_operations *fatent_ops;
> diff --git a/fs/fat/file.c b/fs/fat/file.c
> index b0b632e..9b104f5 100644
> --- a/fs/fat/file.c
> +++ b/fs/fat/file.c
> @@ -114,6 +114,12 @@ out:
> return err;
> }
>
> +static int fat_ioctl_get_volume_id(struct inode *inode, u32 __user *user_attr)
> +{
> + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
> + return put_user(sbi->vol_id, user_attr);
> +}
> +
> long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> {
> struct inode *inode = file_inode(filp);
> @@ -124,6 +130,8 @@ long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> return fat_ioctl_get_attributes(inode, user_attr);
> case FAT_IOCTL_SET_ATTRIBUTES:
> return fat_ioctl_set_attributes(filp, user_attr);
> + case FAT_IOCTL_GET_VOLUME_ID:
> + return fat_ioctl_get_volume_id(inode, user_attr);
> default:
> return -ENOTTY; /* Inappropriate ioctl for device */
> }
> diff --git a/fs/fat/inode.c b/fs/fat/inode.c
> index 5d4513c..11b51bb 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,
> brelse(fsinfo_bh);
> }
>
> + /* interpret volume ID as a little endian 32 bit integer */
> + if (sbi->fat_bits == 32)
> + sbi->vol_id = (((u32)b->fat32.vol_id[0]) |
> + ((u32)b->fat32.vol_id[1] << 8) |
> + ((u32)b->fat32.vol_id[2] << 16) |
> + ((u32)b->fat32.vol_id[3] << 24));
> + else /* fat 16 or 12 */
> + sbi->vol_id = (((u32)b->fat16.vol_id[0]) |
> + ((u32)b->fat16.vol_id[1] << 8) |
> + ((u32)b->fat16.vol_id[2] << 16) |
> + ((u32)b->fat16.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/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h
> index f055e58..e284ff9 100644
> --- a/include/uapi/linux/msdos_fs.h
> +++ b/include/uapi/linux/msdos_fs.h
> @@ -104,6 +104,8 @@ 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)
> +/*Android kernel has used 0x12, so we use 0x13*/
> +#define FAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x13, __u32)
>
> struct fat_boot_sector {
> __u8 ignored[3]; /* Boot strap short or near jump */
> @@ -128,6 +130,10 @@ struct fat_boot_sector {
> __u8 drive_number; /* Physical drive number */
> __u8 state; /* undocumented, but used
> for mount state. */
> + __u8 signature; /* extended boot signature */
> + __u8 vol_id[4]; /* volume ID */
> + __u8 vol_label[11]; /* volume label */
> + __u8 fs_type[8]; /* file system type */
> /* other fiealds are not added here */
> } fat16;
>
> @@ -147,6 +153,10 @@ struct fat_boot_sector {
> __u8 drive_number; /* Physical drive number */
> __u8 state; /* undocumented, but used
> for mount state. */
> + __u8 signature; /* extended boot signature */
> + __u8 vol_id[4]; /* volume ID */
> + __u8 vol_label[11]; /* volume label */
> + __u8 fs_type[8]; /* file system type */
> /* other fiealds are not added here */
> } fat32;
> };
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID
@ 2013-07-03 2:19 bintian.wang
2013-07-03 3:22 ` OGAWA Hirofumi
0 siblings, 1 reply; 9+ messages in thread
From: bintian.wang @ 2013-07-03 2:19 UTC (permalink / raw)
To: linux-kernel
Cc: Mike Lockwood, dmitry pervushin, Colin Cross,
Android Kernel Team, OGAWA Hirofumi, Andrew Morton, John Stultz,
Sean McNeil, Bintian Wang
From: Mike Lockwood <lockwood@android.com>
This patch, originally from Android kernel, adds vfat ioctl command
FAT_IOCTL_GET_VOLUME_ID, with this command we can get the vfat volume ID using
following code:
ioctl(fd, FAT_IOCTL_GET_VOLUME_ID, &volume_ID)
This patch is a modified version of the patch by Mike Lockwood, with changes
from Dmitry Pervushin, who noticed the original patch makes some volume IDs
abiguous with error returns: for example, if volume id is 0xFFFFFDAD, that
matches -ENOIOCTLCMD, we get "FFFFFFFF" from the user space.
So add a parameter to ioctl to get the correct volume ID.
Android uses vfat volume ID to identify different sd card, when a new sd card
is inserted to device, android can scan the media on it and pop up new contents.
Cc: dmitry pervushin <dpervushin@gmail.com>
Cc: Mike Lockwood <lockwood@android.com>
Cc: Colin Cross <ccross@android.com>
Cc: Android Kernel Team <kernel-team@android.com>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Sean McNeil <sean@mcneil.com>
Signed-off-by: Bintian Wang <bintian.wang@linaro.org>
---
fs/fat/fat.h | 1 +
fs/fat/file.c | 8 ++++++++
fs/fat/inode.c | 12 ++++++++++++
include/uapi/linux/msdos_fs.h | 10 ++++++++++
4 files changed, 31 insertions(+)
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 21664fc..4241e6f 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -86,6 +86,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 int vol_id; /*volume ID*/
int fatent_shift;
struct fatent_operations *fatent_ops;
diff --git a/fs/fat/file.c b/fs/fat/file.c
index b0b632e..9b104f5 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -114,6 +114,12 @@ out:
return err;
}
+static int fat_ioctl_get_volume_id(struct inode *inode, u32 __user *user_attr)
+{
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+ return put_user(sbi->vol_id, user_attr);
+}
+
long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct inode *inode = file_inode(filp);
@@ -124,6 +130,8 @@ long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return fat_ioctl_get_attributes(inode, user_attr);
case FAT_IOCTL_SET_ATTRIBUTES:
return fat_ioctl_set_attributes(filp, user_attr);
+ case FAT_IOCTL_GET_VOLUME_ID:
+ return fat_ioctl_get_volume_id(inode, user_attr);
default:
return -ENOTTY; /* Inappropriate ioctl for device */
}
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 5d4513c..11b51bb 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,
brelse(fsinfo_bh);
}
+ /* interpret volume ID as a little endian 32 bit integer */
+ if (sbi->fat_bits == 32)
+ sbi->vol_id = (((u32)b->fat32.vol_id[0]) |
+ ((u32)b->fat32.vol_id[1] << 8) |
+ ((u32)b->fat32.vol_id[2] << 16) |
+ ((u32)b->fat32.vol_id[3] << 24));
+ else /* fat 16 or 12 */
+ sbi->vol_id = (((u32)b->fat16.vol_id[0]) |
+ ((u32)b->fat16.vol_id[1] << 8) |
+ ((u32)b->fat16.vol_id[2] << 16) |
+ ((u32)b->fat16.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/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h
index f055e58..e284ff9 100644
--- a/include/uapi/linux/msdos_fs.h
+++ b/include/uapi/linux/msdos_fs.h
@@ -104,6 +104,8 @@ 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)
+/*Android kernel has used 0x12, so we use 0x13*/
+#define FAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x13, __u32)
struct fat_boot_sector {
__u8 ignored[3]; /* Boot strap short or near jump */
@@ -128,6 +130,10 @@ struct fat_boot_sector {
__u8 drive_number; /* Physical drive number */
__u8 state; /* undocumented, but used
for mount state. */
+ __u8 signature; /* extended boot signature */
+ __u8 vol_id[4]; /* volume ID */
+ __u8 vol_label[11]; /* volume label */
+ __u8 fs_type[8]; /* file system type */
/* other fiealds are not added here */
} fat16;
@@ -147,6 +153,10 @@ struct fat_boot_sector {
__u8 drive_number; /* Physical drive number */
__u8 state; /* undocumented, but used
for mount state. */
+ __u8 signature; /* extended boot signature */
+ __u8 vol_id[4]; /* volume ID */
+ __u8 vol_label[11]; /* volume label */
+ __u8 fs_type[8]; /* file system type */
/* other fiealds are not added here */
} fat32;
};
--
1.7.9.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID
2013-07-01 11:40 bintian.wang
@ 2013-07-01 12:00 ` OGAWA Hirofumi
0 siblings, 0 replies; 9+ messages in thread
From: OGAWA Hirofumi @ 2013-07-01 12:00 UTC (permalink / raw)
To: bintian.wang
Cc: linux-kernel, Mike Lockwood, dmitry pervushin, Colin Cross,
Android Kernel Team, Andrew Morton, John Stultz
bintian.wang@linaro.org writes:
> From: Mike Lockwood <lockwood@android.com>
>
> Adds vfat ioctl command FAT_IOCTL_GET_VOLUME_ID, with this command
> we can get the vfat volume ID using following code:
>
> ioctl(fd, FAT_IOCTL_GET_VOLUME_ID, &volume_ID)
>
> This patch is a modified version of the android kernel patch by Mike Lockwood,
> the original patch makes the return value of ioctl() as the volume ID,
> Dmitry Pervushin noticed some volume IDs abiguous with error returns:
> for example, if volume id is set to "0xFFFFFDAD", that matches -ENOIOCTLCMD,
> we get a wrong volume ID "0xFFFFFFFF" from the user space.
>
> This patch fixes above bug by adding a parameter to ioctl to get the correct
> volume ID.
Personally, I have no objection to do this small one in kernel
though. Please add use case of android to changelog, it would help to
understand.
> +static unsigned int fat_ioctl_volume_id(struct inode *inode)
> +{
> + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
> + return sbi->vol_id;
> +}
> +
> long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> {
> struct inode *inode = file_inode(filp);
> @@ -124,6 +130,8 @@ long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> return fat_ioctl_get_attributes(inode, user_attr);
> case FAT_IOCTL_SET_ATTRIBUTES:
> return fat_ioctl_set_attributes(filp, user_attr);
> + case FAT_IOCTL_GET_VOLUME_ID:
> + return put_user(fat_ioctl_volume_id(inode), user_attr);
> default:
> return -ENOTTY; /* Inappropriate ioctl for device */
> }
Please push put_user() down into fat_ioctl_volume_id() like others. So,
generic_ioctl() itself can forget about the detail of each ioctl.
Thanks.
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID
@ 2013-07-01 11:40 bintian.wang
2013-07-01 12:00 ` OGAWA Hirofumi
0 siblings, 1 reply; 9+ messages in thread
From: bintian.wang @ 2013-07-01 11:40 UTC (permalink / raw)
To: linux-kernel
Cc: Mike Lockwood, dmitry pervushin, Colin Cross,
Android Kernel Team, OGAWA Hirofumi, Andrew Morton, John Stultz,
Bintian Wang
From: Mike Lockwood <lockwood@android.com>
Adds vfat ioctl command FAT_IOCTL_GET_VOLUME_ID, with this command
we can get the vfat volume ID using following code:
ioctl(fd, FAT_IOCTL_GET_VOLUME_ID, &volume_ID)
This patch is a modified version of the android kernel patch by Mike Lockwood,
the original patch makes the return value of ioctl() as the volume ID,
Dmitry Pervushin noticed some volume IDs abiguous with error returns:
for example, if volume id is set to "0xFFFFFDAD", that matches -ENOIOCTLCMD,
we get a wrong volume ID "0xFFFFFFFF" from the user space.
This patch fixes above bug by adding a parameter to ioctl to get the correct
volume ID.
Cc: dmitry pervushin <dpervushin@gmail.com>
Cc: Mike Lockwood <lockwood@android.com>
Cc: Colin Cross <ccross@android.com>
Cc: Android Kernel Team <kernel-team@android.com>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: Bintian Wang <bintian.wang@linaro.org>
---
fs/fat/fat.h | 1 +
fs/fat/file.c | 8 ++++++++
fs/fat/inode.c | 12 ++++++++++++
include/uapi/linux/msdos_fs.h | 10 ++++++++++
4 files changed, 31 insertions(+)
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 21664fc..4241e6f 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -86,6 +86,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 int vol_id; /*volume ID*/
int fatent_shift;
struct fatent_operations *fatent_ops;
diff --git a/fs/fat/file.c b/fs/fat/file.c
index b0b632e..ceef10e 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -114,6 +114,12 @@ out:
return err;
}
+static unsigned int fat_ioctl_volume_id(struct inode *inode)
+{
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+ return sbi->vol_id;
+}
+
long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct inode *inode = file_inode(filp);
@@ -124,6 +130,8 @@ long fat_generic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return fat_ioctl_get_attributes(inode, user_attr);
case FAT_IOCTL_SET_ATTRIBUTES:
return fat_ioctl_set_attributes(filp, user_attr);
+ case FAT_IOCTL_GET_VOLUME_ID:
+ return put_user(fat_ioctl_volume_id(inode), user_attr);
default:
return -ENOTTY; /* Inappropriate ioctl for device */
}
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 5d4513c..11b51bb 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,
brelse(fsinfo_bh);
}
+ /* interpret volume ID as a little endian 32 bit integer */
+ if (sbi->fat_bits == 32)
+ sbi->vol_id = (((u32)b->fat32.vol_id[0]) |
+ ((u32)b->fat32.vol_id[1] << 8) |
+ ((u32)b->fat32.vol_id[2] << 16) |
+ ((u32)b->fat32.vol_id[3] << 24));
+ else /* fat 16 or 12 */
+ sbi->vol_id = (((u32)b->fat16.vol_id[0]) |
+ ((u32)b->fat16.vol_id[1] << 8) |
+ ((u32)b->fat16.vol_id[2] << 16) |
+ ((u32)b->fat16.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/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h
index f055e58..e284ff9 100644
--- a/include/uapi/linux/msdos_fs.h
+++ b/include/uapi/linux/msdos_fs.h
@@ -104,6 +104,8 @@ 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)
+/*Android kernel has used 0x12, so we use 0x13*/
+#define FAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x13, __u32)
struct fat_boot_sector {
__u8 ignored[3]; /* Boot strap short or near jump */
@@ -128,6 +130,10 @@ struct fat_boot_sector {
__u8 drive_number; /* Physical drive number */
__u8 state; /* undocumented, but used
for mount state. */
+ __u8 signature; /* extended boot signature */
+ __u8 vol_id[4]; /* volume ID */
+ __u8 vol_label[11]; /* volume label */
+ __u8 fs_type[8]; /* file system type */
/* other fiealds are not added here */
} fat16;
@@ -147,6 +153,10 @@ struct fat_boot_sector {
__u8 drive_number; /* Physical drive number */
__u8 state; /* undocumented, but used
for mount state. */
+ __u8 signature; /* extended boot signature */
+ __u8 vol_id[4]; /* volume ID */
+ __u8 vol_label[11]; /* volume label */
+ __u8 fs_type[8]; /* file system type */
/* other fiealds are not added here */
} fat32;
};
--
1.7.9.5
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-07-03 3:22 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-01 2:39 [PATCH RFC] Add FAT_IOCTL_GET_VOLUME_ID bintian.wang
2013-07-01 6:12 ` OGAWA Hirofumi
2013-07-01 6:19 ` OGAWA Hirofumi
[not found] ` <CAJ2TvK=SVMfuFw+U46z-iCS1sYZgnmdk+sr30NeNFTayot7g8g@mail.gmail.com>
[not found] ` <CAO+d-qrq9XD2d0FtoA7ZkCsSkka0sfgERb-OeNoU2kLXpF+PVA@mail.gmail.com>
2013-07-01 9:29 ` OGAWA Hirofumi
[not found] ` <CAO+d-qqs0uUqNcmOhgZdKeaJQxd5y+TyKVFSpgknoUkX2YidfQ@mail.gmail.com>
2013-07-01 11:43 ` OGAWA Hirofumi
2013-07-01 11:40 bintian.wang
2013-07-01 12:00 ` OGAWA Hirofumi
2013-07-03 2:19 bintian.wang
2013-07-03 3:22 ` OGAWA Hirofumi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®