Revert "Merge remote-tracking branch 'linux-2.6.32.y/master' into develop"
[firefly-linux-kernel-4.4.55.git] / fs / xfs / linux-2.6 / xfs_ioctl.c
1 /*
2  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include "xfs.h"
19 #include "xfs_fs.h"
20 #include "xfs_bit.h"
21 #include "xfs_log.h"
22 #include "xfs_inum.h"
23 #include "xfs_trans.h"
24 #include "xfs_sb.h"
25 #include "xfs_ag.h"
26 #include "xfs_dir2.h"
27 #include "xfs_alloc.h"
28 #include "xfs_dmapi.h"
29 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h"
31 #include "xfs_alloc_btree.h"
32 #include "xfs_ialloc_btree.h"
33 #include "xfs_attr_sf.h"
34 #include "xfs_dir2_sf.h"
35 #include "xfs_dinode.h"
36 #include "xfs_inode.h"
37 #include "xfs_ioctl.h"
38 #include "xfs_btree.h"
39 #include "xfs_ialloc.h"
40 #include "xfs_rtalloc.h"
41 #include "xfs_itable.h"
42 #include "xfs_error.h"
43 #include "xfs_rw.h"
44 #include "xfs_attr.h"
45 #include "xfs_bmap.h"
46 #include "xfs_buf_item.h"
47 #include "xfs_utils.h"
48 #include "xfs_dfrag.h"
49 #include "xfs_fsops.h"
50 #include "xfs_vnodeops.h"
51 #include "xfs_quota.h"
52 #include "xfs_inode_item.h"
53 #include "xfs_export.h"
54
55 #include <linux/capability.h>
56 #include <linux/dcache.h>
57 #include <linux/mount.h>
58 #include <linux/namei.h>
59 #include <linux/pagemap.h>
60 #include <linux/exportfs.h>
61
62 /*
63  * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
64  * a file or fs handle.
65  *
66  * XFS_IOC_PATH_TO_FSHANDLE
67  *    returns fs handle for a mount point or path within that mount point
68  * XFS_IOC_FD_TO_HANDLE
69  *    returns full handle for a FD opened in user space
70  * XFS_IOC_PATH_TO_HANDLE
71  *    returns full handle for a path
72  */
73 int
74 xfs_find_handle(
75         unsigned int            cmd,
76         xfs_fsop_handlereq_t    *hreq)
77 {
78         int                     hsize;
79         xfs_handle_t            handle;
80         struct inode            *inode;
81         struct file             *file = NULL;
82         struct path             path;
83         int                     error;
84         struct xfs_inode        *ip;
85
86         if (cmd == XFS_IOC_FD_TO_HANDLE) {
87                 file = fget(hreq->fd);
88                 if (!file)
89                         return -EBADF;
90                 inode = file->f_path.dentry->d_inode;
91         } else {
92                 error = user_lpath((const char __user *)hreq->path, &path);
93                 if (error)
94                         return error;
95                 inode = path.dentry->d_inode;
96         }
97         ip = XFS_I(inode);
98
99         /*
100          * We can only generate handles for inodes residing on a XFS filesystem,
101          * and only for regular files, directories or symbolic links.
102          */
103         error = -EINVAL;
104         if (inode->i_sb->s_magic != XFS_SB_MAGIC)
105                 goto out_put;
106
107         error = -EBADF;
108         if (!S_ISREG(inode->i_mode) &&
109             !S_ISDIR(inode->i_mode) &&
110             !S_ISLNK(inode->i_mode))
111                 goto out_put;
112
113
114         memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
115
116         if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
117                 /*
118                  * This handle only contains an fsid, zero the rest.
119                  */
120                 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
121                 hsize = sizeof(xfs_fsid_t);
122         } else {
123                 int             lock_mode;
124
125                 lock_mode = xfs_ilock_map_shared(ip);
126                 handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
127                                         sizeof(handle.ha_fid.fid_len);
128                 handle.ha_fid.fid_pad = 0;
129                 handle.ha_fid.fid_gen = ip->i_d.di_gen;
130                 handle.ha_fid.fid_ino = ip->i_ino;
131                 xfs_iunlock_map_shared(ip, lock_mode);
132
133                 hsize = XFS_HSIZE(handle);
134         }
135
136         error = -EFAULT;
137         if (copy_to_user(hreq->ohandle, &handle, hsize) ||
138             copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
139                 goto out_put;
140
141         error = 0;
142
143  out_put:
144         if (cmd == XFS_IOC_FD_TO_HANDLE)
145                 fput(file);
146         else
147                 path_put(&path);
148         return error;
149 }
150
151 /*
152  * No need to do permission checks on the various pathname components
153  * as the handle operations are privileged.
154  */
155 STATIC int
156 xfs_handle_acceptable(
157         void                    *context,
158         struct dentry           *dentry)
159 {
160         return 1;
161 }
162
163 /*
164  * Convert userspace handle data into a dentry.
165  */
166 struct dentry *
167 xfs_handle_to_dentry(
168         struct file             *parfilp,
169         void __user             *uhandle,
170         u32                     hlen)
171 {
172         xfs_handle_t            handle;
173         struct xfs_fid64        fid;
174
175         /*
176          * Only allow handle opens under a directory.
177          */
178         if (!S_ISDIR(parfilp->f_path.dentry->d_inode->i_mode))
179                 return ERR_PTR(-ENOTDIR);
180
181         if (hlen != sizeof(xfs_handle_t))
182                 return ERR_PTR(-EINVAL);
183         if (copy_from_user(&handle, uhandle, hlen))
184                 return ERR_PTR(-EFAULT);
185         if (handle.ha_fid.fid_len !=
186             sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len))
187                 return ERR_PTR(-EINVAL);
188
189         memset(&fid, 0, sizeof(struct fid));
190         fid.ino = handle.ha_fid.fid_ino;
191         fid.gen = handle.ha_fid.fid_gen;
192
193         return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3,
194                         FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
195                         xfs_handle_acceptable, NULL);
196 }
197
198 STATIC struct dentry *
199 xfs_handlereq_to_dentry(
200         struct file             *parfilp,
201         xfs_fsop_handlereq_t    *hreq)
202 {
203         return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
204 }
205
206 int
207 xfs_open_by_handle(
208         struct file             *parfilp,
209         xfs_fsop_handlereq_t    *hreq)
210 {
211         const struct cred       *cred = current_cred();
212         int                     error;
213         int                     fd;
214         int                     permflag;
215         struct file             *filp;
216         struct inode            *inode;
217         struct dentry           *dentry;
218
219         if (!capable(CAP_SYS_ADMIN))
220                 return -XFS_ERROR(EPERM);
221
222         dentry = xfs_handlereq_to_dentry(parfilp, hreq);
223         if (IS_ERR(dentry))
224                 return PTR_ERR(dentry);
225         inode = dentry->d_inode;
226
227         /* Restrict xfs_open_by_handle to directories & regular files. */
228         if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
229                 error = -XFS_ERROR(EPERM);
230                 goto out_dput;
231         }
232
233 #if BITS_PER_LONG != 32
234         hreq->oflags |= O_LARGEFILE;
235 #endif
236
237         /* Put open permission in namei format. */
238         permflag = hreq->oflags;
239         if ((permflag+1) & O_ACCMODE)
240                 permflag++;
241         if (permflag & O_TRUNC)
242                 permflag |= 2;
243
244         if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
245             (permflag & FMODE_WRITE) && IS_APPEND(inode)) {
246                 error = -XFS_ERROR(EPERM);
247                 goto out_dput;
248         }
249
250         if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
251                 error = -XFS_ERROR(EACCES);
252                 goto out_dput;
253         }
254
255         /* Can't write directories. */
256         if (S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) {
257                 error = -XFS_ERROR(EISDIR);
258                 goto out_dput;
259         }
260
261         fd = get_unused_fd();
262         if (fd < 0) {
263                 error = fd;
264                 goto out_dput;
265         }
266
267         filp = dentry_open(dentry, mntget(parfilp->f_path.mnt),
268                            hreq->oflags, cred);
269         if (IS_ERR(filp)) {
270                 put_unused_fd(fd);
271                 return PTR_ERR(filp);
272         }
273
274         if (inode->i_mode & S_IFREG) {
275                 filp->f_flags |= O_NOATIME;
276                 filp->f_mode |= FMODE_NOCMTIME;
277         }
278
279         fd_install(fd, filp);
280         return fd;
281
282  out_dput:
283         dput(dentry);
284         return error;
285 }
286
287 /*
288  * This is a copy from fs/namei.c:vfs_readlink(), except for removing it's
289  * unused first argument.
290  */
291 STATIC int
292 do_readlink(
293         char __user             *buffer,
294         int                     buflen,
295         const char              *link)
296 {
297         int len;
298
299         len = PTR_ERR(link);
300         if (IS_ERR(link))
301                 goto out;
302
303         len = strlen(link);
304         if (len > (unsigned) buflen)
305                 len = buflen;
306         if (copy_to_user(buffer, link, len))
307                 len = -EFAULT;
308  out:
309         return len;
310 }
311
312
313 int
314 xfs_readlink_by_handle(
315         struct file             *parfilp,
316         xfs_fsop_handlereq_t    *hreq)
317 {
318         struct dentry           *dentry;
319         __u32                   olen;
320         void                    *link;
321         int                     error;
322
323         if (!capable(CAP_SYS_ADMIN))
324                 return -XFS_ERROR(EPERM);
325
326         dentry = xfs_handlereq_to_dentry(parfilp, hreq);
327         if (IS_ERR(dentry))
328                 return PTR_ERR(dentry);
329
330         /* Restrict this handle operation to symlinks only. */
331         if (!S_ISLNK(dentry->d_inode->i_mode)) {
332                 error = -XFS_ERROR(EINVAL);
333                 goto out_dput;
334         }
335
336         if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
337                 error = -XFS_ERROR(EFAULT);
338                 goto out_dput;
339         }
340
341         link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
342         if (!link) {
343                 error = -XFS_ERROR(ENOMEM);
344                 goto out_dput;
345         }
346
347         error = -xfs_readlink(XFS_I(dentry->d_inode), link);
348         if (error)
349                 goto out_kfree;
350         error = do_readlink(hreq->ohandle, olen, link);
351         if (error)
352                 goto out_kfree;
353
354  out_kfree:
355         kfree(link);
356  out_dput:
357         dput(dentry);
358         return error;
359 }
360
361 STATIC int
362 xfs_fssetdm_by_handle(
363         struct file             *parfilp,
364         void                    __user *arg)
365 {
366         int                     error;
367         struct fsdmidata        fsd;
368         xfs_fsop_setdm_handlereq_t dmhreq;
369         struct dentry           *dentry;
370
371         if (!capable(CAP_MKNOD))
372                 return -XFS_ERROR(EPERM);
373         if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t)))
374                 return -XFS_ERROR(EFAULT);
375
376         dentry = xfs_handlereq_to_dentry(parfilp, &dmhreq.hreq);
377         if (IS_ERR(dentry))
378                 return PTR_ERR(dentry);
379
380         if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) {
381                 error = -XFS_ERROR(EPERM);
382                 goto out;
383         }
384
385         if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) {
386                 error = -XFS_ERROR(EFAULT);
387                 goto out;
388         }
389
390         error = -xfs_set_dmattrs(XFS_I(dentry->d_inode), fsd.fsd_dmevmask,
391                                  fsd.fsd_dmstate);
392
393  out:
394         dput(dentry);
395         return error;
396 }
397
398 STATIC int
399 xfs_attrlist_by_handle(
400         struct file             *parfilp,
401         void                    __user *arg)
402 {
403         int                     error = -ENOMEM;
404         attrlist_cursor_kern_t  *cursor;
405         xfs_fsop_attrlist_handlereq_t al_hreq;
406         struct dentry           *dentry;
407         char                    *kbuf;
408
409         if (!capable(CAP_SYS_ADMIN))
410                 return -XFS_ERROR(EPERM);
411         if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
412                 return -XFS_ERROR(EFAULT);
413         if (al_hreq.buflen > XATTR_LIST_MAX)
414                 return -XFS_ERROR(EINVAL);
415
416         /*
417          * Reject flags, only allow namespaces.
418          */
419         if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
420                 return -XFS_ERROR(EINVAL);
421
422         dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
423         if (IS_ERR(dentry))
424                 return PTR_ERR(dentry);
425
426         kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL);
427         if (!kbuf)
428                 goto out_dput;
429
430         cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
431         error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen,
432                                         al_hreq.flags, cursor);
433         if (error)
434                 goto out_kfree;
435
436         if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
437                 error = -EFAULT;
438
439  out_kfree:
440         kfree(kbuf);
441  out_dput:
442         dput(dentry);
443         return error;
444 }
445
446 int
447 xfs_attrmulti_attr_get(
448         struct inode            *inode,
449         char                    *name,
450         char                    __user *ubuf,
451         __uint32_t              *len,
452         __uint32_t              flags)
453 {
454         char                    *kbuf;
455         int                     error = EFAULT;
456
457         if (*len > XATTR_SIZE_MAX)
458                 return EINVAL;
459         kbuf = kmalloc(*len, GFP_KERNEL);
460         if (!kbuf)
461                 return ENOMEM;
462
463         error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags);
464         if (error)
465                 goto out_kfree;
466
467         if (copy_to_user(ubuf, kbuf, *len))
468                 error = EFAULT;
469
470  out_kfree:
471         kfree(kbuf);
472         return error;
473 }
474
475 int
476 xfs_attrmulti_attr_set(
477         struct inode            *inode,
478         char                    *name,
479         const char              __user *ubuf,
480         __uint32_t              len,
481         __uint32_t              flags)
482 {
483         char                    *kbuf;
484         int                     error = EFAULT;
485
486         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
487                 return EPERM;
488         if (len > XATTR_SIZE_MAX)
489                 return EINVAL;
490
491         kbuf = memdup_user(ubuf, len);
492         if (IS_ERR(kbuf))
493                 return PTR_ERR(kbuf);
494
495         error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
496
497         return error;
498 }
499
500 int
501 xfs_attrmulti_attr_remove(
502         struct inode            *inode,
503         char                    *name,
504         __uint32_t              flags)
505 {
506         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
507                 return EPERM;
508         return xfs_attr_remove(XFS_I(inode), name, flags);
509 }
510
511 STATIC int
512 xfs_attrmulti_by_handle(
513         struct file             *parfilp,
514         void                    __user *arg)
515 {
516         int                     error;
517         xfs_attr_multiop_t      *ops;
518         xfs_fsop_attrmulti_handlereq_t am_hreq;
519         struct dentry           *dentry;
520         unsigned int            i, size;
521         char                    *attr_name;
522
523         if (!capable(CAP_SYS_ADMIN))
524                 return -XFS_ERROR(EPERM);
525         if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
526                 return -XFS_ERROR(EFAULT);
527
528         dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
529         if (IS_ERR(dentry))
530                 return PTR_ERR(dentry);
531
532         error = E2BIG;
533         size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
534         if (!size || size > 16 * PAGE_SIZE)
535                 goto out_dput;
536
537         ops = memdup_user(am_hreq.ops, size);
538         if (IS_ERR(ops)) {
539                 error = PTR_ERR(ops);
540                 goto out_dput;
541         }
542
543         attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
544         if (!attr_name)
545                 goto out_kfree_ops;
546
547         error = 0;
548         for (i = 0; i < am_hreq.opcount; i++) {
549                 ops[i].am_error = strncpy_from_user(attr_name,
550                                 ops[i].am_attrname, MAXNAMELEN);
551                 if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
552                         error = -ERANGE;
553                 if (ops[i].am_error < 0)
554                         break;
555
556                 switch (ops[i].am_opcode) {
557                 case ATTR_OP_GET:
558                         ops[i].am_error = xfs_attrmulti_attr_get(
559                                         dentry->d_inode, attr_name,
560                                         ops[i].am_attrvalue, &ops[i].am_length,
561                                         ops[i].am_flags);
562                         break;
563                 case ATTR_OP_SET:
564                         ops[i].am_error = mnt_want_write(parfilp->f_path.mnt);
565                         if (ops[i].am_error)
566                                 break;
567                         ops[i].am_error = xfs_attrmulti_attr_set(
568                                         dentry->d_inode, attr_name,
569                                         ops[i].am_attrvalue, ops[i].am_length,
570                                         ops[i].am_flags);
571                         mnt_drop_write(parfilp->f_path.mnt);
572                         break;
573                 case ATTR_OP_REMOVE:
574                         ops[i].am_error = mnt_want_write(parfilp->f_path.mnt);
575                         if (ops[i].am_error)
576                                 break;
577                         ops[i].am_error = xfs_attrmulti_attr_remove(
578                                         dentry->d_inode, attr_name,
579                                         ops[i].am_flags);
580                         mnt_drop_write(parfilp->f_path.mnt);
581                         break;
582                 default:
583                         ops[i].am_error = EINVAL;
584                 }
585         }
586
587         if (copy_to_user(am_hreq.ops, ops, size))
588                 error = XFS_ERROR(EFAULT);
589
590         kfree(attr_name);
591  out_kfree_ops:
592         kfree(ops);
593  out_dput:
594         dput(dentry);
595         return -error;
596 }
597
598 int
599 xfs_ioc_space(
600         struct xfs_inode        *ip,
601         struct inode            *inode,
602         struct file             *filp,
603         int                     ioflags,
604         unsigned int            cmd,
605         xfs_flock64_t           *bf)
606 {
607         int                     attr_flags = 0;
608         int                     error;
609
610         /*
611          * Only allow the sys admin to reserve space unless
612          * unwritten extents are enabled.
613          */
614         if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) &&
615             !capable(CAP_SYS_ADMIN))
616                 return -XFS_ERROR(EPERM);
617
618         if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
619                 return -XFS_ERROR(EPERM);
620
621         if (!(filp->f_mode & FMODE_WRITE))
622                 return -XFS_ERROR(EBADF);
623
624         if (!S_ISREG(inode->i_mode))
625                 return -XFS_ERROR(EINVAL);
626
627         if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
628                 attr_flags |= XFS_ATTR_NONBLOCK;
629         if (ioflags & IO_INVIS)
630                 attr_flags |= XFS_ATTR_DMI;
631
632         error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags);
633         return -error;
634 }
635
636 STATIC int
637 xfs_ioc_bulkstat(
638         xfs_mount_t             *mp,
639         unsigned int            cmd,
640         void                    __user *arg)
641 {
642         xfs_fsop_bulkreq_t      bulkreq;
643         int                     count;  /* # of records returned */
644         xfs_ino_t               inlast; /* last inode number */
645         int                     done;
646         int                     error;
647
648         /* done = 1 if there are more stats to get and if bulkstat */
649         /* should be called again (unused here, but used in dmapi) */
650
651         if (!capable(CAP_SYS_ADMIN))
652                 return -EPERM;
653
654         if (XFS_FORCED_SHUTDOWN(mp))
655                 return -XFS_ERROR(EIO);
656
657         if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t)))
658                 return -XFS_ERROR(EFAULT);
659
660         if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64)))
661                 return -XFS_ERROR(EFAULT);
662
663         if ((count = bulkreq.icount) <= 0)
664                 return -XFS_ERROR(EINVAL);
665
666         if (bulkreq.ubuffer == NULL)
667                 return -XFS_ERROR(EINVAL);
668
669         if (cmd == XFS_IOC_FSINUMBERS)
670                 error = xfs_inumbers(mp, &inlast, &count,
671                                         bulkreq.ubuffer, xfs_inumbers_fmt);
672         else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE)
673                 error = xfs_bulkstat_single(mp, &inlast,
674                                                 bulkreq.ubuffer, &done);
675         else    /* XFS_IOC_FSBULKSTAT */
676                 error = xfs_bulkstat(mp, &inlast, &count,
677                         (bulkstat_one_pf)xfs_bulkstat_one, NULL,
678                         sizeof(xfs_bstat_t), bulkreq.ubuffer,
679                         BULKSTAT_FG_QUICK, &done);
680
681         if (error)
682                 return -error;
683
684         if (bulkreq.ocount != NULL) {
685                 if (copy_to_user(bulkreq.lastip, &inlast,
686                                                 sizeof(xfs_ino_t)))
687                         return -XFS_ERROR(EFAULT);
688
689                 if (copy_to_user(bulkreq.ocount, &count, sizeof(count)))
690                         return -XFS_ERROR(EFAULT);
691         }
692
693         return 0;
694 }
695
696 STATIC int
697 xfs_ioc_fsgeometry_v1(
698         xfs_mount_t             *mp,
699         void                    __user *arg)
700 {
701         xfs_fsop_geom_v1_t      fsgeo;
702         int                     error;
703
704         error = xfs_fs_geometry(mp, (xfs_fsop_geom_t *)&fsgeo, 3);
705         if (error)
706                 return -error;
707
708         if (copy_to_user(arg, &fsgeo, sizeof(fsgeo)))
709                 return -XFS_ERROR(EFAULT);
710         return 0;
711 }
712
713 STATIC int
714 xfs_ioc_fsgeometry(
715         xfs_mount_t             *mp,
716         void                    __user *arg)
717 {
718         xfs_fsop_geom_t         fsgeo;
719         int                     error;
720
721         error = xfs_fs_geometry(mp, &fsgeo, 4);
722         if (error)
723                 return -error;
724
725         if (copy_to_user(arg, &fsgeo, sizeof(fsgeo)))
726                 return -XFS_ERROR(EFAULT);
727         return 0;
728 }
729
730 /*
731  * Linux extended inode flags interface.
732  */
733
734 STATIC unsigned int
735 xfs_merge_ioc_xflags(
736         unsigned int    flags,
737         unsigned int    start)
738 {
739         unsigned int    xflags = start;
740
741         if (flags & FS_IMMUTABLE_FL)
742                 xflags |= XFS_XFLAG_IMMUTABLE;
743         else
744                 xflags &= ~XFS_XFLAG_IMMUTABLE;
745         if (flags & FS_APPEND_FL)
746                 xflags |= XFS_XFLAG_APPEND;
747         else
748                 xflags &= ~XFS_XFLAG_APPEND;
749         if (flags & FS_SYNC_FL)
750                 xflags |= XFS_XFLAG_SYNC;
751         else
752                 xflags &= ~XFS_XFLAG_SYNC;
753         if (flags & FS_NOATIME_FL)
754                 xflags |= XFS_XFLAG_NOATIME;
755         else
756                 xflags &= ~XFS_XFLAG_NOATIME;
757         if (flags & FS_NODUMP_FL)
758                 xflags |= XFS_XFLAG_NODUMP;
759         else
760                 xflags &= ~XFS_XFLAG_NODUMP;
761
762         return xflags;
763 }
764
765 STATIC unsigned int
766 xfs_di2lxflags(
767         __uint16_t      di_flags)
768 {
769         unsigned int    flags = 0;
770
771         if (di_flags & XFS_DIFLAG_IMMUTABLE)
772                 flags |= FS_IMMUTABLE_FL;
773         if (di_flags & XFS_DIFLAG_APPEND)
774                 flags |= FS_APPEND_FL;
775         if (di_flags & XFS_DIFLAG_SYNC)
776                 flags |= FS_SYNC_FL;
777         if (di_flags & XFS_DIFLAG_NOATIME)
778                 flags |= FS_NOATIME_FL;
779         if (di_flags & XFS_DIFLAG_NODUMP)
780                 flags |= FS_NODUMP_FL;
781         return flags;
782 }
783
784 STATIC int
785 xfs_ioc_fsgetxattr(
786         xfs_inode_t             *ip,
787         int                     attr,
788         void                    __user *arg)
789 {
790         struct fsxattr          fa;
791
792         memset(&fa, 0, sizeof(struct fsxattr));
793
794         xfs_ilock(ip, XFS_ILOCK_SHARED);
795         fa.fsx_xflags = xfs_ip2xflags(ip);
796         fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
797         fa.fsx_projid = ip->i_d.di_projid;
798
799         if (attr) {
800                 if (ip->i_afp) {
801                         if (ip->i_afp->if_flags & XFS_IFEXTENTS)
802                                 fa.fsx_nextents = ip->i_afp->if_bytes /
803                                                         sizeof(xfs_bmbt_rec_t);
804                         else
805                                 fa.fsx_nextents = ip->i_d.di_anextents;
806                 } else
807                         fa.fsx_nextents = 0;
808         } else {
809                 if (ip->i_df.if_flags & XFS_IFEXTENTS)
810                         fa.fsx_nextents = ip->i_df.if_bytes /
811                                                 sizeof(xfs_bmbt_rec_t);
812                 else
813                         fa.fsx_nextents = ip->i_d.di_nextents;
814         }
815         xfs_iunlock(ip, XFS_ILOCK_SHARED);
816
817         if (copy_to_user(arg, &fa, sizeof(fa)))
818                 return -EFAULT;
819         return 0;
820 }
821
822 STATIC void
823 xfs_set_diflags(
824         struct xfs_inode        *ip,
825         unsigned int            xflags)
826 {
827         unsigned int            di_flags;
828
829         /* can't set PREALLOC this way, just preserve it */
830         di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
831         if (xflags & XFS_XFLAG_IMMUTABLE)
832                 di_flags |= XFS_DIFLAG_IMMUTABLE;
833         if (xflags & XFS_XFLAG_APPEND)
834                 di_flags |= XFS_DIFLAG_APPEND;
835         if (xflags & XFS_XFLAG_SYNC)
836                 di_flags |= XFS_DIFLAG_SYNC;
837         if (xflags & XFS_XFLAG_NOATIME)
838                 di_flags |= XFS_DIFLAG_NOATIME;
839         if (xflags & XFS_XFLAG_NODUMP)
840                 di_flags |= XFS_DIFLAG_NODUMP;
841         if (xflags & XFS_XFLAG_PROJINHERIT)
842                 di_flags |= XFS_DIFLAG_PROJINHERIT;
843         if (xflags & XFS_XFLAG_NODEFRAG)
844                 di_flags |= XFS_DIFLAG_NODEFRAG;
845         if (xflags & XFS_XFLAG_FILESTREAM)
846                 di_flags |= XFS_DIFLAG_FILESTREAM;
847         if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
848                 if (xflags & XFS_XFLAG_RTINHERIT)
849                         di_flags |= XFS_DIFLAG_RTINHERIT;
850                 if (xflags & XFS_XFLAG_NOSYMLINKS)
851                         di_flags |= XFS_DIFLAG_NOSYMLINKS;
852                 if (xflags & XFS_XFLAG_EXTSZINHERIT)
853                         di_flags |= XFS_DIFLAG_EXTSZINHERIT;
854         } else if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) {
855                 if (xflags & XFS_XFLAG_REALTIME)
856                         di_flags |= XFS_DIFLAG_REALTIME;
857                 if (xflags & XFS_XFLAG_EXTSIZE)
858                         di_flags |= XFS_DIFLAG_EXTSIZE;
859         }
860
861         ip->i_d.di_flags = di_flags;
862 }
863
864 STATIC void
865 xfs_diflags_to_linux(
866         struct xfs_inode        *ip)
867 {
868         struct inode            *inode = VFS_I(ip);
869         unsigned int            xflags = xfs_ip2xflags(ip);
870
871         if (xflags & XFS_XFLAG_IMMUTABLE)
872                 inode->i_flags |= S_IMMUTABLE;
873         else
874                 inode->i_flags &= ~S_IMMUTABLE;
875         if (xflags & XFS_XFLAG_APPEND)
876                 inode->i_flags |= S_APPEND;
877         else
878                 inode->i_flags &= ~S_APPEND;
879         if (xflags & XFS_XFLAG_SYNC)
880                 inode->i_flags |= S_SYNC;
881         else
882                 inode->i_flags &= ~S_SYNC;
883         if (xflags & XFS_XFLAG_NOATIME)
884                 inode->i_flags |= S_NOATIME;
885         else
886                 inode->i_flags &= ~S_NOATIME;
887 }
888
889 #define FSX_PROJID      1
890 #define FSX_EXTSIZE     2
891 #define FSX_XFLAGS      4
892 #define FSX_NONBLOCK    8
893
894 STATIC int
895 xfs_ioctl_setattr(
896         xfs_inode_t             *ip,
897         struct fsxattr          *fa,
898         int                     mask)
899 {
900         struct xfs_mount        *mp = ip->i_mount;
901         struct xfs_trans        *tp;
902         unsigned int            lock_flags = 0;
903         struct xfs_dquot        *udqp = NULL;
904         struct xfs_dquot        *gdqp = NULL;
905         struct xfs_dquot        *olddquot = NULL;
906         int                     code;
907
908         xfs_itrace_entry(ip);
909
910         if (mp->m_flags & XFS_MOUNT_RDONLY)
911                 return XFS_ERROR(EROFS);
912         if (XFS_FORCED_SHUTDOWN(mp))
913                 return XFS_ERROR(EIO);
914
915         /*
916          * If disk quotas is on, we make sure that the dquots do exist on disk,
917          * before we start any other transactions. Trying to do this later
918          * is messy. We don't care to take a readlock to look at the ids
919          * in inode here, because we can't hold it across the trans_reserve.
920          * If the IDs do change before we take the ilock, we're covered
921          * because the i_*dquot fields will get updated anyway.
922          */
923         if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) {
924                 code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
925                                          ip->i_d.di_gid, fa->fsx_projid,
926                                          XFS_QMOPT_PQUOTA, &udqp, &gdqp);
927                 if (code)
928                         return code;
929         }
930
931         /*
932          * For the other attributes, we acquire the inode lock and
933          * first do an error checking pass.
934          */
935         tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
936         code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0);
937         if (code)
938                 goto error_return;
939
940         lock_flags = XFS_ILOCK_EXCL;
941         xfs_ilock(ip, lock_flags);
942
943         /*
944          * CAP_FOWNER overrides the following restrictions:
945          *
946          * The user ID of the calling process must be equal
947          * to the file owner ID, except in cases where the
948          * CAP_FSETID capability is applicable.
949          */
950         if (current_fsuid() != ip->i_d.di_uid && !capable(CAP_FOWNER)) {
951                 code = XFS_ERROR(EPERM);
952                 goto error_return;
953         }
954
955         /*
956          * Do a quota reservation only if projid is actually going to change.
957          */
958         if (mask & FSX_PROJID) {
959                 if (XFS_IS_QUOTA_RUNNING(mp) &&
960                     XFS_IS_PQUOTA_ON(mp) &&
961                     ip->i_d.di_projid != fa->fsx_projid) {
962                         ASSERT(tp);
963                         code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
964                                                 capable(CAP_FOWNER) ?
965                                                 XFS_QMOPT_FORCE_RES : 0);
966                         if (code)       /* out of quota */
967                                 goto error_return;
968                 }
969         }
970
971         if (mask & FSX_EXTSIZE) {
972                 /*
973                  * Can't change extent size if any extents are allocated.
974                  */
975                 if (ip->i_d.di_nextents &&
976                     ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
977                      fa->fsx_extsize)) {
978                         code = XFS_ERROR(EINVAL);       /* EFBIG? */
979                         goto error_return;
980                 }
981
982                 /*
983                  * Extent size must be a multiple of the appropriate block
984                  * size, if set at all.
985                  */
986                 if (fa->fsx_extsize != 0) {
987                         xfs_extlen_t    size;
988
989                         if (XFS_IS_REALTIME_INODE(ip) ||
990                             ((mask & FSX_XFLAGS) &&
991                             (fa->fsx_xflags & XFS_XFLAG_REALTIME))) {
992                                 size = mp->m_sb.sb_rextsize <<
993                                        mp->m_sb.sb_blocklog;
994                         } else {
995                                 size = mp->m_sb.sb_blocksize;
996                         }
997
998                         if (fa->fsx_extsize % size) {
999                                 code = XFS_ERROR(EINVAL);
1000                                 goto error_return;
1001                         }
1002                 }
1003         }
1004
1005
1006         if (mask & FSX_XFLAGS) {
1007                 /*
1008                  * Can't change realtime flag if any extents are allocated.
1009                  */
1010                 if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
1011                     (XFS_IS_REALTIME_INODE(ip)) !=
1012                     (fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
1013                         code = XFS_ERROR(EINVAL);       /* EFBIG? */
1014                         goto error_return;
1015                 }
1016
1017                 /*
1018                  * If realtime flag is set then must have realtime data.
1019                  */
1020                 if ((fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
1021                         if ((mp->m_sb.sb_rblocks == 0) ||
1022                             (mp->m_sb.sb_rextsize == 0) ||
1023                             (ip->i_d.di_extsize % mp->m_sb.sb_rextsize)) {
1024                                 code = XFS_ERROR(EINVAL);
1025                                 goto error_return;
1026                         }
1027                 }
1028
1029                 /*
1030                  * Can't modify an immutable/append-only file unless
1031                  * we have appropriate permission.
1032                  */
1033                 if ((ip->i_d.di_flags &
1034                                 (XFS_DIFLAG_IMMUTABLE|XFS_DIFLAG_APPEND) ||
1035                      (fa->fsx_xflags &
1036                                 (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
1037                     !capable(CAP_LINUX_IMMUTABLE)) {
1038                         code = XFS_ERROR(EPERM);
1039                         goto error_return;
1040                 }
1041         }
1042
1043         xfs_trans_ijoin(tp, ip, lock_flags);
1044         xfs_trans_ihold(tp, ip);
1045
1046         /*
1047          * Change file ownership.  Must be the owner or privileged.
1048          */
1049         if (mask & FSX_PROJID) {
1050                 /*
1051                  * CAP_FSETID overrides the following restrictions:
1052                  *
1053                  * The set-user-ID and set-group-ID bits of a file will be
1054                  * cleared upon successful return from chown()
1055                  */
1056                 if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
1057                     !capable(CAP_FSETID))
1058                         ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
1059
1060                 /*
1061                  * Change the ownerships and register quota modifications
1062                  * in the transaction.
1063                  */
1064                 if (ip->i_d.di_projid != fa->fsx_projid) {
1065                         if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
1066                                 olddquot = xfs_qm_vop_chown(tp, ip,
1067                                                         &ip->i_gdquot, gdqp);
1068                         }
1069                         ip->i_d.di_projid = fa->fsx_projid;
1070
1071                         /*
1072                          * We may have to rev the inode as well as
1073                          * the superblock version number since projids didn't
1074                          * exist before DINODE_VERSION_2 and SB_VERSION_NLINK.
1075                          */
1076                         if (ip->i_d.di_version == 1)
1077                                 xfs_bump_ino_vers2(tp, ip);
1078                 }
1079
1080         }
1081
1082         if (mask & FSX_EXTSIZE)
1083                 ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog;
1084         if (mask & FSX_XFLAGS) {
1085                 xfs_set_diflags(ip, fa->fsx_xflags);
1086                 xfs_diflags_to_linux(ip);
1087         }
1088
1089         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1090         xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
1091
1092         XFS_STATS_INC(xs_ig_attrchg);
1093
1094         /*
1095          * If this is a synchronous mount, make sure that the
1096          * transaction goes to disk before returning to the user.
1097          * This is slightly sub-optimal in that truncates require
1098          * two sync transactions instead of one for wsync filesystems.
1099          * One for the truncate and one for the timestamps since we
1100          * don't want to change the timestamps unless we're sure the
1101          * truncate worked.  Truncates are less than 1% of the laddis
1102          * mix so this probably isn't worth the trouble to optimize.
1103          */
1104         if (mp->m_flags & XFS_MOUNT_WSYNC)
1105                 xfs_trans_set_sync(tp);
1106         code = xfs_trans_commit(tp, 0);
1107         xfs_iunlock(ip, lock_flags);
1108
1109         /*
1110          * Release any dquot(s) the inode had kept before chown.
1111          */
1112         xfs_qm_dqrele(olddquot);
1113         xfs_qm_dqrele(udqp);
1114         xfs_qm_dqrele(gdqp);
1115
1116         if (code)
1117                 return code;
1118
1119         if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE)) {
1120                 XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, ip, DM_RIGHT_NULL,
1121                                 NULL, DM_RIGHT_NULL, NULL, NULL, 0, 0,
1122                                 (mask & FSX_NONBLOCK) ? DM_FLAGS_NDELAY : 0);
1123         }
1124
1125         return 0;
1126
1127  error_return:
1128         xfs_qm_dqrele(udqp);
1129         xfs_qm_dqrele(gdqp);
1130         xfs_trans_cancel(tp, 0);
1131         if (lock_flags)
1132                 xfs_iunlock(ip, lock_flags);
1133         return code;
1134 }
1135
1136 STATIC int
1137 xfs_ioc_fssetxattr(
1138         xfs_inode_t             *ip,
1139         struct file             *filp,
1140         void                    __user *arg)
1141 {
1142         struct fsxattr          fa;
1143         unsigned int            mask;
1144
1145         if (copy_from_user(&fa, arg, sizeof(fa)))
1146                 return -EFAULT;
1147
1148         mask = FSX_XFLAGS | FSX_EXTSIZE | FSX_PROJID;
1149         if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1150                 mask |= FSX_NONBLOCK;
1151
1152         return -xfs_ioctl_setattr(ip, &fa, mask);
1153 }
1154
1155 STATIC int
1156 xfs_ioc_getxflags(
1157         xfs_inode_t             *ip,
1158         void                    __user *arg)
1159 {
1160         unsigned int            flags;
1161
1162         flags = xfs_di2lxflags(ip->i_d.di_flags);
1163         if (copy_to_user(arg, &flags, sizeof(flags)))
1164                 return -EFAULT;
1165         return 0;
1166 }
1167
1168 STATIC int
1169 xfs_ioc_setxflags(
1170         xfs_inode_t             *ip,
1171         struct file             *filp,
1172         void                    __user *arg)
1173 {
1174         struct fsxattr          fa;
1175         unsigned int            flags;
1176         unsigned int            mask;
1177
1178         if (copy_from_user(&flags, arg, sizeof(flags)))
1179                 return -EFAULT;
1180
1181         if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
1182                       FS_NOATIME_FL | FS_NODUMP_FL | \
1183                       FS_SYNC_FL))
1184                 return -EOPNOTSUPP;
1185
1186         mask = FSX_XFLAGS;
1187         if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1188                 mask |= FSX_NONBLOCK;
1189         fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip));
1190
1191         return -xfs_ioctl_setattr(ip, &fa, mask);
1192 }
1193
1194 STATIC int
1195 xfs_getbmap_format(void **ap, struct getbmapx *bmv, int *full)
1196 {
1197         struct getbmap __user   *base = *ap;
1198
1199         /* copy only getbmap portion (not getbmapx) */
1200         if (copy_to_user(base, bmv, sizeof(struct getbmap)))
1201                 return XFS_ERROR(EFAULT);
1202
1203         *ap += sizeof(struct getbmap);
1204         return 0;
1205 }
1206
1207 STATIC int
1208 xfs_ioc_getbmap(
1209         struct xfs_inode        *ip,
1210         int                     ioflags,
1211         unsigned int            cmd,
1212         void                    __user *arg)
1213 {
1214         struct getbmapx         bmx;
1215         int                     error;
1216
1217         if (copy_from_user(&bmx, arg, sizeof(struct getbmapx)))
1218                 return -XFS_ERROR(EFAULT);
1219
1220         if (bmx.bmv_count < 2)
1221                 return -XFS_ERROR(EINVAL);
1222
1223         bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0);
1224         if (ioflags & IO_INVIS)
1225                 bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ;
1226
1227         error = xfs_getbmap(ip, &bmx, xfs_getbmap_format,
1228                             (struct getbmap *)arg+1);
1229         if (error)
1230                 return -error;
1231
1232         /* copy back header - only size of getbmap */
1233         if (copy_to_user(arg, &bmx, sizeof(struct getbmap)))
1234                 return -XFS_ERROR(EFAULT);
1235         return 0;
1236 }
1237
1238 STATIC int
1239 xfs_getbmapx_format(void **ap, struct getbmapx *bmv, int *full)
1240 {
1241         struct getbmapx __user  *base = *ap;
1242
1243         if (copy_to_user(base, bmv, sizeof(struct getbmapx)))
1244                 return XFS_ERROR(EFAULT);
1245
1246         *ap += sizeof(struct getbmapx);
1247         return 0;
1248 }
1249
1250 STATIC int
1251 xfs_ioc_getbmapx(
1252         struct xfs_inode        *ip,
1253         void                    __user *arg)
1254 {
1255         struct getbmapx         bmx;
1256         int                     error;
1257
1258         if (copy_from_user(&bmx, arg, sizeof(bmx)))
1259                 return -XFS_ERROR(EFAULT);
1260
1261         if (bmx.bmv_count < 2)
1262                 return -XFS_ERROR(EINVAL);
1263
1264         if (bmx.bmv_iflags & (~BMV_IF_VALID))
1265                 return -XFS_ERROR(EINVAL);
1266
1267         error = xfs_getbmap(ip, &bmx, xfs_getbmapx_format,
1268                             (struct getbmapx *)arg+1);
1269         if (error)
1270                 return -error;
1271
1272         /* copy back header */
1273         if (copy_to_user(arg, &bmx, sizeof(struct getbmapx)))
1274                 return -XFS_ERROR(EFAULT);
1275
1276         return 0;
1277 }
1278
1279 /*
1280  * Note: some of the ioctl's return positive numbers as a
1281  * byte count indicating success, such as readlink_by_handle.
1282  * So we don't "sign flip" like most other routines.  This means
1283  * true errors need to be returned as a negative value.
1284  */
1285 long
1286 xfs_file_ioctl(
1287         struct file             *filp,
1288         unsigned int            cmd,
1289         unsigned long           p)
1290 {
1291         struct inode            *inode = filp->f_path.dentry->d_inode;
1292         struct xfs_inode        *ip = XFS_I(inode);
1293         struct xfs_mount        *mp = ip->i_mount;
1294         void                    __user *arg = (void __user *)p;
1295         int                     ioflags = 0;
1296         int                     error;
1297
1298         if (filp->f_mode & FMODE_NOCMTIME)
1299                 ioflags |= IO_INVIS;
1300
1301         xfs_itrace_entry(ip);
1302
1303         switch (cmd) {
1304         case XFS_IOC_ALLOCSP:
1305         case XFS_IOC_FREESP:
1306         case XFS_IOC_RESVSP:
1307         case XFS_IOC_UNRESVSP:
1308         case XFS_IOC_ALLOCSP64:
1309         case XFS_IOC_FREESP64:
1310         case XFS_IOC_RESVSP64:
1311         case XFS_IOC_UNRESVSP64: {
1312                 xfs_flock64_t           bf;
1313
1314                 if (copy_from_user(&bf, arg, sizeof(bf)))
1315                         return -XFS_ERROR(EFAULT);
1316                 return xfs_ioc_space(ip, inode, filp, ioflags, cmd, &bf);
1317         }
1318         case XFS_IOC_DIOINFO: {
1319                 struct dioattr  da;
1320                 xfs_buftarg_t   *target =
1321                         XFS_IS_REALTIME_INODE(ip) ?
1322                         mp->m_rtdev_targp : mp->m_ddev_targp;
1323
1324                 da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
1325                 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
1326
1327                 if (copy_to_user(arg, &da, sizeof(da)))
1328                         return -XFS_ERROR(EFAULT);
1329                 return 0;
1330         }
1331
1332         case XFS_IOC_FSBULKSTAT_SINGLE:
1333         case XFS_IOC_FSBULKSTAT:
1334         case XFS_IOC_FSINUMBERS:
1335                 return xfs_ioc_bulkstat(mp, cmd, arg);
1336
1337         case XFS_IOC_FSGEOMETRY_V1:
1338                 return xfs_ioc_fsgeometry_v1(mp, arg);
1339
1340         case XFS_IOC_FSGEOMETRY:
1341                 return xfs_ioc_fsgeometry(mp, arg);
1342
1343         case XFS_IOC_GETVERSION:
1344                 return put_user(inode->i_generation, (int __user *)arg);
1345
1346         case XFS_IOC_FSGETXATTR:
1347                 return xfs_ioc_fsgetxattr(ip, 0, arg);
1348         case XFS_IOC_FSGETXATTRA:
1349                 return xfs_ioc_fsgetxattr(ip, 1, arg);
1350         case XFS_IOC_FSSETXATTR:
1351                 return xfs_ioc_fssetxattr(ip, filp, arg);
1352         case XFS_IOC_GETXFLAGS:
1353                 return xfs_ioc_getxflags(ip, arg);
1354         case XFS_IOC_SETXFLAGS:
1355                 return xfs_ioc_setxflags(ip, filp, arg);
1356
1357         case XFS_IOC_FSSETDM: {
1358                 struct fsdmidata        dmi;
1359
1360                 if (copy_from_user(&dmi, arg, sizeof(dmi)))
1361                         return -XFS_ERROR(EFAULT);
1362
1363                 error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
1364                                 dmi.fsd_dmstate);
1365                 return -error;
1366         }
1367
1368         case XFS_IOC_GETBMAP:
1369         case XFS_IOC_GETBMAPA:
1370                 return xfs_ioc_getbmap(ip, ioflags, cmd, arg);
1371
1372         case XFS_IOC_GETBMAPX:
1373                 return xfs_ioc_getbmapx(ip, arg);
1374
1375         case XFS_IOC_FD_TO_HANDLE:
1376         case XFS_IOC_PATH_TO_HANDLE:
1377         case XFS_IOC_PATH_TO_FSHANDLE: {
1378                 xfs_fsop_handlereq_t    hreq;
1379
1380                 if (copy_from_user(&hreq, arg, sizeof(hreq)))
1381                         return -XFS_ERROR(EFAULT);
1382                 return xfs_find_handle(cmd, &hreq);
1383         }
1384         case XFS_IOC_OPEN_BY_HANDLE: {
1385                 xfs_fsop_handlereq_t    hreq;
1386
1387                 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
1388                         return -XFS_ERROR(EFAULT);
1389                 return xfs_open_by_handle(filp, &hreq);
1390         }
1391         case XFS_IOC_FSSETDM_BY_HANDLE:
1392                 return xfs_fssetdm_by_handle(filp, arg);
1393
1394         case XFS_IOC_READLINK_BY_HANDLE: {
1395                 xfs_fsop_handlereq_t    hreq;
1396
1397                 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
1398                         return -XFS_ERROR(EFAULT);
1399                 return xfs_readlink_by_handle(filp, &hreq);
1400         }
1401         case XFS_IOC_ATTRLIST_BY_HANDLE:
1402                 return xfs_attrlist_by_handle(filp, arg);
1403
1404         case XFS_IOC_ATTRMULTI_BY_HANDLE:
1405                 return xfs_attrmulti_by_handle(filp, arg);
1406
1407         case XFS_IOC_SWAPEXT: {
1408                 struct xfs_swapext      sxp;
1409
1410                 if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t)))
1411                         return -XFS_ERROR(EFAULT);
1412                 error = xfs_swapext(&sxp);
1413                 return -error;
1414         }
1415
1416         case XFS_IOC_FSCOUNTS: {
1417                 xfs_fsop_counts_t out;
1418
1419                 error = xfs_fs_counts(mp, &out);
1420                 if (error)
1421                         return -error;
1422
1423                 if (copy_to_user(arg, &out, sizeof(out)))
1424                         return -XFS_ERROR(EFAULT);
1425                 return 0;
1426         }
1427
1428         case XFS_IOC_SET_RESBLKS: {
1429                 xfs_fsop_resblks_t inout;
1430                 __uint64_t         in;
1431
1432                 if (!capable(CAP_SYS_ADMIN))
1433                         return -EPERM;
1434
1435                 if (copy_from_user(&inout, arg, sizeof(inout)))
1436                         return -XFS_ERROR(EFAULT);
1437
1438                 /* input parameter is passed in resblks field of structure */
1439                 in = inout.resblks;
1440                 error = xfs_reserve_blocks(mp, &in, &inout);
1441                 if (error)
1442                         return -error;
1443
1444                 if (copy_to_user(arg, &inout, sizeof(inout)))
1445                         return -XFS_ERROR(EFAULT);
1446                 return 0;
1447         }
1448
1449         case XFS_IOC_GET_RESBLKS: {
1450                 xfs_fsop_resblks_t out;
1451
1452                 if (!capable(CAP_SYS_ADMIN))
1453                         return -EPERM;
1454
1455                 error = xfs_reserve_blocks(mp, NULL, &out);
1456                 if (error)
1457                         return -error;
1458
1459                 if (copy_to_user(arg, &out, sizeof(out)))
1460                         return -XFS_ERROR(EFAULT);
1461
1462                 return 0;
1463         }
1464
1465         case XFS_IOC_FSGROWFSDATA: {
1466                 xfs_growfs_data_t in;
1467
1468                 if (copy_from_user(&in, arg, sizeof(in)))
1469                         return -XFS_ERROR(EFAULT);
1470
1471                 error = xfs_growfs_data(mp, &in);
1472                 return -error;
1473         }
1474
1475         case XFS_IOC_FSGROWFSLOG: {
1476                 xfs_growfs_log_t in;
1477
1478                 if (copy_from_user(&in, arg, sizeof(in)))
1479                         return -XFS_ERROR(EFAULT);
1480
1481                 error = xfs_growfs_log(mp, &in);
1482                 return -error;
1483         }
1484
1485         case XFS_IOC_FSGROWFSRT: {
1486                 xfs_growfs_rt_t in;
1487
1488                 if (copy_from_user(&in, arg, sizeof(in)))
1489                         return -XFS_ERROR(EFAULT);
1490
1491                 error = xfs_growfs_rt(mp, &in);
1492                 return -error;
1493         }
1494
1495         case XFS_IOC_GOINGDOWN: {
1496                 __uint32_t in;
1497
1498                 if (!capable(CAP_SYS_ADMIN))
1499                         return -EPERM;
1500
1501                 if (get_user(in, (__uint32_t __user *)arg))
1502                         return -XFS_ERROR(EFAULT);
1503
1504                 error = xfs_fs_goingdown(mp, in);
1505                 return -error;
1506         }
1507
1508         case XFS_IOC_ERROR_INJECTION: {
1509                 xfs_error_injection_t in;
1510
1511                 if (!capable(CAP_SYS_ADMIN))
1512                         return -EPERM;
1513
1514                 if (copy_from_user(&in, arg, sizeof(in)))
1515                         return -XFS_ERROR(EFAULT);
1516
1517                 error = xfs_errortag_add(in.errtag, mp);
1518                 return -error;
1519         }
1520
1521         case XFS_IOC_ERROR_CLEARALL:
1522                 if (!capable(CAP_SYS_ADMIN))
1523                         return -EPERM;
1524
1525                 error = xfs_errortag_clearall(mp, 1);
1526                 return -error;
1527
1528         default:
1529                 return -ENOTTY;
1530         }
1531 }