summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/exfat/exfat_core.c20
-rw-r--r--fs/ext4/ext4.h1
-rw-r--r--fs/ext4/super.c17
-rw-r--r--fs/fuse/file.c6
4 files changed, 38 insertions, 6 deletions
diff --git a/fs/exfat/exfat_core.c b/fs/exfat/exfat_core.c
index d48514189..73c089f7f 100644
--- a/fs/exfat/exfat_core.c
+++ b/fs/exfat/exfat_core.c
@@ -183,7 +183,7 @@ s32 ffsMountVol(struct super_block *sb)
if (sector_read(sb, 0, &tmp_bh, 1) != FFS_SUCCESS)
return FFS_MEDIAERR;
- p_fs->PBR_sector = 0;
+ p_fs->PBR_sector = 0;
p_pbr = (PBR_SECTOR_T *) tmp_bh->b_data;
@@ -3758,7 +3758,7 @@ s32 fat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uni
-2 : entry with the name does not exist */
s32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, s32 num_entries, DOS_NAME_T *p_dosname, u32 type)
{
- int i, dentry = 0, num_ext_entries = 0, len;
+ int i = 0, dentry = 0, num_ext_entries = 0, len, step;
s32 order = 0, is_feasible_entry = FALSE;
s32 dentries_per_clu, num_empty = 0;
u32 entry_type;
@@ -3792,12 +3792,13 @@ s32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_u
if (p_fs->dev_ejected)
break;
- for (i = 0; i < dentries_per_clu; i++, dentry++) {
+ while (i < dentries_per_clu) {
ep = get_entry_in_dir(sb, &clu, i, NULL);
if (!ep)
return -2;
entry_type = p_fs->fs_func->get_entry_type(ep);
+ step = 1;
if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) {
is_feasible_entry = FALSE;
@@ -3820,20 +3821,23 @@ s32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_u
num_empty = 0;
if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) {
+ file_ep = (FILE_DENTRY_T *) ep;
if ((type == TYPE_ALL) || (type == entry_type)) {
- file_ep = (FILE_DENTRY_T *) ep;
num_ext_entries = file_ep->num_ext;
is_feasible_entry = TRUE;
} else {
is_feasible_entry = FALSE;
+ step = file_ep->num_ext + 1;
}
} else if (entry_type == TYPE_STREAM) {
if (is_feasible_entry) {
strm_ep = (STRM_DENTRY_T *) ep;
- if (p_uniname->name_len == strm_ep->name_len) {
+ if (p_uniname->name_hash == GET16_A(strm_ep->name_hash) &&
+ p_uniname->name_len == strm_ep->name_len) {
order = 1;
} else {
is_feasible_entry = FALSE;
+ step = num_ext_entries;
}
}
} else if (entry_type == TYPE_EXTEND) {
@@ -3852,6 +3856,7 @@ s32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_u
if (nls_uniname_cmp(sb, uniname, entry_uniname)) {
is_feasible_entry = FALSE;
+ step = num_ext_entries - order + 1;
} else if (order == num_ext_entries) {
p_fs->hint_uentry.dir = CLUSTER_32(~0);
p_fs->hint_uentry.entry = -1;
@@ -3864,8 +3869,13 @@ s32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_u
is_feasible_entry = FALSE;
}
}
+
+ i += step;
+ dentry += step;
}
+ i -= dentries_per_clu;
+
if (p_dir->dir == CLUSTER_32(0))
break; /* FAT16 root_dir */
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ea3193138..7bd21aaed 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -235,6 +235,7 @@ struct ext4_io_submit {
#define EXT4_MAX_BLOCK_SIZE 65536
#define EXT4_MIN_BLOCK_LOG_SIZE 10
#define EXT4_MAX_BLOCK_LOG_SIZE 16
+#define EXT4_MAX_CLUSTER_LOG_SIZE 30
#ifdef __KERNEL__
# define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize)
#else
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 3ec870898..ec89f5005 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3518,7 +3518,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
if (blocksize < EXT4_MIN_BLOCK_SIZE ||
blocksize > EXT4_MAX_BLOCK_SIZE) {
ext4_msg(sb, KERN_ERR,
- "Unsupported filesystem blocksize %d", blocksize);
+ "Unsupported filesystem blocksize %d (%d log_block_size)",
+ blocksize, le32_to_cpu(es->s_log_block_size));
+ goto failed_mount;
+ }
+ if (le32_to_cpu(es->s_log_block_size) >
+ (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
+ ext4_msg(sb, KERN_ERR,
+ "Invalid log block size: %u",
+ le32_to_cpu(es->s_log_block_size));
goto failed_mount;
}
@@ -3650,6 +3658,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
"block size (%d)", clustersize, blocksize);
goto failed_mount;
}
+ if (le32_to_cpu(es->s_log_cluster_size) >
+ (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
+ ext4_msg(sb, KERN_ERR,
+ "Invalid log cluster size: %u",
+ le32_to_cpu(es->s_log_cluster_size));
+ goto failed_mount;
+ }
sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) -
le32_to_cpu(es->s_log_block_size);
sbi->s_clusters_per_group =
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 3988b43c2..a621dd98a 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1985,6 +1985,10 @@ static int fuse_write_end(struct file *file, struct address_space *mapping,
{
struct inode *inode = page->mapping->host;
+ /* Haven't copied anything? Skip zeroing, size extending, dirtying. */
+ if (!copied)
+ goto unlock;
+
if (!PageUptodate(page)) {
/* Zero any unwritten bytes at the end of the page */
size_t endoff = (pos + copied) & ~PAGE_MASK;
@@ -1995,6 +1999,8 @@ static int fuse_write_end(struct file *file, struct address_space *mapping,
fuse_write_update_size(inode, pos + copied);
set_page_dirty(page);
+
+unlock:
unlock_page(page);
put_page(page);