.. | .. |
---|
86 | 86 | i_size_write(inode2, isize); |
---|
87 | 87 | } |
---|
88 | 88 | |
---|
89 | | -static void reset_inode_seed(struct inode *inode) |
---|
| 89 | +void ext4_reset_inode_seed(struct inode *inode) |
---|
90 | 90 | { |
---|
91 | 91 | struct ext4_inode_info *ei = EXT4_I(inode); |
---|
92 | 92 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
---|
.. | .. |
---|
121 | 121 | blkcnt_t blocks; |
---|
122 | 122 | unsigned short bytes; |
---|
123 | 123 | |
---|
124 | | - inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL); |
---|
| 124 | + inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, |
---|
| 125 | + EXT4_IGET_SPECIAL | EXT4_IGET_BAD); |
---|
125 | 126 | if (IS_ERR(inode_bl)) |
---|
126 | 127 | return PTR_ERR(inode_bl); |
---|
127 | 128 | ei_bl = EXT4_I(inode_bl); |
---|
.. | .. |
---|
165 | 166 | err = -EINVAL; |
---|
166 | 167 | goto err_out; |
---|
167 | 168 | } |
---|
| 169 | + ext4_fc_start_ineligible(sb, EXT4_FC_REASON_SWAP_BOOT); |
---|
168 | 170 | |
---|
169 | 171 | /* Protect extent tree against block allocations via delalloc */ |
---|
170 | 172 | ext4_double_down_write_data_sem(inode, inode_bl); |
---|
171 | 173 | |
---|
172 | | - if (inode_bl->i_nlink == 0) { |
---|
| 174 | + if (is_bad_inode(inode_bl) || !S_ISREG(inode_bl->i_mode)) { |
---|
173 | 175 | /* this inode has never been used as a BOOT_LOADER */ |
---|
174 | 176 | set_nlink(inode_bl, 1); |
---|
175 | 177 | i_uid_write(inode_bl, 0); |
---|
.. | .. |
---|
178 | 180 | ei_bl->i_flags = 0; |
---|
179 | 181 | inode_set_iversion(inode_bl, 1); |
---|
180 | 182 | i_size_write(inode_bl, 0); |
---|
| 183 | + EXT4_I(inode_bl)->i_disksize = inode_bl->i_size; |
---|
181 | 184 | inode_bl->i_mode = S_IFREG; |
---|
182 | 185 | if (ext4_has_feature_extents(sb)) { |
---|
183 | 186 | ext4_set_inode_flag(inode_bl, EXT4_INODE_EXTENTS); |
---|
.. | .. |
---|
199 | 202 | |
---|
200 | 203 | inode->i_generation = prandom_u32(); |
---|
201 | 204 | inode_bl->i_generation = prandom_u32(); |
---|
202 | | - reset_inode_seed(inode); |
---|
203 | | - reset_inode_seed(inode_bl); |
---|
| 205 | + ext4_reset_inode_seed(inode); |
---|
| 206 | + ext4_reset_inode_seed(inode_bl); |
---|
204 | 207 | |
---|
205 | | - ext4_discard_preallocations(inode); |
---|
| 208 | + ext4_discard_preallocations(inode, 0); |
---|
206 | 209 | |
---|
207 | 210 | err = ext4_mark_inode_dirty(handle, inode); |
---|
208 | 211 | if (err < 0) { |
---|
.. | .. |
---|
247 | 250 | |
---|
248 | 251 | err_out1: |
---|
249 | 252 | ext4_journal_stop(handle); |
---|
| 253 | + ext4_fc_stop_ineligible(sb); |
---|
250 | 254 | ext4_double_up_write_data_sem(inode, inode_bl); |
---|
251 | 255 | |
---|
252 | 256 | err_out: |
---|
.. | .. |
---|
292 | 296 | return 0; |
---|
293 | 297 | } |
---|
294 | 298 | |
---|
| 299 | +static void ext4_dax_dontcache(struct inode *inode, unsigned int flags) |
---|
| 300 | +{ |
---|
| 301 | + struct ext4_inode_info *ei = EXT4_I(inode); |
---|
| 302 | + |
---|
| 303 | + if (S_ISDIR(inode->i_mode)) |
---|
| 304 | + return; |
---|
| 305 | + |
---|
| 306 | + if (test_opt2(inode->i_sb, DAX_NEVER) || |
---|
| 307 | + test_opt(inode->i_sb, DAX_ALWAYS)) |
---|
| 308 | + return; |
---|
| 309 | + |
---|
| 310 | + if ((ei->i_flags ^ flags) & EXT4_DAX_FL) |
---|
| 311 | + d_mark_dontcache(inode); |
---|
| 312 | +} |
---|
| 313 | + |
---|
| 314 | +static bool dax_compatible(struct inode *inode, unsigned int oldflags, |
---|
| 315 | + unsigned int flags) |
---|
| 316 | +{ |
---|
| 317 | + /* Allow the DAX flag to be changed on inline directories */ |
---|
| 318 | + if (S_ISDIR(inode->i_mode)) { |
---|
| 319 | + flags &= ~EXT4_INLINE_DATA_FL; |
---|
| 320 | + oldflags &= ~EXT4_INLINE_DATA_FL; |
---|
| 321 | + } |
---|
| 322 | + |
---|
| 323 | + if (flags & EXT4_DAX_FL) { |
---|
| 324 | + if ((oldflags & EXT4_DAX_MUT_EXCL) || |
---|
| 325 | + ext4_test_inode_state(inode, |
---|
| 326 | + EXT4_STATE_VERITY_IN_PROGRESS)) { |
---|
| 327 | + return false; |
---|
| 328 | + } |
---|
| 329 | + } |
---|
| 330 | + |
---|
| 331 | + if ((flags & EXT4_DAX_MUT_EXCL) && (oldflags & EXT4_DAX_FL)) |
---|
| 332 | + return false; |
---|
| 333 | + |
---|
| 334 | + return true; |
---|
| 335 | +} |
---|
| 336 | + |
---|
295 | 337 | static int ext4_ioctl_setflags(struct inode *inode, |
---|
296 | 338 | unsigned int flags) |
---|
297 | 339 | { |
---|
.. | .. |
---|
300 | 342 | int err = -EPERM, migrate = 0; |
---|
301 | 343 | struct ext4_iloc iloc; |
---|
302 | 344 | unsigned int oldflags, mask, i; |
---|
303 | | - unsigned int jflag; |
---|
304 | 345 | struct super_block *sb = inode->i_sb; |
---|
305 | 346 | |
---|
306 | 347 | /* Is it quota file? Do not allow user to mess with it */ |
---|
.. | .. |
---|
309 | 350 | |
---|
310 | 351 | oldflags = ei->i_flags; |
---|
311 | 352 | |
---|
312 | | - /* The JOURNAL_DATA flag is modifiable only by root */ |
---|
313 | | - jflag = flags & EXT4_JOURNAL_DATA_FL; |
---|
314 | | - |
---|
315 | | - /* |
---|
316 | | - * The IMMUTABLE and APPEND_ONLY flags can only be changed by |
---|
317 | | - * the relevant capability. |
---|
318 | | - * |
---|
319 | | - * This test looks nicer. Thanks to Pauline Middelink |
---|
320 | | - */ |
---|
321 | | - if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { |
---|
322 | | - if (!capable(CAP_LINUX_IMMUTABLE)) |
---|
323 | | - goto flags_out; |
---|
324 | | - } |
---|
| 353 | + err = vfs_ioc_setflags_prepare(inode, oldflags, flags); |
---|
| 354 | + if (err) |
---|
| 355 | + goto flags_out; |
---|
325 | 356 | |
---|
326 | 357 | /* |
---|
327 | 358 | * The JOURNAL_DATA flag can only be changed by |
---|
328 | 359 | * the relevant capability. |
---|
329 | 360 | */ |
---|
330 | | - if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { |
---|
| 361 | + if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { |
---|
331 | 362 | if (!capable(CAP_SYS_RESOURCE)) |
---|
332 | 363 | goto flags_out; |
---|
333 | 364 | } |
---|
| 365 | + |
---|
| 366 | + if (!dax_compatible(inode, oldflags, flags)) { |
---|
| 367 | + err = -EOPNOTSUPP; |
---|
| 368 | + goto flags_out; |
---|
| 369 | + } |
---|
| 370 | + |
---|
334 | 371 | if ((flags ^ oldflags) & EXT4_EXTENTS_FL) |
---|
335 | 372 | migrate = 1; |
---|
336 | | - |
---|
337 | | - if (flags & EXT4_EOFBLOCKS_FL) { |
---|
338 | | - /* we don't support adding EOFBLOCKS flag */ |
---|
339 | | - if (!(oldflags & EXT4_EOFBLOCKS_FL)) { |
---|
340 | | - err = -EOPNOTSUPP; |
---|
341 | | - goto flags_out; |
---|
342 | | - } |
---|
343 | | - } else if (oldflags & EXT4_EOFBLOCKS_FL) { |
---|
344 | | - err = ext4_truncate(inode); |
---|
345 | | - if (err) |
---|
346 | | - goto flags_out; |
---|
347 | | - } |
---|
348 | 373 | |
---|
349 | 374 | if ((flags ^ oldflags) & EXT4_CASEFOLD_FL) { |
---|
350 | 375 | if (!ext4_has_feature_casefold(sb)) { |
---|
.. | .. |
---|
388 | 413 | if (err) |
---|
389 | 414 | goto flags_err; |
---|
390 | 415 | |
---|
| 416 | + ext4_dax_dontcache(inode, flags); |
---|
| 417 | + |
---|
391 | 418 | for (i = 0, mask = 1; i < 32; i++, mask <<= 1) { |
---|
392 | 419 | if (!(mask & EXT4_FL_USER_MODIFIABLE)) |
---|
393 | 420 | continue; |
---|
.. | .. |
---|
400 | 427 | ext4_clear_inode_flag(inode, i); |
---|
401 | 428 | } |
---|
402 | 429 | |
---|
403 | | - ext4_set_inode_flags(inode); |
---|
| 430 | + ext4_set_inode_flags(inode, false); |
---|
| 431 | + |
---|
404 | 432 | inode->i_ctime = current_time(inode); |
---|
405 | 433 | |
---|
406 | 434 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
---|
.. | .. |
---|
409 | 437 | if (err) |
---|
410 | 438 | goto flags_out; |
---|
411 | 439 | |
---|
412 | | - if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { |
---|
| 440 | + if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { |
---|
413 | 441 | /* |
---|
414 | 442 | * Changes to the journaling mode can cause unsafe changes to |
---|
415 | | - * S_DAX if we are using the DAX mount option. |
---|
| 443 | + * S_DAX if the inode is DAX |
---|
416 | 444 | */ |
---|
417 | | - if (test_opt(inode->i_sb, DAX)) { |
---|
| 445 | + if (IS_DAX(inode)) { |
---|
418 | 446 | err = -EBUSY; |
---|
419 | 447 | goto flags_out; |
---|
420 | 448 | } |
---|
421 | 449 | |
---|
422 | | - err = ext4_change_inode_journal_flag(inode, jflag); |
---|
| 450 | + err = ext4_change_inode_journal_flag(inode, |
---|
| 451 | + flags & EXT4_JOURNAL_DATA_FL); |
---|
423 | 452 | if (err) |
---|
424 | 453 | goto flags_out; |
---|
425 | 454 | } |
---|
.. | .. |
---|
467 | 496 | if (ext4_is_quota_file(inode)) |
---|
468 | 497 | return err; |
---|
469 | 498 | |
---|
| 499 | + err = dquot_initialize(inode); |
---|
| 500 | + if (err) |
---|
| 501 | + return err; |
---|
| 502 | + |
---|
470 | 503 | err = ext4_get_inode_loc(inode, &iloc); |
---|
471 | 504 | if (err) |
---|
472 | 505 | return err; |
---|
.. | .. |
---|
481 | 514 | } else { |
---|
482 | 515 | brelse(iloc.bh); |
---|
483 | 516 | } |
---|
484 | | - |
---|
485 | | - err = dquot_initialize(inode); |
---|
486 | | - if (err) |
---|
487 | | - return err; |
---|
488 | 517 | |
---|
489 | 518 | handle = ext4_journal_start(inode, EXT4_HT_QUOTA, |
---|
490 | 519 | EXT4_QUOTA_INIT_BLOCKS(sb) + |
---|
.. | .. |
---|
546 | 575 | xflags |= FS_XFLAG_NOATIME; |
---|
547 | 576 | if (iflags & EXT4_PROJINHERIT_FL) |
---|
548 | 577 | xflags |= FS_XFLAG_PROJINHERIT; |
---|
| 578 | + if (iflags & EXT4_DAX_FL) |
---|
| 579 | + xflags |= FS_XFLAG_DAX; |
---|
549 | 580 | return xflags; |
---|
550 | 581 | } |
---|
551 | 582 | |
---|
552 | 583 | #define EXT4_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \ |
---|
553 | 584 | FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \ |
---|
554 | | - FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT) |
---|
| 585 | + FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT | \ |
---|
| 586 | + FS_XFLAG_DAX) |
---|
555 | 587 | |
---|
556 | 588 | /* Transfer xflags flags to internal */ |
---|
557 | 589 | static inline unsigned long ext4_xflags_to_iflags(__u32 xflags) |
---|
.. | .. |
---|
570 | 602 | iflags |= EXT4_NOATIME_FL; |
---|
571 | 603 | if (xflags & FS_XFLAG_PROJINHERIT) |
---|
572 | 604 | iflags |= EXT4_PROJINHERIT_FL; |
---|
| 605 | + if (xflags & FS_XFLAG_DAX) |
---|
| 606 | + iflags |= EXT4_DAX_FL; |
---|
573 | 607 | |
---|
574 | 608 | return iflags; |
---|
575 | 609 | } |
---|
.. | .. |
---|
578 | 612 | { |
---|
579 | 613 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
---|
580 | 614 | __u32 flags; |
---|
| 615 | + int ret; |
---|
581 | 616 | |
---|
582 | 617 | if (!capable(CAP_SYS_ADMIN)) |
---|
583 | 618 | return -EPERM; |
---|
.. | .. |
---|
596 | 631 | |
---|
597 | 632 | switch (flags) { |
---|
598 | 633 | case EXT4_GOING_FLAGS_DEFAULT: |
---|
599 | | - freeze_bdev(sb->s_bdev); |
---|
| 634 | + ret = freeze_bdev(sb->s_bdev); |
---|
| 635 | + if (ret) |
---|
| 636 | + return ret; |
---|
600 | 637 | set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); |
---|
601 | | - thaw_bdev(sb->s_bdev, sb); |
---|
| 638 | + thaw_bdev(sb->s_bdev); |
---|
602 | 639 | break; |
---|
603 | 640 | case EXT4_GOING_FLAGS_LOGFLUSH: |
---|
604 | 641 | set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); |
---|
.. | .. |
---|
645 | 682 | static int ext4_ioc_getfsmap(struct super_block *sb, |
---|
646 | 683 | struct fsmap_head __user *arg) |
---|
647 | 684 | { |
---|
648 | | - struct getfsmap_info info = {0}; |
---|
| 685 | + struct getfsmap_info info = { NULL }; |
---|
649 | 686 | struct ext4_fsmap_head xhead = {0}; |
---|
650 | 687 | struct fsmap_head head; |
---|
651 | 688 | bool aborted = false; |
---|
.. | .. |
---|
741 | 778 | return err; |
---|
742 | 779 | } |
---|
743 | 780 | |
---|
744 | | -static int ext4_ioctl_check_project(struct inode *inode, struct fsxattr *fa) |
---|
| 781 | +static void ext4_fill_fsxattr(struct inode *inode, struct fsxattr *fa) |
---|
745 | 782 | { |
---|
746 | | - /* |
---|
747 | | - * Project Quota ID state is only allowed to change from within the init |
---|
748 | | - * namespace. Enforce that restriction only if we are trying to change |
---|
749 | | - * the quota ID state. Everything else is allowed in user namespaces. |
---|
750 | | - */ |
---|
751 | | - if (current_user_ns() == &init_user_ns) |
---|
752 | | - return 0; |
---|
| 783 | + struct ext4_inode_info *ei = EXT4_I(inode); |
---|
753 | 784 | |
---|
754 | | - if (__kprojid_val(EXT4_I(inode)->i_projid) != fa->fsx_projid) |
---|
755 | | - return -EINVAL; |
---|
| 785 | + simple_fill_fsxattr(fa, ext4_iflags_to_xflags(ei->i_flags & |
---|
| 786 | + EXT4_FL_USER_VISIBLE)); |
---|
756 | 787 | |
---|
757 | | - if (ext4_test_inode_flag(inode, EXT4_INODE_PROJINHERIT)) { |
---|
758 | | - if (!(fa->fsx_xflags & FS_XFLAG_PROJINHERIT)) |
---|
759 | | - return -EINVAL; |
---|
760 | | - } else { |
---|
761 | | - if (fa->fsx_xflags & FS_XFLAG_PROJINHERIT) |
---|
762 | | - return -EINVAL; |
---|
763 | | - } |
---|
764 | | - |
---|
765 | | - return 0; |
---|
| 788 | + if (ext4_has_feature_project(inode->i_sb)) |
---|
| 789 | + fa->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid); |
---|
766 | 790 | } |
---|
767 | 791 | |
---|
768 | | -long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
---|
| 792 | +/* So that the fiemap access checks can't overflow on 32 bit machines. */ |
---|
| 793 | +#define FIEMAP_MAX_EXTENTS (UINT_MAX / sizeof(struct fiemap_extent)) |
---|
| 794 | + |
---|
| 795 | +static int ext4_ioctl_get_es_cache(struct file *filp, unsigned long arg) |
---|
| 796 | +{ |
---|
| 797 | + struct fiemap fiemap; |
---|
| 798 | + struct fiemap __user *ufiemap = (struct fiemap __user *) arg; |
---|
| 799 | + struct fiemap_extent_info fieinfo = { 0, }; |
---|
| 800 | + struct inode *inode = file_inode(filp); |
---|
| 801 | + int error; |
---|
| 802 | + |
---|
| 803 | + if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap))) |
---|
| 804 | + return -EFAULT; |
---|
| 805 | + |
---|
| 806 | + if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS) |
---|
| 807 | + return -EINVAL; |
---|
| 808 | + |
---|
| 809 | + fieinfo.fi_flags = fiemap.fm_flags; |
---|
| 810 | + fieinfo.fi_extents_max = fiemap.fm_extent_count; |
---|
| 811 | + fieinfo.fi_extents_start = ufiemap->fm_extents; |
---|
| 812 | + |
---|
| 813 | + error = ext4_get_es_cache(inode, &fieinfo, fiemap.fm_start, |
---|
| 814 | + fiemap.fm_length); |
---|
| 815 | + fiemap.fm_flags = fieinfo.fi_flags; |
---|
| 816 | + fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped; |
---|
| 817 | + if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap))) |
---|
| 818 | + error = -EFAULT; |
---|
| 819 | + |
---|
| 820 | + return error; |
---|
| 821 | +} |
---|
| 822 | + |
---|
| 823 | +static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
---|
769 | 824 | { |
---|
770 | 825 | struct inode *inode = file_inode(filp); |
---|
771 | 826 | struct super_block *sb = inode->i_sb; |
---|
.. | .. |
---|
777 | 832 | switch (cmd) { |
---|
778 | 833 | case FS_IOC_GETFSMAP: |
---|
779 | 834 | return ext4_ioc_getfsmap(sb, (void __user *)arg); |
---|
780 | | - case EXT4_IOC_GETFLAGS: |
---|
| 835 | + case FS_IOC_GETFLAGS: |
---|
781 | 836 | flags = ei->i_flags & EXT4_FL_USER_VISIBLE; |
---|
| 837 | + if (S_ISREG(inode->i_mode)) |
---|
| 838 | + flags &= ~EXT4_PROJINHERIT_FL; |
---|
782 | 839 | return put_user(flags, (int __user *) arg); |
---|
783 | | - case EXT4_IOC_SETFLAGS: { |
---|
| 840 | + case FS_IOC_SETFLAGS: { |
---|
784 | 841 | int err; |
---|
785 | 842 | |
---|
786 | 843 | if (!inode_owner_or_capable(inode)) |
---|
.. | .. |
---|
1030 | 1087 | |
---|
1031 | 1088 | err = ext4_resize_fs(sb, n_blocks_count); |
---|
1032 | 1089 | if (EXT4_SB(sb)->s_journal) { |
---|
| 1090 | + ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_RESIZE); |
---|
1033 | 1091 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
---|
1034 | 1092 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
---|
1035 | 1093 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
---|
.. | .. |
---|
1083 | 1141 | case EXT4_IOC_PRECACHE_EXTENTS: |
---|
1084 | 1142 | return ext4_ext_precache(inode); |
---|
1085 | 1143 | |
---|
1086 | | - case EXT4_IOC_SET_ENCRYPTION_POLICY: |
---|
| 1144 | + case FS_IOC_SET_ENCRYPTION_POLICY: |
---|
1087 | 1145 | if (!ext4_has_feature_encrypt(sb)) |
---|
1088 | 1146 | return -EOPNOTSUPP; |
---|
1089 | 1147 | return fscrypt_ioctl_set_policy(filp, (const void __user *)arg); |
---|
1090 | 1148 | |
---|
1091 | | - case EXT4_IOC_GET_ENCRYPTION_PWSALT: { |
---|
| 1149 | + case FS_IOC_GET_ENCRYPTION_PWSALT: { |
---|
1092 | 1150 | #ifdef CONFIG_FS_ENCRYPTION |
---|
1093 | 1151 | int err, err2; |
---|
1094 | 1152 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
---|
.. | .. |
---|
1131 | 1189 | return -EOPNOTSUPP; |
---|
1132 | 1190 | #endif |
---|
1133 | 1191 | } |
---|
1134 | | - case EXT4_IOC_GET_ENCRYPTION_POLICY: |
---|
| 1192 | + case FS_IOC_GET_ENCRYPTION_POLICY: |
---|
1135 | 1193 | if (!ext4_has_feature_encrypt(sb)) |
---|
1136 | 1194 | return -EOPNOTSUPP; |
---|
1137 | 1195 | return fscrypt_ioctl_get_policy(filp, (void __user *)arg); |
---|
.. | .. |
---|
1166 | 1224 | return -EOPNOTSUPP; |
---|
1167 | 1225 | return fscrypt_ioctl_get_nonce(filp, (void __user *)arg); |
---|
1168 | 1226 | |
---|
1169 | | - case EXT4_IOC_FSGETXATTR: |
---|
| 1227 | + case EXT4_IOC_CLEAR_ES_CACHE: |
---|
| 1228 | + { |
---|
| 1229 | + if (!inode_owner_or_capable(inode)) |
---|
| 1230 | + return -EACCES; |
---|
| 1231 | + ext4_clear_inode_es(inode); |
---|
| 1232 | + return 0; |
---|
| 1233 | + } |
---|
| 1234 | + |
---|
| 1235 | + case EXT4_IOC_GETSTATE: |
---|
| 1236 | + { |
---|
| 1237 | + __u32 state = 0; |
---|
| 1238 | + |
---|
| 1239 | + if (ext4_test_inode_state(inode, EXT4_STATE_EXT_PRECACHED)) |
---|
| 1240 | + state |= EXT4_STATE_FLAG_EXT_PRECACHED; |
---|
| 1241 | + if (ext4_test_inode_state(inode, EXT4_STATE_NEW)) |
---|
| 1242 | + state |= EXT4_STATE_FLAG_NEW; |
---|
| 1243 | + if (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) |
---|
| 1244 | + state |= EXT4_STATE_FLAG_NEWENTRY; |
---|
| 1245 | + if (ext4_test_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE)) |
---|
| 1246 | + state |= EXT4_STATE_FLAG_DA_ALLOC_CLOSE; |
---|
| 1247 | + |
---|
| 1248 | + return put_user(state, (__u32 __user *) arg); |
---|
| 1249 | + } |
---|
| 1250 | + |
---|
| 1251 | + case EXT4_IOC_GET_ES_CACHE: |
---|
| 1252 | + return ext4_ioctl_get_es_cache(filp, arg); |
---|
| 1253 | + |
---|
| 1254 | + case FS_IOC_FSGETXATTR: |
---|
1170 | 1255 | { |
---|
1171 | 1256 | struct fsxattr fa; |
---|
1172 | 1257 | |
---|
1173 | | - memset(&fa, 0, sizeof(struct fsxattr)); |
---|
1174 | | - fa.fsx_xflags = ext4_iflags_to_xflags(ei->i_flags & EXT4_FL_USER_VISIBLE); |
---|
1175 | | - |
---|
1176 | | - if (ext4_has_feature_project(inode->i_sb)) { |
---|
1177 | | - fa.fsx_projid = (__u32)from_kprojid(&init_user_ns, |
---|
1178 | | - EXT4_I(inode)->i_projid); |
---|
1179 | | - } |
---|
| 1258 | + ext4_fill_fsxattr(inode, &fa); |
---|
1180 | 1259 | |
---|
1181 | 1260 | if (copy_to_user((struct fsxattr __user *)arg, |
---|
1182 | 1261 | &fa, sizeof(fa))) |
---|
1183 | 1262 | return -EFAULT; |
---|
1184 | 1263 | return 0; |
---|
1185 | 1264 | } |
---|
1186 | | - case EXT4_IOC_FSSETXATTR: |
---|
| 1265 | + case FS_IOC_FSSETXATTR: |
---|
1187 | 1266 | { |
---|
1188 | | - struct fsxattr fa; |
---|
| 1267 | + struct fsxattr fa, old_fa; |
---|
1189 | 1268 | int err; |
---|
1190 | 1269 | |
---|
1191 | 1270 | if (copy_from_user(&fa, (struct fsxattr __user *)arg, |
---|
.. | .. |
---|
1208 | 1287 | return err; |
---|
1209 | 1288 | |
---|
1210 | 1289 | inode_lock(inode); |
---|
1211 | | - err = ext4_ioctl_check_project(inode, &fa); |
---|
| 1290 | + ext4_fill_fsxattr(inode, &old_fa); |
---|
| 1291 | + err = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa); |
---|
1212 | 1292 | if (err) |
---|
1213 | 1293 | goto out; |
---|
1214 | 1294 | flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) | |
---|
.. | .. |
---|
1238 | 1318 | return -EOPNOTSUPP; |
---|
1239 | 1319 | return fsverity_ioctl_measure(filp, (void __user *)arg); |
---|
1240 | 1320 | |
---|
| 1321 | + case FS_IOC_READ_VERITY_METADATA: |
---|
| 1322 | + if (!ext4_has_feature_verity(sb)) |
---|
| 1323 | + return -EOPNOTSUPP; |
---|
| 1324 | + return fsverity_ioctl_read_metadata(filp, |
---|
| 1325 | + (const void __user *)arg); |
---|
| 1326 | + |
---|
1241 | 1327 | default: |
---|
1242 | 1328 | return -ENOTTY; |
---|
1243 | 1329 | } |
---|
| 1330 | +} |
---|
| 1331 | + |
---|
| 1332 | +long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
---|
| 1333 | +{ |
---|
| 1334 | + return __ext4_ioctl(filp, cmd, arg); |
---|
1244 | 1335 | } |
---|
1245 | 1336 | |
---|
1246 | 1337 | #ifdef CONFIG_COMPAT |
---|
.. | .. |
---|
1248 | 1339 | { |
---|
1249 | 1340 | /* These are just misnamed, they actually get/put from/to user an int */ |
---|
1250 | 1341 | switch (cmd) { |
---|
1251 | | - case EXT4_IOC32_GETFLAGS: |
---|
1252 | | - cmd = EXT4_IOC_GETFLAGS; |
---|
| 1342 | + case FS_IOC32_GETFLAGS: |
---|
| 1343 | + cmd = FS_IOC_GETFLAGS; |
---|
1253 | 1344 | break; |
---|
1254 | | - case EXT4_IOC32_SETFLAGS: |
---|
1255 | | - cmd = EXT4_IOC_SETFLAGS; |
---|
| 1345 | + case FS_IOC32_SETFLAGS: |
---|
| 1346 | + cmd = FS_IOC_SETFLAGS; |
---|
1256 | 1347 | break; |
---|
1257 | 1348 | case EXT4_IOC32_GETVERSION: |
---|
1258 | 1349 | cmd = EXT4_IOC_GETVERSION; |
---|
.. | .. |
---|
1294 | 1385 | } |
---|
1295 | 1386 | case EXT4_IOC_MOVE_EXT: |
---|
1296 | 1387 | case EXT4_IOC_RESIZE_FS: |
---|
| 1388 | + case FITRIM: |
---|
1297 | 1389 | case EXT4_IOC_PRECACHE_EXTENTS: |
---|
1298 | | - case EXT4_IOC_SET_ENCRYPTION_POLICY: |
---|
1299 | | - case EXT4_IOC_GET_ENCRYPTION_PWSALT: |
---|
1300 | | - case EXT4_IOC_GET_ENCRYPTION_POLICY: |
---|
| 1390 | + case FS_IOC_SET_ENCRYPTION_POLICY: |
---|
| 1391 | + case FS_IOC_GET_ENCRYPTION_PWSALT: |
---|
| 1392 | + case FS_IOC_GET_ENCRYPTION_POLICY: |
---|
1301 | 1393 | case FS_IOC_GET_ENCRYPTION_POLICY_EX: |
---|
1302 | 1394 | case FS_IOC_ADD_ENCRYPTION_KEY: |
---|
1303 | 1395 | case FS_IOC_REMOVE_ENCRYPTION_KEY: |
---|
.. | .. |
---|
1308 | 1400 | case FS_IOC_GETFSMAP: |
---|
1309 | 1401 | case FS_IOC_ENABLE_VERITY: |
---|
1310 | 1402 | case FS_IOC_MEASURE_VERITY: |
---|
1311 | | - case EXT4_IOC_FSGETXATTR: |
---|
1312 | | - case EXT4_IOC_FSSETXATTR: |
---|
| 1403 | + case FS_IOC_READ_VERITY_METADATA: |
---|
| 1404 | + case EXT4_IOC_CLEAR_ES_CACHE: |
---|
| 1405 | + case EXT4_IOC_GETSTATE: |
---|
| 1406 | + case EXT4_IOC_GET_ES_CACHE: |
---|
| 1407 | + case FS_IOC_FSGETXATTR: |
---|
| 1408 | + case FS_IOC_FSSETXATTR: |
---|
1313 | 1409 | break; |
---|
1314 | 1410 | default: |
---|
1315 | 1411 | return -ENOIOCTLCMD; |
---|