diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-17 12:04:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-17 12:04:11 -0400 |
commit | 347c53dca73fca317d57781f510f5ff4f6c0d0d7 (patch) | |
tree | cdc405ac049751da4d76085ce58750b6b2a22326 /fs/xfs | |
parent | 5c8e191e8437616a498a8e1cc0af3dd0d32bbff2 (diff) | |
parent | 7f015072348a14f16d548be557ee58c5c55df0aa (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')
90 files changed, 2762 insertions, 4739 deletions
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 index e7a9a83f0087..d1491aa7a0e2 100644 --- a/fs/xfs/Makefile-linux-2.6 +++ b/fs/xfs/Makefile-linux-2.6 | |||
@@ -49,7 +49,6 @@ xfs-y += xfs_alloc.o \ | |||
49 | xfs_alloc_btree.o \ | 49 | xfs_alloc_btree.o \ |
50 | xfs_attr.o \ | 50 | xfs_attr.o \ |
51 | xfs_attr_leaf.o \ | 51 | xfs_attr_leaf.o \ |
52 | xfs_behavior.o \ | ||
53 | xfs_bit.o \ | 52 | xfs_bit.o \ |
54 | xfs_bmap.o \ | 53 | xfs_bmap.o \ |
55 | xfs_bmap_btree.o \ | 54 | xfs_bmap_btree.o \ |
@@ -108,13 +107,11 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \ | |||
108 | xfs_iops.o \ | 107 | xfs_iops.o \ |
109 | xfs_lrw.o \ | 108 | xfs_lrw.o \ |
110 | xfs_super.o \ | 109 | xfs_super.o \ |
111 | xfs_vfs.o \ | ||
112 | xfs_vnode.o) | 110 | xfs_vnode.o) |
113 | 111 | ||
114 | # Objects in support/ | 112 | # Objects in support/ |
115 | xfs-y += $(addprefix support/, \ | 113 | xfs-y += $(addprefix support/, \ |
116 | debug.o \ | 114 | debug.o \ |
117 | move.o \ | ||
118 | uuid.o) | 115 | uuid.o) |
119 | 116 | ||
120 | xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o | 117 | xfs-$(CONFIG_XFS_TRACE) += support/ktrace.o |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 52bd08c0a278..2e34b104107c 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "xfs_error.h" | 37 | #include "xfs_error.h" |
38 | #include "xfs_rw.h" | 38 | #include "xfs_rw.h" |
39 | #include "xfs_iomap.h" | 39 | #include "xfs_iomap.h" |
40 | #include "xfs_vnodeops.h" | ||
40 | #include <linux/mpage.h> | 41 | #include <linux/mpage.h> |
41 | #include <linux/pagevec.h> | 42 | #include <linux/pagevec.h> |
42 | #include <linux/writeback.h> | 43 | #include <linux/writeback.h> |
@@ -139,9 +140,11 @@ xfs_destroy_ioend( | |||
139 | next = bh->b_private; | 140 | next = bh->b_private; |
140 | bh->b_end_io(bh, !ioend->io_error); | 141 | bh->b_end_io(bh, !ioend->io_error); |
141 | } | 142 | } |
142 | if (unlikely(ioend->io_error)) | 143 | if (unlikely(ioend->io_error)) { |
143 | vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__); | 144 | vn_ioerror(XFS_I(ioend->io_inode), ioend->io_error, |
144 | vn_iowake(ioend->io_vnode); | 145 | __FILE__,__LINE__); |
146 | } | ||
147 | vn_iowake(XFS_I(ioend->io_inode)); | ||
145 | mempool_free(ioend, xfs_ioend_pool); | 148 | mempool_free(ioend, xfs_ioend_pool); |
146 | } | 149 | } |
147 | 150 | ||
@@ -156,14 +159,10 @@ STATIC void | |||
156 | xfs_setfilesize( | 159 | xfs_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 | ||
27 | static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, }; | 33 | static 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 | ||
67 | STATIC ssize_t | 67 | STATIC 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 | ||
106 | STATIC ssize_t | 104 | STATIC 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 | ||
138 | STATIC ssize_t | 136 | STATIC 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 | ||
151 | STATIC ssize_t | 148 | STATIC 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 | ||
163 | STATIC ssize_t | 160 | STATIC 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 | ||
176 | STATIC int | 172 | STATIC 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 | ||
186 | STATIC int | 182 | STATIC 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 | ||
198 | STATIC int | 190 | STATIC 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 | } | ||
294 | done: | ||
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 | ||
306 | STATIC int | 253 | STATIC 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 | |||
397 | xfs_file_open_exec( | 340 | xfs_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 | ||
20 | int fs_noerr(void) { return 0; } | 34 | int fs_noerr(void) { return 0; } |
21 | int fs_nosys(void) { return ENOSYS; } | 35 | int fs_nosys(void) { return ENOSYS; } |
22 | void fs_noval(void) { return; } | 36 | void fs_noval(void) { return; } |
23 | 37 | ||
24 | void | 38 | void |
25 | fs_tosspages( | 39 | xfs_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 | ||
38 | int | 52 | int |
39 | fs_flushinval_pages( | 53 | xfs_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 | ||
59 | int | 72 | int |
60 | fs_flush_pages( | 73 | xfs_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 | ||
21 | struct cred; | ||
22 | extern int fs_noerr(void); | 21 | extern int fs_noerr(void); |
23 | extern int fs_nosys(void); | 22 | extern int fs_nosys(void); |
24 | extern void fs_noval(void); | 23 | extern void fs_noval(void); |
25 | extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int); | ||
26 | extern int fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int); | ||
27 | extern 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 | */ | ||
25 | unsigned 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 | ||
21 | extern uint64_t xfs_panic_mask; /* set to cause more panics */ | 21 | extern uint64_t xfs_panic_mask; /* set to cause more panics */ |
22 | extern unsigned long xfs_physmem; | ||
23 | extern struct cred *sys_cred; | 22 | extern 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 | */ | ||
358 | STATIC int | ||
359 | do_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 | |||
352 | STATIC int | 380 | STATIC int |
353 | xfs_readlink_by_handle( | 381 | xfs_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 | ||
402 | STATIC int | 431 | STATIC 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 | ||
489 | STATIC int | 517 | STATIC int |
490 | xfs_attrmulti_attr_get( | 518 | xfs_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 | ||
518 | STATIC int | 546 | STATIC int |
519 | xfs_attrmulti_attr_set( | 547 | xfs_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 | ||
550 | STATIC int | 578 | STATIC int |
551 | xfs_attrmulti_attr_remove( | 579 | xfs_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 | ||
563 | STATIC int | 591 | STATIC 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 | ||
650 | STATIC int | 678 | STATIC int |
651 | xfs_ioc_space( | 679 | xfs_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 | ||
683 | STATIC int | 711 | STATIC int |
712 | xfs_ioc_fsgetxattr( | ||
713 | xfs_inode_t *ip, | ||
714 | int attr, | ||
715 | void __user *arg); | ||
716 | |||
717 | STATIC int | ||
684 | xfs_ioc_getbmap( | 718 | xfs_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 | ||
690 | STATIC int | 724 | STATIC int |
691 | xfs_ioc_getbmapx( | 725 | xfs_ioc_getbmapx( |
692 | bhv_desc_t *bdp, | 726 | struct xfs_inode *ip, |
693 | void __user *arg); | 727 | void __user *arg); |
694 | 728 | ||
695 | int | 729 | int |
696 | xfs_ioctl( | 730 | xfs_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 | ||
955 | STATIC int | 985 | STATIC int |
956 | xfs_ioc_space( | 986 | xfs_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 | ||
1142 | STATIC int | 1172 | STATIC int |
1173 | xfs_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 | |||
1208 | STATIC int | ||
1143 | xfs_ioc_xattr( | 1209 | xfs_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 | ||
1269 | STATIC int | 1293 | STATIC int |
1270 | xfs_ioc_getbmap( | 1294 | xfs_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 | ||
1299 | STATIC int | 1323 | STATIC int |
1300 | xfs_ioc_getbmapx( | 1324 | xfs_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 | */ | ||
58 | xfs_inode_t * | ||
59 | xfs_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 | */ |
196 | STATIC void | 180 | STATIC void |
197 | xfs_validate_fields( | 181 | xfs_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 | ||
257 | STATIC void | 243 | STATIC void |
258 | xfs_cleanup_inode( | 244 | xfs_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 | ||
591 | STATIC void | 533 | STATIC 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; | |||
26 | extern const struct file_operations xfs_dir_file_operations; | 26 | extern const struct file_operations xfs_dir_file_operations; |
27 | extern const struct file_operations xfs_invis_file_operations; | 27 | extern const struct file_operations xfs_invis_file_operations; |
28 | 28 | ||
29 | extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *, | ||
30 | int, unsigned int, void __user *); | ||
31 | 29 | ||
32 | struct xfs_inode; | 30 | struct xfs_inode; |
33 | extern void xfs_ichgtime(struct xfs_inode *, int); | 31 | extern void xfs_ichgtime(struct xfs_inode *, int); |
34 | extern void xfs_ichgtime_fast(struct xfs_inode *, struct inode *, int); | 32 | extern 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 | ||
170 | ssize_t /* bytes read, or (-) error */ | 171 | ssize_t /* bytes read, or (-) error */ |
171 | xfs_read( | 172 | xfs_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 | ||
278 | ssize_t | 273 | ssize_t |
279 | xfs_splice_read( | 274 | xfs_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 | ||
322 | ssize_t | 314 | ssize_t |
323 | xfs_splice_write( | 315 | xfs_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 | ||
584 | ssize_t /* bytes written, or (-) error */ | 573 | ssize_t /* bytes written, or (-) error */ |
585 | xfs_write( | 574 | xfs_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 | ||
916 | int | 898 | int |
917 | xfs_bmap(bhv_desc_t *bdp, | 899 | xfs_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 | ||
21 | struct bhv_desc; | ||
22 | struct bhv_vnode; | ||
23 | struct xfs_mount; | 21 | struct xfs_mount; |
24 | struct xfs_iocore; | 22 | struct xfs_iocore; |
25 | struct xfs_inode; | 23 | struct 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 | |||
79 | extern int xfs_bmap(struct bhv_desc *, xfs_off_t, ssize_t, int, | ||
80 | struct xfs_iomap *, int *); | ||
81 | extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *); | 72 | extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *); |
82 | extern int xfs_bdstrat_cb(struct xfs_buf *); | 73 | extern int xfs_bdstrat_cb(struct xfs_buf *); |
83 | extern int xfs_dev_is_read_only(struct xfs_mount *, char *); | 74 | extern int xfs_dev_is_read_only(struct xfs_mount *, char *); |
84 | 75 | ||
85 | extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t, | 76 | extern int xfs_zero_eof(struct inode *, struct xfs_iocore *, xfs_off_t, |
86 | xfs_fsize_t); | 77 | xfs_fsize_t); |
87 | extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, | ||
88 | const struct iovec *, unsigned int, | ||
89 | loff_t *, int, struct cred *); | ||
90 | extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *, | ||
91 | const struct iovec *, unsigned int, | ||
92 | loff_t *, int, struct cred *); | ||
93 | extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *, loff_t *, | ||
94 | struct pipe_inode_info *, size_t, int, int, | ||
95 | struct cred *); | ||
96 | extern 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 | ||
202 | void | 204 | void |
203 | xfs_initialize_vnode( | 205 | xfs_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 | |||
429 | xfs_fs_clear_inode( | 431 | xfs_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 | */ |
470 | STATIC void | 464 | STATIC void |
471 | xfs_syncd_queue_work( | 465 | xfs_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 | */ |
495 | STATIC void | 489 | STATIC void |
496 | xfs_flush_inode_work( | 490 | xfs_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 | ||
504 | void | 499 | void |
505 | xfs_flush_inode( | 500 | xfs_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 | */ |
520 | STATIC void | 514 | STATIC void |
521 | xfs_flush_device_work( | 515 | xfs_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 | ||
529 | void | 524 | void |
@@ -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 | ||
542 | STATIC void | 536 | STATIC void |
543 | vfs_sync_worker( | 537 | xfs_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 | ||
557 | STATIC int | 550 | STATIC int |
558 | xfssyncd( | 551 | xfssyncd( |
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 | ||
605 | STATIC int | ||
606 | xfs_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 | |||
617 | STATIC void | ||
618 | xfs_fs_stop_syncd( | ||
619 | bhv_vfs_t *vfsp) | ||
620 | { | ||
621 | kthread_stop(vfsp->vfs_sync_task); | ||
622 | } | ||
623 | |||
624 | STATIC void | 598 | STATIC void |
625 | xfs_fs_put_super( | 599 | xfs_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 | ||
642 | STATIC void | 613 | STATIC 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 | |||
725 | xfs_fs_lockfs( | 708 | xfs_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 | ||
731 | STATIC int | 714 | STATIC 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 | ||
739 | STATIC int | 722 | STATIC 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 | ||
747 | STATIC int | 730 | STATIC 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 | ||
755 | STATIC int | 738 | STATIC 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 | ||
764 | STATIC int | 747 | STATIC 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 | ||
861 | fail_unmount: | 858 | fail_unmount: |
862 | bhv_vfs_unmount(vfsp, 0, NULL); | 859 | xfs_unmount(mp, 0, NULL); |
863 | 860 | ||
864 | fail_vfsop: | 861 | fail_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 | |||
914 | init_xfs_fs( void ) | 910 | init_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 | ||
108 | extern __uint64_t xfs_max_file_offset(unsigned int); | 108 | extern __uint64_t xfs_max_file_offset(unsigned int); |
109 | 109 | ||
110 | extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int); | 110 | extern void xfs_initialize_vnode(struct xfs_mount *mp, bhv_vnode_t *vp, |
111 | struct xfs_inode *ip); | ||
111 | 112 | ||
112 | extern void xfs_flush_inode(struct xfs_inode *); | 113 | extern void xfs_flush_inode(struct xfs_inode *); |
113 | extern void xfs_flush_device(struct xfs_inode *); | 114 | extern void xfs_flush_device(struct xfs_inode *); |
@@ -119,4 +120,6 @@ extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); | |||
119 | 120 | ||
120 | extern struct export_operations xfs_export_operations; | 121 | extern 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 | |||
33 | int | ||
34 | vfs_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 | |||
47 | int | ||
48 | vfs_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 | |||
62 | int | ||
63 | vfs_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 | |||
75 | int | ||
76 | vfs_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 | |||
89 | int | ||
90 | vfs_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 | |||
103 | int | ||
104 | vfs_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 | |||
116 | int | ||
117 | vfs_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 | |||
130 | int | ||
131 | vfs_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 | |||
144 | int | ||
145 | vfs_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 | |||
158 | int | ||
159 | vfs_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 | |||
171 | int | ||
172 | vfs_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 | |||
186 | void | ||
187 | vfs_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 | |||
201 | void | ||
202 | vfs_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 | |||
216 | void | ||
217 | vfs_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 | |||
228 | bhv_vfs_t * | ||
229 | vfs_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 | |||
249 | bhv_vfs_t * | ||
250 | vfs_from_sb( | ||
251 | struct super_block *sb) | ||
252 | { | ||
253 | return (bhv_vfs_t *)sb->s_fs_info; | ||
254 | } | ||
255 | |||
256 | void | ||
257 | vfs_deallocate( | ||
258 | struct bhv_vfs *vfsp) | ||
259 | { | ||
260 | bhv_head_destroy(VFS_BHVHEAD(vfsp)); | ||
261 | kmem_free(vfsp, sizeof(bhv_vfs_t)); | ||
262 | } | ||
263 | |||
264 | void | ||
265 | vfs_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 | |||
276 | void | ||
277 | vfs_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 | |||
287 | void | ||
288 | bhv_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 | |||
301 | void | ||
302 | bhv_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 | |||
317 | void | ||
318 | bhv_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 | ||
24 | struct bhv_vfs; | 24 | struct inode; |
25 | struct bhv_vnode; | ||
26 | 25 | ||
27 | struct fid; | 26 | struct fid; |
28 | struct cred; | 27 | struct cred; |
29 | struct seq_file; | 28 | struct seq_file; |
30 | struct super_block; | 29 | struct super_block; |
30 | struct xfs_inode; | ||
31 | struct xfs_mount; | ||
31 | struct xfs_mount_args; | 32 | struct xfs_mount_args; |
32 | 33 | ||
33 | typedef struct kstatfs bhv_statvfs_t; | 34 | typedef struct kstatfs bhv_statvfs_t; |
34 | 35 | ||
35 | typedef struct bhv_vfs_sync_work { | 36 | typedef 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 | ||
42 | typedef 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 | |||
65 | typedef 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 | ||
118 | typedef 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)) |
120 | typedef int (*vfs_parseargs_t)(bhv_desc_t *, char *, | ||
121 | struct xfs_mount_args *, int); | ||
122 | typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *); | ||
123 | typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *); | ||
124 | typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *, | ||
125 | struct xfs_mount_args *); | ||
126 | typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **); | ||
127 | typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *, | ||
128 | struct bhv_vnode *); | ||
129 | typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); | ||
130 | typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *); | ||
131 | typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t); | ||
132 | typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); | ||
133 | typedef void (*vfs_init_vnode_t)(bhv_desc_t *, | ||
134 | struct bhv_vnode *, bhv_desc_t *, int); | ||
135 | typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); | ||
136 | typedef void (*vfs_freeze_t)(bhv_desc_t *); | ||
137 | |||
138 | typedef 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 | |||
193 | extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *); | ||
194 | extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int); | ||
195 | extern int vfs_showargs(bhv_desc_t *, struct seq_file *); | ||
196 | extern int vfs_unmount(bhv_desc_t *, int, struct cred *); | ||
197 | extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *); | ||
198 | extern int vfs_root(bhv_desc_t *, struct bhv_vnode **); | ||
199 | extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *); | ||
200 | extern int vfs_sync(bhv_desc_t *, int, struct cred *); | ||
201 | extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *); | ||
202 | extern int vfs_dmapiops(bhv_desc_t *, caddr_t); | ||
203 | extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); | ||
204 | extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int); | ||
205 | extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); | ||
206 | extern 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 | |||
211 | typedef 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 | |||
221 | extern bhv_vfs_t *vfs_allocate(struct super_block *); | ||
222 | extern bhv_vfs_t *vfs_from_sb(struct super_block *); | ||
223 | extern void vfs_deallocate(bhv_vfs_t *); | ||
224 | extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *); | ||
225 | |||
226 | extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *); | ||
227 | |||
228 | extern void bhv_insert_all_vfsops(struct bhv_vfs *); | ||
229 | extern void bhv_remove_all_vfsops(struct bhv_vfs *, int); | ||
230 | extern 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 | ||
20 | uint64_t vn_generation; /* vnode generation number */ | ||
21 | DEFINE_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 | ||
40 | void | 52 | void |
41 | vn_iowait( | 53 | vn_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 | ||
49 | void | 61 | void |
50 | vn_iowake( | 62 | vn_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 | */ |
62 | void | 74 | void |
63 | vn_ioerror( | 75 | vn_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 | ||
73 | bhv_vnode_t * | 85 | bhv_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 | */ | ||
188 | static 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 | */ |
209 | void | 213 | void |
210 | vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra) | 214 | vn_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 | ||
215 | void | 219 | void |
216 | vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra) | 220 | vn_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 | ||
221 | void | 225 | void |
222 | vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra) | 226 | vn_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 | ||
227 | void | 231 | void |
228 | vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra) | 232 | vn_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 | ||
233 | void | 237 | void |
234 | vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra) | 238 | vn_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 | ||
21 | struct uio; | ||
22 | struct file; | 21 | struct file; |
23 | struct bhv_vfs; | ||
24 | struct bhv_vattr; | 22 | struct bhv_vattr; |
25 | struct xfs_iomap; | 23 | struct xfs_iomap; |
26 | struct attrlist_cursor_kern; | 24 | struct attrlist_cursor_kern; |
27 | 25 | ||
28 | typedef struct dentry bhv_vname_t; | 26 | typedef struct dentry bhv_vname_t; |
29 | typedef __u64 bhv_vnumber_t; | 27 | typedef __u64 bhv_vnumber_t; |
28 | typedef struct inode bhv_vnode_t; | ||
30 | 29 | ||
31 | typedef 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 | */ | ||
41 | typedef 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 | |||
65 | typedef 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 | */ |
92 | static inline struct bhv_vnode *vn_from_inode(struct inode *inode) | 39 | static 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 | } |
96 | static inline struct inode *vn_to_inode(struct bhv_vnode *vnode) | 43 | static 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 | */ | ||
124 | typedef 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 | |||
132 | typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); | ||
133 | typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, | ||
134 | const struct iovec *, unsigned int, | ||
135 | loff_t *, int, struct cred *); | ||
136 | typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *, | ||
137 | const struct iovec *, unsigned int, | ||
138 | loff_t *, int, struct cred *); | ||
139 | typedef 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 *); | ||
142 | typedef 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 *); | ||
145 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, | ||
146 | int, unsigned int, void __user *); | ||
147 | typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int, | ||
148 | struct cred *); | ||
149 | typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int, | ||
150 | struct cred *); | ||
151 | typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *); | ||
152 | typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **, | ||
153 | int, bhv_vnode_t *, struct cred *); | ||
154 | typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *, | ||
155 | bhv_vnode_t **, struct cred *); | ||
156 | typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *); | ||
157 | typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *, | ||
158 | struct cred *); | ||
159 | typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *, | ||
160 | bhv_vname_t *, struct cred *); | ||
161 | typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *, | ||
162 | bhv_vnode_t **, struct cred *); | ||
163 | typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *); | ||
164 | typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *, | ||
165 | int *); | ||
166 | typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*, | ||
167 | char *, bhv_vnode_t **, struct cred *); | ||
168 | typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, | ||
169 | struct cred *); | ||
170 | typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *, | ||
171 | xfs_off_t, xfs_off_t); | ||
172 | typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *); | ||
173 | typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *); | ||
174 | typedef int (*vop_release_t)(bhv_desc_t *); | ||
175 | typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t); | ||
176 | typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t); | ||
177 | typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int, | ||
178 | struct xfs_iomap *, int *); | ||
179 | typedef int (*vop_reclaim_t)(bhv_desc_t *); | ||
180 | typedef int (*vop_attr_get_t)(bhv_desc_t *, const char *, char *, int *, | ||
181 | int, struct cred *); | ||
182 | typedef int (*vop_attr_set_t)(bhv_desc_t *, const char *, char *, int, | ||
183 | int, struct cred *); | ||
184 | typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *, | ||
185 | int, struct cred *); | ||
186 | typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int, | ||
187 | struct attrlist_cursor_kern *, struct cred *); | ||
188 | typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int); | ||
189 | typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t); | ||
190 | typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); | ||
191 | typedef int (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); | ||
192 | typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, | ||
193 | uint64_t, int); | ||
194 | typedef int (*vop_iflush_t)(bhv_desc_t *, int); | ||
195 | |||
196 | |||
197 | typedef 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 | ||
429 | extern void vn_init(void); | 189 | extern void vn_init(void); |
430 | extern bhv_vnode_t *vn_initialize(struct inode *); | 190 | extern bhv_vnode_t *vn_initialize(struct inode *); |
431 | extern int vn_revalidate(struct bhv_vnode *); | 191 | extern int vn_revalidate(bhv_vnode_t *); |
432 | extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *); | 192 | extern int __vn_revalidate(bhv_vnode_t *, bhv_vattr_t *); |
433 | extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *); | 193 | extern void vn_revalidate_core(bhv_vnode_t *, bhv_vattr_t *); |
434 | |||
435 | extern void vn_iowait(struct bhv_vnode *vp); | ||
436 | extern void vn_iowake(struct bhv_vnode *vp); | ||
437 | 194 | ||
438 | extern 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 | */ | ||
199 | extern void vn_iowait(struct xfs_inode *ip); | ||
200 | extern void vn_iowake(struct xfs_inode *ip); | ||
201 | extern void vn_ioerror(struct xfs_inode *ip, int error, char *f, int l); | ||
439 | 202 | ||
440 | static inline int vn_count(struct bhv_vnode *vp) | 203 | static 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 | */ |
448 | extern bhv_vnode_t *vn_hold(struct bhv_vnode *); | 211 | extern 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 | ||
462 | static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp) | 225 | static 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 | |||
481 | STATIC_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 | |||
488 | STATIC_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 | */ |
507 | static inline void vn_mark_bad(struct bhv_vnode *vp) | 241 | static 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 | ||
512 | static inline int VN_BAD(struct bhv_vnode *vp) | 246 | static 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 | */ |
520 | static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime) | 254 | static 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 | ||
526 | static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts) | 260 | static 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 | ||
531 | static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt) | 265 | static 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 | ||
575 | extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *); | 308 | extern void vn_trace_entry(struct xfs_inode *, const char *, inst_t *); |
576 | extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *); | 309 | extern void vn_trace_exit(struct xfs_inode *, const char *, inst_t *); |
577 | extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *); | 310 | extern void vn_trace_hold(struct xfs_inode *, char *, int, inst_t *); |
578 | extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *); | 311 | extern void vn_trace_ref(struct xfs_inode *, char *, int, inst_t *); |
579 | extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *); | 312 | extern void vn_trace_rele(struct xfs_inode *, char *, int, inst_t *); |
580 | |||
581 | #define VN_TRACE(vp) \ | ||
582 | vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address) | ||
583 | #else | 313 | #else |
584 | #define vn_trace_entry(a,b,c) | 314 | #define vn_trace_entry(a,b,c) |
585 | #define vn_trace_exit(a,b,c) | 315 | #define vn_trace_exit(a,b,c) |
586 | #define vn_trace_hold(a,b,c,d) | 316 | #define vn_trace_hold(a,b,c,d) |
587 | #define vn_trace_ref(a,b,c,d) | 317 | #define vn_trace_ref(a,b,c,d) |
588 | #define vn_trace_rele(a,b,c,d) | 318 | #define vn_trace_rele(a,b,c,d) |
589 | #define VN_TRACE(vp) | ||
590 | #endif | 319 | #endif |
591 | 320 | ||
592 | #endif /* __XFS_VNODE_H__ */ | 321 | #endif /* __XFS_VNODE_H__ */ |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 6ff0f4de1630..b5f91281b707 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -288,45 +288,6 @@ xfs_qm_rele_quotafs_ref( | |||
288 | } | 288 | } |
289 | 289 | ||
290 | /* | 290 | /* |
291 | * This is called at mount time from xfs_mountfs to initialize the quotainfo | ||
292 | * structure and start the global quota manager (xfs_Gqm) if it hasn't done | ||
293 | * so already. Note that the superblock has not been read in yet. | ||
294 | */ | ||
295 | void | ||
296 | xfs_qm_mount_quotainit( | ||
297 | xfs_mount_t *mp, | ||
298 | uint flags) | ||
299 | { | ||
300 | /* | ||
301 | * User, projects or group quotas has to be on. | ||
302 | */ | ||
303 | ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)); | ||
304 | |||
305 | /* | ||
306 | * Initialize the flags in the mount structure. From this point | ||
307 | * onwards we look at m_qflags to figure out if quotas's ON/OFF, etc. | ||
308 | * Note that we enforce nothing if accounting is off. | ||
309 | * ie. XFSMNT_*QUOTA must be ON for XFSMNT_*QUOTAENF. | ||
310 | * It isn't necessary to take the quotaoff lock to do this; this is | ||
311 | * called from mount. | ||
312 | */ | ||
313 | if (flags & XFSMNT_UQUOTA) { | ||
314 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); | ||
315 | if (flags & XFSMNT_UQUOTAENF) | ||
316 | mp->m_qflags |= XFS_UQUOTA_ENFD; | ||
317 | } | ||
318 | if (flags & XFSMNT_GQUOTA) { | ||
319 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | ||
320 | if (flags & XFSMNT_GQUOTAENF) | ||
321 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
322 | } else if (flags & XFSMNT_PQUOTA) { | ||
323 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | ||
324 | if (flags & XFSMNT_PQUOTAENF) | ||
325 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * Just destroy the quotainfo structure. | 291 | * Just destroy the quotainfo structure. |
331 | */ | 292 | */ |
332 | void | 293 | void |
@@ -1039,7 +1000,7 @@ xfs_qm_dqdetach( | |||
1039 | int | 1000 | int |
1040 | xfs_qm_sync( | 1001 | xfs_qm_sync( |
1041 | xfs_mount_t *mp, | 1002 | xfs_mount_t *mp, |
1042 | short flags) | 1003 | int flags) |
1043 | { | 1004 | { |
1044 | int recl, restarts; | 1005 | int recl, restarts; |
1045 | xfs_dquot_t *dqp; | 1006 | xfs_dquot_t *dqp; |
@@ -1717,7 +1678,6 @@ xfs_qm_get_rtblks( | |||
1717 | xfs_extnum_t idx; /* extent record index */ | 1678 | xfs_extnum_t idx; /* extent record index */ |
1718 | xfs_ifork_t *ifp; /* inode fork pointer */ | 1679 | xfs_ifork_t *ifp; /* inode fork pointer */ |
1719 | xfs_extnum_t nextents; /* number of extent entries */ | 1680 | xfs_extnum_t nextents; /* number of extent entries */ |
1720 | xfs_bmbt_rec_t *ep; /* pointer to an extent entry */ | ||
1721 | int error; | 1681 | int error; |
1722 | 1682 | ||
1723 | ASSERT(XFS_IS_REALTIME_INODE(ip)); | 1683 | ASSERT(XFS_IS_REALTIME_INODE(ip)); |
@@ -1728,10 +1688,8 @@ xfs_qm_get_rtblks( | |||
1728 | } | 1688 | } |
1729 | rtblks = 0; | 1689 | rtblks = 0; |
1730 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); | 1690 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); |
1731 | for (idx = 0; idx < nextents; idx++) { | 1691 | for (idx = 0; idx < nextents; idx++) |
1732 | ep = xfs_iext_get_ext(ifp, idx); | 1692 | rtblks += xfs_bmbt_get_blockcount(xfs_iext_get_ext(ifp, idx)); |
1733 | rtblks += xfs_bmbt_get_blockcount(ep); | ||
1734 | } | ||
1735 | *O_rtblks = (xfs_qcnt_t)rtblks; | 1693 | *O_rtblks = (xfs_qcnt_t)rtblks; |
1736 | return 0; | 1694 | return 0; |
1737 | } | 1695 | } |
@@ -2459,8 +2417,7 @@ xfs_qm_vop_dqalloc( | |||
2459 | lockflags = XFS_ILOCK_EXCL; | 2417 | lockflags = XFS_ILOCK_EXCL; |
2460 | xfs_ilock(ip, lockflags); | 2418 | xfs_ilock(ip, lockflags); |
2461 | 2419 | ||
2462 | if ((flags & XFS_QMOPT_INHERIT) && | 2420 | if ((flags & XFS_QMOPT_INHERIT) && XFS_INHERIT_GID(ip)) |
2463 | XFS_INHERIT_GID(ip, XFS_MTOVFS(mp))) | ||
2464 | gid = ip->i_d.di_gid; | 2421 | gid = ip->i_d.di_gid; |
2465 | 2422 | ||
2466 | /* | 2423 | /* |
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index 689407de0a20..23ccaa5fceaf 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
@@ -166,12 +166,11 @@ typedef struct xfs_dquot_acct { | |||
166 | 166 | ||
167 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); | 167 | extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); |
168 | extern int xfs_qm_mount_quotas(xfs_mount_t *, int); | 168 | extern int xfs_qm_mount_quotas(xfs_mount_t *, int); |
169 | extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint); | ||
170 | extern int xfs_qm_quotacheck(xfs_mount_t *); | 169 | extern int xfs_qm_quotacheck(xfs_mount_t *); |
171 | extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); | 170 | extern void xfs_qm_unmount_quotadestroy(xfs_mount_t *); |
172 | extern int xfs_qm_unmount_quotas(xfs_mount_t *); | 171 | extern int xfs_qm_unmount_quotas(xfs_mount_t *); |
173 | extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); | 172 | extern int xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t); |
174 | extern int xfs_qm_sync(xfs_mount_t *, short); | 173 | extern int xfs_qm_sync(xfs_mount_t *, int); |
175 | 174 | ||
176 | /* dquot stuff */ | 175 | /* dquot stuff */ |
177 | extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **); | 176 | extern boolean_t xfs_qm_dqalloc_incore(xfs_dquot_t **); |
@@ -199,7 +198,8 @@ extern void xfs_qm_freelist_unlink(xfs_dquot_t *); | |||
199 | extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); | 198 | extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); |
200 | 199 | ||
201 | /* system call interface */ | 200 | /* system call interface */ |
202 | extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t); | 201 | extern int xfs_qm_quotactl(struct xfs_mount *, int, int, |
202 | xfs_caddr_t); | ||
203 | 203 | ||
204 | #ifdef DEBUG | 204 | #ifdef DEBUG |
205 | extern int xfs_qm_internalqcheck(xfs_mount_t *); | 205 | extern int xfs_qm_internalqcheck(xfs_mount_t *); |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index d2cdb8a2aad6..97bb32937585 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
@@ -48,172 +48,13 @@ | |||
48 | #include "xfs_buf_item.h" | 48 | #include "xfs_buf_item.h" |
49 | #include "xfs_qm.h" | 49 | #include "xfs_qm.h" |
50 | 50 | ||
51 | #define MNTOPT_QUOTA "quota" /* disk quotas (user) */ | ||
52 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ | ||
53 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ | ||
54 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ | ||
55 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ | ||
56 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ | ||
57 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ | ||
58 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ | ||
59 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ | ||
60 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | ||
61 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | ||
62 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | ||
63 | 51 | ||
64 | STATIC int | 52 | STATIC void |
65 | xfs_qm_parseargs( | 53 | xfs_fill_statvfs_from_dquot( |
66 | struct bhv_desc *bhv, | ||
67 | char *options, | ||
68 | struct xfs_mount_args *args, | ||
69 | int update) | ||
70 | { | ||
71 | size_t length; | ||
72 | char *local_options = options; | ||
73 | char *this_char; | ||
74 | int error; | ||
75 | int referenced = update; | ||
76 | |||
77 | while ((this_char = strsep(&local_options, ",")) != NULL) { | ||
78 | length = strlen(this_char); | ||
79 | if (local_options) | ||
80 | length++; | ||
81 | |||
82 | if (!strcmp(this_char, MNTOPT_NOQUOTA)) { | ||
83 | args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA); | ||
84 | args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA); | ||
85 | referenced = update; | ||
86 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || | ||
87 | !strcmp(this_char, MNTOPT_UQUOTA) || | ||
88 | !strcmp(this_char, MNTOPT_USRQUOTA)) { | ||
89 | args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF; | ||
90 | referenced = 1; | ||
91 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || | ||
92 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { | ||
93 | args->flags |= XFSMNT_UQUOTA; | ||
94 | args->flags &= ~XFSMNT_UQUOTAENF; | ||
95 | referenced = 1; | ||
96 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | ||
97 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | ||
98 | args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF; | ||
99 | referenced = 1; | ||
100 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | ||
101 | args->flags |= XFSMNT_PQUOTA; | ||
102 | args->flags &= ~XFSMNT_PQUOTAENF; | ||
103 | referenced = 1; | ||
104 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | ||
105 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | ||
106 | args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; | ||
107 | referenced = 1; | ||
108 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { | ||
109 | args->flags |= XFSMNT_GQUOTA; | ||
110 | args->flags &= ~XFSMNT_GQUOTAENF; | ||
111 | referenced = 1; | ||
112 | } else { | ||
113 | if (local_options) | ||
114 | *(local_options-1) = ','; | ||
115 | continue; | ||
116 | } | ||
117 | |||
118 | while (length--) | ||
119 | *this_char++ = ','; | ||
120 | } | ||
121 | |||
122 | if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) { | ||
123 | cmn_err(CE_WARN, | ||
124 | "XFS: cannot mount with both project and group quota"); | ||
125 | return XFS_ERROR(EINVAL); | ||
126 | } | ||
127 | |||
128 | error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update); | ||
129 | if (!error && !referenced) | ||
130 | bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); | ||
131 | return error; | ||
132 | } | ||
133 | |||
134 | STATIC int | ||
135 | xfs_qm_showargs( | ||
136 | struct bhv_desc *bhv, | ||
137 | struct seq_file *m) | ||
138 | { | ||
139 | struct bhv_vfs *vfsp = bhvtovfs(bhv); | ||
140 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | ||
141 | |||
142 | if (mp->m_qflags & XFS_UQUOTA_ACCT) { | ||
143 | (mp->m_qflags & XFS_UQUOTA_ENFD) ? | ||
144 | seq_puts(m, "," MNTOPT_USRQUOTA) : | ||
145 | seq_puts(m, "," MNTOPT_UQUOTANOENF); | ||
146 | } | ||
147 | |||
148 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { | ||
149 | (mp->m_qflags & XFS_OQUOTA_ENFD) ? | ||
150 | seq_puts(m, "," MNTOPT_PRJQUOTA) : | ||
151 | seq_puts(m, "," MNTOPT_PQUOTANOENF); | ||
152 | } | ||
153 | |||
154 | if (mp->m_qflags & XFS_GQUOTA_ACCT) { | ||
155 | (mp->m_qflags & XFS_OQUOTA_ENFD) ? | ||
156 | seq_puts(m, "," MNTOPT_GRPQUOTA) : | ||
157 | seq_puts(m, "," MNTOPT_GQUOTANOENF); | ||
158 | } | ||
159 | |||
160 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) | ||
161 | seq_puts(m, "," MNTOPT_NOQUOTA); | ||
162 | |||
163 | return bhv_next_vfs_showargs(BHV_NEXT(bhv), m); | ||
164 | } | ||
165 | |||
166 | STATIC int | ||
167 | xfs_qm_mount( | ||
168 | struct bhv_desc *bhv, | ||
169 | struct xfs_mount_args *args, | ||
170 | struct cred *cr) | ||
171 | { | ||
172 | struct bhv_vfs *vfsp = bhvtovfs(bhv); | ||
173 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | ||
174 | |||
175 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) | ||
176 | xfs_qm_mount_quotainit(mp, args->flags); | ||
177 | return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr); | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * Directory tree accounting is implemented using project quotas, where | ||
182 | * the project identifier is inherited from parent directories. | ||
183 | * A statvfs (df, etc.) of a directory that is using project quota should | ||
184 | * return a statvfs of the project, not the entire filesystem. | ||
185 | * This makes such trees appear as if they are filesystems in themselves. | ||
186 | */ | ||
187 | STATIC int | ||
188 | xfs_qm_statvfs( | ||
189 | struct bhv_desc *bhv, | ||
190 | bhv_statvfs_t *statp, | 54 | bhv_statvfs_t *statp, |
191 | struct bhv_vnode *vnode) | 55 | xfs_disk_dquot_t *dp) |
192 | { | 56 | { |
193 | xfs_mount_t *mp; | ||
194 | xfs_inode_t *ip; | ||
195 | xfs_dquot_t *dqp; | ||
196 | xfs_disk_dquot_t *dp; | ||
197 | __uint64_t limit; | 57 | __uint64_t limit; |
198 | int error; | ||
199 | |||
200 | error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode); | ||
201 | if (error || !vnode) | ||
202 | return error; | ||
203 | |||
204 | mp = xfs_vfstom(bhvtovfs(bhv)); | ||
205 | ip = xfs_vtoi(vnode); | ||
206 | |||
207 | if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)) | ||
208 | return 0; | ||
209 | if (!(mp->m_qflags & XFS_PQUOTA_ACCT)) | ||
210 | return 0; | ||
211 | if (!(mp->m_qflags & XFS_OQUOTA_ENFD)) | ||
212 | return 0; | ||
213 | |||
214 | if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) | ||
215 | return 0; | ||
216 | dp = &dqp->q_core; | ||
217 | 58 | ||
218 | limit = dp->d_blk_softlimit ? | 59 | limit = dp->d_blk_softlimit ? |
219 | be64_to_cpu(dp->d_blk_softlimit) : | 60 | be64_to_cpu(dp->d_blk_softlimit) : |
@@ -234,37 +75,35 @@ xfs_qm_statvfs( | |||
234 | (statp->f_files > be64_to_cpu(dp->d_icount)) ? | 75 | (statp->f_files > be64_to_cpu(dp->d_icount)) ? |
235 | (statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0; | 76 | (statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0; |
236 | } | 77 | } |
237 | |||
238 | xfs_qm_dqput(dqp); | ||
239 | return 0; | ||
240 | } | 78 | } |
241 | 79 | ||
242 | STATIC int | 80 | |
243 | xfs_qm_syncall( | 81 | /* |
244 | struct bhv_desc *bhv, | 82 | * Directory tree accounting is implemented using project quotas, where |
245 | int flags, | 83 | * the project identifier is inherited from parent directories. |
246 | cred_t *credp) | 84 | * A statvfs (df, etc.) of a directory that is using project quota should |
85 | * return a statvfs of the project, not the entire filesystem. | ||
86 | * This makes such trees appear as if they are filesystems in themselves. | ||
87 | */ | ||
88 | STATIC void | ||
89 | xfs_qm_statvfs( | ||
90 | xfs_inode_t *ip, | ||
91 | bhv_statvfs_t *statp) | ||
247 | { | 92 | { |
248 | struct bhv_vfs *vfsp = bhvtovfs(bhv); | 93 | xfs_mount_t *mp = ip->i_mount; |
249 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | 94 | xfs_dquot_t *dqp; |
250 | int error; | ||
251 | 95 | ||
252 | /* | 96 | if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) || |
253 | * Get the Quota Manager to flush the dquots. | 97 | !((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) == |
254 | */ | 98 | (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) |
255 | if (XFS_IS_QUOTA_ON(mp)) { | 99 | return; |
256 | if ((error = xfs_qm_sync(mp, flags))) { | 100 | |
257 | /* | 101 | if (!xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) { |
258 | * If we got an IO error, we will be shutting down. | 102 | xfs_disk_dquot_t *dp = &dqp->q_core; |
259 | * So, there's nothing more for us to do here. | 103 | |
260 | */ | 104 | xfs_fill_statvfs_from_dquot(statp, dp); |
261 | ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp)); | 105 | xfs_qm_dqput(dqp); |
262 | if (XFS_FORCED_SHUTDOWN(mp)) { | ||
263 | return XFS_ERROR(error); | ||
264 | } | ||
265 | } | ||
266 | } | 106 | } |
267 | return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp); | ||
268 | } | 107 | } |
269 | 108 | ||
270 | STATIC int | 109 | STATIC int |
@@ -382,7 +221,7 @@ xfs_qm_dqrele_null( | |||
382 | } | 221 | } |
383 | 222 | ||
384 | 223 | ||
385 | static struct xfs_qmops xfs_qmcore_xfs = { | 224 | struct xfs_qmops xfs_qmcore_xfs = { |
386 | .xfs_qminit = xfs_qm_newmount, | 225 | .xfs_qminit = xfs_qm_newmount, |
387 | .xfs_qmdone = xfs_qm_unmount_quotadestroy, | 226 | .xfs_qmdone = xfs_qm_unmount_quotadestroy, |
388 | .xfs_qmmount = xfs_qm_endmount, | 227 | .xfs_qmmount = xfs_qm_endmount, |
@@ -396,36 +235,24 @@ static struct xfs_qmops xfs_qmcore_xfs = { | |||
396 | .xfs_dqvoprename = xfs_qm_vop_rename_dqattach, | 235 | .xfs_dqvoprename = xfs_qm_vop_rename_dqattach, |
397 | .xfs_dqvopchown = xfs_qm_vop_chown, | 236 | .xfs_dqvopchown = xfs_qm_vop_chown, |
398 | .xfs_dqvopchownresv = xfs_qm_vop_chown_reserve, | 237 | .xfs_dqvopchownresv = xfs_qm_vop_chown_reserve, |
238 | .xfs_dqstatvfs = xfs_qm_statvfs, | ||
239 | .xfs_dqsync = xfs_qm_sync, | ||
240 | .xfs_quotactl = xfs_qm_quotactl, | ||
399 | .xfs_dqtrxops = &xfs_trans_dquot_ops, | 241 | .xfs_dqtrxops = &xfs_trans_dquot_ops, |
400 | }; | 242 | }; |
401 | 243 | EXPORT_SYMBOL(xfs_qmcore_xfs); | |
402 | struct bhv_module_vfsops xfs_qmops = { { | ||
403 | BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM), | ||
404 | .vfs_parseargs = xfs_qm_parseargs, | ||
405 | .vfs_showargs = xfs_qm_showargs, | ||
406 | .vfs_mount = xfs_qm_mount, | ||
407 | .vfs_statvfs = xfs_qm_statvfs, | ||
408 | .vfs_sync = xfs_qm_syncall, | ||
409 | .vfs_quotactl = xfs_qm_quotactl, }, | ||
410 | }; | ||
411 | |||
412 | 244 | ||
413 | void __init | 245 | void __init |
414 | xfs_qm_init(void) | 246 | xfs_qm_init(void) |
415 | { | 247 | { |
416 | static char message[] __initdata = | 248 | printk(KERN_INFO "SGI XFS Quota Management subsystem\n"); |
417 | KERN_INFO "SGI XFS Quota Management subsystem\n"; | ||
418 | |||
419 | printk(message); | ||
420 | mutex_init(&xfs_Gqm_lock); | 249 | mutex_init(&xfs_Gqm_lock); |
421 | vfs_bhv_set_custom(&xfs_qmops, &xfs_qmcore_xfs); | ||
422 | xfs_qm_init_procfs(); | 250 | xfs_qm_init_procfs(); |
423 | } | 251 | } |
424 | 252 | ||
425 | void __exit | 253 | void __exit |
426 | xfs_qm_exit(void) | 254 | xfs_qm_exit(void) |
427 | { | 255 | { |
428 | vfs_bhv_clr_custom(&xfs_qmops); | ||
429 | xfs_qm_cleanup_procfs(); | 256 | xfs_qm_cleanup_procfs(); |
430 | if (qm_dqzone) | 257 | if (qm_dqzone) |
431 | kmem_zone_destroy(qm_dqzone); | 258 | kmem_zone_destroy(qm_dqzone); |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 2df67fd913e5..ad5579d4eac4 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -81,18 +81,13 @@ STATIC void xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *, | |||
81 | */ | 81 | */ |
82 | int | 82 | int |
83 | xfs_qm_quotactl( | 83 | xfs_qm_quotactl( |
84 | struct bhv_desc *bdp, | 84 | xfs_mount_t *mp, |
85 | int cmd, | 85 | int cmd, |
86 | int id, | 86 | int id, |
87 | xfs_caddr_t addr) | 87 | xfs_caddr_t addr) |
88 | { | 88 | { |
89 | xfs_mount_t *mp; | ||
90 | bhv_vfs_t *vfsp; | ||
91 | int error; | 89 | int error; |
92 | 90 | ||
93 | vfsp = bhvtovfs(bdp); | ||
94 | mp = XFS_VFSTOM(vfsp); | ||
95 | |||
96 | ASSERT(addr != NULL || cmd == Q_XQUOTASYNC); | 91 | ASSERT(addr != NULL || cmd == Q_XQUOTASYNC); |
97 | 92 | ||
98 | /* | 93 | /* |
@@ -105,7 +100,7 @@ xfs_qm_quotactl( | |||
105 | */ | 100 | */ |
106 | if (XFS_IS_QUOTA_ON(mp)) | 101 | if (XFS_IS_QUOTA_ON(mp)) |
107 | return XFS_ERROR(EINVAL); | 102 | return XFS_ERROR(EINVAL); |
108 | if (vfsp->vfs_flag & VFS_RDONLY) | 103 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
109 | return XFS_ERROR(EROFS); | 104 | return XFS_ERROR(EROFS); |
110 | return (xfs_qm_scall_trunc_qfiles(mp, | 105 | return (xfs_qm_scall_trunc_qfiles(mp, |
111 | xfs_qm_import_qtype_flags(*(uint *)addr))); | 106 | xfs_qm_import_qtype_flags(*(uint *)addr))); |
@@ -121,13 +116,13 @@ xfs_qm_quotactl( | |||
121 | * QUOTAON - enabling quota enforcement. | 116 | * QUOTAON - enabling quota enforcement. |
122 | * Quota accounting must be turned on at mount time. | 117 | * Quota accounting must be turned on at mount time. |
123 | */ | 118 | */ |
124 | if (vfsp->vfs_flag & VFS_RDONLY) | 119 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
125 | return XFS_ERROR(EROFS); | 120 | return XFS_ERROR(EROFS); |
126 | return (xfs_qm_scall_quotaon(mp, | 121 | return (xfs_qm_scall_quotaon(mp, |
127 | xfs_qm_import_flags(*(uint *)addr))); | 122 | xfs_qm_import_flags(*(uint *)addr))); |
128 | 123 | ||
129 | case Q_XQUOTAOFF: | 124 | case Q_XQUOTAOFF: |
130 | if (vfsp->vfs_flag & VFS_RDONLY) | 125 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
131 | return XFS_ERROR(EROFS); | 126 | return XFS_ERROR(EROFS); |
132 | break; | 127 | break; |
133 | 128 | ||
@@ -143,7 +138,7 @@ xfs_qm_quotactl( | |||
143 | 138 | ||
144 | switch (cmd) { | 139 | switch (cmd) { |
145 | case Q_XQUOTAOFF: | 140 | case Q_XQUOTAOFF: |
146 | if (vfsp->vfs_flag & VFS_RDONLY) | 141 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
147 | return XFS_ERROR(EROFS); | 142 | return XFS_ERROR(EROFS); |
148 | error = xfs_qm_scall_quotaoff(mp, | 143 | error = xfs_qm_scall_quotaoff(mp, |
149 | xfs_qm_import_flags(*(uint *)addr), | 144 | xfs_qm_import_flags(*(uint *)addr), |
@@ -164,19 +159,19 @@ xfs_qm_quotactl( | |||
164 | break; | 159 | break; |
165 | 160 | ||
166 | case Q_XSETQLIM: | 161 | case Q_XSETQLIM: |
167 | if (vfsp->vfs_flag & VFS_RDONLY) | 162 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
168 | return XFS_ERROR(EROFS); | 163 | return XFS_ERROR(EROFS); |
169 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, | 164 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, |
170 | (fs_disk_quota_t *)addr); | 165 | (fs_disk_quota_t *)addr); |
171 | break; | 166 | break; |
172 | case Q_XSETGQLIM: | 167 | case Q_XSETGQLIM: |
173 | if (vfsp->vfs_flag & VFS_RDONLY) | 168 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
174 | return XFS_ERROR(EROFS); | 169 | return XFS_ERROR(EROFS); |
175 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, | 170 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, |
176 | (fs_disk_quota_t *)addr); | 171 | (fs_disk_quota_t *)addr); |
177 | break; | 172 | break; |
178 | case Q_XSETPQLIM: | 173 | case Q_XSETPQLIM: |
179 | if (vfsp->vfs_flag & VFS_RDONLY) | 174 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
180 | return XFS_ERROR(EROFS); | 175 | return XFS_ERROR(EROFS); |
181 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, | 176 | error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ, |
182 | (fs_disk_quota_t *)addr); | 177 | (fs_disk_quota_t *)addr); |
diff --git a/fs/xfs/support/move.c b/fs/xfs/support/move.c deleted file mode 100644 index ac8617ca3909..000000000000 --- a/fs/xfs/support/move.c +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include <xfs.h> | ||
19 | |||
20 | /* Read from kernel buffer at src to user/kernel buffer defined | ||
21 | * by the uio structure. Advance the pointer in the uio struct | ||
22 | * as we go. | ||
23 | */ | ||
24 | int | ||
25 | xfs_uio_read(caddr_t src, size_t len, struct uio *uio) | ||
26 | { | ||
27 | size_t count; | ||
28 | |||
29 | if (!len || !uio->uio_resid) | ||
30 | return 0; | ||
31 | |||
32 | count = uio->uio_iov->iov_len; | ||
33 | if (!count) | ||
34 | return 0; | ||
35 | if (count > len) | ||
36 | count = len; | ||
37 | |||
38 | if (uio->uio_segflg == UIO_USERSPACE) { | ||
39 | if (copy_to_user(uio->uio_iov->iov_base, src, count)) | ||
40 | return EFAULT; | ||
41 | } else { | ||
42 | ASSERT(uio->uio_segflg == UIO_SYSSPACE); | ||
43 | memcpy(uio->uio_iov->iov_base, src, count); | ||
44 | } | ||
45 | |||
46 | uio->uio_iov->iov_base = (void*)((char*)uio->uio_iov->iov_base + count); | ||
47 | uio->uio_iov->iov_len -= count; | ||
48 | uio->uio_offset += count; | ||
49 | uio->uio_resid -= count; | ||
50 | return 0; | ||
51 | } | ||
diff --git a/fs/xfs/support/move.h b/fs/xfs/support/move.h deleted file mode 100644 index 324e413deadd..000000000000 --- a/fs/xfs/support/move.h +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | * | ||
18 | * Portions Copyright (c) 1982, 1986, 1993, 1994 | ||
19 | * The Regents of the University of California. All rights reserved. | ||
20 | * | ||
21 | * Redistribution and use in source and binary forms, with or without | ||
22 | * modification, are permitted provided that the following conditions | ||
23 | * are met: | ||
24 | * 1. Redistributions of source code must retain the above copyright | ||
25 | * notice, this list of conditions and the following disclaimer. | ||
26 | * 2. Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in the | ||
28 | * documentation and/or other materials provided with the distribution. | ||
29 | * 3. Neither the name of the University nor the names of its contributors | ||
30 | * may be used to endorse or promote products derived from this software | ||
31 | * without specific prior written permission. | ||
32 | * | ||
33 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
34 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
35 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
36 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
37 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
38 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
39 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
40 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
41 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
42 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
43 | * SUCH DAMAGE. | ||
44 | */ | ||
45 | #ifndef __XFS_SUPPORT_MOVE_H__ | ||
46 | #define __XFS_SUPPORT_MOVE_H__ | ||
47 | |||
48 | #include <linux/uio.h> | ||
49 | #include <asm/uaccess.h> | ||
50 | |||
51 | /* Segment flag values. */ | ||
52 | enum uio_seg { | ||
53 | UIO_USERSPACE, /* from user data space */ | ||
54 | UIO_SYSSPACE, /* from system space */ | ||
55 | }; | ||
56 | |||
57 | struct uio { | ||
58 | struct kvec *uio_iov; /* pointer to array of iovecs */ | ||
59 | int uio_iovcnt; /* number of iovecs in array */ | ||
60 | xfs_off_t uio_offset; /* offset in file this uio corresponds to */ | ||
61 | int uio_resid; /* residual i/o count */ | ||
62 | enum uio_seg uio_segflg; /* see above */ | ||
63 | }; | ||
64 | |||
65 | typedef struct uio uio_t; | ||
66 | typedef struct kvec iovec_t; | ||
67 | |||
68 | extern int xfs_uio_read (caddr_t, size_t, uio_t *); | ||
69 | |||
70 | #endif /* __XFS_SUPPORT_MOVE_H__ */ | ||
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4ca4beb7bb54..5bfb66f33caf 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "xfs_btree.h" | 32 | #include "xfs_btree.h" |
33 | #include "xfs_acl.h" | 33 | #include "xfs_acl.h" |
34 | #include "xfs_attr.h" | 34 | #include "xfs_attr.h" |
35 | #include "xfs_vnodeops.h" | ||
35 | 36 | ||
36 | #include <linux/capability.h> | 37 | #include <linux/capability.h> |
37 | #include <linux/posix_acl_xattr.h> | 38 | #include <linux/posix_acl_xattr.h> |
@@ -241,7 +242,7 @@ xfs_acl_vget( | |||
241 | bhv_vattr_t va; | 242 | bhv_vattr_t va; |
242 | 243 | ||
243 | va.va_mask = XFS_AT_MODE; | 244 | va.va_mask = XFS_AT_MODE; |
244 | error = bhv_vop_getattr(vp, &va, 0, sys_cred); | 245 | error = xfs_getattr(xfs_vtoi(vp), &va, 0); |
245 | if (error) | 246 | if (error) |
246 | goto out; | 247 | goto out; |
247 | xfs_acl_sync_mode(va.va_mode, xfs_acl); | 248 | xfs_acl_sync_mode(va.va_mode, xfs_acl); |
@@ -265,9 +266,10 @@ xfs_acl_vremove( | |||
265 | VN_HOLD(vp); | 266 | VN_HOLD(vp); |
266 | error = xfs_acl_allow_set(vp, kind); | 267 | error = xfs_acl_allow_set(vp, kind); |
267 | if (!error) { | 268 | if (!error) { |
268 | error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT? | 269 | error = xfs_attr_remove(xfs_vtoi(vp), |
270 | kind == _ACL_TYPE_DEFAULT? | ||
269 | SGI_ACL_DEFAULT: SGI_ACL_FILE, | 271 | SGI_ACL_DEFAULT: SGI_ACL_FILE, |
270 | ATTR_ROOT, sys_cred); | 272 | ATTR_ROOT); |
271 | if (error == ENOATTR) | 273 | if (error == ENOATTR) |
272 | error = 0; /* 'scool */ | 274 | error = 0; /* 'scool */ |
273 | } | 275 | } |
@@ -370,17 +372,18 @@ xfs_acl_allow_set( | |||
370 | bhv_vnode_t *vp, | 372 | bhv_vnode_t *vp, |
371 | int kind) | 373 | int kind) |
372 | { | 374 | { |
375 | xfs_inode_t *ip = xfs_vtoi(vp); | ||
373 | bhv_vattr_t va; | 376 | bhv_vattr_t va; |
374 | int error; | 377 | int error; |
375 | 378 | ||
376 | if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) | 379 | if (vp->i_flags & (S_IMMUTABLE|S_APPEND)) |
377 | return EPERM; | 380 | return EPERM; |
378 | if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp)) | 381 | if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp)) |
379 | return ENOTDIR; | 382 | return ENOTDIR; |
380 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 383 | if (vp->i_sb->s_flags & MS_RDONLY) |
381 | return EROFS; | 384 | return EROFS; |
382 | va.va_mask = XFS_AT_UID; | 385 | va.va_mask = XFS_AT_UID; |
383 | error = bhv_vop_getattr(vp, &va, 0, NULL); | 386 | error = xfs_getattr(ip, &va, 0); |
384 | if (error) | 387 | if (error) |
385 | return error; | 388 | return error; |
386 | if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) | 389 | if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) |
@@ -613,7 +616,8 @@ xfs_acl_get_attr( | |||
613 | 616 | ||
614 | ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); | 617 | ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); |
615 | flags |= ATTR_ROOT; | 618 | flags |= ATTR_ROOT; |
616 | *error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ? | 619 | *error = xfs_attr_get(xfs_vtoi(vp), |
620 | kind == _ACL_TYPE_ACCESS ? | ||
617 | SGI_ACL_FILE : SGI_ACL_DEFAULT, | 621 | SGI_ACL_FILE : SGI_ACL_DEFAULT, |
618 | (char *)aclp, &len, flags, sys_cred); | 622 | (char *)aclp, &len, flags, sys_cred); |
619 | if (*error || (flags & ATTR_KERNOVAL)) | 623 | if (*error || (flags & ATTR_KERNOVAL)) |
@@ -651,9 +655,10 @@ xfs_acl_set_attr( | |||
651 | INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); | 655 | INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); |
652 | } | 656 | } |
653 | INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); | 657 | INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); |
654 | *error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ? | 658 | *error = xfs_attr_set(xfs_vtoi(vp), |
659 | kind == _ACL_TYPE_ACCESS ? | ||
655 | SGI_ACL_FILE: SGI_ACL_DEFAULT, | 660 | SGI_ACL_FILE: SGI_ACL_DEFAULT, |
656 | (char *)newacl, len, ATTR_ROOT, sys_cred); | 661 | (char *)newacl, len, ATTR_ROOT); |
657 | _ACL_FREE(newacl); | 662 | _ACL_FREE(newacl); |
658 | } | 663 | } |
659 | 664 | ||
@@ -675,7 +680,7 @@ xfs_acl_vtoacl( | |||
675 | if (!error) { | 680 | if (!error) { |
676 | /* Got the ACL, need the mode... */ | 681 | /* Got the ACL, need the mode... */ |
677 | va.va_mask = XFS_AT_MODE; | 682 | va.va_mask = XFS_AT_MODE; |
678 | error = bhv_vop_getattr(vp, &va, 0, sys_cred); | 683 | error = xfs_getattr(xfs_vtoi(vp), &va, 0); |
679 | } | 684 | } |
680 | 685 | ||
681 | if (error) | 686 | if (error) |
@@ -699,7 +704,7 @@ xfs_acl_vtoacl( | |||
699 | int | 704 | int |
700 | xfs_acl_inherit( | 705 | xfs_acl_inherit( |
701 | bhv_vnode_t *vp, | 706 | bhv_vnode_t *vp, |
702 | bhv_vattr_t *vap, | 707 | mode_t mode, |
703 | xfs_acl_t *pdaclp) | 708 | xfs_acl_t *pdaclp) |
704 | { | 709 | { |
705 | xfs_acl_t *cacl; | 710 | xfs_acl_t *cacl; |
@@ -727,7 +732,7 @@ xfs_acl_inherit( | |||
727 | return ENOMEM; | 732 | return ENOMEM; |
728 | 733 | ||
729 | memcpy(cacl, pdaclp, sizeof(xfs_acl_t)); | 734 | memcpy(cacl, pdaclp, sizeof(xfs_acl_t)); |
730 | xfs_acl_filter_mode(vap->va_mode, cacl); | 735 | xfs_acl_filter_mode(mode, cacl); |
731 | xfs_acl_setmode(vp, cacl, &basicperms); | 736 | xfs_acl_setmode(vp, cacl, &basicperms); |
732 | 737 | ||
733 | /* | 738 | /* |
@@ -773,7 +778,7 @@ xfs_acl_setmode( | |||
773 | * mode. The m:: bits take precedence over the g:: bits. | 778 | * mode. The m:: bits take precedence over the g:: bits. |
774 | */ | 779 | */ |
775 | va.va_mask = XFS_AT_MODE; | 780 | va.va_mask = XFS_AT_MODE; |
776 | error = bhv_vop_getattr(vp, &va, 0, sys_cred); | 781 | error = xfs_getattr(xfs_vtoi(vp), &va, 0); |
777 | if (error) | 782 | if (error) |
778 | return error; | 783 | return error; |
779 | 784 | ||
@@ -807,7 +812,7 @@ xfs_acl_setmode( | |||
807 | if (gap && nomask) | 812 | if (gap && nomask) |
808 | va.va_mode |= gap->ae_perm << 3; | 813 | va.va_mode |= gap->ae_perm << 3; |
809 | 814 | ||
810 | return bhv_vop_setattr(vp, &va, 0, sys_cred); | 815 | return xfs_setattr(xfs_vtoi(vp), &va, 0, sys_cred); |
811 | } | 816 | } |
812 | 817 | ||
813 | /* | 818 | /* |
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index f853cf1a6270..34b7d3391299 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h | |||
@@ -50,7 +50,6 @@ typedef struct xfs_acl { | |||
50 | #ifdef CONFIG_XFS_POSIX_ACL | 50 | #ifdef CONFIG_XFS_POSIX_ACL |
51 | 51 | ||
52 | struct vattr; | 52 | struct vattr; |
53 | struct bhv_vnode; | ||
54 | struct xfs_inode; | 53 | struct xfs_inode; |
55 | 54 | ||
56 | extern struct kmem_zone *xfs_acl_zone; | 55 | extern struct kmem_zone *xfs_acl_zone; |
@@ -58,20 +57,20 @@ extern struct kmem_zone *xfs_acl_zone; | |||
58 | (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name)) | 57 | (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name)) |
59 | #define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) | 58 | #define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) |
60 | 59 | ||
61 | extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *); | 60 | extern int xfs_acl_inherit(bhv_vnode_t *, mode_t mode, xfs_acl_t *); |
62 | extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); | 61 | extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); |
63 | extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *); | 62 | extern int xfs_acl_vtoacl(bhv_vnode_t *, xfs_acl_t *, xfs_acl_t *); |
64 | extern int xfs_acl_vhasacl_access(struct bhv_vnode *); | 63 | extern int xfs_acl_vhasacl_access(bhv_vnode_t *); |
65 | extern int xfs_acl_vhasacl_default(struct bhv_vnode *); | 64 | extern int xfs_acl_vhasacl_default(bhv_vnode_t *); |
66 | extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int); | 65 | extern int xfs_acl_vset(bhv_vnode_t *, void *, size_t, int); |
67 | extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int); | 66 | extern int xfs_acl_vget(bhv_vnode_t *, void *, size_t, int); |
68 | extern int xfs_acl_vremove(struct bhv_vnode *, int); | 67 | extern int xfs_acl_vremove(bhv_vnode_t *, int); |
69 | 68 | ||
70 | #define _ACL_TYPE_ACCESS 1 | 69 | #define _ACL_TYPE_ACCESS 1 |
71 | #define _ACL_TYPE_DEFAULT 2 | 70 | #define _ACL_TYPE_DEFAULT 2 |
72 | #define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE)) | 71 | #define _ACL_PERM_INVALID(perm) ((perm) & ~(ACL_READ|ACL_WRITE|ACL_EXECUTE)) |
73 | 72 | ||
74 | #define _ACL_INHERIT(c,v,d) (xfs_acl_inherit(c,v,d)) | 73 | #define _ACL_INHERIT(c,m,d) (xfs_acl_inherit(c,m,d)) |
75 | #define _ACL_GET_ACCESS(pv,pa) (xfs_acl_vtoacl(pv,pa,NULL) == 0) | 74 | #define _ACL_GET_ACCESS(pv,pa) (xfs_acl_vtoacl(pv,pa,NULL) == 0) |
76 | #define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0) | 75 | #define _ACL_GET_DEFAULT(pv,pd) (xfs_acl_vtoacl(pv,NULL,pd) == 0) |
77 | #define _ACL_ACCESS_EXISTS xfs_acl_vhasacl_access | 76 | #define _ACL_ACCESS_EXISTS xfs_acl_vhasacl_access |
@@ -91,7 +90,7 @@ extern int xfs_acl_vremove(struct bhv_vnode *, int); | |||
91 | #define xfs_acl_vhasacl_default(v) (0) | 90 | #define xfs_acl_vhasacl_default(v) (0) |
92 | #define _ACL_ALLOC(a) (1) /* successfully allocate nothing */ | 91 | #define _ACL_ALLOC(a) (1) /* successfully allocate nothing */ |
93 | #define _ACL_FREE(a) ((void)0) | 92 | #define _ACL_FREE(a) ((void)0) |
94 | #define _ACL_INHERIT(c,v,d) (0) | 93 | #define _ACL_INHERIT(c,m,d) (0) |
95 | #define _ACL_GET_ACCESS(pv,pa) (0) | 94 | #define _ACL_GET_ACCESS(pv,pa) (0) |
96 | #define _ACL_GET_DEFAULT(pv,pd) (0) | 95 | #define _ACL_GET_DEFAULT(pv,pd) (0) |
97 | #define _ACL_ACCESS_EXISTS (NULL) | 96 | #define _ACL_ACCESS_EXISTS (NULL) |
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index 51c09c114a20..9381b0360c4b 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h | |||
@@ -197,6 +197,10 @@ typedef struct xfs_perag | |||
197 | #endif | 197 | #endif |
198 | xfs_perag_busy_t *pagb_list; /* unstable blocks */ | 198 | xfs_perag_busy_t *pagb_list; /* unstable blocks */ |
199 | atomic_t pagf_fstrms; /* # of filestreams active in this AG */ | 199 | atomic_t pagf_fstrms; /* # of filestreams active in this AG */ |
200 | |||
201 | int pag_ici_init; /* incore inode cache initialised */ | ||
202 | rwlock_t pag_ici_lock; /* incore inode lock */ | ||
203 | struct radix_tree_root pag_ici_root; /* incore inode cache root */ | ||
200 | } xfs_perag_t; | 204 | } xfs_perag_t; |
201 | 205 | ||
202 | #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) | 206 | #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 7ce44a7b88a2..93fa64dd1be6 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include "xfs_trans_space.h" | 49 | #include "xfs_trans_space.h" |
50 | #include "xfs_acl.h" | 50 | #include "xfs_acl.h" |
51 | #include "xfs_rw.h" | 51 | #include "xfs_rw.h" |
52 | #include "xfs_vnodeops.h" | ||
52 | 53 | ||
53 | /* | 54 | /* |
54 | * xfs_attr.c | 55 | * xfs_attr.c |
@@ -156,10 +157,14 @@ xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen, | |||
156 | } | 157 | } |
157 | 158 | ||
158 | int | 159 | int |
159 | xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp, | 160 | xfs_attr_get( |
160 | int flags, struct cred *cred) | 161 | xfs_inode_t *ip, |
162 | const char *name, | ||
163 | char *value, | ||
164 | int *valuelenp, | ||
165 | int flags, | ||
166 | cred_t *cred) | ||
161 | { | 167 | { |
162 | xfs_inode_t *ip = XFS_BHVTOI(bdp); | ||
163 | int error, namelen; | 168 | int error, namelen; |
164 | 169 | ||
165 | XFS_STATS_INC(xs_attr_get); | 170 | XFS_STATS_INC(xs_attr_get); |
@@ -417,10 +422,13 @@ out: | |||
417 | } | 422 | } |
418 | 423 | ||
419 | int | 424 | int |
420 | xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int flags, | 425 | xfs_attr_set( |
421 | struct cred *cred) | 426 | xfs_inode_t *dp, |
427 | const char *name, | ||
428 | char *value, | ||
429 | int valuelen, | ||
430 | int flags) | ||
422 | { | 431 | { |
423 | xfs_inode_t *dp; | ||
424 | int namelen; | 432 | int namelen; |
425 | 433 | ||
426 | namelen = strlen(name); | 434 | namelen = strlen(name); |
@@ -429,7 +437,6 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f | |||
429 | 437 | ||
430 | XFS_STATS_INC(xs_attr_set); | 438 | XFS_STATS_INC(xs_attr_set); |
431 | 439 | ||
432 | dp = XFS_BHVTOI(bdp); | ||
433 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 440 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
434 | return (EIO); | 441 | return (EIO); |
435 | 442 | ||
@@ -563,10 +570,12 @@ out: | |||
563 | } | 570 | } |
564 | 571 | ||
565 | int | 572 | int |
566 | xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred) | 573 | xfs_attr_remove( |
574 | xfs_inode_t *dp, | ||
575 | const char *name, | ||
576 | int flags) | ||
567 | { | 577 | { |
568 | xfs_inode_t *dp; | 578 | int namelen; |
569 | int namelen; | ||
570 | 579 | ||
571 | namelen = strlen(name); | 580 | namelen = strlen(name); |
572 | if (namelen >= MAXNAMELEN) | 581 | if (namelen >= MAXNAMELEN) |
@@ -574,7 +583,6 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred) | |||
574 | 583 | ||
575 | XFS_STATS_INC(xs_attr_remove); | 584 | XFS_STATS_INC(xs_attr_remove); |
576 | 585 | ||
577 | dp = XFS_BHVTOI(bdp); | ||
578 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 586 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
579 | return (EIO); | 587 | return (EIO); |
580 | 588 | ||
@@ -702,11 +710,14 @@ xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp, | |||
702 | * success. | 710 | * success. |
703 | */ | 711 | */ |
704 | int | 712 | int |
705 | xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, | 713 | xfs_attr_list( |
706 | attrlist_cursor_kern_t *cursor, struct cred *cred) | 714 | xfs_inode_t *dp, |
715 | char *buffer, | ||
716 | int bufsize, | ||
717 | int flags, | ||
718 | attrlist_cursor_kern_t *cursor) | ||
707 | { | 719 | { |
708 | xfs_attr_list_context_t context; | 720 | xfs_attr_list_context_t context; |
709 | xfs_inode_t *dp; | ||
710 | int error; | 721 | int error; |
711 | 722 | ||
712 | XFS_STATS_INC(xs_attr_list); | 723 | XFS_STATS_INC(xs_attr_list); |
@@ -731,7 +742,7 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, | |||
731 | /* | 742 | /* |
732 | * Initialize the output buffer. | 743 | * Initialize the output buffer. |
733 | */ | 744 | */ |
734 | context.dp = dp = XFS_BHVTOI(bdp); | 745 | context.dp = dp; |
735 | context.cursor = cursor; | 746 | context.cursor = cursor; |
736 | context.count = 0; | 747 | context.count = 0; |
737 | context.dupcnt = 0; | 748 | context.dupcnt = 0; |
@@ -2502,7 +2513,7 @@ STATIC int | |||
2502 | attr_generic_set( | 2513 | attr_generic_set( |
2503 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) | 2514 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) |
2504 | { | 2515 | { |
2505 | return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL); | 2516 | return -xfs_attr_set(xfs_vtoi(vp), name, data, size, xflags); |
2506 | } | 2517 | } |
2507 | 2518 | ||
2508 | STATIC int | 2519 | STATIC int |
@@ -2511,7 +2522,8 @@ attr_generic_get( | |||
2511 | { | 2522 | { |
2512 | int error, asize = size; | 2523 | int error, asize = size; |
2513 | 2524 | ||
2514 | error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL); | 2525 | error = xfs_attr_get(xfs_vtoi(vp), name, data, |
2526 | &asize, xflags, NULL); | ||
2515 | if (!error) | 2527 | if (!error) |
2516 | return asize; | 2528 | return asize; |
2517 | return -error; | 2529 | return -error; |
@@ -2521,7 +2533,7 @@ STATIC int | |||
2521 | attr_generic_remove( | 2533 | attr_generic_remove( |
2522 | bhv_vnode_t *vp, char *name, int xflags) | 2534 | bhv_vnode_t *vp, char *name, int xflags) |
2523 | { | 2535 | { |
2524 | return -bhv_vop_attr_remove(vp, name, xflags, NULL); | 2536 | return -xfs_attr_remove(xfs_vtoi(vp), name, xflags); |
2525 | } | 2537 | } |
2526 | 2538 | ||
2527 | STATIC int | 2539 | STATIC int |
@@ -2576,7 +2588,7 @@ attr_generic_list( | |||
2576 | attrlist_cursor_kern_t cursor = { 0 }; | 2588 | attrlist_cursor_kern_t cursor = { 0 }; |
2577 | int error; | 2589 | int error; |
2578 | 2590 | ||
2579 | error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL); | 2591 | error = xfs_attr_list(xfs_vtoi(vp), data, size, xflags, &cursor); |
2580 | if (error > 0) | 2592 | if (error > 0) |
2581 | return -error; | 2593 | return -error; |
2582 | *result = -error; | 2594 | *result = -error; |
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index 783977d3ea71..786eba3121c4 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h | |||
@@ -36,14 +36,13 @@ | |||
36 | *========================================================================*/ | 36 | *========================================================================*/ |
37 | 37 | ||
38 | struct cred; | 38 | struct cred; |
39 | struct bhv_vnode; | ||
40 | struct xfs_attr_list_context; | 39 | struct xfs_attr_list_context; |
41 | 40 | ||
42 | typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int); | 41 | typedef int (*attrset_t)(bhv_vnode_t *, char *, void *, size_t, int); |
43 | typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int); | 42 | typedef int (*attrget_t)(bhv_vnode_t *, char *, void *, size_t, int); |
44 | typedef int (*attrremove_t)(struct bhv_vnode *, char *, int); | 43 | typedef int (*attrremove_t)(bhv_vnode_t *, char *, int); |
45 | typedef int (*attrexists_t)(struct bhv_vnode *); | 44 | typedef int (*attrexists_t)(bhv_vnode_t *); |
46 | typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *); | 45 | typedef int (*attrcapable_t)(bhv_vnode_t *, struct cred *); |
47 | 46 | ||
48 | typedef struct attrnames { | 47 | typedef struct attrnames { |
49 | char * attr_name; | 48 | char * attr_name; |
@@ -64,7 +63,7 @@ extern struct attrnames attr_trusted; | |||
64 | extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; | 63 | extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; |
65 | 64 | ||
66 | extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); | 65 | extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); |
67 | extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *); | 66 | extern int attr_generic_list(bhv_vnode_t *, void *, size_t, int, ssize_t *); |
68 | 67 | ||
69 | #define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ | 68 | #define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ |
70 | #define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ | 69 | #define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ |
@@ -159,12 +158,8 @@ struct xfs_da_args; | |||
159 | /* | 158 | /* |
160 | * Overall external interface routines. | 159 | * Overall external interface routines. |
161 | */ | 160 | */ |
162 | int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *); | ||
163 | int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *); | ||
164 | int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int); | 161 | int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int); |
165 | int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *); | ||
166 | int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int); | 162 | int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int); |
167 | int xfs_attr_list(bhv_desc_t *, char *, int, int, struct attrlist_cursor_kern *, struct cred *); | ||
168 | int xfs_attr_list_int(struct xfs_attr_list_context *); | 163 | int xfs_attr_list_int(struct xfs_attr_list_context *); |
169 | int xfs_attr_inactive(struct xfs_inode *dp); | 164 | int xfs_attr_inactive(struct xfs_inode *dp); |
170 | 165 | ||
diff --git a/fs/xfs/xfs_behavior.c b/fs/xfs/xfs_behavior.c deleted file mode 100644 index 0dc17219d412..000000000000 --- a/fs/xfs/xfs_behavior.c +++ /dev/null | |||
@@ -1,183 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | |||
20 | /* | ||
21 | * Source file used to associate/disassociate behaviors with virtualized | ||
22 | * objects. See xfs_behavior.h for more information about behaviors, etc. | ||
23 | * | ||
24 | * The implementation is split between functions in this file and macros | ||
25 | * in xfs_behavior.h. | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * Insert a new behavior descriptor into a behavior chain. | ||
30 | * | ||
31 | * The behavior chain is ordered based on the 'position' number which | ||
32 | * lives in the first field of the ops vector (higher numbers first). | ||
33 | * | ||
34 | * Attempts to insert duplicate ops result in an EINVAL return code. | ||
35 | * Otherwise, return 0 to indicate success. | ||
36 | */ | ||
37 | int | ||
38 | bhv_insert(bhv_head_t *bhp, bhv_desc_t *bdp) | ||
39 | { | ||
40 | bhv_desc_t *curdesc, *prev; | ||
41 | int position; | ||
42 | |||
43 | /* | ||
44 | * Validate the position value of the new behavior. | ||
45 | */ | ||
46 | position = BHV_POSITION(bdp); | ||
47 | ASSERT(position >= BHV_POSITION_BASE && position <= BHV_POSITION_TOP); | ||
48 | |||
49 | /* | ||
50 | * Find location to insert behavior. Check for duplicates. | ||
51 | */ | ||
52 | prev = NULL; | ||
53 | for (curdesc = bhp->bh_first; | ||
54 | curdesc != NULL; | ||
55 | curdesc = curdesc->bd_next) { | ||
56 | |||
57 | /* Check for duplication. */ | ||
58 | if (curdesc->bd_ops == bdp->bd_ops) { | ||
59 | ASSERT(0); | ||
60 | return EINVAL; | ||
61 | } | ||
62 | |||
63 | /* Find correct position */ | ||
64 | if (position >= BHV_POSITION(curdesc)) { | ||
65 | ASSERT(position != BHV_POSITION(curdesc)); | ||
66 | break; /* found it */ | ||
67 | } | ||
68 | |||
69 | prev = curdesc; | ||
70 | } | ||
71 | |||
72 | if (prev == NULL) { | ||
73 | /* insert at front of chain */ | ||
74 | bdp->bd_next = bhp->bh_first; | ||
75 | bhp->bh_first = bdp; | ||
76 | } else { | ||
77 | /* insert after prev */ | ||
78 | bdp->bd_next = prev->bd_next; | ||
79 | prev->bd_next = bdp; | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Remove a behavior descriptor from a position in a behavior chain; | ||
87 | * the position is guaranteed not to be the first position. | ||
88 | * Should only be called by the bhv_remove() macro. | ||
89 | */ | ||
90 | void | ||
91 | bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp) | ||
92 | { | ||
93 | bhv_desc_t *curdesc, *prev; | ||
94 | |||
95 | ASSERT(bhp->bh_first != NULL); | ||
96 | ASSERT(bhp->bh_first->bd_next != NULL); | ||
97 | |||
98 | prev = bhp->bh_first; | ||
99 | for (curdesc = bhp->bh_first->bd_next; | ||
100 | curdesc != NULL; | ||
101 | curdesc = curdesc->bd_next) { | ||
102 | |||
103 | if (curdesc == bdp) | ||
104 | break; /* found it */ | ||
105 | prev = curdesc; | ||
106 | } | ||
107 | |||
108 | ASSERT(curdesc == bdp); | ||
109 | prev->bd_next = bdp->bd_next; /* remove from after prev */ | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * Looks for the first behavior within a specified range of positions. | ||
114 | * Return the associated behavior descriptor. Or NULL, if none found. | ||
115 | */ | ||
116 | bhv_desc_t * | ||
117 | bhv_lookup_range(bhv_head_t *bhp, int low, int high) | ||
118 | { | ||
119 | bhv_desc_t *curdesc; | ||
120 | |||
121 | for (curdesc = bhp->bh_first; | ||
122 | curdesc != NULL; | ||
123 | curdesc = curdesc->bd_next) { | ||
124 | |||
125 | int position = BHV_POSITION(curdesc); | ||
126 | |||
127 | if (position <= high) { | ||
128 | if (position >= low) | ||
129 | return curdesc; | ||
130 | return NULL; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | return NULL; | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Return the base behavior in the chain, or NULL if the chain | ||
139 | * is empty. | ||
140 | * | ||
141 | * The caller has not read locked the behavior chain, so acquire the | ||
142 | * lock before traversing the chain. | ||
143 | */ | ||
144 | bhv_desc_t * | ||
145 | bhv_base(bhv_head_t *bhp) | ||
146 | { | ||
147 | bhv_desc_t *curdesc; | ||
148 | |||
149 | for (curdesc = bhp->bh_first; | ||
150 | curdesc != NULL; | ||
151 | curdesc = curdesc->bd_next) { | ||
152 | |||
153 | if (curdesc->bd_next == NULL) { | ||
154 | return curdesc; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | return NULL; | ||
159 | } | ||
160 | |||
161 | void | ||
162 | bhv_head_init( | ||
163 | bhv_head_t *bhp, | ||
164 | char *name) | ||
165 | { | ||
166 | bhp->bh_first = NULL; | ||
167 | } | ||
168 | |||
169 | void | ||
170 | bhv_insert_initial( | ||
171 | bhv_head_t *bhp, | ||
172 | bhv_desc_t *bdp) | ||
173 | { | ||
174 | ASSERT(bhp->bh_first == NULL); | ||
175 | (bhp)->bh_first = bdp; | ||
176 | } | ||
177 | |||
178 | void | ||
179 | bhv_head_destroy( | ||
180 | bhv_head_t *bhp) | ||
181 | { | ||
182 | ASSERT(bhp->bh_first == NULL); | ||
183 | } | ||
diff --git a/fs/xfs/xfs_behavior.h b/fs/xfs/xfs_behavior.h deleted file mode 100644 index e7ca1fed955a..000000000000 --- a/fs/xfs/xfs_behavior.h +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_BEHAVIOR_H__ | ||
19 | #define __XFS_BEHAVIOR_H__ | ||
20 | |||
21 | /* | ||
22 | * Header file used to associate behaviors with virtualized objects. | ||
23 | * | ||
24 | * A virtualized object is an internal, virtualized representation of | ||
25 | * OS entities such as persistent files, processes, or sockets. Examples | ||
26 | * of virtualized objects include vnodes, vprocs, and vsockets. Often | ||
27 | * a virtualized object is referred to simply as an "object." | ||
28 | * | ||
29 | * A behavior is essentially an implementation layer associated with | ||
30 | * an object. Multiple behaviors for an object are chained together, | ||
31 | * the order of chaining determining the order of invocation. Each | ||
32 | * behavior of a given object implements the same set of interfaces | ||
33 | * (e.g., the VOP interfaces). | ||
34 | * | ||
35 | * Behaviors may be dynamically inserted into an object's behavior chain, | ||
36 | * such that the addition is transparent to consumers that already have | ||
37 | * references to the object. Typically, a given behavior will be inserted | ||
38 | * at a particular location in the behavior chain. Insertion of new | ||
39 | * behaviors is synchronized with operations-in-progress (oip's) so that | ||
40 | * the oip's always see a consistent view of the chain. | ||
41 | * | ||
42 | * The term "interposition" is used to refer to the act of inserting | ||
43 | * a behavior such that it interposes on (i.e., is inserted in front | ||
44 | * of) a particular other behavior. A key example of this is when a | ||
45 | * system implementing distributed single system image wishes to | ||
46 | * interpose a distribution layer (providing distributed coherency) | ||
47 | * in front of an object that is otherwise only accessed locally. | ||
48 | * | ||
49 | * Note that the traditional vnode/inode combination is simply a virtualized | ||
50 | * object that has exactly one associated behavior. | ||
51 | * | ||
52 | * Behavior synchronization is logic which is necessary under certain | ||
53 | * circumstances that there is no conflict between ongoing operations | ||
54 | * traversing the behavior chain and those dynamically modifying the | ||
55 | * behavior chain. Because behavior synchronization adds extra overhead | ||
56 | * to virtual operation invocation, we want to restrict, as much as | ||
57 | * we can, the requirement for this extra code, to those situations | ||
58 | * in which it is truly necessary. | ||
59 | * | ||
60 | * Behavior synchronization is needed whenever there's at least one class | ||
61 | * of object in the system for which: | ||
62 | * 1) multiple behaviors for a given object are supported, | ||
63 | * -- AND -- | ||
64 | * 2a) insertion of a new behavior can happen dynamically at any time during | ||
65 | * the life of an active object, | ||
66 | * -- AND -- | ||
67 | * 3a) insertion of a new behavior needs to synchronize with existing | ||
68 | * ops-in-progress. | ||
69 | * -- OR -- | ||
70 | * 3b) multiple different behaviors can be dynamically inserted at | ||
71 | * any time during the life of an active object | ||
72 | * -- OR -- | ||
73 | * 3c) removal of a behavior can occur at any time during the life of | ||
74 | * an active object. | ||
75 | * -- OR -- | ||
76 | * 2b) removal of a behavior can occur at any time during the life of an | ||
77 | * active object | ||
78 | * | ||
79 | */ | ||
80 | |||
81 | /* | ||
82 | * Behavior head. Head of the chain of behaviors. | ||
83 | * Contained within each virtualized object data structure. | ||
84 | */ | ||
85 | typedef struct bhv_head { | ||
86 | struct bhv_desc *bh_first; /* first behavior in chain */ | ||
87 | } bhv_head_t; | ||
88 | |||
89 | /* | ||
90 | * Behavior descriptor. Descriptor associated with each behavior. | ||
91 | * Contained within the behavior's private data structure. | ||
92 | */ | ||
93 | typedef struct bhv_desc { | ||
94 | void *bd_pdata; /* private data for this behavior */ | ||
95 | void *bd_vobj; /* virtual object associated with */ | ||
96 | void *bd_ops; /* ops for this behavior */ | ||
97 | struct bhv_desc *bd_next; /* next behavior in chain */ | ||
98 | } bhv_desc_t; | ||
99 | |||
100 | /* | ||
101 | * Behavior identity field. A behavior's identity determines the position | ||
102 | * where it lives within a behavior chain, and it's always the first field | ||
103 | * of the behavior's ops vector. The optional id field further identifies the | ||
104 | * subsystem responsible for the behavior. | ||
105 | */ | ||
106 | typedef struct bhv_identity { | ||
107 | __u16 bi_id; /* owning subsystem id */ | ||
108 | __u16 bi_position; /* position in chain */ | ||
109 | } bhv_identity_t; | ||
110 | |||
111 | typedef bhv_identity_t bhv_position_t; | ||
112 | |||
113 | #define BHV_IDENTITY_INIT(id,pos) {id, pos} | ||
114 | #define BHV_IDENTITY_INIT_POSITION(pos) BHV_IDENTITY_INIT(0, pos) | ||
115 | |||
116 | /* | ||
117 | * Define boundaries of position values. | ||
118 | */ | ||
119 | #define BHV_POSITION_INVALID 0 /* invalid position number */ | ||
120 | #define BHV_POSITION_BASE 1 /* base (last) implementation layer */ | ||
121 | #define BHV_POSITION_TOP 63 /* top (first) implementation layer */ | ||
122 | |||
123 | /* | ||
124 | * Plumbing macros. | ||
125 | */ | ||
126 | #define BHV_HEAD_FIRST(bhp) (ASSERT((bhp)->bh_first), (bhp)->bh_first) | ||
127 | #define BHV_NEXT(bdp) (ASSERT((bdp)->bd_next), (bdp)->bd_next) | ||
128 | #define BHV_NEXTNULL(bdp) ((bdp)->bd_next) | ||
129 | #define BHV_VOBJ(bdp) (ASSERT((bdp)->bd_vobj), (bdp)->bd_vobj) | ||
130 | #define BHV_VOBJNULL(bdp) ((bdp)->bd_vobj) | ||
131 | #define BHV_PDATA(bdp) (bdp)->bd_pdata | ||
132 | #define BHV_OPS(bdp) (bdp)->bd_ops | ||
133 | #define BHV_IDENTITY(bdp) ((bhv_identity_t *)(bdp)->bd_ops) | ||
134 | #define BHV_POSITION(bdp) (BHV_IDENTITY(bdp)->bi_position) | ||
135 | |||
136 | extern void bhv_head_init(bhv_head_t *, char *); | ||
137 | extern void bhv_head_destroy(bhv_head_t *); | ||
138 | extern int bhv_insert(bhv_head_t *, bhv_desc_t *); | ||
139 | extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *); | ||
140 | |||
141 | /* | ||
142 | * Initialize a new behavior descriptor. | ||
143 | * Arguments: | ||
144 | * bdp - pointer to behavior descriptor | ||
145 | * pdata - pointer to behavior's private data | ||
146 | * vobj - pointer to associated virtual object | ||
147 | * ops - pointer to ops for this behavior | ||
148 | */ | ||
149 | #define bhv_desc_init(bdp, pdata, vobj, ops) \ | ||
150 | { \ | ||
151 | (bdp)->bd_pdata = pdata; \ | ||
152 | (bdp)->bd_vobj = vobj; \ | ||
153 | (bdp)->bd_ops = ops; \ | ||
154 | (bdp)->bd_next = NULL; \ | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Remove a behavior descriptor from a behavior chain. | ||
159 | */ | ||
160 | #define bhv_remove(bhp, bdp) \ | ||
161 | { \ | ||
162 | if ((bhp)->bh_first == (bdp)) { \ | ||
163 | /* \ | ||
164 | * Remove from front of chain. \ | ||
165 | * Atomic wrt oip's. \ | ||
166 | */ \ | ||
167 | (bhp)->bh_first = (bdp)->bd_next; \ | ||
168 | } else { \ | ||
169 | /* remove from non-front of chain */ \ | ||
170 | bhv_remove_not_first(bhp, bdp); \ | ||
171 | } \ | ||
172 | (bdp)->bd_vobj = NULL; \ | ||
173 | } | ||
174 | |||
175 | /* | ||
176 | * Behavior module prototypes. | ||
177 | */ | ||
178 | extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp); | ||
179 | extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high); | ||
180 | extern bhv_desc_t * bhv_base(bhv_head_t *bhp); | ||
181 | |||
182 | /* No bhv locking on Linux */ | ||
183 | #define bhv_base_unlocked bhv_base | ||
184 | |||
185 | #endif /* __XFS_BEHAVIOR_H__ */ | ||
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 94b5c5fe2681..2e9b34b7344b 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include "xfs_trans_space.h" | 53 | #include "xfs_trans_space.h" |
54 | #include "xfs_buf_item.h" | 54 | #include "xfs_buf_item.h" |
55 | #include "xfs_filestream.h" | 55 | #include "xfs_filestream.h" |
56 | #include "xfs_vnodeops.h" | ||
56 | 57 | ||
57 | 58 | ||
58 | #ifdef DEBUG | 59 | #ifdef DEBUG |
@@ -248,7 +249,7 @@ xfs_bmap_local_to_extents( | |||
248 | * Else, *lastxp will be set to the index of the found | 249 | * Else, *lastxp will be set to the index of the found |
249 | * entry; *gotp will contain the entry. | 250 | * entry; *gotp will contain the entry. |
250 | */ | 251 | */ |
251 | STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ | 252 | STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ |
252 | xfs_bmap_search_extents( | 253 | xfs_bmap_search_extents( |
253 | xfs_inode_t *ip, /* incore inode pointer */ | 254 | xfs_inode_t *ip, /* incore inode pointer */ |
254 | xfs_fileoff_t bno, /* block number searched for */ | 255 | xfs_fileoff_t bno, /* block number searched for */ |
@@ -273,21 +274,6 @@ xfs_bmap_isaeof( | |||
273 | 274 | ||
274 | #ifdef XFS_BMAP_TRACE | 275 | #ifdef XFS_BMAP_TRACE |
275 | /* | 276 | /* |
276 | * Add a bmap trace buffer entry. Base routine for the others. | ||
277 | */ | ||
278 | STATIC void | ||
279 | xfs_bmap_trace_addentry( | ||
280 | int opcode, /* operation */ | ||
281 | const char *fname, /* function name */ | ||
282 | char *desc, /* operation description */ | ||
283 | xfs_inode_t *ip, /* incore inode pointer */ | ||
284 | xfs_extnum_t idx, /* index of entry(ies) */ | ||
285 | xfs_extnum_t cnt, /* count of entries, 1 or 2 */ | ||
286 | xfs_bmbt_rec_t *r1, /* first record */ | ||
287 | xfs_bmbt_rec_t *r2, /* second record or null */ | ||
288 | int whichfork); /* data or attr fork */ | ||
289 | |||
290 | /* | ||
291 | * Add bmap trace entry prior to a call to xfs_iext_remove. | 277 | * Add bmap trace entry prior to a call to xfs_iext_remove. |
292 | */ | 278 | */ |
293 | STATIC void | 279 | STATIC void |
@@ -714,7 +700,7 @@ xfs_bmap_add_extent_delay_real( | |||
714 | { | 700 | { |
715 | xfs_btree_cur_t *cur; /* btree cursor */ | 701 | xfs_btree_cur_t *cur; /* btree cursor */ |
716 | int diff; /* temp value */ | 702 | int diff; /* temp value */ |
717 | xfs_bmbt_rec_t *ep; /* extent entry for idx */ | 703 | xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ |
718 | int error; /* error return value */ | 704 | int error; /* error return value */ |
719 | int i; /* temp state */ | 705 | int i; /* temp state */ |
720 | xfs_ifork_t *ifp; /* inode fork pointer */ | 706 | xfs_ifork_t *ifp; /* inode fork pointer */ |
@@ -1270,7 +1256,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
1270 | xfs_extdelta_t *delta) /* Change made to incore extents */ | 1256 | xfs_extdelta_t *delta) /* Change made to incore extents */ |
1271 | { | 1257 | { |
1272 | xfs_btree_cur_t *cur; /* btree cursor */ | 1258 | xfs_btree_cur_t *cur; /* btree cursor */ |
1273 | xfs_bmbt_rec_t *ep; /* extent entry for idx */ | 1259 | xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ |
1274 | int error; /* error return value */ | 1260 | int error; /* error return value */ |
1275 | int i; /* temp state */ | 1261 | int i; /* temp state */ |
1276 | xfs_ifork_t *ifp; /* inode fork pointer */ | 1262 | xfs_ifork_t *ifp; /* inode fork pointer */ |
@@ -1823,7 +1809,7 @@ xfs_bmap_add_extent_hole_delay( | |||
1823 | xfs_extdelta_t *delta, /* Change made to incore extents */ | 1809 | xfs_extdelta_t *delta, /* Change made to incore extents */ |
1824 | int rsvd) /* OK to allocate reserved blocks */ | 1810 | int rsvd) /* OK to allocate reserved blocks */ |
1825 | { | 1811 | { |
1826 | xfs_bmbt_rec_t *ep; /* extent record for idx */ | 1812 | xfs_bmbt_rec_host_t *ep; /* extent record for idx */ |
1827 | xfs_ifork_t *ifp; /* inode fork pointer */ | 1813 | xfs_ifork_t *ifp; /* inode fork pointer */ |
1828 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ | 1814 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ |
1829 | xfs_filblks_t newlen=0; /* new indirect size */ | 1815 | xfs_filblks_t newlen=0; /* new indirect size */ |
@@ -2012,7 +1998,7 @@ xfs_bmap_add_extent_hole_real( | |||
2012 | xfs_extdelta_t *delta, /* Change made to incore extents */ | 1998 | xfs_extdelta_t *delta, /* Change made to incore extents */ |
2013 | int whichfork) /* data or attr fork */ | 1999 | int whichfork) /* data or attr fork */ |
2014 | { | 2000 | { |
2015 | xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ | 2001 | xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */ |
2016 | int error; /* error return value */ | 2002 | int error; /* error return value */ |
2017 | int i; /* temp state */ | 2003 | int i; /* temp state */ |
2018 | xfs_ifork_t *ifp; /* inode fork pointer */ | 2004 | xfs_ifork_t *ifp; /* inode fork pointer */ |
@@ -3070,7 +3056,7 @@ xfs_bmap_del_extent( | |||
3070 | xfs_fileoff_t del_endoff; /* first offset past del */ | 3056 | xfs_fileoff_t del_endoff; /* first offset past del */ |
3071 | int delay; /* current block is delayed allocated */ | 3057 | int delay; /* current block is delayed allocated */ |
3072 | int do_fx; /* free extent at end of routine */ | 3058 | int do_fx; /* free extent at end of routine */ |
3073 | xfs_bmbt_rec_t *ep; /* current extent entry pointer */ | 3059 | xfs_bmbt_rec_host_t *ep; /* current extent entry pointer */ |
3074 | int error; /* error return value */ | 3060 | int error; /* error return value */ |
3075 | int flags; /* inode logging flags */ | 3061 | int flags; /* inode logging flags */ |
3076 | xfs_bmbt_irec_t got; /* current extent entry */ | 3062 | xfs_bmbt_irec_t got; /* current extent entry */ |
@@ -3418,7 +3404,7 @@ xfs_bmap_extents_to_btree( | |||
3418 | xfs_bmbt_rec_t *arp; /* child record pointer */ | 3404 | xfs_bmbt_rec_t *arp; /* child record pointer */ |
3419 | xfs_bmbt_block_t *block; /* btree root block */ | 3405 | xfs_bmbt_block_t *block; /* btree root block */ |
3420 | xfs_btree_cur_t *cur; /* bmap btree cursor */ | 3406 | xfs_btree_cur_t *cur; /* bmap btree cursor */ |
3421 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 3407 | xfs_bmbt_rec_host_t *ep; /* extent record pointer */ |
3422 | int error; /* error return value */ | 3408 | int error; /* error return value */ |
3423 | xfs_extnum_t i, cnt; /* extent record index */ | 3409 | xfs_extnum_t i, cnt; /* extent record index */ |
3424 | xfs_ifork_t *ifp; /* inode fork pointer */ | 3410 | xfs_ifork_t *ifp; /* inode fork pointer */ |
@@ -3507,8 +3493,8 @@ xfs_bmap_extents_to_btree( | |||
3507 | for (cnt = i = 0; i < nextents; i++) { | 3493 | for (cnt = i = 0; i < nextents; i++) { |
3508 | ep = xfs_iext_get_ext(ifp, i); | 3494 | ep = xfs_iext_get_ext(ifp, i); |
3509 | if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { | 3495 | if (!ISNULLSTARTBLOCK(xfs_bmbt_get_startblock(ep))) { |
3510 | arp->l0 = INT_GET(ep->l0, ARCH_CONVERT); | 3496 | arp->l0 = cpu_to_be64(ep->l0); |
3511 | arp->l1 = INT_GET(ep->l1, ARCH_CONVERT); | 3497 | arp->l1 = cpu_to_be64(ep->l1); |
3512 | arp++; cnt++; | 3498 | arp++; cnt++; |
3513 | } | 3499 | } |
3514 | } | 3500 | } |
@@ -3590,7 +3576,7 @@ xfs_bmap_local_to_extents( | |||
3590 | if (ifp->if_bytes) { | 3576 | if (ifp->if_bytes) { |
3591 | xfs_alloc_arg_t args; /* allocation arguments */ | 3577 | xfs_alloc_arg_t args; /* allocation arguments */ |
3592 | xfs_buf_t *bp; /* buffer for extent block */ | 3578 | xfs_buf_t *bp; /* buffer for extent block */ |
3593 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 3579 | xfs_bmbt_rec_host_t *ep;/* extent record pointer */ |
3594 | 3580 | ||
3595 | args.tp = tp; | 3581 | args.tp = tp; |
3596 | args.mp = ip->i_mount; | 3582 | args.mp = ip->i_mount; |
@@ -3655,7 +3641,7 @@ done: | |||
3655 | * entry (null if none). Else, *lastxp will be set to the index | 3641 | * entry (null if none). Else, *lastxp will be set to the index |
3656 | * of the found entry; *gotp will contain the entry. | 3642 | * of the found entry; *gotp will contain the entry. |
3657 | */ | 3643 | */ |
3658 | xfs_bmbt_rec_t * /* pointer to found extent entry */ | 3644 | xfs_bmbt_rec_host_t * /* pointer to found extent entry */ |
3659 | xfs_bmap_search_multi_extents( | 3645 | xfs_bmap_search_multi_extents( |
3660 | xfs_ifork_t *ifp, /* inode fork pointer */ | 3646 | xfs_ifork_t *ifp, /* inode fork pointer */ |
3661 | xfs_fileoff_t bno, /* block number searched for */ | 3647 | xfs_fileoff_t bno, /* block number searched for */ |
@@ -3664,7 +3650,7 @@ xfs_bmap_search_multi_extents( | |||
3664 | xfs_bmbt_irec_t *gotp, /* out: extent entry found */ | 3650 | xfs_bmbt_irec_t *gotp, /* out: extent entry found */ |
3665 | xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ | 3651 | xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ |
3666 | { | 3652 | { |
3667 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 3653 | xfs_bmbt_rec_host_t *ep; /* extent record pointer */ |
3668 | xfs_extnum_t lastx; /* last extent index */ | 3654 | xfs_extnum_t lastx; /* last extent index */ |
3669 | 3655 | ||
3670 | /* | 3656 | /* |
@@ -3706,7 +3692,7 @@ xfs_bmap_search_multi_extents( | |||
3706 | * Else, *lastxp will be set to the index of the found | 3692 | * Else, *lastxp will be set to the index of the found |
3707 | * entry; *gotp will contain the entry. | 3693 | * entry; *gotp will contain the entry. |
3708 | */ | 3694 | */ |
3709 | STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ | 3695 | STATIC xfs_bmbt_rec_host_t * /* pointer to found extent entry */ |
3710 | xfs_bmap_search_extents( | 3696 | xfs_bmap_search_extents( |
3711 | xfs_inode_t *ip, /* incore inode pointer */ | 3697 | xfs_inode_t *ip, /* incore inode pointer */ |
3712 | xfs_fileoff_t bno, /* block number searched for */ | 3698 | xfs_fileoff_t bno, /* block number searched for */ |
@@ -3717,7 +3703,7 @@ xfs_bmap_search_extents( | |||
3717 | xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ | 3703 | xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */ |
3718 | { | 3704 | { |
3719 | xfs_ifork_t *ifp; /* inode fork pointer */ | 3705 | xfs_ifork_t *ifp; /* inode fork pointer */ |
3720 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 3706 | xfs_bmbt_rec_host_t *ep; /* extent record pointer */ |
3721 | 3707 | ||
3722 | XFS_STATS_INC(xs_look_exlist); | 3708 | XFS_STATS_INC(xs_look_exlist); |
3723 | ifp = XFS_IFORK_PTR(ip, fork); | 3709 | ifp = XFS_IFORK_PTR(ip, fork); |
@@ -3757,11 +3743,11 @@ xfs_bmap_trace_addentry( | |||
3757 | xfs_inode_t *ip, /* incore inode pointer */ | 3743 | xfs_inode_t *ip, /* incore inode pointer */ |
3758 | xfs_extnum_t idx, /* index of entry(ies) */ | 3744 | xfs_extnum_t idx, /* index of entry(ies) */ |
3759 | xfs_extnum_t cnt, /* count of entries, 1 or 2 */ | 3745 | xfs_extnum_t cnt, /* count of entries, 1 or 2 */ |
3760 | xfs_bmbt_rec_t *r1, /* first record */ | 3746 | xfs_bmbt_rec_host_t *r1, /* first record */ |
3761 | xfs_bmbt_rec_t *r2, /* second record or null */ | 3747 | xfs_bmbt_rec_host_t *r2, /* second record or null */ |
3762 | int whichfork) /* data or attr fork */ | 3748 | int whichfork) /* data or attr fork */ |
3763 | { | 3749 | { |
3764 | xfs_bmbt_rec_t tr2; | 3750 | xfs_bmbt_rec_host_t tr2; |
3765 | 3751 | ||
3766 | ASSERT(cnt == 1 || cnt == 2); | 3752 | ASSERT(cnt == 1 || cnt == 2); |
3767 | ASSERT(r1 != NULL); | 3753 | ASSERT(r1 != NULL); |
@@ -3842,8 +3828,8 @@ xfs_bmap_trace_insert( | |||
3842 | xfs_bmbt_irec_t *r2, /* inserted record 2 or null */ | 3828 | xfs_bmbt_irec_t *r2, /* inserted record 2 or null */ |
3843 | int whichfork) /* data or attr fork */ | 3829 | int whichfork) /* data or attr fork */ |
3844 | { | 3830 | { |
3845 | xfs_bmbt_rec_t tr1; /* compressed record 1 */ | 3831 | xfs_bmbt_rec_host_t tr1; /* compressed record 1 */ |
3846 | xfs_bmbt_rec_t tr2; /* compressed record 2 if needed */ | 3832 | xfs_bmbt_rec_host_t tr2; /* compressed record 2 if needed */ |
3847 | 3833 | ||
3848 | xfs_bmbt_set_all(&tr1, r1); | 3834 | xfs_bmbt_set_all(&tr1, r1); |
3849 | if (cnt == 2) { | 3835 | if (cnt == 2) { |
@@ -4316,7 +4302,6 @@ xfs_bmap_first_unused( | |||
4316 | xfs_fileoff_t *first_unused, /* unused block */ | 4302 | xfs_fileoff_t *first_unused, /* unused block */ |
4317 | int whichfork) /* data or attr fork */ | 4303 | int whichfork) /* data or attr fork */ |
4318 | { | 4304 | { |
4319 | xfs_bmbt_rec_t *ep; /* pointer to an extent entry */ | ||
4320 | int error; /* error return value */ | 4305 | int error; /* error return value */ |
4321 | int idx; /* extent record index */ | 4306 | int idx; /* extent record index */ |
4322 | xfs_ifork_t *ifp; /* inode fork pointer */ | 4307 | xfs_ifork_t *ifp; /* inode fork pointer */ |
@@ -4340,7 +4325,7 @@ xfs_bmap_first_unused( | |||
4340 | lowest = *first_unused; | 4325 | lowest = *first_unused; |
4341 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); | 4326 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); |
4342 | for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) { | 4327 | for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) { |
4343 | ep = xfs_iext_get_ext(ifp, idx); | 4328 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); |
4344 | off = xfs_bmbt_get_startoff(ep); | 4329 | off = xfs_bmbt_get_startoff(ep); |
4345 | /* | 4330 | /* |
4346 | * See if the hole before this extent will work. | 4331 | * See if the hole before this extent will work. |
@@ -4371,7 +4356,7 @@ xfs_bmap_last_before( | |||
4371 | { | 4356 | { |
4372 | xfs_fileoff_t bno; /* input file offset */ | 4357 | xfs_fileoff_t bno; /* input file offset */ |
4373 | int eof; /* hit end of file */ | 4358 | int eof; /* hit end of file */ |
4374 | xfs_bmbt_rec_t *ep; /* pointer to last extent */ | 4359 | xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ |
4375 | int error; /* error return value */ | 4360 | int error; /* error return value */ |
4376 | xfs_bmbt_irec_t got; /* current extent value */ | 4361 | xfs_bmbt_irec_t got; /* current extent value */ |
4377 | xfs_ifork_t *ifp; /* inode fork pointer */ | 4362 | xfs_ifork_t *ifp; /* inode fork pointer */ |
@@ -4417,7 +4402,7 @@ xfs_bmap_last_offset( | |||
4417 | xfs_fileoff_t *last_block, /* last block */ | 4402 | xfs_fileoff_t *last_block, /* last block */ |
4418 | int whichfork) /* data or attr fork */ | 4403 | int whichfork) /* data or attr fork */ |
4419 | { | 4404 | { |
4420 | xfs_bmbt_rec_t *ep; /* pointer to last extent */ | 4405 | xfs_bmbt_rec_host_t *ep; /* pointer to last extent */ |
4421 | int error; /* error return value */ | 4406 | int error; /* error return value */ |
4422 | xfs_ifork_t *ifp; /* inode fork pointer */ | 4407 | xfs_ifork_t *ifp; /* inode fork pointer */ |
4423 | xfs_extnum_t nextents; /* number of extent entries */ | 4408 | xfs_extnum_t nextents; /* number of extent entries */ |
@@ -4454,7 +4439,7 @@ xfs_bmap_one_block( | |||
4454 | xfs_inode_t *ip, /* incore inode */ | 4439 | xfs_inode_t *ip, /* incore inode */ |
4455 | int whichfork) /* data or attr fork */ | 4440 | int whichfork) /* data or attr fork */ |
4456 | { | 4441 | { |
4457 | xfs_bmbt_rec_t *ep; /* ptr to fork's extent */ | 4442 | xfs_bmbt_rec_host_t *ep; /* ptr to fork's extent */ |
4458 | xfs_ifork_t *ifp; /* inode fork pointer */ | 4443 | xfs_ifork_t *ifp; /* inode fork pointer */ |
4459 | int rval; /* return value */ | 4444 | int rval; /* return value */ |
4460 | xfs_bmbt_irec_t s; /* internal version of extent */ | 4445 | xfs_bmbt_irec_t s; /* internal version of extent */ |
@@ -4549,7 +4534,7 @@ xfs_bmap_read_extents( | |||
4549 | * Loop over all leaf nodes. Copy information to the extent records. | 4534 | * Loop over all leaf nodes. Copy information to the extent records. |
4550 | */ | 4535 | */ |
4551 | for (;;) { | 4536 | for (;;) { |
4552 | xfs_bmbt_rec_t *frp, *trp; | 4537 | xfs_bmbt_rec_t *frp; |
4553 | xfs_fsblock_t nextbno; | 4538 | xfs_fsblock_t nextbno; |
4554 | xfs_extnum_t num_recs; | 4539 | xfs_extnum_t num_recs; |
4555 | xfs_extnum_t start; | 4540 | xfs_extnum_t start; |
@@ -4581,9 +4566,9 @@ xfs_bmap_read_extents( | |||
4581 | frp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1); | 4566 | frp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1); |
4582 | start = i; | 4567 | start = i; |
4583 | for (j = 0; j < num_recs; j++, i++, frp++) { | 4568 | for (j = 0; j < num_recs; j++, i++, frp++) { |
4584 | trp = xfs_iext_get_ext(ifp, i); | 4569 | xfs_bmbt_rec_host_t *trp = xfs_iext_get_ext(ifp, i); |
4585 | trp->l0 = INT_GET(frp->l0, ARCH_CONVERT); | 4570 | trp->l0 = be64_to_cpu(frp->l0); |
4586 | trp->l1 = INT_GET(frp->l1, ARCH_CONVERT); | 4571 | trp->l1 = be64_to_cpu(frp->l1); |
4587 | } | 4572 | } |
4588 | if (exntf == XFS_EXTFMT_NOSTATE) { | 4573 | if (exntf == XFS_EXTFMT_NOSTATE) { |
4589 | /* | 4574 | /* |
@@ -4631,7 +4616,7 @@ xfs_bmap_trace_exlist( | |||
4631 | xfs_extnum_t cnt, /* count of entries in the list */ | 4616 | xfs_extnum_t cnt, /* count of entries in the list */ |
4632 | int whichfork) /* data or attr fork */ | 4617 | int whichfork) /* data or attr fork */ |
4633 | { | 4618 | { |
4634 | xfs_bmbt_rec_t *ep; /* current extent record */ | 4619 | xfs_bmbt_rec_host_t *ep; /* current extent record */ |
4635 | xfs_extnum_t idx; /* extent record index */ | 4620 | xfs_extnum_t idx; /* extent record index */ |
4636 | xfs_ifork_t *ifp; /* inode fork pointer */ | 4621 | xfs_ifork_t *ifp; /* inode fork pointer */ |
4637 | xfs_bmbt_irec_t s; /* file extent record */ | 4622 | xfs_bmbt_irec_t s; /* file extent record */ |
@@ -4727,7 +4712,7 @@ xfs_bmapi( | |||
4727 | xfs_btree_cur_t *cur; /* bmap btree cursor */ | 4712 | xfs_btree_cur_t *cur; /* bmap btree cursor */ |
4728 | xfs_fileoff_t end; /* end of mapped file region */ | 4713 | xfs_fileoff_t end; /* end of mapped file region */ |
4729 | int eof; /* we've hit the end of extents */ | 4714 | int eof; /* we've hit the end of extents */ |
4730 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 4715 | xfs_bmbt_rec_host_t *ep; /* extent record pointer */ |
4731 | int error; /* error return */ | 4716 | int error; /* error return */ |
4732 | xfs_bmbt_irec_t got; /* current file extent record */ | 4717 | xfs_bmbt_irec_t got; /* current file extent record */ |
4733 | xfs_ifork_t *ifp; /* inode fork pointer */ | 4718 | xfs_ifork_t *ifp; /* inode fork pointer */ |
@@ -5378,7 +5363,7 @@ xfs_bunmapi( | |||
5378 | xfs_btree_cur_t *cur; /* bmap btree cursor */ | 5363 | xfs_btree_cur_t *cur; /* bmap btree cursor */ |
5379 | xfs_bmbt_irec_t del; /* extent being deleted */ | 5364 | xfs_bmbt_irec_t del; /* extent being deleted */ |
5380 | int eof; /* is deleting at eof */ | 5365 | int eof; /* is deleting at eof */ |
5381 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 5366 | xfs_bmbt_rec_host_t *ep; /* extent record pointer */ |
5382 | int error; /* error return value */ | 5367 | int error; /* error return value */ |
5383 | xfs_extnum_t extno; /* extent number in list */ | 5368 | xfs_extnum_t extno; /* extent number in list */ |
5384 | xfs_bmbt_irec_t got; /* current extent record */ | 5369 | xfs_bmbt_irec_t got; /* current extent record */ |
@@ -5743,11 +5728,44 @@ error0: | |||
5743 | } | 5728 | } |
5744 | 5729 | ||
5745 | /* | 5730 | /* |
5731 | * returns 1 for success, 0 if we failed to map the extent. | ||
5732 | */ | ||
5733 | STATIC int | ||
5734 | xfs_getbmapx_fix_eof_hole( | ||
5735 | xfs_inode_t *ip, /* xfs incore inode pointer */ | ||
5736 | struct getbmap *out, /* output structure */ | ||
5737 | int prealloced, /* this is a file with | ||
5738 | * preallocated data space */ | ||
5739 | __int64_t end, /* last block requested */ | ||
5740 | xfs_fsblock_t startblock) | ||
5741 | { | ||
5742 | __int64_t fixlen; | ||
5743 | xfs_mount_t *mp; /* file system mount point */ | ||
5744 | |||
5745 | if (startblock == HOLESTARTBLOCK) { | ||
5746 | mp = ip->i_mount; | ||
5747 | out->bmv_block = -1; | ||
5748 | fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, ip->i_size)); | ||
5749 | fixlen -= out->bmv_offset; | ||
5750 | if (prealloced && out->bmv_offset + out->bmv_length == end) { | ||
5751 | /* Came to hole at EOF. Trim it. */ | ||
5752 | if (fixlen <= 0) | ||
5753 | return 0; | ||
5754 | out->bmv_length = fixlen; | ||
5755 | } | ||
5756 | } else { | ||
5757 | out->bmv_block = XFS_FSB_TO_DB(ip, startblock); | ||
5758 | } | ||
5759 | |||
5760 | return 1; | ||
5761 | } | ||
5762 | |||
5763 | /* | ||
5746 | * Fcntl interface to xfs_bmapi. | 5764 | * Fcntl interface to xfs_bmapi. |
5747 | */ | 5765 | */ |
5748 | int /* error code */ | 5766 | int /* error code */ |
5749 | xfs_getbmap( | 5767 | xfs_getbmap( |
5750 | bhv_desc_t *bdp, /* XFS behavior descriptor*/ | 5768 | xfs_inode_t *ip, |
5751 | struct getbmap *bmv, /* user bmap structure */ | 5769 | struct getbmap *bmv, /* user bmap structure */ |
5752 | void __user *ap, /* pointer to user's array */ | 5770 | void __user *ap, /* pointer to user's array */ |
5753 | int interface) /* interface flags */ | 5771 | int interface) /* interface flags */ |
@@ -5756,7 +5774,6 @@ xfs_getbmap( | |||
5756 | int error; /* return value */ | 5774 | int error; /* return value */ |
5757 | __int64_t fixlen; /* length for -1 case */ | 5775 | __int64_t fixlen; /* length for -1 case */ |
5758 | int i; /* extent number */ | 5776 | int i; /* extent number */ |
5759 | xfs_inode_t *ip; /* xfs incore inode pointer */ | ||
5760 | bhv_vnode_t *vp; /* corresponding vnode */ | 5777 | bhv_vnode_t *vp; /* corresponding vnode */ |
5761 | int lock; /* lock state */ | 5778 | int lock; /* lock state */ |
5762 | xfs_bmbt_irec_t *map; /* buffer for user's data */ | 5779 | xfs_bmbt_irec_t *map; /* buffer for user's data */ |
@@ -5774,8 +5791,7 @@ xfs_getbmap( | |||
5774 | int bmapi_flags; /* flags for xfs_bmapi */ | 5791 | int bmapi_flags; /* flags for xfs_bmapi */ |
5775 | __int32_t oflags; /* getbmapx bmv_oflags field */ | 5792 | __int32_t oflags; /* getbmapx bmv_oflags field */ |
5776 | 5793 | ||
5777 | vp = BHV_TO_VNODE(bdp); | 5794 | vp = XFS_ITOV(ip); |
5778 | ip = XFS_BHVTOI(bdp); | ||
5779 | mp = ip->i_mount; | 5795 | mp = ip->i_mount; |
5780 | 5796 | ||
5781 | whichfork = interface & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK; | 5797 | whichfork = interface & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK; |
@@ -5794,10 +5810,9 @@ xfs_getbmap( | |||
5794 | * could misinterpret holes in a DMAPI file as true holes, | 5810 | * could misinterpret holes in a DMAPI file as true holes, |
5795 | * when in fact they may represent offline user data. | 5811 | * when in fact they may represent offline user data. |
5796 | */ | 5812 | */ |
5797 | if ( (interface & BMV_IF_NO_DMAPI_READ) == 0 | 5813 | if ((interface & BMV_IF_NO_DMAPI_READ) == 0 && |
5798 | && DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) | 5814 | DM_EVENT_ENABLED(ip, DM_EVENT_READ) && |
5799 | && whichfork == XFS_DATA_FORK) { | 5815 | whichfork == XFS_DATA_FORK) { |
5800 | |||
5801 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 0, 0, 0, NULL); | 5816 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 0, 0, 0, NULL); |
5802 | if (error) | 5817 | if (error) |
5803 | return XFS_ERROR(error); | 5818 | return XFS_ERROR(error); |
@@ -5854,7 +5869,8 @@ xfs_getbmap( | |||
5854 | if (whichfork == XFS_DATA_FORK && | 5869 | if (whichfork == XFS_DATA_FORK && |
5855 | (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) { | 5870 | (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) { |
5856 | /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ | 5871 | /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ |
5857 | error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF); | 5872 | error = xfs_flush_pages(ip, (xfs_off_t)0, |
5873 | -1, 0, FI_REMAPF); | ||
5858 | } | 5874 | } |
5859 | 5875 | ||
5860 | ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); | 5876 | ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); |
@@ -5904,18 +5920,15 @@ xfs_getbmap( | |||
5904 | out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount); | 5920 | out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount); |
5905 | ASSERT(map[i].br_startblock != DELAYSTARTBLOCK); | 5921 | ASSERT(map[i].br_startblock != DELAYSTARTBLOCK); |
5906 | if (map[i].br_startblock == HOLESTARTBLOCK && | 5922 | if (map[i].br_startblock == HOLESTARTBLOCK && |
5907 | ((prealloced && out.bmv_offset + out.bmv_length == bmvend) || | 5923 | whichfork == XFS_ATTR_FORK) { |
5908 | whichfork == XFS_ATTR_FORK )) { | 5924 | /* came to the end of attribute fork */ |
5909 | /* | ||
5910 | * came to hole at end of file or the end of | ||
5911 | attribute fork | ||
5912 | */ | ||
5913 | goto unlock_and_return; | 5925 | goto unlock_and_return; |
5914 | } else { | 5926 | } else { |
5915 | out.bmv_block = | 5927 | if (!xfs_getbmapx_fix_eof_hole(ip, &out, |
5916 | (map[i].br_startblock == HOLESTARTBLOCK) ? | 5928 | prealloced, bmvend, |
5917 | -1 : | 5929 | map[i].br_startblock)) { |
5918 | XFS_FSB_TO_DB(ip, map[i].br_startblock); | 5930 | goto unlock_and_return; |
5931 | } | ||
5919 | 5932 | ||
5920 | /* return either getbmap/getbmapx structure. */ | 5933 | /* return either getbmap/getbmapx structure. */ |
5921 | if (interface & BMV_IF_EXTENDED) { | 5934 | if (interface & BMV_IF_EXTENDED) { |
@@ -5974,7 +5987,7 @@ xfs_bmap_isaeof( | |||
5974 | { | 5987 | { |
5975 | int error; /* error return value */ | 5988 | int error; /* error return value */ |
5976 | xfs_ifork_t *ifp; /* inode fork pointer */ | 5989 | xfs_ifork_t *ifp; /* inode fork pointer */ |
5977 | xfs_bmbt_rec_t *lastrec; /* extent record pointer */ | 5990 | xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */ |
5978 | xfs_extnum_t nextents; /* number of file extents */ | 5991 | xfs_extnum_t nextents; /* number of file extents */ |
5979 | xfs_bmbt_irec_t s; /* expanded extent record */ | 5992 | xfs_bmbt_irec_t s; /* expanded extent record */ |
5980 | 5993 | ||
@@ -6018,7 +6031,7 @@ xfs_bmap_eof( | |||
6018 | xfs_fsblock_t blockcount; /* extent block count */ | 6031 | xfs_fsblock_t blockcount; /* extent block count */ |
6019 | int error; /* error return value */ | 6032 | int error; /* error return value */ |
6020 | xfs_ifork_t *ifp; /* inode fork pointer */ | 6033 | xfs_ifork_t *ifp; /* inode fork pointer */ |
6021 | xfs_bmbt_rec_t *lastrec; /* extent record pointer */ | 6034 | xfs_bmbt_rec_host_t *lastrec; /* extent record pointer */ |
6022 | xfs_extnum_t nextents; /* number of file extents */ | 6035 | xfs_extnum_t nextents; /* number of file extents */ |
6023 | xfs_fileoff_t startoff; /* extent starting file offset */ | 6036 | xfs_fileoff_t startoff; /* extent starting file offset */ |
6024 | 6037 | ||
@@ -6465,10 +6478,9 @@ xfs_bmap_count_leaves( | |||
6465 | int *count) | 6478 | int *count) |
6466 | { | 6479 | { |
6467 | int b; | 6480 | int b; |
6468 | xfs_bmbt_rec_t *frp; | ||
6469 | 6481 | ||
6470 | for (b = 0; b < numrecs; b++) { | 6482 | for (b = 0; b < numrecs; b++) { |
6471 | frp = xfs_iext_get_ext(ifp, idx + b); | 6483 | xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b); |
6472 | *count += xfs_bmbt_get_blockcount(frp); | 6484 | *count += xfs_bmbt_get_blockcount(frp); |
6473 | } | 6485 | } |
6474 | return 0; | 6486 | return 0; |
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 524b1c9d5246..68267d75ff19 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h | |||
@@ -335,7 +335,7 @@ xfs_bunmapi( | |||
335 | */ | 335 | */ |
336 | int /* error code */ | 336 | int /* error code */ |
337 | xfs_getbmap( | 337 | xfs_getbmap( |
338 | bhv_desc_t *bdp, /* XFS behavior descriptor*/ | 338 | xfs_inode_t *ip, |
339 | struct getbmap *bmv, /* user bmap structure */ | 339 | struct getbmap *bmv, /* user bmap structure */ |
340 | void __user *ap, /* pointer to user's array */ | 340 | void __user *ap, /* pointer to user's array */ |
341 | int iflags); /* interface flags */ | 341 | int iflags); /* interface flags */ |
@@ -378,7 +378,7 @@ xfs_check_nostate_extents( | |||
378 | * entry (null if none). Else, *lastxp will be set to the index | 378 | * entry (null if none). Else, *lastxp will be set to the index |
379 | * of the found entry; *gotp will contain the entry. | 379 | * of the found entry; *gotp will contain the entry. |
380 | */ | 380 | */ |
381 | xfs_bmbt_rec_t * | 381 | xfs_bmbt_rec_host_t * |
382 | xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *, | 382 | xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *, |
383 | xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); | 383 | xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); |
384 | 384 | ||
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 89b891f51cfb..32b49ec00fb5 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -260,13 +260,14 @@ xfs_bmbt_trace_cursor( | |||
260 | char *s, | 260 | char *s, |
261 | int line) | 261 | int line) |
262 | { | 262 | { |
263 | xfs_bmbt_rec_t r; | 263 | xfs_bmbt_rec_host_t r; |
264 | 264 | ||
265 | xfs_bmbt_set_all(&r, &cur->bc_rec.b); | 265 | xfs_bmbt_set_all(&r, &cur->bc_rec.b); |
266 | xfs_bmbt_trace_enter(func, cur, s, XFS_BMBT_KTRACE_CUR, line, | 266 | xfs_bmbt_trace_enter(func, cur, s, XFS_BMBT_KTRACE_CUR, line, |
267 | (cur->bc_nlevels << 24) | (cur->bc_private.b.flags << 16) | | 267 | (cur->bc_nlevels << 24) | (cur->bc_private.b.flags << 16) | |
268 | cur->bc_private.b.allocated, | 268 | cur->bc_private.b.allocated, |
269 | INT_GET(r.l0, ARCH_CONVERT) >> 32, (int)INT_GET(r.l0, ARCH_CONVERT), INT_GET(r.l1, ARCH_CONVERT) >> 32, (int)INT_GET(r.l1, ARCH_CONVERT), | 269 | r.l0 >> 32, (int)r.l0, |
270 | r.l1 >> 32, (int)r.l1, | ||
270 | (unsigned long)cur->bc_bufs[0], (unsigned long)cur->bc_bufs[1], | 271 | (unsigned long)cur->bc_bufs[0], (unsigned long)cur->bc_bufs[1], |
271 | (unsigned long)cur->bc_bufs[2], (unsigned long)cur->bc_bufs[3], | 272 | (unsigned long)cur->bc_bufs[2], (unsigned long)cur->bc_bufs[3], |
272 | (cur->bc_ptrs[0] << 16) | cur->bc_ptrs[1], | 273 | (cur->bc_ptrs[0] << 16) | cur->bc_ptrs[1], |
@@ -383,7 +384,7 @@ xfs_bmbt_delrec( | |||
383 | if (ptr < numrecs) { | 384 | if (ptr < numrecs) { |
384 | memmove(&kp[ptr - 1], &kp[ptr], | 385 | memmove(&kp[ptr - 1], &kp[ptr], |
385 | (numrecs - ptr) * sizeof(*kp)); | 386 | (numrecs - ptr) * sizeof(*kp)); |
386 | memmove(&pp[ptr - 1], &pp[ptr], /* INT_: direct copy */ | 387 | memmove(&pp[ptr - 1], &pp[ptr], |
387 | (numrecs - ptr) * sizeof(*pp)); | 388 | (numrecs - ptr) * sizeof(*pp)); |
388 | xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1); | 389 | xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1); |
389 | xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1); | 390 | xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1); |
@@ -815,7 +816,7 @@ xfs_bmbt_insrec( | |||
815 | #endif | 816 | #endif |
816 | memmove(&kp[ptr], &kp[ptr - 1], | 817 | memmove(&kp[ptr], &kp[ptr - 1], |
817 | (numrecs - ptr + 1) * sizeof(*kp)); | 818 | (numrecs - ptr + 1) * sizeof(*kp)); |
818 | memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */ | 819 | memmove(&pp[ptr], &pp[ptr - 1], |
819 | (numrecs - ptr + 1) * sizeof(*pp)); | 820 | (numrecs - ptr + 1) * sizeof(*pp)); |
820 | #ifdef DEBUG | 821 | #ifdef DEBUG |
821 | if ((error = xfs_btree_check_lptr(cur, *bnop, level))) { | 822 | if ((error = xfs_btree_check_lptr(cur, *bnop, level))) { |
@@ -1250,7 +1251,7 @@ xfs_bmbt_lshift( | |||
1250 | return error; | 1251 | return error; |
1251 | } | 1252 | } |
1252 | #endif | 1253 | #endif |
1253 | *lpp = *rpp; /* INT_: direct copy */ | 1254 | *lpp = *rpp; |
1254 | xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs); | 1255 | xfs_bmbt_log_ptrs(cur, lbp, lrecs, lrecs); |
1255 | } else { | 1256 | } else { |
1256 | lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur); | 1257 | lrp = XFS_BMAP_REC_IADDR(left, lrecs, cur); |
@@ -1388,7 +1389,7 @@ xfs_bmbt_rshift( | |||
1388 | } | 1389 | } |
1389 | #endif | 1390 | #endif |
1390 | *rkp = *lkp; | 1391 | *rkp = *lkp; |
1391 | *rpp = *lpp; /* INT_: direct copy */ | 1392 | *rpp = *lpp; |
1392 | xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); | 1393 | xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); |
1393 | xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); | 1394 | xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); |
1394 | } else { | 1395 | } else { |
@@ -1826,7 +1827,7 @@ __xfs_bmbt_get_all( | |||
1826 | 1827 | ||
1827 | void | 1828 | void |
1828 | xfs_bmbt_get_all( | 1829 | xfs_bmbt_get_all( |
1829 | xfs_bmbt_rec_t *r, | 1830 | xfs_bmbt_rec_host_t *r, |
1830 | xfs_bmbt_irec_t *s) | 1831 | xfs_bmbt_irec_t *s) |
1831 | { | 1832 | { |
1832 | __xfs_bmbt_get_all(r->l0, r->l1, s); | 1833 | __xfs_bmbt_get_all(r->l0, r->l1, s); |
@@ -1862,7 +1863,7 @@ xfs_bmbt_get_block( | |||
1862 | */ | 1863 | */ |
1863 | xfs_filblks_t | 1864 | xfs_filblks_t |
1864 | xfs_bmbt_get_blockcount( | 1865 | xfs_bmbt_get_blockcount( |
1865 | xfs_bmbt_rec_t *r) | 1866 | xfs_bmbt_rec_host_t *r) |
1866 | { | 1867 | { |
1867 | return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21)); | 1868 | return (xfs_filblks_t)(r->l1 & XFS_MASK64LO(21)); |
1868 | } | 1869 | } |
@@ -1872,7 +1873,7 @@ xfs_bmbt_get_blockcount( | |||
1872 | */ | 1873 | */ |
1873 | xfs_fsblock_t | 1874 | xfs_fsblock_t |
1874 | xfs_bmbt_get_startblock( | 1875 | xfs_bmbt_get_startblock( |
1875 | xfs_bmbt_rec_t *r) | 1876 | xfs_bmbt_rec_host_t *r) |
1876 | { | 1877 | { |
1877 | #if XFS_BIG_BLKNOS | 1878 | #if XFS_BIG_BLKNOS |
1878 | return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) | | 1879 | return (((xfs_fsblock_t)r->l0 & XFS_MASK64LO(9)) << 43) | |
@@ -1896,7 +1897,7 @@ xfs_bmbt_get_startblock( | |||
1896 | */ | 1897 | */ |
1897 | xfs_fileoff_t | 1898 | xfs_fileoff_t |
1898 | xfs_bmbt_get_startoff( | 1899 | xfs_bmbt_get_startoff( |
1899 | xfs_bmbt_rec_t *r) | 1900 | xfs_bmbt_rec_host_t *r) |
1900 | { | 1901 | { |
1901 | return ((xfs_fileoff_t)r->l0 & | 1902 | return ((xfs_fileoff_t)r->l0 & |
1902 | XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; | 1903 | XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; |
@@ -1904,7 +1905,7 @@ xfs_bmbt_get_startoff( | |||
1904 | 1905 | ||
1905 | xfs_exntst_t | 1906 | xfs_exntst_t |
1906 | xfs_bmbt_get_state( | 1907 | xfs_bmbt_get_state( |
1907 | xfs_bmbt_rec_t *r) | 1908 | xfs_bmbt_rec_host_t *r) |
1908 | { | 1909 | { |
1909 | int ext_flag; | 1910 | int ext_flag; |
1910 | 1911 | ||
@@ -1913,19 +1914,13 @@ xfs_bmbt_get_state( | |||
1913 | ext_flag); | 1914 | ext_flag); |
1914 | } | 1915 | } |
1915 | 1916 | ||
1916 | #ifndef XFS_NATIVE_HOST | ||
1917 | /* Endian flipping versions of the bmbt extraction functions */ | 1917 | /* Endian flipping versions of the bmbt extraction functions */ |
1918 | void | 1918 | void |
1919 | xfs_bmbt_disk_get_all( | 1919 | xfs_bmbt_disk_get_all( |
1920 | xfs_bmbt_rec_t *r, | 1920 | xfs_bmbt_rec_t *r, |
1921 | xfs_bmbt_irec_t *s) | 1921 | xfs_bmbt_irec_t *s) |
1922 | { | 1922 | { |
1923 | __uint64_t l0, l1; | 1923 | __xfs_bmbt_get_all(be64_to_cpu(r->l0), be64_to_cpu(r->l1), s); |
1924 | |||
1925 | l0 = INT_GET(r->l0, ARCH_CONVERT); | ||
1926 | l1 = INT_GET(r->l1, ARCH_CONVERT); | ||
1927 | |||
1928 | __xfs_bmbt_get_all(l0, l1, s); | ||
1929 | } | 1924 | } |
1930 | 1925 | ||
1931 | /* | 1926 | /* |
@@ -1935,7 +1930,7 @@ xfs_filblks_t | |||
1935 | xfs_bmbt_disk_get_blockcount( | 1930 | xfs_bmbt_disk_get_blockcount( |
1936 | xfs_bmbt_rec_t *r) | 1931 | xfs_bmbt_rec_t *r) |
1937 | { | 1932 | { |
1938 | return (xfs_filblks_t)(INT_GET(r->l1, ARCH_CONVERT) & XFS_MASK64LO(21)); | 1933 | return (xfs_filblks_t)(be64_to_cpu(r->l1) & XFS_MASK64LO(21)); |
1939 | } | 1934 | } |
1940 | 1935 | ||
1941 | /* | 1936 | /* |
@@ -1945,11 +1940,9 @@ xfs_fileoff_t | |||
1945 | xfs_bmbt_disk_get_startoff( | 1940 | xfs_bmbt_disk_get_startoff( |
1946 | xfs_bmbt_rec_t *r) | 1941 | xfs_bmbt_rec_t *r) |
1947 | { | 1942 | { |
1948 | return ((xfs_fileoff_t)INT_GET(r->l0, ARCH_CONVERT) & | 1943 | return ((xfs_fileoff_t)be64_to_cpu(r->l0) & |
1949 | XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; | 1944 | XFS_MASK64LO(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; |
1950 | } | 1945 | } |
1951 | #endif /* XFS_NATIVE_HOST */ | ||
1952 | |||
1953 | 1946 | ||
1954 | /* | 1947 | /* |
1955 | * Increment cursor by one record at the level. | 1948 | * Increment cursor by one record at the level. |
@@ -2290,185 +2283,131 @@ xfs_bmbt_newroot( | |||
2290 | } | 2283 | } |
2291 | 2284 | ||
2292 | /* | 2285 | /* |
2293 | * Set all the fields in a bmap extent record from the uncompressed form. | ||
2294 | */ | ||
2295 | void | ||
2296 | xfs_bmbt_set_all( | ||
2297 | xfs_bmbt_rec_t *r, | ||
2298 | xfs_bmbt_irec_t *s) | ||
2299 | { | ||
2300 | int extent_flag; | ||
2301 | |||
2302 | ASSERT((s->br_state == XFS_EXT_NORM) || | ||
2303 | (s->br_state == XFS_EXT_UNWRITTEN)); | ||
2304 | extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1; | ||
2305 | ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0); | ||
2306 | ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0); | ||
2307 | #if XFS_BIG_BLKNOS | ||
2308 | ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0); | ||
2309 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
2310 | ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | | ||
2311 | ((xfs_bmbt_rec_base_t)s->br_startblock >> 43); | ||
2312 | r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | | ||
2313 | ((xfs_bmbt_rec_base_t)s->br_blockcount & | ||
2314 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); | ||
2315 | #else /* !XFS_BIG_BLKNOS */ | ||
2316 | if (ISNULLSTARTBLOCK(s->br_startblock)) { | ||
2317 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
2318 | ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | | ||
2319 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); | ||
2320 | r->l1 = XFS_MASK64HI(11) | | ||
2321 | ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | | ||
2322 | ((xfs_bmbt_rec_base_t)s->br_blockcount & | ||
2323 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); | ||
2324 | } else { | ||
2325 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
2326 | ((xfs_bmbt_rec_base_t)s->br_startoff << 9); | ||
2327 | r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | | ||
2328 | ((xfs_bmbt_rec_base_t)s->br_blockcount & | ||
2329 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); | ||
2330 | } | ||
2331 | #endif /* XFS_BIG_BLKNOS */ | ||
2332 | } | ||
2333 | |||
2334 | /* | ||
2335 | * Set all the fields in a bmap extent record from the arguments. | 2286 | * Set all the fields in a bmap extent record from the arguments. |
2336 | */ | 2287 | */ |
2337 | void | 2288 | void |
2338 | xfs_bmbt_set_allf( | 2289 | xfs_bmbt_set_allf( |
2339 | xfs_bmbt_rec_t *r, | 2290 | xfs_bmbt_rec_host_t *r, |
2340 | xfs_fileoff_t o, | 2291 | xfs_fileoff_t startoff, |
2341 | xfs_fsblock_t b, | 2292 | xfs_fsblock_t startblock, |
2342 | xfs_filblks_t c, | 2293 | xfs_filblks_t blockcount, |
2343 | xfs_exntst_t v) | 2294 | xfs_exntst_t state) |
2344 | { | 2295 | { |
2345 | int extent_flag; | 2296 | int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; |
2297 | |||
2298 | ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); | ||
2299 | ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); | ||
2300 | ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); | ||
2346 | 2301 | ||
2347 | ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN)); | ||
2348 | extent_flag = (v == XFS_EXT_NORM) ? 0 : 1; | ||
2349 | ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); | ||
2350 | ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); | ||
2351 | #if XFS_BIG_BLKNOS | 2302 | #if XFS_BIG_BLKNOS |
2352 | ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); | 2303 | ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); |
2304 | |||
2353 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | | 2305 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | |
2354 | ((xfs_bmbt_rec_base_t)o << 9) | | 2306 | ((xfs_bmbt_rec_base_t)startoff << 9) | |
2355 | ((xfs_bmbt_rec_base_t)b >> 43); | 2307 | ((xfs_bmbt_rec_base_t)startblock >> 43); |
2356 | r->l1 = ((xfs_bmbt_rec_base_t)b << 21) | | 2308 | r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | |
2357 | ((xfs_bmbt_rec_base_t)c & | 2309 | ((xfs_bmbt_rec_base_t)blockcount & |
2358 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); | 2310 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); |
2359 | #else /* !XFS_BIG_BLKNOS */ | 2311 | #else /* !XFS_BIG_BLKNOS */ |
2360 | if (ISNULLSTARTBLOCK(b)) { | 2312 | if (ISNULLSTARTBLOCK(startblock)) { |
2361 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | | 2313 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | |
2362 | ((xfs_bmbt_rec_base_t)o << 9) | | 2314 | ((xfs_bmbt_rec_base_t)startoff << 9) | |
2363 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); | 2315 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(9); |
2364 | r->l1 = XFS_MASK64HI(11) | | 2316 | r->l1 = XFS_MASK64HI(11) | |
2365 | ((xfs_bmbt_rec_base_t)b << 21) | | 2317 | ((xfs_bmbt_rec_base_t)startblock << 21) | |
2366 | ((xfs_bmbt_rec_base_t)c & | 2318 | ((xfs_bmbt_rec_base_t)blockcount & |
2367 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); | 2319 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); |
2368 | } else { | 2320 | } else { |
2369 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | | 2321 | r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | |
2370 | ((xfs_bmbt_rec_base_t)o << 9); | 2322 | ((xfs_bmbt_rec_base_t)startoff << 9); |
2371 | r->l1 = ((xfs_bmbt_rec_base_t)b << 21) | | 2323 | r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | |
2372 | ((xfs_bmbt_rec_base_t)c & | 2324 | ((xfs_bmbt_rec_base_t)blockcount & |
2373 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); | 2325 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)); |
2374 | } | 2326 | } |
2375 | #endif /* XFS_BIG_BLKNOS */ | 2327 | #endif /* XFS_BIG_BLKNOS */ |
2376 | } | 2328 | } |
2377 | 2329 | ||
2378 | #ifndef XFS_NATIVE_HOST | ||
2379 | /* | 2330 | /* |
2380 | * Set all the fields in a bmap extent record from the uncompressed form. | 2331 | * Set all the fields in a bmap extent record from the uncompressed form. |
2381 | */ | 2332 | */ |
2382 | void | 2333 | void |
2383 | xfs_bmbt_disk_set_all( | 2334 | xfs_bmbt_set_all( |
2384 | xfs_bmbt_rec_t *r, | 2335 | xfs_bmbt_rec_host_t *r, |
2385 | xfs_bmbt_irec_t *s) | 2336 | xfs_bmbt_irec_t *s) |
2386 | { | 2337 | { |
2387 | int extent_flag; | 2338 | xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock, |
2388 | 2339 | s->br_blockcount, s->br_state); | |
2389 | ASSERT((s->br_state == XFS_EXT_NORM) || | ||
2390 | (s->br_state == XFS_EXT_UNWRITTEN)); | ||
2391 | extent_flag = (s->br_state == XFS_EXT_NORM) ? 0 : 1; | ||
2392 | ASSERT((s->br_startoff & XFS_MASK64HI(9)) == 0); | ||
2393 | ASSERT((s->br_blockcount & XFS_MASK64HI(43)) == 0); | ||
2394 | #if XFS_BIG_BLKNOS | ||
2395 | ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0); | ||
2396 | INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
2397 | ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | | ||
2398 | ((xfs_bmbt_rec_base_t)s->br_startblock >> 43)); | ||
2399 | INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | | ||
2400 | ((xfs_bmbt_rec_base_t)s->br_blockcount & | ||
2401 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); | ||
2402 | #else /* !XFS_BIG_BLKNOS */ | ||
2403 | if (ISNULLSTARTBLOCK(s->br_startblock)) { | ||
2404 | INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
2405 | ((xfs_bmbt_rec_base_t)s->br_startoff << 9) | | ||
2406 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); | ||
2407 | INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) | | ||
2408 | ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | | ||
2409 | ((xfs_bmbt_rec_base_t)s->br_blockcount & | ||
2410 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); | ||
2411 | } else { | ||
2412 | INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | | ||
2413 | ((xfs_bmbt_rec_base_t)s->br_startoff << 9)); | ||
2414 | INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)s->br_startblock << 21) | | ||
2415 | ((xfs_bmbt_rec_base_t)s->br_blockcount & | ||
2416 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); | ||
2417 | } | ||
2418 | #endif /* XFS_BIG_BLKNOS */ | ||
2419 | } | 2340 | } |
2420 | 2341 | ||
2342 | |||
2421 | /* | 2343 | /* |
2422 | * Set all the fields in a disk format bmap extent record from the arguments. | 2344 | * Set all the fields in a disk format bmap extent record from the arguments. |
2423 | */ | 2345 | */ |
2424 | void | 2346 | void |
2425 | xfs_bmbt_disk_set_allf( | 2347 | xfs_bmbt_disk_set_allf( |
2426 | xfs_bmbt_rec_t *r, | 2348 | xfs_bmbt_rec_t *r, |
2427 | xfs_fileoff_t o, | 2349 | xfs_fileoff_t startoff, |
2428 | xfs_fsblock_t b, | 2350 | xfs_fsblock_t startblock, |
2429 | xfs_filblks_t c, | 2351 | xfs_filblks_t blockcount, |
2430 | xfs_exntst_t v) | 2352 | xfs_exntst_t state) |
2431 | { | 2353 | { |
2432 | int extent_flag; | 2354 | int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; |
2355 | |||
2356 | ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); | ||
2357 | ASSERT((startoff & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); | ||
2358 | ASSERT((blockcount & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); | ||
2433 | 2359 | ||
2434 | ASSERT((v == XFS_EXT_NORM) || (v == XFS_EXT_UNWRITTEN)); | ||
2435 | extent_flag = (v == XFS_EXT_NORM) ? 0 : 1; | ||
2436 | ASSERT((o & XFS_MASK64HI(64-BMBT_STARTOFF_BITLEN)) == 0); | ||
2437 | ASSERT((c & XFS_MASK64HI(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); | ||
2438 | #if XFS_BIG_BLKNOS | 2360 | #if XFS_BIG_BLKNOS |
2439 | ASSERT((b & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); | 2361 | ASSERT((startblock & XFS_MASK64HI(64-BMBT_STARTBLOCK_BITLEN)) == 0); |
2440 | INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | | 2362 | |
2441 | ((xfs_bmbt_rec_base_t)o << 9) | | 2363 | r->l0 = cpu_to_be64( |
2442 | ((xfs_bmbt_rec_base_t)b >> 43)); | 2364 | ((xfs_bmbt_rec_base_t)extent_flag << 63) | |
2443 | INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) | | 2365 | ((xfs_bmbt_rec_base_t)startoff << 9) | |
2444 | ((xfs_bmbt_rec_base_t)c & | 2366 | ((xfs_bmbt_rec_base_t)startblock >> 43)); |
2445 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); | 2367 | r->l1 = cpu_to_be64( |
2368 | ((xfs_bmbt_rec_base_t)startblock << 21) | | ||
2369 | ((xfs_bmbt_rec_base_t)blockcount & | ||
2370 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); | ||
2446 | #else /* !XFS_BIG_BLKNOS */ | 2371 | #else /* !XFS_BIG_BLKNOS */ |
2447 | if (ISNULLSTARTBLOCK(b)) { | 2372 | if (ISNULLSTARTBLOCK(startblock)) { |
2448 | INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | | 2373 | r->l0 = cpu_to_be64( |
2449 | ((xfs_bmbt_rec_base_t)o << 9) | | 2374 | ((xfs_bmbt_rec_base_t)extent_flag << 63) | |
2450 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); | 2375 | ((xfs_bmbt_rec_base_t)startoff << 9) | |
2451 | INT_SET(r->l1, ARCH_CONVERT, XFS_MASK64HI(11) | | 2376 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(9)); |
2452 | ((xfs_bmbt_rec_base_t)b << 21) | | 2377 | r->l1 = cpu_to_be64(XFS_MASK64HI(11) | |
2453 | ((xfs_bmbt_rec_base_t)c & | 2378 | ((xfs_bmbt_rec_base_t)startblock << 21) | |
2379 | ((xfs_bmbt_rec_base_t)blockcount & | ||
2454 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); | 2380 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); |
2455 | } else { | 2381 | } else { |
2456 | INT_SET(r->l0, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)extent_flag << 63) | | 2382 | r->l0 = cpu_to_be64( |
2457 | ((xfs_bmbt_rec_base_t)o << 9)); | 2383 | ((xfs_bmbt_rec_base_t)extent_flag << 63) | |
2458 | INT_SET(r->l1, ARCH_CONVERT, ((xfs_bmbt_rec_base_t)b << 21) | | 2384 | ((xfs_bmbt_rec_base_t)startoff << 9)); |
2459 | ((xfs_bmbt_rec_base_t)c & | 2385 | r->l1 = cpu_to_be64( |
2460 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); | 2386 | ((xfs_bmbt_rec_base_t)startblock << 21) | |
2387 | ((xfs_bmbt_rec_base_t)blockcount & | ||
2388 | (xfs_bmbt_rec_base_t)XFS_MASK64LO(21))); | ||
2461 | } | 2389 | } |
2462 | #endif /* XFS_BIG_BLKNOS */ | 2390 | #endif /* XFS_BIG_BLKNOS */ |
2463 | } | 2391 | } |
2464 | #endif /* XFS_NATIVE_HOST */ | 2392 | |
2393 | /* | ||
2394 | * Set all the fields in a bmap extent record from the uncompressed form. | ||
2395 | */ | ||
2396 | void | ||
2397 | xfs_bmbt_disk_set_all( | ||
2398 | xfs_bmbt_rec_t *r, | ||
2399 | xfs_bmbt_irec_t *s) | ||
2400 | { | ||
2401 | xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock, | ||
2402 | s->br_blockcount, s->br_state); | ||
2403 | } | ||
2465 | 2404 | ||
2466 | /* | 2405 | /* |
2467 | * Set the blockcount field in a bmap extent record. | 2406 | * Set the blockcount field in a bmap extent record. |
2468 | */ | 2407 | */ |
2469 | void | 2408 | void |
2470 | xfs_bmbt_set_blockcount( | 2409 | xfs_bmbt_set_blockcount( |
2471 | xfs_bmbt_rec_t *r, | 2410 | xfs_bmbt_rec_host_t *r, |
2472 | xfs_filblks_t v) | 2411 | xfs_filblks_t v) |
2473 | { | 2412 | { |
2474 | ASSERT((v & XFS_MASK64HI(43)) == 0); | 2413 | ASSERT((v & XFS_MASK64HI(43)) == 0); |
@@ -2481,7 +2420,7 @@ xfs_bmbt_set_blockcount( | |||
2481 | */ | 2420 | */ |
2482 | void | 2421 | void |
2483 | xfs_bmbt_set_startblock( | 2422 | xfs_bmbt_set_startblock( |
2484 | xfs_bmbt_rec_t *r, | 2423 | xfs_bmbt_rec_host_t *r, |
2485 | xfs_fsblock_t v) | 2424 | xfs_fsblock_t v) |
2486 | { | 2425 | { |
2487 | #if XFS_BIG_BLKNOS | 2426 | #if XFS_BIG_BLKNOS |
@@ -2509,7 +2448,7 @@ xfs_bmbt_set_startblock( | |||
2509 | */ | 2448 | */ |
2510 | void | 2449 | void |
2511 | xfs_bmbt_set_startoff( | 2450 | xfs_bmbt_set_startoff( |
2512 | xfs_bmbt_rec_t *r, | 2451 | xfs_bmbt_rec_host_t *r, |
2513 | xfs_fileoff_t v) | 2452 | xfs_fileoff_t v) |
2514 | { | 2453 | { |
2515 | ASSERT((v & XFS_MASK64HI(9)) == 0); | 2454 | ASSERT((v & XFS_MASK64HI(9)) == 0); |
@@ -2523,7 +2462,7 @@ xfs_bmbt_set_startoff( | |||
2523 | */ | 2462 | */ |
2524 | void | 2463 | void |
2525 | xfs_bmbt_set_state( | 2464 | xfs_bmbt_set_state( |
2526 | xfs_bmbt_rec_t *r, | 2465 | xfs_bmbt_rec_host_t *r, |
2527 | xfs_exntst_t v) | 2466 | xfs_exntst_t v) |
2528 | { | 2467 | { |
2529 | ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN); | 2468 | ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN); |
@@ -2624,10 +2563,8 @@ xfs_check_nostate_extents( | |||
2624 | xfs_extnum_t idx, | 2563 | xfs_extnum_t idx, |
2625 | xfs_extnum_t num) | 2564 | xfs_extnum_t num) |
2626 | { | 2565 | { |
2627 | xfs_bmbt_rec_t *ep; | ||
2628 | |||
2629 | for (; num > 0; num--, idx++) { | 2566 | for (; num > 0; num--, idx++) { |
2630 | ep = xfs_iext_get_ext(ifp, idx); | 2567 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); |
2631 | if ((ep->l0 >> | 2568 | if ((ep->l0 >> |
2632 | (64 - BMBT_EXNTFLAG_BITLEN)) != 0) { | 2569 | (64 - BMBT_EXNTFLAG_BITLEN)) != 0) { |
2633 | ASSERT(0); | 2570 | ASSERT(0); |
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index a77b1b753d0c..2d950e975918 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h | |||
@@ -35,45 +35,16 @@ typedef struct xfs_bmdr_block { | |||
35 | 35 | ||
36 | /* | 36 | /* |
37 | * Bmap btree record and extent descriptor. | 37 | * Bmap btree record and extent descriptor. |
38 | * For 32-bit kernels, | ||
39 | * l0:31 is an extent flag (value 1 indicates non-normal). | ||
40 | * l0:0-30 and l1:9-31 are startoff. | ||
41 | * l1:0-8, l2:0-31, and l3:21-31 are startblock. | ||
42 | * l3:0-20 are blockcount. | ||
43 | * For 64-bit kernels, | ||
44 | * l0:63 is an extent flag (value 1 indicates non-normal). | 38 | * l0:63 is an extent flag (value 1 indicates non-normal). |
45 | * l0:9-62 are startoff. | 39 | * l0:9-62 are startoff. |
46 | * l0:0-8 and l1:21-63 are startblock. | 40 | * l0:0-8 and l1:21-63 are startblock. |
47 | * l1:0-20 are blockcount. | 41 | * l1:0-20 are blockcount. |
48 | */ | 42 | */ |
49 | |||
50 | #ifndef XFS_NATIVE_HOST | ||
51 | |||
52 | #define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */ | ||
53 | #define BMBT_EXNTFLAG_BITOFF 0 | ||
54 | #define BMBT_EXNTFLAG_BITLEN 1 | 43 | #define BMBT_EXNTFLAG_BITLEN 1 |
55 | #define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF + BMBT_EXNTFLAG_BITLEN) | ||
56 | #define BMBT_STARTOFF_BITLEN 54 | 44 | #define BMBT_STARTOFF_BITLEN 54 |
57 | #define BMBT_STARTBLOCK_BITOFF (BMBT_STARTOFF_BITOFF + BMBT_STARTOFF_BITLEN) | ||
58 | #define BMBT_STARTBLOCK_BITLEN 52 | 45 | #define BMBT_STARTBLOCK_BITLEN 52 |
59 | #define BMBT_BLOCKCOUNT_BITOFF \ | ||
60 | (BMBT_STARTBLOCK_BITOFF + BMBT_STARTBLOCK_BITLEN) | ||
61 | #define BMBT_BLOCKCOUNT_BITLEN (BMBT_TOTAL_BITLEN - BMBT_BLOCKCOUNT_BITOFF) | ||
62 | |||
63 | #else | ||
64 | |||
65 | #define BMBT_TOTAL_BITLEN 128 /* 128 bits, 16 bytes */ | ||
66 | #define BMBT_EXNTFLAG_BITOFF 63 | ||
67 | #define BMBT_EXNTFLAG_BITLEN 1 | ||
68 | #define BMBT_STARTOFF_BITOFF (BMBT_EXNTFLAG_BITOFF - BMBT_STARTOFF_BITLEN) | ||
69 | #define BMBT_STARTOFF_BITLEN 54 | ||
70 | #define BMBT_STARTBLOCK_BITOFF 85 /* 128 - 43 (other 9 is in first word) */ | ||
71 | #define BMBT_STARTBLOCK_BITLEN 52 | ||
72 | #define BMBT_BLOCKCOUNT_BITOFF 64 /* Start of second 64 bit container */ | ||
73 | #define BMBT_BLOCKCOUNT_BITLEN 21 | 46 | #define BMBT_BLOCKCOUNT_BITLEN 21 |
74 | 47 | ||
75 | #endif /* XFS_NATIVE_HOST */ | ||
76 | |||
77 | 48 | ||
78 | #define BMBT_USE_64 1 | 49 | #define BMBT_USE_64 1 |
79 | 50 | ||
@@ -83,12 +54,16 @@ typedef struct xfs_bmbt_rec_32 | |||
83 | } xfs_bmbt_rec_32_t; | 54 | } xfs_bmbt_rec_32_t; |
84 | typedef struct xfs_bmbt_rec_64 | 55 | typedef struct xfs_bmbt_rec_64 |
85 | { | 56 | { |
86 | __uint64_t l0, l1; | 57 | __be64 l0, l1; |
87 | } xfs_bmbt_rec_64_t; | 58 | } xfs_bmbt_rec_64_t; |
88 | 59 | ||
89 | typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ | 60 | typedef __uint64_t xfs_bmbt_rec_base_t; /* use this for casts */ |
90 | typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; | 61 | typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t; |
91 | 62 | ||
63 | typedef struct xfs_bmbt_rec_host { | ||
64 | __uint64_t l0, l1; | ||
65 | } xfs_bmbt_rec_host_t; | ||
66 | |||
92 | /* | 67 | /* |
93 | * Values and macros for delayed-allocation startblock fields. | 68 | * Values and macros for delayed-allocation startblock fields. |
94 | */ | 69 | */ |
@@ -281,23 +256,17 @@ extern ktrace_t *xfs_bmbt_trace_buf; | |||
281 | extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int); | 256 | extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int); |
282 | extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *); | 257 | extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *); |
283 | extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *); | 258 | extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *); |
284 | extern void xfs_bmbt_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); | 259 | extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); |
285 | extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur, | 260 | extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur, |
286 | int, struct xfs_buf **bpp); | 261 | int, struct xfs_buf **bpp); |
287 | extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_t *r); | 262 | extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r); |
288 | extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_t *r); | 263 | extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r); |
289 | extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_t *r); | 264 | extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r); |
290 | extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_t *r); | 265 | extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r); |
291 | 266 | ||
292 | #ifndef XFS_NATIVE_HOST | ||
293 | extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); | 267 | extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); |
294 | extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r); | 268 | extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r); |
295 | extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r); | 269 | extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r); |
296 | #else | ||
297 | #define xfs_bmbt_disk_get_all(r, s) xfs_bmbt_get_all(r, s) | ||
298 | #define xfs_bmbt_disk_get_blockcount(r) xfs_bmbt_get_blockcount(r) | ||
299 | #define xfs_bmbt_disk_get_startoff(r) xfs_bmbt_get_startoff(r) | ||
300 | #endif /* XFS_NATIVE_HOST */ | ||
301 | 270 | ||
302 | extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *); | 271 | extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *); |
303 | extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *); | 272 | extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *); |
@@ -315,22 +284,17 @@ extern int xfs_bmbt_lookup_ge(struct xfs_btree_cur *, xfs_fileoff_t, | |||
315 | */ | 284 | */ |
316 | extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat); | 285 | extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat); |
317 | 286 | ||
318 | extern void xfs_bmbt_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); | 287 | extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s); |
319 | extern void xfs_bmbt_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, | 288 | extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o, |
320 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); | 289 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); |
321 | extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_t *r, xfs_filblks_t v); | 290 | extern void xfs_bmbt_set_blockcount(xfs_bmbt_rec_host_t *r, xfs_filblks_t v); |
322 | extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_t *r, xfs_fsblock_t v); | 291 | extern void xfs_bmbt_set_startblock(xfs_bmbt_rec_host_t *r, xfs_fsblock_t v); |
323 | extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_t *r, xfs_fileoff_t v); | 292 | extern void xfs_bmbt_set_startoff(xfs_bmbt_rec_host_t *r, xfs_fileoff_t v); |
324 | extern void xfs_bmbt_set_state(xfs_bmbt_rec_t *r, xfs_exntst_t v); | 293 | extern void xfs_bmbt_set_state(xfs_bmbt_rec_host_t *r, xfs_exntst_t v); |
325 | 294 | ||
326 | #ifndef XFS_NATIVE_HOST | ||
327 | extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); | 295 | extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s); |
328 | extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, | 296 | extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o, |
329 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); | 297 | xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); |
330 | #else | ||
331 | #define xfs_bmbt_disk_set_all(r, s) xfs_bmbt_set_all(r, s) | ||
332 | #define xfs_bmbt_disk_set_allf(r, o, b, c, v) xfs_bmbt_set_allf(r, o, b, c, v) | ||
333 | #endif /* XFS_NATIVE_HOST */ | ||
334 | 298 | ||
335 | extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int); | 299 | extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int); |
336 | extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t, | 300 | extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t, |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index b0667cb27d66..c8f2c2886fe4 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "xfs_inum.h" | 23 | #include "xfs_inum.h" |
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | ||
26 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
28 | #include "xfs_buf_item.h" | 29 | #include "xfs_buf_item.h" |
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h index f89196cb08d2..d16c1b971074 100644 --- a/fs/xfs/xfs_clnt.h +++ b/fs/xfs/xfs_clnt.h | |||
@@ -89,7 +89,6 @@ struct xfs_mount_args { | |||
89 | #define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */ | 89 | #define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */ |
90 | #define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width | 90 | #define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width |
91 | * allocation */ | 91 | * allocation */ |
92 | #define XFSMNT_IHASHSIZE 0x20000000 /* inode hash table size */ | ||
93 | #define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename | 92 | #define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename |
94 | * symlink,mkdir,rmdir,mknod */ | 93 | * symlink,mkdir,rmdir,mknod */ |
95 | #define XFSMNT_FLAGS2 0x80000000 /* more flags set in flags2 */ | 94 | #define XFSMNT_FLAGS2 0x80000000 /* more flags set in flags2 */ |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index de35d18cc002..584f1ae85cd9 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "xfs_dfrag.h" | 42 | #include "xfs_dfrag.h" |
43 | #include "xfs_error.h" | 43 | #include "xfs_error.h" |
44 | #include "xfs_rw.h" | 44 | #include "xfs_rw.h" |
45 | #include "xfs_vnodeops.h" | ||
45 | 46 | ||
46 | /* | 47 | /* |
47 | * Syssgi interface for swapext | 48 | * Syssgi interface for swapext |
@@ -199,7 +200,8 @@ xfs_swap_extents( | |||
199 | 200 | ||
200 | if (VN_CACHED(tvp) != 0) { | 201 | if (VN_CACHED(tvp) != 0) { |
201 | xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); | 202 | xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); |
202 | error = bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED); | 203 | error = xfs_flushinval_pages(tip, 0, -1, |
204 | FI_REMAPF_LOCKED); | ||
203 | if (error) | 205 | if (error) |
204 | goto error0; | 206 | goto error0; |
205 | } | 207 | } |
@@ -265,7 +267,7 @@ xfs_swap_extents( | |||
265 | * fields change. | 267 | * fields change. |
266 | */ | 268 | */ |
267 | 269 | ||
268 | bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); | 270 | xfs_tosspages(ip, 0, -1, FI_REMAPF); |
269 | 271 | ||
270 | tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); | 272 | tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); |
271 | if ((error = xfs_trans_reserve(tp, 0, | 273 | if ((error = xfs_trans_reserve(tp, 0, |
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index fefd0116bac9..dedd713574e1 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h | |||
@@ -34,41 +34,41 @@ struct xfs_mount; | |||
34 | * because we only need the core part in the in-core inode. | 34 | * because we only need the core part in the in-core inode. |
35 | */ | 35 | */ |
36 | typedef struct xfs_timestamp { | 36 | typedef struct xfs_timestamp { |
37 | __int32_t t_sec; /* timestamp seconds */ | 37 | __be32 t_sec; /* timestamp seconds */ |
38 | __int32_t t_nsec; /* timestamp nanoseconds */ | 38 | __be32 t_nsec; /* timestamp nanoseconds */ |
39 | } xfs_timestamp_t; | 39 | } xfs_timestamp_t; |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * Note: Coordinate changes to this structure with the XFS_DI_* #defines | 42 | * Note: Coordinate changes to this structure with the XFS_DI_* #defines |
43 | * below and the offsets table in xfs_ialloc_log_di(). | 43 | * below, the offsets table in xfs_ialloc_log_di() and struct xfs_icdinode |
44 | * in xfs_inode.h. | ||
44 | */ | 45 | */ |
45 | typedef struct xfs_dinode_core | 46 | typedef struct xfs_dinode_core { |
46 | { | 47 | __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */ |
47 | __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ | 48 | __be16 di_mode; /* mode and type of file */ |
48 | __uint16_t di_mode; /* mode and type of file */ | 49 | __u8 di_version; /* inode version */ |
49 | __int8_t di_version; /* inode version */ | 50 | __u8 di_format; /* format of di_c data */ |
50 | __int8_t di_format; /* format of di_c data */ | 51 | __be16 di_onlink; /* old number of links to file */ |
51 | __uint16_t di_onlink; /* old number of links to file */ | 52 | __be32 di_uid; /* owner's user id */ |
52 | __uint32_t di_uid; /* owner's user id */ | 53 | __be32 di_gid; /* owner's group id */ |
53 | __uint32_t di_gid; /* owner's group id */ | 54 | __be32 di_nlink; /* number of links to file */ |
54 | __uint32_t di_nlink; /* number of links to file */ | 55 | __be16 di_projid; /* owner's project id */ |
55 | __uint16_t di_projid; /* owner's project id */ | 56 | __u8 di_pad[8]; /* unused, zeroed space */ |
56 | __uint8_t di_pad[8]; /* unused, zeroed space */ | 57 | __be16 di_flushiter; /* incremented on flush */ |
57 | __uint16_t di_flushiter; /* incremented on flush */ | ||
58 | xfs_timestamp_t di_atime; /* time last accessed */ | 58 | xfs_timestamp_t di_atime; /* time last accessed */ |
59 | xfs_timestamp_t di_mtime; /* time last modified */ | 59 | xfs_timestamp_t di_mtime; /* time last modified */ |
60 | xfs_timestamp_t di_ctime; /* time created/inode modified */ | 60 | xfs_timestamp_t di_ctime; /* time created/inode modified */ |
61 | xfs_fsize_t di_size; /* number of bytes in file */ | 61 | __be64 di_size; /* number of bytes in file */ |
62 | xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ | 62 | __be64 di_nblocks; /* # of direct & btree blocks used */ |
63 | xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ | 63 | __be32 di_extsize; /* basic/minimum extent size for file */ |
64 | xfs_extnum_t di_nextents; /* number of extents in data fork */ | 64 | __be32 di_nextents; /* number of extents in data fork */ |
65 | xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ | 65 | __be16 di_anextents; /* number of extents in attribute fork*/ |
66 | __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ | 66 | __u8 di_forkoff; /* attr fork offs, <<3 for 64b align */ |
67 | __int8_t di_aformat; /* format of attr fork's data */ | 67 | __s8 di_aformat; /* format of attr fork's data */ |
68 | __uint32_t di_dmevmask; /* DMIG event mask */ | 68 | __be32 di_dmevmask; /* DMIG event mask */ |
69 | __uint16_t di_dmstate; /* DMIG state info */ | 69 | __be16 di_dmstate; /* DMIG state info */ |
70 | __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ | 70 | __be16 di_flags; /* random flags, XFS_DIFLAG_... */ |
71 | __uint32_t di_gen; /* generation number */ | 71 | __be32 di_gen; /* generation number */ |
72 | } xfs_dinode_core_t; | 72 | } xfs_dinode_core_t; |
73 | 73 | ||
74 | #define DI_MAX_FLUSH 0xffff | 74 | #define DI_MAX_FLUSH 0xffff |
@@ -81,13 +81,13 @@ typedef struct xfs_dinode | |||
81 | * sure to update the macros like XFS_LITINO below and | 81 | * sure to update the macros like XFS_LITINO below and |
82 | * XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h. | 82 | * XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h. |
83 | */ | 83 | */ |
84 | xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */ | 84 | __be32 di_next_unlinked;/* agi unlinked list ptr */ |
85 | union { | 85 | union { |
86 | xfs_bmdr_block_t di_bmbt; /* btree root block */ | 86 | xfs_bmdr_block_t di_bmbt; /* btree root block */ |
87 | xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ | 87 | xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ |
88 | xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ | 88 | xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ |
89 | char di_c[1]; /* local contents */ | 89 | char di_c[1]; /* local contents */ |
90 | xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ | 90 | __be32 di_dev; /* device for S_IFCHR/S_IFBLK */ |
91 | uuid_t di_muuid; /* mount point value */ | 91 | uuid_t di_muuid; /* mount point value */ |
92 | char di_symlink[1]; /* local symbolic link */ | 92 | char di_symlink[1]; /* local symbolic link */ |
93 | } di_u; | 93 | } di_u; |
@@ -175,8 +175,7 @@ typedef enum xfs_dinode_fmt | |||
175 | #define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0) | 175 | #define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0) |
176 | 176 | ||
177 | #define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3)) | 177 | #define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3)) |
178 | #define XFS_CFORK_BOFF_DISK(dcp) \ | 178 | #define XFS_CFORK_BOFF_DISK(dcp) ((int)((dcp)->di_forkoff << 3)) |
179 | ((int)(INT_GET((dcp)->di_forkoff, ARCH_CONVERT) << 3)) | ||
180 | 179 | ||
181 | #define XFS_CFORK_DSIZE_DISK(dcp,mp) \ | 180 | #define XFS_CFORK_DSIZE_DISK(dcp,mp) \ |
182 | (XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp)) | 181 | (XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp)) |
@@ -225,8 +224,8 @@ typedef enum xfs_dinode_fmt | |||
225 | 224 | ||
226 | #define XFS_CFORK_NEXTENTS_DISK(dcp,w) \ | 225 | #define XFS_CFORK_NEXTENTS_DISK(dcp,w) \ |
227 | ((w) == XFS_DATA_FORK ? \ | 226 | ((w) == XFS_DATA_FORK ? \ |
228 | INT_GET((dcp)->di_nextents, ARCH_CONVERT) : \ | 227 | be32_to_cpu((dcp)->di_nextents) : \ |
229 | INT_GET((dcp)->di_anextents, ARCH_CONVERT)) | 228 | be16_to_cpu((dcp)->di_anextents)) |
230 | #define XFS_CFORK_NEXTENTS(dcp,w) \ | 229 | #define XFS_CFORK_NEXTENTS(dcp,w) \ |
231 | ((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents) | 230 | ((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents) |
232 | #define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w) | 231 | #define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w) |
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 29e091914df4..b0f1ee8fcb90 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
@@ -43,8 +43,6 @@ | |||
43 | #include "xfs_dir2_trace.h" | 43 | #include "xfs_dir2_trace.h" |
44 | #include "xfs_error.h" | 44 | #include "xfs_error.h" |
45 | 45 | ||
46 | static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); | ||
47 | static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); | ||
48 | 46 | ||
49 | void | 47 | void |
50 | xfs_dir_mount( | 48 | xfs_dir_mount( |
@@ -293,47 +291,33 @@ xfs_dir_removename( | |||
293 | * Read a directory. | 291 | * Read a directory. |
294 | */ | 292 | */ |
295 | int | 293 | int |
296 | xfs_dir_getdents( | 294 | xfs_readdir( |
297 | xfs_trans_t *tp, | ||
298 | xfs_inode_t *dp, | 295 | xfs_inode_t *dp, |
299 | uio_t *uio, /* caller's buffer control */ | 296 | void *dirent, |
300 | int *eofp) /* out: eof reached */ | 297 | size_t bufsize, |
298 | xfs_off_t *offset, | ||
299 | filldir_t filldir) | ||
301 | { | 300 | { |
302 | int alignment; /* alignment required for ABI */ | ||
303 | xfs_dirent_t *dbp; /* malloc'ed buffer */ | ||
304 | xfs_dir2_put_t put; /* entry formatting routine */ | ||
305 | int rval; /* return value */ | 301 | int rval; /* return value */ |
306 | int v; /* type-checking value */ | 302 | int v; /* type-checking value */ |
307 | 303 | ||
304 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); | ||
305 | |||
306 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | ||
307 | return XFS_ERROR(EIO); | ||
308 | |||
308 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 309 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
309 | XFS_STATS_INC(xs_dir_getdents); | 310 | XFS_STATS_INC(xs_dir_getdents); |
310 | /* | ||
311 | * If our caller has given us a single contiguous aligned memory buffer, | ||
312 | * just work directly within that buffer. If it's in user memory, | ||
313 | * lock it down first. | ||
314 | */ | ||
315 | alignment = sizeof(xfs_off_t) - 1; | ||
316 | if ((uio->uio_iovcnt == 1) && | ||
317 | (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) && | ||
318 | ((uio->uio_iov[0].iov_len & alignment) == 0)) { | ||
319 | dbp = NULL; | ||
320 | put = xfs_dir2_put_dirent64_direct; | ||
321 | } else { | ||
322 | dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP); | ||
323 | put = xfs_dir2_put_dirent64_uio; | ||
324 | } | ||
325 | 311 | ||
326 | *eofp = 0; | ||
327 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 312 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
328 | rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); | 313 | rval = xfs_dir2_sf_getdents(dp, dirent, offset, filldir); |
329 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) | 314 | else if ((rval = xfs_dir2_isblock(NULL, dp, &v))) |
330 | ; | 315 | ; |
331 | else if (v) | 316 | else if (v) |
332 | rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); | 317 | rval = xfs_dir2_block_getdents(dp, dirent, offset, filldir); |
333 | else | 318 | else |
334 | rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); | 319 | rval = xfs_dir2_leaf_getdents(dp, dirent, bufsize, offset, |
335 | if (dbp != NULL) | 320 | filldir); |
336 | kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN); | ||
337 | return rval; | 321 | return rval; |
338 | } | 322 | } |
339 | 323 | ||
@@ -613,77 +597,6 @@ xfs_dir2_isleaf( | |||
613 | } | 597 | } |
614 | 598 | ||
615 | /* | 599 | /* |
616 | * Getdents put routine for 64-bit ABI, direct form. | ||
617 | */ | ||
618 | static int | ||
619 | xfs_dir2_put_dirent64_direct( | ||
620 | xfs_dir2_put_args_t *pa) | ||
621 | { | ||
622 | xfs_dirent_t *idbp; /* dirent pointer */ | ||
623 | iovec_t *iovp; /* io vector */ | ||
624 | int namelen; /* entry name length */ | ||
625 | int reclen; /* entry total length */ | ||
626 | uio_t *uio; /* I/O control */ | ||
627 | |||
628 | namelen = pa->namelen; | ||
629 | reclen = DIRENTSIZE(namelen); | ||
630 | uio = pa->uio; | ||
631 | /* | ||
632 | * Won't fit in the remaining space. | ||
633 | */ | ||
634 | if (reclen > uio->uio_resid) { | ||
635 | pa->done = 0; | ||
636 | return 0; | ||
637 | } | ||
638 | iovp = uio->uio_iov; | ||
639 | idbp = (xfs_dirent_t *)iovp->iov_base; | ||
640 | iovp->iov_base = (char *)idbp + reclen; | ||
641 | iovp->iov_len -= reclen; | ||
642 | uio->uio_resid -= reclen; | ||
643 | idbp->d_reclen = reclen; | ||
644 | idbp->d_ino = pa->ino; | ||
645 | idbp->d_off = pa->cook; | ||
646 | idbp->d_name[namelen] = '\0'; | ||
647 | pa->done = 1; | ||
648 | memcpy(idbp->d_name, pa->name, namelen); | ||
649 | return 0; | ||
650 | } | ||
651 | |||
652 | /* | ||
653 | * Getdents put routine for 64-bit ABI, uio form. | ||
654 | */ | ||
655 | static int | ||
656 | xfs_dir2_put_dirent64_uio( | ||
657 | xfs_dir2_put_args_t *pa) | ||
658 | { | ||
659 | xfs_dirent_t *idbp; /* dirent pointer */ | ||
660 | int namelen; /* entry name length */ | ||
661 | int reclen; /* entry total length */ | ||
662 | int rval; /* return value */ | ||
663 | uio_t *uio; /* I/O control */ | ||
664 | |||
665 | namelen = pa->namelen; | ||
666 | reclen = DIRENTSIZE(namelen); | ||
667 | uio = pa->uio; | ||
668 | /* | ||
669 | * Won't fit in the remaining space. | ||
670 | */ | ||
671 | if (reclen > uio->uio_resid) { | ||
672 | pa->done = 0; | ||
673 | return 0; | ||
674 | } | ||
675 | idbp = pa->dbp; | ||
676 | idbp->d_reclen = reclen; | ||
677 | idbp->d_ino = pa->ino; | ||
678 | idbp->d_off = pa->cook; | ||
679 | idbp->d_name[namelen] = '\0'; | ||
680 | memcpy(idbp->d_name, pa->name, namelen); | ||
681 | rval = xfs_uio_read((caddr_t)idbp, reclen, uio); | ||
682 | pa->done = (rval == 0); | ||
683 | return rval; | ||
684 | } | ||
685 | |||
686 | /* | ||
687 | * Remove the given block from the directory. | 600 | * Remove the given block from the directory. |
688 | * This routine is used for data and free blocks, leaf/node are done | 601 | * This routine is used for data and free blocks, leaf/node are done |
689 | * by xfs_da_shrink_inode. | 602 | * by xfs_da_shrink_inode. |
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h index 86560b6f794c..b265197e74cf 100644 --- a/fs/xfs/xfs_dir2.h +++ b/fs/xfs/xfs_dir2.h | |||
@@ -60,21 +60,6 @@ typedef __uint32_t xfs_dir2_db_t; | |||
60 | typedef xfs_off_t xfs_dir2_off_t; | 60 | typedef xfs_off_t xfs_dir2_off_t; |
61 | 61 | ||
62 | /* | 62 | /* |
63 | * For getdents, argument struct for put routines. | ||
64 | */ | ||
65 | typedef int (*xfs_dir2_put_t)(struct xfs_dir2_put_args *pa); | ||
66 | typedef struct xfs_dir2_put_args { | ||
67 | xfs_off_t cook; /* cookie of (next) entry */ | ||
68 | xfs_intino_t ino; /* inode number */ | ||
69 | xfs_dirent_t *dbp; /* buffer pointer */ | ||
70 | char *name; /* directory entry name */ | ||
71 | int namelen; /* length of name */ | ||
72 | int done; /* output: set if value was stored */ | ||
73 | xfs_dir2_put_t put; /* put function ptr (i/o) */ | ||
74 | struct uio *uio; /* uio control structure */ | ||
75 | } xfs_dir2_put_args_t; | ||
76 | |||
77 | /* | ||
78 | * Generic directory interface routines | 63 | * Generic directory interface routines |
79 | */ | 64 | */ |
80 | extern void xfs_dir_startup(void); | 65 | extern void xfs_dir_startup(void); |
@@ -92,8 +77,6 @@ extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, | |||
92 | char *name, int namelen, xfs_ino_t ino, | 77 | char *name, int namelen, xfs_ino_t ino, |
93 | xfs_fsblock_t *first, | 78 | xfs_fsblock_t *first, |
94 | struct xfs_bmap_free *flist, xfs_extlen_t tot); | 79 | struct xfs_bmap_free *flist, xfs_extlen_t tot); |
95 | extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp, | ||
96 | uio_t *uio, int *eofp); | ||
97 | extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, | 80 | extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, |
98 | char *name, int namelen, xfs_ino_t inum, | 81 | char *name, int namelen, xfs_ino_t inum, |
99 | xfs_fsblock_t *first, | 82 | xfs_fsblock_t *first, |
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index e4df1aaae2a2..c171767e242a 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | ||
25 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
26 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
@@ -432,12 +433,10 @@ xfs_dir2_block_addname( | |||
432 | */ | 433 | */ |
433 | int /* error */ | 434 | int /* error */ |
434 | xfs_dir2_block_getdents( | 435 | xfs_dir2_block_getdents( |
435 | xfs_trans_t *tp, /* transaction (NULL) */ | ||
436 | xfs_inode_t *dp, /* incore inode */ | 436 | xfs_inode_t *dp, /* incore inode */ |
437 | uio_t *uio, /* caller's buffer control */ | 437 | void *dirent, |
438 | int *eofp, /* eof reached? (out) */ | 438 | xfs_off_t *offset, |
439 | xfs_dirent_t *dbp, /* caller's buffer */ | 439 | filldir_t filldir) |
440 | xfs_dir2_put_t put) /* abi's formatting function */ | ||
441 | { | 440 | { |
442 | xfs_dir2_block_t *block; /* directory block structure */ | 441 | xfs_dir2_block_t *block; /* directory block structure */ |
443 | xfs_dabuf_t *bp; /* buffer for block */ | 442 | xfs_dabuf_t *bp; /* buffer for block */ |
@@ -447,31 +446,32 @@ xfs_dir2_block_getdents( | |||
447 | char *endptr; /* end of the data entries */ | 446 | char *endptr; /* end of the data entries */ |
448 | int error; /* error return value */ | 447 | int error; /* error return value */ |
449 | xfs_mount_t *mp; /* filesystem mount point */ | 448 | xfs_mount_t *mp; /* filesystem mount point */ |
450 | xfs_dir2_put_args_t p; /* arg package for put rtn */ | ||
451 | char *ptr; /* current data entry */ | 449 | char *ptr; /* current data entry */ |
452 | int wantoff; /* starting block offset */ | 450 | int wantoff; /* starting block offset */ |
451 | xfs_ino_t ino; | ||
452 | xfs_off_t cook; | ||
453 | 453 | ||
454 | mp = dp->i_mount; | 454 | mp = dp->i_mount; |
455 | /* | 455 | /* |
456 | * If the block number in the offset is out of range, we're done. | 456 | * If the block number in the offset is out of range, we're done. |
457 | */ | 457 | */ |
458 | if (xfs_dir2_dataptr_to_db(mp, uio->uio_offset) > mp->m_dirdatablk) { | 458 | if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk) { |
459 | *eofp = 1; | ||
460 | return 0; | 459 | return 0; |
461 | } | 460 | } |
462 | /* | 461 | /* |
463 | * Can't read the block, give up, else get dabuf in bp. | 462 | * Can't read the block, give up, else get dabuf in bp. |
464 | */ | 463 | */ |
465 | if ((error = | 464 | error = xfs_da_read_buf(NULL, dp, mp->m_dirdatablk, -1, |
466 | xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &bp, XFS_DATA_FORK))) { | 465 | &bp, XFS_DATA_FORK); |
466 | if (error) | ||
467 | return error; | 467 | return error; |
468 | } | 468 | |
469 | ASSERT(bp != NULL); | 469 | ASSERT(bp != NULL); |
470 | /* | 470 | /* |
471 | * Extract the byte offset we start at from the seek pointer. | 471 | * Extract the byte offset we start at from the seek pointer. |
472 | * We'll skip entries before this. | 472 | * We'll skip entries before this. |
473 | */ | 473 | */ |
474 | wantoff = xfs_dir2_dataptr_to_off(mp, uio->uio_offset); | 474 | wantoff = xfs_dir2_dataptr_to_off(mp, *offset); |
475 | block = bp->data; | 475 | block = bp->data; |
476 | xfs_dir2_data_check(dp, bp); | 476 | xfs_dir2_data_check(dp, bp); |
477 | /* | 477 | /* |
@@ -480,9 +480,7 @@ xfs_dir2_block_getdents( | |||
480 | btp = xfs_dir2_block_tail_p(mp, block); | 480 | btp = xfs_dir2_block_tail_p(mp, block); |
481 | ptr = (char *)block->u; | 481 | ptr = (char *)block->u; |
482 | endptr = (char *)xfs_dir2_block_leaf_p(btp); | 482 | endptr = (char *)xfs_dir2_block_leaf_p(btp); |
483 | p.dbp = dbp; | 483 | |
484 | p.put = put; | ||
485 | p.uio = uio; | ||
486 | /* | 484 | /* |
487 | * Loop over the data portion of the block. | 485 | * Loop over the data portion of the block. |
488 | * Each object is a real entry (dep) or an unused one (dup). | 486 | * Each object is a real entry (dep) or an unused one (dup). |
@@ -508,33 +506,24 @@ xfs_dir2_block_getdents( | |||
508 | */ | 506 | */ |
509 | if ((char *)dep - (char *)block < wantoff) | 507 | if ((char *)dep - (char *)block < wantoff) |
510 | continue; | 508 | continue; |
511 | /* | ||
512 | * Set up argument structure for put routine. | ||
513 | */ | ||
514 | p.namelen = dep->namelen; | ||
515 | 509 | ||
516 | p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 510 | cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
517 | ptr - (char *)block); | 511 | ptr - (char *)block); |
518 | p.ino = be64_to_cpu(dep->inumber); | 512 | ino = be64_to_cpu(dep->inumber); |
519 | #if XFS_BIG_INUMS | 513 | #if XFS_BIG_INUMS |
520 | p.ino += mp->m_inoadd; | 514 | ino += mp->m_inoadd; |
521 | #endif | 515 | #endif |
522 | p.name = (char *)dep->name; | ||
523 | |||
524 | /* | ||
525 | * Put the entry in the caller's buffer. | ||
526 | */ | ||
527 | error = p.put(&p); | ||
528 | 516 | ||
529 | /* | 517 | /* |
530 | * If it didn't fit, set the final offset to here & return. | 518 | * If it didn't fit, set the final offset to here & return. |
531 | */ | 519 | */ |
532 | if (!p.done) { | 520 | if (filldir(dirent, dep->name, dep->namelen, cook, |
533 | uio->uio_offset = | 521 | ino, DT_UNKNOWN)) { |
534 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 522 | *offset = xfs_dir2_db_off_to_dataptr(mp, |
523 | mp->m_dirdatablk, | ||
535 | (char *)dep - (char *)block); | 524 | (char *)dep - (char *)block); |
536 | xfs_da_brelse(tp, bp); | 525 | xfs_da_brelse(NULL, bp); |
537 | return error; | 526 | return 0; |
538 | } | 527 | } |
539 | } | 528 | } |
540 | 529 | ||
@@ -542,13 +531,8 @@ xfs_dir2_block_getdents( | |||
542 | * Reached the end of the block. | 531 | * Reached the end of the block. |
543 | * Set the offset to a non-existent block 1 and return. | 532 | * Set the offset to a non-existent block 1 and return. |
544 | */ | 533 | */ |
545 | *eofp = 1; | 534 | *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); |
546 | 535 | xfs_da_brelse(NULL, bp); | |
547 | uio->uio_offset = | ||
548 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); | ||
549 | |||
550 | xfs_da_brelse(tp, bp); | ||
551 | |||
552 | return 0; | 536 | return 0; |
553 | } | 537 | } |
554 | 538 | ||
diff --git a/fs/xfs/xfs_dir2_block.h b/fs/xfs/xfs_dir2_block.h index e7c2606161e9..10e689676382 100644 --- a/fs/xfs/xfs_dir2_block.h +++ b/fs/xfs/xfs_dir2_block.h | |||
@@ -80,9 +80,8 @@ xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp) | |||
80 | * Function declarations. | 80 | * Function declarations. |
81 | */ | 81 | */ |
82 | extern int xfs_dir2_block_addname(struct xfs_da_args *args); | 82 | extern int xfs_dir2_block_addname(struct xfs_da_args *args); |
83 | extern int xfs_dir2_block_getdents(struct xfs_trans *tp, struct xfs_inode *dp, | 83 | extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent, |
84 | struct uio *uio, int *eofp, | 84 | xfs_off_t *offset, filldir_t filldir); |
85 | struct xfs_dirent *dbp, xfs_dir2_put_t put); | ||
86 | extern int xfs_dir2_block_lookup(struct xfs_da_args *args); | 85 | extern int xfs_dir2_block_lookup(struct xfs_da_args *args); |
87 | extern int xfs_dir2_block_removename(struct xfs_da_args *args); | 86 | extern int xfs_dir2_block_removename(struct xfs_da_args *args); |
88 | extern int xfs_dir2_block_replace(struct xfs_da_args *args); | 87 | extern int xfs_dir2_block_replace(struct xfs_da_args *args); |
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index 7ebe295bd6d3..d2452699e9b1 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | ||
25 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
26 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 1b73c9ad646a..e7c12fa1303e 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
@@ -749,12 +749,11 @@ xfs_dir2_leaf_compact_x1( | |||
749 | */ | 749 | */ |
750 | int /* error */ | 750 | int /* error */ |
751 | xfs_dir2_leaf_getdents( | 751 | xfs_dir2_leaf_getdents( |
752 | xfs_trans_t *tp, /* transaction pointer */ | ||
753 | xfs_inode_t *dp, /* incore directory inode */ | 752 | xfs_inode_t *dp, /* incore directory inode */ |
754 | uio_t *uio, /* I/O control & vectors */ | 753 | void *dirent, |
755 | int *eofp, /* out: reached end of dir */ | 754 | size_t bufsize, |
756 | xfs_dirent_t *dbp, /* caller's buffer */ | 755 | xfs_off_t *offset, |
757 | xfs_dir2_put_t put) /* ABI formatting routine */ | 756 | filldir_t filldir) |
758 | { | 757 | { |
759 | xfs_dabuf_t *bp; /* data block buffer */ | 758 | xfs_dabuf_t *bp; /* data block buffer */ |
760 | int byteoff; /* offset in current block */ | 759 | int byteoff; /* offset in current block */ |
@@ -763,7 +762,6 @@ xfs_dir2_leaf_getdents( | |||
763 | xfs_dir2_data_t *data; /* data block structure */ | 762 | xfs_dir2_data_t *data; /* data block structure */ |
764 | xfs_dir2_data_entry_t *dep; /* data entry */ | 763 | xfs_dir2_data_entry_t *dep; /* data entry */ |
765 | xfs_dir2_data_unused_t *dup; /* unused entry */ | 764 | xfs_dir2_data_unused_t *dup; /* unused entry */ |
766 | int eof; /* reached end of directory */ | ||
767 | int error = 0; /* error return value */ | 765 | int error = 0; /* error return value */ |
768 | int i; /* temporary loop index */ | 766 | int i; /* temporary loop index */ |
769 | int j; /* temporary loop index */ | 767 | int j; /* temporary loop index */ |
@@ -776,46 +774,38 @@ xfs_dir2_leaf_getdents( | |||
776 | xfs_mount_t *mp; /* filesystem mount point */ | 774 | xfs_mount_t *mp; /* filesystem mount point */ |
777 | xfs_dir2_off_t newoff; /* new curoff after new blk */ | 775 | xfs_dir2_off_t newoff; /* new curoff after new blk */ |
778 | int nmap; /* mappings to ask xfs_bmapi */ | 776 | int nmap; /* mappings to ask xfs_bmapi */ |
779 | xfs_dir2_put_args_t *p; /* formatting arg bundle */ | ||
780 | char *ptr = NULL; /* pointer to current data */ | 777 | char *ptr = NULL; /* pointer to current data */ |
781 | int ra_current; /* number of read-ahead blks */ | 778 | int ra_current; /* number of read-ahead blks */ |
782 | int ra_index; /* *map index for read-ahead */ | 779 | int ra_index; /* *map index for read-ahead */ |
783 | int ra_offset; /* map entry offset for ra */ | 780 | int ra_offset; /* map entry offset for ra */ |
784 | int ra_want; /* readahead count wanted */ | 781 | int ra_want; /* readahead count wanted */ |
782 | xfs_ino_t ino; | ||
785 | 783 | ||
786 | /* | 784 | /* |
787 | * If the offset is at or past the largest allowed value, | 785 | * If the offset is at or past the largest allowed value, |
788 | * give up right away, return eof. | 786 | * give up right away. |
789 | */ | 787 | */ |
790 | if (uio->uio_offset >= XFS_DIR2_MAX_DATAPTR) { | 788 | if (*offset >= XFS_DIR2_MAX_DATAPTR) |
791 | *eofp = 1; | ||
792 | return 0; | 789 | return 0; |
793 | } | 790 | |
794 | mp = dp->i_mount; | 791 | mp = dp->i_mount; |
795 | /* | 792 | |
796 | * Setup formatting arguments. | ||
797 | */ | ||
798 | p = kmem_alloc(sizeof(*p), KM_SLEEP); | ||
799 | p->dbp = dbp; | ||
800 | p->put = put; | ||
801 | p->uio = uio; | ||
802 | /* | 793 | /* |
803 | * Set up to bmap a number of blocks based on the caller's | 794 | * Set up to bmap a number of blocks based on the caller's |
804 | * buffer size, the directory block size, and the filesystem | 795 | * buffer size, the directory block size, and the filesystem |
805 | * block size. | 796 | * block size. |
806 | */ | 797 | */ |
807 | map_size = | 798 | map_size = howmany(bufsize + mp->m_dirblksize, mp->m_sb.sb_blocksize); |
808 | howmany(uio->uio_resid + mp->m_dirblksize, | ||
809 | mp->m_sb.sb_blocksize); | ||
810 | map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP); | 799 | map = kmem_alloc(map_size * sizeof(*map), KM_SLEEP); |
811 | map_valid = ra_index = ra_offset = ra_current = map_blocks = 0; | 800 | map_valid = ra_index = ra_offset = ra_current = map_blocks = 0; |
812 | bp = NULL; | 801 | bp = NULL; |
813 | eof = 1; | 802 | |
814 | /* | 803 | /* |
815 | * Inside the loop we keep the main offset value as a byte offset | 804 | * Inside the loop we keep the main offset value as a byte offset |
816 | * in the directory file. | 805 | * in the directory file. |
817 | */ | 806 | */ |
818 | curoff = xfs_dir2_dataptr_to_byte(mp, uio->uio_offset); | 807 | curoff = xfs_dir2_dataptr_to_byte(mp, *offset); |
808 | |||
819 | /* | 809 | /* |
820 | * Force this conversion through db so we truncate the offset | 810 | * Force this conversion through db so we truncate the offset |
821 | * down to get the start of the data block. | 811 | * down to get the start of the data block. |
@@ -836,7 +826,7 @@ xfs_dir2_leaf_getdents( | |||
836 | * take it out of the mapping. | 826 | * take it out of the mapping. |
837 | */ | 827 | */ |
838 | if (bp) { | 828 | if (bp) { |
839 | xfs_da_brelse(tp, bp); | 829 | xfs_da_brelse(NULL, bp); |
840 | bp = NULL; | 830 | bp = NULL; |
841 | map_blocks -= mp->m_dirblkfsbs; | 831 | map_blocks -= mp->m_dirblkfsbs; |
842 | /* | 832 | /* |
@@ -862,8 +852,9 @@ xfs_dir2_leaf_getdents( | |||
862 | /* | 852 | /* |
863 | * Recalculate the readahead blocks wanted. | 853 | * Recalculate the readahead blocks wanted. |
864 | */ | 854 | */ |
865 | ra_want = howmany(uio->uio_resid + mp->m_dirblksize, | 855 | ra_want = howmany(bufsize + mp->m_dirblksize, |
866 | mp->m_sb.sb_blocksize) - 1; | 856 | mp->m_sb.sb_blocksize) - 1; |
857 | |||
867 | /* | 858 | /* |
868 | * If we don't have as many as we want, and we haven't | 859 | * If we don't have as many as we want, and we haven't |
869 | * run out of data blocks, get some more mappings. | 860 | * run out of data blocks, get some more mappings. |
@@ -876,7 +867,7 @@ xfs_dir2_leaf_getdents( | |||
876 | * we already have in the table. | 867 | * we already have in the table. |
877 | */ | 868 | */ |
878 | nmap = map_size - map_valid; | 869 | nmap = map_size - map_valid; |
879 | error = xfs_bmapi(tp, dp, | 870 | error = xfs_bmapi(NULL, dp, |
880 | map_off, | 871 | map_off, |
881 | xfs_dir2_byte_to_da(mp, | 872 | xfs_dir2_byte_to_da(mp, |
882 | XFS_DIR2_LEAF_OFFSET) - map_off, | 873 | XFS_DIR2_LEAF_OFFSET) - map_off, |
@@ -939,7 +930,7 @@ xfs_dir2_leaf_getdents( | |||
939 | * mapping. | 930 | * mapping. |
940 | */ | 931 | */ |
941 | curdb = xfs_dir2_da_to_db(mp, map->br_startoff); | 932 | curdb = xfs_dir2_da_to_db(mp, map->br_startoff); |
942 | error = xfs_da_read_buf(tp, dp, map->br_startoff, | 933 | error = xfs_da_read_buf(NULL, dp, map->br_startoff, |
943 | map->br_blockcount >= mp->m_dirblkfsbs ? | 934 | map->br_blockcount >= mp->m_dirblkfsbs ? |
944 | XFS_FSB_TO_DADDR(mp, map->br_startblock) : | 935 | XFS_FSB_TO_DADDR(mp, map->br_startblock) : |
945 | -1, | 936 | -1, |
@@ -982,7 +973,7 @@ xfs_dir2_leaf_getdents( | |||
982 | * is a very rare case. | 973 | * is a very rare case. |
983 | */ | 974 | */ |
984 | else if (i > ra_current) { | 975 | else if (i > ra_current) { |
985 | (void)xfs_da_reada_buf(tp, dp, | 976 | (void)xfs_da_reada_buf(NULL, dp, |
986 | map[ra_index].br_startoff + | 977 | map[ra_index].br_startoff + |
987 | ra_offset, XFS_DATA_FORK); | 978 | ra_offset, XFS_DATA_FORK); |
988 | ra_current = i; | 979 | ra_current = i; |
@@ -1089,46 +1080,39 @@ xfs_dir2_leaf_getdents( | |||
1089 | */ | 1080 | */ |
1090 | dep = (xfs_dir2_data_entry_t *)ptr; | 1081 | dep = (xfs_dir2_data_entry_t *)ptr; |
1091 | 1082 | ||
1092 | p->namelen = dep->namelen; | 1083 | length = xfs_dir2_data_entsize(dep->namelen); |
1093 | |||
1094 | length = xfs_dir2_data_entsize(p->namelen); | ||
1095 | |||
1096 | p->cook = xfs_dir2_byte_to_dataptr(mp, curoff + length); | ||
1097 | 1084 | ||
1098 | p->ino = be64_to_cpu(dep->inumber); | 1085 | ino = be64_to_cpu(dep->inumber); |
1099 | #if XFS_BIG_INUMS | 1086 | #if XFS_BIG_INUMS |
1100 | p->ino += mp->m_inoadd; | 1087 | ino += mp->m_inoadd; |
1101 | #endif | 1088 | #endif |
1102 | p->name = (char *)dep->name; | ||
1103 | |||
1104 | error = p->put(p); | ||
1105 | 1089 | ||
1106 | /* | 1090 | /* |
1107 | * Won't fit. Return to caller. | 1091 | * Won't fit. Return to caller. |
1108 | */ | 1092 | */ |
1109 | if (!p->done) { | 1093 | if (filldir(dirent, dep->name, dep->namelen, |
1110 | eof = 0; | 1094 | xfs_dir2_byte_to_dataptr(mp, curoff + length), |
1095 | ino, DT_UNKNOWN)) | ||
1111 | break; | 1096 | break; |
1112 | } | 1097 | |
1113 | /* | 1098 | /* |
1114 | * Advance to next entry in the block. | 1099 | * Advance to next entry in the block. |
1115 | */ | 1100 | */ |
1116 | ptr += length; | 1101 | ptr += length; |
1117 | curoff += length; | 1102 | curoff += length; |
1103 | bufsize -= length; | ||
1118 | } | 1104 | } |
1119 | 1105 | ||
1120 | /* | 1106 | /* |
1121 | * All done. Set output offset value to current offset. | 1107 | * All done. Set output offset value to current offset. |
1122 | */ | 1108 | */ |
1123 | *eofp = eof; | ||
1124 | if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) | 1109 | if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) |
1125 | uio->uio_offset = XFS_DIR2_MAX_DATAPTR; | 1110 | *offset = XFS_DIR2_MAX_DATAPTR; |
1126 | else | 1111 | else |
1127 | uio->uio_offset = xfs_dir2_byte_to_dataptr(mp, curoff); | 1112 | *offset = xfs_dir2_byte_to_dataptr(mp, curoff); |
1128 | kmem_free(map, map_size * sizeof(*map)); | 1113 | kmem_free(map, map_size * sizeof(*map)); |
1129 | kmem_free(p, sizeof(*p)); | ||
1130 | if (bp) | 1114 | if (bp) |
1131 | xfs_da_brelse(tp, bp); | 1115 | xfs_da_brelse(NULL, bp); |
1132 | return error; | 1116 | return error; |
1133 | } | 1117 | } |
1134 | 1118 | ||
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h index 70c97f3f815e..6c9539f06987 100644 --- a/fs/xfs/xfs_dir2_leaf.h +++ b/fs/xfs/xfs_dir2_leaf.h | |||
@@ -232,9 +232,9 @@ extern void xfs_dir2_leaf_compact(struct xfs_da_args *args, | |||
232 | extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp, | 232 | extern void xfs_dir2_leaf_compact_x1(struct xfs_dabuf *bp, int *indexp, |
233 | int *lowstalep, int *highstalep, | 233 | int *lowstalep, int *highstalep, |
234 | int *lowlogp, int *highlogp); | 234 | int *lowlogp, int *highlogp); |
235 | extern int xfs_dir2_leaf_getdents(struct xfs_trans *tp, struct xfs_inode *dp, | 235 | extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent, |
236 | struct uio *uio, int *eofp, | 236 | size_t bufsize, xfs_off_t *offset, |
237 | struct xfs_dirent *dbp, xfs_dir2_put_t put); | 237 | filldir_t filldir); |
238 | extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, | 238 | extern int xfs_dir2_leaf_init(struct xfs_da_args *args, xfs_dir2_db_t bno, |
239 | struct xfs_dabuf **bpp, int magic); | 239 | struct xfs_dabuf **bpp, int magic); |
240 | extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp, | 240 | extern void xfs_dir2_leaf_log_ents(struct xfs_trans *tp, struct xfs_dabuf *bp, |
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index 91c61d9632c8..eb18e399e836 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | ||
25 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
26 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index 38fc4f22b76d..182c70315ad1 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | ||
25 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
26 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
@@ -695,19 +696,18 @@ xfs_dir2_sf_create( | |||
695 | int /* error */ | 696 | int /* error */ |
696 | xfs_dir2_sf_getdents( | 697 | xfs_dir2_sf_getdents( |
697 | xfs_inode_t *dp, /* incore directory inode */ | 698 | xfs_inode_t *dp, /* incore directory inode */ |
698 | uio_t *uio, /* caller's buffer control */ | 699 | void *dirent, |
699 | int *eofp, /* eof reached? (out) */ | 700 | xfs_off_t *offset, |
700 | xfs_dirent_t *dbp, /* caller's buffer */ | 701 | filldir_t filldir) |
701 | xfs_dir2_put_t put) /* abi's formatting function */ | ||
702 | { | 702 | { |
703 | int error; /* error return value */ | ||
704 | int i; /* shortform entry number */ | 703 | int i; /* shortform entry number */ |
705 | xfs_mount_t *mp; /* filesystem mount point */ | 704 | xfs_mount_t *mp; /* filesystem mount point */ |
706 | xfs_dir2_dataptr_t off; /* current entry's offset */ | 705 | xfs_dir2_dataptr_t off; /* current entry's offset */ |
707 | xfs_dir2_put_args_t p; /* arg package for put rtn */ | ||
708 | xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ | 706 | xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ |
709 | xfs_dir2_sf_t *sfp; /* shortform structure */ | 707 | xfs_dir2_sf_t *sfp; /* shortform structure */ |
710 | xfs_off_t dir_offset; | 708 | xfs_dir2_dataptr_t dot_offset; |
709 | xfs_dir2_dataptr_t dotdot_offset; | ||
710 | xfs_ino_t ino; | ||
711 | 711 | ||
712 | mp = dp->i_mount; | 712 | mp = dp->i_mount; |
713 | 713 | ||
@@ -720,8 +720,6 @@ xfs_dir2_sf_getdents( | |||
720 | return XFS_ERROR(EIO); | 720 | return XFS_ERROR(EIO); |
721 | } | 721 | } |
722 | 722 | ||
723 | dir_offset = uio->uio_offset; | ||
724 | |||
725 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | 723 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); |
726 | ASSERT(dp->i_df.if_u1.if_data != NULL); | 724 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
727 | 725 | ||
@@ -732,108 +730,78 @@ xfs_dir2_sf_getdents( | |||
732 | /* | 730 | /* |
733 | * If the block number in the offset is out of range, we're done. | 731 | * If the block number in the offset is out of range, we're done. |
734 | */ | 732 | */ |
735 | if (xfs_dir2_dataptr_to_db(mp, dir_offset) > mp->m_dirdatablk) { | 733 | if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk) |
736 | *eofp = 1; | ||
737 | return 0; | 734 | return 0; |
738 | } | ||
739 | 735 | ||
740 | /* | 736 | /* |
741 | * Set up putargs structure. | 737 | * Precalculate offsets for . and .. as we will always need them. |
738 | * | ||
739 | * XXX(hch): the second argument is sometimes 0 and sometimes | ||
740 | * mp->m_dirdatablk. | ||
742 | */ | 741 | */ |
743 | p.dbp = dbp; | 742 | dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
744 | p.put = put; | 743 | XFS_DIR2_DATA_DOT_OFFSET); |
745 | p.uio = uio; | 744 | dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
745 | XFS_DIR2_DATA_DOTDOT_OFFSET); | ||
746 | |||
746 | /* | 747 | /* |
747 | * Put . entry unless we're starting past it. | 748 | * Put . entry unless we're starting past it. |
748 | */ | 749 | */ |
749 | if (dir_offset <= | 750 | if (*offset <= dot_offset) { |
750 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 751 | ino = dp->i_ino; |
751 | XFS_DIR2_DATA_DOT_OFFSET)) { | ||
752 | p.cook = xfs_dir2_db_off_to_dataptr(mp, 0, | ||
753 | XFS_DIR2_DATA_DOTDOT_OFFSET); | ||
754 | p.ino = dp->i_ino; | ||
755 | #if XFS_BIG_INUMS | 752 | #if XFS_BIG_INUMS |
756 | p.ino += mp->m_inoadd; | 753 | ino += mp->m_inoadd; |
757 | #endif | 754 | #endif |
758 | p.name = "."; | 755 | if (filldir(dirent, ".", 1, dotdot_offset, ino, DT_DIR)) { |
759 | p.namelen = 1; | 756 | *offset = dot_offset; |
760 | 757 | return 0; | |
761 | error = p.put(&p); | ||
762 | |||
763 | if (!p.done) { | ||
764 | uio->uio_offset = | ||
765 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | ||
766 | XFS_DIR2_DATA_DOT_OFFSET); | ||
767 | return error; | ||
768 | } | 758 | } |
769 | } | 759 | } |
770 | 760 | ||
771 | /* | 761 | /* |
772 | * Put .. entry unless we're starting past it. | 762 | * Put .. entry unless we're starting past it. |
773 | */ | 763 | */ |
774 | if (dir_offset <= | 764 | if (*offset <= dotdot_offset) { |
775 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 765 | off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
776 | XFS_DIR2_DATA_DOTDOT_OFFSET)) { | 766 | XFS_DIR2_DATA_FIRST_OFFSET); |
777 | p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 767 | ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); |
778 | XFS_DIR2_DATA_FIRST_OFFSET); | ||
779 | p.ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); | ||
780 | #if XFS_BIG_INUMS | 768 | #if XFS_BIG_INUMS |
781 | p.ino += mp->m_inoadd; | 769 | ino += mp->m_inoadd; |
782 | #endif | 770 | #endif |
783 | p.name = ".."; | 771 | if (filldir(dirent, "..", 2, off, ino, DT_DIR)) { |
784 | p.namelen = 2; | 772 | *offset = dotdot_offset; |
785 | 773 | return 0; | |
786 | error = p.put(&p); | ||
787 | |||
788 | if (!p.done) { | ||
789 | uio->uio_offset = | ||
790 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | ||
791 | XFS_DIR2_DATA_DOTDOT_OFFSET); | ||
792 | return error; | ||
793 | } | 774 | } |
794 | } | 775 | } |
795 | 776 | ||
796 | /* | 777 | /* |
797 | * Loop while there are more entries and put'ing works. | 778 | * Loop while there are more entries and put'ing works. |
798 | */ | 779 | */ |
799 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); | 780 | sfep = xfs_dir2_sf_firstentry(sfp); |
800 | i < sfp->hdr.count; | 781 | for (i = 0; i < sfp->hdr.count; i++) { |
801 | i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { | ||
802 | |||
803 | off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 782 | off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
804 | xfs_dir2_sf_get_offset(sfep)); | 783 | xfs_dir2_sf_get_offset(sfep)); |
805 | 784 | ||
806 | if (dir_offset > off) | 785 | if (*offset > off) { |
786 | sfep = xfs_dir2_sf_nextentry(sfp, sfep); | ||
807 | continue; | 787 | continue; |
788 | } | ||
808 | 789 | ||
809 | p.namelen = sfep->namelen; | 790 | ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); |
810 | |||
811 | p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | ||
812 | xfs_dir2_sf_get_offset(sfep) + | ||
813 | xfs_dir2_data_entsize(p.namelen)); | ||
814 | |||
815 | p.ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); | ||
816 | #if XFS_BIG_INUMS | 791 | #if XFS_BIG_INUMS |
817 | p.ino += mp->m_inoadd; | 792 | ino += mp->m_inoadd; |
818 | #endif | 793 | #endif |
819 | p.name = (char *)sfep->name; | ||
820 | |||
821 | error = p.put(&p); | ||
822 | 794 | ||
823 | if (!p.done) { | 795 | if (filldir(dirent, sfep->name, sfep->namelen, |
824 | uio->uio_offset = off; | 796 | off + xfs_dir2_data_entsize(sfep->namelen), |
825 | return error; | 797 | ino, DT_UNKNOWN)) { |
798 | *offset = off; | ||
799 | return 0; | ||
826 | } | 800 | } |
801 | sfep = xfs_dir2_sf_nextentry(sfp, sfep); | ||
827 | } | 802 | } |
828 | 803 | ||
829 | /* | 804 | *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); |
830 | * They all fit. | ||
831 | */ | ||
832 | *eofp = 1; | ||
833 | |||
834 | uio->uio_offset = | ||
835 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); | ||
836 | |||
837 | return 0; | 805 | return 0; |
838 | } | 806 | } |
839 | 807 | ||
diff --git a/fs/xfs/xfs_dir2_sf.h b/fs/xfs/xfs_dir2_sf.h index 11e503209afa..005629d702d2 100644 --- a/fs/xfs/xfs_dir2_sf.h +++ b/fs/xfs/xfs_dir2_sf.h | |||
@@ -169,9 +169,8 @@ extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, | |||
169 | int size, xfs_dir2_sf_hdr_t *sfhp); | 169 | int size, xfs_dir2_sf_hdr_t *sfhp); |
170 | extern int xfs_dir2_sf_addname(struct xfs_da_args *args); | 170 | extern int xfs_dir2_sf_addname(struct xfs_da_args *args); |
171 | extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); | 171 | extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino); |
172 | extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct uio *uio, | 172 | extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent, |
173 | int *eofp, struct xfs_dirent *dbp, | 173 | xfs_off_t *offset, filldir_t filldir); |
174 | xfs_dir2_put_t put); | ||
175 | extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); | 174 | extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); |
176 | extern int xfs_dir2_sf_removename(struct xfs_da_args *args); | 175 | extern int xfs_dir2_sf_removename(struct xfs_da_args *args); |
177 | extern int xfs_dir2_sf_replace(struct xfs_da_args *args); | 176 | extern int xfs_dir2_sf_replace(struct xfs_da_args *args); |
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h index adc3d251240d..f71784ab6a60 100644 --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h | |||
@@ -67,17 +67,15 @@ typedef enum { | |||
67 | #define HAVE_DM_RIGHT_T | 67 | #define HAVE_DM_RIGHT_T |
68 | 68 | ||
69 | /* Defines for determining if an event message should be sent. */ | 69 | /* Defines for determining if an event message should be sent. */ |
70 | #define DM_EVENT_ENABLED(vfsp, ip, event) ( \ | 70 | #ifdef HAVE_DMAPI |
71 | unlikely ((vfsp)->vfs_flag & VFS_DMI) && \ | 71 | #define DM_EVENT_ENABLED(ip, event) ( \ |
72 | unlikely ((ip)->i_mount->m_flags & XFS_MOUNT_DMAPI) && \ | ||
72 | ( ((ip)->i_d.di_dmevmask & (1 << event)) || \ | 73 | ( ((ip)->i_d.di_dmevmask & (1 << event)) || \ |
73 | ((ip)->i_mount->m_dmevmask & (1 << event)) ) \ | 74 | ((ip)->i_mount->m_dmevmask & (1 << event)) ) \ |
74 | ) | 75 | ) |
75 | 76 | #else | |
76 | #define DM_EVENT_ENABLED_IO(vfsp, io, event) ( \ | 77 | #define DM_EVENT_ENABLED(ip, event) (0) |
77 | unlikely ((vfsp)->vfs_flag & VFS_DMI) && \ | 78 | #endif |
78 | ( ((io)->io_dmevmask & (1 << event)) || \ | ||
79 | ((io)->io_mount->m_dmevmask & (1 << event)) ) \ | ||
80 | ) | ||
81 | 79 | ||
82 | #define DM_XFS_VALID_FS_EVENTS ( \ | 80 | #define DM_XFS_VALID_FS_EVENTS ( \ |
83 | (1 << DM_EVENT_PREUNMOUNT) | \ | 81 | (1 << DM_EVENT_PREUNMOUNT) | \ |
@@ -170,7 +168,4 @@ typedef enum { | |||
170 | DM_FLAGS_NDELAY : 0) | 168 | DM_FLAGS_NDELAY : 0) |
171 | #define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) | 169 | #define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) |
172 | 170 | ||
173 | |||
174 | extern struct bhv_module_vfsops xfs_dmops; | ||
175 | |||
176 | #endif /* __XFS_DMAPI_H__ */ | 171 | #endif /* __XFS_DMAPI_H__ */ |
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c index 1e4a35ddf7f9..6cd5704258a2 100644 --- a/fs/xfs/xfs_dmops.c +++ b/fs/xfs/xfs_dmops.c | |||
@@ -19,18 +19,51 @@ | |||
19 | #include "xfs_fs.h" | 19 | #include "xfs_fs.h" |
20 | #include "xfs_types.h" | 20 | #include "xfs_types.h" |
21 | #include "xfs_log.h" | 21 | #include "xfs_log.h" |
22 | #include "xfs_inum.h" | ||
23 | #include "xfs_trans.h" | 22 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 23 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | ||
26 | #include "xfs_dir2.h" | ||
27 | #include "xfs_dmapi.h" | 24 | #include "xfs_dmapi.h" |
25 | #include "xfs_inum.h" | ||
26 | #include "xfs_ag.h" | ||
28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
28 | #include "xfs_clnt.h" | ||
29 | |||
29 | 30 | ||
30 | xfs_dmops_t xfs_dmcore_stub = { | 31 | static struct xfs_dmops xfs_dmcore_stub = { |
31 | .xfs_send_data = (xfs_send_data_t)fs_nosys, | 32 | .xfs_send_data = (xfs_send_data_t)fs_nosys, |
32 | .xfs_send_mmap = (xfs_send_mmap_t)fs_noerr, | 33 | .xfs_send_mmap = (xfs_send_mmap_t)fs_noerr, |
33 | .xfs_send_destroy = (xfs_send_destroy_t)fs_nosys, | 34 | .xfs_send_destroy = (xfs_send_destroy_t)fs_nosys, |
34 | .xfs_send_namesp = (xfs_send_namesp_t)fs_nosys, | 35 | .xfs_send_namesp = (xfs_send_namesp_t)fs_nosys, |
35 | .xfs_send_unmount = (xfs_send_unmount_t)fs_noval, | 36 | .xfs_send_mount = (xfs_send_mount_t)fs_nosys, |
37 | .xfs_send_unmount = (xfs_send_unmount_t)fs_noerr, | ||
36 | }; | 38 | }; |
39 | |||
40 | int | ||
41 | xfs_dmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) | ||
42 | { | ||
43 | if (args->flags & XFSMNT_DMAPI) { | ||
44 | struct xfs_dmops *ops; | ||
45 | |||
46 | ops = symbol_get(xfs_dmcore_xfs); | ||
47 | if (!ops) { | ||
48 | request_module("xfs_dmapi"); | ||
49 | ops = symbol_get(xfs_dmcore_xfs); | ||
50 | } | ||
51 | |||
52 | if (!ops) { | ||
53 | cmn_err(CE_WARN, "XFS: no dmapi support available."); | ||
54 | return EINVAL; | ||
55 | } | ||
56 | mp->m_dm_ops = ops; | ||
57 | } else { | ||
58 | mp->m_dm_ops = &xfs_dmcore_stub; | ||
59 | } | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | void | ||
65 | xfs_dmops_put(struct xfs_mount *mp) | ||
66 | { | ||
67 | if (mp->m_dm_ops != &xfs_dmcore_stub) | ||
68 | symbol_put(xfs_dmcore_xfs); | ||
69 | } | ||
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 8c4331631337..a4634d94e561 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | ||
25 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
26 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
@@ -132,10 +133,14 @@ xfs_errortag_add(int error_tag, xfs_mount_t *mp) | |||
132 | } | 133 | } |
133 | 134 | ||
134 | int | 135 | int |
135 | xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud) | 136 | xfs_errortag_clearall(xfs_mount_t *mp, int loud) |
136 | { | 137 | { |
137 | int i; | 138 | int64_t fsid; |
138 | int cleared = 0; | 139 | int cleared = 0; |
140 | int i; | ||
141 | |||
142 | memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t)); | ||
143 | |||
139 | 144 | ||
140 | for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) { | 145 | for (i = 0; i < XFS_NUM_INJECT_ERROR; i++) { |
141 | if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) && | 146 | if ((fsid == 0LL || xfs_etest_fsid[i] == fsid) && |
@@ -154,20 +159,10 @@ xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud) | |||
154 | if (loud || cleared) | 159 | if (loud || cleared) |
155 | cmn_err(CE_WARN, | 160 | cmn_err(CE_WARN, |
156 | "Cleared all XFS error tags for filesystem \"%s\"", | 161 | "Cleared all XFS error tags for filesystem \"%s\"", |
157 | fsname); | 162 | mp->m_fsname); |
158 | 163 | ||
159 | return 0; | 164 | return 0; |
160 | } | 165 | } |
161 | |||
162 | int | ||
163 | xfs_errortag_clearall(xfs_mount_t *mp) | ||
164 | { | ||
165 | int64_t fsid; | ||
166 | |||
167 | memcpy(&fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t)); | ||
168 | |||
169 | return xfs_errortag_clearall_umount(fsid, mp->m_fsname, 1); | ||
170 | } | ||
171 | #endif /* DEBUG || INDUCE_IO_ERROR */ | 166 | #endif /* DEBUG || INDUCE_IO_ERROR */ |
172 | 167 | ||
173 | static void | 168 | static void |
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index 5599ada456a1..10e9d9619ae5 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h | |||
@@ -144,12 +144,11 @@ extern void xfs_error_test_init(void); | |||
144 | #endif /* __ANSI_CPP__ */ | 144 | #endif /* __ANSI_CPP__ */ |
145 | 145 | ||
146 | extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp); | 146 | extern int xfs_errortag_add(int error_tag, xfs_mount_t *mp); |
147 | extern int xfs_errortag_clearall(xfs_mount_t *mp); | 147 | extern int xfs_errortag_clearall(xfs_mount_t *mp, int loud); |
148 | extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud); | ||
149 | #else | 148 | #else |
150 | #define XFS_TEST_ERROR(expr, mp, tag, rf) (expr) | 149 | #define XFS_TEST_ERROR(expr, mp, tag, rf) (expr) |
151 | #define xfs_errortag_add(tag, mp) (ENOSYS) | 150 | #define xfs_errortag_add(tag, mp) (ENOSYS) |
152 | #define xfs_errortag_clearall(mp) (ENOSYS) | 151 | #define xfs_errortag_clearall(mp, loud) (ENOSYS) |
153 | #endif /* (DEBUG || INDUCE_IO_ERROR) */ | 152 | #endif /* (DEBUG || INDUCE_IO_ERROR) */ |
154 | 153 | ||
155 | /* | 154 | /* |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 3b14427ee123..f938a51be81b 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_buf_item.h" | 24 | #include "xfs_buf_item.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | ||
26 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
28 | #include "xfs_trans_priv.h" | 29 | #include "xfs_trans_priv.h" |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 432e82347ed6..c92d5b821029 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -136,7 +136,6 @@ xfs_growfs_data_private( | |||
136 | xfs_rfsblock_t nfree; | 136 | xfs_rfsblock_t nfree; |
137 | xfs_agnumber_t oagcount; | 137 | xfs_agnumber_t oagcount; |
138 | int pct; | 138 | int pct; |
139 | xfs_sb_t *sbp; | ||
140 | xfs_trans_t *tp; | 139 | xfs_trans_t *tp; |
141 | 140 | ||
142 | nb = in->newblocks; | 141 | nb = in->newblocks; |
@@ -175,7 +174,7 @@ xfs_growfs_data_private( | |||
175 | memset(&mp->m_perag[oagcount], 0, | 174 | memset(&mp->m_perag[oagcount], 0, |
176 | (nagcount - oagcount) * sizeof(xfs_perag_t)); | 175 | (nagcount - oagcount) * sizeof(xfs_perag_t)); |
177 | mp->m_flags |= XFS_MOUNT_32BITINODES; | 176 | mp->m_flags |= XFS_MOUNT_32BITINODES; |
178 | nagimax = xfs_initialize_perag(XFS_MTOVFS(mp), mp, nagcount); | 177 | nagimax = xfs_initialize_perag(mp, nagcount); |
179 | up_write(&mp->m_peraglock); | 178 | up_write(&mp->m_peraglock); |
180 | } | 179 | } |
181 | tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS); | 180 | tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS); |
@@ -377,8 +376,7 @@ xfs_growfs_data_private( | |||
377 | error, agno); | 376 | error, agno); |
378 | break; | 377 | break; |
379 | } | 378 | } |
380 | sbp = XFS_BUF_TO_SBP(bp); | 379 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); |
381 | xfs_xlatesb(sbp, &mp->m_sb, -1, XFS_SB_ALL_BITS); | ||
382 | /* | 380 | /* |
383 | * If we get an error writing out the alternate superblocks, | 381 | * If we get an error writing out the alternate superblocks, |
384 | * just issue a warning and continue. The real work is | 382 | * just issue a warning and continue. The real work is |
@@ -435,10 +433,10 @@ xfs_growfs_data( | |||
435 | xfs_growfs_data_t *in) | 433 | xfs_growfs_data_t *in) |
436 | { | 434 | { |
437 | int error; | 435 | int error; |
438 | if (!cpsema(&mp->m_growlock)) | 436 | if (!mutex_trylock(&mp->m_growlock)) |
439 | return XFS_ERROR(EWOULDBLOCK); | 437 | return XFS_ERROR(EWOULDBLOCK); |
440 | error = xfs_growfs_data_private(mp, in); | 438 | error = xfs_growfs_data_private(mp, in); |
441 | vsema(&mp->m_growlock); | 439 | mutex_unlock(&mp->m_growlock); |
442 | return error; | 440 | return error; |
443 | } | 441 | } |
444 | 442 | ||
@@ -448,10 +446,10 @@ xfs_growfs_log( | |||
448 | xfs_growfs_log_t *in) | 446 | xfs_growfs_log_t *in) |
449 | { | 447 | { |
450 | int error; | 448 | int error; |
451 | if (!cpsema(&mp->m_growlock)) | 449 | if (!mutex_trylock(&mp->m_growlock)) |
452 | return XFS_ERROR(EWOULDBLOCK); | 450 | return XFS_ERROR(EWOULDBLOCK); |
453 | error = xfs_growfs_log_private(mp, in); | 451 | error = xfs_growfs_log_private(mp, in); |
454 | vsema(&mp->m_growlock); | 452 | mutex_unlock(&mp->m_growlock); |
455 | return error; | 453 | return error; |
456 | } | 454 | } |
457 | 455 | ||
@@ -628,8 +626,7 @@ xfs_fs_goingdown( | |||
628 | { | 626 | { |
629 | switch (inflags) { | 627 | switch (inflags) { |
630 | case XFS_FSOP_GOING_FLAGS_DEFAULT: { | 628 | case XFS_FSOP_GOING_FLAGS_DEFAULT: { |
631 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); | 629 | struct super_block *sb = freeze_bdev(mp->m_super->s_bdev); |
632 | struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev); | ||
633 | 630 | ||
634 | if (sb && !IS_ERR(sb)) { | 631 | if (sb && !IS_ERR(sb)) { |
635 | xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT); | 632 | xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT); |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index f943368c9b93..1409c2d61c11 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -293,9 +293,9 @@ xfs_ialloc_ag_alloc( | |||
293 | xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog); | 293 | xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog); |
294 | for (i = 0; i < ninodes; i++) { | 294 | for (i = 0; i < ninodes; i++) { |
295 | free = XFS_MAKE_IPTR(args.mp, fbuf, i); | 295 | free = XFS_MAKE_IPTR(args.mp, fbuf, i); |
296 | INT_SET(free->di_core.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC); | 296 | free->di_core.di_magic = cpu_to_be16(XFS_DINODE_MAGIC); |
297 | INT_SET(free->di_core.di_version, ARCH_CONVERT, version); | 297 | free->di_core.di_version = version; |
298 | INT_SET(free->di_next_unlinked, ARCH_CONVERT, NULLAGINO); | 298 | free->di_next_unlinked = cpu_to_be32(NULLAGINO); |
299 | xfs_ialloc_log_di(tp, fbuf, i, | 299 | xfs_ialloc_log_di(tp, fbuf, i, |
300 | XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED); | 300 | XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED); |
301 | } | 301 | } |
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h index 97f4040931ca..4e30ec1d13bc 100644 --- a/fs/xfs/xfs_ialloc.h +++ b/fs/xfs/xfs_ialloc.h | |||
@@ -30,14 +30,9 @@ struct xfs_trans; | |||
30 | #define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks | 30 | #define XFS_IALLOC_BLOCKS(mp) (mp)->m_ialloc_blks |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * For small block file systems, move inodes in clusters of this size. | 33 | * Move inodes in clusters of this size. |
34 | * When we don't have a lot of memory, however, we go a bit smaller | ||
35 | * to reduce the number of AGI and ialloc btree blocks we need to keep | ||
36 | * around for xfs_dilocate(). We choose which one to use in | ||
37 | * xfs_mount_int(). | ||
38 | */ | 34 | */ |
39 | #define XFS_INODE_BIG_CLUSTER_SIZE 8192 | 35 | #define XFS_INODE_BIG_CLUSTER_SIZE 8192 |
40 | #define XFS_INODE_SMALL_CLUSTER_SIZE 4096 | ||
41 | #define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size | 36 | #define XFS_INODE_CLUSTER_SIZE(mp) (mp)->m_inode_cluster_size |
42 | 37 | ||
43 | /* | 38 | /* |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 114433a22baa..488836e204a3 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -40,131 +40,13 @@ | |||
40 | #include "xfs_utils.h" | 40 | #include "xfs_utils.h" |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Initialize the inode hash table for the newly mounted file system. | ||
44 | * Choose an initial table size based on user specified value, else | ||
45 | * use a simple algorithm using the maximum number of inodes as an | ||
46 | * indicator for table size, and clamp it between one and some large | ||
47 | * number of pages. | ||
48 | */ | ||
49 | void | ||
50 | xfs_ihash_init(xfs_mount_t *mp) | ||
51 | { | ||
52 | __uint64_t icount; | ||
53 | uint i; | ||
54 | |||
55 | if (!mp->m_ihsize) { | ||
56 | icount = mp->m_maxicount ? mp->m_maxicount : | ||
57 | (mp->m_sb.sb_dblocks << mp->m_sb.sb_inopblog); | ||
58 | mp->m_ihsize = 1 << max_t(uint, 8, | ||
59 | (xfs_highbit64(icount) + 1) / 2); | ||
60 | mp->m_ihsize = min_t(uint, mp->m_ihsize, | ||
61 | (64 * NBPP) / sizeof(xfs_ihash_t)); | ||
62 | } | ||
63 | |||
64 | mp->m_ihash = kmem_zalloc_greedy(&mp->m_ihsize, | ||
65 | NBPC * sizeof(xfs_ihash_t), | ||
66 | mp->m_ihsize * sizeof(xfs_ihash_t), | ||
67 | KM_SLEEP | KM_MAYFAIL | KM_LARGE); | ||
68 | mp->m_ihsize /= sizeof(xfs_ihash_t); | ||
69 | for (i = 0; i < mp->m_ihsize; i++) | ||
70 | rwlock_init(&(mp->m_ihash[i].ih_lock)); | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Free up structures allocated by xfs_ihash_init, at unmount time. | ||
75 | */ | ||
76 | void | ||
77 | xfs_ihash_free(xfs_mount_t *mp) | ||
78 | { | ||
79 | kmem_free(mp->m_ihash, mp->m_ihsize * sizeof(xfs_ihash_t)); | ||
80 | mp->m_ihash = NULL; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Initialize the inode cluster hash table for the newly mounted file system. | ||
85 | * Its size is derived from the ihash table size. | ||
86 | */ | ||
87 | void | ||
88 | xfs_chash_init(xfs_mount_t *mp) | ||
89 | { | ||
90 | uint i; | ||
91 | |||
92 | mp->m_chsize = max_t(uint, 1, mp->m_ihsize / | ||
93 | (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)); | ||
94 | mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize); | ||
95 | mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize | ||
96 | * sizeof(xfs_chash_t), | ||
97 | KM_SLEEP | KM_LARGE); | ||
98 | for (i = 0; i < mp->m_chsize; i++) { | ||
99 | spinlock_init(&mp->m_chash[i].ch_lock,"xfshash"); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * Free up structures allocated by xfs_chash_init, at unmount time. | ||
105 | */ | ||
106 | void | ||
107 | xfs_chash_free(xfs_mount_t *mp) | ||
108 | { | ||
109 | int i; | ||
110 | |||
111 | for (i = 0; i < mp->m_chsize; i++) { | ||
112 | spinlock_destroy(&mp->m_chash[i].ch_lock); | ||
113 | } | ||
114 | |||
115 | kmem_free(mp->m_chash, mp->m_chsize*sizeof(xfs_chash_t)); | ||
116 | mp->m_chash = NULL; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Try to move an inode to the front of its hash list if possible | ||
121 | * (and if its not there already). Called right after obtaining | ||
122 | * the list version number and then dropping the read_lock on the | ||
123 | * hash list in question (which is done right after looking up the | ||
124 | * inode in question...). | ||
125 | */ | ||
126 | STATIC void | ||
127 | xfs_ihash_promote( | ||
128 | xfs_ihash_t *ih, | ||
129 | xfs_inode_t *ip, | ||
130 | ulong version) | ||
131 | { | ||
132 | xfs_inode_t *iq; | ||
133 | |||
134 | if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) { | ||
135 | if (likely(version == ih->ih_version)) { | ||
136 | /* remove from list */ | ||
137 | if ((iq = ip->i_next)) { | ||
138 | iq->i_prevp = ip->i_prevp; | ||
139 | } | ||
140 | *ip->i_prevp = iq; | ||
141 | |||
142 | /* insert at list head */ | ||
143 | iq = ih->ih_next; | ||
144 | iq->i_prevp = &ip->i_next; | ||
145 | ip->i_next = iq; | ||
146 | ip->i_prevp = &ih->ih_next; | ||
147 | ih->ih_next = ip; | ||
148 | } | ||
149 | write_unlock(&ih->ih_lock); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Look up an inode by number in the given file system. | 43 | * Look up an inode by number in the given file system. |
155 | * The inode is looked up in the hash table for the file system | 44 | * The inode is looked up in the cache held in each AG. |
156 | * represented by the mount point parameter mp. Each bucket of | 45 | * If the inode is found in the cache, attach it to the provided |
157 | * the hash table is guarded by an individual semaphore. | 46 | * vnode. |
158 | * | ||
159 | * If the inode is found in the hash table, its corresponding vnode | ||
160 | * is obtained with a call to vn_get(). This call takes care of | ||
161 | * coordination with the reclamation of the inode and vnode. Note | ||
162 | * that the vmap structure is filled in while holding the hash lock. | ||
163 | * This gives us the state of the inode/vnode when we found it and | ||
164 | * is used for coordination in vn_get(). | ||
165 | * | 47 | * |
166 | * If it is not in core, read it in from the file system's device and | 48 | * If it is not in core, read it in from the file system's device, |
167 | * add the inode into the hash table. | 49 | * add it to the cache and attach the provided vnode. |
168 | * | 50 | * |
169 | * The inode is locked according to the value of the lock_flags parameter. | 51 | * The inode is locked according to the value of the lock_flags parameter. |
170 | * This flag parameter indicates how and if the inode's IO lock and inode lock | 52 | * This flag parameter indicates how and if the inode's IO lock and inode lock |
@@ -192,274 +74,241 @@ xfs_iget_core( | |||
192 | xfs_inode_t **ipp, | 74 | xfs_inode_t **ipp, |
193 | xfs_daddr_t bno) | 75 | xfs_daddr_t bno) |
194 | { | 76 | { |
195 | xfs_ihash_t *ih; | ||
196 | xfs_inode_t *ip; | 77 | xfs_inode_t *ip; |
197 | xfs_inode_t *iq; | 78 | xfs_inode_t *iq; |
198 | bhv_vnode_t *inode_vp; | 79 | bhv_vnode_t *inode_vp; |
199 | ulong version; | ||
200 | int error; | 80 | int error; |
201 | /* REFERENCED */ | 81 | xfs_icluster_t *icl, *new_icl = NULL; |
202 | xfs_chash_t *ch; | 82 | unsigned long first_index, mask; |
203 | xfs_chashlist_t *chl, *chlnew; | 83 | xfs_perag_t *pag; |
204 | SPLDECL(s); | 84 | xfs_agino_t agino; |
85 | |||
86 | /* the radix tree exists only in inode capable AGs */ | ||
87 | if (XFS_INO_TO_AGNO(mp, ino) >= mp->m_maxagi) | ||
88 | return EINVAL; | ||
89 | |||
90 | /* get the perag structure and ensure that it's inode capable */ | ||
91 | pag = xfs_get_perag(mp, ino); | ||
92 | if (!pag->pagi_inodeok) | ||
93 | return EINVAL; | ||
94 | ASSERT(pag->pag_ici_init); | ||
95 | agino = XFS_INO_TO_AGINO(mp, ino); | ||
205 | 96 | ||
97 | again: | ||
98 | read_lock(&pag->pag_ici_lock); | ||
99 | ip = radix_tree_lookup(&pag->pag_ici_root, agino); | ||
206 | 100 | ||
207 | ih = XFS_IHASH(mp, ino); | 101 | if (ip != NULL) { |
102 | /* | ||
103 | * If INEW is set this inode is being set up | ||
104 | * we need to pause and try again. | ||
105 | */ | ||
106 | if (xfs_iflags_test(ip, XFS_INEW)) { | ||
107 | read_unlock(&pag->pag_ici_lock); | ||
108 | delay(1); | ||
109 | XFS_STATS_INC(xs_ig_frecycle); | ||
208 | 110 | ||
209 | again: | 111 | goto again; |
210 | read_lock(&ih->ih_lock); | 112 | } |
211 | 113 | ||
212 | for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) { | 114 | inode_vp = XFS_ITOV_NULL(ip); |
213 | if (ip->i_ino == ino) { | 115 | if (inode_vp == NULL) { |
214 | /* | 116 | /* |
215 | * If INEW is set this inode is being set up | 117 | * If IRECLAIM is set this inode is |
118 | * on its way out of the system, | ||
216 | * we need to pause and try again. | 119 | * we need to pause and try again. |
217 | */ | 120 | */ |
218 | if (xfs_iflags_test(ip, XFS_INEW)) { | 121 | if (xfs_iflags_test(ip, XFS_IRECLAIM)) { |
219 | read_unlock(&ih->ih_lock); | 122 | read_unlock(&pag->pag_ici_lock); |
220 | delay(1); | 123 | delay(1); |
221 | XFS_STATS_INC(xs_ig_frecycle); | 124 | XFS_STATS_INC(xs_ig_frecycle); |
222 | 125 | ||
223 | goto again; | 126 | goto again; |
224 | } | 127 | } |
128 | ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | ||
225 | 129 | ||
226 | inode_vp = XFS_ITOV_NULL(ip); | 130 | /* |
227 | if (inode_vp == NULL) { | 131 | * If lookup is racing with unlink, then we |
228 | /* | 132 | * should return an error immediately so we |
229 | * If IRECLAIM is set this inode is | 133 | * don't remove it from the reclaim list and |
230 | * on its way out of the system, | 134 | * potentially leak the inode. |
231 | * we need to pause and try again. | 135 | */ |
232 | */ | 136 | if ((ip->i_d.di_mode == 0) && |
233 | if (xfs_iflags_test(ip, XFS_IRECLAIM)) { | 137 | !(flags & XFS_IGET_CREATE)) { |
234 | read_unlock(&ih->ih_lock); | 138 | read_unlock(&pag->pag_ici_lock); |
235 | delay(1); | 139 | xfs_put_perag(mp, pag); |
236 | XFS_STATS_INC(xs_ig_frecycle); | 140 | return ENOENT; |
237 | 141 | } | |
238 | goto again; | 142 | |
239 | } | 143 | /* |
240 | ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | 144 | * There may be transactions sitting in the |
241 | 145 | * incore log buffers or being flushed to disk | |
242 | /* | 146 | * at this time. We can't clear the |
243 | * If lookup is racing with unlink, then we | 147 | * XFS_IRECLAIMABLE flag until these |
244 | * should return an error immediately so we | 148 | * transactions have hit the disk, otherwise we |
245 | * don't remove it from the reclaim list and | 149 | * will void the guarantee the flag provides |
246 | * potentially leak the inode. | 150 | * xfs_iunpin() |
247 | */ | 151 | */ |
248 | if ((ip->i_d.di_mode == 0) && | 152 | if (xfs_ipincount(ip)) { |
249 | !(flags & XFS_IGET_CREATE)) { | 153 | read_unlock(&pag->pag_ici_lock); |
250 | read_unlock(&ih->ih_lock); | 154 | xfs_log_force(mp, 0, |
251 | return ENOENT; | 155 | XFS_LOG_FORCE|XFS_LOG_SYNC); |
252 | } | 156 | XFS_STATS_INC(xs_ig_frecycle); |
253 | 157 | goto again; | |
254 | /* | 158 | } |
255 | * There may be transactions sitting in the | ||
256 | * incore log buffers or being flushed to disk | ||
257 | * at this time. We can't clear the | ||
258 | * XFS_IRECLAIMABLE flag until these | ||
259 | * transactions have hit the disk, otherwise we | ||
260 | * will void the guarantee the flag provides | ||
261 | * xfs_iunpin() | ||
262 | */ | ||
263 | if (xfs_ipincount(ip)) { | ||
264 | read_unlock(&ih->ih_lock); | ||
265 | xfs_log_force(mp, 0, | ||
266 | XFS_LOG_FORCE|XFS_LOG_SYNC); | ||
267 | XFS_STATS_INC(xs_ig_frecycle); | ||
268 | goto again; | ||
269 | } | ||
270 | |||
271 | vn_trace_exit(vp, "xfs_iget.alloc", | ||
272 | (inst_t *)__return_address); | ||
273 | 159 | ||
274 | XFS_STATS_INC(xs_ig_found); | 160 | vn_trace_exit(ip, "xfs_iget.alloc", |
161 | (inst_t *)__return_address); | ||
275 | 162 | ||
276 | xfs_iflags_clear(ip, XFS_IRECLAIMABLE); | 163 | XFS_STATS_INC(xs_ig_found); |
277 | version = ih->ih_version; | ||
278 | read_unlock(&ih->ih_lock); | ||
279 | xfs_ihash_promote(ih, ip, version); | ||
280 | 164 | ||
281 | XFS_MOUNT_ILOCK(mp); | 165 | xfs_iflags_clear(ip, XFS_IRECLAIMABLE); |
282 | list_del_init(&ip->i_reclaim); | 166 | read_unlock(&pag->pag_ici_lock); |
283 | XFS_MOUNT_IUNLOCK(mp); | ||
284 | 167 | ||
285 | goto finish_inode; | 168 | XFS_MOUNT_ILOCK(mp); |
169 | list_del_init(&ip->i_reclaim); | ||
170 | XFS_MOUNT_IUNLOCK(mp); | ||
286 | 171 | ||
287 | } else if (vp != inode_vp) { | 172 | goto finish_inode; |
288 | struct inode *inode = vn_to_inode(inode_vp); | ||
289 | 173 | ||
290 | /* The inode is being torn down, pause and | 174 | } else if (vp != inode_vp) { |
291 | * try again. | 175 | struct inode *inode = vn_to_inode(inode_vp); |
292 | */ | ||
293 | if (inode->i_state & (I_FREEING | I_CLEAR)) { | ||
294 | read_unlock(&ih->ih_lock); | ||
295 | delay(1); | ||
296 | XFS_STATS_INC(xs_ig_frecycle); | ||
297 | 176 | ||
298 | goto again; | 177 | /* The inode is being torn down, pause and |
299 | } | 178 | * try again. |
300 | /* Chances are the other vnode (the one in the inode) is being torn | 179 | */ |
301 | * down right now, and we landed on top of it. Question is, what do | 180 | if (inode->i_state & (I_FREEING | I_CLEAR)) { |
302 | * we do? Unhook the old inode and hook up the new one? | 181 | read_unlock(&pag->pag_ici_lock); |
303 | */ | 182 | delay(1); |
304 | cmn_err(CE_PANIC, | 183 | XFS_STATS_INC(xs_ig_frecycle); |
305 | "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p", | 184 | |
306 | inode_vp, vp); | 185 | goto again; |
307 | } | 186 | } |
187 | /* Chances are the other vnode (the one in the inode) is being torn | ||
188 | * down right now, and we landed on top of it. Question is, what do | ||
189 | * we do? Unhook the old inode and hook up the new one? | ||
190 | */ | ||
191 | cmn_err(CE_PANIC, | ||
192 | "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p", | ||
193 | inode_vp, vp); | ||
194 | } | ||
308 | 195 | ||
309 | /* | 196 | /* |
310 | * Inode cache hit: if ip is not at the front of | 197 | * Inode cache hit |
311 | * its hash chain, move it there now. | 198 | */ |
312 | * Do this with the lock held for update, but | 199 | read_unlock(&pag->pag_ici_lock); |
313 | * do statistics after releasing the lock. | 200 | XFS_STATS_INC(xs_ig_found); |
314 | */ | ||
315 | version = ih->ih_version; | ||
316 | read_unlock(&ih->ih_lock); | ||
317 | xfs_ihash_promote(ih, ip, version); | ||
318 | XFS_STATS_INC(xs_ig_found); | ||
319 | 201 | ||
320 | finish_inode: | 202 | finish_inode: |
321 | if (ip->i_d.di_mode == 0) { | 203 | if (ip->i_d.di_mode == 0) { |
322 | if (!(flags & XFS_IGET_CREATE)) | 204 | if (!(flags & XFS_IGET_CREATE)) { |
323 | return ENOENT; | 205 | xfs_put_perag(mp, pag); |
324 | xfs_iocore_inode_reinit(ip); | 206 | return ENOENT; |
325 | } | 207 | } |
208 | xfs_iocore_inode_reinit(ip); | ||
209 | } | ||
326 | 210 | ||
327 | if (lock_flags != 0) | 211 | if (lock_flags != 0) |
328 | xfs_ilock(ip, lock_flags); | 212 | xfs_ilock(ip, lock_flags); |
329 | 213 | ||
330 | xfs_iflags_clear(ip, XFS_ISTALE); | 214 | xfs_iflags_clear(ip, XFS_ISTALE); |
331 | vn_trace_exit(vp, "xfs_iget.found", | 215 | vn_trace_exit(ip, "xfs_iget.found", |
332 | (inst_t *)__return_address); | 216 | (inst_t *)__return_address); |
333 | goto return_ip; | 217 | goto return_ip; |
334 | } | ||
335 | } | 218 | } |
336 | 219 | ||
337 | /* | 220 | /* |
338 | * Inode cache miss: save the hash chain version stamp and unlock | 221 | * Inode cache miss |
339 | * the chain, so we don't deadlock in vn_alloc. | ||
340 | */ | 222 | */ |
223 | read_unlock(&pag->pag_ici_lock); | ||
341 | XFS_STATS_INC(xs_ig_missed); | 224 | XFS_STATS_INC(xs_ig_missed); |
342 | 225 | ||
343 | version = ih->ih_version; | ||
344 | |||
345 | read_unlock(&ih->ih_lock); | ||
346 | |||
347 | /* | 226 | /* |
348 | * Read the disk inode attributes into a new inode structure and get | 227 | * Read the disk inode attributes into a new inode structure and get |
349 | * a new vnode for it. This should also initialize i_ino and i_mount. | 228 | * a new vnode for it. This should also initialize i_ino and i_mount. |
350 | */ | 229 | */ |
351 | error = xfs_iread(mp, tp, ino, &ip, bno, | 230 | error = xfs_iread(mp, tp, ino, &ip, bno, |
352 | (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0); | 231 | (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0); |
353 | if (error) | 232 | if (error) { |
233 | xfs_put_perag(mp, pag); | ||
354 | return error; | 234 | return error; |
235 | } | ||
355 | 236 | ||
356 | vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address); | 237 | vn_trace_exit(ip, "xfs_iget.alloc", (inst_t *)__return_address); |
357 | 238 | ||
358 | xfs_inode_lock_init(ip, vp); | 239 | xfs_inode_lock_init(ip, vp); |
359 | xfs_iocore_inode_init(ip); | 240 | xfs_iocore_inode_init(ip); |
360 | |||
361 | if (lock_flags) | 241 | if (lock_flags) |
362 | xfs_ilock(ip, lock_flags); | 242 | xfs_ilock(ip, lock_flags); |
363 | 243 | ||
364 | if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { | 244 | if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { |
365 | xfs_idestroy(ip); | 245 | xfs_idestroy(ip); |
246 | xfs_put_perag(mp, pag); | ||
366 | return ENOENT; | 247 | return ENOENT; |
367 | } | 248 | } |
368 | 249 | ||
369 | /* | 250 | /* |
370 | * Put ip on its hash chain, unless someone else hashed a duplicate | 251 | * This is a bit messy - we preallocate everything we _might_ |
371 | * after we released the hash lock. | 252 | * need before we pick up the ici lock. That way we don't have to |
253 | * juggle locks and go all the way back to the start. | ||
372 | */ | 254 | */ |
373 | write_lock(&ih->ih_lock); | 255 | new_icl = kmem_zone_alloc(xfs_icluster_zone, KM_SLEEP); |
256 | if (radix_tree_preload(GFP_KERNEL)) { | ||
257 | delay(1); | ||
258 | goto again; | ||
259 | } | ||
260 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); | ||
261 | first_index = agino & mask; | ||
262 | write_lock(&pag->pag_ici_lock); | ||
374 | 263 | ||
375 | if (ih->ih_version != version) { | 264 | /* |
376 | for (iq = ih->ih_next; iq != NULL; iq = iq->i_next) { | 265 | * Find the cluster if it exists |
377 | if (iq->i_ino == ino) { | 266 | */ |
378 | write_unlock(&ih->ih_lock); | 267 | icl = NULL; |
379 | xfs_idestroy(ip); | 268 | if (radix_tree_gang_lookup(&pag->pag_ici_root, (void**)&iq, |
269 | first_index, 1)) { | ||
270 | if ((iq->i_ino & mask) == first_index) | ||
271 | icl = iq->i_cluster; | ||
272 | } | ||
380 | 273 | ||
381 | XFS_STATS_INC(xs_ig_dup); | 274 | /* |
382 | goto again; | 275 | * insert the new inode |
383 | } | 276 | */ |
384 | } | 277 | error = radix_tree_insert(&pag->pag_ici_root, agino, ip); |
278 | if (unlikely(error)) { | ||
279 | BUG_ON(error != -EEXIST); | ||
280 | write_unlock(&pag->pag_ici_lock); | ||
281 | radix_tree_preload_end(); | ||
282 | xfs_idestroy(ip); | ||
283 | XFS_STATS_INC(xs_ig_dup); | ||
284 | goto again; | ||
385 | } | 285 | } |
386 | 286 | ||
387 | /* | 287 | /* |
388 | * These values _must_ be set before releasing ihlock! | 288 | * These values _must_ be set before releasing ihlock! |
389 | */ | 289 | */ |
390 | ip->i_hash = ih; | ||
391 | if ((iq = ih->ih_next)) { | ||
392 | iq->i_prevp = &ip->i_next; | ||
393 | } | ||
394 | ip->i_next = iq; | ||
395 | ip->i_prevp = &ih->ih_next; | ||
396 | ih->ih_next = ip; | ||
397 | ip->i_udquot = ip->i_gdquot = NULL; | 290 | ip->i_udquot = ip->i_gdquot = NULL; |
398 | ih->ih_version++; | ||
399 | xfs_iflags_set(ip, XFS_INEW); | 291 | xfs_iflags_set(ip, XFS_INEW); |
400 | write_unlock(&ih->ih_lock); | ||
401 | 292 | ||
402 | /* | 293 | ASSERT(ip->i_cluster == NULL); |
403 | * put ip on its cluster's hash chain | ||
404 | */ | ||
405 | ASSERT(ip->i_chash == NULL && ip->i_cprev == NULL && | ||
406 | ip->i_cnext == NULL); | ||
407 | |||
408 | chlnew = NULL; | ||
409 | ch = XFS_CHASH(mp, ip->i_blkno); | ||
410 | chlredo: | ||
411 | s = mutex_spinlock(&ch->ch_lock); | ||
412 | for (chl = ch->ch_list; chl != NULL; chl = chl->chl_next) { | ||
413 | if (chl->chl_blkno == ip->i_blkno) { | ||
414 | |||
415 | /* insert this inode into the doubly-linked list | ||
416 | * where chl points */ | ||
417 | if ((iq = chl->chl_ip)) { | ||
418 | ip->i_cprev = iq->i_cprev; | ||
419 | iq->i_cprev->i_cnext = ip; | ||
420 | iq->i_cprev = ip; | ||
421 | ip->i_cnext = iq; | ||
422 | } else { | ||
423 | ip->i_cnext = ip; | ||
424 | ip->i_cprev = ip; | ||
425 | } | ||
426 | chl->chl_ip = ip; | ||
427 | ip->i_chash = chl; | ||
428 | break; | ||
429 | } | ||
430 | } | ||
431 | 294 | ||
432 | /* no hash list found for this block; add a new hash list */ | 295 | if (!icl) { |
433 | if (chl == NULL) { | 296 | spin_lock_init(&new_icl->icl_lock); |
434 | if (chlnew == NULL) { | 297 | INIT_HLIST_HEAD(&new_icl->icl_inodes); |
435 | mutex_spinunlock(&ch->ch_lock, s); | 298 | icl = new_icl; |
436 | ASSERT(xfs_chashlist_zone != NULL); | 299 | new_icl = NULL; |
437 | chlnew = (xfs_chashlist_t *) | ||
438 | kmem_zone_alloc(xfs_chashlist_zone, | ||
439 | KM_SLEEP); | ||
440 | ASSERT(chlnew != NULL); | ||
441 | goto chlredo; | ||
442 | } else { | ||
443 | ip->i_cnext = ip; | ||
444 | ip->i_cprev = ip; | ||
445 | ip->i_chash = chlnew; | ||
446 | chlnew->chl_ip = ip; | ||
447 | chlnew->chl_blkno = ip->i_blkno; | ||
448 | if (ch->ch_list) | ||
449 | ch->ch_list->chl_prev = chlnew; | ||
450 | chlnew->chl_next = ch->ch_list; | ||
451 | chlnew->chl_prev = NULL; | ||
452 | ch->ch_list = chlnew; | ||
453 | chlnew = NULL; | ||
454 | } | ||
455 | } else { | 300 | } else { |
456 | if (chlnew != NULL) { | 301 | ASSERT(!hlist_empty(&icl->icl_inodes)); |
457 | kmem_zone_free(xfs_chashlist_zone, chlnew); | ||
458 | } | ||
459 | } | 302 | } |
303 | spin_lock(&icl->icl_lock); | ||
304 | hlist_add_head(&ip->i_cnode, &icl->icl_inodes); | ||
305 | ip->i_cluster = icl; | ||
306 | spin_unlock(&icl->icl_lock); | ||
460 | 307 | ||
461 | mutex_spinunlock(&ch->ch_lock, s); | 308 | write_unlock(&pag->pag_ici_lock); |
462 | 309 | radix_tree_preload_end(); | |
310 | if (new_icl) | ||
311 | kmem_zone_free(xfs_icluster_zone, new_icl); | ||
463 | 312 | ||
464 | /* | 313 | /* |
465 | * Link ip to its mount and thread it on the mount's inode list. | 314 | * Link ip to its mount and thread it on the mount's inode list. |
@@ -478,6 +327,7 @@ finish_inode: | |||
478 | mp->m_inodes = ip; | 327 | mp->m_inodes = ip; |
479 | 328 | ||
480 | XFS_MOUNT_IUNLOCK(mp); | 329 | XFS_MOUNT_IUNLOCK(mp); |
330 | xfs_put_perag(mp, pag); | ||
481 | 331 | ||
482 | return_ip: | 332 | return_ip: |
483 | ASSERT(ip->i_df.if_ext_max == | 333 | ASSERT(ip->i_df.if_ext_max == |
@@ -486,14 +336,14 @@ finish_inode: | |||
486 | ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) == | 336 | ASSERT(((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) != 0) == |
487 | ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0)); | 337 | ((ip->i_iocore.io_flags & XFS_IOCORE_RT) != 0)); |
488 | 338 | ||
339 | xfs_iflags_set(ip, XFS_IMODIFIED); | ||
489 | *ipp = ip; | 340 | *ipp = ip; |
490 | 341 | ||
491 | /* | 342 | /* |
492 | * If we have a real type for an on-disk inode, we can set ops(&unlock) | 343 | * If we have a real type for an on-disk inode, we can set ops(&unlock) |
493 | * now. If it's a new inode being created, xfs_ialloc will handle it. | 344 | * now. If it's a new inode being created, xfs_ialloc will handle it. |
494 | */ | 345 | */ |
495 | bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1); | 346 | xfs_initialize_vnode(mp, vp, ip); |
496 | |||
497 | return 0; | 347 | return 0; |
498 | } | 348 | } |
499 | 349 | ||
@@ -519,7 +369,8 @@ xfs_iget( | |||
519 | XFS_STATS_INC(xs_ig_attempts); | 369 | XFS_STATS_INC(xs_ig_attempts); |
520 | 370 | ||
521 | retry: | 371 | retry: |
522 | if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) { | 372 | inode = iget_locked(mp->m_super, ino); |
373 | if (inode) { | ||
523 | xfs_inode_t *ip; | 374 | xfs_inode_t *ip; |
524 | 375 | ||
525 | vp = vn_from_inode(inode); | 376 | vp = vn_from_inode(inode); |
@@ -570,8 +421,8 @@ xfs_inode_lock_init( | |||
570 | bhv_vnode_t *vp) | 421 | bhv_vnode_t *vp) |
571 | { | 422 | { |
572 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | 423 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, |
573 | "xfsino", (long)vp->v_number); | 424 | "xfsino", ip->i_ino); |
574 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number); | 425 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); |
575 | init_waitqueue_head(&ip->i_ipin_wait); | 426 | init_waitqueue_head(&ip->i_ipin_wait); |
576 | atomic_set(&ip->i_pincount, 0); | 427 | atomic_set(&ip->i_pincount, 0); |
577 | initnsema(&ip->i_flock, 1, "xfsfino"); | 428 | initnsema(&ip->i_flock, 1, "xfsfino"); |
@@ -587,32 +438,19 @@ xfs_inode_incore(xfs_mount_t *mp, | |||
587 | xfs_ino_t ino, | 438 | xfs_ino_t ino, |
588 | xfs_trans_t *tp) | 439 | xfs_trans_t *tp) |
589 | { | 440 | { |
590 | xfs_ihash_t *ih; | ||
591 | xfs_inode_t *ip; | 441 | xfs_inode_t *ip; |
592 | ulong version; | 442 | xfs_perag_t *pag; |
593 | 443 | ||
594 | ih = XFS_IHASH(mp, ino); | 444 | pag = xfs_get_perag(mp, ino); |
595 | read_lock(&ih->ih_lock); | 445 | read_lock(&pag->pag_ici_lock); |
596 | for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) { | 446 | ip = radix_tree_lookup(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ino)); |
597 | if (ip->i_ino == ino) { | 447 | read_unlock(&pag->pag_ici_lock); |
598 | /* | 448 | xfs_put_perag(mp, pag); |
599 | * If we find it and tp matches, return it. | 449 | |
600 | * Also move it to the front of the hash list | 450 | /* the returned inode must match the transaction */ |
601 | * if we find it and it is not already there. | 451 | if (ip && (ip->i_transp != tp)) |
602 | * Otherwise break from the loop and return | 452 | return NULL; |
603 | * NULL. | 453 | return ip; |
604 | */ | ||
605 | if (ip->i_transp == tp) { | ||
606 | version = ih->ih_version; | ||
607 | read_unlock(&ih->ih_lock); | ||
608 | xfs_ihash_promote(ih, ip, version); | ||
609 | return (ip); | ||
610 | } | ||
611 | break; | ||
612 | } | ||
613 | } | ||
614 | read_unlock(&ih->ih_lock); | ||
615 | return (NULL); | ||
616 | } | 454 | } |
617 | 455 | ||
618 | /* | 456 | /* |
@@ -629,7 +467,7 @@ xfs_iput(xfs_inode_t *ip, | |||
629 | { | 467 | { |
630 | bhv_vnode_t *vp = XFS_ITOV(ip); | 468 | bhv_vnode_t *vp = XFS_ITOV(ip); |
631 | 469 | ||
632 | vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address); | 470 | vn_trace_entry(ip, "xfs_iput", (inst_t *)__return_address); |
633 | xfs_iunlock(ip, lock_flags); | 471 | xfs_iunlock(ip, lock_flags); |
634 | VN_RELE(vp); | 472 | VN_RELE(vp); |
635 | } | 473 | } |
@@ -644,7 +482,7 @@ xfs_iput_new(xfs_inode_t *ip, | |||
644 | bhv_vnode_t *vp = XFS_ITOV(ip); | 482 | bhv_vnode_t *vp = XFS_ITOV(ip); |
645 | struct inode *inode = vn_to_inode(vp); | 483 | struct inode *inode = vn_to_inode(vp); |
646 | 484 | ||
647 | vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); | 485 | vn_trace_entry(ip, "xfs_iput_new", (inst_t *)__return_address); |
648 | 486 | ||
649 | if ((ip->i_d.di_mode == 0)) { | 487 | if ((ip->i_d.di_mode == 0)) { |
650 | ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | 488 | ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); |
@@ -699,7 +537,8 @@ xfs_ireclaim(xfs_inode_t *ip) | |||
699 | */ | 537 | */ |
700 | vp = XFS_ITOV_NULL(ip); | 538 | vp = XFS_ITOV_NULL(ip); |
701 | if (vp) { | 539 | if (vp) { |
702 | vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); | 540 | vn_to_inode(vp)->i_private = NULL; |
541 | ip->i_vnode = NULL; | ||
703 | } | 542 | } |
704 | 543 | ||
705 | /* | 544 | /* |
@@ -718,58 +557,26 @@ void | |||
718 | xfs_iextract( | 557 | xfs_iextract( |
719 | xfs_inode_t *ip) | 558 | xfs_inode_t *ip) |
720 | { | 559 | { |
721 | xfs_ihash_t *ih; | 560 | xfs_mount_t *mp = ip->i_mount; |
561 | xfs_perag_t *pag = xfs_get_perag(mp, ip->i_ino); | ||
722 | xfs_inode_t *iq; | 562 | xfs_inode_t *iq; |
723 | xfs_mount_t *mp; | 563 | |
724 | xfs_chash_t *ch; | 564 | write_lock(&pag->pag_ici_lock); |
725 | xfs_chashlist_t *chl, *chm; | 565 | radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ip->i_ino)); |
726 | SPLDECL(s); | 566 | write_unlock(&pag->pag_ici_lock); |
727 | 567 | xfs_put_perag(mp, pag); | |
728 | ih = ip->i_hash; | ||
729 | write_lock(&ih->ih_lock); | ||
730 | if ((iq = ip->i_next)) { | ||
731 | iq->i_prevp = ip->i_prevp; | ||
732 | } | ||
733 | *ip->i_prevp = iq; | ||
734 | ih->ih_version++; | ||
735 | write_unlock(&ih->ih_lock); | ||
736 | 568 | ||
737 | /* | 569 | /* |
738 | * Remove from cluster hash list | 570 | * Remove from cluster list |
739 | * 1) delete the chashlist if this is the last inode on the chashlist | ||
740 | * 2) unchain from list of inodes | ||
741 | * 3) point chashlist->chl_ip to 'chl_next' if to this inode. | ||
742 | */ | 571 | */ |
743 | mp = ip->i_mount; | 572 | mp = ip->i_mount; |
744 | ch = XFS_CHASH(mp, ip->i_blkno); | 573 | spin_lock(&ip->i_cluster->icl_lock); |
745 | s = mutex_spinlock(&ch->ch_lock); | 574 | hlist_del(&ip->i_cnode); |
746 | 575 | spin_unlock(&ip->i_cluster->icl_lock); | |
747 | if (ip->i_cnext == ip) { | 576 | |
748 | /* Last inode on chashlist */ | 577 | /* was last inode in cluster? */ |
749 | ASSERT(ip->i_cnext == ip && ip->i_cprev == ip); | 578 | if (hlist_empty(&ip->i_cluster->icl_inodes)) |
750 | ASSERT(ip->i_chash != NULL); | 579 | kmem_zone_free(xfs_icluster_zone, ip->i_cluster); |
751 | chm=NULL; | ||
752 | chl = ip->i_chash; | ||
753 | if (chl->chl_prev) | ||
754 | chl->chl_prev->chl_next = chl->chl_next; | ||
755 | else | ||
756 | ch->ch_list = chl->chl_next; | ||
757 | if (chl->chl_next) | ||
758 | chl->chl_next->chl_prev = chl->chl_prev; | ||
759 | kmem_zone_free(xfs_chashlist_zone, chl); | ||
760 | } else { | ||
761 | /* delete one inode from a non-empty list */ | ||
762 | iq = ip->i_cnext; | ||
763 | iq->i_cprev = ip->i_cprev; | ||
764 | ip->i_cprev->i_cnext = iq; | ||
765 | if (ip->i_chash->chl_ip == ip) { | ||
766 | ip->i_chash->chl_ip = iq; | ||
767 | } | ||
768 | ip->i_chash = __return_address; | ||
769 | ip->i_cprev = __return_address; | ||
770 | ip->i_cnext = __return_address; | ||
771 | } | ||
772 | mutex_spinunlock(&ch->ch_lock, s); | ||
773 | 580 | ||
774 | /* | 581 | /* |
775 | * Remove from mount's inode list. | 582 | * Remove from mount's inode list. |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index cdc4c28926d0..abf509a88915 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -49,12 +49,11 @@ | |||
49 | #include "xfs_quota.h" | 49 | #include "xfs_quota.h" |
50 | #include "xfs_acl.h" | 50 | #include "xfs_acl.h" |
51 | #include "xfs_filestream.h" | 51 | #include "xfs_filestream.h" |
52 | 52 | #include "xfs_vnodeops.h" | |
53 | #include <linux/log2.h> | ||
54 | 53 | ||
55 | kmem_zone_t *xfs_ifork_zone; | 54 | kmem_zone_t *xfs_ifork_zone; |
56 | kmem_zone_t *xfs_inode_zone; | 55 | kmem_zone_t *xfs_inode_zone; |
57 | kmem_zone_t *xfs_chashlist_zone; | 56 | kmem_zone_t *xfs_icluster_zone; |
58 | 57 | ||
59 | /* | 58 | /* |
60 | * Used in xfs_itruncate(). This is the maximum number of extents | 59 | * Used in xfs_itruncate(). This is the maximum number of extents |
@@ -67,7 +66,6 @@ STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int); | |||
67 | STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); | 66 | STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); |
68 | STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); | 67 | STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); |
69 | 68 | ||
70 | |||
71 | #ifdef DEBUG | 69 | #ifdef DEBUG |
72 | /* | 70 | /* |
73 | * Make sure that the extents in the given memory buffer | 71 | * Make sure that the extents in the given memory buffer |
@@ -77,28 +75,23 @@ STATIC void | |||
77 | xfs_validate_extents( | 75 | xfs_validate_extents( |
78 | xfs_ifork_t *ifp, | 76 | xfs_ifork_t *ifp, |
79 | int nrecs, | 77 | int nrecs, |
80 | int disk, | ||
81 | xfs_exntfmt_t fmt) | 78 | xfs_exntfmt_t fmt) |
82 | { | 79 | { |
83 | xfs_bmbt_rec_t *ep; | ||
84 | xfs_bmbt_irec_t irec; | 80 | xfs_bmbt_irec_t irec; |
85 | xfs_bmbt_rec_t rec; | 81 | xfs_bmbt_rec_host_t rec; |
86 | int i; | 82 | int i; |
87 | 83 | ||
88 | for (i = 0; i < nrecs; i++) { | 84 | for (i = 0; i < nrecs; i++) { |
89 | ep = xfs_iext_get_ext(ifp, i); | 85 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); |
90 | rec.l0 = get_unaligned((__uint64_t*)&ep->l0); | 86 | rec.l0 = get_unaligned(&ep->l0); |
91 | rec.l1 = get_unaligned((__uint64_t*)&ep->l1); | 87 | rec.l1 = get_unaligned(&ep->l1); |
92 | if (disk) | 88 | xfs_bmbt_get_all(&rec, &irec); |
93 | xfs_bmbt_disk_get_all(&rec, &irec); | ||
94 | else | ||
95 | xfs_bmbt_get_all(&rec, &irec); | ||
96 | if (fmt == XFS_EXTFMT_NOSTATE) | 89 | if (fmt == XFS_EXTFMT_NOSTATE) |
97 | ASSERT(irec.br_state == XFS_EXT_NORM); | 90 | ASSERT(irec.br_state == XFS_EXT_NORM); |
98 | } | 91 | } |
99 | } | 92 | } |
100 | #else /* DEBUG */ | 93 | #else /* DEBUG */ |
101 | #define xfs_validate_extents(ifp, nrecs, disk, fmt) | 94 | #define xfs_validate_extents(ifp, nrecs, fmt) |
102 | #endif /* DEBUG */ | 95 | #endif /* DEBUG */ |
103 | 96 | ||
104 | /* | 97 | /* |
@@ -201,8 +194,8 @@ xfs_inotobp( | |||
201 | } | 194 | } |
202 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, 0); | 195 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, 0); |
203 | di_ok = | 196 | di_ok = |
204 | INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && | 197 | be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC && |
205 | XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); | 198 | XFS_DINODE_GOOD_VERSION(dip->di_core.di_version); |
206 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, | 199 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, |
207 | XFS_RANDOM_ITOBP_INOTOBP))) { | 200 | XFS_RANDOM_ITOBP_INOTOBP))) { |
208 | XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip); | 201 | XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip); |
@@ -346,8 +339,8 @@ xfs_itobp( | |||
346 | 339 | ||
347 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, | 340 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, |
348 | (i << mp->m_sb.sb_inodelog)); | 341 | (i << mp->m_sb.sb_inodelog)); |
349 | di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && | 342 | di_ok = be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC && |
350 | XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); | 343 | XFS_DINODE_GOOD_VERSION(dip->di_core.di_version); |
351 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, | 344 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, |
352 | XFS_ERRTAG_ITOBP_INOTOBP, | 345 | XFS_ERRTAG_ITOBP_INOTOBP, |
353 | XFS_RANDOM_ITOBP_INOTOBP))) { | 346 | XFS_RANDOM_ITOBP_INOTOBP))) { |
@@ -361,7 +354,7 @@ xfs_itobp( | |||
361 | "daddr %lld #%d (magic=%x)", | 354 | "daddr %lld #%d (magic=%x)", |
362 | XFS_BUFTARG_NAME(mp->m_ddev_targp), | 355 | XFS_BUFTARG_NAME(mp->m_ddev_targp), |
363 | (unsigned long long)imap.im_blkno, i, | 356 | (unsigned long long)imap.im_blkno, i, |
364 | INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); | 357 | be16_to_cpu(dip->di_core.di_magic)); |
365 | #endif | 358 | #endif |
366 | XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH, | 359 | XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH, |
367 | mp, dip); | 360 | mp, dip); |
@@ -407,27 +400,26 @@ xfs_iformat( | |||
407 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | 400 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); |
408 | error = 0; | 401 | error = 0; |
409 | 402 | ||
410 | if (unlikely( | 403 | if (unlikely(be32_to_cpu(dip->di_core.di_nextents) + |
411 | INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) + | 404 | be16_to_cpu(dip->di_core.di_anextents) > |
412 | INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) > | 405 | be64_to_cpu(dip->di_core.di_nblocks))) { |
413 | INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) { | ||
414 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 406 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
415 | "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", | 407 | "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", |
416 | (unsigned long long)ip->i_ino, | 408 | (unsigned long long)ip->i_ino, |
417 | (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) | 409 | (int)(be32_to_cpu(dip->di_core.di_nextents) + |
418 | + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)), | 410 | be16_to_cpu(dip->di_core.di_anextents)), |
419 | (unsigned long long) | 411 | (unsigned long long) |
420 | INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT)); | 412 | be64_to_cpu(dip->di_core.di_nblocks)); |
421 | XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, | 413 | XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, |
422 | ip->i_mount, dip); | 414 | ip->i_mount, dip); |
423 | return XFS_ERROR(EFSCORRUPTED); | 415 | return XFS_ERROR(EFSCORRUPTED); |
424 | } | 416 | } |
425 | 417 | ||
426 | if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) { | 418 | if (unlikely(dip->di_core.di_forkoff > ip->i_mount->m_sb.sb_inodesize)) { |
427 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 419 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
428 | "corrupt dinode %Lu, forkoff = 0x%x.", | 420 | "corrupt dinode %Lu, forkoff = 0x%x.", |
429 | (unsigned long long)ip->i_ino, | 421 | (unsigned long long)ip->i_ino, |
430 | (int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT))); | 422 | dip->di_core.di_forkoff); |
431 | XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, | 423 | XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, |
432 | ip->i_mount, dip); | 424 | ip->i_mount, dip); |
433 | return XFS_ERROR(EFSCORRUPTED); | 425 | return XFS_ERROR(EFSCORRUPTED); |
@@ -438,25 +430,25 @@ xfs_iformat( | |||
438 | case S_IFCHR: | 430 | case S_IFCHR: |
439 | case S_IFBLK: | 431 | case S_IFBLK: |
440 | case S_IFSOCK: | 432 | case S_IFSOCK: |
441 | if (unlikely(INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)) { | 433 | if (unlikely(dip->di_core.di_format != XFS_DINODE_FMT_DEV)) { |
442 | XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, | 434 | XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, |
443 | ip->i_mount, dip); | 435 | ip->i_mount, dip); |
444 | return XFS_ERROR(EFSCORRUPTED); | 436 | return XFS_ERROR(EFSCORRUPTED); |
445 | } | 437 | } |
446 | ip->i_d.di_size = 0; | 438 | ip->i_d.di_size = 0; |
447 | ip->i_size = 0; | 439 | ip->i_size = 0; |
448 | ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); | 440 | ip->i_df.if_u2.if_rdev = be32_to_cpu(dip->di_u.di_dev); |
449 | break; | 441 | break; |
450 | 442 | ||
451 | case S_IFREG: | 443 | case S_IFREG: |
452 | case S_IFLNK: | 444 | case S_IFLNK: |
453 | case S_IFDIR: | 445 | case S_IFDIR: |
454 | switch (INT_GET(dip->di_core.di_format, ARCH_CONVERT)) { | 446 | switch (dip->di_core.di_format) { |
455 | case XFS_DINODE_FMT_LOCAL: | 447 | case XFS_DINODE_FMT_LOCAL: |
456 | /* | 448 | /* |
457 | * no local regular files yet | 449 | * no local regular files yet |
458 | */ | 450 | */ |
459 | if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) { | 451 | if (unlikely((be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFREG)) { |
460 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 452 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
461 | "corrupt inode %Lu " | 453 | "corrupt inode %Lu " |
462 | "(local format for regular file).", | 454 | "(local format for regular file).", |
@@ -467,7 +459,7 @@ xfs_iformat( | |||
467 | return XFS_ERROR(EFSCORRUPTED); | 459 | return XFS_ERROR(EFSCORRUPTED); |
468 | } | 460 | } |
469 | 461 | ||
470 | di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); | 462 | di_size = be64_to_cpu(dip->di_core.di_size); |
471 | if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { | 463 | if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { |
472 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 464 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
473 | "corrupt inode %Lu " | 465 | "corrupt inode %Lu " |
@@ -509,7 +501,7 @@ xfs_iformat( | |||
509 | ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); | 501 | ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); |
510 | ip->i_afp->if_ext_max = | 502 | ip->i_afp->if_ext_max = |
511 | XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | 503 | XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); |
512 | switch (INT_GET(dip->di_core.di_aformat, ARCH_CONVERT)) { | 504 | switch (dip->di_core.di_aformat) { |
513 | case XFS_DINODE_FMT_LOCAL: | 505 | case XFS_DINODE_FMT_LOCAL: |
514 | atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); | 506 | atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); |
515 | size = be16_to_cpu(atp->hdr.totsize); | 507 | size = be16_to_cpu(atp->hdr.totsize); |
@@ -602,7 +594,7 @@ xfs_iformat_extents( | |||
602 | xfs_dinode_t *dip, | 594 | xfs_dinode_t *dip, |
603 | int whichfork) | 595 | int whichfork) |
604 | { | 596 | { |
605 | xfs_bmbt_rec_t *ep, *dp; | 597 | xfs_bmbt_rec_t *dp; |
606 | xfs_ifork_t *ifp; | 598 | xfs_ifork_t *ifp; |
607 | int nex; | 599 | int nex; |
608 | int size; | 600 | int size; |
@@ -637,13 +629,11 @@ xfs_iformat_extents( | |||
637 | ifp->if_bytes = size; | 629 | ifp->if_bytes = size; |
638 | if (size) { | 630 | if (size) { |
639 | dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); | 631 | dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); |
640 | xfs_validate_extents(ifp, nex, 1, XFS_EXTFMT_INODE(ip)); | 632 | xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); |
641 | for (i = 0; i < nex; i++, dp++) { | 633 | for (i = 0; i < nex; i++, dp++) { |
642 | ep = xfs_iext_get_ext(ifp, i); | 634 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); |
643 | ep->l0 = INT_GET(get_unaligned((__uint64_t*)&dp->l0), | 635 | ep->l0 = be64_to_cpu(get_unaligned(&dp->l0)); |
644 | ARCH_CONVERT); | 636 | ep->l1 = be64_to_cpu(get_unaligned(&dp->l1)); |
645 | ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1), | ||
646 | ARCH_CONVERT); | ||
647 | } | 637 | } |
648 | XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); | 638 | XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); |
649 | if (whichfork != XFS_DATA_FORK || | 639 | if (whichfork != XFS_DATA_FORK || |
@@ -719,70 +709,74 @@ xfs_iformat_btree( | |||
719 | return 0; | 709 | return 0; |
720 | } | 710 | } |
721 | 711 | ||
722 | /* | ||
723 | * xfs_xlate_dinode_core - translate an xfs_inode_core_t between ondisk | ||
724 | * and native format | ||
725 | * | ||
726 | * buf = on-disk representation | ||
727 | * dip = native representation | ||
728 | * dir = direction - +ve -> disk to native | ||
729 | * -ve -> native to disk | ||
730 | */ | ||
731 | void | 712 | void |
732 | xfs_xlate_dinode_core( | 713 | xfs_dinode_from_disk( |
733 | xfs_caddr_t buf, | 714 | xfs_icdinode_t *to, |
734 | xfs_dinode_core_t *dip, | 715 | xfs_dinode_core_t *from) |
735 | int dir) | ||
736 | { | 716 | { |
737 | xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf; | 717 | to->di_magic = be16_to_cpu(from->di_magic); |
738 | xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip; | 718 | to->di_mode = be16_to_cpu(from->di_mode); |
739 | xfs_arch_t arch = ARCH_CONVERT; | 719 | to->di_version = from ->di_version; |
740 | 720 | to->di_format = from->di_format; | |
741 | ASSERT(dir); | 721 | to->di_onlink = be16_to_cpu(from->di_onlink); |
742 | 722 | to->di_uid = be32_to_cpu(from->di_uid); | |
743 | INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch); | 723 | to->di_gid = be32_to_cpu(from->di_gid); |
744 | INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch); | 724 | to->di_nlink = be32_to_cpu(from->di_nlink); |
745 | INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch); | 725 | to->di_projid = be16_to_cpu(from->di_projid); |
746 | INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch); | 726 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); |
747 | INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch); | 727 | to->di_flushiter = be16_to_cpu(from->di_flushiter); |
748 | INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch); | 728 | to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); |
749 | INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch); | 729 | to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); |
750 | INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch); | 730 | to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); |
751 | INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch); | 731 | to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); |
752 | 732 | to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); | |
753 | if (dir > 0) { | 733 | to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); |
754 | memcpy(mem_core->di_pad, buf_core->di_pad, | 734 | to->di_size = be64_to_cpu(from->di_size); |
755 | sizeof(buf_core->di_pad)); | 735 | to->di_nblocks = be64_to_cpu(from->di_nblocks); |
756 | } else { | 736 | to->di_extsize = be32_to_cpu(from->di_extsize); |
757 | memcpy(buf_core->di_pad, mem_core->di_pad, | 737 | to->di_nextents = be32_to_cpu(from->di_nextents); |
758 | sizeof(buf_core->di_pad)); | 738 | to->di_anextents = be16_to_cpu(from->di_anextents); |
759 | } | 739 | to->di_forkoff = from->di_forkoff; |
760 | 740 | to->di_aformat = from->di_aformat; | |
761 | INT_XLATE(buf_core->di_flushiter, mem_core->di_flushiter, dir, arch); | 741 | to->di_dmevmask = be32_to_cpu(from->di_dmevmask); |
762 | 742 | to->di_dmstate = be16_to_cpu(from->di_dmstate); | |
763 | INT_XLATE(buf_core->di_atime.t_sec, mem_core->di_atime.t_sec, | 743 | to->di_flags = be16_to_cpu(from->di_flags); |
764 | dir, arch); | 744 | to->di_gen = be32_to_cpu(from->di_gen); |
765 | INT_XLATE(buf_core->di_atime.t_nsec, mem_core->di_atime.t_nsec, | 745 | } |
766 | dir, arch); | 746 | |
767 | INT_XLATE(buf_core->di_mtime.t_sec, mem_core->di_mtime.t_sec, | 747 | void |
768 | dir, arch); | 748 | xfs_dinode_to_disk( |
769 | INT_XLATE(buf_core->di_mtime.t_nsec, mem_core->di_mtime.t_nsec, | 749 | xfs_dinode_core_t *to, |
770 | dir, arch); | 750 | xfs_icdinode_t *from) |
771 | INT_XLATE(buf_core->di_ctime.t_sec, mem_core->di_ctime.t_sec, | 751 | { |
772 | dir, arch); | 752 | to->di_magic = cpu_to_be16(from->di_magic); |
773 | INT_XLATE(buf_core->di_ctime.t_nsec, mem_core->di_ctime.t_nsec, | 753 | to->di_mode = cpu_to_be16(from->di_mode); |
774 | dir, arch); | 754 | to->di_version = from ->di_version; |
775 | INT_XLATE(buf_core->di_size, mem_core->di_size, dir, arch); | 755 | to->di_format = from->di_format; |
776 | INT_XLATE(buf_core->di_nblocks, mem_core->di_nblocks, dir, arch); | 756 | to->di_onlink = cpu_to_be16(from->di_onlink); |
777 | INT_XLATE(buf_core->di_extsize, mem_core->di_extsize, dir, arch); | 757 | to->di_uid = cpu_to_be32(from->di_uid); |
778 | INT_XLATE(buf_core->di_nextents, mem_core->di_nextents, dir, arch); | 758 | to->di_gid = cpu_to_be32(from->di_gid); |
779 | INT_XLATE(buf_core->di_anextents, mem_core->di_anextents, dir, arch); | 759 | to->di_nlink = cpu_to_be32(from->di_nlink); |
780 | INT_XLATE(buf_core->di_forkoff, mem_core->di_forkoff, dir, arch); | 760 | to->di_projid = cpu_to_be16(from->di_projid); |
781 | INT_XLATE(buf_core->di_aformat, mem_core->di_aformat, dir, arch); | 761 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); |
782 | INT_XLATE(buf_core->di_dmevmask, mem_core->di_dmevmask, dir, arch); | 762 | to->di_flushiter = cpu_to_be16(from->di_flushiter); |
783 | INT_XLATE(buf_core->di_dmstate, mem_core->di_dmstate, dir, arch); | 763 | to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); |
784 | INT_XLATE(buf_core->di_flags, mem_core->di_flags, dir, arch); | 764 | to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); |
785 | INT_XLATE(buf_core->di_gen, mem_core->di_gen, dir, arch); | 765 | to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); |
766 | to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); | ||
767 | to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); | ||
768 | to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); | ||
769 | to->di_size = cpu_to_be64(from->di_size); | ||
770 | to->di_nblocks = cpu_to_be64(from->di_nblocks); | ||
771 | to->di_extsize = cpu_to_be32(from->di_extsize); | ||
772 | to->di_nextents = cpu_to_be32(from->di_nextents); | ||
773 | to->di_anextents = cpu_to_be16(from->di_anextents); | ||
774 | to->di_forkoff = from->di_forkoff; | ||
775 | to->di_aformat = from->di_aformat; | ||
776 | to->di_dmevmask = cpu_to_be32(from->di_dmevmask); | ||
777 | to->di_dmstate = cpu_to_be16(from->di_dmstate); | ||
778 | to->di_flags = cpu_to_be16(from->di_flags); | ||
779 | to->di_gen = cpu_to_be32(from->di_gen); | ||
786 | } | 780 | } |
787 | 781 | ||
788 | STATIC uint | 782 | STATIC uint |
@@ -829,7 +823,7 @@ uint | |||
829 | xfs_ip2xflags( | 823 | xfs_ip2xflags( |
830 | xfs_inode_t *ip) | 824 | xfs_inode_t *ip) |
831 | { | 825 | { |
832 | xfs_dinode_core_t *dic = &ip->i_d; | 826 | xfs_icdinode_t *dic = &ip->i_d; |
833 | 827 | ||
834 | return _xfs_dic2xflags(dic->di_flags) | | 828 | return _xfs_dic2xflags(dic->di_flags) | |
835 | (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); | 829 | (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); |
@@ -839,7 +833,7 @@ uint | |||
839 | xfs_dic2xflags( | 833 | xfs_dic2xflags( |
840 | xfs_dinode_core_t *dic) | 834 | xfs_dinode_core_t *dic) |
841 | { | 835 | { |
842 | return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) | | 836 | return _xfs_dic2xflags(be16_to_cpu(dic->di_flags)) | |
843 | (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); | 837 | (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); |
844 | } | 838 | } |
845 | 839 | ||
@@ -870,6 +864,7 @@ xfs_iread( | |||
870 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); | 864 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); |
871 | ip->i_ino = ino; | 865 | ip->i_ino = ino; |
872 | ip->i_mount = mp; | 866 | ip->i_mount = mp; |
867 | atomic_set(&ip->i_iocount, 0); | ||
873 | spin_lock_init(&ip->i_flags_lock); | 868 | spin_lock_init(&ip->i_flags_lock); |
874 | 869 | ||
875 | /* | 870 | /* |
@@ -889,6 +884,9 @@ xfs_iread( | |||
889 | * Initialize inode's trace buffers. | 884 | * Initialize inode's trace buffers. |
890 | * Do this before xfs_iformat in case it adds entries. | 885 | * Do this before xfs_iformat in case it adds entries. |
891 | */ | 886 | */ |
887 | #ifdef XFS_VNODE_TRACE | ||
888 | ip->i_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); | ||
889 | #endif | ||
892 | #ifdef XFS_BMAP_TRACE | 890 | #ifdef XFS_BMAP_TRACE |
893 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP); | 891 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP); |
894 | #endif | 892 | #endif |
@@ -909,14 +907,14 @@ xfs_iread( | |||
909 | * If we got something that isn't an inode it means someone | 907 | * If we got something that isn't an inode it means someone |
910 | * (nfs or dmi) has a stale handle. | 908 | * (nfs or dmi) has a stale handle. |
911 | */ | 909 | */ |
912 | if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) { | 910 | if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) { |
913 | kmem_zone_free(xfs_inode_zone, ip); | 911 | kmem_zone_free(xfs_inode_zone, ip); |
914 | xfs_trans_brelse(tp, bp); | 912 | xfs_trans_brelse(tp, bp); |
915 | #ifdef DEBUG | 913 | #ifdef DEBUG |
916 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " | 914 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " |
917 | "dip->di_core.di_magic (0x%x) != " | 915 | "dip->di_core.di_magic (0x%x) != " |
918 | "XFS_DINODE_MAGIC (0x%x)", | 916 | "XFS_DINODE_MAGIC (0x%x)", |
919 | INT_GET(dip->di_core.di_magic, ARCH_CONVERT), | 917 | be16_to_cpu(dip->di_core.di_magic), |
920 | XFS_DINODE_MAGIC); | 918 | XFS_DINODE_MAGIC); |
921 | #endif /* DEBUG */ | 919 | #endif /* DEBUG */ |
922 | return XFS_ERROR(EINVAL); | 920 | return XFS_ERROR(EINVAL); |
@@ -930,8 +928,7 @@ xfs_iread( | |||
930 | * Otherwise, just get the truly permanent information. | 928 | * Otherwise, just get the truly permanent information. |
931 | */ | 929 | */ |
932 | if (dip->di_core.di_mode) { | 930 | if (dip->di_core.di_mode) { |
933 | xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core, | 931 | xfs_dinode_from_disk(&ip->i_d, &dip->di_core); |
934 | &(ip->i_d), 1); | ||
935 | error = xfs_iformat(ip, dip); | 932 | error = xfs_iformat(ip, dip); |
936 | if (error) { | 933 | if (error) { |
937 | kmem_zone_free(xfs_inode_zone, ip); | 934 | kmem_zone_free(xfs_inode_zone, ip); |
@@ -944,10 +941,10 @@ xfs_iread( | |||
944 | return error; | 941 | return error; |
945 | } | 942 | } |
946 | } else { | 943 | } else { |
947 | ip->i_d.di_magic = INT_GET(dip->di_core.di_magic, ARCH_CONVERT); | 944 | ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic); |
948 | ip->i_d.di_version = INT_GET(dip->di_core.di_version, ARCH_CONVERT); | 945 | ip->i_d.di_version = dip->di_core.di_version; |
949 | ip->i_d.di_gen = INT_GET(dip->di_core.di_gen, ARCH_CONVERT); | 946 | ip->i_d.di_gen = be32_to_cpu(dip->di_core.di_gen); |
950 | ip->i_d.di_flushiter = INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT); | 947 | ip->i_d.di_flushiter = be16_to_cpu(dip->di_core.di_flushiter); |
951 | /* | 948 | /* |
952 | * Make sure to pull in the mode here as well in | 949 | * Make sure to pull in the mode here as well in |
953 | * case the inode is released without being used. | 950 | * case the inode is released without being used. |
@@ -1048,7 +1045,7 @@ xfs_iread_extents( | |||
1048 | ifp->if_flags &= ~XFS_IFEXTENTS; | 1045 | ifp->if_flags &= ~XFS_IFEXTENTS; |
1049 | return error; | 1046 | return error; |
1050 | } | 1047 | } |
1051 | xfs_validate_extents(ifp, nextents, 0, XFS_EXTFMT_INODE(ip)); | 1048 | xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip)); |
1052 | return 0; | 1049 | return 0; |
1053 | } | 1050 | } |
1054 | 1051 | ||
@@ -1161,7 +1158,7 @@ xfs_ialloc( | |||
1161 | if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) | 1158 | if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) |
1162 | xfs_bump_ino_vers2(tp, ip); | 1159 | xfs_bump_ino_vers2(tp, ip); |
1163 | 1160 | ||
1164 | if (pip && XFS_INHERIT_GID(pip, vp->v_vfsp)) { | 1161 | if (pip && XFS_INHERIT_GID(pip)) { |
1165 | ip->i_d.di_gid = pip->i_d.di_gid; | 1162 | ip->i_d.di_gid = pip->i_d.di_gid; |
1166 | if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { | 1163 | if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { |
1167 | ip->i_d.di_mode |= S_ISGID; | 1164 | ip->i_d.di_mode |= S_ISGID; |
@@ -1275,7 +1272,7 @@ xfs_ialloc( | |||
1275 | xfs_trans_log_inode(tp, ip, flags); | 1272 | xfs_trans_log_inode(tp, ip, flags); |
1276 | 1273 | ||
1277 | /* now that we have an i_mode we can setup inode ops and unlock */ | 1274 | /* now that we have an i_mode we can setup inode ops and unlock */ |
1278 | bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1); | 1275 | xfs_initialize_vnode(tp->t_mountp, vp, ip); |
1279 | 1276 | ||
1280 | *ipp = ip; | 1277 | *ipp = ip; |
1281 | return 0; | 1278 | return 0; |
@@ -1462,7 +1459,7 @@ xfs_itruncate_start( | |||
1462 | mp = ip->i_mount; | 1459 | mp = ip->i_mount; |
1463 | vp = XFS_ITOV(ip); | 1460 | vp = XFS_ITOV(ip); |
1464 | 1461 | ||
1465 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ | 1462 | vn_iowait(ip); /* wait for the completion of any pending DIOs */ |
1466 | 1463 | ||
1467 | /* | 1464 | /* |
1468 | * Call toss_pages or flushinval_pages to get rid of pages | 1465 | * Call toss_pages or flushinval_pages to get rid of pages |
@@ -1497,9 +1494,11 @@ xfs_itruncate_start( | |||
1497 | last_byte); | 1494 | last_byte); |
1498 | if (last_byte > toss_start) { | 1495 | if (last_byte > toss_start) { |
1499 | if (flags & XFS_ITRUNC_DEFINITE) { | 1496 | if (flags & XFS_ITRUNC_DEFINITE) { |
1500 | bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); | 1497 | xfs_tosspages(ip, toss_start, |
1498 | -1, FI_REMAPF_LOCKED); | ||
1501 | } else { | 1499 | } else { |
1502 | error = bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); | 1500 | error = xfs_flushinval_pages(ip, toss_start, |
1501 | -1, FI_REMAPF_LOCKED); | ||
1503 | } | 1502 | } |
1504 | } | 1503 | } |
1505 | 1504 | ||
@@ -1932,9 +1931,9 @@ xfs_iunlink( | |||
1932 | */ | 1931 | */ |
1933 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr, | 1932 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr, |
1934 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); | 1933 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); |
1935 | if (error) { | 1934 | if (error) |
1936 | return error; | 1935 | return error; |
1937 | } | 1936 | |
1938 | /* | 1937 | /* |
1939 | * Validate the magic number of the agi block. | 1938 | * Validate the magic number of the agi block. |
1940 | */ | 1939 | */ |
@@ -1958,6 +1957,24 @@ xfs_iunlink( | |||
1958 | ASSERT(agi->agi_unlinked[bucket_index]); | 1957 | ASSERT(agi->agi_unlinked[bucket_index]); |
1959 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); | 1958 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); |
1960 | 1959 | ||
1960 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0); | ||
1961 | if (error) | ||
1962 | return error; | ||
1963 | |||
1964 | /* | ||
1965 | * Clear the on-disk di_nlink. This is to prevent xfs_bulkstat | ||
1966 | * from picking up this inode when it is reclaimed (its incore state | ||
1967 | * initialzed but not flushed to disk yet). The in-core di_nlink is | ||
1968 | * already cleared in xfs_droplink() and a corresponding transaction | ||
1969 | * logged. The hack here just synchronizes the in-core to on-disk | ||
1970 | * di_nlink value in advance before the actual inode sync to disk. | ||
1971 | * This is OK because the inode is already unlinked and would never | ||
1972 | * change its di_nlink again for this inode generation. | ||
1973 | * This is a temporary hack that would require a proper fix | ||
1974 | * in the future. | ||
1975 | */ | ||
1976 | dip->di_core.di_nlink = 0; | ||
1977 | |||
1961 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) { | 1978 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) { |
1962 | /* | 1979 | /* |
1963 | * There is already another inode in the bucket we need | 1980 | * There is already another inode in the bucket we need |
@@ -1965,12 +1982,7 @@ xfs_iunlink( | |||
1965 | * Here we put the head pointer into our next pointer, | 1982 | * Here we put the head pointer into our next pointer, |
1966 | * and then we fall through to point the head at us. | 1983 | * and then we fall through to point the head at us. |
1967 | */ | 1984 | */ |
1968 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0); | 1985 | ASSERT(be32_to_cpu(dip->di_next_unlinked) == NULLAGINO); |
1969 | if (error) { | ||
1970 | return error; | ||
1971 | } | ||
1972 | ASSERT(INT_GET(dip->di_next_unlinked, ARCH_CONVERT) == NULLAGINO); | ||
1973 | ASSERT(dip->di_next_unlinked); | ||
1974 | /* both on-disk, don't endian flip twice */ | 1986 | /* both on-disk, don't endian flip twice */ |
1975 | dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; | 1987 | dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; |
1976 | offset = ip->i_boffset + | 1988 | offset = ip->i_boffset + |
@@ -2081,10 +2093,10 @@ xfs_iunlink_remove( | |||
2081 | error, mp->m_fsname); | 2093 | error, mp->m_fsname); |
2082 | return error; | 2094 | return error; |
2083 | } | 2095 | } |
2084 | next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT); | 2096 | next_agino = be32_to_cpu(dip->di_next_unlinked); |
2085 | ASSERT(next_agino != 0); | 2097 | ASSERT(next_agino != 0); |
2086 | if (next_agino != NULLAGINO) { | 2098 | if (next_agino != NULLAGINO) { |
2087 | INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO); | 2099 | dip->di_next_unlinked = cpu_to_be32(NULLAGINO); |
2088 | offset = ip->i_boffset + | 2100 | offset = ip->i_boffset + |
2089 | offsetof(xfs_dinode_t, di_next_unlinked); | 2101 | offsetof(xfs_dinode_t, di_next_unlinked); |
2090 | xfs_trans_inode_buf(tp, ibp); | 2102 | xfs_trans_inode_buf(tp, ibp); |
@@ -2128,7 +2140,7 @@ xfs_iunlink_remove( | |||
2128 | error, mp->m_fsname); | 2140 | error, mp->m_fsname); |
2129 | return error; | 2141 | return error; |
2130 | } | 2142 | } |
2131 | next_agino = INT_GET(last_dip->di_next_unlinked, ARCH_CONVERT); | 2143 | next_agino = be32_to_cpu(last_dip->di_next_unlinked); |
2132 | ASSERT(next_agino != NULLAGINO); | 2144 | ASSERT(next_agino != NULLAGINO); |
2133 | ASSERT(next_agino != 0); | 2145 | ASSERT(next_agino != 0); |
2134 | } | 2146 | } |
@@ -2143,11 +2155,11 @@ xfs_iunlink_remove( | |||
2143 | error, mp->m_fsname); | 2155 | error, mp->m_fsname); |
2144 | return error; | 2156 | return error; |
2145 | } | 2157 | } |
2146 | next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT); | 2158 | next_agino = be32_to_cpu(dip->di_next_unlinked); |
2147 | ASSERT(next_agino != 0); | 2159 | ASSERT(next_agino != 0); |
2148 | ASSERT(next_agino != agino); | 2160 | ASSERT(next_agino != agino); |
2149 | if (next_agino != NULLAGINO) { | 2161 | if (next_agino != NULLAGINO) { |
2150 | INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO); | 2162 | dip->di_next_unlinked = cpu_to_be32(NULLAGINO); |
2151 | offset = ip->i_boffset + | 2163 | offset = ip->i_boffset + |
2152 | offsetof(xfs_dinode_t, di_next_unlinked); | 2164 | offsetof(xfs_dinode_t, di_next_unlinked); |
2153 | xfs_trans_inode_buf(tp, ibp); | 2165 | xfs_trans_inode_buf(tp, ibp); |
@@ -2160,7 +2172,7 @@ xfs_iunlink_remove( | |||
2160 | /* | 2172 | /* |
2161 | * Point the previous inode on the list to the next inode. | 2173 | * Point the previous inode on the list to the next inode. |
2162 | */ | 2174 | */ |
2163 | INT_SET(last_dip->di_next_unlinked, ARCH_CONVERT, next_agino); | 2175 | last_dip->di_next_unlinked = cpu_to_be32(next_agino); |
2164 | ASSERT(next_agino != 0); | 2176 | ASSERT(next_agino != 0); |
2165 | offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked); | 2177 | offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked); |
2166 | xfs_trans_inode_buf(tp, last_ibp); | 2178 | xfs_trans_inode_buf(tp, last_ibp); |
@@ -2191,10 +2203,10 @@ xfs_ifree_cluster( | |||
2191 | int i, j, found, pre_flushed; | 2203 | int i, j, found, pre_flushed; |
2192 | xfs_daddr_t blkno; | 2204 | xfs_daddr_t blkno; |
2193 | xfs_buf_t *bp; | 2205 | xfs_buf_t *bp; |
2194 | xfs_ihash_t *ih; | ||
2195 | xfs_inode_t *ip, **ip_found; | 2206 | xfs_inode_t *ip, **ip_found; |
2196 | xfs_inode_log_item_t *iip; | 2207 | xfs_inode_log_item_t *iip; |
2197 | xfs_log_item_t *lip; | 2208 | xfs_log_item_t *lip; |
2209 | xfs_perag_t *pag = xfs_get_perag(mp, inum); | ||
2198 | SPLDECL(s); | 2210 | SPLDECL(s); |
2199 | 2211 | ||
2200 | if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { | 2212 | if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { |
@@ -2229,23 +2241,20 @@ xfs_ifree_cluster( | |||
2229 | */ | 2241 | */ |
2230 | found = 0; | 2242 | found = 0; |
2231 | for (i = 0; i < ninodes; i++) { | 2243 | for (i = 0; i < ninodes; i++) { |
2232 | ih = XFS_IHASH(mp, inum + i); | 2244 | read_lock(&pag->pag_ici_lock); |
2233 | read_lock(&ih->ih_lock); | 2245 | ip = radix_tree_lookup(&pag->pag_ici_root, |
2234 | for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) { | 2246 | XFS_INO_TO_AGINO(mp, (inum + i))); |
2235 | if (ip->i_ino == inum + i) | ||
2236 | break; | ||
2237 | } | ||
2238 | 2247 | ||
2239 | /* Inode not in memory or we found it already, | 2248 | /* Inode not in memory or we found it already, |
2240 | * nothing to do | 2249 | * nothing to do |
2241 | */ | 2250 | */ |
2242 | if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { | 2251 | if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { |
2243 | read_unlock(&ih->ih_lock); | 2252 | read_unlock(&pag->pag_ici_lock); |
2244 | continue; | 2253 | continue; |
2245 | } | 2254 | } |
2246 | 2255 | ||
2247 | if (xfs_inode_clean(ip)) { | 2256 | if (xfs_inode_clean(ip)) { |
2248 | read_unlock(&ih->ih_lock); | 2257 | read_unlock(&pag->pag_ici_lock); |
2249 | continue; | 2258 | continue; |
2250 | } | 2259 | } |
2251 | 2260 | ||
@@ -2268,7 +2277,7 @@ xfs_ifree_cluster( | |||
2268 | ip_found[found++] = ip; | 2277 | ip_found[found++] = ip; |
2269 | } | 2278 | } |
2270 | } | 2279 | } |
2271 | read_unlock(&ih->ih_lock); | 2280 | read_unlock(&pag->pag_ici_lock); |
2272 | continue; | 2281 | continue; |
2273 | } | 2282 | } |
2274 | 2283 | ||
@@ -2286,8 +2295,7 @@ xfs_ifree_cluster( | |||
2286 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2295 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2287 | } | 2296 | } |
2288 | } | 2297 | } |
2289 | 2298 | read_unlock(&pag->pag_ici_lock); | |
2290 | read_unlock(&ih->ih_lock); | ||
2291 | } | 2299 | } |
2292 | 2300 | ||
2293 | bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, | 2301 | bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, |
@@ -2342,6 +2350,7 @@ xfs_ifree_cluster( | |||
2342 | } | 2350 | } |
2343 | 2351 | ||
2344 | kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *)); | 2352 | kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *)); |
2353 | xfs_put_perag(mp, pag); | ||
2345 | } | 2354 | } |
2346 | 2355 | ||
2347 | /* | 2356 | /* |
@@ -2737,6 +2746,10 @@ xfs_idestroy( | |||
2737 | mrfree(&ip->i_lock); | 2746 | mrfree(&ip->i_lock); |
2738 | mrfree(&ip->i_iolock); | 2747 | mrfree(&ip->i_iolock); |
2739 | freesema(&ip->i_flock); | 2748 | freesema(&ip->i_flock); |
2749 | |||
2750 | #ifdef XFS_VNODE_TRACE | ||
2751 | ktrace_free(ip->i_trace); | ||
2752 | #endif | ||
2740 | #ifdef XFS_BMAP_TRACE | 2753 | #ifdef XFS_BMAP_TRACE |
2741 | ktrace_free(ip->i_xtrace); | 2754 | ktrace_free(ip->i_xtrace); |
2742 | #endif | 2755 | #endif |
@@ -2887,12 +2900,10 @@ xfs_iunpin_wait( | |||
2887 | int | 2900 | int |
2888 | xfs_iextents_copy( | 2901 | xfs_iextents_copy( |
2889 | xfs_inode_t *ip, | 2902 | xfs_inode_t *ip, |
2890 | xfs_bmbt_rec_t *buffer, | 2903 | xfs_bmbt_rec_t *dp, |
2891 | int whichfork) | 2904 | int whichfork) |
2892 | { | 2905 | { |
2893 | int copied; | 2906 | int copied; |
2894 | xfs_bmbt_rec_t *dest_ep; | ||
2895 | xfs_bmbt_rec_t *ep; | ||
2896 | int i; | 2907 | int i; |
2897 | xfs_ifork_t *ifp; | 2908 | xfs_ifork_t *ifp; |
2898 | int nrecs; | 2909 | int nrecs; |
@@ -2912,10 +2923,9 @@ xfs_iextents_copy( | |||
2912 | * the delayed ones. There must be at least one | 2923 | * the delayed ones. There must be at least one |
2913 | * non-delayed extent. | 2924 | * non-delayed extent. |
2914 | */ | 2925 | */ |
2915 | dest_ep = buffer; | ||
2916 | copied = 0; | 2926 | copied = 0; |
2917 | for (i = 0; i < nrecs; i++) { | 2927 | for (i = 0; i < nrecs; i++) { |
2918 | ep = xfs_iext_get_ext(ifp, i); | 2928 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); |
2919 | start_block = xfs_bmbt_get_startblock(ep); | 2929 | start_block = xfs_bmbt_get_startblock(ep); |
2920 | if (ISNULLSTARTBLOCK(start_block)) { | 2930 | if (ISNULLSTARTBLOCK(start_block)) { |
2921 | /* | 2931 | /* |
@@ -2925,15 +2935,13 @@ xfs_iextents_copy( | |||
2925 | } | 2935 | } |
2926 | 2936 | ||
2927 | /* Translate to on disk format */ | 2937 | /* Translate to on disk format */ |
2928 | put_unaligned(INT_GET(ep->l0, ARCH_CONVERT), | 2938 | put_unaligned(cpu_to_be64(ep->l0), &dp->l0); |
2929 | (__uint64_t*)&dest_ep->l0); | 2939 | put_unaligned(cpu_to_be64(ep->l1), &dp->l1); |
2930 | put_unaligned(INT_GET(ep->l1, ARCH_CONVERT), | 2940 | dp++; |
2931 | (__uint64_t*)&dest_ep->l1); | ||
2932 | dest_ep++; | ||
2933 | copied++; | 2941 | copied++; |
2934 | } | 2942 | } |
2935 | ASSERT(copied != 0); | 2943 | ASSERT(copied != 0); |
2936 | xfs_validate_extents(ifp, copied, 1, XFS_EXTFMT_INODE(ip)); | 2944 | xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip)); |
2937 | 2945 | ||
2938 | return (copied * (uint)sizeof(xfs_bmbt_rec_t)); | 2946 | return (copied * (uint)sizeof(xfs_bmbt_rec_t)); |
2939 | } | 2947 | } |
@@ -3024,7 +3032,7 @@ xfs_iflush_fork( | |||
3024 | case XFS_DINODE_FMT_DEV: | 3032 | case XFS_DINODE_FMT_DEV: |
3025 | if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { | 3033 | if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { |
3026 | ASSERT(whichfork == XFS_DATA_FORK); | 3034 | ASSERT(whichfork == XFS_DATA_FORK); |
3027 | INT_SET(dip->di_u.di_dev, ARCH_CONVERT, ip->i_df.if_u2.if_rdev); | 3035 | dip->di_u.di_dev = cpu_to_be32(ip->i_df.if_u2.if_rdev); |
3028 | } | 3036 | } |
3029 | break; | 3037 | break; |
3030 | 3038 | ||
@@ -3064,12 +3072,11 @@ xfs_iflush( | |||
3064 | xfs_mount_t *mp; | 3072 | xfs_mount_t *mp; |
3065 | int error; | 3073 | int error; |
3066 | /* REFERENCED */ | 3074 | /* REFERENCED */ |
3067 | xfs_chash_t *ch; | ||
3068 | xfs_inode_t *iq; | 3075 | xfs_inode_t *iq; |
3069 | int clcount; /* count of inodes clustered */ | 3076 | int clcount; /* count of inodes clustered */ |
3070 | int bufwasdelwri; | 3077 | int bufwasdelwri; |
3078 | struct hlist_node *entry; | ||
3071 | enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) }; | 3079 | enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) }; |
3072 | SPLDECL(s); | ||
3073 | 3080 | ||
3074 | XFS_STATS_INC(xs_iflush_count); | 3081 | XFS_STATS_INC(xs_iflush_count); |
3075 | 3082 | ||
@@ -3183,14 +3190,14 @@ xfs_iflush( | |||
3183 | * inode clustering: | 3190 | * inode clustering: |
3184 | * see if other inodes can be gathered into this write | 3191 | * see if other inodes can be gathered into this write |
3185 | */ | 3192 | */ |
3186 | 3193 | spin_lock(&ip->i_cluster->icl_lock); | |
3187 | ip->i_chash->chl_buf = bp; | 3194 | ip->i_cluster->icl_buf = bp; |
3188 | |||
3189 | ch = XFS_CHASH(mp, ip->i_blkno); | ||
3190 | s = mutex_spinlock(&ch->ch_lock); | ||
3191 | 3195 | ||
3192 | clcount = 0; | 3196 | clcount = 0; |
3193 | for (iq = ip->i_cnext; iq != ip; iq = iq->i_cnext) { | 3197 | hlist_for_each_entry(iq, entry, &ip->i_cluster->icl_inodes, i_cnode) { |
3198 | if (iq == ip) | ||
3199 | continue; | ||
3200 | |||
3194 | /* | 3201 | /* |
3195 | * Do an un-protected check to see if the inode is dirty and | 3202 | * Do an un-protected check to see if the inode is dirty and |
3196 | * is a candidate for flushing. These checks will be repeated | 3203 | * is a candidate for flushing. These checks will be repeated |
@@ -3241,7 +3248,7 @@ xfs_iflush( | |||
3241 | xfs_iunlock(iq, XFS_ILOCK_SHARED); | 3248 | xfs_iunlock(iq, XFS_ILOCK_SHARED); |
3242 | } | 3249 | } |
3243 | } | 3250 | } |
3244 | mutex_spinunlock(&ch->ch_lock, s); | 3251 | spin_unlock(&ip->i_cluster->icl_lock); |
3245 | 3252 | ||
3246 | if (clcount) { | 3253 | if (clcount) { |
3247 | XFS_STATS_INC(xs_icluster_flushcnt); | 3254 | XFS_STATS_INC(xs_icluster_flushcnt); |
@@ -3278,7 +3285,7 @@ cluster_corrupt_out: | |||
3278 | /* Corruption detected in the clustering loop. Invalidate the | 3285 | /* Corruption detected in the clustering loop. Invalidate the |
3279 | * inode buffer and shut down the filesystem. | 3286 | * inode buffer and shut down the filesystem. |
3280 | */ | 3287 | */ |
3281 | mutex_spinunlock(&ch->ch_lock, s); | 3288 | spin_unlock(&ip->i_cluster->icl_lock); |
3282 | 3289 | ||
3283 | /* | 3290 | /* |
3284 | * Clean up the buffer. If it was B_DELWRI, just release it -- | 3291 | * Clean up the buffer. If it was B_DELWRI, just release it -- |
@@ -3373,11 +3380,11 @@ xfs_iflush_int( | |||
3373 | */ | 3380 | */ |
3374 | xfs_synchronize_atime(ip); | 3381 | xfs_synchronize_atime(ip); |
3375 | 3382 | ||
3376 | if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC, | 3383 | if (XFS_TEST_ERROR(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC, |
3377 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { | 3384 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { |
3378 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, | 3385 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, |
3379 | "xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p", | 3386 | "xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p", |
3380 | ip->i_ino, (int) INT_GET(dip->di_core.di_magic, ARCH_CONVERT), dip); | 3387 | ip->i_ino, be16_to_cpu(dip->di_core.di_magic), dip); |
3381 | goto corrupt_out; | 3388 | goto corrupt_out; |
3382 | } | 3389 | } |
3383 | if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, | 3390 | if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, |
@@ -3440,7 +3447,7 @@ xfs_iflush_int( | |||
3440 | * because if the inode is dirty at all the core must | 3447 | * because if the inode is dirty at all the core must |
3441 | * be. | 3448 | * be. |
3442 | */ | 3449 | */ |
3443 | xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1); | 3450 | xfs_dinode_to_disk(&dip->di_core, &ip->i_d); |
3444 | 3451 | ||
3445 | /* Wrap, we never let the log put out DI_MAX_FLUSH */ | 3452 | /* Wrap, we never let the log put out DI_MAX_FLUSH */ |
3446 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) | 3453 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) |
@@ -3460,7 +3467,7 @@ xfs_iflush_int( | |||
3460 | * Convert it back. | 3467 | * Convert it back. |
3461 | */ | 3468 | */ |
3462 | ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); | 3469 | ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); |
3463 | INT_SET(dip->di_core.di_onlink, ARCH_CONVERT, ip->i_d.di_nlink); | 3470 | dip->di_core.di_onlink = cpu_to_be16(ip->i_d.di_nlink); |
3464 | } else { | 3471 | } else { |
3465 | /* | 3472 | /* |
3466 | * The superblock version has already been bumped, | 3473 | * The superblock version has already been bumped, |
@@ -3468,7 +3475,7 @@ xfs_iflush_int( | |||
3468 | * format permanent. | 3475 | * format permanent. |
3469 | */ | 3476 | */ |
3470 | ip->i_d.di_version = XFS_DINODE_VERSION_2; | 3477 | ip->i_d.di_version = XFS_DINODE_VERSION_2; |
3471 | INT_SET(dip->di_core.di_version, ARCH_CONVERT, XFS_DINODE_VERSION_2); | 3478 | dip->di_core.di_version = XFS_DINODE_VERSION_2; |
3472 | ip->i_d.di_onlink = 0; | 3479 | ip->i_d.di_onlink = 0; |
3473 | dip->di_core.di_onlink = 0; | 3480 | dip->di_core.di_onlink = 0; |
3474 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | 3481 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); |
@@ -3711,7 +3718,7 @@ xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra) | |||
3711 | /* | 3718 | /* |
3712 | * Return a pointer to the extent record at file index idx. | 3719 | * Return a pointer to the extent record at file index idx. |
3713 | */ | 3720 | */ |
3714 | xfs_bmbt_rec_t * | 3721 | xfs_bmbt_rec_host_t * |
3715 | xfs_iext_get_ext( | 3722 | xfs_iext_get_ext( |
3716 | xfs_ifork_t *ifp, /* inode fork pointer */ | 3723 | xfs_ifork_t *ifp, /* inode fork pointer */ |
3717 | xfs_extnum_t idx) /* index of target extent */ | 3724 | xfs_extnum_t idx) /* index of target extent */ |
@@ -3744,15 +3751,12 @@ xfs_iext_insert( | |||
3744 | xfs_extnum_t count, /* number of inserted items */ | 3751 | xfs_extnum_t count, /* number of inserted items */ |
3745 | xfs_bmbt_irec_t *new) /* items to insert */ | 3752 | xfs_bmbt_irec_t *new) /* items to insert */ |
3746 | { | 3753 | { |
3747 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | ||
3748 | xfs_extnum_t i; /* extent record index */ | 3754 | xfs_extnum_t i; /* extent record index */ |
3749 | 3755 | ||
3750 | ASSERT(ifp->if_flags & XFS_IFEXTENTS); | 3756 | ASSERT(ifp->if_flags & XFS_IFEXTENTS); |
3751 | xfs_iext_add(ifp, idx, count); | 3757 | xfs_iext_add(ifp, idx, count); |
3752 | for (i = idx; i < idx + count; i++, new++) { | 3758 | for (i = idx; i < idx + count; i++, new++) |
3753 | ep = xfs_iext_get_ext(ifp, i); | 3759 | xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new); |
3754 | xfs_bmbt_set_all(ep, new); | ||
3755 | } | ||
3756 | } | 3760 | } |
3757 | 3761 | ||
3758 | /* | 3762 | /* |
@@ -4203,7 +4207,7 @@ xfs_iext_realloc_direct( | |||
4203 | rnew_size = xfs_iroundup(new_size); | 4207 | rnew_size = xfs_iroundup(new_size); |
4204 | } | 4208 | } |
4205 | if (rnew_size != ifp->if_real_bytes) { | 4209 | if (rnew_size != ifp->if_real_bytes) { |
4206 | ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) | 4210 | ifp->if_u1.if_extents = |
4207 | kmem_realloc(ifp->if_u1.if_extents, | 4211 | kmem_realloc(ifp->if_u1.if_extents, |
4208 | rnew_size, | 4212 | rnew_size, |
4209 | ifp->if_real_bytes, | 4213 | ifp->if_real_bytes, |
@@ -4266,8 +4270,7 @@ xfs_iext_inline_to_direct( | |||
4266 | xfs_ifork_t *ifp, /* inode fork pointer */ | 4270 | xfs_ifork_t *ifp, /* inode fork pointer */ |
4267 | int new_size) /* number of extents in file */ | 4271 | int new_size) /* number of extents in file */ |
4268 | { | 4272 | { |
4269 | ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) | 4273 | ifp->if_u1.if_extents = kmem_alloc(new_size, KM_SLEEP); |
4270 | kmem_alloc(new_size, KM_SLEEP); | ||
4271 | memset(ifp->if_u1.if_extents, 0, new_size); | 4274 | memset(ifp->if_u1.if_extents, 0, new_size); |
4272 | if (ifp->if_bytes) { | 4275 | if (ifp->if_bytes) { |
4273 | memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, | 4276 | memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, |
@@ -4310,7 +4313,7 @@ void | |||
4310 | xfs_iext_indirect_to_direct( | 4313 | xfs_iext_indirect_to_direct( |
4311 | xfs_ifork_t *ifp) /* inode fork pointer */ | 4314 | xfs_ifork_t *ifp) /* inode fork pointer */ |
4312 | { | 4315 | { |
4313 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 4316 | xfs_bmbt_rec_host_t *ep; /* extent record pointer */ |
4314 | xfs_extnum_t nextents; /* number of extents in file */ | 4317 | xfs_extnum_t nextents; /* number of extents in file */ |
4315 | int size; /* size of file extents */ | 4318 | int size; /* size of file extents */ |
4316 | 4319 | ||
@@ -4362,15 +4365,15 @@ xfs_iext_destroy( | |||
4362 | /* | 4365 | /* |
4363 | * Return a pointer to the extent record for file system block bno. | 4366 | * Return a pointer to the extent record for file system block bno. |
4364 | */ | 4367 | */ |
4365 | xfs_bmbt_rec_t * /* pointer to found extent record */ | 4368 | xfs_bmbt_rec_host_t * /* pointer to found extent record */ |
4366 | xfs_iext_bno_to_ext( | 4369 | xfs_iext_bno_to_ext( |
4367 | xfs_ifork_t *ifp, /* inode fork pointer */ | 4370 | xfs_ifork_t *ifp, /* inode fork pointer */ |
4368 | xfs_fileoff_t bno, /* block number to search for */ | 4371 | xfs_fileoff_t bno, /* block number to search for */ |
4369 | xfs_extnum_t *idxp) /* index of target extent */ | 4372 | xfs_extnum_t *idxp) /* index of target extent */ |
4370 | { | 4373 | { |
4371 | xfs_bmbt_rec_t *base; /* pointer to first extent */ | 4374 | xfs_bmbt_rec_host_t *base; /* pointer to first extent */ |
4372 | xfs_filblks_t blockcount = 0; /* number of blocks in extent */ | 4375 | xfs_filblks_t blockcount = 0; /* number of blocks in extent */ |
4373 | xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */ | 4376 | xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */ |
4374 | xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ | 4377 | xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ |
4375 | int high; /* upper boundary in search */ | 4378 | int high; /* upper boundary in search */ |
4376 | xfs_extnum_t idx = 0; /* index of target extent */ | 4379 | xfs_extnum_t idx = 0; /* index of target extent */ |
@@ -4545,8 +4548,7 @@ xfs_iext_irec_init( | |||
4545 | kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP); | 4548 | kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP); |
4546 | 4549 | ||
4547 | if (nextents == 0) { | 4550 | if (nextents == 0) { |
4548 | ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) | 4551 | ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); |
4549 | kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); | ||
4550 | } else if (!ifp->if_real_bytes) { | 4552 | } else if (!ifp->if_real_bytes) { |
4551 | xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); | 4553 | xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); |
4552 | } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { | 4554 | } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { |
@@ -4594,8 +4596,7 @@ xfs_iext_irec_new( | |||
4594 | 4596 | ||
4595 | /* Initialize new extent record */ | 4597 | /* Initialize new extent record */ |
4596 | erp = ifp->if_u1.if_ext_irec; | 4598 | erp = ifp->if_u1.if_ext_irec; |
4597 | erp[erp_idx].er_extbuf = (xfs_bmbt_rec_t *) | 4599 | erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); |
4598 | kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); | ||
4599 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; | 4600 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; |
4600 | memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); | 4601 | memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); |
4601 | erp[erp_idx].er_extcount = 0; | 4602 | erp[erp_idx].er_extcount = 0; |
@@ -4727,7 +4728,7 @@ void | |||
4727 | xfs_iext_irec_compact_full( | 4728 | xfs_iext_irec_compact_full( |
4728 | xfs_ifork_t *ifp) /* inode fork pointer */ | 4729 | xfs_ifork_t *ifp) /* inode fork pointer */ |
4729 | { | 4730 | { |
4730 | xfs_bmbt_rec_t *ep, *ep_next; /* extent record pointers */ | 4731 | xfs_bmbt_rec_host_t *ep, *ep_next; /* extent record pointers */ |
4731 | xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */ | 4732 | xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */ |
4732 | int erp_idx = 0; /* extent irec index */ | 4733 | int erp_idx = 0; /* extent irec index */ |
4733 | int ext_avail; /* empty entries in ex list */ | 4734 | int ext_avail; /* empty entries in ex list */ |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 012dfd4a958c..e5aff929cc65 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -18,6 +18,10 @@ | |||
18 | #ifndef __XFS_INODE_H__ | 18 | #ifndef __XFS_INODE_H__ |
19 | #define __XFS_INODE_H__ | 19 | #define __XFS_INODE_H__ |
20 | 20 | ||
21 | struct xfs_dinode; | ||
22 | struct xfs_dinode_core; | ||
23 | |||
24 | |||
21 | /* | 25 | /* |
22 | * Fork identifiers. | 26 | * Fork identifiers. |
23 | */ | 27 | */ |
@@ -44,7 +48,7 @@ | |||
44 | * it is possible that a third level of indirection may be required. | 48 | * it is possible that a third level of indirection may be required. |
45 | */ | 49 | */ |
46 | typedef struct xfs_ext_irec { | 50 | typedef struct xfs_ext_irec { |
47 | xfs_bmbt_rec_t *er_extbuf; /* block of extent records */ | 51 | xfs_bmbt_rec_host_t *er_extbuf; /* block of extent records */ |
48 | xfs_extnum_t er_extoff; /* extent offset in file */ | 52 | xfs_extnum_t er_extoff; /* extent offset in file */ |
49 | xfs_extnum_t er_extcount; /* number of extents in page/block */ | 53 | xfs_extnum_t er_extcount; /* number of extents in page/block */ |
50 | } xfs_ext_irec_t; | 54 | } xfs_ext_irec_t; |
@@ -65,12 +69,12 @@ typedef struct xfs_ifork { | |||
65 | unsigned char if_ext_max; /* max # of extent records */ | 69 | unsigned char if_ext_max; /* max # of extent records */ |
66 | xfs_extnum_t if_lastex; /* last if_extents used */ | 70 | xfs_extnum_t if_lastex; /* last if_extents used */ |
67 | union { | 71 | union { |
68 | xfs_bmbt_rec_t *if_extents; /* linear map file exts */ | 72 | xfs_bmbt_rec_host_t *if_extents;/* linear map file exts */ |
69 | xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ | 73 | xfs_ext_irec_t *if_ext_irec; /* irec map file exts */ |
70 | char *if_data; /* inline file data */ | 74 | char *if_data; /* inline file data */ |
71 | } if_u1; | 75 | } if_u1; |
72 | union { | 76 | union { |
73 | xfs_bmbt_rec_t if_inline_ext[XFS_INLINE_EXTS]; | 77 | xfs_bmbt_rec_host_t if_inline_ext[XFS_INLINE_EXTS]; |
74 | /* very small file extents */ | 78 | /* very small file extents */ |
75 | char if_inline_data[XFS_INLINE_DATA]; | 79 | char if_inline_data[XFS_INLINE_DATA]; |
76 | /* very small file data */ | 80 | /* very small file data */ |
@@ -102,7 +106,6 @@ typedef struct xfs_ifork { | |||
102 | 106 | ||
103 | #ifdef __KERNEL__ | 107 | #ifdef __KERNEL__ |
104 | struct bhv_desc; | 108 | struct bhv_desc; |
105 | struct bhv_vnode; | ||
106 | struct cred; | 109 | struct cred; |
107 | struct ktrace; | 110 | struct ktrace; |
108 | struct xfs_buf; | 111 | struct xfs_buf; |
@@ -168,41 +171,18 @@ typedef struct xfs_iocore { | |||
168 | extern void xfs_iocore_inode_init(struct xfs_inode *); | 171 | extern void xfs_iocore_inode_init(struct xfs_inode *); |
169 | extern void xfs_iocore_inode_reinit(struct xfs_inode *); | 172 | extern void xfs_iocore_inode_reinit(struct xfs_inode *); |
170 | 173 | ||
171 | |||
172 | /* | ||
173 | * This is the type used in the xfs inode hash table. | ||
174 | * An array of these is allocated for each mounted | ||
175 | * file system to hash the inodes for that file system. | ||
176 | */ | ||
177 | typedef struct xfs_ihash { | ||
178 | struct xfs_inode *ih_next; | ||
179 | rwlock_t ih_lock; | ||
180 | uint ih_version; | ||
181 | } xfs_ihash_t; | ||
182 | |||
183 | #define XFS_IHASH(mp,ino) ((mp)->m_ihash + (((uint)(ino)) % (mp)->m_ihsize)) | ||
184 | |||
185 | /* | 174 | /* |
186 | * This is the xfs inode cluster hash. This hash is used by xfs_iflush to | 175 | * This is the xfs inode cluster structure. This structure is used by |
187 | * find inodes that share a cluster and can be flushed to disk at the same | 176 | * xfs_iflush to find inodes that share a cluster and can be flushed to disk at |
188 | * time. | 177 | * the same time. |
189 | */ | 178 | */ |
190 | typedef struct xfs_chashlist { | 179 | typedef struct xfs_icluster { |
191 | struct xfs_chashlist *chl_next; | 180 | struct hlist_head icl_inodes; /* list of inodes on cluster */ |
192 | struct xfs_chashlist *chl_prev; | 181 | xfs_daddr_t icl_blkno; /* starting block number of |
193 | struct xfs_inode *chl_ip; | ||
194 | xfs_daddr_t chl_blkno; /* starting block number of | ||
195 | * the cluster */ | 182 | * the cluster */ |
196 | struct xfs_buf *chl_buf; /* the inode buffer */ | 183 | struct xfs_buf *icl_buf; /* the inode buffer */ |
197 | } xfs_chashlist_t; | 184 | lock_t icl_lock; /* inode list lock */ |
198 | 185 | } xfs_icluster_t; | |
199 | typedef struct xfs_chash { | ||
200 | xfs_chashlist_t *ch_list; | ||
201 | lock_t ch_lock; | ||
202 | } xfs_chash_t; | ||
203 | |||
204 | #define XFS_CHASH(mp,blk) ((mp)->m_chash + (((uint)blk) % (mp)->m_chsize)) | ||
205 | |||
206 | 186 | ||
207 | /* | 187 | /* |
208 | * This is the xfs in-core inode structure. | 188 | * This is the xfs in-core inode structure. |
@@ -227,25 +207,56 @@ typedef struct xfs_chash { | |||
227 | * chain off the mount structure by xfs_sync calls. | 207 | * chain off the mount structure by xfs_sync calls. |
228 | */ | 208 | */ |
229 | 209 | ||
210 | typedef struct xfs_ictimestamp { | ||
211 | __int32_t t_sec; /* timestamp seconds */ | ||
212 | __int32_t t_nsec; /* timestamp nanoseconds */ | ||
213 | } xfs_ictimestamp_t; | ||
214 | |||
215 | /* | ||
216 | * NOTE: This structure must be kept identical to struct xfs_dinode_core | ||
217 | * in xfs_dinode.h except for the endianess annotations. | ||
218 | */ | ||
219 | typedef struct xfs_icdinode { | ||
220 | __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */ | ||
221 | __uint16_t di_mode; /* mode and type of file */ | ||
222 | __int8_t di_version; /* inode version */ | ||
223 | __int8_t di_format; /* format of di_c data */ | ||
224 | __uint16_t di_onlink; /* old number of links to file */ | ||
225 | __uint32_t di_uid; /* owner's user id */ | ||
226 | __uint32_t di_gid; /* owner's group id */ | ||
227 | __uint32_t di_nlink; /* number of links to file */ | ||
228 | __uint16_t di_projid; /* owner's project id */ | ||
229 | __uint8_t di_pad[8]; /* unused, zeroed space */ | ||
230 | __uint16_t di_flushiter; /* incremented on flush */ | ||
231 | xfs_ictimestamp_t di_atime; /* time last accessed */ | ||
232 | xfs_ictimestamp_t di_mtime; /* time last modified */ | ||
233 | xfs_ictimestamp_t di_ctime; /* time created/inode modified */ | ||
234 | xfs_fsize_t di_size; /* number of bytes in file */ | ||
235 | xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */ | ||
236 | xfs_extlen_t di_extsize; /* basic/minimum extent size for file */ | ||
237 | xfs_extnum_t di_nextents; /* number of extents in data fork */ | ||
238 | xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/ | ||
239 | __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */ | ||
240 | __int8_t di_aformat; /* format of attr fork's data */ | ||
241 | __uint32_t di_dmevmask; /* DMIG event mask */ | ||
242 | __uint16_t di_dmstate; /* DMIG state info */ | ||
243 | __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */ | ||
244 | __uint32_t di_gen; /* generation number */ | ||
245 | } xfs_icdinode_t; | ||
246 | |||
230 | typedef struct { | 247 | typedef struct { |
231 | struct xfs_ihash *ip_hash; /* pointer to hash header */ | ||
232 | struct xfs_inode *ip_next; /* inode hash link forw */ | ||
233 | struct xfs_inode *ip_mnext; /* next inode in mount list */ | 248 | struct xfs_inode *ip_mnext; /* next inode in mount list */ |
234 | struct xfs_inode *ip_mprev; /* ptr to prev inode */ | 249 | struct xfs_inode *ip_mprev; /* ptr to prev inode */ |
235 | struct xfs_inode **ip_prevp; /* ptr to prev i_next */ | ||
236 | struct xfs_mount *ip_mount; /* fs mount struct ptr */ | 250 | struct xfs_mount *ip_mount; /* fs mount struct ptr */ |
237 | } xfs_iptr_t; | 251 | } xfs_iptr_t; |
238 | 252 | ||
239 | typedef struct xfs_inode { | 253 | typedef struct xfs_inode { |
240 | /* Inode linking and identification information. */ | 254 | /* Inode linking and identification information. */ |
241 | struct xfs_ihash *i_hash; /* pointer to hash header */ | ||
242 | struct xfs_inode *i_next; /* inode hash link forw */ | ||
243 | struct xfs_inode *i_mnext; /* next inode in mount list */ | 255 | struct xfs_inode *i_mnext; /* next inode in mount list */ |
244 | struct xfs_inode *i_mprev; /* ptr to prev inode */ | 256 | struct xfs_inode *i_mprev; /* ptr to prev inode */ |
245 | struct xfs_inode **i_prevp; /* ptr to prev i_next */ | ||
246 | struct xfs_mount *i_mount; /* fs mount struct ptr */ | 257 | struct xfs_mount *i_mount; /* fs mount struct ptr */ |
247 | struct list_head i_reclaim; /* reclaim list */ | 258 | struct list_head i_reclaim; /* reclaim list */ |
248 | struct bhv_desc i_bhv_desc; /* inode behavior descriptor*/ | 259 | bhv_vnode_t *i_vnode; /* vnode backpointer */ |
249 | struct xfs_dquot *i_udquot; /* user dquot */ | 260 | struct xfs_dquot *i_udquot; /* user dquot */ |
250 | struct xfs_dquot *i_gdquot; /* group dquot */ | 261 | struct xfs_dquot *i_gdquot; /* group dquot */ |
251 | 262 | ||
@@ -282,13 +293,16 @@ typedef struct xfs_inode { | |||
282 | unsigned int i_gen; /* generation count */ | 293 | unsigned int i_gen; /* generation count */ |
283 | unsigned int i_delayed_blks; /* count of delay alloc blks */ | 294 | unsigned int i_delayed_blks; /* count of delay alloc blks */ |
284 | 295 | ||
285 | xfs_dinode_core_t i_d; /* most of ondisk inode */ | 296 | xfs_icdinode_t i_d; /* most of ondisk inode */ |
286 | xfs_chashlist_t *i_chash; /* cluster hash list header */ | 297 | xfs_icluster_t *i_cluster; /* cluster list header */ |
287 | struct xfs_inode *i_cnext; /* cluster hash link forward */ | 298 | struct hlist_node i_cnode; /* cluster link node */ |
288 | struct xfs_inode *i_cprev; /* cluster hash link backward */ | ||
289 | 299 | ||
290 | xfs_fsize_t i_size; /* in-memory size */ | 300 | xfs_fsize_t i_size; /* in-memory size */ |
301 | atomic_t i_iocount; /* outstanding I/O count */ | ||
291 | /* Trace buffers per inode. */ | 302 | /* Trace buffers per inode. */ |
303 | #ifdef XFS_VNODE_TRACE | ||
304 | struct ktrace *i_trace; /* general inode trace */ | ||
305 | #endif | ||
292 | #ifdef XFS_BMAP_TRACE | 306 | #ifdef XFS_BMAP_TRACE |
293 | struct ktrace *i_xtrace; /* inode extent list trace */ | 307 | struct ktrace *i_xtrace; /* inode extent list trace */ |
294 | #endif | 308 | #endif |
@@ -349,6 +363,19 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | |||
349 | spin_unlock(&ip->i_flags_lock); | 363 | spin_unlock(&ip->i_flags_lock); |
350 | return ret; | 364 | return ret; |
351 | } | 365 | } |
366 | |||
367 | static inline int | ||
368 | xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags) | ||
369 | { | ||
370 | int ret; | ||
371 | |||
372 | spin_lock(&ip->i_flags_lock); | ||
373 | ret = ip->i_flags & flags; | ||
374 | if (ret) | ||
375 | ip->i_flags &= ~flags; | ||
376 | spin_unlock(&ip->i_flags_lock); | ||
377 | return ret; | ||
378 | } | ||
352 | #endif /* __KERNEL__ */ | 379 | #endif /* __KERNEL__ */ |
353 | 380 | ||
354 | 381 | ||
@@ -380,6 +407,9 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | |||
380 | #define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */ | 407 | #define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */ |
381 | #define XFS_INEW 0x0040 | 408 | #define XFS_INEW 0x0040 |
382 | #define XFS_IFILESTREAM 0x0080 /* inode is in a filestream directory */ | 409 | #define XFS_IFILESTREAM 0x0080 /* inode is in a filestream directory */ |
410 | #define XFS_IMODIFIED 0x0100 /* XFS inode state possibly differs */ | ||
411 | /* to the Linux inode state. */ | ||
412 | #define XFS_ITRUNCATED 0x0200 /* truncated down so flush-on-close */ | ||
383 | 413 | ||
384 | /* | 414 | /* |
385 | * Flags for inode locking. | 415 | * Flags for inode locking. |
@@ -454,20 +484,17 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | |||
454 | #define XFS_ITRUNC_DEFINITE 0x1 | 484 | #define XFS_ITRUNC_DEFINITE 0x1 |
455 | #define XFS_ITRUNC_MAYBE 0x2 | 485 | #define XFS_ITRUNC_MAYBE 0x2 |
456 | 486 | ||
457 | #define XFS_ITOV(ip) BHV_TO_VNODE(XFS_ITOBHV(ip)) | 487 | #define XFS_ITOV(ip) ((ip)->i_vnode) |
458 | #define XFS_ITOV_NULL(ip) BHV_TO_VNODE_NULL(XFS_ITOBHV(ip)) | 488 | #define XFS_ITOV_NULL(ip) ((ip)->i_vnode) |
459 | #define XFS_ITOBHV(ip) ((struct bhv_desc *)(&((ip)->i_bhv_desc))) | ||
460 | #define XFS_BHVTOI(bhvp) ((xfs_inode_t *)((char *)(bhvp) - \ | ||
461 | (char *)&(((xfs_inode_t *)0)->i_bhv_desc))) | ||
462 | #define BHV_IS_XFS(bdp) (BHV_OPS(bdp) == &xfs_vnodeops) | ||
463 | 489 | ||
464 | /* | 490 | /* |
465 | * For multiple groups support: if S_ISGID bit is set in the parent | 491 | * For multiple groups support: if S_ISGID bit is set in the parent |
466 | * directory, group of new file is set to that of the parent, and | 492 | * directory, group of new file is set to that of the parent, and |
467 | * new subdirectory gets S_ISGID bit from parent. | 493 | * new subdirectory gets S_ISGID bit from parent. |
468 | */ | 494 | */ |
469 | #define XFS_INHERIT_GID(pip, vfsp) \ | 495 | #define XFS_INHERIT_GID(pip) \ |
470 | (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID)) | 496 | (((pip)->i_mount->m_flags & XFS_MOUNT_GRPID) || \ |
497 | ((pip)->i_d.di_mode & S_ISGID)) | ||
471 | 498 | ||
472 | /* | 499 | /* |
473 | * Flags for xfs_iget() | 500 | * Flags for xfs_iget() |
@@ -480,11 +507,9 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | |||
480 | */ | 507 | */ |
481 | void xfs_ihash_init(struct xfs_mount *); | 508 | void xfs_ihash_init(struct xfs_mount *); |
482 | void xfs_ihash_free(struct xfs_mount *); | 509 | void xfs_ihash_free(struct xfs_mount *); |
483 | void xfs_chash_init(struct xfs_mount *); | ||
484 | void xfs_chash_free(struct xfs_mount *); | ||
485 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, | 510 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, |
486 | struct xfs_trans *); | 511 | struct xfs_trans *); |
487 | void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *); | 512 | void xfs_inode_lock_init(xfs_inode_t *, bhv_vnode_t *); |
488 | int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 513 | int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, |
489 | uint, uint, xfs_inode_t **, xfs_daddr_t); | 514 | uint, uint, xfs_inode_t **, xfs_daddr_t); |
490 | void xfs_iput(xfs_inode_t *, uint); | 515 | void xfs_iput(xfs_inode_t *, uint); |
@@ -506,7 +531,7 @@ int xfs_finish_reclaim_all(struct xfs_mount *, int); | |||
506 | * xfs_inode.c prototypes. | 531 | * xfs_inode.c prototypes. |
507 | */ | 532 | */ |
508 | int xfs_itobp(struct xfs_mount *, struct xfs_trans *, | 533 | int xfs_itobp(struct xfs_mount *, struct xfs_trans *, |
509 | xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **, | 534 | xfs_inode_t *, struct xfs_dinode **, struct xfs_buf **, |
510 | xfs_daddr_t, uint); | 535 | xfs_daddr_t, uint); |
511 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 536 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, |
512 | xfs_inode_t **, xfs_daddr_t, uint); | 537 | xfs_inode_t **, xfs_daddr_t, uint); |
@@ -514,8 +539,11 @@ int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); | |||
514 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, | 539 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, |
515 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, | 540 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, |
516 | int, struct xfs_buf **, boolean_t *, xfs_inode_t **); | 541 | int, struct xfs_buf **, boolean_t *, xfs_inode_t **); |
517 | void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *, | 542 | void xfs_dinode_from_disk(struct xfs_icdinode *, |
518 | int); | 543 | struct xfs_dinode_core *); |
544 | void xfs_dinode_to_disk(struct xfs_dinode_core *, | ||
545 | struct xfs_icdinode *); | ||
546 | |||
519 | uint xfs_ip2xflags(struct xfs_inode *); | 547 | uint xfs_ip2xflags(struct xfs_inode *); |
520 | uint xfs_dic2xflags(struct xfs_dinode_core *); | 548 | uint xfs_dic2xflags(struct xfs_dinode_core *); |
521 | int xfs_ifree(struct xfs_trans *, xfs_inode_t *, | 549 | int xfs_ifree(struct xfs_trans *, xfs_inode_t *, |
@@ -545,11 +573,9 @@ void xfs_ichgtime(xfs_inode_t *, int); | |||
545 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); | 573 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); |
546 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); | 574 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); |
547 | 575 | ||
548 | xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp); | ||
549 | |||
550 | void xfs_synchronize_atime(xfs_inode_t *); | 576 | void xfs_synchronize_atime(xfs_inode_t *); |
551 | 577 | ||
552 | xfs_bmbt_rec_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); | 578 | xfs_bmbt_rec_host_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t); |
553 | void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, | 579 | void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t, |
554 | xfs_bmbt_irec_t *); | 580 | xfs_bmbt_irec_t *); |
555 | void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int); | 581 | void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int); |
@@ -564,7 +590,7 @@ void xfs_iext_indirect_to_direct(xfs_ifork_t *); | |||
564 | void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t); | 590 | void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t); |
565 | void xfs_iext_inline_to_direct(xfs_ifork_t *, int); | 591 | void xfs_iext_inline_to_direct(xfs_ifork_t *, int); |
566 | void xfs_iext_destroy(xfs_ifork_t *); | 592 | void xfs_iext_destroy(xfs_ifork_t *); |
567 | xfs_bmbt_rec_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *); | 593 | xfs_bmbt_rec_host_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *); |
568 | xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *); | 594 | xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *); |
569 | xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int); | 595 | xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int); |
570 | void xfs_iext_irec_init(xfs_ifork_t *); | 596 | void xfs_iext_irec_init(xfs_ifork_t *); |
@@ -589,7 +615,7 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); | |||
589 | #define xfs_inobp_check(mp, bp) | 615 | #define xfs_inobp_check(mp, bp) |
590 | #endif /* DEBUG */ | 616 | #endif /* DEBUG */ |
591 | 617 | ||
592 | extern struct kmem_zone *xfs_chashlist_zone; | 618 | extern struct kmem_zone *xfs_icluster_zone; |
593 | extern struct kmem_zone *xfs_ifork_zone; | 619 | extern struct kmem_zone *xfs_ifork_zone; |
594 | extern struct kmem_zone *xfs_inode_zone; | 620 | extern struct kmem_zone *xfs_inode_zone; |
595 | extern struct kmem_zone *xfs_ili_zone; | 621 | extern struct kmem_zone *xfs_ili_zone; |
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c index 81548ec72ba6..b27b5d5be841 100644 --- a/fs/xfs/xfs_iocore.c +++ b/fs/xfs/xfs_iocore.c | |||
@@ -57,11 +57,11 @@ xfs_size_fn( | |||
57 | 57 | ||
58 | STATIC int | 58 | STATIC int |
59 | xfs_ioinit( | 59 | xfs_ioinit( |
60 | struct bhv_vfs *vfsp, | 60 | struct xfs_mount *mp, |
61 | struct xfs_mount_args *mntargs, | 61 | struct xfs_mount_args *mntargs, |
62 | int flags) | 62 | int flags) |
63 | { | 63 | { |
64 | return xfs_mountfs(vfsp, XFS_VFSTOM(vfsp), flags); | 64 | return xfs_mountfs(mp, flags); |
65 | } | 65 | } |
66 | 66 | ||
67 | xfs_ioops_t xfs_iocore_xfs = { | 67 | xfs_ioops_t xfs_iocore_xfs = { |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index bf57b75acb90..72786e356d56 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -135,14 +135,10 @@ xfs_imap_to_bmap( | |||
135 | int flags) | 135 | int flags) |
136 | { | 136 | { |
137 | xfs_mount_t *mp; | 137 | xfs_mount_t *mp; |
138 | xfs_fsize_t nisize; | ||
139 | int pbm; | 138 | int pbm; |
140 | xfs_fsblock_t start_block; | 139 | xfs_fsblock_t start_block; |
141 | 140 | ||
142 | mp = io->io_mount; | 141 | mp = io->io_mount; |
143 | nisize = XFS_SIZE(mp, io); | ||
144 | if (io->io_new_size > nisize) | ||
145 | nisize = io->io_new_size; | ||
146 | 142 | ||
147 | for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) { | 143 | for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) { |
148 | iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); | 144 | iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); |
@@ -169,10 +165,6 @@ xfs_imap_to_bmap( | |||
169 | iomapp->iomap_flags |= IOMAP_UNWRITTEN; | 165 | iomapp->iomap_flags |= IOMAP_UNWRITTEN; |
170 | } | 166 | } |
171 | 167 | ||
172 | if ((iomapp->iomap_offset + iomapp->iomap_bsize) >= nisize) { | ||
173 | iomapp->iomap_flags |= IOMAP_EOF; | ||
174 | } | ||
175 | |||
176 | offset += iomapp->iomap_bsize - iomapp->iomap_delta; | 168 | offset += iomapp->iomap_bsize - iomapp->iomap_delta; |
177 | } | 169 | } |
178 | return pbm; /* Return the number filled */ | 170 | return pbm; /* Return the number filled */ |
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index df441ee936b2..f5c09887fe93 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | typedef enum { /* iomap_flags values */ | 24 | typedef enum { /* iomap_flags values */ |
25 | IOMAP_READ = 0, /* mapping for a read */ | 25 | IOMAP_READ = 0, /* mapping for a read */ |
26 | IOMAP_EOF = 0x01, /* mapping contains EOF */ | ||
27 | IOMAP_HOLE = 0x02, /* mapping covers a hole */ | 26 | IOMAP_HOLE = 0x02, /* mapping covers a hole */ |
28 | IOMAP_DELAY = 0x04, /* mapping covers delalloc region */ | 27 | IOMAP_DELAY = 0x04, /* mapping covers delalloc region */ |
29 | IOMAP_REALTIME = 0x10, /* mapping on the realtime device */ | 28 | IOMAP_REALTIME = 0x10, /* mapping on the realtime device */ |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 4c2454bcc714..9972992fd3c3 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -57,7 +57,7 @@ xfs_bulkstat_one_iget( | |||
57 | xfs_bstat_t *buf, /* return buffer */ | 57 | xfs_bstat_t *buf, /* return buffer */ |
58 | int *stat) /* BULKSTAT_RV_... */ | 58 | int *stat) /* BULKSTAT_RV_... */ |
59 | { | 59 | { |
60 | xfs_dinode_core_t *dic; /* dinode core info pointer */ | 60 | xfs_icdinode_t *dic; /* dinode core info pointer */ |
61 | xfs_inode_t *ip; /* incore inode pointer */ | 61 | xfs_inode_t *ip; /* incore inode pointer */ |
62 | bhv_vnode_t *vp; | 62 | bhv_vnode_t *vp; |
63 | int error; | 63 | int error; |
@@ -151,37 +151,37 @@ xfs_bulkstat_one_dinode( | |||
151 | * the new format. We don't change the version number so that we | 151 | * the new format. We don't change the version number so that we |
152 | * can distinguish this from a real new format inode. | 152 | * can distinguish this from a real new format inode. |
153 | */ | 153 | */ |
154 | if (INT_GET(dic->di_version, ARCH_CONVERT) == XFS_DINODE_VERSION_1) { | 154 | if (dic->di_version == XFS_DINODE_VERSION_1) { |
155 | buf->bs_nlink = INT_GET(dic->di_onlink, ARCH_CONVERT); | 155 | buf->bs_nlink = be16_to_cpu(dic->di_onlink); |
156 | buf->bs_projid = 0; | 156 | buf->bs_projid = 0; |
157 | } else { | 157 | } else { |
158 | buf->bs_nlink = INT_GET(dic->di_nlink, ARCH_CONVERT); | 158 | buf->bs_nlink = be32_to_cpu(dic->di_nlink); |
159 | buf->bs_projid = INT_GET(dic->di_projid, ARCH_CONVERT); | 159 | buf->bs_projid = be16_to_cpu(dic->di_projid); |
160 | } | 160 | } |
161 | 161 | ||
162 | buf->bs_ino = ino; | 162 | buf->bs_ino = ino; |
163 | buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT); | 163 | buf->bs_mode = be16_to_cpu(dic->di_mode); |
164 | buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT); | 164 | buf->bs_uid = be32_to_cpu(dic->di_uid); |
165 | buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT); | 165 | buf->bs_gid = be32_to_cpu(dic->di_gid); |
166 | buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT); | 166 | buf->bs_size = be64_to_cpu(dic->di_size); |
167 | buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT); | 167 | buf->bs_atime.tv_sec = be32_to_cpu(dic->di_atime.t_sec); |
168 | buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT); | 168 | buf->bs_atime.tv_nsec = be32_to_cpu(dic->di_atime.t_nsec); |
169 | buf->bs_mtime.tv_sec = INT_GET(dic->di_mtime.t_sec, ARCH_CONVERT); | 169 | buf->bs_mtime.tv_sec = be32_to_cpu(dic->di_mtime.t_sec); |
170 | buf->bs_mtime.tv_nsec = INT_GET(dic->di_mtime.t_nsec, ARCH_CONVERT); | 170 | buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec); |
171 | buf->bs_ctime.tv_sec = INT_GET(dic->di_ctime.t_sec, ARCH_CONVERT); | 171 | buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec); |
172 | buf->bs_ctime.tv_nsec = INT_GET(dic->di_ctime.t_nsec, ARCH_CONVERT); | 172 | buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec); |
173 | buf->bs_xflags = xfs_dic2xflags(dic); | 173 | buf->bs_xflags = xfs_dic2xflags(dic); |
174 | buf->bs_extsize = INT_GET(dic->di_extsize, ARCH_CONVERT) << mp->m_sb.sb_blocklog; | 174 | buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog; |
175 | buf->bs_extents = INT_GET(dic->di_nextents, ARCH_CONVERT); | 175 | buf->bs_extents = be32_to_cpu(dic->di_nextents); |
176 | buf->bs_gen = INT_GET(dic->di_gen, ARCH_CONVERT); | 176 | buf->bs_gen = be32_to_cpu(dic->di_gen); |
177 | memset(buf->bs_pad, 0, sizeof(buf->bs_pad)); | 177 | memset(buf->bs_pad, 0, sizeof(buf->bs_pad)); |
178 | buf->bs_dmevmask = INT_GET(dic->di_dmevmask, ARCH_CONVERT); | 178 | buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask); |
179 | buf->bs_dmstate = INT_GET(dic->di_dmstate, ARCH_CONVERT); | 179 | buf->bs_dmstate = be16_to_cpu(dic->di_dmstate); |
180 | buf->bs_aextents = INT_GET(dic->di_anextents, ARCH_CONVERT); | 180 | buf->bs_aextents = be16_to_cpu(dic->di_anextents); |
181 | 181 | ||
182 | switch (INT_GET(dic->di_format, ARCH_CONVERT)) { | 182 | switch (dic->di_format) { |
183 | case XFS_DINODE_FMT_DEV: | 183 | case XFS_DINODE_FMT_DEV: |
184 | buf->bs_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); | 184 | buf->bs_rdev = be32_to_cpu(dip->di_u.di_dev); |
185 | buf->bs_blksize = BLKDEV_IOSIZE; | 185 | buf->bs_blksize = BLKDEV_IOSIZE; |
186 | buf->bs_blocks = 0; | 186 | buf->bs_blocks = 0; |
187 | break; | 187 | break; |
@@ -195,7 +195,7 @@ xfs_bulkstat_one_dinode( | |||
195 | case XFS_DINODE_FMT_BTREE: | 195 | case XFS_DINODE_FMT_BTREE: |
196 | buf->bs_rdev = 0; | 196 | buf->bs_rdev = 0; |
197 | buf->bs_blksize = mp->m_sb.sb_blocksize; | 197 | buf->bs_blksize = mp->m_sb.sb_blocksize; |
198 | buf->bs_blocks = INT_GET(dic->di_nblocks, ARCH_CONVERT); | 198 | buf->bs_blocks = be64_to_cpu(dic->di_nblocks); |
199 | break; | 199 | break; |
200 | } | 200 | } |
201 | 201 | ||
@@ -290,16 +290,23 @@ xfs_bulkstat_use_dinode( | |||
290 | return 1; | 290 | return 1; |
291 | dip = (xfs_dinode_t *) | 291 | dip = (xfs_dinode_t *) |
292 | xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog); | 292 | xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog); |
293 | if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC || | 293 | /* |
294 | !XFS_DINODE_GOOD_VERSION( | 294 | * Check the buffer containing the on-disk inode for di_nlink == 0. |
295 | INT_GET(dip->di_core.di_version, ARCH_CONVERT))) | 295 | * This is to prevent xfs_bulkstat from picking up just reclaimed |
296 | * inodes that have their in-core state initialized but not flushed | ||
297 | * to disk yet. This is a temporary hack that would require a proper | ||
298 | * fix in the future. | ||
299 | */ | ||
300 | if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC || | ||
301 | !XFS_DINODE_GOOD_VERSION(dip->di_core.di_version) || | ||
302 | !dip->di_core.di_nlink) | ||
296 | return 0; | 303 | return 0; |
297 | if (flags & BULKSTAT_FG_QUICK) { | 304 | if (flags & BULKSTAT_FG_QUICK) { |
298 | *dipp = dip; | 305 | *dipp = dip; |
299 | return 1; | 306 | return 1; |
300 | } | 307 | } |
301 | /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ | 308 | /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ |
302 | aformat = INT_GET(dip->di_core.di_aformat, ARCH_CONVERT); | 309 | aformat = dip->di_core.di_aformat; |
303 | if ((XFS_CFORK_Q(&dip->di_core) == 0) || | 310 | if ((XFS_CFORK_Q(&dip->di_core) == 0) || |
304 | (aformat == XFS_DINODE_FMT_LOCAL) || | 311 | (aformat == XFS_DINODE_FMT_LOCAL) || |
305 | (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) { | 312 | (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) { |
@@ -612,21 +619,25 @@ xfs_bulkstat( | |||
612 | } | 619 | } |
613 | } | 620 | } |
614 | } | 621 | } |
622 | ino = XFS_AGINO_TO_INO(mp, agno, agino); | ||
623 | bno = XFS_AGB_TO_DADDR(mp, agno, agbno); | ||
615 | /* | 624 | /* |
616 | * Skip if this inode is free. | 625 | * Skip if this inode is free. |
617 | */ | 626 | */ |
618 | if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) | 627 | if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) { |
628 | lastino = ino; | ||
619 | continue; | 629 | continue; |
630 | } | ||
620 | /* | 631 | /* |
621 | * Count used inodes as free so we can tell | 632 | * Count used inodes as free so we can tell |
622 | * when the chunk is used up. | 633 | * when the chunk is used up. |
623 | */ | 634 | */ |
624 | irbp->ir_freecount++; | 635 | irbp->ir_freecount++; |
625 | ino = XFS_AGINO_TO_INO(mp, agno, agino); | ||
626 | bno = XFS_AGB_TO_DADDR(mp, agno, agbno); | ||
627 | if (!xfs_bulkstat_use_dinode(mp, flags, bp, | 636 | if (!xfs_bulkstat_use_dinode(mp, flags, bp, |
628 | clustidx, &dip)) | 637 | clustidx, &dip)) { |
638 | lastino = ino; | ||
629 | continue; | 639 | continue; |
640 | } | ||
630 | /* | 641 | /* |
631 | * If we need to do an iget, cannot hold bp. | 642 | * If we need to do an iget, cannot hold bp. |
632 | * Drop it, until starting the next cluster. | 643 | * Drop it, until starting the next cluster. |
@@ -687,8 +698,7 @@ xfs_bulkstat( | |||
687 | if (end_of_ag) { | 698 | if (end_of_ag) { |
688 | agno++; | 699 | agno++; |
689 | agino = 0; | 700 | agino = 0; |
690 | } else | 701 | } |
691 | agino = XFS_INO_TO_AGINO(mp, lastino); | ||
692 | } else | 702 | } else |
693 | break; | 703 | break; |
694 | } | 704 | } |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 9bfb69e1e885..77c12715a7d0 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -252,6 +252,29 @@ xlog_grant_add_space(struct log *log, int bytes) | |||
252 | xlog_grant_add_space_reserve(log, bytes); | 252 | xlog_grant_add_space_reserve(log, bytes); |
253 | } | 253 | } |
254 | 254 | ||
255 | static void | ||
256 | xlog_tic_reset_res(xlog_ticket_t *tic) | ||
257 | { | ||
258 | tic->t_res_num = 0; | ||
259 | tic->t_res_arr_sum = 0; | ||
260 | tic->t_res_num_ophdrs = 0; | ||
261 | } | ||
262 | |||
263 | static void | ||
264 | xlog_tic_add_region(xlog_ticket_t *tic, uint len, uint type) | ||
265 | { | ||
266 | if (tic->t_res_num == XLOG_TIC_LEN_MAX) { | ||
267 | /* add to overflow and start again */ | ||
268 | tic->t_res_o_flow += tic->t_res_arr_sum; | ||
269 | tic->t_res_num = 0; | ||
270 | tic->t_res_arr_sum = 0; | ||
271 | } | ||
272 | |||
273 | tic->t_res_arr[tic->t_res_num].r_len = len; | ||
274 | tic->t_res_arr[tic->t_res_num].r_type = type; | ||
275 | tic->t_res_arr_sum += len; | ||
276 | tic->t_res_num++; | ||
277 | } | ||
255 | 278 | ||
256 | /* | 279 | /* |
257 | * NOTES: | 280 | * NOTES: |
@@ -486,7 +509,7 @@ xfs_log_mount(xfs_mount_t *mp, | |||
486 | cmn_err(CE_NOTE, | 509 | cmn_err(CE_NOTE, |
487 | "!Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.", | 510 | "!Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.", |
488 | mp->m_fsname); | 511 | mp->m_fsname); |
489 | ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY); | 512 | ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); |
490 | } | 513 | } |
491 | 514 | ||
492 | mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks); | 515 | mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks); |
@@ -496,16 +519,15 @@ xfs_log_mount(xfs_mount_t *mp, | |||
496 | * just worked. | 519 | * just worked. |
497 | */ | 520 | */ |
498 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { | 521 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { |
499 | bhv_vfs_t *vfsp = XFS_MTOVFS(mp); | 522 | int error, readonly = (mp->m_flags & XFS_MOUNT_RDONLY); |
500 | int error, readonly = (vfsp->vfs_flag & VFS_RDONLY); | ||
501 | 523 | ||
502 | if (readonly) | 524 | if (readonly) |
503 | vfsp->vfs_flag &= ~VFS_RDONLY; | 525 | mp->m_flags &= ~XFS_MOUNT_RDONLY; |
504 | 526 | ||
505 | error = xlog_recover(mp->m_log); | 527 | error = xlog_recover(mp->m_log); |
506 | 528 | ||
507 | if (readonly) | 529 | if (readonly) |
508 | vfsp->vfs_flag |= VFS_RDONLY; | 530 | mp->m_flags |= XFS_MOUNT_RDONLY; |
509 | if (error) { | 531 | if (error) { |
510 | cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); | 532 | cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); |
511 | xlog_dealloc_log(mp->m_log); | 533 | xlog_dealloc_log(mp->m_log); |
@@ -537,7 +559,7 @@ xfs_log_mount_finish(xfs_mount_t *mp, int mfsi_flags) | |||
537 | error = xlog_recover_finish(mp->m_log, mfsi_flags); | 559 | error = xlog_recover_finish(mp->m_log, mfsi_flags); |
538 | else { | 560 | else { |
539 | error = 0; | 561 | error = 0; |
540 | ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY); | 562 | ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); |
541 | } | 563 | } |
542 | 564 | ||
543 | return error; | 565 | return error; |
@@ -597,7 +619,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
597 | * Don't write out unmount record on read-only mounts. | 619 | * Don't write out unmount record on read-only mounts. |
598 | * Or, if we are doing a forced umount (typically because of IO errors). | 620 | * Or, if we are doing a forced umount (typically because of IO errors). |
599 | */ | 621 | */ |
600 | if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) | 622 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
601 | return 0; | 623 | return 0; |
602 | 624 | ||
603 | xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC); | 625 | xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC); |
@@ -949,6 +971,19 @@ xlog_iodone(xfs_buf_t *bp) | |||
949 | l = iclog->ic_log; | 971 | l = iclog->ic_log; |
950 | 972 | ||
951 | /* | 973 | /* |
974 | * If the ordered flag has been removed by a lower | ||
975 | * layer, it means the underlyin device no longer supports | ||
976 | * barrier I/O. Warn loudly and turn off barriers. | ||
977 | */ | ||
978 | if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ORDERED(bp)) { | ||
979 | l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
980 | xfs_fs_cmn_err(CE_WARN, l->l_mp, | ||
981 | "xlog_iodone: Barriers are no longer supported" | ||
982 | " by device. Disabling barriers\n"); | ||
983 | xfs_buftrace("XLOG_IODONE BARRIERS OFF", bp); | ||
984 | } | ||
985 | |||
986 | /* | ||
952 | * Race to shutdown the filesystem if we see an error. | 987 | * Race to shutdown the filesystem if we see an error. |
953 | */ | 988 | */ |
954 | if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp, | 989 | if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp, |
@@ -1012,10 +1047,7 @@ xlog_bdstrat_cb(struct xfs_buf *bp) | |||
1012 | /* | 1047 | /* |
1013 | * Return size of each in-core log record buffer. | 1048 | * Return size of each in-core log record buffer. |
1014 | * | 1049 | * |
1015 | * Low memory machines only get 2 16KB buffers. We don't want to waste | 1050 | * All machines get 8 x 32KB buffers by default, unless tuned otherwise. |
1016 | * memory here. However, all other machines get at least 2 32KB buffers. | ||
1017 | * The number is hard coded because we don't care about the minimum | ||
1018 | * memory size, just 32MB systems. | ||
1019 | * | 1051 | * |
1020 | * If the filesystem blocksize is too large, we may need to choose a | 1052 | * If the filesystem blocksize is too large, we may need to choose a |
1021 | * larger size since the directory code currently logs entire blocks. | 1053 | * larger size since the directory code currently logs entire blocks. |
@@ -1028,17 +1060,10 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp, | |||
1028 | int size; | 1060 | int size; |
1029 | int xhdrs; | 1061 | int xhdrs; |
1030 | 1062 | ||
1031 | if (mp->m_logbufs <= 0) { | 1063 | if (mp->m_logbufs <= 0) |
1032 | if (xfs_physmem <= btoc(128*1024*1024)) { | 1064 | log->l_iclog_bufs = XLOG_MAX_ICLOGS; |
1033 | log->l_iclog_bufs = XLOG_MIN_ICLOGS; | 1065 | else |
1034 | } else if (xfs_physmem <= btoc(400*1024*1024)) { | ||
1035 | log->l_iclog_bufs = XLOG_MED_ICLOGS; | ||
1036 | } else { /* 256K with 32K bufs */ | ||
1037 | log->l_iclog_bufs = XLOG_MAX_ICLOGS; | ||
1038 | } | ||
1039 | } else { | ||
1040 | log->l_iclog_bufs = mp->m_logbufs; | 1066 | log->l_iclog_bufs = mp->m_logbufs; |
1041 | } | ||
1042 | 1067 | ||
1043 | /* | 1068 | /* |
1044 | * Buffer size passed in from mount system call. | 1069 | * Buffer size passed in from mount system call. |
@@ -1069,18 +1094,9 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp, | |||
1069 | goto done; | 1094 | goto done; |
1070 | } | 1095 | } |
1071 | 1096 | ||
1072 | /* | 1097 | /* All machines use 32KB buffers by default. */ |
1073 | * Special case machines that have less than 32MB of memory. | 1098 | log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; |
1074 | * All machines with more memory use 32KB buffers. | 1099 | log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT; |
1075 | */ | ||
1076 | if (xfs_physmem <= btoc(32*1024*1024)) { | ||
1077 | /* Don't change; min configuration */ | ||
1078 | log->l_iclog_size = XLOG_RECORD_BSIZE; /* 16k */ | ||
1079 | log->l_iclog_size_log = XLOG_RECORD_BSHIFT; | ||
1080 | } else { | ||
1081 | log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; /* 32k */ | ||
1082 | log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT; | ||
1083 | } | ||
1084 | 1100 | ||
1085 | /* the default log size is 16k or 32k which is one header sector */ | 1101 | /* the default log size is 16k or 32k which is one header sector */ |
1086 | log->l_iclog_hsize = BBSIZE; | 1102 | log->l_iclog_hsize = BBSIZE; |
@@ -1771,14 +1787,14 @@ xlog_write(xfs_mount_t * mp, | |||
1771 | len = 0; | 1787 | len = 0; |
1772 | if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */ | 1788 | if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */ |
1773 | len += sizeof(xlog_op_header_t); | 1789 | len += sizeof(xlog_op_header_t); |
1774 | XLOG_TIC_ADD_OPHDR(ticket); | 1790 | ticket->t_res_num_ophdrs++; |
1775 | } | 1791 | } |
1776 | 1792 | ||
1777 | for (index = 0; index < nentries; index++) { | 1793 | for (index = 0; index < nentries; index++) { |
1778 | len += sizeof(xlog_op_header_t); /* each region gets >= 1 */ | 1794 | len += sizeof(xlog_op_header_t); /* each region gets >= 1 */ |
1779 | XLOG_TIC_ADD_OPHDR(ticket); | 1795 | ticket->t_res_num_ophdrs++; |
1780 | len += reg[index].i_len; | 1796 | len += reg[index].i_len; |
1781 | XLOG_TIC_ADD_REGION(ticket, reg[index].i_len, reg[index].i_type); | 1797 | xlog_tic_add_region(ticket, reg[index].i_len, reg[index].i_type); |
1782 | } | 1798 | } |
1783 | contwr = *start_lsn = 0; | 1799 | contwr = *start_lsn = 0; |
1784 | 1800 | ||
@@ -1887,7 +1903,7 @@ xlog_write(xfs_mount_t * mp, | |||
1887 | len += sizeof(xlog_op_header_t); /* from splitting of region */ | 1903 | len += sizeof(xlog_op_header_t); /* from splitting of region */ |
1888 | /* account for new log op header */ | 1904 | /* account for new log op header */ |
1889 | ticket->t_curr_res -= sizeof(xlog_op_header_t); | 1905 | ticket->t_curr_res -= sizeof(xlog_op_header_t); |
1890 | XLOG_TIC_ADD_OPHDR(ticket); | 1906 | ticket->t_res_num_ophdrs++; |
1891 | } | 1907 | } |
1892 | xlog_verify_dest_ptr(log, ptr); | 1908 | xlog_verify_dest_ptr(log, ptr); |
1893 | 1909 | ||
@@ -2385,7 +2401,7 @@ restart: | |||
2385 | */ | 2401 | */ |
2386 | if (log_offset == 0) { | 2402 | if (log_offset == 0) { |
2387 | ticket->t_curr_res -= log->l_iclog_hsize; | 2403 | ticket->t_curr_res -= log->l_iclog_hsize; |
2388 | XLOG_TIC_ADD_REGION(ticket, | 2404 | xlog_tic_add_region(ticket, |
2389 | log->l_iclog_hsize, | 2405 | log->l_iclog_hsize, |
2390 | XLOG_REG_TYPE_LRHEADER); | 2406 | XLOG_REG_TYPE_LRHEADER); |
2391 | INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle); | 2407 | INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle); |
@@ -2573,7 +2589,7 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2573 | #endif | 2589 | #endif |
2574 | 2590 | ||
2575 | tic->t_curr_res = tic->t_unit_res; | 2591 | tic->t_curr_res = tic->t_unit_res; |
2576 | XLOG_TIC_RESET_RES(tic); | 2592 | xlog_tic_reset_res(tic); |
2577 | 2593 | ||
2578 | if (tic->t_cnt > 0) | 2594 | if (tic->t_cnt > 0) |
2579 | return 0; | 2595 | return 0; |
@@ -2714,7 +2730,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2714 | s = GRANT_LOCK(log); | 2730 | s = GRANT_LOCK(log); |
2715 | xlog_grant_sub_space(log, ticket->t_curr_res); | 2731 | xlog_grant_sub_space(log, ticket->t_curr_res); |
2716 | ticket->t_curr_res = ticket->t_unit_res; | 2732 | ticket->t_curr_res = ticket->t_unit_res; |
2717 | XLOG_TIC_RESET_RES(ticket); | 2733 | xlog_tic_reset_res(ticket); |
2718 | xlog_trace_loggrant(log, ticket, | 2734 | xlog_trace_loggrant(log, ticket, |
2719 | "xlog_regrant_reserve_log_space: sub current res"); | 2735 | "xlog_regrant_reserve_log_space: sub current res"); |
2720 | xlog_verify_grant_head(log, 1); | 2736 | xlog_verify_grant_head(log, 1); |
@@ -2731,7 +2747,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2731 | xlog_verify_grant_head(log, 0); | 2747 | xlog_verify_grant_head(log, 0); |
2732 | GRANT_UNLOCK(log, s); | 2748 | GRANT_UNLOCK(log, s); |
2733 | ticket->t_curr_res = ticket->t_unit_res; | 2749 | ticket->t_curr_res = ticket->t_unit_res; |
2734 | XLOG_TIC_RESET_RES(ticket); | 2750 | xlog_tic_reset_res(ticket); |
2735 | } /* xlog_regrant_reserve_log_space */ | 2751 | } /* xlog_regrant_reserve_log_space */ |
2736 | 2752 | ||
2737 | 2753 | ||
@@ -3354,7 +3370,7 @@ xlog_ticket_get(xlog_t *log, | |||
3354 | tic->t_flags |= XLOG_TIC_PERM_RESERV; | 3370 | tic->t_flags |= XLOG_TIC_PERM_RESERV; |
3355 | sv_init(&(tic->t_sema), SV_DEFAULT, "logtick"); | 3371 | sv_init(&(tic->t_sema), SV_DEFAULT, "logtick"); |
3356 | 3372 | ||
3357 | XLOG_TIC_RESET_RES(tic); | 3373 | xlog_tic_reset_res(tic); |
3358 | 3374 | ||
3359 | return tic; | 3375 | return tic; |
3360 | } /* xlog_ticket_get */ | 3376 | } /* xlog_ticket_get */ |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 9bd3cdf11a87..752f964b3699 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -30,17 +30,16 @@ struct xfs_mount; | |||
30 | */ | 30 | */ |
31 | 31 | ||
32 | #define XLOG_MIN_ICLOGS 2 | 32 | #define XLOG_MIN_ICLOGS 2 |
33 | #define XLOG_MED_ICLOGS 4 | ||
34 | #define XLOG_MAX_ICLOGS 8 | 33 | #define XLOG_MAX_ICLOGS 8 |
35 | #define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */ | 34 | #define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */ |
36 | #define XLOG_VERSION_1 1 | 35 | #define XLOG_VERSION_1 1 |
37 | #define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ | 36 | #define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ |
38 | #define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2) | 37 | #define XLOG_VERSION_OKBITS (XLOG_VERSION_1 | XLOG_VERSION_2) |
39 | #define XLOG_RECORD_BSIZE (16*1024) /* eventually 32k */ | 38 | #define XLOG_MIN_RECORD_BSIZE (16*1024) /* eventually 32k */ |
40 | #define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */ | 39 | #define XLOG_BIG_RECORD_BSIZE (32*1024) /* 32k buffers */ |
41 | #define XLOG_MAX_RECORD_BSIZE (256*1024) | 40 | #define XLOG_MAX_RECORD_BSIZE (256*1024) |
42 | #define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */ | 41 | #define XLOG_HEADER_CYCLE_SIZE (32*1024) /* cycle data in header */ |
43 | #define XLOG_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */ | 42 | #define XLOG_MIN_RECORD_BSHIFT 14 /* 16384 == 1 << 14 */ |
44 | #define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */ | 43 | #define XLOG_BIG_RECORD_BSHIFT 15 /* 32k == 1 << 15 */ |
45 | #define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */ | 44 | #define XLOG_MAX_RECORD_BSHIFT 18 /* 256k == 1 << 18 */ |
46 | #define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \ | 45 | #define XLOG_BTOLSUNIT(log, b) (((b)+(log)->l_mp->m_sb.sb_logsunit-1) / \ |
@@ -250,22 +249,6 @@ typedef __uint32_t xlog_tid_t; | |||
250 | 249 | ||
251 | /* Ticket reservation region accounting */ | 250 | /* Ticket reservation region accounting */ |
252 | #define XLOG_TIC_LEN_MAX 15 | 251 | #define XLOG_TIC_LEN_MAX 15 |
253 | #define XLOG_TIC_RESET_RES(t) ((t)->t_res_num = \ | ||
254 | (t)->t_res_arr_sum = (t)->t_res_num_ophdrs = 0) | ||
255 | #define XLOG_TIC_ADD_OPHDR(t) ((t)->t_res_num_ophdrs++) | ||
256 | #define XLOG_TIC_ADD_REGION(t, len, type) \ | ||
257 | do { \ | ||
258 | if ((t)->t_res_num == XLOG_TIC_LEN_MAX) { \ | ||
259 | /* add to overflow and start again */ \ | ||
260 | (t)->t_res_o_flow += (t)->t_res_arr_sum; \ | ||
261 | (t)->t_res_num = 0; \ | ||
262 | (t)->t_res_arr_sum = 0; \ | ||
263 | } \ | ||
264 | (t)->t_res_arr[(t)->t_res_num].r_len = (len); \ | ||
265 | (t)->t_res_arr[(t)->t_res_num].r_type = (type); \ | ||
266 | (t)->t_res_arr_sum += (len); \ | ||
267 | (t)->t_res_num++; \ | ||
268 | } while (0) | ||
269 | 252 | ||
270 | /* | 253 | /* |
271 | * Reservation region | 254 | * Reservation region |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 8ae6e8e5f3db..851eca8a7150 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -2245,7 +2245,7 @@ xlog_recover_do_inode_trans( | |||
2245 | int error; | 2245 | int error; |
2246 | int attr_index; | 2246 | int attr_index; |
2247 | uint fields; | 2247 | uint fields; |
2248 | xfs_dinode_core_t *dicp; | 2248 | xfs_icdinode_t *dicp; |
2249 | int need_free = 0; | 2249 | int need_free = 0; |
2250 | 2250 | ||
2251 | if (pass == XLOG_RECOVER_PASS1) { | 2251 | if (pass == XLOG_RECOVER_PASS1) { |
@@ -2309,7 +2309,7 @@ xlog_recover_do_inode_trans( | |||
2309 | * Make sure the place we're flushing out to really looks | 2309 | * Make sure the place we're flushing out to really looks |
2310 | * like an inode! | 2310 | * like an inode! |
2311 | */ | 2311 | */ |
2312 | if (unlikely(INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC)) { | 2312 | if (unlikely(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC)) { |
2313 | xfs_buf_relse(bp); | 2313 | xfs_buf_relse(bp); |
2314 | xfs_fs_cmn_err(CE_ALERT, mp, | 2314 | xfs_fs_cmn_err(CE_ALERT, mp, |
2315 | "xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld", | 2315 | "xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld", |
@@ -2319,7 +2319,7 @@ xlog_recover_do_inode_trans( | |||
2319 | error = EFSCORRUPTED; | 2319 | error = EFSCORRUPTED; |
2320 | goto error; | 2320 | goto error; |
2321 | } | 2321 | } |
2322 | dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr); | 2322 | dicp = (xfs_icdinode_t *)(item->ri_buf[1].i_addr); |
2323 | if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { | 2323 | if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { |
2324 | xfs_buf_relse(bp); | 2324 | xfs_buf_relse(bp); |
2325 | xfs_fs_cmn_err(CE_ALERT, mp, | 2325 | xfs_fs_cmn_err(CE_ALERT, mp, |
@@ -2332,15 +2332,13 @@ xlog_recover_do_inode_trans( | |||
2332 | } | 2332 | } |
2333 | 2333 | ||
2334 | /* Skip replay when the on disk inode is newer than the log one */ | 2334 | /* Skip replay when the on disk inode is newer than the log one */ |
2335 | if (dicp->di_flushiter < | 2335 | if (dicp->di_flushiter < be16_to_cpu(dip->di_core.di_flushiter)) { |
2336 | INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT)) { | ||
2337 | /* | 2336 | /* |
2338 | * Deal with the wrap case, DI_MAX_FLUSH is less | 2337 | * Deal with the wrap case, DI_MAX_FLUSH is less |
2339 | * than smaller numbers | 2338 | * than smaller numbers |
2340 | */ | 2339 | */ |
2341 | if ((INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT) | 2340 | if (be16_to_cpu(dip->di_core.di_flushiter) == DI_MAX_FLUSH && |
2342 | == DI_MAX_FLUSH) && | 2341 | dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) { |
2343 | (dicp->di_flushiter < (DI_MAX_FLUSH>>1))) { | ||
2344 | /* do nothing */ | 2342 | /* do nothing */ |
2345 | } else { | 2343 | } else { |
2346 | xfs_buf_relse(bp); | 2344 | xfs_buf_relse(bp); |
@@ -2411,8 +2409,8 @@ xlog_recover_do_inode_trans( | |||
2411 | } | 2409 | } |
2412 | 2410 | ||
2413 | /* The core is in in-core format */ | 2411 | /* The core is in in-core format */ |
2414 | xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core, | 2412 | xfs_dinode_to_disk(&dip->di_core, |
2415 | (xfs_dinode_core_t*)item->ri_buf[1].i_addr, -1); | 2413 | (xfs_icdinode_t *)item->ri_buf[1].i_addr); |
2416 | 2414 | ||
2417 | /* the rest is in on-disk format */ | 2415 | /* the rest is in on-disk format */ |
2418 | if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) { | 2416 | if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) { |
@@ -2424,8 +2422,7 @@ xlog_recover_do_inode_trans( | |||
2424 | fields = in_f->ilf_fields; | 2422 | fields = in_f->ilf_fields; |
2425 | switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) { | 2423 | switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) { |
2426 | case XFS_ILOG_DEV: | 2424 | case XFS_ILOG_DEV: |
2427 | INT_SET(dip->di_u.di_dev, ARCH_CONVERT, in_f->ilf_u.ilfu_rdev); | 2425 | dip->di_u.di_dev = cpu_to_be32(in_f->ilf_u.ilfu_rdev); |
2428 | |||
2429 | break; | 2426 | break; |
2430 | case XFS_ILOG_UUID: | 2427 | case XFS_ILOG_UUID: |
2431 | dip->di_u.di_muuid = in_f->ilf_u.ilfu_uuid; | 2428 | dip->di_u.di_muuid = in_f->ilf_u.ilfu_uuid; |
@@ -3234,8 +3231,8 @@ xlog_recover_process_iunlinks( | |||
3234 | ASSERT(ip->i_d.di_nlink == 0); | 3231 | ASSERT(ip->i_d.di_nlink == 0); |
3235 | 3232 | ||
3236 | /* setup for the next pass */ | 3233 | /* setup for the next pass */ |
3237 | agino = INT_GET(dip->di_next_unlinked, | 3234 | agino = be32_to_cpu( |
3238 | ARCH_CONVERT); | 3235 | dip->di_next_unlinked); |
3239 | xfs_buf_relse(ibp); | 3236 | xfs_buf_relse(ibp); |
3240 | /* | 3237 | /* |
3241 | * Prevent any DMAPI event from | 3238 | * Prevent any DMAPI event from |
@@ -3837,7 +3834,10 @@ xlog_do_recover( | |||
3837 | */ | 3834 | */ |
3838 | bp = xfs_getsb(log->l_mp, 0); | 3835 | bp = xfs_getsb(log->l_mp, 0); |
3839 | XFS_BUF_UNDONE(bp); | 3836 | XFS_BUF_UNDONE(bp); |
3837 | ASSERT(!(XFS_BUF_ISWRITE(bp))); | ||
3838 | ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); | ||
3840 | XFS_BUF_READ(bp); | 3839 | XFS_BUF_READ(bp); |
3840 | XFS_BUF_UNASYNC(bp); | ||
3841 | xfsbdstrat(log->l_mp, bp); | 3841 | xfsbdstrat(log->l_mp, bp); |
3842 | if ((error = xfs_iowait(bp))) { | 3842 | if ((error = xfs_iowait(bp))) { |
3843 | xfs_ioerror_alert("xlog_do_recover", | 3843 | xfs_ioerror_alert("xlog_do_recover", |
@@ -3849,7 +3849,7 @@ xlog_do_recover( | |||
3849 | 3849 | ||
3850 | /* Convert superblock from on-disk format */ | 3850 | /* Convert superblock from on-disk format */ |
3851 | sbp = &log->l_mp->m_sb; | 3851 | sbp = &log->l_mp->m_sb; |
3852 | xfs_xlatesb(XFS_BUF_TO_SBP(bp), sbp, 1, XFS_SB_ALL_BITS); | 3852 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp)); |
3853 | ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC); | 3853 | ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC); |
3854 | ASSERT(XFS_SB_GOOD_VERSION(sbp)); | 3854 | ASSERT(XFS_SB_GOOD_VERSION(sbp)); |
3855 | xfs_buf_relse(bp); | 3855 | xfs_buf_relse(bp); |
@@ -4027,7 +4027,7 @@ xlog_recover_check_summary( | |||
4027 | sbbp = xfs_getsb(mp, 0); | 4027 | sbbp = xfs_getsb(mp, 0); |
4028 | #ifdef XFS_LOUD_RECOVERY | 4028 | #ifdef XFS_LOUD_RECOVERY |
4029 | sbp = &mp->m_sb; | 4029 | sbp = &mp->m_sb; |
4030 | xfs_xlatesb(XFS_BUF_TO_SBP(sbbp), sbp, 1, XFS_SB_ALL_BITS); | 4030 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(sbbp)); |
4031 | cmn_err(CE_NOTE, | 4031 | cmn_err(CE_NOTE, |
4032 | "xlog_recover_check_summary: sb_icount %Lu itotal %Lu", | 4032 | "xlog_recover_check_summary: sb_icount %Lu itotal %Lu", |
4033 | sbp->sb_icount, itotal); | 4033 | sbp->sb_icount, itotal); |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index a66b39805176..ebdb76da527c 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -139,7 +139,7 @@ xfs_mount_init(void) | |||
139 | AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail"); | 139 | AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail"); |
140 | spinlock_init(&mp->m_sb_lock, "xfs_sb"); | 140 | spinlock_init(&mp->m_sb_lock, "xfs_sb"); |
141 | mutex_init(&mp->m_ilock); | 141 | mutex_init(&mp->m_ilock); |
142 | initnsema(&mp->m_growlock, 1, "xfs_grow"); | 142 | mutex_init(&mp->m_growlock); |
143 | /* | 143 | /* |
144 | * Initialize the AIL. | 144 | * Initialize the AIL. |
145 | */ | 145 | */ |
@@ -157,14 +157,8 @@ xfs_mount_init(void) | |||
157 | */ | 157 | */ |
158 | void | 158 | void |
159 | xfs_mount_free( | 159 | xfs_mount_free( |
160 | xfs_mount_t *mp, | 160 | xfs_mount_t *mp) |
161 | int remove_bhv) | ||
162 | { | 161 | { |
163 | if (mp->m_ihash) | ||
164 | xfs_ihash_free(mp); | ||
165 | if (mp->m_chash) | ||
166 | xfs_chash_free(mp); | ||
167 | |||
168 | if (mp->m_perag) { | 162 | if (mp->m_perag) { |
169 | int agno; | 163 | int agno; |
170 | 164 | ||
@@ -180,7 +174,7 @@ xfs_mount_free( | |||
180 | AIL_LOCK_DESTROY(&mp->m_ail_lock); | 174 | AIL_LOCK_DESTROY(&mp->m_ail_lock); |
181 | spinlock_destroy(&mp->m_sb_lock); | 175 | spinlock_destroy(&mp->m_sb_lock); |
182 | mutex_destroy(&mp->m_ilock); | 176 | mutex_destroy(&mp->m_ilock); |
183 | freesema(&mp->m_growlock); | 177 | mutex_destroy(&mp->m_growlock); |
184 | if (mp->m_quotainfo) | 178 | if (mp->m_quotainfo) |
185 | XFS_QM_DONE(mp); | 179 | XFS_QM_DONE(mp); |
186 | 180 | ||
@@ -191,15 +185,7 @@ xfs_mount_free( | |||
191 | if (mp->m_logname != NULL) | 185 | if (mp->m_logname != NULL) |
192 | kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); | 186 | kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); |
193 | 187 | ||
194 | if (remove_bhv) { | ||
195 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); | ||
196 | |||
197 | bhv_remove_all_vfsops(vfsp, 0); | ||
198 | VFS_REMOVEBHV(vfsp, &mp->m_bhv); | ||
199 | } | ||
200 | |||
201 | xfs_icsb_destroy_counters(mp); | 188 | xfs_icsb_destroy_counters(mp); |
202 | kmem_free(mp, sizeof(xfs_mount_t)); | ||
203 | } | 189 | } |
204 | 190 | ||
205 | /* | 191 | /* |
@@ -342,9 +328,19 @@ xfs_mount_validate_sb( | |||
342 | return 0; | 328 | return 0; |
343 | } | 329 | } |
344 | 330 | ||
331 | STATIC void | ||
332 | xfs_initialize_perag_icache( | ||
333 | xfs_perag_t *pag) | ||
334 | { | ||
335 | if (!pag->pag_ici_init) { | ||
336 | rwlock_init(&pag->pag_ici_lock); | ||
337 | INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); | ||
338 | pag->pag_ici_init = 1; | ||
339 | } | ||
340 | } | ||
341 | |||
345 | xfs_agnumber_t | 342 | xfs_agnumber_t |
346 | xfs_initialize_perag( | 343 | xfs_initialize_perag( |
347 | bhv_vfs_t *vfs, | ||
348 | xfs_mount_t *mp, | 344 | xfs_mount_t *mp, |
349 | xfs_agnumber_t agcount) | 345 | xfs_agnumber_t agcount) |
350 | { | 346 | { |
@@ -362,7 +358,7 @@ xfs_initialize_perag( | |||
362 | /* Clear the mount flag if no inode can overflow 32 bits | 358 | /* Clear the mount flag if no inode can overflow 32 bits |
363 | * on this filesystem, or if specifically requested.. | 359 | * on this filesystem, or if specifically requested.. |
364 | */ | 360 | */ |
365 | if ((vfs->vfs_flag & VFS_32BITINODES) && ino > max_inum) { | 361 | if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) { |
366 | mp->m_flags |= XFS_MOUNT_32BITINODES; | 362 | mp->m_flags |= XFS_MOUNT_32BITINODES; |
367 | } else { | 363 | } else { |
368 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; | 364 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; |
@@ -396,48 +392,92 @@ xfs_initialize_perag( | |||
396 | pag->pagi_inodeok = 1; | 392 | pag->pagi_inodeok = 1; |
397 | if (index < max_metadata) | 393 | if (index < max_metadata) |
398 | pag->pagf_metadata = 1; | 394 | pag->pagf_metadata = 1; |
395 | xfs_initialize_perag_icache(pag); | ||
399 | } | 396 | } |
400 | } else { | 397 | } else { |
401 | /* Setup default behavior for smaller filesystems */ | 398 | /* Setup default behavior for smaller filesystems */ |
402 | for (index = 0; index < agcount; index++) { | 399 | for (index = 0; index < agcount; index++) { |
403 | pag = &mp->m_perag[index]; | 400 | pag = &mp->m_perag[index]; |
404 | pag->pagi_inodeok = 1; | 401 | pag->pagi_inodeok = 1; |
402 | xfs_initialize_perag_icache(pag); | ||
405 | } | 403 | } |
406 | } | 404 | } |
407 | return index; | 405 | return index; |
408 | } | 406 | } |
409 | 407 | ||
408 | void | ||
409 | xfs_sb_from_disk( | ||
410 | xfs_sb_t *to, | ||
411 | xfs_dsb_t *from) | ||
412 | { | ||
413 | to->sb_magicnum = be32_to_cpu(from->sb_magicnum); | ||
414 | to->sb_blocksize = be32_to_cpu(from->sb_blocksize); | ||
415 | to->sb_dblocks = be64_to_cpu(from->sb_dblocks); | ||
416 | to->sb_rblocks = be64_to_cpu(from->sb_rblocks); | ||
417 | to->sb_rextents = be64_to_cpu(from->sb_rextents); | ||
418 | memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid)); | ||
419 | to->sb_logstart = be64_to_cpu(from->sb_logstart); | ||
420 | to->sb_rootino = be64_to_cpu(from->sb_rootino); | ||
421 | to->sb_rbmino = be64_to_cpu(from->sb_rbmino); | ||
422 | to->sb_rsumino = be64_to_cpu(from->sb_rsumino); | ||
423 | to->sb_rextsize = be32_to_cpu(from->sb_rextsize); | ||
424 | to->sb_agblocks = be32_to_cpu(from->sb_agblocks); | ||
425 | to->sb_agcount = be32_to_cpu(from->sb_agcount); | ||
426 | to->sb_rbmblocks = be32_to_cpu(from->sb_rbmblocks); | ||
427 | to->sb_logblocks = be32_to_cpu(from->sb_logblocks); | ||
428 | to->sb_versionnum = be16_to_cpu(from->sb_versionnum); | ||
429 | to->sb_sectsize = be16_to_cpu(from->sb_sectsize); | ||
430 | to->sb_inodesize = be16_to_cpu(from->sb_inodesize); | ||
431 | to->sb_inopblock = be16_to_cpu(from->sb_inopblock); | ||
432 | memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname)); | ||
433 | to->sb_blocklog = from->sb_blocklog; | ||
434 | to->sb_sectlog = from->sb_sectlog; | ||
435 | to->sb_inodelog = from->sb_inodelog; | ||
436 | to->sb_inopblog = from->sb_inopblog; | ||
437 | to->sb_agblklog = from->sb_agblklog; | ||
438 | to->sb_rextslog = from->sb_rextslog; | ||
439 | to->sb_inprogress = from->sb_inprogress; | ||
440 | to->sb_imax_pct = from->sb_imax_pct; | ||
441 | to->sb_icount = be64_to_cpu(from->sb_icount); | ||
442 | to->sb_ifree = be64_to_cpu(from->sb_ifree); | ||
443 | to->sb_fdblocks = be64_to_cpu(from->sb_fdblocks); | ||
444 | to->sb_frextents = be64_to_cpu(from->sb_frextents); | ||
445 | to->sb_uquotino = be64_to_cpu(from->sb_uquotino); | ||
446 | to->sb_gquotino = be64_to_cpu(from->sb_gquotino); | ||
447 | to->sb_qflags = be16_to_cpu(from->sb_qflags); | ||
448 | to->sb_flags = from->sb_flags; | ||
449 | to->sb_shared_vn = from->sb_shared_vn; | ||
450 | to->sb_inoalignmt = be32_to_cpu(from->sb_inoalignmt); | ||
451 | to->sb_unit = be32_to_cpu(from->sb_unit); | ||
452 | to->sb_width = be32_to_cpu(from->sb_width); | ||
453 | to->sb_dirblklog = from->sb_dirblklog; | ||
454 | to->sb_logsectlog = from->sb_logsectlog; | ||
455 | to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); | ||
456 | to->sb_logsunit = be32_to_cpu(from->sb_logsunit); | ||
457 | to->sb_features2 = be32_to_cpu(from->sb_features2); | ||
458 | } | ||
459 | |||
410 | /* | 460 | /* |
411 | * xfs_xlatesb | 461 | * Copy in core superblock to ondisk one. |
412 | * | 462 | * |
413 | * data - on disk version of sb | 463 | * The fields argument is mask of superblock fields to copy. |
414 | * sb - a superblock | ||
415 | * dir - conversion direction: <0 - convert sb to buf | ||
416 | * >0 - convert buf to sb | ||
417 | * fields - which fields to copy (bitmask) | ||
418 | */ | 464 | */ |
419 | void | 465 | void |
420 | xfs_xlatesb( | 466 | xfs_sb_to_disk( |
421 | void *data, | 467 | xfs_dsb_t *to, |
422 | xfs_sb_t *sb, | 468 | xfs_sb_t *from, |
423 | int dir, | ||
424 | __int64_t fields) | 469 | __int64_t fields) |
425 | { | 470 | { |
426 | xfs_caddr_t buf_ptr; | 471 | xfs_caddr_t to_ptr = (xfs_caddr_t)to; |
427 | xfs_caddr_t mem_ptr; | 472 | xfs_caddr_t from_ptr = (xfs_caddr_t)from; |
428 | xfs_sb_field_t f; | 473 | xfs_sb_field_t f; |
429 | int first; | 474 | int first; |
430 | int size; | 475 | int size; |
431 | 476 | ||
432 | ASSERT(dir); | ||
433 | ASSERT(fields); | 477 | ASSERT(fields); |
434 | |||
435 | if (!fields) | 478 | if (!fields) |
436 | return; | 479 | return; |
437 | 480 | ||
438 | buf_ptr = (xfs_caddr_t)data; | ||
439 | mem_ptr = (xfs_caddr_t)sb; | ||
440 | |||
441 | while (fields) { | 481 | while (fields) { |
442 | f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); | 482 | f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); |
443 | first = xfs_sb_info[f].offset; | 483 | first = xfs_sb_info[f].offset; |
@@ -446,26 +486,20 @@ xfs_xlatesb( | |||
446 | ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); | 486 | ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); |
447 | 487 | ||
448 | if (size == 1 || xfs_sb_info[f].type == 1) { | 488 | if (size == 1 || xfs_sb_info[f].type == 1) { |
449 | if (dir > 0) { | 489 | memcpy(to_ptr + first, from_ptr + first, size); |
450 | memcpy(mem_ptr + first, buf_ptr + first, size); | ||
451 | } else { | ||
452 | memcpy(buf_ptr + first, mem_ptr + first, size); | ||
453 | } | ||
454 | } else { | 490 | } else { |
455 | switch (size) { | 491 | switch (size) { |
456 | case 2: | 492 | case 2: |
457 | INT_XLATE(*(__uint16_t*)(buf_ptr+first), | 493 | *(__be16 *)(to_ptr + first) = |
458 | *(__uint16_t*)(mem_ptr+first), | 494 | cpu_to_be16(*(__u16 *)(from_ptr + first)); |
459 | dir, ARCH_CONVERT); | ||
460 | break; | 495 | break; |
461 | case 4: | 496 | case 4: |
462 | INT_XLATE(*(__uint32_t*)(buf_ptr+first), | 497 | *(__be32 *)(to_ptr + first) = |
463 | *(__uint32_t*)(mem_ptr+first), | 498 | cpu_to_be32(*(__u32 *)(from_ptr + first)); |
464 | dir, ARCH_CONVERT); | ||
465 | break; | 499 | break; |
466 | case 8: | 500 | case 8: |
467 | INT_XLATE(*(__uint64_t*)(buf_ptr+first), | 501 | *(__be64 *)(to_ptr + first) = |
468 | *(__uint64_t*)(mem_ptr+first), dir, ARCH_CONVERT); | 502 | cpu_to_be64(*(__u64 *)(from_ptr + first)); |
469 | break; | 503 | break; |
470 | default: | 504 | default: |
471 | ASSERT(0); | 505 | ASSERT(0); |
@@ -487,7 +521,6 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
487 | unsigned int sector_size; | 521 | unsigned int sector_size; |
488 | unsigned int extra_flags; | 522 | unsigned int extra_flags; |
489 | xfs_buf_t *bp; | 523 | xfs_buf_t *bp; |
490 | xfs_sb_t *sbp; | ||
491 | int error; | 524 | int error; |
492 | 525 | ||
493 | ASSERT(mp->m_sb_bp == NULL); | 526 | ASSERT(mp->m_sb_bp == NULL); |
@@ -515,8 +548,7 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
515 | * Initialize the mount structure from the superblock. | 548 | * Initialize the mount structure from the superblock. |
516 | * But first do some basic consistency checking. | 549 | * But first do some basic consistency checking. |
517 | */ | 550 | */ |
518 | sbp = XFS_BUF_TO_SBP(bp); | 551 | xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp)); |
519 | xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS); | ||
520 | 552 | ||
521 | error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags); | 553 | error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags); |
522 | if (error) { | 554 | if (error) { |
@@ -715,7 +747,6 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) | |||
715 | */ | 747 | */ |
716 | int | 748 | int |
717 | xfs_mountfs( | 749 | xfs_mountfs( |
718 | bhv_vfs_t *vfsp, | ||
719 | xfs_mount_t *mp, | 750 | xfs_mount_t *mp, |
720 | int mfsi_flags) | 751 | int mfsi_flags) |
721 | { | 752 | { |
@@ -842,14 +873,11 @@ xfs_mountfs( | |||
842 | */ | 873 | */ |
843 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && | 874 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && |
844 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { | 875 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { |
845 | __uint64_t ret64; | ||
846 | if (xfs_uuid_mount(mp)) { | 876 | if (xfs_uuid_mount(mp)) { |
847 | error = XFS_ERROR(EINVAL); | 877 | error = XFS_ERROR(EINVAL); |
848 | goto error1; | 878 | goto error1; |
849 | } | 879 | } |
850 | uuid_mounted=1; | 880 | uuid_mounted=1; |
851 | ret64 = uuid_hash64(&sbp->sb_uuid); | ||
852 | memcpy(&vfsp->vfs_fsid, &ret64, sizeof(ret64)); | ||
853 | } | 881 | } |
854 | 882 | ||
855 | /* | 883 | /* |
@@ -871,16 +899,6 @@ xfs_mountfs( | |||
871 | writeio_log = mp->m_writeio_log; | 899 | writeio_log = mp->m_writeio_log; |
872 | } | 900 | } |
873 | 901 | ||
874 | /* | ||
875 | * Set the number of readahead buffers to use based on | ||
876 | * physical memory size. | ||
877 | */ | ||
878 | if (xfs_physmem <= 4096) /* <= 16MB */ | ||
879 | mp->m_nreadaheads = XFS_RW_NREADAHEAD_16MB; | ||
880 | else if (xfs_physmem <= 8192) /* <= 32MB */ | ||
881 | mp->m_nreadaheads = XFS_RW_NREADAHEAD_32MB; | ||
882 | else | ||
883 | mp->m_nreadaheads = XFS_RW_NREADAHEAD_K32; | ||
884 | if (sbp->sb_blocklog > readio_log) { | 902 | if (sbp->sb_blocklog > readio_log) { |
885 | mp->m_readio_log = sbp->sb_blocklog; | 903 | mp->m_readio_log = sbp->sb_blocklog; |
886 | } else { | 904 | } else { |
@@ -895,15 +913,12 @@ xfs_mountfs( | |||
895 | mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog); | 913 | mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog); |
896 | 914 | ||
897 | /* | 915 | /* |
898 | * Set the inode cluster size based on the physical memory | 916 | * Set the inode cluster size. |
899 | * size. This may still be overridden by the file system | 917 | * This may still be overridden by the file system |
900 | * block size if it is larger than the chosen cluster size. | 918 | * block size if it is larger than the chosen cluster size. |
901 | */ | 919 | */ |
902 | if (xfs_physmem <= btoc(32 * 1024 * 1024)) { /* <= 32 MB */ | 920 | mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; |
903 | mp->m_inode_cluster_size = XFS_INODE_SMALL_CLUSTER_SIZE; | 921 | |
904 | } else { | ||
905 | mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE; | ||
906 | } | ||
907 | /* | 922 | /* |
908 | * Set whether we're using inode alignment. | 923 | * Set whether we're using inode alignment. |
909 | */ | 924 | */ |
@@ -987,16 +1002,6 @@ xfs_mountfs( | |||
987 | */ | 1002 | */ |
988 | uuid_getnodeuniq(&sbp->sb_uuid, mp->m_fixedfsid); | 1003 | uuid_getnodeuniq(&sbp->sb_uuid, mp->m_fixedfsid); |
989 | 1004 | ||
990 | /* | ||
991 | * The vfs structure needs to have a file system independent | ||
992 | * way of checking for the invariant file system ID. Since it | ||
993 | * can't look at mount structures it has a pointer to the data | ||
994 | * in the mount structure. | ||
995 | * | ||
996 | * File systems that don't support user level file handles (i.e. | ||
997 | * all of them except for XFS) will leave vfs_altfsid as NULL. | ||
998 | */ | ||
999 | vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid; | ||
1000 | mp->m_dmevmask = 0; /* not persistent; set after each mount */ | 1005 | mp->m_dmevmask = 0; /* not persistent; set after each mount */ |
1001 | 1006 | ||
1002 | xfs_dir_mount(mp); | 1007 | xfs_dir_mount(mp); |
@@ -1012,20 +1017,13 @@ xfs_mountfs( | |||
1012 | xfs_trans_init(mp); | 1017 | xfs_trans_init(mp); |
1013 | 1018 | ||
1014 | /* | 1019 | /* |
1015 | * Allocate and initialize the inode hash table for this | ||
1016 | * file system. | ||
1017 | */ | ||
1018 | xfs_ihash_init(mp); | ||
1019 | xfs_chash_init(mp); | ||
1020 | |||
1021 | /* | ||
1022 | * Allocate and initialize the per-ag data. | 1020 | * Allocate and initialize the per-ag data. |
1023 | */ | 1021 | */ |
1024 | init_rwsem(&mp->m_peraglock); | 1022 | init_rwsem(&mp->m_peraglock); |
1025 | mp->m_perag = | 1023 | mp->m_perag = |
1026 | kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP); | 1024 | kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t), KM_SLEEP); |
1027 | 1025 | ||
1028 | mp->m_maxagi = xfs_initialize_perag(vfsp, mp, sbp->sb_agcount); | 1026 | mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount); |
1029 | 1027 | ||
1030 | /* | 1028 | /* |
1031 | * log's mount-time initialization. Perform 1st part recovery if needed | 1029 | * log's mount-time initialization. Perform 1st part recovery if needed |
@@ -1116,7 +1114,7 @@ xfs_mountfs( | |||
1116 | * If fs is not mounted readonly, then update the superblock | 1114 | * If fs is not mounted readonly, then update the superblock |
1117 | * unit and width changes. | 1115 | * unit and width changes. |
1118 | */ | 1116 | */ |
1119 | if (update_flags && !(vfsp->vfs_flag & VFS_RDONLY)) | 1117 | if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) |
1120 | xfs_mount_log_sbunit(mp, update_flags); | 1118 | xfs_mount_log_sbunit(mp, update_flags); |
1121 | 1119 | ||
1122 | /* | 1120 | /* |
@@ -1169,8 +1167,6 @@ xfs_mountfs( | |||
1169 | error3: | 1167 | error3: |
1170 | xfs_log_unmount_dealloc(mp); | 1168 | xfs_log_unmount_dealloc(mp); |
1171 | error2: | 1169 | error2: |
1172 | xfs_ihash_free(mp); | ||
1173 | xfs_chash_free(mp); | ||
1174 | for (agno = 0; agno < sbp->sb_agcount; agno++) | 1170 | for (agno = 0; agno < sbp->sb_agcount; agno++) |
1175 | if (mp->m_perag[agno].pagb_list) | 1171 | if (mp->m_perag[agno].pagb_list) |
1176 | kmem_free(mp->m_perag[agno].pagb_list, | 1172 | kmem_free(mp->m_perag[agno].pagb_list, |
@@ -1194,10 +1190,6 @@ xfs_mountfs( | |||
1194 | int | 1190 | int |
1195 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | 1191 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) |
1196 | { | 1192 | { |
1197 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); | ||
1198 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) | ||
1199 | int64_t fsid; | ||
1200 | #endif | ||
1201 | __uint64_t resblks; | 1193 | __uint64_t resblks; |
1202 | 1194 | ||
1203 | /* | 1195 | /* |
@@ -1261,21 +1253,17 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1261 | xfs_uuid_unmount(mp); | 1253 | xfs_uuid_unmount(mp); |
1262 | 1254 | ||
1263 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) | 1255 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) |
1264 | /* | 1256 | xfs_errortag_clearall(mp, 0); |
1265 | * clear all error tags on this filesystem | ||
1266 | */ | ||
1267 | memcpy(&fsid, &vfsp->vfs_fsid, sizeof(int64_t)); | ||
1268 | xfs_errortag_clearall_umount(fsid, mp->m_fsname, 0); | ||
1269 | #endif | 1257 | #endif |
1270 | XFS_IODONE(vfsp); | 1258 | XFS_IODONE(mp); |
1271 | xfs_mount_free(mp, 1); | 1259 | xfs_mount_free(mp); |
1272 | return 0; | 1260 | return 0; |
1273 | } | 1261 | } |
1274 | 1262 | ||
1275 | void | 1263 | void |
1276 | xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr) | 1264 | xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr) |
1277 | { | 1265 | { |
1278 | if (mp->m_logdev_targp != mp->m_ddev_targp) | 1266 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) |
1279 | xfs_free_buftarg(mp->m_logdev_targp, 1); | 1267 | xfs_free_buftarg(mp->m_logdev_targp, 1); |
1280 | if (mp->m_rtdev_targp) | 1268 | if (mp->m_rtdev_targp) |
1281 | xfs_free_buftarg(mp->m_rtdev_targp, 1); | 1269 | xfs_free_buftarg(mp->m_rtdev_targp, 1); |
@@ -1295,10 +1283,8 @@ xfs_unmountfs_wait(xfs_mount_t *mp) | |||
1295 | int | 1283 | int |
1296 | xfs_fs_writable(xfs_mount_t *mp) | 1284 | xfs_fs_writable(xfs_mount_t *mp) |
1297 | { | 1285 | { |
1298 | bhv_vfs_t *vfsp = XFS_MTOVFS(mp); | 1286 | return !(xfs_test_for_freeze(mp) || XFS_FORCED_SHUTDOWN(mp) || |
1299 | 1287 | (mp->m_flags & XFS_MOUNT_RDONLY)); | |
1300 | return !(vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) || | ||
1301 | (vfsp->vfs_flag & VFS_RDONLY)); | ||
1302 | } | 1288 | } |
1303 | 1289 | ||
1304 | /* | 1290 | /* |
@@ -1348,34 +1334,44 @@ xfs_log_sbcount( | |||
1348 | return 0; | 1334 | return 0; |
1349 | } | 1335 | } |
1350 | 1336 | ||
1337 | STATIC void | ||
1338 | xfs_mark_shared_ro( | ||
1339 | xfs_mount_t *mp, | ||
1340 | xfs_buf_t *bp) | ||
1341 | { | ||
1342 | xfs_dsb_t *sb = XFS_BUF_TO_SBP(bp); | ||
1343 | __uint16_t version; | ||
1344 | |||
1345 | if (!(sb->sb_flags & XFS_SBF_READONLY)) | ||
1346 | sb->sb_flags |= XFS_SBF_READONLY; | ||
1347 | |||
1348 | version = be16_to_cpu(sb->sb_versionnum); | ||
1349 | if ((version & XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4 || | ||
1350 | !(version & XFS_SB_VERSION_SHAREDBIT)) | ||
1351 | version |= XFS_SB_VERSION_SHAREDBIT; | ||
1352 | sb->sb_versionnum = cpu_to_be16(version); | ||
1353 | } | ||
1354 | |||
1351 | int | 1355 | int |
1352 | xfs_unmountfs_writesb(xfs_mount_t *mp) | 1356 | xfs_unmountfs_writesb(xfs_mount_t *mp) |
1353 | { | 1357 | { |
1354 | xfs_buf_t *sbp; | 1358 | xfs_buf_t *sbp; |
1355 | xfs_sb_t *sb; | ||
1356 | int error = 0; | 1359 | int error = 0; |
1357 | 1360 | ||
1358 | /* | 1361 | /* |
1359 | * skip superblock write if fs is read-only, or | 1362 | * skip superblock write if fs is read-only, or |
1360 | * if we are doing a forced umount. | 1363 | * if we are doing a forced umount. |
1361 | */ | 1364 | */ |
1362 | if (!(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY || | 1365 | if (!((mp->m_flags & XFS_MOUNT_RDONLY) || |
1363 | XFS_FORCED_SHUTDOWN(mp))) { | 1366 | XFS_FORCED_SHUTDOWN(mp))) { |
1364 | 1367 | ||
1365 | sbp = xfs_getsb(mp, 0); | 1368 | sbp = xfs_getsb(mp, 0); |
1366 | sb = XFS_BUF_TO_SBP(sbp); | ||
1367 | 1369 | ||
1368 | /* | 1370 | /* |
1369 | * mark shared-readonly if desired | 1371 | * mark shared-readonly if desired |
1370 | */ | 1372 | */ |
1371 | if (mp->m_mk_sharedro) { | 1373 | if (mp->m_mk_sharedro) |
1372 | if (!(sb->sb_flags & XFS_SBF_READONLY)) | 1374 | xfs_mark_shared_ro(mp, sbp); |
1373 | sb->sb_flags |= XFS_SBF_READONLY; | ||
1374 | if (!XFS_SB_VERSION_HASSHARED(sb)) | ||
1375 | XFS_SB_VERSION_ADDSHARED(sb); | ||
1376 | xfs_fs_cmn_err(CE_NOTE, mp, | ||
1377 | "Unmounting, marking shared read-only"); | ||
1378 | } | ||
1379 | 1375 | ||
1380 | XFS_BUF_UNDONE(sbp); | 1376 | XFS_BUF_UNDONE(sbp); |
1381 | XFS_BUF_UNREAD(sbp); | 1377 | XFS_BUF_UNREAD(sbp); |
@@ -1410,7 +1406,6 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) | |||
1410 | int first; | 1406 | int first; |
1411 | int last; | 1407 | int last; |
1412 | xfs_mount_t *mp; | 1408 | xfs_mount_t *mp; |
1413 | xfs_sb_t *sbp; | ||
1414 | xfs_sb_field_t f; | 1409 | xfs_sb_field_t f; |
1415 | 1410 | ||
1416 | ASSERT(fields); | 1411 | ASSERT(fields); |
@@ -1418,13 +1413,12 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) | |||
1418 | return; | 1413 | return; |
1419 | mp = tp->t_mountp; | 1414 | mp = tp->t_mountp; |
1420 | bp = xfs_trans_getsb(tp, mp, 0); | 1415 | bp = xfs_trans_getsb(tp, mp, 0); |
1421 | sbp = XFS_BUF_TO_SBP(bp); | ||
1422 | first = sizeof(xfs_sb_t); | 1416 | first = sizeof(xfs_sb_t); |
1423 | last = 0; | 1417 | last = 0; |
1424 | 1418 | ||
1425 | /* translate/copy */ | 1419 | /* translate/copy */ |
1426 | 1420 | ||
1427 | xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), -1, fields); | 1421 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); |
1428 | 1422 | ||
1429 | /* find modified range */ | 1423 | /* find modified range */ |
1430 | 1424 | ||
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 76ad74758696..c618f7cb5f0e 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -54,13 +54,8 @@ typedef struct xfs_trans_reservations { | |||
54 | #else | 54 | #else |
55 | struct cred; | 55 | struct cred; |
56 | struct log; | 56 | struct log; |
57 | struct bhv_vfs; | ||
58 | struct bhv_vnode; | ||
59 | struct xfs_mount_args; | 57 | struct xfs_mount_args; |
60 | struct xfs_ihash; | ||
61 | struct xfs_chash; | ||
62 | struct xfs_inode; | 58 | struct xfs_inode; |
63 | struct xfs_perag; | ||
64 | struct xfs_iocore; | 59 | struct xfs_iocore; |
65 | struct xfs_bmbt_irec; | 60 | struct xfs_bmbt_irec; |
66 | struct xfs_bmap_free; | 61 | struct xfs_bmap_free; |
@@ -68,9 +63,6 @@ struct xfs_extdelta; | |||
68 | struct xfs_swapext; | 63 | struct xfs_swapext; |
69 | struct xfs_mru_cache; | 64 | struct xfs_mru_cache; |
70 | 65 | ||
71 | extern struct bhv_vfsops xfs_vfsops; | ||
72 | extern struct bhv_vnodeops xfs_vnodeops; | ||
73 | |||
74 | #define AIL_LOCK_T lock_t | 66 | #define AIL_LOCK_T lock_t |
75 | #define AIL_LOCKINIT(x,y) spinlock_init(x,y) | 67 | #define AIL_LOCKINIT(x,y) spinlock_init(x,y) |
76 | #define AIL_LOCK_DESTROY(x) spinlock_destroy(x) | 68 | #define AIL_LOCK_DESTROY(x) spinlock_destroy(x) |
@@ -82,15 +74,17 @@ extern struct bhv_vnodeops xfs_vnodeops; | |||
82 | * Prototypes and functions for the Data Migration subsystem. | 74 | * Prototypes and functions for the Data Migration subsystem. |
83 | */ | 75 | */ |
84 | 76 | ||
85 | typedef int (*xfs_send_data_t)(int, struct bhv_vnode *, | 77 | typedef int (*xfs_send_data_t)(int, bhv_vnode_t *, |
86 | xfs_off_t, size_t, int, bhv_vrwlock_t *); | 78 | xfs_off_t, size_t, int, bhv_vrwlock_t *); |
87 | typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); | 79 | typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); |
88 | typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t); | 80 | typedef int (*xfs_send_destroy_t)(bhv_vnode_t *, dm_right_t); |
89 | typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *, | 81 | typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct xfs_mount *, |
90 | struct bhv_vnode *, | 82 | bhv_vnode_t *, |
91 | dm_right_t, struct bhv_vnode *, dm_right_t, | 83 | dm_right_t, bhv_vnode_t *, dm_right_t, |
92 | char *, char *, mode_t, int, int); | 84 | char *, char *, mode_t, int, int); |
93 | typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, struct bhv_vnode *, | 85 | typedef int (*xfs_send_mount_t)(struct xfs_mount *, dm_right_t, |
86 | char *, char *); | ||
87 | typedef void (*xfs_send_unmount_t)(struct xfs_mount *, bhv_vnode_t *, | ||
94 | dm_right_t, mode_t, int, int); | 88 | dm_right_t, mode_t, int, int); |
95 | 89 | ||
96 | typedef struct xfs_dmops { | 90 | typedef struct xfs_dmops { |
@@ -98,21 +92,24 @@ typedef struct xfs_dmops { | |||
98 | xfs_send_mmap_t xfs_send_mmap; | 92 | xfs_send_mmap_t xfs_send_mmap; |
99 | xfs_send_destroy_t xfs_send_destroy; | 93 | xfs_send_destroy_t xfs_send_destroy; |
100 | xfs_send_namesp_t xfs_send_namesp; | 94 | xfs_send_namesp_t xfs_send_namesp; |
95 | xfs_send_mount_t xfs_send_mount; | ||
101 | xfs_send_unmount_t xfs_send_unmount; | 96 | xfs_send_unmount_t xfs_send_unmount; |
102 | } xfs_dmops_t; | 97 | } xfs_dmops_t; |
103 | 98 | ||
104 | #define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \ | 99 | #define XFS_SEND_DATA(mp, ev,vp,off,len,fl,lock) \ |
105 | (*(mp)->m_dm_ops.xfs_send_data)(ev,vp,off,len,fl,lock) | 100 | (*(mp)->m_dm_ops->xfs_send_data)(ev,vp,off,len,fl,lock) |
106 | #define XFS_SEND_MMAP(mp, vma,fl) \ | 101 | #define XFS_SEND_MMAP(mp, vma,fl) \ |
107 | (*(mp)->m_dm_ops.xfs_send_mmap)(vma,fl) | 102 | (*(mp)->m_dm_ops->xfs_send_mmap)(vma,fl) |
108 | #define XFS_SEND_DESTROY(mp, vp,right) \ | 103 | #define XFS_SEND_DESTROY(mp, vp,right) \ |
109 | (*(mp)->m_dm_ops.xfs_send_destroy)(vp,right) | 104 | (*(mp)->m_dm_ops->xfs_send_destroy)(vp,right) |
110 | #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ | 105 | #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ |
111 | (*(mp)->m_dm_ops.xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) | 106 | (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) |
112 | #define XFS_SEND_PREUNMOUNT(mp, vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ | 107 | #define XFS_SEND_PREUNMOUNT(mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ |
113 | (*(mp)->m_dm_ops.xfs_send_namesp)(DM_EVENT_PREUNMOUNT,vfs,b1,r1,b2,r2,n1,n2,mode,rval,fl) | 108 | (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT,mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) |
114 | #define XFS_SEND_UNMOUNT(mp, vfsp,vp,right,mode,rval,fl) \ | 109 | #define XFS_SEND_MOUNT(mp,right,path,name) \ |
115 | (*(mp)->m_dm_ops.xfs_send_unmount)(vfsp,vp,right,mode,rval,fl) | 110 | (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name) |
111 | #define XFS_SEND_UNMOUNT(mp, vp,right,mode,rval,fl) \ | ||
112 | (*(mp)->m_dm_ops->xfs_send_unmount)(mp,vp,right,mode,rval,fl) | ||
116 | 113 | ||
117 | 114 | ||
118 | /* | 115 | /* |
@@ -142,6 +139,9 @@ typedef struct xfs_dquot * (*xfs_dqvopchown_t)( | |||
142 | struct xfs_dquot **, struct xfs_dquot *); | 139 | struct xfs_dquot **, struct xfs_dquot *); |
143 | typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *, | 140 | typedef int (*xfs_dqvopchownresv_t)(struct xfs_trans *, struct xfs_inode *, |
144 | struct xfs_dquot *, struct xfs_dquot *, uint); | 141 | struct xfs_dquot *, struct xfs_dquot *, uint); |
142 | typedef void (*xfs_dqstatvfs_t)(struct xfs_inode *, bhv_statvfs_t *); | ||
143 | typedef int (*xfs_dqsync_t)(struct xfs_mount *, int flags); | ||
144 | typedef int (*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t); | ||
145 | 145 | ||
146 | typedef struct xfs_qmops { | 146 | typedef struct xfs_qmops { |
147 | xfs_qminit_t xfs_qminit; | 147 | xfs_qminit_t xfs_qminit; |
@@ -157,42 +157,51 @@ typedef struct xfs_qmops { | |||
157 | xfs_dqvoprename_t xfs_dqvoprename; | 157 | xfs_dqvoprename_t xfs_dqvoprename; |
158 | xfs_dqvopchown_t xfs_dqvopchown; | 158 | xfs_dqvopchown_t xfs_dqvopchown; |
159 | xfs_dqvopchownresv_t xfs_dqvopchownresv; | 159 | xfs_dqvopchownresv_t xfs_dqvopchownresv; |
160 | xfs_dqstatvfs_t xfs_dqstatvfs; | ||
161 | xfs_dqsync_t xfs_dqsync; | ||
162 | xfs_quotactl_t xfs_quotactl; | ||
160 | struct xfs_dqtrxops *xfs_dqtrxops; | 163 | struct xfs_dqtrxops *xfs_dqtrxops; |
161 | } xfs_qmops_t; | 164 | } xfs_qmops_t; |
162 | 165 | ||
163 | #define XFS_QM_INIT(mp, mnt, fl) \ | 166 | #define XFS_QM_INIT(mp, mnt, fl) \ |
164 | (*(mp)->m_qm_ops.xfs_qminit)(mp, mnt, fl) | 167 | (*(mp)->m_qm_ops->xfs_qminit)(mp, mnt, fl) |
165 | #define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \ | 168 | #define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \ |
166 | (*(mp)->m_qm_ops.xfs_qmmount)(mp, mnt, fl, mfsi_flags) | 169 | (*(mp)->m_qm_ops->xfs_qmmount)(mp, mnt, fl, mfsi_flags) |
167 | #define XFS_QM_UNMOUNT(mp) \ | 170 | #define XFS_QM_UNMOUNT(mp) \ |
168 | (*(mp)->m_qm_ops.xfs_qmunmount)(mp) | 171 | (*(mp)->m_qm_ops->xfs_qmunmount)(mp) |
169 | #define XFS_QM_DONE(mp) \ | 172 | #define XFS_QM_DONE(mp) \ |
170 | (*(mp)->m_qm_ops.xfs_qmdone)(mp) | 173 | (*(mp)->m_qm_ops->xfs_qmdone)(mp) |
171 | #define XFS_QM_DQRELE(mp, dq) \ | 174 | #define XFS_QM_DQRELE(mp, dq) \ |
172 | (*(mp)->m_qm_ops.xfs_dqrele)(dq) | 175 | (*(mp)->m_qm_ops->xfs_dqrele)(dq) |
173 | #define XFS_QM_DQATTACH(mp, ip, fl) \ | 176 | #define XFS_QM_DQATTACH(mp, ip, fl) \ |
174 | (*(mp)->m_qm_ops.xfs_dqattach)(ip, fl) | 177 | (*(mp)->m_qm_ops->xfs_dqattach)(ip, fl) |
175 | #define XFS_QM_DQDETACH(mp, ip) \ | 178 | #define XFS_QM_DQDETACH(mp, ip) \ |
176 | (*(mp)->m_qm_ops.xfs_dqdetach)(ip) | 179 | (*(mp)->m_qm_ops->xfs_dqdetach)(ip) |
177 | #define XFS_QM_DQPURGEALL(mp, fl) \ | 180 | #define XFS_QM_DQPURGEALL(mp, fl) \ |
178 | (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) | 181 | (*(mp)->m_qm_ops->xfs_dqpurgeall)(mp, fl) |
179 | #define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \ | 182 | #define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \ |
180 | (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) | 183 | (*(mp)->m_qm_ops->xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2) |
181 | #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ | 184 | #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ |
182 | (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) | 185 | (*(mp)->m_qm_ops->xfs_dqvopcreate)(tp, ip, dq1, dq2) |
183 | #define XFS_QM_DQVOPRENAME(mp, ip) \ | 186 | #define XFS_QM_DQVOPRENAME(mp, ip) \ |
184 | (*(mp)->m_qm_ops.xfs_dqvoprename)(ip) | 187 | (*(mp)->m_qm_ops->xfs_dqvoprename)(ip) |
185 | #define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \ | 188 | #define XFS_QM_DQVOPCHOWN(mp, tp, ip, dqp, dq) \ |
186 | (*(mp)->m_qm_ops.xfs_dqvopchown)(tp, ip, dqp, dq) | 189 | (*(mp)->m_qm_ops->xfs_dqvopchown)(tp, ip, dqp, dq) |
187 | #define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \ | 190 | #define XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, dq1, dq2, fl) \ |
188 | (*(mp)->m_qm_ops.xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl) | 191 | (*(mp)->m_qm_ops->xfs_dqvopchownresv)(tp, ip, dq1, dq2, fl) |
192 | #define XFS_QM_DQSTATVFS(ip, statp) \ | ||
193 | (*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp) | ||
194 | #define XFS_QM_DQSYNC(mp, flags) \ | ||
195 | (*(mp)->m_qm_ops->xfs_dqsync)(mp, flags) | ||
196 | #define XFS_QM_QUOTACTL(mp, cmd, id, addr) \ | ||
197 | (*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr) | ||
189 | 198 | ||
190 | 199 | ||
191 | /* | 200 | /* |
192 | * Prototypes and functions for I/O core modularization. | 201 | * Prototypes and functions for I/O core modularization. |
193 | */ | 202 | */ |
194 | 203 | ||
195 | typedef int (*xfs_ioinit_t)(struct bhv_vfs *, | 204 | typedef int (*xfs_ioinit_t)(struct xfs_mount *, |
196 | struct xfs_mount_args *, int); | 205 | struct xfs_mount_args *, int); |
197 | typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, | 206 | typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, |
198 | xfs_fileoff_t, xfs_filblks_t, int, | 207 | xfs_fileoff_t, xfs_filblks_t, int, |
@@ -222,7 +231,7 @@ typedef void (*xfs_lock_demote_t)(void *, uint); | |||
222 | typedef int (*xfs_lock_nowait_t)(void *, uint); | 231 | typedef int (*xfs_lock_nowait_t)(void *, uint); |
223 | typedef void (*xfs_unlk_t)(void *, unsigned int); | 232 | typedef void (*xfs_unlk_t)(void *, unsigned int); |
224 | typedef xfs_fsize_t (*xfs_size_t)(void *); | 233 | typedef xfs_fsize_t (*xfs_size_t)(void *); |
225 | typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *); | 234 | typedef xfs_fsize_t (*xfs_iodone_t)(struct xfs_mount *); |
226 | typedef int (*xfs_swap_extents_t)(void *, void *, | 235 | typedef int (*xfs_swap_extents_t)(void *, void *, |
227 | struct xfs_swapext*); | 236 | struct xfs_swapext*); |
228 | 237 | ||
@@ -245,8 +254,8 @@ typedef struct xfs_ioops { | |||
245 | xfs_swap_extents_t xfs_swap_extents_func; | 254 | xfs_swap_extents_t xfs_swap_extents_func; |
246 | } xfs_ioops_t; | 255 | } xfs_ioops_t; |
247 | 256 | ||
248 | #define XFS_IOINIT(vfsp, args, flags) \ | 257 | #define XFS_IOINIT(mp, args, flags) \ |
249 | (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) | 258 | (*(mp)->m_io_ops.xfs_ioinit)(mp, args, flags) |
250 | #define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \ | 259 | #define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \ |
251 | (*(mp)->m_io_ops.xfs_bmapi_func) \ | 260 | (*(mp)->m_io_ops.xfs_bmapi_func) \ |
252 | (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta) | 261 | (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta) |
@@ -280,8 +289,8 @@ typedef struct xfs_ioops { | |||
280 | (*(mp)->m_io_ops.xfs_ilock_demote)((io)->io_obj, mode) | 289 | (*(mp)->m_io_ops.xfs_ilock_demote)((io)->io_obj, mode) |
281 | #define XFS_SIZE(mp, io) \ | 290 | #define XFS_SIZE(mp, io) \ |
282 | (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) | 291 | (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) |
283 | #define XFS_IODONE(vfsp) \ | 292 | #define XFS_IODONE(mp) \ |
284 | (*(mp)->m_io_ops.xfs_iodone)(vfsp) | 293 | (*(mp)->m_io_ops.xfs_iodone)(mp) |
285 | #define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \ | 294 | #define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \ |
286 | (*(mp)->m_io_ops.xfs_swap_extents_func) \ | 295 | (*(mp)->m_io_ops.xfs_swap_extents_func) \ |
287 | ((io)->io_obj, (tio)->io_obj, sxp) | 296 | ((io)->io_obj, (tio)->io_obj, sxp) |
@@ -318,7 +327,7 @@ extern void xfs_icsb_sync_counters_flags(struct xfs_mount *, int); | |||
318 | #endif | 327 | #endif |
319 | 328 | ||
320 | typedef struct xfs_mount { | 329 | typedef struct xfs_mount { |
321 | bhv_desc_t m_bhv; /* vfs xfs behavior */ | 330 | struct super_block *m_super; |
322 | xfs_tid_t m_tid; /* next unused tid for fs */ | 331 | xfs_tid_t m_tid; /* next unused tid for fs */ |
323 | AIL_LOCK_T m_ail_lock; /* fs AIL mutex */ | 332 | AIL_LOCK_T m_ail_lock; /* fs AIL mutex */ |
324 | xfs_ail_entry_t m_ail; /* fs active log item list */ | 333 | xfs_ail_entry_t m_ail; /* fs active log item list */ |
@@ -335,8 +344,6 @@ typedef struct xfs_mount { | |||
335 | xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ | 344 | xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ |
336 | lock_t m_agirotor_lock;/* .. and lock protecting it */ | 345 | lock_t m_agirotor_lock;/* .. and lock protecting it */ |
337 | xfs_agnumber_t m_maxagi; /* highest inode alloc group */ | 346 | xfs_agnumber_t m_maxagi; /* highest inode alloc group */ |
338 | size_t m_ihsize; /* size of next field */ | ||
339 | struct xfs_ihash *m_ihash; /* fs private inode hash table*/ | ||
340 | struct xfs_inode *m_inodes; /* active inode list */ | 347 | struct xfs_inode *m_inodes; /* active inode list */ |
341 | struct list_head m_del_inodes; /* inodes to reclaim */ | 348 | struct list_head m_del_inodes; /* inodes to reclaim */ |
342 | mutex_t m_ilock; /* inode list mutex */ | 349 | mutex_t m_ilock; /* inode list mutex */ |
@@ -362,7 +369,6 @@ typedef struct xfs_mount { | |||
362 | __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ | 369 | __uint8_t m_blkbb_log; /* blocklog - BBSHIFT */ |
363 | __uint8_t m_agno_log; /* log #ag's */ | 370 | __uint8_t m_agno_log; /* log #ag's */ |
364 | __uint8_t m_agino_log; /* #bits for agino in inum */ | 371 | __uint8_t m_agino_log; /* #bits for agino in inum */ |
365 | __uint8_t m_nreadaheads; /* #readahead buffers */ | ||
366 | __uint16_t m_inode_cluster_size;/* min inode buf size */ | 372 | __uint16_t m_inode_cluster_size;/* min inode buf size */ |
367 | uint m_blockmask; /* sb_blocksize-1 */ | 373 | uint m_blockmask; /* sb_blocksize-1 */ |
368 | uint m_blockwsize; /* sb_blocksize in words */ | 374 | uint m_blockwsize; /* sb_blocksize in words */ |
@@ -378,7 +384,7 @@ typedef struct xfs_mount { | |||
378 | uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ | 384 | uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ |
379 | struct xfs_perag *m_perag; /* per-ag accounting info */ | 385 | struct xfs_perag *m_perag; /* per-ag accounting info */ |
380 | struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ | 386 | struct rw_semaphore m_peraglock; /* lock for m_perag (pointer) */ |
381 | sema_t m_growlock; /* growfs mutex */ | 387 | struct mutex m_growlock; /* growfs mutex */ |
382 | int m_fixedfsid[2]; /* unchanged for life of FS */ | 388 | int m_fixedfsid[2]; /* unchanged for life of FS */ |
383 | uint m_dmevmask; /* DMI events for this FS */ | 389 | uint m_dmevmask; /* DMI events for this FS */ |
384 | __uint64_t m_flags; /* global mount flags */ | 390 | __uint64_t m_flags; /* global mount flags */ |
@@ -415,8 +421,8 @@ typedef struct xfs_mount { | |||
415 | uint m_chsize; /* size of next field */ | 421 | uint m_chsize; /* size of next field */ |
416 | struct xfs_chash *m_chash; /* fs private inode per-cluster | 422 | struct xfs_chash *m_chash; /* fs private inode per-cluster |
417 | * hash table */ | 423 | * hash table */ |
418 | struct xfs_dmops m_dm_ops; /* vector of DMI ops */ | 424 | struct xfs_dmops *m_dm_ops; /* vector of DMI ops */ |
419 | struct xfs_qmops m_qm_ops; /* vector of XQM ops */ | 425 | struct xfs_qmops *m_qm_ops; /* vector of XQM ops */ |
420 | struct xfs_ioops m_io_ops; /* vector of I/O ops */ | 426 | struct xfs_ioops m_io_ops; /* vector of I/O ops */ |
421 | atomic_t m_active_trans; /* number trans frozen */ | 427 | atomic_t m_active_trans; /* number trans frozen */ |
422 | #ifdef HAVE_PERCPU_SB | 428 | #ifdef HAVE_PERCPU_SB |
@@ -426,6 +432,12 @@ typedef struct xfs_mount { | |||
426 | struct mutex m_icsb_mutex; /* balancer sync lock */ | 432 | struct mutex m_icsb_mutex; /* balancer sync lock */ |
427 | #endif | 433 | #endif |
428 | struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ | 434 | struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ |
435 | struct task_struct *m_sync_task; /* generalised sync thread */ | ||
436 | bhv_vfs_sync_work_t m_sync_work; /* work item for VFS_SYNC */ | ||
437 | struct list_head m_sync_list; /* sync thread work item list */ | ||
438 | spinlock_t m_sync_lock; /* work item list lock */ | ||
439 | int m_sync_seq; /* sync thread generation no. */ | ||
440 | wait_queue_head_t m_wait_single_sync_task; | ||
429 | } xfs_mount_t; | 441 | } xfs_mount_t; |
430 | 442 | ||
431 | /* | 443 | /* |
@@ -435,7 +447,7 @@ typedef struct xfs_mount { | |||
435 | must be synchronous except | 447 | must be synchronous except |
436 | for space allocations */ | 448 | for space allocations */ |
437 | #define XFS_MOUNT_INO64 (1ULL << 1) | 449 | #define XFS_MOUNT_INO64 (1ULL << 1) |
438 | /* (1ULL << 2) -- currently unused */ | 450 | #define XFS_MOUNT_DMAPI (1ULL << 2) /* dmapi is enabled */ |
439 | #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) | 451 | #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) |
440 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem | 452 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem |
441 | operations, typically for | 453 | operations, typically for |
@@ -445,7 +457,7 @@ typedef struct xfs_mount { | |||
445 | #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment | 457 | #define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment |
446 | allocations */ | 458 | allocations */ |
447 | #define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ | 459 | #define XFS_MOUNT_ATTR2 (1ULL << 8) /* allow use of attr2 format */ |
448 | /* (1ULL << 9) -- currently unused */ | 460 | #define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */ |
449 | #define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ | 461 | #define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ |
450 | #define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */ | 462 | #define XFS_MOUNT_SHARED (1ULL << 11) /* shared mount */ |
451 | #define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ | 463 | #define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ |
@@ -453,13 +465,13 @@ typedef struct xfs_mount { | |||
453 | /* osyncisdsync is now default*/ | 465 | /* osyncisdsync is now default*/ |
454 | #define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above | 466 | #define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above |
455 | * 32 bits in size */ | 467 | * 32 bits in size */ |
456 | /* (1ULL << 15) -- currently unused */ | 468 | #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ |
457 | #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ | 469 | #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ |
458 | #define XFS_MOUNT_BARRIER (1ULL << 17) | 470 | #define XFS_MOUNT_BARRIER (1ULL << 17) |
459 | #define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/ | 471 | #define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/ |
460 | #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width | 472 | #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width |
461 | * allocation */ | 473 | * allocation */ |
462 | #define XFS_MOUNT_IHASHSIZE (1ULL << 20) /* inode hash table size */ | 474 | #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ |
463 | #define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */ | 475 | #define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */ |
464 | #define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred | 476 | #define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred |
465 | * I/O size in stat() */ | 477 | * I/O size in stat() */ |
@@ -518,8 +530,10 @@ xfs_preferred_iosize(xfs_mount_t *mp) | |||
518 | #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ | 530 | #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ |
519 | ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) | 531 | ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) |
520 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) | 532 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) |
533 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, | ||
534 | int lnnum); | ||
521 | #define xfs_force_shutdown(m,f) \ | 535 | #define xfs_force_shutdown(m,f) \ |
522 | bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__) | 536 | xfs_do_force_shutdown(m, f, __FILE__, __LINE__) |
523 | 537 | ||
524 | /* | 538 | /* |
525 | * Flags for xfs_mountfs | 539 | * Flags for xfs_mountfs |
@@ -533,28 +547,6 @@ xfs_preferred_iosize(xfs_mount_t *mp) | |||
533 | /* XFS_MFSI_CONVERT_SUNIT */ | 547 | /* XFS_MFSI_CONVERT_SUNIT */ |
534 | #define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ | 548 | #define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */ |
535 | 549 | ||
536 | /* | ||
537 | * Macros for getting from mount to vfs and back. | ||
538 | */ | ||
539 | #define XFS_MTOVFS(mp) xfs_mtovfs(mp) | ||
540 | static inline struct bhv_vfs *xfs_mtovfs(xfs_mount_t *mp) | ||
541 | { | ||
542 | return bhvtovfs(&mp->m_bhv); | ||
543 | } | ||
544 | |||
545 | #define XFS_BHVTOM(bdp) xfs_bhvtom(bdp) | ||
546 | static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp) | ||
547 | { | ||
548 | return (xfs_mount_t *)BHV_PDATA(bdp); | ||
549 | } | ||
550 | |||
551 | #define XFS_VFSTOM(vfs) xfs_vfstom(vfs) | ||
552 | static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs) | ||
553 | { | ||
554 | return XFS_BHVTOM(bhv_lookup_range(VFS_BHVHEAD(vfs), | ||
555 | VFS_POSITION_XFS, VFS_POSITION_XFS)); | ||
556 | } | ||
557 | |||
558 | #define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) | 550 | #define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) |
559 | static inline xfs_agnumber_t | 551 | static inline xfs_agnumber_t |
560 | xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d) | 552 | xfs_daddr_to_agno(struct xfs_mount *mp, xfs_daddr_t d) |
@@ -573,6 +565,21 @@ xfs_daddr_to_agbno(struct xfs_mount *mp, xfs_daddr_t d) | |||
573 | } | 565 | } |
574 | 566 | ||
575 | /* | 567 | /* |
568 | * perag get/put wrappers for eventual ref counting | ||
569 | */ | ||
570 | static inline xfs_perag_t * | ||
571 | xfs_get_perag(struct xfs_mount *mp, xfs_ino_t ino) | ||
572 | { | ||
573 | return &mp->m_perag[XFS_INO_TO_AGNO(mp, ino)]; | ||
574 | } | ||
575 | |||
576 | static inline void | ||
577 | xfs_put_perag(struct xfs_mount *mp, xfs_perag_t *pag) | ||
578 | { | ||
579 | /* nothing to see here, move along */ | ||
580 | } | ||
581 | |||
582 | /* | ||
576 | * Per-cpu superblock locking functions | 583 | * Per-cpu superblock locking functions |
577 | */ | 584 | */ |
578 | #ifdef HAVE_PERCPU_SB | 585 | #ifdef HAVE_PERCPU_SB |
@@ -609,8 +616,8 @@ typedef struct xfs_mod_sb { | |||
609 | extern xfs_mount_t *xfs_mount_init(void); | 616 | extern xfs_mount_t *xfs_mount_init(void); |
610 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); | 617 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); |
611 | extern int xfs_log_sbcount(xfs_mount_t *, uint); | 618 | extern int xfs_log_sbcount(xfs_mount_t *, uint); |
612 | extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); | 619 | extern void xfs_mount_free(xfs_mount_t *mp); |
613 | extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int); | 620 | extern int xfs_mountfs(xfs_mount_t *mp, int); |
614 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); | 621 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); |
615 | 622 | ||
616 | extern int xfs_unmountfs(xfs_mount_t *, struct cred *); | 623 | extern int xfs_unmountfs(xfs_mount_t *, struct cred *); |
@@ -626,16 +633,19 @@ extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); | |||
626 | extern int xfs_readsb(xfs_mount_t *, int); | 633 | extern int xfs_readsb(xfs_mount_t *, int); |
627 | extern void xfs_freesb(xfs_mount_t *); | 634 | extern void xfs_freesb(xfs_mount_t *); |
628 | extern int xfs_fs_writable(xfs_mount_t *); | 635 | extern int xfs_fs_writable(xfs_mount_t *); |
629 | extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); | ||
630 | extern int xfs_syncsub(xfs_mount_t *, int, int *); | 636 | extern int xfs_syncsub(xfs_mount_t *, int, int *); |
631 | extern int xfs_sync_inodes(xfs_mount_t *, int, int *); | 637 | extern int xfs_sync_inodes(xfs_mount_t *, int, int *); |
632 | extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *, | 638 | extern xfs_agnumber_t xfs_initialize_perag(xfs_mount_t *, xfs_agnumber_t); |
633 | xfs_agnumber_t); | 639 | extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); |
634 | extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); | 640 | extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); |
635 | extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); | 641 | extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); |
636 | 642 | ||
637 | extern struct xfs_dmops xfs_dmcore_stub; | 643 | extern int xfs_dmops_get(struct xfs_mount *, struct xfs_mount_args *); |
638 | extern struct xfs_qmops xfs_qmcore_stub; | 644 | extern void xfs_dmops_put(struct xfs_mount *); |
645 | extern int xfs_qmops_get(struct xfs_mount *, struct xfs_mount_args *); | ||
646 | extern void xfs_qmops_put(struct xfs_mount *); | ||
647 | |||
648 | extern struct xfs_dmops xfs_dmcore_xfs; | ||
639 | extern struct xfs_ioops xfs_iocore_xfs; | 649 | extern struct xfs_ioops xfs_iocore_xfs; |
640 | 650 | ||
641 | extern int xfs_init(void); | 651 | extern int xfs_init(void); |
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c index 0d594ed7efef..c266a0184b42 100644 --- a/fs/xfs/xfs_qmops.c +++ b/fs/xfs/xfs_qmops.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
29 | #include "xfs_quota.h" | 29 | #include "xfs_quota.h" |
30 | #include "xfs_error.h" | 30 | #include "xfs_error.h" |
31 | #include "xfs_clnt.h" | ||
32 | |||
31 | 33 | ||
32 | STATIC struct xfs_dquot * | 34 | STATIC struct xfs_dquot * |
33 | xfs_dqvopchown_default( | 35 | xfs_dqvopchown_default( |
@@ -64,7 +66,7 @@ xfs_mount_reset_sbqflags(xfs_mount_t *mp) | |||
64 | * if the fs is readonly, let the incore superblock run | 66 | * if the fs is readonly, let the incore superblock run |
65 | * with quotas off but don't flush the update out to disk | 67 | * with quotas off but don't flush the update out to disk |
66 | */ | 68 | */ |
67 | if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) | 69 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
68 | return 0; | 70 | return 0; |
69 | #ifdef QUOTADEBUG | 71 | #ifdef QUOTADEBUG |
70 | xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes"); | 72 | xfs_fs_cmn_err(CE_NOTE, mp, "Writing superblock quota changes"); |
@@ -110,7 +112,7 @@ xfs_noquota_init( | |||
110 | return error; | 112 | return error; |
111 | } | 113 | } |
112 | 114 | ||
113 | xfs_qmops_t xfs_qmcore_stub = { | 115 | static struct xfs_qmops xfs_qmcore_stub = { |
114 | .xfs_qminit = (xfs_qminit_t) xfs_noquota_init, | 116 | .xfs_qminit = (xfs_qminit_t) xfs_noquota_init, |
115 | .xfs_qmdone = (xfs_qmdone_t) fs_noerr, | 117 | .xfs_qmdone = (xfs_qmdone_t) fs_noerr, |
116 | .xfs_qmmount = (xfs_qmmount_t) fs_noerr, | 118 | .xfs_qmmount = (xfs_qmmount_t) fs_noerr, |
@@ -124,4 +126,38 @@ xfs_qmops_t xfs_qmcore_stub = { | |||
124 | .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr, | 126 | .xfs_dqvoprename = (xfs_dqvoprename_t) fs_noerr, |
125 | .xfs_dqvopchown = xfs_dqvopchown_default, | 127 | .xfs_dqvopchown = xfs_dqvopchown_default, |
126 | .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, | 128 | .xfs_dqvopchownresv = (xfs_dqvopchownresv_t) fs_noerr, |
129 | .xfs_dqstatvfs = (xfs_dqstatvfs_t) fs_noval, | ||
130 | .xfs_dqsync = (xfs_dqsync_t) fs_noerr, | ||
131 | .xfs_quotactl = (xfs_quotactl_t) fs_nosys, | ||
127 | }; | 132 | }; |
133 | |||
134 | int | ||
135 | xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) | ||
136 | { | ||
137 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)) { | ||
138 | struct xfs_qmops *ops; | ||
139 | |||
140 | ops = symbol_get(xfs_qmcore_xfs); | ||
141 | if (!ops) { | ||
142 | request_module("xfs_quota"); | ||
143 | ops = symbol_get(xfs_qmcore_xfs); | ||
144 | } | ||
145 | |||
146 | if (!ops) { | ||
147 | cmn_err(CE_WARN, "XFS: no quota support available."); | ||
148 | return EINVAL; | ||
149 | } | ||
150 | mp->m_qm_ops = ops; | ||
151 | } else { | ||
152 | mp->m_qm_ops = &xfs_qmcore_stub; | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | void | ||
159 | xfs_qmops_put(struct xfs_mount *mp) | ||
160 | { | ||
161 | if (mp->m_qm_ops != &xfs_qmcore_stub) | ||
162 | symbol_put(xfs_qmcore_xfs); | ||
163 | } | ||
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 6f14df976f73..12c4ec775af8 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h | |||
@@ -330,12 +330,12 @@ typedef struct xfs_dqtrxops { | |||
330 | } xfs_dqtrxops_t; | 330 | } xfs_dqtrxops_t; |
331 | 331 | ||
332 | #define XFS_DQTRXOP(mp, tp, op, args...) \ | 332 | #define XFS_DQTRXOP(mp, tp, op, args...) \ |
333 | ((mp)->m_qm_ops.xfs_dqtrxops ? \ | 333 | ((mp)->m_qm_ops->xfs_dqtrxops ? \ |
334 | ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : 0) | 334 | ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : 0) |
335 | 335 | ||
336 | #define XFS_DQTRXOP_VOID(mp, tp, op, args...) \ | 336 | #define XFS_DQTRXOP_VOID(mp, tp, op, args...) \ |
337 | ((mp)->m_qm_ops.xfs_dqtrxops ? \ | 337 | ((mp)->m_qm_ops->xfs_dqtrxops ? \ |
338 | ((mp)->m_qm_ops.xfs_dqtrxops->op)(tp, ## args) : (void)0) | 338 | ((mp)->m_qm_ops->xfs_dqtrxops->op)(tp, ## args) : (void)0) |
339 | 339 | ||
340 | #define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \ | 340 | #define XFS_TRANS_DUP_DQINFO(mp, otp, ntp) \ |
341 | XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp) | 341 | XFS_DQTRXOP_VOID(mp, otp, qo_dup_dqinfo, ntp) |
@@ -364,7 +364,7 @@ typedef struct xfs_dqtrxops { | |||
364 | extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); | 364 | extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); |
365 | extern int xfs_mount_reset_sbqflags(struct xfs_mount *); | 365 | extern int xfs_mount_reset_sbqflags(struct xfs_mount *); |
366 | 366 | ||
367 | extern struct bhv_module_vfsops xfs_qmops; | 367 | extern struct xfs_qmops xfs_qmcore_xfs; |
368 | 368 | ||
369 | #endif /* __KERNEL__ */ | 369 | #endif /* __KERNEL__ */ |
370 | 370 | ||
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 7679d7a7022d..44ea0ba36476 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | ||
25 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
26 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
@@ -128,8 +129,7 @@ xfs_lock_for_rename( | |||
128 | lock_mode = xfs_ilock_map_shared(dp2); | 129 | lock_mode = xfs_ilock_map_shared(dp2); |
129 | } | 130 | } |
130 | 131 | ||
131 | error = xfs_dir_lookup_int(XFS_ITOBHV(dp2), lock_mode, | 132 | error = xfs_dir_lookup_int(dp2, lock_mode, vname2, &inum2, &ip2); |
132 | vname2, &inum2, &ip2); | ||
133 | if (error == ENOENT) { /* target does not need to exist. */ | 133 | if (error == ENOENT) { /* target does not need to exist. */ |
134 | inum2 = 0; | 134 | inum2 = 0; |
135 | } else if (error) { | 135 | } else if (error) { |
@@ -221,15 +221,15 @@ xfs_lock_for_rename( | |||
221 | */ | 221 | */ |
222 | int | 222 | int |
223 | xfs_rename( | 223 | xfs_rename( |
224 | bhv_desc_t *src_dir_bdp, | 224 | xfs_inode_t *src_dp, |
225 | bhv_vname_t *src_vname, | 225 | bhv_vname_t *src_vname, |
226 | bhv_vnode_t *target_dir_vp, | 226 | bhv_vnode_t *target_dir_vp, |
227 | bhv_vname_t *target_vname, | 227 | bhv_vname_t *target_vname) |
228 | cred_t *credp) | ||
229 | { | 228 | { |
229 | bhv_vnode_t *src_dir_vp = XFS_ITOV(src_dp); | ||
230 | xfs_trans_t *tp; | 230 | xfs_trans_t *tp; |
231 | xfs_inode_t *src_dp, *target_dp, *src_ip, *target_ip; | 231 | xfs_inode_t *target_dp, *src_ip, *target_ip; |
232 | xfs_mount_t *mp; | 232 | xfs_mount_t *mp = src_dp->i_mount; |
233 | int new_parent; /* moving to a new dir */ | 233 | int new_parent; /* moving to a new dir */ |
234 | int src_is_directory; /* src_name is a directory */ | 234 | int src_is_directory; /* src_name is a directory */ |
235 | int error; | 235 | int error; |
@@ -239,7 +239,6 @@ xfs_rename( | |||
239 | int committed; | 239 | int committed; |
240 | xfs_inode_t *inodes[4]; | 240 | xfs_inode_t *inodes[4]; |
241 | int target_ip_dropped = 0; /* dropped target_ip link? */ | 241 | int target_ip_dropped = 0; /* dropped target_ip link? */ |
242 | bhv_vnode_t *src_dir_vp; | ||
243 | int spaceres; | 242 | int spaceres; |
244 | int target_link_zero = 0; | 243 | int target_link_zero = 0; |
245 | int num_inodes; | 244 | int num_inodes; |
@@ -248,9 +247,8 @@ xfs_rename( | |||
248 | int src_namelen = VNAMELEN(src_vname); | 247 | int src_namelen = VNAMELEN(src_vname); |
249 | int target_namelen = VNAMELEN(target_vname); | 248 | int target_namelen = VNAMELEN(target_vname); |
250 | 249 | ||
251 | src_dir_vp = BHV_TO_VNODE(src_dir_bdp); | 250 | vn_trace_entry(src_dp, "xfs_rename", (inst_t *)__return_address); |
252 | vn_trace_entry(src_dir_vp, "xfs_rename", (inst_t *)__return_address); | 251 | vn_trace_entry(xfs_vtoi(target_dir_vp), "xfs_rename", (inst_t *)__return_address); |
253 | vn_trace_entry(target_dir_vp, "xfs_rename", (inst_t *)__return_address); | ||
254 | 252 | ||
255 | /* | 253 | /* |
256 | * Find the XFS behavior descriptor for the target directory | 254 | * Find the XFS behavior descriptor for the target directory |
@@ -261,12 +259,8 @@ xfs_rename( | |||
261 | return XFS_ERROR(EXDEV); | 259 | return XFS_ERROR(EXDEV); |
262 | } | 260 | } |
263 | 261 | ||
264 | src_dp = XFS_BHVTOI(src_dir_bdp); | 262 | if (DM_EVENT_ENABLED(src_dp, DM_EVENT_RENAME) || |
265 | mp = src_dp->i_mount; | 263 | DM_EVENT_ENABLED(target_dp, DM_EVENT_RENAME)) { |
266 | |||
267 | if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) || | ||
268 | DM_EVENT_ENABLED(target_dir_vp->v_vfsp, | ||
269 | target_dp, DM_EVENT_RENAME)) { | ||
270 | error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME, | 264 | error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME, |
271 | src_dir_vp, DM_RIGHT_NULL, | 265 | src_dir_vp, DM_RIGHT_NULL, |
272 | target_dir_vp, DM_RIGHT_NULL, | 266 | target_dir_vp, DM_RIGHT_NULL, |
@@ -592,20 +586,16 @@ xfs_rename( | |||
592 | /* | 586 | /* |
593 | * Let interposed file systems know about removed links. | 587 | * Let interposed file systems know about removed links. |
594 | */ | 588 | */ |
595 | if (target_ip_dropped) { | 589 | if (target_ip_dropped) |
596 | bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp, | ||
597 | target_link_zero); | ||
598 | IRELE(target_ip); | 590 | IRELE(target_ip); |
599 | } | ||
600 | 591 | ||
601 | IRELE(src_ip); | 592 | IRELE(src_ip); |
602 | 593 | ||
603 | /* Fall through to std_return with error = 0 or errno from | 594 | /* Fall through to std_return with error = 0 or errno from |
604 | * xfs_trans_commit */ | 595 | * xfs_trans_commit */ |
605 | std_return: | 596 | std_return: |
606 | if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_POSTRENAME) || | 597 | if (DM_EVENT_ENABLED(src_dp, DM_EVENT_POSTRENAME) || |
607 | DM_EVENT_ENABLED(target_dir_vp->v_vfsp, | 598 | DM_EVENT_ENABLED(target_dp, DM_EVENT_POSTRENAME)) { |
608 | target_dp, DM_EVENT_POSTRENAME)) { | ||
609 | (void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME, | 599 | (void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME, |
610 | src_dir_vp, DM_RIGHT_NULL, | 600 | src_dir_vp, DM_RIGHT_NULL, |
611 | target_dir_vp, DM_RIGHT_NULL, | 601 | target_dir_vp, DM_RIGHT_NULL, |
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c index 905d1c008be7..cd3ece6cc918 100644 --- a/fs/xfs/xfs_rw.c +++ b/fs/xfs/xfs_rw.c | |||
@@ -178,18 +178,15 @@ xfs_write_sync_logforce( | |||
178 | * the shop, make sure that absolutely nothing persistent happens to | 178 | * the shop, make sure that absolutely nothing persistent happens to |
179 | * this filesystem after this point. | 179 | * this filesystem after this point. |
180 | */ | 180 | */ |
181 | |||
182 | void | 181 | void |
183 | xfs_do_force_shutdown( | 182 | xfs_do_force_shutdown( |
184 | bhv_desc_t *bdp, | 183 | xfs_mount_t *mp, |
185 | int flags, | 184 | int flags, |
186 | char *fname, | 185 | char *fname, |
187 | int lnnum) | 186 | int lnnum) |
188 | { | 187 | { |
189 | int logerror; | 188 | int logerror; |
190 | xfs_mount_t *mp; | ||
191 | 189 | ||
192 | mp = XFS_BHVTOM(bdp); | ||
193 | logerror = flags & SHUTDOWN_LOG_IO_ERROR; | 190 | logerror = flags & SHUTDOWN_LOG_IO_ERROR; |
194 | 191 | ||
195 | if (!(flags & SHUTDOWN_FORCE_UMOUNT)) { | 192 | if (!(flags & SHUTDOWN_FORCE_UMOUNT)) { |
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h index fcf28dbded7c..49875e1d129f 100644 --- a/fs/xfs/xfs_rw.h +++ b/fs/xfs/xfs_rw.h | |||
@@ -23,32 +23,6 @@ struct xfs_inode; | |||
23 | struct xfs_mount; | 23 | struct xfs_mount; |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Maximum count of bmaps used by read and write paths. | ||
27 | */ | ||
28 | #define XFS_MAX_RW_NBMAPS 4 | ||
29 | |||
30 | /* | ||
31 | * Counts of readahead buffers to use based on physical memory size. | ||
32 | * None of these should be more than XFS_MAX_RW_NBMAPS. | ||
33 | */ | ||
34 | #define XFS_RW_NREADAHEAD_16MB 2 | ||
35 | #define XFS_RW_NREADAHEAD_32MB 3 | ||
36 | #define XFS_RW_NREADAHEAD_K32 4 | ||
37 | #define XFS_RW_NREADAHEAD_K64 4 | ||
38 | |||
39 | /* | ||
40 | * Maximum size of a buffer that we\'ll map. Making this | ||
41 | * too big will degrade performance due to the number of | ||
42 | * pages which need to be gathered. Making it too small | ||
43 | * will prevent us from doing large I/O\'s to hardware that | ||
44 | * needs it. | ||
45 | * | ||
46 | * This is currently set to 512 KB. | ||
47 | */ | ||
48 | #define XFS_MAX_BMAP_LEN_BB 1024 | ||
49 | #define XFS_MAX_BMAP_LEN_BYTES 524288 | ||
50 | |||
51 | /* | ||
52 | * Convert the given file system block to a disk block. | 26 | * Convert the given file system block to a disk block. |
53 | * We have to treat it differently based on whether the | 27 | * We have to treat it differently based on whether the |
54 | * file is a real time file or not, because the bmap code | 28 | * file is a real time file or not, because the bmap code |
@@ -116,14 +90,6 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp, | |||
116 | /* | 90 | /* |
117 | * Prototypes for functions in xfs_vnodeops.c. | 91 | * Prototypes for functions in xfs_vnodeops.c. |
118 | */ | 92 | */ |
119 | extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); | ||
120 | extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); | ||
121 | extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags, | ||
122 | cred_t *credp); | ||
123 | extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf, | ||
124 | xfs_off_t offset, cred_t *credp, int flags); | ||
125 | extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state, | ||
126 | cred_t *credp); | ||
127 | extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip, | 93 | extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip, |
128 | int flags); | 94 | int flags); |
129 | 95 | ||
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h index ef42537a607a..94660b1a6ccc 100644 --- a/fs/xfs/xfs_sb.h +++ b/fs/xfs/xfs_sb.h | |||
@@ -87,8 +87,10 @@ struct xfs_mount; | |||
87 | (XFS_SB_VERSION2_OKREALFBITS | \ | 87 | (XFS_SB_VERSION2_OKREALFBITS | \ |
88 | XFS_SB_VERSION2_OKSASHFBITS ) | 88 | XFS_SB_VERSION2_OKSASHFBITS ) |
89 | 89 | ||
90 | typedef struct xfs_sb | 90 | /* |
91 | { | 91 | * Superblock - in core version. Must match the ondisk version below. |
92 | */ | ||
93 | typedef struct xfs_sb { | ||
92 | __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ | 94 | __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ |
93 | __uint32_t sb_blocksize; /* logical block size, bytes */ | 95 | __uint32_t sb_blocksize; /* logical block size, bytes */ |
94 | xfs_drfsbno_t sb_dblocks; /* number of data blocks */ | 96 | xfs_drfsbno_t sb_dblocks; /* number of data blocks */ |
@@ -146,6 +148,66 @@ typedef struct xfs_sb | |||
146 | } xfs_sb_t; | 148 | } xfs_sb_t; |
147 | 149 | ||
148 | /* | 150 | /* |
151 | * Superblock - on disk version. Must match the in core version below. | ||
152 | */ | ||
153 | typedef struct xfs_dsb { | ||
154 | __be32 sb_magicnum; /* magic number == XFS_SB_MAGIC */ | ||
155 | __be32 sb_blocksize; /* logical block size, bytes */ | ||
156 | __be64 sb_dblocks; /* number of data blocks */ | ||
157 | __be64 sb_rblocks; /* number of realtime blocks */ | ||
158 | __be64 sb_rextents; /* number of realtime extents */ | ||
159 | uuid_t sb_uuid; /* file system unique id */ | ||
160 | __be64 sb_logstart; /* starting block of log if internal */ | ||
161 | __be64 sb_rootino; /* root inode number */ | ||
162 | __be64 sb_rbmino; /* bitmap inode for realtime extents */ | ||
163 | __be64 sb_rsumino; /* summary inode for rt bitmap */ | ||
164 | __be32 sb_rextsize; /* realtime extent size, blocks */ | ||
165 | __be32 sb_agblocks; /* size of an allocation group */ | ||
166 | __be32 sb_agcount; /* number of allocation groups */ | ||
167 | __be32 sb_rbmblocks; /* number of rt bitmap blocks */ | ||
168 | __be32 sb_logblocks; /* number of log blocks */ | ||
169 | __be16 sb_versionnum; /* header version == XFS_SB_VERSION */ | ||
170 | __be16 sb_sectsize; /* volume sector size, bytes */ | ||
171 | __be16 sb_inodesize; /* inode size, bytes */ | ||
172 | __be16 sb_inopblock; /* inodes per block */ | ||
173 | char sb_fname[12]; /* file system name */ | ||
174 | __u8 sb_blocklog; /* log2 of sb_blocksize */ | ||
175 | __u8 sb_sectlog; /* log2 of sb_sectsize */ | ||
176 | __u8 sb_inodelog; /* log2 of sb_inodesize */ | ||
177 | __u8 sb_inopblog; /* log2 of sb_inopblock */ | ||
178 | __u8 sb_agblklog; /* log2 of sb_agblocks (rounded up) */ | ||
179 | __u8 sb_rextslog; /* log2 of sb_rextents */ | ||
180 | __u8 sb_inprogress; /* mkfs is in progress, don't mount */ | ||
181 | __u8 sb_imax_pct; /* max % of fs for inode space */ | ||
182 | /* statistics */ | ||
183 | /* | ||
184 | * These fields must remain contiguous. If you really | ||
185 | * want to change their layout, make sure you fix the | ||
186 | * code in xfs_trans_apply_sb_deltas(). | ||
187 | */ | ||
188 | __be64 sb_icount; /* allocated inodes */ | ||
189 | __be64 sb_ifree; /* free inodes */ | ||
190 | __be64 sb_fdblocks; /* free data blocks */ | ||
191 | __be64 sb_frextents; /* free realtime extents */ | ||
192 | /* | ||
193 | * End contiguous fields. | ||
194 | */ | ||
195 | __be64 sb_uquotino; /* user quota inode */ | ||
196 | __be64 sb_gquotino; /* group quota inode */ | ||
197 | __be16 sb_qflags; /* quota flags */ | ||
198 | __u8 sb_flags; /* misc. flags */ | ||
199 | __u8 sb_shared_vn; /* shared version number */ | ||
200 | __be32 sb_inoalignmt; /* inode chunk alignment, fsblocks */ | ||
201 | __be32 sb_unit; /* stripe or raid unit */ | ||
202 | __be32 sb_width; /* stripe or raid width */ | ||
203 | __u8 sb_dirblklog; /* log2 of dir block size (fsbs) */ | ||
204 | __u8 sb_logsectlog; /* log2 of the log sector size */ | ||
205 | __be16 sb_logsectsize; /* sector size for the log, bytes */ | ||
206 | __be32 sb_logsunit; /* stripe unit size for the log */ | ||
207 | __be32 sb_features2; /* additional feature bits */ | ||
208 | } xfs_dsb_t; | ||
209 | |||
210 | /* | ||
149 | * Sequence number values for the fields. | 211 | * Sequence number values for the fields. |
150 | */ | 212 | */ |
151 | typedef enum { | 213 | typedef enum { |
@@ -446,7 +508,7 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) | |||
446 | 508 | ||
447 | #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ | 509 | #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ |
448 | #define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) | 510 | #define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) |
449 | #define XFS_BUF_TO_SBP(bp) ((xfs_sb_t *)XFS_BUF_PTR(bp)) | 511 | #define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)XFS_BUF_PTR(bp)) |
450 | 512 | ||
451 | #define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) | 513 | #define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) |
452 | #define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ | 514 | #define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 356d6627f581..8878322ee793 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -234,7 +234,7 @@ xfs_trans_alloc( | |||
234 | xfs_mount_t *mp, | 234 | xfs_mount_t *mp, |
235 | uint type) | 235 | uint type) |
236 | { | 236 | { |
237 | vfs_wait_for_freeze(XFS_MTOVFS(mp), SB_FREEZE_TRANS); | 237 | xfs_wait_for_freeze(mp, SB_FREEZE_TRANS); |
238 | return _xfs_trans_alloc(mp, type); | 238 | return _xfs_trans_alloc(mp, type); |
239 | } | 239 | } |
240 | 240 | ||
@@ -548,7 +548,7 @@ STATIC void | |||
548 | xfs_trans_apply_sb_deltas( | 548 | xfs_trans_apply_sb_deltas( |
549 | xfs_trans_t *tp) | 549 | xfs_trans_t *tp) |
550 | { | 550 | { |
551 | xfs_sb_t *sbp; | 551 | xfs_dsb_t *sbp; |
552 | xfs_buf_t *bp; | 552 | xfs_buf_t *bp; |
553 | int whole = 0; | 553 | int whole = 0; |
554 | 554 | ||
@@ -566,57 +566,51 @@ xfs_trans_apply_sb_deltas( | |||
566 | * Only update the superblock counters if we are logging them | 566 | * Only update the superblock counters if we are logging them |
567 | */ | 567 | */ |
568 | if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { | 568 | if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { |
569 | if (tp->t_icount_delta != 0) { | 569 | if (tp->t_icount_delta) |
570 | INT_MOD(sbp->sb_icount, ARCH_CONVERT, tp->t_icount_delta); | 570 | be64_add(&sbp->sb_icount, tp->t_icount_delta); |
571 | } | 571 | if (tp->t_ifree_delta) |
572 | if (tp->t_ifree_delta != 0) { | 572 | be64_add(&sbp->sb_ifree, tp->t_ifree_delta); |
573 | INT_MOD(sbp->sb_ifree, ARCH_CONVERT, tp->t_ifree_delta); | 573 | if (tp->t_fdblocks_delta) |
574 | } | 574 | be64_add(&sbp->sb_fdblocks, tp->t_fdblocks_delta); |
575 | 575 | if (tp->t_res_fdblocks_delta) | |
576 | if (tp->t_fdblocks_delta != 0) { | 576 | be64_add(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta); |
577 | INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_fdblocks_delta); | ||
578 | } | ||
579 | if (tp->t_res_fdblocks_delta != 0) { | ||
580 | INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_res_fdblocks_delta); | ||
581 | } | ||
582 | } | 577 | } |
583 | 578 | ||
584 | if (tp->t_frextents_delta != 0) { | 579 | if (tp->t_frextents_delta) |
585 | INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_frextents_delta); | 580 | be64_add(&sbp->sb_frextents, tp->t_frextents_delta); |
586 | } | 581 | if (tp->t_res_frextents_delta) |
587 | if (tp->t_res_frextents_delta != 0) { | 582 | be64_add(&sbp->sb_frextents, tp->t_res_frextents_delta); |
588 | INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_res_frextents_delta); | 583 | |
589 | } | 584 | if (tp->t_dblocks_delta) { |
590 | if (tp->t_dblocks_delta != 0) { | 585 | be64_add(&sbp->sb_dblocks, tp->t_dblocks_delta); |
591 | INT_MOD(sbp->sb_dblocks, ARCH_CONVERT, tp->t_dblocks_delta); | ||
592 | whole = 1; | 586 | whole = 1; |
593 | } | 587 | } |
594 | if (tp->t_agcount_delta != 0) { | 588 | if (tp->t_agcount_delta) { |
595 | INT_MOD(sbp->sb_agcount, ARCH_CONVERT, tp->t_agcount_delta); | 589 | be32_add(&sbp->sb_agcount, tp->t_agcount_delta); |
596 | whole = 1; | 590 | whole = 1; |
597 | } | 591 | } |
598 | if (tp->t_imaxpct_delta != 0) { | 592 | if (tp->t_imaxpct_delta) { |
599 | INT_MOD(sbp->sb_imax_pct, ARCH_CONVERT, tp->t_imaxpct_delta); | 593 | sbp->sb_imax_pct += tp->t_imaxpct_delta; |
600 | whole = 1; | 594 | whole = 1; |
601 | } | 595 | } |
602 | if (tp->t_rextsize_delta != 0) { | 596 | if (tp->t_rextsize_delta) { |
603 | INT_MOD(sbp->sb_rextsize, ARCH_CONVERT, tp->t_rextsize_delta); | 597 | be32_add(&sbp->sb_rextsize, tp->t_rextsize_delta); |
604 | whole = 1; | 598 | whole = 1; |
605 | } | 599 | } |
606 | if (tp->t_rbmblocks_delta != 0) { | 600 | if (tp->t_rbmblocks_delta) { |
607 | INT_MOD(sbp->sb_rbmblocks, ARCH_CONVERT, tp->t_rbmblocks_delta); | 601 | be32_add(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta); |
608 | whole = 1; | 602 | whole = 1; |
609 | } | 603 | } |
610 | if (tp->t_rblocks_delta != 0) { | 604 | if (tp->t_rblocks_delta) { |
611 | INT_MOD(sbp->sb_rblocks, ARCH_CONVERT, tp->t_rblocks_delta); | 605 | be64_add(&sbp->sb_rblocks, tp->t_rblocks_delta); |
612 | whole = 1; | 606 | whole = 1; |
613 | } | 607 | } |
614 | if (tp->t_rextents_delta != 0) { | 608 | if (tp->t_rextents_delta) { |
615 | INT_MOD(sbp->sb_rextents, ARCH_CONVERT, tp->t_rextents_delta); | 609 | be64_add(&sbp->sb_rextents, tp->t_rextents_delta); |
616 | whole = 1; | 610 | whole = 1; |
617 | } | 611 | } |
618 | if (tp->t_rextslog_delta != 0) { | 612 | if (tp->t_rextslog_delta) { |
619 | INT_MOD(sbp->sb_rextslog, ARCH_CONVERT, tp->t_rextslog_delta); | 613 | sbp->sb_rextslog += tp->t_rextslog_delta; |
620 | whole = 1; | 614 | whole = 1; |
621 | } | 615 | } |
622 | 616 | ||
@@ -624,17 +618,17 @@ xfs_trans_apply_sb_deltas( | |||
624 | /* | 618 | /* |
625 | * Log the whole thing, the fields are noncontiguous. | 619 | * Log the whole thing, the fields are noncontiguous. |
626 | */ | 620 | */ |
627 | xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_sb_t) - 1); | 621 | xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_dsb_t) - 1); |
628 | else | 622 | else |
629 | /* | 623 | /* |
630 | * Since all the modifiable fields are contiguous, we | 624 | * Since all the modifiable fields are contiguous, we |
631 | * can get away with this. | 625 | * can get away with this. |
632 | */ | 626 | */ |
633 | xfs_trans_log_buf(tp, bp, offsetof(xfs_sb_t, sb_icount), | 627 | xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount), |
634 | offsetof(xfs_sb_t, sb_frextents) + | 628 | offsetof(xfs_dsb_t, sb_frextents) + |
635 | sizeof(sbp->sb_frextents) - 1); | 629 | sizeof(sbp->sb_frextents) - 1); |
636 | 630 | ||
637 | XFS_MTOVFS(tp->t_mountp)->vfs_super->s_dirt = 1; | 631 | tp->t_mountp->m_super->s_dirt = 1; |
638 | } | 632 | } |
639 | 633 | ||
640 | /* | 634 | /* |
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index ceb4f6e99960..5b2ff59f19cf 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | ||
25 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
26 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
27 | #include "xfs_trans_priv.h" | 28 | #include "xfs_trans_priv.h" |
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index b290270dd4a6..27cce2a9c7e9 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | ||
25 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
26 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
27 | #include "xfs_trans_priv.h" | 28 | #include "xfs_trans_priv.h" |
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index 104f64a98790..5c89be475464 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h | |||
@@ -151,18 +151,6 @@ typedef __uint8_t xfs_arch_t; /* architecture of an xfs fs */ | |||
151 | */ | 151 | */ |
152 | #define MAXNAMELEN 256 | 152 | #define MAXNAMELEN 256 |
153 | 153 | ||
154 | typedef struct xfs_dirent { /* data from readdir() */ | ||
155 | xfs_ino_t d_ino; /* inode number of entry */ | ||
156 | xfs_off_t d_off; /* offset of disk directory entry */ | ||
157 | unsigned short d_reclen; /* length of this record */ | ||
158 | char d_name[1]; /* name of file */ | ||
159 | } xfs_dirent_t; | ||
160 | |||
161 | #define DIRENTBASESIZE (((xfs_dirent_t *)0)->d_name - (char *)0) | ||
162 | #define DIRENTSIZE(namelen) \ | ||
163 | ((DIRENTBASESIZE + (namelen) + \ | ||
164 | sizeof(xfs_off_t)) & ~(sizeof(xfs_off_t) - 1)) | ||
165 | |||
166 | typedef enum { | 154 | typedef enum { |
167 | XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi | 155 | XFS_LOOKUP_EQi, XFS_LOOKUP_LEi, XFS_LOOKUP_GEi |
168 | } xfs_lookup_t; | 156 | } xfs_lookup_t; |
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 20ffec308e1e..673b405eaa31 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
@@ -65,20 +65,15 @@ xfs_get_dir_entry( | |||
65 | 65 | ||
66 | int | 66 | int |
67 | xfs_dir_lookup_int( | 67 | xfs_dir_lookup_int( |
68 | bhv_desc_t *dir_bdp, | 68 | xfs_inode_t *dp, |
69 | uint lock_mode, | 69 | uint lock_mode, |
70 | bhv_vname_t *dentry, | 70 | bhv_vname_t *dentry, |
71 | xfs_ino_t *inum, | 71 | xfs_ino_t *inum, |
72 | xfs_inode_t **ipp) | 72 | xfs_inode_t **ipp) |
73 | { | 73 | { |
74 | bhv_vnode_t *dir_vp; | ||
75 | xfs_inode_t *dp; | ||
76 | int error; | 74 | int error; |
77 | 75 | ||
78 | dir_vp = BHV_TO_VNODE(dir_bdp); | 76 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
79 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
80 | |||
81 | dp = XFS_BHVTOI(dir_bdp); | ||
82 | 77 | ||
83 | error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum); | 78 | error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum); |
84 | if (!error) { | 79 | if (!error) { |
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h index fe953e98afa7..a00b26d8840e 100644 --- a/fs/xfs/xfs_utils.h +++ b/fs/xfs/xfs_utils.h | |||
@@ -20,13 +20,11 @@ | |||
20 | 20 | ||
21 | #define IRELE(ip) VN_RELE(XFS_ITOV(ip)) | 21 | #define IRELE(ip) VN_RELE(XFS_ITOV(ip)) |
22 | #define IHOLD(ip) VN_HOLD(XFS_ITOV(ip)) | 22 | #define IHOLD(ip) VN_HOLD(XFS_ITOV(ip)) |
23 | #define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \ | 23 | #define ITRACE(ip) vn_trace_ref(ip, __FILE__, __LINE__, \ |
24 | (inst_t *)__return_address) | 24 | (inst_t *)__return_address) |
25 | 25 | ||
26 | extern int xfs_rename (bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *, | ||
27 | bhv_vname_t *, cred_t *); | ||
28 | extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **); | 26 | extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **); |
29 | extern int xfs_dir_lookup_int (bhv_desc_t *, uint, bhv_vname_t *, xfs_ino_t *, | 27 | extern int xfs_dir_lookup_int (xfs_inode_t *, uint, bhv_vname_t *, xfs_ino_t *, |
30 | xfs_inode_t **); | 28 | xfs_inode_t **); |
31 | extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); | 29 | extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); |
32 | extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, | 30 | extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 11f5ea29a038..a5a8454f2a63 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -54,8 +54,9 @@ | |||
54 | #include "xfs_mru_cache.h" | 54 | #include "xfs_mru_cache.h" |
55 | #include "xfs_filestream.h" | 55 | #include "xfs_filestream.h" |
56 | #include "xfs_fsops.h" | 56 | #include "xfs_fsops.h" |
57 | #include "xfs_vnodeops.h" | ||
58 | #include "xfs_vfsops.h" | ||
57 | 59 | ||
58 | STATIC int xfs_sync(bhv_desc_t *, int, cred_t *); | ||
59 | 60 | ||
60 | int | 61 | int |
61 | xfs_init(void) | 62 | xfs_init(void) |
@@ -117,8 +118,8 @@ xfs_init(void) | |||
117 | xfs_ili_zone = | 118 | xfs_ili_zone = |
118 | kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", | 119 | kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", |
119 | KM_ZONE_SPREAD, NULL); | 120 | KM_ZONE_SPREAD, NULL); |
120 | xfs_chashlist_zone = | 121 | xfs_icluster_zone = |
121 | kmem_zone_init_flags(sizeof(xfs_chashlist_t), "xfs_chashlist", | 122 | kmem_zone_init_flags(sizeof(xfs_icluster_t), "xfs_icluster", |
122 | KM_ZONE_SPREAD, NULL); | 123 | KM_ZONE_SPREAD, NULL); |
123 | 124 | ||
124 | /* | 125 | /* |
@@ -163,7 +164,7 @@ xfs_cleanup(void) | |||
163 | extern kmem_zone_t *xfs_efd_zone; | 164 | extern kmem_zone_t *xfs_efd_zone; |
164 | extern kmem_zone_t *xfs_efi_zone; | 165 | extern kmem_zone_t *xfs_efi_zone; |
165 | extern kmem_zone_t *xfs_buf_item_zone; | 166 | extern kmem_zone_t *xfs_buf_item_zone; |
166 | extern kmem_zone_t *xfs_chashlist_zone; | 167 | extern kmem_zone_t *xfs_icluster_zone; |
167 | 168 | ||
168 | xfs_cleanup_procfs(); | 169 | xfs_cleanup_procfs(); |
169 | xfs_sysctl_unregister(); | 170 | xfs_sysctl_unregister(); |
@@ -199,7 +200,7 @@ xfs_cleanup(void) | |||
199 | kmem_zone_destroy(xfs_efi_zone); | 200 | kmem_zone_destroy(xfs_efi_zone); |
200 | kmem_zone_destroy(xfs_ifork_zone); | 201 | kmem_zone_destroy(xfs_ifork_zone); |
201 | kmem_zone_destroy(xfs_ili_zone); | 202 | kmem_zone_destroy(xfs_ili_zone); |
202 | kmem_zone_destroy(xfs_chashlist_zone); | 203 | kmem_zone_destroy(xfs_icluster_zone); |
203 | } | 204 | } |
204 | 205 | ||
205 | /* | 206 | /* |
@@ -210,7 +211,6 @@ xfs_cleanup(void) | |||
210 | */ | 211 | */ |
211 | STATIC int | 212 | STATIC int |
212 | xfs_start_flags( | 213 | xfs_start_flags( |
213 | struct bhv_vfs *vfs, | ||
214 | struct xfs_mount_args *ap, | 214 | struct xfs_mount_args *ap, |
215 | struct xfs_mount *mp) | 215 | struct xfs_mount *mp) |
216 | { | 216 | { |
@@ -238,17 +238,14 @@ xfs_start_flags( | |||
238 | mp->m_logbufs = ap->logbufs; | 238 | mp->m_logbufs = ap->logbufs; |
239 | if (ap->logbufsize != -1 && | 239 | if (ap->logbufsize != -1 && |
240 | ap->logbufsize != 0 && | 240 | ap->logbufsize != 0 && |
241 | ap->logbufsize != 16 * 1024 && | 241 | (ap->logbufsize < XLOG_MIN_RECORD_BSIZE || |
242 | ap->logbufsize != 32 * 1024 && | 242 | ap->logbufsize > XLOG_MAX_RECORD_BSIZE || |
243 | ap->logbufsize != 64 * 1024 && | 243 | !is_power_of_2(ap->logbufsize))) { |
244 | ap->logbufsize != 128 * 1024 && | ||
245 | ap->logbufsize != 256 * 1024) { | ||
246 | cmn_err(CE_WARN, | 244 | cmn_err(CE_WARN, |
247 | "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", | 245 | "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", |
248 | ap->logbufsize); | 246 | ap->logbufsize); |
249 | return XFS_ERROR(EINVAL); | 247 | return XFS_ERROR(EINVAL); |
250 | } | 248 | } |
251 | mp->m_ihsize = ap->ihashsize; | ||
252 | mp->m_logbsize = ap->logbufsize; | 249 | mp->m_logbsize = ap->logbufsize; |
253 | mp->m_fsname_len = strlen(ap->fsname) + 1; | 250 | mp->m_fsname_len = strlen(ap->fsname) + 1; |
254 | mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP); | 251 | mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP); |
@@ -295,8 +292,6 @@ xfs_start_flags( | |||
295 | mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; | 292 | mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; |
296 | } | 293 | } |
297 | 294 | ||
298 | if (ap->flags & XFSMNT_IHASHSIZE) | ||
299 | mp->m_flags |= XFS_MOUNT_IHASHSIZE; | ||
300 | if (ap->flags & XFSMNT_IDELETE) | 295 | if (ap->flags & XFSMNT_IDELETE) |
301 | mp->m_flags |= XFS_MOUNT_IDELETE; | 296 | mp->m_flags |= XFS_MOUNT_IDELETE; |
302 | if (ap->flags & XFSMNT_DIRSYNC) | 297 | if (ap->flags & XFSMNT_DIRSYNC) |
@@ -311,7 +306,7 @@ xfs_start_flags( | |||
311 | * no recovery flag requires a read-only mount | 306 | * no recovery flag requires a read-only mount |
312 | */ | 307 | */ |
313 | if (ap->flags & XFSMNT_NORECOVERY) { | 308 | if (ap->flags & XFSMNT_NORECOVERY) { |
314 | if (!(vfs->vfs_flag & VFS_RDONLY)) { | 309 | if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { |
315 | cmn_err(CE_WARN, | 310 | cmn_err(CE_WARN, |
316 | "XFS: tried to mount a FS read-write without recovery!"); | 311 | "XFS: tried to mount a FS read-write without recovery!"); |
317 | return XFS_ERROR(EINVAL); | 312 | return XFS_ERROR(EINVAL); |
@@ -329,6 +324,8 @@ xfs_start_flags( | |||
329 | if (ap->flags2 & XFSMNT2_FILESTREAMS) | 324 | if (ap->flags2 & XFSMNT2_FILESTREAMS) |
330 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | 325 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; |
331 | 326 | ||
327 | if (ap->flags & XFSMNT_DMAPI) | ||
328 | mp->m_flags |= XFS_MOUNT_DMAPI; | ||
332 | return 0; | 329 | return 0; |
333 | } | 330 | } |
334 | 331 | ||
@@ -338,11 +335,10 @@ xfs_start_flags( | |||
338 | */ | 335 | */ |
339 | STATIC int | 336 | STATIC int |
340 | xfs_finish_flags( | 337 | xfs_finish_flags( |
341 | struct bhv_vfs *vfs, | ||
342 | struct xfs_mount_args *ap, | 338 | struct xfs_mount_args *ap, |
343 | struct xfs_mount *mp) | 339 | struct xfs_mount *mp) |
344 | { | 340 | { |
345 | int ronly = (vfs->vfs_flag & VFS_RDONLY); | 341 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); |
346 | 342 | ||
347 | /* Fail a mount where the logbuf is smaller then the log stripe */ | 343 | /* Fail a mount where the logbuf is smaller then the log stripe */ |
348 | if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) { | 344 | if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) { |
@@ -403,6 +399,22 @@ xfs_finish_flags( | |||
403 | return XFS_ERROR(EINVAL); | 399 | return XFS_ERROR(EINVAL); |
404 | } | 400 | } |
405 | 401 | ||
402 | if (ap->flags & XFSMNT_UQUOTA) { | ||
403 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); | ||
404 | if (ap->flags & XFSMNT_UQUOTAENF) | ||
405 | mp->m_qflags |= XFS_UQUOTA_ENFD; | ||
406 | } | ||
407 | |||
408 | if (ap->flags & XFSMNT_GQUOTA) { | ||
409 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | ||
410 | if (ap->flags & XFSMNT_GQUOTAENF) | ||
411 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
412 | } else if (ap->flags & XFSMNT_PQUOTA) { | ||
413 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | ||
414 | if (ap->flags & XFSMNT_PQUOTAENF) | ||
415 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
416 | } | ||
417 | |||
406 | return 0; | 418 | return 0; |
407 | } | 419 | } |
408 | 420 | ||
@@ -418,30 +430,26 @@ xfs_finish_flags( | |||
418 | * they are present. The data subvolume has already been opened by | 430 | * they are present. The data subvolume has already been opened by |
419 | * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev. | 431 | * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev. |
420 | */ | 432 | */ |
421 | STATIC int | 433 | int |
422 | xfs_mount( | 434 | xfs_mount( |
423 | struct bhv_desc *bhvp, | 435 | struct xfs_mount *mp, |
424 | struct xfs_mount_args *args, | 436 | struct xfs_mount_args *args, |
425 | cred_t *credp) | 437 | cred_t *credp) |
426 | { | 438 | { |
427 | struct bhv_vfs *vfsp = bhvtovfs(bhvp); | ||
428 | struct bhv_desc *p; | ||
429 | struct xfs_mount *mp = XFS_BHVTOM(bhvp); | ||
430 | struct block_device *ddev, *logdev, *rtdev; | 439 | struct block_device *ddev, *logdev, *rtdev; |
431 | int flags = 0, error; | 440 | int flags = 0, error; |
432 | 441 | ||
433 | ddev = vfsp->vfs_super->s_bdev; | 442 | ddev = mp->m_super->s_bdev; |
434 | logdev = rtdev = NULL; | 443 | logdev = rtdev = NULL; |
435 | 444 | ||
436 | /* | 445 | error = xfs_dmops_get(mp, args); |
437 | * Setup xfs_mount function vectors from available behaviors | 446 | if (error) |
438 | */ | 447 | return error; |
439 | p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM); | 448 | error = xfs_qmops_get(mp, args); |
440 | mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub; | 449 | if (error) |
441 | p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM); | 450 | return error; |
442 | mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub; | 451 | |
443 | p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); | 452 | mp->m_io_ops = xfs_iocore_xfs; |
444 | mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs; | ||
445 | 453 | ||
446 | if (args->flags & XFSMNT_QUIET) | 454 | if (args->flags & XFSMNT_QUIET) |
447 | flags |= XFS_MFSI_QUIET; | 455 | flags |= XFS_MFSI_QUIET; |
@@ -482,24 +490,30 @@ xfs_mount( | |||
482 | } | 490 | } |
483 | if (rtdev) { | 491 | if (rtdev) { |
484 | mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1); | 492 | mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1); |
485 | if (!mp->m_rtdev_targp) | 493 | if (!mp->m_rtdev_targp) { |
494 | xfs_blkdev_put(logdev); | ||
495 | xfs_blkdev_put(rtdev); | ||
486 | goto error0; | 496 | goto error0; |
497 | } | ||
487 | } | 498 | } |
488 | mp->m_logdev_targp = (logdev && logdev != ddev) ? | 499 | mp->m_logdev_targp = (logdev && logdev != ddev) ? |
489 | xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp; | 500 | xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp; |
490 | if (!mp->m_logdev_targp) | 501 | if (!mp->m_logdev_targp) { |
502 | xfs_blkdev_put(logdev); | ||
503 | xfs_blkdev_put(rtdev); | ||
491 | goto error0; | 504 | goto error0; |
505 | } | ||
492 | 506 | ||
493 | /* | 507 | /* |
494 | * Setup flags based on mount(2) options and then the superblock | 508 | * Setup flags based on mount(2) options and then the superblock |
495 | */ | 509 | */ |
496 | error = xfs_start_flags(vfsp, args, mp); | 510 | error = xfs_start_flags(args, mp); |
497 | if (error) | 511 | if (error) |
498 | goto error1; | 512 | goto error1; |
499 | error = xfs_readsb(mp, flags); | 513 | error = xfs_readsb(mp, flags); |
500 | if (error) | 514 | if (error) |
501 | goto error1; | 515 | goto error1; |
502 | error = xfs_finish_flags(vfsp, args, mp); | 516 | error = xfs_finish_flags(args, mp); |
503 | if (error) | 517 | if (error) |
504 | goto error2; | 518 | goto error2; |
505 | 519 | ||
@@ -530,10 +544,12 @@ xfs_mount( | |||
530 | if ((error = xfs_filestream_mount(mp))) | 544 | if ((error = xfs_filestream_mount(mp))) |
531 | goto error2; | 545 | goto error2; |
532 | 546 | ||
533 | error = XFS_IOINIT(vfsp, args, flags); | 547 | error = XFS_IOINIT(mp, args, flags); |
534 | if (error) | 548 | if (error) |
535 | goto error2; | 549 | goto error2; |
536 | 550 | ||
551 | XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname); | ||
552 | |||
537 | return 0; | 553 | return 0; |
538 | 554 | ||
539 | error2: | 555 | error2: |
@@ -547,17 +563,17 @@ error1: | |||
547 | xfs_binval(mp->m_rtdev_targp); | 563 | xfs_binval(mp->m_rtdev_targp); |
548 | error0: | 564 | error0: |
549 | xfs_unmountfs_close(mp, credp); | 565 | xfs_unmountfs_close(mp, credp); |
566 | xfs_qmops_put(mp); | ||
567 | xfs_dmops_put(mp); | ||
550 | return error; | 568 | return error; |
551 | } | 569 | } |
552 | 570 | ||
553 | STATIC int | 571 | int |
554 | xfs_unmount( | 572 | xfs_unmount( |
555 | bhv_desc_t *bdp, | 573 | xfs_mount_t *mp, |
556 | int flags, | 574 | int flags, |
557 | cred_t *credp) | 575 | cred_t *credp) |
558 | { | 576 | { |
559 | bhv_vfs_t *vfsp = bhvtovfs(bdp); | ||
560 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | ||
561 | xfs_inode_t *rip; | 577 | xfs_inode_t *rip; |
562 | bhv_vnode_t *rvp; | 578 | bhv_vnode_t *rvp; |
563 | int unmount_event_wanted = 0; | 579 | int unmount_event_wanted = 0; |
@@ -568,8 +584,9 @@ xfs_unmount( | |||
568 | rip = mp->m_rootip; | 584 | rip = mp->m_rootip; |
569 | rvp = XFS_ITOV(rip); | 585 | rvp = XFS_ITOV(rip); |
570 | 586 | ||
571 | if (vfsp->vfs_flag & VFS_DMI) { | 587 | #ifdef HAVE_DMAPI |
572 | error = XFS_SEND_PREUNMOUNT(mp, vfsp, | 588 | if (mp->m_flags & XFS_MOUNT_DMAPI) { |
589 | error = XFS_SEND_PREUNMOUNT(mp, | ||
573 | rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL, | 590 | rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL, |
574 | NULL, NULL, 0, 0, | 591 | NULL, NULL, 0, 0, |
575 | (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))? | 592 | (mp->m_dmevmask & (1<<DM_EVENT_PREUNMOUNT))? |
@@ -580,7 +597,7 @@ xfs_unmount( | |||
580 | unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))? | 597 | unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))? |
581 | 0 : DM_FLAGS_UNWANTED; | 598 | 0 : DM_FLAGS_UNWANTED; |
582 | } | 599 | } |
583 | 600 | #endif | |
584 | /* | 601 | /* |
585 | * First blow any referenced inode from this file system | 602 | * First blow any referenced inode from this file system |
586 | * out of the reference cache, and delete the timer. | 603 | * out of the reference cache, and delete the timer. |
@@ -612,8 +629,7 @@ xfs_unmount( | |||
612 | * referenced vnodes as well. | 629 | * referenced vnodes as well. |
613 | */ | 630 | */ |
614 | if (XFS_FORCED_SHUTDOWN(mp)) { | 631 | if (XFS_FORCED_SHUTDOWN(mp)) { |
615 | error = xfs_sync(&mp->m_bhv, | 632 | error = xfs_sync(mp, SYNC_WAIT | SYNC_CLOSE); |
616 | (SYNC_WAIT | SYNC_CLOSE), credp); | ||
617 | ASSERT(error != EFSCORRUPTED); | 633 | ASSERT(error != EFSCORRUPTED); |
618 | } | 634 | } |
619 | xfs_unmountfs_needed = 1; | 635 | xfs_unmountfs_needed = 1; |
@@ -627,7 +643,7 @@ out: | |||
627 | /* Note: mp structure must still exist for | 643 | /* Note: mp structure must still exist for |
628 | * XFS_SEND_UNMOUNT() call. | 644 | * XFS_SEND_UNMOUNT() call. |
629 | */ | 645 | */ |
630 | XFS_SEND_UNMOUNT(mp, vfsp, error == 0 ? rvp : NULL, | 646 | XFS_SEND_UNMOUNT(mp, error == 0 ? rvp : NULL, |
631 | DM_RIGHT_NULL, 0, error, unmount_event_flags); | 647 | DM_RIGHT_NULL, 0, error, unmount_event_flags); |
632 | } | 648 | } |
633 | if (xfs_unmountfs_needed) { | 649 | if (xfs_unmountfs_needed) { |
@@ -636,6 +652,9 @@ out: | |||
636 | * and free the super block buffer & mount structures. | 652 | * and free the super block buffer & mount structures. |
637 | */ | 653 | */ |
638 | xfs_unmountfs(mp, credp); | 654 | xfs_unmountfs(mp, credp); |
655 | xfs_qmops_put(mp); | ||
656 | xfs_dmops_put(mp); | ||
657 | kmem_free(mp, sizeof(xfs_mount_t)); | ||
639 | } | 658 | } |
640 | 659 | ||
641 | return XFS_ERROR(error); | 660 | return XFS_ERROR(error); |
@@ -694,29 +713,26 @@ xfs_attr_quiesce( | |||
694 | xfs_unmountfs_writesb(mp); | 713 | xfs_unmountfs_writesb(mp); |
695 | } | 714 | } |
696 | 715 | ||
697 | STATIC int | 716 | int |
698 | xfs_mntupdate( | 717 | xfs_mntupdate( |
699 | bhv_desc_t *bdp, | 718 | struct xfs_mount *mp, |
700 | int *flags, | 719 | int *flags, |
701 | struct xfs_mount_args *args) | 720 | struct xfs_mount_args *args) |
702 | { | 721 | { |
703 | bhv_vfs_t *vfsp = bhvtovfs(bdp); | ||
704 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | ||
705 | |||
706 | if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ | 722 | if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ |
707 | if (vfsp->vfs_flag & VFS_RDONLY) | 723 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
708 | vfsp->vfs_flag &= ~VFS_RDONLY; | 724 | mp->m_flags &= ~XFS_MOUNT_RDONLY; |
709 | if (args->flags & XFSMNT_BARRIER) { | 725 | if (args->flags & XFSMNT_BARRIER) { |
710 | mp->m_flags |= XFS_MOUNT_BARRIER; | 726 | mp->m_flags |= XFS_MOUNT_BARRIER; |
711 | xfs_mountfs_check_barriers(mp); | 727 | xfs_mountfs_check_barriers(mp); |
712 | } else { | 728 | } else { |
713 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 729 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
714 | } | 730 | } |
715 | } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ | 731 | } else if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { /* rw -> ro */ |
716 | xfs_filestream_flush(mp); | 732 | xfs_filestream_flush(mp); |
717 | bhv_vfs_sync(vfsp, SYNC_DATA_QUIESCE, NULL); | 733 | xfs_sync(mp, SYNC_DATA_QUIESCE); |
718 | xfs_attr_quiesce(mp); | 734 | xfs_attr_quiesce(mp); |
719 | vfsp->vfs_flag |= VFS_RDONLY; | 735 | mp->m_flags |= XFS_MOUNT_RDONLY; |
720 | } | 736 | } |
721 | return 0; | 737 | return 0; |
722 | } | 738 | } |
@@ -811,14 +827,14 @@ fscorrupt_out2: | |||
811 | * vpp -- address of the caller's vnode pointer which should be | 827 | * vpp -- address of the caller's vnode pointer which should be |
812 | * set to the desired fs root vnode | 828 | * set to the desired fs root vnode |
813 | */ | 829 | */ |
814 | STATIC int | 830 | int |
815 | xfs_root( | 831 | xfs_root( |
816 | bhv_desc_t *bdp, | 832 | xfs_mount_t *mp, |
817 | bhv_vnode_t **vpp) | 833 | bhv_vnode_t **vpp) |
818 | { | 834 | { |
819 | bhv_vnode_t *vp; | 835 | bhv_vnode_t *vp; |
820 | 836 | ||
821 | vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); | 837 | vp = XFS_ITOV(mp->m_rootip); |
822 | VN_HOLD(vp); | 838 | VN_HOLD(vp); |
823 | *vpp = vp; | 839 | *vpp = vp; |
824 | return 0; | 840 | return 0; |
@@ -831,19 +847,17 @@ xfs_root( | |||
831 | * the superblock lock in the mount structure to ensure a consistent | 847 | * the superblock lock in the mount structure to ensure a consistent |
832 | * snapshot of the counters returned. | 848 | * snapshot of the counters returned. |
833 | */ | 849 | */ |
834 | STATIC int | 850 | int |
835 | xfs_statvfs( | 851 | xfs_statvfs( |
836 | bhv_desc_t *bdp, | 852 | xfs_mount_t *mp, |
837 | bhv_statvfs_t *statp, | 853 | bhv_statvfs_t *statp, |
838 | bhv_vnode_t *vp) | 854 | bhv_vnode_t *vp) |
839 | { | 855 | { |
840 | __uint64_t fakeinos; | 856 | __uint64_t fakeinos; |
841 | xfs_extlen_t lsize; | 857 | xfs_extlen_t lsize; |
842 | xfs_mount_t *mp; | ||
843 | xfs_sb_t *sbp; | 858 | xfs_sb_t *sbp; |
844 | unsigned long s; | 859 | unsigned long s; |
845 | 860 | ||
846 | mp = XFS_BHVTOM(bdp); | ||
847 | sbp = &(mp->m_sb); | 861 | sbp = &(mp->m_sb); |
848 | 862 | ||
849 | statp->f_type = XFS_SB_MAGIC; | 863 | statp->f_type = XFS_SB_MAGIC; |
@@ -874,6 +888,8 @@ xfs_statvfs( | |||
874 | xfs_statvfs_fsid(statp, mp); | 888 | xfs_statvfs_fsid(statp, mp); |
875 | statp->f_namelen = MAXNAMELEN - 1; | 889 | statp->f_namelen = MAXNAMELEN - 1; |
876 | 890 | ||
891 | if (vp) | ||
892 | XFS_QM_DQSTATVFS(xfs_vtoi(vp), statp); | ||
877 | return 0; | 893 | return 0; |
878 | } | 894 | } |
879 | 895 | ||
@@ -920,14 +936,30 @@ xfs_statvfs( | |||
920 | * filesystem. | 936 | * filesystem. |
921 | * | 937 | * |
922 | */ | 938 | */ |
923 | /*ARGSUSED*/ | 939 | int |
924 | STATIC int | ||
925 | xfs_sync( | 940 | xfs_sync( |
926 | bhv_desc_t *bdp, | 941 | xfs_mount_t *mp, |
927 | int flags, | 942 | int flags) |
928 | cred_t *credp) | ||
929 | { | 943 | { |
930 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 944 | int error; |
945 | |||
946 | /* | ||
947 | * Get the Quota Manager to flush the dquots. | ||
948 | * | ||
949 | * If XFS quota support is not enabled or this filesystem | ||
950 | * instance does not use quotas XFS_QM_DQSYNC will always | ||
951 | * return zero. | ||
952 | */ | ||
953 | error = XFS_QM_DQSYNC(mp, flags); | ||
954 | if (error) { | ||
955 | /* | ||
956 | * If we got an IO error, we will be shutting down. | ||
957 | * So, there's nothing more for us to do here. | ||
958 | */ | ||
959 | ASSERT(error != EIO || XFS_FORCED_SHUTDOWN(mp)); | ||
960 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
961 | return XFS_ERROR(error); | ||
962 | } | ||
931 | 963 | ||
932 | if (flags & SYNC_IOWAIT) | 964 | if (flags & SYNC_IOWAIT) |
933 | xfs_filestream_flush(mp); | 965 | xfs_filestream_flush(mp); |
@@ -1015,7 +1047,7 @@ xfs_sync_inodes( | |||
1015 | 1047 | ||
1016 | if (bypassed) | 1048 | if (bypassed) |
1017 | *bypassed = 0; | 1049 | *bypassed = 0; |
1018 | if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) | 1050 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
1019 | return 0; | 1051 | return 0; |
1020 | error = 0; | 1052 | error = 0; |
1021 | last_error = 0; | 1053 | last_error = 0; |
@@ -1189,12 +1221,13 @@ xfs_sync_inodes( | |||
1189 | if (flags & SYNC_CLOSE) { | 1221 | if (flags & SYNC_CLOSE) { |
1190 | /* Shutdown case. Flush and invalidate. */ | 1222 | /* Shutdown case. Flush and invalidate. */ |
1191 | if (XFS_FORCED_SHUTDOWN(mp)) | 1223 | if (XFS_FORCED_SHUTDOWN(mp)) |
1192 | bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); | 1224 | xfs_tosspages(ip, 0, -1, |
1225 | FI_REMAPF); | ||
1193 | else | 1226 | else |
1194 | error = bhv_vop_flushinval_pages(vp, 0, | 1227 | error = xfs_flushinval_pages(ip, |
1195 | -1, FI_REMAPF); | 1228 | 0, -1, FI_REMAPF); |
1196 | } else if ((flags & SYNC_DELWRI) && VN_DIRTY(vp)) { | 1229 | } else if ((flags & SYNC_DELWRI) && VN_DIRTY(vp)) { |
1197 | error = bhv_vop_flush_pages(vp, (xfs_off_t)0, | 1230 | error = xfs_flush_pages(ip, 0, |
1198 | -1, fflag, FI_NONE); | 1231 | -1, fflag, FI_NONE); |
1199 | } | 1232 | } |
1200 | 1233 | ||
@@ -1204,7 +1237,7 @@ xfs_sync_inodes( | |||
1204 | * place after this point | 1237 | * place after this point |
1205 | */ | 1238 | */ |
1206 | if (flags & SYNC_IOWAIT) | 1239 | if (flags & SYNC_IOWAIT) |
1207 | vn_iowait(vp); | 1240 | vn_iowait(ip); |
1208 | 1241 | ||
1209 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 1242 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
1210 | } | 1243 | } |
@@ -1598,13 +1631,12 @@ xfs_syncsub( | |||
1598 | /* | 1631 | /* |
1599 | * xfs_vget - called by DMAPI and NFSD to get vnode from file handle | 1632 | * xfs_vget - called by DMAPI and NFSD to get vnode from file handle |
1600 | */ | 1633 | */ |
1601 | STATIC int | 1634 | int |
1602 | xfs_vget( | 1635 | xfs_vget( |
1603 | bhv_desc_t *bdp, | 1636 | xfs_mount_t *mp, |
1604 | bhv_vnode_t **vpp, | 1637 | bhv_vnode_t **vpp, |
1605 | fid_t *fidp) | 1638 | fid_t *fidp) |
1606 | { | 1639 | { |
1607 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | ||
1608 | xfs_fid_t *xfid = (struct xfs_fid *)fidp; | 1640 | xfs_fid_t *xfid = (struct xfs_fid *)fidp; |
1609 | xfs_inode_t *ip; | 1641 | xfs_inode_t *ip; |
1610 | int error; | 1642 | int error; |
@@ -1668,7 +1700,6 @@ xfs_vget( | |||
1668 | #define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ | 1700 | #define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ |
1669 | #define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ | 1701 | #define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ |
1670 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ | 1702 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ |
1671 | #define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */ | ||
1672 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ | 1703 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ |
1673 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and | 1704 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and |
1674 | * unwritten extent conversion */ | 1705 | * unwritten extent conversion */ |
@@ -1683,6 +1714,21 @@ xfs_vget( | |||
1683 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ | 1714 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ |
1684 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ | 1715 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ |
1685 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ | 1716 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ |
1717 | #define MNTOPT_QUOTA "quota" /* disk quotas (user) */ | ||
1718 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ | ||
1719 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ | ||
1720 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ | ||
1721 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ | ||
1722 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ | ||
1723 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ | ||
1724 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ | ||
1725 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ | ||
1726 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | ||
1727 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | ||
1728 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | ||
1729 | #define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */ | ||
1730 | #define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */ | ||
1731 | #define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */ | ||
1686 | 1732 | ||
1687 | STATIC unsigned long | 1733 | STATIC unsigned long |
1688 | suffix_strtoul(char *s, char **endp, unsigned int base) | 1734 | suffix_strtoul(char *s, char **endp, unsigned int base) |
@@ -1707,19 +1753,18 @@ suffix_strtoul(char *s, char **endp, unsigned int base) | |||
1707 | return simple_strtoul((const char *)s, endp, base) << shift_left_factor; | 1753 | return simple_strtoul((const char *)s, endp, base) << shift_left_factor; |
1708 | } | 1754 | } |
1709 | 1755 | ||
1710 | STATIC int | 1756 | int |
1711 | xfs_parseargs( | 1757 | xfs_parseargs( |
1712 | struct bhv_desc *bhv, | 1758 | struct xfs_mount *mp, |
1713 | char *options, | 1759 | char *options, |
1714 | struct xfs_mount_args *args, | 1760 | struct xfs_mount_args *args, |
1715 | int update) | 1761 | int update) |
1716 | { | 1762 | { |
1717 | bhv_vfs_t *vfsp = bhvtovfs(bhv); | ||
1718 | char *this_char, *value, *eov; | 1763 | char *this_char, *value, *eov; |
1719 | int dsunit, dswidth, vol_dsunit, vol_dswidth; | 1764 | int dsunit, dswidth, vol_dsunit, vol_dswidth; |
1720 | int iosize; | 1765 | int iosize; |
1766 | int ikeep = 0; | ||
1721 | 1767 | ||
1722 | args->flags |= XFSMNT_IDELETE; | ||
1723 | args->flags |= XFSMNT_BARRIER; | 1768 | args->flags |= XFSMNT_BARRIER; |
1724 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; | 1769 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; |
1725 | 1770 | ||
@@ -1794,21 +1839,12 @@ xfs_parseargs( | |||
1794 | iosize = suffix_strtoul(value, &eov, 10); | 1839 | iosize = suffix_strtoul(value, &eov, 10); |
1795 | args->flags |= XFSMNT_IOSIZE; | 1840 | args->flags |= XFSMNT_IOSIZE; |
1796 | args->iosizelog = ffs(iosize) - 1; | 1841 | args->iosizelog = ffs(iosize) - 1; |
1797 | } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { | ||
1798 | if (!value || !*value) { | ||
1799 | cmn_err(CE_WARN, | ||
1800 | "XFS: %s option requires an argument", | ||
1801 | this_char); | ||
1802 | return EINVAL; | ||
1803 | } | ||
1804 | args->flags |= XFSMNT_IHASHSIZE; | ||
1805 | args->ihashsize = simple_strtoul(value, &eov, 10); | ||
1806 | } else if (!strcmp(this_char, MNTOPT_GRPID) || | 1842 | } else if (!strcmp(this_char, MNTOPT_GRPID) || |
1807 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { | 1843 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { |
1808 | vfsp->vfs_flag |= VFS_GRPID; | 1844 | mp->m_flags |= XFS_MOUNT_GRPID; |
1809 | } else if (!strcmp(this_char, MNTOPT_NOGRPID) || | 1845 | } else if (!strcmp(this_char, MNTOPT_NOGRPID) || |
1810 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { | 1846 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { |
1811 | vfsp->vfs_flag &= ~VFS_GRPID; | 1847 | mp->m_flags &= ~XFS_MOUNT_GRPID; |
1812 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { | 1848 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { |
1813 | args->flags |= XFSMNT_WSYNC; | 1849 | args->flags |= XFSMNT_WSYNC; |
1814 | } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { | 1850 | } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) { |
@@ -1858,6 +1894,7 @@ xfs_parseargs( | |||
1858 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { | 1894 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { |
1859 | args->flags &= ~XFSMNT_BARRIER; | 1895 | args->flags &= ~XFSMNT_BARRIER; |
1860 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { | 1896 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { |
1897 | ikeep = 1; | ||
1861 | args->flags &= ~XFSMNT_IDELETE; | 1898 | args->flags &= ~XFSMNT_IDELETE; |
1862 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { | 1899 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { |
1863 | args->flags |= XFSMNT_IDELETE; | 1900 | args->flags |= XFSMNT_IDELETE; |
@@ -1871,6 +1908,38 @@ xfs_parseargs( | |||
1871 | args->flags &= ~XFSMNT_ATTR2; | 1908 | args->flags &= ~XFSMNT_ATTR2; |
1872 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { | 1909 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { |
1873 | args->flags2 |= XFSMNT2_FILESTREAMS; | 1910 | args->flags2 |= XFSMNT2_FILESTREAMS; |
1911 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { | ||
1912 | args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA); | ||
1913 | args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA); | ||
1914 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || | ||
1915 | !strcmp(this_char, MNTOPT_UQUOTA) || | ||
1916 | !strcmp(this_char, MNTOPT_USRQUOTA)) { | ||
1917 | args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF; | ||
1918 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || | ||
1919 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { | ||
1920 | args->flags |= XFSMNT_UQUOTA; | ||
1921 | args->flags &= ~XFSMNT_UQUOTAENF; | ||
1922 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | ||
1923 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | ||
1924 | args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF; | ||
1925 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | ||
1926 | args->flags |= XFSMNT_PQUOTA; | ||
1927 | args->flags &= ~XFSMNT_PQUOTAENF; | ||
1928 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | ||
1929 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | ||
1930 | args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; | ||
1931 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { | ||
1932 | args->flags |= XFSMNT_GQUOTA; | ||
1933 | args->flags &= ~XFSMNT_GQUOTAENF; | ||
1934 | } else if (!strcmp(this_char, MNTOPT_DMAPI)) { | ||
1935 | args->flags |= XFSMNT_DMAPI; | ||
1936 | } else if (!strcmp(this_char, MNTOPT_XDSM)) { | ||
1937 | args->flags |= XFSMNT_DMAPI; | ||
1938 | } else if (!strcmp(this_char, MNTOPT_DMI)) { | ||
1939 | args->flags |= XFSMNT_DMAPI; | ||
1940 | } else if (!strcmp(this_char, "ihashsize")) { | ||
1941 | cmn_err(CE_WARN, | ||
1942 | "XFS: ihashsize no longer used, option is deprecated."); | ||
1874 | } else if (!strcmp(this_char, "osyncisdsync")) { | 1943 | } else if (!strcmp(this_char, "osyncisdsync")) { |
1875 | /* no-op, this is now the default */ | 1944 | /* no-op, this is now the default */ |
1876 | cmn_err(CE_WARN, | 1945 | cmn_err(CE_WARN, |
@@ -1886,7 +1955,7 @@ xfs_parseargs( | |||
1886 | } | 1955 | } |
1887 | 1956 | ||
1888 | if (args->flags & XFSMNT_NORECOVERY) { | 1957 | if (args->flags & XFSMNT_NORECOVERY) { |
1889 | if ((vfsp->vfs_flag & VFS_RDONLY) == 0) { | 1958 | if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) { |
1890 | cmn_err(CE_WARN, | 1959 | cmn_err(CE_WARN, |
1891 | "XFS: no-recovery mounts must be read-only."); | 1960 | "XFS: no-recovery mounts must be read-only."); |
1892 | return EINVAL; | 1961 | return EINVAL; |
@@ -1899,6 +1968,18 @@ xfs_parseargs( | |||
1899 | return EINVAL; | 1968 | return EINVAL; |
1900 | } | 1969 | } |
1901 | 1970 | ||
1971 | if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) { | ||
1972 | cmn_err(CE_WARN, | ||
1973 | "XFS: cannot mount with both project and group quota"); | ||
1974 | return EINVAL; | ||
1975 | } | ||
1976 | |||
1977 | if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') { | ||
1978 | printk("XFS: %s option needs the mount point option as well\n", | ||
1979 | MNTOPT_DMAPI); | ||
1980 | return EINVAL; | ||
1981 | } | ||
1982 | |||
1902 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { | 1983 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { |
1903 | cmn_err(CE_WARN, | 1984 | cmn_err(CE_WARN, |
1904 | "XFS: sunit and swidth must be specified together"); | 1985 | "XFS: sunit and swidth must be specified together"); |
@@ -1912,6 +1993,18 @@ xfs_parseargs( | |||
1912 | return EINVAL; | 1993 | return EINVAL; |
1913 | } | 1994 | } |
1914 | 1995 | ||
1996 | /* | ||
1997 | * Applications using DMI filesystems often expect the | ||
1998 | * inode generation number to be monotonically increasing. | ||
1999 | * If we delete inode chunks we break this assumption, so | ||
2000 | * keep unused inode chunks on disk for DMI filesystems | ||
2001 | * until we come up with a better solution. | ||
2002 | * Note that if "ikeep" or "noikeep" mount options are | ||
2003 | * supplied, then they are honored. | ||
2004 | */ | ||
2005 | if (!(args->flags & XFSMNT_DMAPI) && !ikeep) | ||
2006 | args->flags |= XFSMNT_IDELETE; | ||
2007 | |||
1915 | if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { | 2008 | if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { |
1916 | if (dsunit) { | 2009 | if (dsunit) { |
1917 | args->sunit = dsunit; | 2010 | args->sunit = dsunit; |
@@ -1927,15 +2020,15 @@ xfs_parseargs( | |||
1927 | 2020 | ||
1928 | done: | 2021 | done: |
1929 | if (args->flags & XFSMNT_32BITINODES) | 2022 | if (args->flags & XFSMNT_32BITINODES) |
1930 | vfsp->vfs_flag |= VFS_32BITINODES; | 2023 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
1931 | if (args->flags2) | 2024 | if (args->flags2) |
1932 | args->flags |= XFSMNT_FLAGS2; | 2025 | args->flags |= XFSMNT_FLAGS2; |
1933 | return 0; | 2026 | return 0; |
1934 | } | 2027 | } |
1935 | 2028 | ||
1936 | STATIC int | 2029 | int |
1937 | xfs_showargs( | 2030 | xfs_showargs( |
1938 | struct bhv_desc *bhv, | 2031 | struct xfs_mount *mp, |
1939 | struct seq_file *m) | 2032 | struct seq_file *m) |
1940 | { | 2033 | { |
1941 | static struct proc_xfs_info { | 2034 | static struct proc_xfs_info { |
@@ -1953,17 +2046,12 @@ xfs_showargs( | |||
1953 | { 0, NULL } | 2046 | { 0, NULL } |
1954 | }; | 2047 | }; |
1955 | struct proc_xfs_info *xfs_infop; | 2048 | struct proc_xfs_info *xfs_infop; |
1956 | struct xfs_mount *mp = XFS_BHVTOM(bhv); | ||
1957 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); | ||
1958 | 2049 | ||
1959 | for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { | 2050 | for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { |
1960 | if (mp->m_flags & xfs_infop->flag) | 2051 | if (mp->m_flags & xfs_infop->flag) |
1961 | seq_puts(m, xfs_infop->str); | 2052 | seq_puts(m, xfs_infop->str); |
1962 | } | 2053 | } |
1963 | 2054 | ||
1964 | if (mp->m_flags & XFS_MOUNT_IHASHSIZE) | ||
1965 | seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", (int)mp->m_ihsize); | ||
1966 | |||
1967 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) | 2055 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) |
1968 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", | 2056 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", |
1969 | (int)(1 << mp->m_writeio_log) >> 10); | 2057 | (int)(1 << mp->m_writeio_log) >> 10); |
@@ -1990,11 +2078,37 @@ xfs_showargs( | |||
1990 | if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)) | 2078 | if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)) |
1991 | seq_printf(m, "," MNTOPT_LARGEIO); | 2079 | seq_printf(m, "," MNTOPT_LARGEIO); |
1992 | 2080 | ||
1993 | if (!(vfsp->vfs_flag & VFS_32BITINODES)) | 2081 | if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS)) |
1994 | seq_printf(m, "," MNTOPT_64BITINODE); | 2082 | seq_printf(m, "," MNTOPT_64BITINODE); |
1995 | if (vfsp->vfs_flag & VFS_GRPID) | 2083 | if (mp->m_flags & XFS_MOUNT_GRPID) |
1996 | seq_printf(m, "," MNTOPT_GRPID); | 2084 | seq_printf(m, "," MNTOPT_GRPID); |
1997 | 2085 | ||
2086 | if (mp->m_qflags & XFS_UQUOTA_ACCT) { | ||
2087 | if (mp->m_qflags & XFS_UQUOTA_ENFD) | ||
2088 | seq_puts(m, "," MNTOPT_USRQUOTA); | ||
2089 | else | ||
2090 | seq_puts(m, "," MNTOPT_UQUOTANOENF); | ||
2091 | } | ||
2092 | |||
2093 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { | ||
2094 | if (mp->m_qflags & XFS_OQUOTA_ENFD) | ||
2095 | seq_puts(m, "," MNTOPT_PRJQUOTA); | ||
2096 | else | ||
2097 | seq_puts(m, "," MNTOPT_PQUOTANOENF); | ||
2098 | } | ||
2099 | |||
2100 | if (mp->m_qflags & XFS_GQUOTA_ACCT) { | ||
2101 | if (mp->m_qflags & XFS_OQUOTA_ENFD) | ||
2102 | seq_puts(m, "," MNTOPT_GRPQUOTA); | ||
2103 | else | ||
2104 | seq_puts(m, "," MNTOPT_GQUOTANOENF); | ||
2105 | } | ||
2106 | |||
2107 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) | ||
2108 | seq_puts(m, "," MNTOPT_NOQUOTA); | ||
2109 | |||
2110 | if (mp->m_flags & XFS_MOUNT_DMAPI) | ||
2111 | seq_puts(m, "," MNTOPT_DMAPI); | ||
1998 | return 0; | 2112 | return 0; |
1999 | } | 2113 | } |
2000 | 2114 | ||
@@ -2003,31 +2117,10 @@ xfs_showargs( | |||
2003 | * need to take care of themetadata. Once that's done write a dummy | 2117 | * need to take care of themetadata. Once that's done write a dummy |
2004 | * record to dirty the log in case of a crash while frozen. | 2118 | * record to dirty the log in case of a crash while frozen. |
2005 | */ | 2119 | */ |
2006 | STATIC void | 2120 | void |
2007 | xfs_freeze( | 2121 | xfs_freeze( |
2008 | bhv_desc_t *bdp) | 2122 | xfs_mount_t *mp) |
2009 | { | 2123 | { |
2010 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | ||
2011 | |||
2012 | xfs_attr_quiesce(mp); | 2124 | xfs_attr_quiesce(mp); |
2013 | xfs_fs_log_dummy(mp); | 2125 | xfs_fs_log_dummy(mp); |
2014 | } | 2126 | } |
2015 | |||
2016 | |||
2017 | bhv_vfsops_t xfs_vfsops = { | ||
2018 | BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS), | ||
2019 | .vfs_parseargs = xfs_parseargs, | ||
2020 | .vfs_showargs = xfs_showargs, | ||
2021 | .vfs_mount = xfs_mount, | ||
2022 | .vfs_unmount = xfs_unmount, | ||
2023 | .vfs_mntupdate = xfs_mntupdate, | ||
2024 | .vfs_root = xfs_root, | ||
2025 | .vfs_statvfs = xfs_statvfs, | ||
2026 | .vfs_sync = xfs_sync, | ||
2027 | .vfs_vget = xfs_vget, | ||
2028 | .vfs_dmapiops = (vfs_dmapiops_t)fs_nosys, | ||
2029 | .vfs_quotactl = (vfs_quotactl_t)fs_nosys, | ||
2030 | .vfs_init_vnode = xfs_initialize_vnode, | ||
2031 | .vfs_force_shutdown = xfs_do_force_shutdown, | ||
2032 | .vfs_freeze = xfs_freeze, | ||
2033 | }; | ||
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h new file mode 100644 index 000000000000..bc99e3eb7dbb --- /dev/null +++ b/fs/xfs/xfs_vfsops.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef _XFS_VFSOPS_H | ||
2 | #define _XFS_VFSOPS_H 1 | ||
3 | |||
4 | struct cred; | ||
5 | struct fid; | ||
6 | struct inode; | ||
7 | struct kstatfs; | ||
8 | struct xfs_mount; | ||
9 | struct xfs_mount_args; | ||
10 | |||
11 | int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args, | ||
12 | struct cred *credp); | ||
13 | int xfs_unmount(struct xfs_mount *mp, int flags, struct cred *credp); | ||
14 | int xfs_mntupdate(struct xfs_mount *mp, int *flags, | ||
15 | struct xfs_mount_args *args); | ||
16 | int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp); | ||
17 | int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp, | ||
18 | bhv_vnode_t *vp); | ||
19 | int xfs_sync(struct xfs_mount *mp, int flags); | ||
20 | int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct fid *fidp); | ||
21 | int xfs_parseargs(struct xfs_mount *mp, char *options, | ||
22 | struct xfs_mount_args *args, int update); | ||
23 | int xfs_showargs(struct xfs_mount *mp, struct seq_file *m); | ||
24 | void xfs_freeze(struct xfs_mount *mp); | ||
25 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, | ||
26 | int lnnum); | ||
27 | |||
28 | #endif /* _XFS_VFSOPS_H */ | ||
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 603459229904..5e3c57ca9981 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -52,15 +52,13 @@ | |||
52 | #include "xfs_trans_space.h" | 52 | #include "xfs_trans_space.h" |
53 | #include "xfs_log_priv.h" | 53 | #include "xfs_log_priv.h" |
54 | #include "xfs_filestream.h" | 54 | #include "xfs_filestream.h" |
55 | #include "xfs_vnodeops.h" | ||
55 | 56 | ||
56 | STATIC int | 57 | int |
57 | xfs_open( | 58 | xfs_open( |
58 | bhv_desc_t *bdp, | 59 | xfs_inode_t *ip) |
59 | cred_t *credp) | ||
60 | { | 60 | { |
61 | int mode; | 61 | int mode; |
62 | bhv_vnode_t *vp = BHV_TO_VNODE(bdp); | ||
63 | xfs_inode_t *ip = XFS_BHVTOI(bdp); | ||
64 | 62 | ||
65 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 63 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
66 | return XFS_ERROR(EIO); | 64 | return XFS_ERROR(EIO); |
@@ -69,7 +67,7 @@ xfs_open( | |||
69 | * If it's a directory with any blocks, read-ahead block 0 | 67 | * If it's a directory with any blocks, read-ahead block 0 |
70 | * as we're almost certain to have the next operation be a read there. | 68 | * as we're almost certain to have the next operation be a read there. |
71 | */ | 69 | */ |
72 | if (VN_ISDIR(vp) && ip->i_d.di_nextents > 0) { | 70 | if (S_ISDIR(ip->i_d.di_mode) && ip->i_d.di_nextents > 0) { |
73 | mode = xfs_ilock_map_shared(ip); | 71 | mode = xfs_ilock_map_shared(ip); |
74 | if (ip->i_d.di_nextents > 0) | 72 | if (ip->i_d.di_nextents > 0) |
75 | (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); | 73 | (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); |
@@ -81,22 +79,16 @@ xfs_open( | |||
81 | /* | 79 | /* |
82 | * xfs_getattr | 80 | * xfs_getattr |
83 | */ | 81 | */ |
84 | STATIC int | 82 | int |
85 | xfs_getattr( | 83 | xfs_getattr( |
86 | bhv_desc_t *bdp, | 84 | xfs_inode_t *ip, |
87 | bhv_vattr_t *vap, | 85 | bhv_vattr_t *vap, |
88 | int flags, | 86 | int flags) |
89 | cred_t *credp) | ||
90 | { | 87 | { |
91 | xfs_inode_t *ip; | 88 | bhv_vnode_t *vp = XFS_ITOV(ip); |
92 | xfs_mount_t *mp; | 89 | xfs_mount_t *mp = ip->i_mount; |
93 | bhv_vnode_t *vp; | ||
94 | |||
95 | vp = BHV_TO_VNODE(bdp); | ||
96 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | ||
97 | 90 | ||
98 | ip = XFS_BHVTOI(bdp); | 91 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
99 | mp = ip->i_mount; | ||
100 | 92 | ||
101 | if (XFS_FORCED_SHUTDOWN(mp)) | 93 | if (XFS_FORCED_SHUTDOWN(mp)) |
102 | return XFS_ERROR(EIO); | 94 | return XFS_ERROR(EIO); |
@@ -215,14 +207,14 @@ xfs_getattr( | |||
215 | */ | 207 | */ |
216 | int | 208 | int |
217 | xfs_setattr( | 209 | xfs_setattr( |
218 | bhv_desc_t *bdp, | 210 | xfs_inode_t *ip, |
219 | bhv_vattr_t *vap, | 211 | bhv_vattr_t *vap, |
220 | int flags, | 212 | int flags, |
221 | cred_t *credp) | 213 | cred_t *credp) |
222 | { | 214 | { |
223 | xfs_inode_t *ip; | 215 | bhv_vnode_t *vp = XFS_ITOV(ip); |
216 | xfs_mount_t *mp = ip->i_mount; | ||
224 | xfs_trans_t *tp; | 217 | xfs_trans_t *tp; |
225 | xfs_mount_t *mp; | ||
226 | int mask; | 218 | int mask; |
227 | int code; | 219 | int code; |
228 | uint lock_flags; | 220 | uint lock_flags; |
@@ -230,17 +222,15 @@ xfs_setattr( | |||
230 | uid_t uid=0, iuid=0; | 222 | uid_t uid=0, iuid=0; |
231 | gid_t gid=0, igid=0; | 223 | gid_t gid=0, igid=0; |
232 | int timeflags = 0; | 224 | int timeflags = 0; |
233 | bhv_vnode_t *vp; | ||
234 | xfs_prid_t projid=0, iprojid=0; | 225 | xfs_prid_t projid=0, iprojid=0; |
235 | int mandlock_before, mandlock_after; | 226 | int mandlock_before, mandlock_after; |
236 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; | 227 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; |
237 | int file_owner; | 228 | int file_owner; |
238 | int need_iolock = 1; | 229 | int need_iolock = 1; |
239 | 230 | ||
240 | vp = BHV_TO_VNODE(bdp); | 231 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
241 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | ||
242 | 232 | ||
243 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 233 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
244 | return XFS_ERROR(EROFS); | 234 | return XFS_ERROR(EROFS); |
245 | 235 | ||
246 | /* | 236 | /* |
@@ -251,9 +241,6 @@ xfs_setattr( | |||
251 | return XFS_ERROR(EINVAL); | 241 | return XFS_ERROR(EINVAL); |
252 | } | 242 | } |
253 | 243 | ||
254 | ip = XFS_BHVTOI(bdp); | ||
255 | mp = ip->i_mount; | ||
256 | |||
257 | if (XFS_FORCED_SHUTDOWN(mp)) | 244 | if (XFS_FORCED_SHUTDOWN(mp)) |
258 | return XFS_ERROR(EIO); | 245 | return XFS_ERROR(EIO); |
259 | 246 | ||
@@ -337,7 +324,7 @@ xfs_setattr( | |||
337 | } | 324 | } |
338 | } | 325 | } |
339 | } else { | 326 | } else { |
340 | if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) && | 327 | if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) && |
341 | !(flags & ATTR_DMI)) { | 328 | !(flags & ATTR_DMI)) { |
342 | int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR; | 329 | int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR; |
343 | code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp, | 330 | code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp, |
@@ -605,13 +592,13 @@ xfs_setattr( | |||
605 | if (!code && | 592 | if (!code && |
606 | (ip->i_size != ip->i_d.di_size) && | 593 | (ip->i_size != ip->i_d.di_size) && |
607 | (vap->va_size > ip->i_d.di_size)) { | 594 | (vap->va_size > ip->i_d.di_size)) { |
608 | code = bhv_vop_flush_pages(XFS_ITOV(ip), | 595 | code = xfs_flush_pages(ip, |
609 | ip->i_d.di_size, vap->va_size, | 596 | ip->i_d.di_size, vap->va_size, |
610 | XFS_B_ASYNC, FI_NONE); | 597 | XFS_B_ASYNC, FI_NONE); |
611 | } | 598 | } |
612 | 599 | ||
613 | /* wait for all I/O to complete */ | 600 | /* wait for all I/O to complete */ |
614 | vn_iowait(vp); | 601 | vn_iowait(ip); |
615 | 602 | ||
616 | if (!code) | 603 | if (!code) |
617 | code = xfs_itruncate_data(ip, vap->va_size); | 604 | code = xfs_itruncate_data(ip, vap->va_size); |
@@ -673,7 +660,7 @@ xfs_setattr( | |||
673 | * vnode and flush it when the file is closed, and | 660 | * vnode and flush it when the file is closed, and |
674 | * do not wait the usual (long) time for writeout. | 661 | * do not wait the usual (long) time for writeout. |
675 | */ | 662 | */ |
676 | VTRUNCATE(vp); | 663 | xfs_iflags_set(ip, XFS_ITRUNCATED); |
677 | } | 664 | } |
678 | /* | 665 | /* |
679 | * Have to do this even if the file's size doesn't change. | 666 | * Have to do this even if the file's size doesn't change. |
@@ -877,10 +864,6 @@ xfs_setattr( | |||
877 | * racing calls to vop_vnode_change. | 864 | * racing calls to vop_vnode_change. |
878 | */ | 865 | */ |
879 | mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); | 866 | mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); |
880 | if (mandlock_before != mandlock_after) { | ||
881 | bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING, | ||
882 | mandlock_after); | ||
883 | } | ||
884 | 867 | ||
885 | xfs_iunlock(ip, lock_flags); | 868 | xfs_iunlock(ip, lock_flags); |
886 | 869 | ||
@@ -896,7 +879,7 @@ xfs_setattr( | |||
896 | return code; | 879 | return code; |
897 | } | 880 | } |
898 | 881 | ||
899 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) && | 882 | if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) && |
900 | !(flags & ATTR_DMI)) { | 883 | !(flags & ATTR_DMI)) { |
901 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL, | 884 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL, |
902 | NULL, DM_RIGHT_NULL, NULL, NULL, | 885 | NULL, DM_RIGHT_NULL, NULL, NULL, |
@@ -924,19 +907,16 @@ xfs_setattr( | |||
924 | * xfs_access | 907 | * xfs_access |
925 | * Null conversion from vnode mode bits to inode mode bits, as in efs. | 908 | * Null conversion from vnode mode bits to inode mode bits, as in efs. |
926 | */ | 909 | */ |
927 | STATIC int | 910 | int |
928 | xfs_access( | 911 | xfs_access( |
929 | bhv_desc_t *bdp, | 912 | xfs_inode_t *ip, |
930 | int mode, | 913 | int mode, |
931 | cred_t *credp) | 914 | cred_t *credp) |
932 | { | 915 | { |
933 | xfs_inode_t *ip; | ||
934 | int error; | 916 | int error; |
935 | 917 | ||
936 | vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, | 918 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
937 | (inst_t *)__return_address); | ||
938 | 919 | ||
939 | ip = XFS_BHVTOI(bdp); | ||
940 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 920 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
941 | error = xfs_iaccess(ip, mode, credp); | 921 | error = xfs_iaccess(ip, mode, credp); |
942 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 922 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
@@ -951,105 +931,88 @@ xfs_access( | |||
951 | */ | 931 | */ |
952 | #define SYMLINK_MAPS 2 | 932 | #define SYMLINK_MAPS 2 |
953 | 933 | ||
954 | /* | ||
955 | * xfs_readlink | ||
956 | * | ||
957 | */ | ||
958 | STATIC int | 934 | STATIC int |
959 | xfs_readlink( | 935 | xfs_readlink_bmap( |
960 | bhv_desc_t *bdp, | 936 | xfs_inode_t *ip, |
961 | uio_t *uiop, | 937 | char *link) |
962 | int ioflags, | ||
963 | cred_t *credp) | ||
964 | { | 938 | { |
965 | xfs_inode_t *ip; | 939 | xfs_mount_t *mp = ip->i_mount; |
966 | int count; | 940 | int pathlen = ip->i_d.di_size; |
967 | xfs_off_t offset; | 941 | int nmaps = SYMLINK_MAPS; |
968 | int pathlen; | ||
969 | bhv_vnode_t *vp; | ||
970 | int error = 0; | ||
971 | xfs_mount_t *mp; | ||
972 | int nmaps; | ||
973 | xfs_bmbt_irec_t mval[SYMLINK_MAPS]; | 942 | xfs_bmbt_irec_t mval[SYMLINK_MAPS]; |
974 | xfs_daddr_t d; | 943 | xfs_daddr_t d; |
975 | int byte_cnt; | 944 | int byte_cnt; |
976 | int n; | 945 | int n; |
977 | xfs_buf_t *bp; | 946 | xfs_buf_t *bp; |
947 | int error = 0; | ||
978 | 948 | ||
979 | vp = BHV_TO_VNODE(bdp); | 949 | error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 0, NULL, 0, |
980 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 950 | mval, &nmaps, NULL, NULL); |
981 | 951 | if (error) | |
982 | ip = XFS_BHVTOI(bdp); | 952 | goto out; |
983 | mp = ip->i_mount; | ||
984 | 953 | ||
985 | if (XFS_FORCED_SHUTDOWN(mp)) | 954 | for (n = 0; n < nmaps; n++) { |
986 | return XFS_ERROR(EIO); | 955 | d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); |
956 | byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); | ||
987 | 957 | ||
988 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 958 | bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0); |
959 | error = XFS_BUF_GETERROR(bp); | ||
960 | if (error) { | ||
961 | xfs_ioerror_alert("xfs_readlink", | ||
962 | ip->i_mount, bp, XFS_BUF_ADDR(bp)); | ||
963 | xfs_buf_relse(bp); | ||
964 | goto out; | ||
965 | } | ||
966 | if (pathlen < byte_cnt) | ||
967 | byte_cnt = pathlen; | ||
968 | pathlen -= byte_cnt; | ||
989 | 969 | ||
990 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK); | 970 | memcpy(link, XFS_BUF_PTR(bp), byte_cnt); |
971 | xfs_buf_relse(bp); | ||
972 | } | ||
991 | 973 | ||
992 | offset = uiop->uio_offset; | 974 | link[ip->i_d.di_size] = '\0'; |
993 | count = uiop->uio_resid; | 975 | error = 0; |
994 | 976 | ||
995 | if (offset < 0) { | 977 | out: |
996 | error = XFS_ERROR(EINVAL); | 978 | return error; |
997 | goto error_return; | 979 | } |
998 | } | ||
999 | if (count <= 0) { | ||
1000 | error = 0; | ||
1001 | goto error_return; | ||
1002 | } | ||
1003 | 980 | ||
1004 | /* | 981 | int |
1005 | * See if the symlink is stored inline. | 982 | xfs_readlink( |
1006 | */ | 983 | xfs_inode_t *ip, |
1007 | pathlen = (int)ip->i_d.di_size; | 984 | char *link) |
985 | { | ||
986 | xfs_mount_t *mp = ip->i_mount; | ||
987 | int pathlen; | ||
988 | int error = 0; | ||
1008 | 989 | ||
1009 | if (ip->i_df.if_flags & XFS_IFINLINE) { | 990 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
1010 | error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop); | ||
1011 | } | ||
1012 | else { | ||
1013 | /* | ||
1014 | * Symlink not inline. Call bmap to get it in. | ||
1015 | */ | ||
1016 | nmaps = SYMLINK_MAPS; | ||
1017 | 991 | ||
1018 | error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), | 992 | if (XFS_FORCED_SHUTDOWN(mp)) |
1019 | 0, NULL, 0, mval, &nmaps, NULL, NULL); | 993 | return XFS_ERROR(EIO); |
1020 | 994 | ||
1021 | if (error) { | 995 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
1022 | goto error_return; | ||
1023 | } | ||
1024 | 996 | ||
1025 | for (n = 0; n < nmaps; n++) { | 997 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK); |
1026 | d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); | 998 | ASSERT(ip->i_d.di_size <= MAXPATHLEN); |
1027 | byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); | ||
1028 | bp = xfs_buf_read(mp->m_ddev_targp, d, | ||
1029 | BTOBB(byte_cnt), 0); | ||
1030 | error = XFS_BUF_GETERROR(bp); | ||
1031 | if (error) { | ||
1032 | xfs_ioerror_alert("xfs_readlink", | ||
1033 | ip->i_mount, bp, XFS_BUF_ADDR(bp)); | ||
1034 | xfs_buf_relse(bp); | ||
1035 | goto error_return; | ||
1036 | } | ||
1037 | if (pathlen < byte_cnt) | ||
1038 | byte_cnt = pathlen; | ||
1039 | pathlen -= byte_cnt; | ||
1040 | 999 | ||
1041 | error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop); | 1000 | pathlen = ip->i_d.di_size; |
1042 | xfs_buf_relse (bp); | 1001 | if (!pathlen) |
1043 | } | 1002 | goto out; |
1044 | 1003 | ||
1004 | if (ip->i_df.if_flags & XFS_IFINLINE) { | ||
1005 | memcpy(link, ip->i_df.if_u1.if_data, pathlen); | ||
1006 | link[pathlen] = '\0'; | ||
1007 | } else { | ||
1008 | error = xfs_readlink_bmap(ip, link); | ||
1045 | } | 1009 | } |
1046 | 1010 | ||
1047 | error_return: | 1011 | out: |
1048 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 1012 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
1049 | return error; | 1013 | return error; |
1050 | } | 1014 | } |
1051 | 1015 | ||
1052 | |||
1053 | /* | 1016 | /* |
1054 | * xfs_fsync | 1017 | * xfs_fsync |
1055 | * | 1018 | * |
@@ -1059,23 +1022,18 @@ error_return: | |||
1059 | * be held while flushing the data, so acquire after we're done | 1022 | * be held while flushing the data, so acquire after we're done |
1060 | * with that. | 1023 | * with that. |
1061 | */ | 1024 | */ |
1062 | STATIC int | 1025 | int |
1063 | xfs_fsync( | 1026 | xfs_fsync( |
1064 | bhv_desc_t *bdp, | 1027 | xfs_inode_t *ip, |
1065 | int flag, | 1028 | int flag, |
1066 | cred_t *credp, | ||
1067 | xfs_off_t start, | 1029 | xfs_off_t start, |
1068 | xfs_off_t stop) | 1030 | xfs_off_t stop) |
1069 | { | 1031 | { |
1070 | xfs_inode_t *ip; | ||
1071 | xfs_trans_t *tp; | 1032 | xfs_trans_t *tp; |
1072 | int error; | 1033 | int error; |
1073 | int log_flushed = 0, changed = 1; | 1034 | int log_flushed = 0, changed = 1; |
1074 | 1035 | ||
1075 | vn_trace_entry(BHV_TO_VNODE(bdp), | 1036 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
1076 | __FUNCTION__, (inst_t *)__return_address); | ||
1077 | |||
1078 | ip = XFS_BHVTOI(bdp); | ||
1079 | 1037 | ||
1080 | ASSERT(start >= 0 && stop >= -1); | 1038 | ASSERT(start >= 0 && stop >= -1); |
1081 | 1039 | ||
@@ -1545,27 +1503,24 @@ xfs_inactive_attrs( | |||
1545 | return 0; | 1503 | return 0; |
1546 | } | 1504 | } |
1547 | 1505 | ||
1548 | STATIC int | 1506 | int |
1549 | xfs_release( | 1507 | xfs_release( |
1550 | bhv_desc_t *bdp) | 1508 | xfs_inode_t *ip) |
1551 | { | 1509 | { |
1552 | xfs_inode_t *ip; | 1510 | bhv_vnode_t *vp = XFS_ITOV(ip); |
1553 | bhv_vnode_t *vp; | 1511 | xfs_mount_t *mp = ip->i_mount; |
1554 | xfs_mount_t *mp; | ||
1555 | int error; | 1512 | int error; |
1556 | 1513 | ||
1557 | vp = BHV_TO_VNODE(bdp); | ||
1558 | ip = XFS_BHVTOI(bdp); | ||
1559 | mp = ip->i_mount; | ||
1560 | |||
1561 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) | 1514 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) |
1562 | return 0; | 1515 | return 0; |
1563 | 1516 | ||
1564 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1517 | /* If this is a read-only mount, don't do this (would generate I/O) */ |
1565 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 1518 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
1566 | return 0; | 1519 | return 0; |
1567 | 1520 | ||
1568 | if (!XFS_FORCED_SHUTDOWN(mp)) { | 1521 | if (!XFS_FORCED_SHUTDOWN(mp)) { |
1522 | int truncated; | ||
1523 | |||
1569 | /* | 1524 | /* |
1570 | * If we are using filestreams, and we have an unlinked | 1525 | * If we are using filestreams, and we have an unlinked |
1571 | * file that we are processing the last close on, then nothing | 1526 | * file that we are processing the last close on, then nothing |
@@ -1586,8 +1541,9 @@ xfs_release( | |||
1586 | * significantly reducing the time window where we'd otherwise | 1541 | * significantly reducing the time window where we'd otherwise |
1587 | * be exposed to that problem. | 1542 | * be exposed to that problem. |
1588 | */ | 1543 | */ |
1589 | if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0) | 1544 | truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); |
1590 | bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE); | 1545 | if (truncated && VN_DIRTY(vp) && ip->i_delayed_blks > 0) |
1546 | xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE); | ||
1591 | } | 1547 | } |
1592 | 1548 | ||
1593 | #ifdef HAVE_REFCACHE | 1549 | #ifdef HAVE_REFCACHE |
@@ -1623,13 +1579,11 @@ xfs_release( | |||
1623 | * now be truncated. Also, we clear all of the read-ahead state | 1579 | * now be truncated. Also, we clear all of the read-ahead state |
1624 | * kept for the inode here since the file is now closed. | 1580 | * kept for the inode here since the file is now closed. |
1625 | */ | 1581 | */ |
1626 | STATIC int | 1582 | int |
1627 | xfs_inactive( | 1583 | xfs_inactive( |
1628 | bhv_desc_t *bdp, | 1584 | xfs_inode_t *ip) |
1629 | cred_t *credp) | ||
1630 | { | 1585 | { |
1631 | xfs_inode_t *ip; | 1586 | bhv_vnode_t *vp = XFS_ITOV(ip); |
1632 | bhv_vnode_t *vp; | ||
1633 | xfs_bmap_free_t free_list; | 1587 | xfs_bmap_free_t free_list; |
1634 | xfs_fsblock_t first_block; | 1588 | xfs_fsblock_t first_block; |
1635 | int committed; | 1589 | int committed; |
@@ -1638,10 +1592,7 @@ xfs_inactive( | |||
1638 | int error; | 1592 | int error; |
1639 | int truncate; | 1593 | int truncate; |
1640 | 1594 | ||
1641 | vp = BHV_TO_VNODE(bdp); | 1595 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
1642 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | ||
1643 | |||
1644 | ip = XFS_BHVTOI(bdp); | ||
1645 | 1596 | ||
1646 | /* | 1597 | /* |
1647 | * If the inode is already free, then there can be nothing | 1598 | * If the inode is already free, then there can be nothing |
@@ -1666,15 +1617,14 @@ xfs_inactive( | |||
1666 | 1617 | ||
1667 | mp = ip->i_mount; | 1618 | mp = ip->i_mount; |
1668 | 1619 | ||
1669 | if (ip->i_d.di_nlink == 0 && | 1620 | if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY)) { |
1670 | DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_DESTROY)) { | ||
1671 | (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL); | 1621 | (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL); |
1672 | } | 1622 | } |
1673 | 1623 | ||
1674 | error = 0; | 1624 | error = 0; |
1675 | 1625 | ||
1676 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1626 | /* If this is a read-only mount, don't do this (would generate I/O) */ |
1677 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 1627 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
1678 | goto out; | 1628 | goto out; |
1679 | 1629 | ||
1680 | if (ip->i_d.di_nlink != 0) { | 1630 | if (ip->i_d.di_nlink != 0) { |
@@ -1844,34 +1794,24 @@ xfs_inactive( | |||
1844 | } | 1794 | } |
1845 | 1795 | ||
1846 | 1796 | ||
1847 | /* | 1797 | int |
1848 | * xfs_lookup | ||
1849 | */ | ||
1850 | STATIC int | ||
1851 | xfs_lookup( | 1798 | xfs_lookup( |
1852 | bhv_desc_t *dir_bdp, | 1799 | xfs_inode_t *dp, |
1853 | bhv_vname_t *dentry, | 1800 | bhv_vname_t *dentry, |
1854 | bhv_vnode_t **vpp, | 1801 | bhv_vnode_t **vpp) |
1855 | int flags, | ||
1856 | bhv_vnode_t *rdir, | ||
1857 | cred_t *credp) | ||
1858 | { | 1802 | { |
1859 | xfs_inode_t *dp, *ip; | 1803 | xfs_inode_t *ip; |
1860 | xfs_ino_t e_inum; | 1804 | xfs_ino_t e_inum; |
1861 | int error; | 1805 | int error; |
1862 | uint lock_mode; | 1806 | uint lock_mode; |
1863 | bhv_vnode_t *dir_vp; | ||
1864 | |||
1865 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
1866 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
1867 | 1807 | ||
1868 | dp = XFS_BHVTOI(dir_bdp); | 1808 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
1869 | 1809 | ||
1870 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 1810 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
1871 | return XFS_ERROR(EIO); | 1811 | return XFS_ERROR(EIO); |
1872 | 1812 | ||
1873 | lock_mode = xfs_ilock_map_shared(dp); | 1813 | lock_mode = xfs_ilock_map_shared(dp); |
1874 | error = xfs_dir_lookup_int(dir_bdp, lock_mode, dentry, &e_inum, &ip); | 1814 | error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip); |
1875 | if (!error) { | 1815 | if (!error) { |
1876 | *vpp = XFS_ITOV(ip); | 1816 | *vpp = XFS_ITOV(ip); |
1877 | ITRACE(ip); | 1817 | ITRACE(ip); |
@@ -1880,53 +1820,43 @@ xfs_lookup( | |||
1880 | return error; | 1820 | return error; |
1881 | } | 1821 | } |
1882 | 1822 | ||
1883 | 1823 | int | |
1884 | /* | ||
1885 | * xfs_create (create a new file). | ||
1886 | */ | ||
1887 | STATIC int | ||
1888 | xfs_create( | 1824 | xfs_create( |
1889 | bhv_desc_t *dir_bdp, | 1825 | xfs_inode_t *dp, |
1890 | bhv_vname_t *dentry, | 1826 | bhv_vname_t *dentry, |
1891 | bhv_vattr_t *vap, | 1827 | mode_t mode, |
1828 | xfs_dev_t rdev, | ||
1892 | bhv_vnode_t **vpp, | 1829 | bhv_vnode_t **vpp, |
1893 | cred_t *credp) | 1830 | cred_t *credp) |
1894 | { | 1831 | { |
1895 | char *name = VNAME(dentry); | 1832 | char *name = VNAME(dentry); |
1896 | bhv_vnode_t *dir_vp; | 1833 | xfs_mount_t *mp = dp->i_mount; |
1897 | xfs_inode_t *dp, *ip; | 1834 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); |
1835 | xfs_inode_t *ip; | ||
1898 | bhv_vnode_t *vp = NULL; | 1836 | bhv_vnode_t *vp = NULL; |
1899 | xfs_trans_t *tp; | 1837 | xfs_trans_t *tp; |
1900 | xfs_mount_t *mp; | ||
1901 | xfs_dev_t rdev; | ||
1902 | int error; | 1838 | int error; |
1903 | xfs_bmap_free_t free_list; | 1839 | xfs_bmap_free_t free_list; |
1904 | xfs_fsblock_t first_block; | 1840 | xfs_fsblock_t first_block; |
1905 | boolean_t dp_joined_to_trans; | 1841 | boolean_t unlock_dp_on_error = B_FALSE; |
1906 | int dm_event_sent = 0; | 1842 | int dm_event_sent = 0; |
1907 | uint cancel_flags; | 1843 | uint cancel_flags; |
1908 | int committed; | 1844 | int committed; |
1909 | xfs_prid_t prid; | 1845 | xfs_prid_t prid; |
1910 | struct xfs_dquot *udqp, *gdqp; | 1846 | struct xfs_dquot *udqp, *gdqp; |
1911 | uint resblks; | 1847 | uint resblks; |
1912 | int dm_di_mode; | ||
1913 | int namelen; | 1848 | int namelen; |
1914 | 1849 | ||
1915 | ASSERT(!*vpp); | 1850 | ASSERT(!*vpp); |
1916 | dir_vp = BHV_TO_VNODE(dir_bdp); | 1851 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
1917 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
1918 | 1852 | ||
1919 | dp = XFS_BHVTOI(dir_bdp); | ||
1920 | mp = dp->i_mount; | ||
1921 | |||
1922 | dm_di_mode = vap->va_mode; | ||
1923 | namelen = VNAMELEN(dentry); | 1853 | namelen = VNAMELEN(dentry); |
1924 | 1854 | ||
1925 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { | 1855 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { |
1926 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, | 1856 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, |
1927 | dir_vp, DM_RIGHT_NULL, NULL, | 1857 | dir_vp, DM_RIGHT_NULL, NULL, |
1928 | DM_RIGHT_NULL, name, NULL, | 1858 | DM_RIGHT_NULL, name, NULL, |
1929 | dm_di_mode, 0, 0); | 1859 | mode, 0, 0); |
1930 | 1860 | ||
1931 | if (error) | 1861 | if (error) |
1932 | return error; | 1862 | return error; |
@@ -1941,8 +1871,6 @@ xfs_create( | |||
1941 | udqp = gdqp = NULL; | 1871 | udqp = gdqp = NULL; |
1942 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 1872 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) |
1943 | prid = dp->i_d.di_projid; | 1873 | prid = dp->i_d.di_projid; |
1944 | else if (vap->va_mask & XFS_AT_PROJID) | ||
1945 | prid = (xfs_prid_t)vap->va_projid; | ||
1946 | else | 1874 | else |
1947 | prid = (xfs_prid_t)dfltprid; | 1875 | prid = (xfs_prid_t)dfltprid; |
1948 | 1876 | ||
@@ -1956,7 +1884,6 @@ xfs_create( | |||
1956 | goto std_return; | 1884 | goto std_return; |
1957 | 1885 | ||
1958 | ip = NULL; | 1886 | ip = NULL; |
1959 | dp_joined_to_trans = B_FALSE; | ||
1960 | 1887 | ||
1961 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); | 1888 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); |
1962 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | 1889 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; |
@@ -1976,11 +1903,11 @@ xfs_create( | |||
1976 | } | 1903 | } |
1977 | if (error) { | 1904 | if (error) { |
1978 | cancel_flags = 0; | 1905 | cancel_flags = 0; |
1979 | dp = NULL; | ||
1980 | goto error_return; | 1906 | goto error_return; |
1981 | } | 1907 | } |
1982 | 1908 | ||
1983 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 1909 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
1910 | unlock_dp_on_error = B_TRUE; | ||
1984 | 1911 | ||
1985 | XFS_BMAP_INIT(&free_list, &first_block); | 1912 | XFS_BMAP_INIT(&free_list, &first_block); |
1986 | 1913 | ||
@@ -1995,8 +1922,7 @@ xfs_create( | |||
1995 | 1922 | ||
1996 | if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) | 1923 | if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) |
1997 | goto error_return; | 1924 | goto error_return; |
1998 | rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; | 1925 | error = xfs_dir_ialloc(&tp, dp, mode, 1, |
1999 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, | ||
2000 | rdev, credp, prid, resblks > 0, | 1926 | rdev, credp, prid, resblks > 0, |
2001 | &ip, &committed); | 1927 | &ip, &committed); |
2002 | if (error) { | 1928 | if (error) { |
@@ -2014,15 +1940,15 @@ xfs_create( | |||
2014 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); | 1940 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); |
2015 | 1941 | ||
2016 | /* | 1942 | /* |
2017 | * Now we join the directory inode to the transaction. | 1943 | * Now we join the directory inode to the transaction. We do not do it |
2018 | * We do not do it earlier because xfs_dir_ialloc | 1944 | * earlier because xfs_dir_ialloc might commit the previous transaction |
2019 | * might commit the previous transaction (and release | 1945 | * (and release all the locks). An error from here on will result in |
2020 | * all the locks). | 1946 | * the transaction cancel unlocking dp so don't do it explicitly in the |
1947 | * error path. | ||
2021 | */ | 1948 | */ |
2022 | |||
2023 | VN_HOLD(dir_vp); | 1949 | VN_HOLD(dir_vp); |
2024 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 1950 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
2025 | dp_joined_to_trans = B_TRUE; | 1951 | unlock_dp_on_error = B_FALSE; |
2026 | 1952 | ||
2027 | error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, | 1953 | error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, |
2028 | &first_block, &free_list, resblks ? | 1954 | &first_block, &free_list, resblks ? |
@@ -2076,25 +2002,18 @@ xfs_create( | |||
2076 | XFS_QM_DQRELE(mp, udqp); | 2002 | XFS_QM_DQRELE(mp, udqp); |
2077 | XFS_QM_DQRELE(mp, gdqp); | 2003 | XFS_QM_DQRELE(mp, gdqp); |
2078 | 2004 | ||
2079 | /* | ||
2080 | * Propagate the fact that the vnode changed after the | ||
2081 | * xfs_inode locks have been released. | ||
2082 | */ | ||
2083 | bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3); | ||
2084 | |||
2085 | *vpp = vp; | 2005 | *vpp = vp; |
2086 | 2006 | ||
2087 | /* Fallthrough to std_return with error = 0 */ | 2007 | /* Fallthrough to std_return with error = 0 */ |
2088 | 2008 | ||
2089 | std_return: | 2009 | std_return: |
2090 | if ( (*vpp || (error != 0 && dm_event_sent != 0)) && | 2010 | if ((*vpp || (error != 0 && dm_event_sent != 0)) && |
2091 | DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), | 2011 | DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { |
2092 | DM_EVENT_POSTCREATE)) { | ||
2093 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, | 2012 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, |
2094 | dir_vp, DM_RIGHT_NULL, | 2013 | dir_vp, DM_RIGHT_NULL, |
2095 | *vpp ? vp:NULL, | 2014 | *vpp ? vp:NULL, |
2096 | DM_RIGHT_NULL, name, NULL, | 2015 | DM_RIGHT_NULL, name, NULL, |
2097 | dm_di_mode, error, 0); | 2016 | mode, error, 0); |
2098 | } | 2017 | } |
2099 | return error; | 2018 | return error; |
2100 | 2019 | ||
@@ -2106,11 +2025,12 @@ std_return: | |||
2106 | if (tp != NULL) | 2025 | if (tp != NULL) |
2107 | xfs_trans_cancel(tp, cancel_flags); | 2026 | xfs_trans_cancel(tp, cancel_flags); |
2108 | 2027 | ||
2109 | if (!dp_joined_to_trans && (dp != NULL)) | ||
2110 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
2111 | XFS_QM_DQRELE(mp, udqp); | 2028 | XFS_QM_DQRELE(mp, udqp); |
2112 | XFS_QM_DQRELE(mp, gdqp); | 2029 | XFS_QM_DQRELE(mp, gdqp); |
2113 | 2030 | ||
2031 | if (unlock_dp_on_error) | ||
2032 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
2033 | |||
2114 | goto std_return; | 2034 | goto std_return; |
2115 | 2035 | ||
2116 | abort_rele: | 2036 | abort_rele: |
@@ -2381,22 +2301,16 @@ int remove_which_error_return = 0; | |||
2381 | #define REMOVE_DEBUG_TRACE(x) | 2301 | #define REMOVE_DEBUG_TRACE(x) |
2382 | #endif /* ! DEBUG */ | 2302 | #endif /* ! DEBUG */ |
2383 | 2303 | ||
2384 | 2304 | int | |
2385 | /* | ||
2386 | * xfs_remove | ||
2387 | * | ||
2388 | */ | ||
2389 | STATIC int | ||
2390 | xfs_remove( | 2305 | xfs_remove( |
2391 | bhv_desc_t *dir_bdp, | 2306 | xfs_inode_t *dp, |
2392 | bhv_vname_t *dentry, | 2307 | bhv_vname_t *dentry) |
2393 | cred_t *credp) | ||
2394 | { | 2308 | { |
2395 | bhv_vnode_t *dir_vp; | 2309 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); |
2396 | char *name = VNAME(dentry); | 2310 | char *name = VNAME(dentry); |
2397 | xfs_inode_t *dp, *ip; | 2311 | xfs_mount_t *mp = dp->i_mount; |
2312 | xfs_inode_t *ip; | ||
2398 | xfs_trans_t *tp = NULL; | 2313 | xfs_trans_t *tp = NULL; |
2399 | xfs_mount_t *mp; | ||
2400 | int error = 0; | 2314 | int error = 0; |
2401 | xfs_bmap_free_t free_list; | 2315 | xfs_bmap_free_t free_list; |
2402 | xfs_fsblock_t first_block; | 2316 | xfs_fsblock_t first_block; |
@@ -2407,11 +2321,7 @@ xfs_remove( | |||
2407 | uint resblks; | 2321 | uint resblks; |
2408 | int namelen; | 2322 | int namelen; |
2409 | 2323 | ||
2410 | dir_vp = BHV_TO_VNODE(dir_bdp); | 2324 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
2411 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
2412 | |||
2413 | dp = XFS_BHVTOI(dir_bdp); | ||
2414 | mp = dp->i_mount; | ||
2415 | 2325 | ||
2416 | if (XFS_FORCED_SHUTDOWN(mp)) | 2326 | if (XFS_FORCED_SHUTDOWN(mp)) |
2417 | return XFS_ERROR(EIO); | 2327 | return XFS_ERROR(EIO); |
@@ -2423,7 +2333,7 @@ xfs_remove( | |||
2423 | IRELE(ip); | 2333 | IRELE(ip); |
2424 | } | 2334 | } |
2425 | 2335 | ||
2426 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { | 2336 | if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { |
2427 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, | 2337 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, |
2428 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, | 2338 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, |
2429 | name, NULL, dm_di_mode, 0, 0); | 2339 | name, NULL, dm_di_mode, 0, 0); |
@@ -2454,7 +2364,7 @@ xfs_remove( | |||
2454 | 2364 | ||
2455 | dm_di_mode = ip->i_d.di_mode; | 2365 | dm_di_mode = ip->i_d.di_mode; |
2456 | 2366 | ||
2457 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); | 2367 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
2458 | 2368 | ||
2459 | ITRACE(ip); | 2369 | ITRACE(ip); |
2460 | 2370 | ||
@@ -2588,19 +2498,13 @@ xfs_remove( | |||
2588 | if (link_zero && xfs_inode_is_filestream(ip)) | 2498 | if (link_zero && xfs_inode_is_filestream(ip)) |
2589 | xfs_filestream_deassociate(ip); | 2499 | xfs_filestream_deassociate(ip); |
2590 | 2500 | ||
2591 | vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); | 2501 | vn_trace_exit(ip, __FUNCTION__, (inst_t *)__return_address); |
2592 | |||
2593 | /* | ||
2594 | * Let interposed file systems know about removed links. | ||
2595 | */ | ||
2596 | bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero); | ||
2597 | 2502 | ||
2598 | IRELE(ip); | 2503 | IRELE(ip); |
2599 | 2504 | ||
2600 | /* Fall through to std_return with error = 0 */ | 2505 | /* Fall through to std_return with error = 0 */ |
2601 | std_return: | 2506 | std_return: |
2602 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, | 2507 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { |
2603 | DM_EVENT_POSTREMOVE)) { | ||
2604 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, | 2508 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, |
2605 | dir_vp, DM_RIGHT_NULL, | 2509 | dir_vp, DM_RIGHT_NULL, |
2606 | NULL, DM_RIGHT_NULL, | 2510 | NULL, DM_RIGHT_NULL, |
@@ -2638,46 +2542,36 @@ xfs_remove( | |||
2638 | goto std_return; | 2542 | goto std_return; |
2639 | } | 2543 | } |
2640 | 2544 | ||
2641 | 2545 | int | |
2642 | /* | ||
2643 | * xfs_link | ||
2644 | * | ||
2645 | */ | ||
2646 | STATIC int | ||
2647 | xfs_link( | 2546 | xfs_link( |
2648 | bhv_desc_t *target_dir_bdp, | 2547 | xfs_inode_t *tdp, |
2649 | bhv_vnode_t *src_vp, | 2548 | bhv_vnode_t *src_vp, |
2650 | bhv_vname_t *dentry, | 2549 | bhv_vname_t *dentry) |
2651 | cred_t *credp) | ||
2652 | { | 2550 | { |
2653 | xfs_inode_t *tdp, *sip; | 2551 | bhv_vnode_t *target_dir_vp = XFS_ITOV(tdp); |
2552 | xfs_mount_t *mp = tdp->i_mount; | ||
2553 | xfs_inode_t *sip = xfs_vtoi(src_vp); | ||
2654 | xfs_trans_t *tp; | 2554 | xfs_trans_t *tp; |
2655 | xfs_mount_t *mp; | ||
2656 | xfs_inode_t *ips[2]; | 2555 | xfs_inode_t *ips[2]; |
2657 | int error; | 2556 | int error; |
2658 | xfs_bmap_free_t free_list; | 2557 | xfs_bmap_free_t free_list; |
2659 | xfs_fsblock_t first_block; | 2558 | xfs_fsblock_t first_block; |
2660 | int cancel_flags; | 2559 | int cancel_flags; |
2661 | int committed; | 2560 | int committed; |
2662 | bhv_vnode_t *target_dir_vp; | ||
2663 | int resblks; | 2561 | int resblks; |
2664 | char *target_name = VNAME(dentry); | 2562 | char *target_name = VNAME(dentry); |
2665 | int target_namelen; | 2563 | int target_namelen; |
2666 | 2564 | ||
2667 | target_dir_vp = BHV_TO_VNODE(target_dir_bdp); | 2565 | vn_trace_entry(tdp, __FUNCTION__, (inst_t *)__return_address); |
2668 | vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address); | 2566 | vn_trace_entry(xfs_vtoi(src_vp), __FUNCTION__, (inst_t *)__return_address); |
2669 | vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); | ||
2670 | 2567 | ||
2671 | target_namelen = VNAMELEN(dentry); | 2568 | target_namelen = VNAMELEN(dentry); |
2672 | ASSERT(!VN_ISDIR(src_vp)); | 2569 | ASSERT(!VN_ISDIR(src_vp)); |
2673 | 2570 | ||
2674 | sip = xfs_vtoi(src_vp); | ||
2675 | tdp = XFS_BHVTOI(target_dir_bdp); | ||
2676 | mp = tdp->i_mount; | ||
2677 | if (XFS_FORCED_SHUTDOWN(mp)) | 2571 | if (XFS_FORCED_SHUTDOWN(mp)) |
2678 | return XFS_ERROR(EIO); | 2572 | return XFS_ERROR(EIO); |
2679 | 2573 | ||
2680 | if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) { | 2574 | if (DM_EVENT_ENABLED(tdp, DM_EVENT_LINK)) { |
2681 | error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK, | 2575 | error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK, |
2682 | target_dir_vp, DM_RIGHT_NULL, | 2576 | target_dir_vp, DM_RIGHT_NULL, |
2683 | src_vp, DM_RIGHT_NULL, | 2577 | src_vp, DM_RIGHT_NULL, |
@@ -2788,8 +2682,7 @@ xfs_link( | |||
2788 | 2682 | ||
2789 | /* Fall through to std_return with error = 0. */ | 2683 | /* Fall through to std_return with error = 0. */ |
2790 | std_return: | 2684 | std_return: |
2791 | if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip, | 2685 | if (DM_EVENT_ENABLED(sip, DM_EVENT_POSTLINK)) { |
2792 | DM_EVENT_POSTLINK)) { | ||
2793 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK, | 2686 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK, |
2794 | target_dir_vp, DM_RIGHT_NULL, | 2687 | target_dir_vp, DM_RIGHT_NULL, |
2795 | src_vp, DM_RIGHT_NULL, | 2688 | src_vp, DM_RIGHT_NULL, |
@@ -2807,57 +2700,43 @@ std_return: | |||
2807 | } | 2700 | } |
2808 | 2701 | ||
2809 | 2702 | ||
2810 | /* | 2703 | int |
2811 | * xfs_mkdir | ||
2812 | * | ||
2813 | */ | ||
2814 | STATIC int | ||
2815 | xfs_mkdir( | 2704 | xfs_mkdir( |
2816 | bhv_desc_t *dir_bdp, | 2705 | xfs_inode_t *dp, |
2817 | bhv_vname_t *dentry, | 2706 | bhv_vname_t *dentry, |
2818 | bhv_vattr_t *vap, | 2707 | mode_t mode, |
2819 | bhv_vnode_t **vpp, | 2708 | bhv_vnode_t **vpp, |
2820 | cred_t *credp) | 2709 | cred_t *credp) |
2821 | { | 2710 | { |
2711 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
2822 | char *dir_name = VNAME(dentry); | 2712 | char *dir_name = VNAME(dentry); |
2823 | xfs_inode_t *dp; | 2713 | int dir_namelen = VNAMELEN(dentry); |
2714 | xfs_mount_t *mp = dp->i_mount; | ||
2824 | xfs_inode_t *cdp; /* inode of created dir */ | 2715 | xfs_inode_t *cdp; /* inode of created dir */ |
2825 | bhv_vnode_t *cvp; /* vnode of created dir */ | 2716 | bhv_vnode_t *cvp; /* vnode of created dir */ |
2826 | xfs_trans_t *tp; | 2717 | xfs_trans_t *tp; |
2827 | xfs_mount_t *mp; | ||
2828 | int cancel_flags; | 2718 | int cancel_flags; |
2829 | int error; | 2719 | int error; |
2830 | int committed; | 2720 | int committed; |
2831 | xfs_bmap_free_t free_list; | 2721 | xfs_bmap_free_t free_list; |
2832 | xfs_fsblock_t first_block; | 2722 | xfs_fsblock_t first_block; |
2833 | bhv_vnode_t *dir_vp; | 2723 | boolean_t unlock_dp_on_error = B_FALSE; |
2834 | boolean_t dp_joined_to_trans; | ||
2835 | boolean_t created = B_FALSE; | 2724 | boolean_t created = B_FALSE; |
2836 | int dm_event_sent = 0; | 2725 | int dm_event_sent = 0; |
2837 | xfs_prid_t prid; | 2726 | xfs_prid_t prid; |
2838 | struct xfs_dquot *udqp, *gdqp; | 2727 | struct xfs_dquot *udqp, *gdqp; |
2839 | uint resblks; | 2728 | uint resblks; |
2840 | int dm_di_mode; | ||
2841 | int dir_namelen; | ||
2842 | |||
2843 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
2844 | dp = XFS_BHVTOI(dir_bdp); | ||
2845 | mp = dp->i_mount; | ||
2846 | 2729 | ||
2847 | if (XFS_FORCED_SHUTDOWN(mp)) | 2730 | if (XFS_FORCED_SHUTDOWN(mp)) |
2848 | return XFS_ERROR(EIO); | 2731 | return XFS_ERROR(EIO); |
2849 | 2732 | ||
2850 | dir_namelen = VNAMELEN(dentry); | ||
2851 | |||
2852 | tp = NULL; | 2733 | tp = NULL; |
2853 | dp_joined_to_trans = B_FALSE; | ||
2854 | dm_di_mode = vap->va_mode; | ||
2855 | 2734 | ||
2856 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { | 2735 | if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) { |
2857 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, | 2736 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, |
2858 | dir_vp, DM_RIGHT_NULL, NULL, | 2737 | dir_vp, DM_RIGHT_NULL, NULL, |
2859 | DM_RIGHT_NULL, dir_name, NULL, | 2738 | DM_RIGHT_NULL, dir_name, NULL, |
2860 | dm_di_mode, 0, 0); | 2739 | mode, 0, 0); |
2861 | if (error) | 2740 | if (error) |
2862 | return error; | 2741 | return error; |
2863 | dm_event_sent = 1; | 2742 | dm_event_sent = 1; |
@@ -2865,14 +2744,12 @@ xfs_mkdir( | |||
2865 | 2744 | ||
2866 | /* Return through std_return after this point. */ | 2745 | /* Return through std_return after this point. */ |
2867 | 2746 | ||
2868 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | 2747 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
2869 | 2748 | ||
2870 | mp = dp->i_mount; | 2749 | mp = dp->i_mount; |
2871 | udqp = gdqp = NULL; | 2750 | udqp = gdqp = NULL; |
2872 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 2751 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) |
2873 | prid = dp->i_d.di_projid; | 2752 | prid = dp->i_d.di_projid; |
2874 | else if (vap->va_mask & XFS_AT_PROJID) | ||
2875 | prid = (xfs_prid_t)vap->va_projid; | ||
2876 | else | 2753 | else |
2877 | prid = (xfs_prid_t)dfltprid; | 2754 | prid = (xfs_prid_t)dfltprid; |
2878 | 2755 | ||
@@ -2898,11 +2775,11 @@ xfs_mkdir( | |||
2898 | } | 2775 | } |
2899 | if (error) { | 2776 | if (error) { |
2900 | cancel_flags = 0; | 2777 | cancel_flags = 0; |
2901 | dp = NULL; | ||
2902 | goto error_return; | 2778 | goto error_return; |
2903 | } | 2779 | } |
2904 | 2780 | ||
2905 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 2781 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
2782 | unlock_dp_on_error = B_TRUE; | ||
2906 | 2783 | ||
2907 | /* | 2784 | /* |
2908 | * Check for directory link count overflow. | 2785 | * Check for directory link count overflow. |
@@ -2925,7 +2802,7 @@ xfs_mkdir( | |||
2925 | /* | 2802 | /* |
2926 | * create the directory inode. | 2803 | * create the directory inode. |
2927 | */ | 2804 | */ |
2928 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 2, | 2805 | error = xfs_dir_ialloc(&tp, dp, mode, 2, |
2929 | 0, credp, prid, resblks > 0, | 2806 | 0, credp, prid, resblks > 0, |
2930 | &cdp, NULL); | 2807 | &cdp, NULL); |
2931 | if (error) { | 2808 | if (error) { |
@@ -2939,11 +2816,13 @@ xfs_mkdir( | |||
2939 | * Now we add the directory inode to the transaction. | 2816 | * Now we add the directory inode to the transaction. |
2940 | * We waited until now since xfs_dir_ialloc might start | 2817 | * We waited until now since xfs_dir_ialloc might start |
2941 | * a new transaction. Had we joined the transaction | 2818 | * a new transaction. Had we joined the transaction |
2942 | * earlier, the locks might have gotten released. | 2819 | * earlier, the locks might have gotten released. An error |
2820 | * from here on will result in the transaction cancel | ||
2821 | * unlocking dp so don't do it explicitly in the error path. | ||
2943 | */ | 2822 | */ |
2944 | VN_HOLD(dir_vp); | 2823 | VN_HOLD(dir_vp); |
2945 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 2824 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
2946 | dp_joined_to_trans = B_TRUE; | 2825 | unlock_dp_on_error = B_FALSE; |
2947 | 2826 | ||
2948 | XFS_BMAP_INIT(&free_list, &first_block); | 2827 | XFS_BMAP_INIT(&free_list, &first_block); |
2949 | 2828 | ||
@@ -3010,15 +2889,14 @@ xfs_mkdir( | |||
3010 | * xfs_trans_commit. */ | 2889 | * xfs_trans_commit. */ |
3011 | 2890 | ||
3012 | std_return: | 2891 | std_return: |
3013 | if ( (created || (error != 0 && dm_event_sent != 0)) && | 2892 | if ((created || (error != 0 && dm_event_sent != 0)) && |
3014 | DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), | 2893 | DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) { |
3015 | DM_EVENT_POSTCREATE)) { | ||
3016 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, | 2894 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, |
3017 | dir_vp, DM_RIGHT_NULL, | 2895 | dir_vp, DM_RIGHT_NULL, |
3018 | created ? XFS_ITOV(cdp):NULL, | 2896 | created ? XFS_ITOV(cdp):NULL, |
3019 | DM_RIGHT_NULL, | 2897 | DM_RIGHT_NULL, |
3020 | dir_name, NULL, | 2898 | dir_name, NULL, |
3021 | dm_di_mode, error, 0); | 2899 | mode, error, 0); |
3022 | } | 2900 | } |
3023 | return error; | 2901 | return error; |
3024 | 2902 | ||
@@ -3032,56 +2910,43 @@ std_return: | |||
3032 | XFS_QM_DQRELE(mp, udqp); | 2910 | XFS_QM_DQRELE(mp, udqp); |
3033 | XFS_QM_DQRELE(mp, gdqp); | 2911 | XFS_QM_DQRELE(mp, gdqp); |
3034 | 2912 | ||
3035 | if (!dp_joined_to_trans && (dp != NULL)) { | 2913 | if (unlock_dp_on_error) |
3036 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 2914 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
3037 | } | ||
3038 | 2915 | ||
3039 | goto std_return; | 2916 | goto std_return; |
3040 | } | 2917 | } |
3041 | 2918 | ||
3042 | 2919 | int | |
3043 | /* | ||
3044 | * xfs_rmdir | ||
3045 | * | ||
3046 | */ | ||
3047 | STATIC int | ||
3048 | xfs_rmdir( | 2920 | xfs_rmdir( |
3049 | bhv_desc_t *dir_bdp, | 2921 | xfs_inode_t *dp, |
3050 | bhv_vname_t *dentry, | 2922 | bhv_vname_t *dentry) |
3051 | cred_t *credp) | ||
3052 | { | 2923 | { |
2924 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
3053 | char *name = VNAME(dentry); | 2925 | char *name = VNAME(dentry); |
3054 | xfs_inode_t *dp; | 2926 | int namelen = VNAMELEN(dentry); |
3055 | xfs_inode_t *cdp; /* child directory */ | 2927 | xfs_mount_t *mp = dp->i_mount; |
2928 | xfs_inode_t *cdp; /* child directory */ | ||
3056 | xfs_trans_t *tp; | 2929 | xfs_trans_t *tp; |
3057 | xfs_mount_t *mp; | ||
3058 | int error; | 2930 | int error; |
3059 | xfs_bmap_free_t free_list; | 2931 | xfs_bmap_free_t free_list; |
3060 | xfs_fsblock_t first_block; | 2932 | xfs_fsblock_t first_block; |
3061 | int cancel_flags; | 2933 | int cancel_flags; |
3062 | int committed; | 2934 | int committed; |
3063 | bhv_vnode_t *dir_vp; | ||
3064 | int dm_di_mode = S_IFDIR; | 2935 | int dm_di_mode = S_IFDIR; |
3065 | int last_cdp_link; | 2936 | int last_cdp_link; |
3066 | int namelen; | ||
3067 | uint resblks; | 2937 | uint resblks; |
3068 | 2938 | ||
3069 | dir_vp = BHV_TO_VNODE(dir_bdp); | 2939 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
3070 | dp = XFS_BHVTOI(dir_bdp); | ||
3071 | mp = dp->i_mount; | ||
3072 | |||
3073 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | ||
3074 | 2940 | ||
3075 | if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount)) | 2941 | if (XFS_FORCED_SHUTDOWN(mp)) |
3076 | return XFS_ERROR(EIO); | 2942 | return XFS_ERROR(EIO); |
3077 | namelen = VNAMELEN(dentry); | ||
3078 | 2943 | ||
3079 | if (!xfs_get_dir_entry(dentry, &cdp)) { | 2944 | if (!xfs_get_dir_entry(dentry, &cdp)) { |
3080 | dm_di_mode = cdp->i_d.di_mode; | 2945 | dm_di_mode = cdp->i_d.di_mode; |
3081 | IRELE(cdp); | 2946 | IRELE(cdp); |
3082 | } | 2947 | } |
3083 | 2948 | ||
3084 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { | 2949 | if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) { |
3085 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, | 2950 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, |
3086 | dir_vp, DM_RIGHT_NULL, | 2951 | dir_vp, DM_RIGHT_NULL, |
3087 | NULL, DM_RIGHT_NULL, | 2952 | NULL, DM_RIGHT_NULL, |
@@ -3260,17 +3125,12 @@ xfs_rmdir( | |||
3260 | } | 3125 | } |
3261 | 3126 | ||
3262 | 3127 | ||
3263 | /* | ||
3264 | * Let interposed file systems know about removed links. | ||
3265 | */ | ||
3266 | bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link); | ||
3267 | |||
3268 | IRELE(cdp); | 3128 | IRELE(cdp); |
3269 | 3129 | ||
3270 | /* Fall through to std_return with error = 0 or the errno | 3130 | /* Fall through to std_return with error = 0 or the errno |
3271 | * from xfs_trans_commit. */ | 3131 | * from xfs_trans_commit. */ |
3272 | std_return: | 3132 | std_return: |
3273 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) { | 3133 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) { |
3274 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, | 3134 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, |
3275 | dir_vp, DM_RIGHT_NULL, | 3135 | dir_vp, DM_RIGHT_NULL, |
3276 | NULL, DM_RIGHT_NULL, | 3136 | NULL, DM_RIGHT_NULL, |
@@ -3289,56 +3149,24 @@ xfs_rmdir( | |||
3289 | goto std_return; | 3149 | goto std_return; |
3290 | } | 3150 | } |
3291 | 3151 | ||
3292 | 3152 | int | |
3293 | /* | ||
3294 | * Read dp's entries starting at uiop->uio_offset and translate them into | ||
3295 | * bufsize bytes worth of struct dirents starting at bufbase. | ||
3296 | */ | ||
3297 | STATIC int | ||
3298 | xfs_readdir( | ||
3299 | bhv_desc_t *dir_bdp, | ||
3300 | uio_t *uiop, | ||
3301 | cred_t *credp, | ||
3302 | int *eofp) | ||
3303 | { | ||
3304 | xfs_inode_t *dp; | ||
3305 | xfs_trans_t *tp = NULL; | ||
3306 | int error = 0; | ||
3307 | uint lock_mode; | ||
3308 | |||
3309 | vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__, | ||
3310 | (inst_t *)__return_address); | ||
3311 | dp = XFS_BHVTOI(dir_bdp); | ||
3312 | |||
3313 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | ||
3314 | return XFS_ERROR(EIO); | ||
3315 | |||
3316 | lock_mode = xfs_ilock_map_shared(dp); | ||
3317 | error = xfs_dir_getdents(tp, dp, uiop, eofp); | ||
3318 | xfs_iunlock_map_shared(dp, lock_mode); | ||
3319 | return error; | ||
3320 | } | ||
3321 | |||
3322 | |||
3323 | STATIC int | ||
3324 | xfs_symlink( | 3153 | xfs_symlink( |
3325 | bhv_desc_t *dir_bdp, | 3154 | xfs_inode_t *dp, |
3326 | bhv_vname_t *dentry, | 3155 | bhv_vname_t *dentry, |
3327 | bhv_vattr_t *vap, | ||
3328 | char *target_path, | 3156 | char *target_path, |
3157 | mode_t mode, | ||
3329 | bhv_vnode_t **vpp, | 3158 | bhv_vnode_t **vpp, |
3330 | cred_t *credp) | 3159 | cred_t *credp) |
3331 | { | 3160 | { |
3161 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
3162 | xfs_mount_t *mp = dp->i_mount; | ||
3332 | xfs_trans_t *tp; | 3163 | xfs_trans_t *tp; |
3333 | xfs_mount_t *mp; | ||
3334 | xfs_inode_t *dp; | ||
3335 | xfs_inode_t *ip; | 3164 | xfs_inode_t *ip; |
3336 | int error; | 3165 | int error; |
3337 | int pathlen; | 3166 | int pathlen; |
3338 | xfs_bmap_free_t free_list; | 3167 | xfs_bmap_free_t free_list; |
3339 | xfs_fsblock_t first_block; | 3168 | xfs_fsblock_t first_block; |
3340 | boolean_t dp_joined_to_trans; | 3169 | boolean_t unlock_dp_on_error = B_FALSE; |
3341 | bhv_vnode_t *dir_vp; | ||
3342 | uint cancel_flags; | 3170 | uint cancel_flags; |
3343 | int committed; | 3171 | int committed; |
3344 | xfs_fileoff_t first_fsb; | 3172 | xfs_fileoff_t first_fsb; |
@@ -3357,16 +3185,12 @@ xfs_symlink( | |||
3357 | int link_namelen; | 3185 | int link_namelen; |
3358 | 3186 | ||
3359 | *vpp = NULL; | 3187 | *vpp = NULL; |
3360 | dir_vp = BHV_TO_VNODE(dir_bdp); | ||
3361 | dp = XFS_BHVTOI(dir_bdp); | ||
3362 | dp_joined_to_trans = B_FALSE; | ||
3363 | error = 0; | 3188 | error = 0; |
3364 | ip = NULL; | 3189 | ip = NULL; |
3365 | tp = NULL; | 3190 | tp = NULL; |
3366 | 3191 | ||
3367 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | 3192 | vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address); |
3368 | 3193 | ||
3369 | mp = dp->i_mount; | ||
3370 | 3194 | ||
3371 | if (XFS_FORCED_SHUTDOWN(mp)) | 3195 | if (XFS_FORCED_SHUTDOWN(mp)) |
3372 | return XFS_ERROR(EIO); | 3196 | return XFS_ERROR(EIO); |
@@ -3405,7 +3229,7 @@ xfs_symlink( | |||
3405 | } | 3229 | } |
3406 | } | 3230 | } |
3407 | 3231 | ||
3408 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) { | 3232 | if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) { |
3409 | error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp, | 3233 | error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp, |
3410 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, | 3234 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, |
3411 | link_name, target_path, 0, 0, 0); | 3235 | link_name, target_path, 0, 0, 0); |
@@ -3418,8 +3242,6 @@ xfs_symlink( | |||
3418 | udqp = gdqp = NULL; | 3242 | udqp = gdqp = NULL; |
3419 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 3243 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) |
3420 | prid = dp->i_d.di_projid; | 3244 | prid = dp->i_d.di_projid; |
3421 | else if (vap->va_mask & XFS_AT_PROJID) | ||
3422 | prid = (xfs_prid_t)vap->va_projid; | ||
3423 | else | 3245 | else |
3424 | prid = (xfs_prid_t)dfltprid; | 3246 | prid = (xfs_prid_t)dfltprid; |
3425 | 3247 | ||
@@ -3452,11 +3274,11 @@ xfs_symlink( | |||
3452 | } | 3274 | } |
3453 | if (error) { | 3275 | if (error) { |
3454 | cancel_flags = 0; | 3276 | cancel_flags = 0; |
3455 | dp = NULL; | ||
3456 | goto error_return; | 3277 | goto error_return; |
3457 | } | 3278 | } |
3458 | 3279 | ||
3459 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | 3280 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); |
3281 | unlock_dp_on_error = B_TRUE; | ||
3460 | 3282 | ||
3461 | /* | 3283 | /* |
3462 | * Check whether the directory allows new symlinks or not. | 3284 | * Check whether the directory allows new symlinks or not. |
@@ -3488,7 +3310,7 @@ xfs_symlink( | |||
3488 | /* | 3310 | /* |
3489 | * Allocate an inode for the symlink. | 3311 | * Allocate an inode for the symlink. |
3490 | */ | 3312 | */ |
3491 | error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (vap->va_mode&~S_IFMT), | 3313 | error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT), |
3492 | 1, 0, credp, prid, resblks > 0, &ip, NULL); | 3314 | 1, 0, credp, prid, resblks > 0, &ip, NULL); |
3493 | if (error) { | 3315 | if (error) { |
3494 | if (error == ENOSPC) | 3316 | if (error == ENOSPC) |
@@ -3497,9 +3319,14 @@ xfs_symlink( | |||
3497 | } | 3319 | } |
3498 | ITRACE(ip); | 3320 | ITRACE(ip); |
3499 | 3321 | ||
3322 | /* | ||
3323 | * An error after we've joined dp to the transaction will result in the | ||
3324 | * transaction cancel unlocking dp so don't do it explicitly in the | ||
3325 | * error path. | ||
3326 | */ | ||
3500 | VN_HOLD(dir_vp); | 3327 | VN_HOLD(dir_vp); |
3501 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 3328 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
3502 | dp_joined_to_trans = B_TRUE; | 3329 | unlock_dp_on_error = B_FALSE; |
3503 | 3330 | ||
3504 | /* | 3331 | /* |
3505 | * Also attach the dquot(s) to it, if applicable. | 3332 | * Also attach the dquot(s) to it, if applicable. |
@@ -3605,8 +3432,7 @@ xfs_symlink( | |||
3605 | /* Fall through to std_return with error = 0 or errno from | 3432 | /* Fall through to std_return with error = 0 or errno from |
3606 | * xfs_trans_commit */ | 3433 | * xfs_trans_commit */ |
3607 | std_return: | 3434 | std_return: |
3608 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp), | 3435 | if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) { |
3609 | DM_EVENT_POSTSYMLINK)) { | ||
3610 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, | 3436 | (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK, |
3611 | dir_vp, DM_RIGHT_NULL, | 3437 | dir_vp, DM_RIGHT_NULL, |
3612 | error ? NULL : XFS_ITOV(ip), | 3438 | error ? NULL : XFS_ITOV(ip), |
@@ -3633,9 +3459,8 @@ std_return: | |||
3633 | XFS_QM_DQRELE(mp, udqp); | 3459 | XFS_QM_DQRELE(mp, udqp); |
3634 | XFS_QM_DQRELE(mp, gdqp); | 3460 | XFS_QM_DQRELE(mp, gdqp); |
3635 | 3461 | ||
3636 | if (!dp_joined_to_trans && (dp != NULL)) { | 3462 | if (unlock_dp_on_error) |
3637 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 3463 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
3638 | } | ||
3639 | 3464 | ||
3640 | goto std_return; | 3465 | goto std_return; |
3641 | } | 3466 | } |
@@ -3647,20 +3472,16 @@ std_return: | |||
3647 | * A fid routine that takes a pointer to a previously allocated | 3472 | * A fid routine that takes a pointer to a previously allocated |
3648 | * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. | 3473 | * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. |
3649 | */ | 3474 | */ |
3650 | STATIC int | 3475 | int |
3651 | xfs_fid2( | 3476 | xfs_fid2( |
3652 | bhv_desc_t *bdp, | 3477 | xfs_inode_t *ip, |
3653 | fid_t *fidp) | 3478 | fid_t *fidp) |
3654 | { | 3479 | { |
3655 | xfs_inode_t *ip; | 3480 | xfs_fid2_t *xfid = (xfs_fid2_t *)fidp; |
3656 | xfs_fid2_t *xfid; | ||
3657 | 3481 | ||
3658 | vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__, | 3482 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
3659 | (inst_t *)__return_address); | ||
3660 | ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); | 3483 | ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); |
3661 | 3484 | ||
3662 | xfid = (xfs_fid2_t *)fidp; | ||
3663 | ip = XFS_BHVTOI(bdp); | ||
3664 | xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); | 3485 | xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); |
3665 | xfid->fid_pad = 0; | 3486 | xfid->fid_pad = 0; |
3666 | /* | 3487 | /* |
@@ -3674,21 +3495,13 @@ xfs_fid2( | |||
3674 | } | 3495 | } |
3675 | 3496 | ||
3676 | 3497 | ||
3677 | /* | ||
3678 | * xfs_rwlock | ||
3679 | */ | ||
3680 | int | 3498 | int |
3681 | xfs_rwlock( | 3499 | xfs_rwlock( |
3682 | bhv_desc_t *bdp, | 3500 | xfs_inode_t *ip, |
3683 | bhv_vrwlock_t locktype) | 3501 | bhv_vrwlock_t locktype) |
3684 | { | 3502 | { |
3685 | xfs_inode_t *ip; | 3503 | if (S_ISDIR(ip->i_d.di_mode)) |
3686 | bhv_vnode_t *vp; | ||
3687 | |||
3688 | vp = BHV_TO_VNODE(bdp); | ||
3689 | if (VN_ISDIR(vp)) | ||
3690 | return 1; | 3504 | return 1; |
3691 | ip = XFS_BHVTOI(bdp); | ||
3692 | if (locktype == VRWLOCK_WRITE) { | 3505 | if (locktype == VRWLOCK_WRITE) { |
3693 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 3506 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
3694 | } else if (locktype == VRWLOCK_TRY_READ) { | 3507 | } else if (locktype == VRWLOCK_TRY_READ) { |
@@ -3705,21 +3518,13 @@ xfs_rwlock( | |||
3705 | } | 3518 | } |
3706 | 3519 | ||
3707 | 3520 | ||
3708 | /* | ||
3709 | * xfs_rwunlock | ||
3710 | */ | ||
3711 | void | 3521 | void |
3712 | xfs_rwunlock( | 3522 | xfs_rwunlock( |
3713 | bhv_desc_t *bdp, | 3523 | xfs_inode_t *ip, |
3714 | bhv_vrwlock_t locktype) | 3524 | bhv_vrwlock_t locktype) |
3715 | { | 3525 | { |
3716 | xfs_inode_t *ip; | 3526 | if (S_ISDIR(ip->i_d.di_mode)) |
3717 | bhv_vnode_t *vp; | 3527 | return; |
3718 | |||
3719 | vp = BHV_TO_VNODE(bdp); | ||
3720 | if (VN_ISDIR(vp)) | ||
3721 | return; | ||
3722 | ip = XFS_BHVTOI(bdp); | ||
3723 | if (locktype == VRWLOCK_WRITE) { | 3528 | if (locktype == VRWLOCK_WRITE) { |
3724 | /* | 3529 | /* |
3725 | * In the write case, we may have added a new entry to | 3530 | * In the write case, we may have added a new entry to |
@@ -3737,20 +3542,16 @@ xfs_rwunlock( | |||
3737 | return; | 3542 | return; |
3738 | } | 3543 | } |
3739 | 3544 | ||
3740 | STATIC int | 3545 | |
3546 | int | ||
3741 | xfs_inode_flush( | 3547 | xfs_inode_flush( |
3742 | bhv_desc_t *bdp, | 3548 | xfs_inode_t *ip, |
3743 | int flags) | 3549 | int flags) |
3744 | { | 3550 | { |
3745 | xfs_inode_t *ip; | 3551 | xfs_mount_t *mp = ip->i_mount; |
3746 | xfs_mount_t *mp; | 3552 | xfs_inode_log_item_t *iip = ip->i_itemp; |
3747 | xfs_inode_log_item_t *iip; | ||
3748 | int error = 0; | 3553 | int error = 0; |
3749 | 3554 | ||
3750 | ip = XFS_BHVTOI(bdp); | ||
3751 | mp = ip->i_mount; | ||
3752 | iip = ip->i_itemp; | ||
3753 | |||
3754 | if (XFS_FORCED_SHUTDOWN(mp)) | 3555 | if (XFS_FORCED_SHUTDOWN(mp)) |
3755 | return XFS_ERROR(EIO); | 3556 | return XFS_ERROR(EIO); |
3756 | 3557 | ||
@@ -3819,24 +3620,20 @@ xfs_inode_flush( | |||
3819 | return error; | 3620 | return error; |
3820 | } | 3621 | } |
3821 | 3622 | ||
3623 | |||
3822 | int | 3624 | int |
3823 | xfs_set_dmattrs ( | 3625 | xfs_set_dmattrs( |
3824 | bhv_desc_t *bdp, | 3626 | xfs_inode_t *ip, |
3825 | u_int evmask, | 3627 | u_int evmask, |
3826 | u_int16_t state, | 3628 | u_int16_t state) |
3827 | cred_t *credp) | ||
3828 | { | 3629 | { |
3829 | xfs_inode_t *ip; | 3630 | xfs_mount_t *mp = ip->i_mount; |
3830 | xfs_trans_t *tp; | 3631 | xfs_trans_t *tp; |
3831 | xfs_mount_t *mp; | ||
3832 | int error; | 3632 | int error; |
3833 | 3633 | ||
3834 | if (!capable(CAP_SYS_ADMIN)) | 3634 | if (!capable(CAP_SYS_ADMIN)) |
3835 | return XFS_ERROR(EPERM); | 3635 | return XFS_ERROR(EPERM); |
3836 | 3636 | ||
3837 | ip = XFS_BHVTOI(bdp); | ||
3838 | mp = ip->i_mount; | ||
3839 | |||
3840 | if (XFS_FORCED_SHUTDOWN(mp)) | 3637 | if (XFS_FORCED_SHUTDOWN(mp)) |
3841 | return XFS_ERROR(EIO); | 3638 | return XFS_ERROR(EIO); |
3842 | 3639 | ||
@@ -3859,17 +3656,13 @@ xfs_set_dmattrs ( | |||
3859 | return error; | 3656 | return error; |
3860 | } | 3657 | } |
3861 | 3658 | ||
3862 | STATIC int | 3659 | int |
3863 | xfs_reclaim( | 3660 | xfs_reclaim( |
3864 | bhv_desc_t *bdp) | 3661 | xfs_inode_t *ip) |
3865 | { | 3662 | { |
3866 | xfs_inode_t *ip; | 3663 | bhv_vnode_t *vp = XFS_ITOV(ip); |
3867 | bhv_vnode_t *vp; | ||
3868 | |||
3869 | vp = BHV_TO_VNODE(bdp); | ||
3870 | ip = XFS_BHVTOI(bdp); | ||
3871 | 3664 | ||
3872 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 3665 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
3873 | 3666 | ||
3874 | ASSERT(!VN_MAPPED(vp)); | 3667 | ASSERT(!VN_MAPPED(vp)); |
3875 | 3668 | ||
@@ -3879,7 +3672,7 @@ xfs_reclaim( | |||
3879 | return 0; | 3672 | return 0; |
3880 | } | 3673 | } |
3881 | 3674 | ||
3882 | vn_iowait(vp); | 3675 | vn_iowait(ip); |
3883 | 3676 | ||
3884 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); | 3677 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); |
3885 | 3678 | ||
@@ -3911,7 +3704,8 @@ xfs_reclaim( | |||
3911 | XFS_MOUNT_ILOCK(mp); | 3704 | XFS_MOUNT_ILOCK(mp); |
3912 | spin_lock(&ip->i_flags_lock); | 3705 | spin_lock(&ip->i_flags_lock); |
3913 | __xfs_iflags_set(ip, XFS_IRECLAIMABLE); | 3706 | __xfs_iflags_set(ip, XFS_IRECLAIMABLE); |
3914 | vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); | 3707 | vn_to_inode(vp)->i_private = NULL; |
3708 | ip->i_vnode = NULL; | ||
3915 | spin_unlock(&ip->i_flags_lock); | 3709 | spin_unlock(&ip->i_flags_lock); |
3916 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); | 3710 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); |
3917 | XFS_MOUNT_IUNLOCK(mp); | 3711 | XFS_MOUNT_IUNLOCK(mp); |
@@ -3925,7 +3719,7 @@ xfs_finish_reclaim( | |||
3925 | int locked, | 3719 | int locked, |
3926 | int sync_mode) | 3720 | int sync_mode) |
3927 | { | 3721 | { |
3928 | xfs_ihash_t *ih = ip->i_hash; | 3722 | xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); |
3929 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); | 3723 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); |
3930 | int error; | 3724 | int error; |
3931 | 3725 | ||
@@ -3937,12 +3731,12 @@ xfs_finish_reclaim( | |||
3937 | * Once we have the XFS_IRECLAIM flag set it will not touch | 3731 | * Once we have the XFS_IRECLAIM flag set it will not touch |
3938 | * us. | 3732 | * us. |
3939 | */ | 3733 | */ |
3940 | write_lock(&ih->ih_lock); | 3734 | write_lock(&pag->pag_ici_lock); |
3941 | spin_lock(&ip->i_flags_lock); | 3735 | spin_lock(&ip->i_flags_lock); |
3942 | if (__xfs_iflags_test(ip, XFS_IRECLAIM) || | 3736 | if (__xfs_iflags_test(ip, XFS_IRECLAIM) || |
3943 | (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) { | 3737 | (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) { |
3944 | spin_unlock(&ip->i_flags_lock); | 3738 | spin_unlock(&ip->i_flags_lock); |
3945 | write_unlock(&ih->ih_lock); | 3739 | write_unlock(&pag->pag_ici_lock); |
3946 | if (locked) { | 3740 | if (locked) { |
3947 | xfs_ifunlock(ip); | 3741 | xfs_ifunlock(ip); |
3948 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 3742 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
@@ -3951,7 +3745,8 @@ xfs_finish_reclaim( | |||
3951 | } | 3745 | } |
3952 | __xfs_iflags_set(ip, XFS_IRECLAIM); | 3746 | __xfs_iflags_set(ip, XFS_IRECLAIM); |
3953 | spin_unlock(&ip->i_flags_lock); | 3747 | spin_unlock(&ip->i_flags_lock); |
3954 | write_unlock(&ih->ih_lock); | 3748 | write_unlock(&pag->pag_ici_lock); |
3749 | xfs_put_perag(ip->i_mount, pag); | ||
3955 | 3750 | ||
3956 | /* | 3751 | /* |
3957 | * If the inode is still dirty, then flush it out. If the inode | 3752 | * If the inode is still dirty, then flush it out. If the inode |
@@ -4085,7 +3880,7 @@ xfs_alloc_file_space( | |||
4085 | int committed; | 3880 | int committed; |
4086 | int error; | 3881 | int error; |
4087 | 3882 | ||
4088 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); | 3883 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
4089 | 3884 | ||
4090 | if (XFS_FORCED_SHUTDOWN(mp)) | 3885 | if (XFS_FORCED_SHUTDOWN(mp)) |
4091 | return XFS_ERROR(EIO); | 3886 | return XFS_ERROR(EIO); |
@@ -4109,7 +3904,7 @@ xfs_alloc_file_space( | |||
4109 | /* Generate a DMAPI event if needed. */ | 3904 | /* Generate a DMAPI event if needed. */ |
4110 | if (alloc_type != 0 && offset < ip->i_size && | 3905 | if (alloc_type != 0 && offset < ip->i_size && |
4111 | (attr_flags&ATTR_DMI) == 0 && | 3906 | (attr_flags&ATTR_DMI) == 0 && |
4112 | DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { | 3907 | DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) { |
4113 | xfs_off_t end_dmi_offset; | 3908 | xfs_off_t end_dmi_offset; |
4114 | 3909 | ||
4115 | end_dmi_offset = offset+len; | 3910 | end_dmi_offset = offset+len; |
@@ -4223,9 +4018,8 @@ retry: | |||
4223 | allocatesize_fsb -= allocated_fsb; | 4018 | allocatesize_fsb -= allocated_fsb; |
4224 | } | 4019 | } |
4225 | dmapi_enospc_check: | 4020 | dmapi_enospc_check: |
4226 | if (error == ENOSPC && (attr_flags&ATTR_DMI) == 0 && | 4021 | if (error == ENOSPC && (attr_flags & ATTR_DMI) == 0 && |
4227 | DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) { | 4022 | DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) { |
4228 | |||
4229 | error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE, | 4023 | error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE, |
4230 | XFS_ITOV(ip), DM_RIGHT_NULL, | 4024 | XFS_ITOV(ip), DM_RIGHT_NULL, |
4231 | XFS_ITOV(ip), DM_RIGHT_NULL, | 4025 | XFS_ITOV(ip), DM_RIGHT_NULL, |
@@ -4356,7 +4150,7 @@ xfs_free_file_space( | |||
4356 | vp = XFS_ITOV(ip); | 4150 | vp = XFS_ITOV(ip); |
4357 | mp = ip->i_mount; | 4151 | mp = ip->i_mount; |
4358 | 4152 | ||
4359 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 4153 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
4360 | 4154 | ||
4361 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) | 4155 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) |
4362 | return error; | 4156 | return error; |
@@ -4369,9 +4163,8 @@ xfs_free_file_space( | |||
4369 | end_dmi_offset = offset + len; | 4163 | end_dmi_offset = offset + len; |
4370 | endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); | 4164 | endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset); |
4371 | 4165 | ||
4372 | if (offset < ip->i_size && | 4166 | if (offset < ip->i_size && (attr_flags & ATTR_DMI) == 0 && |
4373 | (attr_flags & ATTR_DMI) == 0 && | 4167 | DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) { |
4374 | DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { | ||
4375 | if (end_dmi_offset > ip->i_size) | 4168 | if (end_dmi_offset > ip->i_size) |
4376 | end_dmi_offset = ip->i_size; | 4169 | end_dmi_offset = ip->i_size; |
4377 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, | 4170 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp, |
@@ -4385,7 +4178,7 @@ xfs_free_file_space( | |||
4385 | need_iolock = 0; | 4178 | need_iolock = 0; |
4386 | if (need_iolock) { | 4179 | if (need_iolock) { |
4387 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 4180 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
4388 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ | 4181 | vn_iowait(ip); /* wait for the completion of any pending DIOs */ |
4389 | } | 4182 | } |
4390 | 4183 | ||
4391 | rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); | 4184 | rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); |
@@ -4394,7 +4187,8 @@ xfs_free_file_space( | |||
4394 | if (VN_CACHED(vp) != 0) { | 4187 | if (VN_CACHED(vp) != 0) { |
4395 | xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, | 4188 | xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, |
4396 | ctooff(offtoct(ioffset)), -1); | 4189 | ctooff(offtoct(ioffset)), -1); |
4397 | error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)), | 4190 | error = xfs_flushinval_pages(ip, |
4191 | ctooff(offtoct(ioffset)), | ||
4398 | -1, FI_REMAPF_LOCKED); | 4192 | -1, FI_REMAPF_LOCKED); |
4399 | if (error) | 4193 | if (error) |
4400 | goto out_unlock_iolock; | 4194 | goto out_unlock_iolock; |
@@ -4545,35 +4339,29 @@ xfs_free_file_space( | |||
4545 | */ | 4339 | */ |
4546 | int | 4340 | int |
4547 | xfs_change_file_space( | 4341 | xfs_change_file_space( |
4548 | bhv_desc_t *bdp, | 4342 | xfs_inode_t *ip, |
4549 | int cmd, | 4343 | int cmd, |
4550 | xfs_flock64_t *bf, | 4344 | xfs_flock64_t *bf, |
4551 | xfs_off_t offset, | 4345 | xfs_off_t offset, |
4552 | cred_t *credp, | 4346 | cred_t *credp, |
4553 | int attr_flags) | 4347 | int attr_flags) |
4554 | { | 4348 | { |
4349 | xfs_mount_t *mp = ip->i_mount; | ||
4555 | int clrprealloc; | 4350 | int clrprealloc; |
4556 | int error; | 4351 | int error; |
4557 | xfs_fsize_t fsize; | 4352 | xfs_fsize_t fsize; |
4558 | xfs_inode_t *ip; | ||
4559 | xfs_mount_t *mp; | ||
4560 | int setprealloc; | 4353 | int setprealloc; |
4561 | xfs_off_t startoffset; | 4354 | xfs_off_t startoffset; |
4562 | xfs_off_t llen; | 4355 | xfs_off_t llen; |
4563 | xfs_trans_t *tp; | 4356 | xfs_trans_t *tp; |
4564 | bhv_vattr_t va; | 4357 | bhv_vattr_t va; |
4565 | bhv_vnode_t *vp; | ||
4566 | 4358 | ||
4567 | vp = BHV_TO_VNODE(bdp); | 4359 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
4568 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | ||
4569 | |||
4570 | ip = XFS_BHVTOI(bdp); | ||
4571 | mp = ip->i_mount; | ||
4572 | 4360 | ||
4573 | /* | 4361 | /* |
4574 | * must be a regular file and have write permission | 4362 | * must be a regular file and have write permission |
4575 | */ | 4363 | */ |
4576 | if (!VN_ISREG(vp)) | 4364 | if (!S_ISREG(ip->i_d.di_mode)) |
4577 | return XFS_ERROR(EINVAL); | 4365 | return XFS_ERROR(EINVAL); |
4578 | 4366 | ||
4579 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 4367 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
@@ -4655,7 +4443,7 @@ xfs_change_file_space( | |||
4655 | va.va_mask = XFS_AT_SIZE; | 4443 | va.va_mask = XFS_AT_SIZE; |
4656 | va.va_size = startoffset; | 4444 | va.va_size = startoffset; |
4657 | 4445 | ||
4658 | error = xfs_setattr(bdp, &va, attr_flags, credp); | 4446 | error = xfs_setattr(ip, &va, attr_flags, credp); |
4659 | 4447 | ||
4660 | if (error) | 4448 | if (error) |
4661 | return error; | 4449 | return error; |
@@ -4714,46 +4502,3 @@ xfs_change_file_space( | |||
4714 | 4502 | ||
4715 | return error; | 4503 | return error; |
4716 | } | 4504 | } |
4717 | |||
4718 | bhv_vnodeops_t xfs_vnodeops = { | ||
4719 | BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), | ||
4720 | .vop_open = xfs_open, | ||
4721 | .vop_read = xfs_read, | ||
4722 | #ifdef HAVE_SPLICE | ||
4723 | .vop_splice_read = xfs_splice_read, | ||
4724 | .vop_splice_write = xfs_splice_write, | ||
4725 | #endif | ||
4726 | .vop_write = xfs_write, | ||
4727 | .vop_ioctl = xfs_ioctl, | ||
4728 | .vop_getattr = xfs_getattr, | ||
4729 | .vop_setattr = xfs_setattr, | ||
4730 | .vop_access = xfs_access, | ||
4731 | .vop_lookup = xfs_lookup, | ||
4732 | .vop_create = xfs_create, | ||
4733 | .vop_remove = xfs_remove, | ||
4734 | .vop_link = xfs_link, | ||
4735 | .vop_rename = xfs_rename, | ||
4736 | .vop_mkdir = xfs_mkdir, | ||
4737 | .vop_rmdir = xfs_rmdir, | ||
4738 | .vop_readdir = xfs_readdir, | ||
4739 | .vop_symlink = xfs_symlink, | ||
4740 | .vop_readlink = xfs_readlink, | ||
4741 | .vop_fsync = xfs_fsync, | ||
4742 | .vop_inactive = xfs_inactive, | ||
4743 | .vop_fid2 = xfs_fid2, | ||
4744 | .vop_rwlock = xfs_rwlock, | ||
4745 | .vop_rwunlock = xfs_rwunlock, | ||
4746 | .vop_bmap = xfs_bmap, | ||
4747 | .vop_reclaim = xfs_reclaim, | ||
4748 | .vop_attr_get = xfs_attr_get, | ||
4749 | .vop_attr_set = xfs_attr_set, | ||
4750 | .vop_attr_remove = xfs_attr_remove, | ||
4751 | .vop_attr_list = xfs_attr_list, | ||
4752 | .vop_link_removed = (vop_link_removed_t)fs_noval, | ||
4753 | .vop_vnode_change = (vop_vnode_change_t)fs_noval, | ||
4754 | .vop_tosspages = fs_tosspages, | ||
4755 | .vop_flushinval_pages = fs_flushinval_pages, | ||
4756 | .vop_flush_pages = fs_flush_pages, | ||
4757 | .vop_release = xfs_release, | ||
4758 | .vop_iflush = xfs_inode_flush, | ||
4759 | }; | ||
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h new file mode 100644 index 000000000000..f36e74f2f0c2 --- /dev/null +++ b/fs/xfs/xfs_vnodeops.h | |||
@@ -0,0 +1,86 @@ | |||
1 | #ifndef _XFS_VNODEOPS_H | ||
2 | #define _XFS_VNODEOPS_H 1 | ||
3 | |||
4 | struct attrlist_cursor_kern; | ||
5 | struct bhv_vattr; | ||
6 | struct cred; | ||
7 | struct file; | ||
8 | struct inode; | ||
9 | struct iovec; | ||
10 | struct kiocb; | ||
11 | struct pipe_inode_info; | ||
12 | struct uio; | ||
13 | struct xfs_inode; | ||
14 | struct xfs_iomap; | ||
15 | |||
16 | |||
17 | int xfs_open(struct xfs_inode *ip); | ||
18 | int xfs_getattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags); | ||
19 | int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, | ||
20 | struct cred *credp); | ||
21 | int xfs_access(struct xfs_inode *ip, int mode, struct cred *credp); | ||
22 | int xfs_readlink(struct xfs_inode *ip, char *link); | ||
23 | int xfs_fsync(struct xfs_inode *ip, int flag, xfs_off_t start, | ||
24 | xfs_off_t stop); | ||
25 | int xfs_release(struct xfs_inode *ip); | ||
26 | int xfs_inactive(struct xfs_inode *ip); | ||
27 | int xfs_lookup(struct xfs_inode *dp, bhv_vname_t *dentry, | ||
28 | bhv_vnode_t **vpp); | ||
29 | int xfs_create(struct xfs_inode *dp, bhv_vname_t *dentry, mode_t mode, | ||
30 | xfs_dev_t rdev, bhv_vnode_t **vpp, struct cred *credp); | ||
31 | int xfs_remove(struct xfs_inode *dp, bhv_vname_t *dentry); | ||
32 | int xfs_link(struct xfs_inode *tdp, bhv_vnode_t *src_vp, | ||
33 | bhv_vname_t *dentry); | ||
34 | int xfs_mkdir(struct xfs_inode *dp, bhv_vname_t *dentry, | ||
35 | mode_t mode, bhv_vnode_t **vpp, struct cred *credp); | ||
36 | int xfs_rmdir(struct xfs_inode *dp, bhv_vname_t *dentry); | ||
37 | int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize, | ||
38 | xfs_off_t *offset, filldir_t filldir); | ||
39 | int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry, | ||
40 | char *target_path, mode_t mode, bhv_vnode_t **vpp, | ||
41 | struct cred *credp); | ||
42 | int xfs_fid2(struct xfs_inode *ip, fid_t *fidp); | ||
43 | int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); | ||
44 | void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); | ||
45 | int xfs_inode_flush(struct xfs_inode *ip, int flags); | ||
46 | int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); | ||
47 | int xfs_reclaim(struct xfs_inode *ip); | ||
48 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, | ||
49 | xfs_flock64_t *bf, xfs_off_t offset, | ||
50 | struct cred *credp, int attr_flags); | ||
51 | int xfs_rename(struct xfs_inode *src_dp, bhv_vname_t *src_vname, | ||
52 | bhv_vnode_t *target_dir_vp, bhv_vname_t *target_vname); | ||
53 | int xfs_attr_get(struct xfs_inode *ip, const char *name, char *value, | ||
54 | int *valuelenp, int flags, cred_t *cred); | ||
55 | int xfs_attr_set(struct xfs_inode *dp, const char *name, char *value, | ||
56 | int valuelen, int flags); | ||
57 | int xfs_attr_remove(struct xfs_inode *dp, const char *name, int flags); | ||
58 | int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, | ||
59 | int flags, struct attrlist_cursor_kern *cursor); | ||
60 | int xfs_ioctl(struct xfs_inode *ip, struct file *filp, | ||
61 | int ioflags, unsigned int cmd, void __user *arg); | ||
62 | ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb, | ||
63 | const struct iovec *iovp, unsigned int segs, | ||
64 | loff_t *offset, int ioflags); | ||
65 | ssize_t xfs_sendfile(struct xfs_inode *ip, struct file *filp, | ||
66 | loff_t *offset, int ioflags, size_t count, | ||
67 | read_actor_t actor, void *target); | ||
68 | ssize_t xfs_splice_read(struct xfs_inode *ip, struct file *infilp, | ||
69 | loff_t *ppos, struct pipe_inode_info *pipe, size_t count, | ||
70 | int flags, int ioflags); | ||
71 | ssize_t xfs_splice_write(struct xfs_inode *ip, | ||
72 | struct pipe_inode_info *pipe, struct file *outfilp, | ||
73 | loff_t *ppos, size_t count, int flags, int ioflags); | ||
74 | ssize_t xfs_write(struct xfs_inode *xip, struct kiocb *iocb, | ||
75 | const struct iovec *iovp, unsigned int nsegs, | ||
76 | loff_t *offset, int ioflags); | ||
77 | int xfs_bmap(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, | ||
78 | int flags, struct xfs_iomap *iomapp, int *niomaps); | ||
79 | void xfs_tosspages(struct xfs_inode *inode, xfs_off_t first, | ||
80 | xfs_off_t last, int fiopt); | ||
81 | int xfs_flushinval_pages(struct xfs_inode *ip, xfs_off_t first, | ||
82 | xfs_off_t last, int fiopt); | ||
83 | int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first, | ||
84 | xfs_off_t last, uint64_t flags, int fiopt); | ||
85 | |||
86 | #endif /* _XFS_VNODEOPS_H */ | ||