diff options
Diffstat (limited to 'fs/xfs')
109 files changed, 2326 insertions, 6268 deletions
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index bac27d66151d..26b364c9d62c 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig | |||
@@ -1,6 +1,5 @@ | |||
1 | config XFS_FS | 1 | config XFS_FS |
2 | tristate "XFS filesystem support" | 2 | tristate "XFS filesystem support" |
3 | select EXPORTFS if NFSD!=n | ||
4 | help | 3 | help |
5 | XFS is a high performance journaling filesystem which originated | 4 | XFS is a high performance journaling filesystem which originated |
6 | on the SGI IRIX platform. It is completely multi-threaded, can | 5 | on the SGI IRIX platform. It is completely multi-threaded, can |
@@ -18,11 +17,6 @@ config XFS_FS | |||
18 | system of your root partition is compiled as a module, you'll need | 17 | system of your root partition is compiled as a module, you'll need |
19 | to use an initial ramdisk (initrd) to boot. | 18 | to use an initial ramdisk (initrd) to boot. |
20 | 19 | ||
21 | config XFS_EXPORT | ||
22 | bool | ||
23 | depends on XFS_FS && EXPORTFS | ||
24 | default y | ||
25 | |||
26 | config XFS_QUOTA | 20 | config XFS_QUOTA |
27 | bool "XFS Quota support" | 21 | bool "XFS Quota support" |
28 | depends on XFS_FS | 22 | depends on XFS_FS |
@@ -65,18 +59,19 @@ config XFS_POSIX_ACL | |||
65 | If you don't know what Access Control Lists are, say N. | 59 | If you don't know what Access Control Lists are, say N. |
66 | 60 | ||
67 | config XFS_RT | 61 | config XFS_RT |
68 | bool "XFS Realtime support (EXPERIMENTAL)" | 62 | bool "XFS Realtime subvolume support" |
69 | depends on XFS_FS && EXPERIMENTAL | 63 | depends on XFS_FS |
70 | help | 64 | help |
71 | If you say Y here you will be able to mount and use XFS filesystems | 65 | If you say Y here you will be able to mount and use XFS filesystems |
72 | which contain a realtime subvolume. The realtime subvolume is a | 66 | which contain a realtime subvolume. The realtime subvolume is a |
73 | separate area of disk space where only file data is stored. The | 67 | separate area of disk space where only file data is stored. It was |
74 | realtime subvolume is designed to provide very deterministic | 68 | originally designed to provide deterministic data rates suitable |
75 | data rates suitable for media streaming applications. | 69 | for media streaming applications, but is also useful as a generic |
76 | 70 | mechanism for ensuring data and metadata/log I/Os are completely | |
77 | See the xfs man page in section 5 for a bit more information. | 71 | separated. Regular file I/Os are isolated to a separate device |
72 | from all other requests, and this can be done quite transparently | ||
73 | to applications via the inherit-realtime directory inode flag. | ||
78 | 74 | ||
79 | This feature is unsupported at this time, is not yet fully | 75 | See the xfs man page in section 5 for additional information. |
80 | functional, and may cause serious problems. | ||
81 | 76 | ||
82 | If unsure, say N. | 77 | If unsure, say N. |
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 index 5d73eaa1971f..9e7f85986d0d 100644 --- a/fs/xfs/Makefile-linux-2.6 +++ b/fs/xfs/Makefile-linux-2.6 | |||
@@ -59,7 +59,6 @@ xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o | |||
59 | xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o | 59 | xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o |
60 | xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o | 60 | xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o |
61 | xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o | 61 | xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o |
62 | xfs-$(CONFIG_XFS_EXPORT) += $(XFS_LINUX)/xfs_export.o | ||
63 | 62 | ||
64 | 63 | ||
65 | xfs-y += xfs_alloc.o \ | 64 | xfs-y += xfs_alloc.o \ |
@@ -73,14 +72,12 @@ xfs-y += xfs_alloc.o \ | |||
73 | xfs_btree.o \ | 72 | xfs_btree.o \ |
74 | xfs_buf_item.o \ | 73 | xfs_buf_item.o \ |
75 | xfs_da_btree.o \ | 74 | xfs_da_btree.o \ |
76 | xfs_dir.o \ | ||
77 | xfs_dir2.o \ | 75 | xfs_dir2.o \ |
78 | xfs_dir2_block.o \ | 76 | xfs_dir2_block.o \ |
79 | xfs_dir2_data.o \ | 77 | xfs_dir2_data.o \ |
80 | xfs_dir2_leaf.o \ | 78 | xfs_dir2_leaf.o \ |
81 | xfs_dir2_node.o \ | 79 | xfs_dir2_node.o \ |
82 | xfs_dir2_sf.o \ | 80 | xfs_dir2_sf.o \ |
83 | xfs_dir_leaf.o \ | ||
84 | xfs_error.o \ | 81 | xfs_error.o \ |
85 | xfs_extfree_item.o \ | 82 | xfs_extfree_item.o \ |
86 | xfs_fsops.o \ | 83 | xfs_fsops.o \ |
@@ -117,6 +114,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \ | |||
117 | kmem.o \ | 114 | kmem.o \ |
118 | xfs_aops.o \ | 115 | xfs_aops.o \ |
119 | xfs_buf.o \ | 116 | xfs_buf.o \ |
117 | xfs_export.o \ | ||
120 | xfs_file.o \ | 118 | xfs_file.o \ |
121 | xfs_fs_subr.o \ | 119 | xfs_fs_subr.o \ |
122 | xfs_globals.o \ | 120 | xfs_globals.o \ |
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h index 2cfd33d4d8aa..939bd84bc7ee 100644 --- a/fs/xfs/linux-2.6/kmem.h +++ b/fs/xfs/linux-2.6/kmem.h | |||
@@ -23,42 +23,6 @@ | |||
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * Process flags handling | ||
27 | */ | ||
28 | |||
29 | #define PFLAGS_TEST_NOIO() (current->flags & PF_NOIO) | ||
30 | #define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS) | ||
31 | |||
32 | #define PFLAGS_SET_NOIO() do { \ | ||
33 | current->flags |= PF_NOIO; \ | ||
34 | } while (0) | ||
35 | |||
36 | #define PFLAGS_CLEAR_NOIO() do { \ | ||
37 | current->flags &= ~PF_NOIO; \ | ||
38 | } while (0) | ||
39 | |||
40 | /* these could be nested, so we save state */ | ||
41 | #define PFLAGS_SET_FSTRANS(STATEP) do { \ | ||
42 | *(STATEP) = current->flags; \ | ||
43 | current->flags |= PF_FSTRANS; \ | ||
44 | } while (0) | ||
45 | |||
46 | #define PFLAGS_CLEAR_FSTRANS(STATEP) do { \ | ||
47 | *(STATEP) = current->flags; \ | ||
48 | current->flags &= ~PF_FSTRANS; \ | ||
49 | } while (0) | ||
50 | |||
51 | /* Restore the PF_FSTRANS state to what was saved in STATEP */ | ||
52 | #define PFLAGS_RESTORE_FSTRANS(STATEP) do { \ | ||
53 | current->flags = ((current->flags & ~PF_FSTRANS) | \ | ||
54 | (*(STATEP) & PF_FSTRANS)); \ | ||
55 | } while (0) | ||
56 | |||
57 | #define PFLAGS_DUP(OSTATEP, NSTATEP) do { \ | ||
58 | *(NSTATEP) = *(OSTATEP); \ | ||
59 | } while (0) | ||
60 | |||
61 | /* | ||
62 | * General memory allocation interfaces | 26 | * General memory allocation interfaces |
63 | */ | 27 | */ |
64 | 28 | ||
@@ -83,7 +47,7 @@ kmem_flags_convert(unsigned int __nocast flags) | |||
83 | lflags = GFP_ATOMIC | __GFP_NOWARN; | 47 | lflags = GFP_ATOMIC | __GFP_NOWARN; |
84 | } else { | 48 | } else { |
85 | lflags = GFP_KERNEL | __GFP_NOWARN; | 49 | lflags = GFP_KERNEL | __GFP_NOWARN; |
86 | if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS)) | 50 | if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS)) |
87 | lflags &= ~__GFP_FS; | 51 | lflags &= ~__GFP_FS; |
88 | } | 52 | } |
89 | return lflags; | 53 | return lflags; |
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/linux-2.6/mrlock.h index 1b262b790d9c..32e1ce0f04c9 100644 --- a/fs/xfs/linux-2.6/mrlock.h +++ b/fs/xfs/linux-2.6/mrlock.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -28,7 +28,7 @@ typedef struct { | |||
28 | } mrlock_t; | 28 | } mrlock_t; |
29 | 29 | ||
30 | #define mrinit(mrp, name) \ | 30 | #define mrinit(mrp, name) \ |
31 | ( (mrp)->mr_writer = 0, init_rwsem(&(mrp)->mr_lock) ) | 31 | do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0) |
32 | #define mrlock_init(mrp, t,n,s) mrinit(mrp, n) | 32 | #define mrlock_init(mrp, t,n,s) mrinit(mrp, n) |
33 | #define mrfree(mrp) do { } while (0) | 33 | #define mrfree(mrp) do { } while (0) |
34 | #define mraccess(mrp) mraccessf(mrp, 0) | 34 | #define mraccess(mrp) mraccessf(mrp, 0) |
diff --git a/fs/xfs/linux-2.6/sema.h b/fs/xfs/linux-2.6/sema.h index 194a84490bd1..b25090094cca 100644 --- a/fs/xfs/linux-2.6/sema.h +++ b/fs/xfs/linux-2.6/sema.h | |||
@@ -34,20 +34,21 @@ typedef struct semaphore sema_t; | |||
34 | #define initnsema(sp, val, name) sema_init(sp, val) | 34 | #define initnsema(sp, val, name) sema_init(sp, val) |
35 | #define psema(sp, b) down(sp) | 35 | #define psema(sp, b) down(sp) |
36 | #define vsema(sp) up(sp) | 36 | #define vsema(sp) up(sp) |
37 | #define valusema(sp) (atomic_read(&(sp)->count)) | 37 | #define freesema(sema) do { } while (0) |
38 | #define freesema(sema) | 38 | |
39 | static inline int issemalocked(sema_t *sp) | ||
40 | { | ||
41 | return down_trylock(sp) || (up(sp), 0); | ||
42 | } | ||
39 | 43 | ||
40 | /* | 44 | /* |
41 | * Map cpsema (try to get the sema) to down_trylock. We need to switch | 45 | * Map cpsema (try to get the sema) to down_trylock. We need to switch |
42 | * the return values since cpsema returns 1 (acquired) 0 (failed) and | 46 | * the return values since cpsema returns 1 (acquired) 0 (failed) and |
43 | * down_trylock returns the reverse 0 (acquired) 1 (failed). | 47 | * down_trylock returns the reverse 0 (acquired) 1 (failed). |
44 | */ | 48 | */ |
45 | 49 | static inline int cpsema(sema_t *sp) | |
46 | #define cpsema(sp) (down_trylock(sp) ? 0 : 1) | 50 | { |
47 | 51 | return down_trylock(sp) ? 0 : 1; | |
48 | /* | 52 | } |
49 | * Didn't do cvsema(sp). Not sure how to map this to up/down/... | ||
50 | * It does a vsema if the values is < 0 other wise nothing. | ||
51 | */ | ||
52 | 53 | ||
53 | #endif /* __XFS_SUPPORT_SEMA_H__ */ | 54 | #endif /* __XFS_SUPPORT_SEMA_H__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 4d191ef39b67..3e807b828e22 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "xfs_inum.h" | 21 | #include "xfs_inum.h" |
22 | #include "xfs_sb.h" | 22 | #include "xfs_sb.h" |
23 | #include "xfs_ag.h" | 23 | #include "xfs_ag.h" |
24 | #include "xfs_dir.h" | ||
25 | #include "xfs_dir2.h" | 24 | #include "xfs_dir2.h" |
26 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
@@ -29,7 +28,6 @@ | |||
29 | #include "xfs_bmap_btree.h" | 28 | #include "xfs_bmap_btree.h" |
30 | #include "xfs_alloc_btree.h" | 29 | #include "xfs_alloc_btree.h" |
31 | #include "xfs_ialloc_btree.h" | 30 | #include "xfs_ialloc_btree.h" |
32 | #include "xfs_dir_sf.h" | ||
33 | #include "xfs_dir2_sf.h" | 31 | #include "xfs_dir2_sf.h" |
34 | #include "xfs_attr_sf.h" | 32 | #include "xfs_attr_sf.h" |
35 | #include "xfs_dinode.h" | 33 | #include "xfs_dinode.h" |
@@ -76,7 +74,7 @@ xfs_page_trace( | |||
76 | int mask) | 74 | int mask) |
77 | { | 75 | { |
78 | xfs_inode_t *ip; | 76 | xfs_inode_t *ip; |
79 | vnode_t *vp = vn_from_inode(inode); | 77 | bhv_vnode_t *vp = vn_from_inode(inode); |
80 | loff_t isize = i_size_read(inode); | 78 | loff_t isize = i_size_read(inode); |
81 | loff_t offset = page_offset(page); | 79 | loff_t offset = page_offset(page); |
82 | int delalloc = -1, unmapped = -1, unwritten = -1; | 80 | int delalloc = -1, unmapped = -1, unwritten = -1; |
@@ -136,9 +134,10 @@ xfs_destroy_ioend( | |||
136 | 134 | ||
137 | for (bh = ioend->io_buffer_head; bh; bh = next) { | 135 | for (bh = ioend->io_buffer_head; bh; bh = next) { |
138 | next = bh->b_private; | 136 | next = bh->b_private; |
139 | bh->b_end_io(bh, ioend->io_uptodate); | 137 | bh->b_end_io(bh, !ioend->io_error); |
140 | } | 138 | } |
141 | 139 | if (unlikely(ioend->io_error)) | |
140 | vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__); | ||
142 | vn_iowake(ioend->io_vnode); | 141 | vn_iowake(ioend->io_vnode); |
143 | mempool_free(ioend, xfs_ioend_pool); | 142 | mempool_free(ioend, xfs_ioend_pool); |
144 | } | 143 | } |
@@ -180,13 +179,12 @@ xfs_end_bio_unwritten( | |||
180 | void *data) | 179 | void *data) |
181 | { | 180 | { |
182 | xfs_ioend_t *ioend = data; | 181 | xfs_ioend_t *ioend = data; |
183 | vnode_t *vp = ioend->io_vnode; | 182 | bhv_vnode_t *vp = ioend->io_vnode; |
184 | xfs_off_t offset = ioend->io_offset; | 183 | xfs_off_t offset = ioend->io_offset; |
185 | size_t size = ioend->io_size; | 184 | size_t size = ioend->io_size; |
186 | int error; | ||
187 | 185 | ||
188 | if (ioend->io_uptodate) | 186 | if (likely(!ioend->io_error)) |
189 | VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error); | 187 | bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL); |
190 | xfs_destroy_ioend(ioend); | 188 | xfs_destroy_ioend(ioend); |
191 | } | 189 | } |
192 | 190 | ||
@@ -211,7 +209,7 @@ xfs_alloc_ioend( | |||
211 | * all the I/O from calling the completion routine too early. | 209 | * all the I/O from calling the completion routine too early. |
212 | */ | 210 | */ |
213 | atomic_set(&ioend->io_remaining, 1); | 211 | atomic_set(&ioend->io_remaining, 1); |
214 | ioend->io_uptodate = 1; /* cleared if any I/O fails */ | 212 | ioend->io_error = 0; |
215 | ioend->io_list = NULL; | 213 | ioend->io_list = NULL; |
216 | ioend->io_type = type; | 214 | ioend->io_type = type; |
217 | ioend->io_vnode = vn_from_inode(inode); | 215 | ioend->io_vnode = vn_from_inode(inode); |
@@ -239,10 +237,10 @@ xfs_map_blocks( | |||
239 | xfs_iomap_t *mapp, | 237 | xfs_iomap_t *mapp, |
240 | int flags) | 238 | int flags) |
241 | { | 239 | { |
242 | vnode_t *vp = vn_from_inode(inode); | 240 | bhv_vnode_t *vp = vn_from_inode(inode); |
243 | int error, nmaps = 1; | 241 | int error, nmaps = 1; |
244 | 242 | ||
245 | VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error); | 243 | error = bhv_vop_bmap(vp, offset, count, flags, mapp, &nmaps); |
246 | if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE))) | 244 | if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE))) |
247 | VMODIFY(vp); | 245 | VMODIFY(vp); |
248 | return -error; | 246 | return -error; |
@@ -271,16 +269,14 @@ xfs_end_bio( | |||
271 | if (bio->bi_size) | 269 | if (bio->bi_size) |
272 | return 1; | 270 | return 1; |
273 | 271 | ||
274 | ASSERT(ioend); | ||
275 | ASSERT(atomic_read(&bio->bi_cnt) >= 1); | 272 | ASSERT(atomic_read(&bio->bi_cnt) >= 1); |
273 | ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error; | ||
276 | 274 | ||
277 | /* Toss bio and pass work off to an xfsdatad thread */ | 275 | /* Toss bio and pass work off to an xfsdatad thread */ |
278 | if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) | ||
279 | ioend->io_uptodate = 0; | ||
280 | bio->bi_private = NULL; | 276 | bio->bi_private = NULL; |
281 | bio->bi_end_io = NULL; | 277 | bio->bi_end_io = NULL; |
282 | |||
283 | bio_put(bio); | 278 | bio_put(bio); |
279 | |||
284 | xfs_finish_ioend(ioend); | 280 | xfs_finish_ioend(ioend); |
285 | return 0; | 281 | return 0; |
286 | } | 282 | } |
@@ -1127,7 +1123,7 @@ xfs_vm_writepage( | |||
1127 | * then mark the page dirty again and leave the page | 1123 | * then mark the page dirty again and leave the page |
1128 | * as is. | 1124 | * as is. |
1129 | */ | 1125 | */ |
1130 | if (PFLAGS_TEST_FSTRANS() && need_trans) | 1126 | if (current_test_flags(PF_FSTRANS) && need_trans) |
1131 | goto out_fail; | 1127 | goto out_fail; |
1132 | 1128 | ||
1133 | /* | 1129 | /* |
@@ -1158,6 +1154,18 @@ out_unlock: | |||
1158 | return error; | 1154 | return error; |
1159 | } | 1155 | } |
1160 | 1156 | ||
1157 | STATIC int | ||
1158 | xfs_vm_writepages( | ||
1159 | struct address_space *mapping, | ||
1160 | struct writeback_control *wbc) | ||
1161 | { | ||
1162 | struct bhv_vnode *vp = vn_from_inode(mapping->host); | ||
1163 | |||
1164 | if (VN_TRUNC(vp)) | ||
1165 | VUNTRUNCATE(vp); | ||
1166 | return generic_writepages(mapping, wbc); | ||
1167 | } | ||
1168 | |||
1161 | /* | 1169 | /* |
1162 | * Called to move a page into cleanable state - and from there | 1170 | * Called to move a page into cleanable state - and from there |
1163 | * to be released. Possibly the page is already clean. We always | 1171 | * to be released. Possibly the page is already clean. We always |
@@ -1204,7 +1212,7 @@ xfs_vm_releasepage( | |||
1204 | /* If we are already inside a transaction or the thread cannot | 1212 | /* If we are already inside a transaction or the thread cannot |
1205 | * do I/O, we cannot release this page. | 1213 | * do I/O, we cannot release this page. |
1206 | */ | 1214 | */ |
1207 | if (PFLAGS_TEST_FSTRANS()) | 1215 | if (current_test_flags(PF_FSTRANS)) |
1208 | return 0; | 1216 | return 0; |
1209 | 1217 | ||
1210 | /* | 1218 | /* |
@@ -1231,7 +1239,7 @@ __xfs_get_blocks( | |||
1231 | int direct, | 1239 | int direct, |
1232 | bmapi_flags_t flags) | 1240 | bmapi_flags_t flags) |
1233 | { | 1241 | { |
1234 | vnode_t *vp = vn_from_inode(inode); | 1242 | bhv_vnode_t *vp = vn_from_inode(inode); |
1235 | xfs_iomap_t iomap; | 1243 | xfs_iomap_t iomap; |
1236 | xfs_off_t offset; | 1244 | xfs_off_t offset; |
1237 | ssize_t size; | 1245 | ssize_t size; |
@@ -1241,8 +1249,8 @@ __xfs_get_blocks( | |||
1241 | offset = (xfs_off_t)iblock << inode->i_blkbits; | 1249 | offset = (xfs_off_t)iblock << inode->i_blkbits; |
1242 | ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); | 1250 | ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); |
1243 | size = bh_result->b_size; | 1251 | size = bh_result->b_size; |
1244 | VOP_BMAP(vp, offset, size, | 1252 | error = bhv_vop_bmap(vp, offset, size, |
1245 | create ? flags : BMAPI_READ, &iomap, &niomap, error); | 1253 | create ? flags : BMAPI_READ, &iomap, &niomap); |
1246 | if (error) | 1254 | if (error) |
1247 | return -error; | 1255 | return -error; |
1248 | if (niomap == 0) | 1256 | if (niomap == 0) |
@@ -1370,13 +1378,13 @@ xfs_vm_direct_IO( | |||
1370 | { | 1378 | { |
1371 | struct file *file = iocb->ki_filp; | 1379 | struct file *file = iocb->ki_filp; |
1372 | struct inode *inode = file->f_mapping->host; | 1380 | struct inode *inode = file->f_mapping->host; |
1373 | vnode_t *vp = vn_from_inode(inode); | 1381 | bhv_vnode_t *vp = vn_from_inode(inode); |
1374 | xfs_iomap_t iomap; | 1382 | xfs_iomap_t iomap; |
1375 | int maps = 1; | 1383 | int maps = 1; |
1376 | int error; | 1384 | int error; |
1377 | ssize_t ret; | 1385 | ssize_t ret; |
1378 | 1386 | ||
1379 | VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error); | 1387 | error = bhv_vop_bmap(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps); |
1380 | if (error) | 1388 | if (error) |
1381 | return -error; | 1389 | return -error; |
1382 | 1390 | ||
@@ -1409,14 +1417,12 @@ xfs_vm_bmap( | |||
1409 | sector_t block) | 1417 | sector_t block) |
1410 | { | 1418 | { |
1411 | struct inode *inode = (struct inode *)mapping->host; | 1419 | struct inode *inode = (struct inode *)mapping->host; |
1412 | vnode_t *vp = vn_from_inode(inode); | 1420 | bhv_vnode_t *vp = vn_from_inode(inode); |
1413 | int error; | ||
1414 | 1421 | ||
1415 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 1422 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
1416 | 1423 | bhv_vop_rwlock(vp, VRWLOCK_READ); | |
1417 | VOP_RWLOCK(vp, VRWLOCK_READ); | 1424 | bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF); |
1418 | VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); | 1425 | bhv_vop_rwunlock(vp, VRWLOCK_READ); |
1419 | VOP_RWUNLOCK(vp, VRWLOCK_READ); | ||
1420 | return generic_block_bmap(mapping, block, xfs_get_blocks); | 1426 | return generic_block_bmap(mapping, block, xfs_get_blocks); |
1421 | } | 1427 | } |
1422 | 1428 | ||
@@ -1452,6 +1458,7 @@ struct address_space_operations xfs_address_space_operations = { | |||
1452 | .readpage = xfs_vm_readpage, | 1458 | .readpage = xfs_vm_readpage, |
1453 | .readpages = xfs_vm_readpages, | 1459 | .readpages = xfs_vm_readpages, |
1454 | .writepage = xfs_vm_writepage, | 1460 | .writepage = xfs_vm_writepage, |
1461 | .writepages = xfs_vm_writepages, | ||
1455 | .sync_page = block_sync_page, | 1462 | .sync_page = block_sync_page, |
1456 | .releasepage = xfs_vm_releasepage, | 1463 | .releasepage = xfs_vm_releasepage, |
1457 | .invalidatepage = xfs_vm_invalidatepage, | 1464 | .invalidatepage = xfs_vm_invalidatepage, |
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h index 60716543c68b..706d8c781b8a 100644 --- a/fs/xfs/linux-2.6/xfs_aops.h +++ b/fs/xfs/linux-2.6/xfs_aops.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2005-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -30,9 +30,9 @@ typedef void (*xfs_ioend_func_t)(void *); | |||
30 | typedef struct xfs_ioend { | 30 | typedef struct xfs_ioend { |
31 | struct xfs_ioend *io_list; /* next ioend in chain */ | 31 | struct xfs_ioend *io_list; /* next ioend in chain */ |
32 | unsigned int io_type; /* delalloc / unwritten */ | 32 | unsigned int io_type; /* delalloc / unwritten */ |
33 | unsigned int io_uptodate; /* I/O status register */ | 33 | int io_error; /* I/O error code */ |
34 | atomic_t io_remaining; /* hold count */ | 34 | atomic_t io_remaining; /* hold count */ |
35 | struct vnode *io_vnode; /* file being written to */ | 35 | struct bhv_vnode *io_vnode; /* file being written to */ |
36 | struct buffer_head *io_buffer_head;/* buffer linked list head */ | 36 | struct buffer_head *io_buffer_head;/* buffer linked list head */ |
37 | struct buffer_head *io_buffer_tail;/* buffer linked list tail */ | 37 | struct buffer_head *io_buffer_tail;/* buffer linked list tail */ |
38 | size_t io_size; /* size of the extent */ | 38 | size_t io_size; /* size of the extent */ |
@@ -43,4 +43,4 @@ typedef struct xfs_ioend { | |||
43 | extern struct address_space_operations xfs_address_space_operations; | 43 | extern struct address_space_operations xfs_address_space_operations; |
44 | extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); | 44 | extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); |
45 | 45 | ||
46 | #endif /* __XFS_IOPS_H__ */ | 46 | #endif /* __XFS_AOPS_H__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index b768ea910bbe..5fb75d9151f2 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "xfs_log.h" | 21 | #include "xfs_log.h" |
22 | #include "xfs_trans.h" | 22 | #include "xfs_trans.h" |
23 | #include "xfs_sb.h" | 23 | #include "xfs_sb.h" |
24 | #include "xfs_dir.h" | ||
25 | #include "xfs_mount.h" | 24 | #include "xfs_mount.h" |
26 | #include "xfs_export.h" | 25 | #include "xfs_export.h" |
27 | 26 | ||
@@ -97,7 +96,7 @@ xfs_fs_encode_fh( | |||
97 | int len; | 96 | int len; |
98 | int is64 = 0; | 97 | int is64 = 0; |
99 | #if XFS_BIG_INUMS | 98 | #if XFS_BIG_INUMS |
100 | vfs_t *vfs = vfs_from_sb(inode->i_sb); | 99 | bhv_vfs_t *vfs = vfs_from_sb(inode->i_sb); |
101 | 100 | ||
102 | if (!(vfs->vfs_flag & VFS_32BITINODES)) { | 101 | if (!(vfs->vfs_flag & VFS_32BITINODES)) { |
103 | /* filesystem may contain 64bit inode numbers */ | 102 | /* filesystem may contain 64bit inode numbers */ |
@@ -136,13 +135,13 @@ xfs_fs_get_dentry( | |||
136 | struct super_block *sb, | 135 | struct super_block *sb, |
137 | void *data) | 136 | void *data) |
138 | { | 137 | { |
139 | vnode_t *vp; | 138 | bhv_vnode_t *vp; |
140 | struct inode *inode; | 139 | struct inode *inode; |
141 | struct dentry *result; | 140 | struct dentry *result; |
142 | vfs_t *vfsp = vfs_from_sb(sb); | 141 | bhv_vfs_t *vfsp = vfs_from_sb(sb); |
143 | int error; | 142 | int error; |
144 | 143 | ||
145 | VFS_VGET(vfsp, &vp, (fid_t *)data, error); | 144 | error = bhv_vfs_vget(vfsp, &vp, (fid_t *)data); |
146 | if (error || vp == NULL) | 145 | if (error || vp == NULL) |
147 | return ERR_PTR(-ESTALE) ; | 146 | return ERR_PTR(-ESTALE) ; |
148 | 147 | ||
@@ -160,12 +159,12 @@ xfs_fs_get_parent( | |||
160 | struct dentry *child) | 159 | struct dentry *child) |
161 | { | 160 | { |
162 | int error; | 161 | int error; |
163 | vnode_t *vp, *cvp; | 162 | bhv_vnode_t *vp, *cvp; |
164 | struct dentry *parent; | 163 | struct dentry *parent; |
165 | 164 | ||
166 | cvp = NULL; | 165 | cvp = NULL; |
167 | vp = vn_from_inode(child->d_inode); | 166 | vp = vn_from_inode(child->d_inode); |
168 | VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error); | 167 | error = bhv_vop_lookup(vp, &dotdot, &cvp, 0, NULL, NULL); |
169 | if (unlikely(error)) | 168 | if (unlikely(error)) |
170 | return ERR_PTR(-error); | 169 | return ERR_PTR(-error); |
171 | 170 | ||
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index c847416f6d10..70662371bb11 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "xfs_inum.h" | 21 | #include "xfs_inum.h" |
22 | #include "xfs_sb.h" | 22 | #include "xfs_sb.h" |
23 | #include "xfs_ag.h" | 23 | #include "xfs_ag.h" |
24 | #include "xfs_dir.h" | ||
25 | #include "xfs_dir2.h" | 24 | #include "xfs_dir2.h" |
26 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_alloc.h" | 31 | #include "xfs_alloc.h" |
33 | #include "xfs_btree.h" | 32 | #include "xfs_btree.h" |
34 | #include "xfs_attr_sf.h" | 33 | #include "xfs_attr_sf.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
38 | #include "xfs_inode.h" | 36 | #include "xfs_inode.h" |
@@ -58,15 +56,12 @@ __xfs_file_read( | |||
58 | { | 56 | { |
59 | struct iovec iov = {buf, count}; | 57 | struct iovec iov = {buf, count}; |
60 | struct file *file = iocb->ki_filp; | 58 | struct file *file = iocb->ki_filp; |
61 | vnode_t *vp = vn_from_inode(file->f_dentry->d_inode); | 59 | bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode); |
62 | ssize_t rval; | ||
63 | 60 | ||
64 | BUG_ON(iocb->ki_pos != pos); | 61 | BUG_ON(iocb->ki_pos != pos); |
65 | |||
66 | if (unlikely(file->f_flags & O_DIRECT)) | 62 | if (unlikely(file->f_flags & O_DIRECT)) |
67 | ioflags |= IO_ISDIRECT; | 63 | ioflags |= IO_ISDIRECT; |
68 | VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval); | 64 | return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL); |
69 | return rval; | ||
70 | } | 65 | } |
71 | 66 | ||
72 | STATIC ssize_t | 67 | STATIC ssize_t |
@@ -100,15 +95,12 @@ __xfs_file_write( | |||
100 | struct iovec iov = {(void __user *)buf, count}; | 95 | struct iovec iov = {(void __user *)buf, count}; |
101 | struct file *file = iocb->ki_filp; | 96 | struct file *file = iocb->ki_filp; |
102 | struct inode *inode = file->f_mapping->host; | 97 | struct inode *inode = file->f_mapping->host; |
103 | vnode_t *vp = vn_from_inode(inode); | 98 | bhv_vnode_t *vp = vn_from_inode(inode); |
104 | ssize_t rval; | ||
105 | 99 | ||
106 | BUG_ON(iocb->ki_pos != pos); | 100 | BUG_ON(iocb->ki_pos != pos); |
107 | if (unlikely(file->f_flags & O_DIRECT)) | 101 | if (unlikely(file->f_flags & O_DIRECT)) |
108 | ioflags |= IO_ISDIRECT; | 102 | ioflags |= IO_ISDIRECT; |
109 | 103 | return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL); | |
110 | VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval); | ||
111 | return rval; | ||
112 | } | 104 | } |
113 | 105 | ||
114 | STATIC ssize_t | 106 | STATIC ssize_t |
@@ -140,7 +132,7 @@ __xfs_file_readv( | |||
140 | loff_t *ppos) | 132 | loff_t *ppos) |
141 | { | 133 | { |
142 | struct inode *inode = file->f_mapping->host; | 134 | struct inode *inode = file->f_mapping->host; |
143 | vnode_t *vp = vn_from_inode(inode); | 135 | bhv_vnode_t *vp = vn_from_inode(inode); |
144 | struct kiocb kiocb; | 136 | struct kiocb kiocb; |
145 | ssize_t rval; | 137 | ssize_t rval; |
146 | 138 | ||
@@ -149,7 +141,8 @@ __xfs_file_readv( | |||
149 | 141 | ||
150 | if (unlikely(file->f_flags & O_DIRECT)) | 142 | if (unlikely(file->f_flags & O_DIRECT)) |
151 | ioflags |= IO_ISDIRECT; | 143 | ioflags |= IO_ISDIRECT; |
152 | VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval); | 144 | rval = bhv_vop_read(vp, &kiocb, iov, nr_segs, |
145 | &kiocb.ki_pos, ioflags, NULL); | ||
153 | 146 | ||
154 | *ppos = kiocb.ki_pos; | 147 | *ppos = kiocb.ki_pos; |
155 | return rval; | 148 | return rval; |
@@ -184,7 +177,7 @@ __xfs_file_writev( | |||
184 | loff_t *ppos) | 177 | loff_t *ppos) |
185 | { | 178 | { |
186 | struct inode *inode = file->f_mapping->host; | 179 | struct inode *inode = file->f_mapping->host; |
187 | vnode_t *vp = vn_from_inode(inode); | 180 | bhv_vnode_t *vp = vn_from_inode(inode); |
188 | struct kiocb kiocb; | 181 | struct kiocb kiocb; |
189 | ssize_t rval; | 182 | ssize_t rval; |
190 | 183 | ||
@@ -193,7 +186,8 @@ __xfs_file_writev( | |||
193 | if (unlikely(file->f_flags & O_DIRECT)) | 186 | if (unlikely(file->f_flags & O_DIRECT)) |
194 | ioflags |= IO_ISDIRECT; | 187 | ioflags |= IO_ISDIRECT; |
195 | 188 | ||
196 | VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval); | 189 | rval = bhv_vop_write(vp, &kiocb, iov, nr_segs, |
190 | &kiocb.ki_pos, ioflags, NULL); | ||
197 | 191 | ||
198 | *ppos = kiocb.ki_pos; | 192 | *ppos = kiocb.ki_pos; |
199 | return rval; | 193 | return rval; |
@@ -227,11 +221,8 @@ xfs_file_sendfile( | |||
227 | read_actor_t actor, | 221 | read_actor_t actor, |
228 | void *target) | 222 | void *target) |
229 | { | 223 | { |
230 | vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); | 224 | return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode), |
231 | ssize_t rval; | 225 | filp, pos, 0, count, actor, target, NULL); |
232 | |||
233 | VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval); | ||
234 | return rval; | ||
235 | } | 226 | } |
236 | 227 | ||
237 | STATIC ssize_t | 228 | STATIC ssize_t |
@@ -242,11 +233,8 @@ xfs_file_sendfile_invis( | |||
242 | read_actor_t actor, | 233 | read_actor_t actor, |
243 | void *target) | 234 | void *target) |
244 | { | 235 | { |
245 | vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); | 236 | return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode), |
246 | ssize_t rval; | 237 | filp, pos, IO_INVIS, count, actor, target, NULL); |
247 | |||
248 | VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval); | ||
249 | return rval; | ||
250 | } | 238 | } |
251 | 239 | ||
252 | STATIC ssize_t | 240 | STATIC ssize_t |
@@ -257,11 +245,8 @@ xfs_file_splice_read( | |||
257 | size_t len, | 245 | size_t len, |
258 | unsigned int flags) | 246 | unsigned int flags) |
259 | { | 247 | { |
260 | vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); | 248 | return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode), |
261 | ssize_t rval; | 249 | infilp, ppos, pipe, len, flags, 0, NULL); |
262 | |||
263 | VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, 0, NULL, rval); | ||
264 | return rval; | ||
265 | } | 250 | } |
266 | 251 | ||
267 | STATIC ssize_t | 252 | STATIC ssize_t |
@@ -272,11 +257,9 @@ xfs_file_splice_read_invis( | |||
272 | size_t len, | 257 | size_t len, |
273 | unsigned int flags) | 258 | unsigned int flags) |
274 | { | 259 | { |
275 | vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); | 260 | return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode), |
276 | ssize_t rval; | 261 | infilp, ppos, pipe, len, flags, IO_INVIS, |
277 | 262 | NULL); | |
278 | VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, IO_INVIS, NULL, rval); | ||
279 | return rval; | ||
280 | } | 263 | } |
281 | 264 | ||
282 | STATIC ssize_t | 265 | STATIC ssize_t |
@@ -287,11 +270,8 @@ xfs_file_splice_write( | |||
287 | size_t len, | 270 | size_t len, |
288 | unsigned int flags) | 271 | unsigned int flags) |
289 | { | 272 | { |
290 | vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); | 273 | return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode), |
291 | ssize_t rval; | 274 | pipe, outfilp, ppos, len, flags, 0, NULL); |
292 | |||
293 | VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, 0, NULL, rval); | ||
294 | return rval; | ||
295 | } | 275 | } |
296 | 276 | ||
297 | STATIC ssize_t | 277 | STATIC ssize_t |
@@ -302,11 +282,9 @@ xfs_file_splice_write_invis( | |||
302 | size_t len, | 282 | size_t len, |
303 | unsigned int flags) | 283 | unsigned int flags) |
304 | { | 284 | { |
305 | vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); | 285 | return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode), |
306 | ssize_t rval; | 286 | pipe, outfilp, ppos, len, flags, IO_INVIS, |
307 | 287 | NULL); | |
308 | VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, IO_INVIS, NULL, rval); | ||
309 | return rval; | ||
310 | } | 288 | } |
311 | 289 | ||
312 | STATIC int | 290 | STATIC int |
@@ -314,13 +292,17 @@ xfs_file_open( | |||
314 | struct inode *inode, | 292 | struct inode *inode, |
315 | struct file *filp) | 293 | struct file *filp) |
316 | { | 294 | { |
317 | vnode_t *vp = vn_from_inode(inode); | ||
318 | int error; | ||
319 | |||
320 | if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) | 295 | if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) |
321 | return -EFBIG; | 296 | return -EFBIG; |
322 | VOP_OPEN(vp, NULL, error); | 297 | return -bhv_vop_open(vn_from_inode(inode), NULL); |
323 | return -error; | 298 | } |
299 | |||
300 | STATIC int | ||
301 | xfs_file_close( | ||
302 | struct file *filp) | ||
303 | { | ||
304 | return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0, | ||
305 | file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL); | ||
324 | } | 306 | } |
325 | 307 | ||
326 | STATIC int | 308 | STATIC int |
@@ -328,12 +310,11 @@ xfs_file_release( | |||
328 | struct inode *inode, | 310 | struct inode *inode, |
329 | struct file *filp) | 311 | struct file *filp) |
330 | { | 312 | { |
331 | vnode_t *vp = vn_from_inode(inode); | 313 | bhv_vnode_t *vp = vn_from_inode(inode); |
332 | int error = 0; | ||
333 | 314 | ||
334 | if (vp) | 315 | if (vp) |
335 | VOP_RELEASE(vp, error); | 316 | return -bhv_vop_release(vp); |
336 | return -error; | 317 | return 0; |
337 | } | 318 | } |
338 | 319 | ||
339 | STATIC int | 320 | STATIC int |
@@ -342,15 +323,14 @@ xfs_file_fsync( | |||
342 | struct dentry *dentry, | 323 | struct dentry *dentry, |
343 | int datasync) | 324 | int datasync) |
344 | { | 325 | { |
345 | struct inode *inode = dentry->d_inode; | 326 | bhv_vnode_t *vp = vn_from_inode(dentry->d_inode); |
346 | vnode_t *vp = vn_from_inode(inode); | ||
347 | int error; | ||
348 | int flags = FSYNC_WAIT; | 327 | int flags = FSYNC_WAIT; |
349 | 328 | ||
350 | if (datasync) | 329 | if (datasync) |
351 | flags |= FSYNC_DATA; | 330 | flags |= FSYNC_DATA; |
352 | VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error); | 331 | if (VN_TRUNC(vp)) |
353 | return -error; | 332 | VUNTRUNCATE(vp); |
333 | return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1); | ||
354 | } | 334 | } |
355 | 335 | ||
356 | #ifdef CONFIG_XFS_DMAPI | 336 | #ifdef CONFIG_XFS_DMAPI |
@@ -361,16 +341,11 @@ xfs_vm_nopage( | |||
361 | int *type) | 341 | int *type) |
362 | { | 342 | { |
363 | struct inode *inode = area->vm_file->f_dentry->d_inode; | 343 | struct inode *inode = area->vm_file->f_dentry->d_inode; |
364 | vnode_t *vp = vn_from_inode(inode); | 344 | bhv_vnode_t *vp = vn_from_inode(inode); |
365 | xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp); | ||
366 | int error; | ||
367 | 345 | ||
368 | ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI); | 346 | ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI); |
369 | 347 | if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), area, 0)) | |
370 | error = XFS_SEND_MMAP(mp, area, 0); | ||
371 | if (error) | ||
372 | return NULL; | 348 | return NULL; |
373 | |||
374 | return filemap_nopage(area, address, type); | 349 | return filemap_nopage(area, address, type); |
375 | } | 350 | } |
376 | #endif /* CONFIG_XFS_DMAPI */ | 351 | #endif /* CONFIG_XFS_DMAPI */ |
@@ -382,7 +357,7 @@ xfs_file_readdir( | |||
382 | filldir_t filldir) | 357 | filldir_t filldir) |
383 | { | 358 | { |
384 | int error = 0; | 359 | int error = 0; |
385 | vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); | 360 | bhv_vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); |
386 | uio_t uio; | 361 | uio_t uio; |
387 | iovec_t iov; | 362 | iovec_t iov; |
388 | int eof = 0; | 363 | int eof = 0; |
@@ -417,7 +392,7 @@ xfs_file_readdir( | |||
417 | 392 | ||
418 | start_offset = uio.uio_offset; | 393 | start_offset = uio.uio_offset; |
419 | 394 | ||
420 | VOP_READDIR(vp, &uio, NULL, &eof, error); | 395 | error = bhv_vop_readdir(vp, &uio, NULL, &eof); |
421 | if ((uio.uio_offset == start_offset) || error) { | 396 | if ((uio.uio_offset == start_offset) || error) { |
422 | size = 0; | 397 | size = 0; |
423 | break; | 398 | break; |
@@ -456,38 +431,28 @@ xfs_file_mmap( | |||
456 | struct file *filp, | 431 | struct file *filp, |
457 | struct vm_area_struct *vma) | 432 | struct vm_area_struct *vma) |
458 | { | 433 | { |
459 | struct inode *ip = filp->f_dentry->d_inode; | ||
460 | vnode_t *vp = vn_from_inode(ip); | ||
461 | vattr_t vattr; | ||
462 | int error; | ||
463 | |||
464 | vma->vm_ops = &xfs_file_vm_ops; | 434 | vma->vm_ops = &xfs_file_vm_ops; |
465 | 435 | ||
466 | #ifdef CONFIG_XFS_DMAPI | 436 | #ifdef CONFIG_XFS_DMAPI |
467 | if (vp->v_vfsp->vfs_flag & VFS_DMI) { | 437 | if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI) |
468 | vma->vm_ops = &xfs_dmapi_file_vm_ops; | 438 | vma->vm_ops = &xfs_dmapi_file_vm_ops; |
469 | } | ||
470 | #endif /* CONFIG_XFS_DMAPI */ | 439 | #endif /* CONFIG_XFS_DMAPI */ |
471 | 440 | ||
472 | vattr.va_mask = XFS_AT_UPDATIME; | 441 | file_accessed(filp); |
473 | VOP_SETATTR(vp, &vattr, XFS_AT_UPDATIME, NULL, error); | ||
474 | if (likely(!error)) | ||
475 | __vn_revalidate(vp, &vattr); /* update flags */ | ||
476 | return 0; | 442 | return 0; |
477 | } | 443 | } |
478 | 444 | ||
479 | |||
480 | STATIC long | 445 | STATIC long |
481 | xfs_file_ioctl( | 446 | xfs_file_ioctl( |
482 | struct file *filp, | 447 | struct file *filp, |
483 | unsigned int cmd, | 448 | unsigned int cmd, |
484 | unsigned long arg) | 449 | unsigned long p) |
485 | { | 450 | { |
486 | int error; | 451 | int error; |
487 | struct inode *inode = filp->f_dentry->d_inode; | 452 | struct inode *inode = filp->f_dentry->d_inode; |
488 | vnode_t *vp = vn_from_inode(inode); | 453 | bhv_vnode_t *vp = vn_from_inode(inode); |
489 | 454 | ||
490 | VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error); | 455 | error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p); |
491 | VMODIFY(vp); | 456 | VMODIFY(vp); |
492 | 457 | ||
493 | /* NOTE: some of the ioctl's return positive #'s as a | 458 | /* NOTE: some of the ioctl's return positive #'s as a |
@@ -503,13 +468,13 @@ STATIC long | |||
503 | xfs_file_ioctl_invis( | 468 | xfs_file_ioctl_invis( |
504 | struct file *filp, | 469 | struct file *filp, |
505 | unsigned int cmd, | 470 | unsigned int cmd, |
506 | unsigned long arg) | 471 | unsigned long p) |
507 | { | 472 | { |
508 | struct inode *inode = filp->f_dentry->d_inode; | ||
509 | vnode_t *vp = vn_from_inode(inode); | ||
510 | int error; | 473 | int error; |
474 | struct inode *inode = filp->f_dentry->d_inode; | ||
475 | bhv_vnode_t *vp = vn_from_inode(inode); | ||
511 | 476 | ||
512 | VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); | 477 | error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p); |
513 | VMODIFY(vp); | 478 | VMODIFY(vp); |
514 | 479 | ||
515 | /* NOTE: some of the ioctl's return positive #'s as a | 480 | /* NOTE: some of the ioctl's return positive #'s as a |
@@ -528,7 +493,7 @@ xfs_vm_mprotect( | |||
528 | struct vm_area_struct *vma, | 493 | struct vm_area_struct *vma, |
529 | unsigned int newflags) | 494 | unsigned int newflags) |
530 | { | 495 | { |
531 | vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode); | 496 | bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode); |
532 | int error = 0; | 497 | int error = 0; |
533 | 498 | ||
534 | if (vp->v_vfsp->vfs_flag & VFS_DMI) { | 499 | if (vp->v_vfsp->vfs_flag & VFS_DMI) { |
@@ -554,24 +519,19 @@ STATIC int | |||
554 | xfs_file_open_exec( | 519 | xfs_file_open_exec( |
555 | struct inode *inode) | 520 | struct inode *inode) |
556 | { | 521 | { |
557 | vnode_t *vp = vn_from_inode(inode); | 522 | bhv_vnode_t *vp = vn_from_inode(inode); |
558 | xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp); | ||
559 | int error = 0; | ||
560 | xfs_inode_t *ip; | ||
561 | 523 | ||
562 | if (vp->v_vfsp->vfs_flag & VFS_DMI) { | 524 | if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) { |
563 | ip = xfs_vtoi(vp); | 525 | xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp); |
564 | if (!ip) { | 526 | xfs_inode_t *ip = xfs_vtoi(vp); |
565 | error = -EINVAL; | 527 | |
566 | goto open_exec_out; | 528 | if (!ip) |
567 | } | 529 | return -EINVAL; |
568 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) { | 530 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) |
569 | error = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp, | 531 | return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp, |
570 | 0, 0, 0, NULL); | 532 | 0, 0, 0, NULL); |
571 | } | ||
572 | } | 533 | } |
573 | open_exec_out: | 534 | return 0; |
574 | return error; | ||
575 | } | 535 | } |
576 | #endif /* HAVE_FOP_OPEN_EXEC */ | 536 | #endif /* HAVE_FOP_OPEN_EXEC */ |
577 | 537 | ||
@@ -592,6 +552,7 @@ const struct file_operations xfs_file_operations = { | |||
592 | #endif | 552 | #endif |
593 | .mmap = xfs_file_mmap, | 553 | .mmap = xfs_file_mmap, |
594 | .open = xfs_file_open, | 554 | .open = xfs_file_open, |
555 | .flush = xfs_file_close, | ||
595 | .release = xfs_file_release, | 556 | .release = xfs_file_release, |
596 | .fsync = xfs_file_fsync, | 557 | .fsync = xfs_file_fsync, |
597 | #ifdef HAVE_FOP_OPEN_EXEC | 558 | #ifdef HAVE_FOP_OPEN_EXEC |
@@ -616,6 +577,7 @@ const struct file_operations xfs_invis_file_operations = { | |||
616 | #endif | 577 | #endif |
617 | .mmap = xfs_file_mmap, | 578 | .mmap = xfs_file_mmap, |
618 | .open = xfs_file_open, | 579 | .open = xfs_file_open, |
580 | .flush = xfs_file_close, | ||
619 | .release = xfs_file_release, | 581 | .release = xfs_file_release, |
620 | .fsync = xfs_file_fsync, | 582 | .fsync = xfs_file_fsync, |
621 | }; | 583 | }; |
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c index 575f2a790f31..dc0562828e76 100644 --- a/fs/xfs/linux-2.6/xfs_fs_subr.c +++ b/fs/xfs/linux-2.6/xfs_fs_subr.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2002,2005-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -15,40 +15,12 @@ | |||
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | |||
19 | #include "xfs.h" | 18 | #include "xfs.h" |
20 | 19 | ||
21 | /* | 20 | int fs_noerr(void) { return 0; } |
22 | * Stub for no-op vnode operations that return error status. | 21 | int fs_nosys(void) { return ENOSYS; } |
23 | */ | 22 | void fs_noval(void) { return; } |
24 | int | ||
25 | fs_noerr(void) | ||
26 | { | ||
27 | return 0; | ||
28 | } | ||
29 | 23 | ||
30 | /* | ||
31 | * Operation unsupported under this file system. | ||
32 | */ | ||
33 | int | ||
34 | fs_nosys(void) | ||
35 | { | ||
36 | return ENOSYS; | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | * Stub for inactive, strategy, and read/write lock/unlock. Does nothing. | ||
41 | */ | ||
42 | /* ARGSUSED */ | ||
43 | void | ||
44 | fs_noval(void) | ||
45 | { | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | * vnode pcache layer for vnode_tosspages. | ||
50 | * 'last' parameter unused but left in for IRIX compatibility | ||
51 | */ | ||
52 | void | 24 | void |
53 | fs_tosspages( | 25 | fs_tosspages( |
54 | bhv_desc_t *bdp, | 26 | bhv_desc_t *bdp, |
@@ -56,18 +28,13 @@ fs_tosspages( | |||
56 | xfs_off_t last, | 28 | xfs_off_t last, |
57 | int fiopt) | 29 | int fiopt) |
58 | { | 30 | { |
59 | vnode_t *vp = BHV_TO_VNODE(bdp); | 31 | bhv_vnode_t *vp = BHV_TO_VNODE(bdp); |
60 | struct inode *ip = vn_to_inode(vp); | 32 | struct inode *ip = vn_to_inode(vp); |
61 | 33 | ||
62 | if (VN_CACHED(vp)) | 34 | if (VN_CACHED(vp)) |
63 | truncate_inode_pages(ip->i_mapping, first); | 35 | truncate_inode_pages(ip->i_mapping, first); |
64 | } | 36 | } |
65 | 37 | ||
66 | |||
67 | /* | ||
68 | * vnode pcache layer for vnode_flushinval_pages. | ||
69 | * 'last' parameter unused but left in for IRIX compatibility | ||
70 | */ | ||
71 | void | 38 | void |
72 | fs_flushinval_pages( | 39 | fs_flushinval_pages( |
73 | bhv_desc_t *bdp, | 40 | bhv_desc_t *bdp, |
@@ -75,20 +42,17 @@ fs_flushinval_pages( | |||
75 | xfs_off_t last, | 42 | xfs_off_t last, |
76 | int fiopt) | 43 | int fiopt) |
77 | { | 44 | { |
78 | vnode_t *vp = BHV_TO_VNODE(bdp); | 45 | bhv_vnode_t *vp = BHV_TO_VNODE(bdp); |
79 | struct inode *ip = vn_to_inode(vp); | 46 | struct inode *ip = vn_to_inode(vp); |
80 | 47 | ||
81 | if (VN_CACHED(vp)) { | 48 | if (VN_CACHED(vp)) { |
49 | if (VN_TRUNC(vp)) | ||
50 | VUNTRUNCATE(vp); | ||
82 | filemap_write_and_wait(ip->i_mapping); | 51 | filemap_write_and_wait(ip->i_mapping); |
83 | |||
84 | truncate_inode_pages(ip->i_mapping, first); | 52 | truncate_inode_pages(ip->i_mapping, first); |
85 | } | 53 | } |
86 | } | 54 | } |
87 | 55 | ||
88 | /* | ||
89 | * vnode pcache layer for vnode_flush_pages. | ||
90 | * 'last' parameter unused but left in for IRIX compatibility | ||
91 | */ | ||
92 | int | 56 | int |
93 | fs_flush_pages( | 57 | fs_flush_pages( |
94 | bhv_desc_t *bdp, | 58 | bhv_desc_t *bdp, |
@@ -97,15 +61,16 @@ fs_flush_pages( | |||
97 | uint64_t flags, | 61 | uint64_t flags, |
98 | int fiopt) | 62 | int fiopt) |
99 | { | 63 | { |
100 | vnode_t *vp = BHV_TO_VNODE(bdp); | 64 | bhv_vnode_t *vp = BHV_TO_VNODE(bdp); |
101 | struct inode *ip = vn_to_inode(vp); | 65 | struct inode *ip = vn_to_inode(vp); |
102 | 66 | ||
103 | if (VN_CACHED(vp)) { | 67 | if (VN_DIRTY(vp)) { |
68 | if (VN_TRUNC(vp)) | ||
69 | VUNTRUNCATE(vp); | ||
104 | filemap_fdatawrite(ip->i_mapping); | 70 | filemap_fdatawrite(ip->i_mapping); |
105 | if (flags & XFS_B_ASYNC) | 71 | if (flags & XFS_B_ASYNC) |
106 | return 0; | 72 | return 0; |
107 | filemap_fdatawait(ip->i_mapping); | 73 | filemap_fdatawait(ip->i_mapping); |
108 | } | 74 | } |
109 | |||
110 | return 0; | 75 | return 0; |
111 | } | 76 | } |
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c index 6e8085f34635..6c162c3dde7e 100644 --- a/fs/xfs/linux-2.6/xfs_globals.c +++ b/fs/xfs/linux-2.6/xfs_globals.c | |||
@@ -45,6 +45,7 @@ xfs_param_t xfs_params = { | |||
45 | .xfs_buf_age = { 1*100, 15*100, 7200*100}, | 45 | .xfs_buf_age = { 1*100, 15*100, 7200*100}, |
46 | .inherit_nosym = { 0, 0, 1 }, | 46 | .inherit_nosym = { 0, 0, 1 }, |
47 | .rotorstep = { 1, 1, 255 }, | 47 | .rotorstep = { 1, 1, 255 }, |
48 | .inherit_nodfrg = { 0, 1, 1 }, | ||
48 | }; | 49 | }; |
49 | 50 | ||
50 | /* | 51 | /* |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 84478491609b..6e52a5dd38d8 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -31,7 +30,6 @@ | |||
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_attr_sf.h" | 33 | #include "xfs_attr_sf.h" |
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -78,7 +76,7 @@ xfs_find_handle( | |||
78 | xfs_handle_t handle; | 76 | xfs_handle_t handle; |
79 | xfs_fsop_handlereq_t hreq; | 77 | xfs_fsop_handlereq_t hreq; |
80 | struct inode *inode; | 78 | struct inode *inode; |
81 | struct vnode *vp; | 79 | bhv_vnode_t *vp; |
82 | 80 | ||
83 | if (copy_from_user(&hreq, arg, sizeof(hreq))) | 81 | if (copy_from_user(&hreq, arg, sizeof(hreq))) |
84 | return -XFS_ERROR(EFAULT); | 82 | return -XFS_ERROR(EFAULT); |
@@ -192,7 +190,7 @@ xfs_vget_fsop_handlereq( | |||
192 | xfs_mount_t *mp, | 190 | xfs_mount_t *mp, |
193 | struct inode *parinode, /* parent inode pointer */ | 191 | struct inode *parinode, /* parent inode pointer */ |
194 | xfs_fsop_handlereq_t *hreq, | 192 | xfs_fsop_handlereq_t *hreq, |
195 | vnode_t **vp, | 193 | bhv_vnode_t **vp, |
196 | struct inode **inode) | 194 | struct inode **inode) |
197 | { | 195 | { |
198 | void __user *hanp; | 196 | void __user *hanp; |
@@ -202,7 +200,7 @@ xfs_vget_fsop_handlereq( | |||
202 | xfs_handle_t handle; | 200 | xfs_handle_t handle; |
203 | xfs_inode_t *ip; | 201 | xfs_inode_t *ip; |
204 | struct inode *inodep; | 202 | struct inode *inodep; |
205 | vnode_t *vpp; | 203 | bhv_vnode_t *vpp; |
206 | xfs_ino_t ino; | 204 | xfs_ino_t ino; |
207 | __u32 igen; | 205 | __u32 igen; |
208 | int error; | 206 | int error; |
@@ -277,7 +275,7 @@ xfs_open_by_handle( | |||
277 | struct file *filp; | 275 | struct file *filp; |
278 | struct inode *inode; | 276 | struct inode *inode; |
279 | struct dentry *dentry; | 277 | struct dentry *dentry; |
280 | vnode_t *vp; | 278 | bhv_vnode_t *vp; |
281 | xfs_fsop_handlereq_t hreq; | 279 | xfs_fsop_handlereq_t hreq; |
282 | 280 | ||
283 | if (!capable(CAP_SYS_ADMIN)) | 281 | if (!capable(CAP_SYS_ADMIN)) |
@@ -362,7 +360,7 @@ xfs_readlink_by_handle( | |||
362 | struct uio auio; | 360 | struct uio auio; |
363 | struct inode *inode; | 361 | struct inode *inode; |
364 | xfs_fsop_handlereq_t hreq; | 362 | xfs_fsop_handlereq_t hreq; |
365 | vnode_t *vp; | 363 | bhv_vnode_t *vp; |
366 | __u32 olen; | 364 | __u32 olen; |
367 | 365 | ||
368 | if (!capable(CAP_SYS_ADMIN)) | 366 | if (!capable(CAP_SYS_ADMIN)) |
@@ -393,9 +391,11 @@ xfs_readlink_by_handle( | |||
393 | auio.uio_segflg = UIO_USERSPACE; | 391 | auio.uio_segflg = UIO_USERSPACE; |
394 | auio.uio_resid = olen; | 392 | auio.uio_resid = olen; |
395 | 393 | ||
396 | VOP_READLINK(vp, &auio, IO_INVIS, NULL, error); | 394 | error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL); |
397 | |||
398 | VN_RELE(vp); | 395 | VN_RELE(vp); |
396 | if (error) | ||
397 | return -error; | ||
398 | |||
399 | return (olen - auio.uio_resid); | 399 | return (olen - auio.uio_resid); |
400 | } | 400 | } |
401 | 401 | ||
@@ -411,7 +411,7 @@ xfs_fssetdm_by_handle( | |||
411 | xfs_fsop_setdm_handlereq_t dmhreq; | 411 | xfs_fsop_setdm_handlereq_t dmhreq; |
412 | struct inode *inode; | 412 | struct inode *inode; |
413 | bhv_desc_t *bdp; | 413 | bhv_desc_t *bdp; |
414 | vnode_t *vp; | 414 | bhv_vnode_t *vp; |
415 | 415 | ||
416 | if (!capable(CAP_MKNOD)) | 416 | if (!capable(CAP_MKNOD)) |
417 | return -XFS_ERROR(EPERM); | 417 | return -XFS_ERROR(EPERM); |
@@ -452,7 +452,7 @@ xfs_attrlist_by_handle( | |||
452 | attrlist_cursor_kern_t *cursor; | 452 | attrlist_cursor_kern_t *cursor; |
453 | xfs_fsop_attrlist_handlereq_t al_hreq; | 453 | xfs_fsop_attrlist_handlereq_t al_hreq; |
454 | struct inode *inode; | 454 | struct inode *inode; |
455 | vnode_t *vp; | 455 | bhv_vnode_t *vp; |
456 | char *kbuf; | 456 | char *kbuf; |
457 | 457 | ||
458 | if (!capable(CAP_SYS_ADMIN)) | 458 | if (!capable(CAP_SYS_ADMIN)) |
@@ -472,8 +472,8 @@ xfs_attrlist_by_handle( | |||
472 | goto out_vn_rele; | 472 | goto out_vn_rele; |
473 | 473 | ||
474 | cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; | 474 | cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; |
475 | VOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags, | 475 | error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags, |
476 | cursor, NULL, error); | 476 | cursor, NULL); |
477 | if (error) | 477 | if (error) |
478 | goto out_kfree; | 478 | goto out_kfree; |
479 | 479 | ||
@@ -490,7 +490,7 @@ xfs_attrlist_by_handle( | |||
490 | 490 | ||
491 | STATIC int | 491 | STATIC int |
492 | xfs_attrmulti_attr_get( | 492 | xfs_attrmulti_attr_get( |
493 | struct vnode *vp, | 493 | bhv_vnode_t *vp, |
494 | char *name, | 494 | char *name, |
495 | char __user *ubuf, | 495 | char __user *ubuf, |
496 | __uint32_t *len, | 496 | __uint32_t *len, |
@@ -505,7 +505,7 @@ xfs_attrmulti_attr_get( | |||
505 | if (!kbuf) | 505 | if (!kbuf) |
506 | return ENOMEM; | 506 | return ENOMEM; |
507 | 507 | ||
508 | VOP_ATTR_GET(vp, name, kbuf, len, flags, NULL, error); | 508 | error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL); |
509 | if (error) | 509 | if (error) |
510 | goto out_kfree; | 510 | goto out_kfree; |
511 | 511 | ||
@@ -519,7 +519,7 @@ xfs_attrmulti_attr_get( | |||
519 | 519 | ||
520 | STATIC int | 520 | STATIC int |
521 | xfs_attrmulti_attr_set( | 521 | xfs_attrmulti_attr_set( |
522 | struct vnode *vp, | 522 | bhv_vnode_t *vp, |
523 | char *name, | 523 | char *name, |
524 | const char __user *ubuf, | 524 | const char __user *ubuf, |
525 | __uint32_t len, | 525 | __uint32_t len, |
@@ -542,7 +542,7 @@ xfs_attrmulti_attr_set( | |||
542 | if (copy_from_user(kbuf, ubuf, len)) | 542 | if (copy_from_user(kbuf, ubuf, len)) |
543 | goto out_kfree; | 543 | goto out_kfree; |
544 | 544 | ||
545 | VOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error); | 545 | error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL); |
546 | 546 | ||
547 | out_kfree: | 547 | out_kfree: |
548 | kfree(kbuf); | 548 | kfree(kbuf); |
@@ -551,20 +551,15 @@ xfs_attrmulti_attr_set( | |||
551 | 551 | ||
552 | STATIC int | 552 | STATIC int |
553 | xfs_attrmulti_attr_remove( | 553 | xfs_attrmulti_attr_remove( |
554 | struct vnode *vp, | 554 | bhv_vnode_t *vp, |
555 | char *name, | 555 | char *name, |
556 | __uint32_t flags) | 556 | __uint32_t flags) |
557 | { | 557 | { |
558 | int error; | ||
559 | |||
560 | |||
561 | if (IS_RDONLY(&vp->v_inode)) | 558 | if (IS_RDONLY(&vp->v_inode)) |
562 | return -EROFS; | 559 | return -EROFS; |
563 | if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) | 560 | if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) |
564 | return EPERM; | 561 | return EPERM; |
565 | 562 | return bhv_vop_attr_remove(vp, name, flags, NULL); | |
566 | VOP_ATTR_REMOVE(vp, name, flags, NULL, error); | ||
567 | return error; | ||
568 | } | 563 | } |
569 | 564 | ||
570 | STATIC int | 565 | STATIC int |
@@ -578,7 +573,7 @@ xfs_attrmulti_by_handle( | |||
578 | xfs_attr_multiop_t *ops; | 573 | xfs_attr_multiop_t *ops; |
579 | xfs_fsop_attrmulti_handlereq_t am_hreq; | 574 | xfs_fsop_attrmulti_handlereq_t am_hreq; |
580 | struct inode *inode; | 575 | struct inode *inode; |
581 | vnode_t *vp; | 576 | bhv_vnode_t *vp; |
582 | unsigned int i, size; | 577 | unsigned int i, size; |
583 | char *attr_name; | 578 | char *attr_name; |
584 | 579 | ||
@@ -658,7 +653,7 @@ xfs_attrmulti_by_handle( | |||
658 | STATIC int | 653 | STATIC int |
659 | xfs_ioc_space( | 654 | xfs_ioc_space( |
660 | bhv_desc_t *bdp, | 655 | bhv_desc_t *bdp, |
661 | vnode_t *vp, | 656 | bhv_vnode_t *vp, |
662 | struct file *filp, | 657 | struct file *filp, |
663 | int flags, | 658 | int flags, |
664 | unsigned int cmd, | 659 | unsigned int cmd, |
@@ -682,7 +677,7 @@ xfs_ioc_fsgeometry( | |||
682 | 677 | ||
683 | STATIC int | 678 | STATIC int |
684 | xfs_ioc_xattr( | 679 | xfs_ioc_xattr( |
685 | vnode_t *vp, | 680 | bhv_vnode_t *vp, |
686 | xfs_inode_t *ip, | 681 | xfs_inode_t *ip, |
687 | struct file *filp, | 682 | struct file *filp, |
688 | unsigned int cmd, | 683 | unsigned int cmd, |
@@ -711,7 +706,7 @@ xfs_ioctl( | |||
711 | void __user *arg) | 706 | void __user *arg) |
712 | { | 707 | { |
713 | int error; | 708 | int error; |
714 | vnode_t *vp; | 709 | bhv_vnode_t *vp; |
715 | xfs_inode_t *ip; | 710 | xfs_inode_t *ip; |
716 | xfs_mount_t *mp; | 711 | xfs_mount_t *mp; |
717 | 712 | ||
@@ -962,7 +957,7 @@ xfs_ioctl( | |||
962 | STATIC int | 957 | STATIC int |
963 | xfs_ioc_space( | 958 | xfs_ioc_space( |
964 | bhv_desc_t *bdp, | 959 | bhv_desc_t *bdp, |
965 | vnode_t *vp, | 960 | bhv_vnode_t *vp, |
966 | struct file *filp, | 961 | struct file *filp, |
967 | int ioflags, | 962 | int ioflags, |
968 | unsigned int cmd, | 963 | unsigned int cmd, |
@@ -1153,14 +1148,14 @@ xfs_di2lxflags( | |||
1153 | 1148 | ||
1154 | STATIC int | 1149 | STATIC int |
1155 | xfs_ioc_xattr( | 1150 | xfs_ioc_xattr( |
1156 | vnode_t *vp, | 1151 | bhv_vnode_t *vp, |
1157 | xfs_inode_t *ip, | 1152 | xfs_inode_t *ip, |
1158 | struct file *filp, | 1153 | struct file *filp, |
1159 | unsigned int cmd, | 1154 | unsigned int cmd, |
1160 | void __user *arg) | 1155 | void __user *arg) |
1161 | { | 1156 | { |
1162 | struct fsxattr fa; | 1157 | struct fsxattr fa; |
1163 | struct vattr *vattr; | 1158 | struct bhv_vattr *vattr; |
1164 | int error = 0; | 1159 | int error = 0; |
1165 | int attr_flags; | 1160 | int attr_flags; |
1166 | unsigned int flags; | 1161 | unsigned int flags; |
@@ -1173,7 +1168,7 @@ xfs_ioc_xattr( | |||
1173 | case XFS_IOC_FSGETXATTR: { | 1168 | case XFS_IOC_FSGETXATTR: { |
1174 | vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ | 1169 | vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ |
1175 | XFS_AT_NEXTENTS | XFS_AT_PROJID; | 1170 | XFS_AT_NEXTENTS | XFS_AT_PROJID; |
1176 | VOP_GETATTR(vp, vattr, 0, NULL, error); | 1171 | error = bhv_vop_getattr(vp, vattr, 0, NULL); |
1177 | if (unlikely(error)) { | 1172 | if (unlikely(error)) { |
1178 | error = -error; | 1173 | error = -error; |
1179 | break; | 1174 | break; |
@@ -1206,7 +1201,7 @@ xfs_ioc_xattr( | |||
1206 | vattr->va_extsize = fa.fsx_extsize; | 1201 | vattr->va_extsize = fa.fsx_extsize; |
1207 | vattr->va_projid = fa.fsx_projid; | 1202 | vattr->va_projid = fa.fsx_projid; |
1208 | 1203 | ||
1209 | VOP_SETATTR(vp, vattr, attr_flags, NULL, error); | 1204 | error = bhv_vop_setattr(vp, vattr, attr_flags, NULL); |
1210 | if (likely(!error)) | 1205 | if (likely(!error)) |
1211 | __vn_revalidate(vp, vattr); /* update flags */ | 1206 | __vn_revalidate(vp, vattr); /* update flags */ |
1212 | error = -error; | 1207 | error = -error; |
@@ -1216,7 +1211,7 @@ xfs_ioc_xattr( | |||
1216 | case XFS_IOC_FSGETXATTRA: { | 1211 | case XFS_IOC_FSGETXATTRA: { |
1217 | vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ | 1212 | vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ |
1218 | XFS_AT_ANEXTENTS | XFS_AT_PROJID; | 1213 | XFS_AT_ANEXTENTS | XFS_AT_PROJID; |
1219 | VOP_GETATTR(vp, vattr, 0, NULL, error); | 1214 | error = bhv_vop_getattr(vp, vattr, 0, NULL); |
1220 | if (unlikely(error)) { | 1215 | if (unlikely(error)) { |
1221 | error = -error; | 1216 | error = -error; |
1222 | break; | 1217 | break; |
@@ -1262,7 +1257,7 @@ xfs_ioc_xattr( | |||
1262 | vattr->va_xflags = xfs_merge_ioc_xflags(flags, | 1257 | vattr->va_xflags = xfs_merge_ioc_xflags(flags, |
1263 | xfs_ip2xflags(ip)); | 1258 | xfs_ip2xflags(ip)); |
1264 | 1259 | ||
1265 | VOP_SETATTR(vp, vattr, attr_flags, NULL, error); | 1260 | error = bhv_vop_setattr(vp, vattr, attr_flags, NULL); |
1266 | if (likely(!error)) | 1261 | if (likely(!error)) |
1267 | __vn_revalidate(vp, vattr); /* update flags */ | 1262 | __vn_revalidate(vp, vattr); /* update flags */ |
1268 | error = -error; | 1263 | error = -error; |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index 251bfe451a3f..601f01c92f7f 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c | |||
@@ -114,7 +114,7 @@ xfs_compat_ioctl( | |||
114 | unsigned long arg) | 114 | unsigned long arg) |
115 | { | 115 | { |
116 | struct inode *inode = file->f_dentry->d_inode; | 116 | struct inode *inode = file->f_dentry->d_inode; |
117 | vnode_t *vp = vn_from_inode(inode); | 117 | bhv_vnode_t *vp = vn_from_inode(inode); |
118 | int error; | 118 | int error; |
119 | 119 | ||
120 | switch (cmd) { | 120 | switch (cmd) { |
@@ -193,7 +193,7 @@ xfs_compat_ioctl( | |||
193 | return -ENOIOCTLCMD; | 193 | return -ENOIOCTLCMD; |
194 | } | 194 | } |
195 | 195 | ||
196 | VOP_IOCTL(vp, inode, file, mode, cmd, (void __user *)arg, error); | 196 | error = bhv_vop_ioctl(vp, inode, file, mode, cmd, (void __user *)arg); |
197 | VMODIFY(vp); | 197 | VMODIFY(vp); |
198 | 198 | ||
199 | return error; | 199 | return error; |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 2e2e275c786f..12810baeb5d4 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -61,7 +59,7 @@ | |||
61 | */ | 59 | */ |
62 | xfs_inode_t * | 60 | xfs_inode_t * |
63 | xfs_vtoi( | 61 | xfs_vtoi( |
64 | struct vnode *vp) | 62 | bhv_vnode_t *vp) |
65 | { | 63 | { |
66 | bhv_desc_t *bdp; | 64 | bhv_desc_t *bdp; |
67 | 65 | ||
@@ -80,7 +78,7 @@ void | |||
80 | xfs_synchronize_atime( | 78 | xfs_synchronize_atime( |
81 | xfs_inode_t *ip) | 79 | xfs_inode_t *ip) |
82 | { | 80 | { |
83 | vnode_t *vp; | 81 | bhv_vnode_t *vp; |
84 | 82 | ||
85 | vp = XFS_ITOV_NULL(ip); | 83 | vp = XFS_ITOV_NULL(ip); |
86 | if (vp) { | 84 | if (vp) { |
@@ -200,14 +198,10 @@ xfs_ichgtime_fast( | |||
200 | STATIC void | 198 | STATIC void |
201 | xfs_validate_fields( | 199 | xfs_validate_fields( |
202 | struct inode *ip, | 200 | struct inode *ip, |
203 | struct vattr *vattr) | 201 | bhv_vattr_t *vattr) |
204 | { | 202 | { |
205 | vnode_t *vp = vn_from_inode(ip); | ||
206 | int error; | ||
207 | |||
208 | vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS; | 203 | vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS; |
209 | VOP_GETATTR(vp, vattr, ATTR_LAZY, NULL, error); | 204 | if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) { |
210 | if (likely(!error)) { | ||
211 | ip->i_nlink = vattr->va_nlink; | 205 | ip->i_nlink = vattr->va_nlink; |
212 | ip->i_blocks = vattr->va_nblocks; | 206 | ip->i_blocks = vattr->va_nblocks; |
213 | 207 | ||
@@ -225,7 +219,7 @@ xfs_validate_fields( | |||
225 | */ | 219 | */ |
226 | STATIC int | 220 | STATIC int |
227 | xfs_init_security( | 221 | xfs_init_security( |
228 | struct vnode *vp, | 222 | bhv_vnode_t *vp, |
229 | struct inode *dir) | 223 | struct inode *dir) |
230 | { | 224 | { |
231 | struct inode *ip = vn_to_inode(vp); | 225 | struct inode *ip = vn_to_inode(vp); |
@@ -241,7 +235,7 @@ xfs_init_security( | |||
241 | return -error; | 235 | return -error; |
242 | } | 236 | } |
243 | 237 | ||
244 | VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error); | 238 | error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL); |
245 | if (!error) | 239 | if (!error) |
246 | VMODIFY(vp); | 240 | VMODIFY(vp); |
247 | 241 | ||
@@ -264,13 +258,12 @@ xfs_has_fs_struct(struct task_struct *task) | |||
264 | 258 | ||
265 | STATIC inline void | 259 | STATIC inline void |
266 | xfs_cleanup_inode( | 260 | xfs_cleanup_inode( |
267 | vnode_t *dvp, | 261 | bhv_vnode_t *dvp, |
268 | vnode_t *vp, | 262 | bhv_vnode_t *vp, |
269 | struct dentry *dentry, | 263 | struct dentry *dentry, |
270 | int mode) | 264 | int mode) |
271 | { | 265 | { |
272 | struct dentry teardown = {}; | 266 | struct dentry teardown = {}; |
273 | int error; | ||
274 | 267 | ||
275 | /* Oh, the horror. | 268 | /* Oh, the horror. |
276 | * If we can't add the ACL or we fail in | 269 | * If we can't add the ACL or we fail in |
@@ -281,9 +274,9 @@ xfs_cleanup_inode( | |||
281 | teardown.d_name = dentry->d_name; | 274 | teardown.d_name = dentry->d_name; |
282 | 275 | ||
283 | if (S_ISDIR(mode)) | 276 | if (S_ISDIR(mode)) |
284 | VOP_RMDIR(dvp, &teardown, NULL, error); | 277 | bhv_vop_rmdir(dvp, &teardown, NULL); |
285 | else | 278 | else |
286 | VOP_REMOVE(dvp, &teardown, NULL, error); | 279 | bhv_vop_remove(dvp, &teardown, NULL); |
287 | VN_RELE(vp); | 280 | VN_RELE(vp); |
288 | } | 281 | } |
289 | 282 | ||
@@ -295,8 +288,8 @@ xfs_vn_mknod( | |||
295 | dev_t rdev) | 288 | dev_t rdev) |
296 | { | 289 | { |
297 | struct inode *ip; | 290 | struct inode *ip; |
298 | vattr_t vattr = { 0 }; | 291 | bhv_vattr_t vattr = { 0 }; |
299 | vnode_t *vp = NULL, *dvp = vn_from_inode(dir); | 292 | bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir); |
300 | xfs_acl_t *default_acl = NULL; | 293 | xfs_acl_t *default_acl = NULL; |
301 | attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; | 294 | attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; |
302 | int error; | 295 | int error; |
@@ -330,10 +323,10 @@ xfs_vn_mknod( | |||
330 | vattr.va_mask |= XFS_AT_RDEV; | 323 | vattr.va_mask |= XFS_AT_RDEV; |
331 | /*FALLTHROUGH*/ | 324 | /*FALLTHROUGH*/ |
332 | case S_IFREG: | 325 | case S_IFREG: |
333 | VOP_CREATE(dvp, dentry, &vattr, &vp, NULL, error); | 326 | error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL); |
334 | break; | 327 | break; |
335 | case S_IFDIR: | 328 | case S_IFDIR: |
336 | VOP_MKDIR(dvp, dentry, &vattr, &vp, NULL, error); | 329 | error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL); |
337 | break; | 330 | break; |
338 | default: | 331 | default: |
339 | error = EINVAL; | 332 | error = EINVAL; |
@@ -396,14 +389,14 @@ xfs_vn_lookup( | |||
396 | struct dentry *dentry, | 389 | struct dentry *dentry, |
397 | struct nameidata *nd) | 390 | struct nameidata *nd) |
398 | { | 391 | { |
399 | struct vnode *vp = vn_from_inode(dir), *cvp; | 392 | bhv_vnode_t *vp = vn_from_inode(dir), *cvp; |
400 | int error; | 393 | int error; |
401 | 394 | ||
402 | if (dentry->d_name.len >= MAXNAMELEN) | 395 | if (dentry->d_name.len >= MAXNAMELEN) |
403 | return ERR_PTR(-ENAMETOOLONG); | 396 | return ERR_PTR(-ENAMETOOLONG); |
404 | 397 | ||
405 | VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error); | 398 | error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL); |
406 | if (error) { | 399 | if (unlikely(error)) { |
407 | if (unlikely(error != ENOENT)) | 400 | if (unlikely(error != ENOENT)) |
408 | return ERR_PTR(-error); | 401 | return ERR_PTR(-error); |
409 | d_add(dentry, NULL); | 402 | d_add(dentry, NULL); |
@@ -420,9 +413,9 @@ xfs_vn_link( | |||
420 | struct dentry *dentry) | 413 | struct dentry *dentry) |
421 | { | 414 | { |
422 | struct inode *ip; /* inode of guy being linked to */ | 415 | struct inode *ip; /* inode of guy being linked to */ |
423 | vnode_t *tdvp; /* target directory for new name/link */ | 416 | bhv_vnode_t *tdvp; /* target directory for new name/link */ |
424 | vnode_t *vp; /* vp of name being linked */ | 417 | bhv_vnode_t *vp; /* vp of name being linked */ |
425 | vattr_t vattr; | 418 | bhv_vattr_t vattr; |
426 | int error; | 419 | int error; |
427 | 420 | ||
428 | ip = old_dentry->d_inode; /* inode being linked to */ | 421 | ip = old_dentry->d_inode; /* inode being linked to */ |
@@ -432,7 +425,7 @@ xfs_vn_link( | |||
432 | tdvp = vn_from_inode(dir); | 425 | tdvp = vn_from_inode(dir); |
433 | vp = vn_from_inode(ip); | 426 | vp = vn_from_inode(ip); |
434 | 427 | ||
435 | VOP_LINK(tdvp, vp, dentry, NULL, error); | 428 | error = bhv_vop_link(tdvp, vp, dentry, NULL); |
436 | if (likely(!error)) { | 429 | if (likely(!error)) { |
437 | VMODIFY(tdvp); | 430 | VMODIFY(tdvp); |
438 | VN_HOLD(vp); | 431 | VN_HOLD(vp); |
@@ -448,14 +441,14 @@ xfs_vn_unlink( | |||
448 | struct dentry *dentry) | 441 | struct dentry *dentry) |
449 | { | 442 | { |
450 | struct inode *inode; | 443 | struct inode *inode; |
451 | vnode_t *dvp; /* directory containing name to remove */ | 444 | bhv_vnode_t *dvp; /* directory containing name to remove */ |
452 | vattr_t vattr; | 445 | bhv_vattr_t vattr; |
453 | int error; | 446 | int error; |
454 | 447 | ||
455 | inode = dentry->d_inode; | 448 | inode = dentry->d_inode; |
456 | dvp = vn_from_inode(dir); | 449 | dvp = vn_from_inode(dir); |
457 | 450 | ||
458 | VOP_REMOVE(dvp, dentry, NULL, error); | 451 | error = bhv_vop_remove(dvp, dentry, NULL); |
459 | if (likely(!error)) { | 452 | if (likely(!error)) { |
460 | xfs_validate_fields(dir, &vattr); /* size needs update */ | 453 | xfs_validate_fields(dir, &vattr); /* size needs update */ |
461 | xfs_validate_fields(inode, &vattr); | 454 | xfs_validate_fields(inode, &vattr); |
@@ -470,27 +463,26 @@ xfs_vn_symlink( | |||
470 | const char *symname) | 463 | const char *symname) |
471 | { | 464 | { |
472 | struct inode *ip; | 465 | struct inode *ip; |
473 | vattr_t vattr = { 0 }; | 466 | bhv_vattr_t va = { 0 }; |
474 | vnode_t *dvp; /* directory containing name of symlink */ | 467 | bhv_vnode_t *dvp; /* directory containing name of symlink */ |
475 | vnode_t *cvp; /* used to lookup symlink to put in dentry */ | 468 | bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */ |
476 | int error; | 469 | int error; |
477 | 470 | ||
478 | dvp = vn_from_inode(dir); | 471 | dvp = vn_from_inode(dir); |
479 | cvp = NULL; | 472 | cvp = NULL; |
480 | 473 | ||
481 | vattr.va_mode = S_IFLNK | | 474 | va.va_mode = S_IFLNK | |
482 | (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); | 475 | (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); |
483 | vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE; | 476 | va.va_mask = XFS_AT_TYPE|XFS_AT_MODE; |
484 | 477 | ||
485 | error = 0; | 478 | error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL); |
486 | VOP_SYMLINK(dvp, dentry, &vattr, (char *)symname, &cvp, NULL, error); | ||
487 | if (likely(!error && cvp)) { | 479 | if (likely(!error && cvp)) { |
488 | error = xfs_init_security(cvp, dir); | 480 | error = xfs_init_security(cvp, dir); |
489 | if (likely(!error)) { | 481 | if (likely(!error)) { |
490 | ip = vn_to_inode(cvp); | 482 | ip = vn_to_inode(cvp); |
491 | d_instantiate(dentry, ip); | 483 | d_instantiate(dentry, ip); |
492 | xfs_validate_fields(dir, &vattr); | 484 | xfs_validate_fields(dir, &va); |
493 | xfs_validate_fields(ip, &vattr); | 485 | xfs_validate_fields(ip, &va); |
494 | } else { | 486 | } else { |
495 | xfs_cleanup_inode(dvp, cvp, dentry, 0); | 487 | xfs_cleanup_inode(dvp, cvp, dentry, 0); |
496 | } | 488 | } |
@@ -504,11 +496,11 @@ xfs_vn_rmdir( | |||
504 | struct dentry *dentry) | 496 | struct dentry *dentry) |
505 | { | 497 | { |
506 | struct inode *inode = dentry->d_inode; | 498 | struct inode *inode = dentry->d_inode; |
507 | vnode_t *dvp = vn_from_inode(dir); | 499 | bhv_vnode_t *dvp = vn_from_inode(dir); |
508 | vattr_t vattr; | 500 | bhv_vattr_t vattr; |
509 | int error; | 501 | int error; |
510 | 502 | ||
511 | VOP_RMDIR(dvp, dentry, NULL, error); | 503 | error = bhv_vop_rmdir(dvp, dentry, NULL); |
512 | if (likely(!error)) { | 504 | if (likely(!error)) { |
513 | xfs_validate_fields(inode, &vattr); | 505 | xfs_validate_fields(inode, &vattr); |
514 | xfs_validate_fields(dir, &vattr); | 506 | xfs_validate_fields(dir, &vattr); |
@@ -524,15 +516,15 @@ xfs_vn_rename( | |||
524 | struct dentry *ndentry) | 516 | struct dentry *ndentry) |
525 | { | 517 | { |
526 | struct inode *new_inode = ndentry->d_inode; | 518 | struct inode *new_inode = ndentry->d_inode; |
527 | vnode_t *fvp; /* from directory */ | 519 | bhv_vnode_t *fvp; /* from directory */ |
528 | vnode_t *tvp; /* target directory */ | 520 | bhv_vnode_t *tvp; /* target directory */ |
529 | vattr_t vattr; | 521 | bhv_vattr_t vattr; |
530 | int error; | 522 | int error; |
531 | 523 | ||
532 | fvp = vn_from_inode(odir); | 524 | fvp = vn_from_inode(odir); |
533 | tvp = vn_from_inode(ndir); | 525 | tvp = vn_from_inode(ndir); |
534 | 526 | ||
535 | VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error); | 527 | error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL); |
536 | if (likely(!error)) { | 528 | if (likely(!error)) { |
537 | if (new_inode) | 529 | if (new_inode) |
538 | xfs_validate_fields(new_inode, &vattr); | 530 | xfs_validate_fields(new_inode, &vattr); |
@@ -553,7 +545,7 @@ xfs_vn_follow_link( | |||
553 | struct dentry *dentry, | 545 | struct dentry *dentry, |
554 | struct nameidata *nd) | 546 | struct nameidata *nd) |
555 | { | 547 | { |
556 | vnode_t *vp; | 548 | bhv_vnode_t *vp; |
557 | uio_t *uio; | 549 | uio_t *uio; |
558 | iovec_t iov; | 550 | iovec_t iov; |
559 | int error; | 551 | int error; |
@@ -586,8 +578,8 @@ xfs_vn_follow_link( | |||
586 | uio->uio_resid = MAXPATHLEN; | 578 | uio->uio_resid = MAXPATHLEN; |
587 | uio->uio_iovcnt = 1; | 579 | uio->uio_iovcnt = 1; |
588 | 580 | ||
589 | VOP_READLINK(vp, uio, 0, NULL, error); | 581 | error = bhv_vop_readlink(vp, uio, 0, NULL); |
590 | if (error) { | 582 | if (unlikely(error)) { |
591 | kfree(link); | 583 | kfree(link); |
592 | link = ERR_PTR(-error); | 584 | link = ERR_PTR(-error); |
593 | } else { | 585 | } else { |
@@ -618,12 +610,7 @@ xfs_vn_permission( | |||
618 | int mode, | 610 | int mode, |
619 | struct nameidata *nd) | 611 | struct nameidata *nd) |
620 | { | 612 | { |
621 | vnode_t *vp = vn_from_inode(inode); | 613 | return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL); |
622 | int error; | ||
623 | |||
624 | mode <<= 6; /* convert from linux to vnode access bits */ | ||
625 | VOP_ACCESS(vp, mode, NULL, error); | ||
626 | return -error; | ||
627 | } | 614 | } |
628 | #else | 615 | #else |
629 | #define xfs_vn_permission NULL | 616 | #define xfs_vn_permission NULL |
@@ -636,14 +623,14 @@ xfs_vn_getattr( | |||
636 | struct kstat *stat) | 623 | struct kstat *stat) |
637 | { | 624 | { |
638 | struct inode *inode = dentry->d_inode; | 625 | struct inode *inode = dentry->d_inode; |
639 | vnode_t *vp = vn_from_inode(inode); | 626 | bhv_vnode_t *vp = vn_from_inode(inode); |
640 | int error = 0; | 627 | int error = 0; |
641 | 628 | ||
642 | if (unlikely(vp->v_flag & VMODIFIED)) | 629 | if (unlikely(vp->v_flag & VMODIFIED)) |
643 | error = vn_revalidate(vp); | 630 | error = vn_revalidate(vp); |
644 | if (!error) | 631 | if (!error) |
645 | generic_fillattr(inode, stat); | 632 | generic_fillattr(inode, stat); |
646 | return 0; | 633 | return -error; |
647 | } | 634 | } |
648 | 635 | ||
649 | STATIC int | 636 | STATIC int |
@@ -653,8 +640,8 @@ xfs_vn_setattr( | |||
653 | { | 640 | { |
654 | struct inode *inode = dentry->d_inode; | 641 | struct inode *inode = dentry->d_inode; |
655 | unsigned int ia_valid = attr->ia_valid; | 642 | unsigned int ia_valid = attr->ia_valid; |
656 | vnode_t *vp = vn_from_inode(inode); | 643 | bhv_vnode_t *vp = vn_from_inode(inode); |
657 | vattr_t vattr = { 0 }; | 644 | bhv_vattr_t vattr = { 0 }; |
658 | int flags = 0; | 645 | int flags = 0; |
659 | int error; | 646 | int error; |
660 | 647 | ||
@@ -697,7 +684,7 @@ xfs_vn_setattr( | |||
697 | flags |= ATTR_NONBLOCK; | 684 | flags |= ATTR_NONBLOCK; |
698 | #endif | 685 | #endif |
699 | 686 | ||
700 | VOP_SETATTR(vp, &vattr, flags, NULL, error); | 687 | error = bhv_vop_setattr(vp, &vattr, flags, NULL); |
701 | if (likely(!error)) | 688 | if (likely(!error)) |
702 | __vn_revalidate(vp, &vattr); | 689 | __vn_revalidate(vp, &vattr); |
703 | return -error; | 690 | return -error; |
@@ -718,7 +705,7 @@ xfs_vn_setxattr( | |||
718 | size_t size, | 705 | size_t size, |
719 | int flags) | 706 | int flags) |
720 | { | 707 | { |
721 | vnode_t *vp = vn_from_inode(dentry->d_inode); | 708 | bhv_vnode_t *vp = vn_from_inode(dentry->d_inode); |
722 | char *attr = (char *)name; | 709 | char *attr = (char *)name; |
723 | attrnames_t *namesp; | 710 | attrnames_t *namesp; |
724 | int xflags = 0; | 711 | int xflags = 0; |
@@ -748,7 +735,7 @@ xfs_vn_getxattr( | |||
748 | void *data, | 735 | void *data, |
749 | size_t size) | 736 | size_t size) |
750 | { | 737 | { |
751 | vnode_t *vp = vn_from_inode(dentry->d_inode); | 738 | bhv_vnode_t *vp = vn_from_inode(dentry->d_inode); |
752 | char *attr = (char *)name; | 739 | char *attr = (char *)name; |
753 | attrnames_t *namesp; | 740 | attrnames_t *namesp; |
754 | int xflags = 0; | 741 | int xflags = 0; |
@@ -777,7 +764,7 @@ xfs_vn_listxattr( | |||
777 | char *data, | 764 | char *data, |
778 | size_t size) | 765 | size_t size) |
779 | { | 766 | { |
780 | vnode_t *vp = vn_from_inode(dentry->d_inode); | 767 | bhv_vnode_t *vp = vn_from_inode(dentry->d_inode); |
781 | int error, xflags = ATTR_KERNAMELS; | 768 | int error, xflags = ATTR_KERNAMELS; |
782 | ssize_t result; | 769 | ssize_t result; |
783 | 770 | ||
@@ -796,7 +783,7 @@ xfs_vn_removexattr( | |||
796 | struct dentry *dentry, | 783 | struct dentry *dentry, |
797 | const char *name) | 784 | const char *name) |
798 | { | 785 | { |
799 | vnode_t *vp = vn_from_inode(dentry->d_inode); | 786 | bhv_vnode_t *vp = vn_from_inode(dentry->d_inode); |
800 | char *attr = (char *)name; | 787 | char *attr = (char *)name; |
801 | attrnames_t *namesp; | 788 | attrnames_t *namesp; |
802 | int xflags = 0; | 789 | int xflags = 0; |
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index e9fe43d74768..aa26ab906c88 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
@@ -134,14 +134,21 @@ BUFFER_FNS(PrivateStart, unwritten); | |||
134 | #define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val | 134 | #define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val |
135 | #define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val | 135 | #define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val |
136 | #define xfs_rotorstep xfs_params.rotorstep.val | 136 | #define xfs_rotorstep xfs_params.rotorstep.val |
137 | #define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val | ||
137 | 138 | ||
138 | #ifndef raw_smp_processor_id | 139 | #define current_cpu() (raw_smp_processor_id()) |
139 | #define raw_smp_processor_id() smp_processor_id() | ||
140 | #endif | ||
141 | #define current_cpu() raw_smp_processor_id() | ||
142 | #define current_pid() (current->pid) | 140 | #define current_pid() (current->pid) |
143 | #define current_fsuid(cred) (current->fsuid) | 141 | #define current_fsuid(cred) (current->fsuid) |
144 | #define current_fsgid(cred) (current->fsgid) | 142 | #define current_fsgid(cred) (current->fsgid) |
143 | #define current_set_flags(f) (current->flags |= (f)) | ||
144 | #define current_test_flags(f) (current->flags & (f)) | ||
145 | #define current_clear_flags(f) (current->flags & ~(f)) | ||
146 | #define current_set_flags_nested(sp, f) \ | ||
147 | (*(sp) = current->flags, current->flags |= (f)) | ||
148 | #define current_clear_flags_nested(sp, f) \ | ||
149 | (*(sp) = current->flags, current->flags &= ~(f)) | ||
150 | #define current_restore_flags_nested(sp, f) \ | ||
151 | (current->flags = ((current->flags & ~(f)) | (*(sp) & (f)))) | ||
145 | 152 | ||
146 | #define NBPP PAGE_SIZE | 153 | #define NBPP PAGE_SIZE |
147 | #define DPPSHFT (PAGE_SHIFT - 9) | 154 | #define DPPSHFT (PAGE_SHIFT - 9) |
@@ -187,25 +194,9 @@ BUFFER_FNS(PrivateStart, unwritten); | |||
187 | /* bytes to clicks */ | 194 | /* bytes to clicks */ |
188 | #define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) | 195 | #define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) |
189 | 196 | ||
190 | #ifndef ENOATTR | ||
191 | #define ENOATTR ENODATA /* Attribute not found */ | 197 | #define ENOATTR ENODATA /* Attribute not found */ |
192 | #endif | 198 | #define EWRONGFS EINVAL /* Mount with wrong filesystem type */ |
193 | 199 | #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ | |
194 | /* Note: EWRONGFS never visible outside the kernel */ | ||
195 | #define EWRONGFS EINVAL /* Mount with wrong filesystem type */ | ||
196 | |||
197 | /* | ||
198 | * XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't | ||
199 | * return codes out of its known range in errno. | ||
200 | * XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't | ||
201 | * conflict with any code we use already or any code a driver may use) | ||
202 | * XXX Some options (currently we do #2): | ||
203 | * 1/ New error code ["Filesystem is corrupted", _after_ glibc updated] | ||
204 | * 2/ 990 ["Unknown error 990"] | ||
205 | * 3/ EUCLEAN ["Structure needs cleaning"] | ||
206 | * 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace] | ||
207 | */ | ||
208 | #define EFSCORRUPTED 990 /* Filesystem is corrupted */ | ||
209 | 200 | ||
210 | #define SYNCHRONIZE() barrier() | 201 | #define SYNCHRONIZE() barrier() |
211 | #define __return_address __builtin_return_address(0) | 202 | #define __return_address __builtin_return_address(0) |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 67efe3308980..5d9cfd91ad08 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -206,7 +204,7 @@ xfs_read( | |||
206 | xfs_fsize_t n; | 204 | xfs_fsize_t n; |
207 | xfs_inode_t *ip; | 205 | xfs_inode_t *ip; |
208 | xfs_mount_t *mp; | 206 | xfs_mount_t *mp; |
209 | vnode_t *vp; | 207 | bhv_vnode_t *vp; |
210 | unsigned long seg; | 208 | unsigned long seg; |
211 | 209 | ||
212 | ip = XFS_BHVTOI(bdp); | 210 | ip = XFS_BHVTOI(bdp); |
@@ -258,7 +256,7 @@ xfs_read( | |||
258 | 256 | ||
259 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && | 257 | if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && |
260 | !(ioflags & IO_INVIS)) { | 258 | !(ioflags & IO_INVIS)) { |
261 | vrwlock_t locktype = VRWLOCK_READ; | 259 | bhv_vrwlock_t locktype = VRWLOCK_READ; |
262 | int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); | 260 | int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); |
263 | 261 | ||
264 | ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, | 262 | ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, |
@@ -271,7 +269,7 @@ xfs_read( | |||
271 | } | 269 | } |
272 | 270 | ||
273 | if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) | 271 | if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) |
274 | VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(*offset)), | 272 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), |
275 | -1, FI_REMAPF_LOCKED); | 273 | -1, FI_REMAPF_LOCKED); |
276 | 274 | ||
277 | xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, | 275 | xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, |
@@ -313,7 +311,7 @@ xfs_sendfile( | |||
313 | 311 | ||
314 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && | 312 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && |
315 | (!(ioflags & IO_INVIS))) { | 313 | (!(ioflags & IO_INVIS))) { |
316 | vrwlock_t locktype = VRWLOCK_READ; | 314 | bhv_vrwlock_t locktype = VRWLOCK_READ; |
317 | int error; | 315 | int error; |
318 | 316 | ||
319 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), | 317 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), |
@@ -357,7 +355,7 @@ xfs_splice_read( | |||
357 | 355 | ||
358 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && | 356 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && |
359 | (!(ioflags & IO_INVIS))) { | 357 | (!(ioflags & IO_INVIS))) { |
360 | vrwlock_t locktype = VRWLOCK_READ; | 358 | bhv_vrwlock_t locktype = VRWLOCK_READ; |
361 | int error; | 359 | int error; |
362 | 360 | ||
363 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), | 361 | error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), |
@@ -401,7 +399,7 @@ xfs_splice_write( | |||
401 | 399 | ||
402 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) && | 400 | if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) && |
403 | (!(ioflags & IO_INVIS))) { | 401 | (!(ioflags & IO_INVIS))) { |
404 | vrwlock_t locktype = VRWLOCK_WRITE; | 402 | bhv_vrwlock_t locktype = VRWLOCK_WRITE; |
405 | int error; | 403 | int error; |
406 | 404 | ||
407 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), | 405 | error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), |
@@ -458,7 +456,7 @@ xfs_zero_last_block( | |||
458 | last_fsb = XFS_B_TO_FSBT(mp, isize); | 456 | last_fsb = XFS_B_TO_FSBT(mp, isize); |
459 | nimaps = 1; | 457 | nimaps = 1; |
460 | error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, | 458 | error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, |
461 | &nimaps, NULL); | 459 | &nimaps, NULL, NULL); |
462 | if (error) { | 460 | if (error) { |
463 | return error; | 461 | return error; |
464 | } | 462 | } |
@@ -499,7 +497,7 @@ xfs_zero_last_block( | |||
499 | 497 | ||
500 | int /* error (positive) */ | 498 | int /* error (positive) */ |
501 | xfs_zero_eof( | 499 | xfs_zero_eof( |
502 | vnode_t *vp, | 500 | bhv_vnode_t *vp, |
503 | xfs_iocore_t *io, | 501 | xfs_iocore_t *io, |
504 | xfs_off_t offset, /* starting I/O offset */ | 502 | xfs_off_t offset, /* starting I/O offset */ |
505 | xfs_fsize_t isize, /* current inode size */ | 503 | xfs_fsize_t isize, /* current inode size */ |
@@ -510,7 +508,6 @@ xfs_zero_eof( | |||
510 | xfs_fileoff_t end_zero_fsb; | 508 | xfs_fileoff_t end_zero_fsb; |
511 | xfs_fileoff_t zero_count_fsb; | 509 | xfs_fileoff_t zero_count_fsb; |
512 | xfs_fileoff_t last_fsb; | 510 | xfs_fileoff_t last_fsb; |
513 | xfs_extlen_t buf_len_fsb; | ||
514 | xfs_mount_t *mp = io->io_mount; | 511 | xfs_mount_t *mp = io->io_mount; |
515 | int nimaps; | 512 | int nimaps; |
516 | int error = 0; | 513 | int error = 0; |
@@ -556,7 +553,7 @@ xfs_zero_eof( | |||
556 | nimaps = 1; | 553 | nimaps = 1; |
557 | zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; | 554 | zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; |
558 | error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, | 555 | error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, |
559 | 0, NULL, 0, &imap, &nimaps, NULL); | 556 | 0, NULL, 0, &imap, &nimaps, NULL, NULL); |
560 | if (error) { | 557 | if (error) { |
561 | ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); | 558 | ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); |
562 | ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); | 559 | ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); |
@@ -579,16 +576,7 @@ xfs_zero_eof( | |||
579 | } | 576 | } |
580 | 577 | ||
581 | /* | 578 | /* |
582 | * There are blocks in the range requested. | 579 | * There are blocks we need to zero. |
583 | * Zero them a single write at a time. We actually | ||
584 | * don't zero the entire range returned if it is | ||
585 | * too big and simply loop around to get the rest. | ||
586 | * That is not the most efficient thing to do, but it | ||
587 | * is simple and this path should not be exercised often. | ||
588 | */ | ||
589 | buf_len_fsb = XFS_FILBLKS_MIN(imap.br_blockcount, | ||
590 | mp->m_writeio_blocks << 8); | ||
591 | /* | ||
592 | * Drop the inode lock while we're doing the I/O. | 580 | * Drop the inode lock while we're doing the I/O. |
593 | * We'll still have the iolock to protect us. | 581 | * We'll still have the iolock to protect us. |
594 | */ | 582 | */ |
@@ -596,14 +584,13 @@ xfs_zero_eof( | |||
596 | 584 | ||
597 | error = xfs_iozero(ip, | 585 | error = xfs_iozero(ip, |
598 | XFS_FSB_TO_B(mp, start_zero_fsb), | 586 | XFS_FSB_TO_B(mp, start_zero_fsb), |
599 | XFS_FSB_TO_B(mp, buf_len_fsb), | 587 | XFS_FSB_TO_B(mp, imap.br_blockcount), |
600 | end_size); | 588 | end_size); |
601 | |||
602 | if (error) { | 589 | if (error) { |
603 | goto out_lock; | 590 | goto out_lock; |
604 | } | 591 | } |
605 | 592 | ||
606 | start_zero_fsb = imap.br_startoff + buf_len_fsb; | 593 | start_zero_fsb = imap.br_startoff + imap.br_blockcount; |
607 | ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); | 594 | ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); |
608 | 595 | ||
609 | XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | 596 | XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); |
@@ -637,11 +624,11 @@ xfs_write( | |||
637 | ssize_t ret = 0, error = 0; | 624 | ssize_t ret = 0, error = 0; |
638 | xfs_fsize_t isize, new_size; | 625 | xfs_fsize_t isize, new_size; |
639 | xfs_iocore_t *io; | 626 | xfs_iocore_t *io; |
640 | vnode_t *vp; | 627 | bhv_vnode_t *vp; |
641 | unsigned long seg; | 628 | unsigned long seg; |
642 | int iolock; | 629 | int iolock; |
643 | int eventsent = 0; | 630 | int eventsent = 0; |
644 | vrwlock_t locktype; | 631 | bhv_vrwlock_t locktype; |
645 | size_t ocount = 0, count; | 632 | size_t ocount = 0, count; |
646 | loff_t pos; | 633 | loff_t pos; |
647 | int need_i_mutex = 1, need_flush = 0; | 634 | int need_i_mutex = 1, need_flush = 0; |
@@ -679,11 +666,11 @@ xfs_write( | |||
679 | io = &xip->i_iocore; | 666 | io = &xip->i_iocore; |
680 | mp = io->io_mount; | 667 | mp = io->io_mount; |
681 | 668 | ||
669 | vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE); | ||
670 | |||
682 | if (XFS_FORCED_SHUTDOWN(mp)) | 671 | if (XFS_FORCED_SHUTDOWN(mp)) |
683 | return -EIO; | 672 | return -EIO; |
684 | 673 | ||
685 | fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE); | ||
686 | |||
687 | if (ioflags & IO_ISDIRECT) { | 674 | if (ioflags & IO_ISDIRECT) { |
688 | xfs_buftarg_t *target = | 675 | xfs_buftarg_t *target = |
689 | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? | 676 | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? |
@@ -814,7 +801,7 @@ retry: | |||
814 | if (need_flush) { | 801 | if (need_flush) { |
815 | xfs_inval_cached_trace(io, pos, -1, | 802 | xfs_inval_cached_trace(io, pos, -1, |
816 | ctooff(offtoct(pos)), -1); | 803 | ctooff(offtoct(pos)), -1); |
817 | VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(pos)), | 804 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)), |
818 | -1, FI_REMAPF_LOCKED); | 805 | -1, FI_REMAPF_LOCKED); |
819 | } | 806 | } |
820 | 807 | ||
@@ -903,79 +890,9 @@ retry: | |||
903 | 890 | ||
904 | /* Handle various SYNC-type writes */ | 891 | /* Handle various SYNC-type writes */ |
905 | if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { | 892 | if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { |
906 | /* | 893 | error = xfs_write_sync_logforce(mp, xip); |
907 | * If we're treating this as O_DSYNC and we have not updated the | 894 | if (error) |
908 | * size, force the log. | 895 | goto out_unlock_internal; |
909 | */ | ||
910 | if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) && | ||
911 | !(xip->i_update_size)) { | ||
912 | xfs_inode_log_item_t *iip = xip->i_itemp; | ||
913 | |||
914 | /* | ||
915 | * If an allocation transaction occurred | ||
916 | * without extending the size, then we have to force | ||
917 | * the log up the proper point to ensure that the | ||
918 | * allocation is permanent. We can't count on | ||
919 | * the fact that buffered writes lock out direct I/O | ||
920 | * writes - the direct I/O write could have extended | ||
921 | * the size nontransactionally, then finished before | ||
922 | * we started. xfs_write_file will think that the file | ||
923 | * didn't grow but the update isn't safe unless the | ||
924 | * size change is logged. | ||
925 | * | ||
926 | * Force the log if we've committed a transaction | ||
927 | * against the inode or if someone else has and | ||
928 | * the commit record hasn't gone to disk (e.g. | ||
929 | * the inode is pinned). This guarantees that | ||
930 | * all changes affecting the inode are permanent | ||
931 | * when we return. | ||
932 | */ | ||
933 | if (iip && iip->ili_last_lsn) { | ||
934 | xfs_log_force(mp, iip->ili_last_lsn, | ||
935 | XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
936 | } else if (xfs_ipincount(xip) > 0) { | ||
937 | xfs_log_force(mp, (xfs_lsn_t)0, | ||
938 | XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
939 | } | ||
940 | |||
941 | } else { | ||
942 | xfs_trans_t *tp; | ||
943 | |||
944 | /* | ||
945 | * O_SYNC or O_DSYNC _with_ a size update are handled | ||
946 | * the same way. | ||
947 | * | ||
948 | * If the write was synchronous then we need to make | ||
949 | * sure that the inode modification time is permanent. | ||
950 | * We'll have updated the timestamp above, so here | ||
951 | * we use a synchronous transaction to log the inode. | ||
952 | * It's not fast, but it's necessary. | ||
953 | * | ||
954 | * If this a dsync write and the size got changed | ||
955 | * non-transactionally, then we need to ensure that | ||
956 | * the size change gets logged in a synchronous | ||
957 | * transaction. | ||
958 | */ | ||
959 | |||
960 | tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC); | ||
961 | if ((error = xfs_trans_reserve(tp, 0, | ||
962 | XFS_SWRITE_LOG_RES(mp), | ||
963 | 0, 0, 0))) { | ||
964 | /* Transaction reserve failed */ | ||
965 | xfs_trans_cancel(tp, 0); | ||
966 | } else { | ||
967 | /* Transaction reserve successful */ | ||
968 | xfs_ilock(xip, XFS_ILOCK_EXCL); | ||
969 | xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL); | ||
970 | xfs_trans_ihold(tp, xip); | ||
971 | xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE); | ||
972 | xfs_trans_set_sync(tp); | ||
973 | error = xfs_trans_commit(tp, 0, NULL); | ||
974 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | ||
975 | } | ||
976 | if (error) | ||
977 | goto out_unlock_internal; | ||
978 | } | ||
979 | 896 | ||
980 | xfs_rwunlock(bdp, locktype); | 897 | xfs_rwunlock(bdp, locktype); |
981 | if (need_i_mutex) | 898 | if (need_i_mutex) |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index 8f4539952350..c77e62efb742 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h | |||
@@ -18,8 +18,8 @@ | |||
18 | #ifndef __XFS_LRW_H__ | 18 | #ifndef __XFS_LRW_H__ |
19 | #define __XFS_LRW_H__ | 19 | #define __XFS_LRW_H__ |
20 | 20 | ||
21 | struct vnode; | ||
22 | struct bhv_desc; | 21 | struct bhv_desc; |
22 | struct bhv_vnode; | ||
23 | struct xfs_mount; | 23 | struct xfs_mount; |
24 | struct xfs_iocore; | 24 | struct xfs_iocore; |
25 | struct xfs_inode; | 25 | struct xfs_inode; |
@@ -49,7 +49,7 @@ struct xfs_iomap; | |||
49 | #define XFS_CTRUNC4 14 | 49 | #define XFS_CTRUNC4 14 |
50 | #define XFS_CTRUNC5 15 | 50 | #define XFS_CTRUNC5 15 |
51 | #define XFS_CTRUNC6 16 | 51 | #define XFS_CTRUNC6 16 |
52 | #define XFS_BUNMAPI 17 | 52 | #define XFS_BUNMAP 17 |
53 | #define XFS_INVAL_CACHED 18 | 53 | #define XFS_INVAL_CACHED 18 |
54 | #define XFS_DIORD_ENTER 19 | 54 | #define XFS_DIORD_ENTER 19 |
55 | #define XFS_DIOWR_ENTER 20 | 55 | #define XFS_DIOWR_ENTER 20 |
@@ -82,7 +82,7 @@ extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *); | |||
82 | extern int xfs_bdstrat_cb(struct xfs_buf *); | 82 | extern int xfs_bdstrat_cb(struct xfs_buf *); |
83 | extern int xfs_dev_is_read_only(struct xfs_mount *, char *); | 83 | extern int xfs_dev_is_read_only(struct xfs_mount *, char *); |
84 | 84 | ||
85 | extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, | 85 | extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t, |
86 | xfs_fsize_t, xfs_fsize_t); | 86 | xfs_fsize_t, xfs_fsize_t); |
87 | extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, | 87 | extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, |
88 | const struct iovec *, unsigned int, | 88 | const struct iovec *, unsigned int, |
diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c index 1f0589a05eca..e480b6102051 100644 --- a/fs/xfs/linux-2.6/xfs_stats.c +++ b/fs/xfs/linux-2.6/xfs_stats.c | |||
@@ -62,7 +62,7 @@ xfs_read_xfsstats( | |||
62 | while (j < xstats[i].endpoint) { | 62 | while (j < xstats[i].endpoint) { |
63 | val = 0; | 63 | val = 0; |
64 | /* sum over all cpus */ | 64 | /* sum over all cpus */ |
65 | for_each_cpu(c) | 65 | for_each_possible_cpu(c) |
66 | val += *(((__u32*)&per_cpu(xfsstats, c) + j)); | 66 | val += *(((__u32*)&per_cpu(xfsstats, c) + j)); |
67 | len += sprintf(buffer + len, " %u", val); | 67 | len += sprintf(buffer + len, " %u", val); |
68 | j++; | 68 | j++; |
@@ -70,7 +70,7 @@ xfs_read_xfsstats( | |||
70 | buffer[len++] = '\n'; | 70 | buffer[len++] = '\n'; |
71 | } | 71 | } |
72 | /* extra precision counters */ | 72 | /* extra precision counters */ |
73 | for_each_cpu(i) { | 73 | for_each_possible_cpu(i) { |
74 | xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes; | 74 | xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes; |
75 | xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes; | 75 | xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes; |
76 | xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes; | 76 | xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes; |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 68f4793e8a11..9bdef9d51900 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -151,7 +149,7 @@ xfs_set_inodeops( | |||
151 | STATIC __inline__ void | 149 | STATIC __inline__ void |
152 | xfs_revalidate_inode( | 150 | xfs_revalidate_inode( |
153 | xfs_mount_t *mp, | 151 | xfs_mount_t *mp, |
154 | vnode_t *vp, | 152 | bhv_vnode_t *vp, |
155 | xfs_inode_t *ip) | 153 | xfs_inode_t *ip) |
156 | { | 154 | { |
157 | struct inode *inode = vn_to_inode(vp); | 155 | struct inode *inode = vn_to_inode(vp); |
@@ -206,7 +204,7 @@ xfs_revalidate_inode( | |||
206 | void | 204 | void |
207 | xfs_initialize_vnode( | 205 | xfs_initialize_vnode( |
208 | bhv_desc_t *bdp, | 206 | bhv_desc_t *bdp, |
209 | vnode_t *vp, | 207 | bhv_vnode_t *vp, |
210 | bhv_desc_t *inode_bhv, | 208 | bhv_desc_t *inode_bhv, |
211 | int unlock) | 209 | int unlock) |
212 | { | 210 | { |
@@ -336,7 +334,7 @@ STATIC struct inode * | |||
336 | xfs_fs_alloc_inode( | 334 | xfs_fs_alloc_inode( |
337 | struct super_block *sb) | 335 | struct super_block *sb) |
338 | { | 336 | { |
339 | vnode_t *vp; | 337 | bhv_vnode_t *vp; |
340 | 338 | ||
341 | vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP); | 339 | vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP); |
342 | if (unlikely(!vp)) | 340 | if (unlikely(!vp)) |
@@ -359,13 +357,13 @@ xfs_fs_inode_init_once( | |||
359 | { | 357 | { |
360 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 358 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == |
361 | SLAB_CTOR_CONSTRUCTOR) | 359 | SLAB_CTOR_CONSTRUCTOR) |
362 | inode_init_once(vn_to_inode((vnode_t *)vnode)); | 360 | inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); |
363 | } | 361 | } |
364 | 362 | ||
365 | STATIC int | 363 | STATIC int |
366 | xfs_init_zones(void) | 364 | xfs_init_zones(void) |
367 | { | 365 | { |
368 | xfs_vnode_zone = kmem_zone_init_flags(sizeof(vnode_t), "xfs_vnode_t", | 366 | xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode", |
369 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | | 367 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | |
370 | KM_ZONE_SPREAD, | 368 | KM_ZONE_SPREAD, |
371 | xfs_fs_inode_init_once); | 369 | xfs_fs_inode_init_once); |
@@ -409,22 +407,17 @@ xfs_fs_write_inode( | |||
409 | struct inode *inode, | 407 | struct inode *inode, |
410 | int sync) | 408 | int sync) |
411 | { | 409 | { |
412 | vnode_t *vp = vn_from_inode(inode); | 410 | bhv_vnode_t *vp = vn_from_inode(inode); |
413 | int error = 0, flags = FLUSH_INODE; | 411 | int error = 0, flags = FLUSH_INODE; |
414 | 412 | ||
415 | if (vp) { | 413 | if (vp) { |
416 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 414 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
417 | if (sync) | 415 | if (sync) |
418 | flags |= FLUSH_SYNC; | 416 | flags |= FLUSH_SYNC; |
419 | VOP_IFLUSH(vp, flags, error); | 417 | error = bhv_vop_iflush(vp, flags); |
420 | if (error == EAGAIN) { | 418 | if (error == EAGAIN) |
421 | if (sync) | 419 | error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0; |
422 | VOP_IFLUSH(vp, flags | FLUSH_LOG, error); | ||
423 | else | ||
424 | error = 0; | ||
425 | } | ||
426 | } | 420 | } |
427 | |||
428 | return -error; | 421 | return -error; |
429 | } | 422 | } |
430 | 423 | ||
@@ -432,8 +425,7 @@ STATIC void | |||
432 | xfs_fs_clear_inode( | 425 | xfs_fs_clear_inode( |
433 | struct inode *inode) | 426 | struct inode *inode) |
434 | { | 427 | { |
435 | vnode_t *vp = vn_from_inode(inode); | 428 | bhv_vnode_t *vp = vn_from_inode(inode); |
436 | int error, cache; | ||
437 | 429 | ||
438 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 430 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
439 | 431 | ||
@@ -446,20 +438,18 @@ xfs_fs_clear_inode( | |||
446 | * This can happen because xfs_iget_core calls xfs_idestroy if we | 438 | * This can happen because xfs_iget_core calls xfs_idestroy if we |
447 | * find an inode with di_mode == 0 but without IGET_CREATE set. | 439 | * find an inode with di_mode == 0 but without IGET_CREATE set. |
448 | */ | 440 | */ |
449 | if (vp->v_fbhv) | 441 | if (VNHEAD(vp)) |
450 | VOP_INACTIVE(vp, NULL, cache); | 442 | bhv_vop_inactive(vp, NULL); |
451 | 443 | ||
452 | VN_LOCK(vp); | 444 | VN_LOCK(vp); |
453 | vp->v_flag &= ~VMODIFIED; | 445 | vp->v_flag &= ~VMODIFIED; |
454 | VN_UNLOCK(vp, 0); | 446 | VN_UNLOCK(vp, 0); |
455 | 447 | ||
456 | if (vp->v_fbhv) { | 448 | if (VNHEAD(vp)) |
457 | VOP_RECLAIM(vp, error); | 449 | if (bhv_vop_reclaim(vp)) |
458 | if (error) | 450 | panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, vp); |
459 | panic("vn_purge: cannot reclaim"); | ||
460 | } | ||
461 | 451 | ||
462 | ASSERT(vp->v_fbhv == NULL); | 452 | ASSERT(VNHEAD(vp) == NULL); |
463 | 453 | ||
464 | #ifdef XFS_VNODE_TRACE | 454 | #ifdef XFS_VNODE_TRACE |
465 | ktrace_free(vp->v_trace); | 455 | ktrace_free(vp->v_trace); |
@@ -475,13 +465,13 @@ xfs_fs_clear_inode( | |||
475 | */ | 465 | */ |
476 | STATIC void | 466 | STATIC void |
477 | xfs_syncd_queue_work( | 467 | xfs_syncd_queue_work( |
478 | struct vfs *vfs, | 468 | struct bhv_vfs *vfs, |
479 | void *data, | 469 | void *data, |
480 | void (*syncer)(vfs_t *, void *)) | 470 | void (*syncer)(bhv_vfs_t *, void *)) |
481 | { | 471 | { |
482 | vfs_sync_work_t *work; | 472 | struct bhv_vfs_sync_work *work; |
483 | 473 | ||
484 | work = kmem_alloc(sizeof(struct vfs_sync_work), KM_SLEEP); | 474 | work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP); |
485 | INIT_LIST_HEAD(&work->w_list); | 475 | INIT_LIST_HEAD(&work->w_list); |
486 | work->w_syncer = syncer; | 476 | work->w_syncer = syncer; |
487 | work->w_data = data; | 477 | work->w_data = data; |
@@ -500,7 +490,7 @@ xfs_syncd_queue_work( | |||
500 | */ | 490 | */ |
501 | STATIC void | 491 | STATIC void |
502 | xfs_flush_inode_work( | 492 | xfs_flush_inode_work( |
503 | vfs_t *vfs, | 493 | bhv_vfs_t *vfs, |
504 | void *inode) | 494 | void *inode) |
505 | { | 495 | { |
506 | filemap_flush(((struct inode *)inode)->i_mapping); | 496 | filemap_flush(((struct inode *)inode)->i_mapping); |
@@ -512,7 +502,7 @@ xfs_flush_inode( | |||
512 | xfs_inode_t *ip) | 502 | xfs_inode_t *ip) |
513 | { | 503 | { |
514 | struct inode *inode = vn_to_inode(XFS_ITOV(ip)); | 504 | struct inode *inode = vn_to_inode(XFS_ITOV(ip)); |
515 | struct vfs *vfs = XFS_MTOVFS(ip->i_mount); | 505 | struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount); |
516 | 506 | ||
517 | igrab(inode); | 507 | igrab(inode); |
518 | xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work); | 508 | xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work); |
@@ -525,7 +515,7 @@ xfs_flush_inode( | |||
525 | */ | 515 | */ |
526 | STATIC void | 516 | STATIC void |
527 | xfs_flush_device_work( | 517 | xfs_flush_device_work( |
528 | vfs_t *vfs, | 518 | bhv_vfs_t *vfs, |
529 | void *inode) | 519 | void *inode) |
530 | { | 520 | { |
531 | sync_blockdev(vfs->vfs_super->s_bdev); | 521 | sync_blockdev(vfs->vfs_super->s_bdev); |
@@ -537,7 +527,7 @@ xfs_flush_device( | |||
537 | xfs_inode_t *ip) | 527 | xfs_inode_t *ip) |
538 | { | 528 | { |
539 | struct inode *inode = vn_to_inode(XFS_ITOV(ip)); | 529 | struct inode *inode = vn_to_inode(XFS_ITOV(ip)); |
540 | struct vfs *vfs = XFS_MTOVFS(ip->i_mount); | 530 | struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount); |
541 | 531 | ||
542 | igrab(inode); | 532 | igrab(inode); |
543 | xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work); | 533 | xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work); |
@@ -545,16 +535,16 @@ xfs_flush_device( | |||
545 | xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); | 535 | xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); |
546 | } | 536 | } |
547 | 537 | ||
548 | #define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE) | ||
549 | STATIC void | 538 | STATIC void |
550 | vfs_sync_worker( | 539 | vfs_sync_worker( |
551 | vfs_t *vfsp, | 540 | bhv_vfs_t *vfsp, |
552 | void *unused) | 541 | void *unused) |
553 | { | 542 | { |
554 | int error; | 543 | int error; |
555 | 544 | ||
556 | if (!(vfsp->vfs_flag & VFS_RDONLY)) | 545 | if (!(vfsp->vfs_flag & VFS_RDONLY)) |
557 | VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error); | 546 | error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \ |
547 | SYNC_ATTR | SYNC_REFCACHE, NULL); | ||
558 | vfsp->vfs_sync_seq++; | 548 | vfsp->vfs_sync_seq++; |
559 | wmb(); | 549 | wmb(); |
560 | wake_up(&vfsp->vfs_wait_single_sync_task); | 550 | wake_up(&vfsp->vfs_wait_single_sync_task); |
@@ -565,8 +555,8 @@ xfssyncd( | |||
565 | void *arg) | 555 | void *arg) |
566 | { | 556 | { |
567 | long timeleft; | 557 | long timeleft; |
568 | vfs_t *vfsp = (vfs_t *) arg; | 558 | bhv_vfs_t *vfsp = (bhv_vfs_t *) arg; |
569 | struct vfs_sync_work *work, *n; | 559 | bhv_vfs_sync_work_t *work, *n; |
570 | LIST_HEAD (tmp); | 560 | LIST_HEAD (tmp); |
571 | 561 | ||
572 | timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10); | 562 | timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10); |
@@ -600,7 +590,7 @@ xfssyncd( | |||
600 | list_del(&work->w_list); | 590 | list_del(&work->w_list); |
601 | if (work == &vfsp->vfs_sync_work) | 591 | if (work == &vfsp->vfs_sync_work) |
602 | continue; | 592 | continue; |
603 | kmem_free(work, sizeof(struct vfs_sync_work)); | 593 | kmem_free(work, sizeof(struct bhv_vfs_sync_work)); |
604 | } | 594 | } |
605 | } | 595 | } |
606 | 596 | ||
@@ -609,7 +599,7 @@ xfssyncd( | |||
609 | 599 | ||
610 | STATIC int | 600 | STATIC int |
611 | xfs_fs_start_syncd( | 601 | xfs_fs_start_syncd( |
612 | vfs_t *vfsp) | 602 | bhv_vfs_t *vfsp) |
613 | { | 603 | { |
614 | vfsp->vfs_sync_work.w_syncer = vfs_sync_worker; | 604 | vfsp->vfs_sync_work.w_syncer = vfs_sync_worker; |
615 | vfsp->vfs_sync_work.w_vfs = vfsp; | 605 | vfsp->vfs_sync_work.w_vfs = vfsp; |
@@ -621,7 +611,7 @@ xfs_fs_start_syncd( | |||
621 | 611 | ||
622 | STATIC void | 612 | STATIC void |
623 | xfs_fs_stop_syncd( | 613 | xfs_fs_stop_syncd( |
624 | vfs_t *vfsp) | 614 | bhv_vfs_t *vfsp) |
625 | { | 615 | { |
626 | kthread_stop(vfsp->vfs_sync_task); | 616 | kthread_stop(vfsp->vfs_sync_task); |
627 | } | 617 | } |
@@ -630,35 +620,26 @@ STATIC void | |||
630 | xfs_fs_put_super( | 620 | xfs_fs_put_super( |
631 | struct super_block *sb) | 621 | struct super_block *sb) |
632 | { | 622 | { |
633 | vfs_t *vfsp = vfs_from_sb(sb); | 623 | bhv_vfs_t *vfsp = vfs_from_sb(sb); |
634 | int error; | 624 | int error; |
635 | 625 | ||
636 | xfs_fs_stop_syncd(vfsp); | 626 | xfs_fs_stop_syncd(vfsp); |
637 | VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error); | 627 | bhv_vfs_sync(vfsp, SYNC_ATTR | SYNC_DELWRI, NULL); |
638 | if (!error) | 628 | error = bhv_vfs_unmount(vfsp, 0, NULL); |
639 | VFS_UNMOUNT(vfsp, 0, NULL, error); | ||
640 | if (error) { | 629 | if (error) { |
641 | printk("XFS unmount got error %d\n", error); | 630 | printk("XFS: unmount got error=%d\n", error); |
642 | printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp); | 631 | printk("%s: vfs=0x%p left dangling!\n", __FUNCTION__, vfsp); |
643 | return; | 632 | } else { |
633 | vfs_deallocate(vfsp); | ||
644 | } | 634 | } |
645 | |||
646 | vfs_deallocate(vfsp); | ||
647 | } | 635 | } |
648 | 636 | ||
649 | STATIC void | 637 | STATIC void |
650 | xfs_fs_write_super( | 638 | xfs_fs_write_super( |
651 | struct super_block *sb) | 639 | struct super_block *sb) |
652 | { | 640 | { |
653 | vfs_t *vfsp = vfs_from_sb(sb); | 641 | if (!(sb->s_flags & MS_RDONLY)) |
654 | int error; | 642 | bhv_vfs_sync(vfs_from_sb(sb), SYNC_FSDATA, NULL); |
655 | |||
656 | if (sb->s_flags & MS_RDONLY) { | ||
657 | sb->s_dirt = 0; /* paranoia */ | ||
658 | return; | ||
659 | } | ||
660 | /* Push the log and superblock a little */ | ||
661 | VFS_SYNC(vfsp, SYNC_FSDATA, NULL, error); | ||
662 | sb->s_dirt = 0; | 643 | sb->s_dirt = 0; |
663 | } | 644 | } |
664 | 645 | ||
@@ -667,16 +648,16 @@ xfs_fs_sync_super( | |||
667 | struct super_block *sb, | 648 | struct super_block *sb, |
668 | int wait) | 649 | int wait) |
669 | { | 650 | { |
670 | vfs_t *vfsp = vfs_from_sb(sb); | 651 | bhv_vfs_t *vfsp = vfs_from_sb(sb); |
671 | int error; | 652 | int error; |
672 | int flags = SYNC_FSDATA; | 653 | int flags; |
673 | 654 | ||
674 | if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) | 655 | if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) |
675 | flags = SYNC_QUIESCE; | 656 | flags = SYNC_QUIESCE; |
676 | else | 657 | else |
677 | flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); | 658 | flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); |
678 | 659 | ||
679 | VFS_SYNC(vfsp, flags, NULL, error); | 660 | error = bhv_vfs_sync(vfsp, flags, NULL); |
680 | sb->s_dirt = 0; | 661 | sb->s_dirt = 0; |
681 | 662 | ||
682 | if (unlikely(laptop_mode)) { | 663 | if (unlikely(laptop_mode)) { |
@@ -703,14 +684,11 @@ xfs_fs_sync_super( | |||
703 | 684 | ||
704 | STATIC int | 685 | STATIC int |
705 | xfs_fs_statfs( | 686 | xfs_fs_statfs( |
706 | struct super_block *sb, | 687 | struct dentry *dentry, |
707 | struct kstatfs *statp) | 688 | struct kstatfs *statp) |
708 | { | 689 | { |
709 | vfs_t *vfsp = vfs_from_sb(sb); | 690 | return -bhv_vfs_statvfs(vfs_from_sb(dentry->d_sb), statp, |
710 | int error; | 691 | vn_from_inode(dentry->d_inode)); |
711 | |||
712 | VFS_STATVFS(vfsp, statp, NULL, error); | ||
713 | return -error; | ||
714 | } | 692 | } |
715 | 693 | ||
716 | STATIC int | 694 | STATIC int |
@@ -719,13 +697,13 @@ xfs_fs_remount( | |||
719 | int *flags, | 697 | int *flags, |
720 | char *options) | 698 | char *options) |
721 | { | 699 | { |
722 | vfs_t *vfsp = vfs_from_sb(sb); | 700 | bhv_vfs_t *vfsp = vfs_from_sb(sb); |
723 | struct xfs_mount_args *args = xfs_args_allocate(sb, 0); | 701 | struct xfs_mount_args *args = xfs_args_allocate(sb, 0); |
724 | int error; | 702 | int error; |
725 | 703 | ||
726 | VFS_PARSEARGS(vfsp, options, args, 1, error); | 704 | error = bhv_vfs_parseargs(vfsp, options, args, 1); |
727 | if (!error) | 705 | if (!error) |
728 | VFS_MNTUPDATE(vfsp, flags, args, error); | 706 | error = bhv_vfs_mntupdate(vfsp, flags, args); |
729 | kmem_free(args, sizeof(*args)); | 707 | kmem_free(args, sizeof(*args)); |
730 | return -error; | 708 | return -error; |
731 | } | 709 | } |
@@ -734,7 +712,7 @@ STATIC void | |||
734 | xfs_fs_lockfs( | 712 | xfs_fs_lockfs( |
735 | struct super_block *sb) | 713 | struct super_block *sb) |
736 | { | 714 | { |
737 | VFS_FREEZE(vfs_from_sb(sb)); | 715 | bhv_vfs_freeze(vfs_from_sb(sb)); |
738 | } | 716 | } |
739 | 717 | ||
740 | STATIC int | 718 | STATIC int |
@@ -742,11 +720,7 @@ xfs_fs_show_options( | |||
742 | struct seq_file *m, | 720 | struct seq_file *m, |
743 | struct vfsmount *mnt) | 721 | struct vfsmount *mnt) |
744 | { | 722 | { |
745 | struct vfs *vfsp = vfs_from_sb(mnt->mnt_sb); | 723 | return -bhv_vfs_showargs(vfs_from_sb(mnt->mnt_sb), m); |
746 | int error; | ||
747 | |||
748 | VFS_SHOWARGS(vfsp, m, error); | ||
749 | return error; | ||
750 | } | 724 | } |
751 | 725 | ||
752 | STATIC int | 726 | STATIC int |
@@ -754,11 +728,7 @@ xfs_fs_quotasync( | |||
754 | struct super_block *sb, | 728 | struct super_block *sb, |
755 | int type) | 729 | int type) |
756 | { | 730 | { |
757 | struct vfs *vfsp = vfs_from_sb(sb); | 731 | return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL); |
758 | int error; | ||
759 | |||
760 | VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error); | ||
761 | return -error; | ||
762 | } | 732 | } |
763 | 733 | ||
764 | STATIC int | 734 | STATIC int |
@@ -766,11 +736,7 @@ xfs_fs_getxstate( | |||
766 | struct super_block *sb, | 736 | struct super_block *sb, |
767 | struct fs_quota_stat *fqs) | 737 | struct fs_quota_stat *fqs) |
768 | { | 738 | { |
769 | struct vfs *vfsp = vfs_from_sb(sb); | 739 | return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs); |
770 | int error; | ||
771 | |||
772 | VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error); | ||
773 | return -error; | ||
774 | } | 740 | } |
775 | 741 | ||
776 | STATIC int | 742 | STATIC int |
@@ -779,11 +745,7 @@ xfs_fs_setxstate( | |||
779 | unsigned int flags, | 745 | unsigned int flags, |
780 | int op) | 746 | int op) |
781 | { | 747 | { |
782 | struct vfs *vfsp = vfs_from_sb(sb); | 748 | return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags); |
783 | int error; | ||
784 | |||
785 | VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error); | ||
786 | return -error; | ||
787 | } | 749 | } |
788 | 750 | ||
789 | STATIC int | 751 | STATIC int |
@@ -793,13 +755,10 @@ xfs_fs_getxquota( | |||
793 | qid_t id, | 755 | qid_t id, |
794 | struct fs_disk_quota *fdq) | 756 | struct fs_disk_quota *fdq) |
795 | { | 757 | { |
796 | struct vfs *vfsp = vfs_from_sb(sb); | 758 | return -bhv_vfs_quotactl(vfs_from_sb(sb), |
797 | int error, getmode; | 759 | (type == USRQUOTA) ? Q_XGETQUOTA : |
798 | 760 | ((type == GRPQUOTA) ? Q_XGETGQUOTA : | |
799 | getmode = (type == USRQUOTA) ? Q_XGETQUOTA : | 761 | Q_XGETPQUOTA), id, (caddr_t)fdq); |
800 | ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA); | ||
801 | VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error); | ||
802 | return -error; | ||
803 | } | 762 | } |
804 | 763 | ||
805 | STATIC int | 764 | STATIC int |
@@ -809,13 +768,10 @@ xfs_fs_setxquota( | |||
809 | qid_t id, | 768 | qid_t id, |
810 | struct fs_disk_quota *fdq) | 769 | struct fs_disk_quota *fdq) |
811 | { | 770 | { |
812 | struct vfs *vfsp = vfs_from_sb(sb); | 771 | return -bhv_vfs_quotactl(vfs_from_sb(sb), |
813 | int error, setmode; | 772 | (type == USRQUOTA) ? Q_XSETQLIM : |
814 | 773 | ((type == GRPQUOTA) ? Q_XSETGQLIM : | |
815 | setmode = (type == USRQUOTA) ? Q_XSETQLIM : | 774 | Q_XSETPQLIM), id, (caddr_t)fdq); |
816 | ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM); | ||
817 | VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error); | ||
818 | return -error; | ||
819 | } | 775 | } |
820 | 776 | ||
821 | STATIC int | 777 | STATIC int |
@@ -824,34 +780,32 @@ xfs_fs_fill_super( | |||
824 | void *data, | 780 | void *data, |
825 | int silent) | 781 | int silent) |
826 | { | 782 | { |
827 | vnode_t *rootvp; | 783 | struct bhv_vnode *rootvp; |
828 | struct vfs *vfsp = vfs_allocate(sb); | 784 | struct bhv_vfs *vfsp = vfs_allocate(sb); |
829 | struct xfs_mount_args *args = xfs_args_allocate(sb, silent); | 785 | struct xfs_mount_args *args = xfs_args_allocate(sb, silent); |
830 | struct kstatfs statvfs; | 786 | struct kstatfs statvfs; |
831 | int error, error2; | 787 | int error; |
832 | 788 | ||
833 | bhv_insert_all_vfsops(vfsp); | 789 | bhv_insert_all_vfsops(vfsp); |
834 | 790 | ||
835 | VFS_PARSEARGS(vfsp, (char *)data, args, 0, error); | 791 | error = bhv_vfs_parseargs(vfsp, (char *)data, args, 0); |
836 | if (error) { | 792 | if (error) { |
837 | bhv_remove_all_vfsops(vfsp, 1); | 793 | bhv_remove_all_vfsops(vfsp, 1); |
838 | goto fail_vfsop; | 794 | goto fail_vfsop; |
839 | } | 795 | } |
840 | 796 | ||
841 | sb_min_blocksize(sb, BBSIZE); | 797 | sb_min_blocksize(sb, BBSIZE); |
842 | #ifdef CONFIG_XFS_EXPORT | ||
843 | sb->s_export_op = &xfs_export_operations; | 798 | sb->s_export_op = &xfs_export_operations; |
844 | #endif | ||
845 | sb->s_qcop = &xfs_quotactl_operations; | 799 | sb->s_qcop = &xfs_quotactl_operations; |
846 | sb->s_op = &xfs_super_operations; | 800 | sb->s_op = &xfs_super_operations; |
847 | 801 | ||
848 | VFS_MOUNT(vfsp, args, NULL, error); | 802 | error = bhv_vfs_mount(vfsp, args, NULL); |
849 | if (error) { | 803 | if (error) { |
850 | bhv_remove_all_vfsops(vfsp, 1); | 804 | bhv_remove_all_vfsops(vfsp, 1); |
851 | goto fail_vfsop; | 805 | goto fail_vfsop; |
852 | } | 806 | } |
853 | 807 | ||
854 | VFS_STATVFS(vfsp, &statvfs, NULL, error); | 808 | error = bhv_vfs_statvfs(vfsp, &statvfs, NULL); |
855 | if (error) | 809 | if (error) |
856 | goto fail_unmount; | 810 | goto fail_unmount; |
857 | 811 | ||
@@ -863,7 +817,7 @@ xfs_fs_fill_super( | |||
863 | sb->s_time_gran = 1; | 817 | sb->s_time_gran = 1; |
864 | set_posix_acl_flag(sb); | 818 | set_posix_acl_flag(sb); |
865 | 819 | ||
866 | VFS_ROOT(vfsp, &rootvp, error); | 820 | error = bhv_vfs_root(vfsp, &rootvp); |
867 | if (error) | 821 | if (error) |
868 | goto fail_unmount; | 822 | goto fail_unmount; |
869 | 823 | ||
@@ -892,7 +846,7 @@ fail_vnrele: | |||
892 | } | 846 | } |
893 | 847 | ||
894 | fail_unmount: | 848 | fail_unmount: |
895 | VFS_UNMOUNT(vfsp, 0, NULL, error2); | 849 | bhv_vfs_unmount(vfsp, 0, NULL); |
896 | 850 | ||
897 | fail_vfsop: | 851 | fail_vfsop: |
898 | vfs_deallocate(vfsp); | 852 | vfs_deallocate(vfsp); |
@@ -900,14 +854,16 @@ fail_vfsop: | |||
900 | return -error; | 854 | return -error; |
901 | } | 855 | } |
902 | 856 | ||
903 | STATIC struct super_block * | 857 | STATIC int |
904 | xfs_fs_get_sb( | 858 | xfs_fs_get_sb( |
905 | struct file_system_type *fs_type, | 859 | struct file_system_type *fs_type, |
906 | int flags, | 860 | int flags, |
907 | const char *dev_name, | 861 | const char *dev_name, |
908 | void *data) | 862 | void *data, |
863 | struct vfsmount *mnt) | ||
909 | { | 864 | { |
910 | return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); | 865 | return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super, |
866 | mnt); | ||
911 | } | 867 | } |
912 | 868 | ||
913 | STATIC struct super_operations xfs_super_operations = { | 869 | STATIC struct super_operations xfs_super_operations = { |
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h index 376b96cb513a..33dd1ca13245 100644 --- a/fs/xfs/linux-2.6/xfs_super.h +++ b/fs/xfs/linux-2.6/xfs_super.h | |||
@@ -105,7 +105,7 @@ struct block_device; | |||
105 | 105 | ||
106 | extern __uint64_t xfs_max_file_offset(unsigned int); | 106 | extern __uint64_t xfs_max_file_offset(unsigned int); |
107 | 107 | ||
108 | extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int); | 108 | extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int); |
109 | 109 | ||
110 | extern void xfs_flush_inode(struct xfs_inode *); | 110 | extern void xfs_flush_inode(struct xfs_inode *); |
111 | extern void xfs_flush_device(struct xfs_inode *); | 111 | extern void xfs_flush_device(struct xfs_inode *); |
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c index 7079cc837210..af246532fbfb 100644 --- a/fs/xfs/linux-2.6/xfs_sysctl.c +++ b/fs/xfs/linux-2.6/xfs_sysctl.c | |||
@@ -38,7 +38,7 @@ xfs_stats_clear_proc_handler( | |||
38 | 38 | ||
39 | if (!ret && write && *valp) { | 39 | if (!ret && write && *valp) { |
40 | printk("XFS Clearing xfsstats\n"); | 40 | printk("XFS Clearing xfsstats\n"); |
41 | for_each_cpu(c) { | 41 | for_each_possible_cpu(c) { |
42 | preempt_disable(); | 42 | preempt_disable(); |
43 | /* save vn_active, it's a universal truth! */ | 43 | /* save vn_active, it's a universal truth! */ |
44 | vn_active = per_cpu(xfsstats, c).vn_active; | 44 | vn_active = per_cpu(xfsstats, c).vn_active; |
@@ -120,6 +120,11 @@ STATIC ctl_table xfs_table[] = { | |||
120 | &sysctl_intvec, NULL, | 120 | &sysctl_intvec, NULL, |
121 | &xfs_params.rotorstep.min, &xfs_params.rotorstep.max}, | 121 | &xfs_params.rotorstep.min, &xfs_params.rotorstep.max}, |
122 | 122 | ||
123 | {XFS_INHERIT_NODFRG, "inherit_nodefrag", &xfs_params.inherit_nodfrg.val, | ||
124 | sizeof(int), 0644, NULL, &proc_dointvec_minmax, | ||
125 | &sysctl_intvec, NULL, | ||
126 | &xfs_params.inherit_nodfrg.min, &xfs_params.inherit_nodfrg.max}, | ||
127 | |||
123 | /* please keep this the last entry */ | 128 | /* please keep this the last entry */ |
124 | #ifdef CONFIG_PROC_FS | 129 | #ifdef CONFIG_PROC_FS |
125 | {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val, | 130 | {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val, |
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.h b/fs/xfs/linux-2.6/xfs_sysctl.h index bc8c11f13722..a631fb8cc5ac 100644 --- a/fs/xfs/linux-2.6/xfs_sysctl.h +++ b/fs/xfs/linux-2.6/xfs_sysctl.h | |||
@@ -46,6 +46,7 @@ typedef struct xfs_param { | |||
46 | xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */ | 46 | xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */ |
47 | xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */ | 47 | xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */ |
48 | xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ | 48 | xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ |
49 | xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */ | ||
49 | } xfs_param_t; | 50 | } xfs_param_t; |
50 | 51 | ||
51 | /* | 52 | /* |
@@ -84,6 +85,7 @@ enum { | |||
84 | /* XFS_IO_BYPASS = 18 */ | 85 | /* XFS_IO_BYPASS = 18 */ |
85 | XFS_INHERIT_NOSYM = 19, | 86 | XFS_INHERIT_NOSYM = 19, |
86 | XFS_ROTORSTEP = 20, | 87 | XFS_ROTORSTEP = 20, |
88 | XFS_INHERIT_NODFRG = 21, | ||
87 | }; | 89 | }; |
88 | 90 | ||
89 | extern xfs_param_t xfs_params; | 91 | extern xfs_param_t xfs_params; |
diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c index 6f7c9f7a8624..6145e8bd0be2 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.c +++ b/fs/xfs/linux-2.6/xfs_vfs.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_imap.h" | 27 | #include "xfs_imap.h" |
29 | #include "xfs_alloc.h" | 28 | #include "xfs_alloc.h" |
@@ -104,7 +103,7 @@ vfs_mntupdate( | |||
104 | int | 103 | int |
105 | vfs_root( | 104 | vfs_root( |
106 | struct bhv_desc *bdp, | 105 | struct bhv_desc *bdp, |
107 | struct vnode **vpp) | 106 | struct bhv_vnode **vpp) |
108 | { | 107 | { |
109 | struct bhv_desc *next = bdp; | 108 | struct bhv_desc *next = bdp; |
110 | 109 | ||
@@ -117,15 +116,15 @@ vfs_root( | |||
117 | int | 116 | int |
118 | vfs_statvfs( | 117 | vfs_statvfs( |
119 | struct bhv_desc *bdp, | 118 | struct bhv_desc *bdp, |
120 | xfs_statfs_t *sp, | 119 | bhv_statvfs_t *statp, |
121 | struct vnode *vp) | 120 | struct bhv_vnode *vp) |
122 | { | 121 | { |
123 | struct bhv_desc *next = bdp; | 122 | struct bhv_desc *next = bdp; |
124 | 123 | ||
125 | ASSERT(next); | 124 | ASSERT(next); |
126 | while (! (bhvtovfsops(next))->vfs_statvfs) | 125 | while (! (bhvtovfsops(next))->vfs_statvfs) |
127 | next = BHV_NEXT(next); | 126 | next = BHV_NEXT(next); |
128 | return ((*bhvtovfsops(next)->vfs_statvfs)(next, sp, vp)); | 127 | return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp)); |
129 | } | 128 | } |
130 | 129 | ||
131 | int | 130 | int |
@@ -145,7 +144,7 @@ vfs_sync( | |||
145 | int | 144 | int |
146 | vfs_vget( | 145 | vfs_vget( |
147 | struct bhv_desc *bdp, | 146 | struct bhv_desc *bdp, |
148 | struct vnode **vpp, | 147 | struct bhv_vnode **vpp, |
149 | struct fid *fidp) | 148 | struct fid *fidp) |
150 | { | 149 | { |
151 | struct bhv_desc *next = bdp; | 150 | struct bhv_desc *next = bdp; |
@@ -187,7 +186,7 @@ vfs_quotactl( | |||
187 | void | 186 | void |
188 | vfs_init_vnode( | 187 | vfs_init_vnode( |
189 | struct bhv_desc *bdp, | 188 | struct bhv_desc *bdp, |
190 | struct vnode *vp, | 189 | struct bhv_vnode *vp, |
191 | struct bhv_desc *bp, | 190 | struct bhv_desc *bp, |
192 | int unlock) | 191 | int unlock) |
193 | { | 192 | { |
@@ -226,13 +225,13 @@ vfs_freeze( | |||
226 | ((*bhvtovfsops(next)->vfs_freeze)(next)); | 225 | ((*bhvtovfsops(next)->vfs_freeze)(next)); |
227 | } | 226 | } |
228 | 227 | ||
229 | vfs_t * | 228 | bhv_vfs_t * |
230 | vfs_allocate( | 229 | vfs_allocate( |
231 | struct super_block *sb) | 230 | struct super_block *sb) |
232 | { | 231 | { |
233 | struct vfs *vfsp; | 232 | struct bhv_vfs *vfsp; |
234 | 233 | ||
235 | vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP); | 234 | vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP); |
236 | bhv_head_init(VFS_BHVHEAD(vfsp), "vfs"); | 235 | bhv_head_init(VFS_BHVHEAD(vfsp), "vfs"); |
237 | INIT_LIST_HEAD(&vfsp->vfs_sync_list); | 236 | INIT_LIST_HEAD(&vfsp->vfs_sync_list); |
238 | spin_lock_init(&vfsp->vfs_sync_lock); | 237 | spin_lock_init(&vfsp->vfs_sync_lock); |
@@ -247,25 +246,25 @@ vfs_allocate( | |||
247 | return vfsp; | 246 | return vfsp; |
248 | } | 247 | } |
249 | 248 | ||
250 | vfs_t * | 249 | bhv_vfs_t * |
251 | vfs_from_sb( | 250 | vfs_from_sb( |
252 | struct super_block *sb) | 251 | struct super_block *sb) |
253 | { | 252 | { |
254 | return (vfs_t *)sb->s_fs_info; | 253 | return (bhv_vfs_t *)sb->s_fs_info; |
255 | } | 254 | } |
256 | 255 | ||
257 | void | 256 | void |
258 | vfs_deallocate( | 257 | vfs_deallocate( |
259 | struct vfs *vfsp) | 258 | struct bhv_vfs *vfsp) |
260 | { | 259 | { |
261 | bhv_head_destroy(VFS_BHVHEAD(vfsp)); | 260 | bhv_head_destroy(VFS_BHVHEAD(vfsp)); |
262 | kmem_free(vfsp, sizeof(vfs_t)); | 261 | kmem_free(vfsp, sizeof(bhv_vfs_t)); |
263 | } | 262 | } |
264 | 263 | ||
265 | void | 264 | void |
266 | vfs_insertops( | 265 | vfs_insertops( |
267 | struct vfs *vfsp, | 266 | struct bhv_vfs *vfsp, |
268 | struct bhv_vfsops *vfsops) | 267 | struct bhv_module_vfsops *vfsops) |
269 | { | 268 | { |
270 | struct bhv_desc *bdp; | 269 | struct bhv_desc *bdp; |
271 | 270 | ||
@@ -276,9 +275,9 @@ vfs_insertops( | |||
276 | 275 | ||
277 | void | 276 | void |
278 | vfs_insertbhv( | 277 | vfs_insertbhv( |
279 | struct vfs *vfsp, | 278 | struct bhv_vfs *vfsp, |
280 | struct bhv_desc *bdp, | 279 | struct bhv_desc *bdp, |
281 | struct vfsops *vfsops, | 280 | struct bhv_vfsops *vfsops, |
282 | void *mount) | 281 | void *mount) |
283 | { | 282 | { |
284 | bhv_desc_init(bdp, mount, vfsp, vfsops); | 283 | bhv_desc_init(bdp, mount, vfsp, vfsops); |
@@ -287,7 +286,7 @@ vfs_insertbhv( | |||
287 | 286 | ||
288 | void | 287 | void |
289 | bhv_remove_vfsops( | 288 | bhv_remove_vfsops( |
290 | struct vfs *vfsp, | 289 | struct bhv_vfs *vfsp, |
291 | int pos) | 290 | int pos) |
292 | { | 291 | { |
293 | struct bhv_desc *bhv; | 292 | struct bhv_desc *bhv; |
@@ -301,7 +300,7 @@ bhv_remove_vfsops( | |||
301 | 300 | ||
302 | void | 301 | void |
303 | bhv_remove_all_vfsops( | 302 | bhv_remove_all_vfsops( |
304 | struct vfs *vfsp, | 303 | struct bhv_vfs *vfsp, |
305 | int freebase) | 304 | int freebase) |
306 | { | 305 | { |
307 | struct xfs_mount *mp; | 306 | struct xfs_mount *mp; |
@@ -317,7 +316,7 @@ bhv_remove_all_vfsops( | |||
317 | 316 | ||
318 | void | 317 | void |
319 | bhv_insert_all_vfsops( | 318 | bhv_insert_all_vfsops( |
320 | struct vfs *vfsp) | 319 | struct bhv_vfs *vfsp) |
321 | { | 320 | { |
322 | struct xfs_mount *mp; | 321 | struct xfs_mount *mp; |
323 | 322 | ||
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h index 841200c03092..91fc2c4b3353 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.h +++ b/fs/xfs/linux-2.6/xfs_vfs.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -21,42 +21,40 @@ | |||
21 | #include <linux/vfs.h> | 21 | #include <linux/vfs.h> |
22 | #include "xfs_fs.h" | 22 | #include "xfs_fs.h" |
23 | 23 | ||
24 | struct bhv_vfs; | ||
25 | struct bhv_vnode; | ||
26 | |||
24 | struct fid; | 27 | struct fid; |
25 | struct vfs; | ||
26 | struct cred; | 28 | struct cred; |
27 | struct vnode; | ||
28 | struct kstatfs; | ||
29 | struct seq_file; | 29 | struct seq_file; |
30 | struct super_block; | 30 | struct super_block; |
31 | struct xfs_mount_args; | 31 | struct xfs_mount_args; |
32 | 32 | ||
33 | typedef struct kstatfs xfs_statfs_t; | 33 | typedef struct kstatfs bhv_statvfs_t; |
34 | 34 | ||
35 | typedef struct vfs_sync_work { | 35 | typedef struct bhv_vfs_sync_work { |
36 | struct list_head w_list; | 36 | struct list_head w_list; |
37 | struct vfs *w_vfs; | 37 | struct bhv_vfs *w_vfs; |
38 | void *w_data; /* syncer routine argument */ | 38 | void *w_data; /* syncer routine argument */ |
39 | void (*w_syncer)(struct vfs *, void *); | 39 | void (*w_syncer)(struct bhv_vfs *, void *); |
40 | } vfs_sync_work_t; | 40 | } bhv_vfs_sync_work_t; |
41 | 41 | ||
42 | typedef struct vfs { | 42 | typedef struct bhv_vfs { |
43 | u_int vfs_flag; /* flags */ | 43 | u_int vfs_flag; /* flags */ |
44 | xfs_fsid_t vfs_fsid; /* file system ID */ | 44 | xfs_fsid_t vfs_fsid; /* file system ID */ |
45 | xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */ | 45 | xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */ |
46 | bhv_head_t vfs_bh; /* head of vfs behavior chain */ | 46 | bhv_head_t vfs_bh; /* head of vfs behavior chain */ |
47 | struct super_block *vfs_super; /* generic superblock pointer */ | 47 | struct super_block *vfs_super; /* generic superblock pointer */ |
48 | struct task_struct *vfs_sync_task; /* generalised sync thread */ | 48 | struct task_struct *vfs_sync_task; /* generalised sync thread */ |
49 | vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */ | 49 | bhv_vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */ |
50 | struct list_head vfs_sync_list; /* sync thread work item list */ | 50 | struct list_head vfs_sync_list; /* sync thread work item list */ |
51 | spinlock_t vfs_sync_lock; /* work item list lock */ | 51 | spinlock_t vfs_sync_lock; /* work item list lock */ |
52 | int vfs_sync_seq; /* sync thread generation no. */ | 52 | int vfs_sync_seq; /* sync thread generation no. */ |
53 | wait_queue_head_t vfs_wait_single_sync_task; | 53 | wait_queue_head_t vfs_wait_single_sync_task; |
54 | } vfs_t; | 54 | } bhv_vfs_t; |
55 | |||
56 | #define vfs_fbhv vfs_bh.bh_first /* 1st on vfs behavior chain */ | ||
57 | 55 | ||
58 | #define bhvtovfs(bdp) ( (struct vfs *)BHV_VOBJ(bdp) ) | 56 | #define bhvtovfs(bdp) ( (struct bhv_vfs *)BHV_VOBJ(bdp) ) |
59 | #define bhvtovfsops(bdp) ( (struct vfsops *)BHV_OPS(bdp) ) | 57 | #define bhvtovfsops(bdp) ( (struct bhv_vfsops *)BHV_OPS(bdp) ) |
60 | #define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh ) | 58 | #define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh ) |
61 | #define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) ) | 59 | #define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) ) |
62 | 60 | ||
@@ -71,7 +69,7 @@ typedef enum { | |||
71 | VFS_BHV_QM, /* quota manager */ | 69 | VFS_BHV_QM, /* quota manager */ |
72 | VFS_BHV_IO, /* IO path */ | 70 | VFS_BHV_IO, /* IO path */ |
73 | VFS_BHV_END /* housekeeping end-of-range */ | 71 | VFS_BHV_END /* housekeeping end-of-range */ |
74 | } vfs_bhv_t; | 72 | } bhv_vfs_type_t; |
75 | 73 | ||
76 | #define VFS_POSITION_XFS (BHV_POSITION_BASE) | 74 | #define VFS_POSITION_XFS (BHV_POSITION_BASE) |
77 | #define VFS_POSITION_DM (VFS_POSITION_BASE+10) | 75 | #define VFS_POSITION_DM (VFS_POSITION_BASE+10) |
@@ -81,8 +79,9 @@ typedef enum { | |||
81 | #define VFS_RDONLY 0x0001 /* read-only vfs */ | 79 | #define VFS_RDONLY 0x0001 /* read-only vfs */ |
82 | #define VFS_GRPID 0x0002 /* group-ID assigned from directory */ | 80 | #define VFS_GRPID 0x0002 /* group-ID assigned from directory */ |
83 | #define VFS_DMI 0x0004 /* filesystem has the DMI enabled */ | 81 | #define VFS_DMI 0x0004 /* filesystem has the DMI enabled */ |
84 | #define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */ | 82 | #define VFS_UMOUNT 0x0008 /* unmount in progress */ |
85 | #define VFS_END 0x0008 /* max flag */ | 83 | #define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */ |
84 | #define VFS_END 0x0010 /* max flag */ | ||
86 | 85 | ||
87 | #define SYNC_ATTR 0x0001 /* sync attributes */ | 86 | #define SYNC_ATTR 0x0001 /* sync attributes */ |
88 | #define SYNC_CLOSE 0x0002 /* close file system down */ | 87 | #define SYNC_CLOSE 0x0002 /* close file system down */ |
@@ -92,7 +91,14 @@ typedef enum { | |||
92 | #define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ | 91 | #define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ |
93 | #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ | 92 | #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ |
94 | #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ | 93 | #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ |
95 | #define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */ | 94 | #define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */ |
95 | |||
96 | #define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */ | ||
97 | #define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */ | ||
98 | #define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */ | ||
99 | #define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */ | ||
100 | #define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */ | ||
101 | #define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */ | ||
96 | 102 | ||
97 | typedef int (*vfs_mount_t)(bhv_desc_t *, | 103 | typedef int (*vfs_mount_t)(bhv_desc_t *, |
98 | struct xfs_mount_args *, struct cred *); | 104 | struct xfs_mount_args *, struct cred *); |
@@ -102,18 +108,19 @@ typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *); | |||
102 | typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *); | 108 | typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *); |
103 | typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *, | 109 | typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *, |
104 | struct xfs_mount_args *); | 110 | struct xfs_mount_args *); |
105 | typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **); | 111 | typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **); |
106 | typedef int (*vfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct vnode *); | 112 | typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *, |
113 | struct bhv_vnode *); | ||
107 | typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); | 114 | typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); |
108 | typedef int (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *); | 115 | typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *); |
109 | typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t); | 116 | typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t); |
110 | typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); | 117 | typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); |
111 | typedef void (*vfs_init_vnode_t)(bhv_desc_t *, | 118 | typedef void (*vfs_init_vnode_t)(bhv_desc_t *, |
112 | struct vnode *, bhv_desc_t *, int); | 119 | struct bhv_vnode *, bhv_desc_t *, int); |
113 | typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); | 120 | typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); |
114 | typedef void (*vfs_freeze_t)(bhv_desc_t *); | 121 | typedef void (*vfs_freeze_t)(bhv_desc_t *); |
115 | 122 | ||
116 | typedef struct vfsops { | 123 | typedef struct bhv_vfsops { |
117 | bhv_position_t vf_position; /* behavior chain position */ | 124 | bhv_position_t vf_position; /* behavior chain position */ |
118 | vfs_mount_t vfs_mount; /* mount file system */ | 125 | vfs_mount_t vfs_mount; /* mount file system */ |
119 | vfs_parseargs_t vfs_parseargs; /* parse mount options */ | 126 | vfs_parseargs_t vfs_parseargs; /* parse mount options */ |
@@ -129,82 +136,82 @@ typedef struct vfsops { | |||
129 | vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */ | 136 | vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */ |
130 | vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */ | 137 | vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */ |
131 | vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */ | 138 | vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */ |
132 | } vfsops_t; | 139 | } bhv_vfsops_t; |
133 | 140 | ||
134 | /* | 141 | /* |
135 | * VFS's. Operates on vfs structure pointers (starts at bhv head). | 142 | * Virtual filesystem operations, operating from head bhv. |
136 | */ | 143 | */ |
137 | #define VHEAD(v) ((v)->vfs_fbhv) | 144 | #define VFSHEAD(v) ((v)->vfs_bh.bh_first) |
138 | #define VFS_MOUNT(v, ma,cr, rv) ((rv) = vfs_mount(VHEAD(v), ma,cr)) | 145 | #define bhv_vfs_mount(v, ma,cr) vfs_mount(VFSHEAD(v), ma,cr) |
139 | #define VFS_PARSEARGS(v, o,ma,f, rv) ((rv) = vfs_parseargs(VHEAD(v), o,ma,f)) | 146 | #define bhv_vfs_parseargs(v, o,ma,f) vfs_parseargs(VFSHEAD(v), o,ma,f) |
140 | #define VFS_SHOWARGS(v, m, rv) ((rv) = vfs_showargs(VHEAD(v), m)) | 147 | #define bhv_vfs_showargs(v, m) vfs_showargs(VFSHEAD(v), m) |
141 | #define VFS_UNMOUNT(v, f, cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr)) | 148 | #define bhv_vfs_unmount(v, f,cr) vfs_unmount(VFSHEAD(v), f,cr) |
142 | #define VFS_MNTUPDATE(v, fl, args, rv) ((rv) = vfs_mntupdate(VHEAD(v), fl, args)) | 149 | #define bhv_vfs_mntupdate(v, fl,args) vfs_mntupdate(VFSHEAD(v), fl,args) |
143 | #define VFS_ROOT(v, vpp, rv) ((rv) = vfs_root(VHEAD(v), vpp)) | 150 | #define bhv_vfs_root(v, vpp) vfs_root(VFSHEAD(v), vpp) |
144 | #define VFS_STATVFS(v, sp,vp, rv) ((rv) = vfs_statvfs(VHEAD(v), sp,vp)) | 151 | #define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp) |
145 | #define VFS_SYNC(v, flag,cr, rv) ((rv) = vfs_sync(VHEAD(v), flag,cr)) | 152 | #define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr) |
146 | #define VFS_VGET(v, vpp,fidp, rv) ((rv) = vfs_vget(VHEAD(v), vpp,fidp)) | 153 | #define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp) |
147 | #define VFS_DMAPIOPS(v, p, rv) ((rv) = vfs_dmapiops(VHEAD(v), p)) | 154 | #define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p) |
148 | #define VFS_QUOTACTL(v, c,id,p, rv) ((rv) = vfs_quotactl(VHEAD(v), c,id,p)) | 155 | #define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p) |
149 | #define VFS_INIT_VNODE(v, vp,b,ul) ( vfs_init_vnode(VHEAD(v), vp,b,ul) ) | 156 | #define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul) |
150 | #define VFS_FORCE_SHUTDOWN(v, fl,f,l) ( vfs_force_shutdown(VHEAD(v), fl,f,l) ) | 157 | #define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l) |
151 | #define VFS_FREEZE(v) ( vfs_freeze(VHEAD(v)) ) | 158 | #define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v)) |
152 | 159 | ||
153 | /* | 160 | /* |
154 | * PVFS's. Operates on behavior descriptor pointers. | 161 | * Virtual filesystem operations, operating from next bhv. |
155 | */ | 162 | */ |
156 | #define PVFS_MOUNT(b, ma,cr, rv) ((rv) = vfs_mount(b, ma,cr)) | 163 | #define bhv_next_vfs_mount(b, ma,cr) vfs_mount(b, ma,cr) |
157 | #define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = vfs_parseargs(b, o,ma,f)) | 164 | #define bhv_next_vfs_parseargs(b, o,ma,f) vfs_parseargs(b, o,ma,f) |
158 | #define PVFS_SHOWARGS(b, m, rv) ((rv) = vfs_showargs(b, m)) | 165 | #define bhv_next_vfs_showargs(b, m) vfs_showargs(b, m) |
159 | #define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = vfs_unmount(b, f,cr)) | 166 | #define bhv_next_vfs_unmount(b, f,cr) vfs_unmount(b, f,cr) |
160 | #define PVFS_MNTUPDATE(b, fl, args, rv) ((rv) = vfs_mntupdate(b, fl, args)) | 167 | #define bhv_next_vfs_mntupdate(b, fl,args) vfs_mntupdate(b, fl, args) |
161 | #define PVFS_ROOT(b, vpp, rv) ((rv) = vfs_root(b, vpp)) | 168 | #define bhv_next_vfs_root(b, vpp) vfs_root(b, vpp) |
162 | #define PVFS_STATVFS(b, sp,vp, rv) ((rv) = vfs_statvfs(b, sp,vp)) | 169 | #define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp) |
163 | #define PVFS_SYNC(b, flag,cr, rv) ((rv) = vfs_sync(b, flag,cr)) | 170 | #define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr) |
164 | #define PVFS_VGET(b, vpp,fidp, rv) ((rv) = vfs_vget(b, vpp,fidp)) | 171 | #define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp) |
165 | #define PVFS_DMAPIOPS(b, p, rv) ((rv) = vfs_dmapiops(b, p)) | 172 | #define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p) |
166 | #define PVFS_QUOTACTL(b, c,id,p, rv) ((rv) = vfs_quotactl(b, c,id,p)) | 173 | #define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p) |
167 | #define PVFS_INIT_VNODE(b, vp,b2,ul) ( vfs_init_vnode(b, vp,b2,ul) ) | 174 | #define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul) |
168 | #define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( vfs_force_shutdown(b, fl,f,l) ) | 175 | #define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l) |
169 | #define PVFS_FREEZE(b) ( vfs_freeze(b) ) | 176 | #define bhv_next_vfs_freeze(b) vfs_freeze(b) |
170 | 177 | ||
171 | extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *); | 178 | extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *); |
172 | extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int); | 179 | extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int); |
173 | extern int vfs_showargs(bhv_desc_t *, struct seq_file *); | 180 | extern int vfs_showargs(bhv_desc_t *, struct seq_file *); |
174 | extern int vfs_unmount(bhv_desc_t *, int, struct cred *); | 181 | extern int vfs_unmount(bhv_desc_t *, int, struct cred *); |
175 | extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *); | 182 | extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *); |
176 | extern int vfs_root(bhv_desc_t *, struct vnode **); | 183 | extern int vfs_root(bhv_desc_t *, struct bhv_vnode **); |
177 | extern int vfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct vnode *); | 184 | extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *); |
178 | extern int vfs_sync(bhv_desc_t *, int, struct cred *); | 185 | extern int vfs_sync(bhv_desc_t *, int, struct cred *); |
179 | extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *); | 186 | extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *); |
180 | extern int vfs_dmapiops(bhv_desc_t *, caddr_t); | 187 | extern int vfs_dmapiops(bhv_desc_t *, caddr_t); |
181 | extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); | 188 | extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); |
182 | extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int); | 189 | extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int); |
183 | extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); | 190 | extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); |
184 | extern void vfs_freeze(bhv_desc_t *); | 191 | extern void vfs_freeze(bhv_desc_t *); |
185 | 192 | ||
186 | typedef struct bhv_vfsops { | 193 | #define vfs_test_for_freeze(vfs) ((vfs)->vfs_super->s_frozen) |
187 | struct vfsops bhv_common; | 194 | #define vfs_wait_for_freeze(vfs,l) vfs_check_frozen((vfs)->vfs_super, (l)) |
195 | |||
196 | typedef struct bhv_module_vfsops { | ||
197 | struct bhv_vfsops bhv_common; | ||
188 | void * bhv_custom; | 198 | void * bhv_custom; |
189 | } bhv_vfsops_t; | 199 | } bhv_module_vfsops_t; |
190 | 200 | ||
191 | #define vfs_bhv_lookup(v, id) ( bhv_lookup_range(&(v)->vfs_bh, (id), (id)) ) | 201 | #define vfs_bhv_lookup(v, id) (bhv_lookup_range(&(v)->vfs_bh, (id), (id))) |
192 | #define vfs_bhv_custom(b) ( ((bhv_vfsops_t *)BHV_OPS(b))->bhv_custom ) | 202 | #define vfs_bhv_custom(b) (((bhv_module_vfsops_t*)BHV_OPS(b))->bhv_custom) |
193 | #define vfs_bhv_set_custom(b,o) ( (b)->bhv_custom = (void *)(o)) | 203 | #define vfs_bhv_set_custom(b,o) ((b)->bhv_custom = (void *)(o)) |
194 | #define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL ) | 204 | #define vfs_bhv_clr_custom(b) ((b)->bhv_custom = NULL) |
195 | 205 | ||
196 | extern vfs_t *vfs_allocate(struct super_block *); | 206 | extern bhv_vfs_t *vfs_allocate(struct super_block *); |
197 | extern vfs_t *vfs_from_sb(struct super_block *); | 207 | extern bhv_vfs_t *vfs_from_sb(struct super_block *); |
198 | extern void vfs_deallocate(vfs_t *); | 208 | extern void vfs_deallocate(bhv_vfs_t *); |
199 | extern void vfs_insertops(vfs_t *, bhv_vfsops_t *); | 209 | extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *); |
200 | extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *); | ||
201 | 210 | ||
202 | extern void bhv_insert_all_vfsops(struct vfs *); | 211 | extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *); |
203 | extern void bhv_remove_all_vfsops(struct vfs *, int); | ||
204 | extern void bhv_remove_vfsops(struct vfs *, int); | ||
205 | 212 | ||
206 | #define fs_frozen(vfsp) ((vfsp)->vfs_super->s_frozen) | 213 | extern void bhv_insert_all_vfsops(struct bhv_vfs *); |
207 | #define fs_check_frozen(vfsp, level) \ | 214 | extern void bhv_remove_all_vfsops(struct bhv_vfs *, int); |
208 | vfs_check_frozen(vfsp->vfs_super, level); | 215 | extern void bhv_remove_vfsops(struct bhv_vfs *, int); |
209 | 216 | ||
210 | #endif /* __XFS_VFS_H__ */ | 217 | #endif /* __XFS_VFS_H__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index d27c25b27ccd..6628d96b6fd6 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c | |||
@@ -39,7 +39,7 @@ vn_init(void) | |||
39 | 39 | ||
40 | void | 40 | void |
41 | vn_iowait( | 41 | vn_iowait( |
42 | struct vnode *vp) | 42 | bhv_vnode_t *vp) |
43 | { | 43 | { |
44 | wait_queue_head_t *wq = vptosync(vp); | 44 | wait_queue_head_t *wq = vptosync(vp); |
45 | 45 | ||
@@ -48,17 +48,33 @@ vn_iowait( | |||
48 | 48 | ||
49 | void | 49 | void |
50 | vn_iowake( | 50 | vn_iowake( |
51 | struct vnode *vp) | 51 | bhv_vnode_t *vp) |
52 | { | 52 | { |
53 | if (atomic_dec_and_test(&vp->v_iocount)) | 53 | if (atomic_dec_and_test(&vp->v_iocount)) |
54 | wake_up(vptosync(vp)); | 54 | wake_up(vptosync(vp)); |
55 | } | 55 | } |
56 | 56 | ||
57 | struct vnode * | 57 | /* |
58 | * Volume managers supporting multiple paths can send back ENODEV when the | ||
59 | * final path disappears. In this case continuing to fill the page cache | ||
60 | * with dirty data which cannot be written out is evil, so prevent that. | ||
61 | */ | ||
62 | void | ||
63 | vn_ioerror( | ||
64 | bhv_vnode_t *vp, | ||
65 | int error, | ||
66 | char *f, | ||
67 | int l) | ||
68 | { | ||
69 | if (unlikely(error == -ENODEV)) | ||
70 | bhv_vfs_force_shutdown(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l); | ||
71 | } | ||
72 | |||
73 | bhv_vnode_t * | ||
58 | vn_initialize( | 74 | vn_initialize( |
59 | struct inode *inode) | 75 | struct inode *inode) |
60 | { | 76 | { |
61 | struct vnode *vp = vn_from_inode(inode); | 77 | bhv_vnode_t *vp = vn_from_inode(inode); |
62 | 78 | ||
63 | XFS_STATS_INC(vn_active); | 79 | XFS_STATS_INC(vn_active); |
64 | XFS_STATS_INC(vn_alloc); | 80 | XFS_STATS_INC(vn_alloc); |
@@ -94,8 +110,8 @@ vn_initialize( | |||
94 | */ | 110 | */ |
95 | void | 111 | void |
96 | vn_revalidate_core( | 112 | vn_revalidate_core( |
97 | struct vnode *vp, | 113 | bhv_vnode_t *vp, |
98 | vattr_t *vap) | 114 | bhv_vattr_t *vap) |
99 | { | 115 | { |
100 | struct inode *inode = vn_to_inode(vp); | 116 | struct inode *inode = vn_to_inode(vp); |
101 | 117 | ||
@@ -130,14 +146,14 @@ vn_revalidate_core( | |||
130 | */ | 146 | */ |
131 | int | 147 | int |
132 | __vn_revalidate( | 148 | __vn_revalidate( |
133 | struct vnode *vp, | 149 | bhv_vnode_t *vp, |
134 | struct vattr *vattr) | 150 | bhv_vattr_t *vattr) |
135 | { | 151 | { |
136 | int error; | 152 | int error; |
137 | 153 | ||
138 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 154 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
139 | vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS; | 155 | vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS; |
140 | VOP_GETATTR(vp, vattr, 0, NULL, error); | 156 | error = bhv_vop_getattr(vp, vattr, 0, NULL); |
141 | if (likely(!error)) { | 157 | if (likely(!error)) { |
142 | vn_revalidate_core(vp, vattr); | 158 | vn_revalidate_core(vp, vattr); |
143 | VUNMODIFY(vp); | 159 | VUNMODIFY(vp); |
@@ -147,9 +163,9 @@ __vn_revalidate( | |||
147 | 163 | ||
148 | int | 164 | int |
149 | vn_revalidate( | 165 | vn_revalidate( |
150 | struct vnode *vp) | 166 | bhv_vnode_t *vp) |
151 | { | 167 | { |
152 | vattr_t vattr; | 168 | bhv_vattr_t vattr; |
153 | 169 | ||
154 | return __vn_revalidate(vp, &vattr); | 170 | return __vn_revalidate(vp, &vattr); |
155 | } | 171 | } |
@@ -157,9 +173,9 @@ vn_revalidate( | |||
157 | /* | 173 | /* |
158 | * Add a reference to a referenced vnode. | 174 | * Add a reference to a referenced vnode. |
159 | */ | 175 | */ |
160 | struct vnode * | 176 | bhv_vnode_t * |
161 | vn_hold( | 177 | vn_hold( |
162 | struct vnode *vp) | 178 | bhv_vnode_t *vp) |
163 | { | 179 | { |
164 | struct inode *inode; | 180 | struct inode *inode; |
165 | 181 | ||
@@ -192,31 +208,31 @@ vn_hold( | |||
192 | * Vnode tracing code. | 208 | * Vnode tracing code. |
193 | */ | 209 | */ |
194 | void | 210 | void |
195 | vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra) | 211 | vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra) |
196 | { | 212 | { |
197 | KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); | 213 | KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); |
198 | } | 214 | } |
199 | 215 | ||
200 | void | 216 | void |
201 | vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra) | 217 | vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra) |
202 | { | 218 | { |
203 | KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); | 219 | KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); |
204 | } | 220 | } |
205 | 221 | ||
206 | void | 222 | void |
207 | vn_trace_hold(vnode_t *vp, char *file, int line, inst_t *ra) | 223 | vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra) |
208 | { | 224 | { |
209 | KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra); | 225 | KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra); |
210 | } | 226 | } |
211 | 227 | ||
212 | void | 228 | void |
213 | vn_trace_ref(vnode_t *vp, char *file, int line, inst_t *ra) | 229 | vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra) |
214 | { | 230 | { |
215 | KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra); | 231 | KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra); |
216 | } | 232 | } |
217 | 233 | ||
218 | void | 234 | void |
219 | vn_trace_rele(vnode_t *vp, char *file, int line, inst_t *ra) | 235 | vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra) |
220 | { | 236 | { |
221 | KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra); | 237 | KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra); |
222 | } | 238 | } |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 2a8e16c22353..35c6a01963a7 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -14,57 +14,35 @@ | |||
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | * | ||
18 | * Portions Copyright (c) 1989, 1993 | ||
19 | * The Regents of the University of California. All rights reserved. | ||
20 | * | ||
21 | * Redistribution and use in source and binary forms, with or without | ||
22 | * modification, are permitted provided that the following conditions | ||
23 | * are met: | ||
24 | * 1. Redistributions of source code must retain the above copyright | ||
25 | * notice, this list of conditions and the following disclaimer. | ||
26 | * 2. Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in the | ||
28 | * documentation and/or other materials provided with the distribution. | ||
29 | * 3. Neither the name of the University nor the names of its contributors | ||
30 | * may be used to endorse or promote products derived from this software | ||
31 | * without specific prior written permission. | ||
32 | * | ||
33 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
34 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
35 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
36 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
37 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
38 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
39 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
40 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
41 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
42 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
43 | * SUCH DAMAGE. | ||
44 | */ | 17 | */ |
45 | #ifndef __XFS_VNODE_H__ | 18 | #ifndef __XFS_VNODE_H__ |
46 | #define __XFS_VNODE_H__ | 19 | #define __XFS_VNODE_H__ |
47 | 20 | ||
48 | struct uio; | 21 | struct uio; |
49 | struct file; | 22 | struct file; |
50 | struct vattr; | 23 | struct bhv_vfs; |
24 | struct bhv_vattr; | ||
51 | struct xfs_iomap; | 25 | struct xfs_iomap; |
52 | struct attrlist_cursor_kern; | 26 | struct attrlist_cursor_kern; |
53 | 27 | ||
28 | typedef struct dentry bhv_vname_t; | ||
29 | typedef __u64 bhv_vnumber_t; | ||
54 | 30 | ||
55 | typedef xfs_ino_t vnumber_t; | 31 | typedef enum bhv_vflags { |
56 | typedef struct dentry vname_t; | 32 | VMODIFIED = 0x08, /* XFS inode state possibly differs */ |
57 | typedef bhv_head_t vn_bhv_head_t; | 33 | /* to the Linux inode state. */ |
34 | VTRUNCATED = 0x40, /* truncated down so flush-on-close */ | ||
35 | } bhv_vflags_t; | ||
58 | 36 | ||
59 | /* | 37 | /* |
60 | * MP locking protocols: | 38 | * MP locking protocols: |
61 | * v_flag, v_vfsp VN_LOCK/VN_UNLOCK | 39 | * v_flag, v_vfsp VN_LOCK/VN_UNLOCK |
62 | */ | 40 | */ |
63 | typedef struct vnode { | 41 | typedef struct bhv_vnode { |
64 | __u32 v_flag; /* vnode flags (see below) */ | 42 | bhv_vflags_t v_flag; /* vnode flags (see above) */ |
65 | struct vfs *v_vfsp; /* ptr to containing VFS */ | 43 | bhv_vfs_t *v_vfsp; /* ptr to containing VFS */ |
66 | vnumber_t v_number; /* in-core vnode number */ | 44 | bhv_vnumber_t v_number; /* in-core vnode number */ |
67 | vn_bhv_head_t v_bh; /* behavior head */ | 45 | bhv_head_t v_bh; /* behavior head */ |
68 | spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ | 46 | spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ |
69 | atomic_t v_iocount; /* outstanding I/O count */ | 47 | atomic_t v_iocount; /* outstanding I/O count */ |
70 | #ifdef XFS_VNODE_TRACE | 48 | #ifdef XFS_VNODE_TRACE |
@@ -72,7 +50,7 @@ typedef struct vnode { | |||
72 | #endif | 50 | #endif |
73 | struct inode v_inode; /* Linux inode */ | 51 | struct inode v_inode; /* Linux inode */ |
74 | /* inode MUST be last */ | 52 | /* inode MUST be last */ |
75 | } vnode_t; | 53 | } bhv_vnode_t; |
76 | 54 | ||
77 | #define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode) | 55 | #define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode) |
78 | #define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode) | 56 | #define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode) |
@@ -80,9 +58,6 @@ typedef struct vnode { | |||
80 | #define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode) | 58 | #define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode) |
81 | #define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode) | 59 | #define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode) |
82 | 60 | ||
83 | #define v_fbhv v_bh.bh_first /* first behavior */ | ||
84 | #define v_fops v_bh.bh_first->bd_ops /* first behavior ops */ | ||
85 | |||
86 | #define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */ | 61 | #define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */ |
87 | #define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */ | 62 | #define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */ |
88 | #define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */ | 63 | #define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */ |
@@ -104,8 +79,8 @@ typedef enum { | |||
104 | /* | 79 | /* |
105 | * Macros for dealing with the behavior descriptor inside of the vnode. | 80 | * Macros for dealing with the behavior descriptor inside of the vnode. |
106 | */ | 81 | */ |
107 | #define BHV_TO_VNODE(bdp) ((vnode_t *)BHV_VOBJ(bdp)) | 82 | #define BHV_TO_VNODE(bdp) ((bhv_vnode_t *)BHV_VOBJ(bdp)) |
108 | #define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(bdp)) | 83 | #define BHV_TO_VNODE_NULL(bdp) ((bhv_vnode_t *)BHV_VOBJNULL(bdp)) |
109 | 84 | ||
110 | #define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh))) | 85 | #define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh))) |
111 | #define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name) | 86 | #define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name) |
@@ -116,35 +91,29 @@ typedef enum { | |||
116 | /* | 91 | /* |
117 | * Vnode to Linux inode mapping. | 92 | * Vnode to Linux inode mapping. |
118 | */ | 93 | */ |
119 | static inline struct vnode *vn_from_inode(struct inode *inode) | 94 | static inline struct bhv_vnode *vn_from_inode(struct inode *inode) |
120 | { | 95 | { |
121 | return (vnode_t *)list_entry(inode, vnode_t, v_inode); | 96 | return (bhv_vnode_t *)list_entry(inode, bhv_vnode_t, v_inode); |
122 | } | 97 | } |
123 | static inline struct inode *vn_to_inode(struct vnode *vnode) | 98 | static inline struct inode *vn_to_inode(struct bhv_vnode *vnode) |
124 | { | 99 | { |
125 | return &vnode->v_inode; | 100 | return &vnode->v_inode; |
126 | } | 101 | } |
127 | 102 | ||
128 | /* | 103 | /* |
129 | * Vnode flags. | 104 | * Values for the vop_rwlock/rwunlock flags parameter. |
130 | */ | ||
131 | #define VMODIFIED 0x8 /* XFS inode state possibly differs */ | ||
132 | /* to the Linux inode state. */ | ||
133 | |||
134 | /* | ||
135 | * Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter. | ||
136 | */ | 105 | */ |
137 | typedef enum vrwlock { | 106 | typedef enum bhv_vrwlock { |
138 | VRWLOCK_NONE, | 107 | VRWLOCK_NONE, |
139 | VRWLOCK_READ, | 108 | VRWLOCK_READ, |
140 | VRWLOCK_WRITE, | 109 | VRWLOCK_WRITE, |
141 | VRWLOCK_WRITE_DIRECT, | 110 | VRWLOCK_WRITE_DIRECT, |
142 | VRWLOCK_TRY_READ, | 111 | VRWLOCK_TRY_READ, |
143 | VRWLOCK_TRY_WRITE | 112 | VRWLOCK_TRY_WRITE |
144 | } vrwlock_t; | 113 | } bhv_vrwlock_t; |
145 | 114 | ||
146 | /* | 115 | /* |
147 | * Return values for VOP_INACTIVE. A return value of | 116 | * Return values for bhv_vop_inactive. A return value of |
148 | * VN_INACTIVE_NOCACHE implies that the file system behavior | 117 | * VN_INACTIVE_NOCACHE implies that the file system behavior |
149 | * has disassociated its state and bhv_desc_t from the vnode. | 118 | * has disassociated its state and bhv_desc_t from the vnode. |
150 | */ | 119 | */ |
@@ -152,18 +121,20 @@ typedef enum vrwlock { | |||
152 | #define VN_INACTIVE_NOCACHE 1 | 121 | #define VN_INACTIVE_NOCACHE 1 |
153 | 122 | ||
154 | /* | 123 | /* |
155 | * Values for the cmd code given to VOP_VNODE_CHANGE. | 124 | * Values for the cmd code given to vop_vnode_change. |
156 | */ | 125 | */ |
157 | typedef enum vchange { | 126 | typedef enum bhv_vchange { |
158 | VCHANGE_FLAGS_FRLOCKS = 0, | 127 | VCHANGE_FLAGS_FRLOCKS = 0, |
159 | VCHANGE_FLAGS_ENF_LOCKING = 1, | 128 | VCHANGE_FLAGS_ENF_LOCKING = 1, |
160 | VCHANGE_FLAGS_TRUNCATED = 2, | 129 | VCHANGE_FLAGS_TRUNCATED = 2, |
161 | VCHANGE_FLAGS_PAGE_DIRTY = 3, | 130 | VCHANGE_FLAGS_PAGE_DIRTY = 3, |
162 | VCHANGE_FLAGS_IOEXCL_COUNT = 4 | 131 | VCHANGE_FLAGS_IOEXCL_COUNT = 4 |
163 | } vchange_t; | 132 | } bhv_vchange_t; |
164 | 133 | ||
134 | typedef enum { L_FALSE, L_TRUE } lastclose_t; | ||
165 | 135 | ||
166 | typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); | 136 | typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); |
137 | typedef int (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *); | ||
167 | typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, | 138 | typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, |
168 | const struct iovec *, unsigned int, | 139 | const struct iovec *, unsigned int, |
169 | loff_t *, int, struct cred *); | 140 | loff_t *, int, struct cred *); |
@@ -181,27 +152,27 @@ typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *, | |||
181 | struct cred *); | 152 | struct cred *); |
182 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, | 153 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, |
183 | int, unsigned int, void __user *); | 154 | int, unsigned int, void __user *); |
184 | typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int, | 155 | typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int, |
185 | struct cred *); | 156 | struct cred *); |
186 | typedef int (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int, | 157 | typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int, |
187 | struct cred *); | 158 | struct cred *); |
188 | typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *); | 159 | typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *); |
189 | typedef int (*vop_lookup_t)(bhv_desc_t *, vname_t *, vnode_t **, | 160 | typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **, |
190 | int, vnode_t *, struct cred *); | 161 | int, bhv_vnode_t *, struct cred *); |
191 | typedef int (*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *, | 162 | typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *, |
192 | vnode_t **, struct cred *); | 163 | bhv_vnode_t **, struct cred *); |
193 | typedef int (*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *); | 164 | typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *); |
194 | typedef int (*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *, | 165 | typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *, |
195 | struct cred *); | ||
196 | typedef int (*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *, | ||
197 | struct cred *); | 166 | struct cred *); |
198 | typedef int (*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *, | 167 | typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *, |
199 | vnode_t **, struct cred *); | 168 | bhv_vname_t *, struct cred *); |
200 | typedef int (*vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *); | 169 | typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *, |
170 | bhv_vnode_t **, struct cred *); | ||
171 | typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *); | ||
201 | typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *, | 172 | typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *, |
202 | int *); | 173 | int *); |
203 | typedef int (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *, | 174 | typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*, |
204 | char *, vnode_t **, struct cred *); | 175 | char *, bhv_vnode_t **, struct cred *); |
205 | typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, | 176 | typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, |
206 | struct cred *); | 177 | struct cred *); |
207 | typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *, | 178 | typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *, |
@@ -209,8 +180,8 @@ typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *, | |||
209 | typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *); | 180 | typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *); |
210 | typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *); | 181 | typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *); |
211 | typedef int (*vop_release_t)(bhv_desc_t *); | 182 | typedef int (*vop_release_t)(bhv_desc_t *); |
212 | typedef int (*vop_rwlock_t)(bhv_desc_t *, vrwlock_t); | 183 | typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t); |
213 | typedef void (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t); | 184 | typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t); |
214 | typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int, | 185 | typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int, |
215 | struct xfs_iomap *, int *); | 186 | struct xfs_iomap *, int *); |
216 | typedef int (*vop_reclaim_t)(bhv_desc_t *); | 187 | typedef int (*vop_reclaim_t)(bhv_desc_t *); |
@@ -222,8 +193,8 @@ typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *, | |||
222 | int, struct cred *); | 193 | int, struct cred *); |
223 | typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int, | 194 | typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int, |
224 | struct attrlist_cursor_kern *, struct cred *); | 195 | struct attrlist_cursor_kern *, struct cred *); |
225 | typedef void (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int); | 196 | typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int); |
226 | typedef void (*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t); | 197 | typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t); |
227 | typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); | 198 | typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); |
228 | typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); | 199 | typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); |
229 | typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, | 200 | typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, |
@@ -231,9 +202,10 @@ typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, | |||
231 | typedef int (*vop_iflush_t)(bhv_desc_t *, int); | 202 | typedef int (*vop_iflush_t)(bhv_desc_t *, int); |
232 | 203 | ||
233 | 204 | ||
234 | typedef struct vnodeops { | 205 | typedef struct bhv_vnodeops { |
235 | bhv_position_t vn_position; /* position within behavior chain */ | 206 | bhv_position_t vn_position; /* position within behavior chain */ |
236 | vop_open_t vop_open; | 207 | vop_open_t vop_open; |
208 | vop_close_t vop_close; | ||
237 | vop_read_t vop_read; | 209 | vop_read_t vop_read; |
238 | vop_write_t vop_write; | 210 | vop_write_t vop_write; |
239 | vop_sendfile_t vop_sendfile; | 211 | vop_sendfile_t vop_sendfile; |
@@ -271,103 +243,80 @@ typedef struct vnodeops { | |||
271 | vop_pflushvp_t vop_flush_pages; | 243 | vop_pflushvp_t vop_flush_pages; |
272 | vop_release_t vop_release; | 244 | vop_release_t vop_release; |
273 | vop_iflush_t vop_iflush; | 245 | vop_iflush_t vop_iflush; |
274 | } vnodeops_t; | 246 | } bhv_vnodeops_t; |
275 | 247 | ||
276 | /* | 248 | /* |
277 | * VOP's. | 249 | * Virtual node operations, operating from head bhv. |
278 | */ | ||
279 | #define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op) | ||
280 | |||
281 | #define VOP_READ(vp,file,iov,segs,offset,ioflags,cr,rv) \ | ||
282 | rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr) | ||
283 | #define VOP_WRITE(vp,file,iov,segs,offset,ioflags,cr,rv) \ | ||
284 | rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr) | ||
285 | #define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \ | ||
286 | rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr) | ||
287 | #define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \ | ||
288 | rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr) | ||
289 | #define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \ | ||
290 | rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr) | ||
291 | #define VOP_BMAP(vp,of,sz,rw,b,n,rv) \ | ||
292 | rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n) | ||
293 | #define VOP_OPEN(vp, cr, rv) \ | ||
294 | rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr) | ||
295 | #define VOP_GETATTR(vp, vap, f, cr, rv) \ | ||
296 | rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr) | ||
297 | #define VOP_SETATTR(vp, vap, f, cr, rv) \ | ||
298 | rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr) | ||
299 | #define VOP_ACCESS(vp, mode, cr, rv) \ | ||
300 | rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr) | ||
301 | #define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \ | ||
302 | rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr) | ||
303 | #define VOP_CREATE(dvp,d,vap,vpp,cr,rv) \ | ||
304 | rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr) | ||
305 | #define VOP_REMOVE(dvp,d,cr,rv) \ | ||
306 | rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr) | ||
307 | #define VOP_LINK(tdvp,fvp,d,cr,rv) \ | ||
308 | rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr) | ||
309 | #define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \ | ||
310 | rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr) | ||
311 | #define VOP_MKDIR(dp,d,vap,vpp,cr,rv) \ | ||
312 | rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr) | ||
313 | #define VOP_RMDIR(dp,d,cr,rv) \ | ||
314 | rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr) | ||
315 | #define VOP_READDIR(vp,uiop,cr,eofp,rv) \ | ||
316 | rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp) | ||
317 | #define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \ | ||
318 | rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr) | ||
319 | #define VOP_READLINK(vp,uiop,fl,cr,rv) \ | ||
320 | rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr) | ||
321 | #define VOP_FSYNC(vp,f,cr,b,e,rv) \ | ||
322 | rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e) | ||
323 | #define VOP_INACTIVE(vp, cr, rv) \ | ||
324 | rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr) | ||
325 | #define VOP_RELEASE(vp, rv) \ | ||
326 | rv = _VOP_(vop_release, vp)((vp)->v_fbhv) | ||
327 | #define VOP_FID2(vp, fidp, rv) \ | ||
328 | rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp) | ||
329 | #define VOP_RWLOCK(vp,i) \ | ||
330 | (void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i) | ||
331 | #define VOP_RWLOCK_TRY(vp,i) \ | ||
332 | _VOP_(vop_rwlock, vp)((vp)->v_fbhv, i) | ||
333 | #define VOP_RWUNLOCK(vp,i) \ | ||
334 | (void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i) | ||
335 | #define VOP_FRLOCK(vp,c,fl,flags,offset,fr,rv) \ | ||
336 | rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr) | ||
337 | #define VOP_RECLAIM(vp, rv) \ | ||
338 | rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv) | ||
339 | #define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \ | ||
340 | rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred) | ||
341 | #define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \ | ||
342 | rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred) | ||
343 | #define VOP_ATTR_REMOVE(vp, name, flags, cred, rv) \ | ||
344 | rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred) | ||
345 | #define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \ | ||
346 | rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred) | ||
347 | #define VOP_LINK_REMOVED(vp, dvp, linkzero) \ | ||
348 | (void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero) | ||
349 | #define VOP_VNODE_CHANGE(vp, cmd, val) \ | ||
350 | (void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val) | ||
351 | /* | ||
352 | * These are page cache functions that now go thru VOPs. | ||
353 | * 'last' parameter is unused and left in for IRIX compatibility | ||
354 | */ | 250 | */ |
355 | #define VOP_TOSS_PAGES(vp, first, last, fiopt) \ | 251 | #define VNHEAD(vp) ((vp)->v_bh.bh_first) |
356 | _VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt) | 252 | #define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op) |
357 | /* | 253 | #define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr) |
358 | * 'last' parameter is unused and left in for IRIX compatibility | 254 | #define bhv_vop_close(vp, f,last,cr) VOP(vop_close, vp)(VNHEAD(vp),f,last,cr) |
359 | */ | 255 | #define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \ |
360 | #define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt) \ | 256 | VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) |
361 | _VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt) | 257 | #define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \ |
362 | /* | 258 | VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) |
363 | * 'last' parameter is unused and left in for IRIX compatibility | 259 | #define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \ |
364 | */ | 260 | VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr) |
365 | #define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \ | 261 | #define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \ |
366 | rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt) | 262 | VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr) |
367 | #define VOP_IOCTL(vp, inode, filp, fl, cmd, arg, rv) \ | 263 | #define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \ |
368 | rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,fl,cmd,arg) | 264 | VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr) |
369 | #define VOP_IFLUSH(vp, flags, rv) \ | 265 | #define bhv_vop_bmap(vp,of,sz,rw,b,n) \ |
370 | rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags) | 266 | VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n) |
267 | #define bhv_vop_getattr(vp, vap,f,cr) \ | ||
268 | VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr) | ||
269 | #define bhv_vop_setattr(vp, vap,f,cr) \ | ||
270 | VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr) | ||
271 | #define bhv_vop_access(vp, mode,cr) VOP(vop_access, vp)(VNHEAD(vp), mode,cr) | ||
272 | #define bhv_vop_lookup(vp,d,vpp,f,rdir,cr) \ | ||
273 | VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr) | ||
274 | #define bhv_vop_create(dvp,d,vap,vpp,cr) \ | ||
275 | VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr) | ||
276 | #define bhv_vop_remove(dvp,d,cr) VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr) | ||
277 | #define bhv_vop_link(dvp,fvp,d,cr) VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr) | ||
278 | #define bhv_vop_rename(fvp,fnm,tdvp,tnm,cr) \ | ||
279 | VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr) | ||
280 | #define bhv_vop_mkdir(dp,d,vap,vpp,cr) \ | ||
281 | VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr) | ||
282 | #define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr) | ||
283 | #define bhv_vop_readdir(vp,uiop,cr,eofp) \ | ||
284 | VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp) | ||
285 | #define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \ | ||
286 | VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr) | ||
287 | #define bhv_vop_readlink(vp,uiop,fl,cr) \ | ||
288 | VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr) | ||
289 | #define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e) | ||
290 | #define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr) | ||
291 | #define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp)) | ||
292 | #define bhv_vop_fid2(vp,fidp) VOP(vop_fid2, vp)(VNHEAD(vp),fidp) | ||
293 | #define bhv_vop_rwlock(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i) | ||
294 | #define bhv_vop_rwlock_try(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i) | ||
295 | #define bhv_vop_rwunlock(vp,i) VOP(vop_rwunlock, vp)(VNHEAD(vp),i) | ||
296 | #define bhv_vop_frlock(vp,c,fl,flags,offset,fr) \ | ||
297 | VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr) | ||
298 | #define bhv_vop_reclaim(vp) VOP(vop_reclaim, vp)(VNHEAD(vp)) | ||
299 | #define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred) \ | ||
300 | VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred) | ||
301 | #define bhv_vop_attr_set(vp, name, val, vallen, fl, cred) \ | ||
302 | VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred) | ||
303 | #define bhv_vop_attr_remove(vp, name, flags, cred) \ | ||
304 | VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred) | ||
305 | #define bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred) \ | ||
306 | VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred) | ||
307 | #define bhv_vop_link_removed(vp, dvp, linkzero) \ | ||
308 | VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero) | ||
309 | #define bhv_vop_vnode_change(vp, cmd, val) \ | ||
310 | VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val) | ||
311 | #define bhv_vop_toss_pages(vp, first, last, fiopt) \ | ||
312 | VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt) | ||
313 | #define bhv_vop_flushinval_pages(vp, first, last, fiopt) \ | ||
314 | VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt) | ||
315 | #define bhv_vop_flush_pages(vp, first, last, flags, fiopt) \ | ||
316 | VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt) | ||
317 | #define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg) \ | ||
318 | VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg) | ||
319 | #define bhv_vop_iflush(vp, flags) VOP(vop_iflush, vp)(VNHEAD(vp), flags) | ||
371 | 320 | ||
372 | /* | 321 | /* |
373 | * Flags for read/write calls - same values as IRIX | 322 | * Flags for read/write calls - same values as IRIX |
@@ -377,7 +326,7 @@ typedef struct vnodeops { | |||
377 | #define IO_INVIS 0x00020 /* don't update inode timestamps */ | 326 | #define IO_INVIS 0x00020 /* don't update inode timestamps */ |
378 | 327 | ||
379 | /* | 328 | /* |
380 | * Flags for VOP_IFLUSH call | 329 | * Flags for vop_iflush call |
381 | */ | 330 | */ |
382 | #define FLUSH_SYNC 1 /* wait for flush to complete */ | 331 | #define FLUSH_SYNC 1 /* wait for flush to complete */ |
383 | #define FLUSH_INODE 2 /* flush the inode itself */ | 332 | #define FLUSH_INODE 2 /* flush the inode itself */ |
@@ -385,8 +334,7 @@ typedef struct vnodeops { | |||
385 | * this inode out to disk */ | 334 | * this inode out to disk */ |
386 | 335 | ||
387 | /* | 336 | /* |
388 | * Flush/Invalidate options for VOP_TOSS_PAGES, VOP_FLUSHINVAL_PAGES and | 337 | * Flush/Invalidate options for vop_toss/flush/flushinval_pages. |
389 | * VOP_FLUSH_PAGES. | ||
390 | */ | 338 | */ |
391 | #define FI_NONE 0 /* none */ | 339 | #define FI_NONE 0 /* none */ |
392 | #define FI_REMAPF 1 /* Do a remapf prior to the operation */ | 340 | #define FI_REMAPF 1 /* Do a remapf prior to the operation */ |
@@ -398,7 +346,7 @@ typedef struct vnodeops { | |||
398 | * Vnode attributes. va_mask indicates those attributes the caller | 346 | * Vnode attributes. va_mask indicates those attributes the caller |
399 | * wants to set or extract. | 347 | * wants to set or extract. |
400 | */ | 348 | */ |
401 | typedef struct vattr { | 349 | typedef struct bhv_vattr { |
402 | int va_mask; /* bit-mask of attributes present */ | 350 | int va_mask; /* bit-mask of attributes present */ |
403 | mode_t va_mode; /* file access mode and type */ | 351 | mode_t va_mode; /* file access mode and type */ |
404 | xfs_nlink_t va_nlink; /* number of references to file */ | 352 | xfs_nlink_t va_nlink; /* number of references to file */ |
@@ -418,7 +366,7 @@ typedef struct vattr { | |||
418 | u_long va_nextents; /* number of extents in file */ | 366 | u_long va_nextents; /* number of extents in file */ |
419 | u_long va_anextents; /* number of attr extents in file */ | 367 | u_long va_anextents; /* number of attr extents in file */ |
420 | prid_t va_projid; /* project id */ | 368 | prid_t va_projid; /* project id */ |
421 | } vattr_t; | 369 | } bhv_vattr_t; |
422 | 370 | ||
423 | /* | 371 | /* |
424 | * setattr or getattr attributes | 372 | * setattr or getattr attributes |
@@ -492,29 +440,17 @@ typedef struct vattr { | |||
492 | (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID) | 440 | (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID) |
493 | 441 | ||
494 | extern void vn_init(void); | 442 | extern void vn_init(void); |
495 | extern vnode_t *vn_initialize(struct inode *); | 443 | extern bhv_vnode_t *vn_initialize(struct inode *); |
496 | 444 | extern int vn_revalidate(struct bhv_vnode *); | |
497 | /* | 445 | extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *); |
498 | * vnode_map structures _must_ match vn_epoch and vnode structure sizes. | 446 | extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *); |
499 | */ | ||
500 | typedef struct vnode_map { | ||
501 | vfs_t *v_vfsp; | ||
502 | vnumber_t v_number; /* in-core vnode number */ | ||
503 | xfs_ino_t v_ino; /* inode # */ | ||
504 | } vmap_t; | ||
505 | |||
506 | #define VMAP(vp, vmap) {(vmap).v_vfsp = (vp)->v_vfsp, \ | ||
507 | (vmap).v_number = (vp)->v_number, \ | ||
508 | (vmap).v_ino = (vp)->v_inode.i_ino; } | ||
509 | 447 | ||
510 | extern int vn_revalidate(struct vnode *); | 448 | extern void vn_iowait(struct bhv_vnode *vp); |
511 | extern int __vn_revalidate(struct vnode *, vattr_t *); | 449 | extern void vn_iowake(struct bhv_vnode *vp); |
512 | extern void vn_revalidate_core(struct vnode *, vattr_t *); | ||
513 | 450 | ||
514 | extern void vn_iowait(struct vnode *vp); | 451 | extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l); |
515 | extern void vn_iowake(struct vnode *vp); | ||
516 | 452 | ||
517 | static inline int vn_count(struct vnode *vp) | 453 | static inline int vn_count(struct bhv_vnode *vp) |
518 | { | 454 | { |
519 | return atomic_read(&vn_to_inode(vp)->i_count); | 455 | return atomic_read(&vn_to_inode(vp)->i_count); |
520 | } | 456 | } |
@@ -522,7 +458,7 @@ static inline int vn_count(struct vnode *vp) | |||
522 | /* | 458 | /* |
523 | * Vnode reference counting functions (and macros for compatibility). | 459 | * Vnode reference counting functions (and macros for compatibility). |
524 | */ | 460 | */ |
525 | extern vnode_t *vn_hold(struct vnode *); | 461 | extern bhv_vnode_t *vn_hold(struct bhv_vnode *); |
526 | 462 | ||
527 | #if defined(XFS_VNODE_TRACE) | 463 | #if defined(XFS_VNODE_TRACE) |
528 | #define VN_HOLD(vp) \ | 464 | #define VN_HOLD(vp) \ |
@@ -536,7 +472,7 @@ extern vnode_t *vn_hold(struct vnode *); | |||
536 | #define VN_RELE(vp) (iput(vn_to_inode(vp))) | 472 | #define VN_RELE(vp) (iput(vn_to_inode(vp))) |
537 | #endif | 473 | #endif |
538 | 474 | ||
539 | static inline struct vnode *vn_grab(struct vnode *vp) | 475 | static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp) |
540 | { | 476 | { |
541 | struct inode *inode = igrab(vn_to_inode(vp)); | 477 | struct inode *inode = igrab(vn_to_inode(vp)); |
542 | return inode ? vn_from_inode(inode) : NULL; | 478 | return inode ? vn_from_inode(inode) : NULL; |
@@ -554,32 +490,39 @@ static inline struct vnode *vn_grab(struct vnode *vp) | |||
554 | */ | 490 | */ |
555 | #define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock) | 491 | #define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock) |
556 | #define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s) | 492 | #define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s) |
557 | #define VN_FLAGSET(vp,b) vn_flagset(vp,b) | ||
558 | #define VN_FLAGCLR(vp,b) vn_flagclr(vp,b) | ||
559 | 493 | ||
560 | static __inline__ void vn_flagset(struct vnode *vp, uint flag) | 494 | static __inline__ void vn_flagset(struct bhv_vnode *vp, uint flag) |
561 | { | 495 | { |
562 | spin_lock(&vp->v_lock); | 496 | spin_lock(&vp->v_lock); |
563 | vp->v_flag |= flag; | 497 | vp->v_flag |= flag; |
564 | spin_unlock(&vp->v_lock); | 498 | spin_unlock(&vp->v_lock); |
565 | } | 499 | } |
566 | 500 | ||
567 | static __inline__ void vn_flagclr(struct vnode *vp, uint flag) | 501 | static __inline__ uint vn_flagclr(struct bhv_vnode *vp, uint flag) |
568 | { | 502 | { |
503 | uint cleared; | ||
504 | |||
569 | spin_lock(&vp->v_lock); | 505 | spin_lock(&vp->v_lock); |
506 | cleared = (vp->v_flag & flag); | ||
570 | vp->v_flag &= ~flag; | 507 | vp->v_flag &= ~flag; |
571 | spin_unlock(&vp->v_lock); | 508 | spin_unlock(&vp->v_lock); |
509 | return cleared; | ||
572 | } | 510 | } |
573 | 511 | ||
512 | #define VMODIFY(vp) vn_flagset(vp, VMODIFIED) | ||
513 | #define VUNMODIFY(vp) vn_flagclr(vp, VMODIFIED) | ||
514 | #define VTRUNCATE(vp) vn_flagset(vp, VTRUNCATED) | ||
515 | #define VUNTRUNCATE(vp) vn_flagclr(vp, VTRUNCATED) | ||
516 | |||
574 | /* | 517 | /* |
575 | * Dealing with bad inodes | 518 | * Dealing with bad inodes |
576 | */ | 519 | */ |
577 | static inline void vn_mark_bad(struct vnode *vp) | 520 | static inline void vn_mark_bad(struct bhv_vnode *vp) |
578 | { | 521 | { |
579 | make_bad_inode(vn_to_inode(vp)); | 522 | make_bad_inode(vn_to_inode(vp)); |
580 | } | 523 | } |
581 | 524 | ||
582 | static inline int VN_BAD(struct vnode *vp) | 525 | static inline int VN_BAD(struct bhv_vnode *vp) |
583 | { | 526 | { |
584 | return is_bad_inode(vn_to_inode(vp)); | 527 | return is_bad_inode(vn_to_inode(vp)); |
585 | } | 528 | } |
@@ -587,18 +530,18 @@ static inline int VN_BAD(struct vnode *vp) | |||
587 | /* | 530 | /* |
588 | * Extracting atime values in various formats | 531 | * Extracting atime values in various formats |
589 | */ | 532 | */ |
590 | static inline void vn_atime_to_bstime(struct vnode *vp, xfs_bstime_t *bs_atime) | 533 | static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime) |
591 | { | 534 | { |
592 | bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec; | 535 | bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec; |
593 | bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec; | 536 | bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec; |
594 | } | 537 | } |
595 | 538 | ||
596 | static inline void vn_atime_to_timespec(struct vnode *vp, struct timespec *ts) | 539 | static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts) |
597 | { | 540 | { |
598 | *ts = vp->v_inode.i_atime; | 541 | *ts = vp->v_inode.i_atime; |
599 | } | 542 | } |
600 | 543 | ||
601 | static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt) | 544 | static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt) |
602 | { | 545 | { |
603 | *tt = vp->v_inode.i_atime.tv_sec; | 546 | *tt = vp->v_inode.i_atime.tv_sec; |
604 | } | 547 | } |
@@ -610,11 +553,10 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt) | |||
610 | #define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages) | 553 | #define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages) |
611 | #define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ | 554 | #define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ |
612 | PAGECACHE_TAG_DIRTY) | 555 | PAGECACHE_TAG_DIRTY) |
613 | #define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED) | 556 | #define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED) |
614 | #define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED) | ||
615 | 557 | ||
616 | /* | 558 | /* |
617 | * Flags to VOP_SETATTR/VOP_GETATTR. | 559 | * Flags to vop_setattr/getattr. |
618 | */ | 560 | */ |
619 | #define ATTR_UTIME 0x01 /* non-default utime(2) request */ | 561 | #define ATTR_UTIME 0x01 /* non-default utime(2) request */ |
620 | #define ATTR_DMI 0x08 /* invocation from a DMI function */ | 562 | #define ATTR_DMI 0x08 /* invocation from a DMI function */ |
@@ -624,7 +566,7 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt) | |||
624 | #define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */ | 566 | #define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */ |
625 | 567 | ||
626 | /* | 568 | /* |
627 | * Flags to VOP_FSYNC and VOP_RECLAIM. | 569 | * Flags to vop_fsync/reclaim. |
628 | */ | 570 | */ |
629 | #define FSYNC_NOWAIT 0 /* asynchronous flush */ | 571 | #define FSYNC_NOWAIT 0 /* asynchronous flush */ |
630 | #define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */ | 572 | #define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */ |
@@ -643,11 +585,11 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt) | |||
643 | #define VNODE_KTRACE_REF 4 | 585 | #define VNODE_KTRACE_REF 4 |
644 | #define VNODE_KTRACE_RELE 5 | 586 | #define VNODE_KTRACE_RELE 5 |
645 | 587 | ||
646 | extern void vn_trace_entry(struct vnode *, const char *, inst_t *); | 588 | extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *); |
647 | extern void vn_trace_exit(struct vnode *, const char *, inst_t *); | 589 | extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *); |
648 | extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); | 590 | extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *); |
649 | extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); | 591 | extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *); |
650 | extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); | 592 | extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *); |
651 | 593 | ||
652 | #define VN_TRACE(vp) \ | 594 | #define VN_TRACE(vp) \ |
653 | vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address) | 595 | vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address) |
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 772ac48329ea..3aa771531856 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -444,7 +442,7 @@ xfs_qm_dqalloc( | |||
444 | XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, | 442 | XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, |
445 | &firstblock, | 443 | &firstblock, |
446 | XFS_QM_DQALLOC_SPACE_RES(mp), | 444 | XFS_QM_DQALLOC_SPACE_RES(mp), |
447 | &map, &nmaps, &flist))) { | 445 | &map, &nmaps, &flist, NULL))) { |
448 | goto error0; | 446 | goto error0; |
449 | } | 447 | } |
450 | ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); | 448 | ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); |
@@ -559,7 +557,7 @@ xfs_qm_dqtobp( | |||
559 | error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset, | 557 | error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset, |
560 | XFS_DQUOT_CLUSTER_SIZE_FSB, | 558 | XFS_DQUOT_CLUSTER_SIZE_FSB, |
561 | XFS_BMAPI_METADATA, | 559 | XFS_BMAPI_METADATA, |
562 | NULL, 0, &map, &nmaps, NULL); | 560 | NULL, 0, &map, &nmaps, NULL, NULL); |
563 | 561 | ||
564 | xfs_iunlock(quotip, XFS_ILOCK_SHARED); | 562 | xfs_iunlock(quotip, XFS_ILOCK_SHARED); |
565 | if (error) | 563 | if (error) |
@@ -1261,7 +1259,7 @@ xfs_qm_dqflush( | |||
1261 | 1259 | ||
1262 | if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id), | 1260 | if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id), |
1263 | 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) { | 1261 | 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) { |
1264 | xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); | 1262 | xfs_force_shutdown(dqp->q_mount, SHUTDOWN_CORRUPT_INCORE); |
1265 | return XFS_ERROR(EIO); | 1263 | return XFS_ERROR(EIO); |
1266 | } | 1264 | } |
1267 | 1265 | ||
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index c0c629663a5c..78d3ab95c5fd 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h | |||
@@ -119,7 +119,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) | |||
119 | */ | 119 | */ |
120 | #define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\ | 120 | #define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\ |
121 | (dqp)->dq_flags |= XFS_DQ_FLOCKED; } | 121 | (dqp)->dq_flags |= XFS_DQ_FLOCKED; } |
122 | #define xfs_dqfunlock(dqp) { ASSERT(valusema(&((dqp)->q_flock)) <= 0); \ | 122 | #define xfs_dqfunlock(dqp) { ASSERT(issemalocked(&((dqp)->q_flock))); \ |
123 | vsema(&((dqp)->q_flock)); \ | 123 | vsema(&((dqp)->q_flock)); \ |
124 | (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); } | 124 | (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); } |
125 | 125 | ||
@@ -128,7 +128,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp) | |||
128 | #define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \ | 128 | #define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \ |
129 | &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s) | 129 | &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s) |
130 | 130 | ||
131 | #define XFS_DQ_IS_FLUSH_LOCKED(dqp) (valusema(&((dqp)->q_flock)) <= 0) | 131 | #define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock))) |
132 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) | 132 | #define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) |
133 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) | 133 | #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) |
134 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) | 134 | #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) |
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index 546f48af882a..5b2dcc58b244 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -248,7 +246,7 @@ xfs_qm_dquot_logitem_pushbuf( | |||
248 | * inode flush completed and the inode was taken off the AIL. | 246 | * inode flush completed and the inode was taken off the AIL. |
249 | * So, just get out. | 247 | * So, just get out. |
250 | */ | 248 | */ |
251 | if ((valusema(&(dqp->q_flock)) > 0) || | 249 | if (!issemalocked(&(dqp->q_flock)) || |
252 | ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) { | 250 | ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) { |
253 | qip->qli_pushbuf_flag = 0; | 251 | qip->qli_pushbuf_flag = 0; |
254 | xfs_dqunlock(dqp); | 252 | xfs_dqunlock(dqp); |
@@ -261,7 +259,7 @@ xfs_qm_dquot_logitem_pushbuf( | |||
261 | if (bp != NULL) { | 259 | if (bp != NULL) { |
262 | if (XFS_BUF_ISDELAYWRITE(bp)) { | 260 | if (XFS_BUF_ISDELAYWRITE(bp)) { |
263 | dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && | 261 | dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && |
264 | (valusema(&(dqp->q_flock)) <= 0)); | 262 | issemalocked(&(dqp->q_flock))); |
265 | qip->qli_pushbuf_flag = 0; | 263 | qip->qli_pushbuf_flag = 0; |
266 | xfs_dqunlock(dqp); | 264 | xfs_dqunlock(dqp); |
267 | 265 | ||
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 7fb5eca9bd50..e23e45535c48 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_alloc.h" | 28 | #include "xfs_alloc.h" |
30 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
@@ -33,7 +32,6 @@ | |||
33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
36 | #include "xfs_dir_sf.h" | ||
37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
@@ -1603,7 +1601,7 @@ xfs_qm_dqiterate( | |||
1603 | maxlblkcnt - lblkno, | 1601 | maxlblkcnt - lblkno, |
1604 | XFS_BMAPI_METADATA, | 1602 | XFS_BMAPI_METADATA, |
1605 | NULL, | 1603 | NULL, |
1606 | 0, map, &nmaps, NULL); | 1604 | 0, map, &nmaps, NULL, NULL); |
1607 | xfs_iunlock(qip, XFS_ILOCK_SHARED); | 1605 | xfs_iunlock(qip, XFS_ILOCK_SHARED); |
1608 | if (error) | 1606 | if (error) |
1609 | break; | 1607 | break; |
@@ -1905,9 +1903,7 @@ xfs_qm_quotacheck( | |||
1905 | */ | 1903 | */ |
1906 | if ((error = xfs_bulkstat(mp, &lastino, &count, | 1904 | if ((error = xfs_bulkstat(mp, &lastino, &count, |
1907 | xfs_qm_dqusage_adjust, NULL, | 1905 | xfs_qm_dqusage_adjust, NULL, |
1908 | structsz, NULL, | 1906 | structsz, NULL, BULKSTAT_FG_IGET, &done))) |
1909 | BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED, | ||
1910 | &done))) | ||
1911 | break; | 1907 | break; |
1912 | 1908 | ||
1913 | } while (! done); | 1909 | } while (! done); |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index 6838b36d95a9..e95e99f7168f 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_alloc.h" | 28 | #include "xfs_alloc.h" |
30 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
@@ -33,7 +32,6 @@ | |||
33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
36 | #include "xfs_dir_sf.h" | ||
37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
@@ -129,7 +127,7 @@ xfs_qm_parseargs( | |||
129 | return XFS_ERROR(EINVAL); | 127 | return XFS_ERROR(EINVAL); |
130 | } | 128 | } |
131 | 129 | ||
132 | PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); | 130 | error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update); |
133 | if (!error && !referenced) | 131 | if (!error && !referenced) |
134 | bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); | 132 | bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); |
135 | return error; | 133 | return error; |
@@ -140,9 +138,8 @@ xfs_qm_showargs( | |||
140 | struct bhv_desc *bhv, | 138 | struct bhv_desc *bhv, |
141 | struct seq_file *m) | 139 | struct seq_file *m) |
142 | { | 140 | { |
143 | struct vfs *vfsp = bhvtovfs(bhv); | 141 | struct bhv_vfs *vfsp = bhvtovfs(bhv); |
144 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | 142 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); |
145 | int error; | ||
146 | 143 | ||
147 | if (mp->m_qflags & XFS_UQUOTA_ACCT) { | 144 | if (mp->m_qflags & XFS_UQUOTA_ACCT) { |
148 | (mp->m_qflags & XFS_UQUOTA_ENFD) ? | 145 | (mp->m_qflags & XFS_UQUOTA_ENFD) ? |
@@ -165,8 +162,7 @@ xfs_qm_showargs( | |||
165 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) | 162 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) |
166 | seq_puts(m, "," MNTOPT_NOQUOTA); | 163 | seq_puts(m, "," MNTOPT_NOQUOTA); |
167 | 164 | ||
168 | PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); | 165 | return bhv_next_vfs_showargs(BHV_NEXT(bhv), m); |
169 | return error; | ||
170 | } | 166 | } |
171 | 167 | ||
172 | STATIC int | 168 | STATIC int |
@@ -175,14 +171,67 @@ xfs_qm_mount( | |||
175 | struct xfs_mount_args *args, | 171 | struct xfs_mount_args *args, |
176 | struct cred *cr) | 172 | struct cred *cr) |
177 | { | 173 | { |
178 | struct vfs *vfsp = bhvtovfs(bhv); | 174 | struct bhv_vfs *vfsp = bhvtovfs(bhv); |
179 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | 175 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); |
180 | int error; | ||
181 | 176 | ||
182 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) | 177 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) |
183 | xfs_qm_mount_quotainit(mp, args->flags); | 178 | xfs_qm_mount_quotainit(mp, args->flags); |
184 | PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); | 179 | return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr); |
185 | return error; | 180 | } |
181 | |||
182 | /* | ||
183 | * Directory tree accounting is implemented using project quotas, where | ||
184 | * the project identifier is inherited from parent directories. | ||
185 | * A statvfs (df, etc.) of a directory that is using project quota should | ||
186 | * return a statvfs of the project, not the entire filesystem. | ||
187 | * This makes such trees appear as if they are filesystems in themselves. | ||
188 | */ | ||
189 | STATIC int | ||
190 | xfs_qm_statvfs( | ||
191 | struct bhv_desc *bhv, | ||
192 | bhv_statvfs_t *statp, | ||
193 | struct bhv_vnode *vnode) | ||
194 | { | ||
195 | xfs_mount_t *mp; | ||
196 | xfs_inode_t *ip; | ||
197 | xfs_dquot_t *dqp; | ||
198 | xfs_disk_dquot_t *dp; | ||
199 | __uint64_t limit; | ||
200 | int error; | ||
201 | |||
202 | error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode); | ||
203 | if (error || !vnode) | ||
204 | return error; | ||
205 | |||
206 | mp = XFS_BHVTOM(bhv); | ||
207 | ip = xfs_vtoi(vnode); | ||
208 | |||
209 | if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)) | ||
210 | return 0; | ||
211 | if (!(mp->m_qflags & XFS_PQUOTA_ACCT)) | ||
212 | return 0; | ||
213 | if (!(mp->m_qflags & XFS_OQUOTA_ENFD)) | ||
214 | return 0; | ||
215 | |||
216 | if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp)) | ||
217 | return 0; | ||
218 | dp = &dqp->q_core; | ||
219 | |||
220 | limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit; | ||
221 | if (limit && statp->f_blocks > limit) { | ||
222 | statp->f_blocks = limit; | ||
223 | statp->f_bfree = (statp->f_blocks > dp->d_bcount) ? | ||
224 | (statp->f_blocks - dp->d_bcount) : 0; | ||
225 | } | ||
226 | limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit; | ||
227 | if (limit && statp->f_files > limit) { | ||
228 | statp->f_files = limit; | ||
229 | statp->f_ffree = (statp->f_files > dp->d_icount) ? | ||
230 | (statp->f_ffree - dp->d_icount) : 0; | ||
231 | } | ||
232 | |||
233 | xfs_qm_dqput(dqp); | ||
234 | return 0; | ||
186 | } | 235 | } |
187 | 236 | ||
188 | STATIC int | 237 | STATIC int |
@@ -191,7 +240,7 @@ xfs_qm_syncall( | |||
191 | int flags, | 240 | int flags, |
192 | cred_t *credp) | 241 | cred_t *credp) |
193 | { | 242 | { |
194 | struct vfs *vfsp = bhvtovfs(bhv); | 243 | struct bhv_vfs *vfsp = bhvtovfs(bhv); |
195 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); | 244 | struct xfs_mount *mp = XFS_VFSTOM(vfsp); |
196 | int error; | 245 | int error; |
197 | 246 | ||
@@ -210,8 +259,7 @@ xfs_qm_syncall( | |||
210 | } | 259 | } |
211 | } | 260 | } |
212 | } | 261 | } |
213 | PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error); | 262 | return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp); |
214 | return error; | ||
215 | } | 263 | } |
216 | 264 | ||
217 | STATIC int | 265 | STATIC int |
@@ -346,11 +394,12 @@ STATIC struct xfs_qmops xfs_qmcore_xfs = { | |||
346 | .xfs_dqtrxops = &xfs_trans_dquot_ops, | 394 | .xfs_dqtrxops = &xfs_trans_dquot_ops, |
347 | }; | 395 | }; |
348 | 396 | ||
349 | struct bhv_vfsops xfs_qmops = { { | 397 | struct bhv_module_vfsops xfs_qmops = { { |
350 | BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM), | 398 | BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM), |
351 | .vfs_parseargs = xfs_qm_parseargs, | 399 | .vfs_parseargs = xfs_qm_parseargs, |
352 | .vfs_showargs = xfs_qm_showargs, | 400 | .vfs_showargs = xfs_qm_showargs, |
353 | .vfs_mount = xfs_qm_mount, | 401 | .vfs_mount = xfs_qm_mount, |
402 | .vfs_statvfs = xfs_qm_statvfs, | ||
354 | .vfs_sync = xfs_qm_syncall, | 403 | .vfs_sync = xfs_qm_syncall, |
355 | .vfs_quotactl = xfs_qm_quotactl, }, | 404 | .vfs_quotactl = xfs_qm_quotactl, }, |
356 | }; | 405 | }; |
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c index 0570f7733550..6f858fb81a36 100644 --- a/fs/xfs/quota/xfs_qm_stats.c +++ b/fs/xfs/quota/xfs_qm_stats.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index c55db463bbf2..ed620c4d1594 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "xfs_trans.h" | 26 | #include "xfs_trans.h" |
27 | #include "xfs_sb.h" | 27 | #include "xfs_sb.h" |
28 | #include "xfs_ag.h" | 28 | #include "xfs_ag.h" |
29 | #include "xfs_dir.h" | ||
30 | #include "xfs_dir2.h" | 29 | #include "xfs_dir2.h" |
31 | #include "xfs_alloc.h" | 30 | #include "xfs_alloc.h" |
32 | #include "xfs_dmapi.h" | 31 | #include "xfs_dmapi.h" |
@@ -35,7 +34,6 @@ | |||
35 | #include "xfs_bmap_btree.h" | 34 | #include "xfs_bmap_btree.h" |
36 | #include "xfs_alloc_btree.h" | 35 | #include "xfs_alloc_btree.h" |
37 | #include "xfs_ialloc_btree.h" | 36 | #include "xfs_ialloc_btree.h" |
38 | #include "xfs_dir_sf.h" | ||
39 | #include "xfs_dir2_sf.h" | 37 | #include "xfs_dir2_sf.h" |
40 | #include "xfs_attr_sf.h" | 38 | #include "xfs_attr_sf.h" |
41 | #include "xfs_dinode.h" | 39 | #include "xfs_dinode.h" |
@@ -91,8 +89,8 @@ xfs_qm_quotactl( | |||
91 | xfs_caddr_t addr) | 89 | xfs_caddr_t addr) |
92 | { | 90 | { |
93 | xfs_mount_t *mp; | 91 | xfs_mount_t *mp; |
92 | bhv_vfs_t *vfsp; | ||
94 | int error; | 93 | int error; |
95 | struct vfs *vfsp; | ||
96 | 94 | ||
97 | vfsp = bhvtovfs(bdp); | 95 | vfsp = bhvtovfs(bdp); |
98 | mp = XFS_VFSTOM(vfsp); | 96 | mp = XFS_VFSTOM(vfsp); |
@@ -1035,7 +1033,7 @@ xfs_qm_dqrele_all_inodes( | |||
1035 | { | 1033 | { |
1036 | xfs_inode_t *ip, *topino; | 1034 | xfs_inode_t *ip, *topino; |
1037 | uint ireclaims; | 1035 | uint ireclaims; |
1038 | vnode_t *vp; | 1036 | bhv_vnode_t *vp; |
1039 | boolean_t vnode_refd; | 1037 | boolean_t vnode_refd; |
1040 | 1038 | ||
1041 | ASSERT(mp->m_quotainfo); | 1039 | ASSERT(mp->m_quotainfo); |
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 9168918db252..0242e9666e8e 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -33,7 +32,6 @@ | |||
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
36 | #include "xfs_dir_sf.h" | ||
37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
39 | #include "xfs_inode.h" | 37 | #include "xfs_inode.h" |
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c index b08b3d9345b7..36fbeccdc722 100644 --- a/fs/xfs/support/debug.c +++ b/fs/xfs/support/debug.c | |||
@@ -47,7 +47,7 @@ cmn_err(register int level, char *fmt, ...) | |||
47 | va_start(ap, fmt); | 47 | va_start(ap, fmt); |
48 | if (*fmt == '!') fp++; | 48 | if (*fmt == '!') fp++; |
49 | len = vsprintf(message, fp, ap); | 49 | len = vsprintf(message, fp, ap); |
50 | if (message[len-1] != '\n') | 50 | if (level != CE_DEBUG && message[len-1] != '\n') |
51 | strcat(message, "\n"); | 51 | strcat(message, "\n"); |
52 | printk("%s%s", err_level[level], message); | 52 | printk("%s%s", err_level[level], message); |
53 | va_end(ap); | 53 | va_end(ap); |
@@ -68,7 +68,7 @@ icmn_err(register int level, char *fmt, va_list ap) | |||
68 | level = XFS_MAX_ERR_LEVEL; | 68 | level = XFS_MAX_ERR_LEVEL; |
69 | spin_lock_irqsave(&xfs_err_lock,flags); | 69 | spin_lock_irqsave(&xfs_err_lock,flags); |
70 | len = vsprintf(message, fmt, ap); | 70 | len = vsprintf(message, fmt, ap); |
71 | if (message[len-1] != '\n') | 71 | if (level != CE_DEBUG && message[len-1] != '\n') |
72 | strcat(message, "\n"); | 72 | strcat(message, "\n"); |
73 | spin_unlock_irqrestore(&xfs_err_lock,flags); | 73 | spin_unlock_irqrestore(&xfs_err_lock,flags); |
74 | printk("%s%s", err_level[level], message); | 74 | printk("%s%s", err_level[level], message); |
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h index e3bf58112e7e..4f54dca662a8 100644 --- a/fs/xfs/support/debug.h +++ b/fs/xfs/support/debug.h | |||
@@ -33,9 +33,6 @@ extern void cmn_err(int, char *, ...) | |||
33 | __attribute__ ((format (printf, 2, 3))); | 33 | __attribute__ ((format (printf, 2, 3))); |
34 | extern void assfail(char *expr, char *f, int l); | 34 | extern void assfail(char *expr, char *f, int l); |
35 | 35 | ||
36 | #define prdev(fmt,targ,args...) \ | ||
37 | printk("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args) | ||
38 | |||
39 | #define ASSERT_ALWAYS(expr) \ | 36 | #define ASSERT_ALWAYS(expr) \ |
40 | (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) | 37 | (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) |
41 | 38 | ||
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 2539af34eb63..4b0cb474be4c 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -21,12 +21,10 @@ | |||
21 | #include "xfs_bit.h" | 21 | #include "xfs_bit.h" |
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_ag.h" | 23 | #include "xfs_ag.h" |
24 | #include "xfs_dir.h" | ||
25 | #include "xfs_dir2.h" | 24 | #include "xfs_dir2.h" |
26 | #include "xfs_bmap_btree.h" | 25 | #include "xfs_bmap_btree.h" |
27 | #include "xfs_alloc_btree.h" | 26 | #include "xfs_alloc_btree.h" |
28 | #include "xfs_ialloc_btree.h" | 27 | #include "xfs_ialloc_btree.h" |
29 | #include "xfs_dir_sf.h" | ||
30 | #include "xfs_dir2_sf.h" | 28 | #include "xfs_dir2_sf.h" |
31 | #include "xfs_attr_sf.h" | 29 | #include "xfs_attr_sf.h" |
32 | #include "xfs_dinode.h" | 30 | #include "xfs_dinode.h" |
@@ -39,15 +37,15 @@ | |||
39 | #include <linux/capability.h> | 37 | #include <linux/capability.h> |
40 | #include <linux/posix_acl_xattr.h> | 38 | #include <linux/posix_acl_xattr.h> |
41 | 39 | ||
42 | STATIC int xfs_acl_setmode(vnode_t *, xfs_acl_t *, int *); | 40 | STATIC int xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *); |
43 | STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *); | 41 | STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *); |
44 | STATIC void xfs_acl_get_endian(xfs_acl_t *); | 42 | STATIC void xfs_acl_get_endian(xfs_acl_t *); |
45 | STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *); | 43 | STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *); |
46 | STATIC int xfs_acl_invalid(xfs_acl_t *); | 44 | STATIC int xfs_acl_invalid(xfs_acl_t *); |
47 | STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *); | 45 | STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *); |
48 | STATIC void xfs_acl_get_attr(vnode_t *, xfs_acl_t *, int, int, int *); | 46 | STATIC void xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *); |
49 | STATIC void xfs_acl_set_attr(vnode_t *, xfs_acl_t *, int, int *); | 47 | STATIC void xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *); |
50 | STATIC int xfs_acl_allow_set(vnode_t *, int); | 48 | STATIC int xfs_acl_allow_set(bhv_vnode_t *, int); |
51 | 49 | ||
52 | kmem_zone_t *xfs_acl_zone; | 50 | kmem_zone_t *xfs_acl_zone; |
53 | 51 | ||
@@ -57,7 +55,7 @@ kmem_zone_t *xfs_acl_zone; | |||
57 | */ | 55 | */ |
58 | int | 56 | int |
59 | xfs_acl_vhasacl_access( | 57 | xfs_acl_vhasacl_access( |
60 | vnode_t *vp) | 58 | bhv_vnode_t *vp) |
61 | { | 59 | { |
62 | int error; | 60 | int error; |
63 | 61 | ||
@@ -70,7 +68,7 @@ xfs_acl_vhasacl_access( | |||
70 | */ | 68 | */ |
71 | int | 69 | int |
72 | xfs_acl_vhasacl_default( | 70 | xfs_acl_vhasacl_default( |
73 | vnode_t *vp) | 71 | bhv_vnode_t *vp) |
74 | { | 72 | { |
75 | int error; | 73 | int error; |
76 | 74 | ||
@@ -209,7 +207,7 @@ posix_acl_xfs_to_xattr( | |||
209 | 207 | ||
210 | int | 208 | int |
211 | xfs_acl_vget( | 209 | xfs_acl_vget( |
212 | vnode_t *vp, | 210 | bhv_vnode_t *vp, |
213 | void *acl, | 211 | void *acl, |
214 | size_t size, | 212 | size_t size, |
215 | int kind) | 213 | int kind) |
@@ -241,10 +239,10 @@ xfs_acl_vget( | |||
241 | goto out; | 239 | goto out; |
242 | } | 240 | } |
243 | if (kind == _ACL_TYPE_ACCESS) { | 241 | if (kind == _ACL_TYPE_ACCESS) { |
244 | vattr_t va; | 242 | bhv_vattr_t va; |
245 | 243 | ||
246 | va.va_mask = XFS_AT_MODE; | 244 | va.va_mask = XFS_AT_MODE; |
247 | VOP_GETATTR(vp, &va, 0, sys_cred, error); | 245 | error = bhv_vop_getattr(vp, &va, 0, sys_cred); |
248 | if (error) | 246 | if (error) |
249 | goto out; | 247 | goto out; |
250 | xfs_acl_sync_mode(va.va_mode, xfs_acl); | 248 | xfs_acl_sync_mode(va.va_mode, xfs_acl); |
@@ -260,7 +258,7 @@ out: | |||
260 | 258 | ||
261 | int | 259 | int |
262 | xfs_acl_vremove( | 260 | xfs_acl_vremove( |
263 | vnode_t *vp, | 261 | bhv_vnode_t *vp, |
264 | int kind) | 262 | int kind) |
265 | { | 263 | { |
266 | int error; | 264 | int error; |
@@ -268,9 +266,9 @@ xfs_acl_vremove( | |||
268 | VN_HOLD(vp); | 266 | VN_HOLD(vp); |
269 | error = xfs_acl_allow_set(vp, kind); | 267 | error = xfs_acl_allow_set(vp, kind); |
270 | if (!error) { | 268 | if (!error) { |
271 | VOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT? | 269 | error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT? |
272 | SGI_ACL_DEFAULT: SGI_ACL_FILE, | 270 | SGI_ACL_DEFAULT: SGI_ACL_FILE, |
273 | ATTR_ROOT, sys_cred, error); | 271 | ATTR_ROOT, sys_cred); |
274 | if (error == ENOATTR) | 272 | if (error == ENOATTR) |
275 | error = 0; /* 'scool */ | 273 | error = 0; /* 'scool */ |
276 | } | 274 | } |
@@ -280,7 +278,7 @@ xfs_acl_vremove( | |||
280 | 278 | ||
281 | int | 279 | int |
282 | xfs_acl_vset( | 280 | xfs_acl_vset( |
283 | vnode_t *vp, | 281 | bhv_vnode_t *vp, |
284 | void *acl, | 282 | void *acl, |
285 | size_t size, | 283 | size_t size, |
286 | int kind) | 284 | int kind) |
@@ -370,10 +368,10 @@ xfs_acl_iaccess( | |||
370 | 368 | ||
371 | STATIC int | 369 | STATIC int |
372 | xfs_acl_allow_set( | 370 | xfs_acl_allow_set( |
373 | vnode_t *vp, | 371 | bhv_vnode_t *vp, |
374 | int kind) | 372 | int kind) |
375 | { | 373 | { |
376 | vattr_t va; | 374 | bhv_vattr_t va; |
377 | int error; | 375 | int error; |
378 | 376 | ||
379 | if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) | 377 | if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) |
@@ -383,7 +381,7 @@ xfs_acl_allow_set( | |||
383 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 381 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) |
384 | return EROFS; | 382 | return EROFS; |
385 | va.va_mask = XFS_AT_UID; | 383 | va.va_mask = XFS_AT_UID; |
386 | VOP_GETATTR(vp, &va, 0, NULL, error); | 384 | error = bhv_vop_getattr(vp, &va, 0, NULL); |
387 | if (error) | 385 | if (error) |
388 | return error; | 386 | return error; |
389 | if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) | 387 | if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) |
@@ -606,7 +604,7 @@ xfs_acl_get_endian( | |||
606 | */ | 604 | */ |
607 | STATIC void | 605 | STATIC void |
608 | xfs_acl_get_attr( | 606 | xfs_acl_get_attr( |
609 | vnode_t *vp, | 607 | bhv_vnode_t *vp, |
610 | xfs_acl_t *aclp, | 608 | xfs_acl_t *aclp, |
611 | int kind, | 609 | int kind, |
612 | int flags, | 610 | int flags, |
@@ -616,9 +614,9 @@ xfs_acl_get_attr( | |||
616 | 614 | ||
617 | ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); | 615 | ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); |
618 | flags |= ATTR_ROOT; | 616 | flags |= ATTR_ROOT; |
619 | VOP_ATTR_GET(vp, | 617 | *error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ? |
620 | kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT, | 618 | SGI_ACL_FILE : SGI_ACL_DEFAULT, |
621 | (char *)aclp, &len, flags, sys_cred, *error); | 619 | (char *)aclp, &len, flags, sys_cred); |
622 | if (*error || (flags & ATTR_KERNOVAL)) | 620 | if (*error || (flags & ATTR_KERNOVAL)) |
623 | return; | 621 | return; |
624 | xfs_acl_get_endian(aclp); | 622 | xfs_acl_get_endian(aclp); |
@@ -629,7 +627,7 @@ xfs_acl_get_attr( | |||
629 | */ | 627 | */ |
630 | STATIC void | 628 | STATIC void |
631 | xfs_acl_set_attr( | 629 | xfs_acl_set_attr( |
632 | vnode_t *vp, | 630 | bhv_vnode_t *vp, |
633 | xfs_acl_t *aclp, | 631 | xfs_acl_t *aclp, |
634 | int kind, | 632 | int kind, |
635 | int *error) | 633 | int *error) |
@@ -654,19 +652,19 @@ xfs_acl_set_attr( | |||
654 | INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); | 652 | INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); |
655 | } | 653 | } |
656 | INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); | 654 | INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); |
657 | VOP_ATTR_SET(vp, | 655 | *error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ? |
658 | kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE: SGI_ACL_DEFAULT, | 656 | SGI_ACL_FILE: SGI_ACL_DEFAULT, |
659 | (char *)newacl, len, ATTR_ROOT, sys_cred, *error); | 657 | (char *)newacl, len, ATTR_ROOT, sys_cred); |
660 | _ACL_FREE(newacl); | 658 | _ACL_FREE(newacl); |
661 | } | 659 | } |
662 | 660 | ||
663 | int | 661 | int |
664 | xfs_acl_vtoacl( | 662 | xfs_acl_vtoacl( |
665 | vnode_t *vp, | 663 | bhv_vnode_t *vp, |
666 | xfs_acl_t *access_acl, | 664 | xfs_acl_t *access_acl, |
667 | xfs_acl_t *default_acl) | 665 | xfs_acl_t *default_acl) |
668 | { | 666 | { |
669 | vattr_t va; | 667 | bhv_vattr_t va; |
670 | int error = 0; | 668 | int error = 0; |
671 | 669 | ||
672 | if (access_acl) { | 670 | if (access_acl) { |
@@ -678,7 +676,7 @@ xfs_acl_vtoacl( | |||
678 | if (!error) { | 676 | if (!error) { |
679 | /* Got the ACL, need the mode... */ | 677 | /* Got the ACL, need the mode... */ |
680 | va.va_mask = XFS_AT_MODE; | 678 | va.va_mask = XFS_AT_MODE; |
681 | VOP_GETATTR(vp, &va, 0, sys_cred, error); | 679 | error = bhv_vop_getattr(vp, &va, 0, sys_cred); |
682 | } | 680 | } |
683 | 681 | ||
684 | if (error) | 682 | if (error) |
@@ -701,8 +699,8 @@ xfs_acl_vtoacl( | |||
701 | */ | 699 | */ |
702 | int | 700 | int |
703 | xfs_acl_inherit( | 701 | xfs_acl_inherit( |
704 | vnode_t *vp, | 702 | bhv_vnode_t *vp, |
705 | vattr_t *vap, | 703 | bhv_vattr_t *vap, |
706 | xfs_acl_t *pdaclp) | 704 | xfs_acl_t *pdaclp) |
707 | { | 705 | { |
708 | xfs_acl_t *cacl; | 706 | xfs_acl_t *cacl; |
@@ -757,11 +755,11 @@ xfs_acl_inherit( | |||
757 | */ | 755 | */ |
758 | STATIC int | 756 | STATIC int |
759 | xfs_acl_setmode( | 757 | xfs_acl_setmode( |
760 | vnode_t *vp, | 758 | bhv_vnode_t *vp, |
761 | xfs_acl_t *acl, | 759 | xfs_acl_t *acl, |
762 | int *basicperms) | 760 | int *basicperms) |
763 | { | 761 | { |
764 | vattr_t va; | 762 | bhv_vattr_t va; |
765 | xfs_acl_entry_t *ap; | 763 | xfs_acl_entry_t *ap; |
766 | xfs_acl_entry_t *gap = NULL; | 764 | xfs_acl_entry_t *gap = NULL; |
767 | int i, error, nomask = 1; | 765 | int i, error, nomask = 1; |
@@ -776,7 +774,7 @@ xfs_acl_setmode( | |||
776 | * mode. The m:: bits take precedence over the g:: bits. | 774 | * mode. The m:: bits take precedence over the g:: bits. |
777 | */ | 775 | */ |
778 | va.va_mask = XFS_AT_MODE; | 776 | va.va_mask = XFS_AT_MODE; |
779 | VOP_GETATTR(vp, &va, 0, sys_cred, error); | 777 | error = bhv_vop_getattr(vp, &va, 0, sys_cred); |
780 | if (error) | 778 | if (error) |
781 | return error; | 779 | return error; |
782 | 780 | ||
@@ -810,8 +808,7 @@ xfs_acl_setmode( | |||
810 | if (gap && nomask) | 808 | if (gap && nomask) |
811 | va.va_mode |= gap->ae_perm << 3; | 809 | va.va_mode |= gap->ae_perm << 3; |
812 | 810 | ||
813 | VOP_SETATTR(vp, &va, 0, sys_cred, error); | 811 | return bhv_vop_setattr(vp, &va, 0, sys_cred); |
814 | return error; | ||
815 | } | 812 | } |
816 | 813 | ||
817 | /* | 814 | /* |
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 538d0d65b04c..f853cf1a6270 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h | |||
@@ -50,7 +50,7 @@ typedef struct xfs_acl { | |||
50 | #ifdef CONFIG_XFS_POSIX_ACL | 50 | #ifdef CONFIG_XFS_POSIX_ACL |
51 | 51 | ||
52 | struct vattr; | 52 | struct vattr; |
53 | struct vnode; | 53 | struct bhv_vnode; |
54 | struct xfs_inode; | 54 | struct xfs_inode; |
55 | 55 | ||
56 | extern struct kmem_zone *xfs_acl_zone; | 56 | extern struct kmem_zone *xfs_acl_zone; |
@@ -58,14 +58,14 @@ extern struct kmem_zone *xfs_acl_zone; | |||
58 | (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name)) | 58 | (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name)) |
59 | #define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) | 59 | #define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) |
60 | 60 | ||
61 | extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *); | 61 | extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *); |
62 | extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); | 62 | extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); |
63 | extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *); | 63 | extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *); |
64 | extern int xfs_acl_vhasacl_access(struct vnode *); | 64 | extern int xfs_acl_vhasacl_access(struct bhv_vnode *); |
65 | extern int xfs_acl_vhasacl_default(struct vnode *); | 65 | extern int xfs_acl_vhasacl_default(struct bhv_vnode *); |
66 | extern int xfs_acl_vset(struct vnode *, void *, size_t, int); | 66 | extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int); |
67 | extern int xfs_acl_vget(struct vnode *, void *, size_t, int); | 67 | extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int); |
68 | extern int xfs_acl_vremove(struct vnode *vp, int); | 68 | extern int xfs_acl_vremove(struct bhv_vnode *, int); |
69 | 69 | ||
70 | #define _ACL_TYPE_ACCESS 1 | 70 | #define _ACL_TYPE_ACCESS 1 |
71 | #define _ACL_TYPE_DEFAULT 2 | 71 | #define _ACL_TYPE_DEFAULT 2 |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 8558226281c4..eef6763f3a67 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -1862,7 +1860,7 @@ xfs_alloc_fix_freelist( | |||
1862 | (pag->pagf_longest - delta) : | 1860 | (pag->pagf_longest - delta) : |
1863 | (pag->pagf_flcount > 0 || pag->pagf_longest > 0); | 1861 | (pag->pagf_flcount > 0 || pag->pagf_longest > 0); |
1864 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || | 1862 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || |
1865 | (args->minleft && | 1863 | (!(flags & XFS_ALLOC_FLAG_FREEING) && |
1866 | (int)(pag->pagf_freeblks + pag->pagf_flcount - | 1864 | (int)(pag->pagf_freeblks + pag->pagf_flcount - |
1867 | need - args->total) < | 1865 | need - args->total) < |
1868 | (int)args->minleft)) { | 1866 | (int)args->minleft)) { |
@@ -1898,7 +1896,7 @@ xfs_alloc_fix_freelist( | |||
1898 | longest = (longest > delta) ? (longest - delta) : | 1896 | longest = (longest > delta) ? (longest - delta) : |
1899 | (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); | 1897 | (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); |
1900 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || | 1898 | if (args->minlen + args->alignment + args->minalignslop - 1 > longest || |
1901 | (args->minleft && | 1899 | (!(flags & XFS_ALLOC_FLAG_FREEING) && |
1902 | (int)(be32_to_cpu(agf->agf_freeblks) + | 1900 | (int)(be32_to_cpu(agf->agf_freeblks) + |
1903 | be32_to_cpu(agf->agf_flcount) - need - args->total) < | 1901 | be32_to_cpu(agf->agf_flcount) - need - args->total) < |
1904 | (int)args->minleft)) { | 1902 | (int)args->minleft)) { |
@@ -1951,8 +1949,14 @@ xfs_alloc_fix_freelist( | |||
1951 | * the restrictions correctly. Can happen for free calls | 1949 | * the restrictions correctly. Can happen for free calls |
1952 | * on a completely full ag. | 1950 | * on a completely full ag. |
1953 | */ | 1951 | */ |
1954 | if (targs.agbno == NULLAGBLOCK) | 1952 | if (targs.agbno == NULLAGBLOCK) { |
1953 | if (!(flags & XFS_ALLOC_FLAG_FREEING)) { | ||
1954 | xfs_trans_brelse(tp, agflbp); | ||
1955 | args->agbp = NULL; | ||
1956 | return 0; | ||
1957 | } | ||
1955 | break; | 1958 | break; |
1959 | } | ||
1956 | /* | 1960 | /* |
1957 | * Put each allocated block on the list. | 1961 | * Put each allocated block on the list. |
1958 | */ | 1962 | */ |
@@ -2360,8 +2364,19 @@ xfs_alloc_vextent( | |||
2360 | if (args->agno == sagno && | 2364 | if (args->agno == sagno && |
2361 | type == XFS_ALLOCTYPE_START_BNO) | 2365 | type == XFS_ALLOCTYPE_START_BNO) |
2362 | args->type = XFS_ALLOCTYPE_THIS_AG; | 2366 | args->type = XFS_ALLOCTYPE_THIS_AG; |
2363 | if (++(args->agno) == mp->m_sb.sb_agcount) | 2367 | /* |
2364 | args->agno = 0; | 2368 | * For the first allocation, we can try any AG to get |
2369 | * space. However, if we already have allocated a | ||
2370 | * block, we don't want to try AGs whose number is below | ||
2371 | * sagno. Otherwise, we may end up with out-of-order | ||
2372 | * locking of AGF, which might cause deadlock. | ||
2373 | */ | ||
2374 | if (++(args->agno) == mp->m_sb.sb_agcount) { | ||
2375 | if (args->firstblock != NULLFSBLOCK) | ||
2376 | args->agno = sagno; | ||
2377 | else | ||
2378 | args->agno = 0; | ||
2379 | } | ||
2365 | /* | 2380 | /* |
2366 | * Reached the starting a.g., must either be done | 2381 | * Reached the starting a.g., must either be done |
2367 | * or switch to non-trylock mode. | 2382 | * or switch to non-trylock mode. |
@@ -2443,7 +2458,7 @@ xfs_free_extent( | |||
2443 | args.minlen = args.minleft = args.minalignslop = 0; | 2458 | args.minlen = args.minleft = args.minalignslop = 0; |
2444 | down_read(&args.mp->m_peraglock); | 2459 | down_read(&args.mp->m_peraglock); |
2445 | args.pag = &args.mp->m_perag[args.agno]; | 2460 | args.pag = &args.mp->m_perag[args.agno]; |
2446 | if ((error = xfs_alloc_fix_freelist(&args, 0))) | 2461 | if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) |
2447 | goto error0; | 2462 | goto error0; |
2448 | #ifdef DEBUG | 2463 | #ifdef DEBUG |
2449 | ASSERT(args.agbp != NULL); | 2464 | ASSERT(args.agbp != NULL); |
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h index 2d1f8928b267..650591f999ae 100644 --- a/fs/xfs/xfs_alloc.h +++ b/fs/xfs/xfs_alloc.h | |||
@@ -41,6 +41,7 @@ typedef enum xfs_alloctype | |||
41 | * Flags for xfs_alloc_fix_freelist. | 41 | * Flags for xfs_alloc_fix_freelist. |
42 | */ | 42 | */ |
43 | #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ | 43 | #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ |
44 | #define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ | ||
44 | 45 | ||
45 | /* | 46 | /* |
46 | * Argument structure for xfs_alloc routines. | 47 | * Argument structure for xfs_alloc routines. |
@@ -70,6 +71,7 @@ typedef struct xfs_alloc_arg { | |||
70 | char wasfromfl; /* set if allocation is from freelist */ | 71 | char wasfromfl; /* set if allocation is from freelist */ |
71 | char isfl; /* set if is freelist blocks - !acctg */ | 72 | char isfl; /* set if is freelist blocks - !acctg */ |
72 | char userdata; /* set if this is user data */ | 73 | char userdata; /* set if this is user data */ |
74 | xfs_fsblock_t firstblock; /* io first block allocated */ | ||
73 | } xfs_alloc_arg_t; | 75 | } xfs_alloc_arg_t; |
74 | 76 | ||
75 | /* | 77 | /* |
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index a1d92da86ccd..7446556e8021 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index b6e1e02bbb28..1a2101043275 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include "xfs_trans.h" | 27 | #include "xfs_trans.h" |
28 | #include "xfs_sb.h" | 28 | #include "xfs_sb.h" |
29 | #include "xfs_ag.h" | 29 | #include "xfs_ag.h" |
30 | #include "xfs_dir.h" | ||
31 | #include "xfs_dir2.h" | 30 | #include "xfs_dir2.h" |
32 | #include "xfs_dmapi.h" | 31 | #include "xfs_dmapi.h" |
33 | #include "xfs_mount.h" | 32 | #include "xfs_mount.h" |
@@ -35,7 +34,6 @@ | |||
35 | #include "xfs_bmap_btree.h" | 34 | #include "xfs_bmap_btree.h" |
36 | #include "xfs_alloc_btree.h" | 35 | #include "xfs_alloc_btree.h" |
37 | #include "xfs_ialloc_btree.h" | 36 | #include "xfs_ialloc_btree.h" |
38 | #include "xfs_dir_sf.h" | ||
39 | #include "xfs_dir2_sf.h" | 37 | #include "xfs_dir2_sf.h" |
40 | #include "xfs_attr_sf.h" | 38 | #include "xfs_attr_sf.h" |
41 | #include "xfs_dinode.h" | 39 | #include "xfs_dinode.h" |
@@ -1910,7 +1908,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args) | |||
1910 | error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, | 1908 | error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, |
1911 | args->rmtblkcnt, | 1909 | args->rmtblkcnt, |
1912 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, | 1910 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, |
1913 | NULL, 0, map, &nmap, NULL); | 1911 | NULL, 0, map, &nmap, NULL, NULL); |
1914 | if (error) | 1912 | if (error) |
1915 | return(error); | 1913 | return(error); |
1916 | ASSERT(nmap >= 1); | 1914 | ASSERT(nmap >= 1); |
@@ -1988,7 +1986,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) | |||
1988 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | | 1986 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | |
1989 | XFS_BMAPI_WRITE, | 1987 | XFS_BMAPI_WRITE, |
1990 | args->firstblock, args->total, &map, &nmap, | 1988 | args->firstblock, args->total, &map, &nmap, |
1991 | args->flist); | 1989 | args->flist, NULL); |
1992 | if (!error) { | 1990 | if (!error) { |
1993 | error = xfs_bmap_finish(&args->trans, args->flist, | 1991 | error = xfs_bmap_finish(&args->trans, args->flist, |
1994 | *args->firstblock, &committed); | 1992 | *args->firstblock, &committed); |
@@ -2039,7 +2037,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) | |||
2039 | error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, | 2037 | error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, |
2040 | args->rmtblkcnt, | 2038 | args->rmtblkcnt, |
2041 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, | 2039 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, |
2042 | args->firstblock, 0, &map, &nmap, NULL); | 2040 | args->firstblock, 0, &map, &nmap, |
2041 | NULL, NULL); | ||
2043 | if (error) { | 2042 | if (error) { |
2044 | return(error); | 2043 | return(error); |
2045 | } | 2044 | } |
@@ -2104,7 +2103,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) | |||
2104 | args->rmtblkcnt, | 2103 | args->rmtblkcnt, |
2105 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, | 2104 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, |
2106 | args->firstblock, 0, &map, &nmap, | 2105 | args->firstblock, 0, &map, &nmap, |
2107 | args->flist); | 2106 | args->flist, NULL); |
2108 | if (error) { | 2107 | if (error) { |
2109 | return(error); | 2108 | return(error); |
2110 | } | 2109 | } |
@@ -2142,7 +2141,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) | |||
2142 | XFS_BMAP_INIT(args->flist, args->firstblock); | 2141 | XFS_BMAP_INIT(args->flist, args->firstblock); |
2143 | error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, | 2142 | error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, |
2144 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, | 2143 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, |
2145 | 1, args->firstblock, args->flist, &done); | 2144 | 1, args->firstblock, args->flist, |
2145 | NULL, &done); | ||
2146 | if (!error) { | 2146 | if (!error) { |
2147 | error = xfs_bmap_finish(&args->trans, args->flist, | 2147 | error = xfs_bmap_finish(&args->trans, args->flist, |
2148 | *args->firstblock, &committed); | 2148 | *args->firstblock, &committed); |
@@ -2322,56 +2322,56 @@ xfs_attr_trace_enter(int type, char *where, | |||
2322 | 2322 | ||
2323 | STATIC int | 2323 | STATIC int |
2324 | posix_acl_access_set( | 2324 | posix_acl_access_set( |
2325 | vnode_t *vp, char *name, void *data, size_t size, int xflags) | 2325 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) |
2326 | { | 2326 | { |
2327 | return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS); | 2327 | return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS); |
2328 | } | 2328 | } |
2329 | 2329 | ||
2330 | STATIC int | 2330 | STATIC int |
2331 | posix_acl_access_remove( | 2331 | posix_acl_access_remove( |
2332 | struct vnode *vp, char *name, int xflags) | 2332 | bhv_vnode_t *vp, char *name, int xflags) |
2333 | { | 2333 | { |
2334 | return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); | 2334 | return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); |
2335 | } | 2335 | } |
2336 | 2336 | ||
2337 | STATIC int | 2337 | STATIC int |
2338 | posix_acl_access_get( | 2338 | posix_acl_access_get( |
2339 | vnode_t *vp, char *name, void *data, size_t size, int xflags) | 2339 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) |
2340 | { | 2340 | { |
2341 | return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS); | 2341 | return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS); |
2342 | } | 2342 | } |
2343 | 2343 | ||
2344 | STATIC int | 2344 | STATIC int |
2345 | posix_acl_access_exists( | 2345 | posix_acl_access_exists( |
2346 | vnode_t *vp) | 2346 | bhv_vnode_t *vp) |
2347 | { | 2347 | { |
2348 | return xfs_acl_vhasacl_access(vp); | 2348 | return xfs_acl_vhasacl_access(vp); |
2349 | } | 2349 | } |
2350 | 2350 | ||
2351 | STATIC int | 2351 | STATIC int |
2352 | posix_acl_default_set( | 2352 | posix_acl_default_set( |
2353 | vnode_t *vp, char *name, void *data, size_t size, int xflags) | 2353 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) |
2354 | { | 2354 | { |
2355 | return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT); | 2355 | return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT); |
2356 | } | 2356 | } |
2357 | 2357 | ||
2358 | STATIC int | 2358 | STATIC int |
2359 | posix_acl_default_get( | 2359 | posix_acl_default_get( |
2360 | vnode_t *vp, char *name, void *data, size_t size, int xflags) | 2360 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) |
2361 | { | 2361 | { |
2362 | return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT); | 2362 | return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT); |
2363 | } | 2363 | } |
2364 | 2364 | ||
2365 | STATIC int | 2365 | STATIC int |
2366 | posix_acl_default_remove( | 2366 | posix_acl_default_remove( |
2367 | struct vnode *vp, char *name, int xflags) | 2367 | bhv_vnode_t *vp, char *name, int xflags) |
2368 | { | 2368 | { |
2369 | return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT); | 2369 | return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT); |
2370 | } | 2370 | } |
2371 | 2371 | ||
2372 | STATIC int | 2372 | STATIC int |
2373 | posix_acl_default_exists( | 2373 | posix_acl_default_exists( |
2374 | vnode_t *vp) | 2374 | bhv_vnode_t *vp) |
2375 | { | 2375 | { |
2376 | return xfs_acl_vhasacl_default(vp); | 2376 | return xfs_acl_vhasacl_default(vp); |
2377 | } | 2377 | } |
@@ -2404,21 +2404,18 @@ STATIC struct attrnames *attr_system_names[] = | |||
2404 | 2404 | ||
2405 | STATIC int | 2405 | STATIC int |
2406 | attr_generic_set( | 2406 | attr_generic_set( |
2407 | struct vnode *vp, char *name, void *data, size_t size, int xflags) | 2407 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) |
2408 | { | 2408 | { |
2409 | int error; | 2409 | return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL); |
2410 | |||
2411 | VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error); | ||
2412 | return -error; | ||
2413 | } | 2410 | } |
2414 | 2411 | ||
2415 | STATIC int | 2412 | STATIC int |
2416 | attr_generic_get( | 2413 | attr_generic_get( |
2417 | struct vnode *vp, char *name, void *data, size_t size, int xflags) | 2414 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) |
2418 | { | 2415 | { |
2419 | int error, asize = size; | 2416 | int error, asize = size; |
2420 | 2417 | ||
2421 | VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error); | 2418 | error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL); |
2422 | if (!error) | 2419 | if (!error) |
2423 | return asize; | 2420 | return asize; |
2424 | return -error; | 2421 | return -error; |
@@ -2426,12 +2423,9 @@ attr_generic_get( | |||
2426 | 2423 | ||
2427 | STATIC int | 2424 | STATIC int |
2428 | attr_generic_remove( | 2425 | attr_generic_remove( |
2429 | struct vnode *vp, char *name, int xflags) | 2426 | bhv_vnode_t *vp, char *name, int xflags) |
2430 | { | 2427 | { |
2431 | int error; | 2428 | return -bhv_vop_attr_remove(vp, name, xflags, NULL); |
2432 | |||
2433 | VOP_ATTR_REMOVE(vp, name, xflags, NULL, error); | ||
2434 | return -error; | ||
2435 | } | 2429 | } |
2436 | 2430 | ||
2437 | STATIC int | 2431 | STATIC int |
@@ -2459,7 +2453,7 @@ attr_generic_listadd( | |||
2459 | 2453 | ||
2460 | STATIC int | 2454 | STATIC int |
2461 | attr_system_list( | 2455 | attr_system_list( |
2462 | struct vnode *vp, | 2456 | bhv_vnode_t *vp, |
2463 | void *data, | 2457 | void *data, |
2464 | size_t size, | 2458 | size_t size, |
2465 | ssize_t *result) | 2459 | ssize_t *result) |
@@ -2481,12 +2475,12 @@ attr_system_list( | |||
2481 | 2475 | ||
2482 | int | 2476 | int |
2483 | attr_generic_list( | 2477 | attr_generic_list( |
2484 | struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result) | 2478 | bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result) |
2485 | { | 2479 | { |
2486 | attrlist_cursor_kern_t cursor = { 0 }; | 2480 | attrlist_cursor_kern_t cursor = { 0 }; |
2487 | int error; | 2481 | int error; |
2488 | 2482 | ||
2489 | VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error); | 2483 | error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL); |
2490 | if (error > 0) | 2484 | if (error > 0) |
2491 | return -error; | 2485 | return -error; |
2492 | *result = -error; | 2486 | *result = -error; |
@@ -2514,7 +2508,7 @@ attr_lookup_namespace( | |||
2514 | */ | 2508 | */ |
2515 | STATIC int | 2509 | STATIC int |
2516 | attr_user_capable( | 2510 | attr_user_capable( |
2517 | struct vnode *vp, | 2511 | bhv_vnode_t *vp, |
2518 | cred_t *cred) | 2512 | cred_t *cred) |
2519 | { | 2513 | { |
2520 | struct inode *inode = vn_to_inode(vp); | 2514 | struct inode *inode = vn_to_inode(vp); |
@@ -2532,7 +2526,7 @@ attr_user_capable( | |||
2532 | 2526 | ||
2533 | STATIC int | 2527 | STATIC int |
2534 | attr_trusted_capable( | 2528 | attr_trusted_capable( |
2535 | struct vnode *vp, | 2529 | bhv_vnode_t *vp, |
2536 | cred_t *cred) | 2530 | cred_t *cred) |
2537 | { | 2531 | { |
2538 | struct inode *inode = vn_to_inode(vp); | 2532 | struct inode *inode = vn_to_inode(vp); |
@@ -2546,7 +2540,7 @@ attr_trusted_capable( | |||
2546 | 2540 | ||
2547 | STATIC int | 2541 | STATIC int |
2548 | attr_secure_capable( | 2542 | attr_secure_capable( |
2549 | struct vnode *vp, | 2543 | bhv_vnode_t *vp, |
2550 | cred_t *cred) | 2544 | cred_t *cred) |
2551 | { | 2545 | { |
2552 | return -ENOSECURITY; | 2546 | return -ENOSECURITY; |
@@ -2554,7 +2548,7 @@ attr_secure_capable( | |||
2554 | 2548 | ||
2555 | STATIC int | 2549 | STATIC int |
2556 | attr_system_set( | 2550 | attr_system_set( |
2557 | struct vnode *vp, char *name, void *data, size_t size, int xflags) | 2551 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) |
2558 | { | 2552 | { |
2559 | attrnames_t *namesp; | 2553 | attrnames_t *namesp; |
2560 | int error; | 2554 | int error; |
@@ -2573,7 +2567,7 @@ attr_system_set( | |||
2573 | 2567 | ||
2574 | STATIC int | 2568 | STATIC int |
2575 | attr_system_get( | 2569 | attr_system_get( |
2576 | struct vnode *vp, char *name, void *data, size_t size, int xflags) | 2570 | bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags) |
2577 | { | 2571 | { |
2578 | attrnames_t *namesp; | 2572 | attrnames_t *namesp; |
2579 | 2573 | ||
@@ -2585,7 +2579,7 @@ attr_system_get( | |||
2585 | 2579 | ||
2586 | STATIC int | 2580 | STATIC int |
2587 | attr_system_remove( | 2581 | attr_system_remove( |
2588 | struct vnode *vp, char *name, int xflags) | 2582 | bhv_vnode_t *vp, char *name, int xflags) |
2589 | { | 2583 | { |
2590 | attrnames_t *namesp; | 2584 | attrnames_t *namesp; |
2591 | 2585 | ||
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index b2c7b9fcded3..981633f6c077 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h | |||
@@ -36,13 +36,13 @@ | |||
36 | *========================================================================*/ | 36 | *========================================================================*/ |
37 | 37 | ||
38 | struct cred; | 38 | struct cred; |
39 | struct vnode; | 39 | struct bhv_vnode; |
40 | 40 | ||
41 | typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int); | 41 | typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int); |
42 | typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int); | 42 | typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int); |
43 | typedef int (*attrremove_t)(struct vnode *, char *, int); | 43 | typedef int (*attrremove_t)(struct bhv_vnode *, char *, int); |
44 | typedef int (*attrexists_t)(struct vnode *); | 44 | typedef int (*attrexists_t)(struct bhv_vnode *); |
45 | typedef int (*attrcapable_t)(struct vnode *, struct cred *); | 45 | typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *); |
46 | 46 | ||
47 | typedef struct attrnames { | 47 | typedef struct attrnames { |
48 | char * attr_name; | 48 | char * attr_name; |
@@ -63,7 +63,7 @@ extern struct attrnames attr_trusted; | |||
63 | extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; | 63 | extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; |
64 | 64 | ||
65 | extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); | 65 | extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); |
66 | extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); | 66 | extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *); |
67 | 67 | ||
68 | #define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ | 68 | #define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ |
69 | #define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ | 69 | #define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 9462be86aa14..9455051f0120 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
@@ -34,7 +33,6 @@ | |||
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_alloc.h" | 34 | #include "xfs_alloc.h" |
36 | #include "xfs_btree.h" | 35 | #include "xfs_btree.h" |
37 | #include "xfs_dir_sf.h" | ||
38 | #include "xfs_dir2_sf.h" | 36 | #include "xfs_dir2_sf.h" |
39 | #include "xfs_attr_sf.h" | 37 | #include "xfs_attr_sf.h" |
40 | #include "xfs_dinode.h" | 38 | #include "xfs_dinode.h" |
@@ -2990,7 +2988,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, | |||
2990 | nmap = 1; | 2988 | nmap = 1; |
2991 | error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt, | 2989 | error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt, |
2992 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, | 2990 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, |
2993 | NULL, 0, &map, &nmap, NULL); | 2991 | NULL, 0, &map, &nmap, NULL, NULL); |
2994 | if (error) { | 2992 | if (error) { |
2995 | return(error); | 2993 | return(error); |
2996 | } | 2994 | } |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 26939d364bc4..3a6137539064 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -24,13 +24,11 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
31 | #include "xfs_alloc_btree.h" | 30 | #include "xfs_alloc_btree.h" |
32 | #include "xfs_ialloc_btree.h" | 31 | #include "xfs_ialloc_btree.h" |
33 | #include "xfs_dir_sf.h" | ||
34 | #include "xfs_dir2_sf.h" | 32 | #include "xfs_dir2_sf.h" |
35 | #include "xfs_attr_sf.h" | 33 | #include "xfs_attr_sf.h" |
36 | #include "xfs_dinode.h" | 34 | #include "xfs_dinode.h" |
@@ -40,13 +38,15 @@ | |||
40 | #include "xfs_mount.h" | 38 | #include "xfs_mount.h" |
41 | #include "xfs_ialloc.h" | 39 | #include "xfs_ialloc.h" |
42 | #include "xfs_itable.h" | 40 | #include "xfs_itable.h" |
41 | #include "xfs_dir2_data.h" | ||
42 | #include "xfs_dir2_leaf.h" | ||
43 | #include "xfs_dir2_block.h" | ||
43 | #include "xfs_inode_item.h" | 44 | #include "xfs_inode_item.h" |
44 | #include "xfs_extfree_item.h" | 45 | #include "xfs_extfree_item.h" |
45 | #include "xfs_alloc.h" | 46 | #include "xfs_alloc.h" |
46 | #include "xfs_bmap.h" | 47 | #include "xfs_bmap.h" |
47 | #include "xfs_rtalloc.h" | 48 | #include "xfs_rtalloc.h" |
48 | #include "xfs_error.h" | 49 | #include "xfs_error.h" |
49 | #include "xfs_dir_leaf.h" | ||
50 | #include "xfs_attr_leaf.h" | 50 | #include "xfs_attr_leaf.h" |
51 | #include "xfs_rw.h" | 51 | #include "xfs_rw.h" |
52 | #include "xfs_quota.h" | 52 | #include "xfs_quota.h" |
@@ -101,6 +101,7 @@ xfs_bmap_add_extent( | |||
101 | xfs_fsblock_t *first, /* pointer to firstblock variable */ | 101 | xfs_fsblock_t *first, /* pointer to firstblock variable */ |
102 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | 102 | xfs_bmap_free_t *flist, /* list of extents to be freed */ |
103 | int *logflagsp, /* inode logging flags */ | 103 | int *logflagsp, /* inode logging flags */ |
104 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
104 | int whichfork, /* data or attr fork */ | 105 | int whichfork, /* data or attr fork */ |
105 | int rsvd); /* OK to allocate reserved blocks */ | 106 | int rsvd); /* OK to allocate reserved blocks */ |
106 | 107 | ||
@@ -118,6 +119,7 @@ xfs_bmap_add_extent_delay_real( | |||
118 | xfs_fsblock_t *first, /* pointer to firstblock variable */ | 119 | xfs_fsblock_t *first, /* pointer to firstblock variable */ |
119 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | 120 | xfs_bmap_free_t *flist, /* list of extents to be freed */ |
120 | int *logflagsp, /* inode logging flags */ | 121 | int *logflagsp, /* inode logging flags */ |
122 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
121 | int rsvd); /* OK to allocate reserved blocks */ | 123 | int rsvd); /* OK to allocate reserved blocks */ |
122 | 124 | ||
123 | /* | 125 | /* |
@@ -131,6 +133,7 @@ xfs_bmap_add_extent_hole_delay( | |||
131 | xfs_btree_cur_t *cur, /* if null, not a btree */ | 133 | xfs_btree_cur_t *cur, /* if null, not a btree */ |
132 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 134 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
133 | int *logflagsp,/* inode logging flags */ | 135 | int *logflagsp,/* inode logging flags */ |
136 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
134 | int rsvd); /* OK to allocate reserved blocks */ | 137 | int rsvd); /* OK to allocate reserved blocks */ |
135 | 138 | ||
136 | /* | 139 | /* |
@@ -144,6 +147,7 @@ xfs_bmap_add_extent_hole_real( | |||
144 | xfs_btree_cur_t *cur, /* if null, not a btree */ | 147 | xfs_btree_cur_t *cur, /* if null, not a btree */ |
145 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 148 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
146 | int *logflagsp, /* inode logging flags */ | 149 | int *logflagsp, /* inode logging flags */ |
150 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
147 | int whichfork); /* data or attr fork */ | 151 | int whichfork); /* data or attr fork */ |
148 | 152 | ||
149 | /* | 153 | /* |
@@ -156,7 +160,8 @@ xfs_bmap_add_extent_unwritten_real( | |||
156 | xfs_extnum_t idx, /* extent number to update/insert */ | 160 | xfs_extnum_t idx, /* extent number to update/insert */ |
157 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ | 161 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ |
158 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 162 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
159 | int *logflagsp); /* inode logging flags */ | 163 | int *logflagsp, /* inode logging flags */ |
164 | xfs_extdelta_t *delta); /* Change made to incore extents */ | ||
160 | 165 | ||
161 | /* | 166 | /* |
162 | * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. | 167 | * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. |
@@ -203,6 +208,7 @@ xfs_bmap_del_extent( | |||
203 | xfs_btree_cur_t *cur, /* if null, not a btree */ | 208 | xfs_btree_cur_t *cur, /* if null, not a btree */ |
204 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 209 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
205 | int *logflagsp,/* inode logging flags */ | 210 | int *logflagsp,/* inode logging flags */ |
211 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
206 | int whichfork, /* data or attr fork */ | 212 | int whichfork, /* data or attr fork */ |
207 | int rsvd); /* OK to allocate reserved blocks */ | 213 | int rsvd); /* OK to allocate reserved blocks */ |
208 | 214 | ||
@@ -510,7 +516,7 @@ xfs_bmap_add_attrfork_local( | |||
510 | dargs.total = mp->m_dirblkfsbs; | 516 | dargs.total = mp->m_dirblkfsbs; |
511 | dargs.whichfork = XFS_DATA_FORK; | 517 | dargs.whichfork = XFS_DATA_FORK; |
512 | dargs.trans = tp; | 518 | dargs.trans = tp; |
513 | error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs); | 519 | error = xfs_dir2_sf_to_block(&dargs); |
514 | } else | 520 | } else |
515 | error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, | 521 | error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, |
516 | XFS_DATA_FORK); | 522 | XFS_DATA_FORK); |
@@ -530,6 +536,7 @@ xfs_bmap_add_extent( | |||
530 | xfs_fsblock_t *first, /* pointer to firstblock variable */ | 536 | xfs_fsblock_t *first, /* pointer to firstblock variable */ |
531 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | 537 | xfs_bmap_free_t *flist, /* list of extents to be freed */ |
532 | int *logflagsp, /* inode logging flags */ | 538 | int *logflagsp, /* inode logging flags */ |
539 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
533 | int whichfork, /* data or attr fork */ | 540 | int whichfork, /* data or attr fork */ |
534 | int rsvd) /* OK to use reserved data blocks */ | 541 | int rsvd) /* OK to use reserved data blocks */ |
535 | { | 542 | { |
@@ -567,6 +574,15 @@ xfs_bmap_add_extent( | |||
567 | logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); | 574 | logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); |
568 | } else | 575 | } else |
569 | logflags = 0; | 576 | logflags = 0; |
577 | /* DELTA: single new extent */ | ||
578 | if (delta) { | ||
579 | if (delta->xed_startoff > new->br_startoff) | ||
580 | delta->xed_startoff = new->br_startoff; | ||
581 | if (delta->xed_blockcount < | ||
582 | new->br_startoff + new->br_blockcount) | ||
583 | delta->xed_blockcount = new->br_startoff + | ||
584 | new->br_blockcount; | ||
585 | } | ||
570 | } | 586 | } |
571 | /* | 587 | /* |
572 | * Any kind of new delayed allocation goes here. | 588 | * Any kind of new delayed allocation goes here. |
@@ -576,7 +592,7 @@ xfs_bmap_add_extent( | |||
576 | ASSERT((cur->bc_private.b.flags & | 592 | ASSERT((cur->bc_private.b.flags & |
577 | XFS_BTCUR_BPRV_WASDEL) == 0); | 593 | XFS_BTCUR_BPRV_WASDEL) == 0); |
578 | if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, | 594 | if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, |
579 | &logflags, rsvd))) | 595 | &logflags, delta, rsvd))) |
580 | goto done; | 596 | goto done; |
581 | } | 597 | } |
582 | /* | 598 | /* |
@@ -587,7 +603,7 @@ xfs_bmap_add_extent( | |||
587 | ASSERT((cur->bc_private.b.flags & | 603 | ASSERT((cur->bc_private.b.flags & |
588 | XFS_BTCUR_BPRV_WASDEL) == 0); | 604 | XFS_BTCUR_BPRV_WASDEL) == 0); |
589 | if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, | 605 | if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, |
590 | &logflags, whichfork))) | 606 | &logflags, delta, whichfork))) |
591 | goto done; | 607 | goto done; |
592 | } else { | 608 | } else { |
593 | xfs_bmbt_irec_t prev; /* old extent at offset idx */ | 609 | xfs_bmbt_irec_t prev; /* old extent at offset idx */ |
@@ -612,17 +628,17 @@ xfs_bmap_add_extent( | |||
612 | XFS_BTCUR_BPRV_WASDEL); | 628 | XFS_BTCUR_BPRV_WASDEL); |
613 | if ((error = xfs_bmap_add_extent_delay_real(ip, | 629 | if ((error = xfs_bmap_add_extent_delay_real(ip, |
614 | idx, &cur, new, &da_new, first, flist, | 630 | idx, &cur, new, &da_new, first, flist, |
615 | &logflags, rsvd))) | 631 | &logflags, delta, rsvd))) |
616 | goto done; | 632 | goto done; |
617 | } else if (new->br_state == XFS_EXT_NORM) { | 633 | } else if (new->br_state == XFS_EXT_NORM) { |
618 | ASSERT(new->br_state == XFS_EXT_NORM); | 634 | ASSERT(new->br_state == XFS_EXT_NORM); |
619 | if ((error = xfs_bmap_add_extent_unwritten_real( | 635 | if ((error = xfs_bmap_add_extent_unwritten_real( |
620 | ip, idx, &cur, new, &logflags))) | 636 | ip, idx, &cur, new, &logflags, delta))) |
621 | goto done; | 637 | goto done; |
622 | } else { | 638 | } else { |
623 | ASSERT(new->br_state == XFS_EXT_UNWRITTEN); | 639 | ASSERT(new->br_state == XFS_EXT_UNWRITTEN); |
624 | if ((error = xfs_bmap_add_extent_unwritten_real( | 640 | if ((error = xfs_bmap_add_extent_unwritten_real( |
625 | ip, idx, &cur, new, &logflags))) | 641 | ip, idx, &cur, new, &logflags, delta))) |
626 | goto done; | 642 | goto done; |
627 | } | 643 | } |
628 | ASSERT(*curp == cur || *curp == NULL); | 644 | ASSERT(*curp == cur || *curp == NULL); |
@@ -635,7 +651,7 @@ xfs_bmap_add_extent( | |||
635 | ASSERT((cur->bc_private.b.flags & | 651 | ASSERT((cur->bc_private.b.flags & |
636 | XFS_BTCUR_BPRV_WASDEL) == 0); | 652 | XFS_BTCUR_BPRV_WASDEL) == 0); |
637 | if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, | 653 | if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, |
638 | new, &logflags, whichfork))) | 654 | new, &logflags, delta, whichfork))) |
639 | goto done; | 655 | goto done; |
640 | } | 656 | } |
641 | } | 657 | } |
@@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real( | |||
700 | xfs_fsblock_t *first, /* pointer to firstblock variable */ | 716 | xfs_fsblock_t *first, /* pointer to firstblock variable */ |
701 | xfs_bmap_free_t *flist, /* list of extents to be freed */ | 717 | xfs_bmap_free_t *flist, /* list of extents to be freed */ |
702 | int *logflagsp, /* inode logging flags */ | 718 | int *logflagsp, /* inode logging flags */ |
719 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
703 | int rsvd) /* OK to use reserved data block allocation */ | 720 | int rsvd) /* OK to use reserved data block allocation */ |
704 | { | 721 | { |
705 | xfs_btree_cur_t *cur; /* btree cursor */ | 722 | xfs_btree_cur_t *cur; /* btree cursor */ |
@@ -716,8 +733,8 @@ xfs_bmap_add_extent_delay_real( | |||
716 | /* left is 0, right is 1, prev is 2 */ | 733 | /* left is 0, right is 1, prev is 2 */ |
717 | int rval=0; /* return value (logging flags) */ | 734 | int rval=0; /* return value (logging flags) */ |
718 | int state = 0;/* state bits, accessed thru macros */ | 735 | int state = 0;/* state bits, accessed thru macros */ |
719 | xfs_filblks_t temp; /* value for dnew calculations */ | 736 | xfs_filblks_t temp=0; /* value for dnew calculations */ |
720 | xfs_filblks_t temp2; /* value for dnew calculations */ | 737 | xfs_filblks_t temp2=0;/* value for dnew calculations */ |
721 | int tmp_rval; /* partial logging flags */ | 738 | int tmp_rval; /* partial logging flags */ |
722 | enum { /* bit number definitions for state */ | 739 | enum { /* bit number definitions for state */ |
723 | LEFT_CONTIG, RIGHT_CONTIG, | 740 | LEFT_CONTIG, RIGHT_CONTIG, |
@@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real( | |||
839 | goto done; | 856 | goto done; |
840 | } | 857 | } |
841 | *dnew = 0; | 858 | *dnew = 0; |
859 | /* DELTA: Three in-core extents are replaced by one. */ | ||
860 | temp = LEFT.br_startoff; | ||
861 | temp2 = LEFT.br_blockcount + | ||
862 | PREV.br_blockcount + | ||
863 | RIGHT.br_blockcount; | ||
842 | break; | 864 | break; |
843 | 865 | ||
844 | case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): | 866 | case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): |
@@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real( | |||
872 | goto done; | 894 | goto done; |
873 | } | 895 | } |
874 | *dnew = 0; | 896 | *dnew = 0; |
897 | /* DELTA: Two in-core extents are replaced by one. */ | ||
898 | temp = LEFT.br_startoff; | ||
899 | temp2 = LEFT.br_blockcount + | ||
900 | PREV.br_blockcount; | ||
875 | break; | 901 | break; |
876 | 902 | ||
877 | case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): | 903 | case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): |
@@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real( | |||
906 | goto done; | 932 | goto done; |
907 | } | 933 | } |
908 | *dnew = 0; | 934 | *dnew = 0; |
935 | /* DELTA: Two in-core extents are replaced by one. */ | ||
936 | temp = PREV.br_startoff; | ||
937 | temp2 = PREV.br_blockcount + | ||
938 | RIGHT.br_blockcount; | ||
909 | break; | 939 | break; |
910 | 940 | ||
911 | case MASK2(LEFT_FILLING, RIGHT_FILLING): | 941 | case MASK2(LEFT_FILLING, RIGHT_FILLING): |
@@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real( | |||
936 | ASSERT(i == 1); | 966 | ASSERT(i == 1); |
937 | } | 967 | } |
938 | *dnew = 0; | 968 | *dnew = 0; |
969 | /* DELTA: The in-core extent described by new changed type. */ | ||
970 | temp = new->br_startoff; | ||
971 | temp2 = new->br_blockcount; | ||
939 | break; | 972 | break; |
940 | 973 | ||
941 | case MASK2(LEFT_FILLING, LEFT_CONTIG): | 974 | case MASK2(LEFT_FILLING, LEFT_CONTIG): |
@@ -978,6 +1011,10 @@ xfs_bmap_add_extent_delay_real( | |||
978 | xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, | 1011 | xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, |
979 | XFS_DATA_FORK); | 1012 | XFS_DATA_FORK); |
980 | *dnew = temp; | 1013 | *dnew = temp; |
1014 | /* DELTA: The boundary between two in-core extents moved. */ | ||
1015 | temp = LEFT.br_startoff; | ||
1016 | temp2 = LEFT.br_blockcount + | ||
1017 | PREV.br_blockcount; | ||
981 | break; | 1018 | break; |
982 | 1019 | ||
983 | case MASK(LEFT_FILLING): | 1020 | case MASK(LEFT_FILLING): |
@@ -1025,6 +1062,9 @@ xfs_bmap_add_extent_delay_real( | |||
1025 | xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, | 1062 | xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, |
1026 | XFS_DATA_FORK); | 1063 | XFS_DATA_FORK); |
1027 | *dnew = temp; | 1064 | *dnew = temp; |
1065 | /* DELTA: One in-core extent is split in two. */ | ||
1066 | temp = PREV.br_startoff; | ||
1067 | temp2 = PREV.br_blockcount; | ||
1028 | break; | 1068 | break; |
1029 | 1069 | ||
1030 | case MASK2(RIGHT_FILLING, RIGHT_CONTIG): | 1070 | case MASK2(RIGHT_FILLING, RIGHT_CONTIG): |
@@ -1067,6 +1107,10 @@ xfs_bmap_add_extent_delay_real( | |||
1067 | xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, | 1107 | xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, |
1068 | XFS_DATA_FORK); | 1108 | XFS_DATA_FORK); |
1069 | *dnew = temp; | 1109 | *dnew = temp; |
1110 | /* DELTA: The boundary between two in-core extents moved. */ | ||
1111 | temp = PREV.br_startoff; | ||
1112 | temp2 = PREV.br_blockcount + | ||
1113 | RIGHT.br_blockcount; | ||
1070 | break; | 1114 | break; |
1071 | 1115 | ||
1072 | case MASK(RIGHT_FILLING): | 1116 | case MASK(RIGHT_FILLING): |
@@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real( | |||
1112 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); | 1156 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); |
1113 | xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); | 1157 | xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); |
1114 | *dnew = temp; | 1158 | *dnew = temp; |
1159 | /* DELTA: One in-core extent is split in two. */ | ||
1160 | temp = PREV.br_startoff; | ||
1161 | temp2 = PREV.br_blockcount; | ||
1115 | break; | 1162 | break; |
1116 | 1163 | ||
1117 | case 0: | 1164 | case 0: |
@@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real( | |||
1194 | xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, | 1241 | xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, |
1195 | XFS_DATA_FORK); | 1242 | XFS_DATA_FORK); |
1196 | *dnew = temp + temp2; | 1243 | *dnew = temp + temp2; |
1244 | /* DELTA: One in-core extent is split in three. */ | ||
1245 | temp = PREV.br_startoff; | ||
1246 | temp2 = PREV.br_blockcount; | ||
1197 | break; | 1247 | break; |
1198 | 1248 | ||
1199 | case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): | 1249 | case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): |
@@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real( | |||
1209 | ASSERT(0); | 1259 | ASSERT(0); |
1210 | } | 1260 | } |
1211 | *curp = cur; | 1261 | *curp = cur; |
1262 | if (delta) { | ||
1263 | temp2 += temp; | ||
1264 | if (delta->xed_startoff > temp) | ||
1265 | delta->xed_startoff = temp; | ||
1266 | if (delta->xed_blockcount < temp2) | ||
1267 | delta->xed_blockcount = temp2; | ||
1268 | } | ||
1212 | done: | 1269 | done: |
1213 | *logflagsp = rval; | 1270 | *logflagsp = rval; |
1214 | return error; | 1271 | return error; |
@@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real( | |||
1235 | xfs_extnum_t idx, /* extent number to update/insert */ | 1292 | xfs_extnum_t idx, /* extent number to update/insert */ |
1236 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ | 1293 | xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ |
1237 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 1294 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
1238 | int *logflagsp) /* inode logging flags */ | 1295 | int *logflagsp, /* inode logging flags */ |
1296 | xfs_extdelta_t *delta) /* Change made to incore extents */ | ||
1239 | { | 1297 | { |
1240 | xfs_btree_cur_t *cur; /* btree cursor */ | 1298 | xfs_btree_cur_t *cur; /* btree cursor */ |
1241 | xfs_bmbt_rec_t *ep; /* extent entry for idx */ | 1299 | xfs_bmbt_rec_t *ep; /* extent entry for idx */ |
@@ -1252,6 +1310,8 @@ xfs_bmap_add_extent_unwritten_real( | |||
1252 | /* left is 0, right is 1, prev is 2 */ | 1310 | /* left is 0, right is 1, prev is 2 */ |
1253 | int rval=0; /* return value (logging flags) */ | 1311 | int rval=0; /* return value (logging flags) */ |
1254 | int state = 0;/* state bits, accessed thru macros */ | 1312 | int state = 0;/* state bits, accessed thru macros */ |
1313 | xfs_filblks_t temp=0; | ||
1314 | xfs_filblks_t temp2=0; | ||
1255 | enum { /* bit number definitions for state */ | 1315 | enum { /* bit number definitions for state */ |
1256 | LEFT_CONTIG, RIGHT_CONTIG, | 1316 | LEFT_CONTIG, RIGHT_CONTIG, |
1257 | LEFT_FILLING, RIGHT_FILLING, | 1317 | LEFT_FILLING, RIGHT_FILLING, |
@@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real( | |||
1380 | RIGHT.br_blockcount, LEFT.br_state))) | 1440 | RIGHT.br_blockcount, LEFT.br_state))) |
1381 | goto done; | 1441 | goto done; |
1382 | } | 1442 | } |
1443 | /* DELTA: Three in-core extents are replaced by one. */ | ||
1444 | temp = LEFT.br_startoff; | ||
1445 | temp2 = LEFT.br_blockcount + | ||
1446 | PREV.br_blockcount + | ||
1447 | RIGHT.br_blockcount; | ||
1383 | break; | 1448 | break; |
1384 | 1449 | ||
1385 | case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): | 1450 | case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): |
@@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real( | |||
1419 | LEFT.br_state))) | 1484 | LEFT.br_state))) |
1420 | goto done; | 1485 | goto done; |
1421 | } | 1486 | } |
1487 | /* DELTA: Two in-core extents are replaced by one. */ | ||
1488 | temp = LEFT.br_startoff; | ||
1489 | temp2 = LEFT.br_blockcount + | ||
1490 | PREV.br_blockcount; | ||
1422 | break; | 1491 | break; |
1423 | 1492 | ||
1424 | case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): | 1493 | case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): |
@@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real( | |||
1459 | newext))) | 1528 | newext))) |
1460 | goto done; | 1529 | goto done; |
1461 | } | 1530 | } |
1531 | /* DELTA: Two in-core extents are replaced by one. */ | ||
1532 | temp = PREV.br_startoff; | ||
1533 | temp2 = PREV.br_blockcount + | ||
1534 | RIGHT.br_blockcount; | ||
1462 | break; | 1535 | break; |
1463 | 1536 | ||
1464 | case MASK2(LEFT_FILLING, RIGHT_FILLING): | 1537 | case MASK2(LEFT_FILLING, RIGHT_FILLING): |
@@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real( | |||
1487 | newext))) | 1560 | newext))) |
1488 | goto done; | 1561 | goto done; |
1489 | } | 1562 | } |
1563 | /* DELTA: The in-core extent described by new changed type. */ | ||
1564 | temp = new->br_startoff; | ||
1565 | temp2 = new->br_blockcount; | ||
1490 | break; | 1566 | break; |
1491 | 1567 | ||
1492 | case MASK2(LEFT_FILLING, LEFT_CONTIG): | 1568 | case MASK2(LEFT_FILLING, LEFT_CONTIG): |
@@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real( | |||
1534 | LEFT.br_state)) | 1610 | LEFT.br_state)) |
1535 | goto done; | 1611 | goto done; |
1536 | } | 1612 | } |
1613 | /* DELTA: The boundary between two in-core extents moved. */ | ||
1614 | temp = LEFT.br_startoff; | ||
1615 | temp2 = LEFT.br_blockcount + | ||
1616 | PREV.br_blockcount; | ||
1537 | break; | 1617 | break; |
1538 | 1618 | ||
1539 | case MASK(LEFT_FILLING): | 1619 | case MASK(LEFT_FILLING): |
@@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real( | |||
1574 | goto done; | 1654 | goto done; |
1575 | ASSERT(i == 1); | 1655 | ASSERT(i == 1); |
1576 | } | 1656 | } |
1657 | /* DELTA: One in-core extent is split in two. */ | ||
1658 | temp = PREV.br_startoff; | ||
1659 | temp2 = PREV.br_blockcount; | ||
1577 | break; | 1660 | break; |
1578 | 1661 | ||
1579 | case MASK2(RIGHT_FILLING, RIGHT_CONTIG): | 1662 | case MASK2(RIGHT_FILLING, RIGHT_CONTIG): |
@@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real( | |||
1617 | newext))) | 1700 | newext))) |
1618 | goto done; | 1701 | goto done; |
1619 | } | 1702 | } |
1703 | /* DELTA: The boundary between two in-core extents moved. */ | ||
1704 | temp = PREV.br_startoff; | ||
1705 | temp2 = PREV.br_blockcount + | ||
1706 | RIGHT.br_blockcount; | ||
1620 | break; | 1707 | break; |
1621 | 1708 | ||
1622 | case MASK(RIGHT_FILLING): | 1709 | case MASK(RIGHT_FILLING): |
@@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real( | |||
1657 | goto done; | 1744 | goto done; |
1658 | ASSERT(i == 1); | 1745 | ASSERT(i == 1); |
1659 | } | 1746 | } |
1747 | /* DELTA: One in-core extent is split in two. */ | ||
1748 | temp = PREV.br_startoff; | ||
1749 | temp2 = PREV.br_blockcount; | ||
1660 | break; | 1750 | break; |
1661 | 1751 | ||
1662 | case 0: | 1752 | case 0: |
@@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real( | |||
1710 | goto done; | 1800 | goto done; |
1711 | ASSERT(i == 1); | 1801 | ASSERT(i == 1); |
1712 | } | 1802 | } |
1803 | /* DELTA: One in-core extent is split in three. */ | ||
1804 | temp = PREV.br_startoff; | ||
1805 | temp2 = PREV.br_blockcount; | ||
1713 | break; | 1806 | break; |
1714 | 1807 | ||
1715 | case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): | 1808 | case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): |
@@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real( | |||
1725 | ASSERT(0); | 1818 | ASSERT(0); |
1726 | } | 1819 | } |
1727 | *curp = cur; | 1820 | *curp = cur; |
1821 | if (delta) { | ||
1822 | temp2 += temp; | ||
1823 | if (delta->xed_startoff > temp) | ||
1824 | delta->xed_startoff = temp; | ||
1825 | if (delta->xed_blockcount < temp2) | ||
1826 | delta->xed_blockcount = temp2; | ||
1827 | } | ||
1728 | done: | 1828 | done: |
1729 | *logflagsp = rval; | 1829 | *logflagsp = rval; |
1730 | return error; | 1830 | return error; |
@@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay( | |||
1753 | xfs_btree_cur_t *cur, /* if null, not a btree */ | 1853 | xfs_btree_cur_t *cur, /* if null, not a btree */ |
1754 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 1854 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
1755 | int *logflagsp, /* inode logging flags */ | 1855 | int *logflagsp, /* inode logging flags */ |
1856 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
1756 | int rsvd) /* OK to allocate reserved blocks */ | 1857 | int rsvd) /* OK to allocate reserved blocks */ |
1757 | { | 1858 | { |
1758 | xfs_bmbt_rec_t *ep; /* extent record for idx */ | 1859 | xfs_bmbt_rec_t *ep; /* extent record for idx */ |
@@ -1765,7 +1866,8 @@ xfs_bmap_add_extent_hole_delay( | |||
1765 | xfs_filblks_t oldlen=0; /* old indirect size */ | 1866 | xfs_filblks_t oldlen=0; /* old indirect size */ |
1766 | xfs_bmbt_irec_t right; /* right neighbor extent entry */ | 1867 | xfs_bmbt_irec_t right; /* right neighbor extent entry */ |
1767 | int state; /* state bits, accessed thru macros */ | 1868 | int state; /* state bits, accessed thru macros */ |
1768 | xfs_filblks_t temp; /* temp for indirect calculations */ | 1869 | xfs_filblks_t temp=0; /* temp for indirect calculations */ |
1870 | xfs_filblks_t temp2=0; | ||
1769 | enum { /* bit number definitions for state */ | 1871 | enum { /* bit number definitions for state */ |
1770 | LEFT_CONTIG, RIGHT_CONTIG, | 1872 | LEFT_CONTIG, RIGHT_CONTIG, |
1771 | LEFT_DELAY, RIGHT_DELAY, | 1873 | LEFT_DELAY, RIGHT_DELAY, |
@@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay( | |||
1844 | XFS_DATA_FORK); | 1946 | XFS_DATA_FORK); |
1845 | xfs_iext_remove(ifp, idx, 1); | 1947 | xfs_iext_remove(ifp, idx, 1); |
1846 | ip->i_df.if_lastex = idx - 1; | 1948 | ip->i_df.if_lastex = idx - 1; |
1949 | /* DELTA: Two in-core extents were replaced by one. */ | ||
1950 | temp2 = temp; | ||
1951 | temp = left.br_startoff; | ||
1847 | break; | 1952 | break; |
1848 | 1953 | ||
1849 | case MASK(LEFT_CONTIG): | 1954 | case MASK(LEFT_CONTIG): |
@@ -1864,6 +1969,9 @@ xfs_bmap_add_extent_hole_delay( | |||
1864 | xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, | 1969 | xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, |
1865 | XFS_DATA_FORK); | 1970 | XFS_DATA_FORK); |
1866 | ip->i_df.if_lastex = idx - 1; | 1971 | ip->i_df.if_lastex = idx - 1; |
1972 | /* DELTA: One in-core extent grew into a hole. */ | ||
1973 | temp2 = temp; | ||
1974 | temp = left.br_startoff; | ||
1867 | break; | 1975 | break; |
1868 | 1976 | ||
1869 | case MASK(RIGHT_CONTIG): | 1977 | case MASK(RIGHT_CONTIG): |
@@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay( | |||
1881 | NULLSTARTBLOCK((int)newlen), temp, right.br_state); | 1989 | NULLSTARTBLOCK((int)newlen), temp, right.br_state); |
1882 | xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK); | 1990 | xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK); |
1883 | ip->i_df.if_lastex = idx; | 1991 | ip->i_df.if_lastex = idx; |
1992 | /* DELTA: One in-core extent grew into a hole. */ | ||
1993 | temp2 = temp; | ||
1994 | temp = new->br_startoff; | ||
1884 | break; | 1995 | break; |
1885 | 1996 | ||
1886 | case 0: | 1997 | case 0: |
@@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay( | |||
1894 | XFS_DATA_FORK); | 2005 | XFS_DATA_FORK); |
1895 | xfs_iext_insert(ifp, idx, 1, new); | 2006 | xfs_iext_insert(ifp, idx, 1, new); |
1896 | ip->i_df.if_lastex = idx; | 2007 | ip->i_df.if_lastex = idx; |
2008 | /* DELTA: A new in-core extent was added in a hole. */ | ||
2009 | temp2 = new->br_blockcount; | ||
2010 | temp = new->br_startoff; | ||
1897 | break; | 2011 | break; |
1898 | } | 2012 | } |
1899 | if (oldlen != newlen) { | 2013 | if (oldlen != newlen) { |
@@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay( | |||
1904 | * Nothing to do for disk quota accounting here. | 2018 | * Nothing to do for disk quota accounting here. |
1905 | */ | 2019 | */ |
1906 | } | 2020 | } |
2021 | if (delta) { | ||
2022 | temp2 += temp; | ||
2023 | if (delta->xed_startoff > temp) | ||
2024 | delta->xed_startoff = temp; | ||
2025 | if (delta->xed_blockcount < temp2) | ||
2026 | delta->xed_blockcount = temp2; | ||
2027 | } | ||
1907 | *logflagsp = 0; | 2028 | *logflagsp = 0; |
1908 | return 0; | 2029 | return 0; |
1909 | #undef MASK | 2030 | #undef MASK |
@@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real( | |||
1925 | xfs_btree_cur_t *cur, /* if null, not a btree */ | 2046 | xfs_btree_cur_t *cur, /* if null, not a btree */ |
1926 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ | 2047 | xfs_bmbt_irec_t *new, /* new data to add to file extents */ |
1927 | int *logflagsp, /* inode logging flags */ | 2048 | int *logflagsp, /* inode logging flags */ |
2049 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
1928 | int whichfork) /* data or attr fork */ | 2050 | int whichfork) /* data or attr fork */ |
1929 | { | 2051 | { |
1930 | xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ | 2052 | xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ |
@@ -1936,7 +2058,10 @@ xfs_bmap_add_extent_hole_real( | |||
1936 | xfs_ifork_t *ifp; /* inode fork pointer */ | 2058 | xfs_ifork_t *ifp; /* inode fork pointer */ |
1937 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ | 2059 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ |
1938 | xfs_bmbt_irec_t right; /* right neighbor extent entry */ | 2060 | xfs_bmbt_irec_t right; /* right neighbor extent entry */ |
2061 | int rval=0; /* return value (logging flags) */ | ||
1939 | int state; /* state bits, accessed thru macros */ | 2062 | int state; /* state bits, accessed thru macros */ |
2063 | xfs_filblks_t temp=0; | ||
2064 | xfs_filblks_t temp2=0; | ||
1940 | enum { /* bit number definitions for state */ | 2065 | enum { /* bit number definitions for state */ |
1941 | LEFT_CONTIG, RIGHT_CONTIG, | 2066 | LEFT_CONTIG, RIGHT_CONTIG, |
1942 | LEFT_DELAY, RIGHT_DELAY, | 2067 | LEFT_DELAY, RIGHT_DELAY, |
@@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real( | |||
1993 | left.br_blockcount + new->br_blockcount + | 2118 | left.br_blockcount + new->br_blockcount + |
1994 | right.br_blockcount <= MAXEXTLEN)); | 2119 | right.br_blockcount <= MAXEXTLEN)); |
1995 | 2120 | ||
2121 | error = 0; | ||
1996 | /* | 2122 | /* |
1997 | * Select which case we're in here, and implement it. | 2123 | * Select which case we're in here, and implement it. |
1998 | */ | 2124 | */ |
@@ -2018,25 +2144,35 @@ xfs_bmap_add_extent_hole_real( | |||
2018 | XFS_IFORK_NEXT_SET(ip, whichfork, | 2144 | XFS_IFORK_NEXT_SET(ip, whichfork, |
2019 | XFS_IFORK_NEXTENTS(ip, whichfork) - 1); | 2145 | XFS_IFORK_NEXTENTS(ip, whichfork) - 1); |
2020 | if (cur == NULL) { | 2146 | if (cur == NULL) { |
2021 | *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); | 2147 | rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); |
2022 | return 0; | 2148 | } else { |
2149 | rval = XFS_ILOG_CORE; | ||
2150 | if ((error = xfs_bmbt_lookup_eq(cur, | ||
2151 | right.br_startoff, | ||
2152 | right.br_startblock, | ||
2153 | right.br_blockcount, &i))) | ||
2154 | goto done; | ||
2155 | ASSERT(i == 1); | ||
2156 | if ((error = xfs_bmbt_delete(cur, &i))) | ||
2157 | goto done; | ||
2158 | ASSERT(i == 1); | ||
2159 | if ((error = xfs_bmbt_decrement(cur, 0, &i))) | ||
2160 | goto done; | ||
2161 | ASSERT(i == 1); | ||
2162 | if ((error = xfs_bmbt_update(cur, left.br_startoff, | ||
2163 | left.br_startblock, | ||
2164 | left.br_blockcount + | ||
2165 | new->br_blockcount + | ||
2166 | right.br_blockcount, | ||
2167 | left.br_state))) | ||
2168 | goto done; | ||
2023 | } | 2169 | } |
2024 | *logflagsp = XFS_ILOG_CORE; | 2170 | /* DELTA: Two in-core extents were replaced by one. */ |
2025 | if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, | 2171 | temp = left.br_startoff; |
2026 | right.br_startblock, right.br_blockcount, &i))) | 2172 | temp2 = left.br_blockcount + |
2027 | return error; | 2173 | new->br_blockcount + |
2028 | ASSERT(i == 1); | 2174 | right.br_blockcount; |
2029 | if ((error = xfs_bmbt_delete(cur, &i))) | 2175 | break; |
2030 | return error; | ||
2031 | ASSERT(i == 1); | ||
2032 | if ((error = xfs_bmbt_decrement(cur, 0, &i))) | ||
2033 | return error; | ||
2034 | ASSERT(i == 1); | ||
2035 | error = xfs_bmbt_update(cur, left.br_startoff, | ||
2036 | left.br_startblock, | ||
2037 | left.br_blockcount + new->br_blockcount + | ||
2038 | right.br_blockcount, left.br_state); | ||
2039 | return error; | ||
2040 | 2176 | ||
2041 | case MASK(LEFT_CONTIG): | 2177 | case MASK(LEFT_CONTIG): |
2042 | /* | 2178 | /* |
@@ -2050,19 +2186,27 @@ xfs_bmap_add_extent_hole_real( | |||
2050 | xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); | 2186 | xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); |
2051 | ifp->if_lastex = idx - 1; | 2187 | ifp->if_lastex = idx - 1; |
2052 | if (cur == NULL) { | 2188 | if (cur == NULL) { |
2053 | *logflagsp = XFS_ILOG_FEXT(whichfork); | 2189 | rval = XFS_ILOG_FEXT(whichfork); |
2054 | return 0; | 2190 | } else { |
2191 | rval = 0; | ||
2192 | if ((error = xfs_bmbt_lookup_eq(cur, | ||
2193 | left.br_startoff, | ||
2194 | left.br_startblock, | ||
2195 | left.br_blockcount, &i))) | ||
2196 | goto done; | ||
2197 | ASSERT(i == 1); | ||
2198 | if ((error = xfs_bmbt_update(cur, left.br_startoff, | ||
2199 | left.br_startblock, | ||
2200 | left.br_blockcount + | ||
2201 | new->br_blockcount, | ||
2202 | left.br_state))) | ||
2203 | goto done; | ||
2055 | } | 2204 | } |
2056 | *logflagsp = 0; | 2205 | /* DELTA: One in-core extent grew. */ |
2057 | if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff, | 2206 | temp = left.br_startoff; |
2058 | left.br_startblock, left.br_blockcount, &i))) | 2207 | temp2 = left.br_blockcount + |
2059 | return error; | 2208 | new->br_blockcount; |
2060 | ASSERT(i == 1); | 2209 | break; |
2061 | error = xfs_bmbt_update(cur, left.br_startoff, | ||
2062 | left.br_startblock, | ||
2063 | left.br_blockcount + new->br_blockcount, | ||
2064 | left.br_state); | ||
2065 | return error; | ||
2066 | 2210 | ||
2067 | case MASK(RIGHT_CONTIG): | 2211 | case MASK(RIGHT_CONTIG): |
2068 | /* | 2212 | /* |
@@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real( | |||
2077 | xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork); | 2221 | xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork); |
2078 | ifp->if_lastex = idx; | 2222 | ifp->if_lastex = idx; |
2079 | if (cur == NULL) { | 2223 | if (cur == NULL) { |
2080 | *logflagsp = XFS_ILOG_FEXT(whichfork); | 2224 | rval = XFS_ILOG_FEXT(whichfork); |
2081 | return 0; | 2225 | } else { |
2226 | rval = 0; | ||
2227 | if ((error = xfs_bmbt_lookup_eq(cur, | ||
2228 | right.br_startoff, | ||
2229 | right.br_startblock, | ||
2230 | right.br_blockcount, &i))) | ||
2231 | goto done; | ||
2232 | ASSERT(i == 1); | ||
2233 | if ((error = xfs_bmbt_update(cur, new->br_startoff, | ||
2234 | new->br_startblock, | ||
2235 | new->br_blockcount + | ||
2236 | right.br_blockcount, | ||
2237 | right.br_state))) | ||
2238 | goto done; | ||
2082 | } | 2239 | } |
2083 | *logflagsp = 0; | 2240 | /* DELTA: One in-core extent grew. */ |
2084 | if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, | 2241 | temp = new->br_startoff; |
2085 | right.br_startblock, right.br_blockcount, &i))) | 2242 | temp2 = new->br_blockcount + |
2086 | return error; | 2243 | right.br_blockcount; |
2087 | ASSERT(i == 1); | 2244 | break; |
2088 | error = xfs_bmbt_update(cur, new->br_startoff, | ||
2089 | new->br_startblock, | ||
2090 | new->br_blockcount + right.br_blockcount, | ||
2091 | right.br_state); | ||
2092 | return error; | ||
2093 | 2245 | ||
2094 | case 0: | 2246 | case 0: |
2095 | /* | 2247 | /* |
@@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real( | |||
2104 | XFS_IFORK_NEXT_SET(ip, whichfork, | 2256 | XFS_IFORK_NEXT_SET(ip, whichfork, |
2105 | XFS_IFORK_NEXTENTS(ip, whichfork) + 1); | 2257 | XFS_IFORK_NEXTENTS(ip, whichfork) + 1); |
2106 | if (cur == NULL) { | 2258 | if (cur == NULL) { |
2107 | *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); | 2259 | rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); |
2108 | return 0; | 2260 | } else { |
2261 | rval = XFS_ILOG_CORE; | ||
2262 | if ((error = xfs_bmbt_lookup_eq(cur, | ||
2263 | new->br_startoff, | ||
2264 | new->br_startblock, | ||
2265 | new->br_blockcount, &i))) | ||
2266 | goto done; | ||
2267 | ASSERT(i == 0); | ||
2268 | cur->bc_rec.b.br_state = new->br_state; | ||
2269 | if ((error = xfs_bmbt_insert(cur, &i))) | ||
2270 | goto done; | ||
2271 | ASSERT(i == 1); | ||
2109 | } | 2272 | } |
2110 | *logflagsp = XFS_ILOG_CORE; | 2273 | /* DELTA: A new extent was added in a hole. */ |
2111 | if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, | 2274 | temp = new->br_startoff; |
2112 | new->br_startblock, new->br_blockcount, &i))) | 2275 | temp2 = new->br_blockcount; |
2113 | return error; | 2276 | break; |
2114 | ASSERT(i == 0); | 2277 | } |
2115 | cur->bc_rec.b.br_state = new->br_state; | 2278 | if (delta) { |
2116 | if ((error = xfs_bmbt_insert(cur, &i))) | 2279 | temp2 += temp; |
2117 | return error; | 2280 | if (delta->xed_startoff > temp) |
2118 | ASSERT(i == 1); | 2281 | delta->xed_startoff = temp; |
2119 | return 0; | 2282 | if (delta->xed_blockcount < temp2) |
2283 | delta->xed_blockcount = temp2; | ||
2120 | } | 2284 | } |
2285 | done: | ||
2286 | *logflagsp = rval; | ||
2287 | return error; | ||
2121 | #undef MASK | 2288 | #undef MASK |
2122 | #undef MASK2 | 2289 | #undef MASK2 |
2123 | #undef STATE_SET | 2290 | #undef STATE_SET |
2124 | #undef STATE_TEST | 2291 | #undef STATE_TEST |
2125 | #undef STATE_SET_TEST | 2292 | #undef STATE_SET_TEST |
2126 | #undef SWITCH_STATE | 2293 | #undef SWITCH_STATE |
2127 | /* NOTREACHED */ | ||
2128 | ASSERT(0); | ||
2129 | return 0; /* keep gcc quite */ | ||
2130 | } | 2294 | } |
2131 | 2295 | ||
2132 | /* | 2296 | /* |
@@ -2598,6 +2762,7 @@ xfs_bmap_btalloc( | |||
2598 | args.mp = mp; | 2762 | args.mp = mp; |
2599 | args.fsbno = ap->rval; | 2763 | args.fsbno = ap->rval; |
2600 | args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); | 2764 | args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); |
2765 | args.firstblock = ap->firstblock; | ||
2601 | blen = 0; | 2766 | blen = 0; |
2602 | if (nullfb) { | 2767 | if (nullfb) { |
2603 | args.type = XFS_ALLOCTYPE_START_BNO; | 2768 | args.type = XFS_ALLOCTYPE_START_BNO; |
@@ -2657,7 +2822,7 @@ xfs_bmap_btalloc( | |||
2657 | else | 2822 | else |
2658 | args.minlen = ap->alen; | 2823 | args.minlen = ap->alen; |
2659 | } else if (ap->low) { | 2824 | } else if (ap->low) { |
2660 | args.type = XFS_ALLOCTYPE_FIRST_AG; | 2825 | args.type = XFS_ALLOCTYPE_START_BNO; |
2661 | args.total = args.minlen = ap->minlen; | 2826 | args.total = args.minlen = ap->minlen; |
2662 | } else { | 2827 | } else { |
2663 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | 2828 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
@@ -2669,7 +2834,7 @@ xfs_bmap_btalloc( | |||
2669 | args.prod = ap->ip->i_d.di_extsize; | 2834 | args.prod = ap->ip->i_d.di_extsize; |
2670 | if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) | 2835 | if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) |
2671 | args.mod = (xfs_extlen_t)(args.prod - args.mod); | 2836 | args.mod = (xfs_extlen_t)(args.prod - args.mod); |
2672 | } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) { | 2837 | } else if (mp->m_sb.sb_blocksize >= NBPP) { |
2673 | args.prod = 1; | 2838 | args.prod = 1; |
2674 | args.mod = 0; | 2839 | args.mod = 0; |
2675 | } else { | 2840 | } else { |
@@ -2885,6 +3050,7 @@ xfs_bmap_del_extent( | |||
2885 | xfs_btree_cur_t *cur, /* if null, not a btree */ | 3050 | xfs_btree_cur_t *cur, /* if null, not a btree */ |
2886 | xfs_bmbt_irec_t *del, /* data to remove from extents */ | 3051 | xfs_bmbt_irec_t *del, /* data to remove from extents */ |
2887 | int *logflagsp, /* inode logging flags */ | 3052 | int *logflagsp, /* inode logging flags */ |
3053 | xfs_extdelta_t *delta, /* Change made to incore extents */ | ||
2888 | int whichfork, /* data or attr fork */ | 3054 | int whichfork, /* data or attr fork */ |
2889 | int rsvd) /* OK to allocate reserved blocks */ | 3055 | int rsvd) /* OK to allocate reserved blocks */ |
2890 | { | 3056 | { |
@@ -3193,6 +3359,14 @@ xfs_bmap_del_extent( | |||
3193 | if (da_old > da_new) | 3359 | if (da_old > da_new) |
3194 | xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), | 3360 | xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), |
3195 | rsvd); | 3361 | rsvd); |
3362 | if (delta) { | ||
3363 | /* DELTA: report the original extent. */ | ||
3364 | if (delta->xed_startoff > got.br_startoff) | ||
3365 | delta->xed_startoff = got.br_startoff; | ||
3366 | if (delta->xed_blockcount < got.br_startoff+got.br_blockcount) | ||
3367 | delta->xed_blockcount = got.br_startoff + | ||
3368 | got.br_blockcount; | ||
3369 | } | ||
3196 | done: | 3370 | done: |
3197 | *logflagsp = flags; | 3371 | *logflagsp = flags; |
3198 | return error; | 3372 | return error; |
@@ -3279,6 +3453,7 @@ xfs_bmap_extents_to_btree( | |||
3279 | XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); | 3453 | XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); |
3280 | args.tp = tp; | 3454 | args.tp = tp; |
3281 | args.mp = mp; | 3455 | args.mp = mp; |
3456 | args.firstblock = *firstblock; | ||
3282 | if (*firstblock == NULLFSBLOCK) { | 3457 | if (*firstblock == NULLFSBLOCK) { |
3283 | args.type = XFS_ALLOCTYPE_START_BNO; | 3458 | args.type = XFS_ALLOCTYPE_START_BNO; |
3284 | args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); | 3459 | args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); |
@@ -3414,6 +3589,7 @@ xfs_bmap_local_to_extents( | |||
3414 | 3589 | ||
3415 | args.tp = tp; | 3590 | args.tp = tp; |
3416 | args.mp = ip->i_mount; | 3591 | args.mp = ip->i_mount; |
3592 | args.firstblock = *firstblock; | ||
3417 | ASSERT((ifp->if_flags & | 3593 | ASSERT((ifp->if_flags & |
3418 | (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE); | 3594 | (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE); |
3419 | /* | 3595 | /* |
@@ -3753,7 +3929,7 @@ xfs_bunmap_trace( | |||
3753 | if (ip->i_rwtrace == NULL) | 3929 | if (ip->i_rwtrace == NULL) |
3754 | return; | 3930 | return; |
3755 | ktrace_enter(ip->i_rwtrace, | 3931 | ktrace_enter(ip->i_rwtrace, |
3756 | (void *)(__psint_t)XFS_BUNMAPI, | 3932 | (void *)(__psint_t)XFS_BUNMAP, |
3757 | (void *)ip, | 3933 | (void *)ip, |
3758 | (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff), | 3934 | (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff), |
3759 | (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), | 3935 | (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), |
@@ -4087,8 +4263,8 @@ xfs_bmap_finish( | |||
4087 | if (!XFS_FORCED_SHUTDOWN(mp)) | 4263 | if (!XFS_FORCED_SHUTDOWN(mp)) |
4088 | xfs_force_shutdown(mp, | 4264 | xfs_force_shutdown(mp, |
4089 | (error == EFSCORRUPTED) ? | 4265 | (error == EFSCORRUPTED) ? |
4090 | XFS_CORRUPT_INCORE : | 4266 | SHUTDOWN_CORRUPT_INCORE : |
4091 | XFS_METADATA_IO_ERROR); | 4267 | SHUTDOWN_META_IO_ERROR); |
4092 | return error; | 4268 | return error; |
4093 | } | 4269 | } |
4094 | xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock, | 4270 | xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock, |
@@ -4538,7 +4714,8 @@ xfs_bmapi( | |||
4538 | xfs_extlen_t total, /* total blocks needed */ | 4714 | xfs_extlen_t total, /* total blocks needed */ |
4539 | xfs_bmbt_irec_t *mval, /* output: map values */ | 4715 | xfs_bmbt_irec_t *mval, /* output: map values */ |
4540 | int *nmap, /* i/o: mval size/count */ | 4716 | int *nmap, /* i/o: mval size/count */ |
4541 | xfs_bmap_free_t *flist) /* i/o: list extents to free */ | 4717 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ |
4718 | xfs_extdelta_t *delta) /* o: change made to incore extents */ | ||
4542 | { | 4719 | { |
4543 | xfs_fsblock_t abno; /* allocated block number */ | 4720 | xfs_fsblock_t abno; /* allocated block number */ |
4544 | xfs_extlen_t alen; /* allocated extent length */ | 4721 | xfs_extlen_t alen; /* allocated extent length */ |
@@ -4650,6 +4827,10 @@ xfs_bmapi( | |||
4650 | end = bno + len; | 4827 | end = bno + len; |
4651 | obno = bno; | 4828 | obno = bno; |
4652 | bma.ip = NULL; | 4829 | bma.ip = NULL; |
4830 | if (delta) { | ||
4831 | delta->xed_startoff = NULLFILEOFF; | ||
4832 | delta->xed_blockcount = 0; | ||
4833 | } | ||
4653 | while (bno < end && n < *nmap) { | 4834 | while (bno < end && n < *nmap) { |
4654 | /* | 4835 | /* |
4655 | * Reading past eof, act as though there's a hole | 4836 | * Reading past eof, act as though there's a hole |
@@ -4886,8 +5067,8 @@ xfs_bmapi( | |||
4886 | got.br_state = XFS_EXT_UNWRITTEN; | 5067 | got.br_state = XFS_EXT_UNWRITTEN; |
4887 | } | 5068 | } |
4888 | error = xfs_bmap_add_extent(ip, lastx, &cur, &got, | 5069 | error = xfs_bmap_add_extent(ip, lastx, &cur, &got, |
4889 | firstblock, flist, &tmp_logflags, whichfork, | 5070 | firstblock, flist, &tmp_logflags, delta, |
4890 | (flags & XFS_BMAPI_RSVBLOCKS)); | 5071 | whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); |
4891 | logflags |= tmp_logflags; | 5072 | logflags |= tmp_logflags; |
4892 | if (error) | 5073 | if (error) |
4893 | goto error0; | 5074 | goto error0; |
@@ -4983,8 +5164,8 @@ xfs_bmapi( | |||
4983 | } | 5164 | } |
4984 | mval->br_state = XFS_EXT_NORM; | 5165 | mval->br_state = XFS_EXT_NORM; |
4985 | error = xfs_bmap_add_extent(ip, lastx, &cur, mval, | 5166 | error = xfs_bmap_add_extent(ip, lastx, &cur, mval, |
4986 | firstblock, flist, &tmp_logflags, whichfork, | 5167 | firstblock, flist, &tmp_logflags, delta, |
4987 | (flags & XFS_BMAPI_RSVBLOCKS)); | 5168 | whichfork, (flags & XFS_BMAPI_RSVBLOCKS)); |
4988 | logflags |= tmp_logflags; | 5169 | logflags |= tmp_logflags; |
4989 | if (error) | 5170 | if (error) |
4990 | goto error0; | 5171 | goto error0; |
@@ -5073,7 +5254,14 @@ xfs_bmapi( | |||
5073 | ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || | 5254 | ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || |
5074 | XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); | 5255 | XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); |
5075 | error = 0; | 5256 | error = 0; |
5076 | 5257 | if (delta && delta->xed_startoff != NULLFILEOFF) { | |
5258 | /* A change was actually made. | ||
5259 | * Note that delta->xed_blockount is an offset at this | ||
5260 | * point and needs to be converted to a block count. | ||
5261 | */ | ||
5262 | ASSERT(delta->xed_blockcount > delta->xed_startoff); | ||
5263 | delta->xed_blockcount -= delta->xed_startoff; | ||
5264 | } | ||
5077 | error0: | 5265 | error0: |
5078 | /* | 5266 | /* |
5079 | * Log everything. Do this after conversion, there's no point in | 5267 | * Log everything. Do this after conversion, there's no point in |
@@ -5185,6 +5373,8 @@ xfs_bunmapi( | |||
5185 | xfs_fsblock_t *firstblock, /* first allocated block | 5373 | xfs_fsblock_t *firstblock, /* first allocated block |
5186 | controls a.g. for allocs */ | 5374 | controls a.g. for allocs */ |
5187 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ | 5375 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ |
5376 | xfs_extdelta_t *delta, /* o: change made to incore | ||
5377 | extents */ | ||
5188 | int *done) /* set if not done yet */ | 5378 | int *done) /* set if not done yet */ |
5189 | { | 5379 | { |
5190 | xfs_btree_cur_t *cur; /* bmap btree cursor */ | 5380 | xfs_btree_cur_t *cur; /* bmap btree cursor */ |
@@ -5242,6 +5432,10 @@ xfs_bunmapi( | |||
5242 | bno = start + len - 1; | 5432 | bno = start + len - 1; |
5243 | ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, | 5433 | ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, |
5244 | &prev); | 5434 | &prev); |
5435 | if (delta) { | ||
5436 | delta->xed_startoff = NULLFILEOFF; | ||
5437 | delta->xed_blockcount = 0; | ||
5438 | } | ||
5245 | /* | 5439 | /* |
5246 | * Check to see if the given block number is past the end of the | 5440 | * Check to see if the given block number is past the end of the |
5247 | * file, back up to the last block if so... | 5441 | * file, back up to the last block if so... |
@@ -5340,7 +5534,8 @@ xfs_bunmapi( | |||
5340 | } | 5534 | } |
5341 | del.br_state = XFS_EXT_UNWRITTEN; | 5535 | del.br_state = XFS_EXT_UNWRITTEN; |
5342 | error = xfs_bmap_add_extent(ip, lastx, &cur, &del, | 5536 | error = xfs_bmap_add_extent(ip, lastx, &cur, &del, |
5343 | firstblock, flist, &logflags, XFS_DATA_FORK, 0); | 5537 | firstblock, flist, &logflags, delta, |
5538 | XFS_DATA_FORK, 0); | ||
5344 | if (error) | 5539 | if (error) |
5345 | goto error0; | 5540 | goto error0; |
5346 | goto nodelete; | 5541 | goto nodelete; |
@@ -5394,7 +5589,7 @@ xfs_bunmapi( | |||
5394 | prev.br_state = XFS_EXT_UNWRITTEN; | 5589 | prev.br_state = XFS_EXT_UNWRITTEN; |
5395 | error = xfs_bmap_add_extent(ip, lastx - 1, &cur, | 5590 | error = xfs_bmap_add_extent(ip, lastx - 1, &cur, |
5396 | &prev, firstblock, flist, &logflags, | 5591 | &prev, firstblock, flist, &logflags, |
5397 | XFS_DATA_FORK, 0); | 5592 | delta, XFS_DATA_FORK, 0); |
5398 | if (error) | 5593 | if (error) |
5399 | goto error0; | 5594 | goto error0; |
5400 | goto nodelete; | 5595 | goto nodelete; |
@@ -5403,7 +5598,7 @@ xfs_bunmapi( | |||
5403 | del.br_state = XFS_EXT_UNWRITTEN; | 5598 | del.br_state = XFS_EXT_UNWRITTEN; |
5404 | error = xfs_bmap_add_extent(ip, lastx, &cur, | 5599 | error = xfs_bmap_add_extent(ip, lastx, &cur, |
5405 | &del, firstblock, flist, &logflags, | 5600 | &del, firstblock, flist, &logflags, |
5406 | XFS_DATA_FORK, 0); | 5601 | delta, XFS_DATA_FORK, 0); |
5407 | if (error) | 5602 | if (error) |
5408 | goto error0; | 5603 | goto error0; |
5409 | goto nodelete; | 5604 | goto nodelete; |
@@ -5456,7 +5651,7 @@ xfs_bunmapi( | |||
5456 | goto error0; | 5651 | goto error0; |
5457 | } | 5652 | } |
5458 | error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, | 5653 | error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, |
5459 | &tmp_logflags, whichfork, rsvd); | 5654 | &tmp_logflags, delta, whichfork, rsvd); |
5460 | logflags |= tmp_logflags; | 5655 | logflags |= tmp_logflags; |
5461 | if (error) | 5656 | if (error) |
5462 | goto error0; | 5657 | goto error0; |
@@ -5513,6 +5708,14 @@ nodelete: | |||
5513 | ASSERT(ifp->if_ext_max == | 5708 | ASSERT(ifp->if_ext_max == |
5514 | XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); | 5709 | XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); |
5515 | error = 0; | 5710 | error = 0; |
5711 | if (delta && delta->xed_startoff != NULLFILEOFF) { | ||
5712 | /* A change was actually made. | ||
5713 | * Note that delta->xed_blockount is an offset at this | ||
5714 | * point and needs to be converted to a block count. | ||
5715 | */ | ||
5716 | ASSERT(delta->xed_blockcount > delta->xed_startoff); | ||
5717 | delta->xed_blockcount -= delta->xed_startoff; | ||
5718 | } | ||
5516 | error0: | 5719 | error0: |
5517 | /* | 5720 | /* |
5518 | * Log everything. Do this after conversion, there's no point in | 5721 | * Log everything. Do this after conversion, there's no point in |
@@ -5556,7 +5759,7 @@ xfs_getbmap( | |||
5556 | __int64_t fixlen; /* length for -1 case */ | 5759 | __int64_t fixlen; /* length for -1 case */ |
5557 | int i; /* extent number */ | 5760 | int i; /* extent number */ |
5558 | xfs_inode_t *ip; /* xfs incore inode pointer */ | 5761 | xfs_inode_t *ip; /* xfs incore inode pointer */ |
5559 | vnode_t *vp; /* corresponding vnode */ | 5762 | bhv_vnode_t *vp; /* corresponding vnode */ |
5560 | int lock; /* lock state */ | 5763 | int lock; /* lock state */ |
5561 | xfs_bmbt_irec_t *map; /* buffer for user's data */ | 5764 | xfs_bmbt_irec_t *map; /* buffer for user's data */ |
5562 | xfs_mount_t *mp; /* file system mount point */ | 5765 | xfs_mount_t *mp; /* file system mount point */ |
@@ -5653,7 +5856,7 @@ xfs_getbmap( | |||
5653 | 5856 | ||
5654 | if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) { | 5857 | if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) { |
5655 | /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ | 5858 | /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ |
5656 | VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); | 5859 | error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF); |
5657 | } | 5860 | } |
5658 | 5861 | ||
5659 | ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); | 5862 | ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); |
@@ -5689,7 +5892,8 @@ xfs_getbmap( | |||
5689 | nmap = (nexleft > subnex) ? subnex : nexleft; | 5892 | nmap = (nexleft > subnex) ? subnex : nexleft; |
5690 | error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), | 5893 | error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), |
5691 | XFS_BB_TO_FSB(mp, bmv->bmv_length), | 5894 | XFS_BB_TO_FSB(mp, bmv->bmv_length), |
5692 | bmapi_flags, NULL, 0, map, &nmap, NULL); | 5895 | bmapi_flags, NULL, 0, map, &nmap, |
5896 | NULL, NULL); | ||
5693 | if (error) | 5897 | if (error) |
5694 | goto unlock_and_return; | 5898 | goto unlock_and_return; |
5695 | ASSERT(nmap <= subnex); | 5899 | ASSERT(nmap <= subnex); |
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 8e0d73d9ccc4..80e93409b78d 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -26,6 +26,20 @@ struct xfs_mount; | |||
26 | struct xfs_trans; | 26 | struct xfs_trans; |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * DELTA: describe a change to the in-core extent list. | ||
30 | * | ||
31 | * Internally the use of xed_blockount is somewhat funky. | ||
32 | * xed_blockcount contains an offset much of the time because this | ||
33 | * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are | ||
34 | * the same underlying type). | ||
35 | */ | ||
36 | typedef struct xfs_extdelta | ||
37 | { | ||
38 | xfs_fileoff_t xed_startoff; /* offset of range */ | ||
39 | xfs_filblks_t xed_blockcount; /* blocks in range */ | ||
40 | } xfs_extdelta_t; | ||
41 | |||
42 | /* | ||
29 | * List of extents to be free "later". | 43 | * List of extents to be free "later". |
30 | * The list is kept sorted on xbf_startblock. | 44 | * The list is kept sorted on xbf_startblock. |
31 | */ | 45 | */ |
@@ -275,7 +289,9 @@ xfs_bmapi( | |||
275 | xfs_extlen_t total, /* total blocks needed */ | 289 | xfs_extlen_t total, /* total blocks needed */ |
276 | struct xfs_bmbt_irec *mval, /* output: map values */ | 290 | struct xfs_bmbt_irec *mval, /* output: map values */ |
277 | int *nmap, /* i/o: mval size/count */ | 291 | int *nmap, /* i/o: mval size/count */ |
278 | xfs_bmap_free_t *flist); /* i/o: list extents to free */ | 292 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ |
293 | xfs_extdelta_t *delta); /* o: change made to incore | ||
294 | extents */ | ||
279 | 295 | ||
280 | /* | 296 | /* |
281 | * Map file blocks to filesystem blocks, simple version. | 297 | * Map file blocks to filesystem blocks, simple version. |
@@ -309,6 +325,8 @@ xfs_bunmapi( | |||
309 | xfs_fsblock_t *firstblock, /* first allocated block | 325 | xfs_fsblock_t *firstblock, /* first allocated block |
310 | controls a.g. for allocs */ | 326 | controls a.g. for allocs */ |
311 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ | 327 | xfs_bmap_free_t *flist, /* i/o: list extents to free */ |
328 | xfs_extdelta_t *delta, /* o: change made to incore | ||
329 | extents */ | ||
312 | int *done); /* set if not done yet */ | 330 | int *done); /* set if not done yet */ |
313 | 331 | ||
314 | /* | 332 | /* |
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index bea44709afbe..18fb7385d719 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -1569,12 +1567,11 @@ xfs_bmbt_split( | |||
1569 | lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp)); | 1567 | lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp)); |
1570 | left = XFS_BUF_TO_BMBT_BLOCK(lbp); | 1568 | left = XFS_BUF_TO_BMBT_BLOCK(lbp); |
1571 | args.fsbno = cur->bc_private.b.firstblock; | 1569 | args.fsbno = cur->bc_private.b.firstblock; |
1570 | args.firstblock = args.fsbno; | ||
1572 | if (args.fsbno == NULLFSBLOCK) { | 1571 | if (args.fsbno == NULLFSBLOCK) { |
1573 | args.fsbno = lbno; | 1572 | args.fsbno = lbno; |
1574 | args.type = XFS_ALLOCTYPE_START_BNO; | 1573 | args.type = XFS_ALLOCTYPE_START_BNO; |
1575 | } else if (cur->bc_private.b.flist->xbf_low) | 1574 | } else |
1576 | args.type = XFS_ALLOCTYPE_FIRST_AG; | ||
1577 | else | ||
1578 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | 1575 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
1579 | args.mod = args.minleft = args.alignment = args.total = args.isfl = | 1576 | args.mod = args.minleft = args.alignment = args.total = args.isfl = |
1580 | args.userdata = args.minalignslop = 0; | 1577 | args.userdata = args.minalignslop = 0; |
@@ -2356,6 +2353,7 @@ xfs_bmbt_newroot( | |||
2356 | args.userdata = args.minalignslop = 0; | 2353 | args.userdata = args.minalignslop = 0; |
2357 | args.minlen = args.maxlen = args.prod = 1; | 2354 | args.minlen = args.maxlen = args.prod = 1; |
2358 | args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; | 2355 | args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; |
2356 | args.firstblock = args.fsbno; | ||
2359 | if (args.fsbno == NULLFSBLOCK) { | 2357 | if (args.fsbno == NULLFSBLOCK) { |
2360 | #ifdef DEBUG | 2358 | #ifdef DEBUG |
2361 | if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { | 2359 | if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { |
@@ -2365,9 +2363,7 @@ xfs_bmbt_newroot( | |||
2365 | #endif | 2363 | #endif |
2366 | args.fsbno = INT_GET(*pp, ARCH_CONVERT); | 2364 | args.fsbno = INT_GET(*pp, ARCH_CONVERT); |
2367 | args.type = XFS_ALLOCTYPE_START_BNO; | 2365 | args.type = XFS_ALLOCTYPE_START_BNO; |
2368 | } else if (args.wasdel) | 2366 | } else |
2369 | args.type = XFS_ALLOCTYPE_FIRST_AG; | ||
2370 | else | ||
2371 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | 2367 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
2372 | if ((error = xfs_alloc_vextent(&args))) { | 2368 | if ((error = xfs_alloc_vextent(&args))) { |
2373 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 2369 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 52d5d095fc35..ee2255bd6562 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 5fed15682dda..a4aa53974f76 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_inum.h" | 23 | #include "xfs_inum.h" |
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
29 | #include "xfs_buf_item.h" | 28 | #include "xfs_buf_item.h" |
@@ -1030,9 +1029,9 @@ xfs_buf_iodone_callbacks( | |||
1030 | if ((XFS_BUF_TARGET(bp) != lasttarg) || | 1029 | if ((XFS_BUF_TARGET(bp) != lasttarg) || |
1031 | (time_after(jiffies, (lasttime + 5*HZ)))) { | 1030 | (time_after(jiffies, (lasttime + 5*HZ)))) { |
1032 | lasttime = jiffies; | 1031 | lasttime = jiffies; |
1033 | prdev("XFS write error in file system meta-data " | 1032 | cmn_err(CE_ALERT, "Device %s, XFS metadata write error" |
1034 | "block 0x%llx in %s", | 1033 | " block 0x%llx in %s", |
1035 | XFS_BUF_TARGET(bp), | 1034 | XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)), |
1036 | (__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname); | 1035 | (__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname); |
1037 | } | 1036 | } |
1038 | lasttarg = XFS_BUF_TARGET(bp); | 1037 | lasttarg = XFS_BUF_TARGET(bp); |
@@ -1108,7 +1107,7 @@ xfs_buf_error_relse( | |||
1108 | XFS_BUF_ERROR(bp,0); | 1107 | XFS_BUF_ERROR(bp,0); |
1109 | xfs_buftrace("BUF_ERROR_RELSE", bp); | 1108 | xfs_buftrace("BUF_ERROR_RELSE", bp); |
1110 | if (! XFS_FORCED_SHUTDOWN(mp)) | 1109 | if (! XFS_FORCED_SHUTDOWN(mp)) |
1111 | xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); | 1110 | xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); |
1112 | /* | 1111 | /* |
1113 | * We have to unpin the pinned buffers so do the | 1112 | * We have to unpin the pinned buffers so do the |
1114 | * callbacks. | 1113 | * callbacks. |
diff --git a/fs/xfs/xfs_cap.h b/fs/xfs/xfs_cap.h index d0035c6e9514..7a0e482dd436 100644 --- a/fs/xfs/xfs_cap.h +++ b/fs/xfs/xfs_cap.h | |||
@@ -49,12 +49,12 @@ typedef struct xfs_cap_set { | |||
49 | 49 | ||
50 | #include <linux/posix_cap_xattr.h> | 50 | #include <linux/posix_cap_xattr.h> |
51 | 51 | ||
52 | struct vnode; | 52 | struct bhv_vnode; |
53 | 53 | ||
54 | extern int xfs_cap_vhascap(struct vnode *); | 54 | extern int xfs_cap_vhascap(struct bhv_vnode *); |
55 | extern int xfs_cap_vset(struct vnode *, void *, size_t); | 55 | extern int xfs_cap_vset(struct bhv_vnode *, void *, size_t); |
56 | extern int xfs_cap_vget(struct vnode *, void *, size_t); | 56 | extern int xfs_cap_vget(struct bhv_vnode *, void *, size_t); |
57 | extern int xfs_cap_vremove(struct vnode *vp); | 57 | extern int xfs_cap_vremove(struct bhv_vnode *); |
58 | 58 | ||
59 | #define _CAP_EXISTS xfs_cap_vhascap | 59 | #define _CAP_EXISTS xfs_cap_vhascap |
60 | 60 | ||
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 8988b9051175..32ab61d17ace 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -43,7 +41,6 @@ | |||
43 | #include "xfs_bmap.h" | 41 | #include "xfs_bmap.h" |
44 | #include "xfs_attr.h" | 42 | #include "xfs_attr.h" |
45 | #include "xfs_attr_leaf.h" | 43 | #include "xfs_attr_leaf.h" |
46 | #include "xfs_dir_leaf.h" | ||
47 | #include "xfs_dir2_data.h" | 44 | #include "xfs_dir2_data.h" |
48 | #include "xfs_dir2_leaf.h" | 45 | #include "xfs_dir2_leaf.h" |
49 | #include "xfs_dir2_block.h" | 46 | #include "xfs_dir2_block.h" |
@@ -159,7 +156,7 @@ xfs_da_split(xfs_da_state_t *state) | |||
159 | max = state->path.active - 1; | 156 | max = state->path.active - 1; |
160 | ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); | 157 | ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); |
161 | ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || | 158 | ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || |
162 | state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp)); | 159 | state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC); |
163 | 160 | ||
164 | addblk = &state->path.blk[max]; /* initial dummy value */ | 161 | addblk = &state->path.blk[max]; /* initial dummy value */ |
165 | for (i = max; (i >= 0) && addblk; state->path.active--, i--) { | 162 | for (i = max; (i >= 0) && addblk; state->path.active--, i--) { |
@@ -199,38 +196,7 @@ xfs_da_split(xfs_da_state_t *state) | |||
199 | return(error); /* GROT: attr inconsistent */ | 196 | return(error); /* GROT: attr inconsistent */ |
200 | addblk = newblk; | 197 | addblk = newblk; |
201 | break; | 198 | break; |
202 | case XFS_DIR_LEAF_MAGIC: | ||
203 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
204 | error = xfs_dir_leaf_split(state, oldblk, newblk); | ||
205 | if ((error != 0) && (error != ENOSPC)) { | ||
206 | return(error); /* GROT: dir is inconsistent */ | ||
207 | } | ||
208 | if (!error) { | ||
209 | addblk = newblk; | ||
210 | break; | ||
211 | } | ||
212 | /* | ||
213 | * Entry wouldn't fit, split the leaf again. | ||
214 | */ | ||
215 | state->extravalid = 1; | ||
216 | if (state->inleaf) { | ||
217 | state->extraafter = 0; /* before newblk */ | ||
218 | error = xfs_dir_leaf_split(state, oldblk, | ||
219 | &state->extrablk); | ||
220 | if (error) | ||
221 | return(error); /* GROT: dir incon. */ | ||
222 | addblk = newblk; | ||
223 | } else { | ||
224 | state->extraafter = 1; /* after newblk */ | ||
225 | error = xfs_dir_leaf_split(state, newblk, | ||
226 | &state->extrablk); | ||
227 | if (error) | ||
228 | return(error); /* GROT: dir incon. */ | ||
229 | addblk = newblk; | ||
230 | } | ||
231 | break; | ||
232 | case XFS_DIR2_LEAFN_MAGIC: | 199 | case XFS_DIR2_LEAFN_MAGIC: |
233 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
234 | error = xfs_dir2_leafn_split(state, oldblk, newblk); | 200 | error = xfs_dir2_leafn_split(state, oldblk, newblk); |
235 | if (error) | 201 | if (error) |
236 | return error; | 202 | return error; |
@@ -363,7 +329,6 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
363 | size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - | 329 | size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - |
364 | (char *)oldroot); | 330 | (char *)oldroot); |
365 | } else { | 331 | } else { |
366 | ASSERT(XFS_DIR_IS_V2(mp)); | ||
367 | ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); | 332 | ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); |
368 | leaf = (xfs_dir2_leaf_t *)oldroot; | 333 | leaf = (xfs_dir2_leaf_t *)oldroot; |
369 | size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - | 334 | size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - |
@@ -379,8 +344,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
379 | * Set up the new root node. | 344 | * Set up the new root node. |
380 | */ | 345 | */ |
381 | error = xfs_da_node_create(args, | 346 | error = xfs_da_node_create(args, |
382 | args->whichfork == XFS_DATA_FORK && | 347 | (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0, |
383 | XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0, | ||
384 | be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); | 348 | be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); |
385 | if (error) | 349 | if (error) |
386 | return(error); | 350 | return(error); |
@@ -427,10 +391,9 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
427 | ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); | 391 | ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); |
428 | 392 | ||
429 | /* | 393 | /* |
430 | * With V2 the extra block is data or freespace. | 394 | * With V2 dirs the extra block is data or freespace. |
431 | */ | 395 | */ |
432 | useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) || | 396 | useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK; |
433 | state->args->whichfork == XFS_ATTR_FORK); | ||
434 | newcount = 1 + useextra; | 397 | newcount = 1 + useextra; |
435 | /* | 398 | /* |
436 | * Do we have to split the node? | 399 | * Do we have to split the node? |
@@ -624,7 +587,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
624 | ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); | 587 | ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); |
625 | ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); | 588 | ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); |
626 | ASSERT(newblk->blkno != 0); | 589 | ASSERT(newblk->blkno != 0); |
627 | if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) | 590 | if (state->args->whichfork == XFS_DATA_FORK) |
628 | ASSERT(newblk->blkno >= mp->m_dirleafblk && | 591 | ASSERT(newblk->blkno >= mp->m_dirleafblk && |
629 | newblk->blkno < mp->m_dirfreeblk); | 592 | newblk->blkno < mp->m_dirfreeblk); |
630 | 593 | ||
@@ -670,7 +633,7 @@ xfs_da_join(xfs_da_state_t *state) | |||
670 | save_blk = &state->altpath.blk[ state->path.active-1 ]; | 633 | save_blk = &state->altpath.blk[ state->path.active-1 ]; |
671 | ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); | 634 | ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); |
672 | ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || | 635 | ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || |
673 | drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp)); | 636 | drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); |
674 | 637 | ||
675 | /* | 638 | /* |
676 | * Walk back up the tree joining/deallocating as necessary. | 639 | * Walk back up the tree joining/deallocating as necessary. |
@@ -693,17 +656,7 @@ xfs_da_join(xfs_da_state_t *state) | |||
693 | return(0); | 656 | return(0); |
694 | xfs_attr_leaf_unbalance(state, drop_blk, save_blk); | 657 | xfs_attr_leaf_unbalance(state, drop_blk, save_blk); |
695 | break; | 658 | break; |
696 | case XFS_DIR_LEAF_MAGIC: | ||
697 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
698 | error = xfs_dir_leaf_toosmall(state, &action); | ||
699 | if (error) | ||
700 | return(error); | ||
701 | if (action == 0) | ||
702 | return(0); | ||
703 | xfs_dir_leaf_unbalance(state, drop_blk, save_blk); | ||
704 | break; | ||
705 | case XFS_DIR2_LEAFN_MAGIC: | 659 | case XFS_DIR2_LEAFN_MAGIC: |
706 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
707 | error = xfs_dir2_leafn_toosmall(state, &action); | 660 | error = xfs_dir2_leafn_toosmall(state, &action); |
708 | if (error) | 661 | if (error) |
709 | return error; | 662 | return error; |
@@ -790,7 +743,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) | |||
790 | ASSERT(bp != NULL); | 743 | ASSERT(bp != NULL); |
791 | blkinfo = bp->data; | 744 | blkinfo = bp->data; |
792 | if (be16_to_cpu(oldroot->hdr.level) == 1) { | 745 | if (be16_to_cpu(oldroot->hdr.level) == 1) { |
793 | ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || | 746 | ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC || |
794 | be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); | 747 | be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); |
795 | } else { | 748 | } else { |
796 | ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); | 749 | ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); |
@@ -951,14 +904,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path) | |||
951 | if (count == 0) | 904 | if (count == 0) |
952 | return; | 905 | return; |
953 | break; | 906 | break; |
954 | case XFS_DIR_LEAF_MAGIC: | ||
955 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
956 | lasthash = xfs_dir_leaf_lasthash(blk->bp, &count); | ||
957 | if (count == 0) | ||
958 | return; | ||
959 | break; | ||
960 | case XFS_DIR2_LEAFN_MAGIC: | 907 | case XFS_DIR2_LEAFN_MAGIC: |
961 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
962 | lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); | 908 | lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); |
963 | if (count == 0) | 909 | if (count == 0) |
964 | return; | 910 | return; |
@@ -1117,10 +1063,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1117 | * Descend thru the B-tree searching each level for the right | 1063 | * Descend thru the B-tree searching each level for the right |
1118 | * node to use, until the right hashval is found. | 1064 | * node to use, until the right hashval is found. |
1119 | */ | 1065 | */ |
1120 | if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp)) | 1066 | blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0; |
1121 | blkno = state->mp->m_dirleafblk; | ||
1122 | else | ||
1123 | blkno = 0; | ||
1124 | for (blk = &state->path.blk[0], state->path.active = 1; | 1067 | for (blk = &state->path.blk[0], state->path.active = 1; |
1125 | state->path.active <= XFS_DA_NODE_MAXDEPTH; | 1068 | state->path.active <= XFS_DA_NODE_MAXDEPTH; |
1126 | blk++, state->path.active++) { | 1069 | blk++, state->path.active++) { |
@@ -1137,7 +1080,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1137 | } | 1080 | } |
1138 | curr = blk->bp->data; | 1081 | curr = blk->bp->data; |
1139 | ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || | 1082 | ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || |
1140 | be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || | 1083 | be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC || |
1141 | be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); | 1084 | be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); |
1142 | 1085 | ||
1143 | /* | 1086 | /* |
@@ -1190,16 +1133,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1190 | blk->index = probe; | 1133 | blk->index = probe; |
1191 | blkno = be32_to_cpu(btree->before); | 1134 | blkno = be32_to_cpu(btree->before); |
1192 | } | 1135 | } |
1193 | } | 1136 | } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) { |
1194 | else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) { | ||
1195 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); | 1137 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); |
1196 | break; | 1138 | break; |
1197 | } | 1139 | } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) { |
1198 | else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) { | ||
1199 | blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL); | ||
1200 | break; | ||
1201 | } | ||
1202 | else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) { | ||
1203 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); | 1140 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); |
1204 | break; | 1141 | break; |
1205 | } | 1142 | } |
@@ -1212,12 +1149,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1212 | * next leaf and keep searching. | 1149 | * next leaf and keep searching. |
1213 | */ | 1150 | */ |
1214 | for (;;) { | 1151 | for (;;) { |
1215 | if (blk->magic == XFS_DIR_LEAF_MAGIC) { | 1152 | if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { |
1216 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
1217 | retval = xfs_dir_leaf_lookup_int(blk->bp, args, | ||
1218 | &blk->index); | ||
1219 | } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { | ||
1220 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
1221 | retval = xfs_dir2_leafn_lookup_int(blk->bp, args, | 1153 | retval = xfs_dir2_leafn_lookup_int(blk->bp, args, |
1222 | &blk->index, state); | 1154 | &blk->index, state); |
1223 | } | 1155 | } |
@@ -1270,7 +1202,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
1270 | old_info = old_blk->bp->data; | 1202 | old_info = old_blk->bp->data; |
1271 | new_info = new_blk->bp->data; | 1203 | new_info = new_blk->bp->data; |
1272 | ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || | 1204 | ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || |
1273 | old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || | 1205 | old_blk->magic == XFS_DIR2_LEAFN_MAGIC || |
1274 | old_blk->magic == XFS_ATTR_LEAF_MAGIC); | 1206 | old_blk->magic == XFS_ATTR_LEAF_MAGIC); |
1275 | ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); | 1207 | ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); |
1276 | ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); | 1208 | ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); |
@@ -1280,12 +1212,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
1280 | case XFS_ATTR_LEAF_MAGIC: | 1212 | case XFS_ATTR_LEAF_MAGIC: |
1281 | before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); | 1213 | before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); |
1282 | break; | 1214 | break; |
1283 | case XFS_DIR_LEAF_MAGIC: | ||
1284 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
1285 | before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp); | ||
1286 | break; | ||
1287 | case XFS_DIR2_LEAFN_MAGIC: | 1215 | case XFS_DIR2_LEAFN_MAGIC: |
1288 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
1289 | before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); | 1216 | before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); |
1290 | break; | 1217 | break; |
1291 | case XFS_DA_NODE_MAGIC: | 1218 | case XFS_DA_NODE_MAGIC: |
@@ -1404,7 +1331,7 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1404 | save_info = save_blk->bp->data; | 1331 | save_info = save_blk->bp->data; |
1405 | drop_info = drop_blk->bp->data; | 1332 | drop_info = drop_blk->bp->data; |
1406 | ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || | 1333 | ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || |
1407 | save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || | 1334 | save_blk->magic == XFS_DIR2_LEAFN_MAGIC || |
1408 | save_blk->magic == XFS_ATTR_LEAF_MAGIC); | 1335 | save_blk->magic == XFS_ATTR_LEAF_MAGIC); |
1409 | ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); | 1336 | ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); |
1410 | ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); | 1337 | ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); |
@@ -1529,7 +1456,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | |||
1529 | ASSERT(blk->bp != NULL); | 1456 | ASSERT(blk->bp != NULL); |
1530 | info = blk->bp->data; | 1457 | info = blk->bp->data; |
1531 | ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || | 1458 | ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || |
1532 | be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || | 1459 | be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC || |
1533 | be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); | 1460 | be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); |
1534 | blk->magic = be16_to_cpu(info->magic); | 1461 | blk->magic = be16_to_cpu(info->magic); |
1535 | if (blk->magic == XFS_DA_NODE_MAGIC) { | 1462 | if (blk->magic == XFS_DA_NODE_MAGIC) { |
@@ -1548,20 +1475,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | |||
1548 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, | 1475 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, |
1549 | NULL); | 1476 | NULL); |
1550 | break; | 1477 | break; |
1551 | case XFS_DIR_LEAF_MAGIC: | ||
1552 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
1553 | blk->hashval = xfs_dir_leaf_lasthash(blk->bp, | ||
1554 | NULL); | ||
1555 | break; | ||
1556 | case XFS_DIR2_LEAFN_MAGIC: | 1478 | case XFS_DIR2_LEAFN_MAGIC: |
1557 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
1558 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, | 1479 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, |
1559 | NULL); | 1480 | NULL); |
1560 | break; | 1481 | break; |
1561 | default: | 1482 | default: |
1562 | ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || | 1483 | ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || |
1563 | blk->magic == | 1484 | blk->magic == XFS_DIR2_LEAFN_MAGIC); |
1564 | XFS_DIRX_LEAF_MAGIC(state->mp)); | ||
1565 | break; | 1485 | break; |
1566 | } | 1486 | } |
1567 | } | 1487 | } |
@@ -1620,7 +1540,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
1620 | xfs_bmbt_irec_t *mapp; | 1540 | xfs_bmbt_irec_t *mapp; |
1621 | xfs_inode_t *dp; | 1541 | xfs_inode_t *dp; |
1622 | int nmap, error, w, count, c, got, i, mapi; | 1542 | int nmap, error, w, count, c, got, i, mapi; |
1623 | xfs_fsize_t size; | ||
1624 | xfs_trans_t *tp; | 1543 | xfs_trans_t *tp; |
1625 | xfs_mount_t *mp; | 1544 | xfs_mount_t *mp; |
1626 | 1545 | ||
@@ -1631,7 +1550,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
1631 | /* | 1550 | /* |
1632 | * For new directories adjust the file offset and block count. | 1551 | * For new directories adjust the file offset and block count. |
1633 | */ | 1552 | */ |
1634 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) { | 1553 | if (w == XFS_DATA_FORK) { |
1635 | bno = mp->m_dirleafblk; | 1554 | bno = mp->m_dirleafblk; |
1636 | count = mp->m_dirblkfsbs; | 1555 | count = mp->m_dirblkfsbs; |
1637 | } else { | 1556 | } else { |
@@ -1641,10 +1560,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
1641 | /* | 1560 | /* |
1642 | * Find a spot in the file space to put the new block. | 1561 | * Find a spot in the file space to put the new block. |
1643 | */ | 1562 | */ |
1644 | if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) { | 1563 | if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) |
1645 | return error; | 1564 | return error; |
1646 | } | 1565 | if (w == XFS_DATA_FORK) |
1647 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) | ||
1648 | ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); | 1566 | ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); |
1649 | /* | 1567 | /* |
1650 | * Try mapping it in one filesystem block. | 1568 | * Try mapping it in one filesystem block. |
@@ -1655,7 +1573,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
1655 | XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| | 1573 | XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| |
1656 | XFS_BMAPI_CONTIG, | 1574 | XFS_BMAPI_CONTIG, |
1657 | args->firstblock, args->total, &map, &nmap, | 1575 | args->firstblock, args->total, &map, &nmap, |
1658 | args->flist))) { | 1576 | args->flist, NULL))) { |
1659 | return error; | 1577 | return error; |
1660 | } | 1578 | } |
1661 | ASSERT(nmap <= 1); | 1579 | ASSERT(nmap <= 1); |
@@ -1676,7 +1594,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
1676 | XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE| | 1594 | XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE| |
1677 | XFS_BMAPI_METADATA, | 1595 | XFS_BMAPI_METADATA, |
1678 | args->firstblock, args->total, | 1596 | args->firstblock, args->total, |
1679 | &mapp[mapi], &nmap, args->flist))) { | 1597 | &mapp[mapi], &nmap, args->flist, |
1598 | NULL))) { | ||
1680 | kmem_free(mapp, sizeof(*mapp) * count); | 1599 | kmem_free(mapp, sizeof(*mapp) * count); |
1681 | return error; | 1600 | return error; |
1682 | } | 1601 | } |
@@ -1705,19 +1624,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
1705 | if (mapp != &map) | 1624 | if (mapp != &map) |
1706 | kmem_free(mapp, sizeof(*mapp) * count); | 1625 | kmem_free(mapp, sizeof(*mapp) * count); |
1707 | *new_blkno = (xfs_dablk_t)bno; | 1626 | *new_blkno = (xfs_dablk_t)bno; |
1708 | /* | ||
1709 | * For version 1 directories, adjust the file size if it changed. | ||
1710 | */ | ||
1711 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { | ||
1712 | ASSERT(mapi == 1); | ||
1713 | if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) | ||
1714 | return error; | ||
1715 | size = XFS_FSB_TO_B(mp, bno); | ||
1716 | if (size != dp->i_d.di_size) { | ||
1717 | dp->i_d.di_size = size; | ||
1718 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | ||
1719 | } | ||
1720 | } | ||
1721 | return 0; | 1627 | return 0; |
1722 | } | 1628 | } |
1723 | 1629 | ||
@@ -1742,7 +1648,6 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1742 | int error, w, entno, level, dead_level; | 1648 | int error, w, entno, level, dead_level; |
1743 | xfs_da_blkinfo_t *dead_info, *sib_info; | 1649 | xfs_da_blkinfo_t *dead_info, *sib_info; |
1744 | xfs_da_intnode_t *par_node, *dead_node; | 1650 | xfs_da_intnode_t *par_node, *dead_node; |
1745 | xfs_dir_leafblock_t *dead_leaf; | ||
1746 | xfs_dir2_leaf_t *dead_leaf2; | 1651 | xfs_dir2_leaf_t *dead_leaf2; |
1747 | xfs_dahash_t dead_hash; | 1652 | xfs_dahash_t dead_hash; |
1748 | 1653 | ||
@@ -1753,11 +1658,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1753 | w = args->whichfork; | 1658 | w = args->whichfork; |
1754 | ASSERT(w == XFS_DATA_FORK); | 1659 | ASSERT(w == XFS_DATA_FORK); |
1755 | mp = ip->i_mount; | 1660 | mp = ip->i_mount; |
1756 | if (XFS_DIR_IS_V2(mp)) { | 1661 | lastoff = mp->m_dirfreeblk; |
1757 | lastoff = mp->m_dirfreeblk; | 1662 | error = xfs_bmap_last_before(tp, ip, &lastoff, w); |
1758 | error = xfs_bmap_last_before(tp, ip, &lastoff, w); | ||
1759 | } else | ||
1760 | error = xfs_bmap_last_offset(tp, ip, &lastoff, w); | ||
1761 | if (error) | 1663 | if (error) |
1762 | return error; | 1664 | return error; |
1763 | if (unlikely(lastoff == 0)) { | 1665 | if (unlikely(lastoff == 0)) { |
@@ -1780,14 +1682,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1780 | /* | 1682 | /* |
1781 | * Get values from the moved block. | 1683 | * Get values from the moved block. |
1782 | */ | 1684 | */ |
1783 | if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) { | 1685 | if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) { |
1784 | ASSERT(XFS_DIR_IS_V1(mp)); | ||
1785 | dead_leaf = (xfs_dir_leafblock_t *)dead_info; | ||
1786 | dead_level = 0; | ||
1787 | dead_hash = | ||
1788 | INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT); | ||
1789 | } else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) { | ||
1790 | ASSERT(XFS_DIR_IS_V2(mp)); | ||
1791 | dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; | 1686 | dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; |
1792 | dead_level = 0; | 1687 | dead_level = 0; |
1793 | dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); | 1688 | dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); |
@@ -1842,7 +1737,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
1842 | xfs_da_buf_done(sib_buf); | 1737 | xfs_da_buf_done(sib_buf); |
1843 | sib_buf = NULL; | 1738 | sib_buf = NULL; |
1844 | } | 1739 | } |
1845 | par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk; | 1740 | par_blkno = mp->m_dirleafblk; |
1846 | level = -1; | 1741 | level = -1; |
1847 | /* | 1742 | /* |
1848 | * Walk down the tree looking for the parent of the moved block. | 1743 | * Walk down the tree looking for the parent of the moved block. |
@@ -1941,8 +1836,6 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | |||
1941 | { | 1836 | { |
1942 | xfs_inode_t *dp; | 1837 | xfs_inode_t *dp; |
1943 | int done, error, w, count; | 1838 | int done, error, w, count; |
1944 | xfs_fileoff_t bno; | ||
1945 | xfs_fsize_t size; | ||
1946 | xfs_trans_t *tp; | 1839 | xfs_trans_t *tp; |
1947 | xfs_mount_t *mp; | 1840 | xfs_mount_t *mp; |
1948 | 1841 | ||
@@ -1950,7 +1843,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | |||
1950 | w = args->whichfork; | 1843 | w = args->whichfork; |
1951 | tp = args->trans; | 1844 | tp = args->trans; |
1952 | mp = dp->i_mount; | 1845 | mp = dp->i_mount; |
1953 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) | 1846 | if (w == XFS_DATA_FORK) |
1954 | count = mp->m_dirblkfsbs; | 1847 | count = mp->m_dirblkfsbs; |
1955 | else | 1848 | else |
1956 | count = 1; | 1849 | count = 1; |
@@ -1961,34 +1854,17 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | |||
1961 | */ | 1854 | */ |
1962 | if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, | 1855 | if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, |
1963 | XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, | 1856 | XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, |
1964 | 0, args->firstblock, args->flist, | 1857 | 0, args->firstblock, args->flist, NULL, |
1965 | &done)) == ENOSPC) { | 1858 | &done)) == ENOSPC) { |
1966 | if (w != XFS_DATA_FORK) | 1859 | if (w != XFS_DATA_FORK) |
1967 | goto done; | 1860 | break; |
1968 | if ((error = xfs_da_swap_lastblock(args, &dead_blkno, | 1861 | if ((error = xfs_da_swap_lastblock(args, &dead_blkno, |
1969 | &dead_buf))) | 1862 | &dead_buf))) |
1970 | goto done; | 1863 | break; |
1971 | } else if (error) | 1864 | } else { |
1972 | goto done; | ||
1973 | else | ||
1974 | break; | 1865 | break; |
1975 | } | ||
1976 | ASSERT(done); | ||
1977 | xfs_da_binval(tp, dead_buf); | ||
1978 | /* | ||
1979 | * Adjust the directory size for version 1. | ||
1980 | */ | ||
1981 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { | ||
1982 | if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) | ||
1983 | return error; | ||
1984 | size = XFS_FSB_TO_B(dp->i_mount, bno); | ||
1985 | if (size != dp->i_d.di_size) { | ||
1986 | dp->i_d.di_size = size; | ||
1987 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | ||
1988 | } | 1866 | } |
1989 | } | 1867 | } |
1990 | return 0; | ||
1991 | done: | ||
1992 | xfs_da_binval(tp, dead_buf); | 1868 | xfs_da_binval(tp, dead_buf); |
1993 | return error; | 1869 | return error; |
1994 | } | 1870 | } |
@@ -2049,10 +1925,7 @@ xfs_da_do_buf( | |||
2049 | xfs_dabuf_t *rbp; | 1925 | xfs_dabuf_t *rbp; |
2050 | 1926 | ||
2051 | mp = dp->i_mount; | 1927 | mp = dp->i_mount; |
2052 | if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) | 1928 | nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; |
2053 | nfsb = mp->m_dirblkfsbs; | ||
2054 | else | ||
2055 | nfsb = 1; | ||
2056 | mappedbno = *mappedbnop; | 1929 | mappedbno = *mappedbnop; |
2057 | /* | 1930 | /* |
2058 | * Caller doesn't have a mapping. -2 means don't complain | 1931 | * Caller doesn't have a mapping. -2 means don't complain |
@@ -2086,7 +1959,7 @@ xfs_da_do_buf( | |||
2086 | nfsb, | 1959 | nfsb, |
2087 | XFS_BMAPI_METADATA | | 1960 | XFS_BMAPI_METADATA | |
2088 | XFS_BMAPI_AFLAG(whichfork), | 1961 | XFS_BMAPI_AFLAG(whichfork), |
2089 | NULL, 0, mapp, &nmap, NULL))) | 1962 | NULL, 0, mapp, &nmap, NULL, NULL))) |
2090 | goto exit0; | 1963 | goto exit0; |
2091 | } | 1964 | } |
2092 | } else { | 1965 | } else { |
@@ -2198,7 +2071,6 @@ xfs_da_do_buf( | |||
2198 | magic1 = be32_to_cpu(data->hdr.magic); | 2071 | magic1 = be32_to_cpu(data->hdr.magic); |
2199 | if (unlikely( | 2072 | if (unlikely( |
2200 | XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && | 2073 | XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && |
2201 | (magic != XFS_DIR_LEAF_MAGIC) && | ||
2202 | (magic != XFS_ATTR_LEAF_MAGIC) && | 2074 | (magic != XFS_ATTR_LEAF_MAGIC) && |
2203 | (magic != XFS_DIR2_LEAF1_MAGIC) && | 2075 | (magic != XFS_DIR2_LEAF1_MAGIC) && |
2204 | (magic != XFS_DIR2_LEAFN_MAGIC) && | 2076 | (magic != XFS_DIR2_LEAFN_MAGIC) && |
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index 243a730d5ec8..4ab865ec8b82 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h | |||
@@ -36,14 +36,10 @@ struct zone; | |||
36 | * level in the Btree, and to identify which type of block this is. | 36 | * level in the Btree, and to identify which type of block this is. |
37 | */ | 37 | */ |
38 | #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ | 38 | #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ |
39 | #define XFS_DIR_LEAF_MAGIC 0xfeeb /* magic number: directory leaf blks */ | ||
40 | #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ | 39 | #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ |
41 | #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ | 40 | #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ |
42 | #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ | 41 | #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ |
43 | 42 | ||
44 | #define XFS_DIRX_LEAF_MAGIC(mp) \ | ||
45 | (XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC) | ||
46 | |||
47 | typedef struct xfs_da_blkinfo { | 43 | typedef struct xfs_da_blkinfo { |
48 | __be32 forw; /* previous block in list */ | 44 | __be32 forw; /* previous block in list */ |
49 | __be32 back; /* following block in list */ | 45 | __be32 back; /* following block in list */ |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 4968a6358e61..80562b60fb95 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -54,24 +52,14 @@ xfs_swapext( | |||
54 | xfs_swapext_t __user *sxu) | 52 | xfs_swapext_t __user *sxu) |
55 | { | 53 | { |
56 | xfs_swapext_t *sxp; | 54 | xfs_swapext_t *sxp; |
57 | xfs_inode_t *ip=NULL, *tip=NULL, *ips[2]; | 55 | xfs_inode_t *ip=NULL, *tip=NULL; |
58 | xfs_trans_t *tp; | ||
59 | xfs_mount_t *mp; | 56 | xfs_mount_t *mp; |
60 | xfs_bstat_t *sbp; | ||
61 | struct file *fp = NULL, *tfp = NULL; | 57 | struct file *fp = NULL, *tfp = NULL; |
62 | vnode_t *vp, *tvp; | 58 | bhv_vnode_t *vp, *tvp; |
63 | static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL; | ||
64 | int ilf_fields, tilf_fields; | ||
65 | int error = 0; | 59 | int error = 0; |
66 | xfs_ifork_t *tempifp, *ifp, *tifp; | ||
67 | __uint64_t tmp; | ||
68 | int aforkblks = 0; | ||
69 | int taforkblks = 0; | ||
70 | char locked = 0; | ||
71 | 60 | ||
72 | sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); | 61 | sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); |
73 | tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); | 62 | if (!sxp) { |
74 | if (!sxp || !tempifp) { | ||
75 | error = XFS_ERROR(ENOMEM); | 63 | error = XFS_ERROR(ENOMEM); |
76 | goto error0; | 64 | goto error0; |
77 | } | 65 | } |
@@ -118,14 +106,56 @@ xfs_swapext( | |||
118 | 106 | ||
119 | mp = ip->i_mount; | 107 | mp = ip->i_mount; |
120 | 108 | ||
121 | sbp = &sxp->sx_stat; | ||
122 | |||
123 | if (XFS_FORCED_SHUTDOWN(mp)) { | 109 | if (XFS_FORCED_SHUTDOWN(mp)) { |
124 | error = XFS_ERROR(EIO); | 110 | error = XFS_ERROR(EIO); |
125 | goto error0; | 111 | goto error0; |
126 | } | 112 | } |
127 | 113 | ||
128 | locked = 1; | 114 | error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp); |
115 | |||
116 | error0: | ||
117 | if (fp != NULL) | ||
118 | fput(fp); | ||
119 | if (tfp != NULL) | ||
120 | fput(tfp); | ||
121 | |||
122 | if (sxp != NULL) | ||
123 | kmem_free(sxp, sizeof(xfs_swapext_t)); | ||
124 | |||
125 | return error; | ||
126 | } | ||
127 | |||
128 | int | ||
129 | xfs_swap_extents( | ||
130 | xfs_inode_t *ip, | ||
131 | xfs_inode_t *tip, | ||
132 | xfs_swapext_t *sxp) | ||
133 | { | ||
134 | xfs_mount_t *mp; | ||
135 | xfs_inode_t *ips[2]; | ||
136 | xfs_trans_t *tp; | ||
137 | xfs_bstat_t *sbp = &sxp->sx_stat; | ||
138 | bhv_vnode_t *vp, *tvp; | ||
139 | xfs_ifork_t *tempifp, *ifp, *tifp; | ||
140 | int ilf_fields, tilf_fields; | ||
141 | static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL; | ||
142 | int error = 0; | ||
143 | int aforkblks = 0; | ||
144 | int taforkblks = 0; | ||
145 | __uint64_t tmp; | ||
146 | char locked = 0; | ||
147 | |||
148 | mp = ip->i_mount; | ||
149 | |||
150 | tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); | ||
151 | if (!tempifp) { | ||
152 | error = XFS_ERROR(ENOMEM); | ||
153 | goto error0; | ||
154 | } | ||
155 | |||
156 | sbp = &sxp->sx_stat; | ||
157 | vp = XFS_ITOV(ip); | ||
158 | tvp = XFS_ITOV(tip); | ||
129 | 159 | ||
130 | /* Lock in i_ino order */ | 160 | /* Lock in i_ino order */ |
131 | if (ip->i_ino < tip->i_ino) { | 161 | if (ip->i_ino < tip->i_ino) { |
@@ -137,6 +167,7 @@ xfs_swapext( | |||
137 | } | 167 | } |
138 | 168 | ||
139 | xfs_lock_inodes(ips, 2, 0, lock_flags); | 169 | xfs_lock_inodes(ips, 2, 0, lock_flags); |
170 | locked = 1; | ||
140 | 171 | ||
141 | /* Check permissions */ | 172 | /* Check permissions */ |
142 | error = xfs_iaccess(ip, S_IWUSR, NULL); | 173 | error = xfs_iaccess(ip, S_IWUSR, NULL); |
@@ -169,7 +200,7 @@ xfs_swapext( | |||
169 | 200 | ||
170 | if (VN_CACHED(tvp) != 0) { | 201 | if (VN_CACHED(tvp) != 0) { |
171 | xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); | 202 | xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); |
172 | VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED); | 203 | bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED); |
173 | } | 204 | } |
174 | 205 | ||
175 | /* Verify O_DIRECT for ftmp */ | 206 | /* Verify O_DIRECT for ftmp */ |
@@ -214,7 +245,7 @@ xfs_swapext( | |||
214 | /* We need to fail if the file is memory mapped. Once we have tossed | 245 | /* We need to fail if the file is memory mapped. Once we have tossed |
215 | * all existing pages, the page fault will have no option | 246 | * all existing pages, the page fault will have no option |
216 | * but to go to the filesystem for pages. By making the page fault call | 247 | * but to go to the filesystem for pages. By making the page fault call |
217 | * VOP_READ (or write in the case of autogrow) they block on the iolock | 248 | * vop_read (or write in the case of autogrow) they block on the iolock |
218 | * until we have switched the extents. | 249 | * until we have switched the extents. |
219 | */ | 250 | */ |
220 | if (VN_MAPPED(vp)) { | 251 | if (VN_MAPPED(vp)) { |
@@ -233,7 +264,7 @@ xfs_swapext( | |||
233 | * fields change. | 264 | * fields change. |
234 | */ | 265 | */ |
235 | 266 | ||
236 | VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF); | 267 | bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); |
237 | 268 | ||
238 | tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); | 269 | tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); |
239 | if ((error = xfs_trans_reserve(tp, 0, | 270 | if ((error = xfs_trans_reserve(tp, 0, |
@@ -360,16 +391,7 @@ xfs_swapext( | |||
360 | xfs_iunlock(ip, lock_flags); | 391 | xfs_iunlock(ip, lock_flags); |
361 | xfs_iunlock(tip, lock_flags); | 392 | xfs_iunlock(tip, lock_flags); |
362 | } | 393 | } |
363 | |||
364 | if (fp != NULL) | ||
365 | fput(fp); | ||
366 | if (tfp != NULL) | ||
367 | fput(tfp); | ||
368 | |||
369 | if (sxp != NULL) | ||
370 | kmem_free(sxp, sizeof(xfs_swapext_t)); | ||
371 | if (tempifp != NULL) | 394 | if (tempifp != NULL) |
372 | kmem_free(tempifp, sizeof(xfs_ifork_t)); | 395 | kmem_free(tempifp, sizeof(xfs_ifork_t)); |
373 | |||
374 | return error; | 396 | return error; |
375 | } | 397 | } |
diff --git a/fs/xfs/xfs_dfrag.h b/fs/xfs/xfs_dfrag.h index f678559abc45..da178205be68 100644 --- a/fs/xfs/xfs_dfrag.h +++ b/fs/xfs/xfs_dfrag.h | |||
@@ -48,6 +48,9 @@ typedef struct xfs_swapext | |||
48 | */ | 48 | */ |
49 | int xfs_swapext(struct xfs_swapext __user *sx); | 49 | int xfs_swapext(struct xfs_swapext __user *sx); |
50 | 50 | ||
51 | int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip, | ||
52 | struct xfs_swapext *sxp); | ||
53 | |||
51 | #endif /* __KERNEL__ */ | 54 | #endif /* __KERNEL__ */ |
52 | 55 | ||
53 | #endif /* __XFS_DFRAG_H__ */ | 56 | #endif /* __XFS_DFRAG_H__ */ |
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index 79d0d9e1fbab..b33826961c45 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h | |||
@@ -85,7 +85,6 @@ typedef struct xfs_dinode | |||
85 | union { | 85 | union { |
86 | xfs_bmdr_block_t di_bmbt; /* btree root block */ | 86 | xfs_bmdr_block_t di_bmbt; /* btree root block */ |
87 | xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ | 87 | xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ |
88 | xfs_dir_shortform_t di_dirsf; /* shortform directory */ | ||
89 | xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ | 88 | xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ |
90 | char di_c[1]; /* local contents */ | 89 | char di_c[1]; /* local contents */ |
91 | xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ | 90 | xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ |
@@ -257,6 +256,7 @@ typedef enum xfs_dinode_fmt | |||
257 | #define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ | 256 | #define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ |
258 | #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ | 257 | #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ |
259 | #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ | 258 | #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ |
259 | #define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */ | ||
260 | #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) | 260 | #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) |
261 | #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) | 261 | #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) |
262 | #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) | 262 | #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) |
@@ -270,12 +270,13 @@ typedef enum xfs_dinode_fmt | |||
270 | #define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT) | 270 | #define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT) |
271 | #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) | 271 | #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) |
272 | #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) | 272 | #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) |
273 | #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT) | ||
273 | 274 | ||
274 | #define XFS_DIFLAG_ANY \ | 275 | #define XFS_DIFLAG_ANY \ |
275 | (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ | 276 | (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ |
276 | XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ | 277 | XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ |
277 | XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ | 278 | XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ |
278 | XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ | 279 | XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ |
279 | XFS_DIFLAG_EXTSZINHERIT) | 280 | XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG) |
280 | 281 | ||
281 | #endif /* __XFS_DINODE_H__ */ | 282 | #endif /* __XFS_DINODE_H__ */ |
diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c deleted file mode 100644 index 9cc702a839a3..000000000000 --- a/fs/xfs/xfs_dir.c +++ /dev/null | |||
@@ -1,1217 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_fs.h" | ||
20 | #include "xfs_types.h" | ||
21 | #include "xfs_log.h" | ||
22 | #include "xfs_inum.h" | ||
23 | #include "xfs_trans.h" | ||
24 | #include "xfs_sb.h" | ||
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dir2.h" | ||
27 | #include "xfs_dmapi.h" | ||
28 | #include "xfs_mount.h" | ||
29 | #include "xfs_da_btree.h" | ||
30 | #include "xfs_bmap_btree.h" | ||
31 | #include "xfs_alloc_btree.h" | ||
32 | #include "xfs_ialloc_btree.h" | ||
33 | #include "xfs_alloc.h" | ||
34 | #include "xfs_btree.h" | ||
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | ||
37 | #include "xfs_attr_sf.h" | ||
38 | #include "xfs_dinode.h" | ||
39 | #include "xfs_inode.h" | ||
40 | #include "xfs_bmap.h" | ||
41 | #include "xfs_dir_leaf.h" | ||
42 | #include "xfs_error.h" | ||
43 | |||
44 | /* | ||
45 | * xfs_dir.c | ||
46 | * | ||
47 | * Provide the external interfaces to manage directories. | ||
48 | */ | ||
49 | |||
50 | /*======================================================================== | ||
51 | * Function prototypes for the kernel. | ||
52 | *========================================================================*/ | ||
53 | |||
54 | /* | ||
55 | * Functions for the dirops interfaces. | ||
56 | */ | ||
57 | static void xfs_dir_mount(struct xfs_mount *mp); | ||
58 | |||
59 | static int xfs_dir_isempty(struct xfs_inode *dp); | ||
60 | |||
61 | static int xfs_dir_init(struct xfs_trans *trans, | ||
62 | struct xfs_inode *dir, | ||
63 | struct xfs_inode *parent_dir); | ||
64 | |||
65 | static int xfs_dir_createname(struct xfs_trans *trans, | ||
66 | struct xfs_inode *dp, | ||
67 | char *name_string, | ||
68 | int name_len, | ||
69 | xfs_ino_t inode_number, | ||
70 | xfs_fsblock_t *firstblock, | ||
71 | xfs_bmap_free_t *flist, | ||
72 | xfs_extlen_t total); | ||
73 | |||
74 | static int xfs_dir_lookup(struct xfs_trans *tp, | ||
75 | struct xfs_inode *dp, | ||
76 | char *name_string, | ||
77 | int name_length, | ||
78 | xfs_ino_t *inode_number); | ||
79 | |||
80 | static int xfs_dir_removename(struct xfs_trans *trans, | ||
81 | struct xfs_inode *dp, | ||
82 | char *name_string, | ||
83 | int name_length, | ||
84 | xfs_ino_t ino, | ||
85 | xfs_fsblock_t *firstblock, | ||
86 | xfs_bmap_free_t *flist, | ||
87 | xfs_extlen_t total); | ||
88 | |||
89 | static int xfs_dir_getdents(struct xfs_trans *tp, | ||
90 | struct xfs_inode *dp, | ||
91 | struct uio *uiop, | ||
92 | int *eofp); | ||
93 | |||
94 | static int xfs_dir_replace(struct xfs_trans *tp, | ||
95 | struct xfs_inode *dp, | ||
96 | char *name_string, | ||
97 | int name_length, | ||
98 | xfs_ino_t inode_number, | ||
99 | xfs_fsblock_t *firstblock, | ||
100 | xfs_bmap_free_t *flist, | ||
101 | xfs_extlen_t total); | ||
102 | |||
103 | static int xfs_dir_canenter(struct xfs_trans *tp, | ||
104 | struct xfs_inode *dp, | ||
105 | char *name_string, | ||
106 | int name_length); | ||
107 | |||
108 | static int xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, | ||
109 | xfs_dinode_t *dip); | ||
110 | |||
111 | xfs_dirops_t xfsv1_dirops = { | ||
112 | .xd_mount = xfs_dir_mount, | ||
113 | .xd_isempty = xfs_dir_isempty, | ||
114 | .xd_init = xfs_dir_init, | ||
115 | .xd_createname = xfs_dir_createname, | ||
116 | .xd_lookup = xfs_dir_lookup, | ||
117 | .xd_removename = xfs_dir_removename, | ||
118 | .xd_getdents = xfs_dir_getdents, | ||
119 | .xd_replace = xfs_dir_replace, | ||
120 | .xd_canenter = xfs_dir_canenter, | ||
121 | .xd_shortform_validate_ondisk = xfs_dir_shortform_validate_ondisk, | ||
122 | .xd_shortform_to_single = xfs_dir_shortform_to_leaf, | ||
123 | }; | ||
124 | |||
125 | /* | ||
126 | * Internal routines when dirsize == XFS_LBSIZE(mp). | ||
127 | */ | ||
128 | STATIC int xfs_dir_leaf_lookup(xfs_da_args_t *args); | ||
129 | STATIC int xfs_dir_leaf_removename(xfs_da_args_t *args, int *number_entries, | ||
130 | int *total_namebytes); | ||
131 | STATIC int xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, | ||
132 | uio_t *uio, int *eofp, | ||
133 | xfs_dirent_t *dbp, | ||
134 | xfs_dir_put_t put); | ||
135 | STATIC int xfs_dir_leaf_replace(xfs_da_args_t *args); | ||
136 | |||
137 | /* | ||
138 | * Internal routines when dirsize > XFS_LBSIZE(mp). | ||
139 | */ | ||
140 | STATIC int xfs_dir_node_addname(xfs_da_args_t *args); | ||
141 | STATIC int xfs_dir_node_lookup(xfs_da_args_t *args); | ||
142 | STATIC int xfs_dir_node_removename(xfs_da_args_t *args); | ||
143 | STATIC int xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, | ||
144 | uio_t *uio, int *eofp, | ||
145 | xfs_dirent_t *dbp, | ||
146 | xfs_dir_put_t put); | ||
147 | STATIC int xfs_dir_node_replace(xfs_da_args_t *args); | ||
148 | |||
149 | #if defined(XFS_DIR_TRACE) | ||
150 | ktrace_t *xfs_dir_trace_buf; | ||
151 | #endif | ||
152 | |||
153 | |||
154 | /*======================================================================== | ||
155 | * Overall external interface routines. | ||
156 | *========================================================================*/ | ||
157 | |||
158 | xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; | ||
159 | |||
160 | /* | ||
161 | * One-time startup routine called from xfs_init(). | ||
162 | */ | ||
163 | void | ||
164 | xfs_dir_startup(void) | ||
165 | { | ||
166 | xfs_dir_hash_dot = xfs_da_hashname(".", 1); | ||
167 | xfs_dir_hash_dotdot = xfs_da_hashname("..", 2); | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * Initialize directory-related fields in the mount structure. | ||
172 | */ | ||
173 | static void | ||
174 | xfs_dir_mount(xfs_mount_t *mp) | ||
175 | { | ||
176 | uint shortcount, leafcount, count; | ||
177 | |||
178 | mp->m_dirversion = 1; | ||
179 | if (!(mp->m_flags & XFS_MOUNT_ATTR2)) { | ||
180 | shortcount = (mp->m_attroffset - | ||
181 | (uint)sizeof(xfs_dir_sf_hdr_t)) / | ||
182 | (uint)sizeof(xfs_dir_sf_entry_t); | ||
183 | leafcount = (XFS_LBSIZE(mp) - | ||
184 | (uint)sizeof(xfs_dir_leaf_hdr_t)) / | ||
185 | ((uint)sizeof(xfs_dir_leaf_entry_t) + | ||
186 | (uint)sizeof(xfs_dir_leaf_name_t)); | ||
187 | } else { | ||
188 | shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) - | ||
189 | (uint)sizeof(xfs_dir_sf_hdr_t)) / | ||
190 | (uint)sizeof(xfs_dir_sf_entry_t); | ||
191 | leafcount = (XFS_LBSIZE(mp) - | ||
192 | (uint)sizeof(xfs_dir_leaf_hdr_t)) / | ||
193 | ((uint)sizeof(xfs_dir_leaf_entry_t) + | ||
194 | (uint)sizeof(xfs_dir_leaf_name_t)); | ||
195 | } | ||
196 | count = shortcount > leafcount ? shortcount : leafcount; | ||
197 | mp->m_dircook_elog = xfs_da_log2_roundup(count + 1); | ||
198 | ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog); | ||
199 | mp->m_dir_node_ents = mp->m_attr_node_ents = | ||
200 | (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) / | ||
201 | (uint)sizeof(xfs_da_node_entry_t); | ||
202 | mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100; | ||
203 | mp->m_dirblksize = mp->m_sb.sb_blocksize; | ||
204 | mp->m_dirblkfsbs = 1; | ||
205 | } | ||
206 | |||
207 | /* | ||
208 | * Return 1 if directory contains only "." and "..". | ||
209 | */ | ||
210 | static int | ||
211 | xfs_dir_isempty(xfs_inode_t *dp) | ||
212 | { | ||
213 | xfs_dir_sf_hdr_t *hdr; | ||
214 | |||
215 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
216 | if (dp->i_d.di_size == 0) | ||
217 | return(1); | ||
218 | if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) | ||
219 | return(0); | ||
220 | hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data; | ||
221 | return(hdr->count == 0); | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Initialize a directory with its "." and ".." entries. | ||
226 | */ | ||
227 | static int | ||
228 | xfs_dir_init(xfs_trans_t *trans, xfs_inode_t *dir, xfs_inode_t *parent_dir) | ||
229 | { | ||
230 | xfs_da_args_t args; | ||
231 | int error; | ||
232 | |||
233 | memset((char *)&args, 0, sizeof(args)); | ||
234 | args.dp = dir; | ||
235 | args.trans = trans; | ||
236 | |||
237 | ASSERT((dir->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
238 | if ((error = xfs_dir_ino_validate(trans->t_mountp, parent_dir->i_ino))) | ||
239 | return error; | ||
240 | |||
241 | return(xfs_dir_shortform_create(&args, parent_dir->i_ino)); | ||
242 | } | ||
243 | |||
244 | /* | ||
245 | * Generic handler routine to add a name to a directory. | ||
246 | * Transitions directory from shortform to Btree as necessary. | ||
247 | */ | ||
248 | static int /* error */ | ||
249 | xfs_dir_createname(xfs_trans_t *trans, xfs_inode_t *dp, char *name, | ||
250 | int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock, | ||
251 | xfs_bmap_free_t *flist, xfs_extlen_t total) | ||
252 | { | ||
253 | xfs_da_args_t args; | ||
254 | int retval, newsize, done; | ||
255 | |||
256 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
257 | |||
258 | if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum))) | ||
259 | return (retval); | ||
260 | |||
261 | XFS_STATS_INC(xs_dir_create); | ||
262 | /* | ||
263 | * Fill in the arg structure for this request. | ||
264 | */ | ||
265 | args.name = name; | ||
266 | args.namelen = namelen; | ||
267 | args.hashval = xfs_da_hashname(name, namelen); | ||
268 | args.inumber = inum; | ||
269 | args.dp = dp; | ||
270 | args.firstblock = firstblock; | ||
271 | args.flist = flist; | ||
272 | args.total = total; | ||
273 | args.whichfork = XFS_DATA_FORK; | ||
274 | args.trans = trans; | ||
275 | args.justcheck = 0; | ||
276 | args.addname = args.oknoent = 1; | ||
277 | |||
278 | /* | ||
279 | * Decide on what work routines to call based on the inode size. | ||
280 | */ | ||
281 | done = 0; | ||
282 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
283 | newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen); | ||
284 | if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) { | ||
285 | retval = xfs_dir_shortform_addname(&args); | ||
286 | done = 1; | ||
287 | } else { | ||
288 | if (total == 0) | ||
289 | return XFS_ERROR(ENOSPC); | ||
290 | retval = xfs_dir_shortform_to_leaf(&args); | ||
291 | done = retval != 0; | ||
292 | } | ||
293 | } | ||
294 | if (!done && xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
295 | retval = xfs_dir_leaf_addname(&args); | ||
296 | done = retval != ENOSPC; | ||
297 | if (!done) { | ||
298 | if (total == 0) | ||
299 | return XFS_ERROR(ENOSPC); | ||
300 | retval = xfs_dir_leaf_to_node(&args); | ||
301 | done = retval != 0; | ||
302 | } | ||
303 | } | ||
304 | if (!done) { | ||
305 | retval = xfs_dir_node_addname(&args); | ||
306 | } | ||
307 | return(retval); | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * Generic handler routine to check if a name can be added to a directory, | ||
312 | * without adding any blocks to the directory. | ||
313 | */ | ||
314 | static int /* error */ | ||
315 | xfs_dir_canenter(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen) | ||
316 | { | ||
317 | xfs_da_args_t args; | ||
318 | int retval, newsize; | ||
319 | |||
320 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
321 | /* | ||
322 | * Fill in the arg structure for this request. | ||
323 | */ | ||
324 | args.name = name; | ||
325 | args.namelen = namelen; | ||
326 | args.hashval = xfs_da_hashname(name, namelen); | ||
327 | args.inumber = 0; | ||
328 | args.dp = dp; | ||
329 | args.firstblock = NULL; | ||
330 | args.flist = NULL; | ||
331 | args.total = 0; | ||
332 | args.whichfork = XFS_DATA_FORK; | ||
333 | args.trans = trans; | ||
334 | args.justcheck = args.addname = args.oknoent = 1; | ||
335 | |||
336 | /* | ||
337 | * Decide on what work routines to call based on the inode size. | ||
338 | */ | ||
339 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
340 | newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen); | ||
341 | if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) | ||
342 | retval = 0; | ||
343 | else | ||
344 | retval = XFS_ERROR(ENOSPC); | ||
345 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
346 | retval = xfs_dir_leaf_addname(&args); | ||
347 | } else { | ||
348 | retval = xfs_dir_node_addname(&args); | ||
349 | } | ||
350 | return(retval); | ||
351 | } | ||
352 | |||
353 | /* | ||
354 | * Generic handler routine to remove a name from a directory. | ||
355 | * Transitions directory from Btree to shortform as necessary. | ||
356 | */ | ||
357 | static int /* error */ | ||
358 | xfs_dir_removename(xfs_trans_t *trans, xfs_inode_t *dp, char *name, | ||
359 | int namelen, xfs_ino_t ino, xfs_fsblock_t *firstblock, | ||
360 | xfs_bmap_free_t *flist, xfs_extlen_t total) | ||
361 | { | ||
362 | xfs_da_args_t args; | ||
363 | int count, totallen, newsize, retval; | ||
364 | |||
365 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
366 | XFS_STATS_INC(xs_dir_remove); | ||
367 | /* | ||
368 | * Fill in the arg structure for this request. | ||
369 | */ | ||
370 | args.name = name; | ||
371 | args.namelen = namelen; | ||
372 | args.hashval = xfs_da_hashname(name, namelen); | ||
373 | args.inumber = ino; | ||
374 | args.dp = dp; | ||
375 | args.firstblock = firstblock; | ||
376 | args.flist = flist; | ||
377 | args.total = total; | ||
378 | args.whichfork = XFS_DATA_FORK; | ||
379 | args.trans = trans; | ||
380 | args.justcheck = args.addname = args.oknoent = 0; | ||
381 | |||
382 | /* | ||
383 | * Decide on what work routines to call based on the inode size. | ||
384 | */ | ||
385 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
386 | retval = xfs_dir_shortform_removename(&args); | ||
387 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
388 | retval = xfs_dir_leaf_removename(&args, &count, &totallen); | ||
389 | if (retval == 0) { | ||
390 | newsize = XFS_DIR_SF_ALLFIT(count, totallen); | ||
391 | if (newsize <= XFS_IFORK_DSIZE(dp)) { | ||
392 | retval = xfs_dir_leaf_to_shortform(&args); | ||
393 | } | ||
394 | } | ||
395 | } else { | ||
396 | retval = xfs_dir_node_removename(&args); | ||
397 | } | ||
398 | return(retval); | ||
399 | } | ||
400 | |||
401 | static int /* error */ | ||
402 | xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen, | ||
403 | xfs_ino_t *inum) | ||
404 | { | ||
405 | xfs_da_args_t args; | ||
406 | int retval; | ||
407 | |||
408 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
409 | |||
410 | XFS_STATS_INC(xs_dir_lookup); | ||
411 | /* | ||
412 | * Fill in the arg structure for this request. | ||
413 | */ | ||
414 | args.name = name; | ||
415 | args.namelen = namelen; | ||
416 | args.hashval = xfs_da_hashname(name, namelen); | ||
417 | args.inumber = 0; | ||
418 | args.dp = dp; | ||
419 | args.firstblock = NULL; | ||
420 | args.flist = NULL; | ||
421 | args.total = 0; | ||
422 | args.whichfork = XFS_DATA_FORK; | ||
423 | args.trans = trans; | ||
424 | args.justcheck = args.addname = 0; | ||
425 | args.oknoent = 1; | ||
426 | |||
427 | /* | ||
428 | * Decide on what work routines to call based on the inode size. | ||
429 | */ | ||
430 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
431 | retval = xfs_dir_shortform_lookup(&args); | ||
432 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
433 | retval = xfs_dir_leaf_lookup(&args); | ||
434 | } else { | ||
435 | retval = xfs_dir_node_lookup(&args); | ||
436 | } | ||
437 | if (retval == EEXIST) | ||
438 | retval = 0; | ||
439 | *inum = args.inumber; | ||
440 | return(retval); | ||
441 | } | ||
442 | |||
443 | /* | ||
444 | * Implement readdir. | ||
445 | */ | ||
446 | static int /* error */ | ||
447 | xfs_dir_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, int *eofp) | ||
448 | { | ||
449 | xfs_dirent_t *dbp; | ||
450 | int alignment, retval; | ||
451 | xfs_dir_put_t put; | ||
452 | |||
453 | XFS_STATS_INC(xs_dir_getdents); | ||
454 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
455 | |||
456 | /* | ||
457 | * If our caller has given us a single contiguous memory buffer, | ||
458 | * just work directly within that buffer. If it's in user memory, | ||
459 | * lock it down first. | ||
460 | */ | ||
461 | alignment = sizeof(xfs_off_t) - 1; | ||
462 | if ((uio->uio_iovcnt == 1) && | ||
463 | (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) && | ||
464 | ((uio->uio_iov[0].iov_len & alignment) == 0)) { | ||
465 | dbp = NULL; | ||
466 | put = xfs_dir_put_dirent64_direct; | ||
467 | } else { | ||
468 | dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP); | ||
469 | put = xfs_dir_put_dirent64_uio; | ||
470 | } | ||
471 | |||
472 | /* | ||
473 | * Decide on what work routines to call based on the inode size. | ||
474 | */ | ||
475 | *eofp = 0; | ||
476 | |||
477 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
478 | retval = xfs_dir_shortform_getdents(dp, uio, eofp, dbp, put); | ||
479 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
480 | retval = xfs_dir_leaf_getdents(trans, dp, uio, eofp, dbp, put); | ||
481 | } else { | ||
482 | retval = xfs_dir_node_getdents(trans, dp, uio, eofp, dbp, put); | ||
483 | } | ||
484 | if (dbp != NULL) | ||
485 | kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN); | ||
486 | |||
487 | return(retval); | ||
488 | } | ||
489 | |||
490 | static int /* error */ | ||
491 | xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen, | ||
492 | xfs_ino_t inum, xfs_fsblock_t *firstblock, | ||
493 | xfs_bmap_free_t *flist, xfs_extlen_t total) | ||
494 | { | ||
495 | xfs_da_args_t args; | ||
496 | int retval; | ||
497 | |||
498 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
499 | |||
500 | if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum))) | ||
501 | return retval; | ||
502 | |||
503 | /* | ||
504 | * Fill in the arg structure for this request. | ||
505 | */ | ||
506 | args.name = name; | ||
507 | args.namelen = namelen; | ||
508 | args.hashval = xfs_da_hashname(name, namelen); | ||
509 | args.inumber = inum; | ||
510 | args.dp = dp; | ||
511 | args.firstblock = firstblock; | ||
512 | args.flist = flist; | ||
513 | args.total = total; | ||
514 | args.whichfork = XFS_DATA_FORK; | ||
515 | args.trans = trans; | ||
516 | args.justcheck = args.addname = args.oknoent = 0; | ||
517 | |||
518 | /* | ||
519 | * Decide on what work routines to call based on the inode size. | ||
520 | */ | ||
521 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
522 | retval = xfs_dir_shortform_replace(&args); | ||
523 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
524 | retval = xfs_dir_leaf_replace(&args); | ||
525 | } else { | ||
526 | retval = xfs_dir_node_replace(&args); | ||
527 | } | ||
528 | |||
529 | return(retval); | ||
530 | } | ||
531 | |||
532 | static int | ||
533 | xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, xfs_dinode_t *dp) | ||
534 | { | ||
535 | xfs_ino_t ino; | ||
536 | int namelen_sum; | ||
537 | int count; | ||
538 | xfs_dir_shortform_t *sf; | ||
539 | xfs_dir_sf_entry_t *sfe; | ||
540 | int i; | ||
541 | |||
542 | |||
543 | |||
544 | if ((INT_GET(dp->di_core.di_mode, ARCH_CONVERT) & S_IFMT) != S_IFDIR) { | ||
545 | return 0; | ||
546 | } | ||
547 | if (INT_GET(dp->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_LOCAL) { | ||
548 | return 0; | ||
549 | } | ||
550 | if (INT_GET(dp->di_core.di_size, ARCH_CONVERT) < sizeof(sf->hdr)) { | ||
551 | xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform size: dp 0x%p", | ||
552 | dp); | ||
553 | return 1; | ||
554 | } | ||
555 | sf = (xfs_dir_shortform_t *)(&dp->di_u.di_dirsf); | ||
556 | ino = XFS_GET_DIR_INO8(sf->hdr.parent); | ||
557 | if (xfs_dir_ino_validate(mp, ino)) | ||
558 | return 1; | ||
559 | |||
560 | count = sf->hdr.count; | ||
561 | if ((count < 0) || ((count * 10) > XFS_LITINO(mp))) { | ||
562 | xfs_fs_cmn_err(CE_WARN, mp, | ||
563 | "Invalid shortform count: dp 0x%p", dp); | ||
564 | return(1); | ||
565 | } | ||
566 | |||
567 | if (count == 0) { | ||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | namelen_sum = 0; | ||
572 | sfe = &sf->list[0]; | ||
573 | for (i = sf->hdr.count - 1; i >= 0; i--) { | ||
574 | ino = XFS_GET_DIR_INO8(sfe->inumber); | ||
575 | xfs_dir_ino_validate(mp, ino); | ||
576 | if (sfe->namelen >= XFS_LITINO(mp)) { | ||
577 | xfs_fs_cmn_err(CE_WARN, mp, | ||
578 | "Invalid shortform namelen: dp 0x%p", dp); | ||
579 | return 1; | ||
580 | } | ||
581 | namelen_sum += sfe->namelen; | ||
582 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
583 | } | ||
584 | if (namelen_sum >= XFS_LITINO(mp)) { | ||
585 | xfs_fs_cmn_err(CE_WARN, mp, | ||
586 | "Invalid shortform namelen: dp 0x%p", dp); | ||
587 | return 1; | ||
588 | } | ||
589 | |||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | /*======================================================================== | ||
594 | * External routines when dirsize == XFS_LBSIZE(dp->i_mount). | ||
595 | *========================================================================*/ | ||
596 | |||
597 | /* | ||
598 | * Add a name to the leaf directory structure | ||
599 | * This is the external routine. | ||
600 | */ | ||
601 | int | ||
602 | xfs_dir_leaf_addname(xfs_da_args_t *args) | ||
603 | { | ||
604 | int index, retval; | ||
605 | xfs_dabuf_t *bp; | ||
606 | |||
607 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, | ||
608 | XFS_DATA_FORK); | ||
609 | if (retval) | ||
610 | return(retval); | ||
611 | ASSERT(bp != NULL); | ||
612 | |||
613 | retval = xfs_dir_leaf_lookup_int(bp, args, &index); | ||
614 | if (retval == ENOENT) | ||
615 | retval = xfs_dir_leaf_add(bp, args, index); | ||
616 | xfs_da_buf_done(bp); | ||
617 | return(retval); | ||
618 | } | ||
619 | |||
620 | /* | ||
621 | * Remove a name from the leaf directory structure | ||
622 | * This is the external routine. | ||
623 | */ | ||
624 | STATIC int | ||
625 | xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen) | ||
626 | { | ||
627 | xfs_dir_leafblock_t *leaf; | ||
628 | int index, retval; | ||
629 | xfs_dabuf_t *bp; | ||
630 | |||
631 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, | ||
632 | XFS_DATA_FORK); | ||
633 | if (retval) | ||
634 | return(retval); | ||
635 | ASSERT(bp != NULL); | ||
636 | leaf = bp->data; | ||
637 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
638 | retval = xfs_dir_leaf_lookup_int(bp, args, &index); | ||
639 | if (retval == EEXIST) { | ||
640 | (void)xfs_dir_leaf_remove(args->trans, bp, index); | ||
641 | *count = INT_GET(leaf->hdr.count, ARCH_CONVERT); | ||
642 | *totallen = INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); | ||
643 | retval = 0; | ||
644 | } | ||
645 | xfs_da_buf_done(bp); | ||
646 | return(retval); | ||
647 | } | ||
648 | |||
649 | /* | ||
650 | * Look up a name in a leaf directory structure. | ||
651 | * This is the external routine. | ||
652 | */ | ||
653 | STATIC int | ||
654 | xfs_dir_leaf_lookup(xfs_da_args_t *args) | ||
655 | { | ||
656 | int index, retval; | ||
657 | xfs_dabuf_t *bp; | ||
658 | |||
659 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, | ||
660 | XFS_DATA_FORK); | ||
661 | if (retval) | ||
662 | return(retval); | ||
663 | ASSERT(bp != NULL); | ||
664 | retval = xfs_dir_leaf_lookup_int(bp, args, &index); | ||
665 | xfs_da_brelse(args->trans, bp); | ||
666 | return(retval); | ||
667 | } | ||
668 | |||
669 | /* | ||
670 | * Copy out directory entries for getdents(), for leaf directories. | ||
671 | */ | ||
672 | STATIC int | ||
673 | xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, | ||
674 | int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put) | ||
675 | { | ||
676 | xfs_dabuf_t *bp; | ||
677 | int retval, eob; | ||
678 | |||
679 | retval = xfs_da_read_buf(dp->i_transp, dp, 0, -1, &bp, XFS_DATA_FORK); | ||
680 | if (retval) | ||
681 | return(retval); | ||
682 | ASSERT(bp != NULL); | ||
683 | retval = xfs_dir_leaf_getdents_int(bp, dp, 0, uio, &eob, dbp, put, -1); | ||
684 | xfs_da_brelse(trans, bp); | ||
685 | *eofp = (eob == 0); | ||
686 | return(retval); | ||
687 | } | ||
688 | |||
689 | /* | ||
690 | * Look up a name in a leaf directory structure, replace the inode number. | ||
691 | * This is the external routine. | ||
692 | */ | ||
693 | STATIC int | ||
694 | xfs_dir_leaf_replace(xfs_da_args_t *args) | ||
695 | { | ||
696 | int index, retval; | ||
697 | xfs_dabuf_t *bp; | ||
698 | xfs_ino_t inum; | ||
699 | xfs_dir_leafblock_t *leaf; | ||
700 | xfs_dir_leaf_entry_t *entry; | ||
701 | xfs_dir_leaf_name_t *namest; | ||
702 | |||
703 | inum = args->inumber; | ||
704 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, | ||
705 | XFS_DATA_FORK); | ||
706 | if (retval) | ||
707 | return(retval); | ||
708 | ASSERT(bp != NULL); | ||
709 | retval = xfs_dir_leaf_lookup_int(bp, args, &index); | ||
710 | if (retval == EEXIST) { | ||
711 | leaf = bp->data; | ||
712 | entry = &leaf->entries[index]; | ||
713 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); | ||
714 | /* XXX - replace assert? */ | ||
715 | XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber); | ||
716 | xfs_da_log_buf(args->trans, bp, | ||
717 | XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber))); | ||
718 | xfs_da_buf_done(bp); | ||
719 | retval = 0; | ||
720 | } else | ||
721 | xfs_da_brelse(args->trans, bp); | ||
722 | return(retval); | ||
723 | } | ||
724 | |||
725 | |||
726 | /*======================================================================== | ||
727 | * External routines when dirsize > XFS_LBSIZE(mp). | ||
728 | *========================================================================*/ | ||
729 | |||
730 | /* | ||
731 | * Add a name to a Btree-format directory. | ||
732 | * | ||
733 | * This will involve walking down the Btree, and may involve splitting | ||
734 | * leaf nodes and even splitting intermediate nodes up to and including | ||
735 | * the root node (a special case of an intermediate node). | ||
736 | */ | ||
737 | STATIC int | ||
738 | xfs_dir_node_addname(xfs_da_args_t *args) | ||
739 | { | ||
740 | xfs_da_state_t *state; | ||
741 | xfs_da_state_blk_t *blk; | ||
742 | int retval, error; | ||
743 | |||
744 | /* | ||
745 | * Fill in bucket of arguments/results/context to carry around. | ||
746 | */ | ||
747 | state = xfs_da_state_alloc(); | ||
748 | state->args = args; | ||
749 | state->mp = args->dp->i_mount; | ||
750 | state->blocksize = state->mp->m_sb.sb_blocksize; | ||
751 | state->node_ents = state->mp->m_dir_node_ents; | ||
752 | |||
753 | /* | ||
754 | * Search to see if name already exists, and get back a pointer | ||
755 | * to where it should go. | ||
756 | */ | ||
757 | error = xfs_da_node_lookup_int(state, &retval); | ||
758 | if (error) | ||
759 | retval = error; | ||
760 | if (retval != ENOENT) | ||
761 | goto error; | ||
762 | blk = &state->path.blk[ state->path.active-1 ]; | ||
763 | ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); | ||
764 | retval = xfs_dir_leaf_add(blk->bp, args, blk->index); | ||
765 | if (retval == 0) { | ||
766 | /* | ||
767 | * Addition succeeded, update Btree hashvals. | ||
768 | */ | ||
769 | if (!args->justcheck) | ||
770 | xfs_da_fixhashpath(state, &state->path); | ||
771 | } else { | ||
772 | /* | ||
773 | * Addition failed, split as many Btree elements as required. | ||
774 | */ | ||
775 | if (args->total == 0) { | ||
776 | ASSERT(retval == ENOSPC); | ||
777 | goto error; | ||
778 | } | ||
779 | retval = xfs_da_split(state); | ||
780 | } | ||
781 | error: | ||
782 | xfs_da_state_free(state); | ||
783 | |||
784 | return(retval); | ||
785 | } | ||
786 | |||
787 | /* | ||
788 | * Remove a name from a B-tree directory. | ||
789 | * | ||
790 | * This will involve walking down the Btree, and may involve joining | ||
791 | * leaf nodes and even joining intermediate nodes up to and including | ||
792 | * the root node (a special case of an intermediate node). | ||
793 | */ | ||
794 | STATIC int | ||
795 | xfs_dir_node_removename(xfs_da_args_t *args) | ||
796 | { | ||
797 | xfs_da_state_t *state; | ||
798 | xfs_da_state_blk_t *blk; | ||
799 | int retval, error; | ||
800 | |||
801 | state = xfs_da_state_alloc(); | ||
802 | state->args = args; | ||
803 | state->mp = args->dp->i_mount; | ||
804 | state->blocksize = state->mp->m_sb.sb_blocksize; | ||
805 | state->node_ents = state->mp->m_dir_node_ents; | ||
806 | |||
807 | /* | ||
808 | * Search to see if name exists, and get back a pointer to it. | ||
809 | */ | ||
810 | error = xfs_da_node_lookup_int(state, &retval); | ||
811 | if (error) | ||
812 | retval = error; | ||
813 | if (retval != EEXIST) { | ||
814 | xfs_da_state_free(state); | ||
815 | return(retval); | ||
816 | } | ||
817 | |||
818 | /* | ||
819 | * Remove the name and update the hashvals in the tree. | ||
820 | */ | ||
821 | blk = &state->path.blk[ state->path.active-1 ]; | ||
822 | ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); | ||
823 | retval = xfs_dir_leaf_remove(args->trans, blk->bp, blk->index); | ||
824 | xfs_da_fixhashpath(state, &state->path); | ||
825 | |||
826 | /* | ||
827 | * Check to see if the tree needs to be collapsed. | ||
828 | */ | ||
829 | error = 0; | ||
830 | if (retval) { | ||
831 | error = xfs_da_join(state); | ||
832 | } | ||
833 | |||
834 | xfs_da_state_free(state); | ||
835 | if (error) | ||
836 | return(error); | ||
837 | return(0); | ||
838 | } | ||
839 | |||
840 | /* | ||
841 | * Look up a filename in a int directory. | ||
842 | * Use an internal routine to actually do all the work. | ||
843 | */ | ||
844 | STATIC int | ||
845 | xfs_dir_node_lookup(xfs_da_args_t *args) | ||
846 | { | ||
847 | xfs_da_state_t *state; | ||
848 | int retval, error, i; | ||
849 | |||
850 | state = xfs_da_state_alloc(); | ||
851 | state->args = args; | ||
852 | state->mp = args->dp->i_mount; | ||
853 | state->blocksize = state->mp->m_sb.sb_blocksize; | ||
854 | state->node_ents = state->mp->m_dir_node_ents; | ||
855 | |||
856 | /* | ||
857 | * Search to see if name exists, | ||
858 | * and get back a pointer to it. | ||
859 | */ | ||
860 | error = xfs_da_node_lookup_int(state, &retval); | ||
861 | if (error) { | ||
862 | retval = error; | ||
863 | } | ||
864 | |||
865 | /* | ||
866 | * If not in a transaction, we have to release all the buffers. | ||
867 | */ | ||
868 | for (i = 0; i < state->path.active; i++) { | ||
869 | xfs_da_brelse(args->trans, state->path.blk[i].bp); | ||
870 | state->path.blk[i].bp = NULL; | ||
871 | } | ||
872 | |||
873 | xfs_da_state_free(state); | ||
874 | return(retval); | ||
875 | } | ||
876 | |||
877 | STATIC int | ||
878 | xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, | ||
879 | int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put) | ||
880 | { | ||
881 | xfs_da_intnode_t *node; | ||
882 | xfs_da_node_entry_t *btree; | ||
883 | xfs_dir_leafblock_t *leaf = NULL; | ||
884 | xfs_dablk_t bno, nextbno; | ||
885 | xfs_dahash_t cookhash; | ||
886 | xfs_mount_t *mp; | ||
887 | int error, eob, i; | ||
888 | xfs_dabuf_t *bp; | ||
889 | xfs_daddr_t nextda; | ||
890 | |||
891 | /* | ||
892 | * Pick up our context. | ||
893 | */ | ||
894 | mp = dp->i_mount; | ||
895 | bp = NULL; | ||
896 | bno = XFS_DA_COOKIE_BNO(mp, uio->uio_offset); | ||
897 | cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset); | ||
898 | |||
899 | xfs_dir_trace_g_du("node: start", dp, uio); | ||
900 | |||
901 | /* | ||
902 | * Re-find our place, even if we're confused about what our place is. | ||
903 | * | ||
904 | * First we check the block number from the magic cookie, it is a | ||
905 | * cache of where we ended last time. If we find a leaf block, and | ||
906 | * the starting hashval in that block is less than our desired | ||
907 | * hashval, then we run with it. | ||
908 | */ | ||
909 | if (bno > 0) { | ||
910 | error = xfs_da_read_buf(trans, dp, bno, -2, &bp, XFS_DATA_FORK); | ||
911 | if ((error != 0) && (error != EFSCORRUPTED)) | ||
912 | return(error); | ||
913 | if (bp) | ||
914 | leaf = bp->data; | ||
915 | if (bp && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { | ||
916 | xfs_dir_trace_g_dub("node: block not a leaf", | ||
917 | dp, uio, bno); | ||
918 | xfs_da_brelse(trans, bp); | ||
919 | bp = NULL; | ||
920 | } | ||
921 | if (bp && INT_GET(leaf->entries[0].hashval, ARCH_CONVERT) > cookhash) { | ||
922 | xfs_dir_trace_g_dub("node: leaf hash too large", | ||
923 | dp, uio, bno); | ||
924 | xfs_da_brelse(trans, bp); | ||
925 | bp = NULL; | ||
926 | } | ||
927 | if (bp && | ||
928 | cookhash > INT_GET(leaf->entries[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT)) { | ||
929 | xfs_dir_trace_g_dub("node: leaf hash too small", | ||
930 | dp, uio, bno); | ||
931 | xfs_da_brelse(trans, bp); | ||
932 | bp = NULL; | ||
933 | } | ||
934 | } | ||
935 | |||
936 | /* | ||
937 | * If we did not find a leaf block from the blockno in the cookie, | ||
938 | * or we there was no blockno in the cookie (eg: first time thru), | ||
939 | * the we start at the top of the Btree and re-find our hashval. | ||
940 | */ | ||
941 | if (bp == NULL) { | ||
942 | xfs_dir_trace_g_du("node: start at root" , dp, uio); | ||
943 | bno = 0; | ||
944 | for (;;) { | ||
945 | error = xfs_da_read_buf(trans, dp, bno, -1, &bp, | ||
946 | XFS_DATA_FORK); | ||
947 | if (error) | ||
948 | return(error); | ||
949 | if (bp == NULL) | ||
950 | return(XFS_ERROR(EFSCORRUPTED)); | ||
951 | node = bp->data; | ||
952 | if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) | ||
953 | break; | ||
954 | btree = &node->btree[0]; | ||
955 | xfs_dir_trace_g_dun("node: node detail", dp, uio, node); | ||
956 | for (i = 0; i < be16_to_cpu(node->hdr.count); btree++, i++) { | ||
957 | if (be32_to_cpu(btree->hashval) >= cookhash) { | ||
958 | bno = be32_to_cpu(btree->before); | ||
959 | break; | ||
960 | } | ||
961 | } | ||
962 | if (i == be16_to_cpu(node->hdr.count)) { | ||
963 | xfs_da_brelse(trans, bp); | ||
964 | xfs_dir_trace_g_du("node: hash beyond EOF", | ||
965 | dp, uio); | ||
966 | uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, | ||
967 | XFS_DA_MAXHASH); | ||
968 | *eofp = 1; | ||
969 | return(0); | ||
970 | } | ||
971 | xfs_dir_trace_g_dub("node: going to block", | ||
972 | dp, uio, bno); | ||
973 | xfs_da_brelse(trans, bp); | ||
974 | } | ||
975 | } | ||
976 | ASSERT(cookhash != XFS_DA_MAXHASH); | ||
977 | |||
978 | /* | ||
979 | * We've dropped down to the (first) leaf block that contains the | ||
980 | * hashval we are interested in. Continue rolling upward thru the | ||
981 | * leaf blocks until we fill up our buffer. | ||
982 | */ | ||
983 | for (;;) { | ||
984 | leaf = bp->data; | ||
985 | if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC)) { | ||
986 | xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf); | ||
987 | xfs_da_brelse(trans, bp); | ||
988 | XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)", | ||
989 | XFS_ERRLEVEL_LOW, mp, leaf); | ||
990 | return XFS_ERROR(EFSCORRUPTED); | ||
991 | } | ||
992 | xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf); | ||
993 | if ((nextbno = be32_to_cpu(leaf->hdr.info.forw))) { | ||
994 | nextda = xfs_da_reada_buf(trans, dp, nextbno, | ||
995 | XFS_DATA_FORK); | ||
996 | } else | ||
997 | nextda = -1; | ||
998 | error = xfs_dir_leaf_getdents_int(bp, dp, bno, uio, &eob, dbp, | ||
999 | put, nextda); | ||
1000 | xfs_da_brelse(trans, bp); | ||
1001 | bno = nextbno; | ||
1002 | if (eob) { | ||
1003 | xfs_dir_trace_g_dub("node: E-O-B", dp, uio, bno); | ||
1004 | *eofp = 0; | ||
1005 | return(error); | ||
1006 | } | ||
1007 | if (bno == 0) | ||
1008 | break; | ||
1009 | error = xfs_da_read_buf(trans, dp, bno, nextda, &bp, | ||
1010 | XFS_DATA_FORK); | ||
1011 | if (error) | ||
1012 | return(error); | ||
1013 | if (unlikely(bp == NULL)) { | ||
1014 | XFS_ERROR_REPORT("xfs_dir_node_getdents(2)", | ||
1015 | XFS_ERRLEVEL_LOW, mp); | ||
1016 | return(XFS_ERROR(EFSCORRUPTED)); | ||
1017 | } | ||
1018 | } | ||
1019 | *eofp = 1; | ||
1020 | xfs_dir_trace_g_du("node: E-O-F", dp, uio); | ||
1021 | return(0); | ||
1022 | } | ||
1023 | |||
1024 | /* | ||
1025 | * Look up a filename in an int directory, replace the inode number. | ||
1026 | * Use an internal routine to actually do the lookup. | ||
1027 | */ | ||
1028 | STATIC int | ||
1029 | xfs_dir_node_replace(xfs_da_args_t *args) | ||
1030 | { | ||
1031 | xfs_da_state_t *state; | ||
1032 | xfs_da_state_blk_t *blk; | ||
1033 | xfs_dir_leafblock_t *leaf; | ||
1034 | xfs_dir_leaf_entry_t *entry; | ||
1035 | xfs_dir_leaf_name_t *namest; | ||
1036 | xfs_ino_t inum; | ||
1037 | int retval, error, i; | ||
1038 | xfs_dabuf_t *bp; | ||
1039 | |||
1040 | state = xfs_da_state_alloc(); | ||
1041 | state->args = args; | ||
1042 | state->mp = args->dp->i_mount; | ||
1043 | state->blocksize = state->mp->m_sb.sb_blocksize; | ||
1044 | state->node_ents = state->mp->m_dir_node_ents; | ||
1045 | inum = args->inumber; | ||
1046 | |||
1047 | /* | ||
1048 | * Search to see if name exists, | ||
1049 | * and get back a pointer to it. | ||
1050 | */ | ||
1051 | error = xfs_da_node_lookup_int(state, &retval); | ||
1052 | if (error) { | ||
1053 | retval = error; | ||
1054 | } | ||
1055 | |||
1056 | if (retval == EEXIST) { | ||
1057 | blk = &state->path.blk[state->path.active - 1]; | ||
1058 | ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); | ||
1059 | bp = blk->bp; | ||
1060 | leaf = bp->data; | ||
1061 | entry = &leaf->entries[blk->index]; | ||
1062 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); | ||
1063 | /* XXX - replace assert ? */ | ||
1064 | XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber); | ||
1065 | xfs_da_log_buf(args->trans, bp, | ||
1066 | XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber))); | ||
1067 | xfs_da_buf_done(bp); | ||
1068 | blk->bp = NULL; | ||
1069 | retval = 0; | ||
1070 | } else { | ||
1071 | i = state->path.active - 1; | ||
1072 | xfs_da_brelse(args->trans, state->path.blk[i].bp); | ||
1073 | state->path.blk[i].bp = NULL; | ||
1074 | } | ||
1075 | for (i = 0; i < state->path.active - 1; i++) { | ||
1076 | xfs_da_brelse(args->trans, state->path.blk[i].bp); | ||
1077 | state->path.blk[i].bp = NULL; | ||
1078 | } | ||
1079 | |||
1080 | xfs_da_state_free(state); | ||
1081 | return(retval); | ||
1082 | } | ||
1083 | |||
1084 | #if defined(XFS_DIR_TRACE) | ||
1085 | /* | ||
1086 | * Add a trace buffer entry for an inode and a uio. | ||
1087 | */ | ||
1088 | void | ||
1089 | xfs_dir_trace_g_du(char *where, xfs_inode_t *dp, uio_t *uio) | ||
1090 | { | ||
1091 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DU, where, | ||
1092 | (void *)dp, (void *)dp->i_mount, | ||
1093 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
1094 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
1095 | (void *)(unsigned long)uio->uio_resid, | ||
1096 | NULL, NULL, NULL, NULL, NULL, NULL, NULL); | ||
1097 | } | ||
1098 | |||
1099 | /* | ||
1100 | * Add a trace buffer entry for an inode and a uio. | ||
1101 | */ | ||
1102 | void | ||
1103 | xfs_dir_trace_g_dub(char *where, xfs_inode_t *dp, uio_t *uio, xfs_dablk_t bno) | ||
1104 | { | ||
1105 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUB, where, | ||
1106 | (void *)dp, (void *)dp->i_mount, | ||
1107 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
1108 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
1109 | (void *)(unsigned long)uio->uio_resid, | ||
1110 | (void *)(unsigned long)bno, | ||
1111 | NULL, NULL, NULL, NULL, NULL, NULL); | ||
1112 | } | ||
1113 | |||
1114 | /* | ||
1115 | * Add a trace buffer entry for an inode and a uio. | ||
1116 | */ | ||
1117 | void | ||
1118 | xfs_dir_trace_g_dun(char *where, xfs_inode_t *dp, uio_t *uio, | ||
1119 | xfs_da_intnode_t *node) | ||
1120 | { | ||
1121 | int last = be16_to_cpu(node->hdr.count) - 1; | ||
1122 | |||
1123 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUN, where, | ||
1124 | (void *)dp, (void *)dp->i_mount, | ||
1125 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
1126 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
1127 | (void *)(unsigned long)uio->uio_resid, | ||
1128 | (void *)(unsigned long)be32_to_cpu(node->hdr.info.forw), | ||
1129 | (void *)(unsigned long) | ||
1130 | be16_to_cpu(node->hdr.count), | ||
1131 | (void *)(unsigned long) | ||
1132 | be32_to_cpu(node->btree[0].hashval), | ||
1133 | (void *)(unsigned long) | ||
1134 | be32_to_cpu(node->btree[last].hashval), | ||
1135 | NULL, NULL, NULL); | ||
1136 | } | ||
1137 | |||
1138 | /* | ||
1139 | * Add a trace buffer entry for an inode and a uio. | ||
1140 | */ | ||
1141 | void | ||
1142 | xfs_dir_trace_g_dul(char *where, xfs_inode_t *dp, uio_t *uio, | ||
1143 | xfs_dir_leafblock_t *leaf) | ||
1144 | { | ||
1145 | int last = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1; | ||
1146 | |||
1147 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUL, where, | ||
1148 | (void *)dp, (void *)dp->i_mount, | ||
1149 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
1150 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
1151 | (void *)(unsigned long)uio->uio_resid, | ||
1152 | (void *)(unsigned long)be32_to_cpu(leaf->hdr.info.forw), | ||
1153 | (void *)(unsigned long) | ||
1154 | INT_GET(leaf->hdr.count, ARCH_CONVERT), | ||
1155 | (void *)(unsigned long) | ||
1156 | INT_GET(leaf->entries[0].hashval, ARCH_CONVERT), | ||
1157 | (void *)(unsigned long) | ||
1158 | INT_GET(leaf->entries[last].hashval, ARCH_CONVERT), | ||
1159 | NULL, NULL, NULL); | ||
1160 | } | ||
1161 | |||
1162 | /* | ||
1163 | * Add a trace buffer entry for an inode and a uio. | ||
1164 | */ | ||
1165 | void | ||
1166 | xfs_dir_trace_g_due(char *where, xfs_inode_t *dp, uio_t *uio, | ||
1167 | xfs_dir_leaf_entry_t *entry) | ||
1168 | { | ||
1169 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUE, where, | ||
1170 | (void *)dp, (void *)dp->i_mount, | ||
1171 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
1172 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
1173 | (void *)(unsigned long)uio->uio_resid, | ||
1174 | (void *)(unsigned long) | ||
1175 | INT_GET(entry->hashval, ARCH_CONVERT), | ||
1176 | NULL, NULL, NULL, NULL, NULL, NULL); | ||
1177 | } | ||
1178 | |||
1179 | /* | ||
1180 | * Add a trace buffer entry for an inode and a uio. | ||
1181 | */ | ||
1182 | void | ||
1183 | xfs_dir_trace_g_duc(char *where, xfs_inode_t *dp, uio_t *uio, xfs_off_t cookie) | ||
1184 | { | ||
1185 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUC, where, | ||
1186 | (void *)dp, (void *)dp->i_mount, | ||
1187 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
1188 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
1189 | (void *)(unsigned long)uio->uio_resid, | ||
1190 | (void *)((unsigned long)(cookie >> 32)), | ||
1191 | (void *)((unsigned long)(cookie & 0xFFFFFFFF)), | ||
1192 | NULL, NULL, NULL, NULL, NULL); | ||
1193 | } | ||
1194 | |||
1195 | /* | ||
1196 | * Add a trace buffer entry for the arguments given to the routine, | ||
1197 | * generic form. | ||
1198 | */ | ||
1199 | void | ||
1200 | xfs_dir_trace_enter(int type, char *where, | ||
1201 | void * a0, void * a1, | ||
1202 | void * a2, void * a3, | ||
1203 | void * a4, void * a5, | ||
1204 | void * a6, void * a7, | ||
1205 | void * a8, void * a9, | ||
1206 | void * a10, void * a11) | ||
1207 | { | ||
1208 | ASSERT(xfs_dir_trace_buf); | ||
1209 | ktrace_enter(xfs_dir_trace_buf, (void *)(unsigned long)type, | ||
1210 | (void *)where, | ||
1211 | (void *)a0, (void *)a1, (void *)a2, | ||
1212 | (void *)a3, (void *)a4, (void *)a5, | ||
1213 | (void *)a6, (void *)a7, (void *)a8, | ||
1214 | (void *)a9, (void *)a10, (void *)a11, | ||
1215 | NULL, NULL); | ||
1216 | } | ||
1217 | #endif /* XFS_DIR_TRACE */ | ||
diff --git a/fs/xfs/xfs_dir.h b/fs/xfs/xfs_dir.h deleted file mode 100644 index 8cc8afb9f6c0..000000000000 --- a/fs/xfs/xfs_dir.h +++ /dev/null | |||
@@ -1,142 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_DIR_H__ | ||
19 | #define __XFS_DIR_H__ | ||
20 | |||
21 | /* | ||
22 | * Large directories are structured around Btrees where all the data | ||
23 | * elements are in the leaf nodes. Filenames are hashed into an int, | ||
24 | * then that int is used as the index into the Btree. Since the hashval | ||
25 | * of a filename may not be unique, we may have duplicate keys. The | ||
26 | * internal links in the Btree are logical block offsets into the file. | ||
27 | * | ||
28 | * Small directories use a different format and are packed as tightly | ||
29 | * as possible so as to fit into the literal area of the inode. | ||
30 | */ | ||
31 | |||
32 | /*======================================================================== | ||
33 | * Function prototypes for the kernel. | ||
34 | *========================================================================*/ | ||
35 | |||
36 | struct uio; | ||
37 | struct xfs_bmap_free; | ||
38 | struct xfs_da_args; | ||
39 | struct xfs_dinode; | ||
40 | struct xfs_inode; | ||
41 | struct xfs_mount; | ||
42 | struct xfs_trans; | ||
43 | |||
44 | /* | ||
45 | * Directory function types. | ||
46 | * Put in structures (xfs_dirops_t) for v1 and v2 directories. | ||
47 | */ | ||
48 | typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp); | ||
49 | typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp); | ||
50 | typedef int (*xfs_dir_init_t)(struct xfs_trans *tp, | ||
51 | struct xfs_inode *dp, | ||
52 | struct xfs_inode *pdp); | ||
53 | typedef int (*xfs_dir_createname_t)(struct xfs_trans *tp, | ||
54 | struct xfs_inode *dp, | ||
55 | char *name, | ||
56 | int namelen, | ||
57 | xfs_ino_t inum, | ||
58 | xfs_fsblock_t *first, | ||
59 | struct xfs_bmap_free *flist, | ||
60 | xfs_extlen_t total); | ||
61 | typedef int (*xfs_dir_lookup_t)(struct xfs_trans *tp, | ||
62 | struct xfs_inode *dp, | ||
63 | char *name, | ||
64 | int namelen, | ||
65 | xfs_ino_t *inum); | ||
66 | typedef int (*xfs_dir_removename_t)(struct xfs_trans *tp, | ||
67 | struct xfs_inode *dp, | ||
68 | char *name, | ||
69 | int namelen, | ||
70 | xfs_ino_t ino, | ||
71 | xfs_fsblock_t *first, | ||
72 | struct xfs_bmap_free *flist, | ||
73 | xfs_extlen_t total); | ||
74 | typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp, | ||
75 | struct xfs_inode *dp, | ||
76 | struct uio *uio, | ||
77 | int *eofp); | ||
78 | typedef int (*xfs_dir_replace_t)(struct xfs_trans *tp, | ||
79 | struct xfs_inode *dp, | ||
80 | char *name, | ||
81 | int namelen, | ||
82 | xfs_ino_t inum, | ||
83 | xfs_fsblock_t *first, | ||
84 | struct xfs_bmap_free *flist, | ||
85 | xfs_extlen_t total); | ||
86 | typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp, | ||
87 | struct xfs_inode *dp, | ||
88 | char *name, | ||
89 | int namelen); | ||
90 | typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp, | ||
91 | struct xfs_dinode *dip); | ||
92 | typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args); | ||
93 | |||
94 | typedef struct xfs_dirops { | ||
95 | xfs_dir_mount_t xd_mount; | ||
96 | xfs_dir_isempty_t xd_isempty; | ||
97 | xfs_dir_init_t xd_init; | ||
98 | xfs_dir_createname_t xd_createname; | ||
99 | xfs_dir_lookup_t xd_lookup; | ||
100 | xfs_dir_removename_t xd_removename; | ||
101 | xfs_dir_getdents_t xd_getdents; | ||
102 | xfs_dir_replace_t xd_replace; | ||
103 | xfs_dir_canenter_t xd_canenter; | ||
104 | xfs_dir_shortform_validate_ondisk_t xd_shortform_validate_ondisk; | ||
105 | xfs_dir_shortform_to_single_t xd_shortform_to_single; | ||
106 | } xfs_dirops_t; | ||
107 | |||
108 | /* | ||
109 | * Overall external interface routines. | ||
110 | */ | ||
111 | void xfs_dir_startup(void); /* called exactly once */ | ||
112 | |||
113 | #define XFS_DIR_MOUNT(mp) \ | ||
114 | ((mp)->m_dirops.xd_mount(mp)) | ||
115 | #define XFS_DIR_ISEMPTY(mp,dp) \ | ||
116 | ((mp)->m_dirops.xd_isempty(dp)) | ||
117 | #define XFS_DIR_INIT(mp,tp,dp,pdp) \ | ||
118 | ((mp)->m_dirops.xd_init(tp,dp,pdp)) | ||
119 | #define XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \ | ||
120 | ((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\ | ||
121 | total)) | ||
122 | #define XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum) \ | ||
123 | ((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum)) | ||
124 | #define XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total) \ | ||
125 | ((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total)) | ||
126 | #define XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp) \ | ||
127 | ((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp)) | ||
128 | #define XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total) \ | ||
129 | ((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total)) | ||
130 | #define XFS_DIR_CANENTER(mp,tp,dp,name,namelen) \ | ||
131 | ((mp)->m_dirops.xd_canenter(tp,dp,name,namelen)) | ||
132 | #define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) \ | ||
133 | ((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip)) | ||
134 | #define XFS_DIR_SHORTFORM_TO_SINGLE(mp,args) \ | ||
135 | ((mp)->m_dirops.xd_shortform_to_single(args)) | ||
136 | |||
137 | #define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1) | ||
138 | #define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2) | ||
139 | extern xfs_dirops_t xfsv1_dirops; | ||
140 | extern xfs_dirops_t xfsv2_dirops; | ||
141 | |||
142 | #endif /* __XFS_DIR_H__ */ | ||
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 022c8398ab62..8edbe1adb95b 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
@@ -24,21 +24,18 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_da_btree.h" | 30 | #include "xfs_da_btree.h" |
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
38 | #include "xfs_inode.h" | 36 | #include "xfs_inode.h" |
39 | #include "xfs_inode_item.h" | 37 | #include "xfs_inode_item.h" |
40 | #include "xfs_bmap.h" | 38 | #include "xfs_bmap.h" |
41 | #include "xfs_dir_leaf.h" | ||
42 | #include "xfs_dir2_data.h" | 39 | #include "xfs_dir2_data.h" |
43 | #include "xfs_dir2_leaf.h" | 40 | #include "xfs_dir2_leaf.h" |
44 | #include "xfs_dir2_block.h" | 41 | #include "xfs_dir2_block.h" |
@@ -46,69 +43,14 @@ | |||
46 | #include "xfs_dir2_trace.h" | 43 | #include "xfs_dir2_trace.h" |
47 | #include "xfs_error.h" | 44 | #include "xfs_error.h" |
48 | 45 | ||
49 | /* | ||
50 | * Declarations for interface routines. | ||
51 | */ | ||
52 | static void xfs_dir2_mount(xfs_mount_t *mp); | ||
53 | static int xfs_dir2_isempty(xfs_inode_t *dp); | ||
54 | static int xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp, | ||
55 | xfs_inode_t *pdp); | ||
56 | static int xfs_dir2_createname(xfs_trans_t *tp, xfs_inode_t *dp, | ||
57 | char *name, int namelen, xfs_ino_t inum, | ||
58 | xfs_fsblock_t *first, | ||
59 | xfs_bmap_free_t *flist, xfs_extlen_t total); | ||
60 | static int xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name, | ||
61 | int namelen, xfs_ino_t *inum); | ||
62 | static int xfs_dir2_removename(xfs_trans_t *tp, xfs_inode_t *dp, | ||
63 | char *name, int namelen, xfs_ino_t ino, | ||
64 | xfs_fsblock_t *first, | ||
65 | xfs_bmap_free_t *flist, xfs_extlen_t total); | ||
66 | static int xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio, | ||
67 | int *eofp); | ||
68 | static int xfs_dir2_replace(xfs_trans_t *tp, xfs_inode_t *dp, char *name, | ||
69 | int namelen, xfs_ino_t inum, | ||
70 | xfs_fsblock_t *first, xfs_bmap_free_t *flist, | ||
71 | xfs_extlen_t total); | ||
72 | static int xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name, | ||
73 | int namelen); | ||
74 | static int xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp, | ||
75 | xfs_dinode_t *dip); | ||
76 | |||
77 | /* | ||
78 | * Utility routine declarations. | ||
79 | */ | ||
80 | static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); | 46 | static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); |
81 | static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); | 47 | static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); |
82 | 48 | ||
83 | /* | 49 | void |
84 | * Directory operations vector. | 50 | xfs_dir_mount( |
85 | */ | 51 | xfs_mount_t *mp) |
86 | xfs_dirops_t xfsv2_dirops = { | ||
87 | .xd_mount = xfs_dir2_mount, | ||
88 | .xd_isempty = xfs_dir2_isempty, | ||
89 | .xd_init = xfs_dir2_init, | ||
90 | .xd_createname = xfs_dir2_createname, | ||
91 | .xd_lookup = xfs_dir2_lookup, | ||
92 | .xd_removename = xfs_dir2_removename, | ||
93 | .xd_getdents = xfs_dir2_getdents, | ||
94 | .xd_replace = xfs_dir2_replace, | ||
95 | .xd_canenter = xfs_dir2_canenter, | ||
96 | .xd_shortform_validate_ondisk = xfs_dir2_shortform_validate_ondisk, | ||
97 | .xd_shortform_to_single = xfs_dir2_sf_to_block, | ||
98 | }; | ||
99 | |||
100 | /* | ||
101 | * Interface routines. | ||
102 | */ | ||
103 | |||
104 | /* | ||
105 | * Initialize directory-related fields in the mount structure. | ||
106 | */ | ||
107 | static void | ||
108 | xfs_dir2_mount( | ||
109 | xfs_mount_t *mp) /* filesystem mount point */ | ||
110 | { | 52 | { |
111 | mp->m_dirversion = 2; | 53 | ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb)); |
112 | ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= | 54 | ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= |
113 | XFS_MAX_BLOCKSIZE); | 55 | XFS_MAX_BLOCKSIZE); |
114 | mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); | 56 | mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); |
@@ -128,19 +70,15 @@ xfs_dir2_mount( | |||
128 | /* | 70 | /* |
129 | * Return 1 if directory contains only "." and "..". | 71 | * Return 1 if directory contains only "." and "..". |
130 | */ | 72 | */ |
131 | static int /* return code */ | 73 | int |
132 | xfs_dir2_isempty( | 74 | xfs_dir_isempty( |
133 | xfs_inode_t *dp) /* incore inode structure */ | 75 | xfs_inode_t *dp) |
134 | { | 76 | { |
135 | xfs_dir2_sf_t *sfp; /* shortform directory structure */ | 77 | xfs_dir2_sf_t *sfp; |
136 | 78 | ||
137 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 79 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
138 | /* | 80 | if (dp->i_d.di_size == 0) /* might happen during shutdown. */ |
139 | * Might happen during shutdown. | ||
140 | */ | ||
141 | if (dp->i_d.di_size == 0) { | ||
142 | return 1; | 81 | return 1; |
143 | } | ||
144 | if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) | 82 | if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) |
145 | return 0; | 83 | return 0; |
146 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 84 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
@@ -148,53 +86,83 @@ xfs_dir2_isempty( | |||
148 | } | 86 | } |
149 | 87 | ||
150 | /* | 88 | /* |
89 | * Validate a given inode number. | ||
90 | */ | ||
91 | int | ||
92 | xfs_dir_ino_validate( | ||
93 | xfs_mount_t *mp, | ||
94 | xfs_ino_t ino) | ||
95 | { | ||
96 | xfs_agblock_t agblkno; | ||
97 | xfs_agino_t agino; | ||
98 | xfs_agnumber_t agno; | ||
99 | int ino_ok; | ||
100 | int ioff; | ||
101 | |||
102 | agno = XFS_INO_TO_AGNO(mp, ino); | ||
103 | agblkno = XFS_INO_TO_AGBNO(mp, ino); | ||
104 | ioff = XFS_INO_TO_OFFSET(mp, ino); | ||
105 | agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff); | ||
106 | ino_ok = | ||
107 | agno < mp->m_sb.sb_agcount && | ||
108 | agblkno < mp->m_sb.sb_agblocks && | ||
109 | agblkno != 0 && | ||
110 | ioff < (1 << mp->m_sb.sb_inopblog) && | ||
111 | XFS_AGINO_TO_INO(mp, agno, agino) == ino; | ||
112 | if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, | ||
113 | XFS_RANDOM_DIR_INO_VALIDATE))) { | ||
114 | xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", | ||
115 | (unsigned long long) ino); | ||
116 | XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); | ||
117 | return XFS_ERROR(EFSCORRUPTED); | ||
118 | } | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | /* | ||
151 | * Initialize a directory with its "." and ".." entries. | 123 | * Initialize a directory with its "." and ".." entries. |
152 | */ | 124 | */ |
153 | static int /* error */ | 125 | int |
154 | xfs_dir2_init( | 126 | xfs_dir_init( |
155 | xfs_trans_t *tp, /* transaction pointer */ | 127 | xfs_trans_t *tp, |
156 | xfs_inode_t *dp, /* incore directory inode */ | 128 | xfs_inode_t *dp, |
157 | xfs_inode_t *pdp) /* incore parent directory inode */ | 129 | xfs_inode_t *pdp) |
158 | { | 130 | { |
159 | xfs_da_args_t args; /* operation arguments */ | 131 | xfs_da_args_t args; |
160 | int error; /* error return value */ | 132 | int error; |
161 | 133 | ||
162 | memset((char *)&args, 0, sizeof(args)); | 134 | memset((char *)&args, 0, sizeof(args)); |
163 | args.dp = dp; | 135 | args.dp = dp; |
164 | args.trans = tp; | 136 | args.trans = tp; |
165 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 137 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
166 | if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) { | 138 | if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) |
167 | return error; | 139 | return error; |
168 | } | ||
169 | return xfs_dir2_sf_create(&args, pdp->i_ino); | 140 | return xfs_dir2_sf_create(&args, pdp->i_ino); |
170 | } | 141 | } |
171 | 142 | ||
172 | /* | 143 | /* |
173 | Enter a name in a directory. | 144 | Enter a name in a directory. |
174 | */ | 145 | */ |
175 | static int /* error */ | 146 | int |
176 | xfs_dir2_createname( | 147 | xfs_dir_createname( |
177 | xfs_trans_t *tp, /* transaction pointer */ | 148 | xfs_trans_t *tp, |
178 | xfs_inode_t *dp, /* incore directory inode */ | 149 | xfs_inode_t *dp, |
179 | char *name, /* new entry name */ | 150 | char *name, |
180 | int namelen, /* new entry name length */ | 151 | int namelen, |
181 | xfs_ino_t inum, /* new entry inode number */ | 152 | xfs_ino_t inum, /* new entry inode number */ |
182 | xfs_fsblock_t *first, /* bmap's firstblock */ | 153 | xfs_fsblock_t *first, /* bmap's firstblock */ |
183 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ | 154 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ |
184 | xfs_extlen_t total) /* bmap's total block count */ | 155 | xfs_extlen_t total) /* bmap's total block count */ |
185 | { | 156 | { |
186 | xfs_da_args_t args; /* operation arguments */ | 157 | xfs_da_args_t args; |
187 | int rval; /* return value */ | 158 | int rval; |
188 | int v; /* type-checking value */ | 159 | int v; /* type-checking value */ |
189 | 160 | ||
190 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 161 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
191 | if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { | 162 | if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) |
192 | return rval; | 163 | return rval; |
193 | } | ||
194 | XFS_STATS_INC(xs_dir_create); | 164 | XFS_STATS_INC(xs_dir_create); |
195 | /* | 165 | |
196 | * Fill in the arg structure for this request. | ||
197 | */ | ||
198 | args.name = name; | 166 | args.name = name; |
199 | args.namelen = namelen; | 167 | args.namelen = namelen; |
200 | args.hashval = xfs_da_hashname(name, namelen); | 168 | args.hashval = xfs_da_hashname(name, namelen); |
@@ -207,18 +175,16 @@ xfs_dir2_createname( | |||
207 | args.trans = tp; | 175 | args.trans = tp; |
208 | args.justcheck = 0; | 176 | args.justcheck = 0; |
209 | args.addname = args.oknoent = 1; | 177 | args.addname = args.oknoent = 1; |
210 | /* | 178 | |
211 | * Decide on what work routines to call based on the inode size. | ||
212 | */ | ||
213 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 179 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
214 | rval = xfs_dir2_sf_addname(&args); | 180 | rval = xfs_dir2_sf_addname(&args); |
215 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 181 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
216 | return rval; | 182 | return rval; |
217 | } else if (v) | 183 | else if (v) |
218 | rval = xfs_dir2_block_addname(&args); | 184 | rval = xfs_dir2_block_addname(&args); |
219 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 185 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
220 | return rval; | 186 | return rval; |
221 | } else if (v) | 187 | else if (v) |
222 | rval = xfs_dir2_leaf_addname(&args); | 188 | rval = xfs_dir2_leaf_addname(&args); |
223 | else | 189 | else |
224 | rval = xfs_dir2_node_addname(&args); | 190 | rval = xfs_dir2_node_addname(&args); |
@@ -228,24 +194,21 @@ xfs_dir2_createname( | |||
228 | /* | 194 | /* |
229 | * Lookup a name in a directory, give back the inode number. | 195 | * Lookup a name in a directory, give back the inode number. |
230 | */ | 196 | */ |
231 | static int /* error */ | 197 | int |
232 | xfs_dir2_lookup( | 198 | xfs_dir_lookup( |
233 | xfs_trans_t *tp, /* transaction pointer */ | 199 | xfs_trans_t *tp, |
234 | xfs_inode_t *dp, /* incore directory inode */ | 200 | xfs_inode_t *dp, |
235 | char *name, /* lookup name */ | 201 | char *name, |
236 | int namelen, /* lookup name length */ | 202 | int namelen, |
237 | xfs_ino_t *inum) /* out: inode number */ | 203 | xfs_ino_t *inum) /* out: inode number */ |
238 | { | 204 | { |
239 | xfs_da_args_t args; /* operation arguments */ | 205 | xfs_da_args_t args; |
240 | int rval; /* return value */ | 206 | int rval; |
241 | int v; /* type-checking value */ | 207 | int v; /* type-checking value */ |
242 | 208 | ||
243 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 209 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
244 | XFS_STATS_INC(xs_dir_lookup); | 210 | XFS_STATS_INC(xs_dir_lookup); |
245 | 211 | ||
246 | /* | ||
247 | * Fill in the arg structure for this request. | ||
248 | */ | ||
249 | args.name = name; | 212 | args.name = name; |
250 | args.namelen = namelen; | 213 | args.namelen = namelen; |
251 | args.hashval = xfs_da_hashname(name, namelen); | 214 | args.hashval = xfs_da_hashname(name, namelen); |
@@ -258,18 +221,16 @@ xfs_dir2_lookup( | |||
258 | args.trans = tp; | 221 | args.trans = tp; |
259 | args.justcheck = args.addname = 0; | 222 | args.justcheck = args.addname = 0; |
260 | args.oknoent = 1; | 223 | args.oknoent = 1; |
261 | /* | 224 | |
262 | * Decide on what work routines to call based on the inode size. | ||
263 | */ | ||
264 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 225 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
265 | rval = xfs_dir2_sf_lookup(&args); | 226 | rval = xfs_dir2_sf_lookup(&args); |
266 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 227 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
267 | return rval; | 228 | return rval; |
268 | } else if (v) | 229 | else if (v) |
269 | rval = xfs_dir2_block_lookup(&args); | 230 | rval = xfs_dir2_block_lookup(&args); |
270 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 231 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
271 | return rval; | 232 | return rval; |
272 | } else if (v) | 233 | else if (v) |
273 | rval = xfs_dir2_leaf_lookup(&args); | 234 | rval = xfs_dir2_leaf_lookup(&args); |
274 | else | 235 | else |
275 | rval = xfs_dir2_node_lookup(&args); | 236 | rval = xfs_dir2_node_lookup(&args); |
@@ -283,26 +244,24 @@ xfs_dir2_lookup( | |||
283 | /* | 244 | /* |
284 | * Remove an entry from a directory. | 245 | * Remove an entry from a directory. |
285 | */ | 246 | */ |
286 | static int /* error */ | 247 | int |
287 | xfs_dir2_removename( | 248 | xfs_dir_removename( |
288 | xfs_trans_t *tp, /* transaction pointer */ | 249 | xfs_trans_t *tp, |
289 | xfs_inode_t *dp, /* incore directory inode */ | 250 | xfs_inode_t *dp, |
290 | char *name, /* name of entry to remove */ | 251 | char *name, |
291 | int namelen, /* name length of entry to remove */ | 252 | int namelen, |
292 | xfs_ino_t ino, /* inode number of entry to remove */ | 253 | xfs_ino_t ino, |
293 | xfs_fsblock_t *first, /* bmap's firstblock */ | 254 | xfs_fsblock_t *first, /* bmap's firstblock */ |
294 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ | 255 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ |
295 | xfs_extlen_t total) /* bmap's total block count */ | 256 | xfs_extlen_t total) /* bmap's total block count */ |
296 | { | 257 | { |
297 | xfs_da_args_t args; /* operation arguments */ | 258 | xfs_da_args_t args; |
298 | int rval; /* return value */ | 259 | int rval; |
299 | int v; /* type-checking value */ | 260 | int v; /* type-checking value */ |
300 | 261 | ||
301 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 262 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
302 | XFS_STATS_INC(xs_dir_remove); | 263 | XFS_STATS_INC(xs_dir_remove); |
303 | /* | 264 | |
304 | * Fill in the arg structure for this request. | ||
305 | */ | ||
306 | args.name = name; | 265 | args.name = name; |
307 | args.namelen = namelen; | 266 | args.namelen = namelen; |
308 | args.hashval = xfs_da_hashname(name, namelen); | 267 | args.hashval = xfs_da_hashname(name, namelen); |
@@ -314,18 +273,16 @@ xfs_dir2_removename( | |||
314 | args.whichfork = XFS_DATA_FORK; | 273 | args.whichfork = XFS_DATA_FORK; |
315 | args.trans = tp; | 274 | args.trans = tp; |
316 | args.justcheck = args.addname = args.oknoent = 0; | 275 | args.justcheck = args.addname = args.oknoent = 0; |
317 | /* | 276 | |
318 | * Decide on what work routines to call based on the inode size. | ||
319 | */ | ||
320 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 277 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
321 | rval = xfs_dir2_sf_removename(&args); | 278 | rval = xfs_dir2_sf_removename(&args); |
322 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 279 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
323 | return rval; | 280 | return rval; |
324 | } else if (v) | 281 | else if (v) |
325 | rval = xfs_dir2_block_removename(&args); | 282 | rval = xfs_dir2_block_removename(&args); |
326 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 283 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
327 | return rval; | 284 | return rval; |
328 | } else if (v) | 285 | else if (v) |
329 | rval = xfs_dir2_leaf_removename(&args); | 286 | rval = xfs_dir2_leaf_removename(&args); |
330 | else | 287 | else |
331 | rval = xfs_dir2_node_removename(&args); | 288 | rval = xfs_dir2_node_removename(&args); |
@@ -335,10 +292,10 @@ xfs_dir2_removename( | |||
335 | /* | 292 | /* |
336 | * Read a directory. | 293 | * Read a directory. |
337 | */ | 294 | */ |
338 | static int /* error */ | 295 | int |
339 | xfs_dir2_getdents( | 296 | xfs_dir_getdents( |
340 | xfs_trans_t *tp, /* transaction pointer */ | 297 | xfs_trans_t *tp, |
341 | xfs_inode_t *dp, /* incore directory inode */ | 298 | xfs_inode_t *dp, |
342 | uio_t *uio, /* caller's buffer control */ | 299 | uio_t *uio, /* caller's buffer control */ |
343 | int *eofp) /* out: eof reached */ | 300 | int *eofp) /* out: eof reached */ |
344 | { | 301 | { |
@@ -367,14 +324,11 @@ xfs_dir2_getdents( | |||
367 | } | 324 | } |
368 | 325 | ||
369 | *eofp = 0; | 326 | *eofp = 0; |
370 | /* | ||
371 | * Decide on what work routines to call based on the inode size. | ||
372 | */ | ||
373 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 327 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
374 | rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); | 328 | rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); |
375 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 329 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
376 | ; | 330 | ; |
377 | } else if (v) | 331 | else if (v) |
378 | rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); | 332 | rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); |
379 | else | 333 | else |
380 | rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); | 334 | rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); |
@@ -386,29 +340,26 @@ xfs_dir2_getdents( | |||
386 | /* | 340 | /* |
387 | * Replace the inode number of a directory entry. | 341 | * Replace the inode number of a directory entry. |
388 | */ | 342 | */ |
389 | static int /* error */ | 343 | int |
390 | xfs_dir2_replace( | 344 | xfs_dir_replace( |
391 | xfs_trans_t *tp, /* transaction pointer */ | 345 | xfs_trans_t *tp, |
392 | xfs_inode_t *dp, /* incore directory inode */ | 346 | xfs_inode_t *dp, |
393 | char *name, /* name of entry to replace */ | 347 | char *name, /* name of entry to replace */ |
394 | int namelen, /* name length of entry to replace */ | 348 | int namelen, |
395 | xfs_ino_t inum, /* new inode number */ | 349 | xfs_ino_t inum, /* new inode number */ |
396 | xfs_fsblock_t *first, /* bmap's firstblock */ | 350 | xfs_fsblock_t *first, /* bmap's firstblock */ |
397 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ | 351 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ |
398 | xfs_extlen_t total) /* bmap's total block count */ | 352 | xfs_extlen_t total) /* bmap's total block count */ |
399 | { | 353 | { |
400 | xfs_da_args_t args; /* operation arguments */ | 354 | xfs_da_args_t args; |
401 | int rval; /* return value */ | 355 | int rval; |
402 | int v; /* type-checking value */ | 356 | int v; /* type-checking value */ |
403 | 357 | ||
404 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 358 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
405 | 359 | ||
406 | if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { | 360 | if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) |
407 | return rval; | 361 | return rval; |
408 | } | 362 | |
409 | /* | ||
410 | * Fill in the arg structure for this request. | ||
411 | */ | ||
412 | args.name = name; | 363 | args.name = name; |
413 | args.namelen = namelen; | 364 | args.namelen = namelen; |
414 | args.hashval = xfs_da_hashname(name, namelen); | 365 | args.hashval = xfs_da_hashname(name, namelen); |
@@ -420,18 +371,16 @@ xfs_dir2_replace( | |||
420 | args.whichfork = XFS_DATA_FORK; | 371 | args.whichfork = XFS_DATA_FORK; |
421 | args.trans = tp; | 372 | args.trans = tp; |
422 | args.justcheck = args.addname = args.oknoent = 0; | 373 | args.justcheck = args.addname = args.oknoent = 0; |
423 | /* | 374 | |
424 | * Decide on what work routines to call based on the inode size. | ||
425 | */ | ||
426 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 375 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
427 | rval = xfs_dir2_sf_replace(&args); | 376 | rval = xfs_dir2_sf_replace(&args); |
428 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 377 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
429 | return rval; | 378 | return rval; |
430 | } else if (v) | 379 | else if (v) |
431 | rval = xfs_dir2_block_replace(&args); | 380 | rval = xfs_dir2_block_replace(&args); |
432 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 381 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
433 | return rval; | 382 | return rval; |
434 | } else if (v) | 383 | else if (v) |
435 | rval = xfs_dir2_leaf_replace(&args); | 384 | rval = xfs_dir2_leaf_replace(&args); |
436 | else | 385 | else |
437 | rval = xfs_dir2_node_replace(&args); | 386 | rval = xfs_dir2_node_replace(&args); |
@@ -441,21 +390,19 @@ xfs_dir2_replace( | |||
441 | /* | 390 | /* |
442 | * See if this entry can be added to the directory without allocating space. | 391 | * See if this entry can be added to the directory without allocating space. |
443 | */ | 392 | */ |
444 | static int /* error */ | 393 | int |
445 | xfs_dir2_canenter( | 394 | xfs_dir_canenter( |
446 | xfs_trans_t *tp, /* transaction pointer */ | 395 | xfs_trans_t *tp, |
447 | xfs_inode_t *dp, /* incore directory inode */ | 396 | xfs_inode_t *dp, |
448 | char *name, /* name of entry to add */ | 397 | char *name, /* name of entry to add */ |
449 | int namelen) /* name length of entry to add */ | 398 | int namelen) |
450 | { | 399 | { |
451 | xfs_da_args_t args; /* operation arguments */ | 400 | xfs_da_args_t args; |
452 | int rval; /* return value */ | 401 | int rval; |
453 | int v; /* type-checking value */ | 402 | int v; /* type-checking value */ |
454 | 403 | ||
455 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 404 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
456 | /* | 405 | |
457 | * Fill in the arg structure for this request. | ||
458 | */ | ||
459 | args.name = name; | 406 | args.name = name; |
460 | args.namelen = namelen; | 407 | args.namelen = namelen; |
461 | args.hashval = xfs_da_hashname(name, namelen); | 408 | args.hashval = xfs_da_hashname(name, namelen); |
@@ -467,18 +414,16 @@ xfs_dir2_canenter( | |||
467 | args.whichfork = XFS_DATA_FORK; | 414 | args.whichfork = XFS_DATA_FORK; |
468 | args.trans = tp; | 415 | args.trans = tp; |
469 | args.justcheck = args.addname = args.oknoent = 1; | 416 | args.justcheck = args.addname = args.oknoent = 1; |
470 | /* | 417 | |
471 | * Decide on what work routines to call based on the inode size. | ||
472 | */ | ||
473 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 418 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
474 | rval = xfs_dir2_sf_addname(&args); | 419 | rval = xfs_dir2_sf_addname(&args); |
475 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 420 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
476 | return rval; | 421 | return rval; |
477 | } else if (v) | 422 | else if (v) |
478 | rval = xfs_dir2_block_addname(&args); | 423 | rval = xfs_dir2_block_addname(&args); |
479 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 424 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
480 | return rval; | 425 | return rval; |
481 | } else if (v) | 426 | else if (v) |
482 | rval = xfs_dir2_leaf_addname(&args); | 427 | rval = xfs_dir2_leaf_addname(&args); |
483 | else | 428 | else |
484 | rval = xfs_dir2_node_addname(&args); | 429 | rval = xfs_dir2_node_addname(&args); |
@@ -486,19 +431,6 @@ xfs_dir2_canenter( | |||
486 | } | 431 | } |
487 | 432 | ||
488 | /* | 433 | /* |
489 | * Dummy routine for shortform inode validation. | ||
490 | * Can't really do this. | ||
491 | */ | ||
492 | /* ARGSUSED */ | ||
493 | static int /* error */ | ||
494 | xfs_dir2_shortform_validate_ondisk( | ||
495 | xfs_mount_t *mp, /* filesystem mount point */ | ||
496 | xfs_dinode_t *dip) /* ondisk inode */ | ||
497 | { | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | /* | ||
502 | * Utility routines. | 434 | * Utility routines. |
503 | */ | 435 | */ |
504 | 436 | ||
@@ -507,24 +439,24 @@ xfs_dir2_shortform_validate_ondisk( | |||
507 | * This routine is for data and free blocks, not leaf/node blocks | 439 | * This routine is for data and free blocks, not leaf/node blocks |
508 | * which are handled by xfs_da_grow_inode. | 440 | * which are handled by xfs_da_grow_inode. |
509 | */ | 441 | */ |
510 | int /* error */ | 442 | int |
511 | xfs_dir2_grow_inode( | 443 | xfs_dir2_grow_inode( |
512 | xfs_da_args_t *args, /* operation arguments */ | 444 | xfs_da_args_t *args, |
513 | int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ | 445 | int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ |
514 | xfs_dir2_db_t *dbp) /* out: block number added */ | 446 | xfs_dir2_db_t *dbp) /* out: block number added */ |
515 | { | 447 | { |
516 | xfs_fileoff_t bno; /* directory offset of new block */ | 448 | xfs_fileoff_t bno; /* directory offset of new block */ |
517 | int count; /* count of filesystem blocks */ | 449 | int count; /* count of filesystem blocks */ |
518 | xfs_inode_t *dp; /* incore directory inode */ | 450 | xfs_inode_t *dp; /* incore directory inode */ |
519 | int error; /* error return value */ | 451 | int error; |
520 | int got; /* blocks actually mapped */ | 452 | int got; /* blocks actually mapped */ |
521 | int i; /* temp mapping index */ | 453 | int i; |
522 | xfs_bmbt_irec_t map; /* single structure for bmap */ | 454 | xfs_bmbt_irec_t map; /* single structure for bmap */ |
523 | int mapi; /* mapping index */ | 455 | int mapi; /* mapping index */ |
524 | xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ | 456 | xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ |
525 | xfs_mount_t *mp; /* filesystem mount point */ | 457 | xfs_mount_t *mp; |
526 | int nmap; /* number of bmap entries */ | 458 | int nmap; /* number of bmap entries */ |
527 | xfs_trans_t *tp; /* transaction pointer */ | 459 | xfs_trans_t *tp; |
528 | 460 | ||
529 | xfs_dir2_trace_args_s("grow_inode", args, space); | 461 | xfs_dir2_trace_args_s("grow_inode", args, space); |
530 | dp = args->dp; | 462 | dp = args->dp; |
@@ -538,9 +470,8 @@ xfs_dir2_grow_inode( | |||
538 | /* | 470 | /* |
539 | * Find the first hole for our block. | 471 | * Find the first hole for our block. |
540 | */ | 472 | */ |
541 | if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) { | 473 | if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) |
542 | return error; | 474 | return error; |
543 | } | ||
544 | nmap = 1; | 475 | nmap = 1; |
545 | ASSERT(args->firstblock != NULL); | 476 | ASSERT(args->firstblock != NULL); |
546 | /* | 477 | /* |
@@ -549,13 +480,9 @@ xfs_dir2_grow_inode( | |||
549 | if ((error = xfs_bmapi(tp, dp, bno, count, | 480 | if ((error = xfs_bmapi(tp, dp, bno, count, |
550 | XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, | 481 | XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, |
551 | args->firstblock, args->total, &map, &nmap, | 482 | args->firstblock, args->total, &map, &nmap, |
552 | args->flist))) { | 483 | args->flist, NULL))) |
553 | return error; | 484 | return error; |
554 | } | ||
555 | ASSERT(nmap <= 1); | 485 | ASSERT(nmap <= 1); |
556 | /* | ||
557 | * Got it in 1. | ||
558 | */ | ||
559 | if (nmap == 1) { | 486 | if (nmap == 1) { |
560 | mapp = ↦ | 487 | mapp = ↦ |
561 | mapi = 1; | 488 | mapi = 1; |
@@ -585,7 +512,8 @@ xfs_dir2_grow_inode( | |||
585 | if ((error = xfs_bmapi(tp, dp, b, c, | 512 | if ((error = xfs_bmapi(tp, dp, b, c, |
586 | XFS_BMAPI_WRITE|XFS_BMAPI_METADATA, | 513 | XFS_BMAPI_WRITE|XFS_BMAPI_METADATA, |
587 | args->firstblock, args->total, | 514 | args->firstblock, args->total, |
588 | &mapp[mapi], &nmap, args->flist))) { | 515 | &mapp[mapi], &nmap, args->flist, |
516 | NULL))) { | ||
589 | kmem_free(mapp, sizeof(*mapp) * count); | 517 | kmem_free(mapp, sizeof(*mapp) * count); |
590 | return error; | 518 | return error; |
591 | } | 519 | } |
@@ -645,20 +573,19 @@ xfs_dir2_grow_inode( | |||
645 | /* | 573 | /* |
646 | * See if the directory is a single-block form directory. | 574 | * See if the directory is a single-block form directory. |
647 | */ | 575 | */ |
648 | int /* error */ | 576 | int |
649 | xfs_dir2_isblock( | 577 | xfs_dir2_isblock( |
650 | xfs_trans_t *tp, /* transaction pointer */ | 578 | xfs_trans_t *tp, |
651 | xfs_inode_t *dp, /* incore directory inode */ | 579 | xfs_inode_t *dp, |
652 | int *vp) /* out: 1 is block, 0 is not block */ | 580 | int *vp) /* out: 1 is block, 0 is not block */ |
653 | { | 581 | { |
654 | xfs_fileoff_t last; /* last file offset */ | 582 | xfs_fileoff_t last; /* last file offset */ |
655 | xfs_mount_t *mp; /* filesystem mount point */ | 583 | xfs_mount_t *mp; |
656 | int rval; /* return value */ | 584 | int rval; |
657 | 585 | ||
658 | mp = dp->i_mount; | 586 | mp = dp->i_mount; |
659 | if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { | 587 | if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) |
660 | return rval; | 588 | return rval; |
661 | } | ||
662 | rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; | 589 | rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; |
663 | ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); | 590 | ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); |
664 | *vp = rval; | 591 | *vp = rval; |
@@ -668,20 +595,19 @@ xfs_dir2_isblock( | |||
668 | /* | 595 | /* |
669 | * See if the directory is a single-leaf form directory. | 596 | * See if the directory is a single-leaf form directory. |
670 | */ | 597 | */ |
671 | int /* error */ | 598 | int |
672 | xfs_dir2_isleaf( | 599 | xfs_dir2_isleaf( |
673 | xfs_trans_t *tp, /* transaction pointer */ | 600 | xfs_trans_t *tp, |
674 | xfs_inode_t *dp, /* incore directory inode */ | 601 | xfs_inode_t *dp, |
675 | int *vp) /* out: 1 is leaf, 0 is not leaf */ | 602 | int *vp) /* out: 1 is leaf, 0 is not leaf */ |
676 | { | 603 | { |
677 | xfs_fileoff_t last; /* last file offset */ | 604 | xfs_fileoff_t last; /* last file offset */ |
678 | xfs_mount_t *mp; /* filesystem mount point */ | 605 | xfs_mount_t *mp; |
679 | int rval; /* return value */ | 606 | int rval; |
680 | 607 | ||
681 | mp = dp->i_mount; | 608 | mp = dp->i_mount; |
682 | if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { | 609 | if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) |
683 | return rval; | 610 | return rval; |
684 | } | ||
685 | *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); | 611 | *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); |
686 | return 0; | 612 | return 0; |
687 | } | 613 | } |
@@ -689,9 +615,9 @@ xfs_dir2_isleaf( | |||
689 | /* | 615 | /* |
690 | * Getdents put routine for 64-bit ABI, direct form. | 616 | * Getdents put routine for 64-bit ABI, direct form. |
691 | */ | 617 | */ |
692 | static int /* error */ | 618 | static int |
693 | xfs_dir2_put_dirent64_direct( | 619 | xfs_dir2_put_dirent64_direct( |
694 | xfs_dir2_put_args_t *pa) /* argument bundle */ | 620 | xfs_dir2_put_args_t *pa) |
695 | { | 621 | { |
696 | xfs_dirent_t *idbp; /* dirent pointer */ | 622 | xfs_dirent_t *idbp; /* dirent pointer */ |
697 | iovec_t *iovp; /* io vector */ | 623 | iovec_t *iovp; /* io vector */ |
@@ -726,9 +652,9 @@ xfs_dir2_put_dirent64_direct( | |||
726 | /* | 652 | /* |
727 | * Getdents put routine for 64-bit ABI, uio form. | 653 | * Getdents put routine for 64-bit ABI, uio form. |
728 | */ | 654 | */ |
729 | static int /* error */ | 655 | static int |
730 | xfs_dir2_put_dirent64_uio( | 656 | xfs_dir2_put_dirent64_uio( |
731 | xfs_dir2_put_args_t *pa) /* argument bundle */ | 657 | xfs_dir2_put_args_t *pa) |
732 | { | 658 | { |
733 | xfs_dirent_t *idbp; /* dirent pointer */ | 659 | xfs_dirent_t *idbp; /* dirent pointer */ |
734 | int namelen; /* entry name length */ | 660 | int namelen; /* entry name length */ |
@@ -764,17 +690,17 @@ xfs_dir2_put_dirent64_uio( | |||
764 | */ | 690 | */ |
765 | int | 691 | int |
766 | xfs_dir2_shrink_inode( | 692 | xfs_dir2_shrink_inode( |
767 | xfs_da_args_t *args, /* operation arguments */ | 693 | xfs_da_args_t *args, |
768 | xfs_dir2_db_t db, /* directory block number */ | 694 | xfs_dir2_db_t db, |
769 | xfs_dabuf_t *bp) /* block's buffer */ | 695 | xfs_dabuf_t *bp) |
770 | { | 696 | { |
771 | xfs_fileoff_t bno; /* directory file offset */ | 697 | xfs_fileoff_t bno; /* directory file offset */ |
772 | xfs_dablk_t da; /* directory file offset */ | 698 | xfs_dablk_t da; /* directory file offset */ |
773 | int done; /* bunmap is finished */ | 699 | int done; /* bunmap is finished */ |
774 | xfs_inode_t *dp; /* incore directory inode */ | 700 | xfs_inode_t *dp; |
775 | int error; /* error return value */ | 701 | int error; |
776 | xfs_mount_t *mp; /* filesystem mount point */ | 702 | xfs_mount_t *mp; |
777 | xfs_trans_t *tp; /* transaction pointer */ | 703 | xfs_trans_t *tp; |
778 | 704 | ||
779 | xfs_dir2_trace_args_db("shrink_inode", args, db, bp); | 705 | xfs_dir2_trace_args_db("shrink_inode", args, db, bp); |
780 | dp = args->dp; | 706 | dp = args->dp; |
@@ -786,7 +712,7 @@ xfs_dir2_shrink_inode( | |||
786 | */ | 712 | */ |
787 | if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, | 713 | if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, |
788 | XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, | 714 | XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, |
789 | &done))) { | 715 | NULL, &done))) { |
790 | /* | 716 | /* |
791 | * ENOSPC actually can happen if we're in a removename with | 717 | * ENOSPC actually can happen if we're in a removename with |
792 | * no space reservation, and the resulting block removal | 718 | * no space reservation, and the resulting block removal |
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h index 7dd364b1e038..86560b6f794c 100644 --- a/fs/xfs/xfs_dir2.h +++ b/fs/xfs/xfs_dir2.h | |||
@@ -22,7 +22,9 @@ struct uio; | |||
22 | struct xfs_dabuf; | 22 | struct xfs_dabuf; |
23 | struct xfs_da_args; | 23 | struct xfs_da_args; |
24 | struct xfs_dir2_put_args; | 24 | struct xfs_dir2_put_args; |
25 | struct xfs_bmap_free; | ||
25 | struct xfs_inode; | 26 | struct xfs_inode; |
27 | struct xfs_mount; | ||
26 | struct xfs_trans; | 28 | struct xfs_trans; |
27 | 29 | ||
28 | /* | 30 | /* |
@@ -73,7 +75,35 @@ typedef struct xfs_dir2_put_args { | |||
73 | } xfs_dir2_put_args_t; | 75 | } xfs_dir2_put_args_t; |
74 | 76 | ||
75 | /* | 77 | /* |
76 | * Other interfaces used by the rest of the dir v2 code. | 78 | * Generic directory interface routines |
79 | */ | ||
80 | extern void xfs_dir_startup(void); | ||
81 | extern void xfs_dir_mount(struct xfs_mount *mp); | ||
82 | extern int xfs_dir_isempty(struct xfs_inode *dp); | ||
83 | extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, | ||
84 | struct xfs_inode *pdp); | ||
85 | extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp, | ||
86 | char *name, int namelen, xfs_ino_t inum, | ||
87 | xfs_fsblock_t *first, | ||
88 | struct xfs_bmap_free *flist, xfs_extlen_t tot); | ||
89 | extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, | ||
90 | char *name, int namelen, xfs_ino_t *inum); | ||
91 | extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, | ||
92 | char *name, int namelen, xfs_ino_t ino, | ||
93 | xfs_fsblock_t *first, | ||
94 | struct xfs_bmap_free *flist, xfs_extlen_t tot); | ||
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, | ||
98 | char *name, int namelen, xfs_ino_t inum, | ||
99 | xfs_fsblock_t *first, | ||
100 | struct xfs_bmap_free *flist, xfs_extlen_t tot); | ||
101 | extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, | ||
102 | char *name, int namelen); | ||
103 | extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); | ||
104 | |||
105 | /* | ||
106 | * Utility routines for v2 directories. | ||
77 | */ | 107 | */ |
78 | extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, | 108 | extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, |
79 | xfs_dir2_db_t *dbp); | 109 | xfs_dir2_db_t *dbp); |
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 972ded595476..9d7438bba30d 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
@@ -22,19 +22,16 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
31 | #include "xfs_dir_sf.h" | ||
32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
35 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
36 | #include "xfs_inode_item.h" | 34 | #include "xfs_inode_item.h" |
37 | #include "xfs_dir_leaf.h" | ||
38 | #include "xfs_dir2_data.h" | 35 | #include "xfs_dir2_data.h" |
39 | #include "xfs_dir2_leaf.h" | 36 | #include "xfs_dir2_leaf.h" |
40 | #include "xfs_dir2_block.h" | 37 | #include "xfs_dir2_block.h" |
@@ -51,6 +48,18 @@ static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp, | |||
51 | int *entno); | 48 | int *entno); |
52 | static int xfs_dir2_block_sort(const void *a, const void *b); | 49 | static int xfs_dir2_block_sort(const void *a, const void *b); |
53 | 50 | ||
51 | static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; | ||
52 | |||
53 | /* | ||
54 | * One-time startup routine called from xfs_init(). | ||
55 | */ | ||
56 | void | ||
57 | xfs_dir_startup(void) | ||
58 | { | ||
59 | xfs_dir_hash_dot = xfs_da_hashname(".", 1); | ||
60 | xfs_dir_hash_dotdot = xfs_da_hashname("..", 2); | ||
61 | } | ||
62 | |||
54 | /* | 63 | /* |
55 | * Add an entry to a block directory. | 64 | * Add an entry to a block directory. |
56 | */ | 65 | */ |
@@ -400,7 +409,7 @@ xfs_dir2_block_addname( | |||
400 | /* | 409 | /* |
401 | * Create the new data entry. | 410 | * Create the new data entry. |
402 | */ | 411 | */ |
403 | INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); | 412 | dep->inumber = cpu_to_be64(args->inumber); |
404 | dep->namelen = args->namelen; | 413 | dep->namelen = args->namelen; |
405 | memcpy(dep->name, args->name, args->namelen); | 414 | memcpy(dep->name, args->name, args->namelen); |
406 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 415 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); |
@@ -508,7 +517,7 @@ xfs_dir2_block_getdents( | |||
508 | 517 | ||
509 | p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 518 | p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, |
510 | ptr - (char *)block); | 519 | ptr - (char *)block); |
511 | p.ino = INT_GET(dep->inumber, ARCH_CONVERT); | 520 | p.ino = be64_to_cpu(dep->inumber); |
512 | #if XFS_BIG_INUMS | 521 | #if XFS_BIG_INUMS |
513 | p.ino += mp->m_inoadd; | 522 | p.ino += mp->m_inoadd; |
514 | #endif | 523 | #endif |
@@ -626,7 +635,7 @@ xfs_dir2_block_lookup( | |||
626 | /* | 635 | /* |
627 | * Fill in inode number, release the block. | 636 | * Fill in inode number, release the block. |
628 | */ | 637 | */ |
629 | args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); | 638 | args->inumber = be64_to_cpu(dep->inumber); |
630 | xfs_da_brelse(args->trans, bp); | 639 | xfs_da_brelse(args->trans, bp); |
631 | return XFS_ERROR(EEXIST); | 640 | return XFS_ERROR(EEXIST); |
632 | } | 641 | } |
@@ -844,11 +853,11 @@ xfs_dir2_block_replace( | |||
844 | */ | 853 | */ |
845 | dep = (xfs_dir2_data_entry_t *) | 854 | dep = (xfs_dir2_data_entry_t *) |
846 | ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address))); | 855 | ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address))); |
847 | ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber); | 856 | ASSERT(be64_to_cpu(dep->inumber) != args->inumber); |
848 | /* | 857 | /* |
849 | * Change the inode number to the new value. | 858 | * Change the inode number to the new value. |
850 | */ | 859 | */ |
851 | INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); | 860 | dep->inumber = cpu_to_be64(args->inumber); |
852 | xfs_dir2_data_log_entry(args->trans, bp, dep); | 861 | xfs_dir2_data_log_entry(args->trans, bp, dep); |
853 | xfs_dir2_data_check(dp, bp); | 862 | xfs_dir2_data_check(dp, bp); |
854 | xfs_da_buf_done(bp); | 863 | xfs_da_buf_done(bp); |
@@ -1130,7 +1139,7 @@ xfs_dir2_sf_to_block( | |||
1130 | */ | 1139 | */ |
1131 | dep = (xfs_dir2_data_entry_t *) | 1140 | dep = (xfs_dir2_data_entry_t *) |
1132 | ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); | 1141 | ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); |
1133 | INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino); | 1142 | dep->inumber = cpu_to_be64(dp->i_ino); |
1134 | dep->namelen = 1; | 1143 | dep->namelen = 1; |
1135 | dep->name[0] = '.'; | 1144 | dep->name[0] = '.'; |
1136 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 1145 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); |
@@ -1144,7 +1153,7 @@ xfs_dir2_sf_to_block( | |||
1144 | */ | 1153 | */ |
1145 | dep = (xfs_dir2_data_entry_t *) | 1154 | dep = (xfs_dir2_data_entry_t *) |
1146 | ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); | 1155 | ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); |
1147 | INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); | 1156 | dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); |
1148 | dep->namelen = 2; | 1157 | dep->namelen = 2; |
1149 | dep->name[0] = dep->name[1] = '.'; | 1158 | dep->name[0] = dep->name[1] = '.'; |
1150 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 1159 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); |
@@ -1193,7 +1202,7 @@ xfs_dir2_sf_to_block( | |||
1193 | * Copy a real entry. | 1202 | * Copy a real entry. |
1194 | */ | 1203 | */ |
1195 | dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); | 1204 | dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); |
1196 | INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, | 1205 | dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp, |
1197 | XFS_DIR2_SF_INUMBERP(sfep))); | 1206 | XFS_DIR2_SF_INUMBERP(sfep))); |
1198 | dep->namelen = sfep->namelen; | 1207 | dep->namelen = sfep->namelen; |
1199 | memcpy(dep->name, sfep->name, dep->namelen); | 1208 | memcpy(dep->name, sfep->name, dep->namelen); |
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index bb3d03ff002b..f7c799217072 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c | |||
@@ -22,18 +22,15 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
31 | #include "xfs_dir_sf.h" | ||
32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
35 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
36 | #include "xfs_dir_leaf.h" | ||
37 | #include "xfs_dir2_data.h" | 34 | #include "xfs_dir2_data.h" |
38 | #include "xfs_dir2_leaf.h" | 35 | #include "xfs_dir2_leaf.h" |
39 | #include "xfs_dir2_block.h" | 36 | #include "xfs_dir2_block.h" |
@@ -133,7 +130,7 @@ xfs_dir2_data_check( | |||
133 | */ | 130 | */ |
134 | dep = (xfs_dir2_data_entry_t *)p; | 131 | dep = (xfs_dir2_data_entry_t *)p; |
135 | ASSERT(dep->namelen != 0); | 132 | ASSERT(dep->namelen != 0); |
136 | ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0); | 133 | ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0); |
137 | ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) == | 134 | ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) == |
138 | (char *)dep - (char *)d); | 135 | (char *)dep - (char *)d); |
139 | count++; | 136 | count++; |
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h index 0847cbb53e17..a6ae2d21c40a 100644 --- a/fs/xfs/xfs_dir2_data.h +++ b/fs/xfs/xfs_dir2_data.h | |||
@@ -85,11 +85,11 @@ typedef struct xfs_dir2_data_hdr { | |||
85 | * Tag appears as the last 2 bytes. | 85 | * Tag appears as the last 2 bytes. |
86 | */ | 86 | */ |
87 | typedef struct xfs_dir2_data_entry { | 87 | typedef struct xfs_dir2_data_entry { |
88 | xfs_ino_t inumber; /* inode number */ | 88 | __be64 inumber; /* inode number */ |
89 | __uint8_t namelen; /* name length */ | 89 | __u8 namelen; /* name length */ |
90 | __uint8_t name[1]; /* name bytes, no null */ | 90 | __u8 name[1]; /* name bytes, no null */ |
91 | /* variable offset */ | 91 | /* variable offset */ |
92 | xfs_dir2_data_off_t tag; /* starting offset of us */ | 92 | __be16 tag; /* starting offset of us */ |
93 | } xfs_dir2_data_entry_t; | 93 | } xfs_dir2_data_entry_t; |
94 | 94 | ||
95 | /* | 95 | /* |
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 0f5e2f2ce6ec..b1cf1fbf423d 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_da_btree.h" | 30 | #include "xfs_da_btree.h" |
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_attr_sf.h" | 32 | #include "xfs_attr_sf.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_dinode.h" | 34 | #include "xfs_dinode.h" |
37 | #include "xfs_inode.h" | 35 | #include "xfs_inode.h" |
@@ -407,7 +405,7 @@ xfs_dir2_leaf_addname( | |||
407 | * Initialize our new entry (at last). | 405 | * Initialize our new entry (at last). |
408 | */ | 406 | */ |
409 | dep = (xfs_dir2_data_entry_t *)dup; | 407 | dep = (xfs_dir2_data_entry_t *)dup; |
410 | INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); | 408 | dep->inumber = cpu_to_be64(args->inumber); |
411 | dep->namelen = args->namelen; | 409 | dep->namelen = args->namelen; |
412 | memcpy(dep->name, args->name, dep->namelen); | 410 | memcpy(dep->name, args->name, dep->namelen); |
413 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 411 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); |
@@ -884,7 +882,7 @@ xfs_dir2_leaf_getdents( | |||
884 | XFS_DIR2_BYTE_TO_DA(mp, | 882 | XFS_DIR2_BYTE_TO_DA(mp, |
885 | XFS_DIR2_LEAF_OFFSET) - map_off, | 883 | XFS_DIR2_LEAF_OFFSET) - map_off, |
886 | XFS_BMAPI_METADATA, NULL, 0, | 884 | XFS_BMAPI_METADATA, NULL, 0, |
887 | &map[map_valid], &nmap, NULL); | 885 | &map[map_valid], &nmap, NULL, NULL); |
888 | /* | 886 | /* |
889 | * Don't know if we should ignore this or | 887 | * Don't know if we should ignore this or |
890 | * try to return an error. | 888 | * try to return an error. |
@@ -1098,7 +1096,7 @@ xfs_dir2_leaf_getdents( | |||
1098 | 1096 | ||
1099 | p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length); | 1097 | p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length); |
1100 | 1098 | ||
1101 | p->ino = INT_GET(dep->inumber, ARCH_CONVERT); | 1099 | p->ino = be64_to_cpu(dep->inumber); |
1102 | #if XFS_BIG_INUMS | 1100 | #if XFS_BIG_INUMS |
1103 | p->ino += mp->m_inoadd; | 1101 | p->ino += mp->m_inoadd; |
1104 | #endif | 1102 | #endif |
@@ -1319,7 +1317,7 @@ xfs_dir2_leaf_lookup( | |||
1319 | /* | 1317 | /* |
1320 | * Return the found inode number. | 1318 | * Return the found inode number. |
1321 | */ | 1319 | */ |
1322 | args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); | 1320 | args->inumber = be64_to_cpu(dep->inumber); |
1323 | xfs_da_brelse(tp, dbp); | 1321 | xfs_da_brelse(tp, dbp); |
1324 | xfs_da_brelse(tp, lbp); | 1322 | xfs_da_brelse(tp, lbp); |
1325 | return XFS_ERROR(EEXIST); | 1323 | return XFS_ERROR(EEXIST); |
@@ -1606,11 +1604,11 @@ xfs_dir2_leaf_replace( | |||
1606 | dep = (xfs_dir2_data_entry_t *) | 1604 | dep = (xfs_dir2_data_entry_t *) |
1607 | ((char *)dbp->data + | 1605 | ((char *)dbp->data + |
1608 | XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address))); | 1606 | XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address))); |
1609 | ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT)); | 1607 | ASSERT(args->inumber != be64_to_cpu(dep->inumber)); |
1610 | /* | 1608 | /* |
1611 | * Put the new inode number in, log it. | 1609 | * Put the new inode number in, log it. |
1612 | */ | 1610 | */ |
1613 | INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); | 1611 | dep->inumber = cpu_to_be64(args->inumber); |
1614 | tp = args->trans; | 1612 | tp = args->trans; |
1615 | xfs_dir2_data_log_entry(tp, dbp, dep); | 1613 | xfs_dir2_data_log_entry(tp, dbp, dep); |
1616 | xfs_da_buf_done(dbp); | 1614 | xfs_da_buf_done(dbp); |
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index ac511ab9c52d..9ca71719b683 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c | |||
@@ -22,13 +22,11 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
31 | #include "xfs_dir_sf.h" | ||
32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
@@ -505,7 +503,6 @@ xfs_dir2_leafn_lookup_int( | |||
505 | XFS_DATA_FORK))) { | 503 | XFS_DATA_FORK))) { |
506 | return error; | 504 | return error; |
507 | } | 505 | } |
508 | curfdb = newfdb; | ||
509 | free = curbp->data; | 506 | free = curbp->data; |
510 | ASSERT(be32_to_cpu(free->hdr.magic) == | 507 | ASSERT(be32_to_cpu(free->hdr.magic) == |
511 | XFS_DIR2_FREE_MAGIC); | 508 | XFS_DIR2_FREE_MAGIC); |
@@ -527,8 +524,11 @@ xfs_dir2_leafn_lookup_int( | |||
527 | if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) { | 524 | if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) { |
528 | XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", | 525 | XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", |
529 | XFS_ERRLEVEL_LOW, mp); | 526 | XFS_ERRLEVEL_LOW, mp); |
527 | if (curfdb != newfdb) | ||
528 | xfs_da_brelse(tp, curbp); | ||
530 | return XFS_ERROR(EFSCORRUPTED); | 529 | return XFS_ERROR(EFSCORRUPTED); |
531 | } | 530 | } |
531 | curfdb = newfdb; | ||
532 | if (be16_to_cpu(free->bests[fi]) >= length) { | 532 | if (be16_to_cpu(free->bests[fi]) >= length) { |
533 | *indexp = index; | 533 | *indexp = index; |
534 | state->extravalid = 1; | 534 | state->extravalid = 1; |
@@ -580,7 +580,7 @@ xfs_dir2_leafn_lookup_int( | |||
580 | if (dep->namelen == args->namelen && | 580 | if (dep->namelen == args->namelen && |
581 | dep->name[0] == args->name[0] && | 581 | dep->name[0] == args->name[0] && |
582 | memcmp(dep->name, args->name, args->namelen) == 0) { | 582 | memcmp(dep->name, args->name, args->namelen) == 0) { |
583 | args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); | 583 | args->inumber = be64_to_cpu(dep->inumber); |
584 | *indexp = index; | 584 | *indexp = index; |
585 | state->extravalid = 1; | 585 | state->extravalid = 1; |
586 | state->extrablk.bp = curbp; | 586 | state->extrablk.bp = curbp; |
@@ -970,7 +970,7 @@ xfs_dir2_leafn_remove( | |||
970 | /* | 970 | /* |
971 | * One less used entry in the free table. | 971 | * One less used entry in the free table. |
972 | */ | 972 | */ |
973 | free->hdr.nused = cpu_to_be32(-1); | 973 | be32_add(&free->hdr.nused, -1); |
974 | xfs_dir2_free_log_header(tp, fbp); | 974 | xfs_dir2_free_log_header(tp, fbp); |
975 | /* | 975 | /* |
976 | * If this was the last entry in the table, we can | 976 | * If this was the last entry in the table, we can |
@@ -1695,7 +1695,7 @@ xfs_dir2_node_addname_int( | |||
1695 | * Fill in the new entry and log it. | 1695 | * Fill in the new entry and log it. |
1696 | */ | 1696 | */ |
1697 | dep = (xfs_dir2_data_entry_t *)dup; | 1697 | dep = (xfs_dir2_data_entry_t *)dup; |
1698 | INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); | 1698 | dep->inumber = cpu_to_be64(args->inumber); |
1699 | dep->namelen = args->namelen; | 1699 | dep->namelen = args->namelen; |
1700 | memcpy(dep->name, args->name, dep->namelen); | 1700 | memcpy(dep->name, args->name, dep->namelen); |
1701 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 1701 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); |
@@ -1905,11 +1905,11 @@ xfs_dir2_node_replace( | |||
1905 | dep = (xfs_dir2_data_entry_t *) | 1905 | dep = (xfs_dir2_data_entry_t *) |
1906 | ((char *)data + | 1906 | ((char *)data + |
1907 | XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address))); | 1907 | XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address))); |
1908 | ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT)); | 1908 | ASSERT(inum != be64_to_cpu(dep->inumber)); |
1909 | /* | 1909 | /* |
1910 | * Fill in the new inode number and log the entry. | 1910 | * Fill in the new inode number and log the entry. |
1911 | */ | 1911 | */ |
1912 | INT_SET(dep->inumber, ARCH_CONVERT, inum); | 1912 | dep->inumber = cpu_to_be64(inum); |
1913 | xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); | 1913 | xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); |
1914 | rval = 0; | 1914 | rval = 0; |
1915 | } | 1915 | } |
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index d98a41d1fe63..0cd77b17bf92 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c | |||
@@ -22,19 +22,16 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
31 | #include "xfs_dir_sf.h" | ||
32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
35 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
36 | #include "xfs_inode_item.h" | 34 | #include "xfs_inode_item.h" |
37 | #include "xfs_dir_leaf.h" | ||
38 | #include "xfs_error.h" | 35 | #include "xfs_error.h" |
39 | #include "xfs_dir2_data.h" | 36 | #include "xfs_dir2_data.h" |
40 | #include "xfs_dir2_leaf.h" | 37 | #include "xfs_dir2_leaf.h" |
@@ -117,13 +114,13 @@ xfs_dir2_block_sfsize( | |||
117 | dep->name[0] == '.' && dep->name[1] == '.'; | 114 | dep->name[0] == '.' && dep->name[1] == '.'; |
118 | #if XFS_BIG_INUMS | 115 | #if XFS_BIG_INUMS |
119 | if (!isdot) | 116 | if (!isdot) |
120 | i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM; | 117 | i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM; |
121 | #endif | 118 | #endif |
122 | if (!isdot && !isdotdot) { | 119 | if (!isdot && !isdotdot) { |
123 | count++; | 120 | count++; |
124 | namelen += dep->namelen; | 121 | namelen += dep->namelen; |
125 | } else if (isdotdot) | 122 | } else if (isdotdot) |
126 | parent = INT_GET(dep->inumber, ARCH_CONVERT); | 123 | parent = be64_to_cpu(dep->inumber); |
127 | /* | 124 | /* |
128 | * Calculate the new size, see if we should give up yet. | 125 | * Calculate the new size, see if we should give up yet. |
129 | */ | 126 | */ |
@@ -229,13 +226,13 @@ xfs_dir2_block_to_sf( | |||
229 | * Skip . | 226 | * Skip . |
230 | */ | 227 | */ |
231 | if (dep->namelen == 1 && dep->name[0] == '.') | 228 | if (dep->namelen == 1 && dep->name[0] == '.') |
232 | ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == dp->i_ino); | 229 | ASSERT(be64_to_cpu(dep->inumber) == dp->i_ino); |
233 | /* | 230 | /* |
234 | * Skip .., but make sure the inode number is right. | 231 | * Skip .., but make sure the inode number is right. |
235 | */ | 232 | */ |
236 | else if (dep->namelen == 2 && | 233 | else if (dep->namelen == 2 && |
237 | dep->name[0] == '.' && dep->name[1] == '.') | 234 | dep->name[0] == '.' && dep->name[1] == '.') |
238 | ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == | 235 | ASSERT(be64_to_cpu(dep->inumber) == |
239 | XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); | 236 | XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); |
240 | /* | 237 | /* |
241 | * Normal entry, copy it into shortform. | 238 | * Normal entry, copy it into shortform. |
@@ -246,7 +243,7 @@ xfs_dir2_block_to_sf( | |||
246 | (xfs_dir2_data_aoff_t) | 243 | (xfs_dir2_data_aoff_t) |
247 | ((char *)dep - (char *)block)); | 244 | ((char *)dep - (char *)block)); |
248 | memcpy(sfep->name, dep->name, dep->namelen); | 245 | memcpy(sfep->name, dep->name, dep->namelen); |
249 | temp=INT_GET(dep->inumber, ARCH_CONVERT); | 246 | temp = be64_to_cpu(dep->inumber); |
250 | XFS_DIR2_SF_PUT_INUMBER(sfp, &temp, | 247 | XFS_DIR2_SF_PUT_INUMBER(sfp, &temp, |
251 | XFS_DIR2_SF_INUMBERP(sfep)); | 248 | XFS_DIR2_SF_INUMBERP(sfep)); |
252 | sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); | 249 | sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); |
diff --git a/fs/xfs/xfs_dir2_trace.c b/fs/xfs/xfs_dir2_trace.c index c626943b4112..f3fb2ffd6f5c 100644 --- a/fs/xfs/xfs_dir2_trace.c +++ b/fs/xfs/xfs_dir2_trace.c | |||
@@ -19,11 +19,9 @@ | |||
19 | #include "xfs_fs.h" | 19 | #include "xfs_fs.h" |
20 | #include "xfs_types.h" | 20 | #include "xfs_types.h" |
21 | #include "xfs_inum.h" | 21 | #include "xfs_inum.h" |
22 | #include "xfs_dir.h" | ||
23 | #include "xfs_dir2.h" | 22 | #include "xfs_dir2.h" |
24 | #include "xfs_da_btree.h" | 23 | #include "xfs_da_btree.h" |
25 | #include "xfs_bmap_btree.h" | 24 | #include "xfs_bmap_btree.h" |
26 | #include "xfs_dir_sf.h" | ||
27 | #include "xfs_dir2_sf.h" | 25 | #include "xfs_dir2_sf.h" |
28 | #include "xfs_attr_sf.h" | 26 | #include "xfs_attr_sf.h" |
29 | #include "xfs_dinode.h" | 27 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c deleted file mode 100644 index 6d711869262f..000000000000 --- a/fs/xfs/xfs_dir_leaf.c +++ /dev/null | |||
@@ -1,2213 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_fs.h" | ||
20 | #include "xfs_types.h" | ||
21 | #include "xfs_log.h" | ||
22 | #include "xfs_inum.h" | ||
23 | #include "xfs_trans.h" | ||
24 | #include "xfs_sb.h" | ||
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dir2.h" | ||
27 | #include "xfs_dmapi.h" | ||
28 | #include "xfs_mount.h" | ||
29 | #include "xfs_da_btree.h" | ||
30 | #include "xfs_bmap_btree.h" | ||
31 | #include "xfs_alloc_btree.h" | ||
32 | #include "xfs_ialloc_btree.h" | ||
33 | #include "xfs_dir_sf.h" | ||
34 | #include "xfs_dir2_sf.h" | ||
35 | #include "xfs_attr_sf.h" | ||
36 | #include "xfs_dinode.h" | ||
37 | #include "xfs_inode.h" | ||
38 | #include "xfs_inode_item.h" | ||
39 | #include "xfs_alloc.h" | ||
40 | #include "xfs_btree.h" | ||
41 | #include "xfs_bmap.h" | ||
42 | #include "xfs_dir_leaf.h" | ||
43 | #include "xfs_error.h" | ||
44 | |||
45 | /* | ||
46 | * xfs_dir_leaf.c | ||
47 | * | ||
48 | * Routines to implement leaf blocks of directories as Btrees of hashed names. | ||
49 | */ | ||
50 | |||
51 | /*======================================================================== | ||
52 | * Function prototypes for the kernel. | ||
53 | *========================================================================*/ | ||
54 | |||
55 | /* | ||
56 | * Routines used for growing the Btree. | ||
57 | */ | ||
58 | STATIC void xfs_dir_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, | ||
59 | int insertion_index, | ||
60 | int freemap_index); | ||
61 | STATIC int xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer, | ||
62 | int musthave, int justcheck); | ||
63 | STATIC void xfs_dir_leaf_rebalance(xfs_da_state_t *state, | ||
64 | xfs_da_state_blk_t *blk1, | ||
65 | xfs_da_state_blk_t *blk2); | ||
66 | STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state, | ||
67 | xfs_da_state_blk_t *leaf_blk_1, | ||
68 | xfs_da_state_blk_t *leaf_blk_2, | ||
69 | int *number_entries_in_blk1, | ||
70 | int *number_namebytes_in_blk1); | ||
71 | |||
72 | STATIC int xfs_dir_leaf_create(struct xfs_da_args *args, | ||
73 | xfs_dablk_t which_block, | ||
74 | struct xfs_dabuf **bpp); | ||
75 | |||
76 | /* | ||
77 | * Utility routines. | ||
78 | */ | ||
79 | STATIC void xfs_dir_leaf_moveents(xfs_dir_leafblock_t *src_leaf, | ||
80 | int src_start, | ||
81 | xfs_dir_leafblock_t *dst_leaf, | ||
82 | int dst_start, int move_count, | ||
83 | xfs_mount_t *mp); | ||
84 | |||
85 | |||
86 | /*======================================================================== | ||
87 | * External routines when dirsize < XFS_IFORK_DSIZE(dp). | ||
88 | *========================================================================*/ | ||
89 | |||
90 | |||
91 | /* | ||
92 | * Validate a given inode number. | ||
93 | */ | ||
94 | int | ||
95 | xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino) | ||
96 | { | ||
97 | xfs_agblock_t agblkno; | ||
98 | xfs_agino_t agino; | ||
99 | xfs_agnumber_t agno; | ||
100 | int ino_ok; | ||
101 | int ioff; | ||
102 | |||
103 | agno = XFS_INO_TO_AGNO(mp, ino); | ||
104 | agblkno = XFS_INO_TO_AGBNO(mp, ino); | ||
105 | ioff = XFS_INO_TO_OFFSET(mp, ino); | ||
106 | agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff); | ||
107 | ino_ok = | ||
108 | agno < mp->m_sb.sb_agcount && | ||
109 | agblkno < mp->m_sb.sb_agblocks && | ||
110 | agblkno != 0 && | ||
111 | ioff < (1 << mp->m_sb.sb_inopblog) && | ||
112 | XFS_AGINO_TO_INO(mp, agno, agino) == ino; | ||
113 | if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, | ||
114 | XFS_RANDOM_DIR_INO_VALIDATE))) { | ||
115 | xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", | ||
116 | (unsigned long long) ino); | ||
117 | XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); | ||
118 | return XFS_ERROR(EFSCORRUPTED); | ||
119 | } | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Create the initial contents of a shortform directory. | ||
125 | */ | ||
126 | int | ||
127 | xfs_dir_shortform_create(xfs_da_args_t *args, xfs_ino_t parent) | ||
128 | { | ||
129 | xfs_dir_sf_hdr_t *hdr; | ||
130 | xfs_inode_t *dp; | ||
131 | |||
132 | dp = args->dp; | ||
133 | ASSERT(dp != NULL); | ||
134 | ASSERT(dp->i_d.di_size == 0); | ||
135 | if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { | ||
136 | dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */ | ||
137 | dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; | ||
138 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); | ||
139 | dp->i_df.if_flags |= XFS_IFINLINE; | ||
140 | } | ||
141 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
142 | ASSERT(dp->i_df.if_bytes == 0); | ||
143 | xfs_idata_realloc(dp, sizeof(*hdr), XFS_DATA_FORK); | ||
144 | hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data; | ||
145 | XFS_DIR_SF_PUT_DIRINO(&parent, &hdr->parent); | ||
146 | |||
147 | hdr->count = 0; | ||
148 | dp->i_d.di_size = sizeof(*hdr); | ||
149 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Add a name to the shortform directory structure. | ||
155 | * Overflow from the inode has already been checked for. | ||
156 | */ | ||
157 | int | ||
158 | xfs_dir_shortform_addname(xfs_da_args_t *args) | ||
159 | { | ||
160 | xfs_dir_shortform_t *sf; | ||
161 | xfs_dir_sf_entry_t *sfe; | ||
162 | int i, offset, size; | ||
163 | xfs_inode_t *dp; | ||
164 | |||
165 | dp = args->dp; | ||
166 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
167 | /* | ||
168 | * Catch the case where the conversion from shortform to leaf | ||
169 | * failed part way through. | ||
170 | */ | ||
171 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
172 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
173 | return XFS_ERROR(EIO); | ||
174 | } | ||
175 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
176 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
177 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
178 | sfe = &sf->list[0]; | ||
179 | for (i = sf->hdr.count-1; i >= 0; i--) { | ||
180 | if (sfe->namelen == args->namelen && | ||
181 | args->name[0] == sfe->name[0] && | ||
182 | memcmp(args->name, sfe->name, args->namelen) == 0) | ||
183 | return XFS_ERROR(EEXIST); | ||
184 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
185 | } | ||
186 | |||
187 | offset = (int)((char *)sfe - (char *)sf); | ||
188 | size = XFS_DIR_SF_ENTSIZE_BYNAME(args->namelen); | ||
189 | xfs_idata_realloc(dp, size, XFS_DATA_FORK); | ||
190 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
191 | sfe = (xfs_dir_sf_entry_t *)((char *)sf + offset); | ||
192 | |||
193 | XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber); | ||
194 | sfe->namelen = args->namelen; | ||
195 | memcpy(sfe->name, args->name, sfe->namelen); | ||
196 | sf->hdr.count++; | ||
197 | |||
198 | dp->i_d.di_size += size; | ||
199 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | /* | ||
205 | * Remove a name from the shortform directory structure. | ||
206 | */ | ||
207 | int | ||
208 | xfs_dir_shortform_removename(xfs_da_args_t *args) | ||
209 | { | ||
210 | xfs_dir_shortform_t *sf; | ||
211 | xfs_dir_sf_entry_t *sfe; | ||
212 | int base, size = 0, i; | ||
213 | xfs_inode_t *dp; | ||
214 | |||
215 | dp = args->dp; | ||
216 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
217 | /* | ||
218 | * Catch the case where the conversion from shortform to leaf | ||
219 | * failed part way through. | ||
220 | */ | ||
221 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
222 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
223 | return XFS_ERROR(EIO); | ||
224 | } | ||
225 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
226 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
227 | base = sizeof(xfs_dir_sf_hdr_t); | ||
228 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
229 | sfe = &sf->list[0]; | ||
230 | for (i = sf->hdr.count-1; i >= 0; i--) { | ||
231 | size = XFS_DIR_SF_ENTSIZE_BYENTRY(sfe); | ||
232 | if (sfe->namelen == args->namelen && | ||
233 | sfe->name[0] == args->name[0] && | ||
234 | memcmp(sfe->name, args->name, args->namelen) == 0) | ||
235 | break; | ||
236 | base += size; | ||
237 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
238 | } | ||
239 | if (i < 0) { | ||
240 | ASSERT(args->oknoent); | ||
241 | return XFS_ERROR(ENOENT); | ||
242 | } | ||
243 | |||
244 | if ((base + size) != dp->i_d.di_size) { | ||
245 | memmove(&((char *)sf)[base], &((char *)sf)[base+size], | ||
246 | dp->i_d.di_size - (base+size)); | ||
247 | } | ||
248 | sf->hdr.count--; | ||
249 | |||
250 | xfs_idata_realloc(dp, -size, XFS_DATA_FORK); | ||
251 | dp->i_d.di_size -= size; | ||
252 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | /* | ||
258 | * Look up a name in a shortform directory structure. | ||
259 | */ | ||
260 | int | ||
261 | xfs_dir_shortform_lookup(xfs_da_args_t *args) | ||
262 | { | ||
263 | xfs_dir_shortform_t *sf; | ||
264 | xfs_dir_sf_entry_t *sfe; | ||
265 | int i; | ||
266 | xfs_inode_t *dp; | ||
267 | |||
268 | dp = args->dp; | ||
269 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
270 | /* | ||
271 | * Catch the case where the conversion from shortform to leaf | ||
272 | * failed part way through. | ||
273 | */ | ||
274 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
275 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
276 | return XFS_ERROR(EIO); | ||
277 | } | ||
278 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
279 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
280 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
281 | if (args->namelen == 2 && | ||
282 | args->name[0] == '.' && args->name[1] == '.') { | ||
283 | XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &args->inumber); | ||
284 | return(XFS_ERROR(EEXIST)); | ||
285 | } | ||
286 | if (args->namelen == 1 && args->name[0] == '.') { | ||
287 | args->inumber = dp->i_ino; | ||
288 | return(XFS_ERROR(EEXIST)); | ||
289 | } | ||
290 | sfe = &sf->list[0]; | ||
291 | for (i = sf->hdr.count-1; i >= 0; i--) { | ||
292 | if (sfe->namelen == args->namelen && | ||
293 | sfe->name[0] == args->name[0] && | ||
294 | memcmp(args->name, sfe->name, args->namelen) == 0) { | ||
295 | XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args->inumber); | ||
296 | return(XFS_ERROR(EEXIST)); | ||
297 | } | ||
298 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
299 | } | ||
300 | ASSERT(args->oknoent); | ||
301 | return(XFS_ERROR(ENOENT)); | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * Convert from using the shortform to the leaf. | ||
306 | */ | ||
307 | int | ||
308 | xfs_dir_shortform_to_leaf(xfs_da_args_t *iargs) | ||
309 | { | ||
310 | xfs_inode_t *dp; | ||
311 | xfs_dir_shortform_t *sf; | ||
312 | xfs_dir_sf_entry_t *sfe; | ||
313 | xfs_da_args_t args; | ||
314 | xfs_ino_t inumber; | ||
315 | char *tmpbuffer; | ||
316 | int retval, i, size; | ||
317 | xfs_dablk_t blkno; | ||
318 | xfs_dabuf_t *bp; | ||
319 | |||
320 | dp = iargs->dp; | ||
321 | /* | ||
322 | * Catch the case where the conversion from shortform to leaf | ||
323 | * failed part way through. | ||
324 | */ | ||
325 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
326 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
327 | return XFS_ERROR(EIO); | ||
328 | } | ||
329 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
330 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
331 | size = dp->i_df.if_bytes; | ||
332 | tmpbuffer = kmem_alloc(size, KM_SLEEP); | ||
333 | ASSERT(tmpbuffer != NULL); | ||
334 | |||
335 | memcpy(tmpbuffer, dp->i_df.if_u1.if_data, size); | ||
336 | |||
337 | sf = (xfs_dir_shortform_t *)tmpbuffer; | ||
338 | XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &inumber); | ||
339 | |||
340 | xfs_idata_realloc(dp, -size, XFS_DATA_FORK); | ||
341 | dp->i_d.di_size = 0; | ||
342 | xfs_trans_log_inode(iargs->trans, dp, XFS_ILOG_CORE); | ||
343 | retval = xfs_da_grow_inode(iargs, &blkno); | ||
344 | if (retval) | ||
345 | goto out; | ||
346 | |||
347 | ASSERT(blkno == 0); | ||
348 | retval = xfs_dir_leaf_create(iargs, blkno, &bp); | ||
349 | if (retval) | ||
350 | goto out; | ||
351 | xfs_da_buf_done(bp); | ||
352 | |||
353 | args.name = "."; | ||
354 | args.namelen = 1; | ||
355 | args.hashval = xfs_dir_hash_dot; | ||
356 | args.inumber = dp->i_ino; | ||
357 | args.dp = dp; | ||
358 | args.firstblock = iargs->firstblock; | ||
359 | args.flist = iargs->flist; | ||
360 | args.total = iargs->total; | ||
361 | args.whichfork = XFS_DATA_FORK; | ||
362 | args.trans = iargs->trans; | ||
363 | args.justcheck = 0; | ||
364 | args.addname = args.oknoent = 1; | ||
365 | retval = xfs_dir_leaf_addname(&args); | ||
366 | if (retval) | ||
367 | goto out; | ||
368 | |||
369 | args.name = ".."; | ||
370 | args.namelen = 2; | ||
371 | args.hashval = xfs_dir_hash_dotdot; | ||
372 | args.inumber = inumber; | ||
373 | retval = xfs_dir_leaf_addname(&args); | ||
374 | if (retval) | ||
375 | goto out; | ||
376 | |||
377 | sfe = &sf->list[0]; | ||
378 | for (i = 0; i < sf->hdr.count; i++) { | ||
379 | args.name = (char *)(sfe->name); | ||
380 | args.namelen = sfe->namelen; | ||
381 | args.hashval = xfs_da_hashname((char *)(sfe->name), | ||
382 | sfe->namelen); | ||
383 | XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args.inumber); | ||
384 | retval = xfs_dir_leaf_addname(&args); | ||
385 | if (retval) | ||
386 | goto out; | ||
387 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
388 | } | ||
389 | retval = 0; | ||
390 | |||
391 | out: | ||
392 | kmem_free(tmpbuffer, size); | ||
393 | return retval; | ||
394 | } | ||
395 | |||
396 | STATIC int | ||
397 | xfs_dir_shortform_compare(const void *a, const void *b) | ||
398 | { | ||
399 | xfs_dir_sf_sort_t *sa, *sb; | ||
400 | |||
401 | sa = (xfs_dir_sf_sort_t *)a; | ||
402 | sb = (xfs_dir_sf_sort_t *)b; | ||
403 | if (sa->hash < sb->hash) | ||
404 | return -1; | ||
405 | else if (sa->hash > sb->hash) | ||
406 | return 1; | ||
407 | else | ||
408 | return sa->entno - sb->entno; | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * Copy out directory entries for getdents(), for shortform directories. | ||
413 | */ | ||
414 | /*ARGSUSED*/ | ||
415 | int | ||
416 | xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp, | ||
417 | xfs_dirent_t *dbp, xfs_dir_put_t put) | ||
418 | { | ||
419 | xfs_dir_shortform_t *sf; | ||
420 | xfs_dir_sf_entry_t *sfe; | ||
421 | int retval, i, sbsize, nsbuf, lastresid=0, want_entno; | ||
422 | xfs_mount_t *mp; | ||
423 | xfs_dahash_t cookhash, hash; | ||
424 | xfs_dir_put_args_t p; | ||
425 | xfs_dir_sf_sort_t *sbuf, *sbp; | ||
426 | |||
427 | mp = dp->i_mount; | ||
428 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
429 | cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset); | ||
430 | want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset); | ||
431 | nsbuf = sf->hdr.count + 2; | ||
432 | sbsize = (nsbuf + 1) * sizeof(*sbuf); | ||
433 | sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP); | ||
434 | |||
435 | xfs_dir_trace_g_du("sf: start", dp, uio); | ||
436 | |||
437 | /* | ||
438 | * Collect all the entries into the buffer. | ||
439 | * Entry 0 is . | ||
440 | */ | ||
441 | sbp->entno = 0; | ||
442 | sbp->seqno = 0; | ||
443 | sbp->hash = xfs_dir_hash_dot; | ||
444 | sbp->ino = dp->i_ino; | ||
445 | sbp->name = "."; | ||
446 | sbp->namelen = 1; | ||
447 | sbp++; | ||
448 | |||
449 | /* | ||
450 | * Entry 1 is .. | ||
451 | */ | ||
452 | sbp->entno = 1; | ||
453 | sbp->seqno = 0; | ||
454 | sbp->hash = xfs_dir_hash_dotdot; | ||
455 | sbp->ino = XFS_GET_DIR_INO8(sf->hdr.parent); | ||
456 | sbp->name = ".."; | ||
457 | sbp->namelen = 2; | ||
458 | sbp++; | ||
459 | |||
460 | /* | ||
461 | * Scan the directory data for the rest of the entries. | ||
462 | */ | ||
463 | for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { | ||
464 | |||
465 | if (unlikely( | ||
466 | ((char *)sfe < (char *)sf) || | ||
467 | ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)))) { | ||
468 | xfs_dir_trace_g_du("sf: corrupted", dp, uio); | ||
469 | XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents", | ||
470 | XFS_ERRLEVEL_LOW, mp, sfe); | ||
471 | kmem_free(sbuf, sbsize); | ||
472 | return XFS_ERROR(EFSCORRUPTED); | ||
473 | } | ||
474 | |||
475 | sbp->entno = i + 2; | ||
476 | sbp->seqno = 0; | ||
477 | sbp->hash = xfs_da_hashname((char *)sfe->name, sfe->namelen); | ||
478 | sbp->ino = XFS_GET_DIR_INO8(sfe->inumber); | ||
479 | sbp->name = (char *)sfe->name; | ||
480 | sbp->namelen = sfe->namelen; | ||
481 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
482 | sbp++; | ||
483 | } | ||
484 | |||
485 | /* | ||
486 | * Sort the entries on hash then entno. | ||
487 | */ | ||
488 | xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_dir_shortform_compare); | ||
489 | /* | ||
490 | * Stuff in last entry. | ||
491 | */ | ||
492 | sbp->entno = nsbuf; | ||
493 | sbp->hash = XFS_DA_MAXHASH; | ||
494 | sbp->seqno = 0; | ||
495 | /* | ||
496 | * Figure out the sequence numbers in case there's a hash duplicate. | ||
497 | */ | ||
498 | for (hash = sbuf->hash, sbp = sbuf + 1; | ||
499 | sbp < &sbuf[nsbuf + 1]; sbp++) { | ||
500 | if (sbp->hash == hash) | ||
501 | sbp->seqno = sbp[-1].seqno + 1; | ||
502 | else | ||
503 | hash = sbp->hash; | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * Set up put routine. | ||
508 | */ | ||
509 | p.dbp = dbp; | ||
510 | p.put = put; | ||
511 | p.uio = uio; | ||
512 | |||
513 | /* | ||
514 | * Find our place. | ||
515 | */ | ||
516 | for (sbp = sbuf; sbp < &sbuf[nsbuf + 1]; sbp++) { | ||
517 | if (sbp->hash > cookhash || | ||
518 | (sbp->hash == cookhash && sbp->seqno >= want_entno)) | ||
519 | break; | ||
520 | } | ||
521 | |||
522 | /* | ||
523 | * Did we fail to find anything? We stop at the last entry, | ||
524 | * the one we put maxhash into. | ||
525 | */ | ||
526 | if (sbp == &sbuf[nsbuf]) { | ||
527 | kmem_free(sbuf, sbsize); | ||
528 | xfs_dir_trace_g_du("sf: hash beyond end", dp, uio); | ||
529 | uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH); | ||
530 | *eofp = 1; | ||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | /* | ||
535 | * Loop putting entries into the user buffer. | ||
536 | */ | ||
537 | while (sbp < &sbuf[nsbuf]) { | ||
538 | /* | ||
539 | * Save the first resid in a run of equal-hashval entries | ||
540 | * so that we can back them out if they don't all fit. | ||
541 | */ | ||
542 | if (sbp->seqno == 0 || sbp == sbuf) | ||
543 | lastresid = uio->uio_resid; | ||
544 | XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash); | ||
545 | p.ino = sbp->ino; | ||
546 | #if XFS_BIG_INUMS | ||
547 | p.ino += mp->m_inoadd; | ||
548 | #endif | ||
549 | p.name = sbp->name; | ||
550 | p.namelen = sbp->namelen; | ||
551 | retval = p.put(&p); | ||
552 | if (!p.done) { | ||
553 | uio->uio_offset = | ||
554 | XFS_DA_MAKE_COOKIE(mp, 0, 0, sbp->hash); | ||
555 | kmem_free(sbuf, sbsize); | ||
556 | uio->uio_resid = lastresid; | ||
557 | xfs_dir_trace_g_du("sf: E-O-B", dp, uio); | ||
558 | return retval; | ||
559 | } | ||
560 | sbp++; | ||
561 | } | ||
562 | kmem_free(sbuf, sbsize); | ||
563 | uio->uio_offset = p.cook.o; | ||
564 | *eofp = 1; | ||
565 | xfs_dir_trace_g_du("sf: E-O-F", dp, uio); | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | * Look up a name in a shortform directory structure, replace the inode number. | ||
571 | */ | ||
572 | int | ||
573 | xfs_dir_shortform_replace(xfs_da_args_t *args) | ||
574 | { | ||
575 | xfs_dir_shortform_t *sf; | ||
576 | xfs_dir_sf_entry_t *sfe; | ||
577 | xfs_inode_t *dp; | ||
578 | int i; | ||
579 | |||
580 | dp = args->dp; | ||
581 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
582 | /* | ||
583 | * Catch the case where the conversion from shortform to leaf | ||
584 | * failed part way through. | ||
585 | */ | ||
586 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
587 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
588 | return XFS_ERROR(EIO); | ||
589 | } | ||
590 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
591 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
592 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
593 | if (args->namelen == 2 && | ||
594 | args->name[0] == '.' && args->name[1] == '.') { | ||
595 | /* XXX - replace assert? */ | ||
596 | XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sf->hdr.parent); | ||
597 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); | ||
598 | return 0; | ||
599 | } | ||
600 | ASSERT(args->namelen != 1 || args->name[0] != '.'); | ||
601 | sfe = &sf->list[0]; | ||
602 | for (i = sf->hdr.count-1; i >= 0; i--) { | ||
603 | if (sfe->namelen == args->namelen && | ||
604 | sfe->name[0] == args->name[0] && | ||
605 | memcmp(args->name, sfe->name, args->namelen) == 0) { | ||
606 | ASSERT(memcmp((char *)&args->inumber, | ||
607 | (char *)&sfe->inumber, sizeof(xfs_ino_t))); | ||
608 | XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber); | ||
609 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); | ||
610 | return 0; | ||
611 | } | ||
612 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
613 | } | ||
614 | ASSERT(args->oknoent); | ||
615 | return XFS_ERROR(ENOENT); | ||
616 | } | ||
617 | |||
618 | /* | ||
619 | * Convert a leaf directory to shortform structure | ||
620 | */ | ||
621 | int | ||
622 | xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs) | ||
623 | { | ||
624 | xfs_dir_leafblock_t *leaf; | ||
625 | xfs_dir_leaf_hdr_t *hdr; | ||
626 | xfs_dir_leaf_entry_t *entry; | ||
627 | xfs_dir_leaf_name_t *namest; | ||
628 | xfs_da_args_t args; | ||
629 | xfs_inode_t *dp; | ||
630 | xfs_ino_t parent = 0; | ||
631 | char *tmpbuffer; | ||
632 | int retval, i; | ||
633 | xfs_dabuf_t *bp; | ||
634 | |||
635 | dp = iargs->dp; | ||
636 | tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); | ||
637 | ASSERT(tmpbuffer != NULL); | ||
638 | |||
639 | retval = xfs_da_read_buf(iargs->trans, iargs->dp, 0, -1, &bp, | ||
640 | XFS_DATA_FORK); | ||
641 | if (retval) | ||
642 | goto out; | ||
643 | ASSERT(bp != NULL); | ||
644 | memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); | ||
645 | leaf = (xfs_dir_leafblock_t *)tmpbuffer; | ||
646 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
647 | memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); | ||
648 | |||
649 | /* | ||
650 | * Find and special case the parent inode number | ||
651 | */ | ||
652 | hdr = &leaf->hdr; | ||
653 | entry = &leaf->entries[0]; | ||
654 | for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) { | ||
655 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); | ||
656 | if ((entry->namelen == 2) && | ||
657 | (namest->name[0] == '.') && | ||
658 | (namest->name[1] == '.')) { | ||
659 | XFS_DIR_SF_GET_DIRINO(&namest->inumber, &parent); | ||
660 | entry->nameidx = 0; | ||
661 | } else if ((entry->namelen == 1) && (namest->name[0] == '.')) { | ||
662 | entry->nameidx = 0; | ||
663 | } | ||
664 | } | ||
665 | retval = xfs_da_shrink_inode(iargs, 0, bp); | ||
666 | if (retval) | ||
667 | goto out; | ||
668 | retval = xfs_dir_shortform_create(iargs, parent); | ||
669 | if (retval) | ||
670 | goto out; | ||
671 | |||
672 | /* | ||
673 | * Copy the rest of the filenames | ||
674 | */ | ||
675 | entry = &leaf->entries[0]; | ||
676 | args.dp = dp; | ||
677 | args.firstblock = iargs->firstblock; | ||
678 | args.flist = iargs->flist; | ||
679 | args.total = iargs->total; | ||
680 | args.whichfork = XFS_DATA_FORK; | ||
681 | args.trans = iargs->trans; | ||
682 | args.justcheck = 0; | ||
683 | args.addname = args.oknoent = 1; | ||
684 | for (i = 0; i < INT_GET(hdr->count, ARCH_CONVERT); entry++, i++) { | ||
685 | if (!entry->nameidx) | ||
686 | continue; | ||
687 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); | ||
688 | args.name = (char *)(namest->name); | ||
689 | args.namelen = entry->namelen; | ||
690 | args.hashval = INT_GET(entry->hashval, ARCH_CONVERT); | ||
691 | XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args.inumber); | ||
692 | xfs_dir_shortform_addname(&args); | ||
693 | } | ||
694 | |||
695 | out: | ||
696 | kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount)); | ||
697 | return retval; | ||
698 | } | ||
699 | |||
700 | /* | ||
701 | * Convert from using a single leaf to a root node and a leaf. | ||
702 | */ | ||
703 | int | ||
704 | xfs_dir_leaf_to_node(xfs_da_args_t *args) | ||
705 | { | ||
706 | xfs_dir_leafblock_t *leaf; | ||
707 | xfs_da_intnode_t *node; | ||
708 | xfs_inode_t *dp; | ||
709 | xfs_dabuf_t *bp1, *bp2; | ||
710 | xfs_dablk_t blkno; | ||
711 | int retval; | ||
712 | |||
713 | dp = args->dp; | ||
714 | retval = xfs_da_grow_inode(args, &blkno); | ||
715 | ASSERT(blkno == 1); | ||
716 | if (retval) | ||
717 | return retval; | ||
718 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1, | ||
719 | XFS_DATA_FORK); | ||
720 | if (retval) | ||
721 | return retval; | ||
722 | ASSERT(bp1 != NULL); | ||
723 | retval = xfs_da_get_buf(args->trans, args->dp, 1, -1, &bp2, | ||
724 | XFS_DATA_FORK); | ||
725 | if (retval) { | ||
726 | xfs_da_buf_done(bp1); | ||
727 | return retval; | ||
728 | } | ||
729 | ASSERT(bp2 != NULL); | ||
730 | memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount)); | ||
731 | xfs_da_buf_done(bp1); | ||
732 | xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); | ||
733 | |||
734 | /* | ||
735 | * Set up the new root node. | ||
736 | */ | ||
737 | retval = xfs_da_node_create(args, 0, 1, &bp1, XFS_DATA_FORK); | ||
738 | if (retval) { | ||
739 | xfs_da_buf_done(bp2); | ||
740 | return retval; | ||
741 | } | ||
742 | node = bp1->data; | ||
743 | leaf = bp2->data; | ||
744 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
745 | node->btree[0].hashval = cpu_to_be32( | ||
746 | INT_GET(leaf->entries[ | ||
747 | INT_GET(leaf->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT)); | ||
748 | xfs_da_buf_done(bp2); | ||
749 | node->btree[0].before = cpu_to_be32(blkno); | ||
750 | node->hdr.count = cpu_to_be16(1); | ||
751 | xfs_da_log_buf(args->trans, bp1, | ||
752 | XFS_DA_LOGRANGE(node, &node->btree[0], sizeof(node->btree[0]))); | ||
753 | xfs_da_buf_done(bp1); | ||
754 | |||
755 | return retval; | ||
756 | } | ||
757 | |||
758 | |||
759 | /*======================================================================== | ||
760 | * Routines used for growing the Btree. | ||
761 | *========================================================================*/ | ||
762 | |||
763 | /* | ||
764 | * Create the initial contents of a leaf directory | ||
765 | * or a leaf in a node directory. | ||
766 | */ | ||
767 | STATIC int | ||
768 | xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) | ||
769 | { | ||
770 | xfs_dir_leafblock_t *leaf; | ||
771 | xfs_dir_leaf_hdr_t *hdr; | ||
772 | xfs_inode_t *dp; | ||
773 | xfs_dabuf_t *bp; | ||
774 | int retval; | ||
775 | |||
776 | dp = args->dp; | ||
777 | ASSERT(dp != NULL); | ||
778 | retval = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp, XFS_DATA_FORK); | ||
779 | if (retval) | ||
780 | return retval; | ||
781 | ASSERT(bp != NULL); | ||
782 | leaf = bp->data; | ||
783 | memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); | ||
784 | hdr = &leaf->hdr; | ||
785 | hdr->info.magic = cpu_to_be16(XFS_DIR_LEAF_MAGIC); | ||
786 | INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount)); | ||
787 | if (!hdr->firstused) | ||
788 | INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount) - 1); | ||
789 | INT_SET(hdr->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t)); | ||
790 | INT_SET(hdr->freemap[0].size, ARCH_CONVERT, INT_GET(hdr->firstused, ARCH_CONVERT) - INT_GET(hdr->freemap[0].base, ARCH_CONVERT)); | ||
791 | |||
792 | xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); | ||
793 | |||
794 | *bpp = bp; | ||
795 | return 0; | ||
796 | } | ||
797 | |||
798 | /* | ||
799 | * Split the leaf node, rebalance, then add the new entry. | ||
800 | */ | ||
801 | int | ||
802 | xfs_dir_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | ||
803 | xfs_da_state_blk_t *newblk) | ||
804 | { | ||
805 | xfs_dablk_t blkno; | ||
806 | xfs_da_args_t *args; | ||
807 | int error; | ||
808 | |||
809 | /* | ||
810 | * Allocate space for a new leaf node. | ||
811 | */ | ||
812 | args = state->args; | ||
813 | ASSERT(args != NULL); | ||
814 | ASSERT(oldblk->magic == XFS_DIR_LEAF_MAGIC); | ||
815 | error = xfs_da_grow_inode(args, &blkno); | ||
816 | if (error) | ||
817 | return error; | ||
818 | error = xfs_dir_leaf_create(args, blkno, &newblk->bp); | ||
819 | if (error) | ||
820 | return error; | ||
821 | newblk->blkno = blkno; | ||
822 | newblk->magic = XFS_DIR_LEAF_MAGIC; | ||
823 | |||
824 | /* | ||
825 | * Rebalance the entries across the two leaves. | ||
826 | */ | ||
827 | xfs_dir_leaf_rebalance(state, oldblk, newblk); | ||
828 | error = xfs_da_blk_link(state, oldblk, newblk); | ||
829 | if (error) | ||
830 | return error; | ||
831 | |||
832 | /* | ||
833 | * Insert the new entry in the correct block. | ||
834 | */ | ||
835 | if (state->inleaf) { | ||
836 | error = xfs_dir_leaf_add(oldblk->bp, args, oldblk->index); | ||
837 | } else { | ||
838 | error = xfs_dir_leaf_add(newblk->bp, args, newblk->index); | ||
839 | } | ||
840 | |||
841 | /* | ||
842 | * Update last hashval in each block since we added the name. | ||
843 | */ | ||
844 | oldblk->hashval = xfs_dir_leaf_lasthash(oldblk->bp, NULL); | ||
845 | newblk->hashval = xfs_dir_leaf_lasthash(newblk->bp, NULL); | ||
846 | return error; | ||
847 | } | ||
848 | |||
849 | /* | ||
850 | * Add a name to the leaf directory structure. | ||
851 | * | ||
852 | * Must take into account fragmented leaves and leaves where spacemap has | ||
853 | * lost some freespace information (ie: holes). | ||
854 | */ | ||
855 | int | ||
856 | xfs_dir_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index) | ||
857 | { | ||
858 | xfs_dir_leafblock_t *leaf; | ||
859 | xfs_dir_leaf_hdr_t *hdr; | ||
860 | xfs_dir_leaf_map_t *map; | ||
861 | int tablesize, entsize, sum, i, tmp, error; | ||
862 | |||
863 | leaf = bp->data; | ||
864 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
865 | ASSERT((index >= 0) && (index <= INT_GET(leaf->hdr.count, ARCH_CONVERT))); | ||
866 | hdr = &leaf->hdr; | ||
867 | entsize = XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen); | ||
868 | |||
869 | /* | ||
870 | * Search through freemap for first-fit on new name length. | ||
871 | * (may need to figure in size of entry struct too) | ||
872 | */ | ||
873 | tablesize = (INT_GET(hdr->count, ARCH_CONVERT) + 1) * (uint)sizeof(xfs_dir_leaf_entry_t) | ||
874 | + (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
875 | map = &hdr->freemap[XFS_DIR_LEAF_MAPSIZE-1]; | ||
876 | for (sum = 0, i = XFS_DIR_LEAF_MAPSIZE-1; i >= 0; map--, i--) { | ||
877 | if (tablesize > INT_GET(hdr->firstused, ARCH_CONVERT)) { | ||
878 | sum += INT_GET(map->size, ARCH_CONVERT); | ||
879 | continue; | ||
880 | } | ||
881 | if (!map->size) | ||
882 | continue; /* no space in this map */ | ||
883 | tmp = entsize; | ||
884 | if (INT_GET(map->base, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT)) | ||
885 | tmp += (uint)sizeof(xfs_dir_leaf_entry_t); | ||
886 | if (INT_GET(map->size, ARCH_CONVERT) >= tmp) { | ||
887 | if (!args->justcheck) | ||
888 | xfs_dir_leaf_add_work(bp, args, index, i); | ||
889 | return 0; | ||
890 | } | ||
891 | sum += INT_GET(map->size, ARCH_CONVERT); | ||
892 | } | ||
893 | |||
894 | /* | ||
895 | * If there are no holes in the address space of the block, | ||
896 | * and we don't have enough freespace, then compaction will do us | ||
897 | * no good and we should just give up. | ||
898 | */ | ||
899 | if (!hdr->holes && (sum < entsize)) | ||
900 | return XFS_ERROR(ENOSPC); | ||
901 | |||
902 | /* | ||
903 | * Compact the entries to coalesce free space. | ||
904 | * Pass the justcheck flag so the checking pass can return | ||
905 | * an error, without changing anything, if it won't fit. | ||
906 | */ | ||
907 | error = xfs_dir_leaf_compact(args->trans, bp, | ||
908 | args->total == 0 ? | ||
909 | entsize + | ||
910 | (uint)sizeof(xfs_dir_leaf_entry_t) : 0, | ||
911 | args->justcheck); | ||
912 | if (error) | ||
913 | return error; | ||
914 | /* | ||
915 | * After compaction, the block is guaranteed to have only one | ||
916 | * free region, in freemap[0]. If it is not big enough, give up. | ||
917 | */ | ||
918 | if (INT_GET(hdr->freemap[0].size, ARCH_CONVERT) < | ||
919 | (entsize + (uint)sizeof(xfs_dir_leaf_entry_t))) | ||
920 | return XFS_ERROR(ENOSPC); | ||
921 | |||
922 | if (!args->justcheck) | ||
923 | xfs_dir_leaf_add_work(bp, args, index, 0); | ||
924 | return 0; | ||
925 | } | ||
926 | |||
927 | /* | ||
928 | * Add a name to a leaf directory structure. | ||
929 | */ | ||
930 | STATIC void | ||
931 | xfs_dir_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int index, | ||
932 | int mapindex) | ||
933 | { | ||
934 | xfs_dir_leafblock_t *leaf; | ||
935 | xfs_dir_leaf_hdr_t *hdr; | ||
936 | xfs_dir_leaf_entry_t *entry; | ||
937 | xfs_dir_leaf_name_t *namest; | ||
938 | xfs_dir_leaf_map_t *map; | ||
939 | /* REFERENCED */ | ||
940 | xfs_mount_t *mp; | ||
941 | int tmp, i; | ||
942 | |||
943 | leaf = bp->data; | ||
944 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
945 | hdr = &leaf->hdr; | ||
946 | ASSERT((mapindex >= 0) && (mapindex < XFS_DIR_LEAF_MAPSIZE)); | ||
947 | ASSERT((index >= 0) && (index <= INT_GET(hdr->count, ARCH_CONVERT))); | ||
948 | |||
949 | /* | ||
950 | * Force open some space in the entry array and fill it in. | ||
951 | */ | ||
952 | entry = &leaf->entries[index]; | ||
953 | if (index < INT_GET(hdr->count, ARCH_CONVERT)) { | ||
954 | tmp = INT_GET(hdr->count, ARCH_CONVERT) - index; | ||
955 | tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); | ||
956 | memmove(entry + 1, entry, tmp); | ||
957 | xfs_da_log_buf(args->trans, bp, | ||
958 | XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry))); | ||
959 | } | ||
960 | INT_MOD(hdr->count, ARCH_CONVERT, +1); | ||
961 | |||
962 | /* | ||
963 | * Allocate space for the new string (at the end of the run). | ||
964 | */ | ||
965 | map = &hdr->freemap[mapindex]; | ||
966 | mp = args->trans->t_mountp; | ||
967 | ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp)); | ||
968 | ASSERT(INT_GET(map->size, ARCH_CONVERT) >= XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen)); | ||
969 | ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp)); | ||
970 | INT_MOD(map->size, ARCH_CONVERT, -(XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen))); | ||
971 | INT_SET(entry->nameidx, ARCH_CONVERT, INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT)); | ||
972 | INT_SET(entry->hashval, ARCH_CONVERT, args->hashval); | ||
973 | entry->namelen = args->namelen; | ||
974 | xfs_da_log_buf(args->trans, bp, | ||
975 | XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); | ||
976 | |||
977 | /* | ||
978 | * Copy the string and inode number into the new space. | ||
979 | */ | ||
980 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); | ||
981 | XFS_DIR_SF_PUT_DIRINO(&args->inumber, &namest->inumber); | ||
982 | memcpy(namest->name, args->name, args->namelen); | ||
983 | xfs_da_log_buf(args->trans, bp, | ||
984 | XFS_DA_LOGRANGE(leaf, namest, XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry))); | ||
985 | |||
986 | /* | ||
987 | * Update the control info for this leaf node | ||
988 | */ | ||
989 | if (INT_GET(entry->nameidx, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT)) | ||
990 | INT_COPY(hdr->firstused, entry->nameidx, ARCH_CONVERT); | ||
991 | ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr))); | ||
992 | tmp = (INT_GET(hdr->count, ARCH_CONVERT)-1) * (uint)sizeof(xfs_dir_leaf_entry_t) | ||
993 | + (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
994 | map = &hdr->freemap[0]; | ||
995 | for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) { | ||
996 | if (INT_GET(map->base, ARCH_CONVERT) == tmp) { | ||
997 | INT_MOD(map->base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t)); | ||
998 | INT_MOD(map->size, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t))); | ||
999 | } | ||
1000 | } | ||
1001 | INT_MOD(hdr->namebytes, ARCH_CONVERT, args->namelen); | ||
1002 | xfs_da_log_buf(args->trans, bp, | ||
1003 | XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); | ||
1004 | } | ||
1005 | |||
1006 | /* | ||
1007 | * Garbage collect a leaf directory block by copying it to a new buffer. | ||
1008 | */ | ||
1009 | STATIC int | ||
1010 | xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp, int musthave, | ||
1011 | int justcheck) | ||
1012 | { | ||
1013 | xfs_dir_leafblock_t *leaf_s, *leaf_d; | ||
1014 | xfs_dir_leaf_hdr_t *hdr_s, *hdr_d; | ||
1015 | xfs_mount_t *mp; | ||
1016 | char *tmpbuffer; | ||
1017 | char *tmpbuffer2=NULL; | ||
1018 | int rval; | ||
1019 | int lbsize; | ||
1020 | |||
1021 | mp = trans->t_mountp; | ||
1022 | lbsize = XFS_LBSIZE(mp); | ||
1023 | tmpbuffer = kmem_alloc(lbsize, KM_SLEEP); | ||
1024 | ASSERT(tmpbuffer != NULL); | ||
1025 | memcpy(tmpbuffer, bp->data, lbsize); | ||
1026 | |||
1027 | /* | ||
1028 | * Make a second copy in case xfs_dir_leaf_moveents() | ||
1029 | * below destroys the original. | ||
1030 | */ | ||
1031 | if (musthave || justcheck) { | ||
1032 | tmpbuffer2 = kmem_alloc(lbsize, KM_SLEEP); | ||
1033 | memcpy(tmpbuffer2, bp->data, lbsize); | ||
1034 | } | ||
1035 | memset(bp->data, 0, lbsize); | ||
1036 | |||
1037 | /* | ||
1038 | * Copy basic information | ||
1039 | */ | ||
1040 | leaf_s = (xfs_dir_leafblock_t *)tmpbuffer; | ||
1041 | leaf_d = bp->data; | ||
1042 | hdr_s = &leaf_s->hdr; | ||
1043 | hdr_d = &leaf_d->hdr; | ||
1044 | hdr_d->info = hdr_s->info; /* struct copy */ | ||
1045 | INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize); | ||
1046 | if (!hdr_d->firstused) | ||
1047 | INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize - 1); | ||
1048 | hdr_d->namebytes = 0; | ||
1049 | hdr_d->count = 0; | ||
1050 | hdr_d->holes = 0; | ||
1051 | INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t)); | ||
1052 | INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT)); | ||
1053 | |||
1054 | /* | ||
1055 | * Copy all entry's in the same (sorted) order, | ||
1056 | * but allocate filenames packed and in sequence. | ||
1057 | * This changes the source (leaf_s) as well. | ||
1058 | */ | ||
1059 | xfs_dir_leaf_moveents(leaf_s, 0, leaf_d, 0, (int)INT_GET(hdr_s->count, ARCH_CONVERT), mp); | ||
1060 | |||
1061 | if (musthave && INT_GET(hdr_d->freemap[0].size, ARCH_CONVERT) < musthave) | ||
1062 | rval = XFS_ERROR(ENOSPC); | ||
1063 | else | ||
1064 | rval = 0; | ||
1065 | |||
1066 | if (justcheck || rval == ENOSPC) { | ||
1067 | ASSERT(tmpbuffer2); | ||
1068 | memcpy(bp->data, tmpbuffer2, lbsize); | ||
1069 | } else { | ||
1070 | xfs_da_log_buf(trans, bp, 0, lbsize - 1); | ||
1071 | } | ||
1072 | |||
1073 | kmem_free(tmpbuffer, lbsize); | ||
1074 | if (musthave || justcheck) | ||
1075 | kmem_free(tmpbuffer2, lbsize); | ||
1076 | return rval; | ||
1077 | } | ||
1078 | |||
1079 | /* | ||
1080 | * Redistribute the directory entries between two leaf nodes, | ||
1081 | * taking into account the size of the new entry. | ||
1082 | * | ||
1083 | * NOTE: if new block is empty, then it will get the upper half of old block. | ||
1084 | */ | ||
1085 | STATIC void | ||
1086 | xfs_dir_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | ||
1087 | xfs_da_state_blk_t *blk2) | ||
1088 | { | ||
1089 | xfs_da_state_blk_t *tmp_blk; | ||
1090 | xfs_dir_leafblock_t *leaf1, *leaf2; | ||
1091 | xfs_dir_leaf_hdr_t *hdr1, *hdr2; | ||
1092 | int count, totallen, max, space, swap; | ||
1093 | |||
1094 | /* | ||
1095 | * Set up environment. | ||
1096 | */ | ||
1097 | ASSERT(blk1->magic == XFS_DIR_LEAF_MAGIC); | ||
1098 | ASSERT(blk2->magic == XFS_DIR_LEAF_MAGIC); | ||
1099 | leaf1 = blk1->bp->data; | ||
1100 | leaf2 = blk2->bp->data; | ||
1101 | ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1102 | ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1103 | |||
1104 | /* | ||
1105 | * Check ordering of blocks, reverse if it makes things simpler. | ||
1106 | */ | ||
1107 | swap = 0; | ||
1108 | if (xfs_dir_leaf_order(blk1->bp, blk2->bp)) { | ||
1109 | tmp_blk = blk1; | ||
1110 | blk1 = blk2; | ||
1111 | blk2 = tmp_blk; | ||
1112 | leaf1 = blk1->bp->data; | ||
1113 | leaf2 = blk2->bp->data; | ||
1114 | swap = 1; | ||
1115 | } | ||
1116 | hdr1 = &leaf1->hdr; | ||
1117 | hdr2 = &leaf2->hdr; | ||
1118 | |||
1119 | /* | ||
1120 | * Examine entries until we reduce the absolute difference in | ||
1121 | * byte usage between the two blocks to a minimum. Then get | ||
1122 | * the direction to copy and the number of elements to move. | ||
1123 | */ | ||
1124 | state->inleaf = xfs_dir_leaf_figure_balance(state, blk1, blk2, | ||
1125 | &count, &totallen); | ||
1126 | if (swap) | ||
1127 | state->inleaf = !state->inleaf; | ||
1128 | |||
1129 | /* | ||
1130 | * Move any entries required from leaf to leaf: | ||
1131 | */ | ||
1132 | if (count < INT_GET(hdr1->count, ARCH_CONVERT)) { | ||
1133 | /* | ||
1134 | * Figure the total bytes to be added to the destination leaf. | ||
1135 | */ | ||
1136 | count = INT_GET(hdr1->count, ARCH_CONVERT) - count; /* number entries being moved */ | ||
1137 | space = INT_GET(hdr1->namebytes, ARCH_CONVERT) - totallen; | ||
1138 | space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1); | ||
1139 | space += count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1140 | |||
1141 | /* | ||
1142 | * leaf2 is the destination, compact it if it looks tight. | ||
1143 | */ | ||
1144 | max = INT_GET(hdr2->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
1145 | max -= INT_GET(hdr2->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1146 | if (space > max) { | ||
1147 | xfs_dir_leaf_compact(state->args->trans, blk2->bp, | ||
1148 | 0, 0); | ||
1149 | } | ||
1150 | |||
1151 | /* | ||
1152 | * Move high entries from leaf1 to low end of leaf2. | ||
1153 | */ | ||
1154 | xfs_dir_leaf_moveents(leaf1, INT_GET(hdr1->count, ARCH_CONVERT) - count, | ||
1155 | leaf2, 0, count, state->mp); | ||
1156 | |||
1157 | xfs_da_log_buf(state->args->trans, blk1->bp, 0, | ||
1158 | state->blocksize-1); | ||
1159 | xfs_da_log_buf(state->args->trans, blk2->bp, 0, | ||
1160 | state->blocksize-1); | ||
1161 | |||
1162 | } else if (count > INT_GET(hdr1->count, ARCH_CONVERT)) { | ||
1163 | /* | ||
1164 | * Figure the total bytes to be added to the destination leaf. | ||
1165 | */ | ||
1166 | count -= INT_GET(hdr1->count, ARCH_CONVERT); /* number entries being moved */ | ||
1167 | space = totallen - INT_GET(hdr1->namebytes, ARCH_CONVERT); | ||
1168 | space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1); | ||
1169 | space += count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1170 | |||
1171 | /* | ||
1172 | * leaf1 is the destination, compact it if it looks tight. | ||
1173 | */ | ||
1174 | max = INT_GET(hdr1->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
1175 | max -= INT_GET(hdr1->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1176 | if (space > max) { | ||
1177 | xfs_dir_leaf_compact(state->args->trans, blk1->bp, | ||
1178 | 0, 0); | ||
1179 | } | ||
1180 | |||
1181 | /* | ||
1182 | * Move low entries from leaf2 to high end of leaf1. | ||
1183 | */ | ||
1184 | xfs_dir_leaf_moveents(leaf2, 0, leaf1, (int)INT_GET(hdr1->count, ARCH_CONVERT), | ||
1185 | count, state->mp); | ||
1186 | |||
1187 | xfs_da_log_buf(state->args->trans, blk1->bp, 0, | ||
1188 | state->blocksize-1); | ||
1189 | xfs_da_log_buf(state->args->trans, blk2->bp, 0, | ||
1190 | state->blocksize-1); | ||
1191 | } | ||
1192 | |||
1193 | /* | ||
1194 | * Copy out last hashval in each block for B-tree code. | ||
1195 | */ | ||
1196 | blk1->hashval = INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); | ||
1197 | blk2->hashval = INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); | ||
1198 | |||
1199 | /* | ||
1200 | * Adjust the expected index for insertion. | ||
1201 | * GROT: this doesn't work unless blk2 was originally empty. | ||
1202 | */ | ||
1203 | if (!state->inleaf) { | ||
1204 | blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT); | ||
1205 | } | ||
1206 | } | ||
1207 | |||
1208 | /* | ||
1209 | * Examine entries until we reduce the absolute difference in | ||
1210 | * byte usage between the two blocks to a minimum. | ||
1211 | * GROT: Is this really necessary? With other than a 512 byte blocksize, | ||
1212 | * GROT: there will always be enough room in either block for a new entry. | ||
1213 | * GROT: Do a double-split for this case? | ||
1214 | */ | ||
1215 | STATIC int | ||
1216 | xfs_dir_leaf_figure_balance(xfs_da_state_t *state, | ||
1217 | xfs_da_state_blk_t *blk1, | ||
1218 | xfs_da_state_blk_t *blk2, | ||
1219 | int *countarg, int *namebytesarg) | ||
1220 | { | ||
1221 | xfs_dir_leafblock_t *leaf1, *leaf2; | ||
1222 | xfs_dir_leaf_hdr_t *hdr1, *hdr2; | ||
1223 | xfs_dir_leaf_entry_t *entry; | ||
1224 | int count, max, totallen, half; | ||
1225 | int lastdelta, foundit, tmp; | ||
1226 | |||
1227 | /* | ||
1228 | * Set up environment. | ||
1229 | */ | ||
1230 | leaf1 = blk1->bp->data; | ||
1231 | leaf2 = blk2->bp->data; | ||
1232 | hdr1 = &leaf1->hdr; | ||
1233 | hdr2 = &leaf2->hdr; | ||
1234 | foundit = 0; | ||
1235 | totallen = 0; | ||
1236 | |||
1237 | /* | ||
1238 | * Examine entries until we reduce the absolute difference in | ||
1239 | * byte usage between the two blocks to a minimum. | ||
1240 | */ | ||
1241 | max = INT_GET(hdr1->count, ARCH_CONVERT) + INT_GET(hdr2->count, ARCH_CONVERT); | ||
1242 | half = (max+1) * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1); | ||
1243 | half += INT_GET(hdr1->namebytes, ARCH_CONVERT) + INT_GET(hdr2->namebytes, ARCH_CONVERT) + state->args->namelen; | ||
1244 | half /= 2; | ||
1245 | lastdelta = state->blocksize; | ||
1246 | entry = &leaf1->entries[0]; | ||
1247 | for (count = 0; count < max; entry++, count++) { | ||
1248 | |||
1249 | #define XFS_DIR_ABS(A) (((A) < 0) ? -(A) : (A)) | ||
1250 | /* | ||
1251 | * The new entry is in the first block, account for it. | ||
1252 | */ | ||
1253 | if (count == blk1->index) { | ||
1254 | tmp = totallen + (uint)sizeof(*entry) | ||
1255 | + XFS_DIR_LEAF_ENTSIZE_BYNAME(state->args->namelen); | ||
1256 | if (XFS_DIR_ABS(half - tmp) > lastdelta) | ||
1257 | break; | ||
1258 | lastdelta = XFS_DIR_ABS(half - tmp); | ||
1259 | totallen = tmp; | ||
1260 | foundit = 1; | ||
1261 | } | ||
1262 | |||
1263 | /* | ||
1264 | * Wrap around into the second block if necessary. | ||
1265 | */ | ||
1266 | if (count == INT_GET(hdr1->count, ARCH_CONVERT)) { | ||
1267 | leaf1 = leaf2; | ||
1268 | entry = &leaf1->entries[0]; | ||
1269 | } | ||
1270 | |||
1271 | /* | ||
1272 | * Figure out if next leaf entry would be too much. | ||
1273 | */ | ||
1274 | tmp = totallen + (uint)sizeof(*entry) | ||
1275 | + XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry); | ||
1276 | if (XFS_DIR_ABS(half - tmp) > lastdelta) | ||
1277 | break; | ||
1278 | lastdelta = XFS_DIR_ABS(half - tmp); | ||
1279 | totallen = tmp; | ||
1280 | #undef XFS_DIR_ABS | ||
1281 | } | ||
1282 | |||
1283 | /* | ||
1284 | * Calculate the number of namebytes that will end up in lower block. | ||
1285 | * If new entry not in lower block, fix up the count. | ||
1286 | */ | ||
1287 | totallen -= | ||
1288 | count * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1); | ||
1289 | if (foundit) { | ||
1290 | totallen -= (sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1) + | ||
1291 | state->args->namelen; | ||
1292 | } | ||
1293 | |||
1294 | *countarg = count; | ||
1295 | *namebytesarg = totallen; | ||
1296 | return foundit; | ||
1297 | } | ||
1298 | |||
1299 | /*======================================================================== | ||
1300 | * Routines used for shrinking the Btree. | ||
1301 | *========================================================================*/ | ||
1302 | |||
1303 | /* | ||
1304 | * Check a leaf block and its neighbors to see if the block should be | ||
1305 | * collapsed into one or the other neighbor. Always keep the block | ||
1306 | * with the smaller block number. | ||
1307 | * If the current block is over 50% full, don't try to join it, return 0. | ||
1308 | * If the block is empty, fill in the state structure and return 2. | ||
1309 | * If it can be collapsed, fill in the state structure and return 1. | ||
1310 | * If nothing can be done, return 0. | ||
1311 | */ | ||
1312 | int | ||
1313 | xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action) | ||
1314 | { | ||
1315 | xfs_dir_leafblock_t *leaf; | ||
1316 | xfs_da_state_blk_t *blk; | ||
1317 | xfs_da_blkinfo_t *info; | ||
1318 | int count, bytes, forward, error, retval, i; | ||
1319 | xfs_dablk_t blkno; | ||
1320 | xfs_dabuf_t *bp; | ||
1321 | |||
1322 | /* | ||
1323 | * Check for the degenerate case of the block being over 50% full. | ||
1324 | * If so, it's not worth even looking to see if we might be able | ||
1325 | * to coalesce with a sibling. | ||
1326 | */ | ||
1327 | blk = &state->path.blk[ state->path.active-1 ]; | ||
1328 | info = blk->bp->data; | ||
1329 | ASSERT(be16_to_cpu(info->magic) == XFS_DIR_LEAF_MAGIC); | ||
1330 | leaf = (xfs_dir_leafblock_t *)info; | ||
1331 | count = INT_GET(leaf->hdr.count, ARCH_CONVERT); | ||
1332 | bytes = (uint)sizeof(xfs_dir_leaf_hdr_t) + | ||
1333 | count * (uint)sizeof(xfs_dir_leaf_entry_t) + | ||
1334 | count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) + | ||
1335 | INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); | ||
1336 | if (bytes > (state->blocksize >> 1)) { | ||
1337 | *action = 0; /* blk over 50%, don't try to join */ | ||
1338 | return 0; | ||
1339 | } | ||
1340 | |||
1341 | /* | ||
1342 | * Check for the degenerate case of the block being empty. | ||
1343 | * If the block is empty, we'll simply delete it, no need to | ||
1344 | * coalesce it with a sibling block. We choose (arbitrarily) | ||
1345 | * to merge with the forward block unless it is NULL. | ||
1346 | */ | ||
1347 | if (count == 0) { | ||
1348 | /* | ||
1349 | * Make altpath point to the block we want to keep and | ||
1350 | * path point to the block we want to drop (this one). | ||
1351 | */ | ||
1352 | forward = (info->forw != 0); | ||
1353 | memcpy(&state->altpath, &state->path, sizeof(state->path)); | ||
1354 | error = xfs_da_path_shift(state, &state->altpath, forward, | ||
1355 | 0, &retval); | ||
1356 | if (error) | ||
1357 | return error; | ||
1358 | if (retval) { | ||
1359 | *action = 0; | ||
1360 | } else { | ||
1361 | *action = 2; | ||
1362 | } | ||
1363 | return 0; | ||
1364 | } | ||
1365 | |||
1366 | /* | ||
1367 | * Examine each sibling block to see if we can coalesce with | ||
1368 | * at least 25% free space to spare. We need to figure out | ||
1369 | * whether to merge with the forward or the backward block. | ||
1370 | * We prefer coalescing with the lower numbered sibling so as | ||
1371 | * to shrink a directory over time. | ||
1372 | */ | ||
1373 | forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); /* start with smaller blk num */ | ||
1374 | for (i = 0; i < 2; forward = !forward, i++) { | ||
1375 | if (forward) | ||
1376 | blkno = be32_to_cpu(info->forw); | ||
1377 | else | ||
1378 | blkno = be32_to_cpu(info->back); | ||
1379 | if (blkno == 0) | ||
1380 | continue; | ||
1381 | error = xfs_da_read_buf(state->args->trans, state->args->dp, | ||
1382 | blkno, -1, &bp, | ||
1383 | XFS_DATA_FORK); | ||
1384 | if (error) | ||
1385 | return error; | ||
1386 | ASSERT(bp != NULL); | ||
1387 | |||
1388 | leaf = (xfs_dir_leafblock_t *)info; | ||
1389 | count = INT_GET(leaf->hdr.count, ARCH_CONVERT); | ||
1390 | bytes = state->blocksize - (state->blocksize>>2); | ||
1391 | bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); | ||
1392 | leaf = bp->data; | ||
1393 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1394 | count += INT_GET(leaf->hdr.count, ARCH_CONVERT); | ||
1395 | bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); | ||
1396 | bytes -= count * ((uint)sizeof(xfs_dir_leaf_name_t) - 1); | ||
1397 | bytes -= count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1398 | bytes -= (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
1399 | if (bytes >= 0) | ||
1400 | break; /* fits with at least 25% to spare */ | ||
1401 | |||
1402 | xfs_da_brelse(state->args->trans, bp); | ||
1403 | } | ||
1404 | if (i >= 2) { | ||
1405 | *action = 0; | ||
1406 | return 0; | ||
1407 | } | ||
1408 | xfs_da_buf_done(bp); | ||
1409 | |||
1410 | /* | ||
1411 | * Make altpath point to the block we want to keep (the lower | ||
1412 | * numbered block) and path point to the block we want to drop. | ||
1413 | */ | ||
1414 | memcpy(&state->altpath, &state->path, sizeof(state->path)); | ||
1415 | if (blkno < blk->blkno) { | ||
1416 | error = xfs_da_path_shift(state, &state->altpath, forward, | ||
1417 | 0, &retval); | ||
1418 | } else { | ||
1419 | error = xfs_da_path_shift(state, &state->path, forward, | ||
1420 | 0, &retval); | ||
1421 | } | ||
1422 | if (error) | ||
1423 | return error; | ||
1424 | if (retval) { | ||
1425 | *action = 0; | ||
1426 | } else { | ||
1427 | *action = 1; | ||
1428 | } | ||
1429 | return 0; | ||
1430 | } | ||
1431 | |||
1432 | /* | ||
1433 | * Remove a name from the leaf directory structure. | ||
1434 | * | ||
1435 | * Return 1 if leaf is less than 37% full, 0 if >= 37% full. | ||
1436 | * If two leaves are 37% full, when combined they will leave 25% free. | ||
1437 | */ | ||
1438 | int | ||
1439 | xfs_dir_leaf_remove(xfs_trans_t *trans, xfs_dabuf_t *bp, int index) | ||
1440 | { | ||
1441 | xfs_dir_leafblock_t *leaf; | ||
1442 | xfs_dir_leaf_hdr_t *hdr; | ||
1443 | xfs_dir_leaf_map_t *map; | ||
1444 | xfs_dir_leaf_entry_t *entry; | ||
1445 | xfs_dir_leaf_name_t *namest; | ||
1446 | int before, after, smallest, entsize; | ||
1447 | int tablesize, tmp, i; | ||
1448 | xfs_mount_t *mp; | ||
1449 | |||
1450 | leaf = bp->data; | ||
1451 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1452 | hdr = &leaf->hdr; | ||
1453 | mp = trans->t_mountp; | ||
1454 | ASSERT((INT_GET(hdr->count, ARCH_CONVERT) > 0) && (INT_GET(hdr->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8))); | ||
1455 | ASSERT((index >= 0) && (index < INT_GET(hdr->count, ARCH_CONVERT))); | ||
1456 | ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr))); | ||
1457 | entry = &leaf->entries[index]; | ||
1458 | ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT)); | ||
1459 | ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp)); | ||
1460 | |||
1461 | /* | ||
1462 | * Scan through free region table: | ||
1463 | * check for adjacency of free'd entry with an existing one, | ||
1464 | * find smallest free region in case we need to replace it, | ||
1465 | * adjust any map that borders the entry table, | ||
1466 | */ | ||
1467 | tablesize = INT_GET(hdr->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t) | ||
1468 | + (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
1469 | map = &hdr->freemap[0]; | ||
1470 | tmp = INT_GET(map->size, ARCH_CONVERT); | ||
1471 | before = after = -1; | ||
1472 | smallest = XFS_DIR_LEAF_MAPSIZE - 1; | ||
1473 | entsize = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry); | ||
1474 | for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) { | ||
1475 | ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp)); | ||
1476 | ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp)); | ||
1477 | if (INT_GET(map->base, ARCH_CONVERT) == tablesize) { | ||
1478 | INT_MOD(map->base, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t))); | ||
1479 | INT_MOD(map->size, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t)); | ||
1480 | } | ||
1481 | |||
1482 | if ((INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT)) == INT_GET(entry->nameidx, ARCH_CONVERT)) { | ||
1483 | before = i; | ||
1484 | } else if (INT_GET(map->base, ARCH_CONVERT) == (INT_GET(entry->nameidx, ARCH_CONVERT) + entsize)) { | ||
1485 | after = i; | ||
1486 | } else if (INT_GET(map->size, ARCH_CONVERT) < tmp) { | ||
1487 | tmp = INT_GET(map->size, ARCH_CONVERT); | ||
1488 | smallest = i; | ||
1489 | } | ||
1490 | } | ||
1491 | |||
1492 | /* | ||
1493 | * Coalesce adjacent freemap regions, | ||
1494 | * or replace the smallest region. | ||
1495 | */ | ||
1496 | if ((before >= 0) || (after >= 0)) { | ||
1497 | if ((before >= 0) && (after >= 0)) { | ||
1498 | map = &hdr->freemap[before]; | ||
1499 | INT_MOD(map->size, ARCH_CONVERT, entsize); | ||
1500 | INT_MOD(map->size, ARCH_CONVERT, INT_GET(hdr->freemap[after].size, ARCH_CONVERT)); | ||
1501 | hdr->freemap[after].base = 0; | ||
1502 | hdr->freemap[after].size = 0; | ||
1503 | } else if (before >= 0) { | ||
1504 | map = &hdr->freemap[before]; | ||
1505 | INT_MOD(map->size, ARCH_CONVERT, entsize); | ||
1506 | } else { | ||
1507 | map = &hdr->freemap[after]; | ||
1508 | INT_COPY(map->base, entry->nameidx, ARCH_CONVERT); | ||
1509 | INT_MOD(map->size, ARCH_CONVERT, entsize); | ||
1510 | } | ||
1511 | } else { | ||
1512 | /* | ||
1513 | * Replace smallest region (if it is smaller than free'd entry) | ||
1514 | */ | ||
1515 | map = &hdr->freemap[smallest]; | ||
1516 | if (INT_GET(map->size, ARCH_CONVERT) < entsize) { | ||
1517 | INT_COPY(map->base, entry->nameidx, ARCH_CONVERT); | ||
1518 | INT_SET(map->size, ARCH_CONVERT, entsize); | ||
1519 | } | ||
1520 | } | ||
1521 | |||
1522 | /* | ||
1523 | * Did we remove the first entry? | ||
1524 | */ | ||
1525 | if (INT_GET(entry->nameidx, ARCH_CONVERT) == INT_GET(hdr->firstused, ARCH_CONVERT)) | ||
1526 | smallest = 1; | ||
1527 | else | ||
1528 | smallest = 0; | ||
1529 | |||
1530 | /* | ||
1531 | * Compress the remaining entries and zero out the removed stuff. | ||
1532 | */ | ||
1533 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); | ||
1534 | memset((char *)namest, 0, entsize); | ||
1535 | xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, namest, entsize)); | ||
1536 | |||
1537 | INT_MOD(hdr->namebytes, ARCH_CONVERT, -(entry->namelen)); | ||
1538 | tmp = (INT_GET(hdr->count, ARCH_CONVERT) - index) * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1539 | memmove(entry, entry + 1, tmp); | ||
1540 | INT_MOD(hdr->count, ARCH_CONVERT, -1); | ||
1541 | xfs_da_log_buf(trans, bp, | ||
1542 | XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry))); | ||
1543 | entry = &leaf->entries[INT_GET(hdr->count, ARCH_CONVERT)]; | ||
1544 | memset((char *)entry, 0, sizeof(xfs_dir_leaf_entry_t)); | ||
1545 | |||
1546 | /* | ||
1547 | * If we removed the first entry, re-find the first used byte | ||
1548 | * in the name area. Note that if the entry was the "firstused", | ||
1549 | * then we don't have a "hole" in our block resulting from | ||
1550 | * removing the name. | ||
1551 | */ | ||
1552 | if (smallest) { | ||
1553 | tmp = XFS_LBSIZE(mp); | ||
1554 | entry = &leaf->entries[0]; | ||
1555 | for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) { | ||
1556 | ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT)); | ||
1557 | ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp)); | ||
1558 | if (INT_GET(entry->nameidx, ARCH_CONVERT) < tmp) | ||
1559 | tmp = INT_GET(entry->nameidx, ARCH_CONVERT); | ||
1560 | } | ||
1561 | INT_SET(hdr->firstused, ARCH_CONVERT, tmp); | ||
1562 | if (!hdr->firstused) | ||
1563 | INT_SET(hdr->firstused, ARCH_CONVERT, tmp - 1); | ||
1564 | } else { | ||
1565 | hdr->holes = 1; /* mark as needing compaction */ | ||
1566 | } | ||
1567 | |||
1568 | xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); | ||
1569 | |||
1570 | /* | ||
1571 | * Check if leaf is less than 50% full, caller may want to | ||
1572 | * "join" the leaf with a sibling if so. | ||
1573 | */ | ||
1574 | tmp = (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
1575 | tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1576 | tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * ((uint)sizeof(xfs_dir_leaf_name_t) - 1); | ||
1577 | tmp += INT_GET(leaf->hdr.namebytes, ARCH_CONVERT); | ||
1578 | if (tmp < mp->m_dir_magicpct) | ||
1579 | return 1; /* leaf is < 37% full */ | ||
1580 | return 0; | ||
1581 | } | ||
1582 | |||
1583 | /* | ||
1584 | * Move all the directory entries from drop_leaf into save_leaf. | ||
1585 | */ | ||
1586 | void | ||
1587 | xfs_dir_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | ||
1588 | xfs_da_state_blk_t *save_blk) | ||
1589 | { | ||
1590 | xfs_dir_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf; | ||
1591 | xfs_dir_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr; | ||
1592 | xfs_mount_t *mp; | ||
1593 | char *tmpbuffer; | ||
1594 | |||
1595 | /* | ||
1596 | * Set up environment. | ||
1597 | */ | ||
1598 | mp = state->mp; | ||
1599 | ASSERT(drop_blk->magic == XFS_DIR_LEAF_MAGIC); | ||
1600 | ASSERT(save_blk->magic == XFS_DIR_LEAF_MAGIC); | ||
1601 | drop_leaf = drop_blk->bp->data; | ||
1602 | save_leaf = save_blk->bp->data; | ||
1603 | ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1604 | ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1605 | drop_hdr = &drop_leaf->hdr; | ||
1606 | save_hdr = &save_leaf->hdr; | ||
1607 | |||
1608 | /* | ||
1609 | * Save last hashval from dying block for later Btree fixup. | ||
1610 | */ | ||
1611 | drop_blk->hashval = INT_GET(drop_leaf->entries[ drop_leaf->hdr.count-1 ].hashval, ARCH_CONVERT); | ||
1612 | |||
1613 | /* | ||
1614 | * Check if we need a temp buffer, or can we do it in place. | ||
1615 | * Note that we don't check "leaf" for holes because we will | ||
1616 | * always be dropping it, toosmall() decided that for us already. | ||
1617 | */ | ||
1618 | if (save_hdr->holes == 0) { | ||
1619 | /* | ||
1620 | * dest leaf has no holes, so we add there. May need | ||
1621 | * to make some room in the entry array. | ||
1622 | */ | ||
1623 | if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) { | ||
1624 | xfs_dir_leaf_moveents(drop_leaf, 0, save_leaf, 0, | ||
1625 | (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp); | ||
1626 | } else { | ||
1627 | xfs_dir_leaf_moveents(drop_leaf, 0, | ||
1628 | save_leaf, INT_GET(save_hdr->count, ARCH_CONVERT), | ||
1629 | (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp); | ||
1630 | } | ||
1631 | } else { | ||
1632 | /* | ||
1633 | * Destination has holes, so we make a temporary copy | ||
1634 | * of the leaf and add them both to that. | ||
1635 | */ | ||
1636 | tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP); | ||
1637 | ASSERT(tmpbuffer != NULL); | ||
1638 | memset(tmpbuffer, 0, state->blocksize); | ||
1639 | tmp_leaf = (xfs_dir_leafblock_t *)tmpbuffer; | ||
1640 | tmp_hdr = &tmp_leaf->hdr; | ||
1641 | tmp_hdr->info = save_hdr->info; /* struct copy */ | ||
1642 | tmp_hdr->count = 0; | ||
1643 | INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize); | ||
1644 | if (!tmp_hdr->firstused) | ||
1645 | INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize - 1); | ||
1646 | tmp_hdr->namebytes = 0; | ||
1647 | if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) { | ||
1648 | xfs_dir_leaf_moveents(drop_leaf, 0, tmp_leaf, 0, | ||
1649 | (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp); | ||
1650 | xfs_dir_leaf_moveents(save_leaf, 0, | ||
1651 | tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT), | ||
1652 | (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp); | ||
1653 | } else { | ||
1654 | xfs_dir_leaf_moveents(save_leaf, 0, tmp_leaf, 0, | ||
1655 | (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp); | ||
1656 | xfs_dir_leaf_moveents(drop_leaf, 0, | ||
1657 | tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT), | ||
1658 | (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp); | ||
1659 | } | ||
1660 | memcpy(save_leaf, tmp_leaf, state->blocksize); | ||
1661 | kmem_free(tmpbuffer, state->blocksize); | ||
1662 | } | ||
1663 | |||
1664 | xfs_da_log_buf(state->args->trans, save_blk->bp, 0, | ||
1665 | state->blocksize - 1); | ||
1666 | |||
1667 | /* | ||
1668 | * Copy out last hashval in each block for B-tree code. | ||
1669 | */ | ||
1670 | save_blk->hashval = INT_GET(save_leaf->entries[ INT_GET(save_leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT); | ||
1671 | } | ||
1672 | |||
1673 | /*======================================================================== | ||
1674 | * Routines used for finding things in the Btree. | ||
1675 | *========================================================================*/ | ||
1676 | |||
1677 | /* | ||
1678 | * Look up a name in a leaf directory structure. | ||
1679 | * This is the internal routine, it uses the caller's buffer. | ||
1680 | * | ||
1681 | * Note that duplicate keys are allowed, but only check within the | ||
1682 | * current leaf node. The Btree code must check in adjacent leaf nodes. | ||
1683 | * | ||
1684 | * Return in *index the index into the entry[] array of either the found | ||
1685 | * entry, or where the entry should have been (insert before that entry). | ||
1686 | * | ||
1687 | * Don't change the args->inumber unless we find the filename. | ||
1688 | */ | ||
1689 | int | ||
1690 | xfs_dir_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args, int *index) | ||
1691 | { | ||
1692 | xfs_dir_leafblock_t *leaf; | ||
1693 | xfs_dir_leaf_entry_t *entry; | ||
1694 | xfs_dir_leaf_name_t *namest; | ||
1695 | int probe, span; | ||
1696 | xfs_dahash_t hashval; | ||
1697 | |||
1698 | leaf = bp->data; | ||
1699 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1700 | ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) < (XFS_LBSIZE(args->dp->i_mount)/8)); | ||
1701 | |||
1702 | /* | ||
1703 | * Binary search. (note: small blocks will skip this loop) | ||
1704 | */ | ||
1705 | hashval = args->hashval; | ||
1706 | probe = span = INT_GET(leaf->hdr.count, ARCH_CONVERT) / 2; | ||
1707 | for (entry = &leaf->entries[probe]; span > 4; | ||
1708 | entry = &leaf->entries[probe]) { | ||
1709 | span /= 2; | ||
1710 | if (INT_GET(entry->hashval, ARCH_CONVERT) < hashval) | ||
1711 | probe += span; | ||
1712 | else if (INT_GET(entry->hashval, ARCH_CONVERT) > hashval) | ||
1713 | probe -= span; | ||
1714 | else | ||
1715 | break; | ||
1716 | } | ||
1717 | ASSERT((probe >= 0) && \ | ||
1718 | ((!leaf->hdr.count) || (probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)))); | ||
1719 | ASSERT((span <= 4) || (INT_GET(entry->hashval, ARCH_CONVERT) == hashval)); | ||
1720 | |||
1721 | /* | ||
1722 | * Since we may have duplicate hashval's, find the first matching | ||
1723 | * hashval in the leaf. | ||
1724 | */ | ||
1725 | while ((probe > 0) && (INT_GET(entry->hashval, ARCH_CONVERT) >= hashval)) { | ||
1726 | entry--; | ||
1727 | probe--; | ||
1728 | } | ||
1729 | while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)) { | ||
1730 | entry++; | ||
1731 | probe++; | ||
1732 | } | ||
1733 | if ((probe == INT_GET(leaf->hdr.count, ARCH_CONVERT)) || (INT_GET(entry->hashval, ARCH_CONVERT) != hashval)) { | ||
1734 | *index = probe; | ||
1735 | ASSERT(args->oknoent); | ||
1736 | return XFS_ERROR(ENOENT); | ||
1737 | } | ||
1738 | |||
1739 | /* | ||
1740 | * Duplicate keys may be present, so search all of them for a match. | ||
1741 | */ | ||
1742 | while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) == hashval)) { | ||
1743 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT)); | ||
1744 | if (entry->namelen == args->namelen && | ||
1745 | namest->name[0] == args->name[0] && | ||
1746 | memcmp(args->name, namest->name, args->namelen) == 0) { | ||
1747 | XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args->inumber); | ||
1748 | *index = probe; | ||
1749 | return XFS_ERROR(EEXIST); | ||
1750 | } | ||
1751 | entry++; | ||
1752 | probe++; | ||
1753 | } | ||
1754 | *index = probe; | ||
1755 | ASSERT(probe == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent); | ||
1756 | return XFS_ERROR(ENOENT); | ||
1757 | } | ||
1758 | |||
1759 | /*======================================================================== | ||
1760 | * Utility routines. | ||
1761 | *========================================================================*/ | ||
1762 | |||
1763 | /* | ||
1764 | * Move the indicated entries from one leaf to another. | ||
1765 | * NOTE: this routine modifies both source and destination leaves. | ||
1766 | */ | ||
1767 | /* ARGSUSED */ | ||
1768 | STATIC void | ||
1769 | xfs_dir_leaf_moveents(xfs_dir_leafblock_t *leaf_s, int start_s, | ||
1770 | xfs_dir_leafblock_t *leaf_d, int start_d, | ||
1771 | int count, xfs_mount_t *mp) | ||
1772 | { | ||
1773 | xfs_dir_leaf_hdr_t *hdr_s, *hdr_d; | ||
1774 | xfs_dir_leaf_entry_t *entry_s, *entry_d; | ||
1775 | int tmp, i; | ||
1776 | |||
1777 | /* | ||
1778 | * Check for nothing to do. | ||
1779 | */ | ||
1780 | if (count == 0) | ||
1781 | return; | ||
1782 | |||
1783 | /* | ||
1784 | * Set up environment. | ||
1785 | */ | ||
1786 | ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1787 | ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1788 | hdr_s = &leaf_s->hdr; | ||
1789 | hdr_d = &leaf_d->hdr; | ||
1790 | ASSERT((INT_GET(hdr_s->count, ARCH_CONVERT) > 0) && (INT_GET(hdr_s->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8))); | ||
1791 | ASSERT(INT_GET(hdr_s->firstused, ARCH_CONVERT) >= | ||
1792 | ((INT_GET(hdr_s->count, ARCH_CONVERT)*sizeof(*entry_s))+sizeof(*hdr_s))); | ||
1793 | ASSERT(INT_GET(hdr_d->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)); | ||
1794 | ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= | ||
1795 | ((INT_GET(hdr_d->count, ARCH_CONVERT)*sizeof(*entry_d))+sizeof(*hdr_d))); | ||
1796 | |||
1797 | ASSERT(start_s < INT_GET(hdr_s->count, ARCH_CONVERT)); | ||
1798 | ASSERT(start_d <= INT_GET(hdr_d->count, ARCH_CONVERT)); | ||
1799 | ASSERT(count <= INT_GET(hdr_s->count, ARCH_CONVERT)); | ||
1800 | |||
1801 | /* | ||
1802 | * Move the entries in the destination leaf up to make a hole? | ||
1803 | */ | ||
1804 | if (start_d < INT_GET(hdr_d->count, ARCH_CONVERT)) { | ||
1805 | tmp = INT_GET(hdr_d->count, ARCH_CONVERT) - start_d; | ||
1806 | tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1807 | entry_s = &leaf_d->entries[start_d]; | ||
1808 | entry_d = &leaf_d->entries[start_d + count]; | ||
1809 | memcpy(entry_d, entry_s, tmp); | ||
1810 | } | ||
1811 | |||
1812 | /* | ||
1813 | * Copy all entry's in the same (sorted) order, | ||
1814 | * but allocate filenames packed and in sequence. | ||
1815 | */ | ||
1816 | entry_s = &leaf_s->entries[start_s]; | ||
1817 | entry_d = &leaf_d->entries[start_d]; | ||
1818 | for (i = 0; i < count; entry_s++, entry_d++, i++) { | ||
1819 | ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) >= INT_GET(hdr_s->firstused, ARCH_CONVERT)); | ||
1820 | tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s); | ||
1821 | INT_MOD(hdr_d->firstused, ARCH_CONVERT, -(tmp)); | ||
1822 | entry_d->hashval = entry_s->hashval; /* INT_: direct copy */ | ||
1823 | INT_COPY(entry_d->nameidx, hdr_d->firstused, ARCH_CONVERT); | ||
1824 | entry_d->namelen = entry_s->namelen; | ||
1825 | ASSERT(INT_GET(entry_d->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp)); | ||
1826 | memcpy(XFS_DIR_LEAF_NAMESTRUCT(leaf_d, INT_GET(entry_d->nameidx, ARCH_CONVERT)), | ||
1827 | XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)), tmp); | ||
1828 | ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp)); | ||
1829 | memset((char *)XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)), | ||
1830 | 0, tmp); | ||
1831 | INT_MOD(hdr_s->namebytes, ARCH_CONVERT, -(entry_d->namelen)); | ||
1832 | INT_MOD(hdr_d->namebytes, ARCH_CONVERT, entry_d->namelen); | ||
1833 | INT_MOD(hdr_s->count, ARCH_CONVERT, -1); | ||
1834 | INT_MOD(hdr_d->count, ARCH_CONVERT, +1); | ||
1835 | tmp = INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t) | ||
1836 | + (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
1837 | ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= tmp); | ||
1838 | |||
1839 | } | ||
1840 | |||
1841 | /* | ||
1842 | * Zero out the entries we just copied. | ||
1843 | */ | ||
1844 | if (start_s == INT_GET(hdr_s->count, ARCH_CONVERT)) { | ||
1845 | tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1846 | entry_s = &leaf_s->entries[start_s]; | ||
1847 | ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp)); | ||
1848 | memset((char *)entry_s, 0, tmp); | ||
1849 | } else { | ||
1850 | /* | ||
1851 | * Move the remaining entries down to fill the hole, | ||
1852 | * then zero the entries at the top. | ||
1853 | */ | ||
1854 | tmp = INT_GET(hdr_s->count, ARCH_CONVERT) - count; | ||
1855 | tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1856 | entry_s = &leaf_s->entries[start_s + count]; | ||
1857 | entry_d = &leaf_s->entries[start_s]; | ||
1858 | memcpy(entry_d, entry_s, tmp); | ||
1859 | |||
1860 | tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
1861 | entry_s = &leaf_s->entries[INT_GET(hdr_s->count, ARCH_CONVERT)]; | ||
1862 | ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp)); | ||
1863 | memset((char *)entry_s, 0, tmp); | ||
1864 | } | ||
1865 | |||
1866 | /* | ||
1867 | * Fill in the freemap information | ||
1868 | */ | ||
1869 | INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_hdr_t)); | ||
1870 | INT_MOD(hdr_d->freemap[0].base, ARCH_CONVERT, INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)); | ||
1871 | INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT)); | ||
1872 | INT_SET(hdr_d->freemap[1].base, ARCH_CONVERT, (hdr_d->freemap[2].base = 0)); | ||
1873 | INT_SET(hdr_d->freemap[1].size, ARCH_CONVERT, (hdr_d->freemap[2].size = 0)); | ||
1874 | hdr_s->holes = 1; /* leaf may not be compact */ | ||
1875 | } | ||
1876 | |||
1877 | /* | ||
1878 | * Compare two leaf blocks "order". | ||
1879 | */ | ||
1880 | int | ||
1881 | xfs_dir_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) | ||
1882 | { | ||
1883 | xfs_dir_leafblock_t *leaf1, *leaf2; | ||
1884 | |||
1885 | leaf1 = leaf1_bp->data; | ||
1886 | leaf2 = leaf2_bp->data; | ||
1887 | ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC) && | ||
1888 | (be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC)); | ||
1889 | if ((INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0) && | ||
1890 | ((INT_GET(leaf2->entries[ 0 ].hashval, ARCH_CONVERT) < | ||
1891 | INT_GET(leaf1->entries[ 0 ].hashval, ARCH_CONVERT)) || | ||
1892 | (INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) < | ||
1893 | INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) { | ||
1894 | return 1; | ||
1895 | } | ||
1896 | return 0; | ||
1897 | } | ||
1898 | |||
1899 | /* | ||
1900 | * Pick up the last hashvalue from a leaf block. | ||
1901 | */ | ||
1902 | xfs_dahash_t | ||
1903 | xfs_dir_leaf_lasthash(xfs_dabuf_t *bp, int *count) | ||
1904 | { | ||
1905 | xfs_dir_leafblock_t *leaf; | ||
1906 | |||
1907 | leaf = bp->data; | ||
1908 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
1909 | if (count) | ||
1910 | *count = INT_GET(leaf->hdr.count, ARCH_CONVERT); | ||
1911 | if (!leaf->hdr.count) | ||
1912 | return(0); | ||
1913 | return(INT_GET(leaf->entries[ INT_GET(leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)); | ||
1914 | } | ||
1915 | |||
1916 | /* | ||
1917 | * Copy out directory entries for getdents(), for leaf directories. | ||
1918 | */ | ||
1919 | int | ||
1920 | xfs_dir_leaf_getdents_int( | ||
1921 | xfs_dabuf_t *bp, | ||
1922 | xfs_inode_t *dp, | ||
1923 | xfs_dablk_t bno, | ||
1924 | uio_t *uio, | ||
1925 | int *eobp, | ||
1926 | xfs_dirent_t *dbp, | ||
1927 | xfs_dir_put_t put, | ||
1928 | xfs_daddr_t nextda) | ||
1929 | { | ||
1930 | xfs_dir_leafblock_t *leaf; | ||
1931 | xfs_dir_leaf_entry_t *entry; | ||
1932 | xfs_dir_leaf_name_t *namest; | ||
1933 | int entno, want_entno, i, nextentno; | ||
1934 | xfs_mount_t *mp; | ||
1935 | xfs_dahash_t cookhash; | ||
1936 | xfs_dahash_t nexthash = 0; | ||
1937 | #if (BITS_PER_LONG == 32) | ||
1938 | xfs_dahash_t lasthash = XFS_DA_MAXHASH; | ||
1939 | #endif | ||
1940 | xfs_dir_put_args_t p; | ||
1941 | |||
1942 | mp = dp->i_mount; | ||
1943 | leaf = bp->data; | ||
1944 | if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { | ||
1945 | *eobp = 1; | ||
1946 | return XFS_ERROR(ENOENT); /* XXX wrong code */ | ||
1947 | } | ||
1948 | |||
1949 | want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset); | ||
1950 | |||
1951 | cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset); | ||
1952 | |||
1953 | xfs_dir_trace_g_dul("leaf: start", dp, uio, leaf); | ||
1954 | |||
1955 | /* | ||
1956 | * Re-find our place. | ||
1957 | */ | ||
1958 | for (i = entno = 0, entry = &leaf->entries[0]; | ||
1959 | i < INT_GET(leaf->hdr.count, ARCH_CONVERT); | ||
1960 | entry++, i++) { | ||
1961 | |||
1962 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, | ||
1963 | INT_GET(entry->nameidx, ARCH_CONVERT)); | ||
1964 | |||
1965 | if (unlikely( | ||
1966 | ((char *)namest < (char *)leaf) || | ||
1967 | ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) { | ||
1968 | XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)", | ||
1969 | XFS_ERRLEVEL_LOW, mp, leaf); | ||
1970 | xfs_dir_trace_g_du("leaf: corrupted", dp, uio); | ||
1971 | return XFS_ERROR(EFSCORRUPTED); | ||
1972 | } | ||
1973 | if (INT_GET(entry->hashval, ARCH_CONVERT) >= cookhash) { | ||
1974 | if ( entno < want_entno | ||
1975 | && INT_GET(entry->hashval, ARCH_CONVERT) | ||
1976 | == cookhash) { | ||
1977 | /* | ||
1978 | * Trying to get to a particular offset in a | ||
1979 | * run of equal-hashval entries. | ||
1980 | */ | ||
1981 | entno++; | ||
1982 | } else if ( want_entno > 0 | ||
1983 | && entno == want_entno | ||
1984 | && INT_GET(entry->hashval, ARCH_CONVERT) | ||
1985 | == cookhash) { | ||
1986 | break; | ||
1987 | } else { | ||
1988 | entno = 0; | ||
1989 | break; | ||
1990 | } | ||
1991 | } | ||
1992 | } | ||
1993 | |||
1994 | if (i == INT_GET(leaf->hdr.count, ARCH_CONVERT)) { | ||
1995 | xfs_dir_trace_g_du("leaf: hash not found", dp, uio); | ||
1996 | if (!leaf->hdr.info.forw) | ||
1997 | uio->uio_offset = | ||
1998 | XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH); | ||
1999 | /* | ||
2000 | * Don't set uio_offset if there's another block: | ||
2001 | * the node code will be setting uio_offset anyway. | ||
2002 | */ | ||
2003 | *eobp = 0; | ||
2004 | return 0; | ||
2005 | } | ||
2006 | xfs_dir_trace_g_due("leaf: hash found", dp, uio, entry); | ||
2007 | |||
2008 | p.dbp = dbp; | ||
2009 | p.put = put; | ||
2010 | p.uio = uio; | ||
2011 | |||
2012 | /* | ||
2013 | * We're synchronized, start copying entries out to the user. | ||
2014 | */ | ||
2015 | for (; entno >= 0 && i < INT_GET(leaf->hdr.count, ARCH_CONVERT); | ||
2016 | entry++, i++, (entno = nextentno)) { | ||
2017 | int lastresid=0, retval; | ||
2018 | xfs_dircook_t lastoffset; | ||
2019 | xfs_dahash_t thishash; | ||
2020 | |||
2021 | /* | ||
2022 | * Check for a damaged directory leaf block and pick up | ||
2023 | * the inode number from this entry. | ||
2024 | */ | ||
2025 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, | ||
2026 | INT_GET(entry->nameidx, ARCH_CONVERT)); | ||
2027 | |||
2028 | if (unlikely( | ||
2029 | ((char *)namest < (char *)leaf) || | ||
2030 | ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) { | ||
2031 | XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)", | ||
2032 | XFS_ERRLEVEL_LOW, mp, leaf); | ||
2033 | xfs_dir_trace_g_du("leaf: corrupted", dp, uio); | ||
2034 | return XFS_ERROR(EFSCORRUPTED); | ||
2035 | } | ||
2036 | |||
2037 | xfs_dir_trace_g_duc("leaf: middle cookie ", | ||
2038 | dp, uio, p.cook.o); | ||
2039 | |||
2040 | if (i < (INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1)) { | ||
2041 | nexthash = INT_GET(entry[1].hashval, ARCH_CONVERT); | ||
2042 | |||
2043 | if (nexthash == INT_GET(entry->hashval, ARCH_CONVERT)) | ||
2044 | nextentno = entno + 1; | ||
2045 | else | ||
2046 | nextentno = 0; | ||
2047 | XFS_PUT_COOKIE(p.cook, mp, bno, nextentno, nexthash); | ||
2048 | xfs_dir_trace_g_duc("leaf: middle cookie ", | ||
2049 | dp, uio, p.cook.o); | ||
2050 | |||
2051 | } else if ((thishash = be32_to_cpu(leaf->hdr.info.forw))) { | ||
2052 | xfs_dabuf_t *bp2; | ||
2053 | xfs_dir_leafblock_t *leaf2; | ||
2054 | |||
2055 | ASSERT(nextda != -1); | ||
2056 | |||
2057 | retval = xfs_da_read_buf(dp->i_transp, dp, thishash, | ||
2058 | nextda, &bp2, XFS_DATA_FORK); | ||
2059 | if (retval) | ||
2060 | return retval; | ||
2061 | |||
2062 | ASSERT(bp2 != NULL); | ||
2063 | |||
2064 | leaf2 = bp2->data; | ||
2065 | |||
2066 | if (unlikely( | ||
2067 | (be16_to_cpu(leaf2->hdr.info.magic) | ||
2068 | != XFS_DIR_LEAF_MAGIC) | ||
2069 | || (be32_to_cpu(leaf2->hdr.info.back) | ||
2070 | != bno))) { /* GROT */ | ||
2071 | XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)", | ||
2072 | XFS_ERRLEVEL_LOW, mp, | ||
2073 | leaf2); | ||
2074 | xfs_da_brelse(dp->i_transp, bp2); | ||
2075 | |||
2076 | return XFS_ERROR(EFSCORRUPTED); | ||
2077 | } | ||
2078 | |||
2079 | nexthash = INT_GET(leaf2->entries[0].hashval, | ||
2080 | ARCH_CONVERT); | ||
2081 | nextentno = -1; | ||
2082 | XFS_PUT_COOKIE(p.cook, mp, thishash, 0, nexthash); | ||
2083 | xfs_da_brelse(dp->i_transp, bp2); | ||
2084 | xfs_dir_trace_g_duc("leaf: next blk cookie", | ||
2085 | dp, uio, p.cook.o); | ||
2086 | } else { | ||
2087 | nextentno = -1; | ||
2088 | XFS_PUT_COOKIE(p.cook, mp, 0, 0, XFS_DA_MAXHASH); | ||
2089 | } | ||
2090 | |||
2091 | /* | ||
2092 | * Save off the cookie so we can fall back should the | ||
2093 | * 'put' into the outgoing buffer fails. To handle a run | ||
2094 | * of equal-hashvals, the off_t structure on 64bit | ||
2095 | * builds has entno built into the cookie to ID the | ||
2096 | * entry. On 32bit builds, we only have space for the | ||
2097 | * hashval so we can't ID specific entries within a group | ||
2098 | * of same hashval entries. For this, lastoffset is set | ||
2099 | * to the first in the run of equal hashvals so we don't | ||
2100 | * include any entries unless we can include all entries | ||
2101 | * that share the same hashval. Hopefully the buffer | ||
2102 | * provided is big enough to handle it (see pv763517). | ||
2103 | */ | ||
2104 | #if (BITS_PER_LONG == 32) | ||
2105 | if ((thishash = INT_GET(entry->hashval, ARCH_CONVERT)) | ||
2106 | != lasthash) { | ||
2107 | XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash); | ||
2108 | lastresid = uio->uio_resid; | ||
2109 | lasthash = thishash; | ||
2110 | } else { | ||
2111 | xfs_dir_trace_g_duc("leaf: DUP COOKIES, skipped", | ||
2112 | dp, uio, p.cook.o); | ||
2113 | } | ||
2114 | #else | ||
2115 | thishash = INT_GET(entry->hashval, ARCH_CONVERT); | ||
2116 | XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash); | ||
2117 | lastresid = uio->uio_resid; | ||
2118 | #endif /* BITS_PER_LONG == 32 */ | ||
2119 | |||
2120 | /* | ||
2121 | * Put the current entry into the outgoing buffer. If we fail | ||
2122 | * then restore the UIO to the first entry in the current | ||
2123 | * run of equal-hashval entries (probably one 1 entry long). | ||
2124 | */ | ||
2125 | p.ino = XFS_GET_DIR_INO8(namest->inumber); | ||
2126 | #if XFS_BIG_INUMS | ||
2127 | p.ino += mp->m_inoadd; | ||
2128 | #endif | ||
2129 | p.name = (char *)namest->name; | ||
2130 | p.namelen = entry->namelen; | ||
2131 | |||
2132 | retval = p.put(&p); | ||
2133 | |||
2134 | if (!p.done) { | ||
2135 | uio->uio_offset = lastoffset.o; | ||
2136 | uio->uio_resid = lastresid; | ||
2137 | |||
2138 | *eobp = 1; | ||
2139 | |||
2140 | xfs_dir_trace_g_du("leaf: E-O-B", dp, uio); | ||
2141 | |||
2142 | return retval; | ||
2143 | } | ||
2144 | } | ||
2145 | |||
2146 | uio->uio_offset = p.cook.o; | ||
2147 | |||
2148 | *eobp = 0; | ||
2149 | |||
2150 | xfs_dir_trace_g_du("leaf: E-O-F", dp, uio); | ||
2151 | |||
2152 | return 0; | ||
2153 | } | ||
2154 | |||
2155 | /* | ||
2156 | * Format a dirent64 structure and copy it out the the user's buffer. | ||
2157 | */ | ||
2158 | int | ||
2159 | xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa) | ||
2160 | { | ||
2161 | iovec_t *iovp; | ||
2162 | int reclen, namelen; | ||
2163 | xfs_dirent_t *idbp; | ||
2164 | uio_t *uio; | ||
2165 | |||
2166 | namelen = pa->namelen; | ||
2167 | reclen = DIRENTSIZE(namelen); | ||
2168 | uio = pa->uio; | ||
2169 | if (reclen > uio->uio_resid) { | ||
2170 | pa->done = 0; | ||
2171 | return 0; | ||
2172 | } | ||
2173 | iovp = uio->uio_iov; | ||
2174 | idbp = (xfs_dirent_t *)iovp->iov_base; | ||
2175 | iovp->iov_base = (char *)idbp + reclen; | ||
2176 | iovp->iov_len -= reclen; | ||
2177 | uio->uio_resid -= reclen; | ||
2178 | idbp->d_reclen = reclen; | ||
2179 | idbp->d_ino = pa->ino; | ||
2180 | idbp->d_off = pa->cook.o; | ||
2181 | idbp->d_name[namelen] = '\0'; | ||
2182 | pa->done = 1; | ||
2183 | memcpy(idbp->d_name, pa->name, namelen); | ||
2184 | return 0; | ||
2185 | } | ||
2186 | |||
2187 | /* | ||
2188 | * Format a dirent64 structure and copy it out the the user's buffer. | ||
2189 | */ | ||
2190 | int | ||
2191 | xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa) | ||
2192 | { | ||
2193 | int retval, reclen, namelen; | ||
2194 | xfs_dirent_t *idbp; | ||
2195 | uio_t *uio; | ||
2196 | |||
2197 | namelen = pa->namelen; | ||
2198 | reclen = DIRENTSIZE(namelen); | ||
2199 | uio = pa->uio; | ||
2200 | if (reclen > uio->uio_resid) { | ||
2201 | pa->done = 0; | ||
2202 | return 0; | ||
2203 | } | ||
2204 | idbp = pa->dbp; | ||
2205 | idbp->d_reclen = reclen; | ||
2206 | idbp->d_ino = pa->ino; | ||
2207 | idbp->d_off = pa->cook.o; | ||
2208 | idbp->d_name[namelen] = '\0'; | ||
2209 | memcpy(idbp->d_name, pa->name, namelen); | ||
2210 | retval = uio_read((caddr_t)idbp, reclen, uio); | ||
2211 | pa->done = (retval == 0); | ||
2212 | return retval; | ||
2213 | } | ||
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h deleted file mode 100644 index eb8cd9a4667f..000000000000 --- a/fs/xfs/xfs_dir_leaf.h +++ /dev/null | |||
@@ -1,231 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_DIR_LEAF_H__ | ||
19 | #define __XFS_DIR_LEAF_H__ | ||
20 | |||
21 | /* | ||
22 | * Directory layout, internal structure, access macros, etc. | ||
23 | * | ||
24 | * Large directories are structured around Btrees where all the data | ||
25 | * elements are in the leaf nodes. Filenames are hashed into an int, | ||
26 | * then that int is used as the index into the Btree. Since the hashval | ||
27 | * of a filename may not be unique, we may have duplicate keys. The | ||
28 | * internal links in the Btree are logical block offsets into the file. | ||
29 | */ | ||
30 | |||
31 | struct uio; | ||
32 | struct xfs_bmap_free; | ||
33 | struct xfs_dabuf; | ||
34 | struct xfs_da_args; | ||
35 | struct xfs_da_state; | ||
36 | struct xfs_da_state_blk; | ||
37 | struct xfs_dir_put_args; | ||
38 | struct xfs_inode; | ||
39 | struct xfs_mount; | ||
40 | struct xfs_trans; | ||
41 | |||
42 | /*======================================================================== | ||
43 | * Directory Structure when equal to XFS_LBSIZE(mp) bytes. | ||
44 | *========================================================================*/ | ||
45 | |||
46 | /* | ||
47 | * This is the structure of the leaf nodes in the Btree. | ||
48 | * | ||
49 | * Struct leaf_entry's are packed from the top. Names grow from the bottom | ||
50 | * but are not packed. The freemap contains run-length-encoded entries | ||
51 | * for the free bytes after the leaf_entry's, but only the N largest such, | ||
52 | * smaller runs are dropped. When the freemap doesn't show enough space | ||
53 | * for an allocation, we compact the namelist area and try again. If we | ||
54 | * still don't have enough space, then we have to split the block. | ||
55 | * | ||
56 | * Since we have duplicate hash keys, for each key that matches, compare | ||
57 | * the actual string. The root and intermediate node search always takes | ||
58 | * the first-in-the-block key match found, so we should only have to work | ||
59 | * "forw"ard. If none matches, continue with the "forw"ard leaf nodes | ||
60 | * until the hash key changes or the filename is found. | ||
61 | * | ||
62 | * The parent directory and the self-pointer are explicitly represented | ||
63 | * (ie: there are entries for "." and ".."). | ||
64 | * | ||
65 | * Note that the count being a __uint16_t limits us to something like a | ||
66 | * blocksize of 1.3MB in the face of worst case (short) filenames. | ||
67 | */ | ||
68 | #define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */ | ||
69 | |||
70 | typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */ | ||
71 | __uint16_t base; /* base of free region */ | ||
72 | __uint16_t size; /* run length of free region */ | ||
73 | } xfs_dir_leaf_map_t; | ||
74 | |||
75 | typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */ | ||
76 | xfs_da_blkinfo_t info; /* block type, links, etc. */ | ||
77 | __uint16_t count; /* count of active leaf_entry's */ | ||
78 | __uint16_t namebytes; /* num bytes of name strings stored */ | ||
79 | __uint16_t firstused; /* first used byte in name area */ | ||
80 | __uint8_t holes; /* != 0 if blk needs compaction */ | ||
81 | __uint8_t pad1; | ||
82 | xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE]; | ||
83 | } xfs_dir_leaf_hdr_t; | ||
84 | |||
85 | typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */ | ||
86 | xfs_dahash_t hashval; /* hash value of name */ | ||
87 | __uint16_t nameidx; /* index into buffer of name */ | ||
88 | __uint8_t namelen; /* length of name string */ | ||
89 | __uint8_t pad2; | ||
90 | } xfs_dir_leaf_entry_t; | ||
91 | |||
92 | typedef struct xfs_dir_leaf_name { | ||
93 | xfs_dir_ino_t inumber; /* inode number for this key */ | ||
94 | __uint8_t name[1]; /* name string itself */ | ||
95 | } xfs_dir_leaf_name_t; | ||
96 | |||
97 | typedef struct xfs_dir_leafblock { | ||
98 | xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */ | ||
99 | xfs_dir_leaf_entry_t entries[1]; /* var sized array */ | ||
100 | xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */ | ||
101 | } xfs_dir_leafblock_t; | ||
102 | |||
103 | /* | ||
104 | * Length of name for which a 512-byte block filesystem | ||
105 | * can get a double split. | ||
106 | */ | ||
107 | #define XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN \ | ||
108 | (512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \ | ||
109 | (uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \ | ||
110 | (uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1) | ||
111 | |||
112 | typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa); | ||
113 | |||
114 | typedef union { | ||
115 | xfs_off_t o; /* offset (cookie) */ | ||
116 | /* | ||
117 | * Watch the order here (endian-ness dependent). | ||
118 | */ | ||
119 | struct { | ||
120 | #ifndef XFS_NATIVE_HOST | ||
121 | xfs_dahash_t h; /* hash value */ | ||
122 | __uint32_t be; /* block and entry */ | ||
123 | #else | ||
124 | __uint32_t be; /* block and entry */ | ||
125 | xfs_dahash_t h; /* hash value */ | ||
126 | #endif /* XFS_NATIVE_HOST */ | ||
127 | } s; | ||
128 | } xfs_dircook_t; | ||
129 | |||
130 | #define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \ | ||
131 | ((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash)) | ||
132 | |||
133 | typedef struct xfs_dir_put_args { | ||
134 | xfs_dircook_t cook; /* cookie of (next) entry */ | ||
135 | xfs_intino_t ino; /* inode number */ | ||
136 | struct xfs_dirent *dbp; /* buffer pointer */ | ||
137 | char *name; /* directory entry name */ | ||
138 | int namelen; /* length of name */ | ||
139 | int done; /* output: set if value was stored */ | ||
140 | xfs_dir_put_t put; /* put function ptr (i/o) */ | ||
141 | struct uio *uio; /* uio control structure */ | ||
142 | } xfs_dir_put_args_t; | ||
143 | |||
144 | #define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \ | ||
145 | xfs_dir_leaf_entsize_byname(len) | ||
146 | static inline int xfs_dir_leaf_entsize_byname(int len) | ||
147 | { | ||
148 | return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len; | ||
149 | } | ||
150 | |||
151 | #define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \ | ||
152 | xfs_dir_leaf_entsize_byentry(entry) | ||
153 | static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry) | ||
154 | { | ||
155 | return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen; | ||
156 | } | ||
157 | |||
158 | #define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \ | ||
159 | xfs_dir_leaf_namestruct(leafp,offset) | ||
160 | static inline xfs_dir_leaf_name_t * | ||
161 | xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset) | ||
162 | { | ||
163 | return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset]; | ||
164 | } | ||
165 | |||
166 | /*======================================================================== | ||
167 | * Function prototypes for the kernel. | ||
168 | *========================================================================*/ | ||
169 | |||
170 | /* | ||
171 | * Internal routines when dirsize < XFS_LITINO(mp). | ||
172 | */ | ||
173 | int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent); | ||
174 | int xfs_dir_shortform_addname(struct xfs_da_args *args); | ||
175 | int xfs_dir_shortform_lookup(struct xfs_da_args *args); | ||
176 | int xfs_dir_shortform_to_leaf(struct xfs_da_args *args); | ||
177 | int xfs_dir_shortform_removename(struct xfs_da_args *args); | ||
178 | int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp, | ||
179 | struct xfs_dirent *dbp, xfs_dir_put_t put); | ||
180 | int xfs_dir_shortform_replace(struct xfs_da_args *args); | ||
181 | |||
182 | /* | ||
183 | * Internal routines when dirsize == XFS_LBSIZE(mp). | ||
184 | */ | ||
185 | int xfs_dir_leaf_to_node(struct xfs_da_args *args); | ||
186 | int xfs_dir_leaf_to_shortform(struct xfs_da_args *args); | ||
187 | |||
188 | /* | ||
189 | * Routines used for growing the Btree. | ||
190 | */ | ||
191 | int xfs_dir_leaf_split(struct xfs_da_state *state, | ||
192 | struct xfs_da_state_blk *oldblk, | ||
193 | struct xfs_da_state_blk *newblk); | ||
194 | int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer, | ||
195 | struct xfs_da_args *args, int insertion_index); | ||
196 | int xfs_dir_leaf_addname(struct xfs_da_args *args); | ||
197 | int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer, | ||
198 | struct xfs_da_args *args, | ||
199 | int *index_found_at); | ||
200 | int xfs_dir_leaf_remove(struct xfs_trans *trans, | ||
201 | struct xfs_dabuf *leaf_buffer, | ||
202 | int index_to_remove); | ||
203 | int xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp, | ||
204 | xfs_dablk_t bno, struct uio *uio, | ||
205 | int *eobp, struct xfs_dirent *dbp, | ||
206 | xfs_dir_put_t put, xfs_daddr_t nextda); | ||
207 | |||
208 | /* | ||
209 | * Routines used for shrinking the Btree. | ||
210 | */ | ||
211 | int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval); | ||
212 | void xfs_dir_leaf_unbalance(struct xfs_da_state *state, | ||
213 | struct xfs_da_state_blk *drop_blk, | ||
214 | struct xfs_da_state_blk *save_blk); | ||
215 | |||
216 | /* | ||
217 | * Utility routines. | ||
218 | */ | ||
219 | uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count); | ||
220 | int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp, | ||
221 | struct xfs_dabuf *leaf2_bp); | ||
222 | int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa); | ||
223 | int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa); | ||
224 | int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); | ||
225 | |||
226 | /* | ||
227 | * Global data. | ||
228 | */ | ||
229 | extern xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; | ||
230 | |||
231 | #endif /* __XFS_DIR_LEAF_H__ */ | ||
diff --git a/fs/xfs/xfs_dir_sf.h b/fs/xfs/xfs_dir_sf.h deleted file mode 100644 index 5b20b4d3f57d..000000000000 --- a/fs/xfs/xfs_dir_sf.h +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_DIR_SF_H__ | ||
19 | #define __XFS_DIR_SF_H__ | ||
20 | |||
21 | /* | ||
22 | * Directory layout when stored internal to an inode. | ||
23 | * | ||
24 | * Small directories are packed as tightly as possible so as to | ||
25 | * fit into the literal area of the inode. | ||
26 | */ | ||
27 | |||
28 | typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t; | ||
29 | |||
30 | /* | ||
31 | * The parent directory has a dedicated field, and the self-pointer must | ||
32 | * be calculated on the fly. | ||
33 | * | ||
34 | * Entries are packed toward the top as tight as possible. The header | ||
35 | * and the elements much be memcpy'd out into a work area to get correct | ||
36 | * alignment for the inode number fields. | ||
37 | */ | ||
38 | typedef struct xfs_dir_sf_hdr { /* constant-structure header block */ | ||
39 | xfs_dir_ino_t parent; /* parent dir inode number */ | ||
40 | __uint8_t count; /* count of active entries */ | ||
41 | } xfs_dir_sf_hdr_t; | ||
42 | |||
43 | typedef struct xfs_dir_sf_entry { | ||
44 | xfs_dir_ino_t inumber; /* referenced inode number */ | ||
45 | __uint8_t namelen; /* actual length of name (no NULL) */ | ||
46 | __uint8_t name[1]; /* name */ | ||
47 | } xfs_dir_sf_entry_t; | ||
48 | |||
49 | typedef struct xfs_dir_shortform { | ||
50 | xfs_dir_sf_hdr_t hdr; | ||
51 | xfs_dir_sf_entry_t list[1]; /* variable sized array */ | ||
52 | } xfs_dir_shortform_t; | ||
53 | |||
54 | /* | ||
55 | * We generate this then sort it, so that readdirs are returned in | ||
56 | * hash-order. Else seekdir won't work. | ||
57 | */ | ||
58 | typedef struct xfs_dir_sf_sort { | ||
59 | __uint8_t entno; /* .=0, ..=1, else entry# + 2 */ | ||
60 | __uint8_t seqno; /* sequence # with same hash value */ | ||
61 | __uint8_t namelen; /* length of name value (no null) */ | ||
62 | xfs_dahash_t hash; /* this entry's hash value */ | ||
63 | xfs_intino_t ino; /* this entry's inode number */ | ||
64 | char *name; /* name value, pointer into buffer */ | ||
65 | } xfs_dir_sf_sort_t; | ||
66 | |||
67 | #define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to) | ||
68 | static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to) | ||
69 | { | ||
70 | *(to) = XFS_GET_DIR_INO8(*from); | ||
71 | } | ||
72 | |||
73 | #define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to) | ||
74 | static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to) | ||
75 | { | ||
76 | XFS_PUT_DIR_INO8(*(from), *(to)); | ||
77 | } | ||
78 | |||
79 | #define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len) | ||
80 | static inline int xfs_dir_sf_entsize_byname(int len) | ||
81 | { | ||
82 | return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len); | ||
83 | } | ||
84 | |||
85 | #define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep) | ||
86 | static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep) | ||
87 | { | ||
88 | return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen; | ||
89 | } | ||
90 | |||
91 | #define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep) | ||
92 | static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep) | ||
93 | { | ||
94 | return (xfs_dir_sf_entry_t *) \ | ||
95 | ((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep)); | ||
96 | } | ||
97 | |||
98 | #define XFS_DIR_SF_ALLFIT(count,totallen) \ | ||
99 | xfs_dir_sf_allfit(count,totallen) | ||
100 | static inline int xfs_dir_sf_allfit(int count, int totallen) | ||
101 | { | ||
102 | return ((uint)sizeof(xfs_dir_sf_hdr_t) + \ | ||
103 | ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen)); | ||
104 | } | ||
105 | |||
106 | #if defined(XFS_DIR_TRACE) | ||
107 | |||
108 | /* | ||
109 | * Kernel tracing support for directories. | ||
110 | */ | ||
111 | struct uio; | ||
112 | struct xfs_inode; | ||
113 | struct xfs_da_intnode; | ||
114 | struct xfs_dinode; | ||
115 | struct xfs_dir_leafblock; | ||
116 | struct xfs_dir_leaf_entry; | ||
117 | |||
118 | #define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */ | ||
119 | extern ktrace_t *xfs_dir_trace_buf; | ||
120 | |||
121 | /* | ||
122 | * Trace record types. | ||
123 | */ | ||
124 | #define XFS_DIR_KTRACE_G_DU 1 /* dp, uio */ | ||
125 | #define XFS_DIR_KTRACE_G_DUB 2 /* dp, uio, bno */ | ||
126 | #define XFS_DIR_KTRACE_G_DUN 3 /* dp, uio, node */ | ||
127 | #define XFS_DIR_KTRACE_G_DUL 4 /* dp, uio, leaf */ | ||
128 | #define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */ | ||
129 | #define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */ | ||
130 | |||
131 | void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio); | ||
132 | void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio, | ||
133 | xfs_dablk_t bno); | ||
134 | void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio, | ||
135 | struct xfs_da_intnode *node); | ||
136 | void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio, | ||
137 | struct xfs_dir_leafblock *leaf); | ||
138 | void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio, | ||
139 | struct xfs_dir_leaf_entry *entry); | ||
140 | void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio, | ||
141 | xfs_off_t cookie); | ||
142 | void xfs_dir_trace_enter(int type, char *where, | ||
143 | void *a0, void *a1, void *a2, void *a3, | ||
144 | void *a4, void *a5, void *a6, void *a7, | ||
145 | void *a8, void *a9, void *a10, void *a11); | ||
146 | #else | ||
147 | #define xfs_dir_trace_g_du(w,d,u) | ||
148 | #define xfs_dir_trace_g_dub(w,d,u,b) | ||
149 | #define xfs_dir_trace_g_dun(w,d,u,n) | ||
150 | #define xfs_dir_trace_g_dul(w,d,u,l) | ||
151 | #define xfs_dir_trace_g_due(w,d,u,e) | ||
152 | #define xfs_dir_trace_g_duc(w,d,u,c) | ||
153 | #endif /* DEBUG */ | ||
154 | |||
155 | #endif /* __XFS_DIR_SF_H__ */ | ||
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h index 00b1540f8108..4e7865ad6f0e 100644 --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h | |||
@@ -189,6 +189,6 @@ typedef enum { | |||
189 | #define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) | 189 | #define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) |
190 | 190 | ||
191 | 191 | ||
192 | extern struct bhv_vfsops xfs_dmops; | 192 | extern struct bhv_module_vfsops xfs_dmops; |
193 | 193 | ||
194 | #endif /* __XFS_DMAPI_H__ */ | 194 | #endif /* __XFS_DMAPI_H__ */ |
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c index 629795b3b3d5..1e4a35ddf7f9 100644 --- a/fs/xfs/xfs_dmops.c +++ b/fs/xfs/xfs_dmops.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
29 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 2a21c5024017..b95681b03d81 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c | |||
@@ -22,12 +22,10 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
29 | #include "xfs_bmap_btree.h" | 28 | #include "xfs_bmap_btree.h" |
30 | #include "xfs_dir_sf.h" | ||
31 | #include "xfs_dir2_sf.h" | 29 | #include "xfs_dir2_sf.h" |
32 | #include "xfs_attr_sf.h" | 30 | #include "xfs_attr_sf.h" |
33 | #include "xfs_dinode.h" | 31 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index f19282ec8549..6cf6d8769b97 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_buf_item.h" | 24 | #include "xfs_buf_item.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
29 | #include "xfs_trans_priv.h" | 28 | #include "xfs_trans_priv.h" |
@@ -294,6 +293,62 @@ xfs_efi_init(xfs_mount_t *mp, | |||
294 | } | 293 | } |
295 | 294 | ||
296 | /* | 295 | /* |
296 | * Copy an EFI format buffer from the given buf, and into the destination | ||
297 | * EFI format structure. | ||
298 | * The given buffer can be in 32 bit or 64 bit form (which has different padding), | ||
299 | * one of which will be the native format for this kernel. | ||
300 | * It will handle the conversion of formats if necessary. | ||
301 | */ | ||
302 | int | ||
303 | xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt) | ||
304 | { | ||
305 | xfs_efi_log_format_t *src_efi_fmt = (xfs_efi_log_format_t *)buf->i_addr; | ||
306 | uint i; | ||
307 | uint len = sizeof(xfs_efi_log_format_t) + | ||
308 | (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t); | ||
309 | uint len32 = sizeof(xfs_efi_log_format_32_t) + | ||
310 | (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t); | ||
311 | uint len64 = sizeof(xfs_efi_log_format_64_t) + | ||
312 | (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t); | ||
313 | |||
314 | if (buf->i_len == len) { | ||
315 | memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len); | ||
316 | return 0; | ||
317 | } else if (buf->i_len == len32) { | ||
318 | xfs_efi_log_format_32_t *src_efi_fmt_32 = | ||
319 | (xfs_efi_log_format_32_t *)buf->i_addr; | ||
320 | |||
321 | dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type; | ||
322 | dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size; | ||
323 | dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents; | ||
324 | dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id; | ||
325 | for (i = 0; i < dst_efi_fmt->efi_nextents; i++) { | ||
326 | dst_efi_fmt->efi_extents[i].ext_start = | ||
327 | src_efi_fmt_32->efi_extents[i].ext_start; | ||
328 | dst_efi_fmt->efi_extents[i].ext_len = | ||
329 | src_efi_fmt_32->efi_extents[i].ext_len; | ||
330 | } | ||
331 | return 0; | ||
332 | } else if (buf->i_len == len64) { | ||
333 | xfs_efi_log_format_64_t *src_efi_fmt_64 = | ||
334 | (xfs_efi_log_format_64_t *)buf->i_addr; | ||
335 | |||
336 | dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type; | ||
337 | dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size; | ||
338 | dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents; | ||
339 | dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id; | ||
340 | for (i = 0; i < dst_efi_fmt->efi_nextents; i++) { | ||
341 | dst_efi_fmt->efi_extents[i].ext_start = | ||
342 | src_efi_fmt_64->efi_extents[i].ext_start; | ||
343 | dst_efi_fmt->efi_extents[i].ext_len = | ||
344 | src_efi_fmt_64->efi_extents[i].ext_len; | ||
345 | } | ||
346 | return 0; | ||
347 | } | ||
348 | return EFSCORRUPTED; | ||
349 | } | ||
350 | |||
351 | /* | ||
297 | * This is called by the efd item code below to release references to | 352 | * This is called by the efd item code below to release references to |
298 | * the given efi item. Each efd calls this with the number of | 353 | * the given efi item. Each efd calls this with the number of |
299 | * extents that it has logged, and when the sum of these reaches | 354 | * extents that it has logged, and when the sum of these reaches |
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h index 5bf681708fec..0ea45edaab03 100644 --- a/fs/xfs/xfs_extfree_item.h +++ b/fs/xfs/xfs_extfree_item.h | |||
@@ -27,6 +27,24 @@ typedef struct xfs_extent { | |||
27 | } xfs_extent_t; | 27 | } xfs_extent_t; |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * Since an xfs_extent_t has types (start:64, len: 32) | ||
31 | * there are different alignments on 32 bit and 64 bit kernels. | ||
32 | * So we provide the different variants for use by a | ||
33 | * conversion routine. | ||
34 | */ | ||
35 | |||
36 | typedef struct xfs_extent_32 { | ||
37 | xfs_dfsbno_t ext_start; | ||
38 | xfs_extlen_t ext_len; | ||
39 | } __attribute__((packed)) xfs_extent_32_t; | ||
40 | |||
41 | typedef struct xfs_extent_64 { | ||
42 | xfs_dfsbno_t ext_start; | ||
43 | xfs_extlen_t ext_len; | ||
44 | __uint32_t ext_pad; | ||
45 | } xfs_extent_64_t; | ||
46 | |||
47 | /* | ||
30 | * This is the structure used to lay out an efi log item in the | 48 | * This is the structure used to lay out an efi log item in the |
31 | * log. The efi_extents field is a variable size array whose | 49 | * log. The efi_extents field is a variable size array whose |
32 | * size is given by efi_nextents. | 50 | * size is given by efi_nextents. |
@@ -39,6 +57,22 @@ typedef struct xfs_efi_log_format { | |||
39 | xfs_extent_t efi_extents[1]; /* array of extents to free */ | 57 | xfs_extent_t efi_extents[1]; /* array of extents to free */ |
40 | } xfs_efi_log_format_t; | 58 | } xfs_efi_log_format_t; |
41 | 59 | ||
60 | typedef struct xfs_efi_log_format_32 { | ||
61 | unsigned short efi_type; /* efi log item type */ | ||
62 | unsigned short efi_size; /* size of this item */ | ||
63 | uint efi_nextents; /* # extents to free */ | ||
64 | __uint64_t efi_id; /* efi identifier */ | ||
65 | xfs_extent_32_t efi_extents[1]; /* array of extents to free */ | ||
66 | } __attribute__((packed)) xfs_efi_log_format_32_t; | ||
67 | |||
68 | typedef struct xfs_efi_log_format_64 { | ||
69 | unsigned short efi_type; /* efi log item type */ | ||
70 | unsigned short efi_size; /* size of this item */ | ||
71 | uint efi_nextents; /* # extents to free */ | ||
72 | __uint64_t efi_id; /* efi identifier */ | ||
73 | xfs_extent_64_t efi_extents[1]; /* array of extents to free */ | ||
74 | } xfs_efi_log_format_64_t; | ||
75 | |||
42 | /* | 76 | /* |
43 | * This is the structure used to lay out an efd log item in the | 77 | * This is the structure used to lay out an efd log item in the |
44 | * log. The efd_extents array is a variable size array whose | 78 | * log. The efd_extents array is a variable size array whose |
@@ -52,6 +86,22 @@ typedef struct xfs_efd_log_format { | |||
52 | xfs_extent_t efd_extents[1]; /* array of extents freed */ | 86 | xfs_extent_t efd_extents[1]; /* array of extents freed */ |
53 | } xfs_efd_log_format_t; | 87 | } xfs_efd_log_format_t; |
54 | 88 | ||
89 | typedef struct xfs_efd_log_format_32 { | ||
90 | unsigned short efd_type; /* efd log item type */ | ||
91 | unsigned short efd_size; /* size of this item */ | ||
92 | uint efd_nextents; /* # of extents freed */ | ||
93 | __uint64_t efd_efi_id; /* id of corresponding efi */ | ||
94 | xfs_extent_32_t efd_extents[1]; /* array of extents freed */ | ||
95 | } __attribute__((packed)) xfs_efd_log_format_32_t; | ||
96 | |||
97 | typedef struct xfs_efd_log_format_64 { | ||
98 | unsigned short efd_type; /* efd log item type */ | ||
99 | unsigned short efd_size; /* size of this item */ | ||
100 | uint efd_nextents; /* # of extents freed */ | ||
101 | __uint64_t efd_efi_id; /* id of corresponding efi */ | ||
102 | xfs_extent_64_t efd_extents[1]; /* array of extents freed */ | ||
103 | } xfs_efd_log_format_64_t; | ||
104 | |||
55 | 105 | ||
56 | #ifdef __KERNEL__ | 106 | #ifdef __KERNEL__ |
57 | 107 | ||
@@ -103,7 +153,8 @@ extern struct kmem_zone *xfs_efd_zone; | |||
103 | xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); | 153 | xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); |
104 | xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, | 154 | xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, |
105 | uint); | 155 | uint); |
106 | 156 | int xfs_efi_copy_format(xfs_log_iovec_t *buf, | |
157 | xfs_efi_log_format_t *dst_efi_fmt); | ||
107 | void xfs_efi_item_free(xfs_efi_log_item_t *); | 158 | void xfs_efi_item_free(xfs_efi_log_item_t *); |
108 | 159 | ||
109 | #endif /* __KERNEL__ */ | 160 | #endif /* __KERNEL__ */ |
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 14010f1fa82f..0f0ad1535951 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -67,14 +67,15 @@ struct fsxattr { | |||
67 | #define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ | 67 | #define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ |
68 | #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ | 68 | #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ |
69 | #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ | 69 | #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ |
70 | #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ | ||
70 | #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ | 71 | #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ |
71 | 72 | ||
72 | /* | 73 | /* |
73 | * Structure for XFS_IOC_GETBMAP. | 74 | * Structure for XFS_IOC_GETBMAP. |
74 | * On input, fill in bmv_offset and bmv_length of the first structure | 75 | * On input, fill in bmv_offset and bmv_length of the first structure |
75 | * to indicate the area of interest in the file, and bmv_entry with the | 76 | * to indicate the area of interest in the file, and bmv_entries with |
76 | * number of array elements given. The first structure is updated on | 77 | * the number of array elements given back. The first structure is |
77 | * return to give the offset and length for the next call. | 78 | * updated on return to give the offset and length for the next call. |
78 | */ | 79 | */ |
79 | #ifndef HAVE_GETBMAP | 80 | #ifndef HAVE_GETBMAP |
80 | struct getbmap { | 81 | struct getbmap { |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index dfa3527b20a7..077629bab532 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -542,14 +540,13 @@ xfs_reserve_blocks( | |||
542 | } | 540 | } |
543 | 541 | ||
544 | void | 542 | void |
545 | xfs_fs_log_dummy(xfs_mount_t *mp) | 543 | xfs_fs_log_dummy( |
544 | xfs_mount_t *mp) | ||
546 | { | 545 | { |
547 | xfs_trans_t *tp; | 546 | xfs_trans_t *tp; |
548 | xfs_inode_t *ip; | 547 | xfs_inode_t *ip; |
549 | |||
550 | 548 | ||
551 | tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); | 549 | tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); |
552 | atomic_inc(&mp->m_active_trans); | ||
553 | if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) { | 550 | if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) { |
554 | xfs_trans_cancel(tp, 0); | 551 | xfs_trans_cancel(tp, 0); |
555 | return; | 552 | return; |
@@ -574,21 +571,22 @@ xfs_fs_goingdown( | |||
574 | { | 571 | { |
575 | switch (inflags) { | 572 | switch (inflags) { |
576 | case XFS_FSOP_GOING_FLAGS_DEFAULT: { | 573 | case XFS_FSOP_GOING_FLAGS_DEFAULT: { |
577 | struct vfs *vfsp = XFS_MTOVFS(mp); | 574 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); |
578 | struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev); | 575 | struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev); |
579 | 576 | ||
580 | if (sb && !IS_ERR(sb)) { | 577 | if (sb && !IS_ERR(sb)) { |
581 | xfs_force_shutdown(mp, XFS_FORCE_UMOUNT); | 578 | xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT); |
582 | thaw_bdev(sb->s_bdev, sb); | 579 | thaw_bdev(sb->s_bdev, sb); |
583 | } | 580 | } |
584 | 581 | ||
585 | break; | 582 | break; |
586 | } | 583 | } |
587 | case XFS_FSOP_GOING_FLAGS_LOGFLUSH: | 584 | case XFS_FSOP_GOING_FLAGS_LOGFLUSH: |
588 | xfs_force_shutdown(mp, XFS_FORCE_UMOUNT); | 585 | xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT); |
589 | break; | 586 | break; |
590 | case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH: | 587 | case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH: |
591 | xfs_force_shutdown(mp, XFS_FORCE_UMOUNT|XFS_LOG_IO_ERROR); | 588 | xfs_force_shutdown(mp, |
589 | SHUTDOWN_FORCE_UMOUNT | SHUTDOWN_LOG_IO_ERROR); | ||
592 | break; | 590 | break; |
593 | default: | 591 | default: |
594 | return XFS_ERROR(EINVAL); | 592 | return XFS_ERROR(EINVAL); |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index deddbd03c166..33164a85aa9d 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -1174,6 +1172,9 @@ xfs_dilocate( | |||
1174 | if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || | 1172 | if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || |
1175 | ino != XFS_AGINO_TO_INO(mp, agno, agino)) { | 1173 | ino != XFS_AGINO_TO_INO(mp, agno, agino)) { |
1176 | #ifdef DEBUG | 1174 | #ifdef DEBUG |
1175 | /* no diagnostics for bulkstat, ino comes from userspace */ | ||
1176 | if (flags & XFS_IMAP_BULKSTAT) | ||
1177 | return XFS_ERROR(EINVAL); | ||
1177 | if (agno >= mp->m_sb.sb_agcount) { | 1178 | if (agno >= mp->m_sb.sb_agcount) { |
1178 | xfs_fs_cmn_err(CE_ALERT, mp, | 1179 | xfs_fs_cmn_err(CE_ALERT, mp, |
1179 | "xfs_dilocate: agno (%d) >= " | 1180 | "xfs_dilocate: agno (%d) >= " |
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index 60c65683462d..616eeeb6953e 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index b53854325266..0724df7fabb7 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -186,7 +184,7 @@ xfs_ihash_promote( | |||
186 | */ | 184 | */ |
187 | STATIC int | 185 | STATIC int |
188 | xfs_iget_core( | 186 | xfs_iget_core( |
189 | vnode_t *vp, | 187 | bhv_vnode_t *vp, |
190 | xfs_mount_t *mp, | 188 | xfs_mount_t *mp, |
191 | xfs_trans_t *tp, | 189 | xfs_trans_t *tp, |
192 | xfs_ino_t ino, | 190 | xfs_ino_t ino, |
@@ -198,7 +196,7 @@ xfs_iget_core( | |||
198 | xfs_ihash_t *ih; | 196 | xfs_ihash_t *ih; |
199 | xfs_inode_t *ip; | 197 | xfs_inode_t *ip; |
200 | xfs_inode_t *iq; | 198 | xfs_inode_t *iq; |
201 | vnode_t *inode_vp; | 199 | bhv_vnode_t *inode_vp; |
202 | ulong version; | 200 | ulong version; |
203 | int error; | 201 | int error; |
204 | /* REFERENCED */ | 202 | /* REFERENCED */ |
@@ -468,7 +466,7 @@ finish_inode: | |||
468 | * If we have a real type for an on-disk inode, we can set ops(&unlock) | 466 | * If we have a real type for an on-disk inode, we can set ops(&unlock) |
469 | * now. If it's a new inode being created, xfs_ialloc will handle it. | 467 | * now. If it's a new inode being created, xfs_ialloc will handle it. |
470 | */ | 468 | */ |
471 | VFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1); | 469 | bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1); |
472 | 470 | ||
473 | return 0; | 471 | return 0; |
474 | } | 472 | } |
@@ -489,7 +487,7 @@ xfs_iget( | |||
489 | xfs_daddr_t bno) | 487 | xfs_daddr_t bno) |
490 | { | 488 | { |
491 | struct inode *inode; | 489 | struct inode *inode; |
492 | vnode_t *vp = NULL; | 490 | bhv_vnode_t *vp = NULL; |
493 | int error; | 491 | int error; |
494 | 492 | ||
495 | XFS_STATS_INC(xs_ig_attempts); | 493 | XFS_STATS_INC(xs_ig_attempts); |
@@ -543,7 +541,7 @@ retry: | |||
543 | void | 541 | void |
544 | xfs_inode_lock_init( | 542 | xfs_inode_lock_init( |
545 | xfs_inode_t *ip, | 543 | xfs_inode_t *ip, |
546 | vnode_t *vp) | 544 | bhv_vnode_t *vp) |
547 | { | 545 | { |
548 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | 546 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, |
549 | "xfsino", (long)vp->v_number); | 547 | "xfsino", (long)vp->v_number); |
@@ -603,12 +601,10 @@ void | |||
603 | xfs_iput(xfs_inode_t *ip, | 601 | xfs_iput(xfs_inode_t *ip, |
604 | uint lock_flags) | 602 | uint lock_flags) |
605 | { | 603 | { |
606 | vnode_t *vp = XFS_ITOV(ip); | 604 | bhv_vnode_t *vp = XFS_ITOV(ip); |
607 | 605 | ||
608 | vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address); | 606 | vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address); |
609 | |||
610 | xfs_iunlock(ip, lock_flags); | 607 | xfs_iunlock(ip, lock_flags); |
611 | |||
612 | VN_RELE(vp); | 608 | VN_RELE(vp); |
613 | } | 609 | } |
614 | 610 | ||
@@ -619,7 +615,7 @@ void | |||
619 | xfs_iput_new(xfs_inode_t *ip, | 615 | xfs_iput_new(xfs_inode_t *ip, |
620 | uint lock_flags) | 616 | uint lock_flags) |
621 | { | 617 | { |
622 | vnode_t *vp = XFS_ITOV(ip); | 618 | bhv_vnode_t *vp = XFS_ITOV(ip); |
623 | struct inode *inode = vn_to_inode(vp); | 619 | struct inode *inode = vn_to_inode(vp); |
624 | 620 | ||
625 | vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); | 621 | vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); |
@@ -645,7 +641,7 @@ xfs_iput_new(xfs_inode_t *ip, | |||
645 | void | 641 | void |
646 | xfs_ireclaim(xfs_inode_t *ip) | 642 | xfs_ireclaim(xfs_inode_t *ip) |
647 | { | 643 | { |
648 | vnode_t *vp; | 644 | bhv_vnode_t *vp; |
649 | 645 | ||
650 | /* | 646 | /* |
651 | * Remove from old hash list and mount list. | 647 | * Remove from old hash list and mount list. |
@@ -1033,6 +1029,6 @@ xfs_iflock_nowait(xfs_inode_t *ip) | |||
1033 | void | 1029 | void |
1034 | xfs_ifunlock(xfs_inode_t *ip) | 1030 | xfs_ifunlock(xfs_inode_t *ip) |
1035 | { | 1031 | { |
1036 | ASSERT(valusema(&(ip->i_flock)) <= 0); | 1032 | ASSERT(issemalocked(&(ip->i_flock))); |
1037 | vsema(&(ip->i_flock)); | 1033 | vsema(&(ip->i_flock)); |
1038 | } | 1034 | } |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 94b60dd03801..5fa0adb7e173 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -26,14 +26,12 @@ | |||
26 | #include "xfs_trans_priv.h" | 26 | #include "xfs_trans_priv.h" |
27 | #include "xfs_sb.h" | 27 | #include "xfs_sb.h" |
28 | #include "xfs_ag.h" | 28 | #include "xfs_ag.h" |
29 | #include "xfs_dir.h" | ||
30 | #include "xfs_dir2.h" | 29 | #include "xfs_dir2.h" |
31 | #include "xfs_dmapi.h" | 30 | #include "xfs_dmapi.h" |
32 | #include "xfs_mount.h" | 31 | #include "xfs_mount.h" |
33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
36 | #include "xfs_dir_sf.h" | ||
37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
@@ -256,13 +254,11 @@ xfs_itobp( | |||
256 | xfs_daddr_t bno, | 254 | xfs_daddr_t bno, |
257 | uint imap_flags) | 255 | uint imap_flags) |
258 | { | 256 | { |
257 | xfs_imap_t imap; | ||
259 | xfs_buf_t *bp; | 258 | xfs_buf_t *bp; |
260 | int error; | 259 | int error; |
261 | xfs_imap_t imap; | ||
262 | #ifdef __KERNEL__ | ||
263 | int i; | 260 | int i; |
264 | int ni; | 261 | int ni; |
265 | #endif | ||
266 | 262 | ||
267 | if (ip->i_blkno == (xfs_daddr_t)0) { | 263 | if (ip->i_blkno == (xfs_daddr_t)0) { |
268 | /* | 264 | /* |
@@ -319,7 +315,6 @@ xfs_itobp( | |||
319 | */ | 315 | */ |
320 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno, | 316 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno, |
321 | (int)imap.im_len, XFS_BUF_LOCK, &bp); | 317 | (int)imap.im_len, XFS_BUF_LOCK, &bp); |
322 | |||
323 | if (error) { | 318 | if (error) { |
324 | #ifdef DEBUG | 319 | #ifdef DEBUG |
325 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: " | 320 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: " |
@@ -330,17 +325,21 @@ xfs_itobp( | |||
330 | #endif /* DEBUG */ | 325 | #endif /* DEBUG */ |
331 | return error; | 326 | return error; |
332 | } | 327 | } |
333 | #ifdef __KERNEL__ | 328 | |
334 | /* | 329 | /* |
335 | * Validate the magic number and version of every inode in the buffer | 330 | * Validate the magic number and version of every inode in the buffer |
336 | * (if DEBUG kernel) or the first inode in the buffer, otherwise. | 331 | * (if DEBUG kernel) or the first inode in the buffer, otherwise. |
332 | * No validation is done here in userspace (xfs_repair). | ||
337 | */ | 333 | */ |
338 | #ifdef DEBUG | 334 | #if !defined(__KERNEL__) |
335 | ni = 0; | ||
336 | #elif defined(DEBUG) | ||
339 | ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : | 337 | ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : |
340 | (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog); | 338 | (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog); |
341 | #else | 339 | #else /* usual case */ |
342 | ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1; | 340 | ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1; |
343 | #endif | 341 | #endif |
342 | |||
344 | for (i = 0; i < ni; i++) { | 343 | for (i = 0; i < ni; i++) { |
345 | int di_ok; | 344 | int di_ok; |
346 | xfs_dinode_t *dip; | 345 | xfs_dinode_t *dip; |
@@ -352,8 +351,11 @@ xfs_itobp( | |||
352 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, | 351 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, |
353 | XFS_RANDOM_ITOBP_INOTOBP))) { | 352 | XFS_RANDOM_ITOBP_INOTOBP))) { |
354 | #ifdef DEBUG | 353 | #ifdef DEBUG |
355 | prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)", | 354 | if (!(imap_flags & XFS_IMAP_BULKSTAT)) |
356 | mp->m_ddev_targp, | 355 | cmn_err(CE_ALERT, |
356 | "Device %s - bad inode magic/vsn " | ||
357 | "daddr %lld #%d (magic=%x)", | ||
358 | XFS_BUFTARG_NAME(mp->m_ddev_targp), | ||
357 | (unsigned long long)imap.im_blkno, i, | 359 | (unsigned long long)imap.im_blkno, i, |
358 | INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); | 360 | INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); |
359 | #endif | 361 | #endif |
@@ -363,7 +365,6 @@ xfs_itobp( | |||
363 | return XFS_ERROR(EFSCORRUPTED); | 365 | return XFS_ERROR(EFSCORRUPTED); |
364 | } | 366 | } |
365 | } | 367 | } |
366 | #endif /* __KERNEL__ */ | ||
367 | 368 | ||
368 | xfs_inobp_check(mp, bp); | 369 | xfs_inobp_check(mp, bp); |
369 | 370 | ||
@@ -782,7 +783,6 @@ xfs_xlate_dinode_core( | |||
782 | 783 | ||
783 | STATIC uint | 784 | STATIC uint |
784 | _xfs_dic2xflags( | 785 | _xfs_dic2xflags( |
785 | xfs_dinode_core_t *dic, | ||
786 | __uint16_t di_flags) | 786 | __uint16_t di_flags) |
787 | { | 787 | { |
788 | uint flags = 0; | 788 | uint flags = 0; |
@@ -812,6 +812,8 @@ _xfs_dic2xflags( | |||
812 | flags |= XFS_XFLAG_EXTSIZE; | 812 | flags |= XFS_XFLAG_EXTSIZE; |
813 | if (di_flags & XFS_DIFLAG_EXTSZINHERIT) | 813 | if (di_flags & XFS_DIFLAG_EXTSZINHERIT) |
814 | flags |= XFS_XFLAG_EXTSZINHERIT; | 814 | flags |= XFS_XFLAG_EXTSZINHERIT; |
815 | if (di_flags & XFS_DIFLAG_NODEFRAG) | ||
816 | flags |= XFS_XFLAG_NODEFRAG; | ||
815 | } | 817 | } |
816 | 818 | ||
817 | return flags; | 819 | return flags; |
@@ -823,16 +825,16 @@ xfs_ip2xflags( | |||
823 | { | 825 | { |
824 | xfs_dinode_core_t *dic = &ip->i_d; | 826 | xfs_dinode_core_t *dic = &ip->i_d; |
825 | 827 | ||
826 | return _xfs_dic2xflags(dic, dic->di_flags) | | 828 | return _xfs_dic2xflags(dic->di_flags) | |
827 | (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); | 829 | (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); |
828 | } | 830 | } |
829 | 831 | ||
830 | uint | 832 | uint |
831 | xfs_dic2xflags( | 833 | xfs_dic2xflags( |
832 | xfs_dinode_core_t *dic) | 834 | xfs_dinode_core_t *dic) |
833 | { | 835 | { |
834 | return _xfs_dic2xflags(dic, INT_GET(dic->di_flags, ARCH_CONVERT)) | | 836 | return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) | |
835 | (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); | 837 | (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); |
836 | } | 838 | } |
837 | 839 | ||
838 | /* | 840 | /* |
@@ -1083,7 +1085,7 @@ xfs_ialloc( | |||
1083 | { | 1085 | { |
1084 | xfs_ino_t ino; | 1086 | xfs_ino_t ino; |
1085 | xfs_inode_t *ip; | 1087 | xfs_inode_t *ip; |
1086 | vnode_t *vp; | 1088 | bhv_vnode_t *vp; |
1087 | uint flags; | 1089 | uint flags; |
1088 | int error; | 1090 | int error; |
1089 | 1091 | ||
@@ -1221,6 +1223,9 @@ xfs_ialloc( | |||
1221 | di_flags |= XFS_DIFLAG_NOSYMLINKS; | 1223 | di_flags |= XFS_DIFLAG_NOSYMLINKS; |
1222 | if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | 1224 | if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) |
1223 | di_flags |= XFS_DIFLAG_PROJINHERIT; | 1225 | di_flags |= XFS_DIFLAG_PROJINHERIT; |
1226 | if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) && | ||
1227 | xfs_inherit_nodefrag) | ||
1228 | di_flags |= XFS_DIFLAG_NODEFRAG; | ||
1224 | ip->i_d.di_flags |= di_flags; | 1229 | ip->i_d.di_flags |= di_flags; |
1225 | } | 1230 | } |
1226 | /* FALLTHROUGH */ | 1231 | /* FALLTHROUGH */ |
@@ -1244,8 +1249,8 @@ xfs_ialloc( | |||
1244 | */ | 1249 | */ |
1245 | xfs_trans_log_inode(tp, ip, flags); | 1250 | xfs_trans_log_inode(tp, ip, flags); |
1246 | 1251 | ||
1247 | /* now that we have an i_mode we can set Linux inode ops (& unlock) */ | 1252 | /* now that we have an i_mode we can setup inode ops and unlock */ |
1248 | VFS_INIT_VNODE(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1); | 1253 | bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1); |
1249 | 1254 | ||
1250 | *ipp = ip; | 1255 | *ipp = ip; |
1251 | return 0; | 1256 | return 0; |
@@ -1285,7 +1290,7 @@ xfs_isize_check( | |||
1285 | (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) - | 1290 | (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) - |
1286 | map_first), | 1291 | map_first), |
1287 | XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps, | 1292 | XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps, |
1288 | NULL)) | 1293 | NULL, NULL)) |
1289 | return; | 1294 | return; |
1290 | ASSERT(nimaps == 1); | 1295 | ASSERT(nimaps == 1); |
1291 | ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK); | 1296 | ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK); |
@@ -1421,7 +1426,7 @@ xfs_itruncate_start( | |||
1421 | xfs_fsize_t last_byte; | 1426 | xfs_fsize_t last_byte; |
1422 | xfs_off_t toss_start; | 1427 | xfs_off_t toss_start; |
1423 | xfs_mount_t *mp; | 1428 | xfs_mount_t *mp; |
1424 | vnode_t *vp; | 1429 | bhv_vnode_t *vp; |
1425 | 1430 | ||
1426 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); | 1431 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); |
1427 | ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); | 1432 | ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); |
@@ -1434,9 +1439,9 @@ xfs_itruncate_start( | |||
1434 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ | 1439 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ |
1435 | 1440 | ||
1436 | /* | 1441 | /* |
1437 | * Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers | 1442 | * Call toss_pages or flushinval_pages to get rid of pages |
1438 | * overlapping the region being removed. We have to use | 1443 | * overlapping the region being removed. We have to use |
1439 | * the less efficient VOP_FLUSHINVAL_PAGES() in the case that the | 1444 | * the less efficient flushinval_pages in the case that the |
1440 | * caller may not be able to finish the truncate without | 1445 | * caller may not be able to finish the truncate without |
1441 | * dropping the inode's I/O lock. Make sure | 1446 | * dropping the inode's I/O lock. Make sure |
1442 | * to catch any pages brought in by buffers overlapping | 1447 | * to catch any pages brought in by buffers overlapping |
@@ -1445,10 +1450,10 @@ xfs_itruncate_start( | |||
1445 | * so that we don't toss things on the same block as | 1450 | * so that we don't toss things on the same block as |
1446 | * new_size but before it. | 1451 | * new_size but before it. |
1447 | * | 1452 | * |
1448 | * Before calling VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES(), make sure to | 1453 | * Before calling toss_page or flushinval_pages, make sure to |
1449 | * call remapf() over the same region if the file is mapped. | 1454 | * call remapf() over the same region if the file is mapped. |
1450 | * This frees up mapped file references to the pages in the | 1455 | * This frees up mapped file references to the pages in the |
1451 | * given range and for the VOP_FLUSHINVAL_PAGES() case it ensures | 1456 | * given range and for the flushinval_pages case it ensures |
1452 | * that we get the latest mapped changes flushed out. | 1457 | * that we get the latest mapped changes flushed out. |
1453 | */ | 1458 | */ |
1454 | toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); | 1459 | toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); |
@@ -1466,9 +1471,9 @@ xfs_itruncate_start( | |||
1466 | last_byte); | 1471 | last_byte); |
1467 | if (last_byte > toss_start) { | 1472 | if (last_byte > toss_start) { |
1468 | if (flags & XFS_ITRUNC_DEFINITE) { | 1473 | if (flags & XFS_ITRUNC_DEFINITE) { |
1469 | VOP_TOSS_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED); | 1474 | bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); |
1470 | } else { | 1475 | } else { |
1471 | VOP_FLUSHINVAL_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED); | 1476 | bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); |
1472 | } | 1477 | } |
1473 | } | 1478 | } |
1474 | 1479 | ||
@@ -1666,12 +1671,13 @@ xfs_itruncate_finish( | |||
1666 | * runs. | 1671 | * runs. |
1667 | */ | 1672 | */ |
1668 | XFS_BMAP_INIT(&free_list, &first_block); | 1673 | XFS_BMAP_INIT(&free_list, &first_block); |
1669 | error = xfs_bunmapi(ntp, ip, first_unmap_block, | 1674 | error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore, |
1670 | unmap_len, | 1675 | first_unmap_block, unmap_len, |
1671 | XFS_BMAPI_AFLAG(fork) | | 1676 | XFS_BMAPI_AFLAG(fork) | |
1672 | (sync ? 0 : XFS_BMAPI_ASYNC), | 1677 | (sync ? 0 : XFS_BMAPI_ASYNC), |
1673 | XFS_ITRUNC_MAX_EXTENTS, | 1678 | XFS_ITRUNC_MAX_EXTENTS, |
1674 | &first_block, &free_list, &done); | 1679 | &first_block, &free_list, |
1680 | NULL, &done); | ||
1675 | if (error) { | 1681 | if (error) { |
1676 | /* | 1682 | /* |
1677 | * If the bunmapi call encounters an error, | 1683 | * If the bunmapi call encounters an error, |
@@ -2745,13 +2751,14 @@ xfs_iunpin( | |||
2745 | * the inode to become unpinned. | 2751 | * the inode to become unpinned. |
2746 | */ | 2752 | */ |
2747 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { | 2753 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { |
2748 | vnode_t *vp = XFS_ITOV_NULL(ip); | 2754 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); |
2749 | 2755 | ||
2750 | /* make sync come back and flush this inode */ | 2756 | /* make sync come back and flush this inode */ |
2751 | if (vp) { | 2757 | if (vp) { |
2752 | struct inode *inode = vn_to_inode(vp); | 2758 | struct inode *inode = vn_to_inode(vp); |
2753 | 2759 | ||
2754 | if (!(inode->i_state & I_NEW)) | 2760 | if (!(inode->i_state & |
2761 | (I_NEW|I_FREEING|I_CLEAR))) | ||
2755 | mark_inode_dirty_sync(inode); | 2762 | mark_inode_dirty_sync(inode); |
2756 | } | 2763 | } |
2757 | } | 2764 | } |
@@ -2916,13 +2923,6 @@ xfs_iflush_fork( | |||
2916 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); | 2923 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); |
2917 | memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); | 2924 | memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); |
2918 | } | 2925 | } |
2919 | if (whichfork == XFS_DATA_FORK) { | ||
2920 | if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) { | ||
2921 | XFS_ERROR_REPORT("xfs_iflush_fork", | ||
2922 | XFS_ERRLEVEL_LOW, mp); | ||
2923 | return XFS_ERROR(EFSCORRUPTED); | ||
2924 | } | ||
2925 | } | ||
2926 | break; | 2926 | break; |
2927 | 2927 | ||
2928 | case XFS_DINODE_FMT_EXTENTS: | 2928 | case XFS_DINODE_FMT_EXTENTS: |
@@ -3006,7 +3006,7 @@ xfs_iflush( | |||
3006 | XFS_STATS_INC(xs_iflush_count); | 3006 | XFS_STATS_INC(xs_iflush_count); |
3007 | 3007 | ||
3008 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); | 3008 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); |
3009 | ASSERT(valusema(&ip->i_flock) <= 0); | 3009 | ASSERT(issemalocked(&(ip->i_flock))); |
3010 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 3010 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
3011 | ip->i_d.di_nextents > ip->i_df.if_ext_max); | 3011 | ip->i_d.di_nextents > ip->i_df.if_ext_max); |
3012 | 3012 | ||
@@ -3199,7 +3199,7 @@ xfs_iflush( | |||
3199 | 3199 | ||
3200 | corrupt_out: | 3200 | corrupt_out: |
3201 | xfs_buf_relse(bp); | 3201 | xfs_buf_relse(bp); |
3202 | xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); | 3202 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
3203 | xfs_iflush_abort(ip); | 3203 | xfs_iflush_abort(ip); |
3204 | /* | 3204 | /* |
3205 | * Unlocks the flush lock | 3205 | * Unlocks the flush lock |
@@ -3221,7 +3221,7 @@ cluster_corrupt_out: | |||
3221 | xfs_buf_relse(bp); | 3221 | xfs_buf_relse(bp); |
3222 | } | 3222 | } |
3223 | 3223 | ||
3224 | xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); | 3224 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
3225 | 3225 | ||
3226 | if(!bufwasdelwri) { | 3226 | if(!bufwasdelwri) { |
3227 | /* | 3227 | /* |
@@ -3264,7 +3264,7 @@ xfs_iflush_int( | |||
3264 | SPLDECL(s); | 3264 | SPLDECL(s); |
3265 | 3265 | ||
3266 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); | 3266 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); |
3267 | ASSERT(valusema(&ip->i_flock) <= 0); | 3267 | ASSERT(issemalocked(&(ip->i_flock))); |
3268 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 3268 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
3269 | ip->i_d.di_nextents > ip->i_df.if_ext_max); | 3269 | ip->i_d.di_nextents > ip->i_df.if_ext_max); |
3270 | 3270 | ||
@@ -3504,7 +3504,7 @@ xfs_iflush_all( | |||
3504 | xfs_mount_t *mp) | 3504 | xfs_mount_t *mp) |
3505 | { | 3505 | { |
3506 | xfs_inode_t *ip; | 3506 | xfs_inode_t *ip; |
3507 | vnode_t *vp; | 3507 | bhv_vnode_t *vp; |
3508 | 3508 | ||
3509 | again: | 3509 | again: |
3510 | XFS_MOUNT_ILOCK(mp); | 3510 | XFS_MOUNT_ILOCK(mp); |
@@ -4180,7 +4180,7 @@ xfs_iext_direct_to_inline( | |||
4180 | */ | 4180 | */ |
4181 | memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, | 4181 | memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, |
4182 | nextents * sizeof(xfs_bmbt_rec_t)); | 4182 | nextents * sizeof(xfs_bmbt_rec_t)); |
4183 | kmem_free(ifp->if_u1.if_extents, KM_SLEEP); | 4183 | kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes); |
4184 | ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; | 4184 | ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; |
4185 | ifp->if_real_bytes = 0; | 4185 | ifp->if_real_bytes = 0; |
4186 | } | 4186 | } |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 3b544db1790b..d10b76ed1e5b 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -102,9 +102,9 @@ typedef struct xfs_ifork { | |||
102 | 102 | ||
103 | #ifdef __KERNEL__ | 103 | #ifdef __KERNEL__ |
104 | struct bhv_desc; | 104 | struct bhv_desc; |
105 | struct bhv_vnode; | ||
105 | struct cred; | 106 | struct cred; |
106 | struct ktrace; | 107 | struct ktrace; |
107 | struct vnode; | ||
108 | struct xfs_buf; | 108 | struct xfs_buf; |
109 | struct xfs_bmap_free; | 109 | struct xfs_bmap_free; |
110 | struct xfs_bmbt_irec; | 110 | struct xfs_bmbt_irec; |
@@ -400,7 +400,7 @@ void xfs_chash_init(struct xfs_mount *); | |||
400 | void xfs_chash_free(struct xfs_mount *); | 400 | void xfs_chash_free(struct xfs_mount *); |
401 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, | 401 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, |
402 | struct xfs_trans *); | 402 | struct xfs_trans *); |
403 | void xfs_inode_lock_init(xfs_inode_t *, struct vnode *); | 403 | void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *); |
404 | int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 404 | int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, |
405 | uint, uint, xfs_inode_t **, xfs_daddr_t); | 405 | uint, uint, xfs_inode_t **, xfs_daddr_t); |
406 | void xfs_iput(xfs_inode_t *, uint); | 406 | void xfs_iput(xfs_inode_t *, uint); |
@@ -461,7 +461,7 @@ void xfs_ichgtime(xfs_inode_t *, int); | |||
461 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); | 461 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); |
462 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); | 462 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); |
463 | 463 | ||
464 | xfs_inode_t *xfs_vtoi(struct vnode *vp); | 464 | xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp); |
465 | 465 | ||
466 | void xfs_synchronize_atime(xfs_inode_t *); | 466 | void xfs_synchronize_atime(xfs_inode_t *); |
467 | 467 | ||
@@ -509,7 +509,6 @@ extern struct kmem_zone *xfs_chashlist_zone; | |||
509 | extern struct kmem_zone *xfs_ifork_zone; | 509 | extern struct kmem_zone *xfs_ifork_zone; |
510 | extern struct kmem_zone *xfs_inode_zone; | 510 | extern struct kmem_zone *xfs_inode_zone; |
511 | extern struct kmem_zone *xfs_ili_zone; | 511 | extern struct kmem_zone *xfs_ili_zone; |
512 | extern struct vnodeops xfs_vnodeops; | ||
513 | 512 | ||
514 | #endif /* __KERNEL__ */ | 513 | #endif /* __KERNEL__ */ |
515 | 514 | ||
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 7497a481b2f5..f8e80d8e7237 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include "xfs_buf_item.h" | 25 | #include "xfs_buf_item.h" |
26 | #include "xfs_sb.h" | 26 | #include "xfs_sb.h" |
27 | #include "xfs_ag.h" | 27 | #include "xfs_ag.h" |
28 | #include "xfs_dir.h" | ||
29 | #include "xfs_dir2.h" | 28 | #include "xfs_dir2.h" |
30 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
31 | #include "xfs_mount.h" | 30 | #include "xfs_mount.h" |
@@ -33,7 +32,6 @@ | |||
33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
36 | #include "xfs_dir_sf.h" | ||
37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
@@ -794,7 +792,7 @@ xfs_inode_item_pushbuf( | |||
794 | * inode flush completed and the inode was taken off the AIL. | 792 | * inode flush completed and the inode was taken off the AIL. |
795 | * So, just get out. | 793 | * So, just get out. |
796 | */ | 794 | */ |
797 | if ((valusema(&(ip->i_flock)) > 0) || | 795 | if (!issemalocked(&(ip->i_flock)) || |
798 | ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) { | 796 | ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) { |
799 | iip->ili_pushbuf_flag = 0; | 797 | iip->ili_pushbuf_flag = 0; |
800 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 798 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
@@ -816,7 +814,7 @@ xfs_inode_item_pushbuf( | |||
816 | * If not, we can flush it async. | 814 | * If not, we can flush it async. |
817 | */ | 815 | */ |
818 | dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) && | 816 | dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) && |
819 | (valusema(&(ip->i_flock)) <= 0)); | 817 | issemalocked(&(ip->i_flock))); |
820 | iip->ili_pushbuf_flag = 0; | 818 | iip->ili_pushbuf_flag = 0; |
821 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 819 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
822 | xfs_buftrace("INODE ITEM PUSH", bp); | 820 | xfs_buftrace("INODE ITEM PUSH", bp); |
@@ -864,7 +862,7 @@ xfs_inode_item_push( | |||
864 | ip = iip->ili_inode; | 862 | ip = iip->ili_inode; |
865 | 863 | ||
866 | ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS)); | 864 | ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS)); |
867 | ASSERT(valusema(&(ip->i_flock)) <= 0); | 865 | ASSERT(issemalocked(&(ip->i_flock))); |
868 | /* | 866 | /* |
869 | * Since we were able to lock the inode's flush lock and | 867 | * Since we were able to lock the inode's flush lock and |
870 | * we found it on the AIL, the inode must be dirty. This | 868 | * we found it on the AIL, the inode must be dirty. This |
@@ -1084,3 +1082,52 @@ xfs_istale_done( | |||
1084 | { | 1082 | { |
1085 | xfs_iflush_abort(iip->ili_inode); | 1083 | xfs_iflush_abort(iip->ili_inode); |
1086 | } | 1084 | } |
1085 | |||
1086 | /* | ||
1087 | * convert an xfs_inode_log_format struct from either 32 or 64 bit versions | ||
1088 | * (which can have different field alignments) to the native version | ||
1089 | */ | ||
1090 | int | ||
1091 | xfs_inode_item_format_convert( | ||
1092 | xfs_log_iovec_t *buf, | ||
1093 | xfs_inode_log_format_t *in_f) | ||
1094 | { | ||
1095 | if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) { | ||
1096 | xfs_inode_log_format_32_t *in_f32; | ||
1097 | |||
1098 | in_f32 = (xfs_inode_log_format_32_t *)buf->i_addr; | ||
1099 | in_f->ilf_type = in_f32->ilf_type; | ||
1100 | in_f->ilf_size = in_f32->ilf_size; | ||
1101 | in_f->ilf_fields = in_f32->ilf_fields; | ||
1102 | in_f->ilf_asize = in_f32->ilf_asize; | ||
1103 | in_f->ilf_dsize = in_f32->ilf_dsize; | ||
1104 | in_f->ilf_ino = in_f32->ilf_ino; | ||
1105 | /* copy biggest field of ilf_u */ | ||
1106 | memcpy(in_f->ilf_u.ilfu_uuid.__u_bits, | ||
1107 | in_f32->ilf_u.ilfu_uuid.__u_bits, | ||
1108 | sizeof(uuid_t)); | ||
1109 | in_f->ilf_blkno = in_f32->ilf_blkno; | ||
1110 | in_f->ilf_len = in_f32->ilf_len; | ||
1111 | in_f->ilf_boffset = in_f32->ilf_boffset; | ||
1112 | return 0; | ||
1113 | } else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){ | ||
1114 | xfs_inode_log_format_64_t *in_f64; | ||
1115 | |||
1116 | in_f64 = (xfs_inode_log_format_64_t *)buf->i_addr; | ||
1117 | in_f->ilf_type = in_f64->ilf_type; | ||
1118 | in_f->ilf_size = in_f64->ilf_size; | ||
1119 | in_f->ilf_fields = in_f64->ilf_fields; | ||
1120 | in_f->ilf_asize = in_f64->ilf_asize; | ||
1121 | in_f->ilf_dsize = in_f64->ilf_dsize; | ||
1122 | in_f->ilf_ino = in_f64->ilf_ino; | ||
1123 | /* copy biggest field of ilf_u */ | ||
1124 | memcpy(in_f->ilf_u.ilfu_uuid.__u_bits, | ||
1125 | in_f64->ilf_u.ilfu_uuid.__u_bits, | ||
1126 | sizeof(uuid_t)); | ||
1127 | in_f->ilf_blkno = in_f64->ilf_blkno; | ||
1128 | in_f->ilf_len = in_f64->ilf_len; | ||
1129 | in_f->ilf_boffset = in_f64->ilf_boffset; | ||
1130 | return 0; | ||
1131 | } | ||
1132 | return EFSCORRUPTED; | ||
1133 | } | ||
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index c5dbf93b6661..5db6cd1b4cf3 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h | |||
@@ -23,25 +23,6 @@ | |||
23 | * log. The size of the inline data/extents/b-tree root to be logged | 23 | * log. The size of the inline data/extents/b-tree root to be logged |
24 | * (if any) is indicated in the ilf_dsize field. Changes to this structure | 24 | * (if any) is indicated in the ilf_dsize field. Changes to this structure |
25 | * must be added on to the end. | 25 | * must be added on to the end. |
26 | * | ||
27 | * Convention for naming inode log item versions : The current version | ||
28 | * is always named XFS_LI_INODE. When an inode log item gets superseded, | ||
29 | * add the latest version of IRIX that will generate logs with that item | ||
30 | * to the version name. | ||
31 | * | ||
32 | * -Version 1 of this structure (XFS_LI_5_3_INODE) included up to the first | ||
33 | * union (ilf_u) field. This was released with IRIX 5.3-XFS. | ||
34 | * -Version 2 of this structure (XFS_LI_6_1_INODE) is currently the entire | ||
35 | * structure. This was released with IRIX 6.0.1-XFS and IRIX 6.1. | ||
36 | * -Version 3 of this structure (XFS_LI_INODE) is the same as version 2 | ||
37 | * so a new structure definition wasn't necessary. However, we had | ||
38 | * to add a new type because the inode cluster size changed from 4K | ||
39 | * to 8K and the version number had to be rev'ved to keep older kernels | ||
40 | * from trying to recover logs with the 8K buffers in them. The logging | ||
41 | * code can handle recovery on different-sized clusters now so hopefully | ||
42 | * this'll be the last time we need to change the inode log item just | ||
43 | * for a change in the inode cluster size. This new version was | ||
44 | * released with IRIX 6.2. | ||
45 | */ | 26 | */ |
46 | typedef struct xfs_inode_log_format { | 27 | typedef struct xfs_inode_log_format { |
47 | unsigned short ilf_type; /* inode log item type */ | 28 | unsigned short ilf_type; /* inode log item type */ |
@@ -59,18 +40,38 @@ typedef struct xfs_inode_log_format { | |||
59 | int ilf_boffset; /* off of inode in buffer */ | 40 | int ilf_boffset; /* off of inode in buffer */ |
60 | } xfs_inode_log_format_t; | 41 | } xfs_inode_log_format_t; |
61 | 42 | ||
62 | /* Initial version shipped with IRIX 5.3-XFS */ | 43 | typedef struct xfs_inode_log_format_32 { |
63 | typedef struct xfs_inode_log_format_v1 { | 44 | unsigned short ilf_type; /* 16: inode log item type */ |
64 | unsigned short ilf_type; /* inode log item type */ | 45 | unsigned short ilf_size; /* 16: size of this item */ |
65 | unsigned short ilf_size; /* size of this item */ | 46 | uint ilf_fields; /* 32: flags for fields logged */ |
66 | uint ilf_fields; /* flags for fields logged */ | 47 | ushort ilf_asize; /* 32: size of attr d/ext/root */ |
67 | uint ilf_dsize; /* size of data/ext/root */ | 48 | ushort ilf_dsize; /* 32: size of data/ext/root */ |
68 | xfs_ino_t ilf_ino; /* inode number */ | 49 | xfs_ino_t ilf_ino; /* 64: inode number */ |
69 | union { | 50 | union { |
70 | xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/ | 51 | xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/ |
71 | uuid_t ilfu_uuid; /* mount point value */ | 52 | uuid_t ilfu_uuid; /* 128: mount point value */ |
53 | } ilf_u; | ||
54 | __int64_t ilf_blkno; /* 64: blkno of inode buffer */ | ||
55 | int ilf_len; /* 32: len of inode buffer */ | ||
56 | int ilf_boffset; /* 32: off of inode in buffer */ | ||
57 | } __attribute__((packed)) xfs_inode_log_format_32_t; | ||
58 | |||
59 | typedef struct xfs_inode_log_format_64 { | ||
60 | unsigned short ilf_type; /* 16: inode log item type */ | ||
61 | unsigned short ilf_size; /* 16: size of this item */ | ||
62 | uint ilf_fields; /* 32: flags for fields logged */ | ||
63 | ushort ilf_asize; /* 32: size of attr d/ext/root */ | ||
64 | ushort ilf_dsize; /* 32: size of data/ext/root */ | ||
65 | __uint32_t ilf_pad; /* 32: pad for 64 bit boundary */ | ||
66 | xfs_ino_t ilf_ino; /* 64: inode number */ | ||
67 | union { | ||
68 | xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/ | ||
69 | uuid_t ilfu_uuid; /* 128: mount point value */ | ||
72 | } ilf_u; | 70 | } ilf_u; |
73 | } xfs_inode_log_format_t_v1; | 71 | __int64_t ilf_blkno; /* 64: blkno of inode buffer */ |
72 | int ilf_len; /* 32: len of inode buffer */ | ||
73 | int ilf_boffset; /* 32: off of inode in buffer */ | ||
74 | } xfs_inode_log_format_64_t; | ||
74 | 75 | ||
75 | /* | 76 | /* |
76 | * Flags for xfs_trans_log_inode flags field. | 77 | * Flags for xfs_trans_log_inode flags field. |
@@ -172,6 +173,8 @@ extern void xfs_inode_item_destroy(struct xfs_inode *); | |||
172 | extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *); | 173 | extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *); |
173 | extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *); | 174 | extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *); |
174 | extern void xfs_iflush_abort(struct xfs_inode *); | 175 | extern void xfs_iflush_abort(struct xfs_inode *); |
176 | extern int xfs_inode_item_format_convert(xfs_log_iovec_t *, | ||
177 | xfs_inode_log_format_t *); | ||
175 | 178 | ||
176 | #endif /* __KERNEL__ */ | 179 | #endif /* __KERNEL__ */ |
177 | 180 | ||
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c index a07815661a8c..06d710c9ce4b 100644 --- a/fs/xfs/xfs_iocore.c +++ b/fs/xfs/xfs_iocore.c | |||
@@ -24,14 +24,13 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
28 | #include "xfs_dfrag.h" | ||
29 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 30 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -58,7 +57,7 @@ xfs_size_fn( | |||
58 | 57 | ||
59 | STATIC int | 58 | STATIC int |
60 | xfs_ioinit( | 59 | xfs_ioinit( |
61 | struct vfs *vfsp, | 60 | struct bhv_vfs *vfsp, |
62 | struct xfs_mount_args *mntargs, | 61 | struct xfs_mount_args *mntargs, |
63 | int flags) | 62 | int flags) |
64 | { | 63 | { |
@@ -68,6 +67,7 @@ xfs_ioinit( | |||
68 | xfs_ioops_t xfs_iocore_xfs = { | 67 | xfs_ioops_t xfs_iocore_xfs = { |
69 | .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit, | 68 | .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit, |
70 | .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi, | 69 | .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi, |
70 | .xfs_bunmapi_func = (xfs_bunmapi_t) xfs_bunmapi, | ||
71 | .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof, | 71 | .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof, |
72 | .xfs_iomap_write_direct = | 72 | .xfs_iomap_write_direct = |
73 | (xfs_iomap_write_direct_t) xfs_iomap_write_direct, | 73 | (xfs_iomap_write_direct_t) xfs_iomap_write_direct, |
@@ -84,6 +84,7 @@ xfs_ioops_t xfs_iocore_xfs = { | |||
84 | .xfs_unlock = (xfs_unlk_t) xfs_iunlock, | 84 | .xfs_unlock = (xfs_unlk_t) xfs_iunlock, |
85 | .xfs_size_func = (xfs_size_t) xfs_size_fn, | 85 | .xfs_size_func = (xfs_size_t) xfs_size_fn, |
86 | .xfs_iodone = (xfs_iodone_t) fs_noerr, | 86 | .xfs_iodone = (xfs_iodone_t) fs_noerr, |
87 | .xfs_swap_extents_func = (xfs_swap_extents_t) xfs_swap_extents, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | void | 90 | void |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index d5dfedcb8922..f1949c16df15 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -252,7 +250,7 @@ xfs_iomap( | |||
252 | error = XFS_BMAPI(mp, NULL, io, offset_fsb, | 250 | error = XFS_BMAPI(mp, NULL, io, offset_fsb, |
253 | (xfs_filblks_t)(end_fsb - offset_fsb), | 251 | (xfs_filblks_t)(end_fsb - offset_fsb), |
254 | bmapi_flags, NULL, 0, &imap, | 252 | bmapi_flags, NULL, 0, &imap, |
255 | &nimaps, NULL); | 253 | &nimaps, NULL, NULL); |
256 | 254 | ||
257 | if (error) | 255 | if (error) |
258 | goto out; | 256 | goto out; |
@@ -519,8 +517,8 @@ xfs_iomap_write_direct( | |||
519 | */ | 517 | */ |
520 | XFS_BMAP_INIT(&free_list, &firstfsb); | 518 | XFS_BMAP_INIT(&free_list, &firstfsb); |
521 | nimaps = 1; | 519 | nimaps = 1; |
522 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, | 520 | error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag, |
523 | bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list); | 521 | &firstfsb, 0, &imap, &nimaps, &free_list, NULL); |
524 | if (error) | 522 | if (error) |
525 | goto error0; | 523 | goto error0; |
526 | 524 | ||
@@ -610,8 +608,8 @@ xfs_iomap_eof_want_preallocate( | |||
610 | while (count_fsb > 0) { | 608 | while (count_fsb > 0) { |
611 | imaps = nimaps; | 609 | imaps = nimaps; |
612 | firstblock = NULLFSBLOCK; | 610 | firstblock = NULLFSBLOCK; |
613 | error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, | 611 | error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0, |
614 | 0, &firstblock, 0, imap, &imaps, NULL); | 612 | &firstblock, 0, imap, &imaps, NULL, NULL); |
615 | if (error) | 613 | if (error) |
616 | return error; | 614 | return error; |
617 | for (n = 0; n < imaps; n++) { | 615 | for (n = 0; n < imaps; n++) { |
@@ -695,11 +693,11 @@ retry: | |||
695 | 693 | ||
696 | nimaps = XFS_WRITE_IMAPS; | 694 | nimaps = XFS_WRITE_IMAPS; |
697 | firstblock = NULLFSBLOCK; | 695 | firstblock = NULLFSBLOCK; |
698 | error = xfs_bmapi(NULL, ip, offset_fsb, | 696 | error = XFS_BMAPI(mp, NULL, io, offset_fsb, |
699 | (xfs_filblks_t)(last_fsb - offset_fsb), | 697 | (xfs_filblks_t)(last_fsb - offset_fsb), |
700 | XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | | 698 | XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | |
701 | XFS_BMAPI_ENTIRE, &firstblock, 1, imap, | 699 | XFS_BMAPI_ENTIRE, &firstblock, 1, imap, |
702 | &nimaps, NULL); | 700 | &nimaps, NULL, NULL); |
703 | if (error && (error != ENOSPC)) | 701 | if (error && (error != ENOSPC)) |
704 | return XFS_ERROR(error); | 702 | return XFS_ERROR(error); |
705 | 703 | ||
@@ -832,9 +830,9 @@ xfs_iomap_write_allocate( | |||
832 | } | 830 | } |
833 | 831 | ||
834 | /* Go get the actual blocks */ | 832 | /* Go get the actual blocks */ |
835 | error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, | 833 | error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb, |
836 | XFS_BMAPI_WRITE, &first_block, 1, | 834 | XFS_BMAPI_WRITE, &first_block, 1, |
837 | imap, &nimaps, &free_list); | 835 | imap, &nimaps, &free_list, NULL); |
838 | if (error) | 836 | if (error) |
839 | goto trans_cancel; | 837 | goto trans_cancel; |
840 | 838 | ||
@@ -955,9 +953,9 @@ xfs_iomap_write_unwritten( | |||
955 | */ | 953 | */ |
956 | XFS_BMAP_INIT(&free_list, &firstfsb); | 954 | XFS_BMAP_INIT(&free_list, &firstfsb); |
957 | nimaps = 1; | 955 | nimaps = 1; |
958 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, | 956 | error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, |
959 | XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, | 957 | XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, |
960 | 1, &imap, &nimaps, &free_list); | 958 | 1, &imap, &nimaps, &free_list, NULL); |
961 | if (error) | 959 | if (error) |
962 | goto error_on_bmapi_transaction; | 960 | goto error_on_bmapi_transaction; |
963 | 961 | ||
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 94068d014f27..46249e4d1fea 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -41,11 +39,6 @@ | |||
41 | #include "xfs_error.h" | 39 | #include "xfs_error.h" |
42 | #include "xfs_btree.h" | 40 | #include "xfs_btree.h" |
43 | 41 | ||
44 | #ifndef HAVE_USERACC | ||
45 | #define useracc(ubuffer, size, flags, foo) (0) | ||
46 | #define unuseracc(ubuffer, size, flags) | ||
47 | #endif | ||
48 | |||
49 | STATIC int | 42 | STATIC int |
50 | xfs_bulkstat_one_iget( | 43 | xfs_bulkstat_one_iget( |
51 | xfs_mount_t *mp, /* mount point for filesystem */ | 44 | xfs_mount_t *mp, /* mount point for filesystem */ |
@@ -56,7 +49,7 @@ xfs_bulkstat_one_iget( | |||
56 | { | 49 | { |
57 | xfs_dinode_core_t *dic; /* dinode core info pointer */ | 50 | xfs_dinode_core_t *dic; /* dinode core info pointer */ |
58 | xfs_inode_t *ip; /* incore inode pointer */ | 51 | xfs_inode_t *ip; /* incore inode pointer */ |
59 | vnode_t *vp; | 52 | bhv_vnode_t *vp; |
60 | int error; | 53 | int error; |
61 | 54 | ||
62 | error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); | 55 | error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); |
@@ -336,15 +329,6 @@ xfs_bulkstat( | |||
336 | nimask = ~(nicluster - 1); | 329 | nimask = ~(nicluster - 1); |
337 | nbcluster = nicluster >> mp->m_sb.sb_inopblog; | 330 | nbcluster = nicluster >> mp->m_sb.sb_inopblog; |
338 | /* | 331 | /* |
339 | * Lock down the user's buffer. If a buffer was not sent, as in the case | ||
340 | * disk quota code calls here, we skip this. | ||
341 | */ | ||
342 | if (ubuffer && | ||
343 | (error = useracc(ubuffer, ubcount * statstruct_size, | ||
344 | (B_READ|B_PHYS), NULL))) { | ||
345 | return error; | ||
346 | } | ||
347 | /* | ||
348 | * Allocate a page-sized buffer for inode btree records. | 332 | * Allocate a page-sized buffer for inode btree records. |
349 | * We could try allocating something smaller, but for normal | 333 | * We could try allocating something smaller, but for normal |
350 | * calls we'll always (potentially) need the whole page. | 334 | * calls we'll always (potentially) need the whole page. |
@@ -650,8 +634,6 @@ xfs_bulkstat( | |||
650 | * Done, we're either out of filesystem or space to put the data. | 634 | * Done, we're either out of filesystem or space to put the data. |
651 | */ | 635 | */ |
652 | kmem_free(irbuf, NBPC); | 636 | kmem_free(irbuf, NBPC); |
653 | if (ubuffer) | ||
654 | unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS)); | ||
655 | *ubcountp = ubelem; | 637 | *ubcountp = ubelem; |
656 | if (agno >= mp->m_sb.sb_agcount) { | 638 | if (agno >= mp->m_sb.sb_agcount) { |
657 | /* | 639 | /* |
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h index 11eb4e1b18c4..be5f12e07d22 100644 --- a/fs/xfs/xfs_itable.h +++ b/fs/xfs/xfs_itable.h | |||
@@ -45,7 +45,6 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp, | |||
45 | */ | 45 | */ |
46 | #define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */ | 46 | #define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */ |
47 | #define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ | 47 | #define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ |
48 | #define BULKSTAT_FG_VFSLOCKED 0x4 /* Already have vfs lock */ | ||
49 | 48 | ||
50 | /* | 49 | /* |
51 | * Return stat information in bulk (by-inode) for the filesystem. | 50 | * Return stat information in bulk (by-inode) for the filesystem. |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 32e841d2f26d..d8f5d4cbe8b7 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
@@ -36,7 +35,6 @@ | |||
36 | #include "xfs_ialloc_btree.h" | 35 | #include "xfs_ialloc_btree.h" |
37 | #include "xfs_log_recover.h" | 36 | #include "xfs_log_recover.h" |
38 | #include "xfs_trans_priv.h" | 37 | #include "xfs_trans_priv.h" |
39 | #include "xfs_dir_sf.h" | ||
40 | #include "xfs_dir2_sf.h" | 38 | #include "xfs_dir2_sf.h" |
41 | #include "xfs_attr_sf.h" | 39 | #include "xfs_attr_sf.h" |
42 | #include "xfs_dinode.h" | 40 | #include "xfs_dinode.h" |
@@ -402,7 +400,7 @@ xfs_log_release_iclog(xfs_mount_t *mp, | |||
402 | xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; | 400 | xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; |
403 | 401 | ||
404 | if (xlog_state_release_iclog(log, iclog)) { | 402 | if (xlog_state_release_iclog(log, iclog)) { |
405 | xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); | 403 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); |
406 | return EIO; | 404 | return EIO; |
407 | } | 405 | } |
408 | 406 | ||
@@ -498,9 +496,8 @@ xfs_log_mount(xfs_mount_t *mp, | |||
498 | * just worked. | 496 | * just worked. |
499 | */ | 497 | */ |
500 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { | 498 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { |
501 | int error; | 499 | bhv_vfs_t *vfsp = XFS_MTOVFS(mp); |
502 | vfs_t *vfsp = XFS_MTOVFS(mp); | 500 | int error, readonly = (vfsp->vfs_flag & VFS_RDONLY); |
503 | int readonly = (vfsp->vfs_flag & VFS_RDONLY); | ||
504 | 501 | ||
505 | if (readonly) | 502 | if (readonly) |
506 | vfsp->vfs_flag &= ~VFS_RDONLY; | 503 | vfsp->vfs_flag &= ~VFS_RDONLY; |
@@ -726,7 +723,7 @@ xfs_log_write(xfs_mount_t * mp, | |||
726 | return XFS_ERROR(EIO); | 723 | return XFS_ERROR(EIO); |
727 | 724 | ||
728 | if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) { | 725 | if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) { |
729 | xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); | 726 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); |
730 | } | 727 | } |
731 | return error; | 728 | return error; |
732 | } /* xfs_log_write */ | 729 | } /* xfs_log_write */ |
@@ -816,9 +813,9 @@ xfs_log_need_covered(xfs_mount_t *mp) | |||
816 | SPLDECL(s); | 813 | SPLDECL(s); |
817 | int needed = 0, gen; | 814 | int needed = 0, gen; |
818 | xlog_t *log = mp->m_log; | 815 | xlog_t *log = mp->m_log; |
819 | vfs_t *vfsp = XFS_MTOVFS(mp); | 816 | bhv_vfs_t *vfsp = XFS_MTOVFS(mp); |
820 | 817 | ||
821 | if (fs_frozen(vfsp) || XFS_FORCED_SHUTDOWN(mp) || | 818 | if (vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) || |
822 | (vfsp->vfs_flag & VFS_RDONLY)) | 819 | (vfsp->vfs_flag & VFS_RDONLY)) |
823 | return 0; | 820 | return 0; |
824 | 821 | ||
@@ -956,7 +953,7 @@ xlog_iodone(xfs_buf_t *bp) | |||
956 | XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { | 953 | XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { |
957 | xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp)); | 954 | xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp)); |
958 | XFS_BUF_STALE(bp); | 955 | XFS_BUF_STALE(bp); |
959 | xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR); | 956 | xfs_force_shutdown(l->l_mp, SHUTDOWN_LOG_IO_ERROR); |
960 | /* | 957 | /* |
961 | * This flag will be propagated to the trans-committed | 958 | * This flag will be propagated to the trans-committed |
962 | * callback routines to let them know that the log-commit | 959 | * callback routines to let them know that the log-commit |
@@ -1261,7 +1258,7 @@ xlog_commit_record(xfs_mount_t *mp, | |||
1261 | ASSERT_ALWAYS(iclog); | 1258 | ASSERT_ALWAYS(iclog); |
1262 | if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, | 1259 | if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, |
1263 | iclog, XLOG_COMMIT_TRANS))) { | 1260 | iclog, XLOG_COMMIT_TRANS))) { |
1264 | xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); | 1261 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); |
1265 | } | 1262 | } |
1266 | return error; | 1263 | return error; |
1267 | } /* xlog_commit_record */ | 1264 | } /* xlog_commit_record */ |
@@ -1790,7 +1787,7 @@ xlog_write(xfs_mount_t * mp, | |||
1790 | xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp, | 1787 | xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp, |
1791 | "xfs_log_write: reservation ran out. Need to up reservation"); | 1788 | "xfs_log_write: reservation ran out. Need to up reservation"); |
1792 | /* If we did not panic, shutdown the filesystem */ | 1789 | /* If we did not panic, shutdown the filesystem */ |
1793 | xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); | 1790 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
1794 | #endif | 1791 | #endif |
1795 | } else | 1792 | } else |
1796 | ticket->t_curr_res -= len; | 1793 | ticket->t_curr_res -= len; |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1f0016b0b4ec..55b4237c2153 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -193,14 +191,14 @@ xlog_header_check_dump( | |||
193 | { | 191 | { |
194 | int b; | 192 | int b; |
195 | 193 | ||
196 | printk("%s: SB : uuid = ", __FUNCTION__); | 194 | cmn_err(CE_DEBUG, "%s: SB : uuid = ", __FUNCTION__); |
197 | for (b = 0; b < 16; b++) | 195 | for (b = 0; b < 16; b++) |
198 | printk("%02x",((unsigned char *)&mp->m_sb.sb_uuid)[b]); | 196 | cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]); |
199 | printk(", fmt = %d\n", XLOG_FMT); | 197 | cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT); |
200 | printk(" log : uuid = "); | 198 | cmn_err(CE_DEBUG, " log : uuid = "); |
201 | for (b = 0; b < 16; b++) | 199 | for (b = 0; b < 16; b++) |
202 | printk("%02x",((unsigned char *)&head->h_fs_uuid)[b]); | 200 | cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]); |
203 | printk(", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT)); | 201 | cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT)); |
204 | } | 202 | } |
205 | #else | 203 | #else |
206 | #define xlog_header_check_dump(mp, head) | 204 | #define xlog_header_check_dump(mp, head) |
@@ -282,7 +280,7 @@ xlog_recover_iodone( | |||
282 | mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *); | 280 | mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *); |
283 | xfs_ioerror_alert("xlog_recover_iodone", | 281 | xfs_ioerror_alert("xlog_recover_iodone", |
284 | mp, bp, XFS_BUF_ADDR(bp)); | 282 | mp, bp, XFS_BUF_ADDR(bp)); |
285 | xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); | 283 | xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); |
286 | } | 284 | } |
287 | XFS_BUF_SET_FSPRIVATE(bp, NULL); | 285 | XFS_BUF_SET_FSPRIVATE(bp, NULL); |
288 | XFS_BUF_CLR_IODONE_FUNC(bp); | 286 | XFS_BUF_CLR_IODONE_FUNC(bp); |
@@ -1889,7 +1887,7 @@ xlog_recover_do_inode_buffer( | |||
1889 | 1887 | ||
1890 | buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp, | 1888 | buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp, |
1891 | next_unlinked_offset); | 1889 | next_unlinked_offset); |
1892 | INT_SET(*buffer_nextp, ARCH_CONVERT, *logged_nextp); | 1890 | *buffer_nextp = *logged_nextp; |
1893 | } | 1891 | } |
1894 | 1892 | ||
1895 | return 0; | 1893 | return 0; |
@@ -2292,12 +2290,22 @@ xlog_recover_do_inode_trans( | |||
2292 | int attr_index; | 2290 | int attr_index; |
2293 | uint fields; | 2291 | uint fields; |
2294 | xfs_dinode_core_t *dicp; | 2292 | xfs_dinode_core_t *dicp; |
2293 | int need_free = 0; | ||
2295 | 2294 | ||
2296 | if (pass == XLOG_RECOVER_PASS1) { | 2295 | if (pass == XLOG_RECOVER_PASS1) { |
2297 | return 0; | 2296 | return 0; |
2298 | } | 2297 | } |
2299 | 2298 | ||
2300 | in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr; | 2299 | if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) { |
2300 | in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr; | ||
2301 | } else { | ||
2302 | in_f = (xfs_inode_log_format_t *)kmem_alloc( | ||
2303 | sizeof(xfs_inode_log_format_t), KM_SLEEP); | ||
2304 | need_free = 1; | ||
2305 | error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f); | ||
2306 | if (error) | ||
2307 | goto error; | ||
2308 | } | ||
2301 | ino = in_f->ilf_ino; | 2309 | ino = in_f->ilf_ino; |
2302 | mp = log->l_mp; | 2310 | mp = log->l_mp; |
2303 | if (ITEM_TYPE(item) == XFS_LI_INODE) { | 2311 | if (ITEM_TYPE(item) == XFS_LI_INODE) { |
@@ -2323,8 +2331,10 @@ xlog_recover_do_inode_trans( | |||
2323 | * Inode buffers can be freed, look out for it, | 2331 | * Inode buffers can be freed, look out for it, |
2324 | * and do not replay the inode. | 2332 | * and do not replay the inode. |
2325 | */ | 2333 | */ |
2326 | if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) | 2334 | if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) { |
2327 | return 0; | 2335 | error = 0; |
2336 | goto error; | ||
2337 | } | ||
2328 | 2338 | ||
2329 | bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len, | 2339 | bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len, |
2330 | XFS_BUF_LOCK); | 2340 | XFS_BUF_LOCK); |
@@ -2333,7 +2343,7 @@ xlog_recover_do_inode_trans( | |||
2333 | bp, imap.im_blkno); | 2343 | bp, imap.im_blkno); |
2334 | error = XFS_BUF_GETERROR(bp); | 2344 | error = XFS_BUF_GETERROR(bp); |
2335 | xfs_buf_relse(bp); | 2345 | xfs_buf_relse(bp); |
2336 | return error; | 2346 | goto error; |
2337 | } | 2347 | } |
2338 | error = 0; | 2348 | error = 0; |
2339 | ASSERT(in_f->ilf_fields & XFS_ILOG_CORE); | 2349 | ASSERT(in_f->ilf_fields & XFS_ILOG_CORE); |
@@ -2350,7 +2360,8 @@ xlog_recover_do_inode_trans( | |||
2350 | dip, bp, ino); | 2360 | dip, bp, ino); |
2351 | XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)", | 2361 | XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)", |
2352 | XFS_ERRLEVEL_LOW, mp); | 2362 | XFS_ERRLEVEL_LOW, mp); |
2353 | return XFS_ERROR(EFSCORRUPTED); | 2363 | error = EFSCORRUPTED; |
2364 | goto error; | ||
2354 | } | 2365 | } |
2355 | dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr); | 2366 | dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr); |
2356 | if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { | 2367 | if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { |
@@ -2360,7 +2371,8 @@ xlog_recover_do_inode_trans( | |||
2360 | item, ino); | 2371 | item, ino); |
2361 | XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)", | 2372 | XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)", |
2362 | XFS_ERRLEVEL_LOW, mp); | 2373 | XFS_ERRLEVEL_LOW, mp); |
2363 | return XFS_ERROR(EFSCORRUPTED); | 2374 | error = EFSCORRUPTED; |
2375 | goto error; | ||
2364 | } | 2376 | } |
2365 | 2377 | ||
2366 | /* Skip replay when the on disk inode is newer than the log one */ | 2378 | /* Skip replay when the on disk inode is newer than the log one */ |
@@ -2376,7 +2388,8 @@ xlog_recover_do_inode_trans( | |||
2376 | /* do nothing */ | 2388 | /* do nothing */ |
2377 | } else { | 2389 | } else { |
2378 | xfs_buf_relse(bp); | 2390 | xfs_buf_relse(bp); |
2379 | return 0; | 2391 | error = 0; |
2392 | goto error; | ||
2380 | } | 2393 | } |
2381 | } | 2394 | } |
2382 | /* Take the opportunity to reset the flush iteration count */ | 2395 | /* Take the opportunity to reset the flush iteration count */ |
@@ -2391,7 +2404,8 @@ xlog_recover_do_inode_trans( | |||
2391 | xfs_fs_cmn_err(CE_ALERT, mp, | 2404 | xfs_fs_cmn_err(CE_ALERT, mp, |
2392 | "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", | 2405 | "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", |
2393 | item, dip, bp, ino); | 2406 | item, dip, bp, ino); |
2394 | return XFS_ERROR(EFSCORRUPTED); | 2407 | error = EFSCORRUPTED; |
2408 | goto error; | ||
2395 | } | 2409 | } |
2396 | } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) { | 2410 | } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) { |
2397 | if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && | 2411 | if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && |
@@ -2403,7 +2417,8 @@ xlog_recover_do_inode_trans( | |||
2403 | xfs_fs_cmn_err(CE_ALERT, mp, | 2417 | xfs_fs_cmn_err(CE_ALERT, mp, |
2404 | "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", | 2418 | "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", |
2405 | item, dip, bp, ino); | 2419 | item, dip, bp, ino); |
2406 | return XFS_ERROR(EFSCORRUPTED); | 2420 | error = EFSCORRUPTED; |
2421 | goto error; | ||
2407 | } | 2422 | } |
2408 | } | 2423 | } |
2409 | if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){ | 2424 | if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){ |
@@ -2415,7 +2430,8 @@ xlog_recover_do_inode_trans( | |||
2415 | item, dip, bp, ino, | 2430 | item, dip, bp, ino, |
2416 | dicp->di_nextents + dicp->di_anextents, | 2431 | dicp->di_nextents + dicp->di_anextents, |
2417 | dicp->di_nblocks); | 2432 | dicp->di_nblocks); |
2418 | return XFS_ERROR(EFSCORRUPTED); | 2433 | error = EFSCORRUPTED; |
2434 | goto error; | ||
2419 | } | 2435 | } |
2420 | if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) { | 2436 | if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) { |
2421 | XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)", | 2437 | XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)", |
@@ -2424,7 +2440,8 @@ xlog_recover_do_inode_trans( | |||
2424 | xfs_fs_cmn_err(CE_ALERT, mp, | 2440 | xfs_fs_cmn_err(CE_ALERT, mp, |
2425 | "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x", | 2441 | "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x", |
2426 | item, dip, bp, ino, dicp->di_forkoff); | 2442 | item, dip, bp, ino, dicp->di_forkoff); |
2427 | return XFS_ERROR(EFSCORRUPTED); | 2443 | error = EFSCORRUPTED; |
2444 | goto error; | ||
2428 | } | 2445 | } |
2429 | if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) { | 2446 | if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) { |
2430 | XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)", | 2447 | XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)", |
@@ -2433,7 +2450,8 @@ xlog_recover_do_inode_trans( | |||
2433 | xfs_fs_cmn_err(CE_ALERT, mp, | 2450 | xfs_fs_cmn_err(CE_ALERT, mp, |
2434 | "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p", | 2451 | "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p", |
2435 | item->ri_buf[1].i_len, item); | 2452 | item->ri_buf[1].i_len, item); |
2436 | return XFS_ERROR(EFSCORRUPTED); | 2453 | error = EFSCORRUPTED; |
2454 | goto error; | ||
2437 | } | 2455 | } |
2438 | 2456 | ||
2439 | /* The core is in in-core format */ | 2457 | /* The core is in in-core format */ |
@@ -2521,7 +2539,8 @@ xlog_recover_do_inode_trans( | |||
2521 | xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag"); | 2539 | xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag"); |
2522 | ASSERT(0); | 2540 | ASSERT(0); |
2523 | xfs_buf_relse(bp); | 2541 | xfs_buf_relse(bp); |
2524 | return XFS_ERROR(EIO); | 2542 | error = EIO; |
2543 | goto error; | ||
2525 | } | 2544 | } |
2526 | } | 2545 | } |
2527 | 2546 | ||
@@ -2537,7 +2556,10 @@ write_inode_buffer: | |||
2537 | error = xfs_bwrite(mp, bp); | 2556 | error = xfs_bwrite(mp, bp); |
2538 | } | 2557 | } |
2539 | 2558 | ||
2540 | return (error); | 2559 | error: |
2560 | if (need_free) | ||
2561 | kmem_free(in_f, sizeof(*in_f)); | ||
2562 | return XFS_ERROR(error); | ||
2541 | } | 2563 | } |
2542 | 2564 | ||
2543 | /* | 2565 | /* |
@@ -2674,32 +2696,32 @@ xlog_recover_do_dquot_trans( | |||
2674 | * structure into it, and adds the efi to the AIL with the given | 2696 | * structure into it, and adds the efi to the AIL with the given |
2675 | * LSN. | 2697 | * LSN. |
2676 | */ | 2698 | */ |
2677 | STATIC void | 2699 | STATIC int |
2678 | xlog_recover_do_efi_trans( | 2700 | xlog_recover_do_efi_trans( |
2679 | xlog_t *log, | 2701 | xlog_t *log, |
2680 | xlog_recover_item_t *item, | 2702 | xlog_recover_item_t *item, |
2681 | xfs_lsn_t lsn, | 2703 | xfs_lsn_t lsn, |
2682 | int pass) | 2704 | int pass) |
2683 | { | 2705 | { |
2706 | int error; | ||
2684 | xfs_mount_t *mp; | 2707 | xfs_mount_t *mp; |
2685 | xfs_efi_log_item_t *efip; | 2708 | xfs_efi_log_item_t *efip; |
2686 | xfs_efi_log_format_t *efi_formatp; | 2709 | xfs_efi_log_format_t *efi_formatp; |
2687 | SPLDECL(s); | 2710 | SPLDECL(s); |
2688 | 2711 | ||
2689 | if (pass == XLOG_RECOVER_PASS1) { | 2712 | if (pass == XLOG_RECOVER_PASS1) { |
2690 | return; | 2713 | return 0; |
2691 | } | 2714 | } |
2692 | 2715 | ||
2693 | efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr; | 2716 | efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr; |
2694 | ASSERT(item->ri_buf[0].i_len == | ||
2695 | (sizeof(xfs_efi_log_format_t) + | ||
2696 | ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t)))); | ||
2697 | 2717 | ||
2698 | mp = log->l_mp; | 2718 | mp = log->l_mp; |
2699 | efip = xfs_efi_init(mp, efi_formatp->efi_nextents); | 2719 | efip = xfs_efi_init(mp, efi_formatp->efi_nextents); |
2700 | memcpy((char *)&(efip->efi_format), (char *)efi_formatp, | 2720 | if ((error = xfs_efi_copy_format(&(item->ri_buf[0]), |
2701 | sizeof(xfs_efi_log_format_t) + | 2721 | &(efip->efi_format)))) { |
2702 | ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))); | 2722 | xfs_efi_item_free(efip); |
2723 | return error; | ||
2724 | } | ||
2703 | efip->efi_next_extent = efi_formatp->efi_nextents; | 2725 | efip->efi_next_extent = efi_formatp->efi_nextents; |
2704 | efip->efi_flags |= XFS_EFI_COMMITTED; | 2726 | efip->efi_flags |= XFS_EFI_COMMITTED; |
2705 | 2727 | ||
@@ -2708,6 +2730,7 @@ xlog_recover_do_efi_trans( | |||
2708 | * xfs_trans_update_ail() drops the AIL lock. | 2730 | * xfs_trans_update_ail() drops the AIL lock. |
2709 | */ | 2731 | */ |
2710 | xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s); | 2732 | xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s); |
2733 | return 0; | ||
2711 | } | 2734 | } |
2712 | 2735 | ||
2713 | 2736 | ||
@@ -2738,9 +2761,10 @@ xlog_recover_do_efd_trans( | |||
2738 | } | 2761 | } |
2739 | 2762 | ||
2740 | efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr; | 2763 | efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr; |
2741 | ASSERT(item->ri_buf[0].i_len == | 2764 | ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) + |
2742 | (sizeof(xfs_efd_log_format_t) + | 2765 | ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) || |
2743 | ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_t)))); | 2766 | (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) + |
2767 | ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t))))); | ||
2744 | efi_id = efd_formatp->efd_efi_id; | 2768 | efi_id = efd_formatp->efd_efi_id; |
2745 | 2769 | ||
2746 | /* | 2770 | /* |
@@ -2810,15 +2834,14 @@ xlog_recover_do_trans( | |||
2810 | if ((error = xlog_recover_do_buffer_trans(log, item, | 2834 | if ((error = xlog_recover_do_buffer_trans(log, item, |
2811 | pass))) | 2835 | pass))) |
2812 | break; | 2836 | break; |
2813 | } else if ((ITEM_TYPE(item) == XFS_LI_INODE) || | 2837 | } else if ((ITEM_TYPE(item) == XFS_LI_INODE)) { |
2814 | (ITEM_TYPE(item) == XFS_LI_6_1_INODE) || | ||
2815 | (ITEM_TYPE(item) == XFS_LI_5_3_INODE)) { | ||
2816 | if ((error = xlog_recover_do_inode_trans(log, item, | 2838 | if ((error = xlog_recover_do_inode_trans(log, item, |
2817 | pass))) | 2839 | pass))) |
2818 | break; | 2840 | break; |
2819 | } else if (ITEM_TYPE(item) == XFS_LI_EFI) { | 2841 | } else if (ITEM_TYPE(item) == XFS_LI_EFI) { |
2820 | xlog_recover_do_efi_trans(log, item, trans->r_lsn, | 2842 | if ((error = xlog_recover_do_efi_trans(log, item, trans->r_lsn, |
2821 | pass); | 2843 | pass))) |
2844 | break; | ||
2822 | } else if (ITEM_TYPE(item) == XFS_LI_EFD) { | 2845 | } else if (ITEM_TYPE(item) == XFS_LI_EFD) { |
2823 | xlog_recover_do_efd_trans(log, item, pass); | 2846 | xlog_recover_do_efd_trans(log, item, pass); |
2824 | } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) { | 2847 | } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) { |
@@ -3419,13 +3442,13 @@ xlog_unpack_data_checksum( | |||
3419 | if (rhead->h_chksum || | 3442 | if (rhead->h_chksum || |
3420 | ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) { | 3443 | ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) { |
3421 | cmn_err(CE_DEBUG, | 3444 | cmn_err(CE_DEBUG, |
3422 | "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)", | 3445 | "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n", |
3423 | INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum); | 3446 | INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum); |
3424 | cmn_err(CE_DEBUG, | 3447 | cmn_err(CE_DEBUG, |
3425 | "XFS: Disregard message if filesystem was created with non-DEBUG kernel"); | 3448 | "XFS: Disregard message if filesystem was created with non-DEBUG kernel"); |
3426 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3449 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { |
3427 | cmn_err(CE_DEBUG, | 3450 | cmn_err(CE_DEBUG, |
3428 | "XFS: LogR this is a LogV2 filesystem"); | 3451 | "XFS: LogR this is a LogV2 filesystem\n"); |
3429 | } | 3452 | } |
3430 | log->l_flags |= XLOG_CHKSUM_MISMATCH; | 3453 | log->l_flags |= XLOG_CHKSUM_MISMATCH; |
3431 | } | 3454 | } |
@@ -3798,7 +3821,7 @@ xlog_do_log_recovery( | |||
3798 | error = xlog_do_recovery_pass(log, head_blk, tail_blk, | 3821 | error = xlog_do_recovery_pass(log, head_blk, tail_blk, |
3799 | XLOG_RECOVER_PASS2); | 3822 | XLOG_RECOVER_PASS2); |
3800 | #ifdef DEBUG | 3823 | #ifdef DEBUG |
3801 | { | 3824 | if (!error) { |
3802 | int i; | 3825 | int i; |
3803 | 3826 | ||
3804 | for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) | 3827 | for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) |
@@ -3974,7 +3997,7 @@ xlog_recover_finish( | |||
3974 | log->l_flags &= ~XLOG_RECOVERY_NEEDED; | 3997 | log->l_flags &= ~XLOG_RECOVERY_NEEDED; |
3975 | } else { | 3998 | } else { |
3976 | cmn_err(CE_DEBUG, | 3999 | cmn_err(CE_DEBUG, |
3977 | "!Ending clean XFS mount for filesystem: %s", | 4000 | "!Ending clean XFS mount for filesystem: %s\n", |
3978 | log->l_mp->m_fsname); | 4001 | log->l_mp->m_fsname); |
3979 | } | 4002 | } |
3980 | return 0; | 4003 | return 0; |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index c0b1c2906880..10dbf203c62f 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -196,7 +194,7 @@ xfs_mount_free( | |||
196 | kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); | 194 | kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); |
197 | 195 | ||
198 | if (remove_bhv) { | 196 | if (remove_bhv) { |
199 | struct vfs *vfsp = XFS_MTOVFS(mp); | 197 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); |
200 | 198 | ||
201 | bhv_remove_all_vfsops(vfsp, 0); | 199 | bhv_remove_all_vfsops(vfsp, 0); |
202 | VFS_REMOVEBHV(vfsp, &mp->m_bhv); | 200 | VFS_REMOVEBHV(vfsp, &mp->m_bhv); |
@@ -337,7 +335,7 @@ xfs_mount_validate_sb( | |||
337 | 335 | ||
338 | xfs_agnumber_t | 336 | xfs_agnumber_t |
339 | xfs_initialize_perag( | 337 | xfs_initialize_perag( |
340 | struct vfs *vfs, | 338 | bhv_vfs_t *vfs, |
341 | xfs_mount_t *mp, | 339 | xfs_mount_t *mp, |
342 | xfs_agnumber_t agcount) | 340 | xfs_agnumber_t agcount) |
343 | { | 341 | { |
@@ -651,14 +649,14 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) | |||
651 | */ | 649 | */ |
652 | int | 650 | int |
653 | xfs_mountfs( | 651 | xfs_mountfs( |
654 | vfs_t *vfsp, | 652 | bhv_vfs_t *vfsp, |
655 | xfs_mount_t *mp, | 653 | xfs_mount_t *mp, |
656 | int mfsi_flags) | 654 | int mfsi_flags) |
657 | { | 655 | { |
658 | xfs_buf_t *bp; | 656 | xfs_buf_t *bp; |
659 | xfs_sb_t *sbp = &(mp->m_sb); | 657 | xfs_sb_t *sbp = &(mp->m_sb); |
660 | xfs_inode_t *rip; | 658 | xfs_inode_t *rip; |
661 | vnode_t *rvp = NULL; | 659 | bhv_vnode_t *rvp = NULL; |
662 | int readio_log, writeio_log; | 660 | int readio_log, writeio_log; |
663 | xfs_daddr_t d; | 661 | xfs_daddr_t d; |
664 | __uint64_t ret64; | 662 | __uint64_t ret64; |
@@ -934,18 +932,7 @@ xfs_mountfs( | |||
934 | vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid; | 932 | vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid; |
935 | mp->m_dmevmask = 0; /* not persistent; set after each mount */ | 933 | mp->m_dmevmask = 0; /* not persistent; set after each mount */ |
936 | 934 | ||
937 | /* | 935 | xfs_dir_mount(mp); |
938 | * Select the right directory manager. | ||
939 | */ | ||
940 | mp->m_dirops = | ||
941 | XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ? | ||
942 | xfsv2_dirops : | ||
943 | xfsv1_dirops; | ||
944 | |||
945 | /* | ||
946 | * Initialize directory manager's entries. | ||
947 | */ | ||
948 | XFS_DIR_MOUNT(mp); | ||
949 | 936 | ||
950 | /* | 937 | /* |
951 | * Initialize the attribute manager's entries. | 938 | * Initialize the attribute manager's entries. |
@@ -1006,8 +993,9 @@ xfs_mountfs( | |||
1006 | 993 | ||
1007 | if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { | 994 | if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { |
1008 | cmn_err(CE_WARN, "XFS: corrupted root inode"); | 995 | cmn_err(CE_WARN, "XFS: corrupted root inode"); |
1009 | prdev("Root inode %llu is not a directory", | 996 | cmn_err(CE_WARN, "Device %s - root %llu is not a directory", |
1010 | mp->m_ddev_targp, (unsigned long long)rip->i_ino); | 997 | XFS_BUFTARG_NAME(mp->m_ddev_targp), |
998 | (unsigned long long)rip->i_ino); | ||
1011 | xfs_iunlock(rip, XFS_ILOCK_EXCL); | 999 | xfs_iunlock(rip, XFS_ILOCK_EXCL); |
1012 | XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, | 1000 | XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, |
1013 | mp); | 1001 | mp); |
@@ -1094,7 +1082,7 @@ xfs_mountfs( | |||
1094 | int | 1082 | int |
1095 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | 1083 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) |
1096 | { | 1084 | { |
1097 | struct vfs *vfsp = XFS_MTOVFS(mp); | 1085 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); |
1098 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) | 1086 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) |
1099 | int64_t fsid; | 1087 | int64_t fsid; |
1100 | #endif | 1088 | #endif |
@@ -1254,6 +1242,26 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) | |||
1254 | 1242 | ||
1255 | xfs_trans_log_buf(tp, bp, first, last); | 1243 | xfs_trans_log_buf(tp, bp, first, last); |
1256 | } | 1244 | } |
1245 | |||
1246 | /* | ||
1247 | * In order to avoid ENOSPC-related deadlock caused by | ||
1248 | * out-of-order locking of AGF buffer (PV 947395), we place | ||
1249 | * constraints on the relationship among actual allocations for | ||
1250 | * data blocks, freelist blocks, and potential file data bmap | ||
1251 | * btree blocks. However, these restrictions may result in no | ||
1252 | * actual space allocated for a delayed extent, for example, a data | ||
1253 | * block in a certain AG is allocated but there is no additional | ||
1254 | * block for the additional bmap btree block due to a split of the | ||
1255 | * bmap btree of the file. The result of this may lead to an | ||
1256 | * infinite loop in xfssyncd when the file gets flushed to disk and | ||
1257 | * all delayed extents need to be actually allocated. To get around | ||
1258 | * this, we explicitly set aside a few blocks which will not be | ||
1259 | * reserved in delayed allocation. Considering the minimum number of | ||
1260 | * needed freelist blocks is 4 fsbs, a potential split of file's bmap | ||
1261 | * btree requires 1 fsb, so we set the number of set-aside blocks to 8. | ||
1262 | */ | ||
1263 | #define SET_ASIDE_BLOCKS 8 | ||
1264 | |||
1257 | /* | 1265 | /* |
1258 | * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply | 1266 | * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply |
1259 | * a delta to a specified field in the in-core superblock. Simply | 1267 | * a delta to a specified field in the in-core superblock. Simply |
@@ -1298,7 +1306,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field, | |||
1298 | return 0; | 1306 | return 0; |
1299 | case XFS_SBS_FDBLOCKS: | 1307 | case XFS_SBS_FDBLOCKS: |
1300 | 1308 | ||
1301 | lcounter = (long long)mp->m_sb.sb_fdblocks; | 1309 | lcounter = (long long)mp->m_sb.sb_fdblocks - SET_ASIDE_BLOCKS; |
1302 | res_used = (long long)(mp->m_resblks - mp->m_resblks_avail); | 1310 | res_used = (long long)(mp->m_resblks - mp->m_resblks_avail); |
1303 | 1311 | ||
1304 | if (delta > 0) { /* Putting blocks back */ | 1312 | if (delta > 0) { /* Putting blocks back */ |
@@ -1332,7 +1340,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field, | |||
1332 | } | 1340 | } |
1333 | } | 1341 | } |
1334 | 1342 | ||
1335 | mp->m_sb.sb_fdblocks = lcounter; | 1343 | mp->m_sb.sb_fdblocks = lcounter + SET_ASIDE_BLOCKS; |
1336 | return 0; | 1344 | return 0; |
1337 | case XFS_SBS_FREXTENTS: | 1345 | case XFS_SBS_FREXTENTS: |
1338 | lcounter = (long long)mp->m_sb.sb_frextents; | 1346 | lcounter = (long long)mp->m_sb.sb_frextents; |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 668ad23fd37c..b2bd4be4200a 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -53,8 +53,8 @@ typedef struct xfs_trans_reservations { | |||
53 | #else | 53 | #else |
54 | struct cred; | 54 | struct cred; |
55 | struct log; | 55 | struct log; |
56 | struct vfs; | 56 | struct bhv_vfs; |
57 | struct vnode; | 57 | struct bhv_vnode; |
58 | struct xfs_mount_args; | 58 | struct xfs_mount_args; |
59 | struct xfs_ihash; | 59 | struct xfs_ihash; |
60 | struct xfs_chash; | 60 | struct xfs_chash; |
@@ -63,9 +63,11 @@ struct xfs_perag; | |||
63 | struct xfs_iocore; | 63 | struct xfs_iocore; |
64 | struct xfs_bmbt_irec; | 64 | struct xfs_bmbt_irec; |
65 | struct xfs_bmap_free; | 65 | struct xfs_bmap_free; |
66 | struct xfs_extdelta; | ||
67 | struct xfs_swapext; | ||
66 | 68 | ||
67 | extern struct vfsops xfs_vfsops; | 69 | extern struct bhv_vfsops xfs_vfsops; |
68 | extern struct vnodeops xfs_vnodeops; | 70 | extern struct bhv_vnodeops xfs_vnodeops; |
69 | 71 | ||
70 | #define AIL_LOCK_T lock_t | 72 | #define AIL_LOCK_T lock_t |
71 | #define AIL_LOCKINIT(x,y) spinlock_init(x,y) | 73 | #define AIL_LOCKINIT(x,y) spinlock_init(x,y) |
@@ -78,15 +80,15 @@ extern struct vnodeops xfs_vnodeops; | |||
78 | * Prototypes and functions for the Data Migration subsystem. | 80 | * Prototypes and functions for the Data Migration subsystem. |
79 | */ | 81 | */ |
80 | 82 | ||
81 | typedef int (*xfs_send_data_t)(int, struct vnode *, | 83 | typedef int (*xfs_send_data_t)(int, struct bhv_vnode *, |
82 | xfs_off_t, size_t, int, vrwlock_t *); | 84 | xfs_off_t, size_t, int, bhv_vrwlock_t *); |
83 | typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); | 85 | typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); |
84 | typedef int (*xfs_send_destroy_t)(struct vnode *, dm_right_t); | 86 | typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t); |
85 | typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vfs *, | 87 | typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *, |
86 | struct vnode *, | 88 | struct bhv_vnode *, |
87 | dm_right_t, struct vnode *, dm_right_t, | 89 | dm_right_t, struct bhv_vnode *, dm_right_t, |
88 | char *, char *, mode_t, int, int); | 90 | char *, char *, mode_t, int, int); |
89 | typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *, | 91 | typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, struct bhv_vnode *, |
90 | dm_right_t, mode_t, int, int); | 92 | dm_right_t, mode_t, int, int); |
91 | 93 | ||
92 | typedef struct xfs_dmops { | 94 | typedef struct xfs_dmops { |
@@ -188,13 +190,18 @@ typedef struct xfs_qmops { | |||
188 | * Prototypes and functions for I/O core modularization. | 190 | * Prototypes and functions for I/O core modularization. |
189 | */ | 191 | */ |
190 | 192 | ||
191 | typedef int (*xfs_ioinit_t)(struct vfs *, | 193 | typedef int (*xfs_ioinit_t)(struct bhv_vfs *, |
192 | struct xfs_mount_args *, int); | 194 | struct xfs_mount_args *, int); |
193 | typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, | 195 | typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, |
194 | xfs_fileoff_t, xfs_filblks_t, int, | 196 | xfs_fileoff_t, xfs_filblks_t, int, |
195 | xfs_fsblock_t *, xfs_extlen_t, | 197 | xfs_fsblock_t *, xfs_extlen_t, |
196 | struct xfs_bmbt_irec *, int *, | 198 | struct xfs_bmbt_irec *, int *, |
197 | struct xfs_bmap_free *); | 199 | struct xfs_bmap_free *, struct xfs_extdelta *); |
200 | typedef int (*xfs_bunmapi_t)(struct xfs_trans *, | ||
201 | void *, xfs_fileoff_t, | ||
202 | xfs_filblks_t, int, xfs_extnum_t, | ||
203 | xfs_fsblock_t *, struct xfs_bmap_free *, | ||
204 | struct xfs_extdelta *, int *); | ||
198 | typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); | 205 | typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); |
199 | typedef int (*xfs_iomap_write_direct_t)( | 206 | typedef int (*xfs_iomap_write_direct_t)( |
200 | void *, xfs_off_t, size_t, int, | 207 | void *, xfs_off_t, size_t, int, |
@@ -213,11 +220,14 @@ typedef void (*xfs_lock_demote_t)(void *, uint); | |||
213 | typedef int (*xfs_lock_nowait_t)(void *, uint); | 220 | typedef int (*xfs_lock_nowait_t)(void *, uint); |
214 | typedef void (*xfs_unlk_t)(void *, unsigned int); | 221 | typedef void (*xfs_unlk_t)(void *, unsigned int); |
215 | typedef xfs_fsize_t (*xfs_size_t)(void *); | 222 | typedef xfs_fsize_t (*xfs_size_t)(void *); |
216 | typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *); | 223 | typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *); |
224 | typedef int (*xfs_swap_extents_t)(void *, void *, | ||
225 | struct xfs_swapext*); | ||
217 | 226 | ||
218 | typedef struct xfs_ioops { | 227 | typedef struct xfs_ioops { |
219 | xfs_ioinit_t xfs_ioinit; | 228 | xfs_ioinit_t xfs_ioinit; |
220 | xfs_bmapi_t xfs_bmapi_func; | 229 | xfs_bmapi_t xfs_bmapi_func; |
230 | xfs_bunmapi_t xfs_bunmapi_func; | ||
221 | xfs_bmap_eof_t xfs_bmap_eof_func; | 231 | xfs_bmap_eof_t xfs_bmap_eof_func; |
222 | xfs_iomap_write_direct_t xfs_iomap_write_direct; | 232 | xfs_iomap_write_direct_t xfs_iomap_write_direct; |
223 | xfs_iomap_write_delay_t xfs_iomap_write_delay; | 233 | xfs_iomap_write_delay_t xfs_iomap_write_delay; |
@@ -230,13 +240,17 @@ typedef struct xfs_ioops { | |||
230 | xfs_unlk_t xfs_unlock; | 240 | xfs_unlk_t xfs_unlock; |
231 | xfs_size_t xfs_size_func; | 241 | xfs_size_t xfs_size_func; |
232 | xfs_iodone_t xfs_iodone; | 242 | xfs_iodone_t xfs_iodone; |
243 | xfs_swap_extents_t xfs_swap_extents_func; | ||
233 | } xfs_ioops_t; | 244 | } xfs_ioops_t; |
234 | 245 | ||
235 | #define XFS_IOINIT(vfsp, args, flags) \ | 246 | #define XFS_IOINIT(vfsp, args, flags) \ |
236 | (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) | 247 | (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) |
237 | #define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \ | 248 | #define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \ |
238 | (*(mp)->m_io_ops.xfs_bmapi_func) \ | 249 | (*(mp)->m_io_ops.xfs_bmapi_func) \ |
239 | (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist) | 250 | (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta) |
251 | #define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \ | ||
252 | (*(mp)->m_io_ops.xfs_bunmapi_func) \ | ||
253 | (trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done) | ||
240 | #define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \ | 254 | #define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \ |
241 | (*(mp)->m_io_ops.xfs_bmap_eof_func) \ | 255 | (*(mp)->m_io_ops.xfs_bmap_eof_func) \ |
242 | ((io)->io_obj, endoff, whichfork, eof) | 256 | ((io)->io_obj, endoff, whichfork, eof) |
@@ -266,6 +280,9 @@ typedef struct xfs_ioops { | |||
266 | (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) | 280 | (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) |
267 | #define XFS_IODONE(vfsp) \ | 281 | #define XFS_IODONE(vfsp) \ |
268 | (*(mp)->m_io_ops.xfs_iodone)(vfsp) | 282 | (*(mp)->m_io_ops.xfs_iodone)(vfsp) |
283 | #define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \ | ||
284 | (*(mp)->m_io_ops.xfs_swap_extents_func) \ | ||
285 | ((io)->io_obj, (tio)->io_obj, sxp) | ||
269 | 286 | ||
270 | #ifdef HAVE_PERCPU_SB | 287 | #ifdef HAVE_PERCPU_SB |
271 | 288 | ||
@@ -386,8 +403,6 @@ typedef struct xfs_mount { | |||
386 | __uint8_t m_inode_quiesce;/* call quiesce on new inodes. | 403 | __uint8_t m_inode_quiesce;/* call quiesce on new inodes. |
387 | field governed by m_ilock */ | 404 | field governed by m_ilock */ |
388 | __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ | 405 | __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ |
389 | __uint8_t m_dirversion; /* 1 or 2 */ | ||
390 | xfs_dirops_t m_dirops; /* table of dir funcs */ | ||
391 | int m_dirblksize; /* directory block sz--bytes */ | 406 | int m_dirblksize; /* directory block sz--bytes */ |
392 | int m_dirblkfsbs; /* directory block sz--fsbs */ | 407 | int m_dirblkfsbs; /* directory block sz--fsbs */ |
393 | xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ | 408 | xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ |
@@ -494,16 +509,7 @@ xfs_preferred_iosize(xfs_mount_t *mp) | |||
494 | 509 | ||
495 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) | 510 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) |
496 | #define xfs_force_shutdown(m,f) \ | 511 | #define xfs_force_shutdown(m,f) \ |
497 | VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__) | 512 | bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__) |
498 | |||
499 | /* | ||
500 | * Flags sent to xfs_force_shutdown. | ||
501 | */ | ||
502 | #define XFS_METADATA_IO_ERROR 0x1 | ||
503 | #define XFS_LOG_IO_ERROR 0x2 | ||
504 | #define XFS_FORCE_UMOUNT 0x4 | ||
505 | #define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */ | ||
506 | #define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */ | ||
507 | 513 | ||
508 | /* | 514 | /* |
509 | * Flags for xfs_mountfs | 515 | * Flags for xfs_mountfs |
@@ -521,7 +527,7 @@ xfs_preferred_iosize(xfs_mount_t *mp) | |||
521 | * Macros for getting from mount to vfs and back. | 527 | * Macros for getting from mount to vfs and back. |
522 | */ | 528 | */ |
523 | #define XFS_MTOVFS(mp) xfs_mtovfs(mp) | 529 | #define XFS_MTOVFS(mp) xfs_mtovfs(mp) |
524 | static inline struct vfs *xfs_mtovfs(xfs_mount_t *mp) | 530 | static inline struct bhv_vfs *xfs_mtovfs(xfs_mount_t *mp) |
525 | { | 531 | { |
526 | return bhvtovfs(&mp->m_bhv); | 532 | return bhvtovfs(&mp->m_bhv); |
527 | } | 533 | } |
@@ -533,7 +539,7 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp) | |||
533 | } | 539 | } |
534 | 540 | ||
535 | #define XFS_VFSTOM(vfs) xfs_vfstom(vfs) | 541 | #define XFS_VFSTOM(vfs) xfs_vfstom(vfs) |
536 | static inline xfs_mount_t *xfs_vfstom(vfs_t *vfs) | 542 | static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs) |
537 | { | 543 | { |
538 | return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)); | 544 | return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)); |
539 | } | 545 | } |
@@ -571,7 +577,7 @@ typedef struct xfs_mod_sb { | |||
571 | extern xfs_mount_t *xfs_mount_init(void); | 577 | extern xfs_mount_t *xfs_mount_init(void); |
572 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); | 578 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); |
573 | extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); | 579 | extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); |
574 | extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); | 580 | extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int); |
575 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); | 581 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); |
576 | 582 | ||
577 | extern int xfs_unmountfs(xfs_mount_t *, struct cred *); | 583 | extern int xfs_unmountfs(xfs_mount_t *, struct cred *); |
@@ -589,7 +595,7 @@ extern void xfs_freesb(xfs_mount_t *); | |||
589 | extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); | 595 | extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); |
590 | extern int xfs_syncsub(xfs_mount_t *, int, int, int *); | 596 | extern int xfs_syncsub(xfs_mount_t *, int, int, int *); |
591 | extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *); | 597 | extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *); |
592 | extern xfs_agnumber_t xfs_initialize_perag(struct vfs *, xfs_mount_t *, | 598 | extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *, |
593 | xfs_agnumber_t); | 599 | xfs_agnumber_t); |
594 | extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); | 600 | extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); |
595 | 601 | ||
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c index 1408a32eef88..320d63ff9ca2 100644 --- a/fs/xfs/xfs_qmops.c +++ b/fs/xfs/xfs_qmops.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
26 | #include "xfs_dir.h" | ||
27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
28 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
29 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 7fbef974bce6..acb853b33ebb 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h | |||
@@ -365,7 +365,7 @@ typedef struct xfs_dqtrxops { | |||
365 | extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); | 365 | extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); |
366 | extern int xfs_mount_reset_sbqflags(struct xfs_mount *); | 366 | extern int xfs_mount_reset_sbqflags(struct xfs_mount *); |
367 | 367 | ||
368 | extern struct bhv_vfsops xfs_qmops; | 368 | extern struct bhv_module_vfsops xfs_qmops; |
369 | 369 | ||
370 | #endif /* __KERNEL__ */ | 370 | #endif /* __KERNEL__ */ |
371 | 371 | ||
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 1f148762eb28..d98171deaa1c 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
@@ -22,13 +22,11 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
31 | #include "xfs_dir_sf.h" | ||
32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
@@ -40,7 +38,6 @@ | |||
40 | #include "xfs_refcache.h" | 38 | #include "xfs_refcache.h" |
41 | #include "xfs_utils.h" | 39 | #include "xfs_utils.h" |
42 | #include "xfs_trans_space.h" | 40 | #include "xfs_trans_space.h" |
43 | #include "xfs_dir_leaf.h" | ||
44 | 41 | ||
45 | 42 | ||
46 | /* | 43 | /* |
@@ -87,8 +84,8 @@ STATIC int | |||
87 | xfs_lock_for_rename( | 84 | xfs_lock_for_rename( |
88 | xfs_inode_t *dp1, /* old (source) directory inode */ | 85 | xfs_inode_t *dp1, /* old (source) directory inode */ |
89 | xfs_inode_t *dp2, /* new (target) directory inode */ | 86 | xfs_inode_t *dp2, /* new (target) directory inode */ |
90 | vname_t *vname1,/* old entry name */ | 87 | bhv_vname_t *vname1,/* old entry name */ |
91 | vname_t *vname2,/* new entry name */ | 88 | bhv_vname_t *vname2,/* new entry name */ |
92 | xfs_inode_t **ipp1, /* inode of old entry */ | 89 | xfs_inode_t **ipp1, /* inode of old entry */ |
93 | xfs_inode_t **ipp2, /* inode of new entry, if it | 90 | xfs_inode_t **ipp2, /* inode of new entry, if it |
94 | already exists, NULL otherwise. */ | 91 | already exists, NULL otherwise. */ |
@@ -225,9 +222,9 @@ xfs_lock_for_rename( | |||
225 | int | 222 | int |
226 | xfs_rename( | 223 | xfs_rename( |
227 | bhv_desc_t *src_dir_bdp, | 224 | bhv_desc_t *src_dir_bdp, |
228 | vname_t *src_vname, | 225 | bhv_vname_t *src_vname, |
229 | vnode_t *target_dir_vp, | 226 | bhv_vnode_t *target_dir_vp, |
230 | vname_t *target_vname, | 227 | bhv_vname_t *target_vname, |
231 | cred_t *credp) | 228 | cred_t *credp) |
232 | { | 229 | { |
233 | xfs_trans_t *tp; | 230 | xfs_trans_t *tp; |
@@ -242,7 +239,7 @@ xfs_rename( | |||
242 | int committed; | 239 | int committed; |
243 | xfs_inode_t *inodes[4]; | 240 | xfs_inode_t *inodes[4]; |
244 | int target_ip_dropped = 0; /* dropped target_ip link? */ | 241 | int target_ip_dropped = 0; /* dropped target_ip link? */ |
245 | vnode_t *src_dir_vp; | 242 | bhv_vnode_t *src_dir_vp; |
246 | int spaceres; | 243 | int spaceres; |
247 | int target_link_zero = 0; | 244 | int target_link_zero = 0; |
248 | int num_inodes; | 245 | int num_inodes; |
@@ -398,34 +395,29 @@ xfs_rename( | |||
398 | * fit before actually inserting it. | 395 | * fit before actually inserting it. |
399 | */ | 396 | */ |
400 | if (spaceres == 0 && | 397 | if (spaceres == 0 && |
401 | (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name, | 398 | (error = xfs_dir_canenter(tp, target_dp, target_name, |
402 | target_namelen))) { | 399 | target_namelen))) |
403 | goto error_return; | 400 | goto error_return; |
404 | } | ||
405 | /* | 401 | /* |
406 | * If target does not exist and the rename crosses | 402 | * If target does not exist and the rename crosses |
407 | * directories, adjust the target directory link count | 403 | * directories, adjust the target directory link count |
408 | * to account for the ".." reference from the new entry. | 404 | * to account for the ".." reference from the new entry. |
409 | */ | 405 | */ |
410 | error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name, | 406 | error = xfs_dir_createname(tp, target_dp, target_name, |
411 | target_namelen, src_ip->i_ino, | 407 | target_namelen, src_ip->i_ino, |
412 | &first_block, &free_list, spaceres); | 408 | &first_block, &free_list, spaceres); |
413 | if (error == ENOSPC) { | 409 | if (error == ENOSPC) |
414 | goto error_return; | 410 | goto error_return; |
415 | } | 411 | if (error) |
416 | if (error) { | ||
417 | goto abort_return; | 412 | goto abort_return; |
418 | } | ||
419 | xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 413 | xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
420 | 414 | ||
421 | if (new_parent && src_is_directory) { | 415 | if (new_parent && src_is_directory) { |
422 | error = xfs_bumplink(tp, target_dp); | 416 | error = xfs_bumplink(tp, target_dp); |
423 | if (error) { | 417 | if (error) |
424 | goto abort_return; | 418 | goto abort_return; |
425 | } | ||
426 | } | 419 | } |
427 | } else { /* target_ip != NULL */ | 420 | } else { /* target_ip != NULL */ |
428 | |||
429 | /* | 421 | /* |
430 | * If target exists and it's a directory, check that both | 422 | * If target exists and it's a directory, check that both |
431 | * target and source are directories and that target can be | 423 | * target and source are directories and that target can be |
@@ -435,7 +427,7 @@ xfs_rename( | |||
435 | /* | 427 | /* |
436 | * Make sure target dir is empty. | 428 | * Make sure target dir is empty. |
437 | */ | 429 | */ |
438 | if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) || | 430 | if (!(xfs_dir_isempty(target_ip)) || |
439 | (target_ip->i_d.di_nlink > 2)) { | 431 | (target_ip->i_d.di_nlink > 2)) { |
440 | error = XFS_ERROR(EEXIST); | 432 | error = XFS_ERROR(EEXIST); |
441 | goto error_return; | 433 | goto error_return; |
@@ -451,12 +443,11 @@ xfs_rename( | |||
451 | * In case there is already an entry with the same | 443 | * In case there is already an entry with the same |
452 | * name at the destination directory, remove it first. | 444 | * name at the destination directory, remove it first. |
453 | */ | 445 | */ |
454 | error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name, | 446 | error = xfs_dir_replace(tp, target_dp, target_name, |
455 | target_namelen, src_ip->i_ino, &first_block, | 447 | target_namelen, src_ip->i_ino, |
456 | &free_list, spaceres); | 448 | &first_block, &free_list, spaceres); |
457 | if (error) { | 449 | if (error) |
458 | goto abort_return; | 450 | goto abort_return; |
459 | } | ||
460 | xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 451 | xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
461 | 452 | ||
462 | /* | 453 | /* |
@@ -464,9 +455,8 @@ xfs_rename( | |||
464 | * dir no longer points to it. | 455 | * dir no longer points to it. |
465 | */ | 456 | */ |
466 | error = xfs_droplink(tp, target_ip); | 457 | error = xfs_droplink(tp, target_ip); |
467 | if (error) { | 458 | if (error) |
468 | goto abort_return; | 459 | goto abort_return; |
469 | } | ||
470 | target_ip_dropped = 1; | 460 | target_ip_dropped = 1; |
471 | 461 | ||
472 | if (src_is_directory) { | 462 | if (src_is_directory) { |
@@ -474,9 +464,8 @@ xfs_rename( | |||
474 | * Drop the link from the old "." entry. | 464 | * Drop the link from the old "." entry. |
475 | */ | 465 | */ |
476 | error = xfs_droplink(tp, target_ip); | 466 | error = xfs_droplink(tp, target_ip); |
477 | if (error) { | 467 | if (error) |
478 | goto abort_return; | 468 | goto abort_return; |
479 | } | ||
480 | } | 469 | } |
481 | 470 | ||
482 | /* Do this test while we still hold the locks */ | 471 | /* Do this test while we still hold the locks */ |
@@ -488,18 +477,15 @@ xfs_rename( | |||
488 | * Remove the source. | 477 | * Remove the source. |
489 | */ | 478 | */ |
490 | if (new_parent && src_is_directory) { | 479 | if (new_parent && src_is_directory) { |
491 | |||
492 | /* | 480 | /* |
493 | * Rewrite the ".." entry to point to the new | 481 | * Rewrite the ".." entry to point to the new |
494 | * directory. | 482 | * directory. |
495 | */ | 483 | */ |
496 | error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2, | 484 | error = xfs_dir_replace(tp, src_ip, "..", 2, target_dp->i_ino, |
497 | target_dp->i_ino, &first_block, | 485 | &first_block, &free_list, spaceres); |
498 | &free_list, spaceres); | ||
499 | ASSERT(error != EEXIST); | 486 | ASSERT(error != EEXIST); |
500 | if (error) { | 487 | if (error) |
501 | goto abort_return; | 488 | goto abort_return; |
502 | } | ||
503 | xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 489 | xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
504 | 490 | ||
505 | } else { | 491 | } else { |
@@ -527,16 +513,14 @@ xfs_rename( | |||
527 | * entry that's moved no longer points to it. | 513 | * entry that's moved no longer points to it. |
528 | */ | 514 | */ |
529 | error = xfs_droplink(tp, src_dp); | 515 | error = xfs_droplink(tp, src_dp); |
530 | if (error) { | 516 | if (error) |
531 | goto abort_return; | 517 | goto abort_return; |
532 | } | ||
533 | } | 518 | } |
534 | 519 | ||
535 | error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen, | 520 | error = xfs_dir_removename(tp, src_dp, src_name, src_namelen, |
536 | src_ip->i_ino, &first_block, &free_list, spaceres); | 521 | src_ip->i_ino, &first_block, &free_list, spaceres); |
537 | if (error) { | 522 | if (error) |
538 | goto abort_return; | 523 | goto abort_return; |
539 | } | ||
540 | xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 524 | xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
541 | 525 | ||
542 | /* | 526 | /* |
@@ -609,7 +593,7 @@ xfs_rename( | |||
609 | * Let interposed file systems know about removed links. | 593 | * Let interposed file systems know about removed links. |
610 | */ | 594 | */ |
611 | if (target_ip_dropped) { | 595 | if (target_ip_dropped) { |
612 | VOP_LINK_REMOVED(XFS_ITOV(target_ip), target_dir_vp, | 596 | bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp, |
613 | target_link_zero); | 597 | target_link_zero); |
614 | IRELE(target_ip); | 598 | IRELE(target_ip); |
615 | } | 599 | } |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 5b413946b1c5..0c1e42b037ef 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -141,7 +139,7 @@ xfs_growfs_rt_alloc( | |||
141 | cancelflags |= XFS_TRANS_ABORT; | 139 | cancelflags |= XFS_TRANS_ABORT; |
142 | error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks, | 140 | error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks, |
143 | XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock, | 141 | XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock, |
144 | resblks, &map, &nmap, &flist); | 142 | resblks, &map, &nmap, &flist, NULL); |
145 | if (!error && nmap < 1) | 143 | if (!error && nmap < 1) |
146 | error = XFS_ERROR(ENOSPC); | 144 | error = XFS_ERROR(ENOSPC); |
147 | if (error) | 145 | if (error) |
@@ -2404,10 +2402,10 @@ xfs_rtprint_range( | |||
2404 | { | 2402 | { |
2405 | xfs_extlen_t i; /* block number in the extent */ | 2403 | xfs_extlen_t i; /* block number in the extent */ |
2406 | 2404 | ||
2407 | printk("%Ld: ", (long long)start); | 2405 | cmn_err(CE_DEBUG, "%Ld: ", (long long)start); |
2408 | for (i = 0; i < len; i++) | 2406 | for (i = 0; i < len; i++) |
2409 | printk("%d", xfs_rtcheck_bit(mp, tp, start + i, 1)); | 2407 | cmn_err(CE_DEBUG, "%d", xfs_rtcheck_bit(mp, tp, start + i, 1)); |
2410 | printk("\n"); | 2408 | cmn_err(CE_DEBUG, "\n"); |
2411 | } | 2409 | } |
2412 | 2410 | ||
2413 | /* | 2411 | /* |
@@ -2431,17 +2429,17 @@ xfs_rtprint_summary( | |||
2431 | (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c); | 2429 | (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c); |
2432 | if (c) { | 2430 | if (c) { |
2433 | if (!p) { | 2431 | if (!p) { |
2434 | printk("%Ld-%Ld:", 1LL << l, | 2432 | cmn_err(CE_DEBUG, "%Ld-%Ld:", 1LL << l, |
2435 | XFS_RTMIN((1LL << l) + | 2433 | XFS_RTMIN((1LL << l) + |
2436 | ((1LL << l) - 1LL), | 2434 | ((1LL << l) - 1LL), |
2437 | mp->m_sb.sb_rextents)); | 2435 | mp->m_sb.sb_rextents)); |
2438 | p = 1; | 2436 | p = 1; |
2439 | } | 2437 | } |
2440 | printk(" %Ld:%d", (long long)i, c); | 2438 | cmn_err(CE_DEBUG, " %Ld:%d", (long long)i, c); |
2441 | } | 2439 | } |
2442 | } | 2440 | } |
2443 | if (p) | 2441 | if (p) |
2444 | printk("\n"); | 2442 | cmn_err(CE_DEBUG, "\n"); |
2445 | } | 2443 | } |
2446 | if (sumbp) | 2444 | if (sumbp) |
2447 | xfs_trans_brelse(tp, sumbp); | 2445 | xfs_trans_brelse(tp, sumbp); |
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c index a59c102cf214..defb2febaaf5 100644 --- a/fs/xfs/xfs_rw.c +++ b/fs/xfs/xfs_rw.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -92,6 +90,90 @@ xfs_write_clear_setuid( | |||
92 | } | 90 | } |
93 | 91 | ||
94 | /* | 92 | /* |
93 | * Handle logging requirements of various synchronous types of write. | ||
94 | */ | ||
95 | int | ||
96 | xfs_write_sync_logforce( | ||
97 | xfs_mount_t *mp, | ||
98 | xfs_inode_t *ip) | ||
99 | { | ||
100 | int error = 0; | ||
101 | |||
102 | /* | ||
103 | * If we're treating this as O_DSYNC and we have not updated the | ||
104 | * size, force the log. | ||
105 | */ | ||
106 | if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) && | ||
107 | !(ip->i_update_size)) { | ||
108 | xfs_inode_log_item_t *iip = ip->i_itemp; | ||
109 | |||
110 | /* | ||
111 | * If an allocation transaction occurred | ||
112 | * without extending the size, then we have to force | ||
113 | * the log up the proper point to ensure that the | ||
114 | * allocation is permanent. We can't count on | ||
115 | * the fact that buffered writes lock out direct I/O | ||
116 | * writes - the direct I/O write could have extended | ||
117 | * the size nontransactionally, then finished before | ||
118 | * we started. xfs_write_file will think that the file | ||
119 | * didn't grow but the update isn't safe unless the | ||
120 | * size change is logged. | ||
121 | * | ||
122 | * Force the log if we've committed a transaction | ||
123 | * against the inode or if someone else has and | ||
124 | * the commit record hasn't gone to disk (e.g. | ||
125 | * the inode is pinned). This guarantees that | ||
126 | * all changes affecting the inode are permanent | ||
127 | * when we return. | ||
128 | */ | ||
129 | if (iip && iip->ili_last_lsn) { | ||
130 | xfs_log_force(mp, iip->ili_last_lsn, | ||
131 | XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
132 | } else if (xfs_ipincount(ip) > 0) { | ||
133 | xfs_log_force(mp, (xfs_lsn_t)0, | ||
134 | XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
135 | } | ||
136 | |||
137 | } else { | ||
138 | xfs_trans_t *tp; | ||
139 | |||
140 | /* | ||
141 | * O_SYNC or O_DSYNC _with_ a size update are handled | ||
142 | * the same way. | ||
143 | * | ||
144 | * If the write was synchronous then we need to make | ||
145 | * sure that the inode modification time is permanent. | ||
146 | * We'll have updated the timestamp above, so here | ||
147 | * we use a synchronous transaction to log the inode. | ||
148 | * It's not fast, but it's necessary. | ||
149 | * | ||
150 | * If this a dsync write and the size got changed | ||
151 | * non-transactionally, then we need to ensure that | ||
152 | * the size change gets logged in a synchronous | ||
153 | * transaction. | ||
154 | */ | ||
155 | tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC); | ||
156 | if ((error = xfs_trans_reserve(tp, 0, | ||
157 | XFS_SWRITE_LOG_RES(mp), | ||
158 | 0, 0, 0))) { | ||
159 | /* Transaction reserve failed */ | ||
160 | xfs_trans_cancel(tp, 0); | ||
161 | } else { | ||
162 | /* Transaction reserve successful */ | ||
163 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
164 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
165 | xfs_trans_ihold(tp, ip); | ||
166 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
167 | xfs_trans_set_sync(tp); | ||
168 | error = xfs_trans_commit(tp, 0, NULL); | ||
169 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | return error; | ||
174 | } | ||
175 | |||
176 | /* | ||
95 | * Force a shutdown of the filesystem instantly while keeping | 177 | * Force a shutdown of the filesystem instantly while keeping |
96 | * the filesystem consistent. We don't do an unmount here; just shutdown | 178 | * the filesystem consistent. We don't do an unmount here; just shutdown |
97 | * the shop, make sure that absolutely nothing persistent happens to | 179 | * the shop, make sure that absolutely nothing persistent happens to |
@@ -109,12 +191,12 @@ xfs_do_force_shutdown( | |||
109 | xfs_mount_t *mp; | 191 | xfs_mount_t *mp; |
110 | 192 | ||
111 | mp = XFS_BHVTOM(bdp); | 193 | mp = XFS_BHVTOM(bdp); |
112 | logerror = flags & XFS_LOG_IO_ERROR; | 194 | logerror = flags & SHUTDOWN_LOG_IO_ERROR; |
113 | 195 | ||
114 | if (!(flags & XFS_FORCE_UMOUNT)) { | 196 | if (!(flags & SHUTDOWN_FORCE_UMOUNT)) { |
115 | cmn_err(CE_NOTE, | 197 | cmn_err(CE_NOTE, "xfs_force_shutdown(%s,0x%x) called from " |
116 | "xfs_force_shutdown(%s,0x%x) called from line %d of file %s. Return address = 0x%p", | 198 | "line %d of file %s. Return address = 0x%p", |
117 | mp->m_fsname,flags,lnnum,fname,__return_address); | 199 | mp->m_fsname, flags, lnnum, fname, __return_address); |
118 | } | 200 | } |
119 | /* | 201 | /* |
120 | * No need to duplicate efforts. | 202 | * No need to duplicate efforts. |
@@ -125,33 +207,37 @@ xfs_do_force_shutdown( | |||
125 | /* | 207 | /* |
126 | * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't | 208 | * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't |
127 | * queue up anybody new on the log reservations, and wakes up | 209 | * queue up anybody new on the log reservations, and wakes up |
128 | * everybody who's sleeping on log reservations and tells | 210 | * everybody who's sleeping on log reservations to tell them |
129 | * them the bad news. | 211 | * the bad news. |
130 | */ | 212 | */ |
131 | if (xfs_log_force_umount(mp, logerror)) | 213 | if (xfs_log_force_umount(mp, logerror)) |
132 | return; | 214 | return; |
133 | 215 | ||
134 | if (flags & XFS_CORRUPT_INCORE) { | 216 | if (flags & SHUTDOWN_CORRUPT_INCORE) { |
135 | xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp, | 217 | xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp, |
136 | "Corruption of in-memory data detected. Shutting down filesystem: %s", | 218 | "Corruption of in-memory data detected. Shutting down filesystem: %s", |
137 | mp->m_fsname); | 219 | mp->m_fsname); |
138 | if (XFS_ERRLEVEL_HIGH <= xfs_error_level) { | 220 | if (XFS_ERRLEVEL_HIGH <= xfs_error_level) { |
139 | xfs_stack_trace(); | 221 | xfs_stack_trace(); |
140 | } | 222 | } |
141 | } else if (!(flags & XFS_FORCE_UMOUNT)) { | 223 | } else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) { |
142 | if (logerror) { | 224 | if (logerror) { |
143 | xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp, | 225 | xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp, |
144 | "Log I/O Error Detected. Shutting down filesystem: %s", | 226 | "Log I/O Error Detected. Shutting down filesystem: %s", |
227 | mp->m_fsname); | ||
228 | } else if (flags & SHUTDOWN_DEVICE_REQ) { | ||
229 | xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp, | ||
230 | "All device paths lost. Shutting down filesystem: %s", | ||
145 | mp->m_fsname); | 231 | mp->m_fsname); |
146 | } else if (!(flags & XFS_SHUTDOWN_REMOTE_REQ)) { | 232 | } else if (!(flags & SHUTDOWN_REMOTE_REQ)) { |
147 | xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp, | 233 | xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp, |
148 | "I/O Error Detected. Shutting down filesystem: %s", | 234 | "I/O Error Detected. Shutting down filesystem: %s", |
149 | mp->m_fsname); | 235 | mp->m_fsname); |
150 | } | 236 | } |
151 | } | 237 | } |
152 | if (!(flags & XFS_FORCE_UMOUNT)) { | 238 | if (!(flags & SHUTDOWN_FORCE_UMOUNT)) { |
153 | cmn_err(CE_ALERT, | 239 | cmn_err(CE_ALERT, "Please umount the filesystem, " |
154 | "Please umount the filesystem, and rectify the problem(s)"); | 240 | "and rectify the problem(s)"); |
155 | } | 241 | } |
156 | } | 242 | } |
157 | 243 | ||
@@ -335,7 +421,7 @@ xfs_bwrite( | |||
335 | * from bwrite and we could be tracing a buffer that has | 421 | * from bwrite and we could be tracing a buffer that has |
336 | * been reused. | 422 | * been reused. |
337 | */ | 423 | */ |
338 | xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); | 424 | xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); |
339 | } | 425 | } |
340 | return (error); | 426 | return (error); |
341 | } | 427 | } |
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h index e63795644478..188b296ff50c 100644 --- a/fs/xfs/xfs_rw.h +++ b/fs/xfs/xfs_rw.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -75,6 +75,7 @@ xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb) | |||
75 | * Prototypes for functions in xfs_rw.c. | 75 | * Prototypes for functions in xfs_rw.c. |
76 | */ | 76 | */ |
77 | extern int xfs_write_clear_setuid(struct xfs_inode *ip); | 77 | extern int xfs_write_clear_setuid(struct xfs_inode *ip); |
78 | extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip); | ||
78 | extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); | 79 | extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); |
79 | extern int xfs_bioerror(struct xfs_buf *bp); | 80 | extern int xfs_bioerror(struct xfs_buf *bp); |
80 | extern int xfs_bioerror_relse(struct xfs_buf *bp); | 81 | extern int xfs_bioerror_relse(struct xfs_buf *bp); |
@@ -87,9 +88,10 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp, | |||
87 | /* | 88 | /* |
88 | * Prototypes for functions in xfs_vnodeops.c. | 89 | * Prototypes for functions in xfs_vnodeops.c. |
89 | */ | 90 | */ |
90 | extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock); | 91 | extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); |
91 | extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock); | 92 | extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); |
92 | extern int xfs_setattr(bhv_desc_t *bdp, vattr_t *vap, int flags, cred_t *credp); | 93 | extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags, |
94 | cred_t *credp); | ||
93 | extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf, | 95 | extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf, |
94 | xfs_off_t offset, cred_t *credp, int flags); | 96 | xfs_off_t offset, cred_t *credp, int flags); |
95 | extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state, | 97 | extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state, |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 8d056cef5d1f..ee2721e0de4d 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
@@ -33,7 +32,6 @@ | |||
33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
36 | #include "xfs_dir_sf.h" | ||
37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
@@ -236,11 +234,8 @@ xfs_trans_alloc( | |||
236 | xfs_mount_t *mp, | 234 | xfs_mount_t *mp, |
237 | uint type) | 235 | uint type) |
238 | { | 236 | { |
239 | fs_check_frozen(XFS_MTOVFS(mp), SB_FREEZE_TRANS); | 237 | vfs_wait_for_freeze(XFS_MTOVFS(mp), SB_FREEZE_TRANS); |
240 | atomic_inc(&mp->m_active_trans); | 238 | return _xfs_trans_alloc(mp, type); |
241 | |||
242 | return (_xfs_trans_alloc(mp, type)); | ||
243 | |||
244 | } | 239 | } |
245 | 240 | ||
246 | xfs_trans_t * | 241 | xfs_trans_t * |
@@ -250,12 +245,9 @@ _xfs_trans_alloc( | |||
250 | { | 245 | { |
251 | xfs_trans_t *tp; | 246 | xfs_trans_t *tp; |
252 | 247 | ||
253 | ASSERT(xfs_trans_zone != NULL); | 248 | atomic_inc(&mp->m_active_trans); |
254 | tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP); | ||
255 | 249 | ||
256 | /* | 250 | tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP); |
257 | * Initialize the transaction structure. | ||
258 | */ | ||
259 | tp->t_magic = XFS_TRANS_MAGIC; | 251 | tp->t_magic = XFS_TRANS_MAGIC; |
260 | tp->t_type = type; | 252 | tp->t_type = type; |
261 | tp->t_mountp = mp; | 253 | tp->t_mountp = mp; |
@@ -263,8 +255,7 @@ _xfs_trans_alloc( | |||
263 | tp->t_busy_free = XFS_LBC_NUM_SLOTS; | 255 | tp->t_busy_free = XFS_LBC_NUM_SLOTS; |
264 | XFS_LIC_INIT(&(tp->t_items)); | 256 | XFS_LIC_INIT(&(tp->t_items)); |
265 | XFS_LBC_INIT(&(tp->t_busy)); | 257 | XFS_LBC_INIT(&(tp->t_busy)); |
266 | 258 | return tp; | |
267 | return (tp); | ||
268 | } | 259 | } |
269 | 260 | ||
270 | /* | 261 | /* |
@@ -303,7 +294,7 @@ xfs_trans_dup( | |||
303 | tp->t_blk_res = tp->t_blk_res_used; | 294 | tp->t_blk_res = tp->t_blk_res_used; |
304 | ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; | 295 | ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; |
305 | tp->t_rtx_res = tp->t_rtx_res_used; | 296 | tp->t_rtx_res = tp->t_rtx_res_used; |
306 | PFLAGS_DUP(&tp->t_pflags, &ntp->t_pflags); | 297 | ntp->t_pflags = tp->t_pflags; |
307 | 298 | ||
308 | XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp); | 299 | XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp); |
309 | 300 | ||
@@ -335,14 +326,11 @@ xfs_trans_reserve( | |||
335 | uint logcount) | 326 | uint logcount) |
336 | { | 327 | { |
337 | int log_flags; | 328 | int log_flags; |
338 | int error; | 329 | int error = 0; |
339 | int rsvd; | 330 | int rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; |
340 | |||
341 | error = 0; | ||
342 | rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; | ||
343 | 331 | ||
344 | /* Mark this thread as being in a transaction */ | 332 | /* Mark this thread as being in a transaction */ |
345 | PFLAGS_SET_FSTRANS(&tp->t_pflags); | 333 | current_set_flags_nested(&tp->t_pflags, PF_FSTRANS); |
346 | 334 | ||
347 | /* | 335 | /* |
348 | * Attempt to reserve the needed disk blocks by decrementing | 336 | * Attempt to reserve the needed disk blocks by decrementing |
@@ -353,7 +341,7 @@ xfs_trans_reserve( | |||
353 | error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, | 341 | error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, |
354 | -blocks, rsvd); | 342 | -blocks, rsvd); |
355 | if (error != 0) { | 343 | if (error != 0) { |
356 | PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); | 344 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
357 | return (XFS_ERROR(ENOSPC)); | 345 | return (XFS_ERROR(ENOSPC)); |
358 | } | 346 | } |
359 | tp->t_blk_res += blocks; | 347 | tp->t_blk_res += blocks; |
@@ -426,9 +414,9 @@ undo_blocks: | |||
426 | tp->t_blk_res = 0; | 414 | tp->t_blk_res = 0; |
427 | } | 415 | } |
428 | 416 | ||
429 | PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); | 417 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
430 | 418 | ||
431 | return (error); | 419 | return error; |
432 | } | 420 | } |
433 | 421 | ||
434 | 422 | ||
@@ -819,7 +807,7 @@ shut_us_down: | |||
819 | if (commit_lsn == -1 && !shutdown) | 807 | if (commit_lsn == -1 && !shutdown) |
820 | shutdown = XFS_ERROR(EIO); | 808 | shutdown = XFS_ERROR(EIO); |
821 | } | 809 | } |
822 | PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); | 810 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
823 | xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0); | 811 | xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0); |
824 | xfs_trans_free_busy(tp); | 812 | xfs_trans_free_busy(tp); |
825 | xfs_trans_free(tp); | 813 | xfs_trans_free(tp); |
@@ -846,7 +834,7 @@ shut_us_down: | |||
846 | */ | 834 | */ |
847 | nvec = xfs_trans_count_vecs(tp); | 835 | nvec = xfs_trans_count_vecs(tp); |
848 | if (nvec == 0) { | 836 | if (nvec == 0) { |
849 | xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); | 837 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); |
850 | goto shut_us_down; | 838 | goto shut_us_down; |
851 | } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) { | 839 | } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) { |
852 | log_vector = log_vector_fast; | 840 | log_vector = log_vector_fast; |
@@ -884,7 +872,7 @@ shut_us_down: | |||
884 | * had pinned, clean up, free trans structure, and return error. | 872 | * had pinned, clean up, free trans structure, and return error. |
885 | */ | 873 | */ |
886 | if (error || commit_lsn == -1) { | 874 | if (error || commit_lsn == -1) { |
887 | PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); | 875 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
888 | xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); | 876 | xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); |
889 | return XFS_ERROR(EIO); | 877 | return XFS_ERROR(EIO); |
890 | } | 878 | } |
@@ -926,7 +914,7 @@ shut_us_down: | |||
926 | /* | 914 | /* |
927 | * Mark this thread as no longer being in a transaction | 915 | * Mark this thread as no longer being in a transaction |
928 | */ | 916 | */ |
929 | PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); | 917 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
930 | 918 | ||
931 | /* | 919 | /* |
932 | * Once all the items of the transaction have been copied | 920 | * Once all the items of the transaction have been copied |
@@ -1148,7 +1136,7 @@ xfs_trans_cancel( | |||
1148 | */ | 1136 | */ |
1149 | if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) { | 1137 | if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) { |
1150 | XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp); | 1138 | XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp); |
1151 | xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); | 1139 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
1152 | } | 1140 | } |
1153 | #ifdef DEBUG | 1141 | #ifdef DEBUG |
1154 | if (!(flags & XFS_TRANS_ABORT)) { | 1142 | if (!(flags & XFS_TRANS_ABORT)) { |
@@ -1182,7 +1170,7 @@ xfs_trans_cancel( | |||
1182 | } | 1170 | } |
1183 | 1171 | ||
1184 | /* mark this thread as no longer being in a transaction */ | 1172 | /* mark this thread as no longer being in a transaction */ |
1185 | PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); | 1173 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
1186 | 1174 | ||
1187 | xfs_trans_free_items(tp, flags); | 1175 | xfs_trans_free_items(tp, flags); |
1188 | xfs_trans_free_busy(tp); | 1176 | xfs_trans_free_busy(tp); |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 100d9a4b38ee..cb65c3a603f5 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -805,12 +805,9 @@ typedef struct xfs_trans { | |||
805 | ((mp)->m_sb.sb_inodesize + \ | 805 | ((mp)->m_sb.sb_inodesize + \ |
806 | (mp)->m_sb.sb_sectsize * 2 + \ | 806 | (mp)->m_sb.sb_sectsize * 2 + \ |
807 | (mp)->m_dirblksize + \ | 807 | (mp)->m_dirblksize + \ |
808 | (XFS_DIR_IS_V1(mp) ? 0 : \ | 808 | XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \ |
809 | XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \ | ||
810 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 809 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
811 | (128 * (4 + \ | 810 | (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ |
812 | (XFS_DIR_IS_V1(mp) ? 0 : \ | ||
813 | XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ | ||
814 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | 811 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) |
815 | 812 | ||
816 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) | 813 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) |
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 19ab24af1c1c..558c87ff0c41 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dmapi.h" | 25 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 26 | #include "xfs_mount.h" |
28 | #include "xfs_trans_priv.h" | 27 | #include "xfs_trans_priv.h" |
@@ -363,9 +362,10 @@ xfs_trans_delete_ail( | |||
363 | AIL_UNLOCK(mp, s); | 362 | AIL_UNLOCK(mp, s); |
364 | else { | 363 | else { |
365 | xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, | 364 | xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, |
366 | "xfs_trans_delete_ail: attempting to delete a log item that is not in the AIL"); | 365 | "%s: attempting to delete a log item that is not in the AIL", |
366 | __FUNCTION__); | ||
367 | AIL_UNLOCK(mp, s); | 367 | AIL_UNLOCK(mp, s); |
368 | xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); | 368 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
369 | } | 369 | } |
370 | } | 370 | } |
371 | } | 371 | } |
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index c74c31ebc81c..60b6b898022b 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
@@ -320,7 +318,7 @@ xfs_trans_read_buf( | |||
320 | if (xfs_error_target == target) { | 318 | if (xfs_error_target == target) { |
321 | if (((xfs_req_num++) % xfs_error_mod) == 0) { | 319 | if (((xfs_req_num++) % xfs_error_mod) == 0) { |
322 | xfs_buf_relse(bp); | 320 | xfs_buf_relse(bp); |
323 | printk("Returning error!\n"); | 321 | cmn_err(CE_DEBUG, "Returning error!\n"); |
324 | return XFS_ERROR(EIO); | 322 | return XFS_ERROR(EIO); |
325 | } | 323 | } |
326 | } | 324 | } |
@@ -369,7 +367,7 @@ xfs_trans_read_buf( | |||
369 | */ | 367 | */ |
370 | if (tp->t_flags & XFS_TRANS_DIRTY) | 368 | if (tp->t_flags & XFS_TRANS_DIRTY) |
371 | xfs_force_shutdown(tp->t_mountp, | 369 | xfs_force_shutdown(tp->t_mountp, |
372 | XFS_METADATA_IO_ERROR); | 370 | SHUTDOWN_META_IO_ERROR); |
373 | return error; | 371 | return error; |
374 | } | 372 | } |
375 | } | 373 | } |
@@ -414,7 +412,7 @@ xfs_trans_read_buf( | |||
414 | xfs_ioerror_alert("xfs_trans_read_buf", mp, | 412 | xfs_ioerror_alert("xfs_trans_read_buf", mp, |
415 | bp, blkno); | 413 | bp, blkno); |
416 | if (tp->t_flags & XFS_TRANS_DIRTY) | 414 | if (tp->t_flags & XFS_TRANS_DIRTY) |
417 | xfs_force_shutdown(tp->t_mountp, XFS_METADATA_IO_ERROR); | 415 | xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR); |
418 | xfs_buf_relse(bp); | 416 | xfs_buf_relse(bp); |
419 | return error; | 417 | return error; |
420 | } | 418 | } |
@@ -423,9 +421,9 @@ xfs_trans_read_buf( | |||
423 | if (xfs_error_target == target) { | 421 | if (xfs_error_target == target) { |
424 | if (((xfs_req_num++) % xfs_error_mod) == 0) { | 422 | if (((xfs_req_num++) % xfs_error_mod) == 0) { |
425 | xfs_force_shutdown(tp->t_mountp, | 423 | xfs_force_shutdown(tp->t_mountp, |
426 | XFS_METADATA_IO_ERROR); | 424 | SHUTDOWN_META_IO_ERROR); |
427 | xfs_buf_relse(bp); | 425 | xfs_buf_relse(bp); |
428 | printk("Returning error in trans!\n"); | 426 | cmn_err(CE_DEBUG, "Returning trans error!\n"); |
429 | return XFS_ERROR(EIO); | 427 | return XFS_ERROR(EIO); |
430 | } | 428 | } |
431 | } | 429 | } |
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index 7d7d627f25df..b290270dd4a6 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
25 | #include "xfs_dir.h" | ||
26 | #include "xfs_dmapi.h" | 25 | #include "xfs_dmapi.h" |
27 | #include "xfs_mount.h" | 26 | #include "xfs_mount.h" |
28 | #include "xfs_trans_priv.h" | 27 | #include "xfs_trans_priv.h" |
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 7c5894d59f81..b8db1d5cde5a 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c | |||
@@ -24,14 +24,12 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 31 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir_sf.h" | ||
35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
36 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c index 1117d600d741..2912aac07c7b 100644 --- a/fs/xfs/xfs_trans_item.c +++ b/fs/xfs/xfs_trans_item.c | |||
@@ -493,7 +493,7 @@ xfs_trans_add_busy(xfs_trans_t *tp, xfs_agnumber_t ag, xfs_extlen_t idx) | |||
493 | break; | 493 | break; |
494 | } else { | 494 | } else { |
495 | /* out-of-order vacancy */ | 495 | /* out-of-order vacancy */ |
496 | printk("OOO vacancy lbcp 0x%p\n", lbcp); | 496 | cmn_err(CE_DEBUG, "OOO vacancy lbcp 0x%p\n", lbcp); |
497 | ASSERT(0); | 497 | ASSERT(0); |
498 | } | 498 | } |
499 | } | 499 | } |
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h index 7fe3792b18df..4ea2e5074bdd 100644 --- a/fs/xfs/xfs_trans_space.h +++ b/fs/xfs/xfs_trans_space.h | |||
@@ -30,8 +30,7 @@ | |||
30 | XFS_EXTENTADD_SPACE_RES(mp,w)) | 30 | XFS_EXTENTADD_SPACE_RES(mp,w)) |
31 | #define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) | 31 | #define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) |
32 | #define XFS_DAENTER_DBS(mp,w) \ | 32 | #define XFS_DAENTER_DBS(mp,w) \ |
33 | (XFS_DA_NODE_MAXDEPTH + \ | 33 | (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0)) |
34 | ((XFS_DIR_IS_V2(mp) && (w) == XFS_DATA_FORK) ? 2 : 0)) | ||
35 | #define XFS_DAENTER_BLOCKS(mp,w) \ | 34 | #define XFS_DAENTER_BLOCKS(mp,w) \ |
36 | (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w)) | 35 | (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w)) |
37 | #define XFS_DAENTER_BMAP1B(mp,w) \ | 36 | #define XFS_DAENTER_BMAP1B(mp,w) \ |
@@ -41,10 +40,7 @@ | |||
41 | #define XFS_DAENTER_SPACE_RES(mp,w) \ | 40 | #define XFS_DAENTER_SPACE_RES(mp,w) \ |
42 | (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w)) | 41 | (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w)) |
43 | #define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w) | 42 | #define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w) |
44 | #define XFS_DIRENTER_MAX_SPLIT(mp,nl) \ | 43 | #define XFS_DIRENTER_MAX_SPLIT(mp,nl) 1 |
45 | (((mp)->m_sb.sb_blocksize == 512 && \ | ||
46 | XFS_DIR_IS_V1(mp) && \ | ||
47 | (nl) >= XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN) ? 2 : 1) | ||
48 | #define XFS_DIRENTER_SPACE_RES(mp,nl) \ | 44 | #define XFS_DIRENTER_SPACE_RES(mp,nl) \ |
49 | (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \ | 45 | (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \ |
50 | XFS_DIRENTER_MAX_SPLIT(mp,nl)) | 46 | XFS_DIRENTER_MAX_SPLIT(mp,nl)) |
@@ -57,8 +53,7 @@ | |||
57 | * Space reservation values for various transactions. | 53 | * Space reservation values for various transactions. |
58 | */ | 54 | */ |
59 | #define XFS_ADDAFORK_SPACE_RES(mp) \ | 55 | #define XFS_ADDAFORK_SPACE_RES(mp) \ |
60 | ((mp)->m_dirblkfsbs + \ | 56 | ((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)) |
61 | (XFS_DIR_IS_V1(mp) ? 0 : XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))) | ||
62 | #define XFS_ATTRRM_SPACE_RES(mp) \ | 57 | #define XFS_ATTRRM_SPACE_RES(mp) \ |
63 | XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) | 58 | XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) |
64 | /* This macro is not used - see inline code in xfs_attr_set */ | 59 | /* This macro is not used - see inline code in xfs_attr_set */ |
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 34654ec6ae10..9014d7e44488 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
@@ -24,12 +24,10 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 30 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_dir_sf.h" | ||
33 | #include "xfs_dir2_sf.h" | 31 | #include "xfs_dir2_sf.h" |
34 | #include "xfs_attr_sf.h" | 32 | #include "xfs_attr_sf.h" |
35 | #include "xfs_dinode.h" | 33 | #include "xfs_dinode.h" |
@@ -51,10 +49,10 @@ | |||
51 | */ | 49 | */ |
52 | int | 50 | int |
53 | xfs_get_dir_entry( | 51 | xfs_get_dir_entry( |
54 | vname_t *dentry, | 52 | bhv_vname_t *dentry, |
55 | xfs_inode_t **ipp) | 53 | xfs_inode_t **ipp) |
56 | { | 54 | { |
57 | vnode_t *vp; | 55 | bhv_vnode_t *vp; |
58 | 56 | ||
59 | vp = VNAME_TO_VNODE(dentry); | 57 | vp = VNAME_TO_VNODE(dentry); |
60 | 58 | ||
@@ -69,11 +67,11 @@ int | |||
69 | xfs_dir_lookup_int( | 67 | xfs_dir_lookup_int( |
70 | bhv_desc_t *dir_bdp, | 68 | bhv_desc_t *dir_bdp, |
71 | uint lock_mode, | 69 | uint lock_mode, |
72 | vname_t *dentry, | 70 | bhv_vname_t *dentry, |
73 | xfs_ino_t *inum, | 71 | xfs_ino_t *inum, |
74 | xfs_inode_t **ipp) | 72 | xfs_inode_t **ipp) |
75 | { | 73 | { |
76 | vnode_t *dir_vp; | 74 | bhv_vnode_t *dir_vp; |
77 | xfs_inode_t *dp; | 75 | xfs_inode_t *dp; |
78 | int error; | 76 | int error; |
79 | 77 | ||
@@ -82,8 +80,7 @@ xfs_dir_lookup_int( | |||
82 | 80 | ||
83 | dp = XFS_BHVTOI(dir_bdp); | 81 | dp = XFS_BHVTOI(dir_bdp); |
84 | 82 | ||
85 | error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp, | 83 | error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum); |
86 | VNAME(dentry), VNAMELEN(dentry), inum); | ||
87 | if (!error) { | 84 | if (!error) { |
88 | /* | 85 | /* |
89 | * Unlock the directory. We do this because we can't | 86 | * Unlock the directory. We do this because we can't |
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h index 472661a3b6d8..fe953e98afa7 100644 --- a/fs/xfs/xfs_utils.h +++ b/fs/xfs/xfs_utils.h | |||
@@ -23,9 +23,10 @@ | |||
23 | #define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \ | 23 | #define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \ |
24 | (inst_t *)__return_address) | 24 | (inst_t *)__return_address) |
25 | 25 | ||
26 | extern int xfs_rename (bhv_desc_t *, vname_t *, vnode_t *, vname_t *, cred_t *); | 26 | extern int xfs_rename (bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *, |
27 | extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **); | 27 | bhv_vname_t *, cred_t *); |
28 | extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, | 28 | 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 *, | ||
29 | xfs_inode_t **); | 30 | xfs_inode_t **); |
30 | extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); | 31 | extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); |
31 | extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, | 32 | 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 36ea1b2094f2..6c96391f3f1a 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 26 | #include "xfs_ag.h" |
27 | #include "xfs_dir.h" | ||
28 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
30 | #include "xfs_mount.h" | 29 | #include "xfs_mount.h" |
@@ -32,7 +31,6 @@ | |||
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
35 | #include "xfs_dir_sf.h" | ||
36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
@@ -131,9 +129,6 @@ xfs_init(void) | |||
131 | #ifdef XFS_BMBT_TRACE | 129 | #ifdef XFS_BMBT_TRACE |
132 | xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP); | 130 | xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP); |
133 | #endif | 131 | #endif |
134 | #ifdef XFS_DIR_TRACE | ||
135 | xfs_dir_trace_buf = ktrace_alloc(XFS_DIR_TRACE_SIZE, KM_SLEEP); | ||
136 | #endif | ||
137 | #ifdef XFS_ATTR_TRACE | 132 | #ifdef XFS_ATTR_TRACE |
138 | xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP); | 133 | xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP); |
139 | #endif | 134 | #endif |
@@ -177,9 +172,6 @@ xfs_cleanup(void) | |||
177 | #ifdef XFS_ATTR_TRACE | 172 | #ifdef XFS_ATTR_TRACE |
178 | ktrace_free(xfs_attr_trace_buf); | 173 | ktrace_free(xfs_attr_trace_buf); |
179 | #endif | 174 | #endif |
180 | #ifdef XFS_DIR_TRACE | ||
181 | ktrace_free(xfs_dir_trace_buf); | ||
182 | #endif | ||
183 | #ifdef XFS_BMBT_TRACE | 175 | #ifdef XFS_BMBT_TRACE |
184 | ktrace_free(xfs_bmbt_trace_buf); | 176 | ktrace_free(xfs_bmbt_trace_buf); |
185 | #endif | 177 | #endif |
@@ -212,7 +204,7 @@ xfs_cleanup(void) | |||
212 | */ | 204 | */ |
213 | STATIC int | 205 | STATIC int |
214 | xfs_start_flags( | 206 | xfs_start_flags( |
215 | struct vfs *vfs, | 207 | struct bhv_vfs *vfs, |
216 | struct xfs_mount_args *ap, | 208 | struct xfs_mount_args *ap, |
217 | struct xfs_mount *mp) | 209 | struct xfs_mount *mp) |
218 | { | 210 | { |
@@ -337,7 +329,7 @@ xfs_start_flags( | |||
337 | */ | 329 | */ |
338 | STATIC int | 330 | STATIC int |
339 | xfs_finish_flags( | 331 | xfs_finish_flags( |
340 | struct vfs *vfs, | 332 | struct bhv_vfs *vfs, |
341 | struct xfs_mount_args *ap, | 333 | struct xfs_mount_args *ap, |
342 | struct xfs_mount *mp) | 334 | struct xfs_mount *mp) |
343 | { | 335 | { |
@@ -423,7 +415,7 @@ xfs_mount( | |||
423 | struct xfs_mount_args *args, | 415 | struct xfs_mount_args *args, |
424 | cred_t *credp) | 416 | cred_t *credp) |
425 | { | 417 | { |
426 | struct vfs *vfsp = bhvtovfs(bhvp); | 418 | struct bhv_vfs *vfsp = bhvtovfs(bhvp); |
427 | struct bhv_desc *p; | 419 | struct bhv_desc *p; |
428 | struct xfs_mount *mp = XFS_BHVTOM(bhvp); | 420 | struct xfs_mount *mp = XFS_BHVTOM(bhvp); |
429 | struct block_device *ddev, *logdev, *rtdev; | 421 | struct block_device *ddev, *logdev, *rtdev; |
@@ -552,10 +544,10 @@ xfs_unmount( | |||
552 | int flags, | 544 | int flags, |
553 | cred_t *credp) | 545 | cred_t *credp) |
554 | { | 546 | { |
555 | struct vfs *vfsp = bhvtovfs(bdp); | 547 | bhv_vfs_t *vfsp = bhvtovfs(bdp); |
556 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 548 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
557 | xfs_inode_t *rip; | 549 | xfs_inode_t *rip; |
558 | vnode_t *rvp; | 550 | bhv_vnode_t *rvp; |
559 | int unmount_event_wanted = 0; | 551 | int unmount_event_wanted = 0; |
560 | int unmount_event_flags = 0; | 552 | int unmount_event_flags = 0; |
561 | int xfs_unmountfs_needed = 0; | 553 | int xfs_unmountfs_needed = 0; |
@@ -665,9 +657,8 @@ xfs_mntupdate( | |||
665 | int *flags, | 657 | int *flags, |
666 | struct xfs_mount_args *args) | 658 | struct xfs_mount_args *args) |
667 | { | 659 | { |
668 | struct vfs *vfsp = bhvtovfs(bdp); | 660 | bhv_vfs_t *vfsp = bhvtovfs(bdp); |
669 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 661 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
670 | int error; | ||
671 | 662 | ||
672 | if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ | 663 | if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ |
673 | if (vfsp->vfs_flag & VFS_RDONLY) | 664 | if (vfsp->vfs_flag & VFS_RDONLY) |
@@ -679,7 +670,7 @@ xfs_mntupdate( | |||
679 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 670 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
680 | } | 671 | } |
681 | } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ | 672 | } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ |
682 | VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error); | 673 | bhv_vfs_sync(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL); |
683 | xfs_quiesce_fs(mp); | 674 | xfs_quiesce_fs(mp); |
684 | xfs_log_unmount_write(mp); | 675 | xfs_log_unmount_write(mp); |
685 | xfs_unmountfs_writesb(mp); | 676 | xfs_unmountfs_writesb(mp); |
@@ -702,7 +693,7 @@ xfs_unmount_flush( | |||
702 | xfs_inode_t *rip = mp->m_rootip; | 693 | xfs_inode_t *rip = mp->m_rootip; |
703 | xfs_inode_t *rbmip; | 694 | xfs_inode_t *rbmip; |
704 | xfs_inode_t *rsumip = NULL; | 695 | xfs_inode_t *rsumip = NULL; |
705 | vnode_t *rvp = XFS_ITOV(rip); | 696 | bhv_vnode_t *rvp = XFS_ITOV(rip); |
706 | int error; | 697 | int error; |
707 | 698 | ||
708 | xfs_ilock(rip, XFS_ILOCK_EXCL); | 699 | xfs_ilock(rip, XFS_ILOCK_EXCL); |
@@ -781,9 +772,9 @@ fscorrupt_out2: | |||
781 | STATIC int | 772 | STATIC int |
782 | xfs_root( | 773 | xfs_root( |
783 | bhv_desc_t *bdp, | 774 | bhv_desc_t *bdp, |
784 | vnode_t **vpp) | 775 | bhv_vnode_t **vpp) |
785 | { | 776 | { |
786 | vnode_t *vp; | 777 | bhv_vnode_t *vp; |
787 | 778 | ||
788 | vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); | 779 | vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); |
789 | VN_HOLD(vp); | 780 | VN_HOLD(vp); |
@@ -801,8 +792,8 @@ xfs_root( | |||
801 | STATIC int | 792 | STATIC int |
802 | xfs_statvfs( | 793 | xfs_statvfs( |
803 | bhv_desc_t *bdp, | 794 | bhv_desc_t *bdp, |
804 | xfs_statfs_t *statp, | 795 | bhv_statvfs_t *statp, |
805 | vnode_t *vp) | 796 | bhv_vnode_t *vp) |
806 | { | 797 | { |
807 | __uint64_t fakeinos; | 798 | __uint64_t fakeinos; |
808 | xfs_extlen_t lsize; | 799 | xfs_extlen_t lsize; |
@@ -900,7 +891,7 @@ xfs_sync( | |||
900 | /* | 891 | /* |
901 | * xfs sync routine for internal use | 892 | * xfs sync routine for internal use |
902 | * | 893 | * |
903 | * This routine supports all of the flags defined for the generic VFS_SYNC | 894 | * This routine supports all of the flags defined for the generic vfs_sync |
904 | * interface as explained above under xfs_sync. In the interests of not | 895 | * interface as explained above under xfs_sync. In the interests of not |
905 | * changing interfaces within the 6.5 family, additional internally- | 896 | * changing interfaces within the 6.5 family, additional internally- |
906 | * required functions are specified within a separate xflags parameter, | 897 | * required functions are specified within a separate xflags parameter, |
@@ -917,7 +908,7 @@ xfs_sync_inodes( | |||
917 | xfs_inode_t *ip = NULL; | 908 | xfs_inode_t *ip = NULL; |
918 | xfs_inode_t *ip_next; | 909 | xfs_inode_t *ip_next; |
919 | xfs_buf_t *bp; | 910 | xfs_buf_t *bp; |
920 | vnode_t *vp = NULL; | 911 | bhv_vnode_t *vp = NULL; |
921 | int error; | 912 | int error; |
922 | int last_error; | 913 | int last_error; |
923 | uint64_t fflag; | 914 | uint64_t fflag; |
@@ -1156,9 +1147,9 @@ xfs_sync_inodes( | |||
1156 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 1147 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
1157 | 1148 | ||
1158 | if (XFS_FORCED_SHUTDOWN(mp)) { | 1149 | if (XFS_FORCED_SHUTDOWN(mp)) { |
1159 | VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF); | 1150 | bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); |
1160 | } else { | 1151 | } else { |
1161 | VOP_FLUSHINVAL_PAGES(vp, 0, -1, FI_REMAPF); | 1152 | bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF); |
1162 | } | 1153 | } |
1163 | 1154 | ||
1164 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 1155 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
@@ -1178,8 +1169,8 @@ xfs_sync_inodes( | |||
1178 | * across calls to the buffer cache. | 1169 | * across calls to the buffer cache. |
1179 | */ | 1170 | */ |
1180 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 1171 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
1181 | VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, | 1172 | error = bhv_vop_flush_pages(vp, (xfs_off_t)0, |
1182 | fflag, FI_NONE, error); | 1173 | -1, fflag, FI_NONE); |
1183 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 1174 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
1184 | } | 1175 | } |
1185 | 1176 | ||
@@ -1231,9 +1222,7 @@ xfs_sync_inodes( | |||
1231 | * marker and free it. | 1222 | * marker and free it. |
1232 | */ | 1223 | */ |
1233 | XFS_MOUNT_ILOCK(mp); | 1224 | XFS_MOUNT_ILOCK(mp); |
1234 | |||
1235 | IPOINTER_REMOVE(ip, mp); | 1225 | IPOINTER_REMOVE(ip, mp); |
1236 | |||
1237 | XFS_MOUNT_IUNLOCK(mp); | 1226 | XFS_MOUNT_IUNLOCK(mp); |
1238 | 1227 | ||
1239 | ASSERT(!(lock_flags & | 1228 | ASSERT(!(lock_flags & |
@@ -1421,7 +1410,7 @@ xfs_sync_inodes( | |||
1421 | /* | 1410 | /* |
1422 | * xfs sync routine for internal use | 1411 | * xfs sync routine for internal use |
1423 | * | 1412 | * |
1424 | * This routine supports all of the flags defined for the generic VFS_SYNC | 1413 | * This routine supports all of the flags defined for the generic vfs_sync |
1425 | * interface as explained above under xfs_sync. In the interests of not | 1414 | * interface as explained above under xfs_sync. In the interests of not |
1426 | * changing interfaces within the 6.5 family, additional internally- | 1415 | * changing interfaces within the 6.5 family, additional internally- |
1427 | * required functions are specified within a separate xflags parameter, | 1416 | * required functions are specified within a separate xflags parameter, |
@@ -1574,7 +1563,7 @@ xfs_syncsub( | |||
1574 | STATIC int | 1563 | STATIC int |
1575 | xfs_vget( | 1564 | xfs_vget( |
1576 | bhv_desc_t *bdp, | 1565 | bhv_desc_t *bdp, |
1577 | vnode_t **vpp, | 1566 | bhv_vnode_t **vpp, |
1578 | fid_t *fidp) | 1567 | fid_t *fidp) |
1579 | { | 1568 | { |
1580 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 1569 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
@@ -1657,10 +1646,10 @@ xfs_vget( | |||
1657 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ | 1646 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ |
1658 | 1647 | ||
1659 | STATIC unsigned long | 1648 | STATIC unsigned long |
1660 | suffix_strtoul(const char *cp, char **endp, unsigned int base) | 1649 | suffix_strtoul(char *s, char **endp, unsigned int base) |
1661 | { | 1650 | { |
1662 | int last, shift_left_factor = 0; | 1651 | int last, shift_left_factor = 0; |
1663 | char *value = (char *)cp; | 1652 | char *value = s; |
1664 | 1653 | ||
1665 | last = strlen(value) - 1; | 1654 | last = strlen(value) - 1; |
1666 | if (value[last] == 'K' || value[last] == 'k') { | 1655 | if (value[last] == 'K' || value[last] == 'k') { |
@@ -1676,7 +1665,7 @@ suffix_strtoul(const char *cp, char **endp, unsigned int base) | |||
1676 | value[last] = '\0'; | 1665 | value[last] = '\0'; |
1677 | } | 1666 | } |
1678 | 1667 | ||
1679 | return simple_strtoul(cp, endp, base) << shift_left_factor; | 1668 | return simple_strtoul((const char *)s, endp, base) << shift_left_factor; |
1680 | } | 1669 | } |
1681 | 1670 | ||
1682 | STATIC int | 1671 | STATIC int |
@@ -1686,7 +1675,7 @@ xfs_parseargs( | |||
1686 | struct xfs_mount_args *args, | 1675 | struct xfs_mount_args *args, |
1687 | int update) | 1676 | int update) |
1688 | { | 1677 | { |
1689 | struct vfs *vfsp = bhvtovfs(bhv); | 1678 | bhv_vfs_t *vfsp = bhvtovfs(bhv); |
1690 | char *this_char, *value, *eov; | 1679 | char *this_char, *value, *eov; |
1691 | int dsunit, dswidth, vol_dsunit, vol_dswidth; | 1680 | int dsunit, dswidth, vol_dsunit, vol_dswidth; |
1692 | int iosize; | 1681 | int iosize; |
@@ -1708,42 +1697,48 @@ xfs_parseargs( | |||
1708 | 1697 | ||
1709 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { | 1698 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { |
1710 | if (!value || !*value) { | 1699 | if (!value || !*value) { |
1711 | printk("XFS: %s option requires an argument\n", | 1700 | cmn_err(CE_WARN, |
1701 | "XFS: %s option requires an argument", | ||
1712 | this_char); | 1702 | this_char); |
1713 | return EINVAL; | 1703 | return EINVAL; |
1714 | } | 1704 | } |
1715 | args->logbufs = simple_strtoul(value, &eov, 10); | 1705 | args->logbufs = simple_strtoul(value, &eov, 10); |
1716 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { | 1706 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { |
1717 | if (!value || !*value) { | 1707 | if (!value || !*value) { |
1718 | printk("XFS: %s option requires an argument\n", | 1708 | cmn_err(CE_WARN, |
1709 | "XFS: %s option requires an argument", | ||
1719 | this_char); | 1710 | this_char); |
1720 | return EINVAL; | 1711 | return EINVAL; |
1721 | } | 1712 | } |
1722 | args->logbufsize = suffix_strtoul(value, &eov, 10); | 1713 | args->logbufsize = suffix_strtoul(value, &eov, 10); |
1723 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { | 1714 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { |
1724 | if (!value || !*value) { | 1715 | if (!value || !*value) { |
1725 | printk("XFS: %s option requires an argument\n", | 1716 | cmn_err(CE_WARN, |
1717 | "XFS: %s option requires an argument", | ||
1726 | this_char); | 1718 | this_char); |
1727 | return EINVAL; | 1719 | return EINVAL; |
1728 | } | 1720 | } |
1729 | strncpy(args->logname, value, MAXNAMELEN); | 1721 | strncpy(args->logname, value, MAXNAMELEN); |
1730 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { | 1722 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { |
1731 | if (!value || !*value) { | 1723 | if (!value || !*value) { |
1732 | printk("XFS: %s option requires an argument\n", | 1724 | cmn_err(CE_WARN, |
1725 | "XFS: %s option requires an argument", | ||
1733 | this_char); | 1726 | this_char); |
1734 | return EINVAL; | 1727 | return EINVAL; |
1735 | } | 1728 | } |
1736 | strncpy(args->mtpt, value, MAXNAMELEN); | 1729 | strncpy(args->mtpt, value, MAXNAMELEN); |
1737 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { | 1730 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { |
1738 | if (!value || !*value) { | 1731 | if (!value || !*value) { |
1739 | printk("XFS: %s option requires an argument\n", | 1732 | cmn_err(CE_WARN, |
1733 | "XFS: %s option requires an argument", | ||
1740 | this_char); | 1734 | this_char); |
1741 | return EINVAL; | 1735 | return EINVAL; |
1742 | } | 1736 | } |
1743 | strncpy(args->rtname, value, MAXNAMELEN); | 1737 | strncpy(args->rtname, value, MAXNAMELEN); |
1744 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { | 1738 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { |
1745 | if (!value || !*value) { | 1739 | if (!value || !*value) { |
1746 | printk("XFS: %s option requires an argument\n", | 1740 | cmn_err(CE_WARN, |
1741 | "XFS: %s option requires an argument", | ||
1747 | this_char); | 1742 | this_char); |
1748 | return EINVAL; | 1743 | return EINVAL; |
1749 | } | 1744 | } |
@@ -1752,7 +1747,8 @@ xfs_parseargs( | |||
1752 | args->iosizelog = (uint8_t) iosize; | 1747 | args->iosizelog = (uint8_t) iosize; |
1753 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { | 1748 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { |
1754 | if (!value || !*value) { | 1749 | if (!value || !*value) { |
1755 | printk("XFS: %s option requires an argument\n", | 1750 | cmn_err(CE_WARN, |
1751 | "XFS: %s option requires an argument", | ||
1756 | this_char); | 1752 | this_char); |
1757 | return EINVAL; | 1753 | return EINVAL; |
1758 | } | 1754 | } |
@@ -1761,7 +1757,8 @@ xfs_parseargs( | |||
1761 | args->iosizelog = ffs(iosize) - 1; | 1757 | args->iosizelog = ffs(iosize) - 1; |
1762 | } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { | 1758 | } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { |
1763 | if (!value || !*value) { | 1759 | if (!value || !*value) { |
1764 | printk("XFS: %s option requires an argument\n", | 1760 | cmn_err(CE_WARN, |
1761 | "XFS: %s option requires an argument", | ||
1765 | this_char); | 1762 | this_char); |
1766 | return EINVAL; | 1763 | return EINVAL; |
1767 | } | 1764 | } |
@@ -1782,7 +1779,8 @@ xfs_parseargs( | |||
1782 | } else if (!strcmp(this_char, MNTOPT_INO64)) { | 1779 | } else if (!strcmp(this_char, MNTOPT_INO64)) { |
1783 | args->flags |= XFSMNT_INO64; | 1780 | args->flags |= XFSMNT_INO64; |
1784 | #if !XFS_BIG_INUMS | 1781 | #if !XFS_BIG_INUMS |
1785 | printk("XFS: %s option not allowed on this system\n", | 1782 | cmn_err(CE_WARN, |
1783 | "XFS: %s option not allowed on this system", | ||
1786 | this_char); | 1784 | this_char); |
1787 | return EINVAL; | 1785 | return EINVAL; |
1788 | #endif | 1786 | #endif |
@@ -1792,14 +1790,16 @@ xfs_parseargs( | |||
1792 | args->flags |= XFSMNT_SWALLOC; | 1790 | args->flags |= XFSMNT_SWALLOC; |
1793 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { | 1791 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { |
1794 | if (!value || !*value) { | 1792 | if (!value || !*value) { |
1795 | printk("XFS: %s option requires an argument\n", | 1793 | cmn_err(CE_WARN, |
1794 | "XFS: %s option requires an argument", | ||
1796 | this_char); | 1795 | this_char); |
1797 | return EINVAL; | 1796 | return EINVAL; |
1798 | } | 1797 | } |
1799 | dsunit = simple_strtoul(value, &eov, 10); | 1798 | dsunit = simple_strtoul(value, &eov, 10); |
1800 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { | 1799 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { |
1801 | if (!value || !*value) { | 1800 | if (!value || !*value) { |
1802 | printk("XFS: %s option requires an argument\n", | 1801 | cmn_err(CE_WARN, |
1802 | "XFS: %s option requires an argument", | ||
1803 | this_char); | 1803 | this_char); |
1804 | return EINVAL; | 1804 | return EINVAL; |
1805 | } | 1805 | } |
@@ -1807,7 +1807,8 @@ xfs_parseargs( | |||
1807 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { | 1807 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { |
1808 | args->flags &= ~XFSMNT_32BITINODES; | 1808 | args->flags &= ~XFSMNT_32BITINODES; |
1809 | #if !XFS_BIG_INUMS | 1809 | #if !XFS_BIG_INUMS |
1810 | printk("XFS: %s option not allowed on this system\n", | 1810 | cmn_err(CE_WARN, |
1811 | "XFS: %s option not allowed on this system", | ||
1811 | this_char); | 1812 | this_char); |
1812 | return EINVAL; | 1813 | return EINVAL; |
1813 | #endif | 1814 | #endif |
@@ -1831,36 +1832,41 @@ xfs_parseargs( | |||
1831 | args->flags &= ~XFSMNT_ATTR2; | 1832 | args->flags &= ~XFSMNT_ATTR2; |
1832 | } else if (!strcmp(this_char, "osyncisdsync")) { | 1833 | } else if (!strcmp(this_char, "osyncisdsync")) { |
1833 | /* no-op, this is now the default */ | 1834 | /* no-op, this is now the default */ |
1834 | printk("XFS: osyncisdsync is now the default, option is deprecated.\n"); | 1835 | cmn_err(CE_WARN, |
1836 | "XFS: osyncisdsync is now the default, option is deprecated."); | ||
1835 | } else if (!strcmp(this_char, "irixsgid")) { | 1837 | } else if (!strcmp(this_char, "irixsgid")) { |
1836 | printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n"); | 1838 | cmn_err(CE_WARN, |
1839 | "XFS: irixsgid is now a sysctl(2) variable, option is deprecated."); | ||
1837 | } else { | 1840 | } else { |
1838 | printk("XFS: unknown mount option [%s].\n", this_char); | 1841 | cmn_err(CE_WARN, |
1842 | "XFS: unknown mount option [%s].", this_char); | ||
1839 | return EINVAL; | 1843 | return EINVAL; |
1840 | } | 1844 | } |
1841 | } | 1845 | } |
1842 | 1846 | ||
1843 | if (args->flags & XFSMNT_NORECOVERY) { | 1847 | if (args->flags & XFSMNT_NORECOVERY) { |
1844 | if ((vfsp->vfs_flag & VFS_RDONLY) == 0) { | 1848 | if ((vfsp->vfs_flag & VFS_RDONLY) == 0) { |
1845 | printk("XFS: no-recovery mounts must be read-only.\n"); | 1849 | cmn_err(CE_WARN, |
1850 | "XFS: no-recovery mounts must be read-only."); | ||
1846 | return EINVAL; | 1851 | return EINVAL; |
1847 | } | 1852 | } |
1848 | } | 1853 | } |
1849 | 1854 | ||
1850 | if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { | 1855 | if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { |
1851 | printk( | 1856 | cmn_err(CE_WARN, |
1852 | "XFS: sunit and swidth options incompatible with the noalign option\n"); | 1857 | "XFS: sunit and swidth options incompatible with the noalign option"); |
1853 | return EINVAL; | 1858 | return EINVAL; |
1854 | } | 1859 | } |
1855 | 1860 | ||
1856 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { | 1861 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { |
1857 | printk("XFS: sunit and swidth must be specified together\n"); | 1862 | cmn_err(CE_WARN, |
1863 | "XFS: sunit and swidth must be specified together"); | ||
1858 | return EINVAL; | 1864 | return EINVAL; |
1859 | } | 1865 | } |
1860 | 1866 | ||
1861 | if (dsunit && (dswidth % dsunit != 0)) { | 1867 | if (dsunit && (dswidth % dsunit != 0)) { |
1862 | printk( | 1868 | cmn_err(CE_WARN, |
1863 | "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)\n", | 1869 | "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)", |
1864 | dswidth, dsunit); | 1870 | dswidth, dsunit); |
1865 | return EINVAL; | 1871 | return EINVAL; |
1866 | } | 1872 | } |
@@ -1907,7 +1913,7 @@ xfs_showargs( | |||
1907 | }; | 1913 | }; |
1908 | struct proc_xfs_info *xfs_infop; | 1914 | struct proc_xfs_info *xfs_infop; |
1909 | struct xfs_mount *mp = XFS_BHVTOM(bhv); | 1915 | struct xfs_mount *mp = XFS_BHVTOM(bhv); |
1910 | struct vfs *vfsp = XFS_MTOVFS(mp); | 1916 | struct bhv_vfs *vfsp = XFS_MTOVFS(mp); |
1911 | 1917 | ||
1912 | for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { | 1918 | for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { |
1913 | if (mp->m_flags & xfs_infop->flag) | 1919 | if (mp->m_flags & xfs_infop->flag) |
@@ -1967,7 +1973,7 @@ xfs_freeze( | |||
1967 | } | 1973 | } |
1968 | 1974 | ||
1969 | 1975 | ||
1970 | vfsops_t xfs_vfsops = { | 1976 | bhv_vfsops_t xfs_vfsops = { |
1971 | BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS), | 1977 | BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS), |
1972 | .vfs_parseargs = xfs_parseargs, | 1978 | .vfs_parseargs = xfs_parseargs, |
1973 | .vfs_showargs = xfs_showargs, | 1979 | .vfs_showargs = xfs_showargs, |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 7027ae68ee38..00a6b7dc24a0 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -16,8 +16,6 @@ | |||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/capability.h> | ||
20 | |||
21 | #include "xfs.h" | 19 | #include "xfs.h" |
22 | #include "xfs_fs.h" | 20 | #include "xfs_fs.h" |
23 | #include "xfs_types.h" | 21 | #include "xfs_types.h" |
@@ -27,7 +25,6 @@ | |||
27 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
28 | #include "xfs_sb.h" | 26 | #include "xfs_sb.h" |
29 | #include "xfs_ag.h" | 27 | #include "xfs_ag.h" |
30 | #include "xfs_dir.h" | ||
31 | #include "xfs_dir2.h" | 28 | #include "xfs_dir2.h" |
32 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
33 | #include "xfs_mount.h" | 30 | #include "xfs_mount.h" |
@@ -35,13 +32,11 @@ | |||
35 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
36 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
37 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
38 | #include "xfs_dir_sf.h" | ||
39 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
40 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
41 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
42 | #include "xfs_inode.h" | 38 | #include "xfs_inode.h" |
43 | #include "xfs_inode_item.h" | 39 | #include "xfs_inode_item.h" |
44 | #include "xfs_dir_leaf.h" | ||
45 | #include "xfs_itable.h" | 40 | #include "xfs_itable.h" |
46 | #include "xfs_btree.h" | 41 | #include "xfs_btree.h" |
47 | #include "xfs_ialloc.h" | 42 | #include "xfs_ialloc.h" |
@@ -58,32 +53,14 @@ | |||
58 | #include "xfs_log_priv.h" | 53 | #include "xfs_log_priv.h" |
59 | #include "xfs_mac.h" | 54 | #include "xfs_mac.h" |
60 | 55 | ||
61 | |||
62 | /* | ||
63 | * The maximum pathlen is 1024 bytes. Since the minimum file system | ||
64 | * blocksize is 512 bytes, we can get a max of 2 extents back from | ||
65 | * bmapi. | ||
66 | */ | ||
67 | #define SYMLINK_MAPS 2 | ||
68 | |||
69 | /* | ||
70 | * For xfs, we check that the file isn't too big to be opened by this kernel. | ||
71 | * No other open action is required for regular files. Devices are handled | ||
72 | * through the specfs file system, pipes through fifofs. Device and | ||
73 | * fifo vnodes are "wrapped" by specfs and fifofs vnodes, respectively, | ||
74 | * when a new vnode is first looked up or created. | ||
75 | */ | ||
76 | STATIC int | 56 | STATIC int |
77 | xfs_open( | 57 | xfs_open( |
78 | bhv_desc_t *bdp, | 58 | bhv_desc_t *bdp, |
79 | cred_t *credp) | 59 | cred_t *credp) |
80 | { | 60 | { |
81 | int mode; | 61 | int mode; |
82 | vnode_t *vp; | 62 | bhv_vnode_t *vp = BHV_TO_VNODE(bdp); |
83 | xfs_inode_t *ip; | 63 | xfs_inode_t *ip = XFS_BHVTOI(bdp); |
84 | |||
85 | vp = BHV_TO_VNODE(bdp); | ||
86 | ip = XFS_BHVTOI(bdp); | ||
87 | 64 | ||
88 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 65 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
89 | return XFS_ERROR(EIO); | 66 | return XFS_ERROR(EIO); |
@@ -101,6 +78,35 @@ xfs_open( | |||
101 | return 0; | 78 | return 0; |
102 | } | 79 | } |
103 | 80 | ||
81 | STATIC int | ||
82 | xfs_close( | ||
83 | bhv_desc_t *bdp, | ||
84 | int flags, | ||
85 | lastclose_t lastclose, | ||
86 | cred_t *credp) | ||
87 | { | ||
88 | bhv_vnode_t *vp = BHV_TO_VNODE(bdp); | ||
89 | xfs_inode_t *ip = XFS_BHVTOI(bdp); | ||
90 | |||
91 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | ||
92 | return XFS_ERROR(EIO); | ||
93 | |||
94 | if (lastclose != L_TRUE || !VN_ISREG(vp)) | ||
95 | return 0; | ||
96 | |||
97 | /* | ||
98 | * If we previously truncated this file and removed old data in | ||
99 | * the process, we want to initiate "early" writeout on the last | ||
100 | * close. This is an attempt to combat the notorious NULL files | ||
101 | * problem which is particularly noticable from a truncate down, | ||
102 | * buffered (re-)write (delalloc), followed by a crash. What we | ||
103 | * are effectively doing here is significantly reducing the time | ||
104 | * window where we'd otherwise be exposed to that problem. | ||
105 | */ | ||
106 | if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0) | ||
107 | return bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE); | ||
108 | return 0; | ||
109 | } | ||
104 | 110 | ||
105 | /* | 111 | /* |
106 | * xfs_getattr | 112 | * xfs_getattr |
@@ -108,13 +114,13 @@ xfs_open( | |||
108 | STATIC int | 114 | STATIC int |
109 | xfs_getattr( | 115 | xfs_getattr( |
110 | bhv_desc_t *bdp, | 116 | bhv_desc_t *bdp, |
111 | vattr_t *vap, | 117 | bhv_vattr_t *vap, |
112 | int flags, | 118 | int flags, |
113 | cred_t *credp) | 119 | cred_t *credp) |
114 | { | 120 | { |
115 | xfs_inode_t *ip; | 121 | xfs_inode_t *ip; |
116 | xfs_mount_t *mp; | 122 | xfs_mount_t *mp; |
117 | vnode_t *vp; | 123 | bhv_vnode_t *vp; |
118 | 124 | ||
119 | vp = BHV_TO_VNODE(bdp); | 125 | vp = BHV_TO_VNODE(bdp); |
120 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 126 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
@@ -241,7 +247,7 @@ xfs_getattr( | |||
241 | int | 247 | int |
242 | xfs_setattr( | 248 | xfs_setattr( |
243 | bhv_desc_t *bdp, | 249 | bhv_desc_t *bdp, |
244 | vattr_t *vap, | 250 | bhv_vattr_t *vap, |
245 | int flags, | 251 | int flags, |
246 | cred_t *credp) | 252 | cred_t *credp) |
247 | { | 253 | { |
@@ -255,7 +261,7 @@ xfs_setattr( | |||
255 | uid_t uid=0, iuid=0; | 261 | uid_t uid=0, iuid=0; |
256 | gid_t gid=0, igid=0; | 262 | gid_t gid=0, igid=0; |
257 | int timeflags = 0; | 263 | int timeflags = 0; |
258 | vnode_t *vp; | 264 | bhv_vnode_t *vp; |
259 | xfs_prid_t projid=0, iprojid=0; | 265 | xfs_prid_t projid=0, iprojid=0; |
260 | int mandlock_before, mandlock_after; | 266 | int mandlock_before, mandlock_after; |
261 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; | 267 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; |
@@ -347,7 +353,6 @@ xfs_setattr( | |||
347 | */ | 353 | */ |
348 | tp = NULL; | 354 | tp = NULL; |
349 | lock_flags = XFS_ILOCK_EXCL; | 355 | lock_flags = XFS_ILOCK_EXCL; |
350 | ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1); | ||
351 | if (flags & ATTR_NOLOCK) | 356 | if (flags & ATTR_NOLOCK) |
352 | need_iolock = 0; | 357 | need_iolock = 0; |
353 | if (!(mask & XFS_AT_SIZE)) { | 358 | if (!(mask & XFS_AT_SIZE)) { |
@@ -666,9 +671,17 @@ xfs_setattr( | |||
666 | ((ip->i_d.di_nlink != 0 || | 671 | ((ip->i_d.di_nlink != 0 || |
667 | !(mp->m_flags & XFS_MOUNT_WSYNC)) | 672 | !(mp->m_flags & XFS_MOUNT_WSYNC)) |
668 | ? 1 : 0)); | 673 | ? 1 : 0)); |
669 | if (code) { | 674 | if (code) |
670 | goto abort_return; | 675 | goto abort_return; |
671 | } | 676 | /* |
677 | * Truncated "down", so we're removing references | ||
678 | * to old data here - if we now delay flushing for | ||
679 | * a long time, we expose ourselves unduly to the | ||
680 | * notorious NULL files problem. So, we mark this | ||
681 | * vnode and flush it when the file is closed, and | ||
682 | * do not wait the usual (long) time for writeout. | ||
683 | */ | ||
684 | VTRUNCATE(vp); | ||
672 | } | 685 | } |
673 | /* | 686 | /* |
674 | * Have to do this even if the file's size doesn't change. | 687 | * Have to do this even if the file's size doesn't change. |
@@ -800,6 +813,8 @@ xfs_setattr( | |||
800 | di_flags |= XFS_DIFLAG_NODUMP; | 813 | di_flags |= XFS_DIFLAG_NODUMP; |
801 | if (vap->va_xflags & XFS_XFLAG_PROJINHERIT) | 814 | if (vap->va_xflags & XFS_XFLAG_PROJINHERIT) |
802 | di_flags |= XFS_DIFLAG_PROJINHERIT; | 815 | di_flags |= XFS_DIFLAG_PROJINHERIT; |
816 | if (vap->va_xflags & XFS_XFLAG_NODEFRAG) | ||
817 | di_flags |= XFS_DIFLAG_NODEFRAG; | ||
803 | if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { | 818 | if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { |
804 | if (vap->va_xflags & XFS_XFLAG_RTINHERIT) | 819 | if (vap->va_xflags & XFS_XFLAG_RTINHERIT) |
805 | di_flags |= XFS_DIFLAG_RTINHERIT; | 820 | di_flags |= XFS_DIFLAG_RTINHERIT; |
@@ -869,7 +884,7 @@ xfs_setattr( | |||
869 | */ | 884 | */ |
870 | mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); | 885 | mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); |
871 | if (mandlock_before != mandlock_after) { | 886 | if (mandlock_before != mandlock_after) { |
872 | VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_ENF_LOCKING, | 887 | bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING, |
873 | mandlock_after); | 888 | mandlock_after); |
874 | } | 889 | } |
875 | 890 | ||
@@ -936,6 +951,13 @@ xfs_access( | |||
936 | 951 | ||
937 | 952 | ||
938 | /* | 953 | /* |
954 | * The maximum pathlen is 1024 bytes. Since the minimum file system | ||
955 | * blocksize is 512 bytes, we can get a max of 2 extents back from | ||
956 | * bmapi. | ||
957 | */ | ||
958 | #define SYMLINK_MAPS 2 | ||
959 | |||
960 | /* | ||
939 | * xfs_readlink | 961 | * xfs_readlink |
940 | * | 962 | * |
941 | */ | 963 | */ |
@@ -950,7 +972,7 @@ xfs_readlink( | |||
950 | int count; | 972 | int count; |
951 | xfs_off_t offset; | 973 | xfs_off_t offset; |
952 | int pathlen; | 974 | int pathlen; |
953 | vnode_t *vp; | 975 | bhv_vnode_t *vp; |
954 | int error = 0; | 976 | int error = 0; |
955 | xfs_mount_t *mp; | 977 | xfs_mount_t *mp; |
956 | int nmaps; | 978 | int nmaps; |
@@ -1000,7 +1022,7 @@ xfs_readlink( | |||
1000 | nmaps = SYMLINK_MAPS; | 1022 | nmaps = SYMLINK_MAPS; |
1001 | 1023 | ||
1002 | error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), | 1024 | error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), |
1003 | 0, NULL, 0, mval, &nmaps, NULL); | 1025 | 0, NULL, 0, mval, &nmaps, NULL, NULL); |
1004 | 1026 | ||
1005 | if (error) { | 1027 | if (error) { |
1006 | goto error_return; | 1028 | goto error_return; |
@@ -1208,8 +1230,8 @@ xfs_inactive_free_eofblocks( | |||
1208 | 1230 | ||
1209 | nimaps = 1; | 1231 | nimaps = 1; |
1210 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 1232 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
1211 | error = xfs_bmapi(NULL, ip, end_fsb, map_len, 0, | 1233 | error = XFS_BMAPI(mp, NULL, &ip->i_iocore, end_fsb, map_len, 0, |
1212 | NULL, 0, &imap, &nimaps, NULL); | 1234 | NULL, 0, &imap, &nimaps, NULL, NULL); |
1213 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 1235 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
1214 | 1236 | ||
1215 | if (!error && (nimaps != 0) && | 1237 | if (!error && (nimaps != 0) && |
@@ -1338,7 +1360,7 @@ xfs_inactive_symlink_rmt( | |||
1338 | nmaps = ARRAY_SIZE(mval); | 1360 | nmaps = ARRAY_SIZE(mval); |
1339 | if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size), | 1361 | if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size), |
1340 | XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps, | 1362 | XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps, |
1341 | &free_list))) | 1363 | &free_list, NULL))) |
1342 | goto error0; | 1364 | goto error0; |
1343 | /* | 1365 | /* |
1344 | * Invalidate the block(s). | 1366 | * Invalidate the block(s). |
@@ -1353,7 +1375,7 @@ xfs_inactive_symlink_rmt( | |||
1353 | * Unmap the dead block(s) to the free_list. | 1375 | * Unmap the dead block(s) to the free_list. |
1354 | */ | 1376 | */ |
1355 | if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps, | 1377 | if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps, |
1356 | &first_block, &free_list, &done))) | 1378 | &first_block, &free_list, NULL, &done))) |
1357 | goto error1; | 1379 | goto error1; |
1358 | ASSERT(done); | 1380 | ASSERT(done); |
1359 | /* | 1381 | /* |
@@ -1469,9 +1491,6 @@ xfs_inactive_symlink_local( | |||
1469 | return 0; | 1491 | return 0; |
1470 | } | 1492 | } |
1471 | 1493 | ||
1472 | /* | ||
1473 | * | ||
1474 | */ | ||
1475 | STATIC int | 1494 | STATIC int |
1476 | xfs_inactive_attrs( | 1495 | xfs_inactive_attrs( |
1477 | xfs_inode_t *ip, | 1496 | xfs_inode_t *ip, |
@@ -1524,16 +1543,16 @@ xfs_release( | |||
1524 | bhv_desc_t *bdp) | 1543 | bhv_desc_t *bdp) |
1525 | { | 1544 | { |
1526 | xfs_inode_t *ip; | 1545 | xfs_inode_t *ip; |
1527 | vnode_t *vp; | 1546 | bhv_vnode_t *vp; |
1528 | xfs_mount_t *mp; | 1547 | xfs_mount_t *mp; |
1529 | int error; | 1548 | int error; |
1530 | 1549 | ||
1531 | vp = BHV_TO_VNODE(bdp); | 1550 | vp = BHV_TO_VNODE(bdp); |
1532 | ip = XFS_BHVTOI(bdp); | 1551 | ip = XFS_BHVTOI(bdp); |
1552 | mp = ip->i_mount; | ||
1533 | 1553 | ||
1534 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) { | 1554 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) |
1535 | return 0; | 1555 | return 0; |
1536 | } | ||
1537 | 1556 | ||
1538 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1557 | /* If this is a read-only mount, don't do this (would generate I/O) */ |
1539 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 1558 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) |
@@ -1545,8 +1564,6 @@ xfs_release( | |||
1545 | return 0; | 1564 | return 0; |
1546 | #endif | 1565 | #endif |
1547 | 1566 | ||
1548 | mp = ip->i_mount; | ||
1549 | |||
1550 | if (ip->i_d.di_nlink != 0) { | 1567 | if (ip->i_d.di_nlink != 0) { |
1551 | if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && | 1568 | if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && |
1552 | ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 || | 1569 | ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 || |
@@ -1579,8 +1596,8 @@ xfs_inactive( | |||
1579 | cred_t *credp) | 1596 | cred_t *credp) |
1580 | { | 1597 | { |
1581 | xfs_inode_t *ip; | 1598 | xfs_inode_t *ip; |
1582 | vnode_t *vp; | 1599 | bhv_vnode_t *vp; |
1583 | xfs_bmap_free_t free_list; | 1600 | xfs_bmap_free_t free_list; |
1584 | xfs_fsblock_t first_block; | 1601 | xfs_fsblock_t first_block; |
1585 | int committed; | 1602 | int committed; |
1586 | xfs_trans_t *tp; | 1603 | xfs_trans_t *tp; |
@@ -1760,7 +1777,7 @@ xfs_inactive( | |||
1760 | cmn_err(CE_NOTE, | 1777 | cmn_err(CE_NOTE, |
1761 | "xfs_inactive: xfs_ifree() returned an error = %d on %s", | 1778 | "xfs_inactive: xfs_ifree() returned an error = %d on %s", |
1762 | error, mp->m_fsname); | 1779 | error, mp->m_fsname); |
1763 | xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); | 1780 | xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); |
1764 | } | 1781 | } |
1765 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); | 1782 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); |
1766 | } else { | 1783 | } else { |
@@ -1795,17 +1812,17 @@ xfs_inactive( | |||
1795 | STATIC int | 1812 | STATIC int |
1796 | xfs_lookup( | 1813 | xfs_lookup( |
1797 | bhv_desc_t *dir_bdp, | 1814 | bhv_desc_t *dir_bdp, |
1798 | vname_t *dentry, | 1815 | bhv_vname_t *dentry, |
1799 | vnode_t **vpp, | 1816 | bhv_vnode_t **vpp, |
1800 | int flags, | 1817 | int flags, |
1801 | vnode_t *rdir, | 1818 | bhv_vnode_t *rdir, |
1802 | cred_t *credp) | 1819 | cred_t *credp) |
1803 | { | 1820 | { |
1804 | xfs_inode_t *dp, *ip; | 1821 | xfs_inode_t *dp, *ip; |
1805 | xfs_ino_t e_inum; | 1822 | xfs_ino_t e_inum; |
1806 | int error; | 1823 | int error; |
1807 | uint lock_mode; | 1824 | uint lock_mode; |
1808 | vnode_t *dir_vp; | 1825 | bhv_vnode_t *dir_vp; |
1809 | 1826 | ||
1810 | dir_vp = BHV_TO_VNODE(dir_bdp); | 1827 | dir_vp = BHV_TO_VNODE(dir_bdp); |
1811 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); | 1828 | vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); |
@@ -1832,15 +1849,15 @@ xfs_lookup( | |||
1832 | STATIC int | 1849 | STATIC int |
1833 | xfs_create( | 1850 | xfs_create( |
1834 | bhv_desc_t *dir_bdp, | 1851 | bhv_desc_t *dir_bdp, |
1835 | vname_t *dentry, | 1852 | bhv_vname_t *dentry, |
1836 | vattr_t *vap, | 1853 | bhv_vattr_t *vap, |
1837 | vnode_t **vpp, | 1854 | bhv_vnode_t **vpp, |
1838 | cred_t *credp) | 1855 | cred_t *credp) |
1839 | { | 1856 | { |
1840 | char *name = VNAME(dentry); | 1857 | char *name = VNAME(dentry); |
1841 | vnode_t *dir_vp; | 1858 | bhv_vnode_t *dir_vp; |
1842 | xfs_inode_t *dp, *ip; | 1859 | xfs_inode_t *dp, *ip; |
1843 | vnode_t *vp=NULL; | 1860 | bhv_vnode_t *vp = NULL; |
1844 | xfs_trans_t *tp; | 1861 | xfs_trans_t *tp; |
1845 | xfs_mount_t *mp; | 1862 | xfs_mount_t *mp; |
1846 | xfs_dev_t rdev; | 1863 | xfs_dev_t rdev; |
@@ -1938,8 +1955,7 @@ xfs_create( | |||
1938 | if (error) | 1955 | if (error) |
1939 | goto error_return; | 1956 | goto error_return; |
1940 | 1957 | ||
1941 | if (resblks == 0 && | 1958 | if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) |
1942 | (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen))) | ||
1943 | goto error_return; | 1959 | goto error_return; |
1944 | rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; | 1960 | rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; |
1945 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, | 1961 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, |
@@ -1970,9 +1986,9 @@ xfs_create( | |||
1970 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 1986 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
1971 | dp_joined_to_trans = B_TRUE; | 1987 | dp_joined_to_trans = B_TRUE; |
1972 | 1988 | ||
1973 | error = XFS_DIR_CREATENAME(mp, tp, dp, name, namelen, ip->i_ino, | 1989 | error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, |
1974 | &first_block, &free_list, | 1990 | &first_block, &free_list, resblks ? |
1975 | resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); | 1991 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); |
1976 | if (error) { | 1992 | if (error) { |
1977 | ASSERT(error != ENOSPC); | 1993 | ASSERT(error != ENOSPC); |
1978 | goto abort_return; | 1994 | goto abort_return; |
@@ -2026,7 +2042,7 @@ xfs_create( | |||
2026 | * Propagate the fact that the vnode changed after the | 2042 | * Propagate the fact that the vnode changed after the |
2027 | * xfs_inode locks have been released. | 2043 | * xfs_inode locks have been released. |
2028 | */ | 2044 | */ |
2029 | VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_TRUNCATED, 3); | 2045 | bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3); |
2030 | 2046 | ||
2031 | *vpp = vp; | 2047 | *vpp = vp; |
2032 | 2048 | ||
@@ -2107,7 +2123,7 @@ int xfs_rm_attempts; | |||
2107 | STATIC int | 2123 | STATIC int |
2108 | xfs_lock_dir_and_entry( | 2124 | xfs_lock_dir_and_entry( |
2109 | xfs_inode_t *dp, | 2125 | xfs_inode_t *dp, |
2110 | vname_t *dentry, | 2126 | bhv_vname_t *dentry, |
2111 | xfs_inode_t *ip) /* inode of entry 'name' */ | 2127 | xfs_inode_t *ip) /* inode of entry 'name' */ |
2112 | { | 2128 | { |
2113 | int attempts; | 2129 | int attempts; |
@@ -2321,10 +2337,10 @@ int remove_which_error_return = 0; | |||
2321 | STATIC int | 2337 | STATIC int |
2322 | xfs_remove( | 2338 | xfs_remove( |
2323 | bhv_desc_t *dir_bdp, | 2339 | bhv_desc_t *dir_bdp, |
2324 | vname_t *dentry, | 2340 | bhv_vname_t *dentry, |
2325 | cred_t *credp) | 2341 | cred_t *credp) |
2326 | { | 2342 | { |
2327 | vnode_t *dir_vp; | 2343 | bhv_vnode_t *dir_vp; |
2328 | char *name = VNAME(dentry); | 2344 | char *name = VNAME(dentry); |
2329 | xfs_inode_t *dp, *ip; | 2345 | xfs_inode_t *dp, *ip; |
2330 | xfs_trans_t *tp = NULL; | 2346 | xfs_trans_t *tp = NULL; |
@@ -2448,8 +2464,8 @@ xfs_remove( | |||
2448 | * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. | 2464 | * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. |
2449 | */ | 2465 | */ |
2450 | XFS_BMAP_INIT(&free_list, &first_block); | 2466 | XFS_BMAP_INIT(&free_list, &first_block); |
2451 | error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, ip->i_ino, | 2467 | error = xfs_dir_removename(tp, dp, name, namelen, ip->i_ino, |
2452 | &first_block, &free_list, 0); | 2468 | &first_block, &free_list, 0); |
2453 | if (error) { | 2469 | if (error) { |
2454 | ASSERT(error != ENOENT); | 2470 | ASSERT(error != ENOENT); |
2455 | REMOVE_DEBUG_TRACE(__LINE__); | 2471 | REMOVE_DEBUG_TRACE(__LINE__); |
@@ -2511,7 +2527,7 @@ xfs_remove( | |||
2511 | /* | 2527 | /* |
2512 | * Let interposed file systems know about removed links. | 2528 | * Let interposed file systems know about removed links. |
2513 | */ | 2529 | */ |
2514 | VOP_LINK_REMOVED(XFS_ITOV(ip), dir_vp, link_zero); | 2530 | bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero); |
2515 | 2531 | ||
2516 | IRELE(ip); | 2532 | IRELE(ip); |
2517 | 2533 | ||
@@ -2564,8 +2580,8 @@ xfs_remove( | |||
2564 | STATIC int | 2580 | STATIC int |
2565 | xfs_link( | 2581 | xfs_link( |
2566 | bhv_desc_t *target_dir_bdp, | 2582 | bhv_desc_t *target_dir_bdp, |
2567 | vnode_t *src_vp, | 2583 | bhv_vnode_t *src_vp, |
2568 | vname_t *dentry, | 2584 | bhv_vname_t *dentry, |
2569 | cred_t *credp) | 2585 | cred_t *credp) |
2570 | { | 2586 | { |
2571 | xfs_inode_t *tdp, *sip; | 2587 | xfs_inode_t *tdp, *sip; |
@@ -2577,7 +2593,7 @@ xfs_link( | |||
2577 | xfs_fsblock_t first_block; | 2593 | xfs_fsblock_t first_block; |
2578 | int cancel_flags; | 2594 | int cancel_flags; |
2579 | int committed; | 2595 | int committed; |
2580 | vnode_t *target_dir_vp; | 2596 | bhv_vnode_t *target_dir_vp; |
2581 | int resblks; | 2597 | int resblks; |
2582 | char *target_name = VNAME(dentry); | 2598 | char *target_name = VNAME(dentry); |
2583 | int target_namelen; | 2599 | int target_namelen; |
@@ -2668,13 +2684,12 @@ xfs_link( | |||
2668 | } | 2684 | } |
2669 | 2685 | ||
2670 | if (resblks == 0 && | 2686 | if (resblks == 0 && |
2671 | (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, | 2687 | (error = xfs_dir_canenter(tp, tdp, target_name, target_namelen))) |
2672 | target_namelen))) | ||
2673 | goto error_return; | 2688 | goto error_return; |
2674 | 2689 | ||
2675 | XFS_BMAP_INIT(&free_list, &first_block); | 2690 | XFS_BMAP_INIT(&free_list, &first_block); |
2676 | 2691 | ||
2677 | error = XFS_DIR_CREATENAME(mp, tp, tdp, target_name, target_namelen, | 2692 | error = xfs_dir_createname(tp, tdp, target_name, target_namelen, |
2678 | sip->i_ino, &first_block, &free_list, | 2693 | sip->i_ino, &first_block, &free_list, |
2679 | resblks); | 2694 | resblks); |
2680 | if (error) | 2695 | if (error) |
@@ -2734,15 +2749,15 @@ std_return: | |||
2734 | STATIC int | 2749 | STATIC int |
2735 | xfs_mkdir( | 2750 | xfs_mkdir( |
2736 | bhv_desc_t *dir_bdp, | 2751 | bhv_desc_t *dir_bdp, |
2737 | vname_t *dentry, | 2752 | bhv_vname_t *dentry, |
2738 | vattr_t *vap, | 2753 | bhv_vattr_t *vap, |
2739 | vnode_t **vpp, | 2754 | bhv_vnode_t **vpp, |
2740 | cred_t *credp) | 2755 | cred_t *credp) |
2741 | { | 2756 | { |
2742 | char *dir_name = VNAME(dentry); | 2757 | char *dir_name = VNAME(dentry); |
2743 | xfs_inode_t *dp; | 2758 | xfs_inode_t *dp; |
2744 | xfs_inode_t *cdp; /* inode of created dir */ | 2759 | xfs_inode_t *cdp; /* inode of created dir */ |
2745 | vnode_t *cvp; /* vnode of created dir */ | 2760 | bhv_vnode_t *cvp; /* vnode of created dir */ |
2746 | xfs_trans_t *tp; | 2761 | xfs_trans_t *tp; |
2747 | xfs_mount_t *mp; | 2762 | xfs_mount_t *mp; |
2748 | int cancel_flags; | 2763 | int cancel_flags; |
@@ -2750,7 +2765,7 @@ xfs_mkdir( | |||
2750 | int committed; | 2765 | int committed; |
2751 | xfs_bmap_free_t free_list; | 2766 | xfs_bmap_free_t free_list; |
2752 | xfs_fsblock_t first_block; | 2767 | xfs_fsblock_t first_block; |
2753 | vnode_t *dir_vp; | 2768 | bhv_vnode_t *dir_vp; |
2754 | boolean_t dp_joined_to_trans; | 2769 | boolean_t dp_joined_to_trans; |
2755 | boolean_t created = B_FALSE; | 2770 | boolean_t created = B_FALSE; |
2756 | int dm_event_sent = 0; | 2771 | int dm_event_sent = 0; |
@@ -2840,7 +2855,7 @@ xfs_mkdir( | |||
2840 | goto error_return; | 2855 | goto error_return; |
2841 | 2856 | ||
2842 | if (resblks == 0 && | 2857 | if (resblks == 0 && |
2843 | (error = XFS_DIR_CANENTER(mp, tp, dp, dir_name, dir_namelen))) | 2858 | (error = xfs_dir_canenter(tp, dp, dir_name, dir_namelen))) |
2844 | goto error_return; | 2859 | goto error_return; |
2845 | /* | 2860 | /* |
2846 | * create the directory inode. | 2861 | * create the directory inode. |
@@ -2867,9 +2882,9 @@ xfs_mkdir( | |||
2867 | 2882 | ||
2868 | XFS_BMAP_INIT(&free_list, &first_block); | 2883 | XFS_BMAP_INIT(&free_list, &first_block); |
2869 | 2884 | ||
2870 | error = XFS_DIR_CREATENAME(mp, tp, dp, dir_name, dir_namelen, | 2885 | error = xfs_dir_createname(tp, dp, dir_name, dir_namelen, cdp->i_ino, |
2871 | cdp->i_ino, &first_block, &free_list, | 2886 | &first_block, &free_list, resblks ? |
2872 | resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); | 2887 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); |
2873 | if (error) { | 2888 | if (error) { |
2874 | ASSERT(error != ENOSPC); | 2889 | ASSERT(error != ENOSPC); |
2875 | goto error1; | 2890 | goto error1; |
@@ -2883,16 +2898,14 @@ xfs_mkdir( | |||
2883 | */ | 2898 | */ |
2884 | dp->i_gen++; | 2899 | dp->i_gen++; |
2885 | 2900 | ||
2886 | error = XFS_DIR_INIT(mp, tp, cdp, dp); | 2901 | error = xfs_dir_init(tp, cdp, dp); |
2887 | if (error) { | 2902 | if (error) |
2888 | goto error2; | 2903 | goto error2; |
2889 | } | ||
2890 | 2904 | ||
2891 | cdp->i_gen = 1; | 2905 | cdp->i_gen = 1; |
2892 | error = xfs_bumplink(tp, dp); | 2906 | error = xfs_bumplink(tp, dp); |
2893 | if (error) { | 2907 | if (error) |
2894 | goto error2; | 2908 | goto error2; |
2895 | } | ||
2896 | 2909 | ||
2897 | cvp = XFS_ITOV(cdp); | 2910 | cvp = XFS_ITOV(cdp); |
2898 | 2911 | ||
@@ -2969,7 +2982,7 @@ std_return: | |||
2969 | STATIC int | 2982 | STATIC int |
2970 | xfs_rmdir( | 2983 | xfs_rmdir( |
2971 | bhv_desc_t *dir_bdp, | 2984 | bhv_desc_t *dir_bdp, |
2972 | vname_t *dentry, | 2985 | bhv_vname_t *dentry, |
2973 | cred_t *credp) | 2986 | cred_t *credp) |
2974 | { | 2987 | { |
2975 | char *name = VNAME(dentry); | 2988 | char *name = VNAME(dentry); |
@@ -2982,7 +2995,7 @@ xfs_rmdir( | |||
2982 | xfs_fsblock_t first_block; | 2995 | xfs_fsblock_t first_block; |
2983 | int cancel_flags; | 2996 | int cancel_flags; |
2984 | int committed; | 2997 | int committed; |
2985 | vnode_t *dir_vp; | 2998 | bhv_vnode_t *dir_vp; |
2986 | int dm_di_mode = 0; | 2999 | int dm_di_mode = 0; |
2987 | int last_cdp_link; | 3000 | int last_cdp_link; |
2988 | int namelen; | 3001 | int namelen; |
@@ -3101,16 +3114,15 @@ xfs_rmdir( | |||
3101 | error = XFS_ERROR(ENOTEMPTY); | 3114 | error = XFS_ERROR(ENOTEMPTY); |
3102 | goto error_return; | 3115 | goto error_return; |
3103 | } | 3116 | } |
3104 | if (!XFS_DIR_ISEMPTY(mp, cdp)) { | 3117 | if (!xfs_dir_isempty(cdp)) { |
3105 | error = XFS_ERROR(ENOTEMPTY); | 3118 | error = XFS_ERROR(ENOTEMPTY); |
3106 | goto error_return; | 3119 | goto error_return; |
3107 | } | 3120 | } |
3108 | 3121 | ||
3109 | error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, cdp->i_ino, | 3122 | error = xfs_dir_removename(tp, dp, name, namelen, cdp->i_ino, |
3110 | &first_block, &free_list, resblks); | 3123 | &first_block, &free_list, resblks); |
3111 | if (error) { | 3124 | if (error) |
3112 | goto error1; | 3125 | goto error1; |
3113 | } | ||
3114 | 3126 | ||
3115 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 3127 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
3116 | 3128 | ||
@@ -3181,7 +3193,7 @@ xfs_rmdir( | |||
3181 | /* | 3193 | /* |
3182 | * Let interposed file systems know about removed links. | 3194 | * Let interposed file systems know about removed links. |
3183 | */ | 3195 | */ |
3184 | VOP_LINK_REMOVED(XFS_ITOV(cdp), dir_vp, last_cdp_link); | 3196 | bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link); |
3185 | 3197 | ||
3186 | IRELE(cdp); | 3198 | IRELE(cdp); |
3187 | 3199 | ||
@@ -3209,8 +3221,6 @@ xfs_rmdir( | |||
3209 | 3221 | ||
3210 | 3222 | ||
3211 | /* | 3223 | /* |
3212 | * xfs_readdir | ||
3213 | * | ||
3214 | * Read dp's entries starting at uiop->uio_offset and translate them into | 3224 | * Read dp's entries starting at uiop->uio_offset and translate them into |
3215 | * bufsize bytes worth of struct dirents starting at bufbase. | 3225 | * bufsize bytes worth of struct dirents starting at bufbase. |
3216 | */ | 3226 | */ |
@@ -3230,28 +3240,23 @@ xfs_readdir( | |||
3230 | (inst_t *)__return_address); | 3240 | (inst_t *)__return_address); |
3231 | dp = XFS_BHVTOI(dir_bdp); | 3241 | dp = XFS_BHVTOI(dir_bdp); |
3232 | 3242 | ||
3233 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) { | 3243 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
3234 | return XFS_ERROR(EIO); | 3244 | return XFS_ERROR(EIO); |
3235 | } | ||
3236 | 3245 | ||
3237 | lock_mode = xfs_ilock_map_shared(dp); | 3246 | lock_mode = xfs_ilock_map_shared(dp); |
3238 | error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp); | 3247 | error = xfs_dir_getdents(tp, dp, uiop, eofp); |
3239 | xfs_iunlock_map_shared(dp, lock_mode); | 3248 | xfs_iunlock_map_shared(dp, lock_mode); |
3240 | return error; | 3249 | return error; |
3241 | } | 3250 | } |
3242 | 3251 | ||
3243 | 3252 | ||
3244 | /* | ||
3245 | * xfs_symlink | ||
3246 | * | ||
3247 | */ | ||
3248 | STATIC int | 3253 | STATIC int |
3249 | xfs_symlink( | 3254 | xfs_symlink( |
3250 | bhv_desc_t *dir_bdp, | 3255 | bhv_desc_t *dir_bdp, |
3251 | vname_t *dentry, | 3256 | bhv_vname_t *dentry, |
3252 | vattr_t *vap, | 3257 | bhv_vattr_t *vap, |
3253 | char *target_path, | 3258 | char *target_path, |
3254 | vnode_t **vpp, | 3259 | bhv_vnode_t **vpp, |
3255 | cred_t *credp) | 3260 | cred_t *credp) |
3256 | { | 3261 | { |
3257 | xfs_trans_t *tp; | 3262 | xfs_trans_t *tp; |
@@ -3263,7 +3268,7 @@ xfs_symlink( | |||
3263 | xfs_bmap_free_t free_list; | 3268 | xfs_bmap_free_t free_list; |
3264 | xfs_fsblock_t first_block; | 3269 | xfs_fsblock_t first_block; |
3265 | boolean_t dp_joined_to_trans; | 3270 | boolean_t dp_joined_to_trans; |
3266 | vnode_t *dir_vp; | 3271 | bhv_vnode_t *dir_vp; |
3267 | uint cancel_flags; | 3272 | uint cancel_flags; |
3268 | int committed; | 3273 | int committed; |
3269 | xfs_fileoff_t first_fsb; | 3274 | xfs_fileoff_t first_fsb; |
@@ -3308,7 +3313,7 @@ xfs_symlink( | |||
3308 | int len, total; | 3313 | int len, total; |
3309 | char *path; | 3314 | char *path; |
3310 | 3315 | ||
3311 | for(total = 0, path = target_path; total < pathlen;) { | 3316 | for (total = 0, path = target_path; total < pathlen;) { |
3312 | /* | 3317 | /* |
3313 | * Skip any slashes. | 3318 | * Skip any slashes. |
3314 | */ | 3319 | */ |
@@ -3402,7 +3407,7 @@ xfs_symlink( | |||
3402 | * Check for ability to enter directory entry, if no space reserved. | 3407 | * Check for ability to enter directory entry, if no space reserved. |
3403 | */ | 3408 | */ |
3404 | if (resblks == 0 && | 3409 | if (resblks == 0 && |
3405 | (error = XFS_DIR_CANENTER(mp, tp, dp, link_name, link_namelen))) | 3410 | (error = xfs_dir_canenter(tp, dp, link_name, link_namelen))) |
3406 | goto error_return; | 3411 | goto error_return; |
3407 | /* | 3412 | /* |
3408 | * Initialize the bmap freelist prior to calling either | 3413 | * Initialize the bmap freelist prior to calling either |
@@ -3457,7 +3462,7 @@ xfs_symlink( | |||
3457 | error = xfs_bmapi(tp, ip, first_fsb, fs_blocks, | 3462 | error = xfs_bmapi(tp, ip, first_fsb, fs_blocks, |
3458 | XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, | 3463 | XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, |
3459 | &first_block, resblks, mval, &nmaps, | 3464 | &first_block, resblks, mval, &nmaps, |
3460 | &free_list); | 3465 | &free_list, NULL); |
3461 | if (error) { | 3466 | if (error) { |
3462 | goto error1; | 3467 | goto error1; |
3463 | } | 3468 | } |
@@ -3489,11 +3494,10 @@ xfs_symlink( | |||
3489 | /* | 3494 | /* |
3490 | * Create the directory entry for the symlink. | 3495 | * Create the directory entry for the symlink. |
3491 | */ | 3496 | */ |
3492 | error = XFS_DIR_CREATENAME(mp, tp, dp, link_name, link_namelen, | 3497 | error = xfs_dir_createname(tp, dp, link_name, link_namelen, ip->i_ino, |
3493 | ip->i_ino, &first_block, &free_list, resblks); | 3498 | &first_block, &free_list, resblks); |
3494 | if (error) { | 3499 | if (error) |
3495 | goto error1; | 3500 | goto error1; |
3496 | } | ||
3497 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 3501 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
3498 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | 3502 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); |
3499 | 3503 | ||
@@ -3541,7 +3545,7 @@ std_return: | |||
3541 | } | 3545 | } |
3542 | 3546 | ||
3543 | if (!error) { | 3547 | if (!error) { |
3544 | vnode_t *vp; | 3548 | bhv_vnode_t *vp; |
3545 | 3549 | ||
3546 | ASSERT(ip); | 3550 | ASSERT(ip); |
3547 | vp = XFS_ITOV(ip); | 3551 | vp = XFS_ITOV(ip); |
@@ -3606,10 +3610,10 @@ xfs_fid2( | |||
3606 | int | 3610 | int |
3607 | xfs_rwlock( | 3611 | xfs_rwlock( |
3608 | bhv_desc_t *bdp, | 3612 | bhv_desc_t *bdp, |
3609 | vrwlock_t locktype) | 3613 | bhv_vrwlock_t locktype) |
3610 | { | 3614 | { |
3611 | xfs_inode_t *ip; | 3615 | xfs_inode_t *ip; |
3612 | vnode_t *vp; | 3616 | bhv_vnode_t *vp; |
3613 | 3617 | ||
3614 | vp = BHV_TO_VNODE(bdp); | 3618 | vp = BHV_TO_VNODE(bdp); |
3615 | if (VN_ISDIR(vp)) | 3619 | if (VN_ISDIR(vp)) |
@@ -3637,10 +3641,10 @@ xfs_rwlock( | |||
3637 | void | 3641 | void |
3638 | xfs_rwunlock( | 3642 | xfs_rwunlock( |
3639 | bhv_desc_t *bdp, | 3643 | bhv_desc_t *bdp, |
3640 | vrwlock_t locktype) | 3644 | bhv_vrwlock_t locktype) |
3641 | { | 3645 | { |
3642 | xfs_inode_t *ip; | 3646 | xfs_inode_t *ip; |
3643 | vnode_t *vp; | 3647 | bhv_vnode_t *vp; |
3644 | 3648 | ||
3645 | vp = BHV_TO_VNODE(bdp); | 3649 | vp = BHV_TO_VNODE(bdp); |
3646 | if (VN_ISDIR(vp)) | 3650 | if (VN_ISDIR(vp)) |
@@ -3744,7 +3748,6 @@ xfs_inode_flush( | |||
3744 | return error; | 3748 | return error; |
3745 | } | 3749 | } |
3746 | 3750 | ||
3747 | |||
3748 | int | 3751 | int |
3749 | xfs_set_dmattrs ( | 3752 | xfs_set_dmattrs ( |
3750 | bhv_desc_t *bdp, | 3753 | bhv_desc_t *bdp, |
@@ -3785,16 +3788,12 @@ xfs_set_dmattrs ( | |||
3785 | return error; | 3788 | return error; |
3786 | } | 3789 | } |
3787 | 3790 | ||
3788 | |||
3789 | /* | ||
3790 | * xfs_reclaim | ||
3791 | */ | ||
3792 | STATIC int | 3791 | STATIC int |
3793 | xfs_reclaim( | 3792 | xfs_reclaim( |
3794 | bhv_desc_t *bdp) | 3793 | bhv_desc_t *bdp) |
3795 | { | 3794 | { |
3796 | xfs_inode_t *ip; | 3795 | xfs_inode_t *ip; |
3797 | vnode_t *vp; | 3796 | bhv_vnode_t *vp; |
3798 | 3797 | ||
3799 | vp = BHV_TO_VNODE(bdp); | 3798 | vp = BHV_TO_VNODE(bdp); |
3800 | ip = XFS_BHVTOI(bdp); | 3799 | ip = XFS_BHVTOI(bdp); |
@@ -3849,7 +3848,7 @@ xfs_finish_reclaim( | |||
3849 | int sync_mode) | 3848 | int sync_mode) |
3850 | { | 3849 | { |
3851 | xfs_ihash_t *ih = ip->i_hash; | 3850 | xfs_ihash_t *ih = ip->i_hash; |
3852 | vnode_t *vp = XFS_ITOV_NULL(ip); | 3851 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); |
3853 | int error; | 3852 | int error; |
3854 | 3853 | ||
3855 | if (vp && VN_BAD(vp)) | 3854 | if (vp && VN_BAD(vp)) |
@@ -4116,10 +4115,10 @@ retry: | |||
4116 | * Issue the xfs_bmapi() call to allocate the blocks | 4115 | * Issue the xfs_bmapi() call to allocate the blocks |
4117 | */ | 4116 | */ |
4118 | XFS_BMAP_INIT(&free_list, &firstfsb); | 4117 | XFS_BMAP_INIT(&free_list, &firstfsb); |
4119 | error = xfs_bmapi(tp, ip, startoffset_fsb, | 4118 | error = XFS_BMAPI(mp, tp, &ip->i_iocore, startoffset_fsb, |
4120 | allocatesize_fsb, bmapi_flag, | 4119 | allocatesize_fsb, bmapi_flag, |
4121 | &firstfsb, 0, imapp, &nimaps, | 4120 | &firstfsb, 0, imapp, &nimaps, |
4122 | &free_list); | 4121 | &free_list, NULL); |
4123 | if (error) { | 4122 | if (error) { |
4124 | goto error0; | 4123 | goto error0; |
4125 | } | 4124 | } |
@@ -4199,8 +4198,8 @@ xfs_zero_remaining_bytes( | |||
4199 | for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { | 4198 | for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { |
4200 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 4199 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
4201 | nimap = 1; | 4200 | nimap = 1; |
4202 | error = xfs_bmapi(NULL, ip, offset_fsb, 1, 0, NULL, 0, &imap, | 4201 | error = XFS_BMAPI(mp, NULL, &ip->i_iocore, offset_fsb, 1, 0, |
4203 | &nimap, NULL); | 4202 | NULL, 0, &imap, &nimap, NULL, NULL); |
4204 | if (error || nimap < 1) | 4203 | if (error || nimap < 1) |
4205 | break; | 4204 | break; |
4206 | ASSERT(imap.br_blockcount >= 1); | 4205 | ASSERT(imap.br_blockcount >= 1); |
@@ -4259,7 +4258,7 @@ xfs_free_file_space( | |||
4259 | xfs_off_t len, | 4258 | xfs_off_t len, |
4260 | int attr_flags) | 4259 | int attr_flags) |
4261 | { | 4260 | { |
4262 | vnode_t *vp; | 4261 | bhv_vnode_t *vp; |
4263 | int committed; | 4262 | int committed; |
4264 | int done; | 4263 | int done; |
4265 | xfs_off_t end_dmi_offset; | 4264 | xfs_off_t end_dmi_offset; |
@@ -4308,7 +4307,6 @@ xfs_free_file_space( | |||
4308 | return error; | 4307 | return error; |
4309 | } | 4308 | } |
4310 | 4309 | ||
4311 | ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1); | ||
4312 | if (attr_flags & ATTR_NOLOCK) | 4310 | if (attr_flags & ATTR_NOLOCK) |
4313 | need_iolock = 0; | 4311 | need_iolock = 0; |
4314 | if (need_iolock) { | 4312 | if (need_iolock) { |
@@ -4326,7 +4324,7 @@ xfs_free_file_space( | |||
4326 | if (VN_CACHED(vp) != 0) { | 4324 | if (VN_CACHED(vp) != 0) { |
4327 | xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, | 4325 | xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, |
4328 | ctooff(offtoct(ioffset)), -1); | 4326 | ctooff(offtoct(ioffset)), -1); |
4329 | VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)), | 4327 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)), |
4330 | -1, FI_REMAPF_LOCKED); | 4328 | -1, FI_REMAPF_LOCKED); |
4331 | } | 4329 | } |
4332 | 4330 | ||
@@ -4338,8 +4336,8 @@ xfs_free_file_space( | |||
4338 | */ | 4336 | */ |
4339 | if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { | 4337 | if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { |
4340 | nimap = 1; | 4338 | nimap = 1; |
4341 | error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0, | 4339 | error = XFS_BMAPI(mp, NULL, &ip->i_iocore, startoffset_fsb, |
4342 | &imap, &nimap, NULL); | 4340 | 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); |
4343 | if (error) | 4341 | if (error) |
4344 | goto out_unlock_iolock; | 4342 | goto out_unlock_iolock; |
4345 | ASSERT(nimap == 0 || nimap == 1); | 4343 | ASSERT(nimap == 0 || nimap == 1); |
@@ -4353,8 +4351,8 @@ xfs_free_file_space( | |||
4353 | startoffset_fsb += mp->m_sb.sb_rextsize - mod; | 4351 | startoffset_fsb += mp->m_sb.sb_rextsize - mod; |
4354 | } | 4352 | } |
4355 | nimap = 1; | 4353 | nimap = 1; |
4356 | error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, 1, 0, NULL, 0, | 4354 | error = XFS_BMAPI(mp, NULL, &ip->i_iocore, endoffset_fsb - 1, |
4357 | &imap, &nimap, NULL); | 4355 | 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); |
4358 | if (error) | 4356 | if (error) |
4359 | goto out_unlock_iolock; | 4357 | goto out_unlock_iolock; |
4360 | ASSERT(nimap == 0 || nimap == 1); | 4358 | ASSERT(nimap == 0 || nimap == 1); |
@@ -4426,9 +4424,9 @@ xfs_free_file_space( | |||
4426 | * issue the bunmapi() call to free the blocks | 4424 | * issue the bunmapi() call to free the blocks |
4427 | */ | 4425 | */ |
4428 | XFS_BMAP_INIT(&free_list, &firstfsb); | 4426 | XFS_BMAP_INIT(&free_list, &firstfsb); |
4429 | error = xfs_bunmapi(tp, ip, startoffset_fsb, | 4427 | error = XFS_BUNMAPI(mp, tp, &ip->i_iocore, startoffset_fsb, |
4430 | endoffset_fsb - startoffset_fsb, | 4428 | endoffset_fsb - startoffset_fsb, |
4431 | 0, 2, &firstfsb, &free_list, &done); | 4429 | 0, 2, &firstfsb, &free_list, NULL, &done); |
4432 | if (error) { | 4430 | if (error) { |
4433 | goto error0; | 4431 | goto error0; |
4434 | } | 4432 | } |
@@ -4488,8 +4486,8 @@ xfs_change_file_space( | |||
4488 | xfs_off_t startoffset; | 4486 | xfs_off_t startoffset; |
4489 | xfs_off_t llen; | 4487 | xfs_off_t llen; |
4490 | xfs_trans_t *tp; | 4488 | xfs_trans_t *tp; |
4491 | vattr_t va; | 4489 | bhv_vattr_t va; |
4492 | vnode_t *vp; | 4490 | bhv_vnode_t *vp; |
4493 | 4491 | ||
4494 | vp = BHV_TO_VNODE(bdp); | 4492 | vp = BHV_TO_VNODE(bdp); |
4495 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 4493 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
@@ -4642,9 +4640,10 @@ xfs_change_file_space( | |||
4642 | return error; | 4640 | return error; |
4643 | } | 4641 | } |
4644 | 4642 | ||
4645 | vnodeops_t xfs_vnodeops = { | 4643 | bhv_vnodeops_t xfs_vnodeops = { |
4646 | BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), | 4644 | BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), |
4647 | .vop_open = xfs_open, | 4645 | .vop_open = xfs_open, |
4646 | .vop_close = xfs_close, | ||
4648 | .vop_read = xfs_read, | 4647 | .vop_read = xfs_read, |
4649 | #ifdef HAVE_SENDFILE | 4648 | #ifdef HAVE_SENDFILE |
4650 | .vop_sendfile = xfs_sendfile, | 4649 | .vop_sendfile = xfs_sendfile, |