.. | .. |
---|
45 | 45 | |
---|
46 | 46 | #define EXTENT_MERGE_SIZE 5 |
---|
47 | 47 | |
---|
| 48 | +#define FE_MAPPED_PERMS (FE_PERM_U_READ | FE_PERM_U_WRITE | FE_PERM_U_EXEC | \ |
---|
| 49 | + FE_PERM_G_READ | FE_PERM_G_WRITE | FE_PERM_G_EXEC | \ |
---|
| 50 | + FE_PERM_O_READ | FE_PERM_O_WRITE | FE_PERM_O_EXEC) |
---|
| 51 | + |
---|
| 52 | +#define FE_DELETE_PERMS (FE_PERM_U_DELETE | FE_PERM_G_DELETE | \ |
---|
| 53 | + FE_PERM_O_DELETE) |
---|
| 54 | + |
---|
48 | 55 | static umode_t udf_convert_permissions(struct fileEntry *); |
---|
49 | 56 | static int udf_update_inode(struct inode *, int); |
---|
50 | 57 | static int udf_sync_inode(struct inode *inode); |
---|
.. | .. |
---|
150 | 157 | truncate_inode_pages_final(&inode->i_data); |
---|
151 | 158 | invalidate_inode_buffers(inode); |
---|
152 | 159 | clear_inode(inode); |
---|
153 | | - kfree(iinfo->i_ext.i_data); |
---|
154 | | - iinfo->i_ext.i_data = NULL; |
---|
| 160 | + kfree(iinfo->i_data); |
---|
| 161 | + iinfo->i_data = NULL; |
---|
155 | 162 | udf_clear_extent_cache(inode); |
---|
156 | 163 | if (want_delete) { |
---|
157 | 164 | udf_free_inode(inode); |
---|
.. | .. |
---|
191 | 198 | return mpage_readpage(page, udf_get_block); |
---|
192 | 199 | } |
---|
193 | 200 | |
---|
194 | | -static int udf_readpages(struct file *file, struct address_space *mapping, |
---|
195 | | - struct list_head *pages, unsigned nr_pages) |
---|
| 201 | +static void udf_readahead(struct readahead_control *rac) |
---|
196 | 202 | { |
---|
197 | | - return mpage_readpages(mapping, pages, nr_pages, udf_get_block); |
---|
| 203 | + mpage_readahead(rac, udf_get_block); |
---|
198 | 204 | } |
---|
199 | 205 | |
---|
200 | 206 | static int udf_write_begin(struct file *file, struct address_space *mapping, |
---|
.. | .. |
---|
230 | 236 | |
---|
231 | 237 | const struct address_space_operations udf_aops = { |
---|
232 | 238 | .readpage = udf_readpage, |
---|
233 | | - .readpages = udf_readpages, |
---|
| 239 | + .readahead = udf_readahead, |
---|
234 | 240 | .writepage = udf_writepage, |
---|
235 | 241 | .writepages = udf_writepages, |
---|
236 | 242 | .write_begin = udf_write_begin, |
---|
.. | .. |
---|
278 | 284 | kaddr = kmap_atomic(page); |
---|
279 | 285 | memset(kaddr + iinfo->i_lenAlloc, 0x00, |
---|
280 | 286 | PAGE_SIZE - iinfo->i_lenAlloc); |
---|
281 | | - memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, |
---|
| 287 | + memcpy(kaddr, iinfo->i_data + iinfo->i_lenEAttr, |
---|
282 | 288 | iinfo->i_lenAlloc); |
---|
283 | 289 | flush_dcache_page(page); |
---|
284 | 290 | SetPageUptodate(page); |
---|
285 | 291 | kunmap_atomic(kaddr); |
---|
286 | 292 | } |
---|
287 | 293 | down_write(&iinfo->i_data_sem); |
---|
288 | | - memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00, |
---|
| 294 | + memset(iinfo->i_data + iinfo->i_lenEAttr, 0x00, |
---|
289 | 295 | iinfo->i_lenAlloc); |
---|
290 | 296 | iinfo->i_lenAlloc = 0; |
---|
291 | 297 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) |
---|
.. | .. |
---|
303 | 309 | lock_page(page); |
---|
304 | 310 | down_write(&iinfo->i_data_sem); |
---|
305 | 311 | kaddr = kmap_atomic(page); |
---|
306 | | - memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr, |
---|
307 | | - inode->i_size); |
---|
| 312 | + memcpy(iinfo->i_data + iinfo->i_lenEAttr, kaddr, inode->i_size); |
---|
308 | 313 | kunmap_atomic(kaddr); |
---|
309 | 314 | unlock_page(page); |
---|
310 | 315 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; |
---|
.. | .. |
---|
392 | 397 | } |
---|
393 | 398 | mark_buffer_dirty_inode(dbh, inode); |
---|
394 | 399 | |
---|
395 | | - memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0, |
---|
396 | | - iinfo->i_lenAlloc); |
---|
| 400 | + memset(iinfo->i_data + iinfo->i_lenEAttr, 0, iinfo->i_lenAlloc); |
---|
397 | 401 | iinfo->i_lenAlloc = 0; |
---|
398 | 402 | eloc.logicalBlockNum = *block; |
---|
399 | 403 | eloc.partitionReferenceNum = |
---|
.. | .. |
---|
1259 | 1263 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
---|
1260 | 1264 | down_write(&iinfo->i_data_sem); |
---|
1261 | 1265 | udf_clear_extent_cache(inode); |
---|
1262 | | - memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize, |
---|
| 1266 | + memset(iinfo->i_data + iinfo->i_lenEAttr + newsize, |
---|
1263 | 1267 | 0x00, bsize - newsize - |
---|
1264 | 1268 | udf_file_entry_alloc_offset(inode)); |
---|
1265 | 1269 | iinfo->i_lenAlloc = newsize; |
---|
.. | .. |
---|
1274 | 1278 | truncate_setsize(inode, newsize); |
---|
1275 | 1279 | down_write(&iinfo->i_data_sem); |
---|
1276 | 1280 | udf_clear_extent_cache(inode); |
---|
1277 | | - udf_truncate_extents(inode); |
---|
| 1281 | + err = udf_truncate_extents(inode); |
---|
1278 | 1282 | up_write(&iinfo->i_data_sem); |
---|
| 1283 | + if (err) |
---|
| 1284 | + return err; |
---|
1279 | 1285 | } |
---|
1280 | 1286 | update_time: |
---|
1281 | 1287 | inode->i_mtime = inode->i_ctime = current_time(inode); |
---|
.. | .. |
---|
1408 | 1414 | sizeof(struct extendedFileEntry)); |
---|
1409 | 1415 | if (ret) |
---|
1410 | 1416 | goto out; |
---|
1411 | | - memcpy(iinfo->i_ext.i_data, |
---|
| 1417 | + memcpy(iinfo->i_data, |
---|
1412 | 1418 | bh->b_data + sizeof(struct extendedFileEntry), |
---|
1413 | 1419 | bs - sizeof(struct extendedFileEntry)); |
---|
1414 | 1420 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) { |
---|
.. | .. |
---|
1417 | 1423 | ret = udf_alloc_i_data(inode, bs - sizeof(struct fileEntry)); |
---|
1418 | 1424 | if (ret) |
---|
1419 | 1425 | goto out; |
---|
1420 | | - memcpy(iinfo->i_ext.i_data, |
---|
| 1426 | + memcpy(iinfo->i_data, |
---|
1421 | 1427 | bh->b_data + sizeof(struct fileEntry), |
---|
1422 | 1428 | bs - sizeof(struct fileEntry)); |
---|
1423 | 1429 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) { |
---|
.. | .. |
---|
1430 | 1436 | sizeof(struct unallocSpaceEntry)); |
---|
1431 | 1437 | if (ret) |
---|
1432 | 1438 | goto out; |
---|
1433 | | - memcpy(iinfo->i_ext.i_data, |
---|
| 1439 | + memcpy(iinfo->i_data, |
---|
1434 | 1440 | bh->b_data + sizeof(struct unallocSpaceEntry), |
---|
1435 | 1441 | bs - sizeof(struct unallocSpaceEntry)); |
---|
1436 | 1442 | return 0; |
---|
.. | .. |
---|
1461 | 1467 | else |
---|
1462 | 1468 | inode->i_mode = udf_convert_permissions(fe); |
---|
1463 | 1469 | inode->i_mode &= ~sbi->s_umask; |
---|
| 1470 | + iinfo->i_extraPerms = le32_to_cpu(fe->permissions) & ~FE_MAPPED_PERMS; |
---|
| 1471 | + |
---|
1464 | 1472 | read_unlock(&sbi->s_cred_lock); |
---|
1465 | 1473 | |
---|
1466 | 1474 | link_count = le16_to_cpu(fe->fileLinkCount); |
---|
.. | .. |
---|
1488 | 1496 | iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); |
---|
1489 | 1497 | iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs); |
---|
1490 | 1498 | iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint); |
---|
| 1499 | + iinfo->i_streamdir = 0; |
---|
| 1500 | + iinfo->i_lenStreams = 0; |
---|
1491 | 1501 | } else { |
---|
1492 | 1502 | inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << |
---|
1493 | 1503 | (inode->i_sb->s_blocksize_bits - 9); |
---|
.. | .. |
---|
1501 | 1511 | iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); |
---|
1502 | 1512 | iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); |
---|
1503 | 1513 | iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); |
---|
| 1514 | + |
---|
| 1515 | + /* Named streams */ |
---|
| 1516 | + iinfo->i_streamdir = (efe->streamDirectoryICB.extLength != 0); |
---|
| 1517 | + iinfo->i_locStreamdir = |
---|
| 1518 | + lelb_to_cpu(efe->streamDirectoryICB.extLocation); |
---|
| 1519 | + iinfo->i_lenStreams = le64_to_cpu(efe->objectSize); |
---|
| 1520 | + if (iinfo->i_lenStreams >= inode->i_size) |
---|
| 1521 | + iinfo->i_lenStreams -= inode->i_size; |
---|
| 1522 | + else |
---|
| 1523 | + iinfo->i_lenStreams = 0; |
---|
1504 | 1524 | } |
---|
1505 | 1525 | inode->i_generation = iinfo->i_unique; |
---|
1506 | 1526 | |
---|
.. | .. |
---|
1597 | 1617 | static int udf_alloc_i_data(struct inode *inode, size_t size) |
---|
1598 | 1618 | { |
---|
1599 | 1619 | struct udf_inode_info *iinfo = UDF_I(inode); |
---|
1600 | | - iinfo->i_ext.i_data = kmalloc(size, GFP_KERNEL); |
---|
1601 | | - if (!iinfo->i_ext.i_data) |
---|
| 1620 | + iinfo->i_data = kmalloc(size, GFP_KERNEL); |
---|
| 1621 | + if (!iinfo->i_data) |
---|
1602 | 1622 | return -ENOMEM; |
---|
1603 | 1623 | return 0; |
---|
1604 | 1624 | } |
---|
.. | .. |
---|
1620 | 1640 | ((flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0); |
---|
1621 | 1641 | |
---|
1622 | 1642 | return mode; |
---|
| 1643 | +} |
---|
| 1644 | + |
---|
| 1645 | +void udf_update_extra_perms(struct inode *inode, umode_t mode) |
---|
| 1646 | +{ |
---|
| 1647 | + struct udf_inode_info *iinfo = UDF_I(inode); |
---|
| 1648 | + |
---|
| 1649 | + /* |
---|
| 1650 | + * UDF 2.01 sec. 3.3.3.3 Note 2: |
---|
| 1651 | + * In Unix, delete permission tracks write |
---|
| 1652 | + */ |
---|
| 1653 | + iinfo->i_extraPerms &= ~FE_DELETE_PERMS; |
---|
| 1654 | + if (mode & 0200) |
---|
| 1655 | + iinfo->i_extraPerms |= FE_PERM_U_DELETE; |
---|
| 1656 | + if (mode & 0020) |
---|
| 1657 | + iinfo->i_extraPerms |= FE_PERM_G_DELETE; |
---|
| 1658 | + if (mode & 0002) |
---|
| 1659 | + iinfo->i_extraPerms |= FE_PERM_O_DELETE; |
---|
1623 | 1660 | } |
---|
1624 | 1661 | |
---|
1625 | 1662 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) |
---|
.. | .. |
---|
1672 | 1709 | |
---|
1673 | 1710 | use->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); |
---|
1674 | 1711 | memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), |
---|
1675 | | - iinfo->i_ext.i_data, inode->i_sb->s_blocksize - |
---|
| 1712 | + iinfo->i_data, inode->i_sb->s_blocksize - |
---|
1676 | 1713 | sizeof(struct unallocSpaceEntry)); |
---|
1677 | 1714 | use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE); |
---|
1678 | 1715 | crclen = sizeof(struct unallocSpaceEntry); |
---|
.. | .. |
---|
1694 | 1731 | ((inode->i_mode & 0070) << 2) | |
---|
1695 | 1732 | ((inode->i_mode & 0700) << 4); |
---|
1696 | 1733 | |
---|
1697 | | - udfperms |= (le32_to_cpu(fe->permissions) & |
---|
1698 | | - (FE_PERM_O_DELETE | FE_PERM_O_CHATTR | |
---|
1699 | | - FE_PERM_G_DELETE | FE_PERM_G_CHATTR | |
---|
1700 | | - FE_PERM_U_DELETE | FE_PERM_U_CHATTR)); |
---|
| 1734 | + udfperms |= iinfo->i_extraPerms; |
---|
1701 | 1735 | fe->permissions = cpu_to_le32(udfperms); |
---|
1702 | 1736 | |
---|
1703 | 1737 | if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) |
---|
.. | .. |
---|
1741 | 1775 | |
---|
1742 | 1776 | if (iinfo->i_efe == 0) { |
---|
1743 | 1777 | memcpy(bh->b_data + sizeof(struct fileEntry), |
---|
1744 | | - iinfo->i_ext.i_data, |
---|
| 1778 | + iinfo->i_data, |
---|
1745 | 1779 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); |
---|
1746 | 1780 | fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); |
---|
1747 | 1781 | |
---|
.. | .. |
---|
1760 | 1794 | crclen = sizeof(struct fileEntry); |
---|
1761 | 1795 | } else { |
---|
1762 | 1796 | memcpy(bh->b_data + sizeof(struct extendedFileEntry), |
---|
1763 | | - iinfo->i_ext.i_data, |
---|
| 1797 | + iinfo->i_data, |
---|
1764 | 1798 | inode->i_sb->s_blocksize - |
---|
1765 | 1799 | sizeof(struct extendedFileEntry)); |
---|
1766 | | - efe->objectSize = cpu_to_le64(inode->i_size); |
---|
| 1800 | + efe->objectSize = |
---|
| 1801 | + cpu_to_le64(inode->i_size + iinfo->i_lenStreams); |
---|
1767 | 1802 | efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); |
---|
| 1803 | + |
---|
| 1804 | + if (iinfo->i_streamdir) { |
---|
| 1805 | + struct long_ad *icb_lad = &efe->streamDirectoryICB; |
---|
| 1806 | + |
---|
| 1807 | + icb_lad->extLocation = |
---|
| 1808 | + cpu_to_lelb(iinfo->i_locStreamdir); |
---|
| 1809 | + icb_lad->extLength = |
---|
| 1810 | + cpu_to_le32(inode->i_sb->s_blocksize); |
---|
| 1811 | + } |
---|
1768 | 1812 | |
---|
1769 | 1813 | udf_adjust_time(iinfo, inode->i_atime); |
---|
1770 | 1814 | udf_adjust_time(iinfo, inode->i_mtime); |
---|
.. | .. |
---|
1939 | 1983 | |
---|
1940 | 1984 | __udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1); |
---|
1941 | 1985 | udf_write_aext(inode, epos, &nepos.block, |
---|
1942 | | - sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDECS, 0); |
---|
| 1986 | + sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDESCS, 0); |
---|
1943 | 1987 | } else { |
---|
1944 | 1988 | __udf_add_aext(inode, epos, &nepos.block, |
---|
1945 | | - sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDECS, 0); |
---|
| 1989 | + sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDESCS, 0); |
---|
1946 | 1990 | } |
---|
1947 | 1991 | |
---|
1948 | 1992 | brelse(epos->bh); |
---|
.. | .. |
---|
2046 | 2090 | struct udf_inode_info *iinfo = UDF_I(inode); |
---|
2047 | 2091 | |
---|
2048 | 2092 | if (!epos->bh) |
---|
2049 | | - ptr = iinfo->i_ext.i_data + epos->offset - |
---|
| 2093 | + ptr = iinfo->i_data + epos->offset - |
---|
2050 | 2094 | udf_file_entry_alloc_offset(inode) + |
---|
2051 | 2095 | iinfo->i_lenEAttr; |
---|
2052 | 2096 | else |
---|
.. | .. |
---|
2101 | 2145 | unsigned int indirections = 0; |
---|
2102 | 2146 | |
---|
2103 | 2147 | while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == |
---|
2104 | | - (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { |
---|
| 2148 | + (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) { |
---|
2105 | 2149 | udf_pblk_t block; |
---|
2106 | 2150 | |
---|
2107 | 2151 | if (++indirections > UDF_MAX_INDIR_EXTS) { |
---|
.. | .. |
---|
2138 | 2182 | if (!epos->bh) { |
---|
2139 | 2183 | if (!epos->offset) |
---|
2140 | 2184 | epos->offset = udf_file_entry_alloc_offset(inode); |
---|
2141 | | - ptr = iinfo->i_ext.i_data + epos->offset - |
---|
| 2185 | + ptr = iinfo->i_data + epos->offset - |
---|
2142 | 2186 | udf_file_entry_alloc_offset(inode) + |
---|
2143 | 2187 | iinfo->i_lenEAttr; |
---|
2144 | 2188 | alen = udf_file_entry_alloc_offset(inode) + |
---|