| .. | .. | 
|---|
| 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); | 
|---|
| .. | .. | 
|---|
| 165 | 165 | err = -EINVAL; | 
|---|
| 166 | 166 | goto err_out; | 
|---|
| 167 | 167 | } | 
|---|
|  | 168 | +	ext4_fc_start_ineligible(sb, EXT4_FC_REASON_SWAP_BOOT); | 
|---|
| 168 | 169 |  | 
|---|
| 169 | 170 | /* Protect extent tree against block allocations via delalloc */ | 
|---|
| 170 | 171 | ext4_double_down_write_data_sem(inode, inode_bl); | 
|---|
| .. | .. | 
|---|
| 199 | 200 |  | 
|---|
| 200 | 201 | inode->i_generation = prandom_u32(); | 
|---|
| 201 | 202 | inode_bl->i_generation = prandom_u32(); | 
|---|
| 202 |  | -	reset_inode_seed(inode); | 
|---|
| 203 |  | -	reset_inode_seed(inode_bl); | 
|---|
|  | 203 | +	ext4_reset_inode_seed(inode); | 
|---|
|  | 204 | +	ext4_reset_inode_seed(inode_bl); | 
|---|
| 204 | 205 |  | 
|---|
| 205 |  | -	ext4_discard_preallocations(inode); | 
|---|
|  | 206 | +	ext4_discard_preallocations(inode, 0); | 
|---|
| 206 | 207 |  | 
|---|
| 207 | 208 | err = ext4_mark_inode_dirty(handle, inode); | 
|---|
| 208 | 209 | if (err < 0) { | 
|---|
| .. | .. | 
|---|
| 247 | 248 |  | 
|---|
| 248 | 249 | err_out1: | 
|---|
| 249 | 250 | ext4_journal_stop(handle); | 
|---|
|  | 251 | +	ext4_fc_stop_ineligible(sb); | 
|---|
| 250 | 252 | ext4_double_up_write_data_sem(inode, inode_bl); | 
|---|
| 251 | 253 |  | 
|---|
| 252 | 254 | err_out: | 
|---|
| .. | .. | 
|---|
| 292 | 294 | return 0; | 
|---|
| 293 | 295 | } | 
|---|
| 294 | 296 |  | 
|---|
|  | 297 | +static void ext4_dax_dontcache(struct inode *inode, unsigned int flags) | 
|---|
|  | 298 | +{ | 
|---|
|  | 299 | +	struct ext4_inode_info *ei = EXT4_I(inode); | 
|---|
|  | 300 | + | 
|---|
|  | 301 | +	if (S_ISDIR(inode->i_mode)) | 
|---|
|  | 302 | +		return; | 
|---|
|  | 303 | + | 
|---|
|  | 304 | +	if (test_opt2(inode->i_sb, DAX_NEVER) || | 
|---|
|  | 305 | +	    test_opt(inode->i_sb, DAX_ALWAYS)) | 
|---|
|  | 306 | +		return; | 
|---|
|  | 307 | + | 
|---|
|  | 308 | +	if ((ei->i_flags ^ flags) & EXT4_DAX_FL) | 
|---|
|  | 309 | +		d_mark_dontcache(inode); | 
|---|
|  | 310 | +} | 
|---|
|  | 311 | + | 
|---|
|  | 312 | +static bool dax_compatible(struct inode *inode, unsigned int oldflags, | 
|---|
|  | 313 | +			   unsigned int flags) | 
|---|
|  | 314 | +{ | 
|---|
|  | 315 | +	/* Allow the DAX flag to be changed on inline directories */ | 
|---|
|  | 316 | +	if (S_ISDIR(inode->i_mode)) { | 
|---|
|  | 317 | +		flags &= ~EXT4_INLINE_DATA_FL; | 
|---|
|  | 318 | +		oldflags &= ~EXT4_INLINE_DATA_FL; | 
|---|
|  | 319 | +	} | 
|---|
|  | 320 | + | 
|---|
|  | 321 | +	if (flags & EXT4_DAX_FL) { | 
|---|
|  | 322 | +		if ((oldflags & EXT4_DAX_MUT_EXCL) || | 
|---|
|  | 323 | +		     ext4_test_inode_state(inode, | 
|---|
|  | 324 | +					  EXT4_STATE_VERITY_IN_PROGRESS)) { | 
|---|
|  | 325 | +			return false; | 
|---|
|  | 326 | +		} | 
|---|
|  | 327 | +	} | 
|---|
|  | 328 | + | 
|---|
|  | 329 | +	if ((flags & EXT4_DAX_MUT_EXCL) && (oldflags & EXT4_DAX_FL)) | 
|---|
|  | 330 | +			return false; | 
|---|
|  | 331 | + | 
|---|
|  | 332 | +	return true; | 
|---|
|  | 333 | +} | 
|---|
|  | 334 | + | 
|---|
| 295 | 335 | static int ext4_ioctl_setflags(struct inode *inode, | 
|---|
| 296 | 336 | unsigned int flags) | 
|---|
| 297 | 337 | { | 
|---|
| .. | .. | 
|---|
| 300 | 340 | int err = -EPERM, migrate = 0; | 
|---|
| 301 | 341 | struct ext4_iloc iloc; | 
|---|
| 302 | 342 | unsigned int oldflags, mask, i; | 
|---|
| 303 |  | -	unsigned int jflag; | 
|---|
| 304 | 343 | struct super_block *sb = inode->i_sb; | 
|---|
| 305 | 344 |  | 
|---|
| 306 | 345 | /* Is it quota file? Do not allow user to mess with it */ | 
|---|
| .. | .. | 
|---|
| 309 | 348 |  | 
|---|
| 310 | 349 | oldflags = ei->i_flags; | 
|---|
| 311 | 350 |  | 
|---|
| 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 |  | -	} | 
|---|
|  | 351 | +	err = vfs_ioc_setflags_prepare(inode, oldflags, flags); | 
|---|
|  | 352 | +	if (err) | 
|---|
|  | 353 | +		goto flags_out; | 
|---|
| 325 | 354 |  | 
|---|
| 326 | 355 | /* | 
|---|
| 327 | 356 | * The JOURNAL_DATA flag can only be changed by | 
|---|
| 328 | 357 | * the relevant capability. | 
|---|
| 329 | 358 | */ | 
|---|
| 330 |  | -	if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { | 
|---|
|  | 359 | +	if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { | 
|---|
| 331 | 360 | if (!capable(CAP_SYS_RESOURCE)) | 
|---|
| 332 | 361 | goto flags_out; | 
|---|
| 333 | 362 | } | 
|---|
|  | 363 | + | 
|---|
|  | 364 | +	if (!dax_compatible(inode, oldflags, flags)) { | 
|---|
|  | 365 | +		err = -EOPNOTSUPP; | 
|---|
|  | 366 | +		goto flags_out; | 
|---|
|  | 367 | +	} | 
|---|
|  | 368 | + | 
|---|
| 334 | 369 | if ((flags ^ oldflags) & EXT4_EXTENTS_FL) | 
|---|
| 335 | 370 | 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 | 371 |  | 
|---|
| 349 | 372 | if ((flags ^ oldflags) & EXT4_CASEFOLD_FL) { | 
|---|
| 350 | 373 | if (!ext4_has_feature_casefold(sb)) { | 
|---|
| .. | .. | 
|---|
| 388 | 411 | if (err) | 
|---|
| 389 | 412 | goto flags_err; | 
|---|
| 390 | 413 |  | 
|---|
|  | 414 | +	ext4_dax_dontcache(inode, flags); | 
|---|
|  | 415 | + | 
|---|
| 391 | 416 | for (i = 0, mask = 1; i < 32; i++, mask <<= 1) { | 
|---|
| 392 | 417 | if (!(mask & EXT4_FL_USER_MODIFIABLE)) | 
|---|
| 393 | 418 | continue; | 
|---|
| .. | .. | 
|---|
| 400 | 425 | ext4_clear_inode_flag(inode, i); | 
|---|
| 401 | 426 | } | 
|---|
| 402 | 427 |  | 
|---|
| 403 |  | -	ext4_set_inode_flags(inode); | 
|---|
|  | 428 | +	ext4_set_inode_flags(inode, false); | 
|---|
|  | 429 | + | 
|---|
| 404 | 430 | inode->i_ctime = current_time(inode); | 
|---|
| 405 | 431 |  | 
|---|
| 406 | 432 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); | 
|---|
| .. | .. | 
|---|
| 409 | 435 | if (err) | 
|---|
| 410 | 436 | goto flags_out; | 
|---|
| 411 | 437 |  | 
|---|
| 412 |  | -	if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { | 
|---|
|  | 438 | +	if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { | 
|---|
| 413 | 439 | /* | 
|---|
| 414 | 440 | * Changes to the journaling mode can cause unsafe changes to | 
|---|
| 415 |  | -		 * S_DAX if we are using the DAX mount option. | 
|---|
|  | 441 | +		 * S_DAX if the inode is DAX | 
|---|
| 416 | 442 | */ | 
|---|
| 417 |  | -		if (test_opt(inode->i_sb, DAX)) { | 
|---|
|  | 443 | +		if (IS_DAX(inode)) { | 
|---|
| 418 | 444 | err = -EBUSY; | 
|---|
| 419 | 445 | goto flags_out; | 
|---|
| 420 | 446 | } | 
|---|
| 421 | 447 |  | 
|---|
| 422 |  | -		err = ext4_change_inode_journal_flag(inode, jflag); | 
|---|
|  | 448 | +		err = ext4_change_inode_journal_flag(inode, | 
|---|
|  | 449 | +						     flags & EXT4_JOURNAL_DATA_FL); | 
|---|
| 423 | 450 | if (err) | 
|---|
| 424 | 451 | goto flags_out; | 
|---|
| 425 | 452 | } | 
|---|
| .. | .. | 
|---|
| 546 | 573 | xflags |= FS_XFLAG_NOATIME; | 
|---|
| 547 | 574 | if (iflags & EXT4_PROJINHERIT_FL) | 
|---|
| 548 | 575 | xflags |= FS_XFLAG_PROJINHERIT; | 
|---|
|  | 576 | +	if (iflags & EXT4_DAX_FL) | 
|---|
|  | 577 | +		xflags |= FS_XFLAG_DAX; | 
|---|
| 549 | 578 | return xflags; | 
|---|
| 550 | 579 | } | 
|---|
| 551 | 580 |  | 
|---|
| 552 | 581 | #define EXT4_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \ | 
|---|
| 553 | 582 | FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \ | 
|---|
| 554 |  | -				  FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT) | 
|---|
|  | 583 | +				  FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT | \ | 
|---|
|  | 584 | +				  FS_XFLAG_DAX) | 
|---|
| 555 | 585 |  | 
|---|
| 556 | 586 | /* Transfer xflags flags to internal */ | 
|---|
| 557 | 587 | static inline unsigned long ext4_xflags_to_iflags(__u32 xflags) | 
|---|
| .. | .. | 
|---|
| 570 | 600 | iflags |= EXT4_NOATIME_FL; | 
|---|
| 571 | 601 | if (xflags & FS_XFLAG_PROJINHERIT) | 
|---|
| 572 | 602 | iflags |= EXT4_PROJINHERIT_FL; | 
|---|
|  | 603 | +	if (xflags & FS_XFLAG_DAX) | 
|---|
|  | 604 | +		iflags |= EXT4_DAX_FL; | 
|---|
| 573 | 605 |  | 
|---|
| 574 | 606 | return iflags; | 
|---|
| 575 | 607 | } | 
|---|
| .. | .. | 
|---|
| 598 | 630 | case EXT4_GOING_FLAGS_DEFAULT: | 
|---|
| 599 | 631 | freeze_bdev(sb->s_bdev); | 
|---|
| 600 | 632 | set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); | 
|---|
| 601 |  | -		thaw_bdev(sb->s_bdev, sb); | 
|---|
|  | 633 | +		thaw_bdev(sb->s_bdev); | 
|---|
| 602 | 634 | break; | 
|---|
| 603 | 635 | case EXT4_GOING_FLAGS_LOGFLUSH: | 
|---|
| 604 | 636 | set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags); | 
|---|
| .. | .. | 
|---|
| 645 | 677 | static int ext4_ioc_getfsmap(struct super_block *sb, | 
|---|
| 646 | 678 | struct fsmap_head __user *arg) | 
|---|
| 647 | 679 | { | 
|---|
| 648 |  | -	struct getfsmap_info info = {0}; | 
|---|
|  | 680 | +	struct getfsmap_info info = { NULL }; | 
|---|
| 649 | 681 | struct ext4_fsmap_head xhead = {0}; | 
|---|
| 650 | 682 | struct fsmap_head head; | 
|---|
| 651 | 683 | bool aborted = false; | 
|---|
| .. | .. | 
|---|
| 741 | 773 | return err; | 
|---|
| 742 | 774 | } | 
|---|
| 743 | 775 |  | 
|---|
| 744 |  | -static int ext4_ioctl_check_project(struct inode *inode, struct fsxattr *fa) | 
|---|
|  | 776 | +static void ext4_fill_fsxattr(struct inode *inode, struct fsxattr *fa) | 
|---|
| 745 | 777 | { | 
|---|
| 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; | 
|---|
|  | 778 | +	struct ext4_inode_info *ei = EXT4_I(inode); | 
|---|
| 753 | 779 |  | 
|---|
| 754 |  | -	if (__kprojid_val(EXT4_I(inode)->i_projid) != fa->fsx_projid) | 
|---|
| 755 |  | -		return -EINVAL; | 
|---|
|  | 780 | +	simple_fill_fsxattr(fa, ext4_iflags_to_xflags(ei->i_flags & | 
|---|
|  | 781 | +						      EXT4_FL_USER_VISIBLE)); | 
|---|
| 756 | 782 |  | 
|---|
| 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; | 
|---|
|  | 783 | +	if (ext4_has_feature_project(inode->i_sb)) | 
|---|
|  | 784 | +		fa->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid); | 
|---|
| 766 | 785 | } | 
|---|
| 767 | 786 |  | 
|---|
| 768 |  | -long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 
|---|
|  | 787 | +/* So that the fiemap access checks can't overflow on 32 bit machines. */ | 
|---|
|  | 788 | +#define FIEMAP_MAX_EXTENTS	(UINT_MAX / sizeof(struct fiemap_extent)) | 
|---|
|  | 789 | + | 
|---|
|  | 790 | +static int ext4_ioctl_get_es_cache(struct file *filp, unsigned long arg) | 
|---|
|  | 791 | +{ | 
|---|
|  | 792 | +	struct fiemap fiemap; | 
|---|
|  | 793 | +	struct fiemap __user *ufiemap = (struct fiemap __user *) arg; | 
|---|
|  | 794 | +	struct fiemap_extent_info fieinfo = { 0, }; | 
|---|
|  | 795 | +	struct inode *inode = file_inode(filp); | 
|---|
|  | 796 | +	int error; | 
|---|
|  | 797 | + | 
|---|
|  | 798 | +	if (copy_from_user(&fiemap, ufiemap, sizeof(fiemap))) | 
|---|
|  | 799 | +		return -EFAULT; | 
|---|
|  | 800 | + | 
|---|
|  | 801 | +	if (fiemap.fm_extent_count > FIEMAP_MAX_EXTENTS) | 
|---|
|  | 802 | +		return -EINVAL; | 
|---|
|  | 803 | + | 
|---|
|  | 804 | +	fieinfo.fi_flags = fiemap.fm_flags; | 
|---|
|  | 805 | +	fieinfo.fi_extents_max = fiemap.fm_extent_count; | 
|---|
|  | 806 | +	fieinfo.fi_extents_start = ufiemap->fm_extents; | 
|---|
|  | 807 | + | 
|---|
|  | 808 | +	error = ext4_get_es_cache(inode, &fieinfo, fiemap.fm_start, | 
|---|
|  | 809 | +			fiemap.fm_length); | 
|---|
|  | 810 | +	fiemap.fm_flags = fieinfo.fi_flags; | 
|---|
|  | 811 | +	fiemap.fm_mapped_extents = fieinfo.fi_extents_mapped; | 
|---|
|  | 812 | +	if (copy_to_user(ufiemap, &fiemap, sizeof(fiemap))) | 
|---|
|  | 813 | +		error = -EFAULT; | 
|---|
|  | 814 | + | 
|---|
|  | 815 | +	return error; | 
|---|
|  | 816 | +} | 
|---|
|  | 817 | + | 
|---|
|  | 818 | +static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 
|---|
| 769 | 819 | { | 
|---|
| 770 | 820 | struct inode *inode = file_inode(filp); | 
|---|
| 771 | 821 | struct super_block *sb = inode->i_sb; | 
|---|
| .. | .. | 
|---|
| 777 | 827 | switch (cmd) { | 
|---|
| 778 | 828 | case FS_IOC_GETFSMAP: | 
|---|
| 779 | 829 | return ext4_ioc_getfsmap(sb, (void __user *)arg); | 
|---|
| 780 |  | -	case EXT4_IOC_GETFLAGS: | 
|---|
|  | 830 | +	case FS_IOC_GETFLAGS: | 
|---|
| 781 | 831 | flags = ei->i_flags & EXT4_FL_USER_VISIBLE; | 
|---|
|  | 832 | +		if (S_ISREG(inode->i_mode)) | 
|---|
|  | 833 | +			flags &= ~EXT4_PROJINHERIT_FL; | 
|---|
| 782 | 834 | return put_user(flags, (int __user *) arg); | 
|---|
| 783 |  | -	case EXT4_IOC_SETFLAGS: { | 
|---|
|  | 835 | +	case FS_IOC_SETFLAGS: { | 
|---|
| 784 | 836 | int err; | 
|---|
| 785 | 837 |  | 
|---|
| 786 | 838 | if (!inode_owner_or_capable(inode)) | 
|---|
| .. | .. | 
|---|
| 1030 | 1082 |  | 
|---|
| 1031 | 1083 | err = ext4_resize_fs(sb, n_blocks_count); | 
|---|
| 1032 | 1084 | if (EXT4_SB(sb)->s_journal) { | 
|---|
|  | 1085 | +			ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_RESIZE); | 
|---|
| 1033 | 1086 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 
|---|
| 1034 | 1087 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 
|---|
| 1035 | 1088 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 
|---|
| .. | .. | 
|---|
| 1083 | 1136 | case EXT4_IOC_PRECACHE_EXTENTS: | 
|---|
| 1084 | 1137 | return ext4_ext_precache(inode); | 
|---|
| 1085 | 1138 |  | 
|---|
| 1086 |  | -	case EXT4_IOC_SET_ENCRYPTION_POLICY: | 
|---|
|  | 1139 | +	case FS_IOC_SET_ENCRYPTION_POLICY: | 
|---|
| 1087 | 1140 | if (!ext4_has_feature_encrypt(sb)) | 
|---|
| 1088 | 1141 | return -EOPNOTSUPP; | 
|---|
| 1089 | 1142 | return fscrypt_ioctl_set_policy(filp, (const void __user *)arg); | 
|---|
| 1090 | 1143 |  | 
|---|
| 1091 |  | -	case EXT4_IOC_GET_ENCRYPTION_PWSALT: { | 
|---|
|  | 1144 | +	case FS_IOC_GET_ENCRYPTION_PWSALT: { | 
|---|
| 1092 | 1145 | #ifdef CONFIG_FS_ENCRYPTION | 
|---|
| 1093 | 1146 | int err, err2; | 
|---|
| 1094 | 1147 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 
|---|
| .. | .. | 
|---|
| 1131 | 1184 | return -EOPNOTSUPP; | 
|---|
| 1132 | 1185 | #endif | 
|---|
| 1133 | 1186 | } | 
|---|
| 1134 |  | -	case EXT4_IOC_GET_ENCRYPTION_POLICY: | 
|---|
|  | 1187 | +	case FS_IOC_GET_ENCRYPTION_POLICY: | 
|---|
| 1135 | 1188 | if (!ext4_has_feature_encrypt(sb)) | 
|---|
| 1136 | 1189 | return -EOPNOTSUPP; | 
|---|
| 1137 | 1190 | return fscrypt_ioctl_get_policy(filp, (void __user *)arg); | 
|---|
| .. | .. | 
|---|
| 1166 | 1219 | return -EOPNOTSUPP; | 
|---|
| 1167 | 1220 | return fscrypt_ioctl_get_nonce(filp, (void __user *)arg); | 
|---|
| 1168 | 1221 |  | 
|---|
| 1169 |  | -	case EXT4_IOC_FSGETXATTR: | 
|---|
|  | 1222 | +	case EXT4_IOC_CLEAR_ES_CACHE: | 
|---|
|  | 1223 | +	{ | 
|---|
|  | 1224 | +		if (!inode_owner_or_capable(inode)) | 
|---|
|  | 1225 | +			return -EACCES; | 
|---|
|  | 1226 | +		ext4_clear_inode_es(inode); | 
|---|
|  | 1227 | +		return 0; | 
|---|
|  | 1228 | +	} | 
|---|
|  | 1229 | + | 
|---|
|  | 1230 | +	case EXT4_IOC_GETSTATE: | 
|---|
|  | 1231 | +	{ | 
|---|
|  | 1232 | +		__u32	state = 0; | 
|---|
|  | 1233 | + | 
|---|
|  | 1234 | +		if (ext4_test_inode_state(inode, EXT4_STATE_EXT_PRECACHED)) | 
|---|
|  | 1235 | +			state |= EXT4_STATE_FLAG_EXT_PRECACHED; | 
|---|
|  | 1236 | +		if (ext4_test_inode_state(inode, EXT4_STATE_NEW)) | 
|---|
|  | 1237 | +			state |= EXT4_STATE_FLAG_NEW; | 
|---|
|  | 1238 | +		if (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) | 
|---|
|  | 1239 | +			state |= EXT4_STATE_FLAG_NEWENTRY; | 
|---|
|  | 1240 | +		if (ext4_test_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE)) | 
|---|
|  | 1241 | +			state |= EXT4_STATE_FLAG_DA_ALLOC_CLOSE; | 
|---|
|  | 1242 | + | 
|---|
|  | 1243 | +		return put_user(state, (__u32 __user *) arg); | 
|---|
|  | 1244 | +	} | 
|---|
|  | 1245 | + | 
|---|
|  | 1246 | +	case EXT4_IOC_GET_ES_CACHE: | 
|---|
|  | 1247 | +		return ext4_ioctl_get_es_cache(filp, arg); | 
|---|
|  | 1248 | + | 
|---|
|  | 1249 | +	case FS_IOC_FSGETXATTR: | 
|---|
| 1170 | 1250 | { | 
|---|
| 1171 | 1251 | struct fsxattr fa; | 
|---|
| 1172 | 1252 |  | 
|---|
| 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 |  | -		} | 
|---|
|  | 1253 | +		ext4_fill_fsxattr(inode, &fa); | 
|---|
| 1180 | 1254 |  | 
|---|
| 1181 | 1255 | if (copy_to_user((struct fsxattr __user *)arg, | 
|---|
| 1182 | 1256 | &fa, sizeof(fa))) | 
|---|
| 1183 | 1257 | return -EFAULT; | 
|---|
| 1184 | 1258 | return 0; | 
|---|
| 1185 | 1259 | } | 
|---|
| 1186 |  | -	case EXT4_IOC_FSSETXATTR: | 
|---|
|  | 1260 | +	case FS_IOC_FSSETXATTR: | 
|---|
| 1187 | 1261 | { | 
|---|
| 1188 |  | -		struct fsxattr fa; | 
|---|
|  | 1262 | +		struct fsxattr fa, old_fa; | 
|---|
| 1189 | 1263 | int err; | 
|---|
| 1190 | 1264 |  | 
|---|
| 1191 | 1265 | if (copy_from_user(&fa, (struct fsxattr __user *)arg, | 
|---|
| .. | .. | 
|---|
| 1208 | 1282 | return err; | 
|---|
| 1209 | 1283 |  | 
|---|
| 1210 | 1284 | inode_lock(inode); | 
|---|
| 1211 |  | -		err = ext4_ioctl_check_project(inode, &fa); | 
|---|
|  | 1285 | +		ext4_fill_fsxattr(inode, &old_fa); | 
|---|
|  | 1286 | +		err = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa); | 
|---|
| 1212 | 1287 | if (err) | 
|---|
| 1213 | 1288 | goto out; | 
|---|
| 1214 | 1289 | flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) | | 
|---|
| .. | .. | 
|---|
| 1238 | 1313 | return -EOPNOTSUPP; | 
|---|
| 1239 | 1314 | return fsverity_ioctl_measure(filp, (void __user *)arg); | 
|---|
| 1240 | 1315 |  | 
|---|
|  | 1316 | +	case FS_IOC_READ_VERITY_METADATA: | 
|---|
|  | 1317 | +		if (!ext4_has_feature_verity(sb)) | 
|---|
|  | 1318 | +			return -EOPNOTSUPP; | 
|---|
|  | 1319 | +		return fsverity_ioctl_read_metadata(filp, | 
|---|
|  | 1320 | +						    (const void __user *)arg); | 
|---|
|  | 1321 | + | 
|---|
| 1241 | 1322 | default: | 
|---|
| 1242 | 1323 | return -ENOTTY; | 
|---|
| 1243 | 1324 | } | 
|---|
|  | 1325 | +} | 
|---|
|  | 1326 | + | 
|---|
|  | 1327 | +long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 
|---|
|  | 1328 | +{ | 
|---|
|  | 1329 | +	long ret; | 
|---|
|  | 1330 | + | 
|---|
|  | 1331 | +	ext4_fc_start_update(file_inode(filp)); | 
|---|
|  | 1332 | +	ret = __ext4_ioctl(filp, cmd, arg); | 
|---|
|  | 1333 | +	ext4_fc_stop_update(file_inode(filp)); | 
|---|
|  | 1334 | + | 
|---|
|  | 1335 | +	return ret; | 
|---|
| 1244 | 1336 | } | 
|---|
| 1245 | 1337 |  | 
|---|
| 1246 | 1338 | #ifdef CONFIG_COMPAT | 
|---|
| .. | .. | 
|---|
| 1248 | 1340 | { | 
|---|
| 1249 | 1341 | /* These are just misnamed, they actually get/put from/to user an int */ | 
|---|
| 1250 | 1342 | switch (cmd) { | 
|---|
| 1251 |  | -	case EXT4_IOC32_GETFLAGS: | 
|---|
| 1252 |  | -		cmd = EXT4_IOC_GETFLAGS; | 
|---|
|  | 1343 | +	case FS_IOC32_GETFLAGS: | 
|---|
|  | 1344 | +		cmd = FS_IOC_GETFLAGS; | 
|---|
| 1253 | 1345 | break; | 
|---|
| 1254 |  | -	case EXT4_IOC32_SETFLAGS: | 
|---|
| 1255 |  | -		cmd = EXT4_IOC_SETFLAGS; | 
|---|
|  | 1346 | +	case FS_IOC32_SETFLAGS: | 
|---|
|  | 1347 | +		cmd = FS_IOC_SETFLAGS; | 
|---|
| 1256 | 1348 | break; | 
|---|
| 1257 | 1349 | case EXT4_IOC32_GETVERSION: | 
|---|
| 1258 | 1350 | cmd = EXT4_IOC_GETVERSION; | 
|---|
| .. | .. | 
|---|
| 1294 | 1386 | } | 
|---|
| 1295 | 1387 | case EXT4_IOC_MOVE_EXT: | 
|---|
| 1296 | 1388 | case EXT4_IOC_RESIZE_FS: | 
|---|
|  | 1389 | +	case FITRIM: | 
|---|
| 1297 | 1390 | 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: | 
|---|
|  | 1391 | +	case FS_IOC_SET_ENCRYPTION_POLICY: | 
|---|
|  | 1392 | +	case FS_IOC_GET_ENCRYPTION_PWSALT: | 
|---|
|  | 1393 | +	case FS_IOC_GET_ENCRYPTION_POLICY: | 
|---|
| 1301 | 1394 | case FS_IOC_GET_ENCRYPTION_POLICY_EX: | 
|---|
| 1302 | 1395 | case FS_IOC_ADD_ENCRYPTION_KEY: | 
|---|
| 1303 | 1396 | case FS_IOC_REMOVE_ENCRYPTION_KEY: | 
|---|
| .. | .. | 
|---|
| 1308 | 1401 | case FS_IOC_GETFSMAP: | 
|---|
| 1309 | 1402 | case FS_IOC_ENABLE_VERITY: | 
|---|
| 1310 | 1403 | case FS_IOC_MEASURE_VERITY: | 
|---|
| 1311 |  | -	case EXT4_IOC_FSGETXATTR: | 
|---|
| 1312 |  | -	case EXT4_IOC_FSSETXATTR: | 
|---|
|  | 1404 | +	case FS_IOC_READ_VERITY_METADATA: | 
|---|
|  | 1405 | +	case EXT4_IOC_CLEAR_ES_CACHE: | 
|---|
|  | 1406 | +	case EXT4_IOC_GETSTATE: | 
|---|
|  | 1407 | +	case EXT4_IOC_GET_ES_CACHE: | 
|---|
|  | 1408 | +	case FS_IOC_FSGETXATTR: | 
|---|
|  | 1409 | +	case FS_IOC_FSSETXATTR: | 
|---|
| 1313 | 1410 | break; | 
|---|
| 1314 | 1411 | default: | 
|---|
| 1315 | 1412 | return -ENOIOCTLCMD; | 
|---|