aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.com>2008-10-08 19:44:18 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-10-08 19:44:18 -0400
commitc4b929b85bdb64afacbbf6453b1f2bf7e14c9e89 (patch)
tree6f5a4b1378d7b609d0f1ceab93fb501cf91b218a
parent4d20c685fa365766a8f13584b4c8178a15ab7103 (diff)
vfs: vfs-level fiemap interface
Basic vfs-level fiemap infrastructure, which sets up a new ->fiemap inode operation. Userspace can get extent information on a file via fiemap ioctl. As input, the fiemap ioctl takes a struct fiemap which includes an array of struct fiemap_extent (fm_extents). Size of the extent array is passed as fm_extent_count and number of extents returned will be written into fm_mapped_extents. Offset and length fields on the fiemap structure (fm_start, fm_length) describe a logical range which will be searched for extents. All extents returned will at least partially contain this range. The actual extent offsets and ranges returned will be unmodified from their offset and range on-disk. The fiemap ioctl returns '0' on success. On error, -1 is returned and errno is set. If errno is equal to EBADR, then fm_flags will contain those flags which were passed in which the kernel did not understand. On all other errors, the contents of fm_extents is undefined. As fiemap evolved, there have been many authors of the vfs patch. As far as I can tell, the list includes: Kalpak Shah <kalpak.shah@sun.com> Andreas Dilger <adilger@sun.com> Eric Sandeen <sandeen@redhat.com> Mark Fasheh <mfasheh@suse.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: Michael Kerrisk <mtk.manpages@googlemail.com> Cc: linux-api@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org
-rw-r--r--Documentation/filesystems/fiemap.txt228
-rw-r--r--fs/ioctl.c155
-rw-r--r--include/linux/fiemap.h64
-rw-r--r--include/linux/fs.h18
4 files changed, 465 insertions, 0 deletions
diff --git a/Documentation/filesystems/fiemap.txt b/Documentation/filesystems/fiemap.txt
new file mode 100644
index 000000000000..1e3defcfe50b
--- /dev/null
+++ b/Documentation/filesystems/fiemap.txt
@@ -0,0 +1,228 @@
1============
2Fiemap Ioctl
3============
4
5The fiemap ioctl is an efficient method for userspace to get file
6extent mappings. Instead of block-by-block mapping (such as bmap), fiemap
7returns a list of extents.
8
9
10Request Basics
11--------------
12
13A fiemap request is encoded within struct fiemap:
14
15struct fiemap {
16 __u64 fm_start; /* logical offset (inclusive) at
17 * which to start mapping (in) */
18 __u64 fm_length; /* logical length of mapping which
19 * userspace cares about (in) */
20 __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
21 __u32 fm_mapped_extents; /* number of extents that were
22 * mapped (out) */
23 __u32 fm_extent_count; /* size of fm_extents array (in) */
24 __u32 fm_reserved;
25 struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
26};
27
28
29fm_start, and fm_length specify the logical range within the file
30which the process would like mappings for. Extents returned mirror
31those on disk - that is, the logical offset of the 1st returned extent
32may start before fm_start, and the range covered by the last returned
33extent may end after fm_length. All offsets and lengths are in bytes.
34
35Certain flags to modify the way in which mappings are looked up can be
36set in fm_flags. If the kernel doesn't understand some particular
37flags, it will return EBADR and the contents of fm_flags will contain
38the set of flags which caused the error. If the kernel is compatible
39with all flags passed, the contents of fm_flags will be unmodified.
40It is up to userspace to determine whether rejection of a particular
41flag is fatal to it's operation. This scheme is intended to allow the
42fiemap interface to grow in the future but without losing
43compatibility with old software.
44
45fm_extent_count specifies the number of elements in the fm_extents[] array
46that can be used to return extents. If fm_extent_count is zero, then the
47fm_extents[] array is ignored (no extents will be returned), and the
48fm_mapped_extents count will hold the number of extents needed in
49fm_extents[] to hold the file's current mapping. Note that there is
50nothing to prevent the file from changing between calls to FIEMAP.
51
52The following flags can be set in fm_flags:
53
54* FIEMAP_FLAG_SYNC
55If this flag is set, the kernel will sync the file before mapping extents.
56
57* FIEMAP_FLAG_XATTR
58If this flag is set, the extents returned will describe the inodes
59extended attribute lookup tree, instead of it's data tree.
60
61
62Extent Mapping
63--------------
64
65Extent information is returned within the embedded fm_extents array
66which userspace must allocate along with the fiemap structure. The
67number of elements in the fiemap_extents[] array should be passed via
68fm_extent_count. The number of extents mapped by kernel will be
69returned via fm_mapped_extents. If the number of fiemap_extents
70allocated is less than would be required to map the requested range,
71the maximum number of extents that can be mapped in the fm_extent[]
72array will be returned and fm_mapped_extents will be equal to
73fm_extent_count. In that case, the last extent in the array will not
74complete the requested range and will not have the FIEMAP_EXTENT_LAST
75flag set (see the next section on extent flags).
76
77Each extent is described by a single fiemap_extent structure as
78returned in fm_extents.
79
80struct fiemap_extent {
81 __u64 fe_logical; /* logical offset in bytes for the start of
82 * the extent */
83 __u64 fe_physical; /* physical offset in bytes for the start
84 * of the extent */
85 __u64 fe_length; /* length in bytes for the extent */
86 __u64 fe_reserved64[2];
87 __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */
88 __u32 fe_reserved[3];
89};
90
91All offsets and lengths are in bytes and mirror those on disk. It is valid
92for an extents logical offset to start before the request or it's logical
93length to extend past the request. Unless FIEMAP_EXTENT_NOT_ALIGNED is
94returned, fe_logical, fe_physical, and fe_length will be aligned to the
95block size of the file system. With the exception of extents flagged as
96FIEMAP_EXTENT_MERGED, adjacent extents will not be merged.
97
98The fe_flags field contains flags which describe the extent returned.
99A special flag, FIEMAP_EXTENT_LAST is always set on the last extent in
100the file so that the process making fiemap calls can determine when no
101more extents are available, without having to call the ioctl again.
102
103Some flags are intentionally vague and will always be set in the
104presence of other more specific flags. This way a program looking for
105a general property does not have to know all existing and future flags
106which imply that property.
107
108For example, if FIEMAP_EXTENT_DATA_INLINE or FIEMAP_EXTENT_DATA_TAIL
109are set, FIEMAP_EXTENT_NOT_ALIGNED will also be set. A program looking
110for inline or tail-packed data can key on the specific flag. Software
111which simply cares not to try operating on non-aligned extents
112however, can just key on FIEMAP_EXTENT_NOT_ALIGNED, and not have to
113worry about all present and future flags which might imply unaligned
114data. Note that the opposite is not true - it would be valid for
115FIEMAP_EXTENT_NOT_ALIGNED to appear alone.
116
117* FIEMAP_EXTENT_LAST
118This is the last extent in the file. A mapping attempt past this
119extent will return nothing.
120
121* FIEMAP_EXTENT_UNKNOWN
122The location of this extent is currently unknown. This may indicate
123the data is stored on an inaccessible volume or that no storage has
124been allocated for the file yet.
125
126* FIEMAP_EXTENT_DELALLOC
127 - This will also set FIEMAP_EXTENT_UNKNOWN.
128Delayed allocation - while there is data for this extent, it's
129physical location has not been allocated yet.
130
131* FIEMAP_EXTENT_ENCODED
132This extent does not consist of plain filesystem blocks but is
133encoded (e.g. encrypted or compressed). Reading the data in this
134extent via I/O to the block device will have undefined results.
135
136Note that it is *always* undefined to try to update the data
137in-place by writing to the indicated location without the
138assistance of the filesystem, or to access the data using the
139information returned by the FIEMAP interface while the filesystem
140is mounted. In other words, user applications may only read the
141extent data via I/O to the block device while the filesystem is
142unmounted, and then only if the FIEMAP_EXTENT_ENCODED flag is
143clear; user applications must not try reading or writing to the
144filesystem via the block device under any other circumstances.
145
146* FIEMAP_EXTENT_DATA_ENCRYPTED
147 - This will also set FIEMAP_EXTENT_ENCODED
148The data in this extent has been encrypted by the file system.
149
150* FIEMAP_EXTENT_NOT_ALIGNED
151Extent offsets and length are not guaranteed to be block aligned.
152
153* FIEMAP_EXTENT_DATA_INLINE
154 This will also set FIEMAP_EXTENT_NOT_ALIGNED
155Data is located within a meta data block.
156
157* FIEMAP_EXTENT_DATA_TAIL
158 This will also set FIEMAP_EXTENT_NOT_ALIGNED
159Data is packed into a block with data from other files.
160
161* FIEMAP_EXTENT_UNWRITTEN
162Unwritten extent - the extent is allocated but it's data has not been
163initialized. This indicates the extent's data will be all zero if read
164through the filesystem but the contents are undefined if read directly from
165the device.
166
167* FIEMAP_EXTENT_MERGED
168This will be set when a file does not support extents, i.e., it uses a block
169based addressing scheme. Since returning an extent for each block back to
170userspace would be highly inefficient, the kernel will try to merge most
171adjacent blocks into 'extents'.
172
173
174VFS -> File System Implementation
175---------------------------------
176
177File systems wishing to support fiemap must implement a ->fiemap callback on
178their inode_operations structure. The fs ->fiemap call is responsible for
179defining it's set of supported fiemap flags, and calling a helper function on
180each discovered extent:
181
182struct inode_operations {
183 ...
184
185 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
186 u64 len);
187
188->fiemap is passed struct fiemap_extent_info which describes the
189fiemap request:
190
191struct fiemap_extent_info {
192 unsigned int fi_flags; /* Flags as passed from user */
193 unsigned int fi_extents_mapped; /* Number of mapped extents */
194 unsigned int fi_extents_max; /* Size of fiemap_extent array */
195 struct fiemap_extent *fi_extents_start; /* Start of fiemap_extent array */
196};
197
198It is intended that the file system should not need to access any of this
199structure directly.
200
201
202Flag checking should be done at the beginning of the ->fiemap callback via the
203fiemap_check_flags() helper:
204
205int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
206
207The struct fieinfo should be passed in as recieved from ioctl_fiemap(). The
208set of fiemap flags which the fs understands should be passed via fs_flags. If
209fiemap_check_flags finds invalid user flags, it will place the bad values in
210fieinfo->fi_flags and return -EBADR. If the file system gets -EBADR, from
211fiemap_check_flags(), it should immediately exit, returning that error back to
212ioctl_fiemap().
213
214
215For each extent in the request range, the file system should call
216the helper function, fiemap_fill_next_extent():
217
218int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
219 u64 phys, u64 len, u32 flags, u32 dev);
220
221fiemap_fill_next_extent() will use the passed values to populate the
222next free extent in the fm_extents array. 'General' extent flags will
223automatically be set from specific flags on behalf of the calling file
224system so that the userspace API is not broken.
225
226fiemap_fill_next_extent() returns 0 on success, and 1 when the
227user-supplied fm_extents array is full. If an error is encountered
228while copying the extent to user memory, -EFAULT will be returned.
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 7db32b3382d3..045d9601fbbd 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -16,6 +16,9 @@
16 16
17#include <asm/ioctls.h> 17#include <asm/ioctls.h>
18 18
19/* So that the fiemap access checks can't overflow on 32 bit machines. */
20#define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent))
21
19/** 22/**
20 * vfs_ioctl - call filesystem specific ioctl methods 23 * vfs_ioctl - call filesystem specific ioctl methods
21 * @filp: open file to invoke ioctl method on 24 * @filp: open file to invoke ioctl method on
@@ -71,6 +74,156 @@ static int ioctl_fibmap(struct file *filp, int __user *p)
71 return put_user(res, p); 74 return put_user(res, p);
72} 75}
73 76
77/**
78 * fiemap_fill_next_extent - Fiemap helper function
79 * @fieinfo: Fiemap context passed into ->fiemap
80 * @logical: Extent logical start offset, in bytes
81 * @phys: Extent physical start offset, in bytes
82 * @len: Extent length, in bytes
83 * @flags: FIEMAP_EXTENT flags that describe this extent
84 *
85 * Called from file system ->fiemap callback. Will populate extent
86 * info as passed in via arguments and copy to user memory. On
87 * success, extent count on fieinfo is incremented.
88 *
89 * Returns 0 on success, -errno on error, 1 if this was the last
90 * extent that will fit in user array.
91 */
92#define SET_UNKNOWN_FLAGS (FIEMAP_EXTENT_DELALLOC)
93#define SET_NO_UNMOUNTED_IO_FLAGS (FIEMAP_EXTENT_DATA_ENCRYPTED)
94#define SET_NOT_ALIGNED_FLAGS (FIEMAP_EXTENT_DATA_TAIL|FIEMAP_EXTENT_DATA_INLINE)
95int fiemap_fill_next_extent(struct fiemap_extent_info *fieinfo, u64 logical,
96 u64 phys, u64 len, u32 flags)
97{
98 struct fiemap_extent extent;
99 struct fiemap_extent *dest = fieinfo->fi_extents_start;
100
101 /* only count the extents */
102 if (fieinfo->fi_extents_max == 0) {
103 fieinfo->fi_extents_mapped++;
104 return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
105 }
106
107 if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max)
108 return 1;
109
110 if (flags & SET_UNKNOWN_FLAGS)
111 flags |= FIEMAP_EXTENT_UNKNOWN;
112 if (flags & SET_NO_UNMOUNTED_IO_FLAGS)
113 flags |= FIEMAP_EXTENT_ENCODED;
114 if (flags & SET_NOT_ALIGNED_FLAGS)
115 flags |= FIEMAP_EXTENT_NOT_ALIGNED;
116
117 memset(&extent, 0, sizeof(extent));
118 extent.fe_logical = logical;
119 extent.fe_physical = phys;
120 extent.fe_length = len;
121 extent.fe_flags = flags;
122
123 dest += fieinfo->fi_extents_mapped;
124 if (copy_to_user(dest, &extent, sizeof(extent)))
125 return -EFAULT;
126
127 fieinfo->fi_extents_mapped++;
128 if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max)
129 return 1;
130 return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0;
131}
132EXPORT_SYMBOL(fiemap_fill_next_extent);
133
134/**
135 * fiemap_check_flags - check validity of requested flags for fiemap
136 * @fieinfo: Fiemap context passed into ->fiemap
137 * @fs_flags: Set of fiemap flags that the file system understands
138 *
139 * Called from file system ->fiemap callback. This will compute the
140 * intersection of valid fiemap flags and those that the fs supports. That
141 * value is then compared against the user supplied flags. In case of bad user
142 * flags, the invalid values will be written into the fieinfo structure, and
143 * -EBADR is returned, which tells ioctl_fiemap() to return those values to
144 * userspace. For this reason, a return code of -EBADR should be preserved.
145 *
146 * Returns 0 on success, -EBADR on bad flags.
147 */
148int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags)
149{
150 u32 incompat_flags;
151
152 incompat_flags = fieinfo->fi_flags & ~(FIEMAP_FLAGS_COMPAT & fs_flags);
153 if (incompat_flags) {
154 fieinfo->fi_flags = incompat_flags;
155 return -EBADR;
156 }
157 return 0;
158}
159EXPORT_SYMBOL(fiemap_check_flags);
160
161static int fiemap_check_ranges(struct super_block *sb,
162 u64 start, u64 len, u64 *new_len)
163{
164 *new_len = len;
165
166 if (len == 0)
167 return -EINVAL;
168
169 if (start > sb->s_maxbytes)
170 return -EFBIG;
171
172 /*
173 * Shrink request scope to what the fs can actually handle.
174 */
175 if ((len > sb->s_maxbytes) ||
176 (sb->s_maxbytes - len) < start)
177 *new_len = sb->s_maxbytes - start;
178
179 return 0;
180}
181
182static int ioctl_fiemap(struct file *filp, unsigned long arg)
183{
184 struct fiemap fiemap;
185 struct fiemap_extent_info fieinfo = { 0, };
186 struct inode *inode = filp->f_path.dentry->d_inode;
187 struct super_block *sb = inode->i_sb;
188 u64 len;
189 int error;
190
191 if (!inode->i_op->fiemap)
192 return -EOPNOTSUPP;
193
194 if (copy_from_user(&fiemap, (struct fiemap __user *)arg,
195 sizeof(struct fiemap)))
196 return -EFAULT;
197
198 if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS)
199 return -EINVAL;
200
201 error = fiemap_check_ranges(sb, fiemap.fm_start, fiemap.fm_length,
202 &len);
203 if (error)
204 return error;
205
206 fieinfo.fi_flags = fiemap.fm_flags;
207 fieinfo.fi_extents_max = fiemap.fm_extent_count;
208 fieinfo.fi_extents_start = (struct fiemap_extent *)(arg + sizeof(fiemap));
209
210 if (fiemap.fm_extent_count != 0 &&
211 !access_ok(VERIFY_WRITE, fieinfo.fi_extents_start,
212 fieinfo.fi_extents_max * sizeof(struct fiemap_extent)))
213 return -EFAULT;
214
215 if (fieinfo.fi_flags & FIEMAP_FLAG_SYNC)
216 filemap_write_and_wait(inode->i_mapping);
217
218 error = inode->i_op->fiemap(inode, &fieinfo, fiemap.fm_start, len);
219 fiemap.fm_flags = fieinfo.fi_flags;
220 fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped;
221 if (copy_to_user((char *)arg, &fiemap, sizeof(fiemap)))
222 error = -EFAULT;
223
224 return error;
225}
226
74static int file_ioctl(struct file *filp, unsigned int cmd, 227static int file_ioctl(struct file *filp, unsigned int cmd,
75 unsigned long arg) 228 unsigned long arg)
76{ 229{
@@ -80,6 +233,8 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
80 switch (cmd) { 233 switch (cmd) {
81 case FIBMAP: 234 case FIBMAP:
82 return ioctl_fibmap(filp, p); 235 return ioctl_fibmap(filp, p);
236 case FS_IOC_FIEMAP:
237 return ioctl_fiemap(filp, arg);
83 case FIGETBSZ: 238 case FIGETBSZ:
84 return put_user(inode->i_sb->s_blocksize, p); 239 return put_user(inode->i_sb->s_blocksize, p);
85 case FIONREAD: 240 case FIONREAD:
diff --git a/include/linux/fiemap.h b/include/linux/fiemap.h
new file mode 100644
index 000000000000..671decbd2aeb
--- /dev/null
+++ b/include/linux/fiemap.h
@@ -0,0 +1,64 @@
1/*
2 * FS_IOC_FIEMAP ioctl infrastructure.
3 *
4 * Some portions copyright (C) 2007 Cluster File Systems, Inc
5 *
6 * Authors: Mark Fasheh <mfasheh@suse.com>
7 * Kalpak Shah <kalpak.shah@sun.com>
8 * Andreas Dilger <adilger@sun.com>
9 */
10
11#ifndef _LINUX_FIEMAP_H
12#define _LINUX_FIEMAP_H
13
14struct fiemap_extent {
15 __u64 fe_logical; /* logical offset in bytes for the start of
16 * the extent from the beginning of the file */
17 __u64 fe_physical; /* physical offset in bytes for the start
18 * of the extent from the beginning of the disk */
19 __u64 fe_length; /* length in bytes for this extent */
20 __u64 fe_reserved64[2];
21 __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */
22 __u32 fe_reserved[3];
23};
24
25struct fiemap {
26 __u64 fm_start; /* logical offset (inclusive) at
27 * which to start mapping (in) */
28 __u64 fm_length; /* logical length of mapping which
29 * userspace wants (in) */
30 __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
31 __u32 fm_mapped_extents;/* number of extents that were mapped (out) */
32 __u32 fm_extent_count; /* size of fm_extents array (in) */
33 __u32 fm_reserved;
34 struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
35};
36
37#define FIEMAP_MAX_OFFSET (~0ULL)
38
39#define FIEMAP_FLAG_SYNC 0x00000001 /* sync file data before map */
40#define FIEMAP_FLAG_XATTR 0x00000002 /* map extended attribute tree */
41
42#define FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR)
43
44#define FIEMAP_EXTENT_LAST 0x00000001 /* Last extent in file. */
45#define FIEMAP_EXTENT_UNKNOWN 0x00000002 /* Data location unknown. */
46#define FIEMAP_EXTENT_DELALLOC 0x00000004 /* Location still pending.
47 * Sets EXTENT_UNKNOWN. */
48#define FIEMAP_EXTENT_ENCODED 0x00000008 /* Data can not be read
49 * while fs is unmounted */
50#define FIEMAP_EXTENT_DATA_ENCRYPTED 0x00000080 /* Data is encrypted by fs.
51 * Sets EXTENT_NO_BYPASS. */
52#define FIEMAP_EXTENT_NOT_ALIGNED 0x00000100 /* Extent offsets may not be
53 * block aligned. */
54#define FIEMAP_EXTENT_DATA_INLINE 0x00000200 /* Data mixed with metadata.
55 * Sets EXTENT_NOT_ALIGNED.*/
56#define FIEMAP_EXTENT_DATA_TAIL 0x00000400 /* Multiple files in block.
57 * Sets EXTENT_NOT_ALIGNED.*/
58#define FIEMAP_EXTENT_UNWRITTEN 0x00000800 /* Space allocated, but
59 * no data (i.e. zero). */
60#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively
61 * support extents. Result
62 * merged for efficiency. */
63
64#endif /* _LINUX_FIEMAP_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 580b513668fe..194fb237a307 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -231,6 +231,7 @@ extern int dir_notify_enable;
231#define FS_IOC_SETFLAGS _IOW('f', 2, long) 231#define FS_IOC_SETFLAGS _IOW('f', 2, long)
232#define FS_IOC_GETVERSION _IOR('v', 1, long) 232#define FS_IOC_GETVERSION _IOR('v', 1, long)
233#define FS_IOC_SETVERSION _IOW('v', 2, long) 233#define FS_IOC_SETVERSION _IOW('v', 2, long)
234#define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap)
234#define FS_IOC32_GETFLAGS _IOR('f', 1, int) 235#define FS_IOC32_GETFLAGS _IOR('f', 1, int)
235#define FS_IOC32_SETFLAGS _IOW('f', 2, int) 236#define FS_IOC32_SETFLAGS _IOW('f', 2, int)
236#define FS_IOC32_GETVERSION _IOR('v', 1, int) 237#define FS_IOC32_GETVERSION _IOR('v', 1, int)
@@ -291,6 +292,7 @@ extern int dir_notify_enable;
291#include <linux/mutex.h> 292#include <linux/mutex.h>
292#include <linux/capability.h> 293#include <linux/capability.h>
293#include <linux/semaphore.h> 294#include <linux/semaphore.h>
295#include <linux/fiemap.h>
294 296
295#include <asm/atomic.h> 297#include <asm/atomic.h>
296#include <asm/byteorder.h> 298#include <asm/byteorder.h>
@@ -1179,6 +1181,20 @@ extern void dentry_unhash(struct dentry *dentry);
1179extern int file_permission(struct file *, int); 1181extern int file_permission(struct file *, int);
1180 1182
1181/* 1183/*
1184 * VFS FS_IOC_FIEMAP helper definitions.
1185 */
1186struct fiemap_extent_info {
1187 unsigned int fi_flags; /* Flags as passed from user */
1188 unsigned int fi_extents_mapped; /* Number of mapped extents */
1189 unsigned int fi_extents_max; /* Size of fiemap_extent array */
1190 struct fiemap_extent *fi_extents_start; /* Start of fiemap_extent
1191 * array */
1192};
1193int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
1194 u64 phys, u64 len, u32 flags);
1195int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
1196
1197/*
1182 * File types 1198 * File types
1183 * 1199 *
1184 * NOTE! These match bits 12..15 of stat.st_mode 1200 * NOTE! These match bits 12..15 of stat.st_mode
@@ -1287,6 +1303,8 @@ struct inode_operations {
1287 void (*truncate_range)(struct inode *, loff_t, loff_t); 1303 void (*truncate_range)(struct inode *, loff_t, loff_t);
1288 long (*fallocate)(struct inode *inode, int mode, loff_t offset, 1304 long (*fallocate)(struct inode *inode, int mode, loff_t offset,
1289 loff_t len); 1305 loff_t len);
1306 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
1307 u64 len);
1290}; 1308};
1291 1309
1292struct seq_file; 1310struct seq_file;