aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf')
-rw-r--r--fs/udf/balloc.c12
-rw-r--r--fs/udf/file.c35
-rw-r--r--fs/udf/inode.c13
-rw-r--r--fs/udf/super.c71
-rw-r--r--fs/udf/udftime.c8
5 files changed, 69 insertions, 70 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 276f7207a5..ab26176f6b 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -540,26 +540,24 @@ static void udf_table_free_blocks(struct super_block *sb,
540 if (epos.offset + adsize > sb->s_blocksize) { 540 if (epos.offset + adsize > sb->s_blocksize) {
541 loffset = epos.offset; 541 loffset = epos.offset;
542 aed->lengthAllocDescs = cpu_to_le32(adsize); 542 aed->lengthAllocDescs = cpu_to_le32(adsize);
543 sptr = UDF_I_DATA(inode) + epos.offset - 543 sptr = UDF_I_DATA(table) + epos.offset - adsize;
544 udf_file_entry_alloc_offset(inode) +
545 UDF_I_LENEATTR(inode) - adsize;
546 dptr = epos.bh->b_data + sizeof(struct allocExtDesc); 544 dptr = epos.bh->b_data + sizeof(struct allocExtDesc);
547 memcpy(dptr, sptr, adsize); 545 memcpy(dptr, sptr, adsize);
548 epos.offset = sizeof(struct allocExtDesc) + adsize; 546 epos.offset = sizeof(struct allocExtDesc) + adsize;
549 } else { 547 } else {
550 loffset = epos.offset + adsize; 548 loffset = epos.offset + adsize;
551 aed->lengthAllocDescs = cpu_to_le32(0); 549 aed->lengthAllocDescs = cpu_to_le32(0);
552 sptr = oepos.bh->b_data + epos.offset;
553 epos.offset = sizeof(struct allocExtDesc);
554
555 if (oepos.bh) { 550 if (oepos.bh) {
551 sptr = oepos.bh->b_data + epos.offset;
556 aed = (struct allocExtDesc *)oepos.bh->b_data; 552 aed = (struct allocExtDesc *)oepos.bh->b_data;
557 aed->lengthAllocDescs = 553 aed->lengthAllocDescs =
558 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); 554 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
559 } else { 555 } else {
556 sptr = UDF_I_DATA(table) + epos.offset;
560 UDF_I_LENALLOC(table) += adsize; 557 UDF_I_LENALLOC(table) += adsize;
561 mark_inode_dirty(table); 558 mark_inode_dirty(table);
562 } 559 }
560 epos.offset = sizeof(struct allocExtDesc);
563 } 561 }
564 if (UDF_SB_UDFREV(sb) >= 0x0200) 562 if (UDF_SB_UDFREV(sb) >= 0x0200)
565 udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1, 563 udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1,
@@ -691,7 +689,7 @@ static int udf_table_new_block(struct super_block *sb,
691 uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; 689 uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
692 uint32_t newblock = 0, adsize; 690 uint32_t newblock = 0, adsize;
693 uint32_t elen, goal_elen = 0; 691 uint32_t elen, goal_elen = 0;
694 kernel_lb_addr eloc, goal_eloc; 692 kernel_lb_addr eloc, uninitialized_var(goal_eloc);
695 struct extent_position epos, goal_epos; 693 struct extent_position epos, goal_epos;
696 int8_t etype; 694 int8_t etype;
697 695
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 5d7a4ea277..7c7a1b39d5 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -76,36 +76,29 @@ static int udf_adinicb_writepage(struct page *page, struct writeback_control *wb
76 return 0; 76 return 0;
77} 77}
78 78
79static int udf_adinicb_prepare_write(struct file *file, struct page *page, 79static int udf_adinicb_write_end(struct file *file,
80 unsigned offset, unsigned to) 80 struct address_space *mapping,
81 loff_t pos, unsigned len, unsigned copied,
82 struct page *page, void *fsdata)
81{ 83{
82 kmap(page); 84 struct inode *inode = mapping->host;
83 return 0; 85 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
84} 86 char *kaddr;
85
86static int udf_adinicb_commit_write(struct file *file, struct page *page,
87 unsigned offset, unsigned to)
88{
89 struct inode *inode = page->mapping->host;
90 char *kaddr = page_address(page);
91 87
88 kaddr = kmap_atomic(page, KM_USER0);
92 memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, 89 memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset,
93 kaddr + offset, to - offset); 90 kaddr + offset, copied);
94 mark_inode_dirty(inode); 91 kunmap_atomic(kaddr, KM_USER0);
95 SetPageUptodate(page); 92
96 kunmap(page); 93 return simple_write_end(file, mapping, pos, len, copied, page, fsdata);
97 /* only one page here */
98 if (to > inode->i_size)
99 inode->i_size = to;
100 return 0;
101} 94}
102 95
103const struct address_space_operations udf_adinicb_aops = { 96const struct address_space_operations udf_adinicb_aops = {
104 .readpage = udf_adinicb_readpage, 97 .readpage = udf_adinicb_readpage,
105 .writepage = udf_adinicb_writepage, 98 .writepage = udf_adinicb_writepage,
106 .sync_page = block_sync_page, 99 .sync_page = block_sync_page,
107 .prepare_write = udf_adinicb_prepare_write, 100 .write_begin = simple_write_begin,
108 .commit_write = udf_adinicb_commit_write, 101 .write_end = udf_adinicb_write_end,
109}; 102};
110 103
111static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 104static 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 1652b2c665..6ff8151984 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -133,10 +133,13 @@ static int udf_readpage(struct file *file, struct page *page)
133 return block_read_full_page(page, udf_get_block); 133 return block_read_full_page(page, udf_get_block);
134} 134}
135 135
136static int udf_prepare_write(struct file *file, struct page *page, 136static int udf_write_begin(struct file *file, struct address_space *mapping,
137 unsigned from, unsigned to) 137 loff_t pos, unsigned len, unsigned flags,
138 struct page **pagep, void **fsdata)
138{ 139{
139 return block_prepare_write(page, from, to, udf_get_block); 140 *pagep = NULL;
141 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
142 udf_get_block);
140} 143}
141 144
142static sector_t udf_bmap(struct address_space *mapping, sector_t block) 145static sector_t udf_bmap(struct address_space *mapping, sector_t block)
@@ -148,8 +151,8 @@ const struct address_space_operations udf_aops = {
148 .readpage = udf_readpage, 151 .readpage = udf_readpage,
149 .writepage = udf_writepage, 152 .writepage = udf_writepage,
150 .sync_page = block_sync_page, 153 .sync_page = block_sync_page,
151 .prepare_write = udf_prepare_write, 154 .write_begin = udf_write_begin,
152 .commit_write = generic_commit_write, 155 .write_end = generic_write_end,
153 .bmap = udf_bmap, 156 .bmap = udf_bmap,
154}; 157};
155 158
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 382be7be5a..4360c7a057 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -89,7 +89,7 @@ static int udf_find_fileset(struct super_block *, kernel_lb_addr *,
89static void udf_load_pvoldesc(struct super_block *, struct buffer_head *); 89static void udf_load_pvoldesc(struct super_block *, struct buffer_head *);
90static void udf_load_fileset(struct super_block *, struct buffer_head *, 90static void udf_load_fileset(struct super_block *, struct buffer_head *,
91 kernel_lb_addr *); 91 kernel_lb_addr *);
92static void udf_load_partdesc(struct super_block *, struct buffer_head *); 92static int udf_load_partdesc(struct super_block *, struct buffer_head *);
93static void udf_open_lvid(struct super_block *); 93static void udf_open_lvid(struct super_block *);
94static void udf_close_lvid(struct super_block *); 94static void udf_close_lvid(struct super_block *);
95static unsigned int udf_count_free(struct super_block *); 95static unsigned int udf_count_free(struct super_block *);
@@ -134,7 +134,7 @@ static void udf_destroy_inode(struct inode *inode)
134 kmem_cache_free(udf_inode_cachep, UDF_I(inode)); 134 kmem_cache_free(udf_inode_cachep, UDF_I(inode));
135} 135}
136 136
137static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) 137static void init_once(struct kmem_cache *cachep, void *foo)
138{ 138{
139 struct udf_inode_info *ei = (struct udf_inode_info *)foo; 139 struct udf_inode_info *ei = (struct udf_inode_info *)foo;
140 140
@@ -877,7 +877,7 @@ static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
877 root->logicalBlockNum, root->partitionReferenceNum); 877 root->logicalBlockNum, root->partitionReferenceNum);
878} 878}
879 879
880static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) 880static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
881{ 881{
882 struct partitionDesc *p; 882 struct partitionDesc *p;
883 int i; 883 int i;
@@ -912,6 +912,10 @@ static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
912 912
913 UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table = 913 UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
914 udf_iget(sb, loc); 914 udf_iget(sb, loc);
915 if (!UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table) {
916 udf_debug("cannot load unallocSpaceTable (part %d)\n", i);
917 return 1;
918 }
915 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE; 919 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;
916 udf_debug("unallocSpaceTable (part %d) @ %ld\n", 920 udf_debug("unallocSpaceTable (part %d) @ %ld\n",
917 i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino); 921 i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino);
@@ -938,6 +942,10 @@ static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
938 942
939 UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table = 943 UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =
940 udf_iget(sb, loc); 944 udf_iget(sb, loc);
945 if (!UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table) {
946 udf_debug("cannot load freedSpaceTable (part %d)\n", i);
947 return 1;
948 }
941 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE; 949 UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;
942 udf_debug("freedSpaceTable (part %d) @ %ld\n", 950 udf_debug("freedSpaceTable (part %d) @ %ld\n",
943 i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino); 951 i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino);
@@ -966,6 +974,7 @@ static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
966 le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i), 974 le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i),
967 UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i)); 975 UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i));
968 } 976 }
977 return 0;
969} 978}
970 979
971static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, 980static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
@@ -1177,12 +1186,19 @@ static int udf_process_sequence(struct super_block *sb, long block, long lastblo
1177 udf_load_logicalvol(sb, bh, fileset); 1186 udf_load_logicalvol(sb, bh, fileset);
1178 } else if (i == VDS_POS_PARTITION_DESC) { 1187 } else if (i == VDS_POS_PARTITION_DESC) {
1179 struct buffer_head *bh2 = NULL; 1188 struct buffer_head *bh2 = NULL;
1180 udf_load_partdesc(sb, bh); 1189 if (udf_load_partdesc(sb, bh)) {
1190 brelse(bh);
1191 return 1;
1192 }
1181 for (j = vds[i].block + 1; j < vds[VDS_POS_TERMINATING_DESC].block; j++) { 1193 for (j = vds[i].block + 1; j < vds[VDS_POS_TERMINATING_DESC].block; j++) {
1182 bh2 = udf_read_tagged(sb, j, j, &ident); 1194 bh2 = udf_read_tagged(sb, j, j, &ident);
1183 gd = (struct generic_desc *)bh2->b_data; 1195 gd = (struct generic_desc *)bh2->b_data;
1184 if (ident == TAG_IDENT_PD) 1196 if (ident == TAG_IDENT_PD)
1185 udf_load_partdesc(sb, bh2); 1197 if (udf_load_partdesc(sb, bh2)) {
1198 brelse(bh);
1199 brelse(bh2);
1200 return 1;
1201 }
1186 brelse(bh2); 1202 brelse(bh2);
1187 } 1203 }
1188 } 1204 }
@@ -1275,19 +1291,16 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
1275 1291
1276 if (!UDF_SB_LASTBLOCK(sb)) { 1292 if (!UDF_SB_LASTBLOCK(sb)) {
1277 udf_debug("Unable to determine Lastblock (For " 1293 udf_debug("Unable to determine Lastblock (For "
1278 "Virtual Partition)\n"); 1294 "Virtual Partition)\n");
1279 return 1; 1295 return 1;
1280 } 1296 }
1281 1297
1282 for (j = 0; j < UDF_SB_NUMPARTS(sb); j++) { 1298 for (j = 0; j < UDF_SB_NUMPARTS(sb); j++) {
1283 if (j != i && UDF_SB_PARTVSN(sb, i) == 1299 if (j != i &&
1284 UDF_SB_PARTVSN(sb, j) && 1300 UDF_SB_PARTVSN(sb, i) == UDF_SB_PARTVSN(sb, j) &&
1285 UDF_SB_PARTNUM(sb, i) == 1301 UDF_SB_PARTNUM(sb, i) == UDF_SB_PARTNUM(sb, j)) {
1286 UDF_SB_PARTNUM(sb, j)) {
1287 ino.partitionReferenceNum = j; 1302 ino.partitionReferenceNum = j;
1288 ino.logicalBlockNum = 1303 ino.logicalBlockNum = UDF_SB_LASTBLOCK(sb) - UDF_SB_PARTROOT(sb, j);
1289 UDF_SB_LASTBLOCK(sb) -
1290 UDF_SB_PARTROOT(sb, j);
1291 break; 1304 break;
1292 } 1305 }
1293 } 1306 }
@@ -1300,9 +1313,9 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
1300 1313
1301 if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP15) { 1314 if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP15) {
1302 UDF_SB_TYPEVIRT(sb, i).s_start_offset = 1315 UDF_SB_TYPEVIRT(sb, i).s_start_offset =
1303 udf_ext0_offset(UDF_SB_VAT(sb)); 1316 udf_ext0_offset(UDF_SB_VAT(sb));
1304 UDF_SB_TYPEVIRT(sb, i).s_num_entries = 1317 UDF_SB_TYPEVIRT(sb, i).s_num_entries =
1305 (UDF_SB_VAT(sb)->i_size - 36) >> 2; 1318 (UDF_SB_VAT(sb)->i_size - 36) >> 2;
1306 } else if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP20) { 1319 } else if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP20) {
1307 struct buffer_head *bh = NULL; 1320 struct buffer_head *bh = NULL;
1308 uint32_t pos; 1321 uint32_t pos;
@@ -1312,19 +1325,15 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
1312 if (!bh) 1325 if (!bh)
1313 return 1; 1326 return 1;
1314 UDF_SB_TYPEVIRT(sb, i).s_start_offset = 1327 UDF_SB_TYPEVIRT(sb, i).s_start_offset =
1315 le16_to_cpu(((struct 1328 le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data +
1316 virtualAllocationTable20 *)bh->b_data + 1329 udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
1317 udf_ext0_offset(UDF_SB_VAT(sb)))-> 1330 udf_ext0_offset(UDF_SB_VAT(sb));
1318 lengthHeader) + 1331 UDF_SB_TYPEVIRT(sb, i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
1319 udf_ext0_offset(UDF_SB_VAT(sb)); 1332 UDF_SB_TYPEVIRT(sb, i).s_start_offset) >> 2;
1320 UDF_SB_TYPEVIRT(sb, i).s_num_entries =
1321 (UDF_SB_VAT(sb)->i_size -
1322 UDF_SB_TYPEVIRT(sb, i).s_start_offset) >> 2;
1323 brelse(bh); 1333 brelse(bh);
1324 } 1334 }
1325 UDF_SB_PARTROOT(sb, i) = udf_get_pblock(sb, 0, i, 0); 1335 UDF_SB_PARTROOT(sb, i) = udf_get_pblock(sb, 0, i, 0);
1326 UDF_SB_PARTLEN(sb, i) = UDF_SB_PARTLEN(sb, 1336 UDF_SB_PARTLEN(sb, i) = UDF_SB_PARTLEN(sb, ino.partitionReferenceNum);
1327 ino.partitionReferenceNum);
1328 } 1337 }
1329 } 1338 }
1330 return 0; 1339 return 0;
@@ -1339,21 +1348,17 @@ static void udf_open_lvid(struct super_block *sb)
1339 UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; 1348 UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1340 UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; 1349 UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1341 if (udf_time_to_stamp(&cpu_time, CURRENT_TIME)) 1350 if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
1342 UDF_SB_LVID(sb)->recordingDateAndTime = 1351 UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
1343 cpu_to_lets(cpu_time);
1344 UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN; 1352 UDF_SB_LVID(sb)->integrityType = LVID_INTEGRITY_TYPE_OPEN;
1345 1353
1346 UDF_SB_LVID(sb)->descTag.descCRC = 1354 UDF_SB_LVID(sb)->descTag.descCRC = cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
1347 cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag), 1355 le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
1348 le16_to_cpu(UDF_SB_LVID(sb)->descTag.
1349 descCRCLength), 0));
1350 1356
1351 UDF_SB_LVID(sb)->descTag.tagChecksum = 0; 1357 UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
1352 for (i = 0; i < 16; i++) 1358 for (i = 0; i < 16; i++)
1353 if (i != 4) 1359 if (i != 4)
1354 UDF_SB_LVID(sb)->descTag.tagChecksum += 1360 UDF_SB_LVID(sb)->descTag.tagChecksum +=
1355 ((uint8_t *) & 1361 ((uint8_t *) &(UDF_SB_LVID(sb)->descTag))[i];
1356 (UDF_SB_LVID(sb)->descTag))[i];
1357 1362
1358 mark_buffer_dirty(UDF_SB_LVIDBH(sb)); 1363 mark_buffer_dirty(UDF_SB_LVIDBH(sb));
1359 } 1364 }
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index 3fd80eb66a..adcb87c2da 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -108,10 +108,10 @@ time_t *udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src)
108 *dest = year_seconds[src.year - EPOCH_YEAR]; 108 *dest = year_seconds[src.year - EPOCH_YEAR];
109 *dest -= offset * 60; 109 *dest -= offset * 60;
110 110
111 yday = ((__mon_yday[__isleap (src.year)] 111 yday = ((__mon_yday[__isleap(src.year)][src.month - 1]) + src.day - 1);
112 [src.month - 1]) + (src.day - 1)); 112 *dest += (((yday * 24) + src.hour) * 60 + src.minute) * 60 + src.second;
113 *dest += ( ( (yday * 24) + src.hour ) * 60 + src.minute ) * 60 + src.second; 113 *dest_usec = src.centiseconds * 10000 +
114 *dest_usec = src.centiseconds * 10000 + src.hundredsOfMicroseconds * 100 + src.microseconds; 114 src.hundredsOfMicroseconds * 100 + src.microseconds;
115 return dest; 115 return dest;
116} 116}
117 117