aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/Makefile121
-rw-r--r--fs/xfs/kmem.c (renamed from fs/xfs/linux-2.6/kmem.c)0
-rw-r--r--fs/xfs/kmem.h (renamed from fs/xfs/linux-2.6/kmem.h)0
-rw-r--r--fs/xfs/mrlock.h (renamed from fs/xfs/linux-2.6/mrlock.h)0
-rw-r--r--fs/xfs/time.h (renamed from fs/xfs/linux-2.6/time.h)0
-rw-r--r--fs/xfs/uuid.c (renamed from fs/xfs/support/uuid.c)0
-rw-r--r--fs/xfs/uuid.h (renamed from fs/xfs/support/uuid.h)0
-rw-r--r--fs/xfs/xfs.h4
-rw-r--r--fs/xfs/xfs_acl.c (renamed from fs/xfs/linux-2.6/xfs_acl.c)90
-rw-r--r--fs/xfs/xfs_acl.h7
-rw-r--r--fs/xfs/xfs_ag.h6
-rw-r--r--fs/xfs/xfs_alloc.c21
-rw-r--r--fs/xfs/xfs_alloc_btree.c84
-rw-r--r--fs/xfs/xfs_aops.c (renamed from fs/xfs/linux-2.6/xfs_aops.c)24
-rw-r--r--fs/xfs/xfs_aops.h (renamed from fs/xfs/linux-2.6/xfs_aops.h)0
-rw-r--r--fs/xfs/xfs_arch.h136
-rw-r--r--fs/xfs/xfs_attr.c44
-rw-r--r--fs/xfs/xfs_attr_leaf.c60
-rw-r--r--fs/xfs/xfs_bmap.c51
-rw-r--r--fs/xfs/xfs_bmap_btree.c106
-rw-r--r--fs/xfs/xfs_btree.c46
-rw-r--r--fs/xfs/xfs_btree.h40
-rw-r--r--fs/xfs/xfs_btree_trace.c249
-rw-r--r--fs/xfs/xfs_btree_trace.h99
-rw-r--r--fs/xfs/xfs_buf.c (renamed from fs/xfs/linux-2.6/xfs_buf.c)93
-rw-r--r--fs/xfs/xfs_buf.h (renamed from fs/xfs/linux-2.6/xfs_buf.h)97
-rw-r--r--fs/xfs/xfs_buf_item.c102
-rw-r--r--fs/xfs/xfs_da_btree.c310
-rw-r--r--fs/xfs/xfs_da_btree.h13
-rw-r--r--fs/xfs/xfs_dinode.h2
-rw-r--r--fs/xfs/xfs_dir2.c156
-rw-r--r--fs/xfs/xfs_dir2.h54
-rw-r--r--fs/xfs/xfs_dir2_block.c253
-rw-r--r--fs/xfs/xfs_dir2_block.h92
-rw-r--r--fs/xfs/xfs_dir2_data.c327
-rw-r--r--fs/xfs/xfs_dir2_data.h184
-rw-r--r--fs/xfs/xfs_dir2_format.h597
-rw-r--r--fs/xfs/xfs_dir2_leaf.c417
-rw-r--r--fs/xfs/xfs_dir2_leaf.h253
-rw-r--r--fs/xfs/xfs_dir2_node.c203
-rw-r--r--fs/xfs/xfs_dir2_node.h100
-rw-r--r--fs/xfs/xfs_dir2_priv.h135
-rw-r--r--fs/xfs/xfs_dir2_sf.c338
-rw-r--r--fs/xfs/xfs_dir2_sf.h171
-rw-r--r--fs/xfs/xfs_discard.c (renamed from fs/xfs/linux-2.6/xfs_discard.c)4
-rw-r--r--fs/xfs/xfs_discard.h (renamed from fs/xfs/linux-2.6/xfs_discard.h)0
-rw-r--r--fs/xfs/xfs_dquot.c (renamed from fs/xfs/quota/xfs_dquot.c)64
-rw-r--r--fs/xfs/xfs_dquot.h (renamed from fs/xfs/quota/xfs_dquot.h)6
-rw-r--r--fs/xfs/xfs_dquot_item.c (renamed from fs/xfs/quota/xfs_dquot_item.c)10
-rw-r--r--fs/xfs/xfs_dquot_item.h (renamed from fs/xfs/quota/xfs_dquot_item.h)0
-rw-r--r--fs/xfs/xfs_export.c (renamed from fs/xfs/linux-2.6/xfs_export.c)4
-rw-r--r--fs/xfs/xfs_export.h (renamed from fs/xfs/linux-2.6/xfs_export.h)0
-rw-r--r--fs/xfs/xfs_file.c (renamed from fs/xfs/linux-2.6/xfs_file.c)54
-rw-r--r--fs/xfs/xfs_filestream.c14
-rw-r--r--fs/xfs/xfs_fs.h5
-rw-r--r--fs/xfs/xfs_fs_subr.c (renamed from fs/xfs/linux-2.6/xfs_fs_subr.c)0
-rw-r--r--fs/xfs/xfs_globals.c (renamed from fs/xfs/linux-2.6/xfs_globals.c)0
-rw-r--r--fs/xfs/xfs_ialloc.c19
-rw-r--r--fs/xfs/xfs_ialloc_btree.c75
-rw-r--r--fs/xfs/xfs_iget.c1
-rw-r--r--fs/xfs/xfs_inode.c557
-rw-r--r--fs/xfs/xfs_inode.h27
-rw-r--r--fs/xfs/xfs_inode_item.c27
-rw-r--r--fs/xfs/xfs_inum.h11
-rw-r--r--fs/xfs/xfs_ioctl.c (renamed from fs/xfs/linux-2.6/xfs_ioctl.c)6
-rw-r--r--fs/xfs/xfs_ioctl.h (renamed from fs/xfs/linux-2.6/xfs_ioctl.h)0
-rw-r--r--fs/xfs/xfs_ioctl32.c (renamed from fs/xfs/linux-2.6/xfs_ioctl32.c)0
-rw-r--r--fs/xfs/xfs_ioctl32.h (renamed from fs/xfs/linux-2.6/xfs_ioctl32.h)0
-rw-r--r--fs/xfs/xfs_iops.c (renamed from fs/xfs/linux-2.6/xfs_iops.c)468
-rw-r--r--fs/xfs/xfs_iops.h (renamed from fs/xfs/linux-2.6/xfs_iops.h)0
-rw-r--r--fs/xfs/xfs_linux.h (renamed from fs/xfs/linux-2.6/xfs_linux.h)36
-rw-r--r--fs/xfs/xfs_log.c78
-rw-r--r--fs/xfs/xfs_log_recover.c80
-rw-r--r--fs/xfs/xfs_message.c (renamed from fs/xfs/linux-2.6/xfs_message.c)0
-rw-r--r--fs/xfs/xfs_message.h (renamed from fs/xfs/linux-2.6/xfs_message.h)0
-rw-r--r--fs/xfs/xfs_mount.c106
-rw-r--r--fs/xfs/xfs_mount.h2
-rw-r--r--fs/xfs/xfs_qm.c (renamed from fs/xfs/quota/xfs_qm.c)54
-rw-r--r--fs/xfs/xfs_qm.h (renamed from fs/xfs/quota/xfs_qm.h)6
-rw-r--r--fs/xfs/xfs_qm_bhv.c (renamed from fs/xfs/quota/xfs_qm_bhv.c)0
-rw-r--r--fs/xfs/xfs_qm_stats.c (renamed from fs/xfs/quota/xfs_qm_stats.c)0
-rw-r--r--fs/xfs/xfs_qm_stats.h (renamed from fs/xfs/quota/xfs_qm_stats.h)0
-rw-r--r--fs/xfs/xfs_qm_syscalls.c (renamed from fs/xfs/quota/xfs_qm_syscalls.c)355
-rw-r--r--fs/xfs/xfs_quota_priv.h (renamed from fs/xfs/quota/xfs_quota_priv.h)0
-rw-r--r--fs/xfs/xfs_quotaops.c (renamed from fs/xfs/linux-2.6/xfs_quotaops.c)2
-rw-r--r--fs/xfs/xfs_rename.c4
-rw-r--r--fs/xfs/xfs_rtalloc.c32
-rw-r--r--fs/xfs/xfs_rtalloc.h2
-rw-r--r--fs/xfs/xfs_rw.c8
-rw-r--r--fs/xfs/xfs_sb.h2
-rw-r--r--fs/xfs/xfs_stats.c (renamed from fs/xfs/linux-2.6/xfs_stats.c)0
-rw-r--r--fs/xfs/xfs_stats.h (renamed from fs/xfs/linux-2.6/xfs_stats.h)0
-rw-r--r--fs/xfs/xfs_super.c (renamed from fs/xfs/linux-2.6/xfs_super.c)104
-rw-r--r--fs/xfs/xfs_super.h (renamed from fs/xfs/linux-2.6/xfs_super.h)0
-rw-r--r--fs/xfs/xfs_sync.c (renamed from fs/xfs/linux-2.6/xfs_sync.c)83
-rw-r--r--fs/xfs/xfs_sync.h (renamed from fs/xfs/linux-2.6/xfs_sync.h)13
-rw-r--r--fs/xfs/xfs_sysctl.c (renamed from fs/xfs/linux-2.6/xfs_sysctl.c)0
-rw-r--r--fs/xfs/xfs_sysctl.h (renamed from fs/xfs/linux-2.6/xfs_sysctl.h)0
-rw-r--r--fs/xfs/xfs_trace.c (renamed from fs/xfs/linux-2.6/xfs_trace.c)4
-rw-r--r--fs/xfs/xfs_trace.h (renamed from fs/xfs/linux-2.6/xfs_trace.h)62
-rw-r--r--fs/xfs/xfs_trans.c27
-rw-r--r--fs/xfs/xfs_trans.h2
-rw-r--r--fs/xfs/xfs_trans_ail.c288
-rw-r--r--fs/xfs/xfs_trans_buf.c146
-rw-r--r--fs/xfs/xfs_trans_dquot.c (renamed from fs/xfs/quota/xfs_trans_dquot.c)15
-rw-r--r--fs/xfs/xfs_trans_inode.c9
-rw-r--r--fs/xfs/xfs_trans_priv.h22
-rw-r--r--fs/xfs/xfs_vnode.h (renamed from fs/xfs/linux-2.6/xfs_vnode.h)0
-rw-r--r--fs/xfs/xfs_vnodeops.c514
-rw-r--r--fs/xfs/xfs_vnodeops.h3
-rw-r--r--fs/xfs/xfs_xattr.c (renamed from fs/xfs/linux-2.6/xfs_xattr.c)0
111 files changed, 3293 insertions, 5203 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index 284a7c89697..427a4e82a58 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -16,44 +16,53 @@
16# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17# 17#
18 18
19ccflags-y := -I$(src) -I$(src)/linux-2.6 19ccflags-y += -I$(src) # needed for trace events
20ccflags-$(CONFIG_XFS_DEBUG) += -g
21 20
22XFS_LINUX := linux-2.6 21ccflags-$(CONFIG_XFS_DEBUG) += -g
23 22
24obj-$(CONFIG_XFS_FS) += xfs.o 23obj-$(CONFIG_XFS_FS) += xfs.o
25 24
26xfs-y += linux-2.6/xfs_trace.o 25# this one should be compiled first, as the tracing macros can easily blow up
27 26xfs-y += xfs_trace.o
28xfs-$(CONFIG_XFS_QUOTA) += $(addprefix quota/, \
29 xfs_dquot.o \
30 xfs_dquot_item.o \
31 xfs_trans_dquot.o \
32 xfs_qm_syscalls.o \
33 xfs_qm_bhv.o \
34 xfs_qm.o)
35xfs-$(CONFIG_XFS_QUOTA) += linux-2.6/xfs_quotaops.o
36
37ifeq ($(CONFIG_XFS_QUOTA),y)
38xfs-$(CONFIG_PROC_FS) += quota/xfs_qm_stats.o
39endif
40
41xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
42xfs-$(CONFIG_XFS_POSIX_ACL) += $(XFS_LINUX)/xfs_acl.o
43xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
44xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
45xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
46 27
28# highlevel code
29xfs-y += xfs_aops.o \
30 xfs_bit.o \
31 xfs_buf.o \
32 xfs_dfrag.o \
33 xfs_discard.o \
34 xfs_error.o \
35 xfs_export.o \
36 xfs_file.o \
37 xfs_filestream.o \
38 xfs_fsops.o \
39 xfs_fs_subr.o \
40 xfs_globals.o \
41 xfs_iget.o \
42 xfs_ioctl.o \
43 xfs_iomap.o \
44 xfs_iops.o \
45 xfs_itable.o \
46 xfs_message.o \
47 xfs_mru_cache.o \
48 xfs_super.o \
49 xfs_sync.o \
50 xfs_xattr.o \
51 xfs_rename.o \
52 xfs_rw.o \
53 xfs_utils.o \
54 xfs_vnodeops.o \
55 kmem.o \
56 uuid.o
47 57
58# code shared with libxfs
48xfs-y += xfs_alloc.o \ 59xfs-y += xfs_alloc.o \
49 xfs_alloc_btree.o \ 60 xfs_alloc_btree.o \
50 xfs_attr.o \ 61 xfs_attr.o \
51 xfs_attr_leaf.o \ 62 xfs_attr_leaf.o \
52 xfs_bit.o \
53 xfs_bmap.o \ 63 xfs_bmap.o \
54 xfs_bmap_btree.o \ 64 xfs_bmap_btree.o \
55 xfs_btree.o \ 65 xfs_btree.o \
56 xfs_buf_item.o \
57 xfs_da_btree.o \ 66 xfs_da_btree.o \
58 xfs_dir2.o \ 67 xfs_dir2.o \
59 xfs_dir2_block.o \ 68 xfs_dir2_block.o \
@@ -61,51 +70,37 @@ xfs-y += xfs_alloc.o \
61 xfs_dir2_leaf.o \ 70 xfs_dir2_leaf.o \
62 xfs_dir2_node.o \ 71 xfs_dir2_node.o \
63 xfs_dir2_sf.o \ 72 xfs_dir2_sf.o \
64 xfs_error.o \
65 xfs_extfree_item.o \
66 xfs_filestream.o \
67 xfs_fsops.o \
68 xfs_ialloc.o \ 73 xfs_ialloc.o \
69 xfs_ialloc_btree.o \ 74 xfs_ialloc_btree.o \
70 xfs_iget.o \
71 xfs_inode.o \ 75 xfs_inode.o \
72 xfs_inode_item.o \
73 xfs_iomap.o \
74 xfs_itable.o \
75 xfs_dfrag.o \
76 xfs_log.o \
77 xfs_log_cil.o \
78 xfs_log_recover.o \ 76 xfs_log_recover.o \
79 xfs_mount.o \ 77 xfs_mount.o \
80 xfs_mru_cache.o \ 78 xfs_trans.o
81 xfs_rename.o \ 79
82 xfs_trans.o \ 80# low-level transaction/log code
81xfs-y += xfs_log.o \
82 xfs_log_cil.o \
83 xfs_buf_item.o \
84 xfs_extfree_item.o \
85 xfs_inode_item.o \
83 xfs_trans_ail.o \ 86 xfs_trans_ail.o \
84 xfs_trans_buf.o \ 87 xfs_trans_buf.o \
85 xfs_trans_extfree.o \ 88 xfs_trans_extfree.o \
86 xfs_trans_inode.o \ 89 xfs_trans_inode.o \
87 xfs_utils.o \
88 xfs_vnodeops.o \
89 xfs_rw.o
90 90
91xfs-$(CONFIG_XFS_TRACE) += xfs_btree_trace.o 91# optional features
92 92xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \
93# Objects in linux/ 93 xfs_dquot_item.o \
94xfs-y += $(addprefix $(XFS_LINUX)/, \ 94 xfs_trans_dquot.o \
95 kmem.o \ 95 xfs_qm_syscalls.o \
96 xfs_aops.o \ 96 xfs_qm_bhv.o \
97 xfs_buf.o \ 97 xfs_qm.o \
98 xfs_discard.o \ 98 xfs_quotaops.o
99 xfs_export.o \ 99ifeq ($(CONFIG_XFS_QUOTA),y)
100 xfs_file.o \ 100xfs-$(CONFIG_PROC_FS) += xfs_qm_stats.o
101 xfs_fs_subr.o \ 101endif
102 xfs_globals.o \ 102xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
103 xfs_ioctl.o \ 103xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
104 xfs_iops.o \ 104xfs-$(CONFIG_PROC_FS) += xfs_stats.o
105 xfs_message.o \ 105xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o
106 xfs_super.o \ 106xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o
107 xfs_sync.o \
108 xfs_xattr.o)
109
110# Objects in support/
111xfs-y += support/uuid.o
diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/kmem.c
index a907de565db..a907de565db 100644
--- a/fs/xfs/linux-2.6/kmem.c
+++ b/fs/xfs/kmem.c
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/kmem.h
index f7c8f7a9ea6..f7c8f7a9ea6 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/kmem.h
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/mrlock.h
index ff6a19873e5..ff6a19873e5 100644
--- a/fs/xfs/linux-2.6/mrlock.h
+++ b/fs/xfs/mrlock.h
diff --git a/fs/xfs/linux-2.6/time.h b/fs/xfs/time.h
index 387e695a184..387e695a184 100644
--- a/fs/xfs/linux-2.6/time.h
+++ b/fs/xfs/time.h
diff --git a/fs/xfs/support/uuid.c b/fs/xfs/uuid.c
index b83f76b6d41..b83f76b6d41 100644
--- a/fs/xfs/support/uuid.c
+++ b/fs/xfs/uuid.c
diff --git a/fs/xfs/support/uuid.h b/fs/xfs/uuid.h
index 4732d71262c..4732d71262c 100644
--- a/fs/xfs/support/uuid.h
+++ b/fs/xfs/uuid.h
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h
index 5ad8ad3a1dc..d8b11b7f94a 100644
--- a/fs/xfs/xfs.h
+++ b/fs/xfs/xfs.h
@@ -22,8 +22,8 @@
22#define STATIC 22#define STATIC
23#define DEBUG 1 23#define DEBUG 1
24#define XFS_BUF_LOCK_TRACKING 1 24#define XFS_BUF_LOCK_TRACKING 1
25/* #define QUOTADEBUG 1 */
26#endif 25#endif
27 26
28#include <linux-2.6/xfs_linux.h> 27#include "xfs_linux.h"
28
29#endif /* __XFS_H__ */ 29#endif /* __XFS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/xfs_acl.c
index 39f4f809bb6..ac702a6eab9 100644
--- a/fs/xfs/linux-2.6/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -39,9 +39,11 @@ xfs_acl_from_disk(struct xfs_acl *aclp)
39 struct posix_acl_entry *acl_e; 39 struct posix_acl_entry *acl_e;
40 struct posix_acl *acl; 40 struct posix_acl *acl;
41 struct xfs_acl_entry *ace; 41 struct xfs_acl_entry *ace;
42 int count, i; 42 unsigned int count, i;
43 43
44 count = be32_to_cpu(aclp->acl_cnt); 44 count = be32_to_cpu(aclp->acl_cnt);
45 if (count > XFS_ACL_MAX_ENTRIES)
46 return ERR_PTR(-EFSCORRUPTED);
45 47
46 acl = posix_acl_alloc(count, GFP_KERNEL); 48 acl = posix_acl_alloc(count, GFP_KERNEL);
47 if (!acl) 49 if (!acl)
@@ -114,6 +116,8 @@ xfs_get_acl(struct inode *inode, int type)
114 if (acl != ACL_NOT_CACHED) 116 if (acl != ACL_NOT_CACHED)
115 return acl; 117 return acl;
116 118
119 trace_xfs_get_acl(ip);
120
117 switch (type) { 121 switch (type) {
118 case ACL_TYPE_ACCESS: 122 case ACL_TYPE_ACCESS:
119 ea_name = SGI_ACL_FILE; 123 ea_name = SGI_ACL_FILE;
@@ -218,42 +222,8 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
218 return error; 222 return error;
219} 223}
220 224
221int
222xfs_check_acl(struct inode *inode, int mask, unsigned int flags)
223{
224 struct xfs_inode *ip;
225 struct posix_acl *acl;
226 int error = -EAGAIN;
227
228 ip = XFS_I(inode);
229 trace_xfs_check_acl(ip);
230
231 /*
232 * If there is no attribute fork no ACL exists on this inode and
233 * we can skip the whole exercise.
234 */
235 if (!XFS_IFORK_Q(ip))
236 return -EAGAIN;
237
238 if (flags & IPERM_FLAG_RCU) {
239 if (!negative_cached_acl(inode, ACL_TYPE_ACCESS))
240 return -ECHILD;
241 return -EAGAIN;
242 }
243
244 acl = xfs_get_acl(inode, ACL_TYPE_ACCESS);
245 if (IS_ERR(acl))
246 return PTR_ERR(acl);
247 if (acl) {
248 error = posix_acl_permission(inode, acl, mask);
249 posix_acl_release(acl);
250 }
251
252 return error;
253}
254
255static int 225static int
256xfs_set_mode(struct inode *inode, mode_t mode) 226xfs_set_mode(struct inode *inode, umode_t mode)
257{ 227{
258 int error = 0; 228 int error = 0;
259 229
@@ -264,7 +234,7 @@ xfs_set_mode(struct inode *inode, mode_t mode)
264 iattr.ia_mode = mode; 234 iattr.ia_mode = mode;
265 iattr.ia_ctime = current_fs_time(inode->i_sb); 235 iattr.ia_ctime = current_fs_time(inode->i_sb);
266 236
267 error = -xfs_setattr(XFS_I(inode), &iattr, XFS_ATTR_NOACL); 237 error = -xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL);
268 } 238 }
269 239
270 return error; 240 return error;
@@ -297,29 +267,23 @@ posix_acl_default_exists(struct inode *inode)
297 * No need for i_mutex because the inode is not yet exposed to the VFS. 267 * No need for i_mutex because the inode is not yet exposed to the VFS.
298 */ 268 */
299int 269int
300xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl) 270xfs_inherit_acl(struct inode *inode, struct posix_acl *acl)
301{ 271{
302 struct posix_acl *clone; 272 umode_t mode = inode->i_mode;
303 mode_t mode;
304 int error = 0, inherit = 0; 273 int error = 0, inherit = 0;
305 274
306 if (S_ISDIR(inode->i_mode)) { 275 if (S_ISDIR(inode->i_mode)) {
307 error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl); 276 error = xfs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
308 if (error) 277 if (error)
309 return error; 278 goto out;
310 } 279 }
311 280
312 clone = posix_acl_clone(default_acl, GFP_KERNEL); 281 error = posix_acl_create(&acl, GFP_KERNEL, &mode);
313 if (!clone)
314 return -ENOMEM;
315
316 mode = inode->i_mode;
317 error = posix_acl_create_masq(clone, &mode);
318 if (error < 0) 282 if (error < 0)
319 goto out_release_clone; 283 return error;
320 284
321 /* 285 /*
322 * If posix_acl_create_masq returns a positive value we need to 286 * If posix_acl_create returns a positive value we need to
323 * inherit a permission that can't be represented using the Unix 287 * inherit a permission that can't be represented using the Unix
324 * mode bits and we actually need to set an ACL. 288 * mode bits and we actually need to set an ACL.
325 */ 289 */
@@ -328,20 +292,20 @@ xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl)
328 292
329 error = xfs_set_mode(inode, mode); 293 error = xfs_set_mode(inode, mode);
330 if (error) 294 if (error)
331 goto out_release_clone; 295 goto out;
332 296
333 if (inherit) 297 if (inherit)
334 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone); 298 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
335 299
336 out_release_clone: 300out:
337 posix_acl_release(clone); 301 posix_acl_release(acl);
338 return error; 302 return error;
339} 303}
340 304
341int 305int
342xfs_acl_chmod(struct inode *inode) 306xfs_acl_chmod(struct inode *inode)
343{ 307{
344 struct posix_acl *acl, *clone; 308 struct posix_acl *acl;
345 int error; 309 int error;
346 310
347 if (S_ISLNK(inode->i_mode)) 311 if (S_ISLNK(inode->i_mode))
@@ -351,16 +315,12 @@ xfs_acl_chmod(struct inode *inode)
351 if (IS_ERR(acl) || !acl) 315 if (IS_ERR(acl) || !acl)
352 return PTR_ERR(acl); 316 return PTR_ERR(acl);
353 317
354 clone = posix_acl_clone(acl, GFP_KERNEL); 318 error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
355 posix_acl_release(acl); 319 if (error)
356 if (!clone) 320 return error;
357 return -ENOMEM;
358
359 error = posix_acl_chmod_masq(clone, inode->i_mode);
360 if (!error)
361 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
362 321
363 posix_acl_release(clone); 322 error = xfs_set_acl(inode, ACL_TYPE_ACCESS, acl);
323 posix_acl_release(acl);
364 return error; 324 return error;
365} 325}
366 326
@@ -423,7 +383,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
423 goto out_release; 383 goto out_release;
424 384
425 if (type == ACL_TYPE_ACCESS) { 385 if (type == ACL_TYPE_ACCESS) {
426 mode_t mode = inode->i_mode; 386 umode_t mode = inode->i_mode;
427 error = posix_acl_equiv_mode(acl, &mode); 387 error = posix_acl_equiv_mode(acl, &mode);
428 388
429 if (error <= 0) { 389 if (error <= 0) {
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 11dd72070cb..39632d94135 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -42,7 +42,6 @@ struct xfs_acl {
42#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1) 42#define SGI_ACL_DEFAULT_SIZE (sizeof(SGI_ACL_DEFAULT)-1)
43 43
44#ifdef CONFIG_XFS_POSIX_ACL 44#ifdef CONFIG_XFS_POSIX_ACL
45extern int xfs_check_acl(struct inode *inode, int mask, unsigned int flags);
46extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); 45extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
47extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl); 46extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl);
48extern int xfs_acl_chmod(struct inode *inode); 47extern int xfs_acl_chmod(struct inode *inode);
@@ -52,8 +51,10 @@ extern int posix_acl_default_exists(struct inode *inode);
52extern const struct xattr_handler xfs_xattr_acl_access_handler; 51extern const struct xattr_handler xfs_xattr_acl_access_handler;
53extern const struct xattr_handler xfs_xattr_acl_default_handler; 52extern const struct xattr_handler xfs_xattr_acl_default_handler;
54#else 53#else
55# define xfs_check_acl NULL 54static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type)
56# define xfs_get_acl(inode, type) NULL 55{
56 return NULL;
57}
57# define xfs_inherit_acl(inode, default_acl) 0 58# define xfs_inherit_acl(inode, default_acl) 0
58# define xfs_acl_chmod(inode) 0 59# define xfs_acl_chmod(inode) 0
59# define posix_acl_access_exists(inode) 0 60# define posix_acl_access_exists(inode) 0
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 6530769a999..4805f009f92 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -103,7 +103,7 @@ typedef struct xfs_agf {
103/* disk block (xfs_daddr_t) in the AG */ 103/* disk block (xfs_daddr_t) in the AG */
104#define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) 104#define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
105#define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp)) 105#define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp))
106#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp)) 106#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)((bp)->b_addr))
107 107
108extern int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, 108extern int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp,
109 xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); 109 xfs_agnumber_t agno, int flags, struct xfs_buf **bpp);
@@ -156,7 +156,7 @@ typedef struct xfs_agi {
156/* disk block (xfs_daddr_t) in the AG */ 156/* disk block (xfs_daddr_t) in the AG */
157#define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log)) 157#define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log))
158#define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp)) 158#define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp))
159#define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)XFS_BUF_PTR(bp)) 159#define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)((bp)->b_addr))
160 160
161extern int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp, 161extern int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp,
162 xfs_agnumber_t agno, struct xfs_buf **bpp); 162 xfs_agnumber_t agno, struct xfs_buf **bpp);
@@ -168,7 +168,7 @@ extern int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp,
168#define XFS_AGFL_DADDR(mp) ((xfs_daddr_t)(3 << (mp)->m_sectbb_log)) 168#define XFS_AGFL_DADDR(mp) ((xfs_daddr_t)(3 << (mp)->m_sectbb_log))
169#define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp)) 169#define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp))
170#define XFS_AGFL_SIZE(mp) ((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t)) 170#define XFS_AGFL_SIZE(mp) ((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t))
171#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) 171#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)((bp)->b_addr))
172 172
173typedef struct xfs_agfl { 173typedef struct xfs_agfl {
174 __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ 174 __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 95862bbff56..bdd9cb54d63 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -451,8 +451,7 @@ xfs_alloc_read_agfl(
451 XFS_FSS_TO_BB(mp, 1), 0, &bp); 451 XFS_FSS_TO_BB(mp, 1), 0, &bp);
452 if (error) 452 if (error)
453 return error; 453 return error;
454 ASSERT(bp); 454 ASSERT(!xfs_buf_geterror(bp));
455 ASSERT(!XFS_BUF_GETERROR(bp));
456 XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGFL, XFS_AGFL_REF); 455 XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGFL, XFS_AGFL_REF);
457 *bpp = bp; 456 *bpp = bp;
458 return 0; 457 return 0;
@@ -570,9 +569,7 @@ xfs_alloc_ag_vextent_exact(
570 xfs_agblock_t tbno; /* start block of trimmed extent */ 569 xfs_agblock_t tbno; /* start block of trimmed extent */
571 xfs_extlen_t tlen; /* length of trimmed extent */ 570 xfs_extlen_t tlen; /* length of trimmed extent */
572 xfs_agblock_t tend; /* end block of trimmed extent */ 571 xfs_agblock_t tend; /* end block of trimmed extent */
573 xfs_agblock_t end; /* end of allocated extent */
574 int i; /* success/failure of operation */ 572 int i; /* success/failure of operation */
575 xfs_extlen_t rlen; /* length of returned extent */
576 573
577 ASSERT(args->alignment == 1); 574 ASSERT(args->alignment == 1);
578 575
@@ -625,18 +622,16 @@ xfs_alloc_ag_vextent_exact(
625 * 622 *
626 * Fix the length according to mod and prod if given. 623 * Fix the length according to mod and prod if given.
627 */ 624 */
628 end = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen); 625 args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen)
629 args->len = end - args->agbno; 626 - args->agbno;
630 xfs_alloc_fix_len(args); 627 xfs_alloc_fix_len(args);
631 if (!xfs_alloc_fix_minleft(args)) 628 if (!xfs_alloc_fix_minleft(args))
632 goto not_found; 629 goto not_found;
633 630
634 rlen = args->len; 631 ASSERT(args->agbno + args->len <= tend);
635 ASSERT(args->agbno + rlen <= tend);
636 end = args->agbno + rlen;
637 632
638 /* 633 /*
639 * We are allocating agbno for rlen [agbno .. end] 634 * We are allocating agbno for args->len
640 * Allocate/initialize a cursor for the by-size btree. 635 * Allocate/initialize a cursor for the by-size btree.
641 */ 636 */
642 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, 637 cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
@@ -2120,14 +2115,14 @@ xfs_read_agf(
2120 if (!*bpp) 2115 if (!*bpp)
2121 return 0; 2116 return 0;
2122 2117
2123 ASSERT(!XFS_BUF_GETERROR(*bpp)); 2118 ASSERT(!(*bpp)->b_error);
2124 agf = XFS_BUF_TO_AGF(*bpp); 2119 agf = XFS_BUF_TO_AGF(*bpp);
2125 2120
2126 /* 2121 /*
2127 * Validate the magic number of the agf block. 2122 * Validate the magic number of the agf block.
2128 */ 2123 */
2129 agf_ok = 2124 agf_ok =
2130 be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC && 2125 agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) &&
2131 XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && 2126 XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) &&
2132 be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && 2127 be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) &&
2133 be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && 2128 be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) &&
@@ -2172,7 +2167,7 @@ xfs_alloc_read_agf(
2172 return error; 2167 return error;
2173 if (!*bpp) 2168 if (!*bpp)
2174 return 0; 2169 return 0;
2175 ASSERT(!XFS_BUF_GETERROR(*bpp)); 2170 ASSERT(!(*bpp)->b_error);
2176 2171
2177 agf = XFS_BUF_TO_AGF(*bpp); 2172 agf = XFS_BUF_TO_AGF(*bpp);
2178 pag = xfs_perag_get(mp, agno); 2173 pag = xfs_perag_get(mp, agno);
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index 2b3518826a6..ffb3386e45c 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -31,7 +31,6 @@
31#include "xfs_dinode.h" 31#include "xfs_dinode.h"
32#include "xfs_inode.h" 32#include "xfs_inode.h"
33#include "xfs_btree.h" 33#include "xfs_btree.h"
34#include "xfs_btree_trace.h"
35#include "xfs_alloc.h" 34#include "xfs_alloc.h"
36#include "xfs_error.h" 35#include "xfs_error.h"
37#include "xfs_trace.h" 36#include "xfs_trace.h"
@@ -311,72 +310,6 @@ xfs_allocbt_recs_inorder(
311} 310}
312#endif /* DEBUG */ 311#endif /* DEBUG */
313 312
314#ifdef XFS_BTREE_TRACE
315ktrace_t *xfs_allocbt_trace_buf;
316
317STATIC void
318xfs_allocbt_trace_enter(
319 struct xfs_btree_cur *cur,
320 const char *func,
321 char *s,
322 int type,
323 int line,
324 __psunsigned_t a0,
325 __psunsigned_t a1,
326 __psunsigned_t a2,
327 __psunsigned_t a3,
328 __psunsigned_t a4,
329 __psunsigned_t a5,
330 __psunsigned_t a6,
331 __psunsigned_t a7,
332 __psunsigned_t a8,
333 __psunsigned_t a9,
334 __psunsigned_t a10)
335{
336 ktrace_enter(xfs_allocbt_trace_buf, (void *)(__psint_t)type,
337 (void *)func, (void *)s, NULL, (void *)cur,
338 (void *)a0, (void *)a1, (void *)a2, (void *)a3,
339 (void *)a4, (void *)a5, (void *)a6, (void *)a7,
340 (void *)a8, (void *)a9, (void *)a10);
341}
342
343STATIC void
344xfs_allocbt_trace_cursor(
345 struct xfs_btree_cur *cur,
346 __uint32_t *s0,
347 __uint64_t *l0,
348 __uint64_t *l1)
349{
350 *s0 = cur->bc_private.a.agno;
351 *l0 = cur->bc_rec.a.ar_startblock;
352 *l1 = cur->bc_rec.a.ar_blockcount;
353}
354
355STATIC void
356xfs_allocbt_trace_key(
357 struct xfs_btree_cur *cur,
358 union xfs_btree_key *key,
359 __uint64_t *l0,
360 __uint64_t *l1)
361{
362 *l0 = be32_to_cpu(key->alloc.ar_startblock);
363 *l1 = be32_to_cpu(key->alloc.ar_blockcount);
364}
365
366STATIC void
367xfs_allocbt_trace_record(
368 struct xfs_btree_cur *cur,
369 union xfs_btree_rec *rec,
370 __uint64_t *l0,
371 __uint64_t *l1,
372 __uint64_t *l2)
373{
374 *l0 = be32_to_cpu(rec->alloc.ar_startblock);
375 *l1 = be32_to_cpu(rec->alloc.ar_blockcount);
376 *l2 = 0;
377}
378#endif /* XFS_BTREE_TRACE */
379
380static const struct xfs_btree_ops xfs_allocbt_ops = { 313static const struct xfs_btree_ops xfs_allocbt_ops = {
381 .rec_len = sizeof(xfs_alloc_rec_t), 314 .rec_len = sizeof(xfs_alloc_rec_t),
382 .key_len = sizeof(xfs_alloc_key_t), 315 .key_len = sizeof(xfs_alloc_key_t),
@@ -393,18 +326,10 @@ static const struct xfs_btree_ops xfs_allocbt_ops = {
393 .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, 326 .init_rec_from_cur = xfs_allocbt_init_rec_from_cur,
394 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, 327 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
395 .key_diff = xfs_allocbt_key_diff, 328 .key_diff = xfs_allocbt_key_diff,
396
397#ifdef DEBUG 329#ifdef DEBUG
398 .keys_inorder = xfs_allocbt_keys_inorder, 330 .keys_inorder = xfs_allocbt_keys_inorder,
399 .recs_inorder = xfs_allocbt_recs_inorder, 331 .recs_inorder = xfs_allocbt_recs_inorder,
400#endif 332#endif
401
402#ifdef XFS_BTREE_TRACE
403 .trace_enter = xfs_allocbt_trace_enter,
404 .trace_cursor = xfs_allocbt_trace_cursor,
405 .trace_key = xfs_allocbt_trace_key,
406 .trace_record = xfs_allocbt_trace_record,
407#endif
408}; 333};
409 334
410/* 335/*
@@ -427,13 +352,16 @@ xfs_allocbt_init_cursor(
427 352
428 cur->bc_tp = tp; 353 cur->bc_tp = tp;
429 cur->bc_mp = mp; 354 cur->bc_mp = mp;
430 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[btnum]);
431 cur->bc_btnum = btnum; 355 cur->bc_btnum = btnum;
432 cur->bc_blocklog = mp->m_sb.sb_blocklog; 356 cur->bc_blocklog = mp->m_sb.sb_blocklog;
433
434 cur->bc_ops = &xfs_allocbt_ops; 357 cur->bc_ops = &xfs_allocbt_ops;
435 if (btnum == XFS_BTNUM_CNT) 358
359 if (btnum == XFS_BTNUM_CNT) {
360 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
436 cur->bc_flags = XFS_BTREE_LASTREC_UPDATE; 361 cur->bc_flags = XFS_BTREE_LASTREC_UPDATE;
362 } else {
363 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]);
364 }
437 365
438 cur->bc_private.a.agbp = agbp; 366 cur->bc_private.a.agbp = agbp;
439 cur->bc_private.a.agno = agno; 367 cur->bc_private.a.agno = agno;
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/xfs_aops.c
index 79ce38be15a..8c37dde4c52 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -181,6 +181,7 @@ xfs_setfilesize(
181 181
182 isize = xfs_ioend_new_eof(ioend); 182 isize = xfs_ioend_new_eof(ioend);
183 if (isize) { 183 if (isize) {
184 trace_xfs_setfilesize(ip, ioend->io_offset, ioend->io_size);
184 ip->i_d.di_size = isize; 185 ip->i_d.di_size = isize;
185 xfs_mark_inode_dirty(ip); 186 xfs_mark_inode_dirty(ip);
186 } 187 }
@@ -894,11 +895,6 @@ out_invalidate:
894 * For unwritten space on the page we need to start the conversion to 895 * For unwritten space on the page we need to start the conversion to
895 * regular allocated space. 896 * regular allocated space.
896 * For any other dirty buffer heads on the page we should flush them. 897 * For any other dirty buffer heads on the page we should flush them.
897 *
898 * If we detect that a transaction would be required to flush the page, we
899 * have to check the process flags first, if we are already in a transaction
900 * or disk I/O during allocations is off, we need to fail the writepage and
901 * redirty the page.
902 */ 898 */
903STATIC int 899STATIC int
904xfs_vm_writepage( 900xfs_vm_writepage(
@@ -906,7 +902,6 @@ xfs_vm_writepage(
906 struct writeback_control *wbc) 902 struct writeback_control *wbc)
907{ 903{
908 struct inode *inode = page->mapping->host; 904 struct inode *inode = page->mapping->host;
909 int delalloc, unwritten;
910 struct buffer_head *bh, *head; 905 struct buffer_head *bh, *head;
911 struct xfs_bmbt_irec imap; 906 struct xfs_bmbt_irec imap;
912 xfs_ioend_t *ioend = NULL, *iohead = NULL; 907 xfs_ioend_t *ioend = NULL, *iohead = NULL;
@@ -938,15 +933,10 @@ xfs_vm_writepage(
938 goto redirty; 933 goto redirty;
939 934
940 /* 935 /*
941 * We need a transaction if there are delalloc or unwritten buffers 936 * Given that we do not allow direct reclaim to call us, we should
942 * on the page. 937 * never be called while in a filesystem transaction.
943 *
944 * If we need a transaction and the process flags say we are already
945 * in a transaction, or no IO is allowed then mark the page dirty
946 * again and leave the page as is.
947 */ 938 */
948 xfs_count_page_state(page, &delalloc, &unwritten); 939 if (WARN_ON(current->flags & PF_FSTRANS))
949 if ((current->flags & PF_FSTRANS) && (delalloc || unwritten))
950 goto redirty; 940 goto redirty;
951 941
952 /* Is this page beyond the end of the file? */ 942 /* Is this page beyond the end of the file? */
@@ -970,7 +960,7 @@ xfs_vm_writepage(
970 offset = page_offset(page); 960 offset = page_offset(page);
971 type = IO_OVERWRITE; 961 type = IO_OVERWRITE;
972 962
973 if (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking) 963 if (wbc->sync_mode == WB_SYNC_NONE)
974 nonblocking = 1; 964 nonblocking = 1;
975 965
976 do { 966 do {
@@ -1310,6 +1300,7 @@ xfs_end_io_direct_write(
1310 bool is_async) 1300 bool is_async)
1311{ 1301{
1312 struct xfs_ioend *ioend = iocb->private; 1302 struct xfs_ioend *ioend = iocb->private;
1303 struct inode *inode = ioend->io_inode;
1313 1304
1314 /* 1305 /*
1315 * blockdev_direct_IO can return an error even after the I/O 1306 * blockdev_direct_IO can return an error even after the I/O
@@ -1339,6 +1330,9 @@ xfs_end_io_direct_write(
1339 } else { 1330 } else {
1340 xfs_finish_ioend_sync(ioend); 1331 xfs_finish_ioend_sync(ioend);
1341 } 1332 }
1333
1334 /* XXX: probably should move into the real I/O completion handler */
1335 inode_dio_done(inode);
1342} 1336}
1343 1337
1344STATIC ssize_t 1338STATIC ssize_t
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/xfs_aops.h
index 71f721e1a71..71f721e1a71 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/xfs_aops.h
diff --git a/fs/xfs/xfs_arch.h b/fs/xfs/xfs_arch.h
deleted file mode 100644
index 0902249354a..00000000000
--- a/fs/xfs/xfs_arch.h
+++ /dev/null
@@ -1,136 +0,0 @@
1/*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_ARCH_H__
19#define __XFS_ARCH_H__
20
21#ifndef XFS_BIG_INUMS
22# error XFS_BIG_INUMS must be defined true or false
23#endif
24
25#ifdef __KERNEL__
26
27#include <asm/byteorder.h>
28
29#ifdef __BIG_ENDIAN
30#define XFS_NATIVE_HOST 1
31#else
32#undef XFS_NATIVE_HOST
33#endif
34
35#else /* __KERNEL__ */
36
37#if __BYTE_ORDER == __BIG_ENDIAN
38#define XFS_NATIVE_HOST 1
39#else
40#undef XFS_NATIVE_HOST
41#endif
42
43#ifdef XFS_NATIVE_HOST
44#define cpu_to_be16(val) ((__force __be16)(__u16)(val))
45#define cpu_to_be32(val) ((__force __be32)(__u32)(val))
46#define cpu_to_be64(val) ((__force __be64)(__u64)(val))
47#define be16_to_cpu(val) ((__force __u16)(__be16)(val))
48#define be32_to_cpu(val) ((__force __u32)(__be32)(val))
49#define be64_to_cpu(val) ((__force __u64)(__be64)(val))
50#else
51#define cpu_to_be16(val) ((__force __be16)__swab16((__u16)(val)))
52#define cpu_to_be32(val) ((__force __be32)__swab32((__u32)(val)))
53#define cpu_to_be64(val) ((__force __be64)__swab64((__u64)(val)))
54#define be16_to_cpu(val) (__swab16((__force __u16)(__be16)(val)))
55#define be32_to_cpu(val) (__swab32((__force __u32)(__be32)(val)))
56#define be64_to_cpu(val) (__swab64((__force __u64)(__be64)(val)))
57#endif
58
59static inline void be16_add_cpu(__be16 *a, __s16 b)
60{
61 *a = cpu_to_be16(be16_to_cpu(*a) + b);
62}
63
64static inline void be32_add_cpu(__be32 *a, __s32 b)
65{
66 *a = cpu_to_be32(be32_to_cpu(*a) + b);
67}
68
69static inline void be64_add_cpu(__be64 *a, __s64 b)
70{
71 *a = cpu_to_be64(be64_to_cpu(*a) + b);
72}
73
74#endif /* __KERNEL__ */
75
76/*
77 * get and set integers from potentially unaligned locations
78 */
79
80#define INT_GET_UNALIGNED_16_BE(pointer) \
81 ((__u16)((((__u8*)(pointer))[0] << 8) | (((__u8*)(pointer))[1])))
82#define INT_SET_UNALIGNED_16_BE(pointer,value) \
83 { \
84 ((__u8*)(pointer))[0] = (((value) >> 8) & 0xff); \
85 ((__u8*)(pointer))[1] = (((value) ) & 0xff); \
86 }
87
88/*
89 * In directories inode numbers are stored as unaligned arrays of unsigned
90 * 8bit integers on disk.
91 *
92 * For v1 directories or v2 directories that contain inode numbers that
93 * do not fit into 32bit the array has eight members, but the first member
94 * is always zero:
95 *
96 * |unused|48-55|40-47|32-39|24-31|16-23| 8-15| 0- 7|
97 *
98 * For v2 directories that only contain entries with inode numbers that fit
99 * into 32bits a four-member array is used:
100 *
101 * |24-31|16-23| 8-15| 0- 7|
102 */
103
104#define XFS_GET_DIR_INO4(di) \
105 (((__u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
106
107#define XFS_PUT_DIR_INO4(from, di) \
108do { \
109 (di).i[0] = (((from) & 0xff000000ULL) >> 24); \
110 (di).i[1] = (((from) & 0x00ff0000ULL) >> 16); \
111 (di).i[2] = (((from) & 0x0000ff00ULL) >> 8); \
112 (di).i[3] = ((from) & 0x000000ffULL); \
113} while (0)
114
115#define XFS_DI_HI(di) \
116 (((__u32)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
117#define XFS_DI_LO(di) \
118 (((__u32)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | ((di).i[7]))
119
120#define XFS_GET_DIR_INO8(di) \
121 (((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \
122 ((xfs_ino_t)XFS_DI_HI(di) << 32))
123
124#define XFS_PUT_DIR_INO8(from, di) \
125do { \
126 (di).i[0] = 0; \
127 (di).i[1] = (((from) & 0x00ff000000000000ULL) >> 48); \
128 (di).i[2] = (((from) & 0x0000ff0000000000ULL) >> 40); \
129 (di).i[3] = (((from) & 0x000000ff00000000ULL) >> 32); \
130 (di).i[4] = (((from) & 0x00000000ff000000ULL) >> 24); \
131 (di).i[5] = (((from) & 0x0000000000ff0000ULL) >> 16); \
132 (di).i[6] = (((from) & 0x000000000000ff00ULL) >> 8); \
133 (di).i[7] = ((from) & 0x00000000000000ffULL); \
134} while (0)
135
136#endif /* __XFS_ARCH_H__ */
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 01d2072fb6d..160bcdc34a6 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -822,17 +822,21 @@ xfs_attr_inactive(xfs_inode_t *dp)
822 error = xfs_attr_root_inactive(&trans, dp); 822 error = xfs_attr_root_inactive(&trans, dp);
823 if (error) 823 if (error)
824 goto out; 824 goto out;
825
825 /* 826 /*
826 * signal synchronous inactive transactions unless this 827 * Signal synchronous inactive transactions unless this is a
827 * is a synchronous mount filesystem in which case we 828 * synchronous mount filesystem in which case we know that we're here
828 * know that we're here because we've been called out of 829 * because we've been called out of xfs_inactive which means that the
829 * xfs_inactive which means that the last reference is gone 830 * last reference is gone and the unlink transaction has already hit
830 * and the unlink transaction has already hit the disk so 831 * the disk so async inactive transactions are safe.
831 * async inactive transactions are safe.
832 */ 832 */
833 if ((error = xfs_itruncate_finish(&trans, dp, 0LL, XFS_ATTR_FORK, 833 if (!(mp->m_flags & XFS_MOUNT_WSYNC)) {
834 (!(mp->m_flags & XFS_MOUNT_WSYNC) 834 if (dp->i_d.di_anextents > 0)
835 ? 1 : 0)))) 835 xfs_trans_set_sync(trans);
836 }
837
838 error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0);
839 if (error)
836 goto out; 840 goto out;
837 841
838 /* 842 /*
@@ -1199,7 +1203,7 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
1199 return XFS_ERROR(error); 1203 return XFS_ERROR(error);
1200 ASSERT(bp != NULL); 1204 ASSERT(bp != NULL);
1201 leaf = bp->data; 1205 leaf = bp->data;
1202 if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) { 1206 if (unlikely(leaf->hdr.info.magic != cpu_to_be16(XFS_ATTR_LEAF_MAGIC))) {
1203 XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW, 1207 XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
1204 context->dp->i_mount, leaf); 1208 context->dp->i_mount, leaf);
1205 xfs_da_brelse(NULL, bp); 1209 xfs_da_brelse(NULL, bp);
@@ -1606,9 +1610,8 @@ xfs_attr_node_removename(xfs_da_args_t *args)
1606 XFS_ATTR_FORK); 1610 XFS_ATTR_FORK);
1607 if (error) 1611 if (error)
1608 goto out; 1612 goto out;
1609 ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *) 1613 ASSERT((((xfs_attr_leafblock_t *)bp->data)->hdr.info.magic) ==
1610 bp->data)->hdr.info.magic) 1614 cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1611 == XFS_ATTR_LEAF_MAGIC);
1612 1615
1613 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) { 1616 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1614 xfs_bmap_init(args->flist, args->firstblock); 1617 xfs_bmap_init(args->flist, args->firstblock);
@@ -1873,11 +1876,11 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1873 return(XFS_ERROR(EFSCORRUPTED)); 1876 return(XFS_ERROR(EFSCORRUPTED));
1874 } 1877 }
1875 node = bp->data; 1878 node = bp->data;
1876 if (be16_to_cpu(node->hdr.info.magic) 1879 if (node->hdr.info.magic ==
1877 == XFS_ATTR_LEAF_MAGIC) 1880 cpu_to_be16(XFS_ATTR_LEAF_MAGIC))
1878 break; 1881 break;
1879 if (unlikely(be16_to_cpu(node->hdr.info.magic) 1882 if (unlikely(node->hdr.info.magic !=
1880 != XFS_DA_NODE_MAGIC)) { 1883 cpu_to_be16(XFS_DA_NODE_MAGIC))) {
1881 XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)", 1884 XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
1882 XFS_ERRLEVEL_LOW, 1885 XFS_ERRLEVEL_LOW,
1883 context->dp->i_mount, 1886 context->dp->i_mount,
@@ -1912,8 +1915,8 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
1912 */ 1915 */
1913 for (;;) { 1916 for (;;) {
1914 leaf = bp->data; 1917 leaf = bp->data;
1915 if (unlikely(be16_to_cpu(leaf->hdr.info.magic) 1918 if (unlikely(leaf->hdr.info.magic !=
1916 != XFS_ATTR_LEAF_MAGIC)) { 1919 cpu_to_be16(XFS_ATTR_LEAF_MAGIC))) {
1917 XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)", 1920 XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)",
1918 XFS_ERRLEVEL_LOW, 1921 XFS_ERRLEVEL_LOW,
1919 context->dp->i_mount, leaf); 1922 context->dp->i_mount, leaf);
@@ -2118,8 +2121,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
2118 2121
2119 bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, 2122 bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt,
2120 XBF_LOCK | XBF_DONT_BLOCK); 2123 XBF_LOCK | XBF_DONT_BLOCK);
2121 ASSERT(bp); 2124 ASSERT(!xfs_buf_geterror(bp));
2122 ASSERT(!XFS_BUF_GETERROR(bp));
2123 2125
2124 tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen : 2126 tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen :
2125 XFS_BUF_SIZE(bp); 2127 XFS_BUF_SIZE(bp);
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 71e90dc2aeb..8fad9602542 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -731,7 +731,7 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp)
731 int bytes, i; 731 int bytes, i;
732 732
733 leaf = bp->data; 733 leaf = bp->data;
734 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 734 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
735 735
736 entry = &leaf->entries[0]; 736 entry = &leaf->entries[0];
737 bytes = sizeof(struct xfs_attr_sf_hdr); 737 bytes = sizeof(struct xfs_attr_sf_hdr);
@@ -777,7 +777,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
777 ASSERT(bp != NULL); 777 ASSERT(bp != NULL);
778 memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); 778 memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount));
779 leaf = (xfs_attr_leafblock_t *)tmpbuffer; 779 leaf = (xfs_attr_leafblock_t *)tmpbuffer;
780 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 780 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
781 memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); 781 memset(bp->data, 0, XFS_LBSIZE(dp->i_mount));
782 782
783 /* 783 /*
@@ -872,7 +872,7 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args)
872 goto out; 872 goto out;
873 node = bp1->data; 873 node = bp1->data;
874 leaf = bp2->data; 874 leaf = bp2->data;
875 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 875 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
876 /* both on-disk, don't endian-flip twice */ 876 /* both on-disk, don't endian-flip twice */
877 node->btree[0].hashval = 877 node->btree[0].hashval =
878 leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval; 878 leaf->entries[be16_to_cpu(leaf->hdr.count)-1 ].hashval;
@@ -997,7 +997,7 @@ xfs_attr_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args)
997 int tablesize, entsize, sum, tmp, i; 997 int tablesize, entsize, sum, tmp, i;
998 998
999 leaf = bp->data; 999 leaf = bp->data;
1000 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 1000 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1001 ASSERT((args->index >= 0) 1001 ASSERT((args->index >= 0)
1002 && (args->index <= be16_to_cpu(leaf->hdr.count))); 1002 && (args->index <= be16_to_cpu(leaf->hdr.count)));
1003 hdr = &leaf->hdr; 1003 hdr = &leaf->hdr;
@@ -1070,7 +1070,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
1070 int tmp, i; 1070 int tmp, i;
1071 1071
1072 leaf = bp->data; 1072 leaf = bp->data;
1073 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 1073 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1074 hdr = &leaf->hdr; 1074 hdr = &leaf->hdr;
1075 ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE)); 1075 ASSERT((mapindex >= 0) && (mapindex < XFS_ATTR_LEAF_MAPSIZE));
1076 ASSERT((args->index >= 0) && (args->index <= be16_to_cpu(hdr->count))); 1076 ASSERT((args->index >= 0) && (args->index <= be16_to_cpu(hdr->count)));
@@ -1256,8 +1256,8 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1256 ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); 1256 ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC);
1257 leaf1 = blk1->bp->data; 1257 leaf1 = blk1->bp->data;
1258 leaf2 = blk2->bp->data; 1258 leaf2 = blk2->bp->data;
1259 ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 1259 ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1260 ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 1260 ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1261 args = state->args; 1261 args = state->args;
1262 1262
1263 /* 1263 /*
@@ -1533,7 +1533,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
1533 */ 1533 */
1534 blk = &state->path.blk[ state->path.active-1 ]; 1534 blk = &state->path.blk[ state->path.active-1 ];
1535 info = blk->bp->data; 1535 info = blk->bp->data;
1536 ASSERT(be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); 1536 ASSERT(info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1537 leaf = (xfs_attr_leafblock_t *)info; 1537 leaf = (xfs_attr_leafblock_t *)info;
1538 count = be16_to_cpu(leaf->hdr.count); 1538 count = be16_to_cpu(leaf->hdr.count);
1539 bytes = sizeof(xfs_attr_leaf_hdr_t) + 1539 bytes = sizeof(xfs_attr_leaf_hdr_t) +
@@ -1596,7 +1596,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
1596 bytes = state->blocksize - (state->blocksize>>2); 1596 bytes = state->blocksize - (state->blocksize>>2);
1597 bytes -= be16_to_cpu(leaf->hdr.usedbytes); 1597 bytes -= be16_to_cpu(leaf->hdr.usedbytes);
1598 leaf = bp->data; 1598 leaf = bp->data;
1599 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 1599 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1600 count += be16_to_cpu(leaf->hdr.count); 1600 count += be16_to_cpu(leaf->hdr.count);
1601 bytes -= be16_to_cpu(leaf->hdr.usedbytes); 1601 bytes -= be16_to_cpu(leaf->hdr.usedbytes);
1602 bytes -= count * sizeof(xfs_attr_leaf_entry_t); 1602 bytes -= count * sizeof(xfs_attr_leaf_entry_t);
@@ -1650,7 +1650,7 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args)
1650 xfs_mount_t *mp; 1650 xfs_mount_t *mp;
1651 1651
1652 leaf = bp->data; 1652 leaf = bp->data;
1653 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 1653 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1654 hdr = &leaf->hdr; 1654 hdr = &leaf->hdr;
1655 mp = args->trans->t_mountp; 1655 mp = args->trans->t_mountp;
1656 ASSERT((be16_to_cpu(hdr->count) > 0) 1656 ASSERT((be16_to_cpu(hdr->count) > 0)
@@ -1813,8 +1813,8 @@ xfs_attr_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1813 ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC); 1813 ASSERT(save_blk->magic == XFS_ATTR_LEAF_MAGIC);
1814 drop_leaf = drop_blk->bp->data; 1814 drop_leaf = drop_blk->bp->data;
1815 save_leaf = save_blk->bp->data; 1815 save_leaf = save_blk->bp->data;
1816 ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 1816 ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1817 ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 1817 ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1818 drop_hdr = &drop_leaf->hdr; 1818 drop_hdr = &drop_leaf->hdr;
1819 save_hdr = &save_leaf->hdr; 1819 save_hdr = &save_leaf->hdr;
1820 1820
@@ -1915,7 +1915,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
1915 xfs_dahash_t hashval; 1915 xfs_dahash_t hashval;
1916 1916
1917 leaf = bp->data; 1917 leaf = bp->data;
1918 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 1918 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1919 ASSERT(be16_to_cpu(leaf->hdr.count) 1919 ASSERT(be16_to_cpu(leaf->hdr.count)
1920 < (XFS_LBSIZE(args->dp->i_mount)/8)); 1920 < (XFS_LBSIZE(args->dp->i_mount)/8));
1921 1921
@@ -2019,7 +2019,7 @@ xfs_attr_leaf_getvalue(xfs_dabuf_t *bp, xfs_da_args_t *args)
2019 xfs_attr_leaf_name_remote_t *name_rmt; 2019 xfs_attr_leaf_name_remote_t *name_rmt;
2020 2020
2021 leaf = bp->data; 2021 leaf = bp->data;
2022 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2022 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2023 ASSERT(be16_to_cpu(leaf->hdr.count) 2023 ASSERT(be16_to_cpu(leaf->hdr.count)
2024 < (XFS_LBSIZE(args->dp->i_mount)/8)); 2024 < (XFS_LBSIZE(args->dp->i_mount)/8));
2025 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2025 ASSERT(args->index < be16_to_cpu(leaf->hdr.count));
@@ -2087,8 +2087,8 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s,
2087 /* 2087 /*
2088 * Set up environment. 2088 * Set up environment.
2089 */ 2089 */
2090 ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2090 ASSERT(leaf_s->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2091 ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2091 ASSERT(leaf_d->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2092 hdr_s = &leaf_s->hdr; 2092 hdr_s = &leaf_s->hdr;
2093 hdr_d = &leaf_d->hdr; 2093 hdr_d = &leaf_d->hdr;
2094 ASSERT((be16_to_cpu(hdr_s->count) > 0) && 2094 ASSERT((be16_to_cpu(hdr_s->count) > 0) &&
@@ -2222,8 +2222,8 @@ xfs_attr_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp)
2222 2222
2223 leaf1 = leaf1_bp->data; 2223 leaf1 = leaf1_bp->data;
2224 leaf2 = leaf2_bp->data; 2224 leaf2 = leaf2_bp->data;
2225 ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC) && 2225 ASSERT((leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) &&
2226 (be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC)); 2226 (leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)));
2227 if ((be16_to_cpu(leaf1->hdr.count) > 0) && 2227 if ((be16_to_cpu(leaf1->hdr.count) > 0) &&
2228 (be16_to_cpu(leaf2->hdr.count) > 0) && 2228 (be16_to_cpu(leaf2->hdr.count) > 0) &&
2229 ((be32_to_cpu(leaf2->entries[0].hashval) < 2229 ((be32_to_cpu(leaf2->entries[0].hashval) <
@@ -2246,7 +2246,7 @@ xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count)
2246 xfs_attr_leafblock_t *leaf; 2246 xfs_attr_leafblock_t *leaf;
2247 2247
2248 leaf = bp->data; 2248 leaf = bp->data;
2249 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2249 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2250 if (count) 2250 if (count)
2251 *count = be16_to_cpu(leaf->hdr.count); 2251 *count = be16_to_cpu(leaf->hdr.count);
2252 if (!leaf->hdr.count) 2252 if (!leaf->hdr.count)
@@ -2265,7 +2265,7 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
2265 xfs_attr_leaf_name_remote_t *name_rmt; 2265 xfs_attr_leaf_name_remote_t *name_rmt;
2266 int size; 2266 int size;
2267 2267
2268 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2268 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2269 if (leaf->entries[index].flags & XFS_ATTR_LOCAL) { 2269 if (leaf->entries[index].flags & XFS_ATTR_LOCAL) {
2270 name_loc = xfs_attr_leaf_name_local(leaf, index); 2270 name_loc = xfs_attr_leaf_name_local(leaf, index);
2271 size = xfs_attr_leaf_entsize_local(name_loc->namelen, 2271 size = xfs_attr_leaf_entsize_local(name_loc->namelen,
@@ -2451,7 +2451,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args)
2451 ASSERT(bp != NULL); 2451 ASSERT(bp != NULL);
2452 2452
2453 leaf = bp->data; 2453 leaf = bp->data;
2454 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2454 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2455 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2455 ASSERT(args->index < be16_to_cpu(leaf->hdr.count));
2456 ASSERT(args->index >= 0); 2456 ASSERT(args->index >= 0);
2457 entry = &leaf->entries[ args->index ]; 2457 entry = &leaf->entries[ args->index ];
@@ -2515,7 +2515,7 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args)
2515 ASSERT(bp != NULL); 2515 ASSERT(bp != NULL);
2516 2516
2517 leaf = bp->data; 2517 leaf = bp->data;
2518 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2518 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2519 ASSERT(args->index < be16_to_cpu(leaf->hdr.count)); 2519 ASSERT(args->index < be16_to_cpu(leaf->hdr.count));
2520 ASSERT(args->index >= 0); 2520 ASSERT(args->index >= 0);
2521 entry = &leaf->entries[ args->index ]; 2521 entry = &leaf->entries[ args->index ];
@@ -2585,13 +2585,13 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)
2585 } 2585 }
2586 2586
2587 leaf1 = bp1->data; 2587 leaf1 = bp1->data;
2588 ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2588 ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2589 ASSERT(args->index < be16_to_cpu(leaf1->hdr.count)); 2589 ASSERT(args->index < be16_to_cpu(leaf1->hdr.count));
2590 ASSERT(args->index >= 0); 2590 ASSERT(args->index >= 0);
2591 entry1 = &leaf1->entries[ args->index ]; 2591 entry1 = &leaf1->entries[ args->index ];
2592 2592
2593 leaf2 = bp2->data; 2593 leaf2 = bp2->data;
2594 ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2594 ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2595 ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count)); 2595 ASSERT(args->index2 < be16_to_cpu(leaf2->hdr.count));
2596 ASSERT(args->index2 >= 0); 2596 ASSERT(args->index2 >= 0);
2597 entry2 = &leaf2->entries[ args->index2 ]; 2597 entry2 = &leaf2->entries[ args->index2 ];
@@ -2689,9 +2689,9 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp)
2689 * This is a depth-first traversal! 2689 * This is a depth-first traversal!
2690 */ 2690 */
2691 info = bp->data; 2691 info = bp->data;
2692 if (be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC) { 2692 if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) {
2693 error = xfs_attr_node_inactive(trans, dp, bp, 1); 2693 error = xfs_attr_node_inactive(trans, dp, bp, 1);
2694 } else if (be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC) { 2694 } else if (info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) {
2695 error = xfs_attr_leaf_inactive(trans, dp, bp); 2695 error = xfs_attr_leaf_inactive(trans, dp, bp);
2696 } else { 2696 } else {
2697 error = XFS_ERROR(EIO); 2697 error = XFS_ERROR(EIO);
@@ -2739,7 +2739,7 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
2739 } 2739 }
2740 2740
2741 node = bp->data; 2741 node = bp->data;
2742 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 2742 ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
2743 parent_blkno = xfs_da_blkno(bp); /* save for re-read later */ 2743 parent_blkno = xfs_da_blkno(bp); /* save for re-read later */
2744 count = be16_to_cpu(node->hdr.count); 2744 count = be16_to_cpu(node->hdr.count);
2745 if (!count) { 2745 if (!count) {
@@ -2773,10 +2773,10 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
2773 * Invalidate the subtree, however we have to. 2773 * Invalidate the subtree, however we have to.
2774 */ 2774 */
2775 info = child_bp->data; 2775 info = child_bp->data;
2776 if (be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC) { 2776 if (info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) {
2777 error = xfs_attr_node_inactive(trans, dp, 2777 error = xfs_attr_node_inactive(trans, dp,
2778 child_bp, level+1); 2778 child_bp, level+1);
2779 } else if (be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC) { 2779 } else if (info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)) {
2780 error = xfs_attr_leaf_inactive(trans, dp, 2780 error = xfs_attr_leaf_inactive(trans, dp,
2781 child_bp); 2781 child_bp);
2782 } else { 2782 } else {
@@ -2836,7 +2836,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp)
2836 int error, count, size, tmp, i; 2836 int error, count, size, tmp, i;
2837 2837
2838 leaf = bp->data; 2838 leaf = bp->data;
2839 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_ATTR_LEAF_MAGIC); 2839 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
2840 2840
2841 /* 2841 /*
2842 * Count the number of "remote" value extents. 2842 * Count the number of "remote" value extents.
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index e546a33214c..452a291383a 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -29,15 +29,11 @@
29#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
30#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
31#include "xfs_ialloc_btree.h" 31#include "xfs_ialloc_btree.h"
32#include "xfs_dir2_sf.h"
33#include "xfs_dinode.h" 32#include "xfs_dinode.h"
34#include "xfs_inode.h" 33#include "xfs_inode.h"
35#include "xfs_btree.h" 34#include "xfs_btree.h"
36#include "xfs_mount.h" 35#include "xfs_mount.h"
37#include "xfs_itable.h" 36#include "xfs_itable.h"
38#include "xfs_dir2_data.h"
39#include "xfs_dir2_leaf.h"
40#include "xfs_dir2_block.h"
41#include "xfs_inode_item.h" 37#include "xfs_inode_item.h"
42#include "xfs_extfree_item.h" 38#include "xfs_extfree_item.h"
43#include "xfs_alloc.h" 39#include "xfs_alloc.h"
@@ -94,6 +90,7 @@ xfs_bmap_add_attrfork_local(
94 */ 90 */
95STATIC int /* error */ 91STATIC int /* error */
96xfs_bmap_add_extent_delay_real( 92xfs_bmap_add_extent_delay_real(
93 struct xfs_trans *tp, /* transaction pointer */
97 xfs_inode_t *ip, /* incore inode pointer */ 94 xfs_inode_t *ip, /* incore inode pointer */
98 xfs_extnum_t *idx, /* extent number to update/insert */ 95 xfs_extnum_t *idx, /* extent number to update/insert */
99 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 96 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
@@ -417,7 +414,7 @@ xfs_bmap_add_attrfork_local(
417 414
418 if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip)) 415 if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip))
419 return 0; 416 return 0;
420 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 417 if (S_ISDIR(ip->i_d.di_mode)) {
421 mp = ip->i_mount; 418 mp = ip->i_mount;
422 memset(&dargs, 0, sizeof(dargs)); 419 memset(&dargs, 0, sizeof(dargs));
423 dargs.dp = ip; 420 dargs.dp = ip;
@@ -439,6 +436,7 @@ xfs_bmap_add_attrfork_local(
439 */ 436 */
440STATIC int /* error */ 437STATIC int /* error */
441xfs_bmap_add_extent( 438xfs_bmap_add_extent(
439 struct xfs_trans *tp, /* transaction pointer */
442 xfs_inode_t *ip, /* incore inode pointer */ 440 xfs_inode_t *ip, /* incore inode pointer */
443 xfs_extnum_t *idx, /* extent number to update/insert */ 441 xfs_extnum_t *idx, /* extent number to update/insert */
444 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 442 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
@@ -524,7 +522,7 @@ xfs_bmap_add_extent(
524 if (cur) 522 if (cur)
525 ASSERT(cur->bc_private.b.flags & 523 ASSERT(cur->bc_private.b.flags &
526 XFS_BTCUR_BPRV_WASDEL); 524 XFS_BTCUR_BPRV_WASDEL);
527 error = xfs_bmap_add_extent_delay_real(ip, 525 error = xfs_bmap_add_extent_delay_real(tp, ip,
528 idx, &cur, new, &da_new, 526 idx, &cur, new, &da_new,
529 first, flist, &logflags); 527 first, flist, &logflags);
530 } else { 528 } else {
@@ -561,7 +559,7 @@ xfs_bmap_add_extent(
561 int tmp_logflags; /* partial log flag return val */ 559 int tmp_logflags; /* partial log flag return val */
562 560
563 ASSERT(cur == NULL); 561 ASSERT(cur == NULL);
564 error = xfs_bmap_extents_to_btree(ip->i_transp, ip, first, 562 error = xfs_bmap_extents_to_btree(tp, ip, first,
565 flist, &cur, da_old > 0, &tmp_logflags, whichfork); 563 flist, &cur, da_old > 0, &tmp_logflags, whichfork);
566 logflags |= tmp_logflags; 564 logflags |= tmp_logflags;
567 if (error) 565 if (error)
@@ -604,6 +602,7 @@ done:
604 */ 602 */
605STATIC int /* error */ 603STATIC int /* error */
606xfs_bmap_add_extent_delay_real( 604xfs_bmap_add_extent_delay_real(
605 struct xfs_trans *tp, /* transaction pointer */
607 xfs_inode_t *ip, /* incore inode pointer */ 606 xfs_inode_t *ip, /* incore inode pointer */
608 xfs_extnum_t *idx, /* extent number to update/insert */ 607 xfs_extnum_t *idx, /* extent number to update/insert */
609 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 608 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
@@ -901,7 +900,7 @@ xfs_bmap_add_extent_delay_real(
901 } 900 }
902 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 901 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
903 ip->i_d.di_nextents > ip->i_df.if_ext_max) { 902 ip->i_d.di_nextents > ip->i_df.if_ext_max) {
904 error = xfs_bmap_extents_to_btree(ip->i_transp, ip, 903 error = xfs_bmap_extents_to_btree(tp, ip,
905 first, flist, &cur, 1, &tmp_rval, 904 first, flist, &cur, 1, &tmp_rval,
906 XFS_DATA_FORK); 905 XFS_DATA_FORK);
907 rval |= tmp_rval; 906 rval |= tmp_rval;
@@ -984,7 +983,7 @@ xfs_bmap_add_extent_delay_real(
984 } 983 }
985 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 984 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
986 ip->i_d.di_nextents > ip->i_df.if_ext_max) { 985 ip->i_d.di_nextents > ip->i_df.if_ext_max) {
987 error = xfs_bmap_extents_to_btree(ip->i_transp, ip, 986 error = xfs_bmap_extents_to_btree(tp, ip,
988 first, flist, &cur, 1, &tmp_rval, 987 first, flist, &cur, 1, &tmp_rval,
989 XFS_DATA_FORK); 988 XFS_DATA_FORK);
990 rval |= tmp_rval; 989 rval |= tmp_rval;
@@ -1052,7 +1051,7 @@ xfs_bmap_add_extent_delay_real(
1052 } 1051 }
1053 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && 1052 if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
1054 ip->i_d.di_nextents > ip->i_df.if_ext_max) { 1053 ip->i_d.di_nextents > ip->i_df.if_ext_max) {
1055 error = xfs_bmap_extents_to_btree(ip->i_transp, ip, 1054 error = xfs_bmap_extents_to_btree(tp, ip,
1056 first, flist, &cur, 1, &tmp_rval, 1055 first, flist, &cur, 1, &tmp_rval,
1057 XFS_DATA_FORK); 1056 XFS_DATA_FORK);
1058 rval |= tmp_rval; 1057 rval |= tmp_rval;
@@ -2871,8 +2870,8 @@ xfs_bmap_del_extent(
2871 len = del->br_blockcount; 2870 len = del->br_blockcount;
2872 do_div(bno, mp->m_sb.sb_rextsize); 2871 do_div(bno, mp->m_sb.sb_rextsize);
2873 do_div(len, mp->m_sb.sb_rextsize); 2872 do_div(len, mp->m_sb.sb_rextsize);
2874 if ((error = xfs_rtfree_extent(ip->i_transp, bno, 2873 error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len);
2875 (xfs_extlen_t)len))) 2874 if (error)
2876 goto done; 2875 goto done;
2877 do_fx = 0; 2876 do_fx = 0;
2878 nblks = len * mp->m_sb.sb_rextsize; 2877 nblks = len * mp->m_sb.sb_rextsize;
@@ -3345,8 +3344,7 @@ xfs_bmap_local_to_extents(
3345 * We don't want to deal with the case of keeping inode data inline yet. 3344 * We don't want to deal with the case of keeping inode data inline yet.
3346 * So sending the data fork of a regular inode is invalid. 3345 * So sending the data fork of a regular inode is invalid.
3347 */ 3346 */
3348 ASSERT(!((ip->i_d.di_mode & S_IFMT) == S_IFREG && 3347 ASSERT(!(S_ISREG(ip->i_d.di_mode) && whichfork == XFS_DATA_FORK));
3349 whichfork == XFS_DATA_FORK));
3350 ifp = XFS_IFORK_PTR(ip, whichfork); 3348 ifp = XFS_IFORK_PTR(ip, whichfork);
3351 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); 3349 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL);
3352 flags = 0; 3350 flags = 0;
@@ -3385,8 +3383,7 @@ xfs_bmap_local_to_extents(
3385 ASSERT(args.len == 1); 3383 ASSERT(args.len == 1);
3386 *firstblock = args.fsbno; 3384 *firstblock = args.fsbno;
3387 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); 3385 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
3388 memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data, 3386 memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
3389 ifp->if_bytes);
3390 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); 3387 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
3391 xfs_bmap_forkoff_reset(args.mp, ip, whichfork); 3388 xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
3392 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); 3389 xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
@@ -4053,7 +4050,7 @@ xfs_bmap_one_block(
4053 4050
4054#ifndef DEBUG 4051#ifndef DEBUG
4055 if (whichfork == XFS_DATA_FORK) { 4052 if (whichfork == XFS_DATA_FORK) {
4056 return ((ip->i_d.di_mode & S_IFMT) == S_IFREG) ? 4053 return S_ISREG(ip->i_d.di_mode) ?
4057 (ip->i_size == ip->i_mount->m_sb.sb_blocksize) : 4054 (ip->i_size == ip->i_mount->m_sb.sb_blocksize) :
4058 (ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize); 4055 (ip->i_d.di_size == ip->i_mount->m_sb.sb_blocksize);
4059 } 4056 }
@@ -4080,7 +4077,7 @@ xfs_bmap_sanity_check(
4080{ 4077{
4081 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); 4078 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
4082 4079
4083 if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC || 4080 if (block->bb_magic != cpu_to_be32(XFS_BMAP_MAGIC) ||
4084 be16_to_cpu(block->bb_level) != level || 4081 be16_to_cpu(block->bb_level) != level ||
4085 be16_to_cpu(block->bb_numrecs) == 0 || 4082 be16_to_cpu(block->bb_numrecs) == 0 ||
4086 be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0]) 4083 be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0])
@@ -4662,7 +4659,7 @@ xfs_bmapi(
4662 if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) 4659 if (!wasdelay && (flags & XFS_BMAPI_PREALLOC))
4663 got.br_state = XFS_EXT_UNWRITTEN; 4660 got.br_state = XFS_EXT_UNWRITTEN;
4664 } 4661 }
4665 error = xfs_bmap_add_extent(ip, &lastx, &cur, &got, 4662 error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, &got,
4666 firstblock, flist, &tmp_logflags, 4663 firstblock, flist, &tmp_logflags,
4667 whichfork); 4664 whichfork);
4668 logflags |= tmp_logflags; 4665 logflags |= tmp_logflags;
@@ -4763,7 +4760,7 @@ xfs_bmapi(
4763 mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) 4760 mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
4764 ? XFS_EXT_NORM 4761 ? XFS_EXT_NORM
4765 : XFS_EXT_UNWRITTEN; 4762 : XFS_EXT_UNWRITTEN;
4766 error = xfs_bmap_add_extent(ip, &lastx, &cur, mval, 4763 error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, mval,
4767 firstblock, flist, &tmp_logflags, 4764 firstblock, flist, &tmp_logflags,
4768 whichfork); 4765 whichfork);
4769 logflags |= tmp_logflags; 4766 logflags |= tmp_logflags;
@@ -5117,7 +5114,7 @@ xfs_bunmapi(
5117 del.br_blockcount = mod; 5114 del.br_blockcount = mod;
5118 } 5115 }
5119 del.br_state = XFS_EXT_UNWRITTEN; 5116 del.br_state = XFS_EXT_UNWRITTEN;
5120 error = xfs_bmap_add_extent(ip, &lastx, &cur, &del, 5117 error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, &del,
5121 firstblock, flist, &logflags, 5118 firstblock, flist, &logflags,
5122 XFS_DATA_FORK); 5119 XFS_DATA_FORK);
5123 if (error) 5120 if (error)
@@ -5175,18 +5172,18 @@ xfs_bunmapi(
5175 } 5172 }
5176 prev.br_state = XFS_EXT_UNWRITTEN; 5173 prev.br_state = XFS_EXT_UNWRITTEN;
5177 lastx--; 5174 lastx--;
5178 error = xfs_bmap_add_extent(ip, &lastx, &cur, 5175 error = xfs_bmap_add_extent(tp, ip, &lastx,
5179 &prev, firstblock, flist, &logflags, 5176 &cur, &prev, firstblock, flist,
5180 XFS_DATA_FORK); 5177 &logflags, XFS_DATA_FORK);
5181 if (error) 5178 if (error)
5182 goto error0; 5179 goto error0;
5183 goto nodelete; 5180 goto nodelete;
5184 } else { 5181 } else {
5185 ASSERT(del.br_state == XFS_EXT_NORM); 5182 ASSERT(del.br_state == XFS_EXT_NORM);
5186 del.br_state = XFS_EXT_UNWRITTEN; 5183 del.br_state = XFS_EXT_UNWRITTEN;
5187 error = xfs_bmap_add_extent(ip, &lastx, &cur, 5184 error = xfs_bmap_add_extent(tp, ip, &lastx,
5188 &del, firstblock, flist, &logflags, 5185 &cur, &del, firstblock, flist,
5189 XFS_DATA_FORK); 5186 &logflags, XFS_DATA_FORK);
5190 if (error) 5187 if (error)
5191 goto error0; 5188 goto error0;
5192 goto nodelete; 5189 goto nodelete;
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 87d3c10b695..e2f5d59cbea 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -33,7 +33,6 @@
33#include "xfs_inode_item.h" 33#include "xfs_inode_item.h"
34#include "xfs_alloc.h" 34#include "xfs_alloc.h"
35#include "xfs_btree.h" 35#include "xfs_btree.h"
36#include "xfs_btree_trace.h"
37#include "xfs_itable.h" 36#include "xfs_itable.h"
38#include "xfs_bmap.h" 37#include "xfs_bmap.h"
39#include "xfs_error.h" 38#include "xfs_error.h"
@@ -425,10 +424,10 @@ xfs_bmbt_to_bmdr(
425 xfs_bmbt_key_t *tkp; 424 xfs_bmbt_key_t *tkp;
426 __be64 *tpp; 425 __be64 *tpp;
427 426
428 ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC); 427 ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_MAGIC));
429 ASSERT(be64_to_cpu(rblock->bb_u.l.bb_leftsib) == NULLDFSBNO); 428 ASSERT(rblock->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO));
430 ASSERT(be64_to_cpu(rblock->bb_u.l.bb_rightsib) == NULLDFSBNO); 429 ASSERT(rblock->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO));
431 ASSERT(be16_to_cpu(rblock->bb_level) > 0); 430 ASSERT(rblock->bb_level != 0);
432 dblock->bb_level = rblock->bb_level; 431 dblock->bb_level = rblock->bb_level;
433 dblock->bb_numrecs = rblock->bb_numrecs; 432 dblock->bb_numrecs = rblock->bb_numrecs;
434 dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); 433 dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0);
@@ -732,95 +731,6 @@ xfs_bmbt_recs_inorder(
732} 731}
733#endif /* DEBUG */ 732#endif /* DEBUG */
734 733
735#ifdef XFS_BTREE_TRACE
736ktrace_t *xfs_bmbt_trace_buf;
737
738STATIC void
739xfs_bmbt_trace_enter(
740 struct xfs_btree_cur *cur,
741 const char *func,
742 char *s,
743 int type,
744 int line,
745 __psunsigned_t a0,
746 __psunsigned_t a1,
747 __psunsigned_t a2,
748 __psunsigned_t a3,
749 __psunsigned_t a4,
750 __psunsigned_t a5,
751 __psunsigned_t a6,
752 __psunsigned_t a7,
753 __psunsigned_t a8,
754 __psunsigned_t a9,
755 __psunsigned_t a10)
756{
757 struct xfs_inode *ip = cur->bc_private.b.ip;
758 int whichfork = cur->bc_private.b.whichfork;
759
760 ktrace_enter(xfs_bmbt_trace_buf,
761 (void *)((__psint_t)type | (whichfork << 8) | (line << 16)),
762 (void *)func, (void *)s, (void *)ip, (void *)cur,
763 (void *)a0, (void *)a1, (void *)a2, (void *)a3,
764 (void *)a4, (void *)a5, (void *)a6, (void *)a7,
765 (void *)a8, (void *)a9, (void *)a10);
766}
767
768STATIC void
769xfs_bmbt_trace_cursor(
770 struct xfs_btree_cur *cur,
771 __uint32_t *s0,
772 __uint64_t *l0,
773 __uint64_t *l1)
774{
775 struct xfs_bmbt_rec_host r;
776
777 xfs_bmbt_set_all(&r, &cur->bc_rec.b);
778
779 *s0 = (cur->bc_nlevels << 24) |
780 (cur->bc_private.b.flags << 16) |
781 cur->bc_private.b.allocated;
782 *l0 = r.l0;
783 *l1 = r.l1;
784}
785
786STATIC void
787xfs_bmbt_trace_key(
788 struct xfs_btree_cur *cur,
789 union xfs_btree_key *key,
790 __uint64_t *l0,
791 __uint64_t *l1)
792{
793 *l0 = be64_to_cpu(key->bmbt.br_startoff);
794 *l1 = 0;
795}
796
797/* Endian flipping versions of the bmbt extraction functions */
798STATIC void
799xfs_bmbt_disk_get_all(
800 xfs_bmbt_rec_t *r,
801 xfs_bmbt_irec_t *s)
802{
803 __xfs_bmbt_get_all(get_unaligned_be64(&r->l0),
804 get_unaligned_be64(&r->l1), s);
805}
806
807STATIC void
808xfs_bmbt_trace_record(
809 struct xfs_btree_cur *cur,
810 union xfs_btree_rec *rec,
811 __uint64_t *l0,
812 __uint64_t *l1,
813 __uint64_t *l2)
814{
815 struct xfs_bmbt_irec irec;
816
817 xfs_bmbt_disk_get_all(&rec->bmbt, &irec);
818 *l0 = irec.br_startoff;
819 *l1 = irec.br_startblock;
820 *l2 = irec.br_blockcount;
821}
822#endif /* XFS_BTREE_TRACE */
823
824static const struct xfs_btree_ops xfs_bmbt_ops = { 734static const struct xfs_btree_ops xfs_bmbt_ops = {
825 .rec_len = sizeof(xfs_bmbt_rec_t), 735 .rec_len = sizeof(xfs_bmbt_rec_t),
826 .key_len = sizeof(xfs_bmbt_key_t), 736 .key_len = sizeof(xfs_bmbt_key_t),
@@ -837,18 +747,10 @@ static const struct xfs_btree_ops xfs_bmbt_ops = {
837 .init_rec_from_cur = xfs_bmbt_init_rec_from_cur, 747 .init_rec_from_cur = xfs_bmbt_init_rec_from_cur,
838 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, 748 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
839 .key_diff = xfs_bmbt_key_diff, 749 .key_diff = xfs_bmbt_key_diff,
840
841#ifdef DEBUG 750#ifdef DEBUG
842 .keys_inorder = xfs_bmbt_keys_inorder, 751 .keys_inorder = xfs_bmbt_keys_inorder,
843 .recs_inorder = xfs_bmbt_recs_inorder, 752 .recs_inorder = xfs_bmbt_recs_inorder,
844#endif 753#endif
845
846#ifdef XFS_BTREE_TRACE
847 .trace_enter = xfs_bmbt_trace_enter,
848 .trace_cursor = xfs_bmbt_trace_cursor,
849 .trace_key = xfs_bmbt_trace_key,
850 .trace_record = xfs_bmbt_trace_record,
851#endif
852}; 754};
853 755
854/* 756/*
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 2f9e97c128a..2b9fd385e27 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -32,7 +32,6 @@
32#include "xfs_inode.h" 32#include "xfs_inode.h"
33#include "xfs_inode_item.h" 33#include "xfs_inode_item.h"
34#include "xfs_btree.h" 34#include "xfs_btree.h"
35#include "xfs_btree_trace.h"
36#include "xfs_error.h" 35#include "xfs_error.h"
37#include "xfs_trace.h" 36#include "xfs_trace.h"
38 37
@@ -66,11 +65,11 @@ xfs_btree_check_lblock(
66 be16_to_cpu(block->bb_numrecs) <= 65 be16_to_cpu(block->bb_numrecs) <=
67 cur->bc_ops->get_maxrecs(cur, level) && 66 cur->bc_ops->get_maxrecs(cur, level) &&
68 block->bb_u.l.bb_leftsib && 67 block->bb_u.l.bb_leftsib &&
69 (be64_to_cpu(block->bb_u.l.bb_leftsib) == NULLDFSBNO || 68 (block->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO) ||
70 XFS_FSB_SANITY_CHECK(mp, 69 XFS_FSB_SANITY_CHECK(mp,
71 be64_to_cpu(block->bb_u.l.bb_leftsib))) && 70 be64_to_cpu(block->bb_u.l.bb_leftsib))) &&
72 block->bb_u.l.bb_rightsib && 71 block->bb_u.l.bb_rightsib &&
73 (be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO || 72 (block->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO) ||
74 XFS_FSB_SANITY_CHECK(mp, 73 XFS_FSB_SANITY_CHECK(mp,
75 be64_to_cpu(block->bb_u.l.bb_rightsib))); 74 be64_to_cpu(block->bb_u.l.bb_rightsib)));
76 if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, 75 if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp,
@@ -105,10 +104,10 @@ xfs_btree_check_sblock(
105 be16_to_cpu(block->bb_level) == level && 104 be16_to_cpu(block->bb_level) == level &&
106 be16_to_cpu(block->bb_numrecs) <= 105 be16_to_cpu(block->bb_numrecs) <=
107 cur->bc_ops->get_maxrecs(cur, level) && 106 cur->bc_ops->get_maxrecs(cur, level) &&
108 (be32_to_cpu(block->bb_u.s.bb_leftsib) == NULLAGBLOCK || 107 (block->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK) ||
109 be32_to_cpu(block->bb_u.s.bb_leftsib) < agflen) && 108 be32_to_cpu(block->bb_u.s.bb_leftsib) < agflen) &&
110 block->bb_u.s.bb_leftsib && 109 block->bb_u.s.bb_leftsib &&
111 (be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK || 110 (block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK) ||
112 be32_to_cpu(block->bb_u.s.bb_rightsib) < agflen) && 111 be32_to_cpu(block->bb_u.s.bb_rightsib) < agflen) &&
113 block->bb_u.s.bb_rightsib; 112 block->bb_u.s.bb_rightsib;
114 if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp, 113 if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
@@ -276,8 +275,7 @@ xfs_btree_dup_cursor(
276 return error; 275 return error;
277 } 276 }
278 new->bc_bufs[i] = bp; 277 new->bc_bufs[i] = bp;
279 ASSERT(bp); 278 ASSERT(!xfs_buf_geterror(bp));
280 ASSERT(!XFS_BUF_GETERROR(bp));
281 } else 279 } else
282 new->bc_bufs[i] = NULL; 280 new->bc_bufs[i] = NULL;
283 } 281 }
@@ -468,8 +466,7 @@ xfs_btree_get_bufl(
468 ASSERT(fsbno != NULLFSBLOCK); 466 ASSERT(fsbno != NULLFSBLOCK);
469 d = XFS_FSB_TO_DADDR(mp, fsbno); 467 d = XFS_FSB_TO_DADDR(mp, fsbno);
470 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); 468 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
471 ASSERT(bp); 469 ASSERT(!xfs_buf_geterror(bp));
472 ASSERT(!XFS_BUF_GETERROR(bp));
473 return bp; 470 return bp;
474} 471}
475 472
@@ -492,8 +489,7 @@ xfs_btree_get_bufs(
492 ASSERT(agbno != NULLAGBLOCK); 489 ASSERT(agbno != NULLAGBLOCK);
493 d = XFS_AGB_TO_DADDR(mp, agno, agbno); 490 d = XFS_AGB_TO_DADDR(mp, agno, agbno);
494 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); 491 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock);
495 ASSERT(bp); 492 ASSERT(!xfs_buf_geterror(bp));
496 ASSERT(!XFS_BUF_GETERROR(bp));
497 return bp; 493 return bp;
498} 494}
499 495
@@ -511,9 +507,9 @@ xfs_btree_islastblock(
511 block = xfs_btree_get_block(cur, level, &bp); 507 block = xfs_btree_get_block(cur, level, &bp);
512 xfs_btree_check_block(cur, block, level, bp); 508 xfs_btree_check_block(cur, block, level, bp);
513 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) 509 if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
514 return be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO; 510 return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO);
515 else 511 else
516 return be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK; 512 return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK);
517} 513}
518 514
519/* 515/*
@@ -633,7 +629,7 @@ xfs_btree_read_bufl(
633 mp->m_bsize, lock, &bp))) { 629 mp->m_bsize, lock, &bp))) {
634 return error; 630 return error;
635 } 631 }
636 ASSERT(!bp || !XFS_BUF_GETERROR(bp)); 632 ASSERT(!xfs_buf_geterror(bp));
637 if (bp) 633 if (bp)
638 XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); 634 XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
639 *bpp = bp; 635 *bpp = bp;
@@ -777,14 +773,14 @@ xfs_btree_setbuf(
777 773
778 b = XFS_BUF_TO_BLOCK(bp); 774 b = XFS_BUF_TO_BLOCK(bp);
779 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { 775 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
780 if (be64_to_cpu(b->bb_u.l.bb_leftsib) == NULLDFSBNO) 776 if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO))
781 cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; 777 cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
782 if (be64_to_cpu(b->bb_u.l.bb_rightsib) == NULLDFSBNO) 778 if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO))
783 cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; 779 cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
784 } else { 780 } else {
785 if (be32_to_cpu(b->bb_u.s.bb_leftsib) == NULLAGBLOCK) 781 if (b->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK))
786 cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA; 782 cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
787 if (be32_to_cpu(b->bb_u.s.bb_rightsib) == NULLAGBLOCK) 783 if (b->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK))
788 cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA; 784 cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
789 } 785 }
790} 786}
@@ -795,9 +791,9 @@ xfs_btree_ptr_is_null(
795 union xfs_btree_ptr *ptr) 791 union xfs_btree_ptr *ptr)
796{ 792{
797 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) 793 if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
798 return be64_to_cpu(ptr->l) == NULLDFSBNO; 794 return ptr->l == cpu_to_be64(NULLDFSBNO);
799 else 795 else
800 return be32_to_cpu(ptr->s) == NULLAGBLOCK; 796 return ptr->s == cpu_to_be32(NULLAGBLOCK);
801} 797}
802 798
803STATIC void 799STATIC void
@@ -923,12 +919,12 @@ xfs_btree_ptr_to_daddr(
923 union xfs_btree_ptr *ptr) 919 union xfs_btree_ptr *ptr)
924{ 920{
925 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { 921 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
926 ASSERT(be64_to_cpu(ptr->l) != NULLDFSBNO); 922 ASSERT(ptr->l != cpu_to_be64(NULLDFSBNO));
927 923
928 return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l)); 924 return XFS_FSB_TO_DADDR(cur->bc_mp, be64_to_cpu(ptr->l));
929 } else { 925 } else {
930 ASSERT(cur->bc_private.a.agno != NULLAGNUMBER); 926 ASSERT(cur->bc_private.a.agno != NULLAGNUMBER);
931 ASSERT(be32_to_cpu(ptr->s) != NULLAGBLOCK); 927 ASSERT(ptr->s != cpu_to_be32(NULLAGBLOCK));
932 928
933 return XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno, 929 return XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno,
934 be32_to_cpu(ptr->s)); 930 be32_to_cpu(ptr->s));
@@ -974,8 +970,7 @@ xfs_btree_get_buf_block(
974 *bpp = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d, 970 *bpp = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d,
975 mp->m_bsize, flags); 971 mp->m_bsize, flags);
976 972
977 ASSERT(*bpp); 973 ASSERT(!xfs_buf_geterror(*bpp));
978 ASSERT(!XFS_BUF_GETERROR(*bpp));
979 974
980 *block = XFS_BUF_TO_BLOCK(*bpp); 975 *block = XFS_BUF_TO_BLOCK(*bpp);
981 return 0; 976 return 0;
@@ -1007,8 +1002,7 @@ xfs_btree_read_buf_block(
1007 if (error) 1002 if (error)
1008 return error; 1003 return error;
1009 1004
1010 ASSERT(*bpp != NULL); 1005 ASSERT(!xfs_buf_geterror(*bpp));
1011 ASSERT(!XFS_BUF_GETERROR(*bpp));
1012 1006
1013 xfs_btree_set_refs(cur, *bpp); 1007 xfs_btree_set_refs(cur, *bpp);
1014 *block = XFS_BUF_TO_BLOCK(*bpp); 1008 *block = XFS_BUF_TO_BLOCK(*bpp);
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 82fafc66bd1..5b240de104c 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -199,25 +199,6 @@ struct xfs_btree_ops {
199 union xfs_btree_rec *r1, 199 union xfs_btree_rec *r1,
200 union xfs_btree_rec *r2); 200 union xfs_btree_rec *r2);
201#endif 201#endif
202
203 /* btree tracing */
204#ifdef XFS_BTREE_TRACE
205 void (*trace_enter)(struct xfs_btree_cur *, const char *,
206 char *, int, int, __psunsigned_t,
207 __psunsigned_t, __psunsigned_t,
208 __psunsigned_t, __psunsigned_t,
209 __psunsigned_t, __psunsigned_t,
210 __psunsigned_t, __psunsigned_t,
211 __psunsigned_t, __psunsigned_t);
212 void (*trace_cursor)(struct xfs_btree_cur *, __uint32_t *,
213 __uint64_t *, __uint64_t *);
214 void (*trace_key)(struct xfs_btree_cur *,
215 union xfs_btree_key *, __uint64_t *,
216 __uint64_t *);
217 void (*trace_record)(struct xfs_btree_cur *,
218 union xfs_btree_rec *, __uint64_t *,
219 __uint64_t *, __uint64_t *);
220#endif
221}; 202};
222 203
223/* 204/*
@@ -281,7 +262,7 @@ typedef struct xfs_btree_cur
281/* 262/*
282 * Convert from buffer to btree block header. 263 * Convert from buffer to btree block header.
283 */ 264 */
284#define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)XFS_BUF_PTR(bp)) 265#define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr))
285 266
286 267
287/* 268/*
@@ -452,4 +433,23 @@ static inline int xfs_btree_get_level(struct xfs_btree_block *block)
452 (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \ 433 (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \
453 XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks) 434 XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks)
454 435
436/*
437 * Trace hooks. Currently not implemented as they need to be ported
438 * over to the generic tracing functionality, which is some effort.
439 *
440 * i,j = integer (32 bit)
441 * b = btree block buffer (xfs_buf_t)
442 * p = btree ptr
443 * r = btree record
444 * k = btree key
445 */
446#define XFS_BTREE_TRACE_ARGBI(c, b, i)
447#define XFS_BTREE_TRACE_ARGBII(c, b, i, j)
448#define XFS_BTREE_TRACE_ARGI(c, i)
449#define XFS_BTREE_TRACE_ARGIPK(c, i, p, s)
450#define XFS_BTREE_TRACE_ARGIPR(c, i, p, r)
451#define XFS_BTREE_TRACE_ARGIK(c, i, k)
452#define XFS_BTREE_TRACE_ARGR(c, r)
453#define XFS_BTREE_TRACE_CURSOR(c, t)
454
455#endif /* __XFS_BTREE_H__ */ 455#endif /* __XFS_BTREE_H__ */
diff --git a/fs/xfs/xfs_btree_trace.c b/fs/xfs/xfs_btree_trace.c
deleted file mode 100644
index 44ff942a0fd..00000000000
--- a/fs/xfs/xfs_btree_trace.c
+++ /dev/null
@@ -1,249 +0,0 @@
1/*
2 * Copyright (c) 2008 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#include "xfs.h"
19#include "xfs_types.h"
20#include "xfs_inum.h"
21#include "xfs_bmap_btree.h"
22#include "xfs_alloc_btree.h"
23#include "xfs_ialloc_btree.h"
24#include "xfs_inode.h"
25#include "xfs_btree.h"
26#include "xfs_btree_trace.h"
27
28STATIC void
29xfs_btree_trace_ptr(
30 struct xfs_btree_cur *cur,
31 union xfs_btree_ptr ptr,
32 __psunsigned_t *high,
33 __psunsigned_t *low)
34{
35 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
36 __u64 val = be64_to_cpu(ptr.l);
37 *high = val >> 32;
38 *low = (int)val;
39 } else {
40 *high = 0;
41 *low = be32_to_cpu(ptr.s);
42 }
43}
44
45/*
46 * Add a trace buffer entry for arguments, for a buffer & 1 integer arg.
47 */
48void
49xfs_btree_trace_argbi(
50 const char *func,
51 struct xfs_btree_cur *cur,
52 struct xfs_buf *b,
53 int i,
54 int line)
55{
56 cur->bc_ops->trace_enter(cur, func, XBT_ARGS, XFS_BTREE_KTRACE_ARGBI,
57 line, (__psunsigned_t)b, i, 0, 0, 0, 0, 0,
58 0, 0, 0, 0);
59}
60
61/*
62 * Add a trace buffer entry for arguments, for a buffer & 2 integer args.
63 */
64void
65xfs_btree_trace_argbii(
66 const char *func,
67 struct xfs_btree_cur *cur,
68 struct xfs_buf *b,
69 int i0,
70 int i1,
71 int line)
72{
73 cur->bc_ops->trace_enter(cur, func, XBT_ARGS, XFS_BTREE_KTRACE_ARGBII,
74 line, (__psunsigned_t)b, i0, i1, 0, 0, 0, 0,
75 0, 0, 0, 0);
76}
77
78/*
79 * Add a trace buffer entry for arguments, for 3 block-length args
80 * and an integer arg.
81 */
82void
83xfs_btree_trace_argfffi(
84 const char *func,
85 struct xfs_btree_cur *cur,
86 xfs_dfiloff_t o,
87 xfs_dfsbno_t b,
88 xfs_dfilblks_t i,
89 int j,
90 int line)
91{
92 cur->bc_ops->trace_enter(cur, func, XBT_ARGS, XFS_BTREE_KTRACE_ARGFFFI,
93 line,
94 o >> 32, (int)o,
95 b >> 32, (int)b,
96 i >> 32, (int)i,
97 (int)j, 0, 0, 0, 0);
98}
99
100/*
101 * Add a trace buffer entry for arguments, for one integer arg.
102 */
103void
104xfs_btree_trace_argi(
105 const char *func,
106 struct xfs_btree_cur *cur,
107 int i,
108 int line)
109{
110 cur->bc_ops->trace_enter(cur, func, XBT_ARGS, XFS_BTREE_KTRACE_ARGI,
111 line, i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
112}
113
114/*
115 * Add a trace buffer entry for arguments, for int, fsblock, key.
116 */
117void
118xfs_btree_trace_argipk(
119 const char *func,
120 struct xfs_btree_cur *cur,
121 int i,
122 union xfs_btree_ptr ptr,
123 union xfs_btree_key *key,
124 int line)
125{
126 __psunsigned_t high, low;
127 __uint64_t l0, l1;
128
129 xfs_btree_trace_ptr(cur, ptr, &high, &low);
130 cur->bc_ops->trace_key(cur, key, &l0, &l1);
131 cur->bc_ops->trace_enter(cur, func, XBT_ARGS, XFS_BTREE_KTRACE_ARGIPK,
132 line, i, high, low,
133 l0 >> 32, (int)l0,
134 l1 >> 32, (int)l1,
135 0, 0, 0, 0);
136}
137
138/*
139 * Add a trace buffer entry for arguments, for int, fsblock, rec.
140 */
141void
142xfs_btree_trace_argipr(
143 const char *func,
144 struct xfs_btree_cur *cur,
145 int i,
146 union xfs_btree_ptr ptr,
147 union xfs_btree_rec *rec,
148 int line)
149{
150 __psunsigned_t high, low;
151 __uint64_t l0, l1, l2;
152
153 xfs_btree_trace_ptr(cur, ptr, &high, &low);
154 cur->bc_ops->trace_record(cur, rec, &l0, &l1, &l2);
155 cur->bc_ops->trace_enter(cur, func, XBT_ARGS, XFS_BTREE_KTRACE_ARGIPR,
156 line, i,
157 high, low,
158 l0 >> 32, (int)l0,
159 l1 >> 32, (int)l1,
160 l2 >> 32, (int)l2,
161 0, 0);
162}
163
164/*
165 * Add a trace buffer entry for arguments, for int, key.
166 */
167void
168xfs_btree_trace_argik(
169 const char *func,
170 struct xfs_btree_cur *cur,
171 int i,
172 union xfs_btree_key *key,
173 int line)
174{
175 __uint64_t l0, l1;
176
177 cur->bc_ops->trace_key(cur, key, &l0, &l1);
178 cur->bc_ops->trace_enter(cur, func, XBT_ARGS, XFS_BTREE_KTRACE_ARGIK,
179 line, i,
180 l0 >> 32, (int)l0,
181 l1 >> 32, (int)l1,
182 0, 0, 0, 0, 0, 0);
183}
184
185/*
186 * Add a trace buffer entry for arguments, for record.
187 */
188void
189xfs_btree_trace_argr(
190 const char *func,
191 struct xfs_btree_cur *cur,
192 union xfs_btree_rec *rec,
193 int line)
194{
195 __uint64_t l0, l1, l2;
196
197 cur->bc_ops->trace_record(cur, rec, &l0, &l1, &l2);
198 cur->bc_ops->trace_enter(cur, func, XBT_ARGS, XFS_BTREE_KTRACE_ARGR,
199 line,
200 l0 >> 32, (int)l0,
201 l1 >> 32, (int)l1,
202 l2 >> 32, (int)l2,
203 0, 0, 0, 0, 0);
204}
205
206/*
207 * Add a trace buffer entry for the cursor/operation.
208 */
209void
210xfs_btree_trace_cursor(
211 const char *func,
212 struct xfs_btree_cur *cur,
213 int type,
214 int line)
215{
216 __uint32_t s0;
217 __uint64_t l0, l1;
218 char *s;
219
220 switch (type) {
221 case XBT_ARGS:
222 s = "args";
223 break;
224 case XBT_ENTRY:
225 s = "entry";
226 break;
227 case XBT_ERROR:
228 s = "error";
229 break;
230 case XBT_EXIT:
231 s = "exit";
232 break;
233 default:
234 s = "unknown";
235 break;
236 }
237
238 cur->bc_ops->trace_cursor(cur, &s0, &l0, &l1);
239 cur->bc_ops->trace_enter(cur, func, s, XFS_BTREE_KTRACE_CUR, line,
240 s0,
241 l0 >> 32, (int)l0,
242 l1 >> 32, (int)l1,
243 (__psunsigned_t)cur->bc_bufs[0],
244 (__psunsigned_t)cur->bc_bufs[1],
245 (__psunsigned_t)cur->bc_bufs[2],
246 (__psunsigned_t)cur->bc_bufs[3],
247 (cur->bc_ptrs[0] << 16) | cur->bc_ptrs[1],
248 (cur->bc_ptrs[2] << 16) | cur->bc_ptrs[3]);
249}
diff --git a/fs/xfs/xfs_btree_trace.h b/fs/xfs/xfs_btree_trace.h
deleted file mode 100644
index 2d8a309873e..00000000000
--- a/fs/xfs/xfs_btree_trace.h
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * Copyright (c) 2008 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_BTREE_TRACE_H__
19#define __XFS_BTREE_TRACE_H__
20
21struct xfs_btree_cur;
22struct xfs_buf;
23
24
25/*
26 * Trace hooks.
27 * i,j = integer (32 bit)
28 * b = btree block buffer (xfs_buf_t)
29 * p = btree ptr
30 * r = btree record
31 * k = btree key
32 */
33
34#ifdef XFS_BTREE_TRACE
35
36/*
37 * Trace buffer entry types.
38 */
39#define XFS_BTREE_KTRACE_ARGBI 1
40#define XFS_BTREE_KTRACE_ARGBII 2
41#define XFS_BTREE_KTRACE_ARGFFFI 3
42#define XFS_BTREE_KTRACE_ARGI 4
43#define XFS_BTREE_KTRACE_ARGIPK 5
44#define XFS_BTREE_KTRACE_ARGIPR 6
45#define XFS_BTREE_KTRACE_ARGIK 7
46#define XFS_BTREE_KTRACE_ARGR 8
47#define XFS_BTREE_KTRACE_CUR 9
48
49/*
50 * Sub-types for cursor traces.
51 */
52#define XBT_ARGS 0
53#define XBT_ENTRY 1
54#define XBT_ERROR 2
55#define XBT_EXIT 3
56
57void xfs_btree_trace_argbi(const char *, struct xfs_btree_cur *,
58 struct xfs_buf *, int, int);
59void xfs_btree_trace_argbii(const char *, struct xfs_btree_cur *,
60 struct xfs_buf *, int, int, int);
61void xfs_btree_trace_argi(const char *, struct xfs_btree_cur *, int, int);
62void xfs_btree_trace_argipk(const char *, struct xfs_btree_cur *, int,
63 union xfs_btree_ptr, union xfs_btree_key *, int);
64void xfs_btree_trace_argipr(const char *, struct xfs_btree_cur *, int,
65 union xfs_btree_ptr, union xfs_btree_rec *, int);
66void xfs_btree_trace_argik(const char *, struct xfs_btree_cur *, int,
67 union xfs_btree_key *, int);
68void xfs_btree_trace_argr(const char *, struct xfs_btree_cur *,
69 union xfs_btree_rec *, int);
70void xfs_btree_trace_cursor(const char *, struct xfs_btree_cur *, int, int);
71
72#define XFS_BTREE_TRACE_ARGBI(c, b, i) \
73 xfs_btree_trace_argbi(__func__, c, b, i, __LINE__)
74#define XFS_BTREE_TRACE_ARGBII(c, b, i, j) \
75 xfs_btree_trace_argbii(__func__, c, b, i, j, __LINE__)
76#define XFS_BTREE_TRACE_ARGI(c, i) \
77 xfs_btree_trace_argi(__func__, c, i, __LINE__)
78#define XFS_BTREE_TRACE_ARGIPK(c, i, p, k) \
79 xfs_btree_trace_argipk(__func__, c, i, p, k, __LINE__)
80#define XFS_BTREE_TRACE_ARGIPR(c, i, p, r) \
81 xfs_btree_trace_argipr(__func__, c, i, p, r, __LINE__)
82#define XFS_BTREE_TRACE_ARGIK(c, i, k) \
83 xfs_btree_trace_argik(__func__, c, i, k, __LINE__)
84#define XFS_BTREE_TRACE_ARGR(c, r) \
85 xfs_btree_trace_argr(__func__, c, r, __LINE__)
86#define XFS_BTREE_TRACE_CURSOR(c, t) \
87 xfs_btree_trace_cursor(__func__, c, t, __LINE__)
88#else
89#define XFS_BTREE_TRACE_ARGBI(c, b, i)
90#define XFS_BTREE_TRACE_ARGBII(c, b, i, j)
91#define XFS_BTREE_TRACE_ARGI(c, i)
92#define XFS_BTREE_TRACE_ARGIPK(c, i, p, s)
93#define XFS_BTREE_TRACE_ARGIPR(c, i, p, r)
94#define XFS_BTREE_TRACE_ARGIK(c, i, k)
95#define XFS_BTREE_TRACE_ARGR(c, r)
96#define XFS_BTREE_TRACE_CURSOR(c, t)
97#endif /* XFS_BTREE_TRACE */
98
99#endif /* __XFS_BTREE_TRACE_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/xfs_buf.c
index 5e68099db2a..c57836dc778 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -499,16 +499,14 @@ found:
499 spin_unlock(&pag->pag_buf_lock); 499 spin_unlock(&pag->pag_buf_lock);
500 xfs_perag_put(pag); 500 xfs_perag_put(pag);
501 501
502 if (xfs_buf_cond_lock(bp)) { 502 if (!xfs_buf_trylock(bp)) {
503 /* failed, so wait for the lock if requested. */ 503 if (flags & XBF_TRYLOCK) {
504 if (!(flags & XBF_TRYLOCK)) {
505 xfs_buf_lock(bp);
506 XFS_STATS_INC(xb_get_locked_waited);
507 } else {
508 xfs_buf_rele(bp); 504 xfs_buf_rele(bp);
509 XFS_STATS_INC(xb_busy_locked); 505 XFS_STATS_INC(xb_busy_locked);
510 return NULL; 506 return NULL;
511 } 507 }
508 xfs_buf_lock(bp);
509 XFS_STATS_INC(xb_get_locked_waited);
512 } 510 }
513 511
514 /* 512 /*
@@ -594,13 +592,11 @@ _xfs_buf_read(
594 ASSERT(!(flags & (XBF_DELWRI|XBF_WRITE))); 592 ASSERT(!(flags & (XBF_DELWRI|XBF_WRITE)));
595 ASSERT(bp->b_bn != XFS_BUF_DADDR_NULL); 593 ASSERT(bp->b_bn != XFS_BUF_DADDR_NULL);
596 594
597 bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_DELWRI | \ 595 bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_DELWRI | XBF_READ_AHEAD);
598 XBF_READ_AHEAD | _XBF_RUN_QUEUES); 596 bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD);
599 bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | \
600 XBF_READ_AHEAD | _XBF_RUN_QUEUES);
601 597
602 status = xfs_buf_iorequest(bp); 598 status = xfs_buf_iorequest(bp);
603 if (status || XFS_BUF_ISERROR(bp) || (flags & XBF_ASYNC)) 599 if (status || bp->b_error || (flags & XBF_ASYNC))
604 return status; 600 return status;
605 return xfs_buf_iowait(bp); 601 return xfs_buf_iowait(bp);
606} 602}
@@ -681,10 +677,8 @@ xfs_buf_read_uncached(
681 return NULL; 677 return NULL;
682 678
683 /* set up the buffer for a read IO */ 679 /* set up the buffer for a read IO */
684 xfs_buf_lock(bp);
685 XFS_BUF_SET_ADDR(bp, daddr); 680 XFS_BUF_SET_ADDR(bp, daddr);
686 XFS_BUF_READ(bp); 681 XFS_BUF_READ(bp);
687 XFS_BUF_BUSY(bp);
688 682
689 xfsbdstrat(mp, bp); 683 xfsbdstrat(mp, bp);
690 error = xfs_buf_iowait(bp); 684 error = xfs_buf_iowait(bp);
@@ -816,8 +810,6 @@ xfs_buf_get_uncached(
816 goto fail_free_mem; 810 goto fail_free_mem;
817 } 811 }
818 812
819 xfs_buf_unlock(bp);
820
821 trace_xfs_buf_get_uncached(bp, _RET_IP_); 813 trace_xfs_buf_get_uncached(bp, _RET_IP_);
822 return bp; 814 return bp;
823 815
@@ -896,8 +888,8 @@ xfs_buf_rele(
896 * to push on stale inode buffers. 888 * to push on stale inode buffers.
897 */ 889 */
898int 890int
899xfs_buf_cond_lock( 891xfs_buf_trylock(
900 xfs_buf_t *bp) 892 struct xfs_buf *bp)
901{ 893{
902 int locked; 894 int locked;
903 895
@@ -907,15 +899,8 @@ xfs_buf_cond_lock(
907 else if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE)) 899 else if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE))
908 xfs_log_force(bp->b_target->bt_mount, 0); 900 xfs_log_force(bp->b_target->bt_mount, 0);
909 901
910 trace_xfs_buf_cond_lock(bp, _RET_IP_); 902 trace_xfs_buf_trylock(bp, _RET_IP_);
911 return locked ? 0 : -EBUSY; 903 return locked;
912}
913
914int
915xfs_buf_lock_value(
916 xfs_buf_t *bp)
917{
918 return bp->b_sema.count;
919} 904}
920 905
921/* 906/*
@@ -929,7 +914,7 @@ xfs_buf_lock_value(
929 */ 914 */
930void 915void
931xfs_buf_lock( 916xfs_buf_lock(
932 xfs_buf_t *bp) 917 struct xfs_buf *bp)
933{ 918{
934 trace_xfs_buf_lock(bp, _RET_IP_); 919 trace_xfs_buf_lock(bp, _RET_IP_);
935 920
@@ -950,7 +935,7 @@ xfs_buf_lock(
950 */ 935 */
951void 936void
952xfs_buf_unlock( 937xfs_buf_unlock(
953 xfs_buf_t *bp) 938 struct xfs_buf *bp)
954{ 939{
955 if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) { 940 if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) {
956 atomic_inc(&bp->b_hold); 941 atomic_inc(&bp->b_hold);
@@ -1083,7 +1068,7 @@ xfs_bioerror(
1083 /* 1068 /*
1084 * No need to wait until the buffer is unpinned, we aren't flushing it. 1069 * No need to wait until the buffer is unpinned, we aren't flushing it.
1085 */ 1070 */
1086 XFS_BUF_ERROR(bp, EIO); 1071 xfs_buf_ioerror(bp, EIO);
1087 1072
1088 /* 1073 /*
1089 * We're calling xfs_buf_ioend, so delete XBF_DONE flag. 1074 * We're calling xfs_buf_ioend, so delete XBF_DONE flag.
@@ -1108,7 +1093,7 @@ STATIC int
1108xfs_bioerror_relse( 1093xfs_bioerror_relse(
1109 struct xfs_buf *bp) 1094 struct xfs_buf *bp)
1110{ 1095{
1111 int64_t fl = XFS_BUF_BFLAGS(bp); 1096 int64_t fl = bp->b_flags;
1112 /* 1097 /*
1113 * No need to wait until the buffer is unpinned. 1098 * No need to wait until the buffer is unpinned.
1114 * We aren't flushing it. 1099 * We aren't flushing it.
@@ -1121,7 +1106,7 @@ xfs_bioerror_relse(
1121 XFS_BUF_UNDELAYWRITE(bp); 1106 XFS_BUF_UNDELAYWRITE(bp);
1122 XFS_BUF_DONE(bp); 1107 XFS_BUF_DONE(bp);
1123 XFS_BUF_STALE(bp); 1108 XFS_BUF_STALE(bp);
1124 XFS_BUF_CLR_IODONE_FUNC(bp); 1109 bp->b_iodone = NULL;
1125 if (!(fl & XBF_ASYNC)) { 1110 if (!(fl & XBF_ASYNC)) {
1126 /* 1111 /*
1127 * Mark b_error and B_ERROR _both_. 1112 * Mark b_error and B_ERROR _both_.
@@ -1129,7 +1114,7 @@ xfs_bioerror_relse(
1129 * There's no reason to mark error for 1114 * There's no reason to mark error for
1130 * ASYNC buffers. 1115 * ASYNC buffers.
1131 */ 1116 */
1132 XFS_BUF_ERROR(bp, EIO); 1117 xfs_buf_ioerror(bp, EIO);
1133 XFS_BUF_FINISH_IOWAIT(bp); 1118 XFS_BUF_FINISH_IOWAIT(bp);
1134 } else { 1119 } else {
1135 xfs_buf_relse(bp); 1120 xfs_buf_relse(bp);
@@ -1223,22 +1208,23 @@ _xfs_buf_ioapply(
1223 total_nr_pages = bp->b_page_count; 1208 total_nr_pages = bp->b_page_count;
1224 map_i = 0; 1209 map_i = 0;
1225 1210
1226 if (bp->b_flags & XBF_ORDERED) { 1211 if (bp->b_flags & XBF_WRITE) {
1227 ASSERT(!(bp->b_flags & XBF_READ)); 1212 if (bp->b_flags & XBF_SYNCIO)
1228 rw = WRITE_FLUSH_FUA; 1213 rw = WRITE_SYNC;
1229 } else if (bp->b_flags & XBF_LOG_BUFFER) { 1214 else
1230 ASSERT(!(bp->b_flags & XBF_READ_AHEAD)); 1215 rw = WRITE;
1231 bp->b_flags &= ~_XBF_RUN_QUEUES; 1216 if (bp->b_flags & XBF_FUA)
1232 rw = (bp->b_flags & XBF_WRITE) ? WRITE_SYNC : READ_SYNC; 1217 rw |= REQ_FUA;
1233 } else if (bp->b_flags & _XBF_RUN_QUEUES) { 1218 if (bp->b_flags & XBF_FLUSH)
1234 ASSERT(!(bp->b_flags & XBF_READ_AHEAD)); 1219 rw |= REQ_FLUSH;
1235 bp->b_flags &= ~_XBF_RUN_QUEUES; 1220 } else if (bp->b_flags & XBF_READ_AHEAD) {
1236 rw = (bp->b_flags & XBF_WRITE) ? WRITE_META : READ_META; 1221 rw = READA;
1237 } else { 1222 } else {
1238 rw = (bp->b_flags & XBF_WRITE) ? WRITE : 1223 rw = READ;
1239 (bp->b_flags & XBF_READ_AHEAD) ? READA : READ;
1240 } 1224 }
1241 1225
1226 /* we only use the buffer cache for meta-data */
1227 rw |= REQ_META;
1242 1228
1243next_chunk: 1229next_chunk:
1244 atomic_inc(&bp->b_io_remaining); 1230 atomic_inc(&bp->b_io_remaining);
@@ -1337,7 +1323,7 @@ xfs_buf_offset(
1337 struct page *page; 1323 struct page *page;
1338 1324
1339 if (bp->b_flags & XBF_MAPPED) 1325 if (bp->b_flags & XBF_MAPPED)
1340 return XFS_BUF_PTR(bp) + offset; 1326 return bp->b_addr + offset;
1341 1327
1342 offset += bp->b_offset; 1328 offset += bp->b_offset;
1343 page = bp->b_pages[offset >> PAGE_SHIFT]; 1329 page = bp->b_pages[offset >> PAGE_SHIFT];
@@ -1497,7 +1483,7 @@ xfs_setsize_buftarg_flags(
1497 if (set_blocksize(btp->bt_bdev, sectorsize)) { 1483 if (set_blocksize(btp->bt_bdev, sectorsize)) {
1498 xfs_warn(btp->bt_mount, 1484 xfs_warn(btp->bt_mount,
1499 "Cannot set_blocksize to %u on device %s\n", 1485 "Cannot set_blocksize to %u on device %s\n",
1500 sectorsize, XFS_BUFTARG_NAME(btp)); 1486 sectorsize, xfs_buf_target_name(btp));
1501 return EINVAL; 1487 return EINVAL;
1502 } 1488 }
1503 1489
@@ -1694,15 +1680,14 @@ xfs_buf_delwri_split(
1694 list_for_each_entry_safe(bp, n, dwq, b_list) { 1680 list_for_each_entry_safe(bp, n, dwq, b_list) {
1695 ASSERT(bp->b_flags & XBF_DELWRI); 1681 ASSERT(bp->b_flags & XBF_DELWRI);
1696 1682
1697 if (!XFS_BUF_ISPINNED(bp) && !xfs_buf_cond_lock(bp)) { 1683 if (!xfs_buf_ispinned(bp) && xfs_buf_trylock(bp)) {
1698 if (!force && 1684 if (!force &&
1699 time_before(jiffies, bp->b_queuetime + age)) { 1685 time_before(jiffies, bp->b_queuetime + age)) {
1700 xfs_buf_unlock(bp); 1686 xfs_buf_unlock(bp);
1701 break; 1687 break;
1702 } 1688 }
1703 1689
1704 bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q| 1690 bp->b_flags &= ~(XBF_DELWRI | _XBF_DELWRI_Q);
1705 _XBF_RUN_QUEUES);
1706 bp->b_flags |= XBF_WRITE; 1691 bp->b_flags |= XBF_WRITE;
1707 list_move_tail(&bp->b_list, list); 1692 list_move_tail(&bp->b_list, list);
1708 trace_xfs_buf_delwri_split(bp, _RET_IP_); 1693 trace_xfs_buf_delwri_split(bp, _RET_IP_);
@@ -1738,14 +1723,6 @@ xfs_buf_cmp(
1738 return 0; 1723 return 0;
1739} 1724}
1740 1725
1741void
1742xfs_buf_delwri_sort(
1743 xfs_buftarg_t *target,
1744 struct list_head *list)
1745{
1746 list_sort(NULL, list, xfs_buf_cmp);
1747}
1748
1749STATIC int 1726STATIC int
1750xfsbufd( 1727xfsbufd(
1751 void *data) 1728 void *data)
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/xfs_buf.h
index 50a7d5fb3b7..8e8b06b90b6 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -46,43 +46,46 @@ typedef enum {
46 46
47#define XBF_READ (1 << 0) /* buffer intended for reading from device */ 47#define XBF_READ (1 << 0) /* buffer intended for reading from device */
48#define XBF_WRITE (1 << 1) /* buffer intended for writing to device */ 48#define XBF_WRITE (1 << 1) /* buffer intended for writing to device */
49#define XBF_MAPPED (1 << 2) /* buffer mapped (b_addr valid) */ 49#define XBF_READ_AHEAD (1 << 2) /* asynchronous read-ahead */
50#define XBF_MAPPED (1 << 3) /* buffer mapped (b_addr valid) */
50#define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */ 51#define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */
51#define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */ 52#define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */
52#define XBF_DELWRI (1 << 6) /* buffer has dirty pages */ 53#define XBF_DELWRI (1 << 6) /* buffer has dirty pages */
53#define XBF_STALE (1 << 7) /* buffer has been staled, do not find it */ 54#define XBF_STALE (1 << 7) /* buffer has been staled, do not find it */
54#define XBF_ORDERED (1 << 11)/* use ordered writes */ 55
55#define XBF_READ_AHEAD (1 << 12)/* asynchronous read-ahead */ 56/* I/O hints for the BIO layer */
56#define XBF_LOG_BUFFER (1 << 13)/* this is a buffer used for the log */ 57#define XBF_SYNCIO (1 << 10)/* treat this buffer as synchronous I/O */
58#define XBF_FUA (1 << 11)/* force cache write through mode */
59#define XBF_FLUSH (1 << 12)/* flush the disk cache before a write */
57 60
58/* flags used only as arguments to access routines */ 61/* flags used only as arguments to access routines */
59#define XBF_LOCK (1 << 14)/* lock requested */ 62#define XBF_LOCK (1 << 15)/* lock requested */
60#define XBF_TRYLOCK (1 << 15)/* lock requested, but do not wait */ 63#define XBF_TRYLOCK (1 << 16)/* lock requested, but do not wait */
61#define XBF_DONT_BLOCK (1 << 16)/* do not block in current thread */ 64#define XBF_DONT_BLOCK (1 << 17)/* do not block in current thread */
62 65
63/* flags used only internally */ 66/* flags used only internally */
64#define _XBF_PAGES (1 << 18)/* backed by refcounted pages */ 67#define _XBF_PAGES (1 << 20)/* backed by refcounted pages */
65#define _XBF_RUN_QUEUES (1 << 19)/* run block device task queue */ 68#define _XBF_KMEM (1 << 21)/* backed by heap memory */
66#define _XBF_KMEM (1 << 20)/* backed by heap memory */ 69#define _XBF_DELWRI_Q (1 << 22)/* buffer on delwri queue */
67#define _XBF_DELWRI_Q (1 << 21)/* buffer on delwri queue */
68 70
69typedef unsigned int xfs_buf_flags_t; 71typedef unsigned int xfs_buf_flags_t;
70 72
71#define XFS_BUF_FLAGS \ 73#define XFS_BUF_FLAGS \
72 { XBF_READ, "READ" }, \ 74 { XBF_READ, "READ" }, \
73 { XBF_WRITE, "WRITE" }, \ 75 { XBF_WRITE, "WRITE" }, \
76 { XBF_READ_AHEAD, "READ_AHEAD" }, \
74 { XBF_MAPPED, "MAPPED" }, \ 77 { XBF_MAPPED, "MAPPED" }, \
75 { XBF_ASYNC, "ASYNC" }, \ 78 { XBF_ASYNC, "ASYNC" }, \
76 { XBF_DONE, "DONE" }, \ 79 { XBF_DONE, "DONE" }, \
77 { XBF_DELWRI, "DELWRI" }, \ 80 { XBF_DELWRI, "DELWRI" }, \
78 { XBF_STALE, "STALE" }, \ 81 { XBF_STALE, "STALE" }, \
79 { XBF_ORDERED, "ORDERED" }, \ 82 { XBF_SYNCIO, "SYNCIO" }, \
80 { XBF_READ_AHEAD, "READ_AHEAD" }, \ 83 { XBF_FUA, "FUA" }, \
84 { XBF_FLUSH, "FLUSH" }, \
81 { XBF_LOCK, "LOCK" }, /* should never be set */\ 85 { XBF_LOCK, "LOCK" }, /* should never be set */\
82 { XBF_TRYLOCK, "TRYLOCK" }, /* ditto */\ 86 { XBF_TRYLOCK, "TRYLOCK" }, /* ditto */\
83 { XBF_DONT_BLOCK, "DONT_BLOCK" }, /* ditto */\ 87 { XBF_DONT_BLOCK, "DONT_BLOCK" }, /* ditto */\
84 { _XBF_PAGES, "PAGES" }, \ 88 { _XBF_PAGES, "PAGES" }, \
85 { _XBF_RUN_QUEUES, "RUN_QUEUES" }, \
86 { _XBF_KMEM, "KMEM" }, \ 89 { _XBF_KMEM, "KMEM" }, \
87 { _XBF_DELWRI_Q, "DELWRI_Q" } 90 { _XBF_DELWRI_Q, "DELWRI_Q" }
88 91
@@ -91,11 +94,6 @@ typedef enum {
91 XBT_FORCE_FLUSH = 1, 94 XBT_FORCE_FLUSH = 1,
92} xfs_buftarg_flags_t; 95} xfs_buftarg_flags_t;
93 96
94typedef struct xfs_bufhash {
95 struct list_head bh_list;
96 spinlock_t bh_lock;
97} xfs_bufhash_t;
98
99typedef struct xfs_buftarg { 97typedef struct xfs_buftarg {
100 dev_t bt_dev; 98 dev_t bt_dev;
101 struct block_device *bt_bdev; 99 struct block_device *bt_bdev;
@@ -151,7 +149,7 @@ typedef struct xfs_buf {
151 xfs_buf_iodone_t b_iodone; /* I/O completion function */ 149 xfs_buf_iodone_t b_iodone; /* I/O completion function */
152 struct completion b_iowait; /* queue for I/O waiters */ 150 struct completion b_iowait; /* queue for I/O waiters */
153 void *b_fspriv; 151 void *b_fspriv;
154 void *b_fspriv2; 152 struct xfs_trans *b_transp;
155 struct page **b_pages; /* array of page pointers */ 153 struct page **b_pages; /* array of page pointers */
156 struct page *b_page_array[XB_PAGES]; /* inline pages */ 154 struct page *b_page_array[XB_PAGES]; /* inline pages */
157 unsigned long b_queuetime; /* time buffer was queued */ 155 unsigned long b_queuetime; /* time buffer was queued */
@@ -192,10 +190,11 @@ extern void xfs_buf_free(xfs_buf_t *);
192extern void xfs_buf_rele(xfs_buf_t *); 190extern void xfs_buf_rele(xfs_buf_t *);
193 191
194/* Locking and Unlocking Buffers */ 192/* Locking and Unlocking Buffers */
195extern int xfs_buf_cond_lock(xfs_buf_t *); 193extern int xfs_buf_trylock(xfs_buf_t *);
196extern int xfs_buf_lock_value(xfs_buf_t *);
197extern void xfs_buf_lock(xfs_buf_t *); 194extern void xfs_buf_lock(xfs_buf_t *);
198extern void xfs_buf_unlock(xfs_buf_t *); 195extern void xfs_buf_unlock(xfs_buf_t *);
196#define xfs_buf_islocked(bp) \
197 ((bp)->b_sema.count <= 0)
199 198
200/* Buffer Read and Write Routines */ 199/* Buffer Read and Write Routines */
201extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); 200extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
@@ -229,13 +228,18 @@ extern void xfs_buf_delwri_promote(xfs_buf_t *);
229extern int xfs_buf_init(void); 228extern int xfs_buf_init(void);
230extern void xfs_buf_terminate(void); 229extern void xfs_buf_terminate(void);
231 230
232#define xfs_buf_target_name(target) \ 231static inline const char *
233 ({ char __b[BDEVNAME_SIZE]; bdevname((target)->bt_bdev, __b); __b; }) 232xfs_buf_target_name(struct xfs_buftarg *target)
233{
234 static char __b[BDEVNAME_SIZE];
235
236 return bdevname(target->bt_bdev, __b);
237}
234 238
235 239
236#define XFS_BUF_BFLAGS(bp) ((bp)->b_flags) 240#define XFS_BUF_ZEROFLAGS(bp) \
237#define XFS_BUF_ZEROFLAGS(bp) ((bp)->b_flags &= \ 241 ((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI| \
238 ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI|XBF_ORDERED)) 242 XBF_SYNCIO|XBF_FUA|XBF_FLUSH))
239 243
240void xfs_buf_stale(struct xfs_buf *bp); 244void xfs_buf_stale(struct xfs_buf *bp);
241#define XFS_BUF_STALE(bp) xfs_buf_stale(bp); 245#define XFS_BUF_STALE(bp) xfs_buf_stale(bp);
@@ -251,27 +255,14 @@ void xfs_buf_stale(struct xfs_buf *bp);
251#define XFS_BUF_UNDELAYWRITE(bp) xfs_buf_delwri_dequeue(bp) 255#define XFS_BUF_UNDELAYWRITE(bp) xfs_buf_delwri_dequeue(bp)
252#define XFS_BUF_ISDELAYWRITE(bp) ((bp)->b_flags & XBF_DELWRI) 256#define XFS_BUF_ISDELAYWRITE(bp) ((bp)->b_flags & XBF_DELWRI)
253 257
254#define XFS_BUF_ERROR(bp,no) xfs_buf_ioerror(bp,no)
255#define XFS_BUF_GETERROR(bp) xfs_buf_geterror(bp)
256#define XFS_BUF_ISERROR(bp) (xfs_buf_geterror(bp) ? 1 : 0)
257
258#define XFS_BUF_DONE(bp) ((bp)->b_flags |= XBF_DONE) 258#define XFS_BUF_DONE(bp) ((bp)->b_flags |= XBF_DONE)
259#define XFS_BUF_UNDONE(bp) ((bp)->b_flags &= ~XBF_DONE) 259#define XFS_BUF_UNDONE(bp) ((bp)->b_flags &= ~XBF_DONE)
260#define XFS_BUF_ISDONE(bp) ((bp)->b_flags & XBF_DONE) 260#define XFS_BUF_ISDONE(bp) ((bp)->b_flags & XBF_DONE)
261 261
262#define XFS_BUF_BUSY(bp) do { } while (0)
263#define XFS_BUF_UNBUSY(bp) do { } while (0)
264#define XFS_BUF_ISBUSY(bp) (1)
265
266#define XFS_BUF_ASYNC(bp) ((bp)->b_flags |= XBF_ASYNC) 262#define XFS_BUF_ASYNC(bp) ((bp)->b_flags |= XBF_ASYNC)
267#define XFS_BUF_UNASYNC(bp) ((bp)->b_flags &= ~XBF_ASYNC) 263#define XFS_BUF_UNASYNC(bp) ((bp)->b_flags &= ~XBF_ASYNC)
268#define XFS_BUF_ISASYNC(bp) ((bp)->b_flags & XBF_ASYNC) 264#define XFS_BUF_ISASYNC(bp) ((bp)->b_flags & XBF_ASYNC)
269 265
270#define XFS_BUF_ORDERED(bp) ((bp)->b_flags |= XBF_ORDERED)
271#define XFS_BUF_UNORDERED(bp) ((bp)->b_flags &= ~XBF_ORDERED)
272#define XFS_BUF_ISORDERED(bp) ((bp)->b_flags & XBF_ORDERED)
273
274#define XFS_BUF_HOLD(bp) xfs_buf_hold(bp)
275#define XFS_BUF_READ(bp) ((bp)->b_flags |= XBF_READ) 266#define XFS_BUF_READ(bp) ((bp)->b_flags |= XBF_READ)
276#define XFS_BUF_UNREAD(bp) ((bp)->b_flags &= ~XBF_READ) 267#define XFS_BUF_UNREAD(bp) ((bp)->b_flags &= ~XBF_READ)
277#define XFS_BUF_ISREAD(bp) ((bp)->b_flags & XBF_READ) 268#define XFS_BUF_ISREAD(bp) ((bp)->b_flags & XBF_READ)
@@ -280,18 +271,6 @@ void xfs_buf_stale(struct xfs_buf *bp);
280#define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) 271#define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE)
281#define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) 272#define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE)
282 273
283#define XFS_BUF_IODONE_FUNC(bp) ((bp)->b_iodone)
284#define XFS_BUF_SET_IODONE_FUNC(bp, func) ((bp)->b_iodone = (func))
285#define XFS_BUF_CLR_IODONE_FUNC(bp) ((bp)->b_iodone = NULL)
286
287#define XFS_BUF_FSPRIVATE(bp, type) ((type)(bp)->b_fspriv)
288#define XFS_BUF_SET_FSPRIVATE(bp, val) ((bp)->b_fspriv = (void*)(val))
289#define XFS_BUF_FSPRIVATE2(bp, type) ((type)(bp)->b_fspriv2)
290#define XFS_BUF_SET_FSPRIVATE2(bp, val) ((bp)->b_fspriv2 = (void*)(val))
291#define XFS_BUF_SET_START(bp) do { } while (0)
292
293#define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->b_addr)
294#define XFS_BUF_SET_PTR(bp, val, cnt) xfs_buf_associate_memory(bp, val, cnt)
295#define XFS_BUF_ADDR(bp) ((bp)->b_bn) 274#define XFS_BUF_ADDR(bp) ((bp)->b_bn)
296#define XFS_BUF_SET_ADDR(bp, bno) ((bp)->b_bn = (xfs_daddr_t)(bno)) 275#define XFS_BUF_SET_ADDR(bp, bno) ((bp)->b_bn = (xfs_daddr_t)(bno))
297#define XFS_BUF_OFFSET(bp) ((bp)->b_file_offset) 276#define XFS_BUF_OFFSET(bp) ((bp)->b_file_offset)
@@ -311,18 +290,13 @@ xfs_buf_set_ref(
311#define XFS_BUF_SET_VTYPE_REF(bp, type, ref) xfs_buf_set_ref(bp, ref) 290#define XFS_BUF_SET_VTYPE_REF(bp, type, ref) xfs_buf_set_ref(bp, ref)
312#define XFS_BUF_SET_VTYPE(bp, type) do { } while (0) 291#define XFS_BUF_SET_VTYPE(bp, type) do { } while (0)
313 292
314#define XFS_BUF_ISPINNED(bp) atomic_read(&((bp)->b_pin_count)) 293static inline int xfs_buf_ispinned(struct xfs_buf *bp)
294{
295 return atomic_read(&bp->b_pin_count);
296}
315 297
316#define XFS_BUF_VALUSEMA(bp) xfs_buf_lock_value(bp)
317#define XFS_BUF_CPSEMA(bp) (xfs_buf_cond_lock(bp) == 0)
318#define XFS_BUF_VSEMA(bp) xfs_buf_unlock(bp)
319#define XFS_BUF_PSEMA(bp,x) xfs_buf_lock(bp)
320#define XFS_BUF_FINISH_IOWAIT(bp) complete(&bp->b_iowait); 298#define XFS_BUF_FINISH_IOWAIT(bp) complete(&bp->b_iowait);
321 299
322#define XFS_BUF_SET_TARGET(bp, target) ((bp)->b_target = (target))
323#define XFS_BUF_TARGET(bp) ((bp)->b_target)
324#define XFS_BUFTARG_NAME(target) xfs_buf_target_name(target)
325
326static inline void xfs_buf_relse(xfs_buf_t *bp) 300static inline void xfs_buf_relse(xfs_buf_t *bp)
327{ 301{
328 xfs_buf_unlock(bp); 302 xfs_buf_unlock(bp);
@@ -346,7 +320,6 @@ extern struct list_head *xfs_get_buftarg_list(void);
346#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev) 320#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev)
347#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev) 321#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)
348 322
349#define xfs_binval(buftarg) xfs_flush_buftarg(buftarg, 1)
350#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg, 1) 323#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg, 1)
351 324
352#endif /* __XFS_BUF_H__ */ 325#endif /* __XFS_BUF_H__ */
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 7b7e005e3dc..ef43fce519a 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -90,13 +90,11 @@ xfs_buf_item_flush_log_debug(
90 uint first, 90 uint first,
91 uint last) 91 uint last)
92{ 92{
93 xfs_buf_log_item_t *bip; 93 xfs_buf_log_item_t *bip = bp->b_fspriv;
94 uint nbytes; 94 uint nbytes;
95 95
96 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*); 96 if (bip == NULL || (bip->bli_item.li_type != XFS_LI_BUF))
97 if ((bip == NULL) || (bip->bli_item.li_type != XFS_LI_BUF)) {
98 return; 97 return;
99 }
100 98
101 ASSERT(bip->bli_logged != NULL); 99 ASSERT(bip->bli_logged != NULL);
102 nbytes = last - first + 1; 100 nbytes = last - first + 1;
@@ -126,9 +124,9 @@ xfs_buf_item_log_check(
126 124
127 bp = bip->bli_buf; 125 bp = bip->bli_buf;
128 ASSERT(XFS_BUF_COUNT(bp) > 0); 126 ASSERT(XFS_BUF_COUNT(bp) > 0);
129 ASSERT(XFS_BUF_PTR(bp) != NULL); 127 ASSERT(bp->b_addr != NULL);
130 orig = bip->bli_orig; 128 orig = bip->bli_orig;
131 buffer = XFS_BUF_PTR(bp); 129 buffer = bp->b_addr;
132 for (x = 0; x < XFS_BUF_COUNT(bp); x++) { 130 for (x = 0; x < XFS_BUF_COUNT(bp); x++) {
133 if (orig[x] != buffer[x] && !btst(bip->bli_logged, x)) { 131 if (orig[x] != buffer[x] && !btst(bip->bli_logged, x)) {
134 xfs_emerg(bp->b_mount, 132 xfs_emerg(bp->b_mount,
@@ -373,7 +371,6 @@ xfs_buf_item_pin(
373{ 371{
374 struct xfs_buf_log_item *bip = BUF_ITEM(lip); 372 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
375 373
376 ASSERT(XFS_BUF_ISBUSY(bip->bli_buf));
377 ASSERT(atomic_read(&bip->bli_refcount) > 0); 374 ASSERT(atomic_read(&bip->bli_refcount) > 0);
378 ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || 375 ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
379 (bip->bli_flags & XFS_BLI_STALE)); 376 (bip->bli_flags & XFS_BLI_STALE));
@@ -408,7 +405,7 @@ xfs_buf_item_unpin(
408 int stale = bip->bli_flags & XFS_BLI_STALE; 405 int stale = bip->bli_flags & XFS_BLI_STALE;
409 int freed; 406 int freed;
410 407
411 ASSERT(XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *) == bip); 408 ASSERT(bp->b_fspriv == bip);
412 ASSERT(atomic_read(&bip->bli_refcount) > 0); 409 ASSERT(atomic_read(&bip->bli_refcount) > 0);
413 410
414 trace_xfs_buf_item_unpin(bip); 411 trace_xfs_buf_item_unpin(bip);
@@ -420,7 +417,7 @@ xfs_buf_item_unpin(
420 417
421 if (freed && stale) { 418 if (freed && stale) {
422 ASSERT(bip->bli_flags & XFS_BLI_STALE); 419 ASSERT(bip->bli_flags & XFS_BLI_STALE);
423 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); 420 ASSERT(xfs_buf_islocked(bp));
424 ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); 421 ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
425 ASSERT(XFS_BUF_ISSTALE(bp)); 422 ASSERT(XFS_BUF_ISSTALE(bp));
426 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); 423 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);
@@ -443,7 +440,7 @@ xfs_buf_item_unpin(
443 * Since the transaction no longer refers to the buffer, 440 * Since the transaction no longer refers to the buffer,
444 * the buffer should no longer refer to the transaction. 441 * the buffer should no longer refer to the transaction.
445 */ 442 */
446 XFS_BUF_SET_FSPRIVATE2(bp, NULL); 443 bp->b_transp = NULL;
447 } 444 }
448 445
449 /* 446 /*
@@ -454,13 +451,13 @@ xfs_buf_item_unpin(
454 */ 451 */
455 if (bip->bli_flags & XFS_BLI_STALE_INODE) { 452 if (bip->bli_flags & XFS_BLI_STALE_INODE) {
456 xfs_buf_do_callbacks(bp); 453 xfs_buf_do_callbacks(bp);
457 XFS_BUF_SET_FSPRIVATE(bp, NULL); 454 bp->b_fspriv = NULL;
458 XFS_BUF_CLR_IODONE_FUNC(bp); 455 bp->b_iodone = NULL;
459 } else { 456 } else {
460 spin_lock(&ailp->xa_lock); 457 spin_lock(&ailp->xa_lock);
461 xfs_trans_ail_delete(ailp, (xfs_log_item_t *)bip); 458 xfs_trans_ail_delete(ailp, (xfs_log_item_t *)bip);
462 xfs_buf_item_relse(bp); 459 xfs_buf_item_relse(bp);
463 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL); 460 ASSERT(bp->b_fspriv == NULL);
464 } 461 }
465 xfs_buf_relse(bp); 462 xfs_buf_relse(bp);
466 } 463 }
@@ -481,13 +478,13 @@ xfs_buf_item_trylock(
481 struct xfs_buf_log_item *bip = BUF_ITEM(lip); 478 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
482 struct xfs_buf *bp = bip->bli_buf; 479 struct xfs_buf *bp = bip->bli_buf;
483 480
484 if (XFS_BUF_ISPINNED(bp)) 481 if (xfs_buf_ispinned(bp))
485 return XFS_ITEM_PINNED; 482 return XFS_ITEM_PINNED;
486 if (!XFS_BUF_CPSEMA(bp)) 483 if (!xfs_buf_trylock(bp))
487 return XFS_ITEM_LOCKED; 484 return XFS_ITEM_LOCKED;
488 485
489 /* take a reference to the buffer. */ 486 /* take a reference to the buffer. */
490 XFS_BUF_HOLD(bp); 487 xfs_buf_hold(bp);
491 488
492 ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); 489 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
493 trace_xfs_buf_item_trylock(bip); 490 trace_xfs_buf_item_trylock(bip);
@@ -525,7 +522,7 @@ xfs_buf_item_unlock(
525 uint hold; 522 uint hold;
526 523
527 /* Clear the buffer's association with this transaction. */ 524 /* Clear the buffer's association with this transaction. */
528 XFS_BUF_SET_FSPRIVATE2(bp, NULL); 525 bp->b_transp = NULL;
529 526
530 /* 527 /*
531 * If this is a transaction abort, don't return early. Instead, allow 528 * If this is a transaction abort, don't return early. Instead, allow
@@ -632,7 +629,7 @@ xfs_buf_item_push(
632 * the xfsbufd to get this buffer written. We have to unlock the buffer 629 * the xfsbufd to get this buffer written. We have to unlock the buffer
633 * to allow the xfsbufd to write it, too. 630 * to allow the xfsbufd to write it, too.
634 */ 631 */
635STATIC void 632STATIC bool
636xfs_buf_item_pushbuf( 633xfs_buf_item_pushbuf(
637 struct xfs_log_item *lip) 634 struct xfs_log_item *lip)
638{ 635{
@@ -646,6 +643,7 @@ xfs_buf_item_pushbuf(
646 643
647 xfs_buf_delwri_promote(bp); 644 xfs_buf_delwri_promote(bp);
648 xfs_buf_relse(bp); 645 xfs_buf_relse(bp);
646 return true;
649} 647}
650 648
651STATIC void 649STATIC void
@@ -684,7 +682,7 @@ xfs_buf_item_init(
684 xfs_buf_t *bp, 682 xfs_buf_t *bp,
685 xfs_mount_t *mp) 683 xfs_mount_t *mp)
686{ 684{
687 xfs_log_item_t *lip; 685 xfs_log_item_t *lip = bp->b_fspriv;
688 xfs_buf_log_item_t *bip; 686 xfs_buf_log_item_t *bip;
689 int chunks; 687 int chunks;
690 int map_size; 688 int map_size;
@@ -696,12 +694,8 @@ xfs_buf_item_init(
696 * nothing to do here so return. 694 * nothing to do here so return.
697 */ 695 */
698 ASSERT(bp->b_target->bt_mount == mp); 696 ASSERT(bp->b_target->bt_mount == mp);
699 if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) { 697 if (lip != NULL && lip->li_type == XFS_LI_BUF)
700 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); 698 return;
701 if (lip->li_type == XFS_LI_BUF) {
702 return;
703 }
704 }
705 699
706 /* 700 /*
707 * chunks is the number of XFS_BLF_CHUNK size pieces 701 * chunks is the number of XFS_BLF_CHUNK size pieces
@@ -732,7 +726,7 @@ xfs_buf_item_init(
732 * to have logged. 726 * to have logged.
733 */ 727 */
734 bip->bli_orig = (char *)kmem_alloc(XFS_BUF_COUNT(bp), KM_SLEEP); 728 bip->bli_orig = (char *)kmem_alloc(XFS_BUF_COUNT(bp), KM_SLEEP);
735 memcpy(bip->bli_orig, XFS_BUF_PTR(bp), XFS_BUF_COUNT(bp)); 729 memcpy(bip->bli_orig, bp->b_addr, XFS_BUF_COUNT(bp));
736 bip->bli_logged = (char *)kmem_zalloc(XFS_BUF_COUNT(bp) / NBBY, KM_SLEEP); 730 bip->bli_logged = (char *)kmem_zalloc(XFS_BUF_COUNT(bp) / NBBY, KM_SLEEP);
737#endif 731#endif
738 732
@@ -740,11 +734,9 @@ xfs_buf_item_init(
740 * Put the buf item into the list of items attached to the 734 * Put the buf item into the list of items attached to the
741 * buffer at the front. 735 * buffer at the front.
742 */ 736 */
743 if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) { 737 if (bp->b_fspriv)
744 bip->bli_item.li_bio_list = 738 bip->bli_item.li_bio_list = bp->b_fspriv;
745 XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); 739 bp->b_fspriv = bip;
746 }
747 XFS_BUF_SET_FSPRIVATE(bp, bip);
748} 740}
749 741
750 742
@@ -876,12 +868,11 @@ xfs_buf_item_relse(
876 868
877 trace_xfs_buf_item_relse(bp, _RET_IP_); 869 trace_xfs_buf_item_relse(bp, _RET_IP_);
878 870
879 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*); 871 bip = bp->b_fspriv;
880 XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list); 872 bp->b_fspriv = bip->bli_item.li_bio_list;
881 if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) && 873 if (bp->b_fspriv == NULL)
882 (XFS_BUF_IODONE_FUNC(bp) != NULL)) { 874 bp->b_iodone = NULL;
883 XFS_BUF_CLR_IODONE_FUNC(bp); 875
884 }
885 xfs_buf_rele(bp); 876 xfs_buf_rele(bp);
886 xfs_buf_item_free(bip); 877 xfs_buf_item_free(bip);
887} 878}
@@ -904,21 +895,20 @@ xfs_buf_attach_iodone(
904{ 895{
905 xfs_log_item_t *head_lip; 896 xfs_log_item_t *head_lip;
906 897
907 ASSERT(XFS_BUF_ISBUSY(bp)); 898 ASSERT(xfs_buf_islocked(bp));
908 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
909 899
910 lip->li_cb = cb; 900 lip->li_cb = cb;
911 if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) { 901 head_lip = bp->b_fspriv;
912 head_lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); 902 if (head_lip) {
913 lip->li_bio_list = head_lip->li_bio_list; 903 lip->li_bio_list = head_lip->li_bio_list;
914 head_lip->li_bio_list = lip; 904 head_lip->li_bio_list = lip;
915 } else { 905 } else {
916 XFS_BUF_SET_FSPRIVATE(bp, lip); 906 bp->b_fspriv = lip;
917 } 907 }
918 908
919 ASSERT((XFS_BUF_IODONE_FUNC(bp) == xfs_buf_iodone_callbacks) || 909 ASSERT(bp->b_iodone == NULL ||
920 (XFS_BUF_IODONE_FUNC(bp) == NULL)); 910 bp->b_iodone == xfs_buf_iodone_callbacks);
921 XFS_BUF_SET_IODONE_FUNC(bp, xfs_buf_iodone_callbacks); 911 bp->b_iodone = xfs_buf_iodone_callbacks;
922} 912}
923 913
924/* 914/*
@@ -939,8 +929,8 @@ xfs_buf_do_callbacks(
939{ 929{
940 struct xfs_log_item *lip; 930 struct xfs_log_item *lip;
941 931
942 while ((lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *)) != NULL) { 932 while ((lip = bp->b_fspriv) != NULL) {
943 XFS_BUF_SET_FSPRIVATE(bp, lip->li_bio_list); 933 bp->b_fspriv = lip->li_bio_list;
944 ASSERT(lip->li_cb != NULL); 934 ASSERT(lip->li_cb != NULL);
945 /* 935 /*
946 * Clear the next pointer so we don't have any 936 * Clear the next pointer so we don't have any
@@ -969,7 +959,7 @@ xfs_buf_iodone_callbacks(
969 static ulong lasttime; 959 static ulong lasttime;
970 static xfs_buftarg_t *lasttarg; 960 static xfs_buftarg_t *lasttarg;
971 961
972 if (likely(!XFS_BUF_GETERROR(bp))) 962 if (likely(!xfs_buf_geterror(bp)))
973 goto do_callbacks; 963 goto do_callbacks;
974 964
975 /* 965 /*
@@ -982,14 +972,14 @@ xfs_buf_iodone_callbacks(
982 goto do_callbacks; 972 goto do_callbacks;
983 } 973 }
984 974
985 if (XFS_BUF_TARGET(bp) != lasttarg || 975 if (bp->b_target != lasttarg ||
986 time_after(jiffies, (lasttime + 5*HZ))) { 976 time_after(jiffies, (lasttime + 5*HZ))) {
987 lasttime = jiffies; 977 lasttime = jiffies;
988 xfs_alert(mp, "Device %s: metadata write error block 0x%llx", 978 xfs_alert(mp, "Device %s: metadata write error block 0x%llx",
989 XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)), 979 xfs_buf_target_name(bp->b_target),
990 (__uint64_t)XFS_BUF_ADDR(bp)); 980 (__uint64_t)XFS_BUF_ADDR(bp));
991 } 981 }
992 lasttarg = XFS_BUF_TARGET(bp); 982 lasttarg = bp->b_target;
993 983
994 /* 984 /*
995 * If the write was asynchronous then no one will be looking for the 985 * If the write was asynchronous then no one will be looking for the
@@ -1000,14 +990,13 @@ xfs_buf_iodone_callbacks(
1000 * around. 990 * around.
1001 */ 991 */
1002 if (XFS_BUF_ISASYNC(bp)) { 992 if (XFS_BUF_ISASYNC(bp)) {
1003 XFS_BUF_ERROR(bp, 0); /* errno of 0 unsets the flag */ 993 xfs_buf_ioerror(bp, 0); /* errno of 0 unsets the flag */
1004 994
1005 if (!XFS_BUF_ISSTALE(bp)) { 995 if (!XFS_BUF_ISSTALE(bp)) {
1006 XFS_BUF_DELAYWRITE(bp); 996 XFS_BUF_DELAYWRITE(bp);
1007 XFS_BUF_DONE(bp); 997 XFS_BUF_DONE(bp);
1008 XFS_BUF_SET_START(bp);
1009 } 998 }
1010 ASSERT(XFS_BUF_IODONE_FUNC(bp)); 999 ASSERT(bp->b_iodone != NULL);
1011 trace_xfs_buf_item_iodone_async(bp, _RET_IP_); 1000 trace_xfs_buf_item_iodone_async(bp, _RET_IP_);
1012 xfs_buf_relse(bp); 1001 xfs_buf_relse(bp);
1013 return; 1002 return;
@@ -1022,12 +1011,11 @@ xfs_buf_iodone_callbacks(
1022 XFS_BUF_UNDELAYWRITE(bp); 1011 XFS_BUF_UNDELAYWRITE(bp);
1023 1012
1024 trace_xfs_buf_error_relse(bp, _RET_IP_); 1013 trace_xfs_buf_error_relse(bp, _RET_IP_);
1025 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1026 1014
1027do_callbacks: 1015do_callbacks:
1028 xfs_buf_do_callbacks(bp); 1016 xfs_buf_do_callbacks(bp);
1029 XFS_BUF_SET_FSPRIVATE(bp, NULL); 1017 bp->b_fspriv = NULL;
1030 XFS_BUF_CLR_IODONE_FUNC(bp); 1018 bp->b_iodone = NULL;
1031 xfs_buf_ioend(bp, 0); 1019 xfs_buf_ioend(bp, 0);
1032} 1020}
1033 1021
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 6102ac6d1df..ee9d5427fcd 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -24,11 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir2.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir2_sf.h" 30#include "xfs_dir2.h"
31#include "xfs_dir2_format.h"
32#include "xfs_dir2_priv.h"
32#include "xfs_dinode.h" 33#include "xfs_dinode.h"
33#include "xfs_inode.h" 34#include "xfs_inode.h"
34#include "xfs_inode_item.h" 35#include "xfs_inode_item.h"
@@ -36,10 +37,6 @@
36#include "xfs_bmap.h" 37#include "xfs_bmap.h"
37#include "xfs_attr.h" 38#include "xfs_attr.h"
38#include "xfs_attr_leaf.h" 39#include "xfs_attr_leaf.h"
39#include "xfs_dir2_data.h"
40#include "xfs_dir2_leaf.h"
41#include "xfs_dir2_block.h"
42#include "xfs_dir2_node.h"
43#include "xfs_error.h" 40#include "xfs_error.h"
44#include "xfs_trace.h" 41#include "xfs_trace.h"
45 42
@@ -89,7 +86,7 @@ STATIC void xfs_da_node_unbalance(xfs_da_state_t *state,
89 */ 86 */
90STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); 87STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count);
91STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); 88STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp);
92STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra); 89STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps);
93STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, 90STATIC int xfs_da_blk_unlink(xfs_da_state_t *state,
94 xfs_da_state_blk_t *drop_blk, 91 xfs_da_state_blk_t *drop_blk,
95 xfs_da_state_blk_t *save_blk); 92 xfs_da_state_blk_t *save_blk);
@@ -321,11 +318,11 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
321 ASSERT(bp != NULL); 318 ASSERT(bp != NULL);
322 node = bp->data; 319 node = bp->data;
323 oldroot = blk1->bp->data; 320 oldroot = blk1->bp->data;
324 if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC) { 321 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC)) {
325 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - 322 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
326 (char *)oldroot); 323 (char *)oldroot);
327 } else { 324 } else {
328 ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 325 ASSERT(oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
329 leaf = (xfs_dir2_leaf_t *)oldroot; 326 leaf = (xfs_dir2_leaf_t *)oldroot;
330 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - 327 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] -
331 (char *)leaf); 328 (char *)leaf);
@@ -352,7 +349,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
352 node->hdr.count = cpu_to_be16(2); 349 node->hdr.count = cpu_to_be16(2);
353 350
354#ifdef DEBUG 351#ifdef DEBUG
355 if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC) { 352 if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) {
356 ASSERT(blk1->blkno >= mp->m_dirleafblk && 353 ASSERT(blk1->blkno >= mp->m_dirleafblk &&
357 blk1->blkno < mp->m_dirfreeblk); 354 blk1->blkno < mp->m_dirfreeblk);
358 ASSERT(blk2->blkno >= mp->m_dirleafblk && 355 ASSERT(blk2->blkno >= mp->m_dirleafblk &&
@@ -384,7 +381,7 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
384 int useextra; 381 int useextra;
385 382
386 node = oldblk->bp->data; 383 node = oldblk->bp->data;
387 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 384 ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
388 385
389 /* 386 /*
390 * With V2 dirs the extra block is data or freespace. 387 * With V2 dirs the extra block is data or freespace.
@@ -483,8 +480,8 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
483 node1 = node2; 480 node1 = node2;
484 node2 = tmpnode; 481 node2 = tmpnode;
485 } 482 }
486 ASSERT(be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC); 483 ASSERT(node1->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
487 ASSERT(be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC); 484 ASSERT(node2->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
488 count = (be16_to_cpu(node1->hdr.count) - be16_to_cpu(node2->hdr.count)) / 2; 485 count = (be16_to_cpu(node1->hdr.count) - be16_to_cpu(node2->hdr.count)) / 2;
489 if (count == 0) 486 if (count == 0)
490 return; 487 return;
@@ -578,7 +575,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
578 int tmp; 575 int tmp;
579 576
580 node = oldblk->bp->data; 577 node = oldblk->bp->data;
581 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 578 ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
582 ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); 579 ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));
583 ASSERT(newblk->blkno != 0); 580 ASSERT(newblk->blkno != 0);
584 if (state->args->whichfork == XFS_DATA_FORK) 581 if (state->args->whichfork == XFS_DATA_FORK)
@@ -695,6 +692,24 @@ xfs_da_join(xfs_da_state_t *state)
695 return(error); 692 return(error);
696} 693}
697 694
695#ifdef DEBUG
696static void
697xfs_da_blkinfo_onlychild_validate(struct xfs_da_blkinfo *blkinfo, __u16 level)
698{
699 __be16 magic = blkinfo->magic;
700
701 if (level == 1) {
702 ASSERT(magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
703 magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
704 } else
705 ASSERT(magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
706 ASSERT(!blkinfo->forw);
707 ASSERT(!blkinfo->back);
708}
709#else /* !DEBUG */
710#define xfs_da_blkinfo_onlychild_validate(blkinfo, level)
711#endif /* !DEBUG */
712
698/* 713/*
699 * We have only one entry in the root. Copy the only remaining child of 714 * We have only one entry in the root. Copy the only remaining child of
700 * the old root to block 0 as the new root node. 715 * the old root to block 0 as the new root node.
@@ -703,8 +718,6 @@ STATIC int
703xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) 718xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
704{ 719{
705 xfs_da_intnode_t *oldroot; 720 xfs_da_intnode_t *oldroot;
706 /* REFERENCED */
707 xfs_da_blkinfo_t *blkinfo;
708 xfs_da_args_t *args; 721 xfs_da_args_t *args;
709 xfs_dablk_t child; 722 xfs_dablk_t child;
710 xfs_dabuf_t *bp; 723 xfs_dabuf_t *bp;
@@ -714,7 +727,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
714 ASSERT(args != NULL); 727 ASSERT(args != NULL);
715 ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC); 728 ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC);
716 oldroot = root_blk->bp->data; 729 oldroot = root_blk->bp->data;
717 ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC); 730 ASSERT(oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
718 ASSERT(!oldroot->hdr.info.forw); 731 ASSERT(!oldroot->hdr.info.forw);
719 ASSERT(!oldroot->hdr.info.back); 732 ASSERT(!oldroot->hdr.info.back);
720 733
@@ -735,15 +748,9 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
735 if (error) 748 if (error)
736 return(error); 749 return(error);
737 ASSERT(bp != NULL); 750 ASSERT(bp != NULL);
738 blkinfo = bp->data; 751 xfs_da_blkinfo_onlychild_validate(bp->data,
739 if (be16_to_cpu(oldroot->hdr.level) == 1) { 752 be16_to_cpu(oldroot->hdr.level));
740 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC || 753
741 be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);
742 } else {
743 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC);
744 }
745 ASSERT(!blkinfo->forw);
746 ASSERT(!blkinfo->back);
747 memcpy(root_blk->bp->data, bp->data, state->blocksize); 754 memcpy(root_blk->bp->data, bp->data, state->blocksize);
748 xfs_da_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); 755 xfs_da_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1);
749 error = xfs_da_shrink_inode(args, child, bp); 756 error = xfs_da_shrink_inode(args, child, bp);
@@ -776,7 +783,7 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action)
776 */ 783 */
777 blk = &state->path.blk[ state->path.active-1 ]; 784 blk = &state->path.blk[ state->path.active-1 ];
778 info = blk->bp->data; 785 info = blk->bp->data;
779 ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC); 786 ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
780 node = (xfs_da_intnode_t *)info; 787 node = (xfs_da_intnode_t *)info;
781 count = be16_to_cpu(node->hdr.count); 788 count = be16_to_cpu(node->hdr.count);
782 if (count > (state->node_ents >> 1)) { 789 if (count > (state->node_ents >> 1)) {
@@ -836,7 +843,7 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action)
836 count -= state->node_ents >> 2; 843 count -= state->node_ents >> 2;
837 count -= be16_to_cpu(node->hdr.count); 844 count -= be16_to_cpu(node->hdr.count);
838 node = bp->data; 845 node = bp->data;
839 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 846 ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
840 count -= be16_to_cpu(node->hdr.count); 847 count -= be16_to_cpu(node->hdr.count);
841 xfs_da_brelse(state->args->trans, bp); 848 xfs_da_brelse(state->args->trans, bp);
842 if (count >= 0) 849 if (count >= 0)
@@ -911,7 +918,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
911 } 918 }
912 for (blk--, level--; level >= 0; blk--, level--) { 919 for (blk--, level--; level >= 0; blk--, level--) {
913 node = blk->bp->data; 920 node = blk->bp->data;
914 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 921 ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
915 btree = &node->btree[ blk->index ]; 922 btree = &node->btree[ blk->index ];
916 if (be32_to_cpu(btree->hashval) == lasthash) 923 if (be32_to_cpu(btree->hashval) == lasthash)
917 break; 924 break;
@@ -979,8 +986,8 @@ xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
979 986
980 drop_node = drop_blk->bp->data; 987 drop_node = drop_blk->bp->data;
981 save_node = save_blk->bp->data; 988 save_node = save_blk->bp->data;
982 ASSERT(be16_to_cpu(drop_node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 989 ASSERT(drop_node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
983 ASSERT(be16_to_cpu(save_node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 990 ASSERT(save_node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
984 tp = state->args->trans; 991 tp = state->args->trans;
985 992
986 /* 993 /*
@@ -1278,8 +1285,8 @@ xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp)
1278 1285
1279 node1 = node1_bp->data; 1286 node1 = node1_bp->data;
1280 node2 = node2_bp->data; 1287 node2 = node2_bp->data;
1281 ASSERT((be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC) && 1288 ASSERT(node1->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC) &&
1282 (be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC)); 1289 node2->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
1283 if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) && 1290 if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) &&
1284 ((be32_to_cpu(node2->btree[0].hashval) < 1291 ((be32_to_cpu(node2->btree[0].hashval) <
1285 be32_to_cpu(node1->btree[0].hashval)) || 1292 be32_to_cpu(node1->btree[0].hashval)) ||
@@ -1299,7 +1306,7 @@ xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count)
1299 xfs_da_intnode_t *node; 1306 xfs_da_intnode_t *node;
1300 1307
1301 node = bp->data; 1308 node = bp->data;
1302 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 1309 ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
1303 if (count) 1310 if (count)
1304 *count = be16_to_cpu(node->hdr.count); 1311 *count = be16_to_cpu(node->hdr.count);
1305 if (!node->hdr.count) 1312 if (!node->hdr.count)
@@ -1412,7 +1419,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1412 for (blk = &path->blk[level]; level >= 0; blk--, level--) { 1419 for (blk = &path->blk[level]; level >= 0; blk--, level--) {
1413 ASSERT(blk->bp != NULL); 1420 ASSERT(blk->bp != NULL);
1414 node = blk->bp->data; 1421 node = blk->bp->data;
1415 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 1422 ASSERT(node->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
1416 if (forward && (blk->index < be16_to_cpu(node->hdr.count)-1)) { 1423 if (forward && (blk->index < be16_to_cpu(node->hdr.count)-1)) {
1417 blk->index++; 1424 blk->index++;
1418 blkno = be32_to_cpu(node->btree[blk->index].before); 1425 blkno = be32_to_cpu(node->btree[blk->index].before);
@@ -1451,9 +1458,9 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1451 return(error); 1458 return(error);
1452 ASSERT(blk->bp != NULL); 1459 ASSERT(blk->bp != NULL);
1453 info = blk->bp->data; 1460 info = blk->bp->data;
1454 ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || 1461 ASSERT(info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC) ||
1455 be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC || 1462 info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
1456 be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); 1463 info->magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC));
1457 blk->magic = be16_to_cpu(info->magic); 1464 blk->magic = be16_to_cpu(info->magic);
1458 if (blk->magic == XFS_DA_NODE_MAGIC) { 1465 if (blk->magic == XFS_DA_NODE_MAGIC) {
1459 node = (xfs_da_intnode_t *)info; 1466 node = (xfs_da_intnode_t *)info;
@@ -1546,79 +1553,62 @@ const struct xfs_nameops xfs_default_nameops = {
1546 .compname = xfs_da_compname 1553 .compname = xfs_da_compname
1547}; 1554};
1548 1555
1549/*
1550 * Add a block to the btree ahead of the file.
1551 * Return the new block number to the caller.
1552 */
1553int 1556int
1554xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) 1557xfs_da_grow_inode_int(
1558 struct xfs_da_args *args,
1559 xfs_fileoff_t *bno,
1560 int count)
1555{ 1561{
1556 xfs_fileoff_t bno, b; 1562 struct xfs_trans *tp = args->trans;
1557 xfs_bmbt_irec_t map; 1563 struct xfs_inode *dp = args->dp;
1558 xfs_bmbt_irec_t *mapp; 1564 int w = args->whichfork;
1559 xfs_inode_t *dp; 1565 xfs_drfsbno_t nblks = dp->i_d.di_nblocks;
1560 int nmap, error, w, count, c, got, i, mapi; 1566 struct xfs_bmbt_irec map, *mapp;
1561 xfs_trans_t *tp; 1567 int nmap, error, got, i, mapi;
1562 xfs_mount_t *mp;
1563 xfs_drfsbno_t nblks;
1564
1565 dp = args->dp;
1566 mp = dp->i_mount;
1567 w = args->whichfork;
1568 tp = args->trans;
1569 nblks = dp->i_d.di_nblocks;
1570 1568
1571 /* 1569 /*
1572 * For new directories adjust the file offset and block count.
1573 */
1574 if (w == XFS_DATA_FORK) {
1575 bno = mp->m_dirleafblk;
1576 count = mp->m_dirblkfsbs;
1577 } else {
1578 bno = 0;
1579 count = 1;
1580 }
1581 /*
1582 * Find a spot in the file space to put the new block. 1570 * Find a spot in the file space to put the new block.
1583 */ 1571 */
1584 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) 1572 error = xfs_bmap_first_unused(tp, dp, count, bno, w);
1573 if (error)
1585 return error; 1574 return error;
1586 if (w == XFS_DATA_FORK) 1575
1587 ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);
1588 /* 1576 /*
1589 * Try mapping it in one filesystem block. 1577 * Try mapping it in one filesystem block.
1590 */ 1578 */
1591 nmap = 1; 1579 nmap = 1;
1592 ASSERT(args->firstblock != NULL); 1580 ASSERT(args->firstblock != NULL);
1593 if ((error = xfs_bmapi(tp, dp, bno, count, 1581 error = xfs_bmapi(tp, dp, *bno, count,
1594 xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| 1582 xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
1595 XFS_BMAPI_CONTIG, 1583 XFS_BMAPI_CONTIG,
1596 args->firstblock, args->total, &map, &nmap, 1584 args->firstblock, args->total, &map, &nmap,
1597 args->flist))) { 1585 args->flist);
1586 if (error)
1598 return error; 1587 return error;
1599 } 1588
1600 ASSERT(nmap <= 1); 1589 ASSERT(nmap <= 1);
1601 if (nmap == 1) { 1590 if (nmap == 1) {
1602 mapp = &map; 1591 mapp = &map;
1603 mapi = 1; 1592 mapi = 1;
1604 } 1593 } else if (nmap == 0 && count > 1) {
1605 /* 1594 xfs_fileoff_t b;
1606 * If we didn't get it and the block might work if fragmented, 1595 int c;
1607 * try without the CONTIG flag. Loop until we get it all. 1596
1608 */ 1597 /*
1609 else if (nmap == 0 && count > 1) { 1598 * If we didn't get it and the block might work if fragmented,
1599 * try without the CONTIG flag. Loop until we get it all.
1600 */
1610 mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP); 1601 mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP);
1611 for (b = bno, mapi = 0; b < bno + count; ) { 1602 for (b = *bno, mapi = 0; b < *bno + count; ) {
1612 nmap = MIN(XFS_BMAP_MAX_NMAP, count); 1603 nmap = MIN(XFS_BMAP_MAX_NMAP, count);
1613 c = (int)(bno + count - b); 1604 c = (int)(*bno + count - b);
1614 if ((error = xfs_bmapi(tp, dp, b, c, 1605 error = xfs_bmapi(tp, dp, b, c,
1615 xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE| 1606 xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|
1616 XFS_BMAPI_METADATA, 1607 XFS_BMAPI_METADATA,
1617 args->firstblock, args->total, 1608 args->firstblock, args->total,
1618 &mapp[mapi], &nmap, args->flist))) { 1609 &mapp[mapi], &nmap, args->flist);
1619 kmem_free(mapp); 1610 if (error)
1620 return error; 1611 goto out_free_map;
1621 }
1622 if (nmap < 1) 1612 if (nmap < 1)
1623 break; 1613 break;
1624 mapi += nmap; 1614 mapi += nmap;
@@ -1629,24 +1619,53 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1629 mapi = 0; 1619 mapi = 0;
1630 mapp = NULL; 1620 mapp = NULL;
1631 } 1621 }
1622
1632 /* 1623 /*
1633 * Count the blocks we got, make sure it matches the total. 1624 * Count the blocks we got, make sure it matches the total.
1634 */ 1625 */
1635 for (i = 0, got = 0; i < mapi; i++) 1626 for (i = 0, got = 0; i < mapi; i++)
1636 got += mapp[i].br_blockcount; 1627 got += mapp[i].br_blockcount;
1637 if (got != count || mapp[0].br_startoff != bno || 1628 if (got != count || mapp[0].br_startoff != *bno ||
1638 mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount != 1629 mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount !=
1639 bno + count) { 1630 *bno + count) {
1640 if (mapp != &map) 1631 error = XFS_ERROR(ENOSPC);
1641 kmem_free(mapp); 1632 goto out_free_map;
1642 return XFS_ERROR(ENOSPC);
1643 } 1633 }
1644 if (mapp != &map) 1634
1645 kmem_free(mapp);
1646 /* account for newly allocated blocks in reserved blocks total */ 1635 /* account for newly allocated blocks in reserved blocks total */
1647 args->total -= dp->i_d.di_nblocks - nblks; 1636 args->total -= dp->i_d.di_nblocks - nblks;
1648 *new_blkno = (xfs_dablk_t)bno; 1637
1649 return 0; 1638out_free_map:
1639 if (mapp != &map)
1640 kmem_free(mapp);
1641 return error;
1642}
1643
1644/*
1645 * Add a block to the btree ahead of the file.
1646 * Return the new block number to the caller.
1647 */
1648int
1649xfs_da_grow_inode(
1650 struct xfs_da_args *args,
1651 xfs_dablk_t *new_blkno)
1652{
1653 xfs_fileoff_t bno;
1654 int count;
1655 int error;
1656
1657 if (args->whichfork == XFS_DATA_FORK) {
1658 bno = args->dp->i_mount->m_dirleafblk;
1659 count = args->dp->i_mount->m_dirblkfsbs;
1660 } else {
1661 bno = 0;
1662 count = 1;
1663 }
1664
1665 error = xfs_da_grow_inode_int(args, &bno, count);
1666 if (!error)
1667 *new_blkno = (xfs_dablk_t)bno;
1668 return error;
1650} 1669}
1651 1670
1652/* 1671/*
@@ -1704,12 +1723,12 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1704 /* 1723 /*
1705 * Get values from the moved block. 1724 * Get values from the moved block.
1706 */ 1725 */
1707 if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) { 1726 if (dead_info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) {
1708 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; 1727 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
1709 dead_level = 0; 1728 dead_level = 0;
1710 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); 1729 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval);
1711 } else { 1730 } else {
1712 ASSERT(be16_to_cpu(dead_info->magic) == XFS_DA_NODE_MAGIC); 1731 ASSERT(dead_info->magic == cpu_to_be16(XFS_DA_NODE_MAGIC));
1713 dead_node = (xfs_da_intnode_t *)dead_info; 1732 dead_node = (xfs_da_intnode_t *)dead_info;
1714 dead_level = be16_to_cpu(dead_node->hdr.level); 1733 dead_level = be16_to_cpu(dead_node->hdr.level);
1715 dead_hash = be32_to_cpu(dead_node->btree[be16_to_cpu(dead_node->hdr.count) - 1].hashval); 1734 dead_hash = be32_to_cpu(dead_node->btree[be16_to_cpu(dead_node->hdr.count) - 1].hashval);
@@ -1768,8 +1787,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1768 if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w))) 1787 if ((error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w)))
1769 goto done; 1788 goto done;
1770 par_node = par_buf->data; 1789 par_node = par_buf->data;
1771 if (unlikely( 1790 if (unlikely(par_node->hdr.info.magic !=
1772 be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC || 1791 cpu_to_be16(XFS_DA_NODE_MAGIC) ||
1773 (level >= 0 && level != be16_to_cpu(par_node->hdr.level) + 1))) { 1792 (level >= 0 && level != be16_to_cpu(par_node->hdr.level) + 1))) {
1774 XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)", 1793 XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",
1775 XFS_ERRLEVEL_LOW, mp); 1794 XFS_ERRLEVEL_LOW, mp);
@@ -1820,7 +1839,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1820 par_node = par_buf->data; 1839 par_node = par_buf->data;
1821 if (unlikely( 1840 if (unlikely(
1822 be16_to_cpu(par_node->hdr.level) != level || 1841 be16_to_cpu(par_node->hdr.level) != level ||
1823 be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC)) { 1842 par_node->hdr.info.magic != cpu_to_be16(XFS_DA_NODE_MAGIC))) {
1824 XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)", 1843 XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",
1825 XFS_ERRLEVEL_LOW, mp); 1844 XFS_ERRLEVEL_LOW, mp);
1826 error = XFS_ERROR(EFSCORRUPTED); 1845 error = XFS_ERROR(EFSCORRUPTED);
@@ -1930,8 +1949,7 @@ xfs_da_do_buf(
1930 xfs_daddr_t *mappedbnop, 1949 xfs_daddr_t *mappedbnop,
1931 xfs_dabuf_t **bpp, 1950 xfs_dabuf_t **bpp,
1932 int whichfork, 1951 int whichfork,
1933 int caller, 1952 int caller)
1934 inst_t *ra)
1935{ 1953{
1936 xfs_buf_t *bp = NULL; 1954 xfs_buf_t *bp = NULL;
1937 xfs_buf_t **bplist; 1955 xfs_buf_t **bplist;
@@ -2032,7 +2050,7 @@ xfs_da_do_buf(
2032 case 0: 2050 case 0:
2033 bp = xfs_trans_get_buf(trans, mp->m_ddev_targp, 2051 bp = xfs_trans_get_buf(trans, mp->m_ddev_targp,
2034 mappedbno, nmapped, 0); 2052 mappedbno, nmapped, 0);
2035 error = bp ? XFS_BUF_GETERROR(bp) : XFS_ERROR(EIO); 2053 error = bp ? bp->b_error : XFS_ERROR(EIO);
2036 break; 2054 break;
2037 case 1: 2055 case 1:
2038 case 2: 2056 case 2:
@@ -2070,25 +2088,22 @@ xfs_da_do_buf(
2070 * Build a dabuf structure. 2088 * Build a dabuf structure.
2071 */ 2089 */
2072 if (bplist) { 2090 if (bplist) {
2073 rbp = xfs_da_buf_make(nbplist, bplist, ra); 2091 rbp = xfs_da_buf_make(nbplist, bplist);
2074 } else if (bp) 2092 } else if (bp)
2075 rbp = xfs_da_buf_make(1, &bp, ra); 2093 rbp = xfs_da_buf_make(1, &bp);
2076 else 2094 else
2077 rbp = NULL; 2095 rbp = NULL;
2078 /* 2096 /*
2079 * For read_buf, check the magic number. 2097 * For read_buf, check the magic number.
2080 */ 2098 */
2081 if (caller == 1) { 2099 if (caller == 1) {
2082 xfs_dir2_data_t *data; 2100 xfs_dir2_data_hdr_t *hdr = rbp->data;
2083 xfs_dir2_free_t *free; 2101 xfs_dir2_free_t *free = rbp->data;
2084 xfs_da_blkinfo_t *info; 2102 xfs_da_blkinfo_t *info = rbp->data;
2085 uint magic, magic1; 2103 uint magic, magic1;
2086 2104
2087 info = rbp->data;
2088 data = rbp->data;
2089 free = rbp->data;
2090 magic = be16_to_cpu(info->magic); 2105 magic = be16_to_cpu(info->magic);
2091 magic1 = be32_to_cpu(data->hdr.magic); 2106 magic1 = be32_to_cpu(hdr->magic);
2092 if (unlikely( 2107 if (unlikely(
2093 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && 2108 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
2094 (magic != XFS_ATTR_LEAF_MAGIC) && 2109 (magic != XFS_ATTR_LEAF_MAGIC) &&
@@ -2096,7 +2111,7 @@ xfs_da_do_buf(
2096 (magic != XFS_DIR2_LEAFN_MAGIC) && 2111 (magic != XFS_DIR2_LEAFN_MAGIC) &&
2097 (magic1 != XFS_DIR2_BLOCK_MAGIC) && 2112 (magic1 != XFS_DIR2_BLOCK_MAGIC) &&
2098 (magic1 != XFS_DIR2_DATA_MAGIC) && 2113 (magic1 != XFS_DIR2_DATA_MAGIC) &&
2099 (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC), 2114 (free->hdr.magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC)),
2100 mp, XFS_ERRTAG_DA_READ_BUF, 2115 mp, XFS_ERRTAG_DA_READ_BUF,
2101 XFS_RANDOM_DA_READ_BUF))) { 2116 XFS_RANDOM_DA_READ_BUF))) {
2102 trace_xfs_da_btree_corrupt(rbp->bps[0], _RET_IP_); 2117 trace_xfs_da_btree_corrupt(rbp->bps[0], _RET_IP_);
@@ -2143,8 +2158,7 @@ xfs_da_get_buf(
2143 xfs_dabuf_t **bpp, 2158 xfs_dabuf_t **bpp,
2144 int whichfork) 2159 int whichfork)
2145{ 2160{
2146 return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 0, 2161 return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 0);
2147 (inst_t *)__return_address);
2148} 2162}
2149 2163
2150/* 2164/*
@@ -2159,8 +2173,7 @@ xfs_da_read_buf(
2159 xfs_dabuf_t **bpp, 2173 xfs_dabuf_t **bpp,
2160 int whichfork) 2174 int whichfork)
2161{ 2175{
2162 return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 1, 2176 return xfs_da_do_buf(trans, dp, bno, &mappedbno, bpp, whichfork, 1);
2163 (inst_t *)__return_address);
2164} 2177}
2165 2178
2166/* 2179/*
@@ -2176,8 +2189,7 @@ xfs_da_reada_buf(
2176 xfs_daddr_t rval; 2189 xfs_daddr_t rval;
2177 2190
2178 rval = -1; 2191 rval = -1;
2179 if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3, 2192 if (xfs_da_do_buf(trans, dp, bno, &rval, NULL, whichfork, 3))
2180 (inst_t *)__return_address))
2181 return -1; 2193 return -1;
2182 else 2194 else
2183 return rval; 2195 return rval;
@@ -2235,17 +2247,12 @@ xfs_da_state_free(xfs_da_state_t *state)
2235 kmem_zone_free(xfs_da_state_zone, state); 2247 kmem_zone_free(xfs_da_state_zone, state);
2236} 2248}
2237 2249
2238#ifdef XFS_DABUF_DEBUG
2239xfs_dabuf_t *xfs_dabuf_global_list;
2240static DEFINE_SPINLOCK(xfs_dabuf_global_lock);
2241#endif
2242
2243/* 2250/*
2244 * Create a dabuf. 2251 * Create a dabuf.
2245 */ 2252 */
2246/* ARGSUSED */ 2253/* ARGSUSED */
2247STATIC xfs_dabuf_t * 2254STATIC xfs_dabuf_t *
2248xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra) 2255xfs_da_buf_make(int nbuf, xfs_buf_t **bps)
2249{ 2256{
2250 xfs_buf_t *bp; 2257 xfs_buf_t *bp;
2251 xfs_dabuf_t *dabuf; 2258 xfs_dabuf_t *dabuf;
@@ -2257,16 +2264,11 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra)
2257 else 2264 else
2258 dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_NOFS); 2265 dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_NOFS);
2259 dabuf->dirty = 0; 2266 dabuf->dirty = 0;
2260#ifdef XFS_DABUF_DEBUG
2261 dabuf->ra = ra;
2262 dabuf->target = XFS_BUF_TARGET(bps[0]);
2263 dabuf->blkno = XFS_BUF_ADDR(bps[0]);
2264#endif
2265 if (nbuf == 1) { 2267 if (nbuf == 1) {
2266 dabuf->nbuf = 1; 2268 dabuf->nbuf = 1;
2267 bp = bps[0]; 2269 bp = bps[0];
2268 dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp)); 2270 dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp));
2269 dabuf->data = XFS_BUF_PTR(bp); 2271 dabuf->data = bp->b_addr;
2270 dabuf->bps[0] = bp; 2272 dabuf->bps[0] = bp;
2271 } else { 2273 } else {
2272 dabuf->nbuf = nbuf; 2274 dabuf->nbuf = nbuf;
@@ -2277,27 +2279,10 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra)
2277 dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP); 2279 dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP);
2278 for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) { 2280 for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) {
2279 bp = bps[i]; 2281 bp = bps[i];
2280 memcpy((char *)dabuf->data + off, XFS_BUF_PTR(bp), 2282 memcpy((char *)dabuf->data + off, bp->b_addr,
2281 XFS_BUF_COUNT(bp)); 2283 XFS_BUF_COUNT(bp));
2282 } 2284 }
2283 } 2285 }
2284#ifdef XFS_DABUF_DEBUG
2285 {
2286 xfs_dabuf_t *p;
2287
2288 spin_lock(&xfs_dabuf_global_lock);
2289 for (p = xfs_dabuf_global_list; p; p = p->next) {
2290 ASSERT(p->blkno != dabuf->blkno ||
2291 p->target != dabuf->target);
2292 }
2293 dabuf->prev = NULL;
2294 if (xfs_dabuf_global_list)
2295 xfs_dabuf_global_list->prev = dabuf;
2296 dabuf->next = xfs_dabuf_global_list;
2297 xfs_dabuf_global_list = dabuf;
2298 spin_unlock(&xfs_dabuf_global_lock);
2299 }
2300#endif
2301 return dabuf; 2286 return dabuf;
2302} 2287}
2303 2288
@@ -2317,8 +2302,8 @@ xfs_da_buf_clean(xfs_dabuf_t *dabuf)
2317 for (i = off = 0; i < dabuf->nbuf; 2302 for (i = off = 0; i < dabuf->nbuf;
2318 i++, off += XFS_BUF_COUNT(bp)) { 2303 i++, off += XFS_BUF_COUNT(bp)) {
2319 bp = dabuf->bps[i]; 2304 bp = dabuf->bps[i];
2320 memcpy(XFS_BUF_PTR(bp), (char *)dabuf->data + off, 2305 memcpy(bp->b_addr, dabuf->data + off,
2321 XFS_BUF_COUNT(bp)); 2306 XFS_BUF_COUNT(bp));
2322 } 2307 }
2323 } 2308 }
2324} 2309}
@@ -2333,25 +2318,12 @@ xfs_da_buf_done(xfs_dabuf_t *dabuf)
2333 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); 2318 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
2334 if (dabuf->dirty) 2319 if (dabuf->dirty)
2335 xfs_da_buf_clean(dabuf); 2320 xfs_da_buf_clean(dabuf);
2336 if (dabuf->nbuf > 1) 2321 if (dabuf->nbuf > 1) {
2337 kmem_free(dabuf->data); 2322 kmem_free(dabuf->data);
2338#ifdef XFS_DABUF_DEBUG
2339 {
2340 spin_lock(&xfs_dabuf_global_lock);
2341 if (dabuf->prev)
2342 dabuf->prev->next = dabuf->next;
2343 else
2344 xfs_dabuf_global_list = dabuf->next;
2345 if (dabuf->next)
2346 dabuf->next->prev = dabuf->prev;
2347 spin_unlock(&xfs_dabuf_global_lock);
2348 }
2349 memset(dabuf, 0, XFS_DA_BUF_SIZE(dabuf->nbuf));
2350#endif
2351 if (dabuf->nbuf == 1)
2352 kmem_zone_free(xfs_dabuf_zone, dabuf);
2353 else
2354 kmem_free(dabuf); 2323 kmem_free(dabuf);
2324 } else {
2325 kmem_zone_free(xfs_dabuf_zone, dabuf);
2326 }
2355} 2327}
2356 2328
2357/* 2329/*
@@ -2368,7 +2340,7 @@ xfs_da_log_buf(xfs_trans_t *tp, xfs_dabuf_t *dabuf, uint first, uint last)
2368 2340
2369 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); 2341 ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]);
2370 if (dabuf->nbuf == 1) { 2342 if (dabuf->nbuf == 1) {
2371 ASSERT(dabuf->data == (void *)XFS_BUF_PTR(dabuf->bps[0])); 2343 ASSERT(dabuf->data == dabuf->bps[0]->b_addr);
2372 xfs_trans_log_buf(tp, dabuf->bps[0], first, last); 2344 xfs_trans_log_buf(tp, dabuf->bps[0], first, last);
2373 return; 2345 return;
2374 } 2346 }
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index fe9f5a8c1d2..dbf7c074ae7 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -145,22 +145,11 @@ typedef struct xfs_dabuf {
145 short dirty; /* data needs to be copied back */ 145 short dirty; /* data needs to be copied back */
146 short bbcount; /* how large is data in bbs */ 146 short bbcount; /* how large is data in bbs */
147 void *data; /* pointer for buffers' data */ 147 void *data; /* pointer for buffers' data */
148#ifdef XFS_DABUF_DEBUG
149 inst_t *ra; /* return address of caller to make */
150 struct xfs_dabuf *next; /* next in global chain */
151 struct xfs_dabuf *prev; /* previous in global chain */
152 struct xfs_buftarg *target; /* device for buffer */
153 xfs_daddr_t blkno; /* daddr first in bps[0] */
154#endif
155 struct xfs_buf *bps[1]; /* actually nbuf of these */ 148 struct xfs_buf *bps[1]; /* actually nbuf of these */
156} xfs_dabuf_t; 149} xfs_dabuf_t;
157#define XFS_DA_BUF_SIZE(n) \ 150#define XFS_DA_BUF_SIZE(n) \
158 (sizeof(xfs_dabuf_t) + sizeof(struct xfs_buf *) * ((n) - 1)) 151 (sizeof(xfs_dabuf_t) + sizeof(struct xfs_buf *) * ((n) - 1))
159 152
160#ifdef XFS_DABUF_DEBUG
161extern xfs_dabuf_t *xfs_dabuf_global_list;
162#endif
163
164/* 153/*
165 * Storage for holding state during Btree searches and split/join ops. 154 * Storage for holding state during Btree searches and split/join ops.
166 * 155 *
@@ -248,6 +237,8 @@ int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
248 * Utility routines. 237 * Utility routines.
249 */ 238 */
250int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno); 239int xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno);
240int xfs_da_grow_inode_int(struct xfs_da_args *args, xfs_fileoff_t *bno,
241 int count);
251int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, 242int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp,
252 xfs_dablk_t bno, xfs_daddr_t mappedbno, 243 xfs_dablk_t bno, xfs_daddr_t mappedbno,
253 xfs_dabuf_t **bp, int whichfork); 244 xfs_dabuf_t **bp, int whichfork);
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index dffba9ba0db..a3721633abc 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -148,7 +148,7 @@ typedef enum xfs_dinode_fmt {
148 be32_to_cpu((dip)->di_nextents) : \ 148 be32_to_cpu((dip)->di_nextents) : \
149 be16_to_cpu((dip)->di_anextents)) 149 be16_to_cpu((dip)->di_anextents))
150 150
151#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp)) 151#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)((bp)->b_addr))
152 152
153/* 153/*
154 * For block and character special files the 32bit dev_t is stored at the 154 * For block and character special files the 32bit dev_t is stored at the
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index dba7a71cedf..a2e27010c7f 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -24,20 +24,17 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir2.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
32#include "xfs_dir2_sf.h"
33#include "xfs_dinode.h" 31#include "xfs_dinode.h"
34#include "xfs_inode.h" 32#include "xfs_inode.h"
35#include "xfs_inode_item.h" 33#include "xfs_inode_item.h"
36#include "xfs_bmap.h" 34#include "xfs_bmap.h"
37#include "xfs_dir2_data.h" 35#include "xfs_dir2.h"
38#include "xfs_dir2_leaf.h" 36#include "xfs_dir2_format.h"
39#include "xfs_dir2_block.h" 37#include "xfs_dir2_priv.h"
40#include "xfs_dir2_node.h"
41#include "xfs_error.h" 38#include "xfs_error.h"
42#include "xfs_vnodeops.h" 39#include "xfs_vnodeops.h"
43#include "xfs_trace.h" 40#include "xfs_trace.h"
@@ -122,15 +119,15 @@ int
122xfs_dir_isempty( 119xfs_dir_isempty(
123 xfs_inode_t *dp) 120 xfs_inode_t *dp)
124{ 121{
125 xfs_dir2_sf_t *sfp; 122 xfs_dir2_sf_hdr_t *sfp;
126 123
127 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 124 ASSERT(S_ISDIR(dp->i_d.di_mode));
128 if (dp->i_d.di_size == 0) /* might happen during shutdown. */ 125 if (dp->i_d.di_size == 0) /* might happen during shutdown. */
129 return 1; 126 return 1;
130 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) 127 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
131 return 0; 128 return 0;
132 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 129 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
133 return !sfp->hdr.count; 130 return !sfp->count;
134} 131}
135 132
136/* 133/*
@@ -182,7 +179,7 @@ xfs_dir_init(
182 memset((char *)&args, 0, sizeof(args)); 179 memset((char *)&args, 0, sizeof(args));
183 args.dp = dp; 180 args.dp = dp;
184 args.trans = tp; 181 args.trans = tp;
185 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 182 ASSERT(S_ISDIR(dp->i_d.di_mode));
186 if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) 183 if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino)))
187 return error; 184 return error;
188 return xfs_dir2_sf_create(&args, pdp->i_ino); 185 return xfs_dir2_sf_create(&args, pdp->i_ino);
@@ -205,7 +202,7 @@ xfs_dir_createname(
205 int rval; 202 int rval;
206 int v; /* type-checking value */ 203 int v; /* type-checking value */
207 204
208 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 205 ASSERT(S_ISDIR(dp->i_d.di_mode));
209 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) 206 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
210 return rval; 207 return rval;
211 XFS_STATS_INC(xs_dir_create); 208 XFS_STATS_INC(xs_dir_create);
@@ -281,7 +278,7 @@ xfs_dir_lookup(
281 int rval; 278 int rval;
282 int v; /* type-checking value */ 279 int v; /* type-checking value */
283 280
284 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 281 ASSERT(S_ISDIR(dp->i_d.di_mode));
285 XFS_STATS_INC(xs_dir_lookup); 282 XFS_STATS_INC(xs_dir_lookup);
286 283
287 memset(&args, 0, sizeof(xfs_da_args_t)); 284 memset(&args, 0, sizeof(xfs_da_args_t));
@@ -336,7 +333,7 @@ xfs_dir_removename(
336 int rval; 333 int rval;
337 int v; /* type-checking value */ 334 int v; /* type-checking value */
338 335
339 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 336 ASSERT(S_ISDIR(dp->i_d.di_mode));
340 XFS_STATS_INC(xs_dir_remove); 337 XFS_STATS_INC(xs_dir_remove);
341 338
342 memset(&args, 0, sizeof(xfs_da_args_t)); 339 memset(&args, 0, sizeof(xfs_da_args_t));
@@ -385,7 +382,7 @@ xfs_readdir(
385 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 382 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
386 return XFS_ERROR(EIO); 383 return XFS_ERROR(EIO);
387 384
388 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 385 ASSERT(S_ISDIR(dp->i_d.di_mode));
389 XFS_STATS_INC(xs_dir_getdents); 386 XFS_STATS_INC(xs_dir_getdents);
390 387
391 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 388 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
@@ -417,7 +414,7 @@ xfs_dir_replace(
417 int rval; 414 int rval;
418 int v; /* type-checking value */ 415 int v; /* type-checking value */
419 416
420 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 417 ASSERT(S_ISDIR(dp->i_d.di_mode));
421 418
422 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) 419 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
423 return rval; 420 return rval;
@@ -467,7 +464,7 @@ xfs_dir_canenter(
467 if (resblks) 464 if (resblks)
468 return 0; 465 return 0;
469 466
470 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 467 ASSERT(S_ISDIR(dp->i_d.di_mode));
471 468
472 memset(&args, 0, sizeof(xfs_da_args_t)); 469 memset(&args, 0, sizeof(xfs_da_args_t));
473 args.name = name->name; 470 args.name = name->name;
@@ -500,129 +497,34 @@ xfs_dir_canenter(
500 497
501/* 498/*
502 * Add a block to the directory. 499 * Add a block to the directory.
503 * This routine is for data and free blocks, not leaf/node blocks 500 *
504 * which are handled by xfs_da_grow_inode. 501 * This routine is for data and free blocks, not leaf/node blocks which are
502 * handled by xfs_da_grow_inode.
505 */ 503 */
506int 504int
507xfs_dir2_grow_inode( 505xfs_dir2_grow_inode(
508 xfs_da_args_t *args, 506 struct xfs_da_args *args,
509 int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ 507 int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */
510 xfs_dir2_db_t *dbp) /* out: block number added */ 508 xfs_dir2_db_t *dbp) /* out: block number added */
511{ 509{
512 xfs_fileoff_t bno; /* directory offset of new block */ 510 struct xfs_inode *dp = args->dp;
513 int count; /* count of filesystem blocks */ 511 struct xfs_mount *mp = dp->i_mount;
514 xfs_inode_t *dp; /* incore directory inode */ 512 xfs_fileoff_t bno; /* directory offset of new block */
515 int error; 513 int count; /* count of filesystem blocks */
516 int got; /* blocks actually mapped */ 514 int error;
517 int i;
518 xfs_bmbt_irec_t map; /* single structure for bmap */
519 int mapi; /* mapping index */
520 xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */
521 xfs_mount_t *mp;
522 int nmap; /* number of bmap entries */
523 xfs_trans_t *tp;
524 xfs_drfsbno_t nblks;
525 515
526 trace_xfs_dir2_grow_inode(args, space); 516 trace_xfs_dir2_grow_inode(args, space);
527 517
528 dp = args->dp;
529 tp = args->trans;
530 mp = dp->i_mount;
531 nblks = dp->i_d.di_nblocks;
532 /* 518 /*
533 * Set lowest possible block in the space requested. 519 * Set lowest possible block in the space requested.
534 */ 520 */
535 bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE); 521 bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE);
536 count = mp->m_dirblkfsbs; 522 count = mp->m_dirblkfsbs;
537 /*
538 * Find the first hole for our block.
539 */
540 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK)))
541 return error;
542 nmap = 1;
543 ASSERT(args->firstblock != NULL);
544 /*
545 * Try mapping the new block contiguously (one extent).
546 */
547 if ((error = xfs_bmapi(tp, dp, bno, count,
548 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
549 args->firstblock, args->total, &map, &nmap,
550 args->flist)))
551 return error;
552 ASSERT(nmap <= 1);
553 if (nmap == 1) {
554 mapp = &map;
555 mapi = 1;
556 }
557 /*
558 * Didn't work and this is a multiple-fsb directory block.
559 * Try again with contiguous flag turned on.
560 */
561 else if (nmap == 0 && count > 1) {
562 xfs_fileoff_t b; /* current file offset */
563 523
564 /* 524 error = xfs_da_grow_inode_int(args, &bno, count);
565 * Space for maximum number of mappings. 525 if (error)
566 */ 526 return error;
567 mapp = kmem_alloc(sizeof(*mapp) * count, KM_SLEEP);
568 /*
569 * Iterate until we get to the end of our block.
570 */
571 for (b = bno, mapi = 0; b < bno + count; ) {
572 int c; /* current fsb count */
573
574 /*
575 * Can't map more than MAX_NMAP at once.
576 */
577 nmap = MIN(XFS_BMAP_MAX_NMAP, count);
578 c = (int)(bno + count - b);
579 if ((error = xfs_bmapi(tp, dp, b, c,
580 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,
581 args->firstblock, args->total,
582 &mapp[mapi], &nmap, args->flist))) {
583 kmem_free(mapp);
584 return error;
585 }
586 if (nmap < 1)
587 break;
588 /*
589 * Add this bunch into our table, go to the next offset.
590 */
591 mapi += nmap;
592 b = mapp[mapi - 1].br_startoff +
593 mapp[mapi - 1].br_blockcount;
594 }
595 }
596 /*
597 * Didn't work.
598 */
599 else {
600 mapi = 0;
601 mapp = NULL;
602 }
603 /*
604 * See how many fsb's we got.
605 */
606 for (i = 0, got = 0; i < mapi; i++)
607 got += mapp[i].br_blockcount;
608 /*
609 * Didn't get enough fsb's, or the first/last block's are wrong.
610 */
611 if (got != count || mapp[0].br_startoff != bno ||
612 mapp[mapi - 1].br_startoff + mapp[mapi - 1].br_blockcount !=
613 bno + count) {
614 if (mapp != &map)
615 kmem_free(mapp);
616 return XFS_ERROR(ENOSPC);
617 }
618 /*
619 * Done with the temporary mapping table.
620 */
621 if (mapp != &map)
622 kmem_free(mapp);
623 527
624 /* account for newly allocated blocks in reserved blocks total */
625 args->total -= dp->i_d.di_nblocks - nblks;
626 *dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno); 528 *dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno);
627 529
628 /* 530 /*
@@ -634,7 +536,7 @@ xfs_dir2_grow_inode(
634 size = XFS_FSB_TO_B(mp, bno + count); 536 size = XFS_FSB_TO_B(mp, bno + count);
635 if (size > dp->i_d.di_size) { 537 if (size > dp->i_d.di_size) {
636 dp->i_d.di_size = size; 538 dp->i_d.di_size = size;
637 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 539 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
638 } 540 }
639 } 541 }
640 return 0; 542 return 0;
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 74a3b105768..e937d9991c1 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -16,49 +16,14 @@
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18#ifndef __XFS_DIR2_H__ 18#ifndef __XFS_DIR2_H__
19#define __XFS_DIR2_H__ 19#define __XFS_DIR2_H__
20 20
21struct uio;
22struct xfs_dabuf;
23struct xfs_da_args;
24struct xfs_dir2_put_args;
25struct xfs_bmap_free; 21struct xfs_bmap_free;
22struct xfs_da_args;
26struct xfs_inode; 23struct xfs_inode;
27struct xfs_mount; 24struct xfs_mount;
28struct xfs_trans; 25struct xfs_trans;
29 26
30/*
31 * Directory version 2.
32 * There are 4 possible formats:
33 * shortform
34 * single block - data with embedded leaf at the end
35 * multiple data blocks, single leaf+freeindex block
36 * data blocks, node&leaf blocks (btree), freeindex blocks
37 *
38 * The shortform format is in xfs_dir2_sf.h.
39 * The single block format is in xfs_dir2_block.h.
40 * The data block format is in xfs_dir2_data.h.
41 * The leaf and freeindex block formats are in xfs_dir2_leaf.h.
42 * Node blocks are the same as the other version, in xfs_da_btree.h.
43 */
44
45/*
46 * Byte offset in data block and shortform entry.
47 */
48typedef __uint16_t xfs_dir2_data_off_t;
49#define NULLDATAOFF 0xffffU
50typedef uint xfs_dir2_data_aoff_t; /* argument form */
51
52/*
53 * Directory block number (logical dirblk in file)
54 */
55typedef __uint32_t xfs_dir2_db_t;
56
57/*
58 * Byte offset in a directory.
59 */
60typedef xfs_off_t xfs_dir2_off_t;
61
62extern struct xfs_name xfs_name_dotdot; 27extern struct xfs_name xfs_name_dotdot;
63 28
64/* 29/*
@@ -86,21 +51,10 @@ extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
86 struct xfs_bmap_free *flist, xfs_extlen_t tot); 51 struct xfs_bmap_free *flist, xfs_extlen_t tot);
87extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, 52extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
88 struct xfs_name *name, uint resblks); 53 struct xfs_name *name, uint resblks);
89extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
90 54
91/* 55/*
92 * Utility routines for v2 directories. 56 * Direct call from the bmap code, bypassing the generic directory layer.
93 */ 57 */
94extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, 58extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
95 xfs_dir2_db_t *dbp);
96extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp,
97 int *vp);
98extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp,
99 int *vp);
100extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
101 struct xfs_dabuf *bp);
102
103extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
104 const unsigned char *name, int len);
105 59
106#endif /* __XFS_DIR2_H__ */ 60#endif /* __XFS_DIR2_H__ */
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 580d99cef9e..9245e029b8e 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -23,17 +23,14 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_da_btree.h" 27#include "xfs_da_btree.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir2_sf.h"
31#include "xfs_dinode.h" 29#include "xfs_dinode.h"
32#include "xfs_inode.h" 30#include "xfs_inode.h"
33#include "xfs_inode_item.h" 31#include "xfs_inode_item.h"
34#include "xfs_dir2_data.h" 32#include "xfs_dir2_format.h"
35#include "xfs_dir2_leaf.h" 33#include "xfs_dir2_priv.h"
36#include "xfs_dir2_block.h"
37#include "xfs_error.h" 34#include "xfs_error.h"
38#include "xfs_trace.h" 35#include "xfs_trace.h"
39 36
@@ -67,7 +64,7 @@ xfs_dir2_block_addname(
67 xfs_da_args_t *args) /* directory op arguments */ 64 xfs_da_args_t *args) /* directory op arguments */
68{ 65{
69 xfs_dir2_data_free_t *bf; /* bestfree table in block */ 66 xfs_dir2_data_free_t *bf; /* bestfree table in block */
70 xfs_dir2_block_t *block; /* directory block structure */ 67 xfs_dir2_data_hdr_t *hdr; /* block header */
71 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 68 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
72 xfs_dabuf_t *bp; /* buffer for block */ 69 xfs_dabuf_t *bp; /* buffer for block */
73 xfs_dir2_block_tail_t *btp; /* block tail */ 70 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -105,13 +102,13 @@ xfs_dir2_block_addname(
105 return error; 102 return error;
106 } 103 }
107 ASSERT(bp != NULL); 104 ASSERT(bp != NULL);
108 block = bp->data; 105 hdr = bp->data;
109 /* 106 /*
110 * Check the magic number, corrupted if wrong. 107 * Check the magic number, corrupted if wrong.
111 */ 108 */
112 if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) { 109 if (unlikely(hdr->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))) {
113 XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", 110 XFS_CORRUPTION_ERROR("xfs_dir2_block_addname",
114 XFS_ERRLEVEL_LOW, mp, block); 111 XFS_ERRLEVEL_LOW, mp, hdr);
115 xfs_da_brelse(tp, bp); 112 xfs_da_brelse(tp, bp);
116 return XFS_ERROR(EFSCORRUPTED); 113 return XFS_ERROR(EFSCORRUPTED);
117 } 114 }
@@ -119,8 +116,8 @@ xfs_dir2_block_addname(
119 /* 116 /*
120 * Set up pointers to parts of the block. 117 * Set up pointers to parts of the block.
121 */ 118 */
122 bf = block->hdr.bestfree; 119 bf = hdr->bestfree;
123 btp = xfs_dir2_block_tail_p(mp, block); 120 btp = xfs_dir2_block_tail_p(mp, hdr);
124 blp = xfs_dir2_block_leaf_p(btp); 121 blp = xfs_dir2_block_leaf_p(btp);
125 /* 122 /*
126 * No stale entries? Need space for entry and new leaf. 123 * No stale entries? Need space for entry and new leaf.
@@ -133,7 +130,7 @@ xfs_dir2_block_addname(
133 /* 130 /*
134 * Data object just before the first leaf entry. 131 * Data object just before the first leaf entry.
135 */ 132 */
136 enddup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); 133 enddup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
137 /* 134 /*
138 * If it's not free then can't do this add without cleaning up: 135 * If it's not free then can't do this add without cleaning up:
139 * the space before the first leaf entry needs to be free so it 136 * the space before the first leaf entry needs to be free so it
@@ -146,7 +143,7 @@ xfs_dir2_block_addname(
146 */ 143 */
147 else { 144 else {
148 dup = (xfs_dir2_data_unused_t *) 145 dup = (xfs_dir2_data_unused_t *)
149 ((char *)block + be16_to_cpu(bf[0].offset)); 146 ((char *)hdr + be16_to_cpu(bf[0].offset));
150 if (dup == enddup) { 147 if (dup == enddup) {
151 /* 148 /*
152 * It is the biggest freespace, is it too small 149 * It is the biggest freespace, is it too small
@@ -159,7 +156,7 @@ xfs_dir2_block_addname(
159 */ 156 */
160 if (be16_to_cpu(bf[1].length) >= len) 157 if (be16_to_cpu(bf[1].length) >= len)
161 dup = (xfs_dir2_data_unused_t *) 158 dup = (xfs_dir2_data_unused_t *)
162 ((char *)block + 159 ((char *)hdr +
163 be16_to_cpu(bf[1].offset)); 160 be16_to_cpu(bf[1].offset));
164 else 161 else
165 dup = NULL; 162 dup = NULL;
@@ -182,7 +179,7 @@ xfs_dir2_block_addname(
182 */ 179 */
183 else if (be16_to_cpu(bf[0].length) >= len) { 180 else if (be16_to_cpu(bf[0].length) >= len) {
184 dup = (xfs_dir2_data_unused_t *) 181 dup = (xfs_dir2_data_unused_t *)
185 ((char *)block + be16_to_cpu(bf[0].offset)); 182 ((char *)hdr + be16_to_cpu(bf[0].offset));
186 compact = 0; 183 compact = 0;
187 } 184 }
188 /* 185 /*
@@ -196,7 +193,7 @@ xfs_dir2_block_addname(
196 /* 193 /*
197 * Data object just before the first leaf entry. 194 * Data object just before the first leaf entry.
198 */ 195 */
199 dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); 196 dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
200 /* 197 /*
201 * If it's not free then the data will go where the 198 * If it's not free then the data will go where the
202 * leaf data starts now, if it works at all. 199 * leaf data starts now, if it works at all.
@@ -255,7 +252,8 @@ xfs_dir2_block_addname(
255 highstale = lfloghigh = -1; 252 highstale = lfloghigh = -1;
256 fromidx >= 0; 253 fromidx >= 0;
257 fromidx--) { 254 fromidx--) {
258 if (be32_to_cpu(blp[fromidx].address) == XFS_DIR2_NULL_DATAPTR) { 255 if (blp[fromidx].address ==
256 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) {
259 if (highstale == -1) 257 if (highstale == -1)
260 highstale = toidx; 258 highstale = toidx;
261 else { 259 else {
@@ -272,7 +270,7 @@ xfs_dir2_block_addname(
272 lfloghigh -= be32_to_cpu(btp->stale) - 1; 270 lfloghigh -= be32_to_cpu(btp->stale) - 1;
273 be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); 271 be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1));
274 xfs_dir2_data_make_free(tp, bp, 272 xfs_dir2_data_make_free(tp, bp,
275 (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), 273 (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
276 (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), 274 (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
277 &needlog, &needscan); 275 &needlog, &needscan);
278 blp += be32_to_cpu(btp->stale) - 1; 276 blp += be32_to_cpu(btp->stale) - 1;
@@ -282,7 +280,7 @@ xfs_dir2_block_addname(
282 * This needs to happen before the next call to use_free. 280 * This needs to happen before the next call to use_free.
283 */ 281 */
284 if (needscan) { 282 if (needscan) {
285 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); 283 xfs_dir2_data_freescan(mp, hdr, &needlog);
286 needscan = 0; 284 needscan = 0;
287 } 285 }
288 } 286 }
@@ -318,7 +316,7 @@ xfs_dir2_block_addname(
318 */ 316 */
319 xfs_dir2_data_use_free(tp, bp, enddup, 317 xfs_dir2_data_use_free(tp, bp, enddup,
320 (xfs_dir2_data_aoff_t) 318 (xfs_dir2_data_aoff_t)
321 ((char *)enddup - (char *)block + be16_to_cpu(enddup->length) - 319 ((char *)enddup - (char *)hdr + be16_to_cpu(enddup->length) -
322 sizeof(*blp)), 320 sizeof(*blp)),
323 (xfs_dir2_data_aoff_t)sizeof(*blp), 321 (xfs_dir2_data_aoff_t)sizeof(*blp),
324 &needlog, &needscan); 322 &needlog, &needscan);
@@ -331,8 +329,7 @@ xfs_dir2_block_addname(
331 * This needs to happen before the next call to use_free. 329 * This needs to happen before the next call to use_free.
332 */ 330 */
333 if (needscan) { 331 if (needscan) {
334 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, 332 xfs_dir2_data_freescan(mp, hdr, &needlog);
335 &needlog);
336 needscan = 0; 333 needscan = 0;
337 } 334 }
338 /* 335 /*
@@ -353,12 +350,14 @@ xfs_dir2_block_addname(
353 else { 350 else {
354 for (lowstale = mid; 351 for (lowstale = mid;
355 lowstale >= 0 && 352 lowstale >= 0 &&
356 be32_to_cpu(blp[lowstale].address) != XFS_DIR2_NULL_DATAPTR; 353 blp[lowstale].address !=
354 cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
357 lowstale--) 355 lowstale--)
358 continue; 356 continue;
359 for (highstale = mid + 1; 357 for (highstale = mid + 1;
360 highstale < be32_to_cpu(btp->count) && 358 highstale < be32_to_cpu(btp->count) &&
361 be32_to_cpu(blp[highstale].address) != XFS_DIR2_NULL_DATAPTR && 359 blp[highstale].address !=
360 cpu_to_be32(XFS_DIR2_NULL_DATAPTR) &&
362 (lowstale < 0 || mid - lowstale > highstale - mid); 361 (lowstale < 0 || mid - lowstale > highstale - mid);
363 highstale++) 362 highstale++)
364 continue; 363 continue;
@@ -397,13 +396,13 @@ xfs_dir2_block_addname(
397 */ 396 */
398 blp[mid].hashval = cpu_to_be32(args->hashval); 397 blp[mid].hashval = cpu_to_be32(args->hashval);
399 blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 398 blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
400 (char *)dep - (char *)block)); 399 (char *)dep - (char *)hdr));
401 xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); 400 xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh);
402 /* 401 /*
403 * Mark space for the data entry used. 402 * Mark space for the data entry used.
404 */ 403 */
405 xfs_dir2_data_use_free(tp, bp, dup, 404 xfs_dir2_data_use_free(tp, bp, dup,
406 (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), 405 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
407 (xfs_dir2_data_aoff_t)len, &needlog, &needscan); 406 (xfs_dir2_data_aoff_t)len, &needlog, &needscan);
408 /* 407 /*
409 * Create the new data entry. 408 * Create the new data entry.
@@ -412,12 +411,12 @@ xfs_dir2_block_addname(
412 dep->namelen = args->namelen; 411 dep->namelen = args->namelen;
413 memcpy(dep->name, args->name, args->namelen); 412 memcpy(dep->name, args->name, args->namelen);
414 tagp = xfs_dir2_data_entry_tag_p(dep); 413 tagp = xfs_dir2_data_entry_tag_p(dep);
415 *tagp = cpu_to_be16((char *)dep - (char *)block); 414 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
416 /* 415 /*
417 * Clean up the bestfree array and log the header, tail, and entry. 416 * Clean up the bestfree array and log the header, tail, and entry.
418 */ 417 */
419 if (needscan) 418 if (needscan)
420 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); 419 xfs_dir2_data_freescan(mp, hdr, &needlog);
421 if (needlog) 420 if (needlog)
422 xfs_dir2_data_log_header(tp, bp); 421 xfs_dir2_data_log_header(tp, bp);
423 xfs_dir2_block_log_tail(tp, bp); 422 xfs_dir2_block_log_tail(tp, bp);
@@ -437,7 +436,7 @@ xfs_dir2_block_getdents(
437 xfs_off_t *offset, 436 xfs_off_t *offset,
438 filldir_t filldir) 437 filldir_t filldir)
439{ 438{
440 xfs_dir2_block_t *block; /* directory block structure */ 439 xfs_dir2_data_hdr_t *hdr; /* block header */
441 xfs_dabuf_t *bp; /* buffer for block */ 440 xfs_dabuf_t *bp; /* buffer for block */
442 xfs_dir2_block_tail_t *btp; /* block tail */ 441 xfs_dir2_block_tail_t *btp; /* block tail */
443 xfs_dir2_data_entry_t *dep; /* block data entry */ 442 xfs_dir2_data_entry_t *dep; /* block data entry */
@@ -470,13 +469,13 @@ xfs_dir2_block_getdents(
470 * We'll skip entries before this. 469 * We'll skip entries before this.
471 */ 470 */
472 wantoff = xfs_dir2_dataptr_to_off(mp, *offset); 471 wantoff = xfs_dir2_dataptr_to_off(mp, *offset);
473 block = bp->data; 472 hdr = bp->data;
474 xfs_dir2_data_check(dp, bp); 473 xfs_dir2_data_check(dp, bp);
475 /* 474 /*
476 * Set up values for the loop. 475 * Set up values for the loop.
477 */ 476 */
478 btp = xfs_dir2_block_tail_p(mp, block); 477 btp = xfs_dir2_block_tail_p(mp, hdr);
479 ptr = (char *)block->u; 478 ptr = (char *)(hdr + 1);
480 endptr = (char *)xfs_dir2_block_leaf_p(btp); 479 endptr = (char *)xfs_dir2_block_leaf_p(btp);
481 480
482 /* 481 /*
@@ -502,11 +501,11 @@ xfs_dir2_block_getdents(
502 /* 501 /*
503 * The entry is before the desired starting point, skip it. 502 * The entry is before the desired starting point, skip it.
504 */ 503 */
505 if ((char *)dep - (char *)block < wantoff) 504 if ((char *)dep - (char *)hdr < wantoff)
506 continue; 505 continue;
507 506
508 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 507 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
509 (char *)dep - (char *)block); 508 (char *)dep - (char *)hdr);
510 509
511 /* 510 /*
512 * If it didn't fit, set the final offset to here & return. 511 * If it didn't fit, set the final offset to here & return.
@@ -540,17 +539,14 @@ xfs_dir2_block_log_leaf(
540 int first, /* index of first logged leaf */ 539 int first, /* index of first logged leaf */
541 int last) /* index of last logged leaf */ 540 int last) /* index of last logged leaf */
542{ 541{
543 xfs_dir2_block_t *block; /* directory block structure */ 542 xfs_dir2_data_hdr_t *hdr = bp->data;
544 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 543 xfs_dir2_leaf_entry_t *blp;
545 xfs_dir2_block_tail_t *btp; /* block tail */ 544 xfs_dir2_block_tail_t *btp;
546 xfs_mount_t *mp; /* filesystem mount point */
547 545
548 mp = tp->t_mountp; 546 btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr);
549 block = bp->data;
550 btp = xfs_dir2_block_tail_p(mp, block);
551 blp = xfs_dir2_block_leaf_p(btp); 547 blp = xfs_dir2_block_leaf_p(btp);
552 xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block), 548 xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr),
553 (uint)((char *)&blp[last + 1] - (char *)block - 1)); 549 (uint)((char *)&blp[last + 1] - (char *)hdr - 1));
554} 550}
555 551
556/* 552/*
@@ -561,15 +557,12 @@ xfs_dir2_block_log_tail(
561 xfs_trans_t *tp, /* transaction structure */ 557 xfs_trans_t *tp, /* transaction structure */
562 xfs_dabuf_t *bp) /* block buffer */ 558 xfs_dabuf_t *bp) /* block buffer */
563{ 559{
564 xfs_dir2_block_t *block; /* directory block structure */ 560 xfs_dir2_data_hdr_t *hdr = bp->data;
565 xfs_dir2_block_tail_t *btp; /* block tail */ 561 xfs_dir2_block_tail_t *btp;
566 xfs_mount_t *mp; /* filesystem mount point */
567 562
568 mp = tp->t_mountp; 563 btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr);
569 block = bp->data; 564 xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr),
570 btp = xfs_dir2_block_tail_p(mp, block); 565 (uint)((char *)(btp + 1) - (char *)hdr - 1));
571 xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block),
572 (uint)((char *)(btp + 1) - (char *)block - 1));
573} 566}
574 567
575/* 568/*
@@ -580,7 +573,7 @@ int /* error */
580xfs_dir2_block_lookup( 573xfs_dir2_block_lookup(
581 xfs_da_args_t *args) /* dir lookup arguments */ 574 xfs_da_args_t *args) /* dir lookup arguments */
582{ 575{
583 xfs_dir2_block_t *block; /* block structure */ 576 xfs_dir2_data_hdr_t *hdr; /* block header */
584 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 577 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
585 xfs_dabuf_t *bp; /* block buffer */ 578 xfs_dabuf_t *bp; /* block buffer */
586 xfs_dir2_block_tail_t *btp; /* block tail */ 579 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -600,14 +593,14 @@ xfs_dir2_block_lookup(
600 return error; 593 return error;
601 dp = args->dp; 594 dp = args->dp;
602 mp = dp->i_mount; 595 mp = dp->i_mount;
603 block = bp->data; 596 hdr = bp->data;
604 xfs_dir2_data_check(dp, bp); 597 xfs_dir2_data_check(dp, bp);
605 btp = xfs_dir2_block_tail_p(mp, block); 598 btp = xfs_dir2_block_tail_p(mp, hdr);
606 blp = xfs_dir2_block_leaf_p(btp); 599 blp = xfs_dir2_block_leaf_p(btp);
607 /* 600 /*
608 * Get the offset from the leaf entry, to point to the data. 601 * Get the offset from the leaf entry, to point to the data.
609 */ 602 */
610 dep = (xfs_dir2_data_entry_t *)((char *)block + 603 dep = (xfs_dir2_data_entry_t *)((char *)hdr +
611 xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); 604 xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
612 /* 605 /*
613 * Fill in inode number, CI name if appropriate, release the block. 606 * Fill in inode number, CI name if appropriate, release the block.
@@ -628,7 +621,7 @@ xfs_dir2_block_lookup_int(
628 int *entno) /* returned entry number */ 621 int *entno) /* returned entry number */
629{ 622{
630 xfs_dir2_dataptr_t addr; /* data entry address */ 623 xfs_dir2_dataptr_t addr; /* data entry address */
631 xfs_dir2_block_t *block; /* block structure */ 624 xfs_dir2_data_hdr_t *hdr; /* block header */
632 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 625 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
633 xfs_dabuf_t *bp; /* block buffer */ 626 xfs_dabuf_t *bp; /* block buffer */
634 xfs_dir2_block_tail_t *btp; /* block tail */ 627 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -654,9 +647,9 @@ xfs_dir2_block_lookup_int(
654 return error; 647 return error;
655 } 648 }
656 ASSERT(bp != NULL); 649 ASSERT(bp != NULL);
657 block = bp->data; 650 hdr = bp->data;
658 xfs_dir2_data_check(dp, bp); 651 xfs_dir2_data_check(dp, bp);
659 btp = xfs_dir2_block_tail_p(mp, block); 652 btp = xfs_dir2_block_tail_p(mp, hdr);
660 blp = xfs_dir2_block_leaf_p(btp); 653 blp = xfs_dir2_block_leaf_p(btp);
661 /* 654 /*
662 * Loop doing a binary search for our hash value. 655 * Loop doing a binary search for our hash value.
@@ -694,7 +687,7 @@ xfs_dir2_block_lookup_int(
694 * Get pointer to the entry from the leaf. 687 * Get pointer to the entry from the leaf.
695 */ 688 */
696 dep = (xfs_dir2_data_entry_t *) 689 dep = (xfs_dir2_data_entry_t *)
697 ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); 690 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr));
698 /* 691 /*
699 * Compare name and if it's an exact match, return the index 692 * Compare name and if it's an exact match, return the index
700 * and buffer. If it's the first case-insensitive match, store 693 * and buffer. If it's the first case-insensitive match, store
@@ -733,7 +726,7 @@ int /* error */
733xfs_dir2_block_removename( 726xfs_dir2_block_removename(
734 xfs_da_args_t *args) /* directory operation args */ 727 xfs_da_args_t *args) /* directory operation args */
735{ 728{
736 xfs_dir2_block_t *block; /* block structure */ 729 xfs_dir2_data_hdr_t *hdr; /* block header */
737 xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */ 730 xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */
738 xfs_dabuf_t *bp; /* block buffer */ 731 xfs_dabuf_t *bp; /* block buffer */
739 xfs_dir2_block_tail_t *btp; /* block tail */ 732 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -760,20 +753,20 @@ xfs_dir2_block_removename(
760 dp = args->dp; 753 dp = args->dp;
761 tp = args->trans; 754 tp = args->trans;
762 mp = dp->i_mount; 755 mp = dp->i_mount;
763 block = bp->data; 756 hdr = bp->data;
764 btp = xfs_dir2_block_tail_p(mp, block); 757 btp = xfs_dir2_block_tail_p(mp, hdr);
765 blp = xfs_dir2_block_leaf_p(btp); 758 blp = xfs_dir2_block_leaf_p(btp);
766 /* 759 /*
767 * Point to the data entry using the leaf entry. 760 * Point to the data entry using the leaf entry.
768 */ 761 */
769 dep = (xfs_dir2_data_entry_t *) 762 dep = (xfs_dir2_data_entry_t *)
770 ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); 763 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
771 /* 764 /*
772 * Mark the data entry's space free. 765 * Mark the data entry's space free.
773 */ 766 */
774 needlog = needscan = 0; 767 needlog = needscan = 0;
775 xfs_dir2_data_make_free(tp, bp, 768 xfs_dir2_data_make_free(tp, bp,
776 (xfs_dir2_data_aoff_t)((char *)dep - (char *)block), 769 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
777 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); 770 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
778 /* 771 /*
779 * Fix up the block tail. 772 * Fix up the block tail.
@@ -789,15 +782,15 @@ xfs_dir2_block_removename(
789 * Fix up bestfree, log the header if necessary. 782 * Fix up bestfree, log the header if necessary.
790 */ 783 */
791 if (needscan) 784 if (needscan)
792 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); 785 xfs_dir2_data_freescan(mp, hdr, &needlog);
793 if (needlog) 786 if (needlog)
794 xfs_dir2_data_log_header(tp, bp); 787 xfs_dir2_data_log_header(tp, bp);
795 xfs_dir2_data_check(dp, bp); 788 xfs_dir2_data_check(dp, bp);
796 /* 789 /*
797 * See if the size as a shortform is good enough. 790 * See if the size as a shortform is good enough.
798 */ 791 */
799 if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > 792 size = xfs_dir2_block_sfsize(dp, hdr, &sfh);
800 XFS_IFORK_DSIZE(dp)) { 793 if (size > XFS_IFORK_DSIZE(dp)) {
801 xfs_da_buf_done(bp); 794 xfs_da_buf_done(bp);
802 return 0; 795 return 0;
803 } 796 }
@@ -815,7 +808,7 @@ int /* error */
815xfs_dir2_block_replace( 808xfs_dir2_block_replace(
816 xfs_da_args_t *args) /* directory operation args */ 809 xfs_da_args_t *args) /* directory operation args */
817{ 810{
818 xfs_dir2_block_t *block; /* block structure */ 811 xfs_dir2_data_hdr_t *hdr; /* block header */
819 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 812 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
820 xfs_dabuf_t *bp; /* block buffer */ 813 xfs_dabuf_t *bp; /* block buffer */
821 xfs_dir2_block_tail_t *btp; /* block tail */ 814 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -836,14 +829,14 @@ xfs_dir2_block_replace(
836 } 829 }
837 dp = args->dp; 830 dp = args->dp;
838 mp = dp->i_mount; 831 mp = dp->i_mount;
839 block = bp->data; 832 hdr = bp->data;
840 btp = xfs_dir2_block_tail_p(mp, block); 833 btp = xfs_dir2_block_tail_p(mp, hdr);
841 blp = xfs_dir2_block_leaf_p(btp); 834 blp = xfs_dir2_block_leaf_p(btp);
842 /* 835 /*
843 * Point to the data entry we need to change. 836 * Point to the data entry we need to change.
844 */ 837 */
845 dep = (xfs_dir2_data_entry_t *) 838 dep = (xfs_dir2_data_entry_t *)
846 ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); 839 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address)));
847 ASSERT(be64_to_cpu(dep->inumber) != args->inumber); 840 ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
848 /* 841 /*
849 * Change the inode number to the new value. 842 * Change the inode number to the new value.
@@ -882,7 +875,7 @@ xfs_dir2_leaf_to_block(
882 xfs_dabuf_t *dbp) /* data buffer */ 875 xfs_dabuf_t *dbp) /* data buffer */
883{ 876{
884 __be16 *bestsp; /* leaf bests table */ 877 __be16 *bestsp; /* leaf bests table */
885 xfs_dir2_block_t *block; /* block structure */ 878 xfs_dir2_data_hdr_t *hdr; /* block header */
886 xfs_dir2_block_tail_t *btp; /* block tail */ 879 xfs_dir2_block_tail_t *btp; /* block tail */
887 xfs_inode_t *dp; /* incore directory inode */ 880 xfs_inode_t *dp; /* incore directory inode */
888 xfs_dir2_data_unused_t *dup; /* unused data entry */ 881 xfs_dir2_data_unused_t *dup; /* unused data entry */
@@ -906,7 +899,7 @@ xfs_dir2_leaf_to_block(
906 tp = args->trans; 899 tp = args->trans;
907 mp = dp->i_mount; 900 mp = dp->i_mount;
908 leaf = lbp->data; 901 leaf = lbp->data;
909 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); 902 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
910 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 903 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
911 /* 904 /*
912 * If there are data blocks other than the first one, take this 905 * If there are data blocks other than the first one, take this
@@ -917,7 +910,7 @@ xfs_dir2_leaf_to_block(
917 while (dp->i_d.di_size > mp->m_dirblksize) { 910 while (dp->i_d.di_size > mp->m_dirblksize) {
918 bestsp = xfs_dir2_leaf_bests_p(ltp); 911 bestsp = xfs_dir2_leaf_bests_p(ltp);
919 if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == 912 if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) ==
920 mp->m_dirblksize - (uint)sizeof(block->hdr)) { 913 mp->m_dirblksize - (uint)sizeof(*hdr)) {
921 if ((error = 914 if ((error =
922 xfs_dir2_leaf_trim_data(args, lbp, 915 xfs_dir2_leaf_trim_data(args, lbp,
923 (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) 916 (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1))))
@@ -935,18 +928,18 @@ xfs_dir2_leaf_to_block(
935 XFS_DATA_FORK))) { 928 XFS_DATA_FORK))) {
936 goto out; 929 goto out;
937 } 930 }
938 block = dbp->data; 931 hdr = dbp->data;
939 ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC); 932 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC));
940 /* 933 /*
941 * Size of the "leaf" area in the block. 934 * Size of the "leaf" area in the block.
942 */ 935 */
943 size = (uint)sizeof(block->tail) + 936 size = (uint)sizeof(xfs_dir2_block_tail_t) +
944 (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); 937 (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale));
945 /* 938 /*
946 * Look at the last data entry. 939 * Look at the last data entry.
947 */ 940 */
948 tagp = (__be16 *)((char *)block + mp->m_dirblksize) - 1; 941 tagp = (__be16 *)((char *)hdr + mp->m_dirblksize) - 1;
949 dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); 942 dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
950 /* 943 /*
951 * If it's not free or is too short we can't do it. 944 * If it's not free or is too short we can't do it.
952 */ 945 */
@@ -958,7 +951,7 @@ xfs_dir2_leaf_to_block(
958 /* 951 /*
959 * Start converting it to block form. 952 * Start converting it to block form.
960 */ 953 */
961 block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); 954 hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
962 needlog = 1; 955 needlog = 1;
963 needscan = 0; 956 needscan = 0;
964 /* 957 /*
@@ -969,7 +962,7 @@ xfs_dir2_leaf_to_block(
969 /* 962 /*
970 * Initialize the block tail. 963 * Initialize the block tail.
971 */ 964 */
972 btp = xfs_dir2_block_tail_p(mp, block); 965 btp = xfs_dir2_block_tail_p(mp, hdr);
973 btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); 966 btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale));
974 btp->stale = 0; 967 btp->stale = 0;
975 xfs_dir2_block_log_tail(tp, dbp); 968 xfs_dir2_block_log_tail(tp, dbp);
@@ -978,7 +971,8 @@ xfs_dir2_leaf_to_block(
978 */ 971 */
979 lep = xfs_dir2_block_leaf_p(btp); 972 lep = xfs_dir2_block_leaf_p(btp);
980 for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { 973 for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) {
981 if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) 974 if (leaf->ents[from].address ==
975 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
982 continue; 976 continue;
983 lep[to++] = leaf->ents[from]; 977 lep[to++] = leaf->ents[from];
984 } 978 }
@@ -988,7 +982,7 @@ xfs_dir2_leaf_to_block(
988 * Scan the bestfree if we need it and log the data block header. 982 * Scan the bestfree if we need it and log the data block header.
989 */ 983 */
990 if (needscan) 984 if (needscan)
991 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); 985 xfs_dir2_data_freescan(mp, hdr, &needlog);
992 if (needlog) 986 if (needlog)
993 xfs_dir2_data_log_header(tp, dbp); 987 xfs_dir2_data_log_header(tp, dbp);
994 /* 988 /*
@@ -1002,8 +996,8 @@ xfs_dir2_leaf_to_block(
1002 /* 996 /*
1003 * Now see if the resulting block can be shrunken to shortform. 997 * Now see if the resulting block can be shrunken to shortform.
1004 */ 998 */
1005 if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > 999 size = xfs_dir2_block_sfsize(dp, hdr, &sfh);
1006 XFS_IFORK_DSIZE(dp)) { 1000 if (size > XFS_IFORK_DSIZE(dp)) {
1007 error = 0; 1001 error = 0;
1008 goto out; 1002 goto out;
1009 } 1003 }
@@ -1024,12 +1018,10 @@ xfs_dir2_sf_to_block(
1024 xfs_da_args_t *args) /* operation arguments */ 1018 xfs_da_args_t *args) /* operation arguments */
1025{ 1019{
1026 xfs_dir2_db_t blkno; /* dir-relative block # (0) */ 1020 xfs_dir2_db_t blkno; /* dir-relative block # (0) */
1027 xfs_dir2_block_t *block; /* block structure */ 1021 xfs_dir2_data_hdr_t *hdr; /* block header */
1028 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ 1022 xfs_dir2_leaf_entry_t *blp; /* block leaf entries */
1029 xfs_dabuf_t *bp; /* block buffer */ 1023 xfs_dabuf_t *bp; /* block buffer */
1030 xfs_dir2_block_tail_t *btp; /* block tail pointer */ 1024 xfs_dir2_block_tail_t *btp; /* block tail pointer */
1031 char *buf; /* sf buffer */
1032 int buf_len;
1033 xfs_dir2_data_entry_t *dep; /* data entry pointer */ 1025 xfs_dir2_data_entry_t *dep; /* data entry pointer */
1034 xfs_inode_t *dp; /* incore directory inode */ 1026 xfs_inode_t *dp; /* incore directory inode */
1035 int dummy; /* trash */ 1027 int dummy; /* trash */
@@ -1043,7 +1035,8 @@ xfs_dir2_sf_to_block(
1043 int newoffset; /* offset from current entry */ 1035 int newoffset; /* offset from current entry */
1044 int offset; /* target block offset */ 1036 int offset; /* target block offset */
1045 xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ 1037 xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */
1046 xfs_dir2_sf_t *sfp; /* shortform structure */ 1038 xfs_dir2_sf_hdr_t *oldsfp; /* old shortform header */
1039 xfs_dir2_sf_hdr_t *sfp; /* shortform header */
1047 __be16 *tagp; /* end of data entry */ 1040 __be16 *tagp; /* end of data entry */
1048 xfs_trans_t *tp; /* transaction pointer */ 1041 xfs_trans_t *tp; /* transaction pointer */
1049 struct xfs_name name; 1042 struct xfs_name name;
@@ -1061,32 +1054,30 @@ xfs_dir2_sf_to_block(
1061 ASSERT(XFS_FORCED_SHUTDOWN(mp)); 1054 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1062 return XFS_ERROR(EIO); 1055 return XFS_ERROR(EIO);
1063 } 1056 }
1057
1058 oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
1059
1064 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 1060 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
1065 ASSERT(dp->i_df.if_u1.if_data != NULL); 1061 ASSERT(dp->i_df.if_u1.if_data != NULL);
1066 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1062 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count));
1067 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); 1063
1068 /* 1064 /*
1069 * Copy the directory into the stack buffer. 1065 * Copy the directory into a temporary buffer.
1070 * Then pitch the incore inode data so we can make extents. 1066 * Then pitch the incore inode data so we can make extents.
1071 */ 1067 */
1068 sfp = kmem_alloc(dp->i_df.if_bytes, KM_SLEEP);
1069 memcpy(sfp, oldsfp, dp->i_df.if_bytes);
1072 1070
1073 buf_len = dp->i_df.if_bytes; 1071 xfs_idata_realloc(dp, -dp->i_df.if_bytes, XFS_DATA_FORK);
1074 buf = kmem_alloc(buf_len, KM_SLEEP);
1075
1076 memcpy(buf, sfp, buf_len);
1077 xfs_idata_realloc(dp, -buf_len, XFS_DATA_FORK);
1078 dp->i_d.di_size = 0; 1072 dp->i_d.di_size = 0;
1079 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 1073 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1080 /* 1074
1081 * Reset pointer - old sfp is gone.
1082 */
1083 sfp = (xfs_dir2_sf_t *)buf;
1084 /* 1075 /*
1085 * Add block 0 to the inode. 1076 * Add block 0 to the inode.
1086 */ 1077 */
1087 error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno); 1078 error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno);
1088 if (error) { 1079 if (error) {
1089 kmem_free(buf); 1080 kmem_free(sfp);
1090 return error; 1081 return error;
1091 } 1082 }
1092 /* 1083 /*
@@ -1094,21 +1085,21 @@ xfs_dir2_sf_to_block(
1094 */ 1085 */
1095 error = xfs_dir2_data_init(args, blkno, &bp); 1086 error = xfs_dir2_data_init(args, blkno, &bp);
1096 if (error) { 1087 if (error) {
1097 kmem_free(buf); 1088 kmem_free(sfp);
1098 return error; 1089 return error;
1099 } 1090 }
1100 block = bp->data; 1091 hdr = bp->data;
1101 block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); 1092 hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
1102 /* 1093 /*
1103 * Compute size of block "tail" area. 1094 * Compute size of block "tail" area.
1104 */ 1095 */
1105 i = (uint)sizeof(*btp) + 1096 i = (uint)sizeof(*btp) +
1106 (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); 1097 (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t);
1107 /* 1098 /*
1108 * The whole thing is initialized to free by the init routine. 1099 * The whole thing is initialized to free by the init routine.
1109 * Say we're using the leaf and tail area. 1100 * Say we're using the leaf and tail area.
1110 */ 1101 */
1111 dup = (xfs_dir2_data_unused_t *)block->u; 1102 dup = (xfs_dir2_data_unused_t *)(hdr + 1);
1112 needlog = needscan = 0; 1103 needlog = needscan = 0;
1113 xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog, 1104 xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog,
1114 &needscan); 1105 &needscan);
@@ -1116,50 +1107,51 @@ xfs_dir2_sf_to_block(
1116 /* 1107 /*
1117 * Fill in the tail. 1108 * Fill in the tail.
1118 */ 1109 */
1119 btp = xfs_dir2_block_tail_p(mp, block); 1110 btp = xfs_dir2_block_tail_p(mp, hdr);
1120 btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */ 1111 btp->count = cpu_to_be32(sfp->count + 2); /* ., .. */
1121 btp->stale = 0; 1112 btp->stale = 0;
1122 blp = xfs_dir2_block_leaf_p(btp); 1113 blp = xfs_dir2_block_leaf_p(btp);
1123 endoffset = (uint)((char *)blp - (char *)block); 1114 endoffset = (uint)((char *)blp - (char *)hdr);
1124 /* 1115 /*
1125 * Remove the freespace, we'll manage it. 1116 * Remove the freespace, we'll manage it.
1126 */ 1117 */
1127 xfs_dir2_data_use_free(tp, bp, dup, 1118 xfs_dir2_data_use_free(tp, bp, dup,
1128 (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), 1119 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
1129 be16_to_cpu(dup->length), &needlog, &needscan); 1120 be16_to_cpu(dup->length), &needlog, &needscan);
1130 /* 1121 /*
1131 * Create entry for . 1122 * Create entry for .
1132 */ 1123 */
1133 dep = (xfs_dir2_data_entry_t *) 1124 dep = (xfs_dir2_data_entry_t *)
1134 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); 1125 ((char *)hdr + XFS_DIR2_DATA_DOT_OFFSET);
1135 dep->inumber = cpu_to_be64(dp->i_ino); 1126 dep->inumber = cpu_to_be64(dp->i_ino);
1136 dep->namelen = 1; 1127 dep->namelen = 1;
1137 dep->name[0] = '.'; 1128 dep->name[0] = '.';
1138 tagp = xfs_dir2_data_entry_tag_p(dep); 1129 tagp = xfs_dir2_data_entry_tag_p(dep);
1139 *tagp = cpu_to_be16((char *)dep - (char *)block); 1130 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1140 xfs_dir2_data_log_entry(tp, bp, dep); 1131 xfs_dir2_data_log_entry(tp, bp, dep);
1141 blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); 1132 blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
1142 blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1133 blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
1143 (char *)dep - (char *)block)); 1134 (char *)dep - (char *)hdr));
1144 /* 1135 /*
1145 * Create entry for .. 1136 * Create entry for ..
1146 */ 1137 */
1147 dep = (xfs_dir2_data_entry_t *) 1138 dep = (xfs_dir2_data_entry_t *)
1148 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); 1139 ((char *)hdr + XFS_DIR2_DATA_DOTDOT_OFFSET);
1149 dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); 1140 dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
1150 dep->namelen = 2; 1141 dep->namelen = 2;
1151 dep->name[0] = dep->name[1] = '.'; 1142 dep->name[0] = dep->name[1] = '.';
1152 tagp = xfs_dir2_data_entry_tag_p(dep); 1143 tagp = xfs_dir2_data_entry_tag_p(dep);
1153 *tagp = cpu_to_be16((char *)dep - (char *)block); 1144 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1154 xfs_dir2_data_log_entry(tp, bp, dep); 1145 xfs_dir2_data_log_entry(tp, bp, dep);
1155 blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); 1146 blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
1156 blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1147 blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
1157 (char *)dep - (char *)block)); 1148 (char *)dep - (char *)hdr));
1158 offset = XFS_DIR2_DATA_FIRST_OFFSET; 1149 offset = XFS_DIR2_DATA_FIRST_OFFSET;
1159 /* 1150 /*
1160 * Loop over existing entries, stuff them in. 1151 * Loop over existing entries, stuff them in.
1161 */ 1152 */
1162 if ((i = 0) == sfp->hdr.count) 1153 i = 0;
1154 if (!sfp->count)
1163 sfep = NULL; 1155 sfep = NULL;
1164 else 1156 else
1165 sfep = xfs_dir2_sf_firstentry(sfp); 1157 sfep = xfs_dir2_sf_firstentry(sfp);
@@ -1179,43 +1171,40 @@ xfs_dir2_sf_to_block(
1179 * There should be a hole here, make one. 1171 * There should be a hole here, make one.
1180 */ 1172 */
1181 if (offset < newoffset) { 1173 if (offset < newoffset) {
1182 dup = (xfs_dir2_data_unused_t *) 1174 dup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
1183 ((char *)block + offset);
1184 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 1175 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1185 dup->length = cpu_to_be16(newoffset - offset); 1176 dup->length = cpu_to_be16(newoffset - offset);
1186 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( 1177 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(
1187 ((char *)dup - (char *)block)); 1178 ((char *)dup - (char *)hdr));
1188 xfs_dir2_data_log_unused(tp, bp, dup); 1179 xfs_dir2_data_log_unused(tp, bp, dup);
1189 (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block, 1180 xfs_dir2_data_freeinsert(hdr, dup, &dummy);
1190 dup, &dummy);
1191 offset += be16_to_cpu(dup->length); 1181 offset += be16_to_cpu(dup->length);
1192 continue; 1182 continue;
1193 } 1183 }
1194 /* 1184 /*
1195 * Copy a real entry. 1185 * Copy a real entry.
1196 */ 1186 */
1197 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); 1187 dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
1198 dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, 1188 dep->inumber = cpu_to_be64(xfs_dir2_sfe_get_ino(sfp, sfep));
1199 xfs_dir2_sf_inumberp(sfep)));
1200 dep->namelen = sfep->namelen; 1189 dep->namelen = sfep->namelen;
1201 memcpy(dep->name, sfep->name, dep->namelen); 1190 memcpy(dep->name, sfep->name, dep->namelen);
1202 tagp = xfs_dir2_data_entry_tag_p(dep); 1191 tagp = xfs_dir2_data_entry_tag_p(dep);
1203 *tagp = cpu_to_be16((char *)dep - (char *)block); 1192 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1204 xfs_dir2_data_log_entry(tp, bp, dep); 1193 xfs_dir2_data_log_entry(tp, bp, dep);
1205 name.name = sfep->name; 1194 name.name = sfep->name;
1206 name.len = sfep->namelen; 1195 name.len = sfep->namelen;
1207 blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> 1196 blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->
1208 hashname(&name)); 1197 hashname(&name));
1209 blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1198 blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
1210 (char *)dep - (char *)block)); 1199 (char *)dep - (char *)hdr));
1211 offset = (int)((char *)(tagp + 1) - (char *)block); 1200 offset = (int)((char *)(tagp + 1) - (char *)hdr);
1212 if (++i == sfp->hdr.count) 1201 if (++i == sfp->count)
1213 sfep = NULL; 1202 sfep = NULL;
1214 else 1203 else
1215 sfep = xfs_dir2_sf_nextentry(sfp, sfep); 1204 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
1216 } 1205 }
1217 /* Done with the temporary buffer */ 1206 /* Done with the temporary buffer */
1218 kmem_free(buf); 1207 kmem_free(sfp);
1219 /* 1208 /*
1220 * Sort the leaf entries by hash value. 1209 * Sort the leaf entries by hash value.
1221 */ 1210 */
diff --git a/fs/xfs/xfs_dir2_block.h b/fs/xfs/xfs_dir2_block.h
deleted file mode 100644
index 10e68967638..00000000000
--- a/fs/xfs/xfs_dir2_block.h
+++ /dev/null
@@ -1,92 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_BLOCK_H__
19#define __XFS_DIR2_BLOCK_H__
20
21/*
22 * xfs_dir2_block.h
23 * Directory version 2, single block format structures
24 */
25
26struct uio;
27struct xfs_dabuf;
28struct xfs_da_args;
29struct xfs_dir2_data_hdr;
30struct xfs_dir2_leaf_entry;
31struct xfs_inode;
32struct xfs_mount;
33struct xfs_trans;
34
35/*
36 * The single block format is as follows:
37 * xfs_dir2_data_hdr_t structure
38 * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures
39 * xfs_dir2_leaf_entry_t structures
40 * xfs_dir2_block_tail_t structure
41 */
42
43#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */
44
45typedef struct xfs_dir2_block_tail {
46 __be32 count; /* count of leaf entries */
47 __be32 stale; /* count of stale lf entries */
48} xfs_dir2_block_tail_t;
49
50/*
51 * Generic single-block structure, for xfs_db.
52 */
53typedef struct xfs_dir2_block {
54 xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_BLOCK_MAGIC */
55 xfs_dir2_data_union_t u[1];
56 xfs_dir2_leaf_entry_t leaf[1];
57 xfs_dir2_block_tail_t tail;
58} xfs_dir2_block_t;
59
60/*
61 * Pointer to the leaf header embedded in a data block (1-block format)
62 */
63static inline xfs_dir2_block_tail_t *
64xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block)
65{
66 return (((xfs_dir2_block_tail_t *)
67 ((char *)(block) + (mp)->m_dirblksize)) - 1);
68}
69
70/*
71 * Pointer to the leaf entries embedded in a data block (1-block format)
72 */
73static inline struct xfs_dir2_leaf_entry *
74xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp)
75{
76 return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
77}
78
79/*
80 * Function declarations.
81 */
82extern int xfs_dir2_block_addname(struct xfs_da_args *args);
83extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
84 xfs_off_t *offset, filldir_t filldir);
85extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
86extern int xfs_dir2_block_removename(struct xfs_da_args *args);
87extern int xfs_dir2_block_replace(struct xfs_da_args *args);
88extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
89 struct xfs_dabuf *lbp, struct xfs_dabuf *dbp);
90extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
91
92#endif /* __XFS_DIR2_BLOCK_H__ */
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index 921595b84f5..5bbe2a8a023 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -23,18 +23,18 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_da_btree.h" 27#include "xfs_da_btree.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir2_sf.h"
31#include "xfs_dinode.h" 29#include "xfs_dinode.h"
32#include "xfs_inode.h" 30#include "xfs_inode.h"
33#include "xfs_dir2_data.h" 31#include "xfs_dir2_format.h"
34#include "xfs_dir2_leaf.h" 32#include "xfs_dir2_priv.h"
35#include "xfs_dir2_block.h"
36#include "xfs_error.h" 33#include "xfs_error.h"
37 34
35STATIC xfs_dir2_data_free_t *
36xfs_dir2_data_freefind(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup);
37
38#ifdef DEBUG 38#ifdef DEBUG
39/* 39/*
40 * Check the consistency of the data block. 40 * Check the consistency of the data block.
@@ -50,7 +50,7 @@ xfs_dir2_data_check(
50 xfs_dir2_data_free_t *bf; /* bestfree table */ 50 xfs_dir2_data_free_t *bf; /* bestfree table */
51 xfs_dir2_block_tail_t *btp=NULL; /* block tail */ 51 xfs_dir2_block_tail_t *btp=NULL; /* block tail */
52 int count; /* count of entries found */ 52 int count; /* count of entries found */
53 xfs_dir2_data_t *d; /* data block pointer */ 53 xfs_dir2_data_hdr_t *hdr; /* data block header */
54 xfs_dir2_data_entry_t *dep; /* data entry */ 54 xfs_dir2_data_entry_t *dep; /* data entry */
55 xfs_dir2_data_free_t *dfp; /* bestfree entry */ 55 xfs_dir2_data_free_t *dfp; /* bestfree entry */
56 xfs_dir2_data_unused_t *dup; /* unused entry */ 56 xfs_dir2_data_unused_t *dup; /* unused entry */
@@ -66,17 +66,19 @@ xfs_dir2_data_check(
66 struct xfs_name name; 66 struct xfs_name name;
67 67
68 mp = dp->i_mount; 68 mp = dp->i_mount;
69 d = bp->data; 69 hdr = bp->data;
70 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || 70 bf = hdr->bestfree;
71 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); 71 p = (char *)(hdr + 1);
72 bf = d->hdr.bestfree; 72
73 p = (char *)d->u; 73 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) {
74 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { 74 btp = xfs_dir2_block_tail_p(mp, hdr);
75 btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d);
76 lep = xfs_dir2_block_leaf_p(btp); 75 lep = xfs_dir2_block_leaf_p(btp);
77 endp = (char *)lep; 76 endp = (char *)lep;
78 } else 77 } else {
79 endp = (char *)d + mp->m_dirblksize; 78 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC));
79 endp = (char *)hdr + mp->m_dirblksize;
80 }
81
80 count = lastfree = freeseen = 0; 82 count = lastfree = freeseen = 0;
81 /* 83 /*
82 * Account for zero bestfree entries. 84 * Account for zero bestfree entries.
@@ -108,8 +110,8 @@ xfs_dir2_data_check(
108 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 110 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
109 ASSERT(lastfree == 0); 111 ASSERT(lastfree == 0);
110 ASSERT(be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == 112 ASSERT(be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) ==
111 (char *)dup - (char *)d); 113 (char *)dup - (char *)hdr);
112 dfp = xfs_dir2_data_freefind(d, dup); 114 dfp = xfs_dir2_data_freefind(hdr, dup);
113 if (dfp) { 115 if (dfp) {
114 i = (int)(dfp - bf); 116 i = (int)(dfp - bf);
115 ASSERT((freeseen & (1 << i)) == 0); 117 ASSERT((freeseen & (1 << i)) == 0);
@@ -132,13 +134,13 @@ xfs_dir2_data_check(
132 ASSERT(dep->namelen != 0); 134 ASSERT(dep->namelen != 0);
133 ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0); 135 ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0);
134 ASSERT(be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) == 136 ASSERT(be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) ==
135 (char *)dep - (char *)d); 137 (char *)dep - (char *)hdr);
136 count++; 138 count++;
137 lastfree = 0; 139 lastfree = 0;
138 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { 140 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) {
139 addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 141 addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
140 (xfs_dir2_data_aoff_t) 142 (xfs_dir2_data_aoff_t)
141 ((char *)dep - (char *)d)); 143 ((char *)dep - (char *)hdr));
142 name.name = dep->name; 144 name.name = dep->name;
143 name.len = dep->namelen; 145 name.len = dep->namelen;
144 hash = mp->m_dirnameops->hashname(&name); 146 hash = mp->m_dirnameops->hashname(&name);
@@ -155,9 +157,10 @@ xfs_dir2_data_check(
155 * Need to have seen all the entries and all the bestfree slots. 157 * Need to have seen all the entries and all the bestfree slots.
156 */ 158 */
157 ASSERT(freeseen == 7); 159 ASSERT(freeseen == 7);
158 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { 160 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) {
159 for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { 161 for (i = stale = 0; i < be32_to_cpu(btp->count); i++) {
160 if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) 162 if (lep[i].address ==
163 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
161 stale++; 164 stale++;
162 if (i > 0) 165 if (i > 0)
163 ASSERT(be32_to_cpu(lep[i].hashval) >= be32_to_cpu(lep[i - 1].hashval)); 166 ASSERT(be32_to_cpu(lep[i].hashval) >= be32_to_cpu(lep[i - 1].hashval));
@@ -172,9 +175,9 @@ xfs_dir2_data_check(
172 * Given a data block and an unused entry from that block, 175 * Given a data block and an unused entry from that block,
173 * return the bestfree entry if any that corresponds to it. 176 * return the bestfree entry if any that corresponds to it.
174 */ 177 */
175xfs_dir2_data_free_t * 178STATIC xfs_dir2_data_free_t *
176xfs_dir2_data_freefind( 179xfs_dir2_data_freefind(
177 xfs_dir2_data_t *d, /* data block */ 180 xfs_dir2_data_hdr_t *hdr, /* data block */
178 xfs_dir2_data_unused_t *dup) /* data unused entry */ 181 xfs_dir2_data_unused_t *dup) /* data unused entry */
179{ 182{
180 xfs_dir2_data_free_t *dfp; /* bestfree entry */ 183 xfs_dir2_data_free_t *dfp; /* bestfree entry */
@@ -184,17 +187,17 @@ xfs_dir2_data_freefind(
184 int seenzero; /* saw a 0 bestfree entry */ 187 int seenzero; /* saw a 0 bestfree entry */
185#endif 188#endif
186 189
187 off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)d); 190 off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr);
188#if defined(DEBUG) && defined(__KERNEL__) 191#if defined(DEBUG) && defined(__KERNEL__)
189 /* 192 /*
190 * Validate some consistency in the bestfree table. 193 * Validate some consistency in the bestfree table.
191 * Check order, non-overlapping entries, and if we find the 194 * Check order, non-overlapping entries, and if we find the
192 * one we're looking for it has to be exact. 195 * one we're looking for it has to be exact.
193 */ 196 */
194 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || 197 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
195 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); 198 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC));
196 for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0; 199 for (dfp = &hdr->bestfree[0], seenzero = matched = 0;
197 dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; 200 dfp < &hdr->bestfree[XFS_DIR2_DATA_FD_COUNT];
198 dfp++) { 201 dfp++) {
199 if (!dfp->offset) { 202 if (!dfp->offset) {
200 ASSERT(!dfp->length); 203 ASSERT(!dfp->length);
@@ -210,7 +213,7 @@ xfs_dir2_data_freefind(
210 else 213 else
211 ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off); 214 ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off);
212 ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length)); 215 ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length));
213 if (dfp > &d->hdr.bestfree[0]) 216 if (dfp > &hdr->bestfree[0])
214 ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length)); 217 ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length));
215 } 218 }
216#endif 219#endif
@@ -219,13 +222,13 @@ xfs_dir2_data_freefind(
219 * it can't be there since they're sorted. 222 * it can't be there since they're sorted.
220 */ 223 */
221 if (be16_to_cpu(dup->length) < 224 if (be16_to_cpu(dup->length) <
222 be16_to_cpu(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) 225 be16_to_cpu(hdr->bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length))
223 return NULL; 226 return NULL;
224 /* 227 /*
225 * Look at the three bestfree entries for our guy. 228 * Look at the three bestfree entries for our guy.
226 */ 229 */
227 for (dfp = &d->hdr.bestfree[0]; 230 for (dfp = &hdr->bestfree[0];
228 dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; 231 dfp < &hdr->bestfree[XFS_DIR2_DATA_FD_COUNT];
229 dfp++) { 232 dfp++) {
230 if (!dfp->offset) 233 if (!dfp->offset)
231 return NULL; 234 return NULL;
@@ -243,7 +246,7 @@ xfs_dir2_data_freefind(
243 */ 246 */
244xfs_dir2_data_free_t * /* entry inserted */ 247xfs_dir2_data_free_t * /* entry inserted */
245xfs_dir2_data_freeinsert( 248xfs_dir2_data_freeinsert(
246 xfs_dir2_data_t *d, /* data block pointer */ 249 xfs_dir2_data_hdr_t *hdr, /* data block pointer */
247 xfs_dir2_data_unused_t *dup, /* unused space */ 250 xfs_dir2_data_unused_t *dup, /* unused space */
248 int *loghead) /* log the data header (out) */ 251 int *loghead) /* log the data header (out) */
249{ 252{
@@ -251,12 +254,13 @@ xfs_dir2_data_freeinsert(
251 xfs_dir2_data_free_t new; /* new bestfree entry */ 254 xfs_dir2_data_free_t new; /* new bestfree entry */
252 255
253#ifdef __KERNEL__ 256#ifdef __KERNEL__
254 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || 257 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
255 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); 258 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC));
256#endif 259#endif
257 dfp = d->hdr.bestfree; 260 dfp = hdr->bestfree;
258 new.length = dup->length; 261 new.length = dup->length;
259 new.offset = cpu_to_be16((char *)dup - (char *)d); 262 new.offset = cpu_to_be16((char *)dup - (char *)hdr);
263
260 /* 264 /*
261 * Insert at position 0, 1, or 2; or not at all. 265 * Insert at position 0, 1, or 2; or not at all.
262 */ 266 */
@@ -286,36 +290,36 @@ xfs_dir2_data_freeinsert(
286 */ 290 */
287STATIC void 291STATIC void
288xfs_dir2_data_freeremove( 292xfs_dir2_data_freeremove(
289 xfs_dir2_data_t *d, /* data block pointer */ 293 xfs_dir2_data_hdr_t *hdr, /* data block header */
290 xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ 294 xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */
291 int *loghead) /* out: log data header */ 295 int *loghead) /* out: log data header */
292{ 296{
293#ifdef __KERNEL__ 297#ifdef __KERNEL__
294 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || 298 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
295 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); 299 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC));
296#endif 300#endif
297 /* 301 /*
298 * It's the first entry, slide the next 2 up. 302 * It's the first entry, slide the next 2 up.
299 */ 303 */
300 if (dfp == &d->hdr.bestfree[0]) { 304 if (dfp == &hdr->bestfree[0]) {
301 d->hdr.bestfree[0] = d->hdr.bestfree[1]; 305 hdr->bestfree[0] = hdr->bestfree[1];
302 d->hdr.bestfree[1] = d->hdr.bestfree[2]; 306 hdr->bestfree[1] = hdr->bestfree[2];
303 } 307 }
304 /* 308 /*
305 * It's the second entry, slide the 3rd entry up. 309 * It's the second entry, slide the 3rd entry up.
306 */ 310 */
307 else if (dfp == &d->hdr.bestfree[1]) 311 else if (dfp == &hdr->bestfree[1])
308 d->hdr.bestfree[1] = d->hdr.bestfree[2]; 312 hdr->bestfree[1] = hdr->bestfree[2];
309 /* 313 /*
310 * Must be the last entry. 314 * Must be the last entry.
311 */ 315 */
312 else 316 else
313 ASSERT(dfp == &d->hdr.bestfree[2]); 317 ASSERT(dfp == &hdr->bestfree[2]);
314 /* 318 /*
315 * Clear the 3rd entry, must be zero now. 319 * Clear the 3rd entry, must be zero now.
316 */ 320 */
317 d->hdr.bestfree[2].length = 0; 321 hdr->bestfree[2].length = 0;
318 d->hdr.bestfree[2].offset = 0; 322 hdr->bestfree[2].offset = 0;
319 *loghead = 1; 323 *loghead = 1;
320} 324}
321 325
@@ -325,7 +329,7 @@ xfs_dir2_data_freeremove(
325void 329void
326xfs_dir2_data_freescan( 330xfs_dir2_data_freescan(
327 xfs_mount_t *mp, /* filesystem mount point */ 331 xfs_mount_t *mp, /* filesystem mount point */
328 xfs_dir2_data_t *d, /* data block pointer */ 332 xfs_dir2_data_hdr_t *hdr, /* data block header */
329 int *loghead) /* out: log data header */ 333 int *loghead) /* out: log data header */
330{ 334{
331 xfs_dir2_block_tail_t *btp; /* block tail */ 335 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -335,23 +339,23 @@ xfs_dir2_data_freescan(
335 char *p; /* current entry pointer */ 339 char *p; /* current entry pointer */
336 340
337#ifdef __KERNEL__ 341#ifdef __KERNEL__
338 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || 342 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
339 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); 343 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC));
340#endif 344#endif
341 /* 345 /*
342 * Start by clearing the table. 346 * Start by clearing the table.
343 */ 347 */
344 memset(d->hdr.bestfree, 0, sizeof(d->hdr.bestfree)); 348 memset(hdr->bestfree, 0, sizeof(hdr->bestfree));
345 *loghead = 1; 349 *loghead = 1;
346 /* 350 /*
347 * Set up pointers. 351 * Set up pointers.
348 */ 352 */
349 p = (char *)d->u; 353 p = (char *)(hdr + 1);
350 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { 354 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) {
351 btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); 355 btp = xfs_dir2_block_tail_p(mp, hdr);
352 endp = (char *)xfs_dir2_block_leaf_p(btp); 356 endp = (char *)xfs_dir2_block_leaf_p(btp);
353 } else 357 } else
354 endp = (char *)d + mp->m_dirblksize; 358 endp = (char *)hdr + mp->m_dirblksize;
355 /* 359 /*
356 * Loop over the block's entries. 360 * Loop over the block's entries.
357 */ 361 */
@@ -361,9 +365,9 @@ xfs_dir2_data_freescan(
361 * If it's a free entry, insert it. 365 * If it's a free entry, insert it.
362 */ 366 */
363 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { 367 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
364 ASSERT((char *)dup - (char *)d == 368 ASSERT((char *)dup - (char *)hdr ==
365 be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); 369 be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
366 xfs_dir2_data_freeinsert(d, dup, loghead); 370 xfs_dir2_data_freeinsert(hdr, dup, loghead);
367 p += be16_to_cpu(dup->length); 371 p += be16_to_cpu(dup->length);
368 } 372 }
369 /* 373 /*
@@ -371,7 +375,7 @@ xfs_dir2_data_freescan(
371 */ 375 */
372 else { 376 else {
373 dep = (xfs_dir2_data_entry_t *)p; 377 dep = (xfs_dir2_data_entry_t *)p;
374 ASSERT((char *)dep - (char *)d == 378 ASSERT((char *)dep - (char *)hdr ==
375 be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep))); 379 be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)));
376 p += xfs_dir2_data_entsize(dep->namelen); 380 p += xfs_dir2_data_entsize(dep->namelen);
377 } 381 }
@@ -389,7 +393,7 @@ xfs_dir2_data_init(
389 xfs_dabuf_t **bpp) /* output block buffer */ 393 xfs_dabuf_t **bpp) /* output block buffer */
390{ 394{
391 xfs_dabuf_t *bp; /* block buffer */ 395 xfs_dabuf_t *bp; /* block buffer */
392 xfs_dir2_data_t *d; /* pointer to block */ 396 xfs_dir2_data_hdr_t *hdr; /* data block header */
393 xfs_inode_t *dp; /* incore directory inode */ 397 xfs_inode_t *dp; /* incore directory inode */
394 xfs_dir2_data_unused_t *dup; /* unused entry pointer */ 398 xfs_dir2_data_unused_t *dup; /* unused entry pointer */
395 int error; /* error return value */ 399 int error; /* error return value */
@@ -410,26 +414,28 @@ xfs_dir2_data_init(
410 return error; 414 return error;
411 } 415 }
412 ASSERT(bp != NULL); 416 ASSERT(bp != NULL);
417
413 /* 418 /*
414 * Initialize the header. 419 * Initialize the header.
415 */ 420 */
416 d = bp->data; 421 hdr = bp->data;
417 d->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 422 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
418 d->hdr.bestfree[0].offset = cpu_to_be16(sizeof(d->hdr)); 423 hdr->bestfree[0].offset = cpu_to_be16(sizeof(*hdr));
419 for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { 424 for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
420 d->hdr.bestfree[i].length = 0; 425 hdr->bestfree[i].length = 0;
421 d->hdr.bestfree[i].offset = 0; 426 hdr->bestfree[i].offset = 0;
422 } 427 }
428
423 /* 429 /*
424 * Set up an unused entry for the block's body. 430 * Set up an unused entry for the block's body.
425 */ 431 */
426 dup = &d->u[0].unused; 432 dup = (xfs_dir2_data_unused_t *)(hdr + 1);
427 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 433 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
428 434
429 t=mp->m_dirblksize - (uint)sizeof(d->hdr); 435 t = mp->m_dirblksize - (uint)sizeof(*hdr);
430 d->hdr.bestfree[0].length = cpu_to_be16(t); 436 hdr->bestfree[0].length = cpu_to_be16(t);
431 dup->length = cpu_to_be16(t); 437 dup->length = cpu_to_be16(t);
432 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)d); 438 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
433 /* 439 /*
434 * Log it and return it. 440 * Log it and return it.
435 */ 441 */
@@ -448,14 +454,14 @@ xfs_dir2_data_log_entry(
448 xfs_dabuf_t *bp, /* block buffer */ 454 xfs_dabuf_t *bp, /* block buffer */
449 xfs_dir2_data_entry_t *dep) /* data entry pointer */ 455 xfs_dir2_data_entry_t *dep) /* data entry pointer */
450{ 456{
451 xfs_dir2_data_t *d; /* data block pointer */ 457 xfs_dir2_data_hdr_t *hdr = bp->data;
458
459 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
460 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC));
452 461
453 d = bp->data; 462 xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr),
454 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
455 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
456 xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d),
457 (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - 463 (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) -
458 (char *)d - 1)); 464 (char *)hdr - 1));
459} 465}
460 466
461/* 467/*
@@ -466,13 +472,12 @@ xfs_dir2_data_log_header(
466 xfs_trans_t *tp, /* transaction pointer */ 472 xfs_trans_t *tp, /* transaction pointer */
467 xfs_dabuf_t *bp) /* block buffer */ 473 xfs_dabuf_t *bp) /* block buffer */
468{ 474{
469 xfs_dir2_data_t *d; /* data block pointer */ 475 xfs_dir2_data_hdr_t *hdr = bp->data;
470 476
471 d = bp->data; 477 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
472 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || 478 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC));
473 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); 479
474 xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d), 480 xfs_da_log_buf(tp, bp, 0, sizeof(*hdr) - 1);
475 (uint)(sizeof(d->hdr) - 1));
476} 481}
477 482
478/* 483/*
@@ -484,23 +489,23 @@ xfs_dir2_data_log_unused(
484 xfs_dabuf_t *bp, /* block buffer */ 489 xfs_dabuf_t *bp, /* block buffer */
485 xfs_dir2_data_unused_t *dup) /* data unused pointer */ 490 xfs_dir2_data_unused_t *dup) /* data unused pointer */
486{ 491{
487 xfs_dir2_data_t *d; /* data block pointer */ 492 xfs_dir2_data_hdr_t *hdr = bp->data;
493
494 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
495 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC));
488 496
489 d = bp->data;
490 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
491 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
492 /* 497 /*
493 * Log the first part of the unused entry. 498 * Log the first part of the unused entry.
494 */ 499 */
495 xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)d), 500 xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)hdr),
496 (uint)((char *)&dup->length + sizeof(dup->length) - 501 (uint)((char *)&dup->length + sizeof(dup->length) -
497 1 - (char *)d)); 502 1 - (char *)hdr));
498 /* 503 /*
499 * Log the end (tag) of the unused entry. 504 * Log the end (tag) of the unused entry.
500 */ 505 */
501 xfs_da_log_buf(tp, bp, 506 xfs_da_log_buf(tp, bp,
502 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d), 507 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr),
503 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d + 508 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr +
504 sizeof(xfs_dir2_data_off_t) - 1)); 509 sizeof(xfs_dir2_data_off_t) - 1));
505} 510}
506 511
@@ -517,7 +522,7 @@ xfs_dir2_data_make_free(
517 int *needlogp, /* out: log header */ 522 int *needlogp, /* out: log header */
518 int *needscanp) /* out: regen bestfree */ 523 int *needscanp) /* out: regen bestfree */
519{ 524{
520 xfs_dir2_data_t *d; /* data block pointer */ 525 xfs_dir2_data_hdr_t *hdr; /* data block pointer */
521 xfs_dir2_data_free_t *dfp; /* bestfree pointer */ 526 xfs_dir2_data_free_t *dfp; /* bestfree pointer */
522 char *endptr; /* end of data area */ 527 char *endptr; /* end of data area */
523 xfs_mount_t *mp; /* filesystem mount point */ 528 xfs_mount_t *mp; /* filesystem mount point */
@@ -527,28 +532,29 @@ xfs_dir2_data_make_free(
527 xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ 532 xfs_dir2_data_unused_t *prevdup; /* unused entry before us */
528 533
529 mp = tp->t_mountp; 534 mp = tp->t_mountp;
530 d = bp->data; 535 hdr = bp->data;
536
531 /* 537 /*
532 * Figure out where the end of the data area is. 538 * Figure out where the end of the data area is.
533 */ 539 */
534 if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC) 540 if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC))
535 endptr = (char *)d + mp->m_dirblksize; 541 endptr = (char *)hdr + mp->m_dirblksize;
536 else { 542 else {
537 xfs_dir2_block_tail_t *btp; /* block tail */ 543 xfs_dir2_block_tail_t *btp; /* block tail */
538 544
539 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); 545 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC));
540 btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); 546 btp = xfs_dir2_block_tail_p(mp, hdr);
541 endptr = (char *)xfs_dir2_block_leaf_p(btp); 547 endptr = (char *)xfs_dir2_block_leaf_p(btp);
542 } 548 }
543 /* 549 /*
544 * If this isn't the start of the block, then back up to 550 * If this isn't the start of the block, then back up to
545 * the previous entry and see if it's free. 551 * the previous entry and see if it's free.
546 */ 552 */
547 if (offset > sizeof(d->hdr)) { 553 if (offset > sizeof(*hdr)) {
548 __be16 *tagp; /* tag just before us */ 554 __be16 *tagp; /* tag just before us */
549 555
550 tagp = (__be16 *)((char *)d + offset) - 1; 556 tagp = (__be16 *)((char *)hdr + offset) - 1;
551 prevdup = (xfs_dir2_data_unused_t *)((char *)d + be16_to_cpu(*tagp)); 557 prevdup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
552 if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG) 558 if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
553 prevdup = NULL; 559 prevdup = NULL;
554 } else 560 } else
@@ -557,9 +563,9 @@ xfs_dir2_data_make_free(
557 * If this isn't the end of the block, see if the entry after 563 * If this isn't the end of the block, see if the entry after
558 * us is free. 564 * us is free.
559 */ 565 */
560 if ((char *)d + offset + len < endptr) { 566 if ((char *)hdr + offset + len < endptr) {
561 postdup = 567 postdup =
562 (xfs_dir2_data_unused_t *)((char *)d + offset + len); 568 (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
563 if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG) 569 if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
564 postdup = NULL; 570 postdup = NULL;
565 } else 571 } else
@@ -576,21 +582,21 @@ xfs_dir2_data_make_free(
576 /* 582 /*
577 * See if prevdup and/or postdup are in bestfree table. 583 * See if prevdup and/or postdup are in bestfree table.
578 */ 584 */
579 dfp = xfs_dir2_data_freefind(d, prevdup); 585 dfp = xfs_dir2_data_freefind(hdr, prevdup);
580 dfp2 = xfs_dir2_data_freefind(d, postdup); 586 dfp2 = xfs_dir2_data_freefind(hdr, postdup);
581 /* 587 /*
582 * We need a rescan unless there are exactly 2 free entries 588 * We need a rescan unless there are exactly 2 free entries
583 * namely our two. Then we know what's happening, otherwise 589 * namely our two. Then we know what's happening, otherwise
584 * since the third bestfree is there, there might be more 590 * since the third bestfree is there, there might be more
585 * entries. 591 * entries.
586 */ 592 */
587 needscan = (d->hdr.bestfree[2].length != 0); 593 needscan = (hdr->bestfree[2].length != 0);
588 /* 594 /*
589 * Fix up the new big freespace. 595 * Fix up the new big freespace.
590 */ 596 */
591 be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length)); 597 be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
592 *xfs_dir2_data_unused_tag_p(prevdup) = 598 *xfs_dir2_data_unused_tag_p(prevdup) =
593 cpu_to_be16((char *)prevdup - (char *)d); 599 cpu_to_be16((char *)prevdup - (char *)hdr);
594 xfs_dir2_data_log_unused(tp, bp, prevdup); 600 xfs_dir2_data_log_unused(tp, bp, prevdup);
595 if (!needscan) { 601 if (!needscan) {
596 /* 602 /*
@@ -600,18 +606,18 @@ xfs_dir2_data_make_free(
600 * Remove entry 1 first then entry 0. 606 * Remove entry 1 first then entry 0.
601 */ 607 */
602 ASSERT(dfp && dfp2); 608 ASSERT(dfp && dfp2);
603 if (dfp == &d->hdr.bestfree[1]) { 609 if (dfp == &hdr->bestfree[1]) {
604 dfp = &d->hdr.bestfree[0]; 610 dfp = &hdr->bestfree[0];
605 ASSERT(dfp2 == dfp); 611 ASSERT(dfp2 == dfp);
606 dfp2 = &d->hdr.bestfree[1]; 612 dfp2 = &hdr->bestfree[1];
607 } 613 }
608 xfs_dir2_data_freeremove(d, dfp2, needlogp); 614 xfs_dir2_data_freeremove(hdr, dfp2, needlogp);
609 xfs_dir2_data_freeremove(d, dfp, needlogp); 615 xfs_dir2_data_freeremove(hdr, dfp, needlogp);
610 /* 616 /*
611 * Now insert the new entry. 617 * Now insert the new entry.
612 */ 618 */
613 dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp); 619 dfp = xfs_dir2_data_freeinsert(hdr, prevdup, needlogp);
614 ASSERT(dfp == &d->hdr.bestfree[0]); 620 ASSERT(dfp == &hdr->bestfree[0]);
615 ASSERT(dfp->length == prevdup->length); 621 ASSERT(dfp->length == prevdup->length);
616 ASSERT(!dfp[1].length); 622 ASSERT(!dfp[1].length);
617 ASSERT(!dfp[2].length); 623 ASSERT(!dfp[2].length);
@@ -621,10 +627,10 @@ xfs_dir2_data_make_free(
621 * The entry before us is free, merge with it. 627 * The entry before us is free, merge with it.
622 */ 628 */
623 else if (prevdup) { 629 else if (prevdup) {
624 dfp = xfs_dir2_data_freefind(d, prevdup); 630 dfp = xfs_dir2_data_freefind(hdr, prevdup);
625 be16_add_cpu(&prevdup->length, len); 631 be16_add_cpu(&prevdup->length, len);
626 *xfs_dir2_data_unused_tag_p(prevdup) = 632 *xfs_dir2_data_unused_tag_p(prevdup) =
627 cpu_to_be16((char *)prevdup - (char *)d); 633 cpu_to_be16((char *)prevdup - (char *)hdr);
628 xfs_dir2_data_log_unused(tp, bp, prevdup); 634 xfs_dir2_data_log_unused(tp, bp, prevdup);
629 /* 635 /*
630 * If the previous entry was in the table, the new entry 636 * If the previous entry was in the table, the new entry
@@ -632,27 +638,27 @@ xfs_dir2_data_make_free(
632 * the old one and add the new one. 638 * the old one and add the new one.
633 */ 639 */
634 if (dfp) { 640 if (dfp) {
635 xfs_dir2_data_freeremove(d, dfp, needlogp); 641 xfs_dir2_data_freeremove(hdr, dfp, needlogp);
636 (void)xfs_dir2_data_freeinsert(d, prevdup, needlogp); 642 xfs_dir2_data_freeinsert(hdr, prevdup, needlogp);
637 } 643 }
638 /* 644 /*
639 * Otherwise we need a scan if the new entry is big enough. 645 * Otherwise we need a scan if the new entry is big enough.
640 */ 646 */
641 else { 647 else {
642 needscan = be16_to_cpu(prevdup->length) > 648 needscan = be16_to_cpu(prevdup->length) >
643 be16_to_cpu(d->hdr.bestfree[2].length); 649 be16_to_cpu(hdr->bestfree[2].length);
644 } 650 }
645 } 651 }
646 /* 652 /*
647 * The following entry is free, merge with it. 653 * The following entry is free, merge with it.
648 */ 654 */
649 else if (postdup) { 655 else if (postdup) {
650 dfp = xfs_dir2_data_freefind(d, postdup); 656 dfp = xfs_dir2_data_freefind(hdr, postdup);
651 newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); 657 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
652 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 658 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
653 newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); 659 newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
654 *xfs_dir2_data_unused_tag_p(newdup) = 660 *xfs_dir2_data_unused_tag_p(newdup) =
655 cpu_to_be16((char *)newdup - (char *)d); 661 cpu_to_be16((char *)newdup - (char *)hdr);
656 xfs_dir2_data_log_unused(tp, bp, newdup); 662 xfs_dir2_data_log_unused(tp, bp, newdup);
657 /* 663 /*
658 * If the following entry was in the table, the new entry 664 * If the following entry was in the table, the new entry
@@ -660,28 +666,28 @@ xfs_dir2_data_make_free(
660 * the old one and add the new one. 666 * the old one and add the new one.
661 */ 667 */
662 if (dfp) { 668 if (dfp) {
663 xfs_dir2_data_freeremove(d, dfp, needlogp); 669 xfs_dir2_data_freeremove(hdr, dfp, needlogp);
664 (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); 670 xfs_dir2_data_freeinsert(hdr, newdup, needlogp);
665 } 671 }
666 /* 672 /*
667 * Otherwise we need a scan if the new entry is big enough. 673 * Otherwise we need a scan if the new entry is big enough.
668 */ 674 */
669 else { 675 else {
670 needscan = be16_to_cpu(newdup->length) > 676 needscan = be16_to_cpu(newdup->length) >
671 be16_to_cpu(d->hdr.bestfree[2].length); 677 be16_to_cpu(hdr->bestfree[2].length);
672 } 678 }
673 } 679 }
674 /* 680 /*
675 * Neither neighbor is free. Make a new entry. 681 * Neither neighbor is free. Make a new entry.
676 */ 682 */
677 else { 683 else {
678 newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); 684 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
679 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 685 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
680 newdup->length = cpu_to_be16(len); 686 newdup->length = cpu_to_be16(len);
681 *xfs_dir2_data_unused_tag_p(newdup) = 687 *xfs_dir2_data_unused_tag_p(newdup) =
682 cpu_to_be16((char *)newdup - (char *)d); 688 cpu_to_be16((char *)newdup - (char *)hdr);
683 xfs_dir2_data_log_unused(tp, bp, newdup); 689 xfs_dir2_data_log_unused(tp, bp, newdup);
684 (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); 690 xfs_dir2_data_freeinsert(hdr, newdup, needlogp);
685 } 691 }
686 *needscanp = needscan; 692 *needscanp = needscan;
687} 693}
@@ -699,7 +705,7 @@ xfs_dir2_data_use_free(
699 int *needlogp, /* out: need to log header */ 705 int *needlogp, /* out: need to log header */
700 int *needscanp) /* out: need regen bestfree */ 706 int *needscanp) /* out: need regen bestfree */
701{ 707{
702 xfs_dir2_data_t *d; /* data block */ 708 xfs_dir2_data_hdr_t *hdr; /* data block header */
703 xfs_dir2_data_free_t *dfp; /* bestfree pointer */ 709 xfs_dir2_data_free_t *dfp; /* bestfree pointer */
704 int matchback; /* matches end of freespace */ 710 int matchback; /* matches end of freespace */
705 int matchfront; /* matches start of freespace */ 711 int matchfront; /* matches start of freespace */
@@ -708,24 +714,24 @@ xfs_dir2_data_use_free(
708 xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ 714 xfs_dir2_data_unused_t *newdup2; /* another new unused entry */
709 int oldlen; /* old unused entry's length */ 715 int oldlen; /* old unused entry's length */
710 716
711 d = bp->data; 717 hdr = bp->data;
712 ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || 718 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
713 be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); 719 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC));
714 ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); 720 ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG);
715 ASSERT(offset >= (char *)dup - (char *)d); 721 ASSERT(offset >= (char *)dup - (char *)hdr);
716 ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d); 722 ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)hdr);
717 ASSERT((char *)dup - (char *)d == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); 723 ASSERT((char *)dup - (char *)hdr == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
718 /* 724 /*
719 * Look up the entry in the bestfree table. 725 * Look up the entry in the bestfree table.
720 */ 726 */
721 dfp = xfs_dir2_data_freefind(d, dup); 727 dfp = xfs_dir2_data_freefind(hdr, dup);
722 oldlen = be16_to_cpu(dup->length); 728 oldlen = be16_to_cpu(dup->length);
723 ASSERT(dfp || oldlen <= be16_to_cpu(d->hdr.bestfree[2].length)); 729 ASSERT(dfp || oldlen <= be16_to_cpu(hdr->bestfree[2].length));
724 /* 730 /*
725 * Check for alignment with front and back of the entry. 731 * Check for alignment with front and back of the entry.
726 */ 732 */
727 matchfront = (char *)dup - (char *)d == offset; 733 matchfront = (char *)dup - (char *)hdr == offset;
728 matchback = (char *)dup + oldlen - (char *)d == offset + len; 734 matchback = (char *)dup + oldlen - (char *)hdr == offset + len;
729 ASSERT(*needscanp == 0); 735 ASSERT(*needscanp == 0);
730 needscan = 0; 736 needscan = 0;
731 /* 737 /*
@@ -734,9 +740,9 @@ xfs_dir2_data_use_free(
734 */ 740 */
735 if (matchfront && matchback) { 741 if (matchfront && matchback) {
736 if (dfp) { 742 if (dfp) {
737 needscan = (d->hdr.bestfree[2].offset != 0); 743 needscan = (hdr->bestfree[2].offset != 0);
738 if (!needscan) 744 if (!needscan)
739 xfs_dir2_data_freeremove(d, dfp, needlogp); 745 xfs_dir2_data_freeremove(hdr, dfp, needlogp);
740 } 746 }
741 } 747 }
742 /* 748 /*
@@ -744,27 +750,27 @@ xfs_dir2_data_use_free(
744 * Make a new entry with the remaining freespace. 750 * Make a new entry with the remaining freespace.
745 */ 751 */
746 else if (matchfront) { 752 else if (matchfront) {
747 newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); 753 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
748 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 754 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
749 newdup->length = cpu_to_be16(oldlen - len); 755 newdup->length = cpu_to_be16(oldlen - len);
750 *xfs_dir2_data_unused_tag_p(newdup) = 756 *xfs_dir2_data_unused_tag_p(newdup) =
751 cpu_to_be16((char *)newdup - (char *)d); 757 cpu_to_be16((char *)newdup - (char *)hdr);
752 xfs_dir2_data_log_unused(tp, bp, newdup); 758 xfs_dir2_data_log_unused(tp, bp, newdup);
753 /* 759 /*
754 * If it was in the table, remove it and add the new one. 760 * If it was in the table, remove it and add the new one.
755 */ 761 */
756 if (dfp) { 762 if (dfp) {
757 xfs_dir2_data_freeremove(d, dfp, needlogp); 763 xfs_dir2_data_freeremove(hdr, dfp, needlogp);
758 dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); 764 dfp = xfs_dir2_data_freeinsert(hdr, newdup, needlogp);
759 ASSERT(dfp != NULL); 765 ASSERT(dfp != NULL);
760 ASSERT(dfp->length == newdup->length); 766 ASSERT(dfp->length == newdup->length);
761 ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); 767 ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr);
762 /* 768 /*
763 * If we got inserted at the last slot, 769 * If we got inserted at the last slot,
764 * that means we don't know if there was a better 770 * that means we don't know if there was a better
765 * choice for the last slot, or not. Rescan. 771 * choice for the last slot, or not. Rescan.
766 */ 772 */
767 needscan = dfp == &d->hdr.bestfree[2]; 773 needscan = dfp == &hdr->bestfree[2];
768 } 774 }
769 } 775 }
770 /* 776 /*
@@ -773,25 +779,25 @@ xfs_dir2_data_use_free(
773 */ 779 */
774 else if (matchback) { 780 else if (matchback) {
775 newdup = dup; 781 newdup = dup;
776 newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); 782 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
777 *xfs_dir2_data_unused_tag_p(newdup) = 783 *xfs_dir2_data_unused_tag_p(newdup) =
778 cpu_to_be16((char *)newdup - (char *)d); 784 cpu_to_be16((char *)newdup - (char *)hdr);
779 xfs_dir2_data_log_unused(tp, bp, newdup); 785 xfs_dir2_data_log_unused(tp, bp, newdup);
780 /* 786 /*
781 * If it was in the table, remove it and add the new one. 787 * If it was in the table, remove it and add the new one.
782 */ 788 */
783 if (dfp) { 789 if (dfp) {
784 xfs_dir2_data_freeremove(d, dfp, needlogp); 790 xfs_dir2_data_freeremove(hdr, dfp, needlogp);
785 dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); 791 dfp = xfs_dir2_data_freeinsert(hdr, newdup, needlogp);
786 ASSERT(dfp != NULL); 792 ASSERT(dfp != NULL);
787 ASSERT(dfp->length == newdup->length); 793 ASSERT(dfp->length == newdup->length);
788 ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); 794 ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr);
789 /* 795 /*
790 * If we got inserted at the last slot, 796 * If we got inserted at the last slot,
791 * that means we don't know if there was a better 797 * that means we don't know if there was a better
792 * choice for the last slot, or not. Rescan. 798 * choice for the last slot, or not. Rescan.
793 */ 799 */
794 needscan = dfp == &d->hdr.bestfree[2]; 800 needscan = dfp == &hdr->bestfree[2];
795 } 801 }
796 } 802 }
797 /* 803 /*
@@ -800,15 +806,15 @@ xfs_dir2_data_use_free(
800 */ 806 */
801 else { 807 else {
802 newdup = dup; 808 newdup = dup;
803 newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); 809 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
804 *xfs_dir2_data_unused_tag_p(newdup) = 810 *xfs_dir2_data_unused_tag_p(newdup) =
805 cpu_to_be16((char *)newdup - (char *)d); 811 cpu_to_be16((char *)newdup - (char *)hdr);
806 xfs_dir2_data_log_unused(tp, bp, newdup); 812 xfs_dir2_data_log_unused(tp, bp, newdup);
807 newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len); 813 newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
808 newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); 814 newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
809 newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); 815 newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length));
810 *xfs_dir2_data_unused_tag_p(newdup2) = 816 *xfs_dir2_data_unused_tag_p(newdup2) =
811 cpu_to_be16((char *)newdup2 - (char *)d); 817 cpu_to_be16((char *)newdup2 - (char *)hdr);
812 xfs_dir2_data_log_unused(tp, bp, newdup2); 818 xfs_dir2_data_log_unused(tp, bp, newdup2);
813 /* 819 /*
814 * If the old entry was in the table, we need to scan 820 * If the old entry was in the table, we need to scan
@@ -819,13 +825,12 @@ xfs_dir2_data_use_free(
819 * the 2 new will work. 825 * the 2 new will work.
820 */ 826 */
821 if (dfp) { 827 if (dfp) {
822 needscan = (d->hdr.bestfree[2].length != 0); 828 needscan = (hdr->bestfree[2].length != 0);
823 if (!needscan) { 829 if (!needscan) {
824 xfs_dir2_data_freeremove(d, dfp, needlogp); 830 xfs_dir2_data_freeremove(hdr, dfp, needlogp);
825 (void)xfs_dir2_data_freeinsert(d, newdup, 831 xfs_dir2_data_freeinsert(hdr, newdup, needlogp);
826 needlogp); 832 xfs_dir2_data_freeinsert(hdr, newdup2,
827 (void)xfs_dir2_data_freeinsert(d, newdup2, 833 needlogp);
828 needlogp);
829 } 834 }
830 } 835 }
831 } 836 }
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
deleted file mode 100644
index efbc290c7fe..00000000000
--- a/fs/xfs/xfs_dir2_data.h
+++ /dev/null
@@ -1,184 +0,0 @@
1/*
2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_DATA_H__
19#define __XFS_DIR2_DATA_H__
20
21/*
22 * Directory format 2, data block structures.
23 */
24
25struct xfs_dabuf;
26struct xfs_da_args;
27struct xfs_inode;
28struct xfs_trans;
29
30/*
31 * Constants.
32 */
33#define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: for multiblock dirs */
34#define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */
35#define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
36#define XFS_DIR2_DATA_FREE_TAG 0xffff
37#define XFS_DIR2_DATA_FD_COUNT 3
38
39/*
40 * Directory address space divided into sections,
41 * spaces separated by 32GB.
42 */
43#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
44#define XFS_DIR2_DATA_SPACE 0
45#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
46#define XFS_DIR2_DATA_FIRSTDB(mp) \
47 xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
48
49/*
50 * Offsets of . and .. in data space (always block 0)
51 */
52#define XFS_DIR2_DATA_DOT_OFFSET \
53 ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t))
54#define XFS_DIR2_DATA_DOTDOT_OFFSET \
55 (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1))
56#define XFS_DIR2_DATA_FIRST_OFFSET \
57 (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2))
58
59/*
60 * Structures.
61 */
62
63/*
64 * Describe a free area in the data block.
65 * The freespace will be formatted as a xfs_dir2_data_unused_t.
66 */
67typedef struct xfs_dir2_data_free {
68 __be16 offset; /* start of freespace */
69 __be16 length; /* length of freespace */
70} xfs_dir2_data_free_t;
71
72/*
73 * Header for the data blocks.
74 * Always at the beginning of a directory-sized block.
75 * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
76 */
77typedef struct xfs_dir2_data_hdr {
78 __be32 magic; /* XFS_DIR2_DATA_MAGIC */
79 /* or XFS_DIR2_BLOCK_MAGIC */
80 xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
81} xfs_dir2_data_hdr_t;
82
83/*
84 * Active entry in a data block. Aligned to 8 bytes.
85 * Tag appears as the last 2 bytes.
86 */
87typedef struct xfs_dir2_data_entry {
88 __be64 inumber; /* inode number */
89 __u8 namelen; /* name length */
90 __u8 name[1]; /* name bytes, no null */
91 /* variable offset */
92 __be16 tag; /* starting offset of us */
93} xfs_dir2_data_entry_t;
94
95/*
96 * Unused entry in a data block. Aligned to 8 bytes.
97 * Tag appears as the last 2 bytes.
98 */
99typedef struct xfs_dir2_data_unused {
100 __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */
101 __be16 length; /* total free length */
102 /* variable offset */
103 __be16 tag; /* starting offset of us */
104} xfs_dir2_data_unused_t;
105
106typedef union {
107 xfs_dir2_data_entry_t entry;
108 xfs_dir2_data_unused_t unused;
109} xfs_dir2_data_union_t;
110
111/*
112 * Generic data block structure, for xfs_db.
113 */
114typedef struct xfs_dir2_data {
115 xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_DATA_MAGIC */
116 xfs_dir2_data_union_t u[1];
117} xfs_dir2_data_t;
118
119/*
120 * Macros.
121 */
122
123/*
124 * Size of a data entry.
125 */
126static inline int xfs_dir2_data_entsize(int n)
127{
128 return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \
129 (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
130}
131
132/*
133 * Pointer to an entry's tag word.
134 */
135static inline __be16 *
136xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep)
137{
138 return (__be16 *)((char *)dep +
139 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
140}
141
142/*
143 * Pointer to a freespace's tag word.
144 */
145static inline __be16 *
146xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup)
147{
148 return (__be16 *)((char *)dup +
149 be16_to_cpu(dup->length) - sizeof(__be16));
150}
151
152/*
153 * Function declarations.
154 */
155#ifdef DEBUG
156extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp);
157#else
158#define xfs_dir2_data_check(dp,bp)
159#endif
160extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d,
161 xfs_dir2_data_unused_t *dup);
162extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d,
163 xfs_dir2_data_unused_t *dup, int *loghead);
164extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
165 int *loghead);
166extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
167 struct xfs_dabuf **bpp);
168extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
169 xfs_dir2_data_entry_t *dep);
170extern void xfs_dir2_data_log_header(struct xfs_trans *tp,
171 struct xfs_dabuf *bp);
172extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp,
173 xfs_dir2_data_unused_t *dup);
174extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
175 xfs_dir2_data_aoff_t offset,
176 xfs_dir2_data_aoff_t len, int *needlogp,
177 int *needscanp);
178extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
179 xfs_dir2_data_unused_t *dup,
180 xfs_dir2_data_aoff_t offset,
181 xfs_dir2_data_aoff_t len, int *needlogp,
182 int *needscanp);
183
184#endif /* __XFS_DIR2_DATA_H__ */
diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h
new file mode 100644
index 00000000000..07270981f48
--- /dev/null
+++ b/fs/xfs/xfs_dir2_format.h
@@ -0,0 +1,597 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_FORMAT_H__
19#define __XFS_DIR2_FORMAT_H__
20
21/*
22 * Directory version 2.
23 *
24 * There are 4 possible formats:
25 * - shortform - embedded into the inode
26 * - single block - data with embedded leaf at the end
27 * - multiple data blocks, single leaf+freeindex block
28 * - data blocks, node and leaf blocks (btree), freeindex blocks
29 *
30 * Note: many node blocks structures and constants are shared with the attr
31 * code and defined in xfs_da_btree.h.
32 */
33
34#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: single block dirs */
35#define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: multiblock dirs */
36#define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F: free index blocks */
37
38/*
39 * Byte offset in data block and shortform entry.
40 */
41typedef __uint16_t xfs_dir2_data_off_t;
42#define NULLDATAOFF 0xffffU
43typedef uint xfs_dir2_data_aoff_t; /* argument form */
44
45/*
46 * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
47 * Only need 16 bits, this is the byte offset into the single block form.
48 */
49typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
50
51/*
52 * Offset in data space of a data entry.
53 */
54typedef __uint32_t xfs_dir2_dataptr_t;
55#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff)
56#define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0)
57
58/*
59 * Byte offset in a directory.
60 */
61typedef xfs_off_t xfs_dir2_off_t;
62
63/*
64 * Directory block number (logical dirblk in file)
65 */
66typedef __uint32_t xfs_dir2_db_t;
67
68/*
69 * Inode number stored as 8 8-bit values.
70 */
71typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
72
73/*
74 * Inode number stored as 4 8-bit values.
75 * Works a lot of the time, when all the inode numbers in a directory
76 * fit in 32 bits.
77 */
78typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
79
80typedef union {
81 xfs_dir2_ino8_t i8;
82 xfs_dir2_ino4_t i4;
83} xfs_dir2_inou_t;
84#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
85
86/*
87 * Directory layout when stored internal to an inode.
88 *
89 * Small directories are packed as tightly as possible so as to fit into the
90 * literal area of the inode. These "shortform" directories consist of a
91 * single xfs_dir2_sf_hdr header followed by zero or more xfs_dir2_sf_entry
92 * structures. Due the different inode number storage size and the variable
93 * length name field in the xfs_dir2_sf_entry all these structure are
94 * variable length, and the accessors in this file should be used to iterate
95 * over them.
96 */
97typedef struct xfs_dir2_sf_hdr {
98 __uint8_t count; /* count of entries */
99 __uint8_t i8count; /* count of 8-byte inode #s */
100 xfs_dir2_inou_t parent; /* parent dir inode number */
101} __arch_pack xfs_dir2_sf_hdr_t;
102
103typedef struct xfs_dir2_sf_entry {
104 __u8 namelen; /* actual name length */
105 xfs_dir2_sf_off_t offset; /* saved offset */
106 __u8 name[]; /* name, variable size */
107 /*
108 * A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a
109 * variable offset after the name.
110 */
111} __arch_pack xfs_dir2_sf_entry_t;
112
113static inline int xfs_dir2_sf_hdr_size(int i8count)
114{
115 return sizeof(struct xfs_dir2_sf_hdr) -
116 (i8count == 0) *
117 (sizeof(xfs_dir2_ino8_t) - sizeof(xfs_dir2_ino4_t));
118}
119
120static inline xfs_dir2_data_aoff_t
121xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
122{
123 return get_unaligned_be16(&sfep->offset.i);
124}
125
126static inline void
127xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
128{
129 put_unaligned_be16(off, &sfep->offset.i);
130}
131
132static inline int
133xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
134{
135 return sizeof(struct xfs_dir2_sf_entry) + /* namelen + offset */
136 len + /* name */
137 (hdr->i8count ? /* ino */
138 sizeof(xfs_dir2_ino8_t) :
139 sizeof(xfs_dir2_ino4_t));
140}
141
142static inline struct xfs_dir2_sf_entry *
143xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
144{
145 return (struct xfs_dir2_sf_entry *)
146 ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count));
147}
148
149static inline struct xfs_dir2_sf_entry *
150xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
151 struct xfs_dir2_sf_entry *sfep)
152{
153 return (struct xfs_dir2_sf_entry *)
154 ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
155}
156
157
158/*
159 * Data block structures.
160 *
161 * A pure data block looks like the following drawing on disk:
162 *
163 * +-------------------------------------------------+
164 * | xfs_dir2_data_hdr_t |
165 * +-------------------------------------------------+
166 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
167 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
168 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
169 * | ... |
170 * +-------------------------------------------------+
171 * | unused space |
172 * +-------------------------------------------------+
173 *
174 * As all the entries are variable size structures the accessors below should
175 * be used to iterate over them.
176 *
177 * In addition to the pure data blocks for the data and node formats,
178 * most structures are also used for the combined data/freespace "block"
179 * format below.
180 */
181
182#define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */
183#define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
184#define XFS_DIR2_DATA_FREE_TAG 0xffff
185#define XFS_DIR2_DATA_FD_COUNT 3
186
187/*
188 * Directory address space divided into sections,
189 * spaces separated by 32GB.
190 */
191#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
192#define XFS_DIR2_DATA_SPACE 0
193#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
194#define XFS_DIR2_DATA_FIRSTDB(mp) \
195 xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
196
197/*
198 * Offsets of . and .. in data space (always block 0)
199 */
200#define XFS_DIR2_DATA_DOT_OFFSET \
201 ((xfs_dir2_data_aoff_t)sizeof(struct xfs_dir2_data_hdr))
202#define XFS_DIR2_DATA_DOTDOT_OFFSET \
203 (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1))
204#define XFS_DIR2_DATA_FIRST_OFFSET \
205 (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2))
206
207/*
208 * Describe a free area in the data block.
209 *
210 * The freespace will be formatted as a xfs_dir2_data_unused_t.
211 */
212typedef struct xfs_dir2_data_free {
213 __be16 offset; /* start of freespace */
214 __be16 length; /* length of freespace */
215} xfs_dir2_data_free_t;
216
217/*
218 * Header for the data blocks.
219 *
220 * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
221 */
222typedef struct xfs_dir2_data_hdr {
223 __be32 magic; /* XFS_DIR2_DATA_MAGIC or */
224 /* XFS_DIR2_BLOCK_MAGIC */
225 xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
226} xfs_dir2_data_hdr_t;
227
228/*
229 * Active entry in a data block.
230 *
231 * Aligned to 8 bytes. After the variable length name field there is a
232 * 2 byte tag field, which can be accessed using xfs_dir2_data_entry_tag_p.
233 */
234typedef struct xfs_dir2_data_entry {
235 __be64 inumber; /* inode number */
236 __u8 namelen; /* name length */
237 __u8 name[]; /* name bytes, no null */
238 /* __be16 tag; */ /* starting offset of us */
239} xfs_dir2_data_entry_t;
240
241/*
242 * Unused entry in a data block.
243 *
244 * Aligned to 8 bytes. Tag appears as the last 2 bytes and must be accessed
245 * using xfs_dir2_data_unused_tag_p.
246 */
247typedef struct xfs_dir2_data_unused {
248 __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */
249 __be16 length; /* total free length */
250 /* variable offset */
251 __be16 tag; /* starting offset of us */
252} xfs_dir2_data_unused_t;
253
254/*
255 * Size of a data entry.
256 */
257static inline int xfs_dir2_data_entsize(int n)
258{
259 return (int)roundup(offsetof(struct xfs_dir2_data_entry, name[0]) + n +
260 (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
261}
262
263/*
264 * Pointer to an entry's tag word.
265 */
266static inline __be16 *
267xfs_dir2_data_entry_tag_p(struct xfs_dir2_data_entry *dep)
268{
269 return (__be16 *)((char *)dep +
270 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
271}
272
273/*
274 * Pointer to a freespace's tag word.
275 */
276static inline __be16 *
277xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
278{
279 return (__be16 *)((char *)dup +
280 be16_to_cpu(dup->length) - sizeof(__be16));
281}
282
283/*
284 * Leaf block structures.
285 *
286 * A pure leaf block looks like the following drawing on disk:
287 *
288 * +---------------------------+
289 * | xfs_dir2_leaf_hdr_t |
290 * +---------------------------+
291 * | xfs_dir2_leaf_entry_t |
292 * | xfs_dir2_leaf_entry_t |
293 * | xfs_dir2_leaf_entry_t |
294 * | xfs_dir2_leaf_entry_t |
295 * | ... |
296 * +---------------------------+
297 * | xfs_dir2_data_off_t |
298 * | xfs_dir2_data_off_t |
299 * | xfs_dir2_data_off_t |
300 * | ... |
301 * +---------------------------+
302 * | xfs_dir2_leaf_tail_t |
303 * +---------------------------+
304 *
305 * The xfs_dir2_data_off_t members (bests) and tail are at the end of the block
306 * for single-leaf (magic = XFS_DIR2_LEAF1_MAGIC) blocks only, but not present
307 * for directories with separate leaf nodes and free space blocks
308 * (magic = XFS_DIR2_LEAFN_MAGIC).
309 *
310 * As all the entries are variable size structures the accessors below should
311 * be used to iterate over them.
312 */
313
314/*
315 * Offset of the leaf/node space. First block in this space
316 * is the btree root.
317 */
318#define XFS_DIR2_LEAF_SPACE 1
319#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
320#define XFS_DIR2_LEAF_FIRSTDB(mp) \
321 xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
322
323/*
324 * Leaf block header.
325 */
326typedef struct xfs_dir2_leaf_hdr {
327 xfs_da_blkinfo_t info; /* header for da routines */
328 __be16 count; /* count of entries */
329 __be16 stale; /* count of stale entries */
330} xfs_dir2_leaf_hdr_t;
331
332/*
333 * Leaf block entry.
334 */
335typedef struct xfs_dir2_leaf_entry {
336 __be32 hashval; /* hash value of name */
337 __be32 address; /* address of data entry */
338} xfs_dir2_leaf_entry_t;
339
340/*
341 * Leaf block tail.
342 */
343typedef struct xfs_dir2_leaf_tail {
344 __be32 bestcount;
345} xfs_dir2_leaf_tail_t;
346
347/*
348 * Leaf block.
349 */
350typedef struct xfs_dir2_leaf {
351 xfs_dir2_leaf_hdr_t hdr; /* leaf header */
352 xfs_dir2_leaf_entry_t ents[]; /* entries */
353} xfs_dir2_leaf_t;
354
355/*
356 * DB blocks here are logical directory block numbers, not filesystem blocks.
357 */
358
359static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
360{
361 return (mp->m_dirblksize - (uint)sizeof(struct xfs_dir2_leaf_hdr)) /
362 (uint)sizeof(struct xfs_dir2_leaf_entry);
363}
364
365/*
366 * Get address of the bestcount field in the single-leaf block.
367 */
368static inline struct xfs_dir2_leaf_tail *
369xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
370{
371 return (struct xfs_dir2_leaf_tail *)
372 ((char *)lp + mp->m_dirblksize -
373 sizeof(struct xfs_dir2_leaf_tail));
374}
375
376/*
377 * Get address of the bests array in the single-leaf block.
378 */
379static inline __be16 *
380xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
381{
382 return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
383}
384
385/*
386 * Convert dataptr to byte in file space
387 */
388static inline xfs_dir2_off_t
389xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
390{
391 return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
392}
393
394/*
395 * Convert byte in file space to dataptr. It had better be aligned.
396 */
397static inline xfs_dir2_dataptr_t
398xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
399{
400 return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
401}
402
403/*
404 * Convert byte in space to (DB) block
405 */
406static inline xfs_dir2_db_t
407xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
408{
409 return (xfs_dir2_db_t)
410 (by >> (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog));
411}
412
413/*
414 * Convert dataptr to a block number
415 */
416static inline xfs_dir2_db_t
417xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
418{
419 return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp));
420}
421
422/*
423 * Convert byte in space to offset in a block
424 */
425static inline xfs_dir2_data_aoff_t
426xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
427{
428 return (xfs_dir2_data_aoff_t)(by &
429 ((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) - 1));
430}
431
432/*
433 * Convert dataptr to a byte offset in a block
434 */
435static inline xfs_dir2_data_aoff_t
436xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
437{
438 return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp));
439}
440
441/*
442 * Convert block and offset to byte in space
443 */
444static inline xfs_dir2_off_t
445xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
446 xfs_dir2_data_aoff_t o)
447{
448 return ((xfs_dir2_off_t)db <<
449 (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) + o;
450}
451
452/*
453 * Convert block (DB) to block (dablk)
454 */
455static inline xfs_dablk_t
456xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
457{
458 return (xfs_dablk_t)(db << mp->m_sb.sb_dirblklog);
459}
460
461/*
462 * Convert byte in space to (DA) block
463 */
464static inline xfs_dablk_t
465xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
466{
467 return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by));
468}
469
470/*
471 * Convert block and offset to dataptr
472 */
473static inline xfs_dir2_dataptr_t
474xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
475 xfs_dir2_data_aoff_t o)
476{
477 return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o));
478}
479
480/*
481 * Convert block (dablk) to block (DB)
482 */
483static inline xfs_dir2_db_t
484xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
485{
486 return (xfs_dir2_db_t)(da >> mp->m_sb.sb_dirblklog);
487}
488
489/*
490 * Convert block (dablk) to byte offset in space
491 */
492static inline xfs_dir2_off_t
493xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
494{
495 return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0);
496}
497
498/*
499 * Free space block defintions for the node format.
500 */
501
502/*
503 * Offset of the freespace index.
504 */
505#define XFS_DIR2_FREE_SPACE 2
506#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
507#define XFS_DIR2_FREE_FIRSTDB(mp) \
508 xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
509
510typedef struct xfs_dir2_free_hdr {
511 __be32 magic; /* XFS_DIR2_FREE_MAGIC */
512 __be32 firstdb; /* db of first entry */
513 __be32 nvalid; /* count of valid entries */
514 __be32 nused; /* count of used entries */
515} xfs_dir2_free_hdr_t;
516
517typedef struct xfs_dir2_free {
518 xfs_dir2_free_hdr_t hdr; /* block header */
519 __be16 bests[]; /* best free counts */
520 /* unused entries are -1 */
521} xfs_dir2_free_t;
522
523static inline int xfs_dir2_free_max_bests(struct xfs_mount *mp)
524{
525 return (mp->m_dirblksize - sizeof(struct xfs_dir2_free_hdr)) /
526 sizeof(xfs_dir2_data_off_t);
527}
528
529/*
530 * Convert data space db to the corresponding free db.
531 */
532static inline xfs_dir2_db_t
533xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
534{
535 return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir2_free_max_bests(mp);
536}
537
538/*
539 * Convert data space db to the corresponding index in a free db.
540 */
541static inline int
542xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
543{
544 return db % xfs_dir2_free_max_bests(mp);
545}
546
547/*
548 * Single block format.
549 *
550 * The single block format looks like the following drawing on disk:
551 *
552 * +-------------------------------------------------+
553 * | xfs_dir2_data_hdr_t |
554 * +-------------------------------------------------+
555 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
556 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
557 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t :
558 * | ... |
559 * +-------------------------------------------------+
560 * | unused space |
561 * +-------------------------------------------------+
562 * | ... |
563 * | xfs_dir2_leaf_entry_t |
564 * | xfs_dir2_leaf_entry_t |
565 * +-------------------------------------------------+
566 * | xfs_dir2_block_tail_t |
567 * +-------------------------------------------------+
568 *
569 * As all the entries are variable size structures the accessors below should
570 * be used to iterate over them.
571 */
572
573typedef struct xfs_dir2_block_tail {
574 __be32 count; /* count of leaf entries */
575 __be32 stale; /* count of stale lf entries */
576} xfs_dir2_block_tail_t;
577
578/*
579 * Pointer to the leaf header embedded in a data block (1-block format)
580 */
581static inline struct xfs_dir2_block_tail *
582xfs_dir2_block_tail_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr)
583{
584 return ((struct xfs_dir2_block_tail *)
585 ((char *)hdr + mp->m_dirblksize)) - 1;
586}
587
588/*
589 * Pointer to the leaf entries embedded in a data block (1-block format)
590 */
591static inline struct xfs_dir2_leaf_entry *
592xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
593{
594 return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
595}
596
597#endif /* __XFS_DIR2_FORMAT_H__ */
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index ae891223be9..ca2386d82cd 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -24,18 +24,14 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir2.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir2_sf.h"
32#include "xfs_dinode.h" 30#include "xfs_dinode.h"
33#include "xfs_inode.h" 31#include "xfs_inode.h"
34#include "xfs_bmap.h" 32#include "xfs_bmap.h"
35#include "xfs_dir2_data.h" 33#include "xfs_dir2_format.h"
36#include "xfs_dir2_leaf.h" 34#include "xfs_dir2_priv.h"
37#include "xfs_dir2_block.h"
38#include "xfs_dir2_node.h"
39#include "xfs_error.h" 35#include "xfs_error.h"
40#include "xfs_trace.h" 36#include "xfs_trace.h"
41 37
@@ -64,7 +60,7 @@ xfs_dir2_block_to_leaf(
64{ 60{
65 __be16 *bestsp; /* leaf's bestsp entries */ 61 __be16 *bestsp; /* leaf's bestsp entries */
66 xfs_dablk_t blkno; /* leaf block's bno */ 62 xfs_dablk_t blkno; /* leaf block's bno */
67 xfs_dir2_block_t *block; /* block structure */ 63 xfs_dir2_data_hdr_t *hdr; /* block header */
68 xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */ 64 xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */
69 xfs_dir2_block_tail_t *btp; /* block's tail */ 65 xfs_dir2_block_tail_t *btp; /* block's tail */
70 xfs_inode_t *dp; /* incore directory inode */ 66 xfs_inode_t *dp; /* incore directory inode */
@@ -101,9 +97,9 @@ xfs_dir2_block_to_leaf(
101 } 97 }
102 ASSERT(lbp != NULL); 98 ASSERT(lbp != NULL);
103 leaf = lbp->data; 99 leaf = lbp->data;
104 block = dbp->data; 100 hdr = dbp->data;
105 xfs_dir2_data_check(dp, dbp); 101 xfs_dir2_data_check(dp, dbp);
106 btp = xfs_dir2_block_tail_p(mp, block); 102 btp = xfs_dir2_block_tail_p(mp, hdr);
107 blp = xfs_dir2_block_leaf_p(btp); 103 blp = xfs_dir2_block_leaf_p(btp);
108 /* 104 /*
109 * Set the counts in the leaf header. 105 * Set the counts in the leaf header.
@@ -123,23 +119,23 @@ xfs_dir2_block_to_leaf(
123 * tail be free. 119 * tail be free.
124 */ 120 */
125 xfs_dir2_data_make_free(tp, dbp, 121 xfs_dir2_data_make_free(tp, dbp,
126 (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), 122 (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
127 (xfs_dir2_data_aoff_t)((char *)block + mp->m_dirblksize - 123 (xfs_dir2_data_aoff_t)((char *)hdr + mp->m_dirblksize -
128 (char *)blp), 124 (char *)blp),
129 &needlog, &needscan); 125 &needlog, &needscan);
130 /* 126 /*
131 * Fix up the block header, make it a data block. 127 * Fix up the block header, make it a data block.
132 */ 128 */
133 block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 129 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
134 if (needscan) 130 if (needscan)
135 xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); 131 xfs_dir2_data_freescan(mp, hdr, &needlog);
136 /* 132 /*
137 * Set up leaf tail and bests table. 133 * Set up leaf tail and bests table.
138 */ 134 */
139 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 135 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
140 ltp->bestcount = cpu_to_be32(1); 136 ltp->bestcount = cpu_to_be32(1);
141 bestsp = xfs_dir2_leaf_bests_p(ltp); 137 bestsp = xfs_dir2_leaf_bests_p(ltp);
142 bestsp[0] = block->hdr.bestfree[0].length; 138 bestsp[0] = hdr->bestfree[0].length;
143 /* 139 /*
144 * Log the data header and leaf bests table. 140 * Log the data header and leaf bests table.
145 */ 141 */
@@ -152,6 +148,131 @@ xfs_dir2_block_to_leaf(
152 return 0; 148 return 0;
153} 149}
154 150
151STATIC void
152xfs_dir2_leaf_find_stale(
153 struct xfs_dir2_leaf *leaf,
154 int index,
155 int *lowstale,
156 int *highstale)
157{
158 /*
159 * Find the first stale entry before our index, if any.
160 */
161 for (*lowstale = index - 1; *lowstale >= 0; --*lowstale) {
162 if (leaf->ents[*lowstale].address ==
163 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
164 break;
165 }
166
167 /*
168 * Find the first stale entry at or after our index, if any.
169 * Stop if the result would require moving more entries than using
170 * lowstale.
171 */
172 for (*highstale = index;
173 *highstale < be16_to_cpu(leaf->hdr.count);
174 ++*highstale) {
175 if (leaf->ents[*highstale].address ==
176 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
177 break;
178 if (*lowstale >= 0 && index - *lowstale <= *highstale - index)
179 break;
180 }
181}
182
183struct xfs_dir2_leaf_entry *
184xfs_dir2_leaf_find_entry(
185 xfs_dir2_leaf_t *leaf, /* leaf structure */
186 int index, /* leaf table position */
187 int compact, /* need to compact leaves */
188 int lowstale, /* index of prev stale leaf */
189 int highstale, /* index of next stale leaf */
190 int *lfloglow, /* low leaf logging index */
191 int *lfloghigh) /* high leaf logging index */
192{
193 if (!leaf->hdr.stale) {
194 xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */
195
196 /*
197 * Now we need to make room to insert the leaf entry.
198 *
199 * If there are no stale entries, just insert a hole at index.
200 */
201 lep = &leaf->ents[index];
202 if (index < be16_to_cpu(leaf->hdr.count))
203 memmove(lep + 1, lep,
204 (be16_to_cpu(leaf->hdr.count) - index) *
205 sizeof(*lep));
206
207 /*
208 * Record low and high logging indices for the leaf.
209 */
210 *lfloglow = index;
211 *lfloghigh = be16_to_cpu(leaf->hdr.count);
212 be16_add_cpu(&leaf->hdr.count, 1);
213 return lep;
214 }
215
216 /*
217 * There are stale entries.
218 *
219 * We will use one of them for the new entry. It's probably not at
220 * the right location, so we'll have to shift some up or down first.
221 *
222 * If we didn't compact before, we need to find the nearest stale
223 * entries before and after our insertion point.
224 */
225 if (compact == 0)
226 xfs_dir2_leaf_find_stale(leaf, index, &lowstale, &highstale);
227
228 /*
229 * If the low one is better, use it.
230 */
231 if (lowstale >= 0 &&
232 (highstale == be16_to_cpu(leaf->hdr.count) ||
233 index - lowstale - 1 < highstale - index)) {
234 ASSERT(index - lowstale - 1 >= 0);
235 ASSERT(leaf->ents[lowstale].address ==
236 cpu_to_be32(XFS_DIR2_NULL_DATAPTR));
237
238 /*
239 * Copy entries up to cover the stale entry and make room
240 * for the new entry.
241 */
242 if (index - lowstale - 1 > 0) {
243 memmove(&leaf->ents[lowstale],
244 &leaf->ents[lowstale + 1],
245 (index - lowstale - 1) *
246 sizeof(xfs_dir2_leaf_entry_t));
247 }
248 *lfloglow = MIN(lowstale, *lfloglow);
249 *lfloghigh = MAX(index - 1, *lfloghigh);
250 be16_add_cpu(&leaf->hdr.stale, -1);
251 return &leaf->ents[index - 1];
252 }
253
254 /*
255 * The high one is better, so use that one.
256 */
257 ASSERT(highstale - index >= 0);
258 ASSERT(leaf->ents[highstale].address ==
259 cpu_to_be32(XFS_DIR2_NULL_DATAPTR));
260
261 /*
262 * Copy entries down to cover the stale entry and make room for the
263 * new entry.
264 */
265 if (highstale - index > 0) {
266 memmove(&leaf->ents[index + 1],
267 &leaf->ents[index],
268 (highstale - index) * sizeof(xfs_dir2_leaf_entry_t));
269 }
270 *lfloglow = MIN(index, *lfloglow);
271 *lfloghigh = MAX(highstale, *lfloghigh);
272 be16_add_cpu(&leaf->hdr.stale, -1);
273 return &leaf->ents[index];
274}
275
155/* 276/*
156 * Add an entry to a leaf form directory. 277 * Add an entry to a leaf form directory.
157 */ 278 */
@@ -161,7 +282,7 @@ xfs_dir2_leaf_addname(
161{ 282{
162 __be16 *bestsp; /* freespace table in leaf */ 283 __be16 *bestsp; /* freespace table in leaf */
163 int compact; /* need to compact leaves */ 284 int compact; /* need to compact leaves */
164 xfs_dir2_data_t *data; /* data block structure */ 285 xfs_dir2_data_hdr_t *hdr; /* data block header */
165 xfs_dabuf_t *dbp; /* data block buffer */ 286 xfs_dabuf_t *dbp; /* data block buffer */
166 xfs_dir2_data_entry_t *dep; /* data block entry */ 287 xfs_dir2_data_entry_t *dep; /* data block entry */
167 xfs_inode_t *dp; /* incore directory inode */ 288 xfs_inode_t *dp; /* incore directory inode */
@@ -225,7 +346,7 @@ xfs_dir2_leaf_addname(
225 continue; 346 continue;
226 i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 347 i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
227 ASSERT(i < be32_to_cpu(ltp->bestcount)); 348 ASSERT(i < be32_to_cpu(ltp->bestcount));
228 ASSERT(be16_to_cpu(bestsp[i]) != NULLDATAOFF); 349 ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF));
229 if (be16_to_cpu(bestsp[i]) >= length) { 350 if (be16_to_cpu(bestsp[i]) >= length) {
230 use_block = i; 351 use_block = i;
231 break; 352 break;
@@ -239,7 +360,8 @@ xfs_dir2_leaf_addname(
239 /* 360 /*
240 * Remember a block we see that's missing. 361 * Remember a block we see that's missing.
241 */ 362 */
242 if (be16_to_cpu(bestsp[i]) == NULLDATAOFF && use_block == -1) 363 if (bestsp[i] == cpu_to_be16(NULLDATAOFF) &&
364 use_block == -1)
243 use_block = i; 365 use_block = i;
244 else if (be16_to_cpu(bestsp[i]) >= length) { 366 else if (be16_to_cpu(bestsp[i]) >= length) {
245 use_block = i; 367 use_block = i;
@@ -250,14 +372,17 @@ xfs_dir2_leaf_addname(
250 /* 372 /*
251 * How many bytes do we need in the leaf block? 373 * How many bytes do we need in the leaf block?
252 */ 374 */
253 needbytes = 375 needbytes = 0;
254 (leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) + 376 if (!leaf->hdr.stale)
255 (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0])); 377 needbytes += sizeof(xfs_dir2_leaf_entry_t);
378 if (use_block == -1)
379 needbytes += sizeof(xfs_dir2_data_off_t);
380
256 /* 381 /*
257 * Now kill use_block if it refers to a missing block, so we 382 * Now kill use_block if it refers to a missing block, so we
258 * can use it as an indication of allocation needed. 383 * can use it as an indication of allocation needed.
259 */ 384 */
260 if (use_block != -1 && be16_to_cpu(bestsp[use_block]) == NULLDATAOFF) 385 if (use_block != -1 && bestsp[use_block] == cpu_to_be16(NULLDATAOFF))
261 use_block = -1; 386 use_block = -1;
262 /* 387 /*
263 * If we don't have enough free bytes but we can make enough 388 * If we don't have enough free bytes but we can make enough
@@ -369,8 +494,8 @@ xfs_dir2_leaf_addname(
369 */ 494 */
370 else 495 else
371 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 496 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
372 data = dbp->data; 497 hdr = dbp->data;
373 bestsp[use_block] = data->hdr.bestfree[0].length; 498 bestsp[use_block] = hdr->bestfree[0].length;
374 grown = 1; 499 grown = 1;
375 } 500 }
376 /* 501 /*
@@ -384,7 +509,7 @@ xfs_dir2_leaf_addname(
384 xfs_da_brelse(tp, lbp); 509 xfs_da_brelse(tp, lbp);
385 return error; 510 return error;
386 } 511 }
387 data = dbp->data; 512 hdr = dbp->data;
388 grown = 0; 513 grown = 0;
389 } 514 }
390 xfs_dir2_data_check(dp, dbp); 515 xfs_dir2_data_check(dp, dbp);
@@ -392,14 +517,14 @@ xfs_dir2_leaf_addname(
392 * Point to the biggest freespace in our data block. 517 * Point to the biggest freespace in our data block.
393 */ 518 */
394 dup = (xfs_dir2_data_unused_t *) 519 dup = (xfs_dir2_data_unused_t *)
395 ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); 520 ((char *)hdr + be16_to_cpu(hdr->bestfree[0].offset));
396 ASSERT(be16_to_cpu(dup->length) >= length); 521 ASSERT(be16_to_cpu(dup->length) >= length);
397 needscan = needlog = 0; 522 needscan = needlog = 0;
398 /* 523 /*
399 * Mark the initial part of our freespace in use for the new entry. 524 * Mark the initial part of our freespace in use for the new entry.
400 */ 525 */
401 xfs_dir2_data_use_free(tp, dbp, dup, 526 xfs_dir2_data_use_free(tp, dbp, dup,
402 (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, 527 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
403 &needlog, &needscan); 528 &needlog, &needscan);
404 /* 529 /*
405 * Initialize our new entry (at last). 530 * Initialize our new entry (at last).
@@ -409,12 +534,12 @@ xfs_dir2_leaf_addname(
409 dep->namelen = args->namelen; 534 dep->namelen = args->namelen;
410 memcpy(dep->name, args->name, dep->namelen); 535 memcpy(dep->name, args->name, dep->namelen);
411 tagp = xfs_dir2_data_entry_tag_p(dep); 536 tagp = xfs_dir2_data_entry_tag_p(dep);
412 *tagp = cpu_to_be16((char *)dep - (char *)data); 537 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
413 /* 538 /*
414 * Need to scan fix up the bestfree table. 539 * Need to scan fix up the bestfree table.
415 */ 540 */
416 if (needscan) 541 if (needscan)
417 xfs_dir2_data_freescan(mp, data, &needlog); 542 xfs_dir2_data_freescan(mp, hdr, &needlog);
418 /* 543 /*
419 * Need to log the data block's header. 544 * Need to log the data block's header.
420 */ 545 */
@@ -425,107 +550,15 @@ xfs_dir2_leaf_addname(
425 * If the bests table needs to be changed, do it. 550 * If the bests table needs to be changed, do it.
426 * Log the change unless we've already done that. 551 * Log the change unless we've already done that.
427 */ 552 */
428 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(data->hdr.bestfree[0].length)) { 553 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(hdr->bestfree[0].length)) {
429 bestsp[use_block] = data->hdr.bestfree[0].length; 554 bestsp[use_block] = hdr->bestfree[0].length;
430 if (!grown) 555 if (!grown)
431 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 556 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
432 } 557 }
433 /* 558
434 * Now we need to make room to insert the leaf entry. 559 lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale,
435 * If there are no stale entries, we just insert a hole at index. 560 highstale, &lfloglow, &lfloghigh);
436 */ 561
437 if (!leaf->hdr.stale) {
438 /*
439 * lep is still good as the index leaf entry.
440 */
441 if (index < be16_to_cpu(leaf->hdr.count))
442 memmove(lep + 1, lep,
443 (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
444 /*
445 * Record low and high logging indices for the leaf.
446 */
447 lfloglow = index;
448 lfloghigh = be16_to_cpu(leaf->hdr.count);
449 be16_add_cpu(&leaf->hdr.count, 1);
450 }
451 /*
452 * There are stale entries.
453 * We will use one of them for the new entry.
454 * It's probably not at the right location, so we'll have to
455 * shift some up or down first.
456 */
457 else {
458 /*
459 * If we didn't compact before, we need to find the nearest
460 * stale entries before and after our insertion point.
461 */
462 if (compact == 0) {
463 /*
464 * Find the first stale entry before the insertion
465 * point, if any.
466 */
467 for (lowstale = index - 1;
468 lowstale >= 0 &&
469 be32_to_cpu(leaf->ents[lowstale].address) !=
470 XFS_DIR2_NULL_DATAPTR;
471 lowstale--)
472 continue;
473 /*
474 * Find the next stale entry at or after the insertion
475 * point, if any. Stop if we go so far that the
476 * lowstale entry would be better.
477 */
478 for (highstale = index;
479 highstale < be16_to_cpu(leaf->hdr.count) &&
480 be32_to_cpu(leaf->ents[highstale].address) !=
481 XFS_DIR2_NULL_DATAPTR &&
482 (lowstale < 0 ||
483 index - lowstale - 1 >= highstale - index);
484 highstale++)
485 continue;
486 }
487 /*
488 * If the low one is better, use it.
489 */
490 if (lowstale >= 0 &&
491 (highstale == be16_to_cpu(leaf->hdr.count) ||
492 index - lowstale - 1 < highstale - index)) {
493 ASSERT(index - lowstale - 1 >= 0);
494 ASSERT(be32_to_cpu(leaf->ents[lowstale].address) ==
495 XFS_DIR2_NULL_DATAPTR);
496 /*
497 * Copy entries up to cover the stale entry
498 * and make room for the new entry.
499 */
500 if (index - lowstale - 1 > 0)
501 memmove(&leaf->ents[lowstale],
502 &leaf->ents[lowstale + 1],
503 (index - lowstale - 1) * sizeof(*lep));
504 lep = &leaf->ents[index - 1];
505 lfloglow = MIN(lowstale, lfloglow);
506 lfloghigh = MAX(index - 1, lfloghigh);
507 }
508 /*
509 * The high one is better, so use that one.
510 */
511 else {
512 ASSERT(highstale - index >= 0);
513 ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
514 XFS_DIR2_NULL_DATAPTR);
515 /*
516 * Copy entries down to cover the stale entry
517 * and make room for the new entry.
518 */
519 if (highstale - index > 0)
520 memmove(&leaf->ents[index + 1],
521 &leaf->ents[index],
522 (highstale - index) * sizeof(*lep));
523 lep = &leaf->ents[index];
524 lfloglow = MIN(index, lfloglow);
525 lfloghigh = MAX(highstale, lfloghigh);
526 }
527 be16_add_cpu(&leaf->hdr.stale, -1);
528 }
529 /* 562 /*
530 * Fill in the new leaf entry. 563 * Fill in the new leaf entry.
531 */ 564 */
@@ -562,7 +595,7 @@ xfs_dir2_leaf_check(
562 595
563 leaf = bp->data; 596 leaf = bp->data;
564 mp = dp->i_mount; 597 mp = dp->i_mount;
565 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); 598 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
566 /* 599 /*
567 * This value is not restrictive enough. 600 * This value is not restrictive enough.
568 * Should factor in the size of the bests table as well. 601 * Should factor in the size of the bests table as well.
@@ -582,7 +615,7 @@ xfs_dir2_leaf_check(
582 if (i + 1 < be16_to_cpu(leaf->hdr.count)) 615 if (i + 1 < be16_to_cpu(leaf->hdr.count))
583 ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= 616 ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
584 be32_to_cpu(leaf->ents[i + 1].hashval)); 617 be32_to_cpu(leaf->ents[i + 1].hashval));
585 if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) 618 if (leaf->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
586 stale++; 619 stale++;
587 } 620 }
588 ASSERT(be16_to_cpu(leaf->hdr.stale) == stale); 621 ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
@@ -611,7 +644,8 @@ xfs_dir2_leaf_compact(
611 * Compress out the stale entries in place. 644 * Compress out the stale entries in place.
612 */ 645 */
613 for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) { 646 for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) {
614 if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) 647 if (leaf->ents[from].address ==
648 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
615 continue; 649 continue;
616 /* 650 /*
617 * Only actually copy the entries that are different. 651 * Only actually copy the entries that are different.
@@ -663,24 +697,9 @@ xfs_dir2_leaf_compact_x1(
663 leaf = bp->data; 697 leaf = bp->data;
664 ASSERT(be16_to_cpu(leaf->hdr.stale) > 1); 698 ASSERT(be16_to_cpu(leaf->hdr.stale) > 1);
665 index = *indexp; 699 index = *indexp;
666 /* 700
667 * Find the first stale entry before our index, if any. 701 xfs_dir2_leaf_find_stale(leaf, index, &lowstale, &highstale);
668 */ 702
669 for (lowstale = index - 1;
670 lowstale >= 0 &&
671 be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR;
672 lowstale--)
673 continue;
674 /*
675 * Find the first stale entry at or after our index, if any.
676 * Stop if the answer would be worse than lowstale.
677 */
678 for (highstale = index;
679 highstale < be16_to_cpu(leaf->hdr.count) &&
680 be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR &&
681 (lowstale < 0 || index - lowstale > highstale - index);
682 highstale++)
683 continue;
684 /* 703 /*
685 * Pick the better of lowstale and highstale. 704 * Pick the better of lowstale and highstale.
686 */ 705 */
@@ -701,7 +720,8 @@ xfs_dir2_leaf_compact_x1(
701 if (index == from) 720 if (index == from)
702 newindex = to; 721 newindex = to;
703 if (from != keepstale && 722 if (from != keepstale &&
704 be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) { 723 leaf->ents[from].address ==
724 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) {
705 if (from == to) 725 if (from == to)
706 *lowlogp = to; 726 *lowlogp = to;
707 continue; 727 continue;
@@ -760,7 +780,7 @@ xfs_dir2_leaf_getdents(
760 int byteoff; /* offset in current block */ 780 int byteoff; /* offset in current block */
761 xfs_dir2_db_t curdb; /* db for current block */ 781 xfs_dir2_db_t curdb; /* db for current block */
762 xfs_dir2_off_t curoff; /* current overall offset */ 782 xfs_dir2_off_t curoff; /* current overall offset */
763 xfs_dir2_data_t *data; /* data block structure */ 783 xfs_dir2_data_hdr_t *hdr; /* data block header */
764 xfs_dir2_data_entry_t *dep; /* data entry */ 784 xfs_dir2_data_entry_t *dep; /* data entry */
765 xfs_dir2_data_unused_t *dup; /* unused entry */ 785 xfs_dir2_data_unused_t *dup; /* unused entry */
766 int error = 0; /* error return value */ 786 int error = 0; /* error return value */
@@ -1018,23 +1038,23 @@ xfs_dir2_leaf_getdents(
1018 else if (curoff > newoff) 1038 else if (curoff > newoff)
1019 ASSERT(xfs_dir2_byte_to_db(mp, curoff) == 1039 ASSERT(xfs_dir2_byte_to_db(mp, curoff) ==
1020 curdb); 1040 curdb);
1021 data = bp->data; 1041 hdr = bp->data;
1022 xfs_dir2_data_check(dp, bp); 1042 xfs_dir2_data_check(dp, bp);
1023 /* 1043 /*
1024 * Find our position in the block. 1044 * Find our position in the block.
1025 */ 1045 */
1026 ptr = (char *)&data->u; 1046 ptr = (char *)(hdr + 1);
1027 byteoff = xfs_dir2_byte_to_off(mp, curoff); 1047 byteoff = xfs_dir2_byte_to_off(mp, curoff);
1028 /* 1048 /*
1029 * Skip past the header. 1049 * Skip past the header.
1030 */ 1050 */
1031 if (byteoff == 0) 1051 if (byteoff == 0)
1032 curoff += (uint)sizeof(data->hdr); 1052 curoff += (uint)sizeof(*hdr);
1033 /* 1053 /*
1034 * Skip past entries until we reach our offset. 1054 * Skip past entries until we reach our offset.
1035 */ 1055 */
1036 else { 1056 else {
1037 while ((char *)ptr - (char *)data < byteoff) { 1057 while ((char *)ptr - (char *)hdr < byteoff) {
1038 dup = (xfs_dir2_data_unused_t *)ptr; 1058 dup = (xfs_dir2_data_unused_t *)ptr;
1039 1059
1040 if (be16_to_cpu(dup->freetag) 1060 if (be16_to_cpu(dup->freetag)
@@ -1055,8 +1075,8 @@ xfs_dir2_leaf_getdents(
1055 curoff = 1075 curoff =
1056 xfs_dir2_db_off_to_byte(mp, 1076 xfs_dir2_db_off_to_byte(mp,
1057 xfs_dir2_byte_to_db(mp, curoff), 1077 xfs_dir2_byte_to_db(mp, curoff),
1058 (char *)ptr - (char *)data); 1078 (char *)ptr - (char *)hdr);
1059 if (ptr >= (char *)data + mp->m_dirblksize) { 1079 if (ptr >= (char *)hdr + mp->m_dirblksize) {
1060 continue; 1080 continue;
1061 } 1081 }
1062 } 1082 }
@@ -1179,7 +1199,7 @@ xfs_dir2_leaf_log_bests(
1179 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 1199 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
1180 1200
1181 leaf = bp->data; 1201 leaf = bp->data;
1182 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); 1202 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
1183 ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); 1203 ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf);
1184 firstb = xfs_dir2_leaf_bests_p(ltp) + first; 1204 firstb = xfs_dir2_leaf_bests_p(ltp) + first;
1185 lastb = xfs_dir2_leaf_bests_p(ltp) + last; 1205 lastb = xfs_dir2_leaf_bests_p(ltp) + last;
@@ -1202,8 +1222,8 @@ xfs_dir2_leaf_log_ents(
1202 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1222 xfs_dir2_leaf_t *leaf; /* leaf structure */
1203 1223
1204 leaf = bp->data; 1224 leaf = bp->data;
1205 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || 1225 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1206 be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 1226 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1207 firstlep = &leaf->ents[first]; 1227 firstlep = &leaf->ents[first];
1208 lastlep = &leaf->ents[last]; 1228 lastlep = &leaf->ents[last];
1209 xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), 1229 xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf),
@@ -1221,8 +1241,8 @@ xfs_dir2_leaf_log_header(
1221 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1241 xfs_dir2_leaf_t *leaf; /* leaf structure */
1222 1242
1223 leaf = bp->data; 1243 leaf = bp->data;
1224 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC || 1244 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1225 be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 1245 leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1226 xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), 1246 xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf),
1227 (uint)(sizeof(leaf->hdr) - 1)); 1247 (uint)(sizeof(leaf->hdr) - 1));
1228} 1248}
@@ -1241,7 +1261,7 @@ xfs_dir2_leaf_log_tail(
1241 1261
1242 mp = tp->t_mountp; 1262 mp = tp->t_mountp;
1243 leaf = bp->data; 1263 leaf = bp->data;
1244 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); 1264 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
1245 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1265 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1246 xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), 1266 xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf),
1247 (uint)(mp->m_dirblksize - 1)); 1267 (uint)(mp->m_dirblksize - 1));
@@ -1437,7 +1457,7 @@ xfs_dir2_leaf_removename(
1437 xfs_da_args_t *args) /* operation arguments */ 1457 xfs_da_args_t *args) /* operation arguments */
1438{ 1458{
1439 __be16 *bestsp; /* leaf block best freespace */ 1459 __be16 *bestsp; /* leaf block best freespace */
1440 xfs_dir2_data_t *data; /* data block structure */ 1460 xfs_dir2_data_hdr_t *hdr; /* data block header */
1441 xfs_dir2_db_t db; /* data block number */ 1461 xfs_dir2_db_t db; /* data block number */
1442 xfs_dabuf_t *dbp; /* data block buffer */ 1462 xfs_dabuf_t *dbp; /* data block buffer */
1443 xfs_dir2_data_entry_t *dep; /* data entry structure */ 1463 xfs_dir2_data_entry_t *dep; /* data entry structure */
@@ -1467,7 +1487,7 @@ xfs_dir2_leaf_removename(
1467 tp = args->trans; 1487 tp = args->trans;
1468 mp = dp->i_mount; 1488 mp = dp->i_mount;
1469 leaf = lbp->data; 1489 leaf = lbp->data;
1470 data = dbp->data; 1490 hdr = dbp->data;
1471 xfs_dir2_data_check(dp, dbp); 1491 xfs_dir2_data_check(dp, dbp);
1472 /* 1492 /*
1473 * Point to the leaf entry, use that to point to the data entry. 1493 * Point to the leaf entry, use that to point to the data entry.
@@ -1475,9 +1495,9 @@ xfs_dir2_leaf_removename(
1475 lep = &leaf->ents[index]; 1495 lep = &leaf->ents[index];
1476 db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 1496 db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
1477 dep = (xfs_dir2_data_entry_t *) 1497 dep = (xfs_dir2_data_entry_t *)
1478 ((char *)data + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); 1498 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
1479 needscan = needlog = 0; 1499 needscan = needlog = 0;
1480 oldbest = be16_to_cpu(data->hdr.bestfree[0].length); 1500 oldbest = be16_to_cpu(hdr->bestfree[0].length);
1481 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1501 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1482 bestsp = xfs_dir2_leaf_bests_p(ltp); 1502 bestsp = xfs_dir2_leaf_bests_p(ltp);
1483 ASSERT(be16_to_cpu(bestsp[db]) == oldbest); 1503 ASSERT(be16_to_cpu(bestsp[db]) == oldbest);
@@ -1485,7 +1505,7 @@ xfs_dir2_leaf_removename(
1485 * Mark the former data entry unused. 1505 * Mark the former data entry unused.
1486 */ 1506 */
1487 xfs_dir2_data_make_free(tp, dbp, 1507 xfs_dir2_data_make_free(tp, dbp,
1488 (xfs_dir2_data_aoff_t)((char *)dep - (char *)data), 1508 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
1489 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); 1509 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
1490 /* 1510 /*
1491 * We just mark the leaf entry stale by putting a null in it. 1511 * We just mark the leaf entry stale by putting a null in it.
@@ -1499,23 +1519,23 @@ xfs_dir2_leaf_removename(
1499 * log the data block header if necessary. 1519 * log the data block header if necessary.
1500 */ 1520 */
1501 if (needscan) 1521 if (needscan)
1502 xfs_dir2_data_freescan(mp, data, &needlog); 1522 xfs_dir2_data_freescan(mp, hdr, &needlog);
1503 if (needlog) 1523 if (needlog)
1504 xfs_dir2_data_log_header(tp, dbp); 1524 xfs_dir2_data_log_header(tp, dbp);
1505 /* 1525 /*
1506 * If the longest freespace in the data block has changed, 1526 * If the longest freespace in the data block has changed,
1507 * put the new value in the bests table and log that. 1527 * put the new value in the bests table and log that.
1508 */ 1528 */
1509 if (be16_to_cpu(data->hdr.bestfree[0].length) != oldbest) { 1529 if (be16_to_cpu(hdr->bestfree[0].length) != oldbest) {
1510 bestsp[db] = data->hdr.bestfree[0].length; 1530 bestsp[db] = hdr->bestfree[0].length;
1511 xfs_dir2_leaf_log_bests(tp, lbp, db, db); 1531 xfs_dir2_leaf_log_bests(tp, lbp, db, db);
1512 } 1532 }
1513 xfs_dir2_data_check(dp, dbp); 1533 xfs_dir2_data_check(dp, dbp);
1514 /* 1534 /*
1515 * If the data block is now empty then get rid of the data block. 1535 * If the data block is now empty then get rid of the data block.
1516 */ 1536 */
1517 if (be16_to_cpu(data->hdr.bestfree[0].length) == 1537 if (be16_to_cpu(hdr->bestfree[0].length) ==
1518 mp->m_dirblksize - (uint)sizeof(data->hdr)) { 1538 mp->m_dirblksize - (uint)sizeof(*hdr)) {
1519 ASSERT(db != mp->m_dirdatablk); 1539 ASSERT(db != mp->m_dirdatablk);
1520 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { 1540 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
1521 /* 1541 /*
@@ -1542,7 +1562,7 @@ xfs_dir2_leaf_removename(
1542 * Look for the last active entry (i). 1562 * Look for the last active entry (i).
1543 */ 1563 */
1544 for (i = db - 1; i > 0; i--) { 1564 for (i = db - 1; i > 0; i--) {
1545 if (be16_to_cpu(bestsp[i]) != NULLDATAOFF) 1565 if (bestsp[i] != cpu_to_be16(NULLDATAOFF))
1546 break; 1566 break;
1547 } 1567 }
1548 /* 1568 /*
@@ -1686,9 +1706,6 @@ xfs_dir2_leaf_trim_data(
1686 xfs_dir2_db_t db) /* data block number */ 1706 xfs_dir2_db_t db) /* data block number */
1687{ 1707{
1688 __be16 *bestsp; /* leaf bests table */ 1708 __be16 *bestsp; /* leaf bests table */
1689#ifdef DEBUG
1690 xfs_dir2_data_t *data; /* data block structure */
1691#endif
1692 xfs_dabuf_t *dbp; /* data block buffer */ 1709 xfs_dabuf_t *dbp; /* data block buffer */
1693 xfs_inode_t *dp; /* incore directory inode */ 1710 xfs_inode_t *dp; /* incore directory inode */
1694 int error; /* error return value */ 1711 int error; /* error return value */
@@ -1707,20 +1724,21 @@ xfs_dir2_leaf_trim_data(
1707 XFS_DATA_FORK))) { 1724 XFS_DATA_FORK))) {
1708 return error; 1725 return error;
1709 } 1726 }
1710#ifdef DEBUG
1711 data = dbp->data;
1712 ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC);
1713#endif
1714 /* this seems to be an error
1715 * data is only valid if DEBUG is defined?
1716 * RMC 09/08/1999
1717 */
1718 1727
1719 leaf = lbp->data; 1728 leaf = lbp->data;
1720 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1729 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1721 ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) == 1730
1722 mp->m_dirblksize - (uint)sizeof(data->hdr)); 1731#ifdef DEBUG
1732{
1733 struct xfs_dir2_data_hdr *hdr = dbp->data;
1734
1735 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC));
1736 ASSERT(be16_to_cpu(hdr->bestfree[0].length) ==
1737 mp->m_dirblksize - (uint)sizeof(*hdr));
1723 ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); 1738 ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
1739}
1740#endif
1741
1724 /* 1742 /*
1725 * Get rid of the data block. 1743 * Get rid of the data block.
1726 */ 1744 */
@@ -1740,6 +1758,20 @@ xfs_dir2_leaf_trim_data(
1740 return 0; 1758 return 0;
1741} 1759}
1742 1760
1761static inline size_t
1762xfs_dir2_leaf_size(
1763 struct xfs_dir2_leaf_hdr *hdr,
1764 int counts)
1765{
1766 int entries;
1767
1768 entries = be16_to_cpu(hdr->count) - be16_to_cpu(hdr->stale);
1769 return sizeof(xfs_dir2_leaf_hdr_t) +
1770 entries * sizeof(xfs_dir2_leaf_entry_t) +
1771 counts * sizeof(xfs_dir2_data_off_t) +
1772 sizeof(xfs_dir2_leaf_tail_t);
1773}
1774
1743/* 1775/*
1744 * Convert node form directory to leaf form directory. 1776 * Convert node form directory to leaf form directory.
1745 * The root of the node form dir needs to already be a LEAFN block. 1777 * The root of the node form dir needs to already be a LEAFN block.
@@ -1810,7 +1842,7 @@ xfs_dir2_node_to_leaf(
1810 return 0; 1842 return 0;
1811 lbp = state->path.blk[0].bp; 1843 lbp = state->path.blk[0].bp;
1812 leaf = lbp->data; 1844 leaf = lbp->data;
1813 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 1845 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1814 /* 1846 /*
1815 * Read the freespace block. 1847 * Read the freespace block.
1816 */ 1848 */
@@ -1819,20 +1851,19 @@ xfs_dir2_node_to_leaf(
1819 return error; 1851 return error;
1820 } 1852 }
1821 free = fbp->data; 1853 free = fbp->data;
1822 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 1854 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
1823 ASSERT(!free->hdr.firstdb); 1855 ASSERT(!free->hdr.firstdb);
1856
1824 /* 1857 /*
1825 * Now see if the leafn and free data will fit in a leaf1. 1858 * Now see if the leafn and free data will fit in a leaf1.
1826 * If not, release the buffer and give up. 1859 * If not, release the buffer and give up.
1827 */ 1860 */
1828 if ((uint)sizeof(leaf->hdr) + 1861 if (xfs_dir2_leaf_size(&leaf->hdr, be32_to_cpu(free->hdr.nvalid)) >
1829 (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) + 1862 mp->m_dirblksize) {
1830 be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) +
1831 (uint)sizeof(leaf->tail) >
1832 mp->m_dirblksize) {
1833 xfs_da_brelse(tp, fbp); 1863 xfs_da_brelse(tp, fbp);
1834 return 0; 1864 return 0;
1835 } 1865 }
1866
1836 /* 1867 /*
1837 * If the leaf has any stale entries in it, compress them out. 1868 * If the leaf has any stale entries in it, compress them out.
1838 * The compact routine will log the header. 1869 * The compact routine will log the header.
@@ -1851,7 +1882,7 @@ xfs_dir2_node_to_leaf(
1851 * Set up the leaf bests table. 1882 * Set up the leaf bests table.
1852 */ 1883 */
1853 memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests, 1884 memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests,
1854 be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0])); 1885 be32_to_cpu(ltp->bestcount) * sizeof(xfs_dir2_data_off_t));
1855 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); 1886 xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
1856 xfs_dir2_leaf_log_tail(tp, lbp); 1887 xfs_dir2_leaf_log_tail(tp, lbp);
1857 xfs_dir2_leaf_check(dp, lbp); 1888 xfs_dir2_leaf_check(dp, lbp);
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
deleted file mode 100644
index 6c9539f0698..00000000000
--- a/fs/xfs/xfs_dir2_leaf.h
+++ /dev/null
@@ -1,253 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_LEAF_H__
19#define __XFS_DIR2_LEAF_H__
20
21struct uio;
22struct xfs_dabuf;
23struct xfs_da_args;
24struct xfs_inode;
25struct xfs_mount;
26struct xfs_trans;
27
28/*
29 * Offset of the leaf/node space. First block in this space
30 * is the btree root.
31 */
32#define XFS_DIR2_LEAF_SPACE 1
33#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
34#define XFS_DIR2_LEAF_FIRSTDB(mp) \
35 xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
36
37/*
38 * Offset in data space of a data entry.
39 */
40typedef __uint32_t xfs_dir2_dataptr_t;
41#define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff)
42#define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0)
43
44/*
45 * Leaf block header.
46 */
47typedef struct xfs_dir2_leaf_hdr {
48 xfs_da_blkinfo_t info; /* header for da routines */
49 __be16 count; /* count of entries */
50 __be16 stale; /* count of stale entries */
51} xfs_dir2_leaf_hdr_t;
52
53/*
54 * Leaf block entry.
55 */
56typedef struct xfs_dir2_leaf_entry {
57 __be32 hashval; /* hash value of name */
58 __be32 address; /* address of data entry */
59} xfs_dir2_leaf_entry_t;
60
61/*
62 * Leaf block tail.
63 */
64typedef struct xfs_dir2_leaf_tail {
65 __be32 bestcount;
66} xfs_dir2_leaf_tail_t;
67
68/*
69 * Leaf block.
70 * bests and tail are at the end of the block for single-leaf only
71 * (magic = XFS_DIR2_LEAF1_MAGIC not XFS_DIR2_LEAFN_MAGIC).
72 */
73typedef struct xfs_dir2_leaf {
74 xfs_dir2_leaf_hdr_t hdr; /* leaf header */
75 xfs_dir2_leaf_entry_t ents[1]; /* entries */
76 /* ... */
77 xfs_dir2_data_off_t bests[1]; /* best free counts */
78 xfs_dir2_leaf_tail_t tail; /* leaf tail */
79} xfs_dir2_leaf_t;
80
81/*
82 * DB blocks here are logical directory block numbers, not filesystem blocks.
83 */
84
85static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
86{
87 return (int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) /
88 (uint)sizeof(xfs_dir2_leaf_entry_t));
89}
90
91/*
92 * Get address of the bestcount field in the single-leaf block.
93 */
94static inline xfs_dir2_leaf_tail_t *
95xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp)
96{
97 return (xfs_dir2_leaf_tail_t *)
98 ((char *)(lp) + (mp)->m_dirblksize -
99 (uint)sizeof(xfs_dir2_leaf_tail_t));
100}
101
102/*
103 * Get address of the bests array in the single-leaf block.
104 */
105static inline __be16 *
106xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp)
107{
108 return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
109}
110
111/*
112 * Convert dataptr to byte in file space
113 */
114static inline xfs_dir2_off_t
115xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
116{
117 return (xfs_dir2_off_t)(dp) << XFS_DIR2_DATA_ALIGN_LOG;
118}
119
120/*
121 * Convert byte in file space to dataptr. It had better be aligned.
122 */
123static inline xfs_dir2_dataptr_t
124xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
125{
126 return (xfs_dir2_dataptr_t)((by) >> XFS_DIR2_DATA_ALIGN_LOG);
127}
128
129/*
130 * Convert byte in space to (DB) block
131 */
132static inline xfs_dir2_db_t
133xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
134{
135 return (xfs_dir2_db_t)((by) >> \
136 ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog));
137}
138
139/*
140 * Convert dataptr to a block number
141 */
142static inline xfs_dir2_db_t
143xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
144{
145 return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp));
146}
147
148/*
149 * Convert byte in space to offset in a block
150 */
151static inline xfs_dir2_data_aoff_t
152xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
153{
154 return (xfs_dir2_data_aoff_t)((by) & \
155 ((1 << ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) - 1));
156}
157
158/*
159 * Convert dataptr to a byte offset in a block
160 */
161static inline xfs_dir2_data_aoff_t
162xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
163{
164 return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp));
165}
166
167/*
168 * Convert block and offset to byte in space
169 */
170static inline xfs_dir2_off_t
171xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
172 xfs_dir2_data_aoff_t o)
173{
174 return ((xfs_dir2_off_t)(db) << \
175 ((mp)->m_sb.sb_blocklog + (mp)->m_sb.sb_dirblklog)) + (o);
176}
177
178/*
179 * Convert block (DB) to block (dablk)
180 */
181static inline xfs_dablk_t
182xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
183{
184 return (xfs_dablk_t)((db) << (mp)->m_sb.sb_dirblklog);
185}
186
187/*
188 * Convert byte in space to (DA) block
189 */
190static inline xfs_dablk_t
191xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
192{
193 return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by));
194}
195
196/*
197 * Convert block and offset to dataptr
198 */
199static inline xfs_dir2_dataptr_t
200xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
201 xfs_dir2_data_aoff_t o)
202{
203 return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o));
204}
205
206/*
207 * Convert block (dablk) to block (DB)
208 */
209static inline xfs_dir2_db_t
210xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
211{
212 return (xfs_dir2_db_t)((da) >> (mp)->m_sb.sb_dirblklog);
213}
214
215/*
216 * Convert block (dablk) to byte offset in space
217 */
218static inline xfs_dir2_off_t
219xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
220{
221 return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0);
222}
223
224/*
225 * Function declarations.
226 */
227extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
228 struct xfs_dabuf *dbp);
229extern int xfs_dir2_leaf_addname(struct xfs_da_args *args);
230extern void xfs_dir2_leaf_compact(struct xfs_da_args *args,
231 struct xfs_dabuf *bp);
232extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
233 int *lowstalep, int *highstalep,
234 int *lowlogp, int *highlogp);
235extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
236 size_t bufsize, xfs_off_t *offset,
237 filldir_t filldir);
238extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
239 struct xfs_dabuf **bpp, int magic);
240extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
241 int first, int last);
242extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp,
243 struct xfs_dabuf *bp);
244extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
245extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
246extern int xfs_dir2_leaf_replace(struct xfs_da_args *args);
247extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
248 struct xfs_dabuf *lbp);
249extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args,
250 struct xfs_dabuf *lbp, xfs_dir2_db_t db);
251extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
252
253#endif /* __XFS_DIR2_LEAF_H__ */
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index a0aab7d3294..0179a41d9e5 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -23,18 +23,14 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_da_btree.h" 27#include "xfs_da_btree.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir2_sf.h"
31#include "xfs_dinode.h" 29#include "xfs_dinode.h"
32#include "xfs_inode.h" 30#include "xfs_inode.h"
33#include "xfs_bmap.h" 31#include "xfs_bmap.h"
34#include "xfs_dir2_data.h" 32#include "xfs_dir2_format.h"
35#include "xfs_dir2_leaf.h" 33#include "xfs_dir2_priv.h"
36#include "xfs_dir2_block.h"
37#include "xfs_dir2_node.h"
38#include "xfs_error.h" 34#include "xfs_error.h"
39#include "xfs_trace.h" 35#include "xfs_trace.h"
40 36
@@ -73,7 +69,7 @@ xfs_dir2_free_log_bests(
73 xfs_dir2_free_t *free; /* freespace structure */ 69 xfs_dir2_free_t *free; /* freespace structure */
74 70
75 free = bp->data; 71 free = bp->data;
76 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 72 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
77 xfs_da_log_buf(tp, bp, 73 xfs_da_log_buf(tp, bp,
78 (uint)((char *)&free->bests[first] - (char *)free), 74 (uint)((char *)&free->bests[first] - (char *)free),
79 (uint)((char *)&free->bests[last] - (char *)free + 75 (uint)((char *)&free->bests[last] - (char *)free +
@@ -91,7 +87,7 @@ xfs_dir2_free_log_header(
91 xfs_dir2_free_t *free; /* freespace structure */ 87 xfs_dir2_free_t *free; /* freespace structure */
92 88
93 free = bp->data; 89 free = bp->data;
94 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 90 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
95 xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free), 91 xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free),
96 (uint)(sizeof(xfs_dir2_free_hdr_t) - 1)); 92 (uint)(sizeof(xfs_dir2_free_hdr_t) - 1));
97} 93}
@@ -244,89 +240,13 @@ xfs_dir2_leafn_add(
244 lfloglow = be16_to_cpu(leaf->hdr.count); 240 lfloglow = be16_to_cpu(leaf->hdr.count);
245 lfloghigh = -1; 241 lfloghigh = -1;
246 } 242 }
247 /* 243
248 * No stale entries, just insert a space for the new entry.
249 */
250 if (!leaf->hdr.stale) {
251 lep = &leaf->ents[index];
252 if (index < be16_to_cpu(leaf->hdr.count))
253 memmove(lep + 1, lep,
254 (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
255 lfloglow = index;
256 lfloghigh = be16_to_cpu(leaf->hdr.count);
257 be16_add_cpu(&leaf->hdr.count, 1);
258 }
259 /*
260 * There are stale entries. We'll use one for the new entry.
261 */
262 else {
263 /*
264 * If we didn't do a compact then we need to figure out
265 * which stale entry will be used.
266 */
267 if (compact == 0) {
268 /*
269 * Find first stale entry before our insertion point.
270 */
271 for (lowstale = index - 1;
272 lowstale >= 0 &&
273 be32_to_cpu(leaf->ents[lowstale].address) !=
274 XFS_DIR2_NULL_DATAPTR;
275 lowstale--)
276 continue;
277 /*
278 * Find next stale entry after insertion point.
279 * Stop looking if the answer would be worse than
280 * lowstale already found.
281 */
282 for (highstale = index;
283 highstale < be16_to_cpu(leaf->hdr.count) &&
284 be32_to_cpu(leaf->ents[highstale].address) !=
285 XFS_DIR2_NULL_DATAPTR &&
286 (lowstale < 0 ||
287 index - lowstale - 1 >= highstale - index);
288 highstale++)
289 continue;
290 }
291 /*
292 * Using the low stale entry.
293 * Shift entries up toward the stale slot.
294 */
295 if (lowstale >= 0 &&
296 (highstale == be16_to_cpu(leaf->hdr.count) ||
297 index - lowstale - 1 < highstale - index)) {
298 ASSERT(be32_to_cpu(leaf->ents[lowstale].address) ==
299 XFS_DIR2_NULL_DATAPTR);
300 ASSERT(index - lowstale - 1 >= 0);
301 if (index - lowstale - 1 > 0)
302 memmove(&leaf->ents[lowstale],
303 &leaf->ents[lowstale + 1],
304 (index - lowstale - 1) * sizeof(*lep));
305 lep = &leaf->ents[index - 1];
306 lfloglow = MIN(lowstale, lfloglow);
307 lfloghigh = MAX(index - 1, lfloghigh);
308 }
309 /*
310 * Using the high stale entry.
311 * Shift entries down toward the stale slot.
312 */
313 else {
314 ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
315 XFS_DIR2_NULL_DATAPTR);
316 ASSERT(highstale - index >= 0);
317 if (highstale - index > 0)
318 memmove(&leaf->ents[index + 1],
319 &leaf->ents[index],
320 (highstale - index) * sizeof(*lep));
321 lep = &leaf->ents[index];
322 lfloglow = MIN(index, lfloglow);
323 lfloghigh = MAX(highstale, lfloghigh);
324 }
325 be16_add_cpu(&leaf->hdr.stale, -1);
326 }
327 /* 244 /*
328 * Insert the new entry, log everything. 245 * Insert the new entry, log everything.
329 */ 246 */
247 lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale,
248 highstale, &lfloglow, &lfloghigh);
249
330 lep->hashval = cpu_to_be32(args->hashval); 250 lep->hashval = cpu_to_be32(args->hashval);
331 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, 251 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp,
332 args->blkno, args->index)); 252 args->blkno, args->index));
@@ -352,14 +272,14 @@ xfs_dir2_leafn_check(
352 272
353 leaf = bp->data; 273 leaf = bp->data;
354 mp = dp->i_mount; 274 mp = dp->i_mount;
355 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 275 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
356 ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); 276 ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp));
357 for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { 277 for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
358 if (i + 1 < be16_to_cpu(leaf->hdr.count)) { 278 if (i + 1 < be16_to_cpu(leaf->hdr.count)) {
359 ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= 279 ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
360 be32_to_cpu(leaf->ents[i + 1].hashval)); 280 be32_to_cpu(leaf->ents[i + 1].hashval));
361 } 281 }
362 if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR) 282 if (leaf->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
363 stale++; 283 stale++;
364 } 284 }
365 ASSERT(be16_to_cpu(leaf->hdr.stale) == stale); 285 ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
@@ -378,7 +298,7 @@ xfs_dir2_leafn_lasthash(
378 xfs_dir2_leaf_t *leaf; /* leaf structure */ 298 xfs_dir2_leaf_t *leaf; /* leaf structure */
379 299
380 leaf = bp->data; 300 leaf = bp->data;
381 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 301 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
382 if (count) 302 if (count)
383 *count = be16_to_cpu(leaf->hdr.count); 303 *count = be16_to_cpu(leaf->hdr.count);
384 if (!leaf->hdr.count) 304 if (!leaf->hdr.count)
@@ -417,7 +337,7 @@ xfs_dir2_leafn_lookup_for_addname(
417 tp = args->trans; 337 tp = args->trans;
418 mp = dp->i_mount; 338 mp = dp->i_mount;
419 leaf = bp->data; 339 leaf = bp->data;
420 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 340 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
421#ifdef __KERNEL__ 341#ifdef __KERNEL__
422 ASSERT(be16_to_cpu(leaf->hdr.count) > 0); 342 ASSERT(be16_to_cpu(leaf->hdr.count) > 0);
423#endif 343#endif
@@ -434,7 +354,7 @@ xfs_dir2_leafn_lookup_for_addname(
434 curbp = state->extrablk.bp; 354 curbp = state->extrablk.bp;
435 curfdb = state->extrablk.blkno; 355 curfdb = state->extrablk.blkno;
436 free = curbp->data; 356 free = curbp->data;
437 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 357 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
438 } 358 }
439 length = xfs_dir2_data_entsize(args->namelen); 359 length = xfs_dir2_data_entsize(args->namelen);
440 /* 360 /*
@@ -488,7 +408,7 @@ xfs_dir2_leafn_lookup_for_addname(
488 ASSERT(be32_to_cpu(free->hdr.magic) == 408 ASSERT(be32_to_cpu(free->hdr.magic) ==
489 XFS_DIR2_FREE_MAGIC); 409 XFS_DIR2_FREE_MAGIC);
490 ASSERT((be32_to_cpu(free->hdr.firstdb) % 410 ASSERT((be32_to_cpu(free->hdr.firstdb) %
491 XFS_DIR2_MAX_FREE_BESTS(mp)) == 0); 411 xfs_dir2_free_max_bests(mp)) == 0);
492 ASSERT(be32_to_cpu(free->hdr.firstdb) <= curdb); 412 ASSERT(be32_to_cpu(free->hdr.firstdb) <= curdb);
493 ASSERT(curdb < be32_to_cpu(free->hdr.firstdb) + 413 ASSERT(curdb < be32_to_cpu(free->hdr.firstdb) +
494 be32_to_cpu(free->hdr.nvalid)); 414 be32_to_cpu(free->hdr.nvalid));
@@ -500,7 +420,8 @@ xfs_dir2_leafn_lookup_for_addname(
500 /* 420 /*
501 * If it has room, return it. 421 * If it has room, return it.
502 */ 422 */
503 if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) { 423 if (unlikely(free->bests[fi] ==
424 cpu_to_be16(NULLDATAOFF))) {
504 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", 425 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
505 XFS_ERRLEVEL_LOW, mp); 426 XFS_ERRLEVEL_LOW, mp);
506 if (curfdb != newfdb) 427 if (curfdb != newfdb)
@@ -561,7 +482,7 @@ xfs_dir2_leafn_lookup_for_entry(
561 tp = args->trans; 482 tp = args->trans;
562 mp = dp->i_mount; 483 mp = dp->i_mount;
563 leaf = bp->data; 484 leaf = bp->data;
564 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 485 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
565#ifdef __KERNEL__ 486#ifdef __KERNEL__
566 ASSERT(be16_to_cpu(leaf->hdr.count) > 0); 487 ASSERT(be16_to_cpu(leaf->hdr.count) > 0);
567#endif 488#endif
@@ -742,7 +663,8 @@ xfs_dir2_leafn_moveents(
742 int i; /* temp leaf index */ 663 int i; /* temp leaf index */
743 664
744 for (i = start_s, stale = 0; i < start_s + count; i++) { 665 for (i = start_s, stale = 0; i < start_s + count; i++) {
745 if (be32_to_cpu(leaf_s->ents[i].address) == XFS_DIR2_NULL_DATAPTR) 666 if (leaf_s->ents[i].address ==
667 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
746 stale++; 668 stale++;
747 } 669 }
748 } else 670 } else
@@ -789,8 +711,8 @@ xfs_dir2_leafn_order(
789 711
790 leaf1 = leaf1_bp->data; 712 leaf1 = leaf1_bp->data;
791 leaf2 = leaf2_bp->data; 713 leaf2 = leaf2_bp->data;
792 ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 714 ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
793 ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 715 ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
794 if (be16_to_cpu(leaf1->hdr.count) > 0 && 716 if (be16_to_cpu(leaf1->hdr.count) > 0 &&
795 be16_to_cpu(leaf2->hdr.count) > 0 && 717 be16_to_cpu(leaf2->hdr.count) > 0 &&
796 (be32_to_cpu(leaf2->ents[0].hashval) < be32_to_cpu(leaf1->ents[0].hashval) || 718 (be32_to_cpu(leaf2->ents[0].hashval) < be32_to_cpu(leaf1->ents[0].hashval) ||
@@ -918,7 +840,7 @@ xfs_dir2_leafn_remove(
918 xfs_da_state_blk_t *dblk, /* data block */ 840 xfs_da_state_blk_t *dblk, /* data block */
919 int *rval) /* resulting block needs join */ 841 int *rval) /* resulting block needs join */
920{ 842{
921 xfs_dir2_data_t *data; /* data block structure */ 843 xfs_dir2_data_hdr_t *hdr; /* data block header */
922 xfs_dir2_db_t db; /* data block number */ 844 xfs_dir2_db_t db; /* data block number */
923 xfs_dabuf_t *dbp; /* data block buffer */ 845 xfs_dabuf_t *dbp; /* data block buffer */
924 xfs_dir2_data_entry_t *dep; /* data block entry */ 846 xfs_dir2_data_entry_t *dep; /* data block entry */
@@ -938,7 +860,7 @@ xfs_dir2_leafn_remove(
938 tp = args->trans; 860 tp = args->trans;
939 mp = dp->i_mount; 861 mp = dp->i_mount;
940 leaf = bp->data; 862 leaf = bp->data;
941 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 863 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
942 /* 864 /*
943 * Point to the entry we're removing. 865 * Point to the entry we're removing.
944 */ 866 */
@@ -963,9 +885,9 @@ xfs_dir2_leafn_remove(
963 * in the data block in case it changes. 885 * in the data block in case it changes.
964 */ 886 */
965 dbp = dblk->bp; 887 dbp = dblk->bp;
966 data = dbp->data; 888 hdr = dbp->data;
967 dep = (xfs_dir2_data_entry_t *)((char *)data + off); 889 dep = (xfs_dir2_data_entry_t *)((char *)hdr + off);
968 longest = be16_to_cpu(data->hdr.bestfree[0].length); 890 longest = be16_to_cpu(hdr->bestfree[0].length);
969 needlog = needscan = 0; 891 needlog = needscan = 0;
970 xfs_dir2_data_make_free(tp, dbp, off, 892 xfs_dir2_data_make_free(tp, dbp, off,
971 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); 893 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
@@ -974,7 +896,7 @@ xfs_dir2_leafn_remove(
974 * Log the data block header if needed. 896 * Log the data block header if needed.
975 */ 897 */
976 if (needscan) 898 if (needscan)
977 xfs_dir2_data_freescan(mp, data, &needlog); 899 xfs_dir2_data_freescan(mp, hdr, &needlog);
978 if (needlog) 900 if (needlog)
979 xfs_dir2_data_log_header(tp, dbp); 901 xfs_dir2_data_log_header(tp, dbp);
980 xfs_dir2_data_check(dp, dbp); 902 xfs_dir2_data_check(dp, dbp);
@@ -982,7 +904,7 @@ xfs_dir2_leafn_remove(
982 * If the longest data block freespace changes, need to update 904 * If the longest data block freespace changes, need to update
983 * the corresponding freeblock entry. 905 * the corresponding freeblock entry.
984 */ 906 */
985 if (longest < be16_to_cpu(data->hdr.bestfree[0].length)) { 907 if (longest < be16_to_cpu(hdr->bestfree[0].length)) {
986 int error; /* error return value */ 908 int error; /* error return value */
987 xfs_dabuf_t *fbp; /* freeblock buffer */ 909 xfs_dabuf_t *fbp; /* freeblock buffer */
988 xfs_dir2_db_t fdb; /* freeblock block number */ 910 xfs_dir2_db_t fdb; /* freeblock block number */
@@ -1000,27 +922,27 @@ xfs_dir2_leafn_remove(
1000 return error; 922 return error;
1001 } 923 }
1002 free = fbp->data; 924 free = fbp->data;
1003 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 925 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
1004 ASSERT(be32_to_cpu(free->hdr.firstdb) == 926 ASSERT(be32_to_cpu(free->hdr.firstdb) ==
1005 XFS_DIR2_MAX_FREE_BESTS(mp) * 927 xfs_dir2_free_max_bests(mp) *
1006 (fdb - XFS_DIR2_FREE_FIRSTDB(mp))); 928 (fdb - XFS_DIR2_FREE_FIRSTDB(mp)));
1007 /* 929 /*
1008 * Calculate which entry we need to fix. 930 * Calculate which entry we need to fix.
1009 */ 931 */
1010 findex = xfs_dir2_db_to_fdindex(mp, db); 932 findex = xfs_dir2_db_to_fdindex(mp, db);
1011 longest = be16_to_cpu(data->hdr.bestfree[0].length); 933 longest = be16_to_cpu(hdr->bestfree[0].length);
1012 /* 934 /*
1013 * If the data block is now empty we can get rid of it 935 * If the data block is now empty we can get rid of it
1014 * (usually). 936 * (usually).
1015 */ 937 */
1016 if (longest == mp->m_dirblksize - (uint)sizeof(data->hdr)) { 938 if (longest == mp->m_dirblksize - (uint)sizeof(*hdr)) {
1017 /* 939 /*
1018 * Try to punch out the data block. 940 * Try to punch out the data block.
1019 */ 941 */
1020 error = xfs_dir2_shrink_inode(args, db, dbp); 942 error = xfs_dir2_shrink_inode(args, db, dbp);
1021 if (error == 0) { 943 if (error == 0) {
1022 dblk->bp = NULL; 944 dblk->bp = NULL;
1023 data = NULL; 945 hdr = NULL;
1024 } 946 }
1025 /* 947 /*
1026 * We can get ENOSPC if there's no space reservation. 948 * We can get ENOSPC if there's no space reservation.
@@ -1036,7 +958,7 @@ xfs_dir2_leafn_remove(
1036 * If we got rid of the data block, we can eliminate that entry 958 * If we got rid of the data block, we can eliminate that entry
1037 * in the free block. 959 * in the free block.
1038 */ 960 */
1039 if (data == NULL) { 961 if (hdr == NULL) {
1040 /* 962 /*
1041 * One less used entry in the free table. 963 * One less used entry in the free table.
1042 */ 964 */
@@ -1052,7 +974,8 @@ xfs_dir2_leafn_remove(
1052 int i; /* free entry index */ 974 int i; /* free entry index */
1053 975
1054 for (i = findex - 1; 976 for (i = findex - 1;
1055 i >= 0 && be16_to_cpu(free->bests[i]) == NULLDATAOFF; 977 i >= 0 &&
978 free->bests[i] == cpu_to_be16(NULLDATAOFF);
1056 i--) 979 i--)
1057 continue; 980 continue;
1058 free->hdr.nvalid = cpu_to_be32(i + 1); 981 free->hdr.nvalid = cpu_to_be32(i + 1);
@@ -1209,7 +1132,7 @@ xfs_dir2_leafn_toosmall(
1209 */ 1132 */
1210 blk = &state->path.blk[state->path.active - 1]; 1133 blk = &state->path.blk[state->path.active - 1];
1211 info = blk->bp->data; 1134 info = blk->bp->data;
1212 ASSERT(be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC); 1135 ASSERT(info->magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1213 leaf = (xfs_dir2_leaf_t *)info; 1136 leaf = (xfs_dir2_leaf_t *)info;
1214 count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); 1137 count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
1215 bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]); 1138 bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]);
@@ -1268,7 +1191,7 @@ xfs_dir2_leafn_toosmall(
1268 count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); 1191 count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
1269 bytes = state->blocksize - (state->blocksize >> 2); 1192 bytes = state->blocksize - (state->blocksize >> 2);
1270 leaf = bp->data; 1193 leaf = bp->data;
1271 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 1194 ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1272 count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale); 1195 count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
1273 bytes -= count * (uint)sizeof(leaf->ents[0]); 1196 bytes -= count * (uint)sizeof(leaf->ents[0]);
1274 /* 1197 /*
@@ -1327,8 +1250,8 @@ xfs_dir2_leafn_unbalance(
1327 ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC); 1250 ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC);
1328 drop_leaf = drop_blk->bp->data; 1251 drop_leaf = drop_blk->bp->data;
1329 save_leaf = save_blk->bp->data; 1252 save_leaf = save_blk->bp->data;
1330 ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 1253 ASSERT(drop_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1331 ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 1254 ASSERT(save_leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
1332 /* 1255 /*
1333 * If there are any stale leaf entries, take this opportunity 1256 * If there are any stale leaf entries, take this opportunity
1334 * to purge them. 1257 * to purge them.
@@ -1432,7 +1355,7 @@ xfs_dir2_node_addname_int(
1432 xfs_da_args_t *args, /* operation arguments */ 1355 xfs_da_args_t *args, /* operation arguments */
1433 xfs_da_state_blk_t *fblk) /* optional freespace block */ 1356 xfs_da_state_blk_t *fblk) /* optional freespace block */
1434{ 1357{
1435 xfs_dir2_data_t *data; /* data block structure */ 1358 xfs_dir2_data_hdr_t *hdr; /* data block header */
1436 xfs_dir2_db_t dbno; /* data block number */ 1359 xfs_dir2_db_t dbno; /* data block number */
1437 xfs_dabuf_t *dbp; /* data block buffer */ 1360 xfs_dabuf_t *dbp; /* data block buffer */
1438 xfs_dir2_data_entry_t *dep; /* data entry pointer */ 1361 xfs_dir2_data_entry_t *dep; /* data entry pointer */
@@ -1469,7 +1392,7 @@ xfs_dir2_node_addname_int(
1469 */ 1392 */
1470 ifbno = fblk->blkno; 1393 ifbno = fblk->blkno;
1471 free = fbp->data; 1394 free = fbp->data;
1472 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 1395 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
1473 findex = fblk->index; 1396 findex = fblk->index;
1474 /* 1397 /*
1475 * This means the free entry showed that the data block had 1398 * This means the free entry showed that the data block had
@@ -1553,7 +1476,7 @@ xfs_dir2_node_addname_int(
1553 continue; 1476 continue;
1554 } 1477 }
1555 free = fbp->data; 1478 free = fbp->data;
1556 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 1479 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
1557 findex = 0; 1480 findex = 0;
1558 } 1481 }
1559 /* 1482 /*
@@ -1641,7 +1564,7 @@ xfs_dir2_node_addname_int(
1641 1564
1642 if (unlikely(xfs_dir2_db_to_fdb(mp, dbno) != fbno)) { 1565 if (unlikely(xfs_dir2_db_to_fdb(mp, dbno) != fbno)) {
1643 xfs_alert(mp, 1566 xfs_alert(mp,
1644 "%s: dir ino " "%llu needed freesp block %lld for\n" 1567 "%s: dir ino %llu needed freesp block %lld for\n"
1645 " data block %lld, got %lld ifbno %llu lastfbno %d", 1568 " data block %lld, got %lld ifbno %llu lastfbno %d",
1646 __func__, (unsigned long long)dp->i_ino, 1569 __func__, (unsigned long long)dp->i_ino,
1647 (long long)xfs_dir2_db_to_fdb(mp, dbno), 1570 (long long)xfs_dir2_db_to_fdb(mp, dbno),
@@ -1680,12 +1603,12 @@ xfs_dir2_node_addname_int(
1680 free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC); 1603 free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC);
1681 free->hdr.firstdb = cpu_to_be32( 1604 free->hdr.firstdb = cpu_to_be32(
1682 (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * 1605 (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) *
1683 XFS_DIR2_MAX_FREE_BESTS(mp)); 1606 xfs_dir2_free_max_bests(mp));
1684 free->hdr.nvalid = 0; 1607 free->hdr.nvalid = 0;
1685 free->hdr.nused = 0; 1608 free->hdr.nused = 0;
1686 } else { 1609 } else {
1687 free = fbp->data; 1610 free = fbp->data;
1688 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 1611 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
1689 } 1612 }
1690 1613
1691 /* 1614 /*
@@ -1697,7 +1620,7 @@ xfs_dir2_node_addname_int(
1697 * freespace block, extend that table. 1620 * freespace block, extend that table.
1698 */ 1621 */
1699 if (findex >= be32_to_cpu(free->hdr.nvalid)) { 1622 if (findex >= be32_to_cpu(free->hdr.nvalid)) {
1700 ASSERT(findex < XFS_DIR2_MAX_FREE_BESTS(mp)); 1623 ASSERT(findex < xfs_dir2_free_max_bests(mp));
1701 free->hdr.nvalid = cpu_to_be32(findex + 1); 1624 free->hdr.nvalid = cpu_to_be32(findex + 1);
1702 /* 1625 /*
1703 * Tag new entry so nused will go up. 1626 * Tag new entry so nused will go up.
@@ -1708,7 +1631,7 @@ xfs_dir2_node_addname_int(
1708 * If this entry was for an empty data block 1631 * If this entry was for an empty data block
1709 * (this should always be true) then update the header. 1632 * (this should always be true) then update the header.
1710 */ 1633 */
1711 if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) { 1634 if (free->bests[findex] == cpu_to_be16(NULLDATAOFF)) {
1712 be32_add_cpu(&free->hdr.nused, 1); 1635 be32_add_cpu(&free->hdr.nused, 1);
1713 xfs_dir2_free_log_header(tp, fbp); 1636 xfs_dir2_free_log_header(tp, fbp);
1714 } 1637 }
@@ -1717,8 +1640,8 @@ xfs_dir2_node_addname_int(
1717 * We haven't allocated the data entry yet so this will 1640 * We haven't allocated the data entry yet so this will
1718 * change again. 1641 * change again.
1719 */ 1642 */
1720 data = dbp->data; 1643 hdr = dbp->data;
1721 free->bests[findex] = data->hdr.bestfree[0].length; 1644 free->bests[findex] = hdr->bestfree[0].length;
1722 logfree = 1; 1645 logfree = 1;
1723 } 1646 }
1724 /* 1647 /*
@@ -1743,21 +1666,21 @@ xfs_dir2_node_addname_int(
1743 xfs_da_buf_done(fbp); 1666 xfs_da_buf_done(fbp);
1744 return error; 1667 return error;
1745 } 1668 }
1746 data = dbp->data; 1669 hdr = dbp->data;
1747 logfree = 0; 1670 logfree = 0;
1748 } 1671 }
1749 ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) >= length); 1672 ASSERT(be16_to_cpu(hdr->bestfree[0].length) >= length);
1750 /* 1673 /*
1751 * Point to the existing unused space. 1674 * Point to the existing unused space.
1752 */ 1675 */
1753 dup = (xfs_dir2_data_unused_t *) 1676 dup = (xfs_dir2_data_unused_t *)
1754 ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); 1677 ((char *)hdr + be16_to_cpu(hdr->bestfree[0].offset));
1755 needscan = needlog = 0; 1678 needscan = needlog = 0;
1756 /* 1679 /*
1757 * Mark the first part of the unused space, inuse for us. 1680 * Mark the first part of the unused space, inuse for us.
1758 */ 1681 */
1759 xfs_dir2_data_use_free(tp, dbp, dup, 1682 xfs_dir2_data_use_free(tp, dbp, dup,
1760 (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, 1683 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
1761 &needlog, &needscan); 1684 &needlog, &needscan);
1762 /* 1685 /*
1763 * Fill in the new entry and log it. 1686 * Fill in the new entry and log it.
@@ -1767,13 +1690,13 @@ xfs_dir2_node_addname_int(
1767 dep->namelen = args->namelen; 1690 dep->namelen = args->namelen;
1768 memcpy(dep->name, args->name, dep->namelen); 1691 memcpy(dep->name, args->name, dep->namelen);
1769 tagp = xfs_dir2_data_entry_tag_p(dep); 1692 tagp = xfs_dir2_data_entry_tag_p(dep);
1770 *tagp = cpu_to_be16((char *)dep - (char *)data); 1693 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1771 xfs_dir2_data_log_entry(tp, dbp, dep); 1694 xfs_dir2_data_log_entry(tp, dbp, dep);
1772 /* 1695 /*
1773 * Rescan the block for bestfree if needed. 1696 * Rescan the block for bestfree if needed.
1774 */ 1697 */
1775 if (needscan) 1698 if (needscan)
1776 xfs_dir2_data_freescan(mp, data, &needlog); 1699 xfs_dir2_data_freescan(mp, hdr, &needlog);
1777 /* 1700 /*
1778 * Log the data block header if needed. 1701 * Log the data block header if needed.
1779 */ 1702 */
@@ -1782,8 +1705,8 @@ xfs_dir2_node_addname_int(
1782 /* 1705 /*
1783 * If the freespace entry is now wrong, update it. 1706 * If the freespace entry is now wrong, update it.
1784 */ 1707 */
1785 if (be16_to_cpu(free->bests[findex]) != be16_to_cpu(data->hdr.bestfree[0].length)) { 1708 if (be16_to_cpu(free->bests[findex]) != be16_to_cpu(hdr->bestfree[0].length)) {
1786 free->bests[findex] = data->hdr.bestfree[0].length; 1709 free->bests[findex] = hdr->bestfree[0].length;
1787 logfree = 1; 1710 logfree = 1;
1788 } 1711 }
1789 /* 1712 /*
@@ -1933,7 +1856,7 @@ xfs_dir2_node_replace(
1933 xfs_da_args_t *args) /* operation arguments */ 1856 xfs_da_args_t *args) /* operation arguments */
1934{ 1857{
1935 xfs_da_state_blk_t *blk; /* leaf block */ 1858 xfs_da_state_blk_t *blk; /* leaf block */
1936 xfs_dir2_data_t *data; /* data block structure */ 1859 xfs_dir2_data_hdr_t *hdr; /* data block header */
1937 xfs_dir2_data_entry_t *dep; /* data entry changed */ 1860 xfs_dir2_data_entry_t *dep; /* data entry changed */
1938 int error; /* error return value */ 1861 int error; /* error return value */
1939 int i; /* btree level */ 1862 int i; /* btree level */
@@ -1977,10 +1900,10 @@ xfs_dir2_node_replace(
1977 /* 1900 /*
1978 * Point to the data entry. 1901 * Point to the data entry.
1979 */ 1902 */
1980 data = state->extrablk.bp->data; 1903 hdr = state->extrablk.bp->data;
1981 ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); 1904 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC));
1982 dep = (xfs_dir2_data_entry_t *) 1905 dep = (xfs_dir2_data_entry_t *)
1983 ((char *)data + 1906 ((char *)hdr +
1984 xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); 1907 xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address)));
1985 ASSERT(inum != be64_to_cpu(dep->inumber)); 1908 ASSERT(inum != be64_to_cpu(dep->inumber));
1986 /* 1909 /*
@@ -2044,7 +1967,7 @@ xfs_dir2_node_trim_free(
2044 return 0; 1967 return 0;
2045 } 1968 }
2046 free = bp->data; 1969 free = bp->data;
2047 ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); 1970 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
2048 /* 1971 /*
2049 * If there are used entries, there's nothing to do. 1972 * If there are used entries, there's nothing to do.
2050 */ 1973 */
diff --git a/fs/xfs/xfs_dir2_node.h b/fs/xfs/xfs_dir2_node.h
deleted file mode 100644
index 82dfe714719..00000000000
--- a/fs/xfs/xfs_dir2_node.h
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_NODE_H__
19#define __XFS_DIR2_NODE_H__
20
21/*
22 * Directory version 2, btree node format structures
23 */
24
25struct uio;
26struct xfs_dabuf;
27struct xfs_da_args;
28struct xfs_da_state;
29struct xfs_da_state_blk;
30struct xfs_inode;
31struct xfs_trans;
32
33/*
34 * Offset of the freespace index.
35 */
36#define XFS_DIR2_FREE_SPACE 2
37#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
38#define XFS_DIR2_FREE_FIRSTDB(mp) \
39 xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
40
41#define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */
42
43typedef struct xfs_dir2_free_hdr {
44 __be32 magic; /* XFS_DIR2_FREE_MAGIC */
45 __be32 firstdb; /* db of first entry */
46 __be32 nvalid; /* count of valid entries */
47 __be32 nused; /* count of used entries */
48} xfs_dir2_free_hdr_t;
49
50typedef struct xfs_dir2_free {
51 xfs_dir2_free_hdr_t hdr; /* block header */
52 __be16 bests[1]; /* best free counts */
53 /* unused entries are -1 */
54} xfs_dir2_free_t;
55
56#define XFS_DIR2_MAX_FREE_BESTS(mp) \
57 (((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_free_hdr_t)) / \
58 (uint)sizeof(xfs_dir2_data_off_t))
59
60/*
61 * Convert data space db to the corresponding free db.
62 */
63static inline xfs_dir2_db_t
64xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
65{
66 return (XFS_DIR2_FREE_FIRSTDB(mp) + (db) / XFS_DIR2_MAX_FREE_BESTS(mp));
67}
68
69/*
70 * Convert data space db to the corresponding index in a free db.
71 */
72static inline int
73xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
74{
75 return ((db) % XFS_DIR2_MAX_FREE_BESTS(mp));
76}
77
78extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args,
79 struct xfs_dabuf *lbp);
80extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count);
81extern int xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp,
82 struct xfs_da_args *args, int *indexp,
83 struct xfs_da_state *state);
84extern int xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp,
85 struct xfs_dabuf *leaf2_bp);
86extern int xfs_dir2_leafn_split(struct xfs_da_state *state,
87 struct xfs_da_state_blk *oldblk,
88 struct xfs_da_state_blk *newblk);
89extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action);
90extern void xfs_dir2_leafn_unbalance(struct xfs_da_state *state,
91 struct xfs_da_state_blk *drop_blk,
92 struct xfs_da_state_blk *save_blk);
93extern int xfs_dir2_node_addname(struct xfs_da_args *args);
94extern int xfs_dir2_node_lookup(struct xfs_da_args *args);
95extern int xfs_dir2_node_removename(struct xfs_da_args *args);
96extern int xfs_dir2_node_replace(struct xfs_da_args *args);
97extern int xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo,
98 int *rvalp);
99
100#endif /* __XFS_DIR2_NODE_H__ */
diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h
new file mode 100644
index 00000000000..067f403ecf8
--- /dev/null
+++ b/fs/xfs/xfs_dir2_priv.h
@@ -0,0 +1,135 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_PRIV_H__
19#define __XFS_DIR2_PRIV_H__
20
21/* xfs_dir2.c */
22extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
23extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, int *r);
24extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *r);
25extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
26 xfs_dir2_db_t *dbp);
27extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
28 struct xfs_dabuf *bp);
29extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
30 const unsigned char *name, int len);
31
32/* xfs_dir2_block.c */
33extern int xfs_dir2_block_addname(struct xfs_da_args *args);
34extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
35 xfs_off_t *offset, filldir_t filldir);
36extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
37extern int xfs_dir2_block_removename(struct xfs_da_args *args);
38extern int xfs_dir2_block_replace(struct xfs_da_args *args);
39extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
40 struct xfs_dabuf *lbp, struct xfs_dabuf *dbp);
41
42/* xfs_dir2_data.c */
43#ifdef DEBUG
44extern void xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_dabuf *bp);
45#else
46#define xfs_dir2_data_check(dp,bp)
47#endif
48extern struct xfs_dir2_data_free *
49xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr,
50 struct xfs_dir2_data_unused *dup, int *loghead);
51extern void xfs_dir2_data_freescan(struct xfs_mount *mp,
52 struct xfs_dir2_data_hdr *hdr, int *loghead);
53extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno,
54 struct xfs_dabuf **bpp);
55extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp,
56 struct xfs_dir2_data_entry *dep);
57extern void xfs_dir2_data_log_header(struct xfs_trans *tp,
58 struct xfs_dabuf *bp);
59extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_dabuf *bp,
60 struct xfs_dir2_data_unused *dup);
61extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
62 xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len,
63 int *needlogp, int *needscanp);
64extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_dabuf *bp,
65 struct xfs_dir2_data_unused *dup, xfs_dir2_data_aoff_t offset,
66 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
67
68/* xfs_dir2_leaf.c */
69extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
70 struct xfs_dabuf *dbp);
71extern int xfs_dir2_leaf_addname(struct xfs_da_args *args);
72extern void xfs_dir2_leaf_compact(struct xfs_da_args *args,
73 struct xfs_dabuf *bp);
74extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
75 int *lowstalep, int *highstalep, int *lowlogp, int *highlogp);
76extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
77 size_t bufsize, xfs_off_t *offset, filldir_t filldir);
78extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
79 struct xfs_dabuf **bpp, int magic);
80extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
81 int first, int last);
82extern void xfs_dir2_leaf_log_header(struct xfs_trans *tp,
83 struct xfs_dabuf *bp);
84extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
85extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
86extern int xfs_dir2_leaf_replace(struct xfs_da_args *args);
87extern int xfs_dir2_leaf_search_hash(struct xfs_da_args *args,
88 struct xfs_dabuf *lbp);
89extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args,
90 struct xfs_dabuf *lbp, xfs_dir2_db_t db);
91extern struct xfs_dir2_leaf_entry *
92xfs_dir2_leaf_find_entry(struct xfs_dir2_leaf *leaf, int index, int compact,
93 int lowstale, int highstale,
94 int *lfloglow, int *lfloghigh);
95extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state);
96
97/* xfs_dir2_node.c */
98extern int xfs_dir2_leaf_to_node(struct xfs_da_args *args,
99 struct xfs_dabuf *lbp);
100extern xfs_dahash_t xfs_dir2_leafn_lasthash(struct xfs_dabuf *bp, int *count);
101extern int xfs_dir2_leafn_lookup_int(struct xfs_dabuf *bp,
102 struct xfs_da_args *args, int *indexp,
103 struct xfs_da_state *state);
104extern int xfs_dir2_leafn_order(struct xfs_dabuf *leaf1_bp,
105 struct xfs_dabuf *leaf2_bp);
106extern int xfs_dir2_leafn_split(struct xfs_da_state *state,
107 struct xfs_da_state_blk *oldblk, struct xfs_da_state_blk *newblk);
108extern int xfs_dir2_leafn_toosmall(struct xfs_da_state *state, int *action);
109extern void xfs_dir2_leafn_unbalance(struct xfs_da_state *state,
110 struct xfs_da_state_blk *drop_blk,
111 struct xfs_da_state_blk *save_blk);
112extern int xfs_dir2_node_addname(struct xfs_da_args *args);
113extern int xfs_dir2_node_lookup(struct xfs_da_args *args);
114extern int xfs_dir2_node_removename(struct xfs_da_args *args);
115extern int xfs_dir2_node_replace(struct xfs_da_args *args);
116extern int xfs_dir2_node_trim_free(struct xfs_da_args *args, xfs_fileoff_t fo,
117 int *rvalp);
118
119/* xfs_dir2_sf.c */
120extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp);
121extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf_hdr *sfp,
122 struct xfs_dir2_sf_entry *sfep);
123extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
124 struct xfs_dir2_data_hdr *block, struct xfs_dir2_sf_hdr *sfhp);
125extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
126 int size, xfs_dir2_sf_hdr_t *sfhp);
127extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
128extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
129extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
130 xfs_off_t *offset, filldir_t filldir);
131extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
132extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
133extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
134
135#endif /* __XFS_DIR2_PRIV_H__ */
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index b1bae6b1eed..79d05e84e29 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -23,18 +23,16 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_da_btree.h" 27#include "xfs_da_btree.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir2_sf.h"
31#include "xfs_dinode.h" 29#include "xfs_dinode.h"
32#include "xfs_inode.h" 30#include "xfs_inode.h"
33#include "xfs_inode_item.h" 31#include "xfs_inode_item.h"
34#include "xfs_error.h" 32#include "xfs_error.h"
35#include "xfs_dir2_data.h" 33#include "xfs_dir2.h"
36#include "xfs_dir2_leaf.h" 34#include "xfs_dir2_format.h"
37#include "xfs_dir2_block.h" 35#include "xfs_dir2_priv.h"
38#include "xfs_trace.h" 36#include "xfs_trace.h"
39 37
40/* 38/*
@@ -60,6 +58,82 @@ static void xfs_dir2_sf_toino8(xfs_da_args_t *args);
60#endif /* XFS_BIG_INUMS */ 58#endif /* XFS_BIG_INUMS */
61 59
62/* 60/*
61 * Inode numbers in short-form directories can come in two versions,
62 * either 4 bytes or 8 bytes wide. These helpers deal with the
63 * two forms transparently by looking at the headers i8count field.
64 *
65 * For 64-bit inode number the most significant byte must be zero.
66 */
67static xfs_ino_t
68xfs_dir2_sf_get_ino(
69 struct xfs_dir2_sf_hdr *hdr,
70 xfs_dir2_inou_t *from)
71{
72 if (hdr->i8count)
73 return get_unaligned_be64(&from->i8.i) & 0x00ffffffffffffffULL;
74 else
75 return get_unaligned_be32(&from->i4.i);
76}
77
78static void
79xfs_dir2_sf_put_ino(
80 struct xfs_dir2_sf_hdr *hdr,
81 xfs_dir2_inou_t *to,
82 xfs_ino_t ino)
83{
84 ASSERT((ino & 0xff00000000000000ULL) == 0);
85
86 if (hdr->i8count)
87 put_unaligned_be64(ino, &to->i8.i);
88 else
89 put_unaligned_be32(ino, &to->i4.i);
90}
91
92xfs_ino_t
93xfs_dir2_sf_get_parent_ino(
94 struct xfs_dir2_sf_hdr *hdr)
95{
96 return xfs_dir2_sf_get_ino(hdr, &hdr->parent);
97}
98
99static void
100xfs_dir2_sf_put_parent_ino(
101 struct xfs_dir2_sf_hdr *hdr,
102 xfs_ino_t ino)
103{
104 xfs_dir2_sf_put_ino(hdr, &hdr->parent, ino);
105}
106
107/*
108 * In short-form directory entries the inode numbers are stored at variable
109 * offset behind the entry name. The inode numbers may only be accessed
110 * through the helpers below.
111 */
112static xfs_dir2_inou_t *
113xfs_dir2_sfe_inop(
114 struct xfs_dir2_sf_entry *sfep)
115{
116 return (xfs_dir2_inou_t *)&sfep->name[sfep->namelen];
117}
118
119xfs_ino_t
120xfs_dir2_sfe_get_ino(
121 struct xfs_dir2_sf_hdr *hdr,
122 struct xfs_dir2_sf_entry *sfep)
123{
124 return xfs_dir2_sf_get_ino(hdr, xfs_dir2_sfe_inop(sfep));
125}
126
127static void
128xfs_dir2_sfe_put_ino(
129 struct xfs_dir2_sf_hdr *hdr,
130 struct xfs_dir2_sf_entry *sfep,
131 xfs_ino_t ino)
132{
133 xfs_dir2_sf_put_ino(hdr, xfs_dir2_sfe_inop(sfep), ino);
134}
135
136/*
63 * Given a block directory (dp/block), calculate its size as a shortform (sf) 137 * Given a block directory (dp/block), calculate its size as a shortform (sf)
64 * directory and a header for the sf directory, if it will fit it the 138 * directory and a header for the sf directory, if it will fit it the
65 * space currently present in the inode. If it won't fit, the output 139 * space currently present in the inode. If it won't fit, the output
@@ -68,7 +142,7 @@ static void xfs_dir2_sf_toino8(xfs_da_args_t *args);
68int /* size for sf form */ 142int /* size for sf form */
69xfs_dir2_block_sfsize( 143xfs_dir2_block_sfsize(
70 xfs_inode_t *dp, /* incore inode pointer */ 144 xfs_inode_t *dp, /* incore inode pointer */
71 xfs_dir2_block_t *block, /* block directory data */ 145 xfs_dir2_data_hdr_t *hdr, /* block directory data */
72 xfs_dir2_sf_hdr_t *sfhp) /* output: header for sf form */ 146 xfs_dir2_sf_hdr_t *sfhp) /* output: header for sf form */
73{ 147{
74 xfs_dir2_dataptr_t addr; /* data entry address */ 148 xfs_dir2_dataptr_t addr; /* data entry address */
@@ -88,7 +162,7 @@ xfs_dir2_block_sfsize(
88 mp = dp->i_mount; 162 mp = dp->i_mount;
89 163
90 count = i8count = namelen = 0; 164 count = i8count = namelen = 0;
91 btp = xfs_dir2_block_tail_p(mp, block); 165 btp = xfs_dir2_block_tail_p(mp, hdr);
92 blp = xfs_dir2_block_leaf_p(btp); 166 blp = xfs_dir2_block_leaf_p(btp);
93 167
94 /* 168 /*
@@ -101,7 +175,7 @@ xfs_dir2_block_sfsize(
101 * Calculate the pointer to the entry at hand. 175 * Calculate the pointer to the entry at hand.
102 */ 176 */
103 dep = (xfs_dir2_data_entry_t *) 177 dep = (xfs_dir2_data_entry_t *)
104 ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); 178 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr));
105 /* 179 /*
106 * Detect . and .., so we can special-case them. 180 * Detect . and .., so we can special-case them.
107 * . is not included in sf directories. 181 * . is not included in sf directories.
@@ -138,7 +212,7 @@ xfs_dir2_block_sfsize(
138 */ 212 */
139 sfhp->count = count; 213 sfhp->count = count;
140 sfhp->i8count = i8count; 214 sfhp->i8count = i8count;
141 xfs_dir2_sf_put_inumber((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent); 215 xfs_dir2_sf_put_parent_ino(sfhp, parent);
142 return size; 216 return size;
143} 217}
144 218
@@ -153,7 +227,7 @@ xfs_dir2_block_to_sf(
153 int size, /* shortform directory size */ 227 int size, /* shortform directory size */
154 xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */ 228 xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */
155{ 229{
156 xfs_dir2_block_t *block; /* block structure */ 230 xfs_dir2_data_hdr_t *hdr; /* block header */
157 xfs_dir2_block_tail_t *btp; /* block tail pointer */ 231 xfs_dir2_block_tail_t *btp; /* block tail pointer */
158 xfs_dir2_data_entry_t *dep; /* data entry pointer */ 232 xfs_dir2_data_entry_t *dep; /* data entry pointer */
159 xfs_inode_t *dp; /* incore directory inode */ 233 xfs_inode_t *dp; /* incore directory inode */
@@ -164,8 +238,7 @@ xfs_dir2_block_to_sf(
164 xfs_mount_t *mp; /* filesystem mount point */ 238 xfs_mount_t *mp; /* filesystem mount point */
165 char *ptr; /* current data pointer */ 239 char *ptr; /* current data pointer */
166 xfs_dir2_sf_entry_t *sfep; /* shortform entry */ 240 xfs_dir2_sf_entry_t *sfep; /* shortform entry */
167 xfs_dir2_sf_t *sfp; /* shortform structure */ 241 xfs_dir2_sf_hdr_t *sfp; /* shortform directory header */
168 xfs_ino_t temp;
169 242
170 trace_xfs_dir2_block_to_sf(args); 243 trace_xfs_dir2_block_to_sf(args);
171 244
@@ -176,13 +249,14 @@ xfs_dir2_block_to_sf(
176 * Make a copy of the block data, so we can shrink the inode 249 * Make a copy of the block data, so we can shrink the inode
177 * and add local data. 250 * and add local data.
178 */ 251 */
179 block = kmem_alloc(mp->m_dirblksize, KM_SLEEP); 252 hdr = kmem_alloc(mp->m_dirblksize, KM_SLEEP);
180 memcpy(block, bp->data, mp->m_dirblksize); 253 memcpy(hdr, bp->data, mp->m_dirblksize);
181 logflags = XFS_ILOG_CORE; 254 logflags = XFS_ILOG_CORE;
182 if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) { 255 if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) {
183 ASSERT(error != ENOSPC); 256 ASSERT(error != ENOSPC);
184 goto out; 257 goto out;
185 } 258 }
259
186 /* 260 /*
187 * The buffer is now unconditionally gone, whether 261 * The buffer is now unconditionally gone, whether
188 * xfs_dir2_shrink_inode worked or not. 262 * xfs_dir2_shrink_inode worked or not.
@@ -198,14 +272,14 @@ xfs_dir2_block_to_sf(
198 /* 272 /*
199 * Copy the header into the newly allocate local space. 273 * Copy the header into the newly allocate local space.
200 */ 274 */
201 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 275 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
202 memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count)); 276 memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count));
203 dp->i_d.di_size = size; 277 dp->i_d.di_size = size;
204 /* 278 /*
205 * Set up to loop over the block's entries. 279 * Set up to loop over the block's entries.
206 */ 280 */
207 btp = xfs_dir2_block_tail_p(mp, block); 281 btp = xfs_dir2_block_tail_p(mp, hdr);
208 ptr = (char *)block->u; 282 ptr = (char *)(hdr + 1);
209 endptr = (char *)xfs_dir2_block_leaf_p(btp); 283 endptr = (char *)xfs_dir2_block_leaf_p(btp);
210 sfep = xfs_dir2_sf_firstentry(sfp); 284 sfep = xfs_dir2_sf_firstentry(sfp);
211 /* 285 /*
@@ -233,7 +307,7 @@ xfs_dir2_block_to_sf(
233 else if (dep->namelen == 2 && 307 else if (dep->namelen == 2 &&
234 dep->name[0] == '.' && dep->name[1] == '.') 308 dep->name[0] == '.' && dep->name[1] == '.')
235 ASSERT(be64_to_cpu(dep->inumber) == 309 ASSERT(be64_to_cpu(dep->inumber) ==
236 xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); 310 xfs_dir2_sf_get_parent_ino(sfp));
237 /* 311 /*
238 * Normal entry, copy it into shortform. 312 * Normal entry, copy it into shortform.
239 */ 313 */
@@ -241,11 +315,11 @@ xfs_dir2_block_to_sf(
241 sfep->namelen = dep->namelen; 315 sfep->namelen = dep->namelen;
242 xfs_dir2_sf_put_offset(sfep, 316 xfs_dir2_sf_put_offset(sfep,
243 (xfs_dir2_data_aoff_t) 317 (xfs_dir2_data_aoff_t)
244 ((char *)dep - (char *)block)); 318 ((char *)dep - (char *)hdr));
245 memcpy(sfep->name, dep->name, dep->namelen); 319 memcpy(sfep->name, dep->name, dep->namelen);
246 temp = be64_to_cpu(dep->inumber); 320 xfs_dir2_sfe_put_ino(sfp, sfep,
247 xfs_dir2_sf_put_inumber(sfp, &temp, 321 be64_to_cpu(dep->inumber));
248 xfs_dir2_sf_inumberp(sfep)); 322
249 sfep = xfs_dir2_sf_nextentry(sfp, sfep); 323 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
250 } 324 }
251 ptr += xfs_dir2_data_entsize(dep->namelen); 325 ptr += xfs_dir2_data_entsize(dep->namelen);
@@ -254,7 +328,7 @@ xfs_dir2_block_to_sf(
254 xfs_dir2_sf_check(args); 328 xfs_dir2_sf_check(args);
255out: 329out:
256 xfs_trans_log_inode(args->trans, dp, logflags); 330 xfs_trans_log_inode(args->trans, dp, logflags);
257 kmem_free(block); 331 kmem_free(hdr);
258 return error; 332 return error;
259} 333}
260 334
@@ -277,7 +351,7 @@ xfs_dir2_sf_addname(
277 xfs_dir2_data_aoff_t offset = 0; /* offset for new entry */ 351 xfs_dir2_data_aoff_t offset = 0; /* offset for new entry */
278 int old_isize; /* di_size before adding name */ 352 int old_isize; /* di_size before adding name */
279 int pick; /* which algorithm to use */ 353 int pick; /* which algorithm to use */
280 xfs_dir2_sf_t *sfp; /* shortform structure */ 354 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
281 xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */ 355 xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */
282 356
283 trace_xfs_dir2_sf_addname(args); 357 trace_xfs_dir2_sf_addname(args);
@@ -294,19 +368,19 @@ xfs_dir2_sf_addname(
294 } 368 }
295 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 369 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
296 ASSERT(dp->i_df.if_u1.if_data != NULL); 370 ASSERT(dp->i_df.if_u1.if_data != NULL);
297 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 371 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
298 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); 372 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count));
299 /* 373 /*
300 * Compute entry (and change in) size. 374 * Compute entry (and change in) size.
301 */ 375 */
302 add_entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); 376 add_entsize = xfs_dir2_sf_entsize(sfp, args->namelen);
303 incr_isize = add_entsize; 377 incr_isize = add_entsize;
304 objchange = 0; 378 objchange = 0;
305#if XFS_BIG_INUMS 379#if XFS_BIG_INUMS
306 /* 380 /*
307 * Do we have to change to 8 byte inodes? 381 * Do we have to change to 8 byte inodes?
308 */ 382 */
309 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) { 383 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) {
310 /* 384 /*
311 * Yes, adjust the entry size and the total size. 385 * Yes, adjust the entry size and the total size.
312 */ 386 */
@@ -314,7 +388,7 @@ xfs_dir2_sf_addname(
314 (uint)sizeof(xfs_dir2_ino8_t) - 388 (uint)sizeof(xfs_dir2_ino8_t) -
315 (uint)sizeof(xfs_dir2_ino4_t); 389 (uint)sizeof(xfs_dir2_ino4_t);
316 incr_isize += 390 incr_isize +=
317 (sfp->hdr.count + 2) * 391 (sfp->count + 2) *
318 ((uint)sizeof(xfs_dir2_ino8_t) - 392 ((uint)sizeof(xfs_dir2_ino8_t) -
319 (uint)sizeof(xfs_dir2_ino4_t)); 393 (uint)sizeof(xfs_dir2_ino4_t));
320 objchange = 1; 394 objchange = 1;
@@ -384,21 +458,21 @@ xfs_dir2_sf_addname_easy(
384{ 458{
385 int byteoff; /* byte offset in sf dir */ 459 int byteoff; /* byte offset in sf dir */
386 xfs_inode_t *dp; /* incore directory inode */ 460 xfs_inode_t *dp; /* incore directory inode */
387 xfs_dir2_sf_t *sfp; /* shortform structure */ 461 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
388 462
389 dp = args->dp; 463 dp = args->dp;
390 464
391 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 465 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
392 byteoff = (int)((char *)sfep - (char *)sfp); 466 byteoff = (int)((char *)sfep - (char *)sfp);
393 /* 467 /*
394 * Grow the in-inode space. 468 * Grow the in-inode space.
395 */ 469 */
396 xfs_idata_realloc(dp, xfs_dir2_sf_entsize_byname(sfp, args->namelen), 470 xfs_idata_realloc(dp, xfs_dir2_sf_entsize(sfp, args->namelen),
397 XFS_DATA_FORK); 471 XFS_DATA_FORK);
398 /* 472 /*
399 * Need to set up again due to realloc of the inode data. 473 * Need to set up again due to realloc of the inode data.
400 */ 474 */
401 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 475 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
402 sfep = (xfs_dir2_sf_entry_t *)((char *)sfp + byteoff); 476 sfep = (xfs_dir2_sf_entry_t *)((char *)sfp + byteoff);
403 /* 477 /*
404 * Fill in the new entry. 478 * Fill in the new entry.
@@ -406,15 +480,14 @@ xfs_dir2_sf_addname_easy(
406 sfep->namelen = args->namelen; 480 sfep->namelen = args->namelen;
407 xfs_dir2_sf_put_offset(sfep, offset); 481 xfs_dir2_sf_put_offset(sfep, offset);
408 memcpy(sfep->name, args->name, sfep->namelen); 482 memcpy(sfep->name, args->name, sfep->namelen);
409 xfs_dir2_sf_put_inumber(sfp, &args->inumber, 483 xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber);
410 xfs_dir2_sf_inumberp(sfep));
411 /* 484 /*
412 * Update the header and inode. 485 * Update the header and inode.
413 */ 486 */
414 sfp->hdr.count++; 487 sfp->count++;
415#if XFS_BIG_INUMS 488#if XFS_BIG_INUMS
416 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) 489 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM)
417 sfp->hdr.i8count++; 490 sfp->i8count++;
418#endif 491#endif
419 dp->i_d.di_size = new_isize; 492 dp->i_d.di_size = new_isize;
420 xfs_dir2_sf_check(args); 493 xfs_dir2_sf_check(args);
@@ -444,19 +517,19 @@ xfs_dir2_sf_addname_hard(
444 xfs_dir2_data_aoff_t offset; /* current offset value */ 517 xfs_dir2_data_aoff_t offset; /* current offset value */
445 int old_isize; /* previous di_size */ 518 int old_isize; /* previous di_size */
446 xfs_dir2_sf_entry_t *oldsfep; /* entry in original dir */ 519 xfs_dir2_sf_entry_t *oldsfep; /* entry in original dir */
447 xfs_dir2_sf_t *oldsfp; /* original shortform dir */ 520 xfs_dir2_sf_hdr_t *oldsfp; /* original shortform dir */
448 xfs_dir2_sf_entry_t *sfep; /* entry in new dir */ 521 xfs_dir2_sf_entry_t *sfep; /* entry in new dir */
449 xfs_dir2_sf_t *sfp; /* new shortform dir */ 522 xfs_dir2_sf_hdr_t *sfp; /* new shortform dir */
450 523
451 /* 524 /*
452 * Copy the old directory to the stack buffer. 525 * Copy the old directory to the stack buffer.
453 */ 526 */
454 dp = args->dp; 527 dp = args->dp;
455 528
456 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 529 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
457 old_isize = (int)dp->i_d.di_size; 530 old_isize = (int)dp->i_d.di_size;
458 buf = kmem_alloc(old_isize, KM_SLEEP); 531 buf = kmem_alloc(old_isize, KM_SLEEP);
459 oldsfp = (xfs_dir2_sf_t *)buf; 532 oldsfp = (xfs_dir2_sf_hdr_t *)buf;
460 memcpy(oldsfp, sfp, old_isize); 533 memcpy(oldsfp, sfp, old_isize);
461 /* 534 /*
462 * Loop over the old directory finding the place we're going 535 * Loop over the old directory finding the place we're going
@@ -485,7 +558,7 @@ xfs_dir2_sf_addname_hard(
485 /* 558 /*
486 * Reset the pointer since the buffer was reallocated. 559 * Reset the pointer since the buffer was reallocated.
487 */ 560 */
488 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 561 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
489 /* 562 /*
490 * Copy the first part of the directory, including the header. 563 * Copy the first part of the directory, including the header.
491 */ 564 */
@@ -498,12 +571,11 @@ xfs_dir2_sf_addname_hard(
498 sfep->namelen = args->namelen; 571 sfep->namelen = args->namelen;
499 xfs_dir2_sf_put_offset(sfep, offset); 572 xfs_dir2_sf_put_offset(sfep, offset);
500 memcpy(sfep->name, args->name, sfep->namelen); 573 memcpy(sfep->name, args->name, sfep->namelen);
501 xfs_dir2_sf_put_inumber(sfp, &args->inumber, 574 xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber);
502 xfs_dir2_sf_inumberp(sfep)); 575 sfp->count++;
503 sfp->hdr.count++;
504#if XFS_BIG_INUMS 576#if XFS_BIG_INUMS
505 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) 577 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
506 sfp->hdr.i8count++; 578 sfp->i8count++;
507#endif 579#endif
508 /* 580 /*
509 * If there's more left to copy, do that. 581 * If there's more left to copy, do that.
@@ -537,14 +609,14 @@ xfs_dir2_sf_addname_pick(
537 xfs_mount_t *mp; /* filesystem mount point */ 609 xfs_mount_t *mp; /* filesystem mount point */
538 xfs_dir2_data_aoff_t offset; /* data block offset */ 610 xfs_dir2_data_aoff_t offset; /* data block offset */
539 xfs_dir2_sf_entry_t *sfep; /* shortform entry */ 611 xfs_dir2_sf_entry_t *sfep; /* shortform entry */
540 xfs_dir2_sf_t *sfp; /* shortform structure */ 612 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
541 int size; /* entry's data size */ 613 int size; /* entry's data size */
542 int used; /* data bytes used */ 614 int used; /* data bytes used */
543 615
544 dp = args->dp; 616 dp = args->dp;
545 mp = dp->i_mount; 617 mp = dp->i_mount;
546 618
547 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 619 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
548 size = xfs_dir2_data_entsize(args->namelen); 620 size = xfs_dir2_data_entsize(args->namelen);
549 offset = XFS_DIR2_DATA_FIRST_OFFSET; 621 offset = XFS_DIR2_DATA_FIRST_OFFSET;
550 sfep = xfs_dir2_sf_firstentry(sfp); 622 sfep = xfs_dir2_sf_firstentry(sfp);
@@ -554,7 +626,7 @@ xfs_dir2_sf_addname_pick(
554 * Keep track of data offset and whether we've seen a place 626 * Keep track of data offset and whether we've seen a place
555 * to insert the new entry. 627 * to insert the new entry.
556 */ 628 */
557 for (i = 0; i < sfp->hdr.count; i++) { 629 for (i = 0; i < sfp->count; i++) {
558 if (!holefit) 630 if (!holefit)
559 holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); 631 holefit = offset + size <= xfs_dir2_sf_get_offset(sfep);
560 offset = xfs_dir2_sf_get_offset(sfep) + 632 offset = xfs_dir2_sf_get_offset(sfep) +
@@ -566,7 +638,7 @@ xfs_dir2_sf_addname_pick(
566 * was a data block (block form directory). 638 * was a data block (block form directory).
567 */ 639 */
568 used = offset + 640 used = offset +
569 (sfp->hdr.count + 3) * (uint)sizeof(xfs_dir2_leaf_entry_t) + 641 (sfp->count + 3) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
570 (uint)sizeof(xfs_dir2_block_tail_t); 642 (uint)sizeof(xfs_dir2_block_tail_t);
571 /* 643 /*
572 * If it won't fit in a block form then we can't insert it, 644 * If it won't fit in a block form then we can't insert it,
@@ -612,30 +684,30 @@ xfs_dir2_sf_check(
612 xfs_ino_t ino; /* entry inode number */ 684 xfs_ino_t ino; /* entry inode number */
613 int offset; /* data offset */ 685 int offset; /* data offset */
614 xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */ 686 xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */
615 xfs_dir2_sf_t *sfp; /* shortform structure */ 687 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
616 688
617 dp = args->dp; 689 dp = args->dp;
618 690
619 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 691 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
620 offset = XFS_DIR2_DATA_FIRST_OFFSET; 692 offset = XFS_DIR2_DATA_FIRST_OFFSET;
621 ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); 693 ino = xfs_dir2_sf_get_parent_ino(sfp);
622 i8count = ino > XFS_DIR2_MAX_SHORT_INUM; 694 i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
623 695
624 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); 696 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
625 i < sfp->hdr.count; 697 i < sfp->count;
626 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { 698 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
627 ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); 699 ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
628 ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); 700 ino = xfs_dir2_sfe_get_ino(sfp, sfep);
629 i8count += ino > XFS_DIR2_MAX_SHORT_INUM; 701 i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
630 offset = 702 offset =
631 xfs_dir2_sf_get_offset(sfep) + 703 xfs_dir2_sf_get_offset(sfep) +
632 xfs_dir2_data_entsize(sfep->namelen); 704 xfs_dir2_data_entsize(sfep->namelen);
633 } 705 }
634 ASSERT(i8count == sfp->hdr.i8count); 706 ASSERT(i8count == sfp->i8count);
635 ASSERT(XFS_BIG_INUMS || i8count == 0); 707 ASSERT(XFS_BIG_INUMS || i8count == 0);
636 ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); 708 ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
637 ASSERT(offset + 709 ASSERT(offset +
638 (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + 710 (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
639 (uint)sizeof(xfs_dir2_block_tail_t) <= 711 (uint)sizeof(xfs_dir2_block_tail_t) <=
640 dp->i_mount->m_dirblksize); 712 dp->i_mount->m_dirblksize);
641} 713}
@@ -651,7 +723,7 @@ xfs_dir2_sf_create(
651{ 723{
652 xfs_inode_t *dp; /* incore directory inode */ 724 xfs_inode_t *dp; /* incore directory inode */
653 int i8count; /* parent inode is an 8-byte number */ 725 int i8count; /* parent inode is an 8-byte number */
654 xfs_dir2_sf_t *sfp; /* shortform structure */ 726 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
655 int size; /* directory size */ 727 int size; /* directory size */
656 728
657 trace_xfs_dir2_sf_create(args); 729 trace_xfs_dir2_sf_create(args);
@@ -681,13 +753,13 @@ xfs_dir2_sf_create(
681 /* 753 /*
682 * Fill in the header, 754 * Fill in the header,
683 */ 755 */
684 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 756 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
685 sfp->hdr.i8count = i8count; 757 sfp->i8count = i8count;
686 /* 758 /*
687 * Now can put in the inode number, since i8count is set. 759 * Now can put in the inode number, since i8count is set.
688 */ 760 */
689 xfs_dir2_sf_put_inumber(sfp, &pino, &sfp->hdr.parent); 761 xfs_dir2_sf_put_parent_ino(sfp, pino);
690 sfp->hdr.count = 0; 762 sfp->count = 0;
691 dp->i_d.di_size = size; 763 dp->i_d.di_size = size;
692 xfs_dir2_sf_check(args); 764 xfs_dir2_sf_check(args);
693 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); 765 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
@@ -705,7 +777,7 @@ xfs_dir2_sf_getdents(
705 xfs_mount_t *mp; /* filesystem mount point */ 777 xfs_mount_t *mp; /* filesystem mount point */
706 xfs_dir2_dataptr_t off; /* current entry's offset */ 778 xfs_dir2_dataptr_t off; /* current entry's offset */
707 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 779 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
708 xfs_dir2_sf_t *sfp; /* shortform structure */ 780 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
709 xfs_dir2_dataptr_t dot_offset; 781 xfs_dir2_dataptr_t dot_offset;
710 xfs_dir2_dataptr_t dotdot_offset; 782 xfs_dir2_dataptr_t dotdot_offset;
711 xfs_ino_t ino; 783 xfs_ino_t ino;
@@ -724,9 +796,9 @@ xfs_dir2_sf_getdents(
724 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 796 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
725 ASSERT(dp->i_df.if_u1.if_data != NULL); 797 ASSERT(dp->i_df.if_u1.if_data != NULL);
726 798
727 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 799 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
728 800
729 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); 801 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count));
730 802
731 /* 803 /*
732 * If the block number in the offset is out of range, we're done. 804 * If the block number in the offset is out of range, we're done.
@@ -759,7 +831,7 @@ xfs_dir2_sf_getdents(
759 * Put .. entry unless we're starting past it. 831 * Put .. entry unless we're starting past it.
760 */ 832 */
761 if (*offset <= dotdot_offset) { 833 if (*offset <= dotdot_offset) {
762 ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); 834 ino = xfs_dir2_sf_get_parent_ino(sfp);
763 if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) { 835 if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) {
764 *offset = dotdot_offset & 0x7fffffff; 836 *offset = dotdot_offset & 0x7fffffff;
765 return 0; 837 return 0;
@@ -770,7 +842,7 @@ xfs_dir2_sf_getdents(
770 * Loop while there are more entries and put'ing works. 842 * Loop while there are more entries and put'ing works.
771 */ 843 */
772 sfep = xfs_dir2_sf_firstentry(sfp); 844 sfep = xfs_dir2_sf_firstentry(sfp);
773 for (i = 0; i < sfp->hdr.count; i++) { 845 for (i = 0; i < sfp->count; i++) {
774 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 846 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
775 xfs_dir2_sf_get_offset(sfep)); 847 xfs_dir2_sf_get_offset(sfep));
776 848
@@ -779,7 +851,7 @@ xfs_dir2_sf_getdents(
779 continue; 851 continue;
780 } 852 }
781 853
782 ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); 854 ino = xfs_dir2_sfe_get_ino(sfp, sfep);
783 if (filldir(dirent, (char *)sfep->name, sfep->namelen, 855 if (filldir(dirent, (char *)sfep->name, sfep->namelen,
784 off & 0x7fffffff, ino, DT_UNKNOWN)) { 856 off & 0x7fffffff, ino, DT_UNKNOWN)) {
785 *offset = off & 0x7fffffff; 857 *offset = off & 0x7fffffff;
@@ -805,7 +877,7 @@ xfs_dir2_sf_lookup(
805 int i; /* entry index */ 877 int i; /* entry index */
806 int error; 878 int error;
807 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 879 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
808 xfs_dir2_sf_t *sfp; /* shortform structure */ 880 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
809 enum xfs_dacmp cmp; /* comparison result */ 881 enum xfs_dacmp cmp; /* comparison result */
810 xfs_dir2_sf_entry_t *ci_sfep; /* case-insens. entry */ 882 xfs_dir2_sf_entry_t *ci_sfep; /* case-insens. entry */
811 883
@@ -824,8 +896,8 @@ xfs_dir2_sf_lookup(
824 } 896 }
825 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 897 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
826 ASSERT(dp->i_df.if_u1.if_data != NULL); 898 ASSERT(dp->i_df.if_u1.if_data != NULL);
827 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 899 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
828 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); 900 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count));
829 /* 901 /*
830 * Special case for . 902 * Special case for .
831 */ 903 */
@@ -839,7 +911,7 @@ xfs_dir2_sf_lookup(
839 */ 911 */
840 if (args->namelen == 2 && 912 if (args->namelen == 2 &&
841 args->name[0] == '.' && args->name[1] == '.') { 913 args->name[0] == '.' && args->name[1] == '.') {
842 args->inumber = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); 914 args->inumber = xfs_dir2_sf_get_parent_ino(sfp);
843 args->cmpresult = XFS_CMP_EXACT; 915 args->cmpresult = XFS_CMP_EXACT;
844 return XFS_ERROR(EEXIST); 916 return XFS_ERROR(EEXIST);
845 } 917 }
@@ -847,7 +919,7 @@ xfs_dir2_sf_lookup(
847 * Loop over all the entries trying to match ours. 919 * Loop over all the entries trying to match ours.
848 */ 920 */
849 ci_sfep = NULL; 921 ci_sfep = NULL;
850 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; 922 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
851 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { 923 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
852 /* 924 /*
853 * Compare name and if it's an exact match, return the inode 925 * Compare name and if it's an exact match, return the inode
@@ -858,8 +930,7 @@ xfs_dir2_sf_lookup(
858 sfep->namelen); 930 sfep->namelen);
859 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { 931 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
860 args->cmpresult = cmp; 932 args->cmpresult = cmp;
861 args->inumber = xfs_dir2_sf_get_inumber(sfp, 933 args->inumber = xfs_dir2_sfe_get_ino(sfp, sfep);
862 xfs_dir2_sf_inumberp(sfep));
863 if (cmp == XFS_CMP_EXACT) 934 if (cmp == XFS_CMP_EXACT)
864 return XFS_ERROR(EEXIST); 935 return XFS_ERROR(EEXIST);
865 ci_sfep = sfep; 936 ci_sfep = sfep;
@@ -891,7 +962,7 @@ xfs_dir2_sf_removename(
891 int newsize; /* new inode size */ 962 int newsize; /* new inode size */
892 int oldsize; /* old inode size */ 963 int oldsize; /* old inode size */
893 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 964 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
894 xfs_dir2_sf_t *sfp; /* shortform structure */ 965 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
895 966
896 trace_xfs_dir2_sf_removename(args); 967 trace_xfs_dir2_sf_removename(args);
897 968
@@ -908,32 +979,31 @@ xfs_dir2_sf_removename(
908 } 979 }
909 ASSERT(dp->i_df.if_bytes == oldsize); 980 ASSERT(dp->i_df.if_bytes == oldsize);
910 ASSERT(dp->i_df.if_u1.if_data != NULL); 981 ASSERT(dp->i_df.if_u1.if_data != NULL);
911 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 982 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
912 ASSERT(oldsize >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); 983 ASSERT(oldsize >= xfs_dir2_sf_hdr_size(sfp->i8count));
913 /* 984 /*
914 * Loop over the old directory entries. 985 * Loop over the old directory entries.
915 * Find the one we're deleting. 986 * Find the one we're deleting.
916 */ 987 */
917 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; 988 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count;
918 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { 989 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
919 if (xfs_da_compname(args, sfep->name, sfep->namelen) == 990 if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
920 XFS_CMP_EXACT) { 991 XFS_CMP_EXACT) {
921 ASSERT(xfs_dir2_sf_get_inumber(sfp, 992 ASSERT(xfs_dir2_sfe_get_ino(sfp, sfep) ==
922 xfs_dir2_sf_inumberp(sfep)) == 993 args->inumber);
923 args->inumber);
924 break; 994 break;
925 } 995 }
926 } 996 }
927 /* 997 /*
928 * Didn't find it. 998 * Didn't find it.
929 */ 999 */
930 if (i == sfp->hdr.count) 1000 if (i == sfp->count)
931 return XFS_ERROR(ENOENT); 1001 return XFS_ERROR(ENOENT);
932 /* 1002 /*
933 * Calculate sizes. 1003 * Calculate sizes.
934 */ 1004 */
935 byteoff = (int)((char *)sfep - (char *)sfp); 1005 byteoff = (int)((char *)sfep - (char *)sfp);
936 entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); 1006 entsize = xfs_dir2_sf_entsize(sfp, args->namelen);
937 newsize = oldsize - entsize; 1007 newsize = oldsize - entsize;
938 /* 1008 /*
939 * Copy the part if any after the removed entry, sliding it down. 1009 * Copy the part if any after the removed entry, sliding it down.
@@ -944,22 +1014,22 @@ xfs_dir2_sf_removename(
944 /* 1014 /*
945 * Fix up the header and file size. 1015 * Fix up the header and file size.
946 */ 1016 */
947 sfp->hdr.count--; 1017 sfp->count--;
948 dp->i_d.di_size = newsize; 1018 dp->i_d.di_size = newsize;
949 /* 1019 /*
950 * Reallocate, making it smaller. 1020 * Reallocate, making it smaller.
951 */ 1021 */
952 xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK); 1022 xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK);
953 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1023 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
954#if XFS_BIG_INUMS 1024#if XFS_BIG_INUMS
955 /* 1025 /*
956 * Are we changing inode number size? 1026 * Are we changing inode number size?
957 */ 1027 */
958 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) { 1028 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) {
959 if (sfp->hdr.i8count == 1) 1029 if (sfp->i8count == 1)
960 xfs_dir2_sf_toino4(args); 1030 xfs_dir2_sf_toino4(args);
961 else 1031 else
962 sfp->hdr.i8count--; 1032 sfp->i8count--;
963 } 1033 }
964#endif 1034#endif
965 xfs_dir2_sf_check(args); 1035 xfs_dir2_sf_check(args);
@@ -983,7 +1053,7 @@ xfs_dir2_sf_replace(
983 int i8elevated; /* sf_toino8 set i8count=1 */ 1053 int i8elevated; /* sf_toino8 set i8count=1 */
984#endif 1054#endif
985 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 1055 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
986 xfs_dir2_sf_t *sfp; /* shortform structure */ 1056 xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
987 1057
988 trace_xfs_dir2_sf_replace(args); 1058 trace_xfs_dir2_sf_replace(args);
989 1059
@@ -999,19 +1069,19 @@ xfs_dir2_sf_replace(
999 } 1069 }
1000 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 1070 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
1001 ASSERT(dp->i_df.if_u1.if_data != NULL); 1071 ASSERT(dp->i_df.if_u1.if_data != NULL);
1002 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1072 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
1003 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); 1073 ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count));
1004#if XFS_BIG_INUMS 1074#if XFS_BIG_INUMS
1005 /* 1075 /*
1006 * New inode number is large, and need to convert to 8-byte inodes. 1076 * New inode number is large, and need to convert to 8-byte inodes.
1007 */ 1077 */
1008 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) { 1078 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) {
1009 int error; /* error return value */ 1079 int error; /* error return value */
1010 int newsize; /* new inode size */ 1080 int newsize; /* new inode size */
1011 1081
1012 newsize = 1082 newsize =
1013 dp->i_df.if_bytes + 1083 dp->i_df.if_bytes +
1014 (sfp->hdr.count + 1) * 1084 (sfp->count + 1) *
1015 ((uint)sizeof(xfs_dir2_ino8_t) - 1085 ((uint)sizeof(xfs_dir2_ino8_t) -
1016 (uint)sizeof(xfs_dir2_ino4_t)); 1086 (uint)sizeof(xfs_dir2_ino4_t));
1017 /* 1087 /*
@@ -1029,7 +1099,7 @@ xfs_dir2_sf_replace(
1029 */ 1099 */
1030 xfs_dir2_sf_toino8(args); 1100 xfs_dir2_sf_toino8(args);
1031 i8elevated = 1; 1101 i8elevated = 1;
1032 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1102 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
1033 } else 1103 } else
1034 i8elevated = 0; 1104 i8elevated = 0;
1035#endif 1105#endif
@@ -1040,34 +1110,32 @@ xfs_dir2_sf_replace(
1040 if (args->namelen == 2 && 1110 if (args->namelen == 2 &&
1041 args->name[0] == '.' && args->name[1] == '.') { 1111 args->name[0] == '.' && args->name[1] == '.') {
1042#if XFS_BIG_INUMS || defined(DEBUG) 1112#if XFS_BIG_INUMS || defined(DEBUG)
1043 ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); 1113 ino = xfs_dir2_sf_get_parent_ino(sfp);
1044 ASSERT(args->inumber != ino); 1114 ASSERT(args->inumber != ino);
1045#endif 1115#endif
1046 xfs_dir2_sf_put_inumber(sfp, &args->inumber, &sfp->hdr.parent); 1116 xfs_dir2_sf_put_parent_ino(sfp, args->inumber);
1047 } 1117 }
1048 /* 1118 /*
1049 * Normal entry, look for the name. 1119 * Normal entry, look for the name.
1050 */ 1120 */
1051 else { 1121 else {
1052 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); 1122 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
1053 i < sfp->hdr.count; 1123 i < sfp->count;
1054 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { 1124 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
1055 if (xfs_da_compname(args, sfep->name, sfep->namelen) == 1125 if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
1056 XFS_CMP_EXACT) { 1126 XFS_CMP_EXACT) {
1057#if XFS_BIG_INUMS || defined(DEBUG) 1127#if XFS_BIG_INUMS || defined(DEBUG)
1058 ino = xfs_dir2_sf_get_inumber(sfp, 1128 ino = xfs_dir2_sfe_get_ino(sfp, sfep);
1059 xfs_dir2_sf_inumberp(sfep));
1060 ASSERT(args->inumber != ino); 1129 ASSERT(args->inumber != ino);
1061#endif 1130#endif
1062 xfs_dir2_sf_put_inumber(sfp, &args->inumber, 1131 xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber);
1063 xfs_dir2_sf_inumberp(sfep));
1064 break; 1132 break;
1065 } 1133 }
1066 } 1134 }
1067 /* 1135 /*
1068 * Didn't find it. 1136 * Didn't find it.
1069 */ 1137 */
1070 if (i == sfp->hdr.count) { 1138 if (i == sfp->count) {
1071 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); 1139 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT);
1072#if XFS_BIG_INUMS 1140#if XFS_BIG_INUMS
1073 if (i8elevated) 1141 if (i8elevated)
@@ -1085,10 +1153,10 @@ xfs_dir2_sf_replace(
1085 /* 1153 /*
1086 * And the old count was one, so need to convert to small. 1154 * And the old count was one, so need to convert to small.
1087 */ 1155 */
1088 if (sfp->hdr.i8count == 1) 1156 if (sfp->i8count == 1)
1089 xfs_dir2_sf_toino4(args); 1157 xfs_dir2_sf_toino4(args);
1090 else 1158 else
1091 sfp->hdr.i8count--; 1159 sfp->i8count--;
1092 } 1160 }
1093 /* 1161 /*
1094 * See if the old number was small, the new number is large. 1162 * See if the old number was small, the new number is large.
@@ -1099,9 +1167,9 @@ xfs_dir2_sf_replace(
1099 * add to the i8count unless we just converted to 8-byte 1167 * add to the i8count unless we just converted to 8-byte
1100 * inodes (which does an implied i8count = 1) 1168 * inodes (which does an implied i8count = 1)
1101 */ 1169 */
1102 ASSERT(sfp->hdr.i8count != 0); 1170 ASSERT(sfp->i8count != 0);
1103 if (!i8elevated) 1171 if (!i8elevated)
1104 sfp->hdr.i8count++; 1172 sfp->i8count++;
1105 } 1173 }
1106#endif 1174#endif
1107 xfs_dir2_sf_check(args); 1175 xfs_dir2_sf_check(args);
@@ -1121,13 +1189,12 @@ xfs_dir2_sf_toino4(
1121 char *buf; /* old dir's buffer */ 1189 char *buf; /* old dir's buffer */
1122 xfs_inode_t *dp; /* incore directory inode */ 1190 xfs_inode_t *dp; /* incore directory inode */
1123 int i; /* entry index */ 1191 int i; /* entry index */
1124 xfs_ino_t ino; /* entry inode number */
1125 int newsize; /* new inode size */ 1192 int newsize; /* new inode size */
1126 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ 1193 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */
1127 xfs_dir2_sf_t *oldsfp; /* old sf directory */ 1194 xfs_dir2_sf_hdr_t *oldsfp; /* old sf directory */
1128 int oldsize; /* old inode size */ 1195 int oldsize; /* old inode size */
1129 xfs_dir2_sf_entry_t *sfep; /* new sf entry */ 1196 xfs_dir2_sf_entry_t *sfep; /* new sf entry */
1130 xfs_dir2_sf_t *sfp; /* new sf directory */ 1197 xfs_dir2_sf_hdr_t *sfp; /* new sf directory */
1131 1198
1132 trace_xfs_dir2_sf_toino4(args); 1199 trace_xfs_dir2_sf_toino4(args);
1133 1200
@@ -1140,44 +1207,42 @@ xfs_dir2_sf_toino4(
1140 */ 1207 */
1141 oldsize = dp->i_df.if_bytes; 1208 oldsize = dp->i_df.if_bytes;
1142 buf = kmem_alloc(oldsize, KM_SLEEP); 1209 buf = kmem_alloc(oldsize, KM_SLEEP);
1143 oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1210 oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
1144 ASSERT(oldsfp->hdr.i8count == 1); 1211 ASSERT(oldsfp->i8count == 1);
1145 memcpy(buf, oldsfp, oldsize); 1212 memcpy(buf, oldsfp, oldsize);
1146 /* 1213 /*
1147 * Compute the new inode size. 1214 * Compute the new inode size.
1148 */ 1215 */
1149 newsize = 1216 newsize =
1150 oldsize - 1217 oldsize -
1151 (oldsfp->hdr.count + 1) * 1218 (oldsfp->count + 1) *
1152 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); 1219 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t));
1153 xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); 1220 xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK);
1154 xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); 1221 xfs_idata_realloc(dp, newsize, XFS_DATA_FORK);
1155 /* 1222 /*
1156 * Reset our pointers, the data has moved. 1223 * Reset our pointers, the data has moved.
1157 */ 1224 */
1158 oldsfp = (xfs_dir2_sf_t *)buf; 1225 oldsfp = (xfs_dir2_sf_hdr_t *)buf;
1159 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1226 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
1160 /* 1227 /*
1161 * Fill in the new header. 1228 * Fill in the new header.
1162 */ 1229 */
1163 sfp->hdr.count = oldsfp->hdr.count; 1230 sfp->count = oldsfp->count;
1164 sfp->hdr.i8count = 0; 1231 sfp->i8count = 0;
1165 ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); 1232 xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
1166 xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent);
1167 /* 1233 /*
1168 * Copy the entries field by field. 1234 * Copy the entries field by field.
1169 */ 1235 */
1170 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), 1236 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
1171 oldsfep = xfs_dir2_sf_firstentry(oldsfp); 1237 oldsfep = xfs_dir2_sf_firstentry(oldsfp);
1172 i < sfp->hdr.count; 1238 i < sfp->count;
1173 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), 1239 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep),
1174 oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { 1240 oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) {
1175 sfep->namelen = oldsfep->namelen; 1241 sfep->namelen = oldsfep->namelen;
1176 sfep->offset = oldsfep->offset; 1242 sfep->offset = oldsfep->offset;
1177 memcpy(sfep->name, oldsfep->name, sfep->namelen); 1243 memcpy(sfep->name, oldsfep->name, sfep->namelen);
1178 ino = xfs_dir2_sf_get_inumber(oldsfp, 1244 xfs_dir2_sfe_put_ino(sfp, sfep,
1179 xfs_dir2_sf_inumberp(oldsfep)); 1245 xfs_dir2_sfe_get_ino(oldsfp, oldsfep));
1180 xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep));
1181 } 1246 }
1182 /* 1247 /*
1183 * Clean up the inode. 1248 * Clean up the inode.
@@ -1199,13 +1264,12 @@ xfs_dir2_sf_toino8(
1199 char *buf; /* old dir's buffer */ 1264 char *buf; /* old dir's buffer */
1200 xfs_inode_t *dp; /* incore directory inode */ 1265 xfs_inode_t *dp; /* incore directory inode */
1201 int i; /* entry index */ 1266 int i; /* entry index */
1202 xfs_ino_t ino; /* entry inode number */
1203 int newsize; /* new inode size */ 1267 int newsize; /* new inode size */
1204 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ 1268 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */
1205 xfs_dir2_sf_t *oldsfp; /* old sf directory */ 1269 xfs_dir2_sf_hdr_t *oldsfp; /* old sf directory */
1206 int oldsize; /* old inode size */ 1270 int oldsize; /* old inode size */
1207 xfs_dir2_sf_entry_t *sfep; /* new sf entry */ 1271 xfs_dir2_sf_entry_t *sfep; /* new sf entry */
1208 xfs_dir2_sf_t *sfp; /* new sf directory */ 1272 xfs_dir2_sf_hdr_t *sfp; /* new sf directory */
1209 1273
1210 trace_xfs_dir2_sf_toino8(args); 1274 trace_xfs_dir2_sf_toino8(args);
1211 1275
@@ -1218,44 +1282,42 @@ xfs_dir2_sf_toino8(
1218 */ 1282 */
1219 oldsize = dp->i_df.if_bytes; 1283 oldsize = dp->i_df.if_bytes;
1220 buf = kmem_alloc(oldsize, KM_SLEEP); 1284 buf = kmem_alloc(oldsize, KM_SLEEP);
1221 oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1285 oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
1222 ASSERT(oldsfp->hdr.i8count == 0); 1286 ASSERT(oldsfp->i8count == 0);
1223 memcpy(buf, oldsfp, oldsize); 1287 memcpy(buf, oldsfp, oldsize);
1224 /* 1288 /*
1225 * Compute the new inode size. 1289 * Compute the new inode size.
1226 */ 1290 */
1227 newsize = 1291 newsize =
1228 oldsize + 1292 oldsize +
1229 (oldsfp->hdr.count + 1) * 1293 (oldsfp->count + 1) *
1230 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); 1294 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t));
1231 xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); 1295 xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK);
1232 xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); 1296 xfs_idata_realloc(dp, newsize, XFS_DATA_FORK);
1233 /* 1297 /*
1234 * Reset our pointers, the data has moved. 1298 * Reset our pointers, the data has moved.
1235 */ 1299 */
1236 oldsfp = (xfs_dir2_sf_t *)buf; 1300 oldsfp = (xfs_dir2_sf_hdr_t *)buf;
1237 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 1301 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
1238 /* 1302 /*
1239 * Fill in the new header. 1303 * Fill in the new header.
1240 */ 1304 */
1241 sfp->hdr.count = oldsfp->hdr.count; 1305 sfp->count = oldsfp->count;
1242 sfp->hdr.i8count = 1; 1306 sfp->i8count = 1;
1243 ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); 1307 xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
1244 xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent);
1245 /* 1308 /*
1246 * Copy the entries field by field. 1309 * Copy the entries field by field.
1247 */ 1310 */
1248 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), 1311 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp),
1249 oldsfep = xfs_dir2_sf_firstentry(oldsfp); 1312 oldsfep = xfs_dir2_sf_firstentry(oldsfp);
1250 i < sfp->hdr.count; 1313 i < sfp->count;
1251 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), 1314 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep),
1252 oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { 1315 oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) {
1253 sfep->namelen = oldsfep->namelen; 1316 sfep->namelen = oldsfep->namelen;
1254 sfep->offset = oldsfep->offset; 1317 sfep->offset = oldsfep->offset;
1255 memcpy(sfep->name, oldsfep->name, sfep->namelen); 1318 memcpy(sfep->name, oldsfep->name, sfep->namelen);
1256 ino = xfs_dir2_sf_get_inumber(oldsfp, 1319 xfs_dir2_sfe_put_ino(sfp, sfep,
1257 xfs_dir2_sf_inumberp(oldsfep)); 1320 xfs_dir2_sfe_get_ino(oldsfp, oldsfep));
1258 xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep));
1259 } 1321 }
1260 /* 1322 /*
1261 * Clean up the inode. 1323 * Clean up the inode.
diff --git a/fs/xfs/xfs_dir2_sf.h b/fs/xfs/xfs_dir2_sf.h
deleted file mode 100644
index 6ac44b550d3..00000000000
--- a/fs/xfs/xfs_dir2_sf.h
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR2_SF_H__
19#define __XFS_DIR2_SF_H__
20
21/*
22 * Directory layout when stored internal to an inode.
23 *
24 * Small directories are packed as tightly as possible so as to
25 * fit into the literal area of the inode.
26 */
27
28struct uio;
29struct xfs_dabuf;
30struct xfs_da_args;
31struct xfs_dir2_block;
32struct xfs_inode;
33struct xfs_mount;
34struct xfs_trans;
35
36/*
37 * Inode number stored as 8 8-bit values.
38 */
39typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
40
41/*
42 * Inode number stored as 4 8-bit values.
43 * Works a lot of the time, when all the inode numbers in a directory
44 * fit in 32 bits.
45 */
46typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
47
48typedef union {
49 xfs_dir2_ino8_t i8;
50 xfs_dir2_ino4_t i4;
51} xfs_dir2_inou_t;
52#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
53
54/*
55 * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
56 * Only need 16 bits, this is the byte offset into the single block form.
57 */
58typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
59
60/*
61 * The parent directory has a dedicated field, and the self-pointer must
62 * be calculated on the fly.
63 *
64 * Entries are packed toward the top as tightly as possible. The header
65 * and the elements must be memcpy'd out into a work area to get correct
66 * alignment for the inode number fields.
67 */
68typedef struct xfs_dir2_sf_hdr {
69 __uint8_t count; /* count of entries */
70 __uint8_t i8count; /* count of 8-byte inode #s */
71 xfs_dir2_inou_t parent; /* parent dir inode number */
72} __arch_pack xfs_dir2_sf_hdr_t;
73
74typedef struct xfs_dir2_sf_entry {
75 __uint8_t namelen; /* actual name length */
76 xfs_dir2_sf_off_t offset; /* saved offset */
77 __uint8_t name[1]; /* name, variable size */
78 xfs_dir2_inou_t inumber; /* inode number, var. offset */
79} __arch_pack xfs_dir2_sf_entry_t;
80
81typedef struct xfs_dir2_sf {
82 xfs_dir2_sf_hdr_t hdr; /* shortform header */
83 xfs_dir2_sf_entry_t list[1]; /* shortform entries */
84} xfs_dir2_sf_t;
85
86static inline int xfs_dir2_sf_hdr_size(int i8count)
87{
88 return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \
89 ((i8count) == 0) * \
90 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
91}
92
93static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep)
94{
95 return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen];
96}
97
98static inline xfs_intino_t
99xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from)
100{
101 return ((sfp)->hdr.i8count == 0 ? \
102 (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \
103 (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8));
104}
105
106static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from,
107 xfs_dir2_inou_t *to)
108{
109 if ((sfp)->hdr.i8count == 0)
110 XFS_PUT_DIR_INO4(*(from), (to)->i4);
111 else
112 XFS_PUT_DIR_INO8(*(from), (to)->i8);
113}
114
115static inline xfs_dir2_data_aoff_t
116xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
117{
118 return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i);
119}
120
121static inline void
122xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
123{
124 INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off);
125}
126
127static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len)
128{
129 return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \
130 ((sfp)->hdr.i8count == 0) * \
131 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
132}
133
134static inline int
135xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep)
136{
137 return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \
138 ((sfp)->hdr.i8count == 0) * \
139 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)));
140}
141
142static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp)
143{
144 return ((xfs_dir2_sf_entry_t *) \
145 ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->hdr.i8count)));
146}
147
148static inline xfs_dir2_sf_entry_t *
149xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep)
150{
151 return ((xfs_dir2_sf_entry_t *) \
152 ((char *)(sfep) + xfs_dir2_sf_entsize_byentry(sfp,sfep)));
153}
154
155/*
156 * Functions.
157 */
158extern int xfs_dir2_block_sfsize(struct xfs_inode *dp,
159 struct xfs_dir2_block *block,
160 xfs_dir2_sf_hdr_t *sfhp);
161extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
162 int size, xfs_dir2_sf_hdr_t *sfhp);
163extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
164extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
165extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
166 xfs_off_t *offset, filldir_t filldir);
167extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
168extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
169extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
170
171#endif /* __XFS_DIR2_SF_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_discard.c b/fs/xfs/xfs_discard.c
index 244e797dae3..572494faf26 100644
--- a/fs/xfs/linux-2.6/xfs_discard.c
+++ b/fs/xfs/xfs_discard.c
@@ -68,7 +68,7 @@ xfs_trim_extents(
68 * Look up the longest btree in the AGF and start with it. 68 * Look up the longest btree in the AGF and start with it.
69 */ 69 */
70 error = xfs_alloc_lookup_le(cur, 0, 70 error = xfs_alloc_lookup_le(cur, 0,
71 XFS_BUF_TO_AGF(agbp)->agf_longest, &i); 71 be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_longest), &i);
72 if (error) 72 if (error)
73 goto out_del_cursor; 73 goto out_del_cursor;
74 74
@@ -84,7 +84,7 @@ xfs_trim_extents(
84 if (error) 84 if (error)
85 goto out_del_cursor; 85 goto out_del_cursor;
86 XFS_WANT_CORRUPTED_GOTO(i == 1, out_del_cursor); 86 XFS_WANT_CORRUPTED_GOTO(i == 1, out_del_cursor);
87 ASSERT(flen <= XFS_BUF_TO_AGF(agbp)->agf_longest); 87 ASSERT(flen <= be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_longest));
88 88
89 /* 89 /*
90 * Too small? Give up. 90 * Too small? Give up.
diff --git a/fs/xfs/linux-2.6/xfs_discard.h b/fs/xfs/xfs_discard.h
index 344879aea64..344879aea64 100644
--- a/fs/xfs/linux-2.6/xfs_discard.h
+++ b/fs/xfs/xfs_discard.h
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 6fa21460381..db62959bed1 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -220,7 +220,7 @@ xfs_qm_adjust_dqtimers(
220{ 220{
221 ASSERT(d->d_id); 221 ASSERT(d->d_id);
222 222
223#ifdef QUOTADEBUG 223#ifdef DEBUG
224 if (d->d_blk_hardlimit) 224 if (d->d_blk_hardlimit)
225 ASSERT(be64_to_cpu(d->d_blk_softlimit) <= 225 ASSERT(be64_to_cpu(d->d_blk_softlimit) <=
226 be64_to_cpu(d->d_blk_hardlimit)); 226 be64_to_cpu(d->d_blk_hardlimit));
@@ -231,6 +231,7 @@ xfs_qm_adjust_dqtimers(
231 ASSERT(be64_to_cpu(d->d_rtb_softlimit) <= 231 ASSERT(be64_to_cpu(d->d_rtb_softlimit) <=
232 be64_to_cpu(d->d_rtb_hardlimit)); 232 be64_to_cpu(d->d_rtb_hardlimit));
233#endif 233#endif
234
234 if (!d->d_btimer) { 235 if (!d->d_btimer) {
235 if ((d->d_blk_softlimit && 236 if ((d->d_blk_softlimit &&
236 (be64_to_cpu(d->d_bcount) >= 237 (be64_to_cpu(d->d_bcount) >=
@@ -317,10 +318,9 @@ xfs_qm_init_dquot_blk(
317 int curid, i; 318 int curid, i;
318 319
319 ASSERT(tp); 320 ASSERT(tp);
320 ASSERT(XFS_BUF_ISBUSY(bp)); 321 ASSERT(xfs_buf_islocked(bp));
321 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
322 322
323 d = (xfs_dqblk_t *)XFS_BUF_PTR(bp); 323 d = bp->b_addr;
324 324
325 /* 325 /*
326 * ID of the first dquot in the block - id's are zero based. 326 * ID of the first dquot in the block - id's are zero based.
@@ -402,7 +402,7 @@ xfs_qm_dqalloc(
402 dqp->q_blkno, 402 dqp->q_blkno,
403 mp->m_quotainfo->qi_dqchunklen, 403 mp->m_quotainfo->qi_dqchunklen,
404 0); 404 0);
405 if (!bp || (error = XFS_BUF_GETERROR(bp))) 405 if (!bp || (error = xfs_buf_geterror(bp)))
406 goto error1; 406 goto error1;
407 /* 407 /*
408 * Make a chunk of dquots out of this buffer and log 408 * Make a chunk of dquots out of this buffer and log
@@ -533,13 +533,12 @@ xfs_qm_dqtobp(
533 return XFS_ERROR(error); 533 return XFS_ERROR(error);
534 } 534 }
535 535
536 ASSERT(XFS_BUF_ISBUSY(bp)); 536 ASSERT(xfs_buf_islocked(bp));
537 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
538 537
539 /* 538 /*
540 * calculate the location of the dquot inside the buffer. 539 * calculate the location of the dquot inside the buffer.
541 */ 540 */
542 ddq = (struct xfs_disk_dquot *)(XFS_BUF_PTR(bp) + dqp->q_bufoffset); 541 ddq = bp->b_addr + dqp->q_bufoffset;
543 542
544 /* 543 /*
545 * A simple sanity check in case we got a corrupted dquot... 544 * A simple sanity check in case we got a corrupted dquot...
@@ -552,7 +551,6 @@ xfs_qm_dqtobp(
552 xfs_trans_brelse(tp, bp); 551 xfs_trans_brelse(tp, bp);
553 return XFS_ERROR(EIO); 552 return XFS_ERROR(EIO);
554 } 553 }
555 XFS_BUF_BUSY(bp); /* We dirtied this */
556 } 554 }
557 555
558 *O_bpp = bp; 556 *O_bpp = bp;
@@ -621,8 +619,7 @@ xfs_qm_dqread(
621 * this particular dquot was repaired. We still aren't afraid to 619 * this particular dquot was repaired. We still aren't afraid to
622 * brelse it because we have the changes incore. 620 * brelse it because we have the changes incore.
623 */ 621 */
624 ASSERT(XFS_BUF_ISBUSY(bp)); 622 ASSERT(xfs_buf_islocked(bp));
625 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
626 xfs_trans_brelse(tp, bp); 623 xfs_trans_brelse(tp, bp);
627 624
628 return (error); 625 return (error);
@@ -1203,7 +1200,7 @@ xfs_qm_dqflush(
1203 /* 1200 /*
1204 * Calculate the location of the dquot inside the buffer. 1201 * Calculate the location of the dquot inside the buffer.
1205 */ 1202 */
1206 ddqp = (struct xfs_disk_dquot *)(XFS_BUF_PTR(bp) + dqp->q_bufoffset); 1203 ddqp = bp->b_addr + dqp->q_bufoffset;
1207 1204
1208 /* 1205 /*
1209 * A simple sanity check in case we got a corrupted dquot.. 1206 * A simple sanity check in case we got a corrupted dquot..
@@ -1239,7 +1236,7 @@ xfs_qm_dqflush(
1239 * If the buffer is pinned then push on the log so we won't 1236 * If the buffer is pinned then push on the log so we won't
1240 * get stuck waiting in the write for too long. 1237 * get stuck waiting in the write for too long.
1241 */ 1238 */
1242 if (XFS_BUF_ISPINNED(bp)) { 1239 if (xfs_buf_ispinned(bp)) {
1243 trace_xfs_dqflush_force(dqp); 1240 trace_xfs_dqflush_force(dqp);
1244 xfs_log_force(mp, 0); 1241 xfs_log_force(mp, 0);
1245 } 1242 }
@@ -1423,45 +1420,6 @@ xfs_qm_dqpurge(
1423} 1420}
1424 1421
1425 1422
1426#ifdef QUOTADEBUG
1427void
1428xfs_qm_dqprint(xfs_dquot_t *dqp)
1429{
1430 struct xfs_mount *mp = dqp->q_mount;
1431
1432 xfs_debug(mp, "-----------KERNEL DQUOT----------------");
1433 xfs_debug(mp, "---- dquotID = %d",
1434 (int)be32_to_cpu(dqp->q_core.d_id));
1435 xfs_debug(mp, "---- type = %s", DQFLAGTO_TYPESTR(dqp));
1436 xfs_debug(mp, "---- fs = 0x%p", dqp->q_mount);
1437 xfs_debug(mp, "---- blkno = 0x%x", (int) dqp->q_blkno);
1438 xfs_debug(mp, "---- boffset = 0x%x", (int) dqp->q_bufoffset);
1439 xfs_debug(mp, "---- blkhlimit = %Lu (0x%x)",
1440 be64_to_cpu(dqp->q_core.d_blk_hardlimit),
1441 (int)be64_to_cpu(dqp->q_core.d_blk_hardlimit));
1442 xfs_debug(mp, "---- blkslimit = %Lu (0x%x)",
1443 be64_to_cpu(dqp->q_core.d_blk_softlimit),
1444 (int)be64_to_cpu(dqp->q_core.d_blk_softlimit));
1445 xfs_debug(mp, "---- inohlimit = %Lu (0x%x)",
1446 be64_to_cpu(dqp->q_core.d_ino_hardlimit),
1447 (int)be64_to_cpu(dqp->q_core.d_ino_hardlimit));
1448 xfs_debug(mp, "---- inoslimit = %Lu (0x%x)",
1449 be64_to_cpu(dqp->q_core.d_ino_softlimit),
1450 (int)be64_to_cpu(dqp->q_core.d_ino_softlimit));
1451 xfs_debug(mp, "---- bcount = %Lu (0x%x)",
1452 be64_to_cpu(dqp->q_core.d_bcount),
1453 (int)be64_to_cpu(dqp->q_core.d_bcount));
1454 xfs_debug(mp, "---- icount = %Lu (0x%x)",
1455 be64_to_cpu(dqp->q_core.d_icount),
1456 (int)be64_to_cpu(dqp->q_core.d_icount));
1457 xfs_debug(mp, "---- btimer = %d",
1458 (int)be32_to_cpu(dqp->q_core.d_btimer));
1459 xfs_debug(mp, "---- itimer = %d",
1460 (int)be32_to_cpu(dqp->q_core.d_itimer));
1461 xfs_debug(mp, "---------------------------");
1462}
1463#endif
1464
1465/* 1423/*
1466 * Give the buffer a little push if it is incore and 1424 * Give the buffer a little push if it is incore and
1467 * wait on the flush lock. 1425 * wait on the flush lock.
@@ -1485,7 +1443,7 @@ xfs_qm_dqflock_pushbuf_wait(
1485 goto out_lock; 1443 goto out_lock;
1486 1444
1487 if (XFS_BUF_ISDELAYWRITE(bp)) { 1445 if (XFS_BUF_ISDELAYWRITE(bp)) {
1488 if (XFS_BUF_ISPINNED(bp)) 1446 if (xfs_buf_ispinned(bp))
1489 xfs_log_force(mp, 0); 1447 xfs_log_force(mp, 0);
1490 xfs_buf_delwri_promote(bp); 1448 xfs_buf_delwri_promote(bp);
1491 wake_up_process(bp->b_target->bt_task); 1449 wake_up_process(bp->b_target->bt_task);
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 5da3a23b820..34b7e945dbf 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -116,12 +116,6 @@ static inline void xfs_dqfunlock(xfs_dquot_t *dqp)
116 (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ 116 (XFS_IS_UQUOTA_ON((d)->q_mount)) : \
117 (XFS_IS_OQUOTA_ON((d)->q_mount)))) 117 (XFS_IS_OQUOTA_ON((d)->q_mount))))
118 118
119#ifdef QUOTADEBUG
120extern void xfs_qm_dqprint(xfs_dquot_t *);
121#else
122#define xfs_qm_dqprint(a)
123#endif
124
125extern void xfs_qm_dqdestroy(xfs_dquot_t *); 119extern void xfs_qm_dqdestroy(xfs_dquot_t *);
126extern int xfs_qm_dqflush(xfs_dquot_t *, uint); 120extern int xfs_qm_dqflush(xfs_dquot_t *, uint);
127extern int xfs_qm_dqpurge(xfs_dquot_t *); 121extern int xfs_qm_dqpurge(xfs_dquot_t *);
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
index 9e0e2fa3f2c..bb3f71d236d 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/xfs_dquot_item.c
@@ -183,13 +183,14 @@ xfs_qm_dqunpin_wait(
183 * search the buffer cache can be a time consuming thing, and AIL lock is a 183 * search the buffer cache can be a time consuming thing, and AIL lock is a
184 * spinlock. 184 * spinlock.
185 */ 185 */
186STATIC void 186STATIC bool
187xfs_qm_dquot_logitem_pushbuf( 187xfs_qm_dquot_logitem_pushbuf(
188 struct xfs_log_item *lip) 188 struct xfs_log_item *lip)
189{ 189{
190 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); 190 struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
191 struct xfs_dquot *dqp = qlip->qli_dquot; 191 struct xfs_dquot *dqp = qlip->qli_dquot;
192 struct xfs_buf *bp; 192 struct xfs_buf *bp;
193 bool ret = true;
193 194
194 ASSERT(XFS_DQ_IS_LOCKED(dqp)); 195 ASSERT(XFS_DQ_IS_LOCKED(dqp));
195 196
@@ -201,17 +202,20 @@ xfs_qm_dquot_logitem_pushbuf(
201 if (completion_done(&dqp->q_flush) || 202 if (completion_done(&dqp->q_flush) ||
202 !(lip->li_flags & XFS_LI_IN_AIL)) { 203 !(lip->li_flags & XFS_LI_IN_AIL)) {
203 xfs_dqunlock(dqp); 204 xfs_dqunlock(dqp);
204 return; 205 return true;
205 } 206 }
206 207
207 bp = xfs_incore(dqp->q_mount->m_ddev_targp, qlip->qli_format.qlf_blkno, 208 bp = xfs_incore(dqp->q_mount->m_ddev_targp, qlip->qli_format.qlf_blkno,
208 dqp->q_mount->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK); 209 dqp->q_mount->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK);
209 xfs_dqunlock(dqp); 210 xfs_dqunlock(dqp);
210 if (!bp) 211 if (!bp)
211 return; 212 return true;
212 if (XFS_BUF_ISDELAYWRITE(bp)) 213 if (XFS_BUF_ISDELAYWRITE(bp))
213 xfs_buf_delwri_promote(bp); 214 xfs_buf_delwri_promote(bp);
215 if (xfs_buf_ispinned(bp))
216 ret = false;
214 xfs_buf_relse(bp); 217 xfs_buf_relse(bp);
218 return ret;
215} 219}
216 220
217/* 221/*
diff --git a/fs/xfs/quota/xfs_dquot_item.h b/fs/xfs/xfs_dquot_item.h
index 5acae2ada70..5acae2ada70 100644
--- a/fs/xfs/quota/xfs_dquot_item.h
+++ b/fs/xfs/xfs_dquot_item.h
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/xfs_export.c
index f4f878fc008..75e5d322e48 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -151,14 +151,14 @@ xfs_nfs_get_inode(
151 * We don't use ESTALE directly down the chain to not 151 * We don't use ESTALE directly down the chain to not
152 * confuse applications using bulkstat that expect EINVAL. 152 * confuse applications using bulkstat that expect EINVAL.
153 */ 153 */
154 if (error == EINVAL) 154 if (error == EINVAL || error == ENOENT)
155 error = ESTALE; 155 error = ESTALE;
156 return ERR_PTR(-error); 156 return ERR_PTR(-error);
157 } 157 }
158 158
159 if (ip->i_d.di_gen != generation) { 159 if (ip->i_d.di_gen != generation) {
160 IRELE(ip); 160 IRELE(ip);
161 return ERR_PTR(-ENOENT); 161 return ERR_PTR(-ESTALE);
162 } 162 }
163 163
164 return VFS_I(ip); 164 return VFS_I(ip);
diff --git a/fs/xfs/linux-2.6/xfs_export.h b/fs/xfs/xfs_export.h
index 3272b6ae7a3..3272b6ae7a3 100644
--- a/fs/xfs/linux-2.6/xfs_export.h
+++ b/fs/xfs/xfs_export.h
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/xfs_file.c
index 7f782af286b..b7e75c6ba09 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -127,6 +127,8 @@ xfs_iozero(
127STATIC int 127STATIC int
128xfs_file_fsync( 128xfs_file_fsync(
129 struct file *file, 129 struct file *file,
130 loff_t start,
131 loff_t end,
130 int datasync) 132 int datasync)
131{ 133{
132 struct inode *inode = file->f_mapping->host; 134 struct inode *inode = file->f_mapping->host;
@@ -138,12 +140,18 @@ xfs_file_fsync(
138 140
139 trace_xfs_file_fsync(ip); 141 trace_xfs_file_fsync(ip);
140 142
143 error = filemap_write_and_wait_range(inode->i_mapping, start, end);
144 if (error)
145 return error;
146
141 if (XFS_FORCED_SHUTDOWN(mp)) 147 if (XFS_FORCED_SHUTDOWN(mp))
142 return -XFS_ERROR(EIO); 148 return -XFS_ERROR(EIO);
143 149
144 xfs_iflags_clear(ip, XFS_ITRUNCATED); 150 xfs_iflags_clear(ip, XFS_ITRUNCATED);
145 151
152 xfs_ilock(ip, XFS_IOLOCK_SHARED);
146 xfs_ioend_wait(ip); 153 xfs_ioend_wait(ip);
154 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
147 155
148 if (mp->m_flags & XFS_MOUNT_BARRIER) { 156 if (mp->m_flags & XFS_MOUNT_BARRIER) {
149 /* 157 /*
@@ -309,7 +317,19 @@ xfs_file_aio_read(
309 if (XFS_FORCED_SHUTDOWN(mp)) 317 if (XFS_FORCED_SHUTDOWN(mp))
310 return -EIO; 318 return -EIO;
311 319
312 if (unlikely(ioflags & IO_ISDIRECT)) { 320 /*
321 * Locking is a bit tricky here. If we take an exclusive lock
322 * for direct IO, we effectively serialise all new concurrent
323 * read IO to this file and block it behind IO that is currently in
324 * progress because IO in progress holds the IO lock shared. We only
325 * need to hold the lock exclusive to blow away the page cache, so
326 * only take lock exclusively if the page cache needs invalidation.
327 * This allows the normal direct IO case of no page cache pages to
328 * proceeed concurrently without serialisation.
329 */
330 xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
331 if ((ioflags & IO_ISDIRECT) && inode->i_mapping->nrpages) {
332 xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
313 xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); 333 xfs_rw_ilock(ip, XFS_IOLOCK_EXCL);
314 334
315 if (inode->i_mapping->nrpages) { 335 if (inode->i_mapping->nrpages) {
@@ -322,8 +342,7 @@ xfs_file_aio_read(
322 } 342 }
323 } 343 }
324 xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL); 344 xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL);
325 } else 345 }
326 xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
327 346
328 trace_xfs_file_read(ip, size, iocb->ki_pos, ioflags); 347 trace_xfs_file_read(ip, size, iocb->ki_pos, ioflags);
329 348
@@ -658,6 +677,7 @@ xfs_file_aio_write_checks(
658 xfs_fsize_t new_size; 677 xfs_fsize_t new_size;
659 int error = 0; 678 int error = 0;
660 679
680 xfs_rw_ilock(ip, XFS_ILOCK_EXCL);
661 error = generic_write_checks(file, pos, count, S_ISBLK(inode->i_mode)); 681 error = generic_write_checks(file, pos, count, S_ISBLK(inode->i_mode));
662 if (error) { 682 if (error) {
663 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL | *iolock); 683 xfs_rw_iunlock(ip, XFS_ILOCK_EXCL | *iolock);
@@ -749,14 +769,24 @@ xfs_file_dio_aio_write(
749 *iolock = XFS_IOLOCK_EXCL; 769 *iolock = XFS_IOLOCK_EXCL;
750 else 770 else
751 *iolock = XFS_IOLOCK_SHARED; 771 *iolock = XFS_IOLOCK_SHARED;
752 xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock); 772 xfs_rw_ilock(ip, *iolock);
753 773
754 ret = xfs_file_aio_write_checks(file, &pos, &count, iolock); 774 ret = xfs_file_aio_write_checks(file, &pos, &count, iolock);
755 if (ret) 775 if (ret)
756 return ret; 776 return ret;
757 777
778 /*
779 * Recheck if there are cached pages that need invalidate after we got
780 * the iolock to protect against other threads adding new pages while
781 * we were waiting for the iolock.
782 */
783 if (mapping->nrpages && *iolock == XFS_IOLOCK_SHARED) {
784 xfs_rw_iunlock(ip, *iolock);
785 *iolock = XFS_IOLOCK_EXCL;
786 xfs_rw_ilock(ip, *iolock);
787 }
788
758 if (mapping->nrpages) { 789 if (mapping->nrpages) {
759 WARN_ON(*iolock != XFS_IOLOCK_EXCL);
760 ret = -xfs_flushinval_pages(ip, (pos & PAGE_CACHE_MASK), -1, 790 ret = -xfs_flushinval_pages(ip, (pos & PAGE_CACHE_MASK), -1,
761 FI_REMAPF_LOCKED); 791 FI_REMAPF_LOCKED);
762 if (ret) 792 if (ret)
@@ -801,7 +831,7 @@ xfs_file_buffered_aio_write(
801 size_t count = ocount; 831 size_t count = ocount;
802 832
803 *iolock = XFS_IOLOCK_EXCL; 833 *iolock = XFS_IOLOCK_EXCL;
804 xfs_rw_ilock(ip, XFS_ILOCK_EXCL | *iolock); 834 xfs_rw_ilock(ip, *iolock);
805 835
806 ret = xfs_file_aio_write_checks(file, &pos, &count, iolock); 836 ret = xfs_file_aio_write_checks(file, &pos, &count, iolock);
807 if (ret) 837 if (ret)
@@ -875,18 +905,14 @@ xfs_file_aio_write(
875 /* Handle various SYNC-type writes */ 905 /* Handle various SYNC-type writes */
876 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { 906 if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
877 loff_t end = pos + ret - 1; 907 loff_t end = pos + ret - 1;
878 int error, error2; 908 int error;
879 909
880 xfs_rw_iunlock(ip, iolock); 910 xfs_rw_iunlock(ip, iolock);
881 error = filemap_write_and_wait_range(mapping, pos, end); 911 error = xfs_file_fsync(file, pos, end,
912 (file->f_flags & __O_SYNC) ? 0 : 1);
882 xfs_rw_ilock(ip, iolock); 913 xfs_rw_ilock(ip, iolock);
883
884 error2 = -xfs_file_fsync(file,
885 (file->f_flags & __O_SYNC) ? 0 : 1);
886 if (error) 914 if (error)
887 ret = error; 915 ret = error;
888 else if (error2)
889 ret = error2;
890 } 916 }
891 917
892out_unlock: 918out_unlock:
@@ -944,7 +970,7 @@ xfs_file_fallocate(
944 970
945 iattr.ia_valid = ATTR_SIZE; 971 iattr.ia_valid = ATTR_SIZE;
946 iattr.ia_size = new_size; 972 iattr.ia_size = new_size;
947 error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK); 973 error = -xfs_setattr_size(ip, &iattr, XFS_ATTR_NOLOCK);
948 } 974 }
949 975
950out_unlock: 976out_unlock:
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index 9124425b7f2..3ff3d9e23de 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -344,9 +344,9 @@ _xfs_filestream_update_ag(
344 * Either ip is a regular file and pip is a directory, or ip is a 344 * Either ip is a regular file and pip is a directory, or ip is a
345 * directory and pip is NULL. 345 * directory and pip is NULL.
346 */ 346 */
347 ASSERT(ip && (((ip->i_d.di_mode & S_IFREG) && pip && 347 ASSERT(ip && ((S_ISREG(ip->i_d.di_mode) && pip &&
348 (pip->i_d.di_mode & S_IFDIR)) || 348 S_ISDIR(pip->i_d.di_mode)) ||
349 ((ip->i_d.di_mode & S_IFDIR) && !pip))); 349 (S_ISDIR(ip->i_d.di_mode) && !pip)));
350 350
351 mp = ip->i_mount; 351 mp = ip->i_mount;
352 cache = mp->m_filestream; 352 cache = mp->m_filestream;
@@ -537,7 +537,7 @@ xfs_filestream_lookup_ag(
537 xfs_agnumber_t ag; 537 xfs_agnumber_t ag;
538 int ref; 538 int ref;
539 539
540 if (!(ip->i_d.di_mode & (S_IFREG | S_IFDIR))) { 540 if (!S_ISREG(ip->i_d.di_mode) && !S_ISDIR(ip->i_d.di_mode)) {
541 ASSERT(0); 541 ASSERT(0);
542 return NULLAGNUMBER; 542 return NULLAGNUMBER;
543 } 543 }
@@ -579,9 +579,9 @@ xfs_filestream_associate(
579 xfs_agnumber_t ag, rotorstep, startag; 579 xfs_agnumber_t ag, rotorstep, startag;
580 int err = 0; 580 int err = 0;
581 581
582 ASSERT(pip->i_d.di_mode & S_IFDIR); 582 ASSERT(S_ISDIR(pip->i_d.di_mode));
583 ASSERT(ip->i_d.di_mode & S_IFREG); 583 ASSERT(S_ISREG(ip->i_d.di_mode));
584 if (!(pip->i_d.di_mode & S_IFDIR) || !(ip->i_d.di_mode & S_IFREG)) 584 if (!S_ISDIR(pip->i_d.di_mode) || !S_ISREG(ip->i_d.di_mode))
585 return -EINVAL; 585 return -EINVAL;
586 586
587 mp = pip->i_mount; 587 mp = pip->i_mount;
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 8f6fc1a9638..c13fed8c394 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -249,6 +249,11 @@ typedef struct xfs_fsop_resblks {
249#define XFS_MAX_LOG_BYTES \ 249#define XFS_MAX_LOG_BYTES \
250 ((2 * 1024 * 1024 * 1024ULL) - XFS_MIN_LOG_BYTES) 250 ((2 * 1024 * 1024 * 1024ULL) - XFS_MIN_LOG_BYTES)
251 251
252/* Used for sanity checks on superblock */
253#define XFS_MAX_DBLOCKS(s) ((xfs_drfsbno_t)(s)->sb_agcount * (s)->sb_agblocks)
254#define XFS_MIN_DBLOCKS(s) ((xfs_drfsbno_t)((s)->sb_agcount - 1) * \
255 (s)->sb_agblocks + XFS_MIN_AG_BLOCKS)
256
252/* 257/*
253 * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT 258 * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
254 */ 259 */
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/xfs_fs_subr.c
index ed88ed16811..ed88ed16811 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/xfs_fs_subr.c
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/xfs_globals.c
index 76e81cff70b..76e81cff70b 100644
--- a/fs/xfs/linux-2.6/xfs_globals.c
+++ b/fs/xfs/xfs_globals.c
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 84ebeec1664..9f24ec28283 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -202,8 +202,7 @@ xfs_ialloc_inode_init(
202 fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, 202 fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
203 mp->m_bsize * blks_per_cluster, 203 mp->m_bsize * blks_per_cluster,
204 XBF_LOCK); 204 XBF_LOCK);
205 ASSERT(fbuf); 205 ASSERT(!xfs_buf_geterror(fbuf));
206 ASSERT(!XFS_BUF_GETERROR(fbuf));
207 206
208 /* 207 /*
209 * Initialize all inodes in this buffer and then log them. 208 * Initialize all inodes in this buffer and then log them.
@@ -683,7 +682,7 @@ xfs_dialloc(
683 return 0; 682 return 0;
684 } 683 }
685 agi = XFS_BUF_TO_AGI(agbp); 684 agi = XFS_BUF_TO_AGI(agbp);
686 ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); 685 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
687 } else { 686 } else {
688 /* 687 /*
689 * Continue where we left off before. In this case, we 688 * Continue where we left off before. In this case, we
@@ -691,7 +690,7 @@ xfs_dialloc(
691 */ 690 */
692 agbp = *IO_agbp; 691 agbp = *IO_agbp;
693 agi = XFS_BUF_TO_AGI(agbp); 692 agi = XFS_BUF_TO_AGI(agbp);
694 ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); 693 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
695 ASSERT(be32_to_cpu(agi->agi_freecount) > 0); 694 ASSERT(be32_to_cpu(agi->agi_freecount) > 0);
696 } 695 }
697 mp = tp->t_mountp; 696 mp = tp->t_mountp;
@@ -775,7 +774,7 @@ nextag:
775 if (error) 774 if (error)
776 goto nextag; 775 goto nextag;
777 agi = XFS_BUF_TO_AGI(agbp); 776 agi = XFS_BUF_TO_AGI(agbp);
778 ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); 777 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
779 } 778 }
780 /* 779 /*
781 * Here with an allocation group that has a free inode. 780 * Here with an allocation group that has a free inode.
@@ -944,7 +943,7 @@ nextag:
944 * See if the most recently allocated block has any free. 943 * See if the most recently allocated block has any free.
945 */ 944 */
946newino: 945newino:
947 if (be32_to_cpu(agi->agi_newino) != NULLAGINO) { 946 if (agi->agi_newino != cpu_to_be32(NULLAGINO)) {
948 error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino), 947 error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino),
949 XFS_LOOKUP_EQ, &i); 948 XFS_LOOKUP_EQ, &i);
950 if (error) 949 if (error)
@@ -1085,7 +1084,7 @@ xfs_difree(
1085 return error; 1084 return error;
1086 } 1085 }
1087 agi = XFS_BUF_TO_AGI(agbp); 1086 agi = XFS_BUF_TO_AGI(agbp);
1088 ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); 1087 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
1089 ASSERT(agbno < be32_to_cpu(agi->agi_length)); 1088 ASSERT(agbno < be32_to_cpu(agi->agi_length));
1090 /* 1089 /*
1091 * Initialize the cursor. 1090 * Initialize the cursor.
@@ -1438,7 +1437,7 @@ xfs_ialloc_log_agi(
1438 xfs_agi_t *agi; /* allocation group header */ 1437 xfs_agi_t *agi; /* allocation group header */
1439 1438
1440 agi = XFS_BUF_TO_AGI(bp); 1439 agi = XFS_BUF_TO_AGI(bp);
1441 ASSERT(be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC); 1440 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
1442#endif 1441#endif
1443 /* 1442 /*
1444 * Compute byte offsets for the first and last fields. 1443 * Compute byte offsets for the first and last fields.
@@ -1486,13 +1485,13 @@ xfs_read_agi(
1486 if (error) 1485 if (error)
1487 return error; 1486 return error;
1488 1487
1489 ASSERT(*bpp && !XFS_BUF_GETERROR(*bpp)); 1488 ASSERT(!xfs_buf_geterror(*bpp));
1490 agi = XFS_BUF_TO_AGI(*bpp); 1489 agi = XFS_BUF_TO_AGI(*bpp);
1491 1490
1492 /* 1491 /*
1493 * Validate the magic number of the agi block. 1492 * Validate the magic number of the agi block.
1494 */ 1493 */
1495 agi_ok = be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && 1494 agi_ok = agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC) &&
1496 XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)) && 1495 XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)) &&
1497 be32_to_cpu(agi->agi_seqno) == agno; 1496 be32_to_cpu(agi->agi_seqno) == agno;
1498 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI, 1497 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 16921f55c54..c6a75815aea 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -31,7 +31,6 @@
31#include "xfs_dinode.h" 31#include "xfs_dinode.h"
32#include "xfs_inode.h" 32#include "xfs_inode.h"
33#include "xfs_btree.h" 33#include "xfs_btree.h"
34#include "xfs_btree_trace.h"
35#include "xfs_ialloc.h" 34#include "xfs_ialloc.h"
36#include "xfs_alloc.h" 35#include "xfs_alloc.h"
37#include "xfs_error.h" 36#include "xfs_error.h"
@@ -205,72 +204,6 @@ xfs_inobt_recs_inorder(
205} 204}
206#endif /* DEBUG */ 205#endif /* DEBUG */
207 206
208#ifdef XFS_BTREE_TRACE
209ktrace_t *xfs_inobt_trace_buf;
210
211STATIC void
212xfs_inobt_trace_enter(
213 struct xfs_btree_cur *cur,
214 const char *func,
215 char *s,
216 int type,
217 int line,
218 __psunsigned_t a0,
219 __psunsigned_t a1,
220 __psunsigned_t a2,
221 __psunsigned_t a3,
222 __psunsigned_t a4,
223 __psunsigned_t a5,
224 __psunsigned_t a6,
225 __psunsigned_t a7,
226 __psunsigned_t a8,
227 __psunsigned_t a9,
228 __psunsigned_t a10)
229{
230 ktrace_enter(xfs_inobt_trace_buf, (void *)(__psint_t)type,
231 (void *)func, (void *)s, NULL, (void *)cur,
232 (void *)a0, (void *)a1, (void *)a2, (void *)a3,
233 (void *)a4, (void *)a5, (void *)a6, (void *)a7,
234 (void *)a8, (void *)a9, (void *)a10);
235}
236
237STATIC void
238xfs_inobt_trace_cursor(
239 struct xfs_btree_cur *cur,
240 __uint32_t *s0,
241 __uint64_t *l0,
242 __uint64_t *l1)
243{
244 *s0 = cur->bc_private.a.agno;
245 *l0 = cur->bc_rec.i.ir_startino;
246 *l1 = cur->bc_rec.i.ir_free;
247}
248
249STATIC void
250xfs_inobt_trace_key(
251 struct xfs_btree_cur *cur,
252 union xfs_btree_key *key,
253 __uint64_t *l0,
254 __uint64_t *l1)
255{
256 *l0 = be32_to_cpu(key->inobt.ir_startino);
257 *l1 = 0;
258}
259
260STATIC void
261xfs_inobt_trace_record(
262 struct xfs_btree_cur *cur,
263 union xfs_btree_rec *rec,
264 __uint64_t *l0,
265 __uint64_t *l1,
266 __uint64_t *l2)
267{
268 *l0 = be32_to_cpu(rec->inobt.ir_startino);
269 *l1 = be32_to_cpu(rec->inobt.ir_freecount);
270 *l2 = be64_to_cpu(rec->inobt.ir_free);
271}
272#endif /* XFS_BTREE_TRACE */
273
274static const struct xfs_btree_ops xfs_inobt_ops = { 207static const struct xfs_btree_ops xfs_inobt_ops = {
275 .rec_len = sizeof(xfs_inobt_rec_t), 208 .rec_len = sizeof(xfs_inobt_rec_t),
276 .key_len = sizeof(xfs_inobt_key_t), 209 .key_len = sizeof(xfs_inobt_key_t),
@@ -286,18 +219,10 @@ static const struct xfs_btree_ops xfs_inobt_ops = {
286 .init_rec_from_cur = xfs_inobt_init_rec_from_cur, 219 .init_rec_from_cur = xfs_inobt_init_rec_from_cur,
287 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, 220 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur,
288 .key_diff = xfs_inobt_key_diff, 221 .key_diff = xfs_inobt_key_diff,
289
290#ifdef DEBUG 222#ifdef DEBUG
291 .keys_inorder = xfs_inobt_keys_inorder, 223 .keys_inorder = xfs_inobt_keys_inorder,
292 .recs_inorder = xfs_inobt_recs_inorder, 224 .recs_inorder = xfs_inobt_recs_inorder,
293#endif 225#endif
294
295#ifdef XFS_BTREE_TRACE
296 .trace_enter = xfs_inobt_trace_enter,
297 .trace_cursor = xfs_inobt_trace_cursor,
298 .trace_key = xfs_inobt_trace_key,
299 .trace_record = xfs_inobt_trace_record,
300#endif
301}; 226};
302 227
303/* 228/*
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 3631783b2b5..7759812c1bb 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -38,7 +38,6 @@
38#include "xfs_trans_priv.h" 38#include "xfs_trans_priv.h"
39#include "xfs_inode_item.h" 39#include "xfs_inode_item.h"
40#include "xfs_bmap.h" 40#include "xfs_bmap.h"
41#include "xfs_btree_trace.h"
42#include "xfs_trace.h" 41#include "xfs_trace.h"
43 42
44 43
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index a098a20ca63..0239a7c7c88 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -37,7 +37,6 @@
37#include "xfs_buf_item.h" 37#include "xfs_buf_item.h"
38#include "xfs_inode_item.h" 38#include "xfs_inode_item.h"
39#include "xfs_btree.h" 39#include "xfs_btree.h"
40#include "xfs_btree_trace.h"
41#include "xfs_alloc.h" 40#include "xfs_alloc.h"
42#include "xfs_ialloc.h" 41#include "xfs_ialloc.h"
43#include "xfs_bmap.h" 42#include "xfs_bmap.h"
@@ -52,7 +51,7 @@ kmem_zone_t *xfs_ifork_zone;
52kmem_zone_t *xfs_inode_zone; 51kmem_zone_t *xfs_inode_zone;
53 52
54/* 53/*
55 * Used in xfs_itruncate(). This is the maximum number of extents 54 * Used in xfs_itruncate_extents(). This is the maximum number of extents
56 * freed from a file in a single transaction. 55 * freed from a file in a single transaction.
57 */ 56 */
58#define XFS_ITRUNC_MAX_EXTENTS 2 57#define XFS_ITRUNC_MAX_EXTENTS 2
@@ -167,7 +166,7 @@ xfs_imap_to_bp(
167 166
168 dip = (xfs_dinode_t *)xfs_buf_offset(bp, 167 dip = (xfs_dinode_t *)xfs_buf_offset(bp,
169 (i << mp->m_sb.sb_inodelog)); 168 (i << mp->m_sb.sb_inodelog));
170 di_ok = be16_to_cpu(dip->di_magic) == XFS_DINODE_MAGIC && 169 di_ok = dip->di_magic == cpu_to_be16(XFS_DINODE_MAGIC) &&
171 XFS_DINODE_GOOD_VERSION(dip->di_version); 170 XFS_DINODE_GOOD_VERSION(dip->di_version);
172 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, 171 if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
173 XFS_ERRTAG_ITOBP_INOTOBP, 172 XFS_ERRTAG_ITOBP_INOTOBP,
@@ -369,7 +368,7 @@ xfs_iformat(
369 /* 368 /*
370 * no local regular files yet 369 * no local regular files yet
371 */ 370 */
372 if (unlikely((be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFREG)) { 371 if (unlikely(S_ISREG(be16_to_cpu(dip->di_mode)))) {
373 xfs_warn(ip->i_mount, 372 xfs_warn(ip->i_mount,
374 "corrupt inode %Lu (local format for regular file).", 373 "corrupt inode %Lu (local format for regular file).",
375 (unsigned long long) ip->i_ino); 374 (unsigned long long) ip->i_ino);
@@ -802,7 +801,7 @@ xfs_iread(
802 * If we got something that isn't an inode it means someone 801 * If we got something that isn't an inode it means someone
803 * (nfs or dmi) has a stale handle. 802 * (nfs or dmi) has a stale handle.
804 */ 803 */
805 if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC) { 804 if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC)) {
806#ifdef DEBUG 805#ifdef DEBUG
807 xfs_alert(mp, 806 xfs_alert(mp,
808 "%s: dip->di_magic (0x%x) != XFS_DINODE_MAGIC (0x%x)", 807 "%s: dip->di_magic (0x%x) != XFS_DINODE_MAGIC (0x%x)",
@@ -1041,7 +1040,7 @@ xfs_ialloc(
1041 1040
1042 if (pip && XFS_INHERIT_GID(pip)) { 1041 if (pip && XFS_INHERIT_GID(pip)) {
1043 ip->i_d.di_gid = pip->i_d.di_gid; 1042 ip->i_d.di_gid = pip->i_d.di_gid;
1044 if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { 1043 if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) {
1045 ip->i_d.di_mode |= S_ISGID; 1044 ip->i_d.di_mode |= S_ISGID;
1046 } 1045 }
1047 } 1046 }
@@ -1098,14 +1097,14 @@ xfs_ialloc(
1098 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { 1097 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
1099 uint di_flags = 0; 1098 uint di_flags = 0;
1100 1099
1101 if ((mode & S_IFMT) == S_IFDIR) { 1100 if (S_ISDIR(mode)) {
1102 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) 1101 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
1103 di_flags |= XFS_DIFLAG_RTINHERIT; 1102 di_flags |= XFS_DIFLAG_RTINHERIT;
1104 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { 1103 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
1105 di_flags |= XFS_DIFLAG_EXTSZINHERIT; 1104 di_flags |= XFS_DIFLAG_EXTSZINHERIT;
1106 ip->i_d.di_extsize = pip->i_d.di_extsize; 1105 ip->i_d.di_extsize = pip->i_d.di_extsize;
1107 } 1106 }
1108 } else if ((mode & S_IFMT) == S_IFREG) { 1107 } else if (S_ISREG(mode)) {
1109 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) 1108 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
1110 di_flags |= XFS_DIFLAG_REALTIME; 1109 di_flags |= XFS_DIFLAG_REALTIME;
1111 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { 1110 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
@@ -1179,17 +1178,17 @@ xfs_ialloc(
1179 * at least do it for regular files. 1178 * at least do it for regular files.
1180 */ 1179 */
1181#ifdef DEBUG 1180#ifdef DEBUG
1182void 1181STATIC void
1183xfs_isize_check( 1182xfs_isize_check(
1184 xfs_mount_t *mp, 1183 struct xfs_inode *ip,
1185 xfs_inode_t *ip, 1184 xfs_fsize_t isize)
1186 xfs_fsize_t isize)
1187{ 1185{
1188 xfs_fileoff_t map_first; 1186 struct xfs_mount *mp = ip->i_mount;
1189 int nimaps; 1187 xfs_fileoff_t map_first;
1190 xfs_bmbt_irec_t imaps[2]; 1188 int nimaps;
1189 xfs_bmbt_irec_t imaps[2];
1191 1190
1192 if ((ip->i_d.di_mode & S_IFMT) != S_IFREG) 1191 if (!S_ISREG(ip->i_d.di_mode))
1193 return; 1192 return;
1194 1193
1195 if (XFS_IS_REALTIME_INODE(ip)) 1194 if (XFS_IS_REALTIME_INODE(ip))
@@ -1214,168 +1213,14 @@ xfs_isize_check(
1214 ASSERT(nimaps == 1); 1213 ASSERT(nimaps == 1);
1215 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK); 1214 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
1216} 1215}
1216#else /* DEBUG */
1217#define xfs_isize_check(ip, isize)
1217#endif /* DEBUG */ 1218#endif /* DEBUG */
1218 1219
1219/* 1220/*
1220 * Calculate the last possible buffered byte in a file. This must 1221 * Free up the underlying blocks past new_size. The new size must be smaller
1221 * include data that was buffered beyond the EOF by the write code. 1222 * than the current size. This routine can be used both for the attribute and
1222 * This also needs to deal with overflowing the xfs_fsize_t type 1223 * data fork, and does not modify the inode size, which is left to the caller.
1223 * which can happen for sizes near the limit.
1224 *
1225 * We also need to take into account any blocks beyond the EOF. It
1226 * may be the case that they were buffered by a write which failed.
1227 * In that case the pages will still be in memory, but the inode size
1228 * will never have been updated.
1229 */
1230STATIC xfs_fsize_t
1231xfs_file_last_byte(
1232 xfs_inode_t *ip)
1233{
1234 xfs_mount_t *mp;
1235 xfs_fsize_t last_byte;
1236 xfs_fileoff_t last_block;
1237 xfs_fileoff_t size_last_block;
1238 int error;
1239
1240 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED));
1241
1242 mp = ip->i_mount;
1243 /*
1244 * Only check for blocks beyond the EOF if the extents have
1245 * been read in. This eliminates the need for the inode lock,
1246 * and it also saves us from looking when it really isn't
1247 * necessary.
1248 */
1249 if (ip->i_df.if_flags & XFS_IFEXTENTS) {
1250 xfs_ilock(ip, XFS_ILOCK_SHARED);
1251 error = xfs_bmap_last_offset(NULL, ip, &last_block,
1252 XFS_DATA_FORK);
1253 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1254 if (error) {
1255 last_block = 0;
1256 }
1257 } else {
1258 last_block = 0;
1259 }
1260 size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_size);
1261 last_block = XFS_FILEOFF_MAX(last_block, size_last_block);
1262
1263 last_byte = XFS_FSB_TO_B(mp, last_block);
1264 if (last_byte < 0) {
1265 return XFS_MAXIOFFSET(mp);
1266 }
1267 last_byte += (1 << mp->m_writeio_log);
1268 if (last_byte < 0) {
1269 return XFS_MAXIOFFSET(mp);
1270 }
1271 return last_byte;
1272}
1273
1274/*
1275 * Start the truncation of the file to new_size. The new size
1276 * must be smaller than the current size. This routine will
1277 * clear the buffer and page caches of file data in the removed
1278 * range, and xfs_itruncate_finish() will remove the underlying
1279 * disk blocks.
1280 *
1281 * The inode must have its I/O lock locked EXCLUSIVELY, and it
1282 * must NOT have the inode lock held at all. This is because we're
1283 * calling into the buffer/page cache code and we can't hold the
1284 * inode lock when we do so.
1285 *
1286 * We need to wait for any direct I/Os in flight to complete before we
1287 * proceed with the truncate. This is needed to prevent the extents
1288 * being read or written by the direct I/Os from being removed while the
1289 * I/O is in flight as there is no other method of synchronising
1290 * direct I/O with the truncate operation. Also, because we hold
1291 * the IOLOCK in exclusive mode, we prevent new direct I/Os from being
1292 * started until the truncate completes and drops the lock. Essentially,
1293 * the xfs_ioend_wait() call forms an I/O barrier that provides strict
1294 * ordering between direct I/Os and the truncate operation.
1295 *
1296 * The flags parameter can have either the value XFS_ITRUNC_DEFINITE
1297 * or XFS_ITRUNC_MAYBE. The XFS_ITRUNC_MAYBE value should be used
1298 * in the case that the caller is locking things out of order and
1299 * may not be able to call xfs_itruncate_finish() with the inode lock
1300 * held without dropping the I/O lock. If the caller must drop the
1301 * I/O lock before calling xfs_itruncate_finish(), then xfs_itruncate_start()
1302 * must be called again with all the same restrictions as the initial
1303 * call.
1304 */
1305int
1306xfs_itruncate_start(
1307 xfs_inode_t *ip,
1308 uint flags,
1309 xfs_fsize_t new_size)
1310{
1311 xfs_fsize_t last_byte;
1312 xfs_off_t toss_start;
1313 xfs_mount_t *mp;
1314 int error = 0;
1315
1316 ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
1317 ASSERT((new_size == 0) || (new_size <= ip->i_size));
1318 ASSERT((flags == XFS_ITRUNC_DEFINITE) ||
1319 (flags == XFS_ITRUNC_MAYBE));
1320
1321 mp = ip->i_mount;
1322
1323 /* wait for the completion of any pending DIOs */
1324 if (new_size == 0 || new_size < ip->i_size)
1325 xfs_ioend_wait(ip);
1326
1327 /*
1328 * Call toss_pages or flushinval_pages to get rid of pages
1329 * overlapping the region being removed. We have to use
1330 * the less efficient flushinval_pages in the case that the
1331 * caller may not be able to finish the truncate without
1332 * dropping the inode's I/O lock. Make sure
1333 * to catch any pages brought in by buffers overlapping
1334 * the EOF by searching out beyond the isize by our
1335 * block size. We round new_size up to a block boundary
1336 * so that we don't toss things on the same block as
1337 * new_size but before it.
1338 *
1339 * Before calling toss_page or flushinval_pages, make sure to
1340 * call remapf() over the same region if the file is mapped.
1341 * This frees up mapped file references to the pages in the
1342 * given range and for the flushinval_pages case it ensures
1343 * that we get the latest mapped changes flushed out.
1344 */
1345 toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
1346 toss_start = XFS_FSB_TO_B(mp, toss_start);
1347 if (toss_start < 0) {
1348 /*
1349 * The place to start tossing is beyond our maximum
1350 * file size, so there is no way that the data extended
1351 * out there.
1352 */
1353 return 0;
1354 }
1355 last_byte = xfs_file_last_byte(ip);
1356 trace_xfs_itruncate_start(ip, new_size, flags, toss_start, last_byte);
1357 if (last_byte > toss_start) {
1358 if (flags & XFS_ITRUNC_DEFINITE) {
1359 xfs_tosspages(ip, toss_start,
1360 -1, FI_REMAPF_LOCKED);
1361 } else {
1362 error = xfs_flushinval_pages(ip, toss_start,
1363 -1, FI_REMAPF_LOCKED);
1364 }
1365 }
1366
1367#ifdef DEBUG
1368 if (new_size == 0) {
1369 ASSERT(VN_CACHED(VFS_I(ip)) == 0);
1370 }
1371#endif
1372 return error;
1373}
1374
1375/*
1376 * Shrink the file to the given new_size. The new size must be smaller than
1377 * the current size. This will free up the underlying blocks in the removed
1378 * range after a call to xfs_itruncate_start() or xfs_atruncate_start().
1379 * 1224 *
1380 * The transaction passed to this routine must have made a permanent log 1225 * The transaction passed to this routine must have made a permanent log
1381 * reservation of at least XFS_ITRUNCATE_LOG_RES. This routine may commit the 1226 * reservation of at least XFS_ITRUNCATE_LOG_RES. This routine may commit the
@@ -1387,31 +1232,6 @@ xfs_itruncate_start(
1387 * will be "held" within the returned transaction. This routine does NOT 1232 * will be "held" within the returned transaction. This routine does NOT
1388 * require any disk space to be reserved for it within the transaction. 1233 * require any disk space to be reserved for it within the transaction.
1389 * 1234 *
1390 * The fork parameter must be either xfs_attr_fork or xfs_data_fork, and it
1391 * indicates the fork which is to be truncated. For the attribute fork we only
1392 * support truncation to size 0.
1393 *
1394 * We use the sync parameter to indicate whether or not the first transaction
1395 * we perform might have to be synchronous. For the attr fork, it needs to be
1396 * so if the unlink of the inode is not yet known to be permanent in the log.
1397 * This keeps us from freeing and reusing the blocks of the attribute fork
1398 * before the unlink of the inode becomes permanent.
1399 *
1400 * For the data fork, we normally have to run synchronously if we're being
1401 * called out of the inactive path or we're being called out of the create path
1402 * where we're truncating an existing file. Either way, the truncate needs to
1403 * be sync so blocks don't reappear in the file with altered data in case of a
1404 * crash. wsync filesystems can run the first case async because anything that
1405 * shrinks the inode has to run sync so by the time we're called here from
1406 * inactive, the inode size is permanently set to 0.
1407 *
1408 * Calls from the truncate path always need to be sync unless we're in a wsync
1409 * filesystem and the file has already been unlinked.
1410 *
1411 * The caller is responsible for correctly setting the sync parameter. It gets
1412 * too hard for us to guess here which path we're being called out of just
1413 * based on inode state.
1414 *
1415 * If we get an error, we must return with the inode locked and linked into the 1235 * If we get an error, we must return with the inode locked and linked into the
1416 * current transaction. This keeps things simple for the higher level code, 1236 * current transaction. This keeps things simple for the higher level code,
1417 * because it always knows that the inode is locked and held in the transaction 1237 * because it always knows that the inode is locked and held in the transaction
@@ -1419,124 +1239,30 @@ xfs_itruncate_start(
1419 * dirty on error so that transactions can be easily aborted if possible. 1239 * dirty on error so that transactions can be easily aborted if possible.
1420 */ 1240 */
1421int 1241int
1422xfs_itruncate_finish( 1242xfs_itruncate_extents(
1423 xfs_trans_t **tp, 1243 struct xfs_trans **tpp,
1424 xfs_inode_t *ip, 1244 struct xfs_inode *ip,
1425 xfs_fsize_t new_size, 1245 int whichfork,
1426 int fork, 1246 xfs_fsize_t new_size)
1427 int sync)
1428{ 1247{
1429 xfs_fsblock_t first_block; 1248 struct xfs_mount *mp = ip->i_mount;
1430 xfs_fileoff_t first_unmap_block; 1249 struct xfs_trans *tp = *tpp;
1431 xfs_fileoff_t last_block; 1250 struct xfs_trans *ntp;
1432 xfs_filblks_t unmap_len=0; 1251 xfs_bmap_free_t free_list;
1433 xfs_mount_t *mp; 1252 xfs_fsblock_t first_block;
1434 xfs_trans_t *ntp; 1253 xfs_fileoff_t first_unmap_block;
1435 int done; 1254 xfs_fileoff_t last_block;
1436 int committed; 1255 xfs_filblks_t unmap_len;
1437 xfs_bmap_free_t free_list; 1256 int committed;
1438 int error; 1257 int error = 0;
1258 int done = 0;
1439 1259
1440 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); 1260 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
1441 ASSERT((new_size == 0) || (new_size <= ip->i_size)); 1261 ASSERT(new_size <= ip->i_size);
1442 ASSERT(*tp != NULL); 1262 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
1443 ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
1444 ASSERT(ip->i_transp == *tp);
1445 ASSERT(ip->i_itemp != NULL); 1263 ASSERT(ip->i_itemp != NULL);
1446 ASSERT(ip->i_itemp->ili_lock_flags == 0); 1264 ASSERT(ip->i_itemp->ili_lock_flags == 0);
1447 1265 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
1448
1449 ntp = *tp;
1450 mp = (ntp)->t_mountp;
1451 ASSERT(! XFS_NOT_DQATTACHED(mp, ip));
1452
1453 /*
1454 * We only support truncating the entire attribute fork.
1455 */
1456 if (fork == XFS_ATTR_FORK) {
1457 new_size = 0LL;
1458 }
1459 first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
1460 trace_xfs_itruncate_finish_start(ip, new_size);
1461
1462 /*
1463 * The first thing we do is set the size to new_size permanently
1464 * on disk. This way we don't have to worry about anyone ever
1465 * being able to look at the data being freed even in the face
1466 * of a crash. What we're getting around here is the case where
1467 * we free a block, it is allocated to another file, it is written
1468 * to, and then we crash. If the new data gets written to the
1469 * file but the log buffers containing the free and reallocation
1470 * don't, then we'd end up with garbage in the blocks being freed.
1471 * As long as we make the new_size permanent before actually
1472 * freeing any blocks it doesn't matter if they get written to.
1473 *
1474 * The callers must signal into us whether or not the size
1475 * setting here must be synchronous. There are a few cases
1476 * where it doesn't have to be synchronous. Those cases
1477 * occur if the file is unlinked and we know the unlink is
1478 * permanent or if the blocks being truncated are guaranteed
1479 * to be beyond the inode eof (regardless of the link count)
1480 * and the eof value is permanent. Both of these cases occur
1481 * only on wsync-mounted filesystems. In those cases, we're
1482 * guaranteed that no user will ever see the data in the blocks
1483 * that are being truncated so the truncate can run async.
1484 * In the free beyond eof case, the file may wind up with
1485 * more blocks allocated to it than it needs if we crash
1486 * and that won't get fixed until the next time the file
1487 * is re-opened and closed but that's ok as that shouldn't
1488 * be too many blocks.
1489 *
1490 * However, we can't just make all wsync xactions run async
1491 * because there's one call out of the create path that needs
1492 * to run sync where it's truncating an existing file to size
1493 * 0 whose size is > 0.
1494 *
1495 * It's probably possible to come up with a test in this
1496 * routine that would correctly distinguish all the above
1497 * cases from the values of the function parameters and the
1498 * inode state but for sanity's sake, I've decided to let the
1499 * layers above just tell us. It's simpler to correctly figure
1500 * out in the layer above exactly under what conditions we
1501 * can run async and I think it's easier for others read and
1502 * follow the logic in case something has to be changed.
1503 * cscope is your friend -- rcc.
1504 *
1505 * The attribute fork is much simpler.
1506 *
1507 * For the attribute fork we allow the caller to tell us whether
1508 * the unlink of the inode that led to this call is yet permanent
1509 * in the on disk log. If it is not and we will be freeing extents
1510 * in this inode then we make the first transaction synchronous
1511 * to make sure that the unlink is permanent by the time we free
1512 * the blocks.
1513 */
1514 if (fork == XFS_DATA_FORK) {
1515 if (ip->i_d.di_nextents > 0) {
1516 /*
1517 * If we are not changing the file size then do
1518 * not update the on-disk file size - we may be
1519 * called from xfs_inactive_free_eofblocks(). If we
1520 * update the on-disk file size and then the system
1521 * crashes before the contents of the file are
1522 * flushed to disk then the files may be full of
1523 * holes (ie NULL files bug).
1524 */
1525 if (ip->i_size != new_size) {
1526 ip->i_d.di_size = new_size;
1527 ip->i_size = new_size;
1528 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE);
1529 }
1530 }
1531 } else if (sync) {
1532 ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC));
1533 if (ip->i_d.di_anextents > 0)
1534 xfs_trans_set_sync(ntp);
1535 }
1536 ASSERT(fork == XFS_DATA_FORK ||
1537 (fork == XFS_ATTR_FORK &&
1538 ((sync && !(mp->m_flags & XFS_MOUNT_WSYNC)) ||
1539 (sync == 0 && (mp->m_flags & XFS_MOUNT_WSYNC)))));
1540 1266
1541 /* 1267 /*
1542 * Since it is possible for space to become allocated beyond 1268 * Since it is possible for space to become allocated beyond
@@ -1547,128 +1273,142 @@ xfs_itruncate_finish(
1547 * beyond the maximum file size (ie it is the same as last_block), 1273 * beyond the maximum file size (ie it is the same as last_block),
1548 * then there is nothing to do. 1274 * then there is nothing to do.
1549 */ 1275 */
1276 first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
1550 last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); 1277 last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp));
1551 ASSERT(first_unmap_block <= last_block); 1278 if (first_unmap_block == last_block)
1552 done = 0; 1279 return 0;
1553 if (last_block == first_unmap_block) { 1280
1554 done = 1; 1281 ASSERT(first_unmap_block < last_block);
1555 } else { 1282 unmap_len = last_block - first_unmap_block + 1;
1556 unmap_len = last_block - first_unmap_block + 1;
1557 }
1558 while (!done) { 1283 while (!done) {
1559 /*
1560 * Free up up to XFS_ITRUNC_MAX_EXTENTS. xfs_bunmapi()
1561 * will tell us whether it freed the entire range or
1562 * not. If this is a synchronous mount (wsync),
1563 * then we can tell bunmapi to keep all the
1564 * transactions asynchronous since the unlink
1565 * transaction that made this inode inactive has
1566 * already hit the disk. There's no danger of
1567 * the freed blocks being reused, there being a
1568 * crash, and the reused blocks suddenly reappearing
1569 * in this file with garbage in them once recovery
1570 * runs.
1571 */
1572 xfs_bmap_init(&free_list, &first_block); 1284 xfs_bmap_init(&free_list, &first_block);
1573 error = xfs_bunmapi(ntp, ip, 1285 error = xfs_bunmapi(tp, ip,
1574 first_unmap_block, unmap_len, 1286 first_unmap_block, unmap_len,
1575 xfs_bmapi_aflag(fork), 1287 xfs_bmapi_aflag(whichfork),
1576 XFS_ITRUNC_MAX_EXTENTS, 1288 XFS_ITRUNC_MAX_EXTENTS,
1577 &first_block, &free_list, 1289 &first_block, &free_list,
1578 &done); 1290 &done);
1579 if (error) { 1291 if (error)
1580 /* 1292 goto out_bmap_cancel;
1581 * If the bunmapi call encounters an error,
1582 * return to the caller where the transaction
1583 * can be properly aborted. We just need to
1584 * make sure we're not holding any resources
1585 * that we were not when we came in.
1586 */
1587 xfs_bmap_cancel(&free_list);
1588 return error;
1589 }
1590 1293
1591 /* 1294 /*
1592 * Duplicate the transaction that has the permanent 1295 * Duplicate the transaction that has the permanent
1593 * reservation and commit the old transaction. 1296 * reservation and commit the old transaction.
1594 */ 1297 */
1595 error = xfs_bmap_finish(tp, &free_list, &committed); 1298 error = xfs_bmap_finish(&tp, &free_list, &committed);
1596 ntp = *tp;
1597 if (committed) 1299 if (committed)
1598 xfs_trans_ijoin(ntp, ip); 1300 xfs_trans_ijoin(tp, ip);
1599 1301 if (error)
1600 if (error) { 1302 goto out_bmap_cancel;
1601 /*
1602 * If the bmap finish call encounters an error, return
1603 * to the caller where the transaction can be properly
1604 * aborted. We just need to make sure we're not
1605 * holding any resources that we were not when we came
1606 * in.
1607 *
1608 * Aborting from this point might lose some blocks in
1609 * the file system, but oh well.
1610 */
1611 xfs_bmap_cancel(&free_list);
1612 return error;
1613 }
1614 1303
1615 if (committed) { 1304 if (committed) {
1616 /* 1305 /*
1617 * Mark the inode dirty so it will be logged and 1306 * Mark the inode dirty so it will be logged and
1618 * moved forward in the log as part of every commit. 1307 * moved forward in the log as part of every commit.
1619 */ 1308 */
1620 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); 1309 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1621 } 1310 }
1622 1311
1623 ntp = xfs_trans_dup(ntp); 1312 ntp = xfs_trans_dup(tp);
1624 error = xfs_trans_commit(*tp, 0); 1313 error = xfs_trans_commit(tp, 0);
1625 *tp = ntp; 1314 tp = ntp;
1626 1315
1627 xfs_trans_ijoin(ntp, ip); 1316 xfs_trans_ijoin(tp, ip);
1628 1317
1629 if (error) 1318 if (error)
1630 return error; 1319 goto out;
1320
1631 /* 1321 /*
1632 * transaction commit worked ok so we can drop the extra ticket 1322 * Transaction commit worked ok so we can drop the extra ticket
1633 * reference that we gained in xfs_trans_dup() 1323 * reference that we gained in xfs_trans_dup()
1634 */ 1324 */
1635 xfs_log_ticket_put(ntp->t_ticket); 1325 xfs_log_ticket_put(tp->t_ticket);
1636 error = xfs_trans_reserve(ntp, 0, 1326 error = xfs_trans_reserve(tp, 0,
1637 XFS_ITRUNCATE_LOG_RES(mp), 0, 1327 XFS_ITRUNCATE_LOG_RES(mp), 0,
1638 XFS_TRANS_PERM_LOG_RES, 1328 XFS_TRANS_PERM_LOG_RES,
1639 XFS_ITRUNCATE_LOG_COUNT); 1329 XFS_ITRUNCATE_LOG_COUNT);
1640 if (error) 1330 if (error)
1641 return error; 1331 goto out;
1642 } 1332 }
1333
1334out:
1335 *tpp = tp;
1336 return error;
1337out_bmap_cancel:
1643 /* 1338 /*
1644 * Only update the size in the case of the data fork, but 1339 * If the bunmapi call encounters an error, return to the caller where
1645 * always re-log the inode so that our permanent transaction 1340 * the transaction can be properly aborted. We just need to make sure
1646 * can keep on rolling it forward in the log. 1341 * we're not holding any resources that we were not when we came in.
1647 */ 1342 */
1648 if (fork == XFS_DATA_FORK) { 1343 xfs_bmap_cancel(&free_list);
1649 xfs_isize_check(mp, ip, new_size); 1344 goto out;
1345}
1346
1347int
1348xfs_itruncate_data(
1349 struct xfs_trans **tpp,
1350 struct xfs_inode *ip,
1351 xfs_fsize_t new_size)
1352{
1353 int error;
1354
1355 trace_xfs_itruncate_data_start(ip, new_size);
1356
1357 /*
1358 * The first thing we do is set the size to new_size permanently on
1359 * disk. This way we don't have to worry about anyone ever being able
1360 * to look at the data being freed even in the face of a crash.
1361 * What we're getting around here is the case where we free a block, it
1362 * is allocated to another file, it is written to, and then we crash.
1363 * If the new data gets written to the file but the log buffers
1364 * containing the free and reallocation don't, then we'd end up with
1365 * garbage in the blocks being freed. As long as we make the new_size
1366 * permanent before actually freeing any blocks it doesn't matter if
1367 * they get written to.
1368 */
1369 if (ip->i_d.di_nextents > 0) {
1650 /* 1370 /*
1651 * If we are not changing the file size then do 1371 * If we are not changing the file size then do not update
1652 * not update the on-disk file size - we may be 1372 * the on-disk file size - we may be called from
1653 * called from xfs_inactive_free_eofblocks(). If we 1373 * xfs_inactive_free_eofblocks(). If we update the on-disk
1654 * update the on-disk file size and then the system 1374 * file size and then the system crashes before the contents
1655 * crashes before the contents of the file are 1375 * of the file are flushed to disk then the files may be
1656 * flushed to disk then the files may be full of 1376 * full of holes (ie NULL files bug).
1657 * holes (ie NULL files bug).
1658 */ 1377 */
1659 if (ip->i_size != new_size) { 1378 if (ip->i_size != new_size) {
1660 ip->i_d.di_size = new_size; 1379 ip->i_d.di_size = new_size;
1661 ip->i_size = new_size; 1380 ip->i_size = new_size;
1381 xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
1662 } 1382 }
1663 } 1383 }
1664 xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); 1384
1665 ASSERT((new_size != 0) || 1385 error = xfs_itruncate_extents(tpp, ip, XFS_DATA_FORK, new_size);
1666 (fork == XFS_ATTR_FORK) || 1386 if (error)
1667 (ip->i_delayed_blks == 0)); 1387 return error;
1668 ASSERT((new_size != 0) || 1388
1669 (fork == XFS_ATTR_FORK) || 1389 /*
1670 (ip->i_d.di_nextents == 0)); 1390 * If we are not changing the file size then do not update the on-disk
1671 trace_xfs_itruncate_finish_end(ip, new_size); 1391 * file size - we may be called from xfs_inactive_free_eofblocks().
1392 * If we update the on-disk file size and then the system crashes
1393 * before the contents of the file are flushed to disk then the files
1394 * may be full of holes (ie NULL files bug).
1395 */
1396 xfs_isize_check(ip, new_size);
1397 if (ip->i_size != new_size) {
1398 ip->i_d.di_size = new_size;
1399 ip->i_size = new_size;
1400 }
1401
1402 ASSERT(new_size != 0 || ip->i_delayed_blks == 0);
1403 ASSERT(new_size != 0 || ip->i_d.di_nextents == 0);
1404
1405 /*
1406 * Always re-log the inode so that our permanent transaction can keep
1407 * on rolling it forward in the log.
1408 */
1409 xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);
1410
1411 trace_xfs_itruncate_data_end(ip, new_size);
1672 return 0; 1412 return 0;
1673} 1413}
1674 1414
@@ -1694,7 +1434,6 @@ xfs_iunlink(
1694 1434
1695 ASSERT(ip->i_d.di_nlink == 0); 1435 ASSERT(ip->i_d.di_nlink == 0);
1696 ASSERT(ip->i_d.di_mode != 0); 1436 ASSERT(ip->i_d.di_mode != 0);
1697 ASSERT(ip->i_transp == tp);
1698 1437
1699 mp = tp->t_mountp; 1438 mp = tp->t_mountp;
1700 1439
@@ -1717,7 +1456,7 @@ xfs_iunlink(
1717 ASSERT(agi->agi_unlinked[bucket_index]); 1456 ASSERT(agi->agi_unlinked[bucket_index]);
1718 ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); 1457 ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino);
1719 1458
1720 if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) { 1459 if (agi->agi_unlinked[bucket_index] != cpu_to_be32(NULLAGINO)) {
1721 /* 1460 /*
1722 * There is already another inode in the bucket we need 1461 * There is already another inode in the bucket we need
1723 * to add ourselves to. Add us at the front of the list. 1462 * to add ourselves to. Add us at the front of the list.
@@ -1728,8 +1467,7 @@ xfs_iunlink(
1728 if (error) 1467 if (error)
1729 return error; 1468 return error;
1730 1469
1731 ASSERT(be32_to_cpu(dip->di_next_unlinked) == NULLAGINO); 1470 ASSERT(dip->di_next_unlinked == cpu_to_be32(NULLAGINO));
1732 /* both on-disk, don't endian flip twice */
1733 dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; 1471 dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
1734 offset = ip->i_imap.im_boffset + 1472 offset = ip->i_imap.im_boffset +
1735 offsetof(xfs_dinode_t, di_next_unlinked); 1473 offsetof(xfs_dinode_t, di_next_unlinked);
@@ -1794,7 +1532,7 @@ xfs_iunlink_remove(
1794 agino = XFS_INO_TO_AGINO(mp, ip->i_ino); 1532 agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
1795 ASSERT(agino != 0); 1533 ASSERT(agino != 0);
1796 bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; 1534 bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
1797 ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO); 1535 ASSERT(agi->agi_unlinked[bucket_index] != cpu_to_be32(NULLAGINO));
1798 ASSERT(agi->agi_unlinked[bucket_index]); 1536 ASSERT(agi->agi_unlinked[bucket_index]);
1799 1537
1800 if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) { 1538 if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) {
@@ -1959,7 +1697,7 @@ xfs_ifree_cluster(
1959 * stale first, we will not attempt to lock them in the loop 1697 * stale first, we will not attempt to lock them in the loop
1960 * below as the XFS_ISTALE flag will be set. 1698 * below as the XFS_ISTALE flag will be set.
1961 */ 1699 */
1962 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); 1700 lip = bp->b_fspriv;
1963 while (lip) { 1701 while (lip) {
1964 if (lip->li_type == XFS_LI_INODE) { 1702 if (lip->li_type == XFS_LI_INODE) {
1965 iip = (xfs_inode_log_item_t *)lip; 1703 iip = (xfs_inode_log_item_t *)lip;
@@ -2086,12 +1824,11 @@ xfs_ifree(
2086 xfs_buf_t *ibp; 1824 xfs_buf_t *ibp;
2087 1825
2088 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 1826 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
2089 ASSERT(ip->i_transp == tp);
2090 ASSERT(ip->i_d.di_nlink == 0); 1827 ASSERT(ip->i_d.di_nlink == 0);
2091 ASSERT(ip->i_d.di_nextents == 0); 1828 ASSERT(ip->i_d.di_nextents == 0);
2092 ASSERT(ip->i_d.di_anextents == 0); 1829 ASSERT(ip->i_d.di_anextents == 0);
2093 ASSERT((ip->i_d.di_size == 0 && ip->i_size == 0) || 1830 ASSERT((ip->i_d.di_size == 0 && ip->i_size == 0) ||
2094 ((ip->i_d.di_mode & S_IFMT) != S_IFREG)); 1831 (!S_ISREG(ip->i_d.di_mode)));
2095 ASSERT(ip->i_d.di_nblocks == 0); 1832 ASSERT(ip->i_d.di_nblocks == 0);
2096 1833
2097 /* 1834 /*
@@ -2733,10 +2470,10 @@ cluster_corrupt_out:
2733 * mark the buffer as an error and call them. Otherwise 2470 * mark the buffer as an error and call them. Otherwise
2734 * mark it as stale and brelse. 2471 * mark it as stale and brelse.
2735 */ 2472 */
2736 if (XFS_BUF_IODONE_FUNC(bp)) { 2473 if (bp->b_iodone) {
2737 XFS_BUF_UNDONE(bp); 2474 XFS_BUF_UNDONE(bp);
2738 XFS_BUF_STALE(bp); 2475 XFS_BUF_STALE(bp);
2739 XFS_BUF_ERROR(bp,EIO); 2476 xfs_buf_ioerror(bp, EIO);
2740 xfs_buf_ioend(bp, 0); 2477 xfs_buf_ioend(bp, 0);
2741 } else { 2478 } else {
2742 XFS_BUF_STALE(bp); 2479 XFS_BUF_STALE(bp);
@@ -2848,7 +2585,7 @@ xfs_iflush(
2848 * If the buffer is pinned then push on the log now so we won't 2585 * If the buffer is pinned then push on the log now so we won't
2849 * get stuck waiting in the write for too long. 2586 * get stuck waiting in the write for too long.
2850 */ 2587 */
2851 if (XFS_BUF_ISPINNED(bp)) 2588 if (xfs_buf_ispinned(bp))
2852 xfs_log_force(mp, 0); 2589 xfs_log_force(mp, 0);
2853 2590
2854 /* 2591 /*
@@ -2920,7 +2657,7 @@ xfs_iflush_int(
2920 */ 2657 */
2921 xfs_synchronize_times(ip); 2658 xfs_synchronize_times(ip);
2922 2659
2923 if (XFS_TEST_ERROR(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC, 2660 if (XFS_TEST_ERROR(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC),
2924 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { 2661 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
2925 xfs_alert_tag(mp, XFS_PTAG_IFLUSH, 2662 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
2926 "%s: Bad inode %Lu magic number 0x%x, ptr 0x%p", 2663 "%s: Bad inode %Lu magic number 0x%x, ptr 0x%p",
@@ -2934,7 +2671,7 @@ xfs_iflush_int(
2934 __func__, ip->i_ino, ip, ip->i_d.di_magic); 2671 __func__, ip->i_ino, ip, ip->i_d.di_magic);
2935 goto corrupt_out; 2672 goto corrupt_out;
2936 } 2673 }
2937 if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) { 2674 if (S_ISREG(ip->i_d.di_mode)) {
2938 if (XFS_TEST_ERROR( 2675 if (XFS_TEST_ERROR(
2939 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && 2676 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
2940 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), 2677 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE),
@@ -2944,7 +2681,7 @@ xfs_iflush_int(
2944 __func__, ip->i_ino, ip); 2681 __func__, ip->i_ino, ip);
2945 goto corrupt_out; 2682 goto corrupt_out;
2946 } 2683 }
2947 } else if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 2684 } else if (S_ISDIR(ip->i_d.di_mode)) {
2948 if (XFS_TEST_ERROR( 2685 if (XFS_TEST_ERROR(
2949 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && 2686 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
2950 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && 2687 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
@@ -3073,8 +2810,8 @@ xfs_iflush_int(
3073 */ 2810 */
3074 xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item); 2811 xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item);
3075 2812
3076 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); 2813 ASSERT(bp->b_fspriv != NULL);
3077 ASSERT(XFS_BUF_IODONE_FUNC(bp) != NULL); 2814 ASSERT(bp->b_iodone != NULL);
3078 } else { 2815 } else {
3079 /* 2816 /*
3080 * We're flushing an inode which is not in the AIL and has 2817 * We're flushing an inode which is not in the AIL and has
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 964cfea7768..2380a4bcbec 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -241,7 +241,6 @@ typedef struct xfs_inode {
241 xfs_ifork_t i_df; /* data fork */ 241 xfs_ifork_t i_df; /* data fork */
242 242
243 /* Transaction and locking information. */ 243 /* Transaction and locking information. */
244 struct xfs_trans *i_transp; /* ptr to owning transaction*/
245 struct xfs_inode_log_item *i_itemp; /* logging information */ 244 struct xfs_inode_log_item *i_itemp; /* logging information */
246 mrlock_t i_lock; /* inode lock */ 245 mrlock_t i_lock; /* inode lock */
247 mrlock_t i_iolock; /* inode IO lock */ 246 mrlock_t i_iolock; /* inode IO lock */
@@ -264,7 +263,7 @@ typedef struct xfs_inode {
264 struct inode i_vnode; /* embedded VFS inode */ 263 struct inode i_vnode; /* embedded VFS inode */
265} xfs_inode_t; 264} xfs_inode_t;
266 265
267#define XFS_ISIZE(ip) (((ip)->i_d.di_mode & S_IFMT) == S_IFREG) ? \ 266#define XFS_ISIZE(ip) S_ISREG((ip)->i_d.di_mode) ? \
268 (ip)->i_size : (ip)->i_d.di_size; 267 (ip)->i_size : (ip)->i_d.di_size;
269 268
270/* Convert from vfs inode to xfs inode */ 269/* Convert from vfs inode to xfs inode */
@@ -458,16 +457,6 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
458extern struct lock_class_key xfs_iolock_reclaimable; 457extern struct lock_class_key xfs_iolock_reclaimable;
459 458
460/* 459/*
461 * Flags for xfs_itruncate_start().
462 */
463#define XFS_ITRUNC_DEFINITE 0x1
464#define XFS_ITRUNC_MAYBE 0x2
465
466#define XFS_ITRUNC_FLAGS \
467 { XFS_ITRUNC_DEFINITE, "DEFINITE" }, \
468 { XFS_ITRUNC_MAYBE, "MAYBE" }
469
470/*
471 * For multiple groups support: if S_ISGID bit is set in the parent 460 * For multiple groups support: if S_ISGID bit is set in the parent
472 * directory, group of new file is set to that of the parent, and 461 * directory, group of new file is set to that of the parent, and
473 * new subdirectory gets S_ISGID bit from parent. 462 * new subdirectory gets S_ISGID bit from parent.
@@ -501,9 +490,10 @@ uint xfs_ip2xflags(struct xfs_inode *);
501uint xfs_dic2xflags(struct xfs_dinode *); 490uint xfs_dic2xflags(struct xfs_dinode *);
502int xfs_ifree(struct xfs_trans *, xfs_inode_t *, 491int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
503 struct xfs_bmap_free *); 492 struct xfs_bmap_free *);
504int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); 493int xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *,
505int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *, 494 int, xfs_fsize_t);
506 xfs_fsize_t, int, int); 495int xfs_itruncate_data(struct xfs_trans **, struct xfs_inode *,
496 xfs_fsize_t);
507int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); 497int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
508 498
509void xfs_iext_realloc(xfs_inode_t *, int, int); 499void xfs_iext_realloc(xfs_inode_t *, int, int);
@@ -579,13 +569,6 @@ void xfs_iext_irec_update_extoffs(xfs_ifork_t *, int, int);
579 569
580#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount)) 570#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))
581 571
582#ifdef DEBUG
583void xfs_isize_check(struct xfs_mount *, struct xfs_inode *,
584 xfs_fsize_t);
585#else /* DEBUG */
586#define xfs_isize_check(mp, ip, isize)
587#endif /* DEBUG */
588
589#if defined(DEBUG) 572#if defined(DEBUG)
590void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); 573void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
591#else 574#else
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index b1e88d56069..836ad80d4f2 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -632,13 +632,8 @@ xfs_inode_item_unlock(
632 struct xfs_inode *ip = iip->ili_inode; 632 struct xfs_inode *ip = iip->ili_inode;
633 unsigned short lock_flags; 633 unsigned short lock_flags;
634 634
635 ASSERT(iip->ili_inode->i_itemp != NULL); 635 ASSERT(ip->i_itemp != NULL);
636 ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL)); 636 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
637
638 /*
639 * Clear the transaction pointer in the inode.
640 */
641 ip->i_transp = NULL;
642 637
643 /* 638 /*
644 * If the inode needed a separate buffer with which to log 639 * If the inode needed a separate buffer with which to log
@@ -664,8 +659,8 @@ xfs_inode_item_unlock(
664 lock_flags = iip->ili_lock_flags; 659 lock_flags = iip->ili_lock_flags;
665 iip->ili_lock_flags = 0; 660 iip->ili_lock_flags = 0;
666 if (lock_flags) { 661 if (lock_flags) {
667 xfs_iunlock(iip->ili_inode, lock_flags); 662 xfs_iunlock(ip, lock_flags);
668 IRELE(iip->ili_inode); 663 IRELE(ip);
669 } 664 }
670} 665}
671 666
@@ -713,13 +708,14 @@ xfs_inode_item_committed(
713 * marked delayed write. If that's the case, we'll promote it and that will 708 * marked delayed write. If that's the case, we'll promote it and that will
714 * allow the caller to write the buffer by triggering the xfsbufd to run. 709 * allow the caller to write the buffer by triggering the xfsbufd to run.
715 */ 710 */
716STATIC void 711STATIC bool
717xfs_inode_item_pushbuf( 712xfs_inode_item_pushbuf(
718 struct xfs_log_item *lip) 713 struct xfs_log_item *lip)
719{ 714{
720 struct xfs_inode_log_item *iip = INODE_ITEM(lip); 715 struct xfs_inode_log_item *iip = INODE_ITEM(lip);
721 struct xfs_inode *ip = iip->ili_inode; 716 struct xfs_inode *ip = iip->ili_inode;
722 struct xfs_buf *bp; 717 struct xfs_buf *bp;
718 bool ret = true;
723 719
724 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED)); 720 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED));
725 721
@@ -730,7 +726,7 @@ xfs_inode_item_pushbuf(
730 if (completion_done(&ip->i_flush) || 726 if (completion_done(&ip->i_flush) ||
731 !(lip->li_flags & XFS_LI_IN_AIL)) { 727 !(lip->li_flags & XFS_LI_IN_AIL)) {
732 xfs_iunlock(ip, XFS_ILOCK_SHARED); 728 xfs_iunlock(ip, XFS_ILOCK_SHARED);
733 return; 729 return true;
734 } 730 }
735 731
736 bp = xfs_incore(ip->i_mount->m_ddev_targp, iip->ili_format.ilf_blkno, 732 bp = xfs_incore(ip->i_mount->m_ddev_targp, iip->ili_format.ilf_blkno,
@@ -738,10 +734,13 @@ xfs_inode_item_pushbuf(
738 734
739 xfs_iunlock(ip, XFS_ILOCK_SHARED); 735 xfs_iunlock(ip, XFS_ILOCK_SHARED);
740 if (!bp) 736 if (!bp)
741 return; 737 return true;
742 if (XFS_BUF_ISDELAYWRITE(bp)) 738 if (XFS_BUF_ISDELAYWRITE(bp))
743 xfs_buf_delwri_promote(bp); 739 xfs_buf_delwri_promote(bp);
740 if (xfs_buf_ispinned(bp))
741 ret = false;
744 xfs_buf_relse(bp); 742 xfs_buf_relse(bp);
743 return ret;
745} 744}
746 745
747/* 746/*
@@ -879,7 +878,7 @@ xfs_iflush_done(
879 * Scan the buffer IO completions for other inodes being completed and 878 * Scan the buffer IO completions for other inodes being completed and
880 * attach them to the current inode log item. 879 * attach them to the current inode log item.
881 */ 880 */
882 blip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); 881 blip = bp->b_fspriv;
883 prev = NULL; 882 prev = NULL;
884 while (blip != NULL) { 883 while (blip != NULL) {
885 if (lip->li_cb != xfs_iflush_done) { 884 if (lip->li_cb != xfs_iflush_done) {
@@ -891,7 +890,7 @@ xfs_iflush_done(
891 /* remove from list */ 890 /* remove from list */
892 next = blip->li_bio_list; 891 next = blip->li_bio_list;
893 if (!prev) { 892 if (!prev) {
894 XFS_BUF_SET_FSPRIVATE(bp, next); 893 bp->b_fspriv = next;
895 } else { 894 } else {
896 prev->li_bio_list = next; 895 prev->li_bio_list = next;
897 } 896 }
diff --git a/fs/xfs/xfs_inum.h b/fs/xfs/xfs_inum.h
index b8e4ee4e89a..b253c0ea5be 100644
--- a/fs/xfs/xfs_inum.h
+++ b/fs/xfs/xfs_inum.h
@@ -28,17 +28,6 @@
28 28
29typedef __uint32_t xfs_agino_t; /* within allocation grp inode number */ 29typedef __uint32_t xfs_agino_t; /* within allocation grp inode number */
30 30
31/*
32 * Useful inode bits for this kernel.
33 * Used in some places where having 64-bits in the 32-bit kernels
34 * costs too much.
35 */
36#if XFS_BIG_INUMS
37typedef xfs_ino_t xfs_intino_t;
38#else
39typedef __uint32_t xfs_intino_t;
40#endif
41
42#define NULLFSINO ((xfs_ino_t)-1) 31#define NULLFSINO ((xfs_ino_t)-1)
43#define NULLAGINO ((xfs_agino_t)-1) 32#define NULLAGINO ((xfs_agino_t)-1)
44 33
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index acca2c5ca3f..f7ce7debe14 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -265,7 +265,7 @@ xfs_open_by_handle(
265 return PTR_ERR(filp); 265 return PTR_ERR(filp);
266 } 266 }
267 267
268 if (inode->i_mode & S_IFREG) { 268 if (S_ISREG(inode->i_mode)) {
269 filp->f_flags |= O_NOATIME; 269 filp->f_flags |= O_NOATIME;
270 filp->f_mode |= FMODE_NOCMTIME; 270 filp->f_mode |= FMODE_NOCMTIME;
271 } 271 }
@@ -850,14 +850,14 @@ xfs_set_diflags(
850 di_flags |= XFS_DIFLAG_NODEFRAG; 850 di_flags |= XFS_DIFLAG_NODEFRAG;
851 if (xflags & XFS_XFLAG_FILESTREAM) 851 if (xflags & XFS_XFLAG_FILESTREAM)
852 di_flags |= XFS_DIFLAG_FILESTREAM; 852 di_flags |= XFS_DIFLAG_FILESTREAM;
853 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 853 if (S_ISDIR(ip->i_d.di_mode)) {
854 if (xflags & XFS_XFLAG_RTINHERIT) 854 if (xflags & XFS_XFLAG_RTINHERIT)
855 di_flags |= XFS_DIFLAG_RTINHERIT; 855 di_flags |= XFS_DIFLAG_RTINHERIT;
856 if (xflags & XFS_XFLAG_NOSYMLINKS) 856 if (xflags & XFS_XFLAG_NOSYMLINKS)
857 di_flags |= XFS_DIFLAG_NOSYMLINKS; 857 di_flags |= XFS_DIFLAG_NOSYMLINKS;
858 if (xflags & XFS_XFLAG_EXTSZINHERIT) 858 if (xflags & XFS_XFLAG_EXTSZINHERIT)
859 di_flags |= XFS_DIFLAG_EXTSZINHERIT; 859 di_flags |= XFS_DIFLAG_EXTSZINHERIT;
860 } else if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) { 860 } else if (S_ISREG(ip->i_d.di_mode)) {
861 if (xflags & XFS_XFLAG_REALTIME) 861 if (xflags & XFS_XFLAG_REALTIME)
862 di_flags |= XFS_DIFLAG_REALTIME; 862 di_flags |= XFS_DIFLAG_REALTIME;
863 if (xflags & XFS_XFLAG_EXTSIZE) 863 if (xflags & XFS_XFLAG_EXTSIZE)
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
index d56173b34a2..d56173b34a2 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.h
+++ b/fs/xfs/xfs_ioctl.h
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 54e623bfbb8..54e623bfbb8 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.h b/fs/xfs/xfs_ioctl32.h
index 80f4060e897..80f4060e897 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.h
+++ b/fs/xfs/xfs_ioctl32.h
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/xfs_iops.c
index d44d92cd12b..474920b4655 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -39,6 +39,7 @@
39#include "xfs_buf_item.h" 39#include "xfs_buf_item.h"
40#include "xfs_utils.h" 40#include "xfs_utils.h"
41#include "xfs_vnodeops.h" 41#include "xfs_vnodeops.h"
42#include "xfs_inode_item.h"
42#include "xfs_trace.h" 43#include "xfs_trace.h"
43 44
44#include <linux/capability.h> 45#include <linux/capability.h>
@@ -69,9 +70,8 @@ xfs_synchronize_times(
69} 70}
70 71
71/* 72/*
72 * If the linux inode is valid, mark it dirty. 73 * If the linux inode is valid, mark it dirty, else mark the dirty state
73 * Used when committing a dirty inode into a transaction so that 74 * in the XFS inode to make sure we pick it up when reclaiming the inode.
74 * the inode will get written back by the linux code
75 */ 75 */
76void 76void
77xfs_mark_inode_dirty_sync( 77xfs_mark_inode_dirty_sync(
@@ -81,6 +81,10 @@ xfs_mark_inode_dirty_sync(
81 81
82 if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) 82 if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
83 mark_inode_dirty_sync(inode); 83 mark_inode_dirty_sync(inode);
84 else {
85 barrier();
86 ip->i_update_core = 1;
87 }
84} 88}
85 89
86void 90void
@@ -91,6 +95,11 @@ xfs_mark_inode_dirty(
91 95
92 if (!(inode->i_state & (I_WILL_FREE|I_FREEING))) 96 if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
93 mark_inode_dirty(inode); 97 mark_inode_dirty(inode);
98 else {
99 barrier();
100 ip->i_update_core = 1;
101 }
102
94} 103}
95 104
96/* 105/*
@@ -201,9 +210,9 @@ xfs_vn_mknod(
201 210
202 if (default_acl) { 211 if (default_acl) {
203 error = -xfs_inherit_acl(inode, default_acl); 212 error = -xfs_inherit_acl(inode, default_acl);
213 default_acl = NULL;
204 if (unlikely(error)) 214 if (unlikely(error))
205 goto out_cleanup_inode; 215 goto out_cleanup_inode;
206 posix_acl_release(default_acl);
207 } 216 }
208 217
209 218
@@ -456,7 +465,7 @@ xfs_vn_getattr(
456 trace_xfs_getattr(ip); 465 trace_xfs_getattr(ip);
457 466
458 if (XFS_FORCED_SHUTDOWN(mp)) 467 if (XFS_FORCED_SHUTDOWN(mp))
459 return XFS_ERROR(EIO); 468 return -XFS_ERROR(EIO);
460 469
461 stat->size = XFS_ISIZE(ip); 470 stat->size = XFS_ISIZE(ip);
462 stat->dev = inode->i_sb->s_dev; 471 stat->dev = inode->i_sb->s_dev;
@@ -497,12 +506,442 @@ xfs_vn_getattr(
497 return 0; 506 return 0;
498} 507}
499 508
509int
510xfs_setattr_nonsize(
511 struct xfs_inode *ip,
512 struct iattr *iattr,
513 int flags)
514{
515 xfs_mount_t *mp = ip->i_mount;
516 struct inode *inode = VFS_I(ip);
517 int mask = iattr->ia_valid;
518 xfs_trans_t *tp;
519 int error;
520 uid_t uid = 0, iuid = 0;
521 gid_t gid = 0, igid = 0;
522 struct xfs_dquot *udqp = NULL, *gdqp = NULL;
523 struct xfs_dquot *olddquot1 = NULL, *olddquot2 = NULL;
524
525 trace_xfs_setattr(ip);
526
527 if (mp->m_flags & XFS_MOUNT_RDONLY)
528 return XFS_ERROR(EROFS);
529
530 if (XFS_FORCED_SHUTDOWN(mp))
531 return XFS_ERROR(EIO);
532
533 error = -inode_change_ok(inode, iattr);
534 if (error)
535 return XFS_ERROR(error);
536
537 ASSERT((mask & ATTR_SIZE) == 0);
538
539 /*
540 * If disk quotas is on, we make sure that the dquots do exist on disk,
541 * before we start any other transactions. Trying to do this later
542 * is messy. We don't care to take a readlock to look at the ids
543 * in inode here, because we can't hold it across the trans_reserve.
544 * If the IDs do change before we take the ilock, we're covered
545 * because the i_*dquot fields will get updated anyway.
546 */
547 if (XFS_IS_QUOTA_ON(mp) && (mask & (ATTR_UID|ATTR_GID))) {
548 uint qflags = 0;
549
550 if ((mask & ATTR_UID) && XFS_IS_UQUOTA_ON(mp)) {
551 uid = iattr->ia_uid;
552 qflags |= XFS_QMOPT_UQUOTA;
553 } else {
554 uid = ip->i_d.di_uid;
555 }
556 if ((mask & ATTR_GID) && XFS_IS_GQUOTA_ON(mp)) {
557 gid = iattr->ia_gid;
558 qflags |= XFS_QMOPT_GQUOTA;
559 } else {
560 gid = ip->i_d.di_gid;
561 }
562
563 /*
564 * We take a reference when we initialize udqp and gdqp,
565 * so it is important that we never blindly double trip on
566 * the same variable. See xfs_create() for an example.
567 */
568 ASSERT(udqp == NULL);
569 ASSERT(gdqp == NULL);
570 error = xfs_qm_vop_dqalloc(ip, uid, gid, xfs_get_projid(ip),
571 qflags, &udqp, &gdqp);
572 if (error)
573 return error;
574 }
575
576 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
577 error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0);
578 if (error)
579 goto out_dqrele;
580
581 xfs_ilock(ip, XFS_ILOCK_EXCL);
582
583 /*
584 * Change file ownership. Must be the owner or privileged.
585 */
586 if (mask & (ATTR_UID|ATTR_GID)) {
587 /*
588 * These IDs could have changed since we last looked at them.
589 * But, we're assured that if the ownership did change
590 * while we didn't have the inode locked, inode's dquot(s)
591 * would have changed also.
592 */
593 iuid = ip->i_d.di_uid;
594 igid = ip->i_d.di_gid;
595 gid = (mask & ATTR_GID) ? iattr->ia_gid : igid;
596 uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid;
597
598 /*
599 * Do a quota reservation only if uid/gid is actually
600 * going to change.
601 */
602 if (XFS_IS_QUOTA_RUNNING(mp) &&
603 ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
604 (XFS_IS_GQUOTA_ON(mp) && igid != gid))) {
605 ASSERT(tp);
606 error = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
607 capable(CAP_FOWNER) ?
608 XFS_QMOPT_FORCE_RES : 0);
609 if (error) /* out of quota */
610 goto out_trans_cancel;
611 }
612 }
613
614 xfs_trans_ijoin(tp, ip);
615
616 /*
617 * Change file ownership. Must be the owner or privileged.
618 */
619 if (mask & (ATTR_UID|ATTR_GID)) {
620 /*
621 * CAP_FSETID overrides the following restrictions:
622 *
623 * The set-user-ID and set-group-ID bits of a file will be
624 * cleared upon successful return from chown()
625 */
626 if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
627 !capable(CAP_FSETID))
628 ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
629
630 /*
631 * Change the ownerships and register quota modifications
632 * in the transaction.
633 */
634 if (iuid != uid) {
635 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) {
636 ASSERT(mask & ATTR_UID);
637 ASSERT(udqp);
638 olddquot1 = xfs_qm_vop_chown(tp, ip,
639 &ip->i_udquot, udqp);
640 }
641 ip->i_d.di_uid = uid;
642 inode->i_uid = uid;
643 }
644 if (igid != gid) {
645 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) {
646 ASSERT(!XFS_IS_PQUOTA_ON(mp));
647 ASSERT(mask & ATTR_GID);
648 ASSERT(gdqp);
649 olddquot2 = xfs_qm_vop_chown(tp, ip,
650 &ip->i_gdquot, gdqp);
651 }
652 ip->i_d.di_gid = gid;
653 inode->i_gid = gid;
654 }
655 }
656
657 /*
658 * Change file access modes.
659 */
660 if (mask & ATTR_MODE) {
661 umode_t mode = iattr->ia_mode;
662
663 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
664 mode &= ~S_ISGID;
665
666 ip->i_d.di_mode &= S_IFMT;
667 ip->i_d.di_mode |= mode & ~S_IFMT;
668
669 inode->i_mode &= S_IFMT;
670 inode->i_mode |= mode & ~S_IFMT;
671 }
672
673 /*
674 * Change file access or modified times.
675 */
676 if (mask & ATTR_ATIME) {
677 inode->i_atime = iattr->ia_atime;
678 ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
679 ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
680 ip->i_update_core = 1;
681 }
682 if (mask & ATTR_CTIME) {
683 inode->i_ctime = iattr->ia_ctime;
684 ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
685 ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
686 ip->i_update_core = 1;
687 }
688 if (mask & ATTR_MTIME) {
689 inode->i_mtime = iattr->ia_mtime;
690 ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
691 ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
692 ip->i_update_core = 1;
693 }
694
695 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
696
697 XFS_STATS_INC(xs_ig_attrchg);
698
699 if (mp->m_flags & XFS_MOUNT_WSYNC)
700 xfs_trans_set_sync(tp);
701 error = xfs_trans_commit(tp, 0);
702
703 xfs_iunlock(ip, XFS_ILOCK_EXCL);
704
705 /*
706 * Release any dquot(s) the inode had kept before chown.
707 */
708 xfs_qm_dqrele(olddquot1);
709 xfs_qm_dqrele(olddquot2);
710 xfs_qm_dqrele(udqp);
711 xfs_qm_dqrele(gdqp);
712
713 if (error)
714 return XFS_ERROR(error);
715
716 /*
717 * XXX(hch): Updating the ACL entries is not atomic vs the i_mode
718 * update. We could avoid this with linked transactions
719 * and passing down the transaction pointer all the way
720 * to attr_set. No previous user of the generic
721 * Posix ACL code seems to care about this issue either.
722 */
723 if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) {
724 error = -xfs_acl_chmod(inode);
725 if (error)
726 return XFS_ERROR(error);
727 }
728
729 return 0;
730
731out_trans_cancel:
732 xfs_trans_cancel(tp, 0);
733 xfs_iunlock(ip, XFS_ILOCK_EXCL);
734out_dqrele:
735 xfs_qm_dqrele(udqp);
736 xfs_qm_dqrele(gdqp);
737 return error;
738}
739
740/*
741 * Truncate file. Must have write permission and not be a directory.
742 */
743int
744xfs_setattr_size(
745 struct xfs_inode *ip,
746 struct iattr *iattr,
747 int flags)
748{
749 struct xfs_mount *mp = ip->i_mount;
750 struct inode *inode = VFS_I(ip);
751 int mask = iattr->ia_valid;
752 struct xfs_trans *tp;
753 int error;
754 uint lock_flags;
755 uint commit_flags = 0;
756
757 trace_xfs_setattr(ip);
758
759 if (mp->m_flags & XFS_MOUNT_RDONLY)
760 return XFS_ERROR(EROFS);
761
762 if (XFS_FORCED_SHUTDOWN(mp))
763 return XFS_ERROR(EIO);
764
765 error = -inode_change_ok(inode, iattr);
766 if (error)
767 return XFS_ERROR(error);
768
769 ASSERT(S_ISREG(ip->i_d.di_mode));
770 ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
771 ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID|
772 ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
773
774 lock_flags = XFS_ILOCK_EXCL;
775 if (!(flags & XFS_ATTR_NOLOCK))
776 lock_flags |= XFS_IOLOCK_EXCL;
777 xfs_ilock(ip, lock_flags);
778
779 /*
780 * Short circuit the truncate case for zero length files.
781 */
782 if (iattr->ia_size == 0 &&
783 ip->i_size == 0 && ip->i_d.di_nextents == 0) {
784 if (!(mask & (ATTR_CTIME|ATTR_MTIME)))
785 goto out_unlock;
786
787 /*
788 * Use the regular setattr path to update the timestamps.
789 */
790 xfs_iunlock(ip, lock_flags);
791 iattr->ia_valid &= ~ATTR_SIZE;
792 return xfs_setattr_nonsize(ip, iattr, 0);
793 }
794
795 /*
796 * Make sure that the dquots are attached to the inode.
797 */
798 error = xfs_qm_dqattach_locked(ip, 0);
799 if (error)
800 goto out_unlock;
801
802 /*
803 * Now we can make the changes. Before we join the inode to the
804 * transaction, take care of the part of the truncation that must be
805 * done without the inode lock. This needs to be done before joining
806 * the inode to the transaction, because the inode cannot be unlocked
807 * once it is a part of the transaction.
808 */
809 if (iattr->ia_size > ip->i_size) {
810 /*
811 * Do the first part of growing a file: zero any data in the
812 * last block that is beyond the old EOF. We need to do this
813 * before the inode is joined to the transaction to modify
814 * i_size.
815 */
816 error = xfs_zero_eof(ip, iattr->ia_size, ip->i_size);
817 if (error)
818 goto out_unlock;
819 }
820 xfs_iunlock(ip, XFS_ILOCK_EXCL);
821 lock_flags &= ~XFS_ILOCK_EXCL;
822
823 /*
824 * We are going to log the inode size change in this transaction so
825 * any previous writes that are beyond the on disk EOF and the new
826 * EOF that have not been written out need to be written here. If we
827 * do not write the data out, we expose ourselves to the null files
828 * problem.
829 *
830 * Only flush from the on disk size to the smaller of the in memory
831 * file size or the new size as that's the range we really care about
832 * here and prevents waiting for other data not within the range we
833 * care about here.
834 */
835 if (ip->i_size != ip->i_d.di_size && iattr->ia_size > ip->i_d.di_size) {
836 error = xfs_flush_pages(ip, ip->i_d.di_size, iattr->ia_size,
837 XBF_ASYNC, FI_NONE);
838 if (error)
839 goto out_unlock;
840 }
841
842 /*
843 * Wait for all I/O to complete.
844 */
845 xfs_ioend_wait(ip);
846
847 error = -block_truncate_page(inode->i_mapping, iattr->ia_size,
848 xfs_get_blocks);
849 if (error)
850 goto out_unlock;
851
852 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE);
853 error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
854 XFS_TRANS_PERM_LOG_RES,
855 XFS_ITRUNCATE_LOG_COUNT);
856 if (error)
857 goto out_trans_cancel;
858
859 truncate_setsize(inode, iattr->ia_size);
860
861 commit_flags = XFS_TRANS_RELEASE_LOG_RES;
862 lock_flags |= XFS_ILOCK_EXCL;
863
864 xfs_ilock(ip, XFS_ILOCK_EXCL);
865
866 xfs_trans_ijoin(tp, ip);
867
868 /*
869 * Only change the c/mtime if we are changing the size or we are
870 * explicitly asked to change it. This handles the semantic difference
871 * between truncate() and ftruncate() as implemented in the VFS.
872 *
873 * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a
874 * special case where we need to update the times despite not having
875 * these flags set. For all other operations the VFS set these flags
876 * explicitly if it wants a timestamp update.
877 */
878 if (iattr->ia_size != ip->i_size &&
879 (!(mask & (ATTR_CTIME | ATTR_MTIME)))) {
880 iattr->ia_ctime = iattr->ia_mtime =
881 current_fs_time(inode->i_sb);
882 mask |= ATTR_CTIME | ATTR_MTIME;
883 }
884
885 if (iattr->ia_size > ip->i_size) {
886 ip->i_d.di_size = iattr->ia_size;
887 ip->i_size = iattr->ia_size;
888 } else if (iattr->ia_size <= ip->i_size ||
889 (iattr->ia_size == 0 && ip->i_d.di_nextents)) {
890 error = xfs_itruncate_data(&tp, ip, iattr->ia_size);
891 if (error)
892 goto out_trans_abort;
893
894 /*
895 * Truncated "down", so we're removing references to old data
896 * here - if we delay flushing for a long time, we expose
897 * ourselves unduly to the notorious NULL files problem. So,
898 * we mark this inode and flush it when the file is closed,
899 * and do not wait the usual (long) time for writeout.
900 */
901 xfs_iflags_set(ip, XFS_ITRUNCATED);
902 }
903
904 if (mask & ATTR_CTIME) {
905 inode->i_ctime = iattr->ia_ctime;
906 ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
907 ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
908 ip->i_update_core = 1;
909 }
910 if (mask & ATTR_MTIME) {
911 inode->i_mtime = iattr->ia_mtime;
912 ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
913 ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
914 ip->i_update_core = 1;
915 }
916
917 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
918
919 XFS_STATS_INC(xs_ig_attrchg);
920
921 if (mp->m_flags & XFS_MOUNT_WSYNC)
922 xfs_trans_set_sync(tp);
923
924 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
925out_unlock:
926 if (lock_flags)
927 xfs_iunlock(ip, lock_flags);
928 return error;
929
930out_trans_abort:
931 commit_flags |= XFS_TRANS_ABORT;
932out_trans_cancel:
933 xfs_trans_cancel(tp, commit_flags);
934 goto out_unlock;
935}
936
500STATIC int 937STATIC int
501xfs_vn_setattr( 938xfs_vn_setattr(
502 struct dentry *dentry, 939 struct dentry *dentry,
503 struct iattr *iattr) 940 struct iattr *iattr)
504{ 941{
505 return -xfs_setattr(XFS_I(dentry->d_inode), iattr, 0); 942 if (iattr->ia_valid & ATTR_SIZE)
943 return -xfs_setattr_size(XFS_I(dentry->d_inode), iattr, 0);
944 return -xfs_setattr_nonsize(XFS_I(dentry->d_inode), iattr, 0);
506} 945}
507 946
508#define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR) 947#define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR)
@@ -591,7 +1030,7 @@ xfs_vn_fiemap(
591} 1030}
592 1031
593static const struct inode_operations xfs_inode_operations = { 1032static const struct inode_operations xfs_inode_operations = {
594 .check_acl = xfs_check_acl, 1033 .get_acl = xfs_get_acl,
595 .getattr = xfs_vn_getattr, 1034 .getattr = xfs_vn_getattr,
596 .setattr = xfs_vn_setattr, 1035 .setattr = xfs_vn_setattr,
597 .setxattr = generic_setxattr, 1036 .setxattr = generic_setxattr,
@@ -617,7 +1056,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
617 .rmdir = xfs_vn_unlink, 1056 .rmdir = xfs_vn_unlink,
618 .mknod = xfs_vn_mknod, 1057 .mknod = xfs_vn_mknod,
619 .rename = xfs_vn_rename, 1058 .rename = xfs_vn_rename,
620 .check_acl = xfs_check_acl, 1059 .get_acl = xfs_get_acl,
621 .getattr = xfs_vn_getattr, 1060 .getattr = xfs_vn_getattr,
622 .setattr = xfs_vn_setattr, 1061 .setattr = xfs_vn_setattr,
623 .setxattr = generic_setxattr, 1062 .setxattr = generic_setxattr,
@@ -642,7 +1081,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
642 .rmdir = xfs_vn_unlink, 1081 .rmdir = xfs_vn_unlink,
643 .mknod = xfs_vn_mknod, 1082 .mknod = xfs_vn_mknod,
644 .rename = xfs_vn_rename, 1083 .rename = xfs_vn_rename,
645 .check_acl = xfs_check_acl, 1084 .get_acl = xfs_get_acl,
646 .getattr = xfs_vn_getattr, 1085 .getattr = xfs_vn_getattr,
647 .setattr = xfs_vn_setattr, 1086 .setattr = xfs_vn_setattr,
648 .setxattr = generic_setxattr, 1087 .setxattr = generic_setxattr,
@@ -655,7 +1094,7 @@ static const struct inode_operations xfs_symlink_inode_operations = {
655 .readlink = generic_readlink, 1094 .readlink = generic_readlink,
656 .follow_link = xfs_vn_follow_link, 1095 .follow_link = xfs_vn_follow_link,
657 .put_link = xfs_vn_put_link, 1096 .put_link = xfs_vn_put_link,
658 .check_acl = xfs_check_acl, 1097 .get_acl = xfs_get_acl,
659 .getattr = xfs_vn_getattr, 1098 .getattr = xfs_vn_getattr,
660 .setattr = xfs_vn_setattr, 1099 .setattr = xfs_vn_setattr,
661 .setxattr = generic_setxattr, 1100 .setxattr = generic_setxattr,
@@ -763,6 +1202,15 @@ xfs_setup_inode(
763 break; 1202 break;
764 } 1203 }
765 1204
1205 /*
1206 * If there is no attribute fork no ACL can exist on this inode,
1207 * and it can't have any file capabilities attached to it either.
1208 */
1209 if (!XFS_IFORK_Q(ip)) {
1210 inode_has_no_xattr(inode);
1211 cache_no_acl(inode);
1212 }
1213
766 xfs_iflags_clear(ip, XFS_INEW); 1214 xfs_iflags_clear(ip, XFS_INEW);
767 barrier(); 1215 barrier();
768 1216
diff --git a/fs/xfs/linux-2.6/xfs_iops.h b/fs/xfs/xfs_iops.h
index ef41c92ce66..ef41c92ce66 100644
--- a/fs/xfs/linux-2.6/xfs_iops.h
+++ b/fs/xfs/xfs_iops.h
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/xfs_linux.h
index 8633521b3b2..828662f70d6 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -32,14 +32,12 @@
32# define XFS_BIG_INUMS 0 32# define XFS_BIG_INUMS 0
33#endif 33#endif
34 34
35#include <xfs_types.h> 35#include "xfs_types.h"
36#include <xfs_arch.h>
37 36
38#include <kmem.h> 37#include "kmem.h"
39#include <mrlock.h> 38#include "mrlock.h"
40#include <time.h> 39#include "time.h"
41 40#include "uuid.h"
42#include <support/uuid.h>
43 41
44#include <linux/semaphore.h> 42#include <linux/semaphore.h>
45#include <linux/mm.h> 43#include <linux/mm.h>
@@ -70,6 +68,8 @@
70#include <linux/ctype.h> 68#include <linux/ctype.h>
71#include <linux/writeback.h> 69#include <linux/writeback.h>
72#include <linux/capability.h> 70#include <linux/capability.h>
71#include <linux/kthread.h>
72#include <linux/freezer.h>
73#include <linux/list_sort.h> 73#include <linux/list_sort.h>
74 74
75#include <asm/page.h> 75#include <asm/page.h>
@@ -79,14 +79,20 @@
79#include <asm/byteorder.h> 79#include <asm/byteorder.h>
80#include <asm/unaligned.h> 80#include <asm/unaligned.h>
81 81
82#include <xfs_vnode.h> 82#include "xfs_vnode.h"
83#include <xfs_stats.h> 83#include "xfs_stats.h"
84#include <xfs_sysctl.h> 84#include "xfs_sysctl.h"
85#include <xfs_iops.h> 85#include "xfs_iops.h"
86#include <xfs_aops.h> 86#include "xfs_aops.h"
87#include <xfs_super.h> 87#include "xfs_super.h"
88#include <xfs_buf.h> 88#include "xfs_buf.h"
89#include <xfs_message.h> 89#include "xfs_message.h"
90
91#ifdef __BIG_ENDIAN
92#define XFS_NATIVE_HOST 1
93#else
94#undef XFS_NATIVE_HOST
95#endif
90 96
91/* 97/*
92 * Feature macros (disable/enable) 98 * Feature macros (disable/enable)
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 41d5b8f2bf9..3a8d4f66d70 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -871,20 +871,14 @@ xlog_space_left(
871void 871void
872xlog_iodone(xfs_buf_t *bp) 872xlog_iodone(xfs_buf_t *bp)
873{ 873{
874 xlog_in_core_t *iclog; 874 xlog_in_core_t *iclog = bp->b_fspriv;
875 xlog_t *l; 875 xlog_t *l = iclog->ic_log;
876 int aborted; 876 int aborted = 0;
877
878 iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *);
879 ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long) 2);
880 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
881 aborted = 0;
882 l = iclog->ic_log;
883 877
884 /* 878 /*
885 * Race to shutdown the filesystem if we see an error. 879 * Race to shutdown the filesystem if we see an error.
886 */ 880 */
887 if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp, 881 if (XFS_TEST_ERROR((xfs_buf_geterror(bp)), l->l_mp,
888 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { 882 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
889 xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp)); 883 xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
890 XFS_BUF_STALE(bp); 884 XFS_BUF_STALE(bp);
@@ -1056,10 +1050,8 @@ xlog_alloc_log(xfs_mount_t *mp,
1056 bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp); 1050 bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
1057 if (!bp) 1051 if (!bp)
1058 goto out_free_log; 1052 goto out_free_log;
1059 XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone); 1053 bp->b_iodone = xlog_iodone;
1060 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); 1054 ASSERT(xfs_buf_islocked(bp));
1061 ASSERT(XFS_BUF_ISBUSY(bp));
1062 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
1063 log->l_xbuf = bp; 1055 log->l_xbuf = bp;
1064 1056
1065 spin_lock_init(&log->l_icloglock); 1057 spin_lock_init(&log->l_icloglock);
@@ -1090,10 +1082,8 @@ xlog_alloc_log(xfs_mount_t *mp,
1090 log->l_iclog_size, 0); 1082 log->l_iclog_size, 0);
1091 if (!bp) 1083 if (!bp)
1092 goto out_free_iclog; 1084 goto out_free_iclog;
1093 if (!XFS_BUF_CPSEMA(bp)) 1085
1094 ASSERT(0); 1086 bp->b_iodone = xlog_iodone;
1095 XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
1096 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
1097 iclog->ic_bp = bp; 1087 iclog->ic_bp = bp;
1098 iclog->ic_data = bp->b_addr; 1088 iclog->ic_data = bp->b_addr;
1099#ifdef DEBUG 1089#ifdef DEBUG
@@ -1117,8 +1107,7 @@ xlog_alloc_log(xfs_mount_t *mp,
1117 iclog->ic_callback_tail = &(iclog->ic_callback); 1107 iclog->ic_callback_tail = &(iclog->ic_callback);
1118 iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize; 1108 iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize;
1119 1109
1120 ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp)); 1110 ASSERT(xfs_buf_islocked(iclog->ic_bp));
1121 ASSERT(XFS_BUF_VALUSEMA(iclog->ic_bp) <= 0);
1122 init_waitqueue_head(&iclog->ic_force_wait); 1111 init_waitqueue_head(&iclog->ic_force_wait);
1123 init_waitqueue_head(&iclog->ic_write_wait); 1112 init_waitqueue_head(&iclog->ic_write_wait);
1124 1113
@@ -1254,11 +1243,10 @@ STATIC int
1254xlog_bdstrat( 1243xlog_bdstrat(
1255 struct xfs_buf *bp) 1244 struct xfs_buf *bp)
1256{ 1245{
1257 struct xlog_in_core *iclog; 1246 struct xlog_in_core *iclog = bp->b_fspriv;
1258 1247
1259 iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *);
1260 if (iclog->ic_state & XLOG_STATE_IOERROR) { 1248 if (iclog->ic_state & XLOG_STATE_IOERROR) {
1261 XFS_BUF_ERROR(bp, EIO); 1249 xfs_buf_ioerror(bp, EIO);
1262 XFS_BUF_STALE(bp); 1250 XFS_BUF_STALE(bp);
1263 xfs_buf_ioend(bp, 0); 1251 xfs_buf_ioend(bp, 0);
1264 /* 1252 /*
@@ -1269,7 +1257,6 @@ xlog_bdstrat(
1269 return 0; 1257 return 0;
1270 } 1258 }
1271 1259
1272 bp->b_flags |= _XBF_RUN_QUEUES;
1273 xfs_buf_iorequest(bp); 1260 xfs_buf_iorequest(bp);
1274 return 0; 1261 return 0;
1275} 1262}
@@ -1351,8 +1338,6 @@ xlog_sync(xlog_t *log,
1351 } 1338 }
1352 1339
1353 bp = iclog->ic_bp; 1340 bp = iclog->ic_bp;
1354 ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1);
1355 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
1356 XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn))); 1341 XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn)));
1357 1342
1358 XFS_STATS_ADD(xs_log_blocks, BTOBB(count)); 1343 XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
@@ -1366,22 +1351,27 @@ xlog_sync(xlog_t *log,
1366 iclog->ic_bwritecnt = 1; 1351 iclog->ic_bwritecnt = 1;
1367 } 1352 }
1368 XFS_BUF_SET_COUNT(bp, count); 1353 XFS_BUF_SET_COUNT(bp, count);
1369 XFS_BUF_SET_FSPRIVATE(bp, iclog); /* save for later */ 1354 bp->b_fspriv = iclog;
1370 XFS_BUF_ZEROFLAGS(bp); 1355 XFS_BUF_ZEROFLAGS(bp);
1371 XFS_BUF_BUSY(bp);
1372 XFS_BUF_ASYNC(bp); 1356 XFS_BUF_ASYNC(bp);
1373 bp->b_flags |= XBF_LOG_BUFFER; 1357 bp->b_flags |= XBF_SYNCIO;
1374 1358
1375 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) { 1359 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) {
1360 bp->b_flags |= XBF_FUA;
1361
1376 /* 1362 /*
1377 * If we have an external log device, flush the data device 1363 * Flush the data device before flushing the log to make
1378 * before flushing the log to make sure all meta data 1364 * sure all meta data written back from the AIL actually made
1379 * written back from the AIL actually made it to disk 1365 * it to disk before stamping the new log tail LSN into the
1380 * before writing out the new log tail LSN in the log buffer. 1366 * log buffer. For an external log we need to issue the
1367 * flush explicitly, and unfortunately synchronously here;
1368 * for an internal log we can simply use the block layer
1369 * state machine for preflushes.
1381 */ 1370 */
1382 if (log->l_mp->m_logdev_targp != log->l_mp->m_ddev_targp) 1371 if (log->l_mp->m_logdev_targp != log->l_mp->m_ddev_targp)
1383 xfs_blkdev_issue_flush(log->l_mp->m_ddev_targp); 1372 xfs_blkdev_issue_flush(log->l_mp->m_ddev_targp);
1384 XFS_BUF_ORDERED(bp); 1373 else
1374 bp->b_flags |= XBF_FLUSH;
1385 } 1375 }
1386 1376
1387 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); 1377 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
@@ -1404,20 +1394,16 @@ xlog_sync(xlog_t *log,
1404 } 1394 }
1405 if (split) { 1395 if (split) {
1406 bp = iclog->ic_log->l_xbuf; 1396 bp = iclog->ic_log->l_xbuf;
1407 ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) ==
1408 (unsigned long)1);
1409 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
1410 XFS_BUF_SET_ADDR(bp, 0); /* logical 0 */ 1397 XFS_BUF_SET_ADDR(bp, 0); /* logical 0 */
1411 XFS_BUF_SET_PTR(bp, (xfs_caddr_t)((__psint_t)&(iclog->ic_header)+ 1398 xfs_buf_associate_memory(bp,
1412 (__psint_t)count), split); 1399 (char *)&iclog->ic_header + count, split);
1413 XFS_BUF_SET_FSPRIVATE(bp, iclog); 1400 bp->b_fspriv = iclog;
1414 XFS_BUF_ZEROFLAGS(bp); 1401 XFS_BUF_ZEROFLAGS(bp);
1415 XFS_BUF_BUSY(bp);
1416 XFS_BUF_ASYNC(bp); 1402 XFS_BUF_ASYNC(bp);
1417 bp->b_flags |= XBF_LOG_BUFFER; 1403 bp->b_flags |= XBF_SYNCIO;
1418 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) 1404 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
1419 XFS_BUF_ORDERED(bp); 1405 bp->b_flags |= XBF_FUA;
1420 dptr = XFS_BUF_PTR(bp); 1406 dptr = bp->b_addr;
1421 /* 1407 /*
1422 * Bump the cycle numbers at the start of each block 1408 * Bump the cycle numbers at the start of each block
1423 * since this part of the buffer is at the start of 1409 * since this part of the buffer is at the start of
@@ -3521,13 +3507,13 @@ xlog_verify_iclog(xlog_t *log,
3521 spin_unlock(&log->l_icloglock); 3507 spin_unlock(&log->l_icloglock);
3522 3508
3523 /* check log magic numbers */ 3509 /* check log magic numbers */
3524 if (be32_to_cpu(iclog->ic_header.h_magicno) != XLOG_HEADER_MAGIC_NUM) 3510 if (iclog->ic_header.h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
3525 xfs_emerg(log->l_mp, "%s: invalid magic num", __func__); 3511 xfs_emerg(log->l_mp, "%s: invalid magic num", __func__);
3526 3512
3527 ptr = (xfs_caddr_t) &iclog->ic_header; 3513 ptr = (xfs_caddr_t) &iclog->ic_header;
3528 for (ptr += BBSIZE; ptr < ((xfs_caddr_t)&iclog->ic_header) + count; 3514 for (ptr += BBSIZE; ptr < ((xfs_caddr_t)&iclog->ic_header) + count;
3529 ptr += BBSIZE) { 3515 ptr += BBSIZE) {
3530 if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM) 3516 if (*(__be32 *)ptr == cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
3531 xfs_emerg(log->l_mp, "%s: unexpected magic num", 3517 xfs_emerg(log->l_mp, "%s: unexpected magic num",
3532 __func__); 3518 __func__);
3533 } 3519 }
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 04142caedb2..a199dbcee7d 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -91,6 +91,8 @@ xlog_get_bp(
91 xlog_t *log, 91 xlog_t *log,
92 int nbblks) 92 int nbblks)
93{ 93{
94 struct xfs_buf *bp;
95
94 if (!xlog_buf_bbcount_valid(log, nbblks)) { 96 if (!xlog_buf_bbcount_valid(log, nbblks)) {
95 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer", 97 xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer",
96 nbblks); 98 nbblks);
@@ -118,8 +120,10 @@ xlog_get_bp(
118 nbblks += log->l_sectBBsize; 120 nbblks += log->l_sectBBsize;
119 nbblks = round_up(nbblks, log->l_sectBBsize); 121 nbblks = round_up(nbblks, log->l_sectBBsize);
120 122
121 return xfs_buf_get_uncached(log->l_mp->m_logdev_targp, 123 bp = xfs_buf_get_uncached(log->l_mp->m_logdev_targp, BBTOB(nbblks), 0);
122 BBTOB(nbblks), 0); 124 if (bp)
125 xfs_buf_unlock(bp);
126 return bp;
123} 127}
124 128
125STATIC void 129STATIC void
@@ -143,7 +147,7 @@ xlog_align(
143 xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); 147 xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1);
144 148
145 ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp)); 149 ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp));
146 return XFS_BUF_PTR(bp) + BBTOB(offset); 150 return bp->b_addr + BBTOB(offset);
147} 151}
148 152
149 153
@@ -174,9 +178,7 @@ xlog_bread_noalign(
174 178
175 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); 179 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
176 XFS_BUF_READ(bp); 180 XFS_BUF_READ(bp);
177 XFS_BUF_BUSY(bp);
178 XFS_BUF_SET_COUNT(bp, BBTOB(nbblks)); 181 XFS_BUF_SET_COUNT(bp, BBTOB(nbblks));
179 XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp);
180 182
181 xfsbdstrat(log->l_mp, bp); 183 xfsbdstrat(log->l_mp, bp);
182 error = xfs_buf_iowait(bp); 184 error = xfs_buf_iowait(bp);
@@ -216,18 +218,18 @@ xlog_bread_offset(
216 xfs_buf_t *bp, 218 xfs_buf_t *bp,
217 xfs_caddr_t offset) 219 xfs_caddr_t offset)
218{ 220{
219 xfs_caddr_t orig_offset = XFS_BUF_PTR(bp); 221 xfs_caddr_t orig_offset = bp->b_addr;
220 int orig_len = bp->b_buffer_length; 222 int orig_len = bp->b_buffer_length;
221 int error, error2; 223 int error, error2;
222 224
223 error = XFS_BUF_SET_PTR(bp, offset, BBTOB(nbblks)); 225 error = xfs_buf_associate_memory(bp, offset, BBTOB(nbblks));
224 if (error) 226 if (error)
225 return error; 227 return error;
226 228
227 error = xlog_bread_noalign(log, blk_no, nbblks, bp); 229 error = xlog_bread_noalign(log, blk_no, nbblks, bp);
228 230
229 /* must reset buffer pointer even on error */ 231 /* must reset buffer pointer even on error */
230 error2 = XFS_BUF_SET_PTR(bp, orig_offset, orig_len); 232 error2 = xfs_buf_associate_memory(bp, orig_offset, orig_len);
231 if (error) 233 if (error)
232 return error; 234 return error;
233 return error2; 235 return error2;
@@ -262,11 +264,9 @@ xlog_bwrite(
262 264
263 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); 265 XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
264 XFS_BUF_ZEROFLAGS(bp); 266 XFS_BUF_ZEROFLAGS(bp);
265 XFS_BUF_BUSY(bp); 267 xfs_buf_hold(bp);
266 XFS_BUF_HOLD(bp); 268 xfs_buf_lock(bp);
267 XFS_BUF_PSEMA(bp, PRIBIO);
268 XFS_BUF_SET_COUNT(bp, BBTOB(nbblks)); 269 XFS_BUF_SET_COUNT(bp, BBTOB(nbblks));
269 XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp);
270 270
271 if ((error = xfs_bwrite(log->l_mp, bp))) 271 if ((error = xfs_bwrite(log->l_mp, bp)))
272 xfs_ioerror_alert("xlog_bwrite", log->l_mp, 272 xfs_ioerror_alert("xlog_bwrite", log->l_mp,
@@ -300,14 +300,14 @@ xlog_header_check_recover(
300 xfs_mount_t *mp, 300 xfs_mount_t *mp,
301 xlog_rec_header_t *head) 301 xlog_rec_header_t *head)
302{ 302{
303 ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM); 303 ASSERT(head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM));
304 304
305 /* 305 /*
306 * IRIX doesn't write the h_fmt field and leaves it zeroed 306 * IRIX doesn't write the h_fmt field and leaves it zeroed
307 * (XLOG_FMT_UNKNOWN). This stops us from trying to recover 307 * (XLOG_FMT_UNKNOWN). This stops us from trying to recover
308 * a dirty log created in IRIX. 308 * a dirty log created in IRIX.
309 */ 309 */
310 if (unlikely(be32_to_cpu(head->h_fmt) != XLOG_FMT)) { 310 if (unlikely(head->h_fmt != cpu_to_be32(XLOG_FMT))) {
311 xfs_warn(mp, 311 xfs_warn(mp,
312 "dirty log written in incompatible format - can't recover"); 312 "dirty log written in incompatible format - can't recover");
313 xlog_header_check_dump(mp, head); 313 xlog_header_check_dump(mp, head);
@@ -333,7 +333,7 @@ xlog_header_check_mount(
333 xfs_mount_t *mp, 333 xfs_mount_t *mp,
334 xlog_rec_header_t *head) 334 xlog_rec_header_t *head)
335{ 335{
336 ASSERT(be32_to_cpu(head->h_magicno) == XLOG_HEADER_MAGIC_NUM); 336 ASSERT(head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM));
337 337
338 if (uuid_is_nil(&head->h_fs_uuid)) { 338 if (uuid_is_nil(&head->h_fs_uuid)) {
339 /* 339 /*
@@ -356,7 +356,7 @@ STATIC void
356xlog_recover_iodone( 356xlog_recover_iodone(
357 struct xfs_buf *bp) 357 struct xfs_buf *bp)
358{ 358{
359 if (XFS_BUF_GETERROR(bp)) { 359 if (bp->b_error) {
360 /* 360 /*
361 * We're not going to bother about retrying 361 * We're not going to bother about retrying
362 * this during recovery. One strike! 362 * this during recovery. One strike!
@@ -367,7 +367,7 @@ xlog_recover_iodone(
367 xfs_force_shutdown(bp->b_target->bt_mount, 367 xfs_force_shutdown(bp->b_target->bt_mount,
368 SHUTDOWN_META_IO_ERROR); 368 SHUTDOWN_META_IO_ERROR);
369 } 369 }
370 XFS_BUF_CLR_IODONE_FUNC(bp); 370 bp->b_iodone = NULL;
371 xfs_buf_ioend(bp, 0); 371 xfs_buf_ioend(bp, 0);
372} 372}
373 373
@@ -534,7 +534,7 @@ xlog_find_verify_log_record(
534 534
535 head = (xlog_rec_header_t *)offset; 535 head = (xlog_rec_header_t *)offset;
536 536
537 if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(head->h_magicno)) 537 if (head->h_magicno == cpu_to_be32(XLOG_HEADER_MAGIC_NUM))
538 break; 538 break;
539 539
540 if (!smallmem) 540 if (!smallmem)
@@ -916,7 +916,7 @@ xlog_find_tail(
916 if (error) 916 if (error)
917 goto done; 917 goto done;
918 918
919 if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) { 919 if (*(__be32 *)offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
920 found = 1; 920 found = 1;
921 break; 921 break;
922 } 922 }
@@ -933,8 +933,8 @@ xlog_find_tail(
933 if (error) 933 if (error)
934 goto done; 934 goto done;
935 935
936 if (XLOG_HEADER_MAGIC_NUM == 936 if (*(__be32 *)offset ==
937 be32_to_cpu(*(__be32 *)offset)) { 937 cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) {
938 found = 2; 938 found = 2;
939 break; 939 break;
940 } 940 }
@@ -1258,7 +1258,7 @@ xlog_write_log_records(
1258 */ 1258 */
1259 ealign = round_down(end_block, sectbb); 1259 ealign = round_down(end_block, sectbb);
1260 if (j == 0 && (start_block + endcount > ealign)) { 1260 if (j == 0 && (start_block + endcount > ealign)) {
1261 offset = XFS_BUF_PTR(bp) + BBTOB(ealign - start_block); 1261 offset = bp->b_addr + BBTOB(ealign - start_block);
1262 error = xlog_bread_offset(log, ealign, sectbb, 1262 error = xlog_bread_offset(log, ealign, sectbb,
1263 bp, offset); 1263 bp, offset);
1264 if (error) 1264 if (error)
@@ -1947,7 +1947,7 @@ xfs_qm_dqcheck(
1947 * This is all fine; things are still consistent, and we haven't lost 1947 * This is all fine; things are still consistent, and we haven't lost
1948 * any quota information. Just don't complain about bad dquot blks. 1948 * any quota information. Just don't complain about bad dquot blks.
1949 */ 1949 */
1950 if (be16_to_cpu(ddq->d_magic) != XFS_DQUOT_MAGIC) { 1950 if (ddq->d_magic != cpu_to_be16(XFS_DQUOT_MAGIC)) {
1951 if (flags & XFS_QMOPT_DOWARN) 1951 if (flags & XFS_QMOPT_DOWARN)
1952 xfs_alert(mp, 1952 xfs_alert(mp,
1953 "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x", 1953 "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x",
@@ -2131,15 +2131,16 @@ xlog_recover_buffer_pass2(
2131 2131
2132 bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len, 2132 bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len,
2133 buf_flags); 2133 buf_flags);
2134 if (XFS_BUF_ISERROR(bp)) { 2134 if (!bp)
2135 return XFS_ERROR(ENOMEM);
2136 error = bp->b_error;
2137 if (error) {
2135 xfs_ioerror_alert("xlog_recover_do..(read#1)", mp, 2138 xfs_ioerror_alert("xlog_recover_do..(read#1)", mp,
2136 bp, buf_f->blf_blkno); 2139 bp, buf_f->blf_blkno);
2137 error = XFS_BUF_GETERROR(bp);
2138 xfs_buf_relse(bp); 2140 xfs_buf_relse(bp);
2139 return error; 2141 return error;
2140 } 2142 }
2141 2143
2142 error = 0;
2143 if (buf_f->blf_flags & XFS_BLF_INODE_BUF) { 2144 if (buf_f->blf_flags & XFS_BLF_INODE_BUF) {
2144 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); 2145 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
2145 } else if (buf_f->blf_flags & 2146 } else if (buf_f->blf_flags &
@@ -2174,7 +2175,7 @@ xlog_recover_buffer_pass2(
2174 error = xfs_bwrite(mp, bp); 2175 error = xfs_bwrite(mp, bp);
2175 } else { 2176 } else {
2176 ASSERT(bp->b_target->bt_mount == mp); 2177 ASSERT(bp->b_target->bt_mount == mp);
2177 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone); 2178 bp->b_iodone = xlog_recover_iodone;
2178 xfs_bdwrite(mp, bp); 2179 xfs_bdwrite(mp, bp);
2179 } 2180 }
2180 2181
@@ -2223,14 +2224,17 @@ xlog_recover_inode_pass2(
2223 2224
2224 bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, 2225 bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len,
2225 XBF_LOCK); 2226 XBF_LOCK);
2226 if (XFS_BUF_ISERROR(bp)) { 2227 if (!bp) {
2228 error = ENOMEM;
2229 goto error;
2230 }
2231 error = bp->b_error;
2232 if (error) {
2227 xfs_ioerror_alert("xlog_recover_do..(read#2)", mp, 2233 xfs_ioerror_alert("xlog_recover_do..(read#2)", mp,
2228 bp, in_f->ilf_blkno); 2234 bp, in_f->ilf_blkno);
2229 error = XFS_BUF_GETERROR(bp);
2230 xfs_buf_relse(bp); 2235 xfs_buf_relse(bp);
2231 goto error; 2236 goto error;
2232 } 2237 }
2233 error = 0;
2234 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE); 2238 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
2235 dip = (xfs_dinode_t *)xfs_buf_offset(bp, in_f->ilf_boffset); 2239 dip = (xfs_dinode_t *)xfs_buf_offset(bp, in_f->ilf_boffset);
2236 2240
@@ -2238,7 +2242,7 @@ xlog_recover_inode_pass2(
2238 * Make sure the place we're flushing out to really looks 2242 * Make sure the place we're flushing out to really looks
2239 * like an inode! 2243 * like an inode!
2240 */ 2244 */
2241 if (unlikely(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC)) { 2245 if (unlikely(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))) {
2242 xfs_buf_relse(bp); 2246 xfs_buf_relse(bp);
2243 xfs_alert(mp, 2247 xfs_alert(mp,
2244 "%s: Bad inode magic number, dip = 0x%p, dino bp = 0x%p, ino = %Ld", 2248 "%s: Bad inode magic number, dip = 0x%p, dino bp = 0x%p, ino = %Ld",
@@ -2279,7 +2283,7 @@ xlog_recover_inode_pass2(
2279 /* Take the opportunity to reset the flush iteration count */ 2283 /* Take the opportunity to reset the flush iteration count */
2280 dicp->di_flushiter = 0; 2284 dicp->di_flushiter = 0;
2281 2285
2282 if (unlikely((dicp->di_mode & S_IFMT) == S_IFREG)) { 2286 if (unlikely(S_ISREG(dicp->di_mode))) {
2283 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && 2287 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
2284 (dicp->di_format != XFS_DINODE_FMT_BTREE)) { 2288 (dicp->di_format != XFS_DINODE_FMT_BTREE)) {
2285 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)", 2289 XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)",
@@ -2292,7 +2296,7 @@ xlog_recover_inode_pass2(
2292 error = EFSCORRUPTED; 2296 error = EFSCORRUPTED;
2293 goto error; 2297 goto error;
2294 } 2298 }
2295 } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) { 2299 } else if (unlikely(S_ISDIR(dicp->di_mode))) {
2296 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && 2300 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
2297 (dicp->di_format != XFS_DINODE_FMT_BTREE) && 2301 (dicp->di_format != XFS_DINODE_FMT_BTREE) &&
2298 (dicp->di_format != XFS_DINODE_FMT_LOCAL)) { 2302 (dicp->di_format != XFS_DINODE_FMT_LOCAL)) {
@@ -2434,7 +2438,7 @@ xlog_recover_inode_pass2(
2434 2438
2435write_inode_buffer: 2439write_inode_buffer:
2436 ASSERT(bp->b_target->bt_mount == mp); 2440 ASSERT(bp->b_target->bt_mount == mp);
2437 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone); 2441 bp->b_iodone = xlog_recover_iodone;
2438 xfs_bdwrite(mp, bp); 2442 xfs_bdwrite(mp, bp);
2439error: 2443error:
2440 if (need_free) 2444 if (need_free)
@@ -2556,7 +2560,7 @@ xlog_recover_dquot_pass2(
2556 2560
2557 ASSERT(dq_f->qlf_size == 2); 2561 ASSERT(dq_f->qlf_size == 2);
2558 ASSERT(bp->b_target->bt_mount == mp); 2562 ASSERT(bp->b_target->bt_mount == mp);
2559 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone); 2563 bp->b_iodone = xlog_recover_iodone;
2560 xfs_bdwrite(mp, bp); 2564 xfs_bdwrite(mp, bp);
2561 2565
2562 return (0); 2566 return (0);
@@ -3295,7 +3299,7 @@ xlog_valid_rec_header(
3295{ 3299{
3296 int hlen; 3300 int hlen;
3297 3301
3298 if (unlikely(be32_to_cpu(rhead->h_magicno) != XLOG_HEADER_MAGIC_NUM)) { 3302 if (unlikely(rhead->h_magicno != cpu_to_be32(XLOG_HEADER_MAGIC_NUM))) {
3299 XFS_ERROR_REPORT("xlog_valid_rec_header(1)", 3303 XFS_ERROR_REPORT("xlog_valid_rec_header(1)",
3300 XFS_ERRLEVEL_LOW, log->l_mp); 3304 XFS_ERRLEVEL_LOW, log->l_mp);
3301 return XFS_ERROR(EFSCORRUPTED); 3305 return XFS_ERROR(EFSCORRUPTED);
@@ -3433,7 +3437,7 @@ xlog_do_recovery_pass(
3433 /* 3437 /*
3434 * Check for header wrapping around physical end-of-log 3438 * Check for header wrapping around physical end-of-log
3435 */ 3439 */
3436 offset = XFS_BUF_PTR(hbp); 3440 offset = hbp->b_addr;
3437 split_hblks = 0; 3441 split_hblks = 0;
3438 wrapped_hblks = 0; 3442 wrapped_hblks = 0;
3439 if (blk_no + hblks <= log->l_logBBsize) { 3443 if (blk_no + hblks <= log->l_logBBsize) {
@@ -3493,7 +3497,7 @@ xlog_do_recovery_pass(
3493 } else { 3497 } else {
3494 /* This log record is split across the 3498 /* This log record is split across the
3495 * physical end of log */ 3499 * physical end of log */
3496 offset = XFS_BUF_PTR(dbp); 3500 offset = dbp->b_addr;
3497 split_bblks = 0; 3501 split_bblks = 0;
3498 if (blk_no != log->l_logBBsize) { 3502 if (blk_no != log->l_logBBsize) {
3499 /* some data is before the physical 3503 /* some data is before the physical
diff --git a/fs/xfs/linux-2.6/xfs_message.c b/fs/xfs/xfs_message.c
index bd672def95a..bd672def95a 100644
--- a/fs/xfs/linux-2.6/xfs_message.c
+++ b/fs/xfs/xfs_message.c
diff --git a/fs/xfs/linux-2.6/xfs_message.h b/fs/xfs/xfs_message.h
index 7fb7ea00767..7fb7ea00767 100644
--- a/fs/xfs/linux-2.6/xfs_message.h
+++ b/fs/xfs/xfs_message.h
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index b49b82363d2..d4d5775d6e2 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -44,9 +44,6 @@
44#include "xfs_trace.h" 44#include "xfs_trace.h"
45 45
46 46
47STATIC void xfs_unmountfs_wait(xfs_mount_t *);
48
49
50#ifdef HAVE_PERCPU_SB 47#ifdef HAVE_PERCPU_SB
51STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, 48STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t,
52 int); 49 int);
@@ -348,7 +345,7 @@ xfs_mount_validate_sb(
348 } 345 }
349 346
350 /* 347 /*
351 * More sanity checking. These were stolen directly from 348 * More sanity checking. Most of these were stolen directly from
352 * xfs_repair. 349 * xfs_repair.
353 */ 350 */
354 if (unlikely( 351 if (unlikely(
@@ -371,23 +368,13 @@ xfs_mount_validate_sb(
371 (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) || 368 (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) ||
372 (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) || 369 (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
373 (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) || 370 (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
374 (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */))) { 371 (sbp->sb_imax_pct > 100 /* zero sb_imax_pct is valid */) ||
375 if (loud) 372 sbp->sb_dblocks == 0 ||
376 xfs_warn(mp, "SB sanity check 1 failed"); 373 sbp->sb_dblocks > XFS_MAX_DBLOCKS(sbp) ||
377 return XFS_ERROR(EFSCORRUPTED); 374 sbp->sb_dblocks < XFS_MIN_DBLOCKS(sbp))) {
378 }
379
380 /*
381 * Sanity check AG count, size fields against data size field
382 */
383 if (unlikely(
384 sbp->sb_dblocks == 0 ||
385 sbp->sb_dblocks >
386 (xfs_drfsbno_t)sbp->sb_agcount * sbp->sb_agblocks ||
387 sbp->sb_dblocks < (xfs_drfsbno_t)(sbp->sb_agcount - 1) *
388 sbp->sb_agblocks + XFS_MIN_AG_BLOCKS)) {
389 if (loud) 375 if (loud)
390 xfs_warn(mp, "SB sanity check 2 failed"); 376 XFS_CORRUPTION_ERROR("SB sanity check failed",
377 XFS_ERRLEVEL_LOW, mp, sbp);
391 return XFS_ERROR(EFSCORRUPTED); 378 return XFS_ERROR(EFSCORRUPTED);
392 } 379 }
393 380
@@ -864,7 +851,8 @@ xfs_update_alignment(xfs_mount_t *mp)
864 if ((BBTOB(mp->m_dalign) & mp->m_blockmask) || 851 if ((BBTOB(mp->m_dalign) & mp->m_blockmask) ||
865 (BBTOB(mp->m_swidth) & mp->m_blockmask)) { 852 (BBTOB(mp->m_swidth) & mp->m_blockmask)) {
866 if (mp->m_flags & XFS_MOUNT_RETERR) { 853 if (mp->m_flags & XFS_MOUNT_RETERR) {
867 xfs_warn(mp, "alignment check 1 failed"); 854 xfs_warn(mp, "alignment check failed: "
855 "(sunit/swidth vs. blocksize)");
868 return XFS_ERROR(EINVAL); 856 return XFS_ERROR(EINVAL);
869 } 857 }
870 mp->m_dalign = mp->m_swidth = 0; 858 mp->m_dalign = mp->m_swidth = 0;
@@ -875,6 +863,8 @@ xfs_update_alignment(xfs_mount_t *mp)
875 mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign); 863 mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);
876 if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) { 864 if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) {
877 if (mp->m_flags & XFS_MOUNT_RETERR) { 865 if (mp->m_flags & XFS_MOUNT_RETERR) {
866 xfs_warn(mp, "alignment check failed: "
867 "(sunit/swidth vs. ag size)");
878 return XFS_ERROR(EINVAL); 868 return XFS_ERROR(EINVAL);
879 } 869 }
880 xfs_warn(mp, 870 xfs_warn(mp,
@@ -889,8 +879,8 @@ xfs_update_alignment(xfs_mount_t *mp)
889 mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth); 879 mp->m_swidth = XFS_BB_TO_FSBT(mp, mp->m_swidth);
890 } else { 880 } else {
891 if (mp->m_flags & XFS_MOUNT_RETERR) { 881 if (mp->m_flags & XFS_MOUNT_RETERR) {
892 xfs_warn(mp, 882 xfs_warn(mp, "alignment check failed: "
893 "stripe alignment turned off: sunit(%d) less than bsize(%d)", 883 "sunit(%d) less than bsize(%d)",
894 mp->m_dalign, 884 mp->m_dalign,
895 mp->m_blockmask +1); 885 mp->m_blockmask +1);
896 return XFS_ERROR(EINVAL); 886 return XFS_ERROR(EINVAL);
@@ -1096,10 +1086,6 @@ xfs_mount_reset_sbqflags(
1096 if (mp->m_flags & XFS_MOUNT_RDONLY) 1086 if (mp->m_flags & XFS_MOUNT_RDONLY)
1097 return 0; 1087 return 0;
1098 1088
1099#ifdef QUOTADEBUG
1100 xfs_notice(mp, "Writing superblock quota changes");
1101#endif
1102
1103 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); 1089 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
1104 error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, 1090 error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
1105 XFS_DEFAULT_LOG_COUNT); 1091 XFS_DEFAULT_LOG_COUNT);
@@ -1342,7 +1328,7 @@ xfs_mountfs(
1342 1328
1343 ASSERT(rip != NULL); 1329 ASSERT(rip != NULL);
1344 1330
1345 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { 1331 if (unlikely(!S_ISDIR(rip->i_d.di_mode))) {
1346 xfs_warn(mp, "corrupted root inode %llu: not a directory", 1332 xfs_warn(mp, "corrupted root inode %llu: not a directory",
1347 (unsigned long long)rip->i_ino); 1333 (unsigned long long)rip->i_ino);
1348 xfs_iunlock(rip, XFS_ILOCK_EXCL); 1334 xfs_iunlock(rip, XFS_ILOCK_EXCL);
@@ -1507,11 +1493,6 @@ xfs_unmountfs(
1507 */ 1493 */
1508 xfs_log_force(mp, XFS_LOG_SYNC); 1494 xfs_log_force(mp, XFS_LOG_SYNC);
1509 1495
1510 xfs_binval(mp->m_ddev_targp);
1511 if (mp->m_rtdev_targp) {
1512 xfs_binval(mp->m_rtdev_targp);
1513 }
1514
1515 /* 1496 /*
1516 * Unreserve any blocks we have so that when we unmount we don't account 1497 * Unreserve any blocks we have so that when we unmount we don't account
1517 * the reserved free space as used. This is really only necessary for 1498 * the reserved free space as used. This is really only necessary for
@@ -1532,12 +1513,21 @@ xfs_unmountfs(
1532 xfs_warn(mp, "Unable to free reserved block pool. " 1513 xfs_warn(mp, "Unable to free reserved block pool. "
1533 "Freespace may not be correct on next mount."); 1514 "Freespace may not be correct on next mount.");
1534 1515
1535 error = xfs_log_sbcount(mp, 1); 1516 error = xfs_log_sbcount(mp);
1536 if (error) 1517 if (error)
1537 xfs_warn(mp, "Unable to update superblock counters. " 1518 xfs_warn(mp, "Unable to update superblock counters. "
1538 "Freespace may not be correct on next mount."); 1519 "Freespace may not be correct on next mount.");
1539 xfs_unmountfs_writesb(mp); 1520 xfs_unmountfs_writesb(mp);
1540 xfs_unmountfs_wait(mp); /* wait for async bufs */ 1521
1522 /*
1523 * Make sure all buffers have been flushed and completed before
1524 * unmounting the log.
1525 */
1526 error = xfs_flush_buftarg(mp->m_ddev_targp, 1);
1527 if (error)
1528 xfs_warn(mp, "%d busy buffers during unmount.", error);
1529 xfs_wait_buftarg(mp->m_ddev_targp);
1530
1541 xfs_log_unmount_write(mp); 1531 xfs_log_unmount_write(mp);
1542 xfs_log_unmount(mp); 1532 xfs_log_unmount(mp);
1543 xfs_uuid_unmount(mp); 1533 xfs_uuid_unmount(mp);
@@ -1548,16 +1538,6 @@ xfs_unmountfs(
1548 xfs_free_perag(mp); 1538 xfs_free_perag(mp);
1549} 1539}
1550 1540
1551STATIC void
1552xfs_unmountfs_wait(xfs_mount_t *mp)
1553{
1554 if (mp->m_logdev_targp != mp->m_ddev_targp)
1555 xfs_wait_buftarg(mp->m_logdev_targp);
1556 if (mp->m_rtdev_targp)
1557 xfs_wait_buftarg(mp->m_rtdev_targp);
1558 xfs_wait_buftarg(mp->m_ddev_targp);
1559}
1560
1561int 1541int
1562xfs_fs_writable(xfs_mount_t *mp) 1542xfs_fs_writable(xfs_mount_t *mp)
1563{ 1543{
@@ -1568,18 +1548,14 @@ xfs_fs_writable(xfs_mount_t *mp)
1568/* 1548/*
1569 * xfs_log_sbcount 1549 * xfs_log_sbcount
1570 * 1550 *
1571 * Called either periodically to keep the on disk superblock values 1551 * Sync the superblock counters to disk.
1572 * roughly up to date or from unmount to make sure the values are
1573 * correct on a clean unmount.
1574 * 1552 *
1575 * Note this code can be called during the process of freezing, so 1553 * Note this code can be called during the process of freezing, so
1576 * we may need to use the transaction allocator which does not not 1554 * we may need to use the transaction allocator which does not
1577 * block when the transaction subsystem is in its frozen state. 1555 * block when the transaction subsystem is in its frozen state.
1578 */ 1556 */
1579int 1557int
1580xfs_log_sbcount( 1558xfs_log_sbcount(xfs_mount_t *mp)
1581 xfs_mount_t *mp,
1582 uint sync)
1583{ 1559{
1584 xfs_trans_t *tp; 1560 xfs_trans_t *tp;
1585 int error; 1561 int error;
@@ -1605,8 +1581,7 @@ xfs_log_sbcount(
1605 } 1581 }
1606 1582
1607 xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS); 1583 xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS);
1608 if (sync) 1584 xfs_trans_set_sync(tp);
1609 xfs_trans_set_sync(tp);
1610 error = xfs_trans_commit(tp, 0); 1585 error = xfs_trans_commit(tp, 0);
1611 return error; 1586 return error;
1612} 1587}
@@ -1631,7 +1606,7 @@ xfs_unmountfs_writesb(xfs_mount_t *mp)
1631 XFS_BUF_UNDELAYWRITE(sbp); 1606 XFS_BUF_UNDELAYWRITE(sbp);
1632 XFS_BUF_WRITE(sbp); 1607 XFS_BUF_WRITE(sbp);
1633 XFS_BUF_UNASYNC(sbp); 1608 XFS_BUF_UNASYNC(sbp);
1634 ASSERT(XFS_BUF_TARGET(sbp) == mp->m_ddev_targp); 1609 ASSERT(sbp->b_target == mp->m_ddev_targp);
1635 xfsbdstrat(mp, sbp); 1610 xfsbdstrat(mp, sbp);
1636 error = xfs_buf_iowait(sbp); 1611 error = xfs_buf_iowait(sbp);
1637 if (error) 1612 if (error)
@@ -1941,23 +1916,20 @@ unwind:
1941 * the superblock buffer if it can be locked without sleeping. 1916 * the superblock buffer if it can be locked without sleeping.
1942 * If it can't then we'll return NULL. 1917 * If it can't then we'll return NULL.
1943 */ 1918 */
1944xfs_buf_t * 1919struct xfs_buf *
1945xfs_getsb( 1920xfs_getsb(
1946 xfs_mount_t *mp, 1921 struct xfs_mount *mp,
1947 int flags) 1922 int flags)
1948{ 1923{
1949 xfs_buf_t *bp; 1924 struct xfs_buf *bp = mp->m_sb_bp;
1950 1925
1951 ASSERT(mp->m_sb_bp != NULL); 1926 if (!xfs_buf_trylock(bp)) {
1952 bp = mp->m_sb_bp; 1927 if (flags & XBF_TRYLOCK)
1953 if (flags & XBF_TRYLOCK) {
1954 if (!XFS_BUF_CPSEMA(bp)) {
1955 return NULL; 1928 return NULL;
1956 } 1929 xfs_buf_lock(bp);
1957 } else {
1958 XFS_BUF_PSEMA(bp, PRIBIO);
1959 } 1930 }
1960 XFS_BUF_HOLD(bp); 1931
1932 xfs_buf_hold(bp);
1961 ASSERT(XFS_BUF_ISDONE(bp)); 1933 ASSERT(XFS_BUF_ISDONE(bp));
1962 return bp; 1934 return bp;
1963} 1935}
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 3d68bb267c5..bb24dac42a2 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -371,7 +371,7 @@ typedef struct xfs_mod_sb {
371 int64_t msb_delta; /* Change to make to specified field */ 371 int64_t msb_delta; /* Change to make to specified field */
372} xfs_mod_sb_t; 372} xfs_mod_sb_t;
373 373
374extern int xfs_log_sbcount(xfs_mount_t *, uint); 374extern int xfs_log_sbcount(xfs_mount_t *);
375extern __uint64_t xfs_default_resblks(xfs_mount_t *mp); 375extern __uint64_t xfs_default_resblks(xfs_mount_t *mp);
376extern int xfs_mountfs(xfs_mount_t *mp); 376extern int xfs_mountfs(xfs_mount_t *mp);
377 377
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/xfs_qm.c
index b94dace4e78..95ba6dc885a 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -67,32 +67,6 @@ static struct shrinker xfs_qm_shaker = {
67 .seeks = DEFAULT_SEEKS, 67 .seeks = DEFAULT_SEEKS,
68}; 68};
69 69
70#ifdef DEBUG
71extern struct mutex qcheck_lock;
72#endif
73
74#ifdef QUOTADEBUG
75static void
76xfs_qm_dquot_list_print(
77 struct xfs_mount *mp)
78{
79 xfs_dquot_t *dqp;
80 int i = 0;
81
82 list_for_each_entry(dqp, &mp->m_quotainfo->qi_dqlist_lock, qi_mplist) {
83 xfs_debug(mp, " %d. \"%d (%s)\" "
84 "bcnt = %lld, icnt = %lld, refs = %d",
85 i++, be32_to_cpu(dqp->q_core.d_id),
86 DQFLAGTO_TYPESTR(dqp),
87 (long long)be64_to_cpu(dqp->q_core.d_bcount),
88 (long long)be64_to_cpu(dqp->q_core.d_icount),
89 dqp->q_nrefs);
90 }
91}
92#else
93static void xfs_qm_dquot_list_print(struct xfs_mount *mp) { }
94#endif
95
96/* 70/*
97 * Initialize the XQM structure. 71 * Initialize the XQM structure.
98 * Note that there is not one quota manager per file system. 72 * Note that there is not one quota manager per file system.
@@ -165,9 +139,6 @@ xfs_Gqm_init(void)
165 atomic_set(&xqm->qm_totaldquots, 0); 139 atomic_set(&xqm->qm_totaldquots, 0);
166 xqm->qm_dqfree_ratio = XFS_QM_DQFREE_RATIO; 140 xqm->qm_dqfree_ratio = XFS_QM_DQFREE_RATIO;
167 xqm->qm_nrefs = 0; 141 xqm->qm_nrefs = 0;
168#ifdef DEBUG
169 mutex_init(&qcheck_lock);
170#endif
171 return xqm; 142 return xqm;
172 143
173 out_free_udqhash: 144 out_free_udqhash:
@@ -204,9 +175,6 @@ xfs_qm_destroy(
204 mutex_lock(&xqm->qm_dqfrlist_lock); 175 mutex_lock(&xqm->qm_dqfrlist_lock);
205 list_for_each_entry_safe(dqp, n, &xqm->qm_dqfrlist, q_freelist) { 176 list_for_each_entry_safe(dqp, n, &xqm->qm_dqfrlist, q_freelist) {
206 xfs_dqlock(dqp); 177 xfs_dqlock(dqp);
207#ifdef QUOTADEBUG
208 xfs_debug(dqp->q_mount, "FREELIST destroy 0x%p", dqp);
209#endif
210 list_del_init(&dqp->q_freelist); 178 list_del_init(&dqp->q_freelist);
211 xfs_Gqm->qm_dqfrlist_cnt--; 179 xfs_Gqm->qm_dqfrlist_cnt--;
212 xfs_dqunlock(dqp); 180 xfs_dqunlock(dqp);
@@ -214,9 +182,6 @@ xfs_qm_destroy(
214 } 182 }
215 mutex_unlock(&xqm->qm_dqfrlist_lock); 183 mutex_unlock(&xqm->qm_dqfrlist_lock);
216 mutex_destroy(&xqm->qm_dqfrlist_lock); 184 mutex_destroy(&xqm->qm_dqfrlist_lock);
217#ifdef DEBUG
218 mutex_destroy(&qcheck_lock);
219#endif
220 kmem_free(xqm); 185 kmem_free(xqm);
221} 186}
222 187
@@ -409,11 +374,6 @@ xfs_qm_mount_quotas(
409 xfs_warn(mp, "Failed to initialize disk quotas."); 374 xfs_warn(mp, "Failed to initialize disk quotas.");
410 return; 375 return;
411 } 376 }
412
413#ifdef QUOTADEBUG
414 if (XFS_IS_QUOTA_ON(mp))
415 xfs_qm_internalqcheck(mp);
416#endif
417} 377}
418 378
419/* 379/*
@@ -714,7 +674,8 @@ xfs_qm_dqattach_one(
714 * disk and we didn't ask it to allocate; 674 * disk and we didn't ask it to allocate;
715 * ESRCH if quotas got turned off suddenly. 675 * ESRCH if quotas got turned off suddenly.
716 */ 676 */
717 error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp); 677 error = xfs_qm_dqget(ip->i_mount, ip, id, type,
678 doalloc | XFS_QMOPT_DOWARN, &dqp);
718 if (error) 679 if (error)
719 return error; 680 return error;
720 681
@@ -866,8 +827,8 @@ xfs_qm_dqattach_locked(
866 } 827 }
867 828
868 done: 829 done:
869#ifdef QUOTADEBUG 830#ifdef DEBUG
870 if (! error) { 831 if (!error) {
871 if (XFS_IS_UQUOTA_ON(mp)) 832 if (XFS_IS_UQUOTA_ON(mp))
872 ASSERT(ip->i_udquot); 833 ASSERT(ip->i_udquot);
873 if (XFS_IS_OQUOTA_ON(mp)) 834 if (XFS_IS_OQUOTA_ON(mp))
@@ -1280,7 +1241,7 @@ xfs_qm_reset_dqcounts(
1280 do_div(j, sizeof(xfs_dqblk_t)); 1241 do_div(j, sizeof(xfs_dqblk_t));
1281 ASSERT(mp->m_quotainfo->qi_dqperchunk == j); 1242 ASSERT(mp->m_quotainfo->qi_dqperchunk == j);
1282#endif 1243#endif
1283 ddq = (xfs_disk_dquot_t *)XFS_BUF_PTR(bp); 1244 ddq = bp->b_addr;
1284 for (j = 0; j < mp->m_quotainfo->qi_dqperchunk; j++) { 1245 for (j = 0; j < mp->m_quotainfo->qi_dqperchunk; j++) {
1285 /* 1246 /*
1286 * Do a sanity check, and if needed, repair the dqblk. Don't 1247 * Do a sanity check, and if needed, repair the dqblk. Don't
@@ -1733,8 +1694,6 @@ xfs_qm_quotacheck(
1733 mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD); 1694 mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD);
1734 mp->m_qflags |= flags; 1695 mp->m_qflags |= flags;
1735 1696
1736 xfs_qm_dquot_list_print(mp);
1737
1738 error_return: 1697 error_return:
1739 if (error) { 1698 if (error) {
1740 xfs_warn(mp, 1699 xfs_warn(mp,
@@ -2096,9 +2055,6 @@ xfs_qm_write_sb_changes(
2096 xfs_trans_t *tp; 2055 xfs_trans_t *tp;
2097 int error; 2056 int error;
2098 2057
2099#ifdef QUOTADEBUG
2100 xfs_notice(mp, "Writing superblock quota changes");
2101#endif
2102 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); 2058 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE);
2103 if ((error = xfs_trans_reserve(tp, 0, 2059 if ((error = xfs_trans_reserve(tp, 0,
2104 mp->m_sb.sb_sectsize + 128, 0, 2060 mp->m_sb.sb_sectsize + 128, 0,
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/xfs_qm.h
index 567b29b9f1b..43b9abe1052 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/xfs_qm.h
@@ -163,10 +163,4 @@ extern int xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
163extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint); 163extern int xfs_qm_scall_quotaon(xfs_mount_t *, uint);
164extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint); 164extern int xfs_qm_scall_quotaoff(xfs_mount_t *, uint);
165 165
166#ifdef DEBUG
167extern int xfs_qm_internalqcheck(xfs_mount_t *);
168#else
169#define xfs_qm_internalqcheck(mp) (0)
170#endif
171
172#endif /* __XFS_QM_H__ */ 166#endif /* __XFS_QM_H__ */
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c
index a0a829addca..a0a829addca 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/xfs_qm_bhv.c
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/xfs_qm_stats.c
index 8671a0b3264..8671a0b3264 100644
--- a/fs/xfs/quota/xfs_qm_stats.c
+++ b/fs/xfs/xfs_qm_stats.c
diff --git a/fs/xfs/quota/xfs_qm_stats.h b/fs/xfs/xfs_qm_stats.h
index 5b964fc0dc0..5b964fc0dc0 100644
--- a/fs/xfs/quota/xfs_qm_stats.h
+++ b/fs/xfs/xfs_qm_stats.h
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 2dadb15d5ca..609246f42e6 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -263,7 +263,7 @@ xfs_qm_scall_trunc_qfile(
263 xfs_ilock(ip, XFS_ILOCK_EXCL); 263 xfs_ilock(ip, XFS_ILOCK_EXCL);
264 xfs_trans_ijoin(tp, ip); 264 xfs_trans_ijoin(tp, ip);
265 265
266 error = xfs_itruncate_finish(&tp, ip, 0, XFS_DATA_FORK, 1); 266 error = xfs_itruncate_data(&tp, ip, 0);
267 if (error) { 267 if (error) {
268 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | 268 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
269 XFS_TRANS_ABORT); 269 XFS_TRANS_ABORT);
@@ -622,7 +622,6 @@ xfs_qm_scall_setqlim(
622 xfs_trans_log_dquot(tp, dqp); 622 xfs_trans_log_dquot(tp, dqp);
623 623
624 error = xfs_trans_commit(tp, 0); 624 error = xfs_trans_commit(tp, 0);
625 xfs_qm_dqprint(dqp);
626 xfs_qm_dqrele(dqp); 625 xfs_qm_dqrele(dqp);
627 626
628 out_unlock: 627 out_unlock:
@@ -657,7 +656,6 @@ xfs_qm_scall_getquota(
657 xfs_qm_dqput(dqp); 656 xfs_qm_dqput(dqp);
658 return XFS_ERROR(ENOENT); 657 return XFS_ERROR(ENOENT);
659 } 658 }
660 /* xfs_qm_dqprint(dqp); */
661 /* 659 /*
662 * Convert the disk dquot to the exportable format 660 * Convert the disk dquot to the exportable format
663 */ 661 */
@@ -906,354 +904,3 @@ xfs_qm_dqrele_all_inodes(
906 ASSERT(mp->m_quotainfo); 904 ASSERT(mp->m_quotainfo);
907 xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags); 905 xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags);
908} 906}
909
910/*------------------------------------------------------------------------*/
911#ifdef DEBUG
912/*
913 * This contains all the test functions for XFS disk quotas.
914 * Currently it does a quota accounting check. ie. it walks through
915 * all inodes in the file system, calculating the dquot accounting fields,
916 * and prints out any inconsistencies.
917 */
918xfs_dqhash_t *qmtest_udqtab;
919xfs_dqhash_t *qmtest_gdqtab;
920int qmtest_hashmask;
921int qmtest_nfails;
922struct mutex qcheck_lock;
923
924#define DQTEST_HASHVAL(mp, id) (((__psunsigned_t)(mp) + \
925 (__psunsigned_t)(id)) & \
926 (qmtest_hashmask - 1))
927
928#define DQTEST_HASH(mp, id, type) ((type & XFS_DQ_USER) ? \
929 (qmtest_udqtab + \
930 DQTEST_HASHVAL(mp, id)) : \
931 (qmtest_gdqtab + \
932 DQTEST_HASHVAL(mp, id)))
933
934#define DQTEST_LIST_PRINT(l, NXT, title) \
935{ \
936 xfs_dqtest_t *dqp; int i = 0;\
937 xfs_debug(NULL, "%s (#%d)", title, (int) (l)->qh_nelems); \
938 for (dqp = (xfs_dqtest_t *)(l)->qh_next; dqp != NULL; \
939 dqp = (xfs_dqtest_t *)dqp->NXT) { \
940 xfs_debug(dqp->q_mount, \
941 " %d. \"%d (%s)\" bcnt = %d, icnt = %d", \
942 ++i, dqp->d_id, DQFLAGTO_TYPESTR(dqp), \
943 dqp->d_bcount, dqp->d_icount); } \
944}
945
946typedef struct dqtest {
947 uint dq_flags; /* various flags (XFS_DQ_*) */
948 struct list_head q_hashlist;
949 xfs_dqhash_t *q_hash; /* the hashchain header */
950 xfs_mount_t *q_mount; /* filesystem this relates to */
951 xfs_dqid_t d_id; /* user id or group id */
952 xfs_qcnt_t d_bcount; /* # disk blocks owned by the user */
953 xfs_qcnt_t d_icount; /* # inodes owned by the user */
954} xfs_dqtest_t;
955
956STATIC void
957xfs_qm_hashinsert(xfs_dqhash_t *h, xfs_dqtest_t *dqp)
958{
959 list_add(&dqp->q_hashlist, &h->qh_list);
960 h->qh_version++;
961 h->qh_nelems++;
962}
963STATIC void
964xfs_qm_dqtest_print(
965 struct xfs_mount *mp,
966 struct dqtest *d)
967{
968 xfs_debug(mp, "-----------DQTEST DQUOT----------------");
969 xfs_debug(mp, "---- dquot ID = %d", d->d_id);
970 xfs_debug(mp, "---- fs = 0x%p", d->q_mount);
971 xfs_debug(mp, "---- bcount = %Lu (0x%x)",
972 d->d_bcount, (int)d->d_bcount);
973 xfs_debug(mp, "---- icount = %Lu (0x%x)",
974 d->d_icount, (int)d->d_icount);
975 xfs_debug(mp, "---------------------------");
976}
977
978STATIC void
979xfs_qm_dqtest_failed(
980 xfs_dqtest_t *d,
981 xfs_dquot_t *dqp,
982 char *reason,
983 xfs_qcnt_t a,
984 xfs_qcnt_t b,
985 int error)
986{
987 qmtest_nfails++;
988 if (error)
989 xfs_debug(dqp->q_mount,
990 "quotacheck failed id=%d, err=%d\nreason: %s",
991 d->d_id, error, reason);
992 else
993 xfs_debug(dqp->q_mount,
994 "quotacheck failed id=%d (%s) [%d != %d]",
995 d->d_id, reason, (int)a, (int)b);
996 xfs_qm_dqtest_print(dqp->q_mount, d);
997 if (dqp)
998 xfs_qm_dqprint(dqp);
999}
1000
1001STATIC int
1002xfs_dqtest_cmp2(
1003 xfs_dqtest_t *d,
1004 xfs_dquot_t *dqp)
1005{
1006 int err = 0;
1007 if (be64_to_cpu(dqp->q_core.d_icount) != d->d_icount) {
1008 xfs_qm_dqtest_failed(d, dqp, "icount mismatch",
1009 be64_to_cpu(dqp->q_core.d_icount),
1010 d->d_icount, 0);
1011 err++;
1012 }
1013 if (be64_to_cpu(dqp->q_core.d_bcount) != d->d_bcount) {
1014 xfs_qm_dqtest_failed(d, dqp, "bcount mismatch",
1015 be64_to_cpu(dqp->q_core.d_bcount),
1016 d->d_bcount, 0);
1017 err++;
1018 }
1019 if (dqp->q_core.d_blk_softlimit &&
1020 be64_to_cpu(dqp->q_core.d_bcount) >=
1021 be64_to_cpu(dqp->q_core.d_blk_softlimit)) {
1022 if (!dqp->q_core.d_btimer && dqp->q_core.d_id) {
1023 xfs_debug(dqp->q_mount,
1024 "%d [%s] BLK TIMER NOT STARTED",
1025 d->d_id, DQFLAGTO_TYPESTR(d));
1026 err++;
1027 }
1028 }
1029 if (dqp->q_core.d_ino_softlimit &&
1030 be64_to_cpu(dqp->q_core.d_icount) >=
1031 be64_to_cpu(dqp->q_core.d_ino_softlimit)) {
1032 if (!dqp->q_core.d_itimer && dqp->q_core.d_id) {
1033 xfs_debug(dqp->q_mount,
1034 "%d [%s] INO TIMER NOT STARTED",
1035 d->d_id, DQFLAGTO_TYPESTR(d));
1036 err++;
1037 }
1038 }
1039#ifdef QUOTADEBUG
1040 if (!err) {
1041 xfs_debug(dqp->q_mount, "%d [%s] qchecked",
1042 d->d_id, DQFLAGTO_TYPESTR(d));
1043 }
1044#endif
1045 return (err);
1046}
1047
1048STATIC void
1049xfs_dqtest_cmp(
1050 xfs_dqtest_t *d)
1051{
1052 xfs_dquot_t *dqp;
1053 int error;
1054
1055 /* xfs_qm_dqtest_print(d); */
1056 if ((error = xfs_qm_dqget(d->q_mount, NULL, d->d_id, d->dq_flags, 0,
1057 &dqp))) {
1058 xfs_qm_dqtest_failed(d, NULL, "dqget failed", 0, 0, error);
1059 return;
1060 }
1061 xfs_dqtest_cmp2(d, dqp);
1062 xfs_qm_dqput(dqp);
1063}
1064
1065STATIC int
1066xfs_qm_internalqcheck_dqget(
1067 xfs_mount_t *mp,
1068 xfs_dqid_t id,
1069 uint type,
1070 xfs_dqtest_t **O_dq)
1071{
1072 xfs_dqtest_t *d;
1073 xfs_dqhash_t *h;
1074
1075 h = DQTEST_HASH(mp, id, type);
1076 list_for_each_entry(d, &h->qh_list, q_hashlist) {
1077 if (d->d_id == id && mp == d->q_mount) {
1078 *O_dq = d;
1079 return (0);
1080 }
1081 }
1082 d = kmem_zalloc(sizeof(xfs_dqtest_t), KM_SLEEP);
1083 d->dq_flags = type;
1084 d->d_id = id;
1085 d->q_mount = mp;
1086 d->q_hash = h;
1087 INIT_LIST_HEAD(&d->q_hashlist);
1088 xfs_qm_hashinsert(h, d);
1089 *O_dq = d;
1090 return (0);
1091}
1092
1093STATIC void
1094xfs_qm_internalqcheck_get_dquots(
1095 xfs_mount_t *mp,
1096 xfs_dqid_t uid,
1097 xfs_dqid_t projid,
1098 xfs_dqid_t gid,
1099 xfs_dqtest_t **ud,
1100 xfs_dqtest_t **gd)
1101{
1102 if (XFS_IS_UQUOTA_ON(mp))
1103 xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud);
1104 if (XFS_IS_GQUOTA_ON(mp))
1105 xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd);
1106 else if (XFS_IS_PQUOTA_ON(mp))
1107 xfs_qm_internalqcheck_dqget(mp, projid, XFS_DQ_PROJ, gd);
1108}
1109
1110
1111STATIC void
1112xfs_qm_internalqcheck_dqadjust(
1113 xfs_inode_t *ip,
1114 xfs_dqtest_t *d)
1115{
1116 d->d_icount++;
1117 d->d_bcount += (xfs_qcnt_t)ip->i_d.di_nblocks;
1118}
1119
1120STATIC int
1121xfs_qm_internalqcheck_adjust(
1122 xfs_mount_t *mp, /* mount point for filesystem */
1123 xfs_ino_t ino, /* inode number to get data for */
1124 void __user *buffer, /* not used */
1125 int ubsize, /* not used */
1126 int *ubused, /* not used */
1127 int *res) /* bulkstat result code */
1128{
1129 xfs_inode_t *ip;
1130 xfs_dqtest_t *ud, *gd;
1131 uint lock_flags;
1132 boolean_t ipreleased;
1133 int error;
1134
1135 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
1136
1137 if (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino) {
1138 *res = BULKSTAT_RV_NOTHING;
1139 xfs_debug(mp, "%s: ino=%llu, uqino=%llu, gqino=%llu\n",
1140 __func__, (unsigned long long) ino,
1141 (unsigned long long) mp->m_sb.sb_uquotino,
1142 (unsigned long long) mp->m_sb.sb_gquotino);
1143 return XFS_ERROR(EINVAL);
1144 }
1145 ipreleased = B_FALSE;
1146 again:
1147 lock_flags = XFS_ILOCK_SHARED;
1148 if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip))) {
1149 *res = BULKSTAT_RV_NOTHING;
1150 return (error);
1151 }
1152
1153 /*
1154 * This inode can have blocks after eof which can get released
1155 * when we send it to inactive. Since we don't check the dquot
1156 * until the after all our calculations are done, we must get rid
1157 * of those now.
1158 */
1159 if (! ipreleased) {
1160 xfs_iunlock(ip, lock_flags);
1161 IRELE(ip);
1162 ipreleased = B_TRUE;
1163 goto again;
1164 }
1165 xfs_qm_internalqcheck_get_dquots(mp,
1166 (xfs_dqid_t) ip->i_d.di_uid,
1167 (xfs_dqid_t) xfs_get_projid(ip),
1168 (xfs_dqid_t) ip->i_d.di_gid,
1169 &ud, &gd);
1170 if (XFS_IS_UQUOTA_ON(mp)) {
1171 ASSERT(ud);
1172 xfs_qm_internalqcheck_dqadjust(ip, ud);
1173 }
1174 if (XFS_IS_OQUOTA_ON(mp)) {
1175 ASSERT(gd);
1176 xfs_qm_internalqcheck_dqadjust(ip, gd);
1177 }
1178 xfs_iunlock(ip, lock_flags);
1179 IRELE(ip);
1180 *res = BULKSTAT_RV_DIDONE;
1181 return (0);
1182}
1183
1184
1185/* PRIVATE, debugging */
1186int
1187xfs_qm_internalqcheck(
1188 xfs_mount_t *mp)
1189{
1190 xfs_ino_t lastino;
1191 int done, count;
1192 int i;
1193 int error;
1194
1195 lastino = 0;
1196 qmtest_hashmask = 32;
1197 count = 5;
1198 done = 0;
1199 qmtest_nfails = 0;
1200
1201 if (! XFS_IS_QUOTA_ON(mp))
1202 return XFS_ERROR(ESRCH);
1203
1204 xfs_log_force(mp, XFS_LOG_SYNC);
1205 XFS_bflush(mp->m_ddev_targp);
1206 xfs_log_force(mp, XFS_LOG_SYNC);
1207 XFS_bflush(mp->m_ddev_targp);
1208
1209 mutex_lock(&qcheck_lock);
1210 /* There should be absolutely no quota activity while this
1211 is going on. */
1212 qmtest_udqtab = kmem_zalloc(qmtest_hashmask *
1213 sizeof(xfs_dqhash_t), KM_SLEEP);
1214 qmtest_gdqtab = kmem_zalloc(qmtest_hashmask *
1215 sizeof(xfs_dqhash_t), KM_SLEEP);
1216 do {
1217 /*
1218 * Iterate thru all the inodes in the file system,
1219 * adjusting the corresponding dquot counters
1220 */
1221 error = xfs_bulkstat(mp, &lastino, &count,
1222 xfs_qm_internalqcheck_adjust,
1223 0, NULL, &done);
1224 if (error) {
1225 xfs_debug(mp, "Bulkstat returned error 0x%x", error);
1226 break;
1227 }
1228 } while (!done);
1229
1230 xfs_debug(mp, "Checking results against system dquots");
1231 for (i = 0; i < qmtest_hashmask; i++) {
1232 xfs_dqtest_t *d, *n;
1233 xfs_dqhash_t *h;
1234
1235 h = &qmtest_udqtab[i];
1236 list_for_each_entry_safe(d, n, &h->qh_list, q_hashlist) {
1237 xfs_dqtest_cmp(d);
1238 kmem_free(d);
1239 }
1240 h = &qmtest_gdqtab[i];
1241 list_for_each_entry_safe(d, n, &h->qh_list, q_hashlist) {
1242 xfs_dqtest_cmp(d);
1243 kmem_free(d);
1244 }
1245 }
1246
1247 if (qmtest_nfails) {
1248 xfs_debug(mp, "******** quotacheck failed ********");
1249 xfs_debug(mp, "failures = %d", qmtest_nfails);
1250 } else {
1251 xfs_debug(mp, "******** quotacheck successful! ********");
1252 }
1253 kmem_free(qmtest_udqtab);
1254 kmem_free(qmtest_gdqtab);
1255 mutex_unlock(&qcheck_lock);
1256 return (qmtest_nfails);
1257}
1258
1259#endif /* DEBUG */
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/xfs_quota_priv.h
index 94a3d927d71..94a3d927d71 100644
--- a/fs/xfs/quota/xfs_quota_priv.h
+++ b/fs/xfs/xfs_quota_priv.h
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c
index 29b9d642e93..7e76f537abb 100644
--- a/fs/xfs/linux-2.6/xfs_quotaops.c
+++ b/fs/xfs/xfs_quotaops.c
@@ -25,7 +25,7 @@
25#include "xfs_trans.h" 25#include "xfs_trans.h"
26#include "xfs_bmap_btree.h" 26#include "xfs_bmap_btree.h"
27#include "xfs_inode.h" 27#include "xfs_inode.h"
28#include "quota/xfs_qm.h" 28#include "xfs_qm.h"
29#include <linux/quota.h> 29#include <linux/quota.h>
30 30
31 31
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 77a59891734..df78c297d1a 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -116,7 +116,7 @@ xfs_rename(
116 trace_xfs_rename(src_dp, target_dp, src_name, target_name); 116 trace_xfs_rename(src_dp, target_dp, src_name, target_name);
117 117
118 new_parent = (src_dp != target_dp); 118 new_parent = (src_dp != target_dp);
119 src_is_directory = ((src_ip->i_d.di_mode & S_IFMT) == S_IFDIR); 119 src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
120 120
121 if (src_is_directory) { 121 if (src_is_directory) {
122 /* 122 /*
@@ -226,7 +226,7 @@ xfs_rename(
226 * target and source are directories and that target can be 226 * target and source are directories and that target can be
227 * destroyed, or that neither is a directory. 227 * destroyed, or that neither is a directory.
228 */ 228 */
229 if ((target_ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 229 if (S_ISDIR(target_ip->i_d.di_mode)) {
230 /* 230 /*
231 * Make sure target dir is empty. 231 * Make sure target dir is empty.
232 */ 232 */
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 8f76fdff4f4..35561a511b5 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -168,7 +168,7 @@ error_cancel:
168 xfs_trans_cancel(tp, cancelflags); 168 xfs_trans_cancel(tp, cancelflags);
169 goto error; 169 goto error;
170 } 170 }
171 memset(XFS_BUF_PTR(bp), 0, mp->m_sb.sb_blocksize); 171 memset(bp->b_addr, 0, mp->m_sb.sb_blocksize);
172 xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); 172 xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
173 /* 173 /*
174 * Commit the transaction. 174 * Commit the transaction.
@@ -883,7 +883,7 @@ xfs_rtbuf_get(
883 if (error) { 883 if (error) {
884 return error; 884 return error;
885 } 885 }
886 ASSERT(bp && !XFS_BUF_GETERROR(bp)); 886 ASSERT(!xfs_buf_geterror(bp));
887 *bpp = bp; 887 *bpp = bp;
888 return 0; 888 return 0;
889} 889}
@@ -943,7 +943,7 @@ xfs_rtcheck_range(
943 if (error) { 943 if (error) {
944 return error; 944 return error;
945 } 945 }
946 bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 946 bufp = bp->b_addr;
947 /* 947 /*
948 * Compute the starting word's address, and starting bit. 948 * Compute the starting word's address, and starting bit.
949 */ 949 */
@@ -994,7 +994,7 @@ xfs_rtcheck_range(
994 if (error) { 994 if (error) {
995 return error; 995 return error;
996 } 996 }
997 b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 997 b = bufp = bp->b_addr;
998 word = 0; 998 word = 0;
999 } else { 999 } else {
1000 /* 1000 /*
@@ -1040,7 +1040,7 @@ xfs_rtcheck_range(
1040 if (error) { 1040 if (error) {
1041 return error; 1041 return error;
1042 } 1042 }
1043 b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1043 b = bufp = bp->b_addr;
1044 word = 0; 1044 word = 0;
1045 } else { 1045 } else {
1046 /* 1046 /*
@@ -1158,7 +1158,7 @@ xfs_rtfind_back(
1158 if (error) { 1158 if (error) {
1159 return error; 1159 return error;
1160 } 1160 }
1161 bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1161 bufp = bp->b_addr;
1162 /* 1162 /*
1163 * Get the first word's index & point to it. 1163 * Get the first word's index & point to it.
1164 */ 1164 */
@@ -1210,7 +1210,7 @@ xfs_rtfind_back(
1210 if (error) { 1210 if (error) {
1211 return error; 1211 return error;
1212 } 1212 }
1213 bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1213 bufp = bp->b_addr;
1214 word = XFS_BLOCKWMASK(mp); 1214 word = XFS_BLOCKWMASK(mp);
1215 b = &bufp[word]; 1215 b = &bufp[word];
1216 } else { 1216 } else {
@@ -1256,7 +1256,7 @@ xfs_rtfind_back(
1256 if (error) { 1256 if (error) {
1257 return error; 1257 return error;
1258 } 1258 }
1259 bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1259 bufp = bp->b_addr;
1260 word = XFS_BLOCKWMASK(mp); 1260 word = XFS_BLOCKWMASK(mp);
1261 b = &bufp[word]; 1261 b = &bufp[word];
1262 } else { 1262 } else {
@@ -1333,7 +1333,7 @@ xfs_rtfind_forw(
1333 if (error) { 1333 if (error) {
1334 return error; 1334 return error;
1335 } 1335 }
1336 bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1336 bufp = bp->b_addr;
1337 /* 1337 /*
1338 * Get the first word's index & point to it. 1338 * Get the first word's index & point to it.
1339 */ 1339 */
@@ -1384,7 +1384,7 @@ xfs_rtfind_forw(
1384 if (error) { 1384 if (error) {
1385 return error; 1385 return error;
1386 } 1386 }
1387 b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1387 b = bufp = bp->b_addr;
1388 word = 0; 1388 word = 0;
1389 } else { 1389 } else {
1390 /* 1390 /*
@@ -1429,7 +1429,7 @@ xfs_rtfind_forw(
1429 if (error) { 1429 if (error) {
1430 return error; 1430 return error;
1431 } 1431 }
1432 b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1432 b = bufp = bp->b_addr;
1433 word = 0; 1433 word = 0;
1434 } else { 1434 } else {
1435 /* 1435 /*
@@ -1649,7 +1649,7 @@ xfs_rtmodify_range(
1649 if (error) { 1649 if (error) {
1650 return error; 1650 return error;
1651 } 1651 }
1652 bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1652 bufp = bp->b_addr;
1653 /* 1653 /*
1654 * Compute the starting word's address, and starting bit. 1654 * Compute the starting word's address, and starting bit.
1655 */ 1655 */
@@ -1694,7 +1694,7 @@ xfs_rtmodify_range(
1694 if (error) { 1694 if (error) {
1695 return error; 1695 return error;
1696 } 1696 }
1697 first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1697 first = b = bufp = bp->b_addr;
1698 word = 0; 1698 word = 0;
1699 } else { 1699 } else {
1700 /* 1700 /*
@@ -1734,7 +1734,7 @@ xfs_rtmodify_range(
1734 if (error) { 1734 if (error) {
1735 return error; 1735 return error;
1736 } 1736 }
1737 first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); 1737 first = b = bufp = bp->b_addr;
1738 word = 0; 1738 word = 0;
1739 } else { 1739 } else {
1740 /* 1740 /*
@@ -1832,8 +1832,8 @@ xfs_rtmodify_summary(
1832 */ 1832 */
1833 sp = XFS_SUMPTR(mp, bp, so); 1833 sp = XFS_SUMPTR(mp, bp, so);
1834 *sp += delta; 1834 *sp += delta;
1835 xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)XFS_BUF_PTR(bp)), 1835 xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)bp->b_addr),
1836 (uint)((char *)sp - (char *)XFS_BUF_PTR(bp) + sizeof(*sp) - 1)); 1836 (uint)((char *)sp - (char *)bp->b_addr + sizeof(*sp) - 1));
1837 return 0; 1837 return 0;
1838} 1838}
1839 1839
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 09e1f4f35e9..f7f3a359c1c 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -47,7 +47,7 @@ struct xfs_trans;
47#define XFS_SUMOFFSTOBLOCK(mp,s) \ 47#define XFS_SUMOFFSTOBLOCK(mp,s) \
48 (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog) 48 (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog)
49#define XFS_SUMPTR(mp,bp,so) \ 49#define XFS_SUMPTR(mp,bp,so) \
50 ((xfs_suminfo_t *)((char *)XFS_BUF_PTR(bp) + \ 50 ((xfs_suminfo_t *)((bp)->b_addr + \
51 (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp)))) 51 (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp))))
52 52
53#define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log) 53#define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log)
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index d6d6fdfe942..c96a8a05ac0 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -104,9 +104,9 @@ xfs_ioerror_alert(
104 xfs_alert(mp, 104 xfs_alert(mp,
105 "I/O error occurred: meta-data dev %s block 0x%llx" 105 "I/O error occurred: meta-data dev %s block 0x%llx"
106 " (\"%s\") error %d buf count %zd", 106 " (\"%s\") error %d buf count %zd",
107 XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)), 107 xfs_buf_target_name(bp->b_target),
108 (__uint64_t)blkno, func, 108 (__uint64_t)blkno, func,
109 XFS_BUF_GETERROR(bp), XFS_BUF_COUNT(bp)); 109 bp->b_error, XFS_BUF_COUNT(bp));
110} 110}
111 111
112/* 112/*
@@ -137,8 +137,8 @@ xfs_read_buf(
137 bp = xfs_buf_read(target, blkno, len, flags); 137 bp = xfs_buf_read(target, blkno, len, flags);
138 if (!bp) 138 if (!bp)
139 return XFS_ERROR(EIO); 139 return XFS_ERROR(EIO);
140 error = XFS_BUF_GETERROR(bp); 140 error = bp->b_error;
141 if (bp && !error && !XFS_FORCED_SHUTDOWN(mp)) { 141 if (!error && !XFS_FORCED_SHUTDOWN(mp)) {
142 *bpp = bp; 142 *bpp = bp;
143 } else { 143 } else {
144 *bpp = NULL; 144 *bpp = NULL;
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index 1eb2ba58681..cb6ae715814 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -509,7 +509,7 @@ static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp)
509 509
510#define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ 510#define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */
511#define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) 511#define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR)
512#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)XFS_BUF_PTR(bp)) 512#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)((bp)->b_addr))
513 513
514#define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) 514#define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d))
515#define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ 515#define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \
diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/xfs_stats.c
index 76fdc586193..76fdc586193 100644
--- a/fs/xfs/linux-2.6/xfs_stats.c
+++ b/fs/xfs/xfs_stats.c
diff --git a/fs/xfs/linux-2.6/xfs_stats.h b/fs/xfs/xfs_stats.h
index 736854b1ca1..736854b1ca1 100644
--- a/fs/xfs/linux-2.6/xfs_stats.h
+++ b/fs/xfs/xfs_stats.h
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/xfs_super.c
index a1a881e68a9..5cf06b85fd9 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -33,7 +33,6 @@
33#include "xfs_dinode.h" 33#include "xfs_dinode.h"
34#include "xfs_inode.h" 34#include "xfs_inode.h"
35#include "xfs_btree.h" 35#include "xfs_btree.h"
36#include "xfs_btree_trace.h"
37#include "xfs_ialloc.h" 36#include "xfs_ialloc.h"
38#include "xfs_bmap.h" 37#include "xfs_bmap.h"
39#include "xfs_rtalloc.h" 38#include "xfs_rtalloc.h"
@@ -357,6 +356,8 @@ xfs_parseargs(
357 mp->m_flags |= XFS_MOUNT_DELAYLOG; 356 mp->m_flags |= XFS_MOUNT_DELAYLOG;
358 } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { 357 } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) {
359 mp->m_flags &= ~XFS_MOUNT_DELAYLOG; 358 mp->m_flags &= ~XFS_MOUNT_DELAYLOG;
359 xfs_warn(mp,
360 "nodelaylog is deprecated and will be removed in Linux 3.3");
360 } else if (!strcmp(this_char, MNTOPT_DISCARD)) { 361 } else if (!strcmp(this_char, MNTOPT_DISCARD)) {
361 mp->m_flags |= XFS_MOUNT_DISCARD; 362 mp->m_flags |= XFS_MOUNT_DISCARD;
362 } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { 363 } else if (!strcmp(this_char, MNTOPT_NODISCARD)) {
@@ -878,33 +879,17 @@ xfs_log_inode(
878 struct xfs_trans *tp; 879 struct xfs_trans *tp;
879 int error; 880 int error;
880 881
881 xfs_iunlock(ip, XFS_ILOCK_SHARED);
882 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); 882 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
883 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); 883 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
884
885 if (error) { 884 if (error) {
886 xfs_trans_cancel(tp, 0); 885 xfs_trans_cancel(tp, 0);
887 /* we need to return with the lock hold shared */
888 xfs_ilock(ip, XFS_ILOCK_SHARED);
889 return error; 886 return error;
890 } 887 }
891 888
892 xfs_ilock(ip, XFS_ILOCK_EXCL); 889 xfs_ilock(ip, XFS_ILOCK_EXCL);
893 890 xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
894 /*
895 * Note - it's possible that we might have pushed ourselves out of the
896 * way during trans_reserve which would flush the inode. But there's
897 * no guarantee that the inode buffer has actually gone out yet (it's
898 * delwri). Plus the buffer could be pinned anyway if it's part of
899 * an inode in another recent transaction. So we play it safe and
900 * fire off the transaction anyway.
901 */
902 xfs_trans_ijoin(tp, ip);
903 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 891 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
904 error = xfs_trans_commit(tp, 0); 892 return xfs_trans_commit(tp, 0);
905 xfs_ilock_demote(ip, XFS_ILOCK_EXCL);
906
907 return error;
908} 893}
909 894
910STATIC int 895STATIC int
@@ -919,7 +904,9 @@ xfs_fs_write_inode(
919 trace_xfs_write_inode(ip); 904 trace_xfs_write_inode(ip);
920 905
921 if (XFS_FORCED_SHUTDOWN(mp)) 906 if (XFS_FORCED_SHUTDOWN(mp))
922 return XFS_ERROR(EIO); 907 return -XFS_ERROR(EIO);
908 if (!ip->i_update_core)
909 return 0;
923 910
924 if (wbc->sync_mode == WB_SYNC_ALL) { 911 if (wbc->sync_mode == WB_SYNC_ALL) {
925 /* 912 /*
@@ -930,12 +917,10 @@ xfs_fs_write_inode(
930 * of synchronous log foces dramatically. 917 * of synchronous log foces dramatically.
931 */ 918 */
932 xfs_ioend_wait(ip); 919 xfs_ioend_wait(ip);
933 xfs_ilock(ip, XFS_ILOCK_SHARED); 920 error = xfs_log_inode(ip);
934 if (ip->i_update_core) { 921 if (error)
935 error = xfs_log_inode(ip); 922 goto out;
936 if (error) 923 return 0;
937 goto out_unlock;
938 }
939 } else { 924 } else {
940 /* 925 /*
941 * We make this non-blocking if the inode is contended, return 926 * We make this non-blocking if the inode is contended, return
@@ -1025,11 +1010,6 @@ xfs_fs_put_super(
1025{ 1010{
1026 struct xfs_mount *mp = XFS_M(sb); 1011 struct xfs_mount *mp = XFS_M(sb);
1027 1012
1028 /*
1029 * Unregister the memory shrinker before we tear down the mount
1030 * structure so we don't have memory reclaim racing with us here.
1031 */
1032 xfs_inode_shrinker_unregister(mp);
1033 xfs_syncd_stop(mp); 1013 xfs_syncd_stop(mp);
1034 1014
1035 /* 1015 /*
@@ -1412,36 +1392,31 @@ xfs_fs_fill_super(
1412 sb->s_time_gran = 1; 1392 sb->s_time_gran = 1;
1413 set_posix_acl_flag(sb); 1393 set_posix_acl_flag(sb);
1414 1394
1415 error = xfs_syncd_init(mp); 1395 error = xfs_mountfs(mp);
1416 if (error) 1396 if (error)
1417 goto out_filestream_unmount; 1397 goto out_filestream_unmount;
1418 1398
1419 xfs_inode_shrinker_register(mp); 1399 error = xfs_syncd_init(mp);
1420
1421 error = xfs_mountfs(mp);
1422 if (error) 1400 if (error)
1423 goto out_syncd_stop; 1401 goto out_unmount;
1424 1402
1425 root = igrab(VFS_I(mp->m_rootip)); 1403 root = igrab(VFS_I(mp->m_rootip));
1426 if (!root) { 1404 if (!root) {
1427 error = ENOENT; 1405 error = ENOENT;
1428 goto fail_unmount; 1406 goto out_syncd_stop;
1429 } 1407 }
1430 if (is_bad_inode(root)) { 1408 if (is_bad_inode(root)) {
1431 error = EINVAL; 1409 error = EINVAL;
1432 goto fail_vnrele; 1410 goto out_syncd_stop;
1433 } 1411 }
1434 sb->s_root = d_alloc_root(root); 1412 sb->s_root = d_alloc_root(root);
1435 if (!sb->s_root) { 1413 if (!sb->s_root) {
1436 error = ENOMEM; 1414 error = ENOMEM;
1437 goto fail_vnrele; 1415 goto out_iput;
1438 } 1416 }
1439 1417
1440 return 0; 1418 return 0;
1441 1419
1442 out_syncd_stop:
1443 xfs_inode_shrinker_unregister(mp);
1444 xfs_syncd_stop(mp);
1445 out_filestream_unmount: 1420 out_filestream_unmount:
1446 xfs_filestream_unmount(mp); 1421 xfs_filestream_unmount(mp);
1447 out_free_sb: 1422 out_free_sb:
@@ -1456,18 +1431,11 @@ xfs_fs_fill_super(
1456 out: 1431 out:
1457 return -error; 1432 return -error;
1458 1433
1459 fail_vnrele: 1434 out_iput:
1460 if (sb->s_root) { 1435 iput(root);
1461 dput(sb->s_root); 1436 out_syncd_stop:
1462 sb->s_root = NULL;
1463 } else {
1464 iput(root);
1465 }
1466
1467 fail_unmount:
1468 xfs_inode_shrinker_unregister(mp);
1469 xfs_syncd_stop(mp); 1437 xfs_syncd_stop(mp);
1470 1438 out_unmount:
1471 /* 1439 /*
1472 * Blow away any referenced inode in the filestreams cache. 1440 * Blow away any referenced inode in the filestreams cache.
1473 * This can and will cause log traffic as inodes go inactive 1441 * This can and will cause log traffic as inodes go inactive
@@ -1491,6 +1459,21 @@ xfs_fs_mount(
1491 return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); 1459 return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super);
1492} 1460}
1493 1461
1462static int
1463xfs_fs_nr_cached_objects(
1464 struct super_block *sb)
1465{
1466 return xfs_reclaim_inodes_count(XFS_M(sb));
1467}
1468
1469static void
1470xfs_fs_free_cached_objects(
1471 struct super_block *sb,
1472 int nr_to_scan)
1473{
1474 xfs_reclaim_inodes_nr(XFS_M(sb), nr_to_scan);
1475}
1476
1494static const struct super_operations xfs_super_operations = { 1477static const struct super_operations xfs_super_operations = {
1495 .alloc_inode = xfs_fs_alloc_inode, 1478 .alloc_inode = xfs_fs_alloc_inode,
1496 .destroy_inode = xfs_fs_destroy_inode, 1479 .destroy_inode = xfs_fs_destroy_inode,
@@ -1504,6 +1487,8 @@ static const struct super_operations xfs_super_operations = {
1504 .statfs = xfs_fs_statfs, 1487 .statfs = xfs_fs_statfs,
1505 .remount_fs = xfs_fs_remount, 1488 .remount_fs = xfs_fs_remount,
1506 .show_options = xfs_fs_show_options, 1489 .show_options = xfs_fs_show_options,
1490 .nr_cached_objects = xfs_fs_nr_cached_objects,
1491 .free_cached_objects = xfs_fs_free_cached_objects,
1507}; 1492};
1508 1493
1509static struct file_system_type xfs_fs_type = { 1494static struct file_system_type xfs_fs_type = {
@@ -1667,24 +1652,13 @@ xfs_init_workqueues(void)
1667 */ 1652 */
1668 xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8); 1653 xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8);
1669 if (!xfs_syncd_wq) 1654 if (!xfs_syncd_wq)
1670 goto out; 1655 return -ENOMEM;
1671
1672 xfs_ail_wq = alloc_workqueue("xfsail", WQ_CPU_INTENSIVE, 8);
1673 if (!xfs_ail_wq)
1674 goto out_destroy_syncd;
1675
1676 return 0; 1656 return 0;
1677
1678out_destroy_syncd:
1679 destroy_workqueue(xfs_syncd_wq);
1680out:
1681 return -ENOMEM;
1682} 1657}
1683 1658
1684STATIC void 1659STATIC void
1685xfs_destroy_workqueues(void) 1660xfs_destroy_workqueues(void)
1686{ 1661{
1687 destroy_workqueue(xfs_ail_wq);
1688 destroy_workqueue(xfs_syncd_wq); 1662 destroy_workqueue(xfs_syncd_wq);
1689} 1663}
1690 1664
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/xfs_super.h
index 50a3266c999..50a3266c999 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/xfs_super.h
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/xfs_sync.c
index 8ecad5ff9f9..4604f90f86a 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/xfs_sync.c
@@ -179,6 +179,8 @@ restart:
179 if (error == EFSCORRUPTED) 179 if (error == EFSCORRUPTED)
180 break; 180 break;
181 181
182 cond_resched();
183
182 } while (nr_found && !done); 184 } while (nr_found && !done);
183 185
184 if (skipped) { 186 if (skipped) {
@@ -330,7 +332,7 @@ xfs_sync_fsdata(
330 * between there and here. 332 * between there and here.
331 */ 333 */
332 bp = xfs_getsb(mp, 0); 334 bp = xfs_getsb(mp, 0);
333 if (XFS_BUF_ISPINNED(bp)) 335 if (xfs_buf_ispinned(bp))
334 xfs_log_force(mp, 0); 336 xfs_log_force(mp, 0);
335 337
336 return xfs_bwrite(mp, bp); 338 return xfs_bwrite(mp, bp);
@@ -359,14 +361,12 @@ xfs_quiesce_data(
359{ 361{
360 int error, error2 = 0; 362 int error, error2 = 0;
361 363
362 /* push non-blocking */
363 xfs_sync_data(mp, 0);
364 xfs_qm_sync(mp, SYNC_TRYLOCK); 364 xfs_qm_sync(mp, SYNC_TRYLOCK);
365
366 /* push and block till complete */
367 xfs_sync_data(mp, SYNC_WAIT);
368 xfs_qm_sync(mp, SYNC_WAIT); 365 xfs_qm_sync(mp, SYNC_WAIT);
369 366
367 /* force out the newly dirtied log buffers */
368 xfs_log_force(mp, XFS_LOG_SYNC);
369
370 /* write superblock and hoover up shutdown errors */ 370 /* write superblock and hoover up shutdown errors */
371 error = xfs_sync_fsdata(mp); 371 error = xfs_sync_fsdata(mp);
372 372
@@ -436,7 +436,7 @@ xfs_quiesce_attr(
436 WARN_ON(atomic_read(&mp->m_active_trans) != 0); 436 WARN_ON(atomic_read(&mp->m_active_trans) != 0);
437 437
438 /* Push the superblock and write an unmount record */ 438 /* Push the superblock and write an unmount record */
439 error = xfs_log_sbcount(mp, 1); 439 error = xfs_log_sbcount(mp);
440 if (error) 440 if (error)
441 xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. " 441 xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. "
442 "Frozen image may not be consistent."); 442 "Frozen image may not be consistent.");
@@ -986,6 +986,8 @@ restart:
986 986
987 *nr_to_scan -= XFS_LOOKUP_BATCH; 987 *nr_to_scan -= XFS_LOOKUP_BATCH;
988 988
989 cond_resched();
990
989 } while (nr_found && !done && *nr_to_scan > 0); 991 } while (nr_found && !done && *nr_to_scan > 0);
990 992
991 if (trylock && !done) 993 if (trylock && !done)
@@ -1003,7 +1005,7 @@ restart:
1003 * ensure that when we get more reclaimers than AGs we block rather 1005 * ensure that when we get more reclaimers than AGs we block rather
1004 * than spin trying to execute reclaim. 1006 * than spin trying to execute reclaim.
1005 */ 1007 */
1006 if (trylock && skipped && *nr_to_scan > 0) { 1008 if (skipped && (flags & SYNC_WAIT) && *nr_to_scan > 0) {
1007 trylock = 0; 1009 trylock = 0;
1008 goto restart; 1010 goto restart;
1009 } 1011 }
@@ -1021,44 +1023,38 @@ xfs_reclaim_inodes(
1021} 1023}
1022 1024
1023/* 1025/*
1024 * Inode cache shrinker. 1026 * Scan a certain number of inodes for reclaim.
1025 * 1027 *
1026 * When called we make sure that there is a background (fast) inode reclaim in 1028 * When called we make sure that there is a background (fast) inode reclaim in
1027 * progress, while we will throttle the speed of reclaim via doiing synchronous 1029 * progress, while we will throttle the speed of reclaim via doing synchronous
1028 * reclaim of inodes. That means if we come across dirty inodes, we wait for 1030 * reclaim of inodes. That means if we come across dirty inodes, we wait for
1029 * them to be cleaned, which we hope will not be very long due to the 1031 * them to be cleaned, which we hope will not be very long due to the
1030 * background walker having already kicked the IO off on those dirty inodes. 1032 * background walker having already kicked the IO off on those dirty inodes.
1031 */ 1033 */
1032static int 1034void
1033xfs_reclaim_inode_shrink( 1035xfs_reclaim_inodes_nr(
1034 struct shrinker *shrink, 1036 struct xfs_mount *mp,
1035 struct shrink_control *sc) 1037 int nr_to_scan)
1036{ 1038{
1037 struct xfs_mount *mp; 1039 /* kick background reclaimer and push the AIL */
1038 struct xfs_perag *pag; 1040 xfs_syncd_queue_reclaim(mp);
1039 xfs_agnumber_t ag; 1041 xfs_ail_push_all(mp->m_ail);
1040 int reclaimable;
1041 int nr_to_scan = sc->nr_to_scan;
1042 gfp_t gfp_mask = sc->gfp_mask;
1043
1044 mp = container_of(shrink, struct xfs_mount, m_inode_shrink);
1045 if (nr_to_scan) {
1046 /* kick background reclaimer and push the AIL */
1047 xfs_syncd_queue_reclaim(mp);
1048 xfs_ail_push_all(mp->m_ail);
1049 1042
1050 if (!(gfp_mask & __GFP_FS)) 1043 xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK | SYNC_WAIT, &nr_to_scan);
1051 return -1; 1044}
1052 1045
1053 xfs_reclaim_inodes_ag(mp, SYNC_TRYLOCK | SYNC_WAIT, 1046/*
1054 &nr_to_scan); 1047 * Return the number of reclaimable inodes in the filesystem for
1055 /* terminate if we don't exhaust the scan */ 1048 * the shrinker to determine how much to reclaim.
1056 if (nr_to_scan > 0) 1049 */
1057 return -1; 1050int
1058 } 1051xfs_reclaim_inodes_count(
1052 struct xfs_mount *mp)
1053{
1054 struct xfs_perag *pag;
1055 xfs_agnumber_t ag = 0;
1056 int reclaimable = 0;
1059 1057
1060 reclaimable = 0;
1061 ag = 0;
1062 while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) { 1058 while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) {
1063 ag = pag->pag_agno + 1; 1059 ag = pag->pag_agno + 1;
1064 reclaimable += pag->pag_ici_reclaimable; 1060 reclaimable += pag->pag_ici_reclaimable;
@@ -1067,18 +1063,3 @@ xfs_reclaim_inode_shrink(
1067 return reclaimable; 1063 return reclaimable;
1068} 1064}
1069 1065
1070void
1071xfs_inode_shrinker_register(
1072 struct xfs_mount *mp)
1073{
1074 mp->m_inode_shrink.shrink = xfs_reclaim_inode_shrink;
1075 mp->m_inode_shrink.seeks = DEFAULT_SEEKS;
1076 register_shrinker(&mp->m_inode_shrink);
1077}
1078
1079void
1080xfs_inode_shrinker_unregister(
1081 struct xfs_mount *mp)
1082{
1083 unregister_shrinker(&mp->m_inode_shrink);
1084}
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/xfs_sync.h
index e3a6ad27415..941202e7ac6 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/xfs_sync.h
@@ -21,14 +21,6 @@
21struct xfs_mount; 21struct xfs_mount;
22struct xfs_perag; 22struct xfs_perag;
23 23
24typedef struct xfs_sync_work {
25 struct list_head w_list;
26 struct xfs_mount *w_mount;
27 void *w_data; /* syncer routine argument */
28 void (*w_syncer)(struct xfs_mount *, void *);
29 struct completion *w_completion;
30} xfs_sync_work_t;
31
32#define SYNC_WAIT 0x0001 /* wait for i/o to complete */ 24#define SYNC_WAIT 0x0001 /* wait for i/o to complete */
33#define SYNC_TRYLOCK 0x0002 /* only try to lock inodes */ 25#define SYNC_TRYLOCK 0x0002 /* only try to lock inodes */
34 26
@@ -43,6 +35,8 @@ void xfs_quiesce_attr(struct xfs_mount *mp);
43void xfs_flush_inodes(struct xfs_inode *ip); 35void xfs_flush_inodes(struct xfs_inode *ip);
44 36
45int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); 37int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
38int xfs_reclaim_inodes_count(struct xfs_mount *mp);
39void xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan);
46 40
47void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); 41void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
48void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip); 42void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip);
@@ -54,7 +48,4 @@ int xfs_inode_ag_iterator(struct xfs_mount *mp,
54 int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags), 48 int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
55 int flags); 49 int flags);
56 50
57void xfs_inode_shrinker_register(struct xfs_mount *mp);
58void xfs_inode_shrinker_unregister(struct xfs_mount *mp);
59
60#endif 51#endif
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/xfs_sysctl.c
index ee2d2adaa43..ee2d2adaa43 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.c
+++ b/fs/xfs/xfs_sysctl.c
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.h b/fs/xfs/xfs_sysctl.h
index b9937d450f8..b9937d450f8 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.h
+++ b/fs/xfs/xfs_sysctl.h
diff --git a/fs/xfs/linux-2.6/xfs_trace.c b/fs/xfs/xfs_trace.c
index 88d25d4aa56..9010ce885e6 100644
--- a/fs/xfs/linux-2.6/xfs_trace.c
+++ b/fs/xfs/xfs_trace.c
@@ -43,8 +43,8 @@
43#include "xfs_quota.h" 43#include "xfs_quota.h"
44#include "xfs_iomap.h" 44#include "xfs_iomap.h"
45#include "xfs_aops.h" 45#include "xfs_aops.h"
46#include "quota/xfs_dquot_item.h" 46#include "xfs_dquot_item.h"
47#include "quota/xfs_dquot.h" 47#include "xfs_dquot.h"
48#include "xfs_log_recover.h" 48#include "xfs_log_recover.h"
49#include "xfs_inode_item.h" 49#include "xfs_inode_item.h"
50 50
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/xfs_trace.h
index d48b7a579ae..690fc7a7bd7 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -293,7 +293,7 @@ DECLARE_EVENT_CLASS(xfs_buf_class,
293 __entry->buffer_length = bp->b_buffer_length; 293 __entry->buffer_length = bp->b_buffer_length;
294 __entry->hold = atomic_read(&bp->b_hold); 294 __entry->hold = atomic_read(&bp->b_hold);
295 __entry->pincount = atomic_read(&bp->b_pin_count); 295 __entry->pincount = atomic_read(&bp->b_pin_count);
296 __entry->lockval = xfs_buf_lock_value(bp); 296 __entry->lockval = bp->b_sema.count;
297 __entry->flags = bp->b_flags; 297 __entry->flags = bp->b_flags;
298 __entry->caller_ip = caller_ip; 298 __entry->caller_ip = caller_ip;
299 ), 299 ),
@@ -323,7 +323,7 @@ DEFINE_BUF_EVENT(xfs_buf_bawrite);
323DEFINE_BUF_EVENT(xfs_buf_bdwrite); 323DEFINE_BUF_EVENT(xfs_buf_bdwrite);
324DEFINE_BUF_EVENT(xfs_buf_lock); 324DEFINE_BUF_EVENT(xfs_buf_lock);
325DEFINE_BUF_EVENT(xfs_buf_lock_done); 325DEFINE_BUF_EVENT(xfs_buf_lock_done);
326DEFINE_BUF_EVENT(xfs_buf_cond_lock); 326DEFINE_BUF_EVENT(xfs_buf_trylock);
327DEFINE_BUF_EVENT(xfs_buf_unlock); 327DEFINE_BUF_EVENT(xfs_buf_unlock);
328DEFINE_BUF_EVENT(xfs_buf_iowait); 328DEFINE_BUF_EVENT(xfs_buf_iowait);
329DEFINE_BUF_EVENT(xfs_buf_iowait_done); 329DEFINE_BUF_EVENT(xfs_buf_iowait_done);
@@ -366,7 +366,7 @@ DECLARE_EVENT_CLASS(xfs_buf_flags_class,
366 __entry->flags = flags; 366 __entry->flags = flags;
367 __entry->hold = atomic_read(&bp->b_hold); 367 __entry->hold = atomic_read(&bp->b_hold);
368 __entry->pincount = atomic_read(&bp->b_pin_count); 368 __entry->pincount = atomic_read(&bp->b_pin_count);
369 __entry->lockval = xfs_buf_lock_value(bp); 369 __entry->lockval = bp->b_sema.count;
370 __entry->caller_ip = caller_ip; 370 __entry->caller_ip = caller_ip;
371 ), 371 ),
372 TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " 372 TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d "
@@ -409,7 +409,7 @@ TRACE_EVENT(xfs_buf_ioerror,
409 __entry->buffer_length = bp->b_buffer_length; 409 __entry->buffer_length = bp->b_buffer_length;
410 __entry->hold = atomic_read(&bp->b_hold); 410 __entry->hold = atomic_read(&bp->b_hold);
411 __entry->pincount = atomic_read(&bp->b_pin_count); 411 __entry->pincount = atomic_read(&bp->b_pin_count);
412 __entry->lockval = xfs_buf_lock_value(bp); 412 __entry->lockval = bp->b_sema.count;
413 __entry->error = error; 413 __entry->error = error;
414 __entry->flags = bp->b_flags; 414 __entry->flags = bp->b_flags;
415 __entry->caller_ip = caller_ip; 415 __entry->caller_ip = caller_ip;
@@ -454,7 +454,7 @@ DECLARE_EVENT_CLASS(xfs_buf_item_class,
454 __entry->buf_flags = bip->bli_buf->b_flags; 454 __entry->buf_flags = bip->bli_buf->b_flags;
455 __entry->buf_hold = atomic_read(&bip->bli_buf->b_hold); 455 __entry->buf_hold = atomic_read(&bip->bli_buf->b_hold);
456 __entry->buf_pincount = atomic_read(&bip->bli_buf->b_pin_count); 456 __entry->buf_pincount = atomic_read(&bip->bli_buf->b_pin_count);
457 __entry->buf_lockval = xfs_buf_lock_value(bip->bli_buf); 457 __entry->buf_lockval = bip->bli_buf->b_sema.count;
458 __entry->li_desc = bip->bli_item.li_desc; 458 __entry->li_desc = bip->bli_item.li_desc;
459 __entry->li_flags = bip->bli_item.li_flags; 459 __entry->li_flags = bip->bli_item.li_flags;
460 ), 460 ),
@@ -571,7 +571,7 @@ DEFINE_INODE_EVENT(xfs_alloc_file_space);
571DEFINE_INODE_EVENT(xfs_free_file_space); 571DEFINE_INODE_EVENT(xfs_free_file_space);
572DEFINE_INODE_EVENT(xfs_readdir); 572DEFINE_INODE_EVENT(xfs_readdir);
573#ifdef CONFIG_XFS_POSIX_ACL 573#ifdef CONFIG_XFS_POSIX_ACL
574DEFINE_INODE_EVENT(xfs_check_acl); 574DEFINE_INODE_EVENT(xfs_get_acl);
575#endif 575#endif
576DEFINE_INODE_EVENT(xfs_vm_bmap); 576DEFINE_INODE_EVENT(xfs_vm_bmap);
577DEFINE_INODE_EVENT(xfs_file_ioctl); 577DEFINE_INODE_EVENT(xfs_file_ioctl);
@@ -998,7 +998,8 @@ DECLARE_EVENT_CLASS(xfs_simple_io_class,
998 TP_STRUCT__entry( 998 TP_STRUCT__entry(
999 __field(dev_t, dev) 999 __field(dev_t, dev)
1000 __field(xfs_ino_t, ino) 1000 __field(xfs_ino_t, ino)
1001 __field(loff_t, size) 1001 __field(loff_t, isize)
1002 __field(loff_t, disize)
1002 __field(loff_t, new_size) 1003 __field(loff_t, new_size)
1003 __field(loff_t, offset) 1004 __field(loff_t, offset)
1004 __field(size_t, count) 1005 __field(size_t, count)
@@ -1006,16 +1007,18 @@ DECLARE_EVENT_CLASS(xfs_simple_io_class,
1006 TP_fast_assign( 1007 TP_fast_assign(
1007 __entry->dev = VFS_I(ip)->i_sb->s_dev; 1008 __entry->dev = VFS_I(ip)->i_sb->s_dev;
1008 __entry->ino = ip->i_ino; 1009 __entry->ino = ip->i_ino;
1009 __entry->size = ip->i_d.di_size; 1010 __entry->isize = ip->i_size;
1011 __entry->disize = ip->i_d.di_size;
1010 __entry->new_size = ip->i_new_size; 1012 __entry->new_size = ip->i_new_size;
1011 __entry->offset = offset; 1013 __entry->offset = offset;
1012 __entry->count = count; 1014 __entry->count = count;
1013 ), 1015 ),
1014 TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " 1016 TP_printk("dev %d:%d ino 0x%llx isize 0x%llx disize 0x%llx new_size 0x%llx "
1015 "offset 0x%llx count %zd", 1017 "offset 0x%llx count %zd",
1016 MAJOR(__entry->dev), MINOR(__entry->dev), 1018 MAJOR(__entry->dev), MINOR(__entry->dev),
1017 __entry->ino, 1019 __entry->ino,
1018 __entry->size, 1020 __entry->isize,
1021 __entry->disize,
1019 __entry->new_size, 1022 __entry->new_size,
1020 __entry->offset, 1023 __entry->offset,
1021 __entry->count) 1024 __entry->count)
@@ -1028,40 +1031,7 @@ DEFINE_EVENT(xfs_simple_io_class, name, \
1028DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc); 1031DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc);
1029DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); 1032DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert);
1030DEFINE_SIMPLE_IO_EVENT(xfs_get_blocks_notfound); 1033DEFINE_SIMPLE_IO_EVENT(xfs_get_blocks_notfound);
1031 1034DEFINE_SIMPLE_IO_EVENT(xfs_setfilesize);
1032
1033TRACE_EVENT(xfs_itruncate_start,
1034 TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size, int flag,
1035 xfs_off_t toss_start, xfs_off_t toss_finish),
1036 TP_ARGS(ip, new_size, flag, toss_start, toss_finish),
1037 TP_STRUCT__entry(
1038 __field(dev_t, dev)
1039 __field(xfs_ino_t, ino)
1040 __field(xfs_fsize_t, size)
1041 __field(xfs_fsize_t, new_size)
1042 __field(xfs_off_t, toss_start)
1043 __field(xfs_off_t, toss_finish)
1044 __field(int, flag)
1045 ),
1046 TP_fast_assign(
1047 __entry->dev = VFS_I(ip)->i_sb->s_dev;
1048 __entry->ino = ip->i_ino;
1049 __entry->size = ip->i_d.di_size;
1050 __entry->new_size = new_size;
1051 __entry->toss_start = toss_start;
1052 __entry->toss_finish = toss_finish;
1053 __entry->flag = flag;
1054 ),
1055 TP_printk("dev %d:%d ino 0x%llx %s size 0x%llx new_size 0x%llx "
1056 "toss start 0x%llx toss finish 0x%llx",
1057 MAJOR(__entry->dev), MINOR(__entry->dev),
1058 __entry->ino,
1059 __print_flags(__entry->flag, "|", XFS_ITRUNC_FLAGS),
1060 __entry->size,
1061 __entry->new_size,
1062 __entry->toss_start,
1063 __entry->toss_finish)
1064);
1065 1035
1066DECLARE_EVENT_CLASS(xfs_itrunc_class, 1036DECLARE_EVENT_CLASS(xfs_itrunc_class,
1067 TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size), 1037 TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size),
@@ -1089,8 +1059,8 @@ DECLARE_EVENT_CLASS(xfs_itrunc_class,
1089DEFINE_EVENT(xfs_itrunc_class, name, \ 1059DEFINE_EVENT(xfs_itrunc_class, name, \
1090 TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size), \ 1060 TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size), \
1091 TP_ARGS(ip, new_size)) 1061 TP_ARGS(ip, new_size))
1092DEFINE_ITRUNC_EVENT(xfs_itruncate_finish_start); 1062DEFINE_ITRUNC_EVENT(xfs_itruncate_data_start);
1093DEFINE_ITRUNC_EVENT(xfs_itruncate_finish_end); 1063DEFINE_ITRUNC_EVENT(xfs_itruncate_data_end);
1094 1064
1095TRACE_EVENT(xfs_pagecache_inval, 1065TRACE_EVENT(xfs_pagecache_inval,
1096 TP_PROTO(struct xfs_inode *ip, xfs_off_t start, xfs_off_t finish), 1066 TP_PROTO(struct xfs_inode *ip, xfs_off_t start, xfs_off_t finish),
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index c83f63b33aa..efc147f0e9b 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -1426,6 +1426,7 @@ xfs_trans_committed(
1426static inline void 1426static inline void
1427xfs_log_item_batch_insert( 1427xfs_log_item_batch_insert(
1428 struct xfs_ail *ailp, 1428 struct xfs_ail *ailp,
1429 struct xfs_ail_cursor *cur,
1429 struct xfs_log_item **log_items, 1430 struct xfs_log_item **log_items,
1430 int nr_items, 1431 int nr_items,
1431 xfs_lsn_t commit_lsn) 1432 xfs_lsn_t commit_lsn)
@@ -1434,7 +1435,7 @@ xfs_log_item_batch_insert(
1434 1435
1435 spin_lock(&ailp->xa_lock); 1436 spin_lock(&ailp->xa_lock);
1436 /* xfs_trans_ail_update_bulk drops ailp->xa_lock */ 1437 /* xfs_trans_ail_update_bulk drops ailp->xa_lock */
1437 xfs_trans_ail_update_bulk(ailp, log_items, nr_items, commit_lsn); 1438 xfs_trans_ail_update_bulk(ailp, cur, log_items, nr_items, commit_lsn);
1438 1439
1439 for (i = 0; i < nr_items; i++) 1440 for (i = 0; i < nr_items; i++)
1440 IOP_UNPIN(log_items[i], 0); 1441 IOP_UNPIN(log_items[i], 0);
@@ -1452,6 +1453,13 @@ xfs_log_item_batch_insert(
1452 * as an iclog write error even though we haven't started any IO yet. Hence in 1453 * as an iclog write error even though we haven't started any IO yet. Hence in
1453 * this case all we need to do is IOP_COMMITTED processing, followed by an 1454 * this case all we need to do is IOP_COMMITTED processing, followed by an
1454 * IOP_UNPIN(aborted) call. 1455 * IOP_UNPIN(aborted) call.
1456 *
1457 * The AIL cursor is used to optimise the insert process. If commit_lsn is not
1458 * at the end of the AIL, the insert cursor avoids the need to walk
1459 * the AIL to find the insertion point on every xfs_log_item_batch_insert()
1460 * call. This saves a lot of needless list walking and is a net win, even
1461 * though it slightly increases that amount of AIL lock traffic to set it up
1462 * and tear it down.
1455 */ 1463 */
1456void 1464void
1457xfs_trans_committed_bulk( 1465xfs_trans_committed_bulk(
@@ -1463,8 +1471,13 @@ xfs_trans_committed_bulk(
1463#define LOG_ITEM_BATCH_SIZE 32 1471#define LOG_ITEM_BATCH_SIZE 32
1464 struct xfs_log_item *log_items[LOG_ITEM_BATCH_SIZE]; 1472 struct xfs_log_item *log_items[LOG_ITEM_BATCH_SIZE];
1465 struct xfs_log_vec *lv; 1473 struct xfs_log_vec *lv;
1474 struct xfs_ail_cursor cur;
1466 int i = 0; 1475 int i = 0;
1467 1476
1477 spin_lock(&ailp->xa_lock);
1478 xfs_trans_ail_cursor_last(ailp, &cur, commit_lsn);
1479 spin_unlock(&ailp->xa_lock);
1480
1468 /* unpin all the log items */ 1481 /* unpin all the log items */
1469 for (lv = log_vector; lv; lv = lv->lv_next ) { 1482 for (lv = log_vector; lv; lv = lv->lv_next ) {
1470 struct xfs_log_item *lip = lv->lv_item; 1483 struct xfs_log_item *lip = lv->lv_item;
@@ -1493,7 +1506,9 @@ xfs_trans_committed_bulk(
1493 /* 1506 /*
1494 * Not a bulk update option due to unusual item_lsn. 1507 * Not a bulk update option due to unusual item_lsn.
1495 * Push into AIL immediately, rechecking the lsn once 1508 * Push into AIL immediately, rechecking the lsn once
1496 * we have the ail lock. Then unpin the item. 1509 * we have the ail lock. Then unpin the item. This does
1510 * not affect the AIL cursor the bulk insert path is
1511 * using.
1497 */ 1512 */
1498 spin_lock(&ailp->xa_lock); 1513 spin_lock(&ailp->xa_lock);
1499 if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) 1514 if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0)
@@ -1507,7 +1522,7 @@ xfs_trans_committed_bulk(
1507 /* Item is a candidate for bulk AIL insert. */ 1522 /* Item is a candidate for bulk AIL insert. */
1508 log_items[i++] = lv->lv_item; 1523 log_items[i++] = lv->lv_item;
1509 if (i >= LOG_ITEM_BATCH_SIZE) { 1524 if (i >= LOG_ITEM_BATCH_SIZE) {
1510 xfs_log_item_batch_insert(ailp, log_items, 1525 xfs_log_item_batch_insert(ailp, &cur, log_items,
1511 LOG_ITEM_BATCH_SIZE, commit_lsn); 1526 LOG_ITEM_BATCH_SIZE, commit_lsn);
1512 i = 0; 1527 i = 0;
1513 } 1528 }
@@ -1515,7 +1530,11 @@ xfs_trans_committed_bulk(
1515 1530
1516 /* make sure we insert the remainder! */ 1531 /* make sure we insert the remainder! */
1517 if (i) 1532 if (i)
1518 xfs_log_item_batch_insert(ailp, log_items, i, commit_lsn); 1533 xfs_log_item_batch_insert(ailp, &cur, log_items, i, commit_lsn);
1534
1535 spin_lock(&ailp->xa_lock);
1536 xfs_trans_ail_cursor_done(ailp, &cur);
1537 spin_unlock(&ailp->xa_lock);
1519} 1538}
1520 1539
1521/* 1540/*
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 06a9759b635..53597f4db9b 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -350,7 +350,7 @@ typedef struct xfs_item_ops {
350 void (*iop_unlock)(xfs_log_item_t *); 350 void (*iop_unlock)(xfs_log_item_t *);
351 xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); 351 xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
352 void (*iop_push)(xfs_log_item_t *); 352 void (*iop_push)(xfs_log_item_t *);
353 void (*iop_pushbuf)(xfs_log_item_t *); 353 bool (*iop_pushbuf)(xfs_log_item_t *);
354 void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); 354 void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
355} xfs_item_ops_t; 355} xfs_item_ops_t;
356 356
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 5fc2380092c..3a1e7ca54c2 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -28,8 +28,6 @@
28#include "xfs_trans_priv.h" 28#include "xfs_trans_priv.h"
29#include "xfs_error.h" 29#include "xfs_error.h"
30 30
31struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
32
33#ifdef DEBUG 31#ifdef DEBUG
34/* 32/*
35 * Check that the list is sorted as it should be. 33 * Check that the list is sorted as it should be.
@@ -163,17 +161,11 @@ xfs_ail_max_lsn(
163} 161}
164 162
165/* 163/*
166 * AIL traversal cursor initialisation. 164 * The cursor keeps track of where our current traversal is up to by tracking
167 * 165 * the next item in the list for us. However, for this to be safe, removing an
168 * The cursor keeps track of where our current traversal is up 166 * object from the AIL needs to invalidate any cursor that points to it. hence
169 * to by tracking the next ƣtem in the list for us. However, for 167 * the traversal cursor needs to be linked to the struct xfs_ail so that
170 * this to be safe, removing an object from the AIL needs to invalidate 168 * deletion can search all the active cursors for invalidation.
171 * any cursor that points to it. hence the traversal cursor needs to
172 * be linked to the struct xfs_ail so that deletion can search all the
173 * active cursors for invalidation.
174 *
175 * We don't link the push cursor because it is embedded in the struct
176 * xfs_ail and hence easily findable.
177 */ 169 */
178STATIC void 170STATIC void
179xfs_trans_ail_cursor_init( 171xfs_trans_ail_cursor_init(
@@ -181,31 +173,12 @@ xfs_trans_ail_cursor_init(
181 struct xfs_ail_cursor *cur) 173 struct xfs_ail_cursor *cur)
182{ 174{
183 cur->item = NULL; 175 cur->item = NULL;
184 if (cur == &ailp->xa_cursors) 176 list_add_tail(&cur->list, &ailp->xa_cursors);
185 return;
186
187 cur->next = ailp->xa_cursors.next;
188 ailp->xa_cursors.next = cur;
189}
190
191/*
192 * Set the cursor to the next item, because when we look
193 * up the cursor the current item may have been freed.
194 */
195STATIC void
196xfs_trans_ail_cursor_set(
197 struct xfs_ail *ailp,
198 struct xfs_ail_cursor *cur,
199 struct xfs_log_item *lip)
200{
201 if (lip)
202 cur->item = xfs_ail_next(ailp, lip);
203} 177}
204 178
205/* 179/*
206 * Get the next item in the traversal and advance the cursor. 180 * Get the next item in the traversal and advance the cursor. If the cursor
207 * If the cursor was invalidated (inidicated by a lip of 1), 181 * was invalidated (indicated by a lip of 1), restart the traversal.
208 * restart the traversal.
209 */ 182 */
210struct xfs_log_item * 183struct xfs_log_item *
211xfs_trans_ail_cursor_next( 184xfs_trans_ail_cursor_next(
@@ -216,45 +189,31 @@ xfs_trans_ail_cursor_next(
216 189
217 if ((__psint_t)lip & 1) 190 if ((__psint_t)lip & 1)
218 lip = xfs_ail_min(ailp); 191 lip = xfs_ail_min(ailp);
219 xfs_trans_ail_cursor_set(ailp, cur, lip); 192 if (lip)
193 cur->item = xfs_ail_next(ailp, lip);
220 return lip; 194 return lip;
221} 195}
222 196
223/* 197/*
224 * Now that the traversal is complete, we need to remove the cursor 198 * When the traversal is complete, we need to remove the cursor from the list
225 * from the list of traversing cursors. Avoid removing the embedded 199 * of traversing cursors.
226 * push cursor, but use the fact it is always present to make the
227 * list deletion simple.
228 */ 200 */
229void 201void
230xfs_trans_ail_cursor_done( 202xfs_trans_ail_cursor_done(
231 struct xfs_ail *ailp, 203 struct xfs_ail *ailp,
232 struct xfs_ail_cursor *done) 204 struct xfs_ail_cursor *cur)
233{ 205{
234 struct xfs_ail_cursor *prev = NULL; 206 cur->item = NULL;
235 struct xfs_ail_cursor *cur; 207 list_del_init(&cur->list);
236
237 done->item = NULL;
238 if (done == &ailp->xa_cursors)
239 return;
240 prev = &ailp->xa_cursors;
241 for (cur = prev->next; cur; prev = cur, cur = prev->next) {
242 if (cur == done) {
243 prev->next = cur->next;
244 break;
245 }
246 }
247 ASSERT(cur);
248} 208}
249 209
250/* 210/*
251 * Invalidate any cursor that is pointing to this item. This is 211 * Invalidate any cursor that is pointing to this item. This is called when an
252 * called when an item is removed from the AIL. Any cursor pointing 212 * item is removed from the AIL. Any cursor pointing to this object is now
253 * to this object is now invalid and the traversal needs to be 213 * invalid and the traversal needs to be terminated so it doesn't reference a
254 * terminated so it doesn't reference a freed object. We set the 214 * freed object. We set the low bit of the cursor item pointer so we can
255 * cursor item to a value of 1 so we can distinguish between an 215 * distinguish between an invalidation and the end of the list when getting the
256 * invalidation and the end of the list when getting the next item 216 * next item from the cursor.
257 * from the cursor.
258 */ 217 */
259STATIC void 218STATIC void
260xfs_trans_ail_cursor_clear( 219xfs_trans_ail_cursor_clear(
@@ -263,8 +222,7 @@ xfs_trans_ail_cursor_clear(
263{ 222{
264 struct xfs_ail_cursor *cur; 223 struct xfs_ail_cursor *cur;
265 224
266 /* need to search all cursors */ 225 list_for_each_entry(cur, &ailp->xa_cursors, list) {
267 for (cur = &ailp->xa_cursors; cur; cur = cur->next) {
268 if (cur->item == lip) 226 if (cur->item == lip)
269 cur->item = (struct xfs_log_item *) 227 cur->item = (struct xfs_log_item *)
270 ((__psint_t)cur->item | 1); 228 ((__psint_t)cur->item | 1);
@@ -272,9 +230,10 @@ xfs_trans_ail_cursor_clear(
272} 230}
273 231
274/* 232/*
275 * Return the item in the AIL with the current lsn. 233 * Find the first item in the AIL with the given @lsn by searching in ascending
276 * Return the current tree generation number for use 234 * LSN order and initialise the cursor to point to the next item for a
277 * in calls to xfs_trans_next_ail(). 235 * ascending traversal. Pass a @lsn of zero to initialise the cursor to the
236 * first item in the AIL. Returns NULL if the list is empty.
278 */ 237 */
279xfs_log_item_t * 238xfs_log_item_t *
280xfs_trans_ail_cursor_first( 239xfs_trans_ail_cursor_first(
@@ -285,46 +244,101 @@ xfs_trans_ail_cursor_first(
285 xfs_log_item_t *lip; 244 xfs_log_item_t *lip;
286 245
287 xfs_trans_ail_cursor_init(ailp, cur); 246 xfs_trans_ail_cursor_init(ailp, cur);
288 lip = xfs_ail_min(ailp); 247
289 if (lsn == 0) 248 if (lsn == 0) {
249 lip = xfs_ail_min(ailp);
290 goto out; 250 goto out;
251 }
291 252
292 list_for_each_entry(lip, &ailp->xa_ail, li_ail) { 253 list_for_each_entry(lip, &ailp->xa_ail, li_ail) {
293 if (XFS_LSN_CMP(lip->li_lsn, lsn) >= 0) 254 if (XFS_LSN_CMP(lip->li_lsn, lsn) >= 0)
294 goto out; 255 goto out;
295 } 256 }
296 lip = NULL; 257 return NULL;
258
297out: 259out:
298 xfs_trans_ail_cursor_set(ailp, cur, lip); 260 if (lip)
261 cur->item = xfs_ail_next(ailp, lip);
299 return lip; 262 return lip;
300} 263}
301 264
265static struct xfs_log_item *
266__xfs_trans_ail_cursor_last(
267 struct xfs_ail *ailp,
268 xfs_lsn_t lsn)
269{
270 xfs_log_item_t *lip;
271
272 list_for_each_entry_reverse(lip, &ailp->xa_ail, li_ail) {
273 if (XFS_LSN_CMP(lip->li_lsn, lsn) <= 0)
274 return lip;
275 }
276 return NULL;
277}
278
279/*
280 * Find the last item in the AIL with the given @lsn by searching in descending
281 * LSN order and initialise the cursor to point to that item. If there is no
282 * item with the value of @lsn, then it sets the cursor to the last item with an
283 * LSN lower than @lsn. Returns NULL if the list is empty.
284 */
285struct xfs_log_item *
286xfs_trans_ail_cursor_last(
287 struct xfs_ail *ailp,
288 struct xfs_ail_cursor *cur,
289 xfs_lsn_t lsn)
290{
291 xfs_trans_ail_cursor_init(ailp, cur);
292 cur->item = __xfs_trans_ail_cursor_last(ailp, lsn);
293 return cur->item;
294}
295
302/* 296/*
303 * splice the log item list into the AIL at the given LSN. 297 * Splice the log item list into the AIL at the given LSN. We splice to the
298 * tail of the given LSN to maintain insert order for push traversals. The
299 * cursor is optional, allowing repeated updates to the same LSN to avoid
300 * repeated traversals. This should not be called with an empty list.
304 */ 301 */
305static void 302static void
306xfs_ail_splice( 303xfs_ail_splice(
307 struct xfs_ail *ailp, 304 struct xfs_ail *ailp,
308 struct list_head *list, 305 struct xfs_ail_cursor *cur,
309 xfs_lsn_t lsn) 306 struct list_head *list,
307 xfs_lsn_t lsn)
310{ 308{
311 xfs_log_item_t *next_lip; 309 struct xfs_log_item *lip;
312 310
313 /* If the list is empty, just insert the item. */ 311 ASSERT(!list_empty(list));
314 if (list_empty(&ailp->xa_ail)) {
315 list_splice(list, &ailp->xa_ail);
316 return;
317 }
318 312
319 list_for_each_entry_reverse(next_lip, &ailp->xa_ail, li_ail) { 313 /*
320 if (XFS_LSN_CMP(next_lip->li_lsn, lsn) <= 0) 314 * Use the cursor to determine the insertion point if one is
321 break; 315 * provided. If not, or if the one we got is not valid,
322 } 316 * find the place in the AIL where the items belong.
317 */
318 lip = cur ? cur->item : NULL;
319 if (!lip || (__psint_t) lip & 1)
320 lip = __xfs_trans_ail_cursor_last(ailp, lsn);
323 321
324 ASSERT(&next_lip->li_ail == &ailp->xa_ail || 322 /*
325 XFS_LSN_CMP(next_lip->li_lsn, lsn) <= 0); 323 * If a cursor is provided, we know we're processing the AIL
324 * in lsn order, and future items to be spliced in will
325 * follow the last one being inserted now. Update the
326 * cursor to point to that last item, now while we have a
327 * reliable pointer to it.
328 */
329 if (cur)
330 cur->item = list_entry(list->prev, struct xfs_log_item, li_ail);
326 331
327 list_splice_init(list, &next_lip->li_ail); 332 /*
333 * Finally perform the splice. Unless the AIL was empty,
334 * lip points to the item in the AIL _after_ which the new
335 * items should go. If lip is null the AIL was empty, so
336 * the new items go at the head of the AIL.
337 */
338 if (lip)
339 list_splice(list, &lip->li_ail);
340 else
341 list_splice(list, &ailp->xa_ail);
328} 342}
329 343
330/* 344/*
@@ -340,18 +354,12 @@ xfs_ail_delete(
340 xfs_trans_ail_cursor_clear(ailp, lip); 354 xfs_trans_ail_cursor_clear(ailp, lip);
341} 355}
342 356
343/* 357static long
344 * xfs_ail_worker does the work of pushing on the AIL. It will requeue itself 358xfsaild_push(
345 * to run at a later time if there is more work to do to complete the push. 359 struct xfs_ail *ailp)
346 */
347STATIC void
348xfs_ail_worker(
349 struct work_struct *work)
350{ 360{
351 struct xfs_ail *ailp = container_of(to_delayed_work(work),
352 struct xfs_ail, xa_work);
353 xfs_mount_t *mp = ailp->xa_mount; 361 xfs_mount_t *mp = ailp->xa_mount;
354 struct xfs_ail_cursor *cur = &ailp->xa_cursors; 362 struct xfs_ail_cursor cur;
355 xfs_log_item_t *lip; 363 xfs_log_item_t *lip;
356 xfs_lsn_t lsn; 364 xfs_lsn_t lsn;
357 xfs_lsn_t target; 365 xfs_lsn_t target;
@@ -363,13 +371,12 @@ xfs_ail_worker(
363 371
364 spin_lock(&ailp->xa_lock); 372 spin_lock(&ailp->xa_lock);
365 target = ailp->xa_target; 373 target = ailp->xa_target;
366 xfs_trans_ail_cursor_init(ailp, cur); 374 lip = xfs_trans_ail_cursor_first(ailp, &cur, ailp->xa_last_pushed_lsn);
367 lip = xfs_trans_ail_cursor_first(ailp, cur, ailp->xa_last_pushed_lsn);
368 if (!lip || XFS_FORCED_SHUTDOWN(mp)) { 375 if (!lip || XFS_FORCED_SHUTDOWN(mp)) {
369 /* 376 /*
370 * AIL is empty or our push has reached the end. 377 * AIL is empty or our push has reached the end.
371 */ 378 */
372 xfs_trans_ail_cursor_done(ailp, cur); 379 xfs_trans_ail_cursor_done(ailp, &cur);
373 spin_unlock(&ailp->xa_lock); 380 spin_unlock(&ailp->xa_lock);
374 goto out_done; 381 goto out_done;
375 } 382 }
@@ -412,8 +419,13 @@ xfs_ail_worker(
412 419
413 case XFS_ITEM_PUSHBUF: 420 case XFS_ITEM_PUSHBUF:
414 XFS_STATS_INC(xs_push_ail_pushbuf); 421 XFS_STATS_INC(xs_push_ail_pushbuf);
415 IOP_PUSHBUF(lip); 422
416 ailp->xa_last_pushed_lsn = lsn; 423 if (!IOP_PUSHBUF(lip)) {
424 stuck++;
425 flush_log = 1;
426 } else {
427 ailp->xa_last_pushed_lsn = lsn;
428 }
417 push_xfsbufd = 1; 429 push_xfsbufd = 1;
418 break; 430 break;
419 431
@@ -425,7 +437,6 @@ xfs_ail_worker(
425 437
426 case XFS_ITEM_LOCKED: 438 case XFS_ITEM_LOCKED:
427 XFS_STATS_INC(xs_push_ail_locked); 439 XFS_STATS_INC(xs_push_ail_locked);
428 ailp->xa_last_pushed_lsn = lsn;
429 stuck++; 440 stuck++;
430 break; 441 break;
431 442
@@ -457,12 +468,12 @@ xfs_ail_worker(
457 if (stuck > 100) 468 if (stuck > 100)
458 break; 469 break;
459 470
460 lip = xfs_trans_ail_cursor_next(ailp, cur); 471 lip = xfs_trans_ail_cursor_next(ailp, &cur);
461 if (lip == NULL) 472 if (lip == NULL)
462 break; 473 break;
463 lsn = lip->li_lsn; 474 lsn = lip->li_lsn;
464 } 475 }
465 xfs_trans_ail_cursor_done(ailp, cur); 476 xfs_trans_ail_cursor_done(ailp, &cur);
466 spin_unlock(&ailp->xa_lock); 477 spin_unlock(&ailp->xa_lock);
467 478
468 if (flush_log) { 479 if (flush_log) {
@@ -486,20 +497,6 @@ out_done:
486 /* We're past our target or empty, so idle */ 497 /* We're past our target or empty, so idle */
487 ailp->xa_last_pushed_lsn = 0; 498 ailp->xa_last_pushed_lsn = 0;
488 499
489 /*
490 * We clear the XFS_AIL_PUSHING_BIT first before checking
491 * whether the target has changed. If the target has changed,
492 * this pushes the requeue race directly onto the result of the
493 * atomic test/set bit, so we are guaranteed that either the
494 * the pusher that changed the target or ourselves will requeue
495 * the work (but not both).
496 */
497 clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags);
498 smp_rmb();
499 if (XFS_LSN_CMP(ailp->xa_target, target) == 0 ||
500 test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
501 return;
502
503 tout = 50; 500 tout = 50;
504 } else if (XFS_LSN_CMP(lsn, target) >= 0) { 501 } else if (XFS_LSN_CMP(lsn, target) >= 0) {
505 /* 502 /*
@@ -522,9 +519,30 @@ out_done:
522 tout = 20; 519 tout = 20;
523 } 520 }
524 521
525 /* There is more to do, requeue us. */ 522 return tout;
526 queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 523}
527 msecs_to_jiffies(tout)); 524
525static int
526xfsaild(
527 void *data)
528{
529 struct xfs_ail *ailp = data;
530 long tout = 0; /* milliseconds */
531
532 while (!kthread_should_stop()) {
533 if (tout && tout <= 20)
534 __set_current_state(TASK_KILLABLE);
535 else
536 __set_current_state(TASK_INTERRUPTIBLE);
537 schedule_timeout(tout ?
538 msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT);
539
540 try_to_freeze();
541
542 tout = xfsaild_push(ailp);
543 }
544
545 return 0;
528} 546}
529 547
530/* 548/*
@@ -559,8 +577,9 @@ xfs_ail_push(
559 */ 577 */
560 smp_wmb(); 578 smp_wmb();
561 xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn); 579 xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn);
562 if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags)) 580 smp_wmb();
563 queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0); 581
582 wake_up_process(ailp->xa_task);
564} 583}
565 584
566/* 585/*
@@ -645,6 +664,7 @@ xfs_trans_unlocked_item(
645void 664void
646xfs_trans_ail_update_bulk( 665xfs_trans_ail_update_bulk(
647 struct xfs_ail *ailp, 666 struct xfs_ail *ailp,
667 struct xfs_ail_cursor *cur,
648 struct xfs_log_item **log_items, 668 struct xfs_log_item **log_items,
649 int nr_items, 669 int nr_items,
650 xfs_lsn_t lsn) __releases(ailp->xa_lock) 670 xfs_lsn_t lsn) __releases(ailp->xa_lock)
@@ -655,6 +675,7 @@ xfs_trans_ail_update_bulk(
655 int i; 675 int i;
656 LIST_HEAD(tmp); 676 LIST_HEAD(tmp);
657 677
678 ASSERT(nr_items > 0); /* Not required, but true. */
658 mlip = xfs_ail_min(ailp); 679 mlip = xfs_ail_min(ailp);
659 680
660 for (i = 0; i < nr_items; i++) { 681 for (i = 0; i < nr_items; i++) {
@@ -674,7 +695,8 @@ xfs_trans_ail_update_bulk(
674 list_add(&lip->li_ail, &tmp); 695 list_add(&lip->li_ail, &tmp);
675 } 696 }
676 697
677 xfs_ail_splice(ailp, &tmp, lsn); 698 if (!list_empty(&tmp))
699 xfs_ail_splice(ailp, cur, &tmp, lsn);
678 700
679 if (!mlip_changed) { 701 if (!mlip_changed) {
680 spin_unlock(&ailp->xa_lock); 702 spin_unlock(&ailp->xa_lock);
@@ -793,10 +815,20 @@ xfs_trans_ail_init(
793 815
794 ailp->xa_mount = mp; 816 ailp->xa_mount = mp;
795 INIT_LIST_HEAD(&ailp->xa_ail); 817 INIT_LIST_HEAD(&ailp->xa_ail);
818 INIT_LIST_HEAD(&ailp->xa_cursors);
796 spin_lock_init(&ailp->xa_lock); 819 spin_lock_init(&ailp->xa_lock);
797 INIT_DELAYED_WORK(&ailp->xa_work, xfs_ail_worker); 820
821 ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s",
822 ailp->xa_mount->m_fsname);
823 if (IS_ERR(ailp->xa_task))
824 goto out_free_ailp;
825
798 mp->m_ail = ailp; 826 mp->m_ail = ailp;
799 return 0; 827 return 0;
828
829out_free_ailp:
830 kmem_free(ailp);
831 return ENOMEM;
800} 832}
801 833
802void 834void
@@ -805,6 +837,6 @@ xfs_trans_ail_destroy(
805{ 837{
806 struct xfs_ail *ailp = mp->m_ail; 838 struct xfs_ail *ailp = mp->m_ail;
807 839
808 cancel_delayed_work_sync(&ailp->xa_work); 840 kthread_stop(ailp->xa_task);
809 kmem_free(ailp); 841 kmem_free(ailp);
810} 842}
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 03b3b7f85a3..137e2b9e294 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -54,7 +54,7 @@ xfs_trans_buf_item_match(
54 list_for_each_entry(lidp, &tp->t_items, lid_trans) { 54 list_for_each_entry(lidp, &tp->t_items, lid_trans) {
55 blip = (struct xfs_buf_log_item *)lidp->lid_item; 55 blip = (struct xfs_buf_log_item *)lidp->lid_item;
56 if (blip->bli_item.li_type == XFS_LI_BUF && 56 if (blip->bli_item.li_type == XFS_LI_BUF &&
57 XFS_BUF_TARGET(blip->bli_buf) == target && 57 blip->bli_buf->b_target == target &&
58 XFS_BUF_ADDR(blip->bli_buf) == blkno && 58 XFS_BUF_ADDR(blip->bli_buf) == blkno &&
59 XFS_BUF_COUNT(blip->bli_buf) == len) 59 XFS_BUF_COUNT(blip->bli_buf) == len)
60 return blip->bli_buf; 60 return blip->bli_buf;
@@ -80,8 +80,7 @@ _xfs_trans_bjoin(
80{ 80{
81 struct xfs_buf_log_item *bip; 81 struct xfs_buf_log_item *bip;
82 82
83 ASSERT(XFS_BUF_ISBUSY(bp)); 83 ASSERT(bp->b_transp == NULL);
84 ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
85 84
86 /* 85 /*
87 * The xfs_buf_log_item pointer is stored in b_fsprivate. If 86 * The xfs_buf_log_item pointer is stored in b_fsprivate. If
@@ -89,7 +88,7 @@ _xfs_trans_bjoin(
89 * The checks to see if one is there are in xfs_buf_item_init(). 88 * The checks to see if one is there are in xfs_buf_item_init().
90 */ 89 */
91 xfs_buf_item_init(bp, tp->t_mountp); 90 xfs_buf_item_init(bp, tp->t_mountp);
92 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 91 bip = bp->b_fspriv;
93 ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); 92 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
94 ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); 93 ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));
95 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED)); 94 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
@@ -110,7 +109,7 @@ _xfs_trans_bjoin(
110 * Initialize b_fsprivate2 so we can find it with incore_match() 109 * Initialize b_fsprivate2 so we can find it with incore_match()
111 * in xfs_trans_get_buf() and friends above. 110 * in xfs_trans_get_buf() and friends above.
112 */ 111 */
113 XFS_BUF_SET_FSPRIVATE2(bp, tp); 112 bp->b_transp = tp;
114 113
115} 114}
116 115
@@ -160,7 +159,7 @@ xfs_trans_get_buf(xfs_trans_t *tp,
160 */ 159 */
161 bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len); 160 bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len);
162 if (bp != NULL) { 161 if (bp != NULL) {
163 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); 162 ASSERT(xfs_buf_islocked(bp));
164 if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) 163 if (XFS_FORCED_SHUTDOWN(tp->t_mountp))
165 XFS_BUF_SUPER_STALE(bp); 164 XFS_BUF_SUPER_STALE(bp);
166 165
@@ -172,8 +171,8 @@ xfs_trans_get_buf(xfs_trans_t *tp,
172 else if (XFS_BUF_ISSTALE(bp)) 171 else if (XFS_BUF_ISSTALE(bp))
173 ASSERT(!XFS_BUF_ISDELAYWRITE(bp)); 172 ASSERT(!XFS_BUF_ISDELAYWRITE(bp));
174 173
175 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); 174 ASSERT(bp->b_transp == tp);
176 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 175 bip = bp->b_fspriv;
177 ASSERT(bip != NULL); 176 ASSERT(bip != NULL);
178 ASSERT(atomic_read(&bip->bli_refcount) > 0); 177 ASSERT(atomic_read(&bip->bli_refcount) > 0);
179 bip->bli_recur++; 178 bip->bli_recur++;
@@ -194,7 +193,7 @@ xfs_trans_get_buf(xfs_trans_t *tp,
194 return NULL; 193 return NULL;
195 } 194 }
196 195
197 ASSERT(!XFS_BUF_GETERROR(bp)); 196 ASSERT(!bp->b_error);
198 197
199 _xfs_trans_bjoin(tp, bp, 1); 198 _xfs_trans_bjoin(tp, bp, 1);
200 trace_xfs_trans_get_buf(bp->b_fspriv); 199 trace_xfs_trans_get_buf(bp->b_fspriv);
@@ -232,8 +231,8 @@ xfs_trans_getsb(xfs_trans_t *tp,
232 * recursion count and return the buffer to the caller. 231 * recursion count and return the buffer to the caller.
233 */ 232 */
234 bp = mp->m_sb_bp; 233 bp = mp->m_sb_bp;
235 if (XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp) { 234 if (bp->b_transp == tp) {
236 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*); 235 bip = bp->b_fspriv;
237 ASSERT(bip != NULL); 236 ASSERT(bip != NULL);
238 ASSERT(atomic_read(&bip->bli_refcount) > 0); 237 ASSERT(atomic_read(&bip->bli_refcount) > 0);
239 bip->bli_recur++; 238 bip->bli_recur++;
@@ -293,10 +292,10 @@ xfs_trans_read_buf(
293 return (flags & XBF_TRYLOCK) ? 292 return (flags & XBF_TRYLOCK) ?
294 EAGAIN : XFS_ERROR(ENOMEM); 293 EAGAIN : XFS_ERROR(ENOMEM);
295 294
296 if (XFS_BUF_GETERROR(bp) != 0) { 295 if (bp->b_error) {
296 error = bp->b_error;
297 xfs_ioerror_alert("xfs_trans_read_buf", mp, 297 xfs_ioerror_alert("xfs_trans_read_buf", mp,
298 bp, blkno); 298 bp, blkno);
299 error = XFS_BUF_GETERROR(bp);
300 xfs_buf_relse(bp); 299 xfs_buf_relse(bp);
301 return error; 300 return error;
302 } 301 }
@@ -327,10 +326,10 @@ xfs_trans_read_buf(
327 */ 326 */
328 bp = xfs_trans_buf_item_match(tp, target, blkno, len); 327 bp = xfs_trans_buf_item_match(tp, target, blkno, len);
329 if (bp != NULL) { 328 if (bp != NULL) {
330 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); 329 ASSERT(xfs_buf_islocked(bp));
331 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); 330 ASSERT(bp->b_transp == tp);
332 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); 331 ASSERT(bp->b_fspriv != NULL);
333 ASSERT((XFS_BUF_ISERROR(bp)) == 0); 332 ASSERT(!bp->b_error);
334 if (!(XFS_BUF_ISDONE(bp))) { 333 if (!(XFS_BUF_ISDONE(bp))) {
335 trace_xfs_trans_read_buf_io(bp, _RET_IP_); 334 trace_xfs_trans_read_buf_io(bp, _RET_IP_);
336 ASSERT(!XFS_BUF_ISASYNC(bp)); 335 ASSERT(!XFS_BUF_ISASYNC(bp));
@@ -363,7 +362,7 @@ xfs_trans_read_buf(
363 } 362 }
364 363
365 364
366 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*); 365 bip = bp->b_fspriv;
367 bip->bli_recur++; 366 bip->bli_recur++;
368 367
369 ASSERT(atomic_read(&bip->bli_refcount) > 0); 368 ASSERT(atomic_read(&bip->bli_refcount) > 0);
@@ -386,10 +385,9 @@ xfs_trans_read_buf(
386 return (flags & XBF_TRYLOCK) ? 385 return (flags & XBF_TRYLOCK) ?
387 0 : XFS_ERROR(ENOMEM); 386 0 : XFS_ERROR(ENOMEM);
388 } 387 }
389 if (XFS_BUF_GETERROR(bp) != 0) { 388 if (bp->b_error) {
390 XFS_BUF_SUPER_STALE(bp); 389 error = bp->b_error;
391 error = XFS_BUF_GETERROR(bp); 390 XFS_BUF_SUPER_STALE(bp);
392
393 xfs_ioerror_alert("xfs_trans_read_buf", mp, 391 xfs_ioerror_alert("xfs_trans_read_buf", mp,
394 bp, blkno); 392 bp, blkno);
395 if (tp->t_flags & XFS_TRANS_DIRTY) 393 if (tp->t_flags & XFS_TRANS_DIRTY)
@@ -430,7 +428,7 @@ shutdown_abort:
430 if (XFS_BUF_ISSTALE(bp) && XFS_BUF_ISDELAYWRITE(bp)) 428 if (XFS_BUF_ISSTALE(bp) && XFS_BUF_ISDELAYWRITE(bp))
431 xfs_notice(mp, "about to pop assert, bp == 0x%p", bp); 429 xfs_notice(mp, "about to pop assert, bp == 0x%p", bp);
432#endif 430#endif
433 ASSERT((XFS_BUF_BFLAGS(bp) & (XBF_STALE|XBF_DELWRI)) != 431 ASSERT((bp->b_flags & (XBF_STALE|XBF_DELWRI)) !=
434 (XBF_STALE|XBF_DELWRI)); 432 (XBF_STALE|XBF_DELWRI));
435 433
436 trace_xfs_trans_read_buf_shut(bp, _RET_IP_); 434 trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
@@ -460,32 +458,30 @@ xfs_trans_brelse(xfs_trans_t *tp,
460 xfs_buf_t *bp) 458 xfs_buf_t *bp)
461{ 459{
462 xfs_buf_log_item_t *bip; 460 xfs_buf_log_item_t *bip;
463 xfs_log_item_t *lip;
464 461
465 /* 462 /*
466 * Default to a normal brelse() call if the tp is NULL. 463 * Default to a normal brelse() call if the tp is NULL.
467 */ 464 */
468 if (tp == NULL) { 465 if (tp == NULL) {
469 ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL); 466 struct xfs_log_item *lip = bp->b_fspriv;
467
468 ASSERT(bp->b_transp == NULL);
469
470 /* 470 /*
471 * If there's a buf log item attached to the buffer, 471 * If there's a buf log item attached to the buffer,
472 * then let the AIL know that the buffer is being 472 * then let the AIL know that the buffer is being
473 * unlocked. 473 * unlocked.
474 */ 474 */
475 if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) { 475 if (lip != NULL && lip->li_type == XFS_LI_BUF) {
476 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); 476 bip = bp->b_fspriv;
477 if (lip->li_type == XFS_LI_BUF) { 477 xfs_trans_unlocked_item(bip->bli_item.li_ailp, lip);
478 bip = XFS_BUF_FSPRIVATE(bp,xfs_buf_log_item_t*);
479 xfs_trans_unlocked_item(bip->bli_item.li_ailp,
480 lip);
481 }
482 } 478 }
483 xfs_buf_relse(bp); 479 xfs_buf_relse(bp);
484 return; 480 return;
485 } 481 }
486 482
487 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); 483 ASSERT(bp->b_transp == tp);
488 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 484 bip = bp->b_fspriv;
489 ASSERT(bip->bli_item.li_type == XFS_LI_BUF); 485 ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
490 ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); 486 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
491 ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); 487 ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));
@@ -556,7 +552,7 @@ xfs_trans_brelse(xfs_trans_t *tp,
556 xfs_buf_item_relse(bp); 552 xfs_buf_item_relse(bp);
557 bip = NULL; 553 bip = NULL;
558 } 554 }
559 XFS_BUF_SET_FSPRIVATE2(bp, NULL); 555 bp->b_transp = NULL;
560 556
561 /* 557 /*
562 * If we've still got a buf log item on the buffer, then 558 * If we've still got a buf log item on the buffer, then
@@ -581,16 +577,14 @@ void
581xfs_trans_bhold(xfs_trans_t *tp, 577xfs_trans_bhold(xfs_trans_t *tp,
582 xfs_buf_t *bp) 578 xfs_buf_t *bp)
583{ 579{
584 xfs_buf_log_item_t *bip; 580 xfs_buf_log_item_t *bip = bp->b_fspriv;
585
586 ASSERT(XFS_BUF_ISBUSY(bp));
587 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
588 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
589 581
590 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 582 ASSERT(bp->b_transp == tp);
583 ASSERT(bip != NULL);
591 ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); 584 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
592 ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); 585 ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));
593 ASSERT(atomic_read(&bip->bli_refcount) > 0); 586 ASSERT(atomic_read(&bip->bli_refcount) > 0);
587
594 bip->bli_flags |= XFS_BLI_HOLD; 588 bip->bli_flags |= XFS_BLI_HOLD;
595 trace_xfs_trans_bhold(bip); 589 trace_xfs_trans_bhold(bip);
596} 590}
@@ -603,19 +597,16 @@ void
603xfs_trans_bhold_release(xfs_trans_t *tp, 597xfs_trans_bhold_release(xfs_trans_t *tp,
604 xfs_buf_t *bp) 598 xfs_buf_t *bp)
605{ 599{
606 xfs_buf_log_item_t *bip; 600 xfs_buf_log_item_t *bip = bp->b_fspriv;
607
608 ASSERT(XFS_BUF_ISBUSY(bp));
609 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
610 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
611 601
612 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 602 ASSERT(bp->b_transp == tp);
603 ASSERT(bip != NULL);
613 ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); 604 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
614 ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); 605 ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));
615 ASSERT(atomic_read(&bip->bli_refcount) > 0); 606 ASSERT(atomic_read(&bip->bli_refcount) > 0);
616 ASSERT(bip->bli_flags & XFS_BLI_HOLD); 607 ASSERT(bip->bli_flags & XFS_BLI_HOLD);
617 bip->bli_flags &= ~XFS_BLI_HOLD;
618 608
609 bip->bli_flags &= ~XFS_BLI_HOLD;
619 trace_xfs_trans_bhold_release(bip); 610 trace_xfs_trans_bhold_release(bip);
620} 611}
621 612
@@ -634,14 +625,13 @@ xfs_trans_log_buf(xfs_trans_t *tp,
634 uint first, 625 uint first,
635 uint last) 626 uint last)
636{ 627{
637 xfs_buf_log_item_t *bip; 628 xfs_buf_log_item_t *bip = bp->b_fspriv;
638 629
639 ASSERT(XFS_BUF_ISBUSY(bp)); 630 ASSERT(bp->b_transp == tp);
640 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); 631 ASSERT(bip != NULL);
641 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
642 ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp))); 632 ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp)));
643 ASSERT((XFS_BUF_IODONE_FUNC(bp) == NULL) || 633 ASSERT(bp->b_iodone == NULL ||
644 (XFS_BUF_IODONE_FUNC(bp) == xfs_buf_iodone_callbacks)); 634 bp->b_iodone == xfs_buf_iodone_callbacks);
645 635
646 /* 636 /*
647 * Mark the buffer as needing to be written out eventually, 637 * Mark the buffer as needing to be written out eventually,
@@ -656,9 +646,8 @@ xfs_trans_log_buf(xfs_trans_t *tp,
656 XFS_BUF_DELAYWRITE(bp); 646 XFS_BUF_DELAYWRITE(bp);
657 XFS_BUF_DONE(bp); 647 XFS_BUF_DONE(bp);
658 648
659 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
660 ASSERT(atomic_read(&bip->bli_refcount) > 0); 649 ASSERT(atomic_read(&bip->bli_refcount) > 0);
661 XFS_BUF_SET_IODONE_FUNC(bp, xfs_buf_iodone_callbacks); 650 bp->b_iodone = xfs_buf_iodone_callbacks;
662 bip->bli_item.li_cb = xfs_buf_iodone; 651 bip->bli_item.li_cb = xfs_buf_iodone;
663 652
664 trace_xfs_trans_log_buf(bip); 653 trace_xfs_trans_log_buf(bip);
@@ -706,13 +695,10 @@ xfs_trans_binval(
706 xfs_trans_t *tp, 695 xfs_trans_t *tp,
707 xfs_buf_t *bp) 696 xfs_buf_t *bp)
708{ 697{
709 xfs_buf_log_item_t *bip; 698 xfs_buf_log_item_t *bip = bp->b_fspriv;
710
711 ASSERT(XFS_BUF_ISBUSY(bp));
712 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
713 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
714 699
715 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 700 ASSERT(bp->b_transp == tp);
701 ASSERT(bip != NULL);
716 ASSERT(atomic_read(&bip->bli_refcount) > 0); 702 ASSERT(atomic_read(&bip->bli_refcount) > 0);
717 703
718 trace_xfs_trans_binval(bip); 704 trace_xfs_trans_binval(bip);
@@ -780,13 +766,10 @@ xfs_trans_inode_buf(
780 xfs_trans_t *tp, 766 xfs_trans_t *tp,
781 xfs_buf_t *bp) 767 xfs_buf_t *bp)
782{ 768{
783 xfs_buf_log_item_t *bip; 769 xfs_buf_log_item_t *bip = bp->b_fspriv;
784
785 ASSERT(XFS_BUF_ISBUSY(bp));
786 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
787 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
788 770
789 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 771 ASSERT(bp->b_transp == tp);
772 ASSERT(bip != NULL);
790 ASSERT(atomic_read(&bip->bli_refcount) > 0); 773 ASSERT(atomic_read(&bip->bli_refcount) > 0);
791 774
792 bip->bli_flags |= XFS_BLI_INODE_BUF; 775 bip->bli_flags |= XFS_BLI_INODE_BUF;
@@ -806,13 +789,10 @@ xfs_trans_stale_inode_buf(
806 xfs_trans_t *tp, 789 xfs_trans_t *tp,
807 xfs_buf_t *bp) 790 xfs_buf_t *bp)
808{ 791{
809 xfs_buf_log_item_t *bip; 792 xfs_buf_log_item_t *bip = bp->b_fspriv;
810 793
811 ASSERT(XFS_BUF_ISBUSY(bp)); 794 ASSERT(bp->b_transp == tp);
812 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); 795 ASSERT(bip != NULL);
813 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
814
815 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
816 ASSERT(atomic_read(&bip->bli_refcount) > 0); 796 ASSERT(atomic_read(&bip->bli_refcount) > 0);
817 797
818 bip->bli_flags |= XFS_BLI_STALE_INODE; 798 bip->bli_flags |= XFS_BLI_STALE_INODE;
@@ -833,13 +813,10 @@ xfs_trans_inode_alloc_buf(
833 xfs_trans_t *tp, 813 xfs_trans_t *tp,
834 xfs_buf_t *bp) 814 xfs_buf_t *bp)
835{ 815{
836 xfs_buf_log_item_t *bip; 816 xfs_buf_log_item_t *bip = bp->b_fspriv;
837
838 ASSERT(XFS_BUF_ISBUSY(bp));
839 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
840 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
841 817
842 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 818 ASSERT(bp->b_transp == tp);
819 ASSERT(bip != NULL);
843 ASSERT(atomic_read(&bip->bli_refcount) > 0); 820 ASSERT(atomic_read(&bip->bli_refcount) > 0);
844 821
845 bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF; 822 bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
@@ -863,16 +840,13 @@ xfs_trans_dquot_buf(
863 xfs_buf_t *bp, 840 xfs_buf_t *bp,
864 uint type) 841 uint type)
865{ 842{
866 xfs_buf_log_item_t *bip; 843 xfs_buf_log_item_t *bip = bp->b_fspriv;
867 844
868 ASSERT(XFS_BUF_ISBUSY(bp)); 845 ASSERT(bp->b_transp == tp);
869 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); 846 ASSERT(bip != NULL);
870 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
871 ASSERT(type == XFS_BLF_UDQUOT_BUF || 847 ASSERT(type == XFS_BLF_UDQUOT_BUF ||
872 type == XFS_BLF_PDQUOT_BUF || 848 type == XFS_BLF_PDQUOT_BUF ||
873 type == XFS_BLF_GDQUOT_BUF); 849 type == XFS_BLF_GDQUOT_BUF);
874
875 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
876 ASSERT(atomic_read(&bip->bli_refcount) > 0); 850 ASSERT(atomic_read(&bip->bli_refcount) > 0);
877 851
878 bip->bli_format.blf_flags |= type; 852 bip->bli_format.blf_flags |= type;
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 2a364873133..4d00ee67792 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -59,7 +59,7 @@ xfs_trans_dqjoin(
59 xfs_trans_add_item(tp, &dqp->q_logitem.qli_item); 59 xfs_trans_add_item(tp, &dqp->q_logitem.qli_item);
60 60
61 /* 61 /*
62 * Initialize i_transp so we can later determine if this dquot is 62 * Initialize d_transp so we can later determine if this dquot is
63 * associated with this transaction. 63 * associated with this transaction.
64 */ 64 */
65 dqp->q_transp = tp; 65 dqp->q_transp = tp;
@@ -387,18 +387,18 @@ xfs_trans_apply_dquot_deltas(
387 qtrx->qt_delbcnt_delta; 387 qtrx->qt_delbcnt_delta;
388 totalrtbdelta = qtrx->qt_rtbcount_delta + 388 totalrtbdelta = qtrx->qt_rtbcount_delta +
389 qtrx->qt_delrtb_delta; 389 qtrx->qt_delrtb_delta;
390#ifdef QUOTADEBUG 390#ifdef DEBUG
391 if (totalbdelta < 0) 391 if (totalbdelta < 0)
392 ASSERT(be64_to_cpu(d->d_bcount) >= 392 ASSERT(be64_to_cpu(d->d_bcount) >=
393 (xfs_qcnt_t) -totalbdelta); 393 -totalbdelta);
394 394
395 if (totalrtbdelta < 0) 395 if (totalrtbdelta < 0)
396 ASSERT(be64_to_cpu(d->d_rtbcount) >= 396 ASSERT(be64_to_cpu(d->d_rtbcount) >=
397 (xfs_qcnt_t) -totalrtbdelta); 397 -totalrtbdelta);
398 398
399 if (qtrx->qt_icount_delta < 0) 399 if (qtrx->qt_icount_delta < 0)
400 ASSERT(be64_to_cpu(d->d_icount) >= 400 ASSERT(be64_to_cpu(d->d_icount) >=
401 (xfs_qcnt_t) -qtrx->qt_icount_delta); 401 -qtrx->qt_icount_delta);
402#endif 402#endif
403 if (totalbdelta) 403 if (totalbdelta)
404 be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta); 404 be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta);
@@ -642,11 +642,6 @@ xfs_trans_dqresv(
642 ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) || 642 ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
643 (XFS_IS_OQUOTA_ENFORCED(dqp->q_mount) && 643 (XFS_IS_OQUOTA_ENFORCED(dqp->q_mount) &&
644 (XFS_QM_ISPDQ(dqp) || XFS_QM_ISGDQ(dqp))))) { 644 (XFS_QM_ISPDQ(dqp) || XFS_QM_ISGDQ(dqp))))) {
645#ifdef QUOTADEBUG
646 xfs_debug(mp,
647 "BLK Res: nblks=%ld + resbcount=%Ld > hardlimit=%Ld?",
648 nblks, *resbcountp, hardlimit);
649#endif
650 if (nblks > 0) { 645 if (nblks > 0) {
651 /* 646 /*
652 * dquot is locked already. See if we'd go over the 647 * dquot is locked already. See if we'd go over the
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index 048b0c689d3..c8dea2fd7e6 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -55,7 +55,6 @@ xfs_trans_ijoin(
55{ 55{
56 xfs_inode_log_item_t *iip; 56 xfs_inode_log_item_t *iip;
57 57
58 ASSERT(ip->i_transp == NULL);
59 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 58 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
60 if (ip->i_itemp == NULL) 59 if (ip->i_itemp == NULL)
61 xfs_inode_item_init(ip, ip->i_mount); 60 xfs_inode_item_init(ip, ip->i_mount);
@@ -68,12 +67,6 @@ xfs_trans_ijoin(
68 xfs_trans_add_item(tp, &iip->ili_item); 67 xfs_trans_add_item(tp, &iip->ili_item);
69 68
70 xfs_trans_inode_broot_debug(ip); 69 xfs_trans_inode_broot_debug(ip);
71
72 /*
73 * Initialize i_transp so we can find it with xfs_inode_incore()
74 * in xfs_trans_iget() above.
75 */
76 ip->i_transp = tp;
77} 70}
78 71
79/* 72/*
@@ -111,7 +104,6 @@ xfs_trans_ichgtime(
111 104
112 ASSERT(tp); 105 ASSERT(tp);
113 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 106 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
114 ASSERT(ip->i_transp == tp);
115 107
116 tv = current_fs_time(inode->i_sb); 108 tv = current_fs_time(inode->i_sb);
117 109
@@ -140,7 +132,6 @@ xfs_trans_log_inode(
140 xfs_inode_t *ip, 132 xfs_inode_t *ip,
141 uint flags) 133 uint flags)
142{ 134{
143 ASSERT(ip->i_transp == tp);
144 ASSERT(ip->i_itemp != NULL); 135 ASSERT(ip->i_itemp != NULL);
145 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 136 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
146 137
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
index 6b164e9e9a1..22750b5e4a8 100644
--- a/fs/xfs/xfs_trans_priv.h
+++ b/fs/xfs/xfs_trans_priv.h
@@ -53,7 +53,7 @@ void xfs_trans_committed_bulk(struct xfs_ail *ailp, struct xfs_log_vec *lv,
53 * of the list to trigger traversal restarts. 53 * of the list to trigger traversal restarts.
54 */ 54 */
55struct xfs_ail_cursor { 55struct xfs_ail_cursor {
56 struct xfs_ail_cursor *next; 56 struct list_head list;
57 struct xfs_log_item *item; 57 struct xfs_log_item *item;
58}; 58};
59 59
@@ -64,24 +64,19 @@ struct xfs_ail_cursor {
64 */ 64 */
65struct xfs_ail { 65struct xfs_ail {
66 struct xfs_mount *xa_mount; 66 struct xfs_mount *xa_mount;
67 struct task_struct *xa_task;
67 struct list_head xa_ail; 68 struct list_head xa_ail;
68 xfs_lsn_t xa_target; 69 xfs_lsn_t xa_target;
69 struct xfs_ail_cursor xa_cursors; 70 struct list_head xa_cursors;
70 spinlock_t xa_lock; 71 spinlock_t xa_lock;
71 struct delayed_work xa_work;
72 xfs_lsn_t xa_last_pushed_lsn; 72 xfs_lsn_t xa_last_pushed_lsn;
73 unsigned long xa_flags;
74}; 73};
75 74
76#define XFS_AIL_PUSHING_BIT 0
77
78/* 75/*
79 * From xfs_trans_ail.c 76 * From xfs_trans_ail.c
80 */ 77 */
81
82extern struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
83
84void xfs_trans_ail_update_bulk(struct xfs_ail *ailp, 78void xfs_trans_ail_update_bulk(struct xfs_ail *ailp,
79 struct xfs_ail_cursor *cur,
85 struct xfs_log_item **log_items, int nr_items, 80 struct xfs_log_item **log_items, int nr_items,
86 xfs_lsn_t lsn) __releases(ailp->xa_lock); 81 xfs_lsn_t lsn) __releases(ailp->xa_lock);
87static inline void 82static inline void
@@ -90,7 +85,7 @@ xfs_trans_ail_update(
90 struct xfs_log_item *lip, 85 struct xfs_log_item *lip,
91 xfs_lsn_t lsn) __releases(ailp->xa_lock) 86 xfs_lsn_t lsn) __releases(ailp->xa_lock)
92{ 87{
93 xfs_trans_ail_update_bulk(ailp, &lip, 1, lsn); 88 xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn);
94} 89}
95 90
96void xfs_trans_ail_delete_bulk(struct xfs_ail *ailp, 91void xfs_trans_ail_delete_bulk(struct xfs_ail *ailp,
@@ -111,10 +106,13 @@ xfs_lsn_t xfs_ail_min_lsn(struct xfs_ail *ailp);
111void xfs_trans_unlocked_item(struct xfs_ail *, 106void xfs_trans_unlocked_item(struct xfs_ail *,
112 xfs_log_item_t *); 107 xfs_log_item_t *);
113 108
114struct xfs_log_item *xfs_trans_ail_cursor_first(struct xfs_ail *ailp, 109struct xfs_log_item * xfs_trans_ail_cursor_first(struct xfs_ail *ailp,
110 struct xfs_ail_cursor *cur,
111 xfs_lsn_t lsn);
112struct xfs_log_item * xfs_trans_ail_cursor_last(struct xfs_ail *ailp,
115 struct xfs_ail_cursor *cur, 113 struct xfs_ail_cursor *cur,
116 xfs_lsn_t lsn); 114 xfs_lsn_t lsn);
117struct xfs_log_item *xfs_trans_ail_cursor_next(struct xfs_ail *ailp, 115struct xfs_log_item * xfs_trans_ail_cursor_next(struct xfs_ail *ailp,
118 struct xfs_ail_cursor *cur); 116 struct xfs_ail_cursor *cur);
119void xfs_trans_ail_cursor_done(struct xfs_ail *ailp, 117void xfs_trans_ail_cursor_done(struct xfs_ail *ailp,
120 struct xfs_ail_cursor *cur); 118 struct xfs_ail_cursor *cur);
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/xfs_vnode.h
index 7c220b4227b..7c220b4227b 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/xfs_vnode.h
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 619720705bc..d92419f0f2b 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -50,430 +50,6 @@
50#include "xfs_vnodeops.h" 50#include "xfs_vnodeops.h"
51#include "xfs_trace.h" 51#include "xfs_trace.h"
52 52
53int
54xfs_setattr(
55 struct xfs_inode *ip,
56 struct iattr *iattr,
57 int flags)
58{
59 xfs_mount_t *mp = ip->i_mount;
60 struct inode *inode = VFS_I(ip);
61 int mask = iattr->ia_valid;
62 xfs_trans_t *tp;
63 int code;
64 uint lock_flags;
65 uint commit_flags=0;
66 uid_t uid=0, iuid=0;
67 gid_t gid=0, igid=0;
68 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
69 int need_iolock = 1;
70
71 trace_xfs_setattr(ip);
72
73 if (mp->m_flags & XFS_MOUNT_RDONLY)
74 return XFS_ERROR(EROFS);
75
76 if (XFS_FORCED_SHUTDOWN(mp))
77 return XFS_ERROR(EIO);
78
79 code = -inode_change_ok(inode, iattr);
80 if (code)
81 return code;
82
83 olddquot1 = olddquot2 = NULL;
84 udqp = gdqp = NULL;
85
86 /*
87 * If disk quotas is on, we make sure that the dquots do exist on disk,
88 * before we start any other transactions. Trying to do this later
89 * is messy. We don't care to take a readlock to look at the ids
90 * in inode here, because we can't hold it across the trans_reserve.
91 * If the IDs do change before we take the ilock, we're covered
92 * because the i_*dquot fields will get updated anyway.
93 */
94 if (XFS_IS_QUOTA_ON(mp) && (mask & (ATTR_UID|ATTR_GID))) {
95 uint qflags = 0;
96
97 if ((mask & ATTR_UID) && XFS_IS_UQUOTA_ON(mp)) {
98 uid = iattr->ia_uid;
99 qflags |= XFS_QMOPT_UQUOTA;
100 } else {
101 uid = ip->i_d.di_uid;
102 }
103 if ((mask & ATTR_GID) && XFS_IS_GQUOTA_ON(mp)) {
104 gid = iattr->ia_gid;
105 qflags |= XFS_QMOPT_GQUOTA;
106 } else {
107 gid = ip->i_d.di_gid;
108 }
109
110 /*
111 * We take a reference when we initialize udqp and gdqp,
112 * so it is important that we never blindly double trip on
113 * the same variable. See xfs_create() for an example.
114 */
115 ASSERT(udqp == NULL);
116 ASSERT(gdqp == NULL);
117 code = xfs_qm_vop_dqalloc(ip, uid, gid, xfs_get_projid(ip),
118 qflags, &udqp, &gdqp);
119 if (code)
120 return code;
121 }
122
123 /*
124 * For the other attributes, we acquire the inode lock and
125 * first do an error checking pass.
126 */
127 tp = NULL;
128 lock_flags = XFS_ILOCK_EXCL;
129 if (flags & XFS_ATTR_NOLOCK)
130 need_iolock = 0;
131 if (!(mask & ATTR_SIZE)) {
132 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
133 commit_flags = 0;
134 code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp),
135 0, 0, 0);
136 if (code) {
137 lock_flags = 0;
138 goto error_return;
139 }
140 } else {
141 if (need_iolock)
142 lock_flags |= XFS_IOLOCK_EXCL;
143 }
144
145 xfs_ilock(ip, lock_flags);
146
147 /*
148 * Change file ownership. Must be the owner or privileged.
149 */
150 if (mask & (ATTR_UID|ATTR_GID)) {
151 /*
152 * These IDs could have changed since we last looked at them.
153 * But, we're assured that if the ownership did change
154 * while we didn't have the inode locked, inode's dquot(s)
155 * would have changed also.
156 */
157 iuid = ip->i_d.di_uid;
158 igid = ip->i_d.di_gid;
159 gid = (mask & ATTR_GID) ? iattr->ia_gid : igid;
160 uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid;
161
162 /*
163 * Do a quota reservation only if uid/gid is actually
164 * going to change.
165 */
166 if (XFS_IS_QUOTA_RUNNING(mp) &&
167 ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
168 (XFS_IS_GQUOTA_ON(mp) && igid != gid))) {
169 ASSERT(tp);
170 code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
171 capable(CAP_FOWNER) ?
172 XFS_QMOPT_FORCE_RES : 0);
173 if (code) /* out of quota */
174 goto error_return;
175 }
176 }
177
178 /*
179 * Truncate file. Must have write permission and not be a directory.
180 */
181 if (mask & ATTR_SIZE) {
182 /* Short circuit the truncate case for zero length files */
183 if (iattr->ia_size == 0 &&
184 ip->i_size == 0 && ip->i_d.di_nextents == 0) {
185 xfs_iunlock(ip, XFS_ILOCK_EXCL);
186 lock_flags &= ~XFS_ILOCK_EXCL;
187 if (mask & ATTR_CTIME) {
188 inode->i_mtime = inode->i_ctime =
189 current_fs_time(inode->i_sb);
190 xfs_mark_inode_dirty_sync(ip);
191 }
192 code = 0;
193 goto error_return;
194 }
195
196 if (S_ISDIR(ip->i_d.di_mode)) {
197 code = XFS_ERROR(EISDIR);
198 goto error_return;
199 } else if (!S_ISREG(ip->i_d.di_mode)) {
200 code = XFS_ERROR(EINVAL);
201 goto error_return;
202 }
203
204 /*
205 * Make sure that the dquots are attached to the inode.
206 */
207 code = xfs_qm_dqattach_locked(ip, 0);
208 if (code)
209 goto error_return;
210
211 /*
212 * Now we can make the changes. Before we join the inode
213 * to the transaction, if ATTR_SIZE is set then take care of
214 * the part of the truncation that must be done without the
215 * inode lock. This needs to be done before joining the inode
216 * to the transaction, because the inode cannot be unlocked
217 * once it is a part of the transaction.
218 */
219 if (iattr->ia_size > ip->i_size) {
220 /*
221 * Do the first part of growing a file: zero any data
222 * in the last block that is beyond the old EOF. We
223 * need to do this before the inode is joined to the
224 * transaction to modify the i_size.
225 */
226 code = xfs_zero_eof(ip, iattr->ia_size, ip->i_size);
227 if (code)
228 goto error_return;
229 }
230 xfs_iunlock(ip, XFS_ILOCK_EXCL);
231 lock_flags &= ~XFS_ILOCK_EXCL;
232
233 /*
234 * We are going to log the inode size change in this
235 * transaction so any previous writes that are beyond the on
236 * disk EOF and the new EOF that have not been written out need
237 * to be written here. If we do not write the data out, we
238 * expose ourselves to the null files problem.
239 *
240 * Only flush from the on disk size to the smaller of the in
241 * memory file size or the new size as that's the range we
242 * really care about here and prevents waiting for other data
243 * not within the range we care about here.
244 */
245 if (ip->i_size != ip->i_d.di_size &&
246 iattr->ia_size > ip->i_d.di_size) {
247 code = xfs_flush_pages(ip,
248 ip->i_d.di_size, iattr->ia_size,
249 XBF_ASYNC, FI_NONE);
250 if (code)
251 goto error_return;
252 }
253
254 /* wait for all I/O to complete */
255 xfs_ioend_wait(ip);
256
257 code = -block_truncate_page(inode->i_mapping, iattr->ia_size,
258 xfs_get_blocks);
259 if (code)
260 goto error_return;
261
262 tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE);
263 code = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
264 XFS_TRANS_PERM_LOG_RES,
265 XFS_ITRUNCATE_LOG_COUNT);
266 if (code)
267 goto error_return;
268
269 truncate_setsize(inode, iattr->ia_size);
270
271 commit_flags = XFS_TRANS_RELEASE_LOG_RES;
272 lock_flags |= XFS_ILOCK_EXCL;
273
274 xfs_ilock(ip, XFS_ILOCK_EXCL);
275
276 xfs_trans_ijoin(tp, ip);
277
278 /*
279 * Only change the c/mtime if we are changing the size
280 * or we are explicitly asked to change it. This handles
281 * the semantic difference between truncate() and ftruncate()
282 * as implemented in the VFS.
283 *
284 * The regular truncate() case without ATTR_CTIME and ATTR_MTIME
285 * is a special case where we need to update the times despite
286 * not having these flags set. For all other operations the
287 * VFS set these flags explicitly if it wants a timestamp
288 * update.
289 */
290 if (iattr->ia_size != ip->i_size &&
291 (!(mask & (ATTR_CTIME | ATTR_MTIME)))) {
292 iattr->ia_ctime = iattr->ia_mtime =
293 current_fs_time(inode->i_sb);
294 mask |= ATTR_CTIME | ATTR_MTIME;
295 }
296
297 if (iattr->ia_size > ip->i_size) {
298 ip->i_d.di_size = iattr->ia_size;
299 ip->i_size = iattr->ia_size;
300 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
301 } else if (iattr->ia_size <= ip->i_size ||
302 (iattr->ia_size == 0 && ip->i_d.di_nextents)) {
303 /*
304 * signal a sync transaction unless
305 * we're truncating an already unlinked
306 * file on a wsync filesystem
307 */
308 code = xfs_itruncate_finish(&tp, ip, iattr->ia_size,
309 XFS_DATA_FORK,
310 ((ip->i_d.di_nlink != 0 ||
311 !(mp->m_flags & XFS_MOUNT_WSYNC))
312 ? 1 : 0));
313 if (code)
314 goto abort_return;
315 /*
316 * Truncated "down", so we're removing references
317 * to old data here - if we now delay flushing for
318 * a long time, we expose ourselves unduly to the
319 * notorious NULL files problem. So, we mark this
320 * vnode and flush it when the file is closed, and
321 * do not wait the usual (long) time for writeout.
322 */
323 xfs_iflags_set(ip, XFS_ITRUNCATED);
324 }
325 } else if (tp) {
326 xfs_trans_ijoin(tp, ip);
327 }
328
329 /*
330 * Change file ownership. Must be the owner or privileged.
331 */
332 if (mask & (ATTR_UID|ATTR_GID)) {
333 /*
334 * CAP_FSETID overrides the following restrictions:
335 *
336 * The set-user-ID and set-group-ID bits of a file will be
337 * cleared upon successful return from chown()
338 */
339 if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
340 !capable(CAP_FSETID)) {
341 ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
342 }
343
344 /*
345 * Change the ownerships and register quota modifications
346 * in the transaction.
347 */
348 if (iuid != uid) {
349 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) {
350 ASSERT(mask & ATTR_UID);
351 ASSERT(udqp);
352 olddquot1 = xfs_qm_vop_chown(tp, ip,
353 &ip->i_udquot, udqp);
354 }
355 ip->i_d.di_uid = uid;
356 inode->i_uid = uid;
357 }
358 if (igid != gid) {
359 if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) {
360 ASSERT(!XFS_IS_PQUOTA_ON(mp));
361 ASSERT(mask & ATTR_GID);
362 ASSERT(gdqp);
363 olddquot2 = xfs_qm_vop_chown(tp, ip,
364 &ip->i_gdquot, gdqp);
365 }
366 ip->i_d.di_gid = gid;
367 inode->i_gid = gid;
368 }
369 }
370
371 /*
372 * Change file access modes.
373 */
374 if (mask & ATTR_MODE) {
375 umode_t mode = iattr->ia_mode;
376
377 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
378 mode &= ~S_ISGID;
379
380 ip->i_d.di_mode &= S_IFMT;
381 ip->i_d.di_mode |= mode & ~S_IFMT;
382
383 inode->i_mode &= S_IFMT;
384 inode->i_mode |= mode & ~S_IFMT;
385 }
386
387 /*
388 * Change file access or modified times.
389 */
390 if (mask & ATTR_ATIME) {
391 inode->i_atime = iattr->ia_atime;
392 ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
393 ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
394 ip->i_update_core = 1;
395 }
396 if (mask & ATTR_CTIME) {
397 inode->i_ctime = iattr->ia_ctime;
398 ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
399 ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
400 ip->i_update_core = 1;
401 }
402 if (mask & ATTR_MTIME) {
403 inode->i_mtime = iattr->ia_mtime;
404 ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
405 ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
406 ip->i_update_core = 1;
407 }
408
409 /*
410 * And finally, log the inode core if any attribute in it
411 * has been changed.
412 */
413 if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE|
414 ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
415 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
416
417 XFS_STATS_INC(xs_ig_attrchg);
418
419 /*
420 * If this is a synchronous mount, make sure that the
421 * transaction goes to disk before returning to the user.
422 * This is slightly sub-optimal in that truncates require
423 * two sync transactions instead of one for wsync filesystems.
424 * One for the truncate and one for the timestamps since we
425 * don't want to change the timestamps unless we're sure the
426 * truncate worked. Truncates are less than 1% of the laddis
427 * mix so this probably isn't worth the trouble to optimize.
428 */
429 code = 0;
430 if (mp->m_flags & XFS_MOUNT_WSYNC)
431 xfs_trans_set_sync(tp);
432
433 code = xfs_trans_commit(tp, commit_flags);
434
435 xfs_iunlock(ip, lock_flags);
436
437 /*
438 * Release any dquot(s) the inode had kept before chown.
439 */
440 xfs_qm_dqrele(olddquot1);
441 xfs_qm_dqrele(olddquot2);
442 xfs_qm_dqrele(udqp);
443 xfs_qm_dqrele(gdqp);
444
445 if (code)
446 return code;
447
448 /*
449 * XXX(hch): Updating the ACL entries is not atomic vs the i_mode
450 * update. We could avoid this with linked transactions
451 * and passing down the transaction pointer all the way
452 * to attr_set. No previous user of the generic
453 * Posix ACL code seems to care about this issue either.
454 */
455 if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) {
456 code = -xfs_acl_chmod(inode);
457 if (code)
458 return XFS_ERROR(code);
459 }
460
461 return 0;
462
463 abort_return:
464 commit_flags |= XFS_TRANS_ABORT;
465 error_return:
466 xfs_qm_dqrele(udqp);
467 xfs_qm_dqrele(gdqp);
468 if (tp) {
469 xfs_trans_cancel(tp, commit_flags);
470 }
471 if (lock_flags != 0) {
472 xfs_iunlock(ip, lock_flags);
473 }
474 return code;
475}
476
477/* 53/*
478 * The maximum pathlen is 1024 bytes. Since the minimum file system 54 * The maximum pathlen is 1024 bytes. Since the minimum file system
479 * blocksize is 512 bytes, we can get a max of 2 extents back from 55 * blocksize is 512 bytes, we can get a max of 2 extents back from
@@ -507,7 +83,9 @@ xfs_readlink_bmap(
507 83
508 bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 84 bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt),
509 XBF_LOCK | XBF_MAPPED | XBF_DONT_BLOCK); 85 XBF_LOCK | XBF_MAPPED | XBF_DONT_BLOCK);
510 error = XFS_BUF_GETERROR(bp); 86 if (!bp)
87 return XFS_ERROR(ENOMEM);
88 error = bp->b_error;
511 if (error) { 89 if (error) {
512 xfs_ioerror_alert("xfs_readlink", 90 xfs_ioerror_alert("xfs_readlink",
513 ip->i_mount, bp, XFS_BUF_ADDR(bp)); 91 ip->i_mount, bp, XFS_BUF_ADDR(bp));
@@ -518,7 +96,7 @@ xfs_readlink_bmap(
518 byte_cnt = pathlen; 96 byte_cnt = pathlen;
519 pathlen -= byte_cnt; 97 pathlen -= byte_cnt;
520 98
521 memcpy(link, XFS_BUF_PTR(bp), byte_cnt); 99 memcpy(link, bp->b_addr, byte_cnt);
522 xfs_buf_relse(bp); 100 xfs_buf_relse(bp);
523 } 101 }
524 102
@@ -535,7 +113,7 @@ xfs_readlink(
535 char *link) 113 char *link)
536{ 114{
537 xfs_mount_t *mp = ip->i_mount; 115 xfs_mount_t *mp = ip->i_mount;
538 int pathlen; 116 xfs_fsize_t pathlen;
539 int error = 0; 117 int error = 0;
540 118
541 trace_xfs_readlink(ip); 119 trace_xfs_readlink(ip);
@@ -545,13 +123,20 @@ xfs_readlink(
545 123
546 xfs_ilock(ip, XFS_ILOCK_SHARED); 124 xfs_ilock(ip, XFS_ILOCK_SHARED);
547 125
548 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK);
549 ASSERT(ip->i_d.di_size <= MAXPATHLEN);
550
551 pathlen = ip->i_d.di_size; 126 pathlen = ip->i_d.di_size;
552 if (!pathlen) 127 if (!pathlen)
553 goto out; 128 goto out;
554 129
130 if (pathlen < 0 || pathlen > MAXPATHLEN) {
131 xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
132 __func__, (unsigned long long) ip->i_ino,
133 (long long) pathlen);
134 ASSERT(0);
135 error = XFS_ERROR(EFSCORRUPTED);
136 goto out;
137 }
138
139
555 if (ip->i_df.if_flags & XFS_IFINLINE) { 140 if (ip->i_df.if_flags & XFS_IFINLINE) {
556 memcpy(link, ip->i_df.if_u1.if_data, pathlen); 141 memcpy(link, ip->i_df.if_u1.if_data, pathlen);
557 link[pathlen] = '\0'; 142 link[pathlen] = '\0';
@@ -621,13 +206,6 @@ xfs_free_eofblocks(
621 */ 206 */
622 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); 207 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
623 208
624 /*
625 * Do the xfs_itruncate_start() call before
626 * reserving any log space because
627 * itruncate_start will call into the buffer
628 * cache and we can't
629 * do that within a transaction.
630 */
631 if (flags & XFS_FREE_EOF_TRYLOCK) { 209 if (flags & XFS_FREE_EOF_TRYLOCK) {
632 if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { 210 if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
633 xfs_trans_cancel(tp, 0); 211 xfs_trans_cancel(tp, 0);
@@ -636,13 +214,6 @@ xfs_free_eofblocks(
636 } else { 214 } else {
637 xfs_ilock(ip, XFS_IOLOCK_EXCL); 215 xfs_ilock(ip, XFS_IOLOCK_EXCL);
638 } 216 }
639 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
640 ip->i_size);
641 if (error) {
642 xfs_trans_cancel(tp, 0);
643 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
644 return error;
645 }
646 217
647 error = xfs_trans_reserve(tp, 0, 218 error = xfs_trans_reserve(tp, 0,
648 XFS_ITRUNCATE_LOG_RES(mp), 219 XFS_ITRUNCATE_LOG_RES(mp),
@@ -658,15 +229,12 @@ xfs_free_eofblocks(
658 xfs_ilock(ip, XFS_ILOCK_EXCL); 229 xfs_ilock(ip, XFS_ILOCK_EXCL);
659 xfs_trans_ijoin(tp, ip); 230 xfs_trans_ijoin(tp, ip);
660 231
661 error = xfs_itruncate_finish(&tp, ip, 232 error = xfs_itruncate_data(&tp, ip, ip->i_size);
662 ip->i_size,
663 XFS_DATA_FORK,
664 0);
665 /*
666 * If we get an error at this point we
667 * simply don't bother truncating the file.
668 */
669 if (error) { 233 if (error) {
234 /*
235 * If we get an error at this point we simply don't
236 * bother truncating the file.
237 */
670 xfs_trans_cancel(tp, 238 xfs_trans_cancel(tp,
671 (XFS_TRANS_RELEASE_LOG_RES | 239 (XFS_TRANS_RELEASE_LOG_RES |
672 XFS_TRANS_ABORT)); 240 XFS_TRANS_ABORT));
@@ -970,7 +538,7 @@ xfs_release(
970 if (ip->i_d.di_nlink == 0) 538 if (ip->i_d.di_nlink == 0)
971 return 0; 539 return 0;
972 540
973 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 541 if ((S_ISREG(ip->i_d.di_mode) &&
974 ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 || 542 ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 ||
975 ip->i_delayed_blks > 0)) && 543 ip->i_delayed_blks > 0)) &&
976 (ip->i_df.if_flags & XFS_IFEXTENTS)) && 544 (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
@@ -1051,7 +619,7 @@ xfs_inactive(
1051 truncate = ((ip->i_d.di_nlink == 0) && 619 truncate = ((ip->i_d.di_nlink == 0) &&
1052 ((ip->i_d.di_size != 0) || (ip->i_size != 0) || 620 ((ip->i_d.di_size != 0) || (ip->i_size != 0) ||
1053 (ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) && 621 (ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) &&
1054 ((ip->i_d.di_mode & S_IFMT) == S_IFREG)); 622 S_ISREG(ip->i_d.di_mode));
1055 623
1056 mp = ip->i_mount; 624 mp = ip->i_mount;
1057 625
@@ -1062,7 +630,7 @@ xfs_inactive(
1062 goto out; 630 goto out;
1063 631
1064 if (ip->i_d.di_nlink != 0) { 632 if (ip->i_d.di_nlink != 0) {
1065 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 633 if ((S_ISREG(ip->i_d.di_mode) &&
1066 ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 || 634 ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 ||
1067 ip->i_delayed_blks > 0)) && 635 ip->i_delayed_blks > 0)) &&
1068 (ip->i_df.if_flags & XFS_IFEXTENTS) && 636 (ip->i_df.if_flags & XFS_IFEXTENTS) &&
@@ -1084,20 +652,9 @@ xfs_inactive(
1084 652
1085 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); 653 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1086 if (truncate) { 654 if (truncate) {
1087 /*
1088 * Do the xfs_itruncate_start() call before
1089 * reserving any log space because itruncate_start
1090 * will call into the buffer cache and we can't
1091 * do that within a transaction.
1092 */
1093 xfs_ilock(ip, XFS_IOLOCK_EXCL); 655 xfs_ilock(ip, XFS_IOLOCK_EXCL);
1094 656
1095 error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0); 657 xfs_ioend_wait(ip);
1096 if (error) {
1097 xfs_trans_cancel(tp, 0);
1098 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1099 return VN_INACTIVE_CACHE;
1100 }
1101 658
1102 error = xfs_trans_reserve(tp, 0, 659 error = xfs_trans_reserve(tp, 0,
1103 XFS_ITRUNCATE_LOG_RES(mp), 660 XFS_ITRUNCATE_LOG_RES(mp),
@@ -1114,23 +671,14 @@ xfs_inactive(
1114 xfs_ilock(ip, XFS_ILOCK_EXCL); 671 xfs_ilock(ip, XFS_ILOCK_EXCL);
1115 xfs_trans_ijoin(tp, ip); 672 xfs_trans_ijoin(tp, ip);
1116 673
1117 /* 674 error = xfs_itruncate_data(&tp, ip, 0);
1118 * normally, we have to run xfs_itruncate_finish sync.
1119 * But if filesystem is wsync and we're in the inactive
1120 * path, then we know that nlink == 0, and that the
1121 * xaction that made nlink == 0 is permanently committed
1122 * since xfs_remove runs as a synchronous transaction.
1123 */
1124 error = xfs_itruncate_finish(&tp, ip, 0, XFS_DATA_FORK,
1125 (!(mp->m_flags & XFS_MOUNT_WSYNC) ? 1 : 0));
1126
1127 if (error) { 675 if (error) {
1128 xfs_trans_cancel(tp, 676 xfs_trans_cancel(tp,
1129 XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); 677 XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
1130 xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); 678 xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
1131 return VN_INACTIVE_CACHE; 679 return VN_INACTIVE_CACHE;
1132 } 680 }
1133 } else if ((ip->i_d.di_mode & S_IFMT) == S_IFLNK) { 681 } else if (S_ISLNK(ip->i_d.di_mode)) {
1134 682
1135 /* 683 /*
1136 * If we get an error while cleaning up a 684 * If we get an error while cleaning up a
@@ -2109,13 +1657,13 @@ xfs_symlink(
2109 byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); 1657 byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
2110 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, 1658 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
2111 BTOBB(byte_cnt), 0); 1659 BTOBB(byte_cnt), 0);
2112 ASSERT(bp && !XFS_BUF_GETERROR(bp)); 1660 ASSERT(!xfs_buf_geterror(bp));
2113 if (pathlen < byte_cnt) { 1661 if (pathlen < byte_cnt) {
2114 byte_cnt = pathlen; 1662 byte_cnt = pathlen;
2115 } 1663 }
2116 pathlen -= byte_cnt; 1664 pathlen -= byte_cnt;
2117 1665
2118 memcpy(XFS_BUF_PTR(bp), cur_chunk, byte_cnt); 1666 memcpy(bp->b_addr, cur_chunk, byte_cnt);
2119 cur_chunk += byte_cnt; 1667 cur_chunk += byte_cnt;
2120 1668
2121 xfs_trans_log_buf(tp, bp, 0, byte_cnt - 1); 1669 xfs_trans_log_buf(tp, bp, 0, byte_cnt - 1);
@@ -2430,6 +1978,8 @@ xfs_zero_remaining_bytes(
2430 if (!bp) 1978 if (!bp)
2431 return XFS_ERROR(ENOMEM); 1979 return XFS_ERROR(ENOMEM);
2432 1980
1981 xfs_buf_unlock(bp);
1982
2433 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { 1983 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
2434 offset_fsb = XFS_B_TO_FSBT(mp, offset); 1984 offset_fsb = XFS_B_TO_FSBT(mp, offset);
2435 nimap = 1; 1985 nimap = 1;
@@ -2458,7 +2008,7 @@ xfs_zero_remaining_bytes(
2458 mp, bp, XFS_BUF_ADDR(bp)); 2008 mp, bp, XFS_BUF_ADDR(bp));
2459 break; 2009 break;
2460 } 2010 }
2461 memset(XFS_BUF_PTR(bp) + 2011 memset(bp->b_addr +
2462 (offset - XFS_FSB_TO_B(mp, imap.br_startoff)), 2012 (offset - XFS_FSB_TO_B(mp, imap.br_startoff)),
2463 0, lastoffset - offset + 1); 2013 0, lastoffset - offset + 1);
2464 XFS_BUF_UNDONE(bp); 2014 XFS_BUF_UNDONE(bp);
@@ -2784,7 +2334,7 @@ xfs_change_file_space(
2784 iattr.ia_valid = ATTR_SIZE; 2334 iattr.ia_valid = ATTR_SIZE;
2785 iattr.ia_size = startoffset; 2335 iattr.ia_size = startoffset;
2786 2336
2787 error = xfs_setattr(ip, &iattr, attr_flags); 2337 error = xfs_setattr_size(ip, &iattr, attr_flags);
2788 2338
2789 if (error) 2339 if (error)
2790 return error; 2340 return error;
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 3bcd23353d6..35d3d513e1e 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -13,7 +13,8 @@ struct xfs_inode;
13struct xfs_iomap; 13struct xfs_iomap;
14 14
15 15
16int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags); 16int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap, int flags);
17int xfs_setattr_size(struct xfs_inode *ip, struct iattr *vap, int flags);
17#define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */ 18#define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */
18#define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */ 19#define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */
19#define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */ 20#define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */
diff --git a/fs/xfs/linux-2.6/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index 87d3e03878c..87d3e03878c 100644
--- a/fs/xfs/linux-2.6/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c