diff options
author | Alessio Igor Bogani <abogani@texware.it> | 2010-11-16 12:40:48 -0500 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2011-01-06 11:03:56 -0500 |
commit | 7db09be629033b79792a1bf18f505f5f15914395 (patch) | |
tree | 0302e8f2ae6090d5a47a66f0312413465d383321 /fs/udf | |
parent | 4d0fb621d35007c19a396f2bb629e5aeaacef2d0 (diff) |
udf: Use of s_alloc_mutex to serialize udf_relocate_blocks() execution
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')
-rw-r--r-- | fs/udf/partition.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index 745eb209be0c..a71090ea0e07 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/mutex.h> | ||
28 | 29 | ||
29 | uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, | 30 | uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, |
30 | uint16_t partition, uint32_t offset) | 31 | uint16_t partition, uint32_t offset) |
@@ -159,7 +160,9 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
159 | struct udf_sb_info *sbi = UDF_SB(sb); | 160 | struct udf_sb_info *sbi = UDF_SB(sb); |
160 | u16 reallocationTableLen; | 161 | u16 reallocationTableLen; |
161 | struct buffer_head *bh; | 162 | struct buffer_head *bh; |
163 | int ret = 0; | ||
162 | 164 | ||
165 | mutex_lock(&sbi->s_alloc_mutex); | ||
163 | for (i = 0; i < sbi->s_partitions; i++) { | 166 | for (i = 0; i < sbi->s_partitions; i++) { |
164 | struct udf_part_map *map = &sbi->s_partmaps[i]; | 167 | struct udf_part_map *map = &sbi->s_partmaps[i]; |
165 | if (old_block > map->s_partition_root && | 168 | if (old_block > map->s_partition_root && |
@@ -175,8 +178,10 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
175 | break; | 178 | break; |
176 | } | 179 | } |
177 | 180 | ||
178 | if (!st) | 181 | if (!st) { |
179 | return 1; | 182 | ret = 1; |
183 | goto out; | ||
184 | } | ||
180 | 185 | ||
181 | reallocationTableLen = | 186 | reallocationTableLen = |
182 | le16_to_cpu(st->reallocationTableLen); | 187 | le16_to_cpu(st->reallocationTableLen); |
@@ -207,14 +212,16 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
207 | ((old_block - | 212 | ((old_block - |
208 | map->s_partition_root) & | 213 | map->s_partition_root) & |
209 | (sdata->s_packet_len - 1)); | 214 | (sdata->s_packet_len - 1)); |
210 | return 0; | 215 | ret = 0; |
216 | goto out; | ||
211 | } else if (origLoc == packet) { | 217 | } else if (origLoc == packet) { |
212 | *new_block = le32_to_cpu( | 218 | *new_block = le32_to_cpu( |
213 | entry->mappedLocation) + | 219 | entry->mappedLocation) + |
214 | ((old_block - | 220 | ((old_block - |
215 | map->s_partition_root) & | 221 | map->s_partition_root) & |
216 | (sdata->s_packet_len - 1)); | 222 | (sdata->s_packet_len - 1)); |
217 | return 0; | 223 | ret = 0; |
224 | goto out; | ||
218 | } else if (origLoc > packet) | 225 | } else if (origLoc > packet) |
219 | break; | 226 | break; |
220 | } | 227 | } |
@@ -251,20 +258,24 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block) | |||
251 | st->mapEntry[k].mappedLocation) + | 258 | st->mapEntry[k].mappedLocation) + |
252 | ((old_block - map->s_partition_root) & | 259 | ((old_block - map->s_partition_root) & |
253 | (sdata->s_packet_len - 1)); | 260 | (sdata->s_packet_len - 1)); |
254 | return 0; | 261 | ret = 0; |
262 | goto out; | ||
255 | } | 263 | } |
256 | 264 | ||
257 | return 1; | 265 | ret = 1; |
266 | goto out; | ||
258 | } /* if old_block */ | 267 | } /* if old_block */ |
259 | } | 268 | } |
260 | 269 | ||
261 | if (i == sbi->s_partitions) { | 270 | if (i == sbi->s_partitions) { |
262 | /* outside of partitions */ | 271 | /* outside of partitions */ |
263 | /* for now, fail =) */ | 272 | /* for now, fail =) */ |
264 | return 1; | 273 | ret = 1; |
265 | } | 274 | } |
266 | 275 | ||
267 | return 0; | 276 | out: |
277 | mutex_unlock(&sbi->s_alloc_mutex); | ||
278 | return ret; | ||
268 | } | 279 | } |
269 | 280 | ||
270 | static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, | 281 | static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, |