aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-11 12:03:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-11 12:03:47 -0400
commit412dd3a6daf0cadce1b2d6a34fa3713f40255579 (patch)
treebb2518c00c9d56acc8d36f87ed9c3144d8cf8201 /fs/xfs
parent23d4ed53b7342bf5999b3ea227d9f69e75e5a625 (diff)
parent7691283d0561a350b7517be94818669fb5e3d910 (diff)
Merge tag 'xfs-for-linus-3.16-rc1' of git://oss.sgi.com/xfs/xfs
Pull xfs updates from Dave Chinner: "This update contains: - cleanup removing unused function args - rework of the filestreams allocator to use dentry cache parent lookups - new on-disk free inode btree and optimised inode allocator - various bug fixes - rework of internal attribute API - cleanup of superblock feature bit support to remove historic cruft - more fixes and minor cleanups - added a new directory/attribute geometry abstraction - yet more fixes and minor cleanups" * tag 'xfs-for-linus-3.16-rc1' of git://oss.sgi.com/xfs/xfs: (86 commits) xfs: fix xfs_da_args sparse warning in xfs_readdir xfs: Fix rounding in xfs_alloc_fix_len() xfs: tone down writepage/releasepage WARN_ONs xfs: small cleanup in xfs_lowbit64() xfs: kill xfs_buf_geterror() xfs: xfs_readsb needs to check for magic numbers xfs: block allocation work needs to be kswapd aware xfs: remove redundant geometry information from xfs_da_state xfs: replace attr LBSIZE with xfs_da_geometry xfs: pass xfs_da_args to xfs_attr_leaf_newentsize xfs: use xfs_da_geometry for block size in attr code xfs: remove mp->m_dir_geo from directory logging xfs: reduce direct usage of mp->m_dir_geo xfs: move node entry counts to xfs_da_geometry xfs: convert dir/attr btree threshold to xfs_da_geometry xfs: convert m_dirblksize to xfs_da_geometry xfs: convert m_dirblkfsbs to xfs_da_geometry xfs: convert directory segment limits to xfs_da_geometry xfs: convert directory db conversion to xfs_da_geometry xfs: convert directory dablk conversion to xfs_da_geometry ...
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_ag.h36
-rw-r--r--fs/xfs/xfs_alloc.c19
-rw-r--r--fs/xfs/xfs_alloc_btree.c1
-rw-r--r--fs/xfs/xfs_aops.c55
-rw-r--r--fs/xfs/xfs_attr.c343
-rw-r--r--fs/xfs/xfs_attr_leaf.c184
-rw-r--r--fs/xfs/xfs_attr_leaf.h3
-rw-r--r--fs/xfs/xfs_attr_list.c1
-rw-r--r--fs/xfs/xfs_attr_remote.c58
-rw-r--r--fs/xfs/xfs_bit.h7
-rw-r--r--fs/xfs/xfs_bmap.c211
-rw-r--r--fs/xfs/xfs_bmap.h4
-rw-r--r--fs/xfs/xfs_bmap_btree.c9
-rw-r--r--fs/xfs/xfs_bmap_btree.h2
-rw-r--r--fs/xfs/xfs_bmap_util.c18
-rw-r--r--fs/xfs/xfs_bmap_util.h13
-rw-r--r--fs/xfs/xfs_btree.c56
-rw-r--r--fs/xfs/xfs_btree.h5
-rw-r--r--fs/xfs/xfs_buf.c17
-rw-r--r--fs/xfs/xfs_buf.h9
-rw-r--r--fs/xfs/xfs_buf_item.c5
-rw-r--r--fs/xfs/xfs_da_btree.c114
-rw-r--r--fs/xfs/xfs_da_btree.h26
-rw-r--r--fs/xfs/xfs_da_format.c36
-rw-r--r--fs/xfs/xfs_da_format.h154
-rw-r--r--fs/xfs/xfs_dir2.c136
-rw-r--r--fs/xfs/xfs_dir2.h30
-rw-r--r--fs/xfs/xfs_dir2_block.c97
-rw-r--r--fs/xfs/xfs_dir2_data.c83
-rw-r--r--fs/xfs/xfs_dir2_leaf.c202
-rw-r--r--fs/xfs/xfs_dir2_node.c190
-rw-r--r--fs/xfs/xfs_dir2_priv.h142
-rw-r--r--fs/xfs/xfs_dir2_readdir.c155
-rw-r--r--fs/xfs/xfs_dir2_sf.c39
-rw-r--r--fs/xfs/xfs_dquot.c59
-rw-r--r--fs/xfs/xfs_dquot.h2
-rw-r--r--fs/xfs/xfs_dquot_buf.c5
-rw-r--r--fs/xfs/xfs_file.c2
-rw-r--r--fs/xfs/xfs_filestream.c684
-rw-r--r--fs/xfs/xfs_filestream.h34
-rw-r--r--fs/xfs/xfs_format.h14
-rw-r--r--fs/xfs/xfs_fs.h1
-rw-r--r--fs/xfs/xfs_fsops.c49
-rw-r--r--fs/xfs/xfs_ialloc.c704
-rw-r--r--fs/xfs/xfs_ialloc.h2
-rw-r--r--fs/xfs/xfs_ialloc_btree.c69
-rw-r--r--fs/xfs/xfs_ialloc_btree.h3
-rw-r--r--fs/xfs/xfs_icache.c12
-rw-r--r--fs/xfs/xfs_icache.h6
-rw-r--r--fs/xfs/xfs_inode.c178
-rw-r--r--fs/xfs/xfs_inode.h5
-rw-r--r--fs/xfs/xfs_inode_buf.c17
-rw-r--r--fs/xfs/xfs_inode_fork.c3
-rw-r--r--fs/xfs/xfs_inode_fork.h3
-rw-r--r--fs/xfs/xfs_inode_item.c32
-rw-r--r--fs/xfs/xfs_ioctl.c14
-rw-r--r--fs/xfs/xfs_ioctl32.c5
-rw-r--r--fs/xfs/xfs_iomap.c2
-rw-r--r--fs/xfs/xfs_iops.c20
-rw-r--r--fs/xfs/xfs_itable.c6
-rw-r--r--fs/xfs/xfs_log.c11
-rw-r--r--fs/xfs/xfs_log.h19
-rw-r--r--fs/xfs/xfs_log_cil.c57
-rw-r--r--fs/xfs/xfs_log_recover.c11
-rw-r--r--fs/xfs/xfs_log_rlimit.c2
-rw-r--r--fs/xfs/xfs_mount.c45
-rw-r--r--fs/xfs/xfs_mount.h12
-rw-r--r--fs/xfs/xfs_mru_cache.c151
-rw-r--r--fs/xfs/xfs_mru_cache.h31
-rw-r--r--fs/xfs/xfs_qm.c217
-rw-r--r--fs/xfs/xfs_qm_syscalls.c6
-rw-r--r--fs/xfs/xfs_quota_defs.h2
-rw-r--r--fs/xfs/xfs_quotaops.c29
-rw-r--r--fs/xfs/xfs_rtbitmap.c1
-rw-r--r--fs/xfs/xfs_sb.c12
-rw-r--r--fs/xfs/xfs_sb.h235
-rw-r--r--fs/xfs/xfs_shared.h2
-rw-r--r--fs/xfs/xfs_stats.c1
-rw-r--r--fs/xfs/xfs_stats.h18
-rw-r--r--fs/xfs/xfs_super.c22
-rw-r--r--fs/xfs/xfs_symlink.c3
-rw-r--r--fs/xfs/xfs_symlink_remote.c1
-rw-r--r--fs/xfs/xfs_trace.c1
-rw-r--r--fs/xfs/xfs_trace.h58
-rw-r--r--fs/xfs/xfs_trans.c2
-rw-r--r--fs/xfs/xfs_trans_ail.c5
-rw-r--r--fs/xfs/xfs_trans_priv.h3
-rw-r--r--fs/xfs/xfs_trans_resv.c56
-rw-r--r--fs/xfs/xfs_trans_space.h12
-rw-r--r--fs/xfs/xfs_types.h2
90 files changed, 2634 insertions, 2784 deletions
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 0fdd4109c624..6e247a99f5db 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -160,30 +160,38 @@ typedef struct xfs_agi {
160 * still being referenced. 160 * still being referenced.
161 */ 161 */
162 __be32 agi_unlinked[XFS_AGI_UNLINKED_BUCKETS]; 162 __be32 agi_unlinked[XFS_AGI_UNLINKED_BUCKETS];
163 163 /*
164 * This marks the end of logging region 1 and start of logging region 2.
165 */
164 uuid_t agi_uuid; /* uuid of filesystem */ 166 uuid_t agi_uuid; /* uuid of filesystem */
165 __be32 agi_crc; /* crc of agi sector */ 167 __be32 agi_crc; /* crc of agi sector */
166 __be32 agi_pad32; 168 __be32 agi_pad32;
167 __be64 agi_lsn; /* last write sequence */ 169 __be64 agi_lsn; /* last write sequence */
168 170
171 __be32 agi_free_root; /* root of the free inode btree */
172 __be32 agi_free_level;/* levels in free inode btree */
173
169 /* structure must be padded to 64 bit alignment */ 174 /* structure must be padded to 64 bit alignment */
170} xfs_agi_t; 175} xfs_agi_t;
171 176
172#define XFS_AGI_CRC_OFF offsetof(struct xfs_agi, agi_crc) 177#define XFS_AGI_CRC_OFF offsetof(struct xfs_agi, agi_crc)
173 178
174#define XFS_AGI_MAGICNUM 0x00000001 179#define XFS_AGI_MAGICNUM (1 << 0)
175#define XFS_AGI_VERSIONNUM 0x00000002 180#define XFS_AGI_VERSIONNUM (1 << 1)
176#define XFS_AGI_SEQNO 0x00000004 181#define XFS_AGI_SEQNO (1 << 2)
177#define XFS_AGI_LENGTH 0x00000008 182#define XFS_AGI_LENGTH (1 << 3)
178#define XFS_AGI_COUNT 0x00000010 183#define XFS_AGI_COUNT (1 << 4)
179#define XFS_AGI_ROOT 0x00000020 184#define XFS_AGI_ROOT (1 << 5)
180#define XFS_AGI_LEVEL 0x00000040 185#define XFS_AGI_LEVEL (1 << 6)
181#define XFS_AGI_FREECOUNT 0x00000080 186#define XFS_AGI_FREECOUNT (1 << 7)
182#define XFS_AGI_NEWINO 0x00000100 187#define XFS_AGI_NEWINO (1 << 8)
183#define XFS_AGI_DIRINO 0x00000200 188#define XFS_AGI_DIRINO (1 << 9)
184#define XFS_AGI_UNLINKED 0x00000400 189#define XFS_AGI_UNLINKED (1 << 10)
185#define XFS_AGI_NUM_BITS 11 190#define XFS_AGI_NUM_BITS_R1 11 /* end of the 1st agi logging region */
186#define XFS_AGI_ALL_BITS ((1 << XFS_AGI_NUM_BITS) - 1) 191#define XFS_AGI_ALL_BITS_R1 ((1 << XFS_AGI_NUM_BITS_R1) - 1)
192#define XFS_AGI_FREE_ROOT (1 << 11)
193#define XFS_AGI_FREE_LEVEL (1 << 12)
194#define XFS_AGI_NUM_BITS_R2 13
187 195
188/* disk block (xfs_daddr_t) in the AG */ 196/* disk block (xfs_daddr_t) in the AG */
189#define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log)) 197#define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log))
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index c1cf6a336a72..d43813267a80 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -257,16 +257,14 @@ xfs_alloc_fix_len(
257 k = rlen % args->prod; 257 k = rlen % args->prod;
258 if (k == args->mod) 258 if (k == args->mod)
259 return; 259 return;
260 if (k > args->mod) { 260 if (k > args->mod)
261 if ((int)(rlen = rlen - k - args->mod) < (int)args->minlen) 261 rlen = rlen - (k - args->mod);
262 return; 262 else
263 } else { 263 rlen = rlen - args->prod + (args->mod - k);
264 if ((int)(rlen = rlen - args->prod - (args->mod - k)) < 264 if ((int)rlen < (int)args->minlen)
265 (int)args->minlen) 265 return;
266 return; 266 ASSERT(rlen >= args->minlen && rlen <= args->maxlen);
267 } 267 ASSERT(rlen % args->prod == args->mod);
268 ASSERT(rlen >= args->minlen);
269 ASSERT(rlen <= args->maxlen);
270 args->len = rlen; 268 args->len = rlen;
271} 269}
272 270
@@ -541,7 +539,6 @@ xfs_alloc_read_agfl(
541 XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops); 539 XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops);
542 if (error) 540 if (error)
543 return error; 541 return error;
544 ASSERT(!xfs_buf_geterror(bp));
545 xfs_buf_set_ref(bp, XFS_AGFL_REF); 542 xfs_buf_set_ref(bp, XFS_AGFL_REF);
546 *bpp = bp; 543 *bpp = bp;
547 return 0; 544 return 0;
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index cc1eadcbb049..8358f1ded94d 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -70,7 +70,6 @@ xfs_allocbt_alloc_block(
70 struct xfs_btree_cur *cur, 70 struct xfs_btree_cur *cur,
71 union xfs_btree_ptr *start, 71 union xfs_btree_ptr *start,
72 union xfs_btree_ptr *new, 72 union xfs_btree_ptr *new,
73 int length,
74 int *stat) 73 int *stat)
75{ 74{
76 int error; 75 int error;
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 0479c32c5eb1..e32640eedea6 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -975,14 +975,39 @@ xfs_vm_writepage(
975 * Given that we do not allow direct reclaim to call us, we should 975 * Given that we do not allow direct reclaim to call us, we should
976 * never be called while in a filesystem transaction. 976 * never be called while in a filesystem transaction.
977 */ 977 */
978 if (WARN_ON(current->flags & PF_FSTRANS)) 978 if (WARN_ON_ONCE(current->flags & PF_FSTRANS))
979 goto redirty; 979 goto redirty;
980 980
981 /* Is this page beyond the end of the file? */ 981 /* Is this page beyond the end of the file? */
982 offset = i_size_read(inode); 982 offset = i_size_read(inode);
983 end_index = offset >> PAGE_CACHE_SHIFT; 983 end_index = offset >> PAGE_CACHE_SHIFT;
984 last_index = (offset - 1) >> PAGE_CACHE_SHIFT; 984 last_index = (offset - 1) >> PAGE_CACHE_SHIFT;
985 if (page->index >= end_index) { 985
986 /*
987 * The page index is less than the end_index, adjust the end_offset
988 * to the highest offset that this page should represent.
989 * -----------------------------------------------------
990 * | file mapping | <EOF> |
991 * -----------------------------------------------------
992 * | Page ... | Page N-2 | Page N-1 | Page N | |
993 * ^--------------------------------^----------|--------
994 * | desired writeback range | see else |
995 * ---------------------------------^------------------|
996 */
997 if (page->index < end_index)
998 end_offset = (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT;
999 else {
1000 /*
1001 * Check whether the page to write out is beyond or straddles
1002 * i_size or not.
1003 * -------------------------------------------------------
1004 * | file mapping | <EOF> |
1005 * -------------------------------------------------------
1006 * | Page ... | Page N-2 | Page N-1 | Page N | Beyond |
1007 * ^--------------------------------^-----------|---------
1008 * | | Straddles |
1009 * ---------------------------------^-----------|--------|
1010 */
986 unsigned offset_into_page = offset & (PAGE_CACHE_SIZE - 1); 1011 unsigned offset_into_page = offset & (PAGE_CACHE_SIZE - 1);
987 1012
988 /* 1013 /*
@@ -990,24 +1015,36 @@ xfs_vm_writepage(
990 * truncate operation that is in progress. We must redirty the 1015 * truncate operation that is in progress. We must redirty the
991 * page so that reclaim stops reclaiming it. Otherwise 1016 * page so that reclaim stops reclaiming it. Otherwise
992 * xfs_vm_releasepage() is called on it and gets confused. 1017 * xfs_vm_releasepage() is called on it and gets confused.
1018 *
1019 * Note that the end_index is unsigned long, it would overflow
1020 * if the given offset is greater than 16TB on 32-bit system
1021 * and if we do check the page is fully outside i_size or not
1022 * via "if (page->index >= end_index + 1)" as "end_index + 1"
1023 * will be evaluated to 0. Hence this page will be redirtied
1024 * and be written out repeatedly which would result in an
1025 * infinite loop, the user program that perform this operation
1026 * will hang. Instead, we can verify this situation by checking
1027 * if the page to write is totally beyond the i_size or if it's
1028 * offset is just equal to the EOF.
993 */ 1029 */
994 if (page->index >= end_index + 1 || offset_into_page == 0) 1030 if (page->index > end_index ||
1031 (page->index == end_index && offset_into_page == 0))
995 goto redirty; 1032 goto redirty;
996 1033
997 /* 1034 /*
998 * The page straddles i_size. It must be zeroed out on each 1035 * The page straddles i_size. It must be zeroed out on each
999 * and every writepage invocation because it may be mmapped. 1036 * and every writepage invocation because it may be mmapped.
1000 * "A file is mapped in multiples of the page size. For a file 1037 * "A file is mapped in multiples of the page size. For a file
1001 * that is not a multiple of the page size, the remaining 1038 * that is not a multiple of the page size, the remaining
1002 * memory is zeroed when mapped, and writes to that region are 1039 * memory is zeroed when mapped, and writes to that region are
1003 * not written out to the file." 1040 * not written out to the file."
1004 */ 1041 */
1005 zero_user_segment(page, offset_into_page, PAGE_CACHE_SIZE); 1042 zero_user_segment(page, offset_into_page, PAGE_CACHE_SIZE);
1043
1044 /* Adjust the end_offset to the end of file */
1045 end_offset = offset;
1006 } 1046 }
1007 1047
1008 end_offset = min_t(unsigned long long,
1009 (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,
1010 offset);
1011 len = 1 << inode->i_blkbits; 1048 len = 1 << inode->i_blkbits;
1012 1049
1013 bh = head = page_buffers(page); 1050 bh = head = page_buffers(page);
@@ -1188,9 +1225,9 @@ xfs_vm_releasepage(
1188 1225
1189 xfs_count_page_state(page, &delalloc, &unwritten); 1226 xfs_count_page_state(page, &delalloc, &unwritten);
1190 1227
1191 if (WARN_ON(delalloc)) 1228 if (WARN_ON_ONCE(delalloc))
1192 return 0; 1229 return 0;
1193 if (WARN_ON(unwritten)) 1230 if (WARN_ON_ONCE(unwritten))
1194 return 0; 1231 return 0;
1195 1232
1196 return try_to_free_buffers(page); 1233 return try_to_free_buffers(page);
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index abda1124a70f..bfe36fc2cdc2 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -77,17 +77,27 @@ STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
77 77
78 78
79STATIC int 79STATIC int
80xfs_attr_name_to_xname( 80xfs_attr_args_init(
81 struct xfs_name *xname, 81 struct xfs_da_args *args,
82 const unsigned char *aname) 82 struct xfs_inode *dp,
83 const unsigned char *name,
84 int flags)
83{ 85{
84 if (!aname) 86
87 if (!name)
85 return EINVAL; 88 return EINVAL;
86 xname->name = aname; 89
87 xname->len = strlen((char *)aname); 90 memset(args, 0, sizeof(*args));
88 if (xname->len >= MAXNAMELEN) 91 args->geo = dp->i_mount->m_attr_geo;
92 args->whichfork = XFS_ATTR_FORK;
93 args->dp = dp;
94 args->flags = flags;
95 args->name = name;
96 args->namelen = strlen((const char *)name);
97 if (args->namelen >= MAXNAMELEN)
89 return EFAULT; /* match IRIX behaviour */ 98 return EFAULT; /* match IRIX behaviour */
90 99
100 args->hashval = xfs_da_hashname(args->name, args->namelen);
91 return 0; 101 return 0;
92} 102}
93 103
@@ -106,79 +116,46 @@ xfs_inode_hasattr(
106 * Overall external interface routines. 116 * Overall external interface routines.
107 *========================================================================*/ 117 *========================================================================*/
108 118
109STATIC int 119int
110xfs_attr_get_int( 120xfs_attr_get(
111 struct xfs_inode *ip, 121 struct xfs_inode *ip,
112 struct xfs_name *name, 122 const unsigned char *name,
113 unsigned char *value, 123 unsigned char *value,
114 int *valuelenp, 124 int *valuelenp,
115 int flags) 125 int flags)
116{ 126{
117 xfs_da_args_t args; 127 struct xfs_da_args args;
118 int error; 128 uint lock_mode;
129 int error;
130
131 XFS_STATS_INC(xs_attr_get);
132
133 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
134 return EIO;
119 135
120 if (!xfs_inode_hasattr(ip)) 136 if (!xfs_inode_hasattr(ip))
121 return ENOATTR; 137 return ENOATTR;
122 138
123 /* 139 error = xfs_attr_args_init(&args, ip, name, flags);
124 * Fill in the arg structure for this request. 140 if (error)
125 */ 141 return error;
126 memset((char *)&args, 0, sizeof(args)); 142
127 args.name = name->name;
128 args.namelen = name->len;
129 args.value = value; 143 args.value = value;
130 args.valuelen = *valuelenp; 144 args.valuelen = *valuelenp;
131 args.flags = flags;
132 args.hashval = xfs_da_hashname(args.name, args.namelen);
133 args.dp = ip;
134 args.whichfork = XFS_ATTR_FORK;
135 145
136 /* 146 lock_mode = xfs_ilock_attr_map_shared(ip);
137 * Decide on what work routines to call based on the inode size. 147 if (!xfs_inode_hasattr(ip))
138 */ 148 error = ENOATTR;
139 if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { 149 else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
140 error = xfs_attr_shortform_getvalue(&args); 150 error = xfs_attr_shortform_getvalue(&args);
141 } else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK)) { 151 else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK))
142 error = xfs_attr_leaf_get(&args); 152 error = xfs_attr_leaf_get(&args);
143 } else { 153 else
144 error = xfs_attr_node_get(&args); 154 error = xfs_attr_node_get(&args);
145 } 155 xfs_iunlock(ip, lock_mode);
146 156
147 /*
148 * Return the number of bytes in the value to the caller.
149 */
150 *valuelenp = args.valuelen; 157 *valuelenp = args.valuelen;
151 158 return error == EEXIST ? 0 : error;
152 if (error == EEXIST)
153 error = 0;
154 return(error);
155}
156
157int
158xfs_attr_get(
159 xfs_inode_t *ip,
160 const unsigned char *name,
161 unsigned char *value,
162 int *valuelenp,
163 int flags)
164{
165 int error;
166 struct xfs_name xname;
167 uint lock_mode;
168
169 XFS_STATS_INC(xs_attr_get);
170
171 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
172 return(EIO);
173
174 error = xfs_attr_name_to_xname(&xname, name);
175 if (error)
176 return error;
177
178 lock_mode = xfs_ilock_attr_map_shared(ip);
179 error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags);
180 xfs_iunlock(ip, lock_mode);
181 return(error);
182} 159}
183 160
184/* 161/*
@@ -186,12 +163,10 @@ xfs_attr_get(
186 */ 163 */
187STATIC int 164STATIC int
188xfs_attr_calc_size( 165xfs_attr_calc_size(
189 struct xfs_inode *ip, 166 struct xfs_da_args *args,
190 int namelen,
191 int valuelen,
192 int *local) 167 int *local)
193{ 168{
194 struct xfs_mount *mp = ip->i_mount; 169 struct xfs_mount *mp = args->dp->i_mount;
195 int size; 170 int size;
196 int nblks; 171 int nblks;
197 172
@@ -199,12 +174,10 @@ xfs_attr_calc_size(
199 * Determine space new attribute will use, and if it would be 174 * Determine space new attribute will use, and if it would be
200 * "local" or "remote" (note: local != inline). 175 * "local" or "remote" (note: local != inline).
201 */ 176 */
202 size = xfs_attr_leaf_newentsize(namelen, valuelen, 177 size = xfs_attr_leaf_newentsize(args, local);
203 mp->m_sb.sb_blocksize, local);
204
205 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); 178 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
206 if (*local) { 179 if (*local) {
207 if (size > (mp->m_sb.sb_blocksize >> 1)) { 180 if (size > (args->geo->blksize / 2)) {
208 /* Double split possible */ 181 /* Double split possible */
209 nblks *= 2; 182 nblks *= 2;
210 } 183 }
@@ -213,7 +186,7 @@ xfs_attr_calc_size(
213 * Out of line attribute, cannot double split, but 186 * Out of line attribute, cannot double split, but
214 * make room for the attribute value itself. 187 * make room for the attribute value itself.
215 */ 188 */
216 uint dblocks = xfs_attr3_rmt_blocks(mp, valuelen); 189 uint dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
217 nblks += dblocks; 190 nblks += dblocks;
218 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); 191 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
219 } 192 }
@@ -221,26 +194,38 @@ xfs_attr_calc_size(
221 return nblks; 194 return nblks;
222} 195}
223 196
224STATIC int 197int
225xfs_attr_set_int( 198xfs_attr_set(
226 struct xfs_inode *dp, 199 struct xfs_inode *dp,
227 struct xfs_name *name, 200 const unsigned char *name,
228 unsigned char *value, 201 unsigned char *value,
229 int valuelen, 202 int valuelen,
230 int flags) 203 int flags)
231{ 204{
232 xfs_da_args_t args;
233 xfs_fsblock_t firstblock;
234 xfs_bmap_free_t flist;
235 int error, err2, committed;
236 struct xfs_mount *mp = dp->i_mount; 205 struct xfs_mount *mp = dp->i_mount;
206 struct xfs_da_args args;
207 struct xfs_bmap_free flist;
237 struct xfs_trans_res tres; 208 struct xfs_trans_res tres;
209 xfs_fsblock_t firstblock;
238 int rsvd = (flags & ATTR_ROOT) != 0; 210 int rsvd = (flags & ATTR_ROOT) != 0;
239 int local; 211 int error, err2, committed, local;
212
213 XFS_STATS_INC(xs_attr_set);
214
215 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
216 return EIO;
217
218 error = xfs_attr_args_init(&args, dp, name, flags);
219 if (error)
220 return error;
221
222 args.value = value;
223 args.valuelen = valuelen;
224 args.firstblock = &firstblock;
225 args.flist = &flist;
226 args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
227 args.total = xfs_attr_calc_size(&args, &local);
240 228
241 /*
242 * Attach the dquots to the inode.
243 */
244 error = xfs_qm_dqattach(dp, 0); 229 error = xfs_qm_dqattach(dp, 0);
245 if (error) 230 if (error)
246 return error; 231 return error;
@@ -251,32 +236,14 @@ xfs_attr_set_int(
251 */ 236 */
252 if (XFS_IFORK_Q(dp) == 0) { 237 if (XFS_IFORK_Q(dp) == 0) {
253 int sf_size = sizeof(xfs_attr_sf_hdr_t) + 238 int sf_size = sizeof(xfs_attr_sf_hdr_t) +
254 XFS_ATTR_SF_ENTSIZE_BYNAME(name->len, valuelen); 239 XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen, valuelen);
255 240
256 if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd))) 241 error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
257 return(error); 242 if (error)
243 return error;
258 } 244 }
259 245
260 /* 246 /*
261 * Fill in the arg structure for this request.
262 */
263 memset((char *)&args, 0, sizeof(args));
264 args.name = name->name;
265 args.namelen = name->len;
266 args.value = value;
267 args.valuelen = valuelen;
268 args.flags = flags;
269 args.hashval = xfs_da_hashname(args.name, args.namelen);
270 args.dp = dp;
271 args.firstblock = &firstblock;
272 args.flist = &flist;
273 args.whichfork = XFS_ATTR_FORK;
274 args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
275
276 /* Size is now blocks for attribute data */
277 args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local);
278
279 /*
280 * Start our first transaction of the day. 247 * Start our first transaction of the day.
281 * 248 *
282 * All future transactions during this code must be "chained" off 249 * All future transactions during this code must be "chained" off
@@ -303,7 +270,7 @@ xfs_attr_set_int(
303 error = xfs_trans_reserve(args.trans, &tres, args.total, 0); 270 error = xfs_trans_reserve(args.trans, &tres, args.total, 0);
304 if (error) { 271 if (error) {
305 xfs_trans_cancel(args.trans, 0); 272 xfs_trans_cancel(args.trans, 0);
306 return(error); 273 return error;
307 } 274 }
308 xfs_ilock(dp, XFS_ILOCK_EXCL); 275 xfs_ilock(dp, XFS_ILOCK_EXCL);
309 276
@@ -313,7 +280,7 @@ xfs_attr_set_int(
313 if (error) { 280 if (error) {
314 xfs_iunlock(dp, XFS_ILOCK_EXCL); 281 xfs_iunlock(dp, XFS_ILOCK_EXCL);
315 xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); 282 xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES);
316 return (error); 283 return error;
317 } 284 }
318 285
319 xfs_trans_ijoin(args.trans, dp, 0); 286 xfs_trans_ijoin(args.trans, dp, 0);
@@ -322,9 +289,9 @@ xfs_attr_set_int(
322 * If the attribute list is non-existent or a shortform list, 289 * If the attribute list is non-existent or a shortform list,
323 * upgrade it to a single-leaf-block attribute list. 290 * upgrade it to a single-leaf-block attribute list.
324 */ 291 */
325 if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) || 292 if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL ||
326 ((dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) && 293 (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
327 (dp->i_d.di_anextents == 0))) { 294 dp->i_d.di_anextents == 0)) {
328 295
329 /* 296 /*
330 * Build initial attribute list (if required). 297 * Build initial attribute list (if required).
@@ -349,9 +316,8 @@ xfs_attr_set_int(
349 * the transaction goes to disk before returning 316 * the transaction goes to disk before returning
350 * to the user. 317 * to the user.
351 */ 318 */
352 if (mp->m_flags & XFS_MOUNT_WSYNC) { 319 if (mp->m_flags & XFS_MOUNT_WSYNC)
353 xfs_trans_set_sync(args.trans); 320 xfs_trans_set_sync(args.trans);
354 }
355 321
356 if (!error && (flags & ATTR_KERNOTIME) == 0) { 322 if (!error && (flags & ATTR_KERNOTIME) == 0) {
357 xfs_trans_ichgtime(args.trans, dp, 323 xfs_trans_ichgtime(args.trans, dp,
@@ -361,7 +327,7 @@ xfs_attr_set_int(
361 XFS_TRANS_RELEASE_LOG_RES); 327 XFS_TRANS_RELEASE_LOG_RES);
362 xfs_iunlock(dp, XFS_ILOCK_EXCL); 328 xfs_iunlock(dp, XFS_ILOCK_EXCL);
363 329
364 return(error == 0 ? err2 : error); 330 return error ? error : err2;
365 } 331 }
366 332
367 /* 333 /*
@@ -399,22 +365,19 @@ xfs_attr_set_int(
399 365
400 } 366 }
401 367
402 if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { 368 if (xfs_bmap_one_block(dp, XFS_ATTR_FORK))
403 error = xfs_attr_leaf_addname(&args); 369 error = xfs_attr_leaf_addname(&args);
404 } else { 370 else
405 error = xfs_attr_node_addname(&args); 371 error = xfs_attr_node_addname(&args);
406 } 372 if (error)
407 if (error) {
408 goto out; 373 goto out;
409 }
410 374
411 /* 375 /*
412 * If this is a synchronous mount, make sure that the 376 * If this is a synchronous mount, make sure that the
413 * transaction goes to disk before returning to the user. 377 * transaction goes to disk before returning to the user.
414 */ 378 */
415 if (mp->m_flags & XFS_MOUNT_WSYNC) { 379 if (mp->m_flags & XFS_MOUNT_WSYNC)
416 xfs_trans_set_sync(args.trans); 380 xfs_trans_set_sync(args.trans);
417 }
418 381
419 if ((flags & ATTR_KERNOTIME) == 0) 382 if ((flags & ATTR_KERNOTIME) == 0)
420 xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG); 383 xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
@@ -426,65 +389,47 @@ xfs_attr_set_int(
426 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); 389 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
427 xfs_iunlock(dp, XFS_ILOCK_EXCL); 390 xfs_iunlock(dp, XFS_ILOCK_EXCL);
428 391
429 return(error); 392 return error;
430 393
431out: 394out:
432 if (args.trans) 395 if (args.trans) {
433 xfs_trans_cancel(args.trans, 396 xfs_trans_cancel(args.trans,
434 XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 397 XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
398 }
435 xfs_iunlock(dp, XFS_ILOCK_EXCL); 399 xfs_iunlock(dp, XFS_ILOCK_EXCL);
436 return(error); 400 return error;
437} 401}
438 402
403/*
404 * Generic handler routine to remove a name from an attribute list.
405 * Transitions attribute list from Btree to shortform as necessary.
406 */
439int 407int
440xfs_attr_set( 408xfs_attr_remove(
441 xfs_inode_t *dp, 409 struct xfs_inode *dp,
442 const unsigned char *name, 410 const unsigned char *name,
443 unsigned char *value, 411 int flags)
444 int valuelen,
445 int flags)
446{ 412{
447 int error; 413 struct xfs_mount *mp = dp->i_mount;
448 struct xfs_name xname; 414 struct xfs_da_args args;
415 struct xfs_bmap_free flist;
416 xfs_fsblock_t firstblock;
417 int error;
449 418
450 XFS_STATS_INC(xs_attr_set); 419 XFS_STATS_INC(xs_attr_remove);
451 420
452 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 421 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
453 return (EIO); 422 return EIO;
423
424 if (!xfs_inode_hasattr(dp))
425 return ENOATTR;
454 426
455 error = xfs_attr_name_to_xname(&xname, name); 427 error = xfs_attr_args_init(&args, dp, name, flags);
456 if (error) 428 if (error)
457 return error; 429 return error;
458 430
459 return xfs_attr_set_int(dp, &xname, value, valuelen, flags);
460}
461
462/*
463 * Generic handler routine to remove a name from an attribute list.
464 * Transitions attribute list from Btree to shortform as necessary.
465 */
466STATIC int
467xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
468{
469 xfs_da_args_t args;
470 xfs_fsblock_t firstblock;
471 xfs_bmap_free_t flist;
472 int error;
473 xfs_mount_t *mp = dp->i_mount;
474
475 /*
476 * Fill in the arg structure for this request.
477 */
478 memset((char *)&args, 0, sizeof(args));
479 args.name = name->name;
480 args.namelen = name->len;
481 args.flags = flags;
482 args.hashval = xfs_da_hashname(args.name, args.namelen);
483 args.dp = dp;
484 args.firstblock = &firstblock; 431 args.firstblock = &firstblock;
485 args.flist = &flist; 432 args.flist = &flist;
486 args.total = 0;
487 args.whichfork = XFS_ATTR_FORK;
488 433
489 /* 434 /*
490 * we have no control over the attribute names that userspace passes us 435 * we have no control over the attribute names that userspace passes us
@@ -493,9 +438,6 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
493 */ 438 */
494 args.op_flags = XFS_DA_OP_OKNOENT; 439 args.op_flags = XFS_DA_OP_OKNOENT;
495 440
496 /*
497 * Attach the dquots to the inode.
498 */
499 error = xfs_qm_dqattach(dp, 0); 441 error = xfs_qm_dqattach(dp, 0);
500 if (error) 442 if (error)
501 return error; 443 return error;
@@ -524,7 +466,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
524 XFS_ATTRRM_SPACE_RES(mp), 0); 466 XFS_ATTRRM_SPACE_RES(mp), 0);
525 if (error) { 467 if (error) {
526 xfs_trans_cancel(args.trans, 0); 468 xfs_trans_cancel(args.trans, 0);
527 return(error); 469 return error;
528 } 470 }
529 471
530 xfs_ilock(dp, XFS_ILOCK_EXCL); 472 xfs_ilock(dp, XFS_ILOCK_EXCL);
@@ -534,35 +476,26 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
534 */ 476 */
535 xfs_trans_ijoin(args.trans, dp, 0); 477 xfs_trans_ijoin(args.trans, dp, 0);
536 478
537 /*
538 * Decide on what work routines to call based on the inode size.
539 */
540 if (!xfs_inode_hasattr(dp)) { 479 if (!xfs_inode_hasattr(dp)) {
541 error = XFS_ERROR(ENOATTR); 480 error = XFS_ERROR(ENOATTR);
542 goto out; 481 } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
543 }
544 if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
545 ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); 482 ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
546 error = xfs_attr_shortform_remove(&args); 483 error = xfs_attr_shortform_remove(&args);
547 if (error) {
548 goto out;
549 }
550 } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { 484 } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
551 error = xfs_attr_leaf_removename(&args); 485 error = xfs_attr_leaf_removename(&args);
552 } else { 486 } else {
553 error = xfs_attr_node_removename(&args); 487 error = xfs_attr_node_removename(&args);
554 } 488 }
555 if (error) { 489
490 if (error)
556 goto out; 491 goto out;
557 }
558 492
559 /* 493 /*
560 * If this is a synchronous mount, make sure that the 494 * If this is a synchronous mount, make sure that the
561 * transaction goes to disk before returning to the user. 495 * transaction goes to disk before returning to the user.
562 */ 496 */
563 if (mp->m_flags & XFS_MOUNT_WSYNC) { 497 if (mp->m_flags & XFS_MOUNT_WSYNC)
564 xfs_trans_set_sync(args.trans); 498 xfs_trans_set_sync(args.trans);
565 }
566 499
567 if ((flags & ATTR_KERNOTIME) == 0) 500 if ((flags & ATTR_KERNOTIME) == 0)
568 xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG); 501 xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
@@ -574,45 +507,17 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
574 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); 507 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
575 xfs_iunlock(dp, XFS_ILOCK_EXCL); 508 xfs_iunlock(dp, XFS_ILOCK_EXCL);
576 509
577 return(error); 510 return error;
578 511
579out: 512out:
580 if (args.trans) 513 if (args.trans) {
581 xfs_trans_cancel(args.trans, 514 xfs_trans_cancel(args.trans,
582 XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 515 XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
583 xfs_iunlock(dp, XFS_ILOCK_EXCL);
584 return(error);
585}
586
587int
588xfs_attr_remove(
589 xfs_inode_t *dp,
590 const unsigned char *name,
591 int flags)
592{
593 int error;
594 struct xfs_name xname;
595
596 XFS_STATS_INC(xs_attr_remove);
597
598 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
599 return (EIO);
600
601 error = xfs_attr_name_to_xname(&xname, name);
602 if (error)
603 return error;
604
605 xfs_ilock(dp, XFS_ILOCK_SHARED);
606 if (!xfs_inode_hasattr(dp)) {
607 xfs_iunlock(dp, XFS_ILOCK_SHARED);
608 return XFS_ERROR(ENOATTR);
609 } 516 }
610 xfs_iunlock(dp, XFS_ILOCK_SHARED); 517 xfs_iunlock(dp, XFS_ILOCK_EXCL);
611 518 return error;
612 return xfs_attr_remove_int(dp, &xname, flags);
613} 519}
614 520
615
616/*======================================================================== 521/*========================================================================
617 * External routines when attribute list is inside the inode 522 * External routines when attribute list is inside the inode
618 *========================================================================*/ 523 *========================================================================*/
@@ -958,7 +863,7 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
958} 863}
959 864
960/*======================================================================== 865/*========================================================================
961 * External routines when attribute list size > XFS_LBSIZE(mp). 866 * External routines when attribute list size > geo->blksize
962 *========================================================================*/ 867 *========================================================================*/
963 868
964/* 869/*
@@ -991,8 +896,6 @@ restart:
991 state = xfs_da_state_alloc(); 896 state = xfs_da_state_alloc();
992 state->args = args; 897 state->args = args;
993 state->mp = mp; 898 state->mp = mp;
994 state->blocksize = state->mp->m_sb.sb_blocksize;
995 state->node_ents = state->mp->m_attr_node_ents;
996 899
997 /* 900 /*
998 * Search to see if name already exists, and get back a pointer 901 * Search to see if name already exists, and get back a pointer
@@ -1170,8 +1073,6 @@ restart:
1170 state = xfs_da_state_alloc(); 1073 state = xfs_da_state_alloc();
1171 state->args = args; 1074 state->args = args;
1172 state->mp = mp; 1075 state->mp = mp;
1173 state->blocksize = state->mp->m_sb.sb_blocksize;
1174 state->node_ents = state->mp->m_attr_node_ents;
1175 state->inleaf = 0; 1076 state->inleaf = 0;
1176 error = xfs_da3_node_lookup_int(state, &retval); 1077 error = xfs_da3_node_lookup_int(state, &retval);
1177 if (error) 1078 if (error)
@@ -1262,8 +1163,6 @@ xfs_attr_node_removename(xfs_da_args_t *args)
1262 state = xfs_da_state_alloc(); 1163 state = xfs_da_state_alloc();
1263 state->args = args; 1164 state->args = args;
1264 state->mp = dp->i_mount; 1165 state->mp = dp->i_mount;
1265 state->blocksize = state->mp->m_sb.sb_blocksize;
1266 state->node_ents = state->mp->m_attr_node_ents;
1267 1166
1268 /* 1167 /*
1269 * Search to see if name exists, and get back a pointer to it. 1168 * Search to see if name exists, and get back a pointer to it.
@@ -1525,8 +1424,6 @@ xfs_attr_node_get(xfs_da_args_t *args)
1525 state = xfs_da_state_alloc(); 1424 state = xfs_da_state_alloc();
1526 state->args = args; 1425 state->args = args;
1527 state->mp = args->dp->i_mount; 1426 state->mp = args->dp->i_mount;
1528 state->blocksize = state->mp->m_sb.sb_blocksize;
1529 state->node_ents = state->mp->m_attr_node_ents;
1530 1427
1531 /* 1428 /*
1532 * Search to see if name exists, and get back a pointer to it. 1429 * Search to see if name exists, and get back a pointer to it.
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 511c283459b1..28712d29e43c 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -80,11 +80,12 @@ STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state,
80/* 80/*
81 * Utility routines. 81 * Utility routines.
82 */ 82 */
83STATIC void xfs_attr3_leaf_moveents(struct xfs_attr_leafblock *src_leaf, 83STATIC void xfs_attr3_leaf_moveents(struct xfs_da_args *args,
84 struct xfs_attr_leafblock *src_leaf,
84 struct xfs_attr3_icleaf_hdr *src_ichdr, int src_start, 85 struct xfs_attr3_icleaf_hdr *src_ichdr, int src_start,
85 struct xfs_attr_leafblock *dst_leaf, 86 struct xfs_attr_leafblock *dst_leaf,
86 struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start, 87 struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start,
87 int move_count, struct xfs_mount *mp); 88 int move_count);
88STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); 89STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
89 90
90void 91void
@@ -711,6 +712,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
711 712
712 memset((char *)&nargs, 0, sizeof(nargs)); 713 memset((char *)&nargs, 0, sizeof(nargs));
713 nargs.dp = dp; 714 nargs.dp = dp;
715 nargs.geo = args->geo;
714 nargs.firstblock = args->firstblock; 716 nargs.firstblock = args->firstblock;
715 nargs.flist = args->flist; 717 nargs.flist = args->flist;
716 nargs.total = args->total; 718 nargs.total = args->total;
@@ -805,18 +807,18 @@ xfs_attr3_leaf_to_shortform(
805 807
806 trace_xfs_attr_leaf_to_sf(args); 808 trace_xfs_attr_leaf_to_sf(args);
807 809
808 tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); 810 tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP);
809 if (!tmpbuffer) 811 if (!tmpbuffer)
810 return ENOMEM; 812 return ENOMEM;
811 813
812 memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(dp->i_mount)); 814 memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
813 815
814 leaf = (xfs_attr_leafblock_t *)tmpbuffer; 816 leaf = (xfs_attr_leafblock_t *)tmpbuffer;
815 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); 817 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
816 entry = xfs_attr3_leaf_entryp(leaf); 818 entry = xfs_attr3_leaf_entryp(leaf);
817 819
818 /* XXX (dgc): buffer is about to be marked stale - why zero it? */ 820 /* XXX (dgc): buffer is about to be marked stale - why zero it? */
819 memset(bp->b_addr, 0, XFS_LBSIZE(dp->i_mount)); 821 memset(bp->b_addr, 0, args->geo->blksize);
820 822
821 /* 823 /*
822 * Clean out the prior contents of the attribute list. 824 * Clean out the prior contents of the attribute list.
@@ -838,6 +840,7 @@ xfs_attr3_leaf_to_shortform(
838 * Copy the attributes 840 * Copy the attributes
839 */ 841 */
840 memset((char *)&nargs, 0, sizeof(nargs)); 842 memset((char *)&nargs, 0, sizeof(nargs));
843 nargs.geo = args->geo;
841 nargs.dp = dp; 844 nargs.dp = dp;
842 nargs.firstblock = args->firstblock; 845 nargs.firstblock = args->firstblock;
843 nargs.flist = args->flist; 846 nargs.flist = args->flist;
@@ -904,12 +907,12 @@ xfs_attr3_leaf_to_node(
904 /* copy leaf to new buffer, update identifiers */ 907 /* copy leaf to new buffer, update identifiers */
905 xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF); 908 xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF);
906 bp2->b_ops = bp1->b_ops; 909 bp2->b_ops = bp1->b_ops;
907 memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(mp)); 910 memcpy(bp2->b_addr, bp1->b_addr, args->geo->blksize);
908 if (xfs_sb_version_hascrc(&mp->m_sb)) { 911 if (xfs_sb_version_hascrc(&mp->m_sb)) {
909 struct xfs_da3_blkinfo *hdr3 = bp2->b_addr; 912 struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
910 hdr3->blkno = cpu_to_be64(bp2->b_bn); 913 hdr3->blkno = cpu_to_be64(bp2->b_bn);
911 } 914 }
912 xfs_trans_log_buf(args->trans, bp2, 0, XFS_LBSIZE(mp) - 1); 915 xfs_trans_log_buf(args->trans, bp2, 0, args->geo->blksize - 1);
913 916
914 /* 917 /*
915 * Set up the new root node. 918 * Set up the new root node.
@@ -930,7 +933,7 @@ xfs_attr3_leaf_to_node(
930 btree[0].before = cpu_to_be32(blkno); 933 btree[0].before = cpu_to_be32(blkno);
931 icnodehdr.count = 1; 934 icnodehdr.count = 1;
932 dp->d_ops->node_hdr_to_disk(node, &icnodehdr); 935 dp->d_ops->node_hdr_to_disk(node, &icnodehdr);
933 xfs_trans_log_buf(args->trans, bp1, 0, XFS_LBSIZE(mp) - 1); 936 xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
934 error = 0; 937 error = 0;
935out: 938out:
936 return error; 939 return error;
@@ -966,10 +969,10 @@ xfs_attr3_leaf_create(
966 bp->b_ops = &xfs_attr3_leaf_buf_ops; 969 bp->b_ops = &xfs_attr3_leaf_buf_ops;
967 xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF); 970 xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF);
968 leaf = bp->b_addr; 971 leaf = bp->b_addr;
969 memset(leaf, 0, XFS_LBSIZE(mp)); 972 memset(leaf, 0, args->geo->blksize);
970 973
971 memset(&ichdr, 0, sizeof(ichdr)); 974 memset(&ichdr, 0, sizeof(ichdr));
972 ichdr.firstused = XFS_LBSIZE(mp); 975 ichdr.firstused = args->geo->blksize;
973 976
974 if (xfs_sb_version_hascrc(&mp->m_sb)) { 977 if (xfs_sb_version_hascrc(&mp->m_sb)) {
975 struct xfs_da3_blkinfo *hdr3 = bp->b_addr; 978 struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
@@ -988,7 +991,7 @@ xfs_attr3_leaf_create(
988 ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; 991 ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base;
989 992
990 xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); 993 xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr);
991 xfs_trans_log_buf(args->trans, bp, 0, XFS_LBSIZE(mp) - 1); 994 xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1);
992 995
993 *bpp = bp; 996 *bpp = bp;
994 return 0; 997 return 0;
@@ -1074,8 +1077,7 @@ xfs_attr3_leaf_add(
1074 leaf = bp->b_addr; 1077 leaf = bp->b_addr;
1075 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); 1078 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
1076 ASSERT(args->index >= 0 && args->index <= ichdr.count); 1079 ASSERT(args->index >= 0 && args->index <= ichdr.count);
1077 entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, 1080 entsize = xfs_attr_leaf_newentsize(args, NULL);
1078 args->trans->t_mountp->m_sb.sb_blocksize, NULL);
1079 1081
1080 /* 1082 /*
1081 * Search through freemap for first-fit on new name length. 1083 * Search through freemap for first-fit on new name length.
@@ -1174,17 +1176,14 @@ xfs_attr3_leaf_add_work(
1174 * Allocate space for the new string (at the end of the run). 1176 * Allocate space for the new string (at the end of the run).
1175 */ 1177 */
1176 mp = args->trans->t_mountp; 1178 mp = args->trans->t_mountp;
1177 ASSERT(ichdr->freemap[mapindex].base < XFS_LBSIZE(mp)); 1179 ASSERT(ichdr->freemap[mapindex].base < args->geo->blksize);
1178 ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0); 1180 ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0);
1179 ASSERT(ichdr->freemap[mapindex].size >= 1181 ASSERT(ichdr->freemap[mapindex].size >=
1180 xfs_attr_leaf_newentsize(args->namelen, args->valuelen, 1182 xfs_attr_leaf_newentsize(args, NULL));
1181 mp->m_sb.sb_blocksize, NULL)); 1183 ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize);
1182 ASSERT(ichdr->freemap[mapindex].size < XFS_LBSIZE(mp));
1183 ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0); 1184 ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0);
1184 1185
1185 ichdr->freemap[mapindex].size -= 1186 ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp);
1186 xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
1187 mp->m_sb.sb_blocksize, &tmp);
1188 1187
1189 entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base + 1188 entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
1190 ichdr->freemap[mapindex].size); 1189 ichdr->freemap[mapindex].size);
@@ -1269,14 +1268,13 @@ xfs_attr3_leaf_compact(
1269 struct xfs_attr_leafblock *leaf_dst; 1268 struct xfs_attr_leafblock *leaf_dst;
1270 struct xfs_attr3_icleaf_hdr ichdr_src; 1269 struct xfs_attr3_icleaf_hdr ichdr_src;
1271 struct xfs_trans *trans = args->trans; 1270 struct xfs_trans *trans = args->trans;
1272 struct xfs_mount *mp = trans->t_mountp;
1273 char *tmpbuffer; 1271 char *tmpbuffer;
1274 1272
1275 trace_xfs_attr_leaf_compact(args); 1273 trace_xfs_attr_leaf_compact(args);
1276 1274
1277 tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); 1275 tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP);
1278 memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp)); 1276 memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
1279 memset(bp->b_addr, 0, XFS_LBSIZE(mp)); 1277 memset(bp->b_addr, 0, args->geo->blksize);
1280 leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; 1278 leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
1281 leaf_dst = bp->b_addr; 1279 leaf_dst = bp->b_addr;
1282 1280
@@ -1289,7 +1287,7 @@ xfs_attr3_leaf_compact(
1289 1287
1290 /* Initialise the incore headers */ 1288 /* Initialise the incore headers */
1291 ichdr_src = *ichdr_dst; /* struct copy */ 1289 ichdr_src = *ichdr_dst; /* struct copy */
1292 ichdr_dst->firstused = XFS_LBSIZE(mp); 1290 ichdr_dst->firstused = args->geo->blksize;
1293 ichdr_dst->usedbytes = 0; 1291 ichdr_dst->usedbytes = 0;
1294 ichdr_dst->count = 0; 1292 ichdr_dst->count = 0;
1295 ichdr_dst->holes = 0; 1293 ichdr_dst->holes = 0;
@@ -1304,13 +1302,13 @@ xfs_attr3_leaf_compact(
1304 * Copy all entry's in the same (sorted) order, 1302 * Copy all entry's in the same (sorted) order,
1305 * but allocate name/value pairs packed and in sequence. 1303 * but allocate name/value pairs packed and in sequence.
1306 */ 1304 */
1307 xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0, 1305 xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0,
1308 ichdr_src.count, mp); 1306 leaf_dst, ichdr_dst, 0, ichdr_src.count);
1309 /* 1307 /*
1310 * this logs the entire buffer, but the caller must write the header 1308 * this logs the entire buffer, but the caller must write the header
1311 * back to the buffer when it is finished modifying it. 1309 * back to the buffer when it is finished modifying it.
1312 */ 1310 */
1313 xfs_trans_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); 1311 xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
1314 1312
1315 kmem_free(tmpbuffer); 1313 kmem_free(tmpbuffer);
1316} 1314}
@@ -1461,8 +1459,8 @@ xfs_attr3_leaf_rebalance(
1461 /* 1459 /*
1462 * Move high entries from leaf1 to low end of leaf2. 1460 * Move high entries from leaf1 to low end of leaf2.
1463 */ 1461 */
1464 xfs_attr3_leaf_moveents(leaf1, &ichdr1, ichdr1.count - count, 1462 xfs_attr3_leaf_moveents(args, leaf1, &ichdr1,
1465 leaf2, &ichdr2, 0, count, state->mp); 1463 ichdr1.count - count, leaf2, &ichdr2, 0, count);
1466 1464
1467 } else if (count > ichdr1.count) { 1465 } else if (count > ichdr1.count) {
1468 /* 1466 /*
@@ -1490,14 +1488,14 @@ xfs_attr3_leaf_rebalance(
1490 /* 1488 /*
1491 * Move low entries from leaf2 to high end of leaf1. 1489 * Move low entries from leaf2 to high end of leaf1.
1492 */ 1490 */
1493 xfs_attr3_leaf_moveents(leaf2, &ichdr2, 0, leaf1, &ichdr1, 1491 xfs_attr3_leaf_moveents(args, leaf2, &ichdr2, 0, leaf1, &ichdr1,
1494 ichdr1.count, count, state->mp); 1492 ichdr1.count, count);
1495 } 1493 }
1496 1494
1497 xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1); 1495 xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1);
1498 xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2); 1496 xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2);
1499 xfs_trans_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); 1497 xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1);
1500 xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); 1498 xfs_trans_log_buf(args->trans, blk2->bp, 0, args->geo->blksize - 1);
1501 1499
1502 /* 1500 /*
1503 * Copy out last hashval in each block for B-tree code. 1501 * Copy out last hashval in each block for B-tree code.
@@ -1592,11 +1590,9 @@ xfs_attr3_leaf_figure_balance(
1592 max = ichdr1->count + ichdr2->count; 1590 max = ichdr1->count + ichdr2->count;
1593 half = (max + 1) * sizeof(*entry); 1591 half = (max + 1) * sizeof(*entry);
1594 half += ichdr1->usedbytes + ichdr2->usedbytes + 1592 half += ichdr1->usedbytes + ichdr2->usedbytes +
1595 xfs_attr_leaf_newentsize(state->args->namelen, 1593 xfs_attr_leaf_newentsize(state->args, NULL);
1596 state->args->valuelen,
1597 state->blocksize, NULL);
1598 half /= 2; 1594 half /= 2;
1599 lastdelta = state->blocksize; 1595 lastdelta = state->args->geo->blksize;
1600 entry = xfs_attr3_leaf_entryp(leaf1); 1596 entry = xfs_attr3_leaf_entryp(leaf1);
1601 for (count = index = 0; count < max; entry++, index++, count++) { 1597 for (count = index = 0; count < max; entry++, index++, count++) {
1602 1598
@@ -1606,10 +1602,7 @@ xfs_attr3_leaf_figure_balance(
1606 */ 1602 */
1607 if (count == blk1->index) { 1603 if (count == blk1->index) {
1608 tmp = totallen + sizeof(*entry) + 1604 tmp = totallen + sizeof(*entry) +
1609 xfs_attr_leaf_newentsize( 1605 xfs_attr_leaf_newentsize(state->args, NULL);
1610 state->args->namelen,
1611 state->args->valuelen,
1612 state->blocksize, NULL);
1613 if (XFS_ATTR_ABS(half - tmp) > lastdelta) 1606 if (XFS_ATTR_ABS(half - tmp) > lastdelta)
1614 break; 1607 break;
1615 lastdelta = XFS_ATTR_ABS(half - tmp); 1608 lastdelta = XFS_ATTR_ABS(half - tmp);
@@ -1645,10 +1638,7 @@ xfs_attr3_leaf_figure_balance(
1645 totallen -= count * sizeof(*entry); 1638 totallen -= count * sizeof(*entry);
1646 if (foundit) { 1639 if (foundit) {
1647 totallen -= sizeof(*entry) + 1640 totallen -= sizeof(*entry) +
1648 xfs_attr_leaf_newentsize( 1641 xfs_attr_leaf_newentsize(state->args, NULL);
1649 state->args->namelen,
1650 state->args->valuelen,
1651 state->blocksize, NULL);
1652 } 1642 }
1653 1643
1654 *countarg = count; 1644 *countarg = count;
@@ -1700,7 +1690,7 @@ xfs_attr3_leaf_toosmall(
1700 bytes = xfs_attr3_leaf_hdr_size(leaf) + 1690 bytes = xfs_attr3_leaf_hdr_size(leaf) +
1701 ichdr.count * sizeof(xfs_attr_leaf_entry_t) + 1691 ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
1702 ichdr.usedbytes; 1692 ichdr.usedbytes;
1703 if (bytes > (state->blocksize >> 1)) { 1693 if (bytes > (state->args->geo->blksize >> 1)) {
1704 *action = 0; /* blk over 50%, don't try to join */ 1694 *action = 0; /* blk over 50%, don't try to join */
1705 return(0); 1695 return(0);
1706 } 1696 }
@@ -1754,7 +1744,8 @@ xfs_attr3_leaf_toosmall(
1754 1744
1755 xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr); 1745 xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr);
1756 1746
1757 bytes = state->blocksize - (state->blocksize >> 2) - 1747 bytes = state->args->geo->blksize -
1748 (state->args->geo->blksize >> 2) -
1758 ichdr.usedbytes - ichdr2.usedbytes - 1749 ichdr.usedbytes - ichdr2.usedbytes -
1759 ((ichdr.count + ichdr2.count) * 1750 ((ichdr.count + ichdr2.count) *
1760 sizeof(xfs_attr_leaf_entry_t)) - 1751 sizeof(xfs_attr_leaf_entry_t)) -
@@ -1805,7 +1796,6 @@ xfs_attr3_leaf_remove(
1805 struct xfs_attr_leafblock *leaf; 1796 struct xfs_attr_leafblock *leaf;
1806 struct xfs_attr3_icleaf_hdr ichdr; 1797 struct xfs_attr3_icleaf_hdr ichdr;
1807 struct xfs_attr_leaf_entry *entry; 1798 struct xfs_attr_leaf_entry *entry;
1808 struct xfs_mount *mp = args->trans->t_mountp;
1809 int before; 1799 int before;
1810 int after; 1800 int after;
1811 int smallest; 1801 int smallest;
@@ -1819,7 +1809,7 @@ xfs_attr3_leaf_remove(
1819 leaf = bp->b_addr; 1809 leaf = bp->b_addr;
1820 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); 1810 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
1821 1811
1822 ASSERT(ichdr.count > 0 && ichdr.count < XFS_LBSIZE(mp) / 8); 1812 ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8);
1823 ASSERT(args->index >= 0 && args->index < ichdr.count); 1813 ASSERT(args->index >= 0 && args->index < ichdr.count);
1824 ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) + 1814 ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
1825 xfs_attr3_leaf_hdr_size(leaf)); 1815 xfs_attr3_leaf_hdr_size(leaf));
@@ -1827,7 +1817,7 @@ xfs_attr3_leaf_remove(
1827 entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; 1817 entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
1828 1818
1829 ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); 1819 ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
1830 ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); 1820 ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
1831 1821
1832 /* 1822 /*
1833 * Scan through free region table: 1823 * Scan through free region table:
@@ -1842,8 +1832,8 @@ xfs_attr3_leaf_remove(
1842 smallest = XFS_ATTR_LEAF_MAPSIZE - 1; 1832 smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
1843 entsize = xfs_attr_leaf_entsize(leaf, args->index); 1833 entsize = xfs_attr_leaf_entsize(leaf, args->index);
1844 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { 1834 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
1845 ASSERT(ichdr.freemap[i].base < XFS_LBSIZE(mp)); 1835 ASSERT(ichdr.freemap[i].base < args->geo->blksize);
1846 ASSERT(ichdr.freemap[i].size < XFS_LBSIZE(mp)); 1836 ASSERT(ichdr.freemap[i].size < args->geo->blksize);
1847 if (ichdr.freemap[i].base == tablesize) { 1837 if (ichdr.freemap[i].base == tablesize) {
1848 ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t); 1838 ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t);
1849 ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t); 1839 ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t);
@@ -1920,11 +1910,11 @@ xfs_attr3_leaf_remove(
1920 * removing the name. 1910 * removing the name.
1921 */ 1911 */
1922 if (smallest) { 1912 if (smallest) {
1923 tmp = XFS_LBSIZE(mp); 1913 tmp = args->geo->blksize;
1924 entry = xfs_attr3_leaf_entryp(leaf); 1914 entry = xfs_attr3_leaf_entryp(leaf);
1925 for (i = ichdr.count - 1; i >= 0; entry++, i--) { 1915 for (i = ichdr.count - 1; i >= 0; entry++, i--) {
1926 ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); 1916 ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
1927 ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); 1917 ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
1928 1918
1929 if (be16_to_cpu(entry->nameidx) < tmp) 1919 if (be16_to_cpu(entry->nameidx) < tmp)
1930 tmp = be16_to_cpu(entry->nameidx); 1920 tmp = be16_to_cpu(entry->nameidx);
@@ -1947,7 +1937,7 @@ xfs_attr3_leaf_remove(
1947 tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) + 1937 tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
1948 ichdr.count * sizeof(xfs_attr_leaf_entry_t); 1938 ichdr.count * sizeof(xfs_attr_leaf_entry_t);
1949 1939
1950 return tmp < mp->m_attr_magicpct; /* leaf is < 37% full */ 1940 return tmp < args->geo->magicpct; /* leaf is < 37% full */
1951} 1941}
1952 1942
1953/* 1943/*
@@ -1964,7 +1954,6 @@ xfs_attr3_leaf_unbalance(
1964 struct xfs_attr3_icleaf_hdr drophdr; 1954 struct xfs_attr3_icleaf_hdr drophdr;
1965 struct xfs_attr3_icleaf_hdr savehdr; 1955 struct xfs_attr3_icleaf_hdr savehdr;
1966 struct xfs_attr_leaf_entry *entry; 1956 struct xfs_attr_leaf_entry *entry;
1967 struct xfs_mount *mp = state->mp;
1968 1957
1969 trace_xfs_attr_leaf_unbalance(state->args); 1958 trace_xfs_attr_leaf_unbalance(state->args);
1970 1959
@@ -1991,13 +1980,15 @@ xfs_attr3_leaf_unbalance(
1991 */ 1980 */
1992 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, 1981 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
1993 drop_blk->bp, &drophdr)) { 1982 drop_blk->bp, &drophdr)) {
1994 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, 1983 xfs_attr3_leaf_moveents(state->args,
1984 drop_leaf, &drophdr, 0,
1995 save_leaf, &savehdr, 0, 1985 save_leaf, &savehdr, 0,
1996 drophdr.count, mp); 1986 drophdr.count);
1997 } else { 1987 } else {
1998 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, 1988 xfs_attr3_leaf_moveents(state->args,
1989 drop_leaf, &drophdr, 0,
1999 save_leaf, &savehdr, 1990 save_leaf, &savehdr,
2000 savehdr.count, drophdr.count, mp); 1991 savehdr.count, drophdr.count);
2001 } 1992 }
2002 } else { 1993 } else {
2003 /* 1994 /*
@@ -2007,7 +1998,7 @@ xfs_attr3_leaf_unbalance(
2007 struct xfs_attr_leafblock *tmp_leaf; 1998 struct xfs_attr_leafblock *tmp_leaf;
2008 struct xfs_attr3_icleaf_hdr tmphdr; 1999 struct xfs_attr3_icleaf_hdr tmphdr;
2009 2000
2010 tmp_leaf = kmem_zalloc(state->blocksize, KM_SLEEP); 2001 tmp_leaf = kmem_zalloc(state->args->geo->blksize, KM_SLEEP);
2011 2002
2012 /* 2003 /*
2013 * Copy the header into the temp leaf so that all the stuff 2004 * Copy the header into the temp leaf so that all the stuff
@@ -2020,35 +2011,39 @@ xfs_attr3_leaf_unbalance(
2020 tmphdr.magic = savehdr.magic; 2011 tmphdr.magic = savehdr.magic;
2021 tmphdr.forw = savehdr.forw; 2012 tmphdr.forw = savehdr.forw;
2022 tmphdr.back = savehdr.back; 2013 tmphdr.back = savehdr.back;
2023 tmphdr.firstused = state->blocksize; 2014 tmphdr.firstused = state->args->geo->blksize;
2024 2015
2025 /* write the header to the temp buffer to initialise it */ 2016 /* write the header to the temp buffer to initialise it */
2026 xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); 2017 xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr);
2027 2018
2028 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, 2019 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
2029 drop_blk->bp, &drophdr)) { 2020 drop_blk->bp, &drophdr)) {
2030 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, 2021 xfs_attr3_leaf_moveents(state->args,
2022 drop_leaf, &drophdr, 0,
2031 tmp_leaf, &tmphdr, 0, 2023 tmp_leaf, &tmphdr, 0,
2032 drophdr.count, mp); 2024 drophdr.count);
2033 xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, 2025 xfs_attr3_leaf_moveents(state->args,
2026 save_leaf, &savehdr, 0,
2034 tmp_leaf, &tmphdr, tmphdr.count, 2027 tmp_leaf, &tmphdr, tmphdr.count,
2035 savehdr.count, mp); 2028 savehdr.count);
2036 } else { 2029 } else {
2037 xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, 2030 xfs_attr3_leaf_moveents(state->args,
2031 save_leaf, &savehdr, 0,
2038 tmp_leaf, &tmphdr, 0, 2032 tmp_leaf, &tmphdr, 0,
2039 savehdr.count, mp); 2033 savehdr.count);
2040 xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, 2034 xfs_attr3_leaf_moveents(state->args,
2035 drop_leaf, &drophdr, 0,
2041 tmp_leaf, &tmphdr, tmphdr.count, 2036 tmp_leaf, &tmphdr, tmphdr.count,
2042 drophdr.count, mp); 2037 drophdr.count);
2043 } 2038 }
2044 memcpy(save_leaf, tmp_leaf, state->blocksize); 2039 memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
2045 savehdr = tmphdr; /* struct copy */ 2040 savehdr = tmphdr; /* struct copy */
2046 kmem_free(tmp_leaf); 2041 kmem_free(tmp_leaf);
2047 } 2042 }
2048 2043
2049 xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr); 2044 xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr);
2050 xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, 2045 xfs_trans_log_buf(state->args->trans, save_blk->bp, 0,
2051 state->blocksize - 1); 2046 state->args->geo->blksize - 1);
2052 2047
2053 /* 2048 /*
2054 * Copy out last hashval in each block for B-tree code. 2049 * Copy out last hashval in each block for B-tree code.
@@ -2094,7 +2089,7 @@ xfs_attr3_leaf_lookup_int(
2094 leaf = bp->b_addr; 2089 leaf = bp->b_addr;
2095 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); 2090 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
2096 entries = xfs_attr3_leaf_entryp(leaf); 2091 entries = xfs_attr3_leaf_entryp(leaf);
2097 ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8); 2092 ASSERT(ichdr.count < args->geo->blksize / 8);
2098 2093
2099 /* 2094 /*
2100 * Binary search. (note: small blocks will skip this loop) 2095 * Binary search. (note: small blocks will skip this loop)
@@ -2198,7 +2193,7 @@ xfs_attr3_leaf_getvalue(
2198 2193
2199 leaf = bp->b_addr; 2194 leaf = bp->b_addr;
2200 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); 2195 xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
2201 ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8); 2196 ASSERT(ichdr.count < args->geo->blksize / 8);
2202 ASSERT(args->index < ichdr.count); 2197 ASSERT(args->index < ichdr.count);
2203 2198
2204 entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; 2199 entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
@@ -2249,14 +2244,14 @@ xfs_attr3_leaf_getvalue(
2249/*ARGSUSED*/ 2244/*ARGSUSED*/
2250STATIC void 2245STATIC void
2251xfs_attr3_leaf_moveents( 2246xfs_attr3_leaf_moveents(
2247 struct xfs_da_args *args,
2252 struct xfs_attr_leafblock *leaf_s, 2248 struct xfs_attr_leafblock *leaf_s,
2253 struct xfs_attr3_icleaf_hdr *ichdr_s, 2249 struct xfs_attr3_icleaf_hdr *ichdr_s,
2254 int start_s, 2250 int start_s,
2255 struct xfs_attr_leafblock *leaf_d, 2251 struct xfs_attr_leafblock *leaf_d,
2256 struct xfs_attr3_icleaf_hdr *ichdr_d, 2252 struct xfs_attr3_icleaf_hdr *ichdr_d,
2257 int start_d, 2253 int start_d,
2258 int count, 2254 int count)
2259 struct xfs_mount *mp)
2260{ 2255{
2261 struct xfs_attr_leaf_entry *entry_s; 2256 struct xfs_attr_leaf_entry *entry_s;
2262 struct xfs_attr_leaf_entry *entry_d; 2257 struct xfs_attr_leaf_entry *entry_d;
@@ -2276,10 +2271,10 @@ xfs_attr3_leaf_moveents(
2276 ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC || 2271 ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC ||
2277 ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC); 2272 ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
2278 ASSERT(ichdr_s->magic == ichdr_d->magic); 2273 ASSERT(ichdr_s->magic == ichdr_d->magic);
2279 ASSERT(ichdr_s->count > 0 && ichdr_s->count < XFS_LBSIZE(mp) / 8); 2274 ASSERT(ichdr_s->count > 0 && ichdr_s->count < args->geo->blksize / 8);
2280 ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s)) 2275 ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
2281 + xfs_attr3_leaf_hdr_size(leaf_s)); 2276 + xfs_attr3_leaf_hdr_size(leaf_s));
2282 ASSERT(ichdr_d->count < XFS_LBSIZE(mp) / 8); 2277 ASSERT(ichdr_d->count < args->geo->blksize / 8);
2283 ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d)) 2278 ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
2284 + xfs_attr3_leaf_hdr_size(leaf_d)); 2279 + xfs_attr3_leaf_hdr_size(leaf_d));
2285 2280
@@ -2331,11 +2326,11 @@ xfs_attr3_leaf_moveents(
2331 entry_d->nameidx = cpu_to_be16(ichdr_d->firstused); 2326 entry_d->nameidx = cpu_to_be16(ichdr_d->firstused);
2332 entry_d->flags = entry_s->flags; 2327 entry_d->flags = entry_s->flags;
2333 ASSERT(be16_to_cpu(entry_d->nameidx) + tmp 2328 ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
2334 <= XFS_LBSIZE(mp)); 2329 <= args->geo->blksize);
2335 memmove(xfs_attr3_leaf_name(leaf_d, desti), 2330 memmove(xfs_attr3_leaf_name(leaf_d, desti),
2336 xfs_attr3_leaf_name(leaf_s, start_s + i), tmp); 2331 xfs_attr3_leaf_name(leaf_s, start_s + i), tmp);
2337 ASSERT(be16_to_cpu(entry_s->nameidx) + tmp 2332 ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
2338 <= XFS_LBSIZE(mp)); 2333 <= args->geo->blksize);
2339 memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp); 2334 memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
2340 ichdr_s->usedbytes -= tmp; 2335 ichdr_s->usedbytes -= tmp;
2341 ichdr_d->usedbytes += tmp; 2336 ichdr_d->usedbytes += tmp;
@@ -2356,7 +2351,7 @@ xfs_attr3_leaf_moveents(
2356 tmp = count * sizeof(xfs_attr_leaf_entry_t); 2351 tmp = count * sizeof(xfs_attr_leaf_entry_t);
2357 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s]; 2352 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
2358 ASSERT(((char *)entry_s + tmp) <= 2353 ASSERT(((char *)entry_s + tmp) <=
2359 ((char *)leaf_s + XFS_LBSIZE(mp))); 2354 ((char *)leaf_s + args->geo->blksize));
2360 memset(entry_s, 0, tmp); 2355 memset(entry_s, 0, tmp);
2361 } else { 2356 } else {
2362 /* 2357 /*
@@ -2371,7 +2366,7 @@ xfs_attr3_leaf_moveents(
2371 tmp = count * sizeof(xfs_attr_leaf_entry_t); 2366 tmp = count * sizeof(xfs_attr_leaf_entry_t);
2372 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count]; 2367 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count];
2373 ASSERT(((char *)entry_s + tmp) <= 2368 ASSERT(((char *)entry_s + tmp) <=
2374 ((char *)leaf_s + XFS_LBSIZE(mp))); 2369 ((char *)leaf_s + args->geo->blksize));
2375 memset(entry_s, 0, tmp); 2370 memset(entry_s, 0, tmp);
2376 } 2371 }
2377 2372
@@ -2439,22 +2434,21 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
2439 * a "local" or a "remote" attribute. 2434 * a "local" or a "remote" attribute.
2440 */ 2435 */
2441int 2436int
2442xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local) 2437xfs_attr_leaf_newentsize(
2438 struct xfs_da_args *args,
2439 int *local)
2443{ 2440{
2444 int size; 2441 int size;
2445 2442
2446 size = xfs_attr_leaf_entsize_local(namelen, valuelen); 2443 size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen);
2447 if (size < xfs_attr_leaf_entsize_local_max(blocksize)) { 2444 if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) {
2448 if (local) { 2445 if (local)
2449 *local = 1; 2446 *local = 1;
2450 } 2447 return size;
2451 } else {
2452 size = xfs_attr_leaf_entsize_remote(namelen);
2453 if (local) {
2454 *local = 0;
2455 }
2456 } 2448 }
2457 return size; 2449 if (local)
2450 *local = 0;
2451 return xfs_attr_leaf_entsize_remote(args->namelen);
2458} 2452}
2459 2453
2460 2454
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index 3ec5ec0b8678..e2929da7c3ba 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -96,8 +96,7 @@ int xfs_attr3_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
96xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_buf *bp, int *count); 96xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_buf *bp, int *count);
97int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp, 97int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp,
98 struct xfs_buf *leaf2_bp); 98 struct xfs_buf *leaf2_bp);
99int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, 99int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int *local);
100 int *local);
101int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, 100int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
102 xfs_dablk_t bno, xfs_daddr_t mappedbno, 101 xfs_dablk_t bno, xfs_daddr_t mappedbno,
103 struct xfs_buf **bpp); 102 struct xfs_buf **bpp);
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 833fe5d98d80..90e2eeb21207 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -444,6 +444,7 @@ xfs_attr3_leaf_list_int(
444 xfs_da_args_t args; 444 xfs_da_args_t args;
445 445
446 memset((char *)&args, 0, sizeof(args)); 446 memset((char *)&args, 0, sizeof(args));
447 args.geo = context->dp->i_mount->m_attr_geo;
447 args.dp = context->dp; 448 args.dp = context->dp;
448 args.whichfork = XFS_ATTR_FORK; 449 args.whichfork = XFS_ATTR_FORK;
449 args.valuelen = valuelen; 450 args.valuelen = valuelen;
diff --git a/fs/xfs/xfs_attr_remote.c b/fs/xfs/xfs_attr_remote.c
index d2e6e948cec7..b5adfecbb8ee 100644
--- a/fs/xfs/xfs_attr_remote.c
+++ b/fs/xfs/xfs_attr_remote.c
@@ -68,7 +68,6 @@ xfs_attr3_rmt_blocks(
68 */ 68 */
69static bool 69static bool
70xfs_attr3_rmt_hdr_ok( 70xfs_attr3_rmt_hdr_ok(
71 struct xfs_mount *mp,
72 void *ptr, 71 void *ptr,
73 xfs_ino_t ino, 72 xfs_ino_t ino,
74 uint32_t offset, 73 uint32_t offset,
@@ -126,6 +125,7 @@ xfs_attr3_rmt_read_verify(
126 char *ptr; 125 char *ptr;
127 int len; 126 int len;
128 xfs_daddr_t bno; 127 xfs_daddr_t bno;
128 int blksize = mp->m_attr_geo->blksize;
129 129
130 /* no verification of non-crc buffers */ 130 /* no verification of non-crc buffers */
131 if (!xfs_sb_version_hascrc(&mp->m_sb)) 131 if (!xfs_sb_version_hascrc(&mp->m_sb))
@@ -134,21 +134,20 @@ xfs_attr3_rmt_read_verify(
134 ptr = bp->b_addr; 134 ptr = bp->b_addr;
135 bno = bp->b_bn; 135 bno = bp->b_bn;
136 len = BBTOB(bp->b_length); 136 len = BBTOB(bp->b_length);
137 ASSERT(len >= XFS_LBSIZE(mp)); 137 ASSERT(len >= blksize);
138 138
139 while (len > 0) { 139 while (len > 0) {
140 if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp), 140 if (!xfs_verify_cksum(ptr, blksize, XFS_ATTR3_RMT_CRC_OFF)) {
141 XFS_ATTR3_RMT_CRC_OFF)) {
142 xfs_buf_ioerror(bp, EFSBADCRC); 141 xfs_buf_ioerror(bp, EFSBADCRC);
143 break; 142 break;
144 } 143 }
145 if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { 144 if (!xfs_attr3_rmt_verify(mp, ptr, blksize, bno)) {
146 xfs_buf_ioerror(bp, EFSCORRUPTED); 145 xfs_buf_ioerror(bp, EFSCORRUPTED);
147 break; 146 break;
148 } 147 }
149 len -= XFS_LBSIZE(mp); 148 len -= blksize;
150 ptr += XFS_LBSIZE(mp); 149 ptr += blksize;
151 bno += mp->m_bsize; 150 bno += BTOBB(blksize);
152 } 151 }
153 152
154 if (bp->b_error) 153 if (bp->b_error)
@@ -166,6 +165,7 @@ xfs_attr3_rmt_write_verify(
166 char *ptr; 165 char *ptr;
167 int len; 166 int len;
168 xfs_daddr_t bno; 167 xfs_daddr_t bno;
168 int blksize = mp->m_attr_geo->blksize;
169 169
170 /* no verification of non-crc buffers */ 170 /* no verification of non-crc buffers */
171 if (!xfs_sb_version_hascrc(&mp->m_sb)) 171 if (!xfs_sb_version_hascrc(&mp->m_sb))
@@ -174,10 +174,10 @@ xfs_attr3_rmt_write_verify(
174 ptr = bp->b_addr; 174 ptr = bp->b_addr;
175 bno = bp->b_bn; 175 bno = bp->b_bn;
176 len = BBTOB(bp->b_length); 176 len = BBTOB(bp->b_length);
177 ASSERT(len >= XFS_LBSIZE(mp)); 177 ASSERT(len >= blksize);
178 178
179 while (len > 0) { 179 while (len > 0) {
180 if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { 180 if (!xfs_attr3_rmt_verify(mp, ptr, blksize, bno)) {
181 xfs_buf_ioerror(bp, EFSCORRUPTED); 181 xfs_buf_ioerror(bp, EFSCORRUPTED);
182 xfs_verifier_error(bp); 182 xfs_verifier_error(bp);
183 return; 183 return;
@@ -188,11 +188,11 @@ xfs_attr3_rmt_write_verify(
188 rmt = (struct xfs_attr3_rmt_hdr *)ptr; 188 rmt = (struct xfs_attr3_rmt_hdr *)ptr;
189 rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); 189 rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn);
190 } 190 }
191 xfs_update_cksum(ptr, XFS_LBSIZE(mp), XFS_ATTR3_RMT_CRC_OFF); 191 xfs_update_cksum(ptr, blksize, XFS_ATTR3_RMT_CRC_OFF);
192 192
193 len -= XFS_LBSIZE(mp); 193 len -= blksize;
194 ptr += XFS_LBSIZE(mp); 194 ptr += blksize;
195 bno += mp->m_bsize; 195 bno += BTOBB(blksize);
196 } 196 }
197 ASSERT(len == 0); 197 ASSERT(len == 0);
198} 198}
@@ -241,17 +241,18 @@ xfs_attr_rmtval_copyout(
241 char *src = bp->b_addr; 241 char *src = bp->b_addr;
242 xfs_daddr_t bno = bp->b_bn; 242 xfs_daddr_t bno = bp->b_bn;
243 int len = BBTOB(bp->b_length); 243 int len = BBTOB(bp->b_length);
244 int blksize = mp->m_attr_geo->blksize;
244 245
245 ASSERT(len >= XFS_LBSIZE(mp)); 246 ASSERT(len >= blksize);
246 247
247 while (len > 0 && *valuelen > 0) { 248 while (len > 0 && *valuelen > 0) {
248 int hdr_size = 0; 249 int hdr_size = 0;
249 int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); 250 int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, blksize);
250 251
251 byte_cnt = min(*valuelen, byte_cnt); 252 byte_cnt = min(*valuelen, byte_cnt);
252 253
253 if (xfs_sb_version_hascrc(&mp->m_sb)) { 254 if (xfs_sb_version_hascrc(&mp->m_sb)) {
254 if (!xfs_attr3_rmt_hdr_ok(mp, src, ino, *offset, 255 if (!xfs_attr3_rmt_hdr_ok(src, ino, *offset,
255 byte_cnt, bno)) { 256 byte_cnt, bno)) {
256 xfs_alert(mp, 257 xfs_alert(mp,
257"remote attribute header mismatch bno/off/len/owner (0x%llx/0x%x/Ox%x/0x%llx)", 258"remote attribute header mismatch bno/off/len/owner (0x%llx/0x%x/Ox%x/0x%llx)",
@@ -264,9 +265,9 @@ xfs_attr_rmtval_copyout(
264 memcpy(*dst, src + hdr_size, byte_cnt); 265 memcpy(*dst, src + hdr_size, byte_cnt);
265 266
266 /* roll buffer forwards */ 267 /* roll buffer forwards */
267 len -= XFS_LBSIZE(mp); 268 len -= blksize;
268 src += XFS_LBSIZE(mp); 269 src += blksize;
269 bno += mp->m_bsize; 270 bno += BTOBB(blksize);
270 271
271 /* roll attribute data forwards */ 272 /* roll attribute data forwards */
272 *valuelen -= byte_cnt; 273 *valuelen -= byte_cnt;
@@ -288,12 +289,13 @@ xfs_attr_rmtval_copyin(
288 char *dst = bp->b_addr; 289 char *dst = bp->b_addr;
289 xfs_daddr_t bno = bp->b_bn; 290 xfs_daddr_t bno = bp->b_bn;
290 int len = BBTOB(bp->b_length); 291 int len = BBTOB(bp->b_length);
292 int blksize = mp->m_attr_geo->blksize;
291 293
292 ASSERT(len >= XFS_LBSIZE(mp)); 294 ASSERT(len >= blksize);
293 295
294 while (len > 0 && *valuelen > 0) { 296 while (len > 0 && *valuelen > 0) {
295 int hdr_size; 297 int hdr_size;
296 int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); 298 int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, blksize);
297 299
298 byte_cnt = min(*valuelen, byte_cnt); 300 byte_cnt = min(*valuelen, byte_cnt);
299 hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset, 301 hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset,
@@ -305,17 +307,17 @@ xfs_attr_rmtval_copyin(
305 * If this is the last block, zero the remainder of it. 307 * If this is the last block, zero the remainder of it.
306 * Check that we are actually the last block, too. 308 * Check that we are actually the last block, too.
307 */ 309 */
308 if (byte_cnt + hdr_size < XFS_LBSIZE(mp)) { 310 if (byte_cnt + hdr_size < blksize) {
309 ASSERT(*valuelen - byte_cnt == 0); 311 ASSERT(*valuelen - byte_cnt == 0);
310 ASSERT(len == XFS_LBSIZE(mp)); 312 ASSERT(len == blksize);
311 memset(dst + hdr_size + byte_cnt, 0, 313 memset(dst + hdr_size + byte_cnt, 0,
312 XFS_LBSIZE(mp) - hdr_size - byte_cnt); 314 blksize - hdr_size - byte_cnt);
313 } 315 }
314 316
315 /* roll buffer forwards */ 317 /* roll buffer forwards */
316 len -= XFS_LBSIZE(mp); 318 len -= blksize;
317 dst += XFS_LBSIZE(mp); 319 dst += blksize;
318 bno += mp->m_bsize; 320 bno += BTOBB(blksize);
319 321
320 /* roll attribute data forwards */ 322 /* roll attribute data forwards */
321 *valuelen -= byte_cnt; 323 *valuelen -= byte_cnt;
diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h
index f1e3c907044d..e1649c0d3e02 100644
--- a/fs/xfs/xfs_bit.h
+++ b/fs/xfs/xfs_bit.h
@@ -66,8 +66,11 @@ static inline int xfs_lowbit64(__uint64_t v)
66 n = ffs(w); 66 n = ffs(w);
67 } else { /* upper bits */ 67 } else { /* upper bits */
68 w = (__uint32_t)(v >> 32); 68 w = (__uint32_t)(v >> 32);
69 if (w && (n = ffs(w))) 69 if (w) {
70 n += 32; 70 n = ffs(w);
71 if (n)
72 n += 32;
73 }
71 } 74 }
72 return n - 1; 75 return n - 1;
73} 76}
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index f0efc7e970ef..96175df211b1 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -94,7 +94,7 @@ xfs_bmap_compute_maxlevels(
94 maxleafents = MAXAEXTNUM; 94 maxleafents = MAXAEXTNUM;
95 sz = XFS_BMDR_SPACE_CALC(MINABTPTRS); 95 sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
96 } 96 }
97 maxrootrecs = xfs_bmdr_maxrecs(mp, sz, 0); 97 maxrootrecs = xfs_bmdr_maxrecs(sz, 0);
98 minleafrecs = mp->m_bmap_dmnr[0]; 98 minleafrecs = mp->m_bmap_dmnr[0];
99 minnoderecs = mp->m_bmap_dmnr[1]; 99 minnoderecs = mp->m_bmap_dmnr[1];
100 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs; 100 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
@@ -233,7 +233,6 @@ xfs_default_attroffset(
233 */ 233 */
234STATIC void 234STATIC void
235xfs_bmap_forkoff_reset( 235xfs_bmap_forkoff_reset(
236 xfs_mount_t *mp,
237 xfs_inode_t *ip, 236 xfs_inode_t *ip,
238 int whichfork) 237 int whichfork)
239{ 238{
@@ -905,7 +904,7 @@ xfs_bmap_local_to_extents_empty(
905 ASSERT(ifp->if_bytes == 0); 904 ASSERT(ifp->if_bytes == 0);
906 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0); 905 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) == 0);
907 906
908 xfs_bmap_forkoff_reset(ip->i_mount, ip, whichfork); 907 xfs_bmap_forkoff_reset(ip, whichfork);
909 ifp->if_flags &= ~XFS_IFINLINE; 908 ifp->if_flags &= ~XFS_IFINLINE;
910 ifp->if_flags |= XFS_IFEXTENTS; 909 ifp->if_flags |= XFS_IFEXTENTS;
911 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); 910 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
@@ -1099,10 +1098,11 @@ xfs_bmap_add_attrfork_local(
1099 1098
1100 if (S_ISDIR(ip->i_d.di_mode)) { 1099 if (S_ISDIR(ip->i_d.di_mode)) {
1101 memset(&dargs, 0, sizeof(dargs)); 1100 memset(&dargs, 0, sizeof(dargs));
1101 dargs.geo = ip->i_mount->m_dir_geo;
1102 dargs.dp = ip; 1102 dargs.dp = ip;
1103 dargs.firstblock = firstblock; 1103 dargs.firstblock = firstblock;
1104 dargs.flist = flist; 1104 dargs.flist = flist;
1105 dargs.total = ip->i_mount->m_dirblkfsbs; 1105 dargs.total = dargs.geo->fsbcount;
1106 dargs.whichfork = XFS_DATA_FORK; 1106 dargs.whichfork = XFS_DATA_FORK;
1107 dargs.trans = tp; 1107 dargs.trans = tp;
1108 return xfs_dir2_sf_to_block(&dargs); 1108 return xfs_dir2_sf_to_block(&dargs);
@@ -1675,7 +1675,6 @@ xfs_bmap_isaeof(
1675 */ 1675 */
1676int 1676int
1677xfs_bmap_last_offset( 1677xfs_bmap_last_offset(
1678 struct xfs_trans *tp,
1679 struct xfs_inode *ip, 1678 struct xfs_inode *ip,
1680 xfs_fileoff_t *last_block, 1679 xfs_fileoff_t *last_block,
1681 int whichfork) 1680 int whichfork)
@@ -3517,6 +3516,67 @@ xfs_bmap_adjacent(
3517#undef ISVALID 3516#undef ISVALID
3518} 3517}
3519 3518
3519static int
3520xfs_bmap_longest_free_extent(
3521 struct xfs_trans *tp,
3522 xfs_agnumber_t ag,
3523 xfs_extlen_t *blen,
3524 int *notinit)
3525{
3526 struct xfs_mount *mp = tp->t_mountp;
3527 struct xfs_perag *pag;
3528 xfs_extlen_t longest;
3529 int error = 0;
3530
3531 pag = xfs_perag_get(mp, ag);
3532 if (!pag->pagf_init) {
3533 error = xfs_alloc_pagf_init(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK);
3534 if (error)
3535 goto out;
3536
3537 if (!pag->pagf_init) {
3538 *notinit = 1;
3539 goto out;
3540 }
3541 }
3542
3543 longest = xfs_alloc_longest_free_extent(mp, pag);
3544 if (*blen < longest)
3545 *blen = longest;
3546
3547out:
3548 xfs_perag_put(pag);
3549 return error;
3550}
3551
3552static void
3553xfs_bmap_select_minlen(
3554 struct xfs_bmalloca *ap,
3555 struct xfs_alloc_arg *args,
3556 xfs_extlen_t *blen,
3557 int notinit)
3558{
3559 if (notinit || *blen < ap->minlen) {
3560 /*
3561 * Since we did a BUF_TRYLOCK above, it is possible that
3562 * there is space for this request.
3563 */
3564 args->minlen = ap->minlen;
3565 } else if (*blen < args->maxlen) {
3566 /*
3567 * If the best seen length is less than the request length,
3568 * use the best as the minimum.
3569 */
3570 args->minlen = *blen;
3571 } else {
3572 /*
3573 * Otherwise we've seen an extent as big as maxlen, use that
3574 * as the minimum.
3575 */
3576 args->minlen = args->maxlen;
3577 }
3578}
3579
3520STATIC int 3580STATIC int
3521xfs_bmap_btalloc_nullfb( 3581xfs_bmap_btalloc_nullfb(
3522 struct xfs_bmalloca *ap, 3582 struct xfs_bmalloca *ap,
@@ -3524,111 +3584,74 @@ xfs_bmap_btalloc_nullfb(
3524 xfs_extlen_t *blen) 3584 xfs_extlen_t *blen)
3525{ 3585{
3526 struct xfs_mount *mp = ap->ip->i_mount; 3586 struct xfs_mount *mp = ap->ip->i_mount;
3527 struct xfs_perag *pag;
3528 xfs_agnumber_t ag, startag; 3587 xfs_agnumber_t ag, startag;
3529 int notinit = 0; 3588 int notinit = 0;
3530 int error; 3589 int error;
3531 3590
3532 if (ap->userdata && xfs_inode_is_filestream(ap->ip)) 3591 args->type = XFS_ALLOCTYPE_START_BNO;
3533 args->type = XFS_ALLOCTYPE_NEAR_BNO;
3534 else
3535 args->type = XFS_ALLOCTYPE_START_BNO;
3536 args->total = ap->total; 3592 args->total = ap->total;
3537 3593
3538 /*
3539 * Search for an allocation group with a single extent large enough
3540 * for the request. If one isn't found, then adjust the minimum
3541 * allocation size to the largest space found.
3542 */
3543 startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno); 3594 startag = ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
3544 if (startag == NULLAGNUMBER) 3595 if (startag == NULLAGNUMBER)
3545 startag = ag = 0; 3596 startag = ag = 0;
3546 3597
3547 pag = xfs_perag_get(mp, ag);
3548 while (*blen < args->maxlen) { 3598 while (*blen < args->maxlen) {
3549 if (!pag->pagf_init) { 3599 error = xfs_bmap_longest_free_extent(args->tp, ag, blen,
3550 error = xfs_alloc_pagf_init(mp, args->tp, ag, 3600 &notinit);
3551 XFS_ALLOC_FLAG_TRYLOCK); 3601 if (error)
3552 if (error) { 3602 return error;
3553 xfs_perag_put(pag);
3554 return error;
3555 }
3556 }
3557
3558 /*
3559 * See xfs_alloc_fix_freelist...
3560 */
3561 if (pag->pagf_init) {
3562 xfs_extlen_t longest;
3563 longest = xfs_alloc_longest_free_extent(mp, pag);
3564 if (*blen < longest)
3565 *blen = longest;
3566 } else
3567 notinit = 1;
3568
3569 if (xfs_inode_is_filestream(ap->ip)) {
3570 if (*blen >= args->maxlen)
3571 break;
3572
3573 if (ap->userdata) {
3574 /*
3575 * If startag is an invalid AG, we've
3576 * come here once before and
3577 * xfs_filestream_new_ag picked the
3578 * best currently available.
3579 *
3580 * Don't continue looping, since we
3581 * could loop forever.
3582 */
3583 if (startag == NULLAGNUMBER)
3584 break;
3585
3586 error = xfs_filestream_new_ag(ap, &ag);
3587 xfs_perag_put(pag);
3588 if (error)
3589 return error;
3590 3603
3591 /* loop again to set 'blen'*/
3592 startag = NULLAGNUMBER;
3593 pag = xfs_perag_get(mp, ag);
3594 continue;
3595 }
3596 }
3597 if (++ag == mp->m_sb.sb_agcount) 3604 if (++ag == mp->m_sb.sb_agcount)
3598 ag = 0; 3605 ag = 0;
3599 if (ag == startag) 3606 if (ag == startag)
3600 break; 3607 break;
3601 xfs_perag_put(pag);
3602 pag = xfs_perag_get(mp, ag);
3603 } 3608 }
3604 xfs_perag_put(pag);
3605 3609
3606 /* 3610 xfs_bmap_select_minlen(ap, args, blen, notinit);
3607 * Since the above loop did a BUF_TRYLOCK, it is 3611 return 0;
3608 * possible that there is space for this request. 3612}
3609 */ 3613
3610 if (notinit || *blen < ap->minlen) 3614STATIC int
3611 args->minlen = ap->minlen; 3615xfs_bmap_btalloc_filestreams(
3612 /* 3616 struct xfs_bmalloca *ap,
3613 * If the best seen length is less than the request 3617 struct xfs_alloc_arg *args,
3614 * length, use the best as the minimum. 3618 xfs_extlen_t *blen)
3615 */ 3619{
3616 else if (*blen < args->maxlen) 3620 struct xfs_mount *mp = ap->ip->i_mount;
3617 args->minlen = *blen; 3621 xfs_agnumber_t ag;
3618 /* 3622 int notinit = 0;
3619 * Otherwise we've seen an extent as big as maxlen, 3623 int error;
3620 * use that as the minimum. 3624
3621 */ 3625 args->type = XFS_ALLOCTYPE_NEAR_BNO;
3622 else 3626 args->total = ap->total;
3623 args->minlen = args->maxlen; 3627
3628 ag = XFS_FSB_TO_AGNO(mp, args->fsbno);
3629 if (ag == NULLAGNUMBER)
3630 ag = 0;
3631
3632 error = xfs_bmap_longest_free_extent(args->tp, ag, blen, &notinit);
3633 if (error)
3634 return error;
3635
3636 if (*blen < args->maxlen) {
3637 error = xfs_filestream_new_ag(ap, &ag);
3638 if (error)
3639 return error;
3640
3641 error = xfs_bmap_longest_free_extent(args->tp, ag, blen,
3642 &notinit);
3643 if (error)
3644 return error;
3645
3646 }
3647
3648 xfs_bmap_select_minlen(ap, args, blen, notinit);
3624 3649
3625 /* 3650 /*
3626 * set the failure fallback case to look in the selected 3651 * Set the failure fallback case to look in the selected AG as stream
3627 * AG as the stream may have moved. 3652 * may have moved.
3628 */ 3653 */
3629 if (xfs_inode_is_filestream(ap->ip)) 3654 ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
3630 ap->blkno = args->fsbno = XFS_AGB_TO_FSB(mp, ag, 0);
3631
3632 return 0; 3655 return 0;
3633} 3656}
3634 3657
@@ -3708,7 +3731,15 @@ xfs_bmap_btalloc(
3708 args.firstblock = *ap->firstblock; 3731 args.firstblock = *ap->firstblock;
3709 blen = 0; 3732 blen = 0;
3710 if (nullfb) { 3733 if (nullfb) {
3711 error = xfs_bmap_btalloc_nullfb(ap, &args, &blen); 3734 /*
3735 * Search for an allocation group with a single extent large
3736 * enough for the request. If one isn't found, then adjust
3737 * the minimum allocation size to the largest space found.
3738 */
3739 if (ap->userdata && xfs_inode_is_filestream(ap->ip))
3740 error = xfs_bmap_btalloc_filestreams(ap, &args, &blen);
3741 else
3742 error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
3712 if (error) 3743 if (error)
3713 return error; 3744 return error;
3714 } else if (ap->flist->xbf_low) { 3745 } else if (ap->flist->xbf_low) {
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index f84bd7af43be..38ba36e9b2f0 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -156,8 +156,8 @@ int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip,
156 xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork); 156 xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork);
157int xfs_bmap_last_before(struct xfs_trans *tp, struct xfs_inode *ip, 157int xfs_bmap_last_before(struct xfs_trans *tp, struct xfs_inode *ip,
158 xfs_fileoff_t *last_block, int whichfork); 158 xfs_fileoff_t *last_block, int whichfork);
159int xfs_bmap_last_offset(struct xfs_trans *tp, struct xfs_inode *ip, 159int xfs_bmap_last_offset(struct xfs_inode *ip, xfs_fileoff_t *unused,
160 xfs_fileoff_t *unused, int whichfork); 160 int whichfork);
161int xfs_bmap_one_block(struct xfs_inode *ip, int whichfork); 161int xfs_bmap_one_block(struct xfs_inode *ip, int whichfork);
162int xfs_bmap_read_extents(struct xfs_trans *tp, struct xfs_inode *ip, 162int xfs_bmap_read_extents(struct xfs_trans *tp, struct xfs_inode *ip,
163 int whichfork); 163 int whichfork);
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 818d546664e7..948836c4fd90 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -84,7 +84,7 @@ xfs_bmdr_to_bmbt(
84 rblock->bb_level = dblock->bb_level; 84 rblock->bb_level = dblock->bb_level;
85 ASSERT(be16_to_cpu(rblock->bb_level) > 0); 85 ASSERT(be16_to_cpu(rblock->bb_level) > 0);
86 rblock->bb_numrecs = dblock->bb_numrecs; 86 rblock->bb_numrecs = dblock->bb_numrecs;
87 dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); 87 dmxr = xfs_bmdr_maxrecs(dblocklen, 0);
88 fkp = XFS_BMDR_KEY_ADDR(dblock, 1); 88 fkp = XFS_BMDR_KEY_ADDR(dblock, 1);
89 tkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); 89 tkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1);
90 fpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr); 90 fpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr);
@@ -443,7 +443,7 @@ xfs_bmbt_to_bmdr(
443 ASSERT(rblock->bb_level != 0); 443 ASSERT(rblock->bb_level != 0);
444 dblock->bb_level = rblock->bb_level; 444 dblock->bb_level = rblock->bb_level;
445 dblock->bb_numrecs = rblock->bb_numrecs; 445 dblock->bb_numrecs = rblock->bb_numrecs;
446 dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); 446 dmxr = xfs_bmdr_maxrecs(dblocklen, 0);
447 fkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); 447 fkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1);
448 tkp = XFS_BMDR_KEY_ADDR(dblock, 1); 448 tkp = XFS_BMDR_KEY_ADDR(dblock, 1);
449 fpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); 449 fpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen);
@@ -519,7 +519,6 @@ xfs_bmbt_alloc_block(
519 struct xfs_btree_cur *cur, 519 struct xfs_btree_cur *cur,
520 union xfs_btree_ptr *start, 520 union xfs_btree_ptr *start,
521 union xfs_btree_ptr *new, 521 union xfs_btree_ptr *new,
522 int length,
523 int *stat) 522 int *stat)
524{ 523{
525 xfs_alloc_arg_t args; /* block allocation args */ 524 xfs_alloc_arg_t args; /* block allocation args */
@@ -672,8 +671,7 @@ xfs_bmbt_get_dmaxrecs(
672{ 671{
673 if (level != cur->bc_nlevels - 1) 672 if (level != cur->bc_nlevels - 1)
674 return cur->bc_mp->m_bmap_dmxr[level != 0]; 673 return cur->bc_mp->m_bmap_dmxr[level != 0];
675 return xfs_bmdr_maxrecs(cur->bc_mp, cur->bc_private.b.forksize, 674 return xfs_bmdr_maxrecs(cur->bc_private.b.forksize, level == 0);
676 level == 0);
677} 675}
678 676
679STATIC void 677STATIC void
@@ -914,7 +912,6 @@ xfs_bmbt_maxrecs(
914 */ 912 */
915int 913int
916xfs_bmdr_maxrecs( 914xfs_bmdr_maxrecs(
917 struct xfs_mount *mp,
918 int blocklen, 915 int blocklen,
919 int leaf) 916 int leaf)
920{ 917{
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index 6e42e1e50b89..819a8a4dee95 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -130,7 +130,7 @@ extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int,
130 xfs_bmdr_block_t *, int); 130 xfs_bmdr_block_t *, int);
131 131
132extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level); 132extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level);
133extern int xfs_bmdr_maxrecs(struct xfs_mount *, int blocklen, int leaf); 133extern int xfs_bmdr_maxrecs(int blocklen, int leaf);
134extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf); 134extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf);
135 135
136extern int xfs_bmbt_change_owner(struct xfs_trans *tp, struct xfs_inode *ip, 136extern int xfs_bmbt_change_owner(struct xfs_trans *tp, struct xfs_inode *ip,
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 296160b8e78c..703b3ec1796c 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -258,14 +258,23 @@ xfs_bmapi_allocate_worker(
258 struct xfs_bmalloca *args = container_of(work, 258 struct xfs_bmalloca *args = container_of(work,
259 struct xfs_bmalloca, work); 259 struct xfs_bmalloca, work);
260 unsigned long pflags; 260 unsigned long pflags;
261 unsigned long new_pflags = PF_FSTRANS;
261 262
262 /* we are in a transaction context here */ 263 /*
263 current_set_flags_nested(&pflags, PF_FSTRANS); 264 * we are in a transaction context here, but may also be doing work
265 * in kswapd context, and hence we may need to inherit that state
266 * temporarily to ensure that we don't block waiting for memory reclaim
267 * in any way.
268 */
269 if (args->kswapd)
270 new_pflags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
271
272 current_set_flags_nested(&pflags, new_pflags);
264 273
265 args->result = __xfs_bmapi_allocate(args); 274 args->result = __xfs_bmapi_allocate(args);
266 complete(args->done); 275 complete(args->done);
267 276
268 current_restore_flags_nested(&pflags, PF_FSTRANS); 277 current_restore_flags_nested(&pflags, new_pflags);
269} 278}
270 279
271/* 280/*
@@ -284,6 +293,7 @@ xfs_bmapi_allocate(
284 293
285 294
286 args->done = &done; 295 args->done = &done;
296 args->kswapd = current_is_kswapd();
287 INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker); 297 INIT_WORK_ONSTACK(&args->work, xfs_bmapi_allocate_worker);
288 queue_work(xfs_alloc_wq, &args->work); 298 queue_work(xfs_alloc_wq, &args->work);
289 wait_for_completion(&done); 299 wait_for_completion(&done);
@@ -1519,7 +1529,6 @@ xfs_collapse_file_space(
1519 1529
1520 while (!error && !done) { 1530 while (!error && !done) {
1521 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); 1531 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
1522 tp->t_flags |= XFS_TRANS_RESERVE;
1523 /* 1532 /*
1524 * We would need to reserve permanent block for transaction. 1533 * We would need to reserve permanent block for transaction.
1525 * This will come into picture when after shifting extent into 1534 * This will come into picture when after shifting extent into
@@ -1529,7 +1538,6 @@ xfs_collapse_file_space(
1529 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, 1538 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write,
1530 XFS_DIOSTRAT_SPACE_RES(mp, 0), 0); 1539 XFS_DIOSTRAT_SPACE_RES(mp, 0), 0);
1531 if (error) { 1540 if (error) {
1532 ASSERT(error == ENOSPC || XFS_FORCED_SHUTDOWN(mp));
1533 xfs_trans_cancel(tp, 0); 1541 xfs_trans_cancel(tp, 0);
1534 break; 1542 break;
1535 } 1543 }
diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h
index 935ed2b24edf..075f72232a64 100644
--- a/fs/xfs/xfs_bmap_util.h
+++ b/fs/xfs/xfs_bmap_util.h
@@ -50,12 +50,13 @@ struct xfs_bmalloca {
50 xfs_extlen_t total; /* total blocks needed for xaction */ 50 xfs_extlen_t total; /* total blocks needed for xaction */
51 xfs_extlen_t minlen; /* minimum allocation size (blocks) */ 51 xfs_extlen_t minlen; /* minimum allocation size (blocks) */
52 xfs_extlen_t minleft; /* amount must be left after alloc */ 52 xfs_extlen_t minleft; /* amount must be left after alloc */
53 char eof; /* set if allocating past last extent */ 53 bool eof; /* set if allocating past last extent */
54 char wasdel; /* replacing a delayed allocation */ 54 bool wasdel; /* replacing a delayed allocation */
55 char userdata;/* set if is user data */ 55 bool userdata;/* set if is user data */
56 char aeof; /* allocated space at eof */ 56 bool aeof; /* allocated space at eof */
57 char conv; /* overwriting unwritten extents */ 57 bool conv; /* overwriting unwritten extents */
58 char stack_switch; 58 bool stack_switch;
59 bool kswapd; /* allocation in kswapd context */
59 int flags; 60 int flags;
60 struct completion *done; 61 struct completion *done;
61 struct work_struct work; 62 struct work_struct work;
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index e80d59fdf89a..bf810c6baf2b 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -43,9 +43,10 @@ kmem_zone_t *xfs_btree_cur_zone;
43 * Btree magic numbers. 43 * Btree magic numbers.
44 */ 44 */
45static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = { 45static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = {
46 { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC }, 46 { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC,
47 XFS_FIBT_MAGIC },
47 { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, 48 { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC,
48 XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC } 49 XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC }
49}; 50};
50#define xfs_btree_magic(cur) \ 51#define xfs_btree_magic(cur) \
51 xfs_magics[!!((cur)->bc_flags & XFS_BTREE_CRC_BLOCKS)][cur->bc_btnum] 52 xfs_magics[!!((cur)->bc_flags & XFS_BTREE_CRC_BLOCKS)][cur->bc_btnum]
@@ -552,14 +553,11 @@ xfs_btree_get_bufl(
552 xfs_fsblock_t fsbno, /* file system block number */ 553 xfs_fsblock_t fsbno, /* file system block number */
553 uint lock) /* lock flags for get_buf */ 554 uint lock) /* lock flags for get_buf */
554{ 555{
555 xfs_buf_t *bp; /* buffer pointer (return value) */
556 xfs_daddr_t d; /* real disk block address */ 556 xfs_daddr_t d; /* real disk block address */
557 557
558 ASSERT(fsbno != NULLFSBLOCK); 558 ASSERT(fsbno != NULLFSBLOCK);
559 d = XFS_FSB_TO_DADDR(mp, fsbno); 559 d = XFS_FSB_TO_DADDR(mp, fsbno);
560 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); 560 return xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
561 ASSERT(!xfs_buf_geterror(bp));
562 return bp;
563} 561}
564 562
565/* 563/*
@@ -574,15 +572,12 @@ xfs_btree_get_bufs(
574 xfs_agblock_t agbno, /* allocation group block number */ 572 xfs_agblock_t agbno, /* allocation group block number */
575 uint lock) /* lock flags for get_buf */ 573 uint lock) /* lock flags for get_buf */
576{ 574{
577 xfs_buf_t *bp; /* buffer pointer (return value) */
578 xfs_daddr_t d; /* real disk block address */ 575 xfs_daddr_t d; /* real disk block address */
579 576
580 ASSERT(agno != NULLAGNUMBER); 577 ASSERT(agno != NULLAGNUMBER);
581 ASSERT(agbno != NULLAGBLOCK); 578 ASSERT(agbno != NULLAGBLOCK);
582 d = XFS_AGB_TO_DADDR(mp, agno, agbno); 579 d = XFS_AGB_TO_DADDR(mp, agno, agbno);
583 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); 580 return xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
584 ASSERT(!xfs_buf_geterror(bp));
585 return bp;
586} 581}
587 582
588/* 583/*
@@ -722,7 +717,6 @@ xfs_btree_read_bufl(
722 mp->m_bsize, lock, &bp, ops); 717 mp->m_bsize, lock, &bp, ops);
723 if (error) 718 if (error)
724 return error; 719 return error;
725 ASSERT(!xfs_buf_geterror(bp));
726 if (bp) 720 if (bp)
727 xfs_buf_set_ref(bp, refval); 721 xfs_buf_set_ref(bp, refval);
728 *bpp = bp; 722 *bpp = bp;
@@ -1115,6 +1109,7 @@ xfs_btree_set_refs(
1115 xfs_buf_set_ref(bp, XFS_ALLOC_BTREE_REF); 1109 xfs_buf_set_ref(bp, XFS_ALLOC_BTREE_REF);
1116 break; 1110 break;
1117 case XFS_BTNUM_INO: 1111 case XFS_BTNUM_INO:
1112 case XFS_BTNUM_FINO:
1118 xfs_buf_set_ref(bp, XFS_INO_BTREE_REF); 1113 xfs_buf_set_ref(bp, XFS_INO_BTREE_REF);
1119 break; 1114 break;
1120 case XFS_BTNUM_BMAP: 1115 case XFS_BTNUM_BMAP:
@@ -1159,7 +1154,6 @@ STATIC int
1159xfs_btree_read_buf_block( 1154xfs_btree_read_buf_block(
1160 struct xfs_btree_cur *cur, 1155 struct xfs_btree_cur *cur,
1161 union xfs_btree_ptr *ptr, 1156 union xfs_btree_ptr *ptr,
1162 int level,
1163 int flags, 1157 int flags,
1164 struct xfs_btree_block **block, 1158 struct xfs_btree_block **block,
1165 struct xfs_buf **bpp) 1159 struct xfs_buf **bpp)
@@ -1178,7 +1172,6 @@ xfs_btree_read_buf_block(
1178 if (error) 1172 if (error)
1179 return error; 1173 return error;
1180 1174
1181 ASSERT(!xfs_buf_geterror(*bpp));
1182 xfs_btree_set_refs(cur, *bpp); 1175 xfs_btree_set_refs(cur, *bpp);
1183 *block = XFS_BUF_TO_BLOCK(*bpp); 1176 *block = XFS_BUF_TO_BLOCK(*bpp);
1184 return 0; 1177 return 0;
@@ -1517,8 +1510,8 @@ xfs_btree_increment(
1517 union xfs_btree_ptr *ptrp; 1510 union xfs_btree_ptr *ptrp;
1518 1511
1519 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block); 1512 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
1520 error = xfs_btree_read_buf_block(cur, ptrp, --lev, 1513 --lev;
1521 0, &block, &bp); 1514 error = xfs_btree_read_buf_block(cur, ptrp, 0, &block, &bp);
1522 if (error) 1515 if (error)
1523 goto error0; 1516 goto error0;
1524 1517
@@ -1616,8 +1609,8 @@ xfs_btree_decrement(
1616 union xfs_btree_ptr *ptrp; 1609 union xfs_btree_ptr *ptrp;
1617 1610
1618 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block); 1611 ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
1619 error = xfs_btree_read_buf_block(cur, ptrp, --lev, 1612 --lev;
1620 0, &block, &bp); 1613 error = xfs_btree_read_buf_block(cur, ptrp, 0, &block, &bp);
1621 if (error) 1614 if (error)
1622 goto error0; 1615 goto error0;
1623 xfs_btree_setbuf(cur, lev, bp); 1616 xfs_btree_setbuf(cur, lev, bp);
@@ -1667,7 +1660,7 @@ xfs_btree_lookup_get_block(
1667 return 0; 1660 return 0;
1668 } 1661 }
1669 1662
1670 error = xfs_btree_read_buf_block(cur, pp, level, 0, blkp, &bp); 1663 error = xfs_btree_read_buf_block(cur, pp, 0, blkp, &bp);
1671 if (error) 1664 if (error)
1672 return error; 1665 return error;
1673 1666
@@ -2018,7 +2011,7 @@ xfs_btree_lshift(
2018 goto out0; 2011 goto out0;
2019 2012
2020 /* Set up the left neighbor as "left". */ 2013 /* Set up the left neighbor as "left". */
2021 error = xfs_btree_read_buf_block(cur, &lptr, level, 0, &left, &lbp); 2014 error = xfs_btree_read_buf_block(cur, &lptr, 0, &left, &lbp);
2022 if (error) 2015 if (error)
2023 goto error0; 2016 goto error0;
2024 2017
@@ -2202,7 +2195,7 @@ xfs_btree_rshift(
2202 goto out0; 2195 goto out0;
2203 2196
2204 /* Set up the right neighbor as "right". */ 2197 /* Set up the right neighbor as "right". */
2205 error = xfs_btree_read_buf_block(cur, &rptr, level, 0, &right, &rbp); 2198 error = xfs_btree_read_buf_block(cur, &rptr, 0, &right, &rbp);
2206 if (error) 2199 if (error)
2207 goto error0; 2200 goto error0;
2208 2201
@@ -2372,7 +2365,7 @@ xfs_btree_split(
2372 xfs_btree_buf_to_ptr(cur, lbp, &lptr); 2365 xfs_btree_buf_to_ptr(cur, lbp, &lptr);
2373 2366
2374 /* Allocate the new block. If we can't do it, we're toast. Give up. */ 2367 /* Allocate the new block. If we can't do it, we're toast. Give up. */
2375 error = cur->bc_ops->alloc_block(cur, &lptr, &rptr, 1, stat); 2368 error = cur->bc_ops->alloc_block(cur, &lptr, &rptr, stat);
2376 if (error) 2369 if (error)
2377 goto error0; 2370 goto error0;
2378 if (*stat == 0) 2371 if (*stat == 0)
@@ -2470,7 +2463,7 @@ xfs_btree_split(
2470 * point back to right instead of to left. 2463 * point back to right instead of to left.
2471 */ 2464 */
2472 if (!xfs_btree_ptr_is_null(cur, &rrptr)) { 2465 if (!xfs_btree_ptr_is_null(cur, &rrptr)) {
2473 error = xfs_btree_read_buf_block(cur, &rrptr, level, 2466 error = xfs_btree_read_buf_block(cur, &rrptr,
2474 0, &rrblock, &rrbp); 2467 0, &rrblock, &rrbp);
2475 if (error) 2468 if (error)
2476 goto error0; 2469 goto error0;
@@ -2545,7 +2538,7 @@ xfs_btree_new_iroot(
2545 pp = xfs_btree_ptr_addr(cur, 1, block); 2538 pp = xfs_btree_ptr_addr(cur, 1, block);
2546 2539
2547 /* Allocate the new block. If we can't do it, we're toast. Give up. */ 2540 /* Allocate the new block. If we can't do it, we're toast. Give up. */
2548 error = cur->bc_ops->alloc_block(cur, pp, &nptr, 1, stat); 2541 error = cur->bc_ops->alloc_block(cur, pp, &nptr, stat);
2549 if (error) 2542 if (error)
2550 goto error0; 2543 goto error0;
2551 if (*stat == 0) { 2544 if (*stat == 0) {
@@ -2649,7 +2642,7 @@ xfs_btree_new_root(
2649 cur->bc_ops->init_ptr_from_cur(cur, &rptr); 2642 cur->bc_ops->init_ptr_from_cur(cur, &rptr);
2650 2643
2651 /* Allocate the new block. If we can't do it, we're toast. Give up. */ 2644 /* Allocate the new block. If we can't do it, we're toast. Give up. */
2652 error = cur->bc_ops->alloc_block(cur, &rptr, &lptr, 1, stat); 2645 error = cur->bc_ops->alloc_block(cur, &rptr, &lptr, stat);
2653 if (error) 2646 if (error)
2654 goto error0; 2647 goto error0;
2655 if (*stat == 0) 2648 if (*stat == 0)
@@ -2684,8 +2677,7 @@ xfs_btree_new_root(
2684 lbp = bp; 2677 lbp = bp;
2685 xfs_btree_buf_to_ptr(cur, lbp, &lptr); 2678 xfs_btree_buf_to_ptr(cur, lbp, &lptr);
2686 left = block; 2679 left = block;
2687 error = xfs_btree_read_buf_block(cur, &rptr, 2680 error = xfs_btree_read_buf_block(cur, &rptr, 0, &right, &rbp);
2688 cur->bc_nlevels - 1, 0, &right, &rbp);
2689 if (error) 2681 if (error)
2690 goto error0; 2682 goto error0;
2691 bp = rbp; 2683 bp = rbp;
@@ -2696,8 +2688,7 @@ xfs_btree_new_root(
2696 xfs_btree_buf_to_ptr(cur, rbp, &rptr); 2688 xfs_btree_buf_to_ptr(cur, rbp, &rptr);
2697 right = block; 2689 right = block;
2698 xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB); 2690 xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB);
2699 error = xfs_btree_read_buf_block(cur, &lptr, 2691 error = xfs_btree_read_buf_block(cur, &lptr, 0, &left, &lbp);
2700 cur->bc_nlevels - 1, 0, &left, &lbp);
2701 if (error) 2692 if (error)
2702 goto error0; 2693 goto error0;
2703 bp = lbp; 2694 bp = lbp;
@@ -3649,8 +3640,7 @@ xfs_btree_delrec(
3649 rptr = cptr; 3640 rptr = cptr;
3650 right = block; 3641 right = block;
3651 rbp = bp; 3642 rbp = bp;
3652 error = xfs_btree_read_buf_block(cur, &lptr, level, 3643 error = xfs_btree_read_buf_block(cur, &lptr, 0, &left, &lbp);
3653 0, &left, &lbp);
3654 if (error) 3644 if (error)
3655 goto error0; 3645 goto error0;
3656 3646
@@ -3667,8 +3657,7 @@ xfs_btree_delrec(
3667 lptr = cptr; 3657 lptr = cptr;
3668 left = block; 3658 left = block;
3669 lbp = bp; 3659 lbp = bp;
3670 error = xfs_btree_read_buf_block(cur, &rptr, level, 3660 error = xfs_btree_read_buf_block(cur, &rptr, 0, &right, &rbp);
3671 0, &right, &rbp);
3672 if (error) 3661 if (error)
3673 goto error0; 3662 goto error0;
3674 3663
@@ -3740,8 +3729,7 @@ xfs_btree_delrec(
3740 /* If there is a right sibling, point it to the remaining block. */ 3729 /* If there is a right sibling, point it to the remaining block. */
3741 xfs_btree_get_sibling(cur, left, &cptr, XFS_BB_RIGHTSIB); 3730 xfs_btree_get_sibling(cur, left, &cptr, XFS_BB_RIGHTSIB);
3742 if (!xfs_btree_ptr_is_null(cur, &cptr)) { 3731 if (!xfs_btree_ptr_is_null(cur, &cptr)) {
3743 error = xfs_btree_read_buf_block(cur, &cptr, level, 3732 error = xfs_btree_read_buf_block(cur, &cptr, 0, &rrblock, &rrbp);
3744 0, &rrblock, &rrbp);
3745 if (error) 3733 if (error)
3746 goto error0; 3734 goto error0;
3747 xfs_btree_set_sibling(cur, rrblock, &lptr, XFS_BB_LEFTSIB); 3735 xfs_btree_set_sibling(cur, rrblock, &lptr, XFS_BB_LEFTSIB);
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 91e34f21bace..a04b69422f67 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -62,6 +62,7 @@ union xfs_btree_rec {
62#define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi) 62#define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi)
63#define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) 63#define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi)
64#define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) 64#define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi)
65#define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi)
65 66
66/* 67/*
67 * For logging record fields. 68 * For logging record fields.
@@ -92,6 +93,7 @@ do { \
92 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \ 93 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \
93 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ 94 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \
94 case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ 95 case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \
96 case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \
95 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ 97 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
96 } \ 98 } \
97} while (0) 99} while (0)
@@ -105,6 +107,7 @@ do { \
105 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \ 107 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \
106 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ 108 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \
107 case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ 109 case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \
110 case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \
108 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ 111 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
109 } \ 112 } \
110} while (0) 113} while (0)
@@ -129,7 +132,7 @@ struct xfs_btree_ops {
129 int (*alloc_block)(struct xfs_btree_cur *cur, 132 int (*alloc_block)(struct xfs_btree_cur *cur,
130 union xfs_btree_ptr *start_bno, 133 union xfs_btree_ptr *start_bno,
131 union xfs_btree_ptr *new_bno, 134 union xfs_btree_ptr *new_bno,
132 int length, int *stat); 135 int *stat);
133 int (*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp); 136 int (*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp);
134 137
135 /* update last record information */ 138 /* update last record information */
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index cb10a0aaab3a..7a34a1ae6552 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -216,8 +216,7 @@ _xfs_buf_alloc(
216STATIC int 216STATIC int
217_xfs_buf_get_pages( 217_xfs_buf_get_pages(
218 xfs_buf_t *bp, 218 xfs_buf_t *bp,
219 int page_count, 219 int page_count)
220 xfs_buf_flags_t flags)
221{ 220{
222 /* Make sure that we have a page list */ 221 /* Make sure that we have a page list */
223 if (bp->b_pages == NULL) { 222 if (bp->b_pages == NULL) {
@@ -330,7 +329,7 @@ use_alloc_page:
330 end = (BBTOB(bp->b_maps[0].bm_bn + bp->b_length) + PAGE_SIZE - 1) 329 end = (BBTOB(bp->b_maps[0].bm_bn + bp->b_length) + PAGE_SIZE - 1)
331 >> PAGE_SHIFT; 330 >> PAGE_SHIFT;
332 page_count = end - start; 331 page_count = end - start;
333 error = _xfs_buf_get_pages(bp, page_count, flags); 332 error = _xfs_buf_get_pages(bp, page_count);
334 if (unlikely(error)) 333 if (unlikely(error))
335 return error; 334 return error;
336 335
@@ -778,7 +777,7 @@ xfs_buf_associate_memory(
778 bp->b_pages = NULL; 777 bp->b_pages = NULL;
779 bp->b_addr = mem; 778 bp->b_addr = mem;
780 779
781 rval = _xfs_buf_get_pages(bp, page_count, 0); 780 rval = _xfs_buf_get_pages(bp, page_count);
782 if (rval) 781 if (rval)
783 return rval; 782 return rval;
784 783
@@ -811,7 +810,7 @@ xfs_buf_get_uncached(
811 goto fail; 810 goto fail;
812 811
813 page_count = PAGE_ALIGN(numblks << BBSHIFT) >> PAGE_SHIFT; 812 page_count = PAGE_ALIGN(numblks << BBSHIFT) >> PAGE_SHIFT;
814 error = _xfs_buf_get_pages(bp, page_count, 0); 813 error = _xfs_buf_get_pages(bp, page_count);
815 if (error) 814 if (error)
816 goto fail_free_buf; 815 goto fail_free_buf;
817 816
@@ -1615,7 +1614,6 @@ xfs_free_buftarg(
1615int 1614int
1616xfs_setsize_buftarg( 1615xfs_setsize_buftarg(
1617 xfs_buftarg_t *btp, 1616 xfs_buftarg_t *btp,
1618 unsigned int blocksize,
1619 unsigned int sectorsize) 1617 unsigned int sectorsize)
1620{ 1618{
1621 /* Set up metadata sector size info */ 1619 /* Set up metadata sector size info */
@@ -1650,16 +1648,13 @@ xfs_setsize_buftarg_early(
1650 xfs_buftarg_t *btp, 1648 xfs_buftarg_t *btp,
1651 struct block_device *bdev) 1649 struct block_device *bdev)
1652{ 1650{
1653 return xfs_setsize_buftarg(btp, PAGE_SIZE, 1651 return xfs_setsize_buftarg(btp, bdev_logical_block_size(bdev));
1654 bdev_logical_block_size(bdev));
1655} 1652}
1656 1653
1657xfs_buftarg_t * 1654xfs_buftarg_t *
1658xfs_alloc_buftarg( 1655xfs_alloc_buftarg(
1659 struct xfs_mount *mp, 1656 struct xfs_mount *mp,
1660 struct block_device *bdev, 1657 struct block_device *bdev)
1661 int external,
1662 const char *fsname)
1663{ 1658{
1664 xfs_buftarg_t *btp; 1659 xfs_buftarg_t *btp;
1665 1660
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index b8a3abf6cf47..3a7a5523d3dc 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -298,11 +298,6 @@ extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *,
298 298
299extern int xfs_bioerror_relse(struct xfs_buf *); 299extern int xfs_bioerror_relse(struct xfs_buf *);
300 300
301static inline int xfs_buf_geterror(xfs_buf_t *bp)
302{
303 return bp ? bp->b_error : ENOMEM;
304}
305
306/* Buffer Utility Routines */ 301/* Buffer Utility Routines */
307extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t); 302extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t);
308 303
@@ -387,10 +382,10 @@ xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
387 * Handling of buftargs. 382 * Handling of buftargs.
388 */ 383 */
389extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *, 384extern xfs_buftarg_t *xfs_alloc_buftarg(struct xfs_mount *,
390 struct block_device *, int, const char *); 385 struct block_device *);
391extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); 386extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *);
392extern void xfs_wait_buftarg(xfs_buftarg_t *); 387extern void xfs_wait_buftarg(xfs_buftarg_t *);
393extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); 388extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
394 389
395#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev) 390#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev)
396#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev) 391#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 8752821443be..4654338b03fc 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -812,7 +812,6 @@ xfs_buf_item_init(
812 */ 812 */
813static void 813static void
814xfs_buf_item_log_segment( 814xfs_buf_item_log_segment(
815 struct xfs_buf_log_item *bip,
816 uint first, 815 uint first,
817 uint last, 816 uint last,
818 uint *map) 817 uint *map)
@@ -920,7 +919,7 @@ xfs_buf_item_log(
920 if (end > last) 919 if (end > last)
921 end = last; 920 end = last;
922 921
923 xfs_buf_item_log_segment(bip, first, end, 922 xfs_buf_item_log_segment(first, end,
924 &bip->bli_formats[i].blf_data_map[0]); 923 &bip->bli_formats[i].blf_data_map[0]);
925 924
926 start += bp->b_maps[i].bm_len; 925 start += bp->b_maps[i].bm_len;
@@ -1053,7 +1052,7 @@ xfs_buf_iodone_callbacks(
1053 static ulong lasttime; 1052 static ulong lasttime;
1054 static xfs_buftarg_t *lasttarg; 1053 static xfs_buftarg_t *lasttarg;
1055 1054
1056 if (likely(!xfs_buf_geterror(bp))) 1055 if (likely(!bp->b_error))
1057 goto do_callbacks; 1056 goto do_callbacks;
1058 1057
1059 /* 1058 /*
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 6cc5f6785a77..a514ab616650 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -167,8 +167,8 @@ xfs_da3_node_verify(
167 * we don't know if the node is for and attribute or directory tree, 167 * we don't know if the node is for and attribute or directory tree,
168 * so only fail if the count is outside both bounds 168 * so only fail if the count is outside both bounds
169 */ 169 */
170 if (ichdr.count > mp->m_dir_node_ents && 170 if (ichdr.count > mp->m_dir_geo->node_ents &&
171 ichdr.count > mp->m_attr_node_ents) 171 ichdr.count > mp->m_attr_geo->node_ents)
172 return false; 172 return false;
173 173
174 /* XXX: hash order check? */ 174 /* XXX: hash order check? */
@@ -598,7 +598,7 @@ xfs_da3_root_split(
598 * Set up the new root node. 598 * Set up the new root node.
599 */ 599 */
600 error = xfs_da3_node_create(args, 600 error = xfs_da3_node_create(args,
601 (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0, 601 (args->whichfork == XFS_DATA_FORK) ? args->geo->leafblk : 0,
602 level + 1, &bp, args->whichfork); 602 level + 1, &bp, args->whichfork);
603 if (error) 603 if (error)
604 return error; 604 return error;
@@ -616,10 +616,10 @@ xfs_da3_root_split(
616#ifdef DEBUG 616#ifdef DEBUG
617 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 617 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
618 oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) { 618 oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
619 ASSERT(blk1->blkno >= mp->m_dirleafblk && 619 ASSERT(blk1->blkno >= args->geo->leafblk &&
620 blk1->blkno < mp->m_dirfreeblk); 620 blk1->blkno < args->geo->freeblk);
621 ASSERT(blk2->blkno >= mp->m_dirleafblk && 621 ASSERT(blk2->blkno >= args->geo->leafblk &&
622 blk2->blkno < mp->m_dirfreeblk); 622 blk2->blkno < args->geo->freeblk);
623 } 623 }
624#endif 624#endif
625 625
@@ -663,7 +663,7 @@ xfs_da3_node_split(
663 /* 663 /*
664 * Do we have to split the node? 664 * Do we have to split the node?
665 */ 665 */
666 if (nodehdr.count + newcount > state->node_ents) { 666 if (nodehdr.count + newcount > state->args->geo->node_ents) {
667 /* 667 /*
668 * Allocate a new node, add to the doubly linked chain of 668 * Allocate a new node, add to the doubly linked chain of
669 * nodes, then move some of our excess entries into it. 669 * nodes, then move some of our excess entries into it.
@@ -894,8 +894,8 @@ xfs_da3_node_add(
894 ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count); 894 ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count);
895 ASSERT(newblk->blkno != 0); 895 ASSERT(newblk->blkno != 0);
896 if (state->args->whichfork == XFS_DATA_FORK) 896 if (state->args->whichfork == XFS_DATA_FORK)
897 ASSERT(newblk->blkno >= state->mp->m_dirleafblk && 897 ASSERT(newblk->blkno >= state->args->geo->leafblk &&
898 newblk->blkno < state->mp->m_dirfreeblk); 898 newblk->blkno < state->args->geo->freeblk);
899 899
900 /* 900 /*
901 * We may need to make some room before we insert the new node. 901 * We may need to make some room before we insert the new node.
@@ -1089,14 +1089,15 @@ xfs_da3_root_join(
1089 * that could occur. For dir3 blocks we also need to update the block 1089 * that could occur. For dir3 blocks we also need to update the block
1090 * number in the buffer header. 1090 * number in the buffer header.
1091 */ 1091 */
1092 memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize); 1092 memcpy(root_blk->bp->b_addr, bp->b_addr, args->geo->blksize);
1093 root_blk->bp->b_ops = bp->b_ops; 1093 root_blk->bp->b_ops = bp->b_ops;
1094 xfs_trans_buf_copy_type(root_blk->bp, bp); 1094 xfs_trans_buf_copy_type(root_blk->bp, bp);
1095 if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) { 1095 if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) {
1096 struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr; 1096 struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr;
1097 da3->blkno = cpu_to_be64(root_blk->bp->b_bn); 1097 da3->blkno = cpu_to_be64(root_blk->bp->b_bn);
1098 } 1098 }
1099 xfs_trans_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); 1099 xfs_trans_log_buf(args->trans, root_blk->bp, 0,
1100 args->geo->blksize - 1);
1100 error = xfs_da_shrink_inode(args, child, bp); 1101 error = xfs_da_shrink_inode(args, child, bp);
1101 return(error); 1102 return(error);
1102} 1103}
@@ -1139,7 +1140,7 @@ xfs_da3_node_toosmall(
1139 info = blk->bp->b_addr; 1140 info = blk->bp->b_addr;
1140 node = (xfs_da_intnode_t *)info; 1141 node = (xfs_da_intnode_t *)info;
1141 dp->d_ops->node_hdr_from_disk(&nodehdr, node); 1142 dp->d_ops->node_hdr_from_disk(&nodehdr, node);
1142 if (nodehdr.count > (state->node_ents >> 1)) { 1143 if (nodehdr.count > (state->args->geo->node_ents >> 1)) {
1143 *action = 0; /* blk over 50%, don't try to join */ 1144 *action = 0; /* blk over 50%, don't try to join */
1144 return(0); /* blk over 50%, don't try to join */ 1145 return(0); /* blk over 50%, don't try to join */
1145 } 1146 }
@@ -1176,8 +1177,8 @@ xfs_da3_node_toosmall(
1176 * We prefer coalescing with the lower numbered sibling so as 1177 * We prefer coalescing with the lower numbered sibling so as
1177 * to shrink a directory over time. 1178 * to shrink a directory over time.
1178 */ 1179 */
1179 count = state->node_ents; 1180 count = state->args->geo->node_ents;
1180 count -= state->node_ents >> 2; 1181 count -= state->args->geo->node_ents >> 2;
1181 count -= nodehdr.count; 1182 count -= nodehdr.count;
1182 1183
1183 /* start with smaller blk num */ 1184 /* start with smaller blk num */
@@ -1472,7 +1473,7 @@ xfs_da3_node_lookup_int(
1472 * Descend thru the B-tree searching each level for the right 1473 * Descend thru the B-tree searching each level for the right
1473 * node to use, until the right hashval is found. 1474 * node to use, until the right hashval is found.
1474 */ 1475 */
1475 blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0; 1476 blkno = (args->whichfork == XFS_DATA_FORK)? args->geo->leafblk : 0;
1476 for (blk = &state->path.blk[0], state->path.active = 1; 1477 for (blk = &state->path.blk[0], state->path.active = 1;
1477 state->path.active <= XFS_DA_NODE_MAXDEPTH; 1478 state->path.active <= XFS_DA_NODE_MAXDEPTH;
1478 blk++, state->path.active++) { 1479 blk++, state->path.active++) {
@@ -2090,20 +2091,12 @@ xfs_da_grow_inode(
2090 xfs_dablk_t *new_blkno) 2091 xfs_dablk_t *new_blkno)
2091{ 2092{
2092 xfs_fileoff_t bno; 2093 xfs_fileoff_t bno;
2093 int count;
2094 int error; 2094 int error;
2095 2095
2096 trace_xfs_da_grow_inode(args); 2096 trace_xfs_da_grow_inode(args);
2097 2097
2098 if (args->whichfork == XFS_DATA_FORK) { 2098 bno = args->geo->leafblk;
2099 bno = args->dp->i_mount->m_dirleafblk; 2099 error = xfs_da_grow_inode_int(args, &bno, args->geo->fsbcount);
2100 count = args->dp->i_mount->m_dirblkfsbs;
2101 } else {
2102 bno = 0;
2103 count = 1;
2104 }
2105
2106 error = xfs_da_grow_inode_int(args, &bno, count);
2107 if (!error) 2100 if (!error)
2108 *new_blkno = (xfs_dablk_t)bno; 2101 *new_blkno = (xfs_dablk_t)bno;
2109 return error; 2102 return error;
@@ -2158,7 +2151,7 @@ xfs_da3_swap_lastblock(
2158 w = args->whichfork; 2151 w = args->whichfork;
2159 ASSERT(w == XFS_DATA_FORK); 2152 ASSERT(w == XFS_DATA_FORK);
2160 mp = dp->i_mount; 2153 mp = dp->i_mount;
2161 lastoff = mp->m_dirfreeblk; 2154 lastoff = args->geo->freeblk;
2162 error = xfs_bmap_last_before(tp, dp, &lastoff, w); 2155 error = xfs_bmap_last_before(tp, dp, &lastoff, w);
2163 if (error) 2156 if (error)
2164 return error; 2157 return error;
@@ -2170,15 +2163,15 @@ xfs_da3_swap_lastblock(
2170 /* 2163 /*
2171 * Read the last block in the btree space. 2164 * Read the last block in the btree space.
2172 */ 2165 */
2173 last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs; 2166 last_blkno = (xfs_dablk_t)lastoff - args->geo->fsbcount;
2174 error = xfs_da3_node_read(tp, dp, last_blkno, -1, &last_buf, w); 2167 error = xfs_da3_node_read(tp, dp, last_blkno, -1, &last_buf, w);
2175 if (error) 2168 if (error)
2176 return error; 2169 return error;
2177 /* 2170 /*
2178 * Copy the last block into the dead buffer and log it. 2171 * Copy the last block into the dead buffer and log it.
2179 */ 2172 */
2180 memcpy(dead_buf->b_addr, last_buf->b_addr, mp->m_dirblksize); 2173 memcpy(dead_buf->b_addr, last_buf->b_addr, args->geo->blksize);
2181 xfs_trans_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1); 2174 xfs_trans_log_buf(tp, dead_buf, 0, args->geo->blksize - 1);
2182 dead_info = dead_buf->b_addr; 2175 dead_info = dead_buf->b_addr;
2183 /* 2176 /*
2184 * Get values from the moved block. 2177 * Get values from the moved block.
@@ -2247,7 +2240,7 @@ xfs_da3_swap_lastblock(
2247 sizeof(sib_info->back))); 2240 sizeof(sib_info->back)));
2248 sib_buf = NULL; 2241 sib_buf = NULL;
2249 } 2242 }
2250 par_blkno = mp->m_dirleafblk; 2243 par_blkno = args->geo->leafblk;
2251 level = -1; 2244 level = -1;
2252 /* 2245 /*
2253 * Walk down the tree looking for the parent of the moved block. 2246 * Walk down the tree looking for the parent of the moved block.
@@ -2357,10 +2350,7 @@ xfs_da_shrink_inode(
2357 w = args->whichfork; 2350 w = args->whichfork;
2358 tp = args->trans; 2351 tp = args->trans;
2359 mp = dp->i_mount; 2352 mp = dp->i_mount;
2360 if (w == XFS_DATA_FORK) 2353 count = args->geo->fsbcount;
2361 count = mp->m_dirblkfsbs;
2362 else
2363 count = 1;
2364 for (;;) { 2354 for (;;) {
2365 /* 2355 /*
2366 * Remove extents. If we get ENOSPC for a dir we have to move 2356 * Remove extents. If we get ENOSPC for a dir we have to move
@@ -2462,7 +2452,6 @@ xfs_buf_map_from_irec(
2462 */ 2452 */
2463static int 2453static int
2464xfs_dabuf_map( 2454xfs_dabuf_map(
2465 struct xfs_trans *trans,
2466 struct xfs_inode *dp, 2455 struct xfs_inode *dp,
2467 xfs_dablk_t bno, 2456 xfs_dablk_t bno,
2468 xfs_daddr_t mappedbno, 2457 xfs_daddr_t mappedbno,
@@ -2480,7 +2469,10 @@ xfs_dabuf_map(
2480 ASSERT(map && *map); 2469 ASSERT(map && *map);
2481 ASSERT(*nmaps == 1); 2470 ASSERT(*nmaps == 1);
2482 2471
2483 nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; 2472 if (whichfork == XFS_DATA_FORK)
2473 nfsb = mp->m_dir_geo->fsbcount;
2474 else
2475 nfsb = mp->m_attr_geo->fsbcount;
2484 2476
2485 /* 2477 /*
2486 * Caller doesn't have a mapping. -2 means don't complain 2478 * Caller doesn't have a mapping. -2 means don't complain
@@ -2558,7 +2550,7 @@ xfs_da_get_buf(
2558 *bpp = NULL; 2550 *bpp = NULL;
2559 mapp = &map; 2551 mapp = &map;
2560 nmap = 1; 2552 nmap = 1;
2561 error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, 2553 error = xfs_dabuf_map(dp, bno, mappedbno, whichfork,
2562 &mapp, &nmap); 2554 &mapp, &nmap);
2563 if (error) { 2555 if (error) {
2564 /* mapping a hole is not an error, but we don't continue */ 2556 /* mapping a hole is not an error, but we don't continue */
@@ -2606,7 +2598,7 @@ xfs_da_read_buf(
2606 *bpp = NULL; 2598 *bpp = NULL;
2607 mapp = &map; 2599 mapp = &map;
2608 nmap = 1; 2600 nmap = 1;
2609 error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, 2601 error = xfs_dabuf_map(dp, bno, mappedbno, whichfork,
2610 &mapp, &nmap); 2602 &mapp, &nmap);
2611 if (error) { 2603 if (error) {
2612 /* mapping a hole is not an error, but we don't continue */ 2604 /* mapping a hole is not an error, but we don't continue */
@@ -2625,47 +2617,6 @@ xfs_da_read_buf(
2625 xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF); 2617 xfs_buf_set_ref(bp, XFS_ATTR_BTREE_REF);
2626 else 2618 else
2627 xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF); 2619 xfs_buf_set_ref(bp, XFS_DIR_BTREE_REF);
2628
2629 /*
2630 * This verification code will be moved to a CRC verification callback
2631 * function so just leave it here unchanged until then.
2632 */
2633 {
2634 xfs_dir2_data_hdr_t *hdr = bp->b_addr;
2635 xfs_dir2_free_t *free = bp->b_addr;
2636 xfs_da_blkinfo_t *info = bp->b_addr;
2637 uint magic, magic1;
2638 struct xfs_mount *mp = dp->i_mount;
2639
2640 magic = be16_to_cpu(info->magic);
2641 magic1 = be32_to_cpu(hdr->magic);
2642 if (unlikely(
2643 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
2644 (magic != XFS_DA3_NODE_MAGIC) &&
2645 (magic != XFS_ATTR_LEAF_MAGIC) &&
2646 (magic != XFS_ATTR3_LEAF_MAGIC) &&
2647 (magic != XFS_DIR2_LEAF1_MAGIC) &&
2648 (magic != XFS_DIR3_LEAF1_MAGIC) &&
2649 (magic != XFS_DIR2_LEAFN_MAGIC) &&
2650 (magic != XFS_DIR3_LEAFN_MAGIC) &&
2651 (magic1 != XFS_DIR2_BLOCK_MAGIC) &&
2652 (magic1 != XFS_DIR3_BLOCK_MAGIC) &&
2653 (magic1 != XFS_DIR2_DATA_MAGIC) &&
2654 (magic1 != XFS_DIR3_DATA_MAGIC) &&
2655 (free->hdr.magic !=
2656 cpu_to_be32(XFS_DIR2_FREE_MAGIC)) &&
2657 (free->hdr.magic !=
2658 cpu_to_be32(XFS_DIR3_FREE_MAGIC)),
2659 mp, XFS_ERRTAG_DA_READ_BUF,
2660 XFS_RANDOM_DA_READ_BUF))) {
2661 trace_xfs_da_btree_corrupt(bp, _RET_IP_);
2662 XFS_CORRUPTION_ERROR("xfs_da_do_buf(2)",
2663 XFS_ERRLEVEL_LOW, mp, info);
2664 error = XFS_ERROR(EFSCORRUPTED);
2665 xfs_trans_brelse(trans, bp);
2666 goto out_free;
2667 }
2668 }
2669 *bpp = bp; 2620 *bpp = bp;
2670out_free: 2621out_free:
2671 if (mapp != &map) 2622 if (mapp != &map)
@@ -2679,7 +2630,6 @@ out_free:
2679 */ 2630 */
2680xfs_daddr_t 2631xfs_daddr_t
2681xfs_da_reada_buf( 2632xfs_da_reada_buf(
2682 struct xfs_trans *trans,
2683 struct xfs_inode *dp, 2633 struct xfs_inode *dp,
2684 xfs_dablk_t bno, 2634 xfs_dablk_t bno,
2685 xfs_daddr_t mappedbno, 2635 xfs_daddr_t mappedbno,
@@ -2693,7 +2643,7 @@ xfs_da_reada_buf(
2693 2643
2694 mapp = &map; 2644 mapp = &map;
2695 nmap = 1; 2645 nmap = 1;
2696 error = xfs_dabuf_map(trans, dp, bno, mappedbno, whichfork, 2646 error = xfs_dabuf_map(dp, bno, mappedbno, whichfork,
2697 &mapp, &nmap); 2647 &mapp, &nmap);
2698 if (error) { 2648 if (error) {
2699 /* mapping a hole is not an error, but we don't continue */ 2649 /* mapping a hole is not an error, but we don't continue */
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 201c6091d26a..6e153e399a77 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -25,6 +25,23 @@ struct xfs_trans;
25struct zone; 25struct zone;
26struct xfs_dir_ops; 26struct xfs_dir_ops;
27 27
28/*
29 * Directory/attribute geometry information. There will be one of these for each
30 * data fork type, and it will be passed around via the xfs_da_args. Global
31 * structures will be attached to the xfs_mount.
32 */
33struct xfs_da_geometry {
34 int blksize; /* da block size in bytes */
35 int fsbcount; /* da block size in filesystem blocks */
36 uint8_t fsblog; /* log2 of _filesystem_ block size */
37 uint8_t blklog; /* log2 of da block size */
38 uint node_ents; /* # of entries in a danode */
39 int magicpct; /* 37% of block size in bytes */
40 xfs_dablk_t datablk; /* blockno of dir data v2 */
41 xfs_dablk_t leafblk; /* blockno of leaf data v2 */
42 xfs_dablk_t freeblk; /* blockno of free data v2 */
43};
44
28/*======================================================================== 45/*========================================================================
29 * Btree searching and modification structure definitions. 46 * Btree searching and modification structure definitions.
30 *========================================================================*/ 47 *========================================================================*/
@@ -42,6 +59,7 @@ enum xfs_dacmp {
42 * Structure to ease passing around component names. 59 * Structure to ease passing around component names.
43 */ 60 */
44typedef struct xfs_da_args { 61typedef struct xfs_da_args {
62 struct xfs_da_geometry *geo; /* da block geometry */
45 const __uint8_t *name; /* string (maybe not NULL terminated) */ 63 const __uint8_t *name; /* string (maybe not NULL terminated) */
46 int namelen; /* length of string (maybe no NULL) */ 64 int namelen; /* length of string (maybe no NULL) */
47 __uint8_t filetype; /* filetype of inode for directories */ 65 __uint8_t filetype; /* filetype of inode for directories */
@@ -110,8 +128,6 @@ typedef struct xfs_da_state_path {
110typedef struct xfs_da_state { 128typedef struct xfs_da_state {
111 xfs_da_args_t *args; /* filename arguments */ 129 xfs_da_args_t *args; /* filename arguments */
112 struct xfs_mount *mp; /* filesystem mount point */ 130 struct xfs_mount *mp; /* filesystem mount point */
113 unsigned int blocksize; /* logical block size */
114 unsigned int node_ents; /* how many entries in danode */
115 xfs_da_state_path_t path; /* search/split paths */ 131 xfs_da_state_path_t path; /* search/split paths */
116 xfs_da_state_path_t altpath; /* alternate path for join */ 132 xfs_da_state_path_t altpath; /* alternate path for join */
117 unsigned char inleaf; /* insert into 1->lf, 0->splf */ 133 unsigned char inleaf; /* insert into 1->lf, 0->splf */
@@ -185,9 +201,9 @@ int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp,
185 xfs_dablk_t bno, xfs_daddr_t mappedbno, 201 xfs_dablk_t bno, xfs_daddr_t mappedbno,
186 struct xfs_buf **bpp, int whichfork, 202 struct xfs_buf **bpp, int whichfork,
187 const struct xfs_buf_ops *ops); 203 const struct xfs_buf_ops *ops);
188xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, 204xfs_daddr_t xfs_da_reada_buf(struct xfs_inode *dp, xfs_dablk_t bno,
189 xfs_dablk_t bno, xfs_daddr_t mapped_bno, 205 xfs_daddr_t mapped_bno, int whichfork,
190 int whichfork, const struct xfs_buf_ops *ops); 206 const struct xfs_buf_ops *ops);
191int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, 207int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
192 struct xfs_buf *dead_buf); 208 struct xfs_buf *dead_buf);
193 209
diff --git a/fs/xfs/xfs_da_format.c b/fs/xfs/xfs_da_format.c
index e6c83e1fbc8a..c9aee52a37e2 100644
--- a/fs/xfs/xfs_da_format.c
+++ b/fs/xfs/xfs_da_format.c
@@ -26,8 +26,10 @@
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_mount.h" 27#include "xfs_mount.h"
28#include "xfs_da_format.h" 28#include "xfs_da_format.h"
29#include "xfs_da_btree.h"
29#include "xfs_inode.h" 30#include "xfs_inode.h"
30#include "xfs_dir2.h" 31#include "xfs_dir2.h"
32#include "xfs_dir2_priv.h"
31 33
32/* 34/*
33 * Shortform directory ops 35 * Shortform directory ops
@@ -425,9 +427,9 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
425 * Directory Leaf block operations 427 * Directory Leaf block operations
426 */ 428 */
427static int 429static int
428xfs_dir2_max_leaf_ents(struct xfs_mount *mp) 430xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
429{ 431{
430 return (mp->m_dirblksize - sizeof(struct xfs_dir2_leaf_hdr)) / 432 return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) /
431 (uint)sizeof(struct xfs_dir2_leaf_entry); 433 (uint)sizeof(struct xfs_dir2_leaf_entry);
432} 434}
433 435
@@ -438,9 +440,9 @@ xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
438} 440}
439 441
440static int 442static int
441xfs_dir3_max_leaf_ents(struct xfs_mount *mp) 443xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
442{ 444{
443 return (mp->m_dirblksize - sizeof(struct xfs_dir3_leaf_hdr)) / 445 return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) /
444 (uint)sizeof(struct xfs_dir2_leaf_entry); 446 (uint)sizeof(struct xfs_dir2_leaf_entry);
445} 447}
446 448
@@ -591,9 +593,9 @@ xfs_da3_node_hdr_to_disk(
591 * Directory free space block operations 593 * Directory free space block operations
592 */ 594 */
593static int 595static int
594xfs_dir2_free_max_bests(struct xfs_mount *mp) 596xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
595{ 597{
596 return (mp->m_dirblksize - sizeof(struct xfs_dir2_free_hdr)) / 598 return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) /
597 sizeof(xfs_dir2_data_off_t); 599 sizeof(xfs_dir2_data_off_t);
598} 600}
599 601
@@ -607,24 +609,25 @@ xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
607 * Convert data space db to the corresponding free db. 609 * Convert data space db to the corresponding free db.
608 */ 610 */
609static xfs_dir2_db_t 611static xfs_dir2_db_t
610xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) 612xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
611{ 613{
612 return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir2_free_max_bests(mp); 614 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
615 (db / xfs_dir2_free_max_bests(geo));
613} 616}
614 617
615/* 618/*
616 * Convert data space db to the corresponding index in a free db. 619 * Convert data space db to the corresponding index in a free db.
617 */ 620 */
618static int 621static int
619xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) 622xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
620{ 623{
621 return db % xfs_dir2_free_max_bests(mp); 624 return db % xfs_dir2_free_max_bests(geo);
622} 625}
623 626
624static int 627static int
625xfs_dir3_free_max_bests(struct xfs_mount *mp) 628xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
626{ 629{
627 return (mp->m_dirblksize - sizeof(struct xfs_dir3_free_hdr)) / 630 return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) /
628 sizeof(xfs_dir2_data_off_t); 631 sizeof(xfs_dir2_data_off_t);
629} 632}
630 633
@@ -638,18 +641,19 @@ xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
638 * Convert data space db to the corresponding free db. 641 * Convert data space db to the corresponding free db.
639 */ 642 */
640static xfs_dir2_db_t 643static xfs_dir2_db_t
641xfs_dir3_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) 644xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
642{ 645{
643 return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir3_free_max_bests(mp); 646 return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
647 (db / xfs_dir3_free_max_bests(geo));
644} 648}
645 649
646/* 650/*
647 * Convert data space db to the corresponding index in a free db. 651 * Convert data space db to the corresponding index in a free db.
648 */ 652 */
649static int 653static int
650xfs_dir3_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) 654xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
651{ 655{
652 return db % xfs_dir3_free_max_bests(mp); 656 return db % xfs_dir3_free_max_bests(geo);
653} 657}
654 658
655static void 659static void
diff --git a/fs/xfs/xfs_da_format.h b/fs/xfs/xfs_da_format.h
index a19d3f8f639c..0a49b0286372 100644
--- a/fs/xfs/xfs_da_format.h
+++ b/fs/xfs/xfs_da_format.h
@@ -19,10 +19,6 @@
19#ifndef __XFS_DA_FORMAT_H__ 19#ifndef __XFS_DA_FORMAT_H__
20#define __XFS_DA_FORMAT_H__ 20#define __XFS_DA_FORMAT_H__
21 21
22/*========================================================================
23 * Directory Structure when greater than XFS_LBSIZE(mp) bytes.
24 *========================================================================*/
25
26/* 22/*
27 * This structure is common to both leaf nodes and non-leaf nodes in the Btree. 23 * This structure is common to both leaf nodes and non-leaf nodes in the Btree.
28 * 24 *
@@ -122,8 +118,6 @@ struct xfs_da3_icnode_hdr {
122 __uint16_t level; 118 __uint16_t level;
123}; 119};
124 120
125#define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize
126
127/* 121/*
128 * Directory version 2. 122 * Directory version 2.
129 * 123 *
@@ -330,8 +324,6 @@ xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
330#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG)) 324#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
331#define XFS_DIR2_DATA_SPACE 0 325#define XFS_DIR2_DATA_SPACE 0
332#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) 326#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
333#define XFS_DIR2_DATA_FIRSTDB(mp) \
334 xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
335 327
336/* 328/*
337 * Describe a free area in the data block. 329 * Describe a free area in the data block.
@@ -456,8 +448,6 @@ xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
456 */ 448 */
457#define XFS_DIR2_LEAF_SPACE 1 449#define XFS_DIR2_LEAF_SPACE 1
458#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE) 450#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
459#define XFS_DIR2_LEAF_FIRSTDB(mp) \
460 xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
461 451
462/* 452/*
463 * Leaf block header. 453 * Leaf block header.
@@ -514,17 +504,6 @@ struct xfs_dir3_leaf {
514#define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc) 504#define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc)
515 505
516/* 506/*
517 * Get address of the bestcount field in the single-leaf block.
518 */
519static inline struct xfs_dir2_leaf_tail *
520xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
521{
522 return (struct xfs_dir2_leaf_tail *)
523 ((char *)lp + mp->m_dirblksize -
524 sizeof(struct xfs_dir2_leaf_tail));
525}
526
527/*
528 * Get address of the bests array in the single-leaf block. 507 * Get address of the bests array in the single-leaf block.
529 */ 508 */
530static inline __be16 * 509static inline __be16 *
@@ -534,123 +513,6 @@ xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
534} 513}
535 514
536/* 515/*
537 * DB blocks here are logical directory block numbers, not filesystem blocks.
538 */
539
540/*
541 * Convert dataptr to byte in file space
542 */
543static inline xfs_dir2_off_t
544xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
545{
546 return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
547}
548
549/*
550 * Convert byte in file space to dataptr. It had better be aligned.
551 */
552static inline xfs_dir2_dataptr_t
553xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
554{
555 return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
556}
557
558/*
559 * Convert byte in space to (DB) block
560 */
561static inline xfs_dir2_db_t
562xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
563{
564 return (xfs_dir2_db_t)
565 (by >> (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog));
566}
567
568/*
569 * Convert dataptr to a block number
570 */
571static inline xfs_dir2_db_t
572xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
573{
574 return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp));
575}
576
577/*
578 * Convert byte in space to offset in a block
579 */
580static inline xfs_dir2_data_aoff_t
581xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
582{
583 return (xfs_dir2_data_aoff_t)(by &
584 ((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) - 1));
585}
586
587/*
588 * Convert dataptr to a byte offset in a block
589 */
590static inline xfs_dir2_data_aoff_t
591xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
592{
593 return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp));
594}
595
596/*
597 * Convert block and offset to byte in space
598 */
599static inline xfs_dir2_off_t
600xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
601 xfs_dir2_data_aoff_t o)
602{
603 return ((xfs_dir2_off_t)db <<
604 (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) + o;
605}
606
607/*
608 * Convert block (DB) to block (dablk)
609 */
610static inline xfs_dablk_t
611xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
612{
613 return (xfs_dablk_t)(db << mp->m_sb.sb_dirblklog);
614}
615
616/*
617 * Convert byte in space to (DA) block
618 */
619static inline xfs_dablk_t
620xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
621{
622 return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by));
623}
624
625/*
626 * Convert block and offset to dataptr
627 */
628static inline xfs_dir2_dataptr_t
629xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
630 xfs_dir2_data_aoff_t o)
631{
632 return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o));
633}
634
635/*
636 * Convert block (dablk) to block (DB)
637 */
638static inline xfs_dir2_db_t
639xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
640{
641 return (xfs_dir2_db_t)(da >> mp->m_sb.sb_dirblklog);
642}
643
644/*
645 * Convert block (dablk) to byte offset in space
646 */
647static inline xfs_dir2_off_t
648xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
649{
650 return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0);
651}
652
653/*
654 * Free space block defintions for the node format. 516 * Free space block defintions for the node format.
655 */ 517 */
656 518
@@ -659,8 +521,6 @@ xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
659 */ 521 */
660#define XFS_DIR2_FREE_SPACE 2 522#define XFS_DIR2_FREE_SPACE 2
661#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE) 523#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
662#define XFS_DIR2_FREE_FIRSTDB(mp) \
663 xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
664 524
665typedef struct xfs_dir2_free_hdr { 525typedef struct xfs_dir2_free_hdr {
666 __be32 magic; /* XFS_DIR2_FREE_MAGIC */ 526 __be32 magic; /* XFS_DIR2_FREE_MAGIC */
@@ -736,16 +596,6 @@ typedef struct xfs_dir2_block_tail {
736} xfs_dir2_block_tail_t; 596} xfs_dir2_block_tail_t;
737 597
738/* 598/*
739 * Pointer to the leaf header embedded in a data block (1-block format)
740 */
741static inline struct xfs_dir2_block_tail *
742xfs_dir2_block_tail_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr)
743{
744 return ((struct xfs_dir2_block_tail *)
745 ((char *)hdr + mp->m_dirblksize)) - 1;
746}
747
748/*
749 * Pointer to the leaf entries embedded in a data block (1-block format) 599 * Pointer to the leaf entries embedded in a data block (1-block format)
750 */ 600 */
751static inline struct xfs_dir2_leaf_entry * 601static inline struct xfs_dir2_leaf_entry *
@@ -764,10 +614,6 @@ xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
764 * of an attribute name may not be unique, we may have duplicate keys. The 614 * of an attribute name may not be unique, we may have duplicate keys. The
765 * internal links in the Btree are logical block offsets into the file. 615 * internal links in the Btree are logical block offsets into the file.
766 * 616 *
767 *========================================================================
768 * Attribute structure when equal to XFS_LBSIZE(mp) bytes.
769 *========================================================================
770 *
771 * Struct leaf_entry's are packed from the top. Name/values grow from the 617 * Struct leaf_entry's are packed from the top. Name/values grow from the
772 * bottom but are not packed. The freemap contains run-length-encoded entries 618 * bottom but are not packed. The freemap contains run-length-encoded entries
773 * for the free bytes after the leaf_entry's, but only the N largest such, 619 * for the free bytes after the leaf_entry's, but only the N largest such,
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index fda46253966a..79670cda48ae 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -85,38 +85,74 @@ static struct xfs_nameops xfs_ascii_ci_nameops = {
85 .compname = xfs_ascii_ci_compname, 85 .compname = xfs_ascii_ci_compname,
86}; 86};
87 87
88void 88int
89xfs_dir_mount( 89xfs_da_mount(
90 xfs_mount_t *mp) 90 struct xfs_mount *mp)
91{ 91{
92 int nodehdr_size; 92 struct xfs_da_geometry *dageo;
93 int nodehdr_size;
93 94
94 95
95 ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); 96 ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
96 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= 97 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=
97 XFS_MAX_BLOCKSIZE); 98 XFS_MAX_BLOCKSIZE);
98 99
99 mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL); 100 mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
100 mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL); 101 mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL);
101 102
102 mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
103 mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog;
104 mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp));
105 mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp));
106 mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp));
107
108 nodehdr_size = mp->m_dir_inode_ops->node_hdr_size; 103 nodehdr_size = mp->m_dir_inode_ops->node_hdr_size;
109 mp->m_attr_node_ents = (mp->m_sb.sb_blocksize - nodehdr_size) / 104 mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
105 KM_SLEEP | KM_MAYFAIL);
106 mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
107 KM_SLEEP | KM_MAYFAIL);
108 if (!mp->m_dir_geo || !mp->m_attr_geo) {
109 kmem_free(mp->m_dir_geo);
110 kmem_free(mp->m_attr_geo);
111 return ENOMEM;
112 }
113
114 /* set up directory geometry */
115 dageo = mp->m_dir_geo;
116 dageo->blklog = mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog;
117 dageo->fsblog = mp->m_sb.sb_blocklog;
118 dageo->blksize = 1 << dageo->blklog;
119 dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
120
121 /*
122 * Now we've set up the block conversion variables, we can calculate the
123 * segment block constants using the geometry structure.
124 */
125 dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET);
126 dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET);
127 dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET);
128 dageo->node_ents = (dageo->blksize - nodehdr_size) /
110 (uint)sizeof(xfs_da_node_entry_t); 129 (uint)sizeof(xfs_da_node_entry_t);
111 mp->m_dir_node_ents = (mp->m_dirblksize - nodehdr_size) / 130 dageo->magicpct = (dageo->blksize * 37) / 100;
131
132 /* set up attribute geometry - single fsb only */
133 dageo = mp->m_attr_geo;
134 dageo->blklog = mp->m_sb.sb_blocklog;
135 dageo->fsblog = mp->m_sb.sb_blocklog;
136 dageo->blksize = 1 << dageo->blklog;
137 dageo->fsbcount = 1;
138 dageo->node_ents = (dageo->blksize - nodehdr_size) /
112 (uint)sizeof(xfs_da_node_entry_t); 139 (uint)sizeof(xfs_da_node_entry_t);
140 dageo->magicpct = (dageo->blksize * 37) / 100;
113 141
114 mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100;
115 if (xfs_sb_version_hasasciici(&mp->m_sb)) 142 if (xfs_sb_version_hasasciici(&mp->m_sb))
116 mp->m_dirnameops = &xfs_ascii_ci_nameops; 143 mp->m_dirnameops = &xfs_ascii_ci_nameops;
117 else 144 else
118 mp->m_dirnameops = &xfs_default_nameops; 145 mp->m_dirnameops = &xfs_default_nameops;
119 146
147 return 0;
148}
149
150void
151xfs_da_unmount(
152 struct xfs_mount *mp)
153{
154 kmem_free(mp->m_dir_geo);
155 kmem_free(mp->m_attr_geo);
120} 156}
121 157
122/* 158/*
@@ -192,6 +228,7 @@ xfs_dir_init(
192 if (!args) 228 if (!args)
193 return ENOMEM; 229 return ENOMEM;
194 230
231 args->geo = dp->i_mount->m_dir_geo;
195 args->dp = dp; 232 args->dp = dp;
196 args->trans = tp; 233 args->trans = tp;
197 error = xfs_dir2_sf_create(args, pdp->i_ino); 234 error = xfs_dir2_sf_create(args, pdp->i_ino);
@@ -226,6 +263,7 @@ xfs_dir_createname(
226 if (!args) 263 if (!args)
227 return ENOMEM; 264 return ENOMEM;
228 265
266 args->geo = dp->i_mount->m_dir_geo;
229 args->name = name->name; 267 args->name = name->name;
230 args->namelen = name->len; 268 args->namelen = name->len;
231 args->filetype = name->type; 269 args->filetype = name->type;
@@ -244,7 +282,7 @@ xfs_dir_createname(
244 goto out_free; 282 goto out_free;
245 } 283 }
246 284
247 rval = xfs_dir2_isblock(tp, dp, &v); 285 rval = xfs_dir2_isblock(args, &v);
248 if (rval) 286 if (rval)
249 goto out_free; 287 goto out_free;
250 if (v) { 288 if (v) {
@@ -252,7 +290,7 @@ xfs_dir_createname(
252 goto out_free; 290 goto out_free;
253 } 291 }
254 292
255 rval = xfs_dir2_isleaf(tp, dp, &v); 293 rval = xfs_dir2_isleaf(args, &v);
256 if (rval) 294 if (rval)
257 goto out_free; 295 goto out_free;
258 if (v) 296 if (v)
@@ -320,6 +358,7 @@ xfs_dir_lookup(
320 * annotations into the reclaim path for the ilock. 358 * annotations into the reclaim path for the ilock.
321 */ 359 */
322 args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); 360 args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
361 args->geo = dp->i_mount->m_dir_geo;
323 args->name = name->name; 362 args->name = name->name;
324 args->namelen = name->len; 363 args->namelen = name->len;
325 args->filetype = name->type; 364 args->filetype = name->type;
@@ -336,7 +375,7 @@ xfs_dir_lookup(
336 goto out_check_rval; 375 goto out_check_rval;
337 } 376 }
338 377
339 rval = xfs_dir2_isblock(tp, dp, &v); 378 rval = xfs_dir2_isblock(args, &v);
340 if (rval) 379 if (rval)
341 goto out_free; 380 goto out_free;
342 if (v) { 381 if (v) {
@@ -344,7 +383,7 @@ xfs_dir_lookup(
344 goto out_check_rval; 383 goto out_check_rval;
345 } 384 }
346 385
347 rval = xfs_dir2_isleaf(tp, dp, &v); 386 rval = xfs_dir2_isleaf(args, &v);
348 if (rval) 387 if (rval)
349 goto out_free; 388 goto out_free;
350 if (v) 389 if (v)
@@ -391,6 +430,7 @@ xfs_dir_removename(
391 if (!args) 430 if (!args)
392 return ENOMEM; 431 return ENOMEM;
393 432
433 args->geo = dp->i_mount->m_dir_geo;
394 args->name = name->name; 434 args->name = name->name;
395 args->namelen = name->len; 435 args->namelen = name->len;
396 args->filetype = name->type; 436 args->filetype = name->type;
@@ -408,7 +448,7 @@ xfs_dir_removename(
408 goto out_free; 448 goto out_free;
409 } 449 }
410 450
411 rval = xfs_dir2_isblock(tp, dp, &v); 451 rval = xfs_dir2_isblock(args, &v);
412 if (rval) 452 if (rval)
413 goto out_free; 453 goto out_free;
414 if (v) { 454 if (v) {
@@ -416,7 +456,7 @@ xfs_dir_removename(
416 goto out_free; 456 goto out_free;
417 } 457 }
418 458
419 rval = xfs_dir2_isleaf(tp, dp, &v); 459 rval = xfs_dir2_isleaf(args, &v);
420 if (rval) 460 if (rval)
421 goto out_free; 461 goto out_free;
422 if (v) 462 if (v)
@@ -455,6 +495,7 @@ xfs_dir_replace(
455 if (!args) 495 if (!args)
456 return ENOMEM; 496 return ENOMEM;
457 497
498 args->geo = dp->i_mount->m_dir_geo;
458 args->name = name->name; 499 args->name = name->name;
459 args->namelen = name->len; 500 args->namelen = name->len;
460 args->filetype = name->type; 501 args->filetype = name->type;
@@ -472,7 +513,7 @@ xfs_dir_replace(
472 goto out_free; 513 goto out_free;
473 } 514 }
474 515
475 rval = xfs_dir2_isblock(tp, dp, &v); 516 rval = xfs_dir2_isblock(args, &v);
476 if (rval) 517 if (rval)
477 goto out_free; 518 goto out_free;
478 if (v) { 519 if (v) {
@@ -480,7 +521,7 @@ xfs_dir_replace(
480 goto out_free; 521 goto out_free;
481 } 522 }
482 523
483 rval = xfs_dir2_isleaf(tp, dp, &v); 524 rval = xfs_dir2_isleaf(args, &v);
484 if (rval) 525 if (rval)
485 goto out_free; 526 goto out_free;
486 if (v) 527 if (v)
@@ -516,6 +557,7 @@ xfs_dir_canenter(
516 if (!args) 557 if (!args)
517 return ENOMEM; 558 return ENOMEM;
518 559
560 args->geo = dp->i_mount->m_dir_geo;
519 args->name = name->name; 561 args->name = name->name;
520 args->namelen = name->len; 562 args->namelen = name->len;
521 args->filetype = name->type; 563 args->filetype = name->type;
@@ -531,7 +573,7 @@ xfs_dir_canenter(
531 goto out_free; 573 goto out_free;
532 } 574 }
533 575
534 rval = xfs_dir2_isblock(tp, dp, &v); 576 rval = xfs_dir2_isblock(args, &v);
535 if (rval) 577 if (rval)
536 goto out_free; 578 goto out_free;
537 if (v) { 579 if (v) {
@@ -539,7 +581,7 @@ xfs_dir_canenter(
539 goto out_free; 581 goto out_free;
540 } 582 }
541 583
542 rval = xfs_dir2_isleaf(tp, dp, &v); 584 rval = xfs_dir2_isleaf(args, &v);
543 if (rval) 585 if (rval)
544 goto out_free; 586 goto out_free;
545 if (v) 587 if (v)
@@ -579,13 +621,13 @@ xfs_dir2_grow_inode(
579 * Set lowest possible block in the space requested. 621 * Set lowest possible block in the space requested.
580 */ 622 */
581 bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE); 623 bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE);
582 count = mp->m_dirblkfsbs; 624 count = args->geo->fsbcount;
583 625
584 error = xfs_da_grow_inode_int(args, &bno, count); 626 error = xfs_da_grow_inode_int(args, &bno, count);
585 if (error) 627 if (error)
586 return error; 628 return error;
587 629
588 *dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno); 630 *dbp = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)bno);
589 631
590 /* 632 /*
591 * Update file's size if this is the data space and it grew. 633 * Update file's size if this is the data space and it grew.
@@ -607,19 +649,16 @@ xfs_dir2_grow_inode(
607 */ 649 */
608int 650int
609xfs_dir2_isblock( 651xfs_dir2_isblock(
610 xfs_trans_t *tp, 652 struct xfs_da_args *args,
611 xfs_inode_t *dp, 653 int *vp) /* out: 1 is block, 0 is not block */
612 int *vp) /* out: 1 is block, 0 is not block */
613{ 654{
614 xfs_fileoff_t last; /* last file offset */ 655 xfs_fileoff_t last; /* last file offset */
615 xfs_mount_t *mp; 656 int rval;
616 int rval;
617 657
618 mp = dp->i_mount; 658 if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
619 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
620 return rval; 659 return rval;
621 rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; 660 rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize;
622 ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); 661 ASSERT(rval == 0 || args->dp->i_d.di_size == args->geo->blksize);
623 *vp = rval; 662 *vp = rval;
624 return 0; 663 return 0;
625} 664}
@@ -629,18 +668,15 @@ xfs_dir2_isblock(
629 */ 668 */
630int 669int
631xfs_dir2_isleaf( 670xfs_dir2_isleaf(
632 xfs_trans_t *tp, 671 struct xfs_da_args *args,
633 xfs_inode_t *dp, 672 int *vp) /* out: 1 is block, 0 is not block */
634 int *vp) /* out: 1 is leaf, 0 is not leaf */
635{ 673{
636 xfs_fileoff_t last; /* last file offset */ 674 xfs_fileoff_t last; /* last file offset */
637 xfs_mount_t *mp; 675 int rval;
638 int rval;
639 676
640 mp = dp->i_mount; 677 if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
641 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
642 return rval; 678 return rval;
643 *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); 679 *vp = last == args->geo->leafblk + args->geo->fsbcount;
644 return 0; 680 return 0;
645} 681}
646 682
@@ -668,11 +704,11 @@ xfs_dir2_shrink_inode(
668 dp = args->dp; 704 dp = args->dp;
669 mp = dp->i_mount; 705 mp = dp->i_mount;
670 tp = args->trans; 706 tp = args->trans;
671 da = xfs_dir2_db_to_da(mp, db); 707 da = xfs_dir2_db_to_da(args->geo, db);
672 /* 708 /*
673 * Unmap the fsblock(s). 709 * Unmap the fsblock(s).
674 */ 710 */
675 if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, 711 if ((error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount,
676 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, 712 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
677 &done))) { 713 &done))) {
678 /* 714 /*
@@ -699,12 +735,12 @@ xfs_dir2_shrink_inode(
699 /* 735 /*
700 * If it's not a data block, we're done. 736 * If it's not a data block, we're done.
701 */ 737 */
702 if (db >= XFS_DIR2_LEAF_FIRSTDB(mp)) 738 if (db >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET))
703 return 0; 739 return 0;
704 /* 740 /*
705 * If the block isn't the last one in the directory, we're done. 741 * If the block isn't the last one in the directory, we're done.
706 */ 742 */
707 if (dp->i_d.di_size > xfs_dir2_db_off_to_byte(mp, db + 1, 0)) 743 if (dp->i_d.di_size > xfs_dir2_db_off_to_byte(args->geo, db + 1, 0))
708 return 0; 744 return 0;
709 bno = da; 745 bno = da;
710 if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) { 746 if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) {
@@ -713,7 +749,7 @@ xfs_dir2_shrink_inode(
713 */ 749 */
714 return error; 750 return error;
715 } 751 }
716 if (db == mp->m_dirdatablk) 752 if (db == args->geo->datablk)
717 ASSERT(bno == 0); 753 ASSERT(bno == 0);
718 else 754 else
719 ASSERT(bno > 0); 755 ASSERT(bno > 0);
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index cec70e0781ab..c8e86b0b5e99 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -80,7 +80,7 @@ struct xfs_dir_ops {
80 struct xfs_dir3_icleaf_hdr *from); 80 struct xfs_dir3_icleaf_hdr *from);
81 void (*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to, 81 void (*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to,
82 struct xfs_dir2_leaf *from); 82 struct xfs_dir2_leaf *from);
83 int (*leaf_max_ents)(struct xfs_mount *mp); 83 int (*leaf_max_ents)(struct xfs_da_geometry *geo);
84 struct xfs_dir2_leaf_entry * 84 struct xfs_dir2_leaf_entry *
85 (*leaf_ents_p)(struct xfs_dir2_leaf *lp); 85 (*leaf_ents_p)(struct xfs_dir2_leaf *lp);
86 86
@@ -97,10 +97,12 @@ struct xfs_dir_ops {
97 struct xfs_dir3_icfree_hdr *from); 97 struct xfs_dir3_icfree_hdr *from);
98 void (*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to, 98 void (*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to,
99 struct xfs_dir2_free *from); 99 struct xfs_dir2_free *from);
100 int (*free_max_bests)(struct xfs_mount *mp); 100 int (*free_max_bests)(struct xfs_da_geometry *geo);
101 __be16 * (*free_bests_p)(struct xfs_dir2_free *free); 101 __be16 * (*free_bests_p)(struct xfs_dir2_free *free);
102 xfs_dir2_db_t (*db_to_fdb)(struct xfs_mount *mp, xfs_dir2_db_t db); 102 xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
103 int (*db_to_fdindex)(struct xfs_mount *mp, xfs_dir2_db_t db); 103 xfs_dir2_db_t db);
104 int (*db_to_fdindex)(struct xfs_da_geometry *geo,
105 xfs_dir2_db_t db);
104}; 106};
105 107
106extern const struct xfs_dir_ops * 108extern const struct xfs_dir_ops *
@@ -112,7 +114,9 @@ extern const struct xfs_dir_ops *
112 * Generic directory interface routines 114 * Generic directory interface routines
113 */ 115 */
114extern void xfs_dir_startup(void); 116extern void xfs_dir_startup(void);
115extern void xfs_dir_mount(struct xfs_mount *mp); 117extern int xfs_da_mount(struct xfs_mount *mp);
118extern void xfs_da_unmount(struct xfs_mount *mp);
119
116extern int xfs_dir_isempty(struct xfs_inode *dp); 120extern int xfs_dir_isempty(struct xfs_inode *dp);
117extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, 121extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
118 struct xfs_inode *pdp); 122 struct xfs_inode *pdp);
@@ -142,23 +146,23 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
142/* 146/*
143 * Interface routines used by userspace utilities 147 * Interface routines used by userspace utilities
144 */ 148 */
145extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, int *r); 149extern int xfs_dir2_isblock(struct xfs_da_args *args, int *r);
146extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *r); 150extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
147extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, 151extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
148 struct xfs_buf *bp); 152 struct xfs_buf *bp);
149 153
150extern void xfs_dir2_data_freescan(struct xfs_inode *dp, 154extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
151 struct xfs_dir2_data_hdr *hdr, int *loghead); 155 struct xfs_dir2_data_hdr *hdr, int *loghead);
152extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_inode *dp, 156extern void xfs_dir2_data_log_entry(struct xfs_da_args *args,
153 struct xfs_buf *bp, struct xfs_dir2_data_entry *dep); 157 struct xfs_buf *bp, struct xfs_dir2_data_entry *dep);
154extern void xfs_dir2_data_log_header(struct xfs_trans *tp, struct xfs_inode *dp, 158extern void xfs_dir2_data_log_header(struct xfs_da_args *args,
155 struct xfs_buf *bp); 159 struct xfs_buf *bp);
156extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_buf *bp, 160extern void xfs_dir2_data_log_unused(struct xfs_da_args *args,
157 struct xfs_dir2_data_unused *dup); 161 struct xfs_buf *bp, struct xfs_dir2_data_unused *dup);
158extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_inode *dp, 162extern void xfs_dir2_data_make_free(struct xfs_da_args *args,
159 struct xfs_buf *bp, xfs_dir2_data_aoff_t offset, 163 struct xfs_buf *bp, xfs_dir2_data_aoff_t offset,
160 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); 164 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
161extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_inode *dp, 165extern void xfs_dir2_data_use_free(struct xfs_da_args *args,
162 struct xfs_buf *bp, struct xfs_dir2_data_unused *dup, 166 struct xfs_buf *bp, struct xfs_dir2_data_unused *dup,
163 xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len, 167 xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len,
164 int *needlogp, int *needscanp); 168 int *needlogp, int *needscanp);
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 4f6a38cb83a4..c7cd3154026a 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -136,7 +136,7 @@ xfs_dir3_block_read(
136 struct xfs_mount *mp = dp->i_mount; 136 struct xfs_mount *mp = dp->i_mount;
137 int err; 137 int err;
138 138
139 err = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp, 139 err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, -1, bpp,
140 XFS_DATA_FORK, &xfs_dir3_block_buf_ops); 140 XFS_DATA_FORK, &xfs_dir3_block_buf_ops);
141 if (!err && tp) 141 if (!err && tp)
142 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF); 142 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF);
@@ -281,8 +281,7 @@ out:
281 */ 281 */
282static void 282static void
283xfs_dir2_block_compact( 283xfs_dir2_block_compact(
284 struct xfs_trans *tp, 284 struct xfs_da_args *args,
285 struct xfs_inode *dp,
286 struct xfs_buf *bp, 285 struct xfs_buf *bp,
287 struct xfs_dir2_data_hdr *hdr, 286 struct xfs_dir2_data_hdr *hdr,
288 struct xfs_dir2_block_tail *btp, 287 struct xfs_dir2_block_tail *btp,
@@ -315,18 +314,17 @@ xfs_dir2_block_compact(
315 *lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1); 314 *lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1);
316 *lfloghigh -= be32_to_cpu(btp->stale) - 1; 315 *lfloghigh -= be32_to_cpu(btp->stale) - 1;
317 be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); 316 be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1));
318 xfs_dir2_data_make_free(tp, dp, bp, 317 xfs_dir2_data_make_free(args, bp,
319 (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), 318 (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
320 (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), 319 (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
321 needlog, &needscan); 320 needlog, &needscan);
322 blp += be32_to_cpu(btp->stale) - 1;
323 btp->stale = cpu_to_be32(1); 321 btp->stale = cpu_to_be32(1);
324 /* 322 /*
325 * If we now need to rebuild the bestfree map, do so. 323 * If we now need to rebuild the bestfree map, do so.
326 * This needs to happen before the next call to use_free. 324 * This needs to happen before the next call to use_free.
327 */ 325 */
328 if (needscan) 326 if (needscan)
329 xfs_dir2_data_freescan(dp, hdr, needlog); 327 xfs_dir2_data_freescan(args->dp, hdr, needlog);
330} 328}
331 329
332/* 330/*
@@ -378,7 +376,7 @@ xfs_dir2_block_addname(
378 * Set up pointers to parts of the block. 376 * Set up pointers to parts of the block.
379 */ 377 */
380 hdr = bp->b_addr; 378 hdr = bp->b_addr;
381 btp = xfs_dir2_block_tail_p(mp, hdr); 379 btp = xfs_dir2_block_tail_p(args->geo, hdr);
382 blp = xfs_dir2_block_leaf_p(btp); 380 blp = xfs_dir2_block_leaf_p(btp);
383 381
384 /* 382 /*
@@ -421,7 +419,7 @@ xfs_dir2_block_addname(
421 * If need to compact the leaf entries, do it now. 419 * If need to compact the leaf entries, do it now.
422 */ 420 */
423 if (compact) { 421 if (compact) {
424 xfs_dir2_block_compact(tp, dp, bp, hdr, btp, blp, &needlog, 422 xfs_dir2_block_compact(args, bp, hdr, btp, blp, &needlog,
425 &lfloghigh, &lfloglow); 423 &lfloghigh, &lfloglow);
426 /* recalculate blp post-compaction */ 424 /* recalculate blp post-compaction */
427 blp = xfs_dir2_block_leaf_p(btp); 425 blp = xfs_dir2_block_leaf_p(btp);
@@ -456,7 +454,7 @@ xfs_dir2_block_addname(
456 /* 454 /*
457 * Mark the space needed for the new leaf entry, now in use. 455 * Mark the space needed for the new leaf entry, now in use.
458 */ 456 */
459 xfs_dir2_data_use_free(tp, dp, bp, enddup, 457 xfs_dir2_data_use_free(args, bp, enddup,
460 (xfs_dir2_data_aoff_t) 458 (xfs_dir2_data_aoff_t)
461 ((char *)enddup - (char *)hdr + be16_to_cpu(enddup->length) - 459 ((char *)enddup - (char *)hdr + be16_to_cpu(enddup->length) -
462 sizeof(*blp)), 460 sizeof(*blp)),
@@ -537,13 +535,13 @@ xfs_dir2_block_addname(
537 * Fill in the leaf entry. 535 * Fill in the leaf entry.
538 */ 536 */
539 blp[mid].hashval = cpu_to_be32(args->hashval); 537 blp[mid].hashval = cpu_to_be32(args->hashval);
540 blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 538 blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
541 (char *)dep - (char *)hdr)); 539 (char *)dep - (char *)hdr));
542 xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); 540 xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh);
543 /* 541 /*
544 * Mark space for the data entry used. 542 * Mark space for the data entry used.
545 */ 543 */
546 xfs_dir2_data_use_free(tp, dp, bp, dup, 544 xfs_dir2_data_use_free(args, bp, dup,
547 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), 545 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
548 (xfs_dir2_data_aoff_t)len, &needlog, &needscan); 546 (xfs_dir2_data_aoff_t)len, &needlog, &needscan);
549 /* 547 /*
@@ -561,9 +559,9 @@ xfs_dir2_block_addname(
561 if (needscan) 559 if (needscan)
562 xfs_dir2_data_freescan(dp, hdr, &needlog); 560 xfs_dir2_data_freescan(dp, hdr, &needlog);
563 if (needlog) 561 if (needlog)
564 xfs_dir2_data_log_header(tp, dp, bp); 562 xfs_dir2_data_log_header(args, bp);
565 xfs_dir2_block_log_tail(tp, bp); 563 xfs_dir2_block_log_tail(tp, bp);
566 xfs_dir2_data_log_entry(tp, dp, bp, dep); 564 xfs_dir2_data_log_entry(args, bp, dep);
567 xfs_dir3_data_check(dp, bp); 565 xfs_dir3_data_check(dp, bp);
568 return 0; 566 return 0;
569} 567}
@@ -582,7 +580,7 @@ xfs_dir2_block_log_leaf(
582 xfs_dir2_leaf_entry_t *blp; 580 xfs_dir2_leaf_entry_t *blp;
583 xfs_dir2_block_tail_t *btp; 581 xfs_dir2_block_tail_t *btp;
584 582
585 btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); 583 btp = xfs_dir2_block_tail_p(tp->t_mountp->m_dir_geo, hdr);
586 blp = xfs_dir2_block_leaf_p(btp); 584 blp = xfs_dir2_block_leaf_p(btp);
587 xfs_trans_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr), 585 xfs_trans_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr),
588 (uint)((char *)&blp[last + 1] - (char *)hdr - 1)); 586 (uint)((char *)&blp[last + 1] - (char *)hdr - 1));
@@ -599,7 +597,7 @@ xfs_dir2_block_log_tail(
599 xfs_dir2_data_hdr_t *hdr = bp->b_addr; 597 xfs_dir2_data_hdr_t *hdr = bp->b_addr;
600 xfs_dir2_block_tail_t *btp; 598 xfs_dir2_block_tail_t *btp;
601 599
602 btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); 600 btp = xfs_dir2_block_tail_p(tp->t_mountp->m_dir_geo, hdr);
603 xfs_trans_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr), 601 xfs_trans_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr),
604 (uint)((char *)(btp + 1) - (char *)hdr - 1)); 602 (uint)((char *)(btp + 1) - (char *)hdr - 1));
605} 603}
@@ -634,13 +632,14 @@ xfs_dir2_block_lookup(
634 mp = dp->i_mount; 632 mp = dp->i_mount;
635 hdr = bp->b_addr; 633 hdr = bp->b_addr;
636 xfs_dir3_data_check(dp, bp); 634 xfs_dir3_data_check(dp, bp);
637 btp = xfs_dir2_block_tail_p(mp, hdr); 635 btp = xfs_dir2_block_tail_p(args->geo, hdr);
638 blp = xfs_dir2_block_leaf_p(btp); 636 blp = xfs_dir2_block_leaf_p(btp);
639 /* 637 /*
640 * Get the offset from the leaf entry, to point to the data. 638 * Get the offset from the leaf entry, to point to the data.
641 */ 639 */
642 dep = (xfs_dir2_data_entry_t *)((char *)hdr + 640 dep = (xfs_dir2_data_entry_t *)((char *)hdr +
643 xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); 641 xfs_dir2_dataptr_to_off(args->geo,
642 be32_to_cpu(blp[ent].address)));
644 /* 643 /*
645 * Fill in inode number, CI name if appropriate, release the block. 644 * Fill in inode number, CI name if appropriate, release the block.
646 */ 645 */
@@ -686,7 +685,7 @@ xfs_dir2_block_lookup_int(
686 685
687 hdr = bp->b_addr; 686 hdr = bp->b_addr;
688 xfs_dir3_data_check(dp, bp); 687 xfs_dir3_data_check(dp, bp);
689 btp = xfs_dir2_block_tail_p(mp, hdr); 688 btp = xfs_dir2_block_tail_p(args->geo, hdr);
690 blp = xfs_dir2_block_leaf_p(btp); 689 blp = xfs_dir2_block_leaf_p(btp);
691 /* 690 /*
692 * Loop doing a binary search for our hash value. 691 * Loop doing a binary search for our hash value.
@@ -724,7 +723,7 @@ xfs_dir2_block_lookup_int(
724 * Get pointer to the entry from the leaf. 723 * Get pointer to the entry from the leaf.
725 */ 724 */
726 dep = (xfs_dir2_data_entry_t *) 725 dep = (xfs_dir2_data_entry_t *)
727 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); 726 ((char *)hdr + xfs_dir2_dataptr_to_off(args->geo, addr));
728 /* 727 /*
729 * Compare name and if it's an exact match, return the index 728 * Compare name and if it's an exact match, return the index
730 * and buffer. If it's the first case-insensitive match, store 729 * and buffer. If it's the first case-insensitive match, store
@@ -791,18 +790,19 @@ xfs_dir2_block_removename(
791 tp = args->trans; 790 tp = args->trans;
792 mp = dp->i_mount; 791 mp = dp->i_mount;
793 hdr = bp->b_addr; 792 hdr = bp->b_addr;
794 btp = xfs_dir2_block_tail_p(mp, hdr); 793 btp = xfs_dir2_block_tail_p(args->geo, hdr);
795 blp = xfs_dir2_block_leaf_p(btp); 794 blp = xfs_dir2_block_leaf_p(btp);
796 /* 795 /*
797 * Point to the data entry using the leaf entry. 796 * Point to the data entry using the leaf entry.
798 */ 797 */
799 dep = (xfs_dir2_data_entry_t *) 798 dep = (xfs_dir2_data_entry_t *)((char *)hdr +
800 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); 799 xfs_dir2_dataptr_to_off(args->geo,
800 be32_to_cpu(blp[ent].address)));
801 /* 801 /*
802 * Mark the data entry's space free. 802 * Mark the data entry's space free.
803 */ 803 */
804 needlog = needscan = 0; 804 needlog = needscan = 0;
805 xfs_dir2_data_make_free(tp, dp, bp, 805 xfs_dir2_data_make_free(args, bp,
806 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), 806 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
807 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); 807 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
808 /* 808 /*
@@ -821,7 +821,7 @@ xfs_dir2_block_removename(
821 if (needscan) 821 if (needscan)
822 xfs_dir2_data_freescan(dp, hdr, &needlog); 822 xfs_dir2_data_freescan(dp, hdr, &needlog);
823 if (needlog) 823 if (needlog)
824 xfs_dir2_data_log_header(tp, dp, bp); 824 xfs_dir2_data_log_header(args, bp);
825 xfs_dir3_data_check(dp, bp); 825 xfs_dir3_data_check(dp, bp);
826 /* 826 /*
827 * See if the size as a shortform is good enough. 827 * See if the size as a shortform is good enough.
@@ -866,20 +866,21 @@ xfs_dir2_block_replace(
866 dp = args->dp; 866 dp = args->dp;
867 mp = dp->i_mount; 867 mp = dp->i_mount;
868 hdr = bp->b_addr; 868 hdr = bp->b_addr;
869 btp = xfs_dir2_block_tail_p(mp, hdr); 869 btp = xfs_dir2_block_tail_p(args->geo, hdr);
870 blp = xfs_dir2_block_leaf_p(btp); 870 blp = xfs_dir2_block_leaf_p(btp);
871 /* 871 /*
872 * Point to the data entry we need to change. 872 * Point to the data entry we need to change.
873 */ 873 */
874 dep = (xfs_dir2_data_entry_t *) 874 dep = (xfs_dir2_data_entry_t *)((char *)hdr +
875 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); 875 xfs_dir2_dataptr_to_off(args->geo,
876 be32_to_cpu(blp[ent].address)));
876 ASSERT(be64_to_cpu(dep->inumber) != args->inumber); 877 ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
877 /* 878 /*
878 * Change the inode number to the new value. 879 * Change the inode number to the new value.
879 */ 880 */
880 dep->inumber = cpu_to_be64(args->inumber); 881 dep->inumber = cpu_to_be64(args->inumber);
881 dp->d_ops->data_put_ftype(dep, args->filetype); 882 dp->d_ops->data_put_ftype(dep, args->filetype);
882 xfs_dir2_data_log_entry(args->trans, dp, bp, dep); 883 xfs_dir2_data_log_entry(args, bp, dep);
883 xfs_dir3_data_check(dp, bp); 884 xfs_dir3_data_check(dp, bp);
884 return 0; 885 return 0;
885} 886}
@@ -939,7 +940,7 @@ xfs_dir2_leaf_to_block(
939 leaf = lbp->b_addr; 940 leaf = lbp->b_addr;
940 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 941 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
941 ents = dp->d_ops->leaf_ents_p(leaf); 942 ents = dp->d_ops->leaf_ents_p(leaf);
942 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 943 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
943 944
944 ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC || 945 ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
945 leafhdr.magic == XFS_DIR3_LEAF1_MAGIC); 946 leafhdr.magic == XFS_DIR3_LEAF1_MAGIC);
@@ -949,13 +950,13 @@ xfs_dir2_leaf_to_block(
949 * been left behind during no-space-reservation operations. 950 * been left behind during no-space-reservation operations.
950 * These will show up in the leaf bests table. 951 * These will show up in the leaf bests table.
951 */ 952 */
952 while (dp->i_d.di_size > mp->m_dirblksize) { 953 while (dp->i_d.di_size > args->geo->blksize) {
953 int hdrsz; 954 int hdrsz;
954 955
955 hdrsz = dp->d_ops->data_entry_offset; 956 hdrsz = dp->d_ops->data_entry_offset;
956 bestsp = xfs_dir2_leaf_bests_p(ltp); 957 bestsp = xfs_dir2_leaf_bests_p(ltp);
957 if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == 958 if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) ==
958 mp->m_dirblksize - hdrsz) { 959 args->geo->blksize - hdrsz) {
959 if ((error = 960 if ((error =
960 xfs_dir2_leaf_trim_data(args, lbp, 961 xfs_dir2_leaf_trim_data(args, lbp,
961 (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) 962 (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1))))
@@ -967,7 +968,7 @@ xfs_dir2_leaf_to_block(
967 * Read the data block if we don't already have it, give up if it fails. 968 * Read the data block if we don't already have it, give up if it fails.
968 */ 969 */
969 if (!dbp) { 970 if (!dbp) {
970 error = xfs_dir3_data_read(tp, dp, mp->m_dirdatablk, -1, &dbp); 971 error = xfs_dir3_data_read(tp, dp, args->geo->datablk, -1, &dbp);
971 if (error) 972 if (error)
972 return error; 973 return error;
973 } 974 }
@@ -983,7 +984,7 @@ xfs_dir2_leaf_to_block(
983 /* 984 /*
984 * Look at the last data entry. 985 * Look at the last data entry.
985 */ 986 */
986 tagp = (__be16 *)((char *)hdr + mp->m_dirblksize) - 1; 987 tagp = (__be16 *)((char *)hdr + args->geo->blksize) - 1;
987 dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); 988 dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
988 /* 989 /*
989 * If it's not free or is too short we can't do it. 990 * If it's not free or is too short we can't do it.
@@ -1002,12 +1003,12 @@ xfs_dir2_leaf_to_block(
1002 /* 1003 /*
1003 * Use up the space at the end of the block (blp/btp). 1004 * Use up the space at the end of the block (blp/btp).
1004 */ 1005 */
1005 xfs_dir2_data_use_free(tp, dp, dbp, dup, mp->m_dirblksize - size, size, 1006 xfs_dir2_data_use_free(args, dbp, dup, args->geo->blksize - size, size,
1006 &needlog, &needscan); 1007 &needlog, &needscan);
1007 /* 1008 /*
1008 * Initialize the block tail. 1009 * Initialize the block tail.
1009 */ 1010 */
1010 btp = xfs_dir2_block_tail_p(mp, hdr); 1011 btp = xfs_dir2_block_tail_p(args->geo, hdr);
1011 btp->count = cpu_to_be32(leafhdr.count - leafhdr.stale); 1012 btp->count = cpu_to_be32(leafhdr.count - leafhdr.stale);
1012 btp->stale = 0; 1013 btp->stale = 0;
1013 xfs_dir2_block_log_tail(tp, dbp); 1014 xfs_dir2_block_log_tail(tp, dbp);
@@ -1028,11 +1029,11 @@ xfs_dir2_leaf_to_block(
1028 if (needscan) 1029 if (needscan)
1029 xfs_dir2_data_freescan(dp, hdr, &needlog); 1030 xfs_dir2_data_freescan(dp, hdr, &needlog);
1030 if (needlog) 1031 if (needlog)
1031 xfs_dir2_data_log_header(tp, dp, dbp); 1032 xfs_dir2_data_log_header(args, dbp);
1032 /* 1033 /*
1033 * Pitch the old leaf block. 1034 * Pitch the old leaf block.
1034 */ 1035 */
1035 error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp); 1036 error = xfs_da_shrink_inode(args, args->geo->leafblk, lbp);
1036 if (error) 1037 if (error)
1037 return error; 1038 return error;
1038 1039
@@ -1141,13 +1142,13 @@ xfs_dir2_sf_to_block(
1141 */ 1142 */
1142 dup = dp->d_ops->data_unused_p(hdr); 1143 dup = dp->d_ops->data_unused_p(hdr);
1143 needlog = needscan = 0; 1144 needlog = needscan = 0;
1144 xfs_dir2_data_use_free(tp, dp, bp, dup, mp->m_dirblksize - i, i, &needlog, 1145 xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i,
1145 &needscan); 1146 i, &needlog, &needscan);
1146 ASSERT(needscan == 0); 1147 ASSERT(needscan == 0);
1147 /* 1148 /*
1148 * Fill in the tail. 1149 * Fill in the tail.
1149 */ 1150 */
1150 btp = xfs_dir2_block_tail_p(mp, hdr); 1151 btp = xfs_dir2_block_tail_p(args->geo, hdr);
1151 btp->count = cpu_to_be32(sfp->count + 2); /* ., .. */ 1152 btp->count = cpu_to_be32(sfp->count + 2); /* ., .. */
1152 btp->stale = 0; 1153 btp->stale = 0;
1153 blp = xfs_dir2_block_leaf_p(btp); 1154 blp = xfs_dir2_block_leaf_p(btp);
@@ -1155,7 +1156,7 @@ xfs_dir2_sf_to_block(
1155 /* 1156 /*
1156 * Remove the freespace, we'll manage it. 1157 * Remove the freespace, we'll manage it.
1157 */ 1158 */
1158 xfs_dir2_data_use_free(tp, dp, bp, dup, 1159 xfs_dir2_data_use_free(args, bp, dup,
1159 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), 1160 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
1160 be16_to_cpu(dup->length), &needlog, &needscan); 1161 be16_to_cpu(dup->length), &needlog, &needscan);
1161 /* 1162 /*
@@ -1168,9 +1169,9 @@ xfs_dir2_sf_to_block(
1168 dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); 1169 dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
1169 tagp = dp->d_ops->data_entry_tag_p(dep); 1170 tagp = dp->d_ops->data_entry_tag_p(dep);
1170 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1171 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1171 xfs_dir2_data_log_entry(tp, dp, bp, dep); 1172 xfs_dir2_data_log_entry(args, bp, dep);
1172 blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); 1173 blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
1173 blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1174 blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
1174 (char *)dep - (char *)hdr)); 1175 (char *)dep - (char *)hdr));
1175 /* 1176 /*
1176 * Create entry for .. 1177 * Create entry for ..
@@ -1182,9 +1183,9 @@ xfs_dir2_sf_to_block(
1182 dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); 1183 dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
1183 tagp = dp->d_ops->data_entry_tag_p(dep); 1184 tagp = dp->d_ops->data_entry_tag_p(dep);
1184 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1185 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1185 xfs_dir2_data_log_entry(tp, dp, bp, dep); 1186 xfs_dir2_data_log_entry(args, bp, dep);
1186 blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); 1187 blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
1187 blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1188 blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
1188 (char *)dep - (char *)hdr)); 1189 (char *)dep - (char *)hdr));
1189 offset = dp->d_ops->data_first_offset; 1190 offset = dp->d_ops->data_first_offset;
1190 /* 1191 /*
@@ -1216,7 +1217,7 @@ xfs_dir2_sf_to_block(
1216 dup->length = cpu_to_be16(newoffset - offset); 1217 dup->length = cpu_to_be16(newoffset - offset);
1217 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( 1218 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(
1218 ((char *)dup - (char *)hdr)); 1219 ((char *)dup - (char *)hdr));
1219 xfs_dir2_data_log_unused(tp, bp, dup); 1220 xfs_dir2_data_log_unused(args, bp, dup);
1220 xfs_dir2_data_freeinsert(hdr, 1221 xfs_dir2_data_freeinsert(hdr,
1221 dp->d_ops->data_bestfree_p(hdr), 1222 dp->d_ops->data_bestfree_p(hdr),
1222 dup, &dummy); 1223 dup, &dummy);
@@ -1233,12 +1234,12 @@ xfs_dir2_sf_to_block(
1233 memcpy(dep->name, sfep->name, dep->namelen); 1234 memcpy(dep->name, sfep->name, dep->namelen);
1234 tagp = dp->d_ops->data_entry_tag_p(dep); 1235 tagp = dp->d_ops->data_entry_tag_p(dep);
1235 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1236 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1236 xfs_dir2_data_log_entry(tp, dp, bp, dep); 1237 xfs_dir2_data_log_entry(args, bp, dep);
1237 name.name = sfep->name; 1238 name.name = sfep->name;
1238 name.len = sfep->namelen; 1239 name.len = sfep->namelen;
1239 blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> 1240 blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->
1240 hashname(&name)); 1241 hashname(&name));
1241 blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1242 blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
1242 (char *)dep - (char *)hdr)); 1243 (char *)dep - (char *)hdr));
1243 offset = (int)((char *)(tagp + 1) - (char *)hdr); 1244 offset = (int)((char *)(tagp + 1) - (char *)hdr);
1244 if (++i == sfp->count) 1245 if (++i == sfp->count)
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index afa4ad523f3f..8c2f6422648e 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -63,8 +63,10 @@ __xfs_dir3_data_check(
63 int stale; /* count of stale leaves */ 63 int stale; /* count of stale leaves */
64 struct xfs_name name; 64 struct xfs_name name;
65 const struct xfs_dir_ops *ops; 65 const struct xfs_dir_ops *ops;
66 struct xfs_da_geometry *geo;
66 67
67 mp = bp->b_target->bt_mount; 68 mp = bp->b_target->bt_mount;
69 geo = mp->m_dir_geo;
68 70
69 /* 71 /*
70 * We can be passed a null dp here from a verifier, so we need to go the 72 * We can be passed a null dp here from a verifier, so we need to go the
@@ -78,7 +80,7 @@ __xfs_dir3_data_check(
78 switch (hdr->magic) { 80 switch (hdr->magic) {
79 case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): 81 case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
80 case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): 82 case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
81 btp = xfs_dir2_block_tail_p(mp, hdr); 83 btp = xfs_dir2_block_tail_p(geo, hdr);
82 lep = xfs_dir2_block_leaf_p(btp); 84 lep = xfs_dir2_block_leaf_p(btp);
83 endp = (char *)lep; 85 endp = (char *)lep;
84 86
@@ -94,7 +96,7 @@ __xfs_dir3_data_check(
94 break; 96 break;
95 case cpu_to_be32(XFS_DIR3_DATA_MAGIC): 97 case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
96 case cpu_to_be32(XFS_DIR2_DATA_MAGIC): 98 case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
97 endp = (char *)hdr + mp->m_dirblksize; 99 endp = (char *)hdr + geo->blksize;
98 break; 100 break;
99 default: 101 default:
100 XFS_ERROR_REPORT("Bad Magic", XFS_ERRLEVEL_LOW, mp); 102 XFS_ERROR_REPORT("Bad Magic", XFS_ERRLEVEL_LOW, mp);
@@ -172,9 +174,9 @@ __xfs_dir3_data_check(
172 lastfree = 0; 174 lastfree = 0;
173 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 175 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
174 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { 176 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
175 addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 177 addr = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
176 (xfs_dir2_data_aoff_t) 178 (xfs_dir2_data_aoff_t)
177 ((char *)dep - (char *)hdr)); 179 ((char *)dep - (char *)hdr));
178 name.name = dep->name; 180 name.name = dep->name;
179 name.len = dep->namelen; 181 name.len = dep->namelen;
180 hash = mp->m_dirnameops->hashname(&name); 182 hash = mp->m_dirnameops->hashname(&name);
@@ -329,12 +331,11 @@ xfs_dir3_data_read(
329 331
330int 332int
331xfs_dir3_data_readahead( 333xfs_dir3_data_readahead(
332 struct xfs_trans *tp,
333 struct xfs_inode *dp, 334 struct xfs_inode *dp,
334 xfs_dablk_t bno, 335 xfs_dablk_t bno,
335 xfs_daddr_t mapped_bno) 336 xfs_daddr_t mapped_bno)
336{ 337{
337 return xfs_da_reada_buf(tp, dp, bno, mapped_bno, 338 return xfs_da_reada_buf(dp, bno, mapped_bno,
338 XFS_DATA_FORK, &xfs_dir3_data_reada_buf_ops); 339 XFS_DATA_FORK, &xfs_dir3_data_reada_buf_ops);
339} 340}
340 341
@@ -510,6 +511,7 @@ xfs_dir2_data_freescan(
510 struct xfs_dir2_data_free *bf; 511 struct xfs_dir2_data_free *bf;
511 char *endp; /* end of block's data */ 512 char *endp; /* end of block's data */
512 char *p; /* current entry pointer */ 513 char *p; /* current entry pointer */
514 struct xfs_da_geometry *geo = dp->i_mount->m_dir_geo;
513 515
514 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 516 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
515 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 517 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
@@ -528,10 +530,10 @@ xfs_dir2_data_freescan(
528 p = (char *)dp->d_ops->data_entry_p(hdr); 530 p = (char *)dp->d_ops->data_entry_p(hdr);
529 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 531 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
530 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { 532 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
531 btp = xfs_dir2_block_tail_p(dp->i_mount, hdr); 533 btp = xfs_dir2_block_tail_p(geo, hdr);
532 endp = (char *)xfs_dir2_block_leaf_p(btp); 534 endp = (char *)xfs_dir2_block_leaf_p(btp);
533 } else 535 } else
534 endp = (char *)hdr + dp->i_mount->m_dirblksize; 536 endp = (char *)hdr + geo->blksize;
535 /* 537 /*
536 * Loop over the block's entries. 538 * Loop over the block's entries.
537 */ 539 */
@@ -585,8 +587,8 @@ xfs_dir3_data_init(
585 /* 587 /*
586 * Get the buffer set up for the block. 588 * Get the buffer set up for the block.
587 */ 589 */
588 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, blkno), -1, &bp, 590 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno),
589 XFS_DATA_FORK); 591 -1, &bp, XFS_DATA_FORK);
590 if (error) 592 if (error)
591 return error; 593 return error;
592 bp->b_ops = &xfs_dir3_data_buf_ops; 594 bp->b_ops = &xfs_dir3_data_buf_ops;
@@ -621,15 +623,15 @@ xfs_dir3_data_init(
621 dup = dp->d_ops->data_unused_p(hdr); 623 dup = dp->d_ops->data_unused_p(hdr);
622 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 624 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
623 625
624 t = mp->m_dirblksize - (uint)dp->d_ops->data_entry_offset; 626 t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset;
625 bf[0].length = cpu_to_be16(t); 627 bf[0].length = cpu_to_be16(t);
626 dup->length = cpu_to_be16(t); 628 dup->length = cpu_to_be16(t);
627 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); 629 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
628 /* 630 /*
629 * Log it and return it. 631 * Log it and return it.
630 */ 632 */
631 xfs_dir2_data_log_header(tp, dp, bp); 633 xfs_dir2_data_log_header(args, bp);
632 xfs_dir2_data_log_unused(tp, bp, dup); 634 xfs_dir2_data_log_unused(args, bp, dup);
633 *bpp = bp; 635 *bpp = bp;
634 return 0; 636 return 0;
635} 637}
@@ -639,8 +641,7 @@ xfs_dir3_data_init(
639 */ 641 */
640void 642void
641xfs_dir2_data_log_entry( 643xfs_dir2_data_log_entry(
642 struct xfs_trans *tp, 644 struct xfs_da_args *args,
643 struct xfs_inode *dp,
644 struct xfs_buf *bp, 645 struct xfs_buf *bp,
645 xfs_dir2_data_entry_t *dep) /* data entry pointer */ 646 xfs_dir2_data_entry_t *dep) /* data entry pointer */
646{ 647{
@@ -651,8 +652,8 @@ xfs_dir2_data_log_entry(
651 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 652 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
652 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 653 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
653 654
654 xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr), 655 xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
655 (uint)((char *)(dp->d_ops->data_entry_tag_p(dep) + 1) - 656 (uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) -
656 (char *)hdr - 1)); 657 (char *)hdr - 1));
657} 658}
658 659
@@ -661,8 +662,7 @@ xfs_dir2_data_log_entry(
661 */ 662 */
662void 663void
663xfs_dir2_data_log_header( 664xfs_dir2_data_log_header(
664 struct xfs_trans *tp, 665 struct xfs_da_args *args,
665 struct xfs_inode *dp,
666 struct xfs_buf *bp) 666 struct xfs_buf *bp)
667{ 667{
668#ifdef DEBUG 668#ifdef DEBUG
@@ -674,7 +674,8 @@ xfs_dir2_data_log_header(
674 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 674 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
675#endif 675#endif
676 676
677 xfs_trans_log_buf(tp, bp, 0, dp->d_ops->data_entry_offset - 1); 677 xfs_trans_log_buf(args->trans, bp, 0,
678 args->dp->d_ops->data_entry_offset - 1);
678} 679}
679 680
680/* 681/*
@@ -682,7 +683,7 @@ xfs_dir2_data_log_header(
682 */ 683 */
683void 684void
684xfs_dir2_data_log_unused( 685xfs_dir2_data_log_unused(
685 struct xfs_trans *tp, 686 struct xfs_da_args *args,
686 struct xfs_buf *bp, 687 struct xfs_buf *bp,
687 xfs_dir2_data_unused_t *dup) /* data unused pointer */ 688 xfs_dir2_data_unused_t *dup) /* data unused pointer */
688{ 689{
@@ -696,13 +697,13 @@ xfs_dir2_data_log_unused(
696 /* 697 /*
697 * Log the first part of the unused entry. 698 * Log the first part of the unused entry.
698 */ 699 */
699 xfs_trans_log_buf(tp, bp, (uint)((char *)dup - (char *)hdr), 700 xfs_trans_log_buf(args->trans, bp, (uint)((char *)dup - (char *)hdr),
700 (uint)((char *)&dup->length + sizeof(dup->length) - 701 (uint)((char *)&dup->length + sizeof(dup->length) -
701 1 - (char *)hdr)); 702 1 - (char *)hdr));
702 /* 703 /*
703 * Log the end (tag) of the unused entry. 704 * Log the end (tag) of the unused entry.
704 */ 705 */
705 xfs_trans_log_buf(tp, bp, 706 xfs_trans_log_buf(args->trans, bp,
706 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr), 707 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr),
707 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr + 708 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr +
708 sizeof(xfs_dir2_data_off_t) - 1)); 709 sizeof(xfs_dir2_data_off_t) - 1));
@@ -714,8 +715,7 @@ xfs_dir2_data_log_unused(
714 */ 715 */
715void 716void
716xfs_dir2_data_make_free( 717xfs_dir2_data_make_free(
717 struct xfs_trans *tp, 718 struct xfs_da_args *args,
718 struct xfs_inode *dp,
719 struct xfs_buf *bp, 719 struct xfs_buf *bp,
720 xfs_dir2_data_aoff_t offset, /* starting byte offset */ 720 xfs_dir2_data_aoff_t offset, /* starting byte offset */
721 xfs_dir2_data_aoff_t len, /* length in bytes */ 721 xfs_dir2_data_aoff_t len, /* length in bytes */
@@ -725,14 +725,12 @@ xfs_dir2_data_make_free(
725 xfs_dir2_data_hdr_t *hdr; /* data block pointer */ 725 xfs_dir2_data_hdr_t *hdr; /* data block pointer */
726 xfs_dir2_data_free_t *dfp; /* bestfree pointer */ 726 xfs_dir2_data_free_t *dfp; /* bestfree pointer */
727 char *endptr; /* end of data area */ 727 char *endptr; /* end of data area */
728 xfs_mount_t *mp; /* filesystem mount point */
729 int needscan; /* need to regen bestfree */ 728 int needscan; /* need to regen bestfree */
730 xfs_dir2_data_unused_t *newdup; /* new unused entry */ 729 xfs_dir2_data_unused_t *newdup; /* new unused entry */
731 xfs_dir2_data_unused_t *postdup; /* unused entry after us */ 730 xfs_dir2_data_unused_t *postdup; /* unused entry after us */
732 xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ 731 xfs_dir2_data_unused_t *prevdup; /* unused entry before us */
733 struct xfs_dir2_data_free *bf; 732 struct xfs_dir2_data_free *bf;
734 733
735 mp = tp->t_mountp;
736 hdr = bp->b_addr; 734 hdr = bp->b_addr;
737 735
738 /* 736 /*
@@ -740,20 +738,20 @@ xfs_dir2_data_make_free(
740 */ 738 */
741 if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 739 if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
742 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)) 740 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC))
743 endptr = (char *)hdr + mp->m_dirblksize; 741 endptr = (char *)hdr + args->geo->blksize;
744 else { 742 else {
745 xfs_dir2_block_tail_t *btp; /* block tail */ 743 xfs_dir2_block_tail_t *btp; /* block tail */
746 744
747 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 745 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
748 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 746 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
749 btp = xfs_dir2_block_tail_p(mp, hdr); 747 btp = xfs_dir2_block_tail_p(args->geo, hdr);
750 endptr = (char *)xfs_dir2_block_leaf_p(btp); 748 endptr = (char *)xfs_dir2_block_leaf_p(btp);
751 } 749 }
752 /* 750 /*
753 * If this isn't the start of the block, then back up to 751 * If this isn't the start of the block, then back up to
754 * the previous entry and see if it's free. 752 * the previous entry and see if it's free.
755 */ 753 */
756 if (offset > dp->d_ops->data_entry_offset) { 754 if (offset > args->dp->d_ops->data_entry_offset) {
757 __be16 *tagp; /* tag just before us */ 755 __be16 *tagp; /* tag just before us */
758 756
759 tagp = (__be16 *)((char *)hdr + offset) - 1; 757 tagp = (__be16 *)((char *)hdr + offset) - 1;
@@ -779,7 +777,7 @@ xfs_dir2_data_make_free(
779 * Previous and following entries are both free, 777 * Previous and following entries are both free,
780 * merge everything into a single free entry. 778 * merge everything into a single free entry.
781 */ 779 */
782 bf = dp->d_ops->data_bestfree_p(hdr); 780 bf = args->dp->d_ops->data_bestfree_p(hdr);
783 if (prevdup && postdup) { 781 if (prevdup && postdup) {
784 xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ 782 xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */
785 783
@@ -801,7 +799,7 @@ xfs_dir2_data_make_free(
801 be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length)); 799 be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
802 *xfs_dir2_data_unused_tag_p(prevdup) = 800 *xfs_dir2_data_unused_tag_p(prevdup) =
803 cpu_to_be16((char *)prevdup - (char *)hdr); 801 cpu_to_be16((char *)prevdup - (char *)hdr);
804 xfs_dir2_data_log_unused(tp, bp, prevdup); 802 xfs_dir2_data_log_unused(args, bp, prevdup);
805 if (!needscan) { 803 if (!needscan) {
806 /* 804 /*
807 * Has to be the case that entries 0 and 1 are 805 * Has to be the case that entries 0 and 1 are
@@ -836,7 +834,7 @@ xfs_dir2_data_make_free(
836 be16_add_cpu(&prevdup->length, len); 834 be16_add_cpu(&prevdup->length, len);
837 *xfs_dir2_data_unused_tag_p(prevdup) = 835 *xfs_dir2_data_unused_tag_p(prevdup) =
838 cpu_to_be16((char *)prevdup - (char *)hdr); 836 cpu_to_be16((char *)prevdup - (char *)hdr);
839 xfs_dir2_data_log_unused(tp, bp, prevdup); 837 xfs_dir2_data_log_unused(args, bp, prevdup);
840 /* 838 /*
841 * If the previous entry was in the table, the new entry 839 * If the previous entry was in the table, the new entry
842 * is longer, so it will be in the table too. Remove 840 * is longer, so it will be in the table too. Remove
@@ -864,7 +862,7 @@ xfs_dir2_data_make_free(
864 newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); 862 newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
865 *xfs_dir2_data_unused_tag_p(newdup) = 863 *xfs_dir2_data_unused_tag_p(newdup) =
866 cpu_to_be16((char *)newdup - (char *)hdr); 864 cpu_to_be16((char *)newdup - (char *)hdr);
867 xfs_dir2_data_log_unused(tp, bp, newdup); 865 xfs_dir2_data_log_unused(args, bp, newdup);
868 /* 866 /*
869 * If the following entry was in the table, the new entry 867 * If the following entry was in the table, the new entry
870 * is longer, so it will be in the table too. Remove 868 * is longer, so it will be in the table too. Remove
@@ -891,7 +889,7 @@ xfs_dir2_data_make_free(
891 newdup->length = cpu_to_be16(len); 889 newdup->length = cpu_to_be16(len);
892 *xfs_dir2_data_unused_tag_p(newdup) = 890 *xfs_dir2_data_unused_tag_p(newdup) =
893 cpu_to_be16((char *)newdup - (char *)hdr); 891 cpu_to_be16((char *)newdup - (char *)hdr);
894 xfs_dir2_data_log_unused(tp, bp, newdup); 892 xfs_dir2_data_log_unused(args, bp, newdup);
895 xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp); 893 xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
896 } 894 }
897 *needscanp = needscan; 895 *needscanp = needscan;
@@ -902,8 +900,7 @@ xfs_dir2_data_make_free(
902 */ 900 */
903void 901void
904xfs_dir2_data_use_free( 902xfs_dir2_data_use_free(
905 struct xfs_trans *tp, 903 struct xfs_da_args *args,
906 struct xfs_inode *dp,
907 struct xfs_buf *bp, 904 struct xfs_buf *bp,
908 xfs_dir2_data_unused_t *dup, /* unused entry */ 905 xfs_dir2_data_unused_t *dup, /* unused entry */
909 xfs_dir2_data_aoff_t offset, /* starting offset to use */ 906 xfs_dir2_data_aoff_t offset, /* starting offset to use */
@@ -934,7 +931,7 @@ xfs_dir2_data_use_free(
934 * Look up the entry in the bestfree table. 931 * Look up the entry in the bestfree table.
935 */ 932 */
936 oldlen = be16_to_cpu(dup->length); 933 oldlen = be16_to_cpu(dup->length);
937 bf = dp->d_ops->data_bestfree_p(hdr); 934 bf = args->dp->d_ops->data_bestfree_p(hdr);
938 dfp = xfs_dir2_data_freefind(hdr, bf, dup); 935 dfp = xfs_dir2_data_freefind(hdr, bf, dup);
939 ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length)); 936 ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
940 /* 937 /*
@@ -966,7 +963,7 @@ xfs_dir2_data_use_free(
966 newdup->length = cpu_to_be16(oldlen - len); 963 newdup->length = cpu_to_be16(oldlen - len);
967 *xfs_dir2_data_unused_tag_p(newdup) = 964 *xfs_dir2_data_unused_tag_p(newdup) =
968 cpu_to_be16((char *)newdup - (char *)hdr); 965 cpu_to_be16((char *)newdup - (char *)hdr);
969 xfs_dir2_data_log_unused(tp, bp, newdup); 966 xfs_dir2_data_log_unused(args, bp, newdup);
970 /* 967 /*
971 * If it was in the table, remove it and add the new one. 968 * If it was in the table, remove it and add the new one.
972 */ 969 */
@@ -994,7 +991,7 @@ xfs_dir2_data_use_free(
994 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); 991 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
995 *xfs_dir2_data_unused_tag_p(newdup) = 992 *xfs_dir2_data_unused_tag_p(newdup) =
996 cpu_to_be16((char *)newdup - (char *)hdr); 993 cpu_to_be16((char *)newdup - (char *)hdr);
997 xfs_dir2_data_log_unused(tp, bp, newdup); 994 xfs_dir2_data_log_unused(args, bp, newdup);
998 /* 995 /*
999 * If it was in the table, remove it and add the new one. 996 * If it was in the table, remove it and add the new one.
1000 */ 997 */
@@ -1022,13 +1019,13 @@ xfs_dir2_data_use_free(
1022 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); 1019 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
1023 *xfs_dir2_data_unused_tag_p(newdup) = 1020 *xfs_dir2_data_unused_tag_p(newdup) =
1024 cpu_to_be16((char *)newdup - (char *)hdr); 1021 cpu_to_be16((char *)newdup - (char *)hdr);
1025 xfs_dir2_data_log_unused(tp, bp, newdup); 1022 xfs_dir2_data_log_unused(args, bp, newdup);
1026 newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); 1023 newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
1027 newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 1024 newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1028 newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); 1025 newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length));
1029 *xfs_dir2_data_unused_tag_p(newdup2) = 1026 *xfs_dir2_data_unused_tag_p(newdup2) =
1030 cpu_to_be16((char *)newdup2 - (char *)hdr); 1027 cpu_to_be16((char *)newdup2 - (char *)hdr);
1031 xfs_dir2_data_log_unused(tp, bp, newdup2); 1028 xfs_dir2_data_log_unused(args, bp, newdup2);
1032 /* 1029 /*
1033 * If the old entry was in the table, we need to scan 1030 * If the old entry was in the table, we need to scan
1034 * if the 3rd entry was valid, since these entries 1031 * if the 3rd entry was valid, since these entries
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index d36e97df1187..fb0aad4440c1 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -41,9 +41,10 @@
41 */ 41 */
42static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp, 42static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp,
43 int *indexp, struct xfs_buf **dbpp); 43 int *indexp, struct xfs_buf **dbpp);
44static void xfs_dir3_leaf_log_bests(struct xfs_trans *tp, struct xfs_buf *bp, 44static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args,
45 int first, int last); 45 struct xfs_buf *bp, int first, int last);
46static void xfs_dir3_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp); 46static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args,
47 struct xfs_buf *bp);
47 48
48/* 49/*
49 * Check the internal consistency of a leaf1 block. 50 * Check the internal consistency of a leaf1 block.
@@ -92,6 +93,7 @@ xfs_dir3_leaf_check_int(
92 int i; 93 int i;
93 const struct xfs_dir_ops *ops; 94 const struct xfs_dir_ops *ops;
94 struct xfs_dir3_icleaf_hdr leafhdr; 95 struct xfs_dir3_icleaf_hdr leafhdr;
96 struct xfs_da_geometry *geo = mp->m_dir_geo;
95 97
96 /* 98 /*
97 * we can be passed a null dp here from a verifier, so we need to go the 99 * we can be passed a null dp here from a verifier, so we need to go the
@@ -105,14 +107,14 @@ xfs_dir3_leaf_check_int(
105 } 107 }
106 108
107 ents = ops->leaf_ents_p(leaf); 109 ents = ops->leaf_ents_p(leaf);
108 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 110 ltp = xfs_dir2_leaf_tail_p(geo, leaf);
109 111
110 /* 112 /*
111 * XXX (dgc): This value is not restrictive enough. 113 * XXX (dgc): This value is not restrictive enough.
112 * Should factor in the size of the bests table as well. 114 * Should factor in the size of the bests table as well.
113 * We can deduce a value for that from di_size. 115 * We can deduce a value for that from di_size.
114 */ 116 */
115 if (hdr->count > ops->leaf_max_ents(mp)) 117 if (hdr->count > ops->leaf_max_ents(geo))
116 return false; 118 return false;
117 119
118 /* Leaves and bests don't overlap in leaf format. */ 120 /* Leaves and bests don't overlap in leaf format. */
@@ -323,7 +325,7 @@ xfs_dir3_leaf_init(
323 if (type == XFS_DIR2_LEAF1_MAGIC) { 325 if (type == XFS_DIR2_LEAF1_MAGIC) {
324 struct xfs_dir2_leaf_tail *ltp; 326 struct xfs_dir2_leaf_tail *ltp;
325 327
326 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 328 ltp = xfs_dir2_leaf_tail_p(mp->m_dir_geo, leaf);
327 ltp->bestcount = 0; 329 ltp->bestcount = 0;
328 bp->b_ops = &xfs_dir3_leaf1_buf_ops; 330 bp->b_ops = &xfs_dir3_leaf1_buf_ops;
329 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAF1_BUF); 331 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAF1_BUF);
@@ -347,18 +349,18 @@ xfs_dir3_leaf_get_buf(
347 int error; 349 int error;
348 350
349 ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC); 351 ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC);
350 ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) && 352 ASSERT(bno >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET) &&
351 bno < XFS_DIR2_FREE_FIRSTDB(mp)); 353 bno < xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET));
352 354
353 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp, 355 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, bno),
354 XFS_DATA_FORK); 356 -1, &bp, XFS_DATA_FORK);
355 if (error) 357 if (error)
356 return error; 358 return error;
357 359
358 xfs_dir3_leaf_init(mp, tp, bp, dp->i_ino, magic); 360 xfs_dir3_leaf_init(mp, tp, bp, dp->i_ino, magic);
359 xfs_dir3_leaf_log_header(tp, dp, bp); 361 xfs_dir3_leaf_log_header(args, bp);
360 if (magic == XFS_DIR2_LEAF1_MAGIC) 362 if (magic == XFS_DIR2_LEAF1_MAGIC)
361 xfs_dir3_leaf_log_tail(tp, bp); 363 xfs_dir3_leaf_log_tail(args, bp);
362 *bpp = bp; 364 *bpp = bp;
363 return 0; 365 return 0;
364} 366}
@@ -403,8 +405,8 @@ xfs_dir2_block_to_leaf(
403 if ((error = xfs_da_grow_inode(args, &blkno))) { 405 if ((error = xfs_da_grow_inode(args, &blkno))) {
404 return error; 406 return error;
405 } 407 }
406 ldb = xfs_dir2_da_to_db(mp, blkno); 408 ldb = xfs_dir2_da_to_db(args->geo, blkno);
407 ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp)); 409 ASSERT(ldb == xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET));
408 /* 410 /*
409 * Initialize the leaf block, get a buffer for it. 411 * Initialize the leaf block, get a buffer for it.
410 */ 412 */
@@ -415,7 +417,7 @@ xfs_dir2_block_to_leaf(
415 leaf = lbp->b_addr; 417 leaf = lbp->b_addr;
416 hdr = dbp->b_addr; 418 hdr = dbp->b_addr;
417 xfs_dir3_data_check(dp, dbp); 419 xfs_dir3_data_check(dp, dbp);
418 btp = xfs_dir2_block_tail_p(mp, hdr); 420 btp = xfs_dir2_block_tail_p(args->geo, hdr);
419 blp = xfs_dir2_block_leaf_p(btp); 421 blp = xfs_dir2_block_leaf_p(btp);
420 bf = dp->d_ops->data_bestfree_p(hdr); 422 bf = dp->d_ops->data_bestfree_p(hdr);
421 ents = dp->d_ops->leaf_ents_p(leaf); 423 ents = dp->d_ops->leaf_ents_p(leaf);
@@ -427,23 +429,23 @@ xfs_dir2_block_to_leaf(
427 leafhdr.count = be32_to_cpu(btp->count); 429 leafhdr.count = be32_to_cpu(btp->count);
428 leafhdr.stale = be32_to_cpu(btp->stale); 430 leafhdr.stale = be32_to_cpu(btp->stale);
429 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 431 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
430 xfs_dir3_leaf_log_header(tp, dp, lbp); 432 xfs_dir3_leaf_log_header(args, lbp);
431 433
432 /* 434 /*
433 * Could compact these but I think we always do the conversion 435 * Could compact these but I think we always do the conversion
434 * after squeezing out stale entries. 436 * after squeezing out stale entries.
435 */ 437 */
436 memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); 438 memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t));
437 xfs_dir3_leaf_log_ents(tp, dp, lbp, 0, leafhdr.count - 1); 439 xfs_dir3_leaf_log_ents(args, lbp, 0, leafhdr.count - 1);
438 needscan = 0; 440 needscan = 0;
439 needlog = 1; 441 needlog = 1;
440 /* 442 /*
441 * Make the space formerly occupied by the leaf entries and block 443 * Make the space formerly occupied by the leaf entries and block
442 * tail be free. 444 * tail be free.
443 */ 445 */
444 xfs_dir2_data_make_free(tp, dp, dbp, 446 xfs_dir2_data_make_free(args, dbp,
445 (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), 447 (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
446 (xfs_dir2_data_aoff_t)((char *)hdr + mp->m_dirblksize - 448 (xfs_dir2_data_aoff_t)((char *)hdr + args->geo->blksize -
447 (char *)blp), 449 (char *)blp),
448 &needlog, &needscan); 450 &needlog, &needscan);
449 /* 451 /*
@@ -461,7 +463,7 @@ xfs_dir2_block_to_leaf(
461 /* 463 /*
462 * Set up leaf tail and bests table. 464 * Set up leaf tail and bests table.
463 */ 465 */
464 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 466 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
465 ltp->bestcount = cpu_to_be32(1); 467 ltp->bestcount = cpu_to_be32(1);
466 bestsp = xfs_dir2_leaf_bests_p(ltp); 468 bestsp = xfs_dir2_leaf_bests_p(ltp);
467 bestsp[0] = bf[0].length; 469 bestsp[0] = bf[0].length;
@@ -469,10 +471,10 @@ xfs_dir2_block_to_leaf(
469 * Log the data header and leaf bests table. 471 * Log the data header and leaf bests table.
470 */ 472 */
471 if (needlog) 473 if (needlog)
472 xfs_dir2_data_log_header(tp, dp, dbp); 474 xfs_dir2_data_log_header(args, dbp);
473 xfs_dir3_leaf_check(dp, lbp); 475 xfs_dir3_leaf_check(dp, lbp);
474 xfs_dir3_data_check(dp, dbp); 476 xfs_dir3_data_check(dp, dbp);
475 xfs_dir3_leaf_log_bests(tp, lbp, 0, 0); 477 xfs_dir3_leaf_log_bests(args, lbp, 0, 0);
476 return 0; 478 return 0;
477} 479}
478 480
@@ -641,7 +643,7 @@ xfs_dir2_leaf_addname(
641 tp = args->trans; 643 tp = args->trans;
642 mp = dp->i_mount; 644 mp = dp->i_mount;
643 645
644 error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp); 646 error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
645 if (error) 647 if (error)
646 return error; 648 return error;
647 649
@@ -653,7 +655,7 @@ xfs_dir2_leaf_addname(
653 */ 655 */
654 index = xfs_dir2_leaf_search_hash(args, lbp); 656 index = xfs_dir2_leaf_search_hash(args, lbp);
655 leaf = lbp->b_addr; 657 leaf = lbp->b_addr;
656 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 658 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
657 ents = dp->d_ops->leaf_ents_p(leaf); 659 ents = dp->d_ops->leaf_ents_p(leaf);
658 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); 660 dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
659 bestsp = xfs_dir2_leaf_bests_p(ltp); 661 bestsp = xfs_dir2_leaf_bests_p(ltp);
@@ -670,7 +672,7 @@ xfs_dir2_leaf_addname(
670 index++, lep++) { 672 index++, lep++) {
671 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) 673 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
672 continue; 674 continue;
673 i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 675 i = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
674 ASSERT(i < be32_to_cpu(ltp->bestcount)); 676 ASSERT(i < be32_to_cpu(ltp->bestcount));
675 ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF)); 677 ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF));
676 if (be16_to_cpu(bestsp[i]) >= length) { 678 if (be16_to_cpu(bestsp[i]) >= length) {
@@ -810,14 +812,15 @@ xfs_dir2_leaf_addname(
810 memmove(&bestsp[0], &bestsp[1], 812 memmove(&bestsp[0], &bestsp[1],
811 be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); 813 be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
812 be32_add_cpu(&ltp->bestcount, 1); 814 be32_add_cpu(&ltp->bestcount, 1);
813 xfs_dir3_leaf_log_tail(tp, lbp); 815 xfs_dir3_leaf_log_tail(args, lbp);
814 xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 816 xfs_dir3_leaf_log_bests(args, lbp, 0,
817 be32_to_cpu(ltp->bestcount) - 1);
815 } 818 }
816 /* 819 /*
817 * If we're filling in a previously empty block just log it. 820 * If we're filling in a previously empty block just log it.
818 */ 821 */
819 else 822 else
820 xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block); 823 xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
821 hdr = dbp->b_addr; 824 hdr = dbp->b_addr;
822 bf = dp->d_ops->data_bestfree_p(hdr); 825 bf = dp->d_ops->data_bestfree_p(hdr);
823 bestsp[use_block] = bf[0].length; 826 bestsp[use_block] = bf[0].length;
@@ -828,8 +831,8 @@ xfs_dir2_leaf_addname(
828 * Just read that one in. 831 * Just read that one in.
829 */ 832 */
830 error = xfs_dir3_data_read(tp, dp, 833 error = xfs_dir3_data_read(tp, dp,
831 xfs_dir2_db_to_da(mp, use_block), 834 xfs_dir2_db_to_da(args->geo, use_block),
832 -1, &dbp); 835 -1, &dbp);
833 if (error) { 836 if (error) {
834 xfs_trans_brelse(tp, lbp); 837 xfs_trans_brelse(tp, lbp);
835 return error; 838 return error;
@@ -848,7 +851,7 @@ xfs_dir2_leaf_addname(
848 /* 851 /*
849 * Mark the initial part of our freespace in use for the new entry. 852 * Mark the initial part of our freespace in use for the new entry.
850 */ 853 */
851 xfs_dir2_data_use_free(tp, dp, dbp, dup, 854 xfs_dir2_data_use_free(args, dbp, dup,
852 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length, 855 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
853 &needlog, &needscan); 856 &needlog, &needscan);
854 /* 857 /*
@@ -870,8 +873,8 @@ xfs_dir2_leaf_addname(
870 * Need to log the data block's header. 873 * Need to log the data block's header.
871 */ 874 */
872 if (needlog) 875 if (needlog)
873 xfs_dir2_data_log_header(tp, dp, dbp); 876 xfs_dir2_data_log_header(args, dbp);
874 xfs_dir2_data_log_entry(tp, dp, dbp, dep); 877 xfs_dir2_data_log_entry(args, dbp, dep);
875 /* 878 /*
876 * If the bests table needs to be changed, do it. 879 * If the bests table needs to be changed, do it.
877 * Log the change unless we've already done that. 880 * Log the change unless we've already done that.
@@ -879,7 +882,7 @@ xfs_dir2_leaf_addname(
879 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) { 882 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) {
880 bestsp[use_block] = bf[0].length; 883 bestsp[use_block] = bf[0].length;
881 if (!grown) 884 if (!grown)
882 xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block); 885 xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
883 } 886 }
884 887
885 lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale, 888 lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale,
@@ -889,14 +892,15 @@ xfs_dir2_leaf_addname(
889 * Fill in the new leaf entry. 892 * Fill in the new leaf entry.
890 */ 893 */
891 lep->hashval = cpu_to_be32(args->hashval); 894 lep->hashval = cpu_to_be32(args->hashval);
892 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, use_block, 895 lep->address = cpu_to_be32(
896 xfs_dir2_db_off_to_dataptr(args->geo, use_block,
893 be16_to_cpu(*tagp))); 897 be16_to_cpu(*tagp)));
894 /* 898 /*
895 * Log the leaf fields and give up the buffers. 899 * Log the leaf fields and give up the buffers.
896 */ 900 */
897 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 901 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
898 xfs_dir3_leaf_log_header(tp, dp, lbp); 902 xfs_dir3_leaf_log_header(args, lbp);
899 xfs_dir3_leaf_log_ents(tp, dp, lbp, lfloglow, lfloghigh); 903 xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh);
900 xfs_dir3_leaf_check(dp, lbp); 904 xfs_dir3_leaf_check(dp, lbp);
901 xfs_dir3_data_check(dp, dbp); 905 xfs_dir3_data_check(dp, dbp);
902 return 0; 906 return 0;
@@ -948,9 +952,9 @@ xfs_dir3_leaf_compact(
948 leafhdr->stale = 0; 952 leafhdr->stale = 0;
949 953
950 dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr); 954 dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr);
951 xfs_dir3_leaf_log_header(args->trans, dp, bp); 955 xfs_dir3_leaf_log_header(args, bp);
952 if (loglow != -1) 956 if (loglow != -1)
953 xfs_dir3_leaf_log_ents(args->trans, dp, bp, loglow, to - 1); 957 xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1);
954} 958}
955 959
956/* 960/*
@@ -1052,7 +1056,7 @@ xfs_dir3_leaf_compact_x1(
1052 */ 1056 */
1053static void 1057static void
1054xfs_dir3_leaf_log_bests( 1058xfs_dir3_leaf_log_bests(
1055 xfs_trans_t *tp, /* transaction pointer */ 1059 struct xfs_da_args *args,
1056 struct xfs_buf *bp, /* leaf buffer */ 1060 struct xfs_buf *bp, /* leaf buffer */
1057 int first, /* first entry to log */ 1061 int first, /* first entry to log */
1058 int last) /* last entry to log */ 1062 int last) /* last entry to log */
@@ -1065,10 +1069,11 @@ xfs_dir3_leaf_log_bests(
1065 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || 1069 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1066 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC)); 1070 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC));
1067 1071
1068 ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); 1072 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
1069 firstb = xfs_dir2_leaf_bests_p(ltp) + first; 1073 firstb = xfs_dir2_leaf_bests_p(ltp) + first;
1070 lastb = xfs_dir2_leaf_bests_p(ltp) + last; 1074 lastb = xfs_dir2_leaf_bests_p(ltp) + last;
1071 xfs_trans_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), 1075 xfs_trans_log_buf(args->trans, bp,
1076 (uint)((char *)firstb - (char *)leaf),
1072 (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); 1077 (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1));
1073} 1078}
1074 1079
@@ -1077,8 +1082,7 @@ xfs_dir3_leaf_log_bests(
1077 */ 1082 */
1078void 1083void
1079xfs_dir3_leaf_log_ents( 1084xfs_dir3_leaf_log_ents(
1080 struct xfs_trans *tp, 1085 struct xfs_da_args *args,
1081 struct xfs_inode *dp,
1082 struct xfs_buf *bp, 1086 struct xfs_buf *bp,
1083 int first, 1087 int first,
1084 int last) 1088 int last)
@@ -1093,10 +1097,11 @@ xfs_dir3_leaf_log_ents(
1093 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 1097 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1094 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); 1098 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
1095 1099
1096 ents = dp->d_ops->leaf_ents_p(leaf); 1100 ents = args->dp->d_ops->leaf_ents_p(leaf);
1097 firstlep = &ents[first]; 1101 firstlep = &ents[first];
1098 lastlep = &ents[last]; 1102 lastlep = &ents[last];
1099 xfs_trans_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), 1103 xfs_trans_log_buf(args->trans, bp,
1104 (uint)((char *)firstlep - (char *)leaf),
1100 (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); 1105 (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
1101} 1106}
1102 1107
@@ -1105,8 +1110,7 @@ xfs_dir3_leaf_log_ents(
1105 */ 1110 */
1106void 1111void
1107xfs_dir3_leaf_log_header( 1112xfs_dir3_leaf_log_header(
1108 struct xfs_trans *tp, 1113 struct xfs_da_args *args,
1109 struct xfs_inode *dp,
1110 struct xfs_buf *bp) 1114 struct xfs_buf *bp)
1111{ 1115{
1112 struct xfs_dir2_leaf *leaf = bp->b_addr; 1116 struct xfs_dir2_leaf *leaf = bp->b_addr;
@@ -1116,8 +1120,9 @@ xfs_dir3_leaf_log_header(
1116 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 1120 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1117 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); 1121 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
1118 1122
1119 xfs_trans_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), 1123 xfs_trans_log_buf(args->trans, bp,
1120 dp->d_ops->leaf_hdr_size - 1); 1124 (uint)((char *)&leaf->hdr - (char *)leaf),
1125 args->dp->d_ops->leaf_hdr_size - 1);
1121} 1126}
1122 1127
1123/* 1128/*
@@ -1125,21 +1130,20 @@ xfs_dir3_leaf_log_header(
1125 */ 1130 */
1126STATIC void 1131STATIC void
1127xfs_dir3_leaf_log_tail( 1132xfs_dir3_leaf_log_tail(
1128 struct xfs_trans *tp, 1133 struct xfs_da_args *args,
1129 struct xfs_buf *bp) 1134 struct xfs_buf *bp)
1130{ 1135{
1131 struct xfs_dir2_leaf *leaf = bp->b_addr; 1136 struct xfs_dir2_leaf *leaf = bp->b_addr;
1132 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1137 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1133 struct xfs_mount *mp = tp->t_mountp;
1134 1138
1135 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || 1139 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1136 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || 1140 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
1137 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || 1141 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1138 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); 1142 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
1139 1143
1140 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1144 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
1141 xfs_trans_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), 1145 xfs_trans_log_buf(args->trans, bp, (uint)((char *)ltp - (char *)leaf),
1142 (uint)(mp->m_dirblksize - 1)); 1146 (uint)(args->geo->blksize - 1));
1143} 1147}
1144 1148
1145/* 1149/*
@@ -1185,7 +1189,7 @@ xfs_dir2_leaf_lookup(
1185 */ 1189 */
1186 dep = (xfs_dir2_data_entry_t *) 1190 dep = (xfs_dir2_data_entry_t *)
1187 ((char *)dbp->b_addr + 1191 ((char *)dbp->b_addr +
1188 xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); 1192 xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
1189 /* 1193 /*
1190 * Return the found inode number & CI name if appropriate 1194 * Return the found inode number & CI name if appropriate
1191 */ 1195 */
@@ -1231,7 +1235,7 @@ xfs_dir2_leaf_lookup_int(
1231 tp = args->trans; 1235 tp = args->trans;
1232 mp = dp->i_mount; 1236 mp = dp->i_mount;
1233 1237
1234 error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp); 1238 error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
1235 if (error) 1239 if (error)
1236 return error; 1240 return error;
1237 1241
@@ -1260,7 +1264,8 @@ xfs_dir2_leaf_lookup_int(
1260 /* 1264 /*
1261 * Get the new data block number. 1265 * Get the new data block number.
1262 */ 1266 */
1263 newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 1267 newdb = xfs_dir2_dataptr_to_db(args->geo,
1268 be32_to_cpu(lep->address));
1264 /* 1269 /*
1265 * If it's not the same as the old data block number, 1270 * If it's not the same as the old data block number,
1266 * need to pitch the old one and read the new one. 1271 * need to pitch the old one and read the new one.
@@ -1269,8 +1274,8 @@ xfs_dir2_leaf_lookup_int(
1269 if (dbp) 1274 if (dbp)
1270 xfs_trans_brelse(tp, dbp); 1275 xfs_trans_brelse(tp, dbp);
1271 error = xfs_dir3_data_read(tp, dp, 1276 error = xfs_dir3_data_read(tp, dp,
1272 xfs_dir2_db_to_da(mp, newdb), 1277 xfs_dir2_db_to_da(args->geo, newdb),
1273 -1, &dbp); 1278 -1, &dbp);
1274 if (error) { 1279 if (error) {
1275 xfs_trans_brelse(tp, lbp); 1280 xfs_trans_brelse(tp, lbp);
1276 return error; 1281 return error;
@@ -1281,7 +1286,8 @@ xfs_dir2_leaf_lookup_int(
1281 * Point to the data entry. 1286 * Point to the data entry.
1282 */ 1287 */
1283 dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr + 1288 dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr +
1284 xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); 1289 xfs_dir2_dataptr_to_off(args->geo,
1290 be32_to_cpu(lep->address)));
1285 /* 1291 /*
1286 * Compare name and if it's an exact match, return the index 1292 * Compare name and if it's an exact match, return the index
1287 * and buffer. If it's the first case-insensitive match, store 1293 * and buffer. If it's the first case-insensitive match, store
@@ -1310,8 +1316,8 @@ xfs_dir2_leaf_lookup_int(
1310 if (cidb != curdb) { 1316 if (cidb != curdb) {
1311 xfs_trans_brelse(tp, dbp); 1317 xfs_trans_brelse(tp, dbp);
1312 error = xfs_dir3_data_read(tp, dp, 1318 error = xfs_dir3_data_read(tp, dp,
1313 xfs_dir2_db_to_da(mp, cidb), 1319 xfs_dir2_db_to_da(args->geo, cidb),
1314 -1, &dbp); 1320 -1, &dbp);
1315 if (error) { 1321 if (error) {
1316 xfs_trans_brelse(tp, lbp); 1322 xfs_trans_brelse(tp, lbp);
1317 return error; 1323 return error;
@@ -1380,18 +1386,18 @@ xfs_dir2_leaf_removename(
1380 * Point to the leaf entry, use that to point to the data entry. 1386 * Point to the leaf entry, use that to point to the data entry.
1381 */ 1387 */
1382 lep = &ents[index]; 1388 lep = &ents[index];
1383 db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 1389 db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
1384 dep = (xfs_dir2_data_entry_t *) 1390 dep = (xfs_dir2_data_entry_t *)((char *)hdr +
1385 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); 1391 xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
1386 needscan = needlog = 0; 1392 needscan = needlog = 0;
1387 oldbest = be16_to_cpu(bf[0].length); 1393 oldbest = be16_to_cpu(bf[0].length);
1388 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1394 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
1389 bestsp = xfs_dir2_leaf_bests_p(ltp); 1395 bestsp = xfs_dir2_leaf_bests_p(ltp);
1390 ASSERT(be16_to_cpu(bestsp[db]) == oldbest); 1396 ASSERT(be16_to_cpu(bestsp[db]) == oldbest);
1391 /* 1397 /*
1392 * Mark the former data entry unused. 1398 * Mark the former data entry unused.
1393 */ 1399 */
1394 xfs_dir2_data_make_free(tp, dp, dbp, 1400 xfs_dir2_data_make_free(args, dbp,
1395 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), 1401 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
1396 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); 1402 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
1397 /* 1403 /*
@@ -1399,10 +1405,10 @@ xfs_dir2_leaf_removename(
1399 */ 1405 */
1400 leafhdr.stale++; 1406 leafhdr.stale++;
1401 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 1407 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
1402 xfs_dir3_leaf_log_header(tp, dp, lbp); 1408 xfs_dir3_leaf_log_header(args, lbp);
1403 1409
1404 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); 1410 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
1405 xfs_dir3_leaf_log_ents(tp, dp, lbp, index, index); 1411 xfs_dir3_leaf_log_ents(args, lbp, index, index);
1406 1412
1407 /* 1413 /*
1408 * Scan the freespace in the data block again if necessary, 1414 * Scan the freespace in the data block again if necessary,
@@ -1411,22 +1417,22 @@ xfs_dir2_leaf_removename(
1411 if (needscan) 1417 if (needscan)
1412 xfs_dir2_data_freescan(dp, hdr, &needlog); 1418 xfs_dir2_data_freescan(dp, hdr, &needlog);
1413 if (needlog) 1419 if (needlog)
1414 xfs_dir2_data_log_header(tp, dp, dbp); 1420 xfs_dir2_data_log_header(args, dbp);
1415 /* 1421 /*
1416 * If the longest freespace in the data block has changed, 1422 * If the longest freespace in the data block has changed,
1417 * put the new value in the bests table and log that. 1423 * put the new value in the bests table and log that.
1418 */ 1424 */
1419 if (be16_to_cpu(bf[0].length) != oldbest) { 1425 if (be16_to_cpu(bf[0].length) != oldbest) {
1420 bestsp[db] = bf[0].length; 1426 bestsp[db] = bf[0].length;
1421 xfs_dir3_leaf_log_bests(tp, lbp, db, db); 1427 xfs_dir3_leaf_log_bests(args, lbp, db, db);
1422 } 1428 }
1423 xfs_dir3_data_check(dp, dbp); 1429 xfs_dir3_data_check(dp, dbp);
1424 /* 1430 /*
1425 * If the data block is now empty then get rid of the data block. 1431 * If the data block is now empty then get rid of the data block.
1426 */ 1432 */
1427 if (be16_to_cpu(bf[0].length) == 1433 if (be16_to_cpu(bf[0].length) ==
1428 mp->m_dirblksize - dp->d_ops->data_entry_offset) { 1434 args->geo->blksize - dp->d_ops->data_entry_offset) {
1429 ASSERT(db != mp->m_dirdatablk); 1435 ASSERT(db != args->geo->datablk);
1430 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { 1436 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
1431 /* 1437 /*
1432 * Nope, can't get rid of it because it caused 1438 * Nope, can't get rid of it because it caused
@@ -1459,15 +1465,16 @@ xfs_dir2_leaf_removename(
1459 memmove(&bestsp[db - i], bestsp, 1465 memmove(&bestsp[db - i], bestsp,
1460 (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp)); 1466 (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
1461 be32_add_cpu(&ltp->bestcount, -(db - i)); 1467 be32_add_cpu(&ltp->bestcount, -(db - i));
1462 xfs_dir3_leaf_log_tail(tp, lbp); 1468 xfs_dir3_leaf_log_tail(args, lbp);
1463 xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1469 xfs_dir3_leaf_log_bests(args, lbp, 0,
1470 be32_to_cpu(ltp->bestcount) - 1);
1464 } else 1471 } else
1465 bestsp[db] = cpu_to_be16(NULLDATAOFF); 1472 bestsp[db] = cpu_to_be16(NULLDATAOFF);
1466 } 1473 }
1467 /* 1474 /*
1468 * If the data block was not the first one, drop it. 1475 * If the data block was not the first one, drop it.
1469 */ 1476 */
1470 else if (db != mp->m_dirdatablk) 1477 else if (db != args->geo->datablk)
1471 dbp = NULL; 1478 dbp = NULL;
1472 1479
1473 xfs_dir3_leaf_check(dp, lbp); 1480 xfs_dir3_leaf_check(dp, lbp);
@@ -1515,7 +1522,7 @@ xfs_dir2_leaf_replace(
1515 */ 1522 */
1516 dep = (xfs_dir2_data_entry_t *) 1523 dep = (xfs_dir2_data_entry_t *)
1517 ((char *)dbp->b_addr + 1524 ((char *)dbp->b_addr +
1518 xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); 1525 xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
1519 ASSERT(args->inumber != be64_to_cpu(dep->inumber)); 1526 ASSERT(args->inumber != be64_to_cpu(dep->inumber));
1520 /* 1527 /*
1521 * Put the new inode number in, log it. 1528 * Put the new inode number in, log it.
@@ -1523,7 +1530,7 @@ xfs_dir2_leaf_replace(
1523 dep->inumber = cpu_to_be64(args->inumber); 1530 dep->inumber = cpu_to_be64(args->inumber);
1524 dp->d_ops->data_put_ftype(dep, args->filetype); 1531 dp->d_ops->data_put_ftype(dep, args->filetype);
1525 tp = args->trans; 1532 tp = args->trans;
1526 xfs_dir2_data_log_entry(tp, dp, dbp, dep); 1533 xfs_dir2_data_log_entry(args, dbp, dep);
1527 xfs_dir3_leaf_check(dp, lbp); 1534 xfs_dir3_leaf_check(dp, lbp);
1528 xfs_trans_brelse(tp, lbp); 1535 xfs_trans_brelse(tp, lbp);
1529 return 0; 1536 return 0;
@@ -1609,12 +1616,13 @@ xfs_dir2_leaf_trim_data(
1609 /* 1616 /*
1610 * Read the offending data block. We need its buffer. 1617 * Read the offending data block. We need its buffer.
1611 */ 1618 */
1612 error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp); 1619 error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, db),
1620 -1, &dbp);
1613 if (error) 1621 if (error)
1614 return error; 1622 return error;
1615 1623
1616 leaf = lbp->b_addr; 1624 leaf = lbp->b_addr;
1617 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1625 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
1618 1626
1619#ifdef DEBUG 1627#ifdef DEBUG
1620{ 1628{
@@ -1624,7 +1632,7 @@ xfs_dir2_leaf_trim_data(
1624 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 1632 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
1625 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); 1633 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
1626 ASSERT(be16_to_cpu(bf[0].length) == 1634 ASSERT(be16_to_cpu(bf[0].length) ==
1627 mp->m_dirblksize - dp->d_ops->data_entry_offset); 1635 args->geo->blksize - dp->d_ops->data_entry_offset);
1628 ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); 1636 ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
1629} 1637}
1630#endif 1638#endif
@@ -1643,8 +1651,8 @@ xfs_dir2_leaf_trim_data(
1643 bestsp = xfs_dir2_leaf_bests_p(ltp); 1651 bestsp = xfs_dir2_leaf_bests_p(ltp);
1644 be32_add_cpu(&ltp->bestcount, -1); 1652 be32_add_cpu(&ltp->bestcount, -1);
1645 memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); 1653 memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
1646 xfs_dir3_leaf_log_tail(tp, lbp); 1654 xfs_dir3_leaf_log_tail(args, lbp);
1647 xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1655 xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
1648 return 0; 1656 return 0;
1649} 1657}
1650 1658
@@ -1708,22 +1716,22 @@ xfs_dir2_node_to_leaf(
1708 /* 1716 /*
1709 * Get the last offset in the file. 1717 * Get the last offset in the file.
1710 */ 1718 */
1711 if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) { 1719 if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK))) {
1712 return error; 1720 return error;
1713 } 1721 }
1714 fo -= mp->m_dirblkfsbs; 1722 fo -= args->geo->fsbcount;
1715 /* 1723 /*
1716 * If there are freespace blocks other than the first one, 1724 * If there are freespace blocks other than the first one,
1717 * take this opportunity to remove trailing empty freespace blocks 1725 * take this opportunity to remove trailing empty freespace blocks
1718 * that may have been left behind during no-space-reservation 1726 * that may have been left behind during no-space-reservation
1719 * operations. 1727 * operations.
1720 */ 1728 */
1721 while (fo > mp->m_dirfreeblk) { 1729 while (fo > args->geo->freeblk) {
1722 if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) { 1730 if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) {
1723 return error; 1731 return error;
1724 } 1732 }
1725 if (rval) 1733 if (rval)
1726 fo -= mp->m_dirblkfsbs; 1734 fo -= args->geo->fsbcount;
1727 else 1735 else
1728 return 0; 1736 return 0;
1729 } 1737 }
@@ -1736,7 +1744,7 @@ xfs_dir2_node_to_leaf(
1736 /* 1744 /*
1737 * If it's not the single leaf block, give up. 1745 * If it's not the single leaf block, give up.
1738 */ 1746 */
1739 if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize) 1747 if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + args->geo->blksize)
1740 return 0; 1748 return 0;
1741 lbp = state->path.blk[0].bp; 1749 lbp = state->path.blk[0].bp;
1742 leaf = lbp->b_addr; 1750 leaf = lbp->b_addr;
@@ -1748,7 +1756,7 @@ xfs_dir2_node_to_leaf(
1748 /* 1756 /*
1749 * Read the freespace block. 1757 * Read the freespace block.
1750 */ 1758 */
1751 error = xfs_dir2_free_read(tp, dp, mp->m_dirfreeblk, &fbp); 1759 error = xfs_dir2_free_read(tp, dp, args->geo->freeblk, &fbp);
1752 if (error) 1760 if (error)
1753 return error; 1761 return error;
1754 free = fbp->b_addr; 1762 free = fbp->b_addr;
@@ -1760,7 +1768,7 @@ xfs_dir2_node_to_leaf(
1760 * Now see if the leafn and free data will fit in a leaf1. 1768 * Now see if the leafn and free data will fit in a leaf1.
1761 * If not, release the buffer and give up. 1769 * If not, release the buffer and give up.
1762 */ 1770 */
1763 if (xfs_dir3_leaf_size(&leafhdr, freehdr.nvalid) > mp->m_dirblksize) { 1771 if (xfs_dir3_leaf_size(&leafhdr, freehdr.nvalid) > args->geo->blksize) {
1764 xfs_trans_brelse(tp, fbp); 1772 xfs_trans_brelse(tp, fbp);
1765 return 0; 1773 return 0;
1766 } 1774 }
@@ -1780,7 +1788,7 @@ xfs_dir2_node_to_leaf(
1780 /* 1788 /*
1781 * Set up the leaf tail from the freespace block. 1789 * Set up the leaf tail from the freespace block.
1782 */ 1790 */
1783 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1791 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
1784 ltp->bestcount = cpu_to_be32(freehdr.nvalid); 1792 ltp->bestcount = cpu_to_be32(freehdr.nvalid);
1785 1793
1786 /* 1794 /*
@@ -1790,15 +1798,17 @@ xfs_dir2_node_to_leaf(
1790 freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); 1798 freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
1791 1799
1792 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 1800 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
1793 xfs_dir3_leaf_log_header(tp, dp, lbp); 1801 xfs_dir3_leaf_log_header(args, lbp);
1794 xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1802 xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
1795 xfs_dir3_leaf_log_tail(tp, lbp); 1803 xfs_dir3_leaf_log_tail(args, lbp);
1796 xfs_dir3_leaf_check(dp, lbp); 1804 xfs_dir3_leaf_check(dp, lbp);
1797 1805
1798 /* 1806 /*
1799 * Get rid of the freespace block. 1807 * Get rid of the freespace block.
1800 */ 1808 */
1801 error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp); 1809 error = xfs_dir2_shrink_inode(args,
1810 xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET),
1811 fbp);
1802 if (error) { 1812 if (error) {
1803 /* 1813 /*
1804 * This can't fail here because it can only happen when 1814 * This can't fail here because it can only happen when
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index cb434d732681..da43d304fca2 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -195,17 +195,18 @@ xfs_dir2_free_try_read(
195 195
196static int 196static int
197xfs_dir3_free_get_buf( 197xfs_dir3_free_get_buf(
198 struct xfs_trans *tp, 198 xfs_da_args_t *args,
199 struct xfs_inode *dp,
200 xfs_dir2_db_t fbno, 199 xfs_dir2_db_t fbno,
201 struct xfs_buf **bpp) 200 struct xfs_buf **bpp)
202{ 201{
202 struct xfs_trans *tp = args->trans;
203 struct xfs_inode *dp = args->dp;
203 struct xfs_mount *mp = dp->i_mount; 204 struct xfs_mount *mp = dp->i_mount;
204 struct xfs_buf *bp; 205 struct xfs_buf *bp;
205 int error; 206 int error;
206 struct xfs_dir3_icfree_hdr hdr; 207 struct xfs_dir3_icfree_hdr hdr;
207 208
208 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno), 209 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, fbno),
209 -1, &bp, XFS_DATA_FORK); 210 -1, &bp, XFS_DATA_FORK);
210 if (error) 211 if (error)
211 return error; 212 return error;
@@ -240,8 +241,7 @@ xfs_dir3_free_get_buf(
240 */ 241 */
241STATIC void 242STATIC void
242xfs_dir2_free_log_bests( 243xfs_dir2_free_log_bests(
243 struct xfs_trans *tp, 244 struct xfs_da_args *args,
244 struct xfs_inode *dp,
245 struct xfs_buf *bp, 245 struct xfs_buf *bp,
246 int first, /* first entry to log */ 246 int first, /* first entry to log */
247 int last) /* last entry to log */ 247 int last) /* last entry to log */
@@ -250,10 +250,10 @@ xfs_dir2_free_log_bests(
250 __be16 *bests; 250 __be16 *bests;
251 251
252 free = bp->b_addr; 252 free = bp->b_addr;
253 bests = dp->d_ops->free_bests_p(free); 253 bests = args->dp->d_ops->free_bests_p(free);
254 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || 254 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
255 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); 255 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
256 xfs_trans_log_buf(tp, bp, 256 xfs_trans_log_buf(args->trans, bp,
257 (uint)((char *)&bests[first] - (char *)free), 257 (uint)((char *)&bests[first] - (char *)free),
258 (uint)((char *)&bests[last] - (char *)free + 258 (uint)((char *)&bests[last] - (char *)free +
259 sizeof(bests[0]) - 1)); 259 sizeof(bests[0]) - 1));
@@ -264,8 +264,7 @@ xfs_dir2_free_log_bests(
264 */ 264 */
265static void 265static void
266xfs_dir2_free_log_header( 266xfs_dir2_free_log_header(
267 struct xfs_trans *tp, 267 struct xfs_da_args *args,
268 struct xfs_inode *dp,
269 struct xfs_buf *bp) 268 struct xfs_buf *bp)
270{ 269{
271#ifdef DEBUG 270#ifdef DEBUG
@@ -275,7 +274,8 @@ xfs_dir2_free_log_header(
275 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || 274 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
276 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); 275 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
277#endif 276#endif
278 xfs_trans_log_buf(tp, bp, 0, dp->d_ops->free_hdr_size - 1); 277 xfs_trans_log_buf(args->trans, bp, 0,
278 args->dp->d_ops->free_hdr_size - 1);
279} 279}
280 280
281/* 281/*
@@ -315,20 +315,20 @@ xfs_dir2_leaf_to_node(
315 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) { 315 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) {
316 return error; 316 return error;
317 } 317 }
318 ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp)); 318 ASSERT(fdb == xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET));
319 /* 319 /*
320 * Get the buffer for the new freespace block. 320 * Get the buffer for the new freespace block.
321 */ 321 */
322 error = xfs_dir3_free_get_buf(tp, dp, fdb, &fbp); 322 error = xfs_dir3_free_get_buf(args, fdb, &fbp);
323 if (error) 323 if (error)
324 return error; 324 return error;
325 325
326 free = fbp->b_addr; 326 free = fbp->b_addr;
327 dp->d_ops->free_hdr_from_disk(&freehdr, free); 327 dp->d_ops->free_hdr_from_disk(&freehdr, free);
328 leaf = lbp->b_addr; 328 leaf = lbp->b_addr;
329 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 329 ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
330 ASSERT(be32_to_cpu(ltp->bestcount) <= 330 ASSERT(be32_to_cpu(ltp->bestcount) <=
331 (uint)dp->i_d.di_size / mp->m_dirblksize); 331 (uint)dp->i_d.di_size / args->geo->blksize);
332 332
333 /* 333 /*
334 * Copy freespace entries from the leaf block to the new block. 334 * Copy freespace entries from the leaf block to the new block.
@@ -349,8 +349,8 @@ xfs_dir2_leaf_to_node(
349 freehdr.nvalid = be32_to_cpu(ltp->bestcount); 349 freehdr.nvalid = be32_to_cpu(ltp->bestcount);
350 350
351 dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); 351 dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
352 xfs_dir2_free_log_bests(tp, dp, fbp, 0, freehdr.nvalid - 1); 352 xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1);
353 xfs_dir2_free_log_header(tp, dp, fbp); 353 xfs_dir2_free_log_header(args, fbp);
354 354
355 /* 355 /*
356 * Converting the leaf to a leafnode is just a matter of changing the 356 * Converting the leaf to a leafnode is just a matter of changing the
@@ -364,7 +364,7 @@ xfs_dir2_leaf_to_node(
364 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); 364 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
365 lbp->b_ops = &xfs_dir3_leafn_buf_ops; 365 lbp->b_ops = &xfs_dir3_leafn_buf_ops;
366 xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF); 366 xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF);
367 xfs_dir3_leaf_log_header(tp, dp, lbp); 367 xfs_dir3_leaf_log_header(args, lbp);
368 xfs_dir3_leaf_check(dp, lbp); 368 xfs_dir3_leaf_check(dp, lbp);
369 return 0; 369 return 0;
370} 370}
@@ -415,7 +415,7 @@ xfs_dir2_leafn_add(
415 * a compact. 415 * a compact.
416 */ 416 */
417 417
418 if (leafhdr.count == dp->d_ops->leaf_max_ents(mp)) { 418 if (leafhdr.count == dp->d_ops->leaf_max_ents(args->geo)) {
419 if (!leafhdr.stale) 419 if (!leafhdr.stale)
420 return XFS_ERROR(ENOSPC); 420 return XFS_ERROR(ENOSPC);
421 compact = leafhdr.stale > 1; 421 compact = leafhdr.stale > 1;
@@ -450,12 +450,12 @@ xfs_dir2_leafn_add(
450 highstale, &lfloglow, &lfloghigh); 450 highstale, &lfloglow, &lfloghigh);
451 451
452 lep->hashval = cpu_to_be32(args->hashval); 452 lep->hashval = cpu_to_be32(args->hashval);
453 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, 453 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(args->geo,
454 args->blkno, args->index)); 454 args->blkno, args->index));
455 455
456 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 456 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
457 xfs_dir3_leaf_log_header(tp, dp, bp); 457 xfs_dir3_leaf_log_header(args, bp);
458 xfs_dir3_leaf_log_ents(tp, dp, bp, lfloglow, lfloghigh); 458 xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh);
459 xfs_dir3_leaf_check(dp, bp); 459 xfs_dir3_leaf_check(dp, bp);
460 return 0; 460 return 0;
461} 461}
@@ -471,7 +471,8 @@ xfs_dir2_free_hdr_check(
471 471
472 dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr); 472 dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr);
473 473
474 ASSERT((hdr.firstdb % dp->d_ops->free_max_bests(dp->i_mount)) == 0); 474 ASSERT((hdr.firstdb %
475 dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0);
475 ASSERT(hdr.firstdb <= db); 476 ASSERT(hdr.firstdb <= db);
476 ASSERT(db < hdr.firstdb + hdr.nvalid); 477 ASSERT(db < hdr.firstdb + hdr.nvalid);
477} 478}
@@ -576,7 +577,8 @@ xfs_dir2_leafn_lookup_for_addname(
576 /* 577 /*
577 * Pull the data block number from the entry. 578 * Pull the data block number from the entry.
578 */ 579 */
579 newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 580 newdb = xfs_dir2_dataptr_to_db(args->geo,
581 be32_to_cpu(lep->address));
580 /* 582 /*
581 * For addname, we're looking for a place to put the new entry. 583 * For addname, we're looking for a place to put the new entry.
582 * We want to use a data block with an entry of equal 584 * We want to use a data block with an entry of equal
@@ -593,7 +595,7 @@ xfs_dir2_leafn_lookup_for_addname(
593 * Convert the data block to the free block 595 * Convert the data block to the free block
594 * holding its freespace information. 596 * holding its freespace information.
595 */ 597 */
596 newfdb = dp->d_ops->db_to_fdb(mp, newdb); 598 newfdb = dp->d_ops->db_to_fdb(args->geo, newdb);
597 /* 599 /*
598 * If it's not the one we have in hand, read it in. 600 * If it's not the one we have in hand, read it in.
599 */ 601 */
@@ -605,7 +607,8 @@ xfs_dir2_leafn_lookup_for_addname(
605 xfs_trans_brelse(tp, curbp); 607 xfs_trans_brelse(tp, curbp);
606 608
607 error = xfs_dir2_free_read(tp, dp, 609 error = xfs_dir2_free_read(tp, dp,
608 xfs_dir2_db_to_da(mp, newfdb), 610 xfs_dir2_db_to_da(args->geo,
611 newfdb),
609 &curbp); 612 &curbp);
610 if (error) 613 if (error)
611 return error; 614 return error;
@@ -616,7 +619,7 @@ xfs_dir2_leafn_lookup_for_addname(
616 /* 619 /*
617 * Get the index for our entry. 620 * Get the index for our entry.
618 */ 621 */
619 fi = dp->d_ops->db_to_fdindex(mp, curdb); 622 fi = dp->d_ops->db_to_fdindex(args->geo, curdb);
620 /* 623 /*
621 * If it has room, return it. 624 * If it has room, return it.
622 */ 625 */
@@ -721,7 +724,8 @@ xfs_dir2_leafn_lookup_for_entry(
721 /* 724 /*
722 * Pull the data block number from the entry. 725 * Pull the data block number from the entry.
723 */ 726 */
724 newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 727 newdb = xfs_dir2_dataptr_to_db(args->geo,
728 be32_to_cpu(lep->address));
725 /* 729 /*
726 * Not adding a new entry, so we really want to find 730 * Not adding a new entry, so we really want to find
727 * the name given to us. 731 * the name given to us.
@@ -746,7 +750,8 @@ xfs_dir2_leafn_lookup_for_entry(
746 curbp = state->extrablk.bp; 750 curbp = state->extrablk.bp;
747 } else { 751 } else {
748 error = xfs_dir3_data_read(tp, dp, 752 error = xfs_dir3_data_read(tp, dp,
749 xfs_dir2_db_to_da(mp, newdb), 753 xfs_dir2_db_to_da(args->geo,
754 newdb),
750 -1, &curbp); 755 -1, &curbp);
751 if (error) 756 if (error)
752 return error; 757 return error;
@@ -758,7 +763,8 @@ xfs_dir2_leafn_lookup_for_entry(
758 * Point to the data entry. 763 * Point to the data entry.
759 */ 764 */
760 dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr + 765 dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr +
761 xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); 766 xfs_dir2_dataptr_to_off(args->geo,
767 be32_to_cpu(lep->address)));
762 /* 768 /*
763 * Compare the entry and if it's an exact match, return 769 * Compare the entry and if it's an exact match, return
764 * EEXIST immediately. If it's the first case-insensitive 770 * EEXIST immediately. If it's the first case-insensitive
@@ -844,7 +850,6 @@ xfs_dir3_leafn_moveents(
844 int start_d,/* destination leaf index */ 850 int start_d,/* destination leaf index */
845 int count) /* count of leaves to copy */ 851 int count) /* count of leaves to copy */
846{ 852{
847 struct xfs_trans *tp = args->trans;
848 int stale; /* count stale leaves copied */ 853 int stale; /* count stale leaves copied */
849 854
850 trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count); 855 trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count);
@@ -863,7 +868,7 @@ xfs_dir3_leafn_moveents(
863 if (start_d < dhdr->count) { 868 if (start_d < dhdr->count) {
864 memmove(&dents[start_d + count], &dents[start_d], 869 memmove(&dents[start_d + count], &dents[start_d],
865 (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t)); 870 (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t));
866 xfs_dir3_leaf_log_ents(tp, args->dp, bp_d, start_d + count, 871 xfs_dir3_leaf_log_ents(args, bp_d, start_d + count,
867 count + dhdr->count - 1); 872 count + dhdr->count - 1);
868 } 873 }
869 /* 874 /*
@@ -885,8 +890,7 @@ xfs_dir3_leafn_moveents(
885 */ 890 */
886 memcpy(&dents[start_d], &sents[start_s], 891 memcpy(&dents[start_d], &sents[start_s],
887 count * sizeof(xfs_dir2_leaf_entry_t)); 892 count * sizeof(xfs_dir2_leaf_entry_t));
888 xfs_dir3_leaf_log_ents(tp, args->dp, bp_d, 893 xfs_dir3_leaf_log_ents(args, bp_d, start_d, start_d + count - 1);
889 start_d, start_d + count - 1);
890 894
891 /* 895 /*
892 * If there are source entries after the ones we copied, 896 * If there are source entries after the ones we copied,
@@ -895,8 +899,7 @@ xfs_dir3_leafn_moveents(
895 if (start_s + count < shdr->count) { 899 if (start_s + count < shdr->count) {
896 memmove(&sents[start_s], &sents[start_s + count], 900 memmove(&sents[start_s], &sents[start_s + count],
897 count * sizeof(xfs_dir2_leaf_entry_t)); 901 count * sizeof(xfs_dir2_leaf_entry_t));
898 xfs_dir3_leaf_log_ents(tp, args->dp, bp_s, 902 xfs_dir3_leaf_log_ents(args, bp_s, start_s, start_s + count - 1);
899 start_s, start_s + count - 1);
900 } 903 }
901 904
902 /* 905 /*
@@ -1032,8 +1035,8 @@ xfs_dir2_leafn_rebalance(
1032 /* log the changes made when moving the entries */ 1035 /* log the changes made when moving the entries */
1033 dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1); 1036 dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1);
1034 dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2); 1037 dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2);
1035 xfs_dir3_leaf_log_header(args->trans, dp, blk1->bp); 1038 xfs_dir3_leaf_log_header(args, blk1->bp);
1036 xfs_dir3_leaf_log_header(args->trans, dp, blk2->bp); 1039 xfs_dir3_leaf_log_header(args, blk2->bp);
1037 1040
1038 xfs_dir3_leaf_check(dp, blk1->bp); 1041 xfs_dir3_leaf_check(dp, blk1->bp);
1039 xfs_dir3_leaf_check(dp, blk2->bp); 1042 xfs_dir3_leaf_check(dp, blk2->bp);
@@ -1076,7 +1079,6 @@ xfs_dir3_data_block_free(
1076 struct xfs_buf *fbp, 1079 struct xfs_buf *fbp,
1077 int longest) 1080 int longest)
1078{ 1081{
1079 struct xfs_trans *tp = args->trans;
1080 int logfree = 0; 1082 int logfree = 0;
1081 __be16 *bests; 1083 __be16 *bests;
1082 struct xfs_dir3_icfree_hdr freehdr; 1084 struct xfs_dir3_icfree_hdr freehdr;
@@ -1090,7 +1092,7 @@ xfs_dir3_data_block_free(
1090 * value. 1092 * value.
1091 */ 1093 */
1092 bests[findex] = cpu_to_be16(longest); 1094 bests[findex] = cpu_to_be16(longest);
1093 xfs_dir2_free_log_bests(tp, dp, fbp, findex, findex); 1095 xfs_dir2_free_log_bests(args, fbp, findex, findex);
1094 return 0; 1096 return 0;
1095 } 1097 }
1096 1098
@@ -1118,7 +1120,7 @@ xfs_dir3_data_block_free(
1118 } 1120 }
1119 1121
1120 dp->d_ops->free_hdr_to_disk(free, &freehdr); 1122 dp->d_ops->free_hdr_to_disk(free, &freehdr);
1121 xfs_dir2_free_log_header(tp, dp, fbp); 1123 xfs_dir2_free_log_header(args, fbp);
1122 1124
1123 /* 1125 /*
1124 * If there are no useful entries left in the block, get rid of the 1126 * If there are no useful entries left in the block, get rid of the
@@ -1142,7 +1144,7 @@ xfs_dir3_data_block_free(
1142 1144
1143 /* Log the free entry that changed, unless we got rid of it. */ 1145 /* Log the free entry that changed, unless we got rid of it. */
1144 if (logfree) 1146 if (logfree)
1145 xfs_dir2_free_log_bests(tp, dp, fbp, findex, findex); 1147 xfs_dir2_free_log_bests(args, fbp, findex, findex);
1146 return 0; 1148 return 0;
1147} 1149}
1148 1150
@@ -1193,9 +1195,9 @@ xfs_dir2_leafn_remove(
1193 /* 1195 /*
1194 * Extract the data block and offset from the entry. 1196 * Extract the data block and offset from the entry.
1195 */ 1197 */
1196 db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 1198 db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
1197 ASSERT(dblk->blkno == db); 1199 ASSERT(dblk->blkno == db);
1198 off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)); 1200 off = xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address));
1199 ASSERT(dblk->index == off); 1201 ASSERT(dblk->index == off);
1200 1202
1201 /* 1203 /*
@@ -1204,10 +1206,10 @@ xfs_dir2_leafn_remove(
1204 */ 1206 */
1205 leafhdr.stale++; 1207 leafhdr.stale++;
1206 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); 1208 dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
1207 xfs_dir3_leaf_log_header(tp, dp, bp); 1209 xfs_dir3_leaf_log_header(args, bp);
1208 1210
1209 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); 1211 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
1210 xfs_dir3_leaf_log_ents(tp, dp, bp, index, index); 1212 xfs_dir3_leaf_log_ents(args, bp, index, index);
1211 1213
1212 /* 1214 /*
1213 * Make the data entry free. Keep track of the longest freespace 1215 * Make the data entry free. Keep track of the longest freespace
@@ -1219,7 +1221,7 @@ xfs_dir2_leafn_remove(
1219 bf = dp->d_ops->data_bestfree_p(hdr); 1221 bf = dp->d_ops->data_bestfree_p(hdr);
1220 longest = be16_to_cpu(bf[0].length); 1222 longest = be16_to_cpu(bf[0].length);
1221 needlog = needscan = 0; 1223 needlog = needscan = 0;
1222 xfs_dir2_data_make_free(tp, dp, dbp, off, 1224 xfs_dir2_data_make_free(args, dbp, off,
1223 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); 1225 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
1224 /* 1226 /*
1225 * Rescan the data block freespaces for bestfree. 1227 * Rescan the data block freespaces for bestfree.
@@ -1228,7 +1230,7 @@ xfs_dir2_leafn_remove(
1228 if (needscan) 1230 if (needscan)
1229 xfs_dir2_data_freescan(dp, hdr, &needlog); 1231 xfs_dir2_data_freescan(dp, hdr, &needlog);
1230 if (needlog) 1232 if (needlog)
1231 xfs_dir2_data_log_header(tp, dp, dbp); 1233 xfs_dir2_data_log_header(args, dbp);
1232 xfs_dir3_data_check(dp, dbp); 1234 xfs_dir3_data_check(dp, dbp);
1233 /* 1235 /*
1234 * If the longest data block freespace changes, need to update 1236 * If the longest data block freespace changes, need to update
@@ -1245,8 +1247,9 @@ xfs_dir2_leafn_remove(
1245 * Convert the data block number to a free block, 1247 * Convert the data block number to a free block,
1246 * read in the free block. 1248 * read in the free block.
1247 */ 1249 */
1248 fdb = dp->d_ops->db_to_fdb(mp, db); 1250 fdb = dp->d_ops->db_to_fdb(args->geo, db);
1249 error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(mp, fdb), 1251 error = xfs_dir2_free_read(tp, dp,
1252 xfs_dir2_db_to_da(args->geo, fdb),
1250 &fbp); 1253 &fbp);
1251 if (error) 1254 if (error)
1252 return error; 1255 return error;
@@ -1255,20 +1258,21 @@ xfs_dir2_leafn_remove(
1255 { 1258 {
1256 struct xfs_dir3_icfree_hdr freehdr; 1259 struct xfs_dir3_icfree_hdr freehdr;
1257 dp->d_ops->free_hdr_from_disk(&freehdr, free); 1260 dp->d_ops->free_hdr_from_disk(&freehdr, free);
1258 ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(mp) * 1261 ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) *
1259 (fdb - XFS_DIR2_FREE_FIRSTDB(mp))); 1262 (fdb - xfs_dir2_byte_to_db(args->geo,
1263 XFS_DIR2_FREE_OFFSET)));
1260 } 1264 }
1261#endif 1265#endif
1262 /* 1266 /*
1263 * Calculate which entry we need to fix. 1267 * Calculate which entry we need to fix.
1264 */ 1268 */
1265 findex = dp->d_ops->db_to_fdindex(mp, db); 1269 findex = dp->d_ops->db_to_fdindex(args->geo, db);
1266 longest = be16_to_cpu(bf[0].length); 1270 longest = be16_to_cpu(bf[0].length);
1267 /* 1271 /*
1268 * If the data block is now empty we can get rid of it 1272 * If the data block is now empty we can get rid of it
1269 * (usually). 1273 * (usually).
1270 */ 1274 */
1271 if (longest == mp->m_dirblksize - 1275 if (longest == args->geo->blksize -
1272 dp->d_ops->data_entry_offset) { 1276 dp->d_ops->data_entry_offset) {
1273 /* 1277 /*
1274 * Try to punch out the data block. 1278 * Try to punch out the data block.
@@ -1303,7 +1307,7 @@ xfs_dir2_leafn_remove(
1303 */ 1307 */
1304 *rval = (dp->d_ops->leaf_hdr_size + 1308 *rval = (dp->d_ops->leaf_hdr_size +
1305 (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) < 1309 (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) <
1306 mp->m_dir_magicpct; 1310 args->geo->magicpct;
1307 return 0; 1311 return 0;
1308} 1312}
1309 1313
@@ -1336,7 +1340,7 @@ xfs_dir2_leafn_split(
1336 /* 1340 /*
1337 * Initialize the new leaf block. 1341 * Initialize the new leaf block.
1338 */ 1342 */
1339 error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(mp, blkno), 1343 error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(args->geo, blkno),
1340 &newblk->bp, XFS_DIR2_LEAFN_MAGIC); 1344 &newblk->bp, XFS_DIR2_LEAFN_MAGIC);
1341 if (error) 1345 if (error)
1342 return error; 1346 return error;
@@ -1410,7 +1414,7 @@ xfs_dir2_leafn_toosmall(
1410 1414
1411 count = leafhdr.count - leafhdr.stale; 1415 count = leafhdr.count - leafhdr.stale;
1412 bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]); 1416 bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]);
1413 if (bytes > (state->blocksize >> 1)) { 1417 if (bytes > (state->args->geo->blksize >> 1)) {
1414 /* 1418 /*
1415 * Blk over 50%, don't try to join. 1419 * Blk over 50%, don't try to join.
1416 */ 1420 */
@@ -1463,7 +1467,8 @@ xfs_dir2_leafn_toosmall(
1463 * Count bytes in the two blocks combined. 1467 * Count bytes in the two blocks combined.
1464 */ 1468 */
1465 count = leafhdr.count - leafhdr.stale; 1469 count = leafhdr.count - leafhdr.stale;
1466 bytes = state->blocksize - (state->blocksize >> 2); 1470 bytes = state->args->geo->blksize -
1471 (state->args->geo->blksize >> 2);
1467 1472
1468 leaf = bp->b_addr; 1473 leaf = bp->b_addr;
1469 dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf); 1474 dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf);
@@ -1560,8 +1565,8 @@ xfs_dir2_leafn_unbalance(
1560 /* log the changes made when moving the entries */ 1565 /* log the changes made when moving the entries */
1561 dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr); 1566 dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr);
1562 dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr); 1567 dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr);
1563 xfs_dir3_leaf_log_header(args->trans, dp, save_blk->bp); 1568 xfs_dir3_leaf_log_header(args, save_blk->bp);
1564 xfs_dir3_leaf_log_header(args->trans, dp, drop_blk->bp); 1569 xfs_dir3_leaf_log_header(args, drop_blk->bp);
1565 1570
1566 xfs_dir3_leaf_check(dp, save_blk->bp); 1571 xfs_dir3_leaf_check(dp, save_blk->bp);
1567 xfs_dir3_leaf_check(dp, drop_blk->bp); 1572 xfs_dir3_leaf_check(dp, drop_blk->bp);
@@ -1587,8 +1592,6 @@ xfs_dir2_node_addname(
1587 state = xfs_da_state_alloc(); 1592 state = xfs_da_state_alloc();
1588 state->args = args; 1593 state->args = args;
1589 state->mp = args->dp->i_mount; 1594 state->mp = args->dp->i_mount;
1590 state->blocksize = state->mp->m_dirblksize;
1591 state->node_ents = state->mp->m_dir_node_ents;
1592 /* 1595 /*
1593 * Look up the name. We're not supposed to find it, but 1596 * Look up the name. We're not supposed to find it, but
1594 * this gives us the insertion point. 1597 * this gives us the insertion point.
@@ -1727,9 +1730,9 @@ xfs_dir2_node_addname_int(
1727 if (dbno == -1) { 1730 if (dbno == -1) {
1728 xfs_fileoff_t fo; /* freespace block number */ 1731 xfs_fileoff_t fo; /* freespace block number */
1729 1732
1730 if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) 1733 if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK)))
1731 return error; 1734 return error;
1732 lastfbno = xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo); 1735 lastfbno = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo);
1733 fbno = ifbno; 1736 fbno = ifbno;
1734 } 1737 }
1735 /* 1738 /*
@@ -1747,7 +1750,8 @@ xfs_dir2_node_addname_int(
1747 * us a freespace block to start with. 1750 * us a freespace block to start with.
1748 */ 1751 */
1749 if (++fbno == 0) 1752 if (++fbno == 0)
1750 fbno = XFS_DIR2_FREE_FIRSTDB(mp); 1753 fbno = xfs_dir2_byte_to_db(args->geo,
1754 XFS_DIR2_FREE_OFFSET);
1751 /* 1755 /*
1752 * If it's ifbno we already looked at it. 1756 * If it's ifbno we already looked at it.
1753 */ 1757 */
@@ -1765,8 +1769,8 @@ xfs_dir2_node_addname_int(
1765 * to avoid it. 1769 * to avoid it.
1766 */ 1770 */
1767 error = xfs_dir2_free_try_read(tp, dp, 1771 error = xfs_dir2_free_try_read(tp, dp,
1768 xfs_dir2_db_to_da(mp, fbno), 1772 xfs_dir2_db_to_da(args->geo, fbno),
1769 &fbp); 1773 &fbp);
1770 if (error) 1774 if (error)
1771 return error; 1775 return error;
1772 if (!fbp) 1776 if (!fbp)
@@ -1834,10 +1838,10 @@ xfs_dir2_node_addname_int(
1834 * Get the freespace block corresponding to the data block 1838 * Get the freespace block corresponding to the data block
1835 * that was just allocated. 1839 * that was just allocated.
1836 */ 1840 */
1837 fbno = dp->d_ops->db_to_fdb(mp, dbno); 1841 fbno = dp->d_ops->db_to_fdb(args->geo, dbno);
1838 error = xfs_dir2_free_try_read(tp, dp, 1842 error = xfs_dir2_free_try_read(tp, dp,
1839 xfs_dir2_db_to_da(mp, fbno), 1843 xfs_dir2_db_to_da(args->geo, fbno),
1840 &fbp); 1844 &fbp);
1841 if (error) 1845 if (error)
1842 return error; 1846 return error;
1843 1847
@@ -1851,12 +1855,13 @@ xfs_dir2_node_addname_int(
1851 if (error) 1855 if (error)
1852 return error; 1856 return error;
1853 1857
1854 if (unlikely(dp->d_ops->db_to_fdb(mp, dbno) != fbno)) { 1858 if (dp->d_ops->db_to_fdb(args->geo, dbno) != fbno) {
1855 xfs_alert(mp, 1859 xfs_alert(mp,
1856 "%s: dir ino %llu needed freesp block %lld for\n" 1860 "%s: dir ino %llu needed freesp block %lld for\n"
1857 " data block %lld, got %lld ifbno %llu lastfbno %d", 1861 " data block %lld, got %lld ifbno %llu lastfbno %d",
1858 __func__, (unsigned long long)dp->i_ino, 1862 __func__, (unsigned long long)dp->i_ino,
1859 (long long)dp->d_ops->db_to_fdb(mp, dbno), 1863 (long long)dp->d_ops->db_to_fdb(
1864 args->geo, dbno),
1860 (long long)dbno, (long long)fbno, 1865 (long long)dbno, (long long)fbno,
1861 (unsigned long long)ifbno, lastfbno); 1866 (unsigned long long)ifbno, lastfbno);
1862 if (fblk) { 1867 if (fblk) {
@@ -1877,7 +1882,7 @@ xfs_dir2_node_addname_int(
1877 /* 1882 /*
1878 * Get a buffer for the new block. 1883 * Get a buffer for the new block.
1879 */ 1884 */
1880 error = xfs_dir3_free_get_buf(tp, dp, fbno, &fbp); 1885 error = xfs_dir3_free_get_buf(args, fbno, &fbp);
1881 if (error) 1886 if (error)
1882 return error; 1887 return error;
1883 free = fbp->b_addr; 1888 free = fbp->b_addr;
@@ -1887,8 +1892,10 @@ xfs_dir2_node_addname_int(
1887 /* 1892 /*
1888 * Remember the first slot as our empty slot. 1893 * Remember the first slot as our empty slot.
1889 */ 1894 */
1890 freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * 1895 freehdr.firstdb =
1891 dp->d_ops->free_max_bests(mp); 1896 (fbno - xfs_dir2_byte_to_db(args->geo,
1897 XFS_DIR2_FREE_OFFSET)) *
1898 dp->d_ops->free_max_bests(args->geo);
1892 } else { 1899 } else {
1893 free = fbp->b_addr; 1900 free = fbp->b_addr;
1894 bests = dp->d_ops->free_bests_p(free); 1901 bests = dp->d_ops->free_bests_p(free);
@@ -1898,13 +1905,13 @@ xfs_dir2_node_addname_int(
1898 /* 1905 /*
1899 * Set the freespace block index from the data block number. 1906 * Set the freespace block index from the data block number.
1900 */ 1907 */
1901 findex = dp->d_ops->db_to_fdindex(mp, dbno); 1908 findex = dp->d_ops->db_to_fdindex(args->geo, dbno);
1902 /* 1909 /*
1903 * If it's after the end of the current entries in the 1910 * If it's after the end of the current entries in the
1904 * freespace block, extend that table. 1911 * freespace block, extend that table.
1905 */ 1912 */
1906 if (findex >= freehdr.nvalid) { 1913 if (findex >= freehdr.nvalid) {
1907 ASSERT(findex < dp->d_ops->free_max_bests(mp)); 1914 ASSERT(findex < dp->d_ops->free_max_bests(args->geo));
1908 freehdr.nvalid = findex + 1; 1915 freehdr.nvalid = findex + 1;
1909 /* 1916 /*
1910 * Tag new entry so nused will go up. 1917 * Tag new entry so nused will go up.
@@ -1918,7 +1925,7 @@ xfs_dir2_node_addname_int(
1918 if (bests[findex] == cpu_to_be16(NULLDATAOFF)) { 1925 if (bests[findex] == cpu_to_be16(NULLDATAOFF)) {
1919 freehdr.nused++; 1926 freehdr.nused++;
1920 dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); 1927 dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
1921 xfs_dir2_free_log_header(tp, dp, fbp); 1928 xfs_dir2_free_log_header(args, fbp);
1922 } 1929 }
1923 /* 1930 /*
1924 * Update the real value in the table. 1931 * Update the real value in the table.
@@ -1943,7 +1950,8 @@ xfs_dir2_node_addname_int(
1943 /* 1950 /*
1944 * Read the data block in. 1951 * Read the data block in.
1945 */ 1952 */
1946 error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno), 1953 error = xfs_dir3_data_read(tp, dp,
1954 xfs_dir2_db_to_da(args->geo, dbno),
1947 -1, &dbp); 1955 -1, &dbp);
1948 if (error) 1956 if (error)
1949 return error; 1957 return error;
@@ -1961,7 +1969,7 @@ xfs_dir2_node_addname_int(
1961 /* 1969 /*
1962 * Mark the first part of the unused space, inuse for us. 1970 * Mark the first part of the unused space, inuse for us.
1963 */ 1971 */
1964 xfs_dir2_data_use_free(tp, dp, dbp, dup, 1972 xfs_dir2_data_use_free(args, dbp, dup,
1965 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length, 1973 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
1966 &needlog, &needscan); 1974 &needlog, &needscan);
1967 /* 1975 /*
@@ -1974,7 +1982,7 @@ xfs_dir2_node_addname_int(
1974 dp->d_ops->data_put_ftype(dep, args->filetype); 1982 dp->d_ops->data_put_ftype(dep, args->filetype);
1975 tagp = dp->d_ops->data_entry_tag_p(dep); 1983 tagp = dp->d_ops->data_entry_tag_p(dep);
1976 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1984 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1977 xfs_dir2_data_log_entry(tp, dp, dbp, dep); 1985 xfs_dir2_data_log_entry(args, dbp, dep);
1978 /* 1986 /*
1979 * Rescan the block for bestfree if needed. 1987 * Rescan the block for bestfree if needed.
1980 */ 1988 */
@@ -1984,7 +1992,7 @@ xfs_dir2_node_addname_int(
1984 * Log the data block header if needed. 1992 * Log the data block header if needed.
1985 */ 1993 */
1986 if (needlog) 1994 if (needlog)
1987 xfs_dir2_data_log_header(tp, dp, dbp); 1995 xfs_dir2_data_log_header(args, dbp);
1988 /* 1996 /*
1989 * If the freespace entry is now wrong, update it. 1997 * If the freespace entry is now wrong, update it.
1990 */ 1998 */
@@ -1997,7 +2005,7 @@ xfs_dir2_node_addname_int(
1997 * Log the freespace entry if needed. 2005 * Log the freespace entry if needed.
1998 */ 2006 */
1999 if (logfree) 2007 if (logfree)
2000 xfs_dir2_free_log_bests(tp, dp, fbp, findex, findex); 2008 xfs_dir2_free_log_bests(args, fbp, findex, findex);
2001 /* 2009 /*
2002 * Return the data block and offset in args, then drop the data block. 2010 * Return the data block and offset in args, then drop the data block.
2003 */ 2011 */
@@ -2028,8 +2036,6 @@ xfs_dir2_node_lookup(
2028 state = xfs_da_state_alloc(); 2036 state = xfs_da_state_alloc();
2029 state->args = args; 2037 state->args = args;
2030 state->mp = args->dp->i_mount; 2038 state->mp = args->dp->i_mount;
2031 state->blocksize = state->mp->m_dirblksize;
2032 state->node_ents = state->mp->m_dir_node_ents;
2033 /* 2039 /*
2034 * Fill in the path to the entry in the cursor. 2040 * Fill in the path to the entry in the cursor.
2035 */ 2041 */
@@ -2083,8 +2089,6 @@ xfs_dir2_node_removename(
2083 state = xfs_da_state_alloc(); 2089 state = xfs_da_state_alloc();
2084 state->args = args; 2090 state->args = args;
2085 state->mp = args->dp->i_mount; 2091 state->mp = args->dp->i_mount;
2086 state->blocksize = state->mp->m_dirblksize;
2087 state->node_ents = state->mp->m_dir_node_ents;
2088 2092
2089 /* Look up the entry we're deleting, set up the cursor. */ 2093 /* Look up the entry we're deleting, set up the cursor. */
2090 error = xfs_da3_node_lookup_int(state, &rval); 2094 error = xfs_da3_node_lookup_int(state, &rval);
@@ -2153,8 +2157,6 @@ xfs_dir2_node_replace(
2153 state = xfs_da_state_alloc(); 2157 state = xfs_da_state_alloc();
2154 state->args = args; 2158 state->args = args;
2155 state->mp = args->dp->i_mount; 2159 state->mp = args->dp->i_mount;
2156 state->blocksize = state->mp->m_dirblksize;
2157 state->node_ents = state->mp->m_dir_node_ents;
2158 inum = args->inumber; 2160 inum = args->inumber;
2159 /* 2161 /*
2160 * Lookup the entry to change in the btree. 2162 * Lookup the entry to change in the btree.
@@ -2186,15 +2188,15 @@ xfs_dir2_node_replace(
2186 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); 2188 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
2187 dep = (xfs_dir2_data_entry_t *) 2189 dep = (xfs_dir2_data_entry_t *)
2188 ((char *)hdr + 2190 ((char *)hdr +
2189 xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); 2191 xfs_dir2_dataptr_to_off(args->geo,
2192 be32_to_cpu(lep->address)));
2190 ASSERT(inum != be64_to_cpu(dep->inumber)); 2193 ASSERT(inum != be64_to_cpu(dep->inumber));
2191 /* 2194 /*
2192 * Fill in the new inode number and log the entry. 2195 * Fill in the new inode number and log the entry.
2193 */ 2196 */
2194 dep->inumber = cpu_to_be64(inum); 2197 dep->inumber = cpu_to_be64(inum);
2195 args->dp->d_ops->data_put_ftype(dep, args->filetype); 2198 args->dp->d_ops->data_put_ftype(dep, args->filetype);
2196 xfs_dir2_data_log_entry(args->trans, args->dp, 2199 xfs_dir2_data_log_entry(args, state->extrablk.bp, dep);
2197 state->extrablk.bp, dep);
2198 rval = 0; 2200 rval = 0;
2199 } 2201 }
2200 /* 2202 /*
@@ -2262,9 +2264,9 @@ xfs_dir2_node_trim_free(
2262 /* 2264 /*
2263 * Blow the block away. 2265 * Blow the block away.
2264 */ 2266 */
2265 if ((error = 2267 error = xfs_dir2_shrink_inode(args,
2266 xfs_dir2_shrink_inode(args, xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo), 2268 xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo), bp);
2267 bp))) { 2269 if (error) {
2268 /* 2270 /*
2269 * Can't fail with ENOSPC since that only happens with no 2271 * Can't fail with ENOSPC since that only happens with no
2270 * space reservation, when breaking up an extent into two 2272 * space reservation, when breaking up an extent into two
diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h
index 8b9d2281f85b..27ce0794d196 100644
--- a/fs/xfs/xfs_dir2_priv.h
+++ b/fs/xfs/xfs_dir2_priv.h
@@ -20,6 +20,140 @@
20 20
21struct dir_context; 21struct dir_context;
22 22
23/*
24 * Directory offset/block conversion functions.
25 *
26 * DB blocks here are logical directory block numbers, not filesystem blocks.
27 */
28
29/*
30 * Convert dataptr to byte in file space
31 */
32static inline xfs_dir2_off_t
33xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
34{
35 return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
36}
37
38/*
39 * Convert byte in file space to dataptr. It had better be aligned.
40 */
41static inline xfs_dir2_dataptr_t
42xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
43{
44 return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
45}
46
47/*
48 * Convert byte in space to (DB) block
49 */
50static inline xfs_dir2_db_t
51xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
52{
53 return (xfs_dir2_db_t)(by >> geo->blklog);
54}
55
56/*
57 * Convert dataptr to a block number
58 */
59static inline xfs_dir2_db_t
60xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
61{
62 return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
63}
64
65/*
66 * Convert byte in space to offset in a block
67 */
68static inline xfs_dir2_data_aoff_t
69xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
70{
71 return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
72}
73
74/*
75 * Convert dataptr to a byte offset in a block
76 */
77static inline xfs_dir2_data_aoff_t
78xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
79{
80 return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
81}
82
83/*
84 * Convert block and offset to byte in space
85 */
86static inline xfs_dir2_off_t
87xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
88 xfs_dir2_data_aoff_t o)
89{
90 return ((xfs_dir2_off_t)db << geo->blklog) + o;
91}
92
93/*
94 * Convert block (DB) to block (dablk)
95 */
96static inline xfs_dablk_t
97xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
98{
99 return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
100}
101
102/*
103 * Convert byte in space to (DA) block
104 */
105static inline xfs_dablk_t
106xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
107{
108 return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
109}
110
111/*
112 * Convert block and offset to dataptr
113 */
114static inline xfs_dir2_dataptr_t
115xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
116 xfs_dir2_data_aoff_t o)
117{
118 return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
119}
120
121/*
122 * Convert block (dablk) to block (DB)
123 */
124static inline xfs_dir2_db_t
125xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
126{
127 return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
128}
129
130/*
131 * Convert block (dablk) to byte offset in space
132 */
133static inline xfs_dir2_off_t
134xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
135{
136 return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
137}
138
139/*
140 * Directory tail pointer accessor functions. Based on block geometry.
141 */
142static inline struct xfs_dir2_block_tail *
143xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
144{
145 return ((struct xfs_dir2_block_tail *)
146 ((char *)hdr + geo->blksize)) - 1;
147}
148
149static inline struct xfs_dir2_leaf_tail *
150xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
151{
152 return (struct xfs_dir2_leaf_tail *)
153 ((char *)lp + geo->blksize -
154 sizeof(struct xfs_dir2_leaf_tail));
155}
156
23/* xfs_dir2.c */ 157/* xfs_dir2.c */
24extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); 158extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
25extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, 159extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
@@ -54,8 +188,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
54extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); 188extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
55extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, 189extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp,
56 xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp); 190 xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp);
57extern int xfs_dir3_data_readahead(struct xfs_trans *tp, struct xfs_inode *dp, 191extern int xfs_dir3_data_readahead(struct xfs_inode *dp, xfs_dablk_t bno,
58 xfs_dablk_t bno, xfs_daddr_t mapped_bno); 192 xfs_daddr_t mapped_bno);
59 193
60extern struct xfs_dir2_data_free * 194extern struct xfs_dir2_data_free *
61xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr, 195xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr,
@@ -77,9 +211,9 @@ extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
77 int *lowstalep, int *highstalep, int *lowlogp, int *highlogp); 211 int *lowstalep, int *highstalep, int *lowlogp, int *highlogp);
78extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno, 212extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno,
79 struct xfs_buf **bpp, __uint16_t magic); 213 struct xfs_buf **bpp, __uint16_t magic);
80extern void xfs_dir3_leaf_log_ents(struct xfs_trans *tp, struct xfs_inode *dp, 214extern void xfs_dir3_leaf_log_ents(struct xfs_da_args *args,
81 struct xfs_buf *bp, int first, int last); 215 struct xfs_buf *bp, int first, int last);
82extern void xfs_dir3_leaf_log_header(struct xfs_trans *tp, struct xfs_inode *dp, 216extern void xfs_dir3_leaf_log_header(struct xfs_da_args *args,
83 struct xfs_buf *bp); 217 struct xfs_buf *bp);
84extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); 218extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
85extern int xfs_dir2_leaf_removename(struct xfs_da_args *args); 219extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index aead369e1c30..48e99afb9cb0 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -76,26 +76,25 @@ const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
76 76
77STATIC int 77STATIC int
78xfs_dir2_sf_getdents( 78xfs_dir2_sf_getdents(
79 xfs_inode_t *dp, /* incore directory inode */ 79 struct xfs_da_args *args,
80 struct dir_context *ctx) 80 struct dir_context *ctx)
81{ 81{
82 int i; /* shortform entry number */ 82 int i; /* shortform entry number */
83 xfs_mount_t *mp; /* filesystem mount point */ 83 struct xfs_inode *dp = args->dp; /* incore directory inode */
84 xfs_dir2_dataptr_t off; /* current entry's offset */ 84 xfs_dir2_dataptr_t off; /* current entry's offset */
85 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 85 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
86 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ 86 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
87 xfs_dir2_dataptr_t dot_offset; 87 xfs_dir2_dataptr_t dot_offset;
88 xfs_dir2_dataptr_t dotdot_offset; 88 xfs_dir2_dataptr_t dotdot_offset;
89 xfs_ino_t ino; 89 xfs_ino_t ino;
90 90 struct xfs_da_geometry *geo = args->geo;
91 mp = dp->i_mount;
92 91
93 ASSERT(dp->i_df.if_flags & XFS_IFINLINE); 92 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
94 /* 93 /*
95 * Give up if the directory is way too short. 94 * Give up if the directory is way too short.
96 */ 95 */
97 if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { 96 if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
98 ASSERT(XFS_FORCED_SHUTDOWN(mp)); 97 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
99 return XFS_ERROR(EIO); 98 return XFS_ERROR(EIO);
100 } 99 }
101 100
@@ -109,18 +108,18 @@ xfs_dir2_sf_getdents(
109 /* 108 /*
110 * If the block number in the offset is out of range, we're done. 109 * If the block number in the offset is out of range, we're done.
111 */ 110 */
112 if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk) 111 if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)
113 return 0; 112 return 0;
114 113
115 /* 114 /*
116 * Precalculate offsets for . and .. as we will always need them. 115 * Precalculate offsets for . and .. as we will always need them.
117 * 116 *
118 * XXX(hch): the second argument is sometimes 0 and sometimes 117 * XXX(hch): the second argument is sometimes 0 and sometimes
119 * mp->m_dirdatablk. 118 * geo->datablk
120 */ 119 */
121 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 120 dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
122 dp->d_ops->data_dot_offset); 121 dp->d_ops->data_dot_offset);
123 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 122 dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
124 dp->d_ops->data_dotdot_offset); 123 dp->d_ops->data_dotdot_offset);
125 124
126 /* 125 /*
@@ -149,7 +148,7 @@ xfs_dir2_sf_getdents(
149 for (i = 0; i < sfp->count; i++) { 148 for (i = 0; i < sfp->count; i++) {
150 __uint8_t filetype; 149 __uint8_t filetype;
151 150
152 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 151 off = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
153 xfs_dir2_sf_get_offset(sfep)); 152 xfs_dir2_sf_get_offset(sfep));
154 153
155 if (ctx->pos > off) { 154 if (ctx->pos > off) {
@@ -161,13 +160,13 @@ xfs_dir2_sf_getdents(
161 filetype = dp->d_ops->sf_get_ftype(sfep); 160 filetype = dp->d_ops->sf_get_ftype(sfep);
162 ctx->pos = off & 0x7fffffff; 161 ctx->pos = off & 0x7fffffff;
163 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, 162 if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
164 xfs_dir3_get_dtype(mp, filetype))) 163 xfs_dir3_get_dtype(dp->i_mount, filetype)))
165 return 0; 164 return 0;
166 sfep = dp->d_ops->sf_nextentry(sfp, sfep); 165 sfep = dp->d_ops->sf_nextentry(sfp, sfep);
167 } 166 }
168 167
169 ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & 168 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
170 0x7fffffff; 169 0x7fffffff;
171 return 0; 170 return 0;
172} 171}
173 172
@@ -176,9 +175,10 @@ xfs_dir2_sf_getdents(
176 */ 175 */
177STATIC int 176STATIC int
178xfs_dir2_block_getdents( 177xfs_dir2_block_getdents(
179 xfs_inode_t *dp, /* incore inode */ 178 struct xfs_da_args *args,
180 struct dir_context *ctx) 179 struct dir_context *ctx)
181{ 180{
181 struct xfs_inode *dp = args->dp; /* incore directory inode */
182 xfs_dir2_data_hdr_t *hdr; /* block header */ 182 xfs_dir2_data_hdr_t *hdr; /* block header */
183 struct xfs_buf *bp; /* buffer for block */ 183 struct xfs_buf *bp; /* buffer for block */
184 xfs_dir2_block_tail_t *btp; /* block tail */ 184 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -186,16 +186,15 @@ xfs_dir2_block_getdents(
186 xfs_dir2_data_unused_t *dup; /* block unused entry */ 186 xfs_dir2_data_unused_t *dup; /* block unused entry */
187 char *endptr; /* end of the data entries */ 187 char *endptr; /* end of the data entries */
188 int error; /* error return value */ 188 int error; /* error return value */
189 xfs_mount_t *mp; /* filesystem mount point */
190 char *ptr; /* current data entry */ 189 char *ptr; /* current data entry */
191 int wantoff; /* starting block offset */ 190 int wantoff; /* starting block offset */
192 xfs_off_t cook; 191 xfs_off_t cook;
192 struct xfs_da_geometry *geo = args->geo;
193 193
194 mp = dp->i_mount;
195 /* 194 /*
196 * If the block number in the offset is out of range, we're done. 195 * If the block number in the offset is out of range, we're done.
197 */ 196 */
198 if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk) 197 if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)
199 return 0; 198 return 0;
200 199
201 error = xfs_dir3_block_read(NULL, dp, &bp); 200 error = xfs_dir3_block_read(NULL, dp, &bp);
@@ -206,13 +205,13 @@ xfs_dir2_block_getdents(
206 * Extract the byte offset we start at from the seek pointer. 205 * Extract the byte offset we start at from the seek pointer.
207 * We'll skip entries before this. 206 * We'll skip entries before this.
208 */ 207 */
209 wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos); 208 wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos);
210 hdr = bp->b_addr; 209 hdr = bp->b_addr;
211 xfs_dir3_data_check(dp, bp); 210 xfs_dir3_data_check(dp, bp);
212 /* 211 /*
213 * Set up values for the loop. 212 * Set up values for the loop.
214 */ 213 */
215 btp = xfs_dir2_block_tail_p(mp, hdr); 214 btp = xfs_dir2_block_tail_p(geo, hdr);
216 ptr = (char *)dp->d_ops->data_entry_p(hdr); 215 ptr = (char *)dp->d_ops->data_entry_p(hdr);
217 endptr = (char *)xfs_dir2_block_leaf_p(btp); 216 endptr = (char *)xfs_dir2_block_leaf_p(btp);
218 217
@@ -244,7 +243,7 @@ xfs_dir2_block_getdents(
244 if ((char *)dep - (char *)hdr < wantoff) 243 if ((char *)dep - (char *)hdr < wantoff)
245 continue; 244 continue;
246 245
247 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 246 cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
248 (char *)dep - (char *)hdr); 247 (char *)dep - (char *)hdr);
249 248
250 ctx->pos = cook & 0x7fffffff; 249 ctx->pos = cook & 0x7fffffff;
@@ -254,7 +253,7 @@ xfs_dir2_block_getdents(
254 */ 253 */
255 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 254 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
256 be64_to_cpu(dep->inumber), 255 be64_to_cpu(dep->inumber),
257 xfs_dir3_get_dtype(mp, filetype))) { 256 xfs_dir3_get_dtype(dp->i_mount, filetype))) {
258 xfs_trans_brelse(NULL, bp); 257 xfs_trans_brelse(NULL, bp);
259 return 0; 258 return 0;
260 } 259 }
@@ -264,8 +263,8 @@ xfs_dir2_block_getdents(
264 * Reached the end of the block. 263 * Reached the end of the block.
265 * Set the offset to a non-existent block 1 and return. 264 * Set the offset to a non-existent block 1 and return.
266 */ 265 */
267 ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & 266 ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
268 0x7fffffff; 267 0x7fffffff;
269 xfs_trans_brelse(NULL, bp); 268 xfs_trans_brelse(NULL, bp);
270 return 0; 269 return 0;
271} 270}
@@ -286,13 +285,13 @@ struct xfs_dir2_leaf_map_info {
286 285
287STATIC int 286STATIC int
288xfs_dir2_leaf_readbuf( 287xfs_dir2_leaf_readbuf(
289 struct xfs_inode *dp, 288 struct xfs_da_args *args,
290 size_t bufsize, 289 size_t bufsize,
291 struct xfs_dir2_leaf_map_info *mip, 290 struct xfs_dir2_leaf_map_info *mip,
292 xfs_dir2_off_t *curoff, 291 xfs_dir2_off_t *curoff,
293 struct xfs_buf **bpp) 292 struct xfs_buf **bpp)
294{ 293{
295 struct xfs_mount *mp = dp->i_mount; 294 struct xfs_inode *dp = args->dp;
296 struct xfs_buf *bp = *bpp; 295 struct xfs_buf *bp = *bpp;
297 struct xfs_bmbt_irec *map = mip->map; 296 struct xfs_bmbt_irec *map = mip->map;
298 struct blk_plug plug; 297 struct blk_plug plug;
@@ -300,6 +299,7 @@ xfs_dir2_leaf_readbuf(
300 int length; 299 int length;
301 int i; 300 int i;
302 int j; 301 int j;
302 struct xfs_da_geometry *geo = args->geo;
303 303
304 /* 304 /*
305 * If we have a buffer, we need to release it and 305 * If we have a buffer, we need to release it and
@@ -309,12 +309,12 @@ xfs_dir2_leaf_readbuf(
309 if (bp) { 309 if (bp) {
310 xfs_trans_brelse(NULL, bp); 310 xfs_trans_brelse(NULL, bp);
311 bp = NULL; 311 bp = NULL;
312 mip->map_blocks -= mp->m_dirblkfsbs; 312 mip->map_blocks -= geo->fsbcount;
313 /* 313 /*
314 * Loop to get rid of the extents for the 314 * Loop to get rid of the extents for the
315 * directory block. 315 * directory block.
316 */ 316 */
317 for (i = mp->m_dirblkfsbs; i > 0; ) { 317 for (i = geo->fsbcount; i > 0; ) {
318 j = min_t(int, map->br_blockcount, i); 318 j = min_t(int, map->br_blockcount, i);
319 map->br_blockcount -= j; 319 map->br_blockcount -= j;
320 map->br_startblock += j; 320 map->br_startblock += j;
@@ -333,8 +333,7 @@ xfs_dir2_leaf_readbuf(
333 /* 333 /*
334 * Recalculate the readahead blocks wanted. 334 * Recalculate the readahead blocks wanted.
335 */ 335 */
336 mip->ra_want = howmany(bufsize + mp->m_dirblksize, 336 mip->ra_want = howmany(bufsize + geo->blksize, (1 << geo->fsblog)) - 1;
337 mp->m_sb.sb_blocksize) - 1;
338 ASSERT(mip->ra_want >= 0); 337 ASSERT(mip->ra_want >= 0);
339 338
340 /* 339 /*
@@ -342,14 +341,14 @@ xfs_dir2_leaf_readbuf(
342 * run out of data blocks, get some more mappings. 341 * run out of data blocks, get some more mappings.
343 */ 342 */
344 if (1 + mip->ra_want > mip->map_blocks && 343 if (1 + mip->ra_want > mip->map_blocks &&
345 mip->map_off < xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) { 344 mip->map_off < xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET)) {
346 /* 345 /*
347 * Get more bmaps, fill in after the ones 346 * Get more bmaps, fill in after the ones
348 * we already have in the table. 347 * we already have in the table.
349 */ 348 */
350 mip->nmap = mip->map_size - mip->map_valid; 349 mip->nmap = mip->map_size - mip->map_valid;
351 error = xfs_bmapi_read(dp, mip->map_off, 350 error = xfs_bmapi_read(dp, mip->map_off,
352 xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET) - 351 xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET) -
353 mip->map_off, 352 mip->map_off,
354 &map[mip->map_valid], &mip->nmap, 0); 353 &map[mip->map_valid], &mip->nmap, 0);
355 354
@@ -370,7 +369,7 @@ xfs_dir2_leaf_readbuf(
370 i = mip->map_valid + mip->nmap - 1; 369 i = mip->map_valid + mip->nmap - 1;
371 mip->map_off = map[i].br_startoff + map[i].br_blockcount; 370 mip->map_off = map[i].br_startoff + map[i].br_blockcount;
372 } else 371 } else
373 mip->map_off = xfs_dir2_byte_to_da(mp, 372 mip->map_off = xfs_dir2_byte_to_da(geo,
374 XFS_DIR2_LEAF_OFFSET); 373 XFS_DIR2_LEAF_OFFSET);
375 374
376 /* 375 /*
@@ -396,18 +395,18 @@ xfs_dir2_leaf_readbuf(
396 * No valid mappings, so no more data blocks. 395 * No valid mappings, so no more data blocks.
397 */ 396 */
398 if (!mip->map_valid) { 397 if (!mip->map_valid) {
399 *curoff = xfs_dir2_da_to_byte(mp, mip->map_off); 398 *curoff = xfs_dir2_da_to_byte(geo, mip->map_off);
400 goto out; 399 goto out;
401 } 400 }
402 401
403 /* 402 /*
404 * Read the directory block starting at the first mapping. 403 * Read the directory block starting at the first mapping.
405 */ 404 */
406 mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff); 405 mip->curdb = xfs_dir2_da_to_db(geo, map->br_startoff);
407 error = xfs_dir3_data_read(NULL, dp, map->br_startoff, 406 error = xfs_dir3_data_read(NULL, dp, map->br_startoff,
408 map->br_blockcount >= mp->m_dirblkfsbs ? 407 map->br_blockcount >= geo->fsbcount ?
409 XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp); 408 XFS_FSB_TO_DADDR(dp->i_mount, map->br_startblock) :
410 409 -1, &bp);
411 /* 410 /*
412 * Should just skip over the data block instead of giving up. 411 * Should just skip over the data block instead of giving up.
413 */ 412 */
@@ -419,7 +418,7 @@ xfs_dir2_leaf_readbuf(
419 * was previously ra. 418 * was previously ra.
420 */ 419 */
421 if (mip->ra_current) 420 if (mip->ra_current)
422 mip->ra_current -= mp->m_dirblkfsbs; 421 mip->ra_current -= geo->fsbcount;
423 422
424 /* 423 /*
425 * Do we need more readahead? 424 * Do we need more readahead?
@@ -427,16 +426,16 @@ xfs_dir2_leaf_readbuf(
427 blk_start_plug(&plug); 426 blk_start_plug(&plug);
428 for (mip->ra_index = mip->ra_offset = i = 0; 427 for (mip->ra_index = mip->ra_offset = i = 0;
429 mip->ra_want > mip->ra_current && i < mip->map_blocks; 428 mip->ra_want > mip->ra_current && i < mip->map_blocks;
430 i += mp->m_dirblkfsbs) { 429 i += geo->fsbcount) {
431 ASSERT(mip->ra_index < mip->map_valid); 430 ASSERT(mip->ra_index < mip->map_valid);
432 /* 431 /*
433 * Read-ahead a contiguous directory block. 432 * Read-ahead a contiguous directory block.
434 */ 433 */
435 if (i > mip->ra_current && 434 if (i > mip->ra_current &&
436 map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) { 435 map[mip->ra_index].br_blockcount >= geo->fsbcount) {
437 xfs_dir3_data_readahead(NULL, dp, 436 xfs_dir3_data_readahead(dp,
438 map[mip->ra_index].br_startoff + mip->ra_offset, 437 map[mip->ra_index].br_startoff + mip->ra_offset,
439 XFS_FSB_TO_DADDR(mp, 438 XFS_FSB_TO_DADDR(dp->i_mount,
440 map[mip->ra_index].br_startblock + 439 map[mip->ra_index].br_startblock +
441 mip->ra_offset)); 440 mip->ra_offset));
442 mip->ra_current = i; 441 mip->ra_current = i;
@@ -447,7 +446,7 @@ xfs_dir2_leaf_readbuf(
447 * use our mapping, but this is a very rare case. 446 * use our mapping, but this is a very rare case.
448 */ 447 */
449 else if (i > mip->ra_current) { 448 else if (i > mip->ra_current) {
450 xfs_dir3_data_readahead(NULL, dp, 449 xfs_dir3_data_readahead(dp,
451 map[mip->ra_index].br_startoff + 450 map[mip->ra_index].br_startoff +
452 mip->ra_offset, -1); 451 mip->ra_offset, -1);
453 mip->ra_current = i; 452 mip->ra_current = i;
@@ -456,15 +455,14 @@ xfs_dir2_leaf_readbuf(
456 /* 455 /*
457 * Advance offset through the mapping table. 456 * Advance offset through the mapping table.
458 */ 457 */
459 for (j = 0; j < mp->m_dirblkfsbs; j++) { 458 for (j = 0; j < geo->fsbcount; j += length ) {
460 /* 459 /*
461 * The rest of this extent but not more than a dir 460 * The rest of this extent but not more than a dir
462 * block. 461 * block.
463 */ 462 */
464 length = min_t(int, mp->m_dirblkfsbs, 463 length = min_t(int, geo->fsbcount,
465 map[mip->ra_index].br_blockcount - 464 map[mip->ra_index].br_blockcount -
466 mip->ra_offset); 465 mip->ra_offset);
467 j += length;
468 mip->ra_offset += length; 466 mip->ra_offset += length;
469 467
470 /* 468 /*
@@ -489,22 +487,23 @@ out:
489 */ 487 */
490STATIC int 488STATIC int
491xfs_dir2_leaf_getdents( 489xfs_dir2_leaf_getdents(
492 xfs_inode_t *dp, /* incore directory inode */ 490 struct xfs_da_args *args,
493 struct dir_context *ctx, 491 struct dir_context *ctx,
494 size_t bufsize) 492 size_t bufsize)
495{ 493{
494 struct xfs_inode *dp = args->dp;
496 struct xfs_buf *bp = NULL; /* data block buffer */ 495 struct xfs_buf *bp = NULL; /* data block buffer */
497 xfs_dir2_data_hdr_t *hdr; /* data block header */ 496 xfs_dir2_data_hdr_t *hdr; /* data block header */
498 xfs_dir2_data_entry_t *dep; /* data entry */ 497 xfs_dir2_data_entry_t *dep; /* data entry */
499 xfs_dir2_data_unused_t *dup; /* unused entry */ 498 xfs_dir2_data_unused_t *dup; /* unused entry */
500 int error = 0; /* error return value */ 499 int error = 0; /* error return value */
501 int length; /* temporary length value */ 500 int length; /* temporary length value */
502 xfs_mount_t *mp; /* filesystem mount point */
503 int byteoff; /* offset in current block */ 501 int byteoff; /* offset in current block */
504 xfs_dir2_off_t curoff; /* current overall offset */ 502 xfs_dir2_off_t curoff; /* current overall offset */
505 xfs_dir2_off_t newoff; /* new curoff after new blk */ 503 xfs_dir2_off_t newoff; /* new curoff after new blk */
506 char *ptr = NULL; /* pointer to current data */ 504 char *ptr = NULL; /* pointer to current data */
507 struct xfs_dir2_leaf_map_info *map_info; 505 struct xfs_dir2_leaf_map_info *map_info;
506 struct xfs_da_geometry *geo = args->geo;
508 507
509 /* 508 /*
510 * If the offset is at or past the largest allowed value, 509 * If the offset is at or past the largest allowed value,
@@ -513,15 +512,12 @@ xfs_dir2_leaf_getdents(
513 if (ctx->pos >= XFS_DIR2_MAX_DATAPTR) 512 if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
514 return 0; 513 return 0;
515 514
516 mp = dp->i_mount;
517
518 /* 515 /*
519 * Set up to bmap a number of blocks based on the caller's 516 * Set up to bmap a number of blocks based on the caller's
520 * buffer size, the directory block size, and the filesystem 517 * buffer size, the directory block size, and the filesystem
521 * block size. 518 * block size.
522 */ 519 */
523 length = howmany(bufsize + mp->m_dirblksize, 520 length = howmany(bufsize + geo->blksize, (1 << geo->fsblog));
524 mp->m_sb.sb_blocksize);
525 map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) + 521 map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +
526 (length * sizeof(struct xfs_bmbt_irec)), 522 (length * sizeof(struct xfs_bmbt_irec)),
527 KM_SLEEP | KM_NOFS); 523 KM_SLEEP | KM_NOFS);
@@ -531,14 +527,14 @@ xfs_dir2_leaf_getdents(
531 * Inside the loop we keep the main offset value as a byte offset 527 * Inside the loop we keep the main offset value as a byte offset
532 * in the directory file. 528 * in the directory file.
533 */ 529 */
534 curoff = xfs_dir2_dataptr_to_byte(mp, ctx->pos); 530 curoff = xfs_dir2_dataptr_to_byte(ctx->pos);
535 531
536 /* 532 /*
537 * Force this conversion through db so we truncate the offset 533 * Force this conversion through db so we truncate the offset
538 * down to get the start of the data block. 534 * down to get the start of the data block.
539 */ 535 */
540 map_info->map_off = xfs_dir2_db_to_da(mp, 536 map_info->map_off = xfs_dir2_db_to_da(geo,
541 xfs_dir2_byte_to_db(mp, curoff)); 537 xfs_dir2_byte_to_db(geo, curoff));
542 538
543 /* 539 /*
544 * Loop over directory entries until we reach the end offset. 540 * Loop over directory entries until we reach the end offset.
@@ -551,9 +547,9 @@ xfs_dir2_leaf_getdents(
551 * If we have no buffer, or we're off the end of the 547 * If we have no buffer, or we're off the end of the
552 * current buffer, need to get another one. 548 * current buffer, need to get another one.
553 */ 549 */
554 if (!bp || ptr >= (char *)bp->b_addr + mp->m_dirblksize) { 550 if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) {
555 551
556 error = xfs_dir2_leaf_readbuf(dp, bufsize, map_info, 552 error = xfs_dir2_leaf_readbuf(args, bufsize, map_info,
557 &curoff, &bp); 553 &curoff, &bp);
558 if (error || !map_info->map_valid) 554 if (error || !map_info->map_valid)
559 break; 555 break;
@@ -561,7 +557,8 @@ xfs_dir2_leaf_getdents(
561 /* 557 /*
562 * Having done a read, we need to set a new offset. 558 * Having done a read, we need to set a new offset.
563 */ 559 */
564 newoff = xfs_dir2_db_off_to_byte(mp, map_info->curdb, 0); 560 newoff = xfs_dir2_db_off_to_byte(geo,
561 map_info->curdb, 0);
565 /* 562 /*
566 * Start of the current block. 563 * Start of the current block.
567 */ 564 */
@@ -571,7 +568,7 @@ xfs_dir2_leaf_getdents(
571 * Make sure we're in the right block. 568 * Make sure we're in the right block.
572 */ 569 */
573 else if (curoff > newoff) 570 else if (curoff > newoff)
574 ASSERT(xfs_dir2_byte_to_db(mp, curoff) == 571 ASSERT(xfs_dir2_byte_to_db(geo, curoff) ==
575 map_info->curdb); 572 map_info->curdb);
576 hdr = bp->b_addr; 573 hdr = bp->b_addr;
577 xfs_dir3_data_check(dp, bp); 574 xfs_dir3_data_check(dp, bp);
@@ -579,7 +576,7 @@ xfs_dir2_leaf_getdents(
579 * Find our position in the block. 576 * Find our position in the block.
580 */ 577 */
581 ptr = (char *)dp->d_ops->data_entry_p(hdr); 578 ptr = (char *)dp->d_ops->data_entry_p(hdr);
582 byteoff = xfs_dir2_byte_to_off(mp, curoff); 579 byteoff = xfs_dir2_byte_to_off(geo, curoff);
583 /* 580 /*
584 * Skip past the header. 581 * Skip past the header.
585 */ 582 */
@@ -608,10 +605,10 @@ xfs_dir2_leaf_getdents(
608 * Now set our real offset. 605 * Now set our real offset.
609 */ 606 */
610 curoff = 607 curoff =
611 xfs_dir2_db_off_to_byte(mp, 608 xfs_dir2_db_off_to_byte(geo,
612 xfs_dir2_byte_to_db(mp, curoff), 609 xfs_dir2_byte_to_db(geo, curoff),
613 (char *)ptr - (char *)hdr); 610 (char *)ptr - (char *)hdr);
614 if (ptr >= (char *)hdr + mp->m_dirblksize) { 611 if (ptr >= (char *)hdr + geo->blksize) {
615 continue; 612 continue;
616 } 613 }
617 } 614 }
@@ -635,10 +632,10 @@ xfs_dir2_leaf_getdents(
635 length = dp->d_ops->data_entsize(dep->namelen); 632 length = dp->d_ops->data_entsize(dep->namelen);
636 filetype = dp->d_ops->data_get_ftype(dep); 633 filetype = dp->d_ops->data_get_ftype(dep);
637 634
638 ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff; 635 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
639 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 636 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
640 be64_to_cpu(dep->inumber), 637 be64_to_cpu(dep->inumber),
641 xfs_dir3_get_dtype(mp, filetype))) 638 xfs_dir3_get_dtype(dp->i_mount, filetype)))
642 break; 639 break;
643 640
644 /* 641 /*
@@ -653,10 +650,10 @@ xfs_dir2_leaf_getdents(
653 /* 650 /*
654 * All done. Set output offset value to current offset. 651 * All done. Set output offset value to current offset.
655 */ 652 */
656 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) 653 if (curoff > xfs_dir2_dataptr_to_byte(XFS_DIR2_MAX_DATAPTR))
657 ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff; 654 ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;
658 else 655 else
659 ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff; 656 ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
660 kmem_free(map_info); 657 kmem_free(map_info);
661 if (bp) 658 if (bp)
662 xfs_trans_brelse(NULL, bp); 659 xfs_trans_brelse(NULL, bp);
@@ -668,13 +665,14 @@ xfs_dir2_leaf_getdents(
668 */ 665 */
669int 666int
670xfs_readdir( 667xfs_readdir(
671 xfs_inode_t *dp, 668 struct xfs_inode *dp,
672 struct dir_context *ctx, 669 struct dir_context *ctx,
673 size_t bufsize) 670 size_t bufsize)
674{ 671{
675 int rval; /* return value */ 672 struct xfs_da_args args = { NULL };
676 int v; /* type-checking value */ 673 int rval;
677 uint lock_mode; 674 int v;
675 uint lock_mode;
678 676
679 trace_xfs_readdir(dp); 677 trace_xfs_readdir(dp);
680 678
@@ -684,15 +682,18 @@ xfs_readdir(
684 ASSERT(S_ISDIR(dp->i_d.di_mode)); 682 ASSERT(S_ISDIR(dp->i_d.di_mode));
685 XFS_STATS_INC(xs_dir_getdents); 683 XFS_STATS_INC(xs_dir_getdents);
686 684
685 args.dp = dp;
686 args.geo = dp->i_mount->m_dir_geo;
687
687 lock_mode = xfs_ilock_data_map_shared(dp); 688 lock_mode = xfs_ilock_data_map_shared(dp);
688 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 689 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
689 rval = xfs_dir2_sf_getdents(dp, ctx); 690 rval = xfs_dir2_sf_getdents(&args, ctx);
690 else if ((rval = xfs_dir2_isblock(NULL, dp, &v))) 691 else if ((rval = xfs_dir2_isblock(&args, &v)))
691 ; 692 ;
692 else if (v) 693 else if (v)
693 rval = xfs_dir2_block_getdents(dp, ctx); 694 rval = xfs_dir2_block_getdents(&args, ctx);
694 else 695 else
695 rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize); 696 rval = xfs_dir2_leaf_getdents(&args, ctx, bufsize);
696 xfs_iunlock(dp, lock_mode); 697 xfs_iunlock(dp, lock_mode);
697 698
698 return rval; 699 return rval;
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index 3725fb1b902b..53c3be619db5 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -82,8 +82,10 @@ xfs_dir2_block_sfsize(
82 xfs_ino_t parent = 0; /* parent inode number */ 82 xfs_ino_t parent = 0; /* parent inode number */
83 int size=0; /* total computed size */ 83 int size=0; /* total computed size */
84 int has_ftype; 84 int has_ftype;
85 struct xfs_da_geometry *geo;
85 86
86 mp = dp->i_mount; 87 mp = dp->i_mount;
88 geo = mp->m_dir_geo;
87 89
88 /* 90 /*
89 * if there is a filetype field, add the extra byte to the namelen 91 * if there is a filetype field, add the extra byte to the namelen
@@ -92,7 +94,7 @@ xfs_dir2_block_sfsize(
92 has_ftype = xfs_sb_version_hasftype(&mp->m_sb) ? 1 : 0; 94 has_ftype = xfs_sb_version_hasftype(&mp->m_sb) ? 1 : 0;
93 95
94 count = i8count = namelen = 0; 96 count = i8count = namelen = 0;
95 btp = xfs_dir2_block_tail_p(mp, hdr); 97 btp = xfs_dir2_block_tail_p(geo, hdr);
96 blp = xfs_dir2_block_leaf_p(btp); 98 blp = xfs_dir2_block_leaf_p(btp);
97 99
98 /* 100 /*
@@ -104,8 +106,8 @@ xfs_dir2_block_sfsize(
104 /* 106 /*
105 * Calculate the pointer to the entry at hand. 107 * Calculate the pointer to the entry at hand.
106 */ 108 */
107 dep = (xfs_dir2_data_entry_t *) 109 dep = (xfs_dir2_data_entry_t *)((char *)hdr +
108 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); 110 xfs_dir2_dataptr_to_off(geo, addr));
109 /* 111 /*
110 * Detect . and .., so we can special-case them. 112 * Detect . and .., so we can special-case them.
111 * . is not included in sf directories. 113 * . is not included in sf directories.
@@ -195,7 +197,7 @@ xfs_dir2_block_to_sf(
195 /* 197 /*
196 * Set up to loop over the block's entries. 198 * Set up to loop over the block's entries.
197 */ 199 */
198 btp = xfs_dir2_block_tail_p(mp, hdr); 200 btp = xfs_dir2_block_tail_p(args->geo, hdr);
199 ptr = (char *)dp->d_ops->data_entry_p(hdr); 201 ptr = (char *)dp->d_ops->data_entry_p(hdr);
200 endptr = (char *)xfs_dir2_block_leaf_p(btp); 202 endptr = (char *)xfs_dir2_block_leaf_p(btp);
201 sfep = xfs_dir2_sf_firstentry(sfp); 203 sfep = xfs_dir2_sf_firstentry(sfp);
@@ -247,7 +249,7 @@ xfs_dir2_block_to_sf(
247 249
248 /* now we are done with the block, we can shrink the inode */ 250 /* now we are done with the block, we can shrink the inode */
249 logflags = XFS_ILOG_CORE; 251 logflags = XFS_ILOG_CORE;
250 error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp); 252 error = xfs_dir2_shrink_inode(args, args->geo->datablk, bp);
251 if (error) { 253 if (error) {
252 ASSERT(error != ENOSPC); 254 ASSERT(error != ENOSPC);
253 goto out; 255 goto out;
@@ -285,14 +287,12 @@ int /* error */
285xfs_dir2_sf_addname( 287xfs_dir2_sf_addname(
286 xfs_da_args_t *args) /* operation arguments */ 288 xfs_da_args_t *args) /* operation arguments */
287{ 289{
288 int add_entsize; /* size of the new entry */
289 xfs_inode_t *dp; /* incore directory inode */ 290 xfs_inode_t *dp; /* incore directory inode */
290 int error; /* error return value */ 291 int error; /* error return value */
291 int incr_isize; /* total change in size */ 292 int incr_isize; /* total change in size */
292 int new_isize; /* di_size after adding name */ 293 int new_isize; /* di_size after adding name */
293 int objchange; /* changing to 8-byte inodes */ 294 int objchange; /* changing to 8-byte inodes */
294 xfs_dir2_data_aoff_t offset = 0; /* offset for new entry */ 295 xfs_dir2_data_aoff_t offset = 0; /* offset for new entry */
295 int old_isize; /* di_size before adding name */
296 int pick; /* which algorithm to use */ 296 int pick; /* which algorithm to use */
297 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ 297 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
298 xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */ 298 xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */
@@ -316,8 +316,7 @@ xfs_dir2_sf_addname(
316 /* 316 /*
317 * Compute entry (and change in) size. 317 * Compute entry (and change in) size.
318 */ 318 */
319 add_entsize = dp->d_ops->sf_entsize(sfp, args->namelen); 319 incr_isize = dp->d_ops->sf_entsize(sfp, args->namelen);
320 incr_isize = add_entsize;
321 objchange = 0; 320 objchange = 0;
322#if XFS_BIG_INUMS 321#if XFS_BIG_INUMS
323 /* 322 /*
@@ -325,11 +324,8 @@ xfs_dir2_sf_addname(
325 */ 324 */
326 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) { 325 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) {
327 /* 326 /*
328 * Yes, adjust the entry size and the total size. 327 * Yes, adjust the inode size. old count + (parent + new)
329 */ 328 */
330 add_entsize +=
331 (uint)sizeof(xfs_dir2_ino8_t) -
332 (uint)sizeof(xfs_dir2_ino4_t);
333 incr_isize += 329 incr_isize +=
334 (sfp->count + 2) * 330 (sfp->count + 2) *
335 ((uint)sizeof(xfs_dir2_ino8_t) - 331 ((uint)sizeof(xfs_dir2_ino8_t) -
@@ -337,8 +333,7 @@ xfs_dir2_sf_addname(
337 objchange = 1; 333 objchange = 1;
338 } 334 }
339#endif 335#endif
340 old_isize = (int)dp->i_d.di_size; 336 new_isize = (int)dp->i_d.di_size + incr_isize;
341 new_isize = old_isize + incr_isize;
342 /* 337 /*
343 * Won't fit as shortform any more (due to size), 338 * Won't fit as shortform any more (due to size),
344 * or the pick routine says it won't (due to offset values). 339 * or the pick routine says it won't (due to offset values).
@@ -593,7 +588,7 @@ xfs_dir2_sf_addname_pick(
593 * we'll go back, convert to block, then try the insert and convert 588 * we'll go back, convert to block, then try the insert and convert
594 * to leaf. 589 * to leaf.
595 */ 590 */
596 if (used + (holefit ? 0 : size) > mp->m_dirblksize) 591 if (used + (holefit ? 0 : size) > args->geo->blksize)
597 return 0; 592 return 0;
598 /* 593 /*
599 * If changing the inode number size, do it the hard way. 594 * If changing the inode number size, do it the hard way.
@@ -608,7 +603,7 @@ xfs_dir2_sf_addname_pick(
608 /* 603 /*
609 * If it won't fit at the end then do it the hard way (use the hole). 604 * If it won't fit at the end then do it the hard way (use the hole).
610 */ 605 */
611 if (used + size > mp->m_dirblksize) 606 if (used + size > args->geo->blksize)
612 return 2; 607 return 2;
613 /* 608 /*
614 * Do it the easy way. 609 * Do it the easy way.
@@ -659,7 +654,7 @@ xfs_dir2_sf_check(
659 ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); 654 ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
660 ASSERT(offset + 655 ASSERT(offset +
661 (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + 656 (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
662 (uint)sizeof(xfs_dir2_block_tail_t) <= mp->m_dirblksize); 657 (uint)sizeof(xfs_dir2_block_tail_t) <= args->geo->blksize);
663} 658}
664#endif /* DEBUG */ 659#endif /* DEBUG */
665 660
@@ -1110,9 +1105,9 @@ xfs_dir2_sf_toino4(
1110} 1105}
1111 1106
1112/* 1107/*
1113 * Convert from 4-byte inode numbers to 8-byte inode numbers. 1108 * Convert existing entries from 4-byte inode numbers to 8-byte inode numbers.
1114 * The new 8-byte inode number is not there yet, we leave with the 1109 * The new entry w/ an 8-byte inode number is not there yet; we leave with
1115 * count 1 but no corresponding entry. 1110 * i8count set to 1, but no corresponding 8-byte entry.
1116 */ 1111 */
1117static void 1112static void
1118xfs_dir2_sf_toino8( 1113xfs_dir2_sf_toino8(
@@ -1145,7 +1140,7 @@ xfs_dir2_sf_toino8(
1145 ASSERT(oldsfp->i8count == 0); 1140 ASSERT(oldsfp->i8count == 0);
1146 memcpy(buf, oldsfp, oldsize); 1141 memcpy(buf, oldsfp, oldsize);
1147 /* 1142 /*
1148 * Compute the new inode size. 1143 * Compute the new inode size (nb: entry count + 1 for parent)
1149 */ 1144 */
1150 newsize = 1145 newsize =
1151 oldsize + 1146 oldsize +
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 868b19f096bf..3ee0cd43edc0 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -353,10 +353,10 @@ xfs_qm_dqalloc(
353 dqp->q_blkno, 353 dqp->q_blkno,
354 mp->m_quotainfo->qi_dqchunklen, 354 mp->m_quotainfo->qi_dqchunklen,
355 0); 355 0);
356 356 if (!bp) {
357 error = xfs_buf_geterror(bp); 357 error = ENOMEM;
358 if (error)
359 goto error1; 358 goto error1;
359 }
360 bp->b_ops = &xfs_dquot_buf_ops; 360 bp->b_ops = &xfs_dquot_buf_ops;
361 361
362 /* 362 /*
@@ -832,47 +832,6 @@ restart:
832 return (0); 832 return (0);
833} 833}
834 834
835
836STATIC void
837xfs_qm_dqput_final(
838 struct xfs_dquot *dqp)
839{
840 struct xfs_quotainfo *qi = dqp->q_mount->m_quotainfo;
841 struct xfs_dquot *gdqp;
842 struct xfs_dquot *pdqp;
843
844 trace_xfs_dqput_free(dqp);
845
846 if (list_lru_add(&qi->qi_lru, &dqp->q_lru))
847 XFS_STATS_INC(xs_qm_dquot_unused);
848
849 /*
850 * If we just added a udquot to the freelist, then we want to release
851 * the gdquot/pdquot reference that it (probably) has. Otherwise it'll
852 * keep the gdquot/pdquot from getting reclaimed.
853 */
854 gdqp = dqp->q_gdquot;
855 if (gdqp) {
856 xfs_dqlock(gdqp);
857 dqp->q_gdquot = NULL;
858 }
859
860 pdqp = dqp->q_pdquot;
861 if (pdqp) {
862 xfs_dqlock(pdqp);
863 dqp->q_pdquot = NULL;
864 }
865 xfs_dqunlock(dqp);
866
867 /*
868 * If we had a group/project quota hint, release it now.
869 */
870 if (gdqp)
871 xfs_qm_dqput(gdqp);
872 if (pdqp)
873 xfs_qm_dqput(pdqp);
874}
875
876/* 835/*
877 * Release a reference to the dquot (decrement ref-count) and unlock it. 836 * Release a reference to the dquot (decrement ref-count) and unlock it.
878 * 837 *
@@ -888,10 +847,14 @@ xfs_qm_dqput(
888 847
889 trace_xfs_dqput(dqp); 848 trace_xfs_dqput(dqp);
890 849
891 if (--dqp->q_nrefs > 0) 850 if (--dqp->q_nrefs == 0) {
892 xfs_dqunlock(dqp); 851 struct xfs_quotainfo *qi = dqp->q_mount->m_quotainfo;
893 else 852 trace_xfs_dqput_free(dqp);
894 xfs_qm_dqput_final(dqp); 853
854 if (list_lru_add(&qi->qi_lru, &dqp->q_lru))
855 XFS_STATS_INC(xs_qm_dquot_unused);
856 }
857 xfs_dqunlock(dqp);
895} 858}
896 859
897/* 860/*
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index d22ed0053c32..68a68f704837 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -52,8 +52,6 @@ typedef struct xfs_dquot {
52 int q_bufoffset; /* off of dq in buffer (# dquots) */ 52 int q_bufoffset; /* off of dq in buffer (# dquots) */
53 xfs_fileoff_t q_fileoffset; /* offset in quotas file */ 53 xfs_fileoff_t q_fileoffset; /* offset in quotas file */
54 54
55 struct xfs_dquot*q_gdquot; /* group dquot, hint only */
56 struct xfs_dquot*q_pdquot; /* project dquot, hint only */
57 xfs_disk_dquot_t q_core; /* actual usage & quotas */ 55 xfs_disk_dquot_t q_core; /* actual usage & quotas */
58 xfs_dq_logitem_t q_logitem; /* dquot log item */ 56 xfs_dq_logitem_t q_logitem; /* dquot log item */
59 xfs_qcnt_t q_res_bcount; /* total regular nblks used+reserved */ 57 xfs_qcnt_t q_res_bcount; /* total regular nblks used+reserved */
diff --git a/fs/xfs/xfs_dquot_buf.c b/fs/xfs/xfs_dquot_buf.c
index 610da8177737..c2ac0c611ad8 100644
--- a/fs/xfs/xfs_dquot_buf.c
+++ b/fs/xfs/xfs_dquot_buf.c
@@ -35,7 +35,6 @@
35 35
36int 36int
37xfs_calc_dquots_per_chunk( 37xfs_calc_dquots_per_chunk(
38 struct xfs_mount *mp,
39 unsigned int nbblks) /* basic block units */ 38 unsigned int nbblks) /* basic block units */
40{ 39{
41 unsigned int ndquots; 40 unsigned int ndquots;
@@ -194,7 +193,7 @@ xfs_dquot_buf_verify_crc(
194 if (mp->m_quotainfo) 193 if (mp->m_quotainfo)
195 ndquots = mp->m_quotainfo->qi_dqperchunk; 194 ndquots = mp->m_quotainfo->qi_dqperchunk;
196 else 195 else
197 ndquots = xfs_calc_dquots_per_chunk(mp, 196 ndquots = xfs_calc_dquots_per_chunk(
198 XFS_BB_TO_FSB(mp, bp->b_length)); 197 XFS_BB_TO_FSB(mp, bp->b_length));
199 198
200 for (i = 0; i < ndquots; i++, d++) { 199 for (i = 0; i < ndquots; i++, d++) {
@@ -225,7 +224,7 @@ xfs_dquot_buf_verify(
225 if (mp->m_quotainfo) 224 if (mp->m_quotainfo)
226 ndquots = mp->m_quotainfo->qi_dqperchunk; 225 ndquots = mp->m_quotainfo->qi_dqperchunk;
227 else 226 else
228 ndquots = xfs_calc_dquots_per_chunk(mp, bp->b_length); 227 ndquots = xfs_calc_dquots_per_chunk(bp->b_length);
229 228
230 /* 229 /*
231 * On the first read of the buffer, verify that each dquot is valid. 230 * On the first read of the buffer, verify that each dquot is valid.
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 830c1c937b88..1b8160dc04d1 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -944,7 +944,7 @@ xfs_dir_open(
944 */ 944 */
945 mode = xfs_ilock_data_map_shared(ip); 945 mode = xfs_ilock_data_map_shared(ip);
946 if (ip->i_d.di_nextents > 0) 946 if (ip->i_d.di_nextents > 0)
947 xfs_dir3_data_readahead(NULL, ip, 0, -1); 947 xfs_dir3_data_readahead(ip, 0, -1);
948 xfs_iunlock(ip, mode); 948 xfs_iunlock(ip, mode);
949 return 0; 949 return 0;
950} 950}
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index 12b6e7701985..8ec81bed7992 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006-2007 Silicon Graphics, Inc. 2 * Copyright (c) 2006-2007 Silicon Graphics, Inc.
3 * Copyright (c) 2014 Christoph Hellwig.
3 * All Rights Reserved. 4 * All Rights Reserved.
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -32,100 +33,20 @@
32#include "xfs_filestream.h" 33#include "xfs_filestream.h"
33#include "xfs_trace.h" 34#include "xfs_trace.h"
34 35
35#ifdef XFS_FILESTREAMS_TRACE 36struct xfs_fstrm_item {
36 37 struct xfs_mru_cache_elem mru;
37ktrace_t *xfs_filestreams_trace_buf; 38 struct xfs_inode *ip;
38 39 xfs_agnumber_t ag; /* AG in use for this directory */
39STATIC void 40};
40xfs_filestreams_trace(
41 xfs_mount_t *mp, /* mount point */
42 int type, /* type of trace */
43 const char *func, /* source function */
44 int line, /* source line number */
45 __psunsigned_t arg0,
46 __psunsigned_t arg1,
47 __psunsigned_t arg2,
48 __psunsigned_t arg3,
49 __psunsigned_t arg4,
50 __psunsigned_t arg5)
51{
52 ktrace_enter(xfs_filestreams_trace_buf,
53 (void *)(__psint_t)(type | (line << 16)),
54 (void *)func,
55 (void *)(__psunsigned_t)current_pid(),
56 (void *)mp,
57 (void *)(__psunsigned_t)arg0,
58 (void *)(__psunsigned_t)arg1,
59 (void *)(__psunsigned_t)arg2,
60 (void *)(__psunsigned_t)arg3,
61 (void *)(__psunsigned_t)arg4,
62 (void *)(__psunsigned_t)arg5,
63 NULL, NULL, NULL, NULL, NULL, NULL);
64}
65
66#define TRACE0(mp,t) TRACE6(mp,t,0,0,0,0,0,0)
67#define TRACE1(mp,t,a0) TRACE6(mp,t,a0,0,0,0,0,0)
68#define TRACE2(mp,t,a0,a1) TRACE6(mp,t,a0,a1,0,0,0,0)
69#define TRACE3(mp,t,a0,a1,a2) TRACE6(mp,t,a0,a1,a2,0,0,0)
70#define TRACE4(mp,t,a0,a1,a2,a3) TRACE6(mp,t,a0,a1,a2,a3,0,0)
71#define TRACE5(mp,t,a0,a1,a2,a3,a4) TRACE6(mp,t,a0,a1,a2,a3,a4,0)
72#define TRACE6(mp,t,a0,a1,a2,a3,a4,a5) \
73 xfs_filestreams_trace(mp, t, __func__, __LINE__, \
74 (__psunsigned_t)a0, (__psunsigned_t)a1, \
75 (__psunsigned_t)a2, (__psunsigned_t)a3, \
76 (__psunsigned_t)a4, (__psunsigned_t)a5)
77
78#define TRACE_AG_SCAN(mp, ag, ag2) \
79 TRACE2(mp, XFS_FSTRM_KTRACE_AGSCAN, ag, ag2);
80#define TRACE_AG_PICK1(mp, max_ag, maxfree) \
81 TRACE2(mp, XFS_FSTRM_KTRACE_AGPICK1, max_ag, maxfree);
82#define TRACE_AG_PICK2(mp, ag, ag2, cnt, free, scan, flag) \
83 TRACE6(mp, XFS_FSTRM_KTRACE_AGPICK2, ag, ag2, \
84 cnt, free, scan, flag)
85#define TRACE_UPDATE(mp, ip, ag, cnt, ag2, cnt2) \
86 TRACE5(mp, XFS_FSTRM_KTRACE_UPDATE, ip, ag, cnt, ag2, cnt2)
87#define TRACE_FREE(mp, ip, pip, ag, cnt) \
88 TRACE4(mp, XFS_FSTRM_KTRACE_FREE, ip, pip, ag, cnt)
89#define TRACE_LOOKUP(mp, ip, pip, ag, cnt) \
90 TRACE4(mp, XFS_FSTRM_KTRACE_ITEM_LOOKUP, ip, pip, ag, cnt)
91#define TRACE_ASSOCIATE(mp, ip, pip, ag, cnt) \
92 TRACE4(mp, XFS_FSTRM_KTRACE_ASSOCIATE, ip, pip, ag, cnt)
93#define TRACE_MOVEAG(mp, ip, pip, oag, ocnt, nag, ncnt) \
94 TRACE6(mp, XFS_FSTRM_KTRACE_MOVEAG, ip, pip, oag, ocnt, nag, ncnt)
95#define TRACE_ORPHAN(mp, ip, ag) \
96 TRACE2(mp, XFS_FSTRM_KTRACE_ORPHAN, ip, ag);
97
98
99#else
100#define TRACE_AG_SCAN(mp, ag, ag2)
101#define TRACE_AG_PICK1(mp, max_ag, maxfree)
102#define TRACE_AG_PICK2(mp, ag, ag2, cnt, free, scan, flag)
103#define TRACE_UPDATE(mp, ip, ag, cnt, ag2, cnt2)
104#define TRACE_FREE(mp, ip, pip, ag, cnt)
105#define TRACE_LOOKUP(mp, ip, pip, ag, cnt)
106#define TRACE_ASSOCIATE(mp, ip, pip, ag, cnt)
107#define TRACE_MOVEAG(mp, ip, pip, oag, ocnt, nag, ncnt)
108#define TRACE_ORPHAN(mp, ip, ag)
109#endif
110
111static kmem_zone_t *item_zone;
112 41
113/* 42enum xfs_fstrm_alloc {
114 * Structure for associating a file or a directory with an allocation group. 43 XFS_PICK_USERDATA = 1,
115 * The parent directory pointer is only needed for files, but since there will 44 XFS_PICK_LOWSPACE = 2,
116 * generally be vastly more files than directories in the cache, using the same 45};
117 * data structure simplifies the code with very little memory overhead.
118 */
119typedef struct fstrm_item
120{
121 xfs_agnumber_t ag; /* AG currently in use for the file/directory. */
122 xfs_inode_t *ip; /* inode self-pointer. */
123 xfs_inode_t *pip; /* Parent directory inode pointer. */
124} fstrm_item_t;
125 46
126/* 47/*
127 * Allocation group filestream associations are tracked with per-ag atomic 48 * Allocation group filestream associations are tracked with per-ag atomic
128 * counters. These counters allow _xfs_filestream_pick_ag() to tell whether a 49 * counters. These counters allow xfs_filestream_pick_ag() to tell whether a
129 * particular AG already has active filestreams associated with it. The mount 50 * particular AG already has active filestreams associated with it. The mount
130 * point's m_peraglock is used to protect these counters from per-ag array 51 * point's m_peraglock is used to protect these counters from per-ag array
131 * re-allocation during a growfs operation. When xfs_growfs_data_private() is 52 * re-allocation during a growfs operation. When xfs_growfs_data_private() is
@@ -160,7 +81,7 @@ typedef struct fstrm_item
160 * the cache that reference per-ag array elements that have since been 81 * the cache that reference per-ag array elements that have since been
161 * reallocated. 82 * reallocated.
162 */ 83 */
163static int 84int
164xfs_filestream_peek_ag( 85xfs_filestream_peek_ag(
165 xfs_mount_t *mp, 86 xfs_mount_t *mp,
166 xfs_agnumber_t agno) 87 xfs_agnumber_t agno)
@@ -200,23 +121,40 @@ xfs_filestream_put_ag(
200 xfs_perag_put(pag); 121 xfs_perag_put(pag);
201} 122}
202 123
124static void
125xfs_fstrm_free_func(
126 struct xfs_mru_cache_elem *mru)
127{
128 struct xfs_fstrm_item *item =
129 container_of(mru, struct xfs_fstrm_item, mru);
130
131 xfs_filestream_put_ag(item->ip->i_mount, item->ag);
132
133 trace_xfs_filestream_free(item->ip, item->ag);
134
135 kmem_free(item);
136}
137
203/* 138/*
204 * Scan the AGs starting at startag looking for an AG that isn't in use and has 139 * Scan the AGs starting at startag looking for an AG that isn't in use and has
205 * at least minlen blocks free. 140 * at least minlen blocks free.
206 */ 141 */
207static int 142static int
208_xfs_filestream_pick_ag( 143xfs_filestream_pick_ag(
209 xfs_mount_t *mp, 144 struct xfs_inode *ip,
210 xfs_agnumber_t startag, 145 xfs_agnumber_t startag,
211 xfs_agnumber_t *agp, 146 xfs_agnumber_t *agp,
212 int flags, 147 int flags,
213 xfs_extlen_t minlen) 148 xfs_extlen_t minlen)
214{ 149{
215 int streams, max_streams; 150 struct xfs_mount *mp = ip->i_mount;
216 int err, trylock, nscan; 151 struct xfs_fstrm_item *item;
217 xfs_extlen_t longest, free, minfree, maxfree = 0; 152 struct xfs_perag *pag;
218 xfs_agnumber_t ag, max_ag = NULLAGNUMBER; 153 xfs_extlen_t longest, free = 0, minfree, maxfree = 0;
219 struct xfs_perag *pag; 154 xfs_agnumber_t ag, max_ag = NULLAGNUMBER;
155 int err, trylock, nscan;
156
157 ASSERT(S_ISDIR(ip->i_d.di_mode));
220 158
221 /* 2% of an AG's blocks must be free for it to be chosen. */ 159 /* 2% of an AG's blocks must be free for it to be chosen. */
222 minfree = mp->m_sb.sb_agblocks / 50; 160 minfree = mp->m_sb.sb_agblocks / 50;
@@ -228,8 +166,9 @@ _xfs_filestream_pick_ag(
228 trylock = XFS_ALLOC_FLAG_TRYLOCK; 166 trylock = XFS_ALLOC_FLAG_TRYLOCK;
229 167
230 for (nscan = 0; 1; nscan++) { 168 for (nscan = 0; 1; nscan++) {
169 trace_xfs_filestream_scan(ip, ag);
170
231 pag = xfs_perag_get(mp, ag); 171 pag = xfs_perag_get(mp, ag);
232 TRACE_AG_SCAN(mp, ag, atomic_read(&pag->pagf_fstrms));
233 172
234 if (!pag->pagf_init) { 173 if (!pag->pagf_init) {
235 err = xfs_alloc_pagf_init(mp, NULL, ag, trylock); 174 err = xfs_alloc_pagf_init(mp, NULL, ag, trylock);
@@ -246,7 +185,6 @@ _xfs_filestream_pick_ag(
246 /* Keep track of the AG with the most free blocks. */ 185 /* Keep track of the AG with the most free blocks. */
247 if (pag->pagf_freeblks > maxfree) { 186 if (pag->pagf_freeblks > maxfree) {
248 maxfree = pag->pagf_freeblks; 187 maxfree = pag->pagf_freeblks;
249 max_streams = atomic_read(&pag->pagf_fstrms);
250 max_ag = ag; 188 max_ag = ag;
251 } 189 }
252 190
@@ -269,7 +207,6 @@ _xfs_filestream_pick_ag(
269 207
270 /* Break out, retaining the reference on the AG. */ 208 /* Break out, retaining the reference on the AG. */
271 free = pag->pagf_freeblks; 209 free = pag->pagf_freeblks;
272 streams = atomic_read(&pag->pagf_fstrms);
273 xfs_perag_put(pag); 210 xfs_perag_put(pag);
274 *agp = ag; 211 *agp = ag;
275 break; 212 break;
@@ -305,317 +242,98 @@ next_ag:
305 */ 242 */
306 if (max_ag != NULLAGNUMBER) { 243 if (max_ag != NULLAGNUMBER) {
307 xfs_filestream_get_ag(mp, max_ag); 244 xfs_filestream_get_ag(mp, max_ag);
308 TRACE_AG_PICK1(mp, max_ag, maxfree);
309 streams = max_streams;
310 free = maxfree; 245 free = maxfree;
311 *agp = max_ag; 246 *agp = max_ag;
312 break; 247 break;
313 } 248 }
314 249
315 /* take AG 0 if none matched */ 250 /* take AG 0 if none matched */
316 TRACE_AG_PICK1(mp, max_ag, maxfree); 251 trace_xfs_filestream_pick(ip, *agp, free, nscan);
317 *agp = 0; 252 *agp = 0;
318 return 0; 253 return 0;
319 } 254 }
320 255
321 TRACE_AG_PICK2(mp, startag, *agp, streams, free, nscan, flags); 256 trace_xfs_filestream_pick(ip, *agp, free, nscan);
322
323 return 0;
324}
325 257
326/* 258 if (*agp == NULLAGNUMBER)
327 * Set the allocation group number for a file or a directory, updating inode
328 * references and per-AG references as appropriate.
329 */
330static int
331_xfs_filestream_update_ag(
332 xfs_inode_t *ip,
333 xfs_inode_t *pip,
334 xfs_agnumber_t ag)
335{
336 int err = 0;
337 xfs_mount_t *mp;
338 xfs_mru_cache_t *cache;
339 fstrm_item_t *item;
340 xfs_agnumber_t old_ag;
341 xfs_inode_t *old_pip;
342
343 /*
344 * Either ip is a regular file and pip is a directory, or ip is a
345 * directory and pip is NULL.
346 */
347 ASSERT(ip && ((S_ISREG(ip->i_d.di_mode) && pip &&
348 S_ISDIR(pip->i_d.di_mode)) ||
349 (S_ISDIR(ip->i_d.di_mode) && !pip)));
350
351 mp = ip->i_mount;
352 cache = mp->m_filestream;
353
354 item = xfs_mru_cache_lookup(cache, ip->i_ino);
355 if (item) {
356 ASSERT(item->ip == ip);
357 old_ag = item->ag;
358 item->ag = ag;
359 old_pip = item->pip;
360 item->pip = pip;
361 xfs_mru_cache_done(cache);
362
363 /*
364 * If the AG has changed, drop the old ref and take a new one,
365 * effectively transferring the reference from old to new AG.
366 */
367 if (ag != old_ag) {
368 xfs_filestream_put_ag(mp, old_ag);
369 xfs_filestream_get_ag(mp, ag);
370 }
371
372 /*
373 * If ip is a file and its pip has changed, drop the old ref and
374 * take a new one.
375 */
376 if (pip && pip != old_pip) {
377 IRELE(old_pip);
378 IHOLD(pip);
379 }
380
381 TRACE_UPDATE(mp, ip, old_ag, xfs_filestream_peek_ag(mp, old_ag),
382 ag, xfs_filestream_peek_ag(mp, ag));
383 return 0; 259 return 0;
384 }
385 260
386 item = kmem_zone_zalloc(item_zone, KM_MAYFAIL); 261 err = ENOMEM;
262 item = kmem_alloc(sizeof(*item), KM_MAYFAIL);
387 if (!item) 263 if (!item)
388 return ENOMEM; 264 goto out_put_ag;
389 265
390 item->ag = ag; 266 item->ag = *agp;
391 item->ip = ip; 267 item->ip = ip;
392 item->pip = pip;
393 268
394 err = xfs_mru_cache_insert(cache, ip->i_ino, item); 269 err = xfs_mru_cache_insert(mp->m_filestream, ip->i_ino, &item->mru);
395 if (err) { 270 if (err) {
396 kmem_zone_free(item_zone, item); 271 if (err == EEXIST)
397 return err; 272 err = 0;
273 goto out_free_item;
398 } 274 }
399 275
400 /* Take a reference on the AG. */
401 xfs_filestream_get_ag(mp, ag);
402
403 /*
404 * Take a reference on the inode itself regardless of whether it's a
405 * regular file or a directory.
406 */
407 IHOLD(ip);
408
409 /*
410 * In the case of a regular file, take a reference on the parent inode
411 * as well to ensure it remains in-core.
412 */
413 if (pip)
414 IHOLD(pip);
415
416 TRACE_UPDATE(mp, ip, ag, xfs_filestream_peek_ag(mp, ag),
417 ag, xfs_filestream_peek_ag(mp, ag));
418
419 return 0; 276 return 0;
420}
421
422/* xfs_fstrm_free_func(): callback for freeing cached stream items. */
423STATIC void
424xfs_fstrm_free_func(
425 unsigned long ino,
426 void *data)
427{
428 fstrm_item_t *item = (fstrm_item_t *)data;
429 xfs_inode_t *ip = item->ip;
430
431 ASSERT(ip->i_ino == ino);
432
433 xfs_iflags_clear(ip, XFS_IFILESTREAM);
434
435 /* Drop the reference taken on the AG when the item was added. */
436 xfs_filestream_put_ag(ip->i_mount, item->ag);
437
438 TRACE_FREE(ip->i_mount, ip, item->pip, item->ag,
439 xfs_filestream_peek_ag(ip->i_mount, item->ag));
440
441 /*
442 * _xfs_filestream_update_ag() always takes a reference on the inode
443 * itself, whether it's a file or a directory. Release it here.
444 * This can result in the inode being freed and so we must
445 * not hold any inode locks when freeing filesstreams objects
446 * otherwise we can deadlock here.
447 */
448 IRELE(ip);
449
450 /*
451 * In the case of a regular file, _xfs_filestream_update_ag() also
452 * takes a ref on the parent inode to keep it in-core. Release that
453 * too.
454 */
455 if (item->pip)
456 IRELE(item->pip);
457
458 /* Finally, free the memory allocated for the item. */
459 kmem_zone_free(item_zone, item);
460}
461
462/*
463 * xfs_filestream_init() is called at xfs initialisation time to set up the
464 * memory zone that will be used for filestream data structure allocation.
465 */
466int
467xfs_filestream_init(void)
468{
469 item_zone = kmem_zone_init(sizeof(fstrm_item_t), "fstrm_item");
470 if (!item_zone)
471 return -ENOMEM;
472
473 return 0;
474}
475
476/*
477 * xfs_filestream_uninit() is called at xfs termination time to destroy the
478 * memory zone that was used for filestream data structure allocation.
479 */
480void
481xfs_filestream_uninit(void)
482{
483 kmem_zone_destroy(item_zone);
484}
485
486/*
487 * xfs_filestream_mount() is called when a file system is mounted with the
488 * filestream option. It is responsible for allocating the data structures
489 * needed to track the new file system's file streams.
490 */
491int
492xfs_filestream_mount(
493 xfs_mount_t *mp)
494{
495 int err;
496 unsigned int lifetime, grp_count;
497
498 /*
499 * The filestream timer tunable is currently fixed within the range of
500 * one second to four minutes, with five seconds being the default. The
501 * group count is somewhat arbitrary, but it'd be nice to adhere to the
502 * timer tunable to within about 10 percent. This requires at least 10
503 * groups.
504 */
505 lifetime = xfs_fstrm_centisecs * 10;
506 grp_count = 10;
507
508 err = xfs_mru_cache_create(&mp->m_filestream, lifetime, grp_count,
509 xfs_fstrm_free_func);
510 277
278out_free_item:
279 kmem_free(item);
280out_put_ag:
281 xfs_filestream_put_ag(mp, *agp);
511 return err; 282 return err;
512} 283}
513 284
514/* 285static struct xfs_inode *
515 * xfs_filestream_unmount() is called when a file system that was mounted with 286xfs_filestream_get_parent(
516 * the filestream option is unmounted. It drains the data structures created 287 struct xfs_inode *ip)
517 * to track the file system's file streams and frees all the memory that was
518 * allocated.
519 */
520void
521xfs_filestream_unmount(
522 xfs_mount_t *mp)
523{ 288{
524 xfs_mru_cache_destroy(mp->m_filestream); 289 struct inode *inode = VFS_I(ip), *dir = NULL;
525} 290 struct dentry *dentry, *parent;
526 291
527/* 292 dentry = d_find_alias(inode);
528 * Return the AG of the filestream the file or directory belongs to, or 293 if (!dentry)
529 * NULLAGNUMBER otherwise. 294 goto out;
530 */
531xfs_agnumber_t
532xfs_filestream_lookup_ag(
533 xfs_inode_t *ip)
534{
535 xfs_mru_cache_t *cache;
536 fstrm_item_t *item;
537 xfs_agnumber_t ag;
538 int ref;
539
540 if (!S_ISREG(ip->i_d.di_mode) && !S_ISDIR(ip->i_d.di_mode)) {
541 ASSERT(0);
542 return NULLAGNUMBER;
543 }
544 295
545 cache = ip->i_mount->m_filestream; 296 parent = dget_parent(dentry);
546 item = xfs_mru_cache_lookup(cache, ip->i_ino); 297 if (!parent)
547 if (!item) { 298 goto out_dput;
548 TRACE_LOOKUP(ip->i_mount, ip, NULL, NULLAGNUMBER, 0);
549 return NULLAGNUMBER;
550 }
551 299
552 ASSERT(ip == item->ip); 300 dir = igrab(parent->d_inode);
553 ag = item->ag; 301 dput(parent);
554 ref = xfs_filestream_peek_ag(ip->i_mount, ag);
555 xfs_mru_cache_done(cache);
556 302
557 TRACE_LOOKUP(ip->i_mount, ip, item->pip, ag, ref); 303out_dput:
558 return ag; 304 dput(dentry);
305out:
306 return dir ? XFS_I(dir) : NULL;
559} 307}
560 308
561/* 309/*
562 * xfs_filestream_associate() should only be called to associate a regular file 310 * Find the right allocation group for a file, either by finding an
563 * with its parent directory. Calling it with a child directory isn't 311 * existing file stream or creating a new one.
564 * appropriate because filestreams don't apply to entire directory hierarchies.
565 * Creating a file in a child directory of an existing filestream directory
566 * starts a new filestream with its own allocation group association.
567 * 312 *
568 * Returns < 0 on error, 0 if successful association occurred, > 0 if 313 * Returns NULLAGNUMBER in case of an error.
569 * we failed to get an association because of locking issues.
570 */ 314 */
571int 315xfs_agnumber_t
572xfs_filestream_associate( 316xfs_filestream_lookup_ag(
573 xfs_inode_t *pip, 317 struct xfs_inode *ip)
574 xfs_inode_t *ip)
575{ 318{
576 xfs_mount_t *mp; 319 struct xfs_mount *mp = ip->i_mount;
577 xfs_mru_cache_t *cache; 320 struct xfs_inode *pip = NULL;
578 fstrm_item_t *item; 321 xfs_agnumber_t startag, ag = NULLAGNUMBER;
579 xfs_agnumber_t ag, rotorstep, startag; 322 struct xfs_mru_cache_elem *mru;
580 int err = 0;
581 323
582 ASSERT(S_ISDIR(pip->i_d.di_mode));
583 ASSERT(S_ISREG(ip->i_d.di_mode)); 324 ASSERT(S_ISREG(ip->i_d.di_mode));
584 if (!S_ISDIR(pip->i_d.di_mode) || !S_ISREG(ip->i_d.di_mode))
585 return -EINVAL;
586 325
587 mp = pip->i_mount; 326 pip = xfs_filestream_get_parent(ip);
588 cache = mp->m_filestream; 327 if (!pip)
328 goto out;
589 329
590 /* 330 mru = xfs_mru_cache_lookup(mp->m_filestream, pip->i_ino);
591 * We have a problem, Houston. 331 if (mru) {
592 * 332 ag = container_of(mru, struct xfs_fstrm_item, mru)->ag;
593 * Taking the iolock here violates inode locking order - we already 333 xfs_mru_cache_done(mp->m_filestream);
594 * hold the ilock. Hence if we block getting this lock we may never
595 * wake. Unfortunately, that means if we can't get the lock, we're
596 * screwed in terms of getting a stream association - we can't spin
597 * waiting for the lock because someone else is waiting on the lock we
598 * hold and we cannot drop that as we are in a transaction here.
599 *
600 * Lucky for us, this inversion is not a problem because it's a
601 * directory inode that we are trying to lock here.
602 *
603 * So, if we can't get the iolock without sleeping then just give up
604 */
605 if (!xfs_ilock_nowait(pip, XFS_IOLOCK_EXCL))
606 return 1;
607
608 /* If the parent directory is already in the cache, use its AG. */
609 item = xfs_mru_cache_lookup(cache, pip->i_ino);
610 if (item) {
611 ASSERT(item->ip == pip);
612 ag = item->ag;
613 xfs_mru_cache_done(cache);
614
615 TRACE_LOOKUP(mp, pip, pip, ag, xfs_filestream_peek_ag(mp, ag));
616 err = _xfs_filestream_update_ag(ip, pip, ag);
617 334
618 goto exit; 335 trace_xfs_filestream_lookup(ip, ag);
336 goto out;
619 } 337 }
620 338
621 /* 339 /*
@@ -623,202 +341,94 @@ xfs_filestream_associate(
623 * use the directory inode's AG. 341 * use the directory inode's AG.
624 */ 342 */
625 if (mp->m_flags & XFS_MOUNT_32BITINODES) { 343 if (mp->m_flags & XFS_MOUNT_32BITINODES) {
626 rotorstep = xfs_rotorstep; 344 xfs_agnumber_t rotorstep = xfs_rotorstep;
627 startag = (mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount; 345 startag = (mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount;
628 mp->m_agfrotor = (mp->m_agfrotor + 1) % 346 mp->m_agfrotor = (mp->m_agfrotor + 1) %
629 (mp->m_sb.sb_agcount * rotorstep); 347 (mp->m_sb.sb_agcount * rotorstep);
630 } else 348 } else
631 startag = XFS_INO_TO_AGNO(mp, pip->i_ino); 349 startag = XFS_INO_TO_AGNO(mp, pip->i_ino);
632 350
633 /* Pick a new AG for the parent inode starting at startag. */ 351 if (xfs_filestream_pick_ag(pip, startag, &ag, 0, 0))
634 err = _xfs_filestream_pick_ag(mp, startag, &ag, 0, 0); 352 ag = NULLAGNUMBER;
635 if (err || ag == NULLAGNUMBER) 353out:
636 goto exit_did_pick; 354 IRELE(pip);
637 355 return ag;
638 /* Associate the parent inode with the AG. */
639 err = _xfs_filestream_update_ag(pip, NULL, ag);
640 if (err)
641 goto exit_did_pick;
642
643 /* Associate the file inode with the AG. */
644 err = _xfs_filestream_update_ag(ip, pip, ag);
645 if (err)
646 goto exit_did_pick;
647
648 TRACE_ASSOCIATE(mp, ip, pip, ag, xfs_filestream_peek_ag(mp, ag));
649
650exit_did_pick:
651 /*
652 * If _xfs_filestream_pick_ag() returned a valid AG, remove the
653 * reference it took on it, since the file and directory will have taken
654 * their own now if they were successfully cached.
655 */
656 if (ag != NULLAGNUMBER)
657 xfs_filestream_put_ag(mp, ag);
658
659exit:
660 xfs_iunlock(pip, XFS_IOLOCK_EXCL);
661 return -err;
662} 356}
663 357
664/* 358/*
665 * Pick a new allocation group for the current file and its file stream. This 359 * Pick a new allocation group for the current file and its file stream.
666 * function is called by xfs_bmap_filestreams() with the mount point's per-ag 360 *
667 * lock held. 361 * This is called when the allocator can't find a suitable extent in the
362 * current AG, and we have to move the stream into a new AG with more space.
668 */ 363 */
669int 364int
670xfs_filestream_new_ag( 365xfs_filestream_new_ag(
671 struct xfs_bmalloca *ap, 366 struct xfs_bmalloca *ap,
672 xfs_agnumber_t *agp) 367 xfs_agnumber_t *agp)
673{ 368{
674 int flags, err; 369 struct xfs_inode *ip = ap->ip, *pip;
675 xfs_inode_t *ip, *pip = NULL; 370 struct xfs_mount *mp = ip->i_mount;
676 xfs_mount_t *mp; 371 xfs_extlen_t minlen = ap->length;
677 xfs_mru_cache_t *cache; 372 xfs_agnumber_t startag = 0;
678 xfs_extlen_t minlen; 373 int flags, err = 0;
679 fstrm_item_t *dir, *file; 374 struct xfs_mru_cache_elem *mru;
680 xfs_agnumber_t ag = NULLAGNUMBER;
681
682 ip = ap->ip;
683 mp = ip->i_mount;
684 cache = mp->m_filestream;
685 minlen = ap->length;
686 *agp = NULLAGNUMBER;
687 375
688 /* 376 *agp = NULLAGNUMBER;
689 * Look for the file in the cache, removing it if it's found. Doing
690 * this allows it to be held across the dir lookup that follows.
691 */
692 file = xfs_mru_cache_remove(cache, ip->i_ino);
693 if (file) {
694 ASSERT(ip == file->ip);
695
696 /* Save the file's parent inode and old AG number for later. */
697 pip = file->pip;
698 ag = file->ag;
699
700 /* Look for the file's directory in the cache. */
701 dir = xfs_mru_cache_lookup(cache, pip->i_ino);
702 if (dir) {
703 ASSERT(pip == dir->ip);
704
705 /*
706 * If the directory has already moved on to a new AG,
707 * use that AG as the new AG for the file. Don't
708 * forget to twiddle the AG refcounts to match the
709 * movement.
710 */
711 if (dir->ag != file->ag) {
712 xfs_filestream_put_ag(mp, file->ag);
713 xfs_filestream_get_ag(mp, dir->ag);
714 *agp = file->ag = dir->ag;
715 }
716
717 xfs_mru_cache_done(cache);
718 }
719 377
720 /* 378 pip = xfs_filestream_get_parent(ip);
721 * Put the file back in the cache. If this fails, the free 379 if (!pip)
722 * function needs to be called to tidy up in the same way as if 380 goto exit;
723 * the item had simply expired from the cache.
724 */
725 err = xfs_mru_cache_insert(cache, ip->i_ino, file);
726 if (err) {
727 xfs_fstrm_free_func(ip->i_ino, file);
728 return err;
729 }
730 381
731 /* 382 mru = xfs_mru_cache_remove(mp->m_filestream, pip->i_ino);
732 * If the file's AG was moved to the directory's new AG, there's 383 if (mru) {
733 * nothing more to be done. 384 struct xfs_fstrm_item *item =
734 */ 385 container_of(mru, struct xfs_fstrm_item, mru);
735 if (*agp != NULLAGNUMBER) { 386 startag = (item->ag + 1) % mp->m_sb.sb_agcount;
736 TRACE_MOVEAG(mp, ip, pip,
737 ag, xfs_filestream_peek_ag(mp, ag),
738 *agp, xfs_filestream_peek_ag(mp, *agp));
739 return 0;
740 }
741 } 387 }
742 388
743 /*
744 * If the file's parent directory is known, take its iolock in exclusive
745 * mode to prevent two sibling files from racing each other to migrate
746 * themselves and their parent to different AGs.
747 *
748 * Note that we lock the parent directory iolock inside the child
749 * iolock here. That's fine as we never hold both parent and child
750 * iolock in any other place. This is different from the ilock,
751 * which requires locking of the child after the parent for namespace
752 * operations.
753 */
754 if (pip)
755 xfs_ilock(pip, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
756
757 /*
758 * A new AG needs to be found for the file. If the file's parent
759 * directory is also known, it will be moved to the new AG as well to
760 * ensure that files created inside it in future use the new AG.
761 */
762 ag = (ag == NULLAGNUMBER) ? 0 : (ag + 1) % mp->m_sb.sb_agcount;
763 flags = (ap->userdata ? XFS_PICK_USERDATA : 0) | 389 flags = (ap->userdata ? XFS_PICK_USERDATA : 0) |
764 (ap->flist->xbf_low ? XFS_PICK_LOWSPACE : 0); 390 (ap->flist->xbf_low ? XFS_PICK_LOWSPACE : 0);
765 391
766 err = _xfs_filestream_pick_ag(mp, ag, agp, flags, minlen); 392 err = xfs_filestream_pick_ag(pip, startag, agp, flags, minlen);
767 if (err || *agp == NULLAGNUMBER)
768 goto exit;
769 393
770 /* 394 /*
771 * If the file wasn't found in the file cache, then its parent directory 395 * Only free the item here so we skip over the old AG earlier.
772 * inode isn't known. For this to have happened, the file must either
773 * be pre-existing, or it was created long enough ago that its cache
774 * entry has expired. This isn't the sort of usage that the filestreams
775 * allocator is trying to optimise, so there's no point trying to track
776 * its new AG somehow in the filestream data structures.
777 */ 396 */
778 if (!pip) { 397 if (mru)
779 TRACE_ORPHAN(mp, ip, *agp); 398 xfs_fstrm_free_func(mru);
780 goto exit;
781 }
782
783 /* Associate the parent inode with the AG. */
784 err = _xfs_filestream_update_ag(pip, NULL, *agp);
785 if (err)
786 goto exit;
787
788 /* Associate the file inode with the AG. */
789 err = _xfs_filestream_update_ag(ip, pip, *agp);
790 if (err)
791 goto exit;
792
793 TRACE_MOVEAG(mp, ip, pip, NULLAGNUMBER, 0,
794 *agp, xfs_filestream_peek_ag(mp, *agp));
795 399
400 IRELE(pip);
796exit: 401exit:
797 /* 402 if (*agp == NULLAGNUMBER)
798 * If _xfs_filestream_pick_ag() returned a valid AG, remove the
799 * reference it took on it, since the file and directory will have taken
800 * their own now if they were successfully cached.
801 */
802 if (*agp != NULLAGNUMBER)
803 xfs_filestream_put_ag(mp, *agp);
804 else
805 *agp = 0; 403 *agp = 0;
806
807 if (pip)
808 xfs_iunlock(pip, XFS_IOLOCK_EXCL);
809
810 return err; 404 return err;
811} 405}
812 406
813/*
814 * Remove an association between an inode and a filestream object.
815 * Typically this is done on last close of an unlinked file.
816 */
817void 407void
818xfs_filestream_deassociate( 408xfs_filestream_deassociate(
819 xfs_inode_t *ip) 409 struct xfs_inode *ip)
820{ 410{
821 xfs_mru_cache_t *cache = ip->i_mount->m_filestream; 411 xfs_mru_cache_delete(ip->i_mount->m_filestream, ip->i_ino);
412}
413
414int
415xfs_filestream_mount(
416 xfs_mount_t *mp)
417{
418 /*
419 * The filestream timer tunable is currently fixed within the range of
420 * one second to four minutes, with five seconds being the default. The
421 * group count is somewhat arbitrary, but it'd be nice to adhere to the
422 * timer tunable to within about 10 percent. This requires at least 10
423 * groups.
424 */
425 return xfs_mru_cache_create(&mp->m_filestream, xfs_fstrm_centisecs * 10,
426 10, xfs_fstrm_free_func);
427}
822 428
823 xfs_mru_cache_delete(cache, ip->i_ino); 429void
430xfs_filestream_unmount(
431 xfs_mount_t *mp)
432{
433 xfs_mru_cache_destroy(mp->m_filestream);
824} 434}
diff --git a/fs/xfs/xfs_filestream.h b/fs/xfs/xfs_filestream.h
index 6d61dbee8564..2ef43406e53b 100644
--- a/fs/xfs/xfs_filestream.h
+++ b/fs/xfs/xfs_filestream.h
@@ -20,50 +20,20 @@
20 20
21struct xfs_mount; 21struct xfs_mount;
22struct xfs_inode; 22struct xfs_inode;
23struct xfs_perag;
24struct xfs_bmalloca; 23struct xfs_bmalloca;
25 24
26#ifdef XFS_FILESTREAMS_TRACE
27#define XFS_FSTRM_KTRACE_INFO 1
28#define XFS_FSTRM_KTRACE_AGSCAN 2
29#define XFS_FSTRM_KTRACE_AGPICK1 3
30#define XFS_FSTRM_KTRACE_AGPICK2 4
31#define XFS_FSTRM_KTRACE_UPDATE 5
32#define XFS_FSTRM_KTRACE_FREE 6
33#define XFS_FSTRM_KTRACE_ITEM_LOOKUP 7
34#define XFS_FSTRM_KTRACE_ASSOCIATE 8
35#define XFS_FSTRM_KTRACE_MOVEAG 9
36#define XFS_FSTRM_KTRACE_ORPHAN 10
37
38#define XFS_FSTRM_KTRACE_SIZE 16384
39extern ktrace_t *xfs_filestreams_trace_buf;
40
41#endif
42
43/* allocation selection flags */
44typedef enum xfs_fstrm_alloc {
45 XFS_PICK_USERDATA = 1,
46 XFS_PICK_LOWSPACE = 2,
47} xfs_fstrm_alloc_t;
48
49/* prototypes for filestream.c */
50int xfs_filestream_init(void);
51void xfs_filestream_uninit(void);
52int xfs_filestream_mount(struct xfs_mount *mp); 25int xfs_filestream_mount(struct xfs_mount *mp);
53void xfs_filestream_unmount(struct xfs_mount *mp); 26void xfs_filestream_unmount(struct xfs_mount *mp);
54xfs_agnumber_t xfs_filestream_lookup_ag(struct xfs_inode *ip);
55int xfs_filestream_associate(struct xfs_inode *dip, struct xfs_inode *ip);
56void xfs_filestream_deassociate(struct xfs_inode *ip); 27void xfs_filestream_deassociate(struct xfs_inode *ip);
28xfs_agnumber_t xfs_filestream_lookup_ag(struct xfs_inode *ip);
57int xfs_filestream_new_ag(struct xfs_bmalloca *ap, xfs_agnumber_t *agp); 29int xfs_filestream_new_ag(struct xfs_bmalloca *ap, xfs_agnumber_t *agp);
30int xfs_filestream_peek_ag(struct xfs_mount *mp, xfs_agnumber_t agno);
58 31
59
60/* filestreams for the inode? */
61static inline int 32static inline int
62xfs_inode_is_filestream( 33xfs_inode_is_filestream(
63 struct xfs_inode *ip) 34 struct xfs_inode *ip)
64{ 35{
65 return (ip->i_mount->m_flags & XFS_MOUNT_FILESTREAMS) || 36 return (ip->i_mount->m_flags & XFS_MOUNT_FILESTREAMS) ||
66 xfs_iflags_test(ip, XFS_IFILESTREAM) ||
67 (ip->i_d.di_flags & XFS_DIFLAG_FILESTREAM); 37 (ip->i_d.di_flags & XFS_DIFLAG_FILESTREAM);
68} 38}
69 39
diff --git a/fs/xfs/xfs_format.h b/fs/xfs/xfs_format.h
index 9898f31d05d8..34d85aca3058 100644
--- a/fs/xfs/xfs_format.h
+++ b/fs/xfs/xfs_format.h
@@ -202,6 +202,8 @@ typedef __be32 xfs_alloc_ptr_t;
202 */ 202 */
203#define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */ 203#define XFS_IBT_MAGIC 0x49414254 /* 'IABT' */
204#define XFS_IBT_CRC_MAGIC 0x49414233 /* 'IAB3' */ 204#define XFS_IBT_CRC_MAGIC 0x49414233 /* 'IAB3' */
205#define XFS_FIBT_MAGIC 0x46494254 /* 'FIBT' */
206#define XFS_FIBT_CRC_MAGIC 0x46494233 /* 'FIB3' */
205 207
206typedef __uint64_t xfs_inofree_t; 208typedef __uint64_t xfs_inofree_t;
207#define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t)) 209#define XFS_INODES_PER_CHUNK (NBBY * sizeof(xfs_inofree_t))
@@ -244,7 +246,17 @@ typedef __be32 xfs_inobt_ptr_t;
244 * block numbers in the AG. 246 * block numbers in the AG.
245 */ 247 */
246#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1)) 248#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1))
247#define XFS_PREALLOC_BLOCKS(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1)) 249#define XFS_FIBT_BLOCK(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1))
250
251/*
252 * The first data block of an AG depends on whether the filesystem was formatted
253 * with the finobt feature. If so, account for the finobt reserved root btree
254 * block.
255 */
256#define XFS_PREALLOC_BLOCKS(mp) \
257 (xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \
258 XFS_FIBT_BLOCK(mp) + 1 : \
259 XFS_IBT_BLOCK(mp) + 1)
248 260
249 261
250 262
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index c5fc116dfaa3..d34703dbcb42 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -238,6 +238,7 @@ typedef struct xfs_fsop_resblks {
238#define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000 /* lazy superblock counters */ 238#define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000 /* lazy superblock counters */
239#define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */ 239#define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */
240#define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ 240#define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */
241#define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */
241 242
242/* 243/*
243 * Minimum and maximum sizes need for growth checks. 244 * Minimum and maximum sizes need for growth checks.
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 02fb943cbf22..d2295561570a 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -24,6 +24,8 @@
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_mount.h" 26#include "xfs_mount.h"
27#include "xfs_da_format.h"
28#include "xfs_da_btree.h"
27#include "xfs_inode.h" 29#include "xfs_inode.h"
28#include "xfs_trans.h" 30#include "xfs_trans.h"
29#include "xfs_inode_item.h" 31#include "xfs_inode_item.h"
@@ -74,23 +76,18 @@ xfs_fs_geometry(
74 } 76 }
75 if (new_version >= 3) { 77 if (new_version >= 3) {
76 geo->version = XFS_FSOP_GEOM_VERSION; 78 geo->version = XFS_FSOP_GEOM_VERSION;
77 geo->flags = 79 geo->flags = XFS_FSOP_GEOM_FLAGS_NLINK |
80 XFS_FSOP_GEOM_FLAGS_DIRV2 |
78 (xfs_sb_version_hasattr(&mp->m_sb) ? 81 (xfs_sb_version_hasattr(&mp->m_sb) ?
79 XFS_FSOP_GEOM_FLAGS_ATTR : 0) | 82 XFS_FSOP_GEOM_FLAGS_ATTR : 0) |
80 (xfs_sb_version_hasnlink(&mp->m_sb) ?
81 XFS_FSOP_GEOM_FLAGS_NLINK : 0) |
82 (xfs_sb_version_hasquota(&mp->m_sb) ? 83 (xfs_sb_version_hasquota(&mp->m_sb) ?
83 XFS_FSOP_GEOM_FLAGS_QUOTA : 0) | 84 XFS_FSOP_GEOM_FLAGS_QUOTA : 0) |
84 (xfs_sb_version_hasalign(&mp->m_sb) ? 85 (xfs_sb_version_hasalign(&mp->m_sb) ?
85 XFS_FSOP_GEOM_FLAGS_IALIGN : 0) | 86 XFS_FSOP_GEOM_FLAGS_IALIGN : 0) |
86 (xfs_sb_version_hasdalign(&mp->m_sb) ? 87 (xfs_sb_version_hasdalign(&mp->m_sb) ?
87 XFS_FSOP_GEOM_FLAGS_DALIGN : 0) | 88 XFS_FSOP_GEOM_FLAGS_DALIGN : 0) |
88 (xfs_sb_version_hasshared(&mp->m_sb) ?
89 XFS_FSOP_GEOM_FLAGS_SHARED : 0) |
90 (xfs_sb_version_hasextflgbit(&mp->m_sb) ? 89 (xfs_sb_version_hasextflgbit(&mp->m_sb) ?
91 XFS_FSOP_GEOM_FLAGS_EXTFLG : 0) | 90 XFS_FSOP_GEOM_FLAGS_EXTFLG : 0) |
92 (xfs_sb_version_hasdirv2(&mp->m_sb) ?
93 XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) |
94 (xfs_sb_version_hassector(&mp->m_sb) ? 91 (xfs_sb_version_hassector(&mp->m_sb) ?
95 XFS_FSOP_GEOM_FLAGS_SECTOR : 0) | 92 XFS_FSOP_GEOM_FLAGS_SECTOR : 0) |
96 (xfs_sb_version_hasasciici(&mp->m_sb) ? 93 (xfs_sb_version_hasasciici(&mp->m_sb) ?
@@ -104,11 +101,13 @@ xfs_fs_geometry(
104 (xfs_sb_version_hascrc(&mp->m_sb) ? 101 (xfs_sb_version_hascrc(&mp->m_sb) ?
105 XFS_FSOP_GEOM_FLAGS_V5SB : 0) | 102 XFS_FSOP_GEOM_FLAGS_V5SB : 0) |
106 (xfs_sb_version_hasftype(&mp->m_sb) ? 103 (xfs_sb_version_hasftype(&mp->m_sb) ?
107 XFS_FSOP_GEOM_FLAGS_FTYPE : 0); 104 XFS_FSOP_GEOM_FLAGS_FTYPE : 0) |
105 (xfs_sb_version_hasfinobt(&mp->m_sb) ?
106 XFS_FSOP_GEOM_FLAGS_FINOBT : 0);
108 geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? 107 geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ?
109 mp->m_sb.sb_logsectsize : BBSIZE; 108 mp->m_sb.sb_logsectsize : BBSIZE;
110 geo->rtsectsize = mp->m_sb.sb_blocksize; 109 geo->rtsectsize = mp->m_sb.sb_blocksize;
111 geo->dirblocksize = mp->m_dirblksize; 110 geo->dirblocksize = mp->m_dir_geo->blksize;
112 } 111 }
113 if (new_version >= 4) { 112 if (new_version >= 4) {
114 geo->flags |= 113 geo->flags |=
@@ -316,6 +315,10 @@ xfs_growfs_data_private(
316 agi->agi_dirino = cpu_to_be32(NULLAGINO); 315 agi->agi_dirino = cpu_to_be32(NULLAGINO);
317 if (xfs_sb_version_hascrc(&mp->m_sb)) 316 if (xfs_sb_version_hascrc(&mp->m_sb))
318 uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid); 317 uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid);
318 if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
319 agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
320 agi->agi_free_level = cpu_to_be32(1);
321 }
319 for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) 322 for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++)
320 agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO); 323 agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
321 324
@@ -407,6 +410,34 @@ xfs_growfs_data_private(
407 xfs_buf_relse(bp); 410 xfs_buf_relse(bp);
408 if (error) 411 if (error)
409 goto error0; 412 goto error0;
413
414 /*
415 * FINO btree root block
416 */
417 if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
418 bp = xfs_growfs_get_hdr_buf(mp,
419 XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)),
420 BTOBB(mp->m_sb.sb_blocksize), 0,
421 &xfs_inobt_buf_ops);
422 if (!bp) {
423 error = ENOMEM;
424 goto error0;
425 }
426
427 if (xfs_sb_version_hascrc(&mp->m_sb))
428 xfs_btree_init_block(mp, bp, XFS_FIBT_CRC_MAGIC,
429 0, 0, agno,
430 XFS_BTREE_CRC_BLOCKS);
431 else
432 xfs_btree_init_block(mp, bp, XFS_FIBT_MAGIC, 0,
433 0, agno, 0);
434
435 error = xfs_bwrite(bp);
436 xfs_buf_relse(bp);
437 if (error)
438 goto error0;
439 }
440
410 } 441 }
411 xfs_trans_agblocks_delta(tp, nfree); 442 xfs_trans_agblocks_delta(tp, nfree);
412 /* 443 /*
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 8f711db61a0c..5960e5593fe0 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -112,6 +112,66 @@ xfs_inobt_get_rec(
112} 112}
113 113
114/* 114/*
115 * Insert a single inobt record. Cursor must already point to desired location.
116 */
117STATIC int
118xfs_inobt_insert_rec(
119 struct xfs_btree_cur *cur,
120 __int32_t freecount,
121 xfs_inofree_t free,
122 int *stat)
123{
124 cur->bc_rec.i.ir_freecount = freecount;
125 cur->bc_rec.i.ir_free = free;
126 return xfs_btree_insert(cur, stat);
127}
128
129/*
130 * Insert records describing a newly allocated inode chunk into the inobt.
131 */
132STATIC int
133xfs_inobt_insert(
134 struct xfs_mount *mp,
135 struct xfs_trans *tp,
136 struct xfs_buf *agbp,
137 xfs_agino_t newino,
138 xfs_agino_t newlen,
139 xfs_btnum_t btnum)
140{
141 struct xfs_btree_cur *cur;
142 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
143 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
144 xfs_agino_t thisino;
145 int i;
146 int error;
147
148 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum);
149
150 for (thisino = newino;
151 thisino < newino + newlen;
152 thisino += XFS_INODES_PER_CHUNK) {
153 error = xfs_inobt_lookup(cur, thisino, XFS_LOOKUP_EQ, &i);
154 if (error) {
155 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
156 return error;
157 }
158 ASSERT(i == 0);
159
160 error = xfs_inobt_insert_rec(cur, XFS_INODES_PER_CHUNK,
161 XFS_INOBT_ALL_FREE, &i);
162 if (error) {
163 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
164 return error;
165 }
166 ASSERT(i == 1);
167 }
168
169 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
170
171 return 0;
172}
173
174/*
115 * Verify that the number of free inodes in the AGI is correct. 175 * Verify that the number of free inodes in the AGI is correct.
116 */ 176 */
117#ifdef DEBUG 177#ifdef DEBUG
@@ -220,10 +280,8 @@ xfs_ialloc_inode_init(
220 if (tp) 280 if (tp)
221 xfs_icreate_log(tp, agno, agbno, mp->m_ialloc_inos, 281 xfs_icreate_log(tp, agno, agbno, mp->m_ialloc_inos,
222 mp->m_sb.sb_inodesize, length, gen); 282 mp->m_sb.sb_inodesize, length, gen);
223 } else if (xfs_sb_version_hasnlink(&mp->m_sb)) 283 } else
224 version = 2; 284 version = 2;
225 else
226 version = 1;
227 285
228 for (j = 0; j < nbufs; j++) { 286 for (j = 0; j < nbufs; j++) {
229 /* 287 /*
@@ -303,13 +361,10 @@ xfs_ialloc_ag_alloc(
303{ 361{
304 xfs_agi_t *agi; /* allocation group header */ 362 xfs_agi_t *agi; /* allocation group header */
305 xfs_alloc_arg_t args; /* allocation argument structure */ 363 xfs_alloc_arg_t args; /* allocation argument structure */
306 xfs_btree_cur_t *cur; /* inode btree cursor */
307 xfs_agnumber_t agno; 364 xfs_agnumber_t agno;
308 int error; 365 int error;
309 int i;
310 xfs_agino_t newino; /* new first inode's number */ 366 xfs_agino_t newino; /* new first inode's number */
311 xfs_agino_t newlen; /* new number of inodes */ 367 xfs_agino_t newlen; /* new number of inodes */
312 xfs_agino_t thisino; /* current inode number, for loop */
313 int isaligned = 0; /* inode allocation at stripe unit */ 368 int isaligned = 0; /* inode allocation at stripe unit */
314 /* boundary */ 369 /* boundary */
315 struct xfs_perag *pag; 370 struct xfs_perag *pag;
@@ -459,29 +514,19 @@ xfs_ialloc_ag_alloc(
459 agi->agi_newino = cpu_to_be32(newino); 514 agi->agi_newino = cpu_to_be32(newino);
460 515
461 /* 516 /*
462 * Insert records describing the new inode chunk into the btree. 517 * Insert records describing the new inode chunk into the btrees.
463 */ 518 */
464 cur = xfs_inobt_init_cursor(args.mp, tp, agbp, agno); 519 error = xfs_inobt_insert(args.mp, tp, agbp, newino, newlen,
465 for (thisino = newino; 520 XFS_BTNUM_INO);
466 thisino < newino + newlen; 521 if (error)
467 thisino += XFS_INODES_PER_CHUNK) { 522 return error;
468 cur->bc_rec.i.ir_startino = thisino; 523
469 cur->bc_rec.i.ir_freecount = XFS_INODES_PER_CHUNK; 524 if (xfs_sb_version_hasfinobt(&args.mp->m_sb)) {
470 cur->bc_rec.i.ir_free = XFS_INOBT_ALL_FREE; 525 error = xfs_inobt_insert(args.mp, tp, agbp, newino, newlen,
471 error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, &i); 526 XFS_BTNUM_FINO);
472 if (error) { 527 if (error)
473 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
474 return error;
475 }
476 ASSERT(i == 0);
477 error = xfs_btree_insert(cur, &i);
478 if (error) {
479 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
480 return error; 528 return error;
481 }
482 ASSERT(i == 1);
483 } 529 }
484 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
485 /* 530 /*
486 * Log allocation group header fields 531 * Log allocation group header fields
487 */ 532 */
@@ -675,13 +720,10 @@ xfs_ialloc_get_rec(
675} 720}
676 721
677/* 722/*
678 * Allocate an inode. 723 * Allocate an inode using the inobt-only algorithm.
679 *
680 * The caller selected an AG for us, and made sure that free inodes are
681 * available.
682 */ 724 */
683STATIC int 725STATIC int
684xfs_dialloc_ag( 726xfs_dialloc_ag_inobt(
685 struct xfs_trans *tp, 727 struct xfs_trans *tp,
686 struct xfs_buf *agbp, 728 struct xfs_buf *agbp,
687 xfs_ino_t parent, 729 xfs_ino_t parent,
@@ -707,7 +749,7 @@ xfs_dialloc_ag(
707 ASSERT(pag->pagi_freecount > 0); 749 ASSERT(pag->pagi_freecount > 0);
708 750
709 restart_pagno: 751 restart_pagno:
710 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); 752 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO);
711 /* 753 /*
712 * If pagino is 0 (this is the root inode allocation) use newino. 754 * If pagino is 0 (this is the root inode allocation) use newino.
713 * This must work because we've just allocated some. 755 * This must work because we've just allocated some.
@@ -940,6 +982,294 @@ error0:
940} 982}
941 983
942/* 984/*
985 * Use the free inode btree to allocate an inode based on distance from the
986 * parent. Note that the provided cursor may be deleted and replaced.
987 */
988STATIC int
989xfs_dialloc_ag_finobt_near(
990 xfs_agino_t pagino,
991 struct xfs_btree_cur **ocur,
992 struct xfs_inobt_rec_incore *rec)
993{
994 struct xfs_btree_cur *lcur = *ocur; /* left search cursor */
995 struct xfs_btree_cur *rcur; /* right search cursor */
996 struct xfs_inobt_rec_incore rrec;
997 int error;
998 int i, j;
999
1000 error = xfs_inobt_lookup(lcur, pagino, XFS_LOOKUP_LE, &i);
1001 if (error)
1002 return error;
1003
1004 if (i == 1) {
1005 error = xfs_inobt_get_rec(lcur, rec, &i);
1006 if (error)
1007 return error;
1008 XFS_WANT_CORRUPTED_RETURN(i == 1);
1009
1010 /*
1011 * See if we've landed in the parent inode record. The finobt
1012 * only tracks chunks with at least one free inode, so record
1013 * existence is enough.
1014 */
1015 if (pagino >= rec->ir_startino &&
1016 pagino < (rec->ir_startino + XFS_INODES_PER_CHUNK))
1017 return 0;
1018 }
1019
1020 error = xfs_btree_dup_cursor(lcur, &rcur);
1021 if (error)
1022 return error;
1023
1024 error = xfs_inobt_lookup(rcur, pagino, XFS_LOOKUP_GE, &j);
1025 if (error)
1026 goto error_rcur;
1027 if (j == 1) {
1028 error = xfs_inobt_get_rec(rcur, &rrec, &j);
1029 if (error)
1030 goto error_rcur;
1031 XFS_WANT_CORRUPTED_GOTO(j == 1, error_rcur);
1032 }
1033
1034 XFS_WANT_CORRUPTED_GOTO(i == 1 || j == 1, error_rcur);
1035 if (i == 1 && j == 1) {
1036 /*
1037 * Both the left and right records are valid. Choose the closer
1038 * inode chunk to the target.
1039 */
1040 if ((pagino - rec->ir_startino + XFS_INODES_PER_CHUNK - 1) >
1041 (rrec.ir_startino - pagino)) {
1042 *rec = rrec;
1043 xfs_btree_del_cursor(lcur, XFS_BTREE_NOERROR);
1044 *ocur = rcur;
1045 } else {
1046 xfs_btree_del_cursor(rcur, XFS_BTREE_NOERROR);
1047 }
1048 } else if (j == 1) {
1049 /* only the right record is valid */
1050 *rec = rrec;
1051 xfs_btree_del_cursor(lcur, XFS_BTREE_NOERROR);
1052 *ocur = rcur;
1053 } else if (i == 1) {
1054 /* only the left record is valid */
1055 xfs_btree_del_cursor(rcur, XFS_BTREE_NOERROR);
1056 }
1057
1058 return 0;
1059
1060error_rcur:
1061 xfs_btree_del_cursor(rcur, XFS_BTREE_ERROR);
1062 return error;
1063}
1064
1065/*
1066 * Use the free inode btree to find a free inode based on a newino hint. If
1067 * the hint is NULL, find the first free inode in the AG.
1068 */
1069STATIC int
1070xfs_dialloc_ag_finobt_newino(
1071 struct xfs_agi *agi,
1072 struct xfs_btree_cur *cur,
1073 struct xfs_inobt_rec_incore *rec)
1074{
1075 int error;
1076 int i;
1077
1078 if (agi->agi_newino != cpu_to_be32(NULLAGINO)) {
1079 error = xfs_inobt_lookup(cur, agi->agi_newino, XFS_LOOKUP_EQ,
1080 &i);
1081 if (error)
1082 return error;
1083 if (i == 1) {
1084 error = xfs_inobt_get_rec(cur, rec, &i);
1085 if (error)
1086 return error;
1087 XFS_WANT_CORRUPTED_RETURN(i == 1);
1088
1089 return 0;
1090 }
1091 }
1092
1093 /*
1094 * Find the first inode available in the AG.
1095 */
1096 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
1097 if (error)
1098 return error;
1099 XFS_WANT_CORRUPTED_RETURN(i == 1);
1100
1101 error = xfs_inobt_get_rec(cur, rec, &i);
1102 if (error)
1103 return error;
1104 XFS_WANT_CORRUPTED_RETURN(i == 1);
1105
1106 return 0;
1107}
1108
1109/*
1110 * Update the inobt based on a modification made to the finobt. Also ensure that
1111 * the records from both trees are equivalent post-modification.
1112 */
1113STATIC int
1114xfs_dialloc_ag_update_inobt(
1115 struct xfs_btree_cur *cur, /* inobt cursor */
1116 struct xfs_inobt_rec_incore *frec, /* finobt record */
1117 int offset) /* inode offset */
1118{
1119 struct xfs_inobt_rec_incore rec;
1120 int error;
1121 int i;
1122
1123 error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i);
1124 if (error)
1125 return error;
1126 XFS_WANT_CORRUPTED_RETURN(i == 1);
1127
1128 error = xfs_inobt_get_rec(cur, &rec, &i);
1129 if (error)
1130 return error;
1131 XFS_WANT_CORRUPTED_RETURN(i == 1);
1132 ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) %
1133 XFS_INODES_PER_CHUNK) == 0);
1134
1135 rec.ir_free &= ~XFS_INOBT_MASK(offset);
1136 rec.ir_freecount--;
1137
1138 XFS_WANT_CORRUPTED_RETURN((rec.ir_free == frec->ir_free) &&
1139 (rec.ir_freecount == frec->ir_freecount));
1140
1141 error = xfs_inobt_update(cur, &rec);
1142 if (error)
1143 return error;
1144
1145 return 0;
1146}
1147
1148/*
1149 * Allocate an inode using the free inode btree, if available. Otherwise, fall
1150 * back to the inobt search algorithm.
1151 *
1152 * The caller selected an AG for us, and made sure that free inodes are
1153 * available.
1154 */
1155STATIC int
1156xfs_dialloc_ag(
1157 struct xfs_trans *tp,
1158 struct xfs_buf *agbp,
1159 xfs_ino_t parent,
1160 xfs_ino_t *inop)
1161{
1162 struct xfs_mount *mp = tp->t_mountp;
1163 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
1164 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
1165 xfs_agnumber_t pagno = XFS_INO_TO_AGNO(mp, parent);
1166 xfs_agino_t pagino = XFS_INO_TO_AGINO(mp, parent);
1167 struct xfs_perag *pag;
1168 struct xfs_btree_cur *cur; /* finobt cursor */
1169 struct xfs_btree_cur *icur; /* inobt cursor */
1170 struct xfs_inobt_rec_incore rec;
1171 xfs_ino_t ino;
1172 int error;
1173 int offset;
1174 int i;
1175
1176 if (!xfs_sb_version_hasfinobt(&mp->m_sb))
1177 return xfs_dialloc_ag_inobt(tp, agbp, parent, inop);
1178
1179 pag = xfs_perag_get(mp, agno);
1180
1181 /*
1182 * If pagino is 0 (this is the root inode allocation) use newino.
1183 * This must work because we've just allocated some.
1184 */
1185 if (!pagino)
1186 pagino = be32_to_cpu(agi->agi_newino);
1187
1188 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_FINO);
1189
1190 error = xfs_check_agi_freecount(cur, agi);
1191 if (error)
1192 goto error_cur;
1193
1194 /*
1195 * The search algorithm depends on whether we're in the same AG as the
1196 * parent. If so, find the closest available inode to the parent. If
1197 * not, consider the agi hint or find the first free inode in the AG.
1198 */
1199 if (agno == pagno)
1200 error = xfs_dialloc_ag_finobt_near(pagino, &cur, &rec);
1201 else
1202 error = xfs_dialloc_ag_finobt_newino(agi, cur, &rec);
1203 if (error)
1204 goto error_cur;
1205
1206 offset = xfs_lowbit64(rec.ir_free);
1207 ASSERT(offset >= 0);
1208 ASSERT(offset < XFS_INODES_PER_CHUNK);
1209 ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
1210 XFS_INODES_PER_CHUNK) == 0);
1211 ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
1212
1213 /*
1214 * Modify or remove the finobt record.
1215 */
1216 rec.ir_free &= ~XFS_INOBT_MASK(offset);
1217 rec.ir_freecount--;
1218 if (rec.ir_freecount)
1219 error = xfs_inobt_update(cur, &rec);
1220 else
1221 error = xfs_btree_delete(cur, &i);
1222 if (error)
1223 goto error_cur;
1224
1225 /*
1226 * The finobt has now been updated appropriately. We haven't updated the
1227 * agi and superblock yet, so we can create an inobt cursor and validate
1228 * the original freecount. If all is well, make the equivalent update to
1229 * the inobt using the finobt record and offset information.
1230 */
1231 icur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO);
1232
1233 error = xfs_check_agi_freecount(icur, agi);
1234 if (error)
1235 goto error_icur;
1236
1237 error = xfs_dialloc_ag_update_inobt(icur, &rec, offset);
1238 if (error)
1239 goto error_icur;
1240
1241 /*
1242 * Both trees have now been updated. We must update the perag and
1243 * superblock before we can check the freecount for each btree.
1244 */
1245 be32_add_cpu(&agi->agi_freecount, -1);
1246 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
1247 pag->pagi_freecount--;
1248
1249 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
1250
1251 error = xfs_check_agi_freecount(icur, agi);
1252 if (error)
1253 goto error_icur;
1254 error = xfs_check_agi_freecount(cur, agi);
1255 if (error)
1256 goto error_icur;
1257
1258 xfs_btree_del_cursor(icur, XFS_BTREE_NOERROR);
1259 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1260 xfs_perag_put(pag);
1261 *inop = ino;
1262 return 0;
1263
1264error_icur:
1265 xfs_btree_del_cursor(icur, XFS_BTREE_ERROR);
1266error_cur:
1267 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1268 xfs_perag_put(pag);
1269 return error;
1270}
1271
1272/*
943 * Allocate an inode on disk. 1273 * Allocate an inode on disk.
944 * 1274 *
945 * Mode is used to tell whether the new inode will need space, and whether it 1275 * Mode is used to tell whether the new inode will need space, and whether it
@@ -1098,78 +1428,34 @@ out_error:
1098 return XFS_ERROR(error); 1428 return XFS_ERROR(error);
1099} 1429}
1100 1430
1101/* 1431STATIC int
1102 * Free disk inode. Carefully avoids touching the incore inode, all 1432xfs_difree_inobt(
1103 * manipulations incore are the caller's responsibility. 1433 struct xfs_mount *mp,
1104 * The on-disk inode is not changed by this operation, only the 1434 struct xfs_trans *tp,
1105 * btree (free inode mask) is changed. 1435 struct xfs_buf *agbp,
1106 */ 1436 xfs_agino_t agino,
1107int 1437 struct xfs_bmap_free *flist,
1108xfs_difree( 1438 int *deleted,
1109 xfs_trans_t *tp, /* transaction pointer */ 1439 xfs_ino_t *first_ino,
1110 xfs_ino_t inode, /* inode to be freed */ 1440 struct xfs_inobt_rec_incore *orec)
1111 xfs_bmap_free_t *flist, /* extents to free */
1112 int *delete, /* set if inode cluster was deleted */
1113 xfs_ino_t *first_ino) /* first inode in deleted cluster */
1114{ 1441{
1115 /* REFERENCED */ 1442 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
1116 xfs_agblock_t agbno; /* block number containing inode */ 1443 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
1117 xfs_buf_t *agbp; /* buffer containing allocation group header */ 1444 struct xfs_perag *pag;
1118 xfs_agino_t agino; /* inode number relative to allocation group */ 1445 struct xfs_btree_cur *cur;
1119 xfs_agnumber_t agno; /* allocation group number */ 1446 struct xfs_inobt_rec_incore rec;
1120 xfs_agi_t *agi; /* allocation group header */ 1447 int ilen;
1121 xfs_btree_cur_t *cur; /* inode btree cursor */ 1448 int error;
1122 int error; /* error return value */ 1449 int i;
1123 int i; /* result code */ 1450 int off;
1124 int ilen; /* inodes in an inode cluster */
1125 xfs_mount_t *mp; /* mount structure for filesystem */
1126 int off; /* offset of inode in inode chunk */
1127 xfs_inobt_rec_incore_t rec; /* btree record */
1128 struct xfs_perag *pag;
1129 1451
1130 mp = tp->t_mountp;
1131
1132 /*
1133 * Break up inode number into its components.
1134 */
1135 agno = XFS_INO_TO_AGNO(mp, inode);
1136 if (agno >= mp->m_sb.sb_agcount) {
1137 xfs_warn(mp, "%s: agno >= mp->m_sb.sb_agcount (%d >= %d).",
1138 __func__, agno, mp->m_sb.sb_agcount);
1139 ASSERT(0);
1140 return XFS_ERROR(EINVAL);
1141 }
1142 agino = XFS_INO_TO_AGINO(mp, inode);
1143 if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
1144 xfs_warn(mp, "%s: inode != XFS_AGINO_TO_INO() (%llu != %llu).",
1145 __func__, (unsigned long long)inode,
1146 (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino));
1147 ASSERT(0);
1148 return XFS_ERROR(EINVAL);
1149 }
1150 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1151 if (agbno >= mp->m_sb.sb_agblocks) {
1152 xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).",
1153 __func__, agbno, mp->m_sb.sb_agblocks);
1154 ASSERT(0);
1155 return XFS_ERROR(EINVAL);
1156 }
1157 /*
1158 * Get the allocation group header.
1159 */
1160 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
1161 if (error) {
1162 xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.",
1163 __func__, error);
1164 return error;
1165 }
1166 agi = XFS_BUF_TO_AGI(agbp);
1167 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); 1452 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
1168 ASSERT(agbno < be32_to_cpu(agi->agi_length)); 1453 ASSERT(XFS_AGINO_TO_AGBNO(mp, agino) < be32_to_cpu(agi->agi_length));
1454
1169 /* 1455 /*
1170 * Initialize the cursor. 1456 * Initialize the cursor.
1171 */ 1457 */
1172 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); 1458 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO);
1173 1459
1174 error = xfs_check_agi_freecount(cur, agi); 1460 error = xfs_check_agi_freecount(cur, agi);
1175 if (error) 1461 if (error)
@@ -1209,7 +1495,7 @@ xfs_difree(
1209 if (!(mp->m_flags & XFS_MOUNT_IKEEP) && 1495 if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
1210 (rec.ir_freecount == mp->m_ialloc_inos)) { 1496 (rec.ir_freecount == mp->m_ialloc_inos)) {
1211 1497
1212 *delete = 1; 1498 *deleted = 1;
1213 *first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino); 1499 *first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
1214 1500
1215 /* 1501 /*
@@ -1237,7 +1523,7 @@ xfs_difree(
1237 XFS_AGINO_TO_AGBNO(mp, rec.ir_startino)), 1523 XFS_AGINO_TO_AGBNO(mp, rec.ir_startino)),
1238 mp->m_ialloc_blks, flist, mp); 1524 mp->m_ialloc_blks, flist, mp);
1239 } else { 1525 } else {
1240 *delete = 0; 1526 *deleted = 0;
1241 1527
1242 error = xfs_inobt_update(cur, &rec); 1528 error = xfs_inobt_update(cur, &rec);
1243 if (error) { 1529 if (error) {
@@ -1261,6 +1547,7 @@ xfs_difree(
1261 if (error) 1547 if (error)
1262 goto error0; 1548 goto error0;
1263 1549
1550 *orec = rec;
1264 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 1551 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1265 return 0; 1552 return 0;
1266 1553
@@ -1269,6 +1556,182 @@ error0:
1269 return error; 1556 return error;
1270} 1557}
1271 1558
1559/*
1560 * Free an inode in the free inode btree.
1561 */
1562STATIC int
1563xfs_difree_finobt(
1564 struct xfs_mount *mp,
1565 struct xfs_trans *tp,
1566 struct xfs_buf *agbp,
1567 xfs_agino_t agino,
1568 struct xfs_inobt_rec_incore *ibtrec) /* inobt record */
1569{
1570 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
1571 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
1572 struct xfs_btree_cur *cur;
1573 struct xfs_inobt_rec_incore rec;
1574 int offset = agino - ibtrec->ir_startino;
1575 int error;
1576 int i;
1577
1578 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_FINO);
1579
1580 error = xfs_inobt_lookup(cur, ibtrec->ir_startino, XFS_LOOKUP_EQ, &i);
1581 if (error)
1582 goto error;
1583 if (i == 0) {
1584 /*
1585 * If the record does not exist in the finobt, we must have just
1586 * freed an inode in a previously fully allocated chunk. If not,
1587 * something is out of sync.
1588 */
1589 XFS_WANT_CORRUPTED_GOTO(ibtrec->ir_freecount == 1, error);
1590
1591 error = xfs_inobt_insert_rec(cur, ibtrec->ir_freecount,
1592 ibtrec->ir_free, &i);
1593 if (error)
1594 goto error;
1595 ASSERT(i == 1);
1596
1597 goto out;
1598 }
1599
1600 /*
1601 * Read and update the existing record. We could just copy the ibtrec
1602 * across here, but that would defeat the purpose of having redundant
1603 * metadata. By making the modifications independently, we can catch
1604 * corruptions that we wouldn't see if we just copied from one record
1605 * to another.
1606 */
1607 error = xfs_inobt_get_rec(cur, &rec, &i);
1608 if (error)
1609 goto error;
1610 XFS_WANT_CORRUPTED_GOTO(i == 1, error);
1611
1612 rec.ir_free |= XFS_INOBT_MASK(offset);
1613 rec.ir_freecount++;
1614
1615 XFS_WANT_CORRUPTED_GOTO((rec.ir_free == ibtrec->ir_free) &&
1616 (rec.ir_freecount == ibtrec->ir_freecount),
1617 error);
1618
1619 /*
1620 * The content of inobt records should always match between the inobt
1621 * and finobt. The lifecycle of records in the finobt is different from
1622 * the inobt in that the finobt only tracks records with at least one
1623 * free inode. Hence, if all of the inodes are free and we aren't
1624 * keeping inode chunks permanently on disk, remove the record.
1625 * Otherwise, update the record with the new information.
1626 */
1627 if (rec.ir_freecount == mp->m_ialloc_inos &&
1628 !(mp->m_flags & XFS_MOUNT_IKEEP)) {
1629 error = xfs_btree_delete(cur, &i);
1630 if (error)
1631 goto error;
1632 ASSERT(i == 1);
1633 } else {
1634 error = xfs_inobt_update(cur, &rec);
1635 if (error)
1636 goto error;
1637 }
1638
1639out:
1640 error = xfs_check_agi_freecount(cur, agi);
1641 if (error)
1642 goto error;
1643
1644 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1645 return 0;
1646
1647error:
1648 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1649 return error;
1650}
1651
1652/*
1653 * Free disk inode. Carefully avoids touching the incore inode, all
1654 * manipulations incore are the caller's responsibility.
1655 * The on-disk inode is not changed by this operation, only the
1656 * btree (free inode mask) is changed.
1657 */
1658int
1659xfs_difree(
1660 struct xfs_trans *tp, /* transaction pointer */
1661 xfs_ino_t inode, /* inode to be freed */
1662 struct xfs_bmap_free *flist, /* extents to free */
1663 int *deleted,/* set if inode cluster was deleted */
1664 xfs_ino_t *first_ino)/* first inode in deleted cluster */
1665{
1666 /* REFERENCED */
1667 xfs_agblock_t agbno; /* block number containing inode */
1668 struct xfs_buf *agbp; /* buffer for allocation group header */
1669 xfs_agino_t agino; /* allocation group inode number */
1670 xfs_agnumber_t agno; /* allocation group number */
1671 int error; /* error return value */
1672 struct xfs_mount *mp; /* mount structure for filesystem */
1673 struct xfs_inobt_rec_incore rec;/* btree record */
1674
1675 mp = tp->t_mountp;
1676
1677 /*
1678 * Break up inode number into its components.
1679 */
1680 agno = XFS_INO_TO_AGNO(mp, inode);
1681 if (agno >= mp->m_sb.sb_agcount) {
1682 xfs_warn(mp, "%s: agno >= mp->m_sb.sb_agcount (%d >= %d).",
1683 __func__, agno, mp->m_sb.sb_agcount);
1684 ASSERT(0);
1685 return XFS_ERROR(EINVAL);
1686 }
1687 agino = XFS_INO_TO_AGINO(mp, inode);
1688 if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
1689 xfs_warn(mp, "%s: inode != XFS_AGINO_TO_INO() (%llu != %llu).",
1690 __func__, (unsigned long long)inode,
1691 (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino));
1692 ASSERT(0);
1693 return XFS_ERROR(EINVAL);
1694 }
1695 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1696 if (agbno >= mp->m_sb.sb_agblocks) {
1697 xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).",
1698 __func__, agbno, mp->m_sb.sb_agblocks);
1699 ASSERT(0);
1700 return XFS_ERROR(EINVAL);
1701 }
1702 /*
1703 * Get the allocation group header.
1704 */
1705 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
1706 if (error) {
1707 xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.",
1708 __func__, error);
1709 return error;
1710 }
1711
1712 /*
1713 * Fix up the inode allocation btree.
1714 */
1715 error = xfs_difree_inobt(mp, tp, agbp, agino, flist, deleted, first_ino,
1716 &rec);
1717 if (error)
1718 goto error0;
1719
1720 /*
1721 * Fix up the free inode btree.
1722 */
1723 if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
1724 error = xfs_difree_finobt(mp, tp, agbp, agino, &rec);
1725 if (error)
1726 goto error0;
1727 }
1728
1729 return 0;
1730
1731error0:
1732 return error;
1733}
1734
1272STATIC int 1735STATIC int
1273xfs_imap_lookup( 1736xfs_imap_lookup(
1274 struct xfs_mount *mp, 1737 struct xfs_mount *mp,
@@ -1300,7 +1763,7 @@ xfs_imap_lookup(
1300 * we have a record, we need to ensure it contains the inode number 1763 * we have a record, we need to ensure it contains the inode number
1301 * we are looking up. 1764 * we are looking up.
1302 */ 1765 */
1303 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno); 1766 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO);
1304 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i); 1767 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);
1305 if (!error) { 1768 if (!error) {
1306 if (i) 1769 if (i)
@@ -1488,7 +1951,16 @@ xfs_ialloc_compute_maxlevels(
1488} 1951}
1489 1952
1490/* 1953/*
1491 * Log specified fields for the ag hdr (inode section) 1954 * Log specified fields for the ag hdr (inode section). The growth of the agi
1955 * structure over time requires that we interpret the buffer as two logical
1956 * regions delineated by the end of the unlinked list. This is due to the size
1957 * of the hash table and its location in the middle of the agi.
1958 *
1959 * For example, a request to log a field before agi_unlinked and a field after
1960 * agi_unlinked could cause us to log the entire hash table and use an excessive
1961 * amount of log space. To avoid this behavior, log the region up through
1962 * agi_unlinked in one call and the region after agi_unlinked through the end of
1963 * the structure in another.
1492 */ 1964 */
1493void 1965void
1494xfs_ialloc_log_agi( 1966xfs_ialloc_log_agi(
@@ -1511,6 +1983,8 @@ xfs_ialloc_log_agi(
1511 offsetof(xfs_agi_t, agi_newino), 1983 offsetof(xfs_agi_t, agi_newino),
1512 offsetof(xfs_agi_t, agi_dirino), 1984 offsetof(xfs_agi_t, agi_dirino),
1513 offsetof(xfs_agi_t, agi_unlinked), 1985 offsetof(xfs_agi_t, agi_unlinked),
1986 offsetof(xfs_agi_t, agi_free_root),
1987 offsetof(xfs_agi_t, agi_free_level),
1514 sizeof(xfs_agi_t) 1988 sizeof(xfs_agi_t)
1515 }; 1989 };
1516#ifdef DEBUG 1990#ifdef DEBUG
@@ -1519,15 +1993,30 @@ xfs_ialloc_log_agi(
1519 agi = XFS_BUF_TO_AGI(bp); 1993 agi = XFS_BUF_TO_AGI(bp);
1520 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC)); 1994 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
1521#endif 1995#endif
1996
1997 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGI_BUF);
1998
1522 /* 1999 /*
1523 * Compute byte offsets for the first and last fields. 2000 * Compute byte offsets for the first and last fields in the first
2001 * region and log the agi buffer. This only logs up through
2002 * agi_unlinked.
1524 */ 2003 */
1525 xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS, &first, &last); 2004 if (fields & XFS_AGI_ALL_BITS_R1) {
2005 xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS_R1,
2006 &first, &last);
2007 xfs_trans_log_buf(tp, bp, first, last);
2008 }
2009
1526 /* 2010 /*
1527 * Log the allocation group inode header buffer. 2011 * Mask off the bits in the first region and calculate the first and
2012 * last field offsets for any bits in the second region.
1528 */ 2013 */
1529 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGI_BUF); 2014 fields &= ~XFS_AGI_ALL_BITS_R1;
1530 xfs_trans_log_buf(tp, bp, first, last); 2015 if (fields) {
2016 xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS_R2,
2017 &first, &last);
2018 xfs_trans_log_buf(tp, bp, first, last);
2019 }
1531} 2020}
1532 2021
1533#ifdef DEBUG 2022#ifdef DEBUG
@@ -1640,7 +2129,6 @@ xfs_read_agi(
1640 if (error) 2129 if (error)
1641 return error; 2130 return error;
1642 2131
1643 ASSERT(!xfs_buf_geterror(*bpp));
1644 xfs_buf_set_ref(*bpp, XFS_AGI_REF); 2132 xfs_buf_set_ref(*bpp, XFS_AGI_REF);
1645 return 0; 2133 return 0;
1646} 2134}
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h
index 812365d17e67..95ad1c002d60 100644
--- a/fs/xfs/xfs_ialloc.h
+++ b/fs/xfs/xfs_ialloc.h
@@ -90,7 +90,7 @@ xfs_difree(
90 struct xfs_trans *tp, /* transaction pointer */ 90 struct xfs_trans *tp, /* transaction pointer */
91 xfs_ino_t inode, /* inode to be freed */ 91 xfs_ino_t inode, /* inode to be freed */
92 struct xfs_bmap_free *flist, /* extents to free */ 92 struct xfs_bmap_free *flist, /* extents to free */
93 int *delete, /* set if inode cluster was deleted */ 93 int *deleted, /* set if inode cluster was deleted */
94 xfs_ino_t *first_ino); /* first inode in deleted cluster */ 94 xfs_ino_t *first_ino); /* first inode in deleted cluster */
95 95
96/* 96/*
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 7e309b11e87d..726f83a681a5 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -49,7 +49,8 @@ xfs_inobt_dup_cursor(
49 struct xfs_btree_cur *cur) 49 struct xfs_btree_cur *cur)
50{ 50{
51 return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, 51 return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp,
52 cur->bc_private.a.agbp, cur->bc_private.a.agno); 52 cur->bc_private.a.agbp, cur->bc_private.a.agno,
53 cur->bc_btnum);
53} 54}
54 55
55STATIC void 56STATIC void
@@ -66,12 +67,26 @@ xfs_inobt_set_root(
66 xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL); 67 xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL);
67} 68}
68 69
70STATIC void
71xfs_finobt_set_root(
72 struct xfs_btree_cur *cur,
73 union xfs_btree_ptr *nptr,
74 int inc) /* level change */
75{
76 struct xfs_buf *agbp = cur->bc_private.a.agbp;
77 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
78
79 agi->agi_free_root = nptr->s;
80 be32_add_cpu(&agi->agi_free_level, inc);
81 xfs_ialloc_log_agi(cur->bc_tp, agbp,
82 XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL);
83}
84
69STATIC int 85STATIC int
70xfs_inobt_alloc_block( 86xfs_inobt_alloc_block(
71 struct xfs_btree_cur *cur, 87 struct xfs_btree_cur *cur,
72 union xfs_btree_ptr *start, 88 union xfs_btree_ptr *start,
73 union xfs_btree_ptr *new, 89 union xfs_btree_ptr *new,
74 int length,
75 int *stat) 90 int *stat)
76{ 91{
77 xfs_alloc_arg_t args; /* block allocation args */ 92 xfs_alloc_arg_t args; /* block allocation args */
@@ -173,6 +188,17 @@ xfs_inobt_init_ptr_from_cur(
173 ptr->s = agi->agi_root; 188 ptr->s = agi->agi_root;
174} 189}
175 190
191STATIC void
192xfs_finobt_init_ptr_from_cur(
193 struct xfs_btree_cur *cur,
194 union xfs_btree_ptr *ptr)
195{
196 struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
197
198 ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno));
199 ptr->s = agi->agi_free_root;
200}
201
176STATIC __int64_t 202STATIC __int64_t
177xfs_inobt_key_diff( 203xfs_inobt_key_diff(
178 struct xfs_btree_cur *cur, 204 struct xfs_btree_cur *cur,
@@ -203,6 +229,7 @@ xfs_inobt_verify(
203 */ 229 */
204 switch (block->bb_magic) { 230 switch (block->bb_magic) {
205 case cpu_to_be32(XFS_IBT_CRC_MAGIC): 231 case cpu_to_be32(XFS_IBT_CRC_MAGIC):
232 case cpu_to_be32(XFS_FIBT_CRC_MAGIC):
206 if (!xfs_sb_version_hascrc(&mp->m_sb)) 233 if (!xfs_sb_version_hascrc(&mp->m_sb))
207 return false; 234 return false;
208 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) 235 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid))
@@ -214,6 +241,7 @@ xfs_inobt_verify(
214 return false; 241 return false;
215 /* fall through */ 242 /* fall through */
216 case cpu_to_be32(XFS_IBT_MAGIC): 243 case cpu_to_be32(XFS_IBT_MAGIC):
244 case cpu_to_be32(XFS_FIBT_MAGIC):
217 break; 245 break;
218 default: 246 default:
219 return 0; 247 return 0;
@@ -317,6 +345,28 @@ static const struct xfs_btree_ops xfs_inobt_ops = {
317#endif 345#endif
318}; 346};
319 347
348static const struct xfs_btree_ops xfs_finobt_ops = {
349 .rec_len = sizeof(xfs_inobt_rec_t),
350 .key_len = sizeof(xfs_inobt_key_t),
351
352 .dup_cursor = xfs_inobt_dup_cursor,
353 .set_root = xfs_finobt_set_root,
354 .alloc_block = xfs_inobt_alloc_block,
355 .free_block = xfs_inobt_free_block,
356 .get_minrecs = xfs_inobt_get_minrecs,
357 .get_maxrecs = xfs_inobt_get_maxrecs,
358 .init_key_from_rec = xfs_inobt_init_key_from_rec,
359 .init_rec_from_key = xfs_inobt_init_rec_from_key,
360 .init_rec_from_cur = xfs_inobt_init_rec_from_cur,
361 .init_ptr_from_cur = xfs_finobt_init_ptr_from_cur,
362 .key_diff = xfs_inobt_key_diff,
363 .buf_ops = &xfs_inobt_buf_ops,
364#if defined(DEBUG) || defined(XFS_WARN)
365 .keys_inorder = xfs_inobt_keys_inorder,
366 .recs_inorder = xfs_inobt_recs_inorder,
367#endif
368};
369
320/* 370/*
321 * Allocate a new inode btree cursor. 371 * Allocate a new inode btree cursor.
322 */ 372 */
@@ -325,7 +375,8 @@ xfs_inobt_init_cursor(
325 struct xfs_mount *mp, /* file system mount point */ 375 struct xfs_mount *mp, /* file system mount point */
326 struct xfs_trans *tp, /* transaction pointer */ 376 struct xfs_trans *tp, /* transaction pointer */
327 struct xfs_buf *agbp, /* buffer for agi structure */ 377 struct xfs_buf *agbp, /* buffer for agi structure */
328 xfs_agnumber_t agno) /* allocation group number */ 378 xfs_agnumber_t agno, /* allocation group number */
379 xfs_btnum_t btnum) /* ialloc or free ino btree */
329{ 380{
330 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); 381 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
331 struct xfs_btree_cur *cur; 382 struct xfs_btree_cur *cur;
@@ -334,11 +385,17 @@ xfs_inobt_init_cursor(
334 385
335 cur->bc_tp = tp; 386 cur->bc_tp = tp;
336 cur->bc_mp = mp; 387 cur->bc_mp = mp;
337 cur->bc_nlevels = be32_to_cpu(agi->agi_level); 388 cur->bc_btnum = btnum;
338 cur->bc_btnum = XFS_BTNUM_INO; 389 if (btnum == XFS_BTNUM_INO) {
390 cur->bc_nlevels = be32_to_cpu(agi->agi_level);
391 cur->bc_ops = &xfs_inobt_ops;
392 } else {
393 cur->bc_nlevels = be32_to_cpu(agi->agi_free_level);
394 cur->bc_ops = &xfs_finobt_ops;
395 }
396
339 cur->bc_blocklog = mp->m_sb.sb_blocklog; 397 cur->bc_blocklog = mp->m_sb.sb_blocklog;
340 398
341 cur->bc_ops = &xfs_inobt_ops;
342 if (xfs_sb_version_hascrc(&mp->m_sb)) 399 if (xfs_sb_version_hascrc(&mp->m_sb))
343 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; 400 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
344 401
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
index f38b22011c4e..d7ebea72c2d0 100644
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -58,7 +58,8 @@ struct xfs_mount;
58 ((index) - 1) * sizeof(xfs_inobt_ptr_t))) 58 ((index) - 1) * sizeof(xfs_inobt_ptr_t)))
59 59
60extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *, 60extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *,
61 struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t); 61 struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t,
62 xfs_btnum_t);
62extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int); 63extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int);
63 64
64#endif /* __XFS_IALLOC_BTREE_H__ */ 65#endif /* __XFS_IALLOC_BTREE_H__ */
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 98d35244eecc..c48df5f25b9f 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -507,8 +507,7 @@ STATIC int
507xfs_inode_ag_walk( 507xfs_inode_ag_walk(
508 struct xfs_mount *mp, 508 struct xfs_mount *mp,
509 struct xfs_perag *pag, 509 struct xfs_perag *pag,
510 int (*execute)(struct xfs_inode *ip, 510 int (*execute)(struct xfs_inode *ip, int flags,
511 struct xfs_perag *pag, int flags,
512 void *args), 511 void *args),
513 int flags, 512 int flags,
514 void *args, 513 void *args,
@@ -582,7 +581,7 @@ restart:
582 for (i = 0; i < nr_found; i++) { 581 for (i = 0; i < nr_found; i++) {
583 if (!batch[i]) 582 if (!batch[i])
584 continue; 583 continue;
585 error = execute(batch[i], pag, flags, args); 584 error = execute(batch[i], flags, args);
586 IRELE(batch[i]); 585 IRELE(batch[i]);
587 if (error == EAGAIN) { 586 if (error == EAGAIN) {
588 skipped++; 587 skipped++;
@@ -636,8 +635,7 @@ xfs_eofblocks_worker(
636int 635int
637xfs_inode_ag_iterator( 636xfs_inode_ag_iterator(
638 struct xfs_mount *mp, 637 struct xfs_mount *mp,
639 int (*execute)(struct xfs_inode *ip, 638 int (*execute)(struct xfs_inode *ip, int flags,
640 struct xfs_perag *pag, int flags,
641 void *args), 639 void *args),
642 int flags, 640 int flags,
643 void *args) 641 void *args)
@@ -664,8 +662,7 @@ xfs_inode_ag_iterator(
664int 662int
665xfs_inode_ag_iterator_tag( 663xfs_inode_ag_iterator_tag(
666 struct xfs_mount *mp, 664 struct xfs_mount *mp,
667 int (*execute)(struct xfs_inode *ip, 665 int (*execute)(struct xfs_inode *ip, int flags,
668 struct xfs_perag *pag, int flags,
669 void *args), 666 void *args),
670 int flags, 667 int flags,
671 void *args, 668 void *args,
@@ -1209,7 +1206,6 @@ xfs_inode_match_id(
1209STATIC int 1206STATIC int
1210xfs_inode_free_eofblocks( 1207xfs_inode_free_eofblocks(
1211 struct xfs_inode *ip, 1208 struct xfs_inode *ip,
1212 struct xfs_perag *pag,
1213 int flags, 1209 int flags,
1214 void *args) 1210 void *args)
1215{ 1211{
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index 9ed68bb750f5..9cf017b899be 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -60,12 +60,10 @@ int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *);
60void xfs_eofblocks_worker(struct work_struct *); 60void xfs_eofblocks_worker(struct work_struct *);
61 61
62int xfs_inode_ag_iterator(struct xfs_mount *mp, 62int xfs_inode_ag_iterator(struct xfs_mount *mp,
63 int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, 63 int (*execute)(struct xfs_inode *ip, int flags, void *args),
64 int flags, void *args),
65 int flags, void *args); 64 int flags, void *args);
66int xfs_inode_ag_iterator_tag(struct xfs_mount *mp, 65int xfs_inode_ag_iterator_tag(struct xfs_mount *mp,
67 int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, 66 int (*execute)(struct xfs_inode *ip, int flags, void *args),
68 int flags, void *args),
69 int flags, void *args, int tag); 67 int flags, void *args, int tag);
70 68
71static inline int 69static inline int
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 768087bedbac..a6115fe1ac94 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -655,7 +655,6 @@ xfs_ialloc(
655 uint flags; 655 uint flags;
656 int error; 656 int error;
657 timespec_t tv; 657 timespec_t tv;
658 int filestreams = 0;
659 658
660 /* 659 /*
661 * Call the space management code to pick 660 * Call the space management code to pick
@@ -682,6 +681,14 @@ xfs_ialloc(
682 return error; 681 return error;
683 ASSERT(ip != NULL); 682 ASSERT(ip != NULL);
684 683
684 /*
685 * We always convert v1 inodes to v2 now - we only support filesystems
686 * with >= v2 inode capability, so there is no reason for ever leaving
687 * an inode in v1 format.
688 */
689 if (ip->i_d.di_version == 1)
690 ip->i_d.di_version = 2;
691
685 ip->i_d.di_mode = mode; 692 ip->i_d.di_mode = mode;
686 ip->i_d.di_onlink = 0; 693 ip->i_d.di_onlink = 0;
687 ip->i_d.di_nlink = nlink; 694 ip->i_d.di_nlink = nlink;
@@ -691,27 +698,6 @@ xfs_ialloc(
691 xfs_set_projid(ip, prid); 698 xfs_set_projid(ip, prid);
692 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); 699 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
693 700
694 /*
695 * If the superblock version is up to where we support new format
696 * inodes and this is currently an old format inode, then change
697 * the inode version number now. This way we only do the conversion
698 * here rather than here and in the flush/logging code.
699 */
700 if (xfs_sb_version_hasnlink(&mp->m_sb) &&
701 ip->i_d.di_version == 1) {
702 ip->i_d.di_version = 2;
703 /*
704 * We've already zeroed the old link count, the projid field,
705 * and the pad field.
706 */
707 }
708
709 /*
710 * Project ids won't be stored on disk if we are using a version 1 inode.
711 */
712 if ((prid != 0) && (ip->i_d.di_version == 1))
713 xfs_bump_ino_vers2(tp, ip);
714
715 if (pip && XFS_INHERIT_GID(pip)) { 701 if (pip && XFS_INHERIT_GID(pip)) {
716 ip->i_d.di_gid = pip->i_d.di_gid; 702 ip->i_d.di_gid = pip->i_d.di_gid;
717 if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) { 703 if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) {
@@ -772,13 +758,6 @@ xfs_ialloc(
772 flags |= XFS_ILOG_DEV; 758 flags |= XFS_ILOG_DEV;
773 break; 759 break;
774 case S_IFREG: 760 case S_IFREG:
775 /*
776 * we can't set up filestreams until after the VFS inode
777 * is set up properly.
778 */
779 if (pip && xfs_inode_is_filestream(pip))
780 filestreams = 1;
781 /* fall through */
782 case S_IFDIR: 761 case S_IFDIR:
783 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { 762 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
784 uint di_flags = 0; 763 uint di_flags = 0;
@@ -844,15 +823,6 @@ xfs_ialloc(
844 /* now that we have an i_mode we can setup inode ops and unlock */ 823 /* now that we have an i_mode we can setup inode ops and unlock */
845 xfs_setup_inode(ip); 824 xfs_setup_inode(ip);
846 825
847 /* now we have set up the vfs inode we can associate the filestream */
848 if (filestreams) {
849 error = xfs_filestream_associate(pip, ip);
850 if (error < 0)
851 return -error;
852 if (!error)
853 xfs_iflags_set(ip, XFS_IFILESTREAM);
854 }
855
856 *ipp = ip; 826 *ipp = ip;
857 return 0; 827 return 0;
858} 828}
@@ -1073,40 +1043,6 @@ xfs_droplink(
1073} 1043}
1074 1044
1075/* 1045/*
1076 * This gets called when the inode's version needs to be changed from 1 to 2.
1077 * Currently this happens when the nlink field overflows the old 16-bit value
1078 * or when chproj is called to change the project for the first time.
1079 * As a side effect the superblock version will also get rev'd
1080 * to contain the NLINK bit.
1081 */
1082void
1083xfs_bump_ino_vers2(
1084 xfs_trans_t *tp,
1085 xfs_inode_t *ip)
1086{
1087 xfs_mount_t *mp;
1088
1089 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
1090 ASSERT(ip->i_d.di_version == 1);
1091
1092 ip->i_d.di_version = 2;
1093 ip->i_d.di_onlink = 0;
1094 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
1095 mp = tp->t_mountp;
1096 if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
1097 spin_lock(&mp->m_sb_lock);
1098 if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
1099 xfs_sb_version_addnlink(&mp->m_sb);
1100 spin_unlock(&mp->m_sb_lock);
1101 xfs_mod_sb(tp, XFS_SB_VERSIONNUM);
1102 } else {
1103 spin_unlock(&mp->m_sb_lock);
1104 }
1105 }
1106 /* Caller must log the inode */
1107}
1108
1109/*
1110 * Increment the link count on an inode & log the change. 1046 * Increment the link count on an inode & log the change.
1111 */ 1047 */
1112int 1048int
@@ -1116,22 +1052,10 @@ xfs_bumplink(
1116{ 1052{
1117 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); 1053 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1118 1054
1055 ASSERT(ip->i_d.di_version > 1);
1119 ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE)); 1056 ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE));
1120 ip->i_d.di_nlink++; 1057 ip->i_d.di_nlink++;
1121 inc_nlink(VFS_I(ip)); 1058 inc_nlink(VFS_I(ip));
1122 if ((ip->i_d.di_version == 1) &&
1123 (ip->i_d.di_nlink > XFS_MAXLINK_1)) {
1124 /*
1125 * The inode has increased its number of links beyond
1126 * what can fit in an old format inode. It now needs
1127 * to be converted to a version 2 inode with a 32 bit
1128 * link count. If this is the first inode in the file
1129 * system to do this, then we need to bump the superblock
1130 * version number as well.
1131 */
1132 xfs_bump_ino_vers2(tp, ip);
1133 }
1134
1135 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1059 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1136 return 0; 1060 return 0;
1137} 1061}
@@ -1699,16 +1623,6 @@ xfs_release(
1699 int truncated; 1623 int truncated;
1700 1624
1701 /* 1625 /*
1702 * If we are using filestreams, and we have an unlinked
1703 * file that we are processing the last close on, then nothing
1704 * will be able to reopen and write to this file. Purge this
1705 * inode from the filestreams cache so that it doesn't delay
1706 * teardown of the inode.
1707 */
1708 if ((ip->i_d.di_nlink == 0) && xfs_inode_is_filestream(ip))
1709 xfs_filestream_deassociate(ip);
1710
1711 /*
1712 * If we previously truncated this file and removed old data 1626 * If we previously truncated this file and removed old data
1713 * in the process, we want to initiate "early" writeout on 1627 * in the process, we want to initiate "early" writeout on
1714 * the last close. This is an attempt to combat the notorious 1628 * the last close. This is an attempt to combat the notorious
@@ -1838,9 +1752,33 @@ xfs_inactive_ifree(
1838 int error; 1752 int error;
1839 1753
1840 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); 1754 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1841 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ifree, 0, 0); 1755
1756 /*
1757 * The ifree transaction might need to allocate blocks for record
1758 * insertion to the finobt. We don't want to fail here at ENOSPC, so
1759 * allow ifree to dip into the reserved block pool if necessary.
1760 *
1761 * Freeing large sets of inodes generally means freeing inode chunks,
1762 * directory and file data blocks, so this should be relatively safe.
1763 * Only under severe circumstances should it be possible to free enough
1764 * inodes to exhaust the reserve block pool via finobt expansion while
1765 * at the same time not creating free space in the filesystem.
1766 *
1767 * Send a warning if the reservation does happen to fail, as the inode
1768 * now remains allocated and sits on the unlinked list until the fs is
1769 * repaired.
1770 */
1771 tp->t_flags |= XFS_TRANS_RESERVE;
1772 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ifree,
1773 XFS_IFREE_SPACE_RES(mp), 0);
1842 if (error) { 1774 if (error) {
1843 ASSERT(XFS_FORCED_SHUTDOWN(mp)); 1775 if (error == ENOSPC) {
1776 xfs_warn_ratelimited(mp,
1777 "Failed to remove inode(s) from unlinked list. "
1778 "Please free space, unmount and run xfs_repair.");
1779 } else {
1780 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1781 }
1844 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES); 1782 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
1845 return error; 1783 return error;
1846 } 1784 }
@@ -2664,13 +2602,7 @@ xfs_remove(
2664 if (error) 2602 if (error)
2665 goto std_return; 2603 goto std_return;
2666 2604
2667 /* 2605 if (is_dir && xfs_inode_is_filestream(ip))
2668 * If we are using filestreams, kill the stream association.
2669 * If the file is still open it may get a new one but that
2670 * will get killed on last close in xfs_close() so we don't
2671 * have to worry about that.
2672 */
2673 if (!is_dir && link_zero && xfs_inode_is_filestream(ip))
2674 xfs_filestream_deassociate(ip); 2606 xfs_filestream_deassociate(ip);
2675 2607
2676 return 0; 2608 return 0;
@@ -3258,6 +3190,7 @@ xfs_iflush_int(
3258 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 3190 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
3259 ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); 3191 ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK));
3260 ASSERT(iip != NULL && iip->ili_fields != 0); 3192 ASSERT(iip != NULL && iip->ili_fields != 0);
3193 ASSERT(ip->i_d.di_version > 1);
3261 3194
3262 /* set *dip = inode's place in the buffer */ 3195 /* set *dip = inode's place in the buffer */
3263 dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); 3196 dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset);
@@ -3318,7 +3251,7 @@ xfs_iflush_int(
3318 } 3251 }
3319 3252
3320 /* 3253 /*
3321 * Inode item log recovery for v1/v2 inodes are dependent on the 3254 * Inode item log recovery for v2 inodes are dependent on the
3322 * di_flushiter count for correct sequencing. We bump the flush 3255 * di_flushiter count for correct sequencing. We bump the flush
3323 * iteration count so we can detect flushes which postdate a log record 3256 * iteration count so we can detect flushes which postdate a log record
3324 * during recovery. This is redundant as we now log every change and 3257 * during recovery. This is redundant as we now log every change and
@@ -3341,40 +3274,9 @@ xfs_iflush_int(
3341 if (ip->i_d.di_flushiter == DI_MAX_FLUSH) 3274 if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
3342 ip->i_d.di_flushiter = 0; 3275 ip->i_d.di_flushiter = 0;
3343 3276
3344 /* 3277 xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK);
3345 * If this is really an old format inode and the superblock version
3346 * has not been updated to support only new format inodes, then
3347 * convert back to the old inode format. If the superblock version
3348 * has been updated, then make the conversion permanent.
3349 */
3350 ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb));
3351 if (ip->i_d.di_version == 1) {
3352 if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
3353 /*
3354 * Convert it back.
3355 */
3356 ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
3357 dip->di_onlink = cpu_to_be16(ip->i_d.di_nlink);
3358 } else {
3359 /*
3360 * The superblock version has already been bumped,
3361 * so just make the conversion to the new inode
3362 * format permanent.
3363 */
3364 ip->i_d.di_version = 2;
3365 dip->di_version = 2;
3366 ip->i_d.di_onlink = 0;
3367 dip->di_onlink = 0;
3368 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
3369 memset(&(dip->di_pad[0]), 0,
3370 sizeof(dip->di_pad));
3371 ASSERT(xfs_get_projid(ip) == 0);
3372 }
3373 }
3374
3375 xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK, bp);
3376 if (XFS_IFORK_Q(ip)) 3278 if (XFS_IFORK_Q(ip))
3377 xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK, bp); 3279 xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK);
3378 xfs_inobp_check(mp, bp); 3280 xfs_inobp_check(mp, bp);
3379 3281
3380 /* 3282 /*
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index f2fcde52b66d..f72bffa67266 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -209,7 +209,6 @@ xfs_get_initial_prid(struct xfs_inode *dp)
209#define XFS_ISTALE (1 << 1) /* inode has been staled */ 209#define XFS_ISTALE (1 << 1) /* inode has been staled */
210#define XFS_IRECLAIMABLE (1 << 2) /* inode can be reclaimed */ 210#define XFS_IRECLAIMABLE (1 << 2) /* inode can be reclaimed */
211#define XFS_INEW (1 << 3) /* inode has just been allocated */ 211#define XFS_INEW (1 << 3) /* inode has just been allocated */
212#define XFS_IFILESTREAM (1 << 4) /* inode is in a filestream dir. */
213#define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */ 212#define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */
214#define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */ 213#define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */
215#define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */ 214#define __XFS_IFLOCK_BIT 7 /* inode is being flushed right now */
@@ -225,8 +224,7 @@ xfs_get_initial_prid(struct xfs_inode *dp)
225 */ 224 */
226#define XFS_IRECLAIM_RESET_FLAGS \ 225#define XFS_IRECLAIM_RESET_FLAGS \
227 (XFS_IRECLAIMABLE | XFS_IRECLAIM | \ 226 (XFS_IRECLAIMABLE | XFS_IRECLAIM | \
228 XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | \ 227 XFS_IDIRTY_RELEASE | XFS_ITRUNCATED)
229 XFS_IFILESTREAM);
230 228
231/* 229/*
232 * Synchronize processes attempting to flush the in-core inode back to disk. 230 * Synchronize processes attempting to flush the in-core inode back to disk.
@@ -379,7 +377,6 @@ int xfs_dir_ialloc(struct xfs_trans **, struct xfs_inode *, umode_t,
379 struct xfs_inode **, int *); 377 struct xfs_inode **, int *);
380int xfs_droplink(struct xfs_trans *, struct xfs_inode *); 378int xfs_droplink(struct xfs_trans *, struct xfs_inode *);
381int xfs_bumplink(struct xfs_trans *, struct xfs_inode *); 379int xfs_bumplink(struct xfs_trans *, struct xfs_inode *);
382void xfs_bump_ino_vers2(struct xfs_trans *, struct xfs_inode *);
383 380
384/* from xfs_file.c */ 381/* from xfs_file.c */
385int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t); 382int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t);
diff --git a/fs/xfs/xfs_inode_buf.c b/fs/xfs/xfs_inode_buf.c
index 24e993996bdc..cb35ae41d4a1 100644
--- a/fs/xfs/xfs_inode_buf.c
+++ b/fs/xfs/xfs_inode_buf.c
@@ -437,17 +437,16 @@ xfs_iread(
437 } 437 }
438 438
439 /* 439 /*
440 * The inode format changed when we moved the link count and 440 * Automatically convert version 1 inode formats in memory to version 2
441 * made it 32 bits long. If this is an old format inode, 441 * inode format. If the inode is modified, it will get logged and
442 * convert it in memory to look like a new one. If it gets 442 * rewritten as a version 2 inode. We can do this because we set the
443 * flushed to disk we will convert back before flushing or 443 * superblock feature bit for v2 inodes unconditionally during mount
444 * logging it. We zero out the new projid field and the old link 444 * and it means the reast of the code can assume the inode version is 2
445 * count field. We'll handle clearing the pad field (the remains 445 * or higher.
446 * of the old uuid field) when we actually convert the inode to
447 * the new format. We don't change the version number so that we
448 * can distinguish this from a real new format inode.
449 */ 446 */
450 if (ip->i_d.di_version == 1) { 447 if (ip->i_d.di_version == 1) {
448 ip->i_d.di_version = 2;
449 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
451 ip->i_d.di_nlink = ip->i_d.di_onlink; 450 ip->i_d.di_nlink = ip->i_d.di_onlink;
452 ip->i_d.di_onlink = 0; 451 ip->i_d.di_onlink = 0;
453 xfs_set_projid(ip, 0); 452 xfs_set_projid(ip, 0);
diff --git a/fs/xfs/xfs_inode_fork.c b/fs/xfs/xfs_inode_fork.c
index 73514c0486b7..b031e8d0d928 100644
--- a/fs/xfs/xfs_inode_fork.c
+++ b/fs/xfs/xfs_inode_fork.c
@@ -798,8 +798,7 @@ xfs_iflush_fork(
798 xfs_inode_t *ip, 798 xfs_inode_t *ip,
799 xfs_dinode_t *dip, 799 xfs_dinode_t *dip,
800 xfs_inode_log_item_t *iip, 800 xfs_inode_log_item_t *iip,
801 int whichfork, 801 int whichfork)
802 xfs_buf_t *bp)
803{ 802{
804 char *cp; 803 char *cp;
805 xfs_ifork_t *ifp; 804 xfs_ifork_t *ifp;
diff --git a/fs/xfs/xfs_inode_fork.h b/fs/xfs/xfs_inode_fork.h
index eb329a1ea888..7d3b1ed6dcbe 100644
--- a/fs/xfs/xfs_inode_fork.h
+++ b/fs/xfs/xfs_inode_fork.h
@@ -127,8 +127,7 @@ typedef struct xfs_ifork {
127 127
128int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *); 128int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *);
129void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, 129void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *,
130 struct xfs_inode_log_item *, int, 130 struct xfs_inode_log_item *, int);
131 struct xfs_buf *);
132void xfs_idestroy_fork(struct xfs_inode *, int); 131void xfs_idestroy_fork(struct xfs_inode *, int);
133void xfs_idata_realloc(struct xfs_inode *, int, int); 132void xfs_idata_realloc(struct xfs_inode *, int, int);
134void xfs_iroot_realloc(struct xfs_inode *, int, int); 133void xfs_iroot_realloc(struct xfs_inode *, int, int);
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 686889b4a1e5..a640137b3573 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -145,34 +145,6 @@ xfs_inode_item_size(
145 xfs_inode_item_attr_fork_size(iip, nvecs, nbytes); 145 xfs_inode_item_attr_fork_size(iip, nvecs, nbytes);
146} 146}
147 147
148/*
149 * If this is a v1 format inode, then we need to log it as such. This means
150 * that we have to copy the link count from the new field to the old. We
151 * don't have to worry about the new fields, because nothing trusts them as
152 * long as the old inode version number is there.
153 */
154STATIC void
155xfs_inode_item_format_v1_inode(
156 struct xfs_inode *ip)
157{
158 if (!xfs_sb_version_hasnlink(&ip->i_mount->m_sb)) {
159 /*
160 * Convert it back.
161 */
162 ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
163 ip->i_d.di_onlink = ip->i_d.di_nlink;
164 } else {
165 /*
166 * The superblock version has already been bumped,
167 * so just make the conversion to the new inode
168 * format permanent.
169 */
170 ip->i_d.di_version = 2;
171 ip->i_d.di_onlink = 0;
172 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
173 }
174}
175
176STATIC void 148STATIC void
177xfs_inode_item_format_data_fork( 149xfs_inode_item_format_data_fork(
178 struct xfs_inode_log_item *iip, 150 struct xfs_inode_log_item *iip,
@@ -370,6 +342,8 @@ xfs_inode_item_format(
370 struct xfs_inode_log_format *ilf; 342 struct xfs_inode_log_format *ilf;
371 struct xfs_log_iovec *vecp = NULL; 343 struct xfs_log_iovec *vecp = NULL;
372 344
345 ASSERT(ip->i_d.di_version > 1);
346
373 ilf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_IFORMAT); 347 ilf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_IFORMAT);
374 ilf->ilf_type = XFS_LI_INODE; 348 ilf->ilf_type = XFS_LI_INODE;
375 ilf->ilf_ino = ip->i_ino; 349 ilf->ilf_ino = ip->i_ino;
@@ -380,8 +354,6 @@ xfs_inode_item_format(
380 ilf->ilf_size = 2; /* format + core */ 354 ilf->ilf_size = 2; /* format + core */
381 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format)); 355 xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format));
382 356
383 if (ip->i_d.di_version == 1)
384 xfs_inode_item_format_v1_inode(ip);
385 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE, 357 xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICORE,
386 &ip->i_d, 358 &ip->i_d,
387 xfs_icdinode_size(ip->i_d.di_version)); 359 xfs_icdinode_size(ip->i_d.di_version));
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 6152cbe353e8..8bc1bbce7451 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -543,10 +543,11 @@ xfs_attrmulti_by_handle(
543 543
544 ops = memdup_user(am_hreq.ops, size); 544 ops = memdup_user(am_hreq.ops, size);
545 if (IS_ERR(ops)) { 545 if (IS_ERR(ops)) {
546 error = PTR_ERR(ops); 546 error = -PTR_ERR(ops);
547 goto out_dput; 547 goto out_dput;
548 } 548 }
549 549
550 error = ENOMEM;
550 attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); 551 attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
551 if (!attr_name) 552 if (!attr_name)
552 goto out_kfree_ops; 553 goto out_kfree_ops;
@@ -556,7 +557,7 @@ xfs_attrmulti_by_handle(
556 ops[i].am_error = strncpy_from_user((char *)attr_name, 557 ops[i].am_error = strncpy_from_user((char *)attr_name,
557 ops[i].am_attrname, MAXNAMELEN); 558 ops[i].am_attrname, MAXNAMELEN);
558 if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) 559 if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
559 error = -ERANGE; 560 error = ERANGE;
560 if (ops[i].am_error < 0) 561 if (ops[i].am_error < 0)
561 break; 562 break;
562 563
@@ -1227,15 +1228,8 @@ xfs_ioctl_setattr(
1227 olddquot = xfs_qm_vop_chown(tp, ip, 1228 olddquot = xfs_qm_vop_chown(tp, ip,
1228 &ip->i_pdquot, pdqp); 1229 &ip->i_pdquot, pdqp);
1229 } 1230 }
1231 ASSERT(ip->i_d.di_version > 1);
1230 xfs_set_projid(ip, fa->fsx_projid); 1232 xfs_set_projid(ip, fa->fsx_projid);
1231
1232 /*
1233 * We may have to rev the inode as well as
1234 * the superblock version number since projids didn't
1235 * exist before DINODE_VERSION_2 and SB_VERSION_NLINK.
1236 */
1237 if (ip->i_d.di_version == 1)
1238 xfs_bump_ino_vers2(tp, ip);
1239 } 1233 }
1240 1234
1241 } 1235 }
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index a7992f8de9d3..944d5baa710a 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -424,10 +424,11 @@ xfs_compat_attrmulti_by_handle(
424 424
425 ops = memdup_user(compat_ptr(am_hreq.ops), size); 425 ops = memdup_user(compat_ptr(am_hreq.ops), size);
426 if (IS_ERR(ops)) { 426 if (IS_ERR(ops)) {
427 error = PTR_ERR(ops); 427 error = -PTR_ERR(ops);
428 goto out_dput; 428 goto out_dput;
429 } 429 }
430 430
431 error = ENOMEM;
431 attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); 432 attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
432 if (!attr_name) 433 if (!attr_name)
433 goto out_kfree_ops; 434 goto out_kfree_ops;
@@ -438,7 +439,7 @@ xfs_compat_attrmulti_by_handle(
438 compat_ptr(ops[i].am_attrname), 439 compat_ptr(ops[i].am_attrname),
439 MAXNAMELEN); 440 MAXNAMELEN);
440 if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) 441 if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
441 error = -ERANGE; 442 error = ERANGE;
442 if (ops[i].am_error < 0) 443 if (ops[i].am_error < 0)
443 break; 444 break;
444 445
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 3b80ebae05f5..6c5eb4c551e3 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -730,7 +730,7 @@ xfs_iomap_write_allocate(
730 */ 730 */
731 nimaps = 1; 731 nimaps = 1;
732 end_fsb = XFS_B_TO_FSB(mp, XFS_ISIZE(ip)); 732 end_fsb = XFS_B_TO_FSB(mp, XFS_ISIZE(ip));
733 error = xfs_bmap_last_offset(NULL, ip, &last_block, 733 error = xfs_bmap_last_offset(ip, &last_block,
734 XFS_DATA_FORK); 734 XFS_DATA_FORK);
735 if (error) 735 if (error)
736 goto trans_cancel; 736 goto trans_cancel;
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 36d630319a27..205613a06068 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -829,22 +829,34 @@ xfs_setattr_size(
829 */ 829 */
830 inode_dio_wait(inode); 830 inode_dio_wait(inode);
831 831
832 /*
833 * Do all the page cache truncate work outside the transaction context
834 * as the "lock" order is page lock->log space reservation. i.e.
835 * locking pages inside the transaction can ABBA deadlock with
836 * writeback. We have to do the VFS inode size update before we truncate
837 * the pagecache, however, to avoid racing with page faults beyond the
838 * new EOF they are not serialised against truncate operations except by
839 * page locks and size updates.
840 *
841 * Hence we are in a situation where a truncate can fail with ENOMEM
842 * from xfs_trans_reserve(), but having already truncated the in-memory
843 * version of the file (i.e. made user visible changes). There's not
844 * much we can do about this, except to hope that the caller sees ENOMEM
845 * and retries the truncate operation.
846 */
832 error = -block_truncate_page(inode->i_mapping, newsize, xfs_get_blocks); 847 error = -block_truncate_page(inode->i_mapping, newsize, xfs_get_blocks);
833 if (error) 848 if (error)
834 return error; 849 return error;
850 truncate_setsize(inode, newsize);
835 851
836 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); 852 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE);
837 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); 853 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
838 if (error) 854 if (error)
839 goto out_trans_cancel; 855 goto out_trans_cancel;
840 856
841 truncate_setsize(inode, newsize);
842
843 commit_flags = XFS_TRANS_RELEASE_LOG_RES; 857 commit_flags = XFS_TRANS_RELEASE_LOG_RES;
844 lock_flags |= XFS_ILOCK_EXCL; 858 lock_flags |= XFS_ILOCK_EXCL;
845
846 xfs_ilock(ip, XFS_ILOCK_EXCL); 859 xfs_ilock(ip, XFS_ILOCK_EXCL);
847
848 xfs_trans_ijoin(tp, ip, 0); 860 xfs_trans_ijoin(tp, ip, 0);
849 861
850 /* 862 /*
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index f46338285152..cb64f222d607 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -270,7 +270,8 @@ xfs_bulkstat(
270 /* 270 /*
271 * Allocate and initialize a btree cursor for ialloc btree. 271 * Allocate and initialize a btree cursor for ialloc btree.
272 */ 272 */
273 cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno); 273 cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno,
274 XFS_BTNUM_INO);
274 irbp = irbuf; 275 irbp = irbuf;
275 irbufend = irbuf + nirbuf; 276 irbufend = irbuf + nirbuf;
276 end_of_ag = 0; 277 end_of_ag = 0;
@@ -621,7 +622,8 @@ xfs_inumbers(
621 agino = 0; 622 agino = 0;
622 continue; 623 continue;
623 } 624 }
624 cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno); 625 cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno,
626 XFS_BTNUM_INO);
625 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_GE, 627 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_GE,
626 &tmp); 628 &tmp);
627 if (error) { 629 if (error) {
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index a5f8bd9899d3..292308dede6d 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1165,7 +1165,7 @@ xlog_iodone(xfs_buf_t *bp)
1165 /* 1165 /*
1166 * Race to shutdown the filesystem if we see an error. 1166 * Race to shutdown the filesystem if we see an error.
1167 */ 1167 */
1168 if (XFS_TEST_ERROR((xfs_buf_geterror(bp)), l->l_mp, 1168 if (XFS_TEST_ERROR(bp->b_error, l->l_mp,
1169 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { 1169 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
1170 xfs_buf_ioerror_alert(bp, __func__); 1170 xfs_buf_ioerror_alert(bp, __func__);
1171 xfs_buf_stale(bp); 1171 xfs_buf_stale(bp);
@@ -3952,11 +3952,14 @@ xfs_log_force_umount(
3952 retval = xlog_state_ioerror(log); 3952 retval = xlog_state_ioerror(log);
3953 spin_unlock(&log->l_icloglock); 3953 spin_unlock(&log->l_icloglock);
3954 } 3954 }
3955
3955 /* 3956 /*
3956 * Wake up everybody waiting on xfs_log_force. 3957 * Wake up everybody waiting on xfs_log_force. Wake the CIL push first
3957 * Callback all log item committed functions as if the 3958 * as if the log writes were completed. The abort handling in the log
3958 * log writes were completed. 3959 * item committed callback functions will do this again under lock to
3960 * avoid races.
3959 */ 3961 */
3962 wake_up_all(&log->l_cilp->xc_commit_wait);
3960 xlog_state_do_callback(log, XFS_LI_ABORTED, NULL); 3963 xlog_state_do_callback(log, XFS_LI_ABORTED, NULL);
3961 3964
3962#ifdef XFSERRORDEBUG 3965#ifdef XFSERRORDEBUG
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 2c4004475e71..84e0deb95abd 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -24,7 +24,8 @@ struct xfs_log_vec {
24 struct xfs_log_iovec *lv_iovecp; /* iovec array */ 24 struct xfs_log_iovec *lv_iovecp; /* iovec array */
25 struct xfs_log_item *lv_item; /* owner */ 25 struct xfs_log_item *lv_item; /* owner */
26 char *lv_buf; /* formatted buffer */ 26 char *lv_buf; /* formatted buffer */
27 int lv_buf_len; /* size of formatted buffer */ 27 int lv_bytes; /* accounted space in buffer */
28 int lv_buf_len; /* aligned size of buffer */
28 int lv_size; /* size of allocated lv */ 29 int lv_size; /* size of allocated lv */
29}; 30};
30 31
@@ -52,15 +53,21 @@ xlog_prepare_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp,
52 return vec->i_addr; 53 return vec->i_addr;
53} 54}
54 55
56/*
57 * We need to make sure the next buffer is naturally aligned for the biggest
58 * basic data type we put into it. We already accounted for this padding when
59 * sizing the buffer.
60 *
61 * However, this padding does not get written into the log, and hence we have to
62 * track the space used by the log vectors separately to prevent log space hangs
63 * due to inaccurate accounting (i.e. a leak) of the used log space through the
64 * CIL context ticket.
65 */
55static inline void 66static inline void
56xlog_finish_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *vec, int len) 67xlog_finish_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *vec, int len)
57{ 68{
58 /*
59 * We need to make sure the next buffer is naturally aligned for the
60 * biggest basic data type we put into it. We already accounted for
61 * this when sizing the buffer.
62 */
63 lv->lv_buf_len += round_up(len, sizeof(uint64_t)); 69 lv->lv_buf_len += round_up(len, sizeof(uint64_t));
70 lv->lv_bytes += len;
64 vec->i_len = len; 71 vec->i_len = len;
65} 72}
66 73
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index 7e5455391176..b3425b34e3d5 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -97,7 +97,7 @@ xfs_cil_prepare_item(
97{ 97{
98 /* Account for the new LV being passed in */ 98 /* Account for the new LV being passed in */
99 if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED) { 99 if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED) {
100 *diff_len += lv->lv_buf_len; 100 *diff_len += lv->lv_bytes;
101 *diff_iovecs += lv->lv_niovecs; 101 *diff_iovecs += lv->lv_niovecs;
102 } 102 }
103 103
@@ -111,7 +111,7 @@ xfs_cil_prepare_item(
111 else if (old_lv != lv) { 111 else if (old_lv != lv) {
112 ASSERT(lv->lv_buf_len != XFS_LOG_VEC_ORDERED); 112 ASSERT(lv->lv_buf_len != XFS_LOG_VEC_ORDERED);
113 113
114 *diff_len -= old_lv->lv_buf_len; 114 *diff_len -= old_lv->lv_bytes;
115 *diff_iovecs -= old_lv->lv_niovecs; 115 *diff_iovecs -= old_lv->lv_niovecs;
116 kmem_free(old_lv); 116 kmem_free(old_lv);
117 } 117 }
@@ -239,7 +239,7 @@ xlog_cil_insert_format_items(
239 * that the space reservation accounting is correct. 239 * that the space reservation accounting is correct.
240 */ 240 */
241 *diff_iovecs -= lv->lv_niovecs; 241 *diff_iovecs -= lv->lv_niovecs;
242 *diff_len -= lv->lv_buf_len; 242 *diff_len -= lv->lv_bytes;
243 } else { 243 } else {
244 /* allocate new data chunk */ 244 /* allocate new data chunk */
245 lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS); 245 lv = kmem_zalloc(buf_size, KM_SLEEP|KM_NOFS);
@@ -259,6 +259,7 @@ xlog_cil_insert_format_items(
259 259
260 /* The allocated data region lies beyond the iovec region */ 260 /* The allocated data region lies beyond the iovec region */
261 lv->lv_buf_len = 0; 261 lv->lv_buf_len = 0;
262 lv->lv_bytes = 0;
262 lv->lv_buf = (char *)lv + buf_size - nbytes; 263 lv->lv_buf = (char *)lv + buf_size - nbytes;
263 ASSERT(IS_ALIGNED((unsigned long)lv->lv_buf, sizeof(uint64_t))); 264 ASSERT(IS_ALIGNED((unsigned long)lv->lv_buf, sizeof(uint64_t)));
264 265
@@ -385,7 +386,15 @@ xlog_cil_committed(
385 xfs_extent_busy_clear(mp, &ctx->busy_extents, 386 xfs_extent_busy_clear(mp, &ctx->busy_extents,
386 (mp->m_flags & XFS_MOUNT_DISCARD) && !abort); 387 (mp->m_flags & XFS_MOUNT_DISCARD) && !abort);
387 388
389 /*
390 * If we are aborting the commit, wake up anyone waiting on the
391 * committing list. If we don't, then a shutdown we can leave processes
392 * waiting in xlog_cil_force_lsn() waiting on a sequence commit that
393 * will never happen because we aborted it.
394 */
388 spin_lock(&ctx->cil->xc_push_lock); 395 spin_lock(&ctx->cil->xc_push_lock);
396 if (abort)
397 wake_up_all(&ctx->cil->xc_commit_wait);
389 list_del(&ctx->committing); 398 list_del(&ctx->committing);
390 spin_unlock(&ctx->cil->xc_push_lock); 399 spin_unlock(&ctx->cil->xc_push_lock);
391 400
@@ -564,8 +573,18 @@ restart:
564 spin_lock(&cil->xc_push_lock); 573 spin_lock(&cil->xc_push_lock);
565 list_for_each_entry(new_ctx, &cil->xc_committing, committing) { 574 list_for_each_entry(new_ctx, &cil->xc_committing, committing) {
566 /* 575 /*
576 * Avoid getting stuck in this loop because we were woken by the
577 * shutdown, but then went back to sleep once already in the
578 * shutdown state.
579 */
580 if (XLOG_FORCED_SHUTDOWN(log)) {
581 spin_unlock(&cil->xc_push_lock);
582 goto out_abort_free_ticket;
583 }
584
585 /*
567 * Higher sequences will wait for this one so skip them. 586 * Higher sequences will wait for this one so skip them.
568 * Don't wait for own own sequence, either. 587 * Don't wait for our own sequence, either.
569 */ 588 */
570 if (new_ctx->sequence >= ctx->sequence) 589 if (new_ctx->sequence >= ctx->sequence)
571 continue; 590 continue;
@@ -810,6 +829,13 @@ restart:
810 */ 829 */
811 spin_lock(&cil->xc_push_lock); 830 spin_lock(&cil->xc_push_lock);
812 list_for_each_entry(ctx, &cil->xc_committing, committing) { 831 list_for_each_entry(ctx, &cil->xc_committing, committing) {
832 /*
833 * Avoid getting stuck in this loop because we were woken by the
834 * shutdown, but then went back to sleep once already in the
835 * shutdown state.
836 */
837 if (XLOG_FORCED_SHUTDOWN(log))
838 goto out_shutdown;
813 if (ctx->sequence > sequence) 839 if (ctx->sequence > sequence)
814 continue; 840 continue;
815 if (!ctx->commit_lsn) { 841 if (!ctx->commit_lsn) {
@@ -833,14 +859,12 @@ restart:
833 * push sequence after the above wait loop and the CIL still contains 859 * push sequence after the above wait loop and the CIL still contains
834 * dirty objects. 860 * dirty objects.
835 * 861 *
836 * When the push occurs, it will empty the CIL and 862 * When the push occurs, it will empty the CIL and atomically increment
837 * atomically increment the currect sequence past the push sequence and 863 * the currect sequence past the push sequence and move it into the
838 * move it into the committing list. Of course, if the CIL is clean at 864 * committing list. Of course, if the CIL is clean at the time of the
839 * the time of the push, it won't have pushed the CIL at all, so in that 865 * push, it won't have pushed the CIL at all, so in that case we should
840 * case we should try the push for this sequence again from the start 866 * try the push for this sequence again from the start just in case.
841 * just in case.
842 */ 867 */
843
844 if (sequence == cil->xc_current_sequence && 868 if (sequence == cil->xc_current_sequence &&
845 !list_empty(&cil->xc_cil)) { 869 !list_empty(&cil->xc_cil)) {
846 spin_unlock(&cil->xc_push_lock); 870 spin_unlock(&cil->xc_push_lock);
@@ -849,6 +873,17 @@ restart:
849 873
850 spin_unlock(&cil->xc_push_lock); 874 spin_unlock(&cil->xc_push_lock);
851 return commit_lsn; 875 return commit_lsn;
876
877 /*
878 * We detected a shutdown in progress. We need to trigger the log force
879 * to pass through it's iclog state machine error handling, even though
880 * we are already in a shutdown state. Hence we can't return
881 * NULLCOMMITLSN here as that has special meaning to log forces (i.e.
882 * LSN is already stable), so we return a zero LSN instead.
883 */
884out_shutdown:
885 spin_unlock(&cil->xc_push_lock);
886 return 0;
852} 887}
853 888
854/* 889/*
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index bce53ac81096..981af0f6504b 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2138,7 +2138,9 @@ xlog_recover_validate_buf_type(
2138 bp->b_ops = &xfs_allocbt_buf_ops; 2138 bp->b_ops = &xfs_allocbt_buf_ops;
2139 break; 2139 break;
2140 case XFS_IBT_CRC_MAGIC: 2140 case XFS_IBT_CRC_MAGIC:
2141 case XFS_FIBT_CRC_MAGIC:
2141 case XFS_IBT_MAGIC: 2142 case XFS_IBT_MAGIC:
2143 case XFS_FIBT_MAGIC:
2142 bp->b_ops = &xfs_inobt_buf_ops; 2144 bp->b_ops = &xfs_inobt_buf_ops;
2143 break; 2145 break;
2144 case XFS_BMAP_CRC_MAGIC: 2146 case XFS_BMAP_CRC_MAGIC:
@@ -3145,7 +3147,7 @@ xlog_recover_efd_pass2(
3145 } 3147 }
3146 lip = xfs_trans_ail_cursor_next(ailp, &cur); 3148 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3147 } 3149 }
3148 xfs_trans_ail_cursor_done(ailp, &cur); 3150 xfs_trans_ail_cursor_done(&cur);
3149 spin_unlock(&ailp->xa_lock); 3151 spin_unlock(&ailp->xa_lock);
3150 3152
3151 return 0; 3153 return 0;
@@ -3520,8 +3522,7 @@ out:
3520 3522
3521STATIC int 3523STATIC int
3522xlog_recover_unmount_trans( 3524xlog_recover_unmount_trans(
3523 struct xlog *log, 3525 struct xlog *log)
3524 struct xlog_recover *trans)
3525{ 3526{
3526 /* Do nothing now */ 3527 /* Do nothing now */
3527 xfs_warn(log->l_mp, "%s: Unmount LR", __func__); 3528 xfs_warn(log->l_mp, "%s: Unmount LR", __func__);
@@ -3595,7 +3596,7 @@ xlog_recover_process_data(
3595 trans, pass); 3596 trans, pass);
3596 break; 3597 break;
3597 case XLOG_UNMOUNT_TRANS: 3598 case XLOG_UNMOUNT_TRANS:
3598 error = xlog_recover_unmount_trans(log, trans); 3599 error = xlog_recover_unmount_trans(log);
3599 break; 3600 break;
3600 case XLOG_WAS_CONT_TRANS: 3601 case XLOG_WAS_CONT_TRANS:
3601 error = xlog_recover_add_to_cont_trans(log, 3602 error = xlog_recover_add_to_cont_trans(log,
@@ -3757,7 +3758,7 @@ xlog_recover_process_efis(
3757 lip = xfs_trans_ail_cursor_next(ailp, &cur); 3758 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3758 } 3759 }
3759out: 3760out:
3760 xfs_trans_ail_cursor_done(ailp, &cur); 3761 xfs_trans_ail_cursor_done(&cur);
3761 spin_unlock(&ailp->xa_lock); 3762 spin_unlock(&ailp->xa_lock);
3762 return error; 3763 return error;
3763} 3764}
diff --git a/fs/xfs/xfs_log_rlimit.c b/fs/xfs/xfs_log_rlimit.c
index 2af1a0a4d0f1..ee7e0e80246b 100644
--- a/fs/xfs/xfs_log_rlimit.c
+++ b/fs/xfs/xfs_log_rlimit.c
@@ -42,7 +42,7 @@ xfs_log_calc_max_attrsetm_res(
42 int size; 42 int size;
43 int nblks; 43 int nblks;
44 44
45 size = xfs_attr_leaf_entsize_local_max(mp->m_sb.sb_blocksize) - 45 size = xfs_attr_leaf_entsize_local_max(mp->m_attr_geo->blksize) -
46 MAXNAMELEN - 1; 46 MAXNAMELEN - 1;
47 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); 47 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
48 nblks += XFS_B_TO_FSB(mp, size); 48 nblks += XFS_B_TO_FSB(mp, size);
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 944f3d9456a8..3507cd0ec400 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -323,8 +323,19 @@ reread:
323 /* 323 /*
324 * Initialize the mount structure from the superblock. 324 * Initialize the mount structure from the superblock.
325 */ 325 */
326 xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp)); 326 xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
327 xfs_sb_quota_from_disk(&mp->m_sb); 327 xfs_sb_quota_from_disk(sbp);
328
329 /*
330 * If we haven't validated the superblock, do so now before we try
331 * to check the sector size and reread the superblock appropriately.
332 */
333 if (sbp->sb_magicnum != XFS_SB_MAGIC) {
334 if (loud)
335 xfs_warn(mp, "Invalid superblock magic number");
336 error = EINVAL;
337 goto release_buf;
338 }
328 339
329 /* 340 /*
330 * We must be able to do sector-sized and sector-aligned IO. 341 * We must be able to do sector-sized and sector-aligned IO.
@@ -337,11 +348,11 @@ reread:
337 goto release_buf; 348 goto release_buf;
338 } 349 }
339 350
340 /*
341 * Re-read the superblock so the buffer is correctly sized,
342 * and properly verified.
343 */
344 if (buf_ops == NULL) { 351 if (buf_ops == NULL) {
352 /*
353 * Re-read the superblock so the buffer is correctly sized,
354 * and properly verified.
355 */
345 xfs_buf_relse(bp); 356 xfs_buf_relse(bp);
346 sector_size = sbp->sb_sectsize; 357 sector_size = sbp->sb_sectsize;
347 buf_ops = loud ? &xfs_sb_buf_ops : &xfs_sb_quiet_buf_ops; 358 buf_ops = loud ? &xfs_sb_buf_ops : &xfs_sb_quiet_buf_ops;
@@ -697,6 +708,12 @@ xfs_mountfs(
697 mp->m_update_flags |= XFS_SB_VERSIONNUM; 708 mp->m_update_flags |= XFS_SB_VERSIONNUM;
698 } 709 }
699 710
711 /* always use v2 inodes by default now */
712 if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) {
713 mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT;
714 mp->m_update_flags |= XFS_SB_VERSIONNUM;
715 }
716
700 /* 717 /*
701 * Check if sb_agblocks is aligned at stripe boundary 718 * Check if sb_agblocks is aligned at stripe boundary
702 * If sb_agblocks is NOT aligned turn off m_dalign since 719 * If sb_agblocks is NOT aligned turn off m_dalign since
@@ -774,12 +791,11 @@ xfs_mountfs(
774 791
775 mp->m_dmevmask = 0; /* not persistent; set after each mount */ 792 mp->m_dmevmask = 0; /* not persistent; set after each mount */
776 793
777 xfs_dir_mount(mp); 794 error = xfs_da_mount(mp);
778 795 if (error) {
779 /* 796 xfs_warn(mp, "Failed dir/attr init: %d", error);
780 * Initialize the attribute manager's entries. 797 goto out_remove_uuid;
781 */ 798 }
782 mp->m_attr_magicpct = (mp->m_sb.sb_blocksize * 37) / 100;
783 799
784 /* 800 /*
785 * Initialize the precomputed transaction reservations values. 801 * Initialize the precomputed transaction reservations values.
@@ -794,7 +810,7 @@ xfs_mountfs(
794 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); 810 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
795 if (error) { 811 if (error) {
796 xfs_warn(mp, "Failed per-ag init: %d", error); 812 xfs_warn(mp, "Failed per-ag init: %d", error);
797 goto out_remove_uuid; 813 goto out_free_dir;
798 } 814 }
799 815
800 if (!sbp->sb_logblocks) { 816 if (!sbp->sb_logblocks) {
@@ -969,6 +985,8 @@ xfs_mountfs(
969 xfs_wait_buftarg(mp->m_ddev_targp); 985 xfs_wait_buftarg(mp->m_ddev_targp);
970 out_free_perag: 986 out_free_perag:
971 xfs_free_perag(mp); 987 xfs_free_perag(mp);
988 out_free_dir:
989 xfs_da_unmount(mp);
972 out_remove_uuid: 990 out_remove_uuid:
973 xfs_uuid_unmount(mp); 991 xfs_uuid_unmount(mp);
974 out: 992 out:
@@ -1046,6 +1064,7 @@ xfs_unmountfs(
1046 "Freespace may not be correct on next mount."); 1064 "Freespace may not be correct on next mount.");
1047 1065
1048 xfs_log_unmount(mp); 1066 xfs_log_unmount(mp);
1067 xfs_da_unmount(mp);
1049 xfs_uuid_unmount(mp); 1068 xfs_uuid_unmount(mp);
1050 1069
1051#if defined(DEBUG) 1070#if defined(DEBUG)
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index a466c5e5826e..7295a0b7c343 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -27,6 +27,7 @@ struct xfs_nameops;
27struct xfs_ail; 27struct xfs_ail;
28struct xfs_quotainfo; 28struct xfs_quotainfo;
29struct xfs_dir_ops; 29struct xfs_dir_ops;
30struct xfs_da_geometry;
30 31
31#ifdef HAVE_PERCPU_SB 32#ifdef HAVE_PERCPU_SB
32 33
@@ -96,6 +97,8 @@ typedef struct xfs_mount {
96 uint m_readio_blocks; /* min read size blocks */ 97 uint m_readio_blocks; /* min read size blocks */
97 uint m_writeio_log; /* min write size log bytes */ 98 uint m_writeio_log; /* min write size log bytes */
98 uint m_writeio_blocks; /* min write size blocks */ 99 uint m_writeio_blocks; /* min write size blocks */
100 struct xfs_da_geometry *m_dir_geo; /* directory block geometry */
101 struct xfs_da_geometry *m_attr_geo; /* attribute block geometry */
99 struct xlog *m_log; /* log specific stuff */ 102 struct xlog *m_log; /* log specific stuff */
100 int m_logbufs; /* number of log buffers */ 103 int m_logbufs; /* number of log buffers */
101 int m_logbsize; /* size of each log buffer */ 104 int m_logbsize; /* size of each log buffer */
@@ -131,8 +134,6 @@ typedef struct xfs_mount {
131 int m_fixedfsid[2]; /* unchanged for life of FS */ 134 int m_fixedfsid[2]; /* unchanged for life of FS */
132 uint m_dmevmask; /* DMI events for this FS */ 135 uint m_dmevmask; /* DMI events for this FS */
133 __uint64_t m_flags; /* global mount flags */ 136 __uint64_t m_flags; /* global mount flags */
134 uint m_dir_node_ents; /* #entries in a dir danode */
135 uint m_attr_node_ents; /* #entries in attr danode */
136 int m_ialloc_inos; /* inodes in inode allocation */ 137 int m_ialloc_inos; /* inodes in inode allocation */
137 int m_ialloc_blks; /* blocks in inode allocation */ 138 int m_ialloc_blks; /* blocks in inode allocation */
138 int m_inoalign_mask;/* mask sb_inoalignmt if used */ 139 int m_inoalign_mask;/* mask sb_inoalignmt if used */
@@ -145,17 +146,10 @@ typedef struct xfs_mount {
145 int m_dalign; /* stripe unit */ 146 int m_dalign; /* stripe unit */
146 int m_swidth; /* stripe width */ 147 int m_swidth; /* stripe width */
147 int m_sinoalign; /* stripe unit inode alignment */ 148 int m_sinoalign; /* stripe unit inode alignment */
148 int m_attr_magicpct;/* 37% of the blocksize */
149 int m_dir_magicpct; /* 37% of the dir blocksize */
150 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ 149 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
151 const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ 150 const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */
152 const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */ 151 const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */
153 const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode ops */ 152 const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode ops */
154 int m_dirblksize; /* directory block sz--bytes */
155 int m_dirblkfsbs; /* directory block sz--fsbs */
156 xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */
157 xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */
158 xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */
159 uint m_chsize; /* size of next field */ 153 uint m_chsize; /* size of next field */
160 atomic_t m_active_trans; /* number trans frozen */ 154 atomic_t m_active_trans; /* number trans frozen */
161#ifdef HAVE_PERCPU_SB 155#ifdef HAVE_PERCPU_SB
diff --git a/fs/xfs/xfs_mru_cache.c b/fs/xfs/xfs_mru_cache.c
index 4aff56395732..f99b4933dc22 100644
--- a/fs/xfs/xfs_mru_cache.c
+++ b/fs/xfs/xfs_mru_cache.c
@@ -100,14 +100,20 @@
100 * likely result in a loop in one of the lists. That's a sure-fire recipe for 100 * likely result in a loop in one of the lists. That's a sure-fire recipe for
101 * an infinite loop in the code. 101 * an infinite loop in the code.
102 */ 102 */
103typedef struct xfs_mru_cache_elem 103struct xfs_mru_cache {
104{ 104 struct radix_tree_root store; /* Core storage data structure. */
105 struct list_head list_node; 105 struct list_head *lists; /* Array of lists, one per grp. */
106 unsigned long key; 106 struct list_head reap_list; /* Elements overdue for reaping. */
107 void *value; 107 spinlock_t lock; /* Lock to protect this struct. */
108} xfs_mru_cache_elem_t; 108 unsigned int grp_count; /* Number of discrete groups. */
109 unsigned int grp_time; /* Time period spanned by grps. */
110 unsigned int lru_grp; /* Group containing time zero. */
111 unsigned long time_zero; /* Time first element was added. */
112 xfs_mru_cache_free_func_t free_func; /* Function pointer for freeing. */
113 struct delayed_work work; /* Workqueue data for reaping. */
114 unsigned int queued; /* work has been queued */
115};
109 116
110static kmem_zone_t *xfs_mru_elem_zone;
111static struct workqueue_struct *xfs_mru_reap_wq; 117static struct workqueue_struct *xfs_mru_reap_wq;
112 118
113/* 119/*
@@ -129,12 +135,12 @@ static struct workqueue_struct *xfs_mru_reap_wq;
129 */ 135 */
130STATIC unsigned long 136STATIC unsigned long
131_xfs_mru_cache_migrate( 137_xfs_mru_cache_migrate(
132 xfs_mru_cache_t *mru, 138 struct xfs_mru_cache *mru,
133 unsigned long now) 139 unsigned long now)
134{ 140{
135 unsigned int grp; 141 unsigned int grp;
136 unsigned int migrated = 0; 142 unsigned int migrated = 0;
137 struct list_head *lru_list; 143 struct list_head *lru_list;
138 144
139 /* Nothing to do if the data store is empty. */ 145 /* Nothing to do if the data store is empty. */
140 if (!mru->time_zero) 146 if (!mru->time_zero)
@@ -193,11 +199,11 @@ _xfs_mru_cache_migrate(
193 */ 199 */
194STATIC void 200STATIC void
195_xfs_mru_cache_list_insert( 201_xfs_mru_cache_list_insert(
196 xfs_mru_cache_t *mru, 202 struct xfs_mru_cache *mru,
197 xfs_mru_cache_elem_t *elem) 203 struct xfs_mru_cache_elem *elem)
198{ 204{
199 unsigned int grp = 0; 205 unsigned int grp = 0;
200 unsigned long now = jiffies; 206 unsigned long now = jiffies;
201 207
202 /* 208 /*
203 * If the data store is empty, initialise time zero, leave grp set to 209 * If the data store is empty, initialise time zero, leave grp set to
@@ -231,10 +237,10 @@ _xfs_mru_cache_list_insert(
231 */ 237 */
232STATIC void 238STATIC void
233_xfs_mru_cache_clear_reap_list( 239_xfs_mru_cache_clear_reap_list(
234 xfs_mru_cache_t *mru) __releases(mru->lock) __acquires(mru->lock) 240 struct xfs_mru_cache *mru)
235 241 __releases(mru->lock) __acquires(mru->lock)
236{ 242{
237 xfs_mru_cache_elem_t *elem, *next; 243 struct xfs_mru_cache_elem *elem, *next;
238 struct list_head tmp; 244 struct list_head tmp;
239 245
240 INIT_LIST_HEAD(&tmp); 246 INIT_LIST_HEAD(&tmp);
@@ -252,15 +258,8 @@ _xfs_mru_cache_clear_reap_list(
252 spin_unlock(&mru->lock); 258 spin_unlock(&mru->lock);
253 259
254 list_for_each_entry_safe(elem, next, &tmp, list_node) { 260 list_for_each_entry_safe(elem, next, &tmp, list_node) {
255
256 /* Remove the element from the reap list. */
257 list_del_init(&elem->list_node); 261 list_del_init(&elem->list_node);
258 262 mru->free_func(elem);
259 /* Call the client's free function with the key and value pointer. */
260 mru->free_func(elem->key, elem->value);
261
262 /* Free the element structure. */
263 kmem_zone_free(xfs_mru_elem_zone, elem);
264 } 263 }
265 264
266 spin_lock(&mru->lock); 265 spin_lock(&mru->lock);
@@ -277,7 +276,8 @@ STATIC void
277_xfs_mru_cache_reap( 276_xfs_mru_cache_reap(
278 struct work_struct *work) 277 struct work_struct *work)
279{ 278{
280 xfs_mru_cache_t *mru = container_of(work, xfs_mru_cache_t, work.work); 279 struct xfs_mru_cache *mru =
280 container_of(work, struct xfs_mru_cache, work.work);
281 unsigned long now, next; 281 unsigned long now, next;
282 282
283 ASSERT(mru && mru->lists); 283 ASSERT(mru && mru->lists);
@@ -304,28 +304,16 @@ _xfs_mru_cache_reap(
304int 304int
305xfs_mru_cache_init(void) 305xfs_mru_cache_init(void)
306{ 306{
307 xfs_mru_elem_zone = kmem_zone_init(sizeof(xfs_mru_cache_elem_t),
308 "xfs_mru_cache_elem");
309 if (!xfs_mru_elem_zone)
310 goto out;
311
312 xfs_mru_reap_wq = alloc_workqueue("xfs_mru_cache", WQ_MEM_RECLAIM, 1); 307 xfs_mru_reap_wq = alloc_workqueue("xfs_mru_cache", WQ_MEM_RECLAIM, 1);
313 if (!xfs_mru_reap_wq) 308 if (!xfs_mru_reap_wq)
314 goto out_destroy_mru_elem_zone; 309 return -ENOMEM;
315
316 return 0; 310 return 0;
317
318 out_destroy_mru_elem_zone:
319 kmem_zone_destroy(xfs_mru_elem_zone);
320 out:
321 return -ENOMEM;
322} 311}
323 312
324void 313void
325xfs_mru_cache_uninit(void) 314xfs_mru_cache_uninit(void)
326{ 315{
327 destroy_workqueue(xfs_mru_reap_wq); 316 destroy_workqueue(xfs_mru_reap_wq);
328 kmem_zone_destroy(xfs_mru_elem_zone);
329} 317}
330 318
331/* 319/*
@@ -336,14 +324,14 @@ xfs_mru_cache_uninit(void)
336 */ 324 */
337int 325int
338xfs_mru_cache_create( 326xfs_mru_cache_create(
339 xfs_mru_cache_t **mrup, 327 struct xfs_mru_cache **mrup,
340 unsigned int lifetime_ms, 328 unsigned int lifetime_ms,
341 unsigned int grp_count, 329 unsigned int grp_count,
342 xfs_mru_cache_free_func_t free_func) 330 xfs_mru_cache_free_func_t free_func)
343{ 331{
344 xfs_mru_cache_t *mru = NULL; 332 struct xfs_mru_cache *mru = NULL;
345 int err = 0, grp; 333 int err = 0, grp;
346 unsigned int grp_time; 334 unsigned int grp_time;
347 335
348 if (mrup) 336 if (mrup)
349 *mrup = NULL; 337 *mrup = NULL;
@@ -400,7 +388,7 @@ exit:
400 */ 388 */
401static void 389static void
402xfs_mru_cache_flush( 390xfs_mru_cache_flush(
403 xfs_mru_cache_t *mru) 391 struct xfs_mru_cache *mru)
404{ 392{
405 if (!mru || !mru->lists) 393 if (!mru || !mru->lists)
406 return; 394 return;
@@ -420,7 +408,7 @@ xfs_mru_cache_flush(
420 408
421void 409void
422xfs_mru_cache_destroy( 410xfs_mru_cache_destroy(
423 xfs_mru_cache_t *mru) 411 struct xfs_mru_cache *mru)
424{ 412{
425 if (!mru || !mru->lists) 413 if (!mru || !mru->lists)
426 return; 414 return;
@@ -438,38 +426,30 @@ xfs_mru_cache_destroy(
438 */ 426 */
439int 427int
440xfs_mru_cache_insert( 428xfs_mru_cache_insert(
441 xfs_mru_cache_t *mru, 429 struct xfs_mru_cache *mru,
442 unsigned long key, 430 unsigned long key,
443 void *value) 431 struct xfs_mru_cache_elem *elem)
444{ 432{
445 xfs_mru_cache_elem_t *elem; 433 int error;
446 434
447 ASSERT(mru && mru->lists); 435 ASSERT(mru && mru->lists);
448 if (!mru || !mru->lists) 436 if (!mru || !mru->lists)
449 return EINVAL; 437 return EINVAL;
450 438
451 elem = kmem_zone_zalloc(xfs_mru_elem_zone, KM_SLEEP); 439 if (radix_tree_preload(GFP_KERNEL))
452 if (!elem)
453 return ENOMEM; 440 return ENOMEM;
454 441
455 if (radix_tree_preload(GFP_KERNEL)) {
456 kmem_zone_free(xfs_mru_elem_zone, elem);
457 return ENOMEM;
458 }
459
460 INIT_LIST_HEAD(&elem->list_node); 442 INIT_LIST_HEAD(&elem->list_node);
461 elem->key = key; 443 elem->key = key;
462 elem->value = value;
463 444
464 spin_lock(&mru->lock); 445 spin_lock(&mru->lock);
465 446 error = -radix_tree_insert(&mru->store, key, elem);
466 radix_tree_insert(&mru->store, key, elem);
467 radix_tree_preload_end(); 447 radix_tree_preload_end();
468 _xfs_mru_cache_list_insert(mru, elem); 448 if (!error)
469 449 _xfs_mru_cache_list_insert(mru, elem);
470 spin_unlock(&mru->lock); 450 spin_unlock(&mru->lock);
471 451
472 return 0; 452 return error;
473} 453}
474 454
475/* 455/*
@@ -478,13 +458,12 @@ xfs_mru_cache_insert(
478 * the client data pointer for the removed element is returned, otherwise this 458 * the client data pointer for the removed element is returned, otherwise this
479 * function will return a NULL pointer. 459 * function will return a NULL pointer.
480 */ 460 */
481void * 461struct xfs_mru_cache_elem *
482xfs_mru_cache_remove( 462xfs_mru_cache_remove(
483 xfs_mru_cache_t *mru, 463 struct xfs_mru_cache *mru,
484 unsigned long key) 464 unsigned long key)
485{ 465{
486 xfs_mru_cache_elem_t *elem; 466 struct xfs_mru_cache_elem *elem;
487 void *value = NULL;
488 467
489 ASSERT(mru && mru->lists); 468 ASSERT(mru && mru->lists);
490 if (!mru || !mru->lists) 469 if (!mru || !mru->lists)
@@ -492,17 +471,11 @@ xfs_mru_cache_remove(
492 471
493 spin_lock(&mru->lock); 472 spin_lock(&mru->lock);
494 elem = radix_tree_delete(&mru->store, key); 473 elem = radix_tree_delete(&mru->store, key);
495 if (elem) { 474 if (elem)
496 value = elem->value;
497 list_del(&elem->list_node); 475 list_del(&elem->list_node);
498 }
499
500 spin_unlock(&mru->lock); 476 spin_unlock(&mru->lock);
501 477
502 if (elem) 478 return elem;
503 kmem_zone_free(xfs_mru_elem_zone, elem);
504
505 return value;
506} 479}
507 480
508/* 481/*
@@ -511,13 +484,14 @@ xfs_mru_cache_remove(
511 */ 484 */
512void 485void
513xfs_mru_cache_delete( 486xfs_mru_cache_delete(
514 xfs_mru_cache_t *mru, 487 struct xfs_mru_cache *mru,
515 unsigned long key) 488 unsigned long key)
516{ 489{
517 void *value = xfs_mru_cache_remove(mru, key); 490 struct xfs_mru_cache_elem *elem;
518 491
519 if (value) 492 elem = xfs_mru_cache_remove(mru, key);
520 mru->free_func(key, value); 493 if (elem)
494 mru->free_func(elem);
521} 495}
522 496
523/* 497/*
@@ -540,12 +514,12 @@ xfs_mru_cache_delete(
540 * status, we need to help it get it right by annotating the path that does 514 * status, we need to help it get it right by annotating the path that does
541 * not release the lock. 515 * not release the lock.
542 */ 516 */
543void * 517struct xfs_mru_cache_elem *
544xfs_mru_cache_lookup( 518xfs_mru_cache_lookup(
545 xfs_mru_cache_t *mru, 519 struct xfs_mru_cache *mru,
546 unsigned long key) 520 unsigned long key)
547{ 521{
548 xfs_mru_cache_elem_t *elem; 522 struct xfs_mru_cache_elem *elem;
549 523
550 ASSERT(mru && mru->lists); 524 ASSERT(mru && mru->lists);
551 if (!mru || !mru->lists) 525 if (!mru || !mru->lists)
@@ -560,7 +534,7 @@ xfs_mru_cache_lookup(
560 } else 534 } else
561 spin_unlock(&mru->lock); 535 spin_unlock(&mru->lock);
562 536
563 return elem ? elem->value : NULL; 537 return elem;
564} 538}
565 539
566/* 540/*
@@ -570,7 +544,8 @@ xfs_mru_cache_lookup(
570 */ 544 */
571void 545void
572xfs_mru_cache_done( 546xfs_mru_cache_done(
573 xfs_mru_cache_t *mru) __releases(mru->lock) 547 struct xfs_mru_cache *mru)
548 __releases(mru->lock)
574{ 549{
575 spin_unlock(&mru->lock); 550 spin_unlock(&mru->lock);
576} 551}
diff --git a/fs/xfs/xfs_mru_cache.h b/fs/xfs/xfs_mru_cache.h
index 36dd3ec8b4eb..fb5245ba5ff7 100644
--- a/fs/xfs/xfs_mru_cache.h
+++ b/fs/xfs/xfs_mru_cache.h
@@ -18,24 +18,15 @@
18#ifndef __XFS_MRU_CACHE_H__ 18#ifndef __XFS_MRU_CACHE_H__
19#define __XFS_MRU_CACHE_H__ 19#define __XFS_MRU_CACHE_H__
20 20
21struct xfs_mru_cache;
21 22
22/* Function pointer type for callback to free a client's data pointer. */ 23struct xfs_mru_cache_elem {
23typedef void (*xfs_mru_cache_free_func_t)(unsigned long, void*); 24 struct list_head list_node;
25 unsigned long key;
26};
24 27
25typedef struct xfs_mru_cache 28/* Function pointer type for callback to free a client's data pointer. */
26{ 29typedef void (*xfs_mru_cache_free_func_t)(struct xfs_mru_cache_elem *elem);
27 struct radix_tree_root store; /* Core storage data structure. */
28 struct list_head *lists; /* Array of lists, one per grp. */
29 struct list_head reap_list; /* Elements overdue for reaping. */
30 spinlock_t lock; /* Lock to protect this struct. */
31 unsigned int grp_count; /* Number of discrete groups. */
32 unsigned int grp_time; /* Time period spanned by grps. */
33 unsigned int lru_grp; /* Group containing time zero. */
34 unsigned long time_zero; /* Time first element was added. */
35 xfs_mru_cache_free_func_t free_func; /* Function pointer for freeing. */
36 struct delayed_work work; /* Workqueue data for reaping. */
37 unsigned int queued; /* work has been queued */
38} xfs_mru_cache_t;
39 30
40int xfs_mru_cache_init(void); 31int xfs_mru_cache_init(void);
41void xfs_mru_cache_uninit(void); 32void xfs_mru_cache_uninit(void);
@@ -44,10 +35,12 @@ int xfs_mru_cache_create(struct xfs_mru_cache **mrup, unsigned int lifetime_ms,
44 xfs_mru_cache_free_func_t free_func); 35 xfs_mru_cache_free_func_t free_func);
45void xfs_mru_cache_destroy(struct xfs_mru_cache *mru); 36void xfs_mru_cache_destroy(struct xfs_mru_cache *mru);
46int xfs_mru_cache_insert(struct xfs_mru_cache *mru, unsigned long key, 37int xfs_mru_cache_insert(struct xfs_mru_cache *mru, unsigned long key,
47 void *value); 38 struct xfs_mru_cache_elem *elem);
48void * xfs_mru_cache_remove(struct xfs_mru_cache *mru, unsigned long key); 39struct xfs_mru_cache_elem *
40xfs_mru_cache_remove(struct xfs_mru_cache *mru, unsigned long key);
49void xfs_mru_cache_delete(struct xfs_mru_cache *mru, unsigned long key); 41void xfs_mru_cache_delete(struct xfs_mru_cache *mru, unsigned long key);
50void *xfs_mru_cache_lookup(struct xfs_mru_cache *mru, unsigned long key); 42struct xfs_mru_cache_elem *
43xfs_mru_cache_lookup(struct xfs_mru_cache *mru, unsigned long key);
51void xfs_mru_cache_done(struct xfs_mru_cache *mru); 44void xfs_mru_cache_done(struct xfs_mru_cache *mru);
52 45
53#endif /* __XFS_MRU_CACHE_H__ */ 46#endif /* __XFS_MRU_CACHE_H__ */
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index dc977b6e6a36..6d26759c779a 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -193,47 +193,6 @@ xfs_qm_dqpurge(
193} 193}
194 194
195/* 195/*
196 * Release the group or project dquot pointers the user dquots maybe carrying
197 * around as a hint, and proceed to purge the user dquot cache if requested.
198*/
199STATIC int
200xfs_qm_dqpurge_hints(
201 struct xfs_dquot *dqp,
202 void *data)
203{
204 struct xfs_dquot *gdqp = NULL;
205 struct xfs_dquot *pdqp = NULL;
206 uint flags = *((uint *)data);
207
208 xfs_dqlock(dqp);
209 if (dqp->dq_flags & XFS_DQ_FREEING) {
210 xfs_dqunlock(dqp);
211 return EAGAIN;
212 }
213
214 /* If this quota has a hint attached, prepare for releasing it now */
215 gdqp = dqp->q_gdquot;
216 if (gdqp)
217 dqp->q_gdquot = NULL;
218
219 pdqp = dqp->q_pdquot;
220 if (pdqp)
221 dqp->q_pdquot = NULL;
222
223 xfs_dqunlock(dqp);
224
225 if (gdqp)
226 xfs_qm_dqrele(gdqp);
227 if (pdqp)
228 xfs_qm_dqrele(pdqp);
229
230 if (flags & XFS_QMOPT_UQUOTA)
231 return xfs_qm_dqpurge(dqp, NULL);
232
233 return 0;
234}
235
236/*
237 * Purge the dquot cache. 196 * Purge the dquot cache.
238 */ 197 */
239void 198void
@@ -241,18 +200,8 @@ xfs_qm_dqpurge_all(
241 struct xfs_mount *mp, 200 struct xfs_mount *mp,
242 uint flags) 201 uint flags)
243{ 202{
244 /* 203 if (flags & XFS_QMOPT_UQUOTA)
245 * We have to release group/project dquot hint(s) from the user dquot 204 xfs_qm_dquot_walk(mp, XFS_DQ_USER, xfs_qm_dqpurge, NULL);
246 * at first if they are there, otherwise we would run into an infinite
247 * loop while walking through radix tree to purge other type of dquots
248 * since their refcount is not zero if the user dquot refers to them
249 * as hint.
250 *
251 * Call the special xfs_qm_dqpurge_hints() will end up go through the
252 * general xfs_qm_dqpurge() against user dquot cache if requested.
253 */
254 xfs_qm_dquot_walk(mp, XFS_DQ_USER, xfs_qm_dqpurge_hints, &flags);
255
256 if (flags & XFS_QMOPT_GQUOTA) 205 if (flags & XFS_QMOPT_GQUOTA)
257 xfs_qm_dquot_walk(mp, XFS_DQ_GROUP, xfs_qm_dqpurge, NULL); 206 xfs_qm_dquot_walk(mp, XFS_DQ_GROUP, xfs_qm_dqpurge, NULL);
258 if (flags & XFS_QMOPT_PQUOTA) 207 if (flags & XFS_QMOPT_PQUOTA)
@@ -409,7 +358,6 @@ xfs_qm_dqattach_one(
409 xfs_dqid_t id, 358 xfs_dqid_t id,
410 uint type, 359 uint type,
411 uint doalloc, 360 uint doalloc,
412 xfs_dquot_t *udqhint, /* hint */
413 xfs_dquot_t **IO_idqpp) 361 xfs_dquot_t **IO_idqpp)
414{ 362{
415 xfs_dquot_t *dqp; 363 xfs_dquot_t *dqp;
@@ -419,9 +367,9 @@ xfs_qm_dqattach_one(
419 error = 0; 367 error = 0;
420 368
421 /* 369 /*
422 * See if we already have it in the inode itself. IO_idqpp is 370 * See if we already have it in the inode itself. IO_idqpp is &i_udquot
423 * &i_udquot or &i_gdquot. This made the code look weird, but 371 * or &i_gdquot. This made the code look weird, but made the logic a lot
424 * made the logic a lot simpler. 372 * simpler.
425 */ 373 */
426 dqp = *IO_idqpp; 374 dqp = *IO_idqpp;
427 if (dqp) { 375 if (dqp) {
@@ -430,49 +378,10 @@ xfs_qm_dqattach_one(
430 } 378 }
431 379
432 /* 380 /*
433 * udqhint is the i_udquot field in inode, and is non-NULL only 381 * Find the dquot from somewhere. This bumps the reference count of
434 * when the type arg is group/project. Its purpose is to save a 382 * dquot and returns it locked. This can return ENOENT if dquot didn't
435 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside 383 * exist on disk and we didn't ask it to allocate; ESRCH if quotas got
436 * the user dquot. 384 * turned off suddenly.
437 */
438 if (udqhint) {
439 ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
440 xfs_dqlock(udqhint);
441
442 /*
443 * No need to take dqlock to look at the id.
444 *
445 * The ID can't change until it gets reclaimed, and it won't
446 * be reclaimed as long as we have a ref from inode and we
447 * hold the ilock.
448 */
449 if (type == XFS_DQ_GROUP)
450 dqp = udqhint->q_gdquot;
451 else
452 dqp = udqhint->q_pdquot;
453 if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) {
454 ASSERT(*IO_idqpp == NULL);
455
456 *IO_idqpp = xfs_qm_dqhold(dqp);
457 xfs_dqunlock(udqhint);
458 return 0;
459 }
460
461 /*
462 * We can't hold a dquot lock when we call the dqget code.
463 * We'll deadlock in no time, because of (not conforming to)
464 * lock ordering - the inodelock comes before any dquot lock,
465 * and we may drop and reacquire the ilock in xfs_qm_dqget().
466 */
467 xfs_dqunlock(udqhint);
468 }
469
470 /*
471 * Find the dquot from somewhere. This bumps the
472 * reference count of dquot and returns it locked.
473 * This can return ENOENT if dquot didn't exist on
474 * disk and we didn't ask it to allocate;
475 * ESRCH if quotas got turned off suddenly.
476 */ 385 */
477 error = xfs_qm_dqget(ip->i_mount, ip, id, type, 386 error = xfs_qm_dqget(ip->i_mount, ip, id, type,
478 doalloc | XFS_QMOPT_DOWARN, &dqp); 387 doalloc | XFS_QMOPT_DOWARN, &dqp);
@@ -490,48 +399,6 @@ xfs_qm_dqattach_one(
490 return 0; 399 return 0;
491} 400}
492 401
493
494/*
495 * Given a udquot and group/project type, attach the group/project
496 * dquot pointer to the udquot as a hint for future lookups.
497 */
498STATIC void
499xfs_qm_dqattach_hint(
500 struct xfs_inode *ip,
501 int type)
502{
503 struct xfs_dquot **dqhintp;
504 struct xfs_dquot *dqp;
505 struct xfs_dquot *udq = ip->i_udquot;
506
507 ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
508
509 xfs_dqlock(udq);
510
511 if (type == XFS_DQ_GROUP) {
512 dqp = ip->i_gdquot;
513 dqhintp = &udq->q_gdquot;
514 } else {
515 dqp = ip->i_pdquot;
516 dqhintp = &udq->q_pdquot;
517 }
518
519 if (*dqhintp) {
520 struct xfs_dquot *tmp;
521
522 if (*dqhintp == dqp)
523 goto done;
524
525 tmp = *dqhintp;
526 *dqhintp = NULL;
527 xfs_qm_dqrele(tmp);
528 }
529
530 *dqhintp = xfs_qm_dqhold(dqp);
531done:
532 xfs_dqunlock(udq);
533}
534
535static bool 402static bool
536xfs_qm_need_dqattach( 403xfs_qm_need_dqattach(
537 struct xfs_inode *ip) 404 struct xfs_inode *ip)
@@ -562,7 +429,6 @@ xfs_qm_dqattach_locked(
562 uint flags) 429 uint flags)
563{ 430{
564 xfs_mount_t *mp = ip->i_mount; 431 xfs_mount_t *mp = ip->i_mount;
565 uint nquotas = 0;
566 int error = 0; 432 int error = 0;
567 433
568 if (!xfs_qm_need_dqattach(ip)) 434 if (!xfs_qm_need_dqattach(ip))
@@ -570,77 +436,39 @@ xfs_qm_dqattach_locked(
570 436
571 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 437 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
572 438
573 if (XFS_IS_UQUOTA_ON(mp)) { 439 if (XFS_IS_UQUOTA_ON(mp) && !ip->i_udquot) {
574 error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER, 440 error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
575 flags & XFS_QMOPT_DQALLOC, 441 flags & XFS_QMOPT_DQALLOC,
576 NULL, &ip->i_udquot); 442 &ip->i_udquot);
577 if (error) 443 if (error)
578 goto done; 444 goto done;
579 nquotas++; 445 ASSERT(ip->i_udquot);
580 } 446 }
581 447
582 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 448 if (XFS_IS_GQUOTA_ON(mp) && !ip->i_gdquot) {
583 if (XFS_IS_GQUOTA_ON(mp)) {
584 error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, 449 error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
585 flags & XFS_QMOPT_DQALLOC, 450 flags & XFS_QMOPT_DQALLOC,
586 ip->i_udquot, &ip->i_gdquot); 451 &ip->i_gdquot);
587 /*
588 * Don't worry about the udquot that we may have
589 * attached above. It'll get detached, if not already.
590 */
591 if (error) 452 if (error)
592 goto done; 453 goto done;
593 nquotas++; 454 ASSERT(ip->i_gdquot);
594 } 455 }
595 456
596 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 457 if (XFS_IS_PQUOTA_ON(mp) && !ip->i_pdquot) {
597 if (XFS_IS_PQUOTA_ON(mp)) {
598 error = xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ, 458 error = xfs_qm_dqattach_one(ip, xfs_get_projid(ip), XFS_DQ_PROJ,
599 flags & XFS_QMOPT_DQALLOC, 459 flags & XFS_QMOPT_DQALLOC,
600 ip->i_udquot, &ip->i_pdquot); 460 &ip->i_pdquot);
601 /*
602 * Don't worry about the udquot that we may have
603 * attached above. It'll get detached, if not already.
604 */
605 if (error) 461 if (error)
606 goto done; 462 goto done;
607 nquotas++; 463 ASSERT(ip->i_pdquot);
608 } 464 }
609 465
466done:
610 /* 467 /*
611 * Attach this group/project quota to the user quota as a hint. 468 * Don't worry about the dquots that we may have attached before any
612 * This WON'T, in general, result in a thrash. 469 * error - they'll get detached later if it has not already been done.
613 */ 470 */
614 if (nquotas > 1 && ip->i_udquot) {
615 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
616 ASSERT(ip->i_gdquot || !XFS_IS_GQUOTA_ON(mp));
617 ASSERT(ip->i_pdquot || !XFS_IS_PQUOTA_ON(mp));
618
619 /*
620 * We do not have i_udquot locked at this point, but this check
621 * is OK since we don't depend on the i_gdquot to be accurate
622 * 100% all the time. It is just a hint, and this will
623 * succeed in general.
624 */
625 if (ip->i_udquot->q_gdquot != ip->i_gdquot)
626 xfs_qm_dqattach_hint(ip, XFS_DQ_GROUP);
627
628 if (ip->i_udquot->q_pdquot != ip->i_pdquot)
629 xfs_qm_dqattach_hint(ip, XFS_DQ_PROJ);
630 }
631
632 done:
633#ifdef DEBUG
634 if (!error) {
635 if (XFS_IS_UQUOTA_ON(mp))
636 ASSERT(ip->i_udquot);
637 if (XFS_IS_GQUOTA_ON(mp))
638 ASSERT(ip->i_gdquot);
639 if (XFS_IS_PQUOTA_ON(mp))
640 ASSERT(ip->i_pdquot);
641 }
642 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 471 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
643#endif
644 return error; 472 return error;
645} 473}
646 474
@@ -865,8 +693,7 @@ xfs_qm_init_quotainfo(
865 693
866 /* Precalc some constants */ 694 /* Precalc some constants */
867 qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB); 695 qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB);
868 qinf->qi_dqperchunk = xfs_calc_dquots_per_chunk(mp, 696 qinf->qi_dqperchunk = xfs_calc_dquots_per_chunk(qinf->qi_dqchunklen);
869 qinf->qi_dqchunklen);
870 697
871 mp->m_qflags |= (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_CHKD); 698 mp->m_qflags |= (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_CHKD);
872 699
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 3daf5ea1eb8d..bbc813caba4c 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -278,9 +278,10 @@ xfs_qm_scall_trunc_qfiles(
278 xfs_mount_t *mp, 278 xfs_mount_t *mp,
279 uint flags) 279 uint flags)
280{ 280{
281 int error; 281 int error = EINVAL;
282 282
283 if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { 283 if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0 ||
284 (flags & ~XFS_DQ_ALLTYPES)) {
284 xfs_debug(mp, "%s: flags=%x m_qflags=%x", 285 xfs_debug(mp, "%s: flags=%x m_qflags=%x",
285 __func__, flags, mp->m_qflags); 286 __func__, flags, mp->m_qflags);
286 return XFS_ERROR(EINVAL); 287 return XFS_ERROR(EINVAL);
@@ -959,7 +960,6 @@ xfs_qm_export_flags(
959STATIC int 960STATIC int
960xfs_dqrele_inode( 961xfs_dqrele_inode(
961 struct xfs_inode *ip, 962 struct xfs_inode *ip,
962 struct xfs_perag *pag,
963 int flags, 963 int flags,
964 void *args) 964 void *args)
965{ 965{
diff --git a/fs/xfs/xfs_quota_defs.h b/fs/xfs/xfs_quota_defs.h
index b3b2b1065c0f..137e20937077 100644
--- a/fs/xfs/xfs_quota_defs.h
+++ b/fs/xfs/xfs_quota_defs.h
@@ -156,6 +156,6 @@ typedef __uint16_t xfs_qwarncnt_t;
156 156
157extern int xfs_dqcheck(struct xfs_mount *mp, xfs_disk_dquot_t *ddq, 157extern int xfs_dqcheck(struct xfs_mount *mp, xfs_disk_dquot_t *ddq,
158 xfs_dqid_t id, uint type, uint flags, char *str); 158 xfs_dqid_t id, uint type, uint flags, char *str);
159extern int xfs_calc_dquots_per_chunk(struct xfs_mount *mp, unsigned int nbblks); 159extern int xfs_calc_dquots_per_chunk(unsigned int nbblks);
160 160
161#endif /* __XFS_QUOTA_H__ */ 161#endif /* __XFS_QUOTA_H__ */
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index af33cafe69b6..2ad1b9822e92 100644
--- a/fs/xfs/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -100,16 +100,36 @@ xfs_fs_set_xstate(
100 if (!XFS_IS_QUOTA_ON(mp)) 100 if (!XFS_IS_QUOTA_ON(mp))
101 return -EINVAL; 101 return -EINVAL;
102 return -xfs_qm_scall_quotaoff(mp, flags); 102 return -xfs_qm_scall_quotaoff(mp, flags);
103 case Q_XQUOTARM:
104 if (XFS_IS_QUOTA_ON(mp))
105 return -EINVAL;
106 return -xfs_qm_scall_trunc_qfiles(mp, flags);
107 } 103 }
108 104
109 return -EINVAL; 105 return -EINVAL;
110} 106}
111 107
112STATIC int 108STATIC int
109xfs_fs_rm_xquota(
110 struct super_block *sb,
111 unsigned int uflags)
112{
113 struct xfs_mount *mp = XFS_M(sb);
114 unsigned int flags = 0;
115
116 if (sb->s_flags & MS_RDONLY)
117 return -EROFS;
118
119 if (XFS_IS_QUOTA_ON(mp))
120 return -EINVAL;
121
122 if (uflags & FS_USER_QUOTA)
123 flags |= XFS_DQ_USER;
124 if (uflags & FS_GROUP_QUOTA)
125 flags |= XFS_DQ_GROUP;
126 if (uflags & FS_USER_QUOTA)
127 flags |= XFS_DQ_PROJ;
128
129 return -xfs_qm_scall_trunc_qfiles(mp, flags);
130}
131
132STATIC int
113xfs_fs_get_dqblk( 133xfs_fs_get_dqblk(
114 struct super_block *sb, 134 struct super_block *sb,
115 struct kqid qid, 135 struct kqid qid,
@@ -149,6 +169,7 @@ const struct quotactl_ops xfs_quotactl_operations = {
149 .get_xstatev = xfs_fs_get_xstatev, 169 .get_xstatev = xfs_fs_get_xstatev,
150 .get_xstate = xfs_fs_get_xstate, 170 .get_xstate = xfs_fs_get_xstate,
151 .set_xstate = xfs_fs_set_xstate, 171 .set_xstate = xfs_fs_set_xstate,
172 .rm_xquota = xfs_fs_rm_xquota,
152 .get_dqblk = xfs_fs_get_dqblk, 173 .get_dqblk = xfs_fs_get_dqblk,
153 .set_dqblk = xfs_fs_set_dqblk, 174 .set_dqblk = xfs_fs_set_dqblk,
154}; 175};
diff --git a/fs/xfs/xfs_rtbitmap.c b/fs/xfs/xfs_rtbitmap.c
index b1f2fe8af4a8..f4dd697cac08 100644
--- a/fs/xfs/xfs_rtbitmap.c
+++ b/fs/xfs/xfs_rtbitmap.c
@@ -74,7 +74,6 @@ xfs_rtbuf_get(
74 mp->m_bsize, 0, &bp, NULL); 74 mp->m_bsize, 0, &bp, NULL);
75 if (error) 75 if (error)
76 return error; 76 return error;
77 ASSERT(!xfs_buf_geterror(bp));
78 *bpp = bp; 77 *bpp = bp;
79 return 0; 78 return 0;
80} 79}
diff --git a/fs/xfs/xfs_sb.c b/fs/xfs/xfs_sb.c
index 8baf61afae1d..c3453b11f563 100644
--- a/fs/xfs/xfs_sb.c
+++ b/fs/xfs/xfs_sb.c
@@ -291,7 +291,8 @@ xfs_mount_validate_sb(
291 (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */) || 291 (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */) ||
292 sbp->sb_dblocks == 0 || 292 sbp->sb_dblocks == 0 ||
293 sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) || 293 sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) ||
294 sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp))) { 294 sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp) ||
295 sbp->sb_shared_vn != 0)) {
295 xfs_notice(mp, "SB sanity check failed"); 296 xfs_notice(mp, "SB sanity check failed");
296 return XFS_ERROR(EFSCORRUPTED); 297 return XFS_ERROR(EFSCORRUPTED);
297 } 298 }
@@ -333,15 +334,6 @@ xfs_mount_validate_sb(
333 xfs_warn(mp, "Offline file system operation in progress!"); 334 xfs_warn(mp, "Offline file system operation in progress!");
334 return XFS_ERROR(EFSCORRUPTED); 335 return XFS_ERROR(EFSCORRUPTED);
335 } 336 }
336
337 /*
338 * Version 1 directory format has never worked on Linux.
339 */
340 if (unlikely(!xfs_sb_version_hasdirv2(sbp))) {
341 xfs_warn(mp, "file system using version 1 directory format");
342 return XFS_ERROR(ENOSYS);
343 }
344
345 return 0; 337 return 0;
346} 338}
347 339
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index f7b2fe77c5a5..c43c2d609a24 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -36,8 +36,6 @@ struct xfs_trans;
36#define XFS_SB_VERSION_5 5 /* CRC enabled filesystem */ 36#define XFS_SB_VERSION_5 5 /* CRC enabled filesystem */
37#define XFS_SB_VERSION_NUMBITS 0x000f 37#define XFS_SB_VERSION_NUMBITS 0x000f
38#define XFS_SB_VERSION_ALLFBITS 0xfff0 38#define XFS_SB_VERSION_ALLFBITS 0xfff0
39#define XFS_SB_VERSION_SASHFBITS 0xf000
40#define XFS_SB_VERSION_REALFBITS 0x0ff0
41#define XFS_SB_VERSION_ATTRBIT 0x0010 39#define XFS_SB_VERSION_ATTRBIT 0x0010
42#define XFS_SB_VERSION_NLINKBIT 0x0020 40#define XFS_SB_VERSION_NLINKBIT 0x0020
43#define XFS_SB_VERSION_QUOTABIT 0x0040 41#define XFS_SB_VERSION_QUOTABIT 0x0040
@@ -50,24 +48,15 @@ struct xfs_trans;
50#define XFS_SB_VERSION_DIRV2BIT 0x2000 48#define XFS_SB_VERSION_DIRV2BIT 0x2000
51#define XFS_SB_VERSION_BORGBIT 0x4000 /* ASCII only case-insens. */ 49#define XFS_SB_VERSION_BORGBIT 0x4000 /* ASCII only case-insens. */
52#define XFS_SB_VERSION_MOREBITSBIT 0x8000 50#define XFS_SB_VERSION_MOREBITSBIT 0x8000
53#define XFS_SB_VERSION_OKSASHFBITS \ 51
54 (XFS_SB_VERSION_EXTFLGBIT | \ 52/*
55 XFS_SB_VERSION_DIRV2BIT | \ 53 * Supported feature bit list is just all bits in the versionnum field because
56 XFS_SB_VERSION_BORGBIT) 54 * we've used them all up and understand them all. Except, of course, for the
57#define XFS_SB_VERSION_OKREALFBITS \ 55 * shared superblock bit, which nobody knows what it does and so is unsupported.
58 (XFS_SB_VERSION_ATTRBIT | \ 56 */
59 XFS_SB_VERSION_NLINKBIT | \ 57#define XFS_SB_VERSION_OKBITS \
60 XFS_SB_VERSION_QUOTABIT | \ 58 ((XFS_SB_VERSION_NUMBITS | XFS_SB_VERSION_ALLFBITS) & \
61 XFS_SB_VERSION_ALIGNBIT | \ 59 ~XFS_SB_VERSION_SHAREDBIT)
62 XFS_SB_VERSION_DALIGNBIT | \
63 XFS_SB_VERSION_SHAREDBIT | \
64 XFS_SB_VERSION_LOGV2BIT | \
65 XFS_SB_VERSION_SECTORBIT | \
66 XFS_SB_VERSION_MOREBITSBIT)
67#define XFS_SB_VERSION_OKREALBITS \
68 (XFS_SB_VERSION_NUMBITS | \
69 XFS_SB_VERSION_OKREALFBITS | \
70 XFS_SB_VERSION_OKSASHFBITS)
71 60
72/* 61/*
73 * There are two words to hold XFS "feature" bits: the original 62 * There are two words to hold XFS "feature" bits: the original
@@ -76,7 +65,6 @@ struct xfs_trans;
76 * 65 *
77 * These defines represent bits in sb_features2. 66 * These defines represent bits in sb_features2.
78 */ 67 */
79#define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */
80#define XFS_SB_VERSION2_RESERVED1BIT 0x00000001 68#define XFS_SB_VERSION2_RESERVED1BIT 0x00000001
81#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */ 69#define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */
82#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 70#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004
@@ -86,16 +74,11 @@ struct xfs_trans;
86#define XFS_SB_VERSION2_CRCBIT 0x00000100 /* metadata CRCs */ 74#define XFS_SB_VERSION2_CRCBIT 0x00000100 /* metadata CRCs */
87#define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */ 75#define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */
88 76
89#define XFS_SB_VERSION2_OKREALFBITS \ 77#define XFS_SB_VERSION2_OKBITS \
90 (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ 78 (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
91 XFS_SB_VERSION2_ATTR2BIT | \ 79 XFS_SB_VERSION2_ATTR2BIT | \
92 XFS_SB_VERSION2_PROJID32BIT | \ 80 XFS_SB_VERSION2_PROJID32BIT | \
93 XFS_SB_VERSION2_FTYPE) 81 XFS_SB_VERSION2_FTYPE)
94#define XFS_SB_VERSION2_OKSASHFBITS \
95 (0)
96#define XFS_SB_VERSION2_OKREALBITS \
97 (XFS_SB_VERSION2_OKREALFBITS | \
98 XFS_SB_VERSION2_OKSASHFBITS )
99 82
100/* 83/*
101 * Superblock - in core version. Must match the ondisk version below. 84 * Superblock - in core version. Must match the ondisk version below.
@@ -345,214 +328,140 @@ typedef enum {
345 328
346#define XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS) 329#define XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
347 330
348static inline int xfs_sb_good_version(xfs_sb_t *sbp)
349{
350 /* We always support version 1-3 */
351 if (sbp->sb_versionnum >= XFS_SB_VERSION_1 &&
352 sbp->sb_versionnum <= XFS_SB_VERSION_3)
353 return 1;
354
355 /* We support version 4 if all feature bits are supported */
356 if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) {
357 if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKREALBITS) ||
358 ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
359 (sbp->sb_features2 & ~XFS_SB_VERSION2_OKREALBITS)))
360 return 0;
361
362 if (sbp->sb_shared_vn > XFS_SB_MAX_SHARED_VN)
363 return 0;
364 return 1;
365 }
366 if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
367 return 1;
368
369 return 0;
370}
371
372/* 331/*
373 * Detect a mismatched features2 field. Older kernels read/wrote 332 * The first XFS version we support is a v4 superblock with V2 directories.
374 * this into the wrong slot, so to be safe we keep them in sync.
375 */ 333 */
376static inline int xfs_sb_has_mismatched_features2(xfs_sb_t *sbp) 334static inline bool xfs_sb_good_v4_features(struct xfs_sb *sbp)
377{ 335{
378 return (sbp->sb_bad_features2 != sbp->sb_features2); 336 if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
379} 337 return false;
380
381static inline unsigned xfs_sb_version_tonew(unsigned v)
382{
383 if (v == XFS_SB_VERSION_1)
384 return XFS_SB_VERSION_4;
385 338
386 if (v == XFS_SB_VERSION_2) 339 /* check for unknown features in the fs */
387 return XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT; 340 if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
341 ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
342 (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
343 return false;
388 344
389 return XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT | 345 return true;
390 XFS_SB_VERSION_NLINKBIT;
391} 346}
392 347
393static inline unsigned xfs_sb_version_toold(unsigned v) 348static inline bool xfs_sb_good_version(struct xfs_sb *sbp)
394{ 349{
395 if (v & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT)) 350 if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5)
396 return 0; 351 return true;
397 if (v & XFS_SB_VERSION_NLINKBIT) 352 if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4)
398 return XFS_SB_VERSION_3; 353 return xfs_sb_good_v4_features(sbp);
399 if (v & XFS_SB_VERSION_ATTRBIT) 354 return false;
400 return XFS_SB_VERSION_2;
401 return XFS_SB_VERSION_1;
402}
403
404static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp)
405{
406 return sbp->sb_versionnum == XFS_SB_VERSION_2 ||
407 sbp->sb_versionnum == XFS_SB_VERSION_3 ||
408 (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 &&
409 (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT));
410} 355}
411 356
412static inline void xfs_sb_version_addattr(xfs_sb_t *sbp) 357/*
358 * Detect a mismatched features2 field. Older kernels read/wrote
359 * this into the wrong slot, so to be safe we keep them in sync.
360 */
361static inline bool xfs_sb_has_mismatched_features2(struct xfs_sb *sbp)
413{ 362{
414 if (sbp->sb_versionnum == XFS_SB_VERSION_1) 363 return sbp->sb_bad_features2 != sbp->sb_features2;
415 sbp->sb_versionnum = XFS_SB_VERSION_2;
416 else if (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4)
417 sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
418 else
419 sbp->sb_versionnum = XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT;
420} 364}
421 365
422static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp) 366static inline bool xfs_sb_version_hasattr(struct xfs_sb *sbp)
423{ 367{
424 return sbp->sb_versionnum == XFS_SB_VERSION_3 || 368 return (sbp->sb_versionnum & XFS_SB_VERSION_ATTRBIT);
425 (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 &&
426 (sbp->sb_versionnum & XFS_SB_VERSION_NLINKBIT));
427} 369}
428 370
429static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp) 371static inline void xfs_sb_version_addattr(struct xfs_sb *sbp)
430{ 372{
431 if (sbp->sb_versionnum <= XFS_SB_VERSION_2) 373 sbp->sb_versionnum |= XFS_SB_VERSION_ATTRBIT;
432 sbp->sb_versionnum = XFS_SB_VERSION_3;
433 else
434 sbp->sb_versionnum |= XFS_SB_VERSION_NLINKBIT;
435} 374}
436 375
437static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp) 376static inline bool xfs_sb_version_hasquota(struct xfs_sb *sbp)
438{ 377{
439 return XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && 378 return (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT);
440 (sbp->sb_versionnum & XFS_SB_VERSION_QUOTABIT);
441} 379}
442 380
443static inline void xfs_sb_version_addquota(xfs_sb_t *sbp) 381static inline void xfs_sb_version_addquota(struct xfs_sb *sbp)
444{ 382{
445 if (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4) 383 sbp->sb_versionnum |= XFS_SB_VERSION_QUOTABIT;
446 sbp->sb_versionnum |= XFS_SB_VERSION_QUOTABIT;
447 else
448 sbp->sb_versionnum = xfs_sb_version_tonew(sbp->sb_versionnum) |
449 XFS_SB_VERSION_QUOTABIT;
450} 384}
451 385
452static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp) 386static inline bool xfs_sb_version_hasalign(struct xfs_sb *sbp)
453{ 387{
454 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || 388 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
455 (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 &&
456 (sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT)); 389 (sbp->sb_versionnum & XFS_SB_VERSION_ALIGNBIT));
457} 390}
458 391
459static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp) 392static inline bool xfs_sb_version_hasdalign(struct xfs_sb *sbp)
460{
461 return XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 &&
462 (sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT);
463}
464
465static inline int xfs_sb_version_hasshared(xfs_sb_t *sbp)
466{ 393{
467 return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && 394 return (sbp->sb_versionnum & XFS_SB_VERSION_DALIGNBIT);
468 (sbp->sb_versionnum & XFS_SB_VERSION_SHAREDBIT);
469} 395}
470 396
471static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp) 397static inline bool xfs_sb_version_haslogv2(struct xfs_sb *sbp)
472{ 398{
473 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || 399 return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
474 (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 && 400 (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT);
475 (sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT));
476} 401}
477 402
478static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp) 403static inline bool xfs_sb_version_hasextflgbit(struct xfs_sb *sbp)
479{ 404{
480 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || 405 return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
481 (XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && 406 (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT);
482 (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT));
483} 407}
484 408
485static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp) 409static inline bool xfs_sb_version_hassector(struct xfs_sb *sbp)
486{ 410{
487 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || 411 return (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT);
488 (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
489 (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT));
490} 412}
491 413
492static inline int xfs_sb_version_hassector(xfs_sb_t *sbp) 414static inline bool xfs_sb_version_hasasciici(struct xfs_sb *sbp)
493{ 415{
494 return XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && 416 return (sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT);
495 (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT);
496} 417}
497 418
498static inline int xfs_sb_version_hasasciici(xfs_sb_t *sbp) 419static inline bool xfs_sb_version_hasmorebits(struct xfs_sb *sbp)
499{ 420{
500 return XFS_SB_VERSION_NUM(sbp) >= XFS_SB_VERSION_4 && 421 return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
501 (sbp->sb_versionnum & XFS_SB_VERSION_BORGBIT); 422 (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT);
502}
503
504static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp)
505{
506 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) ||
507 (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 &&
508 (sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT));
509} 423}
510 424
511/* 425/*
512 * sb_features2 bit version macros. 426 * sb_features2 bit version macros.
513 *
514 * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro:
515 *
516 * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp)
517 * ((xfs_sb_version_hasmorebits(sbp) &&
518 * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT)
519 */ 427 */
520 428static inline bool xfs_sb_version_haslazysbcount(struct xfs_sb *sbp)
521static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp)
522{ 429{
523 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || 430 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) ||
524 (xfs_sb_version_hasmorebits(sbp) && 431 (xfs_sb_version_hasmorebits(sbp) &&
525 (sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT)); 432 (sbp->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT));
526} 433}
527 434
528static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp) 435static inline bool xfs_sb_version_hasattr2(struct xfs_sb *sbp)
529{ 436{
530 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || 437 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) ||
531 (xfs_sb_version_hasmorebits(sbp) && 438 (xfs_sb_version_hasmorebits(sbp) &&
532 (sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT)); 439 (sbp->sb_features2 & XFS_SB_VERSION2_ATTR2BIT));
533} 440}
534 441
535static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) 442static inline void xfs_sb_version_addattr2(struct xfs_sb *sbp)
536{ 443{
537 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT; 444 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
538 sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT; 445 sbp->sb_features2 |= XFS_SB_VERSION2_ATTR2BIT;
446 sbp->sb_bad_features2 |= XFS_SB_VERSION2_ATTR2BIT;
539} 447}
540 448
541static inline void xfs_sb_version_removeattr2(xfs_sb_t *sbp) 449static inline void xfs_sb_version_removeattr2(struct xfs_sb *sbp)
542{ 450{
543 sbp->sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT; 451 sbp->sb_features2 &= ~XFS_SB_VERSION2_ATTR2BIT;
452 sbp->sb_bad_features2 &= ~XFS_SB_VERSION2_ATTR2BIT;
544 if (!sbp->sb_features2) 453 if (!sbp->sb_features2)
545 sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT; 454 sbp->sb_versionnum &= ~XFS_SB_VERSION_MOREBITSBIT;
546} 455}
547 456
548static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp) 457static inline bool xfs_sb_version_hasprojid32bit(struct xfs_sb *sbp)
549{ 458{
550 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) || 459 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) ||
551 (xfs_sb_version_hasmorebits(sbp) && 460 (xfs_sb_version_hasmorebits(sbp) &&
552 (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT)); 461 (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT));
553} 462}
554 463
555static inline void xfs_sb_version_addprojid32bit(xfs_sb_t *sbp) 464static inline void xfs_sb_version_addprojid32bit(struct xfs_sb *sbp)
556{ 465{
557 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT; 466 sbp->sb_versionnum |= XFS_SB_VERSION_MOREBITSBIT;
558 sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT; 467 sbp->sb_features2 |= XFS_SB_VERSION2_PROJID32BIT;
@@ -587,7 +496,9 @@ xfs_sb_has_compat_feature(
587 return (sbp->sb_features_compat & feature) != 0; 496 return (sbp->sb_features_compat & feature) != 0;
588} 497}
589 498
590#define XFS_SB_FEAT_RO_COMPAT_ALL 0 499#define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */
500#define XFS_SB_FEAT_RO_COMPAT_ALL \
501 (XFS_SB_FEAT_RO_COMPAT_FINOBT)
591#define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL 502#define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL
592static inline bool 503static inline bool
593xfs_sb_has_ro_compat_feature( 504xfs_sb_has_ro_compat_feature(
@@ -623,12 +534,12 @@ xfs_sb_has_incompat_log_feature(
623/* 534/*
624 * V5 superblock specific feature checks 535 * V5 superblock specific feature checks
625 */ 536 */
626static inline int xfs_sb_version_hascrc(xfs_sb_t *sbp) 537static inline int xfs_sb_version_hascrc(struct xfs_sb *sbp)
627{ 538{
628 return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5; 539 return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
629} 540}
630 541
631static inline int xfs_sb_version_has_pquotino(xfs_sb_t *sbp) 542static inline int xfs_sb_version_has_pquotino(struct xfs_sb *sbp)
632{ 543{
633 return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5; 544 return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5;
634} 545}
@@ -641,6 +552,12 @@ static inline int xfs_sb_version_hasftype(struct xfs_sb *sbp)
641 (sbp->sb_features2 & XFS_SB_VERSION2_FTYPE)); 552 (sbp->sb_features2 & XFS_SB_VERSION2_FTYPE));
642} 553}
643 554
555static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp)
556{
557 return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) &&
558 (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT);
559}
560
644/* 561/*
645 * end of superblock version macros 562 * end of superblock version macros
646 */ 563 */
diff --git a/fs/xfs/xfs_shared.h b/fs/xfs/xfs_shared.h
index 4484e5151395..82404da2ca67 100644
--- a/fs/xfs/xfs_shared.h
+++ b/fs/xfs/xfs_shared.h
@@ -238,7 +238,7 @@ int xfs_log_calc_minimum_size(struct xfs_mount *);
238int xfs_symlink_blocks(struct xfs_mount *mp, int pathlen); 238int xfs_symlink_blocks(struct xfs_mount *mp, int pathlen);
239int xfs_symlink_hdr_set(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset, 239int xfs_symlink_hdr_set(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset,
240 uint32_t size, struct xfs_buf *bp); 240 uint32_t size, struct xfs_buf *bp);
241bool xfs_symlink_hdr_ok(struct xfs_mount *mp, xfs_ino_t ino, uint32_t offset, 241bool xfs_symlink_hdr_ok(xfs_ino_t ino, uint32_t offset,
242 uint32_t size, struct xfs_buf *bp); 242 uint32_t size, struct xfs_buf *bp);
243void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp, 243void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
244 struct xfs_inode *ip, struct xfs_ifork *ifp); 244 struct xfs_inode *ip, struct xfs_ifork *ifp);
diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c
index ce372b7d5644..f2240383d4bb 100644
--- a/fs/xfs/xfs_stats.c
+++ b/fs/xfs/xfs_stats.c
@@ -59,6 +59,7 @@ static int xfs_stat_proc_show(struct seq_file *m, void *v)
59 { "abtc2", XFSSTAT_END_ABTC_V2 }, 59 { "abtc2", XFSSTAT_END_ABTC_V2 },
60 { "bmbt2", XFSSTAT_END_BMBT_V2 }, 60 { "bmbt2", XFSSTAT_END_BMBT_V2 },
61 { "ibt2", XFSSTAT_END_IBT_V2 }, 61 { "ibt2", XFSSTAT_END_IBT_V2 },
62 { "fibt2", XFSSTAT_END_FIBT_V2 },
62 /* we print both series of quota information together */ 63 /* we print both series of quota information together */
63 { "qm", XFSSTAT_END_QM }, 64 { "qm", XFSSTAT_END_QM },
64 }; 65 };
diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h
index c03ad38ceaeb..c8f238b8299a 100644
--- a/fs/xfs/xfs_stats.h
+++ b/fs/xfs/xfs_stats.h
@@ -183,7 +183,23 @@ struct xfsstats {
183 __uint32_t xs_ibt_2_alloc; 183 __uint32_t xs_ibt_2_alloc;
184 __uint32_t xs_ibt_2_free; 184 __uint32_t xs_ibt_2_free;
185 __uint32_t xs_ibt_2_moves; 185 __uint32_t xs_ibt_2_moves;
186#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_IBT_V2+6) 186#define XFSSTAT_END_FIBT_V2 (XFSSTAT_END_IBT_V2+15)
187 __uint32_t xs_fibt_2_lookup;
188 __uint32_t xs_fibt_2_compare;
189 __uint32_t xs_fibt_2_insrec;
190 __uint32_t xs_fibt_2_delrec;
191 __uint32_t xs_fibt_2_newroot;
192 __uint32_t xs_fibt_2_killroot;
193 __uint32_t xs_fibt_2_increment;
194 __uint32_t xs_fibt_2_decrement;
195 __uint32_t xs_fibt_2_lshift;
196 __uint32_t xs_fibt_2_rshift;
197 __uint32_t xs_fibt_2_split;
198 __uint32_t xs_fibt_2_join;
199 __uint32_t xs_fibt_2_alloc;
200 __uint32_t xs_fibt_2_free;
201 __uint32_t xs_fibt_2_moves;
202#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_FIBT_V2+6)
187 __uint32_t xs_qm_dqreclaims; 203 __uint32_t xs_qm_dqreclaims;
188 __uint32_t xs_qm_dqreclaim_misses; 204 __uint32_t xs_qm_dqreclaim_misses;
189 __uint32_t xs_qm_dquot_dups; 205 __uint32_t xs_qm_dquot_dups;
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 3494eff8e4eb..8f0333b3f7a0 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -765,20 +765,18 @@ xfs_open_devices(
765 * Setup xfs_mount buffer target pointers 765 * Setup xfs_mount buffer target pointers
766 */ 766 */
767 error = ENOMEM; 767 error = ENOMEM;
768 mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, 0, mp->m_fsname); 768 mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev);
769 if (!mp->m_ddev_targp) 769 if (!mp->m_ddev_targp)
770 goto out_close_rtdev; 770 goto out_close_rtdev;
771 771
772 if (rtdev) { 772 if (rtdev) {
773 mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, 1, 773 mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev);
774 mp->m_fsname);
775 if (!mp->m_rtdev_targp) 774 if (!mp->m_rtdev_targp)
776 goto out_free_ddev_targ; 775 goto out_free_ddev_targ;
777 } 776 }
778 777
779 if (logdev && logdev != ddev) { 778 if (logdev && logdev != ddev) {
780 mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, 1, 779 mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev);
781 mp->m_fsname);
782 if (!mp->m_logdev_targp) 780 if (!mp->m_logdev_targp)
783 goto out_free_rtdev_targ; 781 goto out_free_rtdev_targ;
784 } else { 782 } else {
@@ -811,8 +809,7 @@ xfs_setup_devices(
811{ 809{
812 int error; 810 int error;
813 811
814 error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, 812 error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_sectsize);
815 mp->m_sb.sb_sectsize);
816 if (error) 813 if (error)
817 return error; 814 return error;
818 815
@@ -822,14 +819,12 @@ xfs_setup_devices(
822 if (xfs_sb_version_hassector(&mp->m_sb)) 819 if (xfs_sb_version_hassector(&mp->m_sb))
823 log_sector_size = mp->m_sb.sb_logsectsize; 820 log_sector_size = mp->m_sb.sb_logsectsize;
824 error = xfs_setsize_buftarg(mp->m_logdev_targp, 821 error = xfs_setsize_buftarg(mp->m_logdev_targp,
825 mp->m_sb.sb_blocksize,
826 log_sector_size); 822 log_sector_size);
827 if (error) 823 if (error)
828 return error; 824 return error;
829 } 825 }
830 if (mp->m_rtdev_targp) { 826 if (mp->m_rtdev_targp) {
831 error = xfs_setsize_buftarg(mp->m_rtdev_targp, 827 error = xfs_setsize_buftarg(mp->m_rtdev_targp,
832 mp->m_sb.sb_blocksize,
833 mp->m_sb.sb_sectsize); 828 mp->m_sb.sb_sectsize);
834 if (error) 829 if (error)
835 return error; 830 return error;
@@ -1754,13 +1749,9 @@ init_xfs_fs(void)
1754 if (error) 1749 if (error)
1755 goto out_destroy_wq; 1750 goto out_destroy_wq;
1756 1751
1757 error = xfs_filestream_init();
1758 if (error)
1759 goto out_mru_cache_uninit;
1760
1761 error = xfs_buf_init(); 1752 error = xfs_buf_init();
1762 if (error) 1753 if (error)
1763 goto out_filestream_uninit; 1754 goto out_mru_cache_uninit;
1764 1755
1765 error = xfs_init_procfs(); 1756 error = xfs_init_procfs();
1766 if (error) 1757 if (error)
@@ -1787,8 +1778,6 @@ init_xfs_fs(void)
1787 xfs_cleanup_procfs(); 1778 xfs_cleanup_procfs();
1788 out_buf_terminate: 1779 out_buf_terminate:
1789 xfs_buf_terminate(); 1780 xfs_buf_terminate();
1790 out_filestream_uninit:
1791 xfs_filestream_uninit();
1792 out_mru_cache_uninit: 1781 out_mru_cache_uninit:
1793 xfs_mru_cache_uninit(); 1782 xfs_mru_cache_uninit();
1794 out_destroy_wq: 1783 out_destroy_wq:
@@ -1807,7 +1796,6 @@ exit_xfs_fs(void)
1807 xfs_sysctl_unregister(); 1796 xfs_sysctl_unregister();
1808 xfs_cleanup_procfs(); 1797 xfs_cleanup_procfs();
1809 xfs_buf_terminate(); 1798 xfs_buf_terminate();
1810 xfs_filestream_uninit();
1811 xfs_mru_cache_uninit(); 1799 xfs_mru_cache_uninit();
1812 xfs_destroy_workqueues(); 1800 xfs_destroy_workqueues();
1813 xfs_destroy_zones(); 1801 xfs_destroy_zones();
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index 52979aa90986..d69363c833e1 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -27,6 +27,7 @@
27#include "xfs_ag.h" 27#include "xfs_ag.h"
28#include "xfs_mount.h" 28#include "xfs_mount.h"
29#include "xfs_da_format.h" 29#include "xfs_da_format.h"
30#include "xfs_da_btree.h"
30#include "xfs_dir2.h" 31#include "xfs_dir2.h"
31#include "xfs_inode.h" 32#include "xfs_inode.h"
32#include "xfs_ialloc.h" 33#include "xfs_ialloc.h"
@@ -92,7 +93,7 @@ xfs_readlink_bmap(
92 93
93 cur_chunk = bp->b_addr; 94 cur_chunk = bp->b_addr;
94 if (xfs_sb_version_hascrc(&mp->m_sb)) { 95 if (xfs_sb_version_hascrc(&mp->m_sb)) {
95 if (!xfs_symlink_hdr_ok(mp, ip->i_ino, offset, 96 if (!xfs_symlink_hdr_ok(ip->i_ino, offset,
96 byte_cnt, bp)) { 97 byte_cnt, bp)) {
97 error = EFSCORRUPTED; 98 error = EFSCORRUPTED;
98 xfs_alert(mp, 99 xfs_alert(mp,
diff --git a/fs/xfs/xfs_symlink_remote.c b/fs/xfs/xfs_symlink_remote.c
index 9b32052ff65e..23c2f2577c8d 100644
--- a/fs/xfs/xfs_symlink_remote.c
+++ b/fs/xfs/xfs_symlink_remote.c
@@ -80,7 +80,6 @@ xfs_symlink_hdr_set(
80 */ 80 */
81bool 81bool
82xfs_symlink_hdr_ok( 82xfs_symlink_hdr_ok(
83 struct xfs_mount *mp,
84 xfs_ino_t ino, 83 xfs_ino_t ino,
85 uint32_t offset, 84 uint32_t offset,
86 uint32_t size, 85 uint32_t size,
diff --git a/fs/xfs/xfs_trace.c b/fs/xfs/xfs_trace.c
index dee3279c095e..1e85bcd0e418 100644
--- a/fs/xfs/xfs_trace.c
+++ b/fs/xfs/xfs_trace.c
@@ -46,6 +46,7 @@
46#include "xfs_log_recover.h" 46#include "xfs_log_recover.h"
47#include "xfs_inode_item.h" 47#include "xfs_inode_item.h"
48#include "xfs_bmap_btree.h" 48#include "xfs_bmap_btree.h"
49#include "xfs_filestream.h"
49 50
50/* 51/*
51 * We include this last to have the helpers above available for the trace 52 * We include this last to have the helpers above available for the trace
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 65d8c793a25c..6910458915cf 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -538,6 +538,64 @@ DEFINE_BUF_ITEM_EVENT(xfs_trans_bhold_release);
538DEFINE_BUF_ITEM_EVENT(xfs_trans_binval); 538DEFINE_BUF_ITEM_EVENT(xfs_trans_binval);
539DEFINE_BUF_ITEM_EVENT(xfs_trans_buf_ordered); 539DEFINE_BUF_ITEM_EVENT(xfs_trans_buf_ordered);
540 540
541DECLARE_EVENT_CLASS(xfs_filestream_class,
542 TP_PROTO(struct xfs_inode *ip, xfs_agnumber_t agno),
543 TP_ARGS(ip, agno),
544 TP_STRUCT__entry(
545 __field(dev_t, dev)
546 __field(xfs_ino_t, ino)
547 __field(xfs_agnumber_t, agno)
548 __field(int, streams)
549 ),
550 TP_fast_assign(
551 __entry->dev = VFS_I(ip)->i_sb->s_dev;
552 __entry->ino = ip->i_ino;
553 __entry->agno = agno;
554 __entry->streams = xfs_filestream_peek_ag(ip->i_mount, agno);
555 ),
556 TP_printk("dev %d:%d ino 0x%llx agno %u streams %d",
557 MAJOR(__entry->dev), MINOR(__entry->dev),
558 __entry->ino,
559 __entry->agno,
560 __entry->streams)
561)
562#define DEFINE_FILESTREAM_EVENT(name) \
563DEFINE_EVENT(xfs_filestream_class, name, \
564 TP_PROTO(struct xfs_inode *ip, xfs_agnumber_t agno), \
565 TP_ARGS(ip, agno))
566DEFINE_FILESTREAM_EVENT(xfs_filestream_free);
567DEFINE_FILESTREAM_EVENT(xfs_filestream_lookup);
568DEFINE_FILESTREAM_EVENT(xfs_filestream_scan);
569
570TRACE_EVENT(xfs_filestream_pick,
571 TP_PROTO(struct xfs_inode *ip, xfs_agnumber_t agno,
572 xfs_extlen_t free, int nscan),
573 TP_ARGS(ip, agno, free, nscan),
574 TP_STRUCT__entry(
575 __field(dev_t, dev)
576 __field(xfs_ino_t, ino)
577 __field(xfs_agnumber_t, agno)
578 __field(int, streams)
579 __field(xfs_extlen_t, free)
580 __field(int, nscan)
581 ),
582 TP_fast_assign(
583 __entry->dev = VFS_I(ip)->i_sb->s_dev;
584 __entry->ino = ip->i_ino;
585 __entry->agno = agno;
586 __entry->streams = xfs_filestream_peek_ag(ip->i_mount, agno);
587 __entry->free = free;
588 __entry->nscan = nscan;
589 ),
590 TP_printk("dev %d:%d ino 0x%llx agno %u streams %d free %d nscan %d",
591 MAJOR(__entry->dev), MINOR(__entry->dev),
592 __entry->ino,
593 __entry->agno,
594 __entry->streams,
595 __entry->free,
596 __entry->nscan)
597);
598
541DECLARE_EVENT_CLASS(xfs_lock_class, 599DECLARE_EVENT_CLASS(xfs_lock_class,
542 TP_PROTO(struct xfs_inode *ip, unsigned lock_flags, 600 TP_PROTO(struct xfs_inode *ip, unsigned lock_flags,
543 unsigned long caller_ip), 601 unsigned long caller_ip),
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 54a57326d85b..d03932564ccb 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -827,7 +827,7 @@ xfs_trans_committed_bulk(
827 xfs_log_item_batch_insert(ailp, &cur, log_items, i, commit_lsn); 827 xfs_log_item_batch_insert(ailp, &cur, log_items, i, commit_lsn);
828 828
829 spin_lock(&ailp->xa_lock); 829 spin_lock(&ailp->xa_lock);
830 xfs_trans_ail_cursor_done(ailp, &cur); 830 xfs_trans_ail_cursor_done(&cur);
831 spin_unlock(&ailp->xa_lock); 831 spin_unlock(&ailp->xa_lock);
832} 832}
833 833
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index a7287354e535..cb0f3a84cc68 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -173,7 +173,6 @@ xfs_trans_ail_cursor_next(
173 */ 173 */
174void 174void
175xfs_trans_ail_cursor_done( 175xfs_trans_ail_cursor_done(
176 struct xfs_ail *ailp,
177 struct xfs_ail_cursor *cur) 176 struct xfs_ail_cursor *cur)
178{ 177{
179 cur->item = NULL; 178 cur->item = NULL;
@@ -368,7 +367,7 @@ xfsaild_push(
368 * If the AIL is empty or our push has reached the end we are 367 * If the AIL is empty or our push has reached the end we are
369 * done now. 368 * done now.
370 */ 369 */
371 xfs_trans_ail_cursor_done(ailp, &cur); 370 xfs_trans_ail_cursor_done(&cur);
372 spin_unlock(&ailp->xa_lock); 371 spin_unlock(&ailp->xa_lock);
373 goto out_done; 372 goto out_done;
374 } 373 }
@@ -453,7 +452,7 @@ xfsaild_push(
453 break; 452 break;
454 lsn = lip->li_lsn; 453 lsn = lip->li_lsn;
455 } 454 }
456 xfs_trans_ail_cursor_done(ailp, &cur); 455 xfs_trans_ail_cursor_done(&cur);
457 spin_unlock(&ailp->xa_lock); 456 spin_unlock(&ailp->xa_lock);
458 457
459 if (xfs_buf_delwri_submit_nowait(&ailp->xa_buf_list)) 458 if (xfs_buf_delwri_submit_nowait(&ailp->xa_buf_list))
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
index 12e86af9d9b9..bd1281862ad7 100644
--- a/fs/xfs/xfs_trans_priv.h
+++ b/fs/xfs/xfs_trans_priv.h
@@ -133,8 +133,7 @@ struct xfs_log_item * xfs_trans_ail_cursor_last(struct xfs_ail *ailp,
133 xfs_lsn_t lsn); 133 xfs_lsn_t lsn);
134struct xfs_log_item * xfs_trans_ail_cursor_next(struct xfs_ail *ailp, 134struct xfs_log_item * xfs_trans_ail_cursor_next(struct xfs_ail *ailp,
135 struct xfs_ail_cursor *cur); 135 struct xfs_ail_cursor *cur);
136void xfs_trans_ail_cursor_done(struct xfs_ail *ailp, 136void xfs_trans_ail_cursor_done(struct xfs_ail_cursor *cur);
137 struct xfs_ail_cursor *cur);
138 137
139#if BITS_PER_LONG != 64 138#if BITS_PER_LONG != 64
140static inline void 139static inline void
diff --git a/fs/xfs/xfs_trans_resv.c b/fs/xfs/xfs_trans_resv.c
index ae368165244d..f2bda7c76b8a 100644
--- a/fs/xfs/xfs_trans_resv.c
+++ b/fs/xfs/xfs_trans_resv.c
@@ -26,6 +26,7 @@
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_mount.h" 27#include "xfs_mount.h"
28#include "xfs_da_format.h" 28#include "xfs_da_format.h"
29#include "xfs_da_btree.h"
29#include "xfs_inode.h" 30#include "xfs_inode.h"
30#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
31#include "xfs_ialloc.h" 32#include "xfs_ialloc.h"
@@ -106,6 +107,47 @@ xfs_calc_inode_res(
106} 107}
107 108
108/* 109/*
110 * The free inode btree is a conditional feature and the log reservation
111 * requirements differ slightly from that of the traditional inode allocation
112 * btree. The finobt tracks records for inode chunks with at least one free
113 * inode. A record can be removed from the tree for an inode allocation
114 * or free and thus the finobt reservation is unconditional across:
115 *
116 * - inode allocation
117 * - inode free
118 * - inode chunk allocation
119 *
120 * The 'modify' param indicates to include the record modification scenario. The
121 * 'alloc' param indicates to include the reservation for free space btree
122 * modifications on behalf of finobt modifications. This is required only for
123 * transactions that do not already account for free space btree modifications.
124 *
125 * the free inode btree: max depth * block size
126 * the allocation btrees: 2 trees * (max depth - 1) * block size
127 * the free inode btree entry: block size
128 */
129STATIC uint
130xfs_calc_finobt_res(
131 struct xfs_mount *mp,
132 int alloc,
133 int modify)
134{
135 uint res;
136
137 if (!xfs_sb_version_hasfinobt(&mp->m_sb))
138 return 0;
139
140 res = xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1));
141 if (alloc)
142 res += xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
143 XFS_FSB_TO_B(mp, 1));
144 if (modify)
145 res += (uint)XFS_FSB_TO_B(mp, 1);
146
147 return res;
148}
149
150/*
109 * Various log reservation values. 151 * Various log reservation values.
110 * 152 *
111 * These are based on the size of the file system block because that is what 153 * These are based on the size of the file system block because that is what
@@ -302,6 +344,7 @@ xfs_calc_remove_reservation(
302 * the superblock for the nlink flag: sector size 344 * the superblock for the nlink flag: sector size
303 * the directory btree: (max depth + v2) * dir block size 345 * the directory btree: (max depth + v2) * dir block size
304 * the directory inode's bmap btree: (max depth + v2) * block size 346 * the directory inode's bmap btree: (max depth + v2) * block size
347 * the finobt (record modification and allocation btrees)
305 */ 348 */
306STATIC uint 349STATIC uint
307xfs_calc_create_resv_modify( 350xfs_calc_create_resv_modify(
@@ -310,7 +353,8 @@ xfs_calc_create_resv_modify(
310 return xfs_calc_inode_res(mp, 2) + 353 return xfs_calc_inode_res(mp, 2) +
311 xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + 354 xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
312 (uint)XFS_FSB_TO_B(mp, 1) + 355 (uint)XFS_FSB_TO_B(mp, 1) +
313 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)); 356 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)) +
357 xfs_calc_finobt_res(mp, 1, 1);
314} 358}
315 359
316/* 360/*
@@ -348,6 +392,7 @@ __xfs_calc_create_reservation(
348 * the superblock for the nlink flag: sector size 392 * the superblock for the nlink flag: sector size
349 * the inode btree: max depth * blocksize 393 * the inode btree: max depth * blocksize
350 * the allocation btrees: 2 trees * (max depth - 1) * block size 394 * the allocation btrees: 2 trees * (max depth - 1) * block size
395 * the finobt (record insertion)
351 */ 396 */
352STATIC uint 397STATIC uint
353xfs_calc_icreate_resv_alloc( 398xfs_calc_icreate_resv_alloc(
@@ -357,7 +402,8 @@ xfs_calc_icreate_resv_alloc(
357 mp->m_sb.sb_sectsize + 402 mp->m_sb.sb_sectsize +
358 xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + 403 xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
359 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 404 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
360 XFS_FSB_TO_B(mp, 1)); 405 XFS_FSB_TO_B(mp, 1)) +
406 xfs_calc_finobt_res(mp, 0, 0);
361} 407}
362 408
363STATIC uint 409STATIC uint
@@ -425,6 +471,7 @@ xfs_calc_symlink_reservation(
425 * the on disk inode before ours in the agi hash list: inode cluster size 471 * the on disk inode before ours in the agi hash list: inode cluster size
426 * the inode btree: max depth * blocksize 472 * the inode btree: max depth * blocksize
427 * the allocation btrees: 2 trees * (max depth - 1) * block size 473 * the allocation btrees: 2 trees * (max depth - 1) * block size
474 * the finobt (record insertion, removal or modification)
428 */ 475 */
429STATIC uint 476STATIC uint
430xfs_calc_ifree_reservation( 477xfs_calc_ifree_reservation(
@@ -439,7 +486,8 @@ xfs_calc_ifree_reservation(
439 xfs_calc_buf_res(2 + mp->m_ialloc_blks + 486 xfs_calc_buf_res(2 + mp->m_ialloc_blks +
440 mp->m_in_maxlevels, 0) + 487 mp->m_in_maxlevels, 0) +
441 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 488 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
442 XFS_FSB_TO_B(mp, 1)); 489 XFS_FSB_TO_B(mp, 1)) +
490 xfs_calc_finobt_res(mp, 0, 1);
443} 491}
444 492
445/* 493/*
@@ -562,7 +610,7 @@ xfs_calc_addafork_reservation(
562 return XFS_DQUOT_LOGRES(mp) + 610 return XFS_DQUOT_LOGRES(mp) +
563 xfs_calc_inode_res(mp, 1) + 611 xfs_calc_inode_res(mp, 1) +
564 xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 612 xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
565 xfs_calc_buf_res(1, mp->m_dirblksize) + 613 xfs_calc_buf_res(1, mp->m_dir_geo->blksize) +
566 xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1, 614 xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1,
567 XFS_FSB_TO_B(mp, 1)) + 615 XFS_FSB_TO_B(mp, 1)) +
568 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 616 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h
index af5dbe06cb65..bf9c4579334d 100644
--- a/fs/xfs/xfs_trans_space.h
+++ b/fs/xfs/xfs_trans_space.h
@@ -28,7 +28,8 @@
28 (((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \ 28 (((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \
29 XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \ 29 XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \
30 XFS_EXTENTADD_SPACE_RES(mp,w)) 30 XFS_EXTENTADD_SPACE_RES(mp,w))
31#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) 31#define XFS_DAENTER_1B(mp,w) \
32 ((w) == XFS_DATA_FORK ? (mp)->m_dir_geo->fsbcount : 1)
32#define XFS_DAENTER_DBS(mp,w) \ 33#define XFS_DAENTER_DBS(mp,w) \
33 (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0)) 34 (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0))
34#define XFS_DAENTER_BLOCKS(mp,w) \ 35#define XFS_DAENTER_BLOCKS(mp,w) \
@@ -47,13 +48,15 @@
47#define XFS_DIRREMOVE_SPACE_RES(mp) \ 48#define XFS_DIRREMOVE_SPACE_RES(mp) \
48 XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK) 49 XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK)
49#define XFS_IALLOC_SPACE_RES(mp) \ 50#define XFS_IALLOC_SPACE_RES(mp) \
50 ((mp)->m_ialloc_blks + (mp)->m_in_maxlevels - 1) 51 ((mp)->m_ialloc_blks + \
52 (xfs_sb_version_hasfinobt(&mp->m_sb) ? 2 : 1 * \
53 ((mp)->m_in_maxlevels - 1)))
51 54
52/* 55/*
53 * Space reservation values for various transactions. 56 * Space reservation values for various transactions.
54 */ 57 */
55#define XFS_ADDAFORK_SPACE_RES(mp) \ 58#define XFS_ADDAFORK_SPACE_RES(mp) \
56 ((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)) 59 ((mp)->m_dir_geo->fsbcount + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))
57#define XFS_ATTRRM_SPACE_RES(mp) \ 60#define XFS_ATTRRM_SPACE_RES(mp) \
58 XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) 61 XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK)
59/* This macro is not used - see inline code in xfs_attr_set */ 62/* This macro is not used - see inline code in xfs_attr_set */
@@ -82,5 +85,8 @@
82 (XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl)) 85 (XFS_DIRREMOVE_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl))
83#define XFS_SYMLINK_SPACE_RES(mp,nl,b) \ 86#define XFS_SYMLINK_SPACE_RES(mp,nl,b) \
84 (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl) + (b)) 87 (XFS_IALLOC_SPACE_RES(mp) + XFS_DIRENTER_SPACE_RES(mp,nl) + (b))
88#define XFS_IFREE_SPACE_RES(mp) \
89 (xfs_sb_version_hasfinobt(&mp->m_sb) ? (mp)->m_in_maxlevels : 0)
90
85 91
86#endif /* __XFS_TRANS_SPACE_H__ */ 92#endif /* __XFS_TRANS_SPACE_H__ */
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 82bbc34d54a3..65c6e6650b1a 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -134,7 +134,7 @@ typedef enum {
134 134
135typedef enum { 135typedef enum {
136 XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi, 136 XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi,
137 XFS_BTNUM_MAX 137 XFS_BTNUM_FINOi, XFS_BTNUM_MAX
138} xfs_btnum_t; 138} xfs_btnum_t;
139 139
140struct xfs_name { 140struct xfs_name {