diff options
Diffstat (limited to 'fs/udf/inode.c')
-rw-r--r-- | fs/udf/inode.c | 51 |
1 files changed, 22 insertions, 29 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index fc48f37aa2dd..c6a2e782b97b 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -31,7 +31,6 @@ | |||
31 | 31 | ||
32 | #include "udfdecl.h" | 32 | #include "udfdecl.h" |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/module.h> | 34 | #include <linux/module.h> |
36 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
37 | #include <linux/buffer_head.h> | 36 | #include <linux/buffer_head.h> |
@@ -51,6 +50,7 @@ MODULE_LICENSE("GPL"); | |||
51 | static mode_t udf_convert_permissions(struct fileEntry *); | 50 | static mode_t udf_convert_permissions(struct fileEntry *); |
52 | static int udf_update_inode(struct inode *, int); | 51 | static int udf_update_inode(struct inode *, int); |
53 | static void udf_fill_inode(struct inode *, struct buffer_head *); | 52 | static void udf_fill_inode(struct inode *, struct buffer_head *); |
53 | static int udf_sync_inode(struct inode *inode); | ||
54 | static int udf_alloc_i_data(struct inode *inode, size_t size); | 54 | static int udf_alloc_i_data(struct inode *inode, size_t size); |
55 | static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, | 55 | static struct buffer_head *inode_getblk(struct inode *, sector_t, int *, |
56 | sector_t *, int *); | 56 | sector_t *, int *); |
@@ -79,9 +79,7 @@ void udf_evict_inode(struct inode *inode) | |||
79 | want_delete = 1; | 79 | want_delete = 1; |
80 | inode->i_size = 0; | 80 | inode->i_size = 0; |
81 | udf_truncate(inode); | 81 | udf_truncate(inode); |
82 | lock_kernel(); | ||
83 | udf_update_inode(inode, IS_SYNC(inode)); | 82 | udf_update_inode(inode, IS_SYNC(inode)); |
84 | unlock_kernel(); | ||
85 | } | 83 | } |
86 | invalidate_inode_buffers(inode); | 84 | invalidate_inode_buffers(inode); |
87 | end_writeback(inode); | 85 | end_writeback(inode); |
@@ -97,9 +95,7 @@ void udf_evict_inode(struct inode *inode) | |||
97 | kfree(iinfo->i_ext.i_data); | 95 | kfree(iinfo->i_ext.i_data); |
98 | iinfo->i_ext.i_data = NULL; | 96 | iinfo->i_ext.i_data = NULL; |
99 | if (want_delete) { | 97 | if (want_delete) { |
100 | lock_kernel(); | ||
101 | udf_free_inode(inode); | 98 | udf_free_inode(inode); |
102 | unlock_kernel(); | ||
103 | } | 99 | } |
104 | } | 100 | } |
105 | 101 | ||
@@ -302,10 +298,9 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
302 | err = -EIO; | 298 | err = -EIO; |
303 | new = 0; | 299 | new = 0; |
304 | bh = NULL; | 300 | bh = NULL; |
305 | |||
306 | lock_kernel(); | ||
307 | |||
308 | iinfo = UDF_I(inode); | 301 | iinfo = UDF_I(inode); |
302 | |||
303 | down_write(&iinfo->i_data_sem); | ||
309 | if (block == iinfo->i_next_alloc_block + 1) { | 304 | if (block == iinfo->i_next_alloc_block + 1) { |
310 | iinfo->i_next_alloc_block++; | 305 | iinfo->i_next_alloc_block++; |
311 | iinfo->i_next_alloc_goal++; | 306 | iinfo->i_next_alloc_goal++; |
@@ -324,7 +319,7 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
324 | map_bh(bh_result, inode->i_sb, phys); | 319 | map_bh(bh_result, inode->i_sb, phys); |
325 | 320 | ||
326 | abort: | 321 | abort: |
327 | unlock_kernel(); | 322 | up_write(&iinfo->i_data_sem); |
328 | return err; | 323 | return err; |
329 | } | 324 | } |
330 | 325 | ||
@@ -1022,16 +1017,16 @@ void udf_truncate(struct inode *inode) | |||
1022 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 1017 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
1023 | return; | 1018 | return; |
1024 | 1019 | ||
1025 | lock_kernel(); | ||
1026 | iinfo = UDF_I(inode); | 1020 | iinfo = UDF_I(inode); |
1027 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1021 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1022 | down_write(&iinfo->i_data_sem); | ||
1028 | if (inode->i_sb->s_blocksize < | 1023 | if (inode->i_sb->s_blocksize < |
1029 | (udf_file_entry_alloc_offset(inode) + | 1024 | (udf_file_entry_alloc_offset(inode) + |
1030 | inode->i_size)) { | 1025 | inode->i_size)) { |
1031 | udf_expand_file_adinicb(inode, inode->i_size, &err); | 1026 | udf_expand_file_adinicb(inode, inode->i_size, &err); |
1032 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1027 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1033 | inode->i_size = iinfo->i_lenAlloc; | 1028 | inode->i_size = iinfo->i_lenAlloc; |
1034 | unlock_kernel(); | 1029 | up_write(&iinfo->i_data_sem); |
1035 | return; | 1030 | return; |
1036 | } else | 1031 | } else |
1037 | udf_truncate_extents(inode); | 1032 | udf_truncate_extents(inode); |
@@ -1042,10 +1037,13 @@ void udf_truncate(struct inode *inode) | |||
1042 | offset - udf_file_entry_alloc_offset(inode)); | 1037 | offset - udf_file_entry_alloc_offset(inode)); |
1043 | iinfo->i_lenAlloc = inode->i_size; | 1038 | iinfo->i_lenAlloc = inode->i_size; |
1044 | } | 1039 | } |
1040 | up_write(&iinfo->i_data_sem); | ||
1045 | } else { | 1041 | } else { |
1046 | block_truncate_page(inode->i_mapping, inode->i_size, | 1042 | block_truncate_page(inode->i_mapping, inode->i_size, |
1047 | udf_get_block); | 1043 | udf_get_block); |
1044 | down_write(&iinfo->i_data_sem); | ||
1048 | udf_truncate_extents(inode); | 1045 | udf_truncate_extents(inode); |
1046 | up_write(&iinfo->i_data_sem); | ||
1049 | } | 1047 | } |
1050 | 1048 | ||
1051 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); | 1049 | inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb); |
@@ -1053,7 +1051,6 @@ void udf_truncate(struct inode *inode) | |||
1053 | udf_sync_inode(inode); | 1051 | udf_sync_inode(inode); |
1054 | else | 1052 | else |
1055 | mark_inode_dirty(inode); | 1053 | mark_inode_dirty(inode); |
1056 | unlock_kernel(); | ||
1057 | } | 1054 | } |
1058 | 1055 | ||
1059 | static void __udf_read_inode(struct inode *inode) | 1056 | static void __udf_read_inode(struct inode *inode) |
@@ -1202,6 +1199,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1202 | return; | 1199 | return; |
1203 | } | 1200 | } |
1204 | 1201 | ||
1202 | read_lock(&sbi->s_cred_lock); | ||
1205 | inode->i_uid = le32_to_cpu(fe->uid); | 1203 | inode->i_uid = le32_to_cpu(fe->uid); |
1206 | if (inode->i_uid == -1 || | 1204 | if (inode->i_uid == -1 || |
1207 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || | 1205 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || |
@@ -1214,13 +1212,6 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1214 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) | 1212 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) |
1215 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; | 1213 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; |
1216 | 1214 | ||
1217 | inode->i_nlink = le16_to_cpu(fe->fileLinkCount); | ||
1218 | if (!inode->i_nlink) | ||
1219 | inode->i_nlink = 1; | ||
1220 | |||
1221 | inode->i_size = le64_to_cpu(fe->informationLength); | ||
1222 | iinfo->i_lenExtents = inode->i_size; | ||
1223 | |||
1224 | if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && | 1215 | if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && |
1225 | sbi->s_fmode != UDF_INVALID_MODE) | 1216 | sbi->s_fmode != UDF_INVALID_MODE) |
1226 | inode->i_mode = sbi->s_fmode; | 1217 | inode->i_mode = sbi->s_fmode; |
@@ -1230,6 +1221,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1230 | else | 1221 | else |
1231 | inode->i_mode = udf_convert_permissions(fe); | 1222 | inode->i_mode = udf_convert_permissions(fe); |
1232 | inode->i_mode &= ~sbi->s_umask; | 1223 | inode->i_mode &= ~sbi->s_umask; |
1224 | read_unlock(&sbi->s_cred_lock); | ||
1225 | |||
1226 | inode->i_nlink = le16_to_cpu(fe->fileLinkCount); | ||
1227 | if (!inode->i_nlink) | ||
1228 | inode->i_nlink = 1; | ||
1229 | |||
1230 | inode->i_size = le64_to_cpu(fe->informationLength); | ||
1231 | iinfo->i_lenExtents = inode->i_size; | ||
1233 | 1232 | ||
1234 | if (iinfo->i_efe == 0) { | 1233 | if (iinfo->i_efe == 0) { |
1235 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << | 1234 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << |
@@ -1373,16 +1372,10 @@ static mode_t udf_convert_permissions(struct fileEntry *fe) | |||
1373 | 1372 | ||
1374 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) | 1373 | int udf_write_inode(struct inode *inode, struct writeback_control *wbc) |
1375 | { | 1374 | { |
1376 | int ret; | 1375 | return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); |
1377 | |||
1378 | lock_kernel(); | ||
1379 | ret = udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | ||
1380 | unlock_kernel(); | ||
1381 | |||
1382 | return ret; | ||
1383 | } | 1376 | } |
1384 | 1377 | ||
1385 | int udf_sync_inode(struct inode *inode) | 1378 | static int udf_sync_inode(struct inode *inode) |
1386 | { | 1379 | { |
1387 | return udf_update_inode(inode, 1); | 1380 | return udf_update_inode(inode, 1); |
1388 | } | 1381 | } |
@@ -2048,7 +2041,7 @@ long udf_block_map(struct inode *inode, sector_t block) | |||
2048 | struct extent_position epos = {}; | 2041 | struct extent_position epos = {}; |
2049 | int ret; | 2042 | int ret; |
2050 | 2043 | ||
2051 | lock_kernel(); | 2044 | down_read(&UDF_I(inode)->i_data_sem); |
2052 | 2045 | ||
2053 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == | 2046 | if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == |
2054 | (EXT_RECORDED_ALLOCATED >> 30)) | 2047 | (EXT_RECORDED_ALLOCATED >> 30)) |
@@ -2056,7 +2049,7 @@ long udf_block_map(struct inode *inode, sector_t block) | |||
2056 | else | 2049 | else |
2057 | ret = 0; | 2050 | ret = 0; |
2058 | 2051 | ||
2059 | unlock_kernel(); | 2052 | up_read(&UDF_I(inode)->i_data_sem); |
2060 | brelse(epos.bh); | 2053 | brelse(epos.bh); |
2061 | 2054 | ||
2062 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) | 2055 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV)) |