1153323Srodrigc/* 2159451Srodrigc * Copyright (c) 2000,2005 Silicon Graphics, Inc. 3159451Srodrigc * All Rights Reserved. 4153323Srodrigc * 5159451Srodrigc * This program is free software; you can redistribute it and/or 6159451Srodrigc * modify it under the terms of the GNU General Public License as 7153323Srodrigc * published by the Free Software Foundation. 8153323Srodrigc * 9159451Srodrigc * This program is distributed in the hope that it would be useful, 10159451Srodrigc * but WITHOUT ANY WARRANTY; without even the implied warranty of 11159451Srodrigc * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12159451Srodrigc * GNU General Public License for more details. 13153323Srodrigc * 14159451Srodrigc * You should have received a copy of the GNU General Public License 15159451Srodrigc * along with this program; if not, write the Free Software Foundation, 16159451Srodrigc * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17153323Srodrigc */ 18153323Srodrigc#include "xfs.h" 19159451Srodrigc#include "xfs_fs.h" 20153323Srodrigc#include "xfs_types.h" 21159451Srodrigc#include "xfs_bit.h" 22159451Srodrigc#include "xfs_log.h" 23153323Srodrigc#include "xfs_inum.h" 24153323Srodrigc#include "xfs_trans.h" 25153323Srodrigc#include "xfs_sb.h" 26153323Srodrigc#include "xfs_ag.h" 27153323Srodrigc#include "xfs_dir.h" 28153323Srodrigc#include "xfs_dir2.h" 29153323Srodrigc#include "xfs_dmapi.h" 30153323Srodrigc#include "xfs_mount.h" 31159451Srodrigc#include "xfs_bmap_btree.h" 32153323Srodrigc#include "xfs_alloc_btree.h" 33153323Srodrigc#include "xfs_ialloc_btree.h" 34153323Srodrigc#include "xfs_dir_sf.h" 35153323Srodrigc#include "xfs_dir2_sf.h" 36159451Srodrigc#include "xfs_attr_sf.h" 37153323Srodrigc#include "xfs_dinode.h" 38159451Srodrigc#include "xfs_inode.h" 39159451Srodrigc#include "xfs_btree.h" 40159451Srodrigc#include "xfs_ialloc.h" 41159451Srodrigc#include "xfs_trans_priv.h" 42153323Srodrigc#include "xfs_inode_item.h" 43153323Srodrigc 44153323Srodrigc#ifdef XFS_TRANS_DEBUG 45153323SrodrigcSTATIC void 46153323Srodrigcxfs_trans_inode_broot_debug( 47153323Srodrigc xfs_inode_t *ip); 48153323Srodrigc#else 49153323Srodrigc#define xfs_trans_inode_broot_debug(ip) 50153323Srodrigc#endif 51153323Srodrigc 52153323Srodrigc 53153323Srodrigc/* 54153323Srodrigc * Get and lock the inode for the caller if it is not already 55153323Srodrigc * locked within the given transaction. If it is already locked 56153323Srodrigc * within the transaction, just increment its lock recursion count 57153323Srodrigc * and return a pointer to it. 58153323Srodrigc * 59153323Srodrigc * For an inode to be locked in a transaction, the inode lock, as 60153323Srodrigc * opposed to the io lock, must be taken exclusively. This ensures 61153323Srodrigc * that the inode can be involved in only 1 transaction at a time. 62153323Srodrigc * Lock recursion is handled on the io lock, but only for lock modes 63153323Srodrigc * of equal or lesser strength. That is, you can recur on the io lock 64153323Srodrigc * held EXCL with a SHARED request but not vice versa. Also, if 65153323Srodrigc * the inode is already a part of the transaction then you cannot 66153323Srodrigc * go from not holding the io lock to having it EXCL or SHARED. 67153323Srodrigc * 68153323Srodrigc * Use the inode cache routine xfs_inode_incore() to find the inode 69153323Srodrigc * if it is already owned by this transaction. 70153323Srodrigc * 71153323Srodrigc * If we don't already own the inode, use xfs_iget() to get it. 72153323Srodrigc * Since the inode log item structure is embedded in the incore 73153323Srodrigc * inode structure and is initialized when the inode is brought 74153323Srodrigc * into memory, there is nothing to do with it here. 75153323Srodrigc * 76153323Srodrigc * If the given transaction pointer is NULL, just call xfs_iget(). 77153323Srodrigc * This simplifies code which must handle both cases. 78153323Srodrigc */ 79153323Srodrigcint 80153323Srodrigcxfs_trans_iget( 81153323Srodrigc xfs_mount_t *mp, 82153323Srodrigc xfs_trans_t *tp, 83153323Srodrigc xfs_ino_t ino, 84159451Srodrigc uint flags, 85153323Srodrigc uint lock_flags, 86153323Srodrigc xfs_inode_t **ipp) 87153323Srodrigc{ 88153323Srodrigc int error; 89153323Srodrigc xfs_inode_t *ip; 90153323Srodrigc xfs_inode_log_item_t *iip; 91153323Srodrigc 92153323Srodrigc /* 93153323Srodrigc * If the transaction pointer is NULL, just call the normal 94153323Srodrigc * xfs_iget(). 95153323Srodrigc */ 96159451Srodrigc if (tp == NULL) 97159451Srodrigc return xfs_iget(mp, NULL, ino, flags, lock_flags, ipp, 0); 98153323Srodrigc 99153323Srodrigc /* 100153323Srodrigc * If we find the inode in core with this transaction 101153323Srodrigc * pointer in its i_transp field, then we know we already 102153323Srodrigc * have it locked. In this case we just increment the lock 103153323Srodrigc * recursion count and return the inode to the caller. 104153323Srodrigc * Assert that the inode is already locked in the mode requested 105153323Srodrigc * by the caller. We cannot do lock promotions yet, so 106153323Srodrigc * die if someone gets this wrong. 107153323Srodrigc */ 108153323Srodrigc if ((ip = xfs_inode_incore(tp->t_mountp, ino, tp)) != NULL) { 109153323Srodrigc /* 110153323Srodrigc * Make sure that the inode lock is held EXCL and 111153323Srodrigc * that the io lock is never upgraded when the inode 112153323Srodrigc * is already a part of the transaction. 113153323Srodrigc */ 114153323Srodrigc ASSERT(ip->i_itemp != NULL); 115153323Srodrigc ASSERT(lock_flags & XFS_ILOCK_EXCL); 116153323Srodrigc ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); 117153323Srodrigc ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) || 118153323Srodrigc ismrlocked(&ip->i_iolock, MR_UPDATE)); 119153323Srodrigc ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) || 120153323Srodrigc (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_EXCL)); 121153323Srodrigc ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) || 122153323Srodrigc ismrlocked(&ip->i_iolock, (MR_UPDATE | MR_ACCESS))); 123153323Srodrigc ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) || 124153323Srodrigc (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_ANY)); 125153323Srodrigc 126153323Srodrigc if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) { 127153323Srodrigc ip->i_itemp->ili_iolock_recur++; 128153323Srodrigc } 129153323Srodrigc if (lock_flags & XFS_ILOCK_EXCL) { 130153323Srodrigc ip->i_itemp->ili_ilock_recur++; 131153323Srodrigc } 132153323Srodrigc *ipp = ip; 133153323Srodrigc return 0; 134153323Srodrigc } 135153323Srodrigc 136153323Srodrigc ASSERT(lock_flags & XFS_ILOCK_EXCL); 137159451Srodrigc error = xfs_iget(tp->t_mountp, tp, ino, flags, lock_flags, &ip, 0); 138153323Srodrigc if (error) { 139153323Srodrigc return error; 140153323Srodrigc } 141153323Srodrigc ASSERT(ip != NULL); 142153323Srodrigc 143153323Srodrigc /* 144153323Srodrigc * Get a log_item_desc to point at the new item. 145153323Srodrigc */ 146153323Srodrigc if (ip->i_itemp == NULL) 147153323Srodrigc xfs_inode_item_init(ip, mp); 148153323Srodrigc iip = ip->i_itemp; 149153323Srodrigc (void) xfs_trans_add_item(tp, (xfs_log_item_t *)(iip)); 150153323Srodrigc 151153323Srodrigc xfs_trans_inode_broot_debug(ip); 152153323Srodrigc 153153323Srodrigc /* 154153323Srodrigc * If the IO lock has been acquired, mark that in 155153323Srodrigc * the inode log item so we'll know to unlock it 156153323Srodrigc * when the transaction commits. 157153323Srodrigc */ 158153323Srodrigc ASSERT(iip->ili_flags == 0); 159153323Srodrigc if (lock_flags & XFS_IOLOCK_EXCL) { 160153323Srodrigc iip->ili_flags |= XFS_ILI_IOLOCKED_EXCL; 161153323Srodrigc } else if (lock_flags & XFS_IOLOCK_SHARED) { 162153323Srodrigc iip->ili_flags |= XFS_ILI_IOLOCKED_SHARED; 163153323Srodrigc } 164153323Srodrigc 165153323Srodrigc /* 166153323Srodrigc * Initialize i_transp so we can find it with xfs_inode_incore() 167153323Srodrigc * above. 168153323Srodrigc */ 169153323Srodrigc ip->i_transp = tp; 170153323Srodrigc 171153323Srodrigc *ipp = ip; 172153323Srodrigc return 0; 173153323Srodrigc} 174153323Srodrigc 175153323Srodrigc/* 176153323Srodrigc * Add the locked inode to the transaction. 177153323Srodrigc * The inode must be locked, and it cannot be associated with any 178153323Srodrigc * transaction. The caller must specify the locks already held 179153323Srodrigc * on the inode. 180153323Srodrigc */ 181153323Srodrigcvoid 182153323Srodrigcxfs_trans_ijoin( 183153323Srodrigc xfs_trans_t *tp, 184153323Srodrigc xfs_inode_t *ip, 185153323Srodrigc uint lock_flags) 186153323Srodrigc{ 187153323Srodrigc xfs_inode_log_item_t *iip; 188153323Srodrigc 189153323Srodrigc ASSERT(ip->i_transp == NULL); 190153323Srodrigc ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); 191153323Srodrigc ASSERT(lock_flags & XFS_ILOCK_EXCL); 192153323Srodrigc if (ip->i_itemp == NULL) 193153323Srodrigc xfs_inode_item_init(ip, ip->i_mount); 194153323Srodrigc iip = ip->i_itemp; 195153323Srodrigc ASSERT(iip->ili_flags == 0); 196153323Srodrigc ASSERT(iip->ili_ilock_recur == 0); 197153323Srodrigc ASSERT(iip->ili_iolock_recur == 0); 198153323Srodrigc 199153323Srodrigc /* 200153323Srodrigc * Get a log_item_desc to point at the new item. 201153323Srodrigc */ 202153323Srodrigc (void) xfs_trans_add_item(tp, (xfs_log_item_t*)(iip)); 203153323Srodrigc 204153323Srodrigc xfs_trans_inode_broot_debug(ip); 205153323Srodrigc 206153323Srodrigc /* 207153323Srodrigc * If the IO lock is already held, mark that in the inode log item. 208153323Srodrigc */ 209153323Srodrigc if (lock_flags & XFS_IOLOCK_EXCL) { 210153323Srodrigc iip->ili_flags |= XFS_ILI_IOLOCKED_EXCL; 211153323Srodrigc } else if (lock_flags & XFS_IOLOCK_SHARED) { 212153323Srodrigc iip->ili_flags |= XFS_ILI_IOLOCKED_SHARED; 213153323Srodrigc } 214153323Srodrigc 215153323Srodrigc /* 216153323Srodrigc * Initialize i_transp so we can find it with xfs_inode_incore() 217153323Srodrigc * in xfs_trans_iget() above. 218153323Srodrigc */ 219153323Srodrigc ip->i_transp = tp; 220153323Srodrigc} 221153323Srodrigc 222153323Srodrigc 223153323Srodrigc 224153323Srodrigc/* 225153323Srodrigc * Mark the inode as not needing to be unlocked when the inode item's 226153323Srodrigc * IOP_UNLOCK() routine is called. The inode must already be locked 227153323Srodrigc * and associated with the given transaction. 228153323Srodrigc */ 229153323Srodrigc/*ARGSUSED*/ 230153323Srodrigcvoid 231153323Srodrigcxfs_trans_ihold( 232153323Srodrigc xfs_trans_t *tp, 233153323Srodrigc xfs_inode_t *ip) 234153323Srodrigc{ 235153323Srodrigc ASSERT(ip->i_transp == tp); 236153323Srodrigc ASSERT(ip->i_itemp != NULL); 237153323Srodrigc ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); 238153323Srodrigc 239153323Srodrigc ip->i_itemp->ili_flags |= XFS_ILI_HOLD; 240153323Srodrigc} 241153323Srodrigc 242153323Srodrigc 243153323Srodrigc/* 244153323Srodrigc * This is called to mark the fields indicated in fieldmask as needing 245153323Srodrigc * to be logged when the transaction is committed. The inode must 246153323Srodrigc * already be associated with the given transaction. 247153323Srodrigc * 248153323Srodrigc * The values for fieldmask are defined in xfs_inode_item.h. We always 249153323Srodrigc * log all of the core inode if any of it has changed, and we always log 250153323Srodrigc * all of the inline data/extents/b-tree root if any of them has changed. 251153323Srodrigc */ 252153323Srodrigcvoid 253153323Srodrigcxfs_trans_log_inode( 254153323Srodrigc xfs_trans_t *tp, 255153323Srodrigc xfs_inode_t *ip, 256153323Srodrigc uint flags) 257153323Srodrigc{ 258153323Srodrigc xfs_log_item_desc_t *lidp; 259153323Srodrigc 260153323Srodrigc ASSERT(ip->i_transp == tp); 261153323Srodrigc ASSERT(ip->i_itemp != NULL); 262153323Srodrigc ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); 263153323Srodrigc 264153323Srodrigc lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)(ip->i_itemp)); 265153323Srodrigc ASSERT(lidp != NULL); 266153323Srodrigc 267153323Srodrigc tp->t_flags |= XFS_TRANS_DIRTY; 268153323Srodrigc lidp->lid_flags |= XFS_LID_DIRTY; 269153323Srodrigc 270153323Srodrigc /* 271153323Srodrigc * Always OR in the bits from the ili_last_fields field. 272153323Srodrigc * This is to coordinate with the xfs_iflush() and xfs_iflush_done() 273153323Srodrigc * routines in the eventual clearing of the ilf_fields bits. 274153323Srodrigc * See the big comment in xfs_iflush() for an explanation of 275159451Srodrigc * this coordination mechanism. 276153323Srodrigc */ 277153323Srodrigc flags |= ip->i_itemp->ili_last_fields; 278153323Srodrigc ip->i_itemp->ili_format.ilf_fields |= flags; 279153323Srodrigc} 280153323Srodrigc 281153323Srodrigc#ifdef XFS_TRANS_DEBUG 282153323Srodrigc/* 283153323Srodrigc * Keep track of the state of the inode btree root to make sure we 284153323Srodrigc * log it properly. 285153323Srodrigc */ 286153323SrodrigcSTATIC void 287153323Srodrigcxfs_trans_inode_broot_debug( 288153323Srodrigc xfs_inode_t *ip) 289153323Srodrigc{ 290153323Srodrigc xfs_inode_log_item_t *iip; 291153323Srodrigc 292153323Srodrigc ASSERT(ip->i_itemp != NULL); 293153323Srodrigc iip = ip->i_itemp; 294153323Srodrigc if (iip->ili_root_size != 0) { 295153323Srodrigc ASSERT(iip->ili_orig_root != NULL); 296153323Srodrigc kmem_free(iip->ili_orig_root, iip->ili_root_size); 297153323Srodrigc iip->ili_root_size = 0; 298153323Srodrigc iip->ili_orig_root = NULL; 299153323Srodrigc } 300153323Srodrigc if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE) { 301153323Srodrigc ASSERT((ip->i_df.if_broot != NULL) && 302153323Srodrigc (ip->i_df.if_broot_bytes > 0)); 303153323Srodrigc iip->ili_root_size = ip->i_df.if_broot_bytes; 304153323Srodrigc iip->ili_orig_root = 305153323Srodrigc (char*)kmem_alloc(iip->ili_root_size, KM_SLEEP); 306153323Srodrigc memcpy(iip->ili_orig_root, (char*)(ip->i_df.if_broot), 307153323Srodrigc iip->ili_root_size); 308153323Srodrigc } 309153323Srodrigc} 310153323Srodrigc#endif 311