aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c292
1 files changed, 157 insertions, 135 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index dbd9cef852ec..cd522827f99e 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -41,6 +41,7 @@
41#include "xfs_buf_item.h" 41#include "xfs_buf_item.h"
42#include "xfs_inode_item.h" 42#include "xfs_inode_item.h"
43#include "xfs_btree.h" 43#include "xfs_btree.h"
44#include "xfs_btree_trace.h"
44#include "xfs_alloc.h" 45#include "xfs_alloc.h"
45#include "xfs_ialloc.h" 46#include "xfs_ialloc.h"
46#include "xfs_bmap.h" 47#include "xfs_bmap.h"
@@ -221,25 +222,26 @@ xfs_imap_to_bp(
221 * Use xfs_imap() to determine the size and location of the 222 * Use xfs_imap() to determine the size and location of the
222 * buffer to read from disk. 223 * buffer to read from disk.
223 */ 224 */
224STATIC int 225int
225xfs_inotobp( 226xfs_inotobp(
226 xfs_mount_t *mp, 227 xfs_mount_t *mp,
227 xfs_trans_t *tp, 228 xfs_trans_t *tp,
228 xfs_ino_t ino, 229 xfs_ino_t ino,
229 xfs_dinode_t **dipp, 230 xfs_dinode_t **dipp,
230 xfs_buf_t **bpp, 231 xfs_buf_t **bpp,
231 int *offset) 232 int *offset,
233 uint imap_flags)
232{ 234{
233 xfs_imap_t imap; 235 xfs_imap_t imap;
234 xfs_buf_t *bp; 236 xfs_buf_t *bp;
235 int error; 237 int error;
236 238
237 imap.im_blkno = 0; 239 imap.im_blkno = 0;
238 error = xfs_imap(mp, tp, ino, &imap, XFS_IMAP_LOOKUP); 240 error = xfs_imap(mp, tp, ino, &imap, imap_flags | XFS_IMAP_LOOKUP);
239 if (error) 241 if (error)
240 return error; 242 return error;
241 243
242 error = xfs_imap_to_bp(mp, tp, &imap, &bp, XFS_BUF_LOCK, 0); 244 error = xfs_imap_to_bp(mp, tp, &imap, &bp, XFS_BUF_LOCK, imap_flags);
243 if (error) 245 if (error)
244 return error; 246 return error;
245 247
@@ -621,7 +623,7 @@ xfs_iformat_btree(
621 ifp = XFS_IFORK_PTR(ip, whichfork); 623 ifp = XFS_IFORK_PTR(ip, whichfork);
622 dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); 624 dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
623 size = XFS_BMAP_BROOT_SPACE(dfp); 625 size = XFS_BMAP_BROOT_SPACE(dfp);
624 nrecs = XFS_BMAP_BROOT_NUMRECS(dfp); 626 nrecs = be16_to_cpu(dfp->bb_numrecs);
625 627
626 /* 628 /*
627 * blow out if -- fork has less extents than can fit in 629 * blow out if -- fork has less extents than can fit in
@@ -649,8 +651,9 @@ xfs_iformat_btree(
649 * Copy and convert from the on-disk structure 651 * Copy and convert from the on-disk structure
650 * to the in-memory structure. 652 * to the in-memory structure.
651 */ 653 */
652 xfs_bmdr_to_bmbt(dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork), 654 xfs_bmdr_to_bmbt(ip->i_mount, dfp,
653 ifp->if_broot, size); 655 XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
656 ifp->if_broot, size);
654 ifp->if_flags &= ~XFS_IFEXTENTS; 657 ifp->if_flags &= ~XFS_IFEXTENTS;
655 ifp->if_flags |= XFS_IFBROOT; 658 ifp->if_flags |= XFS_IFBROOT;
656 659
@@ -788,51 +791,56 @@ xfs_dic2xflags(
788} 791}
789 792
790/* 793/*
791 * Given a mount structure and an inode number, return a pointer 794 * Allocate and initialise an xfs_inode.
792 * to a newly allocated in-core inode corresponding to the given
793 * inode number.
794 *
795 * Initialize the inode's attributes and extent pointers if it
796 * already has them (it will not if the inode has no links).
797 */ 795 */
798int 796STATIC struct xfs_inode *
799xfs_iread( 797xfs_inode_alloc(
800 xfs_mount_t *mp, 798 struct xfs_mount *mp,
801 xfs_trans_t *tp, 799 xfs_ino_t ino)
802 xfs_ino_t ino,
803 xfs_inode_t **ipp,
804 xfs_daddr_t bno,
805 uint imap_flags)
806{ 800{
807 xfs_buf_t *bp; 801 struct xfs_inode *ip;
808 xfs_dinode_t *dip;
809 xfs_inode_t *ip;
810 int error;
811 802
812 ASSERT(xfs_inode_zone != NULL); 803 /*
804 * if this didn't occur in transactions, we could use
805 * KM_MAYFAIL and return NULL here on ENOMEM. Set the
806 * code up to do this anyway.
807 */
808 ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP);
809 if (!ip)
810 return NULL;
813 811
814 ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); 812 ASSERT(atomic_read(&ip->i_iocount) == 0);
815 ip->i_ino = ino; 813 ASSERT(atomic_read(&ip->i_pincount) == 0);
816 ip->i_mount = mp; 814 ASSERT(!spin_is_locked(&ip->i_flags_lock));
817 atomic_set(&ip->i_iocount, 0); 815 ASSERT(completion_done(&ip->i_flush));
818 spin_lock_init(&ip->i_flags_lock);
819 816
820 /* 817 /*
821 * Get pointer's to the on-disk inode and the buffer containing it. 818 * initialise the VFS inode here to get failures
822 * If the inode number refers to a block outside the file system 819 * out of the way early.
823 * then xfs_itobp() will return NULL. In this case we should
824 * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will
825 * know that this is a new incore inode.
826 */ 820 */
827 error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags, XFS_BUF_LOCK); 821 if (!inode_init_always(mp->m_super, VFS_I(ip))) {
828 if (error) {
829 kmem_zone_free(xfs_inode_zone, ip); 822 kmem_zone_free(xfs_inode_zone, ip);
830 return error; 823 return NULL;
831 } 824 }
832 825
826 /* initialise the xfs inode */
827 ip->i_ino = ino;
828 ip->i_mount = mp;
829 ip->i_blkno = 0;
830 ip->i_len = 0;
831 ip->i_boffset =0;
832 ip->i_afp = NULL;
833 memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
834 ip->i_flags = 0;
835 ip->i_update_core = 0;
836 ip->i_update_size = 0;
837 ip->i_delayed_blks = 0;
838 memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
839 ip->i_size = 0;
840 ip->i_new_size = 0;
841
833 /* 842 /*
834 * Initialize inode's trace buffers. 843 * Initialize inode's trace buffers.
835 * Do this before xfs_iformat in case it adds entries.
836 */ 844 */
837#ifdef XFS_INODE_TRACE 845#ifdef XFS_INODE_TRACE
838 ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS); 846 ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
@@ -840,7 +848,7 @@ xfs_iread(
840#ifdef XFS_BMAP_TRACE 848#ifdef XFS_BMAP_TRACE
841 ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS); 849 ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
842#endif 850#endif
843#ifdef XFS_BMBT_TRACE 851#ifdef XFS_BTREE_TRACE
844 ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS); 852 ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
845#endif 853#endif
846#ifdef XFS_RW_TRACE 854#ifdef XFS_RW_TRACE
@@ -853,13 +861,51 @@ xfs_iread(
853 ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS); 861 ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
854#endif 862#endif
855 863
864 return ip;
865}
866
867/*
868 * Given a mount structure and an inode number, return a pointer
869 * to a newly allocated in-core inode corresponding to the given
870 * inode number.
871 *
872 * Initialize the inode's attributes and extent pointers if it
873 * already has them (it will not if the inode has no links).
874 */
875int
876xfs_iread(
877 xfs_mount_t *mp,
878 xfs_trans_t *tp,
879 xfs_ino_t ino,
880 xfs_inode_t **ipp,
881 xfs_daddr_t bno,
882 uint imap_flags)
883{
884 xfs_buf_t *bp;
885 xfs_dinode_t *dip;
886 xfs_inode_t *ip;
887 int error;
888
889 ip = xfs_inode_alloc(mp, ino);
890 if (!ip)
891 return ENOMEM;
892
893 /*
894 * Get pointer's to the on-disk inode and the buffer containing it.
895 * If the inode number refers to a block outside the file system
896 * then xfs_itobp() will return NULL. In this case we should
897 * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will
898 * know that this is a new incore inode.
899 */
900 error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags, XFS_BUF_LOCK);
901 if (error)
902 goto out_destroy_inode;
903
856 /* 904 /*
857 * If we got something that isn't an inode it means someone 905 * If we got something that isn't an inode it means someone
858 * (nfs or dmi) has a stale handle. 906 * (nfs or dmi) has a stale handle.
859 */ 907 */
860 if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) { 908 if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) {
861 kmem_zone_free(xfs_inode_zone, ip);
862 xfs_trans_brelse(tp, bp);
863#ifdef DEBUG 909#ifdef DEBUG
864 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " 910 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
865 "dip->di_core.di_magic (0x%x) != " 911 "dip->di_core.di_magic (0x%x) != "
@@ -867,7 +913,8 @@ xfs_iread(
867 be16_to_cpu(dip->di_core.di_magic), 913 be16_to_cpu(dip->di_core.di_magic),
868 XFS_DINODE_MAGIC); 914 XFS_DINODE_MAGIC);
869#endif /* DEBUG */ 915#endif /* DEBUG */
870 return XFS_ERROR(EINVAL); 916 error = XFS_ERROR(EINVAL);
917 goto out_brelse;
871 } 918 }
872 919
873 /* 920 /*
@@ -881,14 +928,12 @@ xfs_iread(
881 xfs_dinode_from_disk(&ip->i_d, &dip->di_core); 928 xfs_dinode_from_disk(&ip->i_d, &dip->di_core);
882 error = xfs_iformat(ip, dip); 929 error = xfs_iformat(ip, dip);
883 if (error) { 930 if (error) {
884 kmem_zone_free(xfs_inode_zone, ip);
885 xfs_trans_brelse(tp, bp);
886#ifdef DEBUG 931#ifdef DEBUG
887 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " 932 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
888 "xfs_iformat() returned error %d", 933 "xfs_iformat() returned error %d",
889 error); 934 error);
890#endif /* DEBUG */ 935#endif /* DEBUG */
891 return error; 936 goto out_brelse;
892 } 937 }
893 } else { 938 } else {
894 ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic); 939 ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic);
@@ -911,8 +956,6 @@ xfs_iread(
911 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); 956 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
912 } 957 }
913 958
914 INIT_LIST_HEAD(&ip->i_reclaim);
915
916 /* 959 /*
917 * The inode format changed when we moved the link count and 960 * The inode format changed when we moved the link count and
918 * made it 32 bits long. If this is an old format inode, 961 * made it 32 bits long. If this is an old format inode,
@@ -956,6 +999,12 @@ xfs_iread(
956 xfs_trans_brelse(tp, bp); 999 xfs_trans_brelse(tp, bp);
957 *ipp = ip; 1000 *ipp = ip;
958 return 0; 1001 return 0;
1002
1003 out_brelse:
1004 xfs_trans_brelse(tp, bp);
1005 out_destroy_inode:
1006 xfs_destroy_inode(ip);
1007 return error;
959} 1008}
960 1009
961/* 1010/*
@@ -1049,6 +1098,7 @@ xfs_ialloc(
1049 uint flags; 1098 uint flags;
1050 int error; 1099 int error;
1051 timespec_t tv; 1100 timespec_t tv;
1101 int filestreams = 0;
1052 1102
1053 /* 1103 /*
1054 * Call the space management code to pick 1104 * Call the space management code to pick
@@ -1056,9 +1106,8 @@ xfs_ialloc(
1056 */ 1106 */
1057 error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, 1107 error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc,
1058 ialloc_context, call_again, &ino); 1108 ialloc_context, call_again, &ino);
1059 if (error != 0) { 1109 if (error)
1060 return error; 1110 return error;
1061 }
1062 if (*call_again || ino == NULLFSINO) { 1111 if (*call_again || ino == NULLFSINO) {
1063 *ipp = NULL; 1112 *ipp = NULL;
1064 return 0; 1113 return 0;
@@ -1072,9 +1121,8 @@ xfs_ialloc(
1072 */ 1121 */
1073 error = xfs_trans_iget(tp->t_mountp, tp, ino, 1122 error = xfs_trans_iget(tp->t_mountp, tp, ino,
1074 XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip); 1123 XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip);
1075 if (error != 0) { 1124 if (error)
1076 return error; 1125 return error;
1077 }
1078 ASSERT(ip != NULL); 1126 ASSERT(ip != NULL);
1079 1127
1080 ip->i_d.di_mode = (__uint16_t)mode; 1128 ip->i_d.di_mode = (__uint16_t)mode;
@@ -1155,13 +1203,12 @@ xfs_ialloc(
1155 flags |= XFS_ILOG_DEV; 1203 flags |= XFS_ILOG_DEV;
1156 break; 1204 break;
1157 case S_IFREG: 1205 case S_IFREG:
1158 if (pip && xfs_inode_is_filestream(pip)) { 1206 /*
1159 error = xfs_filestream_associate(pip, ip); 1207 * we can't set up filestreams until after the VFS inode
1160 if (error < 0) 1208 * is set up properly.
1161 return -error; 1209 */
1162 if (!error) 1210 if (pip && xfs_inode_is_filestream(pip))
1163 xfs_iflags_set(ip, XFS_IFILESTREAM); 1211 filestreams = 1;
1164 }
1165 /* fall through */ 1212 /* fall through */
1166 case S_IFDIR: 1213 case S_IFDIR:
1167 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { 1214 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
@@ -1227,6 +1274,15 @@ xfs_ialloc(
1227 /* now that we have an i_mode we can setup inode ops and unlock */ 1274 /* now that we have an i_mode we can setup inode ops and unlock */
1228 xfs_setup_inode(ip); 1275 xfs_setup_inode(ip);
1229 1276
1277 /* now we have set up the vfs inode we can associate the filestream */
1278 if (filestreams) {
1279 error = xfs_filestream_associate(pip, ip);
1280 if (error < 0)
1281 return -error;
1282 if (!error)
1283 xfs_iflags_set(ip, XFS_IFILESTREAM);
1284 }
1285
1230 *ipp = ip; 1286 *ipp = ip;
1231 return 0; 1287 return 0;
1232} 1288}
@@ -1414,7 +1470,7 @@ xfs_itruncate_start(
1414 mp = ip->i_mount; 1470 mp = ip->i_mount;
1415 1471
1416 /* wait for the completion of any pending DIOs */ 1472 /* wait for the completion of any pending DIOs */
1417 if (new_size < ip->i_size) 1473 if (new_size == 0 || new_size < ip->i_size)
1418 vn_iowait(ip); 1474 vn_iowait(ip);
1419 1475
1420 /* 1476 /*
@@ -1992,7 +2048,7 @@ xfs_iunlink_remove(
1992 } 2048 }
1993 next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino); 2049 next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino);
1994 error = xfs_inotobp(mp, tp, next_ino, &last_dip, 2050 error = xfs_inotobp(mp, tp, next_ino, &last_dip,
1995 &last_ibp, &last_offset); 2051 &last_ibp, &last_offset, 0);
1996 if (error) { 2052 if (error) {
1997 cmn_err(CE_WARN, 2053 cmn_err(CE_WARN,
1998 "xfs_iunlink_remove: xfs_inotobp() returned an error %d on %s. Returning error.", 2054 "xfs_iunlink_remove: xfs_inotobp() returned an error %d on %s. Returning error.",
@@ -2160,9 +2216,9 @@ xfs_ifree_cluster(
2160 iip = (xfs_inode_log_item_t *)lip; 2216 iip = (xfs_inode_log_item_t *)lip;
2161 ASSERT(iip->ili_logged == 1); 2217 ASSERT(iip->ili_logged == 1);
2162 lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done; 2218 lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done;
2163 spin_lock(&mp->m_ail_lock); 2219 xfs_trans_ail_copy_lsn(mp->m_ail,
2164 iip->ili_flush_lsn = iip->ili_item.li_lsn; 2220 &iip->ili_flush_lsn,
2165 spin_unlock(&mp->m_ail_lock); 2221 &iip->ili_item.li_lsn);
2166 xfs_iflags_set(iip->ili_inode, XFS_ISTALE); 2222 xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
2167 pre_flushed++; 2223 pre_flushed++;
2168 } 2224 }
@@ -2183,9 +2239,8 @@ xfs_ifree_cluster(
2183 iip->ili_last_fields = iip->ili_format.ilf_fields; 2239 iip->ili_last_fields = iip->ili_format.ilf_fields;
2184 iip->ili_format.ilf_fields = 0; 2240 iip->ili_format.ilf_fields = 0;
2185 iip->ili_logged = 1; 2241 iip->ili_logged = 1;
2186 spin_lock(&mp->m_ail_lock); 2242 xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
2187 iip->ili_flush_lsn = iip->ili_item.li_lsn; 2243 &iip->ili_item.li_lsn);
2188 spin_unlock(&mp->m_ail_lock);
2189 2244
2190 xfs_buf_attach_iodone(bp, 2245 xfs_buf_attach_iodone(bp,
2191 (void(*)(xfs_buf_t*,xfs_log_item_t*)) 2246 (void(*)(xfs_buf_t*,xfs_log_item_t*))
@@ -2312,9 +2367,10 @@ xfs_iroot_realloc(
2312 int rec_diff, 2367 int rec_diff,
2313 int whichfork) 2368 int whichfork)
2314{ 2369{
2370 struct xfs_mount *mp = ip->i_mount;
2315 int cur_max; 2371 int cur_max;
2316 xfs_ifork_t *ifp; 2372 xfs_ifork_t *ifp;
2317 xfs_bmbt_block_t *new_broot; 2373 struct xfs_btree_block *new_broot;
2318 int new_max; 2374 int new_max;
2319 size_t new_size; 2375 size_t new_size;
2320 char *np; 2376 char *np;
@@ -2335,8 +2391,7 @@ xfs_iroot_realloc(
2335 */ 2391 */
2336 if (ifp->if_broot_bytes == 0) { 2392 if (ifp->if_broot_bytes == 0) {
2337 new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(rec_diff); 2393 new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(rec_diff);
2338 ifp->if_broot = (xfs_bmbt_block_t*)kmem_alloc(new_size, 2394 ifp->if_broot = kmem_alloc(new_size, KM_SLEEP);
2339 KM_SLEEP);
2340 ifp->if_broot_bytes = (int)new_size; 2395 ifp->if_broot_bytes = (int)new_size;
2341 return; 2396 return;
2342 } 2397 }
@@ -2347,18 +2402,16 @@ xfs_iroot_realloc(
2347 * location. The records don't change location because 2402 * location. The records don't change location because
2348 * they are kept butted up against the btree block header. 2403 * they are kept butted up against the btree block header.
2349 */ 2404 */
2350 cur_max = XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes); 2405 cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
2351 new_max = cur_max + rec_diff; 2406 new_max = cur_max + rec_diff;
2352 new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max); 2407 new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max);
2353 ifp->if_broot = (xfs_bmbt_block_t *) 2408 ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
2354 kmem_realloc(ifp->if_broot,
2355 new_size,
2356 (size_t)XFS_BMAP_BROOT_SPACE_CALC(cur_max), /* old size */ 2409 (size_t)XFS_BMAP_BROOT_SPACE_CALC(cur_max), /* old size */
2357 KM_SLEEP); 2410 KM_SLEEP);
2358 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp->if_broot, 1, 2411 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
2359 ifp->if_broot_bytes); 2412 ifp->if_broot_bytes);
2360 np = (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp->if_broot, 1, 2413 np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
2361 (int)new_size); 2414 (int)new_size);
2362 ifp->if_broot_bytes = (int)new_size; 2415 ifp->if_broot_bytes = (int)new_size;
2363 ASSERT(ifp->if_broot_bytes <= 2416 ASSERT(ifp->if_broot_bytes <=
2364 XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ); 2417 XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ);
@@ -2372,7 +2425,7 @@ xfs_iroot_realloc(
2372 * records, just get rid of the root and clear the status bit. 2425 * records, just get rid of the root and clear the status bit.
2373 */ 2426 */
2374 ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0)); 2427 ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0));
2375 cur_max = XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes); 2428 cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
2376 new_max = cur_max + rec_diff; 2429 new_max = cur_max + rec_diff;
2377 ASSERT(new_max >= 0); 2430 ASSERT(new_max >= 0);
2378 if (new_max > 0) 2431 if (new_max > 0)
@@ -2380,11 +2433,11 @@ xfs_iroot_realloc(
2380 else 2433 else
2381 new_size = 0; 2434 new_size = 0;
2382 if (new_size > 0) { 2435 if (new_size > 0) {
2383 new_broot = (xfs_bmbt_block_t *)kmem_alloc(new_size, KM_SLEEP); 2436 new_broot = kmem_alloc(new_size, KM_SLEEP);
2384 /* 2437 /*
2385 * First copy over the btree block header. 2438 * First copy over the btree block header.
2386 */ 2439 */
2387 memcpy(new_broot, ifp->if_broot, sizeof(xfs_bmbt_block_t)); 2440 memcpy(new_broot, ifp->if_broot, XFS_BTREE_LBLOCK_LEN);
2388 } else { 2441 } else {
2389 new_broot = NULL; 2442 new_broot = NULL;
2390 ifp->if_flags &= ~XFS_IFBROOT; 2443 ifp->if_flags &= ~XFS_IFBROOT;
@@ -2397,18 +2450,16 @@ xfs_iroot_realloc(
2397 /* 2450 /*
2398 * First copy the records. 2451 * First copy the records.
2399 */ 2452 */
2400 op = (char *)XFS_BMAP_BROOT_REC_ADDR(ifp->if_broot, 1, 2453 op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1);
2401 ifp->if_broot_bytes); 2454 np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1);
2402 np = (char *)XFS_BMAP_BROOT_REC_ADDR(new_broot, 1,
2403 (int)new_size);
2404 memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); 2455 memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t));
2405 2456
2406 /* 2457 /*
2407 * Then copy the pointers. 2458 * Then copy the pointers.
2408 */ 2459 */
2409 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp->if_broot, 1, 2460 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
2410 ifp->if_broot_bytes); 2461 ifp->if_broot_bytes);
2411 np = (char *)XFS_BMAP_BROOT_PTR_ADDR(new_broot, 1, 2462 np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1,
2412 (int)new_size); 2463 (int)new_size);
2413 memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); 2464 memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t));
2414 } 2465 }
@@ -2617,6 +2668,10 @@ xfs_idestroy_fork(
2617 * It must free the inode itself and any buffers allocated for 2668 * It must free the inode itself and any buffers allocated for
2618 * if_extents/if_data and if_broot. It must also free the lock 2669 * if_extents/if_data and if_broot. It must also free the lock
2619 * associated with the inode. 2670 * associated with the inode.
2671 *
2672 * Note: because we don't initialise everything on reallocation out
2673 * of the zone, we must ensure we nullify everything correctly before
2674 * freeing the structure.
2620 */ 2675 */
2621void 2676void
2622xfs_idestroy( 2677xfs_idestroy(
@@ -2631,8 +2686,6 @@ xfs_idestroy(
2631 } 2686 }
2632 if (ip->i_afp) 2687 if (ip->i_afp)
2633 xfs_idestroy_fork(ip, XFS_ATTR_FORK); 2688 xfs_idestroy_fork(ip, XFS_ATTR_FORK);
2634 mrfree(&ip->i_lock);
2635 mrfree(&ip->i_iolock);
2636 2689
2637#ifdef XFS_INODE_TRACE 2690#ifdef XFS_INODE_TRACE
2638 ktrace_free(ip->i_trace); 2691 ktrace_free(ip->i_trace);
@@ -2640,7 +2693,7 @@ xfs_idestroy(
2640#ifdef XFS_BMAP_TRACE 2693#ifdef XFS_BMAP_TRACE
2641 ktrace_free(ip->i_xtrace); 2694 ktrace_free(ip->i_xtrace);
2642#endif 2695#endif
2643#ifdef XFS_BMBT_TRACE 2696#ifdef XFS_BTREE_TRACE
2644 ktrace_free(ip->i_btrace); 2697 ktrace_free(ip->i_btrace);
2645#endif 2698#endif
2646#ifdef XFS_RW_TRACE 2699#ifdef XFS_RW_TRACE
@@ -2658,20 +2711,26 @@ xfs_idestroy(
2658 * inode still in the AIL. If it is there, we should remove 2711 * inode still in the AIL. If it is there, we should remove
2659 * it to prevent a use-after-free from occurring. 2712 * it to prevent a use-after-free from occurring.
2660 */ 2713 */
2661 xfs_mount_t *mp = ip->i_mount;
2662 xfs_log_item_t *lip = &ip->i_itemp->ili_item; 2714 xfs_log_item_t *lip = &ip->i_itemp->ili_item;
2715 struct xfs_ail *ailp = lip->li_ailp;
2663 2716
2664 ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) || 2717 ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) ||
2665 XFS_FORCED_SHUTDOWN(ip->i_mount)); 2718 XFS_FORCED_SHUTDOWN(ip->i_mount));
2666 if (lip->li_flags & XFS_LI_IN_AIL) { 2719 if (lip->li_flags & XFS_LI_IN_AIL) {
2667 spin_lock(&mp->m_ail_lock); 2720 spin_lock(&ailp->xa_lock);
2668 if (lip->li_flags & XFS_LI_IN_AIL) 2721 if (lip->li_flags & XFS_LI_IN_AIL)
2669 xfs_trans_delete_ail(mp, lip); 2722 xfs_trans_ail_delete(ailp, lip);
2670 else 2723 else
2671 spin_unlock(&mp->m_ail_lock); 2724 spin_unlock(&ailp->xa_lock);
2672 } 2725 }
2673 xfs_inode_item_destroy(ip); 2726 xfs_inode_item_destroy(ip);
2727 ip->i_itemp = NULL;
2674 } 2728 }
2729 /* asserts to verify all state is correct here */
2730 ASSERT(atomic_read(&ip->i_iocount) == 0);
2731 ASSERT(atomic_read(&ip->i_pincount) == 0);
2732 ASSERT(!spin_is_locked(&ip->i_flags_lock));
2733 ASSERT(completion_done(&ip->i_flush));
2675 kmem_zone_free(xfs_inode_zone, ip); 2734 kmem_zone_free(xfs_inode_zone, ip);
2676} 2735}
2677 2736
@@ -2880,7 +2939,7 @@ xfs_iflush_fork(
2880 ASSERT(ifp->if_broot_bytes <= 2939 ASSERT(ifp->if_broot_bytes <=
2881 (XFS_IFORK_SIZE(ip, whichfork) + 2940 (XFS_IFORK_SIZE(ip, whichfork) +
2882 XFS_BROOT_SIZE_ADJ)); 2941 XFS_BROOT_SIZE_ADJ));
2883 xfs_bmbt_to_bmdr(ifp->if_broot, ifp->if_broot_bytes, 2942 xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes,
2884 (xfs_bmdr_block_t *)cp, 2943 (xfs_bmdr_block_t *)cp,
2885 XFS_DFORK_SIZE(dip, mp, whichfork)); 2944 XFS_DFORK_SIZE(dip, mp, whichfork));
2886 } 2945 }
@@ -3418,10 +3477,8 @@ xfs_iflush_int(
3418 iip->ili_format.ilf_fields = 0; 3477 iip->ili_format.ilf_fields = 0;
3419 iip->ili_logged = 1; 3478 iip->ili_logged = 1;
3420 3479
3421 ASSERT(sizeof(xfs_lsn_t) == 8); /* don't lock if it shrinks */ 3480 xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
3422 spin_lock(&mp->m_ail_lock); 3481 &iip->ili_item.li_lsn);
3423 iip->ili_flush_lsn = iip->ili_item.li_lsn;
3424 spin_unlock(&mp->m_ail_lock);
3425 3482
3426 /* 3483 /*
3427 * Attach the function xfs_iflush_done to the inode's 3484 * Attach the function xfs_iflush_done to the inode's
@@ -3459,41 +3516,6 @@ corrupt_out:
3459} 3516}
3460 3517
3461 3518
3462/*
3463 * Flush all inactive inodes in mp.
3464 */
3465void
3466xfs_iflush_all(
3467 xfs_mount_t *mp)
3468{
3469 xfs_inode_t *ip;
3470
3471 again:
3472 XFS_MOUNT_ILOCK(mp);
3473 ip = mp->m_inodes;
3474 if (ip == NULL)
3475 goto out;
3476
3477 do {
3478 /* Make sure we skip markers inserted by sync */
3479 if (ip->i_mount == NULL) {
3480 ip = ip->i_mnext;
3481 continue;
3482 }
3483
3484 if (!VFS_I(ip)) {
3485 XFS_MOUNT_IUNLOCK(mp);
3486 xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
3487 goto again;
3488 }
3489
3490 ASSERT(vn_count(VFS_I(ip)) == 0);
3491
3492 ip = ip->i_mnext;
3493 } while (ip != mp->m_inodes);
3494 out:
3495 XFS_MOUNT_IUNLOCK(mp);
3496}
3497 3519
3498#ifdef XFS_ILOCK_TRACE 3520#ifdef XFS_ILOCK_TRACE
3499ktrace_t *xfs_ilock_trace_buf; 3521ktrace_t *xfs_ilock_trace_buf;