xfs: convert quotacheck to use the new iwalk functions
[linux-block.git] / fs / xfs / xfs_ioctl.c
CommitLineData
0b61f8a4 1// SPDX-License-Identifier: GPL-2.0
1da177e4 2/*
7b718769
NS
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
1da177e4 5 */
1da177e4 6#include "xfs.h"
1da177e4 7#include "xfs_fs.h"
70a9883c 8#include "xfs_shared.h"
239880ef
DC
9#include "xfs_format.h"
10#include "xfs_log_format.h"
11#include "xfs_trans_resv.h"
1da177e4 12#include "xfs_mount.h"
1da177e4 13#include "xfs_inode.h"
1da177e4 14#include "xfs_rtalloc.h"
1da177e4 15#include "xfs_itable.h"
a844f451 16#include "xfs_error.h"
1da177e4 17#include "xfs_attr.h"
a844f451 18#include "xfs_bmap.h"
68988114 19#include "xfs_bmap_util.h"
1da177e4 20#include "xfs_fsops.h"
a46db608 21#include "xfs_discard.h"
25fe55e8 22#include "xfs_quota.h"
d296d30a 23#include "xfs_export.h"
0b1b213f 24#include "xfs_trace.h"
8ca149de 25#include "xfs_icache.h"
a4fbe6ab 26#include "xfs_trans.h"
47e1bf64 27#include "xfs_acl.h"
e89c0413
DW
28#include "xfs_btree.h"
29#include <linux/fsmap.h>
30#include "xfs_fsmap.h"
36fd6e86 31#include "scrub/xfs_scrub.h"
c368ebcd 32#include "xfs_sb.h"
7cd5006b 33#include "xfs_ag.h"
c23232d4 34#include "xfs_health.h"
1da177e4 35
1da177e4
LT
36#include <linux/mount.h>
37#include <linux/namei.h>
1da177e4
LT
38
39/*
40 * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
41 * a file or fs handle.
42 *
43 * XFS_IOC_PATH_TO_FSHANDLE
44 * returns fs handle for a mount point or path within that mount point
45 * XFS_IOC_FD_TO_HANDLE
46 * returns full handle for a FD opened in user space
47 * XFS_IOC_PATH_TO_HANDLE
48 * returns full handle for a path
49 */
d5547f9f 50int
1da177e4
LT
51xfs_find_handle(
52 unsigned int cmd,
743bb465 53 xfs_fsop_handlereq_t *hreq)
1da177e4
LT
54{
55 int hsize;
56 xfs_handle_t handle;
1da177e4 57 struct inode *inode;
a30b0367 58 struct fd f = {NULL};
4346cdd4 59 struct path path;
2903ff01 60 int error;
4346cdd4 61 struct xfs_inode *ip;
1da177e4 62
4346cdd4 63 if (cmd == XFS_IOC_FD_TO_HANDLE) {
2903ff01
AV
64 f = fdget(hreq->fd);
65 if (!f.file)
4346cdd4 66 return -EBADF;
496ad9aa 67 inode = file_inode(f.file);
4346cdd4
CH
68 } else {
69 error = user_lpath((const char __user *)hreq->path, &path);
70 if (error)
71 return error;
2b0143b5 72 inode = d_inode(path.dentry);
1da177e4 73 }
4346cdd4
CH
74 ip = XFS_I(inode);
75
76 /*
77 * We can only generate handles for inodes residing on a XFS filesystem,
78 * and only for regular files, directories or symbolic links.
79 */
80 error = -EINVAL;
81 if (inode->i_sb->s_magic != XFS_SB_MAGIC)
82 goto out_put;
83
84 error = -EBADF;
85 if (!S_ISREG(inode->i_mode) &&
86 !S_ISDIR(inode->i_mode) &&
87 !S_ISLNK(inode->i_mode))
88 goto out_put;
89
90
91 memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
92
93 if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
94 /*
95 * This handle only contains an fsid, zero the rest.
96 */
97 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
98 hsize = sizeof(xfs_fsid_t);
99 } else {
c6143911
CH
100 handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
101 sizeof(handle.ha_fid.fid_len);
102 handle.ha_fid.fid_pad = 0;
9e9a2674 103 handle.ha_fid.fid_gen = inode->i_generation;
c6143911 104 handle.ha_fid.fid_ino = ip->i_ino;
3398a400 105 hsize = sizeof(xfs_handle_t);
1da177e4
LT
106 }
107
4346cdd4 108 error = -EFAULT;
743bb465 109 if (copy_to_user(hreq->ohandle, &handle, hsize) ||
4346cdd4
CH
110 copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
111 goto out_put;
1da177e4 112
4346cdd4
CH
113 error = 0;
114
115 out_put:
116 if (cmd == XFS_IOC_FD_TO_HANDLE)
2903ff01 117 fdput(f);
4346cdd4
CH
118 else
119 path_put(&path);
120 return error;
1da177e4
LT
121}
122
1da177e4 123/*
d296d30a
CH
124 * No need to do permission checks on the various pathname components
125 * as the handle operations are privileged.
1da177e4
LT
126 */
127STATIC int
d296d30a
CH
128xfs_handle_acceptable(
129 void *context,
130 struct dentry *dentry)
131{
132 return 1;
133}
134
135/*
136 * Convert userspace handle data into a dentry.
137 */
138struct dentry *
139xfs_handle_to_dentry(
140 struct file *parfilp,
141 void __user *uhandle,
142 u32 hlen)
1da177e4 143{
1da177e4 144 xfs_handle_t handle;
d296d30a 145 struct xfs_fid64 fid;
1da177e4
LT
146
147 /*
148 * Only allow handle opens under a directory.
149 */
496ad9aa 150 if (!S_ISDIR(file_inode(parfilp)->i_mode))
d296d30a
CH
151 return ERR_PTR(-ENOTDIR);
152
153 if (hlen != sizeof(xfs_handle_t))
154 return ERR_PTR(-EINVAL);
155 if (copy_from_user(&handle, uhandle, hlen))
156 return ERR_PTR(-EFAULT);
157 if (handle.ha_fid.fid_len !=
158 sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len))
159 return ERR_PTR(-EINVAL);
160
161 memset(&fid, 0, sizeof(struct fid));
162 fid.ino = handle.ha_fid.fid_ino;
163 fid.gen = handle.ha_fid.fid_gen;
164
165 return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3,
166 FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
167 xfs_handle_acceptable, NULL);
168}
1da177e4 169
d296d30a
CH
170STATIC struct dentry *
171xfs_handlereq_to_dentry(
172 struct file *parfilp,
173 xfs_fsop_handlereq_t *hreq)
174{
175 return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
1da177e4
LT
176}
177
d5547f9f 178int
1da177e4 179xfs_open_by_handle(
1da177e4 180 struct file *parfilp,
d296d30a 181 xfs_fsop_handlereq_t *hreq)
1da177e4 182{
745ca247 183 const struct cred *cred = current_cred();
1da177e4 184 int error;
d296d30a 185 int fd;
1da177e4
LT
186 int permflag;
187 struct file *filp;
188 struct inode *inode;
189 struct dentry *dentry;
1a1d7724 190 fmode_t fmode;
765927b2 191 struct path path;
1da177e4
LT
192
193 if (!capable(CAP_SYS_ADMIN))
b474c7ae 194 return -EPERM;
1da177e4 195
d296d30a
CH
196 dentry = xfs_handlereq_to_dentry(parfilp, hreq);
197 if (IS_ERR(dentry))
198 return PTR_ERR(dentry);
2b0143b5 199 inode = d_inode(dentry);
1da177e4
LT
200
201 /* Restrict xfs_open_by_handle to directories & regular files. */
202 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
b474c7ae 203 error = -EPERM;
d296d30a 204 goto out_dput;
1da177e4
LT
205 }
206
207#if BITS_PER_LONG != 32
743bb465 208 hreq->oflags |= O_LARGEFILE;
1da177e4 209#endif
d296d30a 210
743bb465 211 permflag = hreq->oflags;
1a1d7724 212 fmode = OPEN_FMODE(permflag);
1da177e4 213 if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
1a1d7724 214 (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
b474c7ae 215 error = -EPERM;
d296d30a 216 goto out_dput;
1da177e4
LT
217 }
218
1a1d7724 219 if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
337684a1 220 error = -EPERM;
d296d30a 221 goto out_dput;
1da177e4
LT
222 }
223
224 /* Can't write directories. */
1a1d7724 225 if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
b474c7ae 226 error = -EISDIR;
d296d30a 227 goto out_dput;
1da177e4
LT
228 }
229
862a6293 230 fd = get_unused_fd_flags(0);
d296d30a
CH
231 if (fd < 0) {
232 error = fd;
233 goto out_dput;
1da177e4
LT
234 }
235
765927b2
AV
236 path.mnt = parfilp->f_path.mnt;
237 path.dentry = dentry;
238 filp = dentry_open(&path, hreq->oflags, cred);
239 dput(dentry);
1da177e4 240 if (IS_ERR(filp)) {
d296d30a
CH
241 put_unused_fd(fd);
242 return PTR_ERR(filp);
1da177e4 243 }
4d4be482 244
03209378 245 if (S_ISREG(inode->i_mode)) {
2e2e7bb1 246 filp->f_flags |= O_NOATIME;
4d4be482 247 filp->f_mode |= FMODE_NOCMTIME;
2e2e7bb1 248 }
1da177e4 249
d296d30a
CH
250 fd_install(fd, filp);
251 return fd;
252
253 out_dput:
254 dput(dentry);
255 return error;
1da177e4
LT
256}
257
d5547f9f 258int
1da177e4 259xfs_readlink_by_handle(
d296d30a
CH
260 struct file *parfilp,
261 xfs_fsop_handlereq_t *hreq)
1da177e4 262{
d296d30a 263 struct dentry *dentry;
1da177e4 264 __u32 olen;
804c83c3 265 int error;
1da177e4
LT
266
267 if (!capable(CAP_SYS_ADMIN))
b474c7ae 268 return -EPERM;
1da177e4 269
d296d30a
CH
270 dentry = xfs_handlereq_to_dentry(parfilp, hreq);
271 if (IS_ERR(dentry))
272 return PTR_ERR(dentry);
1da177e4
LT
273
274 /* Restrict this handle operation to symlinks only. */
fd4a0edf 275 if (!d_is_symlink(dentry)) {
b474c7ae 276 error = -EINVAL;
d296d30a 277 goto out_dput;
1da177e4
LT
278 }
279
743bb465 280 if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
b474c7ae 281 error = -EFAULT;
d296d30a 282 goto out_dput;
1da177e4 283 }
1da177e4 284
fd4a0edf 285 error = vfs_readlink(dentry, hreq->ohandle, olen);
67fcaa73 286
d296d30a
CH
287 out_dput:
288 dput(dentry);
804c83c3 289 return error;
1da177e4
LT
290}
291
c24b5dfa
DC
292int
293xfs_set_dmattrs(
294 xfs_inode_t *ip,
65a7935d
DW
295 uint evmask,
296 uint16_t state)
c24b5dfa
DC
297{
298 xfs_mount_t *mp = ip->i_mount;
299 xfs_trans_t *tp;
300 int error;
301
302 if (!capable(CAP_SYS_ADMIN))
2451337d 303 return -EPERM;
c24b5dfa
DC
304
305 if (XFS_FORCED_SHUTDOWN(mp))
2451337d 306 return -EIO;
c24b5dfa 307
253f4911
CH
308 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
309 if (error)
c24b5dfa 310 return error;
253f4911 311
c24b5dfa
DC
312 xfs_ilock(ip, XFS_ILOCK_EXCL);
313 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
314
315 ip->i_d.di_dmevmask = evmask;
316 ip->i_d.di_dmstate = state;
317
318 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
70393313 319 error = xfs_trans_commit(tp);
c24b5dfa
DC
320
321 return error;
322}
323
1da177e4
LT
324STATIC int
325xfs_fssetdm_by_handle(
d296d30a
CH
326 struct file *parfilp,
327 void __user *arg)
1da177e4
LT
328{
329 int error;
330 struct fsdmidata fsd;
331 xfs_fsop_setdm_handlereq_t dmhreq;
d296d30a 332 struct dentry *dentry;
1da177e4
LT
333
334 if (!capable(CAP_MKNOD))
b474c7ae 335 return -EPERM;
1da177e4 336 if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t)))
b474c7ae 337 return -EFAULT;
1da177e4 338
d9457dc0
JK
339 error = mnt_want_write_file(parfilp);
340 if (error)
341 return error;
342
d296d30a 343 dentry = xfs_handlereq_to_dentry(parfilp, &dmhreq.hreq);
d9457dc0
JK
344 if (IS_ERR(dentry)) {
345 mnt_drop_write_file(parfilp);
d296d30a 346 return PTR_ERR(dentry);
d9457dc0 347 }
1da177e4 348
2b0143b5 349 if (IS_IMMUTABLE(d_inode(dentry)) || IS_APPEND(d_inode(dentry))) {
b474c7ae 350 error = -EPERM;
6e7f75ea 351 goto out;
1da177e4
LT
352 }
353
354 if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) {
b474c7ae 355 error = -EFAULT;
6e7f75ea 356 goto out;
1da177e4
LT
357 }
358
2b0143b5 359 error = xfs_set_dmattrs(XFS_I(d_inode(dentry)), fsd.fsd_dmevmask,
6e7f75ea 360 fsd.fsd_dmstate);
1da177e4 361
6e7f75ea 362 out:
d9457dc0 363 mnt_drop_write_file(parfilp);
d296d30a 364 dput(dentry);
6e7f75ea 365 return error;
1da177e4
LT
366}
367
368STATIC int
369xfs_attrlist_by_handle(
d296d30a
CH
370 struct file *parfilp,
371 void __user *arg)
1da177e4 372{
d296d30a 373 int error = -ENOMEM;
1da177e4 374 attrlist_cursor_kern_t *cursor;
0facef7f 375 struct xfs_fsop_attrlist_handlereq __user *p = arg;
1da177e4 376 xfs_fsop_attrlist_handlereq_t al_hreq;
d296d30a 377 struct dentry *dentry;
1da177e4
LT
378 char *kbuf;
379
380 if (!capable(CAP_SYS_ADMIN))
b474c7ae 381 return -EPERM;
1da177e4 382 if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
b474c7ae 383 return -EFAULT;
071c529e 384 if (al_hreq.buflen < sizeof(struct attrlist) ||
4e247614 385 al_hreq.buflen > XFS_XATTR_LIST_MAX)
b474c7ae 386 return -EINVAL;
1da177e4 387
90ad58a8
CH
388 /*
389 * Reject flags, only allow namespaces.
390 */
391 if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
b474c7ae 392 return -EINVAL;
90ad58a8 393
d296d30a
CH
394 dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
395 if (IS_ERR(dentry))
396 return PTR_ERR(dentry);
1da177e4 397
fdd3ccee
DC
398 kbuf = kmem_zalloc_large(al_hreq.buflen, KM_SLEEP);
399 if (!kbuf)
400 goto out_dput;
1da177e4
LT
401
402 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
2b0143b5 403 error = xfs_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
739bfb2a 404 al_hreq.flags, cursor);
1da177e4
LT
405 if (error)
406 goto out_kfree;
407
0facef7f
DW
408 if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t))) {
409 error = -EFAULT;
410 goto out_kfree;
411 }
412
1da177e4
LT
413 if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
414 error = -EFAULT;
415
fdd3ccee
DC
416out_kfree:
417 kmem_free(kbuf);
418out_dput:
d296d30a
CH
419 dput(dentry);
420 return error;
1da177e4
LT
421}
422
28750975 423int
1da177e4 424xfs_attrmulti_attr_get(
739bfb2a 425 struct inode *inode,
a9273ca5
DC
426 unsigned char *name,
427 unsigned char __user *ubuf,
c8ce540d
DW
428 uint32_t *len,
429 uint32_t flags)
1da177e4 430{
a9273ca5 431 unsigned char *kbuf;
2451337d 432 int error = -EFAULT;
e8b0ebaa 433
51fcbfe7 434 if (*len > XFS_XATTR_SIZE_MAX)
2451337d 435 return -EINVAL;
fdd3ccee
DC
436 kbuf = kmem_zalloc_large(*len, KM_SLEEP);
437 if (!kbuf)
2451337d 438 return -ENOMEM;
1da177e4 439
e8b0ebaa 440 error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags);
1da177e4
LT
441 if (error)
442 goto out_kfree;
443
444 if (copy_to_user(ubuf, kbuf, *len))
2451337d 445 error = -EFAULT;
1da177e4 446
fdd3ccee
DC
447out_kfree:
448 kmem_free(kbuf);
1da177e4
LT
449 return error;
450}
451
28750975 452int
1da177e4 453xfs_attrmulti_attr_set(
739bfb2a 454 struct inode *inode,
a9273ca5
DC
455 unsigned char *name,
456 const unsigned char __user *ubuf,
c8ce540d
DW
457 uint32_t len,
458 uint32_t flags)
1da177e4 459{
a9273ca5 460 unsigned char *kbuf;
09cb22d2 461 int error;
1da177e4 462
739bfb2a 463 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
2451337d 464 return -EPERM;
51fcbfe7 465 if (len > XFS_XATTR_SIZE_MAX)
2451337d 466 return -EINVAL;
1da177e4 467
0e639bde
LZ
468 kbuf = memdup_user(ubuf, len);
469 if (IS_ERR(kbuf))
470 return PTR_ERR(kbuf);
e8b0ebaa 471
09cb22d2 472 error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
47e1bf64
AG
473 if (!error)
474 xfs_forget_acl(inode, name, flags);
09cb22d2
AG
475 kfree(kbuf);
476 return error;
1da177e4
LT
477}
478
28750975 479int
1da177e4 480xfs_attrmulti_attr_remove(
739bfb2a 481 struct inode *inode,
a9273ca5 482 unsigned char *name,
c8ce540d 483 uint32_t flags)
1da177e4 484{
47e1bf64
AG
485 int error;
486
739bfb2a 487 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
2451337d 488 return -EPERM;
47e1bf64
AG
489 error = xfs_attr_remove(XFS_I(inode), name, flags);
490 if (!error)
491 xfs_forget_acl(inode, name, flags);
492 return error;
1da177e4
LT
493}
494
495STATIC int
496xfs_attrmulti_by_handle(
42a74f20 497 struct file *parfilp,
d296d30a 498 void __user *arg)
1da177e4
LT
499{
500 int error;
501 xfs_attr_multiop_t *ops;
502 xfs_fsop_attrmulti_handlereq_t am_hreq;
d296d30a 503 struct dentry *dentry;
1da177e4 504 unsigned int i, size;
a9273ca5 505 unsigned char *attr_name;
1da177e4
LT
506
507 if (!capable(CAP_SYS_ADMIN))
b474c7ae 508 return -EPERM;
1da177e4 509 if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
b474c7ae 510 return -EFAULT;
1da177e4 511
fda168c2
ZW
512 /* overflow check */
513 if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t))
514 return -E2BIG;
515
d296d30a
CH
516 dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
517 if (IS_ERR(dentry))
518 return PTR_ERR(dentry);
1da177e4 519
2451337d 520 error = -E2BIG;
e182f57a 521 size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
1da177e4 522 if (!size || size > 16 * PAGE_SIZE)
d296d30a 523 goto out_dput;
1da177e4 524
0e639bde
LZ
525 ops = memdup_user(am_hreq.ops, size);
526 if (IS_ERR(ops)) {
2451337d 527 error = PTR_ERR(ops);
d296d30a 528 goto out_dput;
0e639bde 529 }
1da177e4 530
2451337d 531 error = -ENOMEM;
1da177e4
LT
532 attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
533 if (!attr_name)
534 goto out_kfree_ops;
535
1da177e4
LT
536 error = 0;
537 for (i = 0; i < am_hreq.opcount; i++) {
a9273ca5 538 ops[i].am_error = strncpy_from_user((char *)attr_name,
1da177e4
LT
539 ops[i].am_attrname, MAXNAMELEN);
540 if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
2451337d 541 error = -ERANGE;
1da177e4
LT
542 if (ops[i].am_error < 0)
543 break;
544
545 switch (ops[i].am_opcode) {
546 case ATTR_OP_GET:
d296d30a 547 ops[i].am_error = xfs_attrmulti_attr_get(
2b0143b5 548 d_inode(dentry), attr_name,
d296d30a
CH
549 ops[i].am_attrvalue, &ops[i].am_length,
550 ops[i].am_flags);
1da177e4
LT
551 break;
552 case ATTR_OP_SET:
a561be71 553 ops[i].am_error = mnt_want_write_file(parfilp);
42a74f20
DH
554 if (ops[i].am_error)
555 break;
d296d30a 556 ops[i].am_error = xfs_attrmulti_attr_set(
2b0143b5 557 d_inode(dentry), attr_name,
d296d30a
CH
558 ops[i].am_attrvalue, ops[i].am_length,
559 ops[i].am_flags);
2a79f17e 560 mnt_drop_write_file(parfilp);
1da177e4
LT
561 break;
562 case ATTR_OP_REMOVE:
a561be71 563 ops[i].am_error = mnt_want_write_file(parfilp);
42a74f20
DH
564 if (ops[i].am_error)
565 break;
d296d30a 566 ops[i].am_error = xfs_attrmulti_attr_remove(
2b0143b5 567 d_inode(dentry), attr_name,
d296d30a 568 ops[i].am_flags);
2a79f17e 569 mnt_drop_write_file(parfilp);
1da177e4
LT
570 break;
571 default:
2451337d 572 ops[i].am_error = -EINVAL;
1da177e4
LT
573 }
574 }
575
576 if (copy_to_user(am_hreq.ops, ops, size))
2451337d 577 error = -EFAULT;
1da177e4
LT
578
579 kfree(attr_name);
580 out_kfree_ops:
581 kfree(ops);
d296d30a
CH
582 out_dput:
583 dput(dentry);
2451337d 584 return error;
1da177e4
LT
585}
586
d5547f9f 587int
1da177e4 588xfs_ioc_space(
1da177e4 589 struct file *filp,
1da177e4 590 unsigned int cmd,
743bb465 591 xfs_flock64_t *bf)
1da177e4 592{
8f3e2058
CH
593 struct inode *inode = file_inode(filp);
594 struct xfs_inode *ip = XFS_I(inode);
865e9446 595 struct iattr iattr;
8add71ca 596 enum xfs_prealloc_flags flags = 0;
c63a8eae 597 uint iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
1da177e4
LT
598 int error;
599
f37ea149 600 if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
b474c7ae 601 return -EPERM;
1da177e4 602
ad4a8ac4 603 if (!(filp->f_mode & FMODE_WRITE))
b474c7ae 604 return -EBADF;
1da177e4 605
f37ea149 606 if (!S_ISREG(inode->i_mode))
b474c7ae 607 return -EINVAL;
1da177e4 608
8add71ca
CH
609 if (filp->f_flags & O_DSYNC)
610 flags |= XFS_PREALLOC_SYNC;
8f3e2058 611 if (filp->f_mode & FMODE_NOCMTIME)
8add71ca
CH
612 flags |= XFS_PREALLOC_INVISIBLE;
613
d9457dc0
JK
614 error = mnt_want_write_file(filp);
615 if (error)
616 return error;
865e9446 617
781355c6 618 xfs_ilock(ip, iolock);
69eb5fa1 619 error = xfs_break_layouts(inode, &iolock, BREAK_UNMAP);
781355c6
CH
620 if (error)
621 goto out_unlock;
865e9446
CH
622
623 switch (bf->l_whence) {
624 case 0: /*SEEK_SET*/
625 break;
626 case 1: /*SEEK_CUR*/
627 bf->l_start += filp->f_pos;
628 break;
629 case 2: /*SEEK_END*/
630 bf->l_start += XFS_ISIZE(ip);
631 break;
632 default:
2451337d 633 error = -EINVAL;
865e9446
CH
634 goto out_unlock;
635 }
636
637 /*
638 * length of <= 0 for resv/unresv/zero is invalid. length for
639 * alloc/free is ignored completely and we have no idea what userspace
640 * might have set it to, so set it to zero to allow range
641 * checks to pass.
642 */
643 switch (cmd) {
644 case XFS_IOC_ZERO_RANGE:
645 case XFS_IOC_RESVSP:
646 case XFS_IOC_RESVSP64:
647 case XFS_IOC_UNRESVSP:
648 case XFS_IOC_UNRESVSP64:
649 if (bf->l_len <= 0) {
2451337d 650 error = -EINVAL;
865e9446
CH
651 goto out_unlock;
652 }
653 break;
654 default:
655 bf->l_len = 0;
656 break;
657 }
658
659 if (bf->l_start < 0 ||
8add71ca 660 bf->l_start > inode->i_sb->s_maxbytes ||
865e9446 661 bf->l_start + bf->l_len < 0 ||
8add71ca 662 bf->l_start + bf->l_len >= inode->i_sb->s_maxbytes) {
2451337d 663 error = -EINVAL;
865e9446
CH
664 goto out_unlock;
665 }
666
667 switch (cmd) {
668 case XFS_IOC_ZERO_RANGE:
8add71ca 669 flags |= XFS_PREALLOC_SET;
865e9446 670 error = xfs_zero_file_space(ip, bf->l_start, bf->l_len);
865e9446
CH
671 break;
672 case XFS_IOC_RESVSP:
673 case XFS_IOC_RESVSP64:
8add71ca 674 flags |= XFS_PREALLOC_SET;
865e9446
CH
675 error = xfs_alloc_file_space(ip, bf->l_start, bf->l_len,
676 XFS_BMAPI_PREALLOC);
865e9446
CH
677 break;
678 case XFS_IOC_UNRESVSP:
679 case XFS_IOC_UNRESVSP64:
680 error = xfs_free_file_space(ip, bf->l_start, bf->l_len);
681 break;
682 case XFS_IOC_ALLOCSP:
683 case XFS_IOC_ALLOCSP64:
684 case XFS_IOC_FREESP:
685 case XFS_IOC_FREESP64:
8add71ca 686 flags |= XFS_PREALLOC_CLEAR;
865e9446
CH
687 if (bf->l_start > XFS_ISIZE(ip)) {
688 error = xfs_alloc_file_space(ip, XFS_ISIZE(ip),
689 bf->l_start - XFS_ISIZE(ip), 0);
690 if (error)
691 goto out_unlock;
692 }
693
694 iattr.ia_valid = ATTR_SIZE;
695 iattr.ia_size = bf->l_start;
696
69bca807 697 error = xfs_vn_setattr_size(file_dentry(filp), &iattr);
865e9446
CH
698 break;
699 default:
700 ASSERT(0);
2451337d 701 error = -EINVAL;
865e9446
CH
702 }
703
704 if (error)
705 goto out_unlock;
706
8add71ca 707 error = xfs_update_prealloc_flags(ip, flags);
865e9446
CH
708
709out_unlock:
781355c6 710 xfs_iunlock(ip, iolock);
d9457dc0 711 mnt_drop_write_file(filp);
2451337d 712 return error;
1da177e4
LT
713}
714
715STATIC int
716xfs_ioc_bulkstat(
717 xfs_mount_t *mp,
718 unsigned int cmd,
719 void __user *arg)
720{
721 xfs_fsop_bulkreq_t bulkreq;
722 int count; /* # of records returned */
723 xfs_ino_t inlast; /* last inode number */
724 int done;
725 int error;
726
727 /* done = 1 if there are more stats to get and if bulkstat */
728 /* should be called again (unused here, but used in dmapi) */
729
730 if (!capable(CAP_SYS_ADMIN))
731 return -EPERM;
732
733 if (XFS_FORCED_SHUTDOWN(mp))
b474c7ae 734 return -EIO;
1da177e4
LT
735
736 if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t)))
b474c7ae 737 return -EFAULT;
1da177e4
LT
738
739 if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64)))
b474c7ae 740 return -EFAULT;
1da177e4
LT
741
742 if ((count = bulkreq.icount) <= 0)
b474c7ae 743 return -EINVAL;
1da177e4 744
cd57e594 745 if (bulkreq.ubuffer == NULL)
b474c7ae 746 return -EINVAL;
cd57e594 747
1da177e4
LT
748 if (cmd == XFS_IOC_FSINUMBERS)
749 error = xfs_inumbers(mp, &inlast, &count,
faa63e95 750 bulkreq.ubuffer, xfs_inumbers_fmt);
1da177e4 751 else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE)
d716f8ee
CH
752 error = xfs_bulkstat_one(mp, inlast, bulkreq.ubuffer,
753 sizeof(xfs_bstat_t), NULL, &done);
cd57e594 754 else /* XFS_IOC_FSBULKSTAT */
7dce11db
CH
755 error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one,
756 sizeof(xfs_bstat_t), bulkreq.ubuffer,
757 &done);
1da177e4
LT
758
759 if (error)
2451337d 760 return error;
1da177e4
LT
761
762 if (bulkreq.ocount != NULL) {
763 if (copy_to_user(bulkreq.lastip, &inlast,
764 sizeof(xfs_ino_t)))
b474c7ae 765 return -EFAULT;
1da177e4
LT
766
767 if (copy_to_user(bulkreq.ocount, &count, sizeof(count)))
b474c7ae 768 return -EFAULT;
1da177e4
LT
769 }
770
771 return 0;
772}
773
1da177e4
LT
774STATIC int
775xfs_ioc_fsgeometry(
1b6d968d
DC
776 struct xfs_mount *mp,
777 void __user *arg,
778 int struct_version)
1da177e4 779{
1b6d968d
DC
780 struct xfs_fsop_geom fsgeo;
781 size_t len;
1da177e4 782
91083269 783 xfs_fs_geometry(&mp->m_sb, &fsgeo, struct_version);
1da177e4 784
1b6d968d
DC
785 if (struct_version <= 3)
786 len = sizeof(struct xfs_fsop_geom_v1);
787 else if (struct_version == 4)
788 len = sizeof(struct xfs_fsop_geom_v4);
c23232d4
DW
789 else {
790 xfs_fsop_geom_health(mp, &fsgeo);
1b6d968d 791 len = sizeof(fsgeo);
c23232d4 792 }
1b6d968d
DC
793
794 if (copy_to_user(arg, &fsgeo, len))
b474c7ae 795 return -EFAULT;
1da177e4
LT
796 return 0;
797}
798
7cd5006b
DW
799STATIC int
800xfs_ioc_ag_geometry(
801 struct xfs_mount *mp,
802 void __user *arg)
803{
804 struct xfs_ag_geometry ageo;
805 int error;
806
807 if (copy_from_user(&ageo, arg, sizeof(ageo)))
808 return -EFAULT;
809
810 error = xfs_ag_get_geometry(mp, ageo.ag_number, &ageo);
811 if (error)
812 return error;
813
814 if (copy_to_user(arg, &ageo, sizeof(ageo)))
815 return -EFAULT;
816 return 0;
817}
818
1da177e4
LT
819/*
820 * Linux extended inode flags interface.
821 */
1da177e4
LT
822
823STATIC unsigned int
824xfs_merge_ioc_xflags(
825 unsigned int flags,
826 unsigned int start)
827{
828 unsigned int xflags = start;
829
39058a0e 830 if (flags & FS_IMMUTABLE_FL)
e7b89481 831 xflags |= FS_XFLAG_IMMUTABLE;
1da177e4 832 else
e7b89481 833 xflags &= ~FS_XFLAG_IMMUTABLE;
39058a0e 834 if (flags & FS_APPEND_FL)
e7b89481 835 xflags |= FS_XFLAG_APPEND;
1da177e4 836 else
e7b89481 837 xflags &= ~FS_XFLAG_APPEND;
39058a0e 838 if (flags & FS_SYNC_FL)
e7b89481 839 xflags |= FS_XFLAG_SYNC;
1da177e4 840 else
e7b89481 841 xflags &= ~FS_XFLAG_SYNC;
39058a0e 842 if (flags & FS_NOATIME_FL)
e7b89481 843 xflags |= FS_XFLAG_NOATIME;
1da177e4 844 else
e7b89481 845 xflags &= ~FS_XFLAG_NOATIME;
39058a0e 846 if (flags & FS_NODUMP_FL)
e7b89481 847 xflags |= FS_XFLAG_NODUMP;
1da177e4 848 else
e7b89481 849 xflags &= ~FS_XFLAG_NODUMP;
1da177e4
LT
850
851 return xflags;
852}
853
854STATIC unsigned int
855xfs_di2lxflags(
c8ce540d 856 uint16_t di_flags)
1da177e4
LT
857{
858 unsigned int flags = 0;
859
860 if (di_flags & XFS_DIFLAG_IMMUTABLE)
39058a0e 861 flags |= FS_IMMUTABLE_FL;
1da177e4 862 if (di_flags & XFS_DIFLAG_APPEND)
39058a0e 863 flags |= FS_APPEND_FL;
1da177e4 864 if (di_flags & XFS_DIFLAG_SYNC)
39058a0e 865 flags |= FS_SYNC_FL;
1da177e4 866 if (di_flags & XFS_DIFLAG_NOATIME)
39058a0e 867 flags |= FS_NOATIME_FL;
1da177e4 868 if (di_flags & XFS_DIFLAG_NODUMP)
39058a0e 869 flags |= FS_NODUMP_FL;
1da177e4
LT
870 return flags;
871}
872
c83bfab1
CH
873STATIC int
874xfs_ioc_fsgetxattr(
875 xfs_inode_t *ip,
876 int attr,
877 void __user *arg)
878{
879 struct fsxattr fa;
880
a122eb2f
DR
881 memset(&fa, 0, sizeof(struct fsxattr));
882
c83bfab1
CH
883 xfs_ilock(ip, XFS_ILOCK_SHARED);
884 fa.fsx_xflags = xfs_ip2xflags(ip);
885 fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
f7ca3522
DW
886 fa.fsx_cowextsize = ip->i_d.di_cowextsize <<
887 ip->i_mount->m_sb.sb_blocklog;
6743099c 888 fa.fsx_projid = xfs_get_projid(ip);
c83bfab1
CH
889
890 if (attr) {
891 if (ip->i_afp) {
892 if (ip->i_afp->if_flags & XFS_IFEXTENTS)
5d829300 893 fa.fsx_nextents = xfs_iext_count(ip->i_afp);
c83bfab1
CH
894 else
895 fa.fsx_nextents = ip->i_d.di_anextents;
896 } else
897 fa.fsx_nextents = 0;
898 } else {
899 if (ip->i_df.if_flags & XFS_IFEXTENTS)
5d829300 900 fa.fsx_nextents = xfs_iext_count(&ip->i_df);
c83bfab1
CH
901 else
902 fa.fsx_nextents = ip->i_d.di_nextents;
903 }
904 xfs_iunlock(ip, XFS_ILOCK_SHARED);
905
906 if (copy_to_user(arg, &fa, sizeof(fa)))
907 return -EFAULT;
908 return 0;
909}
910
dd60687e
CH
911STATIC uint16_t
912xfs_flags2diflags(
25fe55e8
CH
913 struct xfs_inode *ip,
914 unsigned int xflags)
915{
25fe55e8 916 /* can't set PREALLOC this way, just preserve it */
dd60687e
CH
917 uint16_t di_flags =
918 (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
919
e7b89481 920 if (xflags & FS_XFLAG_IMMUTABLE)
25fe55e8 921 di_flags |= XFS_DIFLAG_IMMUTABLE;
e7b89481 922 if (xflags & FS_XFLAG_APPEND)
25fe55e8 923 di_flags |= XFS_DIFLAG_APPEND;
e7b89481 924 if (xflags & FS_XFLAG_SYNC)
25fe55e8 925 di_flags |= XFS_DIFLAG_SYNC;
e7b89481 926 if (xflags & FS_XFLAG_NOATIME)
25fe55e8 927 di_flags |= XFS_DIFLAG_NOATIME;
e7b89481 928 if (xflags & FS_XFLAG_NODUMP)
25fe55e8 929 di_flags |= XFS_DIFLAG_NODUMP;
e7b89481 930 if (xflags & FS_XFLAG_NODEFRAG)
25fe55e8 931 di_flags |= XFS_DIFLAG_NODEFRAG;
e7b89481 932 if (xflags & FS_XFLAG_FILESTREAM)
25fe55e8 933 di_flags |= XFS_DIFLAG_FILESTREAM;
c19b3b05 934 if (S_ISDIR(VFS_I(ip)->i_mode)) {
e7b89481 935 if (xflags & FS_XFLAG_RTINHERIT)
25fe55e8 936 di_flags |= XFS_DIFLAG_RTINHERIT;
e7b89481 937 if (xflags & FS_XFLAG_NOSYMLINKS)
25fe55e8 938 di_flags |= XFS_DIFLAG_NOSYMLINKS;
e7b89481 939 if (xflags & FS_XFLAG_EXTSZINHERIT)
25fe55e8 940 di_flags |= XFS_DIFLAG_EXTSZINHERIT;
e7b89481 941 if (xflags & FS_XFLAG_PROJINHERIT)
9336e3a7 942 di_flags |= XFS_DIFLAG_PROJINHERIT;
c19b3b05 943 } else if (S_ISREG(VFS_I(ip)->i_mode)) {
e7b89481 944 if (xflags & FS_XFLAG_REALTIME)
25fe55e8 945 di_flags |= XFS_DIFLAG_REALTIME;
e7b89481 946 if (xflags & FS_XFLAG_EXTSIZE)
25fe55e8
CH
947 di_flags |= XFS_DIFLAG_EXTSIZE;
948 }
58f88ca2 949
dd60687e
CH
950 return di_flags;
951}
952
953STATIC uint64_t
954xfs_flags2diflags2(
955 struct xfs_inode *ip,
956 unsigned int xflags)
957{
958 uint64_t di_flags2 =
959 (ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK);
58f88ca2 960
58f88ca2
DC
961 if (xflags & FS_XFLAG_DAX)
962 di_flags2 |= XFS_DIFLAG2_DAX;
f7ca3522
DW
963 if (xflags & FS_XFLAG_COWEXTSIZE)
964 di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
58f88ca2 965
dd60687e 966 return di_flags2;
25fe55e8
CH
967}
968
f13fae2d
CH
969STATIC void
970xfs_diflags_to_linux(
971 struct xfs_inode *ip)
972{
e4f75291 973 struct inode *inode = VFS_I(ip);
f13fae2d
CH
974 unsigned int xflags = xfs_ip2xflags(ip);
975
e7b89481 976 if (xflags & FS_XFLAG_IMMUTABLE)
f13fae2d
CH
977 inode->i_flags |= S_IMMUTABLE;
978 else
979 inode->i_flags &= ~S_IMMUTABLE;
e7b89481 980 if (xflags & FS_XFLAG_APPEND)
f13fae2d
CH
981 inode->i_flags |= S_APPEND;
982 else
983 inode->i_flags &= ~S_APPEND;
e7b89481 984 if (xflags & FS_XFLAG_SYNC)
f13fae2d
CH
985 inode->i_flags |= S_SYNC;
986 else
987 inode->i_flags &= ~S_SYNC;
e7b89481 988 if (xflags & FS_XFLAG_NOATIME)
f13fae2d
CH
989 inode->i_flags |= S_NOATIME;
990 else
991 inode->i_flags &= ~S_NOATIME;
742d8429 992#if 0 /* disabled until the flag switching races are sorted out */
58f88ca2
DC
993 if (xflags & FS_XFLAG_DAX)
994 inode->i_flags |= S_DAX;
995 else
996 inode->i_flags &= ~S_DAX;
742d8429 997#endif
f13fae2d 998}
25fe55e8 999
29a17c00
DC
1000static int
1001xfs_ioctl_setattr_xflags(
1002 struct xfs_trans *tp,
1003 struct xfs_inode *ip,
1004 struct fsxattr *fa)
1005{
1006 struct xfs_mount *mp = ip->i_mount;
dd60687e 1007 uint64_t di_flags2;
29a17c00
DC
1008
1009 /* Can't change realtime flag if any extents are allocated. */
1010 if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
e7b89481 1011 XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME))
29a17c00
DC
1012 return -EINVAL;
1013
1014 /* If realtime flag is set then must have realtime device */
e7b89481 1015 if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
29a17c00
DC
1016 if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
1017 (ip->i_d.di_extsize % mp->m_sb.sb_rextsize))
1018 return -EINVAL;
1019 }
1020
1987fd74 1021 /* Clear reflink if we are actually able to set the rt flag. */
c8e156ac 1022 if ((fa->fsx_xflags & FS_XFLAG_REALTIME) && xfs_is_reflink_inode(ip))
1987fd74 1023 ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
c8e156ac 1024
4f435ebe
DW
1025 /* Don't allow us to set DAX mode for a reflinked file for now. */
1026 if ((fa->fsx_xflags & FS_XFLAG_DAX) && xfs_is_reflink_inode(ip))
1027 return -EINVAL;
1028
29a17c00
DC
1029 /*
1030 * Can't modify an immutable/append-only file unless
1031 * we have appropriate permission.
1032 */
1033 if (((ip->i_d.di_flags & (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND)) ||
e7b89481 1034 (fa->fsx_xflags & (FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND))) &&
29a17c00
DC
1035 !capable(CAP_LINUX_IMMUTABLE))
1036 return -EPERM;
1037
dd60687e
CH
1038 /* diflags2 only valid for v3 inodes. */
1039 di_flags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
1040 if (di_flags2 && ip->i_d.di_version < 3)
1041 return -EINVAL;
1042
1043 ip->i_d.di_flags = xfs_flags2diflags(ip, fa->fsx_xflags);
1044 ip->i_d.di_flags2 = di_flags2;
1045
29a17c00
DC
1046 xfs_diflags_to_linux(ip);
1047 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1048 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
ff6d6af2 1049 XFS_STATS_INC(mp, xs_ig_attrchg);
29a17c00
DC
1050 return 0;
1051}
1052
3a6a854a
DC
1053/*
1054 * If we are changing DAX flags, we have to ensure the file is clean and any
1055 * cached objects in the address space are invalidated and removed. This
1056 * requires us to lock out other IO and page faults similar to a truncate
1057 * operation. The locks need to be held until the transaction has been committed
1058 * so that the cache invalidation is atomic with respect to the DAX flag
1059 * manipulation.
1060 */
1061static int
1062xfs_ioctl_setattr_dax_invalidate(
1063 struct xfs_inode *ip,
1064 struct fsxattr *fa,
1065 int *join_flags)
1066{
1067 struct inode *inode = VFS_I(ip);
6851a3db 1068 struct super_block *sb = inode->i_sb;
3a6a854a
DC
1069 int error;
1070
1071 *join_flags = 0;
1072
e8897529
DC
1073 /*
1074 * It is only valid to set the DAX flag on regular files and
64485437 1075 * directories on filesystems where the block size is equal to the page
aaacdd25
DW
1076 * size. On directories it serves as an inherited hint so we don't
1077 * have to check the device for dax support or flush pagecache.
e8897529 1078 */
64485437
DC
1079 if (fa->fsx_xflags & FS_XFLAG_DAX) {
1080 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
1081 return -EINVAL;
aaacdd25
DW
1082 if (S_ISREG(inode->i_mode) &&
1083 !bdev_dax_supported(xfs_find_bdev_for_inode(VFS_I(ip)),
80660f20 1084 sb->s_blocksize))
64485437
DC
1085 return -EINVAL;
1086 }
e8897529 1087
3a6a854a
DC
1088 /* If the DAX state is not changing, we have nothing to do here. */
1089 if ((fa->fsx_xflags & FS_XFLAG_DAX) && IS_DAX(inode))
1090 return 0;
1091 if (!(fa->fsx_xflags & FS_XFLAG_DAX) && !IS_DAX(inode))
1092 return 0;
1093
aaacdd25
DW
1094 if (S_ISDIR(inode->i_mode))
1095 return 0;
1096
3a6a854a
DC
1097 /* lock, flush and invalidate mapping in preparation for flag change */
1098 xfs_ilock(ip, XFS_MMAPLOCK_EXCL | XFS_IOLOCK_EXCL);
1099 error = filemap_write_and_wait(inode->i_mapping);
1100 if (error)
1101 goto out_unlock;
1102 error = invalidate_inode_pages2(inode->i_mapping);
1103 if (error)
1104 goto out_unlock;
1105
1106 *join_flags = XFS_MMAPLOCK_EXCL | XFS_IOLOCK_EXCL;
29a17c00 1107 return 0;
3a6a854a
DC
1108
1109out_unlock:
1110 xfs_iunlock(ip, XFS_MMAPLOCK_EXCL | XFS_IOLOCK_EXCL);
1111 return error;
1112
29a17c00
DC
1113}
1114
8f3d17ab
DC
1115/*
1116 * Set up the transaction structure for the setattr operation, checking that we
1117 * have permission to do so. On success, return a clean transaction and the
1118 * inode locked exclusively ready for further operation specific checks. On
1119 * failure, return an error without modifying or locking the inode.
3a6a854a
DC
1120 *
1121 * The inode might already be IO locked on call. If this is the case, it is
1122 * indicated in @join_flags and we take full responsibility for ensuring they
1123 * are unlocked from now on. Hence if we have an error here, we still have to
1124 * unlock them. Otherwise, once they are joined to the transaction, they will
1125 * be unlocked on commit/cancel.
8f3d17ab
DC
1126 */
1127static struct xfs_trans *
1128xfs_ioctl_setattr_get_trans(
3a6a854a
DC
1129 struct xfs_inode *ip,
1130 int join_flags)
8f3d17ab
DC
1131{
1132 struct xfs_mount *mp = ip->i_mount;
1133 struct xfs_trans *tp;
3a6a854a 1134 int error = -EROFS;
8f3d17ab
DC
1135
1136 if (mp->m_flags & XFS_MOUNT_RDONLY)
3a6a854a
DC
1137 goto out_unlock;
1138 error = -EIO;
8f3d17ab 1139 if (XFS_FORCED_SHUTDOWN(mp))
3a6a854a 1140 goto out_unlock;
8f3d17ab 1141
253f4911 1142 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
8f3d17ab 1143 if (error)
3de5eab3 1144 goto out_unlock;
8f3d17ab
DC
1145
1146 xfs_ilock(ip, XFS_ILOCK_EXCL);
3a6a854a
DC
1147 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | join_flags);
1148 join_flags = 0;
8f3d17ab
DC
1149
1150 /*
1151 * CAP_FOWNER overrides the following restrictions:
1152 *
1153 * The user ID of the calling process must be equal to the file owner
1154 * ID, except in cases where the CAP_FSETID capability is applicable.
1155 */
1156 if (!inode_owner_or_capable(VFS_I(ip))) {
1157 error = -EPERM;
1158 goto out_cancel;
1159 }
1160
1161 if (mp->m_flags & XFS_MOUNT_WSYNC)
1162 xfs_trans_set_sync(tp);
1163
1164 return tp;
1165
1166out_cancel:
4906e215 1167 xfs_trans_cancel(tp);
3a6a854a
DC
1168out_unlock:
1169 if (join_flags)
1170 xfs_iunlock(ip, join_flags);
8f3d17ab
DC
1171 return ERR_PTR(error);
1172}
1173
9b94fcc3
IP
1174/*
1175 * extent size hint validation is somewhat cumbersome. Rules are:
1176 *
1177 * 1. extent size hint is only valid for directories and regular files
e7b89481
DC
1178 * 2. FS_XFLAG_EXTSIZE is only valid for regular files
1179 * 3. FS_XFLAG_EXTSZINHERIT is only valid for directories.
9b94fcc3
IP
1180 * 4. can only be changed on regular files if no extents are allocated
1181 * 5. can be changed on directories at any time
1182 * 6. extsize hint of 0 turns off hints, clears inode flags.
1183 * 7. Extent size must be a multiple of the appropriate block size.
1184 * 8. for non-realtime files, the extent size hint must be limited
1185 * to half the AG size to avoid alignment extending the extent beyond the
1186 * limits of the AG.
80e4e126
DW
1187 *
1188 * Please keep this function in sync with xfs_scrub_inode_extsize.
9b94fcc3 1189 */
f92090e9 1190static int
d4388d3c
DC
1191xfs_ioctl_setattr_check_extsize(
1192 struct xfs_inode *ip,
1193 struct fsxattr *fa)
1194{
1195 struct xfs_mount *mp = ip->i_mount;
1196
c19b3b05 1197 if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(VFS_I(ip)->i_mode))
9b94fcc3
IP
1198 return -EINVAL;
1199
e7b89481 1200 if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
c19b3b05 1201 !S_ISDIR(VFS_I(ip)->i_mode))
9b94fcc3
IP
1202 return -EINVAL;
1203
c19b3b05 1204 if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents &&
d4388d3c
DC
1205 ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize))
1206 return -EINVAL;
1207
d4388d3c
DC
1208 if (fa->fsx_extsize != 0) {
1209 xfs_extlen_t size;
1210 xfs_fsblock_t extsize_fsb;
1211
1212 extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
1213 if (extsize_fsb > MAXEXTLEN)
1214 return -EINVAL;
1215
1216 if (XFS_IS_REALTIME_INODE(ip) ||
e7b89481 1217 (fa->fsx_xflags & FS_XFLAG_REALTIME)) {
d4388d3c
DC
1218 size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
1219 } else {
1220 size = mp->m_sb.sb_blocksize;
1221 if (extsize_fsb > mp->m_sb.sb_agblocks / 2)
1222 return -EINVAL;
1223 }
1224
1225 if (fa->fsx_extsize % size)
1226 return -EINVAL;
9b94fcc3 1227 } else
e7b89481 1228 fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
9b94fcc3 1229
d4388d3c
DC
1230 return 0;
1231}
1232
f7ca3522
DW
1233/*
1234 * CoW extent size hint validation rules are:
1235 *
1236 * 1. CoW extent size hint can only be set if reflink is enabled on the fs.
1237 * The inode does not have to have any shared blocks, but it must be a v3.
1238 * 2. FS_XFLAG_COWEXTSIZE is only valid for directories and regular files;
1239 * for a directory, the hint is propagated to new files.
1240 * 3. Can be changed on files & directories at any time.
1241 * 4. CoW extsize hint of 0 turns off hints, clears inode flags.
1242 * 5. Extent size must be a multiple of the appropriate block size.
1243 * 6. The extent size hint must be limited to half the AG size to avoid
1244 * alignment extending the extent beyond the limits of the AG.
80e4e126
DW
1245 *
1246 * Please keep this function in sync with xfs_scrub_inode_cowextsize.
f7ca3522
DW
1247 */
1248static int
1249xfs_ioctl_setattr_check_cowextsize(
1250 struct xfs_inode *ip,
1251 struct fsxattr *fa)
1252{
1253 struct xfs_mount *mp = ip->i_mount;
1254
1255 if (!(fa->fsx_xflags & FS_XFLAG_COWEXTSIZE))
1256 return 0;
1257
1258 if (!xfs_sb_version_hasreflink(&ip->i_mount->m_sb) ||
1259 ip->i_d.di_version != 3)
1260 return -EINVAL;
1261
1262 if (!S_ISREG(VFS_I(ip)->i_mode) && !S_ISDIR(VFS_I(ip)->i_mode))
1263 return -EINVAL;
1264
1265 if (fa->fsx_cowextsize != 0) {
1266 xfs_extlen_t size;
1267 xfs_fsblock_t cowextsize_fsb;
1268
1269 cowextsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
1270 if (cowextsize_fsb > MAXEXTLEN)
1271 return -EINVAL;
1272
1273 size = mp->m_sb.sb_blocksize;
1274 if (cowextsize_fsb > mp->m_sb.sb_agblocks / 2)
1275 return -EINVAL;
1276
1277 if (fa->fsx_cowextsize % size)
1278 return -EINVAL;
1279 } else
1280 fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
1281
1282 return 0;
1283}
1284
f92090e9 1285static int
23bd0735
DC
1286xfs_ioctl_setattr_check_projid(
1287 struct xfs_inode *ip,
1288 struct fsxattr *fa)
1289{
1290 /* Disallow 32bit project ids if projid32bit feature is not enabled. */
c8ce540d 1291 if (fa->fsx_projid > (uint16_t)-1 &&
23bd0735
DC
1292 !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
1293 return -EINVAL;
1294
1295 /*
1296 * Project Quota ID state is only allowed to change from within the init
1297 * namespace. Enforce that restriction only if we are trying to change
1298 * the quota ID state. Everything else is allowed in user namespaces.
1299 */
1300 if (current_user_ns() == &init_user_ns)
1301 return 0;
1302
1303 if (xfs_get_projid(ip) != fa->fsx_projid)
1304 return -EINVAL;
e7b89481 1305 if ((fa->fsx_xflags & FS_XFLAG_PROJINHERIT) !=
23bd0735
DC
1306 (ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
1307 return -EINVAL;
1308
1309 return 0;
1310}
25fe55e8
CH
1311
1312STATIC int
1313xfs_ioctl_setattr(
1314 xfs_inode_t *ip,
fd179b9c 1315 struct fsxattr *fa)
25fe55e8
CH
1316{
1317 struct xfs_mount *mp = ip->i_mount;
1318 struct xfs_trans *tp;
7d095257 1319 struct xfs_dquot *udqp = NULL;
92f8ff73 1320 struct xfs_dquot *pdqp = NULL;
25fe55e8
CH
1321 struct xfs_dquot *olddquot = NULL;
1322 int code;
3a6a854a 1323 int join_flags = 0;
25fe55e8 1324
cca28fb8 1325 trace_xfs_ioctl_setattr(ip);
25fe55e8 1326
23bd0735
DC
1327 code = xfs_ioctl_setattr_check_projid(ip, fa);
1328 if (code)
1329 return code;
23963e54 1330
25fe55e8
CH
1331 /*
1332 * If disk quotas is on, we make sure that the dquots do exist on disk,
1333 * before we start any other transactions. Trying to do this later
1334 * is messy. We don't care to take a readlock to look at the ids
1335 * in inode here, because we can't hold it across the trans_reserve.
1336 * If the IDs do change before we take the ilock, we're covered
1337 * because the i_*dquot fields will get updated anyway.
1338 */
fd179b9c 1339 if (XFS_IS_QUOTA_ON(mp)) {
7d095257 1340 code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
25fe55e8 1341 ip->i_d.di_gid, fa->fsx_projid,
92f8ff73 1342 XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp);
25fe55e8
CH
1343 if (code)
1344 return code;
1345 }
1346
3a6a854a
DC
1347 /*
1348 * Changing DAX config may require inode locking for mapping
1349 * invalidation. These need to be held all the way to transaction commit
1350 * or cancel time, so need to be passed through to
1351 * xfs_ioctl_setattr_get_trans() so it can apply them to the join call
1352 * appropriately.
1353 */
1354 code = xfs_ioctl_setattr_dax_invalidate(ip, fa, &join_flags);
1355 if (code)
1356 goto error_free_dquots;
1357
1358 tp = xfs_ioctl_setattr_get_trans(ip, join_flags);
8f3d17ab
DC
1359 if (IS_ERR(tp)) {
1360 code = PTR_ERR(tp);
1361 goto error_free_dquots;
25fe55e8
CH
1362 }
1363
25fe55e8 1364
fd179b9c
DC
1365 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp) &&
1366 xfs_get_projid(ip) != fa->fsx_projid) {
1367 code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL, pdqp,
1368 capable(CAP_FOWNER) ? XFS_QMOPT_FORCE_RES : 0);
1369 if (code) /* out of quota */
d4388d3c 1370 goto error_trans_cancel;
25fe55e8
CH
1371 }
1372
d4388d3c
DC
1373 code = xfs_ioctl_setattr_check_extsize(ip, fa);
1374 if (code)
1375 goto error_trans_cancel;
25fe55e8 1376
f7ca3522
DW
1377 code = xfs_ioctl_setattr_check_cowextsize(ip, fa);
1378 if (code)
1379 goto error_trans_cancel;
1380
29a17c00
DC
1381 code = xfs_ioctl_setattr_xflags(tp, ip, fa);
1382 if (code)
d4388d3c 1383 goto error_trans_cancel;
25fe55e8
CH
1384
1385 /*
fd179b9c
DC
1386 * Change file ownership. Must be the owner or privileged. CAP_FSETID
1387 * overrides the following restrictions:
1388 *
1389 * The set-user-ID and set-group-ID bits of a file will be cleared upon
1390 * successful return from chown()
25fe55e8 1391 */
25fe55e8 1392
c19b3b05 1393 if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&
fd179b9c 1394 !capable_wrt_inode_uidgid(VFS_I(ip), CAP_FSETID))
c19b3b05 1395 VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);
25fe55e8 1396
fd179b9c
DC
1397 /* Change the ownerships and register project quota modifications */
1398 if (xfs_get_projid(ip) != fa->fsx_projid) {
1399 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
1400 olddquot = xfs_qm_vop_chown(tp, ip,
1401 &ip->i_pdquot, pdqp);
1402 }
1403 ASSERT(ip->i_d.di_version > 1);
1404 xfs_set_projid(ip, fa->fsx_projid);
f13fae2d 1405 }
25fe55e8 1406
a872703f
DC
1407 /*
1408 * Only set the extent size hint if we've already determined that the
1409 * extent size hint should be set on the inode. If no extent size flags
1410 * are set on the inode then unconditionally clear the extent size hint.
1411 */
fd179b9c
DC
1412 if (ip->i_d.di_flags & (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))
1413 ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog;
1414 else
1415 ip->i_d.di_extsize = 0;
f7ca3522
DW
1416 if (ip->i_d.di_version == 3 &&
1417 (ip->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE))
1418 ip->i_d.di_cowextsize = fa->fsx_cowextsize >>
1419 mp->m_sb.sb_blocklog;
1420 else
1421 ip->i_d.di_cowextsize = 0;
25fe55e8 1422
70393313 1423 code = xfs_trans_commit(tp);
25fe55e8
CH
1424
1425 /*
1426 * Release any dquot(s) the inode had kept before chown.
1427 */
7d095257
CH
1428 xfs_qm_dqrele(olddquot);
1429 xfs_qm_dqrele(udqp);
92f8ff73 1430 xfs_qm_dqrele(pdqp);
25fe55e8 1431
288699fe 1432 return code;
25fe55e8 1433
d4388d3c 1434error_trans_cancel:
4906e215 1435 xfs_trans_cancel(tp);
8f3d17ab 1436error_free_dquots:
7d095257 1437 xfs_qm_dqrele(udqp);
92f8ff73 1438 xfs_qm_dqrele(pdqp);
25fe55e8
CH
1439 return code;
1440}
1441
1da177e4 1442STATIC int
df26cfe8 1443xfs_ioc_fssetxattr(
1da177e4
LT
1444 xfs_inode_t *ip,
1445 struct file *filp,
1da177e4
LT
1446 void __user *arg)
1447{
1448 struct fsxattr fa;
d9457dc0 1449 int error;
df26cfe8
LM
1450
1451 if (copy_from_user(&fa, arg, sizeof(fa)))
1452 return -EFAULT;
1da177e4 1453
d9457dc0
JK
1454 error = mnt_want_write_file(filp);
1455 if (error)
1456 return error;
fd179b9c 1457 error = xfs_ioctl_setattr(ip, &fa);
d9457dc0 1458 mnt_drop_write_file(filp);
2451337d 1459 return error;
df26cfe8 1460}
1da177e4 1461
df26cfe8
LM
1462STATIC int
1463xfs_ioc_getxflags(
1464 xfs_inode_t *ip,
1465 void __user *arg)
1466{
1467 unsigned int flags;
1da177e4 1468
df26cfe8
LM
1469 flags = xfs_di2lxflags(ip->i_d.di_flags);
1470 if (copy_to_user(arg, &flags, sizeof(flags)))
1471 return -EFAULT;
1472 return 0;
1473}
1da177e4 1474
df26cfe8
LM
1475STATIC int
1476xfs_ioc_setxflags(
f96291f6 1477 struct xfs_inode *ip,
df26cfe8
LM
1478 struct file *filp,
1479 void __user *arg)
1480{
f96291f6 1481 struct xfs_trans *tp;
25fe55e8 1482 struct fsxattr fa;
df26cfe8 1483 unsigned int flags;
3a6a854a 1484 int join_flags = 0;
f96291f6 1485 int error;
1da177e4 1486
df26cfe8
LM
1487 if (copy_from_user(&flags, arg, sizeof(flags)))
1488 return -EFAULT;
1da177e4 1489
df26cfe8
LM
1490 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
1491 FS_NOATIME_FL | FS_NODUMP_FL | \
1492 FS_SYNC_FL))
1493 return -EOPNOTSUPP;
1da177e4 1494
25fe55e8 1495 fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip));
1da177e4 1496
d9457dc0
JK
1497 error = mnt_want_write_file(filp);
1498 if (error)
1499 return error;
f96291f6 1500
3a6a854a
DC
1501 /*
1502 * Changing DAX config may require inode locking for mapping
1503 * invalidation. These need to be held all the way to transaction commit
1504 * or cancel time, so need to be passed through to
1505 * xfs_ioctl_setattr_get_trans() so it can apply them to the join call
1506 * appropriately.
1507 */
1508 error = xfs_ioctl_setattr_dax_invalidate(ip, &fa, &join_flags);
1509 if (error)
1510 goto out_drop_write;
1511
1512 tp = xfs_ioctl_setattr_get_trans(ip, join_flags);
f96291f6
DC
1513 if (IS_ERR(tp)) {
1514 error = PTR_ERR(tp);
1515 goto out_drop_write;
1516 }
1517
1518 error = xfs_ioctl_setattr_xflags(tp, ip, &fa);
1519 if (error) {
4906e215 1520 xfs_trans_cancel(tp);
f96291f6
DC
1521 goto out_drop_write;
1522 }
1523
70393313 1524 error = xfs_trans_commit(tp);
f96291f6 1525out_drop_write:
d9457dc0 1526 mnt_drop_write_file(filp);
2451337d 1527 return error;
1da177e4
LT
1528}
1529
232b5194
CH
1530static bool
1531xfs_getbmap_format(
1532 struct kgetbmap *p,
1533 struct getbmapx __user *u,
1534 size_t recsize)
8a7141a8 1535{
232b5194
CH
1536 if (put_user(p->bmv_offset, &u->bmv_offset) ||
1537 put_user(p->bmv_block, &u->bmv_block) ||
1538 put_user(p->bmv_length, &u->bmv_length) ||
1539 put_user(0, &u->bmv_count) ||
1540 put_user(0, &u->bmv_entries))
1541 return false;
1542 if (recsize < sizeof(struct getbmapx))
1543 return true;
1544 if (put_user(0, &u->bmv_iflags) ||
1545 put_user(p->bmv_oflags, &u->bmv_oflags) ||
1546 put_user(0, &u->bmv_unused1) ||
1547 put_user(0, &u->bmv_unused2))
1548 return false;
1549 return true;
8a7141a8
ES
1550}
1551
1da177e4
LT
1552STATIC int
1553xfs_ioc_getbmap(
8f3e2058 1554 struct file *file,
1da177e4
LT
1555 unsigned int cmd,
1556 void __user *arg)
1557{
be6324c0 1558 struct getbmapx bmx = { 0 };
232b5194
CH
1559 struct kgetbmap *buf;
1560 size_t recsize;
1561 int error, i;
1da177e4 1562
232b5194
CH
1563 switch (cmd) {
1564 case XFS_IOC_GETBMAPA:
1565 bmx.bmv_iflags = BMV_IF_ATTRFORK;
1566 /*FALLTHRU*/
1567 case XFS_IOC_GETBMAP:
1568 if (file->f_mode & FMODE_NOCMTIME)
1569 bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ;
1570 /* struct getbmap is a strict subset of struct getbmapx. */
1571 recsize = sizeof(struct getbmap);
1572 break;
1573 case XFS_IOC_GETBMAPX:
1574 recsize = sizeof(struct getbmapx);
1575 break;
1576 default:
b474c7ae 1577 return -EINVAL;
232b5194 1578 }
1da177e4 1579
232b5194 1580 if (copy_from_user(&bmx, arg, recsize))
b474c7ae 1581 return -EFAULT;
1da177e4
LT
1582
1583 if (bmx.bmv_count < 2)
b474c7ae 1584 return -EINVAL;
232b5194
CH
1585 if (bmx.bmv_count > ULONG_MAX / recsize)
1586 return -ENOMEM;
1da177e4 1587
232b5194
CH
1588 buf = kmem_zalloc_large(bmx.bmv_count * sizeof(*buf), 0);
1589 if (!buf)
1590 return -ENOMEM;
1da177e4 1591
232b5194 1592 error = xfs_getbmap(XFS_I(file_inode(file)), &bmx, buf);
1da177e4 1593 if (error)
232b5194 1594 goto out_free_buf;
1da177e4 1595
232b5194
CH
1596 error = -EFAULT;
1597 if (copy_to_user(arg, &bmx, recsize))
1598 goto out_free_buf;
1599 arg += recsize;
1600
1601 for (i = 0; i < bmx.bmv_entries; i++) {
1602 if (!xfs_getbmap_format(buf + i, arg, recsize))
1603 goto out_free_buf;
1604 arg += recsize;
1605 }
1da177e4 1606
232b5194
CH
1607 error = 0;
1608out_free_buf:
1609 kmem_free(buf);
132bf672 1610 return error;
1da177e4 1611}
df26cfe8 1612
e89c0413
DW
1613struct getfsmap_info {
1614 struct xfs_mount *mp;
9d17e14c
CH
1615 struct fsmap_head __user *data;
1616 unsigned int idx;
e89c0413
DW
1617 __u32 last_flags;
1618};
1619
1620STATIC int
1621xfs_getfsmap_format(struct xfs_fsmap *xfm, void *priv)
1622{
1623 struct getfsmap_info *info = priv;
1624 struct fsmap fm;
1625
1626 trace_xfs_getfsmap_mapping(info->mp, xfm);
1627
1628 info->last_flags = xfm->fmr_flags;
1629 xfs_fsmap_from_internal(&fm, xfm);
9d17e14c
CH
1630 if (copy_to_user(&info->data->fmh_recs[info->idx++], &fm,
1631 sizeof(struct fsmap)))
e89c0413
DW
1632 return -EFAULT;
1633
e89c0413
DW
1634 return 0;
1635}
1636
1637STATIC int
1638xfs_ioc_getfsmap(
1639 struct xfs_inode *ip,
9d17e14c 1640 struct fsmap_head __user *arg)
e89c0413 1641{
ef2b67ec 1642 struct getfsmap_info info = { NULL };
e89c0413
DW
1643 struct xfs_fsmap_head xhead = {0};
1644 struct fsmap_head head;
1645 bool aborted = false;
1646 int error;
1647
1648 if (copy_from_user(&head, arg, sizeof(struct fsmap_head)))
1649 return -EFAULT;
1650 if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) ||
1651 memchr_inv(head.fmh_keys[0].fmr_reserved, 0,
1652 sizeof(head.fmh_keys[0].fmr_reserved)) ||
1653 memchr_inv(head.fmh_keys[1].fmr_reserved, 0,
1654 sizeof(head.fmh_keys[1].fmr_reserved)))
1655 return -EINVAL;
1656
1657 xhead.fmh_iflags = head.fmh_iflags;
1658 xhead.fmh_count = head.fmh_count;
1659 xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]);
1660 xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]);
1661
1662 trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
1663 trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]);
1664
1665 info.mp = ip->i_mount;
9d17e14c 1666 info.data = arg;
e89c0413
DW
1667 error = xfs_getfsmap(ip->i_mount, &xhead, xfs_getfsmap_format, &info);
1668 if (error == XFS_BTREE_QUERY_RANGE_ABORT) {
1669 error = 0;
1670 aborted = true;
1671 } else if (error)
1672 return error;
1673
1674 /* If we didn't abort, set the "last" flag in the last fmx */
12e4a381 1675 if (!aborted && info.idx) {
e89c0413 1676 info.last_flags |= FMR_OF_LAST;
9d17e14c
CH
1677 if (copy_to_user(&info.data->fmh_recs[info.idx - 1].fmr_flags,
1678 &info.last_flags, sizeof(info.last_flags)))
e89c0413
DW
1679 return -EFAULT;
1680 }
1681
1682 /* copy back header */
1683 head.fmh_entries = xhead.fmh_entries;
1684 head.fmh_oflags = xhead.fmh_oflags;
1685 if (copy_to_user(arg, &head, sizeof(struct fsmap_head)))
1686 return -EFAULT;
1687
1688 return 0;
1689}
1690
36fd6e86
DW
1691STATIC int
1692xfs_ioc_scrub_metadata(
1693 struct xfs_inode *ip,
1694 void __user *arg)
1695{
1696 struct xfs_scrub_metadata scrub;
1697 int error;
1698
1699 if (!capable(CAP_SYS_ADMIN))
1700 return -EPERM;
1701
1702 if (copy_from_user(&scrub, arg, sizeof(scrub)))
1703 return -EFAULT;
1704
1705 error = xfs_scrub_metadata(ip, &scrub);
1706 if (error)
1707 return error;
1708
1709 if (copy_to_user(arg, &scrub, sizeof(scrub)))
1710 return -EFAULT;
1711
1712 return 0;
1713}
1714
a133d952
DC
1715int
1716xfs_ioc_swapext(
1717 xfs_swapext_t *sxp)
1718{
1719 xfs_inode_t *ip, *tip;
1720 struct fd f, tmp;
1721 int error = 0;
1722
1723 /* Pull information for the target fd */
1724 f = fdget((int)sxp->sx_fdtarget);
1725 if (!f.file) {
2451337d 1726 error = -EINVAL;
a133d952
DC
1727 goto out;
1728 }
1729
1730 if (!(f.file->f_mode & FMODE_WRITE) ||
1731 !(f.file->f_mode & FMODE_READ) ||
1732 (f.file->f_flags & O_APPEND)) {
2451337d 1733 error = -EBADF;
a133d952
DC
1734 goto out_put_file;
1735 }
1736
1737 tmp = fdget((int)sxp->sx_fdtmp);
1738 if (!tmp.file) {
2451337d 1739 error = -EINVAL;
a133d952
DC
1740 goto out_put_file;
1741 }
1742
1743 if (!(tmp.file->f_mode & FMODE_WRITE) ||
1744 !(tmp.file->f_mode & FMODE_READ) ||
1745 (tmp.file->f_flags & O_APPEND)) {
2451337d 1746 error = -EBADF;
a133d952
DC
1747 goto out_put_tmp_file;
1748 }
1749
1750 if (IS_SWAPFILE(file_inode(f.file)) ||
1751 IS_SWAPFILE(file_inode(tmp.file))) {
2451337d 1752 error = -EINVAL;
a133d952
DC
1753 goto out_put_tmp_file;
1754 }
1755
7f1b6245
JH
1756 /*
1757 * We need to ensure that the fds passed in point to XFS inodes
1758 * before we cast and access them as XFS structures as we have no
1759 * control over what the user passes us here.
1760 */
1761 if (f.file->f_op != &xfs_file_operations ||
1762 tmp.file->f_op != &xfs_file_operations) {
1763 error = -EINVAL;
1764 goto out_put_tmp_file;
1765 }
1766
a133d952
DC
1767 ip = XFS_I(file_inode(f.file));
1768 tip = XFS_I(file_inode(tmp.file));
1769
1770 if (ip->i_mount != tip->i_mount) {
2451337d 1771 error = -EINVAL;
a133d952
DC
1772 goto out_put_tmp_file;
1773 }
1774
1775 if (ip->i_ino == tip->i_ino) {
2451337d 1776 error = -EINVAL;
a133d952
DC
1777 goto out_put_tmp_file;
1778 }
1779
1780 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
2451337d 1781 error = -EIO;
a133d952
DC
1782 goto out_put_tmp_file;
1783 }
1784
1785 error = xfs_swap_extents(ip, tip, sxp);
1786
1787 out_put_tmp_file:
1788 fdput(tmp);
1789 out_put_file:
1790 fdput(f);
1791 out:
1792 return error;
1793}
1794
f7664b31
ES
1795static int
1796xfs_ioc_getlabel(
1797 struct xfs_mount *mp,
1798 char __user *user_label)
1799{
1800 struct xfs_sb *sbp = &mp->m_sb;
1801 char label[XFSLABEL_MAX + 1];
1802
1803 /* Paranoia */
1804 BUILD_BUG_ON(sizeof(sbp->sb_fname) > FSLABEL_MAX);
1805
4bb8b65a
AB
1806 /* 1 larger than sb_fname, so this ensures a trailing NUL char */
1807 memset(label, 0, sizeof(label));
f7664b31 1808 spin_lock(&mp->m_sb_lock);
4bb8b65a 1809 strncpy(label, sbp->sb_fname, XFSLABEL_MAX);
f7664b31
ES
1810 spin_unlock(&mp->m_sb_lock);
1811
4bb8b65a 1812 if (copy_to_user(user_label, label, sizeof(label)))
f7664b31
ES
1813 return -EFAULT;
1814 return 0;
1815}
1816
1817static int
1818xfs_ioc_setlabel(
1819 struct file *filp,
1820 struct xfs_mount *mp,
1821 char __user *newlabel)
1822{
1823 struct xfs_sb *sbp = &mp->m_sb;
1824 char label[XFSLABEL_MAX + 1];
1825 size_t len;
1826 int error;
1827
1828 if (!capable(CAP_SYS_ADMIN))
1829 return -EPERM;
1830 /*
1831 * The generic ioctl allows up to FSLABEL_MAX chars, but XFS is much
1832 * smaller, at 12 bytes. We copy one more to be sure we find the
1833 * (required) NULL character to test the incoming label length.
1834 * NB: The on disk label doesn't need to be null terminated.
1835 */
1836 if (copy_from_user(label, newlabel, XFSLABEL_MAX + 1))
1837 return -EFAULT;
1838 len = strnlen(label, XFSLABEL_MAX + 1);
1839 if (len > sizeof(sbp->sb_fname))
1840 return -EINVAL;
1841
1842 error = mnt_want_write_file(filp);
1843 if (error)
1844 return error;
1845
1846 spin_lock(&mp->m_sb_lock);
1847 memset(sbp->sb_fname, 0, sizeof(sbp->sb_fname));
4bb8b65a 1848 memcpy(sbp->sb_fname, label, len);
f7664b31
ES
1849 spin_unlock(&mp->m_sb_lock);
1850
1851 /*
1852 * Now we do several things to satisfy userspace.
1853 * In addition to normal logging of the primary superblock, we also
1854 * immediately write these changes to sector zero for the primary, then
1855 * update all backup supers (as xfs_db does for a label change), then
1856 * invalidate the block device page cache. This is so that any prior
1857 * buffered reads from userspace (i.e. from blkid) are invalidated,
1858 * and userspace will see the newly-written label.
1859 */
1860 error = xfs_sync_sb_buf(mp);
1861 if (error)
1862 goto out;
1863 /*
1864 * growfs also updates backup supers so lock against that.
1865 */
1866 mutex_lock(&mp->m_growlock);
1867 error = xfs_update_secondary_sbs(mp);
1868 mutex_unlock(&mp->m_growlock);
1869
1870 invalidate_bdev(mp->m_ddev_targp->bt_bdev);
1871
1872out:
1873 mnt_drop_write_file(filp);
1874 return error;
1875}
1876
4d4be482
CH
1877/*
1878 * Note: some of the ioctl's return positive numbers as a
1879 * byte count indicating success, such as readlink_by_handle.
1880 * So we don't "sign flip" like most other routines. This means
1881 * true errors need to be returned as a negative value.
1882 */
1883long
1884xfs_file_ioctl(
df26cfe8 1885 struct file *filp,
df26cfe8 1886 unsigned int cmd,
4d4be482 1887 unsigned long p)
df26cfe8 1888{
496ad9aa 1889 struct inode *inode = file_inode(filp);
4d4be482
CH
1890 struct xfs_inode *ip = XFS_I(inode);
1891 struct xfs_mount *mp = ip->i_mount;
1892 void __user *arg = (void __user *)p;
df26cfe8
LM
1893 int error;
1894
cca28fb8 1895 trace_xfs_file_ioctl(ip);
4d4be482
CH
1896
1897 switch (cmd) {
a46db608
CH
1898 case FITRIM:
1899 return xfs_ioc_trim(mp, arg);
f7664b31
ES
1900 case FS_IOC_GETFSLABEL:
1901 return xfs_ioc_getlabel(mp, arg);
1902 case FS_IOC_SETFSLABEL:
1903 return xfs_ioc_setlabel(filp, mp, arg);
df26cfe8
LM
1904 case XFS_IOC_ALLOCSP:
1905 case XFS_IOC_FREESP:
1906 case XFS_IOC_RESVSP:
1907 case XFS_IOC_UNRESVSP:
1908 case XFS_IOC_ALLOCSP64:
1909 case XFS_IOC_FREESP64:
1910 case XFS_IOC_RESVSP64:
44722352
DC
1911 case XFS_IOC_UNRESVSP64:
1912 case XFS_IOC_ZERO_RANGE: {
743bb465 1913 xfs_flock64_t bf;
df26cfe8 1914
743bb465 1915 if (copy_from_user(&bf, arg, sizeof(bf)))
b474c7ae 1916 return -EFAULT;
8f3e2058 1917 return xfs_ioc_space(filp, cmd, &bf);
743bb465 1918 }
df26cfe8
LM
1919 case XFS_IOC_DIOINFO: {
1920 struct dioattr da;
1921 xfs_buftarg_t *target =
1922 XFS_IS_REALTIME_INODE(ip) ?
1923 mp->m_rtdev_targp : mp->m_ddev_targp;
1924
7c71ee78 1925 da.d_mem = da.d_miniosz = target->bt_logical_sectorsize;
df26cfe8
LM
1926 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
1927
1928 if (copy_to_user(arg, &da, sizeof(da)))
b474c7ae 1929 return -EFAULT;
df26cfe8
LM
1930 return 0;
1931 }
1932
1933 case XFS_IOC_FSBULKSTAT_SINGLE:
1934 case XFS_IOC_FSBULKSTAT:
1935 case XFS_IOC_FSINUMBERS:
1936 return xfs_ioc_bulkstat(mp, cmd, arg);
1937
1938 case XFS_IOC_FSGEOMETRY_V1:
1b6d968d
DC
1939 return xfs_ioc_fsgeometry(mp, arg, 3);
1940 case XFS_IOC_FSGEOMETRY_V4:
1941 return xfs_ioc_fsgeometry(mp, arg, 4);
df26cfe8 1942 case XFS_IOC_FSGEOMETRY:
1b6d968d 1943 return xfs_ioc_fsgeometry(mp, arg, 5);
df26cfe8 1944
7cd5006b
DW
1945 case XFS_IOC_AG_GEOMETRY:
1946 return xfs_ioc_ag_geometry(mp, arg);
1947
df26cfe8
LM
1948 case XFS_IOC_GETVERSION:
1949 return put_user(inode->i_generation, (int __user *)arg);
1950
1951 case XFS_IOC_FSGETXATTR:
1952 return xfs_ioc_fsgetxattr(ip, 0, arg);
1953 case XFS_IOC_FSGETXATTRA:
1954 return xfs_ioc_fsgetxattr(ip, 1, arg);
65e67f51
LM
1955 case XFS_IOC_FSSETXATTR:
1956 return xfs_ioc_fssetxattr(ip, filp, arg);
df26cfe8 1957 case XFS_IOC_GETXFLAGS:
65e67f51 1958 return xfs_ioc_getxflags(ip, arg);
df26cfe8 1959 case XFS_IOC_SETXFLAGS:
65e67f51 1960 return xfs_ioc_setxflags(ip, filp, arg);
df26cfe8
LM
1961
1962 case XFS_IOC_FSSETDM: {
1963 struct fsdmidata dmi;
1964
1965 if (copy_from_user(&dmi, arg, sizeof(dmi)))
b474c7ae 1966 return -EFAULT;
df26cfe8 1967
d9457dc0
JK
1968 error = mnt_want_write_file(filp);
1969 if (error)
1970 return error;
1971
df26cfe8
LM
1972 error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
1973 dmi.fsd_dmstate);
d9457dc0 1974 mnt_drop_write_file(filp);
2451337d 1975 return error;
df26cfe8
LM
1976 }
1977
1978 case XFS_IOC_GETBMAP:
1979 case XFS_IOC_GETBMAPA:
df26cfe8 1980 case XFS_IOC_GETBMAPX:
232b5194 1981 return xfs_ioc_getbmap(filp, cmd, arg);
df26cfe8 1982
e89c0413
DW
1983 case FS_IOC_GETFSMAP:
1984 return xfs_ioc_getfsmap(ip, arg);
1985
36fd6e86
DW
1986 case XFS_IOC_SCRUB_METADATA:
1987 return xfs_ioc_scrub_metadata(ip, arg);
1988
df26cfe8
LM
1989 case XFS_IOC_FD_TO_HANDLE:
1990 case XFS_IOC_PATH_TO_HANDLE:
743bb465 1991 case XFS_IOC_PATH_TO_FSHANDLE: {
1992 xfs_fsop_handlereq_t hreq;
df26cfe8 1993
743bb465 1994 if (copy_from_user(&hreq, arg, sizeof(hreq)))
b474c7ae 1995 return -EFAULT;
743bb465 1996 return xfs_find_handle(cmd, &hreq);
1997 }
1998 case XFS_IOC_OPEN_BY_HANDLE: {
1999 xfs_fsop_handlereq_t hreq;
df26cfe8 2000
743bb465 2001 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
b474c7ae 2002 return -EFAULT;
d296d30a 2003 return xfs_open_by_handle(filp, &hreq);
743bb465 2004 }
df26cfe8 2005 case XFS_IOC_FSSETDM_BY_HANDLE:
d296d30a 2006 return xfs_fssetdm_by_handle(filp, arg);
df26cfe8 2007
743bb465 2008 case XFS_IOC_READLINK_BY_HANDLE: {
2009 xfs_fsop_handlereq_t hreq;
df26cfe8 2010
743bb465 2011 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
b474c7ae 2012 return -EFAULT;
d296d30a 2013 return xfs_readlink_by_handle(filp, &hreq);
743bb465 2014 }
df26cfe8 2015 case XFS_IOC_ATTRLIST_BY_HANDLE:
d296d30a 2016 return xfs_attrlist_by_handle(filp, arg);
df26cfe8
LM
2017
2018 case XFS_IOC_ATTRMULTI_BY_HANDLE:
d296d30a 2019 return xfs_attrmulti_by_handle(filp, arg);
df26cfe8
LM
2020
2021 case XFS_IOC_SWAPEXT: {
743bb465 2022 struct xfs_swapext sxp;
2023
2024 if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t)))
b474c7ae 2025 return -EFAULT;
d9457dc0
JK
2026 error = mnt_want_write_file(filp);
2027 if (error)
2028 return error;
a133d952 2029 error = xfs_ioc_swapext(&sxp);
d9457dc0 2030 mnt_drop_write_file(filp);
2451337d 2031 return error;
df26cfe8
LM
2032 }
2033
2034 case XFS_IOC_FSCOUNTS: {
2035 xfs_fsop_counts_t out;
2036
91083269 2037 xfs_fs_counts(mp, &out);
df26cfe8
LM
2038
2039 if (copy_to_user(arg, &out, sizeof(out)))
b474c7ae 2040 return -EFAULT;
df26cfe8
LM
2041 return 0;
2042 }
2043
2044 case XFS_IOC_SET_RESBLKS: {
2045 xfs_fsop_resblks_t inout;
c8ce540d 2046 uint64_t in;
df26cfe8
LM
2047
2048 if (!capable(CAP_SYS_ADMIN))
2049 return -EPERM;
2050
d5db0f97 2051 if (mp->m_flags & XFS_MOUNT_RDONLY)
b474c7ae 2052 return -EROFS;
d5db0f97 2053
df26cfe8 2054 if (copy_from_user(&inout, arg, sizeof(inout)))
b474c7ae 2055 return -EFAULT;
df26cfe8 2056
d9457dc0
JK
2057 error = mnt_want_write_file(filp);
2058 if (error)
2059 return error;
2060
df26cfe8
LM
2061 /* input parameter is passed in resblks field of structure */
2062 in = inout.resblks;
2063 error = xfs_reserve_blocks(mp, &in, &inout);
d9457dc0 2064 mnt_drop_write_file(filp);
df26cfe8 2065 if (error)
2451337d 2066 return error;
df26cfe8
LM
2067
2068 if (copy_to_user(arg, &inout, sizeof(inout)))
b474c7ae 2069 return -EFAULT;
df26cfe8
LM
2070 return 0;
2071 }
2072
2073 case XFS_IOC_GET_RESBLKS: {
2074 xfs_fsop_resblks_t out;
2075
2076 if (!capable(CAP_SYS_ADMIN))
2077 return -EPERM;
2078
2079 error = xfs_reserve_blocks(mp, NULL, &out);
2080 if (error)
2451337d 2081 return error;
df26cfe8
LM
2082
2083 if (copy_to_user(arg, &out, sizeof(out)))
b474c7ae 2084 return -EFAULT;
df26cfe8
LM
2085
2086 return 0;
2087 }
2088
2089 case XFS_IOC_FSGROWFSDATA: {
2090 xfs_growfs_data_t in;
2091
df26cfe8 2092 if (copy_from_user(&in, arg, sizeof(in)))
b474c7ae 2093 return -EFAULT;
df26cfe8 2094
d9457dc0
JK
2095 error = mnt_want_write_file(filp);
2096 if (error)
2097 return error;
df26cfe8 2098 error = xfs_growfs_data(mp, &in);
d9457dc0 2099 mnt_drop_write_file(filp);
2451337d 2100 return error;
df26cfe8
LM
2101 }
2102
2103 case XFS_IOC_FSGROWFSLOG: {
2104 xfs_growfs_log_t in;
2105
df26cfe8 2106 if (copy_from_user(&in, arg, sizeof(in)))
b474c7ae 2107 return -EFAULT;
df26cfe8 2108
d9457dc0
JK
2109 error = mnt_want_write_file(filp);
2110 if (error)
2111 return error;
df26cfe8 2112 error = xfs_growfs_log(mp, &in);
d9457dc0 2113 mnt_drop_write_file(filp);
2451337d 2114 return error;
df26cfe8
LM
2115 }
2116
2117 case XFS_IOC_FSGROWFSRT: {
2118 xfs_growfs_rt_t in;
2119
df26cfe8 2120 if (copy_from_user(&in, arg, sizeof(in)))
b474c7ae 2121 return -EFAULT;
df26cfe8 2122
d9457dc0
JK
2123 error = mnt_want_write_file(filp);
2124 if (error)
2125 return error;
df26cfe8 2126 error = xfs_growfs_rt(mp, &in);
d9457dc0 2127 mnt_drop_write_file(filp);
2451337d 2128 return error;
df26cfe8
LM
2129 }
2130
df26cfe8 2131 case XFS_IOC_GOINGDOWN: {
c8ce540d 2132 uint32_t in;
df26cfe8
LM
2133
2134 if (!capable(CAP_SYS_ADMIN))
2135 return -EPERM;
2136
c8ce540d 2137 if (get_user(in, (uint32_t __user *)arg))
b474c7ae 2138 return -EFAULT;
df26cfe8 2139
2451337d 2140 return xfs_fs_goingdown(mp, in);
df26cfe8
LM
2141 }
2142
2143 case XFS_IOC_ERROR_INJECTION: {
2144 xfs_error_injection_t in;
2145
2146 if (!capable(CAP_SYS_ADMIN))
2147 return -EPERM;
2148
2149 if (copy_from_user(&in, arg, sizeof(in)))
b474c7ae 2150 return -EFAULT;
df26cfe8 2151
31965ef3 2152 return xfs_errortag_add(mp, in.errtag);
df26cfe8
LM
2153 }
2154
2155 case XFS_IOC_ERROR_CLEARALL:
2156 if (!capable(CAP_SYS_ADMIN))
2157 return -EPERM;
2158
31965ef3 2159 return xfs_errortag_clearall(mp);
df26cfe8 2160
8ca149de 2161 case XFS_IOC_FREE_EOFBLOCKS: {
b9fe5052
DE
2162 struct xfs_fs_eofblocks eofb;
2163 struct xfs_eofblocks keofb;
8ca149de 2164
8c567a7f
DE
2165 if (!capable(CAP_SYS_ADMIN))
2166 return -EPERM;
2167
2168 if (mp->m_flags & XFS_MOUNT_RDONLY)
b474c7ae 2169 return -EROFS;
8c567a7f 2170
8ca149de 2171 if (copy_from_user(&eofb, arg, sizeof(eofb)))
b474c7ae 2172 return -EFAULT;
8ca149de 2173
b9fe5052
DE
2174 error = xfs_fs_eofblocks_from_user(&eofb, &keofb);
2175 if (error)
2451337d 2176 return error;
8ca149de 2177
2451337d 2178 return xfs_icache_free_eofblocks(mp, &keofb);
8ca149de
BF
2179 }
2180
df26cfe8
LM
2181 default:
2182 return -ENOTTY;
2183 }
2184}