Commit b2dffcdf authored by Ben Fennema's avatar Ben Fennema Committed by Linus Torvalds

[PATCH] udf patch for 2.5.7-pre1 (part 3/4)

This patch fixes an extent preallocation bug and adds missing sb_bread == NULL
checks.
parent 0fe988de
...@@ -50,6 +50,7 @@ static int udf_adinicb_readpage(struct file *file, struct page * page) ...@@ -50,6 +50,7 @@ static int udf_adinicb_readpage(struct file *file, struct page * page)
struct buffer_head *bh; struct buffer_head *bh;
int block; int block;
char *kaddr; char *kaddr;
int err = 0;
if (!PageLocked(page)) if (!PageLocked(page))
PAGE_BUG(page); PAGE_BUG(page);
...@@ -58,13 +59,20 @@ static int udf_adinicb_readpage(struct file *file, struct page * page) ...@@ -58,13 +59,20 @@ static int udf_adinicb_readpage(struct file *file, struct page * page)
memset(kaddr, 0, PAGE_CACHE_SIZE); memset(kaddr, 0, PAGE_CACHE_SIZE);
block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
bh = sb_bread(inode->i_sb, block); bh = sb_bread(inode->i_sb, block);
if (!bh)
{
SetPageError(page);
err = -EIO;
goto out;
}
memcpy(kaddr, bh->b_data + udf_ext0_offset(inode), inode->i_size); memcpy(kaddr, bh->b_data + udf_ext0_offset(inode), inode->i_size);
brelse(bh); brelse(bh);
flush_dcache_page(page); flush_dcache_page(page);
SetPageUptodate(page); SetPageUptodate(page);
out:
kunmap(page); kunmap(page);
UnlockPage(page); UnlockPage(page);
return 0; return err;
} }
static int udf_adinicb_writepage(struct page *page) static int udf_adinicb_writepage(struct page *page)
...@@ -74,6 +82,7 @@ static int udf_adinicb_writepage(struct page *page) ...@@ -74,6 +82,7 @@ static int udf_adinicb_writepage(struct page *page)
struct buffer_head *bh; struct buffer_head *bh;
int block; int block;
char *kaddr; char *kaddr;
int err = 0;
if (!PageLocked(page)) if (!PageLocked(page))
PAGE_BUG(page); PAGE_BUG(page);
...@@ -81,13 +90,20 @@ static int udf_adinicb_writepage(struct page *page) ...@@ -81,13 +90,20 @@ static int udf_adinicb_writepage(struct page *page)
kaddr = kmap(page); kaddr = kmap(page);
block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
bh = sb_bread(inode->i_sb, block); bh = sb_bread(inode->i_sb, block);
if (!bh)
{
SetPageError(page);
err = -EIO;
goto out;
}
memcpy(bh->b_data + udf_ext0_offset(inode), kaddr, inode->i_size); memcpy(bh->b_data + udf_ext0_offset(inode), kaddr, inode->i_size);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
SetPageUptodate(page); SetPageUptodate(page);
out:
kunmap(page); kunmap(page);
UnlockPage(page); UnlockPage(page);
return 0; return err;
} }
static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
...@@ -103,19 +119,27 @@ static int udf_adinicb_commit_write(struct file *file, struct page *page, unsign ...@@ -103,19 +119,27 @@ static int udf_adinicb_commit_write(struct file *file, struct page *page, unsign
struct buffer_head *bh; struct buffer_head *bh;
int block; int block;
char *kaddr = page_address(page); char *kaddr = page_address(page);
int err = 0;
block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0); block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
bh = sb_bread(inode->i_sb, block); bh = sb_bread(inode->i_sb, block);
if (!bh)
{
SetPageError(page);
err = -EIO;
goto out;
}
memcpy(bh->b_data + udf_file_entry_alloc_offset(inode) + offset, memcpy(bh->b_data + udf_file_entry_alloc_offset(inode) + offset,
kaddr + offset, to-offset); kaddr + offset, to - offset);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
brelse(bh); brelse(bh);
SetPageUptodate(page); SetPageUptodate(page);
out:
kunmap(page); kunmap(page);
/* only one page here */ /* only one page here */
if (to > inode->i_size) if (to > inode->i_size)
inode->i_size = to; inode->i_size = to;
return 0; return err;
} }
struct address_space_operations udf_adinicb_aops = { struct address_space_operations udf_adinicb_aops = {
......
...@@ -83,9 +83,6 @@ void udf_put_inode(struct inode * inode) ...@@ -83,9 +83,6 @@ void udf_put_inode(struct inode * inode)
{ {
lock_kernel(); lock_kernel();
udf_discard_prealloc(inode); udf_discard_prealloc(inode);
/* write the root inode on put, if dirty */
if (!inode->i_sb->s_root && inode->i_state & I_DIRTY)
udf_update_inode(inode, IS_SYNC(inode));
unlock_kernel(); unlock_kernel();
} }
} }
...@@ -703,7 +700,6 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, ...@@ -703,7 +700,6 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
if (numalloc) if (numalloc)
{ {
UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
if (start == (c+1)) if (start == (c+1))
laarr[start].extLength += laarr[start].extLength +=
(numalloc << inode->i_sb->s_blocksize_bits); (numalloc << inode->i_sb->s_blocksize_bits);
...@@ -727,7 +723,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, ...@@ -727,7 +723,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
if (elen > numalloc) if (elen > numalloc)
{ {
laarr[c+1].extLength -= laarr[c].extLength -=
(numalloc << inode->i_sb->s_blocksize_bits); (numalloc << inode->i_sb->s_blocksize_bits);
numalloc = 0; numalloc = 0;
} }
...@@ -741,6 +737,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock, ...@@ -741,6 +737,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
(*endnum) --; (*endnum) --;
} }
} }
UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
} }
} }
} }
...@@ -1349,6 +1346,7 @@ udf_update_inode(struct inode *inode, int do_sync) ...@@ -1349,6 +1346,7 @@ udf_update_inode(struct inode *inode, int do_sync)
use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode)); use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
crclen = sizeof(struct UnallocatedSpaceEntry) + UDF_I_LENALLOC(inode) - crclen = sizeof(struct UnallocatedSpaceEntry) + UDF_I_LENALLOC(inode) -
sizeof(tag); sizeof(tag);
use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
use->descTag.descCRCLength = cpu_to_le16(crclen); use->descTag.descCRCLength = cpu_to_le16(crclen);
use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0)); use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
......
...@@ -41,6 +41,12 @@ static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset, ...@@ -41,6 +41,12 @@ static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset,
if (nelen) if (nelen)
{ {
if (etype == EXTENT_NOT_RECORDED_ALLOCATED)
{
udf_free_blocks(inode->i_sb, inode, eloc, 0, last_block);
etype = EXTENT_NOT_RECORDED_NOT_ALLOCATED;
}
else
neloc = eloc; neloc = eloc;
nelen = (etype << 30) | nelen; nelen = (etype << 30) | nelen;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment