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/inode.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/inode.c')
-rw-r--r-- | fs/udf/inode.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index fa3c1541151c..b2fe4d7f20eb 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -301,10 +301,9 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
301 | err = -EIO; | 301 | err = -EIO; |
302 | new = 0; | 302 | new = 0; |
303 | bh = NULL; | 303 | bh = NULL; |
304 | |||
305 | lock_kernel(); | ||
306 | |||
307 | iinfo = UDF_I(inode); | 304 | iinfo = UDF_I(inode); |
305 | |||
306 | down_write(&iinfo->i_data_sem); | ||
308 | if (block == iinfo->i_next_alloc_block + 1) { | 307 | if (block == iinfo->i_next_alloc_block + 1) { |
309 | iinfo->i_next_alloc_block++; | 308 | iinfo->i_next_alloc_block++; |
310 | iinfo->i_next_alloc_goal++; | 309 | iinfo->i_next_alloc_goal++; |
@@ -323,7 +322,7 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
323 | map_bh(bh_result, inode->i_sb, phys); | 322 | map_bh(bh_result, inode->i_sb, phys); |
324 | 323 | ||
325 | abort: | 324 | abort: |
326 | unlock_kernel(); | 325 | up_write(&iinfo->i_data_sem); |
327 | return err; | 326 | return err; |
328 | } | 327 | } |
329 | 328 | ||
@@ -1021,16 +1020,16 @@ void udf_truncate(struct inode *inode) | |||
1021 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 1020 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
1022 | return; | 1021 | return; |
1023 | 1022 | ||
1024 | lock_kernel(); | ||
1025 | iinfo = UDF_I(inode); | 1023 | iinfo = UDF_I(inode); |
1026 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1024 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1025 | down_write(&iinfo->i_data_sem); | ||
1027 | if (inode->i_sb->s_blocksize < | 1026 | if (inode->i_sb->s_blocksize < |
1028 | (udf_file_entry_alloc_offset(inode) + | 1027 | (udf_file_entry_alloc_offset(inode) + |
1029 | inode->i_size)) { | 1028 | inode->i_size)) { |
1030 | udf_expand_file_adinicb(inode, inode->i_size, &err); | 1029 | udf_expand_file_adinicb(inode, inode->i_size, &err); |
1031 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1030 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1032 | inode->i_size = iinfo->i_lenAlloc; | 1031 | inode->i_size = iinfo->i_lenAlloc; |
1033 | unlock_kernel(); | 1032 | up_write(&iinfo->i_data_sem); |
1034 | return; | 1033 | return; |
1035 | } else | 1034 | } else |
1036 | udf_truncate_extents(inode); | 1035 | udf_truncate_extents(inode); |
@@ -1041,10 +1040,13 @@ void udf_truncate(struct inode *inode) | |||
1041 | offset - udf_file_entry_alloc_offset(inode)); | 1040 | offset - udf_file_entry_alloc_offset(inode)); |
1042 | iinfo->i_lenAlloc = inode->i_size; | 1041 | iinfo->i_lenAlloc = inode->i_size; |
1043 | } | 1042 | } |
1043 | up_write(&iinfo->i_data_sem); | ||
1044 | } else { | 1044 | } else { |
1045 | block_truncate_page(inode->i_mapping, inode->i_size, | 1045 | block_truncate_page(inode->i_mapping, inode->i_size, |
1046 | udf_get_block); | 1046 | udf_get_block); |
1047 | down_write(&iinfo->i_data_sem); | ||
1047 | udf_truncate_extents(inode); | 1048 | udf_truncate_extents(inode); |
1049 | up_write(&iinfo->i_data_sem); | ||
1048 | } | 1050 | } |
1049 | 1051 | ||
1050 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); | 1052 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); |
@@ -1052,7 +1054,6 @@ void udf_truncate(struct inode *inode) | |||
1052 | udf_sync_inode(inode); | 1054 | udf_sync_inode(inode); |
1053 | else | 1055 | else |
1054 | mark_inode_dirty(inode); | 1056 | mark_inode_dirty(inode); |
1055 | unlock_kernel(); | ||
1056 | } | 1057 | } |
1057 | 1058 | ||
1058 | static void __udf_read_inode(struct inode *inode) | 1059 | static void __udf_read_inode(struct inode *inode) |
@@ -2043,7 +2044,7 @@ long udf_block_map(struct inode *inode, sector_t block) | |||
2043 | struct extent_position epos = {}; | 2044 | struct extent_position epos = {}; |
2044 | int ret; | 2045 | int ret; |
2045 | 2046 | ||
2046 | lock_kernel(); | 2047 | down_read(&UDF_I(inode)->i_data_sem); |
2047 | 2048 | ||
2048 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == | 2049 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == |
2049 | (EXT_RECORDED_ALLOCATED >> 30)) | 2050 | (EXT_RECORDED_ALLOCATED >> 30)) |
@@ -2051,7 +2052,7 @@ long udf_block_map(struct inode *inode, sector_t block) | |||
2051 | else | 2052 | else |
2052 | ret = 0; | 2053 | ret = 0; |
2053 | 2054 | ||
2054 | unlock_kernel(); | 2055 | up_read(&UDF_I(inode)->i_data_sem); |
2055 | brelse(epos.bh); | 2056 | brelse(epos.bh); |
2056 | 2057 | ||
2057 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) | 2058 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |