Commit 7db09be629033b79792a1bf18f505f5f15914395
Committed by
Jan Kara
1 parent
4d0fb621d3
Exists in
master
and in
4 other branches
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>
Showing 1 changed file with 19 additions and 8 deletions Side-by-side Diff
fs/udf/partition.c
... | ... | @@ -25,6 +25,7 @@ |
25 | 25 | #include <linux/fs.h> |
26 | 26 | #include <linux/string.h> |
27 | 27 | #include <linux/buffer_head.h> |
28 | +#include <linux/mutex.h> | |
28 | 29 | |
29 | 30 | uint32_t udf_get_pblock(struct super_block *sb, uint32_t block, |
30 | 31 | uint16_t partition, uint32_t offset) |
31 | 32 | |
... | ... | @@ -159,7 +160,9 @@ |
159 | 160 | struct udf_sb_info *sbi = UDF_SB(sb); |
160 | 161 | u16 reallocationTableLen; |
161 | 162 | struct buffer_head *bh; |
163 | + int ret = 0; | |
162 | 164 | |
165 | + mutex_lock(&sbi->s_alloc_mutex); | |
163 | 166 | for (i = 0; i < sbi->s_partitions; i++) { |
164 | 167 | struct udf_part_map *map = &sbi->s_partmaps[i]; |
165 | 168 | if (old_block > map->s_partition_root && |
... | ... | @@ -175,8 +178,10 @@ |
175 | 178 | break; |
176 | 179 | } |
177 | 180 | |
178 | - if (!st) | |
179 | - return 1; | |
181 | + if (!st) { | |
182 | + ret = 1; | |
183 | + goto out; | |
184 | + } | |
180 | 185 | |
181 | 186 | reallocationTableLen = |
182 | 187 | le16_to_cpu(st->reallocationTableLen); |
183 | 188 | |
... | ... | @@ -207,14 +212,16 @@ |
207 | 212 | ((old_block - |
208 | 213 | map->s_partition_root) & |
209 | 214 | (sdata->s_packet_len - 1)); |
210 | - return 0; | |
215 | + ret = 0; | |
216 | + goto out; | |
211 | 217 | } else if (origLoc == packet) { |
212 | 218 | *new_block = le32_to_cpu( |
213 | 219 | entry->mappedLocation) + |
214 | 220 | ((old_block - |
215 | 221 | map->s_partition_root) & |
216 | 222 | (sdata->s_packet_len - 1)); |
217 | - return 0; | |
223 | + ret = 0; | |
224 | + goto out; | |
218 | 225 | } else if (origLoc > packet) |
219 | 226 | break; |
220 | 227 | } |
221 | 228 | |
222 | 229 | |
223 | 230 | |
... | ... | @@ -251,20 +258,24 @@ |
251 | 258 | st->mapEntry[k].mappedLocation) + |
252 | 259 | ((old_block - map->s_partition_root) & |
253 | 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 | 267 | } /* if old_block */ |
259 | 268 | } |
260 | 269 | |
261 | 270 | if (i == sbi->s_partitions) { |
262 | 271 | /* outside of partitions */ |
263 | 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 | 281 | static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, |