diff options
Diffstat (limited to 'fs/xfs/xfs_bmap_btree.c')
-rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index cf3bc76710c3..aa2eadd41bab 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -925,3 +925,37 @@ xfs_bmdr_maxrecs( return blocklen / sizeof(xfs_bmdr_rec_t); return blocklen / (sizeof(xfs_bmdr_key_t) + sizeof(xfs_bmdr_ptr_t)); } + +/* + * Change the owner of a btree format fork fo the inode passed in. Change it to + * the owner of that is passed in so that we can change owners before or after + * we switch forks between inodes. The operation that the caller is doing will + * determine whether is needs to change owner before or after the switch. + * + * For demand paged modification, the fork switch should be done after reading + * in all the blocks, modifying them and pinning them in the transaction. For + * modification when the buffers are already pinned in memory, the fork switch + * can be done before changing the owner as we won't need to validate the owner + * until the btree buffers are unpinned and writes can occur again. + */ +int +xfs_bmbt_change_owner( + struct xfs_trans *tp, + struct xfs_inode *ip, + int whichfork, + xfs_ino_t new_owner) +{ + struct xfs_btree_cur *cur; + int error; + + if (whichfork == XFS_DATA_FORK) + ASSERT(ip->i_d.di_format = XFS_DINODE_FMT_BTREE); + else + ASSERT(ip->i_d.di_aformat = XFS_DINODE_FMT_BTREE); + + cur = xfs_bmbt_init_cursor(ip->i_mount, tp, ip, whichfork); + error = xfs_btree_change_owner(cur, new_owner); + xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + return error; +} + |