Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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