diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/exfat/exfat_core.c | 20 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
-rw-r--r-- | fs/ext4/super.c | 17 | ||||
-rw-r--r-- | fs/fuse/file.c | 6 |
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); |