X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=include%2Flinux%2Fmsdos_fs.h;h=f40195a50ae6b806fa92bc01721aae8ddfa8000a;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=d35fe747bd9428b9f21bfba78901fe9c55f9d90a;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index d35fe747b..f40195a50 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -12,6 +12,10 @@ #define MSDOS_DPB_BITS 4 /* log2(MSDOS_DPB) */ #define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry)) #define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */ +#define CF_LE_W(v) le16_to_cpu(v) +#define CF_LE_L(v) le32_to_cpu(v) +#define CT_LE_W(v) cpu_to_le16(v) +#define CT_LE_L(v) cpu_to_le32(v) #define MSDOS_SUPER_MAGIC 0x4d44 /* MD */ @@ -23,62 +27,65 @@ #define FAT_MAX_DIR_ENTRIES (65536) #define FAT_MAX_DIR_SIZE (FAT_MAX_DIR_ENTRIES << MSDOS_DIR_BITS) -#define ATTR_NONE 0 /* no attribute bits */ -#define ATTR_RO 1 /* read-only */ -#define ATTR_HIDDEN 2 /* hidden */ -#define ATTR_SYS 4 /* system */ -#define ATTR_VOLUME 8 /* volume label */ -#define ATTR_DIR 16 /* directory */ -#define ATTR_ARCH 32 /* archived */ +#define ATTR_NONE 0 /* no attribute bits */ +#define ATTR_RO 1 /* read-only */ +#define ATTR_HIDDEN 2 /* hidden */ +#define ATTR_SYS 4 /* system */ +#define ATTR_VOLUME 8 /* volume label */ +#define ATTR_DIR 16 /* directory */ +#define ATTR_ARCH 32 /* archived */ /* attribute bits that are copied "as is" */ -#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN) +#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN) /* bits that are used by the Windows 95/Windows NT extended FAT */ -#define ATTR_EXT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME) +#define ATTR_EXT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME) -#define CASE_LOWER_BASE 8 /* base is lower case */ -#define CASE_LOWER_EXT 16 /* extension is lower case */ +#define CASE_LOWER_BASE 8 /* base is lower case */ +#define CASE_LOWER_EXT 16 /* extension is lower case */ -#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */ -#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG) +#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */ +#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG) /* valid file mode bits */ #define MSDOS_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO) /* Convert attribute bits and a mask to the UNIX mode. */ #define MSDOS_MKMODE(a, m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO)) /* Convert the UNIX mode to MS-DOS attribute bits. */ -#define MSDOS_MKATTR(m) ((m & S_IWUGO) ? ATTR_NONE : ATTR_RO) +#define MSDOS_MKATTR(m) ((m & S_IWUGO) ? ATTR_NONE : ATTR_RO) -#define MSDOS_NAME 11 /* maximum name length */ -#define MSDOS_LONGNAME 256 /* maximum name length */ -#define MSDOS_SLOTS 21 /* max # of slots needed for short and long names */ -#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */ -#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ +#define MSDOS_NAME 11 /* maximum name length */ +#define MSDOS_LONGNAME 256 /* maximum name length */ +#define MSDOS_SLOTS 21 /* max # of slots for short and long names */ +#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */ +#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ /* media of boot sector */ #define FAT_VALID_MEDIA(x) ((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0) #define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \ MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x)) +/* start of data cluster's entry (number of reserved clusters) */ +#define FAT_START_ENT 2 + /* maximum number of clusters */ -#define MAX_FAT12 0xFF4 -#define MAX_FAT16 0xFFF4 -#define MAX_FAT32 0x0FFFFFF6 -#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \ +#define MAX_FAT12 0xFF4 +#define MAX_FAT16 0xFFF4 +#define MAX_FAT32 0x0FFFFFF6 +#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \ MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12) /* bad cluster mark */ -#define BAD_FAT12 0xFF7 -#define BAD_FAT16 0xFFF7 -#define BAD_FAT32 0x0FFFFFF7 -#define BAD_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? BAD_FAT32 : \ +#define BAD_FAT12 0xFF7 +#define BAD_FAT16 0xFFF7 +#define BAD_FAT32 0x0FFFFFF7 +#define BAD_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? BAD_FAT32 : \ MSDOS_SB(s)->fat_bits == 16 ? BAD_FAT16 : BAD_FAT12) /* standard EOF */ -#define EOF_FAT12 0xFFF -#define EOF_FAT16 0xFFFF -#define EOF_FAT32 0x0FFFFFFF -#define EOF_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? EOF_FAT32 : \ +#define EOF_FAT12 0xFFF +#define EOF_FAT16 0xFFFF +#define EOF_FAT32 0x0FFFFFFF +#define EOF_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? EOF_FAT32 : \ MSDOS_SB(s)->fat_bits == 16 ? EOF_FAT16 : EOF_FAT12) #define FAT_ENT_FREE (0) @@ -87,8 +94,8 @@ #define FAT_FSINFO_SIG1 0x41615252 #define FAT_FSINFO_SIG2 0x61417272 -#define IS_FSINFO(x) (CF_LE_L((x)->signature1) == FAT_FSINFO_SIG1 \ - && CF_LE_L((x)->signature2) == FAT_FSINFO_SIG2) +#define IS_FSINFO(x) (le32_to_cpu((x)->signature1) == FAT_FSINFO_SIG1 \ + && le32_to_cpu((x)->signature2) == FAT_FSINFO_SIG2) /* * ioctl commands @@ -96,7 +103,7 @@ #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) -/* +/* * vfat shortname flags */ #define VFAT_SFN_DISPLAY_LOWER 0x0001 /* convert to lowercase for display */ @@ -105,18 +112,6 @@ #define VFAT_SFN_CREATE_WIN95 0x0100 /* emulate win95 rule for create */ #define VFAT_SFN_CREATE_WINNT 0x0200 /* emulate winnt rule for create */ -/* - * Conversion from and to little-endian byte order. (no-op on i386/i486) - * - * Naming: Ca_b_c, where a: F = from, T = to, b: LE = little-endian, - * BE = big-endian, c: W = word (16 bits), L = longword (32 bits) - */ - -#define CF_LE_W(v) le16_to_cpu(v) -#define CF_LE_L(v) le32_to_cpu(v) -#define CT_LE_W(v) cpu_to_le16(v) -#define CT_LE_L(v) cpu_to_le32(v) - struct fat_boot_sector { __u8 ignored[3]; /* Boot strap short or near jump */ __u8 system_id[8]; /* Name - can be used to special case @@ -161,7 +156,7 @@ struct msdos_dir_entry { __le16 ctime; /* Creation time */ __le16 cdate; /* Creation date */ __le16 adate; /* Last access date */ - __le16 starthi; /* High 16 bits of cluster in FAT32 */ + __le16 starthi; /* High 16 bits of cluster in FAT32 */ __le16 time,date,start;/* time, date and first cluster */ __le32 size; /* file size (in bytes) */ }; @@ -179,9 +174,9 @@ struct msdos_dir_slot { }; struct vfat_slot_info { - int long_slots; /* number of long slots in filename */ - loff_t longname_offset; /* dir offset for longname start */ - loff_t i_pos; /* on-disk position of directory entry */ + int long_slots; /* number of long slots in filename */ + loff_t longname_offset; /* dir offset for longname start */ + loff_t i_pos; /* on-disk position of directory entry */ }; #ifdef __KERNEL__ @@ -189,8 +184,84 @@ struct vfat_slot_info { #include #include #include -#include -#include +#include + +struct fat_mount_options { + uid_t fs_uid; + gid_t fs_gid; + unsigned short fs_fmask; + unsigned short fs_dmask; + unsigned short codepage; /* Codepage for shortname conversions */ + char *iocharset; /* Charset used for filename input/display */ + unsigned short shortname; /* flags for shortname display/create rule */ + unsigned char name_check; /* r = relaxed, n = normal, s = strict */ + unsigned quiet:1, /* set = fake successful chmods and chowns */ + showexec:1, /* set = only set x bit for com/exe/bat */ + sys_immutable:1, /* set = system files are immutable */ + dotsOK:1, /* set = hidden and system files are named '.filename' */ + isvfat:1, /* 0=no vfat long filename support, 1=vfat support */ + utf8:1, /* Use of UTF8 character set (Default) */ + unicode_xlate:1, /* create escape sequences for unhandled Unicode */ + numtail:1, /* Does first alias have a numeric '~1' type tail? */ + atari:1, /* Use Atari GEMDOS variation of MS-DOS fs */ + nocase:1; /* Does this need case conversion? 0=need case conversion*/ +}; + +#define FAT_HASH_BITS 8 +#define FAT_HASH_SIZE (1UL << FAT_HASH_BITS) +#define FAT_HASH_MASK (FAT_HASH_SIZE-1) + +/* + * MS-DOS file system in-core superblock data + */ +struct msdos_sb_info { + unsigned short sec_per_clus; /* sectors/cluster */ + unsigned short cluster_bits; /* log2(cluster_size) */ + unsigned int cluster_size; /* cluster size */ + unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */ + unsigned short fat_start; + unsigned long fat_length; /* FAT start & length (sec.) */ + unsigned long dir_start; + unsigned short dir_entries; /* root dir start & entries */ + unsigned long data_start; /* first data sector */ + unsigned long max_cluster; /* maximum cluster number */ + unsigned long root_cluster; /* first cluster of the root directory */ + unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */ + struct semaphore fat_lock; + int prev_free; /* previously allocated cluster number */ + int free_clusters; /* -1 if undefined */ + struct fat_mount_options options; + struct nls_table *nls_disk; /* Codepage used on disk */ + struct nls_table *nls_io; /* Charset used for input and display */ + void *dir_ops; /* Opaque; default directory operations */ + int dir_per_block; /* dir entries per block */ + int dir_per_block_bits; /* log2(dir_per_block) */ + + spinlock_t inode_hash_lock; + struct hlist_head inode_hashtable[FAT_HASH_SIZE]; +}; + +#define FAT_CACHE_VALID 0 /* special case for valid cache */ + +/* + * MS-DOS file system inode data in memory + */ +struct msdos_inode_info { + spinlock_t cache_lru_lock; + struct list_head cache_lru; + int nr_caches; + /* for avoiding the race between fat_free() and fat_get_cluster() */ + unsigned int cache_valid_id; + + loff_t mmu_private; + int i_start; /* first cluster or 0 */ + int i_logstart; /* logical first cluster */ + int i_attrs; /* unused attribute bits */ + int i_ctime_ms; /* unused change time in milliseconds */ + loff_t i_pos; /* on-disk position of directory entry or 0 */ + struct hlist_node i_fat_hash; /* hash by i_location */ + struct inode vfs_inode; +}; static inline struct msdos_sb_info *MSDOS_SB(struct super_block *sb) { @@ -202,6 +273,12 @@ static inline struct msdos_inode_info *MSDOS_I(struct inode *inode) return container_of(inode, struct msdos_inode_info, vfs_inode); } +static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus) +{ + return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus + + sbi->data_start; +} + static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len) { #ifdef __BIG_ENDIAN @@ -229,26 +306,20 @@ static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len) } /* fat/cache.c */ -extern int fat_access(struct super_block *sb, int nr, int new_value); -extern int __fat_access(struct super_block *sb, int nr, int new_value); -extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys); -extern void fat_cache_init(struct super_block *sb); -extern void fat_cache_add(struct inode *inode, int f_clu, int d_clu); extern void fat_cache_inval_inode(struct inode *inode); +extern int fat_access(struct super_block *sb, int nr, int new_value); extern int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus); -extern int fat_free(struct inode *inode, int skip); +extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys); /* fat/dir.c */ extern struct file_operations fat_dir_operations; extern int fat_search_long(struct inode *inode, const unsigned char *name, int name_len, int anycase, loff_t *spos, loff_t *lpos); -extern int fat_readdir(struct file *filp, void *dirent, filldir_t filldir); -extern int fat_dir_ioctl(struct inode * inode, struct file * filp, - unsigned int cmd, unsigned long arg); -extern int fat_add_entries(struct inode *dir, int slots, struct buffer_head **bh, - struct msdos_dir_entry **de, loff_t *i_pos); +extern int fat_add_entries(struct inode *dir, int slots, + struct buffer_head **bh, + struct msdos_dir_entry **de, loff_t *i_pos); extern int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat); extern int fat_dir_empty(struct inode *dir); extern int fat_subdirs(struct inode *dir); @@ -259,25 +330,17 @@ extern int fat_scan(struct inode *dir, const unsigned char *name, /* fat/file.c */ extern struct file_operations fat_file_operations; extern struct inode_operations fat_file_inode_operations; -extern int fat_get_block(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create); +extern int fat_notify_change(struct dentry * dentry, struct iattr * attr); extern void fat_truncate(struct inode *inode); /* fat/inode.c */ -extern void fat_hash_init(void); extern void fat_attach(struct inode *inode, loff_t i_pos); extern void fat_detach(struct inode *inode); extern struct inode *fat_iget(struct super_block *sb, loff_t i_pos); extern struct inode *fat_build_inode(struct super_block *sb, struct msdos_dir_entry *de, loff_t i_pos, int *res); -extern void fat_delete_inode(struct inode *inode); -extern void fat_clear_inode(struct inode *inode); -extern void fat_put_super(struct super_block *sb); int fat_fill_super(struct super_block *sb, void *data, int silent, struct inode_operations *fs_dir_inode_ops, int isvfat); -extern int fat_statfs(struct super_block *sb, struct kstatfs *buf); -extern int fat_write_inode(struct inode *inode, int wait); -extern int fat_notify_change(struct dentry * dentry, struct iattr * attr); /* fat/misc.c */ extern void fat_fs_panic(struct super_block *s, const char *fmt, ...); @@ -285,7 +348,6 @@ extern void lock_fat(struct super_block *sb); extern void unlock_fat(struct super_block *sb); extern void fat_clusters_flush(struct super_block *sb); extern int fat_add_cluster(struct inode *inode); -extern struct buffer_head *fat_extend_dir(struct inode *inode); extern int date_dos2unix(unsigned short time, unsigned short date); extern void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date); extern int fat__get_entry(struct inode *dir, loff_t *pos,