.. | .. |
---|
222 | 222 | int ext4_reserve_inode_write(handle_t *handle, struct inode *inode, |
---|
223 | 223 | struct ext4_iloc *iloc); |
---|
224 | 224 | |
---|
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); |
---|
226 | 229 | |
---|
227 | 230 | int ext4_expand_extra_isize(struct inode *inode, |
---|
228 | 231 | unsigned int new_extra_isize, |
---|
.. | .. |
---|
261 | 264 | __ext4_handle_dirty_super(__func__, __LINE__, (handle), (sb)) |
---|
262 | 265 | |
---|
263 | 266 | 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); |
---|
265 | 269 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle); |
---|
266 | 270 | |
---|
267 | 271 | #define EXT4_NOJOURNAL_MAX_REF_COUNT ((unsigned long) 4096) |
---|
.. | .. |
---|
288 | 292 | return 0; |
---|
289 | 293 | } |
---|
290 | 294 | |
---|
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) |
---|
292 | 297 | { |
---|
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); |
---|
296 | 305 | } |
---|
297 | 306 | |
---|
298 | 307 | #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)) |
---|
300 | 310 | |
---|
301 | 311 | #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)) |
---|
303 | 314 | |
---|
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)) |
---|
306 | 322 | |
---|
307 | 323 | static inline handle_t *__ext4_journal_start(struct inode *inode, |
---|
308 | 324 | unsigned int line, int type, |
---|
309 | | - int blocks, int rsv_blocks) |
---|
| 325 | + int blocks, int rsv_blocks, |
---|
| 326 | + int revoke_creds) |
---|
310 | 327 | { |
---|
311 | 328 | return __ext4_journal_start_sb(inode->i_sb, line, type, blocks, |
---|
312 | | - rsv_blocks); |
---|
| 329 | + rsv_blocks, revoke_creds); |
---|
313 | 330 | } |
---|
314 | 331 | |
---|
315 | 332 | #define ext4_journal_stop(handle) \ |
---|
.. | .. |
---|
321 | 338 | handle_t *__ext4_journal_start_reserved(handle_t *handle, unsigned int line, |
---|
322 | 339 | int type); |
---|
323 | 340 | |
---|
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 | | - |
---|
330 | 341 | static inline handle_t *ext4_journal_current_handle(void) |
---|
331 | 342 | { |
---|
332 | 343 | return journal_current_handle(); |
---|
333 | 344 | } |
---|
334 | 345 | |
---|
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) |
---|
336 | 347 | { |
---|
337 | 348 | if (ext4_handle_valid(handle)) |
---|
338 | | - return jbd2_journal_extend(handle, nblocks); |
---|
| 349 | + return jbd2_journal_extend(handle, nblocks, revoke); |
---|
339 | 350 | return 0; |
---|
340 | 351 | } |
---|
341 | 352 | |
---|
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) |
---|
343 | 355 | { |
---|
344 | 356 | if (ext4_handle_valid(handle)) |
---|
345 | | - return jbd2_journal_restart(handle, nblocks); |
---|
| 357 | + return jbd2__journal_restart(handle, nblocks, revoke, GFP_NOFS); |
---|
346 | 358 | 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); |
---|
347 | 406 | } |
---|
348 | 407 | |
---|
349 | 408 | static inline int ext4_journal_blocks_per_page(struct inode *inode) |
---|
.. | .. |
---|
401 | 460 | #define EXT4_INODE_ORDERED_DATA_MODE 0x02 /* ordered data mode */ |
---|
402 | 461 | #define EXT4_INODE_WRITEBACK_DATA_MODE 0x04 /* writeback data mode */ |
---|
403 | 462 | |
---|
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); |
---|
424 | 464 | |
---|
425 | 465 | static inline int ext4_should_journal_data(struct inode *inode) |
---|
426 | 466 | { |
---|
.. | .. |
---|
435 | 475 | static inline int ext4_should_writeback_data(struct inode *inode) |
---|
436 | 476 | { |
---|
437 | 477 | 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); |
---|
438 | 491 | } |
---|
439 | 492 | |
---|
440 | 493 | /* |
---|
.. | .. |
---|
456 | 509 | return 0; |
---|
457 | 510 | if (ext4_should_journal_data(inode)) |
---|
458 | 511 | return 0; |
---|
| 512 | + /* temporary fix to prevent generic/422 test failures */ |
---|
| 513 | + if (!test_opt(inode->i_sb, DELALLOC)) |
---|
| 514 | + return 0; |
---|
459 | 515 | return 1; |
---|
460 | 516 | } |
---|
461 | 517 | |
---|