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 */ | ||
