2006-10-11 12:20:57 +04:00
/*
2008-04-30 02:13:32 +04:00
* ext4_jbd2 . h
2006-10-11 12:20:57 +04:00
*
* Written by Stephen C . Tweedie < sct @ redhat . com > , 1999
*
* Copyright 1998 - - 1999 Red Hat corp - - - All Rights Reserved
*
* This file is part of the Linux kernel and is made available under
* the terms of the GNU General Public License , version 2 , or at your
* option , any later version , incorporated herein by reference .
*
* Ext4 - specific journaling extensions .
*/
2008-04-30 02:13:32 +04:00
# ifndef _EXT4_JBD2_H
# define _EXT4_JBD2_H
2006-10-11 12:20:57 +04:00
# include <linux/fs.h>
2006-10-11 12:20:59 +04:00
# include <linux/jbd2.h>
2008-04-30 02:13:32 +04:00
# include "ext4.h"
2006-10-11 12:20:57 +04:00
# define EXT4_JOURNAL(inode) (EXT4_SB((inode)->i_sb)->s_journal)
/* Define the number of blocks we need to account to a transaction to
* modify one block of data .
*
* We may have to touch one inode , one bitmap buffer , up to three
* indirection blocks , the group and superblock summaries , and the data
2006-10-11 12:21:03 +04:00
* block to complete the transaction .
*
2006-10-11 12:21:07 +04:00
* For extents - enabled fs we may have to allocate and modify up to
* 5 levels of tree + root which are stored in the inode . */
2006-10-11 12:20:57 +04:00
2006-10-11 12:21:03 +04:00
# define EXT4_SINGLEDATA_TRANS_BLOCKS(sb) \
( EXT4_HAS_INCOMPAT_FEATURE ( sb , EXT4_FEATURE_INCOMPAT_EXTENTS ) \
| | test_opt ( sb , EXTENTS ) ? 27U : 8U )
2006-10-11 12:20:57 +04:00
/* Extended attribute operations touch at most two data buffers,
* two bitmap buffers , and two group summaries , in addition to the inode
* and the superblock , which are already accounted for . */
# define EXT4_XATTR_TRANS_BLOCKS 6U
/* Define the minimum size for a transaction which modifies data. This
* needs to take into account the fact that we may end up modifying two
* quota files too ( one for the group , one for the user quota ) . The
* superblock only gets updated once , of course , so don ' t bother
* counting that again for the quota updates . */
2006-10-11 12:21:03 +04:00
# define EXT4_DATA_TRANS_BLOCKS(sb) (EXT4_SINGLEDATA_TRANS_BLOCKS(sb) + \
2006-10-11 12:20:57 +04:00
EXT4_XATTR_TRANS_BLOCKS - 2 + \
2 * EXT4_QUOTA_TRANS_BLOCKS ( sb ) )
/* Delete operations potentially hit one directory's namespace plus an
* entire inode , plus arbitrary amounts of bitmap / indirection data . Be
* generous . We can grow the delete transaction later if necessary . */
# define EXT4_DELETE_TRANS_BLOCKS(sb) (2 * EXT4_DATA_TRANS_BLOCKS(sb) + 64)
/* Define an arbitrary limit for the amount of data we will anticipate
* writing to any given transaction . For unbounded transactions such as
* write ( 2 ) and truncate ( 2 ) we can write more than this , but we always
* start off at the maximum transaction size and grow the transaction
* optimistically as we go . */
# define EXT4_MAX_TRANS_DATA 64U
/* We break up a large truncate or write transaction once the handle's
* buffer credits gets this low , we need either to extend the
* transaction or to start a new one . Reserve enough space here for
* inode , bitmap , superblock , group and indirection updates for at least
* one block , plus two quota updates . Quota allocations are not
* needed . */
# define EXT4_RESERVE_TRANS_BLOCKS 12U
# define EXT4_INDEX_EXTRA_TRANS_BLOCKS 8
# ifdef CONFIG_QUOTA
/* Amount of blocks needed for quota update - we know that the structure was
* allocated so we need to update only inode + data */
# define EXT4_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0)
/* Amount of blocks needed for quota insert/delete - we do some block writes
* but inode , sb and group updates are done only once */
# define EXT4_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
2006-10-11 12:21:03 +04:00
( EXT4_SINGLEDATA_TRANS_BLOCKS ( sb ) - 3 ) + 3 + DQUOT_INIT_REWRITE ) : 0 )
2006-10-11 12:20:57 +04:00
# define EXT4_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
2006-10-11 12:21:03 +04:00
( EXT4_SINGLEDATA_TRANS_BLOCKS ( sb ) - 3 ) + 3 + DQUOT_DEL_REWRITE ) : 0 )
2006-10-11 12:20:57 +04:00
# else
# define EXT4_QUOTA_TRANS_BLOCKS(sb) 0
# define EXT4_QUOTA_INIT_BLOCKS(sb) 0
# define EXT4_QUOTA_DEL_BLOCKS(sb) 0
# endif
int
ext4_mark_iloc_dirty ( handle_t * handle ,
struct inode * inode ,
struct ext4_iloc * iloc ) ;
/*
* On success , We end up with an outstanding reference count against
* iloc - > bh . This _must_ be cleaned up later .
*/
int ext4_reserve_inode_write ( handle_t * handle , struct inode * inode ,
struct ext4_iloc * iloc ) ;
int ext4_mark_inode_dirty ( handle_t * handle , struct inode * inode ) ;
/*
* Wrapper functions with which ext4 calls into JBD . The intent here is
* to allow these to be turned into appropriate stubs so ext4 can control
* ext2 filesystems , so ext2 + ext4 systems only nee one fs . This work hasn ' t
* been done yet .
*/
2006-12-07 07:37:15 +03:00
static inline void ext4_journal_release_buffer ( handle_t * handle ,
struct buffer_head * bh )
2006-10-11 12:20:57 +04:00
{
2006-12-07 07:37:15 +03:00
jbd2_journal_release_buffer ( handle , bh ) ;
2006-10-11 12:20:57 +04:00
}
2006-12-07 07:37:15 +03:00
void ext4_journal_abort_handle ( const char * caller , const char * err_fn ,
struct buffer_head * bh , handle_t * handle , int err ) ;
2006-10-11 12:20:57 +04:00
2006-12-07 07:37:15 +03:00
int __ext4_journal_get_undo_access ( const char * where , handle_t * handle ,
struct buffer_head * bh ) ;
2006-10-11 12:20:57 +04:00
2006-12-07 07:37:15 +03:00
int __ext4_journal_get_write_access ( const char * where , handle_t * handle ,
struct buffer_head * bh ) ;
2006-10-11 12:20:57 +04:00
2006-12-07 07:37:15 +03:00
int __ext4_journal_forget ( const char * where , handle_t * handle ,
struct buffer_head * bh ) ;
2006-10-11 12:20:57 +04:00
2006-12-07 07:37:15 +03:00
int __ext4_journal_revoke ( const char * where , handle_t * handle ,
ext4_fsblk_t blocknr , struct buffer_head * bh ) ;
2006-10-11 12:20:57 +04:00
2006-12-07 07:37:15 +03:00
int __ext4_journal_get_create_access ( const char * where ,
handle_t * handle , struct buffer_head * bh ) ;
2006-10-11 12:20:57 +04:00
2006-12-07 07:37:15 +03:00
int __ext4_journal_dirty_metadata ( const char * where ,
handle_t * handle , struct buffer_head * bh ) ;
2006-10-11 12:20:57 +04:00
# define ext4_journal_get_undo_access(handle, bh) \
__ext4_journal_get_undo_access ( __FUNCTION__ , ( handle ) , ( bh ) )
# define ext4_journal_get_write_access(handle, bh) \
__ext4_journal_get_write_access ( __FUNCTION__ , ( handle ) , ( bh ) )
# define ext4_journal_revoke(handle, blocknr, bh) \
__ext4_journal_revoke ( __FUNCTION__ , ( handle ) , ( blocknr ) , ( bh ) )
# define ext4_journal_get_create_access(handle, bh) \
__ext4_journal_get_create_access ( __FUNCTION__ , ( handle ) , ( bh ) )
# define ext4_journal_dirty_metadata(handle, bh) \
__ext4_journal_dirty_metadata ( __FUNCTION__ , ( handle ) , ( bh ) )
# define ext4_journal_forget(handle, bh) \
__ext4_journal_forget ( __FUNCTION__ , ( handle ) , ( bh ) )
int ext4_journal_dirty_data ( handle_t * handle , struct buffer_head * bh ) ;
handle_t * ext4_journal_start_sb ( struct super_block * sb , int nblocks ) ;
int __ext4_journal_stop ( const char * where , handle_t * handle ) ;
static inline handle_t * ext4_journal_start ( struct inode * inode , int nblocks )
{
return ext4_journal_start_sb ( inode - > i_sb , nblocks ) ;
}
# define ext4_journal_stop(handle) \
__ext4_journal_stop ( __FUNCTION__ , ( handle ) )
static inline handle_t * ext4_journal_current_handle ( void )
{
return journal_current_handle ( ) ;
}
static inline int ext4_journal_extend ( handle_t * handle , int nblocks )
{
2006-10-11 12:20:59 +04:00
return jbd2_journal_extend ( handle , nblocks ) ;
2006-10-11 12:20:57 +04:00
}
static inline int ext4_journal_restart ( handle_t * handle , int nblocks )
{
2006-10-11 12:20:59 +04:00
return jbd2_journal_restart ( handle , nblocks ) ;
2006-10-11 12:20:57 +04:00
}
static inline int ext4_journal_blocks_per_page ( struct inode * inode )
{
2006-10-11 12:20:59 +04:00
return jbd2_journal_blocks_per_page ( inode ) ;
2006-10-11 12:20:57 +04:00
}
static inline int ext4_journal_force_commit ( journal_t * journal )
{
2006-10-11 12:20:59 +04:00
return jbd2_journal_force_commit ( journal ) ;
2006-10-11 12:20:57 +04:00
}
/* super.c */
int ext4_force_commit ( struct super_block * sb ) ;
static inline int ext4_should_journal_data ( struct inode * inode )
{
if ( ! S_ISREG ( inode - > i_mode ) )
return 1 ;
if ( test_opt ( inode - > i_sb , DATA_FLAGS ) = = EXT4_MOUNT_JOURNAL_DATA )
return 1 ;
if ( EXT4_I ( inode ) - > i_flags & EXT4_JOURNAL_DATA_FL )
return 1 ;
return 0 ;
}
static inline int ext4_should_order_data ( struct inode * inode )
{
if ( ! S_ISREG ( inode - > i_mode ) )
return 0 ;
if ( EXT4_I ( inode ) - > i_flags & EXT4_JOURNAL_DATA_FL )
return 0 ;
if ( test_opt ( inode - > i_sb , DATA_FLAGS ) = = EXT4_MOUNT_ORDERED_DATA )
return 1 ;
return 0 ;
}
static inline int ext4_should_writeback_data ( struct inode * inode )
{
if ( ! S_ISREG ( inode - > i_mode ) )
return 0 ;
if ( EXT4_I ( inode ) - > i_flags & EXT4_JOURNAL_DATA_FL )
return 0 ;
if ( test_opt ( inode - > i_sb , DATA_FLAGS ) = = EXT4_MOUNT_WRITEBACK_DATA )
return 1 ;
return 0 ;
}
2008-04-30 02:13:32 +04:00
# endif /* _EXT4_JBD2_H */