diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-09-04 09:34:14 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2014-09-04 15:37:40 -0400 |
commit | d2be51cb34dc501791f3b8c01a99a3f2064bd8d1 (patch) | |
tree | 2afdd0e564e3fe4c849f36a4c257e49cb1b2f98a /fs/udf/namei.c | |
parent | 470cca56c366428d4d5785a0a5a291619c332c7f (diff) |
udf: merge the pieces inserting a new non-directory object into directory
boilerplate code in udf_{create,mknod,symlink} taken to new helper
symlink case converted to unique id calculated by udf_new_inode() - no
point finding a new one.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/namei.c')
-rw-r--r-- | fs/udf/namei.c | 98 |
1 files changed, 29 insertions, 69 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index e041fd9c6816..abec86466735 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -548,31 +548,16 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi, | |||
548 | return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); | 548 | return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL); |
549 | } | 549 | } |
550 | 550 | ||
551 | 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) |
552 | bool excl) | ||
553 | { | 552 | { |
553 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
554 | struct inode *dir = dentry->d_parent->d_inode; | ||
554 | struct udf_fileident_bh fibh; | 555 | struct udf_fileident_bh fibh; |
555 | struct inode *inode; | ||
556 | struct fileIdentDesc cfi, *fi; | 556 | struct fileIdentDesc cfi, *fi; |
557 | int err; | 557 | int err; |
558 | struct udf_inode_info *iinfo; | ||
559 | |||
560 | inode = udf_new_inode(dir, mode, &err); | ||
561 | if (!inode) { | ||
562 | return err; | ||
563 | } | ||
564 | |||
565 | iinfo = UDF_I(inode); | ||
566 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
567 | inode->i_data.a_ops = &udf_adinicb_aops; | ||
568 | else | ||
569 | inode->i_data.a_ops = &udf_aops; | ||
570 | inode->i_op = &udf_file_inode_operations; | ||
571 | inode->i_fop = &udf_file_operations; | ||
572 | mark_inode_dirty(inode); | ||
573 | 558 | ||
574 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 559 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
575 | if (!fi) { | 560 | if (unlikely(!fi)) { |
576 | inode_dec_link_count(inode); | 561 | inode_dec_link_count(inode); |
577 | iput(inode); | 562 | iput(inode); |
578 | return err; | 563 | return err; |
@@ -592,6 +577,28 @@ static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
592 | return 0; | 577 | return 0; |
593 | } | 578 | } |
594 | 579 | ||
580 | static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode, | ||
581 | bool excl) | ||
582 | { | ||
583 | struct inode *inode; | ||
584 | int err; | ||
585 | |||
586 | inode = udf_new_inode(dir, mode, &err); | ||
587 | if (!inode) { | ||
588 | return err; | ||
589 | } | ||
590 | |||
591 | if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
592 | inode->i_data.a_ops = &udf_adinicb_aops; | ||
593 | else | ||
594 | inode->i_data.a_ops = &udf_aops; | ||
595 | inode->i_op = &udf_file_inode_operations; | ||
596 | inode->i_fop = &udf_file_operations; | ||
597 | mark_inode_dirty(inode); | ||
598 | |||
599 | return udf_add_nondir(dentry, inode); | ||
600 | } | ||
601 | |||
595 | static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | 602 | static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) |
596 | { | 603 | { |
597 | struct inode *inode; | 604 | struct inode *inode; |
@@ -619,10 +626,7 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
619 | dev_t rdev) | 626 | dev_t rdev) |
620 | { | 627 | { |
621 | struct inode *inode; | 628 | struct inode *inode; |
622 | struct udf_fileident_bh fibh; | ||
623 | struct fileIdentDesc cfi, *fi; | ||
624 | int err; | 629 | int err; |
625 | struct udf_inode_info *iinfo; | ||
626 | 630 | ||
627 | if (!old_valid_dev(rdev)) | 631 | if (!old_valid_dev(rdev)) |
628 | return -EINVAL; | 632 | return -EINVAL; |
@@ -630,33 +634,10 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
630 | err = -EIO; | 634 | err = -EIO; |
631 | inode = udf_new_inode(dir, mode, &err); | 635 | inode = udf_new_inode(dir, mode, &err); |
632 | if (!inode) | 636 | if (!inode) |
633 | goto out; | ||
634 | |||
635 | iinfo = UDF_I(inode); | ||
636 | init_special_inode(inode, mode, rdev); | ||
637 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | ||
638 | if (!fi) { | ||
639 | inode_dec_link_count(inode); | ||
640 | iput(inode); | ||
641 | return err; | 637 | return err; |
642 | } | ||
643 | cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize); | ||
644 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | ||
645 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | ||
646 | cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL); | ||
647 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | ||
648 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
649 | mark_inode_dirty(dir); | ||
650 | mark_inode_dirty(inode); | ||
651 | |||
652 | if (fibh.sbh != fibh.ebh) | ||
653 | brelse(fibh.ebh); | ||
654 | brelse(fibh.sbh); | ||
655 | d_instantiate(dentry, inode); | ||
656 | err = 0; | ||
657 | 638 | ||
658 | out: | 639 | init_special_inode(inode, mode, rdev); |
659 | return err; | 640 | return udf_add_nondir(dentry, inode); |
660 | } | 641 | } |
661 | 642 | ||
662 | static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 643 | static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
@@ -877,11 +858,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
877 | struct inode *inode; | 858 | struct inode *inode; |
878 | struct pathComponent *pc; | 859 | struct pathComponent *pc; |
879 | const char *compstart; | 860 | const char *compstart; |
880 | struct udf_fileident_bh fibh; | ||
881 | struct extent_position epos = {}; | 861 | struct extent_position epos = {}; |
882 | int eoffset, elen = 0; | 862 | int eoffset, elen = 0; |
883 | struct fileIdentDesc *fi; | ||
884 | struct fileIdentDesc cfi; | ||
885 | uint8_t *ea; | 863 | uint8_t *ea; |
886 | int err; | 864 | int err; |
887 | int block; | 865 | int block; |
@@ -1010,31 +988,13 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1010 | mark_inode_dirty(inode); | 988 | mark_inode_dirty(inode); |
1011 | up_write(&iinfo->i_data_sem); | 989 | up_write(&iinfo->i_data_sem); |
1012 | 990 | ||
1013 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 991 | err = udf_add_nondir(dentry, inode); |
1014 | if (!fi) | ||
1015 | goto out_fail; | ||
1016 | cfi.icb.extLength = cpu_to_le32(sb->s_blocksize); | ||
1017 | cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location); | ||
1018 | if (UDF_SB(inode->i_sb)->s_lvid_bh) { | ||
1019 | *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse = | ||
1020 | cpu_to_le32(lvid_get_unique_id(sb)); | ||
1021 | } | ||
1022 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | ||
1023 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
1024 | mark_inode_dirty(dir); | ||
1025 | if (fibh.sbh != fibh.ebh) | ||
1026 | brelse(fibh.ebh); | ||
1027 | brelse(fibh.sbh); | ||
1028 | d_instantiate(dentry, inode); | ||
1029 | err = 0; | ||
1030 | |||
1031 | out: | 992 | out: |
1032 | kfree(name); | 993 | kfree(name); |
1033 | return err; | 994 | return err; |
1034 | 995 | ||
1035 | out_no_entry: | 996 | out_no_entry: |
1036 | up_write(&iinfo->i_data_sem); | 997 | up_write(&iinfo->i_data_sem); |
1037 | out_fail: | ||
1038 | inode_dec_link_count(inode); | 998 | inode_dec_link_count(inode); |
1039 | iput(inode); | 999 | iput(inode); |
1040 | goto out; | 1000 | goto out; |