aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/Kconfig27
-rw-r--r--fs/xfs/Makefile-linux-2.64
-rw-r--r--fs/xfs/linux-2.6/kmem.h38
-rw-r--r--fs/xfs/linux-2.6/mrlock.h4
-rw-r--r--fs/xfs/linux-2.6/sema.h19
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c65
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h8
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c13
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c170
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c59
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c65
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c117
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h35
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c123
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h6
-rw-r--r--fs/xfs/linux-2.6/xfs_stats.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c200
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.c7
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.c41
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h167
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c52
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h376
-rw-r--r--fs/xfs/quota/xfs_dquot.c8
-rw-r--r--fs/xfs/quota/xfs_dquot.h4
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c6
-rw-r--r--fs/xfs/quota/xfs_qm.c8
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c81
-rw-r--r--fs/xfs/quota/xfs_qm_stats.c2
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c6
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c2
-rw-r--r--fs/xfs/support/debug.c4
-rw-r--r--fs/xfs/support/debug.h3
-rw-r--r--fs/xfs/xfs_acl.c71
-rw-r--r--fs/xfs/xfs_acl.h16
-rw-r--r--fs/xfs/xfs_alloc.c31
-rw-r--r--fs/xfs/xfs_alloc.h2
-rw-r--r--fs/xfs/xfs_alloc_btree.c2
-rw-r--r--fs/xfs/xfs_attr.c66
-rw-r--r--fs/xfs/xfs_attr.h14
-rw-r--r--fs/xfs/xfs_attr_leaf.c4
-rw-r--r--fs/xfs/xfs_bmap.c386
-rw-r--r--fs/xfs/xfs_bmap.h22
-rw-r--r--fs/xfs/xfs_bmap_btree.c12
-rw-r--r--fs/xfs/xfs_btree.c2
-rw-r--r--fs/xfs/xfs_buf_item.c9
-rw-r--r--fs/xfs/xfs_cap.h10
-rw-r--r--fs/xfs/xfs_da_btree.c194
-rw-r--r--fs/xfs/xfs_da_btree.h4
-rw-r--r--fs/xfs/xfs_dfrag.c84
-rw-r--r--fs/xfs/xfs_dfrag.h3
-rw-r--r--fs/xfs/xfs_dinode.h5
-rw-r--r--fs/xfs/xfs_dir.c1217
-rw-r--r--fs/xfs/xfs_dir.h142
-rw-r--r--fs/xfs/xfs_dir2.c396
-rw-r--r--fs/xfs/xfs_dir2.h32
-rw-r--r--fs/xfs/xfs_dir2_block.c31
-rw-r--r--fs/xfs/xfs_dir2_data.c5
-rw-r--r--fs/xfs/xfs_dir2_data.h8
-rw-r--r--fs/xfs/xfs_dir2_leaf.c14
-rw-r--r--fs/xfs/xfs_dir2_node.c16
-rw-r--r--fs/xfs/xfs_dir2_sf.c13
-rw-r--r--fs/xfs/xfs_dir2_trace.c2
-rw-r--r--fs/xfs/xfs_dir_leaf.c2213
-rw-r--r--fs/xfs/xfs_dir_leaf.h231
-rw-r--r--fs/xfs/xfs_dir_sf.h155
-rw-r--r--fs/xfs/xfs_dmapi.h2
-rw-r--r--fs/xfs/xfs_dmops.c1
-rw-r--r--fs/xfs/xfs_error.c2
-rw-r--r--fs/xfs/xfs_extfree_item.c57
-rw-r--r--fs/xfs/xfs_extfree_item.h53
-rw-r--r--fs/xfs/xfs_fs.h7
-rw-r--r--fs/xfs/xfs_fsops.c20
-rw-r--r--fs/xfs/xfs_ialloc.c5
-rw-r--r--fs/xfs/xfs_ialloc_btree.c2
-rw-r--r--fs/xfs/xfs_iget.c22
-rw-r--r--fs/xfs/xfs_inode.c94
-rw-r--r--fs/xfs/xfs_inode.h7
-rw-r--r--fs/xfs/xfs_inode_item.c57
-rw-r--r--fs/xfs/xfs_inode_item.h61
-rw-r--r--fs/xfs/xfs_iocore.c7
-rw-r--r--fs/xfs/xfs_iomap.c26
-rw-r--r--fs/xfs/xfs_itable.c20
-rw-r--r--fs/xfs/xfs_itable.h1
-rw-r--r--fs/xfs/xfs_log.c21
-rw-r--r--fs/xfs/xfs_log_recover.c113
-rw-r--r--fs/xfs/xfs_mount.c54
-rw-r--r--fs/xfs/xfs_mount.h70
-rw-r--r--fs/xfs/xfs_qmops.c1
-rw-r--r--fs/xfs/xfs_quota.h2
-rw-r--r--fs/xfs/xfs_rename.c68
-rw-r--r--fs/xfs/xfs_rtalloc.c16
-rw-r--r--fs/xfs/xfs_rw.c124
-rw-r--r--fs/xfs/xfs_rw.h10
-rw-r--r--fs/xfs/xfs_trans.c48
-rw-r--r--fs/xfs/xfs_trans.h7
-rw-r--r--fs/xfs/xfs_trans_ail.c6
-rw-r--r--fs/xfs/xfs_trans_buf.c12
-rw-r--r--fs/xfs/xfs_trans_extfree.c1
-rw-r--r--fs/xfs/xfs_trans_inode.c2
-rw-r--r--fs/xfs/xfs_trans_item.c2
-rw-r--r--fs/xfs/xfs_trans_space.h11
-rw-r--r--fs/xfs/xfs_utils.c13
-rw-r--r--fs/xfs/xfs_utils.h7
-rw-r--r--fs/xfs/xfs_vfsops.c122
-rw-r--r--fs/xfs/xfs_vnodeops.c295
109 files changed, 2326 insertions, 6268 deletions
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig
index bac27d66151d..26b364c9d62c 100644
--- a/fs/xfs/Kconfig
+++ b/fs/xfs/Kconfig
@@ -1,6 +1,5 @@
1config XFS_FS 1config XFS_FS
2 tristate "XFS filesystem support" 2 tristate "XFS filesystem support"
3 select EXPORTFS if NFSD!=n
4 help 3 help
5 XFS is a high performance journaling filesystem which originated 4 XFS is a high performance journaling filesystem which originated
6 on the SGI IRIX platform. It is completely multi-threaded, can 5 on the SGI IRIX platform. It is completely multi-threaded, can
@@ -18,11 +17,6 @@ config XFS_FS
18 system of your root partition is compiled as a module, you'll need 17 system of your root partition is compiled as a module, you'll need
19 to use an initial ramdisk (initrd) to boot. 18 to use an initial ramdisk (initrd) to boot.
20 19
21config XFS_EXPORT
22 bool
23 depends on XFS_FS && EXPORTFS
24 default y
25
26config XFS_QUOTA 20config XFS_QUOTA
27 bool "XFS Quota support" 21 bool "XFS Quota support"
28 depends on XFS_FS 22 depends on XFS_FS
@@ -65,18 +59,19 @@ config XFS_POSIX_ACL
65 If you don't know what Access Control Lists are, say N. 59 If you don't know what Access Control Lists are, say N.
66 60
67config XFS_RT 61config XFS_RT
68 bool "XFS Realtime support (EXPERIMENTAL)" 62 bool "XFS Realtime subvolume support"
69 depends on XFS_FS && EXPERIMENTAL 63 depends on XFS_FS
70 help 64 help
71 If you say Y here you will be able to mount and use XFS filesystems 65 If you say Y here you will be able to mount and use XFS filesystems
72 which contain a realtime subvolume. The realtime subvolume is a 66 which contain a realtime subvolume. The realtime subvolume is a
73 separate area of disk space where only file data is stored. The 67 separate area of disk space where only file data is stored. It was
74 realtime subvolume is designed to provide very deterministic 68 originally designed to provide deterministic data rates suitable
75 data rates suitable for media streaming applications. 69 for media streaming applications, but is also useful as a generic
76 70 mechanism for ensuring data and metadata/log I/Os are completely
77 See the xfs man page in section 5 for a bit more information. 71 separated. Regular file I/Os are isolated to a separate device
72 from all other requests, and this can be done quite transparently
73 to applications via the inherit-realtime directory inode flag.
78 74
79 This feature is unsupported at this time, is not yet fully 75 See the xfs man page in section 5 for additional information.
80 functional, and may cause serious problems.
81 76
82 If unsure, say N. 77 If unsure, say N.
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index 5d73eaa1971f..9e7f85986d0d 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -59,7 +59,6 @@ xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
59xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o 59xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
60xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o 60xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
61xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o 61xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
62xfs-$(CONFIG_XFS_EXPORT) += $(XFS_LINUX)/xfs_export.o
63 62
64 63
65xfs-y += xfs_alloc.o \ 64xfs-y += xfs_alloc.o \
@@ -73,14 +72,12 @@ xfs-y += xfs_alloc.o \
73 xfs_btree.o \ 72 xfs_btree.o \
74 xfs_buf_item.o \ 73 xfs_buf_item.o \
75 xfs_da_btree.o \ 74 xfs_da_btree.o \
76 xfs_dir.o \
77 xfs_dir2.o \ 75 xfs_dir2.o \
78 xfs_dir2_block.o \ 76 xfs_dir2_block.o \
79 xfs_dir2_data.o \ 77 xfs_dir2_data.o \
80 xfs_dir2_leaf.o \ 78 xfs_dir2_leaf.o \
81 xfs_dir2_node.o \ 79 xfs_dir2_node.o \
82 xfs_dir2_sf.o \ 80 xfs_dir2_sf.o \
83 xfs_dir_leaf.o \
84 xfs_error.o \ 81 xfs_error.o \
85 xfs_extfree_item.o \ 82 xfs_extfree_item.o \
86 xfs_fsops.o \ 83 xfs_fsops.o \
@@ -117,6 +114,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
117 kmem.o \ 114 kmem.o \
118 xfs_aops.o \ 115 xfs_aops.o \
119 xfs_buf.o \ 116 xfs_buf.o \
117 xfs_export.o \
120 xfs_file.o \ 118 xfs_file.o \
121 xfs_fs_subr.o \ 119 xfs_fs_subr.o \
122 xfs_globals.o \ 120 xfs_globals.o \
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index 2cfd33d4d8aa..939bd84bc7ee 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -23,42 +23,6 @@
23#include <linux/mm.h> 23#include <linux/mm.h>
24 24
25/* 25/*
26 * Process flags handling
27 */
28
29#define PFLAGS_TEST_NOIO() (current->flags & PF_NOIO)
30#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
31
32#define PFLAGS_SET_NOIO() do { \
33 current->flags |= PF_NOIO; \
34} while (0)
35
36#define PFLAGS_CLEAR_NOIO() do { \
37 current->flags &= ~PF_NOIO; \
38} while (0)
39
40/* these could be nested, so we save state */
41#define PFLAGS_SET_FSTRANS(STATEP) do { \
42 *(STATEP) = current->flags; \
43 current->flags |= PF_FSTRANS; \
44} while (0)
45
46#define PFLAGS_CLEAR_FSTRANS(STATEP) do { \
47 *(STATEP) = current->flags; \
48 current->flags &= ~PF_FSTRANS; \
49} while (0)
50
51/* Restore the PF_FSTRANS state to what was saved in STATEP */
52#define PFLAGS_RESTORE_FSTRANS(STATEP) do { \
53 current->flags = ((current->flags & ~PF_FSTRANS) | \
54 (*(STATEP) & PF_FSTRANS)); \
55} while (0)
56
57#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
58 *(NSTATEP) = *(OSTATEP); \
59} while (0)
60
61/*
62 * General memory allocation interfaces 26 * General memory allocation interfaces
63 */ 27 */
64 28
@@ -83,7 +47,7 @@ kmem_flags_convert(unsigned int __nocast flags)
83 lflags = GFP_ATOMIC | __GFP_NOWARN; 47 lflags = GFP_ATOMIC | __GFP_NOWARN;
84 } else { 48 } else {
85 lflags = GFP_KERNEL | __GFP_NOWARN; 49 lflags = GFP_KERNEL | __GFP_NOWARN;
86 if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS)) 50 if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
87 lflags &= ~__GFP_FS; 51 lflags &= ~__GFP_FS;
88 } 52 }
89 return lflags; 53 return lflags;
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/linux-2.6/mrlock.h
index 1b262b790d9c..32e1ce0f04c9 100644
--- a/fs/xfs/linux-2.6/mrlock.h
+++ b/fs/xfs/linux-2.6/mrlock.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -28,7 +28,7 @@ typedef struct {
28} mrlock_t; 28} mrlock_t;
29 29
30#define mrinit(mrp, name) \ 30#define mrinit(mrp, name) \
31 ( (mrp)->mr_writer = 0, init_rwsem(&(mrp)->mr_lock) ) 31 do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
32#define mrlock_init(mrp, t,n,s) mrinit(mrp, n) 32#define mrlock_init(mrp, t,n,s) mrinit(mrp, n)
33#define mrfree(mrp) do { } while (0) 33#define mrfree(mrp) do { } while (0)
34#define mraccess(mrp) mraccessf(mrp, 0) 34#define mraccess(mrp) mraccessf(mrp, 0)
diff --git a/fs/xfs/linux-2.6/sema.h b/fs/xfs/linux-2.6/sema.h
index 194a84490bd1..b25090094cca 100644
--- a/fs/xfs/linux-2.6/sema.h
+++ b/fs/xfs/linux-2.6/sema.h
@@ -34,20 +34,21 @@ typedef struct semaphore sema_t;
34#define initnsema(sp, val, name) sema_init(sp, val) 34#define initnsema(sp, val, name) sema_init(sp, val)
35#define psema(sp, b) down(sp) 35#define psema(sp, b) down(sp)
36#define vsema(sp) up(sp) 36#define vsema(sp) up(sp)
37#define valusema(sp) (atomic_read(&(sp)->count)) 37#define freesema(sema) do { } while (0)
38#define freesema(sema) 38
39static inline int issemalocked(sema_t *sp)
40{
41 return down_trylock(sp) || (up(sp), 0);
42}
39 43
40/* 44/*
41 * Map cpsema (try to get the sema) to down_trylock. We need to switch 45 * Map cpsema (try to get the sema) to down_trylock. We need to switch
42 * the return values since cpsema returns 1 (acquired) 0 (failed) and 46 * the return values since cpsema returns 1 (acquired) 0 (failed) and
43 * down_trylock returns the reverse 0 (acquired) 1 (failed). 47 * down_trylock returns the reverse 0 (acquired) 1 (failed).
44 */ 48 */
45 49static inline int cpsema(sema_t *sp)
46#define cpsema(sp) (down_trylock(sp) ? 0 : 1) 50{
47 51 return down_trylock(sp) ? 0 : 1;
48/* 52}
49 * Didn't do cvsema(sp). Not sure how to map this to up/down/...
50 * It does a vsema if the values is < 0 other wise nothing.
51 */
52 53
53#endif /* __XFS_SUPPORT_SEMA_H__ */ 54#endif /* __XFS_SUPPORT_SEMA_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 4d191ef39b67..3e807b828e22 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -21,7 +21,6 @@
21#include "xfs_inum.h" 21#include "xfs_inum.h"
22#include "xfs_sb.h" 22#include "xfs_sb.h"
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_dir.h"
25#include "xfs_dir2.h" 24#include "xfs_dir2.h"
26#include "xfs_trans.h" 25#include "xfs_trans.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
@@ -29,7 +28,6 @@
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_alloc_btree.h" 29#include "xfs_alloc_btree.h"
31#include "xfs_ialloc_btree.h" 30#include "xfs_ialloc_btree.h"
32#include "xfs_dir_sf.h"
33#include "xfs_dir2_sf.h" 31#include "xfs_dir2_sf.h"
34#include "xfs_attr_sf.h" 32#include "xfs_attr_sf.h"
35#include "xfs_dinode.h" 33#include "xfs_dinode.h"
@@ -76,7 +74,7 @@ xfs_page_trace(
76 int mask) 74 int mask)
77{ 75{
78 xfs_inode_t *ip; 76 xfs_inode_t *ip;
79 vnode_t *vp = vn_from_inode(inode); 77 bhv_vnode_t *vp = vn_from_inode(inode);
80 loff_t isize = i_size_read(inode); 78 loff_t isize = i_size_read(inode);
81 loff_t offset = page_offset(page); 79 loff_t offset = page_offset(page);
82 int delalloc = -1, unmapped = -1, unwritten = -1; 80 int delalloc = -1, unmapped = -1, unwritten = -1;
@@ -136,9 +134,10 @@ xfs_destroy_ioend(
136 134
137 for (bh = ioend->io_buffer_head; bh; bh = next) { 135 for (bh = ioend->io_buffer_head; bh; bh = next) {
138 next = bh->b_private; 136 next = bh->b_private;
139 bh->b_end_io(bh, ioend->io_uptodate); 137 bh->b_end_io(bh, !ioend->io_error);
140 } 138 }
141 139 if (unlikely(ioend->io_error))
140 vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__);
142 vn_iowake(ioend->io_vnode); 141 vn_iowake(ioend->io_vnode);
143 mempool_free(ioend, xfs_ioend_pool); 142 mempool_free(ioend, xfs_ioend_pool);
144} 143}
@@ -180,13 +179,12 @@ xfs_end_bio_unwritten(
180 void *data) 179 void *data)
181{ 180{
182 xfs_ioend_t *ioend = data; 181 xfs_ioend_t *ioend = data;
183 vnode_t *vp = ioend->io_vnode; 182 bhv_vnode_t *vp = ioend->io_vnode;
184 xfs_off_t offset = ioend->io_offset; 183 xfs_off_t offset = ioend->io_offset;
185 size_t size = ioend->io_size; 184 size_t size = ioend->io_size;
186 int error;
187 185
188 if (ioend->io_uptodate) 186 if (likely(!ioend->io_error))
189 VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error); 187 bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
190 xfs_destroy_ioend(ioend); 188 xfs_destroy_ioend(ioend);
191} 189}
192 190
@@ -211,7 +209,7 @@ xfs_alloc_ioend(
211 * all the I/O from calling the completion routine too early. 209 * all the I/O from calling the completion routine too early.
212 */ 210 */
213 atomic_set(&ioend->io_remaining, 1); 211 atomic_set(&ioend->io_remaining, 1);
214 ioend->io_uptodate = 1; /* cleared if any I/O fails */ 212 ioend->io_error = 0;
215 ioend->io_list = NULL; 213 ioend->io_list = NULL;
216 ioend->io_type = type; 214 ioend->io_type = type;
217 ioend->io_vnode = vn_from_inode(inode); 215 ioend->io_vnode = vn_from_inode(inode);
@@ -239,10 +237,10 @@ xfs_map_blocks(
239 xfs_iomap_t *mapp, 237 xfs_iomap_t *mapp,
240 int flags) 238 int flags)
241{ 239{
242 vnode_t *vp = vn_from_inode(inode); 240 bhv_vnode_t *vp = vn_from_inode(inode);
243 int error, nmaps = 1; 241 int error, nmaps = 1;
244 242
245 VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error); 243 error = bhv_vop_bmap(vp, offset, count, flags, mapp, &nmaps);
246 if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE))) 244 if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
247 VMODIFY(vp); 245 VMODIFY(vp);
248 return -error; 246 return -error;
@@ -271,16 +269,14 @@ xfs_end_bio(
271 if (bio->bi_size) 269 if (bio->bi_size)
272 return 1; 270 return 1;
273 271
274 ASSERT(ioend);
275 ASSERT(atomic_read(&bio->bi_cnt) >= 1); 272 ASSERT(atomic_read(&bio->bi_cnt) >= 1);
273 ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error;
276 274
277 /* Toss bio and pass work off to an xfsdatad thread */ 275 /* Toss bio and pass work off to an xfsdatad thread */
278 if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
279 ioend->io_uptodate = 0;
280 bio->bi_private = NULL; 276 bio->bi_private = NULL;
281 bio->bi_end_io = NULL; 277 bio->bi_end_io = NULL;
282
283 bio_put(bio); 278 bio_put(bio);
279
284 xfs_finish_ioend(ioend); 280 xfs_finish_ioend(ioend);
285 return 0; 281 return 0;
286} 282}
@@ -1127,7 +1123,7 @@ xfs_vm_writepage(
1127 * then mark the page dirty again and leave the page 1123 * then mark the page dirty again and leave the page
1128 * as is. 1124 * as is.
1129 */ 1125 */
1130 if (PFLAGS_TEST_FSTRANS() && need_trans) 1126 if (current_test_flags(PF_FSTRANS) && need_trans)
1131 goto out_fail; 1127 goto out_fail;
1132 1128
1133 /* 1129 /*
@@ -1158,6 +1154,18 @@ out_unlock:
1158 return error; 1154 return error;
1159} 1155}
1160 1156
1157STATIC int
1158xfs_vm_writepages(
1159 struct address_space *mapping,
1160 struct writeback_control *wbc)
1161{
1162 struct bhv_vnode *vp = vn_from_inode(mapping->host);
1163
1164 if (VN_TRUNC(vp))
1165 VUNTRUNCATE(vp);
1166 return generic_writepages(mapping, wbc);
1167}
1168
1161/* 1169/*
1162 * Called to move a page into cleanable state - and from there 1170 * Called to move a page into cleanable state - and from there
1163 * to be released. Possibly the page is already clean. We always 1171 * to be released. Possibly the page is already clean. We always
@@ -1204,7 +1212,7 @@ xfs_vm_releasepage(
1204 /* If we are already inside a transaction or the thread cannot 1212 /* If we are already inside a transaction or the thread cannot
1205 * do I/O, we cannot release this page. 1213 * do I/O, we cannot release this page.
1206 */ 1214 */
1207 if (PFLAGS_TEST_FSTRANS()) 1215 if (current_test_flags(PF_FSTRANS))
1208 return 0; 1216 return 0;
1209 1217
1210 /* 1218 /*
@@ -1231,7 +1239,7 @@ __xfs_get_blocks(
1231 int direct, 1239 int direct,
1232 bmapi_flags_t flags) 1240 bmapi_flags_t flags)
1233{ 1241{
1234 vnode_t *vp = vn_from_inode(inode); 1242 bhv_vnode_t *vp = vn_from_inode(inode);
1235 xfs_iomap_t iomap; 1243 xfs_iomap_t iomap;
1236 xfs_off_t offset; 1244 xfs_off_t offset;
1237 ssize_t size; 1245 ssize_t size;
@@ -1241,8 +1249,8 @@ __xfs_get_blocks(
1241 offset = (xfs_off_t)iblock << inode->i_blkbits; 1249 offset = (xfs_off_t)iblock << inode->i_blkbits;
1242 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); 1250 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
1243 size = bh_result->b_size; 1251 size = bh_result->b_size;
1244 VOP_BMAP(vp, offset, size, 1252 error = bhv_vop_bmap(vp, offset, size,
1245 create ? flags : BMAPI_READ, &iomap, &niomap, error); 1253 create ? flags : BMAPI_READ, &iomap, &niomap);
1246 if (error) 1254 if (error)
1247 return -error; 1255 return -error;
1248 if (niomap == 0) 1256 if (niomap == 0)
@@ -1370,13 +1378,13 @@ xfs_vm_direct_IO(
1370{ 1378{
1371 struct file *file = iocb->ki_filp; 1379 struct file *file = iocb->ki_filp;
1372 struct inode *inode = file->f_mapping->host; 1380 struct inode *inode = file->f_mapping->host;
1373 vnode_t *vp = vn_from_inode(inode); 1381 bhv_vnode_t *vp = vn_from_inode(inode);
1374 xfs_iomap_t iomap; 1382 xfs_iomap_t iomap;
1375 int maps = 1; 1383 int maps = 1;
1376 int error; 1384 int error;
1377 ssize_t ret; 1385 ssize_t ret;
1378 1386
1379 VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error); 1387 error = bhv_vop_bmap(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps);
1380 if (error) 1388 if (error)
1381 return -error; 1389 return -error;
1382 1390
@@ -1409,14 +1417,12 @@ xfs_vm_bmap(
1409 sector_t block) 1417 sector_t block)
1410{ 1418{
1411 struct inode *inode = (struct inode *)mapping->host; 1419 struct inode *inode = (struct inode *)mapping->host;
1412 vnode_t *vp = vn_from_inode(inode); 1420 bhv_vnode_t *vp = vn_from_inode(inode);
1413 int error;
1414 1421
1415 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 1422 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
1416 1423 bhv_vop_rwlock(vp, VRWLOCK_READ);
1417 VOP_RWLOCK(vp, VRWLOCK_READ); 1424 bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
1418 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); 1425 bhv_vop_rwunlock(vp, VRWLOCK_READ);
1419 VOP_RWUNLOCK(vp, VRWLOCK_READ);
1420 return generic_block_bmap(mapping, block, xfs_get_blocks); 1426 return generic_block_bmap(mapping, block, xfs_get_blocks);
1421} 1427}
1422 1428
@@ -1452,6 +1458,7 @@ struct address_space_operations xfs_address_space_operations = {
1452 .readpage = xfs_vm_readpage, 1458 .readpage = xfs_vm_readpage,
1453 .readpages = xfs_vm_readpages, 1459 .readpages = xfs_vm_readpages,
1454 .writepage = xfs_vm_writepage, 1460 .writepage = xfs_vm_writepage,
1461 .writepages = xfs_vm_writepages,
1455 .sync_page = block_sync_page, 1462 .sync_page = block_sync_page,
1456 .releasepage = xfs_vm_releasepage, 1463 .releasepage = xfs_vm_releasepage,
1457 .invalidatepage = xfs_vm_invalidatepage, 1464 .invalidatepage = xfs_vm_invalidatepage,
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 60716543c68b..706d8c781b8a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005 Silicon Graphics, Inc. 2 * Copyright (c) 2005-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -30,9 +30,9 @@ typedef void (*xfs_ioend_func_t)(void *);
30typedef struct xfs_ioend { 30typedef struct xfs_ioend {
31 struct xfs_ioend *io_list; /* next ioend in chain */ 31 struct xfs_ioend *io_list; /* next ioend in chain */
32 unsigned int io_type; /* delalloc / unwritten */ 32 unsigned int io_type; /* delalloc / unwritten */
33 unsigned int io_uptodate; /* I/O status register */ 33 int io_error; /* I/O error code */
34 atomic_t io_remaining; /* hold count */ 34 atomic_t io_remaining; /* hold count */
35 struct vnode *io_vnode; /* file being written to */ 35 struct bhv_vnode *io_vnode; /* file being written to */
36 struct buffer_head *io_buffer_head;/* buffer linked list head */ 36 struct buffer_head *io_buffer_head;/* buffer linked list head */
37 struct buffer_head *io_buffer_tail;/* buffer linked list tail */ 37 struct buffer_head *io_buffer_tail;/* buffer linked list tail */
38 size_t io_size; /* size of the extent */ 38 size_t io_size; /* size of the extent */
@@ -43,4 +43,4 @@ typedef struct xfs_ioend {
43extern struct address_space_operations xfs_address_space_operations; 43extern struct address_space_operations xfs_address_space_operations;
44extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); 44extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
45 45
46#endif /* __XFS_IOPS_H__ */ 46#endif /* __XFS_AOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index b768ea910bbe..5fb75d9151f2 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -21,7 +21,6 @@
21#include "xfs_log.h" 21#include "xfs_log.h"
22#include "xfs_trans.h" 22#include "xfs_trans.h"
23#include "xfs_sb.h" 23#include "xfs_sb.h"
24#include "xfs_dir.h"
25#include "xfs_mount.h" 24#include "xfs_mount.h"
26#include "xfs_export.h" 25#include "xfs_export.h"
27 26
@@ -97,7 +96,7 @@ xfs_fs_encode_fh(
97 int len; 96 int len;
98 int is64 = 0; 97 int is64 = 0;
99#if XFS_BIG_INUMS 98#if XFS_BIG_INUMS
100 vfs_t *vfs = vfs_from_sb(inode->i_sb); 99 bhv_vfs_t *vfs = vfs_from_sb(inode->i_sb);
101 100
102 if (!(vfs->vfs_flag & VFS_32BITINODES)) { 101 if (!(vfs->vfs_flag & VFS_32BITINODES)) {
103 /* filesystem may contain 64bit inode numbers */ 102 /* filesystem may contain 64bit inode numbers */
@@ -136,13 +135,13 @@ xfs_fs_get_dentry(
136 struct super_block *sb, 135 struct super_block *sb,
137 void *data) 136 void *data)
138{ 137{
139 vnode_t *vp; 138 bhv_vnode_t *vp;
140 struct inode *inode; 139 struct inode *inode;
141 struct dentry *result; 140 struct dentry *result;
142 vfs_t *vfsp = vfs_from_sb(sb); 141 bhv_vfs_t *vfsp = vfs_from_sb(sb);
143 int error; 142 int error;
144 143
145 VFS_VGET(vfsp, &vp, (fid_t *)data, error); 144 error = bhv_vfs_vget(vfsp, &vp, (fid_t *)data);
146 if (error || vp == NULL) 145 if (error || vp == NULL)
147 return ERR_PTR(-ESTALE) ; 146 return ERR_PTR(-ESTALE) ;
148 147
@@ -160,12 +159,12 @@ xfs_fs_get_parent(
160 struct dentry *child) 159 struct dentry *child)
161{ 160{
162 int error; 161 int error;
163 vnode_t *vp, *cvp; 162 bhv_vnode_t *vp, *cvp;
164 struct dentry *parent; 163 struct dentry *parent;
165 164
166 cvp = NULL; 165 cvp = NULL;
167 vp = vn_from_inode(child->d_inode); 166 vp = vn_from_inode(child->d_inode);
168 VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error); 167 error = bhv_vop_lookup(vp, &dotdot, &cvp, 0, NULL, NULL);
169 if (unlikely(error)) 168 if (unlikely(error))
170 return ERR_PTR(-error); 169 return ERR_PTR(-error);
171 170
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index c847416f6d10..70662371bb11 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -21,7 +21,6 @@
21#include "xfs_inum.h" 21#include "xfs_inum.h"
22#include "xfs_sb.h" 22#include "xfs_sb.h"
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_dir.h"
25#include "xfs_dir2.h" 24#include "xfs_dir2.h"
26#include "xfs_trans.h" 25#include "xfs_trans.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_alloc.h" 31#include "xfs_alloc.h"
33#include "xfs_btree.h" 32#include "xfs_btree.h"
34#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
38#include "xfs_inode.h" 36#include "xfs_inode.h"
@@ -58,15 +56,12 @@ __xfs_file_read(
58{ 56{
59 struct iovec iov = {buf, count}; 57 struct iovec iov = {buf, count};
60 struct file *file = iocb->ki_filp; 58 struct file *file = iocb->ki_filp;
61 vnode_t *vp = vn_from_inode(file->f_dentry->d_inode); 59 bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
62 ssize_t rval;
63 60
64 BUG_ON(iocb->ki_pos != pos); 61 BUG_ON(iocb->ki_pos != pos);
65
66 if (unlikely(file->f_flags & O_DIRECT)) 62 if (unlikely(file->f_flags & O_DIRECT))
67 ioflags |= IO_ISDIRECT; 63 ioflags |= IO_ISDIRECT;
68 VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval); 64 return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
69 return rval;
70} 65}
71 66
72STATIC ssize_t 67STATIC ssize_t
@@ -100,15 +95,12 @@ __xfs_file_write(
100 struct iovec iov = {(void __user *)buf, count}; 95 struct iovec iov = {(void __user *)buf, count};
101 struct file *file = iocb->ki_filp; 96 struct file *file = iocb->ki_filp;
102 struct inode *inode = file->f_mapping->host; 97 struct inode *inode = file->f_mapping->host;
103 vnode_t *vp = vn_from_inode(inode); 98 bhv_vnode_t *vp = vn_from_inode(inode);
104 ssize_t rval;
105 99
106 BUG_ON(iocb->ki_pos != pos); 100 BUG_ON(iocb->ki_pos != pos);
107 if (unlikely(file->f_flags & O_DIRECT)) 101 if (unlikely(file->f_flags & O_DIRECT))
108 ioflags |= IO_ISDIRECT; 102 ioflags |= IO_ISDIRECT;
109 103 return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
110 VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
111 return rval;
112} 104}
113 105
114STATIC ssize_t 106STATIC ssize_t
@@ -140,7 +132,7 @@ __xfs_file_readv(
140 loff_t *ppos) 132 loff_t *ppos)
141{ 133{
142 struct inode *inode = file->f_mapping->host; 134 struct inode *inode = file->f_mapping->host;
143 vnode_t *vp = vn_from_inode(inode); 135 bhv_vnode_t *vp = vn_from_inode(inode);
144 struct kiocb kiocb; 136 struct kiocb kiocb;
145 ssize_t rval; 137 ssize_t rval;
146 138
@@ -149,7 +141,8 @@ __xfs_file_readv(
149 141
150 if (unlikely(file->f_flags & O_DIRECT)) 142 if (unlikely(file->f_flags & O_DIRECT))
151 ioflags |= IO_ISDIRECT; 143 ioflags |= IO_ISDIRECT;
152 VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval); 144 rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
145 &kiocb.ki_pos, ioflags, NULL);
153 146
154 *ppos = kiocb.ki_pos; 147 *ppos = kiocb.ki_pos;
155 return rval; 148 return rval;
@@ -184,7 +177,7 @@ __xfs_file_writev(
184 loff_t *ppos) 177 loff_t *ppos)
185{ 178{
186 struct inode *inode = file->f_mapping->host; 179 struct inode *inode = file->f_mapping->host;
187 vnode_t *vp = vn_from_inode(inode); 180 bhv_vnode_t *vp = vn_from_inode(inode);
188 struct kiocb kiocb; 181 struct kiocb kiocb;
189 ssize_t rval; 182 ssize_t rval;
190 183
@@ -193,7 +186,8 @@ __xfs_file_writev(
193 if (unlikely(file->f_flags & O_DIRECT)) 186 if (unlikely(file->f_flags & O_DIRECT))
194 ioflags |= IO_ISDIRECT; 187 ioflags |= IO_ISDIRECT;
195 188
196 VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval); 189 rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
190 &kiocb.ki_pos, ioflags, NULL);
197 191
198 *ppos = kiocb.ki_pos; 192 *ppos = kiocb.ki_pos;
199 return rval; 193 return rval;
@@ -227,11 +221,8 @@ xfs_file_sendfile(
227 read_actor_t actor, 221 read_actor_t actor,
228 void *target) 222 void *target)
229{ 223{
230 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 224 return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
231 ssize_t rval; 225 filp, pos, 0, count, actor, target, NULL);
232
233 VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval);
234 return rval;
235} 226}
236 227
237STATIC ssize_t 228STATIC ssize_t
@@ -242,11 +233,8 @@ xfs_file_sendfile_invis(
242 read_actor_t actor, 233 read_actor_t actor,
243 void *target) 234 void *target)
244{ 235{
245 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 236 return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
246 ssize_t rval; 237 filp, pos, IO_INVIS, count, actor, target, NULL);
247
248 VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval);
249 return rval;
250} 238}
251 239
252STATIC ssize_t 240STATIC ssize_t
@@ -257,11 +245,8 @@ xfs_file_splice_read(
257 size_t len, 245 size_t len,
258 unsigned int flags) 246 unsigned int flags)
259{ 247{
260 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); 248 return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
261 ssize_t rval; 249 infilp, ppos, pipe, len, flags, 0, NULL);
262
263 VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, 0, NULL, rval);
264 return rval;
265} 250}
266 251
267STATIC ssize_t 252STATIC ssize_t
@@ -272,11 +257,9 @@ xfs_file_splice_read_invis(
272 size_t len, 257 size_t len,
273 unsigned int flags) 258 unsigned int flags)
274{ 259{
275 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); 260 return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
276 ssize_t rval; 261 infilp, ppos, pipe, len, flags, IO_INVIS,
277 262 NULL);
278 VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, IO_INVIS, NULL, rval);
279 return rval;
280} 263}
281 264
282STATIC ssize_t 265STATIC ssize_t
@@ -287,11 +270,8 @@ xfs_file_splice_write(
287 size_t len, 270 size_t len,
288 unsigned int flags) 271 unsigned int flags)
289{ 272{
290 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); 273 return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
291 ssize_t rval; 274 pipe, outfilp, ppos, len, flags, 0, NULL);
292
293 VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, 0, NULL, rval);
294 return rval;
295} 275}
296 276
297STATIC ssize_t 277STATIC ssize_t
@@ -302,11 +282,9 @@ xfs_file_splice_write_invis(
302 size_t len, 282 size_t len,
303 unsigned int flags) 283 unsigned int flags)
304{ 284{
305 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); 285 return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
306 ssize_t rval; 286 pipe, outfilp, ppos, len, flags, IO_INVIS,
307 287 NULL);
308 VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, IO_INVIS, NULL, rval);
309 return rval;
310} 288}
311 289
312STATIC int 290STATIC int
@@ -314,13 +292,17 @@ xfs_file_open(
314 struct inode *inode, 292 struct inode *inode,
315 struct file *filp) 293 struct file *filp)
316{ 294{
317 vnode_t *vp = vn_from_inode(inode);
318 int error;
319
320 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) 295 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
321 return -EFBIG; 296 return -EFBIG;
322 VOP_OPEN(vp, NULL, error); 297 return -bhv_vop_open(vn_from_inode(inode), NULL);
323 return -error; 298}
299
300STATIC int
301xfs_file_close(
302 struct file *filp)
303{
304 return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0,
305 file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
324} 306}
325 307
326STATIC int 308STATIC int
@@ -328,12 +310,11 @@ xfs_file_release(
328 struct inode *inode, 310 struct inode *inode,
329 struct file *filp) 311 struct file *filp)
330{ 312{
331 vnode_t *vp = vn_from_inode(inode); 313 bhv_vnode_t *vp = vn_from_inode(inode);
332 int error = 0;
333 314
334 if (vp) 315 if (vp)
335 VOP_RELEASE(vp, error); 316 return -bhv_vop_release(vp);
336 return -error; 317 return 0;
337} 318}
338 319
339STATIC int 320STATIC int
@@ -342,15 +323,14 @@ xfs_file_fsync(
342 struct dentry *dentry, 323 struct dentry *dentry,
343 int datasync) 324 int datasync)
344{ 325{
345 struct inode *inode = dentry->d_inode; 326 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
346 vnode_t *vp = vn_from_inode(inode);
347 int error;
348 int flags = FSYNC_WAIT; 327 int flags = FSYNC_WAIT;
349 328
350 if (datasync) 329 if (datasync)
351 flags |= FSYNC_DATA; 330 flags |= FSYNC_DATA;
352 VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error); 331 if (VN_TRUNC(vp))
353 return -error; 332 VUNTRUNCATE(vp);
333 return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1);
354} 334}
355 335
356#ifdef CONFIG_XFS_DMAPI 336#ifdef CONFIG_XFS_DMAPI
@@ -361,16 +341,11 @@ xfs_vm_nopage(
361 int *type) 341 int *type)
362{ 342{
363 struct inode *inode = area->vm_file->f_dentry->d_inode; 343 struct inode *inode = area->vm_file->f_dentry->d_inode;
364 vnode_t *vp = vn_from_inode(inode); 344 bhv_vnode_t *vp = vn_from_inode(inode);
365 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
366 int error;
367 345
368 ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI); 346 ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI);
369 347 if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), area, 0))
370 error = XFS_SEND_MMAP(mp, area, 0);
371 if (error)
372 return NULL; 348 return NULL;
373
374 return filemap_nopage(area, address, type); 349 return filemap_nopage(area, address, type);
375} 350}
376#endif /* CONFIG_XFS_DMAPI */ 351#endif /* CONFIG_XFS_DMAPI */
@@ -382,7 +357,7 @@ xfs_file_readdir(
382 filldir_t filldir) 357 filldir_t filldir)
383{ 358{
384 int error = 0; 359 int error = 0;
385 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 360 bhv_vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
386 uio_t uio; 361 uio_t uio;
387 iovec_t iov; 362 iovec_t iov;
388 int eof = 0; 363 int eof = 0;
@@ -417,7 +392,7 @@ xfs_file_readdir(
417 392
418 start_offset = uio.uio_offset; 393 start_offset = uio.uio_offset;
419 394
420 VOP_READDIR(vp, &uio, NULL, &eof, error); 395 error = bhv_vop_readdir(vp, &uio, NULL, &eof);
421 if ((uio.uio_offset == start_offset) || error) { 396 if ((uio.uio_offset == start_offset) || error) {
422 size = 0; 397 size = 0;
423 break; 398 break;
@@ -456,38 +431,28 @@ xfs_file_mmap(
456 struct file *filp, 431 struct file *filp,
457 struct vm_area_struct *vma) 432 struct vm_area_struct *vma)
458{ 433{
459 struct inode *ip = filp->f_dentry->d_inode;
460 vnode_t *vp = vn_from_inode(ip);
461 vattr_t vattr;
462 int error;
463
464 vma->vm_ops = &xfs_file_vm_ops; 434 vma->vm_ops = &xfs_file_vm_ops;
465 435
466#ifdef CONFIG_XFS_DMAPI 436#ifdef CONFIG_XFS_DMAPI
467 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 437 if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
468 vma->vm_ops = &xfs_dmapi_file_vm_ops; 438 vma->vm_ops = &xfs_dmapi_file_vm_ops;
469 }
470#endif /* CONFIG_XFS_DMAPI */ 439#endif /* CONFIG_XFS_DMAPI */
471 440
472 vattr.va_mask = XFS_AT_UPDATIME; 441 file_accessed(filp);
473 VOP_SETATTR(vp, &vattr, XFS_AT_UPDATIME, NULL, error);
474 if (likely(!error))
475 __vn_revalidate(vp, &vattr); /* update flags */
476 return 0; 442 return 0;
477} 443}
478 444
479
480STATIC long 445STATIC long
481xfs_file_ioctl( 446xfs_file_ioctl(
482 struct file *filp, 447 struct file *filp,
483 unsigned int cmd, 448 unsigned int cmd,
484 unsigned long arg) 449 unsigned long p)
485{ 450{
486 int error; 451 int error;
487 struct inode *inode = filp->f_dentry->d_inode; 452 struct inode *inode = filp->f_dentry->d_inode;
488 vnode_t *vp = vn_from_inode(inode); 453 bhv_vnode_t *vp = vn_from_inode(inode);
489 454
490 VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error); 455 error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p);
491 VMODIFY(vp); 456 VMODIFY(vp);
492 457
493 /* NOTE: some of the ioctl's return positive #'s as a 458 /* NOTE: some of the ioctl's return positive #'s as a
@@ -503,13 +468,13 @@ STATIC long
503xfs_file_ioctl_invis( 468xfs_file_ioctl_invis(
504 struct file *filp, 469 struct file *filp,
505 unsigned int cmd, 470 unsigned int cmd,
506 unsigned long arg) 471 unsigned long p)
507{ 472{
508 struct inode *inode = filp->f_dentry->d_inode;
509 vnode_t *vp = vn_from_inode(inode);
510 int error; 473 int error;
474 struct inode *inode = filp->f_dentry->d_inode;
475 bhv_vnode_t *vp = vn_from_inode(inode);
511 476
512 VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); 477 error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p);
513 VMODIFY(vp); 478 VMODIFY(vp);
514 479
515 /* NOTE: some of the ioctl's return positive #'s as a 480 /* NOTE: some of the ioctl's return positive #'s as a
@@ -528,7 +493,7 @@ xfs_vm_mprotect(
528 struct vm_area_struct *vma, 493 struct vm_area_struct *vma,
529 unsigned int newflags) 494 unsigned int newflags)
530{ 495{
531 vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode); 496 bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
532 int error = 0; 497 int error = 0;
533 498
534 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 499 if (vp->v_vfsp->vfs_flag & VFS_DMI) {
@@ -554,24 +519,19 @@ STATIC int
554xfs_file_open_exec( 519xfs_file_open_exec(
555 struct inode *inode) 520 struct inode *inode)
556{ 521{
557 vnode_t *vp = vn_from_inode(inode); 522 bhv_vnode_t *vp = vn_from_inode(inode);
558 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
559 int error = 0;
560 xfs_inode_t *ip;
561 523
562 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 524 if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) {
563 ip = xfs_vtoi(vp); 525 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
564 if (!ip) { 526 xfs_inode_t *ip = xfs_vtoi(vp);
565 error = -EINVAL; 527
566 goto open_exec_out; 528 if (!ip)
567 } 529 return -EINVAL;
568 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) { 530 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ))
569 error = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 531 return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
570 0, 0, 0, NULL); 532 0, 0, 0, NULL);
571 }
572 } 533 }
573open_exec_out: 534 return 0;
574 return error;
575} 535}
576#endif /* HAVE_FOP_OPEN_EXEC */ 536#endif /* HAVE_FOP_OPEN_EXEC */
577 537
@@ -592,6 +552,7 @@ const struct file_operations xfs_file_operations = {
592#endif 552#endif
593 .mmap = xfs_file_mmap, 553 .mmap = xfs_file_mmap,
594 .open = xfs_file_open, 554 .open = xfs_file_open,
555 .flush = xfs_file_close,
595 .release = xfs_file_release, 556 .release = xfs_file_release,
596 .fsync = xfs_file_fsync, 557 .fsync = xfs_file_fsync,
597#ifdef HAVE_FOP_OPEN_EXEC 558#ifdef HAVE_FOP_OPEN_EXEC
@@ -616,6 +577,7 @@ const struct file_operations xfs_invis_file_operations = {
616#endif 577#endif
617 .mmap = xfs_file_mmap, 578 .mmap = xfs_file_mmap,
618 .open = xfs_file_open, 579 .open = xfs_file_open,
580 .flush = xfs_file_close,
619 .release = xfs_file_release, 581 .release = xfs_file_release,
620 .fsync = xfs_file_fsync, 582 .fsync = xfs_file_fsync,
621}; 583};
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index 575f2a790f31..dc0562828e76 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2002,2005-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -15,40 +15,12 @@
15 * along with this program; if not, write the Free Software Foundation, 15 * along with this program; if not, write the Free Software Foundation,
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
19#include "xfs.h" 18#include "xfs.h"
20 19
21/* 20int fs_noerr(void) { return 0; }
22 * Stub for no-op vnode operations that return error status. 21int fs_nosys(void) { return ENOSYS; }
23 */ 22void fs_noval(void) { return; }
24int
25fs_noerr(void)
26{
27 return 0;
28}
29 23
30/*
31 * Operation unsupported under this file system.
32 */
33int
34fs_nosys(void)
35{
36 return ENOSYS;
37}
38
39/*
40 * Stub for inactive, strategy, and read/write lock/unlock. Does nothing.
41 */
42/* ARGSUSED */
43void
44fs_noval(void)
45{
46}
47
48/*
49 * vnode pcache layer for vnode_tosspages.
50 * 'last' parameter unused but left in for IRIX compatibility
51 */
52void 24void
53fs_tosspages( 25fs_tosspages(
54 bhv_desc_t *bdp, 26 bhv_desc_t *bdp,
@@ -56,18 +28,13 @@ fs_tosspages(
56 xfs_off_t last, 28 xfs_off_t last,
57 int fiopt) 29 int fiopt)
58{ 30{
59 vnode_t *vp = BHV_TO_VNODE(bdp); 31 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
60 struct inode *ip = vn_to_inode(vp); 32 struct inode *ip = vn_to_inode(vp);
61 33
62 if (VN_CACHED(vp)) 34 if (VN_CACHED(vp))
63 truncate_inode_pages(ip->i_mapping, first); 35 truncate_inode_pages(ip->i_mapping, first);
64} 36}
65 37
66
67/*
68 * vnode pcache layer for vnode_flushinval_pages.
69 * 'last' parameter unused but left in for IRIX compatibility
70 */
71void 38void
72fs_flushinval_pages( 39fs_flushinval_pages(
73 bhv_desc_t *bdp, 40 bhv_desc_t *bdp,
@@ -75,20 +42,17 @@ fs_flushinval_pages(
75 xfs_off_t last, 42 xfs_off_t last,
76 int fiopt) 43 int fiopt)
77{ 44{
78 vnode_t *vp = BHV_TO_VNODE(bdp); 45 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
79 struct inode *ip = vn_to_inode(vp); 46 struct inode *ip = vn_to_inode(vp);
80 47
81 if (VN_CACHED(vp)) { 48 if (VN_CACHED(vp)) {
49 if (VN_TRUNC(vp))
50 VUNTRUNCATE(vp);
82 filemap_write_and_wait(ip->i_mapping); 51 filemap_write_and_wait(ip->i_mapping);
83
84 truncate_inode_pages(ip->i_mapping, first); 52 truncate_inode_pages(ip->i_mapping, first);
85 } 53 }
86} 54}
87 55
88/*
89 * vnode pcache layer for vnode_flush_pages.
90 * 'last' parameter unused but left in for IRIX compatibility
91 */
92int 56int
93fs_flush_pages( 57fs_flush_pages(
94 bhv_desc_t *bdp, 58 bhv_desc_t *bdp,
@@ -97,15 +61,16 @@ fs_flush_pages(
97 uint64_t flags, 61 uint64_t flags,
98 int fiopt) 62 int fiopt)
99{ 63{
100 vnode_t *vp = BHV_TO_VNODE(bdp); 64 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
101 struct inode *ip = vn_to_inode(vp); 65 struct inode *ip = vn_to_inode(vp);
102 66
103 if (VN_CACHED(vp)) { 67 if (VN_DIRTY(vp)) {
68 if (VN_TRUNC(vp))
69 VUNTRUNCATE(vp);
104 filemap_fdatawrite(ip->i_mapping); 70 filemap_fdatawrite(ip->i_mapping);
105 if (flags & XFS_B_ASYNC) 71 if (flags & XFS_B_ASYNC)
106 return 0; 72 return 0;
107 filemap_fdatawait(ip->i_mapping); 73 filemap_fdatawait(ip->i_mapping);
108 } 74 }
109
110 return 0; 75 return 0;
111} 76}
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c
index 6e8085f34635..6c162c3dde7e 100644
--- a/fs/xfs/linux-2.6/xfs_globals.c
+++ b/fs/xfs/linux-2.6/xfs_globals.c
@@ -45,6 +45,7 @@ xfs_param_t xfs_params = {
45 .xfs_buf_age = { 1*100, 15*100, 7200*100}, 45 .xfs_buf_age = { 1*100, 15*100, 7200*100},
46 .inherit_nosym = { 0, 0, 1 }, 46 .inherit_nosym = { 0, 0, 1 },
47 .rotorstep = { 1, 1, 255 }, 47 .rotorstep = { 1, 1, 255 },
48 .inherit_nodfrg = { 0, 1, 1 },
48}; 49};
49 50
50/* 51/*
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 84478491609b..6e52a5dd38d8 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -31,7 +30,6 @@
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -78,7 +76,7 @@ xfs_find_handle(
78 xfs_handle_t handle; 76 xfs_handle_t handle;
79 xfs_fsop_handlereq_t hreq; 77 xfs_fsop_handlereq_t hreq;
80 struct inode *inode; 78 struct inode *inode;
81 struct vnode *vp; 79 bhv_vnode_t *vp;
82 80
83 if (copy_from_user(&hreq, arg, sizeof(hreq))) 81 if (copy_from_user(&hreq, arg, sizeof(hreq)))
84 return -XFS_ERROR(EFAULT); 82 return -XFS_ERROR(EFAULT);
@@ -192,7 +190,7 @@ xfs_vget_fsop_handlereq(
192 xfs_mount_t *mp, 190 xfs_mount_t *mp,
193 struct inode *parinode, /* parent inode pointer */ 191 struct inode *parinode, /* parent inode pointer */
194 xfs_fsop_handlereq_t *hreq, 192 xfs_fsop_handlereq_t *hreq,
195 vnode_t **vp, 193 bhv_vnode_t **vp,
196 struct inode **inode) 194 struct inode **inode)
197{ 195{
198 void __user *hanp; 196 void __user *hanp;
@@ -202,7 +200,7 @@ xfs_vget_fsop_handlereq(
202 xfs_handle_t handle; 200 xfs_handle_t handle;
203 xfs_inode_t *ip; 201 xfs_inode_t *ip;
204 struct inode *inodep; 202 struct inode *inodep;
205 vnode_t *vpp; 203 bhv_vnode_t *vpp;
206 xfs_ino_t ino; 204 xfs_ino_t ino;
207 __u32 igen; 205 __u32 igen;
208 int error; 206 int error;
@@ -277,7 +275,7 @@ xfs_open_by_handle(
277 struct file *filp; 275 struct file *filp;
278 struct inode *inode; 276 struct inode *inode;
279 struct dentry *dentry; 277 struct dentry *dentry;
280 vnode_t *vp; 278 bhv_vnode_t *vp;
281 xfs_fsop_handlereq_t hreq; 279 xfs_fsop_handlereq_t hreq;
282 280
283 if (!capable(CAP_SYS_ADMIN)) 281 if (!capable(CAP_SYS_ADMIN))
@@ -362,7 +360,7 @@ xfs_readlink_by_handle(
362 struct uio auio; 360 struct uio auio;
363 struct inode *inode; 361 struct inode *inode;
364 xfs_fsop_handlereq_t hreq; 362 xfs_fsop_handlereq_t hreq;
365 vnode_t *vp; 363 bhv_vnode_t *vp;
366 __u32 olen; 364 __u32 olen;
367 365
368 if (!capable(CAP_SYS_ADMIN)) 366 if (!capable(CAP_SYS_ADMIN))
@@ -393,9 +391,11 @@ xfs_readlink_by_handle(
393 auio.uio_segflg = UIO_USERSPACE; 391 auio.uio_segflg = UIO_USERSPACE;
394 auio.uio_resid = olen; 392 auio.uio_resid = olen;
395 393
396 VOP_READLINK(vp, &auio, IO_INVIS, NULL, error); 394 error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL);
397
398 VN_RELE(vp); 395 VN_RELE(vp);
396 if (error)
397 return -error;
398
399 return (olen - auio.uio_resid); 399 return (olen - auio.uio_resid);
400} 400}
401 401
@@ -411,7 +411,7 @@ xfs_fssetdm_by_handle(
411 xfs_fsop_setdm_handlereq_t dmhreq; 411 xfs_fsop_setdm_handlereq_t dmhreq;
412 struct inode *inode; 412 struct inode *inode;
413 bhv_desc_t *bdp; 413 bhv_desc_t *bdp;
414 vnode_t *vp; 414 bhv_vnode_t *vp;
415 415
416 if (!capable(CAP_MKNOD)) 416 if (!capable(CAP_MKNOD))
417 return -XFS_ERROR(EPERM); 417 return -XFS_ERROR(EPERM);
@@ -452,7 +452,7 @@ xfs_attrlist_by_handle(
452 attrlist_cursor_kern_t *cursor; 452 attrlist_cursor_kern_t *cursor;
453 xfs_fsop_attrlist_handlereq_t al_hreq; 453 xfs_fsop_attrlist_handlereq_t al_hreq;
454 struct inode *inode; 454 struct inode *inode;
455 vnode_t *vp; 455 bhv_vnode_t *vp;
456 char *kbuf; 456 char *kbuf;
457 457
458 if (!capable(CAP_SYS_ADMIN)) 458 if (!capable(CAP_SYS_ADMIN))
@@ -472,8 +472,8 @@ xfs_attrlist_by_handle(
472 goto out_vn_rele; 472 goto out_vn_rele;
473 473
474 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; 474 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
475 VOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags, 475 error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags,
476 cursor, NULL, error); 476 cursor, NULL);
477 if (error) 477 if (error)
478 goto out_kfree; 478 goto out_kfree;
479 479
@@ -490,7 +490,7 @@ xfs_attrlist_by_handle(
490 490
491STATIC int 491STATIC int
492xfs_attrmulti_attr_get( 492xfs_attrmulti_attr_get(
493 struct vnode *vp, 493 bhv_vnode_t *vp,
494 char *name, 494 char *name,
495 char __user *ubuf, 495 char __user *ubuf,
496 __uint32_t *len, 496 __uint32_t *len,
@@ -505,7 +505,7 @@ xfs_attrmulti_attr_get(
505 if (!kbuf) 505 if (!kbuf)
506 return ENOMEM; 506 return ENOMEM;
507 507
508 VOP_ATTR_GET(vp, name, kbuf, len, flags, NULL, error); 508 error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL);
509 if (error) 509 if (error)
510 goto out_kfree; 510 goto out_kfree;
511 511
@@ -519,7 +519,7 @@ xfs_attrmulti_attr_get(
519 519
520STATIC int 520STATIC int
521xfs_attrmulti_attr_set( 521xfs_attrmulti_attr_set(
522 struct vnode *vp, 522 bhv_vnode_t *vp,
523 char *name, 523 char *name,
524 const char __user *ubuf, 524 const char __user *ubuf,
525 __uint32_t len, 525 __uint32_t len,
@@ -542,7 +542,7 @@ xfs_attrmulti_attr_set(
542 if (copy_from_user(kbuf, ubuf, len)) 542 if (copy_from_user(kbuf, ubuf, len))
543 goto out_kfree; 543 goto out_kfree;
544 544
545 VOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error); 545 error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL);
546 546
547 out_kfree: 547 out_kfree:
548 kfree(kbuf); 548 kfree(kbuf);
@@ -551,20 +551,15 @@ xfs_attrmulti_attr_set(
551 551
552STATIC int 552STATIC int
553xfs_attrmulti_attr_remove( 553xfs_attrmulti_attr_remove(
554 struct vnode *vp, 554 bhv_vnode_t *vp,
555 char *name, 555 char *name,
556 __uint32_t flags) 556 __uint32_t flags)
557{ 557{
558 int error;
559
560
561 if (IS_RDONLY(&vp->v_inode)) 558 if (IS_RDONLY(&vp->v_inode))
562 return -EROFS; 559 return -EROFS;
563 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) 560 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
564 return EPERM; 561 return EPERM;
565 562 return bhv_vop_attr_remove(vp, name, flags, NULL);
566 VOP_ATTR_REMOVE(vp, name, flags, NULL, error);
567 return error;
568} 563}
569 564
570STATIC int 565STATIC int
@@ -578,7 +573,7 @@ xfs_attrmulti_by_handle(
578 xfs_attr_multiop_t *ops; 573 xfs_attr_multiop_t *ops;
579 xfs_fsop_attrmulti_handlereq_t am_hreq; 574 xfs_fsop_attrmulti_handlereq_t am_hreq;
580 struct inode *inode; 575 struct inode *inode;
581 vnode_t *vp; 576 bhv_vnode_t *vp;
582 unsigned int i, size; 577 unsigned int i, size;
583 char *attr_name; 578 char *attr_name;
584 579
@@ -658,7 +653,7 @@ xfs_attrmulti_by_handle(
658STATIC int 653STATIC int
659xfs_ioc_space( 654xfs_ioc_space(
660 bhv_desc_t *bdp, 655 bhv_desc_t *bdp,
661 vnode_t *vp, 656 bhv_vnode_t *vp,
662 struct file *filp, 657 struct file *filp,
663 int flags, 658 int flags,
664 unsigned int cmd, 659 unsigned int cmd,
@@ -682,7 +677,7 @@ xfs_ioc_fsgeometry(
682 677
683STATIC int 678STATIC int
684xfs_ioc_xattr( 679xfs_ioc_xattr(
685 vnode_t *vp, 680 bhv_vnode_t *vp,
686 xfs_inode_t *ip, 681 xfs_inode_t *ip,
687 struct file *filp, 682 struct file *filp,
688 unsigned int cmd, 683 unsigned int cmd,
@@ -711,7 +706,7 @@ xfs_ioctl(
711 void __user *arg) 706 void __user *arg)
712{ 707{
713 int error; 708 int error;
714 vnode_t *vp; 709 bhv_vnode_t *vp;
715 xfs_inode_t *ip; 710 xfs_inode_t *ip;
716 xfs_mount_t *mp; 711 xfs_mount_t *mp;
717 712
@@ -962,7 +957,7 @@ xfs_ioctl(
962STATIC int 957STATIC int
963xfs_ioc_space( 958xfs_ioc_space(
964 bhv_desc_t *bdp, 959 bhv_desc_t *bdp,
965 vnode_t *vp, 960 bhv_vnode_t *vp,
966 struct file *filp, 961 struct file *filp,
967 int ioflags, 962 int ioflags,
968 unsigned int cmd, 963 unsigned int cmd,
@@ -1153,14 +1148,14 @@ xfs_di2lxflags(
1153 1148
1154STATIC int 1149STATIC int
1155xfs_ioc_xattr( 1150xfs_ioc_xattr(
1156 vnode_t *vp, 1151 bhv_vnode_t *vp,
1157 xfs_inode_t *ip, 1152 xfs_inode_t *ip,
1158 struct file *filp, 1153 struct file *filp,
1159 unsigned int cmd, 1154 unsigned int cmd,
1160 void __user *arg) 1155 void __user *arg)
1161{ 1156{
1162 struct fsxattr fa; 1157 struct fsxattr fa;
1163 struct vattr *vattr; 1158 struct bhv_vattr *vattr;
1164 int error = 0; 1159 int error = 0;
1165 int attr_flags; 1160 int attr_flags;
1166 unsigned int flags; 1161 unsigned int flags;
@@ -1173,7 +1168,7 @@ xfs_ioc_xattr(
1173 case XFS_IOC_FSGETXATTR: { 1168 case XFS_IOC_FSGETXATTR: {
1174 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ 1169 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1175 XFS_AT_NEXTENTS | XFS_AT_PROJID; 1170 XFS_AT_NEXTENTS | XFS_AT_PROJID;
1176 VOP_GETATTR(vp, vattr, 0, NULL, error); 1171 error = bhv_vop_getattr(vp, vattr, 0, NULL);
1177 if (unlikely(error)) { 1172 if (unlikely(error)) {
1178 error = -error; 1173 error = -error;
1179 break; 1174 break;
@@ -1206,7 +1201,7 @@ xfs_ioc_xattr(
1206 vattr->va_extsize = fa.fsx_extsize; 1201 vattr->va_extsize = fa.fsx_extsize;
1207 vattr->va_projid = fa.fsx_projid; 1202 vattr->va_projid = fa.fsx_projid;
1208 1203
1209 VOP_SETATTR(vp, vattr, attr_flags, NULL, error); 1204 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
1210 if (likely(!error)) 1205 if (likely(!error))
1211 __vn_revalidate(vp, vattr); /* update flags */ 1206 __vn_revalidate(vp, vattr); /* update flags */
1212 error = -error; 1207 error = -error;
@@ -1216,7 +1211,7 @@ xfs_ioc_xattr(
1216 case XFS_IOC_FSGETXATTRA: { 1211 case XFS_IOC_FSGETXATTRA: {
1217 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ 1212 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1218 XFS_AT_ANEXTENTS | XFS_AT_PROJID; 1213 XFS_AT_ANEXTENTS | XFS_AT_PROJID;
1219 VOP_GETATTR(vp, vattr, 0, NULL, error); 1214 error = bhv_vop_getattr(vp, vattr, 0, NULL);
1220 if (unlikely(error)) { 1215 if (unlikely(error)) {
1221 error = -error; 1216 error = -error;
1222 break; 1217 break;
@@ -1262,7 +1257,7 @@ xfs_ioc_xattr(
1262 vattr->va_xflags = xfs_merge_ioc_xflags(flags, 1257 vattr->va_xflags = xfs_merge_ioc_xflags(flags,
1263 xfs_ip2xflags(ip)); 1258 xfs_ip2xflags(ip));
1264 1259
1265 VOP_SETATTR(vp, vattr, attr_flags, NULL, error); 1260 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
1266 if (likely(!error)) 1261 if (likely(!error))
1267 __vn_revalidate(vp, vattr); /* update flags */ 1262 __vn_revalidate(vp, vattr); /* update flags */
1268 error = -error; 1263 error = -error;
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 251bfe451a3f..601f01c92f7f 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -114,7 +114,7 @@ xfs_compat_ioctl(
114 unsigned long arg) 114 unsigned long arg)
115{ 115{
116 struct inode *inode = file->f_dentry->d_inode; 116 struct inode *inode = file->f_dentry->d_inode;
117 vnode_t *vp = vn_from_inode(inode); 117 bhv_vnode_t *vp = vn_from_inode(inode);
118 int error; 118 int error;
119 119
120 switch (cmd) { 120 switch (cmd) {
@@ -193,7 +193,7 @@ xfs_compat_ioctl(
193 return -ENOIOCTLCMD; 193 return -ENOIOCTLCMD;
194 } 194 }
195 195
196 VOP_IOCTL(vp, inode, file, mode, cmd, (void __user *)arg, error); 196 error = bhv_vop_ioctl(vp, inode, file, mode, cmd, (void __user *)arg);
197 VMODIFY(vp); 197 VMODIFY(vp);
198 198
199 return error; 199 return error;
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 2e2e275c786f..12810baeb5d4 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -61,7 +59,7 @@
61 */ 59 */
62xfs_inode_t * 60xfs_inode_t *
63xfs_vtoi( 61xfs_vtoi(
64 struct vnode *vp) 62 bhv_vnode_t *vp)
65{ 63{
66 bhv_desc_t *bdp; 64 bhv_desc_t *bdp;
67 65
@@ -80,7 +78,7 @@ void
80xfs_synchronize_atime( 78xfs_synchronize_atime(
81 xfs_inode_t *ip) 79 xfs_inode_t *ip)
82{ 80{
83 vnode_t *vp; 81 bhv_vnode_t *vp;
84 82
85 vp = XFS_ITOV_NULL(ip); 83 vp = XFS_ITOV_NULL(ip);
86 if (vp) { 84 if (vp) {
@@ -200,14 +198,10 @@ xfs_ichgtime_fast(
200STATIC void 198STATIC void
201xfs_validate_fields( 199xfs_validate_fields(
202 struct inode *ip, 200 struct inode *ip,
203 struct vattr *vattr) 201 bhv_vattr_t *vattr)
204{ 202{
205 vnode_t *vp = vn_from_inode(ip);
206 int error;
207
208 vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS; 203 vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
209 VOP_GETATTR(vp, vattr, ATTR_LAZY, NULL, error); 204 if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) {
210 if (likely(!error)) {
211 ip->i_nlink = vattr->va_nlink; 205 ip->i_nlink = vattr->va_nlink;
212 ip->i_blocks = vattr->va_nblocks; 206 ip->i_blocks = vattr->va_nblocks;
213 207
@@ -225,7 +219,7 @@ xfs_validate_fields(
225 */ 219 */
226STATIC int 220STATIC int
227xfs_init_security( 221xfs_init_security(
228 struct vnode *vp, 222 bhv_vnode_t *vp,
229 struct inode *dir) 223 struct inode *dir)
230{ 224{
231 struct inode *ip = vn_to_inode(vp); 225 struct inode *ip = vn_to_inode(vp);
@@ -241,7 +235,7 @@ xfs_init_security(
241 return -error; 235 return -error;
242 } 236 }
243 237
244 VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error); 238 error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL);
245 if (!error) 239 if (!error)
246 VMODIFY(vp); 240 VMODIFY(vp);
247 241
@@ -264,13 +258,12 @@ xfs_has_fs_struct(struct task_struct *task)
264 258
265STATIC inline void 259STATIC inline void
266xfs_cleanup_inode( 260xfs_cleanup_inode(
267 vnode_t *dvp, 261 bhv_vnode_t *dvp,
268 vnode_t *vp, 262 bhv_vnode_t *vp,
269 struct dentry *dentry, 263 struct dentry *dentry,
270 int mode) 264 int mode)
271{ 265{
272 struct dentry teardown = {}; 266 struct dentry teardown = {};
273 int error;
274 267
275 /* Oh, the horror. 268 /* Oh, the horror.
276 * If we can't add the ACL or we fail in 269 * If we can't add the ACL or we fail in
@@ -281,9 +274,9 @@ xfs_cleanup_inode(
281 teardown.d_name = dentry->d_name; 274 teardown.d_name = dentry->d_name;
282 275
283 if (S_ISDIR(mode)) 276 if (S_ISDIR(mode))
284 VOP_RMDIR(dvp, &teardown, NULL, error); 277 bhv_vop_rmdir(dvp, &teardown, NULL);
285 else 278 else
286 VOP_REMOVE(dvp, &teardown, NULL, error); 279 bhv_vop_remove(dvp, &teardown, NULL);
287 VN_RELE(vp); 280 VN_RELE(vp);
288} 281}
289 282
@@ -295,8 +288,8 @@ xfs_vn_mknod(
295 dev_t rdev) 288 dev_t rdev)
296{ 289{
297 struct inode *ip; 290 struct inode *ip;
298 vattr_t vattr = { 0 }; 291 bhv_vattr_t vattr = { 0 };
299 vnode_t *vp = NULL, *dvp = vn_from_inode(dir); 292 bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
300 xfs_acl_t *default_acl = NULL; 293 xfs_acl_t *default_acl = NULL;
301 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; 294 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
302 int error; 295 int error;
@@ -330,10 +323,10 @@ xfs_vn_mknod(
330 vattr.va_mask |= XFS_AT_RDEV; 323 vattr.va_mask |= XFS_AT_RDEV;
331 /*FALLTHROUGH*/ 324 /*FALLTHROUGH*/
332 case S_IFREG: 325 case S_IFREG:
333 VOP_CREATE(dvp, dentry, &vattr, &vp, NULL, error); 326 error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL);
334 break; 327 break;
335 case S_IFDIR: 328 case S_IFDIR:
336 VOP_MKDIR(dvp, dentry, &vattr, &vp, NULL, error); 329 error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL);
337 break; 330 break;
338 default: 331 default:
339 error = EINVAL; 332 error = EINVAL;
@@ -396,14 +389,14 @@ xfs_vn_lookup(
396 struct dentry *dentry, 389 struct dentry *dentry,
397 struct nameidata *nd) 390 struct nameidata *nd)
398{ 391{
399 struct vnode *vp = vn_from_inode(dir), *cvp; 392 bhv_vnode_t *vp = vn_from_inode(dir), *cvp;
400 int error; 393 int error;
401 394
402 if (dentry->d_name.len >= MAXNAMELEN) 395 if (dentry->d_name.len >= MAXNAMELEN)
403 return ERR_PTR(-ENAMETOOLONG); 396 return ERR_PTR(-ENAMETOOLONG);
404 397
405 VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error); 398 error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL);
406 if (error) { 399 if (unlikely(error)) {
407 if (unlikely(error != ENOENT)) 400 if (unlikely(error != ENOENT))
408 return ERR_PTR(-error); 401 return ERR_PTR(-error);
409 d_add(dentry, NULL); 402 d_add(dentry, NULL);
@@ -420,9 +413,9 @@ xfs_vn_link(
420 struct dentry *dentry) 413 struct dentry *dentry)
421{ 414{
422 struct inode *ip; /* inode of guy being linked to */ 415 struct inode *ip; /* inode of guy being linked to */
423 vnode_t *tdvp; /* target directory for new name/link */ 416 bhv_vnode_t *tdvp; /* target directory for new name/link */
424 vnode_t *vp; /* vp of name being linked */ 417 bhv_vnode_t *vp; /* vp of name being linked */
425 vattr_t vattr; 418 bhv_vattr_t vattr;
426 int error; 419 int error;
427 420
428 ip = old_dentry->d_inode; /* inode being linked to */ 421 ip = old_dentry->d_inode; /* inode being linked to */
@@ -432,7 +425,7 @@ xfs_vn_link(
432 tdvp = vn_from_inode(dir); 425 tdvp = vn_from_inode(dir);
433 vp = vn_from_inode(ip); 426 vp = vn_from_inode(ip);
434 427
435 VOP_LINK(tdvp, vp, dentry, NULL, error); 428 error = bhv_vop_link(tdvp, vp, dentry, NULL);
436 if (likely(!error)) { 429 if (likely(!error)) {
437 VMODIFY(tdvp); 430 VMODIFY(tdvp);
438 VN_HOLD(vp); 431 VN_HOLD(vp);
@@ -448,14 +441,14 @@ xfs_vn_unlink(
448 struct dentry *dentry) 441 struct dentry *dentry)
449{ 442{
450 struct inode *inode; 443 struct inode *inode;
451 vnode_t *dvp; /* directory containing name to remove */ 444 bhv_vnode_t *dvp; /* directory containing name to remove */
452 vattr_t vattr; 445 bhv_vattr_t vattr;
453 int error; 446 int error;
454 447
455 inode = dentry->d_inode; 448 inode = dentry->d_inode;
456 dvp = vn_from_inode(dir); 449 dvp = vn_from_inode(dir);
457 450
458 VOP_REMOVE(dvp, dentry, NULL, error); 451 error = bhv_vop_remove(dvp, dentry, NULL);
459 if (likely(!error)) { 452 if (likely(!error)) {
460 xfs_validate_fields(dir, &vattr); /* size needs update */ 453 xfs_validate_fields(dir, &vattr); /* size needs update */
461 xfs_validate_fields(inode, &vattr); 454 xfs_validate_fields(inode, &vattr);
@@ -470,27 +463,26 @@ xfs_vn_symlink(
470 const char *symname) 463 const char *symname)
471{ 464{
472 struct inode *ip; 465 struct inode *ip;
473 vattr_t vattr = { 0 }; 466 bhv_vattr_t va = { 0 };
474 vnode_t *dvp; /* directory containing name of symlink */ 467 bhv_vnode_t *dvp; /* directory containing name of symlink */
475 vnode_t *cvp; /* used to lookup symlink to put in dentry */ 468 bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */
476 int error; 469 int error;
477 470
478 dvp = vn_from_inode(dir); 471 dvp = vn_from_inode(dir);
479 cvp = NULL; 472 cvp = NULL;
480 473
481 vattr.va_mode = S_IFLNK | 474 va.va_mode = S_IFLNK |
482 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); 475 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
483 vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE; 476 va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
484 477
485 error = 0; 478 error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL);
486 VOP_SYMLINK(dvp, dentry, &vattr, (char *)symname, &cvp, NULL, error);
487 if (likely(!error && cvp)) { 479 if (likely(!error && cvp)) {
488 error = xfs_init_security(cvp, dir); 480 error = xfs_init_security(cvp, dir);
489 if (likely(!error)) { 481 if (likely(!error)) {
490 ip = vn_to_inode(cvp); 482 ip = vn_to_inode(cvp);
491 d_instantiate(dentry, ip); 483 d_instantiate(dentry, ip);
492 xfs_validate_fields(dir, &vattr); 484 xfs_validate_fields(dir, &va);
493 xfs_validate_fields(ip, &vattr); 485 xfs_validate_fields(ip, &va);
494 } else { 486 } else {
495 xfs_cleanup_inode(dvp, cvp, dentry, 0); 487 xfs_cleanup_inode(dvp, cvp, dentry, 0);
496 } 488 }
@@ -504,11 +496,11 @@ xfs_vn_rmdir(
504 struct dentry *dentry) 496 struct dentry *dentry)
505{ 497{
506 struct inode *inode = dentry->d_inode; 498 struct inode *inode = dentry->d_inode;
507 vnode_t *dvp = vn_from_inode(dir); 499 bhv_vnode_t *dvp = vn_from_inode(dir);
508 vattr_t vattr; 500 bhv_vattr_t vattr;
509 int error; 501 int error;
510 502
511 VOP_RMDIR(dvp, dentry, NULL, error); 503 error = bhv_vop_rmdir(dvp, dentry, NULL);
512 if (likely(!error)) { 504 if (likely(!error)) {
513 xfs_validate_fields(inode, &vattr); 505 xfs_validate_fields(inode, &vattr);
514 xfs_validate_fields(dir, &vattr); 506 xfs_validate_fields(dir, &vattr);
@@ -524,15 +516,15 @@ xfs_vn_rename(
524 struct dentry *ndentry) 516 struct dentry *ndentry)
525{ 517{
526 struct inode *new_inode = ndentry->d_inode; 518 struct inode *new_inode = ndentry->d_inode;
527 vnode_t *fvp; /* from directory */ 519 bhv_vnode_t *fvp; /* from directory */
528 vnode_t *tvp; /* target directory */ 520 bhv_vnode_t *tvp; /* target directory */
529 vattr_t vattr; 521 bhv_vattr_t vattr;
530 int error; 522 int error;
531 523
532 fvp = vn_from_inode(odir); 524 fvp = vn_from_inode(odir);
533 tvp = vn_from_inode(ndir); 525 tvp = vn_from_inode(ndir);
534 526
535 VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error); 527 error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL);
536 if (likely(!error)) { 528 if (likely(!error)) {
537 if (new_inode) 529 if (new_inode)
538 xfs_validate_fields(new_inode, &vattr); 530 xfs_validate_fields(new_inode, &vattr);
@@ -553,7 +545,7 @@ xfs_vn_follow_link(
553 struct dentry *dentry, 545 struct dentry *dentry,
554 struct nameidata *nd) 546 struct nameidata *nd)
555{ 547{
556 vnode_t *vp; 548 bhv_vnode_t *vp;
557 uio_t *uio; 549 uio_t *uio;
558 iovec_t iov; 550 iovec_t iov;
559 int error; 551 int error;
@@ -586,8 +578,8 @@ xfs_vn_follow_link(
586 uio->uio_resid = MAXPATHLEN; 578 uio->uio_resid = MAXPATHLEN;
587 uio->uio_iovcnt = 1; 579 uio->uio_iovcnt = 1;
588 580
589 VOP_READLINK(vp, uio, 0, NULL, error); 581 error = bhv_vop_readlink(vp, uio, 0, NULL);
590 if (error) { 582 if (unlikely(error)) {
591 kfree(link); 583 kfree(link);
592 link = ERR_PTR(-error); 584 link = ERR_PTR(-error);
593 } else { 585 } else {
@@ -618,12 +610,7 @@ xfs_vn_permission(
618 int mode, 610 int mode,
619 struct nameidata *nd) 611 struct nameidata *nd)
620{ 612{
621 vnode_t *vp = vn_from_inode(inode); 613 return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL);
622 int error;
623
624 mode <<= 6; /* convert from linux to vnode access bits */
625 VOP_ACCESS(vp, mode, NULL, error);
626 return -error;
627} 614}
628#else 615#else
629#define xfs_vn_permission NULL 616#define xfs_vn_permission NULL
@@ -636,14 +623,14 @@ xfs_vn_getattr(
636 struct kstat *stat) 623 struct kstat *stat)
637{ 624{
638 struct inode *inode = dentry->d_inode; 625 struct inode *inode = dentry->d_inode;
639 vnode_t *vp = vn_from_inode(inode); 626 bhv_vnode_t *vp = vn_from_inode(inode);
640 int error = 0; 627 int error = 0;
641 628
642 if (unlikely(vp->v_flag & VMODIFIED)) 629 if (unlikely(vp->v_flag & VMODIFIED))
643 error = vn_revalidate(vp); 630 error = vn_revalidate(vp);
644 if (!error) 631 if (!error)
645 generic_fillattr(inode, stat); 632 generic_fillattr(inode, stat);
646 return 0; 633 return -error;
647} 634}
648 635
649STATIC int 636STATIC int
@@ -653,8 +640,8 @@ xfs_vn_setattr(
653{ 640{
654 struct inode *inode = dentry->d_inode; 641 struct inode *inode = dentry->d_inode;
655 unsigned int ia_valid = attr->ia_valid; 642 unsigned int ia_valid = attr->ia_valid;
656 vnode_t *vp = vn_from_inode(inode); 643 bhv_vnode_t *vp = vn_from_inode(inode);
657 vattr_t vattr = { 0 }; 644 bhv_vattr_t vattr = { 0 };
658 int flags = 0; 645 int flags = 0;
659 int error; 646 int error;
660 647
@@ -697,7 +684,7 @@ xfs_vn_setattr(
697 flags |= ATTR_NONBLOCK; 684 flags |= ATTR_NONBLOCK;
698#endif 685#endif
699 686
700 VOP_SETATTR(vp, &vattr, flags, NULL, error); 687 error = bhv_vop_setattr(vp, &vattr, flags, NULL);
701 if (likely(!error)) 688 if (likely(!error))
702 __vn_revalidate(vp, &vattr); 689 __vn_revalidate(vp, &vattr);
703 return -error; 690 return -error;
@@ -718,7 +705,7 @@ xfs_vn_setxattr(
718 size_t size, 705 size_t size,
719 int flags) 706 int flags)
720{ 707{
721 vnode_t *vp = vn_from_inode(dentry->d_inode); 708 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
722 char *attr = (char *)name; 709 char *attr = (char *)name;
723 attrnames_t *namesp; 710 attrnames_t *namesp;
724 int xflags = 0; 711 int xflags = 0;
@@ -748,7 +735,7 @@ xfs_vn_getxattr(
748 void *data, 735 void *data,
749 size_t size) 736 size_t size)
750{ 737{
751 vnode_t *vp = vn_from_inode(dentry->d_inode); 738 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
752 char *attr = (char *)name; 739 char *attr = (char *)name;
753 attrnames_t *namesp; 740 attrnames_t *namesp;
754 int xflags = 0; 741 int xflags = 0;
@@ -777,7 +764,7 @@ xfs_vn_listxattr(
777 char *data, 764 char *data,
778 size_t size) 765 size_t size)
779{ 766{
780 vnode_t *vp = vn_from_inode(dentry->d_inode); 767 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
781 int error, xflags = ATTR_KERNAMELS; 768 int error, xflags = ATTR_KERNAMELS;
782 ssize_t result; 769 ssize_t result;
783 770
@@ -796,7 +783,7 @@ xfs_vn_removexattr(
796 struct dentry *dentry, 783 struct dentry *dentry,
797 const char *name) 784 const char *name)
798{ 785{
799 vnode_t *vp = vn_from_inode(dentry->d_inode); 786 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
800 char *attr = (char *)name; 787 char *attr = (char *)name;
801 attrnames_t *namesp; 788 attrnames_t *namesp;
802 int xflags = 0; 789 int xflags = 0;
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index e9fe43d74768..aa26ab906c88 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -134,14 +134,21 @@ BUFFER_FNS(PrivateStart, unwritten);
134#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val 134#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val
135#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val 135#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
136#define xfs_rotorstep xfs_params.rotorstep.val 136#define xfs_rotorstep xfs_params.rotorstep.val
137#define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
137 138
138#ifndef raw_smp_processor_id 139#define current_cpu() (raw_smp_processor_id())
139#define raw_smp_processor_id() smp_processor_id()
140#endif
141#define current_cpu() raw_smp_processor_id()
142#define current_pid() (current->pid) 140#define current_pid() (current->pid)
143#define current_fsuid(cred) (current->fsuid) 141#define current_fsuid(cred) (current->fsuid)
144#define current_fsgid(cred) (current->fsgid) 142#define current_fsgid(cred) (current->fsgid)
143#define current_set_flags(f) (current->flags |= (f))
144#define current_test_flags(f) (current->flags & (f))
145#define current_clear_flags(f) (current->flags & ~(f))
146#define current_set_flags_nested(sp, f) \
147 (*(sp) = current->flags, current->flags |= (f))
148#define current_clear_flags_nested(sp, f) \
149 (*(sp) = current->flags, current->flags &= ~(f))
150#define current_restore_flags_nested(sp, f) \
151 (current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
145 152
146#define NBPP PAGE_SIZE 153#define NBPP PAGE_SIZE
147#define DPPSHFT (PAGE_SHIFT - 9) 154#define DPPSHFT (PAGE_SHIFT - 9)
@@ -187,25 +194,9 @@ BUFFER_FNS(PrivateStart, unwritten);
187/* bytes to clicks */ 194/* bytes to clicks */
188#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) 195#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
189 196
190#ifndef ENOATTR
191#define ENOATTR ENODATA /* Attribute not found */ 197#define ENOATTR ENODATA /* Attribute not found */
192#endif 198#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
193 199#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
194/* Note: EWRONGFS never visible outside the kernel */
195#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
196
197/*
198 * XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't
199 * return codes out of its known range in errno.
200 * XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't
201 * conflict with any code we use already or any code a driver may use)
202 * XXX Some options (currently we do #2):
203 * 1/ New error code ["Filesystem is corrupted", _after_ glibc updated]
204 * 2/ 990 ["Unknown error 990"]
205 * 3/ EUCLEAN ["Structure needs cleaning"]
206 * 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace]
207 */
208#define EFSCORRUPTED 990 /* Filesystem is corrupted */
209 200
210#define SYNCHRONIZE() barrier() 201#define SYNCHRONIZE() barrier()
211#define __return_address __builtin_return_address(0) 202#define __return_address __builtin_return_address(0)
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 67efe3308980..5d9cfd91ad08 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -206,7 +204,7 @@ xfs_read(
206 xfs_fsize_t n; 204 xfs_fsize_t n;
207 xfs_inode_t *ip; 205 xfs_inode_t *ip;
208 xfs_mount_t *mp; 206 xfs_mount_t *mp;
209 vnode_t *vp; 207 bhv_vnode_t *vp;
210 unsigned long seg; 208 unsigned long seg;
211 209
212 ip = XFS_BHVTOI(bdp); 210 ip = XFS_BHVTOI(bdp);
@@ -258,7 +256,7 @@ xfs_read(
258 256
259 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && 257 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
260 !(ioflags & IO_INVIS)) { 258 !(ioflags & IO_INVIS)) {
261 vrwlock_t locktype = VRWLOCK_READ; 259 bhv_vrwlock_t locktype = VRWLOCK_READ;
262 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); 260 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
263 261
264 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, 262 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
@@ -271,7 +269,7 @@ xfs_read(
271 } 269 }
272 270
273 if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) 271 if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
274 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(*offset)), 272 bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
275 -1, FI_REMAPF_LOCKED); 273 -1, FI_REMAPF_LOCKED);
276 274
277 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, 275 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
@@ -313,7 +311,7 @@ xfs_sendfile(
313 311
314 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && 312 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
315 (!(ioflags & IO_INVIS))) { 313 (!(ioflags & IO_INVIS))) {
316 vrwlock_t locktype = VRWLOCK_READ; 314 bhv_vrwlock_t locktype = VRWLOCK_READ;
317 int error; 315 int error;
318 316
319 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), 317 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@@ -357,7 +355,7 @@ xfs_splice_read(
357 355
358 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && 356 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
359 (!(ioflags & IO_INVIS))) { 357 (!(ioflags & IO_INVIS))) {
360 vrwlock_t locktype = VRWLOCK_READ; 358 bhv_vrwlock_t locktype = VRWLOCK_READ;
361 int error; 359 int error;
362 360
363 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), 361 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@@ -401,7 +399,7 @@ xfs_splice_write(
401 399
402 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) && 400 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
403 (!(ioflags & IO_INVIS))) { 401 (!(ioflags & IO_INVIS))) {
404 vrwlock_t locktype = VRWLOCK_WRITE; 402 bhv_vrwlock_t locktype = VRWLOCK_WRITE;
405 int error; 403 int error;
406 404
407 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), 405 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
@@ -458,7 +456,7 @@ xfs_zero_last_block(
458 last_fsb = XFS_B_TO_FSBT(mp, isize); 456 last_fsb = XFS_B_TO_FSBT(mp, isize);
459 nimaps = 1; 457 nimaps = 1;
460 error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, 458 error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
461 &nimaps, NULL); 459 &nimaps, NULL, NULL);
462 if (error) { 460 if (error) {
463 return error; 461 return error;
464 } 462 }
@@ -499,7 +497,7 @@ xfs_zero_last_block(
499 497
500int /* error (positive) */ 498int /* error (positive) */
501xfs_zero_eof( 499xfs_zero_eof(
502 vnode_t *vp, 500 bhv_vnode_t *vp,
503 xfs_iocore_t *io, 501 xfs_iocore_t *io,
504 xfs_off_t offset, /* starting I/O offset */ 502 xfs_off_t offset, /* starting I/O offset */
505 xfs_fsize_t isize, /* current inode size */ 503 xfs_fsize_t isize, /* current inode size */
@@ -510,7 +508,6 @@ xfs_zero_eof(
510 xfs_fileoff_t end_zero_fsb; 508 xfs_fileoff_t end_zero_fsb;
511 xfs_fileoff_t zero_count_fsb; 509 xfs_fileoff_t zero_count_fsb;
512 xfs_fileoff_t last_fsb; 510 xfs_fileoff_t last_fsb;
513 xfs_extlen_t buf_len_fsb;
514 xfs_mount_t *mp = io->io_mount; 511 xfs_mount_t *mp = io->io_mount;
515 int nimaps; 512 int nimaps;
516 int error = 0; 513 int error = 0;
@@ -556,7 +553,7 @@ xfs_zero_eof(
556 nimaps = 1; 553 nimaps = 1;
557 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; 554 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
558 error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, 555 error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb,
559 0, NULL, 0, &imap, &nimaps, NULL); 556 0, NULL, 0, &imap, &nimaps, NULL, NULL);
560 if (error) { 557 if (error) {
561 ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); 558 ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
562 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); 559 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@@ -579,16 +576,7 @@ xfs_zero_eof(
579 } 576 }
580 577
581 /* 578 /*
582 * There are blocks in the range requested. 579 * There are blocks we need to zero.
583 * Zero them a single write at a time. We actually
584 * don't zero the entire range returned if it is
585 * too big and simply loop around to get the rest.
586 * That is not the most efficient thing to do, but it
587 * is simple and this path should not be exercised often.
588 */
589 buf_len_fsb = XFS_FILBLKS_MIN(imap.br_blockcount,
590 mp->m_writeio_blocks << 8);
591 /*
592 * Drop the inode lock while we're doing the I/O. 580 * Drop the inode lock while we're doing the I/O.
593 * We'll still have the iolock to protect us. 581 * We'll still have the iolock to protect us.
594 */ 582 */
@@ -596,14 +584,13 @@ xfs_zero_eof(
596 584
597 error = xfs_iozero(ip, 585 error = xfs_iozero(ip,
598 XFS_FSB_TO_B(mp, start_zero_fsb), 586 XFS_FSB_TO_B(mp, start_zero_fsb),
599 XFS_FSB_TO_B(mp, buf_len_fsb), 587 XFS_FSB_TO_B(mp, imap.br_blockcount),
600 end_size); 588 end_size);
601
602 if (error) { 589 if (error) {
603 goto out_lock; 590 goto out_lock;
604 } 591 }
605 592
606 start_zero_fsb = imap.br_startoff + buf_len_fsb; 593 start_zero_fsb = imap.br_startoff + imap.br_blockcount;
607 ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); 594 ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
608 595
609 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); 596 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
@@ -637,11 +624,11 @@ xfs_write(
637 ssize_t ret = 0, error = 0; 624 ssize_t ret = 0, error = 0;
638 xfs_fsize_t isize, new_size; 625 xfs_fsize_t isize, new_size;
639 xfs_iocore_t *io; 626 xfs_iocore_t *io;
640 vnode_t *vp; 627 bhv_vnode_t *vp;
641 unsigned long seg; 628 unsigned long seg;
642 int iolock; 629 int iolock;
643 int eventsent = 0; 630 int eventsent = 0;
644 vrwlock_t locktype; 631 bhv_vrwlock_t locktype;
645 size_t ocount = 0, count; 632 size_t ocount = 0, count;
646 loff_t pos; 633 loff_t pos;
647 int need_i_mutex = 1, need_flush = 0; 634 int need_i_mutex = 1, need_flush = 0;
@@ -679,11 +666,11 @@ xfs_write(
679 io = &xip->i_iocore; 666 io = &xip->i_iocore;
680 mp = io->io_mount; 667 mp = io->io_mount;
681 668
669 vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE);
670
682 if (XFS_FORCED_SHUTDOWN(mp)) 671 if (XFS_FORCED_SHUTDOWN(mp))
683 return -EIO; 672 return -EIO;
684 673
685 fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE);
686
687 if (ioflags & IO_ISDIRECT) { 674 if (ioflags & IO_ISDIRECT) {
688 xfs_buftarg_t *target = 675 xfs_buftarg_t *target =
689 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? 676 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
@@ -814,7 +801,7 @@ retry:
814 if (need_flush) { 801 if (need_flush) {
815 xfs_inval_cached_trace(io, pos, -1, 802 xfs_inval_cached_trace(io, pos, -1,
816 ctooff(offtoct(pos)), -1); 803 ctooff(offtoct(pos)), -1);
817 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(pos)), 804 bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
818 -1, FI_REMAPF_LOCKED); 805 -1, FI_REMAPF_LOCKED);
819 } 806 }
820 807
@@ -903,79 +890,9 @@ retry:
903 890
904 /* Handle various SYNC-type writes */ 891 /* Handle various SYNC-type writes */
905 if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { 892 if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
906 /* 893 error = xfs_write_sync_logforce(mp, xip);
907 * If we're treating this as O_DSYNC and we have not updated the 894 if (error)
908 * size, force the log. 895 goto out_unlock_internal;
909 */
910 if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
911 !(xip->i_update_size)) {
912 xfs_inode_log_item_t *iip = xip->i_itemp;
913
914 /*
915 * If an allocation transaction occurred
916 * without extending the size, then we have to force
917 * the log up the proper point to ensure that the
918 * allocation is permanent. We can't count on
919 * the fact that buffered writes lock out direct I/O
920 * writes - the direct I/O write could have extended
921 * the size nontransactionally, then finished before
922 * we started. xfs_write_file will think that the file
923 * didn't grow but the update isn't safe unless the
924 * size change is logged.
925 *
926 * Force the log if we've committed a transaction
927 * against the inode or if someone else has and
928 * the commit record hasn't gone to disk (e.g.
929 * the inode is pinned). This guarantees that
930 * all changes affecting the inode are permanent
931 * when we return.
932 */
933 if (iip && iip->ili_last_lsn) {
934 xfs_log_force(mp, iip->ili_last_lsn,
935 XFS_LOG_FORCE | XFS_LOG_SYNC);
936 } else if (xfs_ipincount(xip) > 0) {
937 xfs_log_force(mp, (xfs_lsn_t)0,
938 XFS_LOG_FORCE | XFS_LOG_SYNC);
939 }
940
941 } else {
942 xfs_trans_t *tp;
943
944 /*
945 * O_SYNC or O_DSYNC _with_ a size update are handled
946 * the same way.
947 *
948 * If the write was synchronous then we need to make
949 * sure that the inode modification time is permanent.
950 * We'll have updated the timestamp above, so here
951 * we use a synchronous transaction to log the inode.
952 * It's not fast, but it's necessary.
953 *
954 * If this a dsync write and the size got changed
955 * non-transactionally, then we need to ensure that
956 * the size change gets logged in a synchronous
957 * transaction.
958 */
959
960 tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
961 if ((error = xfs_trans_reserve(tp, 0,
962 XFS_SWRITE_LOG_RES(mp),
963 0, 0, 0))) {
964 /* Transaction reserve failed */
965 xfs_trans_cancel(tp, 0);
966 } else {
967 /* Transaction reserve successful */
968 xfs_ilock(xip, XFS_ILOCK_EXCL);
969 xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL);
970 xfs_trans_ihold(tp, xip);
971 xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE);
972 xfs_trans_set_sync(tp);
973 error = xfs_trans_commit(tp, 0, NULL);
974 xfs_iunlock(xip, XFS_ILOCK_EXCL);
975 }
976 if (error)
977 goto out_unlock_internal;
978 }
979 896
980 xfs_rwunlock(bdp, locktype); 897 xfs_rwunlock(bdp, locktype);
981 if (need_i_mutex) 898 if (need_i_mutex)
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 8f4539952350..c77e62efb742 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -18,8 +18,8 @@
18#ifndef __XFS_LRW_H__ 18#ifndef __XFS_LRW_H__
19#define __XFS_LRW_H__ 19#define __XFS_LRW_H__
20 20
21struct vnode;
22struct bhv_desc; 21struct bhv_desc;
22struct bhv_vnode;
23struct xfs_mount; 23struct xfs_mount;
24struct xfs_iocore; 24struct xfs_iocore;
25struct xfs_inode; 25struct xfs_inode;
@@ -49,7 +49,7 @@ struct xfs_iomap;
49#define XFS_CTRUNC4 14 49#define XFS_CTRUNC4 14
50#define XFS_CTRUNC5 15 50#define XFS_CTRUNC5 15
51#define XFS_CTRUNC6 16 51#define XFS_CTRUNC6 16
52#define XFS_BUNMAPI 17 52#define XFS_BUNMAP 17
53#define XFS_INVAL_CACHED 18 53#define XFS_INVAL_CACHED 18
54#define XFS_DIORD_ENTER 19 54#define XFS_DIORD_ENTER 19
55#define XFS_DIOWR_ENTER 20 55#define XFS_DIOWR_ENTER 20
@@ -82,7 +82,7 @@ extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
82extern int xfs_bdstrat_cb(struct xfs_buf *); 82extern int xfs_bdstrat_cb(struct xfs_buf *);
83extern int xfs_dev_is_read_only(struct xfs_mount *, char *); 83extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
84 84
85extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, 85extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t,
86 xfs_fsize_t, xfs_fsize_t); 86 xfs_fsize_t, xfs_fsize_t);
87extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, 87extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
88 const struct iovec *, unsigned int, 88 const struct iovec *, unsigned int,
diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c
index 1f0589a05eca..e480b6102051 100644
--- a/fs/xfs/linux-2.6/xfs_stats.c
+++ b/fs/xfs/linux-2.6/xfs_stats.c
@@ -62,7 +62,7 @@ xfs_read_xfsstats(
62 while (j < xstats[i].endpoint) { 62 while (j < xstats[i].endpoint) {
63 val = 0; 63 val = 0;
64 /* sum over all cpus */ 64 /* sum over all cpus */
65 for_each_cpu(c) 65 for_each_possible_cpu(c)
66 val += *(((__u32*)&per_cpu(xfsstats, c) + j)); 66 val += *(((__u32*)&per_cpu(xfsstats, c) + j));
67 len += sprintf(buffer + len, " %u", val); 67 len += sprintf(buffer + len, " %u", val);
68 j++; 68 j++;
@@ -70,7 +70,7 @@ xfs_read_xfsstats(
70 buffer[len++] = '\n'; 70 buffer[len++] = '\n';
71 } 71 }
72 /* extra precision counters */ 72 /* extra precision counters */
73 for_each_cpu(i) { 73 for_each_possible_cpu(i) {
74 xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes; 74 xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes;
75 xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes; 75 xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes;
76 xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes; 76 xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes;
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 68f4793e8a11..9bdef9d51900 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -151,7 +149,7 @@ xfs_set_inodeops(
151STATIC __inline__ void 149STATIC __inline__ void
152xfs_revalidate_inode( 150xfs_revalidate_inode(
153 xfs_mount_t *mp, 151 xfs_mount_t *mp,
154 vnode_t *vp, 152 bhv_vnode_t *vp,
155 xfs_inode_t *ip) 153 xfs_inode_t *ip)
156{ 154{
157 struct inode *inode = vn_to_inode(vp); 155 struct inode *inode = vn_to_inode(vp);
@@ -206,7 +204,7 @@ xfs_revalidate_inode(
206void 204void
207xfs_initialize_vnode( 205xfs_initialize_vnode(
208 bhv_desc_t *bdp, 206 bhv_desc_t *bdp,
209 vnode_t *vp, 207 bhv_vnode_t *vp,
210 bhv_desc_t *inode_bhv, 208 bhv_desc_t *inode_bhv,
211 int unlock) 209 int unlock)
212{ 210{
@@ -336,7 +334,7 @@ STATIC struct inode *
336xfs_fs_alloc_inode( 334xfs_fs_alloc_inode(
337 struct super_block *sb) 335 struct super_block *sb)
338{ 336{
339 vnode_t *vp; 337 bhv_vnode_t *vp;
340 338
341 vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP); 339 vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP);
342 if (unlikely(!vp)) 340 if (unlikely(!vp))
@@ -359,13 +357,13 @@ xfs_fs_inode_init_once(
359{ 357{
360 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == 358 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
361 SLAB_CTOR_CONSTRUCTOR) 359 SLAB_CTOR_CONSTRUCTOR)
362 inode_init_once(vn_to_inode((vnode_t *)vnode)); 360 inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
363} 361}
364 362
365STATIC int 363STATIC int
366xfs_init_zones(void) 364xfs_init_zones(void)
367{ 365{
368 xfs_vnode_zone = kmem_zone_init_flags(sizeof(vnode_t), "xfs_vnode_t", 366 xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode",
369 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | 367 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
370 KM_ZONE_SPREAD, 368 KM_ZONE_SPREAD,
371 xfs_fs_inode_init_once); 369 xfs_fs_inode_init_once);
@@ -409,22 +407,17 @@ xfs_fs_write_inode(
409 struct inode *inode, 407 struct inode *inode,
410 int sync) 408 int sync)
411{ 409{
412 vnode_t *vp = vn_from_inode(inode); 410 bhv_vnode_t *vp = vn_from_inode(inode);
413 int error = 0, flags = FLUSH_INODE; 411 int error = 0, flags = FLUSH_INODE;
414 412
415 if (vp) { 413 if (vp) {
416 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 414 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
417 if (sync) 415 if (sync)
418 flags |= FLUSH_SYNC; 416 flags |= FLUSH_SYNC;
419 VOP_IFLUSH(vp, flags, error); 417 error = bhv_vop_iflush(vp, flags);
420 if (error == EAGAIN) { 418 if (error == EAGAIN)
421 if (sync) 419 error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
422 VOP_IFLUSH(vp, flags | FLUSH_LOG, error);
423 else
424 error = 0;
425 }
426 } 420 }
427
428 return -error; 421 return -error;
429} 422}
430 423
@@ -432,8 +425,7 @@ STATIC void
432xfs_fs_clear_inode( 425xfs_fs_clear_inode(
433 struct inode *inode) 426 struct inode *inode)
434{ 427{
435 vnode_t *vp = vn_from_inode(inode); 428 bhv_vnode_t *vp = vn_from_inode(inode);
436 int error, cache;
437 429
438 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 430 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
439 431
@@ -446,20 +438,18 @@ xfs_fs_clear_inode(
446 * This can happen because xfs_iget_core calls xfs_idestroy if we 438 * This can happen because xfs_iget_core calls xfs_idestroy if we
447 * find an inode with di_mode == 0 but without IGET_CREATE set. 439 * find an inode with di_mode == 0 but without IGET_CREATE set.
448 */ 440 */
449 if (vp->v_fbhv) 441 if (VNHEAD(vp))
450 VOP_INACTIVE(vp, NULL, cache); 442 bhv_vop_inactive(vp, NULL);
451 443
452 VN_LOCK(vp); 444 VN_LOCK(vp);
453 vp->v_flag &= ~VMODIFIED; 445 vp->v_flag &= ~VMODIFIED;
454 VN_UNLOCK(vp, 0); 446 VN_UNLOCK(vp, 0);
455 447
456 if (vp->v_fbhv) { 448 if (VNHEAD(vp))
457 VOP_RECLAIM(vp, error); 449 if (bhv_vop_reclaim(vp))
458 if (error) 450 panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, vp);
459 panic("vn_purge: cannot reclaim");
460 }
461 451
462 ASSERT(vp->v_fbhv == NULL); 452 ASSERT(VNHEAD(vp) == NULL);
463 453
464#ifdef XFS_VNODE_TRACE 454#ifdef XFS_VNODE_TRACE
465 ktrace_free(vp->v_trace); 455 ktrace_free(vp->v_trace);
@@ -475,13 +465,13 @@ xfs_fs_clear_inode(
475 */ 465 */
476STATIC void 466STATIC void
477xfs_syncd_queue_work( 467xfs_syncd_queue_work(
478 struct vfs *vfs, 468 struct bhv_vfs *vfs,
479 void *data, 469 void *data,
480 void (*syncer)(vfs_t *, void *)) 470 void (*syncer)(bhv_vfs_t *, void *))
481{ 471{
482 vfs_sync_work_t *work; 472 struct bhv_vfs_sync_work *work;
483 473
484 work = kmem_alloc(sizeof(struct vfs_sync_work), KM_SLEEP); 474 work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP);
485 INIT_LIST_HEAD(&work->w_list); 475 INIT_LIST_HEAD(&work->w_list);
486 work->w_syncer = syncer; 476 work->w_syncer = syncer;
487 work->w_data = data; 477 work->w_data = data;
@@ -500,7 +490,7 @@ xfs_syncd_queue_work(
500 */ 490 */
501STATIC void 491STATIC void
502xfs_flush_inode_work( 492xfs_flush_inode_work(
503 vfs_t *vfs, 493 bhv_vfs_t *vfs,
504 void *inode) 494 void *inode)
505{ 495{
506 filemap_flush(((struct inode *)inode)->i_mapping); 496 filemap_flush(((struct inode *)inode)->i_mapping);
@@ -512,7 +502,7 @@ xfs_flush_inode(
512 xfs_inode_t *ip) 502 xfs_inode_t *ip)
513{ 503{
514 struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 504 struct inode *inode = vn_to_inode(XFS_ITOV(ip));
515 struct vfs *vfs = XFS_MTOVFS(ip->i_mount); 505 struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
516 506
517 igrab(inode); 507 igrab(inode);
518 xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work); 508 xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work);
@@ -525,7 +515,7 @@ xfs_flush_inode(
525 */ 515 */
526STATIC void 516STATIC void
527xfs_flush_device_work( 517xfs_flush_device_work(
528 vfs_t *vfs, 518 bhv_vfs_t *vfs,
529 void *inode) 519 void *inode)
530{ 520{
531 sync_blockdev(vfs->vfs_super->s_bdev); 521 sync_blockdev(vfs->vfs_super->s_bdev);
@@ -537,7 +527,7 @@ xfs_flush_device(
537 xfs_inode_t *ip) 527 xfs_inode_t *ip)
538{ 528{
539 struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 529 struct inode *inode = vn_to_inode(XFS_ITOV(ip));
540 struct vfs *vfs = XFS_MTOVFS(ip->i_mount); 530 struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
541 531
542 igrab(inode); 532 igrab(inode);
543 xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work); 533 xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work);
@@ -545,16 +535,16 @@ xfs_flush_device(
545 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); 535 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
546} 536}
547 537
548#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE)
549STATIC void 538STATIC void
550vfs_sync_worker( 539vfs_sync_worker(
551 vfs_t *vfsp, 540 bhv_vfs_t *vfsp,
552 void *unused) 541 void *unused)
553{ 542{
554 int error; 543 int error;
555 544
556 if (!(vfsp->vfs_flag & VFS_RDONLY)) 545 if (!(vfsp->vfs_flag & VFS_RDONLY))
557 VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error); 546 error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \
547 SYNC_ATTR | SYNC_REFCACHE, NULL);
558 vfsp->vfs_sync_seq++; 548 vfsp->vfs_sync_seq++;
559 wmb(); 549 wmb();
560 wake_up(&vfsp->vfs_wait_single_sync_task); 550 wake_up(&vfsp->vfs_wait_single_sync_task);
@@ -565,8 +555,8 @@ xfssyncd(
565 void *arg) 555 void *arg)
566{ 556{
567 long timeleft; 557 long timeleft;
568 vfs_t *vfsp = (vfs_t *) arg; 558 bhv_vfs_t *vfsp = (bhv_vfs_t *) arg;
569 struct vfs_sync_work *work, *n; 559 bhv_vfs_sync_work_t *work, *n;
570 LIST_HEAD (tmp); 560 LIST_HEAD (tmp);
571 561
572 timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10); 562 timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
@@ -600,7 +590,7 @@ xfssyncd(
600 list_del(&work->w_list); 590 list_del(&work->w_list);
601 if (work == &vfsp->vfs_sync_work) 591 if (work == &vfsp->vfs_sync_work)
602 continue; 592 continue;
603 kmem_free(work, sizeof(struct vfs_sync_work)); 593 kmem_free(work, sizeof(struct bhv_vfs_sync_work));
604 } 594 }
605 } 595 }
606 596
@@ -609,7 +599,7 @@ xfssyncd(
609 599
610STATIC int 600STATIC int
611xfs_fs_start_syncd( 601xfs_fs_start_syncd(
612 vfs_t *vfsp) 602 bhv_vfs_t *vfsp)
613{ 603{
614 vfsp->vfs_sync_work.w_syncer = vfs_sync_worker; 604 vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
615 vfsp->vfs_sync_work.w_vfs = vfsp; 605 vfsp->vfs_sync_work.w_vfs = vfsp;
@@ -621,7 +611,7 @@ xfs_fs_start_syncd(
621 611
622STATIC void 612STATIC void
623xfs_fs_stop_syncd( 613xfs_fs_stop_syncd(
624 vfs_t *vfsp) 614 bhv_vfs_t *vfsp)
625{ 615{
626 kthread_stop(vfsp->vfs_sync_task); 616 kthread_stop(vfsp->vfs_sync_task);
627} 617}
@@ -630,35 +620,26 @@ STATIC void
630xfs_fs_put_super( 620xfs_fs_put_super(
631 struct super_block *sb) 621 struct super_block *sb)
632{ 622{
633 vfs_t *vfsp = vfs_from_sb(sb); 623 bhv_vfs_t *vfsp = vfs_from_sb(sb);
634 int error; 624 int error;
635 625
636 xfs_fs_stop_syncd(vfsp); 626 xfs_fs_stop_syncd(vfsp);
637 VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error); 627 bhv_vfs_sync(vfsp, SYNC_ATTR | SYNC_DELWRI, NULL);
638 if (!error) 628 error = bhv_vfs_unmount(vfsp, 0, NULL);
639 VFS_UNMOUNT(vfsp, 0, NULL, error);
640 if (error) { 629 if (error) {
641 printk("XFS unmount got error %d\n", error); 630 printk("XFS: unmount got error=%d\n", error);
642 printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp); 631 printk("%s: vfs=0x%p left dangling!\n", __FUNCTION__, vfsp);
643 return; 632 } else {
633 vfs_deallocate(vfsp);
644 } 634 }
645
646 vfs_deallocate(vfsp);
647} 635}
648 636
649STATIC void 637STATIC void
650xfs_fs_write_super( 638xfs_fs_write_super(
651 struct super_block *sb) 639 struct super_block *sb)
652{ 640{
653 vfs_t *vfsp = vfs_from_sb(sb); 641 if (!(sb->s_flags & MS_RDONLY))
654 int error; 642 bhv_vfs_sync(vfs_from_sb(sb), SYNC_FSDATA, NULL);
655
656 if (sb->s_flags & MS_RDONLY) {
657 sb->s_dirt = 0; /* paranoia */
658 return;
659 }
660 /* Push the log and superblock a little */
661 VFS_SYNC(vfsp, SYNC_FSDATA, NULL, error);
662 sb->s_dirt = 0; 643 sb->s_dirt = 0;
663} 644}
664 645
@@ -667,16 +648,16 @@ xfs_fs_sync_super(
667 struct super_block *sb, 648 struct super_block *sb,
668 int wait) 649 int wait)
669{ 650{
670 vfs_t *vfsp = vfs_from_sb(sb); 651 bhv_vfs_t *vfsp = vfs_from_sb(sb);
671 int error; 652 int error;
672 int flags = SYNC_FSDATA; 653 int flags;
673 654
674 if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) 655 if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
675 flags = SYNC_QUIESCE; 656 flags = SYNC_QUIESCE;
676 else 657 else
677 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); 658 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
678 659
679 VFS_SYNC(vfsp, flags, NULL, error); 660 error = bhv_vfs_sync(vfsp, flags, NULL);
680 sb->s_dirt = 0; 661 sb->s_dirt = 0;
681 662
682 if (unlikely(laptop_mode)) { 663 if (unlikely(laptop_mode)) {
@@ -703,14 +684,11 @@ xfs_fs_sync_super(
703 684
704STATIC int 685STATIC int
705xfs_fs_statfs( 686xfs_fs_statfs(
706 struct super_block *sb, 687 struct dentry *dentry,
707 struct kstatfs *statp) 688 struct kstatfs *statp)
708{ 689{
709 vfs_t *vfsp = vfs_from_sb(sb); 690 return -bhv_vfs_statvfs(vfs_from_sb(dentry->d_sb), statp,
710 int error; 691 vn_from_inode(dentry->d_inode));
711
712 VFS_STATVFS(vfsp, statp, NULL, error);
713 return -error;
714} 692}
715 693
716STATIC int 694STATIC int
@@ -719,13 +697,13 @@ xfs_fs_remount(
719 int *flags, 697 int *flags,
720 char *options) 698 char *options)
721{ 699{
722 vfs_t *vfsp = vfs_from_sb(sb); 700 bhv_vfs_t *vfsp = vfs_from_sb(sb);
723 struct xfs_mount_args *args = xfs_args_allocate(sb, 0); 701 struct xfs_mount_args *args = xfs_args_allocate(sb, 0);
724 int error; 702 int error;
725 703
726 VFS_PARSEARGS(vfsp, options, args, 1, error); 704 error = bhv_vfs_parseargs(vfsp, options, args, 1);
727 if (!error) 705 if (!error)
728 VFS_MNTUPDATE(vfsp, flags, args, error); 706 error = bhv_vfs_mntupdate(vfsp, flags, args);
729 kmem_free(args, sizeof(*args)); 707 kmem_free(args, sizeof(*args));
730 return -error; 708 return -error;
731} 709}
@@ -734,7 +712,7 @@ STATIC void
734xfs_fs_lockfs( 712xfs_fs_lockfs(
735 struct super_block *sb) 713 struct super_block *sb)
736{ 714{
737 VFS_FREEZE(vfs_from_sb(sb)); 715 bhv_vfs_freeze(vfs_from_sb(sb));
738} 716}
739 717
740STATIC int 718STATIC int
@@ -742,11 +720,7 @@ xfs_fs_show_options(
742 struct seq_file *m, 720 struct seq_file *m,
743 struct vfsmount *mnt) 721 struct vfsmount *mnt)
744{ 722{
745 struct vfs *vfsp = vfs_from_sb(mnt->mnt_sb); 723 return -bhv_vfs_showargs(vfs_from_sb(mnt->mnt_sb), m);
746 int error;
747
748 VFS_SHOWARGS(vfsp, m, error);
749 return error;
750} 724}
751 725
752STATIC int 726STATIC int
@@ -754,11 +728,7 @@ xfs_fs_quotasync(
754 struct super_block *sb, 728 struct super_block *sb,
755 int type) 729 int type)
756{ 730{
757 struct vfs *vfsp = vfs_from_sb(sb); 731 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL);
758 int error;
759
760 VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error);
761 return -error;
762} 732}
763 733
764STATIC int 734STATIC int
@@ -766,11 +736,7 @@ xfs_fs_getxstate(
766 struct super_block *sb, 736 struct super_block *sb,
767 struct fs_quota_stat *fqs) 737 struct fs_quota_stat *fqs)
768{ 738{
769 struct vfs *vfsp = vfs_from_sb(sb); 739 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
770 int error;
771
772 VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
773 return -error;
774} 740}
775 741
776STATIC int 742STATIC int
@@ -779,11 +745,7 @@ xfs_fs_setxstate(
779 unsigned int flags, 745 unsigned int flags,
780 int op) 746 int op)
781{ 747{
782 struct vfs *vfsp = vfs_from_sb(sb); 748 return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags);
783 int error;
784
785 VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
786 return -error;
787} 749}
788 750
789STATIC int 751STATIC int
@@ -793,13 +755,10 @@ xfs_fs_getxquota(
793 qid_t id, 755 qid_t id,
794 struct fs_disk_quota *fdq) 756 struct fs_disk_quota *fdq)
795{ 757{
796 struct vfs *vfsp = vfs_from_sb(sb); 758 return -bhv_vfs_quotactl(vfs_from_sb(sb),
797 int error, getmode; 759 (type == USRQUOTA) ? Q_XGETQUOTA :
798 760 ((type == GRPQUOTA) ? Q_XGETGQUOTA :
799 getmode = (type == USRQUOTA) ? Q_XGETQUOTA : 761 Q_XGETPQUOTA), id, (caddr_t)fdq);
800 ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
801 VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
802 return -error;
803} 762}
804 763
805STATIC int 764STATIC int
@@ -809,13 +768,10 @@ xfs_fs_setxquota(
809 qid_t id, 768 qid_t id,
810 struct fs_disk_quota *fdq) 769 struct fs_disk_quota *fdq)
811{ 770{
812 struct vfs *vfsp = vfs_from_sb(sb); 771 return -bhv_vfs_quotactl(vfs_from_sb(sb),
813 int error, setmode; 772 (type == USRQUOTA) ? Q_XSETQLIM :
814 773 ((type == GRPQUOTA) ? Q_XSETGQLIM :
815 setmode = (type == USRQUOTA) ? Q_XSETQLIM : 774 Q_XSETPQLIM), id, (caddr_t)fdq);
816 ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
817 VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
818 return -error;
819} 775}
820 776
821STATIC int 777STATIC int
@@ -824,34 +780,32 @@ xfs_fs_fill_super(
824 void *data, 780 void *data,
825 int silent) 781 int silent)
826{ 782{
827 vnode_t *rootvp; 783 struct bhv_vnode *rootvp;
828 struct vfs *vfsp = vfs_allocate(sb); 784 struct bhv_vfs *vfsp = vfs_allocate(sb);
829 struct xfs_mount_args *args = xfs_args_allocate(sb, silent); 785 struct xfs_mount_args *args = xfs_args_allocate(sb, silent);
830 struct kstatfs statvfs; 786 struct kstatfs statvfs;
831 int error, error2; 787 int error;
832 788
833 bhv_insert_all_vfsops(vfsp); 789 bhv_insert_all_vfsops(vfsp);
834 790
835 VFS_PARSEARGS(vfsp, (char *)data, args, 0, error); 791 error = bhv_vfs_parseargs(vfsp, (char *)data, args, 0);
836 if (error) { 792 if (error) {
837 bhv_remove_all_vfsops(vfsp, 1); 793 bhv_remove_all_vfsops(vfsp, 1);
838 goto fail_vfsop; 794 goto fail_vfsop;
839 } 795 }
840 796
841 sb_min_blocksize(sb, BBSIZE); 797 sb_min_blocksize(sb, BBSIZE);
842#ifdef CONFIG_XFS_EXPORT
843 sb->s_export_op = &xfs_export_operations; 798 sb->s_export_op = &xfs_export_operations;
844#endif
845 sb->s_qcop = &xfs_quotactl_operations; 799 sb->s_qcop = &xfs_quotactl_operations;
846 sb->s_op = &xfs_super_operations; 800 sb->s_op = &xfs_super_operations;
847 801
848 VFS_MOUNT(vfsp, args, NULL, error); 802 error = bhv_vfs_mount(vfsp, args, NULL);
849 if (error) { 803 if (error) {
850 bhv_remove_all_vfsops(vfsp, 1); 804 bhv_remove_all_vfsops(vfsp, 1);
851 goto fail_vfsop; 805 goto fail_vfsop;
852 } 806 }
853 807
854 VFS_STATVFS(vfsp, &statvfs, NULL, error); 808 error = bhv_vfs_statvfs(vfsp, &statvfs, NULL);
855 if (error) 809 if (error)
856 goto fail_unmount; 810 goto fail_unmount;
857 811
@@ -863,7 +817,7 @@ xfs_fs_fill_super(
863 sb->s_time_gran = 1; 817 sb->s_time_gran = 1;
864 set_posix_acl_flag(sb); 818 set_posix_acl_flag(sb);
865 819
866 VFS_ROOT(vfsp, &rootvp, error); 820 error = bhv_vfs_root(vfsp, &rootvp);
867 if (error) 821 if (error)
868 goto fail_unmount; 822 goto fail_unmount;
869 823
@@ -892,7 +846,7 @@ fail_vnrele:
892 } 846 }
893 847
894fail_unmount: 848fail_unmount:
895 VFS_UNMOUNT(vfsp, 0, NULL, error2); 849 bhv_vfs_unmount(vfsp, 0, NULL);
896 850
897fail_vfsop: 851fail_vfsop:
898 vfs_deallocate(vfsp); 852 vfs_deallocate(vfsp);
@@ -900,14 +854,16 @@ fail_vfsop:
900 return -error; 854 return -error;
901} 855}
902 856
903STATIC struct super_block * 857STATIC int
904xfs_fs_get_sb( 858xfs_fs_get_sb(
905 struct file_system_type *fs_type, 859 struct file_system_type *fs_type,
906 int flags, 860 int flags,
907 const char *dev_name, 861 const char *dev_name,
908 void *data) 862 void *data,
863 struct vfsmount *mnt)
909{ 864{
910 return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); 865 return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super,
866 mnt);
911} 867}
912 868
913STATIC struct super_operations xfs_super_operations = { 869STATIC struct super_operations xfs_super_operations = {
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index 376b96cb513a..33dd1ca13245 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -105,7 +105,7 @@ struct block_device;
105 105
106extern __uint64_t xfs_max_file_offset(unsigned int); 106extern __uint64_t xfs_max_file_offset(unsigned int);
107 107
108extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int); 108extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int);
109 109
110extern void xfs_flush_inode(struct xfs_inode *); 110extern void xfs_flush_inode(struct xfs_inode *);
111extern void xfs_flush_device(struct xfs_inode *); 111extern void xfs_flush_device(struct xfs_inode *);
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c
index 7079cc837210..af246532fbfb 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.c
+++ b/fs/xfs/linux-2.6/xfs_sysctl.c
@@ -38,7 +38,7 @@ xfs_stats_clear_proc_handler(
38 38
39 if (!ret && write && *valp) { 39 if (!ret && write && *valp) {
40 printk("XFS Clearing xfsstats\n"); 40 printk("XFS Clearing xfsstats\n");
41 for_each_cpu(c) { 41 for_each_possible_cpu(c) {
42 preempt_disable(); 42 preempt_disable();
43 /* save vn_active, it's a universal truth! */ 43 /* save vn_active, it's a universal truth! */
44 vn_active = per_cpu(xfsstats, c).vn_active; 44 vn_active = per_cpu(xfsstats, c).vn_active;
@@ -120,6 +120,11 @@ STATIC ctl_table xfs_table[] = {
120 &sysctl_intvec, NULL, 120 &sysctl_intvec, NULL,
121 &xfs_params.rotorstep.min, &xfs_params.rotorstep.max}, 121 &xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
122 122
123 {XFS_INHERIT_NODFRG, "inherit_nodefrag", &xfs_params.inherit_nodfrg.val,
124 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
125 &sysctl_intvec, NULL,
126 &xfs_params.inherit_nodfrg.min, &xfs_params.inherit_nodfrg.max},
127
123 /* please keep this the last entry */ 128 /* please keep this the last entry */
124#ifdef CONFIG_PROC_FS 129#ifdef CONFIG_PROC_FS
125 {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val, 130 {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.h b/fs/xfs/linux-2.6/xfs_sysctl.h
index bc8c11f13722..a631fb8cc5ac 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.h
+++ b/fs/xfs/linux-2.6/xfs_sysctl.h
@@ -46,6 +46,7 @@ typedef struct xfs_param {
46 xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */ 46 xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */
47 xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */ 47 xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */
48 xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ 48 xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
49 xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
49} xfs_param_t; 50} xfs_param_t;
50 51
51/* 52/*
@@ -84,6 +85,7 @@ enum {
84 /* XFS_IO_BYPASS = 18 */ 85 /* XFS_IO_BYPASS = 18 */
85 XFS_INHERIT_NOSYM = 19, 86 XFS_INHERIT_NOSYM = 19,
86 XFS_ROTORSTEP = 20, 87 XFS_ROTORSTEP = 20,
88 XFS_INHERIT_NODFRG = 21,
87}; 89};
88 90
89extern xfs_param_t xfs_params; 91extern xfs_param_t xfs_params;
diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c
index 6f7c9f7a8624..6145e8bd0be2 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.c
+++ b/fs/xfs/linux-2.6/xfs_vfs.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_imap.h" 27#include "xfs_imap.h"
29#include "xfs_alloc.h" 28#include "xfs_alloc.h"
@@ -104,7 +103,7 @@ vfs_mntupdate(
104int 103int
105vfs_root( 104vfs_root(
106 struct bhv_desc *bdp, 105 struct bhv_desc *bdp,
107 struct vnode **vpp) 106 struct bhv_vnode **vpp)
108{ 107{
109 struct bhv_desc *next = bdp; 108 struct bhv_desc *next = bdp;
110 109
@@ -117,15 +116,15 @@ vfs_root(
117int 116int
118vfs_statvfs( 117vfs_statvfs(
119 struct bhv_desc *bdp, 118 struct bhv_desc *bdp,
120 xfs_statfs_t *sp, 119 bhv_statvfs_t *statp,
121 struct vnode *vp) 120 struct bhv_vnode *vp)
122{ 121{
123 struct bhv_desc *next = bdp; 122 struct bhv_desc *next = bdp;
124 123
125 ASSERT(next); 124 ASSERT(next);
126 while (! (bhvtovfsops(next))->vfs_statvfs) 125 while (! (bhvtovfsops(next))->vfs_statvfs)
127 next = BHV_NEXT(next); 126 next = BHV_NEXT(next);
128 return ((*bhvtovfsops(next)->vfs_statvfs)(next, sp, vp)); 127 return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp));
129} 128}
130 129
131int 130int
@@ -145,7 +144,7 @@ vfs_sync(
145int 144int
146vfs_vget( 145vfs_vget(
147 struct bhv_desc *bdp, 146 struct bhv_desc *bdp,
148 struct vnode **vpp, 147 struct bhv_vnode **vpp,
149 struct fid *fidp) 148 struct fid *fidp)
150{ 149{
151 struct bhv_desc *next = bdp; 150 struct bhv_desc *next = bdp;
@@ -187,7 +186,7 @@ vfs_quotactl(
187void 186void
188vfs_init_vnode( 187vfs_init_vnode(
189 struct bhv_desc *bdp, 188 struct bhv_desc *bdp,
190 struct vnode *vp, 189 struct bhv_vnode *vp,
191 struct bhv_desc *bp, 190 struct bhv_desc *bp,
192 int unlock) 191 int unlock)
193{ 192{
@@ -226,13 +225,13 @@ vfs_freeze(
226 ((*bhvtovfsops(next)->vfs_freeze)(next)); 225 ((*bhvtovfsops(next)->vfs_freeze)(next));
227} 226}
228 227
229vfs_t * 228bhv_vfs_t *
230vfs_allocate( 229vfs_allocate(
231 struct super_block *sb) 230 struct super_block *sb)
232{ 231{
233 struct vfs *vfsp; 232 struct bhv_vfs *vfsp;
234 233
235 vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP); 234 vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP);
236 bhv_head_init(VFS_BHVHEAD(vfsp), "vfs"); 235 bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
237 INIT_LIST_HEAD(&vfsp->vfs_sync_list); 236 INIT_LIST_HEAD(&vfsp->vfs_sync_list);
238 spin_lock_init(&vfsp->vfs_sync_lock); 237 spin_lock_init(&vfsp->vfs_sync_lock);
@@ -247,25 +246,25 @@ vfs_allocate(
247 return vfsp; 246 return vfsp;
248} 247}
249 248
250vfs_t * 249bhv_vfs_t *
251vfs_from_sb( 250vfs_from_sb(
252 struct super_block *sb) 251 struct super_block *sb)
253{ 252{
254 return (vfs_t *)sb->s_fs_info; 253 return (bhv_vfs_t *)sb->s_fs_info;
255} 254}
256 255
257void 256void
258vfs_deallocate( 257vfs_deallocate(
259 struct vfs *vfsp) 258 struct bhv_vfs *vfsp)
260{ 259{
261 bhv_head_destroy(VFS_BHVHEAD(vfsp)); 260 bhv_head_destroy(VFS_BHVHEAD(vfsp));
262 kmem_free(vfsp, sizeof(vfs_t)); 261 kmem_free(vfsp, sizeof(bhv_vfs_t));
263} 262}
264 263
265void 264void
266vfs_insertops( 265vfs_insertops(
267 struct vfs *vfsp, 266 struct bhv_vfs *vfsp,
268 struct bhv_vfsops *vfsops) 267 struct bhv_module_vfsops *vfsops)
269{ 268{
270 struct bhv_desc *bdp; 269 struct bhv_desc *bdp;
271 270
@@ -276,9 +275,9 @@ vfs_insertops(
276 275
277void 276void
278vfs_insertbhv( 277vfs_insertbhv(
279 struct vfs *vfsp, 278 struct bhv_vfs *vfsp,
280 struct bhv_desc *bdp, 279 struct bhv_desc *bdp,
281 struct vfsops *vfsops, 280 struct bhv_vfsops *vfsops,
282 void *mount) 281 void *mount)
283{ 282{
284 bhv_desc_init(bdp, mount, vfsp, vfsops); 283 bhv_desc_init(bdp, mount, vfsp, vfsops);
@@ -287,7 +286,7 @@ vfs_insertbhv(
287 286
288void 287void
289bhv_remove_vfsops( 288bhv_remove_vfsops(
290 struct vfs *vfsp, 289 struct bhv_vfs *vfsp,
291 int pos) 290 int pos)
292{ 291{
293 struct bhv_desc *bhv; 292 struct bhv_desc *bhv;
@@ -301,7 +300,7 @@ bhv_remove_vfsops(
301 300
302void 301void
303bhv_remove_all_vfsops( 302bhv_remove_all_vfsops(
304 struct vfs *vfsp, 303 struct bhv_vfs *vfsp,
305 int freebase) 304 int freebase)
306{ 305{
307 struct xfs_mount *mp; 306 struct xfs_mount *mp;
@@ -317,7 +316,7 @@ bhv_remove_all_vfsops(
317 316
318void 317void
319bhv_insert_all_vfsops( 318bhv_insert_all_vfsops(
320 struct vfs *vfsp) 319 struct bhv_vfs *vfsp)
321{ 320{
322 struct xfs_mount *mp; 321 struct xfs_mount *mp;
323 322
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index 841200c03092..91fc2c4b3353 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -21,42 +21,40 @@
21#include <linux/vfs.h> 21#include <linux/vfs.h>
22#include "xfs_fs.h" 22#include "xfs_fs.h"
23 23
24struct bhv_vfs;
25struct bhv_vnode;
26
24struct fid; 27struct fid;
25struct vfs;
26struct cred; 28struct cred;
27struct vnode;
28struct kstatfs;
29struct seq_file; 29struct seq_file;
30struct super_block; 30struct super_block;
31struct xfs_mount_args; 31struct xfs_mount_args;
32 32
33typedef struct kstatfs xfs_statfs_t; 33typedef struct kstatfs bhv_statvfs_t;
34 34
35typedef struct vfs_sync_work { 35typedef struct bhv_vfs_sync_work {
36 struct list_head w_list; 36 struct list_head w_list;
37 struct vfs *w_vfs; 37 struct bhv_vfs *w_vfs;
38 void *w_data; /* syncer routine argument */ 38 void *w_data; /* syncer routine argument */
39 void (*w_syncer)(struct vfs *, void *); 39 void (*w_syncer)(struct bhv_vfs *, void *);
40} vfs_sync_work_t; 40} bhv_vfs_sync_work_t;
41 41
42typedef struct vfs { 42typedef struct bhv_vfs {
43 u_int vfs_flag; /* flags */ 43 u_int vfs_flag; /* flags */
44 xfs_fsid_t vfs_fsid; /* file system ID */ 44 xfs_fsid_t vfs_fsid; /* file system ID */
45 xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */ 45 xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
46 bhv_head_t vfs_bh; /* head of vfs behavior chain */ 46 bhv_head_t vfs_bh; /* head of vfs behavior chain */
47 struct super_block *vfs_super; /* generic superblock pointer */ 47 struct super_block *vfs_super; /* generic superblock pointer */
48 struct task_struct *vfs_sync_task; /* generalised sync thread */ 48 struct task_struct *vfs_sync_task; /* generalised sync thread */
49 vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */ 49 bhv_vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */
50 struct list_head vfs_sync_list; /* sync thread work item list */ 50 struct list_head vfs_sync_list; /* sync thread work item list */
51 spinlock_t vfs_sync_lock; /* work item list lock */ 51 spinlock_t vfs_sync_lock; /* work item list lock */
52 int vfs_sync_seq; /* sync thread generation no. */ 52 int vfs_sync_seq; /* sync thread generation no. */
53 wait_queue_head_t vfs_wait_single_sync_task; 53 wait_queue_head_t vfs_wait_single_sync_task;
54} vfs_t; 54} bhv_vfs_t;
55
56#define vfs_fbhv vfs_bh.bh_first /* 1st on vfs behavior chain */
57 55
58#define bhvtovfs(bdp) ( (struct vfs *)BHV_VOBJ(bdp) ) 56#define bhvtovfs(bdp) ( (struct bhv_vfs *)BHV_VOBJ(bdp) )
59#define bhvtovfsops(bdp) ( (struct vfsops *)BHV_OPS(bdp) ) 57#define bhvtovfsops(bdp) ( (struct bhv_vfsops *)BHV_OPS(bdp) )
60#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh ) 58#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
61#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) ) 59#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
62 60
@@ -71,7 +69,7 @@ typedef enum {
71 VFS_BHV_QM, /* quota manager */ 69 VFS_BHV_QM, /* quota manager */
72 VFS_BHV_IO, /* IO path */ 70 VFS_BHV_IO, /* IO path */
73 VFS_BHV_END /* housekeeping end-of-range */ 71 VFS_BHV_END /* housekeeping end-of-range */
74} vfs_bhv_t; 72} bhv_vfs_type_t;
75 73
76#define VFS_POSITION_XFS (BHV_POSITION_BASE) 74#define VFS_POSITION_XFS (BHV_POSITION_BASE)
77#define VFS_POSITION_DM (VFS_POSITION_BASE+10) 75#define VFS_POSITION_DM (VFS_POSITION_BASE+10)
@@ -81,8 +79,9 @@ typedef enum {
81#define VFS_RDONLY 0x0001 /* read-only vfs */ 79#define VFS_RDONLY 0x0001 /* read-only vfs */
82#define VFS_GRPID 0x0002 /* group-ID assigned from directory */ 80#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
83#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */ 81#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
84#define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */ 82#define VFS_UMOUNT 0x0008 /* unmount in progress */
85#define VFS_END 0x0008 /* max flag */ 83#define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */
84#define VFS_END 0x0010 /* max flag */
86 85
87#define SYNC_ATTR 0x0001 /* sync attributes */ 86#define SYNC_ATTR 0x0001 /* sync attributes */
88#define SYNC_CLOSE 0x0002 /* close file system down */ 87#define SYNC_CLOSE 0x0002 /* close file system down */
@@ -92,7 +91,14 @@ typedef enum {
92#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ 91#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
93#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ 92#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
94#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ 93#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
95#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */ 94#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */
95
96#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */
97#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */
98#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */
99#define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */
100#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */
101#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */
96 102
97typedef int (*vfs_mount_t)(bhv_desc_t *, 103typedef int (*vfs_mount_t)(bhv_desc_t *,
98 struct xfs_mount_args *, struct cred *); 104 struct xfs_mount_args *, struct cred *);
@@ -102,18 +108,19 @@ typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
102typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *); 108typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
103typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *, 109typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
104 struct xfs_mount_args *); 110 struct xfs_mount_args *);
105typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **); 111typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **);
106typedef int (*vfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct vnode *); 112typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *,
113 struct bhv_vnode *);
107typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); 114typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
108typedef int (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *); 115typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *);
109typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t); 116typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
110typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); 117typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
111typedef void (*vfs_init_vnode_t)(bhv_desc_t *, 118typedef void (*vfs_init_vnode_t)(bhv_desc_t *,
112 struct vnode *, bhv_desc_t *, int); 119 struct bhv_vnode *, bhv_desc_t *, int);
113typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); 120typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
114typedef void (*vfs_freeze_t)(bhv_desc_t *); 121typedef void (*vfs_freeze_t)(bhv_desc_t *);
115 122
116typedef struct vfsops { 123typedef struct bhv_vfsops {
117 bhv_position_t vf_position; /* behavior chain position */ 124 bhv_position_t vf_position; /* behavior chain position */
118 vfs_mount_t vfs_mount; /* mount file system */ 125 vfs_mount_t vfs_mount; /* mount file system */
119 vfs_parseargs_t vfs_parseargs; /* parse mount options */ 126 vfs_parseargs_t vfs_parseargs; /* parse mount options */
@@ -129,82 +136,82 @@ typedef struct vfsops {
129 vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */ 136 vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
130 vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */ 137 vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
131 vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */ 138 vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */
132} vfsops_t; 139} bhv_vfsops_t;
133 140
134/* 141/*
135 * VFS's. Operates on vfs structure pointers (starts at bhv head). 142 * Virtual filesystem operations, operating from head bhv.
136 */ 143 */
137#define VHEAD(v) ((v)->vfs_fbhv) 144#define VFSHEAD(v) ((v)->vfs_bh.bh_first)
138#define VFS_MOUNT(v, ma,cr, rv) ((rv) = vfs_mount(VHEAD(v), ma,cr)) 145#define bhv_vfs_mount(v, ma,cr) vfs_mount(VFSHEAD(v), ma,cr)
139#define VFS_PARSEARGS(v, o,ma,f, rv) ((rv) = vfs_parseargs(VHEAD(v), o,ma,f)) 146#define bhv_vfs_parseargs(v, o,ma,f) vfs_parseargs(VFSHEAD(v), o,ma,f)
140#define VFS_SHOWARGS(v, m, rv) ((rv) = vfs_showargs(VHEAD(v), m)) 147#define bhv_vfs_showargs(v, m) vfs_showargs(VFSHEAD(v), m)
141#define VFS_UNMOUNT(v, f, cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr)) 148#define bhv_vfs_unmount(v, f,cr) vfs_unmount(VFSHEAD(v), f,cr)
142#define VFS_MNTUPDATE(v, fl, args, rv) ((rv) = vfs_mntupdate(VHEAD(v), fl, args)) 149#define bhv_vfs_mntupdate(v, fl,args) vfs_mntupdate(VFSHEAD(v), fl,args)
143#define VFS_ROOT(v, vpp, rv) ((rv) = vfs_root(VHEAD(v), vpp)) 150#define bhv_vfs_root(v, vpp) vfs_root(VFSHEAD(v), vpp)
144#define VFS_STATVFS(v, sp,vp, rv) ((rv) = vfs_statvfs(VHEAD(v), sp,vp)) 151#define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)
145#define VFS_SYNC(v, flag,cr, rv) ((rv) = vfs_sync(VHEAD(v), flag,cr)) 152#define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)
146#define VFS_VGET(v, vpp,fidp, rv) ((rv) = vfs_vget(VHEAD(v), vpp,fidp)) 153#define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp)
147#define VFS_DMAPIOPS(v, p, rv) ((rv) = vfs_dmapiops(VHEAD(v), p)) 154#define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p)
148#define VFS_QUOTACTL(v, c,id,p, rv) ((rv) = vfs_quotactl(VHEAD(v), c,id,p)) 155#define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)
149#define VFS_INIT_VNODE(v, vp,b,ul) ( vfs_init_vnode(VHEAD(v), vp,b,ul) ) 156#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
150#define VFS_FORCE_SHUTDOWN(v, fl,f,l) ( vfs_force_shutdown(VHEAD(v), fl,f,l) ) 157#define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
151#define VFS_FREEZE(v) ( vfs_freeze(VHEAD(v)) ) 158#define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v))
152 159
153/* 160/*
154 * PVFS's. Operates on behavior descriptor pointers. 161 * Virtual filesystem operations, operating from next bhv.
155 */ 162 */
156#define PVFS_MOUNT(b, ma,cr, rv) ((rv) = vfs_mount(b, ma,cr)) 163#define bhv_next_vfs_mount(b, ma,cr) vfs_mount(b, ma,cr)
157#define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = vfs_parseargs(b, o,ma,f)) 164#define bhv_next_vfs_parseargs(b, o,ma,f) vfs_parseargs(b, o,ma,f)
158#define PVFS_SHOWARGS(b, m, rv) ((rv) = vfs_showargs(b, m)) 165#define bhv_next_vfs_showargs(b, m) vfs_showargs(b, m)
159#define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = vfs_unmount(b, f,cr)) 166#define bhv_next_vfs_unmount(b, f,cr) vfs_unmount(b, f,cr)
160#define PVFS_MNTUPDATE(b, fl, args, rv) ((rv) = vfs_mntupdate(b, fl, args)) 167#define bhv_next_vfs_mntupdate(b, fl,args) vfs_mntupdate(b, fl, args)
161#define PVFS_ROOT(b, vpp, rv) ((rv) = vfs_root(b, vpp)) 168#define bhv_next_vfs_root(b, vpp) vfs_root(b, vpp)
162#define PVFS_STATVFS(b, sp,vp, rv) ((rv) = vfs_statvfs(b, sp,vp)) 169#define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp)
163#define PVFS_SYNC(b, flag,cr, rv) ((rv) = vfs_sync(b, flag,cr)) 170#define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr)
164#define PVFS_VGET(b, vpp,fidp, rv) ((rv) = vfs_vget(b, vpp,fidp)) 171#define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp)
165#define PVFS_DMAPIOPS(b, p, rv) ((rv) = vfs_dmapiops(b, p)) 172#define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p)
166#define PVFS_QUOTACTL(b, c,id,p, rv) ((rv) = vfs_quotactl(b, c,id,p)) 173#define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p)
167#define PVFS_INIT_VNODE(b, vp,b2,ul) ( vfs_init_vnode(b, vp,b2,ul) ) 174#define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul)
168#define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( vfs_force_shutdown(b, fl,f,l) ) 175#define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
169#define PVFS_FREEZE(b) ( vfs_freeze(b) ) 176#define bhv_next_vfs_freeze(b) vfs_freeze(b)
170 177
171extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *); 178extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
172extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int); 179extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
173extern int vfs_showargs(bhv_desc_t *, struct seq_file *); 180extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
174extern int vfs_unmount(bhv_desc_t *, int, struct cred *); 181extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
175extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *); 182extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
176extern int vfs_root(bhv_desc_t *, struct vnode **); 183extern int vfs_root(bhv_desc_t *, struct bhv_vnode **);
177extern int vfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct vnode *); 184extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *);
178extern int vfs_sync(bhv_desc_t *, int, struct cred *); 185extern int vfs_sync(bhv_desc_t *, int, struct cred *);
179extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *); 186extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *);
180extern int vfs_dmapiops(bhv_desc_t *, caddr_t); 187extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
181extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); 188extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
182extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int); 189extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int);
183extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); 190extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
184extern void vfs_freeze(bhv_desc_t *); 191extern void vfs_freeze(bhv_desc_t *);
185 192
186typedef struct bhv_vfsops { 193#define vfs_test_for_freeze(vfs) ((vfs)->vfs_super->s_frozen)
187 struct vfsops bhv_common; 194#define vfs_wait_for_freeze(vfs,l) vfs_check_frozen((vfs)->vfs_super, (l))
195
196typedef struct bhv_module_vfsops {
197 struct bhv_vfsops bhv_common;
188 void * bhv_custom; 198 void * bhv_custom;
189} bhv_vfsops_t; 199} bhv_module_vfsops_t;
190 200
191#define vfs_bhv_lookup(v, id) ( bhv_lookup_range(&(v)->vfs_bh, (id), (id)) ) 201#define vfs_bhv_lookup(v, id) (bhv_lookup_range(&(v)->vfs_bh, (id), (id)))
192#define vfs_bhv_custom(b) ( ((bhv_vfsops_t *)BHV_OPS(b))->bhv_custom ) 202#define vfs_bhv_custom(b) (((bhv_module_vfsops_t*)BHV_OPS(b))->bhv_custom)
193#define vfs_bhv_set_custom(b,o) ( (b)->bhv_custom = (void *)(o)) 203#define vfs_bhv_set_custom(b,o) ((b)->bhv_custom = (void *)(o))
194#define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL ) 204#define vfs_bhv_clr_custom(b) ((b)->bhv_custom = NULL)
195 205
196extern vfs_t *vfs_allocate(struct super_block *); 206extern bhv_vfs_t *vfs_allocate(struct super_block *);
197extern vfs_t *vfs_from_sb(struct super_block *); 207extern bhv_vfs_t *vfs_from_sb(struct super_block *);
198extern void vfs_deallocate(vfs_t *); 208extern void vfs_deallocate(bhv_vfs_t *);
199extern void vfs_insertops(vfs_t *, bhv_vfsops_t *); 209extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *);
200extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *);
201 210
202extern void bhv_insert_all_vfsops(struct vfs *); 211extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *);
203extern void bhv_remove_all_vfsops(struct vfs *, int);
204extern void bhv_remove_vfsops(struct vfs *, int);
205 212
206#define fs_frozen(vfsp) ((vfsp)->vfs_super->s_frozen) 213extern void bhv_insert_all_vfsops(struct bhv_vfs *);
207#define fs_check_frozen(vfsp, level) \ 214extern void bhv_remove_all_vfsops(struct bhv_vfs *, int);
208 vfs_check_frozen(vfsp->vfs_super, level); 215extern void bhv_remove_vfsops(struct bhv_vfs *, int);
209 216
210#endif /* __XFS_VFS_H__ */ 217#endif /* __XFS_VFS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index d27c25b27ccd..6628d96b6fd6 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -39,7 +39,7 @@ vn_init(void)
39 39
40void 40void
41vn_iowait( 41vn_iowait(
42 struct vnode *vp) 42 bhv_vnode_t *vp)
43{ 43{
44 wait_queue_head_t *wq = vptosync(vp); 44 wait_queue_head_t *wq = vptosync(vp);
45 45
@@ -48,17 +48,33 @@ vn_iowait(
48 48
49void 49void
50vn_iowake( 50vn_iowake(
51 struct vnode *vp) 51 bhv_vnode_t *vp)
52{ 52{
53 if (atomic_dec_and_test(&vp->v_iocount)) 53 if (atomic_dec_and_test(&vp->v_iocount))
54 wake_up(vptosync(vp)); 54 wake_up(vptosync(vp));
55} 55}
56 56
57struct vnode * 57/*
58 * Volume managers supporting multiple paths can send back ENODEV when the
59 * final path disappears. In this case continuing to fill the page cache
60 * with dirty data which cannot be written out is evil, so prevent that.
61 */
62void
63vn_ioerror(
64 bhv_vnode_t *vp,
65 int error,
66 char *f,
67 int l)
68{
69 if (unlikely(error == -ENODEV))
70 bhv_vfs_force_shutdown(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l);
71}
72
73bhv_vnode_t *
58vn_initialize( 74vn_initialize(
59 struct inode *inode) 75 struct inode *inode)
60{ 76{
61 struct vnode *vp = vn_from_inode(inode); 77 bhv_vnode_t *vp = vn_from_inode(inode);
62 78
63 XFS_STATS_INC(vn_active); 79 XFS_STATS_INC(vn_active);
64 XFS_STATS_INC(vn_alloc); 80 XFS_STATS_INC(vn_alloc);
@@ -94,8 +110,8 @@ vn_initialize(
94 */ 110 */
95void 111void
96vn_revalidate_core( 112vn_revalidate_core(
97 struct vnode *vp, 113 bhv_vnode_t *vp,
98 vattr_t *vap) 114 bhv_vattr_t *vap)
99{ 115{
100 struct inode *inode = vn_to_inode(vp); 116 struct inode *inode = vn_to_inode(vp);
101 117
@@ -130,14 +146,14 @@ vn_revalidate_core(
130 */ 146 */
131int 147int
132__vn_revalidate( 148__vn_revalidate(
133 struct vnode *vp, 149 bhv_vnode_t *vp,
134 struct vattr *vattr) 150 bhv_vattr_t *vattr)
135{ 151{
136 int error; 152 int error;
137 153
138 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 154 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
139 vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS; 155 vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS;
140 VOP_GETATTR(vp, vattr, 0, NULL, error); 156 error = bhv_vop_getattr(vp, vattr, 0, NULL);
141 if (likely(!error)) { 157 if (likely(!error)) {
142 vn_revalidate_core(vp, vattr); 158 vn_revalidate_core(vp, vattr);
143 VUNMODIFY(vp); 159 VUNMODIFY(vp);
@@ -147,9 +163,9 @@ __vn_revalidate(
147 163
148int 164int
149vn_revalidate( 165vn_revalidate(
150 struct vnode *vp) 166 bhv_vnode_t *vp)
151{ 167{
152 vattr_t vattr; 168 bhv_vattr_t vattr;
153 169
154 return __vn_revalidate(vp, &vattr); 170 return __vn_revalidate(vp, &vattr);
155} 171}
@@ -157,9 +173,9 @@ vn_revalidate(
157/* 173/*
158 * Add a reference to a referenced vnode. 174 * Add a reference to a referenced vnode.
159 */ 175 */
160struct vnode * 176bhv_vnode_t *
161vn_hold( 177vn_hold(
162 struct vnode *vp) 178 bhv_vnode_t *vp)
163{ 179{
164 struct inode *inode; 180 struct inode *inode;
165 181
@@ -192,31 +208,31 @@ vn_hold(
192 * Vnode tracing code. 208 * Vnode tracing code.
193 */ 209 */
194void 210void
195vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra) 211vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra)
196{ 212{
197 KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); 213 KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
198} 214}
199 215
200void 216void
201vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra) 217vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra)
202{ 218{
203 KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); 219 KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
204} 220}
205 221
206void 222void
207vn_trace_hold(vnode_t *vp, char *file, int line, inst_t *ra) 223vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
208{ 224{
209 KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra); 225 KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra);
210} 226}
211 227
212void 228void
213vn_trace_ref(vnode_t *vp, char *file, int line, inst_t *ra) 229vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
214{ 230{
215 KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra); 231 KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra);
216} 232}
217 233
218void 234void
219vn_trace_rele(vnode_t *vp, char *file, int line, inst_t *ra) 235vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
220{ 236{
221 KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra); 237 KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra);
222} 238}
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 2a8e16c22353..35c6a01963a7 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -14,57 +14,35 @@
14 * You should have received a copy of the GNU General Public License 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, 15 * along with this program; if not, write the Free Software Foundation,
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 *
18 * Portions Copyright (c) 1989, 1993
19 * The Regents of the University of California. All rights reserved.
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. Neither the name of the University nor the names of its contributors
30 * may be used to endorse or promote products derived from this software
31 * without specific prior written permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 */ 17 */
45#ifndef __XFS_VNODE_H__ 18#ifndef __XFS_VNODE_H__
46#define __XFS_VNODE_H__ 19#define __XFS_VNODE_H__
47 20
48struct uio; 21struct uio;
49struct file; 22struct file;
50struct vattr; 23struct bhv_vfs;
24struct bhv_vattr;
51struct xfs_iomap; 25struct xfs_iomap;
52struct attrlist_cursor_kern; 26struct attrlist_cursor_kern;
53 27
28typedef struct dentry bhv_vname_t;
29typedef __u64 bhv_vnumber_t;
54 30
55typedef xfs_ino_t vnumber_t; 31typedef enum bhv_vflags {
56typedef struct dentry vname_t; 32 VMODIFIED = 0x08, /* XFS inode state possibly differs */
57typedef bhv_head_t vn_bhv_head_t; 33 /* to the Linux inode state. */
34 VTRUNCATED = 0x40, /* truncated down so flush-on-close */
35} bhv_vflags_t;
58 36
59/* 37/*
60 * MP locking protocols: 38 * MP locking protocols:
61 * v_flag, v_vfsp VN_LOCK/VN_UNLOCK 39 * v_flag, v_vfsp VN_LOCK/VN_UNLOCK
62 */ 40 */
63typedef struct vnode { 41typedef struct bhv_vnode {
64 __u32 v_flag; /* vnode flags (see below) */ 42 bhv_vflags_t v_flag; /* vnode flags (see above) */
65 struct vfs *v_vfsp; /* ptr to containing VFS */ 43 bhv_vfs_t *v_vfsp; /* ptr to containing VFS */
66 vnumber_t v_number; /* in-core vnode number */ 44 bhv_vnumber_t v_number; /* in-core vnode number */
67 vn_bhv_head_t v_bh; /* behavior head */ 45 bhv_head_t v_bh; /* behavior head */
68 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ 46 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
69 atomic_t v_iocount; /* outstanding I/O count */ 47 atomic_t v_iocount; /* outstanding I/O count */
70#ifdef XFS_VNODE_TRACE 48#ifdef XFS_VNODE_TRACE
@@ -72,7 +50,7 @@ typedef struct vnode {
72#endif 50#endif
73 struct inode v_inode; /* Linux inode */ 51 struct inode v_inode; /* Linux inode */
74 /* inode MUST be last */ 52 /* inode MUST be last */
75} vnode_t; 53} bhv_vnode_t;
76 54
77#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode) 55#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode)
78#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode) 56#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode)
@@ -80,9 +58,6 @@ typedef struct vnode {
80#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode) 58#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode)
81#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode) 59#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode)
82 60
83#define v_fbhv v_bh.bh_first /* first behavior */
84#define v_fops v_bh.bh_first->bd_ops /* first behavior ops */
85
86#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */ 61#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
87#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */ 62#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */
88#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */ 63#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
@@ -104,8 +79,8 @@ typedef enum {
104/* 79/*
105 * Macros for dealing with the behavior descriptor inside of the vnode. 80 * Macros for dealing with the behavior descriptor inside of the vnode.
106 */ 81 */
107#define BHV_TO_VNODE(bdp) ((vnode_t *)BHV_VOBJ(bdp)) 82#define BHV_TO_VNODE(bdp) ((bhv_vnode_t *)BHV_VOBJ(bdp))
108#define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(bdp)) 83#define BHV_TO_VNODE_NULL(bdp) ((bhv_vnode_t *)BHV_VOBJNULL(bdp))
109 84
110#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh))) 85#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
111#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name) 86#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
@@ -116,35 +91,29 @@ typedef enum {
116/* 91/*
117 * Vnode to Linux inode mapping. 92 * Vnode to Linux inode mapping.
118 */ 93 */
119static inline struct vnode *vn_from_inode(struct inode *inode) 94static inline struct bhv_vnode *vn_from_inode(struct inode *inode)
120{ 95{
121 return (vnode_t *)list_entry(inode, vnode_t, v_inode); 96 return (bhv_vnode_t *)list_entry(inode, bhv_vnode_t, v_inode);
122} 97}
123static inline struct inode *vn_to_inode(struct vnode *vnode) 98static inline struct inode *vn_to_inode(struct bhv_vnode *vnode)
124{ 99{
125 return &vnode->v_inode; 100 return &vnode->v_inode;
126} 101}
127 102
128/* 103/*
129 * Vnode flags. 104 * Values for the vop_rwlock/rwunlock flags parameter.
130 */
131#define VMODIFIED 0x8 /* XFS inode state possibly differs */
132 /* to the Linux inode state. */
133
134/*
135 * Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter.
136 */ 105 */
137typedef enum vrwlock { 106typedef enum bhv_vrwlock {
138 VRWLOCK_NONE, 107 VRWLOCK_NONE,
139 VRWLOCK_READ, 108 VRWLOCK_READ,
140 VRWLOCK_WRITE, 109 VRWLOCK_WRITE,
141 VRWLOCK_WRITE_DIRECT, 110 VRWLOCK_WRITE_DIRECT,
142 VRWLOCK_TRY_READ, 111 VRWLOCK_TRY_READ,
143 VRWLOCK_TRY_WRITE 112 VRWLOCK_TRY_WRITE
144} vrwlock_t; 113} bhv_vrwlock_t;
145 114
146/* 115/*
147 * Return values for VOP_INACTIVE. A return value of 116 * Return values for bhv_vop_inactive. A return value of
148 * VN_INACTIVE_NOCACHE implies that the file system behavior 117 * VN_INACTIVE_NOCACHE implies that the file system behavior
149 * has disassociated its state and bhv_desc_t from the vnode. 118 * has disassociated its state and bhv_desc_t from the vnode.
150 */ 119 */
@@ -152,18 +121,20 @@ typedef enum vrwlock {
152#define VN_INACTIVE_NOCACHE 1 121#define VN_INACTIVE_NOCACHE 1
153 122
154/* 123/*
155 * Values for the cmd code given to VOP_VNODE_CHANGE. 124 * Values for the cmd code given to vop_vnode_change.
156 */ 125 */
157typedef enum vchange { 126typedef enum bhv_vchange {
158 VCHANGE_FLAGS_FRLOCKS = 0, 127 VCHANGE_FLAGS_FRLOCKS = 0,
159 VCHANGE_FLAGS_ENF_LOCKING = 1, 128 VCHANGE_FLAGS_ENF_LOCKING = 1,
160 VCHANGE_FLAGS_TRUNCATED = 2, 129 VCHANGE_FLAGS_TRUNCATED = 2,
161 VCHANGE_FLAGS_PAGE_DIRTY = 3, 130 VCHANGE_FLAGS_PAGE_DIRTY = 3,
162 VCHANGE_FLAGS_IOEXCL_COUNT = 4 131 VCHANGE_FLAGS_IOEXCL_COUNT = 4
163} vchange_t; 132} bhv_vchange_t;
164 133
134typedef enum { L_FALSE, L_TRUE } lastclose_t;
165 135
166typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); 136typedef int (*vop_open_t)(bhv_desc_t *, struct cred *);
137typedef int (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *);
167typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, 138typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
168 const struct iovec *, unsigned int, 139 const struct iovec *, unsigned int,
169 loff_t *, int, struct cred *); 140 loff_t *, int, struct cred *);
@@ -181,27 +152,27 @@ typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
181 struct cred *); 152 struct cred *);
182typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, 153typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
183 int, unsigned int, void __user *); 154 int, unsigned int, void __user *);
184typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int, 155typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
185 struct cred *); 156 struct cred *);
186typedef int (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int, 157typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
187 struct cred *); 158 struct cred *);
188typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *); 159typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *);
189typedef int (*vop_lookup_t)(bhv_desc_t *, vname_t *, vnode_t **, 160typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **,
190 int, vnode_t *, struct cred *); 161 int, bhv_vnode_t *, struct cred *);
191typedef int (*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *, 162typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
192 vnode_t **, struct cred *); 163 bhv_vnode_t **, struct cred *);
193typedef int (*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *); 164typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
194typedef int (*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *, 165typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *,
195 struct cred *);
196typedef int (*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *,
197 struct cred *); 166 struct cred *);
198typedef int (*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *, 167typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
199 vnode_t **, struct cred *); 168 bhv_vname_t *, struct cred *);
200typedef int (*vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *); 169typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
170 bhv_vnode_t **, struct cred *);
171typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
201typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *, 172typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
202 int *); 173 int *);
203typedef int (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *, 174typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
204 char *, vnode_t **, struct cred *); 175 char *, bhv_vnode_t **, struct cred *);
205typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, 176typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
206 struct cred *); 177 struct cred *);
207typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *, 178typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
@@ -209,8 +180,8 @@ typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
209typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *); 180typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *);
210typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *); 181typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *);
211typedef int (*vop_release_t)(bhv_desc_t *); 182typedef int (*vop_release_t)(bhv_desc_t *);
212typedef int (*vop_rwlock_t)(bhv_desc_t *, vrwlock_t); 183typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t);
213typedef void (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t); 184typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t);
214typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int, 185typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
215 struct xfs_iomap *, int *); 186 struct xfs_iomap *, int *);
216typedef int (*vop_reclaim_t)(bhv_desc_t *); 187typedef int (*vop_reclaim_t)(bhv_desc_t *);
@@ -222,8 +193,8 @@ typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *,
222 int, struct cred *); 193 int, struct cred *);
223typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int, 194typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
224 struct attrlist_cursor_kern *, struct cred *); 195 struct attrlist_cursor_kern *, struct cred *);
225typedef void (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int); 196typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
226typedef void (*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t); 197typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
227typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 198typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
228typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 199typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
229typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, 200typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
@@ -231,9 +202,10 @@ typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
231typedef int (*vop_iflush_t)(bhv_desc_t *, int); 202typedef int (*vop_iflush_t)(bhv_desc_t *, int);
232 203
233 204
234typedef struct vnodeops { 205typedef struct bhv_vnodeops {
235 bhv_position_t vn_position; /* position within behavior chain */ 206 bhv_position_t vn_position; /* position within behavior chain */
236 vop_open_t vop_open; 207 vop_open_t vop_open;
208 vop_close_t vop_close;
237 vop_read_t vop_read; 209 vop_read_t vop_read;
238 vop_write_t vop_write; 210 vop_write_t vop_write;
239 vop_sendfile_t vop_sendfile; 211 vop_sendfile_t vop_sendfile;
@@ -271,103 +243,80 @@ typedef struct vnodeops {
271 vop_pflushvp_t vop_flush_pages; 243 vop_pflushvp_t vop_flush_pages;
272 vop_release_t vop_release; 244 vop_release_t vop_release;
273 vop_iflush_t vop_iflush; 245 vop_iflush_t vop_iflush;
274} vnodeops_t; 246} bhv_vnodeops_t;
275 247
276/* 248/*
277 * VOP's. 249 * Virtual node operations, operating from head bhv.
278 */
279#define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op)
280
281#define VOP_READ(vp,file,iov,segs,offset,ioflags,cr,rv) \
282 rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
283#define VOP_WRITE(vp,file,iov,segs,offset,ioflags,cr,rv) \
284 rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
285#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \
286 rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
287#define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
288 rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
289#define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
290 rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
291#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
292 rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
293#define VOP_OPEN(vp, cr, rv) \
294 rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr)
295#define VOP_GETATTR(vp, vap, f, cr, rv) \
296 rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr)
297#define VOP_SETATTR(vp, vap, f, cr, rv) \
298 rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr)
299#define VOP_ACCESS(vp, mode, cr, rv) \
300 rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr)
301#define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \
302 rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr)
303#define VOP_CREATE(dvp,d,vap,vpp,cr,rv) \
304 rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr)
305#define VOP_REMOVE(dvp,d,cr,rv) \
306 rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr)
307#define VOP_LINK(tdvp,fvp,d,cr,rv) \
308 rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr)
309#define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \
310 rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr)
311#define VOP_MKDIR(dp,d,vap,vpp,cr,rv) \
312 rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr)
313#define VOP_RMDIR(dp,d,cr,rv) \
314 rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr)
315#define VOP_READDIR(vp,uiop,cr,eofp,rv) \
316 rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp)
317#define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \
318 rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr)
319#define VOP_READLINK(vp,uiop,fl,cr,rv) \
320 rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr)
321#define VOP_FSYNC(vp,f,cr,b,e,rv) \
322 rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e)
323#define VOP_INACTIVE(vp, cr, rv) \
324 rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr)
325#define VOP_RELEASE(vp, rv) \
326 rv = _VOP_(vop_release, vp)((vp)->v_fbhv)
327#define VOP_FID2(vp, fidp, rv) \
328 rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp)
329#define VOP_RWLOCK(vp,i) \
330 (void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
331#define VOP_RWLOCK_TRY(vp,i) \
332 _VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
333#define VOP_RWUNLOCK(vp,i) \
334 (void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i)
335#define VOP_FRLOCK(vp,c,fl,flags,offset,fr,rv) \
336 rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr)
337#define VOP_RECLAIM(vp, rv) \
338 rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv)
339#define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \
340 rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred)
341#define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \
342 rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred)
343#define VOP_ATTR_REMOVE(vp, name, flags, cred, rv) \
344 rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred)
345#define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \
346 rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred)
347#define VOP_LINK_REMOVED(vp, dvp, linkzero) \
348 (void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero)
349#define VOP_VNODE_CHANGE(vp, cmd, val) \
350 (void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val)
351/*
352 * These are page cache functions that now go thru VOPs.
353 * 'last' parameter is unused and left in for IRIX compatibility
354 */ 250 */
355#define VOP_TOSS_PAGES(vp, first, last, fiopt) \ 251#define VNHEAD(vp) ((vp)->v_bh.bh_first)
356 _VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt) 252#define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
357/* 253#define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr)
358 * 'last' parameter is unused and left in for IRIX compatibility 254#define bhv_vop_close(vp, f,last,cr) VOP(vop_close, vp)(VNHEAD(vp),f,last,cr)
359 */ 255#define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \
360#define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt) \ 256 VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
361 _VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt) 257#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
362/* 258 VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
363 * 'last' parameter is unused and left in for IRIX compatibility 259#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \
364 */ 260 VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
365#define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \ 261#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
366 rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt) 262 VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
367#define VOP_IOCTL(vp, inode, filp, fl, cmd, arg, rv) \ 263#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
368 rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,fl,cmd,arg) 264 VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
369#define VOP_IFLUSH(vp, flags, rv) \ 265#define bhv_vop_bmap(vp,of,sz,rw,b,n) \
370 rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags) 266 VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n)
267#define bhv_vop_getattr(vp, vap,f,cr) \
268 VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr)
269#define bhv_vop_setattr(vp, vap,f,cr) \
270 VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr)
271#define bhv_vop_access(vp, mode,cr) VOP(vop_access, vp)(VNHEAD(vp), mode,cr)
272#define bhv_vop_lookup(vp,d,vpp,f,rdir,cr) \
273 VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr)
274#define bhv_vop_create(dvp,d,vap,vpp,cr) \
275 VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr)
276#define bhv_vop_remove(dvp,d,cr) VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr)
277#define bhv_vop_link(dvp,fvp,d,cr) VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr)
278#define bhv_vop_rename(fvp,fnm,tdvp,tnm,cr) \
279 VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr)
280#define bhv_vop_mkdir(dp,d,vap,vpp,cr) \
281 VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
282#define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
283#define bhv_vop_readdir(vp,uiop,cr,eofp) \
284 VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp)
285#define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \
286 VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
287#define bhv_vop_readlink(vp,uiop,fl,cr) \
288 VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr)
289#define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e)
290#define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr)
291#define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp))
292#define bhv_vop_fid2(vp,fidp) VOP(vop_fid2, vp)(VNHEAD(vp),fidp)
293#define bhv_vop_rwlock(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
294#define bhv_vop_rwlock_try(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
295#define bhv_vop_rwunlock(vp,i) VOP(vop_rwunlock, vp)(VNHEAD(vp),i)
296#define bhv_vop_frlock(vp,c,fl,flags,offset,fr) \
297 VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr)
298#define bhv_vop_reclaim(vp) VOP(vop_reclaim, vp)(VNHEAD(vp))
299#define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred) \
300 VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred)
301#define bhv_vop_attr_set(vp, name, val, vallen, fl, cred) \
302 VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred)
303#define bhv_vop_attr_remove(vp, name, flags, cred) \
304 VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred)
305#define bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred) \
306 VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred)
307#define bhv_vop_link_removed(vp, dvp, linkzero) \
308 VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero)
309#define bhv_vop_vnode_change(vp, cmd, val) \
310 VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val)
311#define bhv_vop_toss_pages(vp, first, last, fiopt) \
312 VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt)
313#define bhv_vop_flushinval_pages(vp, first, last, fiopt) \
314 VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt)
315#define bhv_vop_flush_pages(vp, first, last, flags, fiopt) \
316 VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt)
317#define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg) \
318 VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg)
319#define bhv_vop_iflush(vp, flags) VOP(vop_iflush, vp)(VNHEAD(vp), flags)
371 320
372/* 321/*
373 * Flags for read/write calls - same values as IRIX 322 * Flags for read/write calls - same values as IRIX
@@ -377,7 +326,7 @@ typedef struct vnodeops {
377#define IO_INVIS 0x00020 /* don't update inode timestamps */ 326#define IO_INVIS 0x00020 /* don't update inode timestamps */
378 327
379/* 328/*
380 * Flags for VOP_IFLUSH call 329 * Flags for vop_iflush call
381 */ 330 */
382#define FLUSH_SYNC 1 /* wait for flush to complete */ 331#define FLUSH_SYNC 1 /* wait for flush to complete */
383#define FLUSH_INODE 2 /* flush the inode itself */ 332#define FLUSH_INODE 2 /* flush the inode itself */
@@ -385,8 +334,7 @@ typedef struct vnodeops {
385 * this inode out to disk */ 334 * this inode out to disk */
386 335
387/* 336/*
388 * Flush/Invalidate options for VOP_TOSS_PAGES, VOP_FLUSHINVAL_PAGES and 337 * Flush/Invalidate options for vop_toss/flush/flushinval_pages.
389 * VOP_FLUSH_PAGES.
390 */ 338 */
391#define FI_NONE 0 /* none */ 339#define FI_NONE 0 /* none */
392#define FI_REMAPF 1 /* Do a remapf prior to the operation */ 340#define FI_REMAPF 1 /* Do a remapf prior to the operation */
@@ -398,7 +346,7 @@ typedef struct vnodeops {
398 * Vnode attributes. va_mask indicates those attributes the caller 346 * Vnode attributes. va_mask indicates those attributes the caller
399 * wants to set or extract. 347 * wants to set or extract.
400 */ 348 */
401typedef struct vattr { 349typedef struct bhv_vattr {
402 int va_mask; /* bit-mask of attributes present */ 350 int va_mask; /* bit-mask of attributes present */
403 mode_t va_mode; /* file access mode and type */ 351 mode_t va_mode; /* file access mode and type */
404 xfs_nlink_t va_nlink; /* number of references to file */ 352 xfs_nlink_t va_nlink; /* number of references to file */
@@ -418,7 +366,7 @@ typedef struct vattr {
418 u_long va_nextents; /* number of extents in file */ 366 u_long va_nextents; /* number of extents in file */
419 u_long va_anextents; /* number of attr extents in file */ 367 u_long va_anextents; /* number of attr extents in file */
420 prid_t va_projid; /* project id */ 368 prid_t va_projid; /* project id */
421} vattr_t; 369} bhv_vattr_t;
422 370
423/* 371/*
424 * setattr or getattr attributes 372 * setattr or getattr attributes
@@ -492,29 +440,17 @@ typedef struct vattr {
492 (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID) 440 (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID)
493 441
494extern void vn_init(void); 442extern void vn_init(void);
495extern vnode_t *vn_initialize(struct inode *); 443extern bhv_vnode_t *vn_initialize(struct inode *);
496 444extern int vn_revalidate(struct bhv_vnode *);
497/* 445extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *);
498 * vnode_map structures _must_ match vn_epoch and vnode structure sizes. 446extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *);
499 */
500typedef struct vnode_map {
501 vfs_t *v_vfsp;
502 vnumber_t v_number; /* in-core vnode number */
503 xfs_ino_t v_ino; /* inode # */
504} vmap_t;
505
506#define VMAP(vp, vmap) {(vmap).v_vfsp = (vp)->v_vfsp, \
507 (vmap).v_number = (vp)->v_number, \
508 (vmap).v_ino = (vp)->v_inode.i_ino; }
509 447
510extern int vn_revalidate(struct vnode *); 448extern void vn_iowait(struct bhv_vnode *vp);
511extern int __vn_revalidate(struct vnode *, vattr_t *); 449extern void vn_iowake(struct bhv_vnode *vp);
512extern void vn_revalidate_core(struct vnode *, vattr_t *);
513 450
514extern void vn_iowait(struct vnode *vp); 451extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l);
515extern void vn_iowake(struct vnode *vp);
516 452
517static inline int vn_count(struct vnode *vp) 453static inline int vn_count(struct bhv_vnode *vp)
518{ 454{
519 return atomic_read(&vn_to_inode(vp)->i_count); 455 return atomic_read(&vn_to_inode(vp)->i_count);
520} 456}
@@ -522,7 +458,7 @@ static inline int vn_count(struct vnode *vp)
522/* 458/*
523 * Vnode reference counting functions (and macros for compatibility). 459 * Vnode reference counting functions (and macros for compatibility).
524 */ 460 */
525extern vnode_t *vn_hold(struct vnode *); 461extern bhv_vnode_t *vn_hold(struct bhv_vnode *);
526 462
527#if defined(XFS_VNODE_TRACE) 463#if defined(XFS_VNODE_TRACE)
528#define VN_HOLD(vp) \ 464#define VN_HOLD(vp) \
@@ -536,7 +472,7 @@ extern vnode_t *vn_hold(struct vnode *);
536#define VN_RELE(vp) (iput(vn_to_inode(vp))) 472#define VN_RELE(vp) (iput(vn_to_inode(vp)))
537#endif 473#endif
538 474
539static inline struct vnode *vn_grab(struct vnode *vp) 475static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp)
540{ 476{
541 struct inode *inode = igrab(vn_to_inode(vp)); 477 struct inode *inode = igrab(vn_to_inode(vp));
542 return inode ? vn_from_inode(inode) : NULL; 478 return inode ? vn_from_inode(inode) : NULL;
@@ -554,32 +490,39 @@ static inline struct vnode *vn_grab(struct vnode *vp)
554 */ 490 */
555#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock) 491#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock)
556#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s) 492#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s)
557#define VN_FLAGSET(vp,b) vn_flagset(vp,b)
558#define VN_FLAGCLR(vp,b) vn_flagclr(vp,b)
559 493
560static __inline__ void vn_flagset(struct vnode *vp, uint flag) 494static __inline__ void vn_flagset(struct bhv_vnode *vp, uint flag)
561{ 495{
562 spin_lock(&vp->v_lock); 496 spin_lock(&vp->v_lock);
563 vp->v_flag |= flag; 497 vp->v_flag |= flag;
564 spin_unlock(&vp->v_lock); 498 spin_unlock(&vp->v_lock);
565} 499}
566 500
567static __inline__ void vn_flagclr(struct vnode *vp, uint flag) 501static __inline__ uint vn_flagclr(struct bhv_vnode *vp, uint flag)
568{ 502{
503 uint cleared;
504
569 spin_lock(&vp->v_lock); 505 spin_lock(&vp->v_lock);
506 cleared = (vp->v_flag & flag);
570 vp->v_flag &= ~flag; 507 vp->v_flag &= ~flag;
571 spin_unlock(&vp->v_lock); 508 spin_unlock(&vp->v_lock);
509 return cleared;
572} 510}
573 511
512#define VMODIFY(vp) vn_flagset(vp, VMODIFIED)
513#define VUNMODIFY(vp) vn_flagclr(vp, VMODIFIED)
514#define VTRUNCATE(vp) vn_flagset(vp, VTRUNCATED)
515#define VUNTRUNCATE(vp) vn_flagclr(vp, VTRUNCATED)
516
574/* 517/*
575 * Dealing with bad inodes 518 * Dealing with bad inodes
576 */ 519 */
577static inline void vn_mark_bad(struct vnode *vp) 520static inline void vn_mark_bad(struct bhv_vnode *vp)
578{ 521{
579 make_bad_inode(vn_to_inode(vp)); 522 make_bad_inode(vn_to_inode(vp));
580} 523}
581 524
582static inline int VN_BAD(struct vnode *vp) 525static inline int VN_BAD(struct bhv_vnode *vp)
583{ 526{
584 return is_bad_inode(vn_to_inode(vp)); 527 return is_bad_inode(vn_to_inode(vp));
585} 528}
@@ -587,18 +530,18 @@ static inline int VN_BAD(struct vnode *vp)
587/* 530/*
588 * Extracting atime values in various formats 531 * Extracting atime values in various formats
589 */ 532 */
590static inline void vn_atime_to_bstime(struct vnode *vp, xfs_bstime_t *bs_atime) 533static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime)
591{ 534{
592 bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec; 535 bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
593 bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec; 536 bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
594} 537}
595 538
596static inline void vn_atime_to_timespec(struct vnode *vp, struct timespec *ts) 539static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts)
597{ 540{
598 *ts = vp->v_inode.i_atime; 541 *ts = vp->v_inode.i_atime;
599} 542}
600 543
601static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt) 544static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
602{ 545{
603 *tt = vp->v_inode.i_atime.tv_sec; 546 *tt = vp->v_inode.i_atime.tv_sec;
604} 547}
@@ -610,11 +553,10 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
610#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages) 553#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages)
611#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ 554#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
612 PAGECACHE_TAG_DIRTY) 555 PAGECACHE_TAG_DIRTY)
613#define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED) 556#define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED)
614#define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED)
615 557
616/* 558/*
617 * Flags to VOP_SETATTR/VOP_GETATTR. 559 * Flags to vop_setattr/getattr.
618 */ 560 */
619#define ATTR_UTIME 0x01 /* non-default utime(2) request */ 561#define ATTR_UTIME 0x01 /* non-default utime(2) request */
620#define ATTR_DMI 0x08 /* invocation from a DMI function */ 562#define ATTR_DMI 0x08 /* invocation from a DMI function */
@@ -624,7 +566,7 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
624#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */ 566#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
625 567
626/* 568/*
627 * Flags to VOP_FSYNC and VOP_RECLAIM. 569 * Flags to vop_fsync/reclaim.
628 */ 570 */
629#define FSYNC_NOWAIT 0 /* asynchronous flush */ 571#define FSYNC_NOWAIT 0 /* asynchronous flush */
630#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */ 572#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */
@@ -643,11 +585,11 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
643#define VNODE_KTRACE_REF 4 585#define VNODE_KTRACE_REF 4
644#define VNODE_KTRACE_RELE 5 586#define VNODE_KTRACE_RELE 5
645 587
646extern void vn_trace_entry(struct vnode *, const char *, inst_t *); 588extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *);
647extern void vn_trace_exit(struct vnode *, const char *, inst_t *); 589extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *);
648extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); 590extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *);
649extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); 591extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *);
650extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); 592extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *);
651 593
652#define VN_TRACE(vp) \ 594#define VN_TRACE(vp) \
653 vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address) 595 vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 772ac48329ea..3aa771531856 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -444,7 +442,7 @@ xfs_qm_dqalloc(
444 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, 442 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
445 &firstblock, 443 &firstblock,
446 XFS_QM_DQALLOC_SPACE_RES(mp), 444 XFS_QM_DQALLOC_SPACE_RES(mp),
447 &map, &nmaps, &flist))) { 445 &map, &nmaps, &flist, NULL))) {
448 goto error0; 446 goto error0;
449 } 447 }
450 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); 448 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
@@ -559,7 +557,7 @@ xfs_qm_dqtobp(
559 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset, 557 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
560 XFS_DQUOT_CLUSTER_SIZE_FSB, 558 XFS_DQUOT_CLUSTER_SIZE_FSB,
561 XFS_BMAPI_METADATA, 559 XFS_BMAPI_METADATA,
562 NULL, 0, &map, &nmaps, NULL); 560 NULL, 0, &map, &nmaps, NULL, NULL);
563 561
564 xfs_iunlock(quotip, XFS_ILOCK_SHARED); 562 xfs_iunlock(quotip, XFS_ILOCK_SHARED);
565 if (error) 563 if (error)
@@ -1261,7 +1259,7 @@ xfs_qm_dqflush(
1261 1259
1262 if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id), 1260 if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id),
1263 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) { 1261 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
1264 xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); 1262 xfs_force_shutdown(dqp->q_mount, SHUTDOWN_CORRUPT_INCORE);
1265 return XFS_ERROR(EIO); 1263 return XFS_ERROR(EIO);
1266 } 1264 }
1267 1265
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index c0c629663a5c..78d3ab95c5fd 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -119,7 +119,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
119 */ 119 */
120#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\ 120#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\
121 (dqp)->dq_flags |= XFS_DQ_FLOCKED; } 121 (dqp)->dq_flags |= XFS_DQ_FLOCKED; }
122#define xfs_dqfunlock(dqp) { ASSERT(valusema(&((dqp)->q_flock)) <= 0); \ 122#define xfs_dqfunlock(dqp) { ASSERT(issemalocked(&((dqp)->q_flock))); \
123 vsema(&((dqp)->q_flock)); \ 123 vsema(&((dqp)->q_flock)); \
124 (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); } 124 (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); }
125 125
@@ -128,7 +128,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
128#define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \ 128#define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \
129 &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s) 129 &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s)
130 130
131#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (valusema(&((dqp)->q_flock)) <= 0) 131#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock)))
132#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) 132#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
133#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) 133#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
134#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) 134#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index 546f48af882a..5b2dcc58b244 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -248,7 +246,7 @@ xfs_qm_dquot_logitem_pushbuf(
248 * inode flush completed and the inode was taken off the AIL. 246 * inode flush completed and the inode was taken off the AIL.
249 * So, just get out. 247 * So, just get out.
250 */ 248 */
251 if ((valusema(&(dqp->q_flock)) > 0) || 249 if (!issemalocked(&(dqp->q_flock)) ||
252 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) { 250 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
253 qip->qli_pushbuf_flag = 0; 251 qip->qli_pushbuf_flag = 0;
254 xfs_dqunlock(dqp); 252 xfs_dqunlock(dqp);
@@ -261,7 +259,7 @@ xfs_qm_dquot_logitem_pushbuf(
261 if (bp != NULL) { 259 if (bp != NULL) {
262 if (XFS_BUF_ISDELAYWRITE(bp)) { 260 if (XFS_BUF_ISDELAYWRITE(bp)) {
263 dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && 261 dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
264 (valusema(&(dqp->q_flock)) <= 0)); 262 issemalocked(&(dqp->q_flock)));
265 qip->qli_pushbuf_flag = 0; 263 qip->qli_pushbuf_flag = 0;
266 xfs_dqunlock(dqp); 264 xfs_dqunlock(dqp);
267 265
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 7fb5eca9bd50..e23e45535c48 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -24,7 +24,6 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_alloc.h" 28#include "xfs_alloc.h"
30#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -1603,7 +1601,7 @@ xfs_qm_dqiterate(
1603 maxlblkcnt - lblkno, 1601 maxlblkcnt - lblkno,
1604 XFS_BMAPI_METADATA, 1602 XFS_BMAPI_METADATA,
1605 NULL, 1603 NULL,
1606 0, map, &nmaps, NULL); 1604 0, map, &nmaps, NULL, NULL);
1607 xfs_iunlock(qip, XFS_ILOCK_SHARED); 1605 xfs_iunlock(qip, XFS_ILOCK_SHARED);
1608 if (error) 1606 if (error)
1609 break; 1607 break;
@@ -1905,9 +1903,7 @@ xfs_qm_quotacheck(
1905 */ 1903 */
1906 if ((error = xfs_bulkstat(mp, &lastino, &count, 1904 if ((error = xfs_bulkstat(mp, &lastino, &count,
1907 xfs_qm_dqusage_adjust, NULL, 1905 xfs_qm_dqusage_adjust, NULL,
1908 structsz, NULL, 1906 structsz, NULL, BULKSTAT_FG_IGET, &done)))
1909 BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED,
1910 &done)))
1911 break; 1907 break;
1912 1908
1913 } while (! done); 1909 } while (! done);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index 6838b36d95a9..e95e99f7168f 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_alloc.h" 28#include "xfs_alloc.h"
30#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -129,7 +127,7 @@ xfs_qm_parseargs(
129 return XFS_ERROR(EINVAL); 127 return XFS_ERROR(EINVAL);
130 } 128 }
131 129
132 PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); 130 error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
133 if (!error && !referenced) 131 if (!error && !referenced)
134 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); 132 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
135 return error; 133 return error;
@@ -140,9 +138,8 @@ xfs_qm_showargs(
140 struct bhv_desc *bhv, 138 struct bhv_desc *bhv,
141 struct seq_file *m) 139 struct seq_file *m)
142{ 140{
143 struct vfs *vfsp = bhvtovfs(bhv); 141 struct bhv_vfs *vfsp = bhvtovfs(bhv);
144 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 142 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
145 int error;
146 143
147 if (mp->m_qflags & XFS_UQUOTA_ACCT) { 144 if (mp->m_qflags & XFS_UQUOTA_ACCT) {
148 (mp->m_qflags & XFS_UQUOTA_ENFD) ? 145 (mp->m_qflags & XFS_UQUOTA_ENFD) ?
@@ -165,8 +162,7 @@ xfs_qm_showargs(
165 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) 162 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
166 seq_puts(m, "," MNTOPT_NOQUOTA); 163 seq_puts(m, "," MNTOPT_NOQUOTA);
167 164
168 PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); 165 return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
169 return error;
170} 166}
171 167
172STATIC int 168STATIC int
@@ -175,14 +171,67 @@ xfs_qm_mount(
175 struct xfs_mount_args *args, 171 struct xfs_mount_args *args,
176 struct cred *cr) 172 struct cred *cr)
177{ 173{
178 struct vfs *vfsp = bhvtovfs(bhv); 174 struct bhv_vfs *vfsp = bhvtovfs(bhv);
179 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 175 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
180 int error;
181 176
182 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) 177 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
183 xfs_qm_mount_quotainit(mp, args->flags); 178 xfs_qm_mount_quotainit(mp, args->flags);
184 PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); 179 return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
185 return error; 180}
181
182/*
183 * Directory tree accounting is implemented using project quotas, where
184 * the project identifier is inherited from parent directories.
185 * A statvfs (df, etc.) of a directory that is using project quota should
186 * return a statvfs of the project, not the entire filesystem.
187 * This makes such trees appear as if they are filesystems in themselves.
188 */
189STATIC int
190xfs_qm_statvfs(
191 struct bhv_desc *bhv,
192 bhv_statvfs_t *statp,
193 struct bhv_vnode *vnode)
194{
195 xfs_mount_t *mp;
196 xfs_inode_t *ip;
197 xfs_dquot_t *dqp;
198 xfs_disk_dquot_t *dp;
199 __uint64_t limit;
200 int error;
201
202 error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
203 if (error || !vnode)
204 return error;
205
206 mp = XFS_BHVTOM(bhv);
207 ip = xfs_vtoi(vnode);
208
209 if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
210 return 0;
211 if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
212 return 0;
213 if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
214 return 0;
215
216 if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
217 return 0;
218 dp = &dqp->q_core;
219
220 limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit;
221 if (limit && statp->f_blocks > limit) {
222 statp->f_blocks = limit;
223 statp->f_bfree = (statp->f_blocks > dp->d_bcount) ?
224 (statp->f_blocks - dp->d_bcount) : 0;
225 }
226 limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit;
227 if (limit && statp->f_files > limit) {
228 statp->f_files = limit;
229 statp->f_ffree = (statp->f_files > dp->d_icount) ?
230 (statp->f_ffree - dp->d_icount) : 0;
231 }
232
233 xfs_qm_dqput(dqp);
234 return 0;
186} 235}
187 236
188STATIC int 237STATIC int
@@ -191,7 +240,7 @@ xfs_qm_syncall(
191 int flags, 240 int flags,
192 cred_t *credp) 241 cred_t *credp)
193{ 242{
194 struct vfs *vfsp = bhvtovfs(bhv); 243 struct bhv_vfs *vfsp = bhvtovfs(bhv);
195 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 244 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
196 int error; 245 int error;
197 246
@@ -210,8 +259,7 @@ xfs_qm_syncall(
210 } 259 }
211 } 260 }
212 } 261 }
213 PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error); 262 return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
214 return error;
215} 263}
216 264
217STATIC int 265STATIC int
@@ -346,11 +394,12 @@ STATIC struct xfs_qmops xfs_qmcore_xfs = {
346 .xfs_dqtrxops = &xfs_trans_dquot_ops, 394 .xfs_dqtrxops = &xfs_trans_dquot_ops,
347}; 395};
348 396
349struct bhv_vfsops xfs_qmops = { { 397struct bhv_module_vfsops xfs_qmops = { {
350 BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM), 398 BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
351 .vfs_parseargs = xfs_qm_parseargs, 399 .vfs_parseargs = xfs_qm_parseargs,
352 .vfs_showargs = xfs_qm_showargs, 400 .vfs_showargs = xfs_qm_showargs,
353 .vfs_mount = xfs_qm_mount, 401 .vfs_mount = xfs_qm_mount,
402 .vfs_statvfs = xfs_qm_statvfs,
354 .vfs_sync = xfs_qm_syncall, 403 .vfs_sync = xfs_qm_syncall,
355 .vfs_quotactl = xfs_qm_quotactl, }, 404 .vfs_quotactl = xfs_qm_quotactl, },
356}; 405};
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c
index 0570f7733550..6f858fb81a36 100644
--- a/fs/xfs/quota/xfs_qm_stats.c
+++ b/fs/xfs/quota/xfs_qm_stats.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index c55db463bbf2..ed620c4d1594 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -26,7 +26,6 @@
26#include "xfs_trans.h" 26#include "xfs_trans.h"
27#include "xfs_sb.h" 27#include "xfs_sb.h"
28#include "xfs_ag.h" 28#include "xfs_ag.h"
29#include "xfs_dir.h"
30#include "xfs_dir2.h" 29#include "xfs_dir2.h"
31#include "xfs_alloc.h" 30#include "xfs_alloc.h"
32#include "xfs_dmapi.h" 31#include "xfs_dmapi.h"
@@ -35,7 +34,6 @@
35#include "xfs_bmap_btree.h" 34#include "xfs_bmap_btree.h"
36#include "xfs_alloc_btree.h" 35#include "xfs_alloc_btree.h"
37#include "xfs_ialloc_btree.h" 36#include "xfs_ialloc_btree.h"
38#include "xfs_dir_sf.h"
39#include "xfs_dir2_sf.h" 37#include "xfs_dir2_sf.h"
40#include "xfs_attr_sf.h" 38#include "xfs_attr_sf.h"
41#include "xfs_dinode.h" 39#include "xfs_dinode.h"
@@ -91,8 +89,8 @@ xfs_qm_quotactl(
91 xfs_caddr_t addr) 89 xfs_caddr_t addr)
92{ 90{
93 xfs_mount_t *mp; 91 xfs_mount_t *mp;
92 bhv_vfs_t *vfsp;
94 int error; 93 int error;
95 struct vfs *vfsp;
96 94
97 vfsp = bhvtovfs(bdp); 95 vfsp = bhvtovfs(bdp);
98 mp = XFS_VFSTOM(vfsp); 96 mp = XFS_VFSTOM(vfsp);
@@ -1035,7 +1033,7 @@ xfs_qm_dqrele_all_inodes(
1035{ 1033{
1036 xfs_inode_t *ip, *topino; 1034 xfs_inode_t *ip, *topino;
1037 uint ireclaims; 1035 uint ireclaims;
1038 vnode_t *vp; 1036 bhv_vnode_t *vp;
1039 boolean_t vnode_refd; 1037 boolean_t vnode_refd;
1040 1038
1041 ASSERT(mp->m_quotainfo); 1039 ASSERT(mp->m_quotainfo);
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 9168918db252..0242e9666e8e 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
39#include "xfs_inode.h" 37#include "xfs_inode.h"
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index b08b3d9345b7..36fbeccdc722 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -47,7 +47,7 @@ cmn_err(register int level, char *fmt, ...)
47 va_start(ap, fmt); 47 va_start(ap, fmt);
48 if (*fmt == '!') fp++; 48 if (*fmt == '!') fp++;
49 len = vsprintf(message, fp, ap); 49 len = vsprintf(message, fp, ap);
50 if (message[len-1] != '\n') 50 if (level != CE_DEBUG && message[len-1] != '\n')
51 strcat(message, "\n"); 51 strcat(message, "\n");
52 printk("%s%s", err_level[level], message); 52 printk("%s%s", err_level[level], message);
53 va_end(ap); 53 va_end(ap);
@@ -68,7 +68,7 @@ icmn_err(register int level, char *fmt, va_list ap)
68 level = XFS_MAX_ERR_LEVEL; 68 level = XFS_MAX_ERR_LEVEL;
69 spin_lock_irqsave(&xfs_err_lock,flags); 69 spin_lock_irqsave(&xfs_err_lock,flags);
70 len = vsprintf(message, fmt, ap); 70 len = vsprintf(message, fmt, ap);
71 if (message[len-1] != '\n') 71 if (level != CE_DEBUG && message[len-1] != '\n')
72 strcat(message, "\n"); 72 strcat(message, "\n");
73 spin_unlock_irqrestore(&xfs_err_lock,flags); 73 spin_unlock_irqrestore(&xfs_err_lock,flags);
74 printk("%s%s", err_level[level], message); 74 printk("%s%s", err_level[level], message);
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index e3bf58112e7e..4f54dca662a8 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -33,9 +33,6 @@ extern void cmn_err(int, char *, ...)
33 __attribute__ ((format (printf, 2, 3))); 33 __attribute__ ((format (printf, 2, 3)));
34extern void assfail(char *expr, char *f, int l); 34extern void assfail(char *expr, char *f, int l);
35 35
36#define prdev(fmt,targ,args...) \
37 printk("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
38
39#define ASSERT_ALWAYS(expr) \ 36#define ASSERT_ALWAYS(expr) \
40 (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 37 (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
41 38
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 2539af34eb63..4b0cb474be4c 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -21,12 +21,10 @@
21#include "xfs_bit.h" 21#include "xfs_bit.h"
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_dir.h"
25#include "xfs_dir2.h" 24#include "xfs_dir2.h"
26#include "xfs_bmap_btree.h" 25#include "xfs_bmap_btree.h"
27#include "xfs_alloc_btree.h" 26#include "xfs_alloc_btree.h"
28#include "xfs_ialloc_btree.h" 27#include "xfs_ialloc_btree.h"
29#include "xfs_dir_sf.h"
30#include "xfs_dir2_sf.h" 28#include "xfs_dir2_sf.h"
31#include "xfs_attr_sf.h" 29#include "xfs_attr_sf.h"
32#include "xfs_dinode.h" 30#include "xfs_dinode.h"
@@ -39,15 +37,15 @@
39#include <linux/capability.h> 37#include <linux/capability.h>
40#include <linux/posix_acl_xattr.h> 38#include <linux/posix_acl_xattr.h>
41 39
42STATIC int xfs_acl_setmode(vnode_t *, xfs_acl_t *, int *); 40STATIC int xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *);
43STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *); 41STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *);
44STATIC void xfs_acl_get_endian(xfs_acl_t *); 42STATIC void xfs_acl_get_endian(xfs_acl_t *);
45STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *); 43STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *);
46STATIC int xfs_acl_invalid(xfs_acl_t *); 44STATIC int xfs_acl_invalid(xfs_acl_t *);
47STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *); 45STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *);
48STATIC void xfs_acl_get_attr(vnode_t *, xfs_acl_t *, int, int, int *); 46STATIC void xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *);
49STATIC void xfs_acl_set_attr(vnode_t *, xfs_acl_t *, int, int *); 47STATIC void xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *);
50STATIC int xfs_acl_allow_set(vnode_t *, int); 48STATIC int xfs_acl_allow_set(bhv_vnode_t *, int);
51 49
52kmem_zone_t *xfs_acl_zone; 50kmem_zone_t *xfs_acl_zone;
53 51
@@ -57,7 +55,7 @@ kmem_zone_t *xfs_acl_zone;
57 */ 55 */
58int 56int
59xfs_acl_vhasacl_access( 57xfs_acl_vhasacl_access(
60 vnode_t *vp) 58 bhv_vnode_t *vp)
61{ 59{
62 int error; 60 int error;
63 61
@@ -70,7 +68,7 @@ xfs_acl_vhasacl_access(
70 */ 68 */
71int 69int
72xfs_acl_vhasacl_default( 70xfs_acl_vhasacl_default(
73 vnode_t *vp) 71 bhv_vnode_t *vp)
74{ 72{
75 int error; 73 int error;
76 74
@@ -209,7 +207,7 @@ posix_acl_xfs_to_xattr(
209 207
210int 208int
211xfs_acl_vget( 209xfs_acl_vget(
212 vnode_t *vp, 210 bhv_vnode_t *vp,
213 void *acl, 211 void *acl,
214 size_t size, 212 size_t size,
215 int kind) 213 int kind)
@@ -241,10 +239,10 @@ xfs_acl_vget(
241 goto out; 239 goto out;
242 } 240 }
243 if (kind == _ACL_TYPE_ACCESS) { 241 if (kind == _ACL_TYPE_ACCESS) {
244 vattr_t va; 242 bhv_vattr_t va;
245 243
246 va.va_mask = XFS_AT_MODE; 244 va.va_mask = XFS_AT_MODE;
247 VOP_GETATTR(vp, &va, 0, sys_cred, error); 245 error = bhv_vop_getattr(vp, &va, 0, sys_cred);
248 if (error) 246 if (error)
249 goto out; 247 goto out;
250 xfs_acl_sync_mode(va.va_mode, xfs_acl); 248 xfs_acl_sync_mode(va.va_mode, xfs_acl);
@@ -260,7 +258,7 @@ out:
260 258
261int 259int
262xfs_acl_vremove( 260xfs_acl_vremove(
263 vnode_t *vp, 261 bhv_vnode_t *vp,
264 int kind) 262 int kind)
265{ 263{
266 int error; 264 int error;
@@ -268,9 +266,9 @@ xfs_acl_vremove(
268 VN_HOLD(vp); 266 VN_HOLD(vp);
269 error = xfs_acl_allow_set(vp, kind); 267 error = xfs_acl_allow_set(vp, kind);
270 if (!error) { 268 if (!error) {
271 VOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT? 269 error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT?
272 SGI_ACL_DEFAULT: SGI_ACL_FILE, 270 SGI_ACL_DEFAULT: SGI_ACL_FILE,
273 ATTR_ROOT, sys_cred, error); 271 ATTR_ROOT, sys_cred);
274 if (error == ENOATTR) 272 if (error == ENOATTR)
275 error = 0; /* 'scool */ 273 error = 0; /* 'scool */
276 } 274 }
@@ -280,7 +278,7 @@ xfs_acl_vremove(
280 278
281int 279int
282xfs_acl_vset( 280xfs_acl_vset(
283 vnode_t *vp, 281 bhv_vnode_t *vp,
284 void *acl, 282 void *acl,
285 size_t size, 283 size_t size,
286 int kind) 284 int kind)
@@ -370,10 +368,10 @@ xfs_acl_iaccess(
370 368
371STATIC int 369STATIC int
372xfs_acl_allow_set( 370xfs_acl_allow_set(
373 vnode_t *vp, 371 bhv_vnode_t *vp,
374 int kind) 372 int kind)
375{ 373{
376 vattr_t va; 374 bhv_vattr_t va;
377 int error; 375 int error;
378 376
379 if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) 377 if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
@@ -383,7 +381,7 @@ xfs_acl_allow_set(
383 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 381 if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
384 return EROFS; 382 return EROFS;
385 va.va_mask = XFS_AT_UID; 383 va.va_mask = XFS_AT_UID;
386 VOP_GETATTR(vp, &va, 0, NULL, error); 384 error = bhv_vop_getattr(vp, &va, 0, NULL);
387 if (error) 385 if (error)
388 return error; 386 return error;
389 if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) 387 if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
@@ -606,7 +604,7 @@ xfs_acl_get_endian(
606 */ 604 */
607STATIC void 605STATIC void
608xfs_acl_get_attr( 606xfs_acl_get_attr(
609 vnode_t *vp, 607 bhv_vnode_t *vp,
610 xfs_acl_t *aclp, 608 xfs_acl_t *aclp,
611 int kind, 609 int kind,
612 int flags, 610 int flags,
@@ -616,9 +614,9 @@ xfs_acl_get_attr(
616 614
617 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); 615 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1);
618 flags |= ATTR_ROOT; 616 flags |= ATTR_ROOT;
619 VOP_ATTR_GET(vp, 617 *error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ?
620 kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT, 618 SGI_ACL_FILE : SGI_ACL_DEFAULT,
621 (char *)aclp, &len, flags, sys_cred, *error); 619 (char *)aclp, &len, flags, sys_cred);
622 if (*error || (flags & ATTR_KERNOVAL)) 620 if (*error || (flags & ATTR_KERNOVAL))
623 return; 621 return;
624 xfs_acl_get_endian(aclp); 622 xfs_acl_get_endian(aclp);
@@ -629,7 +627,7 @@ xfs_acl_get_attr(
629 */ 627 */
630STATIC void 628STATIC void
631xfs_acl_set_attr( 629xfs_acl_set_attr(
632 vnode_t *vp, 630 bhv_vnode_t *vp,
633 xfs_acl_t *aclp, 631 xfs_acl_t *aclp,
634 int kind, 632 int kind,
635 int *error) 633 int *error)
@@ -654,19 +652,19 @@ xfs_acl_set_attr(
654 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); 652 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm);
655 } 653 }
656 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); 654 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
657 VOP_ATTR_SET(vp, 655 *error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ?
658 kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE: SGI_ACL_DEFAULT, 656 SGI_ACL_FILE: SGI_ACL_DEFAULT,
659 (char *)newacl, len, ATTR_ROOT, sys_cred, *error); 657 (char *)newacl, len, ATTR_ROOT, sys_cred);
660 _ACL_FREE(newacl); 658 _ACL_FREE(newacl);
661} 659}
662 660
663int 661int
664xfs_acl_vtoacl( 662xfs_acl_vtoacl(
665 vnode_t *vp, 663 bhv_vnode_t *vp,
666 xfs_acl_t *access_acl, 664 xfs_acl_t *access_acl,
667 xfs_acl_t *default_acl) 665 xfs_acl_t *default_acl)
668{ 666{
669 vattr_t va; 667 bhv_vattr_t va;
670 int error = 0; 668 int error = 0;
671 669
672 if (access_acl) { 670 if (access_acl) {
@@ -678,7 +676,7 @@ xfs_acl_vtoacl(
678 if (!error) { 676 if (!error) {
679 /* Got the ACL, need the mode... */ 677 /* Got the ACL, need the mode... */
680 va.va_mask = XFS_AT_MODE; 678 va.va_mask = XFS_AT_MODE;
681 VOP_GETATTR(vp, &va, 0, sys_cred, error); 679 error = bhv_vop_getattr(vp, &va, 0, sys_cred);
682 } 680 }
683 681
684 if (error) 682 if (error)
@@ -701,8 +699,8 @@ xfs_acl_vtoacl(
701 */ 699 */
702int 700int
703xfs_acl_inherit( 701xfs_acl_inherit(
704 vnode_t *vp, 702 bhv_vnode_t *vp,
705 vattr_t *vap, 703 bhv_vattr_t *vap,
706 xfs_acl_t *pdaclp) 704 xfs_acl_t *pdaclp)
707{ 705{
708 xfs_acl_t *cacl; 706 xfs_acl_t *cacl;
@@ -757,11 +755,11 @@ xfs_acl_inherit(
757 */ 755 */
758STATIC int 756STATIC int
759xfs_acl_setmode( 757xfs_acl_setmode(
760 vnode_t *vp, 758 bhv_vnode_t *vp,
761 xfs_acl_t *acl, 759 xfs_acl_t *acl,
762 int *basicperms) 760 int *basicperms)
763{ 761{
764 vattr_t va; 762 bhv_vattr_t va;
765 xfs_acl_entry_t *ap; 763 xfs_acl_entry_t *ap;
766 xfs_acl_entry_t *gap = NULL; 764 xfs_acl_entry_t *gap = NULL;
767 int i, error, nomask = 1; 765 int i, error, nomask = 1;
@@ -776,7 +774,7 @@ xfs_acl_setmode(
776 * mode. The m:: bits take precedence over the g:: bits. 774 * mode. The m:: bits take precedence over the g:: bits.
777 */ 775 */
778 va.va_mask = XFS_AT_MODE; 776 va.va_mask = XFS_AT_MODE;
779 VOP_GETATTR(vp, &va, 0, sys_cred, error); 777 error = bhv_vop_getattr(vp, &va, 0, sys_cred);
780 if (error) 778 if (error)
781 return error; 779 return error;
782 780
@@ -810,8 +808,7 @@ xfs_acl_setmode(
810 if (gap && nomask) 808 if (gap && nomask)
811 va.va_mode |= gap->ae_perm << 3; 809 va.va_mode |= gap->ae_perm << 3;
812 810
813 VOP_SETATTR(vp, &va, 0, sys_cred, error); 811 return bhv_vop_setattr(vp, &va, 0, sys_cred);
814 return error;
815} 812}
816 813
817/* 814/*
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 538d0d65b04c..f853cf1a6270 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -50,7 +50,7 @@ typedef struct xfs_acl {
50#ifdef CONFIG_XFS_POSIX_ACL 50#ifdef CONFIG_XFS_POSIX_ACL
51 51
52struct vattr; 52struct vattr;
53struct vnode; 53struct bhv_vnode;
54struct xfs_inode; 54struct xfs_inode;
55 55
56extern struct kmem_zone *xfs_acl_zone; 56extern struct kmem_zone *xfs_acl_zone;
@@ -58,14 +58,14 @@ extern struct kmem_zone *xfs_acl_zone;
58 (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name)) 58 (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
59#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) 59#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
60 60
61extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *); 61extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *);
62extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); 62extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
63extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *); 63extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *);
64extern int xfs_acl_vhasacl_access(struct vnode *); 64extern int xfs_acl_vhasacl_access(struct bhv_vnode *);
65extern int xfs_acl_vhasacl_default(struct vnode *); 65extern int xfs_acl_vhasacl_default(struct bhv_vnode *);
66extern int xfs_acl_vset(struct vnode *, void *, size_t, int); 66extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int);
67extern int xfs_acl_vget(struct vnode *, void *, size_t, int); 67extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int);
68extern int xfs_acl_vremove(struct vnode *vp, int); 68extern int xfs_acl_vremove(struct bhv_vnode *, int);
69 69
70#define _ACL_TYPE_ACCESS 1 70#define _ACL_TYPE_ACCESS 1
71#define _ACL_TYPE_DEFAULT 2 71#define _ACL_TYPE_DEFAULT 2
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 8558226281c4..eef6763f3a67 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -1862,7 +1860,7 @@ xfs_alloc_fix_freelist(
1862 (pag->pagf_longest - delta) : 1860 (pag->pagf_longest - delta) :
1863 (pag->pagf_flcount > 0 || pag->pagf_longest > 0); 1861 (pag->pagf_flcount > 0 || pag->pagf_longest > 0);
1864 if (args->minlen + args->alignment + args->minalignslop - 1 > longest || 1862 if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
1865 (args->minleft && 1863 (!(flags & XFS_ALLOC_FLAG_FREEING) &&
1866 (int)(pag->pagf_freeblks + pag->pagf_flcount - 1864 (int)(pag->pagf_freeblks + pag->pagf_flcount -
1867 need - args->total) < 1865 need - args->total) <
1868 (int)args->minleft)) { 1866 (int)args->minleft)) {
@@ -1898,7 +1896,7 @@ xfs_alloc_fix_freelist(
1898 longest = (longest > delta) ? (longest - delta) : 1896 longest = (longest > delta) ? (longest - delta) :
1899 (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); 1897 (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
1900 if (args->minlen + args->alignment + args->minalignslop - 1 > longest || 1898 if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
1901 (args->minleft && 1899 (!(flags & XFS_ALLOC_FLAG_FREEING) &&
1902 (int)(be32_to_cpu(agf->agf_freeblks) + 1900 (int)(be32_to_cpu(agf->agf_freeblks) +
1903 be32_to_cpu(agf->agf_flcount) - need - args->total) < 1901 be32_to_cpu(agf->agf_flcount) - need - args->total) <
1904 (int)args->minleft)) { 1902 (int)args->minleft)) {
@@ -1951,8 +1949,14 @@ xfs_alloc_fix_freelist(
1951 * the restrictions correctly. Can happen for free calls 1949 * the restrictions correctly. Can happen for free calls
1952 * on a completely full ag. 1950 * on a completely full ag.
1953 */ 1951 */
1954 if (targs.agbno == NULLAGBLOCK) 1952 if (targs.agbno == NULLAGBLOCK) {
1953 if (!(flags & XFS_ALLOC_FLAG_FREEING)) {
1954 xfs_trans_brelse(tp, agflbp);
1955 args->agbp = NULL;
1956 return 0;
1957 }
1955 break; 1958 break;
1959 }
1956 /* 1960 /*
1957 * Put each allocated block on the list. 1961 * Put each allocated block on the list.
1958 */ 1962 */
@@ -2360,8 +2364,19 @@ xfs_alloc_vextent(
2360 if (args->agno == sagno && 2364 if (args->agno == sagno &&
2361 type == XFS_ALLOCTYPE_START_BNO) 2365 type == XFS_ALLOCTYPE_START_BNO)
2362 args->type = XFS_ALLOCTYPE_THIS_AG; 2366 args->type = XFS_ALLOCTYPE_THIS_AG;
2363 if (++(args->agno) == mp->m_sb.sb_agcount) 2367 /*
2364 args->agno = 0; 2368 * For the first allocation, we can try any AG to get
2369 * space. However, if we already have allocated a
2370 * block, we don't want to try AGs whose number is below
2371 * sagno. Otherwise, we may end up with out-of-order
2372 * locking of AGF, which might cause deadlock.
2373 */
2374 if (++(args->agno) == mp->m_sb.sb_agcount) {
2375 if (args->firstblock != NULLFSBLOCK)
2376 args->agno = sagno;
2377 else
2378 args->agno = 0;
2379 }
2365 /* 2380 /*
2366 * Reached the starting a.g., must either be done 2381 * Reached the starting a.g., must either be done
2367 * or switch to non-trylock mode. 2382 * or switch to non-trylock mode.
@@ -2443,7 +2458,7 @@ xfs_free_extent(
2443 args.minlen = args.minleft = args.minalignslop = 0; 2458 args.minlen = args.minleft = args.minalignslop = 0;
2444 down_read(&args.mp->m_peraglock); 2459 down_read(&args.mp->m_peraglock);
2445 args.pag = &args.mp->m_perag[args.agno]; 2460 args.pag = &args.mp->m_perag[args.agno];
2446 if ((error = xfs_alloc_fix_freelist(&args, 0))) 2461 if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING)))
2447 goto error0; 2462 goto error0;
2448#ifdef DEBUG 2463#ifdef DEBUG
2449 ASSERT(args.agbp != NULL); 2464 ASSERT(args.agbp != NULL);
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 2d1f8928b267..650591f999ae 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -41,6 +41,7 @@ typedef enum xfs_alloctype
41 * Flags for xfs_alloc_fix_freelist. 41 * Flags for xfs_alloc_fix_freelist.
42 */ 42 */
43#define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ 43#define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */
44#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/
44 45
45/* 46/*
46 * Argument structure for xfs_alloc routines. 47 * Argument structure for xfs_alloc routines.
@@ -70,6 +71,7 @@ typedef struct xfs_alloc_arg {
70 char wasfromfl; /* set if allocation is from freelist */ 71 char wasfromfl; /* set if allocation is from freelist */
71 char isfl; /* set if is freelist blocks - !acctg */ 72 char isfl; /* set if is freelist blocks - !acctg */
72 char userdata; /* set if this is user data */ 73 char userdata; /* set if this is user data */
74 xfs_fsblock_t firstblock; /* io first block allocated */
73} xfs_alloc_arg_t; 75} xfs_alloc_arg_t;
74 76
75/* 77/*
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index a1d92da86ccd..7446556e8021 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index b6e1e02bbb28..1a2101043275 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -27,7 +27,6 @@
27#include "xfs_trans.h" 27#include "xfs_trans.h"
28#include "xfs_sb.h" 28#include "xfs_sb.h"
29#include "xfs_ag.h" 29#include "xfs_ag.h"
30#include "xfs_dir.h"
31#include "xfs_dir2.h" 30#include "xfs_dir2.h"
32#include "xfs_dmapi.h" 31#include "xfs_dmapi.h"
33#include "xfs_mount.h" 32#include "xfs_mount.h"
@@ -35,7 +34,6 @@
35#include "xfs_bmap_btree.h" 34#include "xfs_bmap_btree.h"
36#include "xfs_alloc_btree.h" 35#include "xfs_alloc_btree.h"
37#include "xfs_ialloc_btree.h" 36#include "xfs_ialloc_btree.h"
38#include "xfs_dir_sf.h"
39#include "xfs_dir2_sf.h" 37#include "xfs_dir2_sf.h"
40#include "xfs_attr_sf.h" 38#include "xfs_attr_sf.h"
41#include "xfs_dinode.h" 39#include "xfs_dinode.h"
@@ -1910,7 +1908,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)
1910 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, 1908 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
1911 args->rmtblkcnt, 1909 args->rmtblkcnt,
1912 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 1910 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
1913 NULL, 0, map, &nmap, NULL); 1911 NULL, 0, map, &nmap, NULL, NULL);
1914 if (error) 1912 if (error)
1915 return(error); 1913 return(error);
1916 ASSERT(nmap >= 1); 1914 ASSERT(nmap >= 1);
@@ -1988,7 +1986,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
1988 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | 1986 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
1989 XFS_BMAPI_WRITE, 1987 XFS_BMAPI_WRITE,
1990 args->firstblock, args->total, &map, &nmap, 1988 args->firstblock, args->total, &map, &nmap,
1991 args->flist); 1989 args->flist, NULL);
1992 if (!error) { 1990 if (!error) {
1993 error = xfs_bmap_finish(&args->trans, args->flist, 1991 error = xfs_bmap_finish(&args->trans, args->flist,
1994 *args->firstblock, &committed); 1992 *args->firstblock, &committed);
@@ -2039,7 +2037,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
2039 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, 2037 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
2040 args->rmtblkcnt, 2038 args->rmtblkcnt,
2041 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2039 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2042 args->firstblock, 0, &map, &nmap, NULL); 2040 args->firstblock, 0, &map, &nmap,
2041 NULL, NULL);
2043 if (error) { 2042 if (error) {
2044 return(error); 2043 return(error);
2045 } 2044 }
@@ -2104,7 +2103,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
2104 args->rmtblkcnt, 2103 args->rmtblkcnt,
2105 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2104 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2106 args->firstblock, 0, &map, &nmap, 2105 args->firstblock, 0, &map, &nmap,
2107 args->flist); 2106 args->flist, NULL);
2108 if (error) { 2107 if (error) {
2109 return(error); 2108 return(error);
2110 } 2109 }
@@ -2142,7 +2141,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
2142 XFS_BMAP_INIT(args->flist, args->firstblock); 2141 XFS_BMAP_INIT(args->flist, args->firstblock);
2143 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, 2142 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
2144 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2143 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2145 1, args->firstblock, args->flist, &done); 2144 1, args->firstblock, args->flist,
2145 NULL, &done);
2146 if (!error) { 2146 if (!error) {
2147 error = xfs_bmap_finish(&args->trans, args->flist, 2147 error = xfs_bmap_finish(&args->trans, args->flist,
2148 *args->firstblock, &committed); 2148 *args->firstblock, &committed);
@@ -2322,56 +2322,56 @@ xfs_attr_trace_enter(int type, char *where,
2322 2322
2323STATIC int 2323STATIC int
2324posix_acl_access_set( 2324posix_acl_access_set(
2325 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2325 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2326{ 2326{
2327 return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS); 2327 return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
2328} 2328}
2329 2329
2330STATIC int 2330STATIC int
2331posix_acl_access_remove( 2331posix_acl_access_remove(
2332 struct vnode *vp, char *name, int xflags) 2332 bhv_vnode_t *vp, char *name, int xflags)
2333{ 2333{
2334 return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); 2334 return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
2335} 2335}
2336 2336
2337STATIC int 2337STATIC int
2338posix_acl_access_get( 2338posix_acl_access_get(
2339 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2339 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2340{ 2340{
2341 return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS); 2341 return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
2342} 2342}
2343 2343
2344STATIC int 2344STATIC int
2345posix_acl_access_exists( 2345posix_acl_access_exists(
2346 vnode_t *vp) 2346 bhv_vnode_t *vp)
2347{ 2347{
2348 return xfs_acl_vhasacl_access(vp); 2348 return xfs_acl_vhasacl_access(vp);
2349} 2349}
2350 2350
2351STATIC int 2351STATIC int
2352posix_acl_default_set( 2352posix_acl_default_set(
2353 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2353 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2354{ 2354{
2355 return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT); 2355 return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
2356} 2356}
2357 2357
2358STATIC int 2358STATIC int
2359posix_acl_default_get( 2359posix_acl_default_get(
2360 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2360 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2361{ 2361{
2362 return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT); 2362 return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
2363} 2363}
2364 2364
2365STATIC int 2365STATIC int
2366posix_acl_default_remove( 2366posix_acl_default_remove(
2367 struct vnode *vp, char *name, int xflags) 2367 bhv_vnode_t *vp, char *name, int xflags)
2368{ 2368{
2369 return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT); 2369 return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
2370} 2370}
2371 2371
2372STATIC int 2372STATIC int
2373posix_acl_default_exists( 2373posix_acl_default_exists(
2374 vnode_t *vp) 2374 bhv_vnode_t *vp)
2375{ 2375{
2376 return xfs_acl_vhasacl_default(vp); 2376 return xfs_acl_vhasacl_default(vp);
2377} 2377}
@@ -2404,21 +2404,18 @@ STATIC struct attrnames *attr_system_names[] =
2404 2404
2405STATIC int 2405STATIC int
2406attr_generic_set( 2406attr_generic_set(
2407 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2407 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2408{ 2408{
2409 int error; 2409 return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL);
2410
2411 VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error);
2412 return -error;
2413} 2410}
2414 2411
2415STATIC int 2412STATIC int
2416attr_generic_get( 2413attr_generic_get(
2417 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2414 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2418{ 2415{
2419 int error, asize = size; 2416 int error, asize = size;
2420 2417
2421 VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error); 2418 error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL);
2422 if (!error) 2419 if (!error)
2423 return asize; 2420 return asize;
2424 return -error; 2421 return -error;
@@ -2426,12 +2423,9 @@ attr_generic_get(
2426 2423
2427STATIC int 2424STATIC int
2428attr_generic_remove( 2425attr_generic_remove(
2429 struct vnode *vp, char *name, int xflags) 2426 bhv_vnode_t *vp, char *name, int xflags)
2430{ 2427{
2431 int error; 2428 return -bhv_vop_attr_remove(vp, name, xflags, NULL);
2432
2433 VOP_ATTR_REMOVE(vp, name, xflags, NULL, error);
2434 return -error;
2435} 2429}
2436 2430
2437STATIC int 2431STATIC int
@@ -2459,7 +2453,7 @@ attr_generic_listadd(
2459 2453
2460STATIC int 2454STATIC int
2461attr_system_list( 2455attr_system_list(
2462 struct vnode *vp, 2456 bhv_vnode_t *vp,
2463 void *data, 2457 void *data,
2464 size_t size, 2458 size_t size,
2465 ssize_t *result) 2459 ssize_t *result)
@@ -2481,12 +2475,12 @@ attr_system_list(
2481 2475
2482int 2476int
2483attr_generic_list( 2477attr_generic_list(
2484 struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result) 2478 bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result)
2485{ 2479{
2486 attrlist_cursor_kern_t cursor = { 0 }; 2480 attrlist_cursor_kern_t cursor = { 0 };
2487 int error; 2481 int error;
2488 2482
2489 VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error); 2483 error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL);
2490 if (error > 0) 2484 if (error > 0)
2491 return -error; 2485 return -error;
2492 *result = -error; 2486 *result = -error;
@@ -2514,7 +2508,7 @@ attr_lookup_namespace(
2514 */ 2508 */
2515STATIC int 2509STATIC int
2516attr_user_capable( 2510attr_user_capable(
2517 struct vnode *vp, 2511 bhv_vnode_t *vp,
2518 cred_t *cred) 2512 cred_t *cred)
2519{ 2513{
2520 struct inode *inode = vn_to_inode(vp); 2514 struct inode *inode = vn_to_inode(vp);
@@ -2532,7 +2526,7 @@ attr_user_capable(
2532 2526
2533STATIC int 2527STATIC int
2534attr_trusted_capable( 2528attr_trusted_capable(
2535 struct vnode *vp, 2529 bhv_vnode_t *vp,
2536 cred_t *cred) 2530 cred_t *cred)
2537{ 2531{
2538 struct inode *inode = vn_to_inode(vp); 2532 struct inode *inode = vn_to_inode(vp);
@@ -2546,7 +2540,7 @@ attr_trusted_capable(
2546 2540
2547STATIC int 2541STATIC int
2548attr_secure_capable( 2542attr_secure_capable(
2549 struct vnode *vp, 2543 bhv_vnode_t *vp,
2550 cred_t *cred) 2544 cred_t *cred)
2551{ 2545{
2552 return -ENOSECURITY; 2546 return -ENOSECURITY;
@@ -2554,7 +2548,7 @@ attr_secure_capable(
2554 2548
2555STATIC int 2549STATIC int
2556attr_system_set( 2550attr_system_set(
2557 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2551 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2558{ 2552{
2559 attrnames_t *namesp; 2553 attrnames_t *namesp;
2560 int error; 2554 int error;
@@ -2573,7 +2567,7 @@ attr_system_set(
2573 2567
2574STATIC int 2568STATIC int
2575attr_system_get( 2569attr_system_get(
2576 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2570 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2577{ 2571{
2578 attrnames_t *namesp; 2572 attrnames_t *namesp;
2579 2573
@@ -2585,7 +2579,7 @@ attr_system_get(
2585 2579
2586STATIC int 2580STATIC int
2587attr_system_remove( 2581attr_system_remove(
2588 struct vnode *vp, char *name, int xflags) 2582 bhv_vnode_t *vp, char *name, int xflags)
2589{ 2583{
2590 attrnames_t *namesp; 2584 attrnames_t *namesp;
2591 2585
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index b2c7b9fcded3..981633f6c077 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -36,13 +36,13 @@
36 *========================================================================*/ 36 *========================================================================*/
37 37
38struct cred; 38struct cred;
39struct vnode; 39struct bhv_vnode;
40 40
41typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int); 41typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
42typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int); 42typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
43typedef int (*attrremove_t)(struct vnode *, char *, int); 43typedef int (*attrremove_t)(struct bhv_vnode *, char *, int);
44typedef int (*attrexists_t)(struct vnode *); 44typedef int (*attrexists_t)(struct bhv_vnode *);
45typedef int (*attrcapable_t)(struct vnode *, struct cred *); 45typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *);
46 46
47typedef struct attrnames { 47typedef struct attrnames {
48 char * attr_name; 48 char * attr_name;
@@ -63,7 +63,7 @@ extern struct attrnames attr_trusted;
63extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; 63extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
64 64
65extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); 65extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
66extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); 66extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *);
67 67
68#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ 68#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
69#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ 69#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 9462be86aa14..9455051f0120 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -24,7 +24,6 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -34,7 +33,6 @@
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_alloc.h" 34#include "xfs_alloc.h"
36#include "xfs_btree.h" 35#include "xfs_btree.h"
37#include "xfs_dir_sf.h"
38#include "xfs_dir2_sf.h" 36#include "xfs_dir2_sf.h"
39#include "xfs_attr_sf.h" 37#include "xfs_attr_sf.h"
40#include "xfs_dinode.h" 38#include "xfs_dinode.h"
@@ -2990,7 +2988,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
2990 nmap = 1; 2988 nmap = 1;
2991 error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt, 2989 error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,
2992 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2990 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2993 NULL, 0, &map, &nmap, NULL); 2991 NULL, 0, &map, &nmap, NULL, NULL);
2994 if (error) { 2992 if (error) {
2995 return(error); 2993 return(error);
2996 } 2994 }
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 26939d364bc4..3a6137539064 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,13 +24,11 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.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_ialloc_btree.h" 31#include "xfs_ialloc_btree.h"
33#include "xfs_dir_sf.h"
34#include "xfs_dir2_sf.h" 32#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
36#include "xfs_dinode.h" 34#include "xfs_dinode.h"
@@ -40,13 +38,15 @@
40#include "xfs_mount.h" 38#include "xfs_mount.h"
41#include "xfs_ialloc.h" 39#include "xfs_ialloc.h"
42#include "xfs_itable.h" 40#include "xfs_itable.h"
41#include "xfs_dir2_data.h"
42#include "xfs_dir2_leaf.h"
43#include "xfs_dir2_block.h"
43#include "xfs_inode_item.h" 44#include "xfs_inode_item.h"
44#include "xfs_extfree_item.h" 45#include "xfs_extfree_item.h"
45#include "xfs_alloc.h" 46#include "xfs_alloc.h"
46#include "xfs_bmap.h" 47#include "xfs_bmap.h"
47#include "xfs_rtalloc.h" 48#include "xfs_rtalloc.h"
48#include "xfs_error.h" 49#include "xfs_error.h"
49#include "xfs_dir_leaf.h"
50#include "xfs_attr_leaf.h" 50#include "xfs_attr_leaf.h"
51#include "xfs_rw.h" 51#include "xfs_rw.h"
52#include "xfs_quota.h" 52#include "xfs_quota.h"
@@ -101,6 +101,7 @@ xfs_bmap_add_extent(
101 xfs_fsblock_t *first, /* pointer to firstblock variable */ 101 xfs_fsblock_t *first, /* pointer to firstblock variable */
102 xfs_bmap_free_t *flist, /* list of extents to be freed */ 102 xfs_bmap_free_t *flist, /* list of extents to be freed */
103 int *logflagsp, /* inode logging flags */ 103 int *logflagsp, /* inode logging flags */
104 xfs_extdelta_t *delta, /* Change made to incore extents */
104 int whichfork, /* data or attr fork */ 105 int whichfork, /* data or attr fork */
105 int rsvd); /* OK to allocate reserved blocks */ 106 int rsvd); /* OK to allocate reserved blocks */
106 107
@@ -118,6 +119,7 @@ xfs_bmap_add_extent_delay_real(
118 xfs_fsblock_t *first, /* pointer to firstblock variable */ 119 xfs_fsblock_t *first, /* pointer to firstblock variable */
119 xfs_bmap_free_t *flist, /* list of extents to be freed */ 120 xfs_bmap_free_t *flist, /* list of extents to be freed */
120 int *logflagsp, /* inode logging flags */ 121 int *logflagsp, /* inode logging flags */
122 xfs_extdelta_t *delta, /* Change made to incore extents */
121 int rsvd); /* OK to allocate reserved blocks */ 123 int rsvd); /* OK to allocate reserved blocks */
122 124
123/* 125/*
@@ -131,6 +133,7 @@ xfs_bmap_add_extent_hole_delay(
131 xfs_btree_cur_t *cur, /* if null, not a btree */ 133 xfs_btree_cur_t *cur, /* if null, not a btree */
132 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 134 xfs_bmbt_irec_t *new, /* new data to add to file extents */
133 int *logflagsp,/* inode logging flags */ 135 int *logflagsp,/* inode logging flags */
136 xfs_extdelta_t *delta, /* Change made to incore extents */
134 int rsvd); /* OK to allocate reserved blocks */ 137 int rsvd); /* OK to allocate reserved blocks */
135 138
136/* 139/*
@@ -144,6 +147,7 @@ xfs_bmap_add_extent_hole_real(
144 xfs_btree_cur_t *cur, /* if null, not a btree */ 147 xfs_btree_cur_t *cur, /* if null, not a btree */
145 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 148 xfs_bmbt_irec_t *new, /* new data to add to file extents */
146 int *logflagsp, /* inode logging flags */ 149 int *logflagsp, /* inode logging flags */
150 xfs_extdelta_t *delta, /* Change made to incore extents */
147 int whichfork); /* data or attr fork */ 151 int whichfork); /* data or attr fork */
148 152
149/* 153/*
@@ -156,7 +160,8 @@ xfs_bmap_add_extent_unwritten_real(
156 xfs_extnum_t idx, /* extent number to update/insert */ 160 xfs_extnum_t idx, /* extent number to update/insert */
157 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 161 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
158 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 162 xfs_bmbt_irec_t *new, /* new data to add to file extents */
159 int *logflagsp); /* inode logging flags */ 163 int *logflagsp, /* inode logging flags */
164 xfs_extdelta_t *delta); /* Change made to incore extents */
160 165
161/* 166/*
162 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. 167 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
@@ -203,6 +208,7 @@ xfs_bmap_del_extent(
203 xfs_btree_cur_t *cur, /* if null, not a btree */ 208 xfs_btree_cur_t *cur, /* if null, not a btree */
204 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 209 xfs_bmbt_irec_t *new, /* new data to add to file extents */
205 int *logflagsp,/* inode logging flags */ 210 int *logflagsp,/* inode logging flags */
211 xfs_extdelta_t *delta, /* Change made to incore extents */
206 int whichfork, /* data or attr fork */ 212 int whichfork, /* data or attr fork */
207 int rsvd); /* OK to allocate reserved blocks */ 213 int rsvd); /* OK to allocate reserved blocks */
208 214
@@ -510,7 +516,7 @@ xfs_bmap_add_attrfork_local(
510 dargs.total = mp->m_dirblkfsbs; 516 dargs.total = mp->m_dirblkfsbs;
511 dargs.whichfork = XFS_DATA_FORK; 517 dargs.whichfork = XFS_DATA_FORK;
512 dargs.trans = tp; 518 dargs.trans = tp;
513 error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs); 519 error = xfs_dir2_sf_to_block(&dargs);
514 } else 520 } else
515 error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, 521 error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
516 XFS_DATA_FORK); 522 XFS_DATA_FORK);
@@ -530,6 +536,7 @@ xfs_bmap_add_extent(
530 xfs_fsblock_t *first, /* pointer to firstblock variable */ 536 xfs_fsblock_t *first, /* pointer to firstblock variable */
531 xfs_bmap_free_t *flist, /* list of extents to be freed */ 537 xfs_bmap_free_t *flist, /* list of extents to be freed */
532 int *logflagsp, /* inode logging flags */ 538 int *logflagsp, /* inode logging flags */
539 xfs_extdelta_t *delta, /* Change made to incore extents */
533 int whichfork, /* data or attr fork */ 540 int whichfork, /* data or attr fork */
534 int rsvd) /* OK to use reserved data blocks */ 541 int rsvd) /* OK to use reserved data blocks */
535{ 542{
@@ -567,6 +574,15 @@ xfs_bmap_add_extent(
567 logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 574 logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
568 } else 575 } else
569 logflags = 0; 576 logflags = 0;
577 /* DELTA: single new extent */
578 if (delta) {
579 if (delta->xed_startoff > new->br_startoff)
580 delta->xed_startoff = new->br_startoff;
581 if (delta->xed_blockcount <
582 new->br_startoff + new->br_blockcount)
583 delta->xed_blockcount = new->br_startoff +
584 new->br_blockcount;
585 }
570 } 586 }
571 /* 587 /*
572 * Any kind of new delayed allocation goes here. 588 * Any kind of new delayed allocation goes here.
@@ -576,7 +592,7 @@ xfs_bmap_add_extent(
576 ASSERT((cur->bc_private.b.flags & 592 ASSERT((cur->bc_private.b.flags &
577 XFS_BTCUR_BPRV_WASDEL) == 0); 593 XFS_BTCUR_BPRV_WASDEL) == 0);
578 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, 594 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
579 &logflags, rsvd))) 595 &logflags, delta, rsvd)))
580 goto done; 596 goto done;
581 } 597 }
582 /* 598 /*
@@ -587,7 +603,7 @@ xfs_bmap_add_extent(
587 ASSERT((cur->bc_private.b.flags & 603 ASSERT((cur->bc_private.b.flags &
588 XFS_BTCUR_BPRV_WASDEL) == 0); 604 XFS_BTCUR_BPRV_WASDEL) == 0);
589 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, 605 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
590 &logflags, whichfork))) 606 &logflags, delta, whichfork)))
591 goto done; 607 goto done;
592 } else { 608 } else {
593 xfs_bmbt_irec_t prev; /* old extent at offset idx */ 609 xfs_bmbt_irec_t prev; /* old extent at offset idx */
@@ -612,17 +628,17 @@ xfs_bmap_add_extent(
612 XFS_BTCUR_BPRV_WASDEL); 628 XFS_BTCUR_BPRV_WASDEL);
613 if ((error = xfs_bmap_add_extent_delay_real(ip, 629 if ((error = xfs_bmap_add_extent_delay_real(ip,
614 idx, &cur, new, &da_new, first, flist, 630 idx, &cur, new, &da_new, first, flist,
615 &logflags, rsvd))) 631 &logflags, delta, rsvd)))
616 goto done; 632 goto done;
617 } else if (new->br_state == XFS_EXT_NORM) { 633 } else if (new->br_state == XFS_EXT_NORM) {
618 ASSERT(new->br_state == XFS_EXT_NORM); 634 ASSERT(new->br_state == XFS_EXT_NORM);
619 if ((error = xfs_bmap_add_extent_unwritten_real( 635 if ((error = xfs_bmap_add_extent_unwritten_real(
620 ip, idx, &cur, new, &logflags))) 636 ip, idx, &cur, new, &logflags, delta)))
621 goto done; 637 goto done;
622 } else { 638 } else {
623 ASSERT(new->br_state == XFS_EXT_UNWRITTEN); 639 ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
624 if ((error = xfs_bmap_add_extent_unwritten_real( 640 if ((error = xfs_bmap_add_extent_unwritten_real(
625 ip, idx, &cur, new, &logflags))) 641 ip, idx, &cur, new, &logflags, delta)))
626 goto done; 642 goto done;
627 } 643 }
628 ASSERT(*curp == cur || *curp == NULL); 644 ASSERT(*curp == cur || *curp == NULL);
@@ -635,7 +651,7 @@ xfs_bmap_add_extent(
635 ASSERT((cur->bc_private.b.flags & 651 ASSERT((cur->bc_private.b.flags &
636 XFS_BTCUR_BPRV_WASDEL) == 0); 652 XFS_BTCUR_BPRV_WASDEL) == 0);
637 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, 653 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
638 new, &logflags, whichfork))) 654 new, &logflags, delta, whichfork)))
639 goto done; 655 goto done;
640 } 656 }
641 } 657 }
@@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real(
700 xfs_fsblock_t *first, /* pointer to firstblock variable */ 716 xfs_fsblock_t *first, /* pointer to firstblock variable */
701 xfs_bmap_free_t *flist, /* list of extents to be freed */ 717 xfs_bmap_free_t *flist, /* list of extents to be freed */
702 int *logflagsp, /* inode logging flags */ 718 int *logflagsp, /* inode logging flags */
719 xfs_extdelta_t *delta, /* Change made to incore extents */
703 int rsvd) /* OK to use reserved data block allocation */ 720 int rsvd) /* OK to use reserved data block allocation */
704{ 721{
705 xfs_btree_cur_t *cur; /* btree cursor */ 722 xfs_btree_cur_t *cur; /* btree cursor */
@@ -716,8 +733,8 @@ xfs_bmap_add_extent_delay_real(
716 /* left is 0, right is 1, prev is 2 */ 733 /* left is 0, right is 1, prev is 2 */
717 int rval=0; /* return value (logging flags) */ 734 int rval=0; /* return value (logging flags) */
718 int state = 0;/* state bits, accessed thru macros */ 735 int state = 0;/* state bits, accessed thru macros */
719 xfs_filblks_t temp; /* value for dnew calculations */ 736 xfs_filblks_t temp=0; /* value for dnew calculations */
720 xfs_filblks_t temp2; /* value for dnew calculations */ 737 xfs_filblks_t temp2=0;/* value for dnew calculations */
721 int tmp_rval; /* partial logging flags */ 738 int tmp_rval; /* partial logging flags */
722 enum { /* bit number definitions for state */ 739 enum { /* bit number definitions for state */
723 LEFT_CONTIG, RIGHT_CONTIG, 740 LEFT_CONTIG, RIGHT_CONTIG,
@@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real(
839 goto done; 856 goto done;
840 } 857 }
841 *dnew = 0; 858 *dnew = 0;
859 /* DELTA: Three in-core extents are replaced by one. */
860 temp = LEFT.br_startoff;
861 temp2 = LEFT.br_blockcount +
862 PREV.br_blockcount +
863 RIGHT.br_blockcount;
842 break; 864 break;
843 865
844 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 866 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real(
872 goto done; 894 goto done;
873 } 895 }
874 *dnew = 0; 896 *dnew = 0;
897 /* DELTA: Two in-core extents are replaced by one. */
898 temp = LEFT.br_startoff;
899 temp2 = LEFT.br_blockcount +
900 PREV.br_blockcount;
875 break; 901 break;
876 902
877 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 903 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real(
906 goto done; 932 goto done;
907 } 933 }
908 *dnew = 0; 934 *dnew = 0;
935 /* DELTA: Two in-core extents are replaced by one. */
936 temp = PREV.br_startoff;
937 temp2 = PREV.br_blockcount +
938 RIGHT.br_blockcount;
909 break; 939 break;
910 940
911 case MASK2(LEFT_FILLING, RIGHT_FILLING): 941 case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real(
936 ASSERT(i == 1); 966 ASSERT(i == 1);
937 } 967 }
938 *dnew = 0; 968 *dnew = 0;
969 /* DELTA: The in-core extent described by new changed type. */
970 temp = new->br_startoff;
971 temp2 = new->br_blockcount;
939 break; 972 break;
940 973
941 case MASK2(LEFT_FILLING, LEFT_CONTIG): 974 case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -978,6 +1011,10 @@ xfs_bmap_add_extent_delay_real(
978 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, 1011 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,
979 XFS_DATA_FORK); 1012 XFS_DATA_FORK);
980 *dnew = temp; 1013 *dnew = temp;
1014 /* DELTA: The boundary between two in-core extents moved. */
1015 temp = LEFT.br_startoff;
1016 temp2 = LEFT.br_blockcount +
1017 PREV.br_blockcount;
981 break; 1018 break;
982 1019
983 case MASK(LEFT_FILLING): 1020 case MASK(LEFT_FILLING):
@@ -1025,6 +1062,9 @@ xfs_bmap_add_extent_delay_real(
1025 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, 1062 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
1026 XFS_DATA_FORK); 1063 XFS_DATA_FORK);
1027 *dnew = temp; 1064 *dnew = temp;
1065 /* DELTA: One in-core extent is split in two. */
1066 temp = PREV.br_startoff;
1067 temp2 = PREV.br_blockcount;
1028 break; 1068 break;
1029 1069
1030 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1070 case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1067,6 +1107,10 @@ xfs_bmap_add_extent_delay_real(
1067 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, 1107 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
1068 XFS_DATA_FORK); 1108 XFS_DATA_FORK);
1069 *dnew = temp; 1109 *dnew = temp;
1110 /* DELTA: The boundary between two in-core extents moved. */
1111 temp = PREV.br_startoff;
1112 temp2 = PREV.br_blockcount +
1113 RIGHT.br_blockcount;
1070 break; 1114 break;
1071 1115
1072 case MASK(RIGHT_FILLING): 1116 case MASK(RIGHT_FILLING):
@@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real(
1112 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1156 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
1113 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1157 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
1114 *dnew = temp; 1158 *dnew = temp;
1159 /* DELTA: One in-core extent is split in two. */
1160 temp = PREV.br_startoff;
1161 temp2 = PREV.br_blockcount;
1115 break; 1162 break;
1116 1163
1117 case 0: 1164 case 0:
@@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real(
1194 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, 1241 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
1195 XFS_DATA_FORK); 1242 XFS_DATA_FORK);
1196 *dnew = temp + temp2; 1243 *dnew = temp + temp2;
1244 /* DELTA: One in-core extent is split in three. */
1245 temp = PREV.br_startoff;
1246 temp2 = PREV.br_blockcount;
1197 break; 1247 break;
1198 1248
1199 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1249 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real(
1209 ASSERT(0); 1259 ASSERT(0);
1210 } 1260 }
1211 *curp = cur; 1261 *curp = cur;
1262 if (delta) {
1263 temp2 += temp;
1264 if (delta->xed_startoff > temp)
1265 delta->xed_startoff = temp;
1266 if (delta->xed_blockcount < temp2)
1267 delta->xed_blockcount = temp2;
1268 }
1212done: 1269done:
1213 *logflagsp = rval; 1270 *logflagsp = rval;
1214 return error; 1271 return error;
@@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real(
1235 xfs_extnum_t idx, /* extent number to update/insert */ 1292 xfs_extnum_t idx, /* extent number to update/insert */
1236 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 1293 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
1237 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1294 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1238 int *logflagsp) /* inode logging flags */ 1295 int *logflagsp, /* inode logging flags */
1296 xfs_extdelta_t *delta) /* Change made to incore extents */
1239{ 1297{
1240 xfs_btree_cur_t *cur; /* btree cursor */ 1298 xfs_btree_cur_t *cur; /* btree cursor */
1241 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 1299 xfs_bmbt_rec_t *ep; /* extent entry for idx */
@@ -1252,6 +1310,8 @@ xfs_bmap_add_extent_unwritten_real(
1252 /* left is 0, right is 1, prev is 2 */ 1310 /* left is 0, right is 1, prev is 2 */
1253 int rval=0; /* return value (logging flags) */ 1311 int rval=0; /* return value (logging flags) */
1254 int state = 0;/* state bits, accessed thru macros */ 1312 int state = 0;/* state bits, accessed thru macros */
1313 xfs_filblks_t temp=0;
1314 xfs_filblks_t temp2=0;
1255 enum { /* bit number definitions for state */ 1315 enum { /* bit number definitions for state */
1256 LEFT_CONTIG, RIGHT_CONTIG, 1316 LEFT_CONTIG, RIGHT_CONTIG,
1257 LEFT_FILLING, RIGHT_FILLING, 1317 LEFT_FILLING, RIGHT_FILLING,
@@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real(
1380 RIGHT.br_blockcount, LEFT.br_state))) 1440 RIGHT.br_blockcount, LEFT.br_state)))
1381 goto done; 1441 goto done;
1382 } 1442 }
1443 /* DELTA: Three in-core extents are replaced by one. */
1444 temp = LEFT.br_startoff;
1445 temp2 = LEFT.br_blockcount +
1446 PREV.br_blockcount +
1447 RIGHT.br_blockcount;
1383 break; 1448 break;
1384 1449
1385 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 1450 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real(
1419 LEFT.br_state))) 1484 LEFT.br_state)))
1420 goto done; 1485 goto done;
1421 } 1486 }
1487 /* DELTA: Two in-core extents are replaced by one. */
1488 temp = LEFT.br_startoff;
1489 temp2 = LEFT.br_blockcount +
1490 PREV.br_blockcount;
1422 break; 1491 break;
1423 1492
1424 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 1493 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real(
1459 newext))) 1528 newext)))
1460 goto done; 1529 goto done;
1461 } 1530 }
1531 /* DELTA: Two in-core extents are replaced by one. */
1532 temp = PREV.br_startoff;
1533 temp2 = PREV.br_blockcount +
1534 RIGHT.br_blockcount;
1462 break; 1535 break;
1463 1536
1464 case MASK2(LEFT_FILLING, RIGHT_FILLING): 1537 case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real(
1487 newext))) 1560 newext)))
1488 goto done; 1561 goto done;
1489 } 1562 }
1563 /* DELTA: The in-core extent described by new changed type. */
1564 temp = new->br_startoff;
1565 temp2 = new->br_blockcount;
1490 break; 1566 break;
1491 1567
1492 case MASK2(LEFT_FILLING, LEFT_CONTIG): 1568 case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real(
1534 LEFT.br_state)) 1610 LEFT.br_state))
1535 goto done; 1611 goto done;
1536 } 1612 }
1613 /* DELTA: The boundary between two in-core extents moved. */
1614 temp = LEFT.br_startoff;
1615 temp2 = LEFT.br_blockcount +
1616 PREV.br_blockcount;
1537 break; 1617 break;
1538 1618
1539 case MASK(LEFT_FILLING): 1619 case MASK(LEFT_FILLING):
@@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real(
1574 goto done; 1654 goto done;
1575 ASSERT(i == 1); 1655 ASSERT(i == 1);
1576 } 1656 }
1657 /* DELTA: One in-core extent is split in two. */
1658 temp = PREV.br_startoff;
1659 temp2 = PREV.br_blockcount;
1577 break; 1660 break;
1578 1661
1579 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1662 case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real(
1617 newext))) 1700 newext)))
1618 goto done; 1701 goto done;
1619 } 1702 }
1703 /* DELTA: The boundary between two in-core extents moved. */
1704 temp = PREV.br_startoff;
1705 temp2 = PREV.br_blockcount +
1706 RIGHT.br_blockcount;
1620 break; 1707 break;
1621 1708
1622 case MASK(RIGHT_FILLING): 1709 case MASK(RIGHT_FILLING):
@@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real(
1657 goto done; 1744 goto done;
1658 ASSERT(i == 1); 1745 ASSERT(i == 1);
1659 } 1746 }
1747 /* DELTA: One in-core extent is split in two. */
1748 temp = PREV.br_startoff;
1749 temp2 = PREV.br_blockcount;
1660 break; 1750 break;
1661 1751
1662 case 0: 1752 case 0:
@@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real(
1710 goto done; 1800 goto done;
1711 ASSERT(i == 1); 1801 ASSERT(i == 1);
1712 } 1802 }
1803 /* DELTA: One in-core extent is split in three. */
1804 temp = PREV.br_startoff;
1805 temp2 = PREV.br_blockcount;
1713 break; 1806 break;
1714 1807
1715 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1808 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real(
1725 ASSERT(0); 1818 ASSERT(0);
1726 } 1819 }
1727 *curp = cur; 1820 *curp = cur;
1821 if (delta) {
1822 temp2 += temp;
1823 if (delta->xed_startoff > temp)
1824 delta->xed_startoff = temp;
1825 if (delta->xed_blockcount < temp2)
1826 delta->xed_blockcount = temp2;
1827 }
1728done: 1828done:
1729 *logflagsp = rval; 1829 *logflagsp = rval;
1730 return error; 1830 return error;
@@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay(
1753 xfs_btree_cur_t *cur, /* if null, not a btree */ 1853 xfs_btree_cur_t *cur, /* if null, not a btree */
1754 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1854 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1755 int *logflagsp, /* inode logging flags */ 1855 int *logflagsp, /* inode logging flags */
1856 xfs_extdelta_t *delta, /* Change made to incore extents */
1756 int rsvd) /* OK to allocate reserved blocks */ 1857 int rsvd) /* OK to allocate reserved blocks */
1757{ 1858{
1758 xfs_bmbt_rec_t *ep; /* extent record for idx */ 1859 xfs_bmbt_rec_t *ep; /* extent record for idx */
@@ -1765,7 +1866,8 @@ xfs_bmap_add_extent_hole_delay(
1765 xfs_filblks_t oldlen=0; /* old indirect size */ 1866 xfs_filblks_t oldlen=0; /* old indirect size */
1766 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 1867 xfs_bmbt_irec_t right; /* right neighbor extent entry */
1767 int state; /* state bits, accessed thru macros */ 1868 int state; /* state bits, accessed thru macros */
1768 xfs_filblks_t temp; /* temp for indirect calculations */ 1869 xfs_filblks_t temp=0; /* temp for indirect calculations */
1870 xfs_filblks_t temp2=0;
1769 enum { /* bit number definitions for state */ 1871 enum { /* bit number definitions for state */
1770 LEFT_CONTIG, RIGHT_CONTIG, 1872 LEFT_CONTIG, RIGHT_CONTIG,
1771 LEFT_DELAY, RIGHT_DELAY, 1873 LEFT_DELAY, RIGHT_DELAY,
@@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay(
1844 XFS_DATA_FORK); 1946 XFS_DATA_FORK);
1845 xfs_iext_remove(ifp, idx, 1); 1947 xfs_iext_remove(ifp, idx, 1);
1846 ip->i_df.if_lastex = idx - 1; 1948 ip->i_df.if_lastex = idx - 1;
1949 /* DELTA: Two in-core extents were replaced by one. */
1950 temp2 = temp;
1951 temp = left.br_startoff;
1847 break; 1952 break;
1848 1953
1849 case MASK(LEFT_CONTIG): 1954 case MASK(LEFT_CONTIG):
@@ -1864,6 +1969,9 @@ xfs_bmap_add_extent_hole_delay(
1864 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, 1969 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
1865 XFS_DATA_FORK); 1970 XFS_DATA_FORK);
1866 ip->i_df.if_lastex = idx - 1; 1971 ip->i_df.if_lastex = idx - 1;
1972 /* DELTA: One in-core extent grew into a hole. */
1973 temp2 = temp;
1974 temp = left.br_startoff;
1867 break; 1975 break;
1868 1976
1869 case MASK(RIGHT_CONTIG): 1977 case MASK(RIGHT_CONTIG):
@@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay(
1881 NULLSTARTBLOCK((int)newlen), temp, right.br_state); 1989 NULLSTARTBLOCK((int)newlen), temp, right.br_state);
1882 xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK); 1990 xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
1883 ip->i_df.if_lastex = idx; 1991 ip->i_df.if_lastex = idx;
1992 /* DELTA: One in-core extent grew into a hole. */
1993 temp2 = temp;
1994 temp = new->br_startoff;
1884 break; 1995 break;
1885 1996
1886 case 0: 1997 case 0:
@@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay(
1894 XFS_DATA_FORK); 2005 XFS_DATA_FORK);
1895 xfs_iext_insert(ifp, idx, 1, new); 2006 xfs_iext_insert(ifp, idx, 1, new);
1896 ip->i_df.if_lastex = idx; 2007 ip->i_df.if_lastex = idx;
2008 /* DELTA: A new in-core extent was added in a hole. */
2009 temp2 = new->br_blockcount;
2010 temp = new->br_startoff;
1897 break; 2011 break;
1898 } 2012 }
1899 if (oldlen != newlen) { 2013 if (oldlen != newlen) {
@@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay(
1904 * Nothing to do for disk quota accounting here. 2018 * Nothing to do for disk quota accounting here.
1905 */ 2019 */
1906 } 2020 }
2021 if (delta) {
2022 temp2 += temp;
2023 if (delta->xed_startoff > temp)
2024 delta->xed_startoff = temp;
2025 if (delta->xed_blockcount < temp2)
2026 delta->xed_blockcount = temp2;
2027 }
1907 *logflagsp = 0; 2028 *logflagsp = 0;
1908 return 0; 2029 return 0;
1909#undef MASK 2030#undef MASK
@@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real(
1925 xfs_btree_cur_t *cur, /* if null, not a btree */ 2046 xfs_btree_cur_t *cur, /* if null, not a btree */
1926 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 2047 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1927 int *logflagsp, /* inode logging flags */ 2048 int *logflagsp, /* inode logging flags */
2049 xfs_extdelta_t *delta, /* Change made to incore extents */
1928 int whichfork) /* data or attr fork */ 2050 int whichfork) /* data or attr fork */
1929{ 2051{
1930 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ 2052 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */
@@ -1936,7 +2058,10 @@ xfs_bmap_add_extent_hole_real(
1936 xfs_ifork_t *ifp; /* inode fork pointer */ 2058 xfs_ifork_t *ifp; /* inode fork pointer */
1937 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 2059 xfs_bmbt_irec_t left; /* left neighbor extent entry */
1938 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 2060 xfs_bmbt_irec_t right; /* right neighbor extent entry */
2061 int rval=0; /* return value (logging flags) */
1939 int state; /* state bits, accessed thru macros */ 2062 int state; /* state bits, accessed thru macros */
2063 xfs_filblks_t temp=0;
2064 xfs_filblks_t temp2=0;
1940 enum { /* bit number definitions for state */ 2065 enum { /* bit number definitions for state */
1941 LEFT_CONTIG, RIGHT_CONTIG, 2066 LEFT_CONTIG, RIGHT_CONTIG,
1942 LEFT_DELAY, RIGHT_DELAY, 2067 LEFT_DELAY, RIGHT_DELAY,
@@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real(
1993 left.br_blockcount + new->br_blockcount + 2118 left.br_blockcount + new->br_blockcount +
1994 right.br_blockcount <= MAXEXTLEN)); 2119 right.br_blockcount <= MAXEXTLEN));
1995 2120
2121 error = 0;
1996 /* 2122 /*
1997 * Select which case we're in here, and implement it. 2123 * Select which case we're in here, and implement it.
1998 */ 2124 */
@@ -2018,25 +2144,35 @@ xfs_bmap_add_extent_hole_real(
2018 XFS_IFORK_NEXT_SET(ip, whichfork, 2144 XFS_IFORK_NEXT_SET(ip, whichfork,
2019 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 2145 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
2020 if (cur == NULL) { 2146 if (cur == NULL) {
2021 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2147 rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
2022 return 0; 2148 } else {
2149 rval = XFS_ILOG_CORE;
2150 if ((error = xfs_bmbt_lookup_eq(cur,
2151 right.br_startoff,
2152 right.br_startblock,
2153 right.br_blockcount, &i)))
2154 goto done;
2155 ASSERT(i == 1);
2156 if ((error = xfs_bmbt_delete(cur, &i)))
2157 goto done;
2158 ASSERT(i == 1);
2159 if ((error = xfs_bmbt_decrement(cur, 0, &i)))
2160 goto done;
2161 ASSERT(i == 1);
2162 if ((error = xfs_bmbt_update(cur, left.br_startoff,
2163 left.br_startblock,
2164 left.br_blockcount +
2165 new->br_blockcount +
2166 right.br_blockcount,
2167 left.br_state)))
2168 goto done;
2023 } 2169 }
2024 *logflagsp = XFS_ILOG_CORE; 2170 /* DELTA: Two in-core extents were replaced by one. */
2025 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2171 temp = left.br_startoff;
2026 right.br_startblock, right.br_blockcount, &i))) 2172 temp2 = left.br_blockcount +
2027 return error; 2173 new->br_blockcount +
2028 ASSERT(i == 1); 2174 right.br_blockcount;
2029 if ((error = xfs_bmbt_delete(cur, &i))) 2175 break;
2030 return error;
2031 ASSERT(i == 1);
2032 if ((error = xfs_bmbt_decrement(cur, 0, &i)))
2033 return error;
2034 ASSERT(i == 1);
2035 error = xfs_bmbt_update(cur, left.br_startoff,
2036 left.br_startblock,
2037 left.br_blockcount + new->br_blockcount +
2038 right.br_blockcount, left.br_state);
2039 return error;
2040 2176
2041 case MASK(LEFT_CONTIG): 2177 case MASK(LEFT_CONTIG):
2042 /* 2178 /*
@@ -2050,19 +2186,27 @@ xfs_bmap_add_extent_hole_real(
2050 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); 2186 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
2051 ifp->if_lastex = idx - 1; 2187 ifp->if_lastex = idx - 1;
2052 if (cur == NULL) { 2188 if (cur == NULL) {
2053 *logflagsp = XFS_ILOG_FEXT(whichfork); 2189 rval = XFS_ILOG_FEXT(whichfork);
2054 return 0; 2190 } else {
2191 rval = 0;
2192 if ((error = xfs_bmbt_lookup_eq(cur,
2193 left.br_startoff,
2194 left.br_startblock,
2195 left.br_blockcount, &i)))
2196 goto done;
2197 ASSERT(i == 1);
2198 if ((error = xfs_bmbt_update(cur, left.br_startoff,
2199 left.br_startblock,
2200 left.br_blockcount +
2201 new->br_blockcount,
2202 left.br_state)))
2203 goto done;
2055 } 2204 }
2056 *logflagsp = 0; 2205 /* DELTA: One in-core extent grew. */
2057 if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff, 2206 temp = left.br_startoff;
2058 left.br_startblock, left.br_blockcount, &i))) 2207 temp2 = left.br_blockcount +
2059 return error; 2208 new->br_blockcount;
2060 ASSERT(i == 1); 2209 break;
2061 error = xfs_bmbt_update(cur, left.br_startoff,
2062 left.br_startblock,
2063 left.br_blockcount + new->br_blockcount,
2064 left.br_state);
2065 return error;
2066 2210
2067 case MASK(RIGHT_CONTIG): 2211 case MASK(RIGHT_CONTIG):
2068 /* 2212 /*
@@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real(
2077 xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork); 2221 xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
2078 ifp->if_lastex = idx; 2222 ifp->if_lastex = idx;
2079 if (cur == NULL) { 2223 if (cur == NULL) {
2080 *logflagsp = XFS_ILOG_FEXT(whichfork); 2224 rval = XFS_ILOG_FEXT(whichfork);
2081 return 0; 2225 } else {
2226 rval = 0;
2227 if ((error = xfs_bmbt_lookup_eq(cur,
2228 right.br_startoff,
2229 right.br_startblock,
2230 right.br_blockcount, &i)))
2231 goto done;
2232 ASSERT(i == 1);
2233 if ((error = xfs_bmbt_update(cur, new->br_startoff,
2234 new->br_startblock,
2235 new->br_blockcount +
2236 right.br_blockcount,
2237 right.br_state)))
2238 goto done;
2082 } 2239 }
2083 *logflagsp = 0; 2240 /* DELTA: One in-core extent grew. */
2084 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2241 temp = new->br_startoff;
2085 right.br_startblock, right.br_blockcount, &i))) 2242 temp2 = new->br_blockcount +
2086 return error; 2243 right.br_blockcount;
2087 ASSERT(i == 1); 2244 break;
2088 error = xfs_bmbt_update(cur, new->br_startoff,
2089 new->br_startblock,
2090 new->br_blockcount + right.br_blockcount,
2091 right.br_state);
2092 return error;
2093 2245
2094 case 0: 2246 case 0:
2095 /* 2247 /*
@@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real(
2104 XFS_IFORK_NEXT_SET(ip, whichfork, 2256 XFS_IFORK_NEXT_SET(ip, whichfork,
2105 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 2257 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
2106 if (cur == NULL) { 2258 if (cur == NULL) {
2107 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2259 rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
2108 return 0; 2260 } else {
2261 rval = XFS_ILOG_CORE;
2262 if ((error = xfs_bmbt_lookup_eq(cur,
2263 new->br_startoff,
2264 new->br_startblock,
2265 new->br_blockcount, &i)))
2266 goto done;
2267 ASSERT(i == 0);
2268 cur->bc_rec.b.br_state = new->br_state;
2269 if ((error = xfs_bmbt_insert(cur, &i)))
2270 goto done;
2271 ASSERT(i == 1);
2109 } 2272 }
2110 *logflagsp = XFS_ILOG_CORE; 2273 /* DELTA: A new extent was added in a hole. */
2111 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 2274 temp = new->br_startoff;
2112 new->br_startblock, new->br_blockcount, &i))) 2275 temp2 = new->br_blockcount;
2113 return error; 2276 break;
2114 ASSERT(i == 0); 2277 }
2115 cur->bc_rec.b.br_state = new->br_state; 2278 if (delta) {
2116 if ((error = xfs_bmbt_insert(cur, &i))) 2279 temp2 += temp;
2117 return error; 2280 if (delta->xed_startoff > temp)
2118 ASSERT(i == 1); 2281 delta->xed_startoff = temp;
2119 return 0; 2282 if (delta->xed_blockcount < temp2)
2283 delta->xed_blockcount = temp2;
2120 } 2284 }
2285done:
2286 *logflagsp = rval;
2287 return error;
2121#undef MASK 2288#undef MASK
2122#undef MASK2 2289#undef MASK2
2123#undef STATE_SET 2290#undef STATE_SET
2124#undef STATE_TEST 2291#undef STATE_TEST
2125#undef STATE_SET_TEST 2292#undef STATE_SET_TEST
2126#undef SWITCH_STATE 2293#undef SWITCH_STATE
2127 /* NOTREACHED */
2128 ASSERT(0);
2129 return 0; /* keep gcc quite */
2130} 2294}
2131 2295
2132/* 2296/*
@@ -2598,6 +2762,7 @@ xfs_bmap_btalloc(
2598 args.mp = mp; 2762 args.mp = mp;
2599 args.fsbno = ap->rval; 2763 args.fsbno = ap->rval;
2600 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); 2764 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
2765 args.firstblock = ap->firstblock;
2601 blen = 0; 2766 blen = 0;
2602 if (nullfb) { 2767 if (nullfb) {
2603 args.type = XFS_ALLOCTYPE_START_BNO; 2768 args.type = XFS_ALLOCTYPE_START_BNO;
@@ -2657,7 +2822,7 @@ xfs_bmap_btalloc(
2657 else 2822 else
2658 args.minlen = ap->alen; 2823 args.minlen = ap->alen;
2659 } else if (ap->low) { 2824 } else if (ap->low) {
2660 args.type = XFS_ALLOCTYPE_FIRST_AG; 2825 args.type = XFS_ALLOCTYPE_START_BNO;
2661 args.total = args.minlen = ap->minlen; 2826 args.total = args.minlen = ap->minlen;
2662 } else { 2827 } else {
2663 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2828 args.type = XFS_ALLOCTYPE_NEAR_BNO;
@@ -2669,7 +2834,7 @@ xfs_bmap_btalloc(
2669 args.prod = ap->ip->i_d.di_extsize; 2834 args.prod = ap->ip->i_d.di_extsize;
2670 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) 2835 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
2671 args.mod = (xfs_extlen_t)(args.prod - args.mod); 2836 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2672 } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) { 2837 } else if (mp->m_sb.sb_blocksize >= NBPP) {
2673 args.prod = 1; 2838 args.prod = 1;
2674 args.mod = 0; 2839 args.mod = 0;
2675 } else { 2840 } else {
@@ -2885,6 +3050,7 @@ xfs_bmap_del_extent(
2885 xfs_btree_cur_t *cur, /* if null, not a btree */ 3050 xfs_btree_cur_t *cur, /* if null, not a btree */
2886 xfs_bmbt_irec_t *del, /* data to remove from extents */ 3051 xfs_bmbt_irec_t *del, /* data to remove from extents */
2887 int *logflagsp, /* inode logging flags */ 3052 int *logflagsp, /* inode logging flags */
3053 xfs_extdelta_t *delta, /* Change made to incore extents */
2888 int whichfork, /* data or attr fork */ 3054 int whichfork, /* data or attr fork */
2889 int rsvd) /* OK to allocate reserved blocks */ 3055 int rsvd) /* OK to allocate reserved blocks */
2890{ 3056{
@@ -3193,6 +3359,14 @@ xfs_bmap_del_extent(
3193 if (da_old > da_new) 3359 if (da_old > da_new)
3194 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), 3360 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
3195 rsvd); 3361 rsvd);
3362 if (delta) {
3363 /* DELTA: report the original extent. */
3364 if (delta->xed_startoff > got.br_startoff)
3365 delta->xed_startoff = got.br_startoff;
3366 if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
3367 delta->xed_blockcount = got.br_startoff +
3368 got.br_blockcount;
3369 }
3196done: 3370done:
3197 *logflagsp = flags; 3371 *logflagsp = flags;
3198 return error; 3372 return error;
@@ -3279,6 +3453,7 @@ xfs_bmap_extents_to_btree(
3279 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); 3453 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
3280 args.tp = tp; 3454 args.tp = tp;
3281 args.mp = mp; 3455 args.mp = mp;
3456 args.firstblock = *firstblock;
3282 if (*firstblock == NULLFSBLOCK) { 3457 if (*firstblock == NULLFSBLOCK) {
3283 args.type = XFS_ALLOCTYPE_START_BNO; 3458 args.type = XFS_ALLOCTYPE_START_BNO;
3284 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); 3459 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
@@ -3414,6 +3589,7 @@ xfs_bmap_local_to_extents(
3414 3589
3415 args.tp = tp; 3590 args.tp = tp;
3416 args.mp = ip->i_mount; 3591 args.mp = ip->i_mount;
3592 args.firstblock = *firstblock;
3417 ASSERT((ifp->if_flags & 3593 ASSERT((ifp->if_flags &
3418 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE); 3594 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
3419 /* 3595 /*
@@ -3753,7 +3929,7 @@ xfs_bunmap_trace(
3753 if (ip->i_rwtrace == NULL) 3929 if (ip->i_rwtrace == NULL)
3754 return; 3930 return;
3755 ktrace_enter(ip->i_rwtrace, 3931 ktrace_enter(ip->i_rwtrace,
3756 (void *)(__psint_t)XFS_BUNMAPI, 3932 (void *)(__psint_t)XFS_BUNMAP,
3757 (void *)ip, 3933 (void *)ip,
3758 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff), 3934 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
3759 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), 3935 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
@@ -4087,8 +4263,8 @@ xfs_bmap_finish(
4087 if (!XFS_FORCED_SHUTDOWN(mp)) 4263 if (!XFS_FORCED_SHUTDOWN(mp))
4088 xfs_force_shutdown(mp, 4264 xfs_force_shutdown(mp,
4089 (error == EFSCORRUPTED) ? 4265 (error == EFSCORRUPTED) ?
4090 XFS_CORRUPT_INCORE : 4266 SHUTDOWN_CORRUPT_INCORE :
4091 XFS_METADATA_IO_ERROR); 4267 SHUTDOWN_META_IO_ERROR);
4092 return error; 4268 return error;
4093 } 4269 }
4094 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock, 4270 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
@@ -4538,7 +4714,8 @@ xfs_bmapi(
4538 xfs_extlen_t total, /* total blocks needed */ 4714 xfs_extlen_t total, /* total blocks needed */
4539 xfs_bmbt_irec_t *mval, /* output: map values */ 4715 xfs_bmbt_irec_t *mval, /* output: map values */
4540 int *nmap, /* i/o: mval size/count */ 4716 int *nmap, /* i/o: mval size/count */
4541 xfs_bmap_free_t *flist) /* i/o: list extents to free */ 4717 xfs_bmap_free_t *flist, /* i/o: list extents to free */
4718 xfs_extdelta_t *delta) /* o: change made to incore extents */
4542{ 4719{
4543 xfs_fsblock_t abno; /* allocated block number */ 4720 xfs_fsblock_t abno; /* allocated block number */
4544 xfs_extlen_t alen; /* allocated extent length */ 4721 xfs_extlen_t alen; /* allocated extent length */
@@ -4650,6 +4827,10 @@ xfs_bmapi(
4650 end = bno + len; 4827 end = bno + len;
4651 obno = bno; 4828 obno = bno;
4652 bma.ip = NULL; 4829 bma.ip = NULL;
4830 if (delta) {
4831 delta->xed_startoff = NULLFILEOFF;
4832 delta->xed_blockcount = 0;
4833 }
4653 while (bno < end && n < *nmap) { 4834 while (bno < end && n < *nmap) {
4654 /* 4835 /*
4655 * Reading past eof, act as though there's a hole 4836 * Reading past eof, act as though there's a hole
@@ -4886,8 +5067,8 @@ xfs_bmapi(
4886 got.br_state = XFS_EXT_UNWRITTEN; 5067 got.br_state = XFS_EXT_UNWRITTEN;
4887 } 5068 }
4888 error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 5069 error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
4889 firstblock, flist, &tmp_logflags, whichfork, 5070 firstblock, flist, &tmp_logflags, delta,
4890 (flags & XFS_BMAPI_RSVBLOCKS)); 5071 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4891 logflags |= tmp_logflags; 5072 logflags |= tmp_logflags;
4892 if (error) 5073 if (error)
4893 goto error0; 5074 goto error0;
@@ -4983,8 +5164,8 @@ xfs_bmapi(
4983 } 5164 }
4984 mval->br_state = XFS_EXT_NORM; 5165 mval->br_state = XFS_EXT_NORM;
4985 error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 5166 error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
4986 firstblock, flist, &tmp_logflags, whichfork, 5167 firstblock, flist, &tmp_logflags, delta,
4987 (flags & XFS_BMAPI_RSVBLOCKS)); 5168 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4988 logflags |= tmp_logflags; 5169 logflags |= tmp_logflags;
4989 if (error) 5170 if (error)
4990 goto error0; 5171 goto error0;
@@ -5073,7 +5254,14 @@ xfs_bmapi(
5073 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || 5254 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
5074 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); 5255 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
5075 error = 0; 5256 error = 0;
5076 5257 if (delta && delta->xed_startoff != NULLFILEOFF) {
5258 /* A change was actually made.
5259 * Note that delta->xed_blockount is an offset at this
5260 * point and needs to be converted to a block count.
5261 */
5262 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5263 delta->xed_blockcount -= delta->xed_startoff;
5264 }
5077error0: 5265error0:
5078 /* 5266 /*
5079 * Log everything. Do this after conversion, there's no point in 5267 * Log everything. Do this after conversion, there's no point in
@@ -5185,6 +5373,8 @@ xfs_bunmapi(
5185 xfs_fsblock_t *firstblock, /* first allocated block 5373 xfs_fsblock_t *firstblock, /* first allocated block
5186 controls a.g. for allocs */ 5374 controls a.g. for allocs */
5187 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 5375 xfs_bmap_free_t *flist, /* i/o: list extents to free */
5376 xfs_extdelta_t *delta, /* o: change made to incore
5377 extents */
5188 int *done) /* set if not done yet */ 5378 int *done) /* set if not done yet */
5189{ 5379{
5190 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5380 xfs_btree_cur_t *cur; /* bmap btree cursor */
@@ -5242,6 +5432,10 @@ xfs_bunmapi(
5242 bno = start + len - 1; 5432 bno = start + len - 1;
5243 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 5433 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
5244 &prev); 5434 &prev);
5435 if (delta) {
5436 delta->xed_startoff = NULLFILEOFF;
5437 delta->xed_blockcount = 0;
5438 }
5245 /* 5439 /*
5246 * Check to see if the given block number is past the end of the 5440 * Check to see if the given block number is past the end of the
5247 * file, back up to the last block if so... 5441 * file, back up to the last block if so...
@@ -5340,7 +5534,8 @@ xfs_bunmapi(
5340 } 5534 }
5341 del.br_state = XFS_EXT_UNWRITTEN; 5535 del.br_state = XFS_EXT_UNWRITTEN;
5342 error = xfs_bmap_add_extent(ip, lastx, &cur, &del, 5536 error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
5343 firstblock, flist, &logflags, XFS_DATA_FORK, 0); 5537 firstblock, flist, &logflags, delta,
5538 XFS_DATA_FORK, 0);
5344 if (error) 5539 if (error)
5345 goto error0; 5540 goto error0;
5346 goto nodelete; 5541 goto nodelete;
@@ -5394,7 +5589,7 @@ xfs_bunmapi(
5394 prev.br_state = XFS_EXT_UNWRITTEN; 5589 prev.br_state = XFS_EXT_UNWRITTEN;
5395 error = xfs_bmap_add_extent(ip, lastx - 1, &cur, 5590 error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
5396 &prev, firstblock, flist, &logflags, 5591 &prev, firstblock, flist, &logflags,
5397 XFS_DATA_FORK, 0); 5592 delta, XFS_DATA_FORK, 0);
5398 if (error) 5593 if (error)
5399 goto error0; 5594 goto error0;
5400 goto nodelete; 5595 goto nodelete;
@@ -5403,7 +5598,7 @@ xfs_bunmapi(
5403 del.br_state = XFS_EXT_UNWRITTEN; 5598 del.br_state = XFS_EXT_UNWRITTEN;
5404 error = xfs_bmap_add_extent(ip, lastx, &cur, 5599 error = xfs_bmap_add_extent(ip, lastx, &cur,
5405 &del, firstblock, flist, &logflags, 5600 &del, firstblock, flist, &logflags,
5406 XFS_DATA_FORK, 0); 5601 delta, XFS_DATA_FORK, 0);
5407 if (error) 5602 if (error)
5408 goto error0; 5603 goto error0;
5409 goto nodelete; 5604 goto nodelete;
@@ -5456,7 +5651,7 @@ xfs_bunmapi(
5456 goto error0; 5651 goto error0;
5457 } 5652 }
5458 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, 5653 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
5459 &tmp_logflags, whichfork, rsvd); 5654 &tmp_logflags, delta, whichfork, rsvd);
5460 logflags |= tmp_logflags; 5655 logflags |= tmp_logflags;
5461 if (error) 5656 if (error)
5462 goto error0; 5657 goto error0;
@@ -5513,6 +5708,14 @@ nodelete:
5513 ASSERT(ifp->if_ext_max == 5708 ASSERT(ifp->if_ext_max ==
5514 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5709 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
5515 error = 0; 5710 error = 0;
5711 if (delta && delta->xed_startoff != NULLFILEOFF) {
5712 /* A change was actually made.
5713 * Note that delta->xed_blockount is an offset at this
5714 * point and needs to be converted to a block count.
5715 */
5716 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5717 delta->xed_blockcount -= delta->xed_startoff;
5718 }
5516error0: 5719error0:
5517 /* 5720 /*
5518 * Log everything. Do this after conversion, there's no point in 5721 * Log everything. Do this after conversion, there's no point in
@@ -5556,7 +5759,7 @@ xfs_getbmap(
5556 __int64_t fixlen; /* length for -1 case */ 5759 __int64_t fixlen; /* length for -1 case */
5557 int i; /* extent number */ 5760 int i; /* extent number */
5558 xfs_inode_t *ip; /* xfs incore inode pointer */ 5761 xfs_inode_t *ip; /* xfs incore inode pointer */
5559 vnode_t *vp; /* corresponding vnode */ 5762 bhv_vnode_t *vp; /* corresponding vnode */
5560 int lock; /* lock state */ 5763 int lock; /* lock state */
5561 xfs_bmbt_irec_t *map; /* buffer for user's data */ 5764 xfs_bmbt_irec_t *map; /* buffer for user's data */
5562 xfs_mount_t *mp; /* file system mount point */ 5765 xfs_mount_t *mp; /* file system mount point */
@@ -5653,7 +5856,7 @@ xfs_getbmap(
5653 5856
5654 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) { 5857 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
5655 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ 5858 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
5656 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); 5859 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
5657 } 5860 }
5658 5861
5659 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); 5862 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
@@ -5689,7 +5892,8 @@ xfs_getbmap(
5689 nmap = (nexleft > subnex) ? subnex : nexleft; 5892 nmap = (nexleft > subnex) ? subnex : nexleft;
5690 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), 5893 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
5691 XFS_BB_TO_FSB(mp, bmv->bmv_length), 5894 XFS_BB_TO_FSB(mp, bmv->bmv_length),
5692 bmapi_flags, NULL, 0, map, &nmap, NULL); 5895 bmapi_flags, NULL, 0, map, &nmap,
5896 NULL, NULL);
5693 if (error) 5897 if (error)
5694 goto unlock_and_return; 5898 goto unlock_and_return;
5695 ASSERT(nmap <= subnex); 5899 ASSERT(nmap <= subnex);
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 8e0d73d9ccc4..80e93409b78d 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -26,6 +26,20 @@ struct xfs_mount;
26struct xfs_trans; 26struct xfs_trans;
27 27
28/* 28/*
29 * DELTA: describe a change to the in-core extent list.
30 *
31 * Internally the use of xed_blockount is somewhat funky.
32 * xed_blockcount contains an offset much of the time because this
33 * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are
34 * the same underlying type).
35 */
36typedef struct xfs_extdelta
37{
38 xfs_fileoff_t xed_startoff; /* offset of range */
39 xfs_filblks_t xed_blockcount; /* blocks in range */
40} xfs_extdelta_t;
41
42/*
29 * List of extents to be free "later". 43 * List of extents to be free "later".
30 * The list is kept sorted on xbf_startblock. 44 * The list is kept sorted on xbf_startblock.
31 */ 45 */
@@ -275,7 +289,9 @@ xfs_bmapi(
275 xfs_extlen_t total, /* total blocks needed */ 289 xfs_extlen_t total, /* total blocks needed */
276 struct xfs_bmbt_irec *mval, /* output: map values */ 290 struct xfs_bmbt_irec *mval, /* output: map values */
277 int *nmap, /* i/o: mval size/count */ 291 int *nmap, /* i/o: mval size/count */
278 xfs_bmap_free_t *flist); /* i/o: list extents to free */ 292 xfs_bmap_free_t *flist, /* i/o: list extents to free */
293 xfs_extdelta_t *delta); /* o: change made to incore
294 extents */
279 295
280/* 296/*
281 * Map file blocks to filesystem blocks, simple version. 297 * Map file blocks to filesystem blocks, simple version.
@@ -309,6 +325,8 @@ xfs_bunmapi(
309 xfs_fsblock_t *firstblock, /* first allocated block 325 xfs_fsblock_t *firstblock, /* first allocated block
310 controls a.g. for allocs */ 326 controls a.g. for allocs */
311 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 327 xfs_bmap_free_t *flist, /* i/o: list extents to free */
328 xfs_extdelta_t *delta, /* o: change made to incore
329 extents */
312 int *done); /* set if not done yet */ 330 int *done); /* set if not done yet */
313 331
314/* 332/*
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index bea44709afbe..18fb7385d719 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -1569,12 +1567,11 @@ xfs_bmbt_split(
1569 lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp)); 1567 lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp));
1570 left = XFS_BUF_TO_BMBT_BLOCK(lbp); 1568 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
1571 args.fsbno = cur->bc_private.b.firstblock; 1569 args.fsbno = cur->bc_private.b.firstblock;
1570 args.firstblock = args.fsbno;
1572 if (args.fsbno == NULLFSBLOCK) { 1571 if (args.fsbno == NULLFSBLOCK) {
1573 args.fsbno = lbno; 1572 args.fsbno = lbno;
1574 args.type = XFS_ALLOCTYPE_START_BNO; 1573 args.type = XFS_ALLOCTYPE_START_BNO;
1575 } else if (cur->bc_private.b.flist->xbf_low) 1574 } else
1576 args.type = XFS_ALLOCTYPE_FIRST_AG;
1577 else
1578 args.type = XFS_ALLOCTYPE_NEAR_BNO; 1575 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1579 args.mod = args.minleft = args.alignment = args.total = args.isfl = 1576 args.mod = args.minleft = args.alignment = args.total = args.isfl =
1580 args.userdata = args.minalignslop = 0; 1577 args.userdata = args.minalignslop = 0;
@@ -2356,6 +2353,7 @@ xfs_bmbt_newroot(
2356 args.userdata = args.minalignslop = 0; 2353 args.userdata = args.minalignslop = 0;
2357 args.minlen = args.maxlen = args.prod = 1; 2354 args.minlen = args.maxlen = args.prod = 1;
2358 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; 2355 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
2356 args.firstblock = args.fsbno;
2359 if (args.fsbno == NULLFSBLOCK) { 2357 if (args.fsbno == NULLFSBLOCK) {
2360#ifdef DEBUG 2358#ifdef DEBUG
2361 if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { 2359 if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
@@ -2365,9 +2363,7 @@ xfs_bmbt_newroot(
2365#endif 2363#endif
2366 args.fsbno = INT_GET(*pp, ARCH_CONVERT); 2364 args.fsbno = INT_GET(*pp, ARCH_CONVERT);
2367 args.type = XFS_ALLOCTYPE_START_BNO; 2365 args.type = XFS_ALLOCTYPE_START_BNO;
2368 } else if (args.wasdel) 2366 } else
2369 args.type = XFS_ALLOCTYPE_FIRST_AG;
2370 else
2371 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2367 args.type = XFS_ALLOCTYPE_NEAR_BNO;
2372 if ((error = xfs_alloc_vextent(&args))) { 2368 if ((error = xfs_alloc_vextent(&args))) {
2373 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 2369 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 52d5d095fc35..ee2255bd6562 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 5fed15682dda..a4aa53974f76 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -23,7 +23,6 @@
23#include "xfs_inum.h" 23#include "xfs_inum.h"
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_dir.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_buf_item.h" 28#include "xfs_buf_item.h"
@@ -1030,9 +1029,9 @@ xfs_buf_iodone_callbacks(
1030 if ((XFS_BUF_TARGET(bp) != lasttarg) || 1029 if ((XFS_BUF_TARGET(bp) != lasttarg) ||
1031 (time_after(jiffies, (lasttime + 5*HZ)))) { 1030 (time_after(jiffies, (lasttime + 5*HZ)))) {
1032 lasttime = jiffies; 1031 lasttime = jiffies;
1033 prdev("XFS write error in file system meta-data " 1032 cmn_err(CE_ALERT, "Device %s, XFS metadata write error"
1034 "block 0x%llx in %s", 1033 " block 0x%llx in %s",
1035 XFS_BUF_TARGET(bp), 1034 XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),
1036 (__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname); 1035 (__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname);
1037 } 1036 }
1038 lasttarg = XFS_BUF_TARGET(bp); 1037 lasttarg = XFS_BUF_TARGET(bp);
@@ -1108,7 +1107,7 @@ xfs_buf_error_relse(
1108 XFS_BUF_ERROR(bp,0); 1107 XFS_BUF_ERROR(bp,0);
1109 xfs_buftrace("BUF_ERROR_RELSE", bp); 1108 xfs_buftrace("BUF_ERROR_RELSE", bp);
1110 if (! XFS_FORCED_SHUTDOWN(mp)) 1109 if (! XFS_FORCED_SHUTDOWN(mp))
1111 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 1110 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1112 /* 1111 /*
1113 * We have to unpin the pinned buffers so do the 1112 * We have to unpin the pinned buffers so do the
1114 * callbacks. 1113 * callbacks.
diff --git a/fs/xfs/xfs_cap.h b/fs/xfs/xfs_cap.h
index d0035c6e9514..7a0e482dd436 100644
--- a/fs/xfs/xfs_cap.h
+++ b/fs/xfs/xfs_cap.h
@@ -49,12 +49,12 @@ typedef struct xfs_cap_set {
49 49
50#include <linux/posix_cap_xattr.h> 50#include <linux/posix_cap_xattr.h>
51 51
52struct vnode; 52struct bhv_vnode;
53 53
54extern int xfs_cap_vhascap(struct vnode *); 54extern int xfs_cap_vhascap(struct bhv_vnode *);
55extern int xfs_cap_vset(struct vnode *, void *, size_t); 55extern int xfs_cap_vset(struct bhv_vnode *, void *, size_t);
56extern int xfs_cap_vget(struct vnode *, void *, size_t); 56extern int xfs_cap_vget(struct bhv_vnode *, void *, size_t);
57extern int xfs_cap_vremove(struct vnode *vp); 57extern int xfs_cap_vremove(struct bhv_vnode *);
58 58
59#define _CAP_EXISTS xfs_cap_vhascap 59#define _CAP_EXISTS xfs_cap_vhascap
60 60
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 8988b9051175..32ab61d17ace 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -24,7 +24,6 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -43,7 +41,6 @@
43#include "xfs_bmap.h" 41#include "xfs_bmap.h"
44#include "xfs_attr.h" 42#include "xfs_attr.h"
45#include "xfs_attr_leaf.h" 43#include "xfs_attr_leaf.h"
46#include "xfs_dir_leaf.h"
47#include "xfs_dir2_data.h" 44#include "xfs_dir2_data.h"
48#include "xfs_dir2_leaf.h" 45#include "xfs_dir2_leaf.h"
49#include "xfs_dir2_block.h" 46#include "xfs_dir2_block.h"
@@ -159,7 +156,7 @@ xfs_da_split(xfs_da_state_t *state)
159 max = state->path.active - 1; 156 max = state->path.active - 1;
160 ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); 157 ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));
161 ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || 158 ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC ||
162 state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp)); 159 state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC);
163 160
164 addblk = &state->path.blk[max]; /* initial dummy value */ 161 addblk = &state->path.blk[max]; /* initial dummy value */
165 for (i = max; (i >= 0) && addblk; state->path.active--, i--) { 162 for (i = max; (i >= 0) && addblk; state->path.active--, i--) {
@@ -199,38 +196,7 @@ xfs_da_split(xfs_da_state_t *state)
199 return(error); /* GROT: attr inconsistent */ 196 return(error); /* GROT: attr inconsistent */
200 addblk = newblk; 197 addblk = newblk;
201 break; 198 break;
202 case XFS_DIR_LEAF_MAGIC:
203 ASSERT(XFS_DIR_IS_V1(state->mp));
204 error = xfs_dir_leaf_split(state, oldblk, newblk);
205 if ((error != 0) && (error != ENOSPC)) {
206 return(error); /* GROT: dir is inconsistent */
207 }
208 if (!error) {
209 addblk = newblk;
210 break;
211 }
212 /*
213 * Entry wouldn't fit, split the leaf again.
214 */
215 state->extravalid = 1;
216 if (state->inleaf) {
217 state->extraafter = 0; /* before newblk */
218 error = xfs_dir_leaf_split(state, oldblk,
219 &state->extrablk);
220 if (error)
221 return(error); /* GROT: dir incon. */
222 addblk = newblk;
223 } else {
224 state->extraafter = 1; /* after newblk */
225 error = xfs_dir_leaf_split(state, newblk,
226 &state->extrablk);
227 if (error)
228 return(error); /* GROT: dir incon. */
229 addblk = newblk;
230 }
231 break;
232 case XFS_DIR2_LEAFN_MAGIC: 199 case XFS_DIR2_LEAFN_MAGIC:
233 ASSERT(XFS_DIR_IS_V2(state->mp));
234 error = xfs_dir2_leafn_split(state, oldblk, newblk); 200 error = xfs_dir2_leafn_split(state, oldblk, newblk);
235 if (error) 201 if (error)
236 return error; 202 return error;
@@ -363,7 +329,6 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
363 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - 329 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
364 (char *)oldroot); 330 (char *)oldroot);
365 } else { 331 } else {
366 ASSERT(XFS_DIR_IS_V2(mp));
367 ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 332 ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
368 leaf = (xfs_dir2_leaf_t *)oldroot; 333 leaf = (xfs_dir2_leaf_t *)oldroot;
369 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - 334 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] -
@@ -379,8 +344,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
379 * Set up the new root node. 344 * Set up the new root node.
380 */ 345 */
381 error = xfs_da_node_create(args, 346 error = xfs_da_node_create(args,
382 args->whichfork == XFS_DATA_FORK && 347 (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0,
383 XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0,
384 be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); 348 be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork);
385 if (error) 349 if (error)
386 return(error); 350 return(error);
@@ -427,10 +391,9 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
427 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 391 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
428 392
429 /* 393 /*
430 * With V2 the extra block is data or freespace. 394 * With V2 dirs the extra block is data or freespace.
431 */ 395 */
432 useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) || 396 useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK;
433 state->args->whichfork == XFS_ATTR_FORK);
434 newcount = 1 + useextra; 397 newcount = 1 + useextra;
435 /* 398 /*
436 * Do we have to split the node? 399 * Do we have to split the node?
@@ -624,7 +587,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
624 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 587 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
625 ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); 588 ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));
626 ASSERT(newblk->blkno != 0); 589 ASSERT(newblk->blkno != 0);
627 if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 590 if (state->args->whichfork == XFS_DATA_FORK)
628 ASSERT(newblk->blkno >= mp->m_dirleafblk && 591 ASSERT(newblk->blkno >= mp->m_dirleafblk &&
629 newblk->blkno < mp->m_dirfreeblk); 592 newblk->blkno < mp->m_dirfreeblk);
630 593
@@ -670,7 +633,7 @@ xfs_da_join(xfs_da_state_t *state)
670 save_blk = &state->altpath.blk[ state->path.active-1 ]; 633 save_blk = &state->altpath.blk[ state->path.active-1 ];
671 ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); 634 ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);
672 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || 635 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC ||
673 drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp)); 636 drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
674 637
675 /* 638 /*
676 * Walk back up the tree joining/deallocating as necessary. 639 * Walk back up the tree joining/deallocating as necessary.
@@ -693,17 +656,7 @@ xfs_da_join(xfs_da_state_t *state)
693 return(0); 656 return(0);
694 xfs_attr_leaf_unbalance(state, drop_blk, save_blk); 657 xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
695 break; 658 break;
696 case XFS_DIR_LEAF_MAGIC:
697 ASSERT(XFS_DIR_IS_V1(state->mp));
698 error = xfs_dir_leaf_toosmall(state, &action);
699 if (error)
700 return(error);
701 if (action == 0)
702 return(0);
703 xfs_dir_leaf_unbalance(state, drop_blk, save_blk);
704 break;
705 case XFS_DIR2_LEAFN_MAGIC: 659 case XFS_DIR2_LEAFN_MAGIC:
706 ASSERT(XFS_DIR_IS_V2(state->mp));
707 error = xfs_dir2_leafn_toosmall(state, &action); 660 error = xfs_dir2_leafn_toosmall(state, &action);
708 if (error) 661 if (error)
709 return error; 662 return error;
@@ -790,7 +743,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
790 ASSERT(bp != NULL); 743 ASSERT(bp != NULL);
791 blkinfo = bp->data; 744 blkinfo = bp->data;
792 if (be16_to_cpu(oldroot->hdr.level) == 1) { 745 if (be16_to_cpu(oldroot->hdr.level) == 1) {
793 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || 746 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC ||
794 be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); 747 be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);
795 } else { 748 } else {
796 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); 749 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC);
@@ -951,14 +904,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
951 if (count == 0) 904 if (count == 0)
952 return; 905 return;
953 break; 906 break;
954 case XFS_DIR_LEAF_MAGIC:
955 ASSERT(XFS_DIR_IS_V1(state->mp));
956 lasthash = xfs_dir_leaf_lasthash(blk->bp, &count);
957 if (count == 0)
958 return;
959 break;
960 case XFS_DIR2_LEAFN_MAGIC: 907 case XFS_DIR2_LEAFN_MAGIC:
961 ASSERT(XFS_DIR_IS_V2(state->mp));
962 lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); 908 lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count);
963 if (count == 0) 909 if (count == 0)
964 return; 910 return;
@@ -1117,10 +1063,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1117 * Descend thru the B-tree searching each level for the right 1063 * Descend thru the B-tree searching each level for the right
1118 * node to use, until the right hashval is found. 1064 * node to use, until the right hashval is found.
1119 */ 1065 */
1120 if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp)) 1066 blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0;
1121 blkno = state->mp->m_dirleafblk;
1122 else
1123 blkno = 0;
1124 for (blk = &state->path.blk[0], state->path.active = 1; 1067 for (blk = &state->path.blk[0], state->path.active = 1;
1125 state->path.active <= XFS_DA_NODE_MAXDEPTH; 1068 state->path.active <= XFS_DA_NODE_MAXDEPTH;
1126 blk++, state->path.active++) { 1069 blk++, state->path.active++) {
@@ -1137,7 +1080,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1137 } 1080 }
1138 curr = blk->bp->data; 1081 curr = blk->bp->data;
1139 ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || 1082 ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
1140 be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || 1083 be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC ||
1141 be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); 1084 be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
1142 1085
1143 /* 1086 /*
@@ -1190,16 +1133,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1190 blk->index = probe; 1133 blk->index = probe;
1191 blkno = be32_to_cpu(btree->before); 1134 blkno = be32_to_cpu(btree->before);
1192 } 1135 }
1193 } 1136 } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
1194 else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
1195 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); 1137 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
1196 break; 1138 break;
1197 } 1139 } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
1198 else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) {
1199 blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
1200 break;
1201 }
1202 else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
1203 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); 1140 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
1204 break; 1141 break;
1205 } 1142 }
@@ -1212,12 +1149,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1212 * next leaf and keep searching. 1149 * next leaf and keep searching.
1213 */ 1150 */
1214 for (;;) { 1151 for (;;) {
1215 if (blk->magic == XFS_DIR_LEAF_MAGIC) { 1152 if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
1216 ASSERT(XFS_DIR_IS_V1(state->mp));
1217 retval = xfs_dir_leaf_lookup_int(blk->bp, args,
1218 &blk->index);
1219 } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
1220 ASSERT(XFS_DIR_IS_V2(state->mp));
1221 retval = xfs_dir2_leafn_lookup_int(blk->bp, args, 1153 retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
1222 &blk->index, state); 1154 &blk->index, state);
1223 } 1155 }
@@ -1270,7 +1202,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
1270 old_info = old_blk->bp->data; 1202 old_info = old_blk->bp->data;
1271 new_info = new_blk->bp->data; 1203 new_info = new_blk->bp->data;
1272 ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || 1204 ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC ||
1273 old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || 1205 old_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
1274 old_blk->magic == XFS_ATTR_LEAF_MAGIC); 1206 old_blk->magic == XFS_ATTR_LEAF_MAGIC);
1275 ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); 1207 ASSERT(old_blk->magic == be16_to_cpu(old_info->magic));
1276 ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); 1208 ASSERT(new_blk->magic == be16_to_cpu(new_info->magic));
@@ -1280,12 +1212,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
1280 case XFS_ATTR_LEAF_MAGIC: 1212 case XFS_ATTR_LEAF_MAGIC:
1281 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); 1213 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
1282 break; 1214 break;
1283 case XFS_DIR_LEAF_MAGIC:
1284 ASSERT(XFS_DIR_IS_V1(state->mp));
1285 before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp);
1286 break;
1287 case XFS_DIR2_LEAFN_MAGIC: 1215 case XFS_DIR2_LEAFN_MAGIC:
1288 ASSERT(XFS_DIR_IS_V2(state->mp));
1289 before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); 1216 before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp);
1290 break; 1217 break;
1291 case XFS_DA_NODE_MAGIC: 1218 case XFS_DA_NODE_MAGIC:
@@ -1404,7 +1331,7 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1404 save_info = save_blk->bp->data; 1331 save_info = save_blk->bp->data;
1405 drop_info = drop_blk->bp->data; 1332 drop_info = drop_blk->bp->data;
1406 ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || 1333 ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC ||
1407 save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || 1334 save_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
1408 save_blk->magic == XFS_ATTR_LEAF_MAGIC); 1335 save_blk->magic == XFS_ATTR_LEAF_MAGIC);
1409 ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); 1336 ASSERT(save_blk->magic == be16_to_cpu(save_info->magic));
1410 ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); 1337 ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic));
@@ -1529,7 +1456,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1529 ASSERT(blk->bp != NULL); 1456 ASSERT(blk->bp != NULL);
1530 info = blk->bp->data; 1457 info = blk->bp->data;
1531 ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || 1458 ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC ||
1532 be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || 1459 be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC ||
1533 be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); 1460 be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);
1534 blk->magic = be16_to_cpu(info->magic); 1461 blk->magic = be16_to_cpu(info->magic);
1535 if (blk->magic == XFS_DA_NODE_MAGIC) { 1462 if (blk->magic == XFS_DA_NODE_MAGIC) {
@@ -1548,20 +1475,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1548 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, 1475 blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
1549 NULL); 1476 NULL);
1550 break; 1477 break;
1551 case XFS_DIR_LEAF_MAGIC:
1552 ASSERT(XFS_DIR_IS_V1(state->mp));
1553 blk->hashval = xfs_dir_leaf_lasthash(blk->bp,
1554 NULL);
1555 break;
1556 case XFS_DIR2_LEAFN_MAGIC: 1478 case XFS_DIR2_LEAFN_MAGIC:
1557 ASSERT(XFS_DIR_IS_V2(state->mp));
1558 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, 1479 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
1559 NULL); 1480 NULL);
1560 break; 1481 break;
1561 default: 1482 default:
1562 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || 1483 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC ||
1563 blk->magic == 1484 blk->magic == XFS_DIR2_LEAFN_MAGIC);
1564 XFS_DIRX_LEAF_MAGIC(state->mp));
1565 break; 1485 break;
1566 } 1486 }
1567 } 1487 }
@@ -1620,7 +1540,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1620 xfs_bmbt_irec_t *mapp; 1540 xfs_bmbt_irec_t *mapp;
1621 xfs_inode_t *dp; 1541 xfs_inode_t *dp;
1622 int nmap, error, w, count, c, got, i, mapi; 1542 int nmap, error, w, count, c, got, i, mapi;
1623 xfs_fsize_t size;
1624 xfs_trans_t *tp; 1543 xfs_trans_t *tp;
1625 xfs_mount_t *mp; 1544 xfs_mount_t *mp;
1626 1545
@@ -1631,7 +1550,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1631 /* 1550 /*
1632 * For new directories adjust the file offset and block count. 1551 * For new directories adjust the file offset and block count.
1633 */ 1552 */
1634 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) { 1553 if (w == XFS_DATA_FORK) {
1635 bno = mp->m_dirleafblk; 1554 bno = mp->m_dirleafblk;
1636 count = mp->m_dirblkfsbs; 1555 count = mp->m_dirblkfsbs;
1637 } else { 1556 } else {
@@ -1641,10 +1560,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1641 /* 1560 /*
1642 * Find a spot in the file space to put the new block. 1561 * Find a spot in the file space to put the new block.
1643 */ 1562 */
1644 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) { 1563 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w)))
1645 return error; 1564 return error;
1646 } 1565 if (w == XFS_DATA_FORK)
1647 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
1648 ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); 1566 ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);
1649 /* 1567 /*
1650 * Try mapping it in one filesystem block. 1568 * Try mapping it in one filesystem block.
@@ -1655,7 +1573,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1655 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| 1573 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
1656 XFS_BMAPI_CONTIG, 1574 XFS_BMAPI_CONTIG,
1657 args->firstblock, args->total, &map, &nmap, 1575 args->firstblock, args->total, &map, &nmap,
1658 args->flist))) { 1576 args->flist, NULL))) {
1659 return error; 1577 return error;
1660 } 1578 }
1661 ASSERT(nmap <= 1); 1579 ASSERT(nmap <= 1);
@@ -1676,7 +1594,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1676 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE| 1594 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|
1677 XFS_BMAPI_METADATA, 1595 XFS_BMAPI_METADATA,
1678 args->firstblock, args->total, 1596 args->firstblock, args->total,
1679 &mapp[mapi], &nmap, args->flist))) { 1597 &mapp[mapi], &nmap, args->flist,
1598 NULL))) {
1680 kmem_free(mapp, sizeof(*mapp) * count); 1599 kmem_free(mapp, sizeof(*mapp) * count);
1681 return error; 1600 return error;
1682 } 1601 }
@@ -1705,19 +1624,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1705 if (mapp != &map) 1624 if (mapp != &map)
1706 kmem_free(mapp, sizeof(*mapp) * count); 1625 kmem_free(mapp, sizeof(*mapp) * count);
1707 *new_blkno = (xfs_dablk_t)bno; 1626 *new_blkno = (xfs_dablk_t)bno;
1708 /*
1709 * For version 1 directories, adjust the file size if it changed.
1710 */
1711 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
1712 ASSERT(mapi == 1);
1713 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
1714 return error;
1715 size = XFS_FSB_TO_B(mp, bno);
1716 if (size != dp->i_d.di_size) {
1717 dp->i_d.di_size = size;
1718 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1719 }
1720 }
1721 return 0; 1627 return 0;
1722} 1628}
1723 1629
@@ -1742,7 +1648,6 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1742 int error, w, entno, level, dead_level; 1648 int error, w, entno, level, dead_level;
1743 xfs_da_blkinfo_t *dead_info, *sib_info; 1649 xfs_da_blkinfo_t *dead_info, *sib_info;
1744 xfs_da_intnode_t *par_node, *dead_node; 1650 xfs_da_intnode_t *par_node, *dead_node;
1745 xfs_dir_leafblock_t *dead_leaf;
1746 xfs_dir2_leaf_t *dead_leaf2; 1651 xfs_dir2_leaf_t *dead_leaf2;
1747 xfs_dahash_t dead_hash; 1652 xfs_dahash_t dead_hash;
1748 1653
@@ -1753,11 +1658,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1753 w = args->whichfork; 1658 w = args->whichfork;
1754 ASSERT(w == XFS_DATA_FORK); 1659 ASSERT(w == XFS_DATA_FORK);
1755 mp = ip->i_mount; 1660 mp = ip->i_mount;
1756 if (XFS_DIR_IS_V2(mp)) { 1661 lastoff = mp->m_dirfreeblk;
1757 lastoff = mp->m_dirfreeblk; 1662 error = xfs_bmap_last_before(tp, ip, &lastoff, w);
1758 error = xfs_bmap_last_before(tp, ip, &lastoff, w);
1759 } else
1760 error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
1761 if (error) 1663 if (error)
1762 return error; 1664 return error;
1763 if (unlikely(lastoff == 0)) { 1665 if (unlikely(lastoff == 0)) {
@@ -1780,14 +1682,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1780 /* 1682 /*
1781 * Get values from the moved block. 1683 * Get values from the moved block.
1782 */ 1684 */
1783 if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) { 1685 if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
1784 ASSERT(XFS_DIR_IS_V1(mp));
1785 dead_leaf = (xfs_dir_leafblock_t *)dead_info;
1786 dead_level = 0;
1787 dead_hash =
1788 INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
1789 } else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
1790 ASSERT(XFS_DIR_IS_V2(mp));
1791 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; 1686 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
1792 dead_level = 0; 1687 dead_level = 0;
1793 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); 1688 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval);
@@ -1842,7 +1737,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1842 xfs_da_buf_done(sib_buf); 1737 xfs_da_buf_done(sib_buf);
1843 sib_buf = NULL; 1738 sib_buf = NULL;
1844 } 1739 }
1845 par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk; 1740 par_blkno = mp->m_dirleafblk;
1846 level = -1; 1741 level = -1;
1847 /* 1742 /*
1848 * Walk down the tree looking for the parent of the moved block. 1743 * Walk down the tree looking for the parent of the moved block.
@@ -1941,8 +1836,6 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1941{ 1836{
1942 xfs_inode_t *dp; 1837 xfs_inode_t *dp;
1943 int done, error, w, count; 1838 int done, error, w, count;
1944 xfs_fileoff_t bno;
1945 xfs_fsize_t size;
1946 xfs_trans_t *tp; 1839 xfs_trans_t *tp;
1947 xfs_mount_t *mp; 1840 xfs_mount_t *mp;
1948 1841
@@ -1950,7 +1843,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1950 w = args->whichfork; 1843 w = args->whichfork;
1951 tp = args->trans; 1844 tp = args->trans;
1952 mp = dp->i_mount; 1845 mp = dp->i_mount;
1953 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 1846 if (w == XFS_DATA_FORK)
1954 count = mp->m_dirblkfsbs; 1847 count = mp->m_dirblkfsbs;
1955 else 1848 else
1956 count = 1; 1849 count = 1;
@@ -1961,34 +1854,17 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1961 */ 1854 */
1962 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, 1855 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
1963 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, 1856 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA,
1964 0, args->firstblock, args->flist, 1857 0, args->firstblock, args->flist, NULL,
1965 &done)) == ENOSPC) { 1858 &done)) == ENOSPC) {
1966 if (w != XFS_DATA_FORK) 1859 if (w != XFS_DATA_FORK)
1967 goto done; 1860 break;
1968 if ((error = xfs_da_swap_lastblock(args, &dead_blkno, 1861 if ((error = xfs_da_swap_lastblock(args, &dead_blkno,
1969 &dead_buf))) 1862 &dead_buf)))
1970 goto done; 1863 break;
1971 } else if (error) 1864 } else {
1972 goto done;
1973 else
1974 break; 1865 break;
1975 }
1976 ASSERT(done);
1977 xfs_da_binval(tp, dead_buf);
1978 /*
1979 * Adjust the directory size for version 1.
1980 */
1981 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
1982 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
1983 return error;
1984 size = XFS_FSB_TO_B(dp->i_mount, bno);
1985 if (size != dp->i_d.di_size) {
1986 dp->i_d.di_size = size;
1987 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1988 } 1866 }
1989 } 1867 }
1990 return 0;
1991done:
1992 xfs_da_binval(tp, dead_buf); 1868 xfs_da_binval(tp, dead_buf);
1993 return error; 1869 return error;
1994} 1870}
@@ -2049,10 +1925,7 @@ xfs_da_do_buf(
2049 xfs_dabuf_t *rbp; 1925 xfs_dabuf_t *rbp;
2050 1926
2051 mp = dp->i_mount; 1927 mp = dp->i_mount;
2052 if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 1928 nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1;
2053 nfsb = mp->m_dirblkfsbs;
2054 else
2055 nfsb = 1;
2056 mappedbno = *mappedbnop; 1929 mappedbno = *mappedbnop;
2057 /* 1930 /*
2058 * Caller doesn't have a mapping. -2 means don't complain 1931 * Caller doesn't have a mapping. -2 means don't complain
@@ -2086,7 +1959,7 @@ xfs_da_do_buf(
2086 nfsb, 1959 nfsb,
2087 XFS_BMAPI_METADATA | 1960 XFS_BMAPI_METADATA |
2088 XFS_BMAPI_AFLAG(whichfork), 1961 XFS_BMAPI_AFLAG(whichfork),
2089 NULL, 0, mapp, &nmap, NULL))) 1962 NULL, 0, mapp, &nmap, NULL, NULL)))
2090 goto exit0; 1963 goto exit0;
2091 } 1964 }
2092 } else { 1965 } else {
@@ -2198,7 +2071,6 @@ xfs_da_do_buf(
2198 magic1 = be32_to_cpu(data->hdr.magic); 2071 magic1 = be32_to_cpu(data->hdr.magic);
2199 if (unlikely( 2072 if (unlikely(
2200 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && 2073 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
2201 (magic != XFS_DIR_LEAF_MAGIC) &&
2202 (magic != XFS_ATTR_LEAF_MAGIC) && 2074 (magic != XFS_ATTR_LEAF_MAGIC) &&
2203 (magic != XFS_DIR2_LEAF1_MAGIC) && 2075 (magic != XFS_DIR2_LEAF1_MAGIC) &&
2204 (magic != XFS_DIR2_LEAFN_MAGIC) && 2076 (magic != XFS_DIR2_LEAFN_MAGIC) &&
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 243a730d5ec8..4ab865ec8b82 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -36,14 +36,10 @@ struct zone;
36 * level in the Btree, and to identify which type of block this is. 36 * level in the Btree, and to identify which type of block this is.
37 */ 37 */
38#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ 38#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */
39#define XFS_DIR_LEAF_MAGIC 0xfeeb /* magic number: directory leaf blks */
40#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ 39#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */
41#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ 40#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */
42#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ 41#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */
43 42
44#define XFS_DIRX_LEAF_MAGIC(mp) \
45 (XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC)
46
47typedef struct xfs_da_blkinfo { 43typedef struct xfs_da_blkinfo {
48 __be32 forw; /* previous block in list */ 44 __be32 forw; /* previous block in list */
49 __be32 back; /* following block in list */ 45 __be32 back; /* following block in list */
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 4968a6358e61..80562b60fb95 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -54,24 +52,14 @@ xfs_swapext(
54 xfs_swapext_t __user *sxu) 52 xfs_swapext_t __user *sxu)
55{ 53{
56 xfs_swapext_t *sxp; 54 xfs_swapext_t *sxp;
57 xfs_inode_t *ip=NULL, *tip=NULL, *ips[2]; 55 xfs_inode_t *ip=NULL, *tip=NULL;
58 xfs_trans_t *tp;
59 xfs_mount_t *mp; 56 xfs_mount_t *mp;
60 xfs_bstat_t *sbp;
61 struct file *fp = NULL, *tfp = NULL; 57 struct file *fp = NULL, *tfp = NULL;
62 vnode_t *vp, *tvp; 58 bhv_vnode_t *vp, *tvp;
63 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
64 int ilf_fields, tilf_fields;
65 int error = 0; 59 int error = 0;
66 xfs_ifork_t *tempifp, *ifp, *tifp;
67 __uint64_t tmp;
68 int aforkblks = 0;
69 int taforkblks = 0;
70 char locked = 0;
71 60
72 sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); 61 sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
73 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); 62 if (!sxp) {
74 if (!sxp || !tempifp) {
75 error = XFS_ERROR(ENOMEM); 63 error = XFS_ERROR(ENOMEM);
76 goto error0; 64 goto error0;
77 } 65 }
@@ -118,14 +106,56 @@ xfs_swapext(
118 106
119 mp = ip->i_mount; 107 mp = ip->i_mount;
120 108
121 sbp = &sxp->sx_stat;
122
123 if (XFS_FORCED_SHUTDOWN(mp)) { 109 if (XFS_FORCED_SHUTDOWN(mp)) {
124 error = XFS_ERROR(EIO); 110 error = XFS_ERROR(EIO);
125 goto error0; 111 goto error0;
126 } 112 }
127 113
128 locked = 1; 114 error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp);
115
116 error0:
117 if (fp != NULL)
118 fput(fp);
119 if (tfp != NULL)
120 fput(tfp);
121
122 if (sxp != NULL)
123 kmem_free(sxp, sizeof(xfs_swapext_t));
124
125 return error;
126}
127
128int
129xfs_swap_extents(
130 xfs_inode_t *ip,
131 xfs_inode_t *tip,
132 xfs_swapext_t *sxp)
133{
134 xfs_mount_t *mp;
135 xfs_inode_t *ips[2];
136 xfs_trans_t *tp;
137 xfs_bstat_t *sbp = &sxp->sx_stat;
138 bhv_vnode_t *vp, *tvp;
139 xfs_ifork_t *tempifp, *ifp, *tifp;
140 int ilf_fields, tilf_fields;
141 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
142 int error = 0;
143 int aforkblks = 0;
144 int taforkblks = 0;
145 __uint64_t tmp;
146 char locked = 0;
147
148 mp = ip->i_mount;
149
150 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
151 if (!tempifp) {
152 error = XFS_ERROR(ENOMEM);
153 goto error0;
154 }
155
156 sbp = &sxp->sx_stat;
157 vp = XFS_ITOV(ip);
158 tvp = XFS_ITOV(tip);
129 159
130 /* Lock in i_ino order */ 160 /* Lock in i_ino order */
131 if (ip->i_ino < tip->i_ino) { 161 if (ip->i_ino < tip->i_ino) {
@@ -137,6 +167,7 @@ xfs_swapext(
137 } 167 }
138 168
139 xfs_lock_inodes(ips, 2, 0, lock_flags); 169 xfs_lock_inodes(ips, 2, 0, lock_flags);
170 locked = 1;
140 171
141 /* Check permissions */ 172 /* Check permissions */
142 error = xfs_iaccess(ip, S_IWUSR, NULL); 173 error = xfs_iaccess(ip, S_IWUSR, NULL);
@@ -169,7 +200,7 @@ xfs_swapext(
169 200
170 if (VN_CACHED(tvp) != 0) { 201 if (VN_CACHED(tvp) != 0) {
171 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); 202 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
172 VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED); 203 bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
173 } 204 }
174 205
175 /* Verify O_DIRECT for ftmp */ 206 /* Verify O_DIRECT for ftmp */
@@ -214,7 +245,7 @@ xfs_swapext(
214 /* We need to fail if the file is memory mapped. Once we have tossed 245 /* We need to fail if the file is memory mapped. Once we have tossed
215 * all existing pages, the page fault will have no option 246 * all existing pages, the page fault will have no option
216 * but to go to the filesystem for pages. By making the page fault call 247 * but to go to the filesystem for pages. By making the page fault call
217 * VOP_READ (or write in the case of autogrow) they block on the iolock 248 * vop_read (or write in the case of autogrow) they block on the iolock
218 * until we have switched the extents. 249 * until we have switched the extents.
219 */ 250 */
220 if (VN_MAPPED(vp)) { 251 if (VN_MAPPED(vp)) {
@@ -233,7 +264,7 @@ xfs_swapext(
233 * fields change. 264 * fields change.
234 */ 265 */
235 266
236 VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF); 267 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
237 268
238 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); 269 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
239 if ((error = xfs_trans_reserve(tp, 0, 270 if ((error = xfs_trans_reserve(tp, 0,
@@ -360,16 +391,7 @@ xfs_swapext(
360 xfs_iunlock(ip, lock_flags); 391 xfs_iunlock(ip, lock_flags);
361 xfs_iunlock(tip, lock_flags); 392 xfs_iunlock(tip, lock_flags);
362 } 393 }
363
364 if (fp != NULL)
365 fput(fp);
366 if (tfp != NULL)
367 fput(tfp);
368
369 if (sxp != NULL)
370 kmem_free(sxp, sizeof(xfs_swapext_t));
371 if (tempifp != NULL) 394 if (tempifp != NULL)
372 kmem_free(tempifp, sizeof(xfs_ifork_t)); 395 kmem_free(tempifp, sizeof(xfs_ifork_t));
373
374 return error; 396 return error;
375} 397}
diff --git a/fs/xfs/xfs_dfrag.h b/fs/xfs/xfs_dfrag.h
index f678559abc45..da178205be68 100644
--- a/fs/xfs/xfs_dfrag.h
+++ b/fs/xfs/xfs_dfrag.h
@@ -48,6 +48,9 @@ typedef struct xfs_swapext
48 */ 48 */
49int xfs_swapext(struct xfs_swapext __user *sx); 49int xfs_swapext(struct xfs_swapext __user *sx);
50 50
51int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip,
52 struct xfs_swapext *sxp);
53
51#endif /* __KERNEL__ */ 54#endif /* __KERNEL__ */
52 55
53#endif /* __XFS_DFRAG_H__ */ 56#endif /* __XFS_DFRAG_H__ */
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index 79d0d9e1fbab..b33826961c45 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -85,7 +85,6 @@ typedef struct xfs_dinode
85 union { 85 union {
86 xfs_bmdr_block_t di_bmbt; /* btree root block */ 86 xfs_bmdr_block_t di_bmbt; /* btree root block */
87 xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ 87 xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */
88 xfs_dir_shortform_t di_dirsf; /* shortform directory */
89 xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ 88 xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
90 char di_c[1]; /* local contents */ 89 char di_c[1]; /* local contents */
91 xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ 90 xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */
@@ -257,6 +256,7 @@ typedef enum xfs_dinode_fmt
257#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ 256#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */
258#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ 257#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
259#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ 258#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
259#define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */
260#define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) 260#define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
261#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) 261#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
262#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) 262#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT)
@@ -270,12 +270,13 @@ typedef enum xfs_dinode_fmt
270#define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT) 270#define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
271#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) 271#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
272#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) 272#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
273#define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
273 274
274#define XFS_DIFLAG_ANY \ 275#define XFS_DIFLAG_ANY \
275 (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ 276 (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
276 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ 277 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
277 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ 278 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
278 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ 279 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
279 XFS_DIFLAG_EXTSZINHERIT) 280 XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
280 281
281#endif /* __XFS_DINODE_H__ */ 282#endif /* __XFS_DINODE_H__ */
diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c
deleted file mode 100644
index 9cc702a839a3..000000000000
--- a/fs/xfs/xfs_dir.c
+++ /dev/null
@@ -1,1217 +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#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_types.h"
21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h"
27#include "xfs_dmapi.h"
28#include "xfs_mount.h"
29#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h"
33#include "xfs_alloc.h"
34#include "xfs_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h"
38#include "xfs_dinode.h"
39#include "xfs_inode.h"
40#include "xfs_bmap.h"
41#include "xfs_dir_leaf.h"
42#include "xfs_error.h"
43
44/*
45 * xfs_dir.c
46 *
47 * Provide the external interfaces to manage directories.
48 */
49
50/*========================================================================
51 * Function prototypes for the kernel.
52 *========================================================================*/
53
54/*
55 * Functions for the dirops interfaces.
56 */
57static void xfs_dir_mount(struct xfs_mount *mp);
58
59static int xfs_dir_isempty(struct xfs_inode *dp);
60
61static int xfs_dir_init(struct xfs_trans *trans,
62 struct xfs_inode *dir,
63 struct xfs_inode *parent_dir);
64
65static int xfs_dir_createname(struct xfs_trans *trans,
66 struct xfs_inode *dp,
67 char *name_string,
68 int name_len,
69 xfs_ino_t inode_number,
70 xfs_fsblock_t *firstblock,
71 xfs_bmap_free_t *flist,
72 xfs_extlen_t total);
73
74static int xfs_dir_lookup(struct xfs_trans *tp,
75 struct xfs_inode *dp,
76 char *name_string,
77 int name_length,
78 xfs_ino_t *inode_number);
79
80static int xfs_dir_removename(struct xfs_trans *trans,
81 struct xfs_inode *dp,
82 char *name_string,
83 int name_length,
84 xfs_ino_t ino,
85 xfs_fsblock_t *firstblock,
86 xfs_bmap_free_t *flist,
87 xfs_extlen_t total);
88
89static int xfs_dir_getdents(struct xfs_trans *tp,
90 struct xfs_inode *dp,
91 struct uio *uiop,
92 int *eofp);
93
94static int xfs_dir_replace(struct xfs_trans *tp,
95 struct xfs_inode *dp,
96 char *name_string,
97 int name_length,
98 xfs_ino_t inode_number,
99 xfs_fsblock_t *firstblock,
100 xfs_bmap_free_t *flist,
101 xfs_extlen_t total);
102
103static int xfs_dir_canenter(struct xfs_trans *tp,
104 struct xfs_inode *dp,
105 char *name_string,
106 int name_length);
107
108static int xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp,
109 xfs_dinode_t *dip);
110
111xfs_dirops_t xfsv1_dirops = {
112 .xd_mount = xfs_dir_mount,
113 .xd_isempty = xfs_dir_isempty,
114 .xd_init = xfs_dir_init,
115 .xd_createname = xfs_dir_createname,
116 .xd_lookup = xfs_dir_lookup,
117 .xd_removename = xfs_dir_removename,
118 .xd_getdents = xfs_dir_getdents,
119 .xd_replace = xfs_dir_replace,
120 .xd_canenter = xfs_dir_canenter,
121 .xd_shortform_validate_ondisk = xfs_dir_shortform_validate_ondisk,
122 .xd_shortform_to_single = xfs_dir_shortform_to_leaf,
123};
124
125/*
126 * Internal routines when dirsize == XFS_LBSIZE(mp).
127 */
128STATIC int xfs_dir_leaf_lookup(xfs_da_args_t *args);
129STATIC int xfs_dir_leaf_removename(xfs_da_args_t *args, int *number_entries,
130 int *total_namebytes);
131STATIC int xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
132 uio_t *uio, int *eofp,
133 xfs_dirent_t *dbp,
134 xfs_dir_put_t put);
135STATIC int xfs_dir_leaf_replace(xfs_da_args_t *args);
136
137/*
138 * Internal routines when dirsize > XFS_LBSIZE(mp).
139 */
140STATIC int xfs_dir_node_addname(xfs_da_args_t *args);
141STATIC int xfs_dir_node_lookup(xfs_da_args_t *args);
142STATIC int xfs_dir_node_removename(xfs_da_args_t *args);
143STATIC int xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
144 uio_t *uio, int *eofp,
145 xfs_dirent_t *dbp,
146 xfs_dir_put_t put);
147STATIC int xfs_dir_node_replace(xfs_da_args_t *args);
148
149#if defined(XFS_DIR_TRACE)
150ktrace_t *xfs_dir_trace_buf;
151#endif
152
153
154/*========================================================================
155 * Overall external interface routines.
156 *========================================================================*/
157
158xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
159
160/*
161 * One-time startup routine called from xfs_init().
162 */
163void
164xfs_dir_startup(void)
165{
166 xfs_dir_hash_dot = xfs_da_hashname(".", 1);
167 xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
168}
169
170/*
171 * Initialize directory-related fields in the mount structure.
172 */
173static void
174xfs_dir_mount(xfs_mount_t *mp)
175{
176 uint shortcount, leafcount, count;
177
178 mp->m_dirversion = 1;
179 if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
180 shortcount = (mp->m_attroffset -
181 (uint)sizeof(xfs_dir_sf_hdr_t)) /
182 (uint)sizeof(xfs_dir_sf_entry_t);
183 leafcount = (XFS_LBSIZE(mp) -
184 (uint)sizeof(xfs_dir_leaf_hdr_t)) /
185 ((uint)sizeof(xfs_dir_leaf_entry_t) +
186 (uint)sizeof(xfs_dir_leaf_name_t));
187 } else {
188 shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) -
189 (uint)sizeof(xfs_dir_sf_hdr_t)) /
190 (uint)sizeof(xfs_dir_sf_entry_t);
191 leafcount = (XFS_LBSIZE(mp) -
192 (uint)sizeof(xfs_dir_leaf_hdr_t)) /
193 ((uint)sizeof(xfs_dir_leaf_entry_t) +
194 (uint)sizeof(xfs_dir_leaf_name_t));
195 }
196 count = shortcount > leafcount ? shortcount : leafcount;
197 mp->m_dircook_elog = xfs_da_log2_roundup(count + 1);
198 ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog);
199 mp->m_dir_node_ents = mp->m_attr_node_ents =
200 (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) /
201 (uint)sizeof(xfs_da_node_entry_t);
202 mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100;
203 mp->m_dirblksize = mp->m_sb.sb_blocksize;
204 mp->m_dirblkfsbs = 1;
205}
206
207/*
208 * Return 1 if directory contains only "." and "..".
209 */
210static int
211xfs_dir_isempty(xfs_inode_t *dp)
212{
213 xfs_dir_sf_hdr_t *hdr;
214
215 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
216 if (dp->i_d.di_size == 0)
217 return(1);
218 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
219 return(0);
220 hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data;
221 return(hdr->count == 0);
222}
223
224/*
225 * Initialize a directory with its "." and ".." entries.
226 */
227static int
228xfs_dir_init(xfs_trans_t *trans, xfs_inode_t *dir, xfs_inode_t *parent_dir)
229{
230 xfs_da_args_t args;
231 int error;
232
233 memset((char *)&args, 0, sizeof(args));
234 args.dp = dir;
235 args.trans = trans;
236
237 ASSERT((dir->i_d.di_mode & S_IFMT) == S_IFDIR);
238 if ((error = xfs_dir_ino_validate(trans->t_mountp, parent_dir->i_ino)))
239 return error;
240
241 return(xfs_dir_shortform_create(&args, parent_dir->i_ino));
242}
243
244/*
245 * Generic handler routine to add a name to a directory.
246 * Transitions directory from shortform to Btree as necessary.
247 */
248static int /* error */
249xfs_dir_createname(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
250 int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock,
251 xfs_bmap_free_t *flist, xfs_extlen_t total)
252{
253 xfs_da_args_t args;
254 int retval, newsize, done;
255
256 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
257
258 if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
259 return (retval);
260
261 XFS_STATS_INC(xs_dir_create);
262 /*
263 * Fill in the arg structure for this request.
264 */
265 args.name = name;
266 args.namelen = namelen;
267 args.hashval = xfs_da_hashname(name, namelen);
268 args.inumber = inum;
269 args.dp = dp;
270 args.firstblock = firstblock;
271 args.flist = flist;
272 args.total = total;
273 args.whichfork = XFS_DATA_FORK;
274 args.trans = trans;
275 args.justcheck = 0;
276 args.addname = args.oknoent = 1;
277
278 /*
279 * Decide on what work routines to call based on the inode size.
280 */
281 done = 0;
282 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
283 newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
284 if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) {
285 retval = xfs_dir_shortform_addname(&args);
286 done = 1;
287 } else {
288 if (total == 0)
289 return XFS_ERROR(ENOSPC);
290 retval = xfs_dir_shortform_to_leaf(&args);
291 done = retval != 0;
292 }
293 }
294 if (!done && xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
295 retval = xfs_dir_leaf_addname(&args);
296 done = retval != ENOSPC;
297 if (!done) {
298 if (total == 0)
299 return XFS_ERROR(ENOSPC);
300 retval = xfs_dir_leaf_to_node(&args);
301 done = retval != 0;
302 }
303 }
304 if (!done) {
305 retval = xfs_dir_node_addname(&args);
306 }
307 return(retval);
308}
309
310/*
311 * Generic handler routine to check if a name can be added to a directory,
312 * without adding any blocks to the directory.
313 */
314static int /* error */
315xfs_dir_canenter(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen)
316{
317 xfs_da_args_t args;
318 int retval, newsize;
319
320 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
321 /*
322 * Fill in the arg structure for this request.
323 */
324 args.name = name;
325 args.namelen = namelen;
326 args.hashval = xfs_da_hashname(name, namelen);
327 args.inumber = 0;
328 args.dp = dp;
329 args.firstblock = NULL;
330 args.flist = NULL;
331 args.total = 0;
332 args.whichfork = XFS_DATA_FORK;
333 args.trans = trans;
334 args.justcheck = args.addname = args.oknoent = 1;
335
336 /*
337 * Decide on what work routines to call based on the inode size.
338 */
339 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
340 newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
341 if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp))
342 retval = 0;
343 else
344 retval = XFS_ERROR(ENOSPC);
345 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
346 retval = xfs_dir_leaf_addname(&args);
347 } else {
348 retval = xfs_dir_node_addname(&args);
349 }
350 return(retval);
351}
352
353/*
354 * Generic handler routine to remove a name from a directory.
355 * Transitions directory from Btree to shortform as necessary.
356 */
357static int /* error */
358xfs_dir_removename(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
359 int namelen, xfs_ino_t ino, xfs_fsblock_t *firstblock,
360 xfs_bmap_free_t *flist, xfs_extlen_t total)
361{
362 xfs_da_args_t args;
363 int count, totallen, newsize, retval;
364
365 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
366 XFS_STATS_INC(xs_dir_remove);
367 /*
368 * Fill in the arg structure for this request.
369 */
370 args.name = name;
371 args.namelen = namelen;
372 args.hashval = xfs_da_hashname(name, namelen);
373 args.inumber = ino;
374 args.dp = dp;
375 args.firstblock = firstblock;
376 args.flist = flist;
377 args.total = total;
378 args.whichfork = XFS_DATA_FORK;
379 args.trans = trans;
380 args.justcheck = args.addname = args.oknoent = 0;
381
382 /*
383 * Decide on what work routines to call based on the inode size.
384 */
385 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
386 retval = xfs_dir_shortform_removename(&args);
387 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
388 retval = xfs_dir_leaf_removename(&args, &count, &totallen);
389 if (retval == 0) {
390 newsize = XFS_DIR_SF_ALLFIT(count, totallen);
391 if (newsize <= XFS_IFORK_DSIZE(dp)) {
392 retval = xfs_dir_leaf_to_shortform(&args);
393 }
394 }
395 } else {
396 retval = xfs_dir_node_removename(&args);
397 }
398 return(retval);
399}
400
401static int /* error */
402xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
403 xfs_ino_t *inum)
404{
405 xfs_da_args_t args;
406 int retval;
407
408 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
409
410 XFS_STATS_INC(xs_dir_lookup);
411 /*
412 * Fill in the arg structure for this request.
413 */
414 args.name = name;
415 args.namelen = namelen;
416 args.hashval = xfs_da_hashname(name, namelen);
417 args.inumber = 0;
418 args.dp = dp;
419 args.firstblock = NULL;
420 args.flist = NULL;
421 args.total = 0;
422 args.whichfork = XFS_DATA_FORK;
423 args.trans = trans;
424 args.justcheck = args.addname = 0;
425 args.oknoent = 1;
426
427 /*
428 * Decide on what work routines to call based on the inode size.
429 */
430 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
431 retval = xfs_dir_shortform_lookup(&args);
432 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
433 retval = xfs_dir_leaf_lookup(&args);
434 } else {
435 retval = xfs_dir_node_lookup(&args);
436 }
437 if (retval == EEXIST)
438 retval = 0;
439 *inum = args.inumber;
440 return(retval);
441}
442
443/*
444 * Implement readdir.
445 */
446static int /* error */
447xfs_dir_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, int *eofp)
448{
449 xfs_dirent_t *dbp;
450 int alignment, retval;
451 xfs_dir_put_t put;
452
453 XFS_STATS_INC(xs_dir_getdents);
454 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
455
456 /*
457 * If our caller has given us a single contiguous memory buffer,
458 * just work directly within that buffer. If it's in user memory,
459 * lock it down first.
460 */
461 alignment = sizeof(xfs_off_t) - 1;
462 if ((uio->uio_iovcnt == 1) &&
463 (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) &&
464 ((uio->uio_iov[0].iov_len & alignment) == 0)) {
465 dbp = NULL;
466 put = xfs_dir_put_dirent64_direct;
467 } else {
468 dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP);
469 put = xfs_dir_put_dirent64_uio;
470 }
471
472 /*
473 * Decide on what work routines to call based on the inode size.
474 */
475 *eofp = 0;
476
477 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
478 retval = xfs_dir_shortform_getdents(dp, uio, eofp, dbp, put);
479 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
480 retval = xfs_dir_leaf_getdents(trans, dp, uio, eofp, dbp, put);
481 } else {
482 retval = xfs_dir_node_getdents(trans, dp, uio, eofp, dbp, put);
483 }
484 if (dbp != NULL)
485 kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN);
486
487 return(retval);
488}
489
490static int /* error */
491xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
492 xfs_ino_t inum, xfs_fsblock_t *firstblock,
493 xfs_bmap_free_t *flist, xfs_extlen_t total)
494{
495 xfs_da_args_t args;
496 int retval;
497
498 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
499
500 if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
501 return retval;
502
503 /*
504 * Fill in the arg structure for this request.
505 */
506 args.name = name;
507 args.namelen = namelen;
508 args.hashval = xfs_da_hashname(name, namelen);
509 args.inumber = inum;
510 args.dp = dp;
511 args.firstblock = firstblock;
512 args.flist = flist;
513 args.total = total;
514 args.whichfork = XFS_DATA_FORK;
515 args.trans = trans;
516 args.justcheck = args.addname = args.oknoent = 0;
517
518 /*
519 * Decide on what work routines to call based on the inode size.
520 */
521 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
522 retval = xfs_dir_shortform_replace(&args);
523 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
524 retval = xfs_dir_leaf_replace(&args);
525 } else {
526 retval = xfs_dir_node_replace(&args);
527 }
528
529 return(retval);
530}
531
532static int
533xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, xfs_dinode_t *dp)
534{
535 xfs_ino_t ino;
536 int namelen_sum;
537 int count;
538 xfs_dir_shortform_t *sf;
539 xfs_dir_sf_entry_t *sfe;
540 int i;
541
542
543
544 if ((INT_GET(dp->di_core.di_mode, ARCH_CONVERT) & S_IFMT) != S_IFDIR) {
545 return 0;
546 }
547 if (INT_GET(dp->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_LOCAL) {
548 return 0;
549 }
550 if (INT_GET(dp->di_core.di_size, ARCH_CONVERT) < sizeof(sf->hdr)) {
551 xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform size: dp 0x%p",
552 dp);
553 return 1;
554 }
555 sf = (xfs_dir_shortform_t *)(&dp->di_u.di_dirsf);
556 ino = XFS_GET_DIR_INO8(sf->hdr.parent);
557 if (xfs_dir_ino_validate(mp, ino))
558 return 1;
559
560 count = sf->hdr.count;
561 if ((count < 0) || ((count * 10) > XFS_LITINO(mp))) {
562 xfs_fs_cmn_err(CE_WARN, mp,
563 "Invalid shortform count: dp 0x%p", dp);
564 return(1);
565 }
566
567 if (count == 0) {
568 return 0;
569 }
570
571 namelen_sum = 0;
572 sfe = &sf->list[0];
573 for (i = sf->hdr.count - 1; i >= 0; i--) {
574 ino = XFS_GET_DIR_INO8(sfe->inumber);
575 xfs_dir_ino_validate(mp, ino);
576 if (sfe->namelen >= XFS_LITINO(mp)) {
577 xfs_fs_cmn_err(CE_WARN, mp,
578 "Invalid shortform namelen: dp 0x%p", dp);
579 return 1;
580 }
581 namelen_sum += sfe->namelen;
582 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
583 }
584 if (namelen_sum >= XFS_LITINO(mp)) {
585 xfs_fs_cmn_err(CE_WARN, mp,
586 "Invalid shortform namelen: dp 0x%p", dp);
587 return 1;
588 }
589
590 return 0;
591}
592
593/*========================================================================
594 * External routines when dirsize == XFS_LBSIZE(dp->i_mount).
595 *========================================================================*/
596
597/*
598 * Add a name to the leaf directory structure
599 * This is the external routine.
600 */
601int
602xfs_dir_leaf_addname(xfs_da_args_t *args)
603{
604 int index, retval;
605 xfs_dabuf_t *bp;
606
607 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
608 XFS_DATA_FORK);
609 if (retval)
610 return(retval);
611 ASSERT(bp != NULL);
612
613 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
614 if (retval == ENOENT)
615 retval = xfs_dir_leaf_add(bp, args, index);
616 xfs_da_buf_done(bp);
617 return(retval);
618}
619
620/*
621 * Remove a name from the leaf directory structure
622 * This is the external routine.
623 */
624STATIC int
625xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen)
626{
627 xfs_dir_leafblock_t *leaf;
628 int index, retval;
629 xfs_dabuf_t *bp;
630
631 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
632 XFS_DATA_FORK);
633 if (retval)
634 return(retval);
635 ASSERT(bp != NULL);
636 leaf = bp->data;
637 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
638 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
639 if (retval == EEXIST) {
640 (void)xfs_dir_leaf_remove(args->trans, bp, index);
641 *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
642 *totallen = INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
643 retval = 0;
644 }
645 xfs_da_buf_done(bp);
646 return(retval);
647}
648
649/*
650 * Look up a name in a leaf directory structure.
651 * This is the external routine.
652 */
653STATIC int
654xfs_dir_leaf_lookup(xfs_da_args_t *args)
655{
656 int index, retval;
657 xfs_dabuf_t *bp;
658
659 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
660 XFS_DATA_FORK);
661 if (retval)
662 return(retval);
663 ASSERT(bp != NULL);
664 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
665 xfs_da_brelse(args->trans, bp);
666 return(retval);
667}
668
669/*
670 * Copy out directory entries for getdents(), for leaf directories.
671 */
672STATIC int
673xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
674 int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
675{
676 xfs_dabuf_t *bp;
677 int retval, eob;
678
679 retval = xfs_da_read_buf(dp->i_transp, dp, 0, -1, &bp, XFS_DATA_FORK);
680 if (retval)
681 return(retval);
682 ASSERT(bp != NULL);
683 retval = xfs_dir_leaf_getdents_int(bp, dp, 0, uio, &eob, dbp, put, -1);
684 xfs_da_brelse(trans, bp);
685 *eofp = (eob == 0);
686 return(retval);
687}
688
689/*
690 * Look up a name in a leaf directory structure, replace the inode number.
691 * This is the external routine.
692 */
693STATIC int
694xfs_dir_leaf_replace(xfs_da_args_t *args)
695{
696 int index, retval;
697 xfs_dabuf_t *bp;
698 xfs_ino_t inum;
699 xfs_dir_leafblock_t *leaf;
700 xfs_dir_leaf_entry_t *entry;
701 xfs_dir_leaf_name_t *namest;
702
703 inum = args->inumber;
704 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
705 XFS_DATA_FORK);
706 if (retval)
707 return(retval);
708 ASSERT(bp != NULL);
709 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
710 if (retval == EEXIST) {
711 leaf = bp->data;
712 entry = &leaf->entries[index];
713 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
714 /* XXX - replace assert? */
715 XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
716 xfs_da_log_buf(args->trans, bp,
717 XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
718 xfs_da_buf_done(bp);
719 retval = 0;
720 } else
721 xfs_da_brelse(args->trans, bp);
722 return(retval);
723}
724
725
726/*========================================================================
727 * External routines when dirsize > XFS_LBSIZE(mp).
728 *========================================================================*/
729
730/*
731 * Add a name to a Btree-format directory.
732 *
733 * This will involve walking down the Btree, and may involve splitting
734 * leaf nodes and even splitting intermediate nodes up to and including
735 * the root node (a special case of an intermediate node).
736 */
737STATIC int
738xfs_dir_node_addname(xfs_da_args_t *args)
739{
740 xfs_da_state_t *state;
741 xfs_da_state_blk_t *blk;
742 int retval, error;
743
744 /*
745 * Fill in bucket of arguments/results/context to carry around.
746 */
747 state = xfs_da_state_alloc();
748 state->args = args;
749 state->mp = args->dp->i_mount;
750 state->blocksize = state->mp->m_sb.sb_blocksize;
751 state->node_ents = state->mp->m_dir_node_ents;
752
753 /*
754 * Search to see if name already exists, and get back a pointer
755 * to where it should go.
756 */
757 error = xfs_da_node_lookup_int(state, &retval);
758 if (error)
759 retval = error;
760 if (retval != ENOENT)
761 goto error;
762 blk = &state->path.blk[ state->path.active-1 ];
763 ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
764 retval = xfs_dir_leaf_add(blk->bp, args, blk->index);
765 if (retval == 0) {
766 /*
767 * Addition succeeded, update Btree hashvals.
768 */
769 if (!args->justcheck)
770 xfs_da_fixhashpath(state, &state->path);
771 } else {
772 /*
773 * Addition failed, split as many Btree elements as required.
774 */
775 if (args->total == 0) {
776 ASSERT(retval == ENOSPC);
777 goto error;
778 }
779 retval = xfs_da_split(state);
780 }
781error:
782 xfs_da_state_free(state);
783
784 return(retval);
785}
786
787/*
788 * Remove a name from a B-tree directory.
789 *
790 * This will involve walking down the Btree, and may involve joining
791 * leaf nodes and even joining intermediate nodes up to and including
792 * the root node (a special case of an intermediate node).
793 */
794STATIC int
795xfs_dir_node_removename(xfs_da_args_t *args)
796{
797 xfs_da_state_t *state;
798 xfs_da_state_blk_t *blk;
799 int retval, error;
800
801 state = xfs_da_state_alloc();
802 state->args = args;
803 state->mp = args->dp->i_mount;
804 state->blocksize = state->mp->m_sb.sb_blocksize;
805 state->node_ents = state->mp->m_dir_node_ents;
806
807 /*
808 * Search to see if name exists, and get back a pointer to it.
809 */
810 error = xfs_da_node_lookup_int(state, &retval);
811 if (error)
812 retval = error;
813 if (retval != EEXIST) {
814 xfs_da_state_free(state);
815 return(retval);
816 }
817
818 /*
819 * Remove the name and update the hashvals in the tree.
820 */
821 blk = &state->path.blk[ state->path.active-1 ];
822 ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
823 retval = xfs_dir_leaf_remove(args->trans, blk->bp, blk->index);
824 xfs_da_fixhashpath(state, &state->path);
825
826 /*
827 * Check to see if the tree needs to be collapsed.
828 */
829 error = 0;
830 if (retval) {
831 error = xfs_da_join(state);
832 }
833
834 xfs_da_state_free(state);
835 if (error)
836 return(error);
837 return(0);
838}
839
840/*
841 * Look up a filename in a int directory.
842 * Use an internal routine to actually do all the work.
843 */
844STATIC int
845xfs_dir_node_lookup(xfs_da_args_t *args)
846{
847 xfs_da_state_t *state;
848 int retval, error, i;
849
850 state = xfs_da_state_alloc();
851 state->args = args;
852 state->mp = args->dp->i_mount;
853 state->blocksize = state->mp->m_sb.sb_blocksize;
854 state->node_ents = state->mp->m_dir_node_ents;
855
856 /*
857 * Search to see if name exists,
858 * and get back a pointer to it.
859 */
860 error = xfs_da_node_lookup_int(state, &retval);
861 if (error) {
862 retval = error;
863 }
864
865 /*
866 * If not in a transaction, we have to release all the buffers.
867 */
868 for (i = 0; i < state->path.active; i++) {
869 xfs_da_brelse(args->trans, state->path.blk[i].bp);
870 state->path.blk[i].bp = NULL;
871 }
872
873 xfs_da_state_free(state);
874 return(retval);
875}
876
877STATIC int
878xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
879 int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
880{
881 xfs_da_intnode_t *node;
882 xfs_da_node_entry_t *btree;
883 xfs_dir_leafblock_t *leaf = NULL;
884 xfs_dablk_t bno, nextbno;
885 xfs_dahash_t cookhash;
886 xfs_mount_t *mp;
887 int error, eob, i;
888 xfs_dabuf_t *bp;
889 xfs_daddr_t nextda;
890
891 /*
892 * Pick up our context.
893 */
894 mp = dp->i_mount;
895 bp = NULL;
896 bno = XFS_DA_COOKIE_BNO(mp, uio->uio_offset);
897 cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
898
899 xfs_dir_trace_g_du("node: start", dp, uio);
900
901 /*
902 * Re-find our place, even if we're confused about what our place is.
903 *
904 * First we check the block number from the magic cookie, it is a
905 * cache of where we ended last time. If we find a leaf block, and
906 * the starting hashval in that block is less than our desired
907 * hashval, then we run with it.
908 */
909 if (bno > 0) {
910 error = xfs_da_read_buf(trans, dp, bno, -2, &bp, XFS_DATA_FORK);
911 if ((error != 0) && (error != EFSCORRUPTED))
912 return(error);
913 if (bp)
914 leaf = bp->data;
915 if (bp && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
916 xfs_dir_trace_g_dub("node: block not a leaf",
917 dp, uio, bno);
918 xfs_da_brelse(trans, bp);
919 bp = NULL;
920 }
921 if (bp && INT_GET(leaf->entries[0].hashval, ARCH_CONVERT) > cookhash) {
922 xfs_dir_trace_g_dub("node: leaf hash too large",
923 dp, uio, bno);
924 xfs_da_brelse(trans, bp);
925 bp = NULL;
926 }
927 if (bp &&
928 cookhash > INT_GET(leaf->entries[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT)) {
929 xfs_dir_trace_g_dub("node: leaf hash too small",
930 dp, uio, bno);
931 xfs_da_brelse(trans, bp);
932 bp = NULL;
933 }
934 }
935
936 /*
937 * If we did not find a leaf block from the blockno in the cookie,
938 * or we there was no blockno in the cookie (eg: first time thru),
939 * the we start at the top of the Btree and re-find our hashval.
940 */
941 if (bp == NULL) {
942 xfs_dir_trace_g_du("node: start at root" , dp, uio);
943 bno = 0;
944 for (;;) {
945 error = xfs_da_read_buf(trans, dp, bno, -1, &bp,
946 XFS_DATA_FORK);
947 if (error)
948 return(error);
949 if (bp == NULL)
950 return(XFS_ERROR(EFSCORRUPTED));
951 node = bp->data;
952 if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC)
953 break;
954 btree = &node->btree[0];
955 xfs_dir_trace_g_dun("node: node detail", dp, uio, node);
956 for (i = 0; i < be16_to_cpu(node->hdr.count); btree++, i++) {
957 if (be32_to_cpu(btree->hashval) >= cookhash) {
958 bno = be32_to_cpu(btree->before);
959 break;
960 }
961 }
962 if (i == be16_to_cpu(node->hdr.count)) {
963 xfs_da_brelse(trans, bp);
964 xfs_dir_trace_g_du("node: hash beyond EOF",
965 dp, uio);
966 uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0,
967 XFS_DA_MAXHASH);
968 *eofp = 1;
969 return(0);
970 }
971 xfs_dir_trace_g_dub("node: going to block",
972 dp, uio, bno);
973 xfs_da_brelse(trans, bp);
974 }
975 }
976 ASSERT(cookhash != XFS_DA_MAXHASH);
977
978 /*
979 * We've dropped down to the (first) leaf block that contains the
980 * hashval we are interested in. Continue rolling upward thru the
981 * leaf blocks until we fill up our buffer.
982 */
983 for (;;) {
984 leaf = bp->data;
985 if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC)) {
986 xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf);
987 xfs_da_brelse(trans, bp);
988 XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)",
989 XFS_ERRLEVEL_LOW, mp, leaf);
990 return XFS_ERROR(EFSCORRUPTED);
991 }
992 xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf);
993 if ((nextbno = be32_to_cpu(leaf->hdr.info.forw))) {
994 nextda = xfs_da_reada_buf(trans, dp, nextbno,
995 XFS_DATA_FORK);
996 } else
997 nextda = -1;
998 error = xfs_dir_leaf_getdents_int(bp, dp, bno, uio, &eob, dbp,
999 put, nextda);
1000 xfs_da_brelse(trans, bp);
1001 bno = nextbno;
1002 if (eob) {
1003 xfs_dir_trace_g_dub("node: E-O-B", dp, uio, bno);
1004 *eofp = 0;
1005 return(error);
1006 }
1007 if (bno == 0)
1008 break;
1009 error = xfs_da_read_buf(trans, dp, bno, nextda, &bp,
1010 XFS_DATA_FORK);
1011 if (error)
1012 return(error);
1013 if (unlikely(bp == NULL)) {
1014 XFS_ERROR_REPORT("xfs_dir_node_getdents(2)",
1015 XFS_ERRLEVEL_LOW, mp);
1016 return(XFS_ERROR(EFSCORRUPTED));
1017 }
1018 }
1019 *eofp = 1;
1020 xfs_dir_trace_g_du("node: E-O-F", dp, uio);
1021 return(0);
1022}
1023
1024/*
1025 * Look up a filename in an int directory, replace the inode number.
1026 * Use an internal routine to actually do the lookup.
1027 */
1028STATIC int
1029xfs_dir_node_replace(xfs_da_args_t *args)
1030{
1031 xfs_da_state_t *state;
1032 xfs_da_state_blk_t *blk;
1033 xfs_dir_leafblock_t *leaf;
1034 xfs_dir_leaf_entry_t *entry;
1035 xfs_dir_leaf_name_t *namest;
1036 xfs_ino_t inum;
1037 int retval, error, i;
1038 xfs_dabuf_t *bp;
1039
1040 state = xfs_da_state_alloc();
1041 state->args = args;
1042 state->mp = args->dp->i_mount;
1043 state->blocksize = state->mp->m_sb.sb_blocksize;
1044 state->node_ents = state->mp->m_dir_node_ents;
1045 inum = args->inumber;
1046
1047 /*
1048 * Search to see if name exists,
1049 * and get back a pointer to it.
1050 */
1051 error = xfs_da_node_lookup_int(state, &retval);
1052 if (error) {
1053 retval = error;
1054 }
1055
1056 if (retval == EEXIST) {
1057 blk = &state->path.blk[state->path.active - 1];
1058 ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
1059 bp = blk->bp;
1060 leaf = bp->data;
1061 entry = &leaf->entries[blk->index];
1062 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
1063 /* XXX - replace assert ? */
1064 XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
1065 xfs_da_log_buf(args->trans, bp,
1066 XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
1067 xfs_da_buf_done(bp);
1068 blk->bp = NULL;
1069 retval = 0;
1070 } else {
1071 i = state->path.active - 1;
1072 xfs_da_brelse(args->trans, state->path.blk[i].bp);
1073 state->path.blk[i].bp = NULL;
1074 }
1075 for (i = 0; i < state->path.active - 1; i++) {
1076 xfs_da_brelse(args->trans, state->path.blk[i].bp);
1077 state->path.blk[i].bp = NULL;
1078 }
1079
1080 xfs_da_state_free(state);
1081 return(retval);
1082}
1083
1084#if defined(XFS_DIR_TRACE)
1085/*
1086 * Add a trace buffer entry for an inode and a uio.
1087 */
1088void
1089xfs_dir_trace_g_du(char *where, xfs_inode_t *dp, uio_t *uio)
1090{
1091 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DU, where,
1092 (void *)dp, (void *)dp->i_mount,
1093 (void *)((unsigned long)(uio->uio_offset >> 32)),
1094 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1095 (void *)(unsigned long)uio->uio_resid,
1096 NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1097}
1098
1099/*
1100 * Add a trace buffer entry for an inode and a uio.
1101 */
1102void
1103xfs_dir_trace_g_dub(char *where, xfs_inode_t *dp, uio_t *uio, xfs_dablk_t bno)
1104{
1105 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUB, where,
1106 (void *)dp, (void *)dp->i_mount,
1107 (void *)((unsigned long)(uio->uio_offset >> 32)),
1108 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1109 (void *)(unsigned long)uio->uio_resid,
1110 (void *)(unsigned long)bno,
1111 NULL, NULL, NULL, NULL, NULL, NULL);
1112}
1113
1114/*
1115 * Add a trace buffer entry for an inode and a uio.
1116 */
1117void
1118xfs_dir_trace_g_dun(char *where, xfs_inode_t *dp, uio_t *uio,
1119 xfs_da_intnode_t *node)
1120{
1121 int last = be16_to_cpu(node->hdr.count) - 1;
1122
1123 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUN, where,
1124 (void *)dp, (void *)dp->i_mount,
1125 (void *)((unsigned long)(uio->uio_offset >> 32)),
1126 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1127 (void *)(unsigned long)uio->uio_resid,
1128 (void *)(unsigned long)be32_to_cpu(node->hdr.info.forw),
1129 (void *)(unsigned long)
1130 be16_to_cpu(node->hdr.count),
1131 (void *)(unsigned long)
1132 be32_to_cpu(node->btree[0].hashval),
1133 (void *)(unsigned long)
1134 be32_to_cpu(node->btree[last].hashval),
1135 NULL, NULL, NULL);
1136}
1137
1138/*
1139 * Add a trace buffer entry for an inode and a uio.
1140 */
1141void
1142xfs_dir_trace_g_dul(char *where, xfs_inode_t *dp, uio_t *uio,
1143 xfs_dir_leafblock_t *leaf)
1144{
1145 int last = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1;
1146
1147 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUL, where,
1148 (void *)dp, (void *)dp->i_mount,
1149 (void *)((unsigned long)(uio->uio_offset >> 32)),
1150 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1151 (void *)(unsigned long)uio->uio_resid,
1152 (void *)(unsigned long)be32_to_cpu(leaf->hdr.info.forw),
1153 (void *)(unsigned long)
1154 INT_GET(leaf->hdr.count, ARCH_CONVERT),
1155 (void *)(unsigned long)
1156 INT_GET(leaf->entries[0].hashval, ARCH_CONVERT),
1157 (void *)(unsigned long)
1158 INT_GET(leaf->entries[last].hashval, ARCH_CONVERT),
1159 NULL, NULL, NULL);
1160}
1161
1162/*
1163 * Add a trace buffer entry for an inode and a uio.
1164 */
1165void
1166xfs_dir_trace_g_due(char *where, xfs_inode_t *dp, uio_t *uio,
1167 xfs_dir_leaf_entry_t *entry)
1168{
1169 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUE, where,
1170 (void *)dp, (void *)dp->i_mount,
1171 (void *)((unsigned long)(uio->uio_offset >> 32)),
1172 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1173 (void *)(unsigned long)uio->uio_resid,
1174 (void *)(unsigned long)
1175 INT_GET(entry->hashval, ARCH_CONVERT),
1176 NULL, NULL, NULL, NULL, NULL, NULL);
1177}
1178
1179/*
1180 * Add a trace buffer entry for an inode and a uio.
1181 */
1182void
1183xfs_dir_trace_g_duc(char *where, xfs_inode_t *dp, uio_t *uio, xfs_off_t cookie)
1184{
1185 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUC, where,
1186 (void *)dp, (void *)dp->i_mount,
1187 (void *)((unsigned long)(uio->uio_offset >> 32)),
1188 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1189 (void *)(unsigned long)uio->uio_resid,
1190 (void *)((unsigned long)(cookie >> 32)),
1191 (void *)((unsigned long)(cookie & 0xFFFFFFFF)),
1192 NULL, NULL, NULL, NULL, NULL);
1193}
1194
1195/*
1196 * Add a trace buffer entry for the arguments given to the routine,
1197 * generic form.
1198 */
1199void
1200xfs_dir_trace_enter(int type, char *where,
1201 void * a0, void * a1,
1202 void * a2, void * a3,
1203 void * a4, void * a5,
1204 void * a6, void * a7,
1205 void * a8, void * a9,
1206 void * a10, void * a11)
1207{
1208 ASSERT(xfs_dir_trace_buf);
1209 ktrace_enter(xfs_dir_trace_buf, (void *)(unsigned long)type,
1210 (void *)where,
1211 (void *)a0, (void *)a1, (void *)a2,
1212 (void *)a3, (void *)a4, (void *)a5,
1213 (void *)a6, (void *)a7, (void *)a8,
1214 (void *)a9, (void *)a10, (void *)a11,
1215 NULL, NULL);
1216}
1217#endif /* XFS_DIR_TRACE */
diff --git a/fs/xfs/xfs_dir.h b/fs/xfs/xfs_dir.h
deleted file mode 100644
index 8cc8afb9f6c0..000000000000
--- a/fs/xfs/xfs_dir.h
+++ /dev/null
@@ -1,142 +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_DIR_H__
19#define __XFS_DIR_H__
20
21/*
22 * Large directories are structured around Btrees where all the data
23 * elements are in the leaf nodes. Filenames are hashed into an int,
24 * then that int is used as the index into the Btree. Since the hashval
25 * of a filename may not be unique, we may have duplicate keys. The
26 * internal links in the Btree are logical block offsets into the file.
27 *
28 * Small directories use a different format and are packed as tightly
29 * as possible so as to fit into the literal area of the inode.
30 */
31
32/*========================================================================
33 * Function prototypes for the kernel.
34 *========================================================================*/
35
36struct uio;
37struct xfs_bmap_free;
38struct xfs_da_args;
39struct xfs_dinode;
40struct xfs_inode;
41struct xfs_mount;
42struct xfs_trans;
43
44/*
45 * Directory function types.
46 * Put in structures (xfs_dirops_t) for v1 and v2 directories.
47 */
48typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp);
49typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp);
50typedef int (*xfs_dir_init_t)(struct xfs_trans *tp,
51 struct xfs_inode *dp,
52 struct xfs_inode *pdp);
53typedef int (*xfs_dir_createname_t)(struct xfs_trans *tp,
54 struct xfs_inode *dp,
55 char *name,
56 int namelen,
57 xfs_ino_t inum,
58 xfs_fsblock_t *first,
59 struct xfs_bmap_free *flist,
60 xfs_extlen_t total);
61typedef int (*xfs_dir_lookup_t)(struct xfs_trans *tp,
62 struct xfs_inode *dp,
63 char *name,
64 int namelen,
65 xfs_ino_t *inum);
66typedef int (*xfs_dir_removename_t)(struct xfs_trans *tp,
67 struct xfs_inode *dp,
68 char *name,
69 int namelen,
70 xfs_ino_t ino,
71 xfs_fsblock_t *first,
72 struct xfs_bmap_free *flist,
73 xfs_extlen_t total);
74typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp,
75 struct xfs_inode *dp,
76 struct uio *uio,
77 int *eofp);
78typedef int (*xfs_dir_replace_t)(struct xfs_trans *tp,
79 struct xfs_inode *dp,
80 char *name,
81 int namelen,
82 xfs_ino_t inum,
83 xfs_fsblock_t *first,
84 struct xfs_bmap_free *flist,
85 xfs_extlen_t total);
86typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp,
87 struct xfs_inode *dp,
88 char *name,
89 int namelen);
90typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp,
91 struct xfs_dinode *dip);
92typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args);
93
94typedef struct xfs_dirops {
95 xfs_dir_mount_t xd_mount;
96 xfs_dir_isempty_t xd_isempty;
97 xfs_dir_init_t xd_init;
98 xfs_dir_createname_t xd_createname;
99 xfs_dir_lookup_t xd_lookup;
100 xfs_dir_removename_t xd_removename;
101 xfs_dir_getdents_t xd_getdents;
102 xfs_dir_replace_t xd_replace;
103 xfs_dir_canenter_t xd_canenter;
104 xfs_dir_shortform_validate_ondisk_t xd_shortform_validate_ondisk;
105 xfs_dir_shortform_to_single_t xd_shortform_to_single;
106} xfs_dirops_t;
107
108/*
109 * Overall external interface routines.
110 */
111void xfs_dir_startup(void); /* called exactly once */
112
113#define XFS_DIR_MOUNT(mp) \
114 ((mp)->m_dirops.xd_mount(mp))
115#define XFS_DIR_ISEMPTY(mp,dp) \
116 ((mp)->m_dirops.xd_isempty(dp))
117#define XFS_DIR_INIT(mp,tp,dp,pdp) \
118 ((mp)->m_dirops.xd_init(tp,dp,pdp))
119#define XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \
120 ((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\
121 total))
122#define XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum) \
123 ((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum))
124#define XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total) \
125 ((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total))
126#define XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp) \
127 ((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp))
128#define XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total) \
129 ((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total))
130#define XFS_DIR_CANENTER(mp,tp,dp,name,namelen) \
131 ((mp)->m_dirops.xd_canenter(tp,dp,name,namelen))
132#define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) \
133 ((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip))
134#define XFS_DIR_SHORTFORM_TO_SINGLE(mp,args) \
135 ((mp)->m_dirops.xd_shortform_to_single(args))
136
137#define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1)
138#define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2)
139extern xfs_dirops_t xfsv1_dirops;
140extern xfs_dirops_t xfsv2_dirops;
141
142#endif /* __XFS_DIR_H__ */
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 022c8398ab62..8edbe1adb95b 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -24,21 +24,18 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_da_btree.h" 30#include "xfs_da_btree.h"
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
38#include "xfs_inode.h" 36#include "xfs_inode.h"
39#include "xfs_inode_item.h" 37#include "xfs_inode_item.h"
40#include "xfs_bmap.h" 38#include "xfs_bmap.h"
41#include "xfs_dir_leaf.h"
42#include "xfs_dir2_data.h" 39#include "xfs_dir2_data.h"
43#include "xfs_dir2_leaf.h" 40#include "xfs_dir2_leaf.h"
44#include "xfs_dir2_block.h" 41#include "xfs_dir2_block.h"
@@ -46,69 +43,14 @@
46#include "xfs_dir2_trace.h" 43#include "xfs_dir2_trace.h"
47#include "xfs_error.h" 44#include "xfs_error.h"
48 45
49/*
50 * Declarations for interface routines.
51 */
52static void xfs_dir2_mount(xfs_mount_t *mp);
53static int xfs_dir2_isempty(xfs_inode_t *dp);
54static int xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp,
55 xfs_inode_t *pdp);
56static int xfs_dir2_createname(xfs_trans_t *tp, xfs_inode_t *dp,
57 char *name, int namelen, xfs_ino_t inum,
58 xfs_fsblock_t *first,
59 xfs_bmap_free_t *flist, xfs_extlen_t total);
60static int xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
61 int namelen, xfs_ino_t *inum);
62static int xfs_dir2_removename(xfs_trans_t *tp, xfs_inode_t *dp,
63 char *name, int namelen, xfs_ino_t ino,
64 xfs_fsblock_t *first,
65 xfs_bmap_free_t *flist, xfs_extlen_t total);
66static int xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio,
67 int *eofp);
68static int xfs_dir2_replace(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
69 int namelen, xfs_ino_t inum,
70 xfs_fsblock_t *first, xfs_bmap_free_t *flist,
71 xfs_extlen_t total);
72static int xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
73 int namelen);
74static int xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp,
75 xfs_dinode_t *dip);
76
77/*
78 * Utility routine declarations.
79 */
80static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); 46static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);
81static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); 47static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa);
82 48
83/* 49void
84 * Directory operations vector. 50xfs_dir_mount(
85 */ 51 xfs_mount_t *mp)
86xfs_dirops_t xfsv2_dirops = {
87 .xd_mount = xfs_dir2_mount,
88 .xd_isempty = xfs_dir2_isempty,
89 .xd_init = xfs_dir2_init,
90 .xd_createname = xfs_dir2_createname,
91 .xd_lookup = xfs_dir2_lookup,
92 .xd_removename = xfs_dir2_removename,
93 .xd_getdents = xfs_dir2_getdents,
94 .xd_replace = xfs_dir2_replace,
95 .xd_canenter = xfs_dir2_canenter,
96 .xd_shortform_validate_ondisk = xfs_dir2_shortform_validate_ondisk,
97 .xd_shortform_to_single = xfs_dir2_sf_to_block,
98};
99
100/*
101 * Interface routines.
102 */
103
104/*
105 * Initialize directory-related fields in the mount structure.
106 */
107static void
108xfs_dir2_mount(
109 xfs_mount_t *mp) /* filesystem mount point */
110{ 52{
111 mp->m_dirversion = 2; 53 ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb));
112 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= 54 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=
113 XFS_MAX_BLOCKSIZE); 55 XFS_MAX_BLOCKSIZE);
114 mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); 56 mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
@@ -128,19 +70,15 @@ xfs_dir2_mount(
128/* 70/*
129 * Return 1 if directory contains only "." and "..". 71 * Return 1 if directory contains only "." and "..".
130 */ 72 */
131static int /* return code */ 73int
132xfs_dir2_isempty( 74xfs_dir_isempty(
133 xfs_inode_t *dp) /* incore inode structure */ 75 xfs_inode_t *dp)
134{ 76{
135 xfs_dir2_sf_t *sfp; /* shortform directory structure */ 77 xfs_dir2_sf_t *sfp;
136 78
137 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 79 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
138 /* 80 if (dp->i_d.di_size == 0) /* might happen during shutdown. */
139 * Might happen during shutdown.
140 */
141 if (dp->i_d.di_size == 0) {
142 return 1; 81 return 1;
143 }
144 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) 82 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
145 return 0; 83 return 0;
146 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 84 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
@@ -148,53 +86,83 @@ xfs_dir2_isempty(
148} 86}
149 87
150/* 88/*
89 * Validate a given inode number.
90 */
91int
92xfs_dir_ino_validate(
93 xfs_mount_t *mp,
94 xfs_ino_t ino)
95{
96 xfs_agblock_t agblkno;
97 xfs_agino_t agino;
98 xfs_agnumber_t agno;
99 int ino_ok;
100 int ioff;
101
102 agno = XFS_INO_TO_AGNO(mp, ino);
103 agblkno = XFS_INO_TO_AGBNO(mp, ino);
104 ioff = XFS_INO_TO_OFFSET(mp, ino);
105 agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
106 ino_ok =
107 agno < mp->m_sb.sb_agcount &&
108 agblkno < mp->m_sb.sb_agblocks &&
109 agblkno != 0 &&
110 ioff < (1 << mp->m_sb.sb_inopblog) &&
111 XFS_AGINO_TO_INO(mp, agno, agino) == ino;
112 if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
113 XFS_RANDOM_DIR_INO_VALIDATE))) {
114 xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
115 (unsigned long long) ino);
116 XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
117 return XFS_ERROR(EFSCORRUPTED);
118 }
119 return 0;
120}
121
122/*
151 * Initialize a directory with its "." and ".." entries. 123 * Initialize a directory with its "." and ".." entries.
152 */ 124 */
153static int /* error */ 125int
154xfs_dir2_init( 126xfs_dir_init(
155 xfs_trans_t *tp, /* transaction pointer */ 127 xfs_trans_t *tp,
156 xfs_inode_t *dp, /* incore directory inode */ 128 xfs_inode_t *dp,
157 xfs_inode_t *pdp) /* incore parent directory inode */ 129 xfs_inode_t *pdp)
158{ 130{
159 xfs_da_args_t args; /* operation arguments */ 131 xfs_da_args_t args;
160 int error; /* error return value */ 132 int error;
161 133
162 memset((char *)&args, 0, sizeof(args)); 134 memset((char *)&args, 0, sizeof(args));
163 args.dp = dp; 135 args.dp = dp;
164 args.trans = tp; 136 args.trans = tp;
165 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 137 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
166 if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) { 138 if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino)))
167 return error; 139 return error;
168 }
169 return xfs_dir2_sf_create(&args, pdp->i_ino); 140 return xfs_dir2_sf_create(&args, pdp->i_ino);
170} 141}
171 142
172/* 143/*
173 Enter a name in a directory. 144 Enter a name in a directory.
174 */ 145 */
175static int /* error */ 146int
176xfs_dir2_createname( 147xfs_dir_createname(
177 xfs_trans_t *tp, /* transaction pointer */ 148 xfs_trans_t *tp,
178 xfs_inode_t *dp, /* incore directory inode */ 149 xfs_inode_t *dp,
179 char *name, /* new entry name */ 150 char *name,
180 int namelen, /* new entry name length */ 151 int namelen,
181 xfs_ino_t inum, /* new entry inode number */ 152 xfs_ino_t inum, /* new entry inode number */
182 xfs_fsblock_t *first, /* bmap's firstblock */ 153 xfs_fsblock_t *first, /* bmap's firstblock */
183 xfs_bmap_free_t *flist, /* bmap's freeblock list */ 154 xfs_bmap_free_t *flist, /* bmap's freeblock list */
184 xfs_extlen_t total) /* bmap's total block count */ 155 xfs_extlen_t total) /* bmap's total block count */
185{ 156{
186 xfs_da_args_t args; /* operation arguments */ 157 xfs_da_args_t args;
187 int rval; /* return value */ 158 int rval;
188 int v; /* type-checking value */ 159 int v; /* type-checking value */
189 160
190 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 161 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
191 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { 162 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
192 return rval; 163 return rval;
193 }
194 XFS_STATS_INC(xs_dir_create); 164 XFS_STATS_INC(xs_dir_create);
195 /* 165
196 * Fill in the arg structure for this request.
197 */
198 args.name = name; 166 args.name = name;
199 args.namelen = namelen; 167 args.namelen = namelen;
200 args.hashval = xfs_da_hashname(name, namelen); 168 args.hashval = xfs_da_hashname(name, namelen);
@@ -207,18 +175,16 @@ xfs_dir2_createname(
207 args.trans = tp; 175 args.trans = tp;
208 args.justcheck = 0; 176 args.justcheck = 0;
209 args.addname = args.oknoent = 1; 177 args.addname = args.oknoent = 1;
210 /* 178
211 * Decide on what work routines to call based on the inode size.
212 */
213 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 179 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
214 rval = xfs_dir2_sf_addname(&args); 180 rval = xfs_dir2_sf_addname(&args);
215 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 181 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
216 return rval; 182 return rval;
217 } else if (v) 183 else if (v)
218 rval = xfs_dir2_block_addname(&args); 184 rval = xfs_dir2_block_addname(&args);
219 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 185 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
220 return rval; 186 return rval;
221 } else if (v) 187 else if (v)
222 rval = xfs_dir2_leaf_addname(&args); 188 rval = xfs_dir2_leaf_addname(&args);
223 else 189 else
224 rval = xfs_dir2_node_addname(&args); 190 rval = xfs_dir2_node_addname(&args);
@@ -228,24 +194,21 @@ xfs_dir2_createname(
228/* 194/*
229 * Lookup a name in a directory, give back the inode number. 195 * Lookup a name in a directory, give back the inode number.
230 */ 196 */
231static int /* error */ 197int
232xfs_dir2_lookup( 198xfs_dir_lookup(
233 xfs_trans_t *tp, /* transaction pointer */ 199 xfs_trans_t *tp,
234 xfs_inode_t *dp, /* incore directory inode */ 200 xfs_inode_t *dp,
235 char *name, /* lookup name */ 201 char *name,
236 int namelen, /* lookup name length */ 202 int namelen,
237 xfs_ino_t *inum) /* out: inode number */ 203 xfs_ino_t *inum) /* out: inode number */
238{ 204{
239 xfs_da_args_t args; /* operation arguments */ 205 xfs_da_args_t args;
240 int rval; /* return value */ 206 int rval;
241 int v; /* type-checking value */ 207 int v; /* type-checking value */
242 208
243 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 209 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
244 XFS_STATS_INC(xs_dir_lookup); 210 XFS_STATS_INC(xs_dir_lookup);
245 211
246 /*
247 * Fill in the arg structure for this request.
248 */
249 args.name = name; 212 args.name = name;
250 args.namelen = namelen; 213 args.namelen = namelen;
251 args.hashval = xfs_da_hashname(name, namelen); 214 args.hashval = xfs_da_hashname(name, namelen);
@@ -258,18 +221,16 @@ xfs_dir2_lookup(
258 args.trans = tp; 221 args.trans = tp;
259 args.justcheck = args.addname = 0; 222 args.justcheck = args.addname = 0;
260 args.oknoent = 1; 223 args.oknoent = 1;
261 /* 224
262 * Decide on what work routines to call based on the inode size.
263 */
264 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 225 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
265 rval = xfs_dir2_sf_lookup(&args); 226 rval = xfs_dir2_sf_lookup(&args);
266 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 227 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
267 return rval; 228 return rval;
268 } else if (v) 229 else if (v)
269 rval = xfs_dir2_block_lookup(&args); 230 rval = xfs_dir2_block_lookup(&args);
270 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 231 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
271 return rval; 232 return rval;
272 } else if (v) 233 else if (v)
273 rval = xfs_dir2_leaf_lookup(&args); 234 rval = xfs_dir2_leaf_lookup(&args);
274 else 235 else
275 rval = xfs_dir2_node_lookup(&args); 236 rval = xfs_dir2_node_lookup(&args);
@@ -283,26 +244,24 @@ xfs_dir2_lookup(
283/* 244/*
284 * Remove an entry from a directory. 245 * Remove an entry from a directory.
285 */ 246 */
286static int /* error */ 247int
287xfs_dir2_removename( 248xfs_dir_removename(
288 xfs_trans_t *tp, /* transaction pointer */ 249 xfs_trans_t *tp,
289 xfs_inode_t *dp, /* incore directory inode */ 250 xfs_inode_t *dp,
290 char *name, /* name of entry to remove */ 251 char *name,
291 int namelen, /* name length of entry to remove */ 252 int namelen,
292 xfs_ino_t ino, /* inode number of entry to remove */ 253 xfs_ino_t ino,
293 xfs_fsblock_t *first, /* bmap's firstblock */ 254 xfs_fsblock_t *first, /* bmap's firstblock */
294 xfs_bmap_free_t *flist, /* bmap's freeblock list */ 255 xfs_bmap_free_t *flist, /* bmap's freeblock list */
295 xfs_extlen_t total) /* bmap's total block count */ 256 xfs_extlen_t total) /* bmap's total block count */
296{ 257{
297 xfs_da_args_t args; /* operation arguments */ 258 xfs_da_args_t args;
298 int rval; /* return value */ 259 int rval;
299 int v; /* type-checking value */ 260 int v; /* type-checking value */
300 261
301 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 262 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
302 XFS_STATS_INC(xs_dir_remove); 263 XFS_STATS_INC(xs_dir_remove);
303 /* 264
304 * Fill in the arg structure for this request.
305 */
306 args.name = name; 265 args.name = name;
307 args.namelen = namelen; 266 args.namelen = namelen;
308 args.hashval = xfs_da_hashname(name, namelen); 267 args.hashval = xfs_da_hashname(name, namelen);
@@ -314,18 +273,16 @@ xfs_dir2_removename(
314 args.whichfork = XFS_DATA_FORK; 273 args.whichfork = XFS_DATA_FORK;
315 args.trans = tp; 274 args.trans = tp;
316 args.justcheck = args.addname = args.oknoent = 0; 275 args.justcheck = args.addname = args.oknoent = 0;
317 /* 276
318 * Decide on what work routines to call based on the inode size.
319 */
320 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 277 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
321 rval = xfs_dir2_sf_removename(&args); 278 rval = xfs_dir2_sf_removename(&args);
322 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 279 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
323 return rval; 280 return rval;
324 } else if (v) 281 else if (v)
325 rval = xfs_dir2_block_removename(&args); 282 rval = xfs_dir2_block_removename(&args);
326 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 283 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
327 return rval; 284 return rval;
328 } else if (v) 285 else if (v)
329 rval = xfs_dir2_leaf_removename(&args); 286 rval = xfs_dir2_leaf_removename(&args);
330 else 287 else
331 rval = xfs_dir2_node_removename(&args); 288 rval = xfs_dir2_node_removename(&args);
@@ -335,10 +292,10 @@ xfs_dir2_removename(
335/* 292/*
336 * Read a directory. 293 * Read a directory.
337 */ 294 */
338static int /* error */ 295int
339xfs_dir2_getdents( 296xfs_dir_getdents(
340 xfs_trans_t *tp, /* transaction pointer */ 297 xfs_trans_t *tp,
341 xfs_inode_t *dp, /* incore directory inode */ 298 xfs_inode_t *dp,
342 uio_t *uio, /* caller's buffer control */ 299 uio_t *uio, /* caller's buffer control */
343 int *eofp) /* out: eof reached */ 300 int *eofp) /* out: eof reached */
344{ 301{
@@ -367,14 +324,11 @@ xfs_dir2_getdents(
367 } 324 }
368 325
369 *eofp = 0; 326 *eofp = 0;
370 /*
371 * Decide on what work routines to call based on the inode size.
372 */
373 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 327 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
374 rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); 328 rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put);
375 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 329 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
376 ; 330 ;
377 } else if (v) 331 else if (v)
378 rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); 332 rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put);
379 else 333 else
380 rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); 334 rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put);
@@ -386,29 +340,26 @@ xfs_dir2_getdents(
386/* 340/*
387 * Replace the inode number of a directory entry. 341 * Replace the inode number of a directory entry.
388 */ 342 */
389static int /* error */ 343int
390xfs_dir2_replace( 344xfs_dir_replace(
391 xfs_trans_t *tp, /* transaction pointer */ 345 xfs_trans_t *tp,
392 xfs_inode_t *dp, /* incore directory inode */ 346 xfs_inode_t *dp,
393 char *name, /* name of entry to replace */ 347 char *name, /* name of entry to replace */
394 int namelen, /* name length of entry to replace */ 348 int namelen,
395 xfs_ino_t inum, /* new inode number */ 349 xfs_ino_t inum, /* new inode number */
396 xfs_fsblock_t *first, /* bmap's firstblock */ 350 xfs_fsblock_t *first, /* bmap's firstblock */
397 xfs_bmap_free_t *flist, /* bmap's freeblock list */ 351 xfs_bmap_free_t *flist, /* bmap's freeblock list */
398 xfs_extlen_t total) /* bmap's total block count */ 352 xfs_extlen_t total) /* bmap's total block count */
399{ 353{
400 xfs_da_args_t args; /* operation arguments */ 354 xfs_da_args_t args;
401 int rval; /* return value */ 355 int rval;
402 int v; /* type-checking value */ 356 int v; /* type-checking value */
403 357
404 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 358 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
405 359
406 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { 360 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
407 return rval; 361 return rval;
408 } 362
409 /*
410 * Fill in the arg structure for this request.
411 */
412 args.name = name; 363 args.name = name;
413 args.namelen = namelen; 364 args.namelen = namelen;
414 args.hashval = xfs_da_hashname(name, namelen); 365 args.hashval = xfs_da_hashname(name, namelen);
@@ -420,18 +371,16 @@ xfs_dir2_replace(
420 args.whichfork = XFS_DATA_FORK; 371 args.whichfork = XFS_DATA_FORK;
421 args.trans = tp; 372 args.trans = tp;
422 args.justcheck = args.addname = args.oknoent = 0; 373 args.justcheck = args.addname = args.oknoent = 0;
423 /* 374
424 * Decide on what work routines to call based on the inode size.
425 */
426 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 375 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
427 rval = xfs_dir2_sf_replace(&args); 376 rval = xfs_dir2_sf_replace(&args);
428 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 377 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
429 return rval; 378 return rval;
430 } else if (v) 379 else if (v)
431 rval = xfs_dir2_block_replace(&args); 380 rval = xfs_dir2_block_replace(&args);
432 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 381 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
433 return rval; 382 return rval;
434 } else if (v) 383 else if (v)
435 rval = xfs_dir2_leaf_replace(&args); 384 rval = xfs_dir2_leaf_replace(&args);
436 else 385 else
437 rval = xfs_dir2_node_replace(&args); 386 rval = xfs_dir2_node_replace(&args);
@@ -441,21 +390,19 @@ xfs_dir2_replace(
441/* 390/*
442 * See if this entry can be added to the directory without allocating space. 391 * See if this entry can be added to the directory without allocating space.
443 */ 392 */
444static int /* error */ 393int
445xfs_dir2_canenter( 394xfs_dir_canenter(
446 xfs_trans_t *tp, /* transaction pointer */ 395 xfs_trans_t *tp,
447 xfs_inode_t *dp, /* incore directory inode */ 396 xfs_inode_t *dp,
448 char *name, /* name of entry to add */ 397 char *name, /* name of entry to add */
449 int namelen) /* name length of entry to add */ 398 int namelen)
450{ 399{
451 xfs_da_args_t args; /* operation arguments */ 400 xfs_da_args_t args;
452 int rval; /* return value */ 401 int rval;
453 int v; /* type-checking value */ 402 int v; /* type-checking value */
454 403
455 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 404 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
456 /* 405
457 * Fill in the arg structure for this request.
458 */
459 args.name = name; 406 args.name = name;
460 args.namelen = namelen; 407 args.namelen = namelen;
461 args.hashval = xfs_da_hashname(name, namelen); 408 args.hashval = xfs_da_hashname(name, namelen);
@@ -467,18 +414,16 @@ xfs_dir2_canenter(
467 args.whichfork = XFS_DATA_FORK; 414 args.whichfork = XFS_DATA_FORK;
468 args.trans = tp; 415 args.trans = tp;
469 args.justcheck = args.addname = args.oknoent = 1; 416 args.justcheck = args.addname = args.oknoent = 1;
470 /* 417
471 * Decide on what work routines to call based on the inode size.
472 */
473 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 418 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
474 rval = xfs_dir2_sf_addname(&args); 419 rval = xfs_dir2_sf_addname(&args);
475 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 420 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
476 return rval; 421 return rval;
477 } else if (v) 422 else if (v)
478 rval = xfs_dir2_block_addname(&args); 423 rval = xfs_dir2_block_addname(&args);
479 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 424 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
480 return rval; 425 return rval;
481 } else if (v) 426 else if (v)
482 rval = xfs_dir2_leaf_addname(&args); 427 rval = xfs_dir2_leaf_addname(&args);
483 else 428 else
484 rval = xfs_dir2_node_addname(&args); 429 rval = xfs_dir2_node_addname(&args);
@@ -486,19 +431,6 @@ xfs_dir2_canenter(
486} 431}
487 432
488/* 433/*
489 * Dummy routine for shortform inode validation.
490 * Can't really do this.
491 */
492/* ARGSUSED */
493static int /* error */
494xfs_dir2_shortform_validate_ondisk(
495 xfs_mount_t *mp, /* filesystem mount point */
496 xfs_dinode_t *dip) /* ondisk inode */
497{
498 return 0;
499}
500
501/*
502 * Utility routines. 434 * Utility routines.
503 */ 435 */
504 436
@@ -507,24 +439,24 @@ xfs_dir2_shortform_validate_ondisk(
507 * This routine is for data and free blocks, not leaf/node blocks 439 * This routine is for data and free blocks, not leaf/node blocks
508 * which are handled by xfs_da_grow_inode. 440 * which are handled by xfs_da_grow_inode.
509 */ 441 */
510int /* error */ 442int
511xfs_dir2_grow_inode( 443xfs_dir2_grow_inode(
512 xfs_da_args_t *args, /* operation arguments */ 444 xfs_da_args_t *args,
513 int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ 445 int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */
514 xfs_dir2_db_t *dbp) /* out: block number added */ 446 xfs_dir2_db_t *dbp) /* out: block number added */
515{ 447{
516 xfs_fileoff_t bno; /* directory offset of new block */ 448 xfs_fileoff_t bno; /* directory offset of new block */
517 int count; /* count of filesystem blocks */ 449 int count; /* count of filesystem blocks */
518 xfs_inode_t *dp; /* incore directory inode */ 450 xfs_inode_t *dp; /* incore directory inode */
519 int error; /* error return value */ 451 int error;
520 int got; /* blocks actually mapped */ 452 int got; /* blocks actually mapped */
521 int i; /* temp mapping index */ 453 int i;
522 xfs_bmbt_irec_t map; /* single structure for bmap */ 454 xfs_bmbt_irec_t map; /* single structure for bmap */
523 int mapi; /* mapping index */ 455 int mapi; /* mapping index */
524 xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ 456 xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */
525 xfs_mount_t *mp; /* filesystem mount point */ 457 xfs_mount_t *mp;
526 int nmap; /* number of bmap entries */ 458 int nmap; /* number of bmap entries */
527 xfs_trans_t *tp; /* transaction pointer */ 459 xfs_trans_t *tp;
528 460
529 xfs_dir2_trace_args_s("grow_inode", args, space); 461 xfs_dir2_trace_args_s("grow_inode", args, space);
530 dp = args->dp; 462 dp = args->dp;
@@ -538,9 +470,8 @@ xfs_dir2_grow_inode(
538 /* 470 /*
539 * Find the first hole for our block. 471 * Find the first hole for our block.
540 */ 472 */
541 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) { 473 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK)))
542 return error; 474 return error;
543 }
544 nmap = 1; 475 nmap = 1;
545 ASSERT(args->firstblock != NULL); 476 ASSERT(args->firstblock != NULL);
546 /* 477 /*
@@ -549,13 +480,9 @@ xfs_dir2_grow_inode(
549 if ((error = xfs_bmapi(tp, dp, bno, count, 480 if ((error = xfs_bmapi(tp, dp, bno, count,
550 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, 481 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
551 args->firstblock, args->total, &map, &nmap, 482 args->firstblock, args->total, &map, &nmap,
552 args->flist))) { 483 args->flist, NULL)))
553 return error; 484 return error;
554 }
555 ASSERT(nmap <= 1); 485 ASSERT(nmap <= 1);
556 /*
557 * Got it in 1.
558 */
559 if (nmap == 1) { 486 if (nmap == 1) {
560 mapp = &map; 487 mapp = &map;
561 mapi = 1; 488 mapi = 1;
@@ -585,7 +512,8 @@ xfs_dir2_grow_inode(
585 if ((error = xfs_bmapi(tp, dp, b, c, 512 if ((error = xfs_bmapi(tp, dp, b, c,
586 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA, 513 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,
587 args->firstblock, args->total, 514 args->firstblock, args->total,
588 &mapp[mapi], &nmap, args->flist))) { 515 &mapp[mapi], &nmap, args->flist,
516 NULL))) {
589 kmem_free(mapp, sizeof(*mapp) * count); 517 kmem_free(mapp, sizeof(*mapp) * count);
590 return error; 518 return error;
591 } 519 }
@@ -645,20 +573,19 @@ xfs_dir2_grow_inode(
645/* 573/*
646 * See if the directory is a single-block form directory. 574 * See if the directory is a single-block form directory.
647 */ 575 */
648int /* error */ 576int
649xfs_dir2_isblock( 577xfs_dir2_isblock(
650 xfs_trans_t *tp, /* transaction pointer */ 578 xfs_trans_t *tp,
651 xfs_inode_t *dp, /* incore directory inode */ 579 xfs_inode_t *dp,
652 int *vp) /* out: 1 is block, 0 is not block */ 580 int *vp) /* out: 1 is block, 0 is not block */
653{ 581{
654 xfs_fileoff_t last; /* last file offset */ 582 xfs_fileoff_t last; /* last file offset */
655 xfs_mount_t *mp; /* filesystem mount point */ 583 xfs_mount_t *mp;
656 int rval; /* return value */ 584 int rval;
657 585
658 mp = dp->i_mount; 586 mp = dp->i_mount;
659 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { 587 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
660 return rval; 588 return rval;
661 }
662 rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; 589 rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize;
663 ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); 590 ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize);
664 *vp = rval; 591 *vp = rval;
@@ -668,20 +595,19 @@ xfs_dir2_isblock(
668/* 595/*
669 * See if the directory is a single-leaf form directory. 596 * See if the directory is a single-leaf form directory.
670 */ 597 */
671int /* error */ 598int
672xfs_dir2_isleaf( 599xfs_dir2_isleaf(
673 xfs_trans_t *tp, /* transaction pointer */ 600 xfs_trans_t *tp,
674 xfs_inode_t *dp, /* incore directory inode */ 601 xfs_inode_t *dp,
675 int *vp) /* out: 1 is leaf, 0 is not leaf */ 602 int *vp) /* out: 1 is leaf, 0 is not leaf */
676{ 603{
677 xfs_fileoff_t last; /* last file offset */ 604 xfs_fileoff_t last; /* last file offset */
678 xfs_mount_t *mp; /* filesystem mount point */ 605 xfs_mount_t *mp;
679 int rval; /* return value */ 606 int rval;
680 607
681 mp = dp->i_mount; 608 mp = dp->i_mount;
682 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { 609 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
683 return rval; 610 return rval;
684 }
685 *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); 611 *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog);
686 return 0; 612 return 0;
687} 613}
@@ -689,9 +615,9 @@ xfs_dir2_isleaf(
689/* 615/*
690 * Getdents put routine for 64-bit ABI, direct form. 616 * Getdents put routine for 64-bit ABI, direct form.
691 */ 617 */
692static int /* error */ 618static int
693xfs_dir2_put_dirent64_direct( 619xfs_dir2_put_dirent64_direct(
694 xfs_dir2_put_args_t *pa) /* argument bundle */ 620 xfs_dir2_put_args_t *pa)
695{ 621{
696 xfs_dirent_t *idbp; /* dirent pointer */ 622 xfs_dirent_t *idbp; /* dirent pointer */
697 iovec_t *iovp; /* io vector */ 623 iovec_t *iovp; /* io vector */
@@ -726,9 +652,9 @@ xfs_dir2_put_dirent64_direct(
726/* 652/*
727 * Getdents put routine for 64-bit ABI, uio form. 653 * Getdents put routine for 64-bit ABI, uio form.
728 */ 654 */
729static int /* error */ 655static int
730xfs_dir2_put_dirent64_uio( 656xfs_dir2_put_dirent64_uio(
731 xfs_dir2_put_args_t *pa) /* argument bundle */ 657 xfs_dir2_put_args_t *pa)
732{ 658{
733 xfs_dirent_t *idbp; /* dirent pointer */ 659 xfs_dirent_t *idbp; /* dirent pointer */
734 int namelen; /* entry name length */ 660 int namelen; /* entry name length */
@@ -764,17 +690,17 @@ xfs_dir2_put_dirent64_uio(
764 */ 690 */
765int 691int
766xfs_dir2_shrink_inode( 692xfs_dir2_shrink_inode(
767 xfs_da_args_t *args, /* operation arguments */ 693 xfs_da_args_t *args,
768 xfs_dir2_db_t db, /* directory block number */ 694 xfs_dir2_db_t db,
769 xfs_dabuf_t *bp) /* block's buffer */ 695 xfs_dabuf_t *bp)
770{ 696{
771 xfs_fileoff_t bno; /* directory file offset */ 697 xfs_fileoff_t bno; /* directory file offset */
772 xfs_dablk_t da; /* directory file offset */ 698 xfs_dablk_t da; /* directory file offset */
773 int done; /* bunmap is finished */ 699 int done; /* bunmap is finished */
774 xfs_inode_t *dp; /* incore directory inode */ 700 xfs_inode_t *dp;
775 int error; /* error return value */ 701 int error;
776 xfs_mount_t *mp; /* filesystem mount point */ 702 xfs_mount_t *mp;
777 xfs_trans_t *tp; /* transaction pointer */ 703 xfs_trans_t *tp;
778 704
779 xfs_dir2_trace_args_db("shrink_inode", args, db, bp); 705 xfs_dir2_trace_args_db("shrink_inode", args, db, bp);
780 dp = args->dp; 706 dp = args->dp;
@@ -786,7 +712,7 @@ xfs_dir2_shrink_inode(
786 */ 712 */
787 if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, 713 if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,
788 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, 714 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
789 &done))) { 715 NULL, &done))) {
790 /* 716 /*
791 * ENOSPC actually can happen if we're in a removename with 717 * ENOSPC actually can happen if we're in a removename with
792 * no space reservation, and the resulting block removal 718 * no space reservation, and the resulting block removal
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 7dd364b1e038..86560b6f794c 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -22,7 +22,9 @@ struct uio;
22struct xfs_dabuf; 22struct xfs_dabuf;
23struct xfs_da_args; 23struct xfs_da_args;
24struct xfs_dir2_put_args; 24struct xfs_dir2_put_args;
25struct xfs_bmap_free;
25struct xfs_inode; 26struct xfs_inode;
27struct xfs_mount;
26struct xfs_trans; 28struct xfs_trans;
27 29
28/* 30/*
@@ -73,7 +75,35 @@ typedef struct xfs_dir2_put_args {
73} xfs_dir2_put_args_t; 75} xfs_dir2_put_args_t;
74 76
75/* 77/*
76 * Other interfaces used by the rest of the dir v2 code. 78 * Generic directory interface routines
79 */
80extern void xfs_dir_startup(void);
81extern void xfs_dir_mount(struct xfs_mount *mp);
82extern int xfs_dir_isempty(struct xfs_inode *dp);
83extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
84 struct xfs_inode *pdp);
85extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
86 char *name, int namelen, xfs_ino_t inum,
87 xfs_fsblock_t *first,
88 struct xfs_bmap_free *flist, xfs_extlen_t tot);
89extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
90 char *name, int namelen, xfs_ino_t *inum);
91extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
92 char *name, int namelen, xfs_ino_t ino,
93 xfs_fsblock_t *first,
94 struct xfs_bmap_free *flist, xfs_extlen_t tot);
95extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
96 uio_t *uio, int *eofp);
97extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
98 char *name, int namelen, xfs_ino_t inum,
99 xfs_fsblock_t *first,
100 struct xfs_bmap_free *flist, xfs_extlen_t tot);
101extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
102 char *name, int namelen);
103extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
104
105/*
106 * Utility routines for v2 directories.
77 */ 107 */
78extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, 108extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
79 xfs_dir2_db_t *dbp); 109 xfs_dir2_db_t *dbp);
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 972ded595476..9d7438bba30d 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -22,19 +22,16 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.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_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
35#include "xfs_inode.h" 33#include "xfs_inode.h"
36#include "xfs_inode_item.h" 34#include "xfs_inode_item.h"
37#include "xfs_dir_leaf.h"
38#include "xfs_dir2_data.h" 35#include "xfs_dir2_data.h"
39#include "xfs_dir2_leaf.h" 36#include "xfs_dir2_leaf.h"
40#include "xfs_dir2_block.h" 37#include "xfs_dir2_block.h"
@@ -51,6 +48,18 @@ static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp,
51 int *entno); 48 int *entno);
52static int xfs_dir2_block_sort(const void *a, const void *b); 49static int xfs_dir2_block_sort(const void *a, const void *b);
53 50
51static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
52
53/*
54 * One-time startup routine called from xfs_init().
55 */
56void
57xfs_dir_startup(void)
58{
59 xfs_dir_hash_dot = xfs_da_hashname(".", 1);
60 xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
61}
62
54/* 63/*
55 * Add an entry to a block directory. 64 * Add an entry to a block directory.
56 */ 65 */
@@ -400,7 +409,7 @@ xfs_dir2_block_addname(
400 /* 409 /*
401 * Create the new data entry. 410 * Create the new data entry.
402 */ 411 */
403 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 412 dep->inumber = cpu_to_be64(args->inumber);
404 dep->namelen = args->namelen; 413 dep->namelen = args->namelen;
405 memcpy(dep->name, args->name, args->namelen); 414 memcpy(dep->name, args->name, args->namelen);
406 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 415 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -508,7 +517,7 @@ xfs_dir2_block_getdents(
508 517
509 p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, 518 p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
510 ptr - (char *)block); 519 ptr - (char *)block);
511 p.ino = INT_GET(dep->inumber, ARCH_CONVERT); 520 p.ino = be64_to_cpu(dep->inumber);
512#if XFS_BIG_INUMS 521#if XFS_BIG_INUMS
513 p.ino += mp->m_inoadd; 522 p.ino += mp->m_inoadd;
514#endif 523#endif
@@ -626,7 +635,7 @@ xfs_dir2_block_lookup(
626 /* 635 /*
627 * Fill in inode number, release the block. 636 * Fill in inode number, release the block.
628 */ 637 */
629 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 638 args->inumber = be64_to_cpu(dep->inumber);
630 xfs_da_brelse(args->trans, bp); 639 xfs_da_brelse(args->trans, bp);
631 return XFS_ERROR(EEXIST); 640 return XFS_ERROR(EEXIST);
632} 641}
@@ -844,11 +853,11 @@ xfs_dir2_block_replace(
844 */ 853 */
845 dep = (xfs_dir2_data_entry_t *) 854 dep = (xfs_dir2_data_entry_t *)
846 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address))); 855 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
847 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber); 856 ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
848 /* 857 /*
849 * Change the inode number to the new value. 858 * Change the inode number to the new value.
850 */ 859 */
851 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 860 dep->inumber = cpu_to_be64(args->inumber);
852 xfs_dir2_data_log_entry(args->trans, bp, dep); 861 xfs_dir2_data_log_entry(args->trans, bp, dep);
853 xfs_dir2_data_check(dp, bp); 862 xfs_dir2_data_check(dp, bp);
854 xfs_da_buf_done(bp); 863 xfs_da_buf_done(bp);
@@ -1130,7 +1139,7 @@ xfs_dir2_sf_to_block(
1130 */ 1139 */
1131 dep = (xfs_dir2_data_entry_t *) 1140 dep = (xfs_dir2_data_entry_t *)
1132 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); 1141 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET);
1133 INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino); 1142 dep->inumber = cpu_to_be64(dp->i_ino);
1134 dep->namelen = 1; 1143 dep->namelen = 1;
1135 dep->name[0] = '.'; 1144 dep->name[0] = '.';
1136 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1145 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -1144,7 +1153,7 @@ xfs_dir2_sf_to_block(
1144 */ 1153 */
1145 dep = (xfs_dir2_data_entry_t *) 1154 dep = (xfs_dir2_data_entry_t *)
1146 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); 1155 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET);
1147 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); 1156 dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
1148 dep->namelen = 2; 1157 dep->namelen = 2;
1149 dep->name[0] = dep->name[1] = '.'; 1158 dep->name[0] = dep->name[1] = '.';
1150 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1159 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -1193,7 +1202,7 @@ xfs_dir2_sf_to_block(
1193 * Copy a real entry. 1202 * Copy a real entry.
1194 */ 1203 */
1195 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); 1204 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset);
1196 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, 1205 dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp,
1197 XFS_DIR2_SF_INUMBERP(sfep))); 1206 XFS_DIR2_SF_INUMBERP(sfep)));
1198 dep->namelen = sfep->namelen; 1207 dep->namelen = sfep->namelen;
1199 memcpy(dep->name, sfep->name, dep->namelen); 1208 memcpy(dep->name, sfep->name, dep->namelen);
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index bb3d03ff002b..f7c799217072 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -22,18 +22,15 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.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_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
35#include "xfs_inode.h" 33#include "xfs_inode.h"
36#include "xfs_dir_leaf.h"
37#include "xfs_dir2_data.h" 34#include "xfs_dir2_data.h"
38#include "xfs_dir2_leaf.h" 35#include "xfs_dir2_leaf.h"
39#include "xfs_dir2_block.h" 36#include "xfs_dir2_block.h"
@@ -133,7 +130,7 @@ xfs_dir2_data_check(
133 */ 130 */
134 dep = (xfs_dir2_data_entry_t *)p; 131 dep = (xfs_dir2_data_entry_t *)p;
135 ASSERT(dep->namelen != 0); 132 ASSERT(dep->namelen != 0);
136 ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0); 133 ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0);
137 ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) == 134 ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) ==
138 (char *)dep - (char *)d); 135 (char *)dep - (char *)d);
139 count++; 136 count++;
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index 0847cbb53e17..a6ae2d21c40a 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -85,11 +85,11 @@ typedef struct xfs_dir2_data_hdr {
85 * Tag appears as the last 2 bytes. 85 * Tag appears as the last 2 bytes.
86 */ 86 */
87typedef struct xfs_dir2_data_entry { 87typedef struct xfs_dir2_data_entry {
88 xfs_ino_t inumber; /* inode number */ 88 __be64 inumber; /* inode number */
89 __uint8_t namelen; /* name length */ 89 __u8 namelen; /* name length */
90 __uint8_t name[1]; /* name bytes, no null */ 90 __u8 name[1]; /* name bytes, no null */
91 /* variable offset */ 91 /* variable offset */
92 xfs_dir2_data_off_t tag; /* starting offset of us */ 92 __be16 tag; /* starting offset of us */
93} xfs_dir2_data_entry_t; 93} xfs_dir2_data_entry_t;
94 94
95/* 95/*
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 0f5e2f2ce6ec..b1cf1fbf423d 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_da_btree.h" 30#include "xfs_da_btree.h"
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_attr_sf.h" 32#include "xfs_attr_sf.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_dinode.h" 34#include "xfs_dinode.h"
37#include "xfs_inode.h" 35#include "xfs_inode.h"
@@ -407,7 +405,7 @@ xfs_dir2_leaf_addname(
407 * Initialize our new entry (at last). 405 * Initialize our new entry (at last).
408 */ 406 */
409 dep = (xfs_dir2_data_entry_t *)dup; 407 dep = (xfs_dir2_data_entry_t *)dup;
410 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 408 dep->inumber = cpu_to_be64(args->inumber);
411 dep->namelen = args->namelen; 409 dep->namelen = args->namelen;
412 memcpy(dep->name, args->name, dep->namelen); 410 memcpy(dep->name, args->name, dep->namelen);
413 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 411 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -884,7 +882,7 @@ xfs_dir2_leaf_getdents(
884 XFS_DIR2_BYTE_TO_DA(mp, 882 XFS_DIR2_BYTE_TO_DA(mp,
885 XFS_DIR2_LEAF_OFFSET) - map_off, 883 XFS_DIR2_LEAF_OFFSET) - map_off,
886 XFS_BMAPI_METADATA, NULL, 0, 884 XFS_BMAPI_METADATA, NULL, 0,
887 &map[map_valid], &nmap, NULL); 885 &map[map_valid], &nmap, NULL, NULL);
888 /* 886 /*
889 * Don't know if we should ignore this or 887 * Don't know if we should ignore this or
890 * try to return an error. 888 * try to return an error.
@@ -1098,7 +1096,7 @@ xfs_dir2_leaf_getdents(
1098 1096
1099 p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length); 1097 p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
1100 1098
1101 p->ino = INT_GET(dep->inumber, ARCH_CONVERT); 1099 p->ino = be64_to_cpu(dep->inumber);
1102#if XFS_BIG_INUMS 1100#if XFS_BIG_INUMS
1103 p->ino += mp->m_inoadd; 1101 p->ino += mp->m_inoadd;
1104#endif 1102#endif
@@ -1319,7 +1317,7 @@ xfs_dir2_leaf_lookup(
1319 /* 1317 /*
1320 * Return the found inode number. 1318 * Return the found inode number.
1321 */ 1319 */
1322 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 1320 args->inumber = be64_to_cpu(dep->inumber);
1323 xfs_da_brelse(tp, dbp); 1321 xfs_da_brelse(tp, dbp);
1324 xfs_da_brelse(tp, lbp); 1322 xfs_da_brelse(tp, lbp);
1325 return XFS_ERROR(EEXIST); 1323 return XFS_ERROR(EEXIST);
@@ -1606,11 +1604,11 @@ xfs_dir2_leaf_replace(
1606 dep = (xfs_dir2_data_entry_t *) 1604 dep = (xfs_dir2_data_entry_t *)
1607 ((char *)dbp->data + 1605 ((char *)dbp->data +
1608 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address))); 1606 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address)));
1609 ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT)); 1607 ASSERT(args->inumber != be64_to_cpu(dep->inumber));
1610 /* 1608 /*
1611 * Put the new inode number in, log it. 1609 * Put the new inode number in, log it.
1612 */ 1610 */
1613 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 1611 dep->inumber = cpu_to_be64(args->inumber);
1614 tp = args->trans; 1612 tp = args->trans;
1615 xfs_dir2_data_log_entry(tp, dbp, dep); 1613 xfs_dir2_data_log_entry(tp, dbp, dep);
1616 xfs_da_buf_done(dbp); 1614 xfs_da_buf_done(dbp);
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index ac511ab9c52d..9ca71719b683 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -22,13 +22,11 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.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_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
@@ -505,7 +503,6 @@ xfs_dir2_leafn_lookup_int(
505 XFS_DATA_FORK))) { 503 XFS_DATA_FORK))) {
506 return error; 504 return error;
507 } 505 }
508 curfdb = newfdb;
509 free = curbp->data; 506 free = curbp->data;
510 ASSERT(be32_to_cpu(free->hdr.magic) == 507 ASSERT(be32_to_cpu(free->hdr.magic) ==
511 XFS_DIR2_FREE_MAGIC); 508 XFS_DIR2_FREE_MAGIC);
@@ -527,8 +524,11 @@ xfs_dir2_leafn_lookup_int(
527 if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) { 524 if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) {
528 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", 525 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
529 XFS_ERRLEVEL_LOW, mp); 526 XFS_ERRLEVEL_LOW, mp);
527 if (curfdb != newfdb)
528 xfs_da_brelse(tp, curbp);
530 return XFS_ERROR(EFSCORRUPTED); 529 return XFS_ERROR(EFSCORRUPTED);
531 } 530 }
531 curfdb = newfdb;
532 if (be16_to_cpu(free->bests[fi]) >= length) { 532 if (be16_to_cpu(free->bests[fi]) >= length) {
533 *indexp = index; 533 *indexp = index;
534 state->extravalid = 1; 534 state->extravalid = 1;
@@ -580,7 +580,7 @@ xfs_dir2_leafn_lookup_int(
580 if (dep->namelen == args->namelen && 580 if (dep->namelen == args->namelen &&
581 dep->name[0] == args->name[0] && 581 dep->name[0] == args->name[0] &&
582 memcmp(dep->name, args->name, args->namelen) == 0) { 582 memcmp(dep->name, args->name, args->namelen) == 0) {
583 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 583 args->inumber = be64_to_cpu(dep->inumber);
584 *indexp = index; 584 *indexp = index;
585 state->extravalid = 1; 585 state->extravalid = 1;
586 state->extrablk.bp = curbp; 586 state->extrablk.bp = curbp;
@@ -970,7 +970,7 @@ xfs_dir2_leafn_remove(
970 /* 970 /*
971 * One less used entry in the free table. 971 * One less used entry in the free table.
972 */ 972 */
973 free->hdr.nused = cpu_to_be32(-1); 973 be32_add(&free->hdr.nused, -1);
974 xfs_dir2_free_log_header(tp, fbp); 974 xfs_dir2_free_log_header(tp, fbp);
975 /* 975 /*
976 * If this was the last entry in the table, we can 976 * If this was the last entry in the table, we can
@@ -1695,7 +1695,7 @@ xfs_dir2_node_addname_int(
1695 * Fill in the new entry and log it. 1695 * Fill in the new entry and log it.
1696 */ 1696 */
1697 dep = (xfs_dir2_data_entry_t *)dup; 1697 dep = (xfs_dir2_data_entry_t *)dup;
1698 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 1698 dep->inumber = cpu_to_be64(args->inumber);
1699 dep->namelen = args->namelen; 1699 dep->namelen = args->namelen;
1700 memcpy(dep->name, args->name, dep->namelen); 1700 memcpy(dep->name, args->name, dep->namelen);
1701 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1701 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -1905,11 +1905,11 @@ xfs_dir2_node_replace(
1905 dep = (xfs_dir2_data_entry_t *) 1905 dep = (xfs_dir2_data_entry_t *)
1906 ((char *)data + 1906 ((char *)data +
1907 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)));
1908 ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT)); 1908 ASSERT(inum != be64_to_cpu(dep->inumber));
1909 /* 1909 /*
1910 * Fill in the new inode number and log the entry. 1910 * Fill in the new inode number and log the entry.
1911 */ 1911 */
1912 INT_SET(dep->inumber, ARCH_CONVERT, inum); 1912 dep->inumber = cpu_to_be64(inum);
1913 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); 1913 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
1914 rval = 0; 1914 rval = 0;
1915 } 1915 }
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index d98a41d1fe63..0cd77b17bf92 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -22,19 +22,16 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.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_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
35#include "xfs_inode.h" 33#include "xfs_inode.h"
36#include "xfs_inode_item.h" 34#include "xfs_inode_item.h"
37#include "xfs_dir_leaf.h"
38#include "xfs_error.h" 35#include "xfs_error.h"
39#include "xfs_dir2_data.h" 36#include "xfs_dir2_data.h"
40#include "xfs_dir2_leaf.h" 37#include "xfs_dir2_leaf.h"
@@ -117,13 +114,13 @@ xfs_dir2_block_sfsize(
117 dep->name[0] == '.' && dep->name[1] == '.'; 114 dep->name[0] == '.' && dep->name[1] == '.';
118#if XFS_BIG_INUMS 115#if XFS_BIG_INUMS
119 if (!isdot) 116 if (!isdot)
120 i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM; 117 i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM;
121#endif 118#endif
122 if (!isdot && !isdotdot) { 119 if (!isdot && !isdotdot) {
123 count++; 120 count++;
124 namelen += dep->namelen; 121 namelen += dep->namelen;
125 } else if (isdotdot) 122 } else if (isdotdot)
126 parent = INT_GET(dep->inumber, ARCH_CONVERT); 123 parent = be64_to_cpu(dep->inumber);
127 /* 124 /*
128 * Calculate the new size, see if we should give up yet. 125 * Calculate the new size, see if we should give up yet.
129 */ 126 */
@@ -229,13 +226,13 @@ xfs_dir2_block_to_sf(
229 * Skip . 226 * Skip .
230 */ 227 */
231 if (dep->namelen == 1 && dep->name[0] == '.') 228 if (dep->namelen == 1 && dep->name[0] == '.')
232 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == dp->i_ino); 229 ASSERT(be64_to_cpu(dep->inumber) == dp->i_ino);
233 /* 230 /*
234 * Skip .., but make sure the inode number is right. 231 * Skip .., but make sure the inode number is right.
235 */ 232 */
236 else if (dep->namelen == 2 && 233 else if (dep->namelen == 2 &&
237 dep->name[0] == '.' && dep->name[1] == '.') 234 dep->name[0] == '.' && dep->name[1] == '.')
238 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == 235 ASSERT(be64_to_cpu(dep->inumber) ==
239 XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); 236 XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
240 /* 237 /*
241 * Normal entry, copy it into shortform. 238 * Normal entry, copy it into shortform.
@@ -246,7 +243,7 @@ xfs_dir2_block_to_sf(
246 (xfs_dir2_data_aoff_t) 243 (xfs_dir2_data_aoff_t)
247 ((char *)dep - (char *)block)); 244 ((char *)dep - (char *)block));
248 memcpy(sfep->name, dep->name, dep->namelen); 245 memcpy(sfep->name, dep->name, dep->namelen);
249 temp=INT_GET(dep->inumber, ARCH_CONVERT); 246 temp = be64_to_cpu(dep->inumber);
250 XFS_DIR2_SF_PUT_INUMBER(sfp, &temp, 247 XFS_DIR2_SF_PUT_INUMBER(sfp, &temp,
251 XFS_DIR2_SF_INUMBERP(sfep)); 248 XFS_DIR2_SF_INUMBERP(sfep));
252 sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); 249 sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
diff --git a/fs/xfs/xfs_dir2_trace.c b/fs/xfs/xfs_dir2_trace.c
index c626943b4112..f3fb2ffd6f5c 100644
--- a/fs/xfs/xfs_dir2_trace.c
+++ b/fs/xfs/xfs_dir2_trace.c
@@ -19,11 +19,9 @@
19#include "xfs_fs.h" 19#include "xfs_fs.h"
20#include "xfs_types.h" 20#include "xfs_types.h"
21#include "xfs_inum.h" 21#include "xfs_inum.h"
22#include "xfs_dir.h"
23#include "xfs_dir2.h" 22#include "xfs_dir2.h"
24#include "xfs_da_btree.h" 23#include "xfs_da_btree.h"
25#include "xfs_bmap_btree.h" 24#include "xfs_bmap_btree.h"
26#include "xfs_dir_sf.h"
27#include "xfs_dir2_sf.h" 25#include "xfs_dir2_sf.h"
28#include "xfs_attr_sf.h" 26#include "xfs_attr_sf.h"
29#include "xfs_dinode.h" 27#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
deleted file mode 100644
index 6d711869262f..000000000000
--- a/fs/xfs/xfs_dir_leaf.c
+++ /dev/null
@@ -1,2213 +0,0 @@
1/*
2 * Copyright (c) 2000-2003,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#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_types.h"
21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h"
27#include "xfs_dmapi.h"
28#include "xfs_mount.h"
29#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h"
33#include "xfs_dir_sf.h"
34#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h"
36#include "xfs_dinode.h"
37#include "xfs_inode.h"
38#include "xfs_inode_item.h"
39#include "xfs_alloc.h"
40#include "xfs_btree.h"
41#include "xfs_bmap.h"
42#include "xfs_dir_leaf.h"
43#include "xfs_error.h"
44
45/*
46 * xfs_dir_leaf.c
47 *
48 * Routines to implement leaf blocks of directories as Btrees of hashed names.
49 */
50
51/*========================================================================
52 * Function prototypes for the kernel.
53 *========================================================================*/
54
55/*
56 * Routines used for growing the Btree.
57 */
58STATIC void xfs_dir_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args,
59 int insertion_index,
60 int freemap_index);
61STATIC int xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer,
62 int musthave, int justcheck);
63STATIC void xfs_dir_leaf_rebalance(xfs_da_state_t *state,
64 xfs_da_state_blk_t *blk1,
65 xfs_da_state_blk_t *blk2);
66STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
67 xfs_da_state_blk_t *leaf_blk_1,
68 xfs_da_state_blk_t *leaf_blk_2,
69 int *number_entries_in_blk1,
70 int *number_namebytes_in_blk1);
71
72STATIC int xfs_dir_leaf_create(struct xfs_da_args *args,
73 xfs_dablk_t which_block,
74 struct xfs_dabuf **bpp);
75
76/*
77 * Utility routines.
78 */
79STATIC void xfs_dir_leaf_moveents(xfs_dir_leafblock_t *src_leaf,
80 int src_start,
81 xfs_dir_leafblock_t *dst_leaf,
82 int dst_start, int move_count,
83 xfs_mount_t *mp);
84
85
86/*========================================================================
87 * External routines when dirsize < XFS_IFORK_DSIZE(dp).
88 *========================================================================*/
89
90
91/*
92 * Validate a given inode number.
93 */
94int
95xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino)
96{
97 xfs_agblock_t agblkno;
98 xfs_agino_t agino;
99 xfs_agnumber_t agno;
100 int ino_ok;
101 int ioff;
102
103 agno = XFS_INO_TO_AGNO(mp, ino);
104 agblkno = XFS_INO_TO_AGBNO(mp, ino);
105 ioff = XFS_INO_TO_OFFSET(mp, ino);
106 agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
107 ino_ok =
108 agno < mp->m_sb.sb_agcount &&
109 agblkno < mp->m_sb.sb_agblocks &&
110 agblkno != 0 &&
111 ioff < (1 << mp->m_sb.sb_inopblog) &&
112 XFS_AGINO_TO_INO(mp, agno, agino) == ino;
113 if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
114 XFS_RANDOM_DIR_INO_VALIDATE))) {
115 xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
116 (unsigned long long) ino);
117 XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
118 return XFS_ERROR(EFSCORRUPTED);
119 }
120 return 0;
121}
122
123/*
124 * Create the initial contents of a shortform directory.
125 */
126int
127xfs_dir_shortform_create(xfs_da_args_t *args, xfs_ino_t parent)
128{
129 xfs_dir_sf_hdr_t *hdr;
130 xfs_inode_t *dp;
131
132 dp = args->dp;
133 ASSERT(dp != NULL);
134 ASSERT(dp->i_d.di_size == 0);
135 if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) {
136 dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */
137 dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
138 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
139 dp->i_df.if_flags |= XFS_IFINLINE;
140 }
141 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
142 ASSERT(dp->i_df.if_bytes == 0);
143 xfs_idata_realloc(dp, sizeof(*hdr), XFS_DATA_FORK);
144 hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data;
145 XFS_DIR_SF_PUT_DIRINO(&parent, &hdr->parent);
146
147 hdr->count = 0;
148 dp->i_d.di_size = sizeof(*hdr);
149 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
150 return 0;
151}
152
153/*
154 * Add a name to the shortform directory structure.
155 * Overflow from the inode has already been checked for.
156 */
157int
158xfs_dir_shortform_addname(xfs_da_args_t *args)
159{
160 xfs_dir_shortform_t *sf;
161 xfs_dir_sf_entry_t *sfe;
162 int i, offset, size;
163 xfs_inode_t *dp;
164
165 dp = args->dp;
166 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
167 /*
168 * Catch the case where the conversion from shortform to leaf
169 * failed part way through.
170 */
171 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
172 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
173 return XFS_ERROR(EIO);
174 }
175 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
176 ASSERT(dp->i_df.if_u1.if_data != NULL);
177 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
178 sfe = &sf->list[0];
179 for (i = sf->hdr.count-1; i >= 0; i--) {
180 if (sfe->namelen == args->namelen &&
181 args->name[0] == sfe->name[0] &&
182 memcmp(args->name, sfe->name, args->namelen) == 0)
183 return XFS_ERROR(EEXIST);
184 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
185 }
186
187 offset = (int)((char *)sfe - (char *)sf);
188 size = XFS_DIR_SF_ENTSIZE_BYNAME(args->namelen);
189 xfs_idata_realloc(dp, size, XFS_DATA_FORK);
190 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
191 sfe = (xfs_dir_sf_entry_t *)((char *)sf + offset);
192
193 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber);
194 sfe->namelen = args->namelen;
195 memcpy(sfe->name, args->name, sfe->namelen);
196 sf->hdr.count++;
197
198 dp->i_d.di_size += size;
199 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
200
201 return 0;
202}
203
204/*
205 * Remove a name from the shortform directory structure.
206 */
207int
208xfs_dir_shortform_removename(xfs_da_args_t *args)
209{
210 xfs_dir_shortform_t *sf;
211 xfs_dir_sf_entry_t *sfe;
212 int base, size = 0, i;
213 xfs_inode_t *dp;
214
215 dp = args->dp;
216 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
217 /*
218 * Catch the case where the conversion from shortform to leaf
219 * failed part way through.
220 */
221 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
222 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
223 return XFS_ERROR(EIO);
224 }
225 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
226 ASSERT(dp->i_df.if_u1.if_data != NULL);
227 base = sizeof(xfs_dir_sf_hdr_t);
228 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
229 sfe = &sf->list[0];
230 for (i = sf->hdr.count-1; i >= 0; i--) {
231 size = XFS_DIR_SF_ENTSIZE_BYENTRY(sfe);
232 if (sfe->namelen == args->namelen &&
233 sfe->name[0] == args->name[0] &&
234 memcmp(sfe->name, args->name, args->namelen) == 0)
235 break;
236 base += size;
237 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
238 }
239 if (i < 0) {
240 ASSERT(args->oknoent);
241 return XFS_ERROR(ENOENT);
242 }
243
244 if ((base + size) != dp->i_d.di_size) {
245 memmove(&((char *)sf)[base], &((char *)sf)[base+size],
246 dp->i_d.di_size - (base+size));
247 }
248 sf->hdr.count--;
249
250 xfs_idata_realloc(dp, -size, XFS_DATA_FORK);
251 dp->i_d.di_size -= size;
252 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
253
254 return 0;
255}
256
257/*
258 * Look up a name in a shortform directory structure.
259 */
260int
261xfs_dir_shortform_lookup(xfs_da_args_t *args)
262{
263 xfs_dir_shortform_t *sf;
264 xfs_dir_sf_entry_t *sfe;
265 int i;
266 xfs_inode_t *dp;
267
268 dp = args->dp;
269 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
270 /*
271 * Catch the case where the conversion from shortform to leaf
272 * failed part way through.
273 */
274 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
275 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
276 return XFS_ERROR(EIO);
277 }
278 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
279 ASSERT(dp->i_df.if_u1.if_data != NULL);
280 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
281 if (args->namelen == 2 &&
282 args->name[0] == '.' && args->name[1] == '.') {
283 XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &args->inumber);
284 return(XFS_ERROR(EEXIST));
285 }
286 if (args->namelen == 1 && args->name[0] == '.') {
287 args->inumber = dp->i_ino;
288 return(XFS_ERROR(EEXIST));
289 }
290 sfe = &sf->list[0];
291 for (i = sf->hdr.count-1; i >= 0; i--) {
292 if (sfe->namelen == args->namelen &&
293 sfe->name[0] == args->name[0] &&
294 memcmp(args->name, sfe->name, args->namelen) == 0) {
295 XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args->inumber);
296 return(XFS_ERROR(EEXIST));
297 }
298 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
299 }
300 ASSERT(args->oknoent);
301 return(XFS_ERROR(ENOENT));
302}
303
304/*
305 * Convert from using the shortform to the leaf.
306 */
307int
308xfs_dir_shortform_to_leaf(xfs_da_args_t *iargs)
309{
310 xfs_inode_t *dp;
311 xfs_dir_shortform_t *sf;
312 xfs_dir_sf_entry_t *sfe;
313 xfs_da_args_t args;
314 xfs_ino_t inumber;
315 char *tmpbuffer;
316 int retval, i, size;
317 xfs_dablk_t blkno;
318 xfs_dabuf_t *bp;
319
320 dp = iargs->dp;
321 /*
322 * Catch the case where the conversion from shortform to leaf
323 * failed part way through.
324 */
325 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
326 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
327 return XFS_ERROR(EIO);
328 }
329 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
330 ASSERT(dp->i_df.if_u1.if_data != NULL);
331 size = dp->i_df.if_bytes;
332 tmpbuffer = kmem_alloc(size, KM_SLEEP);
333 ASSERT(tmpbuffer != NULL);
334
335 memcpy(tmpbuffer, dp->i_df.if_u1.if_data, size);
336
337 sf = (xfs_dir_shortform_t *)tmpbuffer;
338 XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &inumber);
339
340 xfs_idata_realloc(dp, -size, XFS_DATA_FORK);
341 dp->i_d.di_size = 0;
342 xfs_trans_log_inode(iargs->trans, dp, XFS_ILOG_CORE);
343 retval = xfs_da_grow_inode(iargs, &blkno);
344 if (retval)
345 goto out;
346
347 ASSERT(blkno == 0);
348 retval = xfs_dir_leaf_create(iargs, blkno, &bp);
349 if (retval)
350 goto out;
351 xfs_da_buf_done(bp);
352
353 args.name = ".";
354 args.namelen = 1;
355 args.hashval = xfs_dir_hash_dot;
356 args.inumber = dp->i_ino;
357 args.dp = dp;
358 args.firstblock = iargs->firstblock;
359 args.flist = iargs->flist;
360 args.total = iargs->total;
361 args.whichfork = XFS_DATA_FORK;
362 args.trans = iargs->trans;
363 args.justcheck = 0;
364 args.addname = args.oknoent = 1;
365 retval = xfs_dir_leaf_addname(&args);
366 if (retval)
367 goto out;
368
369 args.name = "..";
370 args.namelen = 2;
371 args.hashval = xfs_dir_hash_dotdot;
372 args.inumber = inumber;
373 retval = xfs_dir_leaf_addname(&args);
374 if (retval)
375 goto out;
376
377 sfe = &sf->list[0];
378 for (i = 0; i < sf->hdr.count; i++) {
379 args.name = (char *)(sfe->name);
380 args.namelen = sfe->namelen;
381 args.hashval = xfs_da_hashname((char *)(sfe->name),
382 sfe->namelen);
383 XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args.inumber);
384 retval = xfs_dir_leaf_addname(&args);
385 if (retval)
386 goto out;
387 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
388 }
389 retval = 0;
390
391out:
392 kmem_free(tmpbuffer, size);
393 return retval;
394}
395
396STATIC int
397xfs_dir_shortform_compare(const void *a, const void *b)
398{
399 xfs_dir_sf_sort_t *sa, *sb;
400
401 sa = (xfs_dir_sf_sort_t *)a;
402 sb = (xfs_dir_sf_sort_t *)b;
403 if (sa->hash < sb->hash)
404 return -1;
405 else if (sa->hash > sb->hash)
406 return 1;
407 else
408 return sa->entno - sb->entno;
409}
410
411/*
412 * Copy out directory entries for getdents(), for shortform directories.
413 */
414/*ARGSUSED*/
415int
416xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp,
417 xfs_dirent_t *dbp, xfs_dir_put_t put)
418{
419 xfs_dir_shortform_t *sf;
420 xfs_dir_sf_entry_t *sfe;
421 int retval, i, sbsize, nsbuf, lastresid=0, want_entno;
422 xfs_mount_t *mp;
423 xfs_dahash_t cookhash, hash;
424 xfs_dir_put_args_t p;
425 xfs_dir_sf_sort_t *sbuf, *sbp;
426
427 mp = dp->i_mount;
428 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
429 cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
430 want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset);
431 nsbuf = sf->hdr.count + 2;
432 sbsize = (nsbuf + 1) * sizeof(*sbuf);
433 sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP);
434
435 xfs_dir_trace_g_du("sf: start", dp, uio);
436
437 /*
438 * Collect all the entries into the buffer.
439 * Entry 0 is .
440 */
441 sbp->entno = 0;
442 sbp->seqno = 0;
443 sbp->hash = xfs_dir_hash_dot;
444 sbp->ino = dp->i_ino;
445 sbp->name = ".";
446 sbp->namelen = 1;
447 sbp++;
448
449 /*
450 * Entry 1 is ..
451 */
452 sbp->entno = 1;
453 sbp->seqno = 0;
454 sbp->hash = xfs_dir_hash_dotdot;
455 sbp->ino = XFS_GET_DIR_INO8(sf->hdr.parent);
456 sbp->name = "..";
457 sbp->namelen = 2;
458 sbp++;
459
460 /*
461 * Scan the directory data for the rest of the entries.
462 */
463 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
464
465 if (unlikely(
466 ((char *)sfe < (char *)sf) ||
467 ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)))) {
468 xfs_dir_trace_g_du("sf: corrupted", dp, uio);
469 XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents",
470 XFS_ERRLEVEL_LOW, mp, sfe);
471 kmem_free(sbuf, sbsize);
472 return XFS_ERROR(EFSCORRUPTED);
473 }
474
475 sbp->entno = i + 2;
476 sbp->seqno = 0;
477 sbp->hash = xfs_da_hashname((char *)sfe->name, sfe->namelen);
478 sbp->ino = XFS_GET_DIR_INO8(sfe->inumber);
479 sbp->name = (char *)sfe->name;
480 sbp->namelen = sfe->namelen;
481 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
482 sbp++;
483 }
484
485 /*
486 * Sort the entries on hash then entno.
487 */
488 xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_dir_shortform_compare);
489 /*
490 * Stuff in last entry.
491 */
492 sbp->entno = nsbuf;
493 sbp->hash = XFS_DA_MAXHASH;
494 sbp->seqno = 0;
495 /*
496 * Figure out the sequence numbers in case there's a hash duplicate.
497 */
498 for (hash = sbuf->hash, sbp = sbuf + 1;
499 sbp < &sbuf[nsbuf + 1]; sbp++) {
500 if (sbp->hash == hash)
501 sbp->seqno = sbp[-1].seqno + 1;
502 else
503 hash = sbp->hash;
504 }
505
506 /*
507 * Set up put routine.
508 */
509 p.dbp = dbp;
510 p.put = put;
511 p.uio = uio;
512
513 /*
514 * Find our place.
515 */
516 for (sbp = sbuf; sbp < &sbuf[nsbuf + 1]; sbp++) {
517 if (sbp->hash > cookhash ||
518 (sbp->hash == cookhash && sbp->seqno >= want_entno))
519 break;
520 }
521
522 /*
523 * Did we fail to find anything? We stop at the last entry,
524 * the one we put maxhash into.
525 */
526 if (sbp == &sbuf[nsbuf]) {
527 kmem_free(sbuf, sbsize);
528 xfs_dir_trace_g_du("sf: hash beyond end", dp, uio);
529 uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH);
530 *eofp = 1;
531 return 0;
532 }
533
534 /*
535 * Loop putting entries into the user buffer.
536 */
537 while (sbp < &sbuf[nsbuf]) {
538 /*
539 * Save the first resid in a run of equal-hashval entries
540 * so that we can back them out if they don't all fit.
541 */
542 if (sbp->seqno == 0 || sbp == sbuf)
543 lastresid = uio->uio_resid;
544 XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash);
545 p.ino = sbp->ino;
546#if XFS_BIG_INUMS
547 p.ino += mp->m_inoadd;
548#endif
549 p.name = sbp->name;
550 p.namelen = sbp->namelen;
551 retval = p.put(&p);
552 if (!p.done) {
553 uio->uio_offset =
554 XFS_DA_MAKE_COOKIE(mp, 0, 0, sbp->hash);
555 kmem_free(sbuf, sbsize);
556 uio->uio_resid = lastresid;
557 xfs_dir_trace_g_du("sf: E-O-B", dp, uio);
558 return retval;
559 }
560 sbp++;
561 }
562 kmem_free(sbuf, sbsize);
563 uio->uio_offset = p.cook.o;
564 *eofp = 1;
565 xfs_dir_trace_g_du("sf: E-O-F", dp, uio);
566 return 0;
567}
568
569/*
570 * Look up a name in a shortform directory structure, replace the inode number.
571 */
572int
573xfs_dir_shortform_replace(xfs_da_args_t *args)
574{
575 xfs_dir_shortform_t *sf;
576 xfs_dir_sf_entry_t *sfe;
577 xfs_inode_t *dp;
578 int i;
579
580 dp = args->dp;
581 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
582 /*
583 * Catch the case where the conversion from shortform to leaf
584 * failed part way through.
585 */
586 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
587 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
588 return XFS_ERROR(EIO);
589 }
590 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
591 ASSERT(dp->i_df.if_u1.if_data != NULL);
592 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
593 if (args->namelen == 2 &&
594 args->name[0] == '.' && args->name[1] == '.') {
595 /* XXX - replace assert? */
596 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sf->hdr.parent);
597 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA);
598 return 0;
599 }
600 ASSERT(args->namelen != 1 || args->name[0] != '.');
601 sfe = &sf->list[0];
602 for (i = sf->hdr.count-1; i >= 0; i--) {
603 if (sfe->namelen == args->namelen &&
604 sfe->name[0] == args->name[0] &&
605 memcmp(args->name, sfe->name, args->namelen) == 0) {
606 ASSERT(memcmp((char *)&args->inumber,
607 (char *)&sfe->inumber, sizeof(xfs_ino_t)));
608 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber);
609 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA);
610 return 0;
611 }
612 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
613 }
614 ASSERT(args->oknoent);
615 return XFS_ERROR(ENOENT);
616}
617
618/*
619 * Convert a leaf directory to shortform structure
620 */
621int
622xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs)
623{
624 xfs_dir_leafblock_t *leaf;
625 xfs_dir_leaf_hdr_t *hdr;
626 xfs_dir_leaf_entry_t *entry;
627 xfs_dir_leaf_name_t *namest;
628 xfs_da_args_t args;
629 xfs_inode_t *dp;
630 xfs_ino_t parent = 0;
631 char *tmpbuffer;
632 int retval, i;
633 xfs_dabuf_t *bp;
634
635 dp = iargs->dp;
636 tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP);
637 ASSERT(tmpbuffer != NULL);
638
639 retval = xfs_da_read_buf(iargs->trans, iargs->dp, 0, -1, &bp,
640 XFS_DATA_FORK);
641 if (retval)
642 goto out;
643 ASSERT(bp != NULL);
644 memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount));
645 leaf = (xfs_dir_leafblock_t *)tmpbuffer;
646 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
647 memset(bp->data, 0, XFS_LBSIZE(dp->i_mount));
648
649 /*
650 * Find and special case the parent inode number
651 */
652 hdr = &leaf->hdr;
653 entry = &leaf->entries[0];
654 for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) {
655 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
656 if ((entry->namelen == 2) &&
657 (namest->name[0] == '.') &&
658 (namest->name[1] == '.')) {
659 XFS_DIR_SF_GET_DIRINO(&namest->inumber, &parent);
660 entry->nameidx = 0;
661 } else if ((entry->namelen == 1) && (namest->name[0] == '.')) {
662 entry->nameidx = 0;
663 }
664 }
665 retval = xfs_da_shrink_inode(iargs, 0, bp);
666 if (retval)
667 goto out;
668 retval = xfs_dir_shortform_create(iargs, parent);
669 if (retval)
670 goto out;
671
672 /*
673 * Copy the rest of the filenames
674 */
675 entry = &leaf->entries[0];
676 args.dp = dp;
677 args.firstblock = iargs->firstblock;
678 args.flist = iargs->flist;
679 args.total = iargs->total;
680 args.whichfork = XFS_DATA_FORK;
681 args.trans = iargs->trans;
682 args.justcheck = 0;
683 args.addname = args.oknoent = 1;
684 for (i = 0; i < INT_GET(hdr->count, ARCH_CONVERT); entry++, i++) {
685 if (!entry->nameidx)
686 continue;
687 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
688 args.name = (char *)(namest->name);
689 args.namelen = entry->namelen;
690 args.hashval = INT_GET(entry->hashval, ARCH_CONVERT);
691 XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args.inumber);
692 xfs_dir_shortform_addname(&args);
693 }
694
695out:
696 kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount));
697 return retval;
698}
699
700/*
701 * Convert from using a single leaf to a root node and a leaf.
702 */
703int
704xfs_dir_leaf_to_node(xfs_da_args_t *args)
705{
706 xfs_dir_leafblock_t *leaf;
707 xfs_da_intnode_t *node;
708 xfs_inode_t *dp;
709 xfs_dabuf_t *bp1, *bp2;
710 xfs_dablk_t blkno;
711 int retval;
712
713 dp = args->dp;
714 retval = xfs_da_grow_inode(args, &blkno);
715 ASSERT(blkno == 1);
716 if (retval)
717 return retval;
718 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1,
719 XFS_DATA_FORK);
720 if (retval)
721 return retval;
722 ASSERT(bp1 != NULL);
723 retval = xfs_da_get_buf(args->trans, args->dp, 1, -1, &bp2,
724 XFS_DATA_FORK);
725 if (retval) {
726 xfs_da_buf_done(bp1);
727 return retval;
728 }
729 ASSERT(bp2 != NULL);
730 memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount));
731 xfs_da_buf_done(bp1);
732 xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1);
733
734 /*
735 * Set up the new root node.
736 */
737 retval = xfs_da_node_create(args, 0, 1, &bp1, XFS_DATA_FORK);
738 if (retval) {
739 xfs_da_buf_done(bp2);
740 return retval;
741 }
742 node = bp1->data;
743 leaf = bp2->data;
744 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
745 node->btree[0].hashval = cpu_to_be32(
746 INT_GET(leaf->entries[
747 INT_GET(leaf->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT));
748 xfs_da_buf_done(bp2);
749 node->btree[0].before = cpu_to_be32(blkno);
750 node->hdr.count = cpu_to_be16(1);
751 xfs_da_log_buf(args->trans, bp1,
752 XFS_DA_LOGRANGE(node, &node->btree[0], sizeof(node->btree[0])));
753 xfs_da_buf_done(bp1);
754
755 return retval;
756}
757
758
759/*========================================================================
760 * Routines used for growing the Btree.
761 *========================================================================*/
762
763/*
764 * Create the initial contents of a leaf directory
765 * or a leaf in a node directory.
766 */
767STATIC int
768xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
769{
770 xfs_dir_leafblock_t *leaf;
771 xfs_dir_leaf_hdr_t *hdr;
772 xfs_inode_t *dp;
773 xfs_dabuf_t *bp;
774 int retval;
775
776 dp = args->dp;
777 ASSERT(dp != NULL);
778 retval = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp, XFS_DATA_FORK);
779 if (retval)
780 return retval;
781 ASSERT(bp != NULL);
782 leaf = bp->data;
783 memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount));
784 hdr = &leaf->hdr;
785 hdr->info.magic = cpu_to_be16(XFS_DIR_LEAF_MAGIC);
786 INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount));
787 if (!hdr->firstused)
788 INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount) - 1);
789 INT_SET(hdr->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t));
790 INT_SET(hdr->freemap[0].size, ARCH_CONVERT, INT_GET(hdr->firstused, ARCH_CONVERT) - INT_GET(hdr->freemap[0].base, ARCH_CONVERT));
791
792 xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1);
793
794 *bpp = bp;
795 return 0;
796}
797
798/*
799 * Split the leaf node, rebalance, then add the new entry.
800 */
801int
802xfs_dir_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
803 xfs_da_state_blk_t *newblk)
804{
805 xfs_dablk_t blkno;
806 xfs_da_args_t *args;
807 int error;
808
809 /*
810 * Allocate space for a new leaf node.
811 */
812 args = state->args;
813 ASSERT(args != NULL);
814 ASSERT(oldblk->magic == XFS_DIR_LEAF_MAGIC);
815 error = xfs_da_grow_inode(args, &blkno);
816 if (error)
817 return error;
818 error = xfs_dir_leaf_create(args, blkno, &newblk->bp);
819 if (error)
820 return error;
821 newblk->blkno = blkno;
822 newblk->magic = XFS_DIR_LEAF_MAGIC;
823
824 /*
825 * Rebalance the entries across the two leaves.
826 */
827 xfs_dir_leaf_rebalance(state, oldblk, newblk);
828 error = xfs_da_blk_link(state, oldblk, newblk);
829 if (error)
830 return error;
831
832 /*
833 * Insert the new entry in the correct block.
834 */
835 if (state->inleaf) {
836 error = xfs_dir_leaf_add(oldblk->bp, args, oldblk->index);
837 } else {
838 error = xfs_dir_leaf_add(newblk->bp, args, newblk->index);
839 }
840
841 /*
842 * Update last hashval in each block since we added the name.
843 */
844 oldblk->hashval = xfs_dir_leaf_lasthash(oldblk->bp, NULL);
845 newblk->hashval = xfs_dir_leaf_lasthash(newblk->bp, NULL);
846 return error;
847}
848
849/*
850 * Add a name to the leaf directory structure.
851 *
852 * Must take into account fragmented leaves and leaves where spacemap has
853 * lost some freespace information (ie: holes).
854 */
855int
856xfs_dir_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index)
857{
858 xfs_dir_leafblock_t *leaf;
859 xfs_dir_leaf_hdr_t *hdr;
860 xfs_dir_leaf_map_t *map;
861 int tablesize, entsize, sum, i, tmp, error;
862
863 leaf = bp->data;
864 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
865 ASSERT((index >= 0) && (index <= INT_GET(leaf->hdr.count, ARCH_CONVERT)));
866 hdr = &leaf->hdr;
867 entsize = XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen);
868
869 /*
870 * Search through freemap for first-fit on new name length.
871 * (may need to figure in size of entry struct too)
872 */
873 tablesize = (INT_GET(hdr->count, ARCH_CONVERT) + 1) * (uint)sizeof(xfs_dir_leaf_entry_t)
874 + (uint)sizeof(xfs_dir_leaf_hdr_t);
875 map = &hdr->freemap[XFS_DIR_LEAF_MAPSIZE-1];
876 for (sum = 0, i = XFS_DIR_LEAF_MAPSIZE-1; i >= 0; map--, i--) {
877 if (tablesize > INT_GET(hdr->firstused, ARCH_CONVERT)) {
878 sum += INT_GET(map->size, ARCH_CONVERT);
879 continue;
880 }
881 if (!map->size)
882 continue; /* no space in this map */
883 tmp = entsize;
884 if (INT_GET(map->base, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT))
885 tmp += (uint)sizeof(xfs_dir_leaf_entry_t);
886 if (INT_GET(map->size, ARCH_CONVERT) >= tmp) {
887 if (!args->justcheck)
888 xfs_dir_leaf_add_work(bp, args, index, i);
889 return 0;
890 }
891 sum += INT_GET(map->size, ARCH_CONVERT);
892 }
893
894 /*
895 * If there are no holes in the address space of the block,
896 * and we don't have enough freespace, then compaction will do us
897 * no good and we should just give up.
898 */
899 if (!hdr->holes && (sum < entsize))
900 return XFS_ERROR(ENOSPC);
901
902 /*
903 * Compact the entries to coalesce free space.
904 * Pass the justcheck flag so the checking pass can return
905 * an error, without changing anything, if it won't fit.
906 */
907 error = xfs_dir_leaf_compact(args->trans, bp,
908 args->total == 0 ?
909 entsize +
910 (uint)sizeof(xfs_dir_leaf_entry_t) : 0,
911 args->justcheck);
912 if (error)
913 return error;
914 /*
915 * After compaction, the block is guaranteed to have only one
916 * free region, in freemap[0]. If it is not big enough, give up.
917 */
918 if (INT_GET(hdr->freemap[0].size, ARCH_CONVERT) <
919 (entsize + (uint)sizeof(xfs_dir_leaf_entry_t)))
920 return XFS_ERROR(ENOSPC);
921
922 if (!args->justcheck)
923 xfs_dir_leaf_add_work(bp, args, index, 0);
924 return 0;
925}
926
927/*
928 * Add a name to a leaf directory structure.
929 */
930STATIC void
931xfs_dir_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int index,
932 int mapindex)
933{
934 xfs_dir_leafblock_t *leaf;
935 xfs_dir_leaf_hdr_t *hdr;
936 xfs_dir_leaf_entry_t *entry;
937 xfs_dir_leaf_name_t *namest;
938 xfs_dir_leaf_map_t *map;
939 /* REFERENCED */
940 xfs_mount_t *mp;
941 int tmp, i;
942
943 leaf = bp->data;
944 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
945 hdr = &leaf->hdr;
946 ASSERT((mapindex >= 0) && (mapindex < XFS_DIR_LEAF_MAPSIZE));
947 ASSERT((index >= 0) && (index <= INT_GET(hdr->count, ARCH_CONVERT)));
948
949 /*
950 * Force open some space in the entry array and fill it in.
951 */
952 entry = &leaf->entries[index];
953 if (index < INT_GET(hdr->count, ARCH_CONVERT)) {
954 tmp = INT_GET(hdr->count, ARCH_CONVERT) - index;
955 tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
956 memmove(entry + 1, entry, tmp);
957 xfs_da_log_buf(args->trans, bp,
958 XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry)));
959 }
960 INT_MOD(hdr->count, ARCH_CONVERT, +1);
961
962 /*
963 * Allocate space for the new string (at the end of the run).
964 */
965 map = &hdr->freemap[mapindex];
966 mp = args->trans->t_mountp;
967 ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
968 ASSERT(INT_GET(map->size, ARCH_CONVERT) >= XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen));
969 ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
970 INT_MOD(map->size, ARCH_CONVERT, -(XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen)));
971 INT_SET(entry->nameidx, ARCH_CONVERT, INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT));
972 INT_SET(entry->hashval, ARCH_CONVERT, args->hashval);
973 entry->namelen = args->namelen;
974 xfs_da_log_buf(args->trans, bp,
975 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
976
977 /*
978 * Copy the string and inode number into the new space.
979 */
980 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
981 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &namest->inumber);
982 memcpy(namest->name, args->name, args->namelen);
983 xfs_da_log_buf(args->trans, bp,
984 XFS_DA_LOGRANGE(leaf, namest, XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry)));
985
986 /*
987 * Update the control info for this leaf node
988 */
989 if (INT_GET(entry->nameidx, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT))
990 INT_COPY(hdr->firstused, entry->nameidx, ARCH_CONVERT);
991 ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr)));
992 tmp = (INT_GET(hdr->count, ARCH_CONVERT)-1) * (uint)sizeof(xfs_dir_leaf_entry_t)
993 + (uint)sizeof(xfs_dir_leaf_hdr_t);
994 map = &hdr->freemap[0];
995 for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) {
996 if (INT_GET(map->base, ARCH_CONVERT) == tmp) {
997 INT_MOD(map->base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t));
998 INT_MOD(map->size, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t)));
999 }
1000 }
1001 INT_MOD(hdr->namebytes, ARCH_CONVERT, args->namelen);
1002 xfs_da_log_buf(args->trans, bp,
1003 XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
1004}
1005
1006/*
1007 * Garbage collect a leaf directory block by copying it to a new buffer.
1008 */
1009STATIC int
1010xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp, int musthave,
1011 int justcheck)
1012{
1013 xfs_dir_leafblock_t *leaf_s, *leaf_d;
1014 xfs_dir_leaf_hdr_t *hdr_s, *hdr_d;
1015 xfs_mount_t *mp;
1016 char *tmpbuffer;
1017 char *tmpbuffer2=NULL;
1018 int rval;
1019 int lbsize;
1020
1021 mp = trans->t_mountp;
1022 lbsize = XFS_LBSIZE(mp);
1023 tmpbuffer = kmem_alloc(lbsize, KM_SLEEP);
1024 ASSERT(tmpbuffer != NULL);
1025 memcpy(tmpbuffer, bp->data, lbsize);
1026
1027 /*
1028 * Make a second copy in case xfs_dir_leaf_moveents()
1029 * below destroys the original.
1030 */
1031 if (musthave || justcheck) {
1032 tmpbuffer2 = kmem_alloc(lbsize, KM_SLEEP);
1033 memcpy(tmpbuffer2, bp->data, lbsize);
1034 }
1035 memset(bp->data, 0, lbsize);
1036
1037 /*
1038 * Copy basic information
1039 */
1040 leaf_s = (xfs_dir_leafblock_t *)tmpbuffer;
1041 leaf_d = bp->data;
1042 hdr_s = &leaf_s->hdr;
1043 hdr_d = &leaf_d->hdr;
1044 hdr_d->info = hdr_s->info; /* struct copy */
1045 INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize);
1046 if (!hdr_d->firstused)
1047 INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize - 1);
1048 hdr_d->namebytes = 0;
1049 hdr_d->count = 0;
1050 hdr_d->holes = 0;
1051 INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t));
1052 INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
1053
1054 /*
1055 * Copy all entry's in the same (sorted) order,
1056 * but allocate filenames packed and in sequence.
1057 * This changes the source (leaf_s) as well.
1058 */
1059 xfs_dir_leaf_moveents(leaf_s, 0, leaf_d, 0, (int)INT_GET(hdr_s->count, ARCH_CONVERT), mp);
1060
1061 if (musthave && INT_GET(hdr_d->freemap[0].size, ARCH_CONVERT) < musthave)
1062 rval = XFS_ERROR(ENOSPC);
1063 else
1064 rval = 0;
1065
1066 if (justcheck || rval == ENOSPC) {
1067 ASSERT(tmpbuffer2);
1068 memcpy(bp->data, tmpbuffer2, lbsize);
1069 } else {
1070 xfs_da_log_buf(trans, bp, 0, lbsize - 1);
1071 }
1072
1073 kmem_free(tmpbuffer, lbsize);
1074 if (musthave || justcheck)
1075 kmem_free(tmpbuffer2, lbsize);
1076 return rval;
1077}
1078
1079/*
1080 * Redistribute the directory entries between two leaf nodes,
1081 * taking into account the size of the new entry.
1082 *
1083 * NOTE: if new block is empty, then it will get the upper half of old block.
1084 */
1085STATIC void
1086xfs_dir_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1087 xfs_da_state_blk_t *blk2)
1088{
1089 xfs_da_state_blk_t *tmp_blk;
1090 xfs_dir_leafblock_t *leaf1, *leaf2;
1091 xfs_dir_leaf_hdr_t *hdr1, *hdr2;
1092 int count, totallen, max, space, swap;
1093
1094 /*
1095 * Set up environment.
1096 */
1097 ASSERT(blk1->magic == XFS_DIR_LEAF_MAGIC);
1098 ASSERT(blk2->magic == XFS_DIR_LEAF_MAGIC);
1099 leaf1 = blk1->bp->data;
1100 leaf2 = blk2->bp->data;
1101 ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1102 ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1103
1104 /*
1105 * Check ordering of blocks, reverse if it makes things simpler.
1106 */
1107 swap = 0;
1108 if (xfs_dir_leaf_order(blk1->bp, blk2->bp)) {
1109 tmp_blk = blk1;
1110 blk1 = blk2;
1111 blk2 = tmp_blk;
1112 leaf1 = blk1->bp->data;
1113 leaf2 = blk2->bp->data;
1114 swap = 1;
1115 }
1116 hdr1 = &leaf1->hdr;
1117 hdr2 = &leaf2->hdr;
1118
1119 /*
1120 * Examine entries until we reduce the absolute difference in
1121 * byte usage between the two blocks to a minimum. Then get
1122 * the direction to copy and the number of elements to move.
1123 */
1124 state->inleaf = xfs_dir_leaf_figure_balance(state, blk1, blk2,
1125 &count, &totallen);
1126 if (swap)
1127 state->inleaf = !state->inleaf;
1128
1129 /*
1130 * Move any entries required from leaf to leaf:
1131 */
1132 if (count < INT_GET(hdr1->count, ARCH_CONVERT)) {
1133 /*
1134 * Figure the total bytes to be added to the destination leaf.
1135 */
1136 count = INT_GET(hdr1->count, ARCH_CONVERT) - count; /* number entries being moved */
1137 space = INT_GET(hdr1->namebytes, ARCH_CONVERT) - totallen;
1138 space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1);
1139 space += count * (uint)sizeof(xfs_dir_leaf_entry_t);
1140
1141 /*
1142 * leaf2 is the destination, compact it if it looks tight.
1143 */
1144 max = INT_GET(hdr2->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t);
1145 max -= INT_GET(hdr2->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
1146 if (space > max) {
1147 xfs_dir_leaf_compact(state->args->trans, blk2->bp,
1148 0, 0);
1149 }
1150
1151 /*
1152 * Move high entries from leaf1 to low end of leaf2.
1153 */
1154 xfs_dir_leaf_moveents(leaf1, INT_GET(hdr1->count, ARCH_CONVERT) - count,
1155 leaf2, 0, count, state->mp);
1156
1157 xfs_da_log_buf(state->args->trans, blk1->bp, 0,
1158 state->blocksize-1);
1159 xfs_da_log_buf(state->args->trans, blk2->bp, 0,
1160 state->blocksize-1);
1161
1162 } else if (count > INT_GET(hdr1->count, ARCH_CONVERT)) {
1163 /*
1164 * Figure the total bytes to be added to the destination leaf.
1165 */
1166 count -= INT_GET(hdr1->count, ARCH_CONVERT); /* number entries being moved */
1167 space = totallen - INT_GET(hdr1->namebytes, ARCH_CONVERT);
1168 space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1);
1169 space += count * (uint)sizeof(xfs_dir_leaf_entry_t);
1170
1171 /*
1172 * leaf1 is the destination, compact it if it looks tight.
1173 */
1174 max = INT_GET(hdr1->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t);
1175 max -= INT_GET(hdr1->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
1176 if (space > max) {
1177 xfs_dir_leaf_compact(state->args->trans, blk1->bp,
1178 0, 0);
1179 }
1180
1181 /*
1182 * Move low entries from leaf2 to high end of leaf1.
1183 */
1184 xfs_dir_leaf_moveents(leaf2, 0, leaf1, (int)INT_GET(hdr1->count, ARCH_CONVERT),
1185 count, state->mp);
1186
1187 xfs_da_log_buf(state->args->trans, blk1->bp, 0,
1188 state->blocksize-1);
1189 xfs_da_log_buf(state->args->trans, blk2->bp, 0,
1190 state->blocksize-1);
1191 }
1192
1193 /*
1194 * Copy out last hashval in each block for B-tree code.
1195 */
1196 blk1->hashval = INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1197 blk2->hashval = INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1198
1199 /*
1200 * Adjust the expected index for insertion.
1201 * GROT: this doesn't work unless blk2 was originally empty.
1202 */
1203 if (!state->inleaf) {
1204 blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT);
1205 }
1206}
1207
1208/*
1209 * Examine entries until we reduce the absolute difference in
1210 * byte usage between the two blocks to a minimum.
1211 * GROT: Is this really necessary? With other than a 512 byte blocksize,
1212 * GROT: there will always be enough room in either block for a new entry.
1213 * GROT: Do a double-split for this case?
1214 */
1215STATIC int
1216xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
1217 xfs_da_state_blk_t *blk1,
1218 xfs_da_state_blk_t *blk2,
1219 int *countarg, int *namebytesarg)
1220{
1221 xfs_dir_leafblock_t *leaf1, *leaf2;
1222 xfs_dir_leaf_hdr_t *hdr1, *hdr2;
1223 xfs_dir_leaf_entry_t *entry;
1224 int count, max, totallen, half;
1225 int lastdelta, foundit, tmp;
1226
1227 /*
1228 * Set up environment.
1229 */
1230 leaf1 = blk1->bp->data;
1231 leaf2 = blk2->bp->data;
1232 hdr1 = &leaf1->hdr;
1233 hdr2 = &leaf2->hdr;
1234 foundit = 0;
1235 totallen = 0;
1236
1237 /*
1238 * Examine entries until we reduce the absolute difference in
1239 * byte usage between the two blocks to a minimum.
1240 */
1241 max = INT_GET(hdr1->count, ARCH_CONVERT) + INT_GET(hdr2->count, ARCH_CONVERT);
1242 half = (max+1) * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1);
1243 half += INT_GET(hdr1->namebytes, ARCH_CONVERT) + INT_GET(hdr2->namebytes, ARCH_CONVERT) + state->args->namelen;
1244 half /= 2;
1245 lastdelta = state->blocksize;
1246 entry = &leaf1->entries[0];
1247 for (count = 0; count < max; entry++, count++) {
1248
1249#define XFS_DIR_ABS(A) (((A) < 0) ? -(A) : (A))
1250 /*
1251 * The new entry is in the first block, account for it.
1252 */
1253 if (count == blk1->index) {
1254 tmp = totallen + (uint)sizeof(*entry)
1255 + XFS_DIR_LEAF_ENTSIZE_BYNAME(state->args->namelen);
1256 if (XFS_DIR_ABS(half - tmp) > lastdelta)
1257 break;
1258 lastdelta = XFS_DIR_ABS(half - tmp);
1259 totallen = tmp;
1260 foundit = 1;
1261 }
1262
1263 /*
1264 * Wrap around into the second block if necessary.
1265 */
1266 if (count == INT_GET(hdr1->count, ARCH_CONVERT)) {
1267 leaf1 = leaf2;
1268 entry = &leaf1->entries[0];
1269 }
1270
1271 /*
1272 * Figure out if next leaf entry would be too much.
1273 */
1274 tmp = totallen + (uint)sizeof(*entry)
1275 + XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry);
1276 if (XFS_DIR_ABS(half - tmp) > lastdelta)
1277 break;
1278 lastdelta = XFS_DIR_ABS(half - tmp);
1279 totallen = tmp;
1280#undef XFS_DIR_ABS
1281 }
1282
1283 /*
1284 * Calculate the number of namebytes that will end up in lower block.
1285 * If new entry not in lower block, fix up the count.
1286 */
1287 totallen -=
1288 count * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1);
1289 if (foundit) {
1290 totallen -= (sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1) +
1291 state->args->namelen;
1292 }
1293
1294 *countarg = count;
1295 *namebytesarg = totallen;
1296 return foundit;
1297}
1298
1299/*========================================================================
1300 * Routines used for shrinking the Btree.
1301 *========================================================================*/
1302
1303/*
1304 * Check a leaf block and its neighbors to see if the block should be
1305 * collapsed into one or the other neighbor. Always keep the block
1306 * with the smaller block number.
1307 * If the current block is over 50% full, don't try to join it, return 0.
1308 * If the block is empty, fill in the state structure and return 2.
1309 * If it can be collapsed, fill in the state structure and return 1.
1310 * If nothing can be done, return 0.
1311 */
1312int
1313xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action)
1314{
1315 xfs_dir_leafblock_t *leaf;
1316 xfs_da_state_blk_t *blk;
1317 xfs_da_blkinfo_t *info;
1318 int count, bytes, forward, error, retval, i;
1319 xfs_dablk_t blkno;
1320 xfs_dabuf_t *bp;
1321
1322 /*
1323 * Check for the degenerate case of the block being over 50% full.
1324 * If so, it's not worth even looking to see if we might be able
1325 * to coalesce with a sibling.
1326 */
1327 blk = &state->path.blk[ state->path.active-1 ];
1328 info = blk->bp->data;
1329 ASSERT(be16_to_cpu(info->magic) == XFS_DIR_LEAF_MAGIC);
1330 leaf = (xfs_dir_leafblock_t *)info;
1331 count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1332 bytes = (uint)sizeof(xfs_dir_leaf_hdr_t) +
1333 count * (uint)sizeof(xfs_dir_leaf_entry_t) +
1334 count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) +
1335 INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1336 if (bytes > (state->blocksize >> 1)) {
1337 *action = 0; /* blk over 50%, don't try to join */
1338 return 0;
1339 }
1340
1341 /*
1342 * Check for the degenerate case of the block being empty.
1343 * If the block is empty, we'll simply delete it, no need to
1344 * coalesce it with a sibling block. We choose (arbitrarily)
1345 * to merge with the forward block unless it is NULL.
1346 */
1347 if (count == 0) {
1348 /*
1349 * Make altpath point to the block we want to keep and
1350 * path point to the block we want to drop (this one).
1351 */
1352 forward = (info->forw != 0);
1353 memcpy(&state->altpath, &state->path, sizeof(state->path));
1354 error = xfs_da_path_shift(state, &state->altpath, forward,
1355 0, &retval);
1356 if (error)
1357 return error;
1358 if (retval) {
1359 *action = 0;
1360 } else {
1361 *action = 2;
1362 }
1363 return 0;
1364 }
1365
1366 /*
1367 * Examine each sibling block to see if we can coalesce with
1368 * at least 25% free space to spare. We need to figure out
1369 * whether to merge with the forward or the backward block.
1370 * We prefer coalescing with the lower numbered sibling so as
1371 * to shrink a directory over time.
1372 */
1373 forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); /* start with smaller blk num */
1374 for (i = 0; i < 2; forward = !forward, i++) {
1375 if (forward)
1376 blkno = be32_to_cpu(info->forw);
1377 else
1378 blkno = be32_to_cpu(info->back);
1379 if (blkno == 0)
1380 continue;
1381 error = xfs_da_read_buf(state->args->trans, state->args->dp,
1382 blkno, -1, &bp,
1383 XFS_DATA_FORK);
1384 if (error)
1385 return error;
1386 ASSERT(bp != NULL);
1387
1388 leaf = (xfs_dir_leafblock_t *)info;
1389 count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1390 bytes = state->blocksize - (state->blocksize>>2);
1391 bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1392 leaf = bp->data;
1393 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1394 count += INT_GET(leaf->hdr.count, ARCH_CONVERT);
1395 bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1396 bytes -= count * ((uint)sizeof(xfs_dir_leaf_name_t) - 1);
1397 bytes -= count * (uint)sizeof(xfs_dir_leaf_entry_t);
1398 bytes -= (uint)sizeof(xfs_dir_leaf_hdr_t);
1399 if (bytes >= 0)
1400 break; /* fits with at least 25% to spare */
1401
1402 xfs_da_brelse(state->args->trans, bp);
1403 }
1404 if (i >= 2) {
1405 *action = 0;
1406 return 0;
1407 }
1408 xfs_da_buf_done(bp);
1409
1410 /*
1411 * Make altpath point to the block we want to keep (the lower
1412 * numbered block) and path point to the block we want to drop.
1413 */
1414 memcpy(&state->altpath, &state->path, sizeof(state->path));
1415 if (blkno < blk->blkno) {
1416 error = xfs_da_path_shift(state, &state->altpath, forward,
1417 0, &retval);
1418 } else {
1419 error = xfs_da_path_shift(state, &state->path, forward,
1420 0, &retval);
1421 }
1422 if (error)
1423 return error;
1424 if (retval) {
1425 *action = 0;
1426 } else {
1427 *action = 1;
1428 }
1429 return 0;
1430}
1431
1432/*
1433 * Remove a name from the leaf directory structure.
1434 *
1435 * Return 1 if leaf is less than 37% full, 0 if >= 37% full.
1436 * If two leaves are 37% full, when combined they will leave 25% free.
1437 */
1438int
1439xfs_dir_leaf_remove(xfs_trans_t *trans, xfs_dabuf_t *bp, int index)
1440{
1441 xfs_dir_leafblock_t *leaf;
1442 xfs_dir_leaf_hdr_t *hdr;
1443 xfs_dir_leaf_map_t *map;
1444 xfs_dir_leaf_entry_t *entry;
1445 xfs_dir_leaf_name_t *namest;
1446 int before, after, smallest, entsize;
1447 int tablesize, tmp, i;
1448 xfs_mount_t *mp;
1449
1450 leaf = bp->data;
1451 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1452 hdr = &leaf->hdr;
1453 mp = trans->t_mountp;
1454 ASSERT((INT_GET(hdr->count, ARCH_CONVERT) > 0) && (INT_GET(hdr->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
1455 ASSERT((index >= 0) && (index < INT_GET(hdr->count, ARCH_CONVERT)));
1456 ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr)));
1457 entry = &leaf->entries[index];
1458 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT));
1459 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp));
1460
1461 /*
1462 * Scan through free region table:
1463 * check for adjacency of free'd entry with an existing one,
1464 * find smallest free region in case we need to replace it,
1465 * adjust any map that borders the entry table,
1466 */
1467 tablesize = INT_GET(hdr->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)
1468 + (uint)sizeof(xfs_dir_leaf_hdr_t);
1469 map = &hdr->freemap[0];
1470 tmp = INT_GET(map->size, ARCH_CONVERT);
1471 before = after = -1;
1472 smallest = XFS_DIR_LEAF_MAPSIZE - 1;
1473 entsize = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry);
1474 for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) {
1475 ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
1476 ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
1477 if (INT_GET(map->base, ARCH_CONVERT) == tablesize) {
1478 INT_MOD(map->base, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t)));
1479 INT_MOD(map->size, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t));
1480 }
1481
1482 if ((INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT)) == INT_GET(entry->nameidx, ARCH_CONVERT)) {
1483 before = i;
1484 } else if (INT_GET(map->base, ARCH_CONVERT) == (INT_GET(entry->nameidx, ARCH_CONVERT) + entsize)) {
1485 after = i;
1486 } else if (INT_GET(map->size, ARCH_CONVERT) < tmp) {
1487 tmp = INT_GET(map->size, ARCH_CONVERT);
1488 smallest = i;
1489 }
1490 }
1491
1492 /*
1493 * Coalesce adjacent freemap regions,
1494 * or replace the smallest region.
1495 */
1496 if ((before >= 0) || (after >= 0)) {
1497 if ((before >= 0) && (after >= 0)) {
1498 map = &hdr->freemap[before];
1499 INT_MOD(map->size, ARCH_CONVERT, entsize);
1500 INT_MOD(map->size, ARCH_CONVERT, INT_GET(hdr->freemap[after].size, ARCH_CONVERT));
1501 hdr->freemap[after].base = 0;
1502 hdr->freemap[after].size = 0;
1503 } else if (before >= 0) {
1504 map = &hdr->freemap[before];
1505 INT_MOD(map->size, ARCH_CONVERT, entsize);
1506 } else {
1507 map = &hdr->freemap[after];
1508 INT_COPY(map->base, entry->nameidx, ARCH_CONVERT);
1509 INT_MOD(map->size, ARCH_CONVERT, entsize);
1510 }
1511 } else {
1512 /*
1513 * Replace smallest region (if it is smaller than free'd entry)
1514 */
1515 map = &hdr->freemap[smallest];
1516 if (INT_GET(map->size, ARCH_CONVERT) < entsize) {
1517 INT_COPY(map->base, entry->nameidx, ARCH_CONVERT);
1518 INT_SET(map->size, ARCH_CONVERT, entsize);
1519 }
1520 }
1521
1522 /*
1523 * Did we remove the first entry?
1524 */
1525 if (INT_GET(entry->nameidx, ARCH_CONVERT) == INT_GET(hdr->firstused, ARCH_CONVERT))
1526 smallest = 1;
1527 else
1528 smallest = 0;
1529
1530 /*
1531 * Compress the remaining entries and zero out the removed stuff.
1532 */
1533 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
1534 memset((char *)namest, 0, entsize);
1535 xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, namest, entsize));
1536
1537 INT_MOD(hdr->namebytes, ARCH_CONVERT, -(entry->namelen));
1538 tmp = (INT_GET(hdr->count, ARCH_CONVERT) - index) * (uint)sizeof(xfs_dir_leaf_entry_t);
1539 memmove(entry, entry + 1, tmp);
1540 INT_MOD(hdr->count, ARCH_CONVERT, -1);
1541 xfs_da_log_buf(trans, bp,
1542 XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry)));
1543 entry = &leaf->entries[INT_GET(hdr->count, ARCH_CONVERT)];
1544 memset((char *)entry, 0, sizeof(xfs_dir_leaf_entry_t));
1545
1546 /*
1547 * If we removed the first entry, re-find the first used byte
1548 * in the name area. Note that if the entry was the "firstused",
1549 * then we don't have a "hole" in our block resulting from
1550 * removing the name.
1551 */
1552 if (smallest) {
1553 tmp = XFS_LBSIZE(mp);
1554 entry = &leaf->entries[0];
1555 for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) {
1556 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT));
1557 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp));
1558 if (INT_GET(entry->nameidx, ARCH_CONVERT) < tmp)
1559 tmp = INT_GET(entry->nameidx, ARCH_CONVERT);
1560 }
1561 INT_SET(hdr->firstused, ARCH_CONVERT, tmp);
1562 if (!hdr->firstused)
1563 INT_SET(hdr->firstused, ARCH_CONVERT, tmp - 1);
1564 } else {
1565 hdr->holes = 1; /* mark as needing compaction */
1566 }
1567
1568 xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
1569
1570 /*
1571 * Check if leaf is less than 50% full, caller may want to
1572 * "join" the leaf with a sibling if so.
1573 */
1574 tmp = (uint)sizeof(xfs_dir_leaf_hdr_t);
1575 tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
1576 tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * ((uint)sizeof(xfs_dir_leaf_name_t) - 1);
1577 tmp += INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1578 if (tmp < mp->m_dir_magicpct)
1579 return 1; /* leaf is < 37% full */
1580 return 0;
1581}
1582
1583/*
1584 * Move all the directory entries from drop_leaf into save_leaf.
1585 */
1586void
1587xfs_dir_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1588 xfs_da_state_blk_t *save_blk)
1589{
1590 xfs_dir_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf;
1591 xfs_dir_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr;
1592 xfs_mount_t *mp;
1593 char *tmpbuffer;
1594
1595 /*
1596 * Set up environment.
1597 */
1598 mp = state->mp;
1599 ASSERT(drop_blk->magic == XFS_DIR_LEAF_MAGIC);
1600 ASSERT(save_blk->magic == XFS_DIR_LEAF_MAGIC);
1601 drop_leaf = drop_blk->bp->data;
1602 save_leaf = save_blk->bp->data;
1603 ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1604 ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1605 drop_hdr = &drop_leaf->hdr;
1606 save_hdr = &save_leaf->hdr;
1607
1608 /*
1609 * Save last hashval from dying block for later Btree fixup.
1610 */
1611 drop_blk->hashval = INT_GET(drop_leaf->entries[ drop_leaf->hdr.count-1 ].hashval, ARCH_CONVERT);
1612
1613 /*
1614 * Check if we need a temp buffer, or can we do it in place.
1615 * Note that we don't check "leaf" for holes because we will
1616 * always be dropping it, toosmall() decided that for us already.
1617 */
1618 if (save_hdr->holes == 0) {
1619 /*
1620 * dest leaf has no holes, so we add there. May need
1621 * to make some room in the entry array.
1622 */
1623 if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) {
1624 xfs_dir_leaf_moveents(drop_leaf, 0, save_leaf, 0,
1625 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1626 } else {
1627 xfs_dir_leaf_moveents(drop_leaf, 0,
1628 save_leaf, INT_GET(save_hdr->count, ARCH_CONVERT),
1629 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1630 }
1631 } else {
1632 /*
1633 * Destination has holes, so we make a temporary copy
1634 * of the leaf and add them both to that.
1635 */
1636 tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP);
1637 ASSERT(tmpbuffer != NULL);
1638 memset(tmpbuffer, 0, state->blocksize);
1639 tmp_leaf = (xfs_dir_leafblock_t *)tmpbuffer;
1640 tmp_hdr = &tmp_leaf->hdr;
1641 tmp_hdr->info = save_hdr->info; /* struct copy */
1642 tmp_hdr->count = 0;
1643 INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize);
1644 if (!tmp_hdr->firstused)
1645 INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize - 1);
1646 tmp_hdr->namebytes = 0;
1647 if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) {
1648 xfs_dir_leaf_moveents(drop_leaf, 0, tmp_leaf, 0,
1649 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1650 xfs_dir_leaf_moveents(save_leaf, 0,
1651 tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT),
1652 (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp);
1653 } else {
1654 xfs_dir_leaf_moveents(save_leaf, 0, tmp_leaf, 0,
1655 (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp);
1656 xfs_dir_leaf_moveents(drop_leaf, 0,
1657 tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT),
1658 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1659 }
1660 memcpy(save_leaf, tmp_leaf, state->blocksize);
1661 kmem_free(tmpbuffer, state->blocksize);
1662 }
1663
1664 xfs_da_log_buf(state->args->trans, save_blk->bp, 0,
1665 state->blocksize - 1);
1666
1667 /*
1668 * Copy out last hashval in each block for B-tree code.
1669 */
1670 save_blk->hashval = INT_GET(save_leaf->entries[ INT_GET(save_leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1671}
1672
1673/*========================================================================
1674 * Routines used for finding things in the Btree.
1675 *========================================================================*/
1676
1677/*
1678 * Look up a name in a leaf directory structure.
1679 * This is the internal routine, it uses the caller's buffer.
1680 *
1681 * Note that duplicate keys are allowed, but only check within the
1682 * current leaf node. The Btree code must check in adjacent leaf nodes.
1683 *
1684 * Return in *index the index into the entry[] array of either the found
1685 * entry, or where the entry should have been (insert before that entry).
1686 *
1687 * Don't change the args->inumber unless we find the filename.
1688 */
1689int
1690xfs_dir_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args, int *index)
1691{
1692 xfs_dir_leafblock_t *leaf;
1693 xfs_dir_leaf_entry_t *entry;
1694 xfs_dir_leaf_name_t *namest;
1695 int probe, span;
1696 xfs_dahash_t hashval;
1697
1698 leaf = bp->data;
1699 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1700 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) < (XFS_LBSIZE(args->dp->i_mount)/8));
1701
1702 /*
1703 * Binary search. (note: small blocks will skip this loop)
1704 */
1705 hashval = args->hashval;
1706 probe = span = INT_GET(leaf->hdr.count, ARCH_CONVERT) / 2;
1707 for (entry = &leaf->entries[probe]; span > 4;
1708 entry = &leaf->entries[probe]) {
1709 span /= 2;
1710 if (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)
1711 probe += span;
1712 else if (INT_GET(entry->hashval, ARCH_CONVERT) > hashval)
1713 probe -= span;
1714 else
1715 break;
1716 }
1717 ASSERT((probe >= 0) && \
1718 ((!leaf->hdr.count) || (probe < INT_GET(leaf->hdr.count, ARCH_CONVERT))));
1719 ASSERT((span <= 4) || (INT_GET(entry->hashval, ARCH_CONVERT) == hashval));
1720
1721 /*
1722 * Since we may have duplicate hashval's, find the first matching
1723 * hashval in the leaf.
1724 */
1725 while ((probe > 0) && (INT_GET(entry->hashval, ARCH_CONVERT) >= hashval)) {
1726 entry--;
1727 probe--;
1728 }
1729 while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)) {
1730 entry++;
1731 probe++;
1732 }
1733 if ((probe == INT_GET(leaf->hdr.count, ARCH_CONVERT)) || (INT_GET(entry->hashval, ARCH_CONVERT) != hashval)) {
1734 *index = probe;
1735 ASSERT(args->oknoent);
1736 return XFS_ERROR(ENOENT);
1737 }
1738
1739 /*
1740 * Duplicate keys may be present, so search all of them for a match.
1741 */
1742 while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) == hashval)) {
1743 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
1744 if (entry->namelen == args->namelen &&
1745 namest->name[0] == args->name[0] &&
1746 memcmp(args->name, namest->name, args->namelen) == 0) {
1747 XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args->inumber);
1748 *index = probe;
1749 return XFS_ERROR(EEXIST);
1750 }
1751 entry++;
1752 probe++;
1753 }
1754 *index = probe;
1755 ASSERT(probe == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent);
1756 return XFS_ERROR(ENOENT);
1757}
1758
1759/*========================================================================
1760 * Utility routines.
1761 *========================================================================*/
1762
1763/*
1764 * Move the indicated entries from one leaf to another.
1765 * NOTE: this routine modifies both source and destination leaves.
1766 */
1767/* ARGSUSED */
1768STATIC void
1769xfs_dir_leaf_moveents(xfs_dir_leafblock_t *leaf_s, int start_s,
1770 xfs_dir_leafblock_t *leaf_d, int start_d,
1771 int count, xfs_mount_t *mp)
1772{
1773 xfs_dir_leaf_hdr_t *hdr_s, *hdr_d;
1774 xfs_dir_leaf_entry_t *entry_s, *entry_d;
1775 int tmp, i;
1776
1777 /*
1778 * Check for nothing to do.
1779 */
1780 if (count == 0)
1781 return;
1782
1783 /*
1784 * Set up environment.
1785 */
1786 ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1787 ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1788 hdr_s = &leaf_s->hdr;
1789 hdr_d = &leaf_d->hdr;
1790 ASSERT((INT_GET(hdr_s->count, ARCH_CONVERT) > 0) && (INT_GET(hdr_s->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
1791 ASSERT(INT_GET(hdr_s->firstused, ARCH_CONVERT) >=
1792 ((INT_GET(hdr_s->count, ARCH_CONVERT)*sizeof(*entry_s))+sizeof(*hdr_s)));
1793 ASSERT(INT_GET(hdr_d->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8));
1794 ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >=
1795 ((INT_GET(hdr_d->count, ARCH_CONVERT)*sizeof(*entry_d))+sizeof(*hdr_d)));
1796
1797 ASSERT(start_s < INT_GET(hdr_s->count, ARCH_CONVERT));
1798 ASSERT(start_d <= INT_GET(hdr_d->count, ARCH_CONVERT));
1799 ASSERT(count <= INT_GET(hdr_s->count, ARCH_CONVERT));
1800
1801 /*
1802 * Move the entries in the destination leaf up to make a hole?
1803 */
1804 if (start_d < INT_GET(hdr_d->count, ARCH_CONVERT)) {
1805 tmp = INT_GET(hdr_d->count, ARCH_CONVERT) - start_d;
1806 tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
1807 entry_s = &leaf_d->entries[start_d];
1808 entry_d = &leaf_d->entries[start_d + count];
1809 memcpy(entry_d, entry_s, tmp);
1810 }
1811
1812 /*
1813 * Copy all entry's in the same (sorted) order,
1814 * but allocate filenames packed and in sequence.
1815 */
1816 entry_s = &leaf_s->entries[start_s];
1817 entry_d = &leaf_d->entries[start_d];
1818 for (i = 0; i < count; entry_s++, entry_d++, i++) {
1819 ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) >= INT_GET(hdr_s->firstused, ARCH_CONVERT));
1820 tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s);
1821 INT_MOD(hdr_d->firstused, ARCH_CONVERT, -(tmp));
1822 entry_d->hashval = entry_s->hashval; /* INT_: direct copy */
1823 INT_COPY(entry_d->nameidx, hdr_d->firstused, ARCH_CONVERT);
1824 entry_d->namelen = entry_s->namelen;
1825 ASSERT(INT_GET(entry_d->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp));
1826 memcpy(XFS_DIR_LEAF_NAMESTRUCT(leaf_d, INT_GET(entry_d->nameidx, ARCH_CONVERT)),
1827 XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)), tmp);
1828 ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp));
1829 memset((char *)XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)),
1830 0, tmp);
1831 INT_MOD(hdr_s->namebytes, ARCH_CONVERT, -(entry_d->namelen));
1832 INT_MOD(hdr_d->namebytes, ARCH_CONVERT, entry_d->namelen);
1833 INT_MOD(hdr_s->count, ARCH_CONVERT, -1);
1834 INT_MOD(hdr_d->count, ARCH_CONVERT, +1);
1835 tmp = INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)
1836 + (uint)sizeof(xfs_dir_leaf_hdr_t);
1837 ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= tmp);
1838
1839 }
1840
1841 /*
1842 * Zero out the entries we just copied.
1843 */
1844 if (start_s == INT_GET(hdr_s->count, ARCH_CONVERT)) {
1845 tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t);
1846 entry_s = &leaf_s->entries[start_s];
1847 ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp));
1848 memset((char *)entry_s, 0, tmp);
1849 } else {
1850 /*
1851 * Move the remaining entries down to fill the hole,
1852 * then zero the entries at the top.
1853 */
1854 tmp = INT_GET(hdr_s->count, ARCH_CONVERT) - count;
1855 tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
1856 entry_s = &leaf_s->entries[start_s + count];
1857 entry_d = &leaf_s->entries[start_s];
1858 memcpy(entry_d, entry_s, tmp);
1859
1860 tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t);
1861 entry_s = &leaf_s->entries[INT_GET(hdr_s->count, ARCH_CONVERT)];
1862 ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp));
1863 memset((char *)entry_s, 0, tmp);
1864 }
1865
1866 /*
1867 * Fill in the freemap information
1868 */
1869 INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_hdr_t));
1870 INT_MOD(hdr_d->freemap[0].base, ARCH_CONVERT, INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t));
1871 INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
1872 INT_SET(hdr_d->freemap[1].base, ARCH_CONVERT, (hdr_d->freemap[2].base = 0));
1873 INT_SET(hdr_d->freemap[1].size, ARCH_CONVERT, (hdr_d->freemap[2].size = 0));
1874 hdr_s->holes = 1; /* leaf may not be compact */
1875}
1876
1877/*
1878 * Compare two leaf blocks "order".
1879 */
1880int
1881xfs_dir_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp)
1882{
1883 xfs_dir_leafblock_t *leaf1, *leaf2;
1884
1885 leaf1 = leaf1_bp->data;
1886 leaf2 = leaf2_bp->data;
1887 ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC) &&
1888 (be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC));
1889 if ((INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0) &&
1890 ((INT_GET(leaf2->entries[ 0 ].hashval, ARCH_CONVERT) <
1891 INT_GET(leaf1->entries[ 0 ].hashval, ARCH_CONVERT)) ||
1892 (INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
1893 INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) {
1894 return 1;
1895 }
1896 return 0;
1897}
1898
1899/*
1900 * Pick up the last hashvalue from a leaf block.
1901 */
1902xfs_dahash_t
1903xfs_dir_leaf_lasthash(xfs_dabuf_t *bp, int *count)
1904{
1905 xfs_dir_leafblock_t *leaf;
1906
1907 leaf = bp->data;
1908 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1909 if (count)
1910 *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1911 if (!leaf->hdr.count)
1912 return(0);
1913 return(INT_GET(leaf->entries[ INT_GET(leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT));
1914}
1915
1916/*
1917 * Copy out directory entries for getdents(), for leaf directories.
1918 */
1919int
1920xfs_dir_leaf_getdents_int(
1921 xfs_dabuf_t *bp,
1922 xfs_inode_t *dp,
1923 xfs_dablk_t bno,
1924 uio_t *uio,
1925 int *eobp,
1926 xfs_dirent_t *dbp,
1927 xfs_dir_put_t put,
1928 xfs_daddr_t nextda)
1929{
1930 xfs_dir_leafblock_t *leaf;
1931 xfs_dir_leaf_entry_t *entry;
1932 xfs_dir_leaf_name_t *namest;
1933 int entno, want_entno, i, nextentno;
1934 xfs_mount_t *mp;
1935 xfs_dahash_t cookhash;
1936 xfs_dahash_t nexthash = 0;
1937#if (BITS_PER_LONG == 32)
1938 xfs_dahash_t lasthash = XFS_DA_MAXHASH;
1939#endif
1940 xfs_dir_put_args_t p;
1941
1942 mp = dp->i_mount;
1943 leaf = bp->data;
1944 if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
1945 *eobp = 1;
1946 return XFS_ERROR(ENOENT); /* XXX wrong code */
1947 }
1948
1949 want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset);
1950
1951 cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
1952
1953 xfs_dir_trace_g_dul("leaf: start", dp, uio, leaf);
1954
1955 /*
1956 * Re-find our place.
1957 */
1958 for (i = entno = 0, entry = &leaf->entries[0];
1959 i < INT_GET(leaf->hdr.count, ARCH_CONVERT);
1960 entry++, i++) {
1961
1962 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
1963 INT_GET(entry->nameidx, ARCH_CONVERT));
1964
1965 if (unlikely(
1966 ((char *)namest < (char *)leaf) ||
1967 ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) {
1968 XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)",
1969 XFS_ERRLEVEL_LOW, mp, leaf);
1970 xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
1971 return XFS_ERROR(EFSCORRUPTED);
1972 }
1973 if (INT_GET(entry->hashval, ARCH_CONVERT) >= cookhash) {
1974 if ( entno < want_entno
1975 && INT_GET(entry->hashval, ARCH_CONVERT)
1976 == cookhash) {
1977 /*
1978 * Trying to get to a particular offset in a
1979 * run of equal-hashval entries.
1980 */
1981 entno++;
1982 } else if ( want_entno > 0
1983 && entno == want_entno
1984 && INT_GET(entry->hashval, ARCH_CONVERT)
1985 == cookhash) {
1986 break;
1987 } else {
1988 entno = 0;
1989 break;
1990 }
1991 }
1992 }
1993
1994 if (i == INT_GET(leaf->hdr.count, ARCH_CONVERT)) {
1995 xfs_dir_trace_g_du("leaf: hash not found", dp, uio);
1996 if (!leaf->hdr.info.forw)
1997 uio->uio_offset =
1998 XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH);
1999 /*
2000 * Don't set uio_offset if there's another block:
2001 * the node code will be setting uio_offset anyway.
2002 */
2003 *eobp = 0;
2004 return 0;
2005 }
2006 xfs_dir_trace_g_due("leaf: hash found", dp, uio, entry);
2007
2008 p.dbp = dbp;
2009 p.put = put;
2010 p.uio = uio;
2011
2012 /*
2013 * We're synchronized, start copying entries out to the user.
2014 */
2015 for (; entno >= 0 && i < INT_GET(leaf->hdr.count, ARCH_CONVERT);
2016 entry++, i++, (entno = nextentno)) {
2017 int lastresid=0, retval;
2018 xfs_dircook_t lastoffset;
2019 xfs_dahash_t thishash;
2020
2021 /*
2022 * Check for a damaged directory leaf block and pick up
2023 * the inode number from this entry.
2024 */
2025 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
2026 INT_GET(entry->nameidx, ARCH_CONVERT));
2027
2028 if (unlikely(
2029 ((char *)namest < (char *)leaf) ||
2030 ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) {
2031 XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)",
2032 XFS_ERRLEVEL_LOW, mp, leaf);
2033 xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
2034 return XFS_ERROR(EFSCORRUPTED);
2035 }
2036
2037 xfs_dir_trace_g_duc("leaf: middle cookie ",
2038 dp, uio, p.cook.o);
2039
2040 if (i < (INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1)) {
2041 nexthash = INT_GET(entry[1].hashval, ARCH_CONVERT);
2042
2043 if (nexthash == INT_GET(entry->hashval, ARCH_CONVERT))
2044 nextentno = entno + 1;
2045 else
2046 nextentno = 0;
2047 XFS_PUT_COOKIE(p.cook, mp, bno, nextentno, nexthash);
2048 xfs_dir_trace_g_duc("leaf: middle cookie ",
2049 dp, uio, p.cook.o);
2050
2051 } else if ((thishash = be32_to_cpu(leaf->hdr.info.forw))) {
2052 xfs_dabuf_t *bp2;
2053 xfs_dir_leafblock_t *leaf2;
2054
2055 ASSERT(nextda != -1);
2056
2057 retval = xfs_da_read_buf(dp->i_transp, dp, thishash,
2058 nextda, &bp2, XFS_DATA_FORK);
2059 if (retval)
2060 return retval;
2061
2062 ASSERT(bp2 != NULL);
2063
2064 leaf2 = bp2->data;
2065
2066 if (unlikely(
2067 (be16_to_cpu(leaf2->hdr.info.magic)
2068 != XFS_DIR_LEAF_MAGIC)
2069 || (be32_to_cpu(leaf2->hdr.info.back)
2070 != bno))) { /* GROT */
2071 XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)",
2072 XFS_ERRLEVEL_LOW, mp,
2073 leaf2);
2074 xfs_da_brelse(dp->i_transp, bp2);
2075
2076 return XFS_ERROR(EFSCORRUPTED);
2077 }
2078
2079 nexthash = INT_GET(leaf2->entries[0].hashval,
2080 ARCH_CONVERT);
2081 nextentno = -1;
2082 XFS_PUT_COOKIE(p.cook, mp, thishash, 0, nexthash);
2083 xfs_da_brelse(dp->i_transp, bp2);
2084 xfs_dir_trace_g_duc("leaf: next blk cookie",
2085 dp, uio, p.cook.o);
2086 } else {
2087 nextentno = -1;
2088 XFS_PUT_COOKIE(p.cook, mp, 0, 0, XFS_DA_MAXHASH);
2089 }
2090
2091 /*
2092 * Save off the cookie so we can fall back should the
2093 * 'put' into the outgoing buffer fails. To handle a run
2094 * of equal-hashvals, the off_t structure on 64bit
2095 * builds has entno built into the cookie to ID the
2096 * entry. On 32bit builds, we only have space for the
2097 * hashval so we can't ID specific entries within a group
2098 * of same hashval entries. For this, lastoffset is set
2099 * to the first in the run of equal hashvals so we don't
2100 * include any entries unless we can include all entries
2101 * that share the same hashval. Hopefully the buffer
2102 * provided is big enough to handle it (see pv763517).
2103 */
2104#if (BITS_PER_LONG == 32)
2105 if ((thishash = INT_GET(entry->hashval, ARCH_CONVERT))
2106 != lasthash) {
2107 XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash);
2108 lastresid = uio->uio_resid;
2109 lasthash = thishash;
2110 } else {
2111 xfs_dir_trace_g_duc("leaf: DUP COOKIES, skipped",
2112 dp, uio, p.cook.o);
2113 }
2114#else
2115 thishash = INT_GET(entry->hashval, ARCH_CONVERT);
2116 XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash);
2117 lastresid = uio->uio_resid;
2118#endif /* BITS_PER_LONG == 32 */
2119
2120 /*
2121 * Put the current entry into the outgoing buffer. If we fail
2122 * then restore the UIO to the first entry in the current
2123 * run of equal-hashval entries (probably one 1 entry long).
2124 */
2125 p.ino = XFS_GET_DIR_INO8(namest->inumber);
2126#if XFS_BIG_INUMS
2127 p.ino += mp->m_inoadd;
2128#endif
2129 p.name = (char *)namest->name;
2130 p.namelen = entry->namelen;
2131
2132 retval = p.put(&p);
2133
2134 if (!p.done) {
2135 uio->uio_offset = lastoffset.o;
2136 uio->uio_resid = lastresid;
2137
2138 *eobp = 1;
2139
2140 xfs_dir_trace_g_du("leaf: E-O-B", dp, uio);
2141
2142 return retval;
2143 }
2144 }
2145
2146 uio->uio_offset = p.cook.o;
2147
2148 *eobp = 0;
2149
2150 xfs_dir_trace_g_du("leaf: E-O-F", dp, uio);
2151
2152 return 0;
2153}
2154
2155/*
2156 * Format a dirent64 structure and copy it out the the user's buffer.
2157 */
2158int
2159xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa)
2160{
2161 iovec_t *iovp;
2162 int reclen, namelen;
2163 xfs_dirent_t *idbp;
2164 uio_t *uio;
2165
2166 namelen = pa->namelen;
2167 reclen = DIRENTSIZE(namelen);
2168 uio = pa->uio;
2169 if (reclen > uio->uio_resid) {
2170 pa->done = 0;
2171 return 0;
2172 }
2173 iovp = uio->uio_iov;
2174 idbp = (xfs_dirent_t *)iovp->iov_base;
2175 iovp->iov_base = (char *)idbp + reclen;
2176 iovp->iov_len -= reclen;
2177 uio->uio_resid -= reclen;
2178 idbp->d_reclen = reclen;
2179 idbp->d_ino = pa->ino;
2180 idbp->d_off = pa->cook.o;
2181 idbp->d_name[namelen] = '\0';
2182 pa->done = 1;
2183 memcpy(idbp->d_name, pa->name, namelen);
2184 return 0;
2185}
2186
2187/*
2188 * Format a dirent64 structure and copy it out the the user's buffer.
2189 */
2190int
2191xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa)
2192{
2193 int retval, reclen, namelen;
2194 xfs_dirent_t *idbp;
2195 uio_t *uio;
2196
2197 namelen = pa->namelen;
2198 reclen = DIRENTSIZE(namelen);
2199 uio = pa->uio;
2200 if (reclen > uio->uio_resid) {
2201 pa->done = 0;
2202 return 0;
2203 }
2204 idbp = pa->dbp;
2205 idbp->d_reclen = reclen;
2206 idbp->d_ino = pa->ino;
2207 idbp->d_off = pa->cook.o;
2208 idbp->d_name[namelen] = '\0';
2209 memcpy(idbp->d_name, pa->name, namelen);
2210 retval = uio_read((caddr_t)idbp, reclen, uio);
2211 pa->done = (retval == 0);
2212 return retval;
2213}
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
deleted file mode 100644
index eb8cd9a4667f..000000000000
--- a/fs/xfs/xfs_dir_leaf.h
+++ /dev/null
@@ -1,231 +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_DIR_LEAF_H__
19#define __XFS_DIR_LEAF_H__
20
21/*
22 * Directory layout, internal structure, access macros, etc.
23 *
24 * Large directories are structured around Btrees where all the data
25 * elements are in the leaf nodes. Filenames are hashed into an int,
26 * then that int is used as the index into the Btree. Since the hashval
27 * of a filename may not be unique, we may have duplicate keys. The
28 * internal links in the Btree are logical block offsets into the file.
29 */
30
31struct uio;
32struct xfs_bmap_free;
33struct xfs_dabuf;
34struct xfs_da_args;
35struct xfs_da_state;
36struct xfs_da_state_blk;
37struct xfs_dir_put_args;
38struct xfs_inode;
39struct xfs_mount;
40struct xfs_trans;
41
42/*========================================================================
43 * Directory Structure when equal to XFS_LBSIZE(mp) bytes.
44 *========================================================================*/
45
46/*
47 * This is the structure of the leaf nodes in the Btree.
48 *
49 * Struct leaf_entry's are packed from the top. Names grow from the bottom
50 * but are not packed. The freemap contains run-length-encoded entries
51 * for the free bytes after the leaf_entry's, but only the N largest such,
52 * smaller runs are dropped. When the freemap doesn't show enough space
53 * for an allocation, we compact the namelist area and try again. If we
54 * still don't have enough space, then we have to split the block.
55 *
56 * Since we have duplicate hash keys, for each key that matches, compare
57 * the actual string. The root and intermediate node search always takes
58 * the first-in-the-block key match found, so we should only have to work
59 * "forw"ard. If none matches, continue with the "forw"ard leaf nodes
60 * until the hash key changes or the filename is found.
61 *
62 * The parent directory and the self-pointer are explicitly represented
63 * (ie: there are entries for "." and "..").
64 *
65 * Note that the count being a __uint16_t limits us to something like a
66 * blocksize of 1.3MB in the face of worst case (short) filenames.
67 */
68#define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */
69
70typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */
71 __uint16_t base; /* base of free region */
72 __uint16_t size; /* run length of free region */
73} xfs_dir_leaf_map_t;
74
75typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */
76 xfs_da_blkinfo_t info; /* block type, links, etc. */
77 __uint16_t count; /* count of active leaf_entry's */
78 __uint16_t namebytes; /* num bytes of name strings stored */
79 __uint16_t firstused; /* first used byte in name area */
80 __uint8_t holes; /* != 0 if blk needs compaction */
81 __uint8_t pad1;
82 xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE];
83} xfs_dir_leaf_hdr_t;
84
85typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */
86 xfs_dahash_t hashval; /* hash value of name */
87 __uint16_t nameidx; /* index into buffer of name */
88 __uint8_t namelen; /* length of name string */
89 __uint8_t pad2;
90} xfs_dir_leaf_entry_t;
91
92typedef struct xfs_dir_leaf_name {
93 xfs_dir_ino_t inumber; /* inode number for this key */
94 __uint8_t name[1]; /* name string itself */
95} xfs_dir_leaf_name_t;
96
97typedef struct xfs_dir_leafblock {
98 xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */
99 xfs_dir_leaf_entry_t entries[1]; /* var sized array */
100 xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */
101} xfs_dir_leafblock_t;
102
103/*
104 * Length of name for which a 512-byte block filesystem
105 * can get a double split.
106 */
107#define XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN \
108 (512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \
109 (uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \
110 (uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1)
111
112typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa);
113
114typedef union {
115 xfs_off_t o; /* offset (cookie) */
116 /*
117 * Watch the order here (endian-ness dependent).
118 */
119 struct {
120#ifndef XFS_NATIVE_HOST
121 xfs_dahash_t h; /* hash value */
122 __uint32_t be; /* block and entry */
123#else
124 __uint32_t be; /* block and entry */
125 xfs_dahash_t h; /* hash value */
126#endif /* XFS_NATIVE_HOST */
127 } s;
128} xfs_dircook_t;
129
130#define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \
131 ((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash))
132
133typedef struct xfs_dir_put_args {
134 xfs_dircook_t cook; /* cookie of (next) entry */
135 xfs_intino_t ino; /* inode number */
136 struct xfs_dirent *dbp; /* buffer pointer */
137 char *name; /* directory entry name */
138 int namelen; /* length of name */
139 int done; /* output: set if value was stored */
140 xfs_dir_put_t put; /* put function ptr (i/o) */
141 struct uio *uio; /* uio control structure */
142} xfs_dir_put_args_t;
143
144#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \
145 xfs_dir_leaf_entsize_byname(len)
146static inline int xfs_dir_leaf_entsize_byname(int len)
147{
148 return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len;
149}
150
151#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \
152 xfs_dir_leaf_entsize_byentry(entry)
153static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry)
154{
155 return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen;
156}
157
158#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \
159 xfs_dir_leaf_namestruct(leafp,offset)
160static inline xfs_dir_leaf_name_t *
161xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset)
162{
163 return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset];
164}
165
166/*========================================================================
167 * Function prototypes for the kernel.
168 *========================================================================*/
169
170/*
171 * Internal routines when dirsize < XFS_LITINO(mp).
172 */
173int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent);
174int xfs_dir_shortform_addname(struct xfs_da_args *args);
175int xfs_dir_shortform_lookup(struct xfs_da_args *args);
176int xfs_dir_shortform_to_leaf(struct xfs_da_args *args);
177int xfs_dir_shortform_removename(struct xfs_da_args *args);
178int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp,
179 struct xfs_dirent *dbp, xfs_dir_put_t put);
180int xfs_dir_shortform_replace(struct xfs_da_args *args);
181
182/*
183 * Internal routines when dirsize == XFS_LBSIZE(mp).
184 */
185int xfs_dir_leaf_to_node(struct xfs_da_args *args);
186int xfs_dir_leaf_to_shortform(struct xfs_da_args *args);
187
188/*
189 * Routines used for growing the Btree.
190 */
191int xfs_dir_leaf_split(struct xfs_da_state *state,
192 struct xfs_da_state_blk *oldblk,
193 struct xfs_da_state_blk *newblk);
194int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer,
195 struct xfs_da_args *args, int insertion_index);
196int xfs_dir_leaf_addname(struct xfs_da_args *args);
197int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer,
198 struct xfs_da_args *args,
199 int *index_found_at);
200int xfs_dir_leaf_remove(struct xfs_trans *trans,
201 struct xfs_dabuf *leaf_buffer,
202 int index_to_remove);
203int xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp,
204 xfs_dablk_t bno, struct uio *uio,
205 int *eobp, struct xfs_dirent *dbp,
206 xfs_dir_put_t put, xfs_daddr_t nextda);
207
208/*
209 * Routines used for shrinking the Btree.
210 */
211int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval);
212void xfs_dir_leaf_unbalance(struct xfs_da_state *state,
213 struct xfs_da_state_blk *drop_blk,
214 struct xfs_da_state_blk *save_blk);
215
216/*
217 * Utility routines.
218 */
219uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count);
220int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp,
221 struct xfs_dabuf *leaf2_bp);
222int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa);
223int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa);
224int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
225
226/*
227 * Global data.
228 */
229extern xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
230
231#endif /* __XFS_DIR_LEAF_H__ */
diff --git a/fs/xfs/xfs_dir_sf.h b/fs/xfs/xfs_dir_sf.h
deleted file mode 100644
index 5b20b4d3f57d..000000000000
--- a/fs/xfs/xfs_dir_sf.h
+++ /dev/null
@@ -1,155 +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_DIR_SF_H__
19#define __XFS_DIR_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
28typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t;
29
30/*
31 * The parent directory has a dedicated field, and the self-pointer must
32 * be calculated on the fly.
33 *
34 * Entries are packed toward the top as tight as possible. The header
35 * and the elements much be memcpy'd out into a work area to get correct
36 * alignment for the inode number fields.
37 */
38typedef struct xfs_dir_sf_hdr { /* constant-structure header block */
39 xfs_dir_ino_t parent; /* parent dir inode number */
40 __uint8_t count; /* count of active entries */
41} xfs_dir_sf_hdr_t;
42
43typedef struct xfs_dir_sf_entry {
44 xfs_dir_ino_t inumber; /* referenced inode number */
45 __uint8_t namelen; /* actual length of name (no NULL) */
46 __uint8_t name[1]; /* name */
47} xfs_dir_sf_entry_t;
48
49typedef struct xfs_dir_shortform {
50 xfs_dir_sf_hdr_t hdr;
51 xfs_dir_sf_entry_t list[1]; /* variable sized array */
52} xfs_dir_shortform_t;
53
54/*
55 * We generate this then sort it, so that readdirs are returned in
56 * hash-order. Else seekdir won't work.
57 */
58typedef struct xfs_dir_sf_sort {
59 __uint8_t entno; /* .=0, ..=1, else entry# + 2 */
60 __uint8_t seqno; /* sequence # with same hash value */
61 __uint8_t namelen; /* length of name value (no null) */
62 xfs_dahash_t hash; /* this entry's hash value */
63 xfs_intino_t ino; /* this entry's inode number */
64 char *name; /* name value, pointer into buffer */
65} xfs_dir_sf_sort_t;
66
67#define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to)
68static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to)
69{
70 *(to) = XFS_GET_DIR_INO8(*from);
71}
72
73#define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to)
74static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to)
75{
76 XFS_PUT_DIR_INO8(*(from), *(to));
77}
78
79#define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len)
80static inline int xfs_dir_sf_entsize_byname(int len)
81{
82 return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len);
83}
84
85#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep)
86static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep)
87{
88 return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen;
89}
90
91#define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep)
92static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep)
93{
94 return (xfs_dir_sf_entry_t *) \
95 ((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep));
96}
97
98#define XFS_DIR_SF_ALLFIT(count,totallen) \
99 xfs_dir_sf_allfit(count,totallen)
100static inline int xfs_dir_sf_allfit(int count, int totallen)
101{
102 return ((uint)sizeof(xfs_dir_sf_hdr_t) + \
103 ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen));
104}
105
106#if defined(XFS_DIR_TRACE)
107
108/*
109 * Kernel tracing support for directories.
110 */
111struct uio;
112struct xfs_inode;
113struct xfs_da_intnode;
114struct xfs_dinode;
115struct xfs_dir_leafblock;
116struct xfs_dir_leaf_entry;
117
118#define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */
119extern ktrace_t *xfs_dir_trace_buf;
120
121/*
122 * Trace record types.
123 */
124#define XFS_DIR_KTRACE_G_DU 1 /* dp, uio */
125#define XFS_DIR_KTRACE_G_DUB 2 /* dp, uio, bno */
126#define XFS_DIR_KTRACE_G_DUN 3 /* dp, uio, node */
127#define XFS_DIR_KTRACE_G_DUL 4 /* dp, uio, leaf */
128#define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */
129#define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */
130
131void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio);
132void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio,
133 xfs_dablk_t bno);
134void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio,
135 struct xfs_da_intnode *node);
136void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio,
137 struct xfs_dir_leafblock *leaf);
138void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio,
139 struct xfs_dir_leaf_entry *entry);
140void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio,
141 xfs_off_t cookie);
142void xfs_dir_trace_enter(int type, char *where,
143 void *a0, void *a1, void *a2, void *a3,
144 void *a4, void *a5, void *a6, void *a7,
145 void *a8, void *a9, void *a10, void *a11);
146#else
147#define xfs_dir_trace_g_du(w,d,u)
148#define xfs_dir_trace_g_dub(w,d,u,b)
149#define xfs_dir_trace_g_dun(w,d,u,n)
150#define xfs_dir_trace_g_dul(w,d,u,l)
151#define xfs_dir_trace_g_due(w,d,u,e)
152#define xfs_dir_trace_g_duc(w,d,u,c)
153#endif /* DEBUG */
154
155#endif /* __XFS_DIR_SF_H__ */
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 00b1540f8108..4e7865ad6f0e 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -189,6 +189,6 @@ typedef enum {
189#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) 189#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
190 190
191 191
192extern struct bhv_vfsops xfs_dmops; 192extern struct bhv_module_vfsops xfs_dmops;
193 193
194#endif /* __XFS_DMAPI_H__ */ 194#endif /* __XFS_DMAPI_H__ */
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
index 629795b3b3d5..1e4a35ddf7f9 100644
--- a/fs/xfs/xfs_dmops.c
+++ b/fs/xfs/xfs_dmops.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
29#include "xfs_mount.h" 28#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index 2a21c5024017..b95681b03d81 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -22,12 +22,10 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir_sf.h"
31#include "xfs_dir2_sf.h" 29#include "xfs_dir2_sf.h"
32#include "xfs_attr_sf.h" 30#include "xfs_attr_sf.h"
33#include "xfs_dinode.h" 31#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index f19282ec8549..6cf6d8769b97 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_buf_item.h" 24#include "xfs_buf_item.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_dir.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_trans_priv.h" 28#include "xfs_trans_priv.h"
@@ -294,6 +293,62 @@ xfs_efi_init(xfs_mount_t *mp,
294} 293}
295 294
296/* 295/*
296 * Copy an EFI format buffer from the given buf, and into the destination
297 * EFI format structure.
298 * The given buffer can be in 32 bit or 64 bit form (which has different padding),
299 * one of which will be the native format for this kernel.
300 * It will handle the conversion of formats if necessary.
301 */
302int
303xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
304{
305 xfs_efi_log_format_t *src_efi_fmt = (xfs_efi_log_format_t *)buf->i_addr;
306 uint i;
307 uint len = sizeof(xfs_efi_log_format_t) +
308 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);
309 uint len32 = sizeof(xfs_efi_log_format_32_t) +
310 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);
311 uint len64 = sizeof(xfs_efi_log_format_64_t) +
312 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);
313
314 if (buf->i_len == len) {
315 memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
316 return 0;
317 } else if (buf->i_len == len32) {
318 xfs_efi_log_format_32_t *src_efi_fmt_32 =
319 (xfs_efi_log_format_32_t *)buf->i_addr;
320
321 dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
322 dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
323 dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
324 dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id;
325 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
326 dst_efi_fmt->efi_extents[i].ext_start =
327 src_efi_fmt_32->efi_extents[i].ext_start;
328 dst_efi_fmt->efi_extents[i].ext_len =
329 src_efi_fmt_32->efi_extents[i].ext_len;
330 }
331 return 0;
332 } else if (buf->i_len == len64) {
333 xfs_efi_log_format_64_t *src_efi_fmt_64 =
334 (xfs_efi_log_format_64_t *)buf->i_addr;
335
336 dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
337 dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
338 dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
339 dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id;
340 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
341 dst_efi_fmt->efi_extents[i].ext_start =
342 src_efi_fmt_64->efi_extents[i].ext_start;
343 dst_efi_fmt->efi_extents[i].ext_len =
344 src_efi_fmt_64->efi_extents[i].ext_len;
345 }
346 return 0;
347 }
348 return EFSCORRUPTED;
349}
350
351/*
297 * This is called by the efd item code below to release references to 352 * This is called by the efd item code below to release references to
298 * the given efi item. Each efd calls this with the number of 353 * the given efi item. Each efd calls this with the number of
299 * extents that it has logged, and when the sum of these reaches 354 * extents that it has logged, and when the sum of these reaches
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index 5bf681708fec..0ea45edaab03 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -27,6 +27,24 @@ typedef struct xfs_extent {
27} xfs_extent_t; 27} xfs_extent_t;
28 28
29/* 29/*
30 * Since an xfs_extent_t has types (start:64, len: 32)
31 * there are different alignments on 32 bit and 64 bit kernels.
32 * So we provide the different variants for use by a
33 * conversion routine.
34 */
35
36typedef struct xfs_extent_32 {
37 xfs_dfsbno_t ext_start;
38 xfs_extlen_t ext_len;
39} __attribute__((packed)) xfs_extent_32_t;
40
41typedef struct xfs_extent_64 {
42 xfs_dfsbno_t ext_start;
43 xfs_extlen_t ext_len;
44 __uint32_t ext_pad;
45} xfs_extent_64_t;
46
47/*
30 * This is the structure used to lay out an efi log item in the 48 * This is the structure used to lay out an efi log item in the
31 * log. The efi_extents field is a variable size array whose 49 * log. The efi_extents field is a variable size array whose
32 * size is given by efi_nextents. 50 * size is given by efi_nextents.
@@ -39,6 +57,22 @@ typedef struct xfs_efi_log_format {
39 xfs_extent_t efi_extents[1]; /* array of extents to free */ 57 xfs_extent_t efi_extents[1]; /* array of extents to free */
40} xfs_efi_log_format_t; 58} xfs_efi_log_format_t;
41 59
60typedef struct xfs_efi_log_format_32 {
61 unsigned short efi_type; /* efi log item type */
62 unsigned short efi_size; /* size of this item */
63 uint efi_nextents; /* # extents to free */
64 __uint64_t efi_id; /* efi identifier */
65 xfs_extent_32_t efi_extents[1]; /* array of extents to free */
66} __attribute__((packed)) xfs_efi_log_format_32_t;
67
68typedef struct xfs_efi_log_format_64 {
69 unsigned short efi_type; /* efi log item type */
70 unsigned short efi_size; /* size of this item */
71 uint efi_nextents; /* # extents to free */
72 __uint64_t efi_id; /* efi identifier */
73 xfs_extent_64_t efi_extents[1]; /* array of extents to free */
74} xfs_efi_log_format_64_t;
75
42/* 76/*
43 * This is the structure used to lay out an efd log item in the 77 * This is the structure used to lay out an efd log item in the
44 * log. The efd_extents array is a variable size array whose 78 * log. The efd_extents array is a variable size array whose
@@ -52,6 +86,22 @@ typedef struct xfs_efd_log_format {
52 xfs_extent_t efd_extents[1]; /* array of extents freed */ 86 xfs_extent_t efd_extents[1]; /* array of extents freed */
53} xfs_efd_log_format_t; 87} xfs_efd_log_format_t;
54 88
89typedef struct xfs_efd_log_format_32 {
90 unsigned short efd_type; /* efd log item type */
91 unsigned short efd_size; /* size of this item */
92 uint efd_nextents; /* # of extents freed */
93 __uint64_t efd_efi_id; /* id of corresponding efi */
94 xfs_extent_32_t efd_extents[1]; /* array of extents freed */
95} __attribute__((packed)) xfs_efd_log_format_32_t;
96
97typedef struct xfs_efd_log_format_64 {
98 unsigned short efd_type; /* efd log item type */
99 unsigned short efd_size; /* size of this item */
100 uint efd_nextents; /* # of extents freed */
101 __uint64_t efd_efi_id; /* id of corresponding efi */
102 xfs_extent_64_t efd_extents[1]; /* array of extents freed */
103} xfs_efd_log_format_64_t;
104
55 105
56#ifdef __KERNEL__ 106#ifdef __KERNEL__
57 107
@@ -103,7 +153,8 @@ extern struct kmem_zone *xfs_efd_zone;
103xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); 153xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint);
104xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, 154xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
105 uint); 155 uint);
106 156int xfs_efi_copy_format(xfs_log_iovec_t *buf,
157 xfs_efi_log_format_t *dst_efi_fmt);
107void xfs_efi_item_free(xfs_efi_log_item_t *); 158void xfs_efi_item_free(xfs_efi_log_item_t *);
108 159
109#endif /* __KERNEL__ */ 160#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 14010f1fa82f..0f0ad1535951 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -67,14 +67,15 @@ struct fsxattr {
67#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ 67#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
68#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ 68#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
69#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ 69#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
70#define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
70#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ 71#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
71 72
72/* 73/*
73 * Structure for XFS_IOC_GETBMAP. 74 * Structure for XFS_IOC_GETBMAP.
74 * On input, fill in bmv_offset and bmv_length of the first structure 75 * On input, fill in bmv_offset and bmv_length of the first structure
75 * to indicate the area of interest in the file, and bmv_entry with the 76 * to indicate the area of interest in the file, and bmv_entries with
76 * number of array elements given. The first structure is updated on 77 * the number of array elements given back. The first structure is
77 * return to give the offset and length for the next call. 78 * updated on return to give the offset and length for the next call.
78 */ 79 */
79#ifndef HAVE_GETBMAP 80#ifndef HAVE_GETBMAP
80struct getbmap { 81struct getbmap {
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index dfa3527b20a7..077629bab532 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -542,14 +540,13 @@ xfs_reserve_blocks(
542} 540}
543 541
544void 542void
545xfs_fs_log_dummy(xfs_mount_t *mp) 543xfs_fs_log_dummy(
544 xfs_mount_t *mp)
546{ 545{
547 xfs_trans_t *tp; 546 xfs_trans_t *tp;
548 xfs_inode_t *ip; 547 xfs_inode_t *ip;
549
550 548
551 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); 549 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
552 atomic_inc(&mp->m_active_trans);
553 if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) { 550 if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
554 xfs_trans_cancel(tp, 0); 551 xfs_trans_cancel(tp, 0);
555 return; 552 return;
@@ -574,21 +571,22 @@ xfs_fs_goingdown(
574{ 571{
575 switch (inflags) { 572 switch (inflags) {
576 case XFS_FSOP_GOING_FLAGS_DEFAULT: { 573 case XFS_FSOP_GOING_FLAGS_DEFAULT: {
577 struct vfs *vfsp = XFS_MTOVFS(mp); 574 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
578 struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev); 575 struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
579 576
580 if (sb && !IS_ERR(sb)) { 577 if (sb && !IS_ERR(sb)) {
581 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT); 578 xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
582 thaw_bdev(sb->s_bdev, sb); 579 thaw_bdev(sb->s_bdev, sb);
583 } 580 }
584 581
585 break; 582 break;
586 } 583 }
587 case XFS_FSOP_GOING_FLAGS_LOGFLUSH: 584 case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
588 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT); 585 xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
589 break; 586 break;
590 case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH: 587 case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH:
591 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT|XFS_LOG_IO_ERROR); 588 xfs_force_shutdown(mp,
589 SHUTDOWN_FORCE_UMOUNT | SHUTDOWN_LOG_IO_ERROR);
592 break; 590 break;
593 default: 591 default:
594 return XFS_ERROR(EINVAL); 592 return XFS_ERROR(EINVAL);
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index deddbd03c166..33164a85aa9d 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -1174,6 +1172,9 @@ xfs_dilocate(
1174 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || 1172 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
1175 ino != XFS_AGINO_TO_INO(mp, agno, agino)) { 1173 ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
1176#ifdef DEBUG 1174#ifdef DEBUG
1175 /* no diagnostics for bulkstat, ino comes from userspace */
1176 if (flags & XFS_IMAP_BULKSTAT)
1177 return XFS_ERROR(EINVAL);
1177 if (agno >= mp->m_sb.sb_agcount) { 1178 if (agno >= mp->m_sb.sb_agcount) {
1178 xfs_fs_cmn_err(CE_ALERT, mp, 1179 xfs_fs_cmn_err(CE_ALERT, mp,
1179 "xfs_dilocate: agno (%d) >= " 1180 "xfs_dilocate: agno (%d) >= "
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 60c65683462d..616eeeb6953e 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index b53854325266..0724df7fabb7 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -186,7 +184,7 @@ xfs_ihash_promote(
186 */ 184 */
187STATIC int 185STATIC int
188xfs_iget_core( 186xfs_iget_core(
189 vnode_t *vp, 187 bhv_vnode_t *vp,
190 xfs_mount_t *mp, 188 xfs_mount_t *mp,
191 xfs_trans_t *tp, 189 xfs_trans_t *tp,
192 xfs_ino_t ino, 190 xfs_ino_t ino,
@@ -198,7 +196,7 @@ xfs_iget_core(
198 xfs_ihash_t *ih; 196 xfs_ihash_t *ih;
199 xfs_inode_t *ip; 197 xfs_inode_t *ip;
200 xfs_inode_t *iq; 198 xfs_inode_t *iq;
201 vnode_t *inode_vp; 199 bhv_vnode_t *inode_vp;
202 ulong version; 200 ulong version;
203 int error; 201 int error;
204 /* REFERENCED */ 202 /* REFERENCED */
@@ -468,7 +466,7 @@ finish_inode:
468 * If we have a real type for an on-disk inode, we can set ops(&unlock) 466 * If we have a real type for an on-disk inode, we can set ops(&unlock)
469 * now. If it's a new inode being created, xfs_ialloc will handle it. 467 * now. If it's a new inode being created, xfs_ialloc will handle it.
470 */ 468 */
471 VFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1); 469 bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
472 470
473 return 0; 471 return 0;
474} 472}
@@ -489,7 +487,7 @@ xfs_iget(
489 xfs_daddr_t bno) 487 xfs_daddr_t bno)
490{ 488{
491 struct inode *inode; 489 struct inode *inode;
492 vnode_t *vp = NULL; 490 bhv_vnode_t *vp = NULL;
493 int error; 491 int error;
494 492
495 XFS_STATS_INC(xs_ig_attempts); 493 XFS_STATS_INC(xs_ig_attempts);
@@ -543,7 +541,7 @@ retry:
543void 541void
544xfs_inode_lock_init( 542xfs_inode_lock_init(
545 xfs_inode_t *ip, 543 xfs_inode_t *ip,
546 vnode_t *vp) 544 bhv_vnode_t *vp)
547{ 545{
548 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, 546 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
549 "xfsino", (long)vp->v_number); 547 "xfsino", (long)vp->v_number);
@@ -603,12 +601,10 @@ void
603xfs_iput(xfs_inode_t *ip, 601xfs_iput(xfs_inode_t *ip,
604 uint lock_flags) 602 uint lock_flags)
605{ 603{
606 vnode_t *vp = XFS_ITOV(ip); 604 bhv_vnode_t *vp = XFS_ITOV(ip);
607 605
608 vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address); 606 vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address);
609
610 xfs_iunlock(ip, lock_flags); 607 xfs_iunlock(ip, lock_flags);
611
612 VN_RELE(vp); 608 VN_RELE(vp);
613} 609}
614 610
@@ -619,7 +615,7 @@ void
619xfs_iput_new(xfs_inode_t *ip, 615xfs_iput_new(xfs_inode_t *ip,
620 uint lock_flags) 616 uint lock_flags)
621{ 617{
622 vnode_t *vp = XFS_ITOV(ip); 618 bhv_vnode_t *vp = XFS_ITOV(ip);
623 struct inode *inode = vn_to_inode(vp); 619 struct inode *inode = vn_to_inode(vp);
624 620
625 vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); 621 vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
@@ -645,7 +641,7 @@ xfs_iput_new(xfs_inode_t *ip,
645void 641void
646xfs_ireclaim(xfs_inode_t *ip) 642xfs_ireclaim(xfs_inode_t *ip)
647{ 643{
648 vnode_t *vp; 644 bhv_vnode_t *vp;
649 645
650 /* 646 /*
651 * Remove from old hash list and mount list. 647 * Remove from old hash list and mount list.
@@ -1033,6 +1029,6 @@ xfs_iflock_nowait(xfs_inode_t *ip)
1033void 1029void
1034xfs_ifunlock(xfs_inode_t *ip) 1030xfs_ifunlock(xfs_inode_t *ip)
1035{ 1031{
1036 ASSERT(valusema(&(ip->i_flock)) <= 0); 1032 ASSERT(issemalocked(&(ip->i_flock)));
1037 vsema(&(ip->i_flock)); 1033 vsema(&(ip->i_flock));
1038} 1034}
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 94b60dd03801..5fa0adb7e173 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -26,14 +26,12 @@
26#include "xfs_trans_priv.h" 26#include "xfs_trans_priv.h"
27#include "xfs_sb.h" 27#include "xfs_sb.h"
28#include "xfs_ag.h" 28#include "xfs_ag.h"
29#include "xfs_dir.h"
30#include "xfs_dir2.h" 29#include "xfs_dir2.h"
31#include "xfs_dmapi.h" 30#include "xfs_dmapi.h"
32#include "xfs_mount.h" 31#include "xfs_mount.h"
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -256,13 +254,11 @@ xfs_itobp(
256 xfs_daddr_t bno, 254 xfs_daddr_t bno,
257 uint imap_flags) 255 uint imap_flags)
258{ 256{
257 xfs_imap_t imap;
259 xfs_buf_t *bp; 258 xfs_buf_t *bp;
260 int error; 259 int error;
261 xfs_imap_t imap;
262#ifdef __KERNEL__
263 int i; 260 int i;
264 int ni; 261 int ni;
265#endif
266 262
267 if (ip->i_blkno == (xfs_daddr_t)0) { 263 if (ip->i_blkno == (xfs_daddr_t)0) {
268 /* 264 /*
@@ -319,7 +315,6 @@ xfs_itobp(
319 */ 315 */
320 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno, 316 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno,
321 (int)imap.im_len, XFS_BUF_LOCK, &bp); 317 (int)imap.im_len, XFS_BUF_LOCK, &bp);
322
323 if (error) { 318 if (error) {
324#ifdef DEBUG 319#ifdef DEBUG
325 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: " 320 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: "
@@ -330,17 +325,21 @@ xfs_itobp(
330#endif /* DEBUG */ 325#endif /* DEBUG */
331 return error; 326 return error;
332 } 327 }
333#ifdef __KERNEL__ 328
334 /* 329 /*
335 * Validate the magic number and version of every inode in the buffer 330 * Validate the magic number and version of every inode in the buffer
336 * (if DEBUG kernel) or the first inode in the buffer, otherwise. 331 * (if DEBUG kernel) or the first inode in the buffer, otherwise.
332 * No validation is done here in userspace (xfs_repair).
337 */ 333 */
338#ifdef DEBUG 334#if !defined(__KERNEL__)
335 ni = 0;
336#elif defined(DEBUG)
339 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 337 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 :
340 (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog); 338 (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog);
341#else 339#else /* usual case */
342 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1; 340 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1;
343#endif 341#endif
342
344 for (i = 0; i < ni; i++) { 343 for (i = 0; i < ni; i++) {
345 int di_ok; 344 int di_ok;
346 xfs_dinode_t *dip; 345 xfs_dinode_t *dip;
@@ -352,8 +351,11 @@ xfs_itobp(
352 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, 351 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
353 XFS_RANDOM_ITOBP_INOTOBP))) { 352 XFS_RANDOM_ITOBP_INOTOBP))) {
354#ifdef DEBUG 353#ifdef DEBUG
355 prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)", 354 if (!(imap_flags & XFS_IMAP_BULKSTAT))
356 mp->m_ddev_targp, 355 cmn_err(CE_ALERT,
356 "Device %s - bad inode magic/vsn "
357 "daddr %lld #%d (magic=%x)",
358 XFS_BUFTARG_NAME(mp->m_ddev_targp),
357 (unsigned long long)imap.im_blkno, i, 359 (unsigned long long)imap.im_blkno, i,
358 INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); 360 INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
359#endif 361#endif
@@ -363,7 +365,6 @@ xfs_itobp(
363 return XFS_ERROR(EFSCORRUPTED); 365 return XFS_ERROR(EFSCORRUPTED);
364 } 366 }
365 } 367 }
366#endif /* __KERNEL__ */
367 368
368 xfs_inobp_check(mp, bp); 369 xfs_inobp_check(mp, bp);
369 370
@@ -782,7 +783,6 @@ xfs_xlate_dinode_core(
782 783
783STATIC uint 784STATIC uint
784_xfs_dic2xflags( 785_xfs_dic2xflags(
785 xfs_dinode_core_t *dic,
786 __uint16_t di_flags) 786 __uint16_t di_flags)
787{ 787{
788 uint flags = 0; 788 uint flags = 0;
@@ -812,6 +812,8 @@ _xfs_dic2xflags(
812 flags |= XFS_XFLAG_EXTSIZE; 812 flags |= XFS_XFLAG_EXTSIZE;
813 if (di_flags & XFS_DIFLAG_EXTSZINHERIT) 813 if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
814 flags |= XFS_XFLAG_EXTSZINHERIT; 814 flags |= XFS_XFLAG_EXTSZINHERIT;
815 if (di_flags & XFS_DIFLAG_NODEFRAG)
816 flags |= XFS_XFLAG_NODEFRAG;
815 } 817 }
816 818
817 return flags; 819 return flags;
@@ -823,16 +825,16 @@ xfs_ip2xflags(
823{ 825{
824 xfs_dinode_core_t *dic = &ip->i_d; 826 xfs_dinode_core_t *dic = &ip->i_d;
825 827
826 return _xfs_dic2xflags(dic, dic->di_flags) | 828 return _xfs_dic2xflags(dic->di_flags) |
827 (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); 829 (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
828} 830}
829 831
830uint 832uint
831xfs_dic2xflags( 833xfs_dic2xflags(
832 xfs_dinode_core_t *dic) 834 xfs_dinode_core_t *dic)
833{ 835{
834 return _xfs_dic2xflags(dic, INT_GET(dic->di_flags, ARCH_CONVERT)) | 836 return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) |
835 (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); 837 (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
836} 838}
837 839
838/* 840/*
@@ -1083,7 +1085,7 @@ xfs_ialloc(
1083{ 1085{
1084 xfs_ino_t ino; 1086 xfs_ino_t ino;
1085 xfs_inode_t *ip; 1087 xfs_inode_t *ip;
1086 vnode_t *vp; 1088 bhv_vnode_t *vp;
1087 uint flags; 1089 uint flags;
1088 int error; 1090 int error;
1089 1091
@@ -1221,6 +1223,9 @@ xfs_ialloc(
1221 di_flags |= XFS_DIFLAG_NOSYMLINKS; 1223 di_flags |= XFS_DIFLAG_NOSYMLINKS;
1222 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) 1224 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1223 di_flags |= XFS_DIFLAG_PROJINHERIT; 1225 di_flags |= XFS_DIFLAG_PROJINHERIT;
1226 if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) &&
1227 xfs_inherit_nodefrag)
1228 di_flags |= XFS_DIFLAG_NODEFRAG;
1224 ip->i_d.di_flags |= di_flags; 1229 ip->i_d.di_flags |= di_flags;
1225 } 1230 }
1226 /* FALLTHROUGH */ 1231 /* FALLTHROUGH */
@@ -1244,8 +1249,8 @@ xfs_ialloc(
1244 */ 1249 */
1245 xfs_trans_log_inode(tp, ip, flags); 1250 xfs_trans_log_inode(tp, ip, flags);
1246 1251
1247 /* now that we have an i_mode we can set Linux inode ops (& unlock) */ 1252 /* now that we have an i_mode we can setup inode ops and unlock */
1248 VFS_INIT_VNODE(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1); 1253 bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
1249 1254
1250 *ipp = ip; 1255 *ipp = ip;
1251 return 0; 1256 return 0;
@@ -1285,7 +1290,7 @@ xfs_isize_check(
1285 (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) - 1290 (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
1286 map_first), 1291 map_first),
1287 XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps, 1292 XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
1288 NULL)) 1293 NULL, NULL))
1289 return; 1294 return;
1290 ASSERT(nimaps == 1); 1295 ASSERT(nimaps == 1);
1291 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK); 1296 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
@@ -1421,7 +1426,7 @@ xfs_itruncate_start(
1421 xfs_fsize_t last_byte; 1426 xfs_fsize_t last_byte;
1422 xfs_off_t toss_start; 1427 xfs_off_t toss_start;
1423 xfs_mount_t *mp; 1428 xfs_mount_t *mp;
1424 vnode_t *vp; 1429 bhv_vnode_t *vp;
1425 1430
1426 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); 1431 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
1427 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); 1432 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
@@ -1434,9 +1439,9 @@ xfs_itruncate_start(
1434 vn_iowait(vp); /* wait for the completion of any pending DIOs */ 1439 vn_iowait(vp); /* wait for the completion of any pending DIOs */
1435 1440
1436 /* 1441 /*
1437 * Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers 1442 * Call toss_pages or flushinval_pages to get rid of pages
1438 * overlapping the region being removed. We have to use 1443 * overlapping the region being removed. We have to use
1439 * the less efficient VOP_FLUSHINVAL_PAGES() in the case that the 1444 * the less efficient flushinval_pages in the case that the
1440 * caller may not be able to finish the truncate without 1445 * caller may not be able to finish the truncate without
1441 * dropping the inode's I/O lock. Make sure 1446 * dropping the inode's I/O lock. Make sure
1442 * to catch any pages brought in by buffers overlapping 1447 * to catch any pages brought in by buffers overlapping
@@ -1445,10 +1450,10 @@ xfs_itruncate_start(
1445 * so that we don't toss things on the same block as 1450 * so that we don't toss things on the same block as
1446 * new_size but before it. 1451 * new_size but before it.
1447 * 1452 *
1448 * Before calling VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES(), make sure to 1453 * Before calling toss_page or flushinval_pages, make sure to
1449 * call remapf() over the same region if the file is mapped. 1454 * call remapf() over the same region if the file is mapped.
1450 * This frees up mapped file references to the pages in the 1455 * This frees up mapped file references to the pages in the
1451 * given range and for the VOP_FLUSHINVAL_PAGES() case it ensures 1456 * given range and for the flushinval_pages case it ensures
1452 * that we get the latest mapped changes flushed out. 1457 * that we get the latest mapped changes flushed out.
1453 */ 1458 */
1454 toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); 1459 toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
@@ -1466,9 +1471,9 @@ xfs_itruncate_start(
1466 last_byte); 1471 last_byte);
1467 if (last_byte > toss_start) { 1472 if (last_byte > toss_start) {
1468 if (flags & XFS_ITRUNC_DEFINITE) { 1473 if (flags & XFS_ITRUNC_DEFINITE) {
1469 VOP_TOSS_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED); 1474 bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
1470 } else { 1475 } else {
1471 VOP_FLUSHINVAL_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED); 1476 bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
1472 } 1477 }
1473 } 1478 }
1474 1479
@@ -1666,12 +1671,13 @@ xfs_itruncate_finish(
1666 * runs. 1671 * runs.
1667 */ 1672 */
1668 XFS_BMAP_INIT(&free_list, &first_block); 1673 XFS_BMAP_INIT(&free_list, &first_block);
1669 error = xfs_bunmapi(ntp, ip, first_unmap_block, 1674 error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore,
1670 unmap_len, 1675 first_unmap_block, unmap_len,
1671 XFS_BMAPI_AFLAG(fork) | 1676 XFS_BMAPI_AFLAG(fork) |
1672 (sync ? 0 : XFS_BMAPI_ASYNC), 1677 (sync ? 0 : XFS_BMAPI_ASYNC),
1673 XFS_ITRUNC_MAX_EXTENTS, 1678 XFS_ITRUNC_MAX_EXTENTS,
1674 &first_block, &free_list, &done); 1679 &first_block, &free_list,
1680 NULL, &done);
1675 if (error) { 1681 if (error) {
1676 /* 1682 /*
1677 * If the bunmapi call encounters an error, 1683 * If the bunmapi call encounters an error,
@@ -2745,13 +2751,14 @@ xfs_iunpin(
2745 * the inode to become unpinned. 2751 * the inode to become unpinned.
2746 */ 2752 */
2747 if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { 2753 if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
2748 vnode_t *vp = XFS_ITOV_NULL(ip); 2754 bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
2749 2755
2750 /* make sync come back and flush this inode */ 2756 /* make sync come back and flush this inode */
2751 if (vp) { 2757 if (vp) {
2752 struct inode *inode = vn_to_inode(vp); 2758 struct inode *inode = vn_to_inode(vp);
2753 2759
2754 if (!(inode->i_state & I_NEW)) 2760 if (!(inode->i_state &
2761 (I_NEW|I_FREEING|I_CLEAR)))
2755 mark_inode_dirty_sync(inode); 2762 mark_inode_dirty_sync(inode);
2756 } 2763 }
2757 } 2764 }
@@ -2916,13 +2923,6 @@ xfs_iflush_fork(
2916 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); 2923 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
2917 memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); 2924 memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
2918 } 2925 }
2919 if (whichfork == XFS_DATA_FORK) {
2920 if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) {
2921 XFS_ERROR_REPORT("xfs_iflush_fork",
2922 XFS_ERRLEVEL_LOW, mp);
2923 return XFS_ERROR(EFSCORRUPTED);
2924 }
2925 }
2926 break; 2926 break;
2927 2927
2928 case XFS_DINODE_FMT_EXTENTS: 2928 case XFS_DINODE_FMT_EXTENTS:
@@ -3006,7 +3006,7 @@ xfs_iflush(
3006 XFS_STATS_INC(xs_iflush_count); 3006 XFS_STATS_INC(xs_iflush_count);
3007 3007
3008 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); 3008 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
3009 ASSERT(valusema(&ip->i_flock) <= 0); 3009 ASSERT(issemalocked(&(ip->i_flock)));
3010 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 3010 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
3011 ip->i_d.di_nextents > ip->i_df.if_ext_max); 3011 ip->i_d.di_nextents > ip->i_df.if_ext_max);
3012 3012
@@ -3199,7 +3199,7 @@ xfs_iflush(
3199 3199
3200corrupt_out: 3200corrupt_out:
3201 xfs_buf_relse(bp); 3201 xfs_buf_relse(bp);
3202 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 3202 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
3203 xfs_iflush_abort(ip); 3203 xfs_iflush_abort(ip);
3204 /* 3204 /*
3205 * Unlocks the flush lock 3205 * Unlocks the flush lock
@@ -3221,7 +3221,7 @@ cluster_corrupt_out:
3221 xfs_buf_relse(bp); 3221 xfs_buf_relse(bp);
3222 } 3222 }
3223 3223
3224 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 3224 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
3225 3225
3226 if(!bufwasdelwri) { 3226 if(!bufwasdelwri) {
3227 /* 3227 /*
@@ -3264,7 +3264,7 @@ xfs_iflush_int(
3264 SPLDECL(s); 3264 SPLDECL(s);
3265 3265
3266 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); 3266 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
3267 ASSERT(valusema(&ip->i_flock) <= 0); 3267 ASSERT(issemalocked(&(ip->i_flock)));
3268 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 3268 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
3269 ip->i_d.di_nextents > ip->i_df.if_ext_max); 3269 ip->i_d.di_nextents > ip->i_df.if_ext_max);
3270 3270
@@ -3504,7 +3504,7 @@ xfs_iflush_all(
3504 xfs_mount_t *mp) 3504 xfs_mount_t *mp)
3505{ 3505{
3506 xfs_inode_t *ip; 3506 xfs_inode_t *ip;
3507 vnode_t *vp; 3507 bhv_vnode_t *vp;
3508 3508
3509 again: 3509 again:
3510 XFS_MOUNT_ILOCK(mp); 3510 XFS_MOUNT_ILOCK(mp);
@@ -4180,7 +4180,7 @@ xfs_iext_direct_to_inline(
4180 */ 4180 */
4181 memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, 4181 memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
4182 nextents * sizeof(xfs_bmbt_rec_t)); 4182 nextents * sizeof(xfs_bmbt_rec_t));
4183 kmem_free(ifp->if_u1.if_extents, KM_SLEEP); 4183 kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
4184 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; 4184 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
4185 ifp->if_real_bytes = 0; 4185 ifp->if_real_bytes = 0;
4186} 4186}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 3b544db1790b..d10b76ed1e5b 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -102,9 +102,9 @@ typedef struct xfs_ifork {
102 102
103#ifdef __KERNEL__ 103#ifdef __KERNEL__
104struct bhv_desc; 104struct bhv_desc;
105struct bhv_vnode;
105struct cred; 106struct cred;
106struct ktrace; 107struct ktrace;
107struct vnode;
108struct xfs_buf; 108struct xfs_buf;
109struct xfs_bmap_free; 109struct xfs_bmap_free;
110struct xfs_bmbt_irec; 110struct xfs_bmbt_irec;
@@ -400,7 +400,7 @@ void xfs_chash_init(struct xfs_mount *);
400void xfs_chash_free(struct xfs_mount *); 400void xfs_chash_free(struct xfs_mount *);
401xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, 401xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
402 struct xfs_trans *); 402 struct xfs_trans *);
403void xfs_inode_lock_init(xfs_inode_t *, struct vnode *); 403void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *);
404int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, 404int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
405 uint, uint, xfs_inode_t **, xfs_daddr_t); 405 uint, uint, xfs_inode_t **, xfs_daddr_t);
406void xfs_iput(xfs_inode_t *, uint); 406void xfs_iput(xfs_inode_t *, uint);
@@ -461,7 +461,7 @@ void xfs_ichgtime(xfs_inode_t *, int);
461xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); 461xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
462void xfs_lock_inodes(xfs_inode_t **, int, int, uint); 462void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
463 463
464xfs_inode_t *xfs_vtoi(struct vnode *vp); 464xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp);
465 465
466void xfs_synchronize_atime(xfs_inode_t *); 466void xfs_synchronize_atime(xfs_inode_t *);
467 467
@@ -509,7 +509,6 @@ extern struct kmem_zone *xfs_chashlist_zone;
509extern struct kmem_zone *xfs_ifork_zone; 509extern struct kmem_zone *xfs_ifork_zone;
510extern struct kmem_zone *xfs_inode_zone; 510extern struct kmem_zone *xfs_inode_zone;
511extern struct kmem_zone *xfs_ili_zone; 511extern struct kmem_zone *xfs_ili_zone;
512extern struct vnodeops xfs_vnodeops;
513 512
514#endif /* __KERNEL__ */ 513#endif /* __KERNEL__ */
515 514
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 7497a481b2f5..f8e80d8e7237 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -25,7 +25,6 @@
25#include "xfs_buf_item.h" 25#include "xfs_buf_item.h"
26#include "xfs_sb.h" 26#include "xfs_sb.h"
27#include "xfs_ag.h" 27#include "xfs_ag.h"
28#include "xfs_dir.h"
29#include "xfs_dir2.h" 28#include "xfs_dir2.h"
30#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
31#include "xfs_mount.h" 30#include "xfs_mount.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -794,7 +792,7 @@ xfs_inode_item_pushbuf(
794 * inode flush completed and the inode was taken off the AIL. 792 * inode flush completed and the inode was taken off the AIL.
795 * So, just get out. 793 * So, just get out.
796 */ 794 */
797 if ((valusema(&(ip->i_flock)) > 0) || 795 if (!issemalocked(&(ip->i_flock)) ||
798 ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) { 796 ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) {
799 iip->ili_pushbuf_flag = 0; 797 iip->ili_pushbuf_flag = 0;
800 xfs_iunlock(ip, XFS_ILOCK_SHARED); 798 xfs_iunlock(ip, XFS_ILOCK_SHARED);
@@ -816,7 +814,7 @@ xfs_inode_item_pushbuf(
816 * If not, we can flush it async. 814 * If not, we can flush it async.
817 */ 815 */
818 dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) && 816 dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) &&
819 (valusema(&(ip->i_flock)) <= 0)); 817 issemalocked(&(ip->i_flock)));
820 iip->ili_pushbuf_flag = 0; 818 iip->ili_pushbuf_flag = 0;
821 xfs_iunlock(ip, XFS_ILOCK_SHARED); 819 xfs_iunlock(ip, XFS_ILOCK_SHARED);
822 xfs_buftrace("INODE ITEM PUSH", bp); 820 xfs_buftrace("INODE ITEM PUSH", bp);
@@ -864,7 +862,7 @@ xfs_inode_item_push(
864 ip = iip->ili_inode; 862 ip = iip->ili_inode;
865 863
866 ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS)); 864 ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS));
867 ASSERT(valusema(&(ip->i_flock)) <= 0); 865 ASSERT(issemalocked(&(ip->i_flock)));
868 /* 866 /*
869 * Since we were able to lock the inode's flush lock and 867 * Since we were able to lock the inode's flush lock and
870 * we found it on the AIL, the inode must be dirty. This 868 * we found it on the AIL, the inode must be dirty. This
@@ -1084,3 +1082,52 @@ xfs_istale_done(
1084{ 1082{
1085 xfs_iflush_abort(iip->ili_inode); 1083 xfs_iflush_abort(iip->ili_inode);
1086} 1084}
1085
1086/*
1087 * convert an xfs_inode_log_format struct from either 32 or 64 bit versions
1088 * (which can have different field alignments) to the native version
1089 */
1090int
1091xfs_inode_item_format_convert(
1092 xfs_log_iovec_t *buf,
1093 xfs_inode_log_format_t *in_f)
1094{
1095 if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) {
1096 xfs_inode_log_format_32_t *in_f32;
1097
1098 in_f32 = (xfs_inode_log_format_32_t *)buf->i_addr;
1099 in_f->ilf_type = in_f32->ilf_type;
1100 in_f->ilf_size = in_f32->ilf_size;
1101 in_f->ilf_fields = in_f32->ilf_fields;
1102 in_f->ilf_asize = in_f32->ilf_asize;
1103 in_f->ilf_dsize = in_f32->ilf_dsize;
1104 in_f->ilf_ino = in_f32->ilf_ino;
1105 /* copy biggest field of ilf_u */
1106 memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
1107 in_f32->ilf_u.ilfu_uuid.__u_bits,
1108 sizeof(uuid_t));
1109 in_f->ilf_blkno = in_f32->ilf_blkno;
1110 in_f->ilf_len = in_f32->ilf_len;
1111 in_f->ilf_boffset = in_f32->ilf_boffset;
1112 return 0;
1113 } else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){
1114 xfs_inode_log_format_64_t *in_f64;
1115
1116 in_f64 = (xfs_inode_log_format_64_t *)buf->i_addr;
1117 in_f->ilf_type = in_f64->ilf_type;
1118 in_f->ilf_size = in_f64->ilf_size;
1119 in_f->ilf_fields = in_f64->ilf_fields;
1120 in_f->ilf_asize = in_f64->ilf_asize;
1121 in_f->ilf_dsize = in_f64->ilf_dsize;
1122 in_f->ilf_ino = in_f64->ilf_ino;
1123 /* copy biggest field of ilf_u */
1124 memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
1125 in_f64->ilf_u.ilfu_uuid.__u_bits,
1126 sizeof(uuid_t));
1127 in_f->ilf_blkno = in_f64->ilf_blkno;
1128 in_f->ilf_len = in_f64->ilf_len;
1129 in_f->ilf_boffset = in_f64->ilf_boffset;
1130 return 0;
1131 }
1132 return EFSCORRUPTED;
1133}
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index c5dbf93b6661..5db6cd1b4cf3 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -23,25 +23,6 @@
23 * log. The size of the inline data/extents/b-tree root to be logged 23 * log. The size of the inline data/extents/b-tree root to be logged
24 * (if any) is indicated in the ilf_dsize field. Changes to this structure 24 * (if any) is indicated in the ilf_dsize field. Changes to this structure
25 * must be added on to the end. 25 * must be added on to the end.
26 *
27 * Convention for naming inode log item versions : The current version
28 * is always named XFS_LI_INODE. When an inode log item gets superseded,
29 * add the latest version of IRIX that will generate logs with that item
30 * to the version name.
31 *
32 * -Version 1 of this structure (XFS_LI_5_3_INODE) included up to the first
33 * union (ilf_u) field. This was released with IRIX 5.3-XFS.
34 * -Version 2 of this structure (XFS_LI_6_1_INODE) is currently the entire
35 * structure. This was released with IRIX 6.0.1-XFS and IRIX 6.1.
36 * -Version 3 of this structure (XFS_LI_INODE) is the same as version 2
37 * so a new structure definition wasn't necessary. However, we had
38 * to add a new type because the inode cluster size changed from 4K
39 * to 8K and the version number had to be rev'ved to keep older kernels
40 * from trying to recover logs with the 8K buffers in them. The logging
41 * code can handle recovery on different-sized clusters now so hopefully
42 * this'll be the last time we need to change the inode log item just
43 * for a change in the inode cluster size. This new version was
44 * released with IRIX 6.2.
45 */ 26 */
46typedef struct xfs_inode_log_format { 27typedef struct xfs_inode_log_format {
47 unsigned short ilf_type; /* inode log item type */ 28 unsigned short ilf_type; /* inode log item type */
@@ -59,18 +40,38 @@ typedef struct xfs_inode_log_format {
59 int ilf_boffset; /* off of inode in buffer */ 40 int ilf_boffset; /* off of inode in buffer */
60} xfs_inode_log_format_t; 41} xfs_inode_log_format_t;
61 42
62/* Initial version shipped with IRIX 5.3-XFS */ 43typedef struct xfs_inode_log_format_32 {
63typedef struct xfs_inode_log_format_v1 { 44 unsigned short ilf_type; /* 16: inode log item type */
64 unsigned short ilf_type; /* inode log item type */ 45 unsigned short ilf_size; /* 16: size of this item */
65 unsigned short ilf_size; /* size of this item */ 46 uint ilf_fields; /* 32: flags for fields logged */
66 uint ilf_fields; /* flags for fields logged */ 47 ushort ilf_asize; /* 32: size of attr d/ext/root */
67 uint ilf_dsize; /* size of data/ext/root */ 48 ushort ilf_dsize; /* 32: size of data/ext/root */
68 xfs_ino_t ilf_ino; /* inode number */ 49 xfs_ino_t ilf_ino; /* 64: inode number */
69 union { 50 union {
70 xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/ 51 xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
71 uuid_t ilfu_uuid; /* mount point value */ 52 uuid_t ilfu_uuid; /* 128: mount point value */
53 } ilf_u;
54 __int64_t ilf_blkno; /* 64: blkno of inode buffer */
55 int ilf_len; /* 32: len of inode buffer */
56 int ilf_boffset; /* 32: off of inode in buffer */
57} __attribute__((packed)) xfs_inode_log_format_32_t;
58
59typedef struct xfs_inode_log_format_64 {
60 unsigned short ilf_type; /* 16: inode log item type */
61 unsigned short ilf_size; /* 16: size of this item */
62 uint ilf_fields; /* 32: flags for fields logged */
63 ushort ilf_asize; /* 32: size of attr d/ext/root */
64 ushort ilf_dsize; /* 32: size of data/ext/root */
65 __uint32_t ilf_pad; /* 32: pad for 64 bit boundary */
66 xfs_ino_t ilf_ino; /* 64: inode number */
67 union {
68 xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
69 uuid_t ilfu_uuid; /* 128: mount point value */
72 } ilf_u; 70 } ilf_u;
73} xfs_inode_log_format_t_v1; 71 __int64_t ilf_blkno; /* 64: blkno of inode buffer */
72 int ilf_len; /* 32: len of inode buffer */
73 int ilf_boffset; /* 32: off of inode in buffer */
74} xfs_inode_log_format_64_t;
74 75
75/* 76/*
76 * Flags for xfs_trans_log_inode flags field. 77 * Flags for xfs_trans_log_inode flags field.
@@ -172,6 +173,8 @@ extern void xfs_inode_item_destroy(struct xfs_inode *);
172extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *); 173extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
173extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *); 174extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
174extern void xfs_iflush_abort(struct xfs_inode *); 175extern void xfs_iflush_abort(struct xfs_inode *);
176extern int xfs_inode_item_format_convert(xfs_log_iovec_t *,
177 xfs_inode_log_format_t *);
175 178
176#endif /* __KERNEL__ */ 179#endif /* __KERNEL__ */
177 180
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index a07815661a8c..06d710c9ce4b 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -24,14 +24,13 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
28#include "xfs_dfrag.h"
29#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
30#include "xfs_mount.h" 30#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -58,7 +57,7 @@ xfs_size_fn(
58 57
59STATIC int 58STATIC int
60xfs_ioinit( 59xfs_ioinit(
61 struct vfs *vfsp, 60 struct bhv_vfs *vfsp,
62 struct xfs_mount_args *mntargs, 61 struct xfs_mount_args *mntargs,
63 int flags) 62 int flags)
64{ 63{
@@ -68,6 +67,7 @@ xfs_ioinit(
68xfs_ioops_t xfs_iocore_xfs = { 67xfs_ioops_t xfs_iocore_xfs = {
69 .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit, 68 .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit,
70 .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi, 69 .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi,
70 .xfs_bunmapi_func = (xfs_bunmapi_t) xfs_bunmapi,
71 .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof, 71 .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof,
72 .xfs_iomap_write_direct = 72 .xfs_iomap_write_direct =
73 (xfs_iomap_write_direct_t) xfs_iomap_write_direct, 73 (xfs_iomap_write_direct_t) xfs_iomap_write_direct,
@@ -84,6 +84,7 @@ xfs_ioops_t xfs_iocore_xfs = {
84 .xfs_unlock = (xfs_unlk_t) xfs_iunlock, 84 .xfs_unlock = (xfs_unlk_t) xfs_iunlock,
85 .xfs_size_func = (xfs_size_t) xfs_size_fn, 85 .xfs_size_func = (xfs_size_t) xfs_size_fn,
86 .xfs_iodone = (xfs_iodone_t) fs_noerr, 86 .xfs_iodone = (xfs_iodone_t) fs_noerr,
87 .xfs_swap_extents_func = (xfs_swap_extents_t) xfs_swap_extents,
87}; 88};
88 89
89void 90void
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index d5dfedcb8922..f1949c16df15 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -252,7 +250,7 @@ xfs_iomap(
252 error = XFS_BMAPI(mp, NULL, io, offset_fsb, 250 error = XFS_BMAPI(mp, NULL, io, offset_fsb,
253 (xfs_filblks_t)(end_fsb - offset_fsb), 251 (xfs_filblks_t)(end_fsb - offset_fsb),
254 bmapi_flags, NULL, 0, &imap, 252 bmapi_flags, NULL, 0, &imap,
255 &nimaps, NULL); 253 &nimaps, NULL, NULL);
256 254
257 if (error) 255 if (error)
258 goto out; 256 goto out;
@@ -519,8 +517,8 @@ xfs_iomap_write_direct(
519 */ 517 */
520 XFS_BMAP_INIT(&free_list, &firstfsb); 518 XFS_BMAP_INIT(&free_list, &firstfsb);
521 nimaps = 1; 519 nimaps = 1;
522 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 520 error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag,
523 bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list); 521 &firstfsb, 0, &imap, &nimaps, &free_list, NULL);
524 if (error) 522 if (error)
525 goto error0; 523 goto error0;
526 524
@@ -610,8 +608,8 @@ xfs_iomap_eof_want_preallocate(
610 while (count_fsb > 0) { 608 while (count_fsb > 0) {
611 imaps = nimaps; 609 imaps = nimaps;
612 firstblock = NULLFSBLOCK; 610 firstblock = NULLFSBLOCK;
613 error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 611 error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0,
614 0, &firstblock, 0, imap, &imaps, NULL); 612 &firstblock, 0, imap, &imaps, NULL, NULL);
615 if (error) 613 if (error)
616 return error; 614 return error;
617 for (n = 0; n < imaps; n++) { 615 for (n = 0; n < imaps; n++) {
@@ -695,11 +693,11 @@ retry:
695 693
696 nimaps = XFS_WRITE_IMAPS; 694 nimaps = XFS_WRITE_IMAPS;
697 firstblock = NULLFSBLOCK; 695 firstblock = NULLFSBLOCK;
698 error = xfs_bmapi(NULL, ip, offset_fsb, 696 error = XFS_BMAPI(mp, NULL, io, offset_fsb,
699 (xfs_filblks_t)(last_fsb - offset_fsb), 697 (xfs_filblks_t)(last_fsb - offset_fsb),
700 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | 698 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
701 XFS_BMAPI_ENTIRE, &firstblock, 1, imap, 699 XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
702 &nimaps, NULL); 700 &nimaps, NULL, NULL);
703 if (error && (error != ENOSPC)) 701 if (error && (error != ENOSPC))
704 return XFS_ERROR(error); 702 return XFS_ERROR(error);
705 703
@@ -832,9 +830,9 @@ xfs_iomap_write_allocate(
832 } 830 }
833 831
834 /* Go get the actual blocks */ 832 /* Go get the actual blocks */
835 error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, 833 error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb,
836 XFS_BMAPI_WRITE, &first_block, 1, 834 XFS_BMAPI_WRITE, &first_block, 1,
837 imap, &nimaps, &free_list); 835 imap, &nimaps, &free_list, NULL);
838 if (error) 836 if (error)
839 goto trans_cancel; 837 goto trans_cancel;
840 838
@@ -955,9 +953,9 @@ xfs_iomap_write_unwritten(
955 */ 953 */
956 XFS_BMAP_INIT(&free_list, &firstfsb); 954 XFS_BMAP_INIT(&free_list, &firstfsb);
957 nimaps = 1; 955 nimaps = 1;
958 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 956 error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb,
959 XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, 957 XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
960 1, &imap, &nimaps, &free_list); 958 1, &imap, &nimaps, &free_list, NULL);
961 if (error) 959 if (error)
962 goto error_on_bmapi_transaction; 960 goto error_on_bmapi_transaction;
963 961
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 94068d014f27..46249e4d1fea 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -41,11 +39,6 @@
41#include "xfs_error.h" 39#include "xfs_error.h"
42#include "xfs_btree.h" 40#include "xfs_btree.h"
43 41
44#ifndef HAVE_USERACC
45#define useracc(ubuffer, size, flags, foo) (0)
46#define unuseracc(ubuffer, size, flags)
47#endif
48
49STATIC int 42STATIC int
50xfs_bulkstat_one_iget( 43xfs_bulkstat_one_iget(
51 xfs_mount_t *mp, /* mount point for filesystem */ 44 xfs_mount_t *mp, /* mount point for filesystem */
@@ -56,7 +49,7 @@ xfs_bulkstat_one_iget(
56{ 49{
57 xfs_dinode_core_t *dic; /* dinode core info pointer */ 50 xfs_dinode_core_t *dic; /* dinode core info pointer */
58 xfs_inode_t *ip; /* incore inode pointer */ 51 xfs_inode_t *ip; /* incore inode pointer */
59 vnode_t *vp; 52 bhv_vnode_t *vp;
60 int error; 53 int error;
61 54
62 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); 55 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
@@ -336,15 +329,6 @@ xfs_bulkstat(
336 nimask = ~(nicluster - 1); 329 nimask = ~(nicluster - 1);
337 nbcluster = nicluster >> mp->m_sb.sb_inopblog; 330 nbcluster = nicluster >> mp->m_sb.sb_inopblog;
338 /* 331 /*
339 * Lock down the user's buffer. If a buffer was not sent, as in the case
340 * disk quota code calls here, we skip this.
341 */
342 if (ubuffer &&
343 (error = useracc(ubuffer, ubcount * statstruct_size,
344 (B_READ|B_PHYS), NULL))) {
345 return error;
346 }
347 /*
348 * Allocate a page-sized buffer for inode btree records. 332 * Allocate a page-sized buffer for inode btree records.
349 * We could try allocating something smaller, but for normal 333 * We could try allocating something smaller, but for normal
350 * calls we'll always (potentially) need the whole page. 334 * calls we'll always (potentially) need the whole page.
@@ -650,8 +634,6 @@ xfs_bulkstat(
650 * Done, we're either out of filesystem or space to put the data. 634 * Done, we're either out of filesystem or space to put the data.
651 */ 635 */
652 kmem_free(irbuf, NBPC); 636 kmem_free(irbuf, NBPC);
653 if (ubuffer)
654 unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS));
655 *ubcountp = ubelem; 637 *ubcountp = ubelem;
656 if (agno >= mp->m_sb.sb_agcount) { 638 if (agno >= mp->m_sb.sb_agcount) {
657 /* 639 /*
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 11eb4e1b18c4..be5f12e07d22 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -45,7 +45,6 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
45 */ 45 */
46#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */ 46#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
47#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ 47#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
48#define BULKSTAT_FG_VFSLOCKED 0x4 /* Already have vfs lock */
49 48
50/* 49/*
51 * Return stat information in bulk (by-inode) for the filesystem. 50 * Return stat information in bulk (by-inode) for the filesystem.
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 32e841d2f26d..d8f5d4cbe8b7 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -24,7 +24,6 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -36,7 +35,6 @@
36#include "xfs_ialloc_btree.h" 35#include "xfs_ialloc_btree.h"
37#include "xfs_log_recover.h" 36#include "xfs_log_recover.h"
38#include "xfs_trans_priv.h" 37#include "xfs_trans_priv.h"
39#include "xfs_dir_sf.h"
40#include "xfs_dir2_sf.h" 38#include "xfs_dir2_sf.h"
41#include "xfs_attr_sf.h" 39#include "xfs_attr_sf.h"
42#include "xfs_dinode.h" 40#include "xfs_dinode.h"
@@ -402,7 +400,7 @@ xfs_log_release_iclog(xfs_mount_t *mp,
402 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; 400 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
403 401
404 if (xlog_state_release_iclog(log, iclog)) { 402 if (xlog_state_release_iclog(log, iclog)) {
405 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 403 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
406 return EIO; 404 return EIO;
407 } 405 }
408 406
@@ -498,9 +496,8 @@ xfs_log_mount(xfs_mount_t *mp,
498 * just worked. 496 * just worked.
499 */ 497 */
500 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { 498 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
501 int error; 499 bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
502 vfs_t *vfsp = XFS_MTOVFS(mp); 500 int error, readonly = (vfsp->vfs_flag & VFS_RDONLY);
503 int readonly = (vfsp->vfs_flag & VFS_RDONLY);
504 501
505 if (readonly) 502 if (readonly)
506 vfsp->vfs_flag &= ~VFS_RDONLY; 503 vfsp->vfs_flag &= ~VFS_RDONLY;
@@ -726,7 +723,7 @@ xfs_log_write(xfs_mount_t * mp,
726 return XFS_ERROR(EIO); 723 return XFS_ERROR(EIO);
727 724
728 if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) { 725 if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
729 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 726 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
730 } 727 }
731 return error; 728 return error;
732} /* xfs_log_write */ 729} /* xfs_log_write */
@@ -816,9 +813,9 @@ xfs_log_need_covered(xfs_mount_t *mp)
816 SPLDECL(s); 813 SPLDECL(s);
817 int needed = 0, gen; 814 int needed = 0, gen;
818 xlog_t *log = mp->m_log; 815 xlog_t *log = mp->m_log;
819 vfs_t *vfsp = XFS_MTOVFS(mp); 816 bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
820 817
821 if (fs_frozen(vfsp) || XFS_FORCED_SHUTDOWN(mp) || 818 if (vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
822 (vfsp->vfs_flag & VFS_RDONLY)) 819 (vfsp->vfs_flag & VFS_RDONLY))
823 return 0; 820 return 0;
824 821
@@ -956,7 +953,7 @@ xlog_iodone(xfs_buf_t *bp)
956 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { 953 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
957 xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp)); 954 xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
958 XFS_BUF_STALE(bp); 955 XFS_BUF_STALE(bp);
959 xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR); 956 xfs_force_shutdown(l->l_mp, SHUTDOWN_LOG_IO_ERROR);
960 /* 957 /*
961 * This flag will be propagated to the trans-committed 958 * This flag will be propagated to the trans-committed
962 * callback routines to let them know that the log-commit 959 * callback routines to let them know that the log-commit
@@ -1261,7 +1258,7 @@ xlog_commit_record(xfs_mount_t *mp,
1261 ASSERT_ALWAYS(iclog); 1258 ASSERT_ALWAYS(iclog);
1262 if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, 1259 if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp,
1263 iclog, XLOG_COMMIT_TRANS))) { 1260 iclog, XLOG_COMMIT_TRANS))) {
1264 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 1261 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
1265 } 1262 }
1266 return error; 1263 return error;
1267} /* xlog_commit_record */ 1264} /* xlog_commit_record */
@@ -1790,7 +1787,7 @@ xlog_write(xfs_mount_t * mp,
1790 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp, 1787 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
1791 "xfs_log_write: reservation ran out. Need to up reservation"); 1788 "xfs_log_write: reservation ran out. Need to up reservation");
1792 /* If we did not panic, shutdown the filesystem */ 1789 /* If we did not panic, shutdown the filesystem */
1793 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 1790 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1794#endif 1791#endif
1795 } else 1792 } else
1796 ticket->t_curr_res -= len; 1793 ticket->t_curr_res -= len;
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 1f0016b0b4ec..55b4237c2153 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -193,14 +191,14 @@ xlog_header_check_dump(
193{ 191{
194 int b; 192 int b;
195 193
196 printk("%s: SB : uuid = ", __FUNCTION__); 194 cmn_err(CE_DEBUG, "%s: SB : uuid = ", __FUNCTION__);
197 for (b = 0; b < 16; b++) 195 for (b = 0; b < 16; b++)
198 printk("%02x",((unsigned char *)&mp->m_sb.sb_uuid)[b]); 196 cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]);
199 printk(", fmt = %d\n", XLOG_FMT); 197 cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT);
200 printk(" log : uuid = "); 198 cmn_err(CE_DEBUG, " log : uuid = ");
201 for (b = 0; b < 16; b++) 199 for (b = 0; b < 16; b++)
202 printk("%02x",((unsigned char *)&head->h_fs_uuid)[b]); 200 cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
203 printk(", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT)); 201 cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
204} 202}
205#else 203#else
206#define xlog_header_check_dump(mp, head) 204#define xlog_header_check_dump(mp, head)
@@ -282,7 +280,7 @@ xlog_recover_iodone(
282 mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *); 280 mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *);
283 xfs_ioerror_alert("xlog_recover_iodone", 281 xfs_ioerror_alert("xlog_recover_iodone",
284 mp, bp, XFS_BUF_ADDR(bp)); 282 mp, bp, XFS_BUF_ADDR(bp));
285 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 283 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
286 } 284 }
287 XFS_BUF_SET_FSPRIVATE(bp, NULL); 285 XFS_BUF_SET_FSPRIVATE(bp, NULL);
288 XFS_BUF_CLR_IODONE_FUNC(bp); 286 XFS_BUF_CLR_IODONE_FUNC(bp);
@@ -1889,7 +1887,7 @@ xlog_recover_do_inode_buffer(
1889 1887
1890 buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp, 1888 buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
1891 next_unlinked_offset); 1889 next_unlinked_offset);
1892 INT_SET(*buffer_nextp, ARCH_CONVERT, *logged_nextp); 1890 *buffer_nextp = *logged_nextp;
1893 } 1891 }
1894 1892
1895 return 0; 1893 return 0;
@@ -2292,12 +2290,22 @@ xlog_recover_do_inode_trans(
2292 int attr_index; 2290 int attr_index;
2293 uint fields; 2291 uint fields;
2294 xfs_dinode_core_t *dicp; 2292 xfs_dinode_core_t *dicp;
2293 int need_free = 0;
2295 2294
2296 if (pass == XLOG_RECOVER_PASS1) { 2295 if (pass == XLOG_RECOVER_PASS1) {
2297 return 0; 2296 return 0;
2298 } 2297 }
2299 2298
2300 in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr; 2299 if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
2300 in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
2301 } else {
2302 in_f = (xfs_inode_log_format_t *)kmem_alloc(
2303 sizeof(xfs_inode_log_format_t), KM_SLEEP);
2304 need_free = 1;
2305 error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
2306 if (error)
2307 goto error;
2308 }
2301 ino = in_f->ilf_ino; 2309 ino = in_f->ilf_ino;
2302 mp = log->l_mp; 2310 mp = log->l_mp;
2303 if (ITEM_TYPE(item) == XFS_LI_INODE) { 2311 if (ITEM_TYPE(item) == XFS_LI_INODE) {
@@ -2323,8 +2331,10 @@ xlog_recover_do_inode_trans(
2323 * Inode buffers can be freed, look out for it, 2331 * Inode buffers can be freed, look out for it,
2324 * and do not replay the inode. 2332 * and do not replay the inode.
2325 */ 2333 */
2326 if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) 2334 if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) {
2327 return 0; 2335 error = 0;
2336 goto error;
2337 }
2328 2338
2329 bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len, 2339 bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
2330 XFS_BUF_LOCK); 2340 XFS_BUF_LOCK);
@@ -2333,7 +2343,7 @@ xlog_recover_do_inode_trans(
2333 bp, imap.im_blkno); 2343 bp, imap.im_blkno);
2334 error = XFS_BUF_GETERROR(bp); 2344 error = XFS_BUF_GETERROR(bp);
2335 xfs_buf_relse(bp); 2345 xfs_buf_relse(bp);
2336 return error; 2346 goto error;
2337 } 2347 }
2338 error = 0; 2348 error = 0;
2339 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE); 2349 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
@@ -2350,7 +2360,8 @@ xlog_recover_do_inode_trans(
2350 dip, bp, ino); 2360 dip, bp, ino);
2351 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)", 2361 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
2352 XFS_ERRLEVEL_LOW, mp); 2362 XFS_ERRLEVEL_LOW, mp);
2353 return XFS_ERROR(EFSCORRUPTED); 2363 error = EFSCORRUPTED;
2364 goto error;
2354 } 2365 }
2355 dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr); 2366 dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
2356 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { 2367 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
@@ -2360,7 +2371,8 @@ xlog_recover_do_inode_trans(
2360 item, ino); 2371 item, ino);
2361 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)", 2372 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
2362 XFS_ERRLEVEL_LOW, mp); 2373 XFS_ERRLEVEL_LOW, mp);
2363 return XFS_ERROR(EFSCORRUPTED); 2374 error = EFSCORRUPTED;
2375 goto error;
2364 } 2376 }
2365 2377
2366 /* Skip replay when the on disk inode is newer than the log one */ 2378 /* Skip replay when the on disk inode is newer than the log one */
@@ -2376,7 +2388,8 @@ xlog_recover_do_inode_trans(
2376 /* do nothing */ 2388 /* do nothing */
2377 } else { 2389 } else {
2378 xfs_buf_relse(bp); 2390 xfs_buf_relse(bp);
2379 return 0; 2391 error = 0;
2392 goto error;
2380 } 2393 }
2381 } 2394 }
2382 /* Take the opportunity to reset the flush iteration count */ 2395 /* Take the opportunity to reset the flush iteration count */
@@ -2391,7 +2404,8 @@ xlog_recover_do_inode_trans(
2391 xfs_fs_cmn_err(CE_ALERT, mp, 2404 xfs_fs_cmn_err(CE_ALERT, mp,
2392 "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 2405 "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
2393 item, dip, bp, ino); 2406 item, dip, bp, ino);
2394 return XFS_ERROR(EFSCORRUPTED); 2407 error = EFSCORRUPTED;
2408 goto error;
2395 } 2409 }
2396 } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) { 2410 } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) {
2397 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && 2411 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
@@ -2403,7 +2417,8 @@ xlog_recover_do_inode_trans(
2403 xfs_fs_cmn_err(CE_ALERT, mp, 2417 xfs_fs_cmn_err(CE_ALERT, mp,
2404 "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 2418 "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
2405 item, dip, bp, ino); 2419 item, dip, bp, ino);
2406 return XFS_ERROR(EFSCORRUPTED); 2420 error = EFSCORRUPTED;
2421 goto error;
2407 } 2422 }
2408 } 2423 }
2409 if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){ 2424 if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
@@ -2415,7 +2430,8 @@ xlog_recover_do_inode_trans(
2415 item, dip, bp, ino, 2430 item, dip, bp, ino,
2416 dicp->di_nextents + dicp->di_anextents, 2431 dicp->di_nextents + dicp->di_anextents,
2417 dicp->di_nblocks); 2432 dicp->di_nblocks);
2418 return XFS_ERROR(EFSCORRUPTED); 2433 error = EFSCORRUPTED;
2434 goto error;
2419 } 2435 }
2420 if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) { 2436 if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
2421 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)", 2437 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
@@ -2424,7 +2440,8 @@ xlog_recover_do_inode_trans(
2424 xfs_fs_cmn_err(CE_ALERT, mp, 2440 xfs_fs_cmn_err(CE_ALERT, mp,
2425 "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x", 2441 "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
2426 item, dip, bp, ino, dicp->di_forkoff); 2442 item, dip, bp, ino, dicp->di_forkoff);
2427 return XFS_ERROR(EFSCORRUPTED); 2443 error = EFSCORRUPTED;
2444 goto error;
2428 } 2445 }
2429 if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) { 2446 if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
2430 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)", 2447 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
@@ -2433,7 +2450,8 @@ xlog_recover_do_inode_trans(
2433 xfs_fs_cmn_err(CE_ALERT, mp, 2450 xfs_fs_cmn_err(CE_ALERT, mp,
2434 "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p", 2451 "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p",
2435 item->ri_buf[1].i_len, item); 2452 item->ri_buf[1].i_len, item);
2436 return XFS_ERROR(EFSCORRUPTED); 2453 error = EFSCORRUPTED;
2454 goto error;
2437 } 2455 }
2438 2456
2439 /* The core is in in-core format */ 2457 /* The core is in in-core format */
@@ -2521,7 +2539,8 @@ xlog_recover_do_inode_trans(
2521 xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag"); 2539 xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag");
2522 ASSERT(0); 2540 ASSERT(0);
2523 xfs_buf_relse(bp); 2541 xfs_buf_relse(bp);
2524 return XFS_ERROR(EIO); 2542 error = EIO;
2543 goto error;
2525 } 2544 }
2526 } 2545 }
2527 2546
@@ -2537,7 +2556,10 @@ write_inode_buffer:
2537 error = xfs_bwrite(mp, bp); 2556 error = xfs_bwrite(mp, bp);
2538 } 2557 }
2539 2558
2540 return (error); 2559error:
2560 if (need_free)
2561 kmem_free(in_f, sizeof(*in_f));
2562 return XFS_ERROR(error);
2541} 2563}
2542 2564
2543/* 2565/*
@@ -2674,32 +2696,32 @@ xlog_recover_do_dquot_trans(
2674 * structure into it, and adds the efi to the AIL with the given 2696 * structure into it, and adds the efi to the AIL with the given
2675 * LSN. 2697 * LSN.
2676 */ 2698 */
2677STATIC void 2699STATIC int
2678xlog_recover_do_efi_trans( 2700xlog_recover_do_efi_trans(
2679 xlog_t *log, 2701 xlog_t *log,
2680 xlog_recover_item_t *item, 2702 xlog_recover_item_t *item,
2681 xfs_lsn_t lsn, 2703 xfs_lsn_t lsn,
2682 int pass) 2704 int pass)
2683{ 2705{
2706 int error;
2684 xfs_mount_t *mp; 2707 xfs_mount_t *mp;
2685 xfs_efi_log_item_t *efip; 2708 xfs_efi_log_item_t *efip;
2686 xfs_efi_log_format_t *efi_formatp; 2709 xfs_efi_log_format_t *efi_formatp;
2687 SPLDECL(s); 2710 SPLDECL(s);
2688 2711
2689 if (pass == XLOG_RECOVER_PASS1) { 2712 if (pass == XLOG_RECOVER_PASS1) {
2690 return; 2713 return 0;
2691 } 2714 }
2692 2715
2693 efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr; 2716 efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
2694 ASSERT(item->ri_buf[0].i_len ==
2695 (sizeof(xfs_efi_log_format_t) +
2696 ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))));
2697 2717
2698 mp = log->l_mp; 2718 mp = log->l_mp;
2699 efip = xfs_efi_init(mp, efi_formatp->efi_nextents); 2719 efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
2700 memcpy((char *)&(efip->efi_format), (char *)efi_formatp, 2720 if ((error = xfs_efi_copy_format(&(item->ri_buf[0]),
2701 sizeof(xfs_efi_log_format_t) + 2721 &(efip->efi_format)))) {
2702 ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))); 2722 xfs_efi_item_free(efip);
2723 return error;
2724 }
2703 efip->efi_next_extent = efi_formatp->efi_nextents; 2725 efip->efi_next_extent = efi_formatp->efi_nextents;
2704 efip->efi_flags |= XFS_EFI_COMMITTED; 2726 efip->efi_flags |= XFS_EFI_COMMITTED;
2705 2727
@@ -2708,6 +2730,7 @@ xlog_recover_do_efi_trans(
2708 * xfs_trans_update_ail() drops the AIL lock. 2730 * xfs_trans_update_ail() drops the AIL lock.
2709 */ 2731 */
2710 xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s); 2732 xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s);
2733 return 0;
2711} 2734}
2712 2735
2713 2736
@@ -2738,9 +2761,10 @@ xlog_recover_do_efd_trans(
2738 } 2761 }
2739 2762
2740 efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr; 2763 efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
2741 ASSERT(item->ri_buf[0].i_len == 2764 ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
2742 (sizeof(xfs_efd_log_format_t) + 2765 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
2743 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_t)))); 2766 (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
2767 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
2744 efi_id = efd_formatp->efd_efi_id; 2768 efi_id = efd_formatp->efd_efi_id;
2745 2769
2746 /* 2770 /*
@@ -2810,15 +2834,14 @@ xlog_recover_do_trans(
2810 if ((error = xlog_recover_do_buffer_trans(log, item, 2834 if ((error = xlog_recover_do_buffer_trans(log, item,
2811 pass))) 2835 pass)))
2812 break; 2836 break;
2813 } else if ((ITEM_TYPE(item) == XFS_LI_INODE) || 2837 } else if ((ITEM_TYPE(item) == XFS_LI_INODE)) {
2814 (ITEM_TYPE(item) == XFS_LI_6_1_INODE) ||
2815 (ITEM_TYPE(item) == XFS_LI_5_3_INODE)) {
2816 if ((error = xlog_recover_do_inode_trans(log, item, 2838 if ((error = xlog_recover_do_inode_trans(log, item,
2817 pass))) 2839 pass)))
2818 break; 2840 break;
2819 } else if (ITEM_TYPE(item) == XFS_LI_EFI) { 2841 } else if (ITEM_TYPE(item) == XFS_LI_EFI) {
2820 xlog_recover_do_efi_trans(log, item, trans->r_lsn, 2842 if ((error = xlog_recover_do_efi_trans(log, item, trans->r_lsn,
2821 pass); 2843 pass)))
2844 break;
2822 } else if (ITEM_TYPE(item) == XFS_LI_EFD) { 2845 } else if (ITEM_TYPE(item) == XFS_LI_EFD) {
2823 xlog_recover_do_efd_trans(log, item, pass); 2846 xlog_recover_do_efd_trans(log, item, pass);
2824 } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) { 2847 } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
@@ -3419,13 +3442,13 @@ xlog_unpack_data_checksum(
3419 if (rhead->h_chksum || 3442 if (rhead->h_chksum ||
3420 ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) { 3443 ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
3421 cmn_err(CE_DEBUG, 3444 cmn_err(CE_DEBUG,
3422 "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)", 3445 "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
3423 INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum); 3446 INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum);
3424 cmn_err(CE_DEBUG, 3447 cmn_err(CE_DEBUG,
3425"XFS: Disregard message if filesystem was created with non-DEBUG kernel"); 3448"XFS: Disregard message if filesystem was created with non-DEBUG kernel");
3426 if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { 3449 if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
3427 cmn_err(CE_DEBUG, 3450 cmn_err(CE_DEBUG,
3428 "XFS: LogR this is a LogV2 filesystem"); 3451 "XFS: LogR this is a LogV2 filesystem\n");
3429 } 3452 }
3430 log->l_flags |= XLOG_CHKSUM_MISMATCH; 3453 log->l_flags |= XLOG_CHKSUM_MISMATCH;
3431 } 3454 }
@@ -3798,7 +3821,7 @@ xlog_do_log_recovery(
3798 error = xlog_do_recovery_pass(log, head_blk, tail_blk, 3821 error = xlog_do_recovery_pass(log, head_blk, tail_blk,
3799 XLOG_RECOVER_PASS2); 3822 XLOG_RECOVER_PASS2);
3800#ifdef DEBUG 3823#ifdef DEBUG
3801 { 3824 if (!error) {
3802 int i; 3825 int i;
3803 3826
3804 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) 3827 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
@@ -3974,7 +3997,7 @@ xlog_recover_finish(
3974 log->l_flags &= ~XLOG_RECOVERY_NEEDED; 3997 log->l_flags &= ~XLOG_RECOVERY_NEEDED;
3975 } else { 3998 } else {
3976 cmn_err(CE_DEBUG, 3999 cmn_err(CE_DEBUG,
3977 "!Ending clean XFS mount for filesystem: %s", 4000 "!Ending clean XFS mount for filesystem: %s\n",
3978 log->l_mp->m_fsname); 4001 log->l_mp->m_fsname);
3979 } 4002 }
3980 return 0; 4003 return 0;
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index c0b1c2906880..10dbf203c62f 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -196,7 +194,7 @@ xfs_mount_free(
196 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); 194 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
197 195
198 if (remove_bhv) { 196 if (remove_bhv) {
199 struct vfs *vfsp = XFS_MTOVFS(mp); 197 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
200 198
201 bhv_remove_all_vfsops(vfsp, 0); 199 bhv_remove_all_vfsops(vfsp, 0);
202 VFS_REMOVEBHV(vfsp, &mp->m_bhv); 200 VFS_REMOVEBHV(vfsp, &mp->m_bhv);
@@ -337,7 +335,7 @@ xfs_mount_validate_sb(
337 335
338xfs_agnumber_t 336xfs_agnumber_t
339xfs_initialize_perag( 337xfs_initialize_perag(
340 struct vfs *vfs, 338 bhv_vfs_t *vfs,
341 xfs_mount_t *mp, 339 xfs_mount_t *mp,
342 xfs_agnumber_t agcount) 340 xfs_agnumber_t agcount)
343{ 341{
@@ -651,14 +649,14 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
651 */ 649 */
652int 650int
653xfs_mountfs( 651xfs_mountfs(
654 vfs_t *vfsp, 652 bhv_vfs_t *vfsp,
655 xfs_mount_t *mp, 653 xfs_mount_t *mp,
656 int mfsi_flags) 654 int mfsi_flags)
657{ 655{
658 xfs_buf_t *bp; 656 xfs_buf_t *bp;
659 xfs_sb_t *sbp = &(mp->m_sb); 657 xfs_sb_t *sbp = &(mp->m_sb);
660 xfs_inode_t *rip; 658 xfs_inode_t *rip;
661 vnode_t *rvp = NULL; 659 bhv_vnode_t *rvp = NULL;
662 int readio_log, writeio_log; 660 int readio_log, writeio_log;
663 xfs_daddr_t d; 661 xfs_daddr_t d;
664 __uint64_t ret64; 662 __uint64_t ret64;
@@ -934,18 +932,7 @@ xfs_mountfs(
934 vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid; 932 vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
935 mp->m_dmevmask = 0; /* not persistent; set after each mount */ 933 mp->m_dmevmask = 0; /* not persistent; set after each mount */
936 934
937 /* 935 xfs_dir_mount(mp);
938 * Select the right directory manager.
939 */
940 mp->m_dirops =
941 XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
942 xfsv2_dirops :
943 xfsv1_dirops;
944
945 /*
946 * Initialize directory manager's entries.
947 */
948 XFS_DIR_MOUNT(mp);
949 936
950 /* 937 /*
951 * Initialize the attribute manager's entries. 938 * Initialize the attribute manager's entries.
@@ -1006,8 +993,9 @@ xfs_mountfs(
1006 993
1007 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { 994 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) {
1008 cmn_err(CE_WARN, "XFS: corrupted root inode"); 995 cmn_err(CE_WARN, "XFS: corrupted root inode");
1009 prdev("Root inode %llu is not a directory", 996 cmn_err(CE_WARN, "Device %s - root %llu is not a directory",
1010 mp->m_ddev_targp, (unsigned long long)rip->i_ino); 997 XFS_BUFTARG_NAME(mp->m_ddev_targp),
998 (unsigned long long)rip->i_ino);
1011 xfs_iunlock(rip, XFS_ILOCK_EXCL); 999 xfs_iunlock(rip, XFS_ILOCK_EXCL);
1012 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, 1000 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
1013 mp); 1001 mp);
@@ -1094,7 +1082,7 @@ xfs_mountfs(
1094int 1082int
1095xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) 1083xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1096{ 1084{
1097 struct vfs *vfsp = XFS_MTOVFS(mp); 1085 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1098#if defined(DEBUG) || defined(INDUCE_IO_ERROR) 1086#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
1099 int64_t fsid; 1087 int64_t fsid;
1100#endif 1088#endif
@@ -1254,6 +1242,26 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
1254 1242
1255 xfs_trans_log_buf(tp, bp, first, last); 1243 xfs_trans_log_buf(tp, bp, first, last);
1256} 1244}
1245
1246/*
1247 * In order to avoid ENOSPC-related deadlock caused by
1248 * out-of-order locking of AGF buffer (PV 947395), we place
1249 * constraints on the relationship among actual allocations for
1250 * data blocks, freelist blocks, and potential file data bmap
1251 * btree blocks. However, these restrictions may result in no
1252 * actual space allocated for a delayed extent, for example, a data
1253 * block in a certain AG is allocated but there is no additional
1254 * block for the additional bmap btree block due to a split of the
1255 * bmap btree of the file. The result of this may lead to an
1256 * infinite loop in xfssyncd when the file gets flushed to disk and
1257 * all delayed extents need to be actually allocated. To get around
1258 * this, we explicitly set aside a few blocks which will not be
1259 * reserved in delayed allocation. Considering the minimum number of
1260 * needed freelist blocks is 4 fsbs, a potential split of file's bmap
1261 * btree requires 1 fsb, so we set the number of set-aside blocks to 8.
1262*/
1263#define SET_ASIDE_BLOCKS 8
1264
1257/* 1265/*
1258 * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply 1266 * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply
1259 * a delta to a specified field in the in-core superblock. Simply 1267 * a delta to a specified field in the in-core superblock. Simply
@@ -1298,7 +1306,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
1298 return 0; 1306 return 0;
1299 case XFS_SBS_FDBLOCKS: 1307 case XFS_SBS_FDBLOCKS:
1300 1308
1301 lcounter = (long long)mp->m_sb.sb_fdblocks; 1309 lcounter = (long long)mp->m_sb.sb_fdblocks - SET_ASIDE_BLOCKS;
1302 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail); 1310 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
1303 1311
1304 if (delta > 0) { /* Putting blocks back */ 1312 if (delta > 0) { /* Putting blocks back */
@@ -1332,7 +1340,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
1332 } 1340 }
1333 } 1341 }
1334 1342
1335 mp->m_sb.sb_fdblocks = lcounter; 1343 mp->m_sb.sb_fdblocks = lcounter + SET_ASIDE_BLOCKS;
1336 return 0; 1344 return 0;
1337 case XFS_SBS_FREXTENTS: 1345 case XFS_SBS_FREXTENTS:
1338 lcounter = (long long)mp->m_sb.sb_frextents; 1346 lcounter = (long long)mp->m_sb.sb_frextents;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 668ad23fd37c..b2bd4be4200a 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -53,8 +53,8 @@ typedef struct xfs_trans_reservations {
53#else 53#else
54struct cred; 54struct cred;
55struct log; 55struct log;
56struct vfs; 56struct bhv_vfs;
57struct vnode; 57struct bhv_vnode;
58struct xfs_mount_args; 58struct xfs_mount_args;
59struct xfs_ihash; 59struct xfs_ihash;
60struct xfs_chash; 60struct xfs_chash;
@@ -63,9 +63,11 @@ struct xfs_perag;
63struct xfs_iocore; 63struct xfs_iocore;
64struct xfs_bmbt_irec; 64struct xfs_bmbt_irec;
65struct xfs_bmap_free; 65struct xfs_bmap_free;
66struct xfs_extdelta;
67struct xfs_swapext;
66 68
67extern struct vfsops xfs_vfsops; 69extern struct bhv_vfsops xfs_vfsops;
68extern struct vnodeops xfs_vnodeops; 70extern struct bhv_vnodeops xfs_vnodeops;
69 71
70#define AIL_LOCK_T lock_t 72#define AIL_LOCK_T lock_t
71#define AIL_LOCKINIT(x,y) spinlock_init(x,y) 73#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
@@ -78,15 +80,15 @@ extern struct vnodeops xfs_vnodeops;
78 * Prototypes and functions for the Data Migration subsystem. 80 * Prototypes and functions for the Data Migration subsystem.
79 */ 81 */
80 82
81typedef int (*xfs_send_data_t)(int, struct vnode *, 83typedef int (*xfs_send_data_t)(int, struct bhv_vnode *,
82 xfs_off_t, size_t, int, vrwlock_t *); 84 xfs_off_t, size_t, int, bhv_vrwlock_t *);
83typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); 85typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
84typedef int (*xfs_send_destroy_t)(struct vnode *, dm_right_t); 86typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t);
85typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vfs *, 87typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *,
86 struct vnode *, 88 struct bhv_vnode *,
87 dm_right_t, struct vnode *, dm_right_t, 89 dm_right_t, struct bhv_vnode *, dm_right_t,
88 char *, char *, mode_t, int, int); 90 char *, char *, mode_t, int, int);
89typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *, 91typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, struct bhv_vnode *,
90 dm_right_t, mode_t, int, int); 92 dm_right_t, mode_t, int, int);
91 93
92typedef struct xfs_dmops { 94typedef struct xfs_dmops {
@@ -188,13 +190,18 @@ typedef struct xfs_qmops {
188 * Prototypes and functions for I/O core modularization. 190 * Prototypes and functions for I/O core modularization.
189 */ 191 */
190 192
191typedef int (*xfs_ioinit_t)(struct vfs *, 193typedef int (*xfs_ioinit_t)(struct bhv_vfs *,
192 struct xfs_mount_args *, int); 194 struct xfs_mount_args *, int);
193typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, 195typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
194 xfs_fileoff_t, xfs_filblks_t, int, 196 xfs_fileoff_t, xfs_filblks_t, int,
195 xfs_fsblock_t *, xfs_extlen_t, 197 xfs_fsblock_t *, xfs_extlen_t,
196 struct xfs_bmbt_irec *, int *, 198 struct xfs_bmbt_irec *, int *,
197 struct xfs_bmap_free *); 199 struct xfs_bmap_free *, struct xfs_extdelta *);
200typedef int (*xfs_bunmapi_t)(struct xfs_trans *,
201 void *, xfs_fileoff_t,
202 xfs_filblks_t, int, xfs_extnum_t,
203 xfs_fsblock_t *, struct xfs_bmap_free *,
204 struct xfs_extdelta *, int *);
198typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); 205typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
199typedef int (*xfs_iomap_write_direct_t)( 206typedef int (*xfs_iomap_write_direct_t)(
200 void *, xfs_off_t, size_t, int, 207 void *, xfs_off_t, size_t, int,
@@ -213,11 +220,14 @@ typedef void (*xfs_lock_demote_t)(void *, uint);
213typedef int (*xfs_lock_nowait_t)(void *, uint); 220typedef int (*xfs_lock_nowait_t)(void *, uint);
214typedef void (*xfs_unlk_t)(void *, unsigned int); 221typedef void (*xfs_unlk_t)(void *, unsigned int);
215typedef xfs_fsize_t (*xfs_size_t)(void *); 222typedef xfs_fsize_t (*xfs_size_t)(void *);
216typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *); 223typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *);
224typedef int (*xfs_swap_extents_t)(void *, void *,
225 struct xfs_swapext*);
217 226
218typedef struct xfs_ioops { 227typedef struct xfs_ioops {
219 xfs_ioinit_t xfs_ioinit; 228 xfs_ioinit_t xfs_ioinit;
220 xfs_bmapi_t xfs_bmapi_func; 229 xfs_bmapi_t xfs_bmapi_func;
230 xfs_bunmapi_t xfs_bunmapi_func;
221 xfs_bmap_eof_t xfs_bmap_eof_func; 231 xfs_bmap_eof_t xfs_bmap_eof_func;
222 xfs_iomap_write_direct_t xfs_iomap_write_direct; 232 xfs_iomap_write_direct_t xfs_iomap_write_direct;
223 xfs_iomap_write_delay_t xfs_iomap_write_delay; 233 xfs_iomap_write_delay_t xfs_iomap_write_delay;
@@ -230,13 +240,17 @@ typedef struct xfs_ioops {
230 xfs_unlk_t xfs_unlock; 240 xfs_unlk_t xfs_unlock;
231 xfs_size_t xfs_size_func; 241 xfs_size_t xfs_size_func;
232 xfs_iodone_t xfs_iodone; 242 xfs_iodone_t xfs_iodone;
243 xfs_swap_extents_t xfs_swap_extents_func;
233} xfs_ioops_t; 244} xfs_ioops_t;
234 245
235#define XFS_IOINIT(vfsp, args, flags) \ 246#define XFS_IOINIT(vfsp, args, flags) \
236 (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) 247 (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags)
237#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \ 248#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \
238 (*(mp)->m_io_ops.xfs_bmapi_func) \ 249 (*(mp)->m_io_ops.xfs_bmapi_func) \
239 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist) 250 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta)
251#define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \
252 (*(mp)->m_io_ops.xfs_bunmapi_func) \
253 (trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done)
240#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \ 254#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \
241 (*(mp)->m_io_ops.xfs_bmap_eof_func) \ 255 (*(mp)->m_io_ops.xfs_bmap_eof_func) \
242 ((io)->io_obj, endoff, whichfork, eof) 256 ((io)->io_obj, endoff, whichfork, eof)
@@ -266,6 +280,9 @@ typedef struct xfs_ioops {
266 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) 280 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
267#define XFS_IODONE(vfsp) \ 281#define XFS_IODONE(vfsp) \
268 (*(mp)->m_io_ops.xfs_iodone)(vfsp) 282 (*(mp)->m_io_ops.xfs_iodone)(vfsp)
283#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \
284 (*(mp)->m_io_ops.xfs_swap_extents_func) \
285 ((io)->io_obj, (tio)->io_obj, sxp)
269 286
270#ifdef HAVE_PERCPU_SB 287#ifdef HAVE_PERCPU_SB
271 288
@@ -386,8 +403,6 @@ typedef struct xfs_mount {
386 __uint8_t m_inode_quiesce;/* call quiesce on new inodes. 403 __uint8_t m_inode_quiesce;/* call quiesce on new inodes.
387 field governed by m_ilock */ 404 field governed by m_ilock */
388 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ 405 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
389 __uint8_t m_dirversion; /* 1 or 2 */
390 xfs_dirops_t m_dirops; /* table of dir funcs */
391 int m_dirblksize; /* directory block sz--bytes */ 406 int m_dirblksize; /* directory block sz--bytes */
392 int m_dirblkfsbs; /* directory block sz--fsbs */ 407 int m_dirblkfsbs; /* directory block sz--fsbs */
393 xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ 408 xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */
@@ -494,16 +509,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
494 509
495#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) 510#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
496#define xfs_force_shutdown(m,f) \ 511#define xfs_force_shutdown(m,f) \
497 VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__) 512 bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
498
499/*
500 * Flags sent to xfs_force_shutdown.
501 */
502#define XFS_METADATA_IO_ERROR 0x1
503#define XFS_LOG_IO_ERROR 0x2
504#define XFS_FORCE_UMOUNT 0x4
505#define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */
506#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */
507 513
508/* 514/*
509 * Flags for xfs_mountfs 515 * Flags for xfs_mountfs
@@ -521,7 +527,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
521 * Macros for getting from mount to vfs and back. 527 * Macros for getting from mount to vfs and back.
522 */ 528 */
523#define XFS_MTOVFS(mp) xfs_mtovfs(mp) 529#define XFS_MTOVFS(mp) xfs_mtovfs(mp)
524static inline struct vfs *xfs_mtovfs(xfs_mount_t *mp) 530static inline struct bhv_vfs *xfs_mtovfs(xfs_mount_t *mp)
525{ 531{
526 return bhvtovfs(&mp->m_bhv); 532 return bhvtovfs(&mp->m_bhv);
527} 533}
@@ -533,7 +539,7 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
533} 539}
534 540
535#define XFS_VFSTOM(vfs) xfs_vfstom(vfs) 541#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
536static inline xfs_mount_t *xfs_vfstom(vfs_t *vfs) 542static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
537{ 543{
538 return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)); 544 return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
539} 545}
@@ -571,7 +577,7 @@ typedef struct xfs_mod_sb {
571extern xfs_mount_t *xfs_mount_init(void); 577extern xfs_mount_t *xfs_mount_init(void);
572extern void xfs_mod_sb(xfs_trans_t *, __int64_t); 578extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
573extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); 579extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
574extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); 580extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int);
575extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); 581extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
576 582
577extern int xfs_unmountfs(xfs_mount_t *, struct cred *); 583extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
@@ -589,7 +595,7 @@ extern void xfs_freesb(xfs_mount_t *);
589extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); 595extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
590extern int xfs_syncsub(xfs_mount_t *, int, int, int *); 596extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
591extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *); 597extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *);
592extern xfs_agnumber_t xfs_initialize_perag(struct vfs *, xfs_mount_t *, 598extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *,
593 xfs_agnumber_t); 599 xfs_agnumber_t);
594extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); 600extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t);
595 601
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 1408a32eef88..320d63ff9ca2 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -23,7 +23,6 @@
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_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
29#include "xfs_mount.h" 28#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 7fbef974bce6..acb853b33ebb 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -365,7 +365,7 @@ typedef struct xfs_dqtrxops {
365extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); 365extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
366extern int xfs_mount_reset_sbqflags(struct xfs_mount *); 366extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
367 367
368extern struct bhv_vfsops xfs_qmops; 368extern struct bhv_module_vfsops xfs_qmops;
369 369
370#endif /* __KERNEL__ */ 370#endif /* __KERNEL__ */
371 371
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 1f148762eb28..d98171deaa1c 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -22,13 +22,11 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.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_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
@@ -40,7 +38,6 @@
40#include "xfs_refcache.h" 38#include "xfs_refcache.h"
41#include "xfs_utils.h" 39#include "xfs_utils.h"
42#include "xfs_trans_space.h" 40#include "xfs_trans_space.h"
43#include "xfs_dir_leaf.h"
44 41
45 42
46/* 43/*
@@ -87,8 +84,8 @@ STATIC int
87xfs_lock_for_rename( 84xfs_lock_for_rename(
88 xfs_inode_t *dp1, /* old (source) directory inode */ 85 xfs_inode_t *dp1, /* old (source) directory inode */
89 xfs_inode_t *dp2, /* new (target) directory inode */ 86 xfs_inode_t *dp2, /* new (target) directory inode */
90 vname_t *vname1,/* old entry name */ 87 bhv_vname_t *vname1,/* old entry name */
91 vname_t *vname2,/* new entry name */ 88 bhv_vname_t *vname2,/* new entry name */
92 xfs_inode_t **ipp1, /* inode of old entry */ 89 xfs_inode_t **ipp1, /* inode of old entry */
93 xfs_inode_t **ipp2, /* inode of new entry, if it 90 xfs_inode_t **ipp2, /* inode of new entry, if it
94 already exists, NULL otherwise. */ 91 already exists, NULL otherwise. */
@@ -225,9 +222,9 @@ xfs_lock_for_rename(
225int 222int
226xfs_rename( 223xfs_rename(
227 bhv_desc_t *src_dir_bdp, 224 bhv_desc_t *src_dir_bdp,
228 vname_t *src_vname, 225 bhv_vname_t *src_vname,
229 vnode_t *target_dir_vp, 226 bhv_vnode_t *target_dir_vp,
230 vname_t *target_vname, 227 bhv_vname_t *target_vname,
231 cred_t *credp) 228 cred_t *credp)
232{ 229{
233 xfs_trans_t *tp; 230 xfs_trans_t *tp;
@@ -242,7 +239,7 @@ xfs_rename(
242 int committed; 239 int committed;
243 xfs_inode_t *inodes[4]; 240 xfs_inode_t *inodes[4];
244 int target_ip_dropped = 0; /* dropped target_ip link? */ 241 int target_ip_dropped = 0; /* dropped target_ip link? */
245 vnode_t *src_dir_vp; 242 bhv_vnode_t *src_dir_vp;
246 int spaceres; 243 int spaceres;
247 int target_link_zero = 0; 244 int target_link_zero = 0;
248 int num_inodes; 245 int num_inodes;
@@ -398,34 +395,29 @@ xfs_rename(
398 * fit before actually inserting it. 395 * fit before actually inserting it.
399 */ 396 */
400 if (spaceres == 0 && 397 if (spaceres == 0 &&
401 (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name, 398 (error = xfs_dir_canenter(tp, target_dp, target_name,
402 target_namelen))) { 399 target_namelen)))
403 goto error_return; 400 goto error_return;
404 }
405 /* 401 /*
406 * If target does not exist and the rename crosses 402 * If target does not exist and the rename crosses
407 * directories, adjust the target directory link count 403 * directories, adjust the target directory link count
408 * to account for the ".." reference from the new entry. 404 * to account for the ".." reference from the new entry.
409 */ 405 */
410 error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name, 406 error = xfs_dir_createname(tp, target_dp, target_name,
411 target_namelen, src_ip->i_ino, 407 target_namelen, src_ip->i_ino,
412 &first_block, &free_list, spaceres); 408 &first_block, &free_list, spaceres);
413 if (error == ENOSPC) { 409 if (error == ENOSPC)
414 goto error_return; 410 goto error_return;
415 } 411 if (error)
416 if (error) {
417 goto abort_return; 412 goto abort_return;
418 }
419 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 413 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
420 414
421 if (new_parent && src_is_directory) { 415 if (new_parent && src_is_directory) {
422 error = xfs_bumplink(tp, target_dp); 416 error = xfs_bumplink(tp, target_dp);
423 if (error) { 417 if (error)
424 goto abort_return; 418 goto abort_return;
425 }
426 } 419 }
427 } else { /* target_ip != NULL */ 420 } else { /* target_ip != NULL */
428
429 /* 421 /*
430 * If target exists and it's a directory, check that both 422 * If target exists and it's a directory, check that both
431 * target and source are directories and that target can be 423 * target and source are directories and that target can be
@@ -435,7 +427,7 @@ xfs_rename(
435 /* 427 /*
436 * Make sure target dir is empty. 428 * Make sure target dir is empty.
437 */ 429 */
438 if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) || 430 if (!(xfs_dir_isempty(target_ip)) ||
439 (target_ip->i_d.di_nlink > 2)) { 431 (target_ip->i_d.di_nlink > 2)) {
440 error = XFS_ERROR(EEXIST); 432 error = XFS_ERROR(EEXIST);
441 goto error_return; 433 goto error_return;
@@ -451,12 +443,11 @@ xfs_rename(
451 * In case there is already an entry with the same 443 * In case there is already an entry with the same
452 * name at the destination directory, remove it first. 444 * name at the destination directory, remove it first.
453 */ 445 */
454 error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name, 446 error = xfs_dir_replace(tp, target_dp, target_name,
455 target_namelen, src_ip->i_ino, &first_block, 447 target_namelen, src_ip->i_ino,
456 &free_list, spaceres); 448 &first_block, &free_list, spaceres);
457 if (error) { 449 if (error)
458 goto abort_return; 450 goto abort_return;
459 }
460 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 451 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
461 452
462 /* 453 /*
@@ -464,9 +455,8 @@ xfs_rename(
464 * dir no longer points to it. 455 * dir no longer points to it.
465 */ 456 */
466 error = xfs_droplink(tp, target_ip); 457 error = xfs_droplink(tp, target_ip);
467 if (error) { 458 if (error)
468 goto abort_return; 459 goto abort_return;
469 }
470 target_ip_dropped = 1; 460 target_ip_dropped = 1;
471 461
472 if (src_is_directory) { 462 if (src_is_directory) {
@@ -474,9 +464,8 @@ xfs_rename(
474 * Drop the link from the old "." entry. 464 * Drop the link from the old "." entry.
475 */ 465 */
476 error = xfs_droplink(tp, target_ip); 466 error = xfs_droplink(tp, target_ip);
477 if (error) { 467 if (error)
478 goto abort_return; 468 goto abort_return;
479 }
480 } 469 }
481 470
482 /* Do this test while we still hold the locks */ 471 /* Do this test while we still hold the locks */
@@ -488,18 +477,15 @@ xfs_rename(
488 * Remove the source. 477 * Remove the source.
489 */ 478 */
490 if (new_parent && src_is_directory) { 479 if (new_parent && src_is_directory) {
491
492 /* 480 /*
493 * Rewrite the ".." entry to point to the new 481 * Rewrite the ".." entry to point to the new
494 * directory. 482 * directory.
495 */ 483 */
496 error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2, 484 error = xfs_dir_replace(tp, src_ip, "..", 2, target_dp->i_ino,
497 target_dp->i_ino, &first_block, 485 &first_block, &free_list, spaceres);
498 &free_list, spaceres);
499 ASSERT(error != EEXIST); 486 ASSERT(error != EEXIST);
500 if (error) { 487 if (error)
501 goto abort_return; 488 goto abort_return;
502 }
503 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 489 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
504 490
505 } else { 491 } else {
@@ -527,16 +513,14 @@ xfs_rename(
527 * entry that's moved no longer points to it. 513 * entry that's moved no longer points to it.
528 */ 514 */
529 error = xfs_droplink(tp, src_dp); 515 error = xfs_droplink(tp, src_dp);
530 if (error) { 516 if (error)
531 goto abort_return; 517 goto abort_return;
532 }
533 } 518 }
534 519
535 error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen, 520 error = xfs_dir_removename(tp, src_dp, src_name, src_namelen,
536 src_ip->i_ino, &first_block, &free_list, spaceres); 521 src_ip->i_ino, &first_block, &free_list, spaceres);
537 if (error) { 522 if (error)
538 goto abort_return; 523 goto abort_return;
539 }
540 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 524 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
541 525
542 /* 526 /*
@@ -609,7 +593,7 @@ xfs_rename(
609 * Let interposed file systems know about removed links. 593 * Let interposed file systems know about removed links.
610 */ 594 */
611 if (target_ip_dropped) { 595 if (target_ip_dropped) {
612 VOP_LINK_REMOVED(XFS_ITOV(target_ip), target_dir_vp, 596 bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp,
613 target_link_zero); 597 target_link_zero);
614 IRELE(target_ip); 598 IRELE(target_ip);
615 } 599 }
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 5b413946b1c5..0c1e42b037ef 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -141,7 +139,7 @@ xfs_growfs_rt_alloc(
141 cancelflags |= XFS_TRANS_ABORT; 139 cancelflags |= XFS_TRANS_ABORT;
142 error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks, 140 error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
143 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock, 141 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
144 resblks, &map, &nmap, &flist); 142 resblks, &map, &nmap, &flist, NULL);
145 if (!error && nmap < 1) 143 if (!error && nmap < 1)
146 error = XFS_ERROR(ENOSPC); 144 error = XFS_ERROR(ENOSPC);
147 if (error) 145 if (error)
@@ -2404,10 +2402,10 @@ xfs_rtprint_range(
2404{ 2402{
2405 xfs_extlen_t i; /* block number in the extent */ 2403 xfs_extlen_t i; /* block number in the extent */
2406 2404
2407 printk("%Ld: ", (long long)start); 2405 cmn_err(CE_DEBUG, "%Ld: ", (long long)start);
2408 for (i = 0; i < len; i++) 2406 for (i = 0; i < len; i++)
2409 printk("%d", xfs_rtcheck_bit(mp, tp, start + i, 1)); 2407 cmn_err(CE_DEBUG, "%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
2410 printk("\n"); 2408 cmn_err(CE_DEBUG, "\n");
2411} 2409}
2412 2410
2413/* 2411/*
@@ -2431,17 +2429,17 @@ xfs_rtprint_summary(
2431 (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c); 2429 (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c);
2432 if (c) { 2430 if (c) {
2433 if (!p) { 2431 if (!p) {
2434 printk("%Ld-%Ld:", 1LL << l, 2432 cmn_err(CE_DEBUG, "%Ld-%Ld:", 1LL << l,
2435 XFS_RTMIN((1LL << l) + 2433 XFS_RTMIN((1LL << l) +
2436 ((1LL << l) - 1LL), 2434 ((1LL << l) - 1LL),
2437 mp->m_sb.sb_rextents)); 2435 mp->m_sb.sb_rextents));
2438 p = 1; 2436 p = 1;
2439 } 2437 }
2440 printk(" %Ld:%d", (long long)i, c); 2438 cmn_err(CE_DEBUG, " %Ld:%d", (long long)i, c);
2441 } 2439 }
2442 } 2440 }
2443 if (p) 2441 if (p)
2444 printk("\n"); 2442 cmn_err(CE_DEBUG, "\n");
2445 } 2443 }
2446 if (sumbp) 2444 if (sumbp)
2447 xfs_trans_brelse(tp, sumbp); 2445 xfs_trans_brelse(tp, sumbp);
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index a59c102cf214..defb2febaaf5 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -92,6 +90,90 @@ xfs_write_clear_setuid(
92} 90}
93 91
94/* 92/*
93 * Handle logging requirements of various synchronous types of write.
94 */
95int
96xfs_write_sync_logforce(
97 xfs_mount_t *mp,
98 xfs_inode_t *ip)
99{
100 int error = 0;
101
102 /*
103 * If we're treating this as O_DSYNC and we have not updated the
104 * size, force the log.
105 */
106 if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
107 !(ip->i_update_size)) {
108 xfs_inode_log_item_t *iip = ip->i_itemp;
109
110 /*
111 * If an allocation transaction occurred
112 * without extending the size, then we have to force
113 * the log up the proper point to ensure that the
114 * allocation is permanent. We can't count on
115 * the fact that buffered writes lock out direct I/O
116 * writes - the direct I/O write could have extended
117 * the size nontransactionally, then finished before
118 * we started. xfs_write_file will think that the file
119 * didn't grow but the update isn't safe unless the
120 * size change is logged.
121 *
122 * Force the log if we've committed a transaction
123 * against the inode or if someone else has and
124 * the commit record hasn't gone to disk (e.g.
125 * the inode is pinned). This guarantees that
126 * all changes affecting the inode are permanent
127 * when we return.
128 */
129 if (iip && iip->ili_last_lsn) {
130 xfs_log_force(mp, iip->ili_last_lsn,
131 XFS_LOG_FORCE | XFS_LOG_SYNC);
132 } else if (xfs_ipincount(ip) > 0) {
133 xfs_log_force(mp, (xfs_lsn_t)0,
134 XFS_LOG_FORCE | XFS_LOG_SYNC);
135 }
136
137 } else {
138 xfs_trans_t *tp;
139
140 /*
141 * O_SYNC or O_DSYNC _with_ a size update are handled
142 * the same way.
143 *
144 * If the write was synchronous then we need to make
145 * sure that the inode modification time is permanent.
146 * We'll have updated the timestamp above, so here
147 * we use a synchronous transaction to log the inode.
148 * It's not fast, but it's necessary.
149 *
150 * If this a dsync write and the size got changed
151 * non-transactionally, then we need to ensure that
152 * the size change gets logged in a synchronous
153 * transaction.
154 */
155 tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
156 if ((error = xfs_trans_reserve(tp, 0,
157 XFS_SWRITE_LOG_RES(mp),
158 0, 0, 0))) {
159 /* Transaction reserve failed */
160 xfs_trans_cancel(tp, 0);
161 } else {
162 /* Transaction reserve successful */
163 xfs_ilock(ip, XFS_ILOCK_EXCL);
164 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
165 xfs_trans_ihold(tp, ip);
166 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
167 xfs_trans_set_sync(tp);
168 error = xfs_trans_commit(tp, 0, NULL);
169 xfs_iunlock(ip, XFS_ILOCK_EXCL);
170 }
171 }
172
173 return error;
174}
175
176/*
95 * Force a shutdown of the filesystem instantly while keeping 177 * Force a shutdown of the filesystem instantly while keeping
96 * the filesystem consistent. We don't do an unmount here; just shutdown 178 * the filesystem consistent. We don't do an unmount here; just shutdown
97 * the shop, make sure that absolutely nothing persistent happens to 179 * the shop, make sure that absolutely nothing persistent happens to
@@ -109,12 +191,12 @@ xfs_do_force_shutdown(
109 xfs_mount_t *mp; 191 xfs_mount_t *mp;
110 192
111 mp = XFS_BHVTOM(bdp); 193 mp = XFS_BHVTOM(bdp);
112 logerror = flags & XFS_LOG_IO_ERROR; 194 logerror = flags & SHUTDOWN_LOG_IO_ERROR;
113 195
114 if (!(flags & XFS_FORCE_UMOUNT)) { 196 if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
115 cmn_err(CE_NOTE, 197 cmn_err(CE_NOTE, "xfs_force_shutdown(%s,0x%x) called from "
116 "xfs_force_shutdown(%s,0x%x) called from line %d of file %s. Return address = 0x%p", 198 "line %d of file %s. Return address = 0x%p",
117 mp->m_fsname,flags,lnnum,fname,__return_address); 199 mp->m_fsname, flags, lnnum, fname, __return_address);
118 } 200 }
119 /* 201 /*
120 * No need to duplicate efforts. 202 * No need to duplicate efforts.
@@ -125,33 +207,37 @@ xfs_do_force_shutdown(
125 /* 207 /*
126 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't 208 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
127 * queue up anybody new on the log reservations, and wakes up 209 * queue up anybody new on the log reservations, and wakes up
128 * everybody who's sleeping on log reservations and tells 210 * everybody who's sleeping on log reservations to tell them
129 * them the bad news. 211 * the bad news.
130 */ 212 */
131 if (xfs_log_force_umount(mp, logerror)) 213 if (xfs_log_force_umount(mp, logerror))
132 return; 214 return;
133 215
134 if (flags & XFS_CORRUPT_INCORE) { 216 if (flags & SHUTDOWN_CORRUPT_INCORE) {
135 xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp, 217 xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp,
136 "Corruption of in-memory data detected. Shutting down filesystem: %s", 218 "Corruption of in-memory data detected. Shutting down filesystem: %s",
137 mp->m_fsname); 219 mp->m_fsname);
138 if (XFS_ERRLEVEL_HIGH <= xfs_error_level) { 220 if (XFS_ERRLEVEL_HIGH <= xfs_error_level) {
139 xfs_stack_trace(); 221 xfs_stack_trace();
140 } 222 }
141 } else if (!(flags & XFS_FORCE_UMOUNT)) { 223 } else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
142 if (logerror) { 224 if (logerror) {
143 xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp, 225 xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp,
144 "Log I/O Error Detected. Shutting down filesystem: %s", 226 "Log I/O Error Detected. Shutting down filesystem: %s",
227 mp->m_fsname);
228 } else if (flags & SHUTDOWN_DEVICE_REQ) {
229 xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
230 "All device paths lost. Shutting down filesystem: %s",
145 mp->m_fsname); 231 mp->m_fsname);
146 } else if (!(flags & XFS_SHUTDOWN_REMOTE_REQ)) { 232 } else if (!(flags & SHUTDOWN_REMOTE_REQ)) {
147 xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp, 233 xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
148 "I/O Error Detected. Shutting down filesystem: %s", 234 "I/O Error Detected. Shutting down filesystem: %s",
149 mp->m_fsname); 235 mp->m_fsname);
150 } 236 }
151 } 237 }
152 if (!(flags & XFS_FORCE_UMOUNT)) { 238 if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
153 cmn_err(CE_ALERT, 239 cmn_err(CE_ALERT, "Please umount the filesystem, "
154 "Please umount the filesystem, and rectify the problem(s)"); 240 "and rectify the problem(s)");
155 } 241 }
156} 242}
157 243
@@ -335,7 +421,7 @@ xfs_bwrite(
335 * from bwrite and we could be tracing a buffer that has 421 * from bwrite and we could be tracing a buffer that has
336 * been reused. 422 * been reused.
337 */ 423 */
338 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 424 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
339 } 425 }
340 return (error); 426 return (error);
341} 427}
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h
index e63795644478..188b296ff50c 100644
--- a/fs/xfs/xfs_rw.h
+++ b/fs/xfs/xfs_rw.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -75,6 +75,7 @@ xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb)
75 * Prototypes for functions in xfs_rw.c. 75 * Prototypes for functions in xfs_rw.c.
76 */ 76 */
77extern int xfs_write_clear_setuid(struct xfs_inode *ip); 77extern int xfs_write_clear_setuid(struct xfs_inode *ip);
78extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip);
78extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); 79extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
79extern int xfs_bioerror(struct xfs_buf *bp); 80extern int xfs_bioerror(struct xfs_buf *bp);
80extern int xfs_bioerror_relse(struct xfs_buf *bp); 81extern int xfs_bioerror_relse(struct xfs_buf *bp);
@@ -87,9 +88,10 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
87/* 88/*
88 * Prototypes for functions in xfs_vnodeops.c. 89 * Prototypes for functions in xfs_vnodeops.c.
89 */ 90 */
90extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock); 91extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
91extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock); 92extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
92extern int xfs_setattr(bhv_desc_t *bdp, vattr_t *vap, int flags, cred_t *credp); 93extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags,
94 cred_t *credp);
93extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf, 95extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf,
94 xfs_off_t offset, cred_t *credp, int flags); 96 xfs_off_t offset, cred_t *credp, int flags);
95extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state, 97extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 8d056cef5d1f..ee2721e0de4d 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -24,7 +24,6 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -236,11 +234,8 @@ xfs_trans_alloc(
236 xfs_mount_t *mp, 234 xfs_mount_t *mp,
237 uint type) 235 uint type)
238{ 236{
239 fs_check_frozen(XFS_MTOVFS(mp), SB_FREEZE_TRANS); 237 vfs_wait_for_freeze(XFS_MTOVFS(mp), SB_FREEZE_TRANS);
240 atomic_inc(&mp->m_active_trans); 238 return _xfs_trans_alloc(mp, type);
241
242 return (_xfs_trans_alloc(mp, type));
243
244} 239}
245 240
246xfs_trans_t * 241xfs_trans_t *
@@ -250,12 +245,9 @@ _xfs_trans_alloc(
250{ 245{
251 xfs_trans_t *tp; 246 xfs_trans_t *tp;
252 247
253 ASSERT(xfs_trans_zone != NULL); 248 atomic_inc(&mp->m_active_trans);
254 tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
255 249
256 /* 250 tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
257 * Initialize the transaction structure.
258 */
259 tp->t_magic = XFS_TRANS_MAGIC; 251 tp->t_magic = XFS_TRANS_MAGIC;
260 tp->t_type = type; 252 tp->t_type = type;
261 tp->t_mountp = mp; 253 tp->t_mountp = mp;
@@ -263,8 +255,7 @@ _xfs_trans_alloc(
263 tp->t_busy_free = XFS_LBC_NUM_SLOTS; 255 tp->t_busy_free = XFS_LBC_NUM_SLOTS;
264 XFS_LIC_INIT(&(tp->t_items)); 256 XFS_LIC_INIT(&(tp->t_items));
265 XFS_LBC_INIT(&(tp->t_busy)); 257 XFS_LBC_INIT(&(tp->t_busy));
266 258 return tp;
267 return (tp);
268} 259}
269 260
270/* 261/*
@@ -303,7 +294,7 @@ xfs_trans_dup(
303 tp->t_blk_res = tp->t_blk_res_used; 294 tp->t_blk_res = tp->t_blk_res_used;
304 ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; 295 ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
305 tp->t_rtx_res = tp->t_rtx_res_used; 296 tp->t_rtx_res = tp->t_rtx_res_used;
306 PFLAGS_DUP(&tp->t_pflags, &ntp->t_pflags); 297 ntp->t_pflags = tp->t_pflags;
307 298
308 XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp); 299 XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp);
309 300
@@ -335,14 +326,11 @@ xfs_trans_reserve(
335 uint logcount) 326 uint logcount)
336{ 327{
337 int log_flags; 328 int log_flags;
338 int error; 329 int error = 0;
339 int rsvd; 330 int rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
340
341 error = 0;
342 rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
343 331
344 /* Mark this thread as being in a transaction */ 332 /* Mark this thread as being in a transaction */
345 PFLAGS_SET_FSTRANS(&tp->t_pflags); 333 current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
346 334
347 /* 335 /*
348 * Attempt to reserve the needed disk blocks by decrementing 336 * Attempt to reserve the needed disk blocks by decrementing
@@ -353,7 +341,7 @@ xfs_trans_reserve(
353 error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, 341 error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
354 -blocks, rsvd); 342 -blocks, rsvd);
355 if (error != 0) { 343 if (error != 0) {
356 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 344 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
357 return (XFS_ERROR(ENOSPC)); 345 return (XFS_ERROR(ENOSPC));
358 } 346 }
359 tp->t_blk_res += blocks; 347 tp->t_blk_res += blocks;
@@ -426,9 +414,9 @@ undo_blocks:
426 tp->t_blk_res = 0; 414 tp->t_blk_res = 0;
427 } 415 }
428 416
429 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 417 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
430 418
431 return (error); 419 return error;
432} 420}
433 421
434 422
@@ -819,7 +807,7 @@ shut_us_down:
819 if (commit_lsn == -1 && !shutdown) 807 if (commit_lsn == -1 && !shutdown)
820 shutdown = XFS_ERROR(EIO); 808 shutdown = XFS_ERROR(EIO);
821 } 809 }
822 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 810 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
823 xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0); 811 xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
824 xfs_trans_free_busy(tp); 812 xfs_trans_free_busy(tp);
825 xfs_trans_free(tp); 813 xfs_trans_free(tp);
@@ -846,7 +834,7 @@ shut_us_down:
846 */ 834 */
847 nvec = xfs_trans_count_vecs(tp); 835 nvec = xfs_trans_count_vecs(tp);
848 if (nvec == 0) { 836 if (nvec == 0) {
849 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 837 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
850 goto shut_us_down; 838 goto shut_us_down;
851 } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) { 839 } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) {
852 log_vector = log_vector_fast; 840 log_vector = log_vector_fast;
@@ -884,7 +872,7 @@ shut_us_down:
884 * had pinned, clean up, free trans structure, and return error. 872 * had pinned, clean up, free trans structure, and return error.
885 */ 873 */
886 if (error || commit_lsn == -1) { 874 if (error || commit_lsn == -1) {
887 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 875 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
888 xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); 876 xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
889 return XFS_ERROR(EIO); 877 return XFS_ERROR(EIO);
890 } 878 }
@@ -926,7 +914,7 @@ shut_us_down:
926 /* 914 /*
927 * Mark this thread as no longer being in a transaction 915 * Mark this thread as no longer being in a transaction
928 */ 916 */
929 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 917 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
930 918
931 /* 919 /*
932 * Once all the items of the transaction have been copied 920 * Once all the items of the transaction have been copied
@@ -1148,7 +1136,7 @@ xfs_trans_cancel(
1148 */ 1136 */
1149 if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) { 1137 if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) {
1150 XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp); 1138 XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
1151 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 1139 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1152 } 1140 }
1153#ifdef DEBUG 1141#ifdef DEBUG
1154 if (!(flags & XFS_TRANS_ABORT)) { 1142 if (!(flags & XFS_TRANS_ABORT)) {
@@ -1182,7 +1170,7 @@ xfs_trans_cancel(
1182 } 1170 }
1183 1171
1184 /* mark this thread as no longer being in a transaction */ 1172 /* mark this thread as no longer being in a transaction */
1185 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 1173 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
1186 1174
1187 xfs_trans_free_items(tp, flags); 1175 xfs_trans_free_items(tp, flags);
1188 xfs_trans_free_busy(tp); 1176 xfs_trans_free_busy(tp);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 100d9a4b38ee..cb65c3a603f5 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -805,12 +805,9 @@ typedef struct xfs_trans {
805 ((mp)->m_sb.sb_inodesize + \ 805 ((mp)->m_sb.sb_inodesize + \
806 (mp)->m_sb.sb_sectsize * 2 + \ 806 (mp)->m_sb.sb_sectsize * 2 + \
807 (mp)->m_dirblksize + \ 807 (mp)->m_dirblksize + \
808 (XFS_DIR_IS_V1(mp) ? 0 : \ 808 XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \
809 XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \
810 XFS_ALLOCFREE_LOG_RES(mp, 1) + \ 809 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
811 (128 * (4 + \ 810 (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
812 (XFS_DIR_IS_V1(mp) ? 0 : \
813 XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
814 XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) 811 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
815 812
816#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) 813#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 19ab24af1c1c..558c87ff0c41 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -22,7 +22,6 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dmapi.h" 25#include "xfs_dmapi.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_trans_priv.h" 27#include "xfs_trans_priv.h"
@@ -363,9 +362,10 @@ xfs_trans_delete_ail(
363 AIL_UNLOCK(mp, s); 362 AIL_UNLOCK(mp, s);
364 else { 363 else {
365 xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, 364 xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp,
366 "xfs_trans_delete_ail: attempting to delete a log item that is not in the AIL"); 365 "%s: attempting to delete a log item that is not in the AIL",
366 __FUNCTION__);
367 AIL_UNLOCK(mp, s); 367 AIL_UNLOCK(mp, s);
368 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 368 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
369 } 369 }
370 } 370 }
371} 371}
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index c74c31ebc81c..60b6b898022b 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -320,7 +318,7 @@ xfs_trans_read_buf(
320 if (xfs_error_target == target) { 318 if (xfs_error_target == target) {
321 if (((xfs_req_num++) % xfs_error_mod) == 0) { 319 if (((xfs_req_num++) % xfs_error_mod) == 0) {
322 xfs_buf_relse(bp); 320 xfs_buf_relse(bp);
323 printk("Returning error!\n"); 321 cmn_err(CE_DEBUG, "Returning error!\n");
324 return XFS_ERROR(EIO); 322 return XFS_ERROR(EIO);
325 } 323 }
326 } 324 }
@@ -369,7 +367,7 @@ xfs_trans_read_buf(
369 */ 367 */
370 if (tp->t_flags & XFS_TRANS_DIRTY) 368 if (tp->t_flags & XFS_TRANS_DIRTY)
371 xfs_force_shutdown(tp->t_mountp, 369 xfs_force_shutdown(tp->t_mountp,
372 XFS_METADATA_IO_ERROR); 370 SHUTDOWN_META_IO_ERROR);
373 return error; 371 return error;
374 } 372 }
375 } 373 }
@@ -414,7 +412,7 @@ xfs_trans_read_buf(
414 xfs_ioerror_alert("xfs_trans_read_buf", mp, 412 xfs_ioerror_alert("xfs_trans_read_buf", mp,
415 bp, blkno); 413 bp, blkno);
416 if (tp->t_flags & XFS_TRANS_DIRTY) 414 if (tp->t_flags & XFS_TRANS_DIRTY)
417 xfs_force_shutdown(tp->t_mountp, XFS_METADATA_IO_ERROR); 415 xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
418 xfs_buf_relse(bp); 416 xfs_buf_relse(bp);
419 return error; 417 return error;
420 } 418 }
@@ -423,9 +421,9 @@ xfs_trans_read_buf(
423 if (xfs_error_target == target) { 421 if (xfs_error_target == target) {
424 if (((xfs_req_num++) % xfs_error_mod) == 0) { 422 if (((xfs_req_num++) % xfs_error_mod) == 0) {
425 xfs_force_shutdown(tp->t_mountp, 423 xfs_force_shutdown(tp->t_mountp,
426 XFS_METADATA_IO_ERROR); 424 SHUTDOWN_META_IO_ERROR);
427 xfs_buf_relse(bp); 425 xfs_buf_relse(bp);
428 printk("Returning error in trans!\n"); 426 cmn_err(CE_DEBUG, "Returning trans error!\n");
429 return XFS_ERROR(EIO); 427 return XFS_ERROR(EIO);
430 } 428 }
431 } 429 }
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c
index 7d7d627f25df..b290270dd4a6 100644
--- a/fs/xfs/xfs_trans_extfree.c
+++ b/fs/xfs/xfs_trans_extfree.c
@@ -22,7 +22,6 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dmapi.h" 25#include "xfs_dmapi.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_trans_priv.h" 27#include "xfs_trans_priv.h"
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index 7c5894d59f81..b8db1d5cde5a 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -24,14 +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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c
index 1117d600d741..2912aac07c7b 100644
--- a/fs/xfs/xfs_trans_item.c
+++ b/fs/xfs/xfs_trans_item.c
@@ -493,7 +493,7 @@ xfs_trans_add_busy(xfs_trans_t *tp, xfs_agnumber_t ag, xfs_extlen_t idx)
493 break; 493 break;
494 } else { 494 } else {
495 /* out-of-order vacancy */ 495 /* out-of-order vacancy */
496 printk("OOO vacancy lbcp 0x%p\n", lbcp); 496 cmn_err(CE_DEBUG, "OOO vacancy lbcp 0x%p\n", lbcp);
497 ASSERT(0); 497 ASSERT(0);
498 } 498 }
499 } 499 }
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h
index 7fe3792b18df..4ea2e5074bdd 100644
--- a/fs/xfs/xfs_trans_space.h
+++ b/fs/xfs/xfs_trans_space.h
@@ -30,8 +30,7 @@
30 XFS_EXTENTADD_SPACE_RES(mp,w)) 30 XFS_EXTENTADD_SPACE_RES(mp,w))
31#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) 31#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1)
32#define XFS_DAENTER_DBS(mp,w) \ 32#define XFS_DAENTER_DBS(mp,w) \
33 (XFS_DA_NODE_MAXDEPTH + \ 33 (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0))
34 ((XFS_DIR_IS_V2(mp) && (w) == XFS_DATA_FORK) ? 2 : 0))
35#define XFS_DAENTER_BLOCKS(mp,w) \ 34#define XFS_DAENTER_BLOCKS(mp,w) \
36 (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w)) 35 (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w))
37#define XFS_DAENTER_BMAP1B(mp,w) \ 36#define XFS_DAENTER_BMAP1B(mp,w) \
@@ -41,10 +40,7 @@
41#define XFS_DAENTER_SPACE_RES(mp,w) \ 40#define XFS_DAENTER_SPACE_RES(mp,w) \
42 (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w)) 41 (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w))
43#define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w) 42#define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w)
44#define XFS_DIRENTER_MAX_SPLIT(mp,nl) \ 43#define XFS_DIRENTER_MAX_SPLIT(mp,nl) 1
45 (((mp)->m_sb.sb_blocksize == 512 && \
46 XFS_DIR_IS_V1(mp) && \
47 (nl) >= XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN) ? 2 : 1)
48#define XFS_DIRENTER_SPACE_RES(mp,nl) \ 44#define XFS_DIRENTER_SPACE_RES(mp,nl) \
49 (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \ 45 (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \
50 XFS_DIRENTER_MAX_SPLIT(mp,nl)) 46 XFS_DIRENTER_MAX_SPLIT(mp,nl))
@@ -57,8 +53,7 @@
57 * Space reservation values for various transactions. 53 * Space reservation values for various transactions.
58 */ 54 */
59#define XFS_ADDAFORK_SPACE_RES(mp) \ 55#define XFS_ADDAFORK_SPACE_RES(mp) \
60 ((mp)->m_dirblkfsbs + \ 56 ((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))
61 (XFS_DIR_IS_V1(mp) ? 0 : XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)))
62#define XFS_ATTRRM_SPACE_RES(mp) \ 57#define XFS_ATTRRM_SPACE_RES(mp) \
63 XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) 58 XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK)
64/* This macro is not used - see inline code in xfs_attr_set */ 59/* This macro is not used - see inline code in xfs_attr_set */
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 34654ec6ae10..9014d7e44488 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -24,12 +24,10 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_dir_sf.h"
33#include "xfs_dir2_sf.h" 31#include "xfs_dir2_sf.h"
34#include "xfs_attr_sf.h" 32#include "xfs_attr_sf.h"
35#include "xfs_dinode.h" 33#include "xfs_dinode.h"
@@ -51,10 +49,10 @@
51 */ 49 */
52int 50int
53xfs_get_dir_entry( 51xfs_get_dir_entry(
54 vname_t *dentry, 52 bhv_vname_t *dentry,
55 xfs_inode_t **ipp) 53 xfs_inode_t **ipp)
56{ 54{
57 vnode_t *vp; 55 bhv_vnode_t *vp;
58 56
59 vp = VNAME_TO_VNODE(dentry); 57 vp = VNAME_TO_VNODE(dentry);
60 58
@@ -69,11 +67,11 @@ int
69xfs_dir_lookup_int( 67xfs_dir_lookup_int(
70 bhv_desc_t *dir_bdp, 68 bhv_desc_t *dir_bdp,
71 uint lock_mode, 69 uint lock_mode,
72 vname_t *dentry, 70 bhv_vname_t *dentry,
73 xfs_ino_t *inum, 71 xfs_ino_t *inum,
74 xfs_inode_t **ipp) 72 xfs_inode_t **ipp)
75{ 73{
76 vnode_t *dir_vp; 74 bhv_vnode_t *dir_vp;
77 xfs_inode_t *dp; 75 xfs_inode_t *dp;
78 int error; 76 int error;
79 77
@@ -82,8 +80,7 @@ xfs_dir_lookup_int(
82 80
83 dp = XFS_BHVTOI(dir_bdp); 81 dp = XFS_BHVTOI(dir_bdp);
84 82
85 error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp, 83 error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum);
86 VNAME(dentry), VNAMELEN(dentry), inum);
87 if (!error) { 84 if (!error) {
88 /* 85 /*
89 * Unlock the directory. We do this because we can't 86 * Unlock the directory. We do this because we can't
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index 472661a3b6d8..fe953e98afa7 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -23,9 +23,10 @@
23#define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \ 23#define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \
24 (inst_t *)__return_address) 24 (inst_t *)__return_address)
25 25
26extern int xfs_rename (bhv_desc_t *, vname_t *, vnode_t *, vname_t *, cred_t *); 26extern int xfs_rename (bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
27extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **); 27 bhv_vname_t *, cred_t *);
28extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, 28extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **);
29extern int xfs_dir_lookup_int (bhv_desc_t *, uint, bhv_vname_t *, xfs_ino_t *,
29 xfs_inode_t **); 30 xfs_inode_t **);
30extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); 31extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
31extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, 32extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t,
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 36ea1b2094f2..6c96391f3f1a 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -24,7 +24,6 @@
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_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -131,9 +129,6 @@ xfs_init(void)
131#ifdef XFS_BMBT_TRACE 129#ifdef XFS_BMBT_TRACE
132 xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP); 130 xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP);
133#endif 131#endif
134#ifdef XFS_DIR_TRACE
135 xfs_dir_trace_buf = ktrace_alloc(XFS_DIR_TRACE_SIZE, KM_SLEEP);
136#endif
137#ifdef XFS_ATTR_TRACE 132#ifdef XFS_ATTR_TRACE
138 xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP); 133 xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP);
139#endif 134#endif
@@ -177,9 +172,6 @@ xfs_cleanup(void)
177#ifdef XFS_ATTR_TRACE 172#ifdef XFS_ATTR_TRACE
178 ktrace_free(xfs_attr_trace_buf); 173 ktrace_free(xfs_attr_trace_buf);
179#endif 174#endif
180#ifdef XFS_DIR_TRACE
181 ktrace_free(xfs_dir_trace_buf);
182#endif
183#ifdef XFS_BMBT_TRACE 175#ifdef XFS_BMBT_TRACE
184 ktrace_free(xfs_bmbt_trace_buf); 176 ktrace_free(xfs_bmbt_trace_buf);
185#endif 177#endif
@@ -212,7 +204,7 @@ xfs_cleanup(void)
212 */ 204 */
213STATIC int 205STATIC int
214xfs_start_flags( 206xfs_start_flags(
215 struct vfs *vfs, 207 struct bhv_vfs *vfs,
216 struct xfs_mount_args *ap, 208 struct xfs_mount_args *ap,
217 struct xfs_mount *mp) 209 struct xfs_mount *mp)
218{ 210{
@@ -337,7 +329,7 @@ xfs_start_flags(
337 */ 329 */
338STATIC int 330STATIC int
339xfs_finish_flags( 331xfs_finish_flags(
340 struct vfs *vfs, 332 struct bhv_vfs *vfs,
341 struct xfs_mount_args *ap, 333 struct xfs_mount_args *ap,
342 struct xfs_mount *mp) 334 struct xfs_mount *mp)
343{ 335{
@@ -423,7 +415,7 @@ xfs_mount(
423 struct xfs_mount_args *args, 415 struct xfs_mount_args *args,
424 cred_t *credp) 416 cred_t *credp)
425{ 417{
426 struct vfs *vfsp = bhvtovfs(bhvp); 418 struct bhv_vfs *vfsp = bhvtovfs(bhvp);
427 struct bhv_desc *p; 419 struct bhv_desc *p;
428 struct xfs_mount *mp = XFS_BHVTOM(bhvp); 420 struct xfs_mount *mp = XFS_BHVTOM(bhvp);
429 struct block_device *ddev, *logdev, *rtdev; 421 struct block_device *ddev, *logdev, *rtdev;
@@ -552,10 +544,10 @@ xfs_unmount(
552 int flags, 544 int flags,
553 cred_t *credp) 545 cred_t *credp)
554{ 546{
555 struct vfs *vfsp = bhvtovfs(bdp); 547 bhv_vfs_t *vfsp = bhvtovfs(bdp);
556 xfs_mount_t *mp = XFS_BHVTOM(bdp); 548 xfs_mount_t *mp = XFS_BHVTOM(bdp);
557 xfs_inode_t *rip; 549 xfs_inode_t *rip;
558 vnode_t *rvp; 550 bhv_vnode_t *rvp;
559 int unmount_event_wanted = 0; 551 int unmount_event_wanted = 0;
560 int unmount_event_flags = 0; 552 int unmount_event_flags = 0;
561 int xfs_unmountfs_needed = 0; 553 int xfs_unmountfs_needed = 0;
@@ -665,9 +657,8 @@ xfs_mntupdate(
665 int *flags, 657 int *flags,
666 struct xfs_mount_args *args) 658 struct xfs_mount_args *args)
667{ 659{
668 struct vfs *vfsp = bhvtovfs(bdp); 660 bhv_vfs_t *vfsp = bhvtovfs(bdp);
669 xfs_mount_t *mp = XFS_BHVTOM(bdp); 661 xfs_mount_t *mp = XFS_BHVTOM(bdp);
670 int error;
671 662
672 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ 663 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */
673 if (vfsp->vfs_flag & VFS_RDONLY) 664 if (vfsp->vfs_flag & VFS_RDONLY)
@@ -679,7 +670,7 @@ xfs_mntupdate(
679 mp->m_flags &= ~XFS_MOUNT_BARRIER; 670 mp->m_flags &= ~XFS_MOUNT_BARRIER;
680 } 671 }
681 } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ 672 } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */
682 VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error); 673 bhv_vfs_sync(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL);
683 xfs_quiesce_fs(mp); 674 xfs_quiesce_fs(mp);
684 xfs_log_unmount_write(mp); 675 xfs_log_unmount_write(mp);
685 xfs_unmountfs_writesb(mp); 676 xfs_unmountfs_writesb(mp);
@@ -702,7 +693,7 @@ xfs_unmount_flush(
702 xfs_inode_t *rip = mp->m_rootip; 693 xfs_inode_t *rip = mp->m_rootip;
703 xfs_inode_t *rbmip; 694 xfs_inode_t *rbmip;
704 xfs_inode_t *rsumip = NULL; 695 xfs_inode_t *rsumip = NULL;
705 vnode_t *rvp = XFS_ITOV(rip); 696 bhv_vnode_t *rvp = XFS_ITOV(rip);
706 int error; 697 int error;
707 698
708 xfs_ilock(rip, XFS_ILOCK_EXCL); 699 xfs_ilock(rip, XFS_ILOCK_EXCL);
@@ -781,9 +772,9 @@ fscorrupt_out2:
781STATIC int 772STATIC int
782xfs_root( 773xfs_root(
783 bhv_desc_t *bdp, 774 bhv_desc_t *bdp,
784 vnode_t **vpp) 775 bhv_vnode_t **vpp)
785{ 776{
786 vnode_t *vp; 777 bhv_vnode_t *vp;
787 778
788 vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); 779 vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip);
789 VN_HOLD(vp); 780 VN_HOLD(vp);
@@ -801,8 +792,8 @@ xfs_root(
801STATIC int 792STATIC int
802xfs_statvfs( 793xfs_statvfs(
803 bhv_desc_t *bdp, 794 bhv_desc_t *bdp,
804 xfs_statfs_t *statp, 795 bhv_statvfs_t *statp,
805 vnode_t *vp) 796 bhv_vnode_t *vp)
806{ 797{
807 __uint64_t fakeinos; 798 __uint64_t fakeinos;
808 xfs_extlen_t lsize; 799 xfs_extlen_t lsize;
@@ -900,7 +891,7 @@ xfs_sync(
900/* 891/*
901 * xfs sync routine for internal use 892 * xfs sync routine for internal use
902 * 893 *
903 * This routine supports all of the flags defined for the generic VFS_SYNC 894 * This routine supports all of the flags defined for the generic vfs_sync
904 * interface as explained above under xfs_sync. In the interests of not 895 * interface as explained above under xfs_sync. In the interests of not
905 * changing interfaces within the 6.5 family, additional internally- 896 * changing interfaces within the 6.5 family, additional internally-
906 * required functions are specified within a separate xflags parameter, 897 * required functions are specified within a separate xflags parameter,
@@ -917,7 +908,7 @@ xfs_sync_inodes(
917 xfs_inode_t *ip = NULL; 908 xfs_inode_t *ip = NULL;
918 xfs_inode_t *ip_next; 909 xfs_inode_t *ip_next;
919 xfs_buf_t *bp; 910 xfs_buf_t *bp;
920 vnode_t *vp = NULL; 911 bhv_vnode_t *vp = NULL;
921 int error; 912 int error;
922 int last_error; 913 int last_error;
923 uint64_t fflag; 914 uint64_t fflag;
@@ -1156,9 +1147,9 @@ xfs_sync_inodes(
1156 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1147 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1157 1148
1158 if (XFS_FORCED_SHUTDOWN(mp)) { 1149 if (XFS_FORCED_SHUTDOWN(mp)) {
1159 VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF); 1150 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
1160 } else { 1151 } else {
1161 VOP_FLUSHINVAL_PAGES(vp, 0, -1, FI_REMAPF); 1152 bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF);
1162 } 1153 }
1163 1154
1164 xfs_ilock(ip, XFS_ILOCK_SHARED); 1155 xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -1178,8 +1169,8 @@ xfs_sync_inodes(
1178 * across calls to the buffer cache. 1169 * across calls to the buffer cache.
1179 */ 1170 */
1180 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1171 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1181 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 1172 error = bhv_vop_flush_pages(vp, (xfs_off_t)0,
1182 fflag, FI_NONE, error); 1173 -1, fflag, FI_NONE);
1183 xfs_ilock(ip, XFS_ILOCK_SHARED); 1174 xfs_ilock(ip, XFS_ILOCK_SHARED);
1184 } 1175 }
1185 1176
@@ -1231,9 +1222,7 @@ xfs_sync_inodes(
1231 * marker and free it. 1222 * marker and free it.
1232 */ 1223 */
1233 XFS_MOUNT_ILOCK(mp); 1224 XFS_MOUNT_ILOCK(mp);
1234
1235 IPOINTER_REMOVE(ip, mp); 1225 IPOINTER_REMOVE(ip, mp);
1236
1237 XFS_MOUNT_IUNLOCK(mp); 1226 XFS_MOUNT_IUNLOCK(mp);
1238 1227
1239 ASSERT(!(lock_flags & 1228 ASSERT(!(lock_flags &
@@ -1421,7 +1410,7 @@ xfs_sync_inodes(
1421/* 1410/*
1422 * xfs sync routine for internal use 1411 * xfs sync routine for internal use
1423 * 1412 *
1424 * This routine supports all of the flags defined for the generic VFS_SYNC 1413 * This routine supports all of the flags defined for the generic vfs_sync
1425 * interface as explained above under xfs_sync. In the interests of not 1414 * interface as explained above under xfs_sync. In the interests of not
1426 * changing interfaces within the 6.5 family, additional internally- 1415 * changing interfaces within the 6.5 family, additional internally-
1427 * required functions are specified within a separate xflags parameter, 1416 * required functions are specified within a separate xflags parameter,
@@ -1574,7 +1563,7 @@ xfs_syncsub(
1574STATIC int 1563STATIC int
1575xfs_vget( 1564xfs_vget(
1576 bhv_desc_t *bdp, 1565 bhv_desc_t *bdp,
1577 vnode_t **vpp, 1566 bhv_vnode_t **vpp,
1578 fid_t *fidp) 1567 fid_t *fidp)
1579{ 1568{
1580 xfs_mount_t *mp = XFS_BHVTOM(bdp); 1569 xfs_mount_t *mp = XFS_BHVTOM(bdp);
@@ -1657,10 +1646,10 @@ xfs_vget(
1657#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ 1646#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
1658 1647
1659STATIC unsigned long 1648STATIC unsigned long
1660suffix_strtoul(const char *cp, char **endp, unsigned int base) 1649suffix_strtoul(char *s, char **endp, unsigned int base)
1661{ 1650{
1662 int last, shift_left_factor = 0; 1651 int last, shift_left_factor = 0;
1663 char *value = (char *)cp; 1652 char *value = s;
1664 1653
1665 last = strlen(value) - 1; 1654 last = strlen(value) - 1;
1666 if (value[last] == 'K' || value[last] == 'k') { 1655 if (value[last] == 'K' || value[last] == 'k') {
@@ -1676,7 +1665,7 @@ suffix_strtoul(const char *cp, char **endp, unsigned int base)
1676 value[last] = '\0'; 1665 value[last] = '\0';
1677 } 1666 }
1678 1667
1679 return simple_strtoul(cp, endp, base) << shift_left_factor; 1668 return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
1680} 1669}
1681 1670
1682STATIC int 1671STATIC int
@@ -1686,7 +1675,7 @@ xfs_parseargs(
1686 struct xfs_mount_args *args, 1675 struct xfs_mount_args *args,
1687 int update) 1676 int update)
1688{ 1677{
1689 struct vfs *vfsp = bhvtovfs(bhv); 1678 bhv_vfs_t *vfsp = bhvtovfs(bhv);
1690 char *this_char, *value, *eov; 1679 char *this_char, *value, *eov;
1691 int dsunit, dswidth, vol_dsunit, vol_dswidth; 1680 int dsunit, dswidth, vol_dsunit, vol_dswidth;
1692 int iosize; 1681 int iosize;
@@ -1708,42 +1697,48 @@ xfs_parseargs(
1708 1697
1709 if (!strcmp(this_char, MNTOPT_LOGBUFS)) { 1698 if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
1710 if (!value || !*value) { 1699 if (!value || !*value) {
1711 printk("XFS: %s option requires an argument\n", 1700 cmn_err(CE_WARN,
1701 "XFS: %s option requires an argument",
1712 this_char); 1702 this_char);
1713 return EINVAL; 1703 return EINVAL;
1714 } 1704 }
1715 args->logbufs = simple_strtoul(value, &eov, 10); 1705 args->logbufs = simple_strtoul(value, &eov, 10);
1716 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { 1706 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
1717 if (!value || !*value) { 1707 if (!value || !*value) {
1718 printk("XFS: %s option requires an argument\n", 1708 cmn_err(CE_WARN,
1709 "XFS: %s option requires an argument",
1719 this_char); 1710 this_char);
1720 return EINVAL; 1711 return EINVAL;
1721 } 1712 }
1722 args->logbufsize = suffix_strtoul(value, &eov, 10); 1713 args->logbufsize = suffix_strtoul(value, &eov, 10);
1723 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { 1714 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
1724 if (!value || !*value) { 1715 if (!value || !*value) {
1725 printk("XFS: %s option requires an argument\n", 1716 cmn_err(CE_WARN,
1717 "XFS: %s option requires an argument",
1726 this_char); 1718 this_char);
1727 return EINVAL; 1719 return EINVAL;
1728 } 1720 }
1729 strncpy(args->logname, value, MAXNAMELEN); 1721 strncpy(args->logname, value, MAXNAMELEN);
1730 } else if (!strcmp(this_char, MNTOPT_MTPT)) { 1722 } else if (!strcmp(this_char, MNTOPT_MTPT)) {
1731 if (!value || !*value) { 1723 if (!value || !*value) {
1732 printk("XFS: %s option requires an argument\n", 1724 cmn_err(CE_WARN,
1725 "XFS: %s option requires an argument",
1733 this_char); 1726 this_char);
1734 return EINVAL; 1727 return EINVAL;
1735 } 1728 }
1736 strncpy(args->mtpt, value, MAXNAMELEN); 1729 strncpy(args->mtpt, value, MAXNAMELEN);
1737 } else if (!strcmp(this_char, MNTOPT_RTDEV)) { 1730 } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
1738 if (!value || !*value) { 1731 if (!value || !*value) {
1739 printk("XFS: %s option requires an argument\n", 1732 cmn_err(CE_WARN,
1733 "XFS: %s option requires an argument",
1740 this_char); 1734 this_char);
1741 return EINVAL; 1735 return EINVAL;
1742 } 1736 }
1743 strncpy(args->rtname, value, MAXNAMELEN); 1737 strncpy(args->rtname, value, MAXNAMELEN);
1744 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { 1738 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
1745 if (!value || !*value) { 1739 if (!value || !*value) {
1746 printk("XFS: %s option requires an argument\n", 1740 cmn_err(CE_WARN,
1741 "XFS: %s option requires an argument",
1747 this_char); 1742 this_char);
1748 return EINVAL; 1743 return EINVAL;
1749 } 1744 }
@@ -1752,7 +1747,8 @@ xfs_parseargs(
1752 args->iosizelog = (uint8_t) iosize; 1747 args->iosizelog = (uint8_t) iosize;
1753 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { 1748 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
1754 if (!value || !*value) { 1749 if (!value || !*value) {
1755 printk("XFS: %s option requires an argument\n", 1750 cmn_err(CE_WARN,
1751 "XFS: %s option requires an argument",
1756 this_char); 1752 this_char);
1757 return EINVAL; 1753 return EINVAL;
1758 } 1754 }
@@ -1761,7 +1757,8 @@ xfs_parseargs(
1761 args->iosizelog = ffs(iosize) - 1; 1757 args->iosizelog = ffs(iosize) - 1;
1762 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { 1758 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
1763 if (!value || !*value) { 1759 if (!value || !*value) {
1764 printk("XFS: %s option requires an argument\n", 1760 cmn_err(CE_WARN,
1761 "XFS: %s option requires an argument",
1765 this_char); 1762 this_char);
1766 return EINVAL; 1763 return EINVAL;
1767 } 1764 }
@@ -1782,7 +1779,8 @@ xfs_parseargs(
1782 } else if (!strcmp(this_char, MNTOPT_INO64)) { 1779 } else if (!strcmp(this_char, MNTOPT_INO64)) {
1783 args->flags |= XFSMNT_INO64; 1780 args->flags |= XFSMNT_INO64;
1784#if !XFS_BIG_INUMS 1781#if !XFS_BIG_INUMS
1785 printk("XFS: %s option not allowed on this system\n", 1782 cmn_err(CE_WARN,
1783 "XFS: %s option not allowed on this system",
1786 this_char); 1784 this_char);
1787 return EINVAL; 1785 return EINVAL;
1788#endif 1786#endif
@@ -1792,14 +1790,16 @@ xfs_parseargs(
1792 args->flags |= XFSMNT_SWALLOC; 1790 args->flags |= XFSMNT_SWALLOC;
1793 } else if (!strcmp(this_char, MNTOPT_SUNIT)) { 1791 } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
1794 if (!value || !*value) { 1792 if (!value || !*value) {
1795 printk("XFS: %s option requires an argument\n", 1793 cmn_err(CE_WARN,
1794 "XFS: %s option requires an argument",
1796 this_char); 1795 this_char);
1797 return EINVAL; 1796 return EINVAL;
1798 } 1797 }
1799 dsunit = simple_strtoul(value, &eov, 10); 1798 dsunit = simple_strtoul(value, &eov, 10);
1800 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { 1799 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
1801 if (!value || !*value) { 1800 if (!value || !*value) {
1802 printk("XFS: %s option requires an argument\n", 1801 cmn_err(CE_WARN,
1802 "XFS: %s option requires an argument",
1803 this_char); 1803 this_char);
1804 return EINVAL; 1804 return EINVAL;
1805 } 1805 }
@@ -1807,7 +1807,8 @@ xfs_parseargs(
1807 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { 1807 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
1808 args->flags &= ~XFSMNT_32BITINODES; 1808 args->flags &= ~XFSMNT_32BITINODES;
1809#if !XFS_BIG_INUMS 1809#if !XFS_BIG_INUMS
1810 printk("XFS: %s option not allowed on this system\n", 1810 cmn_err(CE_WARN,
1811 "XFS: %s option not allowed on this system",
1811 this_char); 1812 this_char);
1812 return EINVAL; 1813 return EINVAL;
1813#endif 1814#endif
@@ -1831,36 +1832,41 @@ xfs_parseargs(
1831 args->flags &= ~XFSMNT_ATTR2; 1832 args->flags &= ~XFSMNT_ATTR2;
1832 } else if (!strcmp(this_char, "osyncisdsync")) { 1833 } else if (!strcmp(this_char, "osyncisdsync")) {
1833 /* no-op, this is now the default */ 1834 /* no-op, this is now the default */
1834printk("XFS: osyncisdsync is now the default, option is deprecated.\n"); 1835 cmn_err(CE_WARN,
1836 "XFS: osyncisdsync is now the default, option is deprecated.");
1835 } else if (!strcmp(this_char, "irixsgid")) { 1837 } else if (!strcmp(this_char, "irixsgid")) {
1836printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n"); 1838 cmn_err(CE_WARN,
1839 "XFS: irixsgid is now a sysctl(2) variable, option is deprecated.");
1837 } else { 1840 } else {
1838 printk("XFS: unknown mount option [%s].\n", this_char); 1841 cmn_err(CE_WARN,
1842 "XFS: unknown mount option [%s].", this_char);
1839 return EINVAL; 1843 return EINVAL;
1840 } 1844 }
1841 } 1845 }
1842 1846
1843 if (args->flags & XFSMNT_NORECOVERY) { 1847 if (args->flags & XFSMNT_NORECOVERY) {
1844 if ((vfsp->vfs_flag & VFS_RDONLY) == 0) { 1848 if ((vfsp->vfs_flag & VFS_RDONLY) == 0) {
1845 printk("XFS: no-recovery mounts must be read-only.\n"); 1849 cmn_err(CE_WARN,
1850 "XFS: no-recovery mounts must be read-only.");
1846 return EINVAL; 1851 return EINVAL;
1847 } 1852 }
1848 } 1853 }
1849 1854
1850 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { 1855 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
1851 printk( 1856 cmn_err(CE_WARN,
1852 "XFS: sunit and swidth options incompatible with the noalign option\n"); 1857 "XFS: sunit and swidth options incompatible with the noalign option");
1853 return EINVAL; 1858 return EINVAL;
1854 } 1859 }
1855 1860
1856 if ((dsunit && !dswidth) || (!dsunit && dswidth)) { 1861 if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
1857 printk("XFS: sunit and swidth must be specified together\n"); 1862 cmn_err(CE_WARN,
1863 "XFS: sunit and swidth must be specified together");
1858 return EINVAL; 1864 return EINVAL;
1859 } 1865 }
1860 1866
1861 if (dsunit && (dswidth % dsunit != 0)) { 1867 if (dsunit && (dswidth % dsunit != 0)) {
1862 printk( 1868 cmn_err(CE_WARN,
1863 "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)\n", 1869 "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)",
1864 dswidth, dsunit); 1870 dswidth, dsunit);
1865 return EINVAL; 1871 return EINVAL;
1866 } 1872 }
@@ -1907,7 +1913,7 @@ xfs_showargs(
1907 }; 1913 };
1908 struct proc_xfs_info *xfs_infop; 1914 struct proc_xfs_info *xfs_infop;
1909 struct xfs_mount *mp = XFS_BHVTOM(bhv); 1915 struct xfs_mount *mp = XFS_BHVTOM(bhv);
1910 struct vfs *vfsp = XFS_MTOVFS(mp); 1916 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1911 1917
1912 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { 1918 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
1913 if (mp->m_flags & xfs_infop->flag) 1919 if (mp->m_flags & xfs_infop->flag)
@@ -1967,7 +1973,7 @@ xfs_freeze(
1967} 1973}
1968 1974
1969 1975
1970vfsops_t xfs_vfsops = { 1976bhv_vfsops_t xfs_vfsops = {
1971 BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS), 1977 BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
1972 .vfs_parseargs = xfs_parseargs, 1978 .vfs_parseargs = xfs_parseargs,
1973 .vfs_showargs = xfs_showargs, 1979 .vfs_showargs = xfs_showargs,
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 7027ae68ee38..00a6b7dc24a0 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -16,8 +16,6 @@
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
19#include <linux/capability.h>
20
21#include "xfs.h" 19#include "xfs.h"
22#include "xfs_fs.h" 20#include "xfs_fs.h"
23#include "xfs_types.h" 21#include "xfs_types.h"
@@ -27,7 +25,6 @@
27#include "xfs_trans.h" 25#include "xfs_trans.h"
28#include "xfs_sb.h" 26#include "xfs_sb.h"
29#include "xfs_ag.h" 27#include "xfs_ag.h"
30#include "xfs_dir.h"
31#include "xfs_dir2.h" 28#include "xfs_dir2.h"
32#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
33#include "xfs_mount.h" 30#include "xfs_mount.h"
@@ -35,13 +32,11 @@
35#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
36#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
37#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
38#include "xfs_dir_sf.h"
39#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
40#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
41#include "xfs_dinode.h" 37#include "xfs_dinode.h"
42#include "xfs_inode.h" 38#include "xfs_inode.h"
43#include "xfs_inode_item.h" 39#include "xfs_inode_item.h"
44#include "xfs_dir_leaf.h"
45#include "xfs_itable.h" 40#include "xfs_itable.h"
46#include "xfs_btree.h" 41#include "xfs_btree.h"
47#include "xfs_ialloc.h" 42#include "xfs_ialloc.h"
@@ -58,32 +53,14 @@
58#include "xfs_log_priv.h" 53#include "xfs_log_priv.h"
59#include "xfs_mac.h" 54#include "xfs_mac.h"
60 55
61
62/*
63 * The maximum pathlen is 1024 bytes. Since the minimum file system
64 * blocksize is 512 bytes, we can get a max of 2 extents back from
65 * bmapi.
66 */
67#define SYMLINK_MAPS 2
68
69/*
70 * For xfs, we check that the file isn't too big to be opened by this kernel.
71 * No other open action is required for regular files. Devices are handled
72 * through the specfs file system, pipes through fifofs. Device and
73 * fifo vnodes are "wrapped" by specfs and fifofs vnodes, respectively,
74 * when a new vnode is first looked up or created.
75 */
76STATIC int 56STATIC int
77xfs_open( 57xfs_open(
78 bhv_desc_t *bdp, 58 bhv_desc_t *bdp,
79 cred_t *credp) 59 cred_t *credp)
80{ 60{
81 int mode; 61 int mode;
82 vnode_t *vp; 62 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
83 xfs_inode_t *ip; 63 xfs_inode_t *ip = XFS_BHVTOI(bdp);
84
85 vp = BHV_TO_VNODE(bdp);
86 ip = XFS_BHVTOI(bdp);
87 64
88 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 65 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
89 return XFS_ERROR(EIO); 66 return XFS_ERROR(EIO);
@@ -101,6 +78,35 @@ xfs_open(
101 return 0; 78 return 0;
102} 79}
103 80
81STATIC int
82xfs_close(
83 bhv_desc_t *bdp,
84 int flags,
85 lastclose_t lastclose,
86 cred_t *credp)
87{
88 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
89 xfs_inode_t *ip = XFS_BHVTOI(bdp);
90
91 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
92 return XFS_ERROR(EIO);
93
94 if (lastclose != L_TRUE || !VN_ISREG(vp))
95 return 0;
96
97 /*
98 * If we previously truncated this file and removed old data in
99 * the process, we want to initiate "early" writeout on the last
100 * close. This is an attempt to combat the notorious NULL files
101 * problem which is particularly noticable from a truncate down,
102 * buffered (re-)write (delalloc), followed by a crash. What we
103 * are effectively doing here is significantly reducing the time
104 * window where we'd otherwise be exposed to that problem.
105 */
106 if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0)
107 return bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE);
108 return 0;
109}
104 110
105/* 111/*
106 * xfs_getattr 112 * xfs_getattr
@@ -108,13 +114,13 @@ xfs_open(
108STATIC int 114STATIC int
109xfs_getattr( 115xfs_getattr(
110 bhv_desc_t *bdp, 116 bhv_desc_t *bdp,
111 vattr_t *vap, 117 bhv_vattr_t *vap,
112 int flags, 118 int flags,
113 cred_t *credp) 119 cred_t *credp)
114{ 120{
115 xfs_inode_t *ip; 121 xfs_inode_t *ip;
116 xfs_mount_t *mp; 122 xfs_mount_t *mp;
117 vnode_t *vp; 123 bhv_vnode_t *vp;
118 124
119 vp = BHV_TO_VNODE(bdp); 125 vp = BHV_TO_VNODE(bdp);
120 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 126 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -241,7 +247,7 @@ xfs_getattr(
241int 247int
242xfs_setattr( 248xfs_setattr(
243 bhv_desc_t *bdp, 249 bhv_desc_t *bdp,
244 vattr_t *vap, 250 bhv_vattr_t *vap,
245 int flags, 251 int flags,
246 cred_t *credp) 252 cred_t *credp)
247{ 253{
@@ -255,7 +261,7 @@ xfs_setattr(
255 uid_t uid=0, iuid=0; 261 uid_t uid=0, iuid=0;
256 gid_t gid=0, igid=0; 262 gid_t gid=0, igid=0;
257 int timeflags = 0; 263 int timeflags = 0;
258 vnode_t *vp; 264 bhv_vnode_t *vp;
259 xfs_prid_t projid=0, iprojid=0; 265 xfs_prid_t projid=0, iprojid=0;
260 int mandlock_before, mandlock_after; 266 int mandlock_before, mandlock_after;
261 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; 267 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
@@ -347,7 +353,6 @@ xfs_setattr(
347 */ 353 */
348 tp = NULL; 354 tp = NULL;
349 lock_flags = XFS_ILOCK_EXCL; 355 lock_flags = XFS_ILOCK_EXCL;
350 ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1);
351 if (flags & ATTR_NOLOCK) 356 if (flags & ATTR_NOLOCK)
352 need_iolock = 0; 357 need_iolock = 0;
353 if (!(mask & XFS_AT_SIZE)) { 358 if (!(mask & XFS_AT_SIZE)) {
@@ -666,9 +671,17 @@ xfs_setattr(
666 ((ip->i_d.di_nlink != 0 || 671 ((ip->i_d.di_nlink != 0 ||
667 !(mp->m_flags & XFS_MOUNT_WSYNC)) 672 !(mp->m_flags & XFS_MOUNT_WSYNC))
668 ? 1 : 0)); 673 ? 1 : 0));
669 if (code) { 674 if (code)
670 goto abort_return; 675 goto abort_return;
671 } 676 /*
677 * Truncated "down", so we're removing references
678 * to old data here - if we now delay flushing for
679 * a long time, we expose ourselves unduly to the
680 * notorious NULL files problem. So, we mark this
681 * vnode and flush it when the file is closed, and
682 * do not wait the usual (long) time for writeout.
683 */
684 VTRUNCATE(vp);
672 } 685 }
673 /* 686 /*
674 * Have to do this even if the file's size doesn't change. 687 * Have to do this even if the file's size doesn't change.
@@ -800,6 +813,8 @@ xfs_setattr(
800 di_flags |= XFS_DIFLAG_NODUMP; 813 di_flags |= XFS_DIFLAG_NODUMP;
801 if (vap->va_xflags & XFS_XFLAG_PROJINHERIT) 814 if (vap->va_xflags & XFS_XFLAG_PROJINHERIT)
802 di_flags |= XFS_DIFLAG_PROJINHERIT; 815 di_flags |= XFS_DIFLAG_PROJINHERIT;
816 if (vap->va_xflags & XFS_XFLAG_NODEFRAG)
817 di_flags |= XFS_DIFLAG_NODEFRAG;
803 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 818 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
804 if (vap->va_xflags & XFS_XFLAG_RTINHERIT) 819 if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
805 di_flags |= XFS_DIFLAG_RTINHERIT; 820 di_flags |= XFS_DIFLAG_RTINHERIT;
@@ -869,7 +884,7 @@ xfs_setattr(
869 */ 884 */
870 mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); 885 mandlock_after = MANDLOCK(vp, ip->i_d.di_mode);
871 if (mandlock_before != mandlock_after) { 886 if (mandlock_before != mandlock_after) {
872 VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_ENF_LOCKING, 887 bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING,
873 mandlock_after); 888 mandlock_after);
874 } 889 }
875 890
@@ -936,6 +951,13 @@ xfs_access(
936 951
937 952
938/* 953/*
954 * The maximum pathlen is 1024 bytes. Since the minimum file system
955 * blocksize is 512 bytes, we can get a max of 2 extents back from
956 * bmapi.
957 */
958#define SYMLINK_MAPS 2
959
960/*
939 * xfs_readlink 961 * xfs_readlink
940 * 962 *
941 */ 963 */
@@ -950,7 +972,7 @@ xfs_readlink(
950 int count; 972 int count;
951 xfs_off_t offset; 973 xfs_off_t offset;
952 int pathlen; 974 int pathlen;
953 vnode_t *vp; 975 bhv_vnode_t *vp;
954 int error = 0; 976 int error = 0;
955 xfs_mount_t *mp; 977 xfs_mount_t *mp;
956 int nmaps; 978 int nmaps;
@@ -1000,7 +1022,7 @@ xfs_readlink(
1000 nmaps = SYMLINK_MAPS; 1022 nmaps = SYMLINK_MAPS;
1001 1023
1002 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 1024 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen),
1003 0, NULL, 0, mval, &nmaps, NULL); 1025 0, NULL, 0, mval, &nmaps, NULL, NULL);
1004 1026
1005 if (error) { 1027 if (error) {
1006 goto error_return; 1028 goto error_return;
@@ -1208,8 +1230,8 @@ xfs_inactive_free_eofblocks(
1208 1230
1209 nimaps = 1; 1231 nimaps = 1;
1210 xfs_ilock(ip, XFS_ILOCK_SHARED); 1232 xfs_ilock(ip, XFS_ILOCK_SHARED);
1211 error = xfs_bmapi(NULL, ip, end_fsb, map_len, 0, 1233 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, end_fsb, map_len, 0,
1212 NULL, 0, &imap, &nimaps, NULL); 1234 NULL, 0, &imap, &nimaps, NULL, NULL);
1213 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1235 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1214 1236
1215 if (!error && (nimaps != 0) && 1237 if (!error && (nimaps != 0) &&
@@ -1338,7 +1360,7 @@ xfs_inactive_symlink_rmt(
1338 nmaps = ARRAY_SIZE(mval); 1360 nmaps = ARRAY_SIZE(mval);
1339 if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size), 1361 if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size),
1340 XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps, 1362 XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps,
1341 &free_list))) 1363 &free_list, NULL)))
1342 goto error0; 1364 goto error0;
1343 /* 1365 /*
1344 * Invalidate the block(s). 1366 * Invalidate the block(s).
@@ -1353,7 +1375,7 @@ xfs_inactive_symlink_rmt(
1353 * Unmap the dead block(s) to the free_list. 1375 * Unmap the dead block(s) to the free_list.
1354 */ 1376 */
1355 if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps, 1377 if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps,
1356 &first_block, &free_list, &done))) 1378 &first_block, &free_list, NULL, &done)))
1357 goto error1; 1379 goto error1;
1358 ASSERT(done); 1380 ASSERT(done);
1359 /* 1381 /*
@@ -1469,9 +1491,6 @@ xfs_inactive_symlink_local(
1469 return 0; 1491 return 0;
1470} 1492}
1471 1493
1472/*
1473 *
1474 */
1475STATIC int 1494STATIC int
1476xfs_inactive_attrs( 1495xfs_inactive_attrs(
1477 xfs_inode_t *ip, 1496 xfs_inode_t *ip,
@@ -1524,16 +1543,16 @@ xfs_release(
1524 bhv_desc_t *bdp) 1543 bhv_desc_t *bdp)
1525{ 1544{
1526 xfs_inode_t *ip; 1545 xfs_inode_t *ip;
1527 vnode_t *vp; 1546 bhv_vnode_t *vp;
1528 xfs_mount_t *mp; 1547 xfs_mount_t *mp;
1529 int error; 1548 int error;
1530 1549
1531 vp = BHV_TO_VNODE(bdp); 1550 vp = BHV_TO_VNODE(bdp);
1532 ip = XFS_BHVTOI(bdp); 1551 ip = XFS_BHVTOI(bdp);
1552 mp = ip->i_mount;
1533 1553
1534 if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) { 1554 if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0))
1535 return 0; 1555 return 0;
1536 }
1537 1556
1538 /* If this is a read-only mount, don't do this (would generate I/O) */ 1557 /* If this is a read-only mount, don't do this (would generate I/O) */
1539 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 1558 if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
@@ -1545,8 +1564,6 @@ xfs_release(
1545 return 0; 1564 return 0;
1546#endif 1565#endif
1547 1566
1548 mp = ip->i_mount;
1549
1550 if (ip->i_d.di_nlink != 0) { 1567 if (ip->i_d.di_nlink != 0) {
1551 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1568 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1552 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 || 1569 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
@@ -1579,8 +1596,8 @@ xfs_inactive(
1579 cred_t *credp) 1596 cred_t *credp)
1580{ 1597{
1581 xfs_inode_t *ip; 1598 xfs_inode_t *ip;
1582 vnode_t *vp; 1599 bhv_vnode_t *vp;
1583 xfs_bmap_free_t free_list; 1600 xfs_bmap_free_t free_list;
1584 xfs_fsblock_t first_block; 1601 xfs_fsblock_t first_block;
1585 int committed; 1602 int committed;
1586 xfs_trans_t *tp; 1603 xfs_trans_t *tp;
@@ -1760,7 +1777,7 @@ xfs_inactive(
1760 cmn_err(CE_NOTE, 1777 cmn_err(CE_NOTE,
1761 "xfs_inactive: xfs_ifree() returned an error = %d on %s", 1778 "xfs_inactive: xfs_ifree() returned an error = %d on %s",
1762 error, mp->m_fsname); 1779 error, mp->m_fsname);
1763 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 1780 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1764 } 1781 }
1765 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 1782 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
1766 } else { 1783 } else {
@@ -1795,17 +1812,17 @@ xfs_inactive(
1795STATIC int 1812STATIC int
1796xfs_lookup( 1813xfs_lookup(
1797 bhv_desc_t *dir_bdp, 1814 bhv_desc_t *dir_bdp,
1798 vname_t *dentry, 1815 bhv_vname_t *dentry,
1799 vnode_t **vpp, 1816 bhv_vnode_t **vpp,
1800 int flags, 1817 int flags,
1801 vnode_t *rdir, 1818 bhv_vnode_t *rdir,
1802 cred_t *credp) 1819 cred_t *credp)
1803{ 1820{
1804 xfs_inode_t *dp, *ip; 1821 xfs_inode_t *dp, *ip;
1805 xfs_ino_t e_inum; 1822 xfs_ino_t e_inum;
1806 int error; 1823 int error;
1807 uint lock_mode; 1824 uint lock_mode;
1808 vnode_t *dir_vp; 1825 bhv_vnode_t *dir_vp;
1809 1826
1810 dir_vp = BHV_TO_VNODE(dir_bdp); 1827 dir_vp = BHV_TO_VNODE(dir_bdp);
1811 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); 1828 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
@@ -1832,15 +1849,15 @@ xfs_lookup(
1832STATIC int 1849STATIC int
1833xfs_create( 1850xfs_create(
1834 bhv_desc_t *dir_bdp, 1851 bhv_desc_t *dir_bdp,
1835 vname_t *dentry, 1852 bhv_vname_t *dentry,
1836 vattr_t *vap, 1853 bhv_vattr_t *vap,
1837 vnode_t **vpp, 1854 bhv_vnode_t **vpp,
1838 cred_t *credp) 1855 cred_t *credp)
1839{ 1856{
1840 char *name = VNAME(dentry); 1857 char *name = VNAME(dentry);
1841 vnode_t *dir_vp; 1858 bhv_vnode_t *dir_vp;
1842 xfs_inode_t *dp, *ip; 1859 xfs_inode_t *dp, *ip;
1843 vnode_t *vp=NULL; 1860 bhv_vnode_t *vp = NULL;
1844 xfs_trans_t *tp; 1861 xfs_trans_t *tp;
1845 xfs_mount_t *mp; 1862 xfs_mount_t *mp;
1846 xfs_dev_t rdev; 1863 xfs_dev_t rdev;
@@ -1938,8 +1955,7 @@ xfs_create(
1938 if (error) 1955 if (error)
1939 goto error_return; 1956 goto error_return;
1940 1957
1941 if (resblks == 0 && 1958 if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen)))
1942 (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen)))
1943 goto error_return; 1959 goto error_return;
1944 rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; 1960 rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;
1945 error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, 1961 error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1,
@@ -1970,9 +1986,9 @@ xfs_create(
1970 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 1986 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
1971 dp_joined_to_trans = B_TRUE; 1987 dp_joined_to_trans = B_TRUE;
1972 1988
1973 error = XFS_DIR_CREATENAME(mp, tp, dp, name, namelen, ip->i_ino, 1989 error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino,
1974 &first_block, &free_list, 1990 &first_block, &free_list, resblks ?
1975 resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); 1991 resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
1976 if (error) { 1992 if (error) {
1977 ASSERT(error != ENOSPC); 1993 ASSERT(error != ENOSPC);
1978 goto abort_return; 1994 goto abort_return;
@@ -2026,7 +2042,7 @@ xfs_create(
2026 * Propagate the fact that the vnode changed after the 2042 * Propagate the fact that the vnode changed after the
2027 * xfs_inode locks have been released. 2043 * xfs_inode locks have been released.
2028 */ 2044 */
2029 VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_TRUNCATED, 3); 2045 bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3);
2030 2046
2031 *vpp = vp; 2047 *vpp = vp;
2032 2048
@@ -2107,7 +2123,7 @@ int xfs_rm_attempts;
2107STATIC int 2123STATIC int
2108xfs_lock_dir_and_entry( 2124xfs_lock_dir_and_entry(
2109 xfs_inode_t *dp, 2125 xfs_inode_t *dp,
2110 vname_t *dentry, 2126 bhv_vname_t *dentry,
2111 xfs_inode_t *ip) /* inode of entry 'name' */ 2127 xfs_inode_t *ip) /* inode of entry 'name' */
2112{ 2128{
2113 int attempts; 2129 int attempts;
@@ -2321,10 +2337,10 @@ int remove_which_error_return = 0;
2321STATIC int 2337STATIC int
2322xfs_remove( 2338xfs_remove(
2323 bhv_desc_t *dir_bdp, 2339 bhv_desc_t *dir_bdp,
2324 vname_t *dentry, 2340 bhv_vname_t *dentry,
2325 cred_t *credp) 2341 cred_t *credp)
2326{ 2342{
2327 vnode_t *dir_vp; 2343 bhv_vnode_t *dir_vp;
2328 char *name = VNAME(dentry); 2344 char *name = VNAME(dentry);
2329 xfs_inode_t *dp, *ip; 2345 xfs_inode_t *dp, *ip;
2330 xfs_trans_t *tp = NULL; 2346 xfs_trans_t *tp = NULL;
@@ -2448,8 +2464,8 @@ xfs_remove(
2448 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. 2464 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry.
2449 */ 2465 */
2450 XFS_BMAP_INIT(&free_list, &first_block); 2466 XFS_BMAP_INIT(&free_list, &first_block);
2451 error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, ip->i_ino, 2467 error = xfs_dir_removename(tp, dp, name, namelen, ip->i_ino,
2452 &first_block, &free_list, 0); 2468 &first_block, &free_list, 0);
2453 if (error) { 2469 if (error) {
2454 ASSERT(error != ENOENT); 2470 ASSERT(error != ENOENT);
2455 REMOVE_DEBUG_TRACE(__LINE__); 2471 REMOVE_DEBUG_TRACE(__LINE__);
@@ -2511,7 +2527,7 @@ xfs_remove(
2511 /* 2527 /*
2512 * Let interposed file systems know about removed links. 2528 * Let interposed file systems know about removed links.
2513 */ 2529 */
2514 VOP_LINK_REMOVED(XFS_ITOV(ip), dir_vp, link_zero); 2530 bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero);
2515 2531
2516 IRELE(ip); 2532 IRELE(ip);
2517 2533
@@ -2564,8 +2580,8 @@ xfs_remove(
2564STATIC int 2580STATIC int
2565xfs_link( 2581xfs_link(
2566 bhv_desc_t *target_dir_bdp, 2582 bhv_desc_t *target_dir_bdp,
2567 vnode_t *src_vp, 2583 bhv_vnode_t *src_vp,
2568 vname_t *dentry, 2584 bhv_vname_t *dentry,
2569 cred_t *credp) 2585 cred_t *credp)
2570{ 2586{
2571 xfs_inode_t *tdp, *sip; 2587 xfs_inode_t *tdp, *sip;
@@ -2577,7 +2593,7 @@ xfs_link(
2577 xfs_fsblock_t first_block; 2593 xfs_fsblock_t first_block;
2578 int cancel_flags; 2594 int cancel_flags;
2579 int committed; 2595 int committed;
2580 vnode_t *target_dir_vp; 2596 bhv_vnode_t *target_dir_vp;
2581 int resblks; 2597 int resblks;
2582 char *target_name = VNAME(dentry); 2598 char *target_name = VNAME(dentry);
2583 int target_namelen; 2599 int target_namelen;
@@ -2668,13 +2684,12 @@ xfs_link(
2668 } 2684 }
2669 2685
2670 if (resblks == 0 && 2686 if (resblks == 0 &&
2671 (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, 2687 (error = xfs_dir_canenter(tp, tdp, target_name, target_namelen)))
2672 target_namelen)))
2673 goto error_return; 2688 goto error_return;
2674 2689
2675 XFS_BMAP_INIT(&free_list, &first_block); 2690 XFS_BMAP_INIT(&free_list, &first_block);
2676 2691
2677 error = XFS_DIR_CREATENAME(mp, tp, tdp, target_name, target_namelen, 2692 error = xfs_dir_createname(tp, tdp, target_name, target_namelen,
2678 sip->i_ino, &first_block, &free_list, 2693 sip->i_ino, &first_block, &free_list,
2679 resblks); 2694 resblks);
2680 if (error) 2695 if (error)
@@ -2734,15 +2749,15 @@ std_return:
2734STATIC int 2749STATIC int
2735xfs_mkdir( 2750xfs_mkdir(
2736 bhv_desc_t *dir_bdp, 2751 bhv_desc_t *dir_bdp,
2737 vname_t *dentry, 2752 bhv_vname_t *dentry,
2738 vattr_t *vap, 2753 bhv_vattr_t *vap,
2739 vnode_t **vpp, 2754 bhv_vnode_t **vpp,
2740 cred_t *credp) 2755 cred_t *credp)
2741{ 2756{
2742 char *dir_name = VNAME(dentry); 2757 char *dir_name = VNAME(dentry);
2743 xfs_inode_t *dp; 2758 xfs_inode_t *dp;
2744 xfs_inode_t *cdp; /* inode of created dir */ 2759 xfs_inode_t *cdp; /* inode of created dir */
2745 vnode_t *cvp; /* vnode of created dir */ 2760 bhv_vnode_t *cvp; /* vnode of created dir */
2746 xfs_trans_t *tp; 2761 xfs_trans_t *tp;
2747 xfs_mount_t *mp; 2762 xfs_mount_t *mp;
2748 int cancel_flags; 2763 int cancel_flags;
@@ -2750,7 +2765,7 @@ xfs_mkdir(
2750 int committed; 2765 int committed;
2751 xfs_bmap_free_t free_list; 2766 xfs_bmap_free_t free_list;
2752 xfs_fsblock_t first_block; 2767 xfs_fsblock_t first_block;
2753 vnode_t *dir_vp; 2768 bhv_vnode_t *dir_vp;
2754 boolean_t dp_joined_to_trans; 2769 boolean_t dp_joined_to_trans;
2755 boolean_t created = B_FALSE; 2770 boolean_t created = B_FALSE;
2756 int dm_event_sent = 0; 2771 int dm_event_sent = 0;
@@ -2840,7 +2855,7 @@ xfs_mkdir(
2840 goto error_return; 2855 goto error_return;
2841 2856
2842 if (resblks == 0 && 2857 if (resblks == 0 &&
2843 (error = XFS_DIR_CANENTER(mp, tp, dp, dir_name, dir_namelen))) 2858 (error = xfs_dir_canenter(tp, dp, dir_name, dir_namelen)))
2844 goto error_return; 2859 goto error_return;
2845 /* 2860 /*
2846 * create the directory inode. 2861 * create the directory inode.
@@ -2867,9 +2882,9 @@ xfs_mkdir(
2867 2882
2868 XFS_BMAP_INIT(&free_list, &first_block); 2883 XFS_BMAP_INIT(&free_list, &first_block);
2869 2884
2870 error = XFS_DIR_CREATENAME(mp, tp, dp, dir_name, dir_namelen, 2885 error = xfs_dir_createname(tp, dp, dir_name, dir_namelen, cdp->i_ino,
2871 cdp->i_ino, &first_block, &free_list, 2886 &first_block, &free_list, resblks ?
2872 resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); 2887 resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
2873 if (error) { 2888 if (error) {
2874 ASSERT(error != ENOSPC); 2889 ASSERT(error != ENOSPC);
2875 goto error1; 2890 goto error1;
@@ -2883,16 +2898,14 @@ xfs_mkdir(
2883 */ 2898 */
2884 dp->i_gen++; 2899 dp->i_gen++;
2885 2900
2886 error = XFS_DIR_INIT(mp, tp, cdp, dp); 2901 error = xfs_dir_init(tp, cdp, dp);
2887 if (error) { 2902 if (error)
2888 goto error2; 2903 goto error2;
2889 }
2890 2904
2891 cdp->i_gen = 1; 2905 cdp->i_gen = 1;
2892 error = xfs_bumplink(tp, dp); 2906 error = xfs_bumplink(tp, dp);
2893 if (error) { 2907 if (error)
2894 goto error2; 2908 goto error2;
2895 }
2896 2909
2897 cvp = XFS_ITOV(cdp); 2910 cvp = XFS_ITOV(cdp);
2898 2911
@@ -2969,7 +2982,7 @@ std_return:
2969STATIC int 2982STATIC int
2970xfs_rmdir( 2983xfs_rmdir(
2971 bhv_desc_t *dir_bdp, 2984 bhv_desc_t *dir_bdp,
2972 vname_t *dentry, 2985 bhv_vname_t *dentry,
2973 cred_t *credp) 2986 cred_t *credp)
2974{ 2987{
2975 char *name = VNAME(dentry); 2988 char *name = VNAME(dentry);
@@ -2982,7 +2995,7 @@ xfs_rmdir(
2982 xfs_fsblock_t first_block; 2995 xfs_fsblock_t first_block;
2983 int cancel_flags; 2996 int cancel_flags;
2984 int committed; 2997 int committed;
2985 vnode_t *dir_vp; 2998 bhv_vnode_t *dir_vp;
2986 int dm_di_mode = 0; 2999 int dm_di_mode = 0;
2987 int last_cdp_link; 3000 int last_cdp_link;
2988 int namelen; 3001 int namelen;
@@ -3101,16 +3114,15 @@ xfs_rmdir(
3101 error = XFS_ERROR(ENOTEMPTY); 3114 error = XFS_ERROR(ENOTEMPTY);
3102 goto error_return; 3115 goto error_return;
3103 } 3116 }
3104 if (!XFS_DIR_ISEMPTY(mp, cdp)) { 3117 if (!xfs_dir_isempty(cdp)) {
3105 error = XFS_ERROR(ENOTEMPTY); 3118 error = XFS_ERROR(ENOTEMPTY);
3106 goto error_return; 3119 goto error_return;
3107 } 3120 }
3108 3121
3109 error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, cdp->i_ino, 3122 error = xfs_dir_removename(tp, dp, name, namelen, cdp->i_ino,
3110 &first_block, &free_list, resblks); 3123 &first_block, &free_list, resblks);
3111 if (error) { 3124 if (error)
3112 goto error1; 3125 goto error1;
3113 }
3114 3126
3115 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 3127 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
3116 3128
@@ -3181,7 +3193,7 @@ xfs_rmdir(
3181 /* 3193 /*
3182 * Let interposed file systems know about removed links. 3194 * Let interposed file systems know about removed links.
3183 */ 3195 */
3184 VOP_LINK_REMOVED(XFS_ITOV(cdp), dir_vp, last_cdp_link); 3196 bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link);
3185 3197
3186 IRELE(cdp); 3198 IRELE(cdp);
3187 3199
@@ -3209,8 +3221,6 @@ xfs_rmdir(
3209 3221
3210 3222
3211/* 3223/*
3212 * xfs_readdir
3213 *
3214 * Read dp's entries starting at uiop->uio_offset and translate them into 3224 * Read dp's entries starting at uiop->uio_offset and translate them into
3215 * bufsize bytes worth of struct dirents starting at bufbase. 3225 * bufsize bytes worth of struct dirents starting at bufbase.
3216 */ 3226 */
@@ -3230,28 +3240,23 @@ xfs_readdir(
3230 (inst_t *)__return_address); 3240 (inst_t *)__return_address);
3231 dp = XFS_BHVTOI(dir_bdp); 3241 dp = XFS_BHVTOI(dir_bdp);
3232 3242
3233 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) { 3243 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
3234 return XFS_ERROR(EIO); 3244 return XFS_ERROR(EIO);
3235 }
3236 3245
3237 lock_mode = xfs_ilock_map_shared(dp); 3246 lock_mode = xfs_ilock_map_shared(dp);
3238 error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp); 3247 error = xfs_dir_getdents(tp, dp, uiop, eofp);
3239 xfs_iunlock_map_shared(dp, lock_mode); 3248 xfs_iunlock_map_shared(dp, lock_mode);
3240 return error; 3249 return error;
3241} 3250}
3242 3251
3243 3252
3244/*
3245 * xfs_symlink
3246 *
3247 */
3248STATIC int 3253STATIC int
3249xfs_symlink( 3254xfs_symlink(
3250 bhv_desc_t *dir_bdp, 3255 bhv_desc_t *dir_bdp,
3251 vname_t *dentry, 3256 bhv_vname_t *dentry,
3252 vattr_t *vap, 3257 bhv_vattr_t *vap,
3253 char *target_path, 3258 char *target_path,
3254 vnode_t **vpp, 3259 bhv_vnode_t **vpp,
3255 cred_t *credp) 3260 cred_t *credp)
3256{ 3261{
3257 xfs_trans_t *tp; 3262 xfs_trans_t *tp;
@@ -3263,7 +3268,7 @@ xfs_symlink(
3263 xfs_bmap_free_t free_list; 3268 xfs_bmap_free_t free_list;
3264 xfs_fsblock_t first_block; 3269 xfs_fsblock_t first_block;
3265 boolean_t dp_joined_to_trans; 3270 boolean_t dp_joined_to_trans;
3266 vnode_t *dir_vp; 3271 bhv_vnode_t *dir_vp;
3267 uint cancel_flags; 3272 uint cancel_flags;
3268 int committed; 3273 int committed;
3269 xfs_fileoff_t first_fsb; 3274 xfs_fileoff_t first_fsb;
@@ -3308,7 +3313,7 @@ xfs_symlink(
3308 int len, total; 3313 int len, total;
3309 char *path; 3314 char *path;
3310 3315
3311 for(total = 0, path = target_path; total < pathlen;) { 3316 for (total = 0, path = target_path; total < pathlen;) {
3312 /* 3317 /*
3313 * Skip any slashes. 3318 * Skip any slashes.
3314 */ 3319 */
@@ -3402,7 +3407,7 @@ xfs_symlink(
3402 * Check for ability to enter directory entry, if no space reserved. 3407 * Check for ability to enter directory entry, if no space reserved.
3403 */ 3408 */
3404 if (resblks == 0 && 3409 if (resblks == 0 &&
3405 (error = XFS_DIR_CANENTER(mp, tp, dp, link_name, link_namelen))) 3410 (error = xfs_dir_canenter(tp, dp, link_name, link_namelen)))
3406 goto error_return; 3411 goto error_return;
3407 /* 3412 /*
3408 * Initialize the bmap freelist prior to calling either 3413 * Initialize the bmap freelist prior to calling either
@@ -3457,7 +3462,7 @@ xfs_symlink(
3457 error = xfs_bmapi(tp, ip, first_fsb, fs_blocks, 3462 error = xfs_bmapi(tp, ip, first_fsb, fs_blocks,
3458 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, 3463 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,
3459 &first_block, resblks, mval, &nmaps, 3464 &first_block, resblks, mval, &nmaps,
3460 &free_list); 3465 &free_list, NULL);
3461 if (error) { 3466 if (error) {
3462 goto error1; 3467 goto error1;
3463 } 3468 }
@@ -3489,11 +3494,10 @@ xfs_symlink(
3489 /* 3494 /*
3490 * Create the directory entry for the symlink. 3495 * Create the directory entry for the symlink.
3491 */ 3496 */
3492 error = XFS_DIR_CREATENAME(mp, tp, dp, link_name, link_namelen, 3497 error = xfs_dir_createname(tp, dp, link_name, link_namelen, ip->i_ino,
3493 ip->i_ino, &first_block, &free_list, resblks); 3498 &first_block, &free_list, resblks);
3494 if (error) { 3499 if (error)
3495 goto error1; 3500 goto error1;
3496 }
3497 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 3501 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
3498 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 3502 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
3499 3503
@@ -3541,7 +3545,7 @@ std_return:
3541 } 3545 }
3542 3546
3543 if (!error) { 3547 if (!error) {
3544 vnode_t *vp; 3548 bhv_vnode_t *vp;
3545 3549
3546 ASSERT(ip); 3550 ASSERT(ip);
3547 vp = XFS_ITOV(ip); 3551 vp = XFS_ITOV(ip);
@@ -3606,10 +3610,10 @@ xfs_fid2(
3606int 3610int
3607xfs_rwlock( 3611xfs_rwlock(
3608 bhv_desc_t *bdp, 3612 bhv_desc_t *bdp,
3609 vrwlock_t locktype) 3613 bhv_vrwlock_t locktype)
3610{ 3614{
3611 xfs_inode_t *ip; 3615 xfs_inode_t *ip;
3612 vnode_t *vp; 3616 bhv_vnode_t *vp;
3613 3617
3614 vp = BHV_TO_VNODE(bdp); 3618 vp = BHV_TO_VNODE(bdp);
3615 if (VN_ISDIR(vp)) 3619 if (VN_ISDIR(vp))
@@ -3637,10 +3641,10 @@ xfs_rwlock(
3637void 3641void
3638xfs_rwunlock( 3642xfs_rwunlock(
3639 bhv_desc_t *bdp, 3643 bhv_desc_t *bdp,
3640 vrwlock_t locktype) 3644 bhv_vrwlock_t locktype)
3641{ 3645{
3642 xfs_inode_t *ip; 3646 xfs_inode_t *ip;
3643 vnode_t *vp; 3647 bhv_vnode_t *vp;
3644 3648
3645 vp = BHV_TO_VNODE(bdp); 3649 vp = BHV_TO_VNODE(bdp);
3646 if (VN_ISDIR(vp)) 3650 if (VN_ISDIR(vp))
@@ -3744,7 +3748,6 @@ xfs_inode_flush(
3744 return error; 3748 return error;
3745} 3749}
3746 3750
3747
3748int 3751int
3749xfs_set_dmattrs ( 3752xfs_set_dmattrs (
3750 bhv_desc_t *bdp, 3753 bhv_desc_t *bdp,
@@ -3785,16 +3788,12 @@ xfs_set_dmattrs (
3785 return error; 3788 return error;
3786} 3789}
3787 3790
3788
3789/*
3790 * xfs_reclaim
3791 */
3792STATIC int 3791STATIC int
3793xfs_reclaim( 3792xfs_reclaim(
3794 bhv_desc_t *bdp) 3793 bhv_desc_t *bdp)
3795{ 3794{
3796 xfs_inode_t *ip; 3795 xfs_inode_t *ip;
3797 vnode_t *vp; 3796 bhv_vnode_t *vp;
3798 3797
3799 vp = BHV_TO_VNODE(bdp); 3798 vp = BHV_TO_VNODE(bdp);
3800 ip = XFS_BHVTOI(bdp); 3799 ip = XFS_BHVTOI(bdp);
@@ -3849,7 +3848,7 @@ xfs_finish_reclaim(
3849 int sync_mode) 3848 int sync_mode)
3850{ 3849{
3851 xfs_ihash_t *ih = ip->i_hash; 3850 xfs_ihash_t *ih = ip->i_hash;
3852 vnode_t *vp = XFS_ITOV_NULL(ip); 3851 bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
3853 int error; 3852 int error;
3854 3853
3855 if (vp && VN_BAD(vp)) 3854 if (vp && VN_BAD(vp))
@@ -4116,10 +4115,10 @@ retry:
4116 * Issue the xfs_bmapi() call to allocate the blocks 4115 * Issue the xfs_bmapi() call to allocate the blocks
4117 */ 4116 */
4118 XFS_BMAP_INIT(&free_list, &firstfsb); 4117 XFS_BMAP_INIT(&free_list, &firstfsb);
4119 error = xfs_bmapi(tp, ip, startoffset_fsb, 4118 error = XFS_BMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
4120 allocatesize_fsb, bmapi_flag, 4119 allocatesize_fsb, bmapi_flag,
4121 &firstfsb, 0, imapp, &nimaps, 4120 &firstfsb, 0, imapp, &nimaps,
4122 &free_list); 4121 &free_list, NULL);
4123 if (error) { 4122 if (error) {
4124 goto error0; 4123 goto error0;
4125 } 4124 }
@@ -4199,8 +4198,8 @@ xfs_zero_remaining_bytes(
4199 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { 4198 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
4200 offset_fsb = XFS_B_TO_FSBT(mp, offset); 4199 offset_fsb = XFS_B_TO_FSBT(mp, offset);
4201 nimap = 1; 4200 nimap = 1;
4202 error = xfs_bmapi(NULL, ip, offset_fsb, 1, 0, NULL, 0, &imap, 4201 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, offset_fsb, 1, 0,
4203 &nimap, NULL); 4202 NULL, 0, &imap, &nimap, NULL, NULL);
4204 if (error || nimap < 1) 4203 if (error || nimap < 1)
4205 break; 4204 break;
4206 ASSERT(imap.br_blockcount >= 1); 4205 ASSERT(imap.br_blockcount >= 1);
@@ -4259,7 +4258,7 @@ xfs_free_file_space(
4259 xfs_off_t len, 4258 xfs_off_t len,
4260 int attr_flags) 4259 int attr_flags)
4261{ 4260{
4262 vnode_t *vp; 4261 bhv_vnode_t *vp;
4263 int committed; 4262 int committed;
4264 int done; 4263 int done;
4265 xfs_off_t end_dmi_offset; 4264 xfs_off_t end_dmi_offset;
@@ -4308,7 +4307,6 @@ xfs_free_file_space(
4308 return error; 4307 return error;
4309 } 4308 }
4310 4309
4311 ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
4312 if (attr_flags & ATTR_NOLOCK) 4310 if (attr_flags & ATTR_NOLOCK)
4313 need_iolock = 0; 4311 need_iolock = 0;
4314 if (need_iolock) { 4312 if (need_iolock) {
@@ -4326,7 +4324,7 @@ xfs_free_file_space(
4326 if (VN_CACHED(vp) != 0) { 4324 if (VN_CACHED(vp) != 0) {
4327 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, 4325 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
4328 ctooff(offtoct(ioffset)), -1); 4326 ctooff(offtoct(ioffset)), -1);
4329 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)), 4327 bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
4330 -1, FI_REMAPF_LOCKED); 4328 -1, FI_REMAPF_LOCKED);
4331 } 4329 }
4332 4330
@@ -4338,8 +4336,8 @@ xfs_free_file_space(
4338 */ 4336 */
4339 if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { 4337 if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
4340 nimap = 1; 4338 nimap = 1;
4341 error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0, 4339 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, startoffset_fsb,
4342 &imap, &nimap, NULL); 4340 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
4343 if (error) 4341 if (error)
4344 goto out_unlock_iolock; 4342 goto out_unlock_iolock;
4345 ASSERT(nimap == 0 || nimap == 1); 4343 ASSERT(nimap == 0 || nimap == 1);
@@ -4353,8 +4351,8 @@ xfs_free_file_space(
4353 startoffset_fsb += mp->m_sb.sb_rextsize - mod; 4351 startoffset_fsb += mp->m_sb.sb_rextsize - mod;
4354 } 4352 }
4355 nimap = 1; 4353 nimap = 1;
4356 error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, 1, 0, NULL, 0, 4354 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, endoffset_fsb - 1,
4357 &imap, &nimap, NULL); 4355 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
4358 if (error) 4356 if (error)
4359 goto out_unlock_iolock; 4357 goto out_unlock_iolock;
4360 ASSERT(nimap == 0 || nimap == 1); 4358 ASSERT(nimap == 0 || nimap == 1);
@@ -4426,9 +4424,9 @@ xfs_free_file_space(
4426 * issue the bunmapi() call to free the blocks 4424 * issue the bunmapi() call to free the blocks
4427 */ 4425 */
4428 XFS_BMAP_INIT(&free_list, &firstfsb); 4426 XFS_BMAP_INIT(&free_list, &firstfsb);
4429 error = xfs_bunmapi(tp, ip, startoffset_fsb, 4427 error = XFS_BUNMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
4430 endoffset_fsb - startoffset_fsb, 4428 endoffset_fsb - startoffset_fsb,
4431 0, 2, &firstfsb, &free_list, &done); 4429 0, 2, &firstfsb, &free_list, NULL, &done);
4432 if (error) { 4430 if (error) {
4433 goto error0; 4431 goto error0;
4434 } 4432 }
@@ -4488,8 +4486,8 @@ xfs_change_file_space(
4488 xfs_off_t startoffset; 4486 xfs_off_t startoffset;
4489 xfs_off_t llen; 4487 xfs_off_t llen;
4490 xfs_trans_t *tp; 4488 xfs_trans_t *tp;
4491 vattr_t va; 4489 bhv_vattr_t va;
4492 vnode_t *vp; 4490 bhv_vnode_t *vp;
4493 4491
4494 vp = BHV_TO_VNODE(bdp); 4492 vp = BHV_TO_VNODE(bdp);
4495 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 4493 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -4642,9 +4640,10 @@ xfs_change_file_space(
4642 return error; 4640 return error;
4643} 4641}
4644 4642
4645vnodeops_t xfs_vnodeops = { 4643bhv_vnodeops_t xfs_vnodeops = {
4646 BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), 4644 BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS),
4647 .vop_open = xfs_open, 4645 .vop_open = xfs_open,
4646 .vop_close = xfs_close,
4648 .vop_read = xfs_read, 4647 .vop_read = xfs_read,
4649#ifdef HAVE_SENDFILE 4648#ifdef HAVE_SENDFILE
4650 .vop_sendfile = xfs_sendfile, 4649 .vop_sendfile = xfs_sendfile,