git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ARM: 6051/1: VFP: preserve the HW context when calling signal handlers
[safe/jmp/linux-2.6]
/
fs
/
fat
/
inode.c
diff --git
a/fs/fat/inode.c
b/fs/fat/inode.c
index
6b74d09
..
0ce143b
100644
(file)
--- a/
fs/fat/inode.c
+++ b/
fs/fat/inode.c
@@
-76,7
+76,7
@@
static inline int __fat_get_block(struct inode *inode, sector_t iblock,
return 0;
if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
return 0;
if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
- fat_fs_
panic
(sb, "corrupted file size (i_pos %lld, %lld)",
+ fat_fs_
error
(sb, "corrupted file size (i_pos %lld, %lld)",
MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
return -EIO;
}
MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
return -EIO;
}
@@
-202,9
+202,9
@@
static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
sector_t blocknr;
/* fat_get_cluster() assumes the requested blocknr isn't truncated. */
sector_t blocknr;
/* fat_get_cluster() assumes the requested blocknr isn't truncated. */
-
mutex_lock(&mapping->host->i_mutex
);
+
down_read(&mapping->host->i_alloc_sem
);
blocknr = generic_block_bmap(mapping, block, fat_get_block);
blocknr = generic_block_bmap(mapping, block, fat_get_block);
-
mutex_unlock(&mapping->host->i_mutex
);
+
up_read(&mapping->host->i_alloc_sem
);
return blocknr;
}
return blocknr;
}
@@
-441,32
+441,49
@@
static void fat_clear_inode(struct inode *inode)
static void fat_write_super(struct super_block *sb)
{
static void fat_write_super(struct super_block *sb)
{
+ lock_super(sb);
sb->s_dirt = 0;
if (!(sb->s_flags & MS_RDONLY))
fat_clusters_flush(sb);
sb->s_dirt = 0;
if (!(sb->s_flags & MS_RDONLY))
fat_clusters_flush(sb);
+ unlock_super(sb);
+}
+
+static int fat_sync_fs(struct super_block *sb, int wait)
+{
+ int err = 0;
+
+ if (sb->s_dirt) {
+ lock_super(sb);
+ sb->s_dirt = 0;
+ err = fat_clusters_flush(sb);
+ unlock_super(sb);
+ }
+
+ return err;
}
static void fat_put_super(struct super_block *sb)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
}
static void fat_put_super(struct super_block *sb)
{
struct msdos_sb_info *sbi = MSDOS_SB(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) {
+ lock_kernel();
+
+ if (sb->s_dirt)
+ fat_write_super(sb);
+
+ iput(sbi->fat_inode);
+
+ unload_nls(sbi->nls_disk);
+ unload_nls(sbi->nls_io);
+
+ if (sbi->options.iocharset != fat_default_iocharset)
kfree(sbi->options.iocharset);
kfree(sbi->options.iocharset);
- sbi->options.iocharset = fat_default_iocharset;
- }
sb->s_fs_info = NULL;
kfree(sbi);
sb->s_fs_info = NULL;
kfree(sbi);
+
+ unlock_kernel();
}
static struct kmem_cache *fat_inode_cachep;
}
static struct kmem_cache *fat_inode_cachep;
@@
-523,7
+540,9
@@
static int fat_remount(struct super_block *sb, int *flags, char *data)
static int fat_statfs(struct dentry *dentry, struct kstatfs *buf)
{
static int fat_statfs(struct dentry *dentry, struct kstatfs *buf)
{
- struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
+ struct super_block *sb = dentry->d_sb;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
/* If the count of free cluster is still unknown, counts it here. */
if (sbi->free_clusters == -1 || !sbi->free_clus_valid) {
/* If the count of free cluster is still unknown, counts it here. */
if (sbi->free_clusters == -1 || !sbi->free_clus_valid) {
@@
-537,7
+556,9
@@
static int fat_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_blocks = sbi->max_cluster - FAT_START_ENT;
buf->f_bfree = sbi->free_clusters;
buf->f_bavail = sbi->free_clusters;
buf->f_blocks = sbi->max_cluster - FAT_START_ENT;
buf->f_bfree = sbi->free_clusters;
buf->f_bavail = sbi->free_clusters;
- buf->f_namelen = sbi->options.isvfat ? 260 : 12;
+ buf->f_fsid.val[0] = (u32)id;
+ buf->f_fsid.val[1] = (u32)(id >> 32);
+ buf->f_namelen = sbi->options.isvfat ? FAT_LFN_LEN : 12;
return 0;
}
return 0;
}
@@
-556,7
+577,7
@@
static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi,
return i_pos;
}
return i_pos;
}
-static int fat_write_inode(struct inode *inode, int wait)
+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 super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@
-613,9
+634,14
@@
retry:
return err;
}
return err;
}
+static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ return __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
+}
+
int fat_sync_inode(struct inode *inode)
{
int fat_sync_inode(struct inode *inode)
{
- return fat_write_inode(inode, 1);
+ return
__
fat_write_inode(inode, 1);
}
EXPORT_SYMBOL_GPL(fat_sync_inode);
}
EXPORT_SYMBOL_GPL(fat_sync_inode);
@@
-628,6
+654,7
@@
static const struct super_operations fat_sops = {
.delete_inode = fat_delete_inode,
.put_super = fat_put_super,
.write_super = fat_write_super,
.delete_inode = fat_delete_inode,
.put_super = fat_put_super,
.write_super = fat_write_super,
+ .sync_fs = fat_sync_fs,
.statfs = fat_statfs,
.clear_inode = fat_clear_inode,
.remount_fs = fat_remount,
.statfs = fat_statfs,
.clear_inode = fat_clear_inode,
.remount_fs = fat_remount,
@@
-794,7
+821,7
@@
static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
seq_puts(m, ",shortname=mixed");
break;
case VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95:
seq_puts(m, ",shortname=mixed");
break;
case VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95:
- /* seq_puts(m, ",shortname=lower"); */
+ seq_puts(m, ",shortname=lower");
break;
default:
seq_puts(m, ",shortname=unknown");
break;
default:
seq_puts(m, ",shortname=unknown");
@@
-830,6
+857,14
@@
static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
seq_puts(m, ",flush");
if (opts->tz_utc)
seq_puts(m, ",tz=UTC");
seq_puts(m, ",flush");
if (opts->tz_utc)
seq_puts(m, ",tz=UTC");
+ if (opts->errors == FAT_ERRORS_CONT)
+ seq_puts(m, ",errors=continue");
+ else if (opts->errors == FAT_ERRORS_PANIC)
+ seq_puts(m, ",errors=panic");
+ else
+ seq_puts(m, ",errors=remount-ro");
+ if (opts->discard)
+ seq_puts(m, ",discard");
return 0;
}
return 0;
}
@@
-842,7
+877,8
@@
enum {
Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
- Opt_obsolate, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err,
+ Opt_obsolate, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont,
+ Opt_err_panic, Opt_err_ro, Opt_discard, Opt_err,
};
static const match_table_t fat_tokens = {
};
static const match_table_t fat_tokens = {
@@
-865,6
+901,12
@@
static const match_table_t fat_tokens = {
{Opt_showexec, "showexec"},
{Opt_debug, "debug"},
{Opt_immutable, "sys_immutable"},
{Opt_showexec, "showexec"},
{Opt_debug, "debug"},
{Opt_immutable, "sys_immutable"},
+ {Opt_flush, "flush"},
+ {Opt_tz_utc, "tz=UTC"},
+ {Opt_err_cont, "errors=continue"},
+ {Opt_err_panic, "errors=panic"},
+ {Opt_err_ro, "errors=remount-ro"},
+ {Opt_discard, "discard"},
{Opt_obsolate, "conv=binary"},
{Opt_obsolate, "conv=text"},
{Opt_obsolate, "conv=auto"},
{Opt_obsolate, "conv=binary"},
{Opt_obsolate, "conv=text"},
{Opt_obsolate, "conv=auto"},
@@
-876,8
+918,6
@@
static const match_table_t fat_tokens = {
{Opt_obsolate, "cvf_format=%20s"},
{Opt_obsolate, "cvf_options=%100s"},
{Opt_obsolate, "posix"},
{Opt_obsolate, "cvf_format=%20s"},
{Opt_obsolate, "cvf_options=%100s"},
{Opt_obsolate, "posix"},
- {Opt_flush, "flush"},
- {Opt_tz_utc, "tz=UTC"},
{Opt_err, NULL},
};
static const match_table_t msdos_tokens = {
{Opt_err, NULL},
};
static const match_table_t msdos_tokens = {
@@
-930,12
+970,12
@@
static int parse_options(char *options, int is_vfat, int silent, int *debug,
opts->fs_uid = current_uid();
opts->fs_gid = current_gid();
opts->fs_uid = current_uid();
opts->fs_gid = current_gid();
- opts->fs_fmask = opts->fs_dmask = current
->fs->umask
;
+ opts->fs_fmask = opts->fs_dmask = current
_umask()
;
opts->allow_utime = -1;
opts->codepage = fat_default_codepage;
opts->iocharset = fat_default_iocharset;
if (is_vfat) {
opts->allow_utime = -1;
opts->codepage = fat_default_codepage;
opts->iocharset = fat_default_iocharset;
if (is_vfat) {
- opts->shortname = VFAT_SFN_DISPLAY_
LOWER
|VFAT_SFN_CREATE_WIN95;
+ opts->shortname = VFAT_SFN_DISPLAY_
WINNT
|VFAT_SFN_CREATE_WIN95;
opts->rodir = 0;
} else {
opts->shortname = 0;
opts->rodir = 0;
} else {
opts->shortname = 0;
@@
-947,6
+987,7
@@
static int parse_options(char *options, int is_vfat, int silent, int *debug,
opts->numtail = 1;
opts->usefree = opts->nocase = 0;
opts->tz_utc = 0;
opts->numtail = 1;
opts->usefree = opts->nocase = 0;
opts->tz_utc = 0;
+ opts->errors = FAT_ERRORS_RO;
*debug = 0;
if (!options)
*debug = 0;
if (!options)
@@
-1039,6
+1080,15
@@
static int parse_options(char *options, int is_vfat, int silent, int *debug,
case Opt_tz_utc:
opts->tz_utc = 1;
break;
case Opt_tz_utc:
opts->tz_utc = 1;
break;
+ case Opt_err_cont:
+ opts->errors = FAT_ERRORS_CONT;
+ break;
+ case Opt_err_panic:
+ opts->errors = FAT_ERRORS_PANIC;
+ break;
+ case Opt_err_ro:
+ opts->errors = FAT_ERRORS_RO;
+ break;
/* msdos specific */
case Opt_dots:
/* msdos specific */
case Opt_dots:
@@
-1094,6
+1144,9
@@
static int parse_options(char *options, int is_vfat, int silent, int *debug,
case Opt_rodir:
opts->rodir = 1;
break;
case Opt_rodir:
opts->rodir = 1;
break;
+ case Opt_discard:
+ opts->discard = 1;
+ break;
/* obsolete mount options */
case Opt_obsolate:
/* obsolete mount options */
case Opt_obsolate:
@@
-1170,7
+1223,7
@@
static int fat_read_root(struct inode *inode)
int fat_fill_super(struct super_block *sb, void *data, int silent,
const struct inode_operations *fs_dir_inode_ops, int isvfat)
{
int fat_fill_super(struct super_block *sb, void *data, int silent,
const struct inode_operations *fs_dir_inode_ops, int isvfat)
{
- struct inode *root_inode = NULL;
+ struct inode *root_inode = NULL
, *fat_inode = NULL
;
struct buffer_head *bh;
struct fat_boot_sector *b;
struct msdos_sb_info *sbi;
struct buffer_head *bh;
struct fat_boot_sector *b;
struct msdos_sb_info *sbi;
@@
-1410,6
+1463,11
@@
int fat_fill_super(struct super_block *sb, void *data, int silent,
}
error = -ENOMEM;
}
error = -ENOMEM;
+ fat_inode = new_inode(sb);
+ if (!fat_inode)
+ goto out_fail;
+ MSDOS_I(fat_inode)->i_pos = 0;
+ sbi->fat_inode = fat_inode;
root_inode = new_inode(sb);
if (!root_inode)
goto out_fail;
root_inode = new_inode(sb);
if (!root_inode)
goto out_fail;
@@
-1435,6
+1493,8
@@
out_invalid:
" on dev %s.\n", sb->s_id);
out_fail:
" on dev %s.\n", sb->s_id);
out_fail:
+ if (fat_inode)
+ iput(fat_inode);
if (root_inode)
iput(root_inode);
if (sbi->nls_io)
if (root_inode)
iput(root_inode);
if (sbi->nls_io)