aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/Makefile-linux-2.63
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c57
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c26
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c20
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c174
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c54
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.h4
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.c5
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c242
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c196
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.h8
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c104
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h23
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c298
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h5
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.c327
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h168
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c100
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h345
-rw-r--r--fs/xfs/quota/xfs_qm.c51
-rw-r--r--fs/xfs/quota/xfs_qm.h6
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c239
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c21
-rw-r--r--fs/xfs/support/move.c51
-rw-r--r--fs/xfs/support/move.h70
-rw-r--r--fs/xfs/xfs_acl.c33
-rw-r--r--fs/xfs/xfs_acl.h19
-rw-r--r--fs/xfs/xfs_ag.h4
-rw-r--r--fs/xfs/xfs_attr.c50
-rw-r--r--fs/xfs/xfs_attr.h17
-rw-r--r--fs/xfs/xfs_behavior.c183
-rw-r--r--fs/xfs/xfs_behavior.h185
-rw-r--r--fs/xfs/xfs_bmap.c150
-rw-r--r--fs/xfs/xfs_bmap.h4
-rw-r--r--fs/xfs/xfs_bmap_btree.c255
-rw-r--r--fs/xfs/xfs_bmap_btree.h68
-rw-r--r--fs/xfs/xfs_buf_item.c1
-rw-r--r--fs/xfs/xfs_clnt.h1
-rw-r--r--fs/xfs/xfs_dfrag.c6
-rw-r--r--fs/xfs/xfs_dinode.h65
-rw-r--r--fs/xfs/xfs_dir2.c117
-rw-r--r--fs/xfs/xfs_dir2.h17
-rw-r--r--fs/xfs/xfs_dir2_block.c64
-rw-r--r--fs/xfs/xfs_dir2_block.h5
-rw-r--r--fs/xfs/xfs_dir2_data.c1
-rw-r--r--fs/xfs/xfs_dir2_leaf.c76
-rw-r--r--fs/xfs/xfs_dir2_leaf.h6
-rw-r--r--fs/xfs/xfs_dir2_node.c1
-rw-r--r--fs/xfs/xfs_dir2_sf.c122
-rw-r--r--fs/xfs/xfs_dir2_sf.h5
-rw-r--r--fs/xfs/xfs_dmapi.h17
-rw-r--r--fs/xfs/xfs_dmops.c43
-rw-r--r--fs/xfs/xfs_error.c21
-rw-r--r--fs/xfs/xfs_error.h5
-rw-r--r--fs/xfs/xfs_extfree_item.c1
-rw-r--r--fs/xfs/xfs_fsops.c17
-rw-r--r--fs/xfs/xfs_ialloc.c6
-rw-r--r--fs/xfs/xfs_ialloc.h7
-rw-r--r--fs/xfs/xfs_iget.c605
-rw-r--r--fs/xfs/xfs_inode.c383
-rw-r--r--fs/xfs/xfs_inode.h158
-rw-r--r--fs/xfs/xfs_iocore.c4
-rw-r--r--fs/xfs/xfs_iomap.c8
-rw-r--r--fs/xfs/xfs_iomap.h1
-rw-r--r--fs/xfs/xfs_itable.c78
-rw-r--r--fs/xfs/xfs_log.c100
-rw-r--r--fs/xfs/xfs_log_priv.h21
-rw-r--r--fs/xfs/xfs_log_recover.c32
-rw-r--r--fs/xfs/xfs_mount.c242
-rw-r--r--fs/xfs/xfs_mount.h176
-rw-r--r--fs/xfs/xfs_qmops.c40
-rw-r--r--fs/xfs/xfs_quota.h10
-rw-r--r--fs/xfs/xfs_rename.c38
-rw-r--r--fs/xfs/xfs_rw.c5
-rw-r--r--fs/xfs/xfs_rw.h34
-rw-r--r--fs/xfs/xfs_sb.h68
-rw-r--r--fs/xfs/xfs_trans.c76
-rw-r--r--fs/xfs/xfs_trans_ail.c1
-rw-r--r--fs/xfs/xfs_trans_extfree.c1
-rw-r--r--fs/xfs/xfs_types.h12
-rw-r--r--fs/xfs/xfs_utils.c9
-rw-r--r--fs/xfs/xfs_utils.h6
-rw-r--r--fs/xfs/xfs_vfsops.c351
-rw-r--r--fs/xfs/xfs_vfsops.h28
-rw-r--r--fs/xfs/xfs_vnodeops.c745
-rw-r--r--fs/xfs/xfs_vnodeops.h86
90 files changed, 2762 insertions, 4739 deletions
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index e7a9a83f0087..d1491aa7a0e2 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -49,7 +49,6 @@ xfs-y += xfs_alloc.o \
49 xfs_alloc_btree.o \ 49 xfs_alloc_btree.o \
50 xfs_attr.o \ 50 xfs_attr.o \
51 xfs_attr_leaf.o \ 51 xfs_attr_leaf.o \
52 xfs_behavior.o \
53 xfs_bit.o \ 52 xfs_bit.o \
54 xfs_bmap.o \ 53 xfs_bmap.o \
55 xfs_bmap_btree.o \ 54 xfs_bmap_btree.o \
@@ -108,13 +107,11 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
108 xfs_iops.o \ 107 xfs_iops.o \
109 xfs_lrw.o \ 108 xfs_lrw.o \
110 xfs_super.o \ 109 xfs_super.o \
111 xfs_vfs.o \
112 xfs_vnode.o) 110 xfs_vnode.o)
113 111
114# Objects in support/ 112# Objects in support/
115xfs-y += $(addprefix support/, \ 113xfs-y += $(addprefix support/, \
116 debug.o \ 114 debug.o \
117 move.o \
118 uuid.o) 115 uuid.o)
119 116
120xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o 117xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 52bd08c0a278..2e34b104107c 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -37,6 +37,7 @@
37#include "xfs_error.h" 37#include "xfs_error.h"
38#include "xfs_rw.h" 38#include "xfs_rw.h"
39#include "xfs_iomap.h" 39#include "xfs_iomap.h"
40#include "xfs_vnodeops.h"
40#include <linux/mpage.h> 41#include <linux/mpage.h>
41#include <linux/pagevec.h> 42#include <linux/pagevec.h>
42#include <linux/writeback.h> 43#include <linux/writeback.h>
@@ -139,9 +140,11 @@ xfs_destroy_ioend(
139 next = bh->b_private; 140 next = bh->b_private;
140 bh->b_end_io(bh, !ioend->io_error); 141 bh->b_end_io(bh, !ioend->io_error);
141 } 142 }
142 if (unlikely(ioend->io_error)) 143 if (unlikely(ioend->io_error)) {
143 vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__); 144 vn_ioerror(XFS_I(ioend->io_inode), ioend->io_error,
144 vn_iowake(ioend->io_vnode); 145 __FILE__,__LINE__);
146 }
147 vn_iowake(XFS_I(ioend->io_inode));
145 mempool_free(ioend, xfs_ioend_pool); 148 mempool_free(ioend, xfs_ioend_pool);
146} 149}
147 150
@@ -156,14 +159,10 @@ STATIC void
156xfs_setfilesize( 159xfs_setfilesize(
157 xfs_ioend_t *ioend) 160 xfs_ioend_t *ioend)
158{ 161{
159 xfs_inode_t *ip; 162 xfs_inode_t *ip = XFS_I(ioend->io_inode);
160 xfs_fsize_t isize; 163 xfs_fsize_t isize;
161 xfs_fsize_t bsize; 164 xfs_fsize_t bsize;
162 165
163 ip = xfs_vtoi(ioend->io_vnode);
164 if (!ip)
165 return;
166
167 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); 166 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
168 ASSERT(ioend->io_type != IOMAP_READ); 167 ASSERT(ioend->io_type != IOMAP_READ);
169 168
@@ -181,7 +180,7 @@ xfs_setfilesize(
181 ip->i_d.di_size = isize; 180 ip->i_d.di_size = isize;
182 ip->i_update_core = 1; 181 ip->i_update_core = 1;
183 ip->i_update_size = 1; 182 ip->i_update_size = 1;
184 mark_inode_dirty_sync(vn_to_inode(ioend->io_vnode)); 183 mark_inode_dirty_sync(ioend->io_inode);
185 } 184 }
186 185
187 xfs_iunlock(ip, XFS_ILOCK_EXCL); 186 xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -227,12 +226,12 @@ xfs_end_bio_unwritten(
227{ 226{
228 xfs_ioend_t *ioend = 227 xfs_ioend_t *ioend =
229 container_of(work, xfs_ioend_t, io_work); 228 container_of(work, xfs_ioend_t, io_work);
230 bhv_vnode_t *vp = ioend->io_vnode;
231 xfs_off_t offset = ioend->io_offset; 229 xfs_off_t offset = ioend->io_offset;
232 size_t size = ioend->io_size; 230 size_t size = ioend->io_size;
233 231
234 if (likely(!ioend->io_error)) { 232 if (likely(!ioend->io_error)) {
235 bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL); 233 xfs_bmap(XFS_I(ioend->io_inode), offset, size,
234 BMAPI_UNWRITTEN, NULL, NULL);
236 xfs_setfilesize(ioend); 235 xfs_setfilesize(ioend);
237 } 236 }
238 xfs_destroy_ioend(ioend); 237 xfs_destroy_ioend(ioend);
@@ -275,10 +274,10 @@ xfs_alloc_ioend(
275 ioend->io_error = 0; 274 ioend->io_error = 0;
276 ioend->io_list = NULL; 275 ioend->io_list = NULL;
277 ioend->io_type = type; 276 ioend->io_type = type;
278 ioend->io_vnode = vn_from_inode(inode); 277 ioend->io_inode = inode;
279 ioend->io_buffer_head = NULL; 278 ioend->io_buffer_head = NULL;
280 ioend->io_buffer_tail = NULL; 279 ioend->io_buffer_tail = NULL;
281 atomic_inc(&ioend->io_vnode->v_iocount); 280 atomic_inc(&XFS_I(ioend->io_inode)->i_iocount);
282 ioend->io_offset = 0; 281 ioend->io_offset = 0;
283 ioend->io_size = 0; 282 ioend->io_size = 0;
284 283
@@ -302,12 +301,13 @@ xfs_map_blocks(
302 xfs_iomap_t *mapp, 301 xfs_iomap_t *mapp,
303 int flags) 302 int flags)
304{ 303{
305 bhv_vnode_t *vp = vn_from_inode(inode); 304 xfs_inode_t *ip = XFS_I(inode);
306 int error, nmaps = 1; 305 int error, nmaps = 1;
307 306
308 error = bhv_vop_bmap(vp, offset, count, flags, mapp, &nmaps); 307 error = xfs_bmap(ip, offset, count,
308 flags, mapp, &nmaps);
309 if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE))) 309 if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
310 VMODIFY(vp); 310 xfs_iflags_set(ip, XFS_IMODIFIED);
311 return -error; 311 return -error;
312} 312}
313 313
@@ -497,7 +497,7 @@ xfs_cancel_ioend(
497 unlock_buffer(bh); 497 unlock_buffer(bh);
498 } while ((bh = next_bh) != NULL); 498 } while ((bh = next_bh) != NULL);
499 499
500 vn_iowake(ioend->io_vnode); 500 vn_iowake(XFS_I(ioend->io_inode));
501 mempool_free(ioend, xfs_ioend_pool); 501 mempool_free(ioend, xfs_ioend_pool);
502 } while ((ioend = next) != NULL); 502 } while ((ioend = next) != NULL);
503} 503}
@@ -1237,10 +1237,7 @@ xfs_vm_writepages(
1237 struct address_space *mapping, 1237 struct address_space *mapping,
1238 struct writeback_control *wbc) 1238 struct writeback_control *wbc)
1239{ 1239{
1240 struct bhv_vnode *vp = vn_from_inode(mapping->host); 1240 xfs_iflags_clear(XFS_I(mapping->host), XFS_ITRUNCATED);
1241
1242 if (VN_TRUNC(vp))
1243 VUNTRUNCATE(vp);
1244 return generic_writepages(mapping, wbc); 1241 return generic_writepages(mapping, wbc);
1245} 1242}
1246 1243
@@ -1317,7 +1314,6 @@ __xfs_get_blocks(
1317 int direct, 1314 int direct,
1318 bmapi_flags_t flags) 1315 bmapi_flags_t flags)
1319{ 1316{
1320 bhv_vnode_t *vp = vn_from_inode(inode);
1321 xfs_iomap_t iomap; 1317 xfs_iomap_t iomap;
1322 xfs_off_t offset; 1318 xfs_off_t offset;
1323 ssize_t size; 1319 ssize_t size;
@@ -1327,7 +1323,7 @@ __xfs_get_blocks(
1327 offset = (xfs_off_t)iblock << inode->i_blkbits; 1323 offset = (xfs_off_t)iblock << inode->i_blkbits;
1328 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); 1324 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
1329 size = bh_result->b_size; 1325 size = bh_result->b_size;
1330 error = bhv_vop_bmap(vp, offset, size, 1326 error = xfs_bmap(XFS_I(inode), offset, size,
1331 create ? flags : BMAPI_READ, &iomap, &niomap); 1327 create ? flags : BMAPI_READ, &iomap, &niomap);
1332 if (error) 1328 if (error)
1333 return -error; 1329 return -error;
@@ -1475,13 +1471,13 @@ xfs_vm_direct_IO(
1475{ 1471{
1476 struct file *file = iocb->ki_filp; 1472 struct file *file = iocb->ki_filp;
1477 struct inode *inode = file->f_mapping->host; 1473 struct inode *inode = file->f_mapping->host;
1478 bhv_vnode_t *vp = vn_from_inode(inode);
1479 xfs_iomap_t iomap; 1474 xfs_iomap_t iomap;
1480 int maps = 1; 1475 int maps = 1;
1481 int error; 1476 int error;
1482 ssize_t ret; 1477 ssize_t ret;
1483 1478
1484 error = bhv_vop_bmap(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps); 1479 error = xfs_bmap(XFS_I(inode), offset, 0,
1480 BMAPI_DEVICE, &iomap, &maps);
1485 if (error) 1481 if (error)
1486 return -error; 1482 return -error;
1487 1483
@@ -1527,12 +1523,13 @@ xfs_vm_bmap(
1527 sector_t block) 1523 sector_t block)
1528{ 1524{
1529 struct inode *inode = (struct inode *)mapping->host; 1525 struct inode *inode = (struct inode *)mapping->host;
1530 bhv_vnode_t *vp = vn_from_inode(inode); 1526 struct xfs_inode *ip = XFS_I(inode);
1531 1527
1532 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 1528 vn_trace_entry(XFS_I(inode), __FUNCTION__,
1533 bhv_vop_rwlock(vp, VRWLOCK_READ); 1529 (inst_t *)__return_address);
1534 bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF); 1530 xfs_rwlock(ip, VRWLOCK_READ);
1535 bhv_vop_rwunlock(vp, VRWLOCK_READ); 1531 xfs_flush_pages(ip, (xfs_off_t)0, -1, 0, FI_REMAPF);
1532 xfs_rwunlock(ip, VRWLOCK_READ);
1536 return generic_block_bmap(mapping, block, xfs_get_blocks); 1533 return generic_block_bmap(mapping, block, xfs_get_blocks);
1537} 1534}
1538 1535
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 2244e516b66a..3ba0631a3818 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -32,7 +32,7 @@ typedef struct xfs_ioend {
32 unsigned int io_type; /* delalloc / unwritten */ 32 unsigned int io_type; /* delalloc / unwritten */
33 int io_error; /* I/O error code */ 33 int io_error; /* I/O error code */
34 atomic_t io_remaining; /* hold count */ 34 atomic_t io_remaining; /* hold count */
35 struct bhv_vnode *io_vnode; /* file being written to */ 35 struct inode *io_inode; /* 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 */
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 39f44ee572e8..b9c8589e05c2 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -187,6 +187,19 @@ free_address(
187{ 187{
188 a_list_t *aentry; 188 a_list_t *aentry;
189 189
190#ifdef CONFIG_XEN
191 /*
192 * Xen needs to be able to make sure it can get an exclusive
193 * RO mapping of pages it wants to turn into a pagetable. If
194 * a newly allocated page is also still being vmap()ed by xfs,
195 * it will cause pagetable construction to fail. This is a
196 * quick workaround to always eagerly unmap pages so that Xen
197 * is happy.
198 */
199 vunmap(addr);
200 return;
201#endif
202
190 aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT); 203 aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT);
191 if (likely(aentry)) { 204 if (likely(aentry)) {
192 spin_lock(&as_lock); 205 spin_lock(&as_lock);
@@ -997,7 +1010,18 @@ xfs_buf_iodone_work(
997 xfs_buf_t *bp = 1010 xfs_buf_t *bp =
998 container_of(work, xfs_buf_t, b_iodone_work); 1011 container_of(work, xfs_buf_t, b_iodone_work);
999 1012
1000 if (bp->b_iodone) 1013 /*
1014 * We can get an EOPNOTSUPP to ordered writes. Here we clear the
1015 * ordered flag and reissue them. Because we can't tell the higher
1016 * layers directly that they should not issue ordered I/O anymore, they
1017 * need to check if the ordered flag was cleared during I/O completion.
1018 */
1019 if ((bp->b_error == EOPNOTSUPP) &&
1020 (bp->b_flags & (XBF_ORDERED|XBF_ASYNC)) == (XBF_ORDERED|XBF_ASYNC)) {
1021 XB_TRACE(bp, "ordered_retry", bp->b_iodone);
1022 bp->b_flags &= ~XBF_ORDERED;
1023 xfs_buf_iorequest(bp);
1024 } else if (bp->b_iodone)
1001 (*(bp->b_iodone))(bp); 1025 (*(bp->b_iodone))(bp);
1002 else if (bp->b_flags & XBF_ASYNC) 1026 else if (bp->b_flags & XBF_ASYNC)
1003 xfs_buf_relse(bp); 1027 xfs_buf_relse(bp);
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index e3a5fedac1ba..726449d4fd22 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -17,12 +17,18 @@
17 */ 17 */
18#include "xfs.h" 18#include "xfs.h"
19#include "xfs_types.h" 19#include "xfs_types.h"
20#include "xfs_dmapi.h" 20#include "xfs_inum.h"
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_ag.h"
25#include "xfs_dmapi.h"
24#include "xfs_mount.h" 26#include "xfs_mount.h"
25#include "xfs_export.h" 27#include "xfs_export.h"
28#include "xfs_vnodeops.h"
29#include "xfs_bmap_btree.h"
30#include "xfs_inode.h"
31#include "xfs_vfsops.h"
26 32
27static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, }; 33static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
28 34
@@ -96,9 +102,7 @@ xfs_fs_encode_fh(
96 int len; 102 int len;
97 int is64 = 0; 103 int is64 = 0;
98#if XFS_BIG_INUMS 104#if XFS_BIG_INUMS
99 bhv_vfs_t *vfs = vfs_from_sb(inode->i_sb); 105 if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS)) {
100
101 if (!(vfs->vfs_flag & VFS_32BITINODES)) {
102 /* filesystem may contain 64bit inode numbers */ 106 /* filesystem may contain 64bit inode numbers */
103 is64 = XFS_FILEID_TYPE_64FLAG; 107 is64 = XFS_FILEID_TYPE_64FLAG;
104 } 108 }
@@ -138,10 +142,9 @@ xfs_fs_get_dentry(
138 bhv_vnode_t *vp; 142 bhv_vnode_t *vp;
139 struct inode *inode; 143 struct inode *inode;
140 struct dentry *result; 144 struct dentry *result;
141 bhv_vfs_t *vfsp = vfs_from_sb(sb);
142 int error; 145 int error;
143 146
144 error = bhv_vfs_vget(vfsp, &vp, (fid_t *)data); 147 error = xfs_vget(XFS_M(sb), &vp, (fid_t *)data);
145 if (error || vp == NULL) 148 if (error || vp == NULL)
146 return ERR_PTR(-ESTALE) ; 149 return ERR_PTR(-ESTALE) ;
147 150
@@ -159,12 +162,11 @@ xfs_fs_get_parent(
159 struct dentry *child) 162 struct dentry *child)
160{ 163{
161 int error; 164 int error;
162 bhv_vnode_t *vp, *cvp; 165 bhv_vnode_t *cvp;
163 struct dentry *parent; 166 struct dentry *parent;
164 167
165 cvp = NULL; 168 cvp = NULL;
166 vp = vn_from_inode(child->d_inode); 169 error = xfs_lookup(XFS_I(child->d_inode), &dotdot, &cvp);
167 error = bhv_vop_lookup(vp, &dotdot, &cvp, 0, NULL, NULL);
168 if (unlikely(error)) 170 if (unlikely(error))
169 return ERR_PTR(-error); 171 return ERR_PTR(-error);
170 172
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 0d4001eafd16..fb8dd34041eb 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -37,6 +37,7 @@
37#include "xfs_error.h" 37#include "xfs_error.h"
38#include "xfs_rw.h" 38#include "xfs_rw.h"
39#include "xfs_ioctl32.h" 39#include "xfs_ioctl32.h"
40#include "xfs_vnodeops.h"
40 41
41#include <linux/dcache.h> 42#include <linux/dcache.h>
42#include <linux/smp_lock.h> 43#include <linux/smp_lock.h>
@@ -55,13 +56,12 @@ __xfs_file_read(
55 loff_t pos) 56 loff_t pos)
56{ 57{
57 struct file *file = iocb->ki_filp; 58 struct file *file = iocb->ki_filp;
58 bhv_vnode_t *vp = vn_from_inode(file->f_path.dentry->d_inode);
59 59
60 BUG_ON(iocb->ki_pos != pos); 60 BUG_ON(iocb->ki_pos != pos);
61 if (unlikely(file->f_flags & O_DIRECT)) 61 if (unlikely(file->f_flags & O_DIRECT))
62 ioflags |= IO_ISDIRECT; 62 ioflags |= IO_ISDIRECT;
63 return bhv_vop_read(vp, iocb, iov, nr_segs, &iocb->ki_pos, 63 return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov,
64 ioflags, NULL); 64 nr_segs, &iocb->ki_pos, ioflags);
65} 65}
66 66
67STATIC ssize_t 67STATIC ssize_t
@@ -93,14 +93,12 @@ __xfs_file_write(
93 loff_t pos) 93 loff_t pos)
94{ 94{
95 struct file *file = iocb->ki_filp; 95 struct file *file = iocb->ki_filp;
96 struct inode *inode = file->f_mapping->host;
97 bhv_vnode_t *vp = vn_from_inode(inode);
98 96
99 BUG_ON(iocb->ki_pos != pos); 97 BUG_ON(iocb->ki_pos != pos);
100 if (unlikely(file->f_flags & O_DIRECT)) 98 if (unlikely(file->f_flags & O_DIRECT))
101 ioflags |= IO_ISDIRECT; 99 ioflags |= IO_ISDIRECT;
102 return bhv_vop_write(vp, iocb, iov, nr_segs, &iocb->ki_pos, 100 return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs,
103 ioflags, NULL); 101 &iocb->ki_pos, ioflags);
104} 102}
105 103
106STATIC ssize_t 104STATIC ssize_t
@@ -131,8 +129,8 @@ xfs_file_splice_read(
131 size_t len, 129 size_t len,
132 unsigned int flags) 130 unsigned int flags)
133{ 131{
134 return bhv_vop_splice_read(vn_from_inode(infilp->f_path.dentry->d_inode), 132 return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
135 infilp, ppos, pipe, len, flags, 0, NULL); 133 infilp, ppos, pipe, len, flags, 0);
136} 134}
137 135
138STATIC ssize_t 136STATIC ssize_t
@@ -143,9 +141,8 @@ xfs_file_splice_read_invis(
143 size_t len, 141 size_t len,
144 unsigned int flags) 142 unsigned int flags)
145{ 143{
146 return bhv_vop_splice_read(vn_from_inode(infilp->f_path.dentry->d_inode), 144 return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode),
147 infilp, ppos, pipe, len, flags, IO_INVIS, 145 infilp, ppos, pipe, len, flags, IO_INVIS);
148 NULL);
149} 146}
150 147
151STATIC ssize_t 148STATIC ssize_t
@@ -156,8 +153,8 @@ xfs_file_splice_write(
156 size_t len, 153 size_t len,
157 unsigned int flags) 154 unsigned int flags)
158{ 155{
159 return bhv_vop_splice_write(vn_from_inode(outfilp->f_path.dentry->d_inode), 156 return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
160 pipe, outfilp, ppos, len, flags, 0, NULL); 157 pipe, outfilp, ppos, len, flags, 0);
161} 158}
162 159
163STATIC ssize_t 160STATIC ssize_t
@@ -168,9 +165,8 @@ xfs_file_splice_write_invis(
168 size_t len, 165 size_t len,
169 unsigned int flags) 166 unsigned int flags)
170{ 167{
171 return bhv_vop_splice_write(vn_from_inode(outfilp->f_path.dentry->d_inode), 168 return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode),
172 pipe, outfilp, ppos, len, flags, IO_INVIS, 169 pipe, outfilp, ppos, len, flags, IO_INVIS);
173 NULL);
174} 170}
175 171
176STATIC int 172STATIC int
@@ -180,7 +176,7 @@ xfs_file_open(
180{ 176{
181 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) 177 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
182 return -EFBIG; 178 return -EFBIG;
183 return -bhv_vop_open(vn_from_inode(inode), NULL); 179 return -xfs_open(XFS_I(inode));
184} 180}
185 181
186STATIC int 182STATIC int
@@ -188,11 +184,7 @@ xfs_file_release(
188 struct inode *inode, 184 struct inode *inode,
189 struct file *filp) 185 struct file *filp)
190{ 186{
191 bhv_vnode_t *vp = vn_from_inode(inode); 187 return -xfs_release(XFS_I(inode));
192
193 if (vp)
194 return -bhv_vop_release(vp);
195 return 0;
196} 188}
197 189
198STATIC int 190STATIC int
@@ -201,14 +193,13 @@ xfs_file_fsync(
201 struct dentry *dentry, 193 struct dentry *dentry,
202 int datasync) 194 int datasync)
203{ 195{
204 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
205 int flags = FSYNC_WAIT; 196 int flags = FSYNC_WAIT;
206 197
207 if (datasync) 198 if (datasync)
208 flags |= FSYNC_DATA; 199 flags |= FSYNC_DATA;
209 if (VN_TRUNC(vp)) 200 xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED);
210 VUNTRUNCATE(vp); 201 return -xfs_fsync(XFS_I(dentry->d_inode), flags,
211 return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1); 202 (xfs_off_t)0, (xfs_off_t)-1);
212} 203}
213 204
214#ifdef CONFIG_XFS_DMAPI 205#ifdef CONFIG_XFS_DMAPI
@@ -233,74 +224,30 @@ xfs_file_readdir(
233 void *dirent, 224 void *dirent,
234 filldir_t filldir) 225 filldir_t filldir)
235{ 226{
236 int error = 0; 227 struct inode *inode = filp->f_path.dentry->d_inode;
237 bhv_vnode_t *vp = vn_from_inode(filp->f_path.dentry->d_inode); 228 xfs_inode_t *ip = XFS_I(inode);
238 uio_t uio; 229 int error;
239 iovec_t iov; 230 size_t bufsize;
240 int eof = 0; 231
241 caddr_t read_buf; 232 /*
242 int namelen, size = 0; 233 * The Linux API doesn't pass down the total size of the buffer
243 size_t rlen = PAGE_CACHE_SIZE; 234 * we read into down to the filesystem. With the filldir concept
244 xfs_off_t start_offset, curr_offset; 235 * it's not needed for correct information, but the XFS dir2 leaf
245 xfs_dirent_t *dbp = NULL; 236 * code wants an estimate of the buffer size to calculate it's
246 237 * readahead window and size the buffers used for mapping to
247 /* Try fairly hard to get memory */ 238 * physical blocks.
248 do { 239 *
249 if ((read_buf = kmalloc(rlen, GFP_KERNEL))) 240 * Try to give it an estimate that's good enough, maybe at some
250 break; 241 * point we can change the ->readdir prototype to include the
251 rlen >>= 1; 242 * buffer size.
252 } while (rlen >= 1024); 243 */
253 244 bufsize = (size_t)min_t(loff_t, PAGE_SIZE, inode->i_size);
254 if (read_buf == NULL)
255 return -ENOMEM;
256
257 uio.uio_iov = &iov;
258 uio.uio_segflg = UIO_SYSSPACE;
259 curr_offset = filp->f_pos;
260 if (filp->f_pos != 0x7fffffff)
261 uio.uio_offset = filp->f_pos;
262 else
263 uio.uio_offset = 0xffffffff;
264
265 while (!eof) {
266 uio.uio_resid = iov.iov_len = rlen;
267 iov.iov_base = read_buf;
268 uio.uio_iovcnt = 1;
269
270 start_offset = uio.uio_offset;
271
272 error = bhv_vop_readdir(vp, &uio, NULL, &eof);
273 if ((uio.uio_offset == start_offset) || error) {
274 size = 0;
275 break;
276 }
277
278 size = rlen - uio.uio_resid;
279 dbp = (xfs_dirent_t *)read_buf;
280 while (size > 0) {
281 namelen = strlen(dbp->d_name);
282
283 if (filldir(dirent, dbp->d_name, namelen,
284 (loff_t) curr_offset & 0x7fffffff,
285 (ino_t) dbp->d_ino,
286 DT_UNKNOWN)) {
287 goto done;
288 }
289 size -= dbp->d_reclen;
290 curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */;
291 dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen);
292 }
293 }
294done:
295 if (!error) {
296 if (size == 0)
297 filp->f_pos = uio.uio_offset & 0x7fffffff;
298 else if (dbp)
299 filp->f_pos = curr_offset;
300 }
301 245
302 kfree(read_buf); 246 error = xfs_readdir(ip, dirent, bufsize,
303 return -error; 247 (xfs_off_t *)&filp->f_pos, filldir);
248 if (error)
249 return -error;
250 return 0;
304} 251}
305 252
306STATIC int 253STATIC int
@@ -312,7 +259,7 @@ xfs_file_mmap(
312 vma->vm_flags |= VM_CAN_NONLINEAR; 259 vma->vm_flags |= VM_CAN_NONLINEAR;
313 260
314#ifdef CONFIG_XFS_DMAPI 261#ifdef CONFIG_XFS_DMAPI
315 if (vn_from_inode(filp->f_path.dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI) 262 if (XFS_M(filp->f_path.dentry->d_inode->i_sb)->m_flags & XFS_MOUNT_DMAPI)
316 vma->vm_ops = &xfs_dmapi_file_vm_ops; 263 vma->vm_ops = &xfs_dmapi_file_vm_ops;
317#endif /* CONFIG_XFS_DMAPI */ 264#endif /* CONFIG_XFS_DMAPI */
318 265
@@ -328,10 +275,9 @@ xfs_file_ioctl(
328{ 275{
329 int error; 276 int error;
330 struct inode *inode = filp->f_path.dentry->d_inode; 277 struct inode *inode = filp->f_path.dentry->d_inode;
331 bhv_vnode_t *vp = vn_from_inode(inode);
332 278
333 error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p); 279 error = xfs_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p);
334 VMODIFY(vp); 280 xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
335 281
336 /* NOTE: some of the ioctl's return positive #'s as a 282 /* NOTE: some of the ioctl's return positive #'s as a
337 * byte count indicating success, such as 283 * byte count indicating success, such as
@@ -350,10 +296,9 @@ xfs_file_ioctl_invis(
350{ 296{
351 int error; 297 int error;
352 struct inode *inode = filp->f_path.dentry->d_inode; 298 struct inode *inode = filp->f_path.dentry->d_inode;
353 bhv_vnode_t *vp = vn_from_inode(inode);
354 299
355 error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p); 300 error = xfs_ioctl(XFS_I(inode), filp, IO_INVIS, cmd, (void __user *)p);
356 VMODIFY(vp); 301 xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
357 302
358 /* NOTE: some of the ioctl's return positive #'s as a 303 /* NOTE: some of the ioctl's return positive #'s as a
359 * byte count indicating success, such as 304 * byte count indicating success, such as
@@ -371,16 +316,14 @@ xfs_vm_mprotect(
371 struct vm_area_struct *vma, 316 struct vm_area_struct *vma,
372 unsigned int newflags) 317 unsigned int newflags)
373{ 318{
374 bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_path.dentry->d_inode); 319 struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
320 struct xfs_mount *mp = XFS_M(inode->i_sb);
375 int error = 0; 321 int error = 0;
376 322
377 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 323 if (mp->m_flags & XFS_MOUNT_DMAPI) {
378 if ((vma->vm_flags & VM_MAYSHARE) && 324 if ((vma->vm_flags & VM_MAYSHARE) &&
379 (newflags & VM_WRITE) && !(vma->vm_flags & VM_WRITE)) { 325 (newflags & VM_WRITE) && !(vma->vm_flags & VM_WRITE))
380 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
381
382 error = XFS_SEND_MMAP(mp, vma, VM_WRITE); 326 error = XFS_SEND_MMAP(mp, vma, VM_WRITE);
383 }
384 } 327 }
385 return error; 328 return error;
386} 329}
@@ -397,18 +340,17 @@ STATIC int
397xfs_file_open_exec( 340xfs_file_open_exec(
398 struct inode *inode) 341 struct inode *inode)
399{ 342{
400 bhv_vnode_t *vp = vn_from_inode(inode); 343 struct xfs_mount *mp = XFS_M(inode->i_sb);
401 344
402 if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) { 345 if (unlikely(mp->m_flags & XFS_MOUNT_DMAPI)) {
403 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp); 346 if (DM_EVENT_ENABLED(XFS_I(inode), DM_EVENT_READ)) {
404 xfs_inode_t *ip = xfs_vtoi(vp); 347 bhv_vnode_t *vp = vn_from_inode(inode);
405 348
406 if (!ip) 349 return -XFS_SEND_DATA(mp, DM_EVENT_READ,
407 return -EINVAL; 350 vp, 0, 0, 0, NULL);
408 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) 351 }
409 return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
410 0, 0, 0, NULL);
411 } 352 }
353
412 return 0; 354 return 0;
413} 355}
414#endif /* HAVE_FOP_OPEN_EXEC */ 356#endif /* HAVE_FOP_OPEN_EXEC */
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index 2eb87cd082af..ac6d34cc355d 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -16,66 +16,78 @@
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#include "xfs.h" 18#include "xfs.h"
19#include "xfs_vnodeops.h"
20
21/*
22 * The following six includes are needed so that we can include
23 * xfs_inode.h. What a mess..
24 */
25#include "xfs_bmap_btree.h"
26#include "xfs_inum.h"
27#include "xfs_dir2.h"
28#include "xfs_dir2_sf.h"
29#include "xfs_attr_sf.h"
30#include "xfs_dinode.h"
31
32#include "xfs_inode.h"
19 33
20int fs_noerr(void) { return 0; } 34int fs_noerr(void) { return 0; }
21int fs_nosys(void) { return ENOSYS; } 35int fs_nosys(void) { return ENOSYS; }
22void fs_noval(void) { return; } 36void fs_noval(void) { return; }
23 37
24void 38void
25fs_tosspages( 39xfs_tosspages(
26 bhv_desc_t *bdp, 40 xfs_inode_t *ip,
27 xfs_off_t first, 41 xfs_off_t first,
28 xfs_off_t last, 42 xfs_off_t last,
29 int fiopt) 43 int fiopt)
30{ 44{
31 bhv_vnode_t *vp = BHV_TO_VNODE(bdp); 45 bhv_vnode_t *vp = XFS_ITOV(ip);
32 struct inode *ip = vn_to_inode(vp); 46 struct inode *inode = vn_to_inode(vp);
33 47
34 if (VN_CACHED(vp)) 48 if (VN_CACHED(vp))
35 truncate_inode_pages(ip->i_mapping, first); 49 truncate_inode_pages(inode->i_mapping, first);
36} 50}
37 51
38int 52int
39fs_flushinval_pages( 53xfs_flushinval_pages(
40 bhv_desc_t *bdp, 54 xfs_inode_t *ip,
41 xfs_off_t first, 55 xfs_off_t first,
42 xfs_off_t last, 56 xfs_off_t last,
43 int fiopt) 57 int fiopt)
44{ 58{
45 bhv_vnode_t *vp = BHV_TO_VNODE(bdp); 59 bhv_vnode_t *vp = XFS_ITOV(ip);
46 struct inode *ip = vn_to_inode(vp); 60 struct inode *inode = vn_to_inode(vp);
47 int ret = 0; 61 int ret = 0;
48 62
49 if (VN_CACHED(vp)) { 63 if (VN_CACHED(vp)) {
50 if (VN_TRUNC(vp)) 64 xfs_iflags_clear(ip, XFS_ITRUNCATED);
51 VUNTRUNCATE(vp); 65 ret = filemap_write_and_wait(inode->i_mapping);
52 ret = filemap_write_and_wait(ip->i_mapping);
53 if (!ret) 66 if (!ret)
54 truncate_inode_pages(ip->i_mapping, first); 67 truncate_inode_pages(inode->i_mapping, first);
55 } 68 }
56 return ret; 69 return ret;
57} 70}
58 71
59int 72int
60fs_flush_pages( 73xfs_flush_pages(
61 bhv_desc_t *bdp, 74 xfs_inode_t *ip,
62 xfs_off_t first, 75 xfs_off_t first,
63 xfs_off_t last, 76 xfs_off_t last,
64 uint64_t flags, 77 uint64_t flags,
65 int fiopt) 78 int fiopt)
66{ 79{
67 bhv_vnode_t *vp = BHV_TO_VNODE(bdp); 80 bhv_vnode_t *vp = XFS_ITOV(ip);
68 struct inode *ip = vn_to_inode(vp); 81 struct inode *inode = vn_to_inode(vp);
69 int ret = 0; 82 int ret = 0;
70 int ret2; 83 int ret2;
71 84
72 if (VN_DIRTY(vp)) { 85 if (VN_DIRTY(vp)) {
73 if (VN_TRUNC(vp)) 86 xfs_iflags_clear(ip, XFS_ITRUNCATED);
74 VUNTRUNCATE(vp); 87 ret = filemap_fdatawrite(inode->i_mapping);
75 ret = filemap_fdatawrite(ip->i_mapping);
76 if (flags & XFS_B_ASYNC) 88 if (flags & XFS_B_ASYNC)
77 return ret; 89 return ret;
78 ret2 = filemap_fdatawait(ip->i_mapping); 90 ret2 = filemap_fdatawait(inode->i_mapping);
79 if (!ret) 91 if (!ret)
80 ret = ret2; 92 ret = ret2;
81 } 93 }
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.h b/fs/xfs/linux-2.6/xfs_fs_subr.h
index c1b53118a303..82bb19b2599e 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.h
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.h
@@ -18,12 +18,8 @@
18#ifndef __XFS_FS_SUBR_H__ 18#ifndef __XFS_FS_SUBR_H__
19#define __XFS_FS_SUBR_H__ 19#define __XFS_FS_SUBR_H__
20 20
21struct cred;
22extern int fs_noerr(void); 21extern int fs_noerr(void);
23extern int fs_nosys(void); 22extern int fs_nosys(void);
24extern void fs_noval(void); 23extern void fs_noval(void);
25extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
26extern int fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
27extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
28 24
29#endif /* __XFS_FS_SUBR_H__ */ 25#endif /* __XFS_FS_SUBR_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c
index 81565dea9af7..9febf9dc999d 100644
--- a/fs/xfs/linux-2.6/xfs_globals.c
+++ b/fs/xfs/linux-2.6/xfs_globals.c
@@ -20,11 +20,6 @@
20#include "xfs_sysctl.h" 20#include "xfs_sysctl.h"
21 21
22/* 22/*
23 * System memory size - used to scale certain data structures in XFS.
24 */
25unsigned long xfs_physmem;
26
27/*
28 * Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n, 23 * Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n,
29 * other XFS code uses these values. Times are measured in centisecs (i.e. 24 * other XFS code uses these values. Times are measured in centisecs (i.e.
30 * 100ths of a second). 25 * 100ths of a second).
diff --git a/fs/xfs/linux-2.6/xfs_globals.h b/fs/xfs/linux-2.6/xfs_globals.h
index e1a22bfcf865..2770b0085ee8 100644
--- a/fs/xfs/linux-2.6/xfs_globals.h
+++ b/fs/xfs/linux-2.6/xfs_globals.h
@@ -19,7 +19,6 @@
19#define __XFS_GLOBALS_H__ 19#define __XFS_GLOBALS_H__
20 20
21extern uint64_t xfs_panic_mask; /* set to cause more panics */ 21extern uint64_t xfs_panic_mask; /* set to cause more panics */
22extern unsigned long xfs_physmem;
23extern struct cred *sys_cred; 22extern struct cred *sys_cred;
24 23
25#endif /* __XFS_GLOBALS_H__ */ 24#endif /* __XFS_GLOBALS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 5917808abbd6..ffec630e7db7 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -47,6 +47,7 @@
47#include "xfs_utils.h" 47#include "xfs_utils.h"
48#include "xfs_dfrag.h" 48#include "xfs_dfrag.h"
49#include "xfs_fsops.h" 49#include "xfs_fsops.h"
50#include "xfs_vnodeops.h"
50 51
51#include <linux/capability.h> 52#include <linux/capability.h>
52#include <linux/dcache.h> 53#include <linux/dcache.h>
@@ -137,7 +138,8 @@ xfs_find_handle(
137 vp = vn_from_inode(inode); 138 vp = vn_from_inode(inode);
138 139
139 /* now we can grab the fsid */ 140 /* now we can grab the fsid */
140 memcpy(&handle.ha_fsid, vp->v_vfsp->vfs_altfsid, sizeof(xfs_fsid_t)); 141 memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
142 sizeof(xfs_fsid_t));
141 hsize = sizeof(xfs_fsid_t); 143 hsize = sizeof(xfs_fsid_t);
142 144
143 if (cmd != XFS_IOC_PATH_TO_FSHANDLE) { 145 if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
@@ -349,19 +351,44 @@ xfs_open_by_handle(
349 return new_fd; 351 return new_fd;
350} 352}
351 353
354/*
355 * This is a copy from fs/namei.c:vfs_readlink(), except for removing it's
356 * unused first argument.
357 */
358STATIC int
359do_readlink(
360 char __user *buffer,
361 int buflen,
362 const char *link)
363{
364 int len;
365
366 len = PTR_ERR(link);
367 if (IS_ERR(link))
368 goto out;
369
370 len = strlen(link);
371 if (len > (unsigned) buflen)
372 len = buflen;
373 if (copy_to_user(buffer, link, len))
374 len = -EFAULT;
375 out:
376 return len;
377}
378
379
352STATIC int 380STATIC int
353xfs_readlink_by_handle( 381xfs_readlink_by_handle(
354 xfs_mount_t *mp, 382 xfs_mount_t *mp,
355 void __user *arg, 383 void __user *arg,
356 struct inode *parinode) 384 struct inode *parinode)
357{ 385{
358 int error;
359 struct iovec aiov;
360 struct uio auio;
361 struct inode *inode; 386 struct inode *inode;
362 xfs_fsop_handlereq_t hreq; 387 xfs_fsop_handlereq_t hreq;
363 bhv_vnode_t *vp; 388 bhv_vnode_t *vp;
364 __u32 olen; 389 __u32 olen;
390 void *link;
391 int error;
365 392
366 if (!capable(CAP_SYS_ADMIN)) 393 if (!capable(CAP_SYS_ADMIN))
367 return -XFS_ERROR(EPERM); 394 return -XFS_ERROR(EPERM);
@@ -374,29 +401,31 @@ xfs_readlink_by_handle(
374 401
375 /* Restrict this handle operation to symlinks only. */ 402 /* Restrict this handle operation to symlinks only. */
376 if (!S_ISLNK(inode->i_mode)) { 403 if (!S_ISLNK(inode->i_mode)) {
377 VN_RELE(vp); 404 error = -XFS_ERROR(EINVAL);
378 return -XFS_ERROR(EINVAL); 405 goto out_iput;
379 } 406 }
380 407
381 if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) { 408 if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) {
382 VN_RELE(vp); 409 error = -XFS_ERROR(EFAULT);
383 return -XFS_ERROR(EFAULT); 410 goto out_iput;
384 } 411 }
385 aiov.iov_len = olen;
386 aiov.iov_base = hreq.ohandle;
387 412
388 auio.uio_iov = (struct kvec *)&aiov; 413 link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
389 auio.uio_iovcnt = 1; 414 if (!link)
390 auio.uio_offset = 0; 415 goto out_iput;
391 auio.uio_segflg = UIO_USERSPACE;
392 auio.uio_resid = olen;
393 416
394 error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL); 417 error = -xfs_readlink(XFS_I(inode), link);
395 VN_RELE(vp);
396 if (error) 418 if (error)
397 return -error; 419 goto out_kfree;
420 error = do_readlink(hreq.ohandle, olen, link);
421 if (error)
422 goto out_kfree;
398 423
399 return (olen - auio.uio_resid); 424 out_kfree:
425 kfree(link);
426 out_iput:
427 iput(inode);
428 return error;
400} 429}
401 430
402STATIC int 431STATIC int
@@ -409,7 +438,6 @@ xfs_fssetdm_by_handle(
409 struct fsdmidata fsd; 438 struct fsdmidata fsd;
410 xfs_fsop_setdm_handlereq_t dmhreq; 439 xfs_fsop_setdm_handlereq_t dmhreq;
411 struct inode *inode; 440 struct inode *inode;
412 bhv_desc_t *bdp;
413 bhv_vnode_t *vp; 441 bhv_vnode_t *vp;
414 442
415 if (!capable(CAP_MKNOD)) 443 if (!capable(CAP_MKNOD))
@@ -431,8 +459,8 @@ xfs_fssetdm_by_handle(
431 return -XFS_ERROR(EFAULT); 459 return -XFS_ERROR(EFAULT);
432 } 460 }
433 461
434 bdp = bhv_base_unlocked(VN_BHV_HEAD(vp)); 462 error = xfs_set_dmattrs(xfs_vtoi(vp),
435 error = xfs_set_dmattrs(bdp, fsd.fsd_dmevmask, fsd.fsd_dmstate, NULL); 463 fsd.fsd_dmevmask, fsd.fsd_dmstate);
436 464
437 VN_RELE(vp); 465 VN_RELE(vp);
438 if (error) 466 if (error)
@@ -470,8 +498,8 @@ xfs_attrlist_by_handle(
470 goto out_vn_rele; 498 goto out_vn_rele;
471 499
472 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; 500 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
473 error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags, 501 error = xfs_attr_list(XFS_I(inode), kbuf, al_hreq.buflen,
474 cursor, NULL); 502 al_hreq.flags, cursor);
475 if (error) 503 if (error)
476 goto out_kfree; 504 goto out_kfree;
477 505
@@ -488,7 +516,7 @@ xfs_attrlist_by_handle(
488 516
489STATIC int 517STATIC int
490xfs_attrmulti_attr_get( 518xfs_attrmulti_attr_get(
491 bhv_vnode_t *vp, 519 struct inode *inode,
492 char *name, 520 char *name,
493 char __user *ubuf, 521 char __user *ubuf,
494 __uint32_t *len, 522 __uint32_t *len,
@@ -503,7 +531,7 @@ xfs_attrmulti_attr_get(
503 if (!kbuf) 531 if (!kbuf)
504 return ENOMEM; 532 return ENOMEM;
505 533
506 error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL); 534 error = xfs_attr_get(XFS_I(inode), name, kbuf, len, flags, NULL);
507 if (error) 535 if (error)
508 goto out_kfree; 536 goto out_kfree;
509 537
@@ -517,7 +545,7 @@ xfs_attrmulti_attr_get(
517 545
518STATIC int 546STATIC int
519xfs_attrmulti_attr_set( 547xfs_attrmulti_attr_set(
520 bhv_vnode_t *vp, 548 struct inode *inode,
521 char *name, 549 char *name,
522 const char __user *ubuf, 550 const char __user *ubuf,
523 __uint32_t len, 551 __uint32_t len,
@@ -526,9 +554,9 @@ xfs_attrmulti_attr_set(
526 char *kbuf; 554 char *kbuf;
527 int error = EFAULT; 555 int error = EFAULT;
528 556
529 if (IS_RDONLY(&vp->v_inode)) 557 if (IS_RDONLY(inode))
530 return -EROFS; 558 return -EROFS;
531 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) 559 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
532 return EPERM; 560 return EPERM;
533 if (len > XATTR_SIZE_MAX) 561 if (len > XATTR_SIZE_MAX)
534 return EINVAL; 562 return EINVAL;
@@ -540,7 +568,7 @@ xfs_attrmulti_attr_set(
540 if (copy_from_user(kbuf, ubuf, len)) 568 if (copy_from_user(kbuf, ubuf, len))
541 goto out_kfree; 569 goto out_kfree;
542 570
543 error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL); 571 error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
544 572
545 out_kfree: 573 out_kfree:
546 kfree(kbuf); 574 kfree(kbuf);
@@ -549,15 +577,15 @@ xfs_attrmulti_attr_set(
549 577
550STATIC int 578STATIC int
551xfs_attrmulti_attr_remove( 579xfs_attrmulti_attr_remove(
552 bhv_vnode_t *vp, 580 struct inode *inode,
553 char *name, 581 char *name,
554 __uint32_t flags) 582 __uint32_t flags)
555{ 583{
556 if (IS_RDONLY(&vp->v_inode)) 584 if (IS_RDONLY(inode))
557 return -EROFS; 585 return -EROFS;
558 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) 586 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
559 return EPERM; 587 return EPERM;
560 return bhv_vop_attr_remove(vp, name, flags, NULL); 588 return xfs_attr_remove(XFS_I(inode), name, flags);
561} 589}
562 590
563STATIC int 591STATIC int
@@ -613,17 +641,17 @@ xfs_attrmulti_by_handle(
613 641
614 switch (ops[i].am_opcode) { 642 switch (ops[i].am_opcode) {
615 case ATTR_OP_GET: 643 case ATTR_OP_GET:
616 ops[i].am_error = xfs_attrmulti_attr_get(vp, 644 ops[i].am_error = xfs_attrmulti_attr_get(inode,
617 attr_name, ops[i].am_attrvalue, 645 attr_name, ops[i].am_attrvalue,
618 &ops[i].am_length, ops[i].am_flags); 646 &ops[i].am_length, ops[i].am_flags);
619 break; 647 break;
620 case ATTR_OP_SET: 648 case ATTR_OP_SET:
621 ops[i].am_error = xfs_attrmulti_attr_set(vp, 649 ops[i].am_error = xfs_attrmulti_attr_set(inode,
622 attr_name, ops[i].am_attrvalue, 650 attr_name, ops[i].am_attrvalue,
623 ops[i].am_length, ops[i].am_flags); 651 ops[i].am_length, ops[i].am_flags);
624 break; 652 break;
625 case ATTR_OP_REMOVE: 653 case ATTR_OP_REMOVE:
626 ops[i].am_error = xfs_attrmulti_attr_remove(vp, 654 ops[i].am_error = xfs_attrmulti_attr_remove(inode,
627 attr_name, ops[i].am_flags); 655 attr_name, ops[i].am_flags);
628 break; 656 break;
629 default: 657 default:
@@ -649,7 +677,7 @@ xfs_attrmulti_by_handle(
649 677
650STATIC int 678STATIC int
651xfs_ioc_space( 679xfs_ioc_space(
652 bhv_desc_t *bdp, 680 struct xfs_inode *ip,
653 struct inode *inode, 681 struct inode *inode,
654 struct file *filp, 682 struct file *filp,
655 int flags, 683 int flags,
@@ -681,37 +709,37 @@ xfs_ioc_xattr(
681 void __user *arg); 709 void __user *arg);
682 710
683STATIC int 711STATIC int
712xfs_ioc_fsgetxattr(
713 xfs_inode_t *ip,
714 int attr,
715 void __user *arg);
716
717STATIC int
684xfs_ioc_getbmap( 718xfs_ioc_getbmap(
685 bhv_desc_t *bdp, 719 struct xfs_inode *ip,
686 int flags, 720 int flags,
687 unsigned int cmd, 721 unsigned int cmd,
688 void __user *arg); 722 void __user *arg);
689 723
690STATIC int 724STATIC int
691xfs_ioc_getbmapx( 725xfs_ioc_getbmapx(
692 bhv_desc_t *bdp, 726 struct xfs_inode *ip,
693 void __user *arg); 727 void __user *arg);
694 728
695int 729int
696xfs_ioctl( 730xfs_ioctl(
697 bhv_desc_t *bdp, 731 xfs_inode_t *ip,
698 struct inode *inode,
699 struct file *filp, 732 struct file *filp,
700 int ioflags, 733 int ioflags,
701 unsigned int cmd, 734 unsigned int cmd,
702 void __user *arg) 735 void __user *arg)
703{ 736{
737 struct inode *inode = filp->f_path.dentry->d_inode;
738 bhv_vnode_t *vp = vn_from_inode(inode);
739 xfs_mount_t *mp = ip->i_mount;
704 int error; 740 int error;
705 bhv_vnode_t *vp;
706 xfs_inode_t *ip;
707 xfs_mount_t *mp;
708 741
709 vp = vn_from_inode(inode); 742 vn_trace_entry(XFS_I(inode), "xfs_ioctl", (inst_t *)__return_address);
710
711 vn_trace_entry(vp, "xfs_ioctl", (inst_t *)__return_address);
712
713 ip = XFS_BHVTOI(bdp);
714 mp = ip->i_mount;
715 743
716 switch (cmd) { 744 switch (cmd) {
717 745
@@ -731,7 +759,7 @@ xfs_ioctl(
731 !capable(CAP_SYS_ADMIN)) 759 !capable(CAP_SYS_ADMIN))
732 return -EPERM; 760 return -EPERM;
733 761
734 return xfs_ioc_space(bdp, inode, filp, ioflags, cmd, arg); 762 return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg);
735 763
736 case XFS_IOC_DIOINFO: { 764 case XFS_IOC_DIOINFO: {
737 struct dioattr da; 765 struct dioattr da;
@@ -761,11 +789,13 @@ xfs_ioctl(
761 case XFS_IOC_GETVERSION: 789 case XFS_IOC_GETVERSION:
762 return put_user(inode->i_generation, (int __user *)arg); 790 return put_user(inode->i_generation, (int __user *)arg);
763 791
792 case XFS_IOC_FSGETXATTR:
793 return xfs_ioc_fsgetxattr(ip, 0, arg);
794 case XFS_IOC_FSGETXATTRA:
795 return xfs_ioc_fsgetxattr(ip, 1, arg);
764 case XFS_IOC_GETXFLAGS: 796 case XFS_IOC_GETXFLAGS:
765 case XFS_IOC_SETXFLAGS: 797 case XFS_IOC_SETXFLAGS:
766 case XFS_IOC_FSGETXATTR:
767 case XFS_IOC_FSSETXATTR: 798 case XFS_IOC_FSSETXATTR:
768 case XFS_IOC_FSGETXATTRA:
769 return xfs_ioc_xattr(vp, ip, filp, cmd, arg); 799 return xfs_ioc_xattr(vp, ip, filp, cmd, arg);
770 800
771 case XFS_IOC_FSSETDM: { 801 case XFS_IOC_FSSETDM: {
@@ -774,17 +804,17 @@ xfs_ioctl(
774 if (copy_from_user(&dmi, arg, sizeof(dmi))) 804 if (copy_from_user(&dmi, arg, sizeof(dmi)))
775 return -XFS_ERROR(EFAULT); 805 return -XFS_ERROR(EFAULT);
776 806
777 error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate, 807 error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
778 NULL); 808 dmi.fsd_dmstate);
779 return -error; 809 return -error;
780 } 810 }
781 811
782 case XFS_IOC_GETBMAP: 812 case XFS_IOC_GETBMAP:
783 case XFS_IOC_GETBMAPA: 813 case XFS_IOC_GETBMAPA:
784 return xfs_ioc_getbmap(bdp, ioflags, cmd, arg); 814 return xfs_ioc_getbmap(ip, ioflags, cmd, arg);
785 815
786 case XFS_IOC_GETBMAPX: 816 case XFS_IOC_GETBMAPX:
787 return xfs_ioc_getbmapx(bdp, arg); 817 return xfs_ioc_getbmapx(ip, arg);
788 818
789 case XFS_IOC_FD_TO_HANDLE: 819 case XFS_IOC_FD_TO_HANDLE:
790 case XFS_IOC_PATH_TO_HANDLE: 820 case XFS_IOC_PATH_TO_HANDLE:
@@ -944,7 +974,7 @@ xfs_ioctl(
944 if (!capable(CAP_SYS_ADMIN)) 974 if (!capable(CAP_SYS_ADMIN))
945 return -EPERM; 975 return -EPERM;
946 976
947 error = xfs_errortag_clearall(mp); 977 error = xfs_errortag_clearall(mp, 1);
948 return -error; 978 return -error;
949 979
950 default: 980 default:
@@ -954,7 +984,7 @@ xfs_ioctl(
954 984
955STATIC int 985STATIC int
956xfs_ioc_space( 986xfs_ioc_space(
957 bhv_desc_t *bdp, 987 struct xfs_inode *ip,
958 struct inode *inode, 988 struct inode *inode,
959 struct file *filp, 989 struct file *filp,
960 int ioflags, 990 int ioflags,
@@ -982,7 +1012,7 @@ xfs_ioc_space(
982 if (ioflags & IO_INVIS) 1012 if (ioflags & IO_INVIS)
983 attr_flags |= ATTR_DMI; 1013 attr_flags |= ATTR_DMI;
984 1014
985 error = xfs_change_file_space(bdp, cmd, &bf, filp->f_pos, 1015 error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos,
986 NULL, attr_flags); 1016 NULL, attr_flags);
987 return -error; 1017 return -error;
988} 1018}
@@ -1140,6 +1170,42 @@ xfs_di2lxflags(
1140} 1170}
1141 1171
1142STATIC int 1172STATIC int
1173xfs_ioc_fsgetxattr(
1174 xfs_inode_t *ip,
1175 int attr,
1176 void __user *arg)
1177{
1178 struct fsxattr fa;
1179
1180 xfs_ilock(ip, XFS_ILOCK_SHARED);
1181 fa.fsx_xflags = xfs_ip2xflags(ip);
1182 fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
1183 fa.fsx_projid = ip->i_d.di_projid;
1184
1185 if (attr) {
1186 if (ip->i_afp) {
1187 if (ip->i_afp->if_flags & XFS_IFEXTENTS)
1188 fa.fsx_nextents = ip->i_afp->if_bytes /
1189 sizeof(xfs_bmbt_rec_t);
1190 else
1191 fa.fsx_nextents = ip->i_d.di_anextents;
1192 } else
1193 fa.fsx_nextents = 0;
1194 } else {
1195 if (ip->i_df.if_flags & XFS_IFEXTENTS)
1196 fa.fsx_nextents = ip->i_df.if_bytes /
1197 sizeof(xfs_bmbt_rec_t);
1198 else
1199 fa.fsx_nextents = ip->i_d.di_nextents;
1200 }
1201 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1202
1203 if (copy_to_user(arg, &fa, sizeof(fa)))
1204 return -EFAULT;
1205 return 0;
1206}
1207
1208STATIC int
1143xfs_ioc_xattr( 1209xfs_ioc_xattr(
1144 bhv_vnode_t *vp, 1210 bhv_vnode_t *vp,
1145 xfs_inode_t *ip, 1211 xfs_inode_t *ip,
@@ -1158,27 +1224,6 @@ xfs_ioc_xattr(
1158 return -ENOMEM; 1224 return -ENOMEM;
1159 1225
1160 switch (cmd) { 1226 switch (cmd) {
1161 case XFS_IOC_FSGETXATTR: {
1162 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1163 XFS_AT_NEXTENTS | XFS_AT_PROJID;
1164 error = bhv_vop_getattr(vp, vattr, 0, NULL);
1165 if (unlikely(error)) {
1166 error = -error;
1167 break;
1168 }
1169
1170 fa.fsx_xflags = vattr->va_xflags;
1171 fa.fsx_extsize = vattr->va_extsize;
1172 fa.fsx_nextents = vattr->va_nextents;
1173 fa.fsx_projid = vattr->va_projid;
1174
1175 if (copy_to_user(arg, &fa, sizeof(fa))) {
1176 error = -EFAULT;
1177 break;
1178 }
1179 break;
1180 }
1181
1182 case XFS_IOC_FSSETXATTR: { 1227 case XFS_IOC_FSSETXATTR: {
1183 if (copy_from_user(&fa, arg, sizeof(fa))) { 1228 if (copy_from_user(&fa, arg, sizeof(fa))) {
1184 error = -EFAULT; 1229 error = -EFAULT;
@@ -1194,34 +1239,13 @@ xfs_ioc_xattr(
1194 vattr->va_extsize = fa.fsx_extsize; 1239 vattr->va_extsize = fa.fsx_extsize;
1195 vattr->va_projid = fa.fsx_projid; 1240 vattr->va_projid = fa.fsx_projid;
1196 1241
1197 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL); 1242 error = xfs_setattr(ip, vattr, attr_flags, NULL);
1198 if (likely(!error)) 1243 if (likely(!error))
1199 __vn_revalidate(vp, vattr); /* update flags */ 1244 __vn_revalidate(vp, vattr); /* update flags */
1200 error = -error; 1245 error = -error;
1201 break; 1246 break;
1202 } 1247 }
1203 1248
1204 case XFS_IOC_FSGETXATTRA: {
1205 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1206 XFS_AT_ANEXTENTS | XFS_AT_PROJID;
1207 error = bhv_vop_getattr(vp, vattr, 0, NULL);
1208 if (unlikely(error)) {
1209 error = -error;
1210 break;
1211 }
1212
1213 fa.fsx_xflags = vattr->va_xflags;
1214 fa.fsx_extsize = vattr->va_extsize;
1215 fa.fsx_nextents = vattr->va_anextents;
1216 fa.fsx_projid = vattr->va_projid;
1217
1218 if (copy_to_user(arg, &fa, sizeof(fa))) {
1219 error = -EFAULT;
1220 break;
1221 }
1222 break;
1223 }
1224
1225 case XFS_IOC_GETXFLAGS: { 1249 case XFS_IOC_GETXFLAGS: {
1226 flags = xfs_di2lxflags(ip->i_d.di_flags); 1250 flags = xfs_di2lxflags(ip->i_d.di_flags);
1227 if (copy_to_user(arg, &flags, sizeof(flags))) 1251 if (copy_to_user(arg, &flags, sizeof(flags)))
@@ -1250,7 +1274,7 @@ xfs_ioc_xattr(
1250 vattr->va_xflags = xfs_merge_ioc_xflags(flags, 1274 vattr->va_xflags = xfs_merge_ioc_xflags(flags,
1251 xfs_ip2xflags(ip)); 1275 xfs_ip2xflags(ip));
1252 1276
1253 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL); 1277 error = xfs_setattr(ip, vattr, attr_flags, NULL);
1254 if (likely(!error)) 1278 if (likely(!error))
1255 __vn_revalidate(vp, vattr); /* update flags */ 1279 __vn_revalidate(vp, vattr); /* update flags */
1256 error = -error; 1280 error = -error;
@@ -1268,7 +1292,7 @@ xfs_ioc_xattr(
1268 1292
1269STATIC int 1293STATIC int
1270xfs_ioc_getbmap( 1294xfs_ioc_getbmap(
1271 bhv_desc_t *bdp, 1295 struct xfs_inode *ip,
1272 int ioflags, 1296 int ioflags,
1273 unsigned int cmd, 1297 unsigned int cmd,
1274 void __user *arg) 1298 void __user *arg)
@@ -1287,7 +1311,7 @@ xfs_ioc_getbmap(
1287 if (ioflags & IO_INVIS) 1311 if (ioflags & IO_INVIS)
1288 iflags |= BMV_IF_NO_DMAPI_READ; 1312 iflags |= BMV_IF_NO_DMAPI_READ;
1289 1313
1290 error = xfs_getbmap(bdp, &bm, (struct getbmap __user *)arg+1, iflags); 1314 error = xfs_getbmap(ip, &bm, (struct getbmap __user *)arg+1, iflags);
1291 if (error) 1315 if (error)
1292 return -error; 1316 return -error;
1293 1317
@@ -1298,7 +1322,7 @@ xfs_ioc_getbmap(
1298 1322
1299STATIC int 1323STATIC int
1300xfs_ioc_getbmapx( 1324xfs_ioc_getbmapx(
1301 bhv_desc_t *bdp, 1325 struct xfs_inode *ip,
1302 void __user *arg) 1326 void __user *arg)
1303{ 1327{
1304 struct getbmapx bmx; 1328 struct getbmapx bmx;
@@ -1325,7 +1349,7 @@ xfs_ioc_getbmapx(
1325 1349
1326 iflags |= BMV_IF_EXTENDED; 1350 iflags |= BMV_IF_EXTENDED;
1327 1351
1328 error = xfs_getbmap(bdp, &bm, (struct getbmapx __user *)arg+1, iflags); 1352 error = xfs_getbmap(ip, &bm, (struct getbmapx __user *)arg+1, iflags);
1329 if (error) 1353 if (error)
1330 return -error; 1354 return -error;
1331 1355
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 42319d75aaab..0046bdd5b7f1 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -43,6 +43,7 @@
43#include "xfs_itable.h" 43#include "xfs_itable.h"
44#include "xfs_error.h" 44#include "xfs_error.h"
45#include "xfs_dfrag.h" 45#include "xfs_dfrag.h"
46#include "xfs_vnodeops.h"
46 47
47#define _NATIVE_IOC(cmd, type) \ 48#define _NATIVE_IOC(cmd, type) \
48 _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type)) 49 _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type))
@@ -370,7 +371,6 @@ xfs_compat_ioctl(
370 unsigned long arg) 371 unsigned long arg)
371{ 372{
372 struct inode *inode = file->f_path.dentry->d_inode; 373 struct inode *inode = file->f_path.dentry->d_inode;
373 bhv_vnode_t *vp = vn_from_inode(inode);
374 int error; 374 int error;
375 375
376 switch (cmd) { 376 switch (cmd) {
@@ -443,7 +443,7 @@ xfs_compat_ioctl(
443 case XFS_IOC_FSBULKSTAT_SINGLE_32: 443 case XFS_IOC_FSBULKSTAT_SINGLE_32:
444 case XFS_IOC_FSINUMBERS_32: 444 case XFS_IOC_FSINUMBERS_32:
445 cmd = _NATIVE_IOC(cmd, struct xfs_fsop_bulkreq); 445 cmd = _NATIVE_IOC(cmd, struct xfs_fsop_bulkreq);
446 return xfs_ioc_bulkstat_compat(XFS_BHVTOI(VNHEAD(vp))->i_mount, 446 return xfs_ioc_bulkstat_compat(XFS_I(inode)->i_mount,
447 cmd, (void __user*)arg); 447 cmd, (void __user*)arg);
448 case XFS_IOC_FD_TO_HANDLE_32: 448 case XFS_IOC_FD_TO_HANDLE_32:
449 case XFS_IOC_PATH_TO_HANDLE_32: 449 case XFS_IOC_PATH_TO_HANDLE_32:
@@ -457,8 +457,8 @@ xfs_compat_ioctl(
457 return -ENOIOCTLCMD; 457 return -ENOIOCTLCMD;
458 } 458 }
459 459
460 error = bhv_vop_ioctl(vp, inode, file, mode, cmd, (void __user *)arg); 460 error = xfs_ioctl(XFS_I(inode), file, mode, cmd, (void __user *)arg);
461 VMODIFY(vp); 461 xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
462 462
463 return error; 463 return error;
464} 464}
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index e0e06dd4bef2..ac50f8a37582 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -46,6 +46,7 @@
46#include "xfs_attr.h" 46#include "xfs_attr.h"
47#include "xfs_buf_item.h" 47#include "xfs_buf_item.h"
48#include "xfs_utils.h" 48#include "xfs_utils.h"
49#include "xfs_vnodeops.h"
49 50
50#include <linux/capability.h> 51#include <linux/capability.h>
51#include <linux/xattr.h> 52#include <linux/xattr.h>
@@ -53,22 +54,6 @@
53#include <linux/security.h> 54#include <linux/security.h>
54 55
55/* 56/*
56 * Get a XFS inode from a given vnode.
57 */
58xfs_inode_t *
59xfs_vtoi(
60 bhv_vnode_t *vp)
61{
62 bhv_desc_t *bdp;
63
64 bdp = bhv_lookup_range(VN_BHV_HEAD(vp),
65 VNODE_POSITION_XFS, VNODE_POSITION_XFS);
66 if (unlikely(bdp == NULL))
67 return NULL;
68 return XFS_BHVTOI(bdp);
69}
70
71/*
72 * Bring the atime in the XFS inode uptodate. 57 * Bring the atime in the XFS inode uptodate.
73 * Used before logging the inode to disk or when the Linux inode goes away. 58 * Used before logging the inode to disk or when the Linux inode goes away.
74 */ 59 */
@@ -80,9 +65,8 @@ xfs_synchronize_atime(
80 65
81 vp = XFS_ITOV_NULL(ip); 66 vp = XFS_ITOV_NULL(ip);
82 if (vp) { 67 if (vp) {
83 struct inode *inode = &vp->v_inode; 68 ip->i_d.di_atime.t_sec = (__int32_t)vp->i_atime.tv_sec;
84 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; 69 ip->i_d.di_atime.t_nsec = (__int32_t)vp->i_atime.tv_nsec;
85 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
86 } 70 }
87} 71}
88 72
@@ -195,18 +179,19 @@ xfs_ichgtime_fast(
195 */ 179 */
196STATIC void 180STATIC void
197xfs_validate_fields( 181xfs_validate_fields(
198 struct inode *ip, 182 struct inode *inode)
199 bhv_vattr_t *vattr)
200{ 183{
201 vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS; 184 struct xfs_inode *ip = XFS_I(inode);
202 if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) { 185 loff_t size;
203 ip->i_nlink = vattr->va_nlink; 186
204 ip->i_blocks = vattr->va_nblocks; 187 inode->i_nlink = ip->i_d.di_nlink;
205 188 inode->i_blocks =
206 /* we're under i_sem so i_size can't change under us */ 189 XFS_FSB_TO_BB(ip->i_mount, ip->i_d.di_nblocks +
207 if (i_size_read(ip) != vattr->va_size) 190 ip->i_delayed_blks);
208 i_size_write(ip, vattr->va_size); 191 /* we're under i_sem so i_size can't change under us */
209 } 192 size = XFS_ISIZE(ip);
193 if (i_size_read(inode) != size)
194 i_size_write(inode, size);
210} 195}
211 196
212/* 197/*
@@ -233,9 +218,10 @@ xfs_init_security(
233 return -error; 218 return -error;
234 } 219 }
235 220
236 error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL); 221 error = xfs_attr_set(XFS_I(ip), name, value,
222 length, ATTR_SECURE);
237 if (!error) 223 if (!error)
238 VMODIFY(vp); 224 xfs_iflags_set(XFS_I(ip), XFS_IMODIFIED);
239 225
240 kfree(name); 226 kfree(name);
241 kfree(value); 227 kfree(value);
@@ -256,7 +242,7 @@ xfs_has_fs_struct(struct task_struct *task)
256 242
257STATIC void 243STATIC void
258xfs_cleanup_inode( 244xfs_cleanup_inode(
259 bhv_vnode_t *dvp, 245 struct inode *dir,
260 bhv_vnode_t *vp, 246 bhv_vnode_t *vp,
261 struct dentry *dentry, 247 struct dentry *dentry,
262 int mode) 248 int mode)
@@ -272,9 +258,9 @@ xfs_cleanup_inode(
272 teardown.d_name = dentry->d_name; 258 teardown.d_name = dentry->d_name;
273 259
274 if (S_ISDIR(mode)) 260 if (S_ISDIR(mode))
275 bhv_vop_rmdir(dvp, &teardown, NULL); 261 xfs_rmdir(XFS_I(dir), &teardown);
276 else 262 else
277 bhv_vop_remove(dvp, &teardown, NULL); 263 xfs_remove(XFS_I(dir), &teardown);
278 VN_RELE(vp); 264 VN_RELE(vp);
279} 265}
280 266
@@ -286,7 +272,6 @@ xfs_vn_mknod(
286 dev_t rdev) 272 dev_t rdev)
287{ 273{
288 struct inode *ip; 274 struct inode *ip;
289 bhv_vattr_t vattr = { 0 };
290 bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir); 275 bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
291 xfs_acl_t *default_acl = NULL; 276 xfs_acl_t *default_acl = NULL;
292 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; 277 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
@@ -312,19 +297,14 @@ xfs_vn_mknod(
312 if (IS_POSIXACL(dir) && !default_acl && xfs_has_fs_struct(current)) 297 if (IS_POSIXACL(dir) && !default_acl && xfs_has_fs_struct(current))
313 mode &= ~current->fs->umask; 298 mode &= ~current->fs->umask;
314 299
315 vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
316 vattr.va_mode = mode;
317
318 switch (mode & S_IFMT) { 300 switch (mode & S_IFMT) {
319 case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: 301 case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
320 vattr.va_rdev = sysv_encode_dev(rdev); 302 rdev = sysv_encode_dev(rdev);
321 vattr.va_mask |= XFS_AT_RDEV;
322 /*FALLTHROUGH*/
323 case S_IFREG: 303 case S_IFREG:
324 error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL); 304 error = xfs_create(XFS_I(dir), dentry, mode, rdev, &vp, NULL);
325 break; 305 break;
326 case S_IFDIR: 306 case S_IFDIR:
327 error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL); 307 error = xfs_mkdir(XFS_I(dir), dentry, mode, &vp, NULL);
328 break; 308 break;
329 default: 309 default:
330 error = EINVAL; 310 error = EINVAL;
@@ -334,16 +314,16 @@ xfs_vn_mknod(
334 if (unlikely(!error)) { 314 if (unlikely(!error)) {
335 error = xfs_init_security(vp, dir); 315 error = xfs_init_security(vp, dir);
336 if (error) 316 if (error)
337 xfs_cleanup_inode(dvp, vp, dentry, mode); 317 xfs_cleanup_inode(dir, vp, dentry, mode);
338 } 318 }
339 319
340 if (unlikely(default_acl)) { 320 if (unlikely(default_acl)) {
341 if (!error) { 321 if (!error) {
342 error = _ACL_INHERIT(vp, &vattr, default_acl); 322 error = _ACL_INHERIT(vp, mode, default_acl);
343 if (!error) 323 if (!error)
344 VMODIFY(vp); 324 xfs_iflags_set(XFS_I(vp), XFS_IMODIFIED);
345 else 325 else
346 xfs_cleanup_inode(dvp, vp, dentry, mode); 326 xfs_cleanup_inode(dir, vp, dentry, mode);
347 } 327 }
348 _ACL_FREE(default_acl); 328 _ACL_FREE(default_acl);
349 } 329 }
@@ -355,9 +335,9 @@ xfs_vn_mknod(
355 if (S_ISCHR(mode) || S_ISBLK(mode)) 335 if (S_ISCHR(mode) || S_ISBLK(mode))
356 ip->i_rdev = rdev; 336 ip->i_rdev = rdev;
357 else if (S_ISDIR(mode)) 337 else if (S_ISDIR(mode))
358 xfs_validate_fields(ip, &vattr); 338 xfs_validate_fields(ip);
359 d_instantiate(dentry, ip); 339 d_instantiate(dentry, ip);
360 xfs_validate_fields(dir, &vattr); 340 xfs_validate_fields(dir);
361 } 341 }
362 return -error; 342 return -error;
363} 343}
@@ -387,13 +367,13 @@ xfs_vn_lookup(
387 struct dentry *dentry, 367 struct dentry *dentry,
388 struct nameidata *nd) 368 struct nameidata *nd)
389{ 369{
390 bhv_vnode_t *vp = vn_from_inode(dir), *cvp; 370 bhv_vnode_t *cvp;
391 int error; 371 int error;
392 372
393 if (dentry->d_name.len >= MAXNAMELEN) 373 if (dentry->d_name.len >= MAXNAMELEN)
394 return ERR_PTR(-ENAMETOOLONG); 374 return ERR_PTR(-ENAMETOOLONG);
395 375
396 error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL); 376 error = xfs_lookup(XFS_I(dir), dentry, &cvp);
397 if (unlikely(error)) { 377 if (unlikely(error)) {
398 if (unlikely(error != ENOENT)) 378 if (unlikely(error != ENOENT))
399 return ERR_PTR(-error); 379 return ERR_PTR(-error);
@@ -411,22 +391,19 @@ xfs_vn_link(
411 struct dentry *dentry) 391 struct dentry *dentry)
412{ 392{
413 struct inode *ip; /* inode of guy being linked to */ 393 struct inode *ip; /* inode of guy being linked to */
414 bhv_vnode_t *tdvp; /* target directory for new name/link */
415 bhv_vnode_t *vp; /* vp of name being linked */ 394 bhv_vnode_t *vp; /* vp of name being linked */
416 bhv_vattr_t vattr;
417 int error; 395 int error;
418 396
419 ip = old_dentry->d_inode; /* inode being linked to */ 397 ip = old_dentry->d_inode; /* inode being linked to */
420 tdvp = vn_from_inode(dir);
421 vp = vn_from_inode(ip); 398 vp = vn_from_inode(ip);
422 399
423 VN_HOLD(vp); 400 VN_HOLD(vp);
424 error = bhv_vop_link(tdvp, vp, dentry, NULL); 401 error = xfs_link(XFS_I(dir), vp, dentry);
425 if (unlikely(error)) { 402 if (unlikely(error)) {
426 VN_RELE(vp); 403 VN_RELE(vp);
427 } else { 404 } else {
428 VMODIFY(tdvp); 405 xfs_iflags_set(XFS_I(dir), XFS_IMODIFIED);
429 xfs_validate_fields(ip, &vattr); 406 xfs_validate_fields(ip);
430 d_instantiate(dentry, ip); 407 d_instantiate(dentry, ip);
431 } 408 }
432 return -error; 409 return -error;
@@ -438,17 +415,14 @@ xfs_vn_unlink(
438 struct dentry *dentry) 415 struct dentry *dentry)
439{ 416{
440 struct inode *inode; 417 struct inode *inode;
441 bhv_vnode_t *dvp; /* directory containing name to remove */
442 bhv_vattr_t vattr;
443 int error; 418 int error;
444 419
445 inode = dentry->d_inode; 420 inode = dentry->d_inode;
446 dvp = vn_from_inode(dir);
447 421
448 error = bhv_vop_remove(dvp, dentry, NULL); 422 error = xfs_remove(XFS_I(dir), dentry);
449 if (likely(!error)) { 423 if (likely(!error)) {
450 xfs_validate_fields(dir, &vattr); /* size needs update */ 424 xfs_validate_fields(dir); /* size needs update */
451 xfs_validate_fields(inode, &vattr); 425 xfs_validate_fields(inode);
452 } 426 }
453 return -error; 427 return -error;
454} 428}
@@ -460,28 +434,26 @@ xfs_vn_symlink(
460 const char *symname) 434 const char *symname)
461{ 435{
462 struct inode *ip; 436 struct inode *ip;
463 bhv_vattr_t va = { 0 };
464 bhv_vnode_t *dvp; /* directory containing name of symlink */
465 bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */ 437 bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */
466 int error; 438 int error;
439 mode_t mode;
467 440
468 dvp = vn_from_inode(dir);
469 cvp = NULL; 441 cvp = NULL;
470 442
471 va.va_mode = S_IFLNK | 443 mode = S_IFLNK |
472 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); 444 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
473 va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
474 445
475 error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL); 446 error = xfs_symlink(XFS_I(dir), dentry, (char *)symname, mode,
447 &cvp, NULL);
476 if (likely(!error && cvp)) { 448 if (likely(!error && cvp)) {
477 error = xfs_init_security(cvp, dir); 449 error = xfs_init_security(cvp, dir);
478 if (likely(!error)) { 450 if (likely(!error)) {
479 ip = vn_to_inode(cvp); 451 ip = vn_to_inode(cvp);
480 d_instantiate(dentry, ip); 452 d_instantiate(dentry, ip);
481 xfs_validate_fields(dir, &va); 453 xfs_validate_fields(dir);
482 xfs_validate_fields(ip, &va); 454 xfs_validate_fields(ip);
483 } else { 455 } else {
484 xfs_cleanup_inode(dvp, cvp, dentry, 0); 456 xfs_cleanup_inode(dir, cvp, dentry, 0);
485 } 457 }
486 } 458 }
487 return -error; 459 return -error;
@@ -493,14 +465,12 @@ xfs_vn_rmdir(
493 struct dentry *dentry) 465 struct dentry *dentry)
494{ 466{
495 struct inode *inode = dentry->d_inode; 467 struct inode *inode = dentry->d_inode;
496 bhv_vnode_t *dvp = vn_from_inode(dir);
497 bhv_vattr_t vattr;
498 int error; 468 int error;
499 469
500 error = bhv_vop_rmdir(dvp, dentry, NULL); 470 error = xfs_rmdir(XFS_I(dir), dentry);
501 if (likely(!error)) { 471 if (likely(!error)) {
502 xfs_validate_fields(inode, &vattr); 472 xfs_validate_fields(inode);
503 xfs_validate_fields(dir, &vattr); 473 xfs_validate_fields(dir);
504 } 474 }
505 return -error; 475 return -error;
506} 476}
@@ -513,21 +483,18 @@ xfs_vn_rename(
513 struct dentry *ndentry) 483 struct dentry *ndentry)
514{ 484{
515 struct inode *new_inode = ndentry->d_inode; 485 struct inode *new_inode = ndentry->d_inode;
516 bhv_vnode_t *fvp; /* from directory */
517 bhv_vnode_t *tvp; /* target directory */ 486 bhv_vnode_t *tvp; /* target directory */
518 bhv_vattr_t vattr;
519 int error; 487 int error;
520 488
521 fvp = vn_from_inode(odir);
522 tvp = vn_from_inode(ndir); 489 tvp = vn_from_inode(ndir);
523 490
524 error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL); 491 error = xfs_rename(XFS_I(odir), odentry, tvp, ndentry);
525 if (likely(!error)) { 492 if (likely(!error)) {
526 if (new_inode) 493 if (new_inode)
527 xfs_validate_fields(new_inode, &vattr); 494 xfs_validate_fields(new_inode);
528 xfs_validate_fields(odir, &vattr); 495 xfs_validate_fields(odir);
529 if (ndir != odir) 496 if (ndir != odir)
530 xfs_validate_fields(ndir, &vattr); 497 xfs_validate_fields(ndir);
531 } 498 }
532 return -error; 499 return -error;
533} 500}
@@ -542,50 +509,25 @@ xfs_vn_follow_link(
542 struct dentry *dentry, 509 struct dentry *dentry,
543 struct nameidata *nd) 510 struct nameidata *nd)
544{ 511{
545 bhv_vnode_t *vp;
546 uio_t *uio;
547 iovec_t iov;
548 int error;
549 char *link; 512 char *link;
550 513 int error = -ENOMEM;
551 ASSERT(dentry);
552 ASSERT(nd);
553 514
554 link = kmalloc(MAXPATHLEN+1, GFP_KERNEL); 515 link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
555 if (!link) { 516 if (!link)
556 nd_set_link(nd, ERR_PTR(-ENOMEM)); 517 goto out_err;
557 return NULL;
558 }
559
560 uio = kmalloc(sizeof(uio_t), GFP_KERNEL);
561 if (!uio) {
562 kfree(link);
563 nd_set_link(nd, ERR_PTR(-ENOMEM));
564 return NULL;
565 }
566
567 vp = vn_from_inode(dentry->d_inode);
568
569 iov.iov_base = link;
570 iov.iov_len = MAXPATHLEN;
571 518
572 uio->uio_iov = &iov; 519 error = -xfs_readlink(XFS_I(dentry->d_inode), link);
573 uio->uio_offset = 0; 520 if (unlikely(error))
574 uio->uio_segflg = UIO_SYSSPACE; 521 goto out_kfree;
575 uio->uio_resid = MAXPATHLEN;
576 uio->uio_iovcnt = 1;
577
578 error = bhv_vop_readlink(vp, uio, 0, NULL);
579 if (unlikely(error)) {
580 kfree(link);
581 link = ERR_PTR(-error);
582 } else {
583 link[MAXPATHLEN - uio->uio_resid] = '\0';
584 }
585 kfree(uio);
586 522
587 nd_set_link(nd, link); 523 nd_set_link(nd, link);
588 return NULL; 524 return NULL;
525
526 out_kfree:
527 kfree(link);
528 out_err:
529 nd_set_link(nd, ERR_PTR(error));
530 return NULL;
589} 531}
590 532
591STATIC void 533STATIC void
@@ -607,7 +549,7 @@ xfs_vn_permission(
607 int mode, 549 int mode,
608 struct nameidata *nd) 550 struct nameidata *nd)
609{ 551{
610 return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL); 552 return -xfs_access(XFS_I(inode), mode << 6, NULL);
611} 553}
612#else 554#else
613#define xfs_vn_permission NULL 555#define xfs_vn_permission NULL
@@ -620,11 +562,10 @@ xfs_vn_getattr(
620 struct kstat *stat) 562 struct kstat *stat)
621{ 563{
622 struct inode *inode = dentry->d_inode; 564 struct inode *inode = dentry->d_inode;
623 bhv_vnode_t *vp = vn_from_inode(inode);
624 bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT }; 565 bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT };
625 int error; 566 int error;
626 567
627 error = bhv_vop_getattr(vp, &vattr, ATTR_LAZY, NULL); 568 error = xfs_getattr(XFS_I(inode), &vattr, ATTR_LAZY);
628 if (likely(!error)) { 569 if (likely(!error)) {
629 stat->size = i_size_read(inode); 570 stat->size = i_size_read(inode);
630 stat->dev = inode->i_sb->s_dev; 571 stat->dev = inode->i_sb->s_dev;
@@ -652,7 +593,6 @@ xfs_vn_setattr(
652{ 593{
653 struct inode *inode = dentry->d_inode; 594 struct inode *inode = dentry->d_inode;
654 unsigned int ia_valid = attr->ia_valid; 595 unsigned int ia_valid = attr->ia_valid;
655 bhv_vnode_t *vp = vn_from_inode(inode);
656 bhv_vattr_t vattr = { 0 }; 596 bhv_vattr_t vattr = { 0 };
657 int flags = 0; 597 int flags = 0;
658 int error; 598 int error;
@@ -696,9 +636,9 @@ xfs_vn_setattr(
696 flags |= ATTR_NONBLOCK; 636 flags |= ATTR_NONBLOCK;
697#endif 637#endif
698 638
699 error = bhv_vop_setattr(vp, &vattr, flags, NULL); 639 error = xfs_setattr(XFS_I(inode), &vattr, flags, NULL);
700 if (likely(!error)) 640 if (likely(!error))
701 __vn_revalidate(vp, &vattr); 641 __vn_revalidate(vn_from_inode(inode), &vattr);
702 return -error; 642 return -error;
703} 643}
704 644
diff --git a/fs/xfs/linux-2.6/xfs_iops.h b/fs/xfs/linux-2.6/xfs_iops.h
index 95a69398fce0..14d0deb7afff 100644
--- a/fs/xfs/linux-2.6/xfs_iops.h
+++ b/fs/xfs/linux-2.6/xfs_iops.h
@@ -26,11 +26,15 @@ extern const struct file_operations xfs_file_operations;
26extern const struct file_operations xfs_dir_file_operations; 26extern const struct file_operations xfs_dir_file_operations;
27extern const struct file_operations xfs_invis_file_operations; 27extern const struct file_operations xfs_invis_file_operations;
28 28
29extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *,
30 int, unsigned int, void __user *);
31 29
32struct xfs_inode; 30struct xfs_inode;
33extern void xfs_ichgtime(struct xfs_inode *, int); 31extern void xfs_ichgtime(struct xfs_inode *, int);
34extern void xfs_ichgtime_fast(struct xfs_inode *, struct inode *, int); 32extern void xfs_ichgtime_fast(struct xfs_inode *, struct inode *, int);
35 33
34#define xfs_vtoi(vp) \
35 ((struct xfs_inode *)vn_to_inode(vp)->i_private)
36
37#define XFS_I(inode) \
38 ((struct xfs_inode *)(inode)->i_private)
39
36#endif /* __XFS_IOPS_H__ */ 40#endif /* __XFS_IOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 330c4ba9d404..dc3752de22da 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -51,7 +51,6 @@
51 51
52#include <support/ktrace.h> 52#include <support/ktrace.h>
53#include <support/debug.h> 53#include <support/debug.h>
54#include <support/move.h>
55#include <support/uuid.h> 54#include <support/uuid.h>
56 55
57#include <linux/mm.h> 56#include <linux/mm.h>
@@ -75,6 +74,7 @@
75#include <linux/cpu.h> 74#include <linux/cpu.h>
76#include <linux/notifier.h> 75#include <linux/notifier.h>
77#include <linux/delay.h> 76#include <linux/delay.h>
77#include <linux/log2.h>
78 78
79#include <asm/page.h> 79#include <asm/page.h>
80#include <asm/div64.h> 80#include <asm/div64.h>
@@ -83,7 +83,6 @@
83#include <asm/byteorder.h> 83#include <asm/byteorder.h>
84#include <asm/unaligned.h> 84#include <asm/unaligned.h>
85 85
86#include <xfs_behavior.h>
87#include <xfs_vfs.h> 86#include <xfs_vfs.h>
88#include <xfs_cred.h> 87#include <xfs_cred.h>
89#include <xfs_vnode.h> 88#include <xfs_vnode.h>
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 7e7aeb4c8a08..d6a8dddb2268 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -48,6 +48,7 @@
48#include "xfs_buf_item.h" 48#include "xfs_buf_item.h"
49#include "xfs_utils.h" 49#include "xfs_utils.h"
50#include "xfs_iomap.h" 50#include "xfs_iomap.h"
51#include "xfs_vnodeops.h"
51 52
52#include <linux/capability.h> 53#include <linux/capability.h>
53#include <linux/writeback.h> 54#include <linux/writeback.h>
@@ -169,27 +170,22 @@ xfs_iozero(
169 170
170ssize_t /* bytes read, or (-) error */ 171ssize_t /* bytes read, or (-) error */
171xfs_read( 172xfs_read(
172 bhv_desc_t *bdp, 173 xfs_inode_t *ip,
173 struct kiocb *iocb, 174 struct kiocb *iocb,
174 const struct iovec *iovp, 175 const struct iovec *iovp,
175 unsigned int segs, 176 unsigned int segs,
176 loff_t *offset, 177 loff_t *offset,
177 int ioflags, 178 int ioflags)
178 cred_t *credp)
179{ 179{
180 struct file *file = iocb->ki_filp; 180 struct file *file = iocb->ki_filp;
181 struct inode *inode = file->f_mapping->host; 181 struct inode *inode = file->f_mapping->host;
182 bhv_vnode_t *vp = XFS_ITOV(ip);
183 xfs_mount_t *mp = ip->i_mount;
182 size_t size = 0; 184 size_t size = 0;
183 ssize_t ret = 0; 185 ssize_t ret = 0;
184 xfs_fsize_t n; 186 xfs_fsize_t n;
185 xfs_inode_t *ip;
186 xfs_mount_t *mp;
187 bhv_vnode_t *vp;
188 unsigned long seg; 187 unsigned long seg;
189 188
190 ip = XFS_BHVTOI(bdp);
191 vp = BHV_TO_VNODE(bdp);
192 mp = ip->i_mount;
193 189
194 XFS_STATS_INC(xs_read_calls); 190 XFS_STATS_INC(xs_read_calls);
195 191
@@ -234,13 +230,11 @@ xfs_read(
234 mutex_lock(&inode->i_mutex); 230 mutex_lock(&inode->i_mutex);
235 xfs_ilock(ip, XFS_IOLOCK_SHARED); 231 xfs_ilock(ip, XFS_IOLOCK_SHARED);
236 232
237 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && 233 if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
238 !(ioflags & IO_INVIS)) {
239 bhv_vrwlock_t locktype = VRWLOCK_READ; 234 bhv_vrwlock_t locktype = VRWLOCK_READ;
240 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); 235 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
241 236
242 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, 237 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp, *offset, size,
243 BHV_TO_VNODE(bdp), *offset, size,
244 dmflags, &locktype); 238 dmflags, &locktype);
245 if (ret) { 239 if (ret) {
246 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 240 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -252,8 +246,9 @@ xfs_read(
252 246
253 if (unlikely(ioflags & IO_ISDIRECT)) { 247 if (unlikely(ioflags & IO_ISDIRECT)) {
254 if (VN_CACHED(vp)) 248 if (VN_CACHED(vp))
255 ret = bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), 249 ret = xfs_flushinval_pages(ip,
256 -1, FI_REMAPF_LOCKED); 250 ctooff(offtoct(*offset)),
251 -1, FI_REMAPF_LOCKED);
257 mutex_unlock(&inode->i_mutex); 252 mutex_unlock(&inode->i_mutex);
258 if (ret) { 253 if (ret) {
259 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 254 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -277,16 +272,15 @@ xfs_read(
277 272
278ssize_t 273ssize_t
279xfs_splice_read( 274xfs_splice_read(
280 bhv_desc_t *bdp, 275 xfs_inode_t *ip,
281 struct file *infilp, 276 struct file *infilp,
282 loff_t *ppos, 277 loff_t *ppos,
283 struct pipe_inode_info *pipe, 278 struct pipe_inode_info *pipe,
284 size_t count, 279 size_t count,
285 int flags, 280 int flags,
286 int ioflags, 281 int ioflags)
287 cred_t *credp)
288{ 282{
289 xfs_inode_t *ip = XFS_BHVTOI(bdp); 283 bhv_vnode_t *vp = XFS_ITOV(ip);
290 xfs_mount_t *mp = ip->i_mount; 284 xfs_mount_t *mp = ip->i_mount;
291 ssize_t ret; 285 ssize_t ret;
292 286
@@ -296,13 +290,11 @@ xfs_splice_read(
296 290
297 xfs_ilock(ip, XFS_IOLOCK_SHARED); 291 xfs_ilock(ip, XFS_IOLOCK_SHARED);
298 292
299 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && 293 if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
300 (!(ioflags & IO_INVIS))) {
301 bhv_vrwlock_t locktype = VRWLOCK_READ; 294 bhv_vrwlock_t locktype = VRWLOCK_READ;
302 int error; 295 int error;
303 296
304 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), 297 error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, *ppos, count,
305 *ppos, count,
306 FILP_DELAY_FLAG(infilp), &locktype); 298 FILP_DELAY_FLAG(infilp), &locktype);
307 if (error) { 299 if (error) {
308 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 300 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -321,16 +313,15 @@ xfs_splice_read(
321 313
322ssize_t 314ssize_t
323xfs_splice_write( 315xfs_splice_write(
324 bhv_desc_t *bdp, 316 xfs_inode_t *ip,
325 struct pipe_inode_info *pipe, 317 struct pipe_inode_info *pipe,
326 struct file *outfilp, 318 struct file *outfilp,
327 loff_t *ppos, 319 loff_t *ppos,
328 size_t count, 320 size_t count,
329 int flags, 321 int flags,
330 int ioflags, 322 int ioflags)
331 cred_t *credp)
332{ 323{
333 xfs_inode_t *ip = XFS_BHVTOI(bdp); 324 bhv_vnode_t *vp = XFS_ITOV(ip);
334 xfs_mount_t *mp = ip->i_mount; 325 xfs_mount_t *mp = ip->i_mount;
335 xfs_iocore_t *io = &ip->i_iocore; 326 xfs_iocore_t *io = &ip->i_iocore;
336 ssize_t ret; 327 ssize_t ret;
@@ -343,13 +334,11 @@ xfs_splice_write(
343 334
344 xfs_ilock(ip, XFS_IOLOCK_EXCL); 335 xfs_ilock(ip, XFS_IOLOCK_EXCL);
345 336
346 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) && 337 if (DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && !(ioflags & IO_INVIS)) {
347 (!(ioflags & IO_INVIS))) {
348 bhv_vrwlock_t locktype = VRWLOCK_WRITE; 338 bhv_vrwlock_t locktype = VRWLOCK_WRITE;
349 int error; 339 int error;
350 340
351 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), 341 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, *ppos, count,
352 *ppos, count,
353 FILP_DELAY_FLAG(outfilp), &locktype); 342 FILP_DELAY_FLAG(outfilp), &locktype);
354 if (error) { 343 if (error) {
355 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 344 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
@@ -583,24 +572,22 @@ out_lock:
583 572
584ssize_t /* bytes written, or (-) error */ 573ssize_t /* bytes written, or (-) error */
585xfs_write( 574xfs_write(
586 bhv_desc_t *bdp, 575 struct xfs_inode *xip,
587 struct kiocb *iocb, 576 struct kiocb *iocb,
588 const struct iovec *iovp, 577 const struct iovec *iovp,
589 unsigned int nsegs, 578 unsigned int nsegs,
590 loff_t *offset, 579 loff_t *offset,
591 int ioflags, 580 int ioflags)
592 cred_t *credp)
593{ 581{
594 struct file *file = iocb->ki_filp; 582 struct file *file = iocb->ki_filp;
595 struct address_space *mapping = file->f_mapping; 583 struct address_space *mapping = file->f_mapping;
596 struct inode *inode = mapping->host; 584 struct inode *inode = mapping->host;
585 bhv_vnode_t *vp = XFS_ITOV(xip);
597 unsigned long segs = nsegs; 586 unsigned long segs = nsegs;
598 xfs_inode_t *xip;
599 xfs_mount_t *mp; 587 xfs_mount_t *mp;
600 ssize_t ret = 0, error = 0; 588 ssize_t ret = 0, error = 0;
601 xfs_fsize_t isize, new_size; 589 xfs_fsize_t isize, new_size;
602 xfs_iocore_t *io; 590 xfs_iocore_t *io;
603 bhv_vnode_t *vp;
604 int iolock; 591 int iolock;
605 int eventsent = 0; 592 int eventsent = 0;
606 bhv_vrwlock_t locktype; 593 bhv_vrwlock_t locktype;
@@ -610,9 +597,6 @@ xfs_write(
610 597
611 XFS_STATS_INC(xs_write_calls); 598 XFS_STATS_INC(xs_write_calls);
612 599
613 vp = BHV_TO_VNODE(bdp);
614 xip = XFS_BHVTOI(bdp);
615
616 error = generic_segment_checks(iovp, &segs, &ocount, VERIFY_READ); 600 error = generic_segment_checks(iovp, &segs, &ocount, VERIFY_READ);
617 if (error) 601 if (error)
618 return error; 602 return error;
@@ -626,7 +610,7 @@ xfs_write(
626 io = &xip->i_iocore; 610 io = &xip->i_iocore;
627 mp = io->io_mount; 611 mp = io->io_mount;
628 612
629 vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE); 613 xfs_wait_for_freeze(mp, SB_FREEZE_WRITE);
630 614
631 if (XFS_FORCED_SHUTDOWN(mp)) 615 if (XFS_FORCED_SHUTDOWN(mp))
632 return -EIO; 616 return -EIO;
@@ -653,7 +637,7 @@ start:
653 goto out_unlock_mutex; 637 goto out_unlock_mutex;
654 } 638 }
655 639
656 if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) && 640 if ((DM_EVENT_ENABLED(xip, DM_EVENT_WRITE) &&
657 !(ioflags & IO_INVIS) && !eventsent)) { 641 !(ioflags & IO_INVIS) && !eventsent)) {
658 int dmflags = FILP_DELAY_FLAG(file); 642 int dmflags = FILP_DELAY_FLAG(file);
659 643
@@ -722,7 +706,7 @@ start:
722 */ 706 */
723 707
724 if (pos > xip->i_size) { 708 if (pos > xip->i_size) {
725 error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, xip->i_size); 709 error = xfs_zero_eof(vp, io, pos, xip->i_size);
726 if (error) { 710 if (error) {
727 xfs_iunlock(xip, XFS_ILOCK_EXCL); 711 xfs_iunlock(xip, XFS_ILOCK_EXCL);
728 goto out_unlock_internal; 712 goto out_unlock_internal;
@@ -758,7 +742,8 @@ retry:
758 WARN_ON(need_i_mutex == 0); 742 WARN_ON(need_i_mutex == 0);
759 xfs_inval_cached_trace(io, pos, -1, 743 xfs_inval_cached_trace(io, pos, -1,
760 ctooff(offtoct(pos)), -1); 744 ctooff(offtoct(pos)), -1);
761 error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)), 745 error = xfs_flushinval_pages(xip,
746 ctooff(offtoct(pos)),
762 -1, FI_REMAPF_LOCKED); 747 -1, FI_REMAPF_LOCKED);
763 if (error) 748 if (error)
764 goto out_unlock_internal; 749 goto out_unlock_internal;
@@ -805,11 +790,9 @@ retry:
805 if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO)) 790 if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO))
806 ret = wait_on_sync_kiocb(iocb); 791 ret = wait_on_sync_kiocb(iocb);
807 792
808 if ((ret == -ENOSPC) && 793 if (ret == -ENOSPC &&
809 DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_NOSPACE) && 794 DM_EVENT_ENABLED(xip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) {
810 !(ioflags & IO_INVIS)) { 795 xfs_rwunlock(xip, locktype);
811
812 xfs_rwunlock(bdp, locktype);
813 if (need_i_mutex) 796 if (need_i_mutex)
814 mutex_unlock(&inode->i_mutex); 797 mutex_unlock(&inode->i_mutex);
815 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, 798 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
@@ -817,7 +800,7 @@ retry:
817 0, 0, 0); /* Delay flag intentionally unused */ 800 0, 0, 0); /* Delay flag intentionally unused */
818 if (need_i_mutex) 801 if (need_i_mutex)
819 mutex_lock(&inode->i_mutex); 802 mutex_lock(&inode->i_mutex);
820 xfs_rwlock(bdp, locktype); 803 xfs_rwlock(xip, locktype);
821 if (error) 804 if (error)
822 goto out_unlock_internal; 805 goto out_unlock_internal;
823 pos = xip->i_size; 806 pos = xip->i_size;
@@ -844,20 +827,19 @@ retry:
844 827
845 /* Handle various SYNC-type writes */ 828 /* Handle various SYNC-type writes */
846 if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { 829 if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
847 error = xfs_write_sync_logforce(mp, xip); 830 int error2;
848 if (error) 831 xfs_rwunlock(xip, locktype);
849 goto out_unlock_internal;
850
851 xfs_rwunlock(bdp, locktype);
852 if (need_i_mutex) 832 if (need_i_mutex)
853 mutex_unlock(&inode->i_mutex); 833 mutex_unlock(&inode->i_mutex);
854 834 error2 = sync_page_range(inode, mapping, pos, ret);
855 error = sync_page_range(inode, mapping, pos, ret);
856 if (!error) 835 if (!error)
857 error = -ret; 836 error = error2;
858 if (need_i_mutex) 837 if (need_i_mutex)
859 mutex_lock(&inode->i_mutex); 838 mutex_lock(&inode->i_mutex);
860 xfs_rwlock(bdp, locktype); 839 xfs_rwlock(xip, locktype);
840 error2 = xfs_write_sync_logforce(mp, xip);
841 if (!error)
842 error = error2;
861 } 843 }
862 844
863 out_unlock_internal: 845 out_unlock_internal:
@@ -875,7 +857,7 @@ retry:
875 xip->i_d.di_size = xip->i_size; 857 xip->i_d.di_size = xip->i_size;
876 xfs_iunlock(xip, XFS_ILOCK_EXCL); 858 xfs_iunlock(xip, XFS_ILOCK_EXCL);
877 } 859 }
878 xfs_rwunlock(bdp, locktype); 860 xfs_rwunlock(xip, locktype);
879 out_unlock_mutex: 861 out_unlock_mutex:
880 if (need_i_mutex) 862 if (need_i_mutex)
881 mutex_unlock(&inode->i_mutex); 863 mutex_unlock(&inode->i_mutex);
@@ -914,14 +896,14 @@ xfs_bdstrat_cb(struct xfs_buf *bp)
914 896
915 897
916int 898int
917xfs_bmap(bhv_desc_t *bdp, 899xfs_bmap(
900 xfs_inode_t *ip,
918 xfs_off_t offset, 901 xfs_off_t offset,
919 ssize_t count, 902 ssize_t count,
920 int flags, 903 int flags,
921 xfs_iomap_t *iomapp, 904 xfs_iomap_t *iomapp,
922 int *niomaps) 905 int *niomaps)
923{ 906{
924 xfs_inode_t *ip = XFS_BHVTOI(bdp);
925 xfs_iocore_t *io = &ip->i_iocore; 907 xfs_iocore_t *io = &ip->i_iocore;
926 908
927 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); 909 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 7c60a1eed88b..4b7747a828d9 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -18,8 +18,6 @@
18#ifndef __XFS_LRW_H__ 18#ifndef __XFS_LRW_H__
19#define __XFS_LRW_H__ 19#define __XFS_LRW_H__
20 20
21struct bhv_desc;
22struct bhv_vnode;
23struct xfs_mount; 21struct xfs_mount;
24struct xfs_iocore; 22struct xfs_iocore;
25struct xfs_inode; 23struct xfs_inode;
@@ -71,30 +69,11 @@ extern void xfs_inval_cached_trace(struct xfs_iocore *,
71#define xfs_inval_cached_trace(io, offset, len, first, last) 69#define xfs_inval_cached_trace(io, offset, len, first, last)
72#endif 70#endif
73 71
74/*
75 * Maximum count of bmaps used by read and write paths.
76 */
77#define XFS_MAX_RW_NBMAPS 4
78
79extern int xfs_bmap(struct bhv_desc *, xfs_off_t, ssize_t, int,
80 struct xfs_iomap *, int *);
81extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *); 72extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
82extern int xfs_bdstrat_cb(struct xfs_buf *); 73extern int xfs_bdstrat_cb(struct xfs_buf *);
83extern int xfs_dev_is_read_only(struct xfs_mount *, char *); 74extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
84 75
85extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t, 76extern int xfs_zero_eof(struct inode *, struct xfs_iocore *, xfs_off_t,
86 xfs_fsize_t); 77 xfs_fsize_t);
87extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
88 const struct iovec *, unsigned int,
89 loff_t *, int, struct cred *);
90extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *,
91 const struct iovec *, unsigned int,
92 loff_t *, int, struct cred *);
93extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *,
94 struct pipe_inode_info *, size_t, int, int,
95 struct cred *);
96extern ssize_t xfs_splice_write(struct bhv_desc *, struct pipe_inode_info *,
97 struct file *, loff_t *, size_t, int, int,
98 struct cred *);
99 78
100#endif /* __XFS_LRW_H__ */ 79#endif /* __XFS_LRW_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 9c7d8202088f..8cb63c60c048 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -46,6 +46,8 @@
46#include "xfs_attr.h" 46#include "xfs_attr.h"
47#include "xfs_buf_item.h" 47#include "xfs_buf_item.h"
48#include "xfs_utils.h" 48#include "xfs_utils.h"
49#include "xfs_vnodeops.h"
50#include "xfs_vfsops.h"
49#include "xfs_version.h" 51#include "xfs_version.h"
50 52
51#include <linux/namei.h> 53#include <linux/namei.h>
@@ -196,23 +198,20 @@ xfs_revalidate_inode(
196 inode->i_flags |= S_NOATIME; 198 inode->i_flags |= S_NOATIME;
197 else 199 else
198 inode->i_flags &= ~S_NOATIME; 200 inode->i_flags &= ~S_NOATIME;
199 vp->v_flag &= ~VMODIFIED; 201 xfs_iflags_clear(ip, XFS_IMODIFIED);
200} 202}
201 203
202void 204void
203xfs_initialize_vnode( 205xfs_initialize_vnode(
204 bhv_desc_t *bdp, 206 struct xfs_mount *mp,
205 bhv_vnode_t *vp, 207 bhv_vnode_t *vp,
206 bhv_desc_t *inode_bhv, 208 struct xfs_inode *ip)
207 int unlock)
208{ 209{
209 xfs_inode_t *ip = XFS_BHVTOI(inode_bhv);
210 struct inode *inode = vn_to_inode(vp); 210 struct inode *inode = vn_to_inode(vp);
211 211
212 if (!inode_bhv->bd_vobj) { 212 if (!ip->i_vnode) {
213 vp->v_vfsp = bhvtovfs(bdp); 213 ip->i_vnode = vp;
214 bhv_desc_init(inode_bhv, ip, vp, &xfs_vnodeops); 214 inode->i_private = ip;
215 bhv_insert(VN_BHV_HEAD(vp), inode_bhv);
216 } 215 }
217 216
218 /* 217 /*
@@ -222,8 +221,8 @@ xfs_initialize_vnode(
222 * second time once the inode is properly set up, and then we can 221 * second time once the inode is properly set up, and then we can
223 * finish our work. 222 * finish our work.
224 */ 223 */
225 if (ip->i_d.di_mode != 0 && unlock && (inode->i_state & I_NEW)) { 224 if (ip->i_d.di_mode != 0 && (inode->i_state & I_NEW)) {
226 xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip); 225 xfs_revalidate_inode(mp, vp, ip);
227 xfs_set_inodeops(inode); 226 xfs_set_inodeops(inode);
228 227
229 xfs_iflags_clear(ip, XFS_INEW); 228 xfs_iflags_clear(ip, XFS_INEW);
@@ -409,19 +408,22 @@ xfs_fs_write_inode(
409 struct inode *inode, 408 struct inode *inode,
410 int sync) 409 int sync)
411{ 410{
412 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 vn_trace_entry(XFS_I(inode), __FUNCTION__,
416 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 414 (inst_t *)__return_address);
417 if (sync) { 415 if (sync) {
418 filemap_fdatawait(inode->i_mapping); 416 filemap_fdatawait(inode->i_mapping);
419 flags |= FLUSH_SYNC; 417 flags |= FLUSH_SYNC;
420 }
421 error = bhv_vop_iflush(vp, flags);
422 if (error == EAGAIN)
423 error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
424 } 418 }
419 error = xfs_inode_flush(XFS_I(inode), flags);
420 /*
421 * if we failed to write out the inode then mark
422 * it dirty again so we'll try again later.
423 */
424 if (error)
425 mark_inode_dirty_sync(inode);
426
425 return -error; 427 return -error;
426} 428}
427 429
@@ -429,35 +431,27 @@ STATIC void
429xfs_fs_clear_inode( 431xfs_fs_clear_inode(
430 struct inode *inode) 432 struct inode *inode)
431{ 433{
432 bhv_vnode_t *vp = vn_from_inode(inode); 434 xfs_inode_t *ip = XFS_I(inode);
433
434 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
435
436 XFS_STATS_INC(vn_rele);
437 XFS_STATS_INC(vn_remove);
438 XFS_STATS_INC(vn_reclaim);
439 XFS_STATS_DEC(vn_active);
440 435
441 /* 436 /*
442 * This can happen because xfs_iget_core calls xfs_idestroy if we 437 * ip can be null when xfs_iget_core calls xfs_idestroy if we
443 * find an inode with di_mode == 0 but without IGET_CREATE set. 438 * find an inode with di_mode == 0 but without IGET_CREATE set.
444 */ 439 */
445 if (VNHEAD(vp)) 440 if (ip) {
446 bhv_vop_inactive(vp, NULL); 441 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
447 442
448 VN_LOCK(vp); 443 XFS_STATS_INC(vn_rele);
449 vp->v_flag &= ~VMODIFIED; 444 XFS_STATS_INC(vn_remove);
450 VN_UNLOCK(vp, 0); 445 XFS_STATS_INC(vn_reclaim);
451 446 XFS_STATS_DEC(vn_active);
452 if (VNHEAD(vp)) 447
453 if (bhv_vop_reclaim(vp)) 448 xfs_inactive(ip);
454 panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, vp); 449 xfs_iflags_clear(ip, XFS_IMODIFIED);
455 450 if (xfs_reclaim(ip))
456 ASSERT(VNHEAD(vp) == NULL); 451 panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, inode);
452 }
457 453
458#ifdef XFS_VNODE_TRACE 454 ASSERT(XFS_I(inode) == NULL);
459 ktrace_free(vp->v_trace);
460#endif
461} 455}
462 456
463/* 457/*
@@ -469,9 +463,9 @@ xfs_fs_clear_inode(
469 */ 463 */
470STATIC void 464STATIC void
471xfs_syncd_queue_work( 465xfs_syncd_queue_work(
472 struct bhv_vfs *vfs, 466 struct xfs_mount *mp,
473 void *data, 467 void *data,
474 void (*syncer)(bhv_vfs_t *, void *)) 468 void (*syncer)(struct xfs_mount *, void *))
475{ 469{
476 struct bhv_vfs_sync_work *work; 470 struct bhv_vfs_sync_work *work;
477 471
@@ -479,11 +473,11 @@ xfs_syncd_queue_work(
479 INIT_LIST_HEAD(&work->w_list); 473 INIT_LIST_HEAD(&work->w_list);
480 work->w_syncer = syncer; 474 work->w_syncer = syncer;
481 work->w_data = data; 475 work->w_data = data;
482 work->w_vfs = vfs; 476 work->w_mount = mp;
483 spin_lock(&vfs->vfs_sync_lock); 477 spin_lock(&mp->m_sync_lock);
484 list_add_tail(&work->w_list, &vfs->vfs_sync_list); 478 list_add_tail(&work->w_list, &mp->m_sync_list);
485 spin_unlock(&vfs->vfs_sync_lock); 479 spin_unlock(&mp->m_sync_lock);
486 wake_up_process(vfs->vfs_sync_task); 480 wake_up_process(mp->m_sync_task);
487} 481}
488 482
489/* 483/*
@@ -494,22 +488,22 @@ xfs_syncd_queue_work(
494 */ 488 */
495STATIC void 489STATIC void
496xfs_flush_inode_work( 490xfs_flush_inode_work(
497 bhv_vfs_t *vfs, 491 struct xfs_mount *mp,
498 void *inode) 492 void *arg)
499{ 493{
500 filemap_flush(((struct inode *)inode)->i_mapping); 494 struct inode *inode = arg;
501 iput((struct inode *)inode); 495 filemap_flush(inode->i_mapping);
496 iput(inode);
502} 497}
503 498
504void 499void
505xfs_flush_inode( 500xfs_flush_inode(
506 xfs_inode_t *ip) 501 xfs_inode_t *ip)
507{ 502{
508 struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 503 struct inode *inode = ip->i_vnode;
509 struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
510 504
511 igrab(inode); 505 igrab(inode);
512 xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work); 506 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inode_work);
513 delay(msecs_to_jiffies(500)); 507 delay(msecs_to_jiffies(500));
514} 508}
515 509
@@ -519,11 +513,12 @@ xfs_flush_inode(
519 */ 513 */
520STATIC void 514STATIC void
521xfs_flush_device_work( 515xfs_flush_device_work(
522 bhv_vfs_t *vfs, 516 struct xfs_mount *mp,
523 void *inode) 517 void *arg)
524{ 518{
525 sync_blockdev(vfs->vfs_super->s_bdev); 519 struct inode *inode = arg;
526 iput((struct inode *)inode); 520 sync_blockdev(mp->m_super->s_bdev);
521 iput(inode);
527} 522}
528 523
529void 524void
@@ -531,35 +526,33 @@ xfs_flush_device(
531 xfs_inode_t *ip) 526 xfs_inode_t *ip)
532{ 527{
533 struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 528 struct inode *inode = vn_to_inode(XFS_ITOV(ip));
534 struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
535 529
536 igrab(inode); 530 igrab(inode);
537 xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work); 531 xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_device_work);
538 delay(msecs_to_jiffies(500)); 532 delay(msecs_to_jiffies(500));
539 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); 533 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
540} 534}
541 535
542STATIC void 536STATIC void
543vfs_sync_worker( 537xfs_sync_worker(
544 bhv_vfs_t *vfsp, 538 struct xfs_mount *mp,
545 void *unused) 539 void *unused)
546{ 540{
547 int error; 541 int error;
548 542
549 if (!(vfsp->vfs_flag & VFS_RDONLY)) 543 if (!(mp->m_flags & XFS_MOUNT_RDONLY))
550 error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \ 544 error = xfs_sync(mp, SYNC_FSDATA | SYNC_BDFLUSH | SYNC_ATTR |
551 SYNC_ATTR | SYNC_REFCACHE | SYNC_SUPER, 545 SYNC_REFCACHE | SYNC_SUPER);
552 NULL); 546 mp->m_sync_seq++;
553 vfsp->vfs_sync_seq++; 547 wake_up(&mp->m_wait_single_sync_task);
554 wake_up(&vfsp->vfs_wait_single_sync_task);
555} 548}
556 549
557STATIC int 550STATIC int
558xfssyncd( 551xfssyncd(
559 void *arg) 552 void *arg)
560{ 553{
554 struct xfs_mount *mp = arg;
561 long timeleft; 555 long timeleft;
562 bhv_vfs_t *vfsp = (bhv_vfs_t *) arg;
563 bhv_vfs_sync_work_t *work, *n; 556 bhv_vfs_sync_work_t *work, *n;
564 LIST_HEAD (tmp); 557 LIST_HEAD (tmp);
565 558
@@ -569,31 +562,31 @@ xfssyncd(
569 timeleft = schedule_timeout_interruptible(timeleft); 562 timeleft = schedule_timeout_interruptible(timeleft);
570 /* swsusp */ 563 /* swsusp */
571 try_to_freeze(); 564 try_to_freeze();
572 if (kthread_should_stop() && list_empty(&vfsp->vfs_sync_list)) 565 if (kthread_should_stop() && list_empty(&mp->m_sync_list))
573 break; 566 break;
574 567
575 spin_lock(&vfsp->vfs_sync_lock); 568 spin_lock(&mp->m_sync_lock);
576 /* 569 /*
577 * We can get woken by laptop mode, to do a sync - 570 * We can get woken by laptop mode, to do a sync -
578 * that's the (only!) case where the list would be 571 * that's the (only!) case where the list would be
579 * empty with time remaining. 572 * empty with time remaining.
580 */ 573 */
581 if (!timeleft || list_empty(&vfsp->vfs_sync_list)) { 574 if (!timeleft || list_empty(&mp->m_sync_list)) {
582 if (!timeleft) 575 if (!timeleft)
583 timeleft = xfs_syncd_centisecs * 576 timeleft = xfs_syncd_centisecs *
584 msecs_to_jiffies(10); 577 msecs_to_jiffies(10);
585 INIT_LIST_HEAD(&vfsp->vfs_sync_work.w_list); 578 INIT_LIST_HEAD(&mp->m_sync_work.w_list);
586 list_add_tail(&vfsp->vfs_sync_work.w_list, 579 list_add_tail(&mp->m_sync_work.w_list,
587 &vfsp->vfs_sync_list); 580 &mp->m_sync_list);
588 } 581 }
589 list_for_each_entry_safe(work, n, &vfsp->vfs_sync_list, w_list) 582 list_for_each_entry_safe(work, n, &mp->m_sync_list, w_list)
590 list_move(&work->w_list, &tmp); 583 list_move(&work->w_list, &tmp);
591 spin_unlock(&vfsp->vfs_sync_lock); 584 spin_unlock(&mp->m_sync_lock);
592 585
593 list_for_each_entry_safe(work, n, &tmp, w_list) { 586 list_for_each_entry_safe(work, n, &tmp, w_list) {
594 (*work->w_syncer)(vfsp, work->w_data); 587 (*work->w_syncer)(mp, work->w_data);
595 list_del(&work->w_list); 588 list_del(&work->w_list);
596 if (work == &vfsp->vfs_sync_work) 589 if (work == &mp->m_sync_work)
597 continue; 590 continue;
598 kmem_free(work, sizeof(struct bhv_vfs_sync_work)); 591 kmem_free(work, sizeof(struct bhv_vfs_sync_work));
599 } 592 }
@@ -602,41 +595,19 @@ xfssyncd(
602 return 0; 595 return 0;
603} 596}
604 597
605STATIC int
606xfs_fs_start_syncd(
607 bhv_vfs_t *vfsp)
608{
609 vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
610 vfsp->vfs_sync_work.w_vfs = vfsp;
611 vfsp->vfs_sync_task = kthread_run(xfssyncd, vfsp, "xfssyncd");
612 if (IS_ERR(vfsp->vfs_sync_task))
613 return -PTR_ERR(vfsp->vfs_sync_task);
614 return 0;
615}
616
617STATIC void
618xfs_fs_stop_syncd(
619 bhv_vfs_t *vfsp)
620{
621 kthread_stop(vfsp->vfs_sync_task);
622}
623
624STATIC void 598STATIC void
625xfs_fs_put_super( 599xfs_fs_put_super(
626 struct super_block *sb) 600 struct super_block *sb)
627{ 601{
628 bhv_vfs_t *vfsp = vfs_from_sb(sb); 602 struct xfs_mount *mp = XFS_M(sb);
629 int error; 603 int error;
630 604
631 xfs_fs_stop_syncd(vfsp); 605 kthread_stop(mp->m_sync_task);
632 bhv_vfs_sync(vfsp, SYNC_ATTR | SYNC_DELWRI, NULL); 606
633 error = bhv_vfs_unmount(vfsp, 0, NULL); 607 xfs_sync(mp, SYNC_ATTR | SYNC_DELWRI);
634 if (error) { 608 error = xfs_unmount(mp, 0, NULL);
609 if (error)
635 printk("XFS: unmount got error=%d\n", error); 610 printk("XFS: unmount got error=%d\n", error);
636 printk("%s: vfs=0x%p left dangling!\n", __FUNCTION__, vfsp);
637 } else {
638 vfs_deallocate(vfsp);
639 }
640} 611}
641 612
642STATIC void 613STATIC void
@@ -644,7 +615,7 @@ xfs_fs_write_super(
644 struct super_block *sb) 615 struct super_block *sb)
645{ 616{
646 if (!(sb->s_flags & MS_RDONLY)) 617 if (!(sb->s_flags & MS_RDONLY))
647 bhv_vfs_sync(vfs_from_sb(sb), SYNC_FSDATA, NULL); 618 xfs_sync(XFS_M(sb), SYNC_FSDATA);
648 sb->s_dirt = 0; 619 sb->s_dirt = 0;
649} 620}
650 621
@@ -653,11 +624,23 @@ xfs_fs_sync_super(
653 struct super_block *sb, 624 struct super_block *sb,
654 int wait) 625 int wait)
655{ 626{
656 bhv_vfs_t *vfsp = vfs_from_sb(sb); 627 struct xfs_mount *mp = XFS_M(sb);
657 int error; 628 int error;
658 int flags; 629 int flags;
659 630
660 if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) { 631 /*
632 * Treat a sync operation like a freeze. This is to work
633 * around a race in sync_inodes() which works in two phases
634 * - an asynchronous flush, which can write out an inode
635 * without waiting for file size updates to complete, and a
636 * synchronous flush, which wont do anything because the
637 * async flush removed the inode's dirty flag. Also
638 * sync_inodes() will not see any files that just have
639 * outstanding transactions to be flushed because we don't
640 * dirty the Linux inode until after the transaction I/O
641 * completes.
642 */
643 if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) {
661 /* 644 /*
662 * First stage of freeze - no more writers will make progress 645 * First stage of freeze - no more writers will make progress
663 * now we are here, so we flush delwri and delalloc buffers 646 * now we are here, so we flush delwri and delalloc buffers
@@ -668,28 +651,28 @@ xfs_fs_sync_super(
668 */ 651 */
669 flags = SYNC_DATA_QUIESCE; 652 flags = SYNC_DATA_QUIESCE;
670 } else 653 } else
671 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); 654 flags = SYNC_FSDATA;
672 655
673 error = bhv_vfs_sync(vfsp, flags, NULL); 656 error = xfs_sync(mp, flags);
674 sb->s_dirt = 0; 657 sb->s_dirt = 0;
675 658
676 if (unlikely(laptop_mode)) { 659 if (unlikely(laptop_mode)) {
677 int prev_sync_seq = vfsp->vfs_sync_seq; 660 int prev_sync_seq = mp->m_sync_seq;
678 661
679 /* 662 /*
680 * The disk must be active because we're syncing. 663 * The disk must be active because we're syncing.
681 * We schedule xfssyncd now (now that the disk is 664 * We schedule xfssyncd now (now that the disk is
682 * active) instead of later (when it might not be). 665 * active) instead of later (when it might not be).
683 */ 666 */
684 wake_up_process(vfsp->vfs_sync_task); 667 wake_up_process(mp->m_sync_task);
685 /* 668 /*
686 * We have to wait for the sync iteration to complete. 669 * We have to wait for the sync iteration to complete.
687 * If we don't, the disk activity caused by the sync 670 * If we don't, the disk activity caused by the sync
688 * will come after the sync is completed, and that 671 * will come after the sync is completed, and that
689 * triggers another sync from laptop mode. 672 * triggers another sync from laptop mode.
690 */ 673 */
691 wait_event(vfsp->vfs_wait_single_sync_task, 674 wait_event(mp->m_wait_single_sync_task,
692 vfsp->vfs_sync_seq != prev_sync_seq); 675 mp->m_sync_seq != prev_sync_seq);
693 } 676 }
694 677
695 return -error; 678 return -error;
@@ -700,7 +683,7 @@ xfs_fs_statfs(
700 struct dentry *dentry, 683 struct dentry *dentry,
701 struct kstatfs *statp) 684 struct kstatfs *statp)
702{ 685{
703 return -bhv_vfs_statvfs(vfs_from_sb(dentry->d_sb), statp, 686 return -xfs_statvfs(XFS_M(dentry->d_sb), statp,
704 vn_from_inode(dentry->d_inode)); 687 vn_from_inode(dentry->d_inode));
705} 688}
706 689
@@ -710,13 +693,13 @@ xfs_fs_remount(
710 int *flags, 693 int *flags,
711 char *options) 694 char *options)
712{ 695{
713 bhv_vfs_t *vfsp = vfs_from_sb(sb); 696 struct xfs_mount *mp = XFS_M(sb);
714 struct xfs_mount_args *args = xfs_args_allocate(sb, 0); 697 struct xfs_mount_args *args = xfs_args_allocate(sb, 0);
715 int error; 698 int error;
716 699
717 error = bhv_vfs_parseargs(vfsp, options, args, 1); 700 error = xfs_parseargs(mp, options, args, 1);
718 if (!error) 701 if (!error)
719 error = bhv_vfs_mntupdate(vfsp, flags, args); 702 error = xfs_mntupdate(mp, flags, args);
720 kmem_free(args, sizeof(*args)); 703 kmem_free(args, sizeof(*args));
721 return -error; 704 return -error;
722} 705}
@@ -725,7 +708,7 @@ STATIC void
725xfs_fs_lockfs( 708xfs_fs_lockfs(
726 struct super_block *sb) 709 struct super_block *sb)
727{ 710{
728 bhv_vfs_freeze(vfs_from_sb(sb)); 711 xfs_freeze(XFS_M(sb));
729} 712}
730 713
731STATIC int 714STATIC int
@@ -733,7 +716,7 @@ xfs_fs_show_options(
733 struct seq_file *m, 716 struct seq_file *m,
734 struct vfsmount *mnt) 717 struct vfsmount *mnt)
735{ 718{
736 return -bhv_vfs_showargs(vfs_from_sb(mnt->mnt_sb), m); 719 return -xfs_showargs(XFS_M(mnt->mnt_sb), m);
737} 720}
738 721
739STATIC int 722STATIC int
@@ -741,7 +724,7 @@ xfs_fs_quotasync(
741 struct super_block *sb, 724 struct super_block *sb,
742 int type) 725 int type)
743{ 726{
744 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL); 727 return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XQUOTASYNC, 0, NULL);
745} 728}
746 729
747STATIC int 730STATIC int
@@ -749,7 +732,7 @@ xfs_fs_getxstate(
749 struct super_block *sb, 732 struct super_block *sb,
750 struct fs_quota_stat *fqs) 733 struct fs_quota_stat *fqs)
751{ 734{
752 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs); 735 return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
753} 736}
754 737
755STATIC int 738STATIC int
@@ -758,7 +741,7 @@ xfs_fs_setxstate(
758 unsigned int flags, 741 unsigned int flags,
759 int op) 742 int op)
760{ 743{
761 return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags); 744 return -XFS_QM_QUOTACTL(XFS_M(sb), op, 0, (caddr_t)&flags);
762} 745}
763 746
764STATIC int 747STATIC int
@@ -768,7 +751,7 @@ xfs_fs_getxquota(
768 qid_t id, 751 qid_t id,
769 struct fs_disk_quota *fdq) 752 struct fs_disk_quota *fdq)
770{ 753{
771 return -bhv_vfs_quotactl(vfs_from_sb(sb), 754 return -XFS_QM_QUOTACTL(XFS_M(sb),
772 (type == USRQUOTA) ? Q_XGETQUOTA : 755 (type == USRQUOTA) ? Q_XGETQUOTA :
773 ((type == GRPQUOTA) ? Q_XGETGQUOTA : 756 ((type == GRPQUOTA) ? Q_XGETGQUOTA :
774 Q_XGETPQUOTA), id, (caddr_t)fdq); 757 Q_XGETPQUOTA), id, (caddr_t)fdq);
@@ -781,7 +764,7 @@ xfs_fs_setxquota(
781 qid_t id, 764 qid_t id,
782 struct fs_disk_quota *fdq) 765 struct fs_disk_quota *fdq)
783{ 766{
784 return -bhv_vfs_quotactl(vfs_from_sb(sb), 767 return -XFS_QM_QUOTACTL(XFS_M(sb),
785 (type == USRQUOTA) ? Q_XSETQLIM : 768 (type == USRQUOTA) ? Q_XSETQLIM :
786 ((type == GRPQUOTA) ? Q_XSETGQLIM : 769 ((type == GRPQUOTA) ? Q_XSETGQLIM :
787 Q_XSETPQLIM), id, (caddr_t)fdq); 770 Q_XSETPQLIM), id, (caddr_t)fdq);
@@ -793,32 +776,38 @@ xfs_fs_fill_super(
793 void *data, 776 void *data,
794 int silent) 777 int silent)
795{ 778{
796 struct bhv_vnode *rootvp; 779 struct inode *rootvp;
797 struct bhv_vfs *vfsp = vfs_allocate(sb); 780 struct xfs_mount *mp = NULL;
798 struct xfs_mount_args *args = xfs_args_allocate(sb, silent); 781 struct xfs_mount_args *args = xfs_args_allocate(sb, silent);
799 struct kstatfs statvfs; 782 struct kstatfs statvfs;
800 int error; 783 int error;
801 784
802 bhv_insert_all_vfsops(vfsp); 785 mp = xfs_mount_init();
803 786
804 error = bhv_vfs_parseargs(vfsp, (char *)data, args, 0); 787 INIT_LIST_HEAD(&mp->m_sync_list);
805 if (error) { 788 spin_lock_init(&mp->m_sync_lock);
806 bhv_remove_all_vfsops(vfsp, 1); 789 init_waitqueue_head(&mp->m_wait_single_sync_task);
790
791 mp->m_super = sb;
792 sb->s_fs_info = mp;
793
794 if (sb->s_flags & MS_RDONLY)
795 mp->m_flags |= XFS_MOUNT_RDONLY;
796
797 error = xfs_parseargs(mp, (char *)data, args, 0);
798 if (error)
807 goto fail_vfsop; 799 goto fail_vfsop;
808 }
809 800
810 sb_min_blocksize(sb, BBSIZE); 801 sb_min_blocksize(sb, BBSIZE);
811 sb->s_export_op = &xfs_export_operations; 802 sb->s_export_op = &xfs_export_operations;
812 sb->s_qcop = &xfs_quotactl_operations; 803 sb->s_qcop = &xfs_quotactl_operations;
813 sb->s_op = &xfs_super_operations; 804 sb->s_op = &xfs_super_operations;
814 805
815 error = bhv_vfs_mount(vfsp, args, NULL); 806 error = xfs_mount(mp, args, NULL);
816 if (error) { 807 if (error)
817 bhv_remove_all_vfsops(vfsp, 1);
818 goto fail_vfsop; 808 goto fail_vfsop;
819 }
820 809
821 error = bhv_vfs_statvfs(vfsp, &statvfs, NULL); 810 error = xfs_statvfs(mp, &statvfs, NULL);
822 if (error) 811 if (error)
823 goto fail_unmount; 812 goto fail_unmount;
824 813
@@ -830,7 +819,7 @@ xfs_fs_fill_super(
830 sb->s_time_gran = 1; 819 sb->s_time_gran = 1;
831 set_posix_acl_flag(sb); 820 set_posix_acl_flag(sb);
832 821
833 error = bhv_vfs_root(vfsp, &rootvp); 822 error = xfs_root(mp, &rootvp);
834 if (error) 823 if (error)
835 goto fail_unmount; 824 goto fail_unmount;
836 825
@@ -843,9 +832,17 @@ xfs_fs_fill_super(
843 error = EINVAL; 832 error = EINVAL;
844 goto fail_vnrele; 833 goto fail_vnrele;
845 } 834 }
846 if ((error = xfs_fs_start_syncd(vfsp))) 835
836 mp->m_sync_work.w_syncer = xfs_sync_worker;
837 mp->m_sync_work.w_mount = mp;
838 mp->m_sync_task = kthread_run(xfssyncd, mp, "xfssyncd");
839 if (IS_ERR(mp->m_sync_task)) {
840 error = -PTR_ERR(mp->m_sync_task);
847 goto fail_vnrele; 841 goto fail_vnrele;
848 vn_trace_exit(rootvp, __FUNCTION__, (inst_t *)__return_address); 842 }
843
844 vn_trace_exit(XFS_I(sb->s_root->d_inode), __FUNCTION__,
845 (inst_t *)__return_address);
849 846
850 kmem_free(args, sizeof(*args)); 847 kmem_free(args, sizeof(*args));
851 return 0; 848 return 0;
@@ -859,10 +856,9 @@ fail_vnrele:
859 } 856 }
860 857
861fail_unmount: 858fail_unmount:
862 bhv_vfs_unmount(vfsp, 0, NULL); 859 xfs_unmount(mp, 0, NULL);
863 860
864fail_vfsop: 861fail_vfsop:
865 vfs_deallocate(vfsp);
866 kmem_free(args, sizeof(*args)); 862 kmem_free(args, sizeof(*args));
867 return -error; 863 return -error;
868} 864}
@@ -914,15 +910,11 @@ STATIC int __init
914init_xfs_fs( void ) 910init_xfs_fs( void )
915{ 911{
916 int error; 912 int error;
917 struct sysinfo si;
918 static char message[] __initdata = KERN_INFO \ 913 static char message[] __initdata = KERN_INFO \
919 XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n"; 914 XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled\n";
920 915
921 printk(message); 916 printk(message);
922 917
923 si_meminfo(&si);
924 xfs_physmem = si.totalram;
925
926 ktrace_init(64); 918 ktrace_init(64);
927 919
928 error = xfs_init_zones(); 920 error = xfs_init_zones();
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index 201cc3273c84..c78c23310fe8 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -107,7 +107,8 @@ struct block_device;
107 107
108extern __uint64_t xfs_max_file_offset(unsigned int); 108extern __uint64_t xfs_max_file_offset(unsigned int);
109 109
110extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int); 110extern void xfs_initialize_vnode(struct xfs_mount *mp, bhv_vnode_t *vp,
111 struct xfs_inode *ip);
111 112
112extern void xfs_flush_inode(struct xfs_inode *); 113extern void xfs_flush_inode(struct xfs_inode *);
113extern void xfs_flush_device(struct xfs_inode *); 114extern void xfs_flush_device(struct xfs_inode *);
@@ -119,4 +120,6 @@ extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
119 120
120extern struct export_operations xfs_export_operations; 121extern struct export_operations xfs_export_operations;
121 122
123#define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info))
124
122#endif /* __XFS_SUPER_H__ */ 125#endif /* __XFS_SUPER_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c
deleted file mode 100644
index 6145e8bd0be2..000000000000
--- a/fs/xfs/linux-2.6/xfs_vfs.c
+++ /dev/null
@@ -1,327 +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#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_inum.h"
21#include "xfs_log.h"
22#include "xfs_clnt.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_imap.h"
28#include "xfs_alloc.h"
29#include "xfs_dmapi.h"
30#include "xfs_mount.h"
31#include "xfs_quota.h"
32
33int
34vfs_mount(
35 struct bhv_desc *bdp,
36 struct xfs_mount_args *args,
37 struct cred *cr)
38{
39 struct bhv_desc *next = bdp;
40
41 ASSERT(next);
42 while (! (bhvtovfsops(next))->vfs_mount)
43 next = BHV_NEXT(next);
44 return ((*bhvtovfsops(next)->vfs_mount)(next, args, cr));
45}
46
47int
48vfs_parseargs(
49 struct bhv_desc *bdp,
50 char *s,
51 struct xfs_mount_args *args,
52 int f)
53{
54 struct bhv_desc *next = bdp;
55
56 ASSERT(next);
57 while (! (bhvtovfsops(next))->vfs_parseargs)
58 next = BHV_NEXT(next);
59 return ((*bhvtovfsops(next)->vfs_parseargs)(next, s, args, f));
60}
61
62int
63vfs_showargs(
64 struct bhv_desc *bdp,
65 struct seq_file *m)
66{
67 struct bhv_desc *next = bdp;
68
69 ASSERT(next);
70 while (! (bhvtovfsops(next))->vfs_showargs)
71 next = BHV_NEXT(next);
72 return ((*bhvtovfsops(next)->vfs_showargs)(next, m));
73}
74
75int
76vfs_unmount(
77 struct bhv_desc *bdp,
78 int fl,
79 struct cred *cr)
80{
81 struct bhv_desc *next = bdp;
82
83 ASSERT(next);
84 while (! (bhvtovfsops(next))->vfs_unmount)
85 next = BHV_NEXT(next);
86 return ((*bhvtovfsops(next)->vfs_unmount)(next, fl, cr));
87}
88
89int
90vfs_mntupdate(
91 struct bhv_desc *bdp,
92 int *fl,
93 struct xfs_mount_args *args)
94{
95 struct bhv_desc *next = bdp;
96
97 ASSERT(next);
98 while (! (bhvtovfsops(next))->vfs_mntupdate)
99 next = BHV_NEXT(next);
100 return ((*bhvtovfsops(next)->vfs_mntupdate)(next, fl, args));
101}
102
103int
104vfs_root(
105 struct bhv_desc *bdp,
106 struct bhv_vnode **vpp)
107{
108 struct bhv_desc *next = bdp;
109
110 ASSERT(next);
111 while (! (bhvtovfsops(next))->vfs_root)
112 next = BHV_NEXT(next);
113 return ((*bhvtovfsops(next)->vfs_root)(next, vpp));
114}
115
116int
117vfs_statvfs(
118 struct bhv_desc *bdp,
119 bhv_statvfs_t *statp,
120 struct bhv_vnode *vp)
121{
122 struct bhv_desc *next = bdp;
123
124 ASSERT(next);
125 while (! (bhvtovfsops(next))->vfs_statvfs)
126 next = BHV_NEXT(next);
127 return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp));
128}
129
130int
131vfs_sync(
132 struct bhv_desc *bdp,
133 int fl,
134 struct cred *cr)
135{
136 struct bhv_desc *next = bdp;
137
138 ASSERT(next);
139 while (! (bhvtovfsops(next))->vfs_sync)
140 next = BHV_NEXT(next);
141 return ((*bhvtovfsops(next)->vfs_sync)(next, fl, cr));
142}
143
144int
145vfs_vget(
146 struct bhv_desc *bdp,
147 struct bhv_vnode **vpp,
148 struct fid *fidp)
149{
150 struct bhv_desc *next = bdp;
151
152 ASSERT(next);
153 while (! (bhvtovfsops(next))->vfs_vget)
154 next = BHV_NEXT(next);
155 return ((*bhvtovfsops(next)->vfs_vget)(next, vpp, fidp));
156}
157
158int
159vfs_dmapiops(
160 struct bhv_desc *bdp,
161 caddr_t addr)
162{
163 struct bhv_desc *next = bdp;
164
165 ASSERT(next);
166 while (! (bhvtovfsops(next))->vfs_dmapiops)
167 next = BHV_NEXT(next);
168 return ((*bhvtovfsops(next)->vfs_dmapiops)(next, addr));
169}
170
171int
172vfs_quotactl(
173 struct bhv_desc *bdp,
174 int cmd,
175 int id,
176 caddr_t addr)
177{
178 struct bhv_desc *next = bdp;
179
180 ASSERT(next);
181 while (! (bhvtovfsops(next))->vfs_quotactl)
182 next = BHV_NEXT(next);
183 return ((*bhvtovfsops(next)->vfs_quotactl)(next, cmd, id, addr));
184}
185
186void
187vfs_init_vnode(
188 struct bhv_desc *bdp,
189 struct bhv_vnode *vp,
190 struct bhv_desc *bp,
191 int unlock)
192{
193 struct bhv_desc *next = bdp;
194
195 ASSERT(next);
196 while (! (bhvtovfsops(next))->vfs_init_vnode)
197 next = BHV_NEXT(next);
198 ((*bhvtovfsops(next)->vfs_init_vnode)(next, vp, bp, unlock));
199}
200
201void
202vfs_force_shutdown(
203 struct bhv_desc *bdp,
204 int fl,
205 char *file,
206 int line)
207{
208 struct bhv_desc *next = bdp;
209
210 ASSERT(next);
211 while (! (bhvtovfsops(next))->vfs_force_shutdown)
212 next = BHV_NEXT(next);
213 ((*bhvtovfsops(next)->vfs_force_shutdown)(next, fl, file, line));
214}
215
216void
217vfs_freeze(
218 struct bhv_desc *bdp)
219{
220 struct bhv_desc *next = bdp;
221
222 ASSERT(next);
223 while (! (bhvtovfsops(next))->vfs_freeze)
224 next = BHV_NEXT(next);
225 ((*bhvtovfsops(next)->vfs_freeze)(next));
226}
227
228bhv_vfs_t *
229vfs_allocate(
230 struct super_block *sb)
231{
232 struct bhv_vfs *vfsp;
233
234 vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP);
235 bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
236 INIT_LIST_HEAD(&vfsp->vfs_sync_list);
237 spin_lock_init(&vfsp->vfs_sync_lock);
238 init_waitqueue_head(&vfsp->vfs_wait_single_sync_task);
239
240 vfsp->vfs_super = sb;
241 sb->s_fs_info = vfsp;
242
243 if (sb->s_flags & MS_RDONLY)
244 vfsp->vfs_flag |= VFS_RDONLY;
245
246 return vfsp;
247}
248
249bhv_vfs_t *
250vfs_from_sb(
251 struct super_block *sb)
252{
253 return (bhv_vfs_t *)sb->s_fs_info;
254}
255
256void
257vfs_deallocate(
258 struct bhv_vfs *vfsp)
259{
260 bhv_head_destroy(VFS_BHVHEAD(vfsp));
261 kmem_free(vfsp, sizeof(bhv_vfs_t));
262}
263
264void
265vfs_insertops(
266 struct bhv_vfs *vfsp,
267 struct bhv_module_vfsops *vfsops)
268{
269 struct bhv_desc *bdp;
270
271 bdp = kmem_alloc(sizeof(struct bhv_desc), KM_SLEEP);
272 bhv_desc_init(bdp, NULL, vfsp, vfsops);
273 bhv_insert(&vfsp->vfs_bh, bdp);
274}
275
276void
277vfs_insertbhv(
278 struct bhv_vfs *vfsp,
279 struct bhv_desc *bdp,
280 struct bhv_vfsops *vfsops,
281 void *mount)
282{
283 bhv_desc_init(bdp, mount, vfsp, vfsops);
284 bhv_insert_initial(&vfsp->vfs_bh, bdp);
285}
286
287void
288bhv_remove_vfsops(
289 struct bhv_vfs *vfsp,
290 int pos)
291{
292 struct bhv_desc *bhv;
293
294 bhv = bhv_lookup_range(&vfsp->vfs_bh, pos, pos);
295 if (!bhv)
296 return;
297 bhv_remove(&vfsp->vfs_bh, bhv);
298 kmem_free(bhv, sizeof(*bhv));
299}
300
301void
302bhv_remove_all_vfsops(
303 struct bhv_vfs *vfsp,
304 int freebase)
305{
306 struct xfs_mount *mp;
307
308 bhv_remove_vfsops(vfsp, VFS_POSITION_QM);
309 bhv_remove_vfsops(vfsp, VFS_POSITION_DM);
310 if (!freebase)
311 return;
312 mp = XFS_VFSTOM(vfsp);
313 VFS_REMOVEBHV(vfsp, &mp->m_bhv);
314 xfs_mount_free(mp, 0);
315}
316
317void
318bhv_insert_all_vfsops(
319 struct bhv_vfs *vfsp)
320{
321 struct xfs_mount *mp;
322
323 mp = xfs_mount_init();
324 vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
325 vfs_insertdmapi(vfsp);
326 vfs_insertquota(vfsp);
327}
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index dca3481aaafa..4da03a4e3520 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -21,68 +21,25 @@
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; 24struct inode;
25struct bhv_vnode;
26 25
27struct fid; 26struct fid;
28struct cred; 27struct cred;
29struct seq_file; 28struct seq_file;
30struct super_block; 29struct super_block;
30struct xfs_inode;
31struct xfs_mount;
31struct xfs_mount_args; 32struct xfs_mount_args;
32 33
33typedef struct kstatfs bhv_statvfs_t; 34typedef struct kstatfs bhv_statvfs_t;
34 35
35typedef struct bhv_vfs_sync_work { 36typedef struct bhv_vfs_sync_work {
36 struct list_head w_list; 37 struct list_head w_list;
37 struct bhv_vfs *w_vfs; 38 struct xfs_mount *w_mount;
38 void *w_data; /* syncer routine argument */ 39 void *w_data; /* syncer routine argument */
39 void (*w_syncer)(struct bhv_vfs *, void *); 40 void (*w_syncer)(struct xfs_mount *, void *);
40} bhv_vfs_sync_work_t; 41} bhv_vfs_sync_work_t;
41 42
42typedef struct bhv_vfs {
43 u_int vfs_flag; /* flags */
44 xfs_fsid_t vfs_fsid; /* file system ID */
45 xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
46 bhv_head_t vfs_bh; /* head of vfs behavior chain */
47 struct super_block *vfs_super; /* generic superblock pointer */
48 struct task_struct *vfs_sync_task; /* generalised sync thread */
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 */
51 spinlock_t vfs_sync_lock; /* work item list lock */
52 int vfs_sync_seq; /* sync thread generation no. */
53 wait_queue_head_t vfs_wait_single_sync_task;
54} bhv_vfs_t;
55
56#define bhvtovfs(bdp) ( (struct bhv_vfs *)BHV_VOBJ(bdp) )
57#define bhvtovfsops(bdp) ( (struct bhv_vfsops *)BHV_OPS(bdp) )
58#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
59#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
60
61#define VFS_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
62#define VFS_POSITION_TOP BHV_POSITION_TOP /* chain top */
63#define VFS_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
64
65typedef enum {
66 VFS_BHV_UNKNOWN, /* not specified */
67 VFS_BHV_XFS, /* xfs */
68 VFS_BHV_DM, /* data migration */
69 VFS_BHV_QM, /* quota manager */
70 VFS_BHV_IO, /* IO path */
71 VFS_BHV_END /* housekeeping end-of-range */
72} bhv_vfs_type_t;
73
74#define VFS_POSITION_XFS (BHV_POSITION_BASE)
75#define VFS_POSITION_DM (VFS_POSITION_BASE+10)
76#define VFS_POSITION_QM (VFS_POSITION_BASE+20)
77#define VFS_POSITION_IO (VFS_POSITION_BASE+30)
78
79#define VFS_RDONLY 0x0001 /* read-only vfs */
80#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
81#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
82/* ---- VFS_UMOUNT ---- 0x0008 -- unneeded, fixed via kthread APIs */
83#define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */
84#define VFS_END 0x0010 /* max flag */
85
86#define SYNC_ATTR 0x0001 /* sync attributes */ 43#define SYNC_ATTR 0x0001 /* sync attributes */
87#define SYNC_CLOSE 0x0002 /* close file system down */ 44#define SYNC_CLOSE 0x0002 /* close file system down */
88#define SYNC_DELWRI 0x0004 /* look at delayed writes */ 45#define SYNC_DELWRI 0x0004 /* look at delayed writes */
@@ -115,118 +72,7 @@ typedef enum {
115#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */ 72#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */
116#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */ 73#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */
117 74
118typedef int (*vfs_mount_t)(bhv_desc_t *, 75#define xfs_test_for_freeze(mp) ((mp)->m_super->s_frozen)
119 struct xfs_mount_args *, struct cred *); 76#define xfs_wait_for_freeze(mp,l) vfs_check_frozen((mp)->m_super, (l))
120typedef int (*vfs_parseargs_t)(bhv_desc_t *, char *,
121 struct xfs_mount_args *, int);
122typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
123typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
124typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
125 struct xfs_mount_args *);
126typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **);
127typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *,
128 struct bhv_vnode *);
129typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
130typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *);
131typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
132typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
133typedef void (*vfs_init_vnode_t)(bhv_desc_t *,
134 struct bhv_vnode *, bhv_desc_t *, int);
135typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
136typedef void (*vfs_freeze_t)(bhv_desc_t *);
137
138typedef struct bhv_vfsops {
139 bhv_position_t vf_position; /* behavior chain position */
140 vfs_mount_t vfs_mount; /* mount file system */
141 vfs_parseargs_t vfs_parseargs; /* parse mount options */
142 vfs_showargs_t vfs_showargs; /* unparse mount options */
143 vfs_unmount_t vfs_unmount; /* unmount file system */
144 vfs_mntupdate_t vfs_mntupdate; /* update file system options */
145 vfs_root_t vfs_root; /* get root vnode */
146 vfs_statvfs_t vfs_statvfs; /* file system statistics */
147 vfs_sync_t vfs_sync; /* flush files */
148 vfs_vget_t vfs_vget; /* get vnode from fid */
149 vfs_dmapiops_t vfs_dmapiops; /* data migration */
150 vfs_quotactl_t vfs_quotactl; /* disk quota */
151 vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
152 vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
153 vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */
154} bhv_vfsops_t;
155
156/*
157 * Virtual filesystem operations, operating from head bhv.
158 */
159#define VFSHEAD(v) ((v)->vfs_bh.bh_first)
160#define bhv_vfs_mount(v, ma,cr) vfs_mount(VFSHEAD(v), ma,cr)
161#define bhv_vfs_parseargs(v, o,ma,f) vfs_parseargs(VFSHEAD(v), o,ma,f)
162#define bhv_vfs_showargs(v, m) vfs_showargs(VFSHEAD(v), m)
163#define bhv_vfs_unmount(v, f,cr) vfs_unmount(VFSHEAD(v), f,cr)
164#define bhv_vfs_mntupdate(v, fl,args) vfs_mntupdate(VFSHEAD(v), fl,args)
165#define bhv_vfs_root(v, vpp) vfs_root(VFSHEAD(v), vpp)
166#define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)
167#define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)
168#define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp)
169#define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p)
170#define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)
171#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
172#define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
173#define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v))
174
175/*
176 * Virtual filesystem operations, operating from next bhv.
177 */
178#define bhv_next_vfs_mount(b, ma,cr) vfs_mount(b, ma,cr)
179#define bhv_next_vfs_parseargs(b, o,ma,f) vfs_parseargs(b, o,ma,f)
180#define bhv_next_vfs_showargs(b, m) vfs_showargs(b, m)
181#define bhv_next_vfs_unmount(b, f,cr) vfs_unmount(b, f,cr)
182#define bhv_next_vfs_mntupdate(b, fl,args) vfs_mntupdate(b, fl, args)
183#define bhv_next_vfs_root(b, vpp) vfs_root(b, vpp)
184#define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp)
185#define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr)
186#define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp)
187#define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p)
188#define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p)
189#define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul)
190#define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
191#define bhv_next_vfs_freeze(b) vfs_freeze(b)
192
193extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
194extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
195extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
196extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
197extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
198extern int vfs_root(bhv_desc_t *, struct bhv_vnode **);
199extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *);
200extern int vfs_sync(bhv_desc_t *, int, struct cred *);
201extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *);
202extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
203extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
204extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int);
205extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
206extern void vfs_freeze(bhv_desc_t *);
207
208#define vfs_test_for_freeze(vfs) ((vfs)->vfs_super->s_frozen)
209#define vfs_wait_for_freeze(vfs,l) vfs_check_frozen((vfs)->vfs_super, (l))
210
211typedef struct bhv_module_vfsops {
212 struct bhv_vfsops bhv_common;
213 void * bhv_custom;
214} bhv_module_vfsops_t;
215
216#define vfs_bhv_lookup(v, id) (bhv_lookup_range(&(v)->vfs_bh, (id), (id)))
217#define vfs_bhv_custom(b) (((bhv_module_vfsops_t*)BHV_OPS(b))->bhv_custom)
218#define vfs_bhv_set_custom(b,o) ((b)->bhv_custom = (void *)(o))
219#define vfs_bhv_clr_custom(b) ((b)->bhv_custom = NULL)
220
221extern bhv_vfs_t *vfs_allocate(struct super_block *);
222extern bhv_vfs_t *vfs_from_sb(struct super_block *);
223extern void vfs_deallocate(bhv_vfs_t *);
224extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *);
225
226extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *);
227
228extern void bhv_insert_all_vfsops(struct bhv_vfs *);
229extern void bhv_remove_all_vfsops(struct bhv_vfs *, int);
230extern void bhv_remove_vfsops(struct bhv_vfs *, int);
231 77
232#endif /* __XFS_VFS_H__ */ 78#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 ada24baf88de..814169fd7e1e 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -16,9 +16,21 @@
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#include "xfs.h" 18#include "xfs.h"
19#include "xfs_vnodeops.h"
20#include "xfs_bmap_btree.h"
21#include "xfs_inode.h"
22
23/*
24 * And this gunk is needed for xfs_mount.h"
25 */
26#include "xfs_log.h"
27#include "xfs_trans.h"
28#include "xfs_sb.h"
29#include "xfs_dmapi.h"
30#include "xfs_inum.h"
31#include "xfs_ag.h"
32#include "xfs_mount.h"
19 33
20uint64_t vn_generation; /* vnode generation number */
21DEFINE_SPINLOCK(vnumber_lock);
22 34
23/* 35/*
24 * Dedicated vnode inactive/reclaim sync semaphores. 36 * Dedicated vnode inactive/reclaim sync semaphores.
@@ -39,19 +51,19 @@ vn_init(void)
39 51
40void 52void
41vn_iowait( 53vn_iowait(
42 bhv_vnode_t *vp) 54 xfs_inode_t *ip)
43{ 55{
44 wait_queue_head_t *wq = vptosync(vp); 56 wait_queue_head_t *wq = vptosync(ip);
45 57
46 wait_event(*wq, (atomic_read(&vp->v_iocount) == 0)); 58 wait_event(*wq, (atomic_read(&ip->i_iocount) == 0));
47} 59}
48 60
49void 61void
50vn_iowake( 62vn_iowake(
51 bhv_vnode_t *vp) 63 xfs_inode_t *ip)
52{ 64{
53 if (atomic_dec_and_test(&vp->v_iocount)) 65 if (atomic_dec_and_test(&ip->i_iocount))
54 wake_up(vptosync(vp)); 66 wake_up(vptosync(ip));
55} 67}
56 68
57/* 69/*
@@ -61,13 +73,13 @@ vn_iowake(
61 */ 73 */
62void 74void
63vn_ioerror( 75vn_ioerror(
64 bhv_vnode_t *vp, 76 xfs_inode_t *ip,
65 int error, 77 int error,
66 char *f, 78 char *f,
67 int l) 79 int l)
68{ 80{
69 if (unlikely(error == -ENODEV)) 81 if (unlikely(error == -ENODEV))
70 bhv_vfs_force_shutdown(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l); 82 xfs_do_force_shutdown(ip->i_mount, SHUTDOWN_DEVICE_REQ, f, l);
71} 83}
72 84
73bhv_vnode_t * 85bhv_vnode_t *
@@ -79,27 +91,8 @@ vn_initialize(
79 XFS_STATS_INC(vn_active); 91 XFS_STATS_INC(vn_active);
80 XFS_STATS_INC(vn_alloc); 92 XFS_STATS_INC(vn_alloc);
81 93
82 vp->v_flag = VMODIFIED;
83 spinlock_init(&vp->v_lock, "v_lock");
84
85 spin_lock(&vnumber_lock);
86 if (!++vn_generation) /* v_number shouldn't be zero */
87 vn_generation++;
88 vp->v_number = vn_generation;
89 spin_unlock(&vnumber_lock);
90
91 ASSERT(VN_CACHED(vp) == 0); 94 ASSERT(VN_CACHED(vp) == 0);
92 95
93 /* Initialize the first behavior and the behavior chain head. */
94 vn_bhv_head_init(VN_BHV_HEAD(vp), "vnode");
95
96 atomic_set(&vp->v_iocount, 0);
97
98#ifdef XFS_VNODE_TRACE
99 vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
100#endif /* XFS_VNODE_TRACE */
101
102 vn_trace_exit(vp, __FUNCTION__, (inst_t *)__return_address);
103 return vp; 96 return vp;
104} 97}
105 98
@@ -150,12 +143,12 @@ __vn_revalidate(
150{ 143{
151 int error; 144 int error;
152 145
153 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 146 vn_trace_entry(xfs_vtoi(vp), __FUNCTION__, (inst_t *)__return_address);
154 vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS; 147 vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS;
155 error = bhv_vop_getattr(vp, vattr, 0, NULL); 148 error = xfs_getattr(xfs_vtoi(vp), vattr, 0);
156 if (likely(!error)) { 149 if (likely(!error)) {
157 vn_revalidate_core(vp, vattr); 150 vn_revalidate_core(vp, vattr);
158 VUNMODIFY(vp); 151 xfs_iflags_clear(xfs_vtoi(vp), XFS_IMODIFIED);
159 } 152 }
160 return -error; 153 return -error;
161} 154}
@@ -180,24 +173,35 @@ vn_hold(
180 173
181 XFS_STATS_INC(vn_hold); 174 XFS_STATS_INC(vn_hold);
182 175
183 VN_LOCK(vp);
184 inode = igrab(vn_to_inode(vp)); 176 inode = igrab(vn_to_inode(vp));
185 ASSERT(inode); 177 ASSERT(inode);
186 VN_UNLOCK(vp, 0);
187 178
188 return vp; 179 return vp;
189} 180}
190 181
191#ifdef XFS_VNODE_TRACE 182#ifdef XFS_VNODE_TRACE
192 183
193#define KTRACE_ENTER(vp, vk, s, line, ra) \ 184/*
194 ktrace_enter( (vp)->v_trace, \ 185 * Reference count of Linux inode if present, -1 if the xfs_inode
186 * has no associated Linux inode.
187 */
188static inline int xfs_icount(struct xfs_inode *ip)
189{
190 bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
191
192 if (vp)
193 return vn_count(vp);
194 return -1;
195}
196
197#define KTRACE_ENTER(ip, vk, s, line, ra) \
198 ktrace_enter( (ip)->i_trace, \
195/* 0 */ (void *)(__psint_t)(vk), \ 199/* 0 */ (void *)(__psint_t)(vk), \
196/* 1 */ (void *)(s), \ 200/* 1 */ (void *)(s), \
197/* 2 */ (void *)(__psint_t) line, \ 201/* 2 */ (void *)(__psint_t) line, \
198/* 3 */ (void *)(__psint_t)(vn_count(vp)), \ 202/* 3 */ (void *)(__psint_t)xfs_icount(ip), \
199/* 4 */ (void *)(ra), \ 203/* 4 */ (void *)(ra), \
200/* 5 */ (void *)(__psunsigned_t)(vp)->v_flag, \ 204/* 5 */ NULL, \
201/* 6 */ (void *)(__psint_t)current_cpu(), \ 205/* 6 */ (void *)(__psint_t)current_cpu(), \
202/* 7 */ (void *)(__psint_t)current_pid(), \ 206/* 7 */ (void *)(__psint_t)current_pid(), \
203/* 8 */ (void *)__return_address, \ 207/* 8 */ (void *)__return_address, \
@@ -207,32 +211,32 @@ vn_hold(
207 * Vnode tracing code. 211 * Vnode tracing code.
208 */ 212 */
209void 213void
210vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra) 214vn_trace_entry(xfs_inode_t *ip, const char *func, inst_t *ra)
211{ 215{
212 KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); 216 KTRACE_ENTER(ip, VNODE_KTRACE_ENTRY, func, 0, ra);
213} 217}
214 218
215void 219void
216vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra) 220vn_trace_exit(xfs_inode_t *ip, const char *func, inst_t *ra)
217{ 221{
218 KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); 222 KTRACE_ENTER(ip, VNODE_KTRACE_EXIT, func, 0, ra);
219} 223}
220 224
221void 225void
222vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra) 226vn_trace_hold(xfs_inode_t *ip, char *file, int line, inst_t *ra)
223{ 227{
224 KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra); 228 KTRACE_ENTER(ip, VNODE_KTRACE_HOLD, file, line, ra);
225} 229}
226 230
227void 231void
228vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra) 232vn_trace_ref(xfs_inode_t *ip, char *file, int line, inst_t *ra)
229{ 233{
230 KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra); 234 KTRACE_ENTER(ip, VNODE_KTRACE_REF, file, line, ra);
231} 235}
232 236
233void 237void
234vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra) 238vn_trace_rele(xfs_inode_t *ip, char *file, int line, inst_t *ra)
235{ 239{
236 KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra); 240 KTRACE_ENTER(ip, VNODE_KTRACE_RELE, file, line, ra);
237} 241}
238#endif /* XFS_VNODE_TRACE */ 242#endif /* XFS_VNODE_TRACE */
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 5742d65f0785..55fb46948589 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -18,84 +18,31 @@
18#ifndef __XFS_VNODE_H__ 18#ifndef __XFS_VNODE_H__
19#define __XFS_VNODE_H__ 19#define __XFS_VNODE_H__
20 20
21struct uio;
22struct file; 21struct file;
23struct bhv_vfs;
24struct bhv_vattr; 22struct bhv_vattr;
25struct xfs_iomap; 23struct xfs_iomap;
26struct attrlist_cursor_kern; 24struct attrlist_cursor_kern;
27 25
28typedef struct dentry bhv_vname_t; 26typedef struct dentry bhv_vname_t;
29typedef __u64 bhv_vnumber_t; 27typedef __u64 bhv_vnumber_t;
28typedef struct inode bhv_vnode_t;
30 29
31typedef enum bhv_vflags { 30#define VN_ISLNK(vp) S_ISLNK((vp)->i_mode)
32 VMODIFIED = 0x08, /* XFS inode state possibly differs */ 31#define VN_ISREG(vp) S_ISREG((vp)->i_mode)
33 /* to the Linux inode state. */ 32#define VN_ISDIR(vp) S_ISDIR((vp)->i_mode)
34 VTRUNCATED = 0x40, /* truncated down so flush-on-close */ 33#define VN_ISCHR(vp) S_ISCHR((vp)->i_mode)
35} bhv_vflags_t; 34#define VN_ISBLK(vp) S_ISBLK((vp)->i_mode)
36
37/*
38 * MP locking protocols:
39 * v_flag, v_vfsp VN_LOCK/VN_UNLOCK
40 */
41typedef struct bhv_vnode {
42 bhv_vflags_t v_flag; /* vnode flags (see above) */
43 bhv_vfs_t *v_vfsp; /* ptr to containing VFS */
44 bhv_vnumber_t v_number; /* in-core vnode number */
45 bhv_head_t v_bh; /* behavior head */
46 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
47 atomic_t v_iocount; /* outstanding I/O count */
48#ifdef XFS_VNODE_TRACE
49 struct ktrace *v_trace; /* trace header structure */
50#endif
51 struct inode v_inode; /* Linux inode */
52 /* inode MUST be last */
53} bhv_vnode_t;
54
55#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode)
56#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode)
57#define VN_ISDIR(vp) S_ISDIR((vp)->v_inode.i_mode)
58#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode)
59#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode)
60
61#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
62#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */
63#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
64
65typedef enum {
66 VN_BHV_UNKNOWN, /* not specified */
67 VN_BHV_XFS, /* xfs */
68 VN_BHV_DM, /* data migration */
69 VN_BHV_QM, /* quota manager */
70 VN_BHV_IO, /* IO path */
71 VN_BHV_END /* housekeeping end-of-range */
72} vn_bhv_t;
73
74#define VNODE_POSITION_XFS (VNODE_POSITION_BASE)
75#define VNODE_POSITION_DM (VNODE_POSITION_BASE+10)
76#define VNODE_POSITION_QM (VNODE_POSITION_BASE+20)
77#define VNODE_POSITION_IO (VNODE_POSITION_BASE+30)
78
79/*
80 * Macros for dealing with the behavior descriptor inside of the vnode.
81 */
82#define BHV_TO_VNODE(bdp) ((bhv_vnode_t *)BHV_VOBJ(bdp))
83#define BHV_TO_VNODE_NULL(bdp) ((bhv_vnode_t *)BHV_VOBJNULL(bdp))
84
85#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
86#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
87#define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp)
88 35
89/* 36/*
90 * Vnode to Linux inode mapping. 37 * Vnode to Linux inode mapping.
91 */ 38 */
92static inline struct bhv_vnode *vn_from_inode(struct inode *inode) 39static inline bhv_vnode_t *vn_from_inode(struct inode *inode)
93{ 40{
94 return container_of(inode, bhv_vnode_t, v_inode); 41 return inode;
95} 42}
96static inline struct inode *vn_to_inode(struct bhv_vnode *vnode) 43static inline struct inode *vn_to_inode(bhv_vnode_t *vnode)
97{ 44{
98 return &vnode->v_inode; 45 return vnode;
99} 46}
100 47
101/* 48/*
@@ -111,7 +58,7 @@ typedef enum bhv_vrwlock {
111} bhv_vrwlock_t; 58} bhv_vrwlock_t;
112 59
113/* 60/*
114 * Return values for bhv_vop_inactive. A return value of 61 * Return values for xfs_inactive. A return value of
115 * VN_INACTIVE_NOCACHE implies that the file system behavior 62 * VN_INACTIVE_NOCACHE implies that the file system behavior
116 * has disassociated its state and bhv_desc_t from the vnode. 63 * has disassociated its state and bhv_desc_t from the vnode.
117 */ 64 */
@@ -119,193 +66,6 @@ typedef enum bhv_vrwlock {
119#define VN_INACTIVE_NOCACHE 1 66#define VN_INACTIVE_NOCACHE 1
120 67
121/* 68/*
122 * Values for the cmd code given to vop_vnode_change.
123 */
124typedef enum bhv_vchange {
125 VCHANGE_FLAGS_FRLOCKS = 0,
126 VCHANGE_FLAGS_ENF_LOCKING = 1,
127 VCHANGE_FLAGS_TRUNCATED = 2,
128 VCHANGE_FLAGS_PAGE_DIRTY = 3,
129 VCHANGE_FLAGS_IOEXCL_COUNT = 4
130} bhv_vchange_t;
131
132typedef int (*vop_open_t)(bhv_desc_t *, struct cred *);
133typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
134 const struct iovec *, unsigned int,
135 loff_t *, int, struct cred *);
136typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *,
137 const struct iovec *, unsigned int,
138 loff_t *, int, struct cred *);
139typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *, loff_t *,
140 struct pipe_inode_info *, size_t, int, int,
141 struct cred *);
142typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
143 struct file *, loff_t *, size_t, int, int,
144 struct cred *);
145typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
146 int, unsigned int, void __user *);
147typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
148 struct cred *);
149typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
150 struct cred *);
151typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *);
152typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **,
153 int, bhv_vnode_t *, struct cred *);
154typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
155 bhv_vnode_t **, struct cred *);
156typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
157typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *,
158 struct cred *);
159typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
160 bhv_vname_t *, struct cred *);
161typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
162 bhv_vnode_t **, struct cred *);
163typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
164typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
165 int *);
166typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
167 char *, bhv_vnode_t **, struct cred *);
168typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
169 struct cred *);
170typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
171 xfs_off_t, xfs_off_t);
172typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *);
173typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *);
174typedef int (*vop_release_t)(bhv_desc_t *);
175typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t);
176typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t);
177typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
178 struct xfs_iomap *, int *);
179typedef int (*vop_reclaim_t)(bhv_desc_t *);
180typedef int (*vop_attr_get_t)(bhv_desc_t *, const char *, char *, int *,
181 int, struct cred *);
182typedef int (*vop_attr_set_t)(bhv_desc_t *, const char *, char *, int,
183 int, struct cred *);
184typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *,
185 int, struct cred *);
186typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
187 struct attrlist_cursor_kern *, struct cred *);
188typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
189typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
190typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
191typedef int (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
192typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
193 uint64_t, int);
194typedef int (*vop_iflush_t)(bhv_desc_t *, int);
195
196
197typedef struct bhv_vnodeops {
198 bhv_position_t vn_position; /* position within behavior chain */
199 vop_open_t vop_open;
200 vop_read_t vop_read;
201 vop_write_t vop_write;
202 vop_splice_read_t vop_splice_read;
203 vop_splice_write_t vop_splice_write;
204 vop_ioctl_t vop_ioctl;
205 vop_getattr_t vop_getattr;
206 vop_setattr_t vop_setattr;
207 vop_access_t vop_access;
208 vop_lookup_t vop_lookup;
209 vop_create_t vop_create;
210 vop_remove_t vop_remove;
211 vop_link_t vop_link;
212 vop_rename_t vop_rename;
213 vop_mkdir_t vop_mkdir;
214 vop_rmdir_t vop_rmdir;
215 vop_readdir_t vop_readdir;
216 vop_symlink_t vop_symlink;
217 vop_readlink_t vop_readlink;
218 vop_fsync_t vop_fsync;
219 vop_inactive_t vop_inactive;
220 vop_fid2_t vop_fid2;
221 vop_rwlock_t vop_rwlock;
222 vop_rwunlock_t vop_rwunlock;
223 vop_bmap_t vop_bmap;
224 vop_reclaim_t vop_reclaim;
225 vop_attr_get_t vop_attr_get;
226 vop_attr_set_t vop_attr_set;
227 vop_attr_remove_t vop_attr_remove;
228 vop_attr_list_t vop_attr_list;
229 vop_link_removed_t vop_link_removed;
230 vop_vnode_change_t vop_vnode_change;
231 vop_ptossvp_t vop_tosspages;
232 vop_pflushinvalvp_t vop_flushinval_pages;
233 vop_pflushvp_t vop_flush_pages;
234 vop_release_t vop_release;
235 vop_iflush_t vop_iflush;
236} bhv_vnodeops_t;
237
238/*
239 * Virtual node operations, operating from head bhv.
240 */
241#define VNHEAD(vp) ((vp)->v_bh.bh_first)
242#define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
243#define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr)
244#define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \
245 VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
246#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
247 VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
248#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
249 VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
250#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
251 VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
252#define bhv_vop_bmap(vp,of,sz,rw,b,n) \
253 VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n)
254#define bhv_vop_getattr(vp, vap,f,cr) \
255 VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr)
256#define bhv_vop_setattr(vp, vap,f,cr) \
257 VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr)
258#define bhv_vop_access(vp, mode,cr) VOP(vop_access, vp)(VNHEAD(vp), mode,cr)
259#define bhv_vop_lookup(vp,d,vpp,f,rdir,cr) \
260 VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr)
261#define bhv_vop_create(dvp,d,vap,vpp,cr) \
262 VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr)
263#define bhv_vop_remove(dvp,d,cr) VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr)
264#define bhv_vop_link(dvp,fvp,d,cr) VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr)
265#define bhv_vop_rename(fvp,fnm,tdvp,tnm,cr) \
266 VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr)
267#define bhv_vop_mkdir(dp,d,vap,vpp,cr) \
268 VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
269#define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
270#define bhv_vop_readdir(vp,uiop,cr,eofp) \
271 VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp)
272#define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \
273 VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
274#define bhv_vop_readlink(vp,uiop,fl,cr) \
275 VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr)
276#define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e)
277#define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr)
278#define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp))
279#define bhv_vop_fid2(vp,fidp) VOP(vop_fid2, vp)(VNHEAD(vp),fidp)
280#define bhv_vop_rwlock(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
281#define bhv_vop_rwlock_try(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
282#define bhv_vop_rwunlock(vp,i) VOP(vop_rwunlock, vp)(VNHEAD(vp),i)
283#define bhv_vop_frlock(vp,c,fl,flags,offset,fr) \
284 VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr)
285#define bhv_vop_reclaim(vp) VOP(vop_reclaim, vp)(VNHEAD(vp))
286#define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred) \
287 VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred)
288#define bhv_vop_attr_set(vp, name, val, vallen, fl, cred) \
289 VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred)
290#define bhv_vop_attr_remove(vp, name, flags, cred) \
291 VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred)
292#define bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred) \
293 VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred)
294#define bhv_vop_link_removed(vp, dvp, linkzero) \
295 VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero)
296#define bhv_vop_vnode_change(vp, cmd, val) \
297 VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val)
298#define bhv_vop_toss_pages(vp, first, last, fiopt) \
299 VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt)
300#define bhv_vop_flushinval_pages(vp, first, last, fiopt) \
301 VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt)
302#define bhv_vop_flush_pages(vp, first, last, flags, fiopt) \
303 VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt)
304#define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg) \
305 VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg)
306#define bhv_vop_iflush(vp, flags) VOP(vop_iflush, vp)(VNHEAD(vp), flags)
307
308/*
309 * Flags for read/write calls - same values as IRIX 69 * Flags for read/write calls - same values as IRIX
310 */ 70 */
311#define IO_ISAIO 0x00001 /* don't wait for completion */ 71#define IO_ISAIO 0x00001 /* don't wait for completion */
@@ -428,16 +188,19 @@ typedef struct bhv_vattr {
428 188
429extern void vn_init(void); 189extern void vn_init(void);
430extern bhv_vnode_t *vn_initialize(struct inode *); 190extern bhv_vnode_t *vn_initialize(struct inode *);
431extern int vn_revalidate(struct bhv_vnode *); 191extern int vn_revalidate(bhv_vnode_t *);
432extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *); 192extern int __vn_revalidate(bhv_vnode_t *, bhv_vattr_t *);
433extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *); 193extern void vn_revalidate_core(bhv_vnode_t *, bhv_vattr_t *);
434
435extern void vn_iowait(struct bhv_vnode *vp);
436extern void vn_iowake(struct bhv_vnode *vp);
437 194
438extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l); 195/*
196 * Yeah, these don't take vnode anymore at all, all this should be
197 * cleaned up at some point.
198 */
199extern void vn_iowait(struct xfs_inode *ip);
200extern void vn_iowake(struct xfs_inode *ip);
201extern void vn_ioerror(struct xfs_inode *ip, int error, char *f, int l);
439 202
440static inline int vn_count(struct bhv_vnode *vp) 203static inline int vn_count(bhv_vnode_t *vp)
441{ 204{
442 return atomic_read(&vn_to_inode(vp)->i_count); 205 return atomic_read(&vn_to_inode(vp)->i_count);
443} 206}
@@ -445,21 +208,21 @@ static inline int vn_count(struct bhv_vnode *vp)
445/* 208/*
446 * Vnode reference counting functions (and macros for compatibility). 209 * Vnode reference counting functions (and macros for compatibility).
447 */ 210 */
448extern bhv_vnode_t *vn_hold(struct bhv_vnode *); 211extern bhv_vnode_t *vn_hold(bhv_vnode_t *);
449 212
450#if defined(XFS_VNODE_TRACE) 213#if defined(XFS_VNODE_TRACE)
451#define VN_HOLD(vp) \ 214#define VN_HOLD(vp) \
452 ((void)vn_hold(vp), \ 215 ((void)vn_hold(vp), \
453 vn_trace_hold(vp, __FILE__, __LINE__, (inst_t *)__return_address)) 216 vn_trace_hold(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address))
454#define VN_RELE(vp) \ 217#define VN_RELE(vp) \
455 (vn_trace_rele(vp, __FILE__, __LINE__, (inst_t *)__return_address), \ 218 (vn_trace_rele(xfs_vtoi(vp), __FILE__, __LINE__, (inst_t *)__return_address), \
456 iput(vn_to_inode(vp))) 219 iput(vn_to_inode(vp)))
457#else 220#else
458#define VN_HOLD(vp) ((void)vn_hold(vp)) 221#define VN_HOLD(vp) ((void)vn_hold(vp))
459#define VN_RELE(vp) (iput(vn_to_inode(vp))) 222#define VN_RELE(vp) (iput(vn_to_inode(vp)))
460#endif 223#endif
461 224
462static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp) 225static inline bhv_vnode_t *vn_grab(bhv_vnode_t *vp)
463{ 226{
464 struct inode *inode = igrab(vn_to_inode(vp)); 227 struct inode *inode = igrab(vn_to_inode(vp));
465 return inode ? vn_from_inode(inode) : NULL; 228 return inode ? vn_from_inode(inode) : NULL;
@@ -473,43 +236,14 @@ static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp)
473#define VNAME_TO_VNODE(dentry) (vn_from_inode((dentry)->d_inode)) 236#define VNAME_TO_VNODE(dentry) (vn_from_inode((dentry)->d_inode))
474 237
475/* 238/*
476 * Vnode spinlock manipulation.
477 */
478#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock)
479#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s)
480
481STATIC_INLINE void vn_flagset(struct bhv_vnode *vp, uint flag)
482{
483 spin_lock(&vp->v_lock);
484 vp->v_flag |= flag;
485 spin_unlock(&vp->v_lock);
486}
487
488STATIC_INLINE uint vn_flagclr(struct bhv_vnode *vp, uint flag)
489{
490 uint cleared;
491
492 spin_lock(&vp->v_lock);
493 cleared = (vp->v_flag & flag);
494 vp->v_flag &= ~flag;
495 spin_unlock(&vp->v_lock);
496 return cleared;
497}
498
499#define VMODIFY(vp) vn_flagset(vp, VMODIFIED)
500#define VUNMODIFY(vp) vn_flagclr(vp, VMODIFIED)
501#define VTRUNCATE(vp) vn_flagset(vp, VTRUNCATED)
502#define VUNTRUNCATE(vp) vn_flagclr(vp, VTRUNCATED)
503
504/*
505 * Dealing with bad inodes 239 * Dealing with bad inodes
506 */ 240 */
507static inline void vn_mark_bad(struct bhv_vnode *vp) 241static inline void vn_mark_bad(bhv_vnode_t *vp)
508{ 242{
509 make_bad_inode(vn_to_inode(vp)); 243 make_bad_inode(vn_to_inode(vp));
510} 244}
511 245
512static inline int VN_BAD(struct bhv_vnode *vp) 246static inline int VN_BAD(bhv_vnode_t *vp)
513{ 247{
514 return is_bad_inode(vn_to_inode(vp)); 248 return is_bad_inode(vn_to_inode(vp));
515} 249}
@@ -519,18 +253,18 @@ static inline int VN_BAD(struct bhv_vnode *vp)
519 */ 253 */
520static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime) 254static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime)
521{ 255{
522 bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec; 256 bs_atime->tv_sec = vp->i_atime.tv_sec;
523 bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec; 257 bs_atime->tv_nsec = vp->i_atime.tv_nsec;
524} 258}
525 259
526static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts) 260static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts)
527{ 261{
528 *ts = vp->v_inode.i_atime; 262 *ts = vp->i_atime;
529} 263}
530 264
531static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt) 265static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
532{ 266{
533 *tt = vp->v_inode.i_atime.tv_sec; 267 *tt = vp->i_atime.tv_sec;
534} 268}
535 269
536/* 270/*
@@ -540,7 +274,6 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
540#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages) 274#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages)
541#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ 275#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
542 PAGECACHE_TAG_DIRTY) 276 PAGECACHE_TAG_DIRTY)
543#define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED)
544 277
545/* 278/*
546 * Flags to vop_setattr/getattr. 279 * Flags to vop_setattr/getattr.
@@ -572,21 +305,17 @@ static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
572#define VNODE_KTRACE_REF 4 305#define VNODE_KTRACE_REF 4
573#define VNODE_KTRACE_RELE 5 306#define VNODE_KTRACE_RELE 5
574 307
575extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *); 308extern void vn_trace_entry(struct xfs_inode *, const char *, inst_t *);
576extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *); 309extern void vn_trace_exit(struct xfs_inode *, const char *, inst_t *);
577extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *); 310extern void vn_trace_hold(struct xfs_inode *, char *, int, inst_t *);
578extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *); 311extern void vn_trace_ref(struct xfs_inode *, char *, int, inst_t *);
579extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *); 312extern void vn_trace_rele(struct xfs_inode *, char *, int, inst_t *);
580
581#define VN_TRACE(vp) \
582 vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)
583#else 313#else
584#define vn_trace_entry(a,b,c) 314#define vn_trace_entry(a,b,c)
585#define vn_trace_exit(a,b,c) 315#define vn_trace_exit(a,b,c)
586#define vn_trace_hold(a,b,c,d) 316#define vn_trace_hold(a,b,c,d)
587#define vn_trace_ref(a,b,c,d) 317#define vn_trace_ref(a,b,c,d)
588#define vn_trace_rele(a,b,c,d) 318#define vn_trace_rele(a,b,c,d)
589#define VN_TRACE(vp)
590#endif 319#endif
591 320
592#endif /* __XFS_VNODE_H__ */ 321#endif /* __XFS_VNODE_H__ */
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 6ff0f4de1630..b5f91281b707 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -288,45 +288,6 @@ xfs_qm_rele_quotafs_ref(
288} 288}
289 289
290/* 290/*
291 * This is called at mount time from xfs_mountfs to initialize the quotainfo
292 * structure and start the global quota manager (xfs_Gqm) if it hasn't done
293 * so already. Note that the superblock has not been read in yet.
294 */
295void
296xfs_qm_mount_quotainit(
297 xfs_mount_t *mp,
298 uint flags)
299{
300 /*
301 * User, projects or group quotas has to be on.
302 */
303 ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA));
304
305 /*
306 * Initialize the flags in the mount structure. From this point
307 * onwards we look at m_qflags to figure out if quotas's ON/OFF, etc.
308 * Note that we enforce nothing if accounting is off.
309 * ie. XFSMNT_*QUOTA must be ON for XFSMNT_*QUOTAENF.
310 * It isn't necessary to take the quotaoff lock to do this; this is
311 * called from mount.
312 */
313 if (flags & XFSMNT_UQUOTA) {
314 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
315 if (flags & XFSMNT_UQUOTAENF)
316 mp->m_qflags |= XFS_UQUOTA_ENFD;
317 }
318 if (flags & XFSMNT_GQUOTA) {
319 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
320 if (flags & XFSMNT_GQUOTAENF)
321 mp->m_qflags |= XFS_OQUOTA_ENFD;
322 } else if (flags & XFSMNT_PQUOTA) {
323 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
324 if (flags & XFSMNT_PQUOTAENF)
325 mp->m_qflags |= XFS_OQUOTA_ENFD;
326 }
327}
328
329/*
330 * Just destroy the quotainfo structure. 291 * Just destroy the quotainfo structure.
331 */ 292 */
332void 293void
@@ -1039,7 +1000,7 @@ xfs_qm_dqdetach(
1039int 1000int
1040xfs_qm_sync( 1001xfs_qm_sync(
1041 xfs_mount_t *mp, 1002 xfs_mount_t *mp,
1042 short flags) 1003 int flags)
1043{ 1004{
1044 int recl, restarts; 1005 int recl, restarts;
1045 xfs_dquot_t *dqp; 1006 xfs_dquot_t *dqp;
@@ -1717,7 +1678,6 @@ xfs_qm_get_rtblks(
1717 xfs_extnum_t idx; /* extent record index */ 1678 xfs_extnum_t idx; /* extent record index */
1718 xfs_ifork_t *ifp; /* inode fork pointer */ 1679 xfs_ifork_t *ifp; /* inode fork pointer */
1719 xfs_extnum_t nextents; /* number of extent entries */ 1680 xfs_extnum_t nextents; /* number of extent entries */
1720 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
1721 int error; 1681 int error;
1722 1682
1723 ASSERT(XFS_IS_REALTIME_INODE(ip)); 1683 ASSERT(XFS_IS_REALTIME_INODE(ip));
@@ -1728,10 +1688,8 @@ xfs_qm_get_rtblks(
1728 } 1688 }
1729 rtblks = 0; 1689 rtblks = 0;
1730 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 1690 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
1731 for (idx = 0; idx < nextents; idx++) { 1691 for (idx = 0; idx < nextents; idx++)
1732 ep = xfs_iext_get_ext(ifp, idx); 1692 rtblks += xfs_bmbt_get_blockcount(xfs_iext_get_ext(ifp, idx));
1733 rtblks += xfs_bmbt_get_blockcount(ep);
1734 }
1735 *O_rtblks = (xfs_qcnt_t)rtblks; 1693 *O_rtblks = (xfs_qcnt_t)rtblks;
1736 return 0; 1694 return 0;
1737} 1695}
@@ -2459,8 +2417,7 @@ xfs_qm_vop_dqalloc(
2459 lockflags = XFS_ILOCK_EXCL; 2417 lockflags = XFS_ILOCK_EXCL;
2460 xfs_ilock(ip, lockflags); 2418 xfs_ilock(ip, lockflags);
2461 2419
2462 if ((flags & XFS_QMOPT_INHERIT) && 2420 if ((flags & XFS_QMOPT_INHERIT) && XFS_INHERIT_GID(ip))
2463 XFS_INHERIT_GID(ip, XFS_MTOVFS(mp)))
2464 gid = ip->i_d.di_gid; 2421 gid = ip->i_d.di_gid;
2465 2422
2466 /* 2423 /*
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index 689407de0a20..23ccaa5fceaf 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -166,12 +166,11 @@ typedef struct xfs_dquot_acct {
166 166
167extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); 167extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
168extern int xfs_qm_mount_quotas(xfs_mount_t *, int); 168extern int xfs_qm_mount_quotas(xfs_mount_t *, int);
169extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint);
170extern int xfs_qm_quotacheck(xfs_mount_t *); 169extern int xfs_qm_quotacheck(xfs_mount_t *);
171extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); 170extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *);
172extern int xfs_qm_unmount_quotas(xfs_mount_t *); 171extern int xfs_qm_unmount_quotas(xfs_mount_t *);
173extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); 172extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
174extern int xfs_qm_sync(xfs_mount_t *, short); 173extern int xfs_qm_sync(xfs_mount_t *, int);
175 174
176/* dquot stuff */ 175/* dquot stuff */
177extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **); 176extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **);
@@ -199,7 +198,8 @@ extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
199extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); 198extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *);
200 199
201/* system call interface */ 200/* system call interface */
202extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t); 201extern int xfs_qm_quotactl(struct xfs_mount *, int, int,
202 xfs_caddr_t);
203 203
204#ifdef DEBUG 204#ifdef DEBUG
205extern int xfs_qm_internalqcheck(xfs_mount_t *); 205extern int xfs_qm_internalqcheck(xfs_mount_t *);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index d2cdb8a2aad6..97bb32937585 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -48,172 +48,13 @@
48#include "xfs_buf_item.h" 48#include "xfs_buf_item.h"
49#include "xfs_qm.h" 49#include "xfs_qm.h"
50 50
51#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
52#define MNTOPT_NOQUOTA "noquota" /* no quotas */
53#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
54#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
55#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
56#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
57#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
58#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
59#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
60#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
61#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
62#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
63 51
64STATIC int 52STATIC void
65xfs_qm_parseargs( 53xfs_fill_statvfs_from_dquot(
66 struct bhv_desc *bhv,
67 char *options,
68 struct xfs_mount_args *args,
69 int update)
70{
71 size_t length;
72 char *local_options = options;
73 char *this_char;
74 int error;
75 int referenced = update;
76
77 while ((this_char = strsep(&local_options, ",")) != NULL) {
78 length = strlen(this_char);
79 if (local_options)
80 length++;
81
82 if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
83 args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
84 args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
85 referenced = update;
86 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
87 !strcmp(this_char, MNTOPT_UQUOTA) ||
88 !strcmp(this_char, MNTOPT_USRQUOTA)) {
89 args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
90 referenced = 1;
91 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
92 !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
93 args->flags |= XFSMNT_UQUOTA;
94 args->flags &= ~XFSMNT_UQUOTAENF;
95 referenced = 1;
96 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
97 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
98 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
99 referenced = 1;
100 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
101 args->flags |= XFSMNT_PQUOTA;
102 args->flags &= ~XFSMNT_PQUOTAENF;
103 referenced = 1;
104 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
105 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
106 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
107 referenced = 1;
108 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
109 args->flags |= XFSMNT_GQUOTA;
110 args->flags &= ~XFSMNT_GQUOTAENF;
111 referenced = 1;
112 } else {
113 if (local_options)
114 *(local_options-1) = ',';
115 continue;
116 }
117
118 while (length--)
119 *this_char++ = ',';
120 }
121
122 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
123 cmn_err(CE_WARN,
124 "XFS: cannot mount with both project and group quota");
125 return XFS_ERROR(EINVAL);
126 }
127
128 error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
129 if (!error && !referenced)
130 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
131 return error;
132}
133
134STATIC int
135xfs_qm_showargs(
136 struct bhv_desc *bhv,
137 struct seq_file *m)
138{
139 struct bhv_vfs *vfsp = bhvtovfs(bhv);
140 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
141
142 if (mp->m_qflags & XFS_UQUOTA_ACCT) {
143 (mp->m_qflags & XFS_UQUOTA_ENFD) ?
144 seq_puts(m, "," MNTOPT_USRQUOTA) :
145 seq_puts(m, "," MNTOPT_UQUOTANOENF);
146 }
147
148 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
149 (mp->m_qflags & XFS_OQUOTA_ENFD) ?
150 seq_puts(m, "," MNTOPT_PRJQUOTA) :
151 seq_puts(m, "," MNTOPT_PQUOTANOENF);
152 }
153
154 if (mp->m_qflags & XFS_GQUOTA_ACCT) {
155 (mp->m_qflags & XFS_OQUOTA_ENFD) ?
156 seq_puts(m, "," MNTOPT_GRPQUOTA) :
157 seq_puts(m, "," MNTOPT_GQUOTANOENF);
158 }
159
160 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
161 seq_puts(m, "," MNTOPT_NOQUOTA);
162
163 return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
164}
165
166STATIC int
167xfs_qm_mount(
168 struct bhv_desc *bhv,
169 struct xfs_mount_args *args,
170 struct cred *cr)
171{
172 struct bhv_vfs *vfsp = bhvtovfs(bhv);
173 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
174
175 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
176 xfs_qm_mount_quotainit(mp, args->flags);
177 return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
178}
179
180/*
181 * Directory tree accounting is implemented using project quotas, where
182 * the project identifier is inherited from parent directories.
183 * A statvfs (df, etc.) of a directory that is using project quota should
184 * return a statvfs of the project, not the entire filesystem.
185 * This makes such trees appear as if they are filesystems in themselves.
186 */
187STATIC int
188xfs_qm_statvfs(
189 struct bhv_desc *bhv,
190 bhv_statvfs_t *statp, 54 bhv_statvfs_t *statp,
191 struct bhv_vnode *vnode) 55 xfs_disk_dquot_t *dp)
192{ 56{
193 xfs_mount_t *mp;
194 xfs_inode_t *ip;
195 xfs_dquot_t *dqp;
196 xfs_disk_dquot_t *dp;
197 __uint64_t limit; 57 __uint64_t limit;
198 int error;
199
200 error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
201 if (error || !vnode)
202 return error;
203
204 mp = xfs_vfstom(bhvtovfs(bhv));
205 ip = xfs_vtoi(vnode);
206
207 if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
208 return 0;
209 if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
210 return 0;
211 if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
212 return 0;
213
214 if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
215 return 0;
216 dp = &dqp->q_core;
217 58
218 limit = dp->d_blk_softlimit ? 59 limit = dp->d_blk_softlimit ?
219 be64_to_cpu(dp->d_blk_softlimit) : 60 be64_to_cpu(dp->d_blk_softlimit) :
@@ -234,37 +75,35 @@ xfs_qm_statvfs(
234 (statp->f_files > be64_to_cpu(dp->d_icount)) ? 75 (statp->f_files > be64_to_cpu(dp->d_icount)) ?
235 (statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0; 76 (statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0;
236 } 77 }
237
238 xfs_qm_dqput(dqp);
239 return 0;
240} 78}
241 79
242STATIC int 80
243xfs_qm_syncall( 81/*
244 struct bhv_desc *bhv, 82 * Directory tree accounting is implemented using project quotas, where
245 int flags, 83 * the project identifier is inherited from parent directories.
246 cred_t *credp) 84 * A statvfs (df, etc.) of a directory that is using project quota should
85 * return a statvfs of the project, not the entire filesystem.
86 * This makes such trees appear as if they are filesystems in themselves.
87 */
88STATIC void
89xfs_qm_statvfs(
90 xfs_inode_t *ip,
91 bhv_statvfs_t *statp)
247{ 92{
248 struct bhv_vfs *vfsp = bhvtovfs(bhv); 93 xfs_mount_t *mp = ip->i_mount;
249 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 94 xfs_dquot_t *dqp;
250 int error;
251 95
252 /* 96 if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) ||
253 * Get the Quota Manager to flush the dquots. 97 !((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) ==
254 */ 98 (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
255 if (XFS_IS_QUOTA_ON(mp)) { 99 return;
256 if ((error = xfs_qm_sync(mp, flags))) { 100
257 /* 101 if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) {
258 * If we got an IO error, we will be shutting down. 102 xfs_disk_dquot_t *dp = &dqp->q_core;
259 * So, there's nothing more for us to do here. 103
260 */ 104 xfs_fill_statvfs_from_dquot(statp, dp);
261 ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp)); 105 xfs_qm_dqput(dqp);
262 if (XFS_FORCED_SHUTDOWN(mp)) {
263 return XFS_ERROR(error);
264 }
265 }
266 } 106 }
267 return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
268} 107}
269 108
270STATIC int 109STATIC int
@@ -382,7 +221,7 @@ xfs_qm_dqrele_null(
382} 221}
383 222
384 223
385static struct xfs_qmops xfs_qmcore_xfs = { 224struct xfs_qmops xfs_qmcore_xfs = {
386 .xfs_qminit = xfs_qm_newmount, 225 .xfs_qminit = xfs_qm_newmount,
387 .xfs_qmdone = xfs_qm_unmount_quotadestroy, 226 .xfs_qmdone = xfs_qm_unmount_quotadestroy,
388 .xfs_qmmount = xfs_qm_endmount, 227 .xfs_qmmount = xfs_qm_endmount,
@@ -396,36 +235,24 @@ static struct xfs_qmops xfs_qmcore_xfs = {
396 .xfs_dqvoprename = xfs_qm_vop_rename_dqattach, 235 .xfs_dqvoprename = xfs_qm_vop_rename_dqattach,
397 .xfs_dqvopchown = xfs_qm_vop_chown, 236 .xfs_dqvopchown = xfs_qm_vop_chown,
398 .xfs_dqvopchownresv = xfs_qm_vop_chown_reserve, 237 .xfs_dqvopchownresv = xfs_qm_vop_chown_reserve,
238 .xfs_dqstatvfs = xfs_qm_statvfs,
239 .xfs_dqsync = xfs_qm_sync,
240 .xfs_quotactl = xfs_qm_quotactl,
399 .xfs_dqtrxops = &xfs_trans_dquot_ops, 241 .xfs_dqtrxops = &xfs_trans_dquot_ops,
400}; 242};
401 243EXPORT_SYMBOL(xfs_qmcore_xfs);
402struct bhv_module_vfsops xfs_qmops = { {
403 BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
404 .vfs_parseargs = xfs_qm_parseargs,
405 .vfs_showargs = xfs_qm_showargs,
406 .vfs_mount = xfs_qm_mount,
407 .vfs_statvfs = xfs_qm_statvfs,
408 .vfs_sync = xfs_qm_syncall,
409 .vfs_quotactl = xfs_qm_quotactl, },
410};
411
412 244
413void __init 245void __init
414xfs_qm_init(void) 246xfs_qm_init(void)
415{ 247{
416 static char message[] __initdata = 248 printk(KERN_INFO "SGI XFS Quota Management subsystem\n");
417 KERN_INFO "SGI XFS Quota Management subsystem\n";
418
419 printk(message);
420 mutex_init(&xfs_Gqm_lock); 249 mutex_init(&xfs_Gqm_lock);
421 vfs_bhv_set_custom(&xfs_qmops, &xfs_qmcore_xfs);
422 xfs_qm_init_procfs(); 250 xfs_qm_init_procfs();
423} 251}
424 252
425void __exit 253void __exit
426xfs_qm_exit(void) 254xfs_qm_exit(void)
427{ 255{
428 vfs_bhv_clr_custom(&xfs_qmops);
429 xfs_qm_cleanup_procfs(); 256 xfs_qm_cleanup_procfs();
430 if (qm_dqzone) 257 if (qm_dqzone)
431 kmem_zone_destroy(qm_dqzone); 258 kmem_zone_destroy(qm_dqzone);
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 2df67fd913e5..ad5579d4eac4 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -81,18 +81,13 @@ STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *,
81 */ 81 */
82int 82int
83xfs_qm_quotactl( 83xfs_qm_quotactl(
84 struct bhv_desc *bdp, 84 xfs_mount_t *mp,
85 int cmd, 85 int cmd,
86 int id, 86 int id,
87 xfs_caddr_t addr) 87 xfs_caddr_t addr)
88{ 88{
89 xfs_mount_t *mp;
90 bhv_vfs_t *vfsp;
91 int error; 89 int error;
92 90
93 vfsp = bhvtovfs(bdp);
94 mp = XFS_VFSTOM(vfsp);
95
96 ASSERT(addr != NULL || cmd == Q_XQUOTASYNC); 91 ASSERT(addr != NULL || cmd == Q_XQUOTASYNC);
97 92
98 /* 93 /*
@@ -105,7 +100,7 @@ xfs_qm_quotactl(
105 */ 100 */
106 if (XFS_IS_QUOTA_ON(mp)) 101 if (XFS_IS_QUOTA_ON(mp))
107 return XFS_ERROR(EINVAL); 102 return XFS_ERROR(EINVAL);
108 if (vfsp->vfs_flag & VFS_RDONLY) 103 if (mp->m_flags & XFS_MOUNT_RDONLY)
109 return XFS_ERROR(EROFS); 104 return XFS_ERROR(EROFS);
110 return (xfs_qm_scall_trunc_qfiles(mp, 105 return (xfs_qm_scall_trunc_qfiles(mp,
111 xfs_qm_import_qtype_flags(*(uint *)addr))); 106 xfs_qm_import_qtype_flags(*(uint *)addr)));
@@ -121,13 +116,13 @@ xfs_qm_quotactl(
121 * QUOTAON - enabling quota enforcement. 116 * QUOTAON - enabling quota enforcement.
122 * Quota accounting must be turned on at mount time. 117 * Quota accounting must be turned on at mount time.
123 */ 118 */
124 if (vfsp->vfs_flag & VFS_RDONLY) 119 if (mp->m_flags & XFS_MOUNT_RDONLY)
125 return XFS_ERROR(EROFS); 120 return XFS_ERROR(EROFS);
126 return (xfs_qm_scall_quotaon(mp, 121 return (xfs_qm_scall_quotaon(mp,
127 xfs_qm_import_flags(*(uint *)addr))); 122 xfs_qm_import_flags(*(uint *)addr)));
128 123
129 case Q_XQUOTAOFF: 124 case Q_XQUOTAOFF:
130 if (vfsp->vfs_flag & VFS_RDONLY) 125 if (mp->m_flags & XFS_MOUNT_RDONLY)
131 return XFS_ERROR(EROFS); 126 return XFS_ERROR(EROFS);
132 break; 127 break;
133 128
@@ -143,7 +138,7 @@ xfs_qm_quotactl(
143 138
144 switch (cmd) { 139 switch (cmd) {
145 case Q_XQUOTAOFF: 140 case Q_XQUOTAOFF:
146 if (vfsp->vfs_flag & VFS_RDONLY) 141 if (mp->m_flags & XFS_MOUNT_RDONLY)
147 return XFS_ERROR(EROFS); 142 return XFS_ERROR(EROFS);
148 error = xfs_qm_scall_quotaoff(mp, 143 error = xfs_qm_scall_quotaoff(mp,
149 xfs_qm_import_flags(*(uint *)addr), 144 xfs_qm_import_flags(*(uint *)addr),
@@ -164,19 +159,19 @@ xfs_qm_quotactl(
164 break; 159 break;
165 160
166 case Q_XSETQLIM: 161 case Q_XSETQLIM:
167 if (vfsp->vfs_flag & VFS_RDONLY) 162 if (mp->m_flags & XFS_MOUNT_RDONLY)
168 return XFS_ERROR(EROFS); 163 return XFS_ERROR(EROFS);
169 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, 164 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
170 (fs_disk_quota_t *)addr); 165 (fs_disk_quota_t *)addr);
171 break; 166 break;
172 case Q_XSETGQLIM: 167 case Q_XSETGQLIM:
173 if (vfsp->vfs_flag & VFS_RDONLY) 168 if (mp->m_flags & XFS_MOUNT_RDONLY)
174 return XFS_ERROR(EROFS); 169 return XFS_ERROR(EROFS);
175 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, 170 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
176 (fs_disk_quota_t *)addr); 171 (fs_disk_quota_t *)addr);
177 break; 172 break;
178 case Q_XSETPQLIM: 173 case Q_XSETPQLIM:
179 if (vfsp->vfs_flag & VFS_RDONLY) 174 if (mp->m_flags & XFS_MOUNT_RDONLY)
180 return XFS_ERROR(EROFS); 175 return XFS_ERROR(EROFS);
181 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, 176 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
182 (fs_disk_quota_t *)addr); 177 (fs_disk_quota_t *)addr);
diff --git a/fs/xfs/support/move.c b/fs/xfs/support/move.c
deleted file mode 100644
index ac8617ca3909..000000000000
--- a/fs/xfs/support/move.c
+++ /dev/null
@@ -1,51 +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
20/* Read from kernel buffer at src to user/kernel buffer defined
21 * by the uio structure. Advance the pointer in the uio struct
22 * as we go.
23 */
24int
25xfs_uio_read(caddr_t src, size_t len, struct uio *uio)
26{
27 size_t count;
28
29 if (!len || !uio->uio_resid)
30 return 0;
31
32 count = uio->uio_iov->iov_len;
33 if (!count)
34 return 0;
35 if (count > len)
36 count = len;
37
38 if (uio->uio_segflg == UIO_USERSPACE) {
39 if (copy_to_user(uio->uio_iov->iov_base, src, count))
40 return EFAULT;
41 } else {
42 ASSERT(uio->uio_segflg == UIO_SYSSPACE);
43 memcpy(uio->uio_iov->iov_base, src, count);
44 }
45
46 uio->uio_iov->iov_base = (void*)((char*)uio->uio_iov->iov_base + count);
47 uio->uio_iov->iov_len -= count;
48 uio->uio_offset += count;
49 uio->uio_resid -= count;
50 return 0;
51}
diff --git a/fs/xfs/support/move.h b/fs/xfs/support/move.h
deleted file mode 100644
index 324e413deadd..000000000000
--- a/fs/xfs/support/move.h
+++ /dev/null
@@ -1,70 +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 * Portions Copyright (c) 1982, 1986, 1993, 1994
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 */
45#ifndef __XFS_SUPPORT_MOVE_H__
46#define __XFS_SUPPORT_MOVE_H__
47
48#include <linux/uio.h>
49#include <asm/uaccess.h>
50
51/* Segment flag values. */
52enum uio_seg {
53 UIO_USERSPACE, /* from user data space */
54 UIO_SYSSPACE, /* from system space */
55};
56
57struct uio {
58 struct kvec *uio_iov; /* pointer to array of iovecs */
59 int uio_iovcnt; /* number of iovecs in array */
60 xfs_off_t uio_offset; /* offset in file this uio corresponds to */
61 int uio_resid; /* residual i/o count */
62 enum uio_seg uio_segflg; /* see above */
63};
64
65typedef struct uio uio_t;
66typedef struct kvec iovec_t;
67
68extern int xfs_uio_read (caddr_t, size_t, uio_t *);
69
70#endif /* __XFS_SUPPORT_MOVE_H__ */
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 4ca4beb7bb54..5bfb66f33caf 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -32,6 +32,7 @@
32#include "xfs_btree.h" 32#include "xfs_btree.h"
33#include "xfs_acl.h" 33#include "xfs_acl.h"
34#include "xfs_attr.h" 34#include "xfs_attr.h"
35#include "xfs_vnodeops.h"
35 36
36#include <linux/capability.h> 37#include <linux/capability.h>
37#include <linux/posix_acl_xattr.h> 38#include <linux/posix_acl_xattr.h>
@@ -241,7 +242,7 @@ xfs_acl_vget(
241 bhv_vattr_t va; 242 bhv_vattr_t va;
242 243
243 va.va_mask = XFS_AT_MODE; 244 va.va_mask = XFS_AT_MODE;
244 error = bhv_vop_getattr(vp, &va, 0, sys_cred); 245 error = xfs_getattr(xfs_vtoi(vp), &va, 0);
245 if (error) 246 if (error)
246 goto out; 247 goto out;
247 xfs_acl_sync_mode(va.va_mode, xfs_acl); 248 xfs_acl_sync_mode(va.va_mode, xfs_acl);
@@ -265,9 +266,10 @@ xfs_acl_vremove(
265 VN_HOLD(vp); 266 VN_HOLD(vp);
266 error = xfs_acl_allow_set(vp, kind); 267 error = xfs_acl_allow_set(vp, kind);
267 if (!error) { 268 if (!error) {
268 error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT? 269 error = xfs_attr_remove(xfs_vtoi(vp),
270 kind == _ACL_TYPE_DEFAULT?
269 SGI_ACL_DEFAULT: SGI_ACL_FILE, 271 SGI_ACL_DEFAULT: SGI_ACL_FILE,
270 ATTR_ROOT, sys_cred); 272 ATTR_ROOT);
271 if (error == ENOATTR) 273 if (error == ENOATTR)
272 error = 0; /* 'scool */ 274 error = 0; /* 'scool */
273 } 275 }
@@ -370,17 +372,18 @@ xfs_acl_allow_set(
370 bhv_vnode_t *vp, 372 bhv_vnode_t *vp,
371 int kind) 373 int kind)
372{ 374{
375 xfs_inode_t *ip = xfs_vtoi(vp);
373 bhv_vattr_t va; 376 bhv_vattr_t va;
374 int error; 377 int error;
375 378
376 if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) 379 if (vp->i_flags & (S_IMMUTABLE|S_APPEND))
377 return EPERM; 380 return EPERM;
378 if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp)) 381 if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp))
379 return ENOTDIR; 382 return ENOTDIR;
380 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 383 if (vp->i_sb->s_flags & MS_RDONLY)
381 return EROFS; 384 return EROFS;
382 va.va_mask = XFS_AT_UID; 385 va.va_mask = XFS_AT_UID;
383 error = bhv_vop_getattr(vp, &va, 0, NULL); 386 error = xfs_getattr(ip, &va, 0);
384 if (error) 387 if (error)
385 return error; 388 return error;
386 if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) 389 if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
@@ -613,7 +616,8 @@ xfs_acl_get_attr(
613 616
614 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); 617 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1);
615 flags |= ATTR_ROOT; 618 flags |= ATTR_ROOT;
616 *error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ? 619 *error = xfs_attr_get(xfs_vtoi(vp),
620 kind == _ACL_TYPE_ACCESS ?
617 SGI_ACL_FILE : SGI_ACL_DEFAULT, 621 SGI_ACL_FILE : SGI_ACL_DEFAULT,
618 (char *)aclp, &len, flags, sys_cred); 622 (char *)aclp, &len, flags, sys_cred);
619 if (*error || (flags & ATTR_KERNOVAL)) 623 if (*error || (flags & ATTR_KERNOVAL))
@@ -651,9 +655,10 @@ xfs_acl_set_attr(
651 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); 655 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm);
652 } 656 }
653 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); 657 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
654 *error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ? 658 *error = xfs_attr_set(xfs_vtoi(vp),
659 kind == _ACL_TYPE_ACCESS ?
655 SGI_ACL_FILE: SGI_ACL_DEFAULT, 660 SGI_ACL_FILE: SGI_ACL_DEFAULT,
656 (char *)newacl, len, ATTR_ROOT, sys_cred); 661 (char *)newacl, len, ATTR_ROOT);
657 _ACL_FREE(newacl); 662 _ACL_FREE(newacl);
658} 663}
659 664
@@ -675,7 +680,7 @@ xfs_acl_vtoacl(
675 if (!error) { 680 if (!error) {
676 /* Got the ACL, need the mode... */ 681 /* Got the ACL, need the mode... */
677 va.va_mask = XFS_AT_MODE; 682 va.va_mask = XFS_AT_MODE;
678 error = bhv_vop_getattr(vp, &va, 0, sys_cred); 683 error = xfs_getattr(xfs_vtoi(vp), &va, 0);
679 } 684 }
680 685
681 if (error) 686 if (error)
@@ -699,7 +704,7 @@ xfs_acl_vtoacl(
699int 704int
700xfs_acl_inherit( 705xfs_acl_inherit(
701 bhv_vnode_t *vp, 706 bhv_vnode_t *vp,
702 bhv_vattr_t *vap, 707 mode_t mode,
703 xfs_acl_t *pdaclp) 708 xfs_acl_t *pdaclp)
704{ 709{
705 xfs_acl_t *cacl; 710 xfs_acl_t *cacl;
@@ -727,7 +732,7 @@ xfs_acl_inherit(
727 return ENOMEM; 732 return ENOMEM;
728 733
729 memcpy(cacl, pdaclp, sizeof(xfs_acl_t)); 734 memcpy(cacl, pdaclp, sizeof(xfs_acl_t));
730 xfs_acl_filter_mode(vap->va_mode, cacl); 735 xfs_acl_filter_mode(mode, cacl);
731 xfs_acl_setmode(vp, cacl, &basicperms); 736 xfs_acl_setmode(vp, cacl, &basicperms);
732 737
733 /* 738 /*
@@ -773,7 +778,7 @@ xfs_acl_setmode(
773 * mode. The m:: bits take precedence over the g:: bits. 778 * mode. The m:: bits take precedence over the g:: bits.
774 */ 779 */
775 va.va_mask = XFS_AT_MODE; 780 va.va_mask = XFS_AT_MODE;
776 error = bhv_vop_getattr(vp, &va, 0, sys_cred); 781 error = xfs_getattr(xfs_vtoi(vp), &va, 0);
777 if (error) 782 if (error)
778 return error; 783 return error;
779 784
@@ -807,7 +812,7 @@ xfs_acl_setmode(
807 if (gap && nomask) 812 if (gap && nomask)
808 va.va_mode |= gap->ae_perm << 3; 813 va.va_mode |= gap->ae_perm << 3;
809 814
810 return bhv_vop_setattr(vp, &va, 0, sys_cred); 815 return xfs_setattr(xfs_vtoi(vp), &va, 0, sys_cred);
811} 816}
812 817
813/* 818/*
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index f853cf1a6270..34b7d3391299 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -50,7 +50,6 @@ typedef struct xfs_acl {
50#ifdef CONFIG_XFS_POSIX_ACL 50#ifdef CONFIG_XFS_POSIX_ACL
51 51
52struct vattr; 52struct vattr;
53struct bhv_vnode;
54struct xfs_inode; 53struct xfs_inode;
55 54
56extern struct kmem_zone *xfs_acl_zone; 55extern struct kmem_zone *xfs_acl_zone;
@@ -58,20 +57,20 @@ extern struct kmem_zone *xfs_acl_zone;
58 (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name)) 57 (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
59#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) 58#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
60 59
61extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *); 60extern int xfs_acl_inherit(bhv_vnode_t *, mode_t mode, xfs_acl_t *);
62extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); 61extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
63extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *); 62extern int xfs_acl_vtoacl(bhv_vnode_t *, xfs_acl_t *, xfs_acl_t *);
64extern int xfs_acl_vhasacl_access(struct bhv_vnode *); 63extern int xfs_acl_vhasacl_access(bhv_vnode_t *);
65extern int xfs_acl_vhasacl_default(struct bhv_vnode *); 64extern int xfs_acl_vhasacl_default(bhv_vnode_t *);
66extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int); 65extern int xfs_acl_vset(bhv_vnode_t *, void *, size_t, int);
67extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int); 66extern int xfs_acl_vget(bhv_vnode_t *, void *, size_t, int);
68extern int xfs_acl_vremove(struct bhv_vnode *, int); 67extern int xfs_acl_vremove(bhv_vnode_t *, int);
69 68
70#define _ACL_TYPE_ACCESS 1 69#define _ACL_TYPE_ACCESS 1
71#define _ACL_TYPE_DEFAULT 2 70#define _ACL_TYPE_DEFAULT 2
72#define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE)) 71#define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE))
73 72
74#define _ACL_INHERIT(c,v,d) (xfs_acl_inherit(c,v,d)) 73#define _ACL_INHERIT(c,m,d) (xfs_acl_inherit(c,m,d))
75#define _ACL_GET_ACCESS(pv,pa) (xfs_acl_vtoacl(pv,pa,NULL) == 0) 74#define _ACL_GET_ACCESS(pv,pa) (xfs_acl_vtoacl(pv,pa,NULL) == 0)
76#define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0) 75#define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0)
77#define _ACL_ACCESS_EXISTS xfs_acl_vhasacl_access 76#define _ACL_ACCESS_EXISTS xfs_acl_vhasacl_access
@@ -91,7 +90,7 @@ extern int xfs_acl_vremove(struct bhv_vnode *, int);
91#define xfs_acl_vhasacl_default(v) (0) 90#define xfs_acl_vhasacl_default(v) (0)
92#define _ACL_ALLOC(a) (1) /* successfully allocate nothing */ 91#define _ACL_ALLOC(a) (1) /* successfully allocate nothing */
93#define _ACL_FREE(a) ((void)0) 92#define _ACL_FREE(a) ((void)0)
94#define _ACL_INHERIT(c,v,d) (0) 93#define _ACL_INHERIT(c,m,d) (0)
95#define _ACL_GET_ACCESS(pv,pa) (0) 94#define _ACL_GET_ACCESS(pv,pa) (0)
96#define _ACL_GET_DEFAULT(pv,pd) (0) 95#define _ACL_GET_DEFAULT(pv,pd) (0)
97#define _ACL_ACCESS_EXISTS (NULL) 96#define _ACL_ACCESS_EXISTS (NULL)
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 51c09c114a20..9381b0360c4b 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -197,6 +197,10 @@ typedef struct xfs_perag
197#endif 197#endif
198 xfs_perag_busy_t *pagb_list; /* unstable blocks */ 198 xfs_perag_busy_t *pagb_list; /* unstable blocks */
199 atomic_t pagf_fstrms; /* # of filestreams active in this AG */ 199 atomic_t pagf_fstrms; /* # of filestreams active in this AG */
200
201 int pag_ici_init; /* incore inode cache initialised */
202 rwlock_t pag_ici_lock; /* incore inode lock */
203 struct radix_tree_root pag_ici_root; /* incore inode cache root */
200} xfs_perag_t; 204} xfs_perag_t;
201 205
202#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) 206#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 7ce44a7b88a2..93fa64dd1be6 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -49,6 +49,7 @@
49#include "xfs_trans_space.h" 49#include "xfs_trans_space.h"
50#include "xfs_acl.h" 50#include "xfs_acl.h"
51#include "xfs_rw.h" 51#include "xfs_rw.h"
52#include "xfs_vnodeops.h"
52 53
53/* 54/*
54 * xfs_attr.c 55 * xfs_attr.c
@@ -156,10 +157,14 @@ xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen,
156} 157}
157 158
158int 159int
159xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp, 160xfs_attr_get(
160 int flags, struct cred *cred) 161 xfs_inode_t *ip,
162 const char *name,
163 char *value,
164 int *valuelenp,
165 int flags,
166 cred_t *cred)
161{ 167{
162 xfs_inode_t *ip = XFS_BHVTOI(bdp);
163 int error, namelen; 168 int error, namelen;
164 169
165 XFS_STATS_INC(xs_attr_get); 170 XFS_STATS_INC(xs_attr_get);
@@ -417,10 +422,13 @@ out:
417} 422}
418 423
419int 424int
420xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int flags, 425xfs_attr_set(
421 struct cred *cred) 426 xfs_inode_t *dp,
427 const char *name,
428 char *value,
429 int valuelen,
430 int flags)
422{ 431{
423 xfs_inode_t *dp;
424 int namelen; 432 int namelen;
425 433
426 namelen = strlen(name); 434 namelen = strlen(name);
@@ -429,7 +437,6 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f
429 437
430 XFS_STATS_INC(xs_attr_set); 438 XFS_STATS_INC(xs_attr_set);
431 439
432 dp = XFS_BHVTOI(bdp);
433 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 440 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
434 return (EIO); 441 return (EIO);
435 442
@@ -563,10 +570,12 @@ out:
563} 570}
564 571
565int 572int
566xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred) 573xfs_attr_remove(
574 xfs_inode_t *dp,
575 const char *name,
576 int flags)
567{ 577{
568 xfs_inode_t *dp; 578 int namelen;
569 int namelen;
570 579
571 namelen = strlen(name); 580 namelen = strlen(name);
572 if (namelen >= MAXNAMELEN) 581 if (namelen >= MAXNAMELEN)
@@ -574,7 +583,6 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
574 583
575 XFS_STATS_INC(xs_attr_remove); 584 XFS_STATS_INC(xs_attr_remove);
576 585
577 dp = XFS_BHVTOI(bdp);
578 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 586 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
579 return (EIO); 587 return (EIO);
580 588
@@ -702,11 +710,14 @@ xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp,
702 * success. 710 * success.
703 */ 711 */
704int 712int
705xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, 713xfs_attr_list(
706 attrlist_cursor_kern_t *cursor, struct cred *cred) 714 xfs_inode_t *dp,
715 char *buffer,
716 int bufsize,
717 int flags,
718 attrlist_cursor_kern_t *cursor)
707{ 719{
708 xfs_attr_list_context_t context; 720 xfs_attr_list_context_t context;
709 xfs_inode_t *dp;
710 int error; 721 int error;
711 722
712 XFS_STATS_INC(xs_attr_list); 723 XFS_STATS_INC(xs_attr_list);
@@ -731,7 +742,7 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
731 /* 742 /*
732 * Initialize the output buffer. 743 * Initialize the output buffer.
733 */ 744 */
734 context.dp = dp = XFS_BHVTOI(bdp); 745 context.dp = dp;
735 context.cursor = cursor; 746 context.cursor = cursor;
736 context.count = 0; 747 context.count = 0;
737 context.dupcnt = 0; 748 context.dupcnt = 0;
@@ -2502,7 +2513,7 @@ STATIC int
2502attr_generic_set( 2513attr_generic_set(
2503 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) 2514 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2504{ 2515{
2505 return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL); 2516 return -xfs_attr_set(xfs_vtoi(vp), name, data, size, xflags);
2506} 2517}
2507 2518
2508STATIC int 2519STATIC int
@@ -2511,7 +2522,8 @@ attr_generic_get(
2511{ 2522{
2512 int error, asize = size; 2523 int error, asize = size;
2513 2524
2514 error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL); 2525 error = xfs_attr_get(xfs_vtoi(vp), name, data,
2526 &asize, xflags, NULL);
2515 if (!error) 2527 if (!error)
2516 return asize; 2528 return asize;
2517 return -error; 2529 return -error;
@@ -2521,7 +2533,7 @@ STATIC int
2521attr_generic_remove( 2533attr_generic_remove(
2522 bhv_vnode_t *vp, char *name, int xflags) 2534 bhv_vnode_t *vp, char *name, int xflags)
2523{ 2535{
2524 return -bhv_vop_attr_remove(vp, name, xflags, NULL); 2536 return -xfs_attr_remove(xfs_vtoi(vp), name, xflags);
2525} 2537}
2526 2538
2527STATIC int 2539STATIC int
@@ -2576,7 +2588,7 @@ attr_generic_list(
2576 attrlist_cursor_kern_t cursor = { 0 }; 2588 attrlist_cursor_kern_t cursor = { 0 };
2577 int error; 2589 int error;
2578 2590
2579 error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL); 2591 error = xfs_attr_list(xfs_vtoi(vp), data, size, xflags, &cursor);
2580 if (error > 0) 2592 if (error > 0)
2581 return -error; 2593 return -error;
2582 *result = -error; 2594 *result = -error;
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index 783977d3ea71..786eba3121c4 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -36,14 +36,13 @@
36 *========================================================================*/ 36 *========================================================================*/
37 37
38struct cred; 38struct cred;
39struct bhv_vnode;
40struct xfs_attr_list_context; 39struct xfs_attr_list_context;
41 40
42typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int); 41typedef int (*attrset_t)(bhv_vnode_t *, char *, void *, size_t, int);
43typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int); 42typedef int (*attrget_t)(bhv_vnode_t *, char *, void *, size_t, int);
44typedef int (*attrremove_t)(struct bhv_vnode *, char *, int); 43typedef int (*attrremove_t)(bhv_vnode_t *, char *, int);
45typedef int (*attrexists_t)(struct bhv_vnode *); 44typedef int (*attrexists_t)(bhv_vnode_t *);
46typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *); 45typedef int (*attrcapable_t)(bhv_vnode_t *, struct cred *);
47 46
48typedef struct attrnames { 47typedef struct attrnames {
49 char * attr_name; 48 char * attr_name;
@@ -64,7 +63,7 @@ extern struct attrnames attr_trusted;
64extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; 63extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
65 64
66extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); 65extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
67extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *); 66extern int attr_generic_list(bhv_vnode_t *, void *, size_t, int, ssize_t *);
68 67
69#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ 68#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
70#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ 69#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
@@ -159,12 +158,8 @@ struct xfs_da_args;
159/* 158/*
160 * Overall external interface routines. 159 * Overall external interface routines.
161 */ 160 */
162int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *);
163int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *);
164int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int); 161int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int);
165int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *);
166int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int); 162int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int);
167int xfs_attr_list(bhv_desc_t *, char *, int, int, struct attrlist_cursor_kern *, struct cred *);
168int xfs_attr_list_int(struct xfs_attr_list_context *); 163int xfs_attr_list_int(struct xfs_attr_list_context *);
169int xfs_attr_inactive(struct xfs_inode *dp); 164int xfs_attr_inactive(struct xfs_inode *dp);
170 165
diff --git a/fs/xfs/xfs_behavior.c b/fs/xfs/xfs_behavior.c
deleted file mode 100644
index 0dc17219d412..000000000000
--- a/fs/xfs/xfs_behavior.c
+++ /dev/null
@@ -1,183 +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
20/*
21 * Source file used to associate/disassociate behaviors with virtualized
22 * objects. See xfs_behavior.h for more information about behaviors, etc.
23 *
24 * The implementation is split between functions in this file and macros
25 * in xfs_behavior.h.
26 */
27
28/*
29 * Insert a new behavior descriptor into a behavior chain.
30 *
31 * The behavior chain is ordered based on the 'position' number which
32 * lives in the first field of the ops vector (higher numbers first).
33 *
34 * Attempts to insert duplicate ops result in an EINVAL return code.
35 * Otherwise, return 0 to indicate success.
36 */
37int
38bhv_insert(bhv_head_t *bhp, bhv_desc_t *bdp)
39{
40 bhv_desc_t *curdesc, *prev;
41 int position;
42
43 /*
44 * Validate the position value of the new behavior.
45 */
46 position = BHV_POSITION(bdp);
47 ASSERT(position >= BHV_POSITION_BASE && position <= BHV_POSITION_TOP);
48
49 /*
50 * Find location to insert behavior. Check for duplicates.
51 */
52 prev = NULL;
53 for (curdesc = bhp->bh_first;
54 curdesc != NULL;
55 curdesc = curdesc->bd_next) {
56
57 /* Check for duplication. */
58 if (curdesc->bd_ops == bdp->bd_ops) {
59 ASSERT(0);
60 return EINVAL;
61 }
62
63 /* Find correct position */
64 if (position >= BHV_POSITION(curdesc)) {
65 ASSERT(position != BHV_POSITION(curdesc));
66 break; /* found it */
67 }
68
69 prev = curdesc;
70 }
71
72 if (prev == NULL) {
73 /* insert at front of chain */
74 bdp->bd_next = bhp->bh_first;
75 bhp->bh_first = bdp;
76 } else {
77 /* insert after prev */
78 bdp->bd_next = prev->bd_next;
79 prev->bd_next = bdp;
80 }
81
82 return 0;
83}
84
85/*
86 * Remove a behavior descriptor from a position in a behavior chain;
87 * the position is guaranteed not to be the first position.
88 * Should only be called by the bhv_remove() macro.
89 */
90void
91bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
92{
93 bhv_desc_t *curdesc, *prev;
94
95 ASSERT(bhp->bh_first != NULL);
96 ASSERT(bhp->bh_first->bd_next != NULL);
97
98 prev = bhp->bh_first;
99 for (curdesc = bhp->bh_first->bd_next;
100 curdesc != NULL;
101 curdesc = curdesc->bd_next) {
102
103 if (curdesc == bdp)
104 break; /* found it */
105 prev = curdesc;
106 }
107
108 ASSERT(curdesc == bdp);
109 prev->bd_next = bdp->bd_next; /* remove from after prev */
110}
111
112/*
113 * Looks for the first behavior within a specified range of positions.
114 * Return the associated behavior descriptor. Or NULL, if none found.
115 */
116bhv_desc_t *
117bhv_lookup_range(bhv_head_t *bhp, int low, int high)
118{
119 bhv_desc_t *curdesc;
120
121 for (curdesc = bhp->bh_first;
122 curdesc != NULL;
123 curdesc = curdesc->bd_next) {
124
125 int position = BHV_POSITION(curdesc);
126
127 if (position <= high) {
128 if (position >= low)
129 return curdesc;
130 return NULL;
131 }
132 }
133
134 return NULL;
135}
136
137/*
138 * Return the base behavior in the chain, or NULL if the chain
139 * is empty.
140 *
141 * The caller has not read locked the behavior chain, so acquire the
142 * lock before traversing the chain.
143 */
144bhv_desc_t *
145bhv_base(bhv_head_t *bhp)
146{
147 bhv_desc_t *curdesc;
148
149 for (curdesc = bhp->bh_first;
150 curdesc != NULL;
151 curdesc = curdesc->bd_next) {
152
153 if (curdesc->bd_next == NULL) {
154 return curdesc;
155 }
156 }
157
158 return NULL;
159}
160
161void
162bhv_head_init(
163 bhv_head_t *bhp,
164 char *name)
165{
166 bhp->bh_first = NULL;
167}
168
169void
170bhv_insert_initial(
171 bhv_head_t *bhp,
172 bhv_desc_t *bdp)
173{
174 ASSERT(bhp->bh_first == NULL);
175 (bhp)->bh_first = bdp;
176}
177
178void
179bhv_head_destroy(
180 bhv_head_t *bhp)
181{
182 ASSERT(bhp->bh_first == NULL);
183}
diff --git a/fs/xfs/xfs_behavior.h b/fs/xfs/xfs_behavior.h
deleted file mode 100644
index e7ca1fed955a..000000000000
--- a/fs/xfs/xfs_behavior.h
+++ /dev/null
@@ -1,185 +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#ifndef __XFS_BEHAVIOR_H__
19#define __XFS_BEHAVIOR_H__
20
21/*
22 * Header file used to associate behaviors with virtualized objects.
23 *
24 * A virtualized object is an internal, virtualized representation of
25 * OS entities such as persistent files, processes, or sockets. Examples
26 * of virtualized objects include vnodes, vprocs, and vsockets. Often
27 * a virtualized object is referred to simply as an "object."
28 *
29 * A behavior is essentially an implementation layer associated with
30 * an object. Multiple behaviors for an object are chained together,
31 * the order of chaining determining the order of invocation. Each
32 * behavior of a given object implements the same set of interfaces
33 * (e.g., the VOP interfaces).
34 *
35 * Behaviors may be dynamically inserted into an object's behavior chain,
36 * such that the addition is transparent to consumers that already have
37 * references to the object. Typically, a given behavior will be inserted
38 * at a particular location in the behavior chain. Insertion of new
39 * behaviors is synchronized with operations-in-progress (oip's) so that
40 * the oip's always see a consistent view of the chain.
41 *
42 * The term "interposition" is used to refer to the act of inserting
43 * a behavior such that it interposes on (i.e., is inserted in front
44 * of) a particular other behavior. A key example of this is when a
45 * system implementing distributed single system image wishes to
46 * interpose a distribution layer (providing distributed coherency)
47 * in front of an object that is otherwise only accessed locally.
48 *
49 * Note that the traditional vnode/inode combination is simply a virtualized
50 * object that has exactly one associated behavior.
51 *
52 * Behavior synchronization is logic which is necessary under certain
53 * circumstances that there is no conflict between ongoing operations
54 * traversing the behavior chain and those dynamically modifying the
55 * behavior chain. Because behavior synchronization adds extra overhead
56 * to virtual operation invocation, we want to restrict, as much as
57 * we can, the requirement for this extra code, to those situations
58 * in which it is truly necessary.
59 *
60 * Behavior synchronization is needed whenever there's at least one class
61 * of object in the system for which:
62 * 1) multiple behaviors for a given object are supported,
63 * -- AND --
64 * 2a) insertion of a new behavior can happen dynamically at any time during
65 * the life of an active object,
66 * -- AND --
67 * 3a) insertion of a new behavior needs to synchronize with existing
68 * ops-in-progress.
69 * -- OR --
70 * 3b) multiple different behaviors can be dynamically inserted at
71 * any time during the life of an active object
72 * -- OR --
73 * 3c) removal of a behavior can occur at any time during the life of
74 * an active object.
75 * -- OR --
76 * 2b) removal of a behavior can occur at any time during the life of an
77 * active object
78 *
79 */
80
81/*
82 * Behavior head. Head of the chain of behaviors.
83 * Contained within each virtualized object data structure.
84 */
85typedef struct bhv_head {
86 struct bhv_desc *bh_first; /* first behavior in chain */
87} bhv_head_t;
88
89/*
90 * Behavior descriptor. Descriptor associated with each behavior.
91 * Contained within the behavior's private data structure.
92 */
93typedef struct bhv_desc {
94 void *bd_pdata; /* private data for this behavior */
95 void *bd_vobj; /* virtual object associated with */
96 void *bd_ops; /* ops for this behavior */
97 struct bhv_desc *bd_next; /* next behavior in chain */
98} bhv_desc_t;
99
100/*
101 * Behavior identity field. A behavior's identity determines the position
102 * where it lives within a behavior chain, and it's always the first field
103 * of the behavior's ops vector. The optional id field further identifies the
104 * subsystem responsible for the behavior.
105 */
106typedef struct bhv_identity {
107 __u16 bi_id; /* owning subsystem id */
108 __u16 bi_position; /* position in chain */
109} bhv_identity_t;
110
111typedef bhv_identity_t bhv_position_t;
112
113#define BHV_IDENTITY_INIT(id,pos) {id, pos}
114#define BHV_IDENTITY_INIT_POSITION(pos) BHV_IDENTITY_INIT(0, pos)
115
116/*
117 * Define boundaries of position values.
118 */
119#define BHV_POSITION_INVALID 0 /* invalid position number */
120#define BHV_POSITION_BASE 1 /* base (last) implementation layer */
121#define BHV_POSITION_TOP 63 /* top (first) implementation layer */
122
123/*
124 * Plumbing macros.
125 */
126#define BHV_HEAD_FIRST(bhp) (ASSERT((bhp)->bh_first), (bhp)->bh_first)
127#define BHV_NEXT(bdp) (ASSERT((bdp)->bd_next), (bdp)->bd_next)
128#define BHV_NEXTNULL(bdp) ((bdp)->bd_next)
129#define BHV_VOBJ(bdp) (ASSERT((bdp)->bd_vobj), (bdp)->bd_vobj)
130#define BHV_VOBJNULL(bdp) ((bdp)->bd_vobj)
131#define BHV_PDATA(bdp) (bdp)->bd_pdata
132#define BHV_OPS(bdp) (bdp)->bd_ops
133#define BHV_IDENTITY(bdp) ((bhv_identity_t *)(bdp)->bd_ops)
134#define BHV_POSITION(bdp) (BHV_IDENTITY(bdp)->bi_position)
135
136extern void bhv_head_init(bhv_head_t *, char *);
137extern void bhv_head_destroy(bhv_head_t *);
138extern int bhv_insert(bhv_head_t *, bhv_desc_t *);
139extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *);
140
141/*
142 * Initialize a new behavior descriptor.
143 * Arguments:
144 * bdp - pointer to behavior descriptor
145 * pdata - pointer to behavior's private data
146 * vobj - pointer to associated virtual object
147 * ops - pointer to ops for this behavior
148 */
149#define bhv_desc_init(bdp, pdata, vobj, ops) \
150 { \
151 (bdp)->bd_pdata = pdata; \
152 (bdp)->bd_vobj = vobj; \
153 (bdp)->bd_ops = ops; \
154 (bdp)->bd_next = NULL; \
155 }
156
157/*
158 * Remove a behavior descriptor from a behavior chain.
159 */
160#define bhv_remove(bhp, bdp) \
161 { \
162 if ((bhp)->bh_first == (bdp)) { \
163 /* \
164 * Remove from front of chain. \
165 * Atomic wrt oip's. \
166 */ \
167 (bhp)->bh_first = (bdp)->bd_next; \
168 } else { \
169 /* remove from non-front of chain */ \
170 bhv_remove_not_first(bhp, bdp); \
171 } \
172 (bdp)->bd_vobj = NULL; \
173 }
174
175/*
176 * Behavior module prototypes.
177 */
178extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp);
179extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high);
180extern bhv_desc_t * bhv_base(bhv_head_t *bhp);
181
182/* No bhv locking on Linux */
183#define bhv_base_unlocked bhv_base
184
185#endif /* __XFS_BEHAVIOR_H__ */
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 94b5c5fe2681..2e9b34b7344b 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -53,6 +53,7 @@
53#include "xfs_trans_space.h" 53#include "xfs_trans_space.h"
54#include "xfs_buf_item.h" 54#include "xfs_buf_item.h"
55#include "xfs_filestream.h" 55#include "xfs_filestream.h"
56#include "xfs_vnodeops.h"
56 57
57 58
58#ifdef DEBUG 59#ifdef DEBUG
@@ -248,7 +249,7 @@ xfs_bmap_local_to_extents(
248 * Else, *lastxp will be set to the index of the found 249 * Else, *lastxp will be set to the index of the found
249 * entry; *gotp will contain the entry. 250 * entry; *gotp will contain the entry.
250 */ 251 */
251STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ 252STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
252xfs_bmap_search_extents( 253xfs_bmap_search_extents(
253 xfs_inode_t *ip, /* incore inode pointer */ 254 xfs_inode_t *ip, /* incore inode pointer */
254 xfs_fileoff_t bno, /* block number searched for */ 255 xfs_fileoff_t bno, /* block number searched for */
@@ -273,21 +274,6 @@ xfs_bmap_isaeof(
273 274
274#ifdef XFS_BMAP_TRACE 275#ifdef XFS_BMAP_TRACE
275/* 276/*
276 * Add a bmap trace buffer entry. Base routine for the others.
277 */
278STATIC void
279xfs_bmap_trace_addentry(
280 int opcode, /* operation */
281 const char *fname, /* function name */
282 char *desc, /* operation description */
283 xfs_inode_t *ip, /* incore inode pointer */
284 xfs_extnum_t idx, /* index of entry(ies) */
285 xfs_extnum_t cnt, /* count of entries, 1 or 2 */
286 xfs_bmbt_rec_t *r1, /* first record */
287 xfs_bmbt_rec_t *r2, /* second record or null */
288 int whichfork); /* data or attr fork */
289
290/*
291 * Add bmap trace entry prior to a call to xfs_iext_remove. 277 * Add bmap trace entry prior to a call to xfs_iext_remove.
292 */ 278 */
293STATIC void 279STATIC void
@@ -714,7 +700,7 @@ xfs_bmap_add_extent_delay_real(
714{ 700{
715 xfs_btree_cur_t *cur; /* btree cursor */ 701 xfs_btree_cur_t *cur; /* btree cursor */
716 int diff; /* temp value */ 702 int diff; /* temp value */
717 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 703 xfs_bmbt_rec_host_t *ep; /* extent entry for idx */
718 int error; /* error return value */ 704 int error; /* error return value */
719 int i; /* temp state */ 705 int i; /* temp state */
720 xfs_ifork_t *ifp; /* inode fork pointer */ 706 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -1270,7 +1256,7 @@ xfs_bmap_add_extent_unwritten_real(
1270 xfs_extdelta_t *delta) /* Change made to incore extents */ 1256 xfs_extdelta_t *delta) /* Change made to incore extents */
1271{ 1257{
1272 xfs_btree_cur_t *cur; /* btree cursor */ 1258 xfs_btree_cur_t *cur; /* btree cursor */
1273 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 1259 xfs_bmbt_rec_host_t *ep; /* extent entry for idx */
1274 int error; /* error return value */ 1260 int error; /* error return value */
1275 int i; /* temp state */ 1261 int i; /* temp state */
1276 xfs_ifork_t *ifp; /* inode fork pointer */ 1262 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -1823,7 +1809,7 @@ xfs_bmap_add_extent_hole_delay(
1823 xfs_extdelta_t *delta, /* Change made to incore extents */ 1809 xfs_extdelta_t *delta, /* Change made to incore extents */
1824 int rsvd) /* OK to allocate reserved blocks */ 1810 int rsvd) /* OK to allocate reserved blocks */
1825{ 1811{
1826 xfs_bmbt_rec_t *ep; /* extent record for idx */ 1812 xfs_bmbt_rec_host_t *ep; /* extent record for idx */
1827 xfs_ifork_t *ifp; /* inode fork pointer */ 1813 xfs_ifork_t *ifp; /* inode fork pointer */
1828 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 1814 xfs_bmbt_irec_t left; /* left neighbor extent entry */
1829 xfs_filblks_t newlen=0; /* new indirect size */ 1815 xfs_filblks_t newlen=0; /* new indirect size */
@@ -2012,7 +1998,7 @@ xfs_bmap_add_extent_hole_real(
2012 xfs_extdelta_t *delta, /* Change made to incore extents */ 1998 xfs_extdelta_t *delta, /* Change made to incore extents */
2013 int whichfork) /* data or attr fork */ 1999 int whichfork) /* data or attr fork */
2014{ 2000{
2015 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ 2001 xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */
2016 int error; /* error return value */ 2002 int error; /* error return value */
2017 int i; /* temp state */ 2003 int i; /* temp state */
2018 xfs_ifork_t *ifp; /* inode fork pointer */ 2004 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -3070,7 +3056,7 @@ xfs_bmap_del_extent(
3070 xfs_fileoff_t del_endoff; /* first offset past del */ 3056 xfs_fileoff_t del_endoff; /* first offset past del */
3071 int delay; /* current block is delayed allocated */ 3057 int delay; /* current block is delayed allocated */
3072 int do_fx; /* free extent at end of routine */ 3058 int do_fx; /* free extent at end of routine */
3073 xfs_bmbt_rec_t *ep; /* current extent entry pointer */ 3059 xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */
3074 int error; /* error return value */ 3060 int error; /* error return value */
3075 int flags; /* inode logging flags */ 3061 int flags; /* inode logging flags */
3076 xfs_bmbt_irec_t got; /* current extent entry */ 3062 xfs_bmbt_irec_t got; /* current extent entry */
@@ -3418,7 +3404,7 @@ xfs_bmap_extents_to_btree(
3418 xfs_bmbt_rec_t *arp; /* child record pointer */ 3404 xfs_bmbt_rec_t *arp; /* child record pointer */
3419 xfs_bmbt_block_t *block; /* btree root block */ 3405 xfs_bmbt_block_t *block; /* btree root block */
3420 xfs_btree_cur_t *cur; /* bmap btree cursor */ 3406 xfs_btree_cur_t *cur; /* bmap btree cursor */
3421 xfs_bmbt_rec_t *ep; /* extent record pointer */ 3407 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
3422 int error; /* error return value */ 3408 int error; /* error return value */
3423 xfs_extnum_t i, cnt; /* extent record index */ 3409 xfs_extnum_t i, cnt; /* extent record index */
3424 xfs_ifork_t *ifp; /* inode fork pointer */ 3410 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -3507,8 +3493,8 @@ xfs_bmap_extents_to_btree(
3507 for (cnt = i = 0; i < nextents; i++) { 3493 for (cnt = i = 0; i < nextents; i++) {
3508 ep = xfs_iext_get_ext(ifp, i); 3494 ep = xfs_iext_get_ext(ifp, i);
3509 if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { 3495 if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) {
3510 arp->l0 = INT_GET(ep->l0, ARCH_CONVERT); 3496 arp->l0 = cpu_to_be64(ep->l0);
3511 arp->l1 = INT_GET(ep->l1, ARCH_CONVERT); 3497 arp->l1 = cpu_to_be64(ep->l1);
3512 arp++; cnt++; 3498 arp++; cnt++;
3513 } 3499 }
3514 } 3500 }
@@ -3590,7 +3576,7 @@ xfs_bmap_local_to_extents(
3590 if (ifp->if_bytes) { 3576 if (ifp->if_bytes) {
3591 xfs_alloc_arg_t args; /* allocation arguments */ 3577 xfs_alloc_arg_t args; /* allocation arguments */
3592 xfs_buf_t *bp; /* buffer for extent block */ 3578 xfs_buf_t *bp; /* buffer for extent block */
3593 xfs_bmbt_rec_t *ep; /* extent record pointer */ 3579 xfs_bmbt_rec_host_t *ep;/* extent record pointer */
3594 3580
3595 args.tp = tp; 3581 args.tp = tp;
3596 args.mp = ip->i_mount; 3582 args.mp = ip->i_mount;
@@ -3655,7 +3641,7 @@ done:
3655 * entry (null if none). Else, *lastxp will be set to the index 3641 * entry (null if none). Else, *lastxp will be set to the index
3656 * of the found entry; *gotp will contain the entry. 3642 * of the found entry; *gotp will contain the entry.
3657 */ 3643 */
3658xfs_bmbt_rec_t * /* pointer to found extent entry */ 3644xfs_bmbt_rec_host_t * /* pointer to found extent entry */
3659xfs_bmap_search_multi_extents( 3645xfs_bmap_search_multi_extents(
3660 xfs_ifork_t *ifp, /* inode fork pointer */ 3646 xfs_ifork_t *ifp, /* inode fork pointer */
3661 xfs_fileoff_t bno, /* block number searched for */ 3647 xfs_fileoff_t bno, /* block number searched for */
@@ -3664,7 +3650,7 @@ xfs_bmap_search_multi_extents(
3664 xfs_bmbt_irec_t *gotp, /* out: extent entry found */ 3650 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
3665 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ 3651 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
3666{ 3652{
3667 xfs_bmbt_rec_t *ep; /* extent record pointer */ 3653 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
3668 xfs_extnum_t lastx; /* last extent index */ 3654 xfs_extnum_t lastx; /* last extent index */
3669 3655
3670 /* 3656 /*
@@ -3706,7 +3692,7 @@ xfs_bmap_search_multi_extents(
3706 * Else, *lastxp will be set to the index of the found 3692 * Else, *lastxp will be set to the index of the found
3707 * entry; *gotp will contain the entry. 3693 * entry; *gotp will contain the entry.
3708 */ 3694 */
3709STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ 3695STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */
3710xfs_bmap_search_extents( 3696xfs_bmap_search_extents(
3711 xfs_inode_t *ip, /* incore inode pointer */ 3697 xfs_inode_t *ip, /* incore inode pointer */
3712 xfs_fileoff_t bno, /* block number searched for */ 3698 xfs_fileoff_t bno, /* block number searched for */
@@ -3717,7 +3703,7 @@ xfs_bmap_search_extents(
3717 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ 3703 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
3718{ 3704{
3719 xfs_ifork_t *ifp; /* inode fork pointer */ 3705 xfs_ifork_t *ifp; /* inode fork pointer */
3720 xfs_bmbt_rec_t *ep; /* extent record pointer */ 3706 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
3721 3707
3722 XFS_STATS_INC(xs_look_exlist); 3708 XFS_STATS_INC(xs_look_exlist);
3723 ifp = XFS_IFORK_PTR(ip, fork); 3709 ifp = XFS_IFORK_PTR(ip, fork);
@@ -3757,11 +3743,11 @@ xfs_bmap_trace_addentry(
3757 xfs_inode_t *ip, /* incore inode pointer */ 3743 xfs_inode_t *ip, /* incore inode pointer */
3758 xfs_extnum_t idx, /* index of entry(ies) */ 3744 xfs_extnum_t idx, /* index of entry(ies) */
3759 xfs_extnum_t cnt, /* count of entries, 1 or 2 */ 3745 xfs_extnum_t cnt, /* count of entries, 1 or 2 */
3760 xfs_bmbt_rec_t *r1, /* first record */ 3746 xfs_bmbt_rec_host_t *r1, /* first record */
3761 xfs_bmbt_rec_t *r2, /* second record or null */ 3747 xfs_bmbt_rec_host_t *r2, /* second record or null */
3762 int whichfork) /* data or attr fork */ 3748 int whichfork) /* data or attr fork */
3763{ 3749{
3764 xfs_bmbt_rec_t tr2; 3750 xfs_bmbt_rec_host_t tr2;
3765 3751
3766 ASSERT(cnt == 1 || cnt == 2); 3752 ASSERT(cnt == 1 || cnt == 2);
3767 ASSERT(r1 != NULL); 3753 ASSERT(r1 != NULL);
@@ -3842,8 +3828,8 @@ xfs_bmap_trace_insert(
3842 xfs_bmbt_irec_t *r2, /* inserted record 2 or null */ 3828 xfs_bmbt_irec_t *r2, /* inserted record 2 or null */
3843 int whichfork) /* data or attr fork */ 3829 int whichfork) /* data or attr fork */
3844{ 3830{
3845 xfs_bmbt_rec_t tr1; /* compressed record 1 */ 3831 xfs_bmbt_rec_host_t tr1; /* compressed record 1 */
3846 xfs_bmbt_rec_t tr2; /* compressed record 2 if needed */ 3832 xfs_bmbt_rec_host_t tr2; /* compressed record 2 if needed */
3847 3833
3848 xfs_bmbt_set_all(&tr1, r1); 3834 xfs_bmbt_set_all(&tr1, r1);
3849 if (cnt == 2) { 3835 if (cnt == 2) {
@@ -4316,7 +4302,6 @@ xfs_bmap_first_unused(
4316 xfs_fileoff_t *first_unused, /* unused block */ 4302 xfs_fileoff_t *first_unused, /* unused block */
4317 int whichfork) /* data or attr fork */ 4303 int whichfork) /* data or attr fork */
4318{ 4304{
4319 xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
4320 int error; /* error return value */ 4305 int error; /* error return value */
4321 int idx; /* extent record index */ 4306 int idx; /* extent record index */
4322 xfs_ifork_t *ifp; /* inode fork pointer */ 4307 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -4340,7 +4325,7 @@ xfs_bmap_first_unused(
4340 lowest = *first_unused; 4325 lowest = *first_unused;
4341 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 4326 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4342 for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) { 4327 for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
4343 ep = xfs_iext_get_ext(ifp, idx); 4328 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
4344 off = xfs_bmbt_get_startoff(ep); 4329 off = xfs_bmbt_get_startoff(ep);
4345 /* 4330 /*
4346 * See if the hole before this extent will work. 4331 * See if the hole before this extent will work.
@@ -4371,7 +4356,7 @@ xfs_bmap_last_before(
4371{ 4356{
4372 xfs_fileoff_t bno; /* input file offset */ 4357 xfs_fileoff_t bno; /* input file offset */
4373 int eof; /* hit end of file */ 4358 int eof; /* hit end of file */
4374 xfs_bmbt_rec_t *ep; /* pointer to last extent */ 4359 xfs_bmbt_rec_host_t *ep; /* pointer to last extent */
4375 int error; /* error return value */ 4360 int error; /* error return value */
4376 xfs_bmbt_irec_t got; /* current extent value */ 4361 xfs_bmbt_irec_t got; /* current extent value */
4377 xfs_ifork_t *ifp; /* inode fork pointer */ 4362 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -4417,7 +4402,7 @@ xfs_bmap_last_offset(
4417 xfs_fileoff_t *last_block, /* last block */ 4402 xfs_fileoff_t *last_block, /* last block */
4418 int whichfork) /* data or attr fork */ 4403 int whichfork) /* data or attr fork */
4419{ 4404{
4420 xfs_bmbt_rec_t *ep; /* pointer to last extent */ 4405 xfs_bmbt_rec_host_t *ep; /* pointer to last extent */
4421 int error; /* error return value */ 4406 int error; /* error return value */
4422 xfs_ifork_t *ifp; /* inode fork pointer */ 4407 xfs_ifork_t *ifp; /* inode fork pointer */
4423 xfs_extnum_t nextents; /* number of extent entries */ 4408 xfs_extnum_t nextents; /* number of extent entries */
@@ -4454,7 +4439,7 @@ xfs_bmap_one_block(
4454 xfs_inode_t *ip, /* incore inode */ 4439 xfs_inode_t *ip, /* incore inode */
4455 int whichfork) /* data or attr fork */ 4440 int whichfork) /* data or attr fork */
4456{ 4441{
4457 xfs_bmbt_rec_t *ep; /* ptr to fork's extent */ 4442 xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */
4458 xfs_ifork_t *ifp; /* inode fork pointer */ 4443 xfs_ifork_t *ifp; /* inode fork pointer */
4459 int rval; /* return value */ 4444 int rval; /* return value */
4460 xfs_bmbt_irec_t s; /* internal version of extent */ 4445 xfs_bmbt_irec_t s; /* internal version of extent */
@@ -4549,7 +4534,7 @@ xfs_bmap_read_extents(
4549 * Loop over all leaf nodes. Copy information to the extent records. 4534 * Loop over all leaf nodes. Copy information to the extent records.
4550 */ 4535 */
4551 for (;;) { 4536 for (;;) {
4552 xfs_bmbt_rec_t *frp, *trp; 4537 xfs_bmbt_rec_t *frp;
4553 xfs_fsblock_t nextbno; 4538 xfs_fsblock_t nextbno;
4554 xfs_extnum_t num_recs; 4539 xfs_extnum_t num_recs;
4555 xfs_extnum_t start; 4540 xfs_extnum_t start;
@@ -4581,9 +4566,9 @@ xfs_bmap_read_extents(
4581 frp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1); 4566 frp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1);
4582 start = i; 4567 start = i;
4583 for (j = 0; j < num_recs; j++, i++, frp++) { 4568 for (j = 0; j < num_recs; j++, i++, frp++) {
4584 trp = xfs_iext_get_ext(ifp, i); 4569 xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i);
4585 trp->l0 = INT_GET(frp->l0, ARCH_CONVERT); 4570 trp->l0 = be64_to_cpu(frp->l0);
4586 trp->l1 = INT_GET(frp->l1, ARCH_CONVERT); 4571 trp->l1 = be64_to_cpu(frp->l1);
4587 } 4572 }
4588 if (exntf == XFS_EXTFMT_NOSTATE) { 4573 if (exntf == XFS_EXTFMT_NOSTATE) {
4589 /* 4574 /*
@@ -4631,7 +4616,7 @@ xfs_bmap_trace_exlist(
4631 xfs_extnum_t cnt, /* count of entries in the list */ 4616 xfs_extnum_t cnt, /* count of entries in the list */
4632 int whichfork) /* data or attr fork */ 4617 int whichfork) /* data or attr fork */
4633{ 4618{
4634 xfs_bmbt_rec_t *ep; /* current extent record */ 4619 xfs_bmbt_rec_host_t *ep; /* current extent record */
4635 xfs_extnum_t idx; /* extent record index */ 4620 xfs_extnum_t idx; /* extent record index */
4636 xfs_ifork_t *ifp; /* inode fork pointer */ 4621 xfs_ifork_t *ifp; /* inode fork pointer */
4637 xfs_bmbt_irec_t s; /* file extent record */ 4622 xfs_bmbt_irec_t s; /* file extent record */
@@ -4727,7 +4712,7 @@ xfs_bmapi(
4727 xfs_btree_cur_t *cur; /* bmap btree cursor */ 4712 xfs_btree_cur_t *cur; /* bmap btree cursor */
4728 xfs_fileoff_t end; /* end of mapped file region */ 4713 xfs_fileoff_t end; /* end of mapped file region */
4729 int eof; /* we've hit the end of extents */ 4714 int eof; /* we've hit the end of extents */
4730 xfs_bmbt_rec_t *ep; /* extent record pointer */ 4715 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
4731 int error; /* error return */ 4716 int error; /* error return */
4732 xfs_bmbt_irec_t got; /* current file extent record */ 4717 xfs_bmbt_irec_t got; /* current file extent record */
4733 xfs_ifork_t *ifp; /* inode fork pointer */ 4718 xfs_ifork_t *ifp; /* inode fork pointer */
@@ -5378,7 +5363,7 @@ xfs_bunmapi(
5378 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5363 xfs_btree_cur_t *cur; /* bmap btree cursor */
5379 xfs_bmbt_irec_t del; /* extent being deleted */ 5364 xfs_bmbt_irec_t del; /* extent being deleted */
5380 int eof; /* is deleting at eof */ 5365 int eof; /* is deleting at eof */
5381 xfs_bmbt_rec_t *ep; /* extent record pointer */ 5366 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
5382 int error; /* error return value */ 5367 int error; /* error return value */
5383 xfs_extnum_t extno; /* extent number in list */ 5368 xfs_extnum_t extno; /* extent number in list */
5384 xfs_bmbt_irec_t got; /* current extent record */ 5369 xfs_bmbt_irec_t got; /* current extent record */
@@ -5743,11 +5728,44 @@ error0:
5743} 5728}
5744 5729
5745/* 5730/*
5731 * returns 1 for success, 0 if we failed to map the extent.
5732 */
5733STATIC int
5734xfs_getbmapx_fix_eof_hole(
5735 xfs_inode_t *ip, /* xfs incore inode pointer */
5736 struct getbmap *out, /* output structure */
5737 int prealloced, /* this is a file with
5738 * preallocated data space */
5739 __int64_t end, /* last block requested */
5740 xfs_fsblock_t startblock)
5741{
5742 __int64_t fixlen;
5743 xfs_mount_t *mp; /* file system mount point */
5744
5745 if (startblock == HOLESTARTBLOCK) {
5746 mp = ip->i_mount;
5747 out->bmv_block = -1;
5748 fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, ip->i_size));
5749 fixlen -= out->bmv_offset;
5750 if (prealloced && out->bmv_offset + out->bmv_length == end) {
5751 /* Came to hole at EOF. Trim it. */
5752 if (fixlen <= 0)
5753 return 0;
5754 out->bmv_length = fixlen;
5755 }
5756 } else {
5757 out->bmv_block = XFS_FSB_TO_DB(ip, startblock);
5758 }
5759
5760 return 1;
5761}
5762
5763/*
5746 * Fcntl interface to xfs_bmapi. 5764 * Fcntl interface to xfs_bmapi.
5747 */ 5765 */
5748int /* error code */ 5766int /* error code */
5749xfs_getbmap( 5767xfs_getbmap(
5750 bhv_desc_t *bdp, /* XFS behavior descriptor*/ 5768 xfs_inode_t *ip,
5751 struct getbmap *bmv, /* user bmap structure */ 5769 struct getbmap *bmv, /* user bmap structure */
5752 void __user *ap, /* pointer to user's array */ 5770 void __user *ap, /* pointer to user's array */
5753 int interface) /* interface flags */ 5771 int interface) /* interface flags */
@@ -5756,7 +5774,6 @@ xfs_getbmap(
5756 int error; /* return value */ 5774 int error; /* return value */
5757 __int64_t fixlen; /* length for -1 case */ 5775 __int64_t fixlen; /* length for -1 case */
5758 int i; /* extent number */ 5776 int i; /* extent number */
5759 xfs_inode_t *ip; /* xfs incore inode pointer */
5760 bhv_vnode_t *vp; /* corresponding vnode */ 5777 bhv_vnode_t *vp; /* corresponding vnode */
5761 int lock; /* lock state */ 5778 int lock; /* lock state */
5762 xfs_bmbt_irec_t *map; /* buffer for user's data */ 5779 xfs_bmbt_irec_t *map; /* buffer for user's data */
@@ -5774,8 +5791,7 @@ xfs_getbmap(
5774 int bmapi_flags; /* flags for xfs_bmapi */ 5791 int bmapi_flags; /* flags for xfs_bmapi */
5775 __int32_t oflags; /* getbmapx bmv_oflags field */ 5792 __int32_t oflags; /* getbmapx bmv_oflags field */
5776 5793
5777 vp = BHV_TO_VNODE(bdp); 5794 vp = XFS_ITOV(ip);
5778 ip = XFS_BHVTOI(bdp);
5779 mp = ip->i_mount; 5795 mp = ip->i_mount;
5780 5796
5781 whichfork = interface & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK; 5797 whichfork = interface & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
@@ -5794,10 +5810,9 @@ xfs_getbmap(
5794 * could misinterpret holes in a DMAPI file as true holes, 5810 * could misinterpret holes in a DMAPI file as true holes,
5795 * when in fact they may represent offline user data. 5811 * when in fact they may represent offline user data.
5796 */ 5812 */
5797 if ( (interface & BMV_IF_NO_DMAPI_READ) == 0 5813 if ((interface & BMV_IF_NO_DMAPI_READ) == 0 &&
5798 && DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) 5814 DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
5799 && whichfork == XFS_DATA_FORK) { 5815 whichfork == XFS_DATA_FORK) {
5800
5801 error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 0, 0, 0, NULL); 5816 error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 0, 0, 0, NULL);
5802 if (error) 5817 if (error)
5803 return XFS_ERROR(error); 5818 return XFS_ERROR(error);
@@ -5854,7 +5869,8 @@ xfs_getbmap(
5854 if (whichfork == XFS_DATA_FORK && 5869 if (whichfork == XFS_DATA_FORK &&
5855 (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) { 5870 (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
5856 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ 5871 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
5857 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF); 5872 error = xfs_flush_pages(ip, (xfs_off_t)0,
5873 -1, 0, FI_REMAPF);
5858 } 5874 }
5859 5875
5860 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); 5876 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
@@ -5904,18 +5920,15 @@ xfs_getbmap(
5904 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount); 5920 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
5905 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK); 5921 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
5906 if (map[i].br_startblock == HOLESTARTBLOCK && 5922 if (map[i].br_startblock == HOLESTARTBLOCK &&
5907 ((prealloced && out.bmv_offset + out.bmv_length == bmvend) || 5923 whichfork == XFS_ATTR_FORK) {
5908 whichfork == XFS_ATTR_FORK )) { 5924 /* came to the end of attribute fork */
5909 /*
5910 * came to hole at end of file or the end of
5911 attribute fork
5912 */
5913 goto unlock_and_return; 5925 goto unlock_and_return;
5914 } else { 5926 } else {
5915 out.bmv_block = 5927 if (!xfs_getbmapx_fix_eof_hole(ip, &out,
5916 (map[i].br_startblock == HOLESTARTBLOCK) ? 5928 prealloced, bmvend,
5917 -1 : 5929 map[i].br_startblock)) {
5918 XFS_FSB_TO_DB(ip, map[i].br_startblock); 5930 goto unlock_and_return;
5931 }
5919 5932
5920 /* return either getbmap/getbmapx structure. */ 5933 /* return either getbmap/getbmapx structure. */
5921 if (interface & BMV_IF_EXTENDED) { 5934 if (interface & BMV_IF_EXTENDED) {
@@ -5974,7 +5987,7 @@ xfs_bmap_isaeof(
5974{ 5987{
5975 int error; /* error return value */ 5988 int error; /* error return value */
5976 xfs_ifork_t *ifp; /* inode fork pointer */ 5989 xfs_ifork_t *ifp; /* inode fork pointer */
5977 xfs_bmbt_rec_t *lastrec; /* extent record pointer */ 5990 xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */
5978 xfs_extnum_t nextents; /* number of file extents */ 5991 xfs_extnum_t nextents; /* number of file extents */
5979 xfs_bmbt_irec_t s; /* expanded extent record */ 5992 xfs_bmbt_irec_t s; /* expanded extent record */
5980 5993
@@ -6018,7 +6031,7 @@ xfs_bmap_eof(
6018 xfs_fsblock_t blockcount; /* extent block count */ 6031 xfs_fsblock_t blockcount; /* extent block count */
6019 int error; /* error return value */ 6032 int error; /* error return value */
6020 xfs_ifork_t *ifp; /* inode fork pointer */ 6033 xfs_ifork_t *ifp; /* inode fork pointer */
6021 xfs_bmbt_rec_t *lastrec; /* extent record pointer */ 6034 xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */
6022 xfs_extnum_t nextents; /* number of file extents */ 6035 xfs_extnum_t nextents; /* number of file extents */
6023 xfs_fileoff_t startoff; /* extent starting file offset */ 6036 xfs_fileoff_t startoff; /* extent starting file offset */
6024 6037
@@ -6465,10 +6478,9 @@ xfs_bmap_count_leaves(
6465 int *count) 6478 int *count)
6466{ 6479{
6467 int b; 6480 int b;
6468 xfs_bmbt_rec_t *frp;
6469 6481
6470 for (b = 0; b < numrecs; b++) { 6482 for (b = 0; b < numrecs; b++) {
6471 frp = xfs_iext_get_ext(ifp, idx + b); 6483 xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b);
6472 *count += xfs_bmbt_get_blockcount(frp); 6484 *count += xfs_bmbt_get_blockcount(frp);
6473 } 6485 }
6474 return 0; 6486 return 0;
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 524b1c9d5246..68267d75ff19 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -335,7 +335,7 @@ xfs_bunmapi(
335 */ 335 */
336int /* error code */ 336int /* error code */
337xfs_getbmap( 337xfs_getbmap(
338 bhv_desc_t *bdp, /* XFS behavior descriptor*/ 338 xfs_inode_t *ip,
339 struct getbmap *bmv, /* user bmap structure */ 339 struct getbmap *bmv, /* user bmap structure */
340 void __user *ap, /* pointer to user's array */ 340 void __user *ap, /* pointer to user's array */
341 int iflags); /* interface flags */ 341 int iflags); /* interface flags */
@@ -378,7 +378,7 @@ xfs_check_nostate_extents(
378 * entry (null if none). Else, *lastxp will be set to the index 378 * entry (null if none). Else, *lastxp will be set to the index
379 * of the found entry; *gotp will contain the entry. 379 * of the found entry; *gotp will contain the entry.
380 */ 380 */
381xfs_bmbt_rec_t * 381xfs_bmbt_rec_host_t *
382xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *, 382xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,
383 xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); 383 xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
384 384
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 89b891f51cfb..32b49ec00fb5 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -260,13 +260,14 @@ xfs_bmbt_trace_cursor(
260 char *s, 260 char *s,
261 int line) 261 int line)
262{ 262{
263 xfs_bmbt_rec_t r; 263 xfs_bmbt_rec_host_t r;
264 264
265 xfs_bmbt_set_all(&r, &cur->bc_rec.b); 265 xfs_bmbt_set_all(&r, &cur->bc_rec.b);
266 xfs_bmbt_trace_enter(func, cur, s, XFS_BMBT_KTRACE_CUR, line, 266 xfs_bmbt_trace_enter(func, cur, s, XFS_BMBT_KTRACE_CUR, line,
267 (cur->bc_nlevels << 24) | (cur->bc_private.b.flags << 16) | 267 (cur->bc_nlevels << 24) | (cur->bc_private.b.flags << 16) |
268 cur->bc_private.b.allocated, 268 cur->bc_private.b.allocated,
269 INT_GET(r.l0, ARCH_CONVERT) >> 32, (int)INT_GET(r.l0, ARCH_CONVERT), INT_GET(r.l1, ARCH_CONVERT) >> 32, (int)INT_GET(r.l1, ARCH_CONVERT), 269 r.l0 >> 32, (int)r.l0,
270 r.l1 >> 32, (int)r.l1,
270 (unsigned long)cur->bc_bufs[0], (unsigned long)cur->bc_bufs[1], 271 (unsigned long)cur->bc_bufs[0], (unsigned long)cur->bc_bufs[1],
271 (unsigned long)cur->bc_bufs[2], (unsigned long)cur->bc_bufs[3], 272 (unsigned long)cur->bc_bufs[2], (unsigned long)cur->bc_bufs[3],
272 (cur->bc_ptrs[0] << 16) | cur->bc_ptrs[1], 273 (cur->bc_ptrs[0] << 16) | cur->bc_ptrs[1],
@@ -383,7 +384,7 @@ xfs_bmbt_delrec(
383 if (ptr < numrecs) { 384 if (ptr < numrecs) {
384 memmove(&kp[ptr - 1], &kp[ptr], 385 memmove(&kp[ptr - 1], &kp[ptr],
385 (numrecs - ptr) * sizeof(*kp)); 386 (numrecs - ptr) * sizeof(*kp));
386 memmove(&pp[ptr - 1], &pp[ptr], /* INT_: direct copy */ 387 memmove(&pp[ptr - 1], &pp[ptr],
387 (numrecs - ptr) * sizeof(*pp)); 388 (numrecs - ptr) * sizeof(*pp));
388 xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1); 389 xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1);
389 xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1); 390 xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1);
@@ -815,7 +816,7 @@ xfs_bmbt_insrec(
815#endif 816#endif
816 memmove(&kp[ptr], &kp[ptr - 1], 817 memmove(&kp[ptr], &kp[ptr - 1],
817 (numrecs - ptr + 1) * sizeof(*kp)); 818 (numrecs - ptr + 1) * sizeof(*kp));
818 memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */ 819 memmove(&pp[ptr], &pp[ptr - 1],
819 (numrecs - ptr + 1) * sizeof(*pp)); 820 (numrecs - ptr + 1) * sizeof(*pp));
820#ifdef DEBUG 821#ifdef DEBUG
821 if ((error = xfs_btree_check_lptr(cur, *bnop, level))) { 822 if ((error = xfs_btree_check_lptr(cur, *bnop, level))) {
@@ -1250,7 +1251,7 @@ xfs_bmbt_lshift(
1250 return error; 1251 return error;
1251 } 1252 }
1252#endif 1253#endif
1253 *lpp = *rpp; /* INT_: direct copy */ 1254 *lpp = *rpp;
1254 xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs); 1255 xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs);
1255 } else { 1256 } else {
1256 lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur); 1257 lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur);
@@ -1388,7 +1389,7 @@ xfs_bmbt_rshift(
1388 } 1389 }
1389#endif 1390#endif
1390 *rkp = *lkp; 1391 *rkp = *lkp;
1391 *rpp = *lpp; /* INT_: direct copy */ 1392 *rpp = *lpp;
1392 xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); 1393 xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
1393 xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); 1394 xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
1394 } else { 1395 } else {
@@ -1826,7 +1827,7 @@ __xfs_bmbt_get_all(
1826 1827
1827void 1828void
1828xfs_bmbt_get_all( 1829xfs_bmbt_get_all(
1829 xfs_bmbt_rec_t *r, 1830 xfs_bmbt_rec_host_t *r,
1830 xfs_bmbt_irec_t *s) 1831 xfs_bmbt_irec_t *s)
1831{ 1832{
1832 __xfs_bmbt_get_all(r->l0, r->l1, s); 1833 __xfs_bmbt_get_all(r->l0, r->l1, s);
@@ -1862,7 +1863,7 @@ xfs_bmbt_get_block(
1862 */ 1863 */
1863xfs_filblks_t 1864xfs_filblks_t
1864xfs_bmbt_get_blockcount( 1865xfs_bmbt_get_blockcount(
1865 xfs_bmbt_rec_t *r) 1866 xfs_bmbt_rec_host_t *r)
1866{ 1867{
1867 return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21)); 1868 return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21));
1868} 1869}
@@ -1872,7 +1873,7 @@ xfs_bmbt_get_blockcount(
1872 */ 1873 */
1873xfs_fsblock_t 1874xfs_fsblock_t
1874xfs_bmbt_get_startblock( 1875xfs_bmbt_get_startblock(
1875 xfs_bmbt_rec_t *r) 1876 xfs_bmbt_rec_host_t *r)
1876{ 1877{
1877#if XFS_BIG_BLKNOS 1878#if XFS_BIG_BLKNOS
1878 return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) | 1879 return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) |
@@ -1896,7 +1897,7 @@ xfs_bmbt_get_startblock(
1896 */ 1897 */
1897xfs_fileoff_t 1898xfs_fileoff_t
1898xfs_bmbt_get_startoff( 1899xfs_bmbt_get_startoff(
1899 xfs_bmbt_rec_t *r) 1900 xfs_bmbt_rec_host_t *r)
1900{ 1901{
1901 return ((xfs_fileoff_t)r->l0 & 1902 return ((xfs_fileoff_t)r->l0 &
1902 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; 1903 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
@@ -1904,7 +1905,7 @@ xfs_bmbt_get_startoff(
1904 1905
1905xfs_exntst_t 1906xfs_exntst_t
1906xfs_bmbt_get_state( 1907xfs_bmbt_get_state(
1907 xfs_bmbt_rec_t *r) 1908 xfs_bmbt_rec_host_t *r)
1908{ 1909{
1909 int ext_flag; 1910 int ext_flag;
1910 1911
@@ -1913,19 +1914,13 @@ xfs_bmbt_get_state(
1913 ext_flag); 1914 ext_flag);
1914} 1915}
1915 1916
1916#ifndef XFS_NATIVE_HOST
1917/* Endian flipping versions of the bmbt extraction functions */ 1917/* Endian flipping versions of the bmbt extraction functions */
1918void 1918void
1919xfs_bmbt_disk_get_all( 1919xfs_bmbt_disk_get_all(
1920 xfs_bmbt_rec_t *r, 1920 xfs_bmbt_rec_t *r,
1921 xfs_bmbt_irec_t *s) 1921 xfs_bmbt_irec_t *s)
1922{ 1922{
1923 __uint64_t l0, l1; 1923 __xfs_bmbt_get_all(be64_to_cpu(r->l0), be64_to_cpu(r->l1), s);
1924
1925 l0 = INT_GET(r->l0, ARCH_CONVERT);
1926 l1 = INT_GET(r->l1, ARCH_CONVERT);
1927
1928 __xfs_bmbt_get_all(l0, l1, s);
1929} 1924}
1930 1925
1931/* 1926/*
@@ -1935,7 +1930,7 @@ xfs_filblks_t
1935xfs_bmbt_disk_get_blockcount( 1930xfs_bmbt_disk_get_blockcount(
1936 xfs_bmbt_rec_t *r) 1931 xfs_bmbt_rec_t *r)
1937{ 1932{
1938 return (xfs_filblks_t)(INT_GET(r->l1, ARCH_CONVERT) & XFS_MASK64LO(21)); 1933 return (xfs_filblks_t)(be64_to_cpu(r->l1) & XFS_MASK64LO(21));
1939} 1934}
1940 1935
1941/* 1936/*
@@ -1945,11 +1940,9 @@ xfs_fileoff_t
1945xfs_bmbt_disk_get_startoff( 1940xfs_bmbt_disk_get_startoff(
1946 xfs_bmbt_rec_t *r) 1941 xfs_bmbt_rec_t *r)
1947{ 1942{
1948 return ((xfs_fileoff_t)INT_GET(r->l0, ARCH_CONVERT) & 1943 return ((xfs_fileoff_t)be64_to_cpu(r->l0) &
1949 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; 1944 XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
1950} 1945}
1951#endif /* XFS_NATIVE_HOST */
1952
1953 1946
1954/* 1947/*
1955 * Increment cursor by one record at the level. 1948 * Increment cursor by one record at the level.
@@ -2290,185 +2283,131 @@ xfs_bmbt_newroot(
2290} 2283}
2291 2284
2292/* 2285/*
2293 * Set all the fields in a bmap extent record from the uncompressed form.
2294 */
2295void
2296xfs_bmbt_set_all(
2297 xfs_bmbt_rec_t *r,
2298 xfs_bmbt_irec_t *s)
2299{
2300 int extent_flag;
2301
2302 ASSERT((s->br_state == XFS_EXT_NORM) ||
2303 (s->br_state == XFS_EXT_UNWRITTEN));
2304 extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
2305 ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
2306 ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
2307#if XFS_BIG_BLKNOS
2308 ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
2309 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2310 ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
2311 ((xfs_bmbt_rec_base_t)s->br_startblock >> 43);
2312 r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
2313 ((xfs_bmbt_rec_base_t)s->br_blockcount &
2314 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
2315#else /* !XFS_BIG_BLKNOS */
2316 if (ISNULLSTARTBLOCK(s->br_startblock)) {
2317 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2318 ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
2319 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
2320 r->l1 = XFS_MASK64HI(11) |
2321 ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
2322 ((xfs_bmbt_rec_base_t)s->br_blockcount &
2323 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
2324 } else {
2325 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2326 ((xfs_bmbt_rec_base_t)s->br_startoff << 9);
2327 r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
2328 ((xfs_bmbt_rec_base_t)s->br_blockcount &
2329 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
2330 }
2331#endif /* XFS_BIG_BLKNOS */
2332}
2333
2334/*
2335 * Set all the fields in a bmap extent record from the arguments. 2286 * Set all the fields in a bmap extent record from the arguments.
2336 */ 2287 */
2337void 2288void
2338xfs_bmbt_set_allf( 2289xfs_bmbt_set_allf(
2339 xfs_bmbt_rec_t *r, 2290 xfs_bmbt_rec_host_t *r,
2340 xfs_fileoff_t o, 2291 xfs_fileoff_t startoff,
2341 xfs_fsblock_t b, 2292 xfs_fsblock_t startblock,
2342 xfs_filblks_t c, 2293 xfs_filblks_t blockcount,
2343 xfs_exntst_t v) 2294 xfs_exntst_t state)
2344{ 2295{
2345 int extent_flag; 2296 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
2297
2298 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
2299 ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
2300 ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
2346 2301
2347 ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN));
2348 extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
2349 ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
2350 ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
2351#if XFS_BIG_BLKNOS 2302#if XFS_BIG_BLKNOS
2352 ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); 2303 ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
2304
2353 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | 2305 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2354 ((xfs_bmbt_rec_base_t)o << 9) | 2306 ((xfs_bmbt_rec_base_t)startoff << 9) |
2355 ((xfs_bmbt_rec_base_t)b >> 43); 2307 ((xfs_bmbt_rec_base_t)startblock >> 43);
2356 r->l1 = ((xfs_bmbt_rec_base_t)b << 21) | 2308 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |
2357 ((xfs_bmbt_rec_base_t)c & 2309 ((xfs_bmbt_rec_base_t)blockcount &
2358 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); 2310 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
2359#else /* !XFS_BIG_BLKNOS */ 2311#else /* !XFS_BIG_BLKNOS */
2360 if (ISNULLSTARTBLOCK(b)) { 2312 if (ISNULLSTARTBLOCK(startblock)) {
2361 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | 2313 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2362 ((xfs_bmbt_rec_base_t)o << 9) | 2314 ((xfs_bmbt_rec_base_t)startoff << 9) |
2363 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); 2315 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9);
2364 r->l1 = XFS_MASK64HI(11) | 2316 r->l1 = XFS_MASK64HI(11) |
2365 ((xfs_bmbt_rec_base_t)b << 21) | 2317 ((xfs_bmbt_rec_base_t)startblock << 21) |
2366 ((xfs_bmbt_rec_base_t)c & 2318 ((xfs_bmbt_rec_base_t)blockcount &
2367 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); 2319 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
2368 } else { 2320 } else {
2369 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | 2321 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2370 ((xfs_bmbt_rec_base_t)o << 9); 2322 ((xfs_bmbt_rec_base_t)startoff << 9);
2371 r->l1 = ((xfs_bmbt_rec_base_t)b << 21) | 2323 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |
2372 ((xfs_bmbt_rec_base_t)c & 2324 ((xfs_bmbt_rec_base_t)blockcount &
2373 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); 2325 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));
2374 } 2326 }
2375#endif /* XFS_BIG_BLKNOS */ 2327#endif /* XFS_BIG_BLKNOS */
2376} 2328}
2377 2329
2378#ifndef XFS_NATIVE_HOST
2379/* 2330/*
2380 * Set all the fields in a bmap extent record from the uncompressed form. 2331 * Set all the fields in a bmap extent record from the uncompressed form.
2381 */ 2332 */
2382void 2333void
2383xfs_bmbt_disk_set_all( 2334xfs_bmbt_set_all(
2384 xfs_bmbt_rec_t *r, 2335 xfs_bmbt_rec_host_t *r,
2385 xfs_bmbt_irec_t *s) 2336 xfs_bmbt_irec_t *s)
2386{ 2337{
2387 int extent_flag; 2338 xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock,
2388 2339 s->br_blockcount, s->br_state);
2389 ASSERT((s->br_state == XFS_EXT_NORM) ||
2390 (s->br_state == XFS_EXT_UNWRITTEN));
2391 extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1;
2392 ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0);
2393 ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0);
2394#if XFS_BIG_BLKNOS
2395 ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
2396 INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2397 ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
2398 ((xfs_bmbt_rec_base_t)s->br_startblock >> 43));
2399 INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
2400 ((xfs_bmbt_rec_base_t)s->br_blockcount &
2401 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
2402#else /* !XFS_BIG_BLKNOS */
2403 if (ISNULLSTARTBLOCK(s->br_startblock)) {
2404 INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2405 ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
2406 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
2407 INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) |
2408 ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
2409 ((xfs_bmbt_rec_base_t)s->br_blockcount &
2410 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
2411 } else {
2412 INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2413 ((xfs_bmbt_rec_base_t)s->br_startoff << 9));
2414 INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
2415 ((xfs_bmbt_rec_base_t)s->br_blockcount &
2416 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
2417 }
2418#endif /* XFS_BIG_BLKNOS */
2419} 2340}
2420 2341
2342
2421/* 2343/*
2422 * Set all the fields in a disk format bmap extent record from the arguments. 2344 * Set all the fields in a disk format bmap extent record from the arguments.
2423 */ 2345 */
2424void 2346void
2425xfs_bmbt_disk_set_allf( 2347xfs_bmbt_disk_set_allf(
2426 xfs_bmbt_rec_t *r, 2348 xfs_bmbt_rec_t *r,
2427 xfs_fileoff_t o, 2349 xfs_fileoff_t startoff,
2428 xfs_fsblock_t b, 2350 xfs_fsblock_t startblock,
2429 xfs_filblks_t c, 2351 xfs_filblks_t blockcount,
2430 xfs_exntst_t v) 2352 xfs_exntst_t state)
2431{ 2353{
2432 int extent_flag; 2354 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
2355
2356 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
2357 ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
2358 ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
2433 2359
2434 ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN));
2435 extent_flag = (v == XFS_EXT_NORM) ? 0 : 1;
2436 ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0);
2437 ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
2438#if XFS_BIG_BLKNOS 2360#if XFS_BIG_BLKNOS
2439 ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); 2361 ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0);
2440 INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | 2362
2441 ((xfs_bmbt_rec_base_t)o << 9) | 2363 r->l0 = cpu_to_be64(
2442 ((xfs_bmbt_rec_base_t)b >> 43)); 2364 ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2443 INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) | 2365 ((xfs_bmbt_rec_base_t)startoff << 9) |
2444 ((xfs_bmbt_rec_base_t)c & 2366 ((xfs_bmbt_rec_base_t)startblock >> 43));
2445 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); 2367 r->l1 = cpu_to_be64(
2368 ((xfs_bmbt_rec_base_t)startblock << 21) |
2369 ((xfs_bmbt_rec_base_t)blockcount &
2370 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
2446#else /* !XFS_BIG_BLKNOS */ 2371#else /* !XFS_BIG_BLKNOS */
2447 if (ISNULLSTARTBLOCK(b)) { 2372 if (ISNULLSTARTBLOCK(startblock)) {
2448 INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | 2373 r->l0 = cpu_to_be64(
2449 ((xfs_bmbt_rec_base_t)o << 9) | 2374 ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2450 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); 2375 ((xfs_bmbt_rec_base_t)startoff << 9) |
2451 INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) | 2376 (xfs_bmbt_rec_base_t)XFS_MASK64LO(9));
2452 ((xfs_bmbt_rec_base_t)b << 21) | 2377 r->l1 = cpu_to_be64(XFS_MASK64HI(11) |
2453 ((xfs_bmbt_rec_base_t)c & 2378 ((xfs_bmbt_rec_base_t)startblock << 21) |
2379 ((xfs_bmbt_rec_base_t)blockcount &
2454 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); 2380 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
2455 } else { 2381 } else {
2456 INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | 2382 r->l0 = cpu_to_be64(
2457 ((xfs_bmbt_rec_base_t)o << 9)); 2383 ((xfs_bmbt_rec_base_t)extent_flag << 63) |
2458 INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) | 2384 ((xfs_bmbt_rec_base_t)startoff << 9));
2459 ((xfs_bmbt_rec_base_t)c & 2385 r->l1 = cpu_to_be64(
2460 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); 2386 ((xfs_bmbt_rec_base_t)startblock << 21) |
2387 ((xfs_bmbt_rec_base_t)blockcount &
2388 (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)));
2461 } 2389 }
2462#endif /* XFS_BIG_BLKNOS */ 2390#endif /* XFS_BIG_BLKNOS */
2463} 2391}
2464#endif /* XFS_NATIVE_HOST */ 2392
2393/*
2394 * Set all the fields in a bmap extent record from the uncompressed form.
2395 */
2396void
2397xfs_bmbt_disk_set_all(
2398 xfs_bmbt_rec_t *r,
2399 xfs_bmbt_irec_t *s)
2400{
2401 xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock,
2402 s->br_blockcount, s->br_state);
2403}
2465 2404
2466/* 2405/*
2467 * Set the blockcount field in a bmap extent record. 2406 * Set the blockcount field in a bmap extent record.
2468 */ 2407 */
2469void 2408void
2470xfs_bmbt_set_blockcount( 2409xfs_bmbt_set_blockcount(
2471 xfs_bmbt_rec_t *r, 2410 xfs_bmbt_rec_host_t *r,
2472 xfs_filblks_t v) 2411 xfs_filblks_t v)
2473{ 2412{
2474 ASSERT((v & XFS_MASK64HI(43)) == 0); 2413 ASSERT((v & XFS_MASK64HI(43)) == 0);
@@ -2481,7 +2420,7 @@ xfs_bmbt_set_blockcount(
2481 */ 2420 */
2482void 2421void
2483xfs_bmbt_set_startblock( 2422xfs_bmbt_set_startblock(
2484 xfs_bmbt_rec_t *r, 2423 xfs_bmbt_rec_host_t *r,
2485 xfs_fsblock_t v) 2424 xfs_fsblock_t v)
2486{ 2425{
2487#if XFS_BIG_BLKNOS 2426#if XFS_BIG_BLKNOS
@@ -2509,7 +2448,7 @@ xfs_bmbt_set_startblock(
2509 */ 2448 */
2510void 2449void
2511xfs_bmbt_set_startoff( 2450xfs_bmbt_set_startoff(
2512 xfs_bmbt_rec_t *r, 2451 xfs_bmbt_rec_host_t *r,
2513 xfs_fileoff_t v) 2452 xfs_fileoff_t v)
2514{ 2453{
2515 ASSERT((v & XFS_MASK64HI(9)) == 0); 2454 ASSERT((v & XFS_MASK64HI(9)) == 0);
@@ -2523,7 +2462,7 @@ xfs_bmbt_set_startoff(
2523 */ 2462 */
2524void 2463void
2525xfs_bmbt_set_state( 2464xfs_bmbt_set_state(
2526 xfs_bmbt_rec_t *r, 2465 xfs_bmbt_rec_host_t *r,
2527 xfs_exntst_t v) 2466 xfs_exntst_t v)
2528{ 2467{
2529 ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN); 2468 ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN);
@@ -2624,10 +2563,8 @@ xfs_check_nostate_extents(
2624 xfs_extnum_t idx, 2563 xfs_extnum_t idx,
2625 xfs_extnum_t num) 2564 xfs_extnum_t num)
2626{ 2565{
2627 xfs_bmbt_rec_t *ep;
2628
2629 for (; num > 0; num--, idx++) { 2566 for (; num > 0; num--, idx++) {
2630 ep = xfs_iext_get_ext(ifp, idx); 2567 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
2631 if ((ep->l0 >> 2568 if ((ep->l0 >>
2632 (64 - BMBT_EXNTFLAG_BITLEN)) != 0) { 2569 (64 - BMBT_EXNTFLAG_BITLEN)) != 0) {
2633 ASSERT(0); 2570 ASSERT(0);
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index a77b1b753d0c..2d950e975918 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -35,45 +35,16 @@ typedef struct xfs_bmdr_block {
35 35
36/* 36/*
37 * Bmap btree record and extent descriptor. 37 * Bmap btree record and extent descriptor.
38 * For 32-bit kernels,
39 * l0:31 is an extent flag (value 1 indicates non-normal).
40 * l0:0-30 and l1:9-31 are startoff.
41 * l1:0-8, l2:0-31, and l3:21-31 are startblock.
42 * l3:0-20 are blockcount.
43 * For 64-bit kernels,
44 * l0:63 is an extent flag (value 1 indicates non-normal). 38 * l0:63 is an extent flag (value 1 indicates non-normal).
45 * l0:9-62 are startoff. 39 * l0:9-62 are startoff.
46 * l0:0-8 and l1:21-63 are startblock. 40 * l0:0-8 and l1:21-63 are startblock.
47 * l1:0-20 are blockcount. 41 * l1:0-20 are blockcount.
48 */ 42 */
49
50#ifndef XFS_NATIVE_HOST
51
52#define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */
53#define BMBT_EXNTFLAG_BITOFF 0
54#define BMBT_EXNTFLAG_BITLEN 1 43#define BMBT_EXNTFLAG_BITLEN 1
55#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN)
56#define BMBT_STARTOFF_BITLEN 54 44#define BMBT_STARTOFF_BITLEN 54
57#define BMBT_STARTBLOCK_BITOFF (BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN)
58#define BMBT_STARTBLOCK_BITLEN 52 45#define BMBT_STARTBLOCK_BITLEN 52
59#define BMBT_BLOCKCOUNT_BITOFF \
60 (BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN)
61#define BMBT_BLOCKCOUNT_BITLEN (BMBT_TOTAL_BITLEN - BMBT_BLOCKCOUNT_BITOFF)
62
63#else
64
65#define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */
66#define BMBT_EXNTFLAG_BITOFF 63
67#define BMBT_EXNTFLAG_BITLEN 1
68#define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF - BMBT_STARTOFF_BITLEN)
69#define BMBT_STARTOFF_BITLEN 54
70#define BMBT_STARTBLOCK_BITOFF 85 /* 128 - 43 (other 9 is in first word) */
71#define BMBT_STARTBLOCK_BITLEN 52
72#define BMBT_BLOCKCOUNT_BITOFF 64 /* Start of second 64 bit container */
73#define BMBT_BLOCKCOUNT_BITLEN 21 46#define BMBT_BLOCKCOUNT_BITLEN 21
74 47
75#endif /* XFS_NATIVE_HOST */
76
77 48
78#define BMBT_USE_64 1 49#define BMBT_USE_64 1
79 50
@@ -83,12 +54,16 @@ typedef struct xfs_bmbt_rec_32
83} xfs_bmbt_rec_32_t; 54} xfs_bmbt_rec_32_t;
84typedef struct xfs_bmbt_rec_64 55typedef struct xfs_bmbt_rec_64
85{ 56{
86 __uint64_t l0, l1; 57 __be64 l0, l1;
87} xfs_bmbt_rec_64_t; 58} xfs_bmbt_rec_64_t;
88 59
89typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ 60typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */
90typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; 61typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
91 62
63typedef struct xfs_bmbt_rec_host {
64 __uint64_t l0, l1;
65} xfs_bmbt_rec_host_t;
66
92/* 67/*
93 * Values and macros for delayed-allocation startblock fields. 68 * Values and macros for delayed-allocation startblock fields.
94 */ 69 */
@@ -281,23 +256,17 @@ extern ktrace_t *xfs_bmbt_trace_buf;
281extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int); 256extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int);
282extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *); 257extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *);
283extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *); 258extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *);
284extern void xfs_bmbt_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); 259extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
285extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur, 260extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur,
286 int, struct xfs_buf **bpp); 261 int, struct xfs_buf **bpp);
287extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_t *r); 262extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r);
288extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_t *r); 263extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r);
289extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_t *r); 264extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r);
290extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_t *r); 265extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r);
291 266
292#ifndef XFS_NATIVE_HOST
293extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); 267extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
294extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r); 268extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
295extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r); 269extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
296#else
297#define xfs_bmbt_disk_get_all(r, s) xfs_bmbt_get_all(r, s)
298#define xfs_bmbt_disk_get_blockcount(r) xfs_bmbt_get_blockcount(r)
299#define xfs_bmbt_disk_get_startoff(r) xfs_bmbt_get_startoff(r)
300#endif /* XFS_NATIVE_HOST */
301 270
302extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *); 271extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *);
303extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *); 272extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *);
@@ -315,22 +284,17 @@ extern int xfs_bmbt_lookup_ge(struct xfs_btree_cur *, xfs_fileoff_t,
315 */ 284 */
316extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat); 285extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat);
317 286
318extern void xfs_bmbt_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); 287extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
319extern void xfs_bmbt_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, 288extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o,
320 xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); 289 xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
321extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_t *r, xfs_filblks_t v); 290extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_host_t *r, xfs_filblks_t v);
322extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_t *r, xfs_fsblock_t v); 291extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_host_t *r, xfs_fsblock_t v);
323extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_t *r, xfs_fileoff_t v); 292extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_host_t *r, xfs_fileoff_t v);
324extern void xfs_bmbt_set_state(xfs_bmbt_rec_t *r, xfs_exntst_t v); 293extern void xfs_bmbt_set_state(xfs_bmbt_rec_host_t *r, xfs_exntst_t v);
325 294
326#ifndef XFS_NATIVE_HOST
327extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); 295extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
328extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, 296extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
329 xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); 297 xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
330#else
331#define xfs_bmbt_disk_set_all(r, s) xfs_bmbt_set_all(r, s)
332#define xfs_bmbt_disk_set_allf(r, o, b, c, v) xfs_bmbt_set_allf(r, o, b, c, v)
333#endif /* XFS_NATIVE_HOST */
334 298
335extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int); 299extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int);
336extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t, 300extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t,
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index b0667cb27d66..c8f2c2886fe4 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -23,6 +23,7 @@
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_ag.h"
26#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
27#include "xfs_mount.h" 28#include "xfs_mount.h"
28#include "xfs_buf_item.h" 29#include "xfs_buf_item.h"
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
index f89196cb08d2..d16c1b971074 100644
--- a/fs/xfs/xfs_clnt.h
+++ b/fs/xfs/xfs_clnt.h
@@ -89,7 +89,6 @@ struct xfs_mount_args {
89#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */ 89#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */
90#define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width 90#define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width
91 * allocation */ 91 * allocation */
92#define XFSMNT_IHASHSIZE 0x20000000 /* inode hash table size */
93#define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename 92#define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename
94 * symlink,mkdir,rmdir,mknod */ 93 * symlink,mkdir,rmdir,mknod */
95#define XFSMNT_FLAGS2 0x80000000 /* more flags set in flags2 */ 94#define XFSMNT_FLAGS2 0x80000000 /* more flags set in flags2 */
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index de35d18cc002..584f1ae85cd9 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -42,6 +42,7 @@
42#include "xfs_dfrag.h" 42#include "xfs_dfrag.h"
43#include "xfs_error.h" 43#include "xfs_error.h"
44#include "xfs_rw.h" 44#include "xfs_rw.h"
45#include "xfs_vnodeops.h"
45 46
46/* 47/*
47 * Syssgi interface for swapext 48 * Syssgi interface for swapext
@@ -199,7 +200,8 @@ xfs_swap_extents(
199 200
200 if (VN_CACHED(tvp) != 0) { 201 if (VN_CACHED(tvp) != 0) {
201 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); 202 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
202 error = bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED); 203 error = xfs_flushinval_pages(tip, 0, -1,
204 FI_REMAPF_LOCKED);
203 if (error) 205 if (error)
204 goto error0; 206 goto error0;
205 } 207 }
@@ -265,7 +267,7 @@ xfs_swap_extents(
265 * fields change. 267 * fields change.
266 */ 268 */
267 269
268 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); 270 xfs_tosspages(ip, 0, -1, FI_REMAPF);
269 271
270 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); 272 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
271 if ((error = xfs_trans_reserve(tp, 0, 273 if ((error = xfs_trans_reserve(tp, 0,
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index fefd0116bac9..dedd713574e1 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -34,41 +34,41 @@ struct xfs_mount;
34 * because we only need the core part in the in-core inode. 34 * because we only need the core part in the in-core inode.
35 */ 35 */
36typedef struct xfs_timestamp { 36typedef struct xfs_timestamp {
37 __int32_t t_sec; /* timestamp seconds */ 37 __be32 t_sec; /* timestamp seconds */
38 __int32_t t_nsec; /* timestamp nanoseconds */ 38 __be32 t_nsec; /* timestamp nanoseconds */
39} xfs_timestamp_t; 39} xfs_timestamp_t;
40 40
41/* 41/*
42 * Note: Coordinate changes to this structure with the XFS_DI_* #defines 42 * Note: Coordinate changes to this structure with the XFS_DI_* #defines
43 * below and the offsets table in xfs_ialloc_log_di(). 43 * below, the offsets table in xfs_ialloc_log_di() and struct xfs_icdinode
44 * in xfs_inode.h.
44 */ 45 */
45typedef struct xfs_dinode_core 46typedef struct xfs_dinode_core {
46{ 47 __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */
47 __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ 48 __be16 di_mode; /* mode and type of file */
48 __uint16_t di_mode; /* mode and type of file */ 49 __u8 di_version; /* inode version */
49 __int8_t di_version; /* inode version */ 50 __u8 di_format; /* format of di_c data */
50 __int8_t di_format; /* format of di_c data */ 51 __be16 di_onlink; /* old number of links to file */
51 __uint16_t di_onlink; /* old number of links to file */ 52 __be32 di_uid; /* owner's user id */
52 __uint32_t di_uid; /* owner's user id */ 53 __be32 di_gid; /* owner's group id */
53 __uint32_t di_gid; /* owner's group id */ 54 __be32 di_nlink; /* number of links to file */
54 __uint32_t di_nlink; /* number of links to file */ 55 __be16 di_projid; /* owner's project id */
55 __uint16_t di_projid; /* owner's project id */ 56 __u8 di_pad[8]; /* unused, zeroed space */
56 __uint8_t di_pad[8]; /* unused, zeroed space */ 57 __be16 di_flushiter; /* incremented on flush */
57 __uint16_t di_flushiter; /* incremented on flush */
58 xfs_timestamp_t di_atime; /* time last accessed */ 58 xfs_timestamp_t di_atime; /* time last accessed */
59 xfs_timestamp_t di_mtime; /* time last modified */ 59 xfs_timestamp_t di_mtime; /* time last modified */
60 xfs_timestamp_t di_ctime; /* time created/inode modified */ 60 xfs_timestamp_t di_ctime; /* time created/inode modified */
61 xfs_fsize_t di_size; /* number of bytes in file */ 61 __be64 di_size; /* number of bytes in file */
62 xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ 62 __be64 di_nblocks; /* # of direct & btree blocks used */
63 xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ 63 __be32 di_extsize; /* basic/minimum extent size for file */
64 xfs_extnum_t di_nextents; /* number of extents in data fork */ 64 __be32 di_nextents; /* number of extents in data fork */
65 xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ 65 __be16 di_anextents; /* number of extents in attribute fork*/
66 __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ 66 __u8 di_forkoff; /* attr fork offs, <<3 for 64b align */
67 __int8_t di_aformat; /* format of attr fork's data */ 67 __s8 di_aformat; /* format of attr fork's data */
68 __uint32_t di_dmevmask; /* DMIG event mask */ 68 __be32 di_dmevmask; /* DMIG event mask */
69 __uint16_t di_dmstate; /* DMIG state info */ 69 __be16 di_dmstate; /* DMIG state info */
70 __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ 70 __be16 di_flags; /* random flags, XFS_DIFLAG_... */
71 __uint32_t di_gen; /* generation number */ 71 __be32 di_gen; /* generation number */
72} xfs_dinode_core_t; 72} xfs_dinode_core_t;
73 73
74#define DI_MAX_FLUSH 0xffff 74#define DI_MAX_FLUSH 0xffff
@@ -81,13 +81,13 @@ typedef struct xfs_dinode
81 * sure to update the macros like XFS_LITINO below and 81 * sure to update the macros like XFS_LITINO below and
82 * XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h. 82 * XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h.
83 */ 83 */
84 xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */ 84 __be32 di_next_unlinked;/* agi unlinked list ptr */
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_dir2_sf_t di_dir2sf; /* shortform directory v2 */ 88 xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
89 char di_c[1]; /* local contents */ 89 char di_c[1]; /* local contents */
90 xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ 90 __be32 di_dev; /* device for S_IFCHR/S_IFBLK */
91 uuid_t di_muuid; /* mount point value */ 91 uuid_t di_muuid; /* mount point value */
92 char di_symlink[1]; /* local symbolic link */ 92 char di_symlink[1]; /* local symbolic link */
93 } di_u; 93 } di_u;
@@ -175,8 +175,7 @@ typedef enum xfs_dinode_fmt
175#define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0) 175#define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0)
176 176
177#define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3)) 177#define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3))
178#define XFS_CFORK_BOFF_DISK(dcp) \ 178#define XFS_CFORK_BOFF_DISK(dcp) ((int)((dcp)->di_forkoff << 3))
179 ((int)(INT_GET((dcp)->di_forkoff, ARCH_CONVERT) << 3))
180 179
181#define XFS_CFORK_DSIZE_DISK(dcp,mp) \ 180#define XFS_CFORK_DSIZE_DISK(dcp,mp) \
182 (XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp)) 181 (XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp))
@@ -225,8 +224,8 @@ typedef enum xfs_dinode_fmt
225 224
226#define XFS_CFORK_NEXTENTS_DISK(dcp,w) \ 225#define XFS_CFORK_NEXTENTS_DISK(dcp,w) \
227 ((w) == XFS_DATA_FORK ? \ 226 ((w) == XFS_DATA_FORK ? \
228 INT_GET((dcp)->di_nextents, ARCH_CONVERT) : \ 227 be32_to_cpu((dcp)->di_nextents) : \
229 INT_GET((dcp)->di_anextents, ARCH_CONVERT)) 228 be16_to_cpu((dcp)->di_anextents))
230#define XFS_CFORK_NEXTENTS(dcp,w) \ 229#define XFS_CFORK_NEXTENTS(dcp,w) \
231 ((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents) 230 ((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents)
232#define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w) 231#define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w)
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 29e091914df4..b0f1ee8fcb90 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -43,8 +43,6 @@
43#include "xfs_dir2_trace.h" 43#include "xfs_dir2_trace.h"
44#include "xfs_error.h" 44#include "xfs_error.h"
45 45
46static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);
47static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa);
48 46
49void 47void
50xfs_dir_mount( 48xfs_dir_mount(
@@ -293,47 +291,33 @@ xfs_dir_removename(
293 * Read a directory. 291 * Read a directory.
294 */ 292 */
295int 293int
296xfs_dir_getdents( 294xfs_readdir(
297 xfs_trans_t *tp,
298 xfs_inode_t *dp, 295 xfs_inode_t *dp,
299 uio_t *uio, /* caller's buffer control */ 296 void *dirent,
300 int *eofp) /* out: eof reached */ 297 size_t bufsize,
298 xfs_off_t *offset,
299 filldir_t filldir)
301{ 300{
302 int alignment; /* alignment required for ABI */
303 xfs_dirent_t *dbp; /* malloc'ed buffer */
304 xfs_dir2_put_t put; /* entry formatting routine */
305 int rval; /* return value */ 301 int rval; /* return value */
306 int v; /* type-checking value */ 302 int v; /* type-checking value */
307 303
304 vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
305
306 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
307 return XFS_ERROR(EIO);
308
308 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 309 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
309 XFS_STATS_INC(xs_dir_getdents); 310 XFS_STATS_INC(xs_dir_getdents);
310 /*
311 * If our caller has given us a single contiguous aligned memory buffer,
312 * just work directly within that buffer. If it's in user memory,
313 * lock it down first.
314 */
315 alignment = sizeof(xfs_off_t) - 1;
316 if ((uio->uio_iovcnt == 1) &&
317 (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) &&
318 ((uio->uio_iov[0].iov_len & alignment) == 0)) {
319 dbp = NULL;
320 put = xfs_dir2_put_dirent64_direct;
321 } else {
322 dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP);
323 put = xfs_dir2_put_dirent64_uio;
324 }
325 311
326 *eofp = 0;
327 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 312 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
328 rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); 313 rval = xfs_dir2_sf_getdents(dp, dirent, offset, filldir);
329 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) 314 else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))
330 ; 315 ;
331 else if (v) 316 else if (v)
332 rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); 317 rval = xfs_dir2_block_getdents(dp, dirent, offset, filldir);
333 else 318 else
334 rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); 319 rval = xfs_dir2_leaf_getdents(dp, dirent, bufsize, offset,
335 if (dbp != NULL) 320 filldir);
336 kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN);
337 return rval; 321 return rval;
338} 322}
339 323
@@ -613,77 +597,6 @@ xfs_dir2_isleaf(
613} 597}
614 598
615/* 599/*
616 * Getdents put routine for 64-bit ABI, direct form.
617 */
618static int
619xfs_dir2_put_dirent64_direct(
620 xfs_dir2_put_args_t *pa)
621{
622 xfs_dirent_t *idbp; /* dirent pointer */
623 iovec_t *iovp; /* io vector */
624 int namelen; /* entry name length */
625 int reclen; /* entry total length */
626 uio_t *uio; /* I/O control */
627
628 namelen = pa->namelen;
629 reclen = DIRENTSIZE(namelen);
630 uio = pa->uio;
631 /*
632 * Won't fit in the remaining space.
633 */
634 if (reclen > uio->uio_resid) {
635 pa->done = 0;
636 return 0;
637 }
638 iovp = uio->uio_iov;
639 idbp = (xfs_dirent_t *)iovp->iov_base;
640 iovp->iov_base = (char *)idbp + reclen;
641 iovp->iov_len -= reclen;
642 uio->uio_resid -= reclen;
643 idbp->d_reclen = reclen;
644 idbp->d_ino = pa->ino;
645 idbp->d_off = pa->cook;
646 idbp->d_name[namelen] = '\0';
647 pa->done = 1;
648 memcpy(idbp->d_name, pa->name, namelen);
649 return 0;
650}
651
652/*
653 * Getdents put routine for 64-bit ABI, uio form.
654 */
655static int
656xfs_dir2_put_dirent64_uio(
657 xfs_dir2_put_args_t *pa)
658{
659 xfs_dirent_t *idbp; /* dirent pointer */
660 int namelen; /* entry name length */
661 int reclen; /* entry total length */
662 int rval; /* return value */
663 uio_t *uio; /* I/O control */
664
665 namelen = pa->namelen;
666 reclen = DIRENTSIZE(namelen);
667 uio = pa->uio;
668 /*
669 * Won't fit in the remaining space.
670 */
671 if (reclen > uio->uio_resid) {
672 pa->done = 0;
673 return 0;
674 }
675 idbp = pa->dbp;
676 idbp->d_reclen = reclen;
677 idbp->d_ino = pa->ino;
678 idbp->d_off = pa->cook;
679 idbp->d_name[namelen] = '\0';
680 memcpy(idbp->d_name, pa->name, namelen);
681 rval = xfs_uio_read((caddr_t)idbp, reclen, uio);
682 pa->done = (rval == 0);
683 return rval;
684}
685
686/*
687 * Remove the given block from the directory. 600 * Remove the given block from the directory.
688 * This routine is used for data and free blocks, leaf/node are done 601 * This routine is used for data and free blocks, leaf/node are done
689 * by xfs_da_shrink_inode. 602 * by xfs_da_shrink_inode.
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 86560b6f794c..b265197e74cf 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -60,21 +60,6 @@ typedef __uint32_t xfs_dir2_db_t;
60typedef xfs_off_t xfs_dir2_off_t; 60typedef xfs_off_t xfs_dir2_off_t;
61 61
62/* 62/*
63 * For getdents, argument struct for put routines.
64 */
65typedef int (*xfs_dir2_put_t)(struct xfs_dir2_put_args *pa);
66typedef struct xfs_dir2_put_args {
67 xfs_off_t cook; /* cookie of (next) entry */
68 xfs_intino_t ino; /* inode number */
69 xfs_dirent_t *dbp; /* buffer pointer */
70 char *name; /* directory entry name */
71 int namelen; /* length of name */
72 int done; /* output: set if value was stored */
73 xfs_dir2_put_t put; /* put function ptr (i/o) */
74 struct uio *uio; /* uio control structure */
75} xfs_dir2_put_args_t;
76
77/*
78 * Generic directory interface routines 63 * Generic directory interface routines
79 */ 64 */
80extern void xfs_dir_startup(void); 65extern void xfs_dir_startup(void);
@@ -92,8 +77,6 @@ extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
92 char *name, int namelen, xfs_ino_t ino, 77 char *name, int namelen, xfs_ino_t ino,
93 xfs_fsblock_t *first, 78 xfs_fsblock_t *first,
94 struct xfs_bmap_free *flist, xfs_extlen_t tot); 79 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, 80extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
98 char *name, int namelen, xfs_ino_t inum, 81 char *name, int namelen, xfs_ino_t inum,
99 xfs_fsblock_t *first, 82 xfs_fsblock_t *first,
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index e4df1aaae2a2..c171767e242a 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -22,6 +22,7 @@
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_ag.h"
25#include "xfs_dir2.h" 26#include "xfs_dir2.h"
26#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
27#include "xfs_mount.h" 28#include "xfs_mount.h"
@@ -432,12 +433,10 @@ xfs_dir2_block_addname(
432 */ 433 */
433int /* error */ 434int /* error */
434xfs_dir2_block_getdents( 435xfs_dir2_block_getdents(
435 xfs_trans_t *tp, /* transaction (NULL) */
436 xfs_inode_t *dp, /* incore inode */ 436 xfs_inode_t *dp, /* incore inode */
437 uio_t *uio, /* caller's buffer control */ 437 void *dirent,
438 int *eofp, /* eof reached? (out) */ 438 xfs_off_t *offset,
439 xfs_dirent_t *dbp, /* caller's buffer */ 439 filldir_t filldir)
440 xfs_dir2_put_t put) /* abi's formatting function */
441{ 440{
442 xfs_dir2_block_t *block; /* directory block structure */ 441 xfs_dir2_block_t *block; /* directory block structure */
443 xfs_dabuf_t *bp; /* buffer for block */ 442 xfs_dabuf_t *bp; /* buffer for block */
@@ -447,31 +446,32 @@ xfs_dir2_block_getdents(
447 char *endptr; /* end of the data entries */ 446 char *endptr; /* end of the data entries */
448 int error; /* error return value */ 447 int error; /* error return value */
449 xfs_mount_t *mp; /* filesystem mount point */ 448 xfs_mount_t *mp; /* filesystem mount point */
450 xfs_dir2_put_args_t p; /* arg package for put rtn */
451 char *ptr; /* current data entry */ 449 char *ptr; /* current data entry */
452 int wantoff; /* starting block offset */ 450 int wantoff; /* starting block offset */
451 xfs_ino_t ino;
452 xfs_off_t cook;
453 453
454 mp = dp->i_mount; 454 mp = dp->i_mount;
455 /* 455 /*
456 * If the block number in the offset is out of range, we're done. 456 * If the block number in the offset is out of range, we're done.
457 */ 457 */
458 if (xfs_dir2_dataptr_to_db(mp, uio->uio_offset) > mp->m_dirdatablk) { 458 if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk) {
459 *eofp = 1;
460 return 0; 459 return 0;
461 } 460 }
462 /* 461 /*
463 * Can't read the block, give up, else get dabuf in bp. 462 * Can't read the block, give up, else get dabuf in bp.
464 */ 463 */
465 if ((error = 464 error = xfs_da_read_buf(NULL, dp, mp->m_dirdatablk, -1,
466 xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { 465 &bp, XFS_DATA_FORK);
466 if (error)
467 return error; 467 return error;
468 } 468
469 ASSERT(bp != NULL); 469 ASSERT(bp != NULL);
470 /* 470 /*
471 * Extract the byte offset we start at from the seek pointer. 471 * Extract the byte offset we start at from the seek pointer.
472 * We'll skip entries before this. 472 * We'll skip entries before this.
473 */ 473 */
474 wantoff = xfs_dir2_dataptr_to_off(mp, uio->uio_offset); 474 wantoff = xfs_dir2_dataptr_to_off(mp, *offset);
475 block = bp->data; 475 block = bp->data;
476 xfs_dir2_data_check(dp, bp); 476 xfs_dir2_data_check(dp, bp);
477 /* 477 /*
@@ -480,9 +480,7 @@ xfs_dir2_block_getdents(
480 btp = xfs_dir2_block_tail_p(mp, block); 480 btp = xfs_dir2_block_tail_p(mp, block);
481 ptr = (char *)block->u; 481 ptr = (char *)block->u;
482 endptr = (char *)xfs_dir2_block_leaf_p(btp); 482 endptr = (char *)xfs_dir2_block_leaf_p(btp);
483 p.dbp = dbp; 483
484 p.put = put;
485 p.uio = uio;
486 /* 484 /*
487 * Loop over the data portion of the block. 485 * Loop over the data portion of the block.
488 * Each object is a real entry (dep) or an unused one (dup). 486 * Each object is a real entry (dep) or an unused one (dup).
@@ -508,33 +506,24 @@ xfs_dir2_block_getdents(
508 */ 506 */
509 if ((char *)dep - (char *)block < wantoff) 507 if ((char *)dep - (char *)block < wantoff)
510 continue; 508 continue;
511 /*
512 * Set up argument structure for put routine.
513 */
514 p.namelen = dep->namelen;
515 509
516 p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 510 cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
517 ptr - (char *)block); 511 ptr - (char *)block);
518 p.ino = be64_to_cpu(dep->inumber); 512 ino = be64_to_cpu(dep->inumber);
519#if XFS_BIG_INUMS 513#if XFS_BIG_INUMS
520 p.ino += mp->m_inoadd; 514 ino += mp->m_inoadd;
521#endif 515#endif
522 p.name = (char *)dep->name;
523
524 /*
525 * Put the entry in the caller's buffer.
526 */
527 error = p.put(&p);
528 516
529 /* 517 /*
530 * If it didn't fit, set the final offset to here & return. 518 * If it didn't fit, set the final offset to here & return.
531 */ 519 */
532 if (!p.done) { 520 if (filldir(dirent, dep->name, dep->namelen, cook,
533 uio->uio_offset = 521 ino, DT_UNKNOWN)) {
534 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 522 *offset = xfs_dir2_db_off_to_dataptr(mp,
523 mp->m_dirdatablk,
535 (char *)dep - (char *)block); 524 (char *)dep - (char *)block);
536 xfs_da_brelse(tp, bp); 525 xfs_da_brelse(NULL, bp);
537 return error; 526 return 0;
538 } 527 }
539 } 528 }
540 529
@@ -542,13 +531,8 @@ xfs_dir2_block_getdents(
542 * Reached the end of the block. 531 * Reached the end of the block.
543 * Set the offset to a non-existent block 1 and return. 532 * Set the offset to a non-existent block 1 and return.
544 */ 533 */
545 *eofp = 1; 534 *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
546 535 xfs_da_brelse(NULL, bp);
547 uio->uio_offset =
548 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
549
550 xfs_da_brelse(tp, bp);
551
552 return 0; 536 return 0;
553} 537}
554 538
diff --git a/fs/xfs/xfs_dir2_block.h b/fs/xfs/xfs_dir2_block.h
index e7c2606161e9..10e689676382 100644
--- a/fs/xfs/xfs_dir2_block.h
+++ b/fs/xfs/xfs_dir2_block.h
@@ -80,9 +80,8 @@ xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp)
80 * Function declarations. 80 * Function declarations.
81 */ 81 */
82extern int xfs_dir2_block_addname(struct xfs_da_args *args); 82extern int xfs_dir2_block_addname(struct xfs_da_args *args);
83extern int xfs_dir2_block_getdents(struct xfs_trans *tp, struct xfs_inode *dp, 83extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
84 struct uio *uio, int *eofp, 84 xfs_off_t *offset, filldir_t filldir);
85 struct xfs_dirent *dbp, xfs_dir2_put_t put);
86extern int xfs_dir2_block_lookup(struct xfs_da_args *args); 85extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
87extern int xfs_dir2_block_removename(struct xfs_da_args *args); 86extern int xfs_dir2_block_removename(struct xfs_da_args *args);
88extern int xfs_dir2_block_replace(struct xfs_da_args *args); 87extern int xfs_dir2_block_replace(struct xfs_da_args *args);
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index 7ebe295bd6d3..d2452699e9b1 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -22,6 +22,7 @@
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_ag.h"
25#include "xfs_dir2.h" 26#include "xfs_dir2.h"
26#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
27#include "xfs_mount.h" 28#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 1b73c9ad646a..e7c12fa1303e 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -749,12 +749,11 @@ xfs_dir2_leaf_compact_x1(
749 */ 749 */
750int /* error */ 750int /* error */
751xfs_dir2_leaf_getdents( 751xfs_dir2_leaf_getdents(
752 xfs_trans_t *tp, /* transaction pointer */
753 xfs_inode_t *dp, /* incore directory inode */ 752 xfs_inode_t *dp, /* incore directory inode */
754 uio_t *uio, /* I/O control & vectors */ 753 void *dirent,
755 int *eofp, /* out: reached end of dir */ 754 size_t bufsize,
756 xfs_dirent_t *dbp, /* caller's buffer */ 755 xfs_off_t *offset,
757 xfs_dir2_put_t put) /* ABI formatting routine */ 756 filldir_t filldir)
758{ 757{
759 xfs_dabuf_t *bp; /* data block buffer */ 758 xfs_dabuf_t *bp; /* data block buffer */
760 int byteoff; /* offset in current block */ 759 int byteoff; /* offset in current block */
@@ -763,7 +762,6 @@ xfs_dir2_leaf_getdents(
763 xfs_dir2_data_t *data; /* data block structure */ 762 xfs_dir2_data_t *data; /* data block structure */
764 xfs_dir2_data_entry_t *dep; /* data entry */ 763 xfs_dir2_data_entry_t *dep; /* data entry */
765 xfs_dir2_data_unused_t *dup; /* unused entry */ 764 xfs_dir2_data_unused_t *dup; /* unused entry */
766 int eof; /* reached end of directory */
767 int error = 0; /* error return value */ 765 int error = 0; /* error return value */
768 int i; /* temporary loop index */ 766 int i; /* temporary loop index */
769 int j; /* temporary loop index */ 767 int j; /* temporary loop index */
@@ -776,46 +774,38 @@ xfs_dir2_leaf_getdents(
776 xfs_mount_t *mp; /* filesystem mount point */ 774 xfs_mount_t *mp; /* filesystem mount point */
777 xfs_dir2_off_t newoff; /* new curoff after new blk */ 775 xfs_dir2_off_t newoff; /* new curoff after new blk */
778 int nmap; /* mappings to ask xfs_bmapi */ 776 int nmap; /* mappings to ask xfs_bmapi */
779 xfs_dir2_put_args_t *p; /* formatting arg bundle */
780 char *ptr = NULL; /* pointer to current data */ 777 char *ptr = NULL; /* pointer to current data */
781 int ra_current; /* number of read-ahead blks */ 778 int ra_current; /* number of read-ahead blks */
782 int ra_index; /* *map index for read-ahead */ 779 int ra_index; /* *map index for read-ahead */
783 int ra_offset; /* map entry offset for ra */ 780 int ra_offset; /* map entry offset for ra */
784 int ra_want; /* readahead count wanted */ 781 int ra_want; /* readahead count wanted */
782 xfs_ino_t ino;
785 783
786 /* 784 /*
787 * If the offset is at or past the largest allowed value, 785 * If the offset is at or past the largest allowed value,
788 * give up right away, return eof. 786 * give up right away.
789 */ 787 */
790 if (uio->uio_offset >= XFS_DIR2_MAX_DATAPTR) { 788 if (*offset >= XFS_DIR2_MAX_DATAPTR)
791 *eofp = 1;
792 return 0; 789 return 0;
793 } 790
794 mp = dp->i_mount; 791 mp = dp->i_mount;
795 /* 792
796 * Setup formatting arguments.
797 */
798 p = kmem_alloc(sizeof(*p), KM_SLEEP);
799 p->dbp = dbp;
800 p->put = put;
801 p->uio = uio;
802 /* 793 /*
803 * Set up to bmap a number of blocks based on the caller's 794 * Set up to bmap a number of blocks based on the caller's
804 * buffer size, the directory block size, and the filesystem 795 * buffer size, the directory block size, and the filesystem
805 * block size. 796 * block size.
806 */ 797 */
807 map_size = 798 map_size = howmany(bufsize + mp->m_dirblksize, mp->m_sb.sb_blocksize);
808 howmany(uio->uio_resid + mp->m_dirblksize,
809 mp->m_sb.sb_blocksize);
810 map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP); 799 map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP);
811 map_valid = ra_index = ra_offset = ra_current = map_blocks = 0; 800 map_valid = ra_index = ra_offset = ra_current = map_blocks = 0;
812 bp = NULL; 801 bp = NULL;
813 eof = 1; 802
814 /* 803 /*
815 * Inside the loop we keep the main offset value as a byte offset 804 * Inside the loop we keep the main offset value as a byte offset
816 * in the directory file. 805 * in the directory file.
817 */ 806 */
818 curoff = xfs_dir2_dataptr_to_byte(mp, uio->uio_offset); 807 curoff = xfs_dir2_dataptr_to_byte(mp, *offset);
808
819 /* 809 /*
820 * Force this conversion through db so we truncate the offset 810 * Force this conversion through db so we truncate the offset
821 * down to get the start of the data block. 811 * down to get the start of the data block.
@@ -836,7 +826,7 @@ xfs_dir2_leaf_getdents(
836 * take it out of the mapping. 826 * take it out of the mapping.
837 */ 827 */
838 if (bp) { 828 if (bp) {
839 xfs_da_brelse(tp, bp); 829 xfs_da_brelse(NULL, bp);
840 bp = NULL; 830 bp = NULL;
841 map_blocks -= mp->m_dirblkfsbs; 831 map_blocks -= mp->m_dirblkfsbs;
842 /* 832 /*
@@ -862,8 +852,9 @@ xfs_dir2_leaf_getdents(
862 /* 852 /*
863 * Recalculate the readahead blocks wanted. 853 * Recalculate the readahead blocks wanted.
864 */ 854 */
865 ra_want = howmany(uio->uio_resid + mp->m_dirblksize, 855 ra_want = howmany(bufsize + mp->m_dirblksize,
866 mp->m_sb.sb_blocksize) - 1; 856 mp->m_sb.sb_blocksize) - 1;
857
867 /* 858 /*
868 * If we don't have as many as we want, and we haven't 859 * If we don't have as many as we want, and we haven't
869 * run out of data blocks, get some more mappings. 860 * run out of data blocks, get some more mappings.
@@ -876,7 +867,7 @@ xfs_dir2_leaf_getdents(
876 * we already have in the table. 867 * we already have in the table.
877 */ 868 */
878 nmap = map_size - map_valid; 869 nmap = map_size - map_valid;
879 error = xfs_bmapi(tp, dp, 870 error = xfs_bmapi(NULL, dp,
880 map_off, 871 map_off,
881 xfs_dir2_byte_to_da(mp, 872 xfs_dir2_byte_to_da(mp,
882 XFS_DIR2_LEAF_OFFSET) - map_off, 873 XFS_DIR2_LEAF_OFFSET) - map_off,
@@ -939,7 +930,7 @@ xfs_dir2_leaf_getdents(
939 * mapping. 930 * mapping.
940 */ 931 */
941 curdb = xfs_dir2_da_to_db(mp, map->br_startoff); 932 curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
942 error = xfs_da_read_buf(tp, dp, map->br_startoff, 933 error = xfs_da_read_buf(NULL, dp, map->br_startoff,
943 map->br_blockcount >= mp->m_dirblkfsbs ? 934 map->br_blockcount >= mp->m_dirblkfsbs ?
944 XFS_FSB_TO_DADDR(mp, map->br_startblock) : 935 XFS_FSB_TO_DADDR(mp, map->br_startblock) :
945 -1, 936 -1,
@@ -982,7 +973,7 @@ xfs_dir2_leaf_getdents(
982 * is a very rare case. 973 * is a very rare case.
983 */ 974 */
984 else if (i > ra_current) { 975 else if (i > ra_current) {
985 (void)xfs_da_reada_buf(tp, dp, 976 (void)xfs_da_reada_buf(NULL, dp,
986 map[ra_index].br_startoff + 977 map[ra_index].br_startoff +
987 ra_offset, XFS_DATA_FORK); 978 ra_offset, XFS_DATA_FORK);
988 ra_current = i; 979 ra_current = i;
@@ -1089,46 +1080,39 @@ xfs_dir2_leaf_getdents(
1089 */ 1080 */
1090 dep = (xfs_dir2_data_entry_t *)ptr; 1081 dep = (xfs_dir2_data_entry_t *)ptr;
1091 1082
1092 p->namelen = dep->namelen; 1083 length = xfs_dir2_data_entsize(dep->namelen);
1093
1094 length = xfs_dir2_data_entsize(p->namelen);
1095
1096 p->cook = xfs_dir2_byte_to_dataptr(mp, curoff + length);
1097 1084
1098 p->ino = be64_to_cpu(dep->inumber); 1085 ino = be64_to_cpu(dep->inumber);
1099#if XFS_BIG_INUMS 1086#if XFS_BIG_INUMS
1100 p->ino += mp->m_inoadd; 1087 ino += mp->m_inoadd;
1101#endif 1088#endif
1102 p->name = (char *)dep->name;
1103
1104 error = p->put(p);
1105 1089
1106 /* 1090 /*
1107 * Won't fit. Return to caller. 1091 * Won't fit. Return to caller.
1108 */ 1092 */
1109 if (!p->done) { 1093 if (filldir(dirent, dep->name, dep->namelen,
1110 eof = 0; 1094 xfs_dir2_byte_to_dataptr(mp, curoff + length),
1095 ino, DT_UNKNOWN))
1111 break; 1096 break;
1112 } 1097
1113 /* 1098 /*
1114 * Advance to next entry in the block. 1099 * Advance to next entry in the block.
1115 */ 1100 */
1116 ptr += length; 1101 ptr += length;
1117 curoff += length; 1102 curoff += length;
1103 bufsize -= length;
1118 } 1104 }
1119 1105
1120 /* 1106 /*
1121 * All done. Set output offset value to current offset. 1107 * All done. Set output offset value to current offset.
1122 */ 1108 */
1123 *eofp = eof;
1124 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) 1109 if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR))
1125 uio->uio_offset = XFS_DIR2_MAX_DATAPTR; 1110 *offset = XFS_DIR2_MAX_DATAPTR;
1126 else 1111 else
1127 uio->uio_offset = xfs_dir2_byte_to_dataptr(mp, curoff); 1112 *offset = xfs_dir2_byte_to_dataptr(mp, curoff);
1128 kmem_free(map, map_size * sizeof(*map)); 1113 kmem_free(map, map_size * sizeof(*map));
1129 kmem_free(p, sizeof(*p));
1130 if (bp) 1114 if (bp)
1131 xfs_da_brelse(tp, bp); 1115 xfs_da_brelse(NULL, bp);
1132 return error; 1116 return error;
1133} 1117}
1134 1118
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
index 70c97f3f815e..6c9539f06987 100644
--- a/fs/xfs/xfs_dir2_leaf.h
+++ b/fs/xfs/xfs_dir2_leaf.h
@@ -232,9 +232,9 @@ extern void xfs_dir2_leaf_compact(struct xfs_da_args *args,
232extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp, 232extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp,
233 int *lowstalep, int *highstalep, 233 int *lowstalep, int *highstalep,
234 int *lowlogp, int *highlogp); 234 int *lowlogp, int *highlogp);
235extern int xfs_dir2_leaf_getdents(struct xfs_trans *tp, struct xfs_inode *dp, 235extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
236 struct uio *uio, int *eofp, 236 size_t bufsize, xfs_off_t *offset,
237 struct xfs_dirent *dbp, xfs_dir2_put_t put); 237 filldir_t filldir);
238extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, 238extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno,
239 struct xfs_dabuf **bpp, int magic); 239 struct xfs_dabuf **bpp, int magic);
240extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp, 240extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp,
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index 91c61d9632c8..eb18e399e836 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -22,6 +22,7 @@
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_ag.h"
25#include "xfs_dir2.h" 26#include "xfs_dir2.h"
26#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
27#include "xfs_mount.h" 28#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index 38fc4f22b76d..182c70315ad1 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -22,6 +22,7 @@
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_ag.h"
25#include "xfs_dir2.h" 26#include "xfs_dir2.h"
26#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
27#include "xfs_mount.h" 28#include "xfs_mount.h"
@@ -695,19 +696,18 @@ xfs_dir2_sf_create(
695int /* error */ 696int /* error */
696xfs_dir2_sf_getdents( 697xfs_dir2_sf_getdents(
697 xfs_inode_t *dp, /* incore directory inode */ 698 xfs_inode_t *dp, /* incore directory inode */
698 uio_t *uio, /* caller's buffer control */ 699 void *dirent,
699 int *eofp, /* eof reached? (out) */ 700 xfs_off_t *offset,
700 xfs_dirent_t *dbp, /* caller's buffer */ 701 filldir_t filldir)
701 xfs_dir2_put_t put) /* abi's formatting function */
702{ 702{
703 int error; /* error return value */
704 int i; /* shortform entry number */ 703 int i; /* shortform entry number */
705 xfs_mount_t *mp; /* filesystem mount point */ 704 xfs_mount_t *mp; /* filesystem mount point */
706 xfs_dir2_dataptr_t off; /* current entry's offset */ 705 xfs_dir2_dataptr_t off; /* current entry's offset */
707 xfs_dir2_put_args_t p; /* arg package for put rtn */
708 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ 706 xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
709 xfs_dir2_sf_t *sfp; /* shortform structure */ 707 xfs_dir2_sf_t *sfp; /* shortform structure */
710 xfs_off_t dir_offset; 708 xfs_dir2_dataptr_t dot_offset;
709 xfs_dir2_dataptr_t dotdot_offset;
710 xfs_ino_t ino;
711 711
712 mp = dp->i_mount; 712 mp = dp->i_mount;
713 713
@@ -720,8 +720,6 @@ xfs_dir2_sf_getdents(
720 return XFS_ERROR(EIO); 720 return XFS_ERROR(EIO);
721 } 721 }
722 722
723 dir_offset = uio->uio_offset;
724
725 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); 723 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
726 ASSERT(dp->i_df.if_u1.if_data != NULL); 724 ASSERT(dp->i_df.if_u1.if_data != NULL);
727 725
@@ -732,108 +730,78 @@ xfs_dir2_sf_getdents(
732 /* 730 /*
733 * If the block number in the offset is out of range, we're done. 731 * If the block number in the offset is out of range, we're done.
734 */ 732 */
735 if (xfs_dir2_dataptr_to_db(mp, dir_offset) > mp->m_dirdatablk) { 733 if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk)
736 *eofp = 1;
737 return 0; 734 return 0;
738 }
739 735
740 /* 736 /*
741 * Set up putargs structure. 737 * Precalculate offsets for . and .. as we will always need them.
738 *
739 * XXX(hch): the second argument is sometimes 0 and sometimes
740 * mp->m_dirdatablk.
742 */ 741 */
743 p.dbp = dbp; 742 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
744 p.put = put; 743 XFS_DIR2_DATA_DOT_OFFSET);
745 p.uio = uio; 744 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
745 XFS_DIR2_DATA_DOTDOT_OFFSET);
746
746 /* 747 /*
747 * Put . entry unless we're starting past it. 748 * Put . entry unless we're starting past it.
748 */ 749 */
749 if (dir_offset <= 750 if (*offset <= dot_offset) {
750 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 751 ino = dp->i_ino;
751 XFS_DIR2_DATA_DOT_OFFSET)) {
752 p.cook = xfs_dir2_db_off_to_dataptr(mp, 0,
753 XFS_DIR2_DATA_DOTDOT_OFFSET);
754 p.ino = dp->i_ino;
755#if XFS_BIG_INUMS 752#if XFS_BIG_INUMS
756 p.ino += mp->m_inoadd; 753 ino += mp->m_inoadd;
757#endif 754#endif
758 p.name = "."; 755 if (filldir(dirent, ".", 1, dotdot_offset, ino, DT_DIR)) {
759 p.namelen = 1; 756 *offset = dot_offset;
760 757 return 0;
761 error = p.put(&p);
762
763 if (!p.done) {
764 uio->uio_offset =
765 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
766 XFS_DIR2_DATA_DOT_OFFSET);
767 return error;
768 } 758 }
769 } 759 }
770 760
771 /* 761 /*
772 * Put .. entry unless we're starting past it. 762 * Put .. entry unless we're starting past it.
773 */ 763 */
774 if (dir_offset <= 764 if (*offset <= dotdot_offset) {
775 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 765 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
776 XFS_DIR2_DATA_DOTDOT_OFFSET)) { 766 XFS_DIR2_DATA_FIRST_OFFSET);
777 p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 767 ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
778 XFS_DIR2_DATA_FIRST_OFFSET);
779 p.ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
780#if XFS_BIG_INUMS 768#if XFS_BIG_INUMS
781 p.ino += mp->m_inoadd; 769 ino += mp->m_inoadd;
782#endif 770#endif
783 p.name = ".."; 771 if (filldir(dirent, "..", 2, off, ino, DT_DIR)) {
784 p.namelen = 2; 772 *offset = dotdot_offset;
785 773 return 0;
786 error = p.put(&p);
787
788 if (!p.done) {
789 uio->uio_offset =
790 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
791 XFS_DIR2_DATA_DOTDOT_OFFSET);
792 return error;
793 } 774 }
794 } 775 }
795 776
796 /* 777 /*
797 * Loop while there are more entries and put'ing works. 778 * Loop while there are more entries and put'ing works.
798 */ 779 */
799 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); 780 sfep = xfs_dir2_sf_firstentry(sfp);
800 i < sfp->hdr.count; 781 for (i = 0; i < sfp->hdr.count; i++) {
801 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
802
803 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 782 off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
804 xfs_dir2_sf_get_offset(sfep)); 783 xfs_dir2_sf_get_offset(sfep));
805 784
806 if (dir_offset > off) 785 if (*offset > off) {
786 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
807 continue; 787 continue;
788 }
808 789
809 p.namelen = sfep->namelen; 790 ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
810
811 p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
812 xfs_dir2_sf_get_offset(sfep) +
813 xfs_dir2_data_entsize(p.namelen));
814
815 p.ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
816#if XFS_BIG_INUMS 791#if XFS_BIG_INUMS
817 p.ino += mp->m_inoadd; 792 ino += mp->m_inoadd;
818#endif 793#endif
819 p.name = (char *)sfep->name;
820
821 error = p.put(&p);
822 794
823 if (!p.done) { 795 if (filldir(dirent, sfep->name, sfep->namelen,
824 uio->uio_offset = off; 796 off + xfs_dir2_data_entsize(sfep->namelen),
825 return error; 797 ino, DT_UNKNOWN)) {
798 *offset = off;
799 return 0;
826 } 800 }
801 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
827 } 802 }
828 803
829 /* 804 *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
830 * They all fit.
831 */
832 *eofp = 1;
833
834 uio->uio_offset =
835 xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0);
836
837 return 0; 805 return 0;
838} 806}
839 807
diff --git a/fs/xfs/xfs_dir2_sf.h b/fs/xfs/xfs_dir2_sf.h
index 11e503209afa..005629d702d2 100644
--- a/fs/xfs/xfs_dir2_sf.h
+++ b/fs/xfs/xfs_dir2_sf.h
@@ -169,9 +169,8 @@ extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp,
169 int size, xfs_dir2_sf_hdr_t *sfhp); 169 int size, xfs_dir2_sf_hdr_t *sfhp);
170extern int xfs_dir2_sf_addname(struct xfs_da_args *args); 170extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
171extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); 171extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
172extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio, 172extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
173 int *eofp, struct xfs_dirent *dbp, 173 xfs_off_t *offset, filldir_t filldir);
174 xfs_dir2_put_t put);
175extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); 174extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
176extern int xfs_dir2_sf_removename(struct xfs_da_args *args); 175extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
177extern int xfs_dir2_sf_replace(struct xfs_da_args *args); 176extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index adc3d251240d..f71784ab6a60 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -67,17 +67,15 @@ typedef enum {
67#define HAVE_DM_RIGHT_T 67#define HAVE_DM_RIGHT_T
68 68
69/* Defines for determining if an event message should be sent. */ 69/* Defines for determining if an event message should be sent. */
70#define DM_EVENT_ENABLED(vfsp, ip, event) ( \ 70#ifdef HAVE_DMAPI
71 unlikely ((vfsp)->vfs_flag & VFS_DMI) && \ 71#define DM_EVENT_ENABLED(ip, event) ( \
72 unlikely ((ip)->i_mount->m_flags & XFS_MOUNT_DMAPI) && \
72 ( ((ip)->i_d.di_dmevmask & (1 << event)) || \ 73 ( ((ip)->i_d.di_dmevmask & (1 << event)) || \
73 ((ip)->i_mount->m_dmevmask & (1 << event)) ) \ 74 ((ip)->i_mount->m_dmevmask & (1 << event)) ) \
74 ) 75 )
75 76#else
76#define DM_EVENT_ENABLED_IO(vfsp, io, event) ( \ 77#define DM_EVENT_ENABLED(ip, event) (0)
77 unlikely ((vfsp)->vfs_flag & VFS_DMI) && \ 78#endif
78 ( ((io)->io_dmevmask & (1 << event)) || \
79 ((io)->io_mount->m_dmevmask & (1 << event)) ) \
80 )
81 79
82#define DM_XFS_VALID_FS_EVENTS ( \ 80#define DM_XFS_VALID_FS_EVENTS ( \
83 (1 << DM_EVENT_PREUNMOUNT) | \ 81 (1 << DM_EVENT_PREUNMOUNT) | \
@@ -170,7 +168,4 @@ typedef enum {
170 DM_FLAGS_NDELAY : 0) 168 DM_FLAGS_NDELAY : 0)
171#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) 169#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
172 170
173
174extern struct bhv_module_vfsops xfs_dmops;
175
176#endif /* __XFS_DMAPI_H__ */ 171#endif /* __XFS_DMAPI_H__ */
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
index 1e4a35ddf7f9..6cd5704258a2 100644
--- a/fs/xfs/xfs_dmops.c
+++ b/fs/xfs/xfs_dmops.c
@@ -19,18 +19,51 @@
19#include "xfs_fs.h" 19#include "xfs_fs.h"
20#include "xfs_types.h" 20#include "xfs_types.h"
21#include "xfs_log.h" 21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h" 22#include "xfs_trans.h"
24#include "xfs_sb.h" 23#include "xfs_sb.h"
25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 24#include "xfs_dmapi.h"
25#include "xfs_inum.h"
26#include "xfs_ag.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
28#include "xfs_clnt.h"
29
29 30
30xfs_dmops_t xfs_dmcore_stub = { 31static struct xfs_dmops xfs_dmcore_stub = {
31 .xfs_send_data = (xfs_send_data_t)fs_nosys, 32 .xfs_send_data = (xfs_send_data_t)fs_nosys,
32 .xfs_send_mmap = (xfs_send_mmap_t)fs_noerr, 33 .xfs_send_mmap = (xfs_send_mmap_t)fs_noerr,
33 .xfs_send_destroy = (xfs_send_destroy_t)fs_nosys, 34 .xfs_send_destroy = (xfs_send_destroy_t)fs_nosys,
34 .xfs_send_namesp = (xfs_send_namesp_t)fs_nosys, 35 .xfs_send_namesp = (xfs_send_namesp_t)fs_nosys,
35 .xfs_send_unmount = (xfs_send_unmount_t)fs_noval, 36 .xfs_send_mount = (xfs_send_mount_t)fs_nosys,
37 .xfs_send_unmount = (xfs_send_unmount_t)fs_noerr,
36}; 38};
39
40int
41xfs_dmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
42{
43 if (args->flags & XFSMNT_DMAPI) {
44 struct xfs_dmops *ops;
45
46 ops = symbol_get(xfs_dmcore_xfs);
47 if (!ops) {
48 request_module("xfs_dmapi");
49 ops = symbol_get(xfs_dmcore_xfs);
50 }
51
52 if (!ops) {
53 cmn_err(CE_WARN, "XFS: no dmapi support available.");
54 return EINVAL;
55 }
56 mp->m_dm_ops = ops;
57 } else {
58 mp->m_dm_ops = &xfs_dmcore_stub;
59 }
60
61 return 0;
62}
63
64void
65xfs_dmops_put(struct xfs_mount *mp)
66{
67 if (mp->m_dm_ops != &xfs_dmcore_stub)
68 symbol_put(xfs_dmcore_xfs);
69}
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index 8c4331631337..a4634d94e561 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -22,6 +22,7 @@
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_ag.h"
25#include "xfs_dir2.h" 26#include "xfs_dir2.h"
26#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
27#include "xfs_mount.h" 28#include "xfs_mount.h"
@@ -132,10 +133,14 @@ xfs_errortag_add(int error_tag, xfs_mount_t *mp)
132} 133}
133 134
134int 135int
135xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud) 136xfs_errortag_clearall(xfs_mount_t *mp, int loud)
136{ 137{
137 int i; 138 int64_t fsid;
138 int cleared = 0; 139 int cleared = 0;
140 int i;
141
142 memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
143
139 144
140 for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) { 145 for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) {
141 if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) && 146 if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) &&
@@ -154,20 +159,10 @@ xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud)
154 if (loud || cleared) 159 if (loud || cleared)
155 cmn_err(CE_WARN, 160 cmn_err(CE_WARN,
156 "Cleared all XFS error tags for filesystem \"%s\"", 161 "Cleared all XFS error tags for filesystem \"%s\"",
157 fsname); 162 mp->m_fsname);
158 163
159 return 0; 164 return 0;
160} 165}
161
162int
163xfs_errortag_clearall(xfs_mount_t *mp)
164{
165 int64_t fsid;
166
167 memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t));
168
169 return xfs_errortag_clearall_umount(fsid, mp->m_fsname, 1);
170}
171#endif /* DEBUG || INDUCE_IO_ERROR */ 166#endif /* DEBUG || INDUCE_IO_ERROR */
172 167
173static void 168static void
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index 5599ada456a1..10e9d9619ae5 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -144,12 +144,11 @@ extern void xfs_error_test_init(void);
144#endif /* __ANSI_CPP__ */ 144#endif /* __ANSI_CPP__ */
145 145
146extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp); 146extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp);
147extern int xfs_errortag_clearall(xfs_mount_t *mp); 147extern int xfs_errortag_clearall(xfs_mount_t *mp, int loud);
148extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud);
149#else 148#else
150#define XFS_TEST_ERROR(expr, mp, tag, rf) (expr) 149#define XFS_TEST_ERROR(expr, mp, tag, rf) (expr)
151#define xfs_errortag_add(tag, mp) (ENOSYS) 150#define xfs_errortag_add(tag, mp) (ENOSYS)
152#define xfs_errortag_clearall(mp) (ENOSYS) 151#define xfs_errortag_clearall(mp, loud) (ENOSYS)
153#endif /* (DEBUG || INDUCE_IO_ERROR) */ 152#endif /* (DEBUG || INDUCE_IO_ERROR) */
154 153
155/* 154/*
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 3b14427ee123..f938a51be81b 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -23,6 +23,7 @@
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_ag.h"
26#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
27#include "xfs_mount.h" 28#include "xfs_mount.h"
28#include "xfs_trans_priv.h" 29#include "xfs_trans_priv.h"
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 432e82347ed6..c92d5b821029 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -136,7 +136,6 @@ xfs_growfs_data_private(
136 xfs_rfsblock_t nfree; 136 xfs_rfsblock_t nfree;
137 xfs_agnumber_t oagcount; 137 xfs_agnumber_t oagcount;
138 int pct; 138 int pct;
139 xfs_sb_t *sbp;
140 xfs_trans_t *tp; 139 xfs_trans_t *tp;
141 140
142 nb = in->newblocks; 141 nb = in->newblocks;
@@ -175,7 +174,7 @@ xfs_growfs_data_private(
175 memset(&mp->m_perag[oagcount], 0, 174 memset(&mp->m_perag[oagcount], 0,
176 (nagcount - oagcount) * sizeof(xfs_perag_t)); 175 (nagcount - oagcount) * sizeof(xfs_perag_t));
177 mp->m_flags |= XFS_MOUNT_32BITINODES; 176 mp->m_flags |= XFS_MOUNT_32BITINODES;
178 nagimax = xfs_initialize_perag(XFS_MTOVFS(mp), mp, nagcount); 177 nagimax = xfs_initialize_perag(mp, nagcount);
179 up_write(&mp->m_peraglock); 178 up_write(&mp->m_peraglock);
180 } 179 }
181 tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS); 180 tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
@@ -377,8 +376,7 @@ xfs_growfs_data_private(
377 error, agno); 376 error, agno);
378 break; 377 break;
379 } 378 }
380 sbp = XFS_BUF_TO_SBP(bp); 379 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS);
381 xfs_xlatesb(sbp, &mp->m_sb, -1, XFS_SB_ALL_BITS);
382 /* 380 /*
383 * If we get an error writing out the alternate superblocks, 381 * If we get an error writing out the alternate superblocks,
384 * just issue a warning and continue. The real work is 382 * just issue a warning and continue. The real work is
@@ -435,10 +433,10 @@ xfs_growfs_data(
435 xfs_growfs_data_t *in) 433 xfs_growfs_data_t *in)
436{ 434{
437 int error; 435 int error;
438 if (!cpsema(&mp->m_growlock)) 436 if (!mutex_trylock(&mp->m_growlock))
439 return XFS_ERROR(EWOULDBLOCK); 437 return XFS_ERROR(EWOULDBLOCK);
440 error = xfs_growfs_data_private(mp, in); 438 error = xfs_growfs_data_private(mp, in);
441 vsema(&mp->m_growlock); 439 mutex_unlock(&mp->m_growlock);
442 return error; 440 return error;
443} 441}
444 442
@@ -448,10 +446,10 @@ xfs_growfs_log(
448 xfs_growfs_log_t *in) 446 xfs_growfs_log_t *in)
449{ 447{
450 int error; 448 int error;
451 if (!cpsema(&mp->m_growlock)) 449 if (!mutex_trylock(&mp->m_growlock))
452 return XFS_ERROR(EWOULDBLOCK); 450 return XFS_ERROR(EWOULDBLOCK);
453 error = xfs_growfs_log_private(mp, in); 451 error = xfs_growfs_log_private(mp, in);
454 vsema(&mp->m_growlock); 452 mutex_unlock(&mp->m_growlock);
455 return error; 453 return error;
456} 454}
457 455
@@ -628,8 +626,7 @@ xfs_fs_goingdown(
628{ 626{
629 switch (inflags) { 627 switch (inflags) {
630 case XFS_FSOP_GOING_FLAGS_DEFAULT: { 628 case XFS_FSOP_GOING_FLAGS_DEFAULT: {
631 struct bhv_vfs *vfsp = XFS_MTOVFS(mp); 629 struct super_block *sb = freeze_bdev(mp->m_super->s_bdev);
632 struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
633 630
634 if (sb && !IS_ERR(sb)) { 631 if (sb && !IS_ERR(sb)) {
635 xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT); 632 xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index f943368c9b93..1409c2d61c11 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -293,9 +293,9 @@ xfs_ialloc_ag_alloc(
293 xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog); 293 xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);
294 for (i = 0; i < ninodes; i++) { 294 for (i = 0; i < ninodes; i++) {
295 free = XFS_MAKE_IPTR(args.mp, fbuf, i); 295 free = XFS_MAKE_IPTR(args.mp, fbuf, i);
296 INT_SET(free->di_core.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC); 296 free->di_core.di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
297 INT_SET(free->di_core.di_version, ARCH_CONVERT, version); 297 free->di_core.di_version = version;
298 INT_SET(free->di_next_unlinked, ARCH_CONVERT, NULLAGINO); 298 free->di_next_unlinked = cpu_to_be32(NULLAGINO);
299 xfs_ialloc_log_di(tp, fbuf, i, 299 xfs_ialloc_log_di(tp, fbuf, i,
300 XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED); 300 XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED);
301 } 301 }
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h
index 97f4040931ca..4e30ec1d13bc 100644
--- a/fs/xfs/xfs_ialloc.h
+++ b/fs/xfs/xfs_ialloc.h
@@ -30,14 +30,9 @@ struct xfs_trans;
30#define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks 30#define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks
31 31
32/* 32/*
33 * For small block file systems, move inodes in clusters of this size. 33 * Move inodes in clusters of this size.
34 * When we don't have a lot of memory, however, we go a bit smaller
35 * to reduce the number of AGI and ialloc btree blocks we need to keep
36 * around for xfs_dilocate(). We choose which one to use in
37 * xfs_mount_int().
38 */ 34 */
39#define XFS_INODE_BIG_CLUSTER_SIZE 8192 35#define XFS_INODE_BIG_CLUSTER_SIZE 8192
40#define XFS_INODE_SMALL_CLUSTER_SIZE 4096
41#define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size 36#define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size
42 37
43/* 38/*
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 114433a22baa..488836e204a3 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -40,131 +40,13 @@
40#include "xfs_utils.h" 40#include "xfs_utils.h"
41 41
42/* 42/*
43 * Initialize the inode hash table for the newly mounted file system.
44 * Choose an initial table size based on user specified value, else
45 * use a simple algorithm using the maximum number of inodes as an
46 * indicator for table size, and clamp it between one and some large
47 * number of pages.
48 */
49void
50xfs_ihash_init(xfs_mount_t *mp)
51{
52 __uint64_t icount;
53 uint i;
54
55 if (!mp->m_ihsize) {
56 icount = mp->m_maxicount ? mp->m_maxicount :
57 (mp->m_sb.sb_dblocks << mp->m_sb.sb_inopblog);
58 mp->m_ihsize = 1 << max_t(uint, 8,
59 (xfs_highbit64(icount) + 1) / 2);
60 mp->m_ihsize = min_t(uint, mp->m_ihsize,
61 (64 * NBPP) / sizeof(xfs_ihash_t));
62 }
63
64 mp->m_ihash = kmem_zalloc_greedy(&mp->m_ihsize,
65 NBPC * sizeof(xfs_ihash_t),
66 mp->m_ihsize * sizeof(xfs_ihash_t),
67 KM_SLEEP | KM_MAYFAIL | KM_LARGE);
68 mp->m_ihsize /= sizeof(xfs_ihash_t);
69 for (i = 0; i < mp->m_ihsize; i++)
70 rwlock_init(&(mp->m_ihash[i].ih_lock));
71}
72
73/*
74 * Free up structures allocated by xfs_ihash_init, at unmount time.
75 */
76void
77xfs_ihash_free(xfs_mount_t *mp)
78{
79 kmem_free(mp->m_ihash, mp->m_ihsize * sizeof(xfs_ihash_t));
80 mp->m_ihash = NULL;
81}
82
83/*
84 * Initialize the inode cluster hash table for the newly mounted file system.
85 * Its size is derived from the ihash table size.
86 */
87void
88xfs_chash_init(xfs_mount_t *mp)
89{
90 uint i;
91
92 mp->m_chsize = max_t(uint, 1, mp->m_ihsize /
93 (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog));
94 mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize);
95 mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize
96 * sizeof(xfs_chash_t),
97 KM_SLEEP | KM_LARGE);
98 for (i = 0; i < mp->m_chsize; i++) {
99 spinlock_init(&mp->m_chash[i].ch_lock,"xfshash");
100 }
101}
102
103/*
104 * Free up structures allocated by xfs_chash_init, at unmount time.
105 */
106void
107xfs_chash_free(xfs_mount_t *mp)
108{
109 int i;
110
111 for (i = 0; i < mp->m_chsize; i++) {
112 spinlock_destroy(&mp->m_chash[i].ch_lock);
113 }
114
115 kmem_free(mp->m_chash, mp->m_chsize*sizeof(xfs_chash_t));
116 mp->m_chash = NULL;
117}
118
119/*
120 * Try to move an inode to the front of its hash list if possible
121 * (and if its not there already). Called right after obtaining
122 * the list version number and then dropping the read_lock on the
123 * hash list in question (which is done right after looking up the
124 * inode in question...).
125 */
126STATIC void
127xfs_ihash_promote(
128 xfs_ihash_t *ih,
129 xfs_inode_t *ip,
130 ulong version)
131{
132 xfs_inode_t *iq;
133
134 if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) {
135 if (likely(version == ih->ih_version)) {
136 /* remove from list */
137 if ((iq = ip->i_next)) {
138 iq->i_prevp = ip->i_prevp;
139 }
140 *ip->i_prevp = iq;
141
142 /* insert at list head */
143 iq = ih->ih_next;
144 iq->i_prevp = &ip->i_next;
145 ip->i_next = iq;
146 ip->i_prevp = &ih->ih_next;
147 ih->ih_next = ip;
148 }
149 write_unlock(&ih->ih_lock);
150 }
151}
152
153/*
154 * Look up an inode by number in the given file system. 43 * Look up an inode by number in the given file system.
155 * The inode is looked up in the hash table for the file system 44 * The inode is looked up in the cache held in each AG.
156 * represented by the mount point parameter mp. Each bucket of 45 * If the inode is found in the cache, attach it to the provided
157 * the hash table is guarded by an individual semaphore. 46 * vnode.
158 *
159 * If the inode is found in the hash table, its corresponding vnode
160 * is obtained with a call to vn_get(). This call takes care of
161 * coordination with the reclamation of the inode and vnode. Note
162 * that the vmap structure is filled in while holding the hash lock.
163 * This gives us the state of the inode/vnode when we found it and
164 * is used for coordination in vn_get().
165 * 47 *
166 * If it is not in core, read it in from the file system's device and 48 * If it is not in core, read it in from the file system's device,
167 * add the inode into the hash table. 49 * add it to the cache and attach the provided vnode.
168 * 50 *
169 * The inode is locked according to the value of the lock_flags parameter. 51 * The inode is locked according to the value of the lock_flags parameter.
170 * This flag parameter indicates how and if the inode's IO lock and inode lock 52 * This flag parameter indicates how and if the inode's IO lock and inode lock
@@ -192,274 +74,241 @@ xfs_iget_core(
192 xfs_inode_t **ipp, 74 xfs_inode_t **ipp,
193 xfs_daddr_t bno) 75 xfs_daddr_t bno)
194{ 76{
195 xfs_ihash_t *ih;
196 xfs_inode_t *ip; 77 xfs_inode_t *ip;
197 xfs_inode_t *iq; 78 xfs_inode_t *iq;
198 bhv_vnode_t *inode_vp; 79 bhv_vnode_t *inode_vp;
199 ulong version;
200 int error; 80 int error;
201 /* REFERENCED */ 81 xfs_icluster_t *icl, *new_icl = NULL;
202 xfs_chash_t *ch; 82 unsigned long first_index, mask;
203 xfs_chashlist_t *chl, *chlnew; 83 xfs_perag_t *pag;
204 SPLDECL(s); 84 xfs_agino_t agino;
85
86 /* the radix tree exists only in inode capable AGs */
87 if (XFS_INO_TO_AGNO(mp, ino) >= mp->m_maxagi)
88 return EINVAL;
89
90 /* get the perag structure and ensure that it's inode capable */
91 pag = xfs_get_perag(mp, ino);
92 if (!pag->pagi_inodeok)
93 return EINVAL;
94 ASSERT(pag->pag_ici_init);
95 agino = XFS_INO_TO_AGINO(mp, ino);
205 96
97again:
98 read_lock(&pag->pag_ici_lock);
99 ip = radix_tree_lookup(&pag->pag_ici_root, agino);
206 100
207 ih = XFS_IHASH(mp, ino); 101 if (ip != NULL) {
102 /*
103 * If INEW is set this inode is being set up
104 * we need to pause and try again.
105 */
106 if (xfs_iflags_test(ip, XFS_INEW)) {
107 read_unlock(&pag->pag_ici_lock);
108 delay(1);
109 XFS_STATS_INC(xs_ig_frecycle);
208 110
209again: 111 goto again;
210 read_lock(&ih->ih_lock); 112 }
211 113
212 for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) { 114 inode_vp = XFS_ITOV_NULL(ip);
213 if (ip->i_ino == ino) { 115 if (inode_vp == NULL) {
214 /* 116 /*
215 * If INEW is set this inode is being set up 117 * If IRECLAIM is set this inode is
118 * on its way out of the system,
216 * we need to pause and try again. 119 * we need to pause and try again.
217 */ 120 */
218 if (xfs_iflags_test(ip, XFS_INEW)) { 121 if (xfs_iflags_test(ip, XFS_IRECLAIM)) {
219 read_unlock(&ih->ih_lock); 122 read_unlock(&pag->pag_ici_lock);
220 delay(1); 123 delay(1);
221 XFS_STATS_INC(xs_ig_frecycle); 124 XFS_STATS_INC(xs_ig_frecycle);
222 125
223 goto again; 126 goto again;
224 } 127 }
128 ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE));
225 129
226 inode_vp = XFS_ITOV_NULL(ip); 130 /*
227 if (inode_vp == NULL) { 131 * If lookup is racing with unlink, then we
228 /* 132 * should return an error immediately so we
229 * If IRECLAIM is set this inode is 133 * don't remove it from the reclaim list and
230 * on its way out of the system, 134 * potentially leak the inode.
231 * we need to pause and try again. 135 */
232 */ 136 if ((ip->i_d.di_mode == 0) &&
233 if (xfs_iflags_test(ip, XFS_IRECLAIM)) { 137 !(flags & XFS_IGET_CREATE)) {
234 read_unlock(&ih->ih_lock); 138 read_unlock(&pag->pag_ici_lock);
235 delay(1); 139 xfs_put_perag(mp, pag);
236 XFS_STATS_INC(xs_ig_frecycle); 140 return ENOENT;
237 141 }
238 goto again; 142
239 } 143 /*
240 ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE)); 144 * There may be transactions sitting in the
241 145 * incore log buffers or being flushed to disk
242 /* 146 * at this time. We can't clear the
243 * If lookup is racing with unlink, then we 147 * XFS_IRECLAIMABLE flag until these
244 * should return an error immediately so we 148 * transactions have hit the disk, otherwise we
245 * don't remove it from the reclaim list and 149 * will void the guarantee the flag provides
246 * potentially leak the inode. 150 * xfs_iunpin()
247 */ 151 */
248 if ((ip->i_d.di_mode == 0) && 152 if (xfs_ipincount(ip)) {
249 !(flags & XFS_IGET_CREATE)) { 153 read_unlock(&pag->pag_ici_lock);
250 read_unlock(&ih->ih_lock); 154 xfs_log_force(mp, 0,
251 return ENOENT; 155 XFS_LOG_FORCE|XFS_LOG_SYNC);
252 } 156 XFS_STATS_INC(xs_ig_frecycle);
253 157 goto again;
254 /* 158 }
255 * There may be transactions sitting in the
256 * incore log buffers or being flushed to disk
257 * at this time. We can't clear the
258 * XFS_IRECLAIMABLE flag until these
259 * transactions have hit the disk, otherwise we
260 * will void the guarantee the flag provides
261 * xfs_iunpin()
262 */
263 if (xfs_ipincount(ip)) {
264 read_unlock(&ih->ih_lock);
265 xfs_log_force(mp, 0,
266 XFS_LOG_FORCE|XFS_LOG_SYNC);
267 XFS_STATS_INC(xs_ig_frecycle);
268 goto again;
269 }
270
271 vn_trace_exit(vp, "xfs_iget.alloc",
272 (inst_t *)__return_address);
273 159
274 XFS_STATS_INC(xs_ig_found); 160 vn_trace_exit(ip, "xfs_iget.alloc",
161 (inst_t *)__return_address);
275 162
276 xfs_iflags_clear(ip, XFS_IRECLAIMABLE); 163 XFS_STATS_INC(xs_ig_found);
277 version = ih->ih_version;
278 read_unlock(&ih->ih_lock);
279 xfs_ihash_promote(ih, ip, version);
280 164
281 XFS_MOUNT_ILOCK(mp); 165 xfs_iflags_clear(ip, XFS_IRECLAIMABLE);
282 list_del_init(&ip->i_reclaim); 166 read_unlock(&pag->pag_ici_lock);
283 XFS_MOUNT_IUNLOCK(mp);
284 167
285 goto finish_inode; 168 XFS_MOUNT_ILOCK(mp);
169 list_del_init(&ip->i_reclaim);
170 XFS_MOUNT_IUNLOCK(mp);
286 171
287 } else if (vp != inode_vp) { 172 goto finish_inode;
288 struct inode *inode = vn_to_inode(inode_vp);
289 173
290 /* The inode is being torn down, pause and 174 } else if (vp != inode_vp) {
291 * try again. 175 struct inode *inode = vn_to_inode(inode_vp);
292 */
293 if (inode->i_state & (I_FREEING | I_CLEAR)) {
294 read_unlock(&ih->ih_lock);
295 delay(1);
296 XFS_STATS_INC(xs_ig_frecycle);
297 176
298 goto again; 177 /* The inode is being torn down, pause and
299 } 178 * try again.
300/* Chances are the other vnode (the one in the inode) is being torn 179 */
301 * down right now, and we landed on top of it. Question is, what do 180 if (inode->i_state & (I_FREEING | I_CLEAR)) {
302 * we do? Unhook the old inode and hook up the new one? 181 read_unlock(&pag->pag_ici_lock);
303 */ 182 delay(1);
304 cmn_err(CE_PANIC, 183 XFS_STATS_INC(xs_ig_frecycle);
305 "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p", 184
306 inode_vp, vp); 185 goto again;
307 } 186 }
187/* Chances are the other vnode (the one in the inode) is being torn
188* down right now, and we landed on top of it. Question is, what do
189* we do? Unhook the old inode and hook up the new one?
190*/
191 cmn_err(CE_PANIC,
192 "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p",
193 inode_vp, vp);
194 }
308 195
309 /* 196 /*
310 * Inode cache hit: if ip is not at the front of 197 * Inode cache hit
311 * its hash chain, move it there now. 198 */
312 * Do this with the lock held for update, but 199 read_unlock(&pag->pag_ici_lock);
313 * do statistics after releasing the lock. 200 XFS_STATS_INC(xs_ig_found);
314 */
315 version = ih->ih_version;
316 read_unlock(&ih->ih_lock);
317 xfs_ihash_promote(ih, ip, version);
318 XFS_STATS_INC(xs_ig_found);
319 201
320finish_inode: 202finish_inode:
321 if (ip->i_d.di_mode == 0) { 203 if (ip->i_d.di_mode == 0) {
322 if (!(flags & XFS_IGET_CREATE)) 204 if (!(flags & XFS_IGET_CREATE)) {
323 return ENOENT; 205 xfs_put_perag(mp, pag);
324 xfs_iocore_inode_reinit(ip); 206 return ENOENT;
325 } 207 }
208 xfs_iocore_inode_reinit(ip);
209 }
326 210
327 if (lock_flags != 0) 211 if (lock_flags != 0)
328 xfs_ilock(ip, lock_flags); 212 xfs_ilock(ip, lock_flags);
329 213
330 xfs_iflags_clear(ip, XFS_ISTALE); 214 xfs_iflags_clear(ip, XFS_ISTALE);
331 vn_trace_exit(vp, "xfs_iget.found", 215 vn_trace_exit(ip, "xfs_iget.found",
332 (inst_t *)__return_address); 216 (inst_t *)__return_address);
333 goto return_ip; 217 goto return_ip;
334 }
335 } 218 }
336 219
337 /* 220 /*
338 * Inode cache miss: save the hash chain version stamp and unlock 221 * Inode cache miss
339 * the chain, so we don't deadlock in vn_alloc.
340 */ 222 */
223 read_unlock(&pag->pag_ici_lock);
341 XFS_STATS_INC(xs_ig_missed); 224 XFS_STATS_INC(xs_ig_missed);
342 225
343 version = ih->ih_version;
344
345 read_unlock(&ih->ih_lock);
346
347 /* 226 /*
348 * Read the disk inode attributes into a new inode structure and get 227 * Read the disk inode attributes into a new inode structure and get
349 * a new vnode for it. This should also initialize i_ino and i_mount. 228 * a new vnode for it. This should also initialize i_ino and i_mount.
350 */ 229 */
351 error = xfs_iread(mp, tp, ino, &ip, bno, 230 error = xfs_iread(mp, tp, ino, &ip, bno,
352 (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0); 231 (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0);
353 if (error) 232 if (error) {
233 xfs_put_perag(mp, pag);
354 return error; 234 return error;
235 }
355 236
356 vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address); 237 vn_trace_exit(ip, "xfs_iget.alloc", (inst_t *)__return_address);
357 238
358 xfs_inode_lock_init(ip, vp); 239 xfs_inode_lock_init(ip, vp);
359 xfs_iocore_inode_init(ip); 240 xfs_iocore_inode_init(ip);
360
361 if (lock_flags) 241 if (lock_flags)
362 xfs_ilock(ip, lock_flags); 242 xfs_ilock(ip, lock_flags);
363 243
364 if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { 244 if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
365 xfs_idestroy(ip); 245 xfs_idestroy(ip);
246 xfs_put_perag(mp, pag);
366 return ENOENT; 247 return ENOENT;
367 } 248 }
368 249
369 /* 250 /*
370 * Put ip on its hash chain, unless someone else hashed a duplicate 251 * This is a bit messy - we preallocate everything we _might_
371 * after we released the hash lock. 252 * need before we pick up the ici lock. That way we don't have to
253 * juggle locks and go all the way back to the start.
372 */ 254 */
373 write_lock(&ih->ih_lock); 255 new_icl = kmem_zone_alloc(xfs_icluster_zone, KM_SLEEP);
256 if (radix_tree_preload(GFP_KERNEL)) {
257 delay(1);
258 goto again;
259 }
260 mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
261 first_index = agino & mask;
262 write_lock(&pag->pag_ici_lock);
374 263
375 if (ih->ih_version != version) { 264 /*
376 for (iq = ih->ih_next; iq != NULL; iq = iq->i_next) { 265 * Find the cluster if it exists
377 if (iq->i_ino == ino) { 266 */
378 write_unlock(&ih->ih_lock); 267 icl = NULL;
379 xfs_idestroy(ip); 268 if (radix_tree_gang_lookup(&pag->pag_ici_root, (void**)&iq,
269 first_index, 1)) {
270 if ((iq->i_ino & mask) == first_index)
271 icl = iq->i_cluster;
272 }
380 273
381 XFS_STATS_INC(xs_ig_dup); 274 /*
382 goto again; 275 * insert the new inode
383 } 276 */
384 } 277 error = radix_tree_insert(&pag->pag_ici_root, agino, ip);
278 if (unlikely(error)) {
279 BUG_ON(error != -EEXIST);
280 write_unlock(&pag->pag_ici_lock);
281 radix_tree_preload_end();
282 xfs_idestroy(ip);
283 XFS_STATS_INC(xs_ig_dup);
284 goto again;
385 } 285 }
386 286
387 /* 287 /*
388 * These values _must_ be set before releasing ihlock! 288 * These values _must_ be set before releasing ihlock!
389 */ 289 */
390 ip->i_hash = ih;
391 if ((iq = ih->ih_next)) {
392 iq->i_prevp = &ip->i_next;
393 }
394 ip->i_next = iq;
395 ip->i_prevp = &ih->ih_next;
396 ih->ih_next = ip;
397 ip->i_udquot = ip->i_gdquot = NULL; 290 ip->i_udquot = ip->i_gdquot = NULL;
398 ih->ih_version++;
399 xfs_iflags_set(ip, XFS_INEW); 291 xfs_iflags_set(ip, XFS_INEW);
400 write_unlock(&ih->ih_lock);
401 292
402 /* 293 ASSERT(ip->i_cluster == NULL);
403 * put ip on its cluster's hash chain
404 */
405 ASSERT(ip->i_chash == NULL && ip->i_cprev == NULL &&
406 ip->i_cnext == NULL);
407
408 chlnew = NULL;
409 ch = XFS_CHASH(mp, ip->i_blkno);
410 chlredo:
411 s = mutex_spinlock(&ch->ch_lock);
412 for (chl = ch->ch_list; chl != NULL; chl = chl->chl_next) {
413 if (chl->chl_blkno == ip->i_blkno) {
414
415 /* insert this inode into the doubly-linked list
416 * where chl points */
417 if ((iq = chl->chl_ip)) {
418 ip->i_cprev = iq->i_cprev;
419 iq->i_cprev->i_cnext = ip;
420 iq->i_cprev = ip;
421 ip->i_cnext = iq;
422 } else {
423 ip->i_cnext = ip;
424 ip->i_cprev = ip;
425 }
426 chl->chl_ip = ip;
427 ip->i_chash = chl;
428 break;
429 }
430 }
431 294
432 /* no hash list found for this block; add a new hash list */ 295 if (!icl) {
433 if (chl == NULL) { 296 spin_lock_init(&new_icl->icl_lock);
434 if (chlnew == NULL) { 297 INIT_HLIST_HEAD(&new_icl->icl_inodes);
435 mutex_spinunlock(&ch->ch_lock, s); 298 icl = new_icl;
436 ASSERT(xfs_chashlist_zone != NULL); 299 new_icl = NULL;
437 chlnew = (xfs_chashlist_t *)
438 kmem_zone_alloc(xfs_chashlist_zone,
439 KM_SLEEP);
440 ASSERT(chlnew != NULL);
441 goto chlredo;
442 } else {
443 ip->i_cnext = ip;
444 ip->i_cprev = ip;
445 ip->i_chash = chlnew;
446 chlnew->chl_ip = ip;
447 chlnew->chl_blkno = ip->i_blkno;
448 if (ch->ch_list)
449 ch->ch_list->chl_prev = chlnew;
450 chlnew->chl_next = ch->ch_list;
451 chlnew->chl_prev = NULL;
452 ch->ch_list = chlnew;
453 chlnew = NULL;
454 }
455 } else { 300 } else {
456 if (chlnew != NULL) { 301 ASSERT(!hlist_empty(&icl->icl_inodes));
457 kmem_zone_free(xfs_chashlist_zone, chlnew);
458 }
459 } 302 }
303 spin_lock(&icl->icl_lock);
304 hlist_add_head(&ip->i_cnode, &icl->icl_inodes);
305 ip->i_cluster = icl;
306 spin_unlock(&icl->icl_lock);
460 307
461 mutex_spinunlock(&ch->ch_lock, s); 308 write_unlock(&pag->pag_ici_lock);
462 309 radix_tree_preload_end();
310 if (new_icl)
311 kmem_zone_free(xfs_icluster_zone, new_icl);
463 312
464 /* 313 /*
465 * Link ip to its mount and thread it on the mount's inode list. 314 * Link ip to its mount and thread it on the mount's inode list.
@@ -478,6 +327,7 @@ finish_inode:
478 mp->m_inodes = ip; 327 mp->m_inodes = ip;
479 328
480 XFS_MOUNT_IUNLOCK(mp); 329 XFS_MOUNT_IUNLOCK(mp);
330 xfs_put_perag(mp, pag);
481 331
482 return_ip: 332 return_ip:
483 ASSERT(ip->i_df.if_ext_max == 333 ASSERT(ip->i_df.if_ext_max ==
@@ -486,14 +336,14 @@ finish_inode:
486 ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) == 336 ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) ==
487 ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0)); 337 ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0));
488 338
339 xfs_iflags_set(ip, XFS_IMODIFIED);
489 *ipp = ip; 340 *ipp = ip;
490 341
491 /* 342 /*
492 * If we have a real type for an on-disk inode, we can set ops(&unlock) 343 * If we have a real type for an on-disk inode, we can set ops(&unlock)
493 * now. If it's a new inode being created, xfs_ialloc will handle it. 344 * now. If it's a new inode being created, xfs_ialloc will handle it.
494 */ 345 */
495 bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1); 346 xfs_initialize_vnode(mp, vp, ip);
496
497 return 0; 347 return 0;
498} 348}
499 349
@@ -519,7 +369,8 @@ xfs_iget(
519 XFS_STATS_INC(xs_ig_attempts); 369 XFS_STATS_INC(xs_ig_attempts);
520 370
521retry: 371retry:
522 if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) { 372 inode = iget_locked(mp->m_super, ino);
373 if (inode) {
523 xfs_inode_t *ip; 374 xfs_inode_t *ip;
524 375
525 vp = vn_from_inode(inode); 376 vp = vn_from_inode(inode);
@@ -570,8 +421,8 @@ xfs_inode_lock_init(
570 bhv_vnode_t *vp) 421 bhv_vnode_t *vp)
571{ 422{
572 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, 423 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
573 "xfsino", (long)vp->v_number); 424 "xfsino", ip->i_ino);
574 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number); 425 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
575 init_waitqueue_head(&ip->i_ipin_wait); 426 init_waitqueue_head(&ip->i_ipin_wait);
576 atomic_set(&ip->i_pincount, 0); 427 atomic_set(&ip->i_pincount, 0);
577 initnsema(&ip->i_flock, 1, "xfsfino"); 428 initnsema(&ip->i_flock, 1, "xfsfino");
@@ -587,32 +438,19 @@ xfs_inode_incore(xfs_mount_t *mp,
587 xfs_ino_t ino, 438 xfs_ino_t ino,
588 xfs_trans_t *tp) 439 xfs_trans_t *tp)
589{ 440{
590 xfs_ihash_t *ih;
591 xfs_inode_t *ip; 441 xfs_inode_t *ip;
592 ulong version; 442 xfs_perag_t *pag;
593 443
594 ih = XFS_IHASH(mp, ino); 444 pag = xfs_get_perag(mp, ino);
595 read_lock(&ih->ih_lock); 445 read_lock(&pag->pag_ici_lock);
596 for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) { 446 ip = radix_tree_lookup(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ino));
597 if (ip->i_ino == ino) { 447 read_unlock(&pag->pag_ici_lock);
598 /* 448 xfs_put_perag(mp, pag);
599 * If we find it and tp matches, return it. 449
600 * Also move it to the front of the hash list 450 /* the returned inode must match the transaction */
601 * if we find it and it is not already there. 451 if (ip && (ip->i_transp != tp))
602 * Otherwise break from the loop and return 452 return NULL;
603 * NULL. 453 return ip;
604 */
605 if (ip->i_transp == tp) {
606 version = ih->ih_version;
607 read_unlock(&ih->ih_lock);
608 xfs_ihash_promote(ih, ip, version);
609 return (ip);
610 }
611 break;
612 }
613 }
614 read_unlock(&ih->ih_lock);
615 return (NULL);
616} 454}
617 455
618/* 456/*
@@ -629,7 +467,7 @@ xfs_iput(xfs_inode_t *ip,
629{ 467{
630 bhv_vnode_t *vp = XFS_ITOV(ip); 468 bhv_vnode_t *vp = XFS_ITOV(ip);
631 469
632 vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address); 470 vn_trace_entry(ip, "xfs_iput", (inst_t *)__return_address);
633 xfs_iunlock(ip, lock_flags); 471 xfs_iunlock(ip, lock_flags);
634 VN_RELE(vp); 472 VN_RELE(vp);
635} 473}
@@ -644,7 +482,7 @@ xfs_iput_new(xfs_inode_t *ip,
644 bhv_vnode_t *vp = XFS_ITOV(ip); 482 bhv_vnode_t *vp = XFS_ITOV(ip);
645 struct inode *inode = vn_to_inode(vp); 483 struct inode *inode = vn_to_inode(vp);
646 484
647 vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); 485 vn_trace_entry(ip, "xfs_iput_new", (inst_t *)__return_address);
648 486
649 if ((ip->i_d.di_mode == 0)) { 487 if ((ip->i_d.di_mode == 0)) {
650 ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); 488 ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
@@ -699,7 +537,8 @@ xfs_ireclaim(xfs_inode_t *ip)
699 */ 537 */
700 vp = XFS_ITOV_NULL(ip); 538 vp = XFS_ITOV_NULL(ip);
701 if (vp) { 539 if (vp) {
702 vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); 540 vn_to_inode(vp)->i_private = NULL;
541 ip->i_vnode = NULL;
703 } 542 }
704 543
705 /* 544 /*
@@ -718,58 +557,26 @@ void
718xfs_iextract( 557xfs_iextract(
719 xfs_inode_t *ip) 558 xfs_inode_t *ip)
720{ 559{
721 xfs_ihash_t *ih; 560 xfs_mount_t *mp = ip->i_mount;
561 xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino);
722 xfs_inode_t *iq; 562 xfs_inode_t *iq;
723 xfs_mount_t *mp; 563
724 xfs_chash_t *ch; 564 write_lock(&pag->pag_ici_lock);
725 xfs_chashlist_t *chl, *chm; 565 radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ip->i_ino));
726 SPLDECL(s); 566 write_unlock(&pag->pag_ici_lock);
727 567 xfs_put_perag(mp, pag);
728 ih = ip->i_hash;
729 write_lock(&ih->ih_lock);
730 if ((iq = ip->i_next)) {
731 iq->i_prevp = ip->i_prevp;
732 }
733 *ip->i_prevp = iq;
734 ih->ih_version++;
735 write_unlock(&ih->ih_lock);
736 568
737 /* 569 /*
738 * Remove from cluster hash list 570 * Remove from cluster list
739 * 1) delete the chashlist if this is the last inode on the chashlist
740 * 2) unchain from list of inodes
741 * 3) point chashlist->chl_ip to 'chl_next' if to this inode.
742 */ 571 */
743 mp = ip->i_mount; 572 mp = ip->i_mount;
744 ch = XFS_CHASH(mp, ip->i_blkno); 573 spin_lock(&ip->i_cluster->icl_lock);
745 s = mutex_spinlock(&ch->ch_lock); 574 hlist_del(&ip->i_cnode);
746 575 spin_unlock(&ip->i_cluster->icl_lock);
747 if (ip->i_cnext == ip) { 576
748 /* Last inode on chashlist */ 577 /* was last inode in cluster? */
749 ASSERT(ip->i_cnext == ip && ip->i_cprev == ip); 578 if (hlist_empty(&ip->i_cluster->icl_inodes))
750 ASSERT(ip->i_chash != NULL); 579 kmem_zone_free(xfs_icluster_zone, ip->i_cluster);
751 chm=NULL;
752 chl = ip->i_chash;
753 if (chl->chl_prev)
754 chl->chl_prev->chl_next = chl->chl_next;
755 else
756 ch->ch_list = chl->chl_next;
757 if (chl->chl_next)
758 chl->chl_next->chl_prev = chl->chl_prev;
759 kmem_zone_free(xfs_chashlist_zone, chl);
760 } else {
761 /* delete one inode from a non-empty list */
762 iq = ip->i_cnext;
763 iq->i_cprev = ip->i_cprev;
764 ip->i_cprev->i_cnext = iq;
765 if (ip->i_chash->chl_ip == ip) {
766 ip->i_chash->chl_ip = iq;
767 }
768 ip->i_chash = __return_address;
769 ip->i_cprev = __return_address;
770 ip->i_cnext = __return_address;
771 }
772 mutex_spinunlock(&ch->ch_lock, s);
773 580
774 /* 581 /*
775 * Remove from mount's inode list. 582 * Remove from mount's inode list.
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index cdc4c28926d0..abf509a88915 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -49,12 +49,11 @@
49#include "xfs_quota.h" 49#include "xfs_quota.h"
50#include "xfs_acl.h" 50#include "xfs_acl.h"
51#include "xfs_filestream.h" 51#include "xfs_filestream.h"
52 52#include "xfs_vnodeops.h"
53#include <linux/log2.h>
54 53
55kmem_zone_t *xfs_ifork_zone; 54kmem_zone_t *xfs_ifork_zone;
56kmem_zone_t *xfs_inode_zone; 55kmem_zone_t *xfs_inode_zone;
57kmem_zone_t *xfs_chashlist_zone; 56kmem_zone_t *xfs_icluster_zone;
58 57
59/* 58/*
60 * Used in xfs_itruncate(). This is the maximum number of extents 59 * Used in xfs_itruncate(). This is the maximum number of extents
@@ -67,7 +66,6 @@ STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int);
67STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); 66STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
68STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); 67STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
69 68
70
71#ifdef DEBUG 69#ifdef DEBUG
72/* 70/*
73 * Make sure that the extents in the given memory buffer 71 * Make sure that the extents in the given memory buffer
@@ -77,28 +75,23 @@ STATIC void
77xfs_validate_extents( 75xfs_validate_extents(
78 xfs_ifork_t *ifp, 76 xfs_ifork_t *ifp,
79 int nrecs, 77 int nrecs,
80 int disk,
81 xfs_exntfmt_t fmt) 78 xfs_exntfmt_t fmt)
82{ 79{
83 xfs_bmbt_rec_t *ep;
84 xfs_bmbt_irec_t irec; 80 xfs_bmbt_irec_t irec;
85 xfs_bmbt_rec_t rec; 81 xfs_bmbt_rec_host_t rec;
86 int i; 82 int i;
87 83
88 for (i = 0; i < nrecs; i++) { 84 for (i = 0; i < nrecs; i++) {
89 ep = xfs_iext_get_ext(ifp, i); 85 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
90 rec.l0 = get_unaligned((__uint64_t*)&ep->l0); 86 rec.l0 = get_unaligned(&ep->l0);
91 rec.l1 = get_unaligned((__uint64_t*)&ep->l1); 87 rec.l1 = get_unaligned(&ep->l1);
92 if (disk) 88 xfs_bmbt_get_all(&rec, &irec);
93 xfs_bmbt_disk_get_all(&rec, &irec);
94 else
95 xfs_bmbt_get_all(&rec, &irec);
96 if (fmt == XFS_EXTFMT_NOSTATE) 89 if (fmt == XFS_EXTFMT_NOSTATE)
97 ASSERT(irec.br_state == XFS_EXT_NORM); 90 ASSERT(irec.br_state == XFS_EXT_NORM);
98 } 91 }
99} 92}
100#else /* DEBUG */ 93#else /* DEBUG */
101#define xfs_validate_extents(ifp, nrecs, disk, fmt) 94#define xfs_validate_extents(ifp, nrecs, fmt)
102#endif /* DEBUG */ 95#endif /* DEBUG */
103 96
104/* 97/*
@@ -201,8 +194,8 @@ xfs_inotobp(
201 } 194 }
202 dip = (xfs_dinode_t *)xfs_buf_offset(bp, 0); 195 dip = (xfs_dinode_t *)xfs_buf_offset(bp, 0);
203 di_ok = 196 di_ok =
204 INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && 197 be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC &&
205 XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); 198 XFS_DINODE_GOOD_VERSION(dip->di_core.di_version);
206 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, 199 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
207 XFS_RANDOM_ITOBP_INOTOBP))) { 200 XFS_RANDOM_ITOBP_INOTOBP))) {
208 XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip); 201 XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip);
@@ -346,8 +339,8 @@ xfs_itobp(
346 339
347 dip = (xfs_dinode_t *)xfs_buf_offset(bp, 340 dip = (xfs_dinode_t *)xfs_buf_offset(bp,
348 (i << mp->m_sb.sb_inodelog)); 341 (i << mp->m_sb.sb_inodelog));
349 di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && 342 di_ok = be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC &&
350 XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); 343 XFS_DINODE_GOOD_VERSION(dip->di_core.di_version);
351 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, 344 if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
352 XFS_ERRTAG_ITOBP_INOTOBP, 345 XFS_ERRTAG_ITOBP_INOTOBP,
353 XFS_RANDOM_ITOBP_INOTOBP))) { 346 XFS_RANDOM_ITOBP_INOTOBP))) {
@@ -361,7 +354,7 @@ xfs_itobp(
361 "daddr %lld #%d (magic=%x)", 354 "daddr %lld #%d (magic=%x)",
362 XFS_BUFTARG_NAME(mp->m_ddev_targp), 355 XFS_BUFTARG_NAME(mp->m_ddev_targp),
363 (unsigned long long)imap.im_blkno, i, 356 (unsigned long long)imap.im_blkno, i,
364 INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); 357 be16_to_cpu(dip->di_core.di_magic));
365#endif 358#endif
366 XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH, 359 XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH,
367 mp, dip); 360 mp, dip);
@@ -407,27 +400,26 @@ xfs_iformat(
407 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); 400 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
408 error = 0; 401 error = 0;
409 402
410 if (unlikely( 403 if (unlikely(be32_to_cpu(dip->di_core.di_nextents) +
411 INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) + 404 be16_to_cpu(dip->di_core.di_anextents) >
412 INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) > 405 be64_to_cpu(dip->di_core.di_nblocks))) {
413 INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) {
414 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, 406 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
415 "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", 407 "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.",
416 (unsigned long long)ip->i_ino, 408 (unsigned long long)ip->i_ino,
417 (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) 409 (int)(be32_to_cpu(dip->di_core.di_nextents) +
418 + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)), 410 be16_to_cpu(dip->di_core.di_anextents)),
419 (unsigned long long) 411 (unsigned long long)
420 INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT)); 412 be64_to_cpu(dip->di_core.di_nblocks));
421 XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, 413 XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW,
422 ip->i_mount, dip); 414 ip->i_mount, dip);
423 return XFS_ERROR(EFSCORRUPTED); 415 return XFS_ERROR(EFSCORRUPTED);
424 } 416 }
425 417
426 if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) { 418 if (unlikely(dip->di_core.di_forkoff > ip->i_mount->m_sb.sb_inodesize)) {
427 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, 419 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
428 "corrupt dinode %Lu, forkoff = 0x%x.", 420 "corrupt dinode %Lu, forkoff = 0x%x.",
429 (unsigned long long)ip->i_ino, 421 (unsigned long long)ip->i_ino,
430 (int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT))); 422 dip->di_core.di_forkoff);
431 XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, 423 XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW,
432 ip->i_mount, dip); 424 ip->i_mount, dip);
433 return XFS_ERROR(EFSCORRUPTED); 425 return XFS_ERROR(EFSCORRUPTED);
@@ -438,25 +430,25 @@ xfs_iformat(
438 case S_IFCHR: 430 case S_IFCHR:
439 case S_IFBLK: 431 case S_IFBLK:
440 case S_IFSOCK: 432 case S_IFSOCK:
441 if (unlikely(INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)) { 433 if (unlikely(dip->di_core.di_format != XFS_DINODE_FMT_DEV)) {
442 XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, 434 XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW,
443 ip->i_mount, dip); 435 ip->i_mount, dip);
444 return XFS_ERROR(EFSCORRUPTED); 436 return XFS_ERROR(EFSCORRUPTED);
445 } 437 }
446 ip->i_d.di_size = 0; 438 ip->i_d.di_size = 0;
447 ip->i_size = 0; 439 ip->i_size = 0;
448 ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); 440 ip->i_df.if_u2.if_rdev = be32_to_cpu(dip->di_u.di_dev);
449 break; 441 break;
450 442
451 case S_IFREG: 443 case S_IFREG:
452 case S_IFLNK: 444 case S_IFLNK:
453 case S_IFDIR: 445 case S_IFDIR:
454 switch (INT_GET(dip->di_core.di_format, ARCH_CONVERT)) { 446 switch (dip->di_core.di_format) {
455 case XFS_DINODE_FMT_LOCAL: 447 case XFS_DINODE_FMT_LOCAL:
456 /* 448 /*
457 * no local regular files yet 449 * no local regular files yet
458 */ 450 */
459 if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) { 451 if (unlikely((be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFREG)) {
460 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, 452 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
461 "corrupt inode %Lu " 453 "corrupt inode %Lu "
462 "(local format for regular file).", 454 "(local format for regular file).",
@@ -467,7 +459,7 @@ xfs_iformat(
467 return XFS_ERROR(EFSCORRUPTED); 459 return XFS_ERROR(EFSCORRUPTED);
468 } 460 }
469 461
470 di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); 462 di_size = be64_to_cpu(dip->di_core.di_size);
471 if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { 463 if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) {
472 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, 464 xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
473 "corrupt inode %Lu " 465 "corrupt inode %Lu "
@@ -509,7 +501,7 @@ xfs_iformat(
509 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); 501 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
510 ip->i_afp->if_ext_max = 502 ip->i_afp->if_ext_max =
511 XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); 503 XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
512 switch (INT_GET(dip->di_core.di_aformat, ARCH_CONVERT)) { 504 switch (dip->di_core.di_aformat) {
513 case XFS_DINODE_FMT_LOCAL: 505 case XFS_DINODE_FMT_LOCAL:
514 atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); 506 atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
515 size = be16_to_cpu(atp->hdr.totsize); 507 size = be16_to_cpu(atp->hdr.totsize);
@@ -602,7 +594,7 @@ xfs_iformat_extents(
602 xfs_dinode_t *dip, 594 xfs_dinode_t *dip,
603 int whichfork) 595 int whichfork)
604{ 596{
605 xfs_bmbt_rec_t *ep, *dp; 597 xfs_bmbt_rec_t *dp;
606 xfs_ifork_t *ifp; 598 xfs_ifork_t *ifp;
607 int nex; 599 int nex;
608 int size; 600 int size;
@@ -637,13 +629,11 @@ xfs_iformat_extents(
637 ifp->if_bytes = size; 629 ifp->if_bytes = size;
638 if (size) { 630 if (size) {
639 dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); 631 dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
640 xfs_validate_extents(ifp, nex, 1, XFS_EXTFMT_INODE(ip)); 632 xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip));
641 for (i = 0; i < nex; i++, dp++) { 633 for (i = 0; i < nex; i++, dp++) {
642 ep = xfs_iext_get_ext(ifp, i); 634 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
643 ep->l0 = INT_GET(get_unaligned((__uint64_t*)&dp->l0), 635 ep->l0 = be64_to_cpu(get_unaligned(&dp->l0));
644 ARCH_CONVERT); 636 ep->l1 = be64_to_cpu(get_unaligned(&dp->l1));
645 ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1),
646 ARCH_CONVERT);
647 } 637 }
648 XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); 638 XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork);
649 if (whichfork != XFS_DATA_FORK || 639 if (whichfork != XFS_DATA_FORK ||
@@ -719,70 +709,74 @@ xfs_iformat_btree(
719 return 0; 709 return 0;
720} 710}
721 711
722/*
723 * xfs_xlate_dinode_core - translate an xfs_inode_core_t between ondisk
724 * and native format
725 *
726 * buf = on-disk representation
727 * dip = native representation
728 * dir = direction - +ve -> disk to native
729 * -ve -> native to disk
730 */
731void 712void
732xfs_xlate_dinode_core( 713xfs_dinode_from_disk(
733 xfs_caddr_t buf, 714 xfs_icdinode_t *to,
734 xfs_dinode_core_t *dip, 715 xfs_dinode_core_t *from)
735 int dir)
736{ 716{
737 xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf; 717 to->di_magic = be16_to_cpu(from->di_magic);
738 xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip; 718 to->di_mode = be16_to_cpu(from->di_mode);
739 xfs_arch_t arch = ARCH_CONVERT; 719 to->di_version = from ->di_version;
740 720 to->di_format = from->di_format;
741 ASSERT(dir); 721 to->di_onlink = be16_to_cpu(from->di_onlink);
742 722 to->di_uid = be32_to_cpu(from->di_uid);
743 INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch); 723 to->di_gid = be32_to_cpu(from->di_gid);
744 INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch); 724 to->di_nlink = be32_to_cpu(from->di_nlink);
745 INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch); 725 to->di_projid = be16_to_cpu(from->di_projid);
746 INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch); 726 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
747 INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch); 727 to->di_flushiter = be16_to_cpu(from->di_flushiter);
748 INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch); 728 to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
749 INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch); 729 to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec);
750 INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch); 730 to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec);
751 INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch); 731 to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec);
752 732 to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec);
753 if (dir > 0) { 733 to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec);
754 memcpy(mem_core->di_pad, buf_core->di_pad, 734 to->di_size = be64_to_cpu(from->di_size);
755 sizeof(buf_core->di_pad)); 735 to->di_nblocks = be64_to_cpu(from->di_nblocks);
756 } else { 736 to->di_extsize = be32_to_cpu(from->di_extsize);
757 memcpy(buf_core->di_pad, mem_core->di_pad, 737 to->di_nextents = be32_to_cpu(from->di_nextents);
758 sizeof(buf_core->di_pad)); 738 to->di_anextents = be16_to_cpu(from->di_anextents);
759 } 739 to->di_forkoff = from->di_forkoff;
760 740 to->di_aformat = from->di_aformat;
761 INT_XLATE(buf_core->di_flushiter, mem_core->di_flushiter, dir, arch); 741 to->di_dmevmask = be32_to_cpu(from->di_dmevmask);
762 742 to->di_dmstate = be16_to_cpu(from->di_dmstate);
763 INT_XLATE(buf_core->di_atime.t_sec, mem_core->di_atime.t_sec, 743 to->di_flags = be16_to_cpu(from->di_flags);
764 dir, arch); 744 to->di_gen = be32_to_cpu(from->di_gen);
765 INT_XLATE(buf_core->di_atime.t_nsec, mem_core->di_atime.t_nsec, 745}
766 dir, arch); 746
767 INT_XLATE(buf_core->di_mtime.t_sec, mem_core->di_mtime.t_sec, 747void
768 dir, arch); 748xfs_dinode_to_disk(
769 INT_XLATE(buf_core->di_mtime.t_nsec, mem_core->di_mtime.t_nsec, 749 xfs_dinode_core_t *to,
770 dir, arch); 750 xfs_icdinode_t *from)
771 INT_XLATE(buf_core->di_ctime.t_sec, mem_core->di_ctime.t_sec, 751{
772 dir, arch); 752 to->di_magic = cpu_to_be16(from->di_magic);
773 INT_XLATE(buf_core->di_ctime.t_nsec, mem_core->di_ctime.t_nsec, 753 to->di_mode = cpu_to_be16(from->di_mode);
774 dir, arch); 754 to->di_version = from ->di_version;
775 INT_XLATE(buf_core->di_size, mem_core->di_size, dir, arch); 755 to->di_format = from->di_format;
776 INT_XLATE(buf_core->di_nblocks, mem_core->di_nblocks, dir, arch); 756 to->di_onlink = cpu_to_be16(from->di_onlink);
777 INT_XLATE(buf_core->di_extsize, mem_core->di_extsize, dir, arch); 757 to->di_uid = cpu_to_be32(from->di_uid);
778 INT_XLATE(buf_core->di_nextents, mem_core->di_nextents, dir, arch); 758 to->di_gid = cpu_to_be32(from->di_gid);
779 INT_XLATE(buf_core->di_anextents, mem_core->di_anextents, dir, arch); 759 to->di_nlink = cpu_to_be32(from->di_nlink);
780 INT_XLATE(buf_core->di_forkoff, mem_core->di_forkoff, dir, arch); 760 to->di_projid = cpu_to_be16(from->di_projid);
781 INT_XLATE(buf_core->di_aformat, mem_core->di_aformat, dir, arch); 761 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
782 INT_XLATE(buf_core->di_dmevmask, mem_core->di_dmevmask, dir, arch); 762 to->di_flushiter = cpu_to_be16(from->di_flushiter);
783 INT_XLATE(buf_core->di_dmstate, mem_core->di_dmstate, dir, arch); 763 to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
784 INT_XLATE(buf_core->di_flags, mem_core->di_flags, dir, arch); 764 to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
785 INT_XLATE(buf_core->di_gen, mem_core->di_gen, dir, arch); 765 to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
766 to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);
767 to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);
768 to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);
769 to->di_size = cpu_to_be64(from->di_size);
770 to->di_nblocks = cpu_to_be64(from->di_nblocks);
771 to->di_extsize = cpu_to_be32(from->di_extsize);
772 to->di_nextents = cpu_to_be32(from->di_nextents);
773 to->di_anextents = cpu_to_be16(from->di_anextents);
774 to->di_forkoff = from->di_forkoff;
775 to->di_aformat = from->di_aformat;
776 to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
777 to->di_dmstate = cpu_to_be16(from->di_dmstate);
778 to->di_flags = cpu_to_be16(from->di_flags);
779 to->di_gen = cpu_to_be32(from->di_gen);
786} 780}
787 781
788STATIC uint 782STATIC uint
@@ -829,7 +823,7 @@ uint
829xfs_ip2xflags( 823xfs_ip2xflags(
830 xfs_inode_t *ip) 824 xfs_inode_t *ip)
831{ 825{
832 xfs_dinode_core_t *dic = &ip->i_d; 826 xfs_icdinode_t *dic = &ip->i_d;
833 827
834 return _xfs_dic2xflags(dic->di_flags) | 828 return _xfs_dic2xflags(dic->di_flags) |
835 (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); 829 (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
@@ -839,7 +833,7 @@ uint
839xfs_dic2xflags( 833xfs_dic2xflags(
840 xfs_dinode_core_t *dic) 834 xfs_dinode_core_t *dic)
841{ 835{
842 return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) | 836 return _xfs_dic2xflags(be16_to_cpu(dic->di_flags)) |
843 (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); 837 (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
844} 838}
845 839
@@ -870,6 +864,7 @@ xfs_iread(
870 ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); 864 ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP);
871 ip->i_ino = ino; 865 ip->i_ino = ino;
872 ip->i_mount = mp; 866 ip->i_mount = mp;
867 atomic_set(&ip->i_iocount, 0);
873 spin_lock_init(&ip->i_flags_lock); 868 spin_lock_init(&ip->i_flags_lock);
874 869
875 /* 870 /*
@@ -889,6 +884,9 @@ xfs_iread(
889 * Initialize inode's trace buffers. 884 * Initialize inode's trace buffers.
890 * Do this before xfs_iformat in case it adds entries. 885 * Do this before xfs_iformat in case it adds entries.
891 */ 886 */
887#ifdef XFS_VNODE_TRACE
888 ip->i_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
889#endif
892#ifdef XFS_BMAP_TRACE 890#ifdef XFS_BMAP_TRACE
893 ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP); 891 ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP);
894#endif 892#endif
@@ -909,14 +907,14 @@ xfs_iread(
909 * If we got something that isn't an inode it means someone 907 * If we got something that isn't an inode it means someone
910 * (nfs or dmi) has a stale handle. 908 * (nfs or dmi) has a stale handle.
911 */ 909 */
912 if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) { 910 if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) {
913 kmem_zone_free(xfs_inode_zone, ip); 911 kmem_zone_free(xfs_inode_zone, ip);
914 xfs_trans_brelse(tp, bp); 912 xfs_trans_brelse(tp, bp);
915#ifdef DEBUG 913#ifdef DEBUG
916 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " 914 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
917 "dip->di_core.di_magic (0x%x) != " 915 "dip->di_core.di_magic (0x%x) != "
918 "XFS_DINODE_MAGIC (0x%x)", 916 "XFS_DINODE_MAGIC (0x%x)",
919 INT_GET(dip->di_core.di_magic, ARCH_CONVERT), 917 be16_to_cpu(dip->di_core.di_magic),
920 XFS_DINODE_MAGIC); 918 XFS_DINODE_MAGIC);
921#endif /* DEBUG */ 919#endif /* DEBUG */
922 return XFS_ERROR(EINVAL); 920 return XFS_ERROR(EINVAL);
@@ -930,8 +928,7 @@ xfs_iread(
930 * Otherwise, just get the truly permanent information. 928 * Otherwise, just get the truly permanent information.
931 */ 929 */
932 if (dip->di_core.di_mode) { 930 if (dip->di_core.di_mode) {
933 xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core, 931 xfs_dinode_from_disk(&ip->i_d, &dip->di_core);
934 &(ip->i_d), 1);
935 error = xfs_iformat(ip, dip); 932 error = xfs_iformat(ip, dip);
936 if (error) { 933 if (error) {
937 kmem_zone_free(xfs_inode_zone, ip); 934 kmem_zone_free(xfs_inode_zone, ip);
@@ -944,10 +941,10 @@ xfs_iread(
944 return error; 941 return error;
945 } 942 }
946 } else { 943 } else {
947 ip->i_d.di_magic = INT_GET(dip->di_core.di_magic, ARCH_CONVERT); 944 ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic);
948 ip->i_d.di_version = INT_GET(dip->di_core.di_version, ARCH_CONVERT); 945 ip->i_d.di_version = dip->di_core.di_version;
949 ip->i_d.di_gen = INT_GET(dip->di_core.di_gen, ARCH_CONVERT); 946 ip->i_d.di_gen = be32_to_cpu(dip->di_core.di_gen);
950 ip->i_d.di_flushiter = INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT); 947 ip->i_d.di_flushiter = be16_to_cpu(dip->di_core.di_flushiter);
951 /* 948 /*
952 * Make sure to pull in the mode here as well in 949 * Make sure to pull in the mode here as well in
953 * case the inode is released without being used. 950 * case the inode is released without being used.
@@ -1048,7 +1045,7 @@ xfs_iread_extents(
1048 ifp->if_flags &= ~XFS_IFEXTENTS; 1045 ifp->if_flags &= ~XFS_IFEXTENTS;
1049 return error; 1046 return error;
1050 } 1047 }
1051 xfs_validate_extents(ifp, nextents, 0, XFS_EXTFMT_INODE(ip)); 1048 xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip));
1052 return 0; 1049 return 0;
1053} 1050}
1054 1051
@@ -1161,7 +1158,7 @@ xfs_ialloc(
1161 if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) 1158 if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1))
1162 xfs_bump_ino_vers2(tp, ip); 1159 xfs_bump_ino_vers2(tp, ip);
1163 1160
1164 if (pip && XFS_INHERIT_GID(pip, vp->v_vfsp)) { 1161 if (pip && XFS_INHERIT_GID(pip)) {
1165 ip->i_d.di_gid = pip->i_d.di_gid; 1162 ip->i_d.di_gid = pip->i_d.di_gid;
1166 if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { 1163 if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
1167 ip->i_d.di_mode |= S_ISGID; 1164 ip->i_d.di_mode |= S_ISGID;
@@ -1275,7 +1272,7 @@ xfs_ialloc(
1275 xfs_trans_log_inode(tp, ip, flags); 1272 xfs_trans_log_inode(tp, ip, flags);
1276 1273
1277 /* now that we have an i_mode we can setup inode ops and unlock */ 1274 /* now that we have an i_mode we can setup inode ops and unlock */
1278 bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1); 1275 xfs_initialize_vnode(tp->t_mountp, vp, ip);
1279 1276
1280 *ipp = ip; 1277 *ipp = ip;
1281 return 0; 1278 return 0;
@@ -1462,7 +1459,7 @@ xfs_itruncate_start(
1462 mp = ip->i_mount; 1459 mp = ip->i_mount;
1463 vp = XFS_ITOV(ip); 1460 vp = XFS_ITOV(ip);
1464 1461
1465 vn_iowait(vp); /* wait for the completion of any pending DIOs */ 1462 vn_iowait(ip); /* wait for the completion of any pending DIOs */
1466 1463
1467 /* 1464 /*
1468 * Call toss_pages or flushinval_pages to get rid of pages 1465 * Call toss_pages or flushinval_pages to get rid of pages
@@ -1497,9 +1494,11 @@ xfs_itruncate_start(
1497 last_byte); 1494 last_byte);
1498 if (last_byte > toss_start) { 1495 if (last_byte > toss_start) {
1499 if (flags & XFS_ITRUNC_DEFINITE) { 1496 if (flags & XFS_ITRUNC_DEFINITE) {
1500 bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); 1497 xfs_tosspages(ip, toss_start,
1498 -1, FI_REMAPF_LOCKED);
1501 } else { 1499 } else {
1502 error = bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); 1500 error = xfs_flushinval_pages(ip, toss_start,
1501 -1, FI_REMAPF_LOCKED);
1503 } 1502 }
1504 } 1503 }
1505 1504
@@ -1932,9 +1931,9 @@ xfs_iunlink(
1932 */ 1931 */
1933 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr, 1932 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr,
1934 XFS_FSS_TO_BB(mp, 1), 0, &agibp); 1933 XFS_FSS_TO_BB(mp, 1), 0, &agibp);
1935 if (error) { 1934 if (error)
1936 return error; 1935 return error;
1937 } 1936
1938 /* 1937 /*
1939 * Validate the magic number of the agi block. 1938 * Validate the magic number of the agi block.
1940 */ 1939 */
@@ -1958,6 +1957,24 @@ xfs_iunlink(
1958 ASSERT(agi->agi_unlinked[bucket_index]); 1957 ASSERT(agi->agi_unlinked[bucket_index]);
1959 ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); 1958 ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino);
1960 1959
1960 error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0);
1961 if (error)
1962 return error;
1963
1964 /*
1965 * Clear the on-disk di_nlink. This is to prevent xfs_bulkstat
1966 * from picking up this inode when it is reclaimed (its incore state
1967 * initialzed but not flushed to disk yet). The in-core di_nlink is
1968 * already cleared in xfs_droplink() and a corresponding transaction
1969 * logged. The hack here just synchronizes the in-core to on-disk
1970 * di_nlink value in advance before the actual inode sync to disk.
1971 * This is OK because the inode is already unlinked and would never
1972 * change its di_nlink again for this inode generation.
1973 * This is a temporary hack that would require a proper fix
1974 * in the future.
1975 */
1976 dip->di_core.di_nlink = 0;
1977
1961 if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) { 1978 if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) {
1962 /* 1979 /*
1963 * There is already another inode in the bucket we need 1980 * There is already another inode in the bucket we need
@@ -1965,12 +1982,7 @@ xfs_iunlink(
1965 * Here we put the head pointer into our next pointer, 1982 * Here we put the head pointer into our next pointer,
1966 * and then we fall through to point the head at us. 1983 * and then we fall through to point the head at us.
1967 */ 1984 */
1968 error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0); 1985 ASSERT(be32_to_cpu(dip->di_next_unlinked) == NULLAGINO);
1969 if (error) {
1970 return error;
1971 }
1972 ASSERT(INT_GET(dip->di_next_unlinked, ARCH_CONVERT) == NULLAGINO);
1973 ASSERT(dip->di_next_unlinked);
1974 /* both on-disk, don't endian flip twice */ 1986 /* both on-disk, don't endian flip twice */
1975 dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; 1987 dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
1976 offset = ip->i_boffset + 1988 offset = ip->i_boffset +
@@ -2081,10 +2093,10 @@ xfs_iunlink_remove(
2081 error, mp->m_fsname); 2093 error, mp->m_fsname);
2082 return error; 2094 return error;
2083 } 2095 }
2084 next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT); 2096 next_agino = be32_to_cpu(dip->di_next_unlinked);
2085 ASSERT(next_agino != 0); 2097 ASSERT(next_agino != 0);
2086 if (next_agino != NULLAGINO) { 2098 if (next_agino != NULLAGINO) {
2087 INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO); 2099 dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
2088 offset = ip->i_boffset + 2100 offset = ip->i_boffset +
2089 offsetof(xfs_dinode_t, di_next_unlinked); 2101 offsetof(xfs_dinode_t, di_next_unlinked);
2090 xfs_trans_inode_buf(tp, ibp); 2102 xfs_trans_inode_buf(tp, ibp);
@@ -2128,7 +2140,7 @@ xfs_iunlink_remove(
2128 error, mp->m_fsname); 2140 error, mp->m_fsname);
2129 return error; 2141 return error;
2130 } 2142 }
2131 next_agino = INT_GET(last_dip->di_next_unlinked, ARCH_CONVERT); 2143 next_agino = be32_to_cpu(last_dip->di_next_unlinked);
2132 ASSERT(next_agino != NULLAGINO); 2144 ASSERT(next_agino != NULLAGINO);
2133 ASSERT(next_agino != 0); 2145 ASSERT(next_agino != 0);
2134 } 2146 }
@@ -2143,11 +2155,11 @@ xfs_iunlink_remove(
2143 error, mp->m_fsname); 2155 error, mp->m_fsname);
2144 return error; 2156 return error;
2145 } 2157 }
2146 next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT); 2158 next_agino = be32_to_cpu(dip->di_next_unlinked);
2147 ASSERT(next_agino != 0); 2159 ASSERT(next_agino != 0);
2148 ASSERT(next_agino != agino); 2160 ASSERT(next_agino != agino);
2149 if (next_agino != NULLAGINO) { 2161 if (next_agino != NULLAGINO) {
2150 INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO); 2162 dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
2151 offset = ip->i_boffset + 2163 offset = ip->i_boffset +
2152 offsetof(xfs_dinode_t, di_next_unlinked); 2164 offsetof(xfs_dinode_t, di_next_unlinked);
2153 xfs_trans_inode_buf(tp, ibp); 2165 xfs_trans_inode_buf(tp, ibp);
@@ -2160,7 +2172,7 @@ xfs_iunlink_remove(
2160 /* 2172 /*
2161 * Point the previous inode on the list to the next inode. 2173 * Point the previous inode on the list to the next inode.
2162 */ 2174 */
2163 INT_SET(last_dip->di_next_unlinked, ARCH_CONVERT, next_agino); 2175 last_dip->di_next_unlinked = cpu_to_be32(next_agino);
2164 ASSERT(next_agino != 0); 2176 ASSERT(next_agino != 0);
2165 offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked); 2177 offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked);
2166 xfs_trans_inode_buf(tp, last_ibp); 2178 xfs_trans_inode_buf(tp, last_ibp);
@@ -2191,10 +2203,10 @@ xfs_ifree_cluster(
2191 int i, j, found, pre_flushed; 2203 int i, j, found, pre_flushed;
2192 xfs_daddr_t blkno; 2204 xfs_daddr_t blkno;
2193 xfs_buf_t *bp; 2205 xfs_buf_t *bp;
2194 xfs_ihash_t *ih;
2195 xfs_inode_t *ip, **ip_found; 2206 xfs_inode_t *ip, **ip_found;
2196 xfs_inode_log_item_t *iip; 2207 xfs_inode_log_item_t *iip;
2197 xfs_log_item_t *lip; 2208 xfs_log_item_t *lip;
2209 xfs_perag_t *pag = xfs_get_perag(mp, inum);
2198 SPLDECL(s); 2210 SPLDECL(s);
2199 2211
2200 if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { 2212 if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {
@@ -2229,23 +2241,20 @@ xfs_ifree_cluster(
2229 */ 2241 */
2230 found = 0; 2242 found = 0;
2231 for (i = 0; i < ninodes; i++) { 2243 for (i = 0; i < ninodes; i++) {
2232 ih = XFS_IHASH(mp, inum + i); 2244 read_lock(&pag->pag_ici_lock);
2233 read_lock(&ih->ih_lock); 2245 ip = radix_tree_lookup(&pag->pag_ici_root,
2234 for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) { 2246 XFS_INO_TO_AGINO(mp, (inum + i)));
2235 if (ip->i_ino == inum + i)
2236 break;
2237 }
2238 2247
2239 /* Inode not in memory or we found it already, 2248 /* Inode not in memory or we found it already,
2240 * nothing to do 2249 * nothing to do
2241 */ 2250 */
2242 if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { 2251 if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) {
2243 read_unlock(&ih->ih_lock); 2252 read_unlock(&pag->pag_ici_lock);
2244 continue; 2253 continue;
2245 } 2254 }
2246 2255
2247 if (xfs_inode_clean(ip)) { 2256 if (xfs_inode_clean(ip)) {
2248 read_unlock(&ih->ih_lock); 2257 read_unlock(&pag->pag_ici_lock);
2249 continue; 2258 continue;
2250 } 2259 }
2251 2260
@@ -2268,7 +2277,7 @@ xfs_ifree_cluster(
2268 ip_found[found++] = ip; 2277 ip_found[found++] = ip;
2269 } 2278 }
2270 } 2279 }
2271 read_unlock(&ih->ih_lock); 2280 read_unlock(&pag->pag_ici_lock);
2272 continue; 2281 continue;
2273 } 2282 }
2274 2283
@@ -2286,8 +2295,7 @@ xfs_ifree_cluster(
2286 xfs_iunlock(ip, XFS_ILOCK_EXCL); 2295 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2287 } 2296 }
2288 } 2297 }
2289 2298 read_unlock(&pag->pag_ici_lock);
2290 read_unlock(&ih->ih_lock);
2291 } 2299 }
2292 2300
2293 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, 2301 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
@@ -2342,6 +2350,7 @@ xfs_ifree_cluster(
2342 } 2350 }
2343 2351
2344 kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *)); 2352 kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *));
2353 xfs_put_perag(mp, pag);
2345} 2354}
2346 2355
2347/* 2356/*
@@ -2737,6 +2746,10 @@ xfs_idestroy(
2737 mrfree(&ip->i_lock); 2746 mrfree(&ip->i_lock);
2738 mrfree(&ip->i_iolock); 2747 mrfree(&ip->i_iolock);
2739 freesema(&ip->i_flock); 2748 freesema(&ip->i_flock);
2749
2750#ifdef XFS_VNODE_TRACE
2751 ktrace_free(ip->i_trace);
2752#endif
2740#ifdef XFS_BMAP_TRACE 2753#ifdef XFS_BMAP_TRACE
2741 ktrace_free(ip->i_xtrace); 2754 ktrace_free(ip->i_xtrace);
2742#endif 2755#endif
@@ -2887,12 +2900,10 @@ xfs_iunpin_wait(
2887int 2900int
2888xfs_iextents_copy( 2901xfs_iextents_copy(
2889 xfs_inode_t *ip, 2902 xfs_inode_t *ip,
2890 xfs_bmbt_rec_t *buffer, 2903 xfs_bmbt_rec_t *dp,
2891 int whichfork) 2904 int whichfork)
2892{ 2905{
2893 int copied; 2906 int copied;
2894 xfs_bmbt_rec_t *dest_ep;
2895 xfs_bmbt_rec_t *ep;
2896 int i; 2907 int i;
2897 xfs_ifork_t *ifp; 2908 xfs_ifork_t *ifp;
2898 int nrecs; 2909 int nrecs;
@@ -2912,10 +2923,9 @@ xfs_iextents_copy(
2912 * the delayed ones. There must be at least one 2923 * the delayed ones. There must be at least one
2913 * non-delayed extent. 2924 * non-delayed extent.
2914 */ 2925 */
2915 dest_ep = buffer;
2916 copied = 0; 2926 copied = 0;
2917 for (i = 0; i < nrecs; i++) { 2927 for (i = 0; i < nrecs; i++) {
2918 ep = xfs_iext_get_ext(ifp, i); 2928 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
2919 start_block = xfs_bmbt_get_startblock(ep); 2929 start_block = xfs_bmbt_get_startblock(ep);
2920 if (ISNULLSTARTBLOCK(start_block)) { 2930 if (ISNULLSTARTBLOCK(start_block)) {
2921 /* 2931 /*
@@ -2925,15 +2935,13 @@ xfs_iextents_copy(
2925 } 2935 }
2926 2936
2927 /* Translate to on disk format */ 2937 /* Translate to on disk format */
2928 put_unaligned(INT_GET(ep->l0, ARCH_CONVERT), 2938 put_unaligned(cpu_to_be64(ep->l0), &dp->l0);
2929 (__uint64_t*)&dest_ep->l0); 2939 put_unaligned(cpu_to_be64(ep->l1), &dp->l1);
2930 put_unaligned(INT_GET(ep->l1, ARCH_CONVERT), 2940 dp++;
2931 (__uint64_t*)&dest_ep->l1);
2932 dest_ep++;
2933 copied++; 2941 copied++;
2934 } 2942 }
2935 ASSERT(copied != 0); 2943 ASSERT(copied != 0);
2936 xfs_validate_extents(ifp, copied, 1, XFS_EXTFMT_INODE(ip)); 2944 xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip));
2937 2945
2938 return (copied * (uint)sizeof(xfs_bmbt_rec_t)); 2946 return (copied * (uint)sizeof(xfs_bmbt_rec_t));
2939} 2947}
@@ -3024,7 +3032,7 @@ xfs_iflush_fork(
3024 case XFS_DINODE_FMT_DEV: 3032 case XFS_DINODE_FMT_DEV:
3025 if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { 3033 if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) {
3026 ASSERT(whichfork == XFS_DATA_FORK); 3034 ASSERT(whichfork == XFS_DATA_FORK);
3027 INT_SET(dip->di_u.di_dev, ARCH_CONVERT, ip->i_df.if_u2.if_rdev); 3035 dip->di_u.di_dev = cpu_to_be32(ip->i_df.if_u2.if_rdev);
3028 } 3036 }
3029 break; 3037 break;
3030 3038
@@ -3064,12 +3072,11 @@ xfs_iflush(
3064 xfs_mount_t *mp; 3072 xfs_mount_t *mp;
3065 int error; 3073 int error;
3066 /* REFERENCED */ 3074 /* REFERENCED */
3067 xfs_chash_t *ch;
3068 xfs_inode_t *iq; 3075 xfs_inode_t *iq;
3069 int clcount; /* count of inodes clustered */ 3076 int clcount; /* count of inodes clustered */
3070 int bufwasdelwri; 3077 int bufwasdelwri;
3078 struct hlist_node *entry;
3071 enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) }; 3079 enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) };
3072 SPLDECL(s);
3073 3080
3074 XFS_STATS_INC(xs_iflush_count); 3081 XFS_STATS_INC(xs_iflush_count);
3075 3082
@@ -3183,14 +3190,14 @@ xfs_iflush(
3183 * inode clustering: 3190 * inode clustering:
3184 * see if other inodes can be gathered into this write 3191 * see if other inodes can be gathered into this write
3185 */ 3192 */
3186 3193 spin_lock(&ip->i_cluster->icl_lock);
3187 ip->i_chash->chl_buf = bp; 3194 ip->i_cluster->icl_buf = bp;
3188
3189 ch = XFS_CHASH(mp, ip->i_blkno);
3190 s = mutex_spinlock(&ch->ch_lock);
3191 3195
3192 clcount = 0; 3196 clcount = 0;
3193 for (iq = ip->i_cnext; iq != ip; iq = iq->i_cnext) { 3197 hlist_for_each_entry(iq, entry, &ip->i_cluster->icl_inodes, i_cnode) {
3198 if (iq == ip)
3199 continue;
3200
3194 /* 3201 /*
3195 * Do an un-protected check to see if the inode is dirty and 3202 * Do an un-protected check to see if the inode is dirty and
3196 * is a candidate for flushing. These checks will be repeated 3203 * is a candidate for flushing. These checks will be repeated
@@ -3241,7 +3248,7 @@ xfs_iflush(
3241 xfs_iunlock(iq, XFS_ILOCK_SHARED); 3248 xfs_iunlock(iq, XFS_ILOCK_SHARED);
3242 } 3249 }
3243 } 3250 }
3244 mutex_spinunlock(&ch->ch_lock, s); 3251 spin_unlock(&ip->i_cluster->icl_lock);
3245 3252
3246 if (clcount) { 3253 if (clcount) {
3247 XFS_STATS_INC(xs_icluster_flushcnt); 3254 XFS_STATS_INC(xs_icluster_flushcnt);
@@ -3278,7 +3285,7 @@ cluster_corrupt_out:
3278 /* Corruption detected in the clustering loop. Invalidate the 3285 /* Corruption detected in the clustering loop. Invalidate the
3279 * inode buffer and shut down the filesystem. 3286 * inode buffer and shut down the filesystem.
3280 */ 3287 */
3281 mutex_spinunlock(&ch->ch_lock, s); 3288 spin_unlock(&ip->i_cluster->icl_lock);
3282 3289
3283 /* 3290 /*
3284 * Clean up the buffer. If it was B_DELWRI, just release it -- 3291 * Clean up the buffer. If it was B_DELWRI, just release it --
@@ -3373,11 +3380,11 @@ xfs_iflush_int(
3373 */ 3380 */
3374 xfs_synchronize_atime(ip); 3381 xfs_synchronize_atime(ip);
3375 3382
3376 if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC, 3383 if (XFS_TEST_ERROR(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC,
3377 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { 3384 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
3378 xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, 3385 xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp,
3379 "xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p", 3386 "xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p",
3380 ip->i_ino, (int) INT_GET(dip->di_core.di_magic, ARCH_CONVERT), dip); 3387 ip->i_ino, be16_to_cpu(dip->di_core.di_magic), dip);
3381 goto corrupt_out; 3388 goto corrupt_out;
3382 } 3389 }
3383 if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, 3390 if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC,
@@ -3440,7 +3447,7 @@ xfs_iflush_int(
3440 * because if the inode is dirty at all the core must 3447 * because if the inode is dirty at all the core must
3441 * be. 3448 * be.
3442 */ 3449 */
3443 xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1); 3450 xfs_dinode_to_disk(&dip->di_core, &ip->i_d);
3444 3451
3445 /* Wrap, we never let the log put out DI_MAX_FLUSH */ 3452 /* Wrap, we never let the log put out DI_MAX_FLUSH */
3446 if (ip->i_d.di_flushiter == DI_MAX_FLUSH) 3453 if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
@@ -3460,7 +3467,7 @@ xfs_iflush_int(
3460 * Convert it back. 3467 * Convert it back.
3461 */ 3468 */
3462 ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); 3469 ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
3463 INT_SET(dip->di_core.di_onlink, ARCH_CONVERT, ip->i_d.di_nlink); 3470 dip->di_core.di_onlink = cpu_to_be16(ip->i_d.di_nlink);
3464 } else { 3471 } else {
3465 /* 3472 /*
3466 * The superblock version has already been bumped, 3473 * The superblock version has already been bumped,
@@ -3468,7 +3475,7 @@ xfs_iflush_int(
3468 * format permanent. 3475 * format permanent.
3469 */ 3476 */
3470 ip->i_d.di_version = XFS_DINODE_VERSION_2; 3477 ip->i_d.di_version = XFS_DINODE_VERSION_2;
3471 INT_SET(dip->di_core.di_version, ARCH_CONVERT, XFS_DINODE_VERSION_2); 3478 dip->di_core.di_version = XFS_DINODE_VERSION_2;
3472 ip->i_d.di_onlink = 0; 3479 ip->i_d.di_onlink = 0;
3473 dip->di_core.di_onlink = 0; 3480 dip->di_core.di_onlink = 0;
3474 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); 3481 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
@@ -3711,7 +3718,7 @@ xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra)
3711/* 3718/*
3712 * Return a pointer to the extent record at file index idx. 3719 * Return a pointer to the extent record at file index idx.
3713 */ 3720 */
3714xfs_bmbt_rec_t * 3721xfs_bmbt_rec_host_t *
3715xfs_iext_get_ext( 3722xfs_iext_get_ext(
3716 xfs_ifork_t *ifp, /* inode fork pointer */ 3723 xfs_ifork_t *ifp, /* inode fork pointer */
3717 xfs_extnum_t idx) /* index of target extent */ 3724 xfs_extnum_t idx) /* index of target extent */
@@ -3744,15 +3751,12 @@ xfs_iext_insert(
3744 xfs_extnum_t count, /* number of inserted items */ 3751 xfs_extnum_t count, /* number of inserted items */
3745 xfs_bmbt_irec_t *new) /* items to insert */ 3752 xfs_bmbt_irec_t *new) /* items to insert */
3746{ 3753{
3747 xfs_bmbt_rec_t *ep; /* extent record pointer */
3748 xfs_extnum_t i; /* extent record index */ 3754 xfs_extnum_t i; /* extent record index */
3749 3755
3750 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 3756 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
3751 xfs_iext_add(ifp, idx, count); 3757 xfs_iext_add(ifp, idx, count);
3752 for (i = idx; i < idx + count; i++, new++) { 3758 for (i = idx; i < idx + count; i++, new++)
3753 ep = xfs_iext_get_ext(ifp, i); 3759 xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new);
3754 xfs_bmbt_set_all(ep, new);
3755 }
3756} 3760}
3757 3761
3758/* 3762/*
@@ -4203,7 +4207,7 @@ xfs_iext_realloc_direct(
4203 rnew_size = xfs_iroundup(new_size); 4207 rnew_size = xfs_iroundup(new_size);
4204 } 4208 }
4205 if (rnew_size != ifp->if_real_bytes) { 4209 if (rnew_size != ifp->if_real_bytes) {
4206 ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) 4210 ifp->if_u1.if_extents =
4207 kmem_realloc(ifp->if_u1.if_extents, 4211 kmem_realloc(ifp->if_u1.if_extents,
4208 rnew_size, 4212 rnew_size,
4209 ifp->if_real_bytes, 4213 ifp->if_real_bytes,
@@ -4266,8 +4270,7 @@ xfs_iext_inline_to_direct(
4266 xfs_ifork_t *ifp, /* inode fork pointer */ 4270 xfs_ifork_t *ifp, /* inode fork pointer */
4267 int new_size) /* number of extents in file */ 4271 int new_size) /* number of extents in file */
4268{ 4272{
4269 ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) 4273 ifp->if_u1.if_extents = kmem_alloc(new_size, KM_SLEEP);
4270 kmem_alloc(new_size, KM_SLEEP);
4271 memset(ifp->if_u1.if_extents, 0, new_size); 4274 memset(ifp->if_u1.if_extents, 0, new_size);
4272 if (ifp->if_bytes) { 4275 if (ifp->if_bytes) {
4273 memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, 4276 memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext,
@@ -4310,7 +4313,7 @@ void
4310xfs_iext_indirect_to_direct( 4313xfs_iext_indirect_to_direct(
4311 xfs_ifork_t *ifp) /* inode fork pointer */ 4314 xfs_ifork_t *ifp) /* inode fork pointer */
4312{ 4315{
4313 xfs_bmbt_rec_t *ep; /* extent record pointer */ 4316 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
4314 xfs_extnum_t nextents; /* number of extents in file */ 4317 xfs_extnum_t nextents; /* number of extents in file */
4315 int size; /* size of file extents */ 4318 int size; /* size of file extents */
4316 4319
@@ -4362,15 +4365,15 @@ xfs_iext_destroy(
4362/* 4365/*
4363 * Return a pointer to the extent record for file system block bno. 4366 * Return a pointer to the extent record for file system block bno.
4364 */ 4367 */
4365xfs_bmbt_rec_t * /* pointer to found extent record */ 4368xfs_bmbt_rec_host_t * /* pointer to found extent record */
4366xfs_iext_bno_to_ext( 4369xfs_iext_bno_to_ext(
4367 xfs_ifork_t *ifp, /* inode fork pointer */ 4370 xfs_ifork_t *ifp, /* inode fork pointer */
4368 xfs_fileoff_t bno, /* block number to search for */ 4371 xfs_fileoff_t bno, /* block number to search for */
4369 xfs_extnum_t *idxp) /* index of target extent */ 4372 xfs_extnum_t *idxp) /* index of target extent */
4370{ 4373{
4371 xfs_bmbt_rec_t *base; /* pointer to first extent */ 4374 xfs_bmbt_rec_host_t *base; /* pointer to first extent */
4372 xfs_filblks_t blockcount = 0; /* number of blocks in extent */ 4375 xfs_filblks_t blockcount = 0; /* number of blocks in extent */
4373 xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */ 4376 xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */
4374 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ 4377 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
4375 int high; /* upper boundary in search */ 4378 int high; /* upper boundary in search */
4376 xfs_extnum_t idx = 0; /* index of target extent */ 4379 xfs_extnum_t idx = 0; /* index of target extent */
@@ -4545,8 +4548,7 @@ xfs_iext_irec_init(
4545 kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP); 4548 kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP);
4546 4549
4547 if (nextents == 0) { 4550 if (nextents == 0) {
4548 ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) 4551 ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
4549 kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
4550 } else if (!ifp->if_real_bytes) { 4552 } else if (!ifp->if_real_bytes) {
4551 xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); 4553 xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ);
4552 } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { 4554 } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) {
@@ -4594,8 +4596,7 @@ xfs_iext_irec_new(
4594 4596
4595 /* Initialize new extent record */ 4597 /* Initialize new extent record */
4596 erp = ifp->if_u1.if_ext_irec; 4598 erp = ifp->if_u1.if_ext_irec;
4597 erp[erp_idx].er_extbuf = (xfs_bmbt_rec_t *) 4599 erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
4598 kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP);
4599 ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; 4600 ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
4600 memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); 4601 memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ);
4601 erp[erp_idx].er_extcount = 0; 4602 erp[erp_idx].er_extcount = 0;
@@ -4727,7 +4728,7 @@ void
4727xfs_iext_irec_compact_full( 4728xfs_iext_irec_compact_full(
4728 xfs_ifork_t *ifp) /* inode fork pointer */ 4729 xfs_ifork_t *ifp) /* inode fork pointer */
4729{ 4730{
4730 xfs_bmbt_rec_t *ep, *ep_next; /* extent record pointers */ 4731 xfs_bmbt_rec_host_t *ep, *ep_next; /* extent record pointers */
4731 xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */ 4732 xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */
4732 int erp_idx = 0; /* extent irec index */ 4733 int erp_idx = 0; /* extent irec index */
4733 int ext_avail; /* empty entries in ex list */ 4734 int ext_avail; /* empty entries in ex list */
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 012dfd4a958c..e5aff929cc65 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -18,6 +18,10 @@
18#ifndef __XFS_INODE_H__ 18#ifndef __XFS_INODE_H__
19#define __XFS_INODE_H__ 19#define __XFS_INODE_H__
20 20
21struct xfs_dinode;
22struct xfs_dinode_core;
23
24
21/* 25/*
22 * Fork identifiers. 26 * Fork identifiers.
23 */ 27 */
@@ -44,7 +48,7 @@
44 * it is possible that a third level of indirection may be required. 48 * it is possible that a third level of indirection may be required.
45 */ 49 */
46typedef struct xfs_ext_irec { 50typedef struct xfs_ext_irec {
47 xfs_bmbt_rec_t *er_extbuf; /* block of extent records */ 51 xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */
48 xfs_extnum_t er_extoff; /* extent offset in file */ 52 xfs_extnum_t er_extoff; /* extent offset in file */
49 xfs_extnum_t er_extcount; /* number of extents in page/block */ 53 xfs_extnum_t er_extcount; /* number of extents in page/block */
50} xfs_ext_irec_t; 54} xfs_ext_irec_t;
@@ -65,12 +69,12 @@ typedef struct xfs_ifork {
65 unsigned char if_ext_max; /* max # of extent records */ 69 unsigned char if_ext_max; /* max # of extent records */
66 xfs_extnum_t if_lastex; /* last if_extents used */ 70 xfs_extnum_t if_lastex; /* last if_extents used */
67 union { 71 union {
68 xfs_bmbt_rec_t *if_extents; /* linear map file exts */ 72 xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */
69 xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ 73 xfs_ext_irec_t *if_ext_irec; /* irec map file exts */
70 char *if_data; /* inline file data */ 74 char *if_data; /* inline file data */
71 } if_u1; 75 } if_u1;
72 union { 76 union {
73 xfs_bmbt_rec_t if_inline_ext[XFS_INLINE_EXTS]; 77 xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS];
74 /* very small file extents */ 78 /* very small file extents */
75 char if_inline_data[XFS_INLINE_DATA]; 79 char if_inline_data[XFS_INLINE_DATA];
76 /* very small file data */ 80 /* very small file data */
@@ -102,7 +106,6 @@ typedef struct xfs_ifork {
102 106
103#ifdef __KERNEL__ 107#ifdef __KERNEL__
104struct bhv_desc; 108struct bhv_desc;
105struct bhv_vnode;
106struct cred; 109struct cred;
107struct ktrace; 110struct ktrace;
108struct xfs_buf; 111struct xfs_buf;
@@ -168,41 +171,18 @@ typedef struct xfs_iocore {
168extern void xfs_iocore_inode_init(struct xfs_inode *); 171extern void xfs_iocore_inode_init(struct xfs_inode *);
169extern void xfs_iocore_inode_reinit(struct xfs_inode *); 172extern void xfs_iocore_inode_reinit(struct xfs_inode *);
170 173
171
172/*
173 * This is the type used in the xfs inode hash table.
174 * An array of these is allocated for each mounted
175 * file system to hash the inodes for that file system.
176 */
177typedef struct xfs_ihash {
178 struct xfs_inode *ih_next;
179 rwlock_t ih_lock;
180 uint ih_version;
181} xfs_ihash_t;
182
183#define XFS_IHASH(mp,ino) ((mp)->m_ihash + (((uint)(ino)) % (mp)->m_ihsize))
184
185/* 174/*
186 * This is the xfs inode cluster hash. This hash is used by xfs_iflush to 175 * This is the xfs inode cluster structure. This structure is used by
187 * find inodes that share a cluster and can be flushed to disk at the same 176 * xfs_iflush to find inodes that share a cluster and can be flushed to disk at
188 * time. 177 * the same time.
189 */ 178 */
190typedef struct xfs_chashlist { 179typedef struct xfs_icluster {
191 struct xfs_chashlist *chl_next; 180 struct hlist_head icl_inodes; /* list of inodes on cluster */
192 struct xfs_chashlist *chl_prev; 181 xfs_daddr_t icl_blkno; /* starting block number of
193 struct xfs_inode *chl_ip;
194 xfs_daddr_t chl_blkno; /* starting block number of
195 * the cluster */ 182 * the cluster */
196 struct xfs_buf *chl_buf; /* the inode buffer */ 183 struct xfs_buf *icl_buf; /* the inode buffer */
197} xfs_chashlist_t; 184 lock_t icl_lock; /* inode list lock */
198 185} xfs_icluster_t;
199typedef struct xfs_chash {
200 xfs_chashlist_t *ch_list;
201 lock_t ch_lock;
202} xfs_chash_t;
203
204#define XFS_CHASH(mp,blk) ((mp)->m_chash + (((uint)blk) % (mp)->m_chsize))
205
206 186
207/* 187/*
208 * This is the xfs in-core inode structure. 188 * This is the xfs in-core inode structure.
@@ -227,25 +207,56 @@ typedef struct xfs_chash {
227 * chain off the mount structure by xfs_sync calls. 207 * chain off the mount structure by xfs_sync calls.
228 */ 208 */
229 209
210typedef struct xfs_ictimestamp {
211 __int32_t t_sec; /* timestamp seconds */
212 __int32_t t_nsec; /* timestamp nanoseconds */
213} xfs_ictimestamp_t;
214
215/*
216 * NOTE: This structure must be kept identical to struct xfs_dinode_core
217 * in xfs_dinode.h except for the endianess annotations.
218 */
219typedef struct xfs_icdinode {
220 __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
221 __uint16_t di_mode; /* mode and type of file */
222 __int8_t di_version; /* inode version */
223 __int8_t di_format; /* format of di_c data */
224 __uint16_t di_onlink; /* old number of links to file */
225 __uint32_t di_uid; /* owner's user id */
226 __uint32_t di_gid; /* owner's group id */
227 __uint32_t di_nlink; /* number of links to file */
228 __uint16_t di_projid; /* owner's project id */
229 __uint8_t di_pad[8]; /* unused, zeroed space */
230 __uint16_t di_flushiter; /* incremented on flush */
231 xfs_ictimestamp_t di_atime; /* time last accessed */
232 xfs_ictimestamp_t di_mtime; /* time last modified */
233 xfs_ictimestamp_t di_ctime; /* time created/inode modified */
234 xfs_fsize_t di_size; /* number of bytes in file */
235 xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */
236 xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
237 xfs_extnum_t di_nextents; /* number of extents in data fork */
238 xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
239 __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
240 __int8_t di_aformat; /* format of attr fork's data */
241 __uint32_t di_dmevmask; /* DMIG event mask */
242 __uint16_t di_dmstate; /* DMIG state info */
243 __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
244 __uint32_t di_gen; /* generation number */
245} xfs_icdinode_t;
246
230typedef struct { 247typedef struct {
231 struct xfs_ihash *ip_hash; /* pointer to hash header */
232 struct xfs_inode *ip_next; /* inode hash link forw */
233 struct xfs_inode *ip_mnext; /* next inode in mount list */ 248 struct xfs_inode *ip_mnext; /* next inode in mount list */
234 struct xfs_inode *ip_mprev; /* ptr to prev inode */ 249 struct xfs_inode *ip_mprev; /* ptr to prev inode */
235 struct xfs_inode **ip_prevp; /* ptr to prev i_next */
236 struct xfs_mount *ip_mount; /* fs mount struct ptr */ 250 struct xfs_mount *ip_mount; /* fs mount struct ptr */
237} xfs_iptr_t; 251} xfs_iptr_t;
238 252
239typedef struct xfs_inode { 253typedef struct xfs_inode {
240 /* Inode linking and identification information. */ 254 /* Inode linking and identification information. */
241 struct xfs_ihash *i_hash; /* pointer to hash header */
242 struct xfs_inode *i_next; /* inode hash link forw */
243 struct xfs_inode *i_mnext; /* next inode in mount list */ 255 struct xfs_inode *i_mnext; /* next inode in mount list */
244 struct xfs_inode *i_mprev; /* ptr to prev inode */ 256 struct xfs_inode *i_mprev; /* ptr to prev inode */
245 struct xfs_inode **i_prevp; /* ptr to prev i_next */
246 struct xfs_mount *i_mount; /* fs mount struct ptr */ 257 struct xfs_mount *i_mount; /* fs mount struct ptr */
247 struct list_head i_reclaim; /* reclaim list */ 258 struct list_head i_reclaim; /* reclaim list */
248 struct bhv_desc i_bhv_desc; /* inode behavior descriptor*/ 259 bhv_vnode_t *i_vnode; /* vnode backpointer */
249 struct xfs_dquot *i_udquot; /* user dquot */ 260 struct xfs_dquot *i_udquot; /* user dquot */
250 struct xfs_dquot *i_gdquot; /* group dquot */ 261 struct xfs_dquot *i_gdquot; /* group dquot */
251 262
@@ -282,13 +293,16 @@ typedef struct xfs_inode {
282 unsigned int i_gen; /* generation count */ 293 unsigned int i_gen; /* generation count */
283 unsigned int i_delayed_blks; /* count of delay alloc blks */ 294 unsigned int i_delayed_blks; /* count of delay alloc blks */
284 295
285 xfs_dinode_core_t i_d; /* most of ondisk inode */ 296 xfs_icdinode_t i_d; /* most of ondisk inode */
286 xfs_chashlist_t *i_chash; /* cluster hash list header */ 297 xfs_icluster_t *i_cluster; /* cluster list header */
287 struct xfs_inode *i_cnext; /* cluster hash link forward */ 298 struct hlist_node i_cnode; /* cluster link node */
288 struct xfs_inode *i_cprev; /* cluster hash link backward */
289 299
290 xfs_fsize_t i_size; /* in-memory size */ 300 xfs_fsize_t i_size; /* in-memory size */
301 atomic_t i_iocount; /* outstanding I/O count */
291 /* Trace buffers per inode. */ 302 /* Trace buffers per inode. */
303#ifdef XFS_VNODE_TRACE
304 struct ktrace *i_trace; /* general inode trace */
305#endif
292#ifdef XFS_BMAP_TRACE 306#ifdef XFS_BMAP_TRACE
293 struct ktrace *i_xtrace; /* inode extent list trace */ 307 struct ktrace *i_xtrace; /* inode extent list trace */
294#endif 308#endif
@@ -349,6 +363,19 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
349 spin_unlock(&ip->i_flags_lock); 363 spin_unlock(&ip->i_flags_lock);
350 return ret; 364 return ret;
351} 365}
366
367static inline int
368xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags)
369{
370 int ret;
371
372 spin_lock(&ip->i_flags_lock);
373 ret = ip->i_flags & flags;
374 if (ret)
375 ip->i_flags &= ~flags;
376 spin_unlock(&ip->i_flags_lock);
377 return ret;
378}
352#endif /* __KERNEL__ */ 379#endif /* __KERNEL__ */
353 380
354 381
@@ -380,6 +407,9 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
380#define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */ 407#define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */
381#define XFS_INEW 0x0040 408#define XFS_INEW 0x0040
382#define XFS_IFILESTREAM 0x0080 /* inode is in a filestream directory */ 409#define XFS_IFILESTREAM 0x0080 /* inode is in a filestream directory */
410#define XFS_IMODIFIED 0x0100 /* XFS inode state possibly differs */
411 /* to the Linux inode state. */
412#define XFS_ITRUNCATED 0x0200 /* truncated down so flush-on-close */
383 413
384/* 414/*
385 * Flags for inode locking. 415 * Flags for inode locking.
@@ -454,20 +484,17 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
454#define XFS_ITRUNC_DEFINITE 0x1 484#define XFS_ITRUNC_DEFINITE 0x1
455#define XFS_ITRUNC_MAYBE 0x2 485#define XFS_ITRUNC_MAYBE 0x2
456 486
457#define XFS_ITOV(ip) BHV_TO_VNODE(XFS_ITOBHV(ip)) 487#define XFS_ITOV(ip) ((ip)->i_vnode)
458#define XFS_ITOV_NULL(ip) BHV_TO_VNODE_NULL(XFS_ITOBHV(ip)) 488#define XFS_ITOV_NULL(ip) ((ip)->i_vnode)
459#define XFS_ITOBHV(ip) ((struct bhv_desc *)(&((ip)->i_bhv_desc)))
460#define XFS_BHVTOI(bhvp) ((xfs_inode_t *)((char *)(bhvp) - \
461 (char *)&(((xfs_inode_t *)0)->i_bhv_desc)))
462#define BHV_IS_XFS(bdp) (BHV_OPS(bdp) == &xfs_vnodeops)
463 489
464/* 490/*
465 * For multiple groups support: if S_ISGID bit is set in the parent 491 * For multiple groups support: if S_ISGID bit is set in the parent
466 * directory, group of new file is set to that of the parent, and 492 * directory, group of new file is set to that of the parent, and
467 * new subdirectory gets S_ISGID bit from parent. 493 * new subdirectory gets S_ISGID bit from parent.
468 */ 494 */
469#define XFS_INHERIT_GID(pip, vfsp) \ 495#define XFS_INHERIT_GID(pip) \
470 (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID)) 496 (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \
497 ((pip)->i_d.di_mode & S_ISGID))
471 498
472/* 499/*
473 * Flags for xfs_iget() 500 * Flags for xfs_iget()
@@ -480,11 +507,9 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
480 */ 507 */
481void xfs_ihash_init(struct xfs_mount *); 508void xfs_ihash_init(struct xfs_mount *);
482void xfs_ihash_free(struct xfs_mount *); 509void xfs_ihash_free(struct xfs_mount *);
483void xfs_chash_init(struct xfs_mount *);
484void xfs_chash_free(struct xfs_mount *);
485xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, 510xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
486 struct xfs_trans *); 511 struct xfs_trans *);
487void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *); 512void xfs_inode_lock_init(xfs_inode_t *, bhv_vnode_t *);
488int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, 513int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
489 uint, uint, xfs_inode_t **, xfs_daddr_t); 514 uint, uint, xfs_inode_t **, xfs_daddr_t);
490void xfs_iput(xfs_inode_t *, uint); 515void xfs_iput(xfs_inode_t *, uint);
@@ -506,7 +531,7 @@ int xfs_finish_reclaim_all(struct xfs_mount *, int);
506 * xfs_inode.c prototypes. 531 * xfs_inode.c prototypes.
507 */ 532 */
508int xfs_itobp(struct xfs_mount *, struct xfs_trans *, 533int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
509 xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **, 534 xfs_inode_t *, struct xfs_dinode **, struct xfs_buf **,
510 xfs_daddr_t, uint); 535 xfs_daddr_t, uint);
511int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, 536int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
512 xfs_inode_t **, xfs_daddr_t, uint); 537 xfs_inode_t **, xfs_daddr_t, uint);
@@ -514,8 +539,11 @@ int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
514int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, 539int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
515 xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, 540 xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
516 int, struct xfs_buf **, boolean_t *, xfs_inode_t **); 541 int, struct xfs_buf **, boolean_t *, xfs_inode_t **);
517void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *, 542void xfs_dinode_from_disk(struct xfs_icdinode *,
518 int); 543 struct xfs_dinode_core *);
544void xfs_dinode_to_disk(struct xfs_dinode_core *,
545 struct xfs_icdinode *);
546
519uint xfs_ip2xflags(struct xfs_inode *); 547uint xfs_ip2xflags(struct xfs_inode *);
520uint xfs_dic2xflags(struct xfs_dinode_core *); 548uint xfs_dic2xflags(struct xfs_dinode_core *);
521int xfs_ifree(struct xfs_trans *, xfs_inode_t *, 549int xfs_ifree(struct xfs_trans *, xfs_inode_t *,
@@ -545,11 +573,9 @@ void xfs_ichgtime(xfs_inode_t *, int);
545xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); 573xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
546void xfs_lock_inodes(xfs_inode_t **, int, int, uint); 574void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
547 575
548xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp);
549
550void xfs_synchronize_atime(xfs_inode_t *); 576void xfs_synchronize_atime(xfs_inode_t *);
551 577
552xfs_bmbt_rec_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); 578xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t);
553void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, 579void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t,
554 xfs_bmbt_irec_t *); 580 xfs_bmbt_irec_t *);
555void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int); 581void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int);
@@ -564,7 +590,7 @@ void xfs_iext_indirect_to_direct(xfs_ifork_t *);
564void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t); 590void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t);
565void xfs_iext_inline_to_direct(xfs_ifork_t *, int); 591void xfs_iext_inline_to_direct(xfs_ifork_t *, int);
566void xfs_iext_destroy(xfs_ifork_t *); 592void xfs_iext_destroy(xfs_ifork_t *);
567xfs_bmbt_rec_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *); 593xfs_bmbt_rec_host_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *);
568xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *); 594xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *);
569xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int); 595xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int);
570void xfs_iext_irec_init(xfs_ifork_t *); 596void xfs_iext_irec_init(xfs_ifork_t *);
@@ -589,7 +615,7 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
589#define xfs_inobp_check(mp, bp) 615#define xfs_inobp_check(mp, bp)
590#endif /* DEBUG */ 616#endif /* DEBUG */
591 617
592extern struct kmem_zone *xfs_chashlist_zone; 618extern struct kmem_zone *xfs_icluster_zone;
593extern struct kmem_zone *xfs_ifork_zone; 619extern struct kmem_zone *xfs_ifork_zone;
594extern struct kmem_zone *xfs_inode_zone; 620extern struct kmem_zone *xfs_inode_zone;
595extern struct kmem_zone *xfs_ili_zone; 621extern struct kmem_zone *xfs_ili_zone;
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index 81548ec72ba6..b27b5d5be841 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -57,11 +57,11 @@ xfs_size_fn(
57 57
58STATIC int 58STATIC int
59xfs_ioinit( 59xfs_ioinit(
60 struct bhv_vfs *vfsp, 60 struct xfs_mount *mp,
61 struct xfs_mount_args *mntargs, 61 struct xfs_mount_args *mntargs,
62 int flags) 62 int flags)
63{ 63{
64 return xfs_mountfs(vfsp, XFS_VFSTOM(vfsp), flags); 64 return xfs_mountfs(mp, flags);
65} 65}
66 66
67xfs_ioops_t xfs_iocore_xfs = { 67xfs_ioops_t xfs_iocore_xfs = {
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index bf57b75acb90..72786e356d56 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -135,14 +135,10 @@ xfs_imap_to_bmap(
135 int flags) 135 int flags)
136{ 136{
137 xfs_mount_t *mp; 137 xfs_mount_t *mp;
138 xfs_fsize_t nisize;
139 int pbm; 138 int pbm;
140 xfs_fsblock_t start_block; 139 xfs_fsblock_t start_block;
141 140
142 mp = io->io_mount; 141 mp = io->io_mount;
143 nisize = XFS_SIZE(mp, io);
144 if (io->io_new_size > nisize)
145 nisize = io->io_new_size;
146 142
147 for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) { 143 for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) {
148 iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); 144 iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff);
@@ -169,10 +165,6 @@ xfs_imap_to_bmap(
169 iomapp->iomap_flags |= IOMAP_UNWRITTEN; 165 iomapp->iomap_flags |= IOMAP_UNWRITTEN;
170 } 166 }
171 167
172 if ((iomapp->iomap_offset + iomapp->iomap_bsize) >= nisize) {
173 iomapp->iomap_flags |= IOMAP_EOF;
174 }
175
176 offset += iomapp->iomap_bsize - iomapp->iomap_delta; 168 offset += iomapp->iomap_bsize - iomapp->iomap_delta;
177 } 169 }
178 return pbm; /* Return the number filled */ 170 return pbm; /* Return the number filled */
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index df441ee936b2..f5c09887fe93 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -23,7 +23,6 @@
23 23
24typedef enum { /* iomap_flags values */ 24typedef enum { /* iomap_flags values */
25 IOMAP_READ = 0, /* mapping for a read */ 25 IOMAP_READ = 0, /* mapping for a read */
26 IOMAP_EOF = 0x01, /* mapping contains EOF */
27 IOMAP_HOLE = 0x02, /* mapping covers a hole */ 26 IOMAP_HOLE = 0x02, /* mapping covers a hole */
28 IOMAP_DELAY = 0x04, /* mapping covers delalloc region */ 27 IOMAP_DELAY = 0x04, /* mapping covers delalloc region */
29 IOMAP_REALTIME = 0x10, /* mapping on the realtime device */ 28 IOMAP_REALTIME = 0x10, /* mapping on the realtime device */
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 4c2454bcc714..9972992fd3c3 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -57,7 +57,7 @@ xfs_bulkstat_one_iget(
57 xfs_bstat_t *buf, /* return buffer */ 57 xfs_bstat_t *buf, /* return buffer */
58 int *stat) /* BULKSTAT_RV_... */ 58 int *stat) /* BULKSTAT_RV_... */
59{ 59{
60 xfs_dinode_core_t *dic; /* dinode core info pointer */ 60 xfs_icdinode_t *dic; /* dinode core info pointer */
61 xfs_inode_t *ip; /* incore inode pointer */ 61 xfs_inode_t *ip; /* incore inode pointer */
62 bhv_vnode_t *vp; 62 bhv_vnode_t *vp;
63 int error; 63 int error;
@@ -151,37 +151,37 @@ xfs_bulkstat_one_dinode(
151 * the new format. We don't change the version number so that we 151 * the new format. We don't change the version number so that we
152 * can distinguish this from a real new format inode. 152 * can distinguish this from a real new format inode.
153 */ 153 */
154 if (INT_GET(dic->di_version, ARCH_CONVERT) == XFS_DINODE_VERSION_1) { 154 if (dic->di_version == XFS_DINODE_VERSION_1) {
155 buf->bs_nlink = INT_GET(dic->di_onlink, ARCH_CONVERT); 155 buf->bs_nlink = be16_to_cpu(dic->di_onlink);
156 buf->bs_projid = 0; 156 buf->bs_projid = 0;
157 } else { 157 } else {
158 buf->bs_nlink = INT_GET(dic->di_nlink, ARCH_CONVERT); 158 buf->bs_nlink = be32_to_cpu(dic->di_nlink);
159 buf->bs_projid = INT_GET(dic->di_projid, ARCH_CONVERT); 159 buf->bs_projid = be16_to_cpu(dic->di_projid);
160 } 160 }
161 161
162 buf->bs_ino = ino; 162 buf->bs_ino = ino;
163 buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT); 163 buf->bs_mode = be16_to_cpu(dic->di_mode);
164 buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT); 164 buf->bs_uid = be32_to_cpu(dic->di_uid);
165 buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT); 165 buf->bs_gid = be32_to_cpu(dic->di_gid);
166 buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT); 166 buf->bs_size = be64_to_cpu(dic->di_size);
167 buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT); 167 buf->bs_atime.tv_sec = be32_to_cpu(dic->di_atime.t_sec);
168 buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT); 168 buf->bs_atime.tv_nsec = be32_to_cpu(dic->di_atime.t_nsec);
169 buf->bs_mtime.tv_sec = INT_GET(dic->di_mtime.t_sec, ARCH_CONVERT); 169 buf->bs_mtime.tv_sec = be32_to_cpu(dic->di_mtime.t_sec);
170 buf->bs_mtime.tv_nsec = INT_GET(dic->di_mtime.t_nsec, ARCH_CONVERT); 170 buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec);
171 buf->bs_ctime.tv_sec = INT_GET(dic->di_ctime.t_sec, ARCH_CONVERT); 171 buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec);
172 buf->bs_ctime.tv_nsec = INT_GET(dic->di_ctime.t_nsec, ARCH_CONVERT); 172 buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec);
173 buf->bs_xflags = xfs_dic2xflags(dic); 173 buf->bs_xflags = xfs_dic2xflags(dic);
174 buf->bs_extsize = INT_GET(dic->di_extsize, ARCH_CONVERT) << mp->m_sb.sb_blocklog; 174 buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog;
175 buf->bs_extents = INT_GET(dic->di_nextents, ARCH_CONVERT); 175 buf->bs_extents = be32_to_cpu(dic->di_nextents);
176 buf->bs_gen = INT_GET(dic->di_gen, ARCH_CONVERT); 176 buf->bs_gen = be32_to_cpu(dic->di_gen);
177 memset(buf->bs_pad, 0, sizeof(buf->bs_pad)); 177 memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
178 buf->bs_dmevmask = INT_GET(dic->di_dmevmask, ARCH_CONVERT); 178 buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask);
179 buf->bs_dmstate = INT_GET(dic->di_dmstate, ARCH_CONVERT); 179 buf->bs_dmstate = be16_to_cpu(dic->di_dmstate);
180 buf->bs_aextents = INT_GET(dic->di_anextents, ARCH_CONVERT); 180 buf->bs_aextents = be16_to_cpu(dic->di_anextents);
181 181
182 switch (INT_GET(dic->di_format, ARCH_CONVERT)) { 182 switch (dic->di_format) {
183 case XFS_DINODE_FMT_DEV: 183 case XFS_DINODE_FMT_DEV:
184 buf->bs_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); 184 buf->bs_rdev = be32_to_cpu(dip->di_u.di_dev);
185 buf->bs_blksize = BLKDEV_IOSIZE; 185 buf->bs_blksize = BLKDEV_IOSIZE;
186 buf->bs_blocks = 0; 186 buf->bs_blocks = 0;
187 break; 187 break;
@@ -195,7 +195,7 @@ xfs_bulkstat_one_dinode(
195 case XFS_DINODE_FMT_BTREE: 195 case XFS_DINODE_FMT_BTREE:
196 buf->bs_rdev = 0; 196 buf->bs_rdev = 0;
197 buf->bs_blksize = mp->m_sb.sb_blocksize; 197 buf->bs_blksize = mp->m_sb.sb_blocksize;
198 buf->bs_blocks = INT_GET(dic->di_nblocks, ARCH_CONVERT); 198 buf->bs_blocks = be64_to_cpu(dic->di_nblocks);
199 break; 199 break;
200 } 200 }
201 201
@@ -290,16 +290,23 @@ xfs_bulkstat_use_dinode(
290 return 1; 290 return 1;
291 dip = (xfs_dinode_t *) 291 dip = (xfs_dinode_t *)
292 xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog); 292 xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog);
293 if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC || 293 /*
294 !XFS_DINODE_GOOD_VERSION( 294 * Check the buffer containing the on-disk inode for di_nlink == 0.
295 INT_GET(dip->di_core.di_version, ARCH_CONVERT))) 295 * This is to prevent xfs_bulkstat from picking up just reclaimed
296 * inodes that have their in-core state initialized but not flushed
297 * to disk yet. This is a temporary hack that would require a proper
298 * fix in the future.
299 */
300 if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC ||
301 !XFS_DINODE_GOOD_VERSION(dip->di_core.di_version) ||
302 !dip->di_core.di_nlink)
296 return 0; 303 return 0;
297 if (flags & BULKSTAT_FG_QUICK) { 304 if (flags & BULKSTAT_FG_QUICK) {
298 *dipp = dip; 305 *dipp = dip;
299 return 1; 306 return 1;
300 } 307 }
301 /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ 308 /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */
302 aformat = INT_GET(dip->di_core.di_aformat, ARCH_CONVERT); 309 aformat = dip->di_core.di_aformat;
303 if ((XFS_CFORK_Q(&dip->di_core) == 0) || 310 if ((XFS_CFORK_Q(&dip->di_core) == 0) ||
304 (aformat == XFS_DINODE_FMT_LOCAL) || 311 (aformat == XFS_DINODE_FMT_LOCAL) ||
305 (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) { 312 (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) {
@@ -612,21 +619,25 @@ xfs_bulkstat(
612 } 619 }
613 } 620 }
614 } 621 }
622 ino = XFS_AGINO_TO_INO(mp, agno, agino);
623 bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
615 /* 624 /*
616 * Skip if this inode is free. 625 * Skip if this inode is free.
617 */ 626 */
618 if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) 627 if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) {
628 lastino = ino;
619 continue; 629 continue;
630 }
620 /* 631 /*
621 * Count used inodes as free so we can tell 632 * Count used inodes as free so we can tell
622 * when the chunk is used up. 633 * when the chunk is used up.
623 */ 634 */
624 irbp->ir_freecount++; 635 irbp->ir_freecount++;
625 ino = XFS_AGINO_TO_INO(mp, agno, agino);
626 bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
627 if (!xfs_bulkstat_use_dinode(mp, flags, bp, 636 if (!xfs_bulkstat_use_dinode(mp, flags, bp,
628 clustidx, &dip)) 637 clustidx, &dip)) {
638 lastino = ino;
629 continue; 639 continue;
640 }
630 /* 641 /*
631 * If we need to do an iget, cannot hold bp. 642 * If we need to do an iget, cannot hold bp.
632 * Drop it, until starting the next cluster. 643 * Drop it, until starting the next cluster.
@@ -687,8 +698,7 @@ xfs_bulkstat(
687 if (end_of_ag) { 698 if (end_of_ag) {
688 agno++; 699 agno++;
689 agino = 0; 700 agino = 0;
690 } else 701 }
691 agino = XFS_INO_TO_AGINO(mp, lastino);
692 } else 702 } else
693 break; 703 break;
694 } 704 }
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 9bfb69e1e885..77c12715a7d0 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -252,6 +252,29 @@ xlog_grant_add_space(struct log *log, int bytes)
252 xlog_grant_add_space_reserve(log, bytes); 252 xlog_grant_add_space_reserve(log, bytes);
253} 253}
254 254
255static void
256xlog_tic_reset_res(xlog_ticket_t *tic)
257{
258 tic->t_res_num = 0;
259 tic->t_res_arr_sum = 0;
260 tic->t_res_num_ophdrs = 0;
261}
262
263static void
264xlog_tic_add_region(xlog_ticket_t *tic, uint len, uint type)
265{
266 if (tic->t_res_num == XLOG_TIC_LEN_MAX) {
267 /* add to overflow and start again */
268 tic->t_res_o_flow += tic->t_res_arr_sum;
269 tic->t_res_num = 0;
270 tic->t_res_arr_sum = 0;
271 }
272
273 tic->t_res_arr[tic->t_res_num].r_len = len;
274 tic->t_res_arr[tic->t_res_num].r_type = type;
275 tic->t_res_arr_sum += len;
276 tic->t_res_num++;
277}
255 278
256/* 279/*
257 * NOTES: 280 * NOTES:
@@ -486,7 +509,7 @@ xfs_log_mount(xfs_mount_t *mp,
486 cmn_err(CE_NOTE, 509 cmn_err(CE_NOTE,
487 "!Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.", 510 "!Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.",
488 mp->m_fsname); 511 mp->m_fsname);
489 ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY); 512 ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
490 } 513 }
491 514
492 mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks); 515 mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
@@ -496,16 +519,15 @@ xfs_log_mount(xfs_mount_t *mp,
496 * just worked. 519 * just worked.
497 */ 520 */
498 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { 521 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
499 bhv_vfs_t *vfsp = XFS_MTOVFS(mp); 522 int error, readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
500 int error, readonly = (vfsp->vfs_flag & VFS_RDONLY);
501 523
502 if (readonly) 524 if (readonly)
503 vfsp->vfs_flag &= ~VFS_RDONLY; 525 mp->m_flags &= ~XFS_MOUNT_RDONLY;
504 526
505 error = xlog_recover(mp->m_log); 527 error = xlog_recover(mp->m_log);
506 528
507 if (readonly) 529 if (readonly)
508 vfsp->vfs_flag |= VFS_RDONLY; 530 mp->m_flags |= XFS_MOUNT_RDONLY;
509 if (error) { 531 if (error) {
510 cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); 532 cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
511 xlog_dealloc_log(mp->m_log); 533 xlog_dealloc_log(mp->m_log);
@@ -537,7 +559,7 @@ xfs_log_mount_finish(xfs_mount_t *mp, int mfsi_flags)
537 error = xlog_recover_finish(mp->m_log, mfsi_flags); 559 error = xlog_recover_finish(mp->m_log, mfsi_flags);
538 else { 560 else {
539 error = 0; 561 error = 0;
540 ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY); 562 ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
541 } 563 }
542 564
543 return error; 565 return error;
@@ -597,7 +619,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
597 * Don't write out unmount record on read-only mounts. 619 * Don't write out unmount record on read-only mounts.
598 * Or, if we are doing a forced umount (typically because of IO errors). 620 * Or, if we are doing a forced umount (typically because of IO errors).
599 */ 621 */
600 if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) 622 if (mp->m_flags & XFS_MOUNT_RDONLY)
601 return 0; 623 return 0;
602 624
603 xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC); 625 xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC);
@@ -949,6 +971,19 @@ xlog_iodone(xfs_buf_t *bp)
949 l = iclog->ic_log; 971 l = iclog->ic_log;
950 972
951 /* 973 /*
974 * If the ordered flag has been removed by a lower
975 * layer, it means the underlyin device no longer supports
976 * barrier I/O. Warn loudly and turn off barriers.
977 */
978 if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ORDERED(bp)) {
979 l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER;
980 xfs_fs_cmn_err(CE_WARN, l->l_mp,
981 "xlog_iodone: Barriers are no longer supported"
982 " by device. Disabling barriers\n");
983 xfs_buftrace("XLOG_IODONE BARRIERS OFF", bp);
984 }
985
986 /*
952 * Race to shutdown the filesystem if we see an error. 987 * Race to shutdown the filesystem if we see an error.
953 */ 988 */
954 if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp, 989 if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp,
@@ -1012,10 +1047,7 @@ xlog_bdstrat_cb(struct xfs_buf *bp)
1012/* 1047/*
1013 * Return size of each in-core log record buffer. 1048 * Return size of each in-core log record buffer.
1014 * 1049 *
1015 * Low memory machines only get 2 16KB buffers. We don't want to waste 1050 * All machines get 8 x 32KB buffers by default, unless tuned otherwise.
1016 * memory here. However, all other machines get at least 2 32KB buffers.
1017 * The number is hard coded because we don't care about the minimum
1018 * memory size, just 32MB systems.
1019 * 1051 *
1020 * If the filesystem blocksize is too large, we may need to choose a 1052 * If the filesystem blocksize is too large, we may need to choose a
1021 * larger size since the directory code currently logs entire blocks. 1053 * larger size since the directory code currently logs entire blocks.
@@ -1028,17 +1060,10 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
1028 int size; 1060 int size;
1029 int xhdrs; 1061 int xhdrs;
1030 1062
1031 if (mp->m_logbufs <= 0) { 1063 if (mp->m_logbufs <= 0)
1032 if (xfs_physmem <= btoc(128*1024*1024)) { 1064 log->l_iclog_bufs = XLOG_MAX_ICLOGS;
1033 log->l_iclog_bufs = XLOG_MIN_ICLOGS; 1065 else
1034 } else if (xfs_physmem <= btoc(400*1024*1024)) {
1035 log->l_iclog_bufs = XLOG_MED_ICLOGS;
1036 } else { /* 256K with 32K bufs */
1037 log->l_iclog_bufs = XLOG_MAX_ICLOGS;
1038 }
1039 } else {
1040 log->l_iclog_bufs = mp->m_logbufs; 1066 log->l_iclog_bufs = mp->m_logbufs;
1041 }
1042 1067
1043 /* 1068 /*
1044 * Buffer size passed in from mount system call. 1069 * Buffer size passed in from mount system call.
@@ -1069,18 +1094,9 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
1069 goto done; 1094 goto done;
1070 } 1095 }
1071 1096
1072 /* 1097 /* All machines use 32KB buffers by default. */
1073 * Special case machines that have less than 32MB of memory. 1098 log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
1074 * All machines with more memory use 32KB buffers. 1099 log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
1075 */
1076 if (xfs_physmem <= btoc(32*1024*1024)) {
1077 /* Don't change; min configuration */
1078 log->l_iclog_size = XLOG_RECORD_BSIZE; /* 16k */
1079 log->l_iclog_size_log = XLOG_RECORD_BSHIFT;
1080 } else {
1081 log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; /* 32k */
1082 log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
1083 }
1084 1100
1085 /* the default log size is 16k or 32k which is one header sector */ 1101 /* the default log size is 16k or 32k which is one header sector */
1086 log->l_iclog_hsize = BBSIZE; 1102 log->l_iclog_hsize = BBSIZE;
@@ -1771,14 +1787,14 @@ xlog_write(xfs_mount_t * mp,
1771 len = 0; 1787 len = 0;
1772 if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */ 1788 if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */
1773 len += sizeof(xlog_op_header_t); 1789 len += sizeof(xlog_op_header_t);
1774 XLOG_TIC_ADD_OPHDR(ticket); 1790 ticket->t_res_num_ophdrs++;
1775 } 1791 }
1776 1792
1777 for (index = 0; index < nentries; index++) { 1793 for (index = 0; index < nentries; index++) {
1778 len += sizeof(xlog_op_header_t); /* each region gets >= 1 */ 1794 len += sizeof(xlog_op_header_t); /* each region gets >= 1 */
1779 XLOG_TIC_ADD_OPHDR(ticket); 1795 ticket->t_res_num_ophdrs++;
1780 len += reg[index].i_len; 1796 len += reg[index].i_len;
1781 XLOG_TIC_ADD_REGION(ticket, reg[index].i_len, reg[index].i_type); 1797 xlog_tic_add_region(ticket, reg[index].i_len, reg[index].i_type);
1782 } 1798 }
1783 contwr = *start_lsn = 0; 1799 contwr = *start_lsn = 0;
1784 1800
@@ -1887,7 +1903,7 @@ xlog_write(xfs_mount_t * mp,
1887 len += sizeof(xlog_op_header_t); /* from splitting of region */ 1903 len += sizeof(xlog_op_header_t); /* from splitting of region */
1888 /* account for new log op header */ 1904 /* account for new log op header */
1889 ticket->t_curr_res -= sizeof(xlog_op_header_t); 1905 ticket->t_curr_res -= sizeof(xlog_op_header_t);
1890 XLOG_TIC_ADD_OPHDR(ticket); 1906 ticket->t_res_num_ophdrs++;
1891 } 1907 }
1892 xlog_verify_dest_ptr(log, ptr); 1908 xlog_verify_dest_ptr(log, ptr);
1893 1909
@@ -2385,7 +2401,7 @@ restart:
2385 */ 2401 */
2386 if (log_offset == 0) { 2402 if (log_offset == 0) {
2387 ticket->t_curr_res -= log->l_iclog_hsize; 2403 ticket->t_curr_res -= log->l_iclog_hsize;
2388 XLOG_TIC_ADD_REGION(ticket, 2404 xlog_tic_add_region(ticket,
2389 log->l_iclog_hsize, 2405 log->l_iclog_hsize,
2390 XLOG_REG_TYPE_LRHEADER); 2406 XLOG_REG_TYPE_LRHEADER);
2391 INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle); 2407 INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle);
@@ -2573,7 +2589,7 @@ xlog_regrant_write_log_space(xlog_t *log,
2573#endif 2589#endif
2574 2590
2575 tic->t_curr_res = tic->t_unit_res; 2591 tic->t_curr_res = tic->t_unit_res;
2576 XLOG_TIC_RESET_RES(tic); 2592 xlog_tic_reset_res(tic);
2577 2593
2578 if (tic->t_cnt > 0) 2594 if (tic->t_cnt > 0)
2579 return 0; 2595 return 0;
@@ -2714,7 +2730,7 @@ xlog_regrant_reserve_log_space(xlog_t *log,
2714 s = GRANT_LOCK(log); 2730 s = GRANT_LOCK(log);
2715 xlog_grant_sub_space(log, ticket->t_curr_res); 2731 xlog_grant_sub_space(log, ticket->t_curr_res);
2716 ticket->t_curr_res = ticket->t_unit_res; 2732 ticket->t_curr_res = ticket->t_unit_res;
2717 XLOG_TIC_RESET_RES(ticket); 2733 xlog_tic_reset_res(ticket);
2718 xlog_trace_loggrant(log, ticket, 2734 xlog_trace_loggrant(log, ticket,
2719 "xlog_regrant_reserve_log_space: sub current res"); 2735 "xlog_regrant_reserve_log_space: sub current res");
2720 xlog_verify_grant_head(log, 1); 2736 xlog_verify_grant_head(log, 1);
@@ -2731,7 +2747,7 @@ xlog_regrant_reserve_log_space(xlog_t *log,
2731 xlog_verify_grant_head(log, 0); 2747 xlog_verify_grant_head(log, 0);
2732 GRANT_UNLOCK(log, s); 2748 GRANT_UNLOCK(log, s);
2733 ticket->t_curr_res = ticket->t_unit_res; 2749 ticket->t_curr_res = ticket->t_unit_res;
2734 XLOG_TIC_RESET_RES(ticket); 2750 xlog_tic_reset_res(ticket);
2735} /* xlog_regrant_reserve_log_space */ 2751} /* xlog_regrant_reserve_log_space */
2736 2752
2737 2753
@@ -3354,7 +3370,7 @@ xlog_ticket_get(xlog_t *log,
3354 tic->t_flags |= XLOG_TIC_PERM_RESERV; 3370 tic->t_flags |= XLOG_TIC_PERM_RESERV;
3355 sv_init(&(tic->t_sema), SV_DEFAULT, "logtick"); 3371 sv_init(&(tic->t_sema), SV_DEFAULT, "logtick");
3356 3372
3357 XLOG_TIC_RESET_RES(tic); 3373 xlog_tic_reset_res(tic);
3358 3374
3359 return tic; 3375 return tic;
3360} /* xlog_ticket_get */ 3376} /* xlog_ticket_get */
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 9bd3cdf11a87..752f964b3699 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -30,17 +30,16 @@ struct xfs_mount;
30 */ 30 */
31 31
32#define XLOG_MIN_ICLOGS 2 32#define XLOG_MIN_ICLOGS 2
33#define XLOG_MED_ICLOGS 4
34#define XLOG_MAX_ICLOGS 8 33#define XLOG_MAX_ICLOGS 8
35#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */ 34#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */
36#define XLOG_VERSION_1 1 35#define XLOG_VERSION_1 1
37#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ 36#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */
38#define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2) 37#define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2)
39#define XLOG_RECORD_BSIZE (16*1024) /* eventually 32k */ 38#define XLOG_MIN_RECORD_BSIZE (16*1024) /* eventually 32k */
40#define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */ 39#define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */
41#define XLOG_MAX_RECORD_BSIZE (256*1024) 40#define XLOG_MAX_RECORD_BSIZE (256*1024)
42#define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */ 41#define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */
43#define XLOG_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */ 42#define XLOG_MIN_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */
44#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */ 43#define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */
45#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */ 44#define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */
46#define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \ 45#define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \
@@ -250,22 +249,6 @@ typedef __uint32_t xlog_tid_t;
250 249
251/* Ticket reservation region accounting */ 250/* Ticket reservation region accounting */
252#define XLOG_TIC_LEN_MAX 15 251#define XLOG_TIC_LEN_MAX 15
253#define XLOG_TIC_RESET_RES(t) ((t)->t_res_num = \
254 (t)->t_res_arr_sum = (t)->t_res_num_ophdrs = 0)
255#define XLOG_TIC_ADD_OPHDR(t) ((t)->t_res_num_ophdrs++)
256#define XLOG_TIC_ADD_REGION(t, len, type) \
257 do { \
258 if ((t)->t_res_num == XLOG_TIC_LEN_MAX) { \
259 /* add to overflow and start again */ \
260 (t)->t_res_o_flow += (t)->t_res_arr_sum; \
261 (t)->t_res_num = 0; \
262 (t)->t_res_arr_sum = 0; \
263 } \
264 (t)->t_res_arr[(t)->t_res_num].r_len = (len); \
265 (t)->t_res_arr[(t)->t_res_num].r_type = (type); \
266 (t)->t_res_arr_sum += (len); \
267 (t)->t_res_num++; \
268 } while (0)
269 252
270/* 253/*
271 * Reservation region 254 * Reservation region
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 8ae6e8e5f3db..851eca8a7150 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -2245,7 +2245,7 @@ xlog_recover_do_inode_trans(
2245 int error; 2245 int error;
2246 int attr_index; 2246 int attr_index;
2247 uint fields; 2247 uint fields;
2248 xfs_dinode_core_t *dicp; 2248 xfs_icdinode_t *dicp;
2249 int need_free = 0; 2249 int need_free = 0;
2250 2250
2251 if (pass == XLOG_RECOVER_PASS1) { 2251 if (pass == XLOG_RECOVER_PASS1) {
@@ -2309,7 +2309,7 @@ xlog_recover_do_inode_trans(
2309 * Make sure the place we're flushing out to really looks 2309 * Make sure the place we're flushing out to really looks
2310 * like an inode! 2310 * like an inode!
2311 */ 2311 */
2312 if (unlikely(INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC)) { 2312 if (unlikely(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC)) {
2313 xfs_buf_relse(bp); 2313 xfs_buf_relse(bp);
2314 xfs_fs_cmn_err(CE_ALERT, mp, 2314 xfs_fs_cmn_err(CE_ALERT, mp,
2315 "xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld", 2315 "xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld",
@@ -2319,7 +2319,7 @@ xlog_recover_do_inode_trans(
2319 error = EFSCORRUPTED; 2319 error = EFSCORRUPTED;
2320 goto error; 2320 goto error;
2321 } 2321 }
2322 dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr); 2322 dicp = (xfs_icdinode_t *)(item->ri_buf[1].i_addr);
2323 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { 2323 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
2324 xfs_buf_relse(bp); 2324 xfs_buf_relse(bp);
2325 xfs_fs_cmn_err(CE_ALERT, mp, 2325 xfs_fs_cmn_err(CE_ALERT, mp,
@@ -2332,15 +2332,13 @@ xlog_recover_do_inode_trans(
2332 } 2332 }
2333 2333
2334 /* Skip replay when the on disk inode is newer than the log one */ 2334 /* Skip replay when the on disk inode is newer than the log one */
2335 if (dicp->di_flushiter < 2335 if (dicp->di_flushiter < be16_to_cpu(dip->di_core.di_flushiter)) {
2336 INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT)) {
2337 /* 2336 /*
2338 * Deal with the wrap case, DI_MAX_FLUSH is less 2337 * Deal with the wrap case, DI_MAX_FLUSH is less
2339 * than smaller numbers 2338 * than smaller numbers
2340 */ 2339 */
2341 if ((INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT) 2340 if (be16_to_cpu(dip->di_core.di_flushiter) == DI_MAX_FLUSH &&
2342 == DI_MAX_FLUSH) && 2341 dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) {
2343 (dicp->di_flushiter < (DI_MAX_FLUSH>>1))) {
2344 /* do nothing */ 2342 /* do nothing */
2345 } else { 2343 } else {
2346 xfs_buf_relse(bp); 2344 xfs_buf_relse(bp);
@@ -2411,8 +2409,8 @@ xlog_recover_do_inode_trans(
2411 } 2409 }
2412 2410
2413 /* The core is in in-core format */ 2411 /* The core is in in-core format */
2414 xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core, 2412 xfs_dinode_to_disk(&dip->di_core,
2415 (xfs_dinode_core_t*)item->ri_buf[1].i_addr, -1); 2413 (xfs_icdinode_t *)item->ri_buf[1].i_addr);
2416 2414
2417 /* the rest is in on-disk format */ 2415 /* the rest is in on-disk format */
2418 if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) { 2416 if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) {
@@ -2424,8 +2422,7 @@ xlog_recover_do_inode_trans(
2424 fields = in_f->ilf_fields; 2422 fields = in_f->ilf_fields;
2425 switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) { 2423 switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
2426 case XFS_ILOG_DEV: 2424 case XFS_ILOG_DEV:
2427 INT_SET(dip->di_u.di_dev, ARCH_CONVERT, in_f->ilf_u.ilfu_rdev); 2425 dip->di_u.di_dev = cpu_to_be32(in_f->ilf_u.ilfu_rdev);
2428
2429 break; 2426 break;
2430 case XFS_ILOG_UUID: 2427 case XFS_ILOG_UUID:
2431 dip->di_u.di_muuid = in_f->ilf_u.ilfu_uuid; 2428 dip->di_u.di_muuid = in_f->ilf_u.ilfu_uuid;
@@ -3234,8 +3231,8 @@ xlog_recover_process_iunlinks(
3234 ASSERT(ip->i_d.di_nlink == 0); 3231 ASSERT(ip->i_d.di_nlink == 0);
3235 3232
3236 /* setup for the next pass */ 3233 /* setup for the next pass */
3237 agino = INT_GET(dip->di_next_unlinked, 3234 agino = be32_to_cpu(
3238 ARCH_CONVERT); 3235 dip->di_next_unlinked);
3239 xfs_buf_relse(ibp); 3236 xfs_buf_relse(ibp);
3240 /* 3237 /*
3241 * Prevent any DMAPI event from 3238 * Prevent any DMAPI event from
@@ -3837,7 +3834,10 @@ xlog_do_recover(
3837 */ 3834 */
3838 bp = xfs_getsb(log->l_mp, 0); 3835 bp = xfs_getsb(log->l_mp, 0);
3839 XFS_BUF_UNDONE(bp); 3836 XFS_BUF_UNDONE(bp);
3837 ASSERT(!(XFS_BUF_ISWRITE(bp)));
3838 ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
3840 XFS_BUF_READ(bp); 3839 XFS_BUF_READ(bp);
3840 XFS_BUF_UNASYNC(bp);
3841 xfsbdstrat(log->l_mp, bp); 3841 xfsbdstrat(log->l_mp, bp);
3842 if ((error = xfs_iowait(bp))) { 3842 if ((error = xfs_iowait(bp))) {
3843 xfs_ioerror_alert("xlog_do_recover", 3843 xfs_ioerror_alert("xlog_do_recover",
@@ -3849,7 +3849,7 @@ xlog_do_recover(
3849 3849
3850 /* Convert superblock from on-disk format */ 3850 /* Convert superblock from on-disk format */
3851 sbp = &log->l_mp->m_sb; 3851 sbp = &log->l_mp->m_sb;
3852 xfs_xlatesb(XFS_BUF_TO_SBP(bp), sbp, 1, XFS_SB_ALL_BITS); 3852 xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
3853 ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC); 3853 ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC);
3854 ASSERT(XFS_SB_GOOD_VERSION(sbp)); 3854 ASSERT(XFS_SB_GOOD_VERSION(sbp));
3855 xfs_buf_relse(bp); 3855 xfs_buf_relse(bp);
@@ -4027,7 +4027,7 @@ xlog_recover_check_summary(
4027 sbbp = xfs_getsb(mp, 0); 4027 sbbp = xfs_getsb(mp, 0);
4028#ifdef XFS_LOUD_RECOVERY 4028#ifdef XFS_LOUD_RECOVERY
4029 sbp = &mp->m_sb; 4029 sbp = &mp->m_sb;
4030 xfs_xlatesb(XFS_BUF_TO_SBP(sbbp), sbp, 1, XFS_SB_ALL_BITS); 4030 xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(sbbp));
4031 cmn_err(CE_NOTE, 4031 cmn_err(CE_NOTE,
4032 "xlog_recover_check_summary: sb_icount %Lu itotal %Lu", 4032 "xlog_recover_check_summary: sb_icount %Lu itotal %Lu",
4033 sbp->sb_icount, itotal); 4033 sbp->sb_icount, itotal);
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index a66b39805176..ebdb76da527c 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -139,7 +139,7 @@ xfs_mount_init(void)
139 AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail"); 139 AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail");
140 spinlock_init(&mp->m_sb_lock, "xfs_sb"); 140 spinlock_init(&mp->m_sb_lock, "xfs_sb");
141 mutex_init(&mp->m_ilock); 141 mutex_init(&mp->m_ilock);
142 initnsema(&mp->m_growlock, 1, "xfs_grow"); 142 mutex_init(&mp->m_growlock);
143 /* 143 /*
144 * Initialize the AIL. 144 * Initialize the AIL.
145 */ 145 */
@@ -157,14 +157,8 @@ xfs_mount_init(void)
157 */ 157 */
158void 158void
159xfs_mount_free( 159xfs_mount_free(
160 xfs_mount_t *mp, 160 xfs_mount_t *mp)
161 int remove_bhv)
162{ 161{
163 if (mp->m_ihash)
164 xfs_ihash_free(mp);
165 if (mp->m_chash)
166 xfs_chash_free(mp);
167
168 if (mp->m_perag) { 162 if (mp->m_perag) {
169 int agno; 163 int agno;
170 164
@@ -180,7 +174,7 @@ xfs_mount_free(
180 AIL_LOCK_DESTROY(&mp->m_ail_lock); 174 AIL_LOCK_DESTROY(&mp->m_ail_lock);
181 spinlock_destroy(&mp->m_sb_lock); 175 spinlock_destroy(&mp->m_sb_lock);
182 mutex_destroy(&mp->m_ilock); 176 mutex_destroy(&mp->m_ilock);
183 freesema(&mp->m_growlock); 177 mutex_destroy(&mp->m_growlock);
184 if (mp->m_quotainfo) 178 if (mp->m_quotainfo)
185 XFS_QM_DONE(mp); 179 XFS_QM_DONE(mp);
186 180
@@ -191,15 +185,7 @@ xfs_mount_free(
191 if (mp->m_logname != NULL) 185 if (mp->m_logname != NULL)
192 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); 186 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
193 187
194 if (remove_bhv) {
195 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
196
197 bhv_remove_all_vfsops(vfsp, 0);
198 VFS_REMOVEBHV(vfsp, &mp->m_bhv);
199 }
200
201 xfs_icsb_destroy_counters(mp); 188 xfs_icsb_destroy_counters(mp);
202 kmem_free(mp, sizeof(xfs_mount_t));
203} 189}
204 190
205/* 191/*
@@ -342,9 +328,19 @@ xfs_mount_validate_sb(
342 return 0; 328 return 0;
343} 329}
344 330
331STATIC void
332xfs_initialize_perag_icache(
333 xfs_perag_t *pag)
334{
335 if (!pag->pag_ici_init) {
336 rwlock_init(&pag->pag_ici_lock);
337 INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
338 pag->pag_ici_init = 1;
339 }
340}
341
345xfs_agnumber_t 342xfs_agnumber_t
346xfs_initialize_perag( 343xfs_initialize_perag(
347 bhv_vfs_t *vfs,
348 xfs_mount_t *mp, 344 xfs_mount_t *mp,
349 xfs_agnumber_t agcount) 345 xfs_agnumber_t agcount)
350{ 346{
@@ -362,7 +358,7 @@ xfs_initialize_perag(
362 /* Clear the mount flag if no inode can overflow 32 bits 358 /* Clear the mount flag if no inode can overflow 32 bits
363 * on this filesystem, or if specifically requested.. 359 * on this filesystem, or if specifically requested..
364 */ 360 */
365 if ((vfs->vfs_flag & VFS_32BITINODES) && ino > max_inum) { 361 if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) {
366 mp->m_flags |= XFS_MOUNT_32BITINODES; 362 mp->m_flags |= XFS_MOUNT_32BITINODES;
367 } else { 363 } else {
368 mp->m_flags &= ~XFS_MOUNT_32BITINODES; 364 mp->m_flags &= ~XFS_MOUNT_32BITINODES;
@@ -396,48 +392,92 @@ xfs_initialize_perag(
396 pag->pagi_inodeok = 1; 392 pag->pagi_inodeok = 1;
397 if (index < max_metadata) 393 if (index < max_metadata)
398 pag->pagf_metadata = 1; 394 pag->pagf_metadata = 1;
395 xfs_initialize_perag_icache(pag);
399 } 396 }
400 } else { 397 } else {
401 /* Setup default behavior for smaller filesystems */ 398 /* Setup default behavior for smaller filesystems */
402 for (index = 0; index < agcount; index++) { 399 for (index = 0; index < agcount; index++) {
403 pag = &mp->m_perag[index]; 400 pag = &mp->m_perag[index];
404 pag->pagi_inodeok = 1; 401 pag->pagi_inodeok = 1;
402 xfs_initialize_perag_icache(pag);
405 } 403 }
406 } 404 }
407 return index; 405 return index;
408} 406}
409 407
408void
409xfs_sb_from_disk(
410 xfs_sb_t *to,
411 xfs_dsb_t *from)
412{
413 to->sb_magicnum = be32_to_cpu(from->sb_magicnum);
414 to->sb_blocksize = be32_to_cpu(from->sb_blocksize);
415 to->sb_dblocks = be64_to_cpu(from->sb_dblocks);
416 to->sb_rblocks = be64_to_cpu(from->sb_rblocks);
417 to->sb_rextents = be64_to_cpu(from->sb_rextents);
418 memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid));
419 to->sb_logstart = be64_to_cpu(from->sb_logstart);
420 to->sb_rootino = be64_to_cpu(from->sb_rootino);
421 to->sb_rbmino = be64_to_cpu(from->sb_rbmino);
422 to->sb_rsumino = be64_to_cpu(from->sb_rsumino);
423 to->sb_rextsize = be32_to_cpu(from->sb_rextsize);
424 to->sb_agblocks = be32_to_cpu(from->sb_agblocks);
425 to->sb_agcount = be32_to_cpu(from->sb_agcount);
426 to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks);
427 to->sb_logblocks = be32_to_cpu(from->sb_logblocks);
428 to->sb_versionnum = be16_to_cpu(from->sb_versionnum);
429 to->sb_sectsize = be16_to_cpu(from->sb_sectsize);
430 to->sb_inodesize = be16_to_cpu(from->sb_inodesize);
431 to->sb_inopblock = be16_to_cpu(from->sb_inopblock);
432 memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname));
433 to->sb_blocklog = from->sb_blocklog;
434 to->sb_sectlog = from->sb_sectlog;
435 to->sb_inodelog = from->sb_inodelog;
436 to->sb_inopblog = from->sb_inopblog;
437 to->sb_agblklog = from->sb_agblklog;
438 to->sb_rextslog = from->sb_rextslog;
439 to->sb_inprogress = from->sb_inprogress;
440 to->sb_imax_pct = from->sb_imax_pct;
441 to->sb_icount = be64_to_cpu(from->sb_icount);
442 to->sb_ifree = be64_to_cpu(from->sb_ifree);
443 to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks);
444 to->sb_frextents = be64_to_cpu(from->sb_frextents);
445 to->sb_uquotino = be64_to_cpu(from->sb_uquotino);
446 to->sb_gquotino = be64_to_cpu(from->sb_gquotino);
447 to->sb_qflags = be16_to_cpu(from->sb_qflags);
448 to->sb_flags = from->sb_flags;
449 to->sb_shared_vn = from->sb_shared_vn;
450 to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt);
451 to->sb_unit = be32_to_cpu(from->sb_unit);
452 to->sb_width = be32_to_cpu(from->sb_width);
453 to->sb_dirblklog = from->sb_dirblklog;
454 to->sb_logsectlog = from->sb_logsectlog;
455 to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
456 to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
457 to->sb_features2 = be32_to_cpu(from->sb_features2);
458}
459
410/* 460/*
411 * xfs_xlatesb 461 * Copy in core superblock to ondisk one.
412 * 462 *
413 * data - on disk version of sb 463 * The fields argument is mask of superblock fields to copy.
414 * sb - a superblock
415 * dir - conversion direction: <0 - convert sb to buf
416 * >0 - convert buf to sb
417 * fields - which fields to copy (bitmask)
418 */ 464 */
419void 465void
420xfs_xlatesb( 466xfs_sb_to_disk(
421 void *data, 467 xfs_dsb_t *to,
422 xfs_sb_t *sb, 468 xfs_sb_t *from,
423 int dir,
424 __int64_t fields) 469 __int64_t fields)
425{ 470{
426 xfs_caddr_t buf_ptr; 471 xfs_caddr_t to_ptr = (xfs_caddr_t)to;
427 xfs_caddr_t mem_ptr; 472 xfs_caddr_t from_ptr = (xfs_caddr_t)from;
428 xfs_sb_field_t f; 473 xfs_sb_field_t f;
429 int first; 474 int first;
430 int size; 475 int size;
431 476
432 ASSERT(dir);
433 ASSERT(fields); 477 ASSERT(fields);
434
435 if (!fields) 478 if (!fields)
436 return; 479 return;
437 480
438 buf_ptr = (xfs_caddr_t)data;
439 mem_ptr = (xfs_caddr_t)sb;
440
441 while (fields) { 481 while (fields) {
442 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); 482 f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields);
443 first = xfs_sb_info[f].offset; 483 first = xfs_sb_info[f].offset;
@@ -446,26 +486,20 @@ xfs_xlatesb(
446 ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); 486 ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1);
447 487
448 if (size == 1 || xfs_sb_info[f].type == 1) { 488 if (size == 1 || xfs_sb_info[f].type == 1) {
449 if (dir > 0) { 489 memcpy(to_ptr + first, from_ptr + first, size);
450 memcpy(mem_ptr + first, buf_ptr + first, size);
451 } else {
452 memcpy(buf_ptr + first, mem_ptr + first, size);
453 }
454 } else { 490 } else {
455 switch (size) { 491 switch (size) {
456 case 2: 492 case 2:
457 INT_XLATE(*(__uint16_t*)(buf_ptr+first), 493 *(__be16 *)(to_ptr + first) =
458 *(__uint16_t*)(mem_ptr+first), 494 cpu_to_be16(*(__u16 *)(from_ptr + first));
459 dir, ARCH_CONVERT);
460 break; 495 break;
461 case 4: 496 case 4:
462 INT_XLATE(*(__uint32_t*)(buf_ptr+first), 497 *(__be32 *)(to_ptr + first) =
463 *(__uint32_t*)(mem_ptr+first), 498 cpu_to_be32(*(__u32 *)(from_ptr + first));
464 dir, ARCH_CONVERT);
465 break; 499 break;
466 case 8: 500 case 8:
467 INT_XLATE(*(__uint64_t*)(buf_ptr+first), 501 *(__be64 *)(to_ptr + first) =
468 *(__uint64_t*)(mem_ptr+first), dir, ARCH_CONVERT); 502 cpu_to_be64(*(__u64 *)(from_ptr + first));
469 break; 503 break;
470 default: 504 default:
471 ASSERT(0); 505 ASSERT(0);
@@ -487,7 +521,6 @@ xfs_readsb(xfs_mount_t *mp, int flags)
487 unsigned int sector_size; 521 unsigned int sector_size;
488 unsigned int extra_flags; 522 unsigned int extra_flags;
489 xfs_buf_t *bp; 523 xfs_buf_t *bp;
490 xfs_sb_t *sbp;
491 int error; 524 int error;
492 525
493 ASSERT(mp->m_sb_bp == NULL); 526 ASSERT(mp->m_sb_bp == NULL);
@@ -515,8 +548,7 @@ xfs_readsb(xfs_mount_t *mp, int flags)
515 * Initialize the mount structure from the superblock. 548 * Initialize the mount structure from the superblock.
516 * But first do some basic consistency checking. 549 * But first do some basic consistency checking.
517 */ 550 */
518 sbp = XFS_BUF_TO_SBP(bp); 551 xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
519 xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS);
520 552
521 error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags); 553 error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags);
522 if (error) { 554 if (error) {
@@ -715,7 +747,6 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
715 */ 747 */
716int 748int
717xfs_mountfs( 749xfs_mountfs(
718 bhv_vfs_t *vfsp,
719 xfs_mount_t *mp, 750 xfs_mount_t *mp,
720 int mfsi_flags) 751 int mfsi_flags)
721{ 752{
@@ -842,14 +873,11 @@ xfs_mountfs(
842 */ 873 */
843 if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && 874 if ((mfsi_flags & XFS_MFSI_SECOND) == 0 &&
844 (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { 875 (mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
845 __uint64_t ret64;
846 if (xfs_uuid_mount(mp)) { 876 if (xfs_uuid_mount(mp)) {
847 error = XFS_ERROR(EINVAL); 877 error = XFS_ERROR(EINVAL);
848 goto error1; 878 goto error1;
849 } 879 }
850 uuid_mounted=1; 880 uuid_mounted=1;
851 ret64 = uuid_hash64(&sbp->sb_uuid);
852 memcpy(&vfsp->vfs_fsid, &ret64, sizeof(ret64));
853 } 881 }
854 882
855 /* 883 /*
@@ -871,16 +899,6 @@ xfs_mountfs(
871 writeio_log = mp->m_writeio_log; 899 writeio_log = mp->m_writeio_log;
872 } 900 }
873 901
874 /*
875 * Set the number of readahead buffers to use based on
876 * physical memory size.
877 */
878 if (xfs_physmem <= 4096) /* <= 16MB */
879 mp->m_nreadaheads = XFS_RW_NREADAHEAD_16MB;
880 else if (xfs_physmem <= 8192) /* <= 32MB */
881 mp->m_nreadaheads = XFS_RW_NREADAHEAD_32MB;
882 else
883 mp->m_nreadaheads = XFS_RW_NREADAHEAD_K32;
884 if (sbp->sb_blocklog > readio_log) { 902 if (sbp->sb_blocklog > readio_log) {
885 mp->m_readio_log = sbp->sb_blocklog; 903 mp->m_readio_log = sbp->sb_blocklog;
886 } else { 904 } else {
@@ -895,15 +913,12 @@ xfs_mountfs(
895 mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog); 913 mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog);
896 914
897 /* 915 /*
898 * Set the inode cluster size based on the physical memory 916 * Set the inode cluster size.
899 * size. This may still be overridden by the file system 917 * This may still be overridden by the file system
900 * block size if it is larger than the chosen cluster size. 918 * block size if it is larger than the chosen cluster size.
901 */ 919 */
902 if (xfs_physmem <= btoc(32 * 1024 * 1024)) { /* <= 32 MB */ 920 mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
903 mp->m_inode_cluster_size = XFS_INODE_SMALL_CLUSTER_SIZE; 921
904 } else {
905 mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
906 }
907 /* 922 /*
908 * Set whether we're using inode alignment. 923 * Set whether we're using inode alignment.
909 */ 924 */
@@ -987,16 +1002,6 @@ xfs_mountfs(
987 */ 1002 */
988 uuid_getnodeuniq(&sbp->sb_uuid, mp->m_fixedfsid); 1003 uuid_getnodeuniq(&sbp->sb_uuid, mp->m_fixedfsid);
989 1004
990 /*
991 * The vfs structure needs to have a file system independent
992 * way of checking for the invariant file system ID. Since it
993 * can't look at mount structures it has a pointer to the data
994 * in the mount structure.
995 *
996 * File systems that don't support user level file handles (i.e.
997 * all of them except for XFS) will leave vfs_altfsid as NULL.
998 */
999 vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
1000 mp->m_dmevmask = 0; /* not persistent; set after each mount */ 1005 mp->m_dmevmask = 0; /* not persistent; set after each mount */
1001 1006
1002 xfs_dir_mount(mp); 1007 xfs_dir_mount(mp);
@@ -1012,20 +1017,13 @@ xfs_mountfs(
1012 xfs_trans_init(mp); 1017 xfs_trans_init(mp);
1013 1018
1014 /* 1019 /*
1015 * Allocate and initialize the inode hash table for this
1016 * file system.
1017 */
1018 xfs_ihash_init(mp);
1019 xfs_chash_init(mp);
1020
1021 /*
1022 * Allocate and initialize the per-ag data. 1020 * Allocate and initialize the per-ag data.
1023 */ 1021 */
1024 init_rwsem(&mp->m_peraglock); 1022 init_rwsem(&mp->m_peraglock);
1025 mp->m_perag = 1023 mp->m_perag =
1026 kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP); 1024 kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP);
1027 1025
1028 mp->m_maxagi = xfs_initialize_perag(vfsp, mp, sbp->sb_agcount); 1026 mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount);
1029 1027
1030 /* 1028 /*
1031 * log's mount-time initialization. Perform 1st part recovery if needed 1029 * log's mount-time initialization. Perform 1st part recovery if needed
@@ -1116,7 +1114,7 @@ xfs_mountfs(
1116 * If fs is not mounted readonly, then update the superblock 1114 * If fs is not mounted readonly, then update the superblock
1117 * unit and width changes. 1115 * unit and width changes.
1118 */ 1116 */
1119 if (update_flags && !(vfsp->vfs_flag & VFS_RDONLY)) 1117 if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY))
1120 xfs_mount_log_sbunit(mp, update_flags); 1118 xfs_mount_log_sbunit(mp, update_flags);
1121 1119
1122 /* 1120 /*
@@ -1169,8 +1167,6 @@ xfs_mountfs(
1169 error3: 1167 error3:
1170 xfs_log_unmount_dealloc(mp); 1168 xfs_log_unmount_dealloc(mp);
1171 error2: 1169 error2:
1172 xfs_ihash_free(mp);
1173 xfs_chash_free(mp);
1174 for (agno = 0; agno < sbp->sb_agcount; agno++) 1170 for (agno = 0; agno < sbp->sb_agcount; agno++)
1175 if (mp->m_perag[agno].pagb_list) 1171 if (mp->m_perag[agno].pagb_list)
1176 kmem_free(mp->m_perag[agno].pagb_list, 1172 kmem_free(mp->m_perag[agno].pagb_list,
@@ -1194,10 +1190,6 @@ xfs_mountfs(
1194int 1190int
1195xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) 1191xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1196{ 1192{
1197 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1198#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
1199 int64_t fsid;
1200#endif
1201 __uint64_t resblks; 1193 __uint64_t resblks;
1202 1194
1203 /* 1195 /*
@@ -1261,21 +1253,17 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1261 xfs_uuid_unmount(mp); 1253 xfs_uuid_unmount(mp);
1262 1254
1263#if defined(DEBUG) || defined(INDUCE_IO_ERROR) 1255#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
1264 /* 1256 xfs_errortag_clearall(mp, 0);
1265 * clear all error tags on this filesystem
1266 */
1267 memcpy(&fsid, &vfsp->vfs_fsid, sizeof(int64_t));
1268 xfs_errortag_clearall_umount(fsid, mp->m_fsname, 0);
1269#endif 1257#endif
1270 XFS_IODONE(vfsp); 1258 XFS_IODONE(mp);
1271 xfs_mount_free(mp, 1); 1259 xfs_mount_free(mp);
1272 return 0; 1260 return 0;
1273} 1261}
1274 1262
1275void 1263void
1276xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr) 1264xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
1277{ 1265{
1278 if (mp->m_logdev_targp != mp->m_ddev_targp) 1266 if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp)
1279 xfs_free_buftarg(mp->m_logdev_targp, 1); 1267 xfs_free_buftarg(mp->m_logdev_targp, 1);
1280 if (mp->m_rtdev_targp) 1268 if (mp->m_rtdev_targp)
1281 xfs_free_buftarg(mp->m_rtdev_targp, 1); 1269 xfs_free_buftarg(mp->m_rtdev_targp, 1);
@@ -1295,10 +1283,8 @@ xfs_unmountfs_wait(xfs_mount_t *mp)
1295int 1283int
1296xfs_fs_writable(xfs_mount_t *mp) 1284xfs_fs_writable(xfs_mount_t *mp)
1297{ 1285{
1298 bhv_vfs_t *vfsp = XFS_MTOVFS(mp); 1286 return !(xfs_test_for_freeze(mp) || XFS_FORCED_SHUTDOWN(mp) ||
1299 1287 (mp->m_flags & XFS_MOUNT_RDONLY));
1300 return !(vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
1301 (vfsp->vfs_flag & VFS_RDONLY));
1302} 1288}
1303 1289
1304/* 1290/*
@@ -1348,34 +1334,44 @@ xfs_log_sbcount(
1348 return 0; 1334 return 0;
1349} 1335}
1350 1336
1337STATIC void
1338xfs_mark_shared_ro(
1339 xfs_mount_t *mp,
1340 xfs_buf_t *bp)
1341{
1342 xfs_dsb_t *sb = XFS_BUF_TO_SBP(bp);
1343 __uint16_t version;
1344
1345 if (!(sb->sb_flags & XFS_SBF_READONLY))
1346 sb->sb_flags |= XFS_SBF_READONLY;
1347
1348 version = be16_to_cpu(sb->sb_versionnum);
1349 if ((version & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4 ||
1350 !(version & XFS_SB_VERSION_SHAREDBIT))
1351 version |= XFS_SB_VERSION_SHAREDBIT;
1352 sb->sb_versionnum = cpu_to_be16(version);
1353}
1354
1351int 1355int
1352xfs_unmountfs_writesb(xfs_mount_t *mp) 1356xfs_unmountfs_writesb(xfs_mount_t *mp)
1353{ 1357{
1354 xfs_buf_t *sbp; 1358 xfs_buf_t *sbp;
1355 xfs_sb_t *sb;
1356 int error = 0; 1359 int error = 0;
1357 1360
1358 /* 1361 /*
1359 * skip superblock write if fs is read-only, or 1362 * skip superblock write if fs is read-only, or
1360 * if we are doing a forced umount. 1363 * if we are doing a forced umount.
1361 */ 1364 */
1362 if (!(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY || 1365 if (!((mp->m_flags & XFS_MOUNT_RDONLY) ||
1363 XFS_FORCED_SHUTDOWN(mp))) { 1366 XFS_FORCED_SHUTDOWN(mp))) {
1364 1367
1365 sbp = xfs_getsb(mp, 0); 1368 sbp = xfs_getsb(mp, 0);
1366 sb = XFS_BUF_TO_SBP(sbp);
1367 1369
1368 /* 1370 /*
1369 * mark shared-readonly if desired 1371 * mark shared-readonly if desired
1370 */ 1372 */
1371 if (mp->m_mk_sharedro) { 1373 if (mp->m_mk_sharedro)
1372 if (!(sb->sb_flags & XFS_SBF_READONLY)) 1374 xfs_mark_shared_ro(mp, sbp);
1373 sb->sb_flags |= XFS_SBF_READONLY;
1374 if (!XFS_SB_VERSION_HASSHARED(sb))
1375 XFS_SB_VERSION_ADDSHARED(sb);
1376 xfs_fs_cmn_err(CE_NOTE, mp,
1377 "Unmounting, marking shared read-only");
1378 }
1379 1375
1380 XFS_BUF_UNDONE(sbp); 1376 XFS_BUF_UNDONE(sbp);
1381 XFS_BUF_UNREAD(sbp); 1377 XFS_BUF_UNREAD(sbp);
@@ -1410,7 +1406,6 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
1410 int first; 1406 int first;
1411 int last; 1407 int last;
1412 xfs_mount_t *mp; 1408 xfs_mount_t *mp;
1413 xfs_sb_t *sbp;
1414 xfs_sb_field_t f; 1409 xfs_sb_field_t f;
1415 1410
1416 ASSERT(fields); 1411 ASSERT(fields);
@@ -1418,13 +1413,12 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
1418 return; 1413 return;
1419 mp = tp->t_mountp; 1414 mp = tp->t_mountp;
1420 bp = xfs_trans_getsb(tp, mp, 0); 1415 bp = xfs_trans_getsb(tp, mp, 0);
1421 sbp = XFS_BUF_TO_SBP(bp);
1422 first = sizeof(xfs_sb_t); 1416 first = sizeof(xfs_sb_t);
1423 last = 0; 1417 last = 0;
1424 1418
1425 /* translate/copy */ 1419 /* translate/copy */
1426 1420
1427 xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), -1, fields); 1421 xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields);
1428 1422
1429 /* find modified range */ 1423 /* find modified range */
1430 1424
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 76ad74758696..c618f7cb5f0e 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -54,13 +54,8 @@ typedef struct xfs_trans_reservations {
54#else 54#else
55struct cred; 55struct cred;
56struct log; 56struct log;
57struct bhv_vfs;
58struct bhv_vnode;
59struct xfs_mount_args; 57struct xfs_mount_args;
60struct xfs_ihash;
61struct xfs_chash;
62struct xfs_inode; 58struct xfs_inode;
63struct xfs_perag;
64struct xfs_iocore; 59struct xfs_iocore;
65struct xfs_bmbt_irec; 60struct xfs_bmbt_irec;
66struct xfs_bmap_free; 61struct xfs_bmap_free;
@@ -68,9 +63,6 @@ struct xfs_extdelta;
68struct xfs_swapext; 63struct xfs_swapext;
69struct xfs_mru_cache; 64struct xfs_mru_cache;
70 65
71extern struct bhv_vfsops xfs_vfsops;
72extern struct bhv_vnodeops xfs_vnodeops;
73
74#define AIL_LOCK_T lock_t 66#define AIL_LOCK_T lock_t
75#define AIL_LOCKINIT(x,y) spinlock_init(x,y) 67#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
76#define AIL_LOCK_DESTROY(x) spinlock_destroy(x) 68#define AIL_LOCK_DESTROY(x) spinlock_destroy(x)
@@ -82,15 +74,17 @@ extern struct bhv_vnodeops xfs_vnodeops;
82 * Prototypes and functions for the Data Migration subsystem. 74 * Prototypes and functions for the Data Migration subsystem.
83 */ 75 */
84 76
85typedef int (*xfs_send_data_t)(int, struct bhv_vnode *, 77typedef int (*xfs_send_data_t)(int, bhv_vnode_t *,
86 xfs_off_t, size_t, int, bhv_vrwlock_t *); 78 xfs_off_t, size_t, int, bhv_vrwlock_t *);
87typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); 79typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
88typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t); 80typedef int (*xfs_send_destroy_t)(bhv_vnode_t *, dm_right_t);
89typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *, 81typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct xfs_mount *,
90 struct bhv_vnode *, 82 bhv_vnode_t *,
91 dm_right_t, struct bhv_vnode *, dm_right_t, 83 dm_right_t, bhv_vnode_t *, dm_right_t,
92 char *, char *, mode_t, int, int); 84 char *, char *, mode_t, int, int);
93typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, struct bhv_vnode *, 85typedef int (*xfs_send_mount_t)(struct xfs_mount *, dm_right_t,
86 char *, char *);
87typedef void (*xfs_send_unmount_t)(struct xfs_mount *, bhv_vnode_t *,
94 dm_right_t, mode_t, int, int); 88 dm_right_t, mode_t, int, int);
95 89
96typedef struct xfs_dmops { 90typedef struct xfs_dmops {
@@ -98,21 +92,24 @@ typedef struct xfs_dmops {
98 xfs_send_mmap_t xfs_send_mmap; 92 xfs_send_mmap_t xfs_send_mmap;
99 xfs_send_destroy_t xfs_send_destroy; 93 xfs_send_destroy_t xfs_send_destroy;
100 xfs_send_namesp_t xfs_send_namesp; 94 xfs_send_namesp_t xfs_send_namesp;
95 xfs_send_mount_t xfs_send_mount;
101 xfs_send_unmount_t xfs_send_unmount; 96 xfs_send_unmount_t xfs_send_unmount;
102} xfs_dmops_t; 97} xfs_dmops_t;
103 98
104#define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \ 99#define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \
105 (*(mp)->m_dm_ops.xfs_send_data)(ev,vp,off,len,fl,lock) 100 (*(mp)->m_dm_ops->xfs_send_data)(ev,vp,off,len,fl,lock)
106#define XFS_SEND_MMAP(mp, vma,fl) \ 101#define XFS_SEND_MMAP(mp, vma,fl) \
107 (*(mp)->m_dm_ops.xfs_send_mmap)(vma,fl) 102 (*(mp)->m_dm_ops->xfs_send_mmap)(vma,fl)
108#define XFS_SEND_DESTROY(mp, vp,right) \ 103#define XFS_SEND_DESTROY(mp, vp,right) \
109 (*(mp)->m_dm_ops.xfs_send_destroy)(vp,right) 104 (*(mp)->m_dm_ops->xfs_send_destroy)(vp,right)
110#define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ 105#define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
111 (*(mp)->m_dm_ops.xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) 106 (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl)
112#define XFS_SEND_PREUNMOUNT(mp, vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ 107#define XFS_SEND_PREUNMOUNT(mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
113 (*(mp)->m_dm_ops.xfs_send_namesp)(DM_EVENT_PREUNMOUNT,vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) 108 (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT,mp,b1,r1,b2,r2,n1,n2,mode,rval,fl)
114#define XFS_SEND_UNMOUNT(mp, vfsp,vp,right,mode,rval,fl) \ 109#define XFS_SEND_MOUNT(mp,right,path,name) \
115 (*(mp)->m_dm_ops.xfs_send_unmount)(vfsp,vp,right,mode,rval,fl) 110 (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name)
111#define XFS_SEND_UNMOUNT(mp, vp,right,mode,rval,fl) \
112 (*(mp)->m_dm_ops->xfs_send_unmount)(mp,vp,right,mode,rval,fl)
116 113
117 114
118/* 115/*
@@ -142,6 +139,9 @@ typedef struct xfs_dquot * (*xfs_dqvopchown_t)(
142 struct xfs_dquot **, struct xfs_dquot *); 139 struct xfs_dquot **, struct xfs_dquot *);
143typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *, 140typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *,
144 struct xfs_dquot *, struct xfs_dquot *, uint); 141 struct xfs_dquot *, struct xfs_dquot *, uint);
142typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, bhv_statvfs_t *);
143typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags);
144typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t);
145 145
146typedef struct xfs_qmops { 146typedef struct xfs_qmops {
147 xfs_qminit_t xfs_qminit; 147 xfs_qminit_t xfs_qminit;
@@ -157,42 +157,51 @@ typedef struct xfs_qmops {
157 xfs_dqvoprename_t xfs_dqvoprename; 157 xfs_dqvoprename_t xfs_dqvoprename;
158 xfs_dqvopchown_t xfs_dqvopchown; 158 xfs_dqvopchown_t xfs_dqvopchown;
159 xfs_dqvopchownresv_t xfs_dqvopchownresv; 159 xfs_dqvopchownresv_t xfs_dqvopchownresv;
160 xfs_dqstatvfs_t xfs_dqstatvfs;
161 xfs_dqsync_t xfs_dqsync;
162 xfs_quotactl_t xfs_quotactl;
160 struct xfs_dqtrxops *xfs_dqtrxops; 163 struct xfs_dqtrxops *xfs_dqtrxops;
161} xfs_qmops_t; 164} xfs_qmops_t;
162 165
163#define XFS_QM_INIT(mp, mnt, fl) \ 166#define XFS_QM_INIT(mp, mnt, fl) \
164 (*(mp)->m_qm_ops.xfs_qminit)(mp, mnt, fl) 167 (*(mp)->m_qm_ops->xfs_qminit)(mp, mnt, fl)
165#define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \ 168#define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \
166 (*(mp)->m_qm_ops.xfs_qmmount)(mp, mnt, fl, mfsi_flags) 169 (*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl, mfsi_flags)
167#define XFS_QM_UNMOUNT(mp) \ 170#define XFS_QM_UNMOUNT(mp) \
168 (*(mp)->m_qm_ops.xfs_qmunmount)(mp) 171 (*(mp)->m_qm_ops->xfs_qmunmount)(mp)
169#define XFS_QM_DONE(mp) \ 172#define XFS_QM_DONE(mp) \
170 (*(mp)->m_qm_ops.xfs_qmdone)(mp) 173 (*(mp)->m_qm_ops->xfs_qmdone)(mp)
171#define XFS_QM_DQRELE(mp, dq) \ 174#define XFS_QM_DQRELE(mp, dq) \
172 (*(mp)->m_qm_ops.xfs_dqrele)(dq) 175 (*(mp)->m_qm_ops->xfs_dqrele)(dq)
173#define XFS_QM_DQATTACH(mp, ip, fl) \ 176#define XFS_QM_DQATTACH(mp, ip, fl) \
174 (*(mp)->m_qm_ops.xfs_dqattach)(ip, fl) 177 (*(mp)->m_qm_ops->xfs_dqattach)(ip, fl)
175#define XFS_QM_DQDETACH(mp, ip) \ 178#define XFS_QM_DQDETACH(mp, ip) \
176 (*(mp)->m_qm_ops.xfs_dqdetach)(ip) 179 (*(mp)->m_qm_ops->xfs_dqdetach)(ip)
177#define XFS_QM_DQPURGEALL(mp, fl) \ 180#define XFS_QM_DQPURGEALL(mp, fl) \
178 (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) 181 (*(mp)->m_qm_ops->xfs_dqpurgeall)(mp, fl)
179#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \ 182#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \
180 (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) 183 (*(mp)->m_qm_ops->xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
181#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ 184#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
182 (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) 185 (*(mp)->m_qm_ops->xfs_dqvopcreate)(tp, ip, dq1, dq2)
183#define XFS_QM_DQVOPRENAME(mp, ip) \ 186#define XFS_QM_DQVOPRENAME(mp, ip) \
184 (*(mp)->m_qm_ops.xfs_dqvoprename)(ip) 187 (*(mp)->m_qm_ops->xfs_dqvoprename)(ip)
185#define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \ 188#define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \
186 (*(mp)->m_qm_ops.xfs_dqvopchown)(tp, ip, dqp, dq) 189 (*(mp)->m_qm_ops->xfs_dqvopchown)(tp, ip, dqp, dq)
187#define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \ 190#define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \
188 (*(mp)->m_qm_ops.xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl) 191 (*(mp)->m_qm_ops->xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl)
192#define XFS_QM_DQSTATVFS(ip, statp) \
193 (*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp)
194#define XFS_QM_DQSYNC(mp, flags) \
195 (*(mp)->m_qm_ops->xfs_dqsync)(mp, flags)
196#define XFS_QM_QUOTACTL(mp, cmd, id, addr) \
197 (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr)
189 198
190 199
191/* 200/*
192 * Prototypes and functions for I/O core modularization. 201 * Prototypes and functions for I/O core modularization.
193 */ 202 */
194 203
195typedef int (*xfs_ioinit_t)(struct bhv_vfs *, 204typedef int (*xfs_ioinit_t)(struct xfs_mount *,
196 struct xfs_mount_args *, int); 205 struct xfs_mount_args *, int);
197typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, 206typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
198 xfs_fileoff_t, xfs_filblks_t, int, 207 xfs_fileoff_t, xfs_filblks_t, int,
@@ -222,7 +231,7 @@ typedef void (*xfs_lock_demote_t)(void *, uint);
222typedef int (*xfs_lock_nowait_t)(void *, uint); 231typedef int (*xfs_lock_nowait_t)(void *, uint);
223typedef void (*xfs_unlk_t)(void *, unsigned int); 232typedef void (*xfs_unlk_t)(void *, unsigned int);
224typedef xfs_fsize_t (*xfs_size_t)(void *); 233typedef xfs_fsize_t (*xfs_size_t)(void *);
225typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *); 234typedef xfs_fsize_t (*xfs_iodone_t)(struct xfs_mount *);
226typedef int (*xfs_swap_extents_t)(void *, void *, 235typedef int (*xfs_swap_extents_t)(void *, void *,
227 struct xfs_swapext*); 236 struct xfs_swapext*);
228 237
@@ -245,8 +254,8 @@ typedef struct xfs_ioops {
245 xfs_swap_extents_t xfs_swap_extents_func; 254 xfs_swap_extents_t xfs_swap_extents_func;
246} xfs_ioops_t; 255} xfs_ioops_t;
247 256
248#define XFS_IOINIT(vfsp, args, flags) \ 257#define XFS_IOINIT(mp, args, flags) \
249 (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) 258 (*(mp)->m_io_ops.xfs_ioinit)(mp, args, flags)
250#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \ 259#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \
251 (*(mp)->m_io_ops.xfs_bmapi_func) \ 260 (*(mp)->m_io_ops.xfs_bmapi_func) \
252 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta) 261 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta)
@@ -280,8 +289,8 @@ typedef struct xfs_ioops {
280 (*(mp)->m_io_ops.xfs_ilock_demote)((io)->io_obj, mode) 289 (*(mp)->m_io_ops.xfs_ilock_demote)((io)->io_obj, mode)
281#define XFS_SIZE(mp, io) \ 290#define XFS_SIZE(mp, io) \
282 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) 291 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
283#define XFS_IODONE(vfsp) \ 292#define XFS_IODONE(mp) \
284 (*(mp)->m_io_ops.xfs_iodone)(vfsp) 293 (*(mp)->m_io_ops.xfs_iodone)(mp)
285#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \ 294#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \
286 (*(mp)->m_io_ops.xfs_swap_extents_func) \ 295 (*(mp)->m_io_ops.xfs_swap_extents_func) \
287 ((io)->io_obj, (tio)->io_obj, sxp) 296 ((io)->io_obj, (tio)->io_obj, sxp)
@@ -318,7 +327,7 @@ extern void xfs_icsb_sync_counters_flags(struct xfs_mount *, int);
318#endif 327#endif
319 328
320typedef struct xfs_mount { 329typedef struct xfs_mount {
321 bhv_desc_t m_bhv; /* vfs xfs behavior */ 330 struct super_block *m_super;
322 xfs_tid_t m_tid; /* next unused tid for fs */ 331 xfs_tid_t m_tid; /* next unused tid for fs */
323 AIL_LOCK_T m_ail_lock; /* fs AIL mutex */ 332 AIL_LOCK_T m_ail_lock; /* fs AIL mutex */
324 xfs_ail_entry_t m_ail; /* fs active log item list */ 333 xfs_ail_entry_t m_ail; /* fs active log item list */
@@ -335,8 +344,6 @@ typedef struct xfs_mount {
335 xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ 344 xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */
336 lock_t m_agirotor_lock;/* .. and lock protecting it */ 345 lock_t m_agirotor_lock;/* .. and lock protecting it */
337 xfs_agnumber_t m_maxagi; /* highest inode alloc group */ 346 xfs_agnumber_t m_maxagi; /* highest inode alloc group */
338 size_t m_ihsize; /* size of next field */
339 struct xfs_ihash *m_ihash; /* fs private inode hash table*/
340 struct xfs_inode *m_inodes; /* active inode list */ 347 struct xfs_inode *m_inodes; /* active inode list */
341 struct list_head m_del_inodes; /* inodes to reclaim */ 348 struct list_head m_del_inodes; /* inodes to reclaim */
342 mutex_t m_ilock; /* inode list mutex */ 349 mutex_t m_ilock; /* inode list mutex */
@@ -362,7 +369,6 @@ typedef struct xfs_mount {
362 __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ 369 __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */
363 __uint8_t m_agno_log; /* log #ag's */ 370 __uint8_t m_agno_log; /* log #ag's */
364 __uint8_t m_agino_log; /* #bits for agino in inum */ 371 __uint8_t m_agino_log; /* #bits for agino in inum */
365 __uint8_t m_nreadaheads; /* #readahead buffers */
366 __uint16_t m_inode_cluster_size;/* min inode buf size */ 372 __uint16_t m_inode_cluster_size;/* min inode buf size */
367 uint m_blockmask; /* sb_blocksize-1 */ 373 uint m_blockmask; /* sb_blocksize-1 */
368 uint m_blockwsize; /* sb_blocksize in words */ 374 uint m_blockwsize; /* sb_blocksize in words */
@@ -378,7 +384,7 @@ typedef struct xfs_mount {
378 uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ 384 uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */
379 struct xfs_perag *m_perag; /* per-ag accounting info */ 385 struct xfs_perag *m_perag; /* per-ag accounting info */
380 struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ 386 struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */
381 sema_t m_growlock; /* growfs mutex */ 387 struct mutex m_growlock; /* growfs mutex */
382 int m_fixedfsid[2]; /* unchanged for life of FS */ 388 int m_fixedfsid[2]; /* unchanged for life of FS */
383 uint m_dmevmask; /* DMI events for this FS */ 389 uint m_dmevmask; /* DMI events for this FS */
384 __uint64_t m_flags; /* global mount flags */ 390 __uint64_t m_flags; /* global mount flags */
@@ -415,8 +421,8 @@ typedef struct xfs_mount {
415 uint m_chsize; /* size of next field */ 421 uint m_chsize; /* size of next field */
416 struct xfs_chash *m_chash; /* fs private inode per-cluster 422 struct xfs_chash *m_chash; /* fs private inode per-cluster
417 * hash table */ 423 * hash table */
418 struct xfs_dmops m_dm_ops; /* vector of DMI ops */ 424 struct xfs_dmops *m_dm_ops; /* vector of DMI ops */
419 struct xfs_qmops m_qm_ops; /* vector of XQM ops */ 425 struct xfs_qmops *m_qm_ops; /* vector of XQM ops */
420 struct xfs_ioops m_io_ops; /* vector of I/O ops */ 426 struct xfs_ioops m_io_ops; /* vector of I/O ops */
421 atomic_t m_active_trans; /* number trans frozen */ 427 atomic_t m_active_trans; /* number trans frozen */
422#ifdef HAVE_PERCPU_SB 428#ifdef HAVE_PERCPU_SB
@@ -426,6 +432,12 @@ typedef struct xfs_mount {
426 struct mutex m_icsb_mutex; /* balancer sync lock */ 432 struct mutex m_icsb_mutex; /* balancer sync lock */
427#endif 433#endif
428 struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ 434 struct xfs_mru_cache *m_filestream; /* per-mount filestream data */
435 struct task_struct *m_sync_task; /* generalised sync thread */
436 bhv_vfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */
437 struct list_head m_sync_list; /* sync thread work item list */
438 spinlock_t m_sync_lock; /* work item list lock */
439 int m_sync_seq; /* sync thread generation no. */
440 wait_queue_head_t m_wait_single_sync_task;
429} xfs_mount_t; 441} xfs_mount_t;
430 442
431/* 443/*
@@ -435,7 +447,7 @@ typedef struct xfs_mount {
435 must be synchronous except 447 must be synchronous except
436 for space allocations */ 448 for space allocations */
437#define XFS_MOUNT_INO64 (1ULL << 1) 449#define XFS_MOUNT_INO64 (1ULL << 1)
438 /* (1ULL << 2) -- currently unused */ 450#define XFS_MOUNT_DMAPI (1ULL << 2) /* dmapi is enabled */
439#define XFS_MOUNT_WAS_CLEAN (1ULL << 3) 451#define XFS_MOUNT_WAS_CLEAN (1ULL << 3)
440#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem 452#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem
441 operations, typically for 453 operations, typically for
@@ -445,7 +457,7 @@ typedef struct xfs_mount {
445#define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment 457#define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment
446 allocations */ 458 allocations */
447#define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ 459#define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */
448 /* (1ULL << 9) -- currently unused */ 460#define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */
449#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ 461#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */
450#define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */ 462#define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */
451#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ 463#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */
@@ -453,13 +465,13 @@ typedef struct xfs_mount {
453 /* osyncisdsync is now default*/ 465 /* osyncisdsync is now default*/
454#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above 466#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above
455 * 32 bits in size */ 467 * 32 bits in size */
456 /* (1ULL << 15) -- currently unused */ 468#define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */
457#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ 469#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */
458#define XFS_MOUNT_BARRIER (1ULL << 17) 470#define XFS_MOUNT_BARRIER (1ULL << 17)
459#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/ 471#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/
460#define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width 472#define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width
461 * allocation */ 473 * allocation */
462#define XFS_MOUNT_IHASHSIZE (1ULL << 20) /* inode hash table size */ 474#define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */
463#define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */ 475#define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */
464#define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred 476#define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred
465 * I/O size in stat() */ 477 * I/O size in stat() */
@@ -518,8 +530,10 @@ xfs_preferred_iosize(xfs_mount_t *mp)
518#define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ 530#define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \
519 ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) 531 ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN)
520#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) 532#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
533void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
534 int lnnum);
521#define xfs_force_shutdown(m,f) \ 535#define xfs_force_shutdown(m,f) \
522 bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__) 536 xfs_do_force_shutdown(m, f, __FILE__, __LINE__)
523 537
524/* 538/*
525 * Flags for xfs_mountfs 539 * Flags for xfs_mountfs
@@ -533,28 +547,6 @@ xfs_preferred_iosize(xfs_mount_t *mp)
533/* XFS_MFSI_CONVERT_SUNIT */ 547/* XFS_MFSI_CONVERT_SUNIT */
534#define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ 548#define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */
535 549
536/*
537 * Macros for getting from mount to vfs and back.
538 */
539#define XFS_MTOVFS(mp) xfs_mtovfs(mp)
540static inline struct bhv_vfs *xfs_mtovfs(xfs_mount_t *mp)
541{
542 return bhvtovfs(&mp->m_bhv);
543}
544
545#define XFS_BHVTOM(bdp) xfs_bhvtom(bdp)
546static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
547{
548 return (xfs_mount_t *)BHV_PDATA(bdp);
549}
550
551#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
552static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
553{
554 return XFS_BHVTOM(bhv_lookup_range(VFS_BHVHEAD(vfs),
555 VFS_POSITION_XFS, VFS_POSITION_XFS));
556}
557
558#define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) 550#define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d)
559static inline xfs_agnumber_t 551static inline xfs_agnumber_t
560xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d) 552xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d)
@@ -573,6 +565,21 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d)
573} 565}
574 566
575/* 567/*
568 * perag get/put wrappers for eventual ref counting
569 */
570static inline xfs_perag_t *
571xfs_get_perag(struct xfs_mount *mp, xfs_ino_t ino)
572{
573 return &mp->m_perag[XFS_INO_TO_AGNO(mp, ino)];
574}
575
576static inline void
577xfs_put_perag(struct xfs_mount *mp, xfs_perag_t *pag)
578{
579 /* nothing to see here, move along */
580}
581
582/*
576 * Per-cpu superblock locking functions 583 * Per-cpu superblock locking functions
577 */ 584 */
578#ifdef HAVE_PERCPU_SB 585#ifdef HAVE_PERCPU_SB
@@ -609,8 +616,8 @@ typedef struct xfs_mod_sb {
609extern xfs_mount_t *xfs_mount_init(void); 616extern xfs_mount_t *xfs_mount_init(void);
610extern void xfs_mod_sb(xfs_trans_t *, __int64_t); 617extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
611extern int xfs_log_sbcount(xfs_mount_t *, uint); 618extern int xfs_log_sbcount(xfs_mount_t *, uint);
612extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); 619extern void xfs_mount_free(xfs_mount_t *mp);
613extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int); 620extern int xfs_mountfs(xfs_mount_t *mp, int);
614extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); 621extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
615 622
616extern int xfs_unmountfs(xfs_mount_t *, struct cred *); 623extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
@@ -626,16 +633,19 @@ extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
626extern int xfs_readsb(xfs_mount_t *, int); 633extern int xfs_readsb(xfs_mount_t *, int);
627extern void xfs_freesb(xfs_mount_t *); 634extern void xfs_freesb(xfs_mount_t *);
628extern int xfs_fs_writable(xfs_mount_t *); 635extern int xfs_fs_writable(xfs_mount_t *);
629extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
630extern int xfs_syncsub(xfs_mount_t *, int, int *); 636extern int xfs_syncsub(xfs_mount_t *, int, int *);
631extern int xfs_sync_inodes(xfs_mount_t *, int, int *); 637extern int xfs_sync_inodes(xfs_mount_t *, int, int *);
632extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *, 638extern xfs_agnumber_t xfs_initialize_perag(xfs_mount_t *, xfs_agnumber_t);
633 xfs_agnumber_t); 639extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *);
634extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); 640extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t);
635extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); 641extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);
636 642
637extern struct xfs_dmops xfs_dmcore_stub; 643extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *);
638extern struct xfs_qmops xfs_qmcore_stub; 644extern void xfs_dmops_put(struct xfs_mount *);
645extern int xfs_qmops_get(struct xfs_mount *, struct xfs_mount_args *);
646extern void xfs_qmops_put(struct xfs_mount *);
647
648extern struct xfs_dmops xfs_dmcore_xfs;
639extern struct xfs_ioops xfs_iocore_xfs; 649extern struct xfs_ioops xfs_iocore_xfs;
640 650
641extern int xfs_init(void); 651extern int xfs_init(void);
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 0d594ed7efef..c266a0184b42 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -28,6 +28,8 @@
28#include "xfs_mount.h" 28#include "xfs_mount.h"
29#include "xfs_quota.h" 29#include "xfs_quota.h"
30#include "xfs_error.h" 30#include "xfs_error.h"
31#include "xfs_clnt.h"
32
31 33
32STATIC struct xfs_dquot * 34STATIC struct xfs_dquot *
33xfs_dqvopchown_default( 35xfs_dqvopchown_default(
@@ -64,7 +66,7 @@ xfs_mount_reset_sbqflags(xfs_mount_t *mp)
64 * if the fs is readonly, let the incore superblock run 66 * if the fs is readonly, let the incore superblock run
65 * with quotas off but don't flush the update out to disk 67 * with quotas off but don't flush the update out to disk
66 */ 68 */
67 if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) 69 if (mp->m_flags & XFS_MOUNT_RDONLY)
68 return 0; 70 return 0;
69#ifdef QUOTADEBUG 71#ifdef QUOTADEBUG
70 xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes"); 72 xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes");
@@ -110,7 +112,7 @@ xfs_noquota_init(
110 return error; 112 return error;
111} 113}
112 114
113xfs_qmops_t xfs_qmcore_stub = { 115static struct xfs_qmops xfs_qmcore_stub = {
114 .xfs_qminit = (xfs_qminit_t) xfs_noquota_init, 116 .xfs_qminit = (xfs_qminit_t) xfs_noquota_init,
115 .xfs_qmdone = (xfs_qmdone_t) fs_noerr, 117 .xfs_qmdone = (xfs_qmdone_t) fs_noerr,
116 .xfs_qmmount = (xfs_qmmount_t) fs_noerr, 118 .xfs_qmmount = (xfs_qmmount_t) fs_noerr,
@@ -124,4 +126,38 @@ xfs_qmops_t xfs_qmcore_stub = {
124 .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr, 126 .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr,
125 .xfs_dqvopchown = xfs_dqvopchown_default, 127 .xfs_dqvopchown = xfs_dqvopchown_default,
126 .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, 128 .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr,
129 .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval,
130 .xfs_dqsync = (xfs_dqsync_t) fs_noerr,
131 .xfs_quotactl = (xfs_quotactl_t) fs_nosys,
127}; 132};
133
134int
135xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
136{
137 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)) {
138 struct xfs_qmops *ops;
139
140 ops = symbol_get(xfs_qmcore_xfs);
141 if (!ops) {
142 request_module("xfs_quota");
143 ops = symbol_get(xfs_qmcore_xfs);
144 }
145
146 if (!ops) {
147 cmn_err(CE_WARN, "XFS: no quota support available.");
148 return EINVAL;
149 }
150 mp->m_qm_ops = ops;
151 } else {
152 mp->m_qm_ops = &xfs_qmcore_stub;
153 }
154
155 return 0;
156}
157
158void
159xfs_qmops_put(struct xfs_mount *mp)
160{
161 if (mp->m_qm_ops != &xfs_qmcore_stub)
162 symbol_put(xfs_qmcore_xfs);
163}
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 6f14df976f73..12c4ec775af8 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -330,12 +330,12 @@ typedef struct xfs_dqtrxops {
330} xfs_dqtrxops_t; 330} xfs_dqtrxops_t;
331 331
332#define XFS_DQTRXOP(mp, tp, op, args...) \ 332#define XFS_DQTRXOP(mp, tp, op, args...) \
333 ((mp)->m_qm_ops.xfs_dqtrxops ? \ 333 ((mp)->m_qm_ops->xfs_dqtrxops ? \
334 ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0) 334 ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : 0)
335 335
336#define XFS_DQTRXOP_VOID(mp, tp, op, args...) \ 336#define XFS_DQTRXOP_VOID(mp, tp, op, args...) \
337 ((mp)->m_qm_ops.xfs_dqtrxops ? \ 337 ((mp)->m_qm_ops->xfs_dqtrxops ? \
338 ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : (void)0) 338 ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : (void)0)
339 339
340#define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \ 340#define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \
341 XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp) 341 XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp)
@@ -364,7 +364,7 @@ typedef struct xfs_dqtrxops {
364extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); 364extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
365extern int xfs_mount_reset_sbqflags(struct xfs_mount *); 365extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
366 366
367extern struct bhv_module_vfsops xfs_qmops; 367extern struct xfs_qmops xfs_qmcore_xfs;
368 368
369#endif /* __KERNEL__ */ 369#endif /* __KERNEL__ */
370 370
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 7679d7a7022d..44ea0ba36476 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -22,6 +22,7 @@
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_ag.h"
25#include "xfs_dir2.h" 26#include "xfs_dir2.h"
26#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
27#include "xfs_mount.h" 28#include "xfs_mount.h"
@@ -128,8 +129,7 @@ xfs_lock_for_rename(
128 lock_mode = xfs_ilock_map_shared(dp2); 129 lock_mode = xfs_ilock_map_shared(dp2);
129 } 130 }
130 131
131 error = xfs_dir_lookup_int(XFS_ITOBHV(dp2), lock_mode, 132 error = xfs_dir_lookup_int(dp2, lock_mode, vname2, &inum2, &ip2);
132 vname2, &inum2, &ip2);
133 if (error == ENOENT) { /* target does not need to exist. */ 133 if (error == ENOENT) { /* target does not need to exist. */
134 inum2 = 0; 134 inum2 = 0;
135 } else if (error) { 135 } else if (error) {
@@ -221,15 +221,15 @@ xfs_lock_for_rename(
221 */ 221 */
222int 222int
223xfs_rename( 223xfs_rename(
224 bhv_desc_t *src_dir_bdp, 224 xfs_inode_t *src_dp,
225 bhv_vname_t *src_vname, 225 bhv_vname_t *src_vname,
226 bhv_vnode_t *target_dir_vp, 226 bhv_vnode_t *target_dir_vp,
227 bhv_vname_t *target_vname, 227 bhv_vname_t *target_vname)
228 cred_t *credp)
229{ 228{
229 bhv_vnode_t *src_dir_vp = XFS_ITOV(src_dp);
230 xfs_trans_t *tp; 230 xfs_trans_t *tp;
231 xfs_inode_t *src_dp, *target_dp, *src_ip, *target_ip; 231 xfs_inode_t *target_dp, *src_ip, *target_ip;
232 xfs_mount_t *mp; 232 xfs_mount_t *mp = src_dp->i_mount;
233 int new_parent; /* moving to a new dir */ 233 int new_parent; /* moving to a new dir */
234 int src_is_directory; /* src_name is a directory */ 234 int src_is_directory; /* src_name is a directory */
235 int error; 235 int error;
@@ -239,7 +239,6 @@ xfs_rename(
239 int committed; 239 int committed;
240 xfs_inode_t *inodes[4]; 240 xfs_inode_t *inodes[4];
241 int target_ip_dropped = 0; /* dropped target_ip link? */ 241 int target_ip_dropped = 0; /* dropped target_ip link? */
242 bhv_vnode_t *src_dir_vp;
243 int spaceres; 242 int spaceres;
244 int target_link_zero = 0; 243 int target_link_zero = 0;
245 int num_inodes; 244 int num_inodes;
@@ -248,9 +247,8 @@ xfs_rename(
248 int src_namelen = VNAMELEN(src_vname); 247 int src_namelen = VNAMELEN(src_vname);
249 int target_namelen = VNAMELEN(target_vname); 248 int target_namelen = VNAMELEN(target_vname);
250 249
251 src_dir_vp = BHV_TO_VNODE(src_dir_bdp); 250 vn_trace_entry(src_dp, "xfs_rename", (inst_t *)__return_address);
252 vn_trace_entry(src_dir_vp, "xfs_rename", (inst_t *)__return_address); 251 vn_trace_entry(xfs_vtoi(target_dir_vp), "xfs_rename", (inst_t *)__return_address);
253 vn_trace_entry(target_dir_vp, "xfs_rename", (inst_t *)__return_address);
254 252
255 /* 253 /*
256 * Find the XFS behavior descriptor for the target directory 254 * Find the XFS behavior descriptor for the target directory
@@ -261,12 +259,8 @@ xfs_rename(
261 return XFS_ERROR(EXDEV); 259 return XFS_ERROR(EXDEV);
262 } 260 }
263 261
264 src_dp = XFS_BHVTOI(src_dir_bdp); 262 if (DM_EVENT_ENABLED(src_dp, DM_EVENT_RENAME) ||
265 mp = src_dp->i_mount; 263 DM_EVENT_ENABLED(target_dp, DM_EVENT_RENAME)) {
266
267 if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) ||
268 DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
269 target_dp, DM_EVENT_RENAME)) {
270 error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME, 264 error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME,
271 src_dir_vp, DM_RIGHT_NULL, 265 src_dir_vp, DM_RIGHT_NULL,
272 target_dir_vp, DM_RIGHT_NULL, 266 target_dir_vp, DM_RIGHT_NULL,
@@ -592,20 +586,16 @@ xfs_rename(
592 /* 586 /*
593 * Let interposed file systems know about removed links. 587 * Let interposed file systems know about removed links.
594 */ 588 */
595 if (target_ip_dropped) { 589 if (target_ip_dropped)
596 bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp,
597 target_link_zero);
598 IRELE(target_ip); 590 IRELE(target_ip);
599 }
600 591
601 IRELE(src_ip); 592 IRELE(src_ip);
602 593
603 /* Fall through to std_return with error = 0 or errno from 594 /* Fall through to std_return with error = 0 or errno from
604 * xfs_trans_commit */ 595 * xfs_trans_commit */
605std_return: 596std_return:
606 if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_POSTRENAME) || 597 if (DM_EVENT_ENABLED(src_dp, DM_EVENT_POSTRENAME) ||
607 DM_EVENT_ENABLED(target_dir_vp->v_vfsp, 598 DM_EVENT_ENABLED(target_dp, DM_EVENT_POSTRENAME)) {
608 target_dp, DM_EVENT_POSTRENAME)) {
609 (void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME, 599 (void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME,
610 src_dir_vp, DM_RIGHT_NULL, 600 src_dir_vp, DM_RIGHT_NULL,
611 target_dir_vp, DM_RIGHT_NULL, 601 target_dir_vp, DM_RIGHT_NULL,
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index 905d1c008be7..cd3ece6cc918 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -178,18 +178,15 @@ xfs_write_sync_logforce(
178 * the shop, make sure that absolutely nothing persistent happens to 178 * the shop, make sure that absolutely nothing persistent happens to
179 * this filesystem after this point. 179 * this filesystem after this point.
180 */ 180 */
181
182void 181void
183xfs_do_force_shutdown( 182xfs_do_force_shutdown(
184 bhv_desc_t *bdp, 183 xfs_mount_t *mp,
185 int flags, 184 int flags,
186 char *fname, 185 char *fname,
187 int lnnum) 186 int lnnum)
188{ 187{
189 int logerror; 188 int logerror;
190 xfs_mount_t *mp;
191 189
192 mp = XFS_BHVTOM(bdp);
193 logerror = flags & SHUTDOWN_LOG_IO_ERROR; 190 logerror = flags & SHUTDOWN_LOG_IO_ERROR;
194 191
195 if (!(flags & SHUTDOWN_FORCE_UMOUNT)) { 192 if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h
index fcf28dbded7c..49875e1d129f 100644
--- a/fs/xfs/xfs_rw.h
+++ b/fs/xfs/xfs_rw.h
@@ -23,32 +23,6 @@ struct xfs_inode;
23struct xfs_mount; 23struct xfs_mount;
24 24
25/* 25/*
26 * Maximum count of bmaps used by read and write paths.
27 */
28#define XFS_MAX_RW_NBMAPS 4
29
30/*
31 * Counts of readahead buffers to use based on physical memory size.
32 * None of these should be more than XFS_MAX_RW_NBMAPS.
33 */
34#define XFS_RW_NREADAHEAD_16MB 2
35#define XFS_RW_NREADAHEAD_32MB 3
36#define XFS_RW_NREADAHEAD_K32 4
37#define XFS_RW_NREADAHEAD_K64 4
38
39/*
40 * Maximum size of a buffer that we\'ll map. Making this
41 * too big will degrade performance due to the number of
42 * pages which need to be gathered. Making it too small
43 * will prevent us from doing large I/O\'s to hardware that
44 * needs it.
45 *
46 * This is currently set to 512 KB.
47 */
48#define XFS_MAX_BMAP_LEN_BB 1024
49#define XFS_MAX_BMAP_LEN_BYTES 524288
50
51/*
52 * Convert the given file system block to a disk block. 26 * Convert the given file system block to a disk block.
53 * We have to treat it differently based on whether the 27 * We have to treat it differently based on whether the
54 * file is a real time file or not, because the bmap code 28 * file is a real time file or not, because the bmap code
@@ -116,14 +90,6 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
116/* 90/*
117 * Prototypes for functions in xfs_vnodeops.c. 91 * Prototypes for functions in xfs_vnodeops.c.
118 */ 92 */
119extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
120extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
121extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags,
122 cred_t *credp);
123extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf,
124 xfs_off_t offset, cred_t *credp, int flags);
125extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,
126 cred_t *credp);
127extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip, 93extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip,
128 int flags); 94 int flags);
129 95
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index ef42537a607a..94660b1a6ccc 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -87,8 +87,10 @@ struct xfs_mount;
87 (XFS_SB_VERSION2_OKREALFBITS | \ 87 (XFS_SB_VERSION2_OKREALFBITS | \
88 XFS_SB_VERSION2_OKSASHFBITS ) 88 XFS_SB_VERSION2_OKSASHFBITS )
89 89
90typedef struct xfs_sb 90/*
91{ 91 * Superblock - in core version. Must match the ondisk version below.
92 */
93typedef struct xfs_sb {
92 __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ 94 __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */
93 __uint32_t sb_blocksize; /* logical block size, bytes */ 95 __uint32_t sb_blocksize; /* logical block size, bytes */
94 xfs_drfsbno_t sb_dblocks; /* number of data blocks */ 96 xfs_drfsbno_t sb_dblocks; /* number of data blocks */
@@ -146,6 +148,66 @@ typedef struct xfs_sb
146} xfs_sb_t; 148} xfs_sb_t;
147 149
148/* 150/*
151 * Superblock - on disk version. Must match the in core version below.
152 */
153typedef struct xfs_dsb {
154 __be32 sb_magicnum; /* magic number == XFS_SB_MAGIC */
155 __be32 sb_blocksize; /* logical block size, bytes */
156 __be64 sb_dblocks; /* number of data blocks */
157 __be64 sb_rblocks; /* number of realtime blocks */
158 __be64 sb_rextents; /* number of realtime extents */
159 uuid_t sb_uuid; /* file system unique id */
160 __be64 sb_logstart; /* starting block of log if internal */
161 __be64 sb_rootino; /* root inode number */
162 __be64 sb_rbmino; /* bitmap inode for realtime extents */
163 __be64 sb_rsumino; /* summary inode for rt bitmap */
164 __be32 sb_rextsize; /* realtime extent size, blocks */
165 __be32 sb_agblocks; /* size of an allocation group */
166 __be32 sb_agcount; /* number of allocation groups */
167 __be32 sb_rbmblocks; /* number of rt bitmap blocks */
168 __be32 sb_logblocks; /* number of log blocks */
169 __be16 sb_versionnum; /* header version == XFS_SB_VERSION */
170 __be16 sb_sectsize; /* volume sector size, bytes */
171 __be16 sb_inodesize; /* inode size, bytes */
172 __be16 sb_inopblock; /* inodes per block */
173 char sb_fname[12]; /* file system name */
174 __u8 sb_blocklog; /* log2 of sb_blocksize */
175 __u8 sb_sectlog; /* log2 of sb_sectsize */
176 __u8 sb_inodelog; /* log2 of sb_inodesize */
177 __u8 sb_inopblog; /* log2 of sb_inopblock */
178 __u8 sb_agblklog; /* log2 of sb_agblocks (rounded up) */
179 __u8 sb_rextslog; /* log2 of sb_rextents */
180 __u8 sb_inprogress; /* mkfs is in progress, don't mount */
181 __u8 sb_imax_pct; /* max % of fs for inode space */
182 /* statistics */
183 /*
184 * These fields must remain contiguous. If you really
185 * want to change their layout, make sure you fix the
186 * code in xfs_trans_apply_sb_deltas().
187 */
188 __be64 sb_icount; /* allocated inodes */
189 __be64 sb_ifree; /* free inodes */
190 __be64 sb_fdblocks; /* free data blocks */
191 __be64 sb_frextents; /* free realtime extents */
192 /*
193 * End contiguous fields.
194 */
195 __be64 sb_uquotino; /* user quota inode */
196 __be64 sb_gquotino; /* group quota inode */
197 __be16 sb_qflags; /* quota flags */
198 __u8 sb_flags; /* misc. flags */
199 __u8 sb_shared_vn; /* shared version number */
200 __be32 sb_inoalignmt; /* inode chunk alignment, fsblocks */
201 __be32 sb_unit; /* stripe or raid unit */
202 __be32 sb_width; /* stripe or raid width */
203 __u8 sb_dirblklog; /* log2 of dir block size (fsbs) */
204 __u8 sb_logsectlog; /* log2 of the log sector size */
205 __be16 sb_logsectsize; /* sector size for the log, bytes */
206 __be32 sb_logsunit; /* stripe unit size for the log */
207 __be32 sb_features2; /* additional feature bits */
208} xfs_dsb_t;
209
210/*
149 * Sequence number values for the fields. 211 * Sequence number values for the fields.
150 */ 212 */
151typedef enum { 213typedef enum {
@@ -446,7 +508,7 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp)
446 508
447#define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ 509#define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */
448#define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) 510#define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR)
449#define XFS_BUF_TO_SBP(bp) ((xfs_sb_t *)XFS_BUF_PTR(bp)) 511#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)XFS_BUF_PTR(bp))
450 512
451#define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) 513#define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d))
452#define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ 514#define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 356d6627f581..8878322ee793 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -234,7 +234,7 @@ xfs_trans_alloc(
234 xfs_mount_t *mp, 234 xfs_mount_t *mp,
235 uint type) 235 uint type)
236{ 236{
237 vfs_wait_for_freeze(XFS_MTOVFS(mp), SB_FREEZE_TRANS); 237 xfs_wait_for_freeze(mp, SB_FREEZE_TRANS);
238 return _xfs_trans_alloc(mp, type); 238 return _xfs_trans_alloc(mp, type);
239} 239}
240 240
@@ -548,7 +548,7 @@ STATIC void
548xfs_trans_apply_sb_deltas( 548xfs_trans_apply_sb_deltas(
549 xfs_trans_t *tp) 549 xfs_trans_t *tp)
550{ 550{
551 xfs_sb_t *sbp; 551 xfs_dsb_t *sbp;
552 xfs_buf_t *bp; 552 xfs_buf_t *bp;
553 int whole = 0; 553 int whole = 0;
554 554
@@ -566,57 +566,51 @@ xfs_trans_apply_sb_deltas(
566 * Only update the superblock counters if we are logging them 566 * Only update the superblock counters if we are logging them
567 */ 567 */
568 if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { 568 if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) {
569 if (tp->t_icount_delta != 0) { 569 if (tp->t_icount_delta)
570 INT_MOD(sbp->sb_icount, ARCH_CONVERT, tp->t_icount_delta); 570 be64_add(&sbp->sb_icount, tp->t_icount_delta);
571 } 571 if (tp->t_ifree_delta)
572 if (tp->t_ifree_delta != 0) { 572 be64_add(&sbp->sb_ifree, tp->t_ifree_delta);
573 INT_MOD(sbp->sb_ifree, ARCH_CONVERT, tp->t_ifree_delta); 573 if (tp->t_fdblocks_delta)
574 } 574 be64_add(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
575 575 if (tp->t_res_fdblocks_delta)
576 if (tp->t_fdblocks_delta != 0) { 576 be64_add(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
577 INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_fdblocks_delta);
578 }
579 if (tp->t_res_fdblocks_delta != 0) {
580 INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_res_fdblocks_delta);
581 }
582 } 577 }
583 578
584 if (tp->t_frextents_delta != 0) { 579 if (tp->t_frextents_delta)
585 INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_frextents_delta); 580 be64_add(&sbp->sb_frextents, tp->t_frextents_delta);
586 } 581 if (tp->t_res_frextents_delta)
587 if (tp->t_res_frextents_delta != 0) { 582 be64_add(&sbp->sb_frextents, tp->t_res_frextents_delta);
588 INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_res_frextents_delta); 583
589 } 584 if (tp->t_dblocks_delta) {
590 if (tp->t_dblocks_delta != 0) { 585 be64_add(&sbp->sb_dblocks, tp->t_dblocks_delta);
591 INT_MOD(sbp->sb_dblocks, ARCH_CONVERT, tp->t_dblocks_delta);
592 whole = 1; 586 whole = 1;
593 } 587 }
594 if (tp->t_agcount_delta != 0) { 588 if (tp->t_agcount_delta) {
595 INT_MOD(sbp->sb_agcount, ARCH_CONVERT, tp->t_agcount_delta); 589 be32_add(&sbp->sb_agcount, tp->t_agcount_delta);
596 whole = 1; 590 whole = 1;
597 } 591 }
598 if (tp->t_imaxpct_delta != 0) { 592 if (tp->t_imaxpct_delta) {
599 INT_MOD(sbp->sb_imax_pct, ARCH_CONVERT, tp->t_imaxpct_delta); 593 sbp->sb_imax_pct += tp->t_imaxpct_delta;
600 whole = 1; 594 whole = 1;
601 } 595 }
602 if (tp->t_rextsize_delta != 0) { 596 if (tp->t_rextsize_delta) {
603 INT_MOD(sbp->sb_rextsize, ARCH_CONVERT, tp->t_rextsize_delta); 597 be32_add(&sbp->sb_rextsize, tp->t_rextsize_delta);
604 whole = 1; 598 whole = 1;
605 } 599 }
606 if (tp->t_rbmblocks_delta != 0) { 600 if (tp->t_rbmblocks_delta) {
607 INT_MOD(sbp->sb_rbmblocks, ARCH_CONVERT, tp->t_rbmblocks_delta); 601 be32_add(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
608 whole = 1; 602 whole = 1;
609 } 603 }
610 if (tp->t_rblocks_delta != 0) { 604 if (tp->t_rblocks_delta) {
611 INT_MOD(sbp->sb_rblocks, ARCH_CONVERT, tp->t_rblocks_delta); 605 be64_add(&sbp->sb_rblocks, tp->t_rblocks_delta);
612 whole = 1; 606 whole = 1;
613 } 607 }
614 if (tp->t_rextents_delta != 0) { 608 if (tp->t_rextents_delta) {
615 INT_MOD(sbp->sb_rextents, ARCH_CONVERT, tp->t_rextents_delta); 609 be64_add(&sbp->sb_rextents, tp->t_rextents_delta);
616 whole = 1; 610 whole = 1;
617 } 611 }
618 if (tp->t_rextslog_delta != 0) { 612 if (tp->t_rextslog_delta) {
619 INT_MOD(sbp->sb_rextslog, ARCH_CONVERT, tp->t_rextslog_delta); 613 sbp->sb_rextslog += tp->t_rextslog_delta;
620 whole = 1; 614 whole = 1;
621 } 615 }
622 616
@@ -624,17 +618,17 @@ xfs_trans_apply_sb_deltas(
624 /* 618 /*
625 * Log the whole thing, the fields are noncontiguous. 619 * Log the whole thing, the fields are noncontiguous.
626 */ 620 */
627 xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_sb_t) - 1); 621 xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_dsb_t) - 1);
628 else 622 else
629 /* 623 /*
630 * Since all the modifiable fields are contiguous, we 624 * Since all the modifiable fields are contiguous, we
631 * can get away with this. 625 * can get away with this.
632 */ 626 */
633 xfs_trans_log_buf(tp, bp, offsetof(xfs_sb_t, sb_icount), 627 xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount),
634 offsetof(xfs_sb_t, sb_frextents) + 628 offsetof(xfs_dsb_t, sb_frextents) +
635 sizeof(sbp->sb_frextents) - 1); 629 sizeof(sbp->sb_frextents) - 1);
636 630
637 XFS_MTOVFS(tp->t_mountp)->vfs_super->s_dirt = 1; 631 tp->t_mountp->m_super->s_dirt = 1;
638} 632}
639 633
640/* 634/*
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index ceb4f6e99960..5b2ff59f19cf 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -22,6 +22,7 @@
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_ag.h"
25#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
26#include "xfs_mount.h" 27#include "xfs_mount.h"
27#include "xfs_trans_priv.h" 28#include "xfs_trans_priv.h"
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c
index b290270dd4a6..27cce2a9c7e9 100644
--- a/fs/xfs/xfs_trans_extfree.c
+++ b/fs/xfs/xfs_trans_extfree.c
@@ -22,6 +22,7 @@
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_ag.h"
25#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
26#include "xfs_mount.h" 27#include "xfs_mount.h"
27#include "xfs_trans_priv.h" 28#include "xfs_trans_priv.h"
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index 104f64a98790..5c89be475464 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -151,18 +151,6 @@ typedef __uint8_t xfs_arch_t; /* architecture of an xfs fs */
151 */ 151 */
152#define MAXNAMELEN 256 152#define MAXNAMELEN 256
153 153
154typedef struct xfs_dirent { /* data from readdir() */
155 xfs_ino_t d_ino; /* inode number of entry */
156 xfs_off_t d_off; /* offset of disk directory entry */
157 unsigned short d_reclen; /* length of this record */
158 char d_name[1]; /* name of file */
159} xfs_dirent_t;
160
161#define DIRENTBASESIZE (((xfs_dirent_t *)0)->d_name - (char *)0)
162#define DIRENTSIZE(namelen) \
163 ((DIRENTBASESIZE + (namelen) + \
164 sizeof(xfs_off_t)) & ~(sizeof(xfs_off_t) - 1))
165
166typedef enum { 154typedef enum {
167 XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi 155 XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi
168} xfs_lookup_t; 156} xfs_lookup_t;
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 20ffec308e1e..673b405eaa31 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -65,20 +65,15 @@ xfs_get_dir_entry(
65 65
66int 66int
67xfs_dir_lookup_int( 67xfs_dir_lookup_int(
68 bhv_desc_t *dir_bdp, 68 xfs_inode_t *dp,
69 uint lock_mode, 69 uint lock_mode,
70 bhv_vname_t *dentry, 70 bhv_vname_t *dentry,
71 xfs_ino_t *inum, 71 xfs_ino_t *inum,
72 xfs_inode_t **ipp) 72 xfs_inode_t **ipp)
73{ 73{
74 bhv_vnode_t *dir_vp;
75 xfs_inode_t *dp;
76 int error; 74 int error;
77 75
78 dir_vp = BHV_TO_VNODE(dir_bdp); 76 vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
79 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
80
81 dp = XFS_BHVTOI(dir_bdp);
82 77
83 error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum); 78 error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum);
84 if (!error) { 79 if (!error) {
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index fe953e98afa7..a00b26d8840e 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -20,13 +20,11 @@
20 20
21#define IRELE(ip) VN_RELE(XFS_ITOV(ip)) 21#define IRELE(ip) VN_RELE(XFS_ITOV(ip))
22#define IHOLD(ip) VN_HOLD(XFS_ITOV(ip)) 22#define IHOLD(ip) VN_HOLD(XFS_ITOV(ip))
23#define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \ 23#define ITRACE(ip) vn_trace_ref(ip, __FILE__, __LINE__, \
24 (inst_t *)__return_address) 24 (inst_t *)__return_address)
25 25
26extern int xfs_rename (bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
27 bhv_vname_t *, cred_t *);
28extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **); 26extern 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 *, 27extern int xfs_dir_lookup_int (xfs_inode_t *, uint, bhv_vname_t *, xfs_ino_t *,
30 xfs_inode_t **); 28 xfs_inode_t **);
31extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); 29extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
32extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, 30extern 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 11f5ea29a038..a5a8454f2a63 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -54,8 +54,9 @@
54#include "xfs_mru_cache.h" 54#include "xfs_mru_cache.h"
55#include "xfs_filestream.h" 55#include "xfs_filestream.h"
56#include "xfs_fsops.h" 56#include "xfs_fsops.h"
57#include "xfs_vnodeops.h"
58#include "xfs_vfsops.h"
57 59
58STATIC int xfs_sync(bhv_desc_t *, int, cred_t *);
59 60
60int 61int
61xfs_init(void) 62xfs_init(void)
@@ -117,8 +118,8 @@ xfs_init(void)
117 xfs_ili_zone = 118 xfs_ili_zone =
118 kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", 119 kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili",
119 KM_ZONE_SPREAD, NULL); 120 KM_ZONE_SPREAD, NULL);
120 xfs_chashlist_zone = 121 xfs_icluster_zone =
121 kmem_zone_init_flags(sizeof(xfs_chashlist_t), "xfs_chashlist", 122 kmem_zone_init_flags(sizeof(xfs_icluster_t), "xfs_icluster",
122 KM_ZONE_SPREAD, NULL); 123 KM_ZONE_SPREAD, NULL);
123 124
124 /* 125 /*
@@ -163,7 +164,7 @@ xfs_cleanup(void)
163 extern kmem_zone_t *xfs_efd_zone; 164 extern kmem_zone_t *xfs_efd_zone;
164 extern kmem_zone_t *xfs_efi_zone; 165 extern kmem_zone_t *xfs_efi_zone;
165 extern kmem_zone_t *xfs_buf_item_zone; 166 extern kmem_zone_t *xfs_buf_item_zone;
166 extern kmem_zone_t *xfs_chashlist_zone; 167 extern kmem_zone_t *xfs_icluster_zone;
167 168
168 xfs_cleanup_procfs(); 169 xfs_cleanup_procfs();
169 xfs_sysctl_unregister(); 170 xfs_sysctl_unregister();
@@ -199,7 +200,7 @@ xfs_cleanup(void)
199 kmem_zone_destroy(xfs_efi_zone); 200 kmem_zone_destroy(xfs_efi_zone);
200 kmem_zone_destroy(xfs_ifork_zone); 201 kmem_zone_destroy(xfs_ifork_zone);
201 kmem_zone_destroy(xfs_ili_zone); 202 kmem_zone_destroy(xfs_ili_zone);
202 kmem_zone_destroy(xfs_chashlist_zone); 203 kmem_zone_destroy(xfs_icluster_zone);
203} 204}
204 205
205/* 206/*
@@ -210,7 +211,6 @@ xfs_cleanup(void)
210 */ 211 */
211STATIC int 212STATIC int
212xfs_start_flags( 213xfs_start_flags(
213 struct bhv_vfs *vfs,
214 struct xfs_mount_args *ap, 214 struct xfs_mount_args *ap,
215 struct xfs_mount *mp) 215 struct xfs_mount *mp)
216{ 216{
@@ -238,17 +238,14 @@ xfs_start_flags(
238 mp->m_logbufs = ap->logbufs; 238 mp->m_logbufs = ap->logbufs;
239 if (ap->logbufsize != -1 && 239 if (ap->logbufsize != -1 &&
240 ap->logbufsize != 0 && 240 ap->logbufsize != 0 &&
241 ap->logbufsize != 16 * 1024 && 241 (ap->logbufsize < XLOG_MIN_RECORD_BSIZE ||
242 ap->logbufsize != 32 * 1024 && 242 ap->logbufsize > XLOG_MAX_RECORD_BSIZE ||
243 ap->logbufsize != 64 * 1024 && 243 !is_power_of_2(ap->logbufsize))) {
244 ap->logbufsize != 128 * 1024 &&
245 ap->logbufsize != 256 * 1024) {
246 cmn_err(CE_WARN, 244 cmn_err(CE_WARN,
247 "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", 245 "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
248 ap->logbufsize); 246 ap->logbufsize);
249 return XFS_ERROR(EINVAL); 247 return XFS_ERROR(EINVAL);
250 } 248 }
251 mp->m_ihsize = ap->ihashsize;
252 mp->m_logbsize = ap->logbufsize; 249 mp->m_logbsize = ap->logbufsize;
253 mp->m_fsname_len = strlen(ap->fsname) + 1; 250 mp->m_fsname_len = strlen(ap->fsname) + 1;
254 mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP); 251 mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
@@ -295,8 +292,6 @@ xfs_start_flags(
295 mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; 292 mp->m_readio_log = mp->m_writeio_log = ap->iosizelog;
296 } 293 }
297 294
298 if (ap->flags & XFSMNT_IHASHSIZE)
299 mp->m_flags |= XFS_MOUNT_IHASHSIZE;
300 if (ap->flags & XFSMNT_IDELETE) 295 if (ap->flags & XFSMNT_IDELETE)
301 mp->m_flags |= XFS_MOUNT_IDELETE; 296 mp->m_flags |= XFS_MOUNT_IDELETE;
302 if (ap->flags & XFSMNT_DIRSYNC) 297 if (ap->flags & XFSMNT_DIRSYNC)
@@ -311,7 +306,7 @@ xfs_start_flags(
311 * no recovery flag requires a read-only mount 306 * no recovery flag requires a read-only mount
312 */ 307 */
313 if (ap->flags & XFSMNT_NORECOVERY) { 308 if (ap->flags & XFSMNT_NORECOVERY) {
314 if (!(vfs->vfs_flag & VFS_RDONLY)) { 309 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
315 cmn_err(CE_WARN, 310 cmn_err(CE_WARN,
316 "XFS: tried to mount a FS read-write without recovery!"); 311 "XFS: tried to mount a FS read-write without recovery!");
317 return XFS_ERROR(EINVAL); 312 return XFS_ERROR(EINVAL);
@@ -329,6 +324,8 @@ xfs_start_flags(
329 if (ap->flags2 & XFSMNT2_FILESTREAMS) 324 if (ap->flags2 & XFSMNT2_FILESTREAMS)
330 mp->m_flags |= XFS_MOUNT_FILESTREAMS; 325 mp->m_flags |= XFS_MOUNT_FILESTREAMS;
331 326
327 if (ap->flags & XFSMNT_DMAPI)
328 mp->m_flags |= XFS_MOUNT_DMAPI;
332 return 0; 329 return 0;
333} 330}
334 331
@@ -338,11 +335,10 @@ xfs_start_flags(
338 */ 335 */
339STATIC int 336STATIC int
340xfs_finish_flags( 337xfs_finish_flags(
341 struct bhv_vfs *vfs,
342 struct xfs_mount_args *ap, 338 struct xfs_mount_args *ap,
343 struct xfs_mount *mp) 339 struct xfs_mount *mp)
344{ 340{
345 int ronly = (vfs->vfs_flag & VFS_RDONLY); 341 int ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
346 342
347 /* Fail a mount where the logbuf is smaller then the log stripe */ 343 /* Fail a mount where the logbuf is smaller then the log stripe */
348 if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) { 344 if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
@@ -403,6 +399,22 @@ xfs_finish_flags(
403 return XFS_ERROR(EINVAL); 399 return XFS_ERROR(EINVAL);
404 } 400 }
405 401
402 if (ap->flags & XFSMNT_UQUOTA) {
403 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
404 if (ap->flags & XFSMNT_UQUOTAENF)
405 mp->m_qflags |= XFS_UQUOTA_ENFD;
406 }
407
408 if (ap->flags & XFSMNT_GQUOTA) {
409 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
410 if (ap->flags & XFSMNT_GQUOTAENF)
411 mp->m_qflags |= XFS_OQUOTA_ENFD;
412 } else if (ap->flags & XFSMNT_PQUOTA) {
413 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
414 if (ap->flags & XFSMNT_PQUOTAENF)
415 mp->m_qflags |= XFS_OQUOTA_ENFD;
416 }
417
406 return 0; 418 return 0;
407} 419}
408 420
@@ -418,30 +430,26 @@ xfs_finish_flags(
418 * they are present. The data subvolume has already been opened by 430 * they are present. The data subvolume has already been opened by
419 * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev. 431 * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev.
420 */ 432 */
421STATIC int 433int
422xfs_mount( 434xfs_mount(
423 struct bhv_desc *bhvp, 435 struct xfs_mount *mp,
424 struct xfs_mount_args *args, 436 struct xfs_mount_args *args,
425 cred_t *credp) 437 cred_t *credp)
426{ 438{
427 struct bhv_vfs *vfsp = bhvtovfs(bhvp);
428 struct bhv_desc *p;
429 struct xfs_mount *mp = XFS_BHVTOM(bhvp);
430 struct block_device *ddev, *logdev, *rtdev; 439 struct block_device *ddev, *logdev, *rtdev;
431 int flags = 0, error; 440 int flags = 0, error;
432 441
433 ddev = vfsp->vfs_super->s_bdev; 442 ddev = mp->m_super->s_bdev;
434 logdev = rtdev = NULL; 443 logdev = rtdev = NULL;
435 444
436 /* 445 error = xfs_dmops_get(mp, args);
437 * Setup xfs_mount function vectors from available behaviors 446 if (error)
438 */ 447 return error;
439 p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM); 448 error = xfs_qmops_get(mp, args);
440 mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub; 449 if (error)
441 p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM); 450 return error;
442 mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub; 451
443 p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); 452 mp->m_io_ops = xfs_iocore_xfs;
444 mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
445 453
446 if (args->flags & XFSMNT_QUIET) 454 if (args->flags & XFSMNT_QUIET)
447 flags |= XFS_MFSI_QUIET; 455 flags |= XFS_MFSI_QUIET;
@@ -482,24 +490,30 @@ xfs_mount(
482 } 490 }
483 if (rtdev) { 491 if (rtdev) {
484 mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1); 492 mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1);
485 if (!mp->m_rtdev_targp) 493 if (!mp->m_rtdev_targp) {
494 xfs_blkdev_put(logdev);
495 xfs_blkdev_put(rtdev);
486 goto error0; 496 goto error0;
497 }
487 } 498 }
488 mp->m_logdev_targp = (logdev && logdev != ddev) ? 499 mp->m_logdev_targp = (logdev && logdev != ddev) ?
489 xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp; 500 xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp;
490 if (!mp->m_logdev_targp) 501 if (!mp->m_logdev_targp) {
502 xfs_blkdev_put(logdev);
503 xfs_blkdev_put(rtdev);
491 goto error0; 504 goto error0;
505 }
492 506
493 /* 507 /*
494 * Setup flags based on mount(2) options and then the superblock 508 * Setup flags based on mount(2) options and then the superblock
495 */ 509 */
496 error = xfs_start_flags(vfsp, args, mp); 510 error = xfs_start_flags(args, mp);
497 if (error) 511 if (error)
498 goto error1; 512 goto error1;
499 error = xfs_readsb(mp, flags); 513 error = xfs_readsb(mp, flags);
500 if (error) 514 if (error)
501 goto error1; 515 goto error1;
502 error = xfs_finish_flags(vfsp, args, mp); 516 error = xfs_finish_flags(args, mp);
503 if (error) 517 if (error)
504 goto error2; 518 goto error2;
505 519
@@ -530,10 +544,12 @@ xfs_mount(
530 if ((error = xfs_filestream_mount(mp))) 544 if ((error = xfs_filestream_mount(mp)))
531 goto error2; 545 goto error2;
532 546
533 error = XFS_IOINIT(vfsp, args, flags); 547 error = XFS_IOINIT(mp, args, flags);
534 if (error) 548 if (error)
535 goto error2; 549 goto error2;
536 550
551 XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname);
552
537 return 0; 553 return 0;
538 554
539error2: 555error2:
@@ -547,17 +563,17 @@ error1:
547 xfs_binval(mp->m_rtdev_targp); 563 xfs_binval(mp->m_rtdev_targp);
548error0: 564error0:
549 xfs_unmountfs_close(mp, credp); 565 xfs_unmountfs_close(mp, credp);
566 xfs_qmops_put(mp);
567 xfs_dmops_put(mp);
550 return error; 568 return error;
551} 569}
552 570
553STATIC int 571int
554xfs_unmount( 572xfs_unmount(
555 bhv_desc_t *bdp, 573 xfs_mount_t *mp,
556 int flags, 574 int flags,
557 cred_t *credp) 575 cred_t *credp)
558{ 576{
559 bhv_vfs_t *vfsp = bhvtovfs(bdp);
560 xfs_mount_t *mp = XFS_BHVTOM(bdp);
561 xfs_inode_t *rip; 577 xfs_inode_t *rip;
562 bhv_vnode_t *rvp; 578 bhv_vnode_t *rvp;
563 int unmount_event_wanted = 0; 579 int unmount_event_wanted = 0;
@@ -568,8 +584,9 @@ xfs_unmount(
568 rip = mp->m_rootip; 584 rip = mp->m_rootip;
569 rvp = XFS_ITOV(rip); 585 rvp = XFS_ITOV(rip);
570 586
571 if (vfsp->vfs_flag & VFS_DMI) { 587#ifdef HAVE_DMAPI
572 error = XFS_SEND_PREUNMOUNT(mp, vfsp, 588 if (mp->m_flags & XFS_MOUNT_DMAPI) {
589 error = XFS_SEND_PREUNMOUNT(mp,
573 rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL, 590 rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL,
574 NULL, NULL, 0, 0, 591 NULL, NULL, 0, 0,
575 (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))? 592 (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))?
@@ -580,7 +597,7 @@ xfs_unmount(
580 unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))? 597 unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))?
581 0 : DM_FLAGS_UNWANTED; 598 0 : DM_FLAGS_UNWANTED;
582 } 599 }
583 600#endif
584 /* 601 /*
585 * First blow any referenced inode from this file system 602 * First blow any referenced inode from this file system
586 * out of the reference cache, and delete the timer. 603 * out of the reference cache, and delete the timer.
@@ -612,8 +629,7 @@ xfs_unmount(
612 * referenced vnodes as well. 629 * referenced vnodes as well.
613 */ 630 */
614 if (XFS_FORCED_SHUTDOWN(mp)) { 631 if (XFS_FORCED_SHUTDOWN(mp)) {
615 error = xfs_sync(&mp->m_bhv, 632 error = xfs_sync(mp, SYNC_WAIT | SYNC_CLOSE);
616 (SYNC_WAIT | SYNC_CLOSE), credp);
617 ASSERT(error != EFSCORRUPTED); 633 ASSERT(error != EFSCORRUPTED);
618 } 634 }
619 xfs_unmountfs_needed = 1; 635 xfs_unmountfs_needed = 1;
@@ -627,7 +643,7 @@ out:
627 /* Note: mp structure must still exist for 643 /* Note: mp structure must still exist for
628 * XFS_SEND_UNMOUNT() call. 644 * XFS_SEND_UNMOUNT() call.
629 */ 645 */
630 XFS_SEND_UNMOUNT(mp, vfsp, error == 0 ? rvp : NULL, 646 XFS_SEND_UNMOUNT(mp, error == 0 ? rvp : NULL,
631 DM_RIGHT_NULL, 0, error, unmount_event_flags); 647 DM_RIGHT_NULL, 0, error, unmount_event_flags);
632 } 648 }
633 if (xfs_unmountfs_needed) { 649 if (xfs_unmountfs_needed) {
@@ -636,6 +652,9 @@ out:
636 * and free the super block buffer & mount structures. 652 * and free the super block buffer & mount structures.
637 */ 653 */
638 xfs_unmountfs(mp, credp); 654 xfs_unmountfs(mp, credp);
655 xfs_qmops_put(mp);
656 xfs_dmops_put(mp);
657 kmem_free(mp, sizeof(xfs_mount_t));
639 } 658 }
640 659
641 return XFS_ERROR(error); 660 return XFS_ERROR(error);
@@ -694,29 +713,26 @@ xfs_attr_quiesce(
694 xfs_unmountfs_writesb(mp); 713 xfs_unmountfs_writesb(mp);
695} 714}
696 715
697STATIC int 716int
698xfs_mntupdate( 717xfs_mntupdate(
699 bhv_desc_t *bdp, 718 struct xfs_mount *mp,
700 int *flags, 719 int *flags,
701 struct xfs_mount_args *args) 720 struct xfs_mount_args *args)
702{ 721{
703 bhv_vfs_t *vfsp = bhvtovfs(bdp);
704 xfs_mount_t *mp = XFS_BHVTOM(bdp);
705
706 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ 722 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */
707 if (vfsp->vfs_flag & VFS_RDONLY) 723 if (mp->m_flags & XFS_MOUNT_RDONLY)
708 vfsp->vfs_flag &= ~VFS_RDONLY; 724 mp->m_flags &= ~XFS_MOUNT_RDONLY;
709 if (args->flags & XFSMNT_BARRIER) { 725 if (args->flags & XFSMNT_BARRIER) {
710 mp->m_flags |= XFS_MOUNT_BARRIER; 726 mp->m_flags |= XFS_MOUNT_BARRIER;
711 xfs_mountfs_check_barriers(mp); 727 xfs_mountfs_check_barriers(mp);
712 } else { 728 } else {
713 mp->m_flags &= ~XFS_MOUNT_BARRIER; 729 mp->m_flags &= ~XFS_MOUNT_BARRIER;
714 } 730 }
715 } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ 731 } else if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { /* rw -> ro */
716 xfs_filestream_flush(mp); 732 xfs_filestream_flush(mp);
717 bhv_vfs_sync(vfsp, SYNC_DATA_QUIESCE, NULL); 733 xfs_sync(mp, SYNC_DATA_QUIESCE);
718 xfs_attr_quiesce(mp); 734 xfs_attr_quiesce(mp);
719 vfsp->vfs_flag |= VFS_RDONLY; 735 mp->m_flags |= XFS_MOUNT_RDONLY;
720 } 736 }
721 return 0; 737 return 0;
722} 738}
@@ -811,14 +827,14 @@ fscorrupt_out2:
811 * vpp -- address of the caller's vnode pointer which should be 827 * vpp -- address of the caller's vnode pointer which should be
812 * set to the desired fs root vnode 828 * set to the desired fs root vnode
813 */ 829 */
814STATIC int 830int
815xfs_root( 831xfs_root(
816 bhv_desc_t *bdp, 832 xfs_mount_t *mp,
817 bhv_vnode_t **vpp) 833 bhv_vnode_t **vpp)
818{ 834{
819 bhv_vnode_t *vp; 835 bhv_vnode_t *vp;
820 836
821 vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); 837 vp = XFS_ITOV(mp->m_rootip);
822 VN_HOLD(vp); 838 VN_HOLD(vp);
823 *vpp = vp; 839 *vpp = vp;
824 return 0; 840 return 0;
@@ -831,19 +847,17 @@ xfs_root(
831 * the superblock lock in the mount structure to ensure a consistent 847 * the superblock lock in the mount structure to ensure a consistent
832 * snapshot of the counters returned. 848 * snapshot of the counters returned.
833 */ 849 */
834STATIC int 850int
835xfs_statvfs( 851xfs_statvfs(
836 bhv_desc_t *bdp, 852 xfs_mount_t *mp,
837 bhv_statvfs_t *statp, 853 bhv_statvfs_t *statp,
838 bhv_vnode_t *vp) 854 bhv_vnode_t *vp)
839{ 855{
840 __uint64_t fakeinos; 856 __uint64_t fakeinos;
841 xfs_extlen_t lsize; 857 xfs_extlen_t lsize;
842 xfs_mount_t *mp;
843 xfs_sb_t *sbp; 858 xfs_sb_t *sbp;
844 unsigned long s; 859 unsigned long s;
845 860
846 mp = XFS_BHVTOM(bdp);
847 sbp = &(mp->m_sb); 861 sbp = &(mp->m_sb);
848 862
849 statp->f_type = XFS_SB_MAGIC; 863 statp->f_type = XFS_SB_MAGIC;
@@ -874,6 +888,8 @@ xfs_statvfs(
874 xfs_statvfs_fsid(statp, mp); 888 xfs_statvfs_fsid(statp, mp);
875 statp->f_namelen = MAXNAMELEN - 1; 889 statp->f_namelen = MAXNAMELEN - 1;
876 890
891 if (vp)
892 XFS_QM_DQSTATVFS(xfs_vtoi(vp), statp);
877 return 0; 893 return 0;
878} 894}
879 895
@@ -920,14 +936,30 @@ xfs_statvfs(
920 * filesystem. 936 * filesystem.
921 * 937 *
922 */ 938 */
923/*ARGSUSED*/ 939int
924STATIC int
925xfs_sync( 940xfs_sync(
926 bhv_desc_t *bdp, 941 xfs_mount_t *mp,
927 int flags, 942 int flags)
928 cred_t *credp)
929{ 943{
930 xfs_mount_t *mp = XFS_BHVTOM(bdp); 944 int error;
945
946 /*
947 * Get the Quota Manager to flush the dquots.
948 *
949 * If XFS quota support is not enabled or this filesystem
950 * instance does not use quotas XFS_QM_DQSYNC will always
951 * return zero.
952 */
953 error = XFS_QM_DQSYNC(mp, flags);
954 if (error) {
955 /*
956 * If we got an IO error, we will be shutting down.
957 * So, there's nothing more for us to do here.
958 */
959 ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp));
960 if (XFS_FORCED_SHUTDOWN(mp))
961 return XFS_ERROR(error);
962 }
931 963
932 if (flags & SYNC_IOWAIT) 964 if (flags & SYNC_IOWAIT)
933 xfs_filestream_flush(mp); 965 xfs_filestream_flush(mp);
@@ -1015,7 +1047,7 @@ xfs_sync_inodes(
1015 1047
1016 if (bypassed) 1048 if (bypassed)
1017 *bypassed = 0; 1049 *bypassed = 0;
1018 if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) 1050 if (mp->m_flags & XFS_MOUNT_RDONLY)
1019 return 0; 1051 return 0;
1020 error = 0; 1052 error = 0;
1021 last_error = 0; 1053 last_error = 0;
@@ -1189,12 +1221,13 @@ xfs_sync_inodes(
1189 if (flags & SYNC_CLOSE) { 1221 if (flags & SYNC_CLOSE) {
1190 /* Shutdown case. Flush and invalidate. */ 1222 /* Shutdown case. Flush and invalidate. */
1191 if (XFS_FORCED_SHUTDOWN(mp)) 1223 if (XFS_FORCED_SHUTDOWN(mp))
1192 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); 1224 xfs_tosspages(ip, 0, -1,
1225 FI_REMAPF);
1193 else 1226 else
1194 error = bhv_vop_flushinval_pages(vp, 0, 1227 error = xfs_flushinval_pages(ip,
1195 -1, FI_REMAPF); 1228 0, -1, FI_REMAPF);
1196 } else if ((flags & SYNC_DELWRI) && VN_DIRTY(vp)) { 1229 } else if ((flags & SYNC_DELWRI) && VN_DIRTY(vp)) {
1197 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, 1230 error = xfs_flush_pages(ip, 0,
1198 -1, fflag, FI_NONE); 1231 -1, fflag, FI_NONE);
1199 } 1232 }
1200 1233
@@ -1204,7 +1237,7 @@ xfs_sync_inodes(
1204 * place after this point 1237 * place after this point
1205 */ 1238 */
1206 if (flags & SYNC_IOWAIT) 1239 if (flags & SYNC_IOWAIT)
1207 vn_iowait(vp); 1240 vn_iowait(ip);
1208 1241
1209 xfs_ilock(ip, XFS_ILOCK_SHARED); 1242 xfs_ilock(ip, XFS_ILOCK_SHARED);
1210 } 1243 }
@@ -1598,13 +1631,12 @@ xfs_syncsub(
1598/* 1631/*
1599 * xfs_vget - called by DMAPI and NFSD to get vnode from file handle 1632 * xfs_vget - called by DMAPI and NFSD to get vnode from file handle
1600 */ 1633 */
1601STATIC int 1634int
1602xfs_vget( 1635xfs_vget(
1603 bhv_desc_t *bdp, 1636 xfs_mount_t *mp,
1604 bhv_vnode_t **vpp, 1637 bhv_vnode_t **vpp,
1605 fid_t *fidp) 1638 fid_t *fidp)
1606{ 1639{
1607 xfs_mount_t *mp = XFS_BHVTOM(bdp);
1608 xfs_fid_t *xfid = (struct xfs_fid *)fidp; 1640 xfs_fid_t *xfid = (struct xfs_fid *)fidp;
1609 xfs_inode_t *ip; 1641 xfs_inode_t *ip;
1610 int error; 1642 int error;
@@ -1668,7 +1700,6 @@ xfs_vget(
1668#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ 1700#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */
1669#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ 1701#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */
1670#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ 1702#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
1671#define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */
1672#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ 1703#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
1673#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and 1704#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
1674 * unwritten extent conversion */ 1705 * unwritten extent conversion */
@@ -1683,6 +1714,21 @@ xfs_vget(
1683#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ 1714#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
1684#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ 1715#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
1685#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ 1716#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */
1717#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
1718#define MNTOPT_NOQUOTA "noquota" /* no quotas */
1719#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
1720#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
1721#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
1722#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
1723#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
1724#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
1725#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
1726#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
1727#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
1728#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
1729#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
1730#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
1731#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
1686 1732
1687STATIC unsigned long 1733STATIC unsigned long
1688suffix_strtoul(char *s, char **endp, unsigned int base) 1734suffix_strtoul(char *s, char **endp, unsigned int base)
@@ -1707,19 +1753,18 @@ suffix_strtoul(char *s, char **endp, unsigned int base)
1707 return simple_strtoul((const char *)s, endp, base) << shift_left_factor; 1753 return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
1708} 1754}
1709 1755
1710STATIC int 1756int
1711xfs_parseargs( 1757xfs_parseargs(
1712 struct bhv_desc *bhv, 1758 struct xfs_mount *mp,
1713 char *options, 1759 char *options,
1714 struct xfs_mount_args *args, 1760 struct xfs_mount_args *args,
1715 int update) 1761 int update)
1716{ 1762{
1717 bhv_vfs_t *vfsp = bhvtovfs(bhv);
1718 char *this_char, *value, *eov; 1763 char *this_char, *value, *eov;
1719 int dsunit, dswidth, vol_dsunit, vol_dswidth; 1764 int dsunit, dswidth, vol_dsunit, vol_dswidth;
1720 int iosize; 1765 int iosize;
1766 int ikeep = 0;
1721 1767
1722 args->flags |= XFSMNT_IDELETE;
1723 args->flags |= XFSMNT_BARRIER; 1768 args->flags |= XFSMNT_BARRIER;
1724 args->flags2 |= XFSMNT2_COMPAT_IOSIZE; 1769 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1725 1770
@@ -1794,21 +1839,12 @@ xfs_parseargs(
1794 iosize = suffix_strtoul(value, &eov, 10); 1839 iosize = suffix_strtoul(value, &eov, 10);
1795 args->flags |= XFSMNT_IOSIZE; 1840 args->flags |= XFSMNT_IOSIZE;
1796 args->iosizelog = ffs(iosize) - 1; 1841 args->iosizelog = ffs(iosize) - 1;
1797 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
1798 if (!value || !*value) {
1799 cmn_err(CE_WARN,
1800 "XFS: %s option requires an argument",
1801 this_char);
1802 return EINVAL;
1803 }
1804 args->flags |= XFSMNT_IHASHSIZE;
1805 args->ihashsize = simple_strtoul(value, &eov, 10);
1806 } else if (!strcmp(this_char, MNTOPT_GRPID) || 1842 } else if (!strcmp(this_char, MNTOPT_GRPID) ||
1807 !strcmp(this_char, MNTOPT_BSDGROUPS)) { 1843 !strcmp(this_char, MNTOPT_BSDGROUPS)) {
1808 vfsp->vfs_flag |= VFS_GRPID; 1844 mp->m_flags |= XFS_MOUNT_GRPID;
1809 } else if (!strcmp(this_char, MNTOPT_NOGRPID) || 1845 } else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
1810 !strcmp(this_char, MNTOPT_SYSVGROUPS)) { 1846 !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
1811 vfsp->vfs_flag &= ~VFS_GRPID; 1847 mp->m_flags &= ~XFS_MOUNT_GRPID;
1812 } else if (!strcmp(this_char, MNTOPT_WSYNC)) { 1848 } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
1813 args->flags |= XFSMNT_WSYNC; 1849 args->flags |= XFSMNT_WSYNC;
1814 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { 1850 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
@@ -1858,6 +1894,7 @@ xfs_parseargs(
1858 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { 1894 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
1859 args->flags &= ~XFSMNT_BARRIER; 1895 args->flags &= ~XFSMNT_BARRIER;
1860 } else if (!strcmp(this_char, MNTOPT_IKEEP)) { 1896 } else if (!strcmp(this_char, MNTOPT_IKEEP)) {
1897 ikeep = 1;
1861 args->flags &= ~XFSMNT_IDELETE; 1898 args->flags &= ~XFSMNT_IDELETE;
1862 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { 1899 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
1863 args->flags |= XFSMNT_IDELETE; 1900 args->flags |= XFSMNT_IDELETE;
@@ -1871,6 +1908,38 @@ xfs_parseargs(
1871 args->flags &= ~XFSMNT_ATTR2; 1908 args->flags &= ~XFSMNT_ATTR2;
1872 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { 1909 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
1873 args->flags2 |= XFSMNT2_FILESTREAMS; 1910 args->flags2 |= XFSMNT2_FILESTREAMS;
1911 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
1912 args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
1913 args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
1914 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
1915 !strcmp(this_char, MNTOPT_UQUOTA) ||
1916 !strcmp(this_char, MNTOPT_USRQUOTA)) {
1917 args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
1918 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
1919 !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
1920 args->flags |= XFSMNT_UQUOTA;
1921 args->flags &= ~XFSMNT_UQUOTAENF;
1922 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
1923 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
1924 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
1925 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
1926 args->flags |= XFSMNT_PQUOTA;
1927 args->flags &= ~XFSMNT_PQUOTAENF;
1928 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
1929 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
1930 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
1931 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
1932 args->flags |= XFSMNT_GQUOTA;
1933 args->flags &= ~XFSMNT_GQUOTAENF;
1934 } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
1935 args->flags |= XFSMNT_DMAPI;
1936 } else if (!strcmp(this_char, MNTOPT_XDSM)) {
1937 args->flags |= XFSMNT_DMAPI;
1938 } else if (!strcmp(this_char, MNTOPT_DMI)) {
1939 args->flags |= XFSMNT_DMAPI;
1940 } else if (!strcmp(this_char, "ihashsize")) {
1941 cmn_err(CE_WARN,
1942 "XFS: ihashsize no longer used, option is deprecated.");
1874 } else if (!strcmp(this_char, "osyncisdsync")) { 1943 } else if (!strcmp(this_char, "osyncisdsync")) {
1875 /* no-op, this is now the default */ 1944 /* no-op, this is now the default */
1876 cmn_err(CE_WARN, 1945 cmn_err(CE_WARN,
@@ -1886,7 +1955,7 @@ xfs_parseargs(
1886 } 1955 }
1887 1956
1888 if (args->flags & XFSMNT_NORECOVERY) { 1957 if (args->flags & XFSMNT_NORECOVERY) {
1889 if ((vfsp->vfs_flag & VFS_RDONLY) == 0) { 1958 if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) {
1890 cmn_err(CE_WARN, 1959 cmn_err(CE_WARN,
1891 "XFS: no-recovery mounts must be read-only."); 1960 "XFS: no-recovery mounts must be read-only.");
1892 return EINVAL; 1961 return EINVAL;
@@ -1899,6 +1968,18 @@ xfs_parseargs(
1899 return EINVAL; 1968 return EINVAL;
1900 } 1969 }
1901 1970
1971 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
1972 cmn_err(CE_WARN,
1973 "XFS: cannot mount with both project and group quota");
1974 return EINVAL;
1975 }
1976
1977 if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') {
1978 printk("XFS: %s option needs the mount point option as well\n",
1979 MNTOPT_DMAPI);
1980 return EINVAL;
1981 }
1982
1902 if ((dsunit && !dswidth) || (!dsunit && dswidth)) { 1983 if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
1903 cmn_err(CE_WARN, 1984 cmn_err(CE_WARN,
1904 "XFS: sunit and swidth must be specified together"); 1985 "XFS: sunit and swidth must be specified together");
@@ -1912,6 +1993,18 @@ xfs_parseargs(
1912 return EINVAL; 1993 return EINVAL;
1913 } 1994 }
1914 1995
1996 /*
1997 * Applications using DMI filesystems often expect the
1998 * inode generation number to be monotonically increasing.
1999 * If we delete inode chunks we break this assumption, so
2000 * keep unused inode chunks on disk for DMI filesystems
2001 * until we come up with a better solution.
2002 * Note that if "ikeep" or "noikeep" mount options are
2003 * supplied, then they are honored.
2004 */
2005 if (!(args->flags & XFSMNT_DMAPI) && !ikeep)
2006 args->flags |= XFSMNT_IDELETE;
2007
1915 if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { 2008 if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
1916 if (dsunit) { 2009 if (dsunit) {
1917 args->sunit = dsunit; 2010 args->sunit = dsunit;
@@ -1927,15 +2020,15 @@ xfs_parseargs(
1927 2020
1928done: 2021done:
1929 if (args->flags & XFSMNT_32BITINODES) 2022 if (args->flags & XFSMNT_32BITINODES)
1930 vfsp->vfs_flag |= VFS_32BITINODES; 2023 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
1931 if (args->flags2) 2024 if (args->flags2)
1932 args->flags |= XFSMNT_FLAGS2; 2025 args->flags |= XFSMNT_FLAGS2;
1933 return 0; 2026 return 0;
1934} 2027}
1935 2028
1936STATIC int 2029int
1937xfs_showargs( 2030xfs_showargs(
1938 struct bhv_desc *bhv, 2031 struct xfs_mount *mp,
1939 struct seq_file *m) 2032 struct seq_file *m)
1940{ 2033{
1941 static struct proc_xfs_info { 2034 static struct proc_xfs_info {
@@ -1953,17 +2046,12 @@ xfs_showargs(
1953 { 0, NULL } 2046 { 0, NULL }
1954 }; 2047 };
1955 struct proc_xfs_info *xfs_infop; 2048 struct proc_xfs_info *xfs_infop;
1956 struct xfs_mount *mp = XFS_BHVTOM(bhv);
1957 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1958 2049
1959 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { 2050 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
1960 if (mp->m_flags & xfs_infop->flag) 2051 if (mp->m_flags & xfs_infop->flag)
1961 seq_puts(m, xfs_infop->str); 2052 seq_puts(m, xfs_infop->str);
1962 } 2053 }
1963 2054
1964 if (mp->m_flags & XFS_MOUNT_IHASHSIZE)
1965 seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", (int)mp->m_ihsize);
1966
1967 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) 2055 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
1968 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", 2056 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
1969 (int)(1 << mp->m_writeio_log) >> 10); 2057 (int)(1 << mp->m_writeio_log) >> 10);
@@ -1990,11 +2078,37 @@ xfs_showargs(
1990 if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)) 2078 if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
1991 seq_printf(m, "," MNTOPT_LARGEIO); 2079 seq_printf(m, "," MNTOPT_LARGEIO);
1992 2080
1993 if (!(vfsp->vfs_flag & VFS_32BITINODES)) 2081 if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS))
1994 seq_printf(m, "," MNTOPT_64BITINODE); 2082 seq_printf(m, "," MNTOPT_64BITINODE);
1995 if (vfsp->vfs_flag & VFS_GRPID) 2083 if (mp->m_flags & XFS_MOUNT_GRPID)
1996 seq_printf(m, "," MNTOPT_GRPID); 2084 seq_printf(m, "," MNTOPT_GRPID);
1997 2085
2086 if (mp->m_qflags & XFS_UQUOTA_ACCT) {
2087 if (mp->m_qflags & XFS_UQUOTA_ENFD)
2088 seq_puts(m, "," MNTOPT_USRQUOTA);
2089 else
2090 seq_puts(m, "," MNTOPT_UQUOTANOENF);
2091 }
2092
2093 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
2094 if (mp->m_qflags & XFS_OQUOTA_ENFD)
2095 seq_puts(m, "," MNTOPT_PRJQUOTA);
2096 else
2097 seq_puts(m, "," MNTOPT_PQUOTANOENF);
2098 }
2099
2100 if (mp->m_qflags & XFS_GQUOTA_ACCT) {
2101 if (mp->m_qflags & XFS_OQUOTA_ENFD)
2102 seq_puts(m, "," MNTOPT_GRPQUOTA);
2103 else
2104 seq_puts(m, "," MNTOPT_GQUOTANOENF);
2105 }
2106
2107 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
2108 seq_puts(m, "," MNTOPT_NOQUOTA);
2109
2110 if (mp->m_flags & XFS_MOUNT_DMAPI)
2111 seq_puts(m, "," MNTOPT_DMAPI);
1998 return 0; 2112 return 0;
1999} 2113}
2000 2114
@@ -2003,31 +2117,10 @@ xfs_showargs(
2003 * need to take care of themetadata. Once that's done write a dummy 2117 * need to take care of themetadata. Once that's done write a dummy
2004 * record to dirty the log in case of a crash while frozen. 2118 * record to dirty the log in case of a crash while frozen.
2005 */ 2119 */
2006STATIC void 2120void
2007xfs_freeze( 2121xfs_freeze(
2008 bhv_desc_t *bdp) 2122 xfs_mount_t *mp)
2009{ 2123{
2010 xfs_mount_t *mp = XFS_BHVTOM(bdp);
2011
2012 xfs_attr_quiesce(mp); 2124 xfs_attr_quiesce(mp);
2013 xfs_fs_log_dummy(mp); 2125 xfs_fs_log_dummy(mp);
2014} 2126}
2015
2016
2017bhv_vfsops_t xfs_vfsops = {
2018 BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
2019 .vfs_parseargs = xfs_parseargs,
2020 .vfs_showargs = xfs_showargs,
2021 .vfs_mount = xfs_mount,
2022 .vfs_unmount = xfs_unmount,
2023 .vfs_mntupdate = xfs_mntupdate,
2024 .vfs_root = xfs_root,
2025 .vfs_statvfs = xfs_statvfs,
2026 .vfs_sync = xfs_sync,
2027 .vfs_vget = xfs_vget,
2028 .vfs_dmapiops = (vfs_dmapiops_t)fs_nosys,
2029 .vfs_quotactl = (vfs_quotactl_t)fs_nosys,
2030 .vfs_init_vnode = xfs_initialize_vnode,
2031 .vfs_force_shutdown = xfs_do_force_shutdown,
2032 .vfs_freeze = xfs_freeze,
2033};
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h
new file mode 100644
index 000000000000..bc99e3eb7dbb
--- /dev/null
+++ b/fs/xfs/xfs_vfsops.h
@@ -0,0 +1,28 @@
1#ifndef _XFS_VFSOPS_H
2#define _XFS_VFSOPS_H 1
3
4struct cred;
5struct fid;
6struct inode;
7struct kstatfs;
8struct xfs_mount;
9struct xfs_mount_args;
10
11int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args,
12 struct cred *credp);
13int xfs_unmount(struct xfs_mount *mp, int flags, struct cred *credp);
14int xfs_mntupdate(struct xfs_mount *mp, int *flags,
15 struct xfs_mount_args *args);
16int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp);
17int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp,
18 bhv_vnode_t *vp);
19int xfs_sync(struct xfs_mount *mp, int flags);
20int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct fid *fidp);
21int xfs_parseargs(struct xfs_mount *mp, char *options,
22 struct xfs_mount_args *args, int update);
23int xfs_showargs(struct xfs_mount *mp, struct seq_file *m);
24void xfs_freeze(struct xfs_mount *mp);
25void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
26 int lnnum);
27
28#endif /* _XFS_VFSOPS_H */
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 603459229904..5e3c57ca9981 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -52,15 +52,13 @@
52#include "xfs_trans_space.h" 52#include "xfs_trans_space.h"
53#include "xfs_log_priv.h" 53#include "xfs_log_priv.h"
54#include "xfs_filestream.h" 54#include "xfs_filestream.h"
55#include "xfs_vnodeops.h"
55 56
56STATIC int 57int
57xfs_open( 58xfs_open(
58 bhv_desc_t *bdp, 59 xfs_inode_t *ip)
59 cred_t *credp)
60{ 60{
61 int mode; 61 int mode;
62 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
63 xfs_inode_t *ip = XFS_BHVTOI(bdp);
64 62
65 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 63 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
66 return XFS_ERROR(EIO); 64 return XFS_ERROR(EIO);
@@ -69,7 +67,7 @@ xfs_open(
69 * If it's a directory with any blocks, read-ahead block 0 67 * If it's a directory with any blocks, read-ahead block 0
70 * as we're almost certain to have the next operation be a read there. 68 * as we're almost certain to have the next operation be a read there.
71 */ 69 */
72 if (VN_ISDIR(vp) && ip->i_d.di_nextents > 0) { 70 if (S_ISDIR(ip->i_d.di_mode) && ip->i_d.di_nextents > 0) {
73 mode = xfs_ilock_map_shared(ip); 71 mode = xfs_ilock_map_shared(ip);
74 if (ip->i_d.di_nextents > 0) 72 if (ip->i_d.di_nextents > 0)
75 (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); 73 (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK);
@@ -81,22 +79,16 @@ xfs_open(
81/* 79/*
82 * xfs_getattr 80 * xfs_getattr
83 */ 81 */
84STATIC int 82int
85xfs_getattr( 83xfs_getattr(
86 bhv_desc_t *bdp, 84 xfs_inode_t *ip,
87 bhv_vattr_t *vap, 85 bhv_vattr_t *vap,
88 int flags, 86 int flags)
89 cred_t *credp)
90{ 87{
91 xfs_inode_t *ip; 88 bhv_vnode_t *vp = XFS_ITOV(ip);
92 xfs_mount_t *mp; 89 xfs_mount_t *mp = ip->i_mount;
93 bhv_vnode_t *vp;
94
95 vp = BHV_TO_VNODE(bdp);
96 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
97 90
98 ip = XFS_BHVTOI(bdp); 91 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
99 mp = ip->i_mount;
100 92
101 if (XFS_FORCED_SHUTDOWN(mp)) 93 if (XFS_FORCED_SHUTDOWN(mp))
102 return XFS_ERROR(EIO); 94 return XFS_ERROR(EIO);
@@ -215,14 +207,14 @@ xfs_getattr(
215 */ 207 */
216int 208int
217xfs_setattr( 209xfs_setattr(
218 bhv_desc_t *bdp, 210 xfs_inode_t *ip,
219 bhv_vattr_t *vap, 211 bhv_vattr_t *vap,
220 int flags, 212 int flags,
221 cred_t *credp) 213 cred_t *credp)
222{ 214{
223 xfs_inode_t *ip; 215 bhv_vnode_t *vp = XFS_ITOV(ip);
216 xfs_mount_t *mp = ip->i_mount;
224 xfs_trans_t *tp; 217 xfs_trans_t *tp;
225 xfs_mount_t *mp;
226 int mask; 218 int mask;
227 int code; 219 int code;
228 uint lock_flags; 220 uint lock_flags;
@@ -230,17 +222,15 @@ xfs_setattr(
230 uid_t uid=0, iuid=0; 222 uid_t uid=0, iuid=0;
231 gid_t gid=0, igid=0; 223 gid_t gid=0, igid=0;
232 int timeflags = 0; 224 int timeflags = 0;
233 bhv_vnode_t *vp;
234 xfs_prid_t projid=0, iprojid=0; 225 xfs_prid_t projid=0, iprojid=0;
235 int mandlock_before, mandlock_after; 226 int mandlock_before, mandlock_after;
236 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; 227 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
237 int file_owner; 228 int file_owner;
238 int need_iolock = 1; 229 int need_iolock = 1;
239 230
240 vp = BHV_TO_VNODE(bdp); 231 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
241 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
242 232
243 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 233 if (mp->m_flags & XFS_MOUNT_RDONLY)
244 return XFS_ERROR(EROFS); 234 return XFS_ERROR(EROFS);
245 235
246 /* 236 /*
@@ -251,9 +241,6 @@ xfs_setattr(
251 return XFS_ERROR(EINVAL); 241 return XFS_ERROR(EINVAL);
252 } 242 }
253 243
254 ip = XFS_BHVTOI(bdp);
255 mp = ip->i_mount;
256
257 if (XFS_FORCED_SHUTDOWN(mp)) 244 if (XFS_FORCED_SHUTDOWN(mp))
258 return XFS_ERROR(EIO); 245 return XFS_ERROR(EIO);
259 246
@@ -337,7 +324,7 @@ xfs_setattr(
337 } 324 }
338 } 325 }
339 } else { 326 } else {
340 if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) && 327 if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) &&
341 !(flags & ATTR_DMI)) { 328 !(flags & ATTR_DMI)) {
342 int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR; 329 int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR;
343 code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp, 330 code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp,
@@ -605,13 +592,13 @@ xfs_setattr(
605 if (!code && 592 if (!code &&
606 (ip->i_size != ip->i_d.di_size) && 593 (ip->i_size != ip->i_d.di_size) &&
607 (vap->va_size > ip->i_d.di_size)) { 594 (vap->va_size > ip->i_d.di_size)) {
608 code = bhv_vop_flush_pages(XFS_ITOV(ip), 595 code = xfs_flush_pages(ip,
609 ip->i_d.di_size, vap->va_size, 596 ip->i_d.di_size, vap->va_size,
610 XFS_B_ASYNC, FI_NONE); 597 XFS_B_ASYNC, FI_NONE);
611 } 598 }
612 599
613 /* wait for all I/O to complete */ 600 /* wait for all I/O to complete */
614 vn_iowait(vp); 601 vn_iowait(ip);
615 602
616 if (!code) 603 if (!code)
617 code = xfs_itruncate_data(ip, vap->va_size); 604 code = xfs_itruncate_data(ip, vap->va_size);
@@ -673,7 +660,7 @@ xfs_setattr(
673 * vnode and flush it when the file is closed, and 660 * vnode and flush it when the file is closed, and
674 * do not wait the usual (long) time for writeout. 661 * do not wait the usual (long) time for writeout.
675 */ 662 */
676 VTRUNCATE(vp); 663 xfs_iflags_set(ip, XFS_ITRUNCATED);
677 } 664 }
678 /* 665 /*
679 * Have to do this even if the file's size doesn't change. 666 * Have to do this even if the file's size doesn't change.
@@ -877,10 +864,6 @@ xfs_setattr(
877 * racing calls to vop_vnode_change. 864 * racing calls to vop_vnode_change.
878 */ 865 */
879 mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); 866 mandlock_after = MANDLOCK(vp, ip->i_d.di_mode);
880 if (mandlock_before != mandlock_after) {
881 bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING,
882 mandlock_after);
883 }
884 867
885 xfs_iunlock(ip, lock_flags); 868 xfs_iunlock(ip, lock_flags);
886 869
@@ -896,7 +879,7 @@ xfs_setattr(
896 return code; 879 return code;
897 } 880 }
898 881
899 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) && 882 if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) &&
900 !(flags & ATTR_DMI)) { 883 !(flags & ATTR_DMI)) {
901 (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL, 884 (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL,
902 NULL, DM_RIGHT_NULL, NULL, NULL, 885 NULL, DM_RIGHT_NULL, NULL, NULL,
@@ -924,19 +907,16 @@ xfs_setattr(
924 * xfs_access 907 * xfs_access
925 * Null conversion from vnode mode bits to inode mode bits, as in efs. 908 * Null conversion from vnode mode bits to inode mode bits, as in efs.
926 */ 909 */
927STATIC int 910int
928xfs_access( 911xfs_access(
929 bhv_desc_t *bdp, 912 xfs_inode_t *ip,
930 int mode, 913 int mode,
931 cred_t *credp) 914 cred_t *credp)
932{ 915{
933 xfs_inode_t *ip;
934 int error; 916 int error;
935 917
936 vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, 918 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
937 (inst_t *)__return_address);
938 919
939 ip = XFS_BHVTOI(bdp);
940 xfs_ilock(ip, XFS_ILOCK_SHARED); 920 xfs_ilock(ip, XFS_ILOCK_SHARED);
941 error = xfs_iaccess(ip, mode, credp); 921 error = xfs_iaccess(ip, mode, credp);
942 xfs_iunlock(ip, XFS_ILOCK_SHARED); 922 xfs_iunlock(ip, XFS_ILOCK_SHARED);
@@ -951,105 +931,88 @@ xfs_access(
951 */ 931 */
952#define SYMLINK_MAPS 2 932#define SYMLINK_MAPS 2
953 933
954/*
955 * xfs_readlink
956 *
957 */
958STATIC int 934STATIC int
959xfs_readlink( 935xfs_readlink_bmap(
960 bhv_desc_t *bdp, 936 xfs_inode_t *ip,
961 uio_t *uiop, 937 char *link)
962 int ioflags,
963 cred_t *credp)
964{ 938{
965 xfs_inode_t *ip; 939 xfs_mount_t *mp = ip->i_mount;
966 int count; 940 int pathlen = ip->i_d.di_size;
967 xfs_off_t offset; 941 int nmaps = SYMLINK_MAPS;
968 int pathlen;
969 bhv_vnode_t *vp;
970 int error = 0;
971 xfs_mount_t *mp;
972 int nmaps;
973 xfs_bmbt_irec_t mval[SYMLINK_MAPS]; 942 xfs_bmbt_irec_t mval[SYMLINK_MAPS];
974 xfs_daddr_t d; 943 xfs_daddr_t d;
975 int byte_cnt; 944 int byte_cnt;
976 int n; 945 int n;
977 xfs_buf_t *bp; 946 xfs_buf_t *bp;
947 int error = 0;
978 948
979 vp = BHV_TO_VNODE(bdp); 949 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 0, NULL, 0,
980 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 950 mval, &nmaps, NULL, NULL);
981 951 if (error)
982 ip = XFS_BHVTOI(bdp); 952 goto out;
983 mp = ip->i_mount;
984 953
985 if (XFS_FORCED_SHUTDOWN(mp)) 954 for (n = 0; n < nmaps; n++) {
986 return XFS_ERROR(EIO); 955 d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
956 byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
987 957
988 xfs_ilock(ip, XFS_ILOCK_SHARED); 958 bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0);
959 error = XFS_BUF_GETERROR(bp);
960 if (error) {
961 xfs_ioerror_alert("xfs_readlink",
962 ip->i_mount, bp, XFS_BUF_ADDR(bp));
963 xfs_buf_relse(bp);
964 goto out;
965 }
966 if (pathlen < byte_cnt)
967 byte_cnt = pathlen;
968 pathlen -= byte_cnt;
989 969
990 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK); 970 memcpy(link, XFS_BUF_PTR(bp), byte_cnt);
971 xfs_buf_relse(bp);
972 }
991 973
992 offset = uiop->uio_offset; 974 link[ip->i_d.di_size] = '\0';
993 count = uiop->uio_resid; 975 error = 0;
994 976
995 if (offset < 0) { 977 out:
996 error = XFS_ERROR(EINVAL); 978 return error;
997 goto error_return; 979}
998 }
999 if (count <= 0) {
1000 error = 0;
1001 goto error_return;
1002 }
1003 980
1004 /* 981int
1005 * See if the symlink is stored inline. 982xfs_readlink(
1006 */ 983 xfs_inode_t *ip,
1007 pathlen = (int)ip->i_d.di_size; 984 char *link)
985{
986 xfs_mount_t *mp = ip->i_mount;
987 int pathlen;
988 int error = 0;
1008 989
1009 if (ip->i_df.if_flags & XFS_IFINLINE) { 990 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
1010 error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop);
1011 }
1012 else {
1013 /*
1014 * Symlink not inline. Call bmap to get it in.
1015 */
1016 nmaps = SYMLINK_MAPS;
1017 991
1018 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 992 if (XFS_FORCED_SHUTDOWN(mp))
1019 0, NULL, 0, mval, &nmaps, NULL, NULL); 993 return XFS_ERROR(EIO);
1020 994
1021 if (error) { 995 xfs_ilock(ip, XFS_ILOCK_SHARED);
1022 goto error_return;
1023 }
1024 996
1025 for (n = 0; n < nmaps; n++) { 997 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK);
1026 d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); 998 ASSERT(ip->i_d.di_size <= MAXPATHLEN);
1027 byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
1028 bp = xfs_buf_read(mp->m_ddev_targp, d,
1029 BTOBB(byte_cnt), 0);
1030 error = XFS_BUF_GETERROR(bp);
1031 if (error) {
1032 xfs_ioerror_alert("xfs_readlink",
1033 ip->i_mount, bp, XFS_BUF_ADDR(bp));
1034 xfs_buf_relse(bp);
1035 goto error_return;
1036 }
1037 if (pathlen < byte_cnt)
1038 byte_cnt = pathlen;
1039 pathlen -= byte_cnt;
1040 999
1041 error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop); 1000 pathlen = ip->i_d.di_size;
1042 xfs_buf_relse (bp); 1001 if (!pathlen)
1043 } 1002 goto out;
1044 1003
1004 if (ip->i_df.if_flags & XFS_IFINLINE) {
1005 memcpy(link, ip->i_df.if_u1.if_data, pathlen);
1006 link[pathlen] = '\0';
1007 } else {
1008 error = xfs_readlink_bmap(ip, link);
1045 } 1009 }
1046 1010
1047error_return: 1011 out:
1048 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1012 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1049 return error; 1013 return error;
1050} 1014}
1051 1015
1052
1053/* 1016/*
1054 * xfs_fsync 1017 * xfs_fsync
1055 * 1018 *
@@ -1059,23 +1022,18 @@ error_return:
1059 * be held while flushing the data, so acquire after we're done 1022 * be held while flushing the data, so acquire after we're done
1060 * with that. 1023 * with that.
1061 */ 1024 */
1062STATIC int 1025int
1063xfs_fsync( 1026xfs_fsync(
1064 bhv_desc_t *bdp, 1027 xfs_inode_t *ip,
1065 int flag, 1028 int flag,
1066 cred_t *credp,
1067 xfs_off_t start, 1029 xfs_off_t start,
1068 xfs_off_t stop) 1030 xfs_off_t stop)
1069{ 1031{
1070 xfs_inode_t *ip;
1071 xfs_trans_t *tp; 1032 xfs_trans_t *tp;
1072 int error; 1033 int error;
1073 int log_flushed = 0, changed = 1; 1034 int log_flushed = 0, changed = 1;
1074 1035
1075 vn_trace_entry(BHV_TO_VNODE(bdp), 1036 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
1076 __FUNCTION__, (inst_t *)__return_address);
1077
1078 ip = XFS_BHVTOI(bdp);
1079 1037
1080 ASSERT(start >= 0 && stop >= -1); 1038 ASSERT(start >= 0 && stop >= -1);
1081 1039
@@ -1545,27 +1503,24 @@ xfs_inactive_attrs(
1545 return 0; 1503 return 0;
1546} 1504}
1547 1505
1548STATIC int 1506int
1549xfs_release( 1507xfs_release(
1550 bhv_desc_t *bdp) 1508 xfs_inode_t *ip)
1551{ 1509{
1552 xfs_inode_t *ip; 1510 bhv_vnode_t *vp = XFS_ITOV(ip);
1553 bhv_vnode_t *vp; 1511 xfs_mount_t *mp = ip->i_mount;
1554 xfs_mount_t *mp;
1555 int error; 1512 int error;
1556 1513
1557 vp = BHV_TO_VNODE(bdp);
1558 ip = XFS_BHVTOI(bdp);
1559 mp = ip->i_mount;
1560
1561 if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) 1514 if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0))
1562 return 0; 1515 return 0;
1563 1516
1564 /* If this is a read-only mount, don't do this (would generate I/O) */ 1517 /* If this is a read-only mount, don't do this (would generate I/O) */
1565 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 1518 if (mp->m_flags & XFS_MOUNT_RDONLY)
1566 return 0; 1519 return 0;
1567 1520
1568 if (!XFS_FORCED_SHUTDOWN(mp)) { 1521 if (!XFS_FORCED_SHUTDOWN(mp)) {
1522 int truncated;
1523
1569 /* 1524 /*
1570 * If we are using filestreams, and we have an unlinked 1525 * If we are using filestreams, and we have an unlinked
1571 * file that we are processing the last close on, then nothing 1526 * file that we are processing the last close on, then nothing
@@ -1586,8 +1541,9 @@ xfs_release(
1586 * significantly reducing the time window where we'd otherwise 1541 * significantly reducing the time window where we'd otherwise
1587 * be exposed to that problem. 1542 * be exposed to that problem.
1588 */ 1543 */
1589 if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0) 1544 truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED);
1590 bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE); 1545 if (truncated && VN_DIRTY(vp) && ip->i_delayed_blks > 0)
1546 xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE);
1591 } 1547 }
1592 1548
1593#ifdef HAVE_REFCACHE 1549#ifdef HAVE_REFCACHE
@@ -1623,13 +1579,11 @@ xfs_release(
1623 * now be truncated. Also, we clear all of the read-ahead state 1579 * now be truncated. Also, we clear all of the read-ahead state
1624 * kept for the inode here since the file is now closed. 1580 * kept for the inode here since the file is now closed.
1625 */ 1581 */
1626STATIC int 1582int
1627xfs_inactive( 1583xfs_inactive(
1628 bhv_desc_t *bdp, 1584 xfs_inode_t *ip)
1629 cred_t *credp)
1630{ 1585{
1631 xfs_inode_t *ip; 1586 bhv_vnode_t *vp = XFS_ITOV(ip);
1632 bhv_vnode_t *vp;
1633 xfs_bmap_free_t free_list; 1587 xfs_bmap_free_t free_list;
1634 xfs_fsblock_t first_block; 1588 xfs_fsblock_t first_block;
1635 int committed; 1589 int committed;
@@ -1638,10 +1592,7 @@ xfs_inactive(
1638 int error; 1592 int error;
1639 int truncate; 1593 int truncate;
1640 1594
1641 vp = BHV_TO_VNODE(bdp); 1595 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
1642 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
1643
1644 ip = XFS_BHVTOI(bdp);
1645 1596
1646 /* 1597 /*
1647 * If the inode is already free, then there can be nothing 1598 * If the inode is already free, then there can be nothing
@@ -1666,15 +1617,14 @@ xfs_inactive(
1666 1617
1667 mp = ip->i_mount; 1618 mp = ip->i_mount;
1668 1619
1669 if (ip->i_d.di_nlink == 0 && 1620 if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY)) {
1670 DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_DESTROY)) {
1671 (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL); 1621 (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL);
1672 } 1622 }
1673 1623
1674 error = 0; 1624 error = 0;
1675 1625
1676 /* If this is a read-only mount, don't do this (would generate I/O) */ 1626 /* If this is a read-only mount, don't do this (would generate I/O) */
1677 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 1627 if (mp->m_flags & XFS_MOUNT_RDONLY)
1678 goto out; 1628 goto out;
1679 1629
1680 if (ip->i_d.di_nlink != 0) { 1630 if (ip->i_d.di_nlink != 0) {
@@ -1844,34 +1794,24 @@ xfs_inactive(
1844} 1794}
1845 1795
1846 1796
1847/* 1797int
1848 * xfs_lookup
1849 */
1850STATIC int
1851xfs_lookup( 1798xfs_lookup(
1852 bhv_desc_t *dir_bdp, 1799 xfs_inode_t *dp,
1853 bhv_vname_t *dentry, 1800 bhv_vname_t *dentry,
1854 bhv_vnode_t **vpp, 1801 bhv_vnode_t **vpp)
1855 int flags,
1856 bhv_vnode_t *rdir,
1857 cred_t *credp)
1858{ 1802{
1859 xfs_inode_t *dp, *ip; 1803 xfs_inode_t *ip;
1860 xfs_ino_t e_inum; 1804 xfs_ino_t e_inum;
1861 int error; 1805 int error;
1862 uint lock_mode; 1806 uint lock_mode;
1863 bhv_vnode_t *dir_vp;
1864
1865 dir_vp = BHV_TO_VNODE(dir_bdp);
1866 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
1867 1807
1868 dp = XFS_BHVTOI(dir_bdp); 1808 vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
1869 1809
1870 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 1810 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
1871 return XFS_ERROR(EIO); 1811 return XFS_ERROR(EIO);
1872 1812
1873 lock_mode = xfs_ilock_map_shared(dp); 1813 lock_mode = xfs_ilock_map_shared(dp);
1874 error = xfs_dir_lookup_int(dir_bdp, lock_mode, dentry, &e_inum, &ip); 1814 error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip);
1875 if (!error) { 1815 if (!error) {
1876 *vpp = XFS_ITOV(ip); 1816 *vpp = XFS_ITOV(ip);
1877 ITRACE(ip); 1817 ITRACE(ip);
@@ -1880,53 +1820,43 @@ xfs_lookup(
1880 return error; 1820 return error;
1881} 1821}
1882 1822
1883 1823int
1884/*
1885 * xfs_create (create a new file).
1886 */
1887STATIC int
1888xfs_create( 1824xfs_create(
1889 bhv_desc_t *dir_bdp, 1825 xfs_inode_t *dp,
1890 bhv_vname_t *dentry, 1826 bhv_vname_t *dentry,
1891 bhv_vattr_t *vap, 1827 mode_t mode,
1828 xfs_dev_t rdev,
1892 bhv_vnode_t **vpp, 1829 bhv_vnode_t **vpp,
1893 cred_t *credp) 1830 cred_t *credp)
1894{ 1831{
1895 char *name = VNAME(dentry); 1832 char *name = VNAME(dentry);
1896 bhv_vnode_t *dir_vp; 1833 xfs_mount_t *mp = dp->i_mount;
1897 xfs_inode_t *dp, *ip; 1834 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
1835 xfs_inode_t *ip;
1898 bhv_vnode_t *vp = NULL; 1836 bhv_vnode_t *vp = NULL;
1899 xfs_trans_t *tp; 1837 xfs_trans_t *tp;
1900 xfs_mount_t *mp;
1901 xfs_dev_t rdev;
1902 int error; 1838 int error;
1903 xfs_bmap_free_t free_list; 1839 xfs_bmap_free_t free_list;
1904 xfs_fsblock_t first_block; 1840 xfs_fsblock_t first_block;
1905 boolean_t dp_joined_to_trans; 1841 boolean_t unlock_dp_on_error = B_FALSE;
1906 int dm_event_sent = 0; 1842 int dm_event_sent = 0;
1907 uint cancel_flags; 1843 uint cancel_flags;
1908 int committed; 1844 int committed;
1909 xfs_prid_t prid; 1845 xfs_prid_t prid;
1910 struct xfs_dquot *udqp, *gdqp; 1846 struct xfs_dquot *udqp, *gdqp;
1911 uint resblks; 1847 uint resblks;
1912 int dm_di_mode;
1913 int namelen; 1848 int namelen;
1914 1849
1915 ASSERT(!*vpp); 1850 ASSERT(!*vpp);
1916 dir_vp = BHV_TO_VNODE(dir_bdp); 1851 vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
1917 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
1918 1852
1919 dp = XFS_BHVTOI(dir_bdp);
1920 mp = dp->i_mount;
1921
1922 dm_di_mode = vap->va_mode;
1923 namelen = VNAMELEN(dentry); 1853 namelen = VNAMELEN(dentry);
1924 1854
1925 if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { 1855 if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
1926 error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, 1856 error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
1927 dir_vp, DM_RIGHT_NULL, NULL, 1857 dir_vp, DM_RIGHT_NULL, NULL,
1928 DM_RIGHT_NULL, name, NULL, 1858 DM_RIGHT_NULL, name, NULL,
1929 dm_di_mode, 0, 0); 1859 mode, 0, 0);
1930 1860
1931 if (error) 1861 if (error)
1932 return error; 1862 return error;
@@ -1941,8 +1871,6 @@ xfs_create(
1941 udqp = gdqp = NULL; 1871 udqp = gdqp = NULL;
1942 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) 1872 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1943 prid = dp->i_d.di_projid; 1873 prid = dp->i_d.di_projid;
1944 else if (vap->va_mask & XFS_AT_PROJID)
1945 prid = (xfs_prid_t)vap->va_projid;
1946 else 1874 else
1947 prid = (xfs_prid_t)dfltprid; 1875 prid = (xfs_prid_t)dfltprid;
1948 1876
@@ -1956,7 +1884,6 @@ xfs_create(
1956 goto std_return; 1884 goto std_return;
1957 1885
1958 ip = NULL; 1886 ip = NULL;
1959 dp_joined_to_trans = B_FALSE;
1960 1887
1961 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); 1888 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
1962 cancel_flags = XFS_TRANS_RELEASE_LOG_RES; 1889 cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
@@ -1976,11 +1903,11 @@ xfs_create(
1976 } 1903 }
1977 if (error) { 1904 if (error) {
1978 cancel_flags = 0; 1905 cancel_flags = 0;
1979 dp = NULL;
1980 goto error_return; 1906 goto error_return;
1981 } 1907 }
1982 1908
1983 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); 1909 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
1910 unlock_dp_on_error = B_TRUE;
1984 1911
1985 XFS_BMAP_INIT(&free_list, &first_block); 1912 XFS_BMAP_INIT(&free_list, &first_block);
1986 1913
@@ -1995,8 +1922,7 @@ xfs_create(
1995 1922
1996 if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) 1923 if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen)))
1997 goto error_return; 1924 goto error_return;
1998 rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; 1925 error = xfs_dir_ialloc(&tp, dp, mode, 1,
1999 error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1,
2000 rdev, credp, prid, resblks > 0, 1926 rdev, credp, prid, resblks > 0,
2001 &ip, &committed); 1927 &ip, &committed);
2002 if (error) { 1928 if (error) {
@@ -2014,15 +1940,15 @@ xfs_create(
2014 ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); 1940 ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE));
2015 1941
2016 /* 1942 /*
2017 * Now we join the directory inode to the transaction. 1943 * Now we join the directory inode to the transaction. We do not do it
2018 * We do not do it earlier because xfs_dir_ialloc 1944 * earlier because xfs_dir_ialloc might commit the previous transaction
2019 * might commit the previous transaction (and release 1945 * (and release all the locks). An error from here on will result in
2020 * all the locks). 1946 * the transaction cancel unlocking dp so don't do it explicitly in the
1947 * error path.
2021 */ 1948 */
2022
2023 VN_HOLD(dir_vp); 1949 VN_HOLD(dir_vp);
2024 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 1950 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
2025 dp_joined_to_trans = B_TRUE; 1951 unlock_dp_on_error = B_FALSE;
2026 1952
2027 error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, 1953 error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino,
2028 &first_block, &free_list, resblks ? 1954 &first_block, &free_list, resblks ?
@@ -2076,25 +2002,18 @@ xfs_create(
2076 XFS_QM_DQRELE(mp, udqp); 2002 XFS_QM_DQRELE(mp, udqp);
2077 XFS_QM_DQRELE(mp, gdqp); 2003 XFS_QM_DQRELE(mp, gdqp);
2078 2004
2079 /*
2080 * Propagate the fact that the vnode changed after the
2081 * xfs_inode locks have been released.
2082 */
2083 bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3);
2084
2085 *vpp = vp; 2005 *vpp = vp;
2086 2006
2087 /* Fallthrough to std_return with error = 0 */ 2007 /* Fallthrough to std_return with error = 0 */
2088 2008
2089std_return: 2009std_return:
2090 if ( (*vpp || (error != 0 && dm_event_sent != 0)) && 2010 if ((*vpp || (error != 0 && dm_event_sent != 0)) &&
2091 DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), 2011 DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
2092 DM_EVENT_POSTCREATE)) {
2093 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, 2012 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
2094 dir_vp, DM_RIGHT_NULL, 2013 dir_vp, DM_RIGHT_NULL,
2095 *vpp ? vp:NULL, 2014 *vpp ? vp:NULL,
2096 DM_RIGHT_NULL, name, NULL, 2015 DM_RIGHT_NULL, name, NULL,
2097 dm_di_mode, error, 0); 2016 mode, error, 0);
2098 } 2017 }
2099 return error; 2018 return error;
2100 2019
@@ -2106,11 +2025,12 @@ std_return:
2106 if (tp != NULL) 2025 if (tp != NULL)
2107 xfs_trans_cancel(tp, cancel_flags); 2026 xfs_trans_cancel(tp, cancel_flags);
2108 2027
2109 if (!dp_joined_to_trans && (dp != NULL))
2110 xfs_iunlock(dp, XFS_ILOCK_EXCL);
2111 XFS_QM_DQRELE(mp, udqp); 2028 XFS_QM_DQRELE(mp, udqp);
2112 XFS_QM_DQRELE(mp, gdqp); 2029 XFS_QM_DQRELE(mp, gdqp);
2113 2030
2031 if (unlock_dp_on_error)
2032 xfs_iunlock(dp, XFS_ILOCK_EXCL);
2033
2114 goto std_return; 2034 goto std_return;
2115 2035
2116 abort_rele: 2036 abort_rele:
@@ -2381,22 +2301,16 @@ int remove_which_error_return = 0;
2381#define REMOVE_DEBUG_TRACE(x) 2301#define REMOVE_DEBUG_TRACE(x)
2382#endif /* ! DEBUG */ 2302#endif /* ! DEBUG */
2383 2303
2384 2304int
2385/*
2386 * xfs_remove
2387 *
2388 */
2389STATIC int
2390xfs_remove( 2305xfs_remove(
2391 bhv_desc_t *dir_bdp, 2306 xfs_inode_t *dp,
2392 bhv_vname_t *dentry, 2307 bhv_vname_t *dentry)
2393 cred_t *credp)
2394{ 2308{
2395 bhv_vnode_t *dir_vp; 2309 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
2396 char *name = VNAME(dentry); 2310 char *name = VNAME(dentry);
2397 xfs_inode_t *dp, *ip; 2311 xfs_mount_t *mp = dp->i_mount;
2312 xfs_inode_t *ip;
2398 xfs_trans_t *tp = NULL; 2313 xfs_trans_t *tp = NULL;
2399 xfs_mount_t *mp;
2400 int error = 0; 2314 int error = 0;
2401 xfs_bmap_free_t free_list; 2315 xfs_bmap_free_t free_list;
2402 xfs_fsblock_t first_block; 2316 xfs_fsblock_t first_block;
@@ -2407,11 +2321,7 @@ xfs_remove(
2407 uint resblks; 2321 uint resblks;
2408 int namelen; 2322 int namelen;
2409 2323
2410 dir_vp = BHV_TO_VNODE(dir_bdp); 2324 vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
2411 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
2412
2413 dp = XFS_BHVTOI(dir_bdp);
2414 mp = dp->i_mount;
2415 2325
2416 if (XFS_FORCED_SHUTDOWN(mp)) 2326 if (XFS_FORCED_SHUTDOWN(mp))
2417 return XFS_ERROR(EIO); 2327 return XFS_ERROR(EIO);
@@ -2423,7 +2333,7 @@ xfs_remove(
2423 IRELE(ip); 2333 IRELE(ip);
2424 } 2334 }
2425 2335
2426 if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { 2336 if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) {
2427 error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, 2337 error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
2428 DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, 2338 DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
2429 name, NULL, dm_di_mode, 0, 0); 2339 name, NULL, dm_di_mode, 0, 0);
@@ -2454,7 +2364,7 @@ xfs_remove(
2454 2364
2455 dm_di_mode = ip->i_d.di_mode; 2365 dm_di_mode = ip->i_d.di_mode;
2456 2366
2457 vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); 2367 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
2458 2368
2459 ITRACE(ip); 2369 ITRACE(ip);
2460 2370
@@ -2588,19 +2498,13 @@ xfs_remove(
2588 if (link_zero && xfs_inode_is_filestream(ip)) 2498 if (link_zero && xfs_inode_is_filestream(ip))
2589 xfs_filestream_deassociate(ip); 2499 xfs_filestream_deassociate(ip);
2590 2500
2591 vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); 2501 vn_trace_exit(ip, __FUNCTION__, (inst_t *)__return_address);
2592
2593 /*
2594 * Let interposed file systems know about removed links.
2595 */
2596 bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero);
2597 2502
2598 IRELE(ip); 2503 IRELE(ip);
2599 2504
2600/* Fall through to std_return with error = 0 */ 2505/* Fall through to std_return with error = 0 */
2601 std_return: 2506 std_return:
2602 if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, 2507 if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) {
2603 DM_EVENT_POSTREMOVE)) {
2604 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, 2508 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
2605 dir_vp, DM_RIGHT_NULL, 2509 dir_vp, DM_RIGHT_NULL,
2606 NULL, DM_RIGHT_NULL, 2510 NULL, DM_RIGHT_NULL,
@@ -2638,46 +2542,36 @@ xfs_remove(
2638 goto std_return; 2542 goto std_return;
2639} 2543}
2640 2544
2641 2545int
2642/*
2643 * xfs_link
2644 *
2645 */
2646STATIC int
2647xfs_link( 2546xfs_link(
2648 bhv_desc_t *target_dir_bdp, 2547 xfs_inode_t *tdp,
2649 bhv_vnode_t *src_vp, 2548 bhv_vnode_t *src_vp,
2650 bhv_vname_t *dentry, 2549 bhv_vname_t *dentry)
2651 cred_t *credp)
2652{ 2550{
2653 xfs_inode_t *tdp, *sip; 2551 bhv_vnode_t *target_dir_vp = XFS_ITOV(tdp);
2552 xfs_mount_t *mp = tdp->i_mount;
2553 xfs_inode_t *sip = xfs_vtoi(src_vp);
2654 xfs_trans_t *tp; 2554 xfs_trans_t *tp;
2655 xfs_mount_t *mp;
2656 xfs_inode_t *ips[2]; 2555 xfs_inode_t *ips[2];
2657 int error; 2556 int error;
2658 xfs_bmap_free_t free_list; 2557 xfs_bmap_free_t free_list;
2659 xfs_fsblock_t first_block; 2558 xfs_fsblock_t first_block;
2660 int cancel_flags; 2559 int cancel_flags;
2661 int committed; 2560 int committed;
2662 bhv_vnode_t *target_dir_vp;
2663 int resblks; 2561 int resblks;
2664 char *target_name = VNAME(dentry); 2562 char *target_name = VNAME(dentry);
2665 int target_namelen; 2563 int target_namelen;
2666 2564
2667 target_dir_vp = BHV_TO_VNODE(target_dir_bdp); 2565 vn_trace_entry(tdp, __FUNCTION__, (inst_t *)__return_address);
2668 vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address); 2566 vn_trace_entry(xfs_vtoi(src_vp), __FUNCTION__, (inst_t *)__return_address);
2669 vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address);
2670 2567
2671 target_namelen = VNAMELEN(dentry); 2568 target_namelen = VNAMELEN(dentry);
2672 ASSERT(!VN_ISDIR(src_vp)); 2569 ASSERT(!VN_ISDIR(src_vp));
2673 2570
2674 sip = xfs_vtoi(src_vp);
2675 tdp = XFS_BHVTOI(target_dir_bdp);
2676 mp = tdp->i_mount;
2677 if (XFS_FORCED_SHUTDOWN(mp)) 2571 if (XFS_FORCED_SHUTDOWN(mp))
2678 return XFS_ERROR(EIO); 2572 return XFS_ERROR(EIO);
2679 2573
2680 if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) { 2574 if (DM_EVENT_ENABLED(tdp, DM_EVENT_LINK)) {
2681 error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK, 2575 error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK,
2682 target_dir_vp, DM_RIGHT_NULL, 2576 target_dir_vp, DM_RIGHT_NULL,
2683 src_vp, DM_RIGHT_NULL, 2577 src_vp, DM_RIGHT_NULL,
@@ -2788,8 +2682,7 @@ xfs_link(
2788 2682
2789 /* Fall through to std_return with error = 0. */ 2683 /* Fall through to std_return with error = 0. */
2790std_return: 2684std_return:
2791 if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip, 2685 if (DM_EVENT_ENABLED(sip, DM_EVENT_POSTLINK)) {
2792 DM_EVENT_POSTLINK)) {
2793 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK, 2686 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK,
2794 target_dir_vp, DM_RIGHT_NULL, 2687 target_dir_vp, DM_RIGHT_NULL,
2795 src_vp, DM_RIGHT_NULL, 2688 src_vp, DM_RIGHT_NULL,
@@ -2807,57 +2700,43 @@ std_return:
2807} 2700}
2808 2701
2809 2702
2810/* 2703int
2811 * xfs_mkdir
2812 *
2813 */
2814STATIC int
2815xfs_mkdir( 2704xfs_mkdir(
2816 bhv_desc_t *dir_bdp, 2705 xfs_inode_t *dp,
2817 bhv_vname_t *dentry, 2706 bhv_vname_t *dentry,
2818 bhv_vattr_t *vap, 2707 mode_t mode,
2819 bhv_vnode_t **vpp, 2708 bhv_vnode_t **vpp,
2820 cred_t *credp) 2709 cred_t *credp)
2821{ 2710{
2711 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
2822 char *dir_name = VNAME(dentry); 2712 char *dir_name = VNAME(dentry);
2823 xfs_inode_t *dp; 2713 int dir_namelen = VNAMELEN(dentry);
2714 xfs_mount_t *mp = dp->i_mount;
2824 xfs_inode_t *cdp; /* inode of created dir */ 2715 xfs_inode_t *cdp; /* inode of created dir */
2825 bhv_vnode_t *cvp; /* vnode of created dir */ 2716 bhv_vnode_t *cvp; /* vnode of created dir */
2826 xfs_trans_t *tp; 2717 xfs_trans_t *tp;
2827 xfs_mount_t *mp;
2828 int cancel_flags; 2718 int cancel_flags;
2829 int error; 2719 int error;
2830 int committed; 2720 int committed;
2831 xfs_bmap_free_t free_list; 2721 xfs_bmap_free_t free_list;
2832 xfs_fsblock_t first_block; 2722 xfs_fsblock_t first_block;
2833 bhv_vnode_t *dir_vp; 2723 boolean_t unlock_dp_on_error = B_FALSE;
2834 boolean_t dp_joined_to_trans;
2835 boolean_t created = B_FALSE; 2724 boolean_t created = B_FALSE;
2836 int dm_event_sent = 0; 2725 int dm_event_sent = 0;
2837 xfs_prid_t prid; 2726 xfs_prid_t prid;
2838 struct xfs_dquot *udqp, *gdqp; 2727 struct xfs_dquot *udqp, *gdqp;
2839 uint resblks; 2728 uint resblks;
2840 int dm_di_mode;
2841 int dir_namelen;
2842
2843 dir_vp = BHV_TO_VNODE(dir_bdp);
2844 dp = XFS_BHVTOI(dir_bdp);
2845 mp = dp->i_mount;
2846 2729
2847 if (XFS_FORCED_SHUTDOWN(mp)) 2730 if (XFS_FORCED_SHUTDOWN(mp))
2848 return XFS_ERROR(EIO); 2731 return XFS_ERROR(EIO);
2849 2732
2850 dir_namelen = VNAMELEN(dentry);
2851
2852 tp = NULL; 2733 tp = NULL;
2853 dp_joined_to_trans = B_FALSE;
2854 dm_di_mode = vap->va_mode;
2855 2734
2856 if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { 2735 if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
2857 error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, 2736 error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
2858 dir_vp, DM_RIGHT_NULL, NULL, 2737 dir_vp, DM_RIGHT_NULL, NULL,
2859 DM_RIGHT_NULL, dir_name, NULL, 2738 DM_RIGHT_NULL, dir_name, NULL,
2860 dm_di_mode, 0, 0); 2739 mode, 0, 0);
2861 if (error) 2740 if (error)
2862 return error; 2741 return error;
2863 dm_event_sent = 1; 2742 dm_event_sent = 1;
@@ -2865,14 +2744,12 @@ xfs_mkdir(
2865 2744
2866 /* Return through std_return after this point. */ 2745 /* Return through std_return after this point. */
2867 2746
2868 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); 2747 vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
2869 2748
2870 mp = dp->i_mount; 2749 mp = dp->i_mount;
2871 udqp = gdqp = NULL; 2750 udqp = gdqp = NULL;
2872 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) 2751 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
2873 prid = dp->i_d.di_projid; 2752 prid = dp->i_d.di_projid;
2874 else if (vap->va_mask & XFS_AT_PROJID)
2875 prid = (xfs_prid_t)vap->va_projid;
2876 else 2753 else
2877 prid = (xfs_prid_t)dfltprid; 2754 prid = (xfs_prid_t)dfltprid;
2878 2755
@@ -2898,11 +2775,11 @@ xfs_mkdir(
2898 } 2775 }
2899 if (error) { 2776 if (error) {
2900 cancel_flags = 0; 2777 cancel_flags = 0;
2901 dp = NULL;
2902 goto error_return; 2778 goto error_return;
2903 } 2779 }
2904 2780
2905 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); 2781 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
2782 unlock_dp_on_error = B_TRUE;
2906 2783
2907 /* 2784 /*
2908 * Check for directory link count overflow. 2785 * Check for directory link count overflow.
@@ -2925,7 +2802,7 @@ xfs_mkdir(
2925 /* 2802 /*
2926 * create the directory inode. 2803 * create the directory inode.
2927 */ 2804 */
2928 error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 2, 2805 error = xfs_dir_ialloc(&tp, dp, mode, 2,
2929 0, credp, prid, resblks > 0, 2806 0, credp, prid, resblks > 0,
2930 &cdp, NULL); 2807 &cdp, NULL);
2931 if (error) { 2808 if (error) {
@@ -2939,11 +2816,13 @@ xfs_mkdir(
2939 * Now we add the directory inode to the transaction. 2816 * Now we add the directory inode to the transaction.
2940 * We waited until now since xfs_dir_ialloc might start 2817 * We waited until now since xfs_dir_ialloc might start
2941 * a new transaction. Had we joined the transaction 2818 * a new transaction. Had we joined the transaction
2942 * earlier, the locks might have gotten released. 2819 * earlier, the locks might have gotten released. An error
2820 * from here on will result in the transaction cancel
2821 * unlocking dp so don't do it explicitly in the error path.
2943 */ 2822 */
2944 VN_HOLD(dir_vp); 2823 VN_HOLD(dir_vp);
2945 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 2824 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
2946 dp_joined_to_trans = B_TRUE; 2825 unlock_dp_on_error = B_FALSE;
2947 2826
2948 XFS_BMAP_INIT(&free_list, &first_block); 2827 XFS_BMAP_INIT(&free_list, &first_block);
2949 2828
@@ -3010,15 +2889,14 @@ xfs_mkdir(
3010 * xfs_trans_commit. */ 2889 * xfs_trans_commit. */
3011 2890
3012std_return: 2891std_return:
3013 if ( (created || (error != 0 && dm_event_sent != 0)) && 2892 if ((created || (error != 0 && dm_event_sent != 0)) &&
3014 DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), 2893 DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
3015 DM_EVENT_POSTCREATE)) {
3016 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, 2894 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
3017 dir_vp, DM_RIGHT_NULL, 2895 dir_vp, DM_RIGHT_NULL,
3018 created ? XFS_ITOV(cdp):NULL, 2896 created ? XFS_ITOV(cdp):NULL,
3019 DM_RIGHT_NULL, 2897 DM_RIGHT_NULL,
3020 dir_name, NULL, 2898 dir_name, NULL,
3021 dm_di_mode, error, 0); 2899 mode, error, 0);
3022 } 2900 }
3023 return error; 2901 return error;
3024 2902
@@ -3032,56 +2910,43 @@ std_return:
3032 XFS_QM_DQRELE(mp, udqp); 2910 XFS_QM_DQRELE(mp, udqp);
3033 XFS_QM_DQRELE(mp, gdqp); 2911 XFS_QM_DQRELE(mp, gdqp);
3034 2912
3035 if (!dp_joined_to_trans && (dp != NULL)) { 2913 if (unlock_dp_on_error)
3036 xfs_iunlock(dp, XFS_ILOCK_EXCL); 2914 xfs_iunlock(dp, XFS_ILOCK_EXCL);
3037 }
3038 2915
3039 goto std_return; 2916 goto std_return;
3040} 2917}
3041 2918
3042 2919int
3043/*
3044 * xfs_rmdir
3045 *
3046 */
3047STATIC int
3048xfs_rmdir( 2920xfs_rmdir(
3049 bhv_desc_t *dir_bdp, 2921 xfs_inode_t *dp,
3050 bhv_vname_t *dentry, 2922 bhv_vname_t *dentry)
3051 cred_t *credp)
3052{ 2923{
2924 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
3053 char *name = VNAME(dentry); 2925 char *name = VNAME(dentry);
3054 xfs_inode_t *dp; 2926 int namelen = VNAMELEN(dentry);
3055 xfs_inode_t *cdp; /* child directory */ 2927 xfs_mount_t *mp = dp->i_mount;
2928 xfs_inode_t *cdp; /* child directory */
3056 xfs_trans_t *tp; 2929 xfs_trans_t *tp;
3057 xfs_mount_t *mp;
3058 int error; 2930 int error;
3059 xfs_bmap_free_t free_list; 2931 xfs_bmap_free_t free_list;
3060 xfs_fsblock_t first_block; 2932 xfs_fsblock_t first_block;
3061 int cancel_flags; 2933 int cancel_flags;
3062 int committed; 2934 int committed;
3063 bhv_vnode_t *dir_vp;
3064 int dm_di_mode = S_IFDIR; 2935 int dm_di_mode = S_IFDIR;
3065 int last_cdp_link; 2936 int last_cdp_link;
3066 int namelen;
3067 uint resblks; 2937 uint resblks;
3068 2938
3069 dir_vp = BHV_TO_VNODE(dir_bdp); 2939 vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
3070 dp = XFS_BHVTOI(dir_bdp);
3071 mp = dp->i_mount;
3072
3073 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
3074 2940
3075 if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount)) 2941 if (XFS_FORCED_SHUTDOWN(mp))
3076 return XFS_ERROR(EIO); 2942 return XFS_ERROR(EIO);
3077 namelen = VNAMELEN(dentry);
3078 2943
3079 if (!xfs_get_dir_entry(dentry, &cdp)) { 2944 if (!xfs_get_dir_entry(dentry, &cdp)) {
3080 dm_di_mode = cdp->i_d.di_mode; 2945 dm_di_mode = cdp->i_d.di_mode;
3081 IRELE(cdp); 2946 IRELE(cdp);
3082 } 2947 }
3083 2948
3084 if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { 2949 if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) {
3085 error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, 2950 error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
3086 dir_vp, DM_RIGHT_NULL, 2951 dir_vp, DM_RIGHT_NULL,
3087 NULL, DM_RIGHT_NULL, 2952 NULL, DM_RIGHT_NULL,
@@ -3260,17 +3125,12 @@ xfs_rmdir(
3260 } 3125 }
3261 3126
3262 3127
3263 /*
3264 * Let interposed file systems know about removed links.
3265 */
3266 bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link);
3267
3268 IRELE(cdp); 3128 IRELE(cdp);
3269 3129
3270 /* Fall through to std_return with error = 0 or the errno 3130 /* Fall through to std_return with error = 0 or the errno
3271 * from xfs_trans_commit. */ 3131 * from xfs_trans_commit. */
3272 std_return: 3132 std_return:
3273 if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) { 3133 if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) {
3274 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, 3134 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
3275 dir_vp, DM_RIGHT_NULL, 3135 dir_vp, DM_RIGHT_NULL,
3276 NULL, DM_RIGHT_NULL, 3136 NULL, DM_RIGHT_NULL,
@@ -3289,56 +3149,24 @@ xfs_rmdir(
3289 goto std_return; 3149 goto std_return;
3290} 3150}
3291 3151
3292 3152int
3293/*
3294 * Read dp's entries starting at uiop->uio_offset and translate them into
3295 * bufsize bytes worth of struct dirents starting at bufbase.
3296 */
3297STATIC int
3298xfs_readdir(
3299 bhv_desc_t *dir_bdp,
3300 uio_t *uiop,
3301 cred_t *credp,
3302 int *eofp)
3303{
3304 xfs_inode_t *dp;
3305 xfs_trans_t *tp = NULL;
3306 int error = 0;
3307 uint lock_mode;
3308
3309 vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
3310 (inst_t *)__return_address);
3311 dp = XFS_BHVTOI(dir_bdp);
3312
3313 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
3314 return XFS_ERROR(EIO);
3315
3316 lock_mode = xfs_ilock_map_shared(dp);
3317 error = xfs_dir_getdents(tp, dp, uiop, eofp);
3318 xfs_iunlock_map_shared(dp, lock_mode);
3319 return error;
3320}
3321
3322
3323STATIC int
3324xfs_symlink( 3153xfs_symlink(
3325 bhv_desc_t *dir_bdp, 3154 xfs_inode_t *dp,
3326 bhv_vname_t *dentry, 3155 bhv_vname_t *dentry,
3327 bhv_vattr_t *vap,
3328 char *target_path, 3156 char *target_path,
3157 mode_t mode,
3329 bhv_vnode_t **vpp, 3158 bhv_vnode_t **vpp,
3330 cred_t *credp) 3159 cred_t *credp)
3331{ 3160{
3161 bhv_vnode_t *dir_vp = XFS_ITOV(dp);
3162 xfs_mount_t *mp = dp->i_mount;
3332 xfs_trans_t *tp; 3163 xfs_trans_t *tp;
3333 xfs_mount_t *mp;
3334 xfs_inode_t *dp;
3335 xfs_inode_t *ip; 3164 xfs_inode_t *ip;
3336 int error; 3165 int error;
3337 int pathlen; 3166 int pathlen;
3338 xfs_bmap_free_t free_list; 3167 xfs_bmap_free_t free_list;
3339 xfs_fsblock_t first_block; 3168 xfs_fsblock_t first_block;
3340 boolean_t dp_joined_to_trans; 3169 boolean_t unlock_dp_on_error = B_FALSE;
3341 bhv_vnode_t *dir_vp;
3342 uint cancel_flags; 3170 uint cancel_flags;
3343 int committed; 3171 int committed;
3344 xfs_fileoff_t first_fsb; 3172 xfs_fileoff_t first_fsb;
@@ -3357,16 +3185,12 @@ xfs_symlink(
3357 int link_namelen; 3185 int link_namelen;
3358 3186
3359 *vpp = NULL; 3187 *vpp = NULL;
3360 dir_vp = BHV_TO_VNODE(dir_bdp);
3361 dp = XFS_BHVTOI(dir_bdp);
3362 dp_joined_to_trans = B_FALSE;
3363 error = 0; 3188 error = 0;
3364 ip = NULL; 3189 ip = NULL;
3365 tp = NULL; 3190 tp = NULL;
3366 3191
3367 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); 3192 vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
3368 3193
3369 mp = dp->i_mount;
3370 3194
3371 if (XFS_FORCED_SHUTDOWN(mp)) 3195 if (XFS_FORCED_SHUTDOWN(mp))
3372 return XFS_ERROR(EIO); 3196 return XFS_ERROR(EIO);
@@ -3405,7 +3229,7 @@ xfs_symlink(
3405 } 3229 }
3406 } 3230 }
3407 3231
3408 if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) { 3232 if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) {
3409 error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp, 3233 error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp,
3410 DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, 3234 DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
3411 link_name, target_path, 0, 0, 0); 3235 link_name, target_path, 0, 0, 0);
@@ -3418,8 +3242,6 @@ xfs_symlink(
3418 udqp = gdqp = NULL; 3242 udqp = gdqp = NULL;
3419 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) 3243 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
3420 prid = dp->i_d.di_projid; 3244 prid = dp->i_d.di_projid;
3421 else if (vap->va_mask & XFS_AT_PROJID)
3422 prid = (xfs_prid_t)vap->va_projid;
3423 else 3245 else
3424 prid = (xfs_prid_t)dfltprid; 3246 prid = (xfs_prid_t)dfltprid;
3425 3247
@@ -3452,11 +3274,11 @@ xfs_symlink(
3452 } 3274 }
3453 if (error) { 3275 if (error) {
3454 cancel_flags = 0; 3276 cancel_flags = 0;
3455 dp = NULL;
3456 goto error_return; 3277 goto error_return;
3457 } 3278 }
3458 3279
3459 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); 3280 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
3281 unlock_dp_on_error = B_TRUE;
3460 3282
3461 /* 3283 /*
3462 * Check whether the directory allows new symlinks or not. 3284 * Check whether the directory allows new symlinks or not.
@@ -3488,7 +3310,7 @@ xfs_symlink(
3488 /* 3310 /*
3489 * Allocate an inode for the symlink. 3311 * Allocate an inode for the symlink.
3490 */ 3312 */
3491 error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (vap->va_mode&~S_IFMT), 3313 error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT),
3492 1, 0, credp, prid, resblks > 0, &ip, NULL); 3314 1, 0, credp, prid, resblks > 0, &ip, NULL);
3493 if (error) { 3315 if (error) {
3494 if (error == ENOSPC) 3316 if (error == ENOSPC)
@@ -3497,9 +3319,14 @@ xfs_symlink(
3497 } 3319 }
3498 ITRACE(ip); 3320 ITRACE(ip);
3499 3321
3322 /*
3323 * An error after we've joined dp to the transaction will result in the
3324 * transaction cancel unlocking dp so don't do it explicitly in the
3325 * error path.
3326 */
3500 VN_HOLD(dir_vp); 3327 VN_HOLD(dir_vp);
3501 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 3328 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
3502 dp_joined_to_trans = B_TRUE; 3329 unlock_dp_on_error = B_FALSE;
3503 3330
3504 /* 3331 /*
3505 * Also attach the dquot(s) to it, if applicable. 3332 * Also attach the dquot(s) to it, if applicable.
@@ -3605,8 +3432,7 @@ xfs_symlink(
3605 /* Fall through to std_return with error = 0 or errno from 3432 /* Fall through to std_return with error = 0 or errno from
3606 * xfs_trans_commit */ 3433 * xfs_trans_commit */
3607std_return: 3434std_return:
3608 if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), 3435 if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) {
3609 DM_EVENT_POSTSYMLINK)) {
3610 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, 3436 (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK,
3611 dir_vp, DM_RIGHT_NULL, 3437 dir_vp, DM_RIGHT_NULL,
3612 error ? NULL : XFS_ITOV(ip), 3438 error ? NULL : XFS_ITOV(ip),
@@ -3633,9 +3459,8 @@ std_return:
3633 XFS_QM_DQRELE(mp, udqp); 3459 XFS_QM_DQRELE(mp, udqp);
3634 XFS_QM_DQRELE(mp, gdqp); 3460 XFS_QM_DQRELE(mp, gdqp);
3635 3461
3636 if (!dp_joined_to_trans && (dp != NULL)) { 3462 if (unlock_dp_on_error)
3637 xfs_iunlock(dp, XFS_ILOCK_EXCL); 3463 xfs_iunlock(dp, XFS_ILOCK_EXCL);
3638 }
3639 3464
3640 goto std_return; 3465 goto std_return;
3641} 3466}
@@ -3647,20 +3472,16 @@ std_return:
3647 * A fid routine that takes a pointer to a previously allocated 3472 * A fid routine that takes a pointer to a previously allocated
3648 * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. 3473 * fid structure (like xfs_fast_fid) but uses a 64 bit inode number.
3649 */ 3474 */
3650STATIC int 3475int
3651xfs_fid2( 3476xfs_fid2(
3652 bhv_desc_t *bdp, 3477 xfs_inode_t *ip,
3653 fid_t *fidp) 3478 fid_t *fidp)
3654{ 3479{
3655 xfs_inode_t *ip; 3480 xfs_fid2_t *xfid = (xfs_fid2_t *)fidp;
3656 xfs_fid2_t *xfid;
3657 3481
3658 vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, 3482 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
3659 (inst_t *)__return_address);
3660 ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); 3483 ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t));
3661 3484
3662 xfid = (xfs_fid2_t *)fidp;
3663 ip = XFS_BHVTOI(bdp);
3664 xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); 3485 xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len);
3665 xfid->fid_pad = 0; 3486 xfid->fid_pad = 0;
3666 /* 3487 /*
@@ -3674,21 +3495,13 @@ xfs_fid2(
3674} 3495}
3675 3496
3676 3497
3677/*
3678 * xfs_rwlock
3679 */
3680int 3498int
3681xfs_rwlock( 3499xfs_rwlock(
3682 bhv_desc_t *bdp, 3500 xfs_inode_t *ip,
3683 bhv_vrwlock_t locktype) 3501 bhv_vrwlock_t locktype)
3684{ 3502{
3685 xfs_inode_t *ip; 3503 if (S_ISDIR(ip->i_d.di_mode))
3686 bhv_vnode_t *vp;
3687
3688 vp = BHV_TO_VNODE(bdp);
3689 if (VN_ISDIR(vp))
3690 return 1; 3504 return 1;
3691 ip = XFS_BHVTOI(bdp);
3692 if (locktype == VRWLOCK_WRITE) { 3505 if (locktype == VRWLOCK_WRITE) {
3693 xfs_ilock(ip, XFS_IOLOCK_EXCL); 3506 xfs_ilock(ip, XFS_IOLOCK_EXCL);
3694 } else if (locktype == VRWLOCK_TRY_READ) { 3507 } else if (locktype == VRWLOCK_TRY_READ) {
@@ -3705,21 +3518,13 @@ xfs_rwlock(
3705} 3518}
3706 3519
3707 3520
3708/*
3709 * xfs_rwunlock
3710 */
3711void 3521void
3712xfs_rwunlock( 3522xfs_rwunlock(
3713 bhv_desc_t *bdp, 3523 xfs_inode_t *ip,
3714 bhv_vrwlock_t locktype) 3524 bhv_vrwlock_t locktype)
3715{ 3525{
3716 xfs_inode_t *ip; 3526 if (S_ISDIR(ip->i_d.di_mode))
3717 bhv_vnode_t *vp; 3527 return;
3718
3719 vp = BHV_TO_VNODE(bdp);
3720 if (VN_ISDIR(vp))
3721 return;
3722 ip = XFS_BHVTOI(bdp);
3723 if (locktype == VRWLOCK_WRITE) { 3528 if (locktype == VRWLOCK_WRITE) {
3724 /* 3529 /*
3725 * In the write case, we may have added a new entry to 3530 * In the write case, we may have added a new entry to
@@ -3737,20 +3542,16 @@ xfs_rwunlock(
3737 return; 3542 return;
3738} 3543}
3739 3544
3740STATIC int 3545
3546int
3741xfs_inode_flush( 3547xfs_inode_flush(
3742 bhv_desc_t *bdp, 3548 xfs_inode_t *ip,
3743 int flags) 3549 int flags)
3744{ 3550{
3745 xfs_inode_t *ip; 3551 xfs_mount_t *mp = ip->i_mount;
3746 xfs_mount_t *mp; 3552 xfs_inode_log_item_t *iip = ip->i_itemp;
3747 xfs_inode_log_item_t *iip;
3748 int error = 0; 3553 int error = 0;
3749 3554
3750 ip = XFS_BHVTOI(bdp);
3751 mp = ip->i_mount;
3752 iip = ip->i_itemp;
3753
3754 if (XFS_FORCED_SHUTDOWN(mp)) 3555 if (XFS_FORCED_SHUTDOWN(mp))
3755 return XFS_ERROR(EIO); 3556 return XFS_ERROR(EIO);
3756 3557
@@ -3819,24 +3620,20 @@ xfs_inode_flush(
3819 return error; 3620 return error;
3820} 3621}
3821 3622
3623
3822int 3624int
3823xfs_set_dmattrs ( 3625xfs_set_dmattrs(
3824 bhv_desc_t *bdp, 3626 xfs_inode_t *ip,
3825 u_int evmask, 3627 u_int evmask,
3826 u_int16_t state, 3628 u_int16_t state)
3827 cred_t *credp)
3828{ 3629{
3829 xfs_inode_t *ip; 3630 xfs_mount_t *mp = ip->i_mount;
3830 xfs_trans_t *tp; 3631 xfs_trans_t *tp;
3831 xfs_mount_t *mp;
3832 int error; 3632 int error;
3833 3633
3834 if (!capable(CAP_SYS_ADMIN)) 3634 if (!capable(CAP_SYS_ADMIN))
3835 return XFS_ERROR(EPERM); 3635 return XFS_ERROR(EPERM);
3836 3636
3837 ip = XFS_BHVTOI(bdp);
3838 mp = ip->i_mount;
3839
3840 if (XFS_FORCED_SHUTDOWN(mp)) 3637 if (XFS_FORCED_SHUTDOWN(mp))
3841 return XFS_ERROR(EIO); 3638 return XFS_ERROR(EIO);
3842 3639
@@ -3859,17 +3656,13 @@ xfs_set_dmattrs (
3859 return error; 3656 return error;
3860} 3657}
3861 3658
3862STATIC int 3659int
3863xfs_reclaim( 3660xfs_reclaim(
3864 bhv_desc_t *bdp) 3661 xfs_inode_t *ip)
3865{ 3662{
3866 xfs_inode_t *ip; 3663 bhv_vnode_t *vp = XFS_ITOV(ip);
3867 bhv_vnode_t *vp;
3868
3869 vp = BHV_TO_VNODE(bdp);
3870 ip = XFS_BHVTOI(bdp);
3871 3664
3872 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 3665 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
3873 3666
3874 ASSERT(!VN_MAPPED(vp)); 3667 ASSERT(!VN_MAPPED(vp));
3875 3668
@@ -3879,7 +3672,7 @@ xfs_reclaim(
3879 return 0; 3672 return 0;
3880 } 3673 }
3881 3674
3882 vn_iowait(vp); 3675 vn_iowait(ip);
3883 3676
3884 ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); 3677 ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
3885 3678
@@ -3911,7 +3704,8 @@ xfs_reclaim(
3911 XFS_MOUNT_ILOCK(mp); 3704 XFS_MOUNT_ILOCK(mp);
3912 spin_lock(&ip->i_flags_lock); 3705 spin_lock(&ip->i_flags_lock);
3913 __xfs_iflags_set(ip, XFS_IRECLAIMABLE); 3706 __xfs_iflags_set(ip, XFS_IRECLAIMABLE);
3914 vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); 3707 vn_to_inode(vp)->i_private = NULL;
3708 ip->i_vnode = NULL;
3915 spin_unlock(&ip->i_flags_lock); 3709 spin_unlock(&ip->i_flags_lock);
3916 list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); 3710 list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
3917 XFS_MOUNT_IUNLOCK(mp); 3711 XFS_MOUNT_IUNLOCK(mp);
@@ -3925,7 +3719,7 @@ xfs_finish_reclaim(
3925 int locked, 3719 int locked,
3926 int sync_mode) 3720 int sync_mode)
3927{ 3721{
3928 xfs_ihash_t *ih = ip->i_hash; 3722 xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino);
3929 bhv_vnode_t *vp = XFS_ITOV_NULL(ip); 3723 bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
3930 int error; 3724 int error;
3931 3725
@@ -3937,12 +3731,12 @@ xfs_finish_reclaim(
3937 * Once we have the XFS_IRECLAIM flag set it will not touch 3731 * Once we have the XFS_IRECLAIM flag set it will not touch
3938 * us. 3732 * us.
3939 */ 3733 */
3940 write_lock(&ih->ih_lock); 3734 write_lock(&pag->pag_ici_lock);
3941 spin_lock(&ip->i_flags_lock); 3735 spin_lock(&ip->i_flags_lock);
3942 if (__xfs_iflags_test(ip, XFS_IRECLAIM) || 3736 if (__xfs_iflags_test(ip, XFS_IRECLAIM) ||
3943 (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) { 3737 (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) {
3944 spin_unlock(&ip->i_flags_lock); 3738 spin_unlock(&ip->i_flags_lock);
3945 write_unlock(&ih->ih_lock); 3739 write_unlock(&pag->pag_ici_lock);
3946 if (locked) { 3740 if (locked) {
3947 xfs_ifunlock(ip); 3741 xfs_ifunlock(ip);
3948 xfs_iunlock(ip, XFS_ILOCK_EXCL); 3742 xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -3951,7 +3745,8 @@ xfs_finish_reclaim(
3951 } 3745 }
3952 __xfs_iflags_set(ip, XFS_IRECLAIM); 3746 __xfs_iflags_set(ip, XFS_IRECLAIM);
3953 spin_unlock(&ip->i_flags_lock); 3747 spin_unlock(&ip->i_flags_lock);
3954 write_unlock(&ih->ih_lock); 3748 write_unlock(&pag->pag_ici_lock);
3749 xfs_put_perag(ip->i_mount, pag);
3955 3750
3956 /* 3751 /*
3957 * If the inode is still dirty, then flush it out. If the inode 3752 * If the inode is still dirty, then flush it out. If the inode
@@ -4085,7 +3880,7 @@ xfs_alloc_file_space(
4085 int committed; 3880 int committed;
4086 int error; 3881 int error;
4087 3882
4088 vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); 3883 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
4089 3884
4090 if (XFS_FORCED_SHUTDOWN(mp)) 3885 if (XFS_FORCED_SHUTDOWN(mp))
4091 return XFS_ERROR(EIO); 3886 return XFS_ERROR(EIO);
@@ -4109,7 +3904,7 @@ xfs_alloc_file_space(
4109 /* Generate a DMAPI event if needed. */ 3904 /* Generate a DMAPI event if needed. */
4110 if (alloc_type != 0 && offset < ip->i_size && 3905 if (alloc_type != 0 && offset < ip->i_size &&
4111 (attr_flags&ATTR_DMI) == 0 && 3906 (attr_flags&ATTR_DMI) == 0 &&
4112 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { 3907 DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
4113 xfs_off_t end_dmi_offset; 3908 xfs_off_t end_dmi_offset;
4114 3909
4115 end_dmi_offset = offset+len; 3910 end_dmi_offset = offset+len;
@@ -4223,9 +4018,8 @@ retry:
4223 allocatesize_fsb -= allocated_fsb; 4018 allocatesize_fsb -= allocated_fsb;
4224 } 4019 }
4225dmapi_enospc_check: 4020dmapi_enospc_check:
4226 if (error == ENOSPC && (attr_flags&ATTR_DMI) == 0 && 4021 if (error == ENOSPC && (attr_flags & ATTR_DMI) == 0 &&
4227 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) { 4022 DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) {
4228
4229 error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE, 4023 error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
4230 XFS_ITOV(ip), DM_RIGHT_NULL, 4024 XFS_ITOV(ip), DM_RIGHT_NULL,
4231 XFS_ITOV(ip), DM_RIGHT_NULL, 4025 XFS_ITOV(ip), DM_RIGHT_NULL,
@@ -4356,7 +4150,7 @@ xfs_free_file_space(
4356 vp = XFS_ITOV(ip); 4150 vp = XFS_ITOV(ip);
4357 mp = ip->i_mount; 4151 mp = ip->i_mount;
4358 4152
4359 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 4153 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
4360 4154
4361 if ((error = XFS_QM_DQATTACH(mp, ip, 0))) 4155 if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
4362 return error; 4156 return error;
@@ -4369,9 +4163,8 @@ xfs_free_file_space(
4369 end_dmi_offset = offset + len; 4163 end_dmi_offset = offset + len;
4370 endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); 4164 endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
4371 4165
4372 if (offset < ip->i_size && 4166 if (offset < ip->i_size && (attr_flags & ATTR_DMI) == 0 &&
4373 (attr_flags & ATTR_DMI) == 0 && 4167 DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
4374 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
4375 if (end_dmi_offset > ip->i_size) 4168 if (end_dmi_offset > ip->i_size)
4376 end_dmi_offset = ip->i_size; 4169 end_dmi_offset = ip->i_size;
4377 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, 4170 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
@@ -4385,7 +4178,7 @@ xfs_free_file_space(
4385 need_iolock = 0; 4178 need_iolock = 0;
4386 if (need_iolock) { 4179 if (need_iolock) {
4387 xfs_ilock(ip, XFS_IOLOCK_EXCL); 4180 xfs_ilock(ip, XFS_IOLOCK_EXCL);
4388 vn_iowait(vp); /* wait for the completion of any pending DIOs */ 4181 vn_iowait(ip); /* wait for the completion of any pending DIOs */
4389 } 4182 }
4390 4183
4391 rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); 4184 rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
@@ -4394,7 +4187,8 @@ xfs_free_file_space(
4394 if (VN_CACHED(vp) != 0) { 4187 if (VN_CACHED(vp) != 0) {
4395 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, 4188 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
4396 ctooff(offtoct(ioffset)), -1); 4189 ctooff(offtoct(ioffset)), -1);
4397 error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)), 4190 error = xfs_flushinval_pages(ip,
4191 ctooff(offtoct(ioffset)),
4398 -1, FI_REMAPF_LOCKED); 4192 -1, FI_REMAPF_LOCKED);
4399 if (error) 4193 if (error)
4400 goto out_unlock_iolock; 4194 goto out_unlock_iolock;
@@ -4545,35 +4339,29 @@ xfs_free_file_space(
4545 */ 4339 */
4546int 4340int
4547xfs_change_file_space( 4341xfs_change_file_space(
4548 bhv_desc_t *bdp, 4342 xfs_inode_t *ip,
4549 int cmd, 4343 int cmd,
4550 xfs_flock64_t *bf, 4344 xfs_flock64_t *bf,
4551 xfs_off_t offset, 4345 xfs_off_t offset,
4552 cred_t *credp, 4346 cred_t *credp,
4553 int attr_flags) 4347 int attr_flags)
4554{ 4348{
4349 xfs_mount_t *mp = ip->i_mount;
4555 int clrprealloc; 4350 int clrprealloc;
4556 int error; 4351 int error;
4557 xfs_fsize_t fsize; 4352 xfs_fsize_t fsize;
4558 xfs_inode_t *ip;
4559 xfs_mount_t *mp;
4560 int setprealloc; 4353 int setprealloc;
4561 xfs_off_t startoffset; 4354 xfs_off_t startoffset;
4562 xfs_off_t llen; 4355 xfs_off_t llen;
4563 xfs_trans_t *tp; 4356 xfs_trans_t *tp;
4564 bhv_vattr_t va; 4357 bhv_vattr_t va;
4565 bhv_vnode_t *vp;
4566 4358
4567 vp = BHV_TO_VNODE(bdp); 4359 vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
4568 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
4569
4570 ip = XFS_BHVTOI(bdp);
4571 mp = ip->i_mount;
4572 4360
4573 /* 4361 /*
4574 * must be a regular file and have write permission 4362 * must be a regular file and have write permission
4575 */ 4363 */
4576 if (!VN_ISREG(vp)) 4364 if (!S_ISREG(ip->i_d.di_mode))
4577 return XFS_ERROR(EINVAL); 4365 return XFS_ERROR(EINVAL);
4578 4366
4579 xfs_ilock(ip, XFS_ILOCK_SHARED); 4367 xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -4655,7 +4443,7 @@ xfs_change_file_space(
4655 va.va_mask = XFS_AT_SIZE; 4443 va.va_mask = XFS_AT_SIZE;
4656 va.va_size = startoffset; 4444 va.va_size = startoffset;
4657 4445
4658 error = xfs_setattr(bdp, &va, attr_flags, credp); 4446 error = xfs_setattr(ip, &va, attr_flags, credp);
4659 4447
4660 if (error) 4448 if (error)
4661 return error; 4449 return error;
@@ -4714,46 +4502,3 @@ xfs_change_file_space(
4714 4502
4715 return error; 4503 return error;
4716} 4504}
4717
4718bhv_vnodeops_t xfs_vnodeops = {
4719 BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS),
4720 .vop_open = xfs_open,
4721 .vop_read = xfs_read,
4722#ifdef HAVE_SPLICE
4723 .vop_splice_read = xfs_splice_read,
4724 .vop_splice_write = xfs_splice_write,
4725#endif
4726 .vop_write = xfs_write,
4727 .vop_ioctl = xfs_ioctl,
4728 .vop_getattr = xfs_getattr,
4729 .vop_setattr = xfs_setattr,
4730 .vop_access = xfs_access,
4731 .vop_lookup = xfs_lookup,
4732 .vop_create = xfs_create,
4733 .vop_remove = xfs_remove,
4734 .vop_link = xfs_link,
4735 .vop_rename = xfs_rename,
4736 .vop_mkdir = xfs_mkdir,
4737 .vop_rmdir = xfs_rmdir,
4738 .vop_readdir = xfs_readdir,
4739 .vop_symlink = xfs_symlink,
4740 .vop_readlink = xfs_readlink,
4741 .vop_fsync = xfs_fsync,
4742 .vop_inactive = xfs_inactive,
4743 .vop_fid2 = xfs_fid2,
4744 .vop_rwlock = xfs_rwlock,
4745 .vop_rwunlock = xfs_rwunlock,
4746 .vop_bmap = xfs_bmap,
4747 .vop_reclaim = xfs_reclaim,
4748 .vop_attr_get = xfs_attr_get,
4749 .vop_attr_set = xfs_attr_set,
4750 .vop_attr_remove = xfs_attr_remove,
4751 .vop_attr_list = xfs_attr_list,
4752 .vop_link_removed = (vop_link_removed_t)fs_noval,
4753 .vop_vnode_change = (vop_vnode_change_t)fs_noval,
4754 .vop_tosspages = fs_tosspages,
4755 .vop_flushinval_pages = fs_flushinval_pages,
4756 .vop_flush_pages = fs_flush_pages,
4757 .vop_release = xfs_release,
4758 .vop_iflush = xfs_inode_flush,
4759};
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
new file mode 100644
index 000000000000..f36e74f2f0c2
--- /dev/null
+++ b/fs/xfs/xfs_vnodeops.h
@@ -0,0 +1,86 @@
1#ifndef _XFS_VNODEOPS_H
2#define _XFS_VNODEOPS_H 1
3
4struct attrlist_cursor_kern;
5struct bhv_vattr;
6struct cred;
7struct file;
8struct inode;
9struct iovec;
10struct kiocb;
11struct pipe_inode_info;
12struct uio;
13struct xfs_inode;
14struct xfs_iomap;
15
16
17int xfs_open(struct xfs_inode *ip);
18int xfs_getattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags);
19int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags,
20 struct cred *credp);
21int xfs_access(struct xfs_inode *ip, int mode, struct cred *credp);
22int xfs_readlink(struct xfs_inode *ip, char *link);
23int xfs_fsync(struct xfs_inode *ip, int flag, xfs_off_t start,
24 xfs_off_t stop);
25int xfs_release(struct xfs_inode *ip);
26int xfs_inactive(struct xfs_inode *ip);
27int xfs_lookup(struct xfs_inode *dp, bhv_vname_t *dentry,
28 bhv_vnode_t **vpp);
29int xfs_create(struct xfs_inode *dp, bhv_vname_t *dentry, mode_t mode,
30 xfs_dev_t rdev, bhv_vnode_t **vpp, struct cred *credp);
31int xfs_remove(struct xfs_inode *dp, bhv_vname_t *dentry);
32int xfs_link(struct xfs_inode *tdp, bhv_vnode_t *src_vp,
33 bhv_vname_t *dentry);
34int xfs_mkdir(struct xfs_inode *dp, bhv_vname_t *dentry,
35 mode_t mode, bhv_vnode_t **vpp, struct cred *credp);
36int xfs_rmdir(struct xfs_inode *dp, bhv_vname_t *dentry);
37int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize,
38 xfs_off_t *offset, filldir_t filldir);
39int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry,
40 char *target_path, mode_t mode, bhv_vnode_t **vpp,
41 struct cred *credp);
42int xfs_fid2(struct xfs_inode *ip, fid_t *fidp);
43int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
44void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
45int xfs_inode_flush(struct xfs_inode *ip, int flags);
46int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
47int xfs_reclaim(struct xfs_inode *ip);
48int xfs_change_file_space(struct xfs_inode *ip, int cmd,
49 xfs_flock64_t *bf, xfs_off_t offset,
50 struct cred *credp, int attr_flags);
51int xfs_rename(struct xfs_inode *src_dp, bhv_vname_t *src_vname,
52 bhv_vnode_t *target_dir_vp, bhv_vname_t *target_vname);
53int xfs_attr_get(struct xfs_inode *ip, const char *name, char *value,
54 int *valuelenp, int flags, cred_t *cred);
55int xfs_attr_set(struct xfs_inode *dp, const char *name, char *value,
56 int valuelen, int flags);
57int xfs_attr_remove(struct xfs_inode *dp, const char *name, int flags);
58int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
59 int flags, struct attrlist_cursor_kern *cursor);
60int xfs_ioctl(struct xfs_inode *ip, struct file *filp,
61 int ioflags, unsigned int cmd, void __user *arg);
62ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb,
63 const struct iovec *iovp, unsigned int segs,
64 loff_t *offset, int ioflags);
65ssize_t xfs_sendfile(struct xfs_inode *ip, struct file *filp,
66 loff_t *offset, int ioflags, size_t count,
67 read_actor_t actor, void *target);
68ssize_t xfs_splice_read(struct xfs_inode *ip, struct file *infilp,
69 loff_t *ppos, struct pipe_inode_info *pipe, size_t count,
70 int flags, int ioflags);
71ssize_t xfs_splice_write(struct xfs_inode *ip,
72 struct pipe_inode_info *pipe, struct file *outfilp,
73 loff_t *ppos, size_t count, int flags, int ioflags);
74ssize_t xfs_write(struct xfs_inode *xip, struct kiocb *iocb,
75 const struct iovec *iovp, unsigned int nsegs,
76 loff_t *offset, int ioflags);
77int xfs_bmap(struct xfs_inode *ip, xfs_off_t offset, ssize_t count,
78 int flags, struct xfs_iomap *iomapp, int *niomaps);
79void xfs_tosspages(struct xfs_inode *inode, xfs_off_t first,
80 xfs_off_t last, int fiopt);
81int xfs_flushinval_pages(struct xfs_inode *ip, xfs_off_t first,
82 xfs_off_t last, int fiopt);
83int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first,
84 xfs_off_t last, uint64_t flags, int fiopt);
85
86#endif /* _XFS_VNODEOPS_H */