aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/inode.c
diff options
context:
space:
mode:
authorAlessio Igor Bogani <abogani@texware.it>2010-11-16 12:40:47 -0500
committerJan Kara <jack@suse.cz>2011-01-06 11:03:56 -0500
commit4d0fb621d35007c19a396f2bb629e5aeaacef2d0 (patch)
tree92f6e0d3c38c15b0af507bd4b6d3353e34a337a9 /fs/udf/inode.c
parentd1668fe390c1e84580575965684a8fa7e4626dee (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.c19
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
325abort: 324abort:
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
1058static void __udf_read_inode(struct inode *inode) 1059static 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))