diff options
Diffstat (limited to 'fs/udf/inode.c')
| -rw-r--r-- | fs/udf/inode.c | 161 |
1 files changed, 76 insertions, 85 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 236cd48184c2..08598843288f 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
| @@ -51,7 +51,6 @@ MODULE_LICENSE("GPL"); | |||
| 51 | 51 | ||
| 52 | static umode_t udf_convert_permissions(struct fileEntry *); | 52 | static umode_t udf_convert_permissions(struct fileEntry *); |
| 53 | static int udf_update_inode(struct inode *, int); | 53 | static int udf_update_inode(struct inode *, int); |
| 54 | static void udf_fill_inode(struct inode *, struct buffer_head *); | ||
| 55 | static int udf_sync_inode(struct inode *inode); | 54 | static int udf_sync_inode(struct inode *inode); |
| 56 | static int udf_alloc_i_data(struct inode *inode, size_t size); | 55 | static int udf_alloc_i_data(struct inode *inode, size_t size); |
| 57 | static sector_t inode_getblk(struct inode *, sector_t, int *, int *); | 56 | static sector_t inode_getblk(struct inode *, sector_t, int *, int *); |
| @@ -1271,12 +1270,33 @@ update_time: | |||
| 1271 | return 0; | 1270 | return 0; |
| 1272 | } | 1271 | } |
| 1273 | 1272 | ||
| 1274 | static void __udf_read_inode(struct inode *inode) | 1273 | /* |
| 1274 | * Maximum length of linked list formed by ICB hierarchy. The chosen number is | ||
| 1275 | * arbitrary - just that we hopefully don't limit any real use of rewritten | ||
| 1276 | * inode on write-once media but avoid looping for too long on corrupted media. | ||
| 1277 | */ | ||
| 1278 | #define UDF_MAX_ICB_NESTING 1024 | ||
| 1279 | |||
| 1280 | static int udf_read_inode(struct inode *inode) | ||
| 1275 | { | 1281 | { |
| 1276 | struct buffer_head *bh = NULL; | 1282 | struct buffer_head *bh = NULL; |
| 1277 | struct fileEntry *fe; | 1283 | struct fileEntry *fe; |
| 1284 | struct extendedFileEntry *efe; | ||
| 1278 | uint16_t ident; | 1285 | uint16_t ident; |
| 1279 | struct udf_inode_info *iinfo = UDF_I(inode); | 1286 | struct udf_inode_info *iinfo = UDF_I(inode); |
| 1287 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); | ||
| 1288 | struct kernel_lb_addr *iloc = &iinfo->i_location; | ||
| 1289 | unsigned int link_count; | ||
| 1290 | unsigned int indirections = 0; | ||
| 1291 | int ret = -EIO; | ||
| 1292 | |||
| 1293 | reread: | ||
| 1294 | if (iloc->logicalBlockNum >= | ||
| 1295 | sbi->s_partmaps[iloc->partitionReferenceNum].s_partition_len) { | ||
| 1296 | udf_debug("block=%d, partition=%d out of range\n", | ||
| 1297 | iloc->logicalBlockNum, iloc->partitionReferenceNum); | ||
| 1298 | return -EIO; | ||
| 1299 | } | ||
| 1280 | 1300 | ||
| 1281 | /* | 1301 | /* |
| 1282 | * Set defaults, but the inode is still incomplete! | 1302 | * Set defaults, but the inode is still incomplete! |
| @@ -1290,78 +1310,54 @@ static void __udf_read_inode(struct inode *inode) | |||
| 1290 | * i_nlink = 1 | 1310 | * i_nlink = 1 |
| 1291 | * i_op = NULL; | 1311 | * i_op = NULL; |
| 1292 | */ | 1312 | */ |
| 1293 | bh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 0, &ident); | 1313 | bh = udf_read_ptagged(inode->i_sb, iloc, 0, &ident); |
| 1294 | if (!bh) { | 1314 | if (!bh) { |
| 1295 | udf_err(inode->i_sb, "(ino %ld) failed !bh\n", inode->i_ino); | 1315 | udf_err(inode->i_sb, "(ino %ld) failed !bh\n", inode->i_ino); |
| 1296 | make_bad_inode(inode); | 1316 | return -EIO; |
| 1297 | return; | ||
| 1298 | } | 1317 | } |
| 1299 | 1318 | ||
| 1300 | if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE && | 1319 | if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE && |
| 1301 | ident != TAG_IDENT_USE) { | 1320 | ident != TAG_IDENT_USE) { |
| 1302 | udf_err(inode->i_sb, "(ino %ld) failed ident=%d\n", | 1321 | udf_err(inode->i_sb, "(ino %ld) failed ident=%d\n", |
| 1303 | inode->i_ino, ident); | 1322 | inode->i_ino, ident); |
| 1304 | brelse(bh); | 1323 | goto out; |
| 1305 | make_bad_inode(inode); | ||
| 1306 | return; | ||
| 1307 | } | 1324 | } |
| 1308 | 1325 | ||
| 1309 | fe = (struct fileEntry *)bh->b_data; | 1326 | fe = (struct fileEntry *)bh->b_data; |
| 1327 | efe = (struct extendedFileEntry *)bh->b_data; | ||
| 1310 | 1328 | ||
| 1311 | if (fe->icbTag.strategyType == cpu_to_le16(4096)) { | 1329 | if (fe->icbTag.strategyType == cpu_to_le16(4096)) { |
| 1312 | struct buffer_head *ibh; | 1330 | struct buffer_head *ibh; |
| 1313 | 1331 | ||
| 1314 | ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1, | 1332 | ibh = udf_read_ptagged(inode->i_sb, iloc, 1, &ident); |
| 1315 | &ident); | ||
| 1316 | if (ident == TAG_IDENT_IE && ibh) { | 1333 | if (ident == TAG_IDENT_IE && ibh) { |
| 1317 | struct buffer_head *nbh = NULL; | ||
| 1318 | struct kernel_lb_addr loc; | 1334 | struct kernel_lb_addr loc; |
| 1319 | struct indirectEntry *ie; | 1335 | struct indirectEntry *ie; |
| 1320 | 1336 | ||
| 1321 | ie = (struct indirectEntry *)ibh->b_data; | 1337 | ie = (struct indirectEntry *)ibh->b_data; |
| 1322 | loc = lelb_to_cpu(ie->indirectICB.extLocation); | 1338 | loc = lelb_to_cpu(ie->indirectICB.extLocation); |
| 1323 | 1339 | ||
| 1324 | if (ie->indirectICB.extLength && | 1340 | if (ie->indirectICB.extLength) { |
| 1325 | (nbh = udf_read_ptagged(inode->i_sb, &loc, 0, | 1341 | brelse(ibh); |
| 1326 | &ident))) { | 1342 | memcpy(&iinfo->i_location, &loc, |
| 1327 | if (ident == TAG_IDENT_FE || | 1343 | sizeof(struct kernel_lb_addr)); |
| 1328 | ident == TAG_IDENT_EFE) { | 1344 | if (++indirections > UDF_MAX_ICB_NESTING) { |
| 1329 | memcpy(&iinfo->i_location, | 1345 | udf_err(inode->i_sb, |
| 1330 | &loc, | 1346 | "too many ICBs in ICB hierarchy" |
| 1331 | sizeof(struct kernel_lb_addr)); | 1347 | " (max %d supported)\n", |
| 1332 | brelse(bh); | 1348 | UDF_MAX_ICB_NESTING); |
| 1333 | brelse(ibh); | 1349 | goto out; |
| 1334 | brelse(nbh); | ||
| 1335 | __udf_read_inode(inode); | ||
| 1336 | return; | ||
| 1337 | } | 1350 | } |
| 1338 | brelse(nbh); | 1351 | brelse(bh); |
| 1352 | goto reread; | ||
| 1339 | } | 1353 | } |
| 1340 | } | 1354 | } |
| 1341 | brelse(ibh); | 1355 | brelse(ibh); |
| 1342 | } else if (fe->icbTag.strategyType != cpu_to_le16(4)) { | 1356 | } else if (fe->icbTag.strategyType != cpu_to_le16(4)) { |
| 1343 | udf_err(inode->i_sb, "unsupported strategy type: %d\n", | 1357 | udf_err(inode->i_sb, "unsupported strategy type: %d\n", |
| 1344 | le16_to_cpu(fe->icbTag.strategyType)); | 1358 | le16_to_cpu(fe->icbTag.strategyType)); |
| 1345 | brelse(bh); | 1359 | goto out; |
| 1346 | make_bad_inode(inode); | ||
| 1347 | return; | ||
| 1348 | } | 1360 | } |
| 1349 | udf_fill_inode(inode, bh); | ||
| 1350 | |||
| 1351 | brelse(bh); | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | ||
| 1355 | { | ||
| 1356 | struct fileEntry *fe; | ||
| 1357 | struct extendedFileEntry *efe; | ||
| 1358 | struct udf_sb_info *sbi = UDF_SB(inode->i_sb); | ||
| 1359 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
| 1360 | unsigned int link_count; | ||
| 1361 | |||
| 1362 | fe = (struct fileEntry *)bh->b_data; | ||
| 1363 | efe = (struct extendedFileEntry *)bh->b_data; | ||
| 1364 | |||
| 1365 | if (fe->icbTag.strategyType == cpu_to_le16(4)) | 1361 | if (fe->icbTag.strategyType == cpu_to_le16(4)) |
| 1366 | iinfo->i_strat4096 = 0; | 1362 | iinfo->i_strat4096 = 0; |
| 1367 | else /* if (fe->icbTag.strategyType == cpu_to_le16(4096)) */ | 1363 | else /* if (fe->icbTag.strategyType == cpu_to_le16(4096)) */ |
| @@ -1378,11 +1374,10 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
| 1378 | if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) { | 1374 | if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) { |
| 1379 | iinfo->i_efe = 1; | 1375 | iinfo->i_efe = 1; |
| 1380 | iinfo->i_use = 0; | 1376 | iinfo->i_use = 0; |
| 1381 | if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - | 1377 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - |
| 1382 | sizeof(struct extendedFileEntry))) { | 1378 | sizeof(struct extendedFileEntry)); |
| 1383 | make_bad_inode(inode); | 1379 | if (ret) |
| 1384 | return; | 1380 | goto out; |
| 1385 | } | ||
| 1386 | memcpy(iinfo->i_ext.i_data, | 1381 | memcpy(iinfo->i_ext.i_data, |
| 1387 | bh->b_data + sizeof(struct extendedFileEntry), | 1382 | bh->b_data + sizeof(struct extendedFileEntry), |
| 1388 | inode->i_sb->s_blocksize - | 1383 | inode->i_sb->s_blocksize - |
| @@ -1390,11 +1385,10 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
| 1390 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) { | 1385 | } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) { |
| 1391 | iinfo->i_efe = 0; | 1386 | iinfo->i_efe = 0; |
| 1392 | iinfo->i_use = 0; | 1387 | iinfo->i_use = 0; |
| 1393 | if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - | 1388 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - |
| 1394 | sizeof(struct fileEntry))) { | 1389 | sizeof(struct fileEntry)); |
| 1395 | make_bad_inode(inode); | 1390 | if (ret) |
| 1396 | return; | 1391 | goto out; |
| 1397 | } | ||
| 1398 | memcpy(iinfo->i_ext.i_data, | 1392 | memcpy(iinfo->i_ext.i_data, |
| 1399 | bh->b_data + sizeof(struct fileEntry), | 1393 | bh->b_data + sizeof(struct fileEntry), |
| 1400 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); | 1394 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); |
| @@ -1404,18 +1398,18 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
| 1404 | iinfo->i_lenAlloc = le32_to_cpu( | 1398 | iinfo->i_lenAlloc = le32_to_cpu( |
| 1405 | ((struct unallocSpaceEntry *)bh->b_data)-> | 1399 | ((struct unallocSpaceEntry *)bh->b_data)-> |
| 1406 | lengthAllocDescs); | 1400 | lengthAllocDescs); |
| 1407 | if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - | 1401 | ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize - |
| 1408 | sizeof(struct unallocSpaceEntry))) { | 1402 | sizeof(struct unallocSpaceEntry)); |
| 1409 | make_bad_inode(inode); | 1403 | if (ret) |
| 1410 | return; | 1404 | goto out; |
| 1411 | } | ||
| 1412 | memcpy(iinfo->i_ext.i_data, | 1405 | memcpy(iinfo->i_ext.i_data, |
| 1413 | bh->b_data + sizeof(struct unallocSpaceEntry), | 1406 | bh->b_data + sizeof(struct unallocSpaceEntry), |
| 1414 | inode->i_sb->s_blocksize - | 1407 | inode->i_sb->s_blocksize - |
| 1415 | sizeof(struct unallocSpaceEntry)); | 1408 | sizeof(struct unallocSpaceEntry)); |
| 1416 | return; | 1409 | return 0; |
| 1417 | } | 1410 | } |
| 1418 | 1411 | ||
| 1412 | ret = -EIO; | ||
| 1419 | read_lock(&sbi->s_cred_lock); | 1413 | read_lock(&sbi->s_cred_lock); |
| 1420 | i_uid_write(inode, le32_to_cpu(fe->uid)); | 1414 | i_uid_write(inode, le32_to_cpu(fe->uid)); |
| 1421 | if (!uid_valid(inode->i_uid) || | 1415 | if (!uid_valid(inode->i_uid) || |
| @@ -1441,8 +1435,10 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
| 1441 | read_unlock(&sbi->s_cred_lock); | 1435 | read_unlock(&sbi->s_cred_lock); |
| 1442 | 1436 | ||
| 1443 | link_count = le16_to_cpu(fe->fileLinkCount); | 1437 | link_count = le16_to_cpu(fe->fileLinkCount); |
| 1444 | if (!link_count) | 1438 | if (!link_count) { |
| 1445 | link_count = 1; | 1439 | ret = -ESTALE; |
| 1440 | goto out; | ||
| 1441 | } | ||
| 1446 | set_nlink(inode, link_count); | 1442 | set_nlink(inode, link_count); |
| 1447 | 1443 | ||
| 1448 | inode->i_size = le64_to_cpu(fe->informationLength); | 1444 | inode->i_size = le64_to_cpu(fe->informationLength); |
| @@ -1488,6 +1484,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
| 1488 | iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); | 1484 | iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); |
| 1489 | iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); | 1485 | iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); |
| 1490 | } | 1486 | } |
| 1487 | inode->i_generation = iinfo->i_unique; | ||
| 1491 | 1488 | ||
| 1492 | switch (fe->icbTag.fileType) { | 1489 | switch (fe->icbTag.fileType) { |
| 1493 | case ICBTAG_FILE_TYPE_DIRECTORY: | 1490 | case ICBTAG_FILE_TYPE_DIRECTORY: |
| @@ -1537,8 +1534,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
| 1537 | default: | 1534 | default: |
| 1538 | udf_err(inode->i_sb, "(ino %ld) failed unknown file type=%d\n", | 1535 | udf_err(inode->i_sb, "(ino %ld) failed unknown file type=%d\n", |
| 1539 | inode->i_ino, fe->icbTag.fileType); | 1536 | inode->i_ino, fe->icbTag.fileType); |
| 1540 | make_bad_inode(inode); | 1537 | goto out; |
| 1541 | return; | ||
| 1542 | } | 1538 | } |
| 1543 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { | 1539 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { |
| 1544 | struct deviceSpec *dsea = | 1540 | struct deviceSpec *dsea = |
| @@ -1549,8 +1545,12 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
| 1549 | le32_to_cpu(dsea->minorDeviceIdent))); | 1545 | le32_to_cpu(dsea->minorDeviceIdent))); |
| 1550 | /* Developer ID ??? */ | 1546 | /* Developer ID ??? */ |
| 1551 | } else | 1547 | } else |
| 1552 | make_bad_inode(inode); | 1548 | goto out; |
| 1553 | } | 1549 | } |
| 1550 | ret = 0; | ||
| 1551 | out: | ||
| 1552 | brelse(bh); | ||
| 1553 | return ret; | ||
| 1554 | } | 1554 | } |
| 1555 | 1555 | ||
| 1556 | static int udf_alloc_i_data(struct inode *inode, size_t size) | 1556 | static int udf_alloc_i_data(struct inode *inode, size_t size) |
| @@ -1664,7 +1664,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
| 1664 | FE_PERM_U_DELETE | FE_PERM_U_CHATTR)); | 1664 | FE_PERM_U_DELETE | FE_PERM_U_CHATTR)); |
| 1665 | fe->permissions = cpu_to_le32(udfperms); | 1665 | fe->permissions = cpu_to_le32(udfperms); |
| 1666 | 1666 | ||
| 1667 | if (S_ISDIR(inode->i_mode)) | 1667 | if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0) |
| 1668 | fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); | 1668 | fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1); |
| 1669 | else | 1669 | else |
| 1670 | fe->fileLinkCount = cpu_to_le16(inode->i_nlink); | 1670 | fe->fileLinkCount = cpu_to_le16(inode->i_nlink); |
| @@ -1830,32 +1830,23 @@ struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino) | |||
| 1830 | { | 1830 | { |
| 1831 | unsigned long block = udf_get_lb_pblock(sb, ino, 0); | 1831 | unsigned long block = udf_get_lb_pblock(sb, ino, 0); |
| 1832 | struct inode *inode = iget_locked(sb, block); | 1832 | struct inode *inode = iget_locked(sb, block); |
| 1833 | int err; | ||
| 1833 | 1834 | ||
| 1834 | if (!inode) | 1835 | if (!inode) |
| 1835 | return NULL; | 1836 | return ERR_PTR(-ENOMEM); |
| 1836 | |||
| 1837 | if (inode->i_state & I_NEW) { | ||
| 1838 | memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr)); | ||
| 1839 | __udf_read_inode(inode); | ||
| 1840 | unlock_new_inode(inode); | ||
| 1841 | } | ||
| 1842 | 1837 | ||
| 1843 | if (is_bad_inode(inode)) | 1838 | if (!(inode->i_state & I_NEW)) |
| 1844 | goto out_iput; | 1839 | return inode; |
| 1845 | 1840 | ||
| 1846 | if (ino->logicalBlockNum >= UDF_SB(sb)-> | 1841 | memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr)); |
| 1847 | s_partmaps[ino->partitionReferenceNum].s_partition_len) { | 1842 | err = udf_read_inode(inode); |
| 1848 | udf_debug("block=%d, partition=%d out of range\n", | 1843 | if (err < 0) { |
| 1849 | ino->logicalBlockNum, ino->partitionReferenceNum); | 1844 | iget_failed(inode); |
| 1850 | make_bad_inode(inode); | 1845 | return ERR_PTR(err); |
| 1851 | goto out_iput; | ||
| 1852 | } | 1846 | } |
| 1847 | unlock_new_inode(inode); | ||
| 1853 | 1848 | ||
| 1854 | return inode; | 1849 | return inode; |
| 1855 | |||
| 1856 | out_iput: | ||
| 1857 | iput(inode); | ||
| 1858 | return NULL; | ||
| 1859 | } | 1850 | } |
| 1860 | 1851 | ||
| 1861 | int udf_add_aext(struct inode *inode, struct extent_position *epos, | 1852 | int udf_add_aext(struct inode *inode, struct extent_position *epos, |
