hc
2024-10-09 05e59e5fb0064c97a1c10921ecd549f2d4a58565
kernel/fs/incfs/data_mgmt.c
....@@ -3,7 +3,6 @@
33 * Copyright 2019 Google LLC
44 */
55 #include <linux/crc32.h>
6
-#include <linux/delay.h>
76 #include <linux/file.h>
87 #include <linux/fsverity.h>
98 #include <linux/gfp.h>
....@@ -1104,25 +1103,10 @@
11041103 wake_up_all(&mi->mi_blocks_written_notif_wq);
11051104 }
11061105
1107
-static int usleep_interruptible(u32 us)
1108
-{
1109
- /* See:
1110
- * https://www.kernel.org/doc/Documentation/timers/timers-howto.txt
1111
- * for explanation
1112
- */
1113
- if (us < 10) {
1114
- udelay(us);
1115
- return 0;
1116
- } else if (us < 20000) {
1117
- usleep_range(us, us + us / 10);
1118
- return 0;
1119
- } else
1120
- return msleep_interruptible(us / 1000);
1121
-}
1122
-
11231106 static int wait_for_data_block(struct data_file *df, int block_index,
11241107 struct data_file_block *res_block,
1125
- struct incfs_read_data_file_timeouts *timeouts)
1108
+ struct incfs_read_data_file_timeouts *timeouts,
1109
+ unsigned int *delayed_min_us)
11261110 {
11271111 struct data_file_block block = {};
11281112 struct data_file_segment *segment = NULL;
....@@ -1130,7 +1114,7 @@
11301114 struct mount_info *mi = NULL;
11311115 int error;
11321116 int wait_res = 0;
1133
- unsigned int delayed_pending_us = 0, delayed_min_us = 0;
1117
+ unsigned int delayed_pending_us = 0;
11341118 bool delayed_pending = false;
11351119
11361120 if (!df || !res_block)
....@@ -1161,8 +1145,7 @@
11611145 if (is_data_block_present(&block)) {
11621146 *res_block = block;
11631147 if (timeouts && timeouts->min_time_us) {
1164
- delayed_min_us = timeouts->min_time_us;
1165
- error = usleep_interruptible(delayed_min_us);
1148
+ *delayed_min_us = timeouts->min_time_us;
11661149 goto out;
11671150 }
11681151 return 0;
....@@ -1209,13 +1192,9 @@
12091192 delayed_pending = true;
12101193 delayed_pending_us = timeouts->max_pending_time_us -
12111194 jiffies_to_usecs(wait_res);
1212
- if (timeouts->min_pending_time_us > delayed_pending_us) {
1213
- delayed_min_us = timeouts->min_pending_time_us -
1195
+ if (timeouts->min_pending_time_us > delayed_pending_us)
1196
+ *delayed_min_us = timeouts->min_pending_time_us -
12141197 delayed_pending_us;
1215
- error = usleep_interruptible(delayed_min_us);
1216
- if (error)
1217
- return error;
1218
- }
12191198
12201199 error = down_read_killable(&segment->rwsem);
12211200 if (error)
....@@ -1250,9 +1229,9 @@
12501229 delayed_pending_us;
12511230 }
12521231
1253
- if (delayed_min_us) {
1232
+ if (delayed_min_us && *delayed_min_us) {
12541233 mi->mi_reads_delayed_min++;
1255
- mi->mi_reads_delayed_min_us += delayed_min_us;
1234
+ mi->mi_reads_delayed_min_us += *delayed_min_us;
12561235 }
12571236
12581237 return 0;
....@@ -1282,7 +1261,8 @@
12821261
12831262 ssize_t incfs_read_data_file_block(struct mem_range dst, struct file *f,
12841263 int index, struct mem_range tmp,
1285
- struct incfs_read_data_file_timeouts *timeouts)
1264
+ struct incfs_read_data_file_timeouts *timeouts,
1265
+ unsigned int *delayed_min_us)
12861266 {
12871267 loff_t pos;
12881268 ssize_t result;
....@@ -1301,7 +1281,8 @@
13011281 mi = df->df_mount_info;
13021282 bfc = df->df_backing_file_context;
13031283
1304
- result = wait_for_data_block(df, index, &block, timeouts);
1284
+ result = wait_for_data_block(df, index, &block, timeouts,
1285
+ delayed_min_us);
13051286 if (result < 0)
13061287 goto out;
13071288
....@@ -1379,7 +1360,8 @@
13791360 }
13801361
13811362 int incfs_process_new_data_block(struct data_file *df,
1382
- struct incfs_fill_block *block, u8 *data)
1363
+ struct incfs_fill_block *block, u8 *data,
1364
+ bool *complete)
13831365 {
13841366 struct mount_info *mi = NULL;
13851367 struct backing_file_context *bfc = NULL;
....@@ -1418,27 +1400,42 @@
14181400
14191401 if (error)
14201402 return error;
1421
- if (is_data_block_present(&existing_block)) {
1403
+ if (is_data_block_present(&existing_block))
14221404 /* Block is already present, nothing to do here */
14231405 return 0;
1424
- }
14251406
14261407 error = down_write_killable(&segment->rwsem);
14271408 if (error)
14281409 return error;
14291410
1430
- error = mutex_lock_interruptible(&bfc->bc_mutex);
1431
- if (!error) {
1432
- error = incfs_write_data_block_to_backing_file(
1433
- bfc, range(data, block->data_len), block->block_index,
1434
- df->df_blockmap_off, flags);
1435
- mutex_unlock(&bfc->bc_mutex);
1436
- }
1437
- if (!error) {
1438
- notify_pending_reads(mi, segment, block->block_index);
1439
- atomic_inc(&df->df_data_blocks_written);
1440
- }
1411
+ /* Recheck inside write lock */
1412
+ error = get_data_file_block(df, block->block_index, &existing_block);
1413
+ if (error)
1414
+ goto out_up_write;
14411415
1416
+ if (is_data_block_present(&existing_block))
1417
+ goto out_up_write;
1418
+
1419
+ error = mutex_lock_interruptible(&bfc->bc_mutex);
1420
+ if (error)
1421
+ goto out_up_write;
1422
+
1423
+ error = incfs_write_data_block_to_backing_file(bfc,
1424
+ range(data, block->data_len), block->block_index,
1425
+ df->df_blockmap_off, flags);
1426
+ if (error)
1427
+ goto out_mutex_unlock;
1428
+
1429
+ if (atomic_inc_return(&df->df_data_blocks_written)
1430
+ >= df->df_data_block_count)
1431
+ *complete = true;
1432
+
1433
+out_mutex_unlock:
1434
+ mutex_unlock(&bfc->bc_mutex);
1435
+ if (!error)
1436
+ notify_pending_reads(mi, segment, block->block_index);
1437
+
1438
+out_up_write:
14421439 up_write(&segment->rwsem);
14431440
14441441 if (error)