Posix file attribute support on VFAT
PATCH 1/1 Posix file attribute support on VFAT
Ogawa-san and FAT developpers,
Here is a patch to enable posix file attribute mapping to VFAT attributes, with restrictions.
Main purpose of this patch is to build root file system with VFAT for small embedded device. FAT is widely used for embedded device to exchange data, and also small embedded device has resource limitation. So it's very handy that VFAT has capability to built root fs, even that has restrictions.
Details are described within a patch. I think this feature still needs improvemnts, however it is very helpful for most embedded developpers.
Thanks,
Hiroyuki Machida
---
* vfat-posix_attr.patch:
fs/fat/file.c | 10 + fs/fat/inode.c | 27 +++ fs/vfat/namei.c | 291 ++++++++++++++++++++++++++++++++++++++++++ include/linux/msdos_fs.h | 320 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 646 insertions(+), 2 deletions(-)
This patch enables "posix_attr" option described as following;
"posix_attr" mapping support on VFAT.
- Descriptions
The option "posix_attr" enables attribute mapping from POSIX special files and permission modes/attributes to VFAT attributes and creation time fields.
On memory resident inode storage holds full posix attributes, however in media side, VFAT can't have enough room to store all attributes. So attribute mapping taken by this option is designed to be minimal.
For newly created and/or modified files/dirs, system can utilize full posix attributes, because memory resident inode storage can hold those. After umount-mount cycle, system may lose some attributes to preserve VFAT format.
This mapping method has many restrictions, however it's very handy to build root file system with FAT for small embedded device where inter-operation with PC is needed.
- Features
Following attributes/modes are supported with this option in VFAT media side. However, on memory resident inode storage holds full posix attributes. That means, for newly created and/or modified files/dirs, system can utilize full posix attributes. After umount-mount cycle, system can just keep following attributes/modes.
- FileType
File type is held in 3MSB bits in ctime_cs. This enables support following special files.
symbolic link,
block device node,
char device node,
fifo,
socket
Regular files also may have POSIX attributes.
- DeviceFile
Major and minor number would be held at ctime and both values are limited to 255.
- Owner's User ID/Group ID: 2nd LSB bit in ctime_cs
This can be used to distinguish root and others, because this has just one bit width.
Value of UID/GID for non-root user will be taken from uid/gid option on mounting. If nothing is specified, system uses -1 as last resort.
- Permission for Group/Other (rwx): 3rd-5th LSB bit in ctime_cs
Those modes will be kept in ctime_cs. Also permission modes for "others" will be same as "group", due to lack of fields.
- Permission for Owner (rwx)
These modes will be mapped to FAT attributes. Just same as mapping under VFAT.
- Others
no sticky, setgid nor setuid bits are not supported.
- Algorithm for attribute mapping decision
- Regular file/dir
To distinguish regular files/dirs, look if this fat dir entry doesn't have ATTR_SYS, first. If it doesn't have ATTR_SYS, then check if TYPE field (MSB 3bits) in ctime_cs is equal to 7. If so, this regular file/dir is created and/or modified under VFAT with "poisx_attr". And posix attribute mapping can be take place. Otherwise, conventional VFAT attribute mapping is used.
- Special file
To distinguish special files, look if this fat dir entry has ATTR_SYS, first. If it has ATTR_SYS, then check 1st. LSB bit in ctime_cs, refered as "special file flag". If set, this file is created under VFAT with "posix_attr". Look up TYPE field to decide special file type. This spcial file detection mothod has some flaw to make potential confusion. E.g. some system file created under dos/win may be treated as special file. However in most case, user don't create system file under dos/win.
- FAT DIR entry fields description
- ctime_cs
8bit byte 7 6 5 4 3 2 1 0 |===| | | | | | TYPE | | | | +- special file flag (vaild if ATTR_SYS) | | | +--- User/Group ID(owner) | | +----- !group X | +------- !group W +--------- !group R special file flag Indicate this entry has posix attribut mapping. This field is vaild for fat dir entry, which have ATTR_SYS. special file TYPE val type on VFS(val) Description ------------------------------------------------ 0 (place folder for backword compat) 1 DT_LNK (10) symbolic link 2 DT_BLK (6) block dev 3 DT_CHR (4) char dev 4 DT_FIFO (1) fifo 5 DT_SOCK (12) socket 7 (resevered for DT_REG/DT_DIR) *) *)Value 7 is reserved for regular file/dir (DT_REG/DT_DIR). Normally ctime_cs would have 0-199 value to stand for up to 2sec. The value for DT_REG/DT_DIR is selected to be over this range to distinguish if file was created under POSIX_ATTR or not.
- attr
FAT attribute (val) mapped attribute ------------------------------------------------ ATTR_RO 0x01 !owner W ATTR_HIDDEN 0x02 !owner R ATTR_SYS 0x04 ATTR_VOLUME 0x08 ATTR_DIR 0x10 DIR ATTR_ARCH 0x20 !owner X
- ctime
16bit word f e d c b a 9 8 7 6 5 4 3 2 1 0 |=============| |-------------| major minor
---
* looking for alp@oak--linux-1/alp-linux--dev-2-6-12--1.7--patch-8 to compare with
* comparing to alp@oak--linux-1/alp-linux--dev-2-6-12--1.7--patch-8
M fs/fat/file.c M fs/vfat/namei.c M include/linux/msdos_fs.h M fs/fat/inode.c
* modified files
fs/fat/file.c +10 -0
@@ -179,6 +179,10 @@ error =0 ; goto out; } +if (sbi->options.posix_attr){ + error =inode_setattr (inode, attr); + goto out; + } if (((attr->ia_valid & ATTR_UID) && (attr->ia_uid != sbi->options.fs_uid)) || ((attr->ia_valid & ATTR_GID) &&
@@ -306,3 +310,9 @@ .truncate = fat_truncate, .setattr = fat_notify_change, }; + +struct inode_operations fat_symlink_inode_operations = { + .readlink = page_readlink, + .follow_link = page_follow_link_light, + .setattr = fat_notify_change, +};
fs/fat/inode.c +25 -2
@@ -274,6 +274,10 @@MSDOS_I (inode)->i_logstart =MSDOS_I (inode)->i_start; inode->i_size =le32_to_cpu (de->size); inode->i_op = &fat_file_inode_operations; +if (sbi->options.posix_attr + &&is_vfat_posix_symlink (inode, de)){ + inode->i_op = &fat_symlink_inode_operations; + } inode->i_fop = &fat_file_operations; inode->i_mapping->a_ops = &fat_aops;MSDOS_I (inode)->mmu_private = inode->i_size;
@@ -499,8 +503,11 @@fat_date_unix2dos (inode->i_mtime.tv_sec, &raw_entry->time, &raw_entry->date);if (sbi->options.isvfat) {fat_date_unix2dos (inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate); - raw_entry->ctime_cs = (inode->i_ctime.tv_sec &1 ) *100 + - inode->i_ctime.tv_nsec /10000000 ; +if (set_vfat_posix_attr (raw_entry, inode) ==-1 ) { + raw_entry->ctime_cs + = (inode->i_ctime.tv_sec &1 ) *100 + + inode->i_ctime.tv_nsec /10000000 ; + } }spin_unlock (&sbi->inode_hash_lock);mark_buffer_dirty (bh);
@@ -742,6 +749,8 @@seq_puts (m,",uni_xlate" );if (!opts->numtail)seq_puts (m,",nonumtail" ); +if (opts->posix_attr) +seq_puts (m,",posix_attr" ); }return 0 ;
@@ -755,6 +764,7 @@ Opt_charset, Opt_shortname_lower, Opt_shortname_win95, Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, + Opt_posix_attr_no, Opt_posix_attr_yes, Opt_obsolate, Opt_err, };
@@ -823,6 +833,13 @@ {Opt_nonumtail_yes, "nonumtail=yes"}, {Opt_nonumtail_yes, "nonumtail=true"}, {Opt_nonumtail_yes, "nonumtail"}, + {Opt_posix_attr_no, "posix_attr=0"}, /* 0 or no or false */ + {Opt_posix_attr_no, "posix_attr=no"}, + {Opt_posix_attr_no, "posix_attr=false"}, + {Opt_posix_attr_yes, "posix_attr=1"}, /* empty or 1 or yes or true */ + {Opt_posix_attr_yes, "posix_attr=yes"}, + {Opt_posix_attr_yes, "posix_attr=true"}, + {Opt_posix_attr_yes, "posix_attr"}, {Opt_err, NULL} };
@@ -980,6 +997,12 @@case Opt_nonumtail_yes:/* empty or 1 or yes or true */ opts->numtail =0 ;/* negated option */ break ; +case Opt_posix_attr_no:/* 0 or no or false */ + opts->posix_attr =0 ; +break ; +case Opt_posix_attr_yes:/* empty or 1 or yes or true */ + opts->posix_attr =1 ; +break ;/* obsolete mount options */ case Opt_obsolate:
fs/vfat/namei.c +291 -0
327 lines not on this page · raw message
include/linux/msdos_fs.h +320 -0
338 lines not on this page · raw message