diff options
author | Alessio Igor Bogani <abogani@texware.it> | 2010-11-16 12:40:47 -0500 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2011-01-06 11:03:56 -0500 |
commit | 4d0fb621d35007c19a396f2bb629e5aeaacef2d0 (patch) | |
tree | 92f6e0d3c38c15b0af507bd4b6d3353e34a337a9 /fs/udf/namei.c | |
parent | d1668fe390c1e84580575965684a8fa7e4626dee (diff) |
udf: Replace bkl with the UDF_I(inode)->i_data_sem for protect udf_inode_info struct
Replace bkl with the UDF_I(inode)->i_data_sem rw semaphore in
udf_release_file(), udf_symlink(), udf_symlink_filler(), udf_get_block(),
udf_block_map(), and udf_setattr(). The rule now is that any operation
on regular file's or symlink's extents (or generally allocation information
including goal block) needs to hold i_data_sem.
This work was supported by a hardware donation from the CE Linux Forum.
Signed-off-by: Alessio Igor Bogani <abogani@texware.it>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/namei.c')
-rw-r--r-- | fs/udf/namei.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 701fcda18415..d5eb000ddddd 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -893,18 +893,18 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
893 | struct udf_inode_info *iinfo; | 893 | struct udf_inode_info *iinfo; |
894 | struct super_block *sb = dir->i_sb; | 894 | struct super_block *sb = dir->i_sb; |
895 | 895 | ||
896 | lock_kernel(); | ||
897 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); | 896 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); |
898 | if (!inode) | 897 | if (!inode) |
899 | goto out; | 898 | goto out; |
900 | 899 | ||
900 | iinfo = UDF_I(inode); | ||
901 | down_write(&iinfo->i_data_sem); | ||
901 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); | 902 | name = kmalloc(UDF_NAME_LEN, GFP_NOFS); |
902 | if (!name) { | 903 | if (!name) { |
903 | err = -ENOMEM; | 904 | err = -ENOMEM; |
904 | goto out_no_entry; | 905 | goto out_no_entry; |
905 | } | 906 | } |
906 | 907 | ||
907 | iinfo = UDF_I(inode); | ||
908 | inode->i_data.a_ops = &udf_symlink_aops; | 908 | inode->i_data.a_ops = &udf_symlink_aops; |
909 | inode->i_op = &udf_symlink_inode_operations; | 909 | inode->i_op = &udf_symlink_inode_operations; |
910 | 910 | ||
@@ -1024,6 +1024,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1024 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); | 1024 | udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); |
1025 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | 1025 | if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) |
1026 | mark_inode_dirty(dir); | 1026 | mark_inode_dirty(dir); |
1027 | up_write(&iinfo->i_data_sem); | ||
1027 | if (fibh.sbh != fibh.ebh) | 1028 | if (fibh.sbh != fibh.ebh) |
1028 | brelse(fibh.ebh); | 1029 | brelse(fibh.ebh); |
1029 | brelse(fibh.sbh); | 1030 | brelse(fibh.sbh); |
@@ -1032,10 +1033,10 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
1032 | 1033 | ||
1033 | out: | 1034 | out: |
1034 | kfree(name); | 1035 | kfree(name); |
1035 | unlock_kernel(); | ||
1036 | return err; | 1036 | return err; |
1037 | 1037 | ||
1038 | out_no_entry: | 1038 | out_no_entry: |
1039 | up_write(&iinfo->i_data_sem); | ||
1039 | inode_dec_link_count(inode); | 1040 | inode_dec_link_count(inode); |
1040 | iput(inode); | 1041 | iput(inode); |
1041 | goto out; | 1042 | goto out; |