aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ioctl.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2008-10-14 09:43:29 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2009-01-05 02:38:46 -0500
commite9079cce201784632aed4b1a3121ee38c1ced0b6 (patch)
tree6d99fc45afb3889e5835d713948226d7548d6750 /fs/ioctl.c
parentfe0bdec68b77020281dc814805edfe594ae89e0f (diff)
GFS2: Support for FIEMAP ioctl
This patch implements the FIEMAP ioctl for GFS2. We can use the generic code (aside from a lock order issue, solved as per Ted Tso's suggestion) for which I've introduced a new variant of the generic function. We also have one exception to deal with, namely stuffed files, so we do that "by hand", setting all the required flags. This has been tested with a modified (I could only find an old version) of Eric's test program, and appears to work correctly. This patch does not currently support FIEMAP of xattrs, but the plan is to add that feature at some future point. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com> Cc: Theodore Tso <tytso@mit.edu> Cc: Eric Sandeen <sandeen@redhat.com>
Diffstat (limited to 'fs/ioctl.c')
-rw-r--r--fs/ioctl.c44
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 */
247int generic_block_fiemap(struct inode *inode, 251
248 struct fiemap_extent_info *fieinfo, u64 start, 252int __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}
345EXPORT_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
359int 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}
345EXPORT_SYMBOL(generic_block_fiemap); 369EXPORT_SYMBOL(generic_block_fiemap);
346 370
347#endif /* CONFIG_BLOCK */ 371#endif /* CONFIG_BLOCK */