hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/ext4/ext4_jbd2.h
....@@ -222,7 +222,10 @@
222222 int ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
223223 struct ext4_iloc *iloc);
224224
225
-int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode);
225
+#define ext4_mark_inode_dirty(__h, __i) \
226
+ __ext4_mark_inode_dirty((__h), (__i), __func__, __LINE__)
227
+int __ext4_mark_inode_dirty(handle_t *handle, struct inode *inode,
228
+ const char *func, unsigned int line);
226229
227230 int ext4_expand_extra_isize(struct inode *inode,
228231 unsigned int new_extra_isize,
....@@ -261,7 +264,8 @@
261264 __ext4_handle_dirty_super(__func__, __LINE__, (handle), (sb))
262265
263266 handle_t *__ext4_journal_start_sb(struct super_block *sb, unsigned int line,
264
- int type, int blocks, int rsv_blocks);
267
+ int type, int blocks, int rsv_blocks,
268
+ int revoke_creds);
265269 int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle);
266270
267271 #define EXT4_NOJOURNAL_MAX_REF_COUNT ((unsigned long) 4096)
....@@ -288,28 +292,41 @@
288292 return 0;
289293 }
290294
291
-static inline int ext4_handle_has_enough_credits(handle_t *handle, int needed)
295
+static inline int ext4_free_metadata_revoke_credits(struct super_block *sb,
296
+ int blocks)
292297 {
293
- if (ext4_handle_valid(handle) && handle->h_buffer_credits < needed)
294
- return 0;
295
- return 1;
298
+ /* Freeing each metadata block can result in freeing one cluster */
299
+ return blocks * EXT4_SB(sb)->s_cluster_ratio;
300
+}
301
+
302
+static inline int ext4_trans_default_revoke_credits(struct super_block *sb)
303
+{
304
+ return ext4_free_metadata_revoke_credits(sb, 8);
296305 }
297306
298307 #define ext4_journal_start_sb(sb, type, nblocks) \
299
- __ext4_journal_start_sb((sb), __LINE__, (type), (nblocks), 0)
308
+ __ext4_journal_start_sb((sb), __LINE__, (type), (nblocks), 0, \
309
+ ext4_trans_default_revoke_credits(sb))
300310
301311 #define ext4_journal_start(inode, type, nblocks) \
302
- __ext4_journal_start((inode), __LINE__, (type), (nblocks), 0)
312
+ __ext4_journal_start((inode), __LINE__, (type), (nblocks), 0, \
313
+ ext4_trans_default_revoke_credits((inode)->i_sb))
303314
304
-#define ext4_journal_start_with_reserve(inode, type, blocks, rsv_blocks) \
305
- __ext4_journal_start((inode), __LINE__, (type), (blocks), (rsv_blocks))
315
+#define ext4_journal_start_with_reserve(inode, type, blocks, rsv_blocks)\
316
+ __ext4_journal_start((inode), __LINE__, (type), (blocks), (rsv_blocks),\
317
+ ext4_trans_default_revoke_credits((inode)->i_sb))
318
+
319
+#define ext4_journal_start_with_revoke(inode, type, blocks, revoke_creds) \
320
+ __ext4_journal_start((inode), __LINE__, (type), (blocks), 0, \
321
+ (revoke_creds))
306322
307323 static inline handle_t *__ext4_journal_start(struct inode *inode,
308324 unsigned int line, int type,
309
- int blocks, int rsv_blocks)
325
+ int blocks, int rsv_blocks,
326
+ int revoke_creds)
310327 {
311328 return __ext4_journal_start_sb(inode->i_sb, line, type, blocks,
312
- rsv_blocks);
329
+ rsv_blocks, revoke_creds);
313330 }
314331
315332 #define ext4_journal_stop(handle) \
....@@ -321,29 +338,71 @@
321338 handle_t *__ext4_journal_start_reserved(handle_t *handle, unsigned int line,
322339 int type);
323340
324
-static inline void ext4_journal_free_reserved(handle_t *handle)
325
-{
326
- if (ext4_handle_valid(handle))
327
- jbd2_journal_free_reserved(handle);
328
-}
329
-
330341 static inline handle_t *ext4_journal_current_handle(void)
331342 {
332343 return journal_current_handle();
333344 }
334345
335
-static inline int ext4_journal_extend(handle_t *handle, int nblocks)
346
+static inline int ext4_journal_extend(handle_t *handle, int nblocks, int revoke)
336347 {
337348 if (ext4_handle_valid(handle))
338
- return jbd2_journal_extend(handle, nblocks);
349
+ return jbd2_journal_extend(handle, nblocks, revoke);
339350 return 0;
340351 }
341352
342
-static inline int ext4_journal_restart(handle_t *handle, int nblocks)
353
+static inline int ext4_journal_restart(handle_t *handle, int nblocks,
354
+ int revoke)
343355 {
344356 if (ext4_handle_valid(handle))
345
- return jbd2_journal_restart(handle, nblocks);
357
+ return jbd2__journal_restart(handle, nblocks, revoke, GFP_NOFS);
346358 return 0;
359
+}
360
+
361
+int __ext4_journal_ensure_credits(handle_t *handle, int check_cred,
362
+ int extend_cred, int revoke_cred);
363
+
364
+
365
+/*
366
+ * Ensure @handle has at least @check_creds credits available. If not,
367
+ * transaction will be extended or restarted to contain at least @extend_cred
368
+ * credits. Before restarting transaction @fn is executed to allow for cleanup
369
+ * before the transaction is restarted.
370
+ *
371
+ * The return value is < 0 in case of error, 0 in case the handle has enough
372
+ * credits or transaction extension succeeded, 1 in case transaction had to be
373
+ * restarted.
374
+ */
375
+#define ext4_journal_ensure_credits_fn(handle, check_cred, extend_cred, \
376
+ revoke_cred, fn) \
377
+({ \
378
+ __label__ __ensure_end; \
379
+ int err = __ext4_journal_ensure_credits((handle), (check_cred), \
380
+ (extend_cred), (revoke_cred)); \
381
+ \
382
+ if (err <= 0) \
383
+ goto __ensure_end; \
384
+ err = (fn); \
385
+ if (err < 0) \
386
+ goto __ensure_end; \
387
+ err = ext4_journal_restart((handle), (extend_cred), (revoke_cred)); \
388
+ if (err == 0) \
389
+ err = 1; \
390
+__ensure_end: \
391
+ err; \
392
+})
393
+
394
+/*
395
+ * Ensure given handle has at least requested amount of credits available,
396
+ * possibly restarting transaction if needed. We also make sure the transaction
397
+ * has space for at least ext4_trans_default_revoke_credits(sb) revoke records
398
+ * as freeing one or two blocks is very common pattern and requesting this is
399
+ * very cheap.
400
+ */
401
+static inline int ext4_journal_ensure_credits(handle_t *handle, int credits,
402
+ int revoke_creds)
403
+{
404
+ return ext4_journal_ensure_credits_fn(handle, credits, credits,
405
+ revoke_creds, 0);
347406 }
348407
349408 static inline int ext4_journal_blocks_per_page(struct inode *inode)
....@@ -401,26 +460,7 @@
401460 #define EXT4_INODE_ORDERED_DATA_MODE 0x02 /* ordered data mode */
402461 #define EXT4_INODE_WRITEBACK_DATA_MODE 0x04 /* writeback data mode */
403462
404
-static inline int ext4_inode_journal_mode(struct inode *inode)
405
-{
406
- if (EXT4_JOURNAL(inode) == NULL)
407
- return EXT4_INODE_WRITEBACK_DATA_MODE; /* writeback */
408
- /* We do not support data journalling with delayed allocation */
409
- if (!S_ISREG(inode->i_mode) ||
410
- test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
411
- (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
412
- !test_opt(inode->i_sb, DELALLOC))) {
413
- /* We do not support data journalling for encrypted data */
414
- if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode))
415
- return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */
416
- return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */
417
- }
418
- if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
419
- return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */
420
- if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
421
- return EXT4_INODE_WRITEBACK_DATA_MODE; /* writeback */
422
- BUG();
423
-}
463
+int ext4_inode_journal_mode(struct inode *inode);
424464
425465 static inline int ext4_should_journal_data(struct inode *inode)
426466 {
....@@ -435,6 +475,19 @@
435475 static inline int ext4_should_writeback_data(struct inode *inode)
436476 {
437477 return ext4_inode_journal_mode(inode) & EXT4_INODE_WRITEBACK_DATA_MODE;
478
+}
479
+
480
+static inline int ext4_free_data_revoke_credits(struct inode *inode, int blocks)
481
+{
482
+ if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
483
+ return 0;
484
+ if (!ext4_should_journal_data(inode))
485
+ return 0;
486
+ /*
487
+ * Data blocks in one extent are contiguous, just account for partial
488
+ * clusters at extent boundaries
489
+ */
490
+ return blocks + 2*(EXT4_SB(inode->i_sb)->s_cluster_ratio - 1);
438491 }
439492
440493 /*
....@@ -456,6 +509,9 @@
456509 return 0;
457510 if (ext4_should_journal_data(inode))
458511 return 0;
512
+ /* temporary fix to prevent generic/422 test failures */
513
+ if (!test_opt(inode->i_sb, DELALLOC))
514
+ return 0;
459515 return 1;
460516 }
461517