aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/dir.c8
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/inode.c14
-rw-r--r--fs/ext4/namei.c34
-rw-r--r--fs/ext4/super.c18
5 files changed, 34 insertions, 43 deletions
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 0bb3f9ea0832..c24143ea9c08 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -151,13 +151,11 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
151 &file->f_ra, file, 151 &file->f_ra, file,
152 index, 1); 152 index, 1);
153 file->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT; 153 file->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT;
154 bh = ext4_bread(NULL, inode, map.m_lblk, 0, &err); 154 bh = ext4_bread(NULL, inode, map.m_lblk, 0);
155 if (IS_ERR(bh))
156 return PTR_ERR(bh);
155 } 157 }
156 158
157 /*
158 * We ignore I/O errors on directories so users have a chance
159 * of recovering data when there's a bad sector
160 */
161 if (!bh) { 159 if (!bh) {
162 if (!dir_has_error) { 160 if (!dir_has_error) {
163 EXT4_ERROR_FILE(file, 0, 161 EXT4_ERROR_FILE(file, 0,
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 8009077079e4..ca53bcece838 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2087,8 +2087,7 @@ extern int ext4_trim_fs(struct super_block *, struct fstrim_range *);
2087 2087
2088/* inode.c */ 2088/* inode.c */
2089struct buffer_head *ext4_getblk(handle_t *, struct inode *, ext4_lblk_t, int); 2089struct buffer_head *ext4_getblk(handle_t *, struct inode *, ext4_lblk_t, int);
2090struct buffer_head *ext4_bread(handle_t *, struct inode *, 2090struct buffer_head *ext4_bread(handle_t *, struct inode *, ext4_lblk_t, int);
2091 ext4_lblk_t, int, int *);
2092int ext4_get_block_write(struct inode *inode, sector_t iblock, 2091int ext4_get_block_write(struct inode *inode, sector_t iblock,
2093 struct buffer_head *bh_result, int create); 2092 struct buffer_head *bh_result, int create);
2094int ext4_get_block(struct inode *inode, sector_t iblock, 2093int ext4_get_block(struct inode *inode, sector_t iblock,
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 0dfc1cd1eb52..8aa241a000c5 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -791,27 +791,21 @@ errout:
791} 791}
792 792
793struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, 793struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
794 ext4_lblk_t block, int create, int *err) 794 ext4_lblk_t block, int create)
795{ 795{
796 struct buffer_head *bh; 796 struct buffer_head *bh;
797 797
798 *err = 0;
799 bh = ext4_getblk(handle, inode, block, create); 798 bh = ext4_getblk(handle, inode, block, create);
800 if (IS_ERR(bh)) { 799 if (IS_ERR(bh))
801 *err = PTR_ERR(bh);
802 return NULL;
803 }
804 if (!bh)
805 return bh; 800 return bh;
806 if (buffer_uptodate(bh)) 801 if (!bh || buffer_uptodate(bh))
807 return bh; 802 return bh;
808 ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &bh); 803 ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &bh);
809 wait_on_buffer(bh); 804 wait_on_buffer(bh);
810 if (buffer_uptodate(bh)) 805 if (buffer_uptodate(bh))
811 return bh; 806 return bh;
812 put_bh(bh); 807 put_bh(bh);
813 *err = -EIO; 808 return ERR_PTR(-EIO);
814 return NULL;
815} 809}
816 810
817int ext4_walk_page_buffers(handle_t *handle, 811int ext4_walk_page_buffers(handle_t *handle,
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 26f114b1e4d6..af13c908f617 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -53,7 +53,7 @@ static struct buffer_head *ext4_append(handle_t *handle,
53 ext4_lblk_t *block) 53 ext4_lblk_t *block)
54{ 54{
55 struct buffer_head *bh; 55 struct buffer_head *bh;
56 int err = 0; 56 int err;
57 57
58 if (unlikely(EXT4_SB(inode->i_sb)->s_max_dir_size_kb && 58 if (unlikely(EXT4_SB(inode->i_sb)->s_max_dir_size_kb &&
59 ((inode->i_size >> 10) >= 59 ((inode->i_size >> 10) >=
@@ -62,9 +62,9 @@ static struct buffer_head *ext4_append(handle_t *handle,
62 62
63 *block = inode->i_size >> inode->i_sb->s_blocksize_bits; 63 *block = inode->i_size >> inode->i_sb->s_blocksize_bits;
64 64
65 bh = ext4_bread(handle, inode, *block, 1, &err); 65 bh = ext4_bread(handle, inode, *block, 1);
66 if (!bh) 66 if (IS_ERR(bh))
67 return ERR_PTR(err); 67 return bh;
68 inode->i_size += inode->i_sb->s_blocksize; 68 inode->i_size += inode->i_sb->s_blocksize;
69 EXT4_I(inode)->i_disksize = inode->i_size; 69 EXT4_I(inode)->i_disksize = inode->i_size;
70 BUFFER_TRACE(bh, "get_write_access"); 70 BUFFER_TRACE(bh, "get_write_access");
@@ -94,20 +94,20 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
94{ 94{
95 struct buffer_head *bh; 95 struct buffer_head *bh;
96 struct ext4_dir_entry *dirent; 96 struct ext4_dir_entry *dirent;
97 int err = 0, is_dx_block = 0; 97 int is_dx_block = 0;
98 98
99 bh = ext4_bread(NULL, inode, block, 0, &err); 99 bh = ext4_bread(NULL, inode, block, 0);
100 if (!bh) { 100 if (IS_ERR(bh)) {
101 if (err == 0) {
102 ext4_error_inode(inode, __func__, line, block,
103 "Directory hole found");
104 return ERR_PTR(-EIO);
105 }
106 __ext4_warning(inode->i_sb, __func__, line, 101 __ext4_warning(inode->i_sb, __func__, line,
107 "error reading directory block " 102 "error %ld reading directory block "
108 "(ino %lu, block %lu)", inode->i_ino, 103 "(ino %lu, block %lu)", PTR_ERR(bh), inode->i_ino,
109 (unsigned long) block); 104 (unsigned long) block);
110 return ERR_PTR(err); 105
106 return bh;
107 }
108 if (!bh) {
109 ext4_error_inode(inode, __func__, line, block, "Directory hole found");
110 return ERR_PTR(-EIO);
111 } 111 }
112 dirent = (struct ext4_dir_entry *) bh->b_data; 112 dirent = (struct ext4_dir_entry *) bh->b_data;
113 /* Determine whether or not we have an index block */ 113 /* Determine whether or not we have an index block */
@@ -640,7 +640,9 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
640 u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash; 640 u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
641 struct stats stats; 641 struct stats stats;
642 printk("%s%3u:%03u hash %8x/%8x ",levels?"":" ", i, block, hash, range); 642 printk("%s%3u:%03u hash %8x/%8x ",levels?"":" ", i, block, hash, range);
643 if (!(bh = ext4_bread (NULL,dir, block, 0,&err))) continue; 643 bh = ext4_bread(NULL,dir, block, 0);
644 if (!bh || IS_ERR(bh))
645 continue;
644 stats = levels? 646 stats = levels?
645 dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1): 647 dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
646 dx_show_leaf(hinfo, (struct ext4_dir_entry_2 *) bh->b_data, blocksize, 0); 648 dx_show_leaf(hinfo, (struct ext4_dir_entry_2 *) bh->b_data, blocksize, 0);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 0b28b36e7915..896e452b739d 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5305,7 +5305,6 @@ static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
5305{ 5305{
5306 struct inode *inode = sb_dqopt(sb)->files[type]; 5306 struct inode *inode = sb_dqopt(sb)->files[type];
5307 ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); 5307 ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
5308 int err = 0;
5309 int offset = off & (sb->s_blocksize - 1); 5308 int offset = off & (sb->s_blocksize - 1);
5310 int tocopy; 5309 int tocopy;
5311 size_t toread; 5310 size_t toread;
@@ -5320,9 +5319,9 @@ static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
5320 while (toread > 0) { 5319 while (toread > 0) {
5321 tocopy = sb->s_blocksize - offset < toread ? 5320 tocopy = sb->s_blocksize - offset < toread ?
5322 sb->s_blocksize - offset : toread; 5321 sb->s_blocksize - offset : toread;
5323 bh = ext4_bread(NULL, inode, blk, 0, &err); 5322 bh = ext4_bread(NULL, inode, blk, 0);
5324 if (err) 5323 if (IS_ERR(bh))
5325 return err; 5324 return PTR_ERR(bh);
5326 if (!bh) /* A hole? */ 5325 if (!bh) /* A hole? */
5327 memset(data, 0, tocopy); 5326 memset(data, 0, tocopy);
5328 else 5327 else
@@ -5343,8 +5342,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
5343{ 5342{
5344 struct inode *inode = sb_dqopt(sb)->files[type]; 5343 struct inode *inode = sb_dqopt(sb)->files[type];
5345 ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); 5344 ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
5346 int err = 0; 5345 int err, offset = off & (sb->s_blocksize - 1);
5347 int offset = off & (sb->s_blocksize - 1);
5348 struct buffer_head *bh; 5346 struct buffer_head *bh;
5349 handle_t *handle = journal_current_handle(); 5347 handle_t *handle = journal_current_handle();
5350 5348
@@ -5365,14 +5363,16 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
5365 return -EIO; 5363 return -EIO;
5366 } 5364 }
5367 5365
5368 bh = ext4_bread(handle, inode, blk, 1, &err); 5366 bh = ext4_bread(handle, inode, blk, 1);
5367 if (IS_ERR(bh))
5368 return PTR_ERR(bh);
5369 if (!bh) 5369 if (!bh)
5370 goto out; 5370 goto out;
5371 BUFFER_TRACE(bh, "get write access"); 5371 BUFFER_TRACE(bh, "get write access");
5372 err = ext4_journal_get_write_access(handle, bh); 5372 err = ext4_journal_get_write_access(handle, bh);
5373 if (err) { 5373 if (err) {
5374 brelse(bh); 5374 brelse(bh);
5375 goto out; 5375 return err;
5376 } 5376 }
5377 lock_buffer(bh); 5377 lock_buffer(bh);
5378 memcpy(bh->b_data+offset, data, len); 5378 memcpy(bh->b_data+offset, data, len);
@@ -5381,8 +5381,6 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
5381 err = ext4_handle_dirty_metadata(handle, NULL, bh); 5381 err = ext4_handle_dirty_metadata(handle, NULL, bh);
5382 brelse(bh); 5382 brelse(bh);
5383out: 5383out:
5384 if (err)
5385 return err;
5386 if (inode->i_size < off + len) { 5384 if (inode->i_size < off + len) {
5387 i_size_write(inode, off + len); 5385 i_size_write(inode, off + len);
5388 EXT4_I(inode)->i_disksize = inode->i_size; 5386 EXT4_I(inode)->i_disksize = inode->i_size;