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/symlink.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/symlink.c')
-rw-r--r-- | fs/udf/symlink.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index 16064787d2b7..b1d4488b0f14 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/stat.h> | 28 | #include <linux/stat.h> |
29 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/buffer_head.h> | 30 | #include <linux/buffer_head.h> |
32 | #include "udf_i.h" | 31 | #include "udf_i.h" |
33 | 32 | ||
@@ -78,13 +77,16 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
78 | int err = -EIO; | 77 | int err = -EIO; |
79 | unsigned char *p = kmap(page); | 78 | unsigned char *p = kmap(page); |
80 | struct udf_inode_info *iinfo; | 79 | struct udf_inode_info *iinfo; |
80 | uint32_t pos; | ||
81 | 81 | ||
82 | lock_kernel(); | ||
83 | iinfo = UDF_I(inode); | 82 | iinfo = UDF_I(inode); |
83 | pos = udf_block_map(inode, 0); | ||
84 | |||
85 | down_read(&iinfo->i_data_sem); | ||
84 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 86 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
85 | symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr; | 87 | symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr; |
86 | } else { | 88 | } else { |
87 | bh = sb_bread(inode->i_sb, udf_block_map(inode, 0)); | 89 | bh = sb_bread(inode->i_sb, pos); |
88 | 90 | ||
89 | if (!bh) | 91 | if (!bh) |
90 | goto out; | 92 | goto out; |
@@ -95,14 +97,14 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
95 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); | 97 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); |
96 | brelse(bh); | 98 | brelse(bh); |
97 | 99 | ||
98 | unlock_kernel(); | 100 | up_read(&iinfo->i_data_sem); |
99 | SetPageUptodate(page); | 101 | SetPageUptodate(page); |
100 | kunmap(page); | 102 | kunmap(page); |
101 | unlock_page(page); | 103 | unlock_page(page); |
102 | return 0; | 104 | return 0; |
103 | 105 | ||
104 | out: | 106 | out: |
105 | unlock_kernel(); | 107 | up_read(&iinfo->i_data_sem); |
106 | SetPageError(page); | 108 | SetPageError(page); |
107 | kunmap(page); | 109 | kunmap(page); |
108 | unlock_page(page); | 110 | unlock_page(page); |