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