fs/affs/file.c: unlock/release page on error
When affs_bread_ino() fails, correctly unlock the page and release the page cache with proper error value. All write_end() should unlock/release the page that was locked by write_beg(). Signed-off-by: Taesoo Kim <tsgatesv@gmail.com> Cc: Fabian Frederick <fabf@skynet.be> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
cfa8694382
Коммит
3d5d472cf5
|
@ -699,8 +699,10 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
|
|||
boff = tmp % bsize;
|
||||
if (boff) {
|
||||
bh = affs_bread_ino(inode, bidx, 0);
|
||||
if (IS_ERR(bh))
|
||||
return PTR_ERR(bh);
|
||||
if (IS_ERR(bh)) {
|
||||
written = PTR_ERR(bh);
|
||||
goto err_first_bh;
|
||||
}
|
||||
tmp = min(bsize - boff, to - from);
|
||||
BUG_ON(boff + tmp > bsize || tmp > bsize);
|
||||
memcpy(AFFS_DATA(bh) + boff, data + from, tmp);
|
||||
|
@ -712,14 +714,16 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
|
|||
bidx++;
|
||||
} else if (bidx) {
|
||||
bh = affs_bread_ino(inode, bidx - 1, 0);
|
||||
if (IS_ERR(bh))
|
||||
return PTR_ERR(bh);
|
||||
if (IS_ERR(bh)) {
|
||||
written = PTR_ERR(bh);
|
||||
goto err_first_bh;
|
||||
}
|
||||
}
|
||||
while (from + bsize <= to) {
|
||||
prev_bh = bh;
|
||||
bh = affs_getemptyblk_ino(inode, bidx);
|
||||
if (IS_ERR(bh))
|
||||
goto out;
|
||||
goto err_bh;
|
||||
memcpy(AFFS_DATA(bh), data + from, bsize);
|
||||
if (buffer_new(bh)) {
|
||||
AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA);
|
||||
|
@ -751,7 +755,7 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
|
|||
prev_bh = bh;
|
||||
bh = affs_bread_ino(inode, bidx, 1);
|
||||
if (IS_ERR(bh))
|
||||
goto out;
|
||||
goto err_bh;
|
||||
tmp = min(bsize, to - from);
|
||||
BUG_ON(tmp > bsize);
|
||||
memcpy(AFFS_DATA(bh), data + from, tmp);
|
||||
|
@ -790,12 +794,13 @@ done:
|
|||
if (tmp > inode->i_size)
|
||||
inode->i_size = AFFS_I(inode)->mmu_private = tmp;
|
||||
|
||||
err_first_bh:
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
|
||||
return written;
|
||||
|
||||
out:
|
||||
err_bh:
|
||||
bh = prev_bh;
|
||||
if (!written)
|
||||
written = PTR_ERR(bh);
|
||||
|
|
Загрузка…
Ссылка в новой задаче