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 = file_inode(f.file); 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(file_inode(parfilp)->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_flags(0); 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 = kmem_zalloc(al_hreq.buflen, KM_SLEEP | KM_MAYFAIL); 426 if (!kbuf) { 427 kbuf = kmem_zalloc_large(al_hreq.buflen); 428 if (!kbuf) 429 goto out_dput; 430 } 431 432 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; 433 error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen, 434 al_hreq.flags, cursor); 435 if (error) 436 goto out_kfree; 437 438 if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen)) 439 error = -EFAULT; 440 441 out_kfree: 442 if (is_vmalloc_addr(kbuf)) 443 kmem_free_large(kbuf); 444 else 445 kmem_free(kbuf); 446 out_dput: 447 dput(dentry); 448 return error; 449 } 450 451 int 452 xfs_attrmulti_attr_get( 453 struct inode *inode, 454 unsigned char *name, 455 unsigned char __user *ubuf, 456 __uint32_t *len, 457 __uint32_t flags) 458 { 459 unsigned char *kbuf; 460 int error = EFAULT; 461 462 if (*len > XATTR_SIZE_MAX) 463 return EINVAL; 464 kbuf = kmem_zalloc(*len, KM_SLEEP | KM_MAYFAIL); 465 if (!kbuf) { 466 kbuf = kmem_zalloc_large(*len); 467 if (!kbuf) 468 return ENOMEM; 469 } 470 471 error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags); 472 if (error) 473 goto out_kfree; 474 475 if (copy_to_user(ubuf, kbuf, *len)) 476 error = EFAULT; 477 478 out_kfree: 479 if (is_vmalloc_addr(kbuf)) 480 kmem_free_large(kbuf); 481 else 482 kmem_free(kbuf); 483 return error; 484 } 485 486 int 487 xfs_attrmulti_attr_set( 488 struct inode *inode, 489 unsigned char *name, 490 const unsigned char __user *ubuf, 491 __uint32_t len, 492 __uint32_t flags) 493 { 494 unsigned char *kbuf; 495 int error = EFAULT; 496 497 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 498 return EPERM; 499 if (len > XATTR_SIZE_MAX) 500 return EINVAL; 501 502 kbuf = memdup_user(ubuf, len); 503 if (IS_ERR(kbuf)) 504 return PTR_ERR(kbuf); 505 506 error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); 507 508 return error; 509 } 510 511 int 512 xfs_attrmulti_attr_remove( 513 struct inode *inode, 514 unsigned char *name, 515 __uint32_t flags) 516 { 517 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 518 return EPERM; 519 return xfs_attr_remove(XFS_I(inode), name, flags); 520 } 521 522 STATIC int 523 xfs_attrmulti_by_handle( 524 struct file *parfilp, 525 void __user *arg) 526 { 527 int error; 528 xfs_attr_multiop_t *ops; 529 xfs_fsop_attrmulti_handlereq_t am_hreq; 530 struct dentry *dentry; 531 unsigned int i, size; 532 unsigned char *attr_name; 533 534 if (!capable(CAP_SYS_ADMIN)) 535 return -XFS_ERROR(EPERM); 536 if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t))) 537 return -XFS_ERROR(EFAULT); 538 539 /* overflow check */ 540 if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t)) 541 return -E2BIG; 542 543 dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq); 544 if (IS_ERR(dentry)) 545 return PTR_ERR(dentry); 546 547 error = E2BIG; 548 size = am_hreq.opcount * sizeof(xfs_attr_multiop_t); 549 if (!size || size > 16 * PAGE_SIZE) 550 goto out_dput; 551 552 ops = memdup_user(am_hreq.ops, size); 553 if (IS_ERR(ops)) { 554 error = PTR_ERR(ops); 555 goto out_dput; 556 } 557 558 attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); 559 if (!attr_name) 560 goto out_kfree_ops; 561 562 error = 0; 563 for (i = 0; i < am_hreq.opcount; i++) { 564 ops[i].am_error = strncpy_from_user((char *)attr_name, 565 ops[i].am_attrname, MAXNAMELEN); 566 if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) 567 error = -ERANGE; 568 if (ops[i].am_error < 0) 569 break; 570 571 switch (ops[i].am_opcode) { 572 case ATTR_OP_GET: 573 ops[i].am_error = xfs_attrmulti_attr_get( 574 dentry->d_inode, attr_name, 575 ops[i].am_attrvalue, &ops[i].am_length, 576 ops[i].am_flags); 577 break; 578 case ATTR_OP_SET: 579 ops[i].am_error = mnt_want_write_file(parfilp); 580 if (ops[i].am_error) 581 break; 582 ops[i].am_error = xfs_attrmulti_attr_set( 583 dentry->d_inode, attr_name, 584 ops[i].am_attrvalue, ops[i].am_length, 585 ops[i].am_flags); 586 mnt_drop_write_file(parfilp); 587 break; 588 case ATTR_OP_REMOVE: 589 ops[i].am_error = mnt_want_write_file(parfilp); 590 if (ops[i].am_error) 591 break; 592 ops[i].am_error = xfs_attrmulti_attr_remove( 593 dentry->d_inode, attr_name, 594 ops[i].am_flags); 595 mnt_drop_write_file(parfilp); 596 break; 597 default: 598 ops[i].am_error = EINVAL; 599 } 600 } 601 602 if (copy_to_user(am_hreq.ops, ops, size)) 603 error = XFS_ERROR(EFAULT); 604 605 kfree(attr_name); 606 out_kfree_ops: 607 kfree(ops); 608 out_dput: 609 dput(dentry); 610 return -error; 611 } 612 613 int 614 xfs_ioc_space( 615 struct xfs_inode *ip, 616 struct inode *inode, 617 struct file *filp, 618 int ioflags, 619 unsigned int cmd, 620 xfs_flock64_t *bf) 621 { 622 int attr_flags = 0; 623 int error; 624 625 /* 626 * Only allow the sys admin to reserve space unless 627 * unwritten extents are enabled. 628 */ 629 if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) && 630 !capable(CAP_SYS_ADMIN)) 631 return -XFS_ERROR(EPERM); 632 633 if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) 634 return -XFS_ERROR(EPERM); 635 636 if (!(filp->f_mode & FMODE_WRITE)) 637 return -XFS_ERROR(EBADF); 638 639 if (!S_ISREG(inode->i_mode)) 640 return -XFS_ERROR(EINVAL); 641 642 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 643 attr_flags |= XFS_ATTR_NONBLOCK; 644 645 if (filp->f_flags & O_DSYNC) 646 attr_flags |= XFS_ATTR_SYNC; 647 648 if (ioflags & IO_INVIS) 649 attr_flags |= XFS_ATTR_DMI; 650 651 error = mnt_want_write_file(filp); 652 if (error) 653 return error; 654 error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags); 655 mnt_drop_write_file(filp); 656 return -error; 657 } 658 659 STATIC int 660 xfs_ioc_bulkstat( 661 xfs_mount_t *mp, 662 unsigned int cmd, 663 void __user *arg) 664 { 665 xfs_fsop_bulkreq_t bulkreq; 666 int count; /* # of records returned */ 667 xfs_ino_t inlast; /* last inode number */ 668 int done; 669 int error; 670 671 /* done = 1 if there are more stats to get and if bulkstat */ 672 /* should be called again (unused here, but used in dmapi) */ 673 674 if (!capable(CAP_SYS_ADMIN)) 675 return -EPERM; 676 677 if (XFS_FORCED_SHUTDOWN(mp)) 678 return -XFS_ERROR(EIO); 679 680 if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t))) 681 return -XFS_ERROR(EFAULT); 682 683 if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64))) 684 return -XFS_ERROR(EFAULT); 685 686 if ((count = bulkreq.icount) <= 0) 687 return -XFS_ERROR(EINVAL); 688 689 if (bulkreq.ubuffer == NULL) 690 return -XFS_ERROR(EINVAL); 691 692 if (cmd == XFS_IOC_FSINUMBERS) 693 error = xfs_inumbers(mp, &inlast, &count, 694 bulkreq.ubuffer, xfs_inumbers_fmt); 695 else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) 696 error = xfs_bulkstat_single(mp, &inlast, 697 bulkreq.ubuffer, &done); 698 else /* XFS_IOC_FSBULKSTAT */ 699 error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one, 700 sizeof(xfs_bstat_t), bulkreq.ubuffer, 701 &done); 702 703 if (error) 704 return -error; 705 706 if (bulkreq.ocount != NULL) { 707 if (copy_to_user(bulkreq.lastip, &inlast, 708 sizeof(xfs_ino_t))) 709 return -XFS_ERROR(EFAULT); 710 711 if (copy_to_user(bulkreq.ocount, &count, sizeof(count))) 712 return -XFS_ERROR(EFAULT); 713 } 714 715 return 0; 716 } 717 718 STATIC int 719 xfs_ioc_fsgeometry_v1( 720 xfs_mount_t *mp, 721 void __user *arg) 722 { 723 xfs_fsop_geom_t fsgeo; 724 int error; 725 726 error = xfs_fs_geometry(mp, &fsgeo, 3); 727 if (error) 728 return -error; 729 730 /* 731 * Caller should have passed an argument of type 732 * xfs_fsop_geom_v1_t. This is a proper subset of the 733 * xfs_fsop_geom_t that xfs_fs_geometry() fills in. 734 */ 735 if (copy_to_user(arg, &fsgeo, sizeof(xfs_fsop_geom_v1_t))) 736 return -XFS_ERROR(EFAULT); 737 return 0; 738 } 739 740 STATIC int 741 xfs_ioc_fsgeometry( 742 xfs_mount_t *mp, 743 void __user *arg) 744 { 745 xfs_fsop_geom_t fsgeo; 746 int error; 747 748 error = xfs_fs_geometry(mp, &fsgeo, 4); 749 if (error) 750 return -error; 751 752 if (copy_to_user(arg, &fsgeo, sizeof(fsgeo))) 753 return -XFS_ERROR(EFAULT); 754 return 0; 755 } 756 757 /* 758 * Linux extended inode flags interface. 759 */ 760 761 STATIC unsigned int 762 xfs_merge_ioc_xflags( 763 unsigned int flags, 764 unsigned int start) 765 { 766 unsigned int xflags = start; 767 768 if (flags & FS_IMMUTABLE_FL) 769 xflags |= XFS_XFLAG_IMMUTABLE; 770 else 771 xflags &= ~XFS_XFLAG_IMMUTABLE; 772 if (flags & FS_APPEND_FL) 773 xflags |= XFS_XFLAG_APPEND; 774 else 775 xflags &= ~XFS_XFLAG_APPEND; 776 if (flags & FS_SYNC_FL) 777 xflags |= XFS_XFLAG_SYNC; 778 else 779 xflags &= ~XFS_XFLAG_SYNC; 780 if (flags & FS_NOATIME_FL) 781 xflags |= XFS_XFLAG_NOATIME; 782 else 783 xflags &= ~XFS_XFLAG_NOATIME; 784 if (flags & FS_NODUMP_FL) 785 xflags |= XFS_XFLAG_NODUMP; 786 else 787 xflags &= ~XFS_XFLAG_NODUMP; 788 789 return xflags; 790 } 791 792 STATIC unsigned int 793 xfs_di2lxflags( 794 __uint16_t di_flags) 795 { 796 unsigned int flags = 0; 797 798 if (di_flags & XFS_DIFLAG_IMMUTABLE) 799 flags |= FS_IMMUTABLE_FL; 800 if (di_flags & XFS_DIFLAG_APPEND) 801 flags |= FS_APPEND_FL; 802 if (di_flags & XFS_DIFLAG_SYNC) 803 flags |= FS_SYNC_FL; 804 if (di_flags & XFS_DIFLAG_NOATIME) 805 flags |= FS_NOATIME_FL; 806 if (di_flags & XFS_DIFLAG_NODUMP) 807 flags |= FS_NODUMP_FL; 808 return flags; 809 } 810 811 STATIC int 812 xfs_ioc_fsgetxattr( 813 xfs_inode_t *ip, 814 int attr, 815 void __user *arg) 816 { 817 struct fsxattr fa; 818 819 memset(&fa, 0, sizeof(struct fsxattr)); 820 821 xfs_ilock(ip, XFS_ILOCK_SHARED); 822 fa.fsx_xflags = xfs_ip2xflags(ip); 823 fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog; 824 fa.fsx_projid = xfs_get_projid(ip); 825 826 if (attr) { 827 if (ip->i_afp) { 828 if (ip->i_afp->if_flags & XFS_IFEXTENTS) 829 fa.fsx_nextents = ip->i_afp->if_bytes / 830 sizeof(xfs_bmbt_rec_t); 831 else 832 fa.fsx_nextents = ip->i_d.di_anextents; 833 } else 834 fa.fsx_nextents = 0; 835 } else { 836 if (ip->i_df.if_flags & XFS_IFEXTENTS) 837 fa.fsx_nextents = ip->i_df.if_bytes / 838 sizeof(xfs_bmbt_rec_t); 839 else 840 fa.fsx_nextents = ip->i_d.di_nextents; 841 } 842 xfs_iunlock(ip, XFS_ILOCK_SHARED); 843 844 if (copy_to_user(arg, &fa, sizeof(fa))) 845 return -EFAULT; 846 return 0; 847 } 848 849 STATIC void 850 xfs_set_diflags( 851 struct xfs_inode *ip, 852 unsigned int xflags) 853 { 854 unsigned int di_flags; 855 856 /* can't set PREALLOC this way, just preserve it */ 857 di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC); 858 if (xflags & XFS_XFLAG_IMMUTABLE) 859 di_flags |= XFS_DIFLAG_IMMUTABLE; 860 if (xflags & XFS_XFLAG_APPEND) 861 di_flags |= XFS_DIFLAG_APPEND; 862 if (xflags & XFS_XFLAG_SYNC) 863 di_flags |= XFS_DIFLAG_SYNC; 864 if (xflags & XFS_XFLAG_NOATIME) 865 di_flags |= XFS_DIFLAG_NOATIME; 866 if (xflags & XFS_XFLAG_NODUMP) 867 di_flags |= XFS_DIFLAG_NODUMP; 868 if (xflags & XFS_XFLAG_PROJINHERIT) 869 di_flags |= XFS_DIFLAG_PROJINHERIT; 870 if (xflags & XFS_XFLAG_NODEFRAG) 871 di_flags |= XFS_DIFLAG_NODEFRAG; 872 if (xflags & XFS_XFLAG_FILESTREAM) 873 di_flags |= XFS_DIFLAG_FILESTREAM; 874 if (S_ISDIR(ip->i_d.di_mode)) { 875 if (xflags & XFS_XFLAG_RTINHERIT) 876 di_flags |= XFS_DIFLAG_RTINHERIT; 877 if (xflags & XFS_XFLAG_NOSYMLINKS) 878 di_flags |= XFS_DIFLAG_NOSYMLINKS; 879 if (xflags & XFS_XFLAG_EXTSZINHERIT) 880 di_flags |= XFS_DIFLAG_EXTSZINHERIT; 881 } else if (S_ISREG(ip->i_d.di_mode)) { 882 if (xflags & XFS_XFLAG_REALTIME) 883 di_flags |= XFS_DIFLAG_REALTIME; 884 if (xflags & XFS_XFLAG_EXTSIZE) 885 di_flags |= XFS_DIFLAG_EXTSIZE; 886 } 887 888 ip->i_d.di_flags = di_flags; 889 } 890 891 STATIC void 892 xfs_diflags_to_linux( 893 struct xfs_inode *ip) 894 { 895 struct inode *inode = VFS_I(ip); 896 unsigned int xflags = xfs_ip2xflags(ip); 897 898 if (xflags & XFS_XFLAG_IMMUTABLE) 899 inode->i_flags |= S_IMMUTABLE; 900 else 901 inode->i_flags &= ~S_IMMUTABLE; 902 if (xflags & XFS_XFLAG_APPEND) 903 inode->i_flags |= S_APPEND; 904 else 905 inode->i_flags &= ~S_APPEND; 906 if (xflags & XFS_XFLAG_SYNC) 907 inode->i_flags |= S_SYNC; 908 else 909 inode->i_flags &= ~S_SYNC; 910 if (xflags & XFS_XFLAG_NOATIME) 911 inode->i_flags |= S_NOATIME; 912 else 913 inode->i_flags &= ~S_NOATIME; 914 } 915 916 #define FSX_PROJID 1 917 #define FSX_EXTSIZE 2 918 #define FSX_XFLAGS 4 919 #define FSX_NONBLOCK 8 920 921 STATIC int 922 xfs_ioctl_setattr( 923 xfs_inode_t *ip, 924 struct fsxattr *fa, 925 int mask) 926 { 927 struct xfs_mount *mp = ip->i_mount; 928 struct xfs_trans *tp; 929 unsigned int lock_flags = 0; 930 struct xfs_dquot *udqp = NULL; 931 struct xfs_dquot *pdqp = NULL; 932 struct xfs_dquot *olddquot = NULL; 933 int code; 934 935 trace_xfs_ioctl_setattr(ip); 936 937 if (mp->m_flags & XFS_MOUNT_RDONLY) 938 return XFS_ERROR(EROFS); 939 if (XFS_FORCED_SHUTDOWN(mp)) 940 return XFS_ERROR(EIO); 941 942 /* 943 * Disallow 32bit project ids when projid32bit feature is not enabled. 944 */ 945 if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1) && 946 !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb)) 947 return XFS_ERROR(EINVAL); 948 949 /* 950 * If disk quotas is on, we make sure that the dquots do exist on disk, 951 * before we start any other transactions. Trying to do this later 952 * is messy. We don't care to take a readlock to look at the ids 953 * in inode here, because we can't hold it across the trans_reserve. 954 * If the IDs do change before we take the ilock, we're covered 955 * because the i_*dquot fields will get updated anyway. 956 */ 957 if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) { 958 code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid, 959 ip->i_d.di_gid, fa->fsx_projid, 960 XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp); 961 if (code) 962 return code; 963 } 964 965 /* 966 * For the other attributes, we acquire the inode lock and 967 * first do an error checking pass. 968 */ 969 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); 970 code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); 971 if (code) 972 goto error_return; 973 974 lock_flags = XFS_ILOCK_EXCL; 975 xfs_ilock(ip, lock_flags); 976 977 /* 978 * CAP_FOWNER overrides the following restrictions: 979 * 980 * The user ID of the calling process must be equal 981 * to the file owner ID, except in cases where the 982 * CAP_FSETID capability is applicable. 983 */ 984 if (current_fsuid() != ip->i_d.di_uid && !capable(CAP_FOWNER)) { 985 code = XFS_ERROR(EPERM); 986 goto error_return; 987 } 988 989 /* 990 * Do a quota reservation only if projid is actually going to change. 991 */ 992 if (mask & FSX_PROJID) { 993 if (XFS_IS_QUOTA_RUNNING(mp) && 994 XFS_IS_PQUOTA_ON(mp) && 995 xfs_get_projid(ip) != fa->fsx_projid) { 996 ASSERT(tp); 997 code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL, 998 pdqp, capable(CAP_FOWNER) ? 999 XFS_QMOPT_FORCE_RES : 0); 1000 if (code) /* out of quota */ 1001 goto error_return; 1002 } 1003 } 1004 1005 if (mask & FSX_EXTSIZE) { 1006 /* 1007 * Can't change extent size if any extents are allocated. 1008 */ 1009 if (ip->i_d.di_nextents && 1010 ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != 1011 fa->fsx_extsize)) { 1012 code = XFS_ERROR(EINVAL); /* EFBIG? */ 1013 goto error_return; 1014 } 1015 1016 /* 1017 * Extent size must be a multiple of the appropriate block 1018 * size, if set at all. It must also be smaller than the 1019 * maximum extent size supported by the filesystem. 1020 * 1021 * Also, for non-realtime files, limit the extent size hint to 1022 * half the size of the AGs in the filesystem so alignment 1023 * doesn't result in extents larger than an AG. 1024 */ 1025 if (fa->fsx_extsize != 0) { 1026 xfs_extlen_t size; 1027 xfs_fsblock_t extsize_fsb; 1028 1029 extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize); 1030 if (extsize_fsb > MAXEXTLEN) { 1031 code = XFS_ERROR(EINVAL); 1032 goto error_return; 1033 } 1034 1035 if (XFS_IS_REALTIME_INODE(ip) || 1036 ((mask & FSX_XFLAGS) && 1037 (fa->fsx_xflags & XFS_XFLAG_REALTIME))) { 1038 size = mp->m_sb.sb_rextsize << 1039 mp->m_sb.sb_blocklog; 1040 } else { 1041 size = mp->m_sb.sb_blocksize; 1042 if (extsize_fsb > mp->m_sb.sb_agblocks / 2) { 1043 code = XFS_ERROR(EINVAL); 1044 goto error_return; 1045 } 1046 } 1047 1048 if (fa->fsx_extsize % size) { 1049 code = XFS_ERROR(EINVAL); 1050 goto error_return; 1051 } 1052 } 1053 } 1054 1055 1056 if (mask & FSX_XFLAGS) { 1057 /* 1058 * Can't change realtime flag if any extents are allocated. 1059 */ 1060 if ((ip->i_d.di_nextents || ip->i_delayed_blks) && 1061 (XFS_IS_REALTIME_INODE(ip)) != 1062 (fa->fsx_xflags & XFS_XFLAG_REALTIME)) { 1063 code = XFS_ERROR(EINVAL); /* EFBIG? */ 1064 goto error_return; 1065 } 1066 1067 /* 1068 * If realtime flag is set then must have realtime data. 1069 */ 1070 if ((fa->fsx_xflags & XFS_XFLAG_REALTIME)) { 1071 if ((mp->m_sb.sb_rblocks == 0) || 1072 (mp->m_sb.sb_rextsize == 0) || 1073 (ip->i_d.di_extsize % mp->m_sb.sb_rextsize)) { 1074 code = XFS_ERROR(EINVAL); 1075 goto error_return; 1076 } 1077 } 1078 1079 /* 1080 * Can't modify an immutable/append-only file unless 1081 * we have appropriate permission. 1082 */ 1083 if ((ip->i_d.di_flags & 1084 (XFS_DIFLAG_IMMUTABLE|XFS_DIFLAG_APPEND) || 1085 (fa->fsx_xflags & 1086 (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) && 1087 !capable(CAP_LINUX_IMMUTABLE)) { 1088 code = XFS_ERROR(EPERM); 1089 goto error_return; 1090 } 1091 } 1092 1093 xfs_trans_ijoin(tp, ip, 0); 1094 1095 /* 1096 * Change file ownership. Must be the owner or privileged. 1097 */ 1098 if (mask & FSX_PROJID) { 1099 /* 1100 * CAP_FSETID overrides the following restrictions: 1101 * 1102 * The set-user-ID and set-group-ID bits of a file will be 1103 * cleared upon successful return from chown() 1104 */ 1105 if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) && 1106 !capable(CAP_FSETID)) 1107 ip->i_d.di_mode &= ~(S_ISUID|S_ISGID); 1108 1109 /* 1110 * Change the ownerships and register quota modifications 1111 * in the transaction. 1112 */ 1113 if (xfs_get_projid(ip) != fa->fsx_projid) { 1114 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) { 1115 olddquot = xfs_qm_vop_chown(tp, ip, 1116 &ip->i_pdquot, pdqp); 1117 } 1118 xfs_set_projid(ip, fa->fsx_projid); 1119 1120 /* 1121 * We may have to rev the inode as well as 1122 * the superblock version number since projids didn't 1123 * exist before DINODE_VERSION_2 and SB_VERSION_NLINK. 1124 */ 1125 if (ip->i_d.di_version == 1) 1126 xfs_bump_ino_vers2(tp, ip); 1127 } 1128 1129 } 1130 1131 if (mask & FSX_EXTSIZE) 1132 ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog; 1133 if (mask & FSX_XFLAGS) { 1134 xfs_set_diflags(ip, fa->fsx_xflags); 1135 xfs_diflags_to_linux(ip); 1136 } 1137 1138 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); 1139 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1140 1141 XFS_STATS_INC(xs_ig_attrchg); 1142 1143 /* 1144 * If this is a synchronous mount, make sure that the 1145 * transaction goes to disk before returning to the user. 1146 * This is slightly sub-optimal in that truncates require 1147 * two sync transactions instead of one for wsync filesystems. 1148 * One for the truncate and one for the timestamps since we 1149 * don't want to change the timestamps unless we're sure the 1150 * truncate worked. Truncates are less than 1% of the laddis 1151 * mix so this probably isn't worth the trouble to optimize. 1152 */ 1153 if (mp->m_flags & XFS_MOUNT_WSYNC) 1154 xfs_trans_set_sync(tp); 1155 code = xfs_trans_commit(tp, 0); 1156 xfs_iunlock(ip, lock_flags); 1157 1158 /* 1159 * Release any dquot(s) the inode had kept before chown. 1160 */ 1161 xfs_qm_dqrele(olddquot); 1162 xfs_qm_dqrele(udqp); 1163 xfs_qm_dqrele(pdqp); 1164 1165 return code; 1166 1167 error_return: 1168 xfs_qm_dqrele(udqp); 1169 xfs_qm_dqrele(pdqp); 1170 xfs_trans_cancel(tp, 0); 1171 if (lock_flags) 1172 xfs_iunlock(ip, lock_flags); 1173 return code; 1174 } 1175 1176 STATIC int 1177 xfs_ioc_fssetxattr( 1178 xfs_inode_t *ip, 1179 struct file *filp, 1180 void __user *arg) 1181 { 1182 struct fsxattr fa; 1183 unsigned int mask; 1184 int error; 1185 1186 if (copy_from_user(&fa, arg, sizeof(fa))) 1187 return -EFAULT; 1188 1189 mask = FSX_XFLAGS | FSX_EXTSIZE | FSX_PROJID; 1190 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 1191 mask |= FSX_NONBLOCK; 1192 1193 error = mnt_want_write_file(filp); 1194 if (error) 1195 return error; 1196 error = xfs_ioctl_setattr(ip, &fa, mask); 1197 mnt_drop_write_file(filp); 1198 return -error; 1199 } 1200 1201 STATIC int 1202 xfs_ioc_getxflags( 1203 xfs_inode_t *ip, 1204 void __user *arg) 1205 { 1206 unsigned int flags; 1207 1208 flags = xfs_di2lxflags(ip->i_d.di_flags); 1209 if (copy_to_user(arg, &flags, sizeof(flags))) 1210 return -EFAULT; 1211 return 0; 1212 } 1213 1214 STATIC int 1215 xfs_ioc_setxflags( 1216 xfs_inode_t *ip, 1217 struct file *filp, 1218 void __user *arg) 1219 { 1220 struct fsxattr fa; 1221 unsigned int flags; 1222 unsigned int mask; 1223 int error; 1224 1225 if (copy_from_user(&flags, arg, sizeof(flags))) 1226 return -EFAULT; 1227 1228 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ 1229 FS_NOATIME_FL | FS_NODUMP_FL | \ 1230 FS_SYNC_FL)) 1231 return -EOPNOTSUPP; 1232 1233 mask = FSX_XFLAGS; 1234 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 1235 mask |= FSX_NONBLOCK; 1236 fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip)); 1237 1238 error = mnt_want_write_file(filp); 1239 if (error) 1240 return error; 1241 error = xfs_ioctl_setattr(ip, &fa, mask); 1242 mnt_drop_write_file(filp); 1243 return -error; 1244 } 1245 1246 STATIC int 1247 xfs_getbmap_format(void **ap, struct getbmapx *bmv, int *full) 1248 { 1249 struct getbmap __user *base = *ap; 1250 1251 /* copy only getbmap portion (not getbmapx) */ 1252 if (copy_to_user(base, bmv, sizeof(struct getbmap))) 1253 return XFS_ERROR(EFAULT); 1254 1255 *ap += sizeof(struct getbmap); 1256 return 0; 1257 } 1258 1259 STATIC int 1260 xfs_ioc_getbmap( 1261 struct xfs_inode *ip, 1262 int ioflags, 1263 unsigned int cmd, 1264 void __user *arg) 1265 { 1266 struct getbmapx bmx; 1267 int error; 1268 1269 if (copy_from_user(&bmx, arg, sizeof(struct getbmapx))) 1270 return -XFS_ERROR(EFAULT); 1271 1272 if (bmx.bmv_count < 2) 1273 return -XFS_ERROR(EINVAL); 1274 1275 bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); 1276 if (ioflags & IO_INVIS) 1277 bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ; 1278 1279 error = xfs_getbmap(ip, &bmx, xfs_getbmap_format, 1280 (struct getbmap *)arg+1); 1281 if (error) 1282 return -error; 1283 1284 /* copy back header - only size of getbmap */ 1285 if (copy_to_user(arg, &bmx, sizeof(struct getbmap))) 1286 return -XFS_ERROR(EFAULT); 1287 return 0; 1288 } 1289 1290 STATIC int 1291 xfs_getbmapx_format(void **ap, struct getbmapx *bmv, int *full) 1292 { 1293 struct getbmapx __user *base = *ap; 1294 1295 if (copy_to_user(base, bmv, sizeof(struct getbmapx))) 1296 return XFS_ERROR(EFAULT); 1297 1298 *ap += sizeof(struct getbmapx); 1299 return 0; 1300 } 1301 1302 STATIC int 1303 xfs_ioc_getbmapx( 1304 struct xfs_inode *ip, 1305 void __user *arg) 1306 { 1307 struct getbmapx bmx; 1308 int error; 1309 1310 if (copy_from_user(&bmx, arg, sizeof(bmx))) 1311 return -XFS_ERROR(EFAULT); 1312 1313 if (bmx.bmv_count < 2) 1314 return -XFS_ERROR(EINVAL); 1315 1316 if (bmx.bmv_iflags & (~BMV_IF_VALID)) 1317 return -XFS_ERROR(EINVAL); 1318 1319 error = xfs_getbmap(ip, &bmx, xfs_getbmapx_format, 1320 (struct getbmapx *)arg+1); 1321 if (error) 1322 return -error; 1323 1324 /* copy back header */ 1325 if (copy_to_user(arg, &bmx, sizeof(struct getbmapx))) 1326 return -XFS_ERROR(EFAULT); 1327 1328 return 0; 1329 } 1330 1331 /* 1332 * Note: some of the ioctl's return positive numbers as a 1333 * byte count indicating success, such as readlink_by_handle. 1334 * So we don't "sign flip" like most other routines. This means 1335 * true errors need to be returned as a negative value. 1336 */ 1337 long 1338 xfs_file_ioctl( 1339 struct file *filp, 1340 unsigned int cmd, 1341 unsigned long p) 1342 { 1343 struct inode *inode = file_inode(filp); 1344 struct xfs_inode *ip = XFS_I(inode); 1345 struct xfs_mount *mp = ip->i_mount; 1346 void __user *arg = (void __user *)p; 1347 int ioflags = 0; 1348 int error; 1349 1350 if (filp->f_mode & FMODE_NOCMTIME) 1351 ioflags |= IO_INVIS; 1352 1353 trace_xfs_file_ioctl(ip); 1354 1355 switch (cmd) { 1356 case FITRIM: 1357 return xfs_ioc_trim(mp, arg); 1358 case XFS_IOC_ALLOCSP: 1359 case XFS_IOC_FREESP: 1360 case XFS_IOC_RESVSP: 1361 case XFS_IOC_UNRESVSP: 1362 case XFS_IOC_ALLOCSP64: 1363 case XFS_IOC_FREESP64: 1364 case XFS_IOC_RESVSP64: 1365 case XFS_IOC_UNRESVSP64: 1366 case XFS_IOC_ZERO_RANGE: { 1367 xfs_flock64_t bf; 1368 1369 if (copy_from_user(&bf, arg, sizeof(bf))) 1370 return -XFS_ERROR(EFAULT); 1371 return xfs_ioc_space(ip, inode, filp, ioflags, cmd, &bf); 1372 } 1373 case XFS_IOC_DIOINFO: { 1374 struct dioattr da; 1375 xfs_buftarg_t *target = 1376 XFS_IS_REALTIME_INODE(ip) ? 1377 mp->m_rtdev_targp : mp->m_ddev_targp; 1378 1379 da.d_mem = da.d_miniosz = 1 << target->bt_sshift; 1380 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1); 1381 1382 if (copy_to_user(arg, &da, sizeof(da))) 1383 return -XFS_ERROR(EFAULT); 1384 return 0; 1385 } 1386 1387 case XFS_IOC_FSBULKSTAT_SINGLE: 1388 case XFS_IOC_FSBULKSTAT: 1389 case XFS_IOC_FSINUMBERS: 1390 return xfs_ioc_bulkstat(mp, cmd, arg); 1391 1392 case XFS_IOC_FSGEOMETRY_V1: 1393 return xfs_ioc_fsgeometry_v1(mp, arg); 1394 1395 case XFS_IOC_FSGEOMETRY: 1396 return xfs_ioc_fsgeometry(mp, arg); 1397 1398 case XFS_IOC_GETVERSION: 1399 return put_user(inode->i_generation, (int __user *)arg); 1400 1401 case XFS_IOC_FSGETXATTR: 1402 return xfs_ioc_fsgetxattr(ip, 0, arg); 1403 case XFS_IOC_FSGETXATTRA: 1404 return xfs_ioc_fsgetxattr(ip, 1, arg); 1405 case XFS_IOC_FSSETXATTR: 1406 return xfs_ioc_fssetxattr(ip, filp, arg); 1407 case XFS_IOC_GETXFLAGS: 1408 return xfs_ioc_getxflags(ip, arg); 1409 case XFS_IOC_SETXFLAGS: 1410 return xfs_ioc_setxflags(ip, filp, arg); 1411 1412 case XFS_IOC_FSSETDM: { 1413 struct fsdmidata dmi; 1414 1415 if (copy_from_user(&dmi, arg, sizeof(dmi))) 1416 return -XFS_ERROR(EFAULT); 1417 1418 error = mnt_want_write_file(filp); 1419 if (error) 1420 return error; 1421 1422 error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask, 1423 dmi.fsd_dmstate); 1424 mnt_drop_write_file(filp); 1425 return -error; 1426 } 1427 1428 case XFS_IOC_GETBMAP: 1429 case XFS_IOC_GETBMAPA: 1430 return xfs_ioc_getbmap(ip, ioflags, cmd, arg); 1431 1432 case XFS_IOC_GETBMAPX: 1433 return xfs_ioc_getbmapx(ip, arg); 1434 1435 case XFS_IOC_FD_TO_HANDLE: 1436 case XFS_IOC_PATH_TO_HANDLE: 1437 case XFS_IOC_PATH_TO_FSHANDLE: { 1438 xfs_fsop_handlereq_t hreq; 1439 1440 if (copy_from_user(&hreq, arg, sizeof(hreq))) 1441 return -XFS_ERROR(EFAULT); 1442 return xfs_find_handle(cmd, &hreq); 1443 } 1444 case XFS_IOC_OPEN_BY_HANDLE: { 1445 xfs_fsop_handlereq_t hreq; 1446 1447 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) 1448 return -XFS_ERROR(EFAULT); 1449 return xfs_open_by_handle(filp, &hreq); 1450 } 1451 case XFS_IOC_FSSETDM_BY_HANDLE: 1452 return xfs_fssetdm_by_handle(filp, arg); 1453 1454 case XFS_IOC_READLINK_BY_HANDLE: { 1455 xfs_fsop_handlereq_t hreq; 1456 1457 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) 1458 return -XFS_ERROR(EFAULT); 1459 return xfs_readlink_by_handle(filp, &hreq); 1460 } 1461 case XFS_IOC_ATTRLIST_BY_HANDLE: 1462 return xfs_attrlist_by_handle(filp, arg); 1463 1464 case XFS_IOC_ATTRMULTI_BY_HANDLE: 1465 return xfs_attrmulti_by_handle(filp, arg); 1466 1467 case XFS_IOC_SWAPEXT: { 1468 struct xfs_swapext sxp; 1469 1470 if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t))) 1471 return -XFS_ERROR(EFAULT); 1472 error = mnt_want_write_file(filp); 1473 if (error) 1474 return error; 1475 error = xfs_swapext(&sxp); 1476 mnt_drop_write_file(filp); 1477 return -error; 1478 } 1479 1480 case XFS_IOC_FSCOUNTS: { 1481 xfs_fsop_counts_t out; 1482 1483 error = xfs_fs_counts(mp, &out); 1484 if (error) 1485 return -error; 1486 1487 if (copy_to_user(arg, &out, sizeof(out))) 1488 return -XFS_ERROR(EFAULT); 1489 return 0; 1490 } 1491 1492 case XFS_IOC_SET_RESBLKS: { 1493 xfs_fsop_resblks_t inout; 1494 __uint64_t in; 1495 1496 if (!capable(CAP_SYS_ADMIN)) 1497 return -EPERM; 1498 1499 if (mp->m_flags & XFS_MOUNT_RDONLY) 1500 return -XFS_ERROR(EROFS); 1501 1502 if (copy_from_user(&inout, arg, sizeof(inout))) 1503 return -XFS_ERROR(EFAULT); 1504 1505 error = mnt_want_write_file(filp); 1506 if (error) 1507 return error; 1508 1509 /* input parameter is passed in resblks field of structure */ 1510 in = inout.resblks; 1511 error = xfs_reserve_blocks(mp, &in, &inout); 1512 mnt_drop_write_file(filp); 1513 if (error) 1514 return -error; 1515 1516 if (copy_to_user(arg, &inout, sizeof(inout))) 1517 return -XFS_ERROR(EFAULT); 1518 return 0; 1519 } 1520 1521 case XFS_IOC_GET_RESBLKS: { 1522 xfs_fsop_resblks_t out; 1523 1524 if (!capable(CAP_SYS_ADMIN)) 1525 return -EPERM; 1526 1527 error = xfs_reserve_blocks(mp, NULL, &out); 1528 if (error) 1529 return -error; 1530 1531 if (copy_to_user(arg, &out, sizeof(out))) 1532 return -XFS_ERROR(EFAULT); 1533 1534 return 0; 1535 } 1536 1537 case XFS_IOC_FSGROWFSDATA: { 1538 xfs_growfs_data_t in; 1539 1540 if (copy_from_user(&in, arg, sizeof(in))) 1541 return -XFS_ERROR(EFAULT); 1542 1543 error = mnt_want_write_file(filp); 1544 if (error) 1545 return error; 1546 error = xfs_growfs_data(mp, &in); 1547 mnt_drop_write_file(filp); 1548 return -error; 1549 } 1550 1551 case XFS_IOC_FSGROWFSLOG: { 1552 xfs_growfs_log_t in; 1553 1554 if (copy_from_user(&in, arg, sizeof(in))) 1555 return -XFS_ERROR(EFAULT); 1556 1557 error = mnt_want_write_file(filp); 1558 if (error) 1559 return error; 1560 error = xfs_growfs_log(mp, &in); 1561 mnt_drop_write_file(filp); 1562 return -error; 1563 } 1564 1565 case XFS_IOC_FSGROWFSRT: { 1566 xfs_growfs_rt_t in; 1567 1568 if (copy_from_user(&in, arg, sizeof(in))) 1569 return -XFS_ERROR(EFAULT); 1570 1571 error = mnt_want_write_file(filp); 1572 if (error) 1573 return error; 1574 error = xfs_growfs_rt(mp, &in); 1575 mnt_drop_write_file(filp); 1576 return -error; 1577 } 1578 1579 case XFS_IOC_GOINGDOWN: { 1580 __uint32_t in; 1581 1582 if (!capable(CAP_SYS_ADMIN)) 1583 return -EPERM; 1584 1585 if (get_user(in, (__uint32_t __user *)arg)) 1586 return -XFS_ERROR(EFAULT); 1587 1588 error = xfs_fs_goingdown(mp, in); 1589 return -error; 1590 } 1591 1592 case XFS_IOC_ERROR_INJECTION: { 1593 xfs_error_injection_t in; 1594 1595 if (!capable(CAP_SYS_ADMIN)) 1596 return -EPERM; 1597 1598 if (copy_from_user(&in, arg, sizeof(in))) 1599 return -XFS_ERROR(EFAULT); 1600 1601 error = xfs_errortag_add(in.errtag, mp); 1602 return -error; 1603 } 1604 1605 case XFS_IOC_ERROR_CLEARALL: 1606 if (!capable(CAP_SYS_ADMIN)) 1607 return -EPERM; 1608 1609 error = xfs_errortag_clearall(mp, 1); 1610 return -error; 1611 1612 case XFS_IOC_FREE_EOFBLOCKS: { 1613 struct xfs_eofblocks eofb; 1614 1615 if (copy_from_user(&eofb, arg, sizeof(eofb))) 1616 return -XFS_ERROR(EFAULT); 1617 1618 if (eofb.eof_version != XFS_EOFBLOCKS_VERSION) 1619 return -XFS_ERROR(EINVAL); 1620 1621 if (eofb.eof_flags & ~XFS_EOF_FLAGS_VALID) 1622 return -XFS_ERROR(EINVAL); 1623 1624 if (memchr_inv(&eofb.pad32, 0, sizeof(eofb.pad32)) || 1625 memchr_inv(eofb.pad64, 0, sizeof(eofb.pad64))) 1626 return -XFS_ERROR(EINVAL); 1627 1628 error = xfs_icache_free_eofblocks(mp, &eofb); 1629 return -error; 1630 } 1631 1632 default: 1633 return -ENOTTY; 1634 } 1635 } 1636