brintos

brintos / linux-shallow public Read only

0
0
Text · 17.2 KiB · 0c77697 Raw
517 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * ext4_jbd2.h4 *5 * Written by Stephen C. Tweedie <sct@redhat.com>, 19996 *7 * Copyright 1998--1999 Red Hat corp --- All Rights Reserved8 *9 * Ext4-specific journaling extensions.10 */11 12#ifndef _EXT4_JBD2_H13#define _EXT4_JBD2_H14 15#include <linux/fs.h>16#include <linux/jbd2.h>17#include "ext4.h"18 19#define EXT4_JOURNAL(inode)	(EXT4_SB((inode)->i_sb)->s_journal)20 21/* Define the number of blocks we need to account to a transaction to22 * modify one block of data.23 *24 * We may have to touch one inode, one bitmap buffer, up to three25 * indirection blocks, the group and superblock summaries, and the data26 * block to complete the transaction.27 *28 * For extents-enabled fs we may have to allocate and modify up to29 * 5 levels of tree, data block (for each of these we need bitmap + group30 * summaries), root which is stored in the inode, sb31 */32 33#define EXT4_SINGLEDATA_TRANS_BLOCKS(sb)				\34	(ext4_has_feature_extents(sb) ? 20U : 8U)35 36/* Extended attribute operations touch at most two data buffers,37 * two bitmap buffers, and two group summaries, in addition to the inode38 * and the superblock, which are already accounted for. */39 40#define EXT4_XATTR_TRANS_BLOCKS		6U41 42/* Define the minimum size for a transaction which modifies data.  This43 * needs to take into account the fact that we may end up modifying two44 * quota files too (one for the group, one for the user quota).  The45 * superblock only gets updated once, of course, so don't bother46 * counting that again for the quota updates. */47 48#define EXT4_DATA_TRANS_BLOCKS(sb)	(EXT4_SINGLEDATA_TRANS_BLOCKS(sb) + \49					 EXT4_XATTR_TRANS_BLOCKS - 2 + \50					 EXT4_MAXQUOTAS_TRANS_BLOCKS(sb))51 52/*53 * Define the number of metadata blocks we need to account to modify data.54 *55 * This include super block, inode block, quota blocks and xattr blocks56 */57#define EXT4_META_TRANS_BLOCKS(sb)	(EXT4_XATTR_TRANS_BLOCKS + \58					EXT4_MAXQUOTAS_TRANS_BLOCKS(sb))59 60/* Define an arbitrary limit for the amount of data we will anticipate61 * writing to any given transaction.  For unbounded transactions such as62 * write(2) and truncate(2) we can write more than this, but we always63 * start off at the maximum transaction size and grow the transaction64 * optimistically as we go. */65 66#define EXT4_MAX_TRANS_DATA		64U67 68/* We break up a large truncate or write transaction once the handle's69 * buffer credits gets this low, we need either to extend the70 * transaction or to start a new one.  Reserve enough space here for71 * inode, bitmap, superblock, group and indirection updates for at least72 * one block, plus two quota updates.  Quota allocations are not73 * needed. */74 75#define EXT4_RESERVE_TRANS_BLOCKS	12U76 77/*78 * Number of credits needed if we need to insert an entry into a79 * directory.  For each new index block, we need 4 blocks (old index80 * block, new index block, bitmap block, bg summary).  For normal81 * htree directories there are 2 levels; if the largedir feature82 * enabled it's 3 levels.83 */84#define EXT4_INDEX_EXTRA_TRANS_BLOCKS	12U85 86#ifdef CONFIG_QUOTA87/* Amount of blocks needed for quota update - we know that the structure was88 * allocated so we need to update only data block */89#define EXT4_QUOTA_TRANS_BLOCKS(sb) ((ext4_quota_capable(sb)) ? 1 : 0)90/* Amount of blocks needed for quota insert/delete - we do some block writes91 * but inode, sb and group updates are done only once */92#define EXT4_QUOTA_INIT_BLOCKS(sb) ((ext4_quota_capable(sb)) ?\93		(DQUOT_INIT_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\94		 +3+DQUOT_INIT_REWRITE) : 0)95 96#define EXT4_QUOTA_DEL_BLOCKS(sb) ((ext4_quota_capable(sb)) ?\97		(DQUOT_DEL_ALLOC*(EXT4_SINGLEDATA_TRANS_BLOCKS(sb)-3)\98		 +3+DQUOT_DEL_REWRITE) : 0)99#else100#define EXT4_QUOTA_TRANS_BLOCKS(sb) 0101#define EXT4_QUOTA_INIT_BLOCKS(sb) 0102#define EXT4_QUOTA_DEL_BLOCKS(sb) 0103#endif104#define EXT4_MAXQUOTAS_TRANS_BLOCKS(sb) (EXT4_MAXQUOTAS*EXT4_QUOTA_TRANS_BLOCKS(sb))105#define EXT4_MAXQUOTAS_INIT_BLOCKS(sb) (EXT4_MAXQUOTAS*EXT4_QUOTA_INIT_BLOCKS(sb))106#define EXT4_MAXQUOTAS_DEL_BLOCKS(sb) (EXT4_MAXQUOTAS*EXT4_QUOTA_DEL_BLOCKS(sb))107 108/*109 * Ext4 handle operation types -- for logging purposes110 */111#define EXT4_HT_MISC             0112#define EXT4_HT_INODE            1113#define EXT4_HT_WRITE_PAGE       2114#define EXT4_HT_MAP_BLOCKS       3115#define EXT4_HT_DIR              4116#define EXT4_HT_TRUNCATE         5117#define EXT4_HT_QUOTA            6118#define EXT4_HT_RESIZE           7119#define EXT4_HT_MIGRATE          8120#define EXT4_HT_MOVE_EXTENTS     9121#define EXT4_HT_XATTR           10122#define EXT4_HT_EXT_CONVERT     11123#define EXT4_HT_MAX             12124 125/**126 *   struct ext4_journal_cb_entry - Base structure for callback information.127 *128 *   This struct is a 'seed' structure for a using with your own callback129 *   structs. If you are using callbacks you must allocate one of these130 *   or another struct of your own definition which has this struct131 *   as it's first element and pass it to ext4_journal_callback_add().132 */133struct ext4_journal_cb_entry {134	/* list information for other callbacks attached to the same handle */135	struct list_head jce_list;136 137	/*  Function to call with this callback structure */138	void (*jce_func)(struct super_block *sb,139			 struct ext4_journal_cb_entry *jce, int error);140 141	/* user data goes here */142};143 144/**145 * ext4_journal_callback_add: add a function to call after transaction commit146 * @handle: active journal transaction handle to register callback on147 * @func: callback function to call after the transaction has committed:148 *        @sb: superblock of current filesystem for transaction149 *        @jce: returned journal callback data150 *        @rc: journal state at commit (0 = transaction committed properly)151 * @jce: journal callback data (internal and function private data struct)152 *153 * The registered function will be called in the context of the journal thread154 * after the transaction for which the handle was created has completed.155 *156 * No locks are held when the callback function is called, so it is safe to157 * call blocking functions from within the callback, but the callback should158 * not block or run for too long, or the filesystem will be blocked waiting for159 * the next transaction to commit. No journaling functions can be used, or160 * there is a risk of deadlock.161 *162 * There is no guaranteed calling order of multiple registered callbacks on163 * the same transaction.164 */165static inline void _ext4_journal_callback_add(handle_t *handle,166			struct ext4_journal_cb_entry *jce)167{168	/* Add the jce to transaction's private list */169	list_add_tail(&jce->jce_list, &handle->h_transaction->t_private_list);170}171 172static inline void ext4_journal_callback_add(handle_t *handle,173			void (*func)(struct super_block *sb,174				     struct ext4_journal_cb_entry *jce,175				     int rc),176			struct ext4_journal_cb_entry *jce)177{178	struct ext4_sb_info *sbi =179			EXT4_SB(handle->h_transaction->t_journal->j_private);180 181	/* Add the jce to transaction's private list */182	jce->jce_func = func;183	spin_lock(&sbi->s_md_lock);184	_ext4_journal_callback_add(handle, jce);185	spin_unlock(&sbi->s_md_lock);186}187 188 189/**190 * ext4_journal_callback_del: delete a registered callback191 * @handle: active journal transaction handle on which callback was registered192 * @jce: registered journal callback entry to unregister193 * Return true if object was successfully removed194 */195static inline bool ext4_journal_callback_try_del(handle_t *handle,196					     struct ext4_journal_cb_entry *jce)197{198	bool deleted;199	struct ext4_sb_info *sbi =200			EXT4_SB(handle->h_transaction->t_journal->j_private);201 202	spin_lock(&sbi->s_md_lock);203	deleted = !list_empty(&jce->jce_list);204	list_del_init(&jce->jce_list);205	spin_unlock(&sbi->s_md_lock);206	return deleted;207}208 209int210ext4_mark_iloc_dirty(handle_t *handle,211		     struct inode *inode,212		     struct ext4_iloc *iloc);213 214/*215 * On success, We end up with an outstanding reference count against216 * iloc->bh.  This _must_ be cleaned up later.217 */218 219int ext4_reserve_inode_write(handle_t *handle, struct inode *inode,220			struct ext4_iloc *iloc);221 222#define ext4_mark_inode_dirty(__h, __i)					\223		__ext4_mark_inode_dirty((__h), (__i), __func__, __LINE__)224int __ext4_mark_inode_dirty(handle_t *handle, struct inode *inode,225				const char *func, unsigned int line);226 227int ext4_expand_extra_isize(struct inode *inode,228			    unsigned int new_extra_isize,229			    struct ext4_iloc *iloc);230/*231 * Wrapper functions with which ext4 calls into JBD.232 */233int __ext4_journal_get_write_access(const char *where, unsigned int line,234				    handle_t *handle, struct super_block *sb,235				    struct buffer_head *bh,236				    enum ext4_journal_trigger_type trigger_type);237 238int __ext4_forget(const char *where, unsigned int line, handle_t *handle,239		  int is_metadata, struct inode *inode,240		  struct buffer_head *bh, ext4_fsblk_t blocknr);241 242int __ext4_journal_get_create_access(const char *where, unsigned int line,243				handle_t *handle, struct super_block *sb,244				struct buffer_head *bh,245				enum ext4_journal_trigger_type trigger_type);246 247int __ext4_handle_dirty_metadata(const char *where, unsigned int line,248				 handle_t *handle, struct inode *inode,249				 struct buffer_head *bh);250 251#define ext4_journal_get_write_access(handle, sb, bh, trigger_type) \252	__ext4_journal_get_write_access(__func__, __LINE__, (handle), (sb), \253					(bh), (trigger_type))254#define ext4_forget(handle, is_metadata, inode, bh, block_nr) \255	__ext4_forget(__func__, __LINE__, (handle), (is_metadata), (inode), \256		      (bh), (block_nr))257#define ext4_journal_get_create_access(handle, sb, bh, trigger_type) \258	__ext4_journal_get_create_access(__func__, __LINE__, (handle), (sb), \259					 (bh), (trigger_type))260#define ext4_handle_dirty_metadata(handle, inode, bh) \261	__ext4_handle_dirty_metadata(__func__, __LINE__, (handle), (inode), \262				     (bh))263 264handle_t *__ext4_journal_start_sb(struct inode *inode, struct super_block *sb,265				  unsigned int line, int type, int blocks,266				  int rsv_blocks, int revoke_creds);267int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle);268 269#define EXT4_NOJOURNAL_MAX_REF_COUNT ((unsigned long) 4096)270 271/* Note:  Do not use this for NULL handles.  This is only to determine if272 * a properly allocated handle is using a journal or not. */273static inline int ext4_handle_valid(handle_t *handle)274{275	if ((unsigned long)handle < EXT4_NOJOURNAL_MAX_REF_COUNT)276		return 0;277	return 1;278}279 280static inline void ext4_handle_sync(handle_t *handle)281{282	if (ext4_handle_valid(handle))283		handle->h_sync = 1;284}285 286static inline int ext4_handle_is_aborted(handle_t *handle)287{288	if (ext4_handle_valid(handle))289		return is_handle_aborted(handle);290	return 0;291}292 293static inline int ext4_free_metadata_revoke_credits(struct super_block *sb,294						    int blocks)295{296	/* Freeing each metadata block can result in freeing one cluster */297	return blocks * EXT4_SB(sb)->s_cluster_ratio;298}299 300static inline int ext4_trans_default_revoke_credits(struct super_block *sb)301{302	return ext4_free_metadata_revoke_credits(sb, 8);303}304 305#define ext4_journal_start_sb(sb, type, nblocks)			\306	__ext4_journal_start_sb(NULL, (sb), __LINE__, (type), (nblocks), 0,\307				ext4_trans_default_revoke_credits(sb))308 309#define ext4_journal_start(inode, type, nblocks)			\310	__ext4_journal_start((inode), __LINE__, (type), (nblocks), 0,	\311			     ext4_trans_default_revoke_credits((inode)->i_sb))312 313#define ext4_journal_start_with_reserve(inode, type, blocks, rsv_blocks)\314	__ext4_journal_start((inode), __LINE__, (type), (blocks), (rsv_blocks),\315			     ext4_trans_default_revoke_credits((inode)->i_sb))316 317#define ext4_journal_start_with_revoke(inode, type, blocks, revoke_creds) \318	__ext4_journal_start((inode), __LINE__, (type), (blocks), 0,	\319			     (revoke_creds))320 321static inline handle_t *__ext4_journal_start(struct inode *inode,322					     unsigned int line, int type,323					     int blocks, int rsv_blocks,324					     int revoke_creds)325{326	return __ext4_journal_start_sb(inode, inode->i_sb, line, type, blocks,327				       rsv_blocks, revoke_creds);328}329 330#define ext4_journal_stop(handle) \331	__ext4_journal_stop(__func__, __LINE__, (handle))332 333#define ext4_journal_start_reserved(handle, type) \334	__ext4_journal_start_reserved((handle), __LINE__, (type))335 336handle_t *__ext4_journal_start_reserved(handle_t *handle, unsigned int line,337					int type);338 339static inline handle_t *ext4_journal_current_handle(void)340{341	return journal_current_handle();342}343 344static inline int ext4_journal_extend(handle_t *handle, int nblocks, int revoke)345{346	if (ext4_handle_valid(handle))347		return jbd2_journal_extend(handle, nblocks, revoke);348	return 0;349}350 351static inline int ext4_journal_restart(handle_t *handle, int nblocks,352				       int revoke)353{354	if (ext4_handle_valid(handle))355		return jbd2__journal_restart(handle, nblocks, revoke, GFP_NOFS);356	return 0;357}358 359int __ext4_journal_ensure_credits(handle_t *handle, int check_cred,360				  int extend_cred, int revoke_cred);361 362 363/*364 * Ensure @handle has at least @check_creds credits available. If not,365 * transaction will be extended or restarted to contain at least @extend_cred366 * credits. Before restarting transaction @fn is executed to allow for cleanup367 * before the transaction is restarted.368 *369 * The return value is < 0 in case of error, 0 in case the handle has enough370 * credits or transaction extension succeeded, 1 in case transaction had to be371 * restarted.372 */373#define ext4_journal_ensure_credits_fn(handle, check_cred, extend_cred,	\374				       revoke_cred, fn) \375({									\376	__label__ __ensure_end;						\377	int err = __ext4_journal_ensure_credits((handle), (check_cred),	\378					(extend_cred), (revoke_cred));	\379									\380	if (err <= 0)							\381		goto __ensure_end;					\382	err = (fn);							\383	if (err < 0)							\384		goto __ensure_end;					\385	err = ext4_journal_restart((handle), (extend_cred), (revoke_cred)); \386	if (err == 0)							\387		err = 1;						\388__ensure_end:								\389	err;								\390})391 392/*393 * Ensure given handle has at least requested amount of credits available,394 * possibly restarting transaction if needed. We also make sure the transaction395 * has space for at least ext4_trans_default_revoke_credits(sb) revoke records396 * as freeing one or two blocks is very common pattern and requesting this is397 * very cheap.398 */399static inline int ext4_journal_ensure_credits(handle_t *handle, int credits,400					      int revoke_creds)401{402	return ext4_journal_ensure_credits_fn(handle, credits, credits,403				revoke_creds, 0);404}405 406static inline int ext4_journal_blocks_per_page(struct inode *inode)407{408	if (EXT4_JOURNAL(inode) != NULL)409		return jbd2_journal_blocks_per_page(inode);410	return 0;411}412 413static inline int ext4_journal_force_commit(journal_t *journal)414{415	if (journal)416		return jbd2_journal_force_commit(journal);417	return 0;418}419 420static inline int ext4_jbd2_inode_add_write(handle_t *handle,421		struct inode *inode, loff_t start_byte, loff_t length)422{423	if (ext4_handle_valid(handle))424		return jbd2_journal_inode_ranged_write(handle,425				EXT4_I(inode)->jinode, start_byte, length);426	return 0;427}428 429static inline int ext4_jbd2_inode_add_wait(handle_t *handle,430		struct inode *inode, loff_t start_byte, loff_t length)431{432	if (ext4_handle_valid(handle))433		return jbd2_journal_inode_ranged_wait(handle,434				EXT4_I(inode)->jinode, start_byte, length);435	return 0;436}437 438static inline void ext4_update_inode_fsync_trans(handle_t *handle,439						 struct inode *inode,440						 int datasync)441{442	struct ext4_inode_info *ei = EXT4_I(inode);443 444	if (ext4_handle_valid(handle) && !is_handle_aborted(handle)) {445		ei->i_sync_tid = handle->h_transaction->t_tid;446		if (datasync)447			ei->i_datasync_tid = handle->h_transaction->t_tid;448	}449}450 451/* super.c */452int ext4_force_commit(struct super_block *sb);453 454/*455 * Ext4 inode journal modes456 */457#define EXT4_INODE_JOURNAL_DATA_MODE	0x01 /* journal data mode */458#define EXT4_INODE_ORDERED_DATA_MODE	0x02 /* ordered data mode */459#define EXT4_INODE_WRITEBACK_DATA_MODE	0x04 /* writeback data mode */460 461int ext4_inode_journal_mode(struct inode *inode);462 463static inline int ext4_should_journal_data(struct inode *inode)464{465	return ext4_inode_journal_mode(inode) & EXT4_INODE_JOURNAL_DATA_MODE;466}467 468static inline int ext4_should_order_data(struct inode *inode)469{470	return ext4_inode_journal_mode(inode) & EXT4_INODE_ORDERED_DATA_MODE;471}472 473static inline int ext4_should_writeback_data(struct inode *inode)474{475	return ext4_inode_journal_mode(inode) & EXT4_INODE_WRITEBACK_DATA_MODE;476}477 478static inline int ext4_free_data_revoke_credits(struct inode *inode, int blocks)479{480	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)481		return 0;482	if (!ext4_should_journal_data(inode))483		return 0;484	/*485	 * Data blocks in one extent are contiguous, just account for partial486	 * clusters at extent boundaries487	 */488	return blocks + 2*(EXT4_SB(inode->i_sb)->s_cluster_ratio - 1);489}490 491/*492 * This function controls whether or not we should try to go down the493 * dioread_nolock code paths, which makes it safe to avoid taking494 * i_rwsem for direct I/O reads.  This only works for extent-based495 * files, and it doesn't work if data journaling is enabled, since the496 * dioread_nolock code uses b_private to pass information back to the497 * I/O completion handler, and this conflicts with the jbd's use of498 * b_private.499 */500static inline int ext4_should_dioread_nolock(struct inode *inode)501{502	if (!test_opt(inode->i_sb, DIOREAD_NOLOCK))503		return 0;504	if (!S_ISREG(inode->i_mode))505		return 0;506	if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))507		return 0;508	if (ext4_should_journal_data(inode))509		return 0;510	/* temporary fix to prevent generic/422 test failures */511	if (!test_opt(inode->i_sb, DELALLOC))512		return 0;513	return 1;514}515 516#endif	/* _EXT4_JBD2_H */517