162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * journal.h 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Defines journalling api and structures. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2003, 2005 Oracle. All rights reserved. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef OCFS2_JOURNAL_H 1162306a36Sopenharmony_ci#define OCFS2_JOURNAL_H 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/fs.h> 1462306a36Sopenharmony_ci#include <linux/jbd2.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cienum ocfs2_journal_state { 1762306a36Sopenharmony_ci OCFS2_JOURNAL_FREE = 0, 1862306a36Sopenharmony_ci OCFS2_JOURNAL_LOADED, 1962306a36Sopenharmony_ci OCFS2_JOURNAL_IN_SHUTDOWN, 2062306a36Sopenharmony_ci}; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistruct ocfs2_super; 2362306a36Sopenharmony_cistruct ocfs2_dinode; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* 2662306a36Sopenharmony_ci * The recovery_list is a simple linked list of node numbers to recover. 2762306a36Sopenharmony_ci * It is protected by the recovery_lock. 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistruct ocfs2_recovery_map { 3162306a36Sopenharmony_ci unsigned int rm_used; 3262306a36Sopenharmony_ci unsigned int rm_entries[]; 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistruct ocfs2_journal { 3762306a36Sopenharmony_ci enum ocfs2_journal_state j_state; /* Journals current state */ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci journal_t *j_journal; /* The kernels journal type */ 4062306a36Sopenharmony_ci struct inode *j_inode; /* Kernel inode pointing to 4162306a36Sopenharmony_ci * this journal */ 4262306a36Sopenharmony_ci struct ocfs2_super *j_osb; /* pointer to the super 4362306a36Sopenharmony_ci * block for the node 4462306a36Sopenharmony_ci * we're currently 4562306a36Sopenharmony_ci * running on -- not 4662306a36Sopenharmony_ci * necessarily the super 4762306a36Sopenharmony_ci * block from the node 4862306a36Sopenharmony_ci * which we usually run 4962306a36Sopenharmony_ci * from (recovery, 5062306a36Sopenharmony_ci * etc) */ 5162306a36Sopenharmony_ci struct buffer_head *j_bh; /* Journal disk inode block */ 5262306a36Sopenharmony_ci atomic_t j_num_trans; /* Number of transactions 5362306a36Sopenharmony_ci * currently in the system. */ 5462306a36Sopenharmony_ci spinlock_t j_lock; 5562306a36Sopenharmony_ci unsigned long j_trans_id; 5662306a36Sopenharmony_ci struct rw_semaphore j_trans_barrier; 5762306a36Sopenharmony_ci wait_queue_head_t j_checkpointed; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci /* both fields protected by j_lock*/ 6062306a36Sopenharmony_ci struct list_head j_la_cleanups; 6162306a36Sopenharmony_ci struct work_struct j_recovery_work; 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ciextern spinlock_t trans_inc_lock; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* wrap j_trans_id so we never have it equal to zero. */ 6762306a36Sopenharmony_cistatic inline unsigned long ocfs2_inc_trans_id(struct ocfs2_journal *j) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci unsigned long old_id; 7062306a36Sopenharmony_ci spin_lock(&trans_inc_lock); 7162306a36Sopenharmony_ci old_id = j->j_trans_id++; 7262306a36Sopenharmony_ci if (unlikely(!j->j_trans_id)) 7362306a36Sopenharmony_ci j->j_trans_id = 1; 7462306a36Sopenharmony_ci spin_unlock(&trans_inc_lock); 7562306a36Sopenharmony_ci return old_id; 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cistatic inline void ocfs2_set_ci_lock_trans(struct ocfs2_journal *journal, 7962306a36Sopenharmony_ci struct ocfs2_caching_info *ci) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci spin_lock(&trans_inc_lock); 8262306a36Sopenharmony_ci ci->ci_last_trans = journal->j_trans_id; 8362306a36Sopenharmony_ci spin_unlock(&trans_inc_lock); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* Used to figure out whether it's safe to drop a metadata lock on an 8762306a36Sopenharmony_ci * cached object. Returns true if all the object's changes have been 8862306a36Sopenharmony_ci * checkpointed to disk. You should be holding the spinlock on the 8962306a36Sopenharmony_ci * metadata lock while calling this to be sure that nobody can take 9062306a36Sopenharmony_ci * the lock and put it on another transaction. */ 9162306a36Sopenharmony_cistatic inline int ocfs2_ci_fully_checkpointed(struct ocfs2_caching_info *ci) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci int ret; 9462306a36Sopenharmony_ci struct ocfs2_journal *journal = 9562306a36Sopenharmony_ci OCFS2_SB(ocfs2_metadata_cache_get_super(ci))->journal; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci spin_lock(&trans_inc_lock); 9862306a36Sopenharmony_ci ret = time_after(journal->j_trans_id, ci->ci_last_trans); 9962306a36Sopenharmony_ci spin_unlock(&trans_inc_lock); 10062306a36Sopenharmony_ci return ret; 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci/* convenience function to check if an object backed by struct 10462306a36Sopenharmony_ci * ocfs2_caching_info is still new (has never hit disk) Will do you a 10562306a36Sopenharmony_ci * favor and set created_trans = 0 when you've 10662306a36Sopenharmony_ci * been checkpointed. returns '1' if the ci is still new. */ 10762306a36Sopenharmony_cistatic inline int ocfs2_ci_is_new(struct ocfs2_caching_info *ci) 10862306a36Sopenharmony_ci{ 10962306a36Sopenharmony_ci int ret; 11062306a36Sopenharmony_ci struct ocfs2_journal *journal = 11162306a36Sopenharmony_ci OCFS2_SB(ocfs2_metadata_cache_get_super(ci))->journal; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci spin_lock(&trans_inc_lock); 11462306a36Sopenharmony_ci ret = !(time_after(journal->j_trans_id, ci->ci_created_trans)); 11562306a36Sopenharmony_ci if (!ret) 11662306a36Sopenharmony_ci ci->ci_created_trans = 0; 11762306a36Sopenharmony_ci spin_unlock(&trans_inc_lock); 11862306a36Sopenharmony_ci return ret; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/* Wrapper for inodes so we can check system files */ 12262306a36Sopenharmony_cistatic inline int ocfs2_inode_is_new(struct inode *inode) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci /* System files are never "new" as they're written out by 12562306a36Sopenharmony_ci * mkfs. This helps us early during mount, before we have the 12662306a36Sopenharmony_ci * journal open and j_trans_id could be junk. */ 12762306a36Sopenharmony_ci if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) 12862306a36Sopenharmony_ci return 0; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci return ocfs2_ci_is_new(INODE_CACHE(inode)); 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic inline void ocfs2_ci_set_new(struct ocfs2_super *osb, 13462306a36Sopenharmony_ci struct ocfs2_caching_info *ci) 13562306a36Sopenharmony_ci{ 13662306a36Sopenharmony_ci spin_lock(&trans_inc_lock); 13762306a36Sopenharmony_ci ci->ci_created_trans = osb->journal->j_trans_id; 13862306a36Sopenharmony_ci spin_unlock(&trans_inc_lock); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/* Exported only for the journal struct init code in super.c. Do not call. */ 14262306a36Sopenharmony_civoid ocfs2_orphan_scan_init(struct ocfs2_super *osb); 14362306a36Sopenharmony_civoid ocfs2_orphan_scan_start(struct ocfs2_super *osb); 14462306a36Sopenharmony_civoid ocfs2_orphan_scan_stop(struct ocfs2_super *osb); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_civoid ocfs2_complete_recovery(struct work_struct *work); 14762306a36Sopenharmony_civoid ocfs2_wait_for_recovery(struct ocfs2_super *osb); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ciint ocfs2_recovery_init(struct ocfs2_super *osb); 15062306a36Sopenharmony_civoid ocfs2_recovery_exit(struct ocfs2_super *osb); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ciint ocfs2_compute_replay_slots(struct ocfs2_super *osb); 15362306a36Sopenharmony_civoid ocfs2_free_replay_slots(struct ocfs2_super *osb); 15462306a36Sopenharmony_ci/* 15562306a36Sopenharmony_ci * Journal Control: 15662306a36Sopenharmony_ci * Initialize, Load, Shutdown, Wipe a journal. 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * ocfs2_journal_alloc - Initialize skeleton for journal structure. 15962306a36Sopenharmony_ci * ocfs2_journal_init - Initialize journal structures in the OSB. 16062306a36Sopenharmony_ci * ocfs2_journal_load - Load the given journal off disk. Replay it if 16162306a36Sopenharmony_ci * there's transactions still in there. 16262306a36Sopenharmony_ci * ocfs2_journal_shutdown - Shutdown a journal, this will flush all 16362306a36Sopenharmony_ci * uncommitted, uncheckpointed transactions. 16462306a36Sopenharmony_ci * ocfs2_journal_wipe - Wipe transactions from a journal. Optionally 16562306a36Sopenharmony_ci * zero out each block. 16662306a36Sopenharmony_ci * ocfs2_recovery_thread - Perform recovery on a node. osb is our own osb. 16762306a36Sopenharmony_ci * ocfs2_mark_dead_nodes - Start recovery on nodes we won't get a heartbeat 16862306a36Sopenharmony_ci * event on. 16962306a36Sopenharmony_ci * ocfs2_start_checkpoint - Kick the commit thread to do a checkpoint. 17062306a36Sopenharmony_ci */ 17162306a36Sopenharmony_civoid ocfs2_set_journal_params(struct ocfs2_super *osb); 17262306a36Sopenharmony_ciint ocfs2_journal_alloc(struct ocfs2_super *osb); 17362306a36Sopenharmony_ciint ocfs2_journal_init(struct ocfs2_super *osb, int *dirty); 17462306a36Sopenharmony_civoid ocfs2_journal_shutdown(struct ocfs2_super *osb); 17562306a36Sopenharmony_ciint ocfs2_journal_wipe(struct ocfs2_journal *journal, 17662306a36Sopenharmony_ci int full); 17762306a36Sopenharmony_ciint ocfs2_journal_load(struct ocfs2_journal *journal, int local, 17862306a36Sopenharmony_ci int replayed); 17962306a36Sopenharmony_ciint ocfs2_check_journals_nolocks(struct ocfs2_super *osb); 18062306a36Sopenharmony_civoid ocfs2_recovery_thread(struct ocfs2_super *osb, 18162306a36Sopenharmony_ci int node_num); 18262306a36Sopenharmony_ciint ocfs2_mark_dead_nodes(struct ocfs2_super *osb); 18362306a36Sopenharmony_civoid ocfs2_complete_mount_recovery(struct ocfs2_super *osb); 18462306a36Sopenharmony_civoid ocfs2_complete_quota_recovery(struct ocfs2_super *osb); 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistatic inline void ocfs2_start_checkpoint(struct ocfs2_super *osb) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci wake_up(&osb->checkpoint_event); 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cistatic inline void ocfs2_checkpoint_inode(struct inode *inode) 19262306a36Sopenharmony_ci{ 19362306a36Sopenharmony_ci struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci if (ocfs2_mount_local(osb)) 19662306a36Sopenharmony_ci return; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci if (!ocfs2_ci_fully_checkpointed(INODE_CACHE(inode))) { 19962306a36Sopenharmony_ci /* WARNING: This only kicks off a single 20062306a36Sopenharmony_ci * checkpoint. If someone races you and adds more 20162306a36Sopenharmony_ci * metadata to the journal, you won't know, and will 20262306a36Sopenharmony_ci * wind up waiting *a lot* longer than necessary. Right 20362306a36Sopenharmony_ci * now we only use this in clear_inode so that's 20462306a36Sopenharmony_ci * OK. */ 20562306a36Sopenharmony_ci ocfs2_start_checkpoint(osb); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci wait_event(osb->journal->j_checkpointed, 20862306a36Sopenharmony_ci ocfs2_ci_fully_checkpointed(INODE_CACHE(inode))); 20962306a36Sopenharmony_ci } 21062306a36Sopenharmony_ci} 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/* 21362306a36Sopenharmony_ci * Transaction Handling: 21462306a36Sopenharmony_ci * Manage the lifetime of a transaction handle. 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * ocfs2_start_trans - Begin a transaction. Give it an upper estimate of 21762306a36Sopenharmony_ci * the number of blocks that will be changed during 21862306a36Sopenharmony_ci * this handle. 21962306a36Sopenharmony_ci * ocfs2_commit_trans - Complete a handle. It might return -EIO if 22062306a36Sopenharmony_ci * the journal was aborted. The majority of paths don't 22162306a36Sopenharmony_ci * check the return value as an error there comes too 22262306a36Sopenharmony_ci * late to do anything (and will be picked up in a 22362306a36Sopenharmony_ci * later transaction). 22462306a36Sopenharmony_ci * ocfs2_extend_trans - Extend a handle by nblocks credits. This may 22562306a36Sopenharmony_ci * commit the handle to disk in the process, but will 22662306a36Sopenharmony_ci * not release any locks taken during the transaction. 22762306a36Sopenharmony_ci * ocfs2_journal_access* - Notify the handle that we want to journal this 22862306a36Sopenharmony_ci * buffer. Will have to call ocfs2_journal_dirty once 22962306a36Sopenharmony_ci * we've actually dirtied it. Type is one of . or . 23062306a36Sopenharmony_ci * Always call the specific flavor of 23162306a36Sopenharmony_ci * ocfs2_journal_access_*() unless you intend to 23262306a36Sopenharmony_ci * manage the checksum by hand. 23362306a36Sopenharmony_ci * ocfs2_journal_dirty - Mark a journalled buffer as having dirty data. 23462306a36Sopenharmony_ci * ocfs2_jbd2_inode_add_write - Mark an inode with range so that its data goes 23562306a36Sopenharmony_ci * out before the current handle commits. 23662306a36Sopenharmony_ci */ 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci/* You must always start_trans with a number of buffs > 0, but it's 23962306a36Sopenharmony_ci * perfectly legal to go through an entire transaction without having 24062306a36Sopenharmony_ci * dirtied any buffers. */ 24162306a36Sopenharmony_cihandle_t *ocfs2_start_trans(struct ocfs2_super *osb, 24262306a36Sopenharmony_ci int max_buffs); 24362306a36Sopenharmony_ciint ocfs2_commit_trans(struct ocfs2_super *osb, 24462306a36Sopenharmony_ci handle_t *handle); 24562306a36Sopenharmony_ciint ocfs2_extend_trans(handle_t *handle, int nblocks); 24662306a36Sopenharmony_ciint ocfs2_allocate_extend_trans(handle_t *handle, 24762306a36Sopenharmony_ci int thresh); 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci/* 25062306a36Sopenharmony_ci * Define an arbitrary limit for the amount of data we will anticipate 25162306a36Sopenharmony_ci * writing to any given transaction. For unbounded transactions such as 25262306a36Sopenharmony_ci * fallocate(2) we can write more than this, but we always 25362306a36Sopenharmony_ci * start off at the maximum transaction size and grow the transaction 25462306a36Sopenharmony_ci * optimistically as we go. 25562306a36Sopenharmony_ci */ 25662306a36Sopenharmony_ci#define OCFS2_MAX_TRANS_DATA 64U 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci/* 25962306a36Sopenharmony_ci * Create access is for when we get a newly created buffer and we're 26062306a36Sopenharmony_ci * not gonna read it off disk, but rather fill it ourselves. Right 26162306a36Sopenharmony_ci * now, we don't do anything special with this (it turns into a write 26262306a36Sopenharmony_ci * request), but this is a good placeholder in case we do... 26362306a36Sopenharmony_ci * 26462306a36Sopenharmony_ci * Write access is for when we read a block off disk and are going to 26562306a36Sopenharmony_ci * modify it. This way the journalling layer knows it may need to make 26662306a36Sopenharmony_ci * a copy of that block (if it's part of another, uncommitted 26762306a36Sopenharmony_ci * transaction) before we do so. 26862306a36Sopenharmony_ci */ 26962306a36Sopenharmony_ci#define OCFS2_JOURNAL_ACCESS_CREATE 0 27062306a36Sopenharmony_ci#define OCFS2_JOURNAL_ACCESS_WRITE 1 27162306a36Sopenharmony_ci#define OCFS2_JOURNAL_ACCESS_UNDO 2 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci/* ocfs2_inode */ 27562306a36Sopenharmony_ciint ocfs2_journal_access_di(handle_t *handle, struct ocfs2_caching_info *ci, 27662306a36Sopenharmony_ci struct buffer_head *bh, int type); 27762306a36Sopenharmony_ci/* ocfs2_extent_block */ 27862306a36Sopenharmony_ciint ocfs2_journal_access_eb(handle_t *handle, struct ocfs2_caching_info *ci, 27962306a36Sopenharmony_ci struct buffer_head *bh, int type); 28062306a36Sopenharmony_ci/* ocfs2_refcount_block */ 28162306a36Sopenharmony_ciint ocfs2_journal_access_rb(handle_t *handle, struct ocfs2_caching_info *ci, 28262306a36Sopenharmony_ci struct buffer_head *bh, int type); 28362306a36Sopenharmony_ci/* ocfs2_group_desc */ 28462306a36Sopenharmony_ciint ocfs2_journal_access_gd(handle_t *handle, struct ocfs2_caching_info *ci, 28562306a36Sopenharmony_ci struct buffer_head *bh, int type); 28662306a36Sopenharmony_ci/* ocfs2_xattr_block */ 28762306a36Sopenharmony_ciint ocfs2_journal_access_xb(handle_t *handle, struct ocfs2_caching_info *ci, 28862306a36Sopenharmony_ci struct buffer_head *bh, int type); 28962306a36Sopenharmony_ci/* quota blocks */ 29062306a36Sopenharmony_ciint ocfs2_journal_access_dq(handle_t *handle, struct ocfs2_caching_info *ci, 29162306a36Sopenharmony_ci struct buffer_head *bh, int type); 29262306a36Sopenharmony_ci/* dirblock */ 29362306a36Sopenharmony_ciint ocfs2_journal_access_db(handle_t *handle, struct ocfs2_caching_info *ci, 29462306a36Sopenharmony_ci struct buffer_head *bh, int type); 29562306a36Sopenharmony_ci/* ocfs2_dx_root_block */ 29662306a36Sopenharmony_ciint ocfs2_journal_access_dr(handle_t *handle, struct ocfs2_caching_info *ci, 29762306a36Sopenharmony_ci struct buffer_head *bh, int type); 29862306a36Sopenharmony_ci/* ocfs2_dx_leaf */ 29962306a36Sopenharmony_ciint ocfs2_journal_access_dl(handle_t *handle, struct ocfs2_caching_info *ci, 30062306a36Sopenharmony_ci struct buffer_head *bh, int type); 30162306a36Sopenharmony_ci/* Anything that has no ecc */ 30262306a36Sopenharmony_ciint ocfs2_journal_access(handle_t *handle, struct ocfs2_caching_info *ci, 30362306a36Sopenharmony_ci struct buffer_head *bh, int type); 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci/* 30662306a36Sopenharmony_ci * A word about the journal_access/journal_dirty "dance". It is 30762306a36Sopenharmony_ci * entirely legal to journal_access a buffer more than once (as long 30862306a36Sopenharmony_ci * as the access type is the same -- I'm not sure what will happen if 30962306a36Sopenharmony_ci * access type is different but this should never happen anyway) It is 31062306a36Sopenharmony_ci * also legal to journal_dirty a buffer more than once. In fact, you 31162306a36Sopenharmony_ci * can even journal_access a buffer after you've done a 31262306a36Sopenharmony_ci * journal_access/journal_dirty pair. The only thing you cannot do 31362306a36Sopenharmony_ci * however, is journal_dirty a buffer which you haven't yet passed to 31462306a36Sopenharmony_ci * journal_access at least once. 31562306a36Sopenharmony_ci * 31662306a36Sopenharmony_ci * That said, 99% of the time this doesn't matter and this is what the 31762306a36Sopenharmony_ci * path looks like: 31862306a36Sopenharmony_ci * 31962306a36Sopenharmony_ci * <read a bh> 32062306a36Sopenharmony_ci * ocfs2_journal_access(handle, bh, OCFS2_JOURNAL_ACCESS_WRITE); 32162306a36Sopenharmony_ci * <modify the bh> 32262306a36Sopenharmony_ci * ocfs2_journal_dirty(handle, bh); 32362306a36Sopenharmony_ci */ 32462306a36Sopenharmony_civoid ocfs2_journal_dirty(handle_t *handle, struct buffer_head *bh); 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci/* 32762306a36Sopenharmony_ci * Credit Macros: 32862306a36Sopenharmony_ci * Convenience macros to calculate number of credits needed. 32962306a36Sopenharmony_ci * 33062306a36Sopenharmony_ci * For convenience sake, I have a set of macros here which calculate 33162306a36Sopenharmony_ci * the *maximum* number of sectors which will be changed for various 33262306a36Sopenharmony_ci * metadata updates. 33362306a36Sopenharmony_ci */ 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci/* simple file updates like chmod, etc. */ 33662306a36Sopenharmony_ci#define OCFS2_INODE_UPDATE_CREDITS 1 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci/* extended attribute block update */ 33962306a36Sopenharmony_ci#define OCFS2_XATTR_BLOCK_UPDATE_CREDITS 1 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci/* Update of a single quota block */ 34262306a36Sopenharmony_ci#define OCFS2_QUOTA_BLOCK_UPDATE_CREDITS 1 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci/* global quotafile inode update, data block */ 34562306a36Sopenharmony_ci#define OCFS2_QINFO_WRITE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \ 34662306a36Sopenharmony_ci OCFS2_QUOTA_BLOCK_UPDATE_CREDITS) 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci#define OCFS2_LOCAL_QINFO_WRITE_CREDITS OCFS2_QUOTA_BLOCK_UPDATE_CREDITS 34962306a36Sopenharmony_ci/* 35062306a36Sopenharmony_ci * The two writes below can accidentally see global info dirty due 35162306a36Sopenharmony_ci * to set_info() quotactl so make them prepared for the writes. 35262306a36Sopenharmony_ci */ 35362306a36Sopenharmony_ci/* quota data block, global info */ 35462306a36Sopenharmony_ci/* Write to local quota file */ 35562306a36Sopenharmony_ci#define OCFS2_QWRITE_CREDITS (OCFS2_QINFO_WRITE_CREDITS + \ 35662306a36Sopenharmony_ci OCFS2_QUOTA_BLOCK_UPDATE_CREDITS) 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci/* global quota data block, local quota data block, global quota inode, 35962306a36Sopenharmony_ci * global quota info */ 36062306a36Sopenharmony_ci#define OCFS2_QSYNC_CREDITS (OCFS2_QINFO_WRITE_CREDITS + \ 36162306a36Sopenharmony_ci 2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS) 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_cistatic inline int ocfs2_quota_trans_credits(struct super_block *sb) 36462306a36Sopenharmony_ci{ 36562306a36Sopenharmony_ci int credits = 0; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) 36862306a36Sopenharmony_ci credits += OCFS2_QWRITE_CREDITS; 36962306a36Sopenharmony_ci if (OCFS2_HAS_RO_COMPAT_FEATURE(sb, OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) 37062306a36Sopenharmony_ci credits += OCFS2_QWRITE_CREDITS; 37162306a36Sopenharmony_ci return credits; 37262306a36Sopenharmony_ci} 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci/* group extend. inode update and last group update. */ 37562306a36Sopenharmony_ci#define OCFS2_GROUP_EXTEND_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1) 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci/* group add. inode update and the new group update. */ 37862306a36Sopenharmony_ci#define OCFS2_GROUP_ADD_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1) 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci/* get one bit out of a suballocator: dinode + group descriptor + 38162306a36Sopenharmony_ci * prev. group desc. if we relink. */ 38262306a36Sopenharmony_ci#define OCFS2_SUBALLOC_ALLOC (3) 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_cistatic inline int ocfs2_inline_to_extents_credits(struct super_block *sb) 38562306a36Sopenharmony_ci{ 38662306a36Sopenharmony_ci return OCFS2_SUBALLOC_ALLOC + OCFS2_INODE_UPDATE_CREDITS + 38762306a36Sopenharmony_ci ocfs2_quota_trans_credits(sb); 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci/* dinode + group descriptor update. We don't relink on free yet. */ 39162306a36Sopenharmony_ci#define OCFS2_SUBALLOC_FREE (2) 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci#define OCFS2_TRUNCATE_LOG_UPDATE OCFS2_INODE_UPDATE_CREDITS 39462306a36Sopenharmony_ci#define OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC (OCFS2_SUBALLOC_FREE \ 39562306a36Sopenharmony_ci + OCFS2_TRUNCATE_LOG_UPDATE) 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_cistatic inline int ocfs2_remove_extent_credits(struct super_block *sb) 39862306a36Sopenharmony_ci{ 39962306a36Sopenharmony_ci return OCFS2_TRUNCATE_LOG_UPDATE + OCFS2_INODE_UPDATE_CREDITS + 40062306a36Sopenharmony_ci ocfs2_quota_trans_credits(sb); 40162306a36Sopenharmony_ci} 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci/* data block for new dir/symlink, allocation of directory block, dx_root 40462306a36Sopenharmony_ci * update for free list */ 40562306a36Sopenharmony_ci#define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + OCFS2_SUBALLOC_ALLOC + 1) 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_cistatic inline int ocfs2_add_dir_index_credits(struct super_block *sb) 40862306a36Sopenharmony_ci{ 40962306a36Sopenharmony_ci /* 1 block for index, 2 allocs (data, metadata), 1 clusters 41062306a36Sopenharmony_ci * worth of blocks for initial extent. */ 41162306a36Sopenharmony_ci return 1 + 2 * OCFS2_SUBALLOC_ALLOC + 41262306a36Sopenharmony_ci ocfs2_clusters_to_blocks(sb, 1); 41362306a36Sopenharmony_ci} 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci/* parent fe, parent block, new file entry, index leaf, inode alloc fe, inode 41662306a36Sopenharmony_ci * alloc group descriptor + mkdir/symlink blocks + dir blocks + xattr 41762306a36Sopenharmony_ci * blocks + quota update */ 41862306a36Sopenharmony_cistatic inline int ocfs2_mknod_credits(struct super_block *sb, int is_dir, 41962306a36Sopenharmony_ci int xattr_credits) 42062306a36Sopenharmony_ci{ 42162306a36Sopenharmony_ci int dir_credits = OCFS2_DIR_LINK_ADDITIONAL_CREDITS; 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci if (is_dir) 42462306a36Sopenharmony_ci dir_credits += ocfs2_add_dir_index_credits(sb); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci return 4 + OCFS2_SUBALLOC_ALLOC + dir_credits + xattr_credits + 42762306a36Sopenharmony_ci ocfs2_quota_trans_credits(sb); 42862306a36Sopenharmony_ci} 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci/* local alloc metadata change + main bitmap updates */ 43162306a36Sopenharmony_ci#define OCFS2_WINDOW_MOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS \ 43262306a36Sopenharmony_ci + OCFS2_SUBALLOC_ALLOC + OCFS2_SUBALLOC_FREE) 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci/* used when we don't need an allocation change for a dir extend. One 43562306a36Sopenharmony_ci * for the dinode, one for the new block. */ 43662306a36Sopenharmony_ci#define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2) 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci/* file update (nlink, etc) + directory mtime/ctime + dir entry block + quota 43962306a36Sopenharmony_ci * update on dir + index leaf + dx root update for free list + 44062306a36Sopenharmony_ci * previous dirblock update in the free list */ 44162306a36Sopenharmony_cistatic inline int ocfs2_link_credits(struct super_block *sb) 44262306a36Sopenharmony_ci{ 44362306a36Sopenharmony_ci return 2 * OCFS2_INODE_UPDATE_CREDITS + 4 + 44462306a36Sopenharmony_ci ocfs2_quota_trans_credits(sb); 44562306a36Sopenharmony_ci} 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci/* inode + dir inode (if we unlink a dir), + dir entry block + orphan 44862306a36Sopenharmony_ci * dir inode link + dir inode index leaf + dir index root */ 44962306a36Sopenharmony_cistatic inline int ocfs2_unlink_credits(struct super_block *sb) 45062306a36Sopenharmony_ci{ 45162306a36Sopenharmony_ci /* The quota update from ocfs2_link_credits is unused here... */ 45262306a36Sopenharmony_ci return 2 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_link_credits(sb); 45362306a36Sopenharmony_ci} 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci/* dinode + orphan dir dinode + inode alloc dinode + orphan dir entry + 45662306a36Sopenharmony_ci * inode alloc group descriptor + orphan dir index root + 45762306a36Sopenharmony_ci * orphan dir index leaf */ 45862306a36Sopenharmony_ci#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 4) 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci/* dinode + orphan dir dinode + extent tree leaf block + orphan dir entry + 46162306a36Sopenharmony_ci * orphan dir index root + orphan dir index leaf */ 46262306a36Sopenharmony_ci#define OCFS2_INODE_ADD_TO_ORPHAN_CREDITS (2 * OCFS2_INODE_UPDATE_CREDITS + 4) 46362306a36Sopenharmony_ci#define OCFS2_INODE_DEL_FROM_ORPHAN_CREDITS OCFS2_INODE_ADD_TO_ORPHAN_CREDITS 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci/* dinode update, old dir dinode update, new dir dinode update, old 46662306a36Sopenharmony_ci * dir dir entry, new dir dir entry, dir entry update for renaming 46762306a36Sopenharmony_ci * directory + target unlink + 3 x dir index leaves */ 46862306a36Sopenharmony_cistatic inline int ocfs2_rename_credits(struct super_block *sb) 46962306a36Sopenharmony_ci{ 47062306a36Sopenharmony_ci return 3 * OCFS2_INODE_UPDATE_CREDITS + 6 + ocfs2_unlink_credits(sb); 47162306a36Sopenharmony_ci} 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci/* global bitmap dinode, group desc., relinked group, 47462306a36Sopenharmony_ci * suballocator dinode, group desc., relinked group, 47562306a36Sopenharmony_ci * dinode, xattr block */ 47662306a36Sopenharmony_ci#define OCFS2_XATTR_BLOCK_CREATE_CREDITS (OCFS2_SUBALLOC_ALLOC * 2 + \ 47762306a36Sopenharmony_ci + OCFS2_INODE_UPDATE_CREDITS \ 47862306a36Sopenharmony_ci + OCFS2_XATTR_BLOCK_UPDATE_CREDITS) 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci/* inode update, removal of dx root block from allocator */ 48162306a36Sopenharmony_ci#define OCFS2_DX_ROOT_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \ 48262306a36Sopenharmony_ci OCFS2_SUBALLOC_FREE) 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_cistatic inline int ocfs2_calc_dxi_expand_credits(struct super_block *sb) 48562306a36Sopenharmony_ci{ 48662306a36Sopenharmony_ci int credits = 1 + OCFS2_SUBALLOC_ALLOC; 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci credits += ocfs2_clusters_to_blocks(sb, 1); 48962306a36Sopenharmony_ci credits += ocfs2_quota_trans_credits(sb); 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci return credits; 49262306a36Sopenharmony_ci} 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci/* inode update, new refcount block and its allocation credits. */ 49562306a36Sopenharmony_ci#define OCFS2_REFCOUNT_TREE_CREATE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1 \ 49662306a36Sopenharmony_ci + OCFS2_SUBALLOC_ALLOC) 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci/* inode and the refcount block update. */ 49962306a36Sopenharmony_ci#define OCFS2_REFCOUNT_TREE_SET_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1) 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci/* 50262306a36Sopenharmony_ci * inode and the refcount block update. 50362306a36Sopenharmony_ci * It doesn't include the credits for sub alloc change. 50462306a36Sopenharmony_ci * So if we need to free the bit, OCFS2_SUBALLOC_FREE needs to be added. 50562306a36Sopenharmony_ci */ 50662306a36Sopenharmony_ci#define OCFS2_REFCOUNT_TREE_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1) 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci/* 2 metadata alloc, 2 new blocks and root refcount block */ 50962306a36Sopenharmony_ci#define OCFS2_EXPAND_REFCOUNT_TREE_CREDITS (OCFS2_SUBALLOC_ALLOC * 2 + 3) 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci/* 51262306a36Sopenharmony_ci * Please note that the caller must make sure that root_el is the root 51362306a36Sopenharmony_ci * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise 51462306a36Sopenharmony_ci * the result may be wrong. 51562306a36Sopenharmony_ci */ 51662306a36Sopenharmony_cistatic inline int ocfs2_calc_extend_credits(struct super_block *sb, 51762306a36Sopenharmony_ci struct ocfs2_extent_list *root_el) 51862306a36Sopenharmony_ci{ 51962306a36Sopenharmony_ci int bitmap_blocks, sysfile_bitmap_blocks, extent_blocks; 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci /* bitmap dinode, group desc. + relinked group. */ 52262306a36Sopenharmony_ci bitmap_blocks = OCFS2_SUBALLOC_ALLOC; 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci /* we might need to shift tree depth so lets assume an 52562306a36Sopenharmony_ci * absolute worst case of complete fragmentation. Even with 52662306a36Sopenharmony_ci * that, we only need one update for the dinode, and then 52762306a36Sopenharmony_ci * however many metadata chunks needed * a remaining suballoc 52862306a36Sopenharmony_ci * alloc. */ 52962306a36Sopenharmony_ci sysfile_bitmap_blocks = 1 + 53062306a36Sopenharmony_ci (OCFS2_SUBALLOC_ALLOC - 1) * ocfs2_extend_meta_needed(root_el); 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci /* this does not include *new* metadata blocks, which are 53362306a36Sopenharmony_ci * accounted for in sysfile_bitmap_blocks. root_el + 53462306a36Sopenharmony_ci * prev. last_eb_blk + blocks along edge of tree. 53562306a36Sopenharmony_ci * calc_symlink_credits passes because we just need 1 53662306a36Sopenharmony_ci * credit for the dinode there. */ 53762306a36Sopenharmony_ci extent_blocks = 1 + 1 + le16_to_cpu(root_el->l_tree_depth); 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci return bitmap_blocks + sysfile_bitmap_blocks + extent_blocks + 54062306a36Sopenharmony_ci ocfs2_quota_trans_credits(sb); 54162306a36Sopenharmony_ci} 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_cistatic inline int ocfs2_calc_symlink_credits(struct super_block *sb) 54462306a36Sopenharmony_ci{ 54562306a36Sopenharmony_ci int blocks = ocfs2_mknod_credits(sb, 0, 0); 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_ci /* links can be longer than one block so we may update many 54862306a36Sopenharmony_ci * within our single allocated extent. */ 54962306a36Sopenharmony_ci blocks += ocfs2_clusters_to_blocks(sb, 1); 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci return blocks + ocfs2_quota_trans_credits(sb); 55262306a36Sopenharmony_ci} 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_cistatic inline int ocfs2_calc_group_alloc_credits(struct super_block *sb, 55562306a36Sopenharmony_ci unsigned int cpg) 55662306a36Sopenharmony_ci{ 55762306a36Sopenharmony_ci int blocks; 55862306a36Sopenharmony_ci int bitmap_blocks = OCFS2_SUBALLOC_ALLOC + 1; 55962306a36Sopenharmony_ci /* parent inode update + new block group header + bitmap inode update 56062306a36Sopenharmony_ci + bitmap blocks affected */ 56162306a36Sopenharmony_ci blocks = 1 + 1 + 1 + bitmap_blocks; 56262306a36Sopenharmony_ci return blocks; 56362306a36Sopenharmony_ci} 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci/* 56662306a36Sopenharmony_ci * Allocating a discontiguous block group requires the credits from 56762306a36Sopenharmony_ci * ocfs2_calc_group_alloc_credits() as well as enough credits to fill 56862306a36Sopenharmony_ci * the group descriptor's extent list. The caller already has started 56962306a36Sopenharmony_ci * the transaction with ocfs2_calc_group_alloc_credits(). They extend 57062306a36Sopenharmony_ci * it with these credits. 57162306a36Sopenharmony_ci */ 57262306a36Sopenharmony_cistatic inline int ocfs2_calc_bg_discontig_credits(struct super_block *sb) 57362306a36Sopenharmony_ci{ 57462306a36Sopenharmony_ci return ocfs2_extent_recs_per_gd(sb); 57562306a36Sopenharmony_ci} 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_cistatic inline int ocfs2_jbd2_inode_add_write(handle_t *handle, struct inode *inode, 57862306a36Sopenharmony_ci loff_t start_byte, loff_t length) 57962306a36Sopenharmony_ci{ 58062306a36Sopenharmony_ci return jbd2_journal_inode_ranged_write(handle, 58162306a36Sopenharmony_ci &OCFS2_I(inode)->ip_jinode, 58262306a36Sopenharmony_ci start_byte, length); 58362306a36Sopenharmony_ci} 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cistatic inline int ocfs2_begin_ordered_truncate(struct inode *inode, 58662306a36Sopenharmony_ci loff_t new_size) 58762306a36Sopenharmony_ci{ 58862306a36Sopenharmony_ci return jbd2_journal_begin_ordered_truncate( 58962306a36Sopenharmony_ci OCFS2_SB(inode->i_sb)->journal->j_journal, 59062306a36Sopenharmony_ci &OCFS2_I(inode)->ip_jinode, 59162306a36Sopenharmony_ci new_size); 59262306a36Sopenharmony_ci} 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_cistatic inline void ocfs2_update_inode_fsync_trans(handle_t *handle, 59562306a36Sopenharmony_ci struct inode *inode, 59662306a36Sopenharmony_ci int datasync) 59762306a36Sopenharmony_ci{ 59862306a36Sopenharmony_ci struct ocfs2_inode_info *oi = OCFS2_I(inode); 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci if (!is_handle_aborted(handle)) { 60162306a36Sopenharmony_ci oi->i_sync_tid = handle->h_transaction->t_tid; 60262306a36Sopenharmony_ci if (datasync) 60362306a36Sopenharmony_ci oi->i_datasync_tid = handle->h_transaction->t_tid; 60462306a36Sopenharmony_ci } 60562306a36Sopenharmony_ci} 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci#endif /* OCFS2_JOURNAL_H */ 608