diff options
Diffstat (limited to 'fs/ioctl.c')
-rw-r--r-- | fs/ioctl.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/fs/ioctl.c b/fs/ioctl.c index 43e8b2c0664b..cc3f1aa1cf7b 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -231,7 +231,8 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg) | |||
231 | #define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits) | 231 | #define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits) |
232 | #define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits); | 232 | #define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits); |
233 | 233 | ||
234 | /* | 234 | /** |
235 | * __generic_block_fiemap - FIEMAP for block based inodes (no locking) | ||
235 | * @inode - the inode to map | 236 | * @inode - the inode to map |
236 | * @arg - the pointer to userspace where we copy everything to | 237 | * @arg - the pointer to userspace where we copy everything to |
237 | * @get_block - the fs's get_block function | 238 | * @get_block - the fs's get_block function |
@@ -242,11 +243,15 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg) | |||
242 | * | 243 | * |
243 | * If it is possible to have data blocks beyond a hole past @inode->i_size, then | 244 | * If it is possible to have data blocks beyond a hole past @inode->i_size, then |
244 | * please do not use this function, it will stop at the first unmapped block | 245 | * please do not use this function, it will stop at the first unmapped block |
245 | * beyond i_size | 246 | * beyond i_size. |
247 | * | ||
248 | * If you use this function directly, you need to do your own locking. Use | ||
249 | * generic_block_fiemap if you want the locking done for you. | ||
246 | */ | 250 | */ |
247 | int generic_block_fiemap(struct inode *inode, | 251 | |
248 | struct fiemap_extent_info *fieinfo, u64 start, | 252 | int __generic_block_fiemap(struct inode *inode, |
249 | u64 len, get_block_t *get_block) | 253 | struct fiemap_extent_info *fieinfo, u64 start, |
254 | u64 len, get_block_t *get_block) | ||
250 | { | 255 | { |
251 | struct buffer_head tmp; | 256 | struct buffer_head tmp; |
252 | unsigned int start_blk; | 257 | unsigned int start_blk; |
@@ -260,9 +265,6 @@ int generic_block_fiemap(struct inode *inode, | |||
260 | 265 | ||
261 | start_blk = logical_to_blk(inode, start); | 266 | start_blk = logical_to_blk(inode, start); |
262 | 267 | ||
263 | /* guard against change */ | ||
264 | mutex_lock(&inode->i_mutex); | ||
265 | |||
266 | length = (long long)min_t(u64, len, i_size_read(inode)); | 268 | length = (long long)min_t(u64, len, i_size_read(inode)); |
267 | map_len = length; | 269 | map_len = length; |
268 | 270 | ||
@@ -334,14 +336,36 @@ int generic_block_fiemap(struct inode *inode, | |||
334 | cond_resched(); | 336 | cond_resched(); |
335 | } while (1); | 337 | } while (1); |
336 | 338 | ||
337 | mutex_unlock(&inode->i_mutex); | ||
338 | |||
339 | /* if ret is 1 then we just hit the end of the extent array */ | 339 | /* if ret is 1 then we just hit the end of the extent array */ |
340 | if (ret == 1) | 340 | if (ret == 1) |
341 | ret = 0; | 341 | ret = 0; |
342 | 342 | ||
343 | return ret; | 343 | return ret; |
344 | } | 344 | } |
345 | EXPORT_SYMBOL(__generic_block_fiemap); | ||
346 | |||
347 | /** | ||
348 | * generic_block_fiemap - FIEMAP for block based inodes | ||
349 | * @inode: The inode to map | ||
350 | * @fieinfo: The mapping information | ||
351 | * @start: The initial block to map | ||
352 | * @len: The length of the extect to attempt to map | ||
353 | * @get_block: The block mapping function for the fs | ||
354 | * | ||
355 | * Calls __generic_block_fiemap to map the inode, after taking | ||
356 | * the inode's mutex lock. | ||
357 | */ | ||
358 | |||
359 | int generic_block_fiemap(struct inode *inode, | ||
360 | struct fiemap_extent_info *fieinfo, u64 start, | ||
361 | u64 len, get_block_t *get_block) | ||
362 | { | ||
363 | int ret; | ||
364 | mutex_lock(&inode->i_mutex); | ||
365 | ret = __generic_block_fiemap(inode, fieinfo, start, len, get_block); | ||
366 | mutex_unlock(&inode->i_mutex); | ||
367 | return ret; | ||
368 | } | ||
345 | EXPORT_SYMBOL(generic_block_fiemap); | 369 | EXPORT_SYMBOL(generic_block_fiemap); |
346 | 370 | ||
347 | #endif /* CONFIG_BLOCK */ | 371 | #endif /* CONFIG_BLOCK */ |