Add ext4-printk-throttling patch
[ext4-patch-queue.git] / vfs-fiemap.patch
blob5838bb4419647821788d9156dbd02d1145858324
1 Basic vfs-level fiemap infrastructure, which sets up a new ->fiemap
2 inode operation.
4 Userspace can get extent information on a file via fiemap ioctl. As input,
5 the fiemap ioctl takes a struct fiemap which includes an array of struct
6 fiemap_extent (fm_extents). Size of the extent array is passed as
7 fm_extent_count and number of extents returned will be written into
8 fm_mapped_extents. Offset and length fields on the fiemap structure
9 (fm_start, fm_length) describe a logical range which will be searched for
10 extents. All extents returned will at least partially contain this range.
11 The actual extent offsets and ranges returned will be unmodified from their
12 offset and range on-disk.
14 The fiemap ioctl returns '0' on success. On error, -1 is returned and errno
15 is set. If errno is equal to EBADR, then fm_flags will contain those flags
16 which were passed in which the kernel did not understand. On all other
17 errors, the contents of fm_extents is undefined.
19 As fiemap evolved, there have been many authors of the vfs patch. As far as
20 I can tell, the list includes:
21 Kalpak Shah <kalpak.shah@sun.com>
22 Andreas Dilger <adilger@sun.com>
23 Eric Sandeen <sandeen@redhat.com>
24 Mark Fasheh <mfasheh@suse.com>
26 Signed-off-by: Mark Fasheh <mfasheh@suse.com>
27 ---
28 Documentation/filesystems/fiemap.txt | 227 ++++++++++++++++++++++++++++++++++
29 fs/ioctl.c | 158 +++++++++++++++++++++++
30 include/linux/fiemap.h | 68 ++++++++++
31 include/linux/fs.h | 18 +++
32 4 files changed, 471 insertions(+), 0 deletions(-)
33 create mode 100644 Documentation/filesystems/fiemap.txt
34 create mode 100644 include/linux/fiemap.h
36 Index: linux-2.6/Documentation/filesystems/fiemap.txt
37 ===================================================================
38 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
39 +++ linux-2.6/Documentation/filesystems/fiemap.txt 2008-07-14 16:53:46.018353648 -0500
40 @@ -0,0 +1,227 @@
41 +============
42 +Fiemap Ioctl
43 +============
45 +The fiemap ioctl is an efficient method for userspace to get file
46 +extent mappings. Instead of block-by-block mapping (such as bmap), fiemap
47 +returns a list of extents.
50 +Request Basics
51 +--------------
53 +A fiemap request is encoded within struct fiemap:
55 +struct fiemap {
56 + __u64 fm_start; /* logical offset (inclusive) at
57 + * which to start mapping (in) */
58 + __u64 fm_length; /* logical length of mapping which
59 + * userspace cares about (in) */
60 + __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
61 + __u32 fm_mapped_extents; /* number of extents that were
62 + * mapped (out) */
63 + __u32 fm_extent_count; /* size of fm_extents array (in) */
64 + __u32 fm_reserved;
65 + struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
66 +};
69 +fm_start, and fm_length specify the logical range within the file
70 +which the process would like mappings for. Extents returned mirror
71 +those on disk - that is, the logical offset of the 1st returned extent
72 +may start before fm_start, and the range covered by the last returned
73 +extent may end after fm_length. All offsets and lengths are in bytes.
75 +Certain flags to modify the way in which mappings are looked up can be
76 +set in fm_flags. If the kernel doesn't understand some particular
77 +flags, it will return EBADR and the contents of fm_flags will contain
78 +the set of flags which caused the error. If the kernel is compatible
79 +with all flags passed, the contents of fm_flags will be unmodified.
80 +It is up to userspace to determine whether rejection of a particular
81 +flag is fatal to it's operation. This scheme is intended to allow the
82 +fiemap interface to grow in the future but without losing
83 +compatibility with old software.
85 +fm_extent_count specifies the number of elements in the fm_extents[] array
86 +that can be used to return extents. If fm_extent_count is zero, then the
87 +fm_extents[] array is ignored (no extents will be returned), and the
88 +fm_mapped_extents count will hold the number of extents needed in
89 +fm_extents[] to hold the file's current mapping. Note that there is
90 +nothing to prevent the file from changing between calls to FIEMAP.
92 +Currently, there are three flags which can be set in fm_flags:
94 +* FIEMAP_FLAG_SYNC
95 +If this flag is set, the kernel will sync the file before mapping extents.
97 +* FIEMAP_FLAG_XATTR
98 +If this flag is set, the extents returned will describe the inodes
99 +extended attribute lookup tree, instead of it's data tree.
102 +Extent Mapping
103 +--------------
105 +Extent information is returned within the embedded fm_extents array
106 +which userspace must allocate along with the fiemap structure. The
107 +number of elements in the fiemap_extents[] array should be passed via
108 +fm_extent_count. The number of extents mapped by kernel will be
109 +returned via fm_mapped_extents. If the number of fiemap_extents
110 +allocated is less than would be required to map the requested range,
111 +the maximum number of extents that can be mapped in the fm_extent[]
112 +array will be returned and fm_mapped_extents will be equal to
113 +fm_extent_count. In that case, the last extent in the array will not
114 +complete the requested range and will not have the FIEMAP_EXTENT_LAST
115 +flag set (see the next section on extent flags).
117 +Each extent is described by a single fiemap_extent structure as
118 +returned in fm_extents.
120 +struct fiemap_extent {
121 + __u64 fe_logical; /* logical offset in bytes for the start of
122 + * the extent */
123 + __u64 fe_physical; /* physical offset in bytes for the start
124 + * of the extent */
125 + __u64 fe_length; /* length in bytes for the extent */
126 + __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */
127 + __u32 fe_device; /* device number for extent */
130 +All offsets and lengths are in bytes and mirror those on disk. It is valid
131 +for an extents logical offset to start before the request or it's logical
132 +length to extend past the request. Unless FIEMAP_EXTENT_NOT_ALIGNED is
133 +returned, fe_logical, fe_physical, and fe_length will be aligned to the
134 +block size of the file system. With the exception of extents flagged as
135 +FIEMAP_EXTENT_MERGED, adjacent extents will not be merged.
137 +The fe_flags field contains flags which describe the extent returned.
138 +A special flag, FIEMAP_EXTENT_LAST is always set on the last extent in
139 +the file so that the process making fiemap calls can determine when no
140 +more extents are available, without having to call the ioctl again.
142 +Some flags are intentionally vague and will always be set in the
143 +presence of other more specific flags. This way a program looking for
144 +a general property does not have to know all existing and future flags
145 +which imply that property.
147 +For example, if FIEMAP_EXTENT_DATA_INLINE or FIEMAP_EXTENT_DATA_TAIL
148 +are set, FIEMAP_EXTENT_NOT_ALIGNED will also be set. A program looking
149 +for inline or tail-packed data can key on the specific flag. Software
150 +which simply cares not to try operating on non-aligned extents
151 +however, can just key on FIEMAP_EXTENT_NOT_ALIGNED, and not have to
152 +worry about all present and future flags which might imply unaligned
153 +data. Note that the opposite is not true - it would be valid for
154 +FIEMAP_EXTENT_NOT_ALIGNED to appear alone.
156 +* FIEMAP_EXTENT_LAST
157 +This is the last extent in the file. A mapping attempt past this
158 +extent will return nothing.
160 +* FIEMAP_EXTENT_UNKNOWN
161 +The location of this extent is currently unknown. This may indicate
162 +the data is stored on an inaccessible volume or that no storage has
163 +been allocated for the file yet.
165 +* FIEMAP_EXTENT_DELALLOC
166 + - This will also set FIEMAP_EXTENT_UNKNOWN.
167 +Delayed allocation - while there is data for this extent, it's
168 +physical location has not been allocated yet.
170 +* FIEMAP_EXTENT_NO_DIRECT
171 +Direct access to the data in this extent is illegal or will have
172 +undefined results.
174 +* FIEMAP_EXTENT_SECONDARY
175 +The data for this extent is in secondary storage (e.g. HSM). If the
176 +data is not also in the filesystem, then FIEMAP_EXTENT_NO_DIRECT
177 +should also be set.
179 +* FIEMAP_EXTENT_NET
180 + - This will also set FIEMAP_EXTENT_NO_DIRECT
181 +The data for this extent is not stored in a locally-accessible device.
183 +* FIEMAP_EXTENT_DATA_COMPRESSED
184 + - This will also set FIEMAP_EXTENT_NO_DIRECT
185 +The data in this extent has been compressed by the file system.
187 +* FIEMAP_EXTENT_DATA_ENCRYPTED
188 + - This will also set FIEMAP_EXTENT_NO_DIRECT
189 +The data in this extent has been encrypted by the file system.
191 +* FIEMAP_EXTENT_NOT_ALIGNED
192 +Extent offsets and length are not guaranteed to be block aligned.
194 +* FIEMAP_EXTENT_DATA_INLINE
195 + This will also set FIEMAP_EXTENT_NOT_ALIGNED
196 +Data is located within a meta data block.
198 +* FIEMAP_EXTENT_DATA_TAIL
199 + This will also set FIEMAP_EXTENT_NOT_ALIGNED
200 +Data is packed into a block with data from other files.
202 +* FIEMAP_EXTENT_UNWRITTEN
203 +Unwritten extent - the extent is allocated but it's data has not been
204 +initialized. This indicates the extent's data will be all zero.
206 +* FIEMAP_EXTENT_MERGED
207 +This will be set when a file does not support extents, i.e., it uses a block
208 +based addressing scheme. Since returning an extent for each block back to
209 +userspace would be highly inefficient, the kernel will try to merge most
210 +adjacent blocks into 'extents'.
213 +VFS -> File System Implementation
214 +---------------------------------
216 +File systems wishing to support fiemap must implement a ->fiemap callback on
217 +their inode_operations structure. The fs ->fiemap call is responsible for
218 +defining it's set of supported fiemap flags, and calling a helper function on
219 +each discovered extent:
221 +struct inode_operations {
222 + ...
224 + int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
225 + u64 len);
227 +->fiemap is passed struct fiemap_extent_info which describes the
228 +fiemap request:
230 +struct fiemap_extent_info {
231 + unsigned int fi_flags; /* Flags as passed from user */
232 + unsigned int fi_extents_mapped; /* Number of mapped extents */
233 + unsigned int fi_extents_max; /* Size of fiemap_extent array */
234 + struct fiemap_extent *fi_extents_start; /* Start of fiemap_extent array */
237 +It is intended that the file system should not need to access any of this
238 +structure directly.
241 +Flag checking should be done at the beginning of the ->fiemap callback via the
242 +fiemap_check_flags() helper:
244 +int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
246 +The struct fieinfo should be passed in as recieved from ioctl_fiemap(). The
247 +set of fiemap flags which the fs understands should be passed via fs_flags. If
248 +fiemap_check_flags finds invalid user flags, it will place the bad values in
249 +fieinfo->fi_flags and return -EBADR. If the file system gets -EBADR, from
250 +fiemap_check_flags(), it should immediately exit, returning that error back to
251 +ioctl_fiemap().
254 +For each extent in the request range, the file system should call
255 +the helper function, fiemap_fill_next_extent():
257 +int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
258 + u64 phys, u64 len, u32 flags, u32 dev);
260 +fiemap_fill_next_extent() will use the passed values to populate the
261 +next free extent in the fm_extents array. 'General' extent flags will
262 +automatically be set from specific flags on behalf of the calling file
263 +system so that the userspace API is not broken.
265 +fiemap_fill_next_extent() returns 0 on success, and 1 when the
266 +user-supplied fm_extents array is full. If an error is encountered
267 +while copying the extent to user memory, -EFAULT will be returned.
268 Index: linux-2.6/fs/ioctl.c
269 ===================================================================
270 --- linux-2.6.orig/fs/ioctl.c 2008-07-14 16:51:43.073354079 -0500
271 +++ linux-2.6/fs/ioctl.c 2008-07-14 16:53:46.019353480 -0500
272 @@ -16,6 +16,9 @@
274 #include <asm/ioctls.h>
276 +/* So that the fiemap access checks can't overflow on 32 bit machines. */
277 +#define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
280 * vfs_ioctl - call filesystem specific ioctl methods
281 * @filp: open file to invoke ioctl method on
282 @@ -71,6 +74,159 @@ static int ioctl_fibmap(struct file *fil
283 return put_user(res, p);
286 +/**
287 + * fiemap_fill_next_extent - Fiemap helper function
288 + * @fieinfo: Fiemap context passed into ->fiemap
289 + * @logical: Extent logical start offset, in bytes
290 + * @phys: Extent physical start offset, in bytes
291 + * @len: Extent length, in bytes
292 + * @flags: FIEMAP_EXTENT flags that describe this extent
293 + * @dev: Device on which this extent resides
295 + * Called from file system ->fiemap callback. Will populate extent
296 + * info as passed in via arguments and copy to user memory. On
297 + * success, extent count on fieinfo is incremented.
299 + * Returns 0 on success, -errno on error, 1 if this was the last
300 + * extent that will fit in user array.
301 + */
302 +#define SET_UNKNOWN_FLAGS (FIEMAP_EXTENT_DELALLOC)
303 +#define SET_NO_DIRECT_FLAGS (FIEMAP_EXTENT_DATA_COMPRESSED \
304 + |FIEMAP_EXTENT_DATA_ENCRYPTED \
305 + |FIEMAP_EXTENT_NET)
306 +#define SET_NOT_ALIGNED_FLAGS (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
307 +int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
308 + u64 phys, u64 len, u32 flags, dev_t dev)
310 + struct fiemap_extent extent;
311 + struct fiemap_extent *dest = fieinfo->fi_extents_start;
313 + /* only count the extents */
314 + if (fieinfo->fi_extents_max == 0) {
315 + fieinfo->fi_extents_mapped++;
316 + return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
319 + if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
320 + return 1;
322 + if (flags & SET_UNKNOWN_FLAGS)
323 + flags |= FIEMAP_EXTENT_UNKNOWN;
324 + if (flags & SET_NO_DIRECT_FLAGS)
325 + flags |= FIEMAP_EXTENT_NO_DIRECT;
326 + if (flags & SET_NOT_ALIGNED_FLAGS)
327 + flags |= FIEMAP_EXTENT_NOT_ALIGNED;
329 + extent.fe_logical = logical;
330 + extent.fe_physical = phys;
331 + extent.fe_length = len;
332 + extent.fe_flags = flags;
333 + extent.fe_device = new_encode_dev(dev);
335 + dest += fieinfo->fi_extents_mapped;
336 + if (copy_to_user(dest, &extent, sizeof(extent)))
337 + return -EFAULT;
339 + fieinfo->fi_extents_mapped++;
340 + if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
341 + return 1;
342 + return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
344 +EXPORT_SYMBOL(fiemap_fill_next_extent);
346 +/**
347 + * fiemap_check_flags - check validity of requested flags for fiemap
348 + * @fieinfo: Fiemap context passed into ->fiemap
349 + * @fs_flags: Set of fiemap flags that the file system understands
351 + * Called from file system ->fiemap callback. This will compute the
352 + * intersection of valid fiemap flags and those that the fs supports. That
353 + * value is then compared against the user supplied flags. In case of bad user
354 + * flags, the invalid values will be written into the fieinfo structure, and
355 + * -EBADR is returned, which tells ioctl_fiemap() to return those values to
356 + * userspace. For this reason, a return code of -EBADR should be preserved.
358 + * Returns 0 on success, -EBADR on bad flags.
359 + */
360 +int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags)
362 + u32 incompat_flags;
364 + incompat_flags = fieinfo->fi_flags & ~(FIEMAP_FLAGS_COMPAT & fs_flags);
365 + if (incompat_flags) {
366 + fieinfo->fi_flags = incompat_flags;
367 + return -EBADR;
369 + return 0;
371 +EXPORT_SYMBOL(fiemap_check_flags);
373 +static int fiemap_check_ranges(struct super_block *sb,
374 + u64 start, u64 len, u64 *new_len)
376 + *new_len = len;
378 + if (len == 0)
379 + return -EINVAL;
381 + if (start > sb->s_maxbytes)
382 + return -EFBIG;
384 + /*
385 + * Shrink request scope to what the fs can actually handle.
386 + */
387 + if ((len > sb->s_maxbytes) ||
388 + (sb->s_maxbytes - len) < start)
389 + *new_len = sb->s_maxbytes - start;
391 + return 0;
394 +static int ioctl_fiemap(struct file *filp, unsigned long arg)
396 + struct fiemap fiemap;
397 + struct fiemap_extent_info fieinfo = { 0, };
398 + struct inode *inode = filp->f_path.dentry->d_inode;
399 + struct super_block *sb = inode->i_sb;
400 + u64 len;
401 + int error;
403 + if (!inode->i_op->fiemap)
404 + return -EOPNOTSUPP;
406 + if (copy_from_user(&fiemap, (struct fiemap __user *)arg,
407 + sizeof(struct fiemap)))
408 + return -EFAULT;
410 + if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
411 + return -EINVAL;
413 + error = fiemap_check_ranges(sb, fiemap.fm_start, fiemap.fm_length,
414 + &len);
415 + if (error)
416 + return error;
418 + fieinfo.fi_flags = fiemap.fm_flags;
419 + fieinfo.fi_extents_max = fiemap.fm_extent_count;
420 + fieinfo.fi_extents_start = (struct fiemap_extent *)(arg + sizeof(fiemap));
422 + if (fiemap.fm_extent_count != 0 &&
423 + !access_ok(VERIFY_WRITE, fieinfo.fi_extents_start,
424 + fieinfo.fi_extents_max * sizeof(struct fiemap_extent)))
425 + return -EFAULT;
427 + if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
428 + filemap_write_and_wait(inode->i_mapping);
430 + error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start, len);
431 + fiemap.fm_flags = fieinfo.fi_flags;
432 + fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
433 + if (copy_to_user((char *)arg, &fiemap, sizeof(fiemap)))
434 + error = -EFAULT;
436 + return error;
439 static int file_ioctl(struct file *filp, unsigned int cmd,
440 unsigned long arg)
442 @@ -80,6 +236,8 @@ static int file_ioctl(struct file *filp,
443 switch (cmd) {
444 case FIBMAP:
445 return ioctl_fibmap(filp, p);
446 + case FS_IOC_FIEMAP:
447 + return ioctl_fiemap(filp, arg);
448 case FIGETBSZ:
449 return put_user(inode->i_sb->s_blocksize, p);
450 case FIONREAD:
451 Index: linux-2.6/include/linux/fiemap.h
452 ===================================================================
453 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
454 +++ linux-2.6/include/linux/fiemap.h 2008-07-14 16:53:46.040353378 -0500
455 @@ -0,0 +1,68 @@
457 + * FS_IOC_FIEMAP ioctl infrastructure.
459 + * Some portions copyright (C) 2007 Cluster File Systems, Inc
461 + * Authors: Mark Fasheh <mfasheh@suse.com>
462 + * Kalpak Shah <kalpak.shah@sun.com>
463 + * Andreas Dilger <adilger@sun.com>
464 + */
466 +#ifndef _LINUX_FIEMAP_H
467 +#define _LINUX_FIEMAP_H
469 +struct fiemap_extent {
470 + __u64 fe_logical; /* logical offset in bytes for the start of
471 + * the extent from the beginning of the file */
472 + __u64 fe_physical; /* physical offset in bytes for the start
473 + * of the extent from the beginning of the disk */
474 + __u64 fe_length; /* length in bytes for this extent */
475 + __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */
476 + __u32 fe_device; /* device number for this extent */
479 +struct fiemap {
480 + __u64 fm_start; /* logical offset (inclusive) at
481 + * which to start mapping (in) */
482 + __u64 fm_length; /* logical length of mapping which
483 + * userspace wants (in) */
484 + __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
485 + __u32 fm_mapped_extents;/* number of extents that were mapped (out) */
486 + __u32 fm_extent_count; /* size of fm_extents array (in) */
487 + __u32 fm_reserved;
488 + struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
491 +#define FIEMAP_MAX_OFFSET (~0ULL)
493 +#define FIEMAP_FLAG_SYNC 0x00000001 /* sync file data before map */
494 +#define FIEMAP_FLAG_XATTR 0x00000002 /* map extended attribute tree */
496 +#define FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR)
498 +#define FIEMAP_EXTENT_LAST 0x00000001 /* Last extent in file. */
499 +#define FIEMAP_EXTENT_UNKNOWN 0x00000002 /* Data location unknown. */
500 +#define FIEMAP_EXTENT_DELALLOC 0x00000004 /* Location still pending.
501 + * Sets EXTENT_UNKNOWN. */
502 +#define FIEMAP_EXTENT_NO_DIRECT 0x00000008 /* Data mapping undefined */
503 +#define FIEMAP_EXTENT_SECONDARY 0x00000010 /* Data copied offline. May
504 + * set EXTENT_NO_DIRECT. */
505 +#define FIEMAP_EXTENT_NET 0x00000020 /* Data stored remotely.
506 + * Sets EXTENT_NO_DIRECT. */
507 +#define FIEMAP_EXTENT_DATA_COMPRESSED 0x00000040 /* Data is compressed by fs.
508 + * Sets EXTENT_NO_DIRECT. */
509 +#define FIEMAP_EXTENT_DATA_ENCRYPTED 0x00000080 /* Data is encrypted by fs.
510 + * Sets EXTENT_NO_DIRECT. */
511 +#define FIEMAP_EXTENT_NOT_ALIGNED 0x00000100 /* Extent offsets may not be
512 + * block aligned. */
513 +#define FIEMAP_EXTENT_DATA_INLINE 0x00000200 /* Data mixed with metadata.
514 + * Sets EXTENT_NOT_ALIGNED.*/
515 +#define FIEMAP_EXTENT_DATA_TAIL 0x00000400 /* Multiple files in block.
516 + * Sets EXTENT_NOT_ALIGNED.*/
517 +#define FIEMAP_EXTENT_UNWRITTEN 0x00000800 /* Space allocated, but
518 + * no data (i.e. zero). */
519 +#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively
520 + * support extents. Result
521 + * merged for efficiency. */
523 +#endif /* _LINUX_FIEMAP_H */
524 Index: linux-2.6/include/linux/fs.h
525 ===================================================================
526 --- linux-2.6.orig/include/linux/fs.h 2008-07-14 16:51:43.073354079 -0500
527 +++ linux-2.6/include/linux/fs.h 2008-07-14 16:53:46.046353840 -0500
528 @@ -229,6 +229,7 @@ extern int dir_notify_enable;
529 #define FS_IOC_SETFLAGS _IOW('f', 2, long)
530 #define FS_IOC_GETVERSION _IOR('v', 1, long)
531 #define FS_IOC_SETVERSION _IOW('v', 2, long)
532 +#define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
533 #define FS_IOC32_GETFLAGS _IOR('f', 1, int)
534 #define FS_IOC32_SETFLAGS _IOW('f', 2, int)
535 #define FS_IOC32_GETVERSION _IOR('v', 1, int)
536 @@ -289,6 +290,7 @@ extern int dir_notify_enable;
537 #include <linux/mutex.h>
538 #include <linux/capability.h>
539 #include <linux/semaphore.h>
540 +#include <linux/fiemap.h>
542 #include <asm/atomic.h>
543 #include <asm/byteorder.h>
544 @@ -1143,6 +1145,20 @@ extern void dentry_unhash(struct dentry
545 extern int file_permission(struct file *, int);
548 + * VFS FS_IOC_FIEMAP helper definitions.
549 + */
550 +struct fiemap_extent_info {
551 + unsigned int fi_flags; /* Flags as passed from user */
552 + unsigned int fi_extents_mapped; /* Number of mapped extents */
553 + unsigned int fi_extents_max; /* Size of fiemap_extent array */
554 + struct fiemap_extent *fi_extents_start; /* Start of fiemap_extent
555 + * array */
557 +int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
558 + u64 phys, u64 len, u32 flags, dev_t dev);
559 +int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
562 * File types
564 * NOTE! These match bits 12..15 of stat.st_mode
565 @@ -1272,6 +1288,8 @@ struct inode_operations {
566 void (*truncate_range)(struct inode *, loff_t, loff_t);
567 long (*fallocate)(struct inode *inode, int mode, loff_t offset,
568 loff_t len);
569 + int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
570 + u64 len);
573 struct seq_file;