Hi,
Since 1~13 patches is including the "Lindent" cleanup, size is bit
big. However these are trivial changes.
Please apply.
--
OGAWA Hirofumi <[email protected]>
The patch below removes fatfs_syms.c
All EXPORT_SYMBOL's are moved to the files where the actual functions
are.
Signed-off-by: Adrian Bunk <[email protected]>
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/fat/Makefile | 2 +-
fs/fat/dir.c | 11 +++++++++++
fs/fat/inode.c | 34 ++++++++++++++++++++++++++++++++++
fs/fat/misc.c | 4 ++++
fs/fat/fatfs_syms.c | 48 ------------------------------------------------
5 files changed, 50 insertions(+), 49 deletions(-)
diff -puN fs/fat/Makefile~fat_export-cleanup fs/fat/Makefile
--- linux-2.6.10/fs/fat/Makefile~fat_export-cleanup 2005-01-08 09:07:36.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/Makefile 2005-01-08 09:07:37.000000000 +0900
@@ -4,4 +4,4 @@
obj-$(CONFIG_FAT_FS) += fat.o
-fat-objs := cache.o dir.o file.o inode.o misc.o fatfs_syms.o
+fat-objs := cache.o dir.o file.o inode.o misc.o
diff -puN fs/fat/dir.c~fat_export-cleanup fs/fat/dir.c
--- linux-2.6.10/fs/fat/dir.c~fat_export-cleanup 2005-01-08 09:07:37.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/dir.c 2005-01-08 09:07:37.000000000 +0900
@@ -13,6 +13,7 @@
* Short name translation 1999, 2001 by Wolfram Pienkoss <[email protected]>
*/
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/msdos_fs.h>
@@ -335,6 +336,8 @@ struct fat_ioctl_filldir_callback {
int short_len;
};
+EXPORT_SYMBOL(fat_search_long);
+
static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
filldir_t filldir, int short_only, int both)
{
@@ -732,6 +735,8 @@ int fat_add_entries(struct inode *dir,in
return offset;
}
+EXPORT_SYMBOL(fat_add_entries);
+
int fat_new_dir(struct inode *dir, struct inode *parent, int is_vfat)
{
struct buffer_head *bh;
@@ -767,6 +772,8 @@ int fat_new_dir(struct inode *dir, struc
return 0;
}
+EXPORT_SYMBOL(fat_new_dir);
+
static int fat_get_short_entry(struct inode *dir, loff_t *pos,
struct buffer_head **bh,
struct msdos_dir_entry **de, loff_t *i_pos)
@@ -800,6 +807,8 @@ int fat_dir_empty(struct inode *dir)
return result;
}
+EXPORT_SYMBOL(fat_dir_empty);
+
/*
* fat_subdirs counts the number of sub-directories of dir. It can be run
* on directories being created.
@@ -839,3 +848,5 @@ int fat_scan(struct inode *dir, const un
}
return -ENOENT;
}
+
+EXPORT_SYMBOL(fat_scan);
diff -L fs/fat/fatfs_syms.c -puN fs/fat/fatfs_syms.c~fat_export-cleanup /dev/null
--- linux-2.6.10/fs/fat/fatfs_syms.c
+++ /dev/null 2004-09-13 22:36:32.000000000 +0900
@@ -1,48 +0,0 @@
-/*
- * linux/fs/fat/fatfs_syms.c
- *
- * Exported kernel symbols for the low-level FAT-based fs support.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/mm.h>
-#include <linux/msdos_fs.h>
-
-EXPORT_SYMBOL(fat_new_dir);
-EXPORT_SYMBOL(fat_date_unix2dos);
-EXPORT_SYMBOL(fat__get_entry);
-EXPORT_SYMBOL(fat_notify_change);
-EXPORT_SYMBOL(fat_attach);
-EXPORT_SYMBOL(fat_detach);
-EXPORT_SYMBOL(fat_build_inode);
-EXPORT_SYMBOL(fat_fill_super);
-EXPORT_SYMBOL(fat_search_long);
-EXPORT_SYMBOL(fat_scan);
-EXPORT_SYMBOL(fat_add_entries);
-EXPORT_SYMBOL(fat_dir_empty);
-
-int __init fat_cache_init(void);
-void __exit fat_cache_destroy(void);
-int __init fat_init_inodecache(void);
-void __exit fat_destroy_inodecache(void);
-static int __init init_fat_fs(void)
-{
- int ret;
-
- ret = fat_cache_init();
- if (ret < 0)
- return ret;
- return fat_init_inodecache();
-}
-
-static void __exit exit_fat_fs(void)
-{
- fat_cache_destroy();
- fat_destroy_inodecache();
-}
-
-module_init(init_fat_fs)
-module_exit(exit_fat_fs)
diff -puN fs/fat/inode.c~fat_export-cleanup fs/fat/inode.c
--- linux-2.6.10/fs/fat/inode.c~fat_export-cleanup 2005-01-08 09:07:37.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/inode.c 2005-01-08 09:07:37.000000000 +0900
@@ -11,6 +11,7 @@
*/
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
@@ -87,6 +88,8 @@ void fat_attach(struct inode *inode, lof
spin_unlock(&sbi->inode_hash_lock);
}
+EXPORT_SYMBOL(fat_attach);
+
void fat_detach(struct inode *inode)
{
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
@@ -96,6 +99,8 @@ void fat_detach(struct inode *inode)
spin_unlock(&sbi->inode_hash_lock);
}
+EXPORT_SYMBOL(fat_detach);
+
struct inode *fat_iget(struct super_block *sb, loff_t i_pos)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -145,6 +150,8 @@ out:
return inode;
}
+EXPORT_SYMBOL(fat_build_inode);
+
static void fat_delete_inode(struct inode *inode)
{
if (!is_bad_inode(inode)) {
@@ -1070,6 +1077,8 @@ out_fail:
return error;
}
+EXPORT_SYMBOL(fat_fill_super);
+
static int fat_statfs(struct super_block *sb, struct kstatfs *buf)
{
int free, nr, ret;
@@ -1328,4 +1337,29 @@ out:
unlock_kernel();
return error;
}
+
+EXPORT_SYMBOL(fat_notify_change);
+
+int __init fat_cache_init(void);
+void __exit fat_cache_destroy(void);
+
+static int __init init_fat_fs(void)
+{
+ int ret;
+
+ ret = fat_cache_init();
+ if (ret < 0)
+ return ret;
+ return fat_init_inodecache();
+}
+
+static void __exit exit_fat_fs(void)
+{
+ fat_cache_destroy();
+ fat_destroy_inodecache();
+}
+
+module_init(init_fat_fs)
+module_exit(exit_fat_fs)
+
MODULE_LICENSE("GPL");
diff -puN fs/fat/misc.c~fat_export-cleanup fs/fat/misc.c
--- linux-2.6.10/fs/fat/misc.c~fat_export-cleanup 2005-01-08 09:07:37.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/misc.c 2005-01-08 09:07:37.000000000 +0900
@@ -6,6 +6,7 @@
* and date_dos2unix for date==0 by Igor Zhbanov([email protected])
*/
+#include <linux/module.h>
#include <linux/fs.h>
#include <linux/msdos_fs.h>
#include <linux/buffer_head.h>
@@ -272,6 +273,7 @@ void fat_date_unix2dos(int unix_date,__l
*date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9));
}
+EXPORT_SYMBOL(fat_date_unix2dos);
/* Returns the inode number of the directory entry at offset pos. If bh is
non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
@@ -320,3 +322,5 @@ next:
return 0;
}
+
+EXPORT_SYMBOL(fat__get_entry);
_
We don't have the union in "struct inode" and "struct super_block", so
we doesn't need xxx_fs_i.h and xxx_fs_sb.h anymore.
From Christoph Hellwig <[email protected]>
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
include/linux/msdos_fs.h | 80 ++++++++++++++++++++++++++++++++++++++++++--
include/linux/msdos_fs_i.h | 29 ---------------
include/linux/msdos_fs_sb.h | 60 ---------------------------------
3 files changed, 78 insertions(+), 91 deletions(-)
diff -puN include/linux/msdos_fs.h~fat_remove_headers include/linux/msdos_fs.h
--- linux-2.6.10/include/linux/msdos_fs.h~fat_remove_headers 2005-01-08 09:07:45.000000000 +0900
+++ linux-2.6.10-hirofumi/include/linux/msdos_fs.h 2005-01-08 09:07:45.000000000 +0900
@@ -189,8 +189,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 clusters; /* number of clusters */
+ 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)
{
diff -L include/linux/msdos_fs_i.h -puN include/linux/msdos_fs_i.h~fat_remove_headers /dev/null
--- linux-2.6.10/include/linux/msdos_fs_i.h
+++ /dev/null 2004-09-13 22:36:32.000000000 +0900
@@ -1,29 +0,0 @@
-#ifndef _MSDOS_FS_I
-#define _MSDOS_FS_I
-
-#include <linux/fs.h>
-
-/*
- * MS-DOS file system inode data in memory
- */
-
-#define FAT_CACHE_VALID 0 /* special case for valid cache */
-
-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;
-};
-
-#endif
diff -L include/linux/msdos_fs_sb.h -puN include/linux/msdos_fs_sb.h~fat_remove_headers /dev/null
--- linux-2.6.10/include/linux/msdos_fs_sb.h
+++ /dev/null 2004-09-13 22:36:32.000000000 +0900
@@ -1,60 +0,0 @@
-#ifndef _MSDOS_FS_SB
-#define _MSDOS_FS_SB
-
-/*
- * MS-DOS file system in-core superblock data
- */
-
-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)
-
-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 clusters; /* number of clusters */
- 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];
-};
-
-#endif
_
Fix error code.
From Rene Scharfe <[email protected]>
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/vfat/namei.c | 17 +++++++++--------
1 files changed, 9 insertions(+), 8 deletions(-)
diff -puN fs/vfat/namei.c~fat_nametoolong fs/vfat/namei.c
--- linux-2.6.10/fs/vfat/namei.c~fat_nametoolong 2005-01-08 09:07:53.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/vfat/namei.c 2005-01-08 09:07:53.000000000 +0900
@@ -192,10 +192,10 @@ static inline int vfat_is_used_badchars(
static int vfat_valid_longname(const unsigned char *name, unsigned int len)
{
- if (len && name[len-1] == ' ')
- return 0;
+ if (name[len - 1] == ' ')
+ return -EINVAL;
if (len >= 256)
- return 0;
+ return -ENAMETOOLONG;
/* MS-DOS "device special files" */
if (len == 3 || (len > 3 && name[3] == '.')) { /* basename == 3 */
@@ -203,18 +203,18 @@ static int vfat_valid_longname(const uns
!strnicmp(name, "con", 3) ||
!strnicmp(name, "nul", 3) ||
!strnicmp(name, "prn", 3))
- return 0;
+ return -EINVAL;
}
if (len == 4 || (len > 4 && name[4] == '.')) { /* basename == 4 */
/* "com1", "com2", ... */
if ('1' <= name[3] && name[3] <= '9') {
if (!strnicmp(name, "com", 3) ||
!strnicmp(name, "lpt", 3))
- return 0;
+ return -EINVAL;
}
}
- return 1;
+ return 0;
}
static int vfat_find_form(struct inode *dir, unsigned char *name)
@@ -617,8 +617,9 @@ static int vfat_build_slots(struct inode
loff_t offset;
*slots = 0;
- if (!vfat_valid_longname(name, len))
- return -EINVAL;
+ res = vfat_valid_longname(name, len);
+ if (res)
+ return res;
if(!(page = __get_free_page(GFP_KERNEL)))
return -ENOMEM;
_
From Rene Scharfe <[email protected]>
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/vfat/namei.c | 49 +++++++++++++++++++++----------------------------
1 files changed, 21 insertions(+), 28 deletions(-)
diff -puN fs/vfat/namei.c~fat_check-chars-cleanup fs/vfat/namei.c
--- linux-2.6.10/fs/vfat/namei.c~fat_check-chars-cleanup 2005-01-08 09:07:50.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/vfat/namei.c 2005-01-08 09:07:50.000000000 +0900
@@ -158,33 +158,26 @@ static int vfat_cmp(struct dentry *dentr
/* Characters that are undesirable in an MS-DOS file name */
-static wchar_t bad_chars[] = {
- /* `*' `?' `<' `>' `|' `"' `:' `/' */
- 0x002A, 0x003F, 0x003C, 0x003E, 0x007C, 0x0022, 0x003A, 0x002F,
- /* `\' */
- 0x005C, 0,
-};
-#define IS_BADCHAR(uni) (vfat_unistrchr(bad_chars, (uni)) != NULL)
-
-static wchar_t replace_chars[] = {
- /* `[' `]' `;' `,' `+' `=' */
- 0x005B, 0x005D, 0x003B, 0x002C, 0x002B, 0x003D, 0,
-};
-#define IS_REPLACECHAR(uni) (vfat_unistrchr(replace_chars, (uni)) != NULL)
+static inline wchar_t vfat_bad_char(wchar_t w)
+{
+ return (w < 0x0020)
+ || (w == 0x002A) /* * */ || (w == 0x003F) /* ? */
+ || (w == 0x003C) /* < */ || (w == 0x003E) /* > */
+ || (w == 0x007C) /* | */ || (w == 0x0022) /* " */
+ || (w == 0x003A) /* : */ || (w == 0x002F) /* / */
+ || (w == 0x005C);/* \ */
+}
-static wchar_t skip_chars[] = {
- /* `.' ` ' */
- 0x002E, 0x0020, 0,
-};
-#define IS_SKIPCHAR(uni) \
- ((wchar_t)(uni) == skip_chars[0] || (wchar_t)(uni) == skip_chars[1])
+static inline wchar_t vfat_replace_char(wchar_t w)
+{
+ return (w == 0x005B) /* [ */ || (w == 0x005D) /* ] */
+ || (w == 0x003B) /* ; */ || (w == 0x002C) /* , */
+ || (w == 0x002B) /* + */ || (w == 0x003D);/* = */
+}
-static inline wchar_t *vfat_unistrchr(const wchar_t *s, const wchar_t c)
+static wchar_t vfat_skip_char(wchar_t w)
{
- for(; *s != c; ++s)
- if (*s == 0)
- return NULL;
- return (wchar_t *) s;
+ return (w == 0x002E) /* . */ || (w == 0x0020);/* <space> */
}
static inline int vfat_is_used_badchars(const wchar_t *s, int len)
@@ -192,7 +185,7 @@ static inline int vfat_is_used_badchars(
int i;
for (i = 0; i < len; i++)
- if (s[i] < 0x0020 || IS_BADCHAR(s[i]))
+ if (vfat_bad_char(s[i]))
return -EINVAL;
return 0;
}
@@ -291,11 +284,11 @@ static inline int to_shortname_char(stru
{
int len;
- if (IS_SKIPCHAR(*src)) {
+ if (vfat_skip_char(*src)) {
info->valid = 0;
return 0;
}
- if (IS_REPLACECHAR(*src)) {
+ if (vfat_replace_char(*src)) {
info->valid = 0;
buf[0] = '_';
return 1;
@@ -375,7 +368,7 @@ static int vfat_create_shortname(struct
*/
name_start = &uname[0];
while (name_start < ext_start) {
- if (!IS_SKIPCHAR(*name_start))
+ if (!vfat_skip_char(*name_start))
break;
name_start++;
}
_
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/fat/inode.c | 22 +++++++---------------
1 files changed, 7 insertions(+), 15 deletions(-)
diff -puN fs/fat/inode.c~fat_kill-unnecessary_kmap fs/fat/inode.c
--- linux-2.6.10/fs/fat/inode.c~fat_kill-unnecessary_kmap 2005-01-08 09:08:10.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/inode.c 2005-01-08 09:08:10.000000000 +0900
@@ -1137,30 +1137,22 @@ static int
fat_prepare_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
- kmap(page);
return cont_prepare_write(page,from,to,fat_get_block,
&MSDOS_I(page->mapping->host)->mmu_private);
}
-static int
-fat_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
-{
- kunmap(page);
- return generic_commit_write(file, page, from, to);
-}
-
static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
{
return generic_block_bmap(mapping,block,fat_get_block);
}
+
static struct address_space_operations fat_aops = {
- .readpage = fat_readpage,
- .writepage = fat_writepage,
- .sync_page = block_sync_page,
- .prepare_write = fat_prepare_write,
- .commit_write = fat_commit_write,
- .bmap = _fat_bmap
+ .readpage = fat_readpage,
+ .writepage = fat_writepage,
+ .sync_page = block_sync_page,
+ .prepare_write = fat_prepare_write,
+ .commit_write = generic_commit_write,
+ .bmap = _fat_bmap
};
/* doesn't deal with root inode */
_
The patch below makes a needlessly global function static.
Signed-off-by: Adrian Bunk <[email protected]>
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/fat/cache.c | 2 +-
include/linux/msdos_fs.h | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff -puN fs/fat/cache.c~fat__fat_access fs/fat/cache.c
--- linux-2.6.10/fs/fat/cache.c~fat__fat_access 2005-01-08 09:08:14.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/cache.c 2005-01-08 09:08:14.000000000 +0900
@@ -203,7 +203,7 @@ void fat_cache_inval_inode(struct inode
spin_unlock(&MSDOS_I(inode)->cache_lru_lock);
}
-int __fat_access(struct super_block *sb, int nr, int new_value)
+static int __fat_access(struct super_block *sb, int nr, int new_value)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
struct buffer_head *bh, *bh2, *c_bh, *c_bh2;
diff -puN include/linux/msdos_fs.h~fat__fat_access include/linux/msdos_fs.h
--- linux-2.6.10/include/linux/msdos_fs.h~fat__fat_access 2005-01-08 09:08:14.000000000 +0900
+++ linux-2.6.10-hirofumi/include/linux/msdos_fs.h 2005-01-08 09:08:14.000000000 +0900
@@ -306,7 +306,6 @@ static inline void fatwchar_to16(__u8 *d
/* 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_inval_inode(struct inode *inode);
extern int fat_get_cluster(struct inode *inode, int cluster,
_
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/fat/misc.c | 22 +++++++++-------------
1 files changed, 9 insertions(+), 13 deletions(-)
diff -puN fs/fat/misc.c~fat_sprintf-to-vprintk fs/fat/misc.c
--- linux-2.6.10/fs/fat/misc.c~fat_sprintf-to-vprintk 2005-01-08 09:08:05.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/misc.c 2005-01-08 09:08:05.000000000 +0900
@@ -15,26 +15,22 @@
* fat_fs_panic reports a severe file system problem and sets the file system
* read-only. The file system can be made writable again by remounting it.
*/
-
-static char panic_msg[512];
-
void fat_fs_panic(struct super_block *s, const char *fmt, ...)
{
- int not_ro;
va_list args;
- va_start (args, fmt);
- vsnprintf (panic_msg, sizeof(panic_msg), fmt, args);
- va_end (args);
+ printk(KERN_ERR "FAT: Filesystem panic (dev %s)\n", s->s_id);
- not_ro = !(s->s_flags & MS_RDONLY);
- if (not_ro)
- s->s_flags |= MS_RDONLY;
+ printk(KERN_ERR " ");
+ va_start(args, fmt);
+ vprintk(fmt, args);
+ va_end(args);
+ printk("\n");
- printk(KERN_ERR "FAT: Filesystem panic (dev %s)\n"
- " %s\n", s->s_id, panic_msg);
- if (not_ro)
+ if (!(s->s_flags & MS_RDONLY)) {
+ s->s_flags |= MS_RDONLY;
printk(KERN_ERR " File system has been set read-only\n");
+ }
}
void lock_fat(struct super_block *sb)
_
This patch inlines shortname_info_to_lcase() by hand. At least my
compiler (gcc 3.3.4 from Debian) doesn't go all the way, so the compiled
text size is decreased by this patch. And IMHO the code gets more
readable, too.
The terms (base->valid && ext->valid), (ext->lower || ext->upper) and
(base->lower || base->upper) are trivially found to be true at the
single callsite of shortname_info_to_lcase(). The relevant lines are
included in this patch file.
From [email protected]
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/vfat/namei.c | 26 ++++++--------------------
1 files changed, 6 insertions(+), 20 deletions(-)
diff -puN fs/vfat/namei.c~fat_lcase-cleanup fs/vfat/namei.c
--- linux-2.6.10/fs/vfat/namei.c~fat_lcase-cleanup 2005-01-08 09:07:58.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/vfat/namei.c 2005-01-08 09:07:58.000000000 +0900
@@ -262,22 +262,6 @@ struct shortname_info {
(x)->valid = 1; \
} while (0)
-static inline unsigned char
-shortname_info_to_lcase(struct shortname_info *base,
- struct shortname_info *ext)
-{
- unsigned char lcase = 0;
-
- if (base->valid && ext->valid) {
- if (!base->upper && base->lower && (ext->lower || ext->upper))
- lcase |= CASE_LOWER_BASE;
- if (!ext->upper && ext->lower && (base->lower || base->upper))
- lcase |= CASE_LOWER_EXT;
- }
-
- return lcase;
-}
-
static inline int to_shortname_char(struct nls_table *nls,
unsigned char *buf, int buf_size, wchar_t *src,
struct shortname_info *info)
@@ -455,10 +439,12 @@ static int vfat_create_shortname(struct
if (opt_shortname & VFAT_SFN_CREATE_WIN95) {
return (base_info.upper && ext_info.upper);
} else if (opt_shortname & VFAT_SFN_CREATE_WINNT) {
- if ((base_info.upper || base_info.lower)
- && (ext_info.upper || ext_info.lower)) {
- *lcase = shortname_info_to_lcase(&base_info,
- &ext_info);
+ if ((base_info.upper || base_info.lower) &&
+ (ext_info.upper || ext_info.lower)) {
+ if (!base_info.upper && base_info.lower)
+ *lcase |= CASE_LOWER_BASE;
+ if (!ext_info.upper && ext_info.lower)
+ *lcase |= CASE_LOWER_EXT;
return 1;
}
return 0;
_
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/msdos/namei.c | 179 ++++++++++++++++++++++++++++++++-----------------------
1 files changed, 105 insertions(+), 74 deletions(-)
diff -puN fs/msdos/namei.c~fat_lindent-msdos fs/msdos/namei.c
--- linux-2.6.10/fs/msdos/namei.c~fat_lindent-msdos 2005-01-08 09:08:19.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/msdos/namei.c 2005-01-08 09:08:19.000000000 +0900
@@ -12,25 +12,28 @@
#include <linux/msdos_fs.h>
#include <linux/smp_lock.h>
-
/* MS-DOS "device special files" */
static const unsigned char *reserved_names[] = {
- "CON ","PRN ","NUL ","AUX ",
- "LPT1 ","LPT2 ","LPT3 ","LPT4 ",
- "COM1 ","COM2 ","COM3 ","COM4 ",
+ "CON ", "PRN ", "NUL ", "AUX ",
+ "LPT1 ", "LPT2 ", "LPT3 ", "LPT4 ",
+ "COM1 ", "COM2 ", "COM3 ", "COM4 ",
NULL
};
/* Characters that are undesirable in an MS-DOS file name */
static unsigned char bad_chars[] = "*?<>|\"";
static unsigned char bad_if_strict_pc[] = "+=,; ";
-static unsigned char bad_if_strict_atari[] = " "; /* GEMDOS is less restrictive */
-#define bad_if_strict(opts) ((opts)->atari ? bad_if_strict_atari : bad_if_strict_pc)
+/* GEMDOS is less restrictive */
+static unsigned char bad_if_strict_atari[] = " ";
+
+#define bad_if_strict(opts) \
+ ((opts)->atari ? bad_if_strict_atari : bad_if_strict_pc)
/***** Formats an MS-DOS file name. Rejects invalid names. */
static int msdos_format_name(const unsigned char *name, int len,
- unsigned char *res, struct fat_mount_options *opts)
- /* name is the proposed name, len is its length, res is
+ unsigned char *res, struct fat_mount_options *opts)
+ /*
+ * name is the proposed name, len is its length, res is
* the resulting name, opts->name_check is either (r)elaxed,
* (n)ormal or (s)trict, opts->dotsOK allows dots at the
* beginning of name (for hidden files)
@@ -41,52 +44,66 @@ static int msdos_format_name(const unsig
unsigned char c;
int space;
- if (name[0] == '.') { /* dotfile because . and .. already done */
+ if (name[0] == '.') { /* dotfile because . and .. already done */
if (opts->dotsOK) {
/* Get rid of dot - test for it elsewhere */
- name++; len--;
- }
- else if (!opts->atari) return -EINVAL;
+ name++;
+ len--;
+ } else if (!opts->atari)
+ return -EINVAL;
}
- /* disallow names that _really_ start with a dot for MS-DOS, GEMDOS does
- * not care */
+ /*
+ * disallow names that _really_ start with a dot for MS-DOS,
+ * GEMDOS does not care
+ */
space = !opts->atari;
c = 0;
- for (walk = res; len && walk-res < 8; walk++) {
- c = *name++;
+ for (walk = res; len && walk - res < 8; walk++) {
+ c = *name++;
len--;
- if (opts->name_check != 'r' && strchr(bad_chars,c))
+ if (opts->name_check != 'r' && strchr(bad_chars, c))
return -EINVAL;
- if (opts->name_check == 's' && strchr(bad_if_strict(opts),c))
+ if (opts->name_check == 's' && strchr(bad_if_strict(opts), c))
return -EINVAL;
- if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
+ if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
return -EINVAL;
- if (c < ' ' || c == ':' || c == '\\') return -EINVAL;
-/* 0xE5 is legal as a first character, but we must substitute 0x05 */
-/* because 0xE5 marks deleted files. Yes, DOS really does this. */
-/* It seems that Microsoft hacked DOS to support non-US characters */
-/* after the 0xE5 character was already in use to mark deleted files. */
- if((res==walk) && (c==0xE5)) c=0x05;
- if (c == '.') break;
+ if (c < ' ' || c == ':' || c == '\\')
+ return -EINVAL;
+ /*
+ * 0xE5 is legal as a first character, but we must substitute
+ * 0x05 because 0xE5 marks deleted files. Yes, DOS really
+ * does this.
+ * It seems that Microsoft hacked DOS to support non-US
+ * characters after the 0xE5 character was already in use to
+ * mark deleted files.
+ */
+ if ((res == walk) && (c == 0xE5))
+ c = 0x05;
+ if (c == '.')
+ break;
space = (c == ' ');
- *walk = (!opts->nocase && c >= 'a' && c <= 'z') ? c-32 : c;
+ *walk = (!opts->nocase && c >= 'a' && c <= 'z') ? c - 32 : c;
}
- if (space) return -EINVAL;
+ if (space)
+ return -EINVAL;
if (opts->name_check == 's' && len && c != '.') {
c = *name++;
len--;
- if (c != '.') return -EINVAL;
+ if (c != '.')
+ return -EINVAL;
}
- while (c != '.' && len--) c = *name++;
+ while (c != '.' && len--)
+ c = *name++;
if (c == '.') {
- while (walk-res < 8) *walk++ = ' ';
- while (len > 0 && walk-res < MSDOS_NAME) {
+ while (walk - res < 8)
+ *walk++ = ' ';
+ while (len > 0 && walk - res < MSDOS_NAME) {
c = *name++;
len--;
- if (opts->name_check != 'r' && strchr(bad_chars,c))
+ if (opts->name_check != 'r' && strchr(bad_chars, c))
return -EINVAL;
if (opts->name_check == 's' &&
- strchr(bad_if_strict(opts),c))
+ strchr(bad_if_strict(opts), c))
return -EINVAL;
if (c < ' ' || c == ':' || c == '\\')
return -EINVAL;
@@ -98,16 +115,23 @@ static int msdos_format_name(const unsig
if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
return -EINVAL;
space = c == ' ';
- *walk++ = (!opts->nocase && c >= 'a' && c <= 'z') ? c-32 : c;
+ if (!opts->nocase && c >= 'a' && c <= 'z')
+ *walk++ = c - 32;
+ else
+ *walk++ = c;
}
- if (space) return -EINVAL;
- if (opts->name_check == 's' && len) return -EINVAL;
+ if (space)
+ return -EINVAL;
+ if (opts->name_check == 's' && len)
+ return -EINVAL;
}
- while (walk-res < MSDOS_NAME) *walk++ = ' ';
+ while (walk - res < MSDOS_NAME)
+ *walk++ = ' ';
if (!opts->atari)
/* GEMDOS is less stupid and has no reserved names */
for (reserved = reserved_names; *reserved; reserved++)
- if (!strncmp(res,*reserved,8)) return -EINVAL;
+ if (!strncmp(res, *reserved, 8))
+ return -EINVAL;
return 0;
}
@@ -121,12 +145,13 @@ static int msdos_find(struct inode *dir,
int res;
dotsOK = MSDOS_SB(dir->i_sb)->options.dotsOK;
- res = msdos_format_name(name,len, msdos_name,&MSDOS_SB(dir->i_sb)->options);
+ res = msdos_format_name(name, len, msdos_name,
+ &MSDOS_SB(dir->i_sb)->options);
if (res < 0)
return -ENOENT;
res = fat_scan(dir, msdos_name, bh, de, i_pos);
if (!res && dotsOK) {
- if (name[0]=='.') {
+ if (name[0] == '.') {
if (!((*de)->attr & ATTR_HIDDEN))
res = -ENOENT;
} else {
@@ -145,10 +170,10 @@ static int msdos_find(struct inode *dir,
*/
static int msdos_hash(struct dentry *dentry, struct qstr *qstr)
{
- struct fat_mount_options *options = & (MSDOS_SB(dentry->d_sb)->options);
+ struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options;
unsigned char msdos_name[MSDOS_NAME];
int error;
-
+
error = msdos_format_name(qstr->name, qstr->len, msdos_name, options);
if (!error)
qstr->hash = full_name_hash(msdos_name, MSDOS_NAME);
@@ -161,7 +186,7 @@ static int msdos_hash(struct dentry *den
*/
static int msdos_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b)
{
- struct fat_mount_options *options = & (MSDOS_SB(dentry->d_sb)->options);
+ struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options;
unsigned char a_msdos_name[MSDOS_NAME], b_msdos_name[MSDOS_NAME];
int error;
@@ -182,7 +207,6 @@ old_compare:
goto out;
}
-
static struct dentry_operations msdos_dentry_operations = {
.d_hash = msdos_hash,
.d_compare = msdos_cmp,
@@ -194,7 +218,7 @@ static struct dentry_operations msdos_de
/***** Get inode using directory and name */
static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry,
- struct nameidata *nd)
+ struct nameidata *nd)
{
struct super_block *sb = dir->i_sb;
struct inode *inode = NULL;
@@ -202,7 +226,7 @@ static struct dentry *msdos_lookup(struc
struct buffer_head *bh = NULL;
loff_t i_pos;
int res;
-
+
dentry->d_op = &msdos_dentry_operations;
lock_kernel();
@@ -260,7 +284,7 @@ static int msdos_add_entry(struct inode
/***** Create a file */
static int msdos_create(struct inode *dir, struct dentry *dentry, int mode,
- struct nameidata *nd)
+ struct nameidata *nd)
{
struct super_block *sb = dir->i_sb;
struct buffer_head *bh;
@@ -271,19 +295,19 @@ static int msdos_create(struct inode *di
unsigned char msdos_name[MSDOS_NAME];
lock_kernel();
- res = msdos_format_name(dentry->d_name.name,dentry->d_name.len,
+ res = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options);
if (res < 0) {
unlock_kernel();
return res;
}
- is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
+ is_hid = (dentry->d_name.name[0] == '.') && (msdos_name[0] != '.');
/* Have to do it due to foo vs. .foo conflicts */
if (fat_scan(dir, msdos_name, &bh, &de, &i_pos) >= 0) {
brelse(bh);
unlock_kernel();
return -EINVAL;
- }
+ }
inode = NULL;
res = msdos_add_entry(dir, msdos_name, &bh, &de, &i_pos, 0, is_hid);
if (res) {
@@ -349,18 +373,18 @@ static int msdos_mkdir(struct inode *dir
struct buffer_head *bh;
struct msdos_dir_entry *de;
struct inode *inode;
- int res,is_hid;
+ int res, is_hid;
unsigned char msdos_name[MSDOS_NAME];
loff_t i_pos;
lock_kernel();
- res = msdos_format_name(dentry->d_name.name,dentry->d_name.len,
+ res = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
msdos_name, &MSDOS_SB(sb)->options);
if (res < 0) {
unlock_kernel();
return res;
}
- is_hid = (dentry->d_name.name[0]=='.') && (msdos_name[0]!='.');
+ is_hid = (dentry->d_name.name[0] == '.') && (msdos_name[0] != '.');
/* foo vs .foo situation */
if (fat_scan(dir, msdos_name, &bh, &de, &i_pos) >= 0)
goto out_exist;
@@ -376,7 +400,7 @@ static int msdos_mkdir(struct inode *dir
res = 0;
dir->i_nlink++;
- inode->i_nlink = 2; /* no need to mark them dirty */
+ inode->i_nlink = 2; /* no need to mark them dirty */
res = fat_new_dir(inode, dir, 0);
if (res)
@@ -440,14 +464,16 @@ unlink_done:
}
static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
- struct dentry *old_dentry,
- struct inode *new_dir, unsigned char *new_name, struct dentry *new_dentry,
- struct buffer_head *old_bh,
- struct msdos_dir_entry *old_de, loff_t old_i_pos, int is_hid)
-{
- struct buffer_head *new_bh=NULL,*dotdot_bh=NULL;
- struct msdos_dir_entry *new_de,*dotdot_de;
- struct inode *old_inode,*new_inode;
+ struct dentry *old_dentry,
+ struct inode *new_dir, unsigned char *new_name,
+ struct dentry *new_dentry,
+ struct buffer_head *old_bh,
+ struct msdos_dir_entry *old_de, loff_t old_i_pos,
+ int is_hid)
+{
+ struct buffer_head *new_bh = NULL, *dotdot_bh = NULL;
+ struct msdos_dir_entry *new_de, *dotdot_de;
+ struct inode *old_inode, *new_inode;
loff_t new_i_pos, dotdot_i_pos;
int error;
int is_dir;
@@ -456,8 +482,8 @@ static int do_msdos_rename(struct inode
new_inode = new_dentry->d_inode;
is_dir = S_ISDIR(old_inode->i_mode);
- if (fat_scan(new_dir, new_name, &new_bh, &new_de, &new_i_pos) >= 0
- && !new_inode)
+ if (fat_scan(new_dir, new_name, &new_bh, &new_de, &new_i_pos) >= 0 &&
+ !new_inode)
goto degenerate_case;
if (is_dir) {
if (new_inode) {
@@ -502,7 +528,8 @@ static int do_msdos_rename(struct inode
}
if (dotdot_bh) {
dotdot_de->start = cpu_to_le16(MSDOS_I(new_dir)->i_logstart);
- dotdot_de->starthi = cpu_to_le16((MSDOS_I(new_dir)->i_logstart) >> 16);
+ dotdot_de->starthi =
+ cpu_to_le16((MSDOS_I(new_dir)->i_logstart) >> 16);
mark_buffer_dirty(dotdot_bh);
old_dir->i_nlink--;
mark_inode_dirty(old_dir);
@@ -522,7 +549,7 @@ out:
degenerate_case:
error = -EINVAL;
- if (new_de!=old_de)
+ if (new_de != old_de)
goto out;
if (is_hid)
MSDOS_I(old_inode)->i_attrs |= ATTR_HIDDEN;
@@ -537,7 +564,7 @@ degenerate_case:
/***** Rename, a wrapper for rename_same_dir & rename_diff_dir */
static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry)
+ struct inode *new_dir, struct dentry *new_dentry)
{
struct buffer_head *old_bh;
struct msdos_dir_entry *old_de;
@@ -547,18 +574,21 @@ static int msdos_rename(struct inode *ol
lock_kernel();
error = msdos_format_name(old_dentry->d_name.name,
- old_dentry->d_name.len,old_msdos_name,
+ old_dentry->d_name.len, old_msdos_name,
&MSDOS_SB(old_dir->i_sb)->options);
if (error < 0)
goto rename_done;
error = msdos_format_name(new_dentry->d_name.name,
- new_dentry->d_name.len,new_msdos_name,
+ new_dentry->d_name.len, new_msdos_name,
&MSDOS_SB(new_dir->i_sb)->options);
if (error < 0)
goto rename_done;
- is_hid = (new_dentry->d_name.name[0]=='.') && (new_msdos_name[0]!='.');
- old_hid = (old_dentry->d_name.name[0]=='.') && (old_msdos_name[0]!='.');
+ is_hid =
+ (new_dentry->d_name.name[0] == '.') && (new_msdos_name[0] != '.');
+ old_hid =
+ (old_dentry->d_name.name[0] == '.') && (old_msdos_name[0] != '.');
+
error = fat_scan(old_dir, old_msdos_name, &old_bh, &old_de, &old_i_pos);
if (error < 0)
goto rename_done;
@@ -583,7 +613,7 @@ static struct inode_operations msdos_dir
.setattr = fat_notify_change,
};
-static int msdos_fill_super(struct super_block *sb,void *data, int silent)
+static int msdos_fill_super(struct super_block *sb, void *data, int silent)
{
int res;
@@ -596,7 +626,8 @@ static int msdos_fill_super(struct super
}
static struct super_block *msdos_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
+ int flags, const char *dev_name,
+ void *data)
{
return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super);
}
_
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/vfat/namei.c | 225 ++++++++++++++++++++++++++++----------------------------
1 files changed, 113 insertions(+), 112 deletions(-)
diff -puN fs/vfat/namei.c~fat_lindent-vfat fs/vfat/namei.c
--- linux-2.6.10/fs/vfat/namei.c~fat_lindent-vfat 2005-01-10 01:57:31.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/vfat/namei.c 2005-01-10 01:57:44.000000000 +0900
@@ -12,7 +12,7 @@
* Short name translation 1999, 2001 by Wolfram Pienkoss <[email protected]>
*
* Support Multibyte character and cleanup by
- * OGAWA Hirofumi <[email protected]>
+ * OGAWA Hirofumi <[email protected]>
*/
#include <linux/module.h>
@@ -25,33 +25,6 @@
#include <linux/buffer_head.h>
#include <linux/namei.h>
-static int vfat_hashi(struct dentry *parent, struct qstr *qstr);
-static int vfat_hash(struct dentry *parent, struct qstr *qstr);
-static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd);
-
-static struct dentry_operations vfat_dentry_ops[4] = {
- {
- .d_hash = vfat_hashi,
- .d_compare = vfat_cmpi,
- },
- {
- .d_revalidate = vfat_revalidate,
- .d_hash = vfat_hashi,
- .d_compare = vfat_cmpi,
- },
- {
- .d_hash = vfat_hash,
- .d_compare = vfat_cmp,
- },
- {
- .d_revalidate = vfat_revalidate,
- .d_hash = vfat_hash,
- .d_compare = vfat_cmp,
- }
-};
-
static int vfat_revalidate(struct dentry *dentry, struct nameidata *nd)
{
int ret = 1;
@@ -78,9 +51,8 @@ static unsigned int vfat_striptail_len(s
{
unsigned int len = qstr->len;
- while (len && qstr->name[len-1] == '.')
+ while (len && qstr->name[len - 1] == '.')
len--;
-
return len;
}
@@ -93,7 +65,6 @@ static unsigned int vfat_striptail_len(s
static int vfat_hash(struct dentry *dentry, struct qstr *qstr)
{
qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr));
-
return 0;
}
@@ -156,6 +127,27 @@ static int vfat_cmp(struct dentry *dentr
return 1;
}
+static struct dentry_operations vfat_dentry_ops[4] = {
+ {
+ .d_hash = vfat_hashi,
+ .d_compare = vfat_cmpi,
+ },
+ {
+ .d_revalidate = vfat_revalidate,
+ .d_hash = vfat_hashi,
+ .d_compare = vfat_cmpi,
+ },
+ {
+ .d_hash = vfat_hash,
+ .d_compare = vfat_cmp,
+ },
+ {
+ .d_revalidate = vfat_revalidate,
+ .d_hash = vfat_hash,
+ .d_compare = vfat_cmp,
+ }
+};
+
/* Characters that are undesirable in an MS-DOS file name */
static inline wchar_t vfat_bad_char(wchar_t w)
@@ -183,7 +175,7 @@ static wchar_t vfat_skip_char(wchar_t w)
static inline int vfat_is_used_badchars(const wchar_t *s, int len)
{
int i;
-
+
for (i = 0; i < len; i++)
if (vfat_bad_char(s[i]))
return -EINVAL;
@@ -231,7 +223,7 @@ static int vfat_find_form(struct inode *
return 0;
}
-/*
+/*
* 1) Valid characters for the 8.3 format alias are any combination of
* letters, uppercase alphabets, digits, any of the
* following special characters:
@@ -241,11 +233,11 @@ static int vfat_find_form(struct inode *
* WinNT's Extension:
* File name and extension name is contain uppercase/lowercase
* only. And it is expressed by CASE_LOWER_BASE and CASE_LOWER_EXT.
- *
+ *
* 2) File name is 8.3 format, but it contain the uppercase and
* lowercase char, muliti bytes char, etc. In this case numtail is not
* added, but Longfilename is stored.
- *
+ *
* 3) When the one except for the above, or the following special
* character are contained:
* . [ ] ; , + =
@@ -263,8 +255,8 @@ struct shortname_info {
} while (0)
static inline int to_shortname_char(struct nls_table *nls,
- unsigned char *buf, int buf_size, wchar_t *src,
- struct shortname_info *info)
+ unsigned char *buf, int buf_size,
+ wchar_t *src, struct shortname_info *info)
{
int len;
@@ -277,7 +269,7 @@ static inline int to_shortname_char(stru
buf[0] = '_';
return 1;
}
-
+
len = nls->uni2char(*src, buf, buf_size);
if (len <= 0) {
info->valid = 0;
@@ -302,7 +294,7 @@ static inline int to_shortname_char(stru
info->lower = 0;
info->upper = 0;
}
-
+
return len;
}
@@ -332,7 +324,7 @@ static int vfat_create_shortname(struct
/* Now, we need to create a shortname from the long name */
ext_start = end = &uname[ulen];
while (--ext_start >= uname) {
- if (*ext_start == 0x002E) { /* is `.' */
+ if (*ext_start == 0x002E) { /* is `.' */
if (ext_start == end - 1) {
sz = ulen;
ext_start = NULL;
@@ -361,7 +353,7 @@ static int vfat_create_shortname(struct
ext_start++;
} else {
sz = ulen;
- ext_start=NULL;
+ ext_start = NULL;
}
}
@@ -377,7 +369,7 @@ static int vfat_create_shortname(struct
numtail2_baselen = baselen;
if (baselen < 6 && (baselen + chl) > 6)
numtail_baselen = baselen;
- for (chi = 0; chi < chl; chi++){
+ for (chi = 0; chi < chl; chi++) {
*p++ = charbuf[chi];
baselen++;
if (baselen >= 8)
@@ -452,7 +444,7 @@ static int vfat_create_shortname(struct
BUG();
}
}
-
+
if (MSDOS_SB(dir->i_sb)->options.numtail == 0)
if (vfat_find_form(dir, name_res) < 0)
return 0;
@@ -465,25 +457,25 @@ static int vfat_create_shortname(struct
* values for part of the base.
*/
- if (baselen>6) {
+ if (baselen > 6) {
baselen = numtail_baselen;
name_res[7] = ' ';
}
name_res[baselen] = '~';
for (i = 1; i < 10; i++) {
- name_res[baselen+1] = i + '0';
+ name_res[baselen + 1] = i + '0';
if (vfat_find_form(dir, name_res) < 0)
return 0;
}
i = jiffies & 0xffff;
sz = (jiffies >> 16) & 0x7;
- if (baselen>2) {
+ if (baselen > 2) {
baselen = numtail2_baselen;
name_res[7] = ' ';
}
- name_res[baselen+4] = '~';
- name_res[baselen+5] = '1' + sz;
+ name_res[baselen + 4] = '~';
+ name_res[baselen + 5] = '1' + sz;
while (1) {
sprintf(buf, "%04X", i);
memcpy(&name_res[baselen], buf, 4);
@@ -516,13 +508,14 @@ xlate_to_uni(const unsigned char *name,
* We stripped '.'s before and set len appropriately,
* but utf8_mbstowcs doesn't care about len
*/
- *outlen -= (name_len-len);
+ *outlen -= (name_len - len);
op = &outname[*outlen * sizeof(wchar_t)];
} else {
if (nls) {
for (i = 0, ip = name, op = outname, *outlen = 0;
- i < len && *outlen <= 260; *outlen += 1)
+ i < len && *outlen <= 260;
+ *outlen += 1)
{
if (escape && (*ip == ':')) {
if (i > len - 5)
@@ -550,7 +543,7 @@ xlate_to_uni(const unsigned char *name,
ip += 5;
i += 5;
} else {
- if ((charlen = nls->char2uni(ip, len-i, (wchar_t *)op)) < 0)
+ if ((charlen = nls->char2uni(ip, len - i, (wchar_t *)op)) < 0)
return -EINVAL;
ip += charlen;
i += charlen;
@@ -559,7 +552,8 @@ xlate_to_uni(const unsigned char *name,
}
} else {
for (i = 0, ip = name, op = outname, *outlen = 0;
- i < len && *outlen <= 260; i++, *outlen += 1)
+ i < len && *outlen <= 260;
+ i++, *outlen += 1)
{
*op++ = *ip++;
*op++ = 0;
@@ -607,7 +601,8 @@ static int vfat_build_slots(struct inode
if (res)
return res;
- if(!(page = __get_free_page(GFP_KERNEL)))
+ page = __get_free_page(GFP_KERNEL);
+ if (!page)
return -ENOMEM;
uname = (wchar_t *)page;
@@ -632,9 +627,8 @@ static int vfat_build_slots(struct inode
/* build the entry of long file name */
*slots = usize / 13;
- for (cksum = i = 0; i < 11; i++) {
+ for (cksum = i = 0; i < 11; i++)
cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
- }
for (ps = ds, slot = *slots; slot > 0; slot--, ps++) {
ps->id = slot;
@@ -648,7 +642,7 @@ static int vfat_build_slots(struct inode
fatwchar_to16(ps->name11_12, uname + offset + 11, 2);
}
ds[0].id |= 0x40;
- de = (struct msdos_dir_entry *) ps;
+ de = (struct msdos_dir_entry *)ps;
shortname:
/* build the entry of 8.3 alias name */
@@ -668,7 +662,7 @@ out_free:
return res;
}
-static int vfat_add_entry(struct inode *dir,struct qstr* qname,
+static int vfat_add_entry(struct inode *dir, struct qstr *qname,
int is_dir, struct vfat_slot_info *sinfo_out,
struct buffer_head **bh, struct msdos_dir_entry **de)
{
@@ -684,8 +678,7 @@ static int vfat_add_entry(struct inode *
if (len == 0)
return -ENOENT;
- dir_slots =
- kmalloc(sizeof(struct msdos_dir_slot) * MSDOS_SLOTS, GFP_KERNEL);
+ dir_slots = kmalloc(sizeof(*dir_slots) * MSDOS_SLOTS, GFP_KERNEL);
if (dir_slots == NULL)
return -ENOMEM;
@@ -695,7 +688,8 @@ static int vfat_add_entry(struct inode *
goto cleanup;
/* build the empty directory entry of number of slots */
- offset = fat_add_entries(dir, slots, &dummy_bh, &dummy_de, &dummy_i_pos);
+ offset =
+ fat_add_entries(dir, slots, &dummy_bh, &dummy_de, &dummy_i_pos);
if (offset < 0) {
res = offset;
goto cleanup;
@@ -735,9 +729,9 @@ cleanup:
return res;
}
-static int vfat_find(struct inode *dir,struct qstr* qname,
- struct vfat_slot_info *sinfo, struct buffer_head **last_bh,
- struct msdos_dir_entry **last_de)
+static int vfat_find(struct inode *dir, struct qstr *qname,
+ struct vfat_slot_info *sinfo, struct buffer_head **last_bh,
+ struct msdos_dir_entry **last_de)
{
struct super_block *sb = dir->i_sb;
loff_t offset;
@@ -751,17 +745,17 @@ static int vfat_find(struct inode *dir,s
res = fat_search_long(dir, qname->name, len,
(MSDOS_SB(sb)->options.name_check != 's'),
&offset, &sinfo->longname_offset);
- if (res>0) {
- sinfo->long_slots = res-1;
- if (fat_get_entry(dir,&offset,last_bh,last_de,&sinfo->i_pos)>=0)
+ if (res > 0) {
+ sinfo->long_slots = res - 1;
+ if (fat_get_entry(dir, &offset, last_bh, last_de, &sinfo->i_pos) >= 0)
return 0;
res = -EIO;
- }
+ }
return res ? res : -ENOENT;
}
static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
- struct nameidata *nd)
+ struct nameidata *nd)
{
int res;
struct vfat_slot_info sinfo;
@@ -770,13 +764,13 @@ static struct dentry *vfat_lookup(struct
struct buffer_head *bh = NULL;
struct msdos_dir_entry *de;
int table;
-
+
lock_kernel();
table = (MSDOS_SB(dir->i_sb)->options.name_check == 's') ? 2 : 0;
dentry->d_op = &vfat_dentry_ops[table];
inode = NULL;
- res = vfat_find(dir,&dentry->d_name,&sinfo,&bh,&de);
+ res = vfat_find(dir, &dentry->d_name, &sinfo, &bh, &de);
if (res < 0) {
table++;
goto error;
@@ -789,14 +783,14 @@ static struct dentry *vfat_lookup(struct
}
alias = d_find_alias(inode);
if (alias) {
- if (d_invalidate(alias)==0)
+ if (d_invalidate(alias) == 0)
dput(alias);
else {
iput(inode);
unlock_kernel();
return alias;
}
-
+
}
error:
unlock_kernel();
@@ -810,8 +804,8 @@ error:
return dentry;
}
-static int vfat_create(struct inode *dir, struct dentry* dentry, int mode,
- struct nameidata *nd)
+static int vfat_create(struct inode *dir, struct dentry *dentry, int mode,
+ struct nameidata *nd)
{
struct super_block *sb = dir->i_sb;
struct inode *inode = NULL;
@@ -834,14 +828,15 @@ static int vfat_create(struct inode *dir
inode->i_version++;
dir->i_version++;
dentry->d_time = dentry->d_parent->d_inode->i_version;
- d_instantiate(dentry,inode);
+ d_instantiate(dentry, inode);
out:
unlock_kernel();
return res;
}
-static void vfat_remove_entry(struct inode *dir,struct vfat_slot_info *sinfo,
- struct buffer_head *bh, struct msdos_dir_entry *de)
+static void vfat_remove_entry(struct inode *dir, struct vfat_slot_info *sinfo,
+ struct buffer_head *bh,
+ struct msdos_dir_entry *de)
{
loff_t offset, i_pos;
int i;
@@ -853,7 +848,8 @@ static void vfat_remove_entry(struct ino
de->name[0] = DELETED_FLAG;
mark_buffer_dirty(bh);
/* remove the longname */
- offset = sinfo->longname_offset; de = NULL;
+ offset = sinfo->longname_offset;
+ de = NULL;
for (i = sinfo->long_slots; i > 0; --i) {
if (fat_get_entry(dir, &offset, &bh, &de, &i_pos) < 0)
continue;
@@ -864,28 +860,30 @@ static void vfat_remove_entry(struct ino
brelse(bh);
}
-static int vfat_rmdir(struct inode *dir, struct dentry* dentry)
+static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
{
- int res;
+ struct inode *inode = dentry->d_inode;
struct vfat_slot_info sinfo;
struct buffer_head *bh = NULL;
struct msdos_dir_entry *de;
+ int res;
lock_kernel();
- res = fat_dir_empty(dentry->d_inode);
+ res = fat_dir_empty(inode);
if (res)
goto out;
- res = vfat_find(dir,&dentry->d_name,&sinfo, &bh, &de);
+ res = vfat_find(dir, &dentry->d_name, &sinfo, &bh, &de);
if (res < 0)
goto out;
+
res = 0;
- dentry->d_inode->i_nlink = 0;
- dentry->d_inode->i_mtime = dentry->d_inode->i_atime = CURRENT_TIME_SEC;
- fat_detach(dentry->d_inode);
- mark_inode_dirty(dentry->d_inode);
+ inode->i_nlink = 0;
+ inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
+ fat_detach(inode);
+ mark_inode_dirty(inode);
/* releases bh */
- vfat_remove_entry(dir,&sinfo,bh,de);
+ vfat_remove_entry(dir, &sinfo, bh, de);
dir->i_nlink--;
out:
unlock_kernel();
@@ -894,28 +892,29 @@ out:
static int vfat_unlink(struct inode *dir, struct dentry *dentry)
{
- int res;
+ struct inode *inode = dentry->d_inode;
struct vfat_slot_info sinfo;
struct buffer_head *bh = NULL;
struct msdos_dir_entry *de;
+ int res;
lock_kernel();
- res = vfat_find(dir,&dentry->d_name,&sinfo,&bh,&de);
+ res = vfat_find(dir, &dentry->d_name, &sinfo, &bh, &de);
if (res < 0)
goto out;
- dentry->d_inode->i_nlink = 0;
- dentry->d_inode->i_mtime = dentry->d_inode->i_atime = CURRENT_TIME_SEC;
- fat_detach(dentry->d_inode);
- mark_inode_dirty(dentry->d_inode);
+ inode->i_nlink = 0;
+ inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
+ fat_detach(inode);
+ mark_inode_dirty(inode);
/* releases bh */
- vfat_remove_entry(dir,&sinfo,bh,de);
+ vfat_remove_entry(dir, &sinfo, bh, de);
out:
unlock_kernel();
return res;
}
-static int vfat_mkdir(struct inode *dir,struct dentry* dentry,int mode)
+static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
struct super_block *sb = dir->i_sb;
struct inode *inode = NULL;
@@ -936,12 +935,12 @@ static int vfat_mkdir(struct inode *dir,
inode->i_version++;
dir->i_version++;
dir->i_nlink++;
- inode->i_nlink = 2; /* no need to mark them dirty */
+ inode->i_nlink = 2; /* no need to mark them dirty */
res = fat_new_dir(inode, dir, 1);
if (res < 0)
goto mkdir_failed;
dentry->d_time = dentry->d_parent->d_inode->i_version;
- d_instantiate(dentry,inode);
+ d_instantiate(dentry, inode);
out_brelse:
brelse(bh);
out:
@@ -954,27 +953,28 @@ mkdir_failed:
fat_detach(inode);
mark_inode_dirty(inode);
/* releases bh */
- vfat_remove_entry(dir,&sinfo,bh,de);
+ vfat_remove_entry(dir, &sinfo, bh, de);
iput(inode);
dir->i_nlink--;
goto out;
}
-
+
static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry)
+ struct inode *new_dir, struct dentry *new_dentry)
{
- struct buffer_head *old_bh,*new_bh,*dotdot_bh;
- struct msdos_dir_entry *old_de,*new_de,*dotdot_de;
+ struct buffer_head *old_bh, *new_bh, *dotdot_bh;
+ struct msdos_dir_entry *old_de, *new_de, *dotdot_de;
loff_t dotdot_i_pos;
struct inode *old_inode, *new_inode;
int res, is_dir;
- struct vfat_slot_info old_sinfo,sinfo;
+ struct vfat_slot_info old_sinfo, sinfo;
old_bh = new_bh = dotdot_bh = NULL;
old_inode = old_dentry->d_inode;
new_inode = new_dentry->d_inode;
lock_kernel();
- res = vfat_find(old_dir,&old_dentry->d_name,&old_sinfo,&old_bh,&old_de);
+ res = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo, &old_bh,
+ &old_de);
if (res < 0)
goto rename_done;
@@ -989,7 +989,7 @@ static int vfat_rename(struct inode *old
}
if (new_dentry->d_inode) {
- res = vfat_find(new_dir,&new_dentry->d_name,&sinfo,&new_bh,
+ res = vfat_find(new_dir, &new_dentry->d_name, &sinfo, &new_bh,
&new_de);
if (res < 0 || MSDOS_I(new_inode)->i_pos != sinfo.i_pos) {
/* WTF??? Cry and fail. */
@@ -1004,16 +1004,17 @@ static int vfat_rename(struct inode *old
}
fat_detach(new_inode);
} else {
- res = vfat_add_entry(new_dir,&new_dentry->d_name,is_dir,&sinfo,
- &new_bh,&new_de);
- if (res < 0) goto rename_done;
+ res = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir,
+ &sinfo, &new_bh, &new_de);
+ if (res < 0)
+ goto rename_done;
}
new_dir->i_version++;
/* releases old_bh */
- vfat_remove_entry(old_dir,&old_sinfo,old_bh,old_de);
- old_bh=NULL;
+ vfat_remove_entry(old_dir, &old_sinfo, old_bh, old_de);
+ old_bh = NULL;
fat_detach(old_inode);
fat_attach(old_inode, sinfo.i_pos);
mark_inode_dirty(old_inode);
@@ -1046,7 +1047,6 @@ rename_done:
brelse(new_bh);
unlock_kernel();
return res;
-
}
static struct inode_operations vfat_dir_inode_operations = {
@@ -1076,7 +1076,8 @@ static int vfat_fill_super(struct super_
}
static struct super_block *vfat_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
+ int flags, const char *dev_name,
+ void *data)
{
return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super);
}
_
This patch is just cleanup (whitespace, and place of functions is changed).
No changes of logic.
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/fat/cache.c | 68 ---
fs/fat/dir.c | 252 ++++++-----
fs/fat/file.c | 168 +++++--
fs/fat/inode.c | 1035 +++++++++++++++++++++++------------------------
fs/fat/misc.c | 94 +---
include/linux/msdos_fs.h | 113 ++---
6 files changed, 846 insertions(+), 884 deletions(-)
diff -puN fs/fat/cache.c~fat_cleanup fs/fat/cache.c
--- linux-2.6.10/fs/fat/cache.c~fat_cleanup 2005-01-10 01:57:57.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/cache.c 2005-01-10 05:07:47.000000000 +0900
@@ -296,7 +296,7 @@ static int __fat_access(struct super_blo
return next;
}
-/*
+/*
* Returns the this'th FAT entry, -1 if it is an end-of-file entry. If
* new_value is != -1, that FAT entry is replaced by it.
*/
@@ -343,7 +343,7 @@ int fat_get_cluster(struct inode *inode,
int nr;
BUG_ON(MSDOS_I(inode)->i_start == 0);
-
+
*fclus = 0;
*dclus = MSDOS_I(inode)->i_start;
if (cluster == 0)
@@ -368,7 +368,7 @@ int fat_get_cluster(struct inode *inode,
nr = fat_access(sb, *dclus, -1);
if (nr < 0)
- return nr;
+ return nr;
else if (nr == FAT_ENT_FREE) {
fat_fs_panic(sb, "%s: invalid cluster chain"
" (i_pos %lld)", __FUNCTION__,
@@ -437,65 +437,3 @@ int fat_bmap(struct inode *inode, sector
}
return 0;
}
-
-/* Free all clusters after the skip'th cluster. */
-int fat_free(struct inode *inode, int skip)
-{
- struct super_block *sb = inode->i_sb;
- int nr, ret, fclus, dclus;
-
- if (MSDOS_I(inode)->i_start == 0)
- return 0;
-
- if (skip) {
- ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus);
- if (ret < 0)
- return ret;
- else if (ret == FAT_ENT_EOF)
- return 0;
-
- nr = fat_access(sb, dclus, -1);
- if (nr == FAT_ENT_EOF)
- return 0;
- else if (nr > 0) {
- /*
- * write a new EOF, and get the remaining cluster
- * chain for freeing.
- */
- nr = fat_access(sb, dclus, FAT_ENT_EOF);
- }
- if (nr < 0)
- return nr;
-
- fat_cache_inval_inode(inode);
- } else {
- fat_cache_inval_inode(inode);
-
- nr = MSDOS_I(inode)->i_start;
- MSDOS_I(inode)->i_start = 0;
- MSDOS_I(inode)->i_logstart = 0;
- mark_inode_dirty(inode);
- }
-
- lock_fat(sb);
- do {
- nr = fat_access(sb, nr, FAT_ENT_FREE);
- if (nr < 0)
- goto error;
- else if (nr == FAT_ENT_FREE) {
- fat_fs_panic(sb, "%s: deleting beyond EOF (i_pos %lld)",
- __FUNCTION__, MSDOS_I(inode)->i_pos);
- nr = -EIO;
- goto error;
- }
- if (MSDOS_SB(sb)->free_clusters != -1)
- MSDOS_SB(sb)->free_clusters++;
- inode->i_blocks -= MSDOS_SB(sb)->cluster_size >> 9;
- } while (nr != FAT_ENT_EOF);
- fat_clusters_flush(sb);
- nr = 0;
-error:
- unlock_fat(sb);
-
- return nr;
-}
diff -puN fs/fat/dir.c~fat_cleanup fs/fat/dir.c
--- linux-2.6.10/fs/fat/dir.c~fat_cleanup 2005-01-10 01:57:57.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/dir.c 2005-01-10 05:07:47.000000000 +0900
@@ -20,20 +20,8 @@
#include <linux/dirent.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
-
#include <asm/uaccess.h>
-static int fat_dir_ioctl(struct inode * inode, struct file * filp,
- unsigned int cmd, unsigned long arg);
-static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir);
-
-struct file_operations fat_dir_operations = {
- .read = generic_read_dir,
- .readdir = fat_readdir,
- .ioctl = fat_dir_ioctl,
- .fsync = file_fsync,
-};
-
/*
* Convert Unicode 16 to UTF8, translated Unicode, or ASCII.
* If uni_xlate is enabled and we can't get a 1:1 conversion, use a
@@ -44,9 +32,8 @@ struct file_operations fat_dir_operation
* but ignore that right now.
* Ahem... Stack smashing in ring 0 isn't fun. Fixed.
*/
-static int
-uni16_to_x8(unsigned char *ascii, wchar_t *uni, int uni_xlate,
- struct nls_table *nls)
+static int uni16_to_x8(unsigned char *ascii, wchar_t *uni, int uni_xlate,
+ struct nls_table *nls)
{
wchar_t *ip, ec;
unsigned char *op, nc;
@@ -84,20 +71,6 @@ uni16_to_x8(unsigned char *ascii, wchar_
return (op - ascii);
}
-#if 0
-static void dump_de(struct msdos_dir_entry *de)
-{
- int i;
- unsigned char *p = (unsigned char *) de;
- printk("[");
-
- for (i = 0; i < 32; i++, p++) {
- printk("%02x ", *p);
- }
- printk("]\n");
-}
-#endif
-
static inline int
fat_short2uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni)
{
@@ -123,17 +96,17 @@ fat_short2lower_uni(struct nls_table *t,
charlen = 1;
} else if (charlen <= 1) {
unsigned char nc = t->charset2lower[*c];
-
+
if (!nc)
nc = *c;
-
+
if ( (charlen = t->char2uni(&nc, 1, uni)) < 0) {
*uni = 0x003f; /* a question mark */
charlen = 1;
}
} else
*uni = wc;
-
+
return charlen;
}
@@ -150,7 +123,7 @@ fat_shortname2uni(struct nls_table *nls,
else if (opt & VFAT_SFN_DISPLAY_WINNT) {
if (lower)
len = fat_short2lower_uni(nls, buf, buf_size, uni_buf);
- else
+ else
len = fat_short2uni(nls, buf, buf_size, uni_buf);
} else
len = fat_short2uni(nls, buf, buf_size, uni_buf);
@@ -326,6 +299,8 @@ EODir:
return res;
}
+EXPORT_SYMBOL(fat_search_long);
+
struct fat_ioctl_filldir_callback {
struct dirent __user *dirent;
int result;
@@ -336,8 +311,6 @@ struct fat_ioctl_filldir_callback {
int short_len;
};
-EXPORT_SYMBOL(fat_search_long);
-
static int fat_readdirx(struct inode *inode, struct file *filp, void *dirent,
filldir_t filldir, int short_only, int both)
{
@@ -362,7 +335,7 @@ static int fat_readdirx(struct inode *in
int chi, chl, i, i2, j, last, last_u, dotoffset = 0;
loff_t i_pos, cpos;
int ret = 0;
-
+
lock_kernel();
cpos = filp->f_pos;
@@ -385,7 +358,7 @@ static int fat_readdirx(struct inode *in
goto out;
}
- bh = NULL;
+ bh = NULL;
GetNew:
long_slots = 0;
if (fat_get_entry(inode,&cpos,&bh,&de,&i_pos) == -1)
@@ -694,6 +667,132 @@ static int fat_dir_ioctl(struct inode *
return ret;
}
+struct file_operations fat_dir_operations = {
+ .read = generic_read_dir,
+ .readdir = fat_readdir,
+ .ioctl = fat_dir_ioctl,
+ .fsync = file_fsync,
+};
+
+static int fat_get_short_entry(struct inode *dir, loff_t *pos,
+ struct buffer_head **bh,
+ struct msdos_dir_entry **de, loff_t *i_pos)
+{
+ while (fat_get_entry(dir, pos, bh, de, i_pos) >= 0) {
+ /* free entry or long name entry or volume label */
+ if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME))
+ return 0;
+ }
+ return -ENOENT;
+}
+
+/* See if directory is empty */
+int fat_dir_empty(struct inode *dir)
+{
+ struct buffer_head *bh;
+ struct msdos_dir_entry *de;
+ loff_t cpos, i_pos;
+ int result = 0;
+
+ bh = NULL;
+ cpos = 0;
+ while (fat_get_short_entry(dir, &cpos, &bh, &de, &i_pos) >= 0) {
+ if (strncmp(de->name, MSDOS_DOT , MSDOS_NAME) &&
+ strncmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) {
+ result = -ENOTEMPTY;
+ break;
+ }
+ }
+ brelse(bh);
+ return result;
+}
+
+EXPORT_SYMBOL(fat_dir_empty);
+
+/*
+ * fat_subdirs counts the number of sub-directories of dir. It can be run
+ * on directories being created.
+ */
+int fat_subdirs(struct inode *dir)
+{
+ struct buffer_head *bh;
+ struct msdos_dir_entry *de;
+ loff_t cpos, i_pos;
+ int count = 0;
+
+ bh = NULL;
+ cpos = 0;
+ while (fat_get_short_entry(dir, &cpos, &bh, &de, &i_pos) >= 0) {
+ if (de->attr & ATTR_DIR)
+ count++;
+ }
+ brelse(bh);
+ return count;
+}
+
+/*
+ * Scans a directory for a given file (name points to its formatted name).
+ * Returns an error code or zero.
+ */
+int fat_scan(struct inode *dir, const unsigned char *name,
+ struct buffer_head **bh, struct msdos_dir_entry **de,
+ loff_t *i_pos)
+{
+ loff_t cpos;
+
+ *bh = NULL;
+ cpos = 0;
+ while (fat_get_short_entry(dir, &cpos, bh, de, i_pos) >= 0) {
+ if (!strncmp((*de)->name, name, MSDOS_NAME))
+ return 0;
+ }
+ return -ENOENT;
+}
+
+EXPORT_SYMBOL(fat_scan);
+
+static struct buffer_head *fat_extend_dir(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+ struct buffer_head *bh, *res = NULL;
+ int nr, sec_per_clus = MSDOS_SB(sb)->sec_per_clus;
+ sector_t sector, last_sector;
+
+ if (MSDOS_SB(sb)->fat_bits != 32) {
+ if (inode->i_ino == MSDOS_ROOT_INO)
+ return ERR_PTR(-ENOSPC);
+ }
+
+ nr = fat_add_cluster(inode);
+ if (nr < 0)
+ return ERR_PTR(nr);
+
+ sector = ((sector_t)nr - 2) * sec_per_clus + MSDOS_SB(sb)->data_start;
+ last_sector = sector + sec_per_clus;
+ for ( ; sector < last_sector; sector++) {
+ if ((bh = sb_getblk(sb, sector))) {
+ memset(bh->b_data, 0, sb->s_blocksize);
+ set_buffer_uptodate(bh);
+ mark_buffer_dirty(bh);
+ if (!res)
+ res = bh;
+ else
+ brelse(bh);
+ }
+ }
+ if (res == NULL)
+ res = ERR_PTR(-EIO);
+ if (inode->i_size & (sb->s_blocksize - 1)) {
+ fat_fs_panic(sb, "Odd directory size");
+ inode->i_size = (inode->i_size + sb->s_blocksize)
+ & ~((loff_t)sb->s_blocksize - 1);
+ }
+ inode->i_size += MSDOS_SB(sb)->cluster_size;
+ MSDOS_I(inode)->mmu_private += MSDOS_SB(sb)->cluster_size;
+
+ return res;
+}
+
/* This assumes that size of cluster is above the 32*slots */
int fat_add_entries(struct inode *dir,int slots, struct buffer_head **bh,
@@ -722,7 +821,7 @@ int fat_add_entries(struct inode *dir,in
offset = curr;
}
}
- if ((dir->i_ino == MSDOS_ROOT_INO) && (MSDOS_SB(sb)->fat_bits != 32))
+ if ((dir->i_ino == MSDOS_ROOT_INO) && (MSDOS_SB(sb)->fat_bits != 32))
return -ENOSPC;
new_bh = fat_extend_dir(dir);
if (IS_ERR(new_bh))
@@ -773,80 +872,3 @@ int fat_new_dir(struct inode *dir, struc
}
EXPORT_SYMBOL(fat_new_dir);
-
-static int fat_get_short_entry(struct inode *dir, loff_t *pos,
- struct buffer_head **bh,
- struct msdos_dir_entry **de, loff_t *i_pos)
-{
- while (fat_get_entry(dir, pos, bh, de, i_pos) >= 0) {
- /* free entry or long name entry or volume label */
- if (!IS_FREE((*de)->name) && !((*de)->attr & ATTR_VOLUME))
- return 0;
- }
- return -ENOENT;
-}
-
-/* See if directory is empty */
-int fat_dir_empty(struct inode *dir)
-{
- struct buffer_head *bh;
- struct msdos_dir_entry *de;
- loff_t cpos, i_pos;
- int result = 0;
-
- bh = NULL;
- cpos = 0;
- while (fat_get_short_entry(dir, &cpos, &bh, &de, &i_pos) >= 0) {
- if (strncmp(de->name, MSDOS_DOT , MSDOS_NAME) &&
- strncmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) {
- result = -ENOTEMPTY;
- break;
- }
- }
- brelse(bh);
- return result;
-}
-
-EXPORT_SYMBOL(fat_dir_empty);
-
-/*
- * fat_subdirs counts the number of sub-directories of dir. It can be run
- * on directories being created.
- */
-int fat_subdirs(struct inode *dir)
-{
- struct buffer_head *bh;
- struct msdos_dir_entry *de;
- loff_t cpos, i_pos;
- int count = 0;
-
- bh = NULL;
- cpos = 0;
- while (fat_get_short_entry(dir, &cpos, &bh, &de, &i_pos) >= 0) {
- if (de->attr & ATTR_DIR)
- count++;
- }
- brelse(bh);
- return count;
-}
-
-/*
- * Scans a directory for a given file (name points to its formatted name).
- * Returns an error code or zero.
- */
-int fat_scan(struct inode *dir, const unsigned char *name,
- struct buffer_head **bh, struct msdos_dir_entry **de,
- loff_t *i_pos)
-{
- loff_t cpos;
-
- *bh = NULL;
- cpos = 0;
- while (fat_get_short_entry(dir, &cpos, bh, de, i_pos) >= 0) {
- if (!strncmp((*de)->name, name, MSDOS_NAME))
- return 0;
- }
- return -ENOENT;
-}
-
-EXPORT_SYMBOL(fat_scan);
diff -puN fs/fat/file.c~fat_cleanup fs/fat/file.c
--- linux-2.6.10/fs/fat/file.c~fat_cleanup 2005-01-10 01:57:57.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/file.c 2005-01-10 05:07:45.000000000 +0900
@@ -6,13 +6,26 @@
* regular file handling primitives for fat-based filesystems
*/
+#include <linux/module.h>
#include <linux/time.h>
#include <linux/msdos_fs.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
static ssize_t fat_file_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *ppos);
+ size_t count, loff_t *ppos)
+{
+ struct inode *inode = filp->f_dentry->d_inode;
+ int retval;
+
+ retval = generic_file_write(filp, buf, count, ppos);
+ if (retval > 0) {
+ inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
+ MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
+ mark_inode_dirty(inode);
+ }
+ return retval;
+}
struct file_operations fat_file_operations = {
.llseek = generic_file_llseek,
@@ -25,63 +38,117 @@ struct file_operations fat_file_operatio
.sendfile = generic_file_sendfile,
};
-struct inode_operations fat_file_inode_operations = {
- .truncate = fat_truncate,
- .setattr = fat_notify_change,
-};
-
-int fat_get_block(struct inode *inode, sector_t iblock,
- struct buffer_head *bh_result, int create)
+int fat_notify_change(struct dentry *dentry, struct iattr *attr)
{
- struct super_block *sb = inode->i_sb;
- sector_t phys;
- int err;
+ struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
+ struct inode *inode = dentry->d_inode;
+ int mask, error = 0;
- err = fat_bmap(inode, iblock, &phys);
- if (err)
- return err;
- if (phys) {
- map_bh(bh_result, sb, phys);
- return 0;
- }
- if (!create)
- return 0;
- if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
- fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
- MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
- return -EIO;
+ lock_kernel();
+
+ /* FAT cannot truncate to a longer file */
+ if (attr->ia_valid & ATTR_SIZE) {
+ if (attr->ia_size > inode->i_size) {
+ error = -EPERM;
+ goto out;
+ }
}
- if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) {
- int error;
- error = fat_add_cluster(inode);
- if (error < 0)
- return error;
+ error = inode_change_ok(inode, attr);
+ if (error) {
+ if (sbi->options.quiet)
+ error = 0;
+ goto out;
+ }
+ if (((attr->ia_valid & ATTR_UID) &&
+ (attr->ia_uid != sbi->options.fs_uid)) ||
+ ((attr->ia_valid & ATTR_GID) &&
+ (attr->ia_gid != sbi->options.fs_gid)) ||
+ ((attr->ia_valid & ATTR_MODE) &&
+ (attr->ia_mode & ~MSDOS_VALID_MODE)))
+ error = -EPERM;
+
+ if (error) {
+ if (sbi->options.quiet)
+ error = 0;
+ goto out;
}
- MSDOS_I(inode)->mmu_private += sb->s_blocksize;
- err = fat_bmap(inode, iblock, &phys);
- if (err)
- return err;
- if (!phys)
- BUG();
- set_buffer_new(bh_result);
- map_bh(bh_result, sb, phys);
- return 0;
+ error = inode_setattr(inode, attr);
+ if (error)
+ goto out;
+
+ if (S_ISDIR(inode->i_mode))
+ mask = sbi->options.fs_dmask;
+ else
+ mask = sbi->options.fs_fmask;
+ inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
+out:
+ unlock_kernel();
+ return error;
}
-static ssize_t fat_file_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *ppos)
+EXPORT_SYMBOL(fat_notify_change);
+
+/* Free all clusters after the skip'th cluster. */
+static int fat_free(struct inode *inode, int skip)
{
- struct inode *inode = filp->f_dentry->d_inode;
- int retval;
+ struct super_block *sb = inode->i_sb;
+ int nr, ret, fclus, dclus;
- retval = generic_file_write(filp, buf, count, ppos);
- if (retval > 0) {
- inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
- MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
+ if (MSDOS_I(inode)->i_start == 0)
+ return 0;
+
+ if (skip) {
+ ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus);
+ if (ret < 0)
+ return ret;
+ else if (ret == FAT_ENT_EOF)
+ return 0;
+
+ nr = fat_access(sb, dclus, -1);
+ if (nr == FAT_ENT_EOF)
+ return 0;
+ else if (nr > 0) {
+ /*
+ * write a new EOF, and get the remaining cluster
+ * chain for freeing.
+ */
+ nr = fat_access(sb, dclus, FAT_ENT_EOF);
+ }
+ if (nr < 0)
+ return nr;
+
+ fat_cache_inval_inode(inode);
+ } else {
+ fat_cache_inval_inode(inode);
+
+ nr = MSDOS_I(inode)->i_start;
+ MSDOS_I(inode)->i_start = 0;
+ MSDOS_I(inode)->i_logstart = 0;
mark_inode_dirty(inode);
}
- return retval;
+
+ lock_fat(sb);
+ do {
+ nr = fat_access(sb, nr, FAT_ENT_FREE);
+ if (nr < 0)
+ goto error;
+ else if (nr == FAT_ENT_FREE) {
+ fat_fs_panic(sb, "%s: deleting beyond EOF (i_pos %lld)",
+ __FUNCTION__, MSDOS_I(inode)->i_pos);
+ nr = -EIO;
+ goto error;
+ }
+ if (MSDOS_SB(sb)->free_clusters != -1)
+ MSDOS_SB(sb)->free_clusters++;
+ inode->i_blocks -= MSDOS_SB(sb)->cluster_size >> 9;
+ } while (nr != FAT_ENT_EOF);
+ fat_clusters_flush(sb);
+ nr = 0;
+error:
+ unlock_fat(sb);
+
+ return nr;
}
void fat_truncate(struct inode *inode)
@@ -90,7 +157,7 @@ void fat_truncate(struct inode *inode)
const unsigned int cluster_size = sbi->cluster_size;
int nr_clusters;
- /*
+ /*
* This protects against truncating a file bigger than it was then
* trying to write into the hole.
*/
@@ -106,3 +173,8 @@ void fat_truncate(struct inode *inode)
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
}
+
+struct inode_operations fat_file_inode_operations = {
+ .truncate = fat_truncate,
+ .setattr = fat_notify_change,
+};
diff -puN fs/fat/inode.c~fat_cleanup fs/fat/inode.c
--- linux-2.6.10/fs/fat/inode.c~fat_cleanup 2005-01-10 01:57:57.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/inode.c 2005-01-10 05:07:47.000000000 +0900
@@ -7,7 +7,7 @@
*
* Fixes:
*
- * Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
+ * Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
*/
#include <linux/module.h>
@@ -32,8 +32,76 @@
static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;
-static int fat_statfs(struct super_block *sb, struct kstatfs *buf);
-static int fat_write_inode(struct inode *inode, int wait);
+
+static int fat_get_block(struct inode *inode, sector_t iblock,
+ struct buffer_head *bh_result, int create)
+{
+ struct super_block *sb = inode->i_sb;
+ sector_t phys;
+ int err;
+
+ err = fat_bmap(inode, iblock, &phys);
+ if (err)
+ return err;
+ if (phys) {
+ map_bh(bh_result, sb, phys);
+ return 0;
+ }
+ if (!create)
+ return 0;
+ if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
+ fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
+ MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
+ return -EIO;
+ }
+ if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) {
+ int error;
+
+ error = fat_add_cluster(inode);
+ if (error < 0)
+ return error;
+ }
+ MSDOS_I(inode)->mmu_private += sb->s_blocksize;
+ err = fat_bmap(inode, iblock, &phys);
+ if (err)
+ return err;
+ if (!phys)
+ BUG();
+ set_buffer_new(bh_result);
+ map_bh(bh_result, sb, phys);
+ return 0;
+}
+
+static int fat_writepage(struct page *page, struct writeback_control *wbc)
+{
+ return block_write_full_page(page, fat_get_block, wbc);
+}
+
+static int fat_readpage(struct file *file, struct page *page)
+{
+ return block_read_full_page(page, fat_get_block);
+}
+
+static int fat_prepare_write(struct file *file, struct page *page,
+ unsigned from, unsigned to)
+{
+ return cont_prepare_write(page, from, to, fat_get_block,
+ &MSDOS_I(page->mapping->host)->mmu_private);
+}
+
+static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
+{
+ return generic_block_bmap(mapping, block, fat_get_block);
+}
+
+static struct address_space_operations fat_aops = {
+ .readpage = fat_readpage,
+ .writepage = fat_writepage,
+ .sync_page = block_sync_page,
+ .prepare_write = fat_prepare_write,
+ .commit_write = generic_commit_write,
+ .bmap = _fat_bmap
+};
/*
* New FAT inode stuff. We do the following:
@@ -122,7 +190,102 @@ struct inode *fat_iget(struct super_bloc
return inode;
}
-static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de);
+static int is_exec(unsigned char *extension)
+{
+ unsigned char *exe_extensions = "EXECOMBAT", *walk;
+
+ for (walk = exe_extensions; *walk; walk += 3)
+ if (!strncmp(extension, walk, 3))
+ return 1;
+ return 0;
+}
+
+static int fat_calc_dir_size(struct inode *inode)
+{
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+ int ret, fclus, dclus;
+
+ inode->i_size = 0;
+ if (MSDOS_I(inode)->i_start == 0)
+ return 0;
+
+ ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
+ if (ret < 0)
+ return ret;
+ inode->i_size = (fclus + 1) << sbi->cluster_bits;
+
+ return 0;
+}
+
+/* doesn't deal with root inode */
+static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
+{
+ struct super_block *sb = inode->i_sb;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ int error;
+
+ MSDOS_I(inode)->i_pos = 0;
+ inode->i_uid = sbi->options.fs_uid;
+ inode->i_gid = sbi->options.fs_gid;
+ inode->i_version++;
+ inode->i_generation = get_seconds();
+
+ if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
+ inode->i_generation &= ~1;
+ inode->i_mode = MSDOS_MKMODE(de->attr,
+ S_IRWXUGO & ~sbi->options.fs_dmask) | S_IFDIR;
+ inode->i_op = sbi->dir_ops;
+ inode->i_fop = &fat_dir_operations;
+
+ MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
+ if (sbi->fat_bits == 32)
+ MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
+
+ MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
+ error = fat_calc_dir_size(inode);
+ if (error < 0)
+ return error;
+ MSDOS_I(inode)->mmu_private = inode->i_size;
+
+ inode->i_nlink = fat_subdirs(inode);
+ } else { /* not a directory */
+ inode->i_generation |= 1;
+ inode->i_mode = MSDOS_MKMODE(de->attr,
+ ((sbi->options.showexec &&
+ !is_exec(de->ext))
+ ? S_IRUGO|S_IWUGO : S_IRWXUGO)
+ & ~sbi->options.fs_fmask) | S_IFREG;
+ MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
+ if (sbi->fat_bits == 32)
+ MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
+
+ 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;
+ inode->i_fop = &fat_file_operations;
+ inode->i_mapping->a_ops = &fat_aops;
+ MSDOS_I(inode)->mmu_private = inode->i_size;
+ }
+ if(de->attr & ATTR_SYS)
+ if (sbi->options.sys_immutable)
+ inode->i_flags |= S_IMMUTABLE;
+ MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
+ /* this is as close to the truth as we can get ... */
+ inode->i_blksize = sbi->cluster_size;
+ inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
+ & ~((loff_t)sbi->cluster_size - 1)) >> 9;
+ inode->i_mtime.tv_sec = inode->i_atime.tv_sec =
+ date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date));
+ inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = 0;
+ inode->i_ctime.tv_sec =
+ MSDOS_SB(sb)->options.isvfat
+ ? date_dos2unix(le16_to_cpu(de->ctime), le16_to_cpu(de->cdate))
+ : inode->i_mtime.tv_sec;
+ inode->i_ctime.tv_nsec = de->ctime_ms * 1000000;
+ MSDOS_I(inode)->i_ctime_ms = de->ctime_ms;
+
+ return 0;
+}
struct inode *fat_build_inode(struct super_block *sb,
struct msdos_dir_entry *de, loff_t i_pos, int *res)
@@ -177,29 +340,343 @@ static void fat_clear_inode(struct inode
static void fat_put_super(struct super_block *sb)
{
- struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
+
+ if (!(sb->s_flags & MS_RDONLY))
+ fat_clusters_flush(sb);
+
+ if (sbi->nls_disk) {
+ unload_nls(sbi->nls_disk);
+ sbi->nls_disk = NULL;
+ sbi->options.codepage = fat_default_codepage;
+ }
+ if (sbi->nls_io) {
+ unload_nls(sbi->nls_io);
+ sbi->nls_io = NULL;
+ }
+ if (sbi->options.iocharset != fat_default_iocharset) {
+ kfree(sbi->options.iocharset);
+ sbi->options.iocharset = fat_default_iocharset;
+ }
+
+ sb->s_fs_info = NULL;
+ kfree(sbi);
+}
+
+static kmem_cache_t *fat_inode_cachep;
+
+static struct inode *fat_alloc_inode(struct super_block *sb)
+{
+ struct msdos_inode_info *ei;
+ ei = kmem_cache_alloc(fat_inode_cachep, SLAB_KERNEL);
+ if (!ei)
+ return NULL;
+ return &ei->vfs_inode;
+}
+
+static void fat_destroy_inode(struct inode *inode)
+{
+ kmem_cache_free(fat_inode_cachep, MSDOS_I(inode));
+}
+
+static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+{
+ struct msdos_inode_info *ei = (struct msdos_inode_info *)foo;
+
+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+ SLAB_CTOR_CONSTRUCTOR) {
+ spin_lock_init(&ei->cache_lru_lock);
+ ei->nr_caches = 0;
+ ei->cache_valid_id = FAT_CACHE_VALID + 1;
+ INIT_LIST_HEAD(&ei->cache_lru);
+ INIT_HLIST_NODE(&ei->i_fat_hash);
+ inode_init_once(&ei->vfs_inode);
+ }
+}
+
+static int __init fat_init_inodecache(void)
+{
+ fat_inode_cachep = kmem_cache_create("fat_inode_cache",
+ sizeof(struct msdos_inode_info),
+ 0, SLAB_RECLAIM_ACCOUNT,
+ init_once, NULL);
+ if (fat_inode_cachep == NULL)
+ return -ENOMEM;
+ return 0;
+}
+
+static void __exit fat_destroy_inodecache(void)
+{
+ if (kmem_cache_destroy(fat_inode_cachep))
+ printk(KERN_INFO "fat_inode_cache: not all structures were freed\n");
+}
+
+static int fat_remount(struct super_block *sb, int *flags, char *data)
+{
+ *flags |= MS_NODIRATIME;
+ return 0;
+}
+
+static int fat_statfs(struct super_block *sb, struct kstatfs *buf)
+{
+ int free, nr, ret;
+
+ if (MSDOS_SB(sb)->free_clusters != -1)
+ free = MSDOS_SB(sb)->free_clusters;
+ else {
+ lock_fat(sb);
+ if (MSDOS_SB(sb)->free_clusters != -1)
+ free = MSDOS_SB(sb)->free_clusters;
+ else {
+ free = 0;
+ for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) {
+ ret = fat_access(sb, nr, -1);
+ if (ret < 0) {
+ unlock_fat(sb);
+ return ret;
+ } else if (ret == FAT_ENT_FREE)
+ free++;
+ }
+ MSDOS_SB(sb)->free_clusters = free;
+ }
+ unlock_fat(sb);
+ }
+
+ buf->f_type = sb->s_magic;
+ buf->f_bsize = MSDOS_SB(sb)->cluster_size;
+ buf->f_blocks = MSDOS_SB(sb)->clusters;
+ buf->f_bfree = free;
+ buf->f_bavail = free;
+ buf->f_namelen = MSDOS_SB(sb)->options.isvfat ? 260 : 12;
+
+ return 0;
+}
+
+static int fat_write_inode(struct inode *inode, int wait)
+{
+ struct super_block *sb = inode->i_sb;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ struct buffer_head *bh;
+ struct msdos_dir_entry *raw_entry;
+ loff_t i_pos;
+
+retry:
+ i_pos = MSDOS_I(inode)->i_pos;
+ if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) {
+ return 0;
+ }
+ lock_kernel();
+ if (!(bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits))) {
+ printk(KERN_ERR "FAT: unable to read inode block "
+ "for updating (i_pos %lld)\n", i_pos);
+ unlock_kernel();
+ return -EIO;
+ }
+ spin_lock(&sbi->inode_hash_lock);
+ if (i_pos != MSDOS_I(inode)->i_pos) {
+ spin_unlock(&sbi->inode_hash_lock);
+ brelse(bh);
+ unlock_kernel();
+ goto retry;
+ }
+
+ raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
+ [i_pos & (sbi->dir_per_block - 1)];
+ if (S_ISDIR(inode->i_mode)) {
+ raw_entry->attr = ATTR_DIR;
+ raw_entry->size = 0;
+ }
+ else {
+ raw_entry->attr = ATTR_NONE;
+ raw_entry->size = cpu_to_le32(inode->i_size);
+ }
+ raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) |
+ MSDOS_I(inode)->i_attrs;
+ raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart);
+ raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
+ 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_ms = MSDOS_I(inode)->i_ctime_ms; /* use i_ctime.tv_nsec? */
+ }
+ spin_unlock(&sbi->inode_hash_lock);
+ mark_buffer_dirty(bh);
+ brelse(bh);
+ unlock_kernel();
+ return 0;
+}
+
+static int fat_show_options(struct seq_file *m, struct vfsmount *mnt);
+static struct super_operations fat_sops = {
+ .alloc_inode = fat_alloc_inode,
+ .destroy_inode = fat_destroy_inode,
+ .write_inode = fat_write_inode,
+ .delete_inode = fat_delete_inode,
+ .put_super = fat_put_super,
+ .statfs = fat_statfs,
+ .clear_inode = fat_clear_inode,
+ .remount_fs = fat_remount,
+
+ .read_inode = make_bad_inode,
+
+ .show_options = fat_show_options,
+};
+
+/*
+ * a FAT file handle with fhtype 3 is
+ * 0/ i_ino - for fast, reliable lookup if still in the cache
+ * 1/ i_generation - to see if i_ino is still valid
+ * bit 0 == 0 iff directory
+ * 2/ i_pos(8-39) - if ino has changed, but still in cache
+ * 3/ i_pos(4-7)|i_logstart - to semi-verify inode found at i_pos
+ * 4/ i_pos(0-3)|parent->i_logstart - maybe used to hunt for the file on disc
+ *
+ * Hack for NFSv2: Maximum FAT entry number is 28bits and maximum
+ * i_pos is 40bits (blocknr(32) + dir offset(8)), so two 4bits
+ * of i_logstart is used to store the directory entry offset.
+ */
+
+static struct dentry *
+fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype,
+ int (*acceptable)(void *context, struct dentry *de),
+ void *context)
+{
+ if (fhtype != 3)
+ return ERR_PTR(-ESTALE);
+ if (len < 5)
+ return ERR_PTR(-ESTALE);
+
+ return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
+}
+
+static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
+{
+ struct inode *inode = NULL;
+ struct dentry *result;
+ __u32 *fh = inump;
+
+ inode = iget(sb, fh[0]);
+ if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
+ if (inode)
+ iput(inode);
+ inode = NULL;
+ }
+ if (!inode) {
+ loff_t i_pos;
+ int i_logstart = fh[3] & 0x0fffffff;
+
+ i_pos = (loff_t)fh[2] << 8;
+ i_pos |= ((fh[3] >> 24) & 0xf0) | (fh[4] >> 28);
+
+ /* try 2 - see if i_pos is in F-d-c
+ * require i_logstart to be the same
+ * Will fail if you truncate and then re-write
+ */
+
+ inode = fat_iget(sb, i_pos);
+ if (inode && MSDOS_I(inode)->i_logstart != i_logstart) {
+ iput(inode);
+ inode = NULL;
+ }
+ }
+ if (!inode) {
+ /* For now, do nothing
+ * What we could do is:
+ * follow the file starting at fh[4], and record
+ * the ".." entry, and the name of the fh[2] entry.
+ * The follow the ".." file finding the next step up.
+ * This way we build a path to the root of
+ * the tree. If this works, we lookup the path and so
+ * get this inode into the cache.
+ * Finally try the fat_iget lookup again
+ * If that fails, then weare totally out of luck
+ * But all that is for another day
+ */
+ }
+ if (!inode)
+ return ERR_PTR(-ESTALE);
+
+
+ /* now to find a dentry.
+ * If possible, get a well-connected one
+ */
+ result = d_alloc_anon(inode);
+ if (result == NULL) {
+ iput(inode);
+ return ERR_PTR(-ENOMEM);
+ }
+ result->d_op = sb->s_root->d_op;
+ return result;
+}
+
+static int
+fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
+{
+ int len = *lenp;
+ struct inode *inode = de->d_inode;
+ u32 ipos_h, ipos_m, ipos_l;
+
+ if (len < 5)
+ return 255; /* no room */
+
+ ipos_h = MSDOS_I(inode)->i_pos >> 8;
+ ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24;
+ ipos_l = (MSDOS_I(inode)->i_pos & 0x0f) << 28;
+ *lenp = 5;
+ fh[0] = inode->i_ino;
+ fh[1] = inode->i_generation;
+ fh[2] = ipos_h;
+ fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;
+ spin_lock(&de->d_lock);
+ fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart;
+ spin_unlock(&de->d_lock);
+ return 3;
+}
+
+static struct dentry *fat_get_parent(struct dentry *child)
+{
+ struct buffer_head *bh=NULL;
+ struct msdos_dir_entry *de = NULL;
+ struct dentry *parent = NULL;
+ int res;
+ loff_t i_pos = 0;
+ struct inode *inode;
- if (!(sb->s_flags & MS_RDONLY))
- fat_clusters_flush(sb);
+ lock_kernel();
+ res = fat_scan(child->d_inode, MSDOS_DOTDOT, &bh, &de, &i_pos);
- if (sbi->nls_disk) {
- unload_nls(sbi->nls_disk);
- sbi->nls_disk = NULL;
- sbi->options.codepage = fat_default_codepage;
- }
- if (sbi->nls_io) {
- unload_nls(sbi->nls_io);
- sbi->nls_io = NULL;
- }
- if (sbi->options.iocharset != fat_default_iocharset) {
- kfree(sbi->options.iocharset);
- sbi->options.iocharset = fat_default_iocharset;
+ if (res < 0)
+ goto out;
+ inode = fat_build_inode(child->d_sb, de, i_pos, &res);
+ if (res)
+ goto out;
+ if (!inode)
+ res = -EACCES;
+ else {
+ parent = d_alloc_anon(inode);
+ if (!parent) {
+ iput(inode);
+ res = -ENOMEM;
+ }
}
- sb->s_fs_info = NULL;
- kfree(sbi);
+ out:
+ if(bh)
+ brelse(bh);
+ unlock_kernel();
+ if (res)
+ return ERR_PTR(res);
+ else
+ return parent;
}
+static struct export_operations fat_export_ops = {
+ .decode_fh = fat_decode_fh,
+ .encode_fh = fat_encode_fh,
+ .get_dentry = fat_get_dentry,
+ .get_parent = fat_get_parent,
+};
+
static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
{
struct msdos_sb_info *sbi = MSDOS_SB(mnt->mnt_sb);
@@ -516,23 +993,6 @@ static int parse_options(char *options,
if (opts->unicode_xlate)
opts->utf8 = 0;
-
- return 0;
-}
-
-static int fat_calc_dir_size(struct inode *inode)
-{
- struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
- int ret, fclus, dclus;
-
- inode->i_size = 0;
- if (MSDOS_I(inode)->i_start == 0)
- return 0;
-
- ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
- if (ret < 0)
- return ret;
- inode->i_size = (fclus + 1) << sbi->cluster_bits;
return 0;
}
@@ -560,245 +1020,21 @@ static int fat_read_root(struct inode *i
MSDOS_I(inode)->i_start = 0;
inode->i_size = sbi->dir_entries * sizeof(struct msdos_dir_entry);
}
- inode->i_blksize = sbi->cluster_size;
- inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
- & ~((loff_t)sbi->cluster_size - 1)) >> 9;
- MSDOS_I(inode)->i_logstart = 0;
- MSDOS_I(inode)->mmu_private = inode->i_size;
-
- MSDOS_I(inode)->i_attrs = 0;
- inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = 0;
- inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = 0;
- MSDOS_I(inode)->i_ctime_ms = 0;
- inode->i_nlink = fat_subdirs(inode)+2;
-
- return 0;
-}
-
-/*
- * a FAT file handle with fhtype 3 is
- * 0/ i_ino - for fast, reliable lookup if still in the cache
- * 1/ i_generation - to see if i_ino is still valid
- * bit 0 == 0 iff directory
- * 2/ i_pos(8-39) - if ino has changed, but still in cache
- * 3/ i_pos(4-7)|i_logstart - to semi-verify inode found at i_pos
- * 4/ i_pos(0-3)|parent->i_logstart - maybe used to hunt for the file on disc
- *
- * Hack for NFSv2: Maximum FAT entry number is 28bits and maximum
- * i_pos is 40bits (blocknr(32) + dir offset(8)), so two 4bits
- * of i_logstart is used to store the directory entry offset.
- */
-
-static struct dentry *
-fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype,
- int (*acceptable)(void *context, struct dentry *de),
- void *context)
-{
- if (fhtype != 3)
- return ERR_PTR(-ESTALE);
- if (len < 5)
- return ERR_PTR(-ESTALE);
-
- return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
-}
-
-static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
-{
- struct inode *inode = NULL;
- struct dentry *result;
- __u32 *fh = inump;
-
- inode = iget(sb, fh[0]);
- if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
- if (inode)
- iput(inode);
- inode = NULL;
- }
- if (!inode) {
- loff_t i_pos;
- int i_logstart = fh[3] & 0x0fffffff;
-
- i_pos = (loff_t)fh[2] << 8;
- i_pos |= ((fh[3] >> 24) & 0xf0) | (fh[4] >> 28);
-
- /* try 2 - see if i_pos is in F-d-c
- * require i_logstart to be the same
- * Will fail if you truncate and then re-write
- */
-
- inode = fat_iget(sb, i_pos);
- if (inode && MSDOS_I(inode)->i_logstart != i_logstart) {
- iput(inode);
- inode = NULL;
- }
- }
- if (!inode) {
- /* For now, do nothing
- * What we could do is:
- * follow the file starting at fh[4], and record
- * the ".." entry, and the name of the fh[2] entry.
- * The follow the ".." file finding the next step up.
- * This way we build a path to the root of
- * the tree. If this works, we lookup the path and so
- * get this inode into the cache.
- * Finally try the fat_iget lookup again
- * If that fails, then weare totally out of luck
- * But all that is for another day
- */
- }
- if (!inode)
- return ERR_PTR(-ESTALE);
-
-
- /* now to find a dentry.
- * If possible, get a well-connected one
- */
- result = d_alloc_anon(inode);
- if (result == NULL) {
- iput(inode);
- return ERR_PTR(-ENOMEM);
- }
- result->d_op = sb->s_root->d_op;
- return result;
-}
-
-static int
-fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
-{
- int len = *lenp;
- struct inode *inode = de->d_inode;
- u32 ipos_h, ipos_m, ipos_l;
-
- if (len < 5)
- return 255; /* no room */
-
- ipos_h = MSDOS_I(inode)->i_pos >> 8;
- ipos_m = (MSDOS_I(inode)->i_pos & 0xf0) << 24;
- ipos_l = (MSDOS_I(inode)->i_pos & 0x0f) << 28;
- *lenp = 5;
- fh[0] = inode->i_ino;
- fh[1] = inode->i_generation;
- fh[2] = ipos_h;
- fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;
- spin_lock(&de->d_lock);
- fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart;
- spin_unlock(&de->d_lock);
- return 3;
-}
-
-static struct dentry *fat_get_parent(struct dentry *child)
-{
- struct buffer_head *bh=NULL;
- struct msdos_dir_entry *de = NULL;
- struct dentry *parent = NULL;
- int res;
- loff_t i_pos = 0;
- struct inode *inode;
-
- lock_kernel();
- res = fat_scan(child->d_inode, MSDOS_DOTDOT, &bh, &de, &i_pos);
-
- if (res < 0)
- goto out;
- inode = fat_build_inode(child->d_sb, de, i_pos, &res);
- if (res)
- goto out;
- if (!inode)
- res = -EACCES;
- else {
- parent = d_alloc_anon(inode);
- if (!parent) {
- iput(inode);
- res = -ENOMEM;
- }
- }
-
- out:
- if(bh)
- brelse(bh);
- unlock_kernel();
- if (res)
- return ERR_PTR(res);
- else
- return parent;
-}
-
-static kmem_cache_t *fat_inode_cachep;
-
-static struct inode *fat_alloc_inode(struct super_block *sb)
-{
- struct msdos_inode_info *ei;
- ei = (struct msdos_inode_info *)kmem_cache_alloc(fat_inode_cachep, SLAB_KERNEL);
- if (!ei)
- return NULL;
- return &ei->vfs_inode;
-}
-
-static void fat_destroy_inode(struct inode *inode)
-{
- kmem_cache_free(fat_inode_cachep, MSDOS_I(inode));
-}
-
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
-{
- struct msdos_inode_info *ei = (struct msdos_inode_info *) foo;
-
- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
- SLAB_CTOR_CONSTRUCTOR) {
- spin_lock_init(&ei->cache_lru_lock);
- ei->nr_caches = 0;
- ei->cache_valid_id = FAT_CACHE_VALID + 1;
- INIT_LIST_HEAD(&ei->cache_lru);
- INIT_HLIST_NODE(&ei->i_fat_hash);
- inode_init_once(&ei->vfs_inode);
- }
-}
-
-int __init fat_init_inodecache(void)
-{
- fat_inode_cachep = kmem_cache_create("fat_inode_cache",
- sizeof(struct msdos_inode_info),
- 0, SLAB_RECLAIM_ACCOUNT,
- init_once, NULL);
- if (fat_inode_cachep == NULL)
- return -ENOMEM;
- return 0;
-}
+ inode->i_blksize = sbi->cluster_size;
+ inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
+ & ~((loff_t)sbi->cluster_size - 1)) >> 9;
+ MSDOS_I(inode)->i_logstart = 0;
+ MSDOS_I(inode)->mmu_private = inode->i_size;
-void __exit fat_destroy_inodecache(void)
-{
- if (kmem_cache_destroy(fat_inode_cachep))
- printk(KERN_INFO "fat_inode_cache: not all structures were freed\n");
-}
+ MSDOS_I(inode)->i_attrs = 0;
+ inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = 0;
+ inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = 0;
+ MSDOS_I(inode)->i_ctime_ms = 0;
+ inode->i_nlink = fat_subdirs(inode)+2;
-static int fat_remount(struct super_block *sb, int *flags, char *data)
-{
- *flags |= MS_NODIRATIME;
return 0;
}
-static struct super_operations fat_sops = {
- .alloc_inode = fat_alloc_inode,
- .destroy_inode = fat_destroy_inode,
- .write_inode = fat_write_inode,
- .delete_inode = fat_delete_inode,
- .put_super = fat_put_super,
- .statfs = fat_statfs,
- .clear_inode = fat_clear_inode,
- .remount_fs = fat_remount,
-
- .read_inode = make_bad_inode,
-
- .show_options = fat_show_options,
-};
-
-static struct export_operations fat_export_ops = {
- .decode_fh = fat_decode_fh,
- .encode_fh = fat_encode_fh,
- .get_dentry = fat_get_dentry,
- .get_parent = fat_get_parent,
-};
-
/*
* Read the super block of an MS-DOS FS.
*/
@@ -937,7 +1173,7 @@ int fat_fill_super(struct super_block *s
sbi->root_cluster = le32_to_cpu(b->root_cluster);
sb->s_maxbytes = 0xffffffff;
-
+
/* MC - if info_sector is 0, don't multiply by 0 */
sbi->fsinfo_sector = le16_to_cpu(b->info_sector);
if (sbi->fsinfo_sector == 0)
@@ -1079,259 +1315,6 @@ out_fail:
EXPORT_SYMBOL(fat_fill_super);
-static int fat_statfs(struct super_block *sb, struct kstatfs *buf)
-{
- int free, nr, ret;
-
- if (MSDOS_SB(sb)->free_clusters != -1)
- free = MSDOS_SB(sb)->free_clusters;
- else {
- lock_fat(sb);
- if (MSDOS_SB(sb)->free_clusters != -1)
- free = MSDOS_SB(sb)->free_clusters;
- else {
- free = 0;
- for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) {
- ret = fat_access(sb, nr, -1);
- if (ret < 0) {
- unlock_fat(sb);
- return ret;
- } else if (ret == FAT_ENT_FREE)
- free++;
- }
- MSDOS_SB(sb)->free_clusters = free;
- }
- unlock_fat(sb);
- }
-
- buf->f_type = sb->s_magic;
- buf->f_bsize = MSDOS_SB(sb)->cluster_size;
- buf->f_blocks = MSDOS_SB(sb)->clusters;
- buf->f_bfree = free;
- buf->f_bavail = free;
- buf->f_namelen = MSDOS_SB(sb)->options.isvfat ? 260 : 12;
-
- return 0;
-}
-
-static int is_exec(unsigned char *extension)
-{
- unsigned char *exe_extensions = "EXECOMBAT", *walk;
-
- for (walk = exe_extensions; *walk; walk += 3)
- if (!strncmp(extension, walk, 3))
- return 1;
- return 0;
-}
-
-static int fat_writepage(struct page *page, struct writeback_control *wbc)
-{
- return block_write_full_page(page,fat_get_block, wbc);
-}
-static int fat_readpage(struct file *file, struct page *page)
-{
- return block_read_full_page(page,fat_get_block);
-}
-
-static int
-fat_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
-{
- return cont_prepare_write(page,from,to,fat_get_block,
- &MSDOS_I(page->mapping->host)->mmu_private);
-}
-
-static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
-{
- return generic_block_bmap(mapping,block,fat_get_block);
-}
-
-static struct address_space_operations fat_aops = {
- .readpage = fat_readpage,
- .writepage = fat_writepage,
- .sync_page = block_sync_page,
- .prepare_write = fat_prepare_write,
- .commit_write = generic_commit_write,
- .bmap = _fat_bmap
-};
-
-/* doesn't deal with root inode */
-static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
-{
- struct super_block *sb = inode->i_sb;
- struct msdos_sb_info *sbi = MSDOS_SB(sb);
- int error;
-
- MSDOS_I(inode)->i_pos = 0;
- inode->i_uid = sbi->options.fs_uid;
- inode->i_gid = sbi->options.fs_gid;
- inode->i_version++;
- inode->i_generation = get_seconds();
-
- if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
- inode->i_generation &= ~1;
- inode->i_mode = MSDOS_MKMODE(de->attr,
- S_IRWXUGO & ~sbi->options.fs_dmask) | S_IFDIR;
- inode->i_op = sbi->dir_ops;
- inode->i_fop = &fat_dir_operations;
-
- MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
- if (sbi->fat_bits == 32)
- MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
-
- MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
- error = fat_calc_dir_size(inode);
- if (error < 0)
- return error;
- MSDOS_I(inode)->mmu_private = inode->i_size;
-
- inode->i_nlink = fat_subdirs(inode);
- } else { /* not a directory */
- inode->i_generation |= 1;
- inode->i_mode = MSDOS_MKMODE(de->attr,
- ((sbi->options.showexec &&
- !is_exec(de->ext))
- ? S_IRUGO|S_IWUGO : S_IRWXUGO)
- & ~sbi->options.fs_fmask) | S_IFREG;
- MSDOS_I(inode)->i_start = le16_to_cpu(de->start);
- if (sbi->fat_bits == 32)
- MSDOS_I(inode)->i_start |= (le16_to_cpu(de->starthi) << 16);
-
- 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;
- inode->i_fop = &fat_file_operations;
- inode->i_mapping->a_ops = &fat_aops;
- MSDOS_I(inode)->mmu_private = inode->i_size;
- }
- if(de->attr & ATTR_SYS)
- if (sbi->options.sys_immutable)
- inode->i_flags |= S_IMMUTABLE;
- MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
- /* this is as close to the truth as we can get ... */
- inode->i_blksize = sbi->cluster_size;
- inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
- & ~((loff_t)sbi->cluster_size - 1)) >> 9;
- inode->i_mtime.tv_sec = inode->i_atime.tv_sec =
- date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date));
- inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = 0;
- inode->i_ctime.tv_sec =
- MSDOS_SB(sb)->options.isvfat
- ? date_dos2unix(le16_to_cpu(de->ctime), le16_to_cpu(de->cdate))
- : inode->i_mtime.tv_sec;
- inode->i_ctime.tv_nsec = de->ctime_ms * 1000000;
- MSDOS_I(inode)->i_ctime_ms = de->ctime_ms;
-
- return 0;
-}
-
-static int fat_write_inode(struct inode *inode, int wait)
-{
- struct super_block *sb = inode->i_sb;
- struct msdos_sb_info *sbi = MSDOS_SB(sb);
- struct buffer_head *bh;
- struct msdos_dir_entry *raw_entry;
- loff_t i_pos;
-
-retry:
- i_pos = MSDOS_I(inode)->i_pos;
- if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) {
- return 0;
- }
- lock_kernel();
- if (!(bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits))) {
- printk(KERN_ERR "FAT: unable to read inode block "
- "for updating (i_pos %lld)\n", i_pos);
- unlock_kernel();
- return -EIO;
- }
- spin_lock(&sbi->inode_hash_lock);
- if (i_pos != MSDOS_I(inode)->i_pos) {
- spin_unlock(&sbi->inode_hash_lock);
- brelse(bh);
- unlock_kernel();
- goto retry;
- }
-
- raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
- [i_pos & (sbi->dir_per_block - 1)];
- if (S_ISDIR(inode->i_mode)) {
- raw_entry->attr = ATTR_DIR;
- raw_entry->size = 0;
- }
- else {
- raw_entry->attr = ATTR_NONE;
- raw_entry->size = cpu_to_le32(inode->i_size);
- }
- raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) |
- MSDOS_I(inode)->i_attrs;
- raw_entry->start = cpu_to_le16(MSDOS_I(inode)->i_logstart);
- raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
- 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_ms = MSDOS_I(inode)->i_ctime_ms; /* use i_ctime.tv_nsec? */
- }
- spin_unlock(&sbi->inode_hash_lock);
- mark_buffer_dirty(bh);
- brelse(bh);
- unlock_kernel();
- return 0;
-}
-
-
-int fat_notify_change(struct dentry * dentry, struct iattr * attr)
-{
- struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
- struct inode *inode = dentry->d_inode;
- int mask, error = 0;
-
- lock_kernel();
-
- /* FAT cannot truncate to a longer file */
- if (attr->ia_valid & ATTR_SIZE) {
- if (attr->ia_size > inode->i_size) {
- error = -EPERM;
- goto out;
- }
- }
-
- error = inode_change_ok(inode, attr);
- if (error) {
- if (sbi->options.quiet)
- error = 0;
- goto out;
- }
-
- if (((attr->ia_valid & ATTR_UID) &&
- (attr->ia_uid != sbi->options.fs_uid)) ||
- ((attr->ia_valid & ATTR_GID) &&
- (attr->ia_gid != sbi->options.fs_gid)) ||
- ((attr->ia_valid & ATTR_MODE) &&
- (attr->ia_mode & ~MSDOS_VALID_MODE)))
- error = -EPERM;
-
- if (error) {
- if (sbi->options.quiet)
- error = 0;
- goto out;
- }
- error = inode_setattr(inode, attr);
- if (error)
- goto out;
-
- if (S_ISDIR(inode->i_mode))
- mask = sbi->options.fs_dmask;
- else
- mask = sbi->options.fs_fmask;
- inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask);
-out:
- unlock_kernel();
- return error;
-}
-
-EXPORT_SYMBOL(fat_notify_change);
-
int __init fat_cache_init(void);
void __exit fat_cache_destroy(void);
diff -puN fs/fat/misc.c~fat_cleanup fs/fat/misc.c
--- linux-2.6.10/fs/fat/misc.c~fat_cleanup 2005-01-10 01:57:57.000000000 +0900
+++ linux-2.6.10-hirofumi/fs/fat/misc.c 2005-01-10 05:07:47.000000000 +0900
@@ -88,8 +88,8 @@ int fat_add_cluster(struct inode *inode)
struct super_block *sb = inode->i_sb;
int ret, count, limit, new_dclus, new_fclus, last;
int cluster_bits = MSDOS_SB(sb)->cluster_bits;
-
- /*
+
+ /*
* We must locate the last cluster of the file to add this new
* one (new_dclus) to the end of the link list (the FAT).
*
@@ -109,7 +109,7 @@ int fat_add_cluster(struct inode *inode)
/* find free FAT entry */
lock_fat(sb);
-
+
if (MSDOS_SB(sb)->free_clusters == 0) {
unlock_fat(sb);
return -ENOSPC;
@@ -145,7 +145,7 @@ int fat_add_cluster(struct inode *inode)
if (MSDOS_SB(sb)->free_clusters != -1)
MSDOS_SB(sb)->free_clusters--;
fat_clusters_flush(sb);
-
+
unlock_fat(sb);
/* add new one to the last of the cluster chain */
@@ -169,65 +169,23 @@ int fat_add_cluster(struct inode *inode)
return new_dclus;
}
-struct buffer_head *fat_extend_dir(struct inode *inode)
-{
- struct super_block *sb = inode->i_sb;
- struct buffer_head *bh, *res = NULL;
- int nr, sec_per_clus = MSDOS_SB(sb)->sec_per_clus;
- sector_t sector, last_sector;
-
- if (MSDOS_SB(sb)->fat_bits != 32) {
- if (inode->i_ino == MSDOS_ROOT_INO)
- return ERR_PTR(-ENOSPC);
- }
-
- nr = fat_add_cluster(inode);
- if (nr < 0)
- return ERR_PTR(nr);
-
- sector = ((sector_t)nr - 2) * sec_per_clus + MSDOS_SB(sb)->data_start;
- last_sector = sector + sec_per_clus;
- for ( ; sector < last_sector; sector++) {
- if ((bh = sb_getblk(sb, sector))) {
- memset(bh->b_data, 0, sb->s_blocksize);
- set_buffer_uptodate(bh);
- mark_buffer_dirty(bh);
- if (!res)
- res = bh;
- else
- brelse(bh);
- }
- }
- if (res == NULL)
- res = ERR_PTR(-EIO);
- if (inode->i_size & (sb->s_blocksize - 1)) {
- fat_fs_panic(sb, "Odd directory size");
- inode->i_size = (inode->i_size + sb->s_blocksize)
- & ~((loff_t)sb->s_blocksize - 1);
- }
- inode->i_size += MSDOS_SB(sb)->cluster_size;
- MSDOS_I(inode)->mmu_private += MSDOS_SB(sb)->cluster_size;
-
- return res;
-}
-
-/* Linear day numbers of the respective 1sts in non-leap years. */
-
-static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
- /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
-
-
extern struct timezone sys_tz;
+/* Linear day numbers of the respective 1sts in non-leap years. */
+static int day_n[] = {
+ /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0
+};
/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
-
-int date_dos2unix(unsigned short time,unsigned short date)
+int date_dos2unix(unsigned short time, unsigned short date)
{
- int month,year,secs;
+ int month, year, secs;
- /* first subtract and mask after that... Otherwise, if
- date == 0, bad things happen */
+ /*
+ * first subtract and mask after that... Otherwise, if
+ * date == 0, bad things happen
+ */
month = ((date >> 5) - 1) & 15;
year = date >> 9;
secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
@@ -238,12 +196,10 @@ int date_dos2unix(unsigned short time,un
return secs;
}
-
/* Convert linear UNIX date to a MS-DOS time/date pair. */
-
-void fat_date_unix2dos(int unix_date,__le16 *time, __le16 *date)
+void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date)
{
- int day,year,nl_day,month;
+ int day, year, nl_day, month;
unix_date -= sys_tz.tz_minuteswest*60;
@@ -255,16 +211,18 @@ void fat_date_unix2dos(int unix_date,__l
(((unix_date/3600) % 24) << 11));
day = unix_date/86400-3652;
year = day/365;
- if ((year+3)/4+365*year > day) year--;
+ if ((year+3)/4+365*year > day)
+ year--;
day -= (year+3)/4+365*year;
if (day == 59 && !(year & 3)) {
nl_day = day;
month = 2;
- }
- else {
+ } else {
nl_day = (year & 3) || day <= 59 ? day : day-1;
- for (month = 0; month < 12; month++)
- if (day_n[month] > nl_day) break;
+ for (month = 0; month < 12; month++) {
+ if (day_n[month] > nl_day)
+ break;
+ }
}
*date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9));
}
@@ -279,10 +237,10 @@ EXPORT_SYMBOL(fat_date_unix2dos);
AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
AV. It's done in fat_get_entry() (inlined), here the slow case lives.
AV. Additionally, when we return -1 (i.e. reached the end of directory)
- AV. we make bh NULL.
+ AV. we make bh NULL.
*/
-int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
+int fat__get_entry(struct inode *dir, loff_t *pos, struct buffer_head **bh,
struct msdos_dir_entry **de, loff_t *i_pos)
{
struct super_block *sb = dir->i_sb;
diff -puN include/linux/msdos_fs.h~fat_cleanup include/linux/msdos_fs.h
--- linux-2.6.10/include/linux/msdos_fs.h~fat_cleanup 2005-01-10 01:57:57.000000000 +0900
+++ linux-2.6.10-hirofumi/include/linux/msdos_fs.h 2005-01-10 05:10:38.000000000 +0900
@@ -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,37 +27,37 @@
#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)
@@ -61,24 +65,24 @@
MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
/* 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)
@@ -96,7 +100,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 +109,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 +153,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 +171,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__
@@ -259,11 +251,11 @@ struct msdos_inode_info {
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 */
+ 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;
};
@@ -305,20 +297,20 @@ static inline void fatwchar_to16(__u8 *d
}
/* fat/cache.c */
-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_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_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);
@@ -329,8 +321,7 @@ extern int fat_scan(struct inode *dir, c
/* 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 */
@@ -341,7 +332,6 @@ extern struct inode *fat_build_inode(str
struct msdos_dir_entry *de, loff_t i_pos, int *res);
int fat_fill_super(struct super_block *sb, void *data, int silent,
struct inode_operations *fs_dir_inode_ops, int isvfat);
-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, ...);
@@ -349,7 +339,6 @@ extern void lock_fat(struct super_block
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,
_
Default config may be setted by distributer. By this change, certainly
the user can know current NLS using by FAT.
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/fat/inode.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff -puN fs/fat/inode.c~fat_show-default fs/fat/inode.c
--- linux-2.6.11-rc1/fs/fat/inode.c~fat_show-default 2005-01-13 03:53:45.000000000 +0900
+++ linux-2.6.11-rc1-hirofumi/fs/fat/inode.c 2005-01-13 03:53:45.000000000 +0900
@@ -690,11 +690,10 @@ static int fat_show_options(struct seq_f
seq_printf(m, ",gid=%u", opts->fs_gid);
seq_printf(m, ",fmask=%04o", opts->fs_fmask);
seq_printf(m, ",dmask=%04o", opts->fs_dmask);
- if (sbi->nls_disk && opts->codepage != fat_default_codepage)
+ if (sbi->nls_disk)
seq_printf(m, ",codepage=%s", sbi->nls_disk->charset);
if (isvfat) {
- if (sbi->nls_io &&
- strcmp(opts->iocharset, fat_default_iocharset))
+ if (sbi->nls_io)
seq_printf(m, ",iocharset=%s", sbi->nls_io->charset);
switch (opts->shortname) {
_
- Replaces the "number of reserved clusters" by FAT_START_ENT.
- The ->clusters is total number of clusters. Instead of it, use the
maximum cluster number (->max_cluster).
By this change, removes the some "->clusters + 2" calculation.
- Adds inline function for cluster to block number conversion. And
replaces the open-coding for it.
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/fat/cache.c | 8 +++-----
fs/fat/dir.c | 2 +-
fs/fat/inode.c | 25 +++++++++++++------------
fs/fat/misc.c | 27 ++++++++++++++-------------
include/linux/msdos_fs.h | 11 ++++++++++-
5 files changed, 41 insertions(+), 32 deletions(-)
diff -puN fs/fat/cache.c~fat_max-clusters-cleanup fs/fat/cache.c
--- linux-2.6.11-rc1/fs/fat/cache.c~fat_max-clusters-cleanup 2005-01-15 16:49:08.000000000 +0900
+++ linux-2.6.11-rc1-hirofumi/fs/fat/cache.c 2005-01-15 16:49:08.000000000 +0900
@@ -305,7 +305,7 @@ int fat_access(struct super_block *sb, i
int next;
next = -EIO;
- if (nr < 2 || MSDOS_SB(sb)->clusters + 2 <= nr) {
+ if (nr < FAT_START_ENT || MSDOS_SB(sb)->max_cluster <= nr) {
fat_fs_panic(sb, "invalid access to FAT (entry 0x%08x)", nr);
goto out;
}
@@ -431,9 +431,7 @@ int fat_bmap(struct inode *inode, sector
cluster = fat_bmap_cluster(inode, cluster);
if (cluster < 0)
return cluster;
- else if (cluster) {
- *phys = ((sector_t)cluster - 2) * sbi->sec_per_clus
- + sbi->data_start + offset;
- }
+ else if (cluster)
+ *phys = fat_clus_to_blknr(sbi, cluster) + offset;
return 0;
}
diff -puN fs/fat/dir.c~fat_max-clusters-cleanup fs/fat/dir.c
--- linux-2.6.11-rc1/fs/fat/dir.c~fat_max-clusters-cleanup 2005-01-15 16:49:08.000000000 +0900
+++ linux-2.6.11-rc1-hirofumi/fs/fat/dir.c 2005-01-15 16:49:08.000000000 +0900
@@ -767,7 +767,7 @@ static struct buffer_head *fat_extend_di
if (nr < 0)
return ERR_PTR(nr);
- sector = ((sector_t)nr - 2) * sec_per_clus + MSDOS_SB(sb)->data_start;
+ sector = fat_clus_to_blknr(MSDOS_SB(sb), nr);
last_sector = sector + sec_per_clus;
for ( ; sector < last_sector; sector++) {
if ((bh = sb_getblk(sb, sector))) {
diff -puN fs/fat/inode.c~fat_max-clusters-cleanup fs/fat/inode.c
--- linux-2.6.11-rc1/fs/fat/inode.c~fat_max-clusters-cleanup 2005-01-15 16:49:08.000000000 +0900
+++ linux-2.6.11-rc1-hirofumi/fs/fat/inode.c 2005-01-15 16:49:08.000000000 +0900
@@ -419,17 +419,18 @@ static int fat_remount(struct super_bloc
static int fat_statfs(struct super_block *sb, struct kstatfs *buf)
{
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
int free, nr, ret;
- if (MSDOS_SB(sb)->free_clusters != -1)
- free = MSDOS_SB(sb)->free_clusters;
+ if (sbi->free_clusters != -1)
+ free = sbi->free_clusters;
else {
lock_fat(sb);
- if (MSDOS_SB(sb)->free_clusters != -1)
- free = MSDOS_SB(sb)->free_clusters;
+ if (sbi->free_clusters != -1)
+ free = sbi->free_clusters;
else {
free = 0;
- for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) {
+ for (nr = FAT_START_ENT; nr < sbi->max_cluster; nr++) {
ret = fat_access(sb, nr, -1);
if (ret < 0) {
unlock_fat(sb);
@@ -437,17 +438,17 @@ static int fat_statfs(struct super_block
} else if (ret == FAT_ENT_FREE)
free++;
}
- MSDOS_SB(sb)->free_clusters = free;
+ sbi->free_clusters = free;
}
unlock_fat(sb);
}
buf->f_type = sb->s_magic;
- buf->f_bsize = MSDOS_SB(sb)->cluster_size;
- buf->f_blocks = MSDOS_SB(sb)->clusters;
+ buf->f_bsize = sbi->cluster_size;
+ buf->f_blocks = sbi->max_cluster - FAT_START_ENT;
buf->f_bfree = free;
buf->f_bavail = free;
- buf->f_namelen = MSDOS_SB(sb)->options.isvfat ? 260 : 12;
+ buf->f_namelen = sbi->options.isvfat ? 260 : 12;
return 0;
}
@@ -1232,7 +1233,7 @@ int fat_fill_super(struct super_block *s
/* check that FAT table does not overflow */
fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
- total_clusters = min(total_clusters, fat_clusters - 2);
+ total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
if (total_clusters > MAX_FAT(sb)) {
if (!silent)
printk(KERN_ERR "FAT: count of clusters too big (%u)\n",
@@ -1241,9 +1242,9 @@ int fat_fill_super(struct super_block *s
goto out_invalid;
}
- sbi->clusters = total_clusters;
+ sbi->max_cluster = total_clusters + FAT_START_ENT;
/* check the free_clusters, it's not necessarily correct */
- if (sbi->free_clusters != -1 && sbi->free_clusters > sbi->clusters)
+ if (sbi->free_clusters != -1 && sbi->free_clusters > total_clusters)
sbi->free_clusters = -1;
brelse(bh);
diff -puN fs/fat/misc.c~fat_max-clusters-cleanup fs/fat/misc.c
--- linux-2.6.11-rc1/fs/fat/misc.c~fat_max-clusters-cleanup 2005-01-15 16:49:08.000000000 +0900
+++ linux-2.6.11-rc1-hirofumi/fs/fat/misc.c 2005-01-15 16:49:08.000000000 +0900
@@ -86,8 +86,9 @@ void fat_clusters_flush(struct super_blo
int fat_add_cluster(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
int ret, count, limit, new_dclus, new_fclus, last;
- int cluster_bits = MSDOS_SB(sb)->cluster_bits;
+ int cluster_bits = sbi->cluster_bits;
/*
* We must locate the last cluster of the file to add this new
@@ -110,17 +111,17 @@ int fat_add_cluster(struct inode *inode)
/* find free FAT entry */
lock_fat(sb);
- if (MSDOS_SB(sb)->free_clusters == 0) {
+ if (sbi->free_clusters == 0) {
unlock_fat(sb);
return -ENOSPC;
}
- limit = MSDOS_SB(sb)->clusters + 2;
- new_dclus = MSDOS_SB(sb)->prev_free + 1;
- for (count = 0; count < MSDOS_SB(sb)->clusters; count++, new_dclus++) {
+ limit = sbi->max_cluster;
+ new_dclus = sbi->prev_free + 1;
+ for (count = FAT_START_ENT; count < limit; count++, new_dclus++) {
new_dclus = new_dclus % limit;
- if (new_dclus < 2)
- new_dclus = 2;
+ if (new_dclus < FAT_START_ENT)
+ new_dclus = FAT_START_ENT;
ret = fat_access(sb, new_dclus, -1);
if (ret < 0) {
@@ -129,8 +130,8 @@ int fat_add_cluster(struct inode *inode)
} else if (ret == FAT_ENT_FREE)
break;
}
- if (count >= MSDOS_SB(sb)->clusters) {
- MSDOS_SB(sb)->free_clusters = 0;
+ if (count >= limit) {
+ sbi->free_clusters = 0;
unlock_fat(sb);
return -ENOSPC;
}
@@ -141,9 +142,9 @@ int fat_add_cluster(struct inode *inode)
return ret;
}
- MSDOS_SB(sb)->prev_free = new_dclus;
- if (MSDOS_SB(sb)->free_clusters != -1)
- MSDOS_SB(sb)->free_clusters--;
+ sbi->prev_free = new_dclus;
+ if (sbi->free_clusters != -1)
+ sbi->free_clusters--;
fat_clusters_flush(sb);
unlock_fat(sb);
@@ -164,7 +165,7 @@ int fat_add_cluster(struct inode *inode)
new_fclus, inode->i_blocks >> (cluster_bits - 9));
fat_cache_inval_inode(inode);
}
- inode->i_blocks += MSDOS_SB(sb)->cluster_size >> 9;
+ inode->i_blocks += sbi->cluster_size >> 9;
return new_dclus;
}
diff -puN include/linux/msdos_fs.h~fat_max-clusters-cleanup include/linux/msdos_fs.h
--- linux-2.6.11-rc1/include/linux/msdos_fs.h~fat_max-clusters-cleanup 2005-01-15 16:49:08.000000000 +0900
+++ linux-2.6.11-rc1-hirofumi/include/linux/msdos_fs.h 2005-01-15 16:49:08.000000000 +0900
@@ -64,6 +64,9 @@
#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
@@ -221,7 +224,7 @@ struct msdos_sb_info {
unsigned long dir_start;
unsigned short dir_entries; /* root dir start & entries */
unsigned long data_start; /* first data sector */
- unsigned long clusters; /* number of clusters */
+ 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;
@@ -270,6 +273,12 @@ static inline struct msdos_inode_info *M
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
_
On Tue, Jan 18, 2005 at 02:41:05AM +0900, OGAWA Hirofumi wrote:
> +static inline wchar_t vfat_bad_char(wchar_t w)
> +{
> + return (w < 0x0020)
> + || (w == 0x002A) /* * */ || (w == 0x003F) /* ? */
> + || (w == 0x003C) /* < */ || (w == 0x003E) /* > */
> + || (w == 0x007C) /* | */ || (w == 0x0022) /* " */
> + || (w == 0x003A) /* : */ || (w == 0x002F) /* / */
> + || (w == 0x005C);/* \ */
> +}
Ugh... What's wrong with comparison to '*', '<', etc.? All values are
below 0x80, so signedness of char doesn't matter and when they get
promoted to int, they will give you the values you want...
> +static inline wchar_t vfat_replace_char(wchar_t w)
> +{
> + return (w == 0x005B) /* [ */ || (w == 0x005D) /* ] */
> + || (w == 0x003B) /* ; */ || (w == 0x002C) /* , */
> + || (w == 0x002B) /* + */ || (w == 0x003D);/* = */
> +}
Ditto.
On Tue, Jan 18, 2005 at 02:49:21AM +0900, OGAWA Hirofumi wrote:
> diff -puN fs/vfat/namei.c~fat_lindent-vfat fs/vfat/namei.c
> --- linux-2.6.10/fs/vfat/namei.c~fat_lindent-vfat 2005-01-10 01:57:31.000000000 +0900
> +++ linux-2.6.10-hirofumi/fs/vfat/namei.c 2005-01-10 01:57:44.000000000 +0900
> @@ -12,7 +12,7 @@
> * Short name translation 1999, 2001 by Wolfram Pienkoss <[email protected]>
> *
> * Support Multibyte character and cleanup by
^^^ Shouldn't that be 'characters'?
Yup, that was it.. sorry if I'm nitpicking :-P
Sytse
Al Viro <[email protected]> writes:
> Ugh... What's wrong with comparison to '*', '<', etc.? All values are
> below 0x80, so signedness of char doesn't matter and when they get
> promoted to int, they will give you the values you want...
Indeed. Thanks.
Please apply the following incremental patch.
--
OGAWA Hirofumi <[email protected]>
[PATCH 14] FAT: Further IS_BADCHAR/IS_REPLACECHR/IS_SKIPCHAR cleanup
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/vfat/namei.c | 15 ++++++---------
1 files changed, 6 insertions(+), 9 deletions(-)
diff -puN fs/vfat/namei.c~fat_check-chars-cleanup2 fs/vfat/namei.c
--- linux-2.6.11-rc1/fs/vfat/namei.c~fat_check-chars-cleanup2 2005-01-18 09:50:45.000000000 +0900
+++ linux-2.6.11-rc1-hirofumi/fs/vfat/namei.c 2005-01-18 09:56:08.000000000 +0900
@@ -153,23 +153,20 @@ static struct dentry_operations vfat_den
static inline wchar_t vfat_bad_char(wchar_t w)
{
return (w < 0x0020)
- || (w == 0x002A) /* * */ || (w == 0x003F) /* ? */
- || (w == 0x003C) /* < */ || (w == 0x003E) /* > */
- || (w == 0x007C) /* | */ || (w == 0x0022) /* " */
- || (w == 0x003A) /* : */ || (w == 0x002F) /* / */
- || (w == 0x005C);/* \ */
+ || (w == '*') || (w == '?') || (w == '<') || (w == '>')
+ || (w == '|') || (w == '"') || (w == ':') || (w == '/')
+ || (w == '\\');
}
static inline wchar_t vfat_replace_char(wchar_t w)
{
- return (w == 0x005B) /* [ */ || (w == 0x005D) /* ] */
- || (w == 0x003B) /* ; */ || (w == 0x002C) /* , */
- || (w == 0x002B) /* + */ || (w == 0x003D);/* = */
+ return (w == '[') || (w == ']') || (w == ';') || (w == ',')
+ || (w == '+') || (w == '=');
}
static wchar_t vfat_skip_char(wchar_t w)
{
- return (w == 0x002E) /* . */ || (w == 0x0020);/* <space> */
+ return (w == '.') || (w == ' ');
}
static inline int vfat_is_used_badchars(const wchar_t *s, int len)
_
Sytse Wielinga <[email protected]> writes:
>> * Support Multibyte character and cleanup by
> ^^^ Shouldn't that be 'characters'?
Thanks.
Please apply the following incremental patch.
--
OGAWA Hirofumi <[email protected]>
[PATCH 15] FAT: Fix typo in comment
Signed-off-by: OGAWA Hirofumi <[email protected]>
---
fs/vfat/namei.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -puN fs/vfat/namei.c~fat_fix-typo fs/vfat/namei.c
--- linux-2.6.11-rc1/fs/vfat/namei.c~fat_fix-typo 2005-01-18 09:57:16.000000000 +0900
+++ linux-2.6.11-rc1-hirofumi/fs/vfat/namei.c 2005-01-18 09:57:16.000000000 +0900
@@ -11,7 +11,7 @@
*
* Short name translation 1999, 2001 by Wolfram Pienkoss <[email protected]>
*
- * Support Multibyte character and cleanup by
+ * Support Multibyte characters and cleanup by
* OGAWA Hirofumi <[email protected]>
*/
_
On Jan 18 2005, OGAWA Hirofumi wrote:
> static int vfat_valid_longname(const unsigned char *name, unsigned int len)
> {
> - if (len && name[len-1] == ' ')
> - return 0;
> + if (name[len - 1] == ' ')
> + return -EINVAL;
Sorry for the stupid question, but is len guaranteed to be always greater
than zero?
Otherwise, I think that the test with len would be warranted. And, if that
is the case, wouldn't it be better to have it explicitly say if (len > 0...)?
Just curious. And sorry again for the stupid question. But as Knuth says,
"premature optimization is the root of all evil".
Perhaps I'm way too much into proving invariants of algorithms. :-)
Thanks for your work, Rog?rio.
--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Rog?rio Brito - [email protected] - http://www.ime.usp.br/~rbrito
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Rog?rio Brito <[email protected]> writes:
> On Jan 18 2005, OGAWA Hirofumi wrote:
>> static int vfat_valid_longname(const unsigned char *name, unsigned int len)
>> {
>> - if (len && name[len-1] == ' ')
>> - return 0;
>> + if (name[len - 1] == ' ')
>> + return -EINVAL;
>
> Sorry for the stupid question, but is len guaranteed to be always greater
> than zero?
Yes. That "len" was already checked in vfat_add_entry().
Thanks.
--
OGAWA Hirofumi <[email protected]>
On Jan 18 2005, OGAWA Hirofumi wrote:
> Rog?rio Brito <[email protected]> writes:
> > Sorry for the stupid question, but is len guaranteed to be always greater
> > than zero?
>
> Yes. That "len" was already checked in vfat_add_entry().
Sorry for the stupid question then.
Thanks.
--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Rog?rio Brito - [email protected] - http://www.ime.usp.br/~rbrito
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=