2005-04-17 02:20:36 +04:00
/*
2005-11-02 06:58:39 +03:00
* Copyright ( c ) 2000 , 2005 Silicon Graphics , Inc .
* All Rights Reserved .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
2005-04-17 02:20:36 +04:00
* published by the Free Software Foundation .
*
2005-11-02 06:58:39 +03:00
* This program is distributed in the hope that it would be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2005-04-17 02:20:36 +04:00
*
2005-11-02 06:58:39 +03:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
2005-04-17 02:20:36 +04:00
*/
# include "xfs.h"
2005-11-02 06:38:42 +03:00
# include "xfs_fs.h"
2005-04-17 02:20:36 +04:00
# include "xfs_types.h"
# include "xfs_log.h"
# include "xfs_trans.h"
# include "xfs_sb.h"
# include "xfs_ag.h"
# include "xfs_mount.h"
# include "xfs_bmap_btree.h"
2005-11-02 06:38:42 +03:00
# include "xfs_alloc_btree.h"
2005-04-17 02:20:36 +04:00
# include "xfs_ialloc_btree.h"
# include "xfs_dinode.h"
# include "xfs_inode.h"
2005-11-02 06:38:42 +03:00
# include "xfs_btree.h"
# include "xfs_trans_priv.h"
# include "xfs_inode_item.h"
2010-06-24 05:36:58 +04:00
# include "xfs_trace.h"
2005-04-17 02:20:36 +04:00
# ifdef XFS_TRANS_DEBUG
STATIC void
xfs_trans_inode_broot_debug (
xfs_inode_t * ip ) ;
# else
# define xfs_trans_inode_broot_debug(ip)
# endif
/*
2010-06-24 05:36:58 +04:00
* Add a locked inode to the transaction .
*
* The inode must be locked , and it cannot be associated with any transaction .
2011-09-19 19:00:54 +04:00
* If lock_flags is non - zero the inode will be unlocked on transaction commit .
2005-04-17 02:20:36 +04:00
*/
void
xfs_trans_ijoin (
2010-06-24 05:36:58 +04:00
struct xfs_trans * tp ,
2011-09-19 19:00:54 +04:00
struct xfs_inode * ip ,
uint lock_flags )
2005-04-17 02:20:36 +04:00
{
xfs_inode_log_item_t * iip ;
2008-04-22 11:34:00 +04:00
ASSERT ( xfs_isilocked ( ip , XFS_ILOCK_EXCL ) ) ;
2005-04-17 02:20:36 +04:00
if ( ip - > i_itemp = = NULL )
xfs_inode_item_init ( ip , ip - > i_mount ) ;
iip = ip - > i_itemp ;
2011-09-19 19:00:54 +04:00
2010-06-24 05:36:58 +04:00
ASSERT ( iip - > ili_lock_flags = = 0 ) ;
2011-09-19 19:00:54 +04:00
iip - > ili_lock_flags = lock_flags ;
2005-04-17 02:20:36 +04:00
/*
* Get a log_item_desc to point at the new item .
*/
2010-06-23 12:11:15 +04:00
xfs_trans_add_item ( tp , & iip - > ili_item ) ;
2005-04-17 02:20:36 +04:00
xfs_trans_inode_broot_debug ( ip ) ;
}
2010-09-28 06:27:25 +04:00
/*
* Transactional inode timestamp update . Requires the inode to be locked and
* joined to the transaction supplied . Relies on the transaction subsystem to
* track dirty state and update / writeback the inode accordingly .
*/
void
xfs_trans_ichgtime (
struct xfs_trans * tp ,
struct xfs_inode * ip ,
int flags )
{
struct inode * inode = VFS_I ( ip ) ;
timespec_t tv ;
ASSERT ( tp ) ;
ASSERT ( xfs_isilocked ( ip , XFS_ILOCK_EXCL ) ) ;
tv = current_fs_time ( inode - > i_sb ) ;
if ( ( flags & XFS_ICHGTIME_MOD ) & &
! timespec_equal ( & inode - > i_mtime , & tv ) ) {
inode - > i_mtime = tv ;
2012-02-29 13:53:52 +04:00
ip - > i_d . di_mtime . t_sec = tv . tv_sec ;
ip - > i_d . di_mtime . t_nsec = tv . tv_nsec ;
2010-09-28 06:27:25 +04:00
}
if ( ( flags & XFS_ICHGTIME_CHG ) & &
! timespec_equal ( & inode - > i_ctime , & tv ) ) {
inode - > i_ctime = tv ;
2012-02-29 13:53:52 +04:00
ip - > i_d . di_ctime . t_sec = tv . tv_sec ;
ip - > i_d . di_ctime . t_nsec = tv . tv_nsec ;
2010-09-28 06:27:25 +04:00
}
}
2005-04-17 02:20:36 +04:00
/*
* This is called to mark the fields indicated in fieldmask as needing
* to be logged when the transaction is committed . The inode must
* already be associated with the given transaction .
*
* The values for fieldmask are defined in xfs_inode_item . h . We always
* log all of the core inode if any of it has changed , and we always log
* all of the inline data / extents / b - tree root if any of them has changed .
*/
void
xfs_trans_log_inode (
xfs_trans_t * tp ,
xfs_inode_t * ip ,
uint flags )
{
ASSERT ( ip - > i_itemp ! = NULL ) ;
2008-04-22 11:34:00 +04:00
ASSERT ( xfs_isilocked ( ip , XFS_ILOCK_EXCL ) ) ;
2005-04-17 02:20:36 +04:00
tp - > t_flags | = XFS_TRANS_DIRTY ;
2010-06-23 12:11:15 +04:00
ip - > i_itemp - > ili_item . li_desc - > lid_flags | = XFS_LID_DIRTY ;
2005-04-17 02:20:36 +04:00
/*
* Always OR in the bits from the ili_last_fields field .
* This is to coordinate with the xfs_iflush ( ) and xfs_iflush_done ( )
2012-02-29 13:53:54 +04:00
* routines in the eventual clearing of the ili_fields bits .
2005-04-17 02:20:36 +04:00
* See the big comment in xfs_iflush ( ) for an explanation of
2006-03-29 02:55:14 +04:00
* this coordination mechanism .
2005-04-17 02:20:36 +04:00
*/
flags | = ip - > i_itemp - > ili_last_fields ;
2012-02-29 13:53:54 +04:00
ip - > i_itemp - > ili_fields | = flags ;
2005-04-17 02:20:36 +04:00
}
# ifdef XFS_TRANS_DEBUG
/*
* Keep track of the state of the inode btree root to make sure we
* log it properly .
*/
STATIC void
xfs_trans_inode_broot_debug (
xfs_inode_t * ip )
{
xfs_inode_log_item_t * iip ;
ASSERT ( ip - > i_itemp ! = NULL ) ;
iip = ip - > i_itemp ;
if ( iip - > ili_root_size ! = 0 ) {
ASSERT ( iip - > ili_orig_root ! = NULL ) ;
2008-05-19 10:31:57 +04:00
kmem_free ( iip - > ili_orig_root ) ;
2005-04-17 02:20:36 +04:00
iip - > ili_root_size = 0 ;
iip - > ili_orig_root = NULL ;
}
if ( ip - > i_d . di_format = = XFS_DINODE_FMT_BTREE ) {
ASSERT ( ( ip - > i_df . if_broot ! = NULL ) & &
( ip - > i_df . if_broot_bytes > 0 ) ) ;
iip - > ili_root_size = ip - > i_df . if_broot_bytes ;
iip - > ili_orig_root =
( char * ) kmem_alloc ( iip - > ili_root_size , KM_SLEEP ) ;
memcpy ( iip - > ili_orig_root , ( char * ) ( ip - > i_df . if_broot ) ,
iip - > ili_root_size ) ;
}
}
# endif