hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/fs/udf/inode.c
....@@ -45,6 +45,13 @@
4545
4646 #define EXTENT_MERGE_SIZE 5
4747
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
+
4855 static umode_t udf_convert_permissions(struct fileEntry *);
4956 static int udf_update_inode(struct inode *, int);
5057 static int udf_sync_inode(struct inode *inode);
....@@ -150,8 +157,8 @@
150157 truncate_inode_pages_final(&inode->i_data);
151158 invalidate_inode_buffers(inode);
152159 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;
155162 udf_clear_extent_cache(inode);
156163 if (want_delete) {
157164 udf_free_inode(inode);
....@@ -191,10 +198,9 @@
191198 return mpage_readpage(page, udf_get_block);
192199 }
193200
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)
196202 {
197
- return mpage_readpages(mapping, pages, nr_pages, udf_get_block);
203
+ mpage_readahead(rac, udf_get_block);
198204 }
199205
200206 static int udf_write_begin(struct file *file, struct address_space *mapping,
....@@ -230,7 +236,7 @@
230236
231237 const struct address_space_operations udf_aops = {
232238 .readpage = udf_readpage,
233
- .readpages = udf_readpages,
239
+ .readahead = udf_readahead,
234240 .writepage = udf_writepage,
235241 .writepages = udf_writepages,
236242 .write_begin = udf_write_begin,
....@@ -278,14 +284,14 @@
278284 kaddr = kmap_atomic(page);
279285 memset(kaddr + iinfo->i_lenAlloc, 0x00,
280286 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,
282288 iinfo->i_lenAlloc);
283289 flush_dcache_page(page);
284290 SetPageUptodate(page);
285291 kunmap_atomic(kaddr);
286292 }
287293 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,
289295 iinfo->i_lenAlloc);
290296 iinfo->i_lenAlloc = 0;
291297 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
....@@ -303,8 +309,7 @@
303309 lock_page(page);
304310 down_write(&iinfo->i_data_sem);
305311 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);
308313 kunmap_atomic(kaddr);
309314 unlock_page(page);
310315 iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
....@@ -392,8 +397,7 @@
392397 }
393398 mark_buffer_dirty_inode(dbh, inode);
394399
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);
397401 iinfo->i_lenAlloc = 0;
398402 eloc.logicalBlockNum = *block;
399403 eloc.partitionReferenceNum =
....@@ -1259,7 +1263,7 @@
12591263 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
12601264 down_write(&iinfo->i_data_sem);
12611265 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,
12631267 0x00, bsize - newsize -
12641268 udf_file_entry_alloc_offset(inode));
12651269 iinfo->i_lenAlloc = newsize;
....@@ -1274,8 +1278,10 @@
12741278 truncate_setsize(inode, newsize);
12751279 down_write(&iinfo->i_data_sem);
12761280 udf_clear_extent_cache(inode);
1277
- udf_truncate_extents(inode);
1281
+ err = udf_truncate_extents(inode);
12781282 up_write(&iinfo->i_data_sem);
1283
+ if (err)
1284
+ return err;
12791285 }
12801286 update_time:
12811287 inode->i_mtime = inode->i_ctime = current_time(inode);
....@@ -1408,7 +1414,7 @@
14081414 sizeof(struct extendedFileEntry));
14091415 if (ret)
14101416 goto out;
1411
- memcpy(iinfo->i_ext.i_data,
1417
+ memcpy(iinfo->i_data,
14121418 bh->b_data + sizeof(struct extendedFileEntry),
14131419 bs - sizeof(struct extendedFileEntry));
14141420 } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) {
....@@ -1417,7 +1423,7 @@
14171423 ret = udf_alloc_i_data(inode, bs - sizeof(struct fileEntry));
14181424 if (ret)
14191425 goto out;
1420
- memcpy(iinfo->i_ext.i_data,
1426
+ memcpy(iinfo->i_data,
14211427 bh->b_data + sizeof(struct fileEntry),
14221428 bs - sizeof(struct fileEntry));
14231429 } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) {
....@@ -1430,7 +1436,7 @@
14301436 sizeof(struct unallocSpaceEntry));
14311437 if (ret)
14321438 goto out;
1433
- memcpy(iinfo->i_ext.i_data,
1439
+ memcpy(iinfo->i_data,
14341440 bh->b_data + sizeof(struct unallocSpaceEntry),
14351441 bs - sizeof(struct unallocSpaceEntry));
14361442 return 0;
....@@ -1461,6 +1467,8 @@
14611467 else
14621468 inode->i_mode = udf_convert_permissions(fe);
14631469 inode->i_mode &= ~sbi->s_umask;
1470
+ iinfo->i_extraPerms = le32_to_cpu(fe->permissions) & ~FE_MAPPED_PERMS;
1471
+
14641472 read_unlock(&sbi->s_cred_lock);
14651473
14661474 link_count = le16_to_cpu(fe->fileLinkCount);
....@@ -1488,6 +1496,8 @@
14881496 iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
14891497 iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs);
14901498 iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint);
1499
+ iinfo->i_streamdir = 0;
1500
+ iinfo->i_lenStreams = 0;
14911501 } else {
14921502 inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
14931503 (inode->i_sb->s_blocksize_bits - 9);
....@@ -1501,6 +1511,16 @@
15011511 iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
15021512 iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs);
15031513 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;
15041524 }
15051525 inode->i_generation = iinfo->i_unique;
15061526
....@@ -1597,8 +1617,8 @@
15971617 static int udf_alloc_i_data(struct inode *inode, size_t size)
15981618 {
15991619 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)
16021622 return -ENOMEM;
16031623 return 0;
16041624 }
....@@ -1620,6 +1640,23 @@
16201640 ((flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);
16211641
16221642 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;
16231660 }
16241661
16251662 int udf_write_inode(struct inode *inode, struct writeback_control *wbc)
....@@ -1672,7 +1709,7 @@
16721709
16731710 use->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
16741711 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 -
16761713 sizeof(struct unallocSpaceEntry));
16771714 use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE);
16781715 crclen = sizeof(struct unallocSpaceEntry);
....@@ -1694,10 +1731,7 @@
16941731 ((inode->i_mode & 0070) << 2) |
16951732 ((inode->i_mode & 0700) << 4);
16961733
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;
17011735 fe->permissions = cpu_to_le32(udfperms);
17021736
17031737 if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0)
....@@ -1741,7 +1775,7 @@
17411775
17421776 if (iinfo->i_efe == 0) {
17431777 memcpy(bh->b_data + sizeof(struct fileEntry),
1744
- iinfo->i_ext.i_data,
1778
+ iinfo->i_data,
17451779 inode->i_sb->s_blocksize - sizeof(struct fileEntry));
17461780 fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
17471781
....@@ -1760,11 +1794,21 @@
17601794 crclen = sizeof(struct fileEntry);
17611795 } else {
17621796 memcpy(bh->b_data + sizeof(struct extendedFileEntry),
1763
- iinfo->i_ext.i_data,
1797
+ iinfo->i_data,
17641798 inode->i_sb->s_blocksize -
17651799 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);
17671802 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
+ }
17681812
17691813 udf_adjust_time(iinfo, inode->i_atime);
17701814 udf_adjust_time(iinfo, inode->i_mtime);
....@@ -1939,10 +1983,10 @@
19391983
19401984 __udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1);
19411985 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);
19431987 } else {
19441988 __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);
19461990 }
19471991
19481992 brelse(epos->bh);
....@@ -2046,7 +2090,7 @@
20462090 struct udf_inode_info *iinfo = UDF_I(inode);
20472091
20482092 if (!epos->bh)
2049
- ptr = iinfo->i_ext.i_data + epos->offset -
2093
+ ptr = iinfo->i_data + epos->offset -
20502094 udf_file_entry_alloc_offset(inode) +
20512095 iinfo->i_lenEAttr;
20522096 else
....@@ -2101,7 +2145,7 @@
21012145 unsigned int indirections = 0;
21022146
21032147 while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
2104
- (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
2148
+ (EXT_NEXT_EXTENT_ALLOCDESCS >> 30)) {
21052149 udf_pblk_t block;
21062150
21072151 if (++indirections > UDF_MAX_INDIR_EXTS) {
....@@ -2138,7 +2182,7 @@
21382182 if (!epos->bh) {
21392183 if (!epos->offset)
21402184 epos->offset = udf_file_entry_alloc_offset(inode);
2141
- ptr = iinfo->i_ext.i_data + epos->offset -
2185
+ ptr = iinfo->i_data + epos->offset -
21422186 udf_file_entry_alloc_offset(inode) +
21432187 iinfo->i_lenEAttr;
21442188 alen = udf_file_entry_alloc_offset(inode) +