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_btree.h" 38#include "xfs_ialloc.h" 39#include "xfs_rtalloc.h" 40#include "xfs_itable.h" 41#include "xfs_error.h" 42#include "xfs_rw.h" 43#include "xfs_acl.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 51#include <linux/capability.h> 52#include <linux/dcache.h> 53#include <linux/mount.h> 54#include <linux/namei.h> 55#include <linux/pagemap.h> 56 57/* 58 * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to 59 * a file or fs handle. 60 * 61 * XFS_IOC_PATH_TO_FSHANDLE 62 * returns fs handle for a mount point or path within that mount point 63 * XFS_IOC_FD_TO_HANDLE 64 * returns full handle for a FD opened in user space 65 * XFS_IOC_PATH_TO_HANDLE 66 * returns full handle for a path 67 */ 68STATIC int 69xfs_find_handle( 70 unsigned int cmd, 71 void __user *arg) 72{ 73 int hsize; 74 xfs_handle_t handle; 75 xfs_fsop_handlereq_t hreq; 76 struct inode *inode; 77 bhv_vnode_t *vp; 78 79 if (copy_from_user(&hreq, arg, sizeof(hreq))) 80 return -XFS_ERROR(EFAULT); 81 82 memset((char *)&handle, 0, sizeof(handle)); 83 84 switch (cmd) { 85 case XFS_IOC_PATH_TO_FSHANDLE: 86 case XFS_IOC_PATH_TO_HANDLE: { 87 struct nameidata nd; 88 int error; 89 90 error = user_path_walk_link((const char __user *)hreq.path, &nd); 91 if (error) 92 return error; 93 94 ASSERT(nd.dentry); 95 ASSERT(nd.dentry->d_inode); 96 inode = igrab(nd.dentry->d_inode); 97 path_release(&nd); 98 break; 99 } 100 101 case XFS_IOC_FD_TO_HANDLE: { 102 struct file *file; 103 104 file = fget(hreq.fd); 105 if (!file) 106 return -EBADF; 107 108 ASSERT(file->f_path.dentry); 109 ASSERT(file->f_path.dentry->d_inode); 110 inode = igrab(file->f_path.dentry->d_inode); 111 fput(file); 112 break; 113 } 114 115 default: 116 ASSERT(0); 117 return -XFS_ERROR(EINVAL); 118 } 119 120 if (inode->i_sb->s_magic != XFS_SB_MAGIC) { 121 /* we're not in XFS anymore, Toto */ 122 iput(inode); 123 return -XFS_ERROR(EINVAL); 124 } 125 126 switch (inode->i_mode & S_IFMT) { 127 case S_IFREG: 128 case S_IFDIR: 129 case S_IFLNK: 130 break; 131 default: 132 iput(inode); 133 return -XFS_ERROR(EBADF); 134 } 135 136 /* we need the vnode */ 137 vp = vn_from_inode(inode); 138 139 /* now we can grab the fsid */ 140 memcpy(&handle.ha_fsid, vp->v_vfsp->vfs_altfsid, sizeof(xfs_fsid_t)); 141 hsize = sizeof(xfs_fsid_t); 142 143 if (cmd != XFS_IOC_PATH_TO_FSHANDLE) { 144 xfs_inode_t *ip; 145 int lock_mode; 146 147 /* need to get access to the xfs_inode to read the generation */ 148 ip = xfs_vtoi(vp); 149 ASSERT(ip); 150 lock_mode = xfs_ilock_map_shared(ip); 151 152 /* fill in fid section of handle from inode */ 153 handle.ha_fid.xfs_fid_len = sizeof(xfs_fid_t) - 154 sizeof(handle.ha_fid.xfs_fid_len); 155 handle.ha_fid.xfs_fid_pad = 0; 156 handle.ha_fid.xfs_fid_gen = ip->i_d.di_gen; 157 handle.ha_fid.xfs_fid_ino = ip->i_ino; 158 159 xfs_iunlock_map_shared(ip, lock_mode); 160 161 hsize = XFS_HSIZE(handle); 162 } 163 164 /* now copy our handle into the user buffer & write out the size */ 165 if (copy_to_user(hreq.ohandle, &handle, hsize) || 166 copy_to_user(hreq.ohandlen, &hsize, sizeof(__s32))) { 167 iput(inode); 168 return -XFS_ERROR(EFAULT); 169 } 170 171 iput(inode); 172 return 0; 173} 174 175 176/* 177 * Convert userspace handle data into vnode (and inode). 178 * We [ab]use the fact that all the fsop_handlereq ioctl calls 179 * have a data structure argument whose first component is always 180 * a xfs_fsop_handlereq_t, so we can cast to and from this type. 181 * This allows us to optimise the copy_from_user calls and gives 182 * a handy, shared routine. 183 * 184 * If no error, caller must always VN_RELE the returned vp. 185 */ 186STATIC int 187xfs_vget_fsop_handlereq( 188 xfs_mount_t *mp, 189 struct inode *parinode, /* parent inode pointer */ 190 xfs_fsop_handlereq_t *hreq, 191 bhv_vnode_t **vp, 192 struct inode **inode) 193{ 194 void __user *hanp; 195 size_t hlen; 196 xfs_fid_t *xfid; 197 xfs_handle_t *handlep; 198 xfs_handle_t handle; 199 xfs_inode_t *ip; 200 struct inode *inodep; 201 bhv_vnode_t *vpp; 202 xfs_ino_t ino; 203 __u32 igen; 204 int error; 205 206 /* 207 * Only allow handle opens under a directory. 208 */ 209 if (!S_ISDIR(parinode->i_mode)) 210 return XFS_ERROR(ENOTDIR); 211 212 hanp = hreq->ihandle; 213 hlen = hreq->ihandlen; 214 handlep = &handle; 215 216 if (hlen < sizeof(handlep->ha_fsid) || hlen > sizeof(*handlep)) 217 return XFS_ERROR(EINVAL); 218 if (copy_from_user(handlep, hanp, hlen)) 219 return XFS_ERROR(EFAULT); 220 if (hlen < sizeof(*handlep)) 221 memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen); 222 if (hlen > sizeof(handlep->ha_fsid)) { 223 if (handlep->ha_fid.xfs_fid_len != 224 (hlen - sizeof(handlep->ha_fsid) 225 - sizeof(handlep->ha_fid.xfs_fid_len)) 226 || handlep->ha_fid.xfs_fid_pad) 227 return XFS_ERROR(EINVAL); 228 } 229 230 /* 231 * Crack the handle, obtain the inode # & generation # 232 */ 233 xfid = (struct xfs_fid *)&handlep->ha_fid; 234 if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) { 235 ino = xfid->xfs_fid_ino; 236 igen = xfid->xfs_fid_gen; 237 } else { 238 return XFS_ERROR(EINVAL); 239 } 240 241 /* 242 * Get the XFS inode, building a vnode to go with it. 243 */ 244 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0); 245 if (error) 246 return error; 247 if (ip == NULL) 248 return XFS_ERROR(EIO); 249 if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) { 250 xfs_iput_new(ip, XFS_ILOCK_SHARED); 251 return XFS_ERROR(ENOENT); 252 } 253 254 vpp = XFS_ITOV(ip); 255 inodep = vn_to_inode(vpp); 256 xfs_iunlock(ip, XFS_ILOCK_SHARED); 257 258 *vp = vpp; 259 *inode = inodep; 260 return 0; 261} 262 263STATIC int 264xfs_open_by_handle( 265 xfs_mount_t *mp, 266 void __user *arg, 267 struct file *parfilp, 268 struct inode *parinode) 269{ 270 int error; 271 int new_fd; 272 int permflag; 273 struct file *filp; 274 struct inode *inode; 275 struct dentry *dentry; 276 bhv_vnode_t *vp; 277 xfs_fsop_handlereq_t hreq; 278 279 if (!capable(CAP_SYS_ADMIN)) 280 return -XFS_ERROR(EPERM); 281 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) 282 return -XFS_ERROR(EFAULT); 283 284 error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode); 285 if (error) 286 return -error; 287 288 /* Restrict xfs_open_by_handle to directories & regular files. */ 289 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) { 290 iput(inode); 291 return -XFS_ERROR(EINVAL); 292 } 293 294#if BITS_PER_LONG != 32 295 hreq.oflags |= O_LARGEFILE; 296#endif 297 /* Put open permission in namei format. */ 298 permflag = hreq.oflags; 299 if ((permflag+1) & O_ACCMODE) 300 permflag++; 301 if (permflag & O_TRUNC) 302 permflag |= 2; 303 304 if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) && 305 (permflag & FMODE_WRITE) && IS_APPEND(inode)) { 306 iput(inode); 307 return -XFS_ERROR(EPERM); 308 } 309 310 if ((permflag & FMODE_WRITE) && IS_IMMUTABLE(inode)) { 311 iput(inode); 312 return -XFS_ERROR(EACCES); 313 } 314 315 /* Can't write directories. */ 316 if ( S_ISDIR(inode->i_mode) && (permflag & FMODE_WRITE)) { 317 iput(inode); 318 return -XFS_ERROR(EISDIR); 319 } 320 321 if ((new_fd = get_unused_fd()) < 0) { 322 iput(inode); 323 return new_fd; 324 } 325 326 dentry = d_alloc_anon(inode); 327 if (dentry == NULL) { 328 iput(inode); 329 put_unused_fd(new_fd); 330 return -XFS_ERROR(ENOMEM); 331 } 332 333 /* Ensure umount returns EBUSY on umounts while this file is open. */ 334 mntget(parfilp->f_path.mnt); 335 336 /* Create file pointer. */ 337 filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags); 338 if (IS_ERR(filp)) { 339 put_unused_fd(new_fd); 340 return -XFS_ERROR(-PTR_ERR(filp)); 341 } 342 if (inode->i_mode & S_IFREG) { 343 /* invisible operation should not change atime */ 344 filp->f_flags |= O_NOATIME; 345 filp->f_op = &xfs_invis_file_operations; 346 } 347 348 fd_install(new_fd, filp); 349 return new_fd; 350} 351 352STATIC int 353xfs_readlink_by_handle( 354 xfs_mount_t *mp, 355 void __user *arg, 356 struct inode *parinode) 357{ 358 int error; 359 struct iovec aiov; 360 struct uio auio; 361 struct inode *inode; 362 xfs_fsop_handlereq_t hreq; 363 bhv_vnode_t *vp; 364 __u32 olen; 365 366 if (!capable(CAP_SYS_ADMIN)) 367 return -XFS_ERROR(EPERM); 368 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) 369 return -XFS_ERROR(EFAULT); 370 371 error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &vp, &inode); 372 if (error) 373 return -error; 374 375 /* Restrict this handle operation to symlinks only. */ 376 if (!S_ISLNK(inode->i_mode)) { 377 VN_RELE(vp); 378 return -XFS_ERROR(EINVAL); 379 } 380 381 if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) { 382 VN_RELE(vp); 383 return -XFS_ERROR(EFAULT); 384 } 385 aiov.iov_len = olen; 386 aiov.iov_base = hreq.ohandle; 387 388 auio.uio_iov = (struct kvec *)&aiov; 389 auio.uio_iovcnt = 1; 390 auio.uio_offset = 0; 391 auio.uio_segflg = UIO_USERSPACE; 392 auio.uio_resid = olen; 393 394 error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL); 395 VN_RELE(vp); 396 if (error) 397 return -error; 398 399 return (olen - auio.uio_resid); 400} 401 402STATIC int 403xfs_fssetdm_by_handle( 404 xfs_mount_t *mp, 405 void __user *arg, 406 struct inode *parinode) 407{ 408 int error; 409 struct fsdmidata fsd; 410 xfs_fsop_setdm_handlereq_t dmhreq; 411 struct inode *inode; 412 bhv_desc_t *bdp; 413 bhv_vnode_t *vp; 414 415 if (!capable(CAP_MKNOD)) 416 return -XFS_ERROR(EPERM); 417 if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t))) 418 return -XFS_ERROR(EFAULT); 419 420 error = xfs_vget_fsop_handlereq(mp, parinode, &dmhreq.hreq, &vp, &inode); 421 if (error) 422 return -error; 423 424 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { 425 VN_RELE(vp); 426 return -XFS_ERROR(EPERM); 427 } 428 429 if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) { 430 VN_RELE(vp); 431 return -XFS_ERROR(EFAULT); 432 } 433 434 bdp = bhv_base_unlocked(VN_BHV_HEAD(vp)); 435 error = xfs_set_dmattrs(bdp, fsd.fsd_dmevmask, fsd.fsd_dmstate, NULL); 436 437 VN_RELE(vp); 438 if (error) 439 return -error; 440 return 0; 441} 442 443STATIC int 444xfs_attrlist_by_handle( 445 xfs_mount_t *mp, 446 void __user *arg, 447 struct inode *parinode) 448{ 449 int error; 450 attrlist_cursor_kern_t *cursor; 451 xfs_fsop_attrlist_handlereq_t al_hreq; 452 struct inode *inode; 453 bhv_vnode_t *vp; 454 char *kbuf; 455 456 if (!capable(CAP_SYS_ADMIN)) 457 return -XFS_ERROR(EPERM); 458 if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t))) 459 return -XFS_ERROR(EFAULT); 460 if (al_hreq.buflen > XATTR_LIST_MAX) 461 return -XFS_ERROR(EINVAL); 462 463 error = xfs_vget_fsop_handlereq(mp, parinode, &al_hreq.hreq, 464 &vp, &inode); 465 if (error) 466 goto out; 467 468 kbuf = kmalloc(al_hreq.buflen, GFP_KERNEL); 469 if (!kbuf) 470 goto out_vn_rele; 471 472 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; 473 error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags, 474 cursor, NULL); 475 if (error) 476 goto out_kfree; 477 478 if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen)) 479 error = -EFAULT; 480 481 out_kfree: 482 kfree(kbuf); 483 out_vn_rele: 484 VN_RELE(vp); 485 out: 486 return -error; 487} 488 489STATIC int 490xfs_attrmulti_attr_get( 491 bhv_vnode_t *vp, 492 char *name, 493 char __user *ubuf, 494 __uint32_t *len, 495 __uint32_t flags) 496{ 497 char *kbuf; 498 int error = EFAULT; 499 500 if (*len > XATTR_SIZE_MAX) 501 return EINVAL; 502 kbuf = kmalloc(*len, GFP_KERNEL); 503 if (!kbuf) 504 return ENOMEM; 505 506 error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL); 507 if (error) 508 goto out_kfree; 509 510 if (copy_to_user(ubuf, kbuf, *len)) 511 error = EFAULT; 512 513 out_kfree: 514 kfree(kbuf); 515 return error; 516} 517 518STATIC int 519xfs_attrmulti_attr_set( 520 bhv_vnode_t *vp, 521 char *name, 522 const char __user *ubuf, 523 __uint32_t len, 524 __uint32_t flags) 525{ 526 char *kbuf; 527 int error = EFAULT; 528 529 if (IS_RDONLY(&vp->v_inode)) 530 return -EROFS; 531 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) 532 return EPERM; 533 if (len > XATTR_SIZE_MAX) 534 return EINVAL; 535 536 kbuf = kmalloc(len, GFP_KERNEL); 537 if (!kbuf) 538 return ENOMEM; 539 540 if (copy_from_user(kbuf, ubuf, len)) 541 goto out_kfree; 542 543 error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL); 544 545 out_kfree: 546 kfree(kbuf); 547 return error; 548} 549 550STATIC int 551xfs_attrmulti_attr_remove( 552 bhv_vnode_t *vp, 553 char *name, 554 __uint32_t flags) 555{ 556 if (IS_RDONLY(&vp->v_inode)) 557 return -EROFS; 558 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) 559 return EPERM; 560 return bhv_vop_attr_remove(vp, name, flags, NULL); 561} 562 563STATIC int 564xfs_attrmulti_by_handle( 565 xfs_mount_t *mp, 566 void __user *arg, 567 struct inode *parinode) 568{ 569 int error; 570 xfs_attr_multiop_t *ops; 571 xfs_fsop_attrmulti_handlereq_t am_hreq; 572 struct inode *inode; 573 bhv_vnode_t *vp; 574 unsigned int i, size; 575 char *attr_name; 576 577 if (!capable(CAP_SYS_ADMIN)) 578 return -XFS_ERROR(EPERM); 579 if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t))) 580 return -XFS_ERROR(EFAULT); 581 582 error = xfs_vget_fsop_handlereq(mp, parinode, &am_hreq.hreq, &vp, &inode); 583 if (error) 584 goto out; 585 586 error = E2BIG; 587 size = am_hreq.opcount * sizeof(attr_multiop_t); 588 if (!size || size > 16 * PAGE_SIZE) 589 goto out_vn_rele; 590 591 error = ENOMEM; 592 ops = kmalloc(size, GFP_KERNEL); 593 if (!ops) 594 goto out_vn_rele; 595 596 error = EFAULT; 597 if (copy_from_user(ops, am_hreq.ops, size)) 598 goto out_kfree_ops; 599 600 attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); 601 if (!attr_name) 602 goto out_kfree_ops; 603 604 605 error = 0; 606 for (i = 0; i < am_hreq.opcount; i++) { 607 ops[i].am_error = strncpy_from_user(attr_name, 608 ops[i].am_attrname, MAXNAMELEN); 609 if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) 610 error = -ERANGE; 611 if (ops[i].am_error < 0) 612 break; 613 614 switch (ops[i].am_opcode) { 615 case ATTR_OP_GET: 616 ops[i].am_error = xfs_attrmulti_attr_get(vp, 617 attr_name, ops[i].am_attrvalue, 618 &ops[i].am_length, ops[i].am_flags); 619 break; 620 case ATTR_OP_SET: 621 ops[i].am_error = xfs_attrmulti_attr_set(vp, 622 attr_name, ops[i].am_attrvalue, 623 ops[i].am_length, ops[i].am_flags); 624 break; 625 case ATTR_OP_REMOVE: 626 ops[i].am_error = xfs_attrmulti_attr_remove(vp, 627 attr_name, ops[i].am_flags); 628 break; 629 default: 630 ops[i].am_error = EINVAL; 631 } 632 } 633 634 if (copy_to_user(am_hreq.ops, ops, size)) 635 error = XFS_ERROR(EFAULT); 636 637 kfree(attr_name); 638 out_kfree_ops: 639 kfree(ops); 640 out_vn_rele: 641 VN_RELE(vp); 642 out: 643 return -error; 644} 645 646/* prototypes for a few of the stack-hungry cases that have 647 * their own functions. Functions are defined after their use 648 * so gcc doesn't get fancy and inline them with -03 */ 649 650STATIC int 651xfs_ioc_space( 652 bhv_desc_t *bdp, 653 struct inode *inode, 654 struct file *filp, 655 int flags, 656 unsigned int cmd, 657 void __user *arg); 658 659STATIC int 660xfs_ioc_bulkstat( 661 xfs_mount_t *mp, 662 unsigned int cmd, 663 void __user *arg); 664 665STATIC int 666xfs_ioc_fsgeometry_v1( 667 xfs_mount_t *mp, 668 void __user *arg); 669 670STATIC int 671xfs_ioc_fsgeometry( 672 xfs_mount_t *mp, 673 void __user *arg); 674 675STATIC int 676xfs_ioc_xattr( 677 bhv_vnode_t *vp, 678 xfs_inode_t *ip, 679 struct file *filp, 680 unsigned int cmd, 681 void __user *arg); 682 683STATIC int 684xfs_ioc_getbmap( 685 bhv_desc_t *bdp, 686 int flags, 687 unsigned int cmd, 688 void __user *arg); 689 690STATIC int 691xfs_ioc_getbmapx( 692 bhv_desc_t *bdp, 693 void __user *arg); 694 695int 696xfs_ioctl( 697 bhv_desc_t *bdp, 698 struct inode *inode, 699 struct file *filp, 700 int ioflags, 701 unsigned int cmd, 702 void __user *arg) 703{ 704 int error; 705 bhv_vnode_t *vp; 706 xfs_inode_t *ip; 707 xfs_mount_t *mp; 708 709 vp = vn_from_inode(inode); 710 711 vn_trace_entry(vp, "xfs_ioctl", (inst_t *)__return_address); 712 713 ip = XFS_BHVTOI(bdp); 714 mp = ip->i_mount; 715 716 switch (cmd) { 717 718 case XFS_IOC_ALLOCSP: 719 case XFS_IOC_FREESP: 720 case XFS_IOC_RESVSP: 721 case XFS_IOC_UNRESVSP: 722 case XFS_IOC_ALLOCSP64: 723 case XFS_IOC_FREESP64: 724 case XFS_IOC_RESVSP64: 725 case XFS_IOC_UNRESVSP64: 726 /* 727 * Only allow the sys admin to reserve space unless 728 * unwritten extents are enabled. 729 */ 730 if (!XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) && 731 !capable(CAP_SYS_ADMIN)) 732 return -EPERM; 733 734 return xfs_ioc_space(bdp, inode, filp, ioflags, cmd, arg); 735 736 case XFS_IOC_DIOINFO: { 737 struct dioattr da; 738 xfs_buftarg_t *target = 739 (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? 740 mp->m_rtdev_targp : mp->m_ddev_targp; 741 742 da.d_mem = da.d_miniosz = 1 << target->bt_sshift; 743 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1); 744 745 if (copy_to_user(arg, &da, sizeof(da))) 746 return -XFS_ERROR(EFAULT); 747 return 0; 748 } 749 750 case XFS_IOC_FSBULKSTAT_SINGLE: 751 case XFS_IOC_FSBULKSTAT: 752 case XFS_IOC_FSINUMBERS: 753 return xfs_ioc_bulkstat(mp, cmd, arg); 754 755 case XFS_IOC_FSGEOMETRY_V1: 756 return xfs_ioc_fsgeometry_v1(mp, arg); 757 758 case XFS_IOC_FSGEOMETRY: 759 return xfs_ioc_fsgeometry(mp, arg); 760 761 case XFS_IOC_GETVERSION: 762 return put_user(inode->i_generation, (int __user *)arg); 763 764 case XFS_IOC_GETXFLAGS: 765 case XFS_IOC_SETXFLAGS: 766 case XFS_IOC_FSGETXATTR: 767 case XFS_IOC_FSSETXATTR: 768 case XFS_IOC_FSGETXATTRA: 769 return xfs_ioc_xattr(vp, ip, filp, cmd, arg); 770 771 case XFS_IOC_FSSETDM: { 772 struct fsdmidata dmi; 773 774 if (copy_from_user(&dmi, arg, sizeof(dmi))) 775 return -XFS_ERROR(EFAULT); 776 777 error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate, 778 NULL); 779 return -error; 780 } 781 782 case XFS_IOC_GETBMAP: 783 case XFS_IOC_GETBMAPA: 784 return xfs_ioc_getbmap(bdp, ioflags, cmd, arg); 785 786 case XFS_IOC_GETBMAPX: 787 return xfs_ioc_getbmapx(bdp, arg); 788 789 case XFS_IOC_FD_TO_HANDLE: 790 case XFS_IOC_PATH_TO_HANDLE: 791 case XFS_IOC_PATH_TO_FSHANDLE: 792 return xfs_find_handle(cmd, arg); 793 794 case XFS_IOC_OPEN_BY_HANDLE: 795 return xfs_open_by_handle(mp, arg, filp, inode); 796 797 case XFS_IOC_FSSETDM_BY_HANDLE: 798 return xfs_fssetdm_by_handle(mp, arg, inode); 799 800 case XFS_IOC_READLINK_BY_HANDLE: 801 return xfs_readlink_by_handle(mp, arg, inode); 802 803 case XFS_IOC_ATTRLIST_BY_HANDLE: 804 return xfs_attrlist_by_handle(mp, arg, inode); 805 806 case XFS_IOC_ATTRMULTI_BY_HANDLE: 807 return xfs_attrmulti_by_handle(mp, arg, inode); 808 809 case XFS_IOC_SWAPEXT: { 810 error = xfs_swapext((struct xfs_swapext __user *)arg); 811 return -error; 812 } 813 814 case XFS_IOC_FSCOUNTS: { 815 xfs_fsop_counts_t out; 816 817 error = xfs_fs_counts(mp, &out); 818 if (error) 819 return -error; 820 821 if (copy_to_user(arg, &out, sizeof(out))) 822 return -XFS_ERROR(EFAULT); 823 return 0; 824 } 825 826 case XFS_IOC_SET_RESBLKS: { 827 xfs_fsop_resblks_t inout; 828 __uint64_t in; 829 830 if (!capable(CAP_SYS_ADMIN)) 831 return -EPERM; 832 833 if (copy_from_user(&inout, arg, sizeof(inout))) 834 return -XFS_ERROR(EFAULT); 835 836 /* input parameter is passed in resblks field of structure */ 837 in = inout.resblks; 838 error = xfs_reserve_blocks(mp, &in, &inout); 839 if (error) 840 return -error; 841 842 if (copy_to_user(arg, &inout, sizeof(inout))) 843 return -XFS_ERROR(EFAULT); 844 return 0; 845 } 846 847 case XFS_IOC_GET_RESBLKS: { 848 xfs_fsop_resblks_t out; 849 850 if (!capable(CAP_SYS_ADMIN)) 851 return -EPERM; 852 853 error = xfs_reserve_blocks(mp, NULL, &out); 854 if (error) 855 return -error; 856 857 if (copy_to_user(arg, &out, sizeof(out))) 858 return -XFS_ERROR(EFAULT); 859 860 return 0; 861 } 862 863 case XFS_IOC_FSGROWFSDATA: { 864 xfs_growfs_data_t in; 865 866 if (!capable(CAP_SYS_ADMIN)) 867 return -EPERM; 868 869 if (copy_from_user(&in, arg, sizeof(in))) 870 return -XFS_ERROR(EFAULT); 871 872 error = xfs_growfs_data(mp, &in); 873 return -error; 874 } 875 876 case XFS_IOC_FSGROWFSLOG: { 877 xfs_growfs_log_t in; 878 879 if (!capable(CAP_SYS_ADMIN)) 880 return -EPERM; 881 882 if (copy_from_user(&in, arg, sizeof(in))) 883 return -XFS_ERROR(EFAULT); 884 885 error = xfs_growfs_log(mp, &in); 886 return -error; 887 } 888 889 case XFS_IOC_FSGROWFSRT: { 890 xfs_growfs_rt_t in; 891 892 if (!capable(CAP_SYS_ADMIN)) 893 return -EPERM; 894 895 if (copy_from_user(&in, arg, sizeof(in))) 896 return -XFS_ERROR(EFAULT); 897 898 error = xfs_growfs_rt(mp, &in); 899 return -error; 900 } 901 902 case XFS_IOC_FREEZE: 903 if (!capable(CAP_SYS_ADMIN)) 904 return -EPERM; 905 906 if (inode->i_sb->s_frozen == SB_UNFROZEN) 907 freeze_bdev(inode->i_sb->s_bdev); 908 return 0; 909 910 case XFS_IOC_THAW: 911 if (!capable(CAP_SYS_ADMIN)) 912 return -EPERM; 913 if (inode->i_sb->s_frozen != SB_UNFROZEN) 914 thaw_bdev(inode->i_sb->s_bdev, inode->i_sb); 915 return 0; 916 917 case XFS_IOC_GOINGDOWN: { 918 __uint32_t in; 919 920 if (!capable(CAP_SYS_ADMIN)) 921 return -EPERM; 922 923 if (get_user(in, (__uint32_t __user *)arg)) 924 return -XFS_ERROR(EFAULT); 925 926 error = xfs_fs_goingdown(mp, in); 927 return -error; 928 } 929 930 case XFS_IOC_ERROR_INJECTION: { 931 xfs_error_injection_t in; 932 933 if (!capable(CAP_SYS_ADMIN)) 934 return -EPERM; 935 936 if (copy_from_user(&in, arg, sizeof(in))) 937 return -XFS_ERROR(EFAULT); 938 939 error = xfs_errortag_add(in.errtag, mp); 940 return -error; 941 } 942 943 case XFS_IOC_ERROR_CLEARALL: 944 if (!capable(CAP_SYS_ADMIN)) 945 return -EPERM; 946 947 error = xfs_errortag_clearall(mp); 948 return -error; 949 950 default: 951 return -ENOTTY; 952 } 953} 954 955STATIC int 956xfs_ioc_space( 957 bhv_desc_t *bdp, 958 struct inode *inode, 959 struct file *filp, 960 int ioflags, 961 unsigned int cmd, 962 void __user *arg) 963{ 964 xfs_flock64_t bf; 965 int attr_flags = 0; 966 int error; 967 968 if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) 969 return -XFS_ERROR(EPERM); 970 971 if (!(filp->f_mode & FMODE_WRITE)) 972 return -XFS_ERROR(EBADF); 973 974 if (!S_ISREG(inode->i_mode)) 975 return -XFS_ERROR(EINVAL); 976 977 if (copy_from_user(&bf, arg, sizeof(bf))) 978 return -XFS_ERROR(EFAULT); 979 980 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 981 attr_flags |= ATTR_NONBLOCK; 982 if (ioflags & IO_INVIS) 983 attr_flags |= ATTR_DMI; 984 985 error = xfs_change_file_space(bdp, cmd, &bf, filp->f_pos, 986 NULL, attr_flags); 987 return -error; 988} 989 990STATIC int 991xfs_ioc_bulkstat( 992 xfs_mount_t *mp, 993 unsigned int cmd, 994 void __user *arg) 995{ 996 xfs_fsop_bulkreq_t bulkreq; 997 int count; /* # of records returned */ 998 xfs_ino_t inlast; /* last inode number */ 999 int done; 1000 int error; 1001 1002 /* done = 1 if there are more stats to get and if bulkstat */ 1003 /* should be called again (unused here, but used in dmapi) */ 1004 1005 if (!capable(CAP_SYS_ADMIN)) 1006 return -EPERM; 1007 1008 if (XFS_FORCED_SHUTDOWN(mp)) 1009 return -XFS_ERROR(EIO); 1010 1011 if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t))) 1012 return -XFS_ERROR(EFAULT); 1013 1014 if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64))) 1015 return -XFS_ERROR(EFAULT); 1016 1017 if ((count = bulkreq.icount) <= 0) 1018 return -XFS_ERROR(EINVAL); 1019 1020 if (cmd == XFS_IOC_FSINUMBERS) 1021 error = xfs_inumbers(mp, &inlast, &count, 1022 bulkreq.ubuffer); 1023 else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) 1024 error = xfs_bulkstat_single(mp, &inlast, 1025 bulkreq.ubuffer, &done); 1026 else { /* XFS_IOC_FSBULKSTAT */ 1027 if (count == 1 && inlast != 0) { 1028 inlast++; 1029 error = xfs_bulkstat_single(mp, &inlast, 1030 bulkreq.ubuffer, &done); 1031 } else { 1032 error = xfs_bulkstat(mp, &inlast, &count, 1033 (bulkstat_one_pf)xfs_bulkstat_one, NULL, 1034 sizeof(xfs_bstat_t), bulkreq.ubuffer, 1035 BULKSTAT_FG_QUICK, &done); 1036 } 1037 } 1038 1039 if (error) 1040 return -error; 1041 1042 if (bulkreq.ocount != NULL) { 1043 if (copy_to_user(bulkreq.lastip, &inlast, 1044 sizeof(xfs_ino_t))) 1045 return -XFS_ERROR(EFAULT); 1046 1047 if (copy_to_user(bulkreq.ocount, &count, sizeof(count))) 1048 return -XFS_ERROR(EFAULT); 1049 } 1050 1051 return 0; 1052} 1053 1054STATIC int 1055xfs_ioc_fsgeometry_v1( 1056 xfs_mount_t *mp, 1057 void __user *arg) 1058{ 1059 xfs_fsop_geom_v1_t fsgeo; 1060 int error; 1061 1062 error = xfs_fs_geometry(mp, (xfs_fsop_geom_t *)&fsgeo, 3); 1063 if (error) 1064 return -error; 1065 1066 if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) 1067 return -XFS_ERROR(EFAULT); 1068 return 0; 1069} 1070 1071STATIC int 1072xfs_ioc_fsgeometry( 1073 xfs_mount_t *mp, 1074 void __user *arg) 1075{ 1076 xfs_fsop_geom_t fsgeo; 1077 int error; 1078 1079 error = xfs_fs_geometry(mp, &fsgeo, 4); 1080 if (error) 1081 return -error; 1082 1083 if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) 1084 return -XFS_ERROR(EFAULT); 1085 return 0; 1086} 1087 1088/* 1089 * Linux extended inode flags interface. 1090 */ 1091 1092STATIC unsigned int 1093xfs_merge_ioc_xflags( 1094 unsigned int flags, 1095 unsigned int start) 1096{ 1097 unsigned int xflags = start; 1098 1099 if (flags & FS_IMMUTABLE_FL) 1100 xflags |= XFS_XFLAG_IMMUTABLE; 1101 else 1102 xflags &= ~XFS_XFLAG_IMMUTABLE; 1103 if (flags & FS_APPEND_FL) 1104 xflags |= XFS_XFLAG_APPEND; 1105 else 1106 xflags &= ~XFS_XFLAG_APPEND; 1107 if (flags & FS_SYNC_FL) 1108 xflags |= XFS_XFLAG_SYNC; 1109 else 1110 xflags &= ~XFS_XFLAG_SYNC; 1111 if (flags & FS_NOATIME_FL) 1112 xflags |= XFS_XFLAG_NOATIME; 1113 else 1114 xflags &= ~XFS_XFLAG_NOATIME; 1115 if (flags & FS_NODUMP_FL) 1116 xflags |= XFS_XFLAG_NODUMP; 1117 else 1118 xflags &= ~XFS_XFLAG_NODUMP; 1119 1120 return xflags; 1121} 1122 1123STATIC unsigned int 1124xfs_di2lxflags( 1125 __uint16_t di_flags) 1126{ 1127 unsigned int flags = 0; 1128 1129 if (di_flags & XFS_DIFLAG_IMMUTABLE) 1130 flags |= FS_IMMUTABLE_FL; 1131 if (di_flags & XFS_DIFLAG_APPEND) 1132 flags |= FS_APPEND_FL; 1133 if (di_flags & XFS_DIFLAG_SYNC) 1134 flags |= FS_SYNC_FL; 1135 if (di_flags & XFS_DIFLAG_NOATIME) 1136 flags |= FS_NOATIME_FL; 1137 if (di_flags & XFS_DIFLAG_NODUMP) 1138 flags |= FS_NODUMP_FL; 1139 return flags; 1140} 1141 1142STATIC int 1143xfs_ioc_xattr( 1144 bhv_vnode_t *vp, 1145 xfs_inode_t *ip, 1146 struct file *filp, 1147 unsigned int cmd, 1148 void __user *arg) 1149{ 1150 struct fsxattr fa; 1151 struct bhv_vattr *vattr; 1152 int error = 0; 1153 int attr_flags; 1154 unsigned int flags; 1155 1156 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); 1157 if (unlikely(!vattr)) 1158 return -ENOMEM; 1159 1160 switch (cmd) { 1161 case XFS_IOC_FSGETXATTR: { 1162 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ 1163 XFS_AT_NEXTENTS | XFS_AT_PROJID; 1164 error = bhv_vop_getattr(vp, vattr, 0, NULL); 1165 if (unlikely(error)) { 1166 error = -error; 1167 break; 1168 } 1169 1170 fa.fsx_xflags = vattr->va_xflags; 1171 fa.fsx_extsize = vattr->va_extsize; 1172 fa.fsx_nextents = vattr->va_nextents; 1173 fa.fsx_projid = vattr->va_projid; 1174 1175 if (copy_to_user(arg, &fa, sizeof(fa))) { 1176 error = -EFAULT; 1177 break; 1178 } 1179 break; 1180 } 1181 1182 case XFS_IOC_FSSETXATTR: { 1183 if (copy_from_user(&fa, arg, sizeof(fa))) { 1184 error = -EFAULT; 1185 break; 1186 } 1187 1188 attr_flags = 0; 1189 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 1190 attr_flags |= ATTR_NONBLOCK; 1191 1192 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID; 1193 vattr->va_xflags = fa.fsx_xflags; 1194 vattr->va_extsize = fa.fsx_extsize; 1195 vattr->va_projid = fa.fsx_projid; 1196 1197 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL); 1198 if (likely(!error)) 1199 __vn_revalidate(vp, vattr); /* update flags */ 1200 error = -error; 1201 break; 1202 } 1203 1204 case XFS_IOC_FSGETXATTRA: { 1205 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ 1206 XFS_AT_ANEXTENTS | XFS_AT_PROJID; 1207 error = bhv_vop_getattr(vp, vattr, 0, NULL); 1208 if (unlikely(error)) { 1209 error = -error; 1210 break; 1211 } 1212 1213 fa.fsx_xflags = vattr->va_xflags; 1214 fa.fsx_extsize = vattr->va_extsize; 1215 fa.fsx_nextents = vattr->va_anextents; 1216 fa.fsx_projid = vattr->va_projid; 1217 1218 if (copy_to_user(arg, &fa, sizeof(fa))) { 1219 error = -EFAULT; 1220 break; 1221 } 1222 break; 1223 } 1224 1225 case XFS_IOC_GETXFLAGS: { 1226 flags = xfs_di2lxflags(ip->i_d.di_flags); 1227 if (copy_to_user(arg, &flags, sizeof(flags))) 1228 error = -EFAULT; 1229 break; 1230 } 1231 1232 case XFS_IOC_SETXFLAGS: { 1233 if (copy_from_user(&flags, arg, sizeof(flags))) { 1234 error = -EFAULT; 1235 break; 1236 } 1237 1238 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ 1239 FS_NOATIME_FL | FS_NODUMP_FL | \ 1240 FS_SYNC_FL)) { 1241 error = -EOPNOTSUPP; 1242 break; 1243 } 1244 1245 attr_flags = 0; 1246 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 1247 attr_flags |= ATTR_NONBLOCK; 1248 1249 vattr->va_mask = XFS_AT_XFLAGS; 1250 vattr->va_xflags = xfs_merge_ioc_xflags(flags, 1251 xfs_ip2xflags(ip)); 1252 1253 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL); 1254 if (likely(!error)) 1255 __vn_revalidate(vp, vattr); /* update flags */ 1256 error = -error; 1257 break; 1258 } 1259 1260 default: 1261 error = -ENOTTY; 1262 break; 1263 } 1264 1265 kfree(vattr); 1266 return error; 1267} 1268 1269STATIC int 1270xfs_ioc_getbmap( 1271 bhv_desc_t *bdp, 1272 int ioflags, 1273 unsigned int cmd, 1274 void __user *arg) 1275{ 1276 struct getbmap bm; 1277 int iflags; 1278 int error; 1279 1280 if (copy_from_user(&bm, arg, sizeof(bm))) 1281 return -XFS_ERROR(EFAULT); 1282 1283 if (bm.bmv_count < 2) 1284 return -XFS_ERROR(EINVAL); 1285 1286 iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); 1287 if (ioflags & IO_INVIS) 1288 iflags |= BMV_IF_NO_DMAPI_READ; 1289 1290 error = xfs_getbmap(bdp, &bm, (struct getbmap __user *)arg+1, iflags); 1291 if (error) 1292 return -error; 1293 1294 if (copy_to_user(arg, &bm, sizeof(bm))) 1295 return -XFS_ERROR(EFAULT); 1296 return 0; 1297} 1298 1299STATIC int 1300xfs_ioc_getbmapx( 1301 bhv_desc_t *bdp, 1302 void __user *arg) 1303{ 1304 struct getbmapx bmx; 1305 struct getbmap bm; 1306 int iflags; 1307 int error; 1308 1309 if (copy_from_user(&bmx, arg, sizeof(bmx))) 1310 return -XFS_ERROR(EFAULT); 1311 1312 if (bmx.bmv_count < 2) 1313 return -XFS_ERROR(EINVAL); 1314 1315 /* 1316 * Map input getbmapx structure to a getbmap 1317 * structure for xfs_getbmap. 1318 */ 1319 GETBMAP_CONVERT(bmx, bm); 1320 1321 iflags = bmx.bmv_iflags; 1322 1323 if (iflags & (~BMV_IF_VALID)) 1324 return -XFS_ERROR(EINVAL); 1325 1326 iflags |= BMV_IF_EXTENDED; 1327 1328 error = xfs_getbmap(bdp, &bm, (struct getbmapx __user *)arg+1, iflags); 1329 if (error) 1330 return -error; 1331 1332 GETBMAP_CONVERT(bm, bmx); 1333 1334 if (copy_to_user(arg, &bmx, sizeof(bmx))) 1335 return -XFS_ERROR(EFAULT); 1336 1337 return 0; 1338} 1339