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 */ |
