vfs: vfs-level fiemap interface
[linux-2.6.git] / fs / ioctl.c
1 /*
2  *  linux/fs/ioctl.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 #include <linux/syscalls.h>
8 #include <linux/mm.h>
9 #include <linux/smp_lock.h>
10 #include <linux/capability.h>
11 #include <linux/file.h>
12 #include <linux/fs.h>
13 #include <linux/security.h>
14 #include <linux/module.h>
15 #include <linux/uaccess.h>
16
17 #include <asm/ioctls.h>
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
22 /**
23  * vfs_ioctl - call filesystem specific ioctl methods
24  * @filp:       open file to invoke ioctl method on
25  * @cmd:        ioctl command to execute
26  * @arg:        command-specific argument for ioctl
27  *
28  * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
29  * invokes filesystem specific ->ioctl method.  If neither method exists,
30  * returns -ENOTTY.
31  *
32  * Returns 0 on success, -errno on error.
33  */
34 static long vfs_ioctl(struct file *filp, unsigned int cmd,
35                       unsigned long arg)
36 {
37         int error = -ENOTTY;
38
39         if (!filp->f_op)
40                 goto out;
41
42         if (filp->f_op->unlocked_ioctl) {
43                 error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
44                 if (error == -ENOIOCTLCMD)
45                         error = -EINVAL;
46                 goto out;
47         } else if (filp->f_op->ioctl) {
48                 lock_kernel();
49                 error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
50                                           filp, cmd, arg);
51                 unlock_kernel();
52         }
53
54  out:
55         return error;
56 }
57
58 static int ioctl_fibmap(struct file *filp, int __user *p)
59 {
60         struct address_space *mapping = filp->f_mapping;
61         int res, block;
62
63         /* do we support this mess? */
64         if (!mapping->a_ops->bmap)
65                 return -EINVAL;
66         if (!capable(CAP_SYS_RAWIO))
67                 return -EPERM;
68         res = get_user(block, p);
69         if (res)
70                 return res;
71         lock_kernel();
72         res = mapping->a_ops->bmap(mapping, block);
73         unlock_kernel();
74         return put_user(res, p);
75 }
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)
95 int 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 }
132 EXPORT_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  */
148 int 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 }
159 EXPORT_SYMBOL(fiemap_check_flags);
160
161 static 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
182 static 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
227 static int file_ioctl(struct file *filp, unsigned int cmd,
228                 unsigned long arg)
229 {
230         struct inode *inode = filp->f_path.dentry->d_inode;
231         int __user *p = (int __user *)arg;
232
233         switch (cmd) {
234         case FIBMAP:
235                 return ioctl_fibmap(filp, p);
236         case FS_IOC_FIEMAP:
237                 return ioctl_fiemap(filp, arg);
238         case FIGETBSZ:
239                 return put_user(inode->i_sb->s_blocksize, p);
240         case FIONREAD:
241                 return put_user(i_size_read(inode) - filp->f_pos, p);
242         }
243
244         return vfs_ioctl(filp, cmd, arg);
245 }
246
247 static int ioctl_fionbio(struct file *filp, int __user *argp)
248 {
249         unsigned int flag;
250         int on, error;
251
252         error = get_user(on, argp);
253         if (error)
254                 return error;
255         flag = O_NONBLOCK;
256 #ifdef __sparc__
257         /* SunOS compatibility item. */
258         if (O_NONBLOCK != O_NDELAY)
259                 flag |= O_NDELAY;
260 #endif
261         if (on)
262                 filp->f_flags |= flag;
263         else
264                 filp->f_flags &= ~flag;
265         return error;
266 }
267
268 static int ioctl_fioasync(unsigned int fd, struct file *filp,
269                           int __user *argp)
270 {
271         unsigned int flag;
272         int on, error;
273
274         error = get_user(on, argp);
275         if (error)
276                 return error;
277         flag = on ? FASYNC : 0;
278
279         /* Did FASYNC state change ? */
280         if ((flag ^ filp->f_flags) & FASYNC) {
281                 if (filp->f_op && filp->f_op->fasync) {
282                         lock_kernel();
283                         error = filp->f_op->fasync(fd, filp, on);
284                         unlock_kernel();
285                 } else
286                         error = -ENOTTY;
287         }
288         if (error)
289                 return error;
290
291         if (on)
292                 filp->f_flags |= FASYNC;
293         else
294                 filp->f_flags &= ~FASYNC;
295         return error;
296 }
297
298 /*
299  * When you add any new common ioctls to the switches above and below
300  * please update compat_sys_ioctl() too.
301  *
302  * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
303  * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
304  */
305 int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
306              unsigned long arg)
307 {
308         int error = 0;
309         int __user *argp = (int __user *)arg;
310
311         switch (cmd) {
312         case FIOCLEX:
313                 set_close_on_exec(fd, 1);
314                 break;
315
316         case FIONCLEX:
317                 set_close_on_exec(fd, 0);
318                 break;
319
320         case FIONBIO:
321                 error = ioctl_fionbio(filp, argp);
322                 break;
323
324         case FIOASYNC:
325                 error = ioctl_fioasync(fd, filp, argp);
326                 break;
327
328         case FIOQSIZE:
329                 if (S_ISDIR(filp->f_path.dentry->d_inode->i_mode) ||
330                     S_ISREG(filp->f_path.dentry->d_inode->i_mode) ||
331                     S_ISLNK(filp->f_path.dentry->d_inode->i_mode)) {
332                         loff_t res =
333                                 inode_get_bytes(filp->f_path.dentry->d_inode);
334                         error = copy_to_user((loff_t __user *)arg, &res,
335                                              sizeof(res)) ? -EFAULT : 0;
336                 } else
337                         error = -ENOTTY;
338                 break;
339         default:
340                 if (S_ISREG(filp->f_path.dentry->d_inode->i_mode))
341                         error = file_ioctl(filp, cmd, arg);
342                 else
343                         error = vfs_ioctl(filp, cmd, arg);
344                 break;
345         }
346         return error;
347 }
348
349 asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
350 {
351         struct file *filp;
352         int error = -EBADF;
353         int fput_needed;
354
355         filp = fget_light(fd, &fput_needed);
356         if (!filp)
357                 goto out;
358
359         error = security_file_ioctl(filp, cmd, arg);
360         if (error)
361                 goto out_fput;
362
363         error = do_vfs_ioctl(filp, fd, cmd, arg);
364  out_fput:
365         fput_light(filp, fput_needed);
366  out:
367         return error;
368 }