diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-12-30 02:03:58 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-12-31 18:07:44 -0500 |
commit | c1eaa26b671299b3ec01d40c6c71ee19a4f81517 (patch) | |
tree | a9cc7d3126a727f01d3cb9aa41fee199bb502987 | |
parent | 6b38e842bb832a3dbeb17e382404aef3c40ac5f9 (diff) |
nfsd race fixes: reiserfs
... and the same for reiserfs. The difference here is that we need
insert_inode_locked4() to match iget5_locked().
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/reiserfs/inode.c | 15 | ||||
-rw-r--r-- | fs/reiserfs/namei.c | 8 |
2 files changed, 18 insertions, 5 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 6c4c2c69449f..145c2d3e5e01 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1753,6 +1753,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1753 | struct inode *inode) | 1753 | struct inode *inode) |
1754 | { | 1754 | { |
1755 | struct super_block *sb; | 1755 | struct super_block *sb; |
1756 | struct reiserfs_iget_args args; | ||
1756 | INITIALIZE_PATH(path_to_key); | 1757 | INITIALIZE_PATH(path_to_key); |
1757 | struct cpu_key key; | 1758 | struct cpu_key key; |
1758 | struct item_head ih; | 1759 | struct item_head ih; |
@@ -1780,6 +1781,14 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1780 | err = -ENOMEM; | 1781 | err = -ENOMEM; |
1781 | goto out_bad_inode; | 1782 | goto out_bad_inode; |
1782 | } | 1783 | } |
1784 | args.objectid = inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid); | ||
1785 | memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); | ||
1786 | args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); | ||
1787 | if (insert_inode_locked4(inode, args.objectid, | ||
1788 | reiserfs_find_actor, &args) < 0) { | ||
1789 | err = -EINVAL; | ||
1790 | goto out_bad_inode; | ||
1791 | } | ||
1783 | if (old_format_only(sb)) | 1792 | if (old_format_only(sb)) |
1784 | /* not a perfect generation count, as object ids can be reused, but | 1793 | /* not a perfect generation count, as object ids can be reused, but |
1785 | ** this is as good as reiserfs can do right now. | 1794 | ** this is as good as reiserfs can do right now. |
@@ -1859,13 +1868,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1859 | } else { | 1868 | } else { |
1860 | inode2sd(&sd, inode, inode->i_size); | 1869 | inode2sd(&sd, inode, inode->i_size); |
1861 | } | 1870 | } |
1862 | // these do not go to on-disk stat data | ||
1863 | inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid); | ||
1864 | |||
1865 | // store in in-core inode the key of stat data and version all | 1871 | // store in in-core inode the key of stat data and version all |
1866 | // object items will have (directory items will have old offset | 1872 | // object items will have (directory items will have old offset |
1867 | // format, other new objects will consist of new items) | 1873 | // format, other new objects will consist of new items) |
1868 | memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); | ||
1869 | if (old_format_only(sb) || S_ISDIR(mode) || S_ISLNK(mode)) | 1874 | if (old_format_only(sb) || S_ISDIR(mode) || S_ISLNK(mode)) |
1870 | set_inode_item_key_version(inode, KEY_FORMAT_3_5); | 1875 | set_inode_item_key_version(inode, KEY_FORMAT_3_5); |
1871 | else | 1876 | else |
@@ -1929,7 +1934,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1929 | reiserfs_mark_inode_private(inode); | 1934 | reiserfs_mark_inode_private(inode); |
1930 | } | 1935 | } |
1931 | 1936 | ||
1932 | insert_inode_hash(inode); | ||
1933 | reiserfs_update_sd(th, inode); | 1937 | reiserfs_update_sd(th, inode); |
1934 | reiserfs_check_path(&path_to_key); | 1938 | reiserfs_check_path(&path_to_key); |
1935 | 1939 | ||
@@ -1956,6 +1960,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1956 | out_inserted_sd: | 1960 | out_inserted_sd: |
1957 | inode->i_nlink = 0; | 1961 | inode->i_nlink = 0; |
1958 | th->t_trans_id = 0; /* so the caller can't use this handle later */ | 1962 | th->t_trans_id = 0; /* so the caller can't use this handle later */ |
1963 | unlock_new_inode(inode); /* OK to do even if we hadn't locked it */ | ||
1959 | 1964 | ||
1960 | /* If we were inheriting an ACL, we need to release the lock so that | 1965 | /* If we were inheriting an ACL, we need to release the lock so that |
1961 | * iput doesn't deadlock in reiserfs_delete_xattrs. The locking | 1966 | * iput doesn't deadlock in reiserfs_delete_xattrs. The locking |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 4f322e5ed840..738967f6c8ee 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -646,6 +646,7 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
646 | err = journal_end(&th, dir->i_sb, jbegin_count); | 646 | err = journal_end(&th, dir->i_sb, jbegin_count); |
647 | if (err) | 647 | if (err) |
648 | retval = err; | 648 | retval = err; |
649 | unlock_new_inode(inode); | ||
649 | iput(inode); | 650 | iput(inode); |
650 | goto out_failed; | 651 | goto out_failed; |
651 | } | 652 | } |
@@ -653,6 +654,7 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
653 | reiserfs_update_inode_transaction(dir); | 654 | reiserfs_update_inode_transaction(dir); |
654 | 655 | ||
655 | d_instantiate(dentry, inode); | 656 | d_instantiate(dentry, inode); |
657 | unlock_new_inode(inode); | ||
656 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 658 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
657 | 659 | ||
658 | out_failed: | 660 | out_failed: |
@@ -727,11 +729,13 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
727 | err = journal_end(&th, dir->i_sb, jbegin_count); | 729 | err = journal_end(&th, dir->i_sb, jbegin_count); |
728 | if (err) | 730 | if (err) |
729 | retval = err; | 731 | retval = err; |
732 | unlock_new_inode(inode); | ||
730 | iput(inode); | 733 | iput(inode); |
731 | goto out_failed; | 734 | goto out_failed; |
732 | } | 735 | } |
733 | 736 | ||
734 | d_instantiate(dentry, inode); | 737 | d_instantiate(dentry, inode); |
738 | unlock_new_inode(inode); | ||
735 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 739 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
736 | 740 | ||
737 | out_failed: | 741 | out_failed: |
@@ -812,6 +816,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
812 | err = journal_end(&th, dir->i_sb, jbegin_count); | 816 | err = journal_end(&th, dir->i_sb, jbegin_count); |
813 | if (err) | 817 | if (err) |
814 | retval = err; | 818 | retval = err; |
819 | unlock_new_inode(inode); | ||
815 | iput(inode); | 820 | iput(inode); |
816 | goto out_failed; | 821 | goto out_failed; |
817 | } | 822 | } |
@@ -819,6 +824,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
819 | reiserfs_update_sd(&th, dir); | 824 | reiserfs_update_sd(&th, dir); |
820 | 825 | ||
821 | d_instantiate(dentry, inode); | 826 | d_instantiate(dentry, inode); |
827 | unlock_new_inode(inode); | ||
822 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 828 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
823 | out_failed: | 829 | out_failed: |
824 | if (locked) | 830 | if (locked) |
@@ -1096,11 +1102,13 @@ static int reiserfs_symlink(struct inode *parent_dir, | |||
1096 | err = journal_end(&th, parent_dir->i_sb, jbegin_count); | 1102 | err = journal_end(&th, parent_dir->i_sb, jbegin_count); |
1097 | if (err) | 1103 | if (err) |
1098 | retval = err; | 1104 | retval = err; |
1105 | unlock_new_inode(inode); | ||
1099 | iput(inode); | 1106 | iput(inode); |
1100 | goto out_failed; | 1107 | goto out_failed; |
1101 | } | 1108 | } |
1102 | 1109 | ||
1103 | d_instantiate(dentry, inode); | 1110 | d_instantiate(dentry, inode); |
1111 | unlock_new_inode(inode); | ||
1104 | retval = journal_end(&th, parent_dir->i_sb, jbegin_count); | 1112 | retval = journal_end(&th, parent_dir->i_sb, jbegin_count); |
1105 | out_failed: | 1113 | out_failed: |
1106 | reiserfs_write_unlock(parent_dir->i_sb); | 1114 | reiserfs_write_unlock(parent_dir->i_sb); |