aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 12:04:11 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 12:04:11 -0400
commit347c53dca73fca317d57781f510f5ff4f6c0d0d7 (patch)
treecdc405ac049751da4d76085ce58750b6b2a22326 /fs/xfs/linux-2.6
parent5c8e191e8437616a498a8e1cc0af3dd0d32bbff2 (diff)
parent7f015072348a14f16d548be557ee58c5c55df0aa (diff)
Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6
* 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6: (59 commits) [XFS] eagerly remove vmap mappings to avoid upsetting Xen [XFS] simplify validata_fields [XFS] no longer using io_vnode, as was remaining from 23 cherrypick [XFS] Remove STATIC which was missing from prior manual merge [XFS] Put back the QUEUE_ORDERED_NONE test in the barrier check. [XFS] Turn off XBF_ASYNC flag before re-reading superblock. [XFS] avoid race in sync_inodes() that can fail to write out all dirty data [XFS] This fix prevents bulkstat from spinning in an infinite loop. [XFS] simplify xfs_create/mknod/symlink prototype [XFS] avoid xfs_getattr in XFS_IOC_FSGETXATTR ioctl [XFS] get_bulkall() could return incorrect inode state [XFS] Kill unused IOMAP_EOF flag [XFS] fix when DMAPI mount option processing happens [XFS] ensure file size is logged on synchronous writes [XFS] growlock should be a mutex [XFS] replace some large xfs_log_priv.h macros by proper functions [XFS] kill struct bhv_vfs [XFS] move syncing related members from struct bhv_vfs to struct xfs_mount [XFS] kill the vfs_flags member in struct bhv_vfs [XFS] kill the vfs_fsid and vfs_altfsid members in struct bhv_vfs ...
Diffstat (limited to 'fs/xfs/linux-2.6')
-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
22 files changed, 656 insertions, 1514 deletions
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__ */