diff options
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/file.c | 35 | ||||
-rw-r--r-- | fs/udf/inode.c | 5 | ||||
-rw-r--r-- | fs/udf/super.c | 7 |
3 files changed, 39 insertions, 8 deletions
diff --git a/fs/udf/file.c b/fs/udf/file.c index 7f3f7ba3df6e..d1c6093fd3d3 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -39,20 +39,24 @@ | |||
39 | #include "udf_i.h" | 39 | #include "udf_i.h" |
40 | #include "udf_sb.h" | 40 | #include "udf_sb.h" |
41 | 41 | ||
42 | static int udf_adinicb_readpage(struct file *file, struct page *page) | 42 | static void __udf_adinicb_readpage(struct page *page) |
43 | { | 43 | { |
44 | struct inode *inode = page->mapping->host; | 44 | struct inode *inode = page->mapping->host; |
45 | char *kaddr; | 45 | char *kaddr; |
46 | struct udf_inode_info *iinfo = UDF_I(inode); | 46 | struct udf_inode_info *iinfo = UDF_I(inode); |
47 | 47 | ||
48 | BUG_ON(!PageLocked(page)); | ||
49 | |||
50 | kaddr = kmap(page); | 48 | kaddr = kmap(page); |
51 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
52 | memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size); | 49 | memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size); |
50 | memset(kaddr + inode->i_size, 0, PAGE_CACHE_SIZE - inode->i_size); | ||
53 | flush_dcache_page(page); | 51 | flush_dcache_page(page); |
54 | SetPageUptodate(page); | 52 | SetPageUptodate(page); |
55 | kunmap(page); | 53 | kunmap(page); |
54 | } | ||
55 | |||
56 | static int udf_adinicb_readpage(struct file *file, struct page *page) | ||
57 | { | ||
58 | BUG_ON(!PageLocked(page)); | ||
59 | __udf_adinicb_readpage(page); | ||
56 | unlock_page(page); | 60 | unlock_page(page); |
57 | 61 | ||
58 | return 0; | 62 | return 0; |
@@ -77,6 +81,25 @@ static int udf_adinicb_writepage(struct page *page, | |||
77 | return 0; | 81 | return 0; |
78 | } | 82 | } |
79 | 83 | ||
84 | static int udf_adinicb_write_begin(struct file *file, | ||
85 | struct address_space *mapping, loff_t pos, | ||
86 | unsigned len, unsigned flags, struct page **pagep, | ||
87 | void **fsdata) | ||
88 | { | ||
89 | struct page *page; | ||
90 | |||
91 | if (WARN_ON_ONCE(pos >= PAGE_CACHE_SIZE)) | ||
92 | return -EIO; | ||
93 | page = grab_cache_page_write_begin(mapping, 0, flags); | ||
94 | if (!page) | ||
95 | return -ENOMEM; | ||
96 | *pagep = page; | ||
97 | |||
98 | if (!PageUptodate(page) && len != PAGE_CACHE_SIZE) | ||
99 | __udf_adinicb_readpage(page); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
80 | static int udf_adinicb_write_end(struct file *file, | 103 | static int udf_adinicb_write_end(struct file *file, |
81 | struct address_space *mapping, | 104 | struct address_space *mapping, |
82 | loff_t pos, unsigned len, unsigned copied, | 105 | loff_t pos, unsigned len, unsigned copied, |
@@ -98,8 +121,8 @@ static int udf_adinicb_write_end(struct file *file, | |||
98 | const struct address_space_operations udf_adinicb_aops = { | 121 | const struct address_space_operations udf_adinicb_aops = { |
99 | .readpage = udf_adinicb_readpage, | 122 | .readpage = udf_adinicb_readpage, |
100 | .writepage = udf_adinicb_writepage, | 123 | .writepage = udf_adinicb_writepage, |
101 | .write_begin = simple_write_begin, | 124 | .write_begin = udf_adinicb_write_begin, |
102 | .write_end = udf_adinicb_write_end, | 125 | .write_end = udf_adinicb_write_end, |
103 | }; | 126 | }; |
104 | 127 | ||
105 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 128 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index fafaad795cd6..aa233469b3c1 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1124,14 +1124,17 @@ int udf_setsize(struct inode *inode, loff_t newsize) | |||
1124 | if (err) | 1124 | if (err) |
1125 | return err; | 1125 | return err; |
1126 | down_write(&iinfo->i_data_sem); | 1126 | down_write(&iinfo->i_data_sem); |
1127 | } else | 1127 | } else { |
1128 | iinfo->i_lenAlloc = newsize; | 1128 | iinfo->i_lenAlloc = newsize; |
1129 | goto set_size; | ||
1130 | } | ||
1129 | } | 1131 | } |
1130 | err = udf_extend_file(inode, newsize); | 1132 | err = udf_extend_file(inode, newsize); |
1131 | if (err) { | 1133 | if (err) { |
1132 | up_write(&iinfo->i_data_sem); | 1134 | up_write(&iinfo->i_data_sem); |
1133 | return err; | 1135 | return err; |
1134 | } | 1136 | } |
1137 | set_size: | ||
1135 | truncate_setsize(inode, newsize); | 1138 | truncate_setsize(inode, newsize); |
1136 | up_write(&iinfo->i_data_sem); | 1139 | up_write(&iinfo->i_data_sem); |
1137 | } else { | 1140 | } else { |
diff --git a/fs/udf/super.c b/fs/udf/super.c index dcbf98722afc..18fc038a438d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1344,6 +1344,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
1344 | udf_err(sb, "error loading logical volume descriptor: " | 1344 | udf_err(sb, "error loading logical volume descriptor: " |
1345 | "Partition table too long (%u > %lu)\n", table_len, | 1345 | "Partition table too long (%u > %lu)\n", table_len, |
1346 | sb->s_blocksize - sizeof(*lvd)); | 1346 | sb->s_blocksize - sizeof(*lvd)); |
1347 | ret = 1; | ||
1347 | goto out_bh; | 1348 | goto out_bh; |
1348 | } | 1349 | } |
1349 | 1350 | ||
@@ -1388,8 +1389,10 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
1388 | UDF_ID_SPARABLE, | 1389 | UDF_ID_SPARABLE, |
1389 | strlen(UDF_ID_SPARABLE))) { | 1390 | strlen(UDF_ID_SPARABLE))) { |
1390 | if (udf_load_sparable_map(sb, map, | 1391 | if (udf_load_sparable_map(sb, map, |
1391 | (struct sparablePartitionMap *)gpm) < 0) | 1392 | (struct sparablePartitionMap *)gpm) < 0) { |
1393 | ret = 1; | ||
1392 | goto out_bh; | 1394 | goto out_bh; |
1395 | } | ||
1393 | } else if (!strncmp(upm2->partIdent.ident, | 1396 | } else if (!strncmp(upm2->partIdent.ident, |
1394 | UDF_ID_METADATA, | 1397 | UDF_ID_METADATA, |
1395 | strlen(UDF_ID_METADATA))) { | 1398 | strlen(UDF_ID_METADATA))) { |
@@ -2000,6 +2003,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
2000 | if (!silent) | 2003 | if (!silent) |
2001 | pr_notice("Rescanning with blocksize %d\n", | 2004 | pr_notice("Rescanning with blocksize %d\n", |
2002 | UDF_DEFAULT_BLOCKSIZE); | 2005 | UDF_DEFAULT_BLOCKSIZE); |
2006 | brelse(sbi->s_lvid_bh); | ||
2007 | sbi->s_lvid_bh = NULL; | ||
2003 | uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; | 2008 | uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; |
2004 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); | 2009 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); |
2005 | } | 2010 | } |