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