forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/fs/ext4/ioctl.c
....@@ -86,7 +86,7 @@
8686 i_size_write(inode2, isize);
8787 }
8888
89
-static void reset_inode_seed(struct inode *inode)
89
+void ext4_reset_inode_seed(struct inode *inode)
9090 {
9191 struct ext4_inode_info *ei = EXT4_I(inode);
9292 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
....@@ -165,6 +165,7 @@
165165 err = -EINVAL;
166166 goto err_out;
167167 }
168
+ ext4_fc_start_ineligible(sb, EXT4_FC_REASON_SWAP_BOOT);
168169
169170 /* Protect extent tree against block allocations via delalloc */
170171 ext4_double_down_write_data_sem(inode, inode_bl);
....@@ -199,10 +200,10 @@
199200
200201 inode->i_generation = prandom_u32();
201202 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);
204205
205
- ext4_discard_preallocations(inode);
206
+ ext4_discard_preallocations(inode, 0);
206207
207208 err = ext4_mark_inode_dirty(handle, inode);
208209 if (err < 0) {
....@@ -247,6 +248,7 @@
247248
248249 err_out1:
249250 ext4_journal_stop(handle);
251
+ ext4_fc_stop_ineligible(sb);
250252 ext4_double_up_write_data_sem(inode, inode_bl);
251253
252254 err_out:
....@@ -292,6 +294,44 @@
292294 return 0;
293295 }
294296
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
+
295335 static int ext4_ioctl_setflags(struct inode *inode,
296336 unsigned int flags)
297337 {
....@@ -300,7 +340,6 @@
300340 int err = -EPERM, migrate = 0;
301341 struct ext4_iloc iloc;
302342 unsigned int oldflags, mask, i;
303
- unsigned int jflag;
304343 struct super_block *sb = inode->i_sb;
305344
306345 /* Is it quota file? Do not allow user to mess with it */
....@@ -309,42 +348,26 @@
309348
310349 oldflags = ei->i_flags;
311350
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;
325354
326355 /*
327356 * The JOURNAL_DATA flag can only be changed by
328357 * the relevant capability.
329358 */
330
- if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
359
+ if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
331360 if (!capable(CAP_SYS_RESOURCE))
332361 goto flags_out;
333362 }
363
+
364
+ if (!dax_compatible(inode, oldflags, flags)) {
365
+ err = -EOPNOTSUPP;
366
+ goto flags_out;
367
+ }
368
+
334369 if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
335370 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
- }
348371
349372 if ((flags ^ oldflags) & EXT4_CASEFOLD_FL) {
350373 if (!ext4_has_feature_casefold(sb)) {
....@@ -388,6 +411,8 @@
388411 if (err)
389412 goto flags_err;
390413
414
+ ext4_dax_dontcache(inode, flags);
415
+
391416 for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
392417 if (!(mask & EXT4_FL_USER_MODIFIABLE))
393418 continue;
....@@ -400,7 +425,8 @@
400425 ext4_clear_inode_flag(inode, i);
401426 }
402427
403
- ext4_set_inode_flags(inode);
428
+ ext4_set_inode_flags(inode, false);
429
+
404430 inode->i_ctime = current_time(inode);
405431
406432 err = ext4_mark_iloc_dirty(handle, inode, &iloc);
....@@ -409,17 +435,18 @@
409435 if (err)
410436 goto flags_out;
411437
412
- if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
438
+ if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
413439 /*
414440 * 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
416442 */
417
- if (test_opt(inode->i_sb, DAX)) {
443
+ if (IS_DAX(inode)) {
418444 err = -EBUSY;
419445 goto flags_out;
420446 }
421447
422
- err = ext4_change_inode_journal_flag(inode, jflag);
448
+ err = ext4_change_inode_journal_flag(inode,
449
+ flags & EXT4_JOURNAL_DATA_FL);
423450 if (err)
424451 goto flags_out;
425452 }
....@@ -546,12 +573,15 @@
546573 xflags |= FS_XFLAG_NOATIME;
547574 if (iflags & EXT4_PROJINHERIT_FL)
548575 xflags |= FS_XFLAG_PROJINHERIT;
576
+ if (iflags & EXT4_DAX_FL)
577
+ xflags |= FS_XFLAG_DAX;
549578 return xflags;
550579 }
551580
552581 #define EXT4_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \
553582 FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \
554
- FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT)
583
+ FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT | \
584
+ FS_XFLAG_DAX)
555585
556586 /* Transfer xflags flags to internal */
557587 static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)
....@@ -570,6 +600,8 @@
570600 iflags |= EXT4_NOATIME_FL;
571601 if (xflags & FS_XFLAG_PROJINHERIT)
572602 iflags |= EXT4_PROJINHERIT_FL;
603
+ if (xflags & FS_XFLAG_DAX)
604
+ iflags |= EXT4_DAX_FL;
573605
574606 return iflags;
575607 }
....@@ -598,7 +630,7 @@
598630 case EXT4_GOING_FLAGS_DEFAULT:
599631 freeze_bdev(sb->s_bdev);
600632 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
601
- thaw_bdev(sb->s_bdev, sb);
633
+ thaw_bdev(sb->s_bdev);
602634 break;
603635 case EXT4_GOING_FLAGS_LOGFLUSH:
604636 set_bit(EXT4_FLAGS_SHUTDOWN, &sbi->s_ext4_flags);
....@@ -645,7 +677,7 @@
645677 static int ext4_ioc_getfsmap(struct super_block *sb,
646678 struct fsmap_head __user *arg)
647679 {
648
- struct getfsmap_info info = {0};
680
+ struct getfsmap_info info = { NULL };
649681 struct ext4_fsmap_head xhead = {0};
650682 struct fsmap_head head;
651683 bool aborted = false;
....@@ -741,31 +773,49 @@
741773 return err;
742774 }
743775
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)
745777 {
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);
753779
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));
756782
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);
766785 }
767786
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)
769819 {
770820 struct inode *inode = file_inode(filp);
771821 struct super_block *sb = inode->i_sb;
....@@ -777,10 +827,12 @@
777827 switch (cmd) {
778828 case FS_IOC_GETFSMAP:
779829 return ext4_ioc_getfsmap(sb, (void __user *)arg);
780
- case EXT4_IOC_GETFLAGS:
830
+ case FS_IOC_GETFLAGS:
781831 flags = ei->i_flags & EXT4_FL_USER_VISIBLE;
832
+ if (S_ISREG(inode->i_mode))
833
+ flags &= ~EXT4_PROJINHERIT_FL;
782834 return put_user(flags, (int __user *) arg);
783
- case EXT4_IOC_SETFLAGS: {
835
+ case FS_IOC_SETFLAGS: {
784836 int err;
785837
786838 if (!inode_owner_or_capable(inode))
....@@ -1030,6 +1082,7 @@
10301082
10311083 err = ext4_resize_fs(sb, n_blocks_count);
10321084 if (EXT4_SB(sb)->s_journal) {
1085
+ ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_RESIZE);
10331086 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
10341087 err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
10351088 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
....@@ -1083,12 +1136,12 @@
10831136 case EXT4_IOC_PRECACHE_EXTENTS:
10841137 return ext4_ext_precache(inode);
10851138
1086
- case EXT4_IOC_SET_ENCRYPTION_POLICY:
1139
+ case FS_IOC_SET_ENCRYPTION_POLICY:
10871140 if (!ext4_has_feature_encrypt(sb))
10881141 return -EOPNOTSUPP;
10891142 return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
10901143
1091
- case EXT4_IOC_GET_ENCRYPTION_PWSALT: {
1144
+ case FS_IOC_GET_ENCRYPTION_PWSALT: {
10921145 #ifdef CONFIG_FS_ENCRYPTION
10931146 int err, err2;
10941147 struct ext4_sb_info *sbi = EXT4_SB(sb);
....@@ -1131,7 +1184,7 @@
11311184 return -EOPNOTSUPP;
11321185 #endif
11331186 }
1134
- case EXT4_IOC_GET_ENCRYPTION_POLICY:
1187
+ case FS_IOC_GET_ENCRYPTION_POLICY:
11351188 if (!ext4_has_feature_encrypt(sb))
11361189 return -EOPNOTSUPP;
11371190 return fscrypt_ioctl_get_policy(filp, (void __user *)arg);
....@@ -1166,26 +1219,47 @@
11661219 return -EOPNOTSUPP;
11671220 return fscrypt_ioctl_get_nonce(filp, (void __user *)arg);
11681221
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:
11701250 {
11711251 struct fsxattr fa;
11721252
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);
11801254
11811255 if (copy_to_user((struct fsxattr __user *)arg,
11821256 &fa, sizeof(fa)))
11831257 return -EFAULT;
11841258 return 0;
11851259 }
1186
- case EXT4_IOC_FSSETXATTR:
1260
+ case FS_IOC_FSSETXATTR:
11871261 {
1188
- struct fsxattr fa;
1262
+ struct fsxattr fa, old_fa;
11891263 int err;
11901264
11911265 if (copy_from_user(&fa, (struct fsxattr __user *)arg,
....@@ -1208,7 +1282,8 @@
12081282 return err;
12091283
12101284 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);
12121287 if (err)
12131288 goto out;
12141289 flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) |
....@@ -1238,9 +1313,26 @@
12381313 return -EOPNOTSUPP;
12391314 return fsverity_ioctl_measure(filp, (void __user *)arg);
12401315
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
+
12411322 default:
12421323 return -ENOTTY;
12431324 }
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;
12441336 }
12451337
12461338 #ifdef CONFIG_COMPAT
....@@ -1248,11 +1340,11 @@
12481340 {
12491341 /* These are just misnamed, they actually get/put from/to user an int */
12501342 switch (cmd) {
1251
- case EXT4_IOC32_GETFLAGS:
1252
- cmd = EXT4_IOC_GETFLAGS;
1343
+ case FS_IOC32_GETFLAGS:
1344
+ cmd = FS_IOC_GETFLAGS;
12531345 break;
1254
- case EXT4_IOC32_SETFLAGS:
1255
- cmd = EXT4_IOC_SETFLAGS;
1346
+ case FS_IOC32_SETFLAGS:
1347
+ cmd = FS_IOC_SETFLAGS;
12561348 break;
12571349 case EXT4_IOC32_GETVERSION:
12581350 cmd = EXT4_IOC_GETVERSION;
....@@ -1294,10 +1386,11 @@
12941386 }
12951387 case EXT4_IOC_MOVE_EXT:
12961388 case EXT4_IOC_RESIZE_FS:
1389
+ case FITRIM:
12971390 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:
13011394 case FS_IOC_GET_ENCRYPTION_POLICY_EX:
13021395 case FS_IOC_ADD_ENCRYPTION_KEY:
13031396 case FS_IOC_REMOVE_ENCRYPTION_KEY:
....@@ -1308,8 +1401,12 @@
13081401 case FS_IOC_GETFSMAP:
13091402 case FS_IOC_ENABLE_VERITY:
13101403 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:
13131410 break;
13141411 default:
13151412 return -ENOIOCTLCMD;