Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 : * All Rights Reserved.
5 : */
6 : #include "xfs.h"
7 : #include "xfs_fs.h"
8 : #include "xfs_shared.h"
9 : #include "xfs_format.h"
10 : #include "xfs_log_format.h"
11 : #include "xfs_trans_resv.h"
12 : #include "xfs_mount.h"
13 : #include "xfs_inode.h"
14 : #include "xfs_rtalloc.h"
15 : #include "xfs_iwalk.h"
16 : #include "xfs_itable.h"
17 : #include "xfs_error.h"
18 : #include "xfs_da_format.h"
19 : #include "xfs_da_btree.h"
20 : #include "xfs_attr.h"
21 : #include "xfs_bmap.h"
22 : #include "xfs_bmap_util.h"
23 : #include "xfs_fsops.h"
24 : #include "xfs_discard.h"
25 : #include "xfs_quota.h"
26 : #include "xfs_export.h"
27 : #include "xfs_trace.h"
28 : #include "xfs_icache.h"
29 : #include "xfs_trans.h"
30 : #include "xfs_acl.h"
31 : #include "xfs_btree.h"
32 : #include <linux/fsmap.h>
33 : #include "xfs_fsmap.h"
34 : #include "xfs_fsrefs.h"
35 : #include "scrub/xfs_scrub.h"
36 : #include "xfs_sb.h"
37 : #include "xfs_ag.h"
38 : #include "xfs_health.h"
39 : #include "xfs_reflink.h"
40 : #include "xfs_ioctl.h"
41 : #include "xfs_parent_utils.h"
42 : #include "xfs_xattr.h"
43 : #include "xfs_xchgrange.h"
44 : #include "xfs_file.h"
45 : #include "xfs_rtbitmap.h"
46 : #include "xfs_rtgroup.h"
47 :
48 : #include <linux/mount.h>
49 : #include <linux/namei.h>
50 : #include <linux/fileattr.h>
51 :
52 : /*
53 : * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
54 : * a file or fs handle.
55 : *
56 : * XFS_IOC_PATH_TO_FSHANDLE
57 : * returns fs handle for a mount point or path within that mount point
58 : * XFS_IOC_FD_TO_HANDLE
59 : * returns full handle for a FD opened in user space
60 : * XFS_IOC_PATH_TO_HANDLE
61 : * returns full handle for a path
62 : */
63 : int
64 26244 : xfs_find_handle(
65 : unsigned int cmd,
66 : xfs_fsop_handlereq_t *hreq)
67 : {
68 26244 : int hsize;
69 26244 : xfs_handle_t handle;
70 26244 : struct inode *inode;
71 26244 : struct fd f = {NULL};
72 26244 : struct path path;
73 26244 : int error;
74 26244 : struct xfs_inode *ip;
75 :
76 26244 : if (cmd == XFS_IOC_FD_TO_HANDLE) {
77 436 : f = fdget(hreq->fd);
78 436 : if (!f.file)
79 : return -EBADF;
80 436 : inode = file_inode(f.file);
81 : } else {
82 25808 : error = user_path_at(AT_FDCWD, hreq->path, 0, &path);
83 25808 : if (error)
84 : return error;
85 25808 : inode = d_inode(path.dentry);
86 : }
87 26244 : ip = XFS_I(inode);
88 :
89 : /*
90 : * We can only generate handles for inodes residing on a XFS filesystem,
91 : * and only for regular files, directories or symbolic links.
92 : */
93 26244 : error = -EINVAL;
94 26244 : if (inode->i_sb->s_magic != XFS_SB_MAGIC)
95 0 : goto out_put;
96 :
97 26244 : error = -EBADF;
98 26244 : if (!S_ISREG(inode->i_mode) &&
99 0 : !S_ISDIR(inode->i_mode) &&
100 : !S_ISLNK(inode->i_mode))
101 0 : goto out_put;
102 :
103 :
104 26244 : memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
105 :
106 26244 : if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
107 : /*
108 : * This handle only contains an fsid, zero the rest.
109 : */
110 22772 : memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
111 22772 : hsize = sizeof(xfs_fsid_t);
112 : } else {
113 3472 : handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
114 : sizeof(handle.ha_fid.fid_len);
115 3472 : handle.ha_fid.fid_pad = 0;
116 3472 : handle.ha_fid.fid_gen = inode->i_generation;
117 3472 : handle.ha_fid.fid_ino = ip->i_ino;
118 3472 : hsize = sizeof(xfs_handle_t);
119 : }
120 :
121 26244 : error = -EFAULT;
122 78732 : if (copy_to_user(hreq->ohandle, &handle, hsize) ||
123 26244 : copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
124 0 : goto out_put;
125 :
126 : error = 0;
127 :
128 26244 : out_put:
129 26244 : if (cmd == XFS_IOC_FD_TO_HANDLE)
130 436 : fdput(f);
131 : else
132 25808 : path_put(&path);
133 : return error;
134 : }
135 :
136 : /*
137 : * No need to do permission checks on the various pathname components
138 : * as the handle operations are privileged.
139 : */
140 : STATIC int
141 168187985 : xfs_handle_acceptable(
142 : void *context,
143 : struct dentry *dentry)
144 : {
145 168187985 : return 1;
146 : }
147 :
148 : /*
149 : * Convert userspace handle data into a dentry.
150 : */
151 : struct dentry *
152 168214772 : xfs_handle_to_dentry(
153 : struct file *parfilp,
154 : void __user *uhandle,
155 : u32 hlen)
156 : {
157 168214772 : xfs_handle_t handle;
158 168214772 : struct xfs_fid64 fid;
159 :
160 : /*
161 : * Only allow handle opens under a directory.
162 : */
163 168214772 : if (!S_ISDIR(file_inode(parfilp)->i_mode))
164 : return ERR_PTR(-ENOTDIR);
165 :
166 168215934 : if (hlen != sizeof(xfs_handle_t))
167 : return ERR_PTR(-EINVAL);
168 168215428 : if (copy_from_user(&handle, uhandle, hlen))
169 : return ERR_PTR(-EFAULT);
170 168219409 : if (handle.ha_fid.fid_len !=
171 : sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len))
172 : return ERR_PTR(-EINVAL);
173 :
174 168217701 : memset(&fid, 0, sizeof(struct fid));
175 168217701 : fid.ino = handle.ha_fid.fid_ino;
176 168217701 : fid.gen = handle.ha_fid.fid_gen;
177 :
178 168217701 : return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3,
179 : FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
180 : xfs_handle_acceptable, NULL);
181 : }
182 :
183 : STATIC struct dentry *
184 168210384 : xfs_handlereq_to_dentry(
185 : struct file *parfilp,
186 : xfs_fsop_handlereq_t *hreq)
187 : {
188 168210384 : return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
189 : }
190 :
191 : int
192 33293157 : xfs_open_by_handle(
193 : struct file *parfilp,
194 : xfs_fsop_handlereq_t *hreq)
195 : {
196 33293157 : const struct cred *cred = current_cred();
197 33293157 : int error;
198 33293157 : int fd;
199 33293157 : int permflag;
200 33293157 : struct file *filp;
201 33293157 : struct inode *inode;
202 33293157 : struct dentry *dentry;
203 33293157 : fmode_t fmode;
204 33293157 : struct path path;
205 :
206 33293157 : if (!capable(CAP_SYS_ADMIN))
207 : return -EPERM;
208 :
209 33293120 : dentry = xfs_handlereq_to_dentry(parfilp, hreq);
210 33292939 : if (IS_ERR(dentry))
211 2084 : return PTR_ERR(dentry);
212 33290855 : inode = d_inode(dentry);
213 :
214 : /* Restrict xfs_open_by_handle to directories & regular files. */
215 33290855 : if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
216 0 : error = -EPERM;
217 0 : goto out_dput;
218 : }
219 :
220 : #if BITS_PER_LONG != 32
221 33290855 : hreq->oflags |= O_LARGEFILE;
222 : #endif
223 :
224 33290855 : permflag = hreq->oflags;
225 33290855 : fmode = OPEN_FMODE(permflag);
226 33290855 : if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
227 33290846 : (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
228 12 : error = -EPERM;
229 12 : goto out_dput;
230 : }
231 :
232 33290843 : if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
233 16 : error = -EPERM;
234 16 : goto out_dput;
235 : }
236 :
237 : /* Can't write directories. */
238 33290827 : if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
239 0 : error = -EISDIR;
240 0 : goto out_dput;
241 : }
242 :
243 33290827 : fd = get_unused_fd_flags(0);
244 33291450 : if (fd < 0) {
245 0 : error = fd;
246 0 : goto out_dput;
247 : }
248 :
249 33291450 : path.mnt = parfilp->f_path.mnt;
250 33291450 : path.dentry = dentry;
251 33291450 : filp = dentry_open(&path, hreq->oflags, cred);
252 33290930 : dput(dentry);
253 33290988 : if (IS_ERR(filp)) {
254 0 : put_unused_fd(fd);
255 0 : return PTR_ERR(filp);
256 : }
257 :
258 33290988 : if (S_ISREG(inode->i_mode)) {
259 22147193 : filp->f_flags |= O_NOATIME;
260 22147193 : filp->f_mode |= FMODE_NOCMTIME;
261 : }
262 :
263 33290988 : fd_install(fd, filp);
264 33290988 : return fd;
265 :
266 28 : out_dput:
267 28 : dput(dentry);
268 28 : return error;
269 : }
270 :
271 : int
272 184 : xfs_readlink_by_handle(
273 : struct file *parfilp,
274 : xfs_fsop_handlereq_t *hreq)
275 : {
276 184 : struct dentry *dentry;
277 184 : __u32 olen;
278 184 : int error;
279 :
280 184 : if (!capable(CAP_SYS_ADMIN))
281 : return -EPERM;
282 :
283 184 : dentry = xfs_handlereq_to_dentry(parfilp, hreq);
284 184 : if (IS_ERR(dentry))
285 0 : return PTR_ERR(dentry);
286 :
287 : /* Restrict this handle operation to symlinks only. */
288 184 : if (!d_is_symlink(dentry)) {
289 2 : error = -EINVAL;
290 2 : goto out_dput;
291 : }
292 :
293 182 : if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
294 0 : error = -EFAULT;
295 0 : goto out_dput;
296 : }
297 :
298 182 : error = vfs_readlink(dentry, hreq->ohandle, olen);
299 :
300 184 : out_dput:
301 184 : dput(dentry);
302 184 : return error;
303 : }
304 :
305 : /*
306 : * Format an attribute and copy it out to the user's buffer.
307 : * Take care to check values and protect against them changing later,
308 : * we may be reading them directly out of a user buffer.
309 : */
310 : static void
311 271239910 : xfs_ioc_attr_put_listent(
312 : struct xfs_attr_list_context *context,
313 : int flags,
314 : unsigned char *name,
315 : int namelen,
316 : void *value,
317 : int valuelen)
318 : {
319 271239910 : struct xfs_attrlist *alist = context->buffer;
320 271239910 : struct xfs_attrlist_ent *aep;
321 271239910 : int arraytop;
322 :
323 271239910 : ASSERT(!context->seen_enough);
324 271239910 : ASSERT(context->count >= 0);
325 271239910 : ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
326 271239910 : ASSERT(context->firstu >= sizeof(*alist));
327 271239910 : ASSERT(context->firstu <= context->bufsize);
328 :
329 : /*
330 : * Only list entries in the right namespace.
331 : */
332 271239910 : if (context->attr_filter != (flags & XFS_ATTR_NSP_ONDISK_MASK))
333 : return;
334 :
335 39378140 : arraytop = sizeof(*alist) +
336 39378140 : context->count * sizeof(alist->al_offset[0]);
337 :
338 : /* decrement by the actual bytes used by the attr */
339 39378140 : context->firstu -= round_up(offsetof(struct xfs_attrlist_ent, a_name) +
340 : namelen + 1, sizeof(uint32_t));
341 39378140 : if (context->firstu < arraytop) {
342 365 : trace_xfs_attr_list_full(context);
343 365 : alist->al_more = 1;
344 365 : context->seen_enough = 1;
345 365 : return;
346 : }
347 :
348 39377775 : aep = context->buffer + context->firstu;
349 39377775 : aep->a_valuelen = valuelen;
350 78755550 : memcpy(aep->a_name, name, namelen);
351 39377775 : aep->a_name[namelen] = 0;
352 39377775 : alist->al_offset[context->count++] = context->firstu;
353 39377775 : alist->al_count = context->count;
354 39377775 : trace_xfs_attr_list_add(context);
355 : }
356 :
357 : static unsigned int
358 : xfs_attr_filter(
359 : u32 ioc_flags)
360 : {
361 134917980 : if (ioc_flags & XFS_IOC_ATTR_ROOT)
362 : return XFS_ATTR_ROOT;
363 89942830 : if (ioc_flags & XFS_IOC_ATTR_SECURE)
364 44975407 : return XFS_ATTR_SECURE;
365 : return 0;
366 : }
367 :
368 : static unsigned int
369 : xfs_attr_flags(
370 : u32 ioc_flags)
371 : {
372 140 : if (ioc_flags & XFS_IOC_ATTR_CREATE)
373 : return XATTR_CREATE;
374 140 : if (ioc_flags & XFS_IOC_ATTR_REPLACE)
375 0 : return XATTR_REPLACE;
376 : return 0;
377 : }
378 :
379 : int
380 134912245 : xfs_ioc_attr_list(
381 : struct xfs_inode *dp,
382 : void __user *ubuf,
383 : size_t bufsize,
384 : int flags,
385 : struct xfs_attrlist_cursor __user *ucursor)
386 : {
387 134912245 : struct xfs_attr_list_context context = { };
388 134912245 : struct xfs_attrlist *alist;
389 134912245 : void *buffer;
390 134912245 : int error;
391 :
392 134912245 : if (bufsize < sizeof(struct xfs_attrlist) ||
393 : bufsize > XFS_XATTR_LIST_MAX)
394 : return -EINVAL;
395 :
396 : /*
397 : * Reject flags, only allow namespaces.
398 : */
399 134912245 : if (flags & ~(XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
400 : return -EINVAL;
401 134912245 : if (flags == (XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
402 : return -EINVAL;
403 :
404 : /*
405 : * Validate the cursor.
406 : */
407 134912245 : if (copy_from_user(&context.cursor, ucursor, sizeof(context.cursor)))
408 : return -EFAULT;
409 134916694 : if (context.cursor.pad1 || context.cursor.pad2)
410 : return -EINVAL;
411 134916694 : if (!context.cursor.initted &&
412 134916329 : (context.cursor.hashval || context.cursor.blkno ||
413 134916329 : context.cursor.offset))
414 : return -EINVAL;
415 :
416 134916694 : buffer = kvzalloc(bufsize, GFP_KERNEL);
417 134917840 : if (!buffer)
418 : return -ENOMEM;
419 :
420 : /*
421 : * Initialize the output buffer.
422 : */
423 134917840 : context.dp = dp;
424 134917840 : context.resynch = 1;
425 134917840 : context.attr_filter = xfs_attr_filter(flags);
426 134917840 : context.buffer = buffer;
427 134917840 : context.bufsize = round_down(bufsize, sizeof(uint32_t));
428 134917840 : context.firstu = context.bufsize;
429 134917840 : context.put_listent = xfs_ioc_attr_put_listent;
430 :
431 134917840 : alist = context.buffer;
432 134917840 : alist->al_count = 0;
433 134917840 : alist->al_more = 0;
434 134917840 : alist->al_offset[0] = context.bufsize;
435 :
436 134917840 : error = xfs_attr_list(&context);
437 134904492 : if (error)
438 0 : goto out_free;
439 :
440 404714082 : if (copy_to_user(ubuf, buffer, bufsize) ||
441 : copy_to_user(ucursor, &context.cursor, sizeof(context.cursor)))
442 : error = -EFAULT;
443 134910033 : out_free:
444 134910033 : kmem_free(buffer);
445 134910033 : return error;
446 : }
447 :
448 : STATIC int
449 134913826 : xfs_attrlist_by_handle(
450 : struct file *parfilp,
451 : struct xfs_fsop_attrlist_handlereq __user *p)
452 : {
453 134913826 : struct xfs_fsop_attrlist_handlereq al_hreq;
454 134913826 : struct dentry *dentry;
455 134913826 : int error = -ENOMEM;
456 :
457 134913826 : if (!capable(CAP_SYS_ADMIN))
458 : return -EPERM;
459 134915993 : if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
460 : return -EFAULT;
461 :
462 134917181 : dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
463 134905769 : if (IS_ERR(dentry))
464 167 : return PTR_ERR(dentry);
465 :
466 134905602 : error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
467 134905602 : al_hreq.buflen, al_hreq.flags, &p->pos);
468 134909726 : dput(dentry);
469 134909726 : return error;
470 : }
471 :
472 : static int
473 140 : xfs_attrmulti_attr_get(
474 : struct inode *inode,
475 : unsigned char *name,
476 : unsigned char __user *ubuf,
477 : uint32_t *len,
478 : uint32_t flags)
479 : {
480 420 : struct xfs_da_args args = {
481 : .dp = XFS_I(inode),
482 : .attr_filter = xfs_attr_filter(flags),
483 : .attr_flags = xfs_attr_flags(flags),
484 : .name = name,
485 : .namelen = strlen(name),
486 140 : .valuelen = *len,
487 140 : .owner = XFS_I(inode)->i_ino,
488 : };
489 140 : int error;
490 :
491 140 : if (*len > XFS_XATTR_SIZE_MAX)
492 : return -EINVAL;
493 :
494 140 : error = xfs_attr_get(&args);
495 140 : if (error)
496 0 : goto out_kfree;
497 :
498 140 : *len = args.valuelen;
499 280 : if (copy_to_user(ubuf, args.value, args.valuelen))
500 0 : error = -EFAULT;
501 :
502 140 : out_kfree:
503 140 : kmem_free(args.value);
504 140 : return error;
505 : }
506 :
507 : static int
508 0 : xfs_attrmulti_attr_set(
509 : struct inode *inode,
510 : unsigned char *name,
511 : const unsigned char __user *ubuf,
512 : uint32_t len,
513 : uint32_t flags)
514 : {
515 0 : struct xfs_da_args args = {
516 : .dp = XFS_I(inode),
517 : .attr_filter = xfs_attr_filter(flags),
518 : .attr_flags = xfs_attr_flags(flags),
519 : .name = name,
520 : .namelen = strlen(name),
521 0 : .owner = XFS_I(inode)->i_ino,
522 : };
523 0 : int error;
524 :
525 0 : if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
526 : return -EPERM;
527 :
528 0 : if (ubuf) {
529 0 : if (len > XFS_XATTR_SIZE_MAX)
530 : return -EINVAL;
531 0 : args.value = memdup_user(ubuf, len);
532 0 : if (IS_ERR(args.value))
533 0 : return PTR_ERR(args.value);
534 0 : args.valuelen = len;
535 : }
536 :
537 0 : error = xfs_attr_change(&args);
538 0 : if (!error && (flags & XFS_IOC_ATTR_ROOT))
539 0 : xfs_forget_acl(inode, name);
540 0 : kfree(args.value);
541 0 : return error;
542 : }
543 :
544 : int
545 140 : xfs_ioc_attrmulti_one(
546 : struct file *parfilp,
547 : struct inode *inode,
548 : uint32_t opcode,
549 : void __user *uname,
550 : void __user *value,
551 : uint32_t *len,
552 : uint32_t flags)
553 : {
554 140 : unsigned char *name;
555 140 : int error;
556 :
557 140 : if ((flags & XFS_IOC_ATTR_ROOT) && (flags & XFS_IOC_ATTR_SECURE))
558 : return -EINVAL;
559 :
560 140 : name = strndup_user(uname, MAXNAMELEN);
561 140 : if (IS_ERR(name))
562 0 : return PTR_ERR(name);
563 :
564 140 : switch (opcode) {
565 140 : case ATTR_OP_GET:
566 140 : error = xfs_attrmulti_attr_get(inode, name, value, len, flags);
567 140 : break;
568 0 : case ATTR_OP_REMOVE:
569 0 : value = NULL;
570 0 : *len = 0;
571 0 : fallthrough;
572 0 : case ATTR_OP_SET:
573 0 : error = mnt_want_write_file(parfilp);
574 0 : if (error)
575 : break;
576 0 : error = xfs_attrmulti_attr_set(inode, name, value, *len, flags);
577 0 : mnt_drop_write_file(parfilp);
578 0 : break;
579 : default:
580 : error = -EINVAL;
581 : break;
582 : }
583 :
584 140 : kfree(name);
585 140 : return error;
586 : }
587 :
588 : STATIC int
589 132 : xfs_attrmulti_by_handle(
590 : struct file *parfilp,
591 : void __user *arg)
592 : {
593 132 : int error;
594 132 : xfs_attr_multiop_t *ops;
595 132 : xfs_fsop_attrmulti_handlereq_t am_hreq;
596 132 : struct dentry *dentry;
597 132 : unsigned int i, size;
598 :
599 132 : if (!capable(CAP_SYS_ADMIN))
600 : return -EPERM;
601 132 : if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
602 : return -EFAULT;
603 :
604 : /* overflow check */
605 132 : if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t))
606 : return -E2BIG;
607 :
608 132 : dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
609 132 : if (IS_ERR(dentry))
610 0 : return PTR_ERR(dentry);
611 :
612 132 : error = -E2BIG;
613 132 : size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
614 132 : if (!size || size > 16 * PAGE_SIZE)
615 0 : goto out_dput;
616 :
617 132 : ops = memdup_user(am_hreq.ops, size);
618 132 : if (IS_ERR(ops)) {
619 0 : error = PTR_ERR(ops);
620 0 : goto out_dput;
621 : }
622 :
623 : error = 0;
624 272 : for (i = 0; i < am_hreq.opcount; i++) {
625 140 : ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
626 140 : d_inode(dentry), ops[i].am_opcode,
627 : ops[i].am_attrname, ops[i].am_attrvalue,
628 140 : &ops[i].am_length, ops[i].am_flags);
629 : }
630 :
631 264 : if (copy_to_user(am_hreq.ops, ops, size))
632 0 : error = -EFAULT;
633 :
634 132 : kfree(ops);
635 132 : out_dput:
636 132 : dput(dentry);
637 132 : return error;
638 : }
639 :
640 : /* Return 0 on success or positive error */
641 : int
642 68814237307 : xfs_fsbulkstat_one_fmt(
643 : struct xfs_ibulk *breq,
644 : const struct xfs_bulkstat *bstat)
645 : {
646 68814237307 : struct xfs_bstat bs1;
647 :
648 68814237307 : xfs_bulkstat_to_bstat(breq->mp, &bs1, bstat);
649 68841402096 : if (copy_to_user(breq->ubuffer, &bs1, sizeof(bs1)))
650 : return -EFAULT;
651 68760304474 : return xfs_ibulk_advance(breq, sizeof(struct xfs_bstat));
652 : }
653 :
654 : int
655 11596 : xfs_fsinumbers_fmt(
656 : struct xfs_ibulk *breq,
657 : const struct xfs_inumbers *igrp)
658 : {
659 11596 : struct xfs_inogrp ig1;
660 :
661 11596 : xfs_inumbers_to_inogrp(&ig1, igrp);
662 11596 : if (copy_to_user(breq->ubuffer, &ig1, sizeof(struct xfs_inogrp)))
663 : return -EFAULT;
664 11596 : return xfs_ibulk_advance(breq, sizeof(struct xfs_inogrp));
665 : }
666 :
667 : STATIC int
668 450691340 : xfs_ioc_fsbulkstat(
669 : struct file *file,
670 : unsigned int cmd,
671 : void __user *arg)
672 : {
673 450691340 : struct xfs_mount *mp = XFS_I(file_inode(file))->i_mount;
674 450691340 : struct xfs_fsop_bulkreq bulkreq;
675 450691340 : struct xfs_ibulk breq = {
676 : .mp = mp,
677 : .idmap = file_mnt_idmap(file),
678 : .ocount = 0,
679 : };
680 450706070 : xfs_ino_t lastino;
681 450706070 : int error;
682 :
683 : /* done = 1 if there are more stats to get and if bulkstat */
684 : /* should be called again (unused here, but used in dmapi) */
685 :
686 450706070 : if (!capable(CAP_SYS_ADMIN))
687 : return -EPERM;
688 :
689 901361602 : if (xfs_is_shutdown(mp))
690 : return -EIO;
691 :
692 450667333 : if (copy_from_user(&bulkreq, arg, sizeof(struct xfs_fsop_bulkreq)))
693 : return -EFAULT;
694 :
695 450676729 : if (copy_from_user(&lastino, bulkreq.lastip, sizeof(__s64)))
696 : return -EFAULT;
697 :
698 450681444 : if (bulkreq.icount <= 0)
699 : return -EINVAL;
700 :
701 450681444 : if (bulkreq.ubuffer == NULL)
702 : return -EINVAL;
703 :
704 450681444 : breq.ubuffer = bulkreq.ubuffer;
705 450681444 : breq.icount = bulkreq.icount;
706 :
707 : /*
708 : * FSBULKSTAT_SINGLE expects that *lastip contains the inode number
709 : * that we want to stat. However, FSINUMBERS and FSBULKSTAT expect
710 : * that *lastip contains either zero or the number of the last inode to
711 : * be examined by the previous call and return results starting with
712 : * the next inode after that. The new bulk request back end functions
713 : * take the inode to start with, so we have to compute the startino
714 : * parameter from lastino to maintain correct function. lastino == 0
715 : * is a special case because it has traditionally meant "first inode
716 : * in filesystem".
717 : */
718 450681444 : if (cmd == XFS_IOC_FSINUMBERS) {
719 3074 : breq.startino = lastino ? lastino + 1 : 0;
720 3074 : error = xfs_inumbers(&breq, xfs_fsinumbers_fmt);
721 3074 : lastino = breq.startino - 1;
722 450678370 : } else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) {
723 1402961 : breq.startino = lastino;
724 1402961 : breq.icount = 1;
725 1402961 : error = xfs_bulkstat_one(&breq, xfs_fsbulkstat_one_fmt);
726 : } else { /* XFS_IOC_FSBULKSTAT */
727 449275409 : breq.startino = lastino ? lastino + 1 : 0;
728 449275409 : error = xfs_bulkstat(&breq, xfs_fsbulkstat_one_fmt);
729 449247851 : lastino = breq.startino - 1;
730 : }
731 :
732 450653887 : if (error)
733 : return error;
734 :
735 899891022 : if (bulkreq.lastip != NULL &&
736 : copy_to_user(bulkreq.lastip, &lastino, sizeof(xfs_ino_t)))
737 : return -EFAULT;
738 :
739 899222101 : if (bulkreq.ocount != NULL &&
740 : copy_to_user(bulkreq.ocount, &breq.ocount, sizeof(__s32)))
741 0 : return -EFAULT;
742 :
743 : return 0;
744 : }
745 :
746 : /* Return 0 on success or positive error */
747 : static int
748 157272966 : xfs_bulkstat_fmt(
749 : struct xfs_ibulk *breq,
750 : const struct xfs_bulkstat *bstat)
751 : {
752 314542691 : if (copy_to_user(breq->ubuffer, bstat, sizeof(struct xfs_bulkstat)))
753 0 : return -EFAULT;
754 157269725 : return xfs_ibulk_advance(breq, sizeof(struct xfs_bulkstat));
755 : }
756 :
757 : /*
758 : * Check the incoming bulk request @hdr from userspace and initialize the
759 : * internal @breq bulk request appropriately. Returns 0 if the bulk request
760 : * should proceed; -ECANCELED if there's nothing to do; or the usual
761 : * negative error code.
762 : */
763 : static int
764 8270311 : xfs_bulk_ireq_setup(
765 : struct xfs_mount *mp,
766 : const struct xfs_bulk_ireq *hdr,
767 : struct xfs_ibulk *breq,
768 : void __user *ubuffer)
769 : {
770 8270311 : if (hdr->icount == 0 ||
771 16541730 : (hdr->flags & ~XFS_BULK_IREQ_FLAGS_ALL) ||
772 8270311 : memchr_inv(hdr->reserved, 0, sizeof(hdr->reserved)))
773 0 : return -EINVAL;
774 :
775 8271419 : breq->startino = hdr->ino;
776 8271419 : breq->ubuffer = ubuffer;
777 8271419 : breq->icount = hdr->icount;
778 8271419 : breq->ocount = 0;
779 8271419 : breq->flags = 0;
780 :
781 : /*
782 : * The @ino parameter is a special value, so we must look it up here.
783 : * We're not allowed to have IREQ_AGNO, and we only return one inode
784 : * worth of data.
785 : */
786 8271419 : if (hdr->flags & XFS_BULK_IREQ_SPECIAL) {
787 4 : if (hdr->flags & XFS_BULK_IREQ_AGNO)
788 : return -EINVAL;
789 :
790 4 : switch (hdr->ino) {
791 4 : case XFS_BULK_IREQ_SPECIAL_ROOT:
792 4 : breq->startino = mp->m_sb.sb_rootino;
793 4 : break;
794 : default:
795 : return -EINVAL;
796 : }
797 4 : breq->icount = 1;
798 : }
799 :
800 : /*
801 : * The IREQ_AGNO flag means that we only want results from a given AG.
802 : * If @hdr->ino is zero, we start iterating in that AG. If @hdr->ino is
803 : * beyond the specified AG then we return no results.
804 : */
805 8271419 : if (hdr->flags & XFS_BULK_IREQ_AGNO) {
806 2627314 : if (hdr->agno >= mp->m_sb.sb_agcount)
807 : return -EINVAL;
808 :
809 2627314 : if (breq->startino == 0)
810 135242 : breq->startino = XFS_AGINO_TO_INO(mp, hdr->agno, 0);
811 2492072 : else if (XFS_INO_TO_AGNO(mp, breq->startino) < hdr->agno)
812 : return -EINVAL;
813 :
814 2627314 : breq->flags |= XFS_IBULK_SAME_AG;
815 :
816 : /* Asking for an inode past the end of the AG? We're done! */
817 2627314 : if (XFS_INO_TO_AGNO(mp, breq->startino) > hdr->agno)
818 : return -ECANCELED;
819 5644105 : } else if (hdr->agno)
820 : return -EINVAL;
821 :
822 : /* Asking for an inode past the end of the FS? We're done! */
823 8271419 : if (XFS_INO_TO_AGNO(mp, breq->startino) >= mp->m_sb.sb_agcount)
824 : return -ECANCELED;
825 :
826 8271409 : if (hdr->flags & XFS_BULK_IREQ_NREXT64)
827 5659979 : breq->flags |= XFS_IBULK_NREXT64;
828 :
829 : /* Caller wants to see metadata directories in bulkstat output. */
830 8271409 : if (hdr->flags & XFS_BULK_IREQ_METADIR)
831 1774187 : breq->flags |= XFS_IBULK_METADIR;
832 :
833 : return 0;
834 : }
835 :
836 : /*
837 : * Update the userspace bulk request @hdr to reflect the end state of the
838 : * internal bulk request @breq.
839 : */
840 : static void
841 : xfs_bulk_ireq_teardown(
842 : struct xfs_bulk_ireq *hdr,
843 : struct xfs_ibulk *breq)
844 : {
845 8271578 : hdr->ino = breq->startino;
846 8271578 : hdr->ocount = breq->ocount;
847 : }
848 :
849 : /* Handle the v5 bulkstat ioctl. */
850 : STATIC int
851 5659927 : xfs_ioc_bulkstat(
852 : struct file *file,
853 : unsigned int cmd,
854 : struct xfs_bulkstat_req __user *arg)
855 : {
856 5659927 : struct xfs_mount *mp = XFS_I(file_inode(file))->i_mount;
857 5659927 : struct xfs_bulk_ireq hdr;
858 5659927 : struct xfs_ibulk breq = {
859 : .mp = mp,
860 : .idmap = file_mnt_idmap(file),
861 : };
862 5660064 : int error;
863 :
864 5660064 : if (!capable(CAP_SYS_ADMIN))
865 : return -EPERM;
866 :
867 11320056 : if (xfs_is_shutdown(mp))
868 : return -EIO;
869 :
870 5660028 : if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))
871 : return -EFAULT;
872 :
873 5660030 : error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->bulkstat);
874 5660034 : if (error == -ECANCELED)
875 10 : goto out_teardown;
876 5660024 : if (error < 0)
877 : return error;
878 :
879 5660024 : error = xfs_bulkstat(&breq, xfs_bulkstat_fmt);
880 5660036 : if (error)
881 : return error;
882 :
883 5660034 : out_teardown:
884 5660044 : xfs_bulk_ireq_teardown(&hdr, &breq);
885 5660044 : if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))
886 0 : return -EFAULT;
887 :
888 : return 0;
889 : }
890 :
891 : STATIC int
892 3941807 : xfs_inumbers_fmt(
893 : struct xfs_ibulk *breq,
894 : const struct xfs_inumbers *igrp)
895 : {
896 7884680 : if (copy_to_user(breq->ubuffer, igrp, sizeof(struct xfs_inumbers)))
897 0 : return -EFAULT;
898 3942873 : return xfs_ibulk_advance(breq, sizeof(struct xfs_inumbers));
899 : }
900 :
901 : /* Handle the v5 inumbers ioctl. */
902 : STATIC int
903 2611652 : xfs_ioc_inumbers(
904 : struct xfs_mount *mp,
905 : unsigned int cmd,
906 : struct xfs_inumbers_req __user *arg)
907 : {
908 2611652 : struct xfs_bulk_ireq hdr;
909 2611652 : struct xfs_ibulk breq = {
910 : .mp = mp,
911 : };
912 2611652 : int error;
913 :
914 2611652 : if (!capable(CAP_SYS_ADMIN))
915 : return -EPERM;
916 :
917 5222026 : if (xfs_is_shutdown(mp))
918 : return -EIO;
919 :
920 2611013 : if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))
921 : return -EFAULT;
922 :
923 2611544 : if (hdr.flags & XFS_BULK_IREQ_METADIR)
924 : return -EINVAL;
925 :
926 2611544 : error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->inumbers);
927 2611537 : if (error == -ECANCELED)
928 0 : goto out_teardown;
929 2611537 : if (error < 0)
930 : return error;
931 :
932 2611537 : error = xfs_inumbers(&breq, xfs_inumbers_fmt);
933 2611534 : if (error)
934 : return error;
935 :
936 2611534 : out_teardown:
937 2611534 : xfs_bulk_ireq_teardown(&hdr, &breq);
938 2611534 : if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))
939 0 : return -EFAULT;
940 :
941 : return 0;
942 : }
943 :
944 : STATIC int
945 2049051 : xfs_ioc_fsgeometry(
946 : struct xfs_mount *mp,
947 : void __user *arg,
948 : int struct_version)
949 : {
950 2049051 : struct xfs_fsop_geom fsgeo;
951 2049051 : size_t len;
952 :
953 2049051 : xfs_fs_geometry(mp, &fsgeo, struct_version);
954 :
955 2048953 : if (struct_version <= 3)
956 : len = sizeof(struct xfs_fsop_geom_v1);
957 2048821 : else if (struct_version == 4)
958 : len = sizeof(struct xfs_fsop_geom_v4);
959 : else {
960 2048784 : xfs_fsop_geom_health(mp, &fsgeo);
961 2048784 : len = sizeof(fsgeo);
962 : }
963 :
964 4118060 : if (copy_to_user(arg, &fsgeo, len))
965 0 : return -EFAULT;
966 : return 0;
967 : }
968 :
969 : STATIC int
970 15595 : xfs_ioc_ag_geometry(
971 : struct xfs_mount *mp,
972 : void __user *arg)
973 : {
974 15595 : struct xfs_perag *pag;
975 15595 : struct xfs_ag_geometry ageo;
976 15595 : int error;
977 :
978 15595 : if (copy_from_user(&ageo, arg, sizeof(ageo)))
979 : return -EFAULT;
980 15595 : if (ageo.ag_flags & ~XFS_AG_FLAG_ALL)
981 : return -EINVAL;
982 15595 : if (memchr_inv(&ageo.ag_reserved, 0, sizeof(ageo.ag_reserved)))
983 : return -EINVAL;
984 15595 : if ((ageo.ag_flags & XFS_AG_FLAG_UPDATE) && !capable(CAP_SYS_ADMIN))
985 : return -EPERM;
986 :
987 15595 : pag = xfs_perag_get(mp, ageo.ag_number);
988 15595 : if (!pag)
989 : return -EINVAL;
990 :
991 15595 : error = xfs_ag_get_geometry(pag, &ageo);
992 15595 : xfs_perag_put(pag);
993 15595 : if (error)
994 : return error;
995 :
996 15595 : if (copy_to_user(arg, &ageo, sizeof(ageo)))
997 0 : return -EFAULT;
998 : return 0;
999 : }
1000 :
1001 : STATIC int
1002 396 : xfs_ioc_rtgroup_geometry(
1003 : struct xfs_mount *mp,
1004 : void __user *arg)
1005 : {
1006 396 : struct xfs_rtgroup *rtg;
1007 396 : struct xfs_rtgroup_geometry rgeo;
1008 396 : int error;
1009 :
1010 396 : if (copy_from_user(&rgeo, arg, sizeof(rgeo)))
1011 : return -EFAULT;
1012 396 : if (rgeo.rg_flags || rgeo.rg_pad)
1013 : return -EINVAL;
1014 396 : if (memchr_inv(&rgeo.rg_reserved, 0, sizeof(rgeo.rg_reserved)))
1015 : return -EINVAL;
1016 :
1017 396 : rtg = xfs_rtgroup_get(mp, rgeo.rg_number);
1018 396 : if (!rtg)
1019 : return -EINVAL;
1020 :
1021 396 : error = xfs_rtgroup_get_geometry(rtg, &rgeo);
1022 396 : xfs_rtgroup_put(rtg);
1023 396 : if (error)
1024 : return error;
1025 :
1026 396 : if (copy_to_user(arg, &rgeo, sizeof(rgeo)))
1027 0 : return -EFAULT;
1028 : return 0;
1029 : }
1030 :
1031 : /*
1032 : * Linux extended inode flags interface.
1033 : */
1034 :
1035 : static void
1036 3246839 : xfs_fill_fsxattr(
1037 : struct xfs_inode *ip,
1038 : int whichfork,
1039 : struct fileattr *fa)
1040 : {
1041 3246839 : struct xfs_mount *mp = ip->i_mount;
1042 3246839 : struct xfs_ifork *ifp = xfs_ifork_ptr(ip, whichfork);
1043 :
1044 3246827 : fileattr_fill_xflags(fa, xfs_ip2xflags(ip));
1045 :
1046 3246824 : if (ip->i_diflags & XFS_DIFLAG_EXTSIZE) {
1047 35 : fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
1048 3246789 : } else if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
1049 : /*
1050 : * Don't let a misaligned extent size hint on a directory
1051 : * escape to userspace if it won't pass the setattr checks
1052 : * later.
1053 : */
1054 8 : if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
1055 0 : xfs_extlen_to_rtxmod(mp, ip->i_extsize) > 0) {
1056 0 : fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE |
1057 : FS_XFLAG_EXTSZINHERIT);
1058 0 : fa->fsx_extsize = 0;
1059 : } else {
1060 8 : fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
1061 : }
1062 : }
1063 :
1064 3246824 : if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) {
1065 : /*
1066 : * Don't let a misaligned CoW extent size hint on a directory
1067 : * escape to userspace if it won't pass the setattr checks
1068 : * later.
1069 : */
1070 255 : if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
1071 0 : ip->i_cowextsize % mp->m_sb.sb_rextsize > 0) {
1072 0 : fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
1073 0 : fa->fsx_cowextsize = 0;
1074 : } else {
1075 255 : fa->fsx_cowextsize = XFS_FSB_TO_B(mp, ip->i_cowextsize);
1076 : }
1077 : }
1078 :
1079 3246824 : fa->fsx_projid = ip->i_projid;
1080 6490080 : if (ifp && !xfs_need_iread_extents(ifp))
1081 3231773 : fa->fsx_nextents = xfs_iext_count(ifp);
1082 : else
1083 26571 : fa->fsx_nextents = xfs_ifork_nextents(ifp);
1084 3246808 : }
1085 :
1086 : STATIC int
1087 5216 : xfs_ioc_fsgetxattra(
1088 : xfs_inode_t *ip,
1089 : void __user *arg)
1090 : {
1091 5216 : struct fileattr fa;
1092 :
1093 5216 : xfs_ilock(ip, XFS_ILOCK_SHARED);
1094 5216 : xfs_fill_fsxattr(ip, XFS_ATTR_FORK, &fa);
1095 5216 : xfs_iunlock(ip, XFS_ILOCK_SHARED);
1096 :
1097 5216 : return copy_fsxattr_to_user(&fa, arg);
1098 : }
1099 :
1100 : int
1101 3241639 : xfs_fileattr_get(
1102 : struct dentry *dentry,
1103 : struct fileattr *fa)
1104 : {
1105 3241639 : struct xfs_inode *ip = XFS_I(d_inode(dentry));
1106 :
1107 3241639 : if (d_is_special(dentry))
1108 : return -ENOTTY;
1109 :
1110 3241639 : xfs_ilock(ip, XFS_ILOCK_SHARED);
1111 3241620 : xfs_fill_fsxattr(ip, XFS_DATA_FORK, fa);
1112 3241594 : xfs_iunlock(ip, XFS_ILOCK_SHARED);
1113 :
1114 3241594 : return 0;
1115 : }
1116 :
1117 : static int
1118 671461 : xfs_ioctl_setattr_xflags(
1119 : struct xfs_trans *tp,
1120 : struct xfs_inode *ip,
1121 : struct fileattr *fa)
1122 : {
1123 671461 : struct xfs_mount *mp = ip->i_mount;
1124 671461 : uint64_t i_flags2;
1125 :
1126 : /* Can't change realtime flag if any extents are allocated. */
1127 671461 : if ((ip->i_df.if_nextents || ip->i_delayed_blks) &&
1128 814086 : XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME))
1129 : return -EINVAL;
1130 :
1131 : /* If realtime flag is set then must have realtime device */
1132 671461 : if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
1133 376536 : if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
1134 188268 : xfs_extlen_to_rtxmod(mp, ip->i_extsize))
1135 : return -EINVAL;
1136 : }
1137 :
1138 : /* diflags2 only valid for v3 inodes. */
1139 671461 : i_flags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
1140 671460 : if (i_flags2 && !xfs_has_v3inodes(mp))
1141 : return -EINVAL;
1142 :
1143 671460 : ip->i_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
1144 671460 : ip->i_diflags2 = i_flags2;
1145 :
1146 671460 : xfs_diflags_to_iflags(ip, false);
1147 671461 : xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1148 671460 : xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1149 671461 : XFS_STATS_INC(mp, xs_ig_attrchg);
1150 671461 : return 0;
1151 : }
1152 :
1153 : static void
1154 671466 : xfs_ioctl_setattr_prepare_dax(
1155 : struct xfs_inode *ip,
1156 : struct fileattr *fa)
1157 : {
1158 671466 : struct xfs_mount *mp = ip->i_mount;
1159 671466 : struct inode *inode = VFS_I(ip);
1160 :
1161 671466 : if (S_ISDIR(inode->i_mode))
1162 : return;
1163 :
1164 663716 : if (xfs_has_dax_always(mp) || xfs_has_dax_never(mp))
1165 : return;
1166 :
1167 663716 : if (((fa->fsx_xflags & FS_XFLAG_DAX) &&
1168 663716 : !(ip->i_diflags2 & XFS_DIFLAG2_DAX)) ||
1169 663714 : (!(fa->fsx_xflags & FS_XFLAG_DAX) &&
1170 663714 : (ip->i_diflags2 & XFS_DIFLAG2_DAX)))
1171 4 : d_mark_dontcache(inode);
1172 : }
1173 :
1174 : /*
1175 : * Set up the transaction structure for the setattr operation, checking that we
1176 : * have permission to do so. On success, return a clean transaction and the
1177 : * inode locked exclusively ready for further operation specific checks. On
1178 : * failure, return an error without modifying or locking the inode.
1179 : */
1180 : static struct xfs_trans *
1181 671466 : xfs_ioctl_setattr_get_trans(
1182 : struct xfs_inode *ip,
1183 : struct xfs_dquot *pdqp)
1184 : {
1185 671466 : struct xfs_mount *mp = ip->i_mount;
1186 671466 : struct xfs_trans *tp;
1187 671466 : int error = -EROFS;
1188 :
1189 1342932 : if (xfs_is_readonly(mp))
1190 0 : goto out_error;
1191 671466 : error = -EIO;
1192 1342932 : if (xfs_is_shutdown(mp))
1193 0 : goto out_error;
1194 :
1195 671466 : error = xfs_trans_alloc_ichange(ip, NULL, NULL, pdqp,
1196 : has_capability_noaudit(current, CAP_FOWNER), &tp);
1197 671464 : if (error)
1198 0 : goto out_error;
1199 :
1200 671464 : if (xfs_has_wsync(mp))
1201 152 : xfs_trans_set_sync(tp);
1202 :
1203 671464 : return tp;
1204 :
1205 0 : out_error:
1206 0 : return ERR_PTR(error);
1207 : }
1208 :
1209 : /*
1210 : * Validate a proposed extent size hint. For regular files, the hint can only
1211 : * be changed if no extents are allocated.
1212 : */
1213 : static int
1214 671465 : xfs_ioctl_setattr_check_extsize(
1215 : struct xfs_inode *ip,
1216 : struct fileattr *fa)
1217 : {
1218 671465 : struct xfs_mount *mp = ip->i_mount;
1219 671465 : xfs_failaddr_t failaddr;
1220 671465 : uint16_t new_diflags;
1221 :
1222 671465 : if (!fa->fsx_valid)
1223 : return 0;
1224 :
1225 601727 : if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents &&
1226 471202 : XFS_FSB_TO_B(mp, ip->i_extsize) != fa->fsx_extsize)
1227 : return -EINVAL;
1228 :
1229 601725 : if (fa->fsx_extsize & mp->m_blockmask)
1230 : return -EINVAL;
1231 :
1232 601723 : new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
1233 :
1234 : /*
1235 : * Inode verifiers do not check that the extent size hint is an integer
1236 : * multiple of the rt extent size on a directory with both rtinherit
1237 : * and extszinherit flags set. Don't let sysadmins misconfigure
1238 : * directories.
1239 : */
1240 601722 : if ((new_diflags & XFS_DIFLAG_RTINHERIT) &&
1241 : (new_diflags & XFS_DIFLAG_EXTSZINHERIT)) {
1242 0 : unsigned int rtextsize_bytes;
1243 :
1244 0 : rtextsize_bytes = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize);
1245 0 : if (fa->fsx_extsize % rtextsize_bytes)
1246 : return -EINVAL;
1247 : }
1248 :
1249 601722 : failaddr = xfs_inode_validate_extsize(ip->i_mount,
1250 601722 : XFS_B_TO_FSB(mp, fa->fsx_extsize),
1251 : VFS_I(ip)->i_mode, new_diflags);
1252 601722 : return failaddr != NULL ? -EINVAL : 0;
1253 : }
1254 :
1255 : static int
1256 671461 : xfs_ioctl_setattr_check_cowextsize(
1257 : struct xfs_inode *ip,
1258 : struct fileattr *fa)
1259 : {
1260 671461 : struct xfs_mount *mp = ip->i_mount;
1261 671461 : xfs_failaddr_t failaddr;
1262 671461 : uint64_t new_diflags2;
1263 671461 : uint16_t new_diflags;
1264 :
1265 671461 : if (!fa->fsx_valid)
1266 : return 0;
1267 :
1268 601723 : if (fa->fsx_cowextsize & mp->m_blockmask)
1269 : return -EINVAL;
1270 :
1271 601723 : new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
1272 601723 : new_diflags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
1273 :
1274 601724 : failaddr = xfs_inode_validate_cowextsize(ip->i_mount,
1275 601724 : XFS_B_TO_FSB(mp, fa->fsx_cowextsize),
1276 : VFS_I(ip)->i_mode, new_diflags, new_diflags2);
1277 601723 : return failaddr != NULL ? -EINVAL : 0;
1278 : }
1279 :
1280 : static int
1281 : xfs_ioctl_setattr_check_projid(
1282 : struct xfs_inode *ip,
1283 : struct fileattr *fa)
1284 : {
1285 672542 : if (!fa->fsx_valid)
1286 : return 0;
1287 :
1288 : /* Disallow 32bit project ids if 32bit IDs are not enabled. */
1289 602805 : if (fa->fsx_projid > (uint16_t)-1 &&
1290 0 : !xfs_has_projid32(ip->i_mount))
1291 : return -EINVAL;
1292 : return 0;
1293 : }
1294 :
1295 : int
1296 687104 : xfs_fileattr_set(
1297 : struct mnt_idmap *idmap,
1298 : struct dentry *dentry,
1299 : struct fileattr *fa)
1300 : {
1301 687104 : struct xfs_inode *ip = XFS_I(d_inode(dentry));
1302 687104 : struct xfs_mount *mp = ip->i_mount;
1303 687104 : struct xfs_trans *tp;
1304 687104 : struct xfs_dquot *pdqp = NULL;
1305 687104 : struct xfs_dquot *olddquot = NULL;
1306 687104 : int error;
1307 :
1308 687104 : trace_xfs_ioctl_setattr(ip);
1309 :
1310 687103 : if (d_is_special(dentry))
1311 : return -ENOTTY;
1312 :
1313 687103 : if (!fa->fsx_valid) {
1314 84299 : if (fa->flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL |
1315 : FS_NOATIME_FL | FS_NODUMP_FL |
1316 : FS_SYNC_FL | FS_DAX_FL | FS_PROJINHERIT_FL))
1317 : return -EOPNOTSUPP;
1318 : }
1319 :
1320 672542 : error = xfs_ioctl_setattr_check_projid(ip, fa);
1321 : if (error)
1322 : return error;
1323 :
1324 : /*
1325 : * If disk quotas is on, we make sure that the dquots do exist on disk,
1326 : * before we start any other transactions. Trying to do this later
1327 : * is messy. We don't care to take a readlock to look at the ids
1328 : * in inode here, because we can't hold it across the trans_reserve.
1329 : * If the IDs do change before we take the ilock, we're covered
1330 : * because the i_*dquot fields will get updated anyway.
1331 : */
1332 672542 : if (fa->fsx_valid && XFS_IS_QUOTA_ON(mp)) {
1333 591910 : error = xfs_qm_vop_dqalloc(ip, VFS_I(ip)->i_uid,
1334 : VFS_I(ip)->i_gid, fa->fsx_projid,
1335 : XFS_QMOPT_PQUOTA, NULL, NULL, &pdqp);
1336 591911 : if (error)
1337 : return error;
1338 : }
1339 :
1340 671466 : xfs_ioctl_setattr_prepare_dax(ip, fa);
1341 :
1342 671466 : tp = xfs_ioctl_setattr_get_trans(ip, pdqp);
1343 671464 : if (IS_ERR(tp)) {
1344 0 : error = PTR_ERR(tp);
1345 0 : goto error_free_dquots;
1346 : }
1347 :
1348 671464 : error = xfs_ioctl_setattr_check_extsize(ip, fa);
1349 671464 : if (error)
1350 4 : goto error_trans_cancel;
1351 :
1352 671460 : error = xfs_ioctl_setattr_check_cowextsize(ip, fa);
1353 671461 : if (error)
1354 0 : goto error_trans_cancel;
1355 :
1356 671461 : error = xfs_ioctl_setattr_xflags(tp, ip, fa);
1357 671462 : if (error)
1358 0 : goto error_trans_cancel;
1359 :
1360 671462 : if (!fa->fsx_valid)
1361 69738 : goto skip_xattr;
1362 : /*
1363 : * Change file ownership. Must be the owner or privileged. CAP_FSETID
1364 : * overrides the following restrictions:
1365 : *
1366 : * The set-user-ID and set-group-ID bits of a file will be cleared upon
1367 : * successful return from chown()
1368 : */
1369 :
1370 601732 : if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&
1371 8 : !capable_wrt_inode_uidgid(idmap, VFS_I(ip), CAP_FSETID))
1372 0 : VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);
1373 :
1374 : /* Change the ownerships and register project quota modifications */
1375 601724 : if (ip->i_projid != fa->fsx_projid) {
1376 526746 : if (XFS_IS_PQUOTA_ON(mp)) {
1377 516987 : olddquot = xfs_qm_vop_chown(tp, ip,
1378 : &ip->i_pdquot, pdqp);
1379 : }
1380 526746 : ip->i_projid = fa->fsx_projid;
1381 : }
1382 :
1383 : /*
1384 : * Only set the extent size hint if we've already determined that the
1385 : * extent size hint should be set on the inode. If no extent size flags
1386 : * are set on the inode then unconditionally clear the extent size hint.
1387 : */
1388 601724 : if (ip->i_diflags & (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))
1389 33 : ip->i_extsize = XFS_B_TO_FSB(mp, fa->fsx_extsize);
1390 : else
1391 601691 : ip->i_extsize = 0;
1392 :
1393 601724 : if (xfs_has_v3inodes(mp)) {
1394 601724 : if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
1395 137 : ip->i_cowextsize = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
1396 : else
1397 601587 : ip->i_cowextsize = 0;
1398 : }
1399 :
1400 0 : skip_xattr:
1401 671462 : error = xfs_trans_commit(tp);
1402 :
1403 : /*
1404 : * Release any dquot(s) the inode had kept before chown.
1405 : */
1406 671461 : xfs_qm_dqrele(olddquot);
1407 671461 : xfs_qm_dqrele(pdqp);
1408 :
1409 671461 : return error;
1410 :
1411 4 : error_trans_cancel:
1412 4 : xfs_trans_cancel(tp);
1413 4 : error_free_dquots:
1414 4 : xfs_qm_dqrele(pdqp);
1415 4 : return error;
1416 : }
1417 :
1418 : static bool
1419 5416358 : xfs_getbmap_format(
1420 : struct kgetbmap *p,
1421 : struct getbmapx __user *u,
1422 : size_t recsize)
1423 : {
1424 5416358 : if (put_user(p->bmv_offset, &u->bmv_offset) ||
1425 5416353 : put_user(p->bmv_block, &u->bmv_block) ||
1426 5416405 : put_user(p->bmv_length, &u->bmv_length) ||
1427 5416380 : put_user(0, &u->bmv_count) ||
1428 5416351 : put_user(0, &u->bmv_entries))
1429 5 : return false;
1430 5416354 : if (recsize < sizeof(struct getbmapx))
1431 : return true;
1432 5279092 : if (put_user(0, &u->bmv_iflags) ||
1433 5279100 : put_user(p->bmv_oflags, &u->bmv_oflags) ||
1434 5279067 : put_user(0, &u->bmv_unused1) ||
1435 5279086 : put_user(0, &u->bmv_unused2))
1436 24 : return false;
1437 : return true;
1438 : }
1439 :
1440 : STATIC int
1441 1196120 : xfs_ioc_getbmap(
1442 : struct file *file,
1443 : unsigned int cmd,
1444 : void __user *arg)
1445 : {
1446 1196120 : struct getbmapx bmx = { 0 };
1447 1196120 : struct kgetbmap *buf;
1448 1196120 : size_t recsize;
1449 1196120 : int error, i;
1450 :
1451 1196120 : switch (cmd) {
1452 0 : case XFS_IOC_GETBMAPA:
1453 0 : bmx.bmv_iflags = BMV_IF_ATTRFORK;
1454 : fallthrough;
1455 : case XFS_IOC_GETBMAP:
1456 : /* struct getbmap is a strict subset of struct getbmapx. */
1457 : recsize = sizeof(struct getbmap);
1458 : break;
1459 : case XFS_IOC_GETBMAPX:
1460 : recsize = sizeof(struct getbmapx);
1461 : break;
1462 : default:
1463 : return -EINVAL;
1464 : }
1465 :
1466 2392171 : if (copy_from_user(&bmx, arg, recsize))
1467 : return -EFAULT;
1468 :
1469 1196051 : if (bmx.bmv_count < 2)
1470 : return -EINVAL;
1471 1196051 : if (bmx.bmv_count >= INT_MAX / recsize)
1472 : return -ENOMEM;
1473 :
1474 1196051 : buf = kvcalloc(bmx.bmv_count, sizeof(*buf), GFP_KERNEL);
1475 1196050 : if (!buf)
1476 : return -ENOMEM;
1477 :
1478 1196050 : error = xfs_getbmap(XFS_I(file_inode(file)), &bmx, buf);
1479 1196077 : if (error)
1480 0 : goto out_free_buf;
1481 :
1482 1196077 : error = -EFAULT;
1483 2392162 : if (copy_to_user(arg, &bmx, recsize))
1484 0 : goto out_free_buf;
1485 1196085 : arg += recsize;
1486 :
1487 6612425 : for (i = 0; i < bmx.bmv_entries; i++) {
1488 5416370 : if (!xfs_getbmap_format(buf + i, arg, recsize))
1489 0 : goto out_free_buf;
1490 5416340 : arg += recsize;
1491 : }
1492 :
1493 : error = 0;
1494 1196055 : out_free_buf:
1495 1196055 : kmem_free(buf);
1496 1196055 : return error;
1497 : }
1498 :
1499 : STATIC int
1500 95045 : xfs_ioc_getfsmap(
1501 : struct xfs_inode *ip,
1502 : struct fsmap_head __user *arg)
1503 : {
1504 95045 : struct xfs_fsmap_head xhead = {0};
1505 95045 : struct fsmap_head head;
1506 95045 : struct fsmap *recs;
1507 95045 : unsigned int count;
1508 95045 : __u32 last_flags = 0;
1509 95045 : bool done = false;
1510 95045 : int error;
1511 :
1512 95045 : if (copy_from_user(&head, arg, sizeof(struct fsmap_head)))
1513 : return -EFAULT;
1514 189488 : if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) ||
1515 : memchr_inv(head.fmh_keys[0].fmr_reserved, 0,
1516 94682 : sizeof(head.fmh_keys[0].fmr_reserved)) ||
1517 : memchr_inv(head.fmh_keys[1].fmr_reserved, 0,
1518 : sizeof(head.fmh_keys[1].fmr_reserved)))
1519 0 : return -EINVAL;
1520 :
1521 : /*
1522 : * Use an internal memory buffer so that we don't have to copy fsmap
1523 : * data to userspace while holding locks. Start by trying to allocate
1524 : * up to 128k for the buffer, but fall back to a single page if needed.
1525 : */
1526 94682 : count = min_t(unsigned int, head.fmh_count,
1527 : 131072 / sizeof(struct fsmap));
1528 94682 : recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL);
1529 94778 : if (!recs) {
1530 0 : count = min_t(unsigned int, head.fmh_count,
1531 : PAGE_SIZE / sizeof(struct fsmap));
1532 0 : recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL);
1533 0 : if (!recs)
1534 : return -ENOMEM;
1535 : }
1536 :
1537 94778 : xhead.fmh_iflags = head.fmh_iflags;
1538 94778 : xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]);
1539 94586 : xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]);
1540 :
1541 94598 : trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
1542 94587 : trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]);
1543 :
1544 94792 : head.fmh_entries = 0;
1545 135939 : do {
1546 135939 : struct fsmap __user *user_recs;
1547 135939 : struct fsmap *last_rec;
1548 :
1549 135939 : user_recs = &arg->fmh_recs[head.fmh_entries];
1550 135939 : xhead.fmh_entries = 0;
1551 135939 : xhead.fmh_count = min_t(unsigned int, count,
1552 : head.fmh_count - head.fmh_entries);
1553 :
1554 : /* Run query, record how many entries we got. */
1555 135939 : error = xfs_getfsmap(ip->i_mount, &xhead, recs);
1556 136196 : switch (error) {
1557 : case 0:
1558 : /*
1559 : * There are no more records in the result set. Copy
1560 : * whatever we got to userspace and break out.
1561 : */
1562 : done = true;
1563 : break;
1564 59366 : case -ECANCELED:
1565 : /*
1566 : * The internal memory buffer is full. Copy whatever
1567 : * records we got to userspace and go again if we have
1568 : * not yet filled the userspace buffer.
1569 : */
1570 59366 : error = 0;
1571 59366 : break;
1572 0 : default:
1573 0 : goto out_free;
1574 : }
1575 136196 : head.fmh_entries += xhead.fmh_entries;
1576 136196 : head.fmh_oflags = xhead.fmh_oflags;
1577 :
1578 : /*
1579 : * If the caller wanted a record count or there aren't any
1580 : * new records to return, we're done.
1581 : */
1582 136196 : if (head.fmh_count == 0 || xhead.fmh_entries == 0)
1583 : break;
1584 :
1585 : /* Copy all the records we got out to userspace. */
1586 136199 : if (copy_to_user(user_recs, recs,
1587 136196 : xhead.fmh_entries * sizeof(struct fsmap))) {
1588 0 : error = -EFAULT;
1589 0 : goto out_free;
1590 : }
1591 :
1592 : /* Remember the last record flags we copied to userspace. */
1593 136199 : last_rec = &recs[xhead.fmh_entries - 1];
1594 136199 : last_flags = last_rec->fmr_flags;
1595 :
1596 : /* Set up the low key for the next iteration. */
1597 136199 : xfs_fsmap_to_internal(&xhead.fmh_keys[0], last_rec);
1598 136204 : trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
1599 136199 : } while (!done && head.fmh_entries < head.fmh_count);
1600 :
1601 : /*
1602 : * If there are no more records in the query result set and we're not
1603 : * in counting mode, mark the last record returned with the LAST flag.
1604 : */
1605 95052 : if (done && head.fmh_count > 0 && head.fmh_entries > 0) {
1606 76830 : struct fsmap __user *user_rec;
1607 :
1608 76830 : last_flags |= FMR_OF_LAST;
1609 76830 : user_rec = &arg->fmh_recs[head.fmh_entries - 1];
1610 :
1611 76830 : if (copy_to_user(&user_rec->fmr_flags, &last_flags,
1612 : sizeof(last_flags))) {
1613 0 : error = -EFAULT;
1614 0 : goto out_free;
1615 : }
1616 : }
1617 :
1618 : /* copy back header */
1619 95049 : if (copy_to_user(arg, &head, sizeof(struct fsmap_head))) {
1620 0 : error = -EFAULT;
1621 0 : goto out_free;
1622 : }
1623 :
1624 95043 : out_free:
1625 95043 : kmem_free(recs);
1626 95043 : return error;
1627 : }
1628 :
1629 : STATIC int
1630 1011 : xfs_ioc_getfsrefcounts(
1631 : struct xfs_inode *ip,
1632 : struct xfs_getfsrefs_head __user *arg)
1633 : {
1634 1011 : struct xfs_fsrefs_head xhead = {0};
1635 1011 : struct xfs_getfsrefs_head head;
1636 1011 : struct xfs_getfsrefs *recs;
1637 1011 : unsigned int count;
1638 1011 : __u32 last_flags = 0;
1639 1011 : bool done = false;
1640 1011 : int error;
1641 :
1642 1011 : if (copy_from_user(&head, arg, sizeof(struct xfs_getfsrefs_head)))
1643 : return -EFAULT;
1644 2022 : if (memchr_inv(head.fch_reserved, 0, sizeof(head.fch_reserved)) ||
1645 : memchr_inv(head.fch_keys[0].fcr_reserved, 0,
1646 1011 : sizeof(head.fch_keys[0].fcr_reserved)) ||
1647 : memchr_inv(head.fch_keys[1].fcr_reserved, 0,
1648 : sizeof(head.fch_keys[1].fcr_reserved)))
1649 0 : return -EINVAL;
1650 :
1651 : /*
1652 : * Use an internal memory buffer so that we don't have to copy fsrefs
1653 : * data to userspace while holding locks. Start by trying to allocate
1654 : * up to 128k for the buffer, but fall back to a single page if needed.
1655 : */
1656 1011 : count = min_t(unsigned int, head.fch_count,
1657 : 131072 / sizeof(struct xfs_getfsrefs));
1658 1011 : recs = kvzalloc(count * sizeof(struct xfs_getfsrefs), GFP_KERNEL);
1659 1011 : if (!recs) {
1660 0 : count = min_t(unsigned int, head.fch_count,
1661 : PAGE_SIZE / sizeof(struct xfs_getfsrefs));
1662 0 : recs = kvzalloc(count * sizeof(struct xfs_getfsrefs),
1663 : GFP_KERNEL);
1664 0 : if (!recs)
1665 : return -ENOMEM;
1666 : }
1667 :
1668 1011 : xhead.fch_iflags = head.fch_iflags;
1669 1011 : xfs_fsrefs_to_internal(&xhead.fch_keys[0], &head.fch_keys[0]);
1670 1011 : xfs_fsrefs_to_internal(&xhead.fch_keys[1], &head.fch_keys[1]);
1671 :
1672 1011 : trace_xfs_getfsrefs_low_key(ip->i_mount, &xhead.fch_keys[0]);
1673 1011 : trace_xfs_getfsrefs_high_key(ip->i_mount, &xhead.fch_keys[1]);
1674 :
1675 1011 : head.fch_entries = 0;
1676 1011 : do {
1677 1011 : struct xfs_getfsrefs __user *user_recs;
1678 1011 : struct xfs_getfsrefs *last_rec;
1679 :
1680 1011 : user_recs = &arg->fch_recs[head.fch_entries];
1681 1011 : xhead.fch_entries = 0;
1682 1011 : xhead.fch_count = min_t(unsigned int, count,
1683 : head.fch_count - head.fch_entries);
1684 :
1685 : /* Run query, record how many entries we got. */
1686 1011 : error = xfs_getfsrefs(ip->i_mount, &xhead, recs);
1687 1011 : switch (error) {
1688 : case 0:
1689 : /*
1690 : * There are no more records in the result set. Copy
1691 : * whatever we got to userspace and break out.
1692 : */
1693 : done = true;
1694 : break;
1695 1005 : case -ECANCELED:
1696 : /*
1697 : * The internal memory buffer is full. Copy whatever
1698 : * records we got to userspace and go again if we have
1699 : * not yet filled the userspace buffer.
1700 : */
1701 1005 : error = 0;
1702 1005 : break;
1703 0 : default:
1704 0 : goto out_free;
1705 : }
1706 1011 : head.fch_entries += xhead.fch_entries;
1707 1011 : head.fch_oflags = xhead.fch_oflags;
1708 :
1709 : /*
1710 : * If the caller wanted a record count or there aren't any
1711 : * new records to return, we're done.
1712 : */
1713 1011 : if (head.fch_count == 0 || xhead.fch_entries == 0)
1714 : break;
1715 :
1716 : /* Copy all the records we got out to userspace. */
1717 1011 : if (copy_to_user(user_recs, recs,
1718 1011 : xhead.fch_entries * sizeof(struct xfs_getfsrefs))) {
1719 0 : error = -EFAULT;
1720 0 : goto out_free;
1721 : }
1722 :
1723 : /* Remember the last record flags we copied to userspace. */
1724 1011 : last_rec = &recs[xhead.fch_entries - 1];
1725 1011 : last_flags = last_rec->fcr_flags;
1726 :
1727 : /* Set up the low key for the next iteration. */
1728 1011 : xfs_fsrefs_to_internal(&xhead.fch_keys[0], last_rec);
1729 1011 : trace_xfs_getfsrefs_low_key(ip->i_mount, &xhead.fch_keys[0]);
1730 1011 : } while (!done && head.fch_entries < head.fch_count);
1731 :
1732 : /*
1733 : * If there are no more records in the query result set and we're not
1734 : * in counting mode, mark the last record returned with the LAST flag.
1735 : */
1736 1011 : if (done && head.fch_count > 0 && head.fch_entries > 0) {
1737 6 : struct xfs_getfsrefs __user *user_rec;
1738 :
1739 6 : last_flags |= FCR_OF_LAST;
1740 6 : user_rec = &arg->fch_recs[head.fch_entries - 1];
1741 :
1742 6 : if (copy_to_user(&user_rec->fcr_flags, &last_flags,
1743 : sizeof(last_flags))) {
1744 0 : error = -EFAULT;
1745 0 : goto out_free;
1746 : }
1747 : }
1748 :
1749 : /* copy back header */
1750 1011 : if (copy_to_user(arg, &head, sizeof(struct xfs_getfsrefs_head))) {
1751 0 : error = -EFAULT;
1752 0 : goto out_free;
1753 : }
1754 :
1755 1011 : out_free:
1756 1011 : kmem_free(recs);
1757 1011 : return error;
1758 : }
1759 :
1760 : STATIC int
1761 2689436 : xfs_ioc_scrub_metadata(
1762 : struct file *file,
1763 : void __user *arg)
1764 : {
1765 2689436 : struct xfs_scrub_metadata scrub;
1766 2689436 : int error;
1767 :
1768 2689436 : if (!capable(CAP_SYS_ADMIN))
1769 : return -EPERM;
1770 :
1771 2689436 : if (copy_from_user(&scrub, arg, sizeof(scrub)))
1772 : return -EFAULT;
1773 :
1774 2689436 : error = xfs_scrub_metadata(file, &scrub);
1775 2689436 : if (error)
1776 : return error;
1777 :
1778 2664380 : if (copy_to_user(arg, &scrub, sizeof(scrub)))
1779 0 : return -EFAULT;
1780 :
1781 : return 0;
1782 : }
1783 :
1784 : /*
1785 : * IOCTL routine to get the parent pointers of an inode and return it to user
1786 : * space. Caller must pass a buffer space containing a struct xfs_getparents,
1787 : * followed by a region large enough to contain an array of struct
1788 : * xfs_getparents_rec of a size specified in gp_bufsize. If the inode contains
1789 : * more parent pointers than can fit in the buffer space, caller may re-call
1790 : * the function using the returned gp_cursor to resume iteration. The
1791 : * number of xfs_getparents_rec returned will be stored in gp_count.
1792 : *
1793 : * Returns 0 on success or non-zero on failure
1794 : */
1795 : STATIC int
1796 36289764 : xfs_ioc_get_parent_pointer(
1797 : struct file *filp,
1798 : void __user *arg)
1799 : {
1800 36289764 : struct xfs_getparents *ppi = NULL;
1801 36289764 : int error = 0;
1802 36289764 : struct xfs_inode *file_ip = XFS_I(file_inode(filp));
1803 36289764 : struct xfs_inode *call_ip = file_ip;
1804 36289764 : struct xfs_mount *mp = file_ip->i_mount;
1805 36289764 : void __user *o_pptr;
1806 36289764 : struct xfs_getparents_rec *i_pptr;
1807 36289764 : unsigned int bytes;
1808 :
1809 36289764 : if (!capable(CAP_SYS_ADMIN))
1810 : return -EPERM;
1811 :
1812 : /* Allocate an xfs_getparents to put the user data */
1813 36290483 : ppi = kvmalloc(sizeof(struct xfs_getparents), GFP_KERNEL);
1814 36290659 : if (!ppi)
1815 : return -ENOMEM;
1816 :
1817 : /* Copy the data from the user */
1818 36290659 : error = copy_from_user(ppi, arg, sizeof(struct xfs_getparents));
1819 36290621 : if (error) {
1820 0 : error = -EFAULT;
1821 0 : goto out;
1822 : }
1823 :
1824 : /* Check size of buffer requested by user */
1825 36290621 : if (ppi->gp_bufsize > XFS_XATTR_LIST_MAX) {
1826 0 : error = -ENOMEM;
1827 0 : goto out;
1828 : }
1829 36290621 : if (ppi->gp_bufsize < sizeof(struct xfs_getparents)) {
1830 0 : error = -EINVAL;
1831 0 : goto out;
1832 : }
1833 :
1834 36290621 : if (ppi->gp_flags & ~XFS_GETPARENTS_FLAG_ALL) {
1835 0 : error = -EINVAL;
1836 0 : goto out;
1837 : }
1838 36290621 : ppi->gp_flags &= ~(XFS_GETPARENTS_OFLAG_ROOT | XFS_GETPARENTS_OFLAG_DONE);
1839 :
1840 : /*
1841 : * Now that we know how big the trailing buffer is, expand
1842 : * our kernel xfs_getparents to be the same size
1843 : */
1844 36290621 : ppi = kvrealloc(ppi, sizeof(struct xfs_getparents), ppi->gp_bufsize,
1845 : GFP_KERNEL | __GFP_ZERO);
1846 36284726 : if (!ppi)
1847 : return -ENOMEM;
1848 :
1849 36284726 : if (ppi->gp_flags & XFS_GETPARENTS_IFLAG_HANDLE) {
1850 36284292 : struct xfs_handle *hanp = &ppi->gp_handle;
1851 :
1852 72568584 : if (memcmp(&hanp->ha_fsid, mp->m_fixedfsid,
1853 : sizeof(xfs_fsid_t))) {
1854 0 : error = -EINVAL;
1855 0 : goto out;
1856 : }
1857 :
1858 36284292 : if (hanp->ha_fid.fid_ino != file_ip->i_ino) {
1859 34230758 : error = xfs_iget(mp, NULL, hanp->ha_fid.fid_ino,
1860 : XFS_IGET_UNTRUSTED, 0, &call_ip);
1861 34234688 : if (error)
1862 175 : goto out;
1863 : }
1864 :
1865 36288047 : if (VFS_I(call_ip)->i_generation != hanp->ha_fid.fid_gen) {
1866 19927 : error = -EINVAL;
1867 19927 : goto out;
1868 : }
1869 : }
1870 :
1871 : /* Get the parent pointers */
1872 36268554 : error = xfs_getparent_pointers(call_ip, ppi);
1873 36270374 : if (error)
1874 0 : goto out;
1875 :
1876 : /*
1877 : * If we ran out of buffer space before copying any parent pointers at
1878 : * all, the caller's buffer was too short. Tell userspace that, erm,
1879 : * the message is too long.
1880 : */
1881 36270374 : if (ppi->gp_count == 0 && !(ppi->gp_flags & XFS_GETPARENTS_OFLAG_DONE)) {
1882 0 : error = -EMSGSIZE;
1883 0 : goto out;
1884 : }
1885 :
1886 : /* Copy the parent pointer head back to the user */
1887 36270374 : bytes = xfs_getparents_arraytop(ppi, ppi->gp_count);
1888 36270374 : error = copy_to_user(arg, ppi, bytes);
1889 36269756 : if (error) {
1890 0 : error = -EFAULT;
1891 0 : goto out;
1892 : }
1893 :
1894 36269756 : if (ppi->gp_count == 0)
1895 2091478 : goto out;
1896 :
1897 : /* Copy the parent pointer records back to the user. */
1898 34178278 : o_pptr = (__user char*)arg + ppi->gp_offsets[ppi->gp_count - 1];
1899 34178278 : i_pptr = xfs_getparents_rec(ppi, ppi->gp_count - 1);
1900 34178278 : bytes = ((char *)ppi + ppi->gp_bufsize) - (char *)i_pptr;
1901 34178278 : error = copy_to_user(o_pptr, i_pptr, bytes);
1902 34177745 : if (error) {
1903 0 : error = -EFAULT;
1904 0 : goto out;
1905 : }
1906 :
1907 34177745 : out:
1908 36289325 : if (call_ip != file_ip)
1909 34235689 : xfs_irele(call_ip);
1910 36289414 : kvfree(ppi);
1911 36289414 : return error;
1912 : }
1913 :
1914 : int
1915 0 : xfs_ioc_swapext(
1916 : struct xfs_swapext *sxp)
1917 : {
1918 0 : struct xfs_exch_range fxr = { 0 };
1919 0 : struct fd fd2, fd1;
1920 0 : int error = 0;
1921 :
1922 0 : fd2 = fdget((int)sxp->sx_fdtarget);
1923 0 : if (!fd2.file)
1924 : return -EINVAL;
1925 :
1926 0 : fd1 = fdget((int)sxp->sx_fdtmp);
1927 0 : if (!fd1.file) {
1928 0 : error = -EINVAL;
1929 0 : goto dest_fdput;
1930 : }
1931 :
1932 0 : fxr.file1_fd = sxp->sx_fdtmp;
1933 0 : fxr.length = sxp->sx_length;
1934 0 : fxr.flags = XFS_EXCH_RANGE_NONATOMIC | XFS_EXCH_RANGE_FILE2_FRESH |
1935 : XFS_EXCH_RANGE_FULL_FILES;
1936 0 : fxr.file2_ino = sxp->sx_stat.bs_ino;
1937 0 : fxr.file2_mtime = sxp->sx_stat.bs_mtime.tv_sec;
1938 0 : fxr.file2_ctime = sxp->sx_stat.bs_ctime.tv_sec;
1939 0 : fxr.file2_mtime_nsec = sxp->sx_stat.bs_mtime.tv_nsec;
1940 0 : fxr.file2_ctime_nsec = sxp->sx_stat.bs_ctime.tv_nsec;
1941 :
1942 0 : error = xfs_exch_range(fd1.file, fd2.file, &fxr);
1943 :
1944 : /*
1945 : * The old implementation returned EFAULT if the swap range was not
1946 : * the entirety of both files.
1947 : */
1948 0 : if (error == -EDOM)
1949 0 : error = -EFAULT;
1950 0 : fdput(fd1);
1951 0 : dest_fdput:
1952 0 : fdput(fd2);
1953 0 : return error;
1954 : }
1955 :
1956 : static int
1957 7058 : xfs_ioc_getlabel(
1958 : struct xfs_mount *mp,
1959 : char __user *user_label)
1960 : {
1961 7058 : struct xfs_sb *sbp = &mp->m_sb;
1962 7058 : char label[XFSLABEL_MAX + 1];
1963 :
1964 : /* Paranoia */
1965 7058 : BUILD_BUG_ON(sizeof(sbp->sb_fname) > FSLABEL_MAX);
1966 :
1967 : /* 1 larger than sb_fname, so this ensures a trailing NUL char */
1968 7058 : memset(label, 0, sizeof(label));
1969 7058 : spin_lock(&mp->m_sb_lock);
1970 7058 : strncpy(label, sbp->sb_fname, XFSLABEL_MAX);
1971 7058 : spin_unlock(&mp->m_sb_lock);
1972 :
1973 7058 : if (copy_to_user(user_label, label, sizeof(label)))
1974 0 : return -EFAULT;
1975 : return 0;
1976 : }
1977 :
1978 : static int
1979 54 : xfs_ioc_setlabel(
1980 : struct file *filp,
1981 : struct xfs_mount *mp,
1982 : char __user *newlabel)
1983 : {
1984 54 : struct xfs_sb *sbp = &mp->m_sb;
1985 54 : struct block_device *bdev = xfs_buftarg_bdev(mp->m_ddev_targp);
1986 54 : char label[XFSLABEL_MAX + 1];
1987 54 : size_t len;
1988 54 : int error;
1989 :
1990 54 : if (!capable(CAP_SYS_ADMIN))
1991 : return -EPERM;
1992 : /*
1993 : * The generic ioctl allows up to FSLABEL_MAX chars, but XFS is much
1994 : * smaller, at 12 bytes. We copy one more to be sure we find the
1995 : * (required) NULL character to test the incoming label length.
1996 : * NB: The on disk label doesn't need to be null terminated.
1997 : */
1998 54 : if (copy_from_user(label, newlabel, XFSLABEL_MAX + 1))
1999 : return -EFAULT;
2000 54 : len = strnlen(label, XFSLABEL_MAX + 1);
2001 54 : if (len > sizeof(sbp->sb_fname))
2002 : return -EINVAL;
2003 :
2004 52 : error = mnt_want_write_file(filp);
2005 52 : if (error)
2006 : return error;
2007 :
2008 52 : spin_lock(&mp->m_sb_lock);
2009 52 : memset(sbp->sb_fname, 0, sizeof(sbp->sb_fname));
2010 104 : memcpy(sbp->sb_fname, label, len);
2011 52 : spin_unlock(&mp->m_sb_lock);
2012 :
2013 : /*
2014 : * Now we do several things to satisfy userspace.
2015 : * In addition to normal logging of the primary superblock, we also
2016 : * immediately write these changes to sector zero for the primary, then
2017 : * update all backup supers (as xfs_db does for a label change), then
2018 : * invalidate the block device page cache. This is so that any prior
2019 : * buffered reads from userspace (i.e. from blkid) are invalidated,
2020 : * and userspace will see the newly-written label.
2021 : */
2022 52 : error = xfs_sync_sb_buf(mp);
2023 52 : if (error)
2024 0 : goto out;
2025 : /*
2026 : * growfs also updates backup supers so lock against that.
2027 : */
2028 52 : mutex_lock(&mp->m_growlock);
2029 52 : error = xfs_update_secondary_sbs(mp);
2030 52 : if (!error)
2031 52 : error = xfs_rtgroup_update_secondary_sbs(mp);
2032 52 : mutex_unlock(&mp->m_growlock);
2033 :
2034 52 : invalidate_bdev(bdev);
2035 :
2036 52 : out:
2037 52 : mnt_drop_write_file(filp);
2038 52 : return error;
2039 : }
2040 :
2041 : STATIC int
2042 89747449 : xfs_ioc_scrubv_metadata(
2043 : struct file *filp,
2044 : void __user *arg)
2045 : {
2046 89747449 : struct xfs_scrub_vec_head __user *uhead = arg;
2047 89747449 : struct xfs_scrub_vec_head head;
2048 89747449 : struct xfs_scrub_vec_head *vhead;
2049 89747449 : size_t bytes;
2050 89747449 : int error;
2051 :
2052 89747449 : if (!capable(CAP_SYS_ADMIN))
2053 : return -EPERM;
2054 :
2055 89747867 : if (copy_from_user(&head, uhead, sizeof(head)))
2056 : return -EFAULT;
2057 :
2058 89748724 : bytes = sizeof_xfs_scrub_vec(head.svh_nr);
2059 89748724 : if (bytes > PAGE_SIZE)
2060 : return -ENOMEM;
2061 89748724 : vhead = kvmalloc(bytes, GFP_KERNEL | __GFP_RETRY_MAYFAIL);
2062 89748945 : if (!vhead)
2063 : return -ENOMEM;
2064 179497890 : memcpy(vhead, &head, sizeof(struct xfs_scrub_vec_head));
2065 :
2066 89748498 : if (copy_from_user(&vhead->svh_vecs, &uhead->svh_vecs,
2067 89748945 : head.svh_nr * sizeof(struct xfs_scrub_vec))) {
2068 0 : error = -EFAULT;
2069 0 : goto err_free;
2070 : }
2071 :
2072 89748498 : error = xfs_scrubv_metadata(filp, vhead);
2073 89749620 : if (error)
2074 79 : goto err_free;
2075 :
2076 179499682 : if (copy_to_user(uhead, vhead, bytes)) {
2077 0 : error = -EFAULT;
2078 0 : goto err_free;
2079 : }
2080 :
2081 89750141 : err_free:
2082 89750220 : kvfree(vhead);
2083 89750220 : return error;
2084 : }
2085 :
2086 : #define XFS_ADDFEATURE_SUPPORTED (XFS_FSOP_GEOM_FLAGS_INOBTCNT | \
2087 : XFS_FSOP_GEOM_FLAGS_BIGTIME | \
2088 : XFS_FSOP_GEOM_FLAGS_NREXT64)
2089 : static int
2090 0 : xfs_ioc_addfeature(
2091 : struct file *filp,
2092 : struct xfs_mount *mp,
2093 : __u64 __user *uflags)
2094 : {
2095 0 : struct xfs_sb *sbp = &mp->m_sb;
2096 0 : struct block_device *bdev = xfs_buftarg_bdev(mp->m_ddev_targp);
2097 0 : __u64 flags;
2098 0 : bool dirty = false;
2099 0 : int error = 0;
2100 :
2101 0 : if (!capable(CAP_SYS_ADMIN))
2102 : return -EPERM;
2103 :
2104 0 : if (copy_from_user(&flags, uflags, sizeof(__u64)))
2105 : return -EFAULT;
2106 :
2107 0 : if (flags & ~XFS_ADDFEATURE_SUPPORTED)
2108 : return -EINVAL;
2109 :
2110 0 : error = mnt_want_write_file(filp);
2111 0 : if (error)
2112 : return error;
2113 :
2114 0 : spin_lock(&mp->m_sb_lock);
2115 0 : if ((flags & XFS_FSOP_GEOM_FLAGS_BIGTIME) && !xfs_has_bigtime(mp)) {
2116 0 : xfs_info(mp, "Adding bigtime feature.");
2117 0 : sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME;
2118 0 : mp->m_features |= XFS_FEAT_BIGTIME;
2119 0 : dirty = true;
2120 : }
2121 0 : if ((flags & XFS_FSOP_GEOM_FLAGS_INOBTCNT) &&
2122 : !xfs_has_inobtcounts(mp)) {
2123 0 : xfs_info(mp, "Adding inobtcount feature.");
2124 0 : sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
2125 0 : mp->m_features |= XFS_FEAT_INOBTCNT;
2126 0 : dirty = true;
2127 : }
2128 0 : if ((flags & XFS_FSOP_GEOM_FLAGS_NREXT64) &&
2129 : !xfs_has_large_extent_counts(mp)) {
2130 0 : xfs_info(mp, "Adding nrext64 feature.");
2131 0 : sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NREXT64;
2132 0 : mp->m_features |= XFS_FEAT_NREXT64;
2133 0 : dirty = true;
2134 : }
2135 0 : spin_unlock(&mp->m_sb_lock);
2136 :
2137 0 : if (!dirty)
2138 0 : goto out;
2139 :
2140 : /*
2141 : * Now we do several things to satisfy userspace.
2142 : * In addition to normal logging of the primary superblock, we also
2143 : * immediately write these changes to sector zero for the primary, then
2144 : * update all backup supers (as xfs_db does for a label change), then
2145 : * invalidate the block device page cache. This is so that any prior
2146 : * buffered reads from userspace (i.e. from blkid) are invalidated,
2147 : * and userspace will see the newly-written label.
2148 : */
2149 0 : error = xfs_sync_sb_buf(mp);
2150 0 : if (error)
2151 0 : goto out;
2152 : /*
2153 : * growfs also updates backup supers so lock against that.
2154 : */
2155 0 : mutex_lock(&mp->m_growlock);
2156 0 : error = xfs_update_secondary_sbs(mp);
2157 0 : mutex_unlock(&mp->m_growlock);
2158 :
2159 0 : invalidate_bdev(bdev);
2160 :
2161 0 : out:
2162 0 : mnt_drop_write_file(filp);
2163 0 : return error;
2164 : }
2165 :
2166 : static inline int
2167 0 : xfs_fs_eofblocks_from_user(
2168 : struct xfs_fs_eofblocks *src,
2169 : struct xfs_icwalk *dst)
2170 : {
2171 0 : if (src->eof_version != XFS_EOFBLOCKS_VERSION)
2172 : return -EINVAL;
2173 :
2174 0 : if (src->eof_flags & ~XFS_EOF_FLAGS_VALID)
2175 : return -EINVAL;
2176 :
2177 0 : if (memchr_inv(&src->pad32, 0, sizeof(src->pad32)) ||
2178 0 : memchr_inv(src->pad64, 0, sizeof(src->pad64)))
2179 0 : return -EINVAL;
2180 :
2181 0 : dst->icw_flags = 0;
2182 0 : if (src->eof_flags & XFS_EOF_FLAGS_SYNC)
2183 0 : dst->icw_flags |= XFS_ICWALK_FLAG_SYNC;
2184 0 : if (src->eof_flags & XFS_EOF_FLAGS_UID)
2185 0 : dst->icw_flags |= XFS_ICWALK_FLAG_UID;
2186 0 : if (src->eof_flags & XFS_EOF_FLAGS_GID)
2187 0 : dst->icw_flags |= XFS_ICWALK_FLAG_GID;
2188 0 : if (src->eof_flags & XFS_EOF_FLAGS_PRID)
2189 0 : dst->icw_flags |= XFS_ICWALK_FLAG_PRID;
2190 0 : if (src->eof_flags & XFS_EOF_FLAGS_MINFILESIZE)
2191 0 : dst->icw_flags |= XFS_ICWALK_FLAG_MINFILESIZE;
2192 :
2193 0 : dst->icw_prid = src->eof_prid;
2194 0 : dst->icw_min_file_size = src->eof_min_file_size;
2195 :
2196 0 : dst->icw_uid = INVALID_UID;
2197 0 : if (src->eof_flags & XFS_EOF_FLAGS_UID) {
2198 0 : dst->icw_uid = make_kuid(current_user_ns(), src->eof_uid);
2199 0 : if (!uid_valid(dst->icw_uid))
2200 : return -EINVAL;
2201 : }
2202 :
2203 0 : dst->icw_gid = INVALID_GID;
2204 0 : if (src->eof_flags & XFS_EOF_FLAGS_GID) {
2205 0 : dst->icw_gid = make_kgid(current_user_ns(), src->eof_gid);
2206 0 : if (!gid_valid(dst->icw_gid))
2207 0 : return -EINVAL;
2208 : }
2209 : return 0;
2210 : }
2211 :
2212 : static long
2213 2313621 : xfs_ioc_exchange_range(
2214 : struct file *file2,
2215 : struct xfs_exch_range __user *argp)
2216 : {
2217 2313621 : struct xfs_exch_range args;
2218 2313621 : struct fd file1;
2219 2313621 : int error;
2220 :
2221 2313621 : if (copy_from_user(&args, argp, sizeof(args)))
2222 : return -EFAULT;
2223 :
2224 2313618 : file1 = fdget(args.file1_fd);
2225 2313619 : if (!file1.file)
2226 : return -EBADF;
2227 :
2228 2313619 : error = -EXDEV;
2229 2313619 : if (file1.file->f_path.mnt != file2->f_path.mnt)
2230 4 : goto fdput;
2231 :
2232 2313615 : error = xfs_exch_range(file1.file, file2, &args);
2233 2313615 : fdput:
2234 2313615 : fdput(file1);
2235 2313615 : return error;
2236 : }
2237 :
2238 : /*
2239 : * These long-unused ioctls were removed from the official ioctl API in 5.17,
2240 : * but retain these definitions so that we can log warnings about them.
2241 : */
2242 : #define XFS_IOC_ALLOCSP _IOW ('X', 10, struct xfs_flock64)
2243 : #define XFS_IOC_FREESP _IOW ('X', 11, struct xfs_flock64)
2244 : #define XFS_IOC_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64)
2245 : #define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64)
2246 :
2247 : /*
2248 : * Note: some of the ioctl's return positive numbers as a
2249 : * byte count indicating success, such as readlink_by_handle.
2250 : * So we don't "sign flip" like most other routines. This means
2251 : * true errors need to be returned as a negative value.
2252 : */
2253 : long
2254 773823385 : xfs_file_ioctl(
2255 : struct file *filp,
2256 : unsigned int cmd,
2257 : unsigned long p)
2258 : {
2259 773823385 : struct inode *inode = file_inode(filp);
2260 773823385 : struct xfs_inode *ip = XFS_I(inode);
2261 773823385 : struct xfs_mount *mp = ip->i_mount;
2262 773823385 : void __user *arg = (void __user *)p;
2263 773823385 : int error;
2264 :
2265 773823385 : trace_xfs_file_ioctl(ip);
2266 :
2267 773865391 : switch (cmd) {
2268 39469 : case FITRIM:
2269 39469 : return xfs_ioc_trim(mp, arg);
2270 7058 : case FS_IOC_GETFSLABEL:
2271 7058 : return xfs_ioc_getlabel(mp, arg);
2272 54 : case FS_IOC_SETFSLABEL:
2273 54 : return xfs_ioc_setlabel(filp, mp, arg);
2274 0 : case XFS_IOC_ADDFEATURE:
2275 0 : return xfs_ioc_addfeature(filp, mp, arg);
2276 : case XFS_IOC_ALLOCSP:
2277 : case XFS_IOC_FREESP:
2278 : case XFS_IOC_ALLOCSP64:
2279 : case XFS_IOC_FREESP64:
2280 2 : xfs_warn_once(mp,
2281 : "%s should use fallocate; XFS_IOC_{ALLOC,FREE}SP ioctl unsupported",
2282 : current->comm);
2283 : return -ENOTTY;
2284 12131443 : case XFS_IOC_DIOINFO: {
2285 12131443 : struct xfs_buftarg *target = xfs_inode_buftarg(ip);
2286 12131443 : struct dioattr da;
2287 :
2288 12131443 : da.d_mem = da.d_miniosz = target->bt_logical_sectorsize;
2289 12131443 : da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
2290 :
2291 12131443 : if (copy_to_user(arg, &da, sizeof(da)))
2292 0 : return -EFAULT;
2293 : return 0;
2294 : }
2295 :
2296 450696976 : case XFS_IOC_FSBULKSTAT_SINGLE:
2297 : case XFS_IOC_FSBULKSTAT:
2298 : case XFS_IOC_FSINUMBERS:
2299 450696976 : return xfs_ioc_fsbulkstat(filp, cmd, arg);
2300 :
2301 5660035 : case XFS_IOC_BULKSTAT:
2302 5660035 : return xfs_ioc_bulkstat(filp, cmd, arg);
2303 2611631 : case XFS_IOC_INUMBERS:
2304 2611631 : return xfs_ioc_inumbers(mp, cmd, arg);
2305 :
2306 144 : case XFS_IOC_FSGEOMETRY_V1:
2307 144 : return xfs_ioc_fsgeometry(mp, arg, 3);
2308 0 : case XFS_IOC_FSGEOMETRY_V4:
2309 0 : return xfs_ioc_fsgeometry(mp, arg, 4);
2310 2051862 : case XFS_IOC_FSGEOMETRY:
2311 2051862 : return xfs_ioc_fsgeometry(mp, arg, 5);
2312 :
2313 15595 : case XFS_IOC_AG_GEOMETRY:
2314 15595 : return xfs_ioc_ag_geometry(mp, arg);
2315 396 : case XFS_IOC_RTGROUP_GEOMETRY:
2316 396 : return xfs_ioc_rtgroup_geometry(mp, arg);
2317 :
2318 0 : case XFS_IOC_GETVERSION:
2319 0 : return put_user(inode->i_generation, (int __user *)arg);
2320 :
2321 5216 : case XFS_IOC_FSGETXATTRA:
2322 5216 : return xfs_ioc_fsgetxattra(ip, arg);
2323 36290603 : case XFS_IOC_GETPARENTS:
2324 36290603 : return xfs_ioc_get_parent_pointer(filp, arg);
2325 1196056 : case XFS_IOC_GETBMAP:
2326 : case XFS_IOC_GETBMAPA:
2327 : case XFS_IOC_GETBMAPX:
2328 1196056 : return xfs_ioc_getbmap(filp, cmd, arg);
2329 :
2330 94829 : case FS_IOC_GETFSMAP:
2331 94829 : return xfs_ioc_getfsmap(ip, arg);
2332 :
2333 1011 : case XFS_IOC_GETFSREFCOUNTS:
2334 1011 : return xfs_ioc_getfsrefcounts(ip, arg);
2335 :
2336 89747893 : case XFS_IOC_SCRUBV_METADATA:
2337 89747893 : return xfs_ioc_scrubv_metadata(filp, arg);
2338 2689436 : case XFS_IOC_SCRUB_METADATA:
2339 2689436 : return xfs_ioc_scrub_metadata(filp, arg);
2340 :
2341 : case XFS_IOC_FD_TO_HANDLE:
2342 : case XFS_IOC_PATH_TO_HANDLE:
2343 : case XFS_IOC_PATH_TO_FSHANDLE: {
2344 26244 : xfs_fsop_handlereq_t hreq;
2345 :
2346 26244 : if (copy_from_user(&hreq, arg, sizeof(hreq)))
2347 : return -EFAULT;
2348 26244 : return xfs_find_handle(cmd, &hreq);
2349 : }
2350 : case XFS_IOC_OPEN_BY_HANDLE: {
2351 33293251 : xfs_fsop_handlereq_t hreq;
2352 :
2353 33293251 : if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
2354 : return -EFAULT;
2355 33293263 : return xfs_open_by_handle(filp, &hreq);
2356 : }
2357 :
2358 : case XFS_IOC_READLINK_BY_HANDLE: {
2359 184 : xfs_fsop_handlereq_t hreq;
2360 :
2361 184 : if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
2362 : return -EFAULT;
2363 184 : return xfs_readlink_by_handle(filp, &hreq);
2364 : }
2365 134918157 : case XFS_IOC_ATTRLIST_BY_HANDLE:
2366 134918157 : return xfs_attrlist_by_handle(filp, arg);
2367 :
2368 132 : case XFS_IOC_ATTRMULTI_BY_HANDLE:
2369 132 : return xfs_attrmulti_by_handle(filp, arg);
2370 :
2371 : case XFS_IOC_SWAPEXT: {
2372 0 : struct xfs_swapext sxp;
2373 :
2374 0 : if (copy_from_user(&sxp, arg, sizeof(struct xfs_swapext)))
2375 : return -EFAULT;
2376 :
2377 0 : return xfs_ioc_swapext(&sxp);
2378 : }
2379 :
2380 11318 : case XFS_IOC_FSCOUNTS: {
2381 11318 : xfs_fsop_counts_t out;
2382 :
2383 11318 : xfs_fs_counts(mp, &out);
2384 :
2385 11318 : if (copy_to_user(arg, &out, sizeof(out)))
2386 2 : return -EFAULT;
2387 : return 0;
2388 : }
2389 :
2390 20 : case XFS_IOC_SET_RESBLKS: {
2391 20 : xfs_fsop_resblks_t inout;
2392 20 : uint64_t in;
2393 :
2394 20 : if (!capable(CAP_SYS_ADMIN))
2395 : return -EPERM;
2396 :
2397 40 : if (xfs_is_readonly(mp))
2398 : return -EROFS;
2399 :
2400 20 : if (copy_from_user(&inout, arg, sizeof(inout)))
2401 : return -EFAULT;
2402 :
2403 18 : error = mnt_want_write_file(filp);
2404 18 : if (error)
2405 0 : return error;
2406 :
2407 : /* input parameter is passed in resblks field of structure */
2408 18 : in = inout.resblks;
2409 18 : error = xfs_reserve_blocks(mp, &in, &inout);
2410 18 : mnt_drop_write_file(filp);
2411 18 : if (error)
2412 0 : return error;
2413 :
2414 18 : if (copy_to_user(arg, &inout, sizeof(inout)))
2415 0 : return -EFAULT;
2416 : return 0;
2417 : }
2418 :
2419 6 : case XFS_IOC_GET_RESBLKS: {
2420 6 : xfs_fsop_resblks_t out;
2421 :
2422 6 : if (!capable(CAP_SYS_ADMIN))
2423 : return -EPERM;
2424 :
2425 6 : error = xfs_reserve_blocks(mp, NULL, &out);
2426 6 : if (error)
2427 0 : return error;
2428 :
2429 6 : if (copy_to_user(arg, &out, sizeof(out)))
2430 0 : return -EFAULT;
2431 :
2432 : return 0;
2433 : }
2434 :
2435 : case XFS_IOC_FSGROWFSDATA: {
2436 336 : struct xfs_growfs_data in;
2437 :
2438 336 : if (copy_from_user(&in, arg, sizeof(in)))
2439 : return -EFAULT;
2440 :
2441 336 : error = mnt_want_write_file(filp);
2442 336 : if (error)
2443 0 : return error;
2444 336 : error = xfs_growfs_data(mp, &in);
2445 336 : mnt_drop_write_file(filp);
2446 336 : return error;
2447 : }
2448 :
2449 : case XFS_IOC_FSGROWFSLOG: {
2450 0 : struct xfs_growfs_log in;
2451 :
2452 0 : if (copy_from_user(&in, arg, sizeof(in)))
2453 : return -EFAULT;
2454 :
2455 0 : error = mnt_want_write_file(filp);
2456 0 : if (error)
2457 0 : return error;
2458 0 : error = xfs_growfs_log(mp, &in);
2459 0 : mnt_drop_write_file(filp);
2460 0 : return error;
2461 : }
2462 :
2463 : case XFS_IOC_FSGROWFSRT: {
2464 3 : xfs_growfs_rt_t in;
2465 :
2466 3 : if (copy_from_user(&in, arg, sizeof(in)))
2467 : return -EFAULT;
2468 :
2469 3 : error = mnt_want_write_file(filp);
2470 3 : if (error)
2471 0 : return error;
2472 3 : error = xfs_growfs_rt(mp, &in);
2473 3 : mnt_drop_write_file(filp);
2474 3 : return error;
2475 : }
2476 :
2477 4816 : case XFS_IOC_GOINGDOWN: {
2478 4816 : uint32_t in;
2479 :
2480 4816 : if (!capable(CAP_SYS_ADMIN))
2481 : return -EPERM;
2482 :
2483 4816 : if (get_user(in, (uint32_t __user *)arg))
2484 : return -EFAULT;
2485 :
2486 4816 : return xfs_fs_goingdown(mp, in);
2487 : }
2488 :
2489 14 : case XFS_IOC_ERROR_INJECTION: {
2490 14 : xfs_error_injection_t in;
2491 :
2492 14 : if (!capable(CAP_SYS_ADMIN))
2493 : return -EPERM;
2494 :
2495 14 : if (copy_from_user(&in, arg, sizeof(in)))
2496 : return -EFAULT;
2497 :
2498 14 : return xfs_errortag_add(mp, in.errtag);
2499 : }
2500 :
2501 0 : case XFS_IOC_ERROR_CLEARALL:
2502 0 : if (!capable(CAP_SYS_ADMIN))
2503 : return -EPERM;
2504 :
2505 0 : return xfs_errortag_clearall(mp);
2506 :
2507 0 : case XFS_IOC_FREE_EOFBLOCKS: {
2508 0 : struct xfs_fs_eofblocks eofb;
2509 0 : struct xfs_icwalk icw;
2510 :
2511 0 : if (!capable(CAP_SYS_ADMIN))
2512 : return -EPERM;
2513 :
2514 0 : if (xfs_is_readonly(mp))
2515 : return -EROFS;
2516 :
2517 0 : if (copy_from_user(&eofb, arg, sizeof(eofb)))
2518 : return -EFAULT;
2519 :
2520 0 : error = xfs_fs_eofblocks_from_user(&eofb, &icw);
2521 0 : if (error)
2522 0 : return error;
2523 :
2524 0 : trace_xfs_ioc_free_eofblocks(mp, &icw, _RET_IP_);
2525 :
2526 0 : sb_start_write(mp->m_super);
2527 0 : error = xfs_blockgc_free_space(mp, &icw);
2528 0 : sb_end_write(mp->m_super);
2529 0 : return error;
2530 : }
2531 :
2532 2313625 : case XFS_IOC_EXCHANGE_RANGE:
2533 2313625 : return xfs_ioc_exchange_range(filp, arg);
2534 :
2535 : default:
2536 : return -ENOTTY;
2537 : }
2538 : }
|