diff options
Diffstat (limited to 'fs/udf/namei.c')
| -rw-r--r-- | fs/udf/namei.c | 156 |
1 files changed, 54 insertions, 102 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 9737cba1357d..c12e260fd6c4 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
| @@ -270,9 +270,8 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | |||
| 270 | NULL, 0), | 270 | NULL, 0), |
| 271 | }; | 271 | }; |
| 272 | inode = udf_iget(dir->i_sb, lb); | 272 | inode = udf_iget(dir->i_sb, lb); |
| 273 | if (!inode) { | 273 | if (IS_ERR(inode)) |
| 274 | return ERR_PTR(-EACCES); | 274 | return inode; |
| 275 | } | ||
| 276 | } else | 275 | } else |
| 277 | #endif /* UDF_RECOVERY */ | 276 | #endif /* UDF_RECOVERY */ |
| 278 | 277 | ||
| @@ -285,9 +284,8 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry, | |||
| 285 | 284 | ||
| 286 | loc = lelb_to_cpu(cfi.icb.extLocation); | 285 | loc = lelb_to_cpu(cfi.icb.extLocation); |
| 287 | inode = udf_iget(dir->i_sb, &loc); | 286 | inode = udf_iget(dir->i_sb, &loc); |
| 288 | if (!inode) { | 287 | if (IS_ERR(inode)) |
| 289 | return ERR_PTR(-EACCES); | 288 | return ERR_CAST(inode); |
| 290 | } | ||
| 291 | } | 289 | } |
| 292 | 290 | ||
| 293 | return d_splice_alias(inode, dentry); | 291 | return d_splice_alias(inode, dentry); |
| @@ -550,32 +548,18 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, | |||
| 550 | return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); | 548 | return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); |
| 551 | } | 549 | } |
| 552 | 550 | ||
| 553 | static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 551 | static int udf_add_nondir(struct dentry *dentry, struct inode *inode) |
| 554 | bool excl) | ||
| 555 | { | 552 | { |
| 553 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
| 554 | struct inode *dir = dentry->d_parent->d_inode; | ||
| 556 | struct udf_fileident_bh fibh; | 555 | struct udf_fileident_bh fibh; |
| 557 | struct inode *inode; | ||
| 558 | struct fileIdentDesc cfi, *fi; | 556 | struct fileIdentDesc cfi, *fi; |
| 559 | int err; | 557 | int err; |
| 560 | struct udf_inode_info *iinfo; | ||
| 561 | |||
| 562 | inode = udf_new_inode(dir, mode, &err); | ||
| 563 | if (!inode) { | ||
| 564 | return err; | ||
| 565 | } | ||
| 566 | |||
| 567 | iinfo = UDF_I(inode); | ||
| 568 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
| 569 | inode->i_data.a_ops = &udf_adinicb_aops; | ||
| 570 | else | ||
| 571 | inode->i_data.a_ops = &udf_aops; | ||
| 572 | inode->i_op = &udf_file_inode_operations; | ||
| 573 | inode->i_fop = &udf_file_operations; | ||
| 574 | mark_inode_dirty(inode); | ||
| 575 | 558 | ||
| 576 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 559 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
| 577 | if (!fi) { | 560 | if (unlikely(!fi)) { |
| 578 | inode_dec_link_count(inode); | 561 | inode_dec_link_count(inode); |
| 562 | unlock_new_inode(inode); | ||
| 579 | iput(inode); | 563 | iput(inode); |
| 580 | return err; | 564 | return err; |
| 581 | } | 565 | } |
| @@ -589,23 +573,21 @@ static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
| 589 | if (fibh.sbh != fibh.ebh) | 573 | if (fibh.sbh != fibh.ebh) |
| 590 | brelse(fibh.ebh); | 574 | brelse(fibh.ebh); |
| 591 | brelse(fibh.sbh); | 575 | brelse(fibh.sbh); |
| 576 | unlock_new_inode(inode); | ||
| 592 | d_instantiate(dentry, inode); | 577 | d_instantiate(dentry, inode); |
| 593 | 578 | ||
| 594 | return 0; | 579 | return 0; |
| 595 | } | 580 | } |
| 596 | 581 | ||
| 597 | static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | 582 | static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
| 583 | bool excl) | ||
| 598 | { | 584 | { |
| 599 | struct inode *inode; | 585 | struct inode *inode = udf_new_inode(dir, mode); |
| 600 | struct udf_inode_info *iinfo; | ||
| 601 | int err; | ||
| 602 | 586 | ||
| 603 | inode = udf_new_inode(dir, mode, &err); | 587 | if (IS_ERR(inode)) |
| 604 | if (!inode) | 588 | return PTR_ERR(inode); |
| 605 | return err; | ||
| 606 | 589 | ||
| 607 | iinfo = UDF_I(inode); | 590 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
| 608 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
| 609 | inode->i_data.a_ops = &udf_adinicb_aops; | 591 | inode->i_data.a_ops = &udf_adinicb_aops; |
| 610 | else | 592 | else |
| 611 | inode->i_data.a_ops = &udf_aops; | 593 | inode->i_data.a_ops = &udf_aops; |
| @@ -613,7 +595,25 @@ static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 613 | inode->i_fop = &udf_file_operations; | 595 | inode->i_fop = &udf_file_operations; |
| 614 | mark_inode_dirty(inode); | 596 | mark_inode_dirty(inode); |
| 615 | 597 | ||
| 598 | return udf_add_nondir(dentry, inode); | ||
| 599 | } | ||
| 600 | |||
| 601 | static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||
| 602 | { | ||
| 603 | struct inode *inode = udf_new_inode(dir, mode); | ||
| 604 | |||
| 605 | if (IS_ERR(inode)) | ||
| 606 | return PTR_ERR(inode); | ||
| 607 | |||
| 608 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
| 609 | inode->i_data.a_ops = &udf_adinicb_aops; | ||
| 610 | else | ||
| 611 | inode->i_data.a_ops = &udf_aops; | ||
| 612 | inode->i_op = &udf_file_inode_operations; | ||
| 613 | inode->i_fop = &udf_file_operations; | ||
| 614 | mark_inode_dirty(inode); | ||
| 616 | d_tmpfile(dentry, inode); | 615 | d_tmpfile(dentry, inode); |
| 616 | unlock_new_inode(inode); | ||
| 617 | return 0; | 617 | return 0; |
| 618 | } | 618 | } |
| 619 | 619 | ||
| @@ -621,44 +621,16 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
| 621 | dev_t rdev) | 621 | dev_t rdev) |
| 622 | { | 622 | { |
| 623 | struct inode *inode; | 623 | struct inode *inode; |
| 624 | struct udf_fileident_bh fibh; | ||
| 625 | struct fileIdentDesc cfi, *fi; | ||
| 626 | int err; | ||
| 627 | struct udf_inode_info *iinfo; | ||
| 628 | 624 | ||
| 629 | if (!old_valid_dev(rdev)) | 625 | if (!old_valid_dev(rdev)) |
| 630 | return -EINVAL; | 626 | return -EINVAL; |
| 631 | 627 | ||
| 632 | err = -EIO; | 628 | inode = udf_new_inode(dir, mode); |
| 633 | inode = udf_new_inode(dir, mode, &err); | 629 | if (IS_ERR(inode)) |
| 634 | if (!inode) | 630 | return PTR_ERR(inode); |
| 635 | goto out; | ||
| 636 | 631 | ||
| 637 | iinfo = UDF_I(inode); | ||
| 638 | init_special_inode(inode, mode, rdev); | 632 | init_special_inode(inode, mode, rdev); |
| 639 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 633 | return udf_add_nondir(dentry, inode); |
| 640 | if (!fi) { | ||
| 641 | inode_dec_link_count(inode); | ||
| 642 | iput(inode); | ||
| 643 | return err; | ||
| 644 | } | ||
| 645 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | ||
| 646 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | ||
| 647 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | ||
| 648 | cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL); | ||
| 649 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | ||
| 650 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
| 651 | mark_inode_dirty(dir); | ||
| 652 | mark_inode_dirty(inode); | ||
| 653 | |||
| 654 | if (fibh.sbh != fibh.ebh) | ||
| 655 | brelse(fibh.ebh); | ||
| 656 | brelse(fibh.sbh); | ||
| 657 | d_instantiate(dentry, inode); | ||
| 658 | err = 0; | ||
| 659 | |||
| 660 | out: | ||
| 661 | return err; | ||
| 662 | } | 634 | } |
| 663 | 635 | ||
| 664 | static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 636 | static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
| @@ -670,10 +642,9 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 670 | struct udf_inode_info *dinfo = UDF_I(dir); | 642 | struct udf_inode_info *dinfo = UDF_I(dir); |
| 671 | struct udf_inode_info *iinfo; | 643 | struct udf_inode_info *iinfo; |
| 672 | 644 | ||
| 673 | err = -EIO; | 645 | inode = udf_new_inode(dir, S_IFDIR | mode); |
| 674 | inode = udf_new_inode(dir, S_IFDIR | mode, &err); | 646 | if (IS_ERR(inode)) |
| 675 | if (!inode) | 647 | return PTR_ERR(inode); |
| 676 | goto out; | ||
| 677 | 648 | ||
| 678 | iinfo = UDF_I(inode); | 649 | iinfo = UDF_I(inode); |
| 679 | inode->i_op = &udf_dir_inode_operations; | 650 | inode->i_op = &udf_dir_inode_operations; |
| @@ -681,6 +652,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 681 | fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err); | 652 | fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err); |
| 682 | if (!fi) { | 653 | if (!fi) { |
| 683 | inode_dec_link_count(inode); | 654 | inode_dec_link_count(inode); |
| 655 | unlock_new_inode(inode); | ||
| 684 | iput(inode); | 656 | iput(inode); |
| 685 | goto out; | 657 | goto out; |
| 686 | } | 658 | } |
| @@ -699,6 +671,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 699 | if (!fi) { | 671 | if (!fi) { |
| 700 | clear_nlink(inode); | 672 | clear_nlink(inode); |
| 701 | mark_inode_dirty(inode); | 673 | mark_inode_dirty(inode); |
| 674 | unlock_new_inode(inode); | ||
| 702 | iput(inode); | 675 | iput(inode); |
| 703 | goto out; | 676 | goto out; |
| 704 | } | 677 | } |
| @@ -710,6 +683,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 710 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 683 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
| 711 | inc_nlink(dir); | 684 | inc_nlink(dir); |
| 712 | mark_inode_dirty(dir); | 685 | mark_inode_dirty(dir); |
| 686 | unlock_new_inode(inode); | ||
| 713 | d_instantiate(dentry, inode); | 687 | d_instantiate(dentry, inode); |
| 714 | if (fibh.sbh != fibh.ebh) | 688 | if (fibh.sbh != fibh.ebh) |
| 715 | brelse(fibh.ebh); | 689 | brelse(fibh.ebh); |
| @@ -876,14 +850,11 @@ out: | |||
| 876 | static int udf_symlink(struct inode *dir, struct dentry *dentry, | 850 | static int udf_symlink(struct inode *dir, struct dentry *dentry, |
| 877 | const char *symname) | 851 | const char *symname) |
| 878 | { | 852 | { |
| 879 | struct inode *inode; | 853 | struct inode *inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO); |
| 880 | struct pathComponent *pc; | 854 | struct pathComponent *pc; |
| 881 | const char *compstart; | 855 | const char *compstart; |
| 882 | struct udf_fileident_bh fibh; | ||
| 883 | struct extent_position epos = {}; | 856 | struct extent_position epos = {}; |
| 884 | int eoffset, elen = 0; | 857 | int eoffset, elen = 0; |
| 885 | struct fileIdentDesc *fi; | ||
| 886 | struct fileIdentDesc cfi; | ||
| 887 | uint8_t *ea; | 858 | uint8_t *ea; |
| 888 | int err; | 859 | int err; |
| 889 | int block; | 860 | int block; |
| @@ -892,9 +863,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 892 | struct udf_inode_info *iinfo; | 863 | struct udf_inode_info *iinfo; |
| 893 | struct super_block *sb = dir->i_sb; | 864 | struct super_block *sb = dir->i_sb; |
| 894 | 865 | ||
| 895 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); | 866 | if (IS_ERR(inode)) |
| 896 | if (!inode) | 867 | return PTR_ERR(inode); |
| 897 | goto out; | ||
| 898 | 868 | ||
| 899 | iinfo = UDF_I(inode); | 869 | iinfo = UDF_I(inode); |
| 900 | down_write(&iinfo->i_data_sem); | 870 | down_write(&iinfo->i_data_sem); |
| @@ -1012,24 +982,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 1012 | mark_inode_dirty(inode); | 982 | mark_inode_dirty(inode); |
| 1013 | up_write(&iinfo->i_data_sem); | 983 | up_write(&iinfo->i_data_sem); |
| 1014 | 984 | ||
| 1015 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 985 | err = udf_add_nondir(dentry, inode); |
| 1016 | if (!fi) | ||
| 1017 | goto out_no_entry; | ||
| 1018 | cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); | ||
| 1019 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | ||
| 1020 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { | ||
| 1021 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | ||
| 1022 | cpu_to_le32(lvid_get_unique_id(sb)); | ||
| 1023 | } | ||
| 1024 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | ||
| 1025 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
| 1026 | mark_inode_dirty(dir); | ||
| 1027 | if (fibh.sbh != fibh.ebh) | ||
| 1028 | brelse(fibh.ebh); | ||
| 1029 | brelse(fibh.sbh); | ||
| 1030 | d_instantiate(dentry, inode); | ||
| 1031 | err = 0; | ||
| 1032 | |||
| 1033 | out: | 986 | out: |
| 1034 | kfree(name); | 987 | kfree(name); |
| 1035 | return err; | 988 | return err; |
| @@ -1037,6 +990,7 @@ out: | |||
| 1037 | out_no_entry: | 990 | out_no_entry: |
| 1038 | up_write(&iinfo->i_data_sem); | 991 | up_write(&iinfo->i_data_sem); |
| 1039 | inode_dec_link_count(inode); | 992 | inode_dec_link_count(inode); |
| 993 | unlock_new_inode(inode); | ||
| 1040 | iput(inode); | 994 | iput(inode); |
| 1041 | goto out; | 995 | goto out; |
| 1042 | } | 996 | } |
| @@ -1221,7 +1175,7 @@ static struct dentry *udf_get_parent(struct dentry *child) | |||
| 1221 | struct udf_fileident_bh fibh; | 1175 | struct udf_fileident_bh fibh; |
| 1222 | 1176 | ||
| 1223 | if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) | 1177 | if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi)) |
| 1224 | goto out_unlock; | 1178 | return ERR_PTR(-EACCES); |
| 1225 | 1179 | ||
| 1226 | if (fibh.sbh != fibh.ebh) | 1180 | if (fibh.sbh != fibh.ebh) |
| 1227 | brelse(fibh.ebh); | 1181 | brelse(fibh.ebh); |
| @@ -1229,12 +1183,10 @@ static struct dentry *udf_get_parent(struct dentry *child) | |||
| 1229 | 1183 | ||
| 1230 | tloc = lelb_to_cpu(cfi.icb.extLocation); | 1184 | tloc = lelb_to_cpu(cfi.icb.extLocation); |
| 1231 | inode = udf_iget(child->d_inode->i_sb, &tloc); | 1185 | inode = udf_iget(child->d_inode->i_sb, &tloc); |
| 1232 | if (!inode) | 1186 | if (IS_ERR(inode)) |
| 1233 | goto out_unlock; | 1187 | return ERR_CAST(inode); |
| 1234 | 1188 | ||
| 1235 | return d_obtain_alias(inode); | 1189 | return d_obtain_alias(inode); |
| 1236 | out_unlock: | ||
| 1237 | return ERR_PTR(-EACCES); | ||
| 1238 | } | 1190 | } |
| 1239 | 1191 | ||
| 1240 | 1192 | ||
| @@ -1251,8 +1203,8 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block, | |||
| 1251 | loc.partitionReferenceNum = partref; | 1203 | loc.partitionReferenceNum = partref; |
| 1252 | inode = udf_iget(sb, &loc); | 1204 | inode = udf_iget(sb, &loc); |
| 1253 | 1205 | ||
| 1254 | if (inode == NULL) | 1206 | if (IS_ERR(inode)) |
| 1255 | return ERR_PTR(-ENOMEM); | 1207 | return ERR_CAST(inode); |
| 1256 | 1208 | ||
| 1257 | if (generation && inode->i_generation != generation) { | 1209 | if (generation && inode->i_generation != generation) { |
| 1258 | iput(inode); | 1210 | iput(inode); |
