vserver 1.9.5.x5
[linux-2.6.git] / include / linux / msdos_fs.h
index d35fe74..f40195a 100644 (file)
 #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 */
 #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
 #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 */
 #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 <linux/buffer_head.h>
 #include <linux/string.h>
 #include <linux/nls.h>
-#include <linux/msdos_fs_i.h>
-#include <linux/msdos_fs_sb.h>
+#include <linux/fs.h>
+
+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,