Commit 742ae1e35b038ed65ddd86182723441ea74db765

Authored by Dave Chinner
Committed by Ben Myers
1 parent cab09a81fb

xfs: introduce CONFIG_XFS_WARN

Running a CONFIG_XFS_DEBUG kernel in production environments is not
the best idea as it introduces significant overhead, can change
the behaviour of algorithms (such as allocation) to improve test
coverage, and (most importantly) panic the machine on non-fatal
errors.

There are many cases where all we want to do is run a
kernel with more bounds checking enabled, such as is provided by the
ASSERT() statements throughout the code, but without all the
potential overhead and drawbacks.

This patch converts all the ASSERT statements to evaluate as
WARN_ON(1) statements and hence if they fail dump a warning and a
stack trace to the log. This has minimal overhead and does not
change any algorithms, and will allow us to find strange "out of
bounds" problems more easily on production machines.

There are a few places where assert statements contain debug only
code. These are converted to be debug-or-warn only code so that we
still get all the assert checks in the code.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>

Showing 13 changed files with 63 additions and 24 deletions Inline Diff

1 config XFS_FS 1 config XFS_FS
2 tristate "XFS filesystem support" 2 tristate "XFS filesystem support"
3 depends on BLOCK 3 depends on BLOCK
4 select EXPORTFS 4 select EXPORTFS
5 select LIBCRC32C 5 select LIBCRC32C
6 help 6 help
7 XFS is a high performance journaling filesystem which originated 7 XFS is a high performance journaling filesystem which originated
8 on the SGI IRIX platform. It is completely multi-threaded, can 8 on the SGI IRIX platform. It is completely multi-threaded, can
9 support large files and large filesystems, extended attributes, 9 support large files and large filesystems, extended attributes,
10 variable block sizes, is extent based, and makes extensive use of 10 variable block sizes, is extent based, and makes extensive use of
11 Btrees (directories, extents, free space) to aid both performance 11 Btrees (directories, extents, free space) to aid both performance
12 and scalability. 12 and scalability.
13 13
14 Refer to the documentation at <http://oss.sgi.com/projects/xfs/> 14 Refer to the documentation at <http://oss.sgi.com/projects/xfs/>
15 for complete details. This implementation is on-disk compatible 15 for complete details. This implementation is on-disk compatible
16 with the IRIX version of XFS. 16 with the IRIX version of XFS.
17 17
18 To compile this file system support as a module, choose M here: the 18 To compile this file system support as a module, choose M here: the
19 module will be called xfs. Be aware, however, that if the file 19 module will be called xfs. Be aware, however, that if the file
20 system of your root partition is compiled as a module, you'll need 20 system of your root partition is compiled as a module, you'll need
21 to use an initial ramdisk (initrd) to boot. 21 to use an initial ramdisk (initrd) to boot.
22 22
23 config XFS_QUOTA 23 config XFS_QUOTA
24 bool "XFS Quota support" 24 bool "XFS Quota support"
25 depends on XFS_FS 25 depends on XFS_FS
26 select QUOTACTL 26 select QUOTACTL
27 help 27 help
28 If you say Y here, you will be able to set limits for disk usage on 28 If you say Y here, you will be able to set limits for disk usage on
29 a per user and/or a per group basis under XFS. XFS considers quota 29 a per user and/or a per group basis under XFS. XFS considers quota
30 information as filesystem metadata and uses journaling to provide a 30 information as filesystem metadata and uses journaling to provide a
31 higher level guarantee of consistency. The on-disk data format for 31 higher level guarantee of consistency. The on-disk data format for
32 quota is also compatible with the IRIX version of XFS, allowing a 32 quota is also compatible with the IRIX version of XFS, allowing a
33 filesystem to be migrated between Linux and IRIX without any need 33 filesystem to be migrated between Linux and IRIX without any need
34 for conversion. 34 for conversion.
35 35
36 If unsure, say N. More comprehensive documentation can be found in 36 If unsure, say N. More comprehensive documentation can be found in
37 README.quota in the xfsprogs package. XFS quota can be used either 37 README.quota in the xfsprogs package. XFS quota can be used either
38 with or without the generic quota support enabled (CONFIG_QUOTA) - 38 with or without the generic quota support enabled (CONFIG_QUOTA) -
39 they are completely independent subsystems. 39 they are completely independent subsystems.
40 40
41 config XFS_POSIX_ACL 41 config XFS_POSIX_ACL
42 bool "XFS POSIX ACL support" 42 bool "XFS POSIX ACL support"
43 depends on XFS_FS 43 depends on XFS_FS
44 select FS_POSIX_ACL 44 select FS_POSIX_ACL
45 help 45 help
46 POSIX Access Control Lists (ACLs) support permissions for users and 46 POSIX Access Control Lists (ACLs) support permissions for users and
47 groups beyond the owner/group/world scheme. 47 groups beyond the owner/group/world scheme.
48 48
49 To learn more about Access Control Lists, visit the POSIX ACLs for 49 To learn more about Access Control Lists, visit the POSIX ACLs for
50 Linux website <http://acl.bestbits.at/>. 50 Linux website <http://acl.bestbits.at/>.
51 51
52 If you don't know what Access Control Lists are, say N. 52 If you don't know what Access Control Lists are, say N.
53 53
54 config XFS_RT 54 config XFS_RT
55 bool "XFS Realtime subvolume support" 55 bool "XFS Realtime subvolume support"
56 depends on XFS_FS 56 depends on XFS_FS
57 help 57 help
58 If you say Y here you will be able to mount and use XFS filesystems 58 If you say Y here you will be able to mount and use XFS filesystems
59 which contain a realtime subvolume. The realtime subvolume is a 59 which contain a realtime subvolume. The realtime subvolume is a
60 separate area of disk space where only file data is stored. It was 60 separate area of disk space where only file data is stored. It was
61 originally designed to provide deterministic data rates suitable 61 originally designed to provide deterministic data rates suitable
62 for media streaming applications, but is also useful as a generic 62 for media streaming applications, but is also useful as a generic
63 mechanism for ensuring data and metadata/log I/Os are completely 63 mechanism for ensuring data and metadata/log I/Os are completely
64 separated. Regular file I/Os are isolated to a separate device 64 separated. Regular file I/Os are isolated to a separate device
65 from all other requests, and this can be done quite transparently 65 from all other requests, and this can be done quite transparently
66 to applications via the inherit-realtime directory inode flag. 66 to applications via the inherit-realtime directory inode flag.
67 67
68 See the xfs man page in section 5 for additional information. 68 See the xfs man page in section 5 for additional information.
69 69
70 If unsure, say N. 70 If unsure, say N.
71 71
72 config XFS_WARN
73 bool "XFS Verbose Warnings"
74 depends on XFS_FS && !XFS_DEBUG
75 help
76 Say Y here to get an XFS build with many additional warnings.
77 It converts ASSERT checks to WARN, so will log any out-of-bounds
78 conditions that occur that would otherwise be missed. It is much
79 lighter weight than XFS_DEBUG and does not modify algorithms and will
80 not cause the kernel to panic on non-fatal errors.
81
82 However, similar to XFS_DEBUG, it is only advisable to use this if you
83 are debugging a particular problem.
84
72 config XFS_DEBUG 85 config XFS_DEBUG
73 bool "XFS Debugging support" 86 bool "XFS Debugging support"
74 depends on XFS_FS 87 depends on XFS_FS
75 help 88 help
76 Say Y here to get an XFS build with many debugging features, 89 Say Y here to get an XFS build with many debugging features,
77 including ASSERT checks, function wrappers around macros, 90 including ASSERT checks, function wrappers around macros,
78 and extra sanity-checking functions in various code paths. 91 and extra sanity-checking functions in various code paths.
79 92
80 Note that the resulting code will be HUGE and SLOW, and probably 93 Note that the resulting code will be HUGE and SLOW, and probably
81 not useful unless you are debugging a particular problem. 94 not useful unless you are debugging a particular problem.
82 95
83 Say N unless you are an XFS developer, or you play one on TV. 96 Say N unless you are an XFS developer, or you play one on TV.
84 97
1 /* 1 /*
2 * Copyright (c) 2000-2006 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
6 * modify it under the terms of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
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 */ 17 */
18 #ifndef __XFS_SUPPORT_MRLOCK_H__ 18 #ifndef __XFS_SUPPORT_MRLOCK_H__
19 #define __XFS_SUPPORT_MRLOCK_H__ 19 #define __XFS_SUPPORT_MRLOCK_H__
20 20
21 #include <linux/rwsem.h> 21 #include <linux/rwsem.h>
22 22
23 typedef struct { 23 typedef struct {
24 struct rw_semaphore mr_lock; 24 struct rw_semaphore mr_lock;
25 #ifdef DEBUG 25 #if defined(DEBUG) || defined(XFS_WARN)
26 int mr_writer; 26 int mr_writer;
27 #endif 27 #endif
28 } mrlock_t; 28 } mrlock_t;
29 29
30 #ifdef DEBUG 30 #if defined(DEBUG) || defined(XFS_WARN)
31 #define mrinit(mrp, name) \ 31 #define mrinit(mrp, name) \
32 do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0) 32 do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
33 #else 33 #else
34 #define mrinit(mrp, name) \ 34 #define mrinit(mrp, name) \
35 do { init_rwsem(&(mrp)->mr_lock); } while (0) 35 do { init_rwsem(&(mrp)->mr_lock); } while (0)
36 #endif 36 #endif
37 37
38 #define mrlock_init(mrp, t,n,s) mrinit(mrp, n) 38 #define mrlock_init(mrp, t,n,s) mrinit(mrp, n)
39 #define mrfree(mrp) do { } while (0) 39 #define mrfree(mrp) do { } while (0)
40 40
41 static inline void mraccess_nested(mrlock_t *mrp, int subclass) 41 static inline void mraccess_nested(mrlock_t *mrp, int subclass)
42 { 42 {
43 down_read_nested(&mrp->mr_lock, subclass); 43 down_read_nested(&mrp->mr_lock, subclass);
44 } 44 }
45 45
46 static inline void mrupdate_nested(mrlock_t *mrp, int subclass) 46 static inline void mrupdate_nested(mrlock_t *mrp, int subclass)
47 { 47 {
48 down_write_nested(&mrp->mr_lock, subclass); 48 down_write_nested(&mrp->mr_lock, subclass);
49 #ifdef DEBUG 49 #if defined(DEBUG) || defined(XFS_WARN)
50 mrp->mr_writer = 1; 50 mrp->mr_writer = 1;
51 #endif 51 #endif
52 } 52 }
53 53
54 static inline int mrtryaccess(mrlock_t *mrp) 54 static inline int mrtryaccess(mrlock_t *mrp)
55 { 55 {
56 return down_read_trylock(&mrp->mr_lock); 56 return down_read_trylock(&mrp->mr_lock);
57 } 57 }
58 58
59 static inline int mrtryupdate(mrlock_t *mrp) 59 static inline int mrtryupdate(mrlock_t *mrp)
60 { 60 {
61 if (!down_write_trylock(&mrp->mr_lock)) 61 if (!down_write_trylock(&mrp->mr_lock))
62 return 0; 62 return 0;
63 #ifdef DEBUG 63 #if defined(DEBUG) || defined(XFS_WARN)
64 mrp->mr_writer = 1; 64 mrp->mr_writer = 1;
65 #endif 65 #endif
66 return 1; 66 return 1;
67 } 67 }
68 68
69 static inline void mrunlock_excl(mrlock_t *mrp) 69 static inline void mrunlock_excl(mrlock_t *mrp)
70 { 70 {
71 #ifdef DEBUG 71 #if defined(DEBUG) || defined(XFS_WARN)
72 mrp->mr_writer = 0; 72 mrp->mr_writer = 0;
73 #endif 73 #endif
74 up_write(&mrp->mr_lock); 74 up_write(&mrp->mr_lock);
75 } 75 }
76 76
77 static inline void mrunlock_shared(mrlock_t *mrp) 77 static inline void mrunlock_shared(mrlock_t *mrp)
78 { 78 {
79 up_read(&mrp->mr_lock); 79 up_read(&mrp->mr_lock);
80 } 80 }
81 81
82 static inline void mrdemote(mrlock_t *mrp) 82 static inline void mrdemote(mrlock_t *mrp)
83 { 83 {
84 #ifdef DEBUG 84 #if defined(DEBUG) || defined(XFS_WARN)
85 mrp->mr_writer = 0; 85 mrp->mr_writer = 0;
86 #endif 86 #endif
87 downgrade_write(&mrp->mr_lock); 87 downgrade_write(&mrp->mr_lock);
88 } 88 }
89 89
90 #endif /* __XFS_SUPPORT_MRLOCK_H__ */ 90 #endif /* __XFS_SUPPORT_MRLOCK_H__ */
91 91
1 /* 1 /*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2003,2005 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
6 * modify it under the terms of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
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 */ 17 */
18 #ifndef __XFS_H__ 18 #ifndef __XFS_H__
19 #define __XFS_H__ 19 #define __XFS_H__
20 20
21 #ifdef CONFIG_XFS_DEBUG 21 #ifdef CONFIG_XFS_DEBUG
22 #define STATIC 22 #define STATIC
23 #define DEBUG 1 23 #define DEBUG 1
24 #define XFS_BUF_LOCK_TRACKING 1 24 #define XFS_BUF_LOCK_TRACKING 1
25 #endif 25 #endif
26 26
27 #ifdef CONFIG_XFS_WARN
28 #define XFS_WARN 1
29 #endif
30
31
27 #include "xfs_linux.h" 32 #include "xfs_linux.h"
28 33
29 #endif /* __XFS_H__ */ 34 #endif /* __XFS_H__ */
30 35
fs/xfs/xfs_alloc_btree.c
1 /* 1 /*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2001,2005 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
6 * modify it under the terms of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
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 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_log.h" 21 #include "xfs_log.h"
22 #include "xfs_trans.h" 22 #include "xfs_trans.h"
23 #include "xfs_sb.h" 23 #include "xfs_sb.h"
24 #include "xfs_ag.h" 24 #include "xfs_ag.h"
25 #include "xfs_mount.h" 25 #include "xfs_mount.h"
26 #include "xfs_bmap_btree.h" 26 #include "xfs_bmap_btree.h"
27 #include "xfs_alloc_btree.h" 27 #include "xfs_alloc_btree.h"
28 #include "xfs_ialloc_btree.h" 28 #include "xfs_ialloc_btree.h"
29 #include "xfs_dinode.h" 29 #include "xfs_dinode.h"
30 #include "xfs_inode.h" 30 #include "xfs_inode.h"
31 #include "xfs_btree.h" 31 #include "xfs_btree.h"
32 #include "xfs_alloc.h" 32 #include "xfs_alloc.h"
33 #include "xfs_extent_busy.h" 33 #include "xfs_extent_busy.h"
34 #include "xfs_error.h" 34 #include "xfs_error.h"
35 #include "xfs_trace.h" 35 #include "xfs_trace.h"
36 #include "xfs_cksum.h" 36 #include "xfs_cksum.h"
37 37
38 38
39 STATIC struct xfs_btree_cur * 39 STATIC struct xfs_btree_cur *
40 xfs_allocbt_dup_cursor( 40 xfs_allocbt_dup_cursor(
41 struct xfs_btree_cur *cur) 41 struct xfs_btree_cur *cur)
42 { 42 {
43 return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp, 43 return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp,
44 cur->bc_private.a.agbp, cur->bc_private.a.agno, 44 cur->bc_private.a.agbp, cur->bc_private.a.agno,
45 cur->bc_btnum); 45 cur->bc_btnum);
46 } 46 }
47 47
48 STATIC void 48 STATIC void
49 xfs_allocbt_set_root( 49 xfs_allocbt_set_root(
50 struct xfs_btree_cur *cur, 50 struct xfs_btree_cur *cur,
51 union xfs_btree_ptr *ptr, 51 union xfs_btree_ptr *ptr,
52 int inc) 52 int inc)
53 { 53 {
54 struct xfs_buf *agbp = cur->bc_private.a.agbp; 54 struct xfs_buf *agbp = cur->bc_private.a.agbp;
55 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); 55 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
56 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); 56 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
57 int btnum = cur->bc_btnum; 57 int btnum = cur->bc_btnum;
58 struct xfs_perag *pag = xfs_perag_get(cur->bc_mp, seqno); 58 struct xfs_perag *pag = xfs_perag_get(cur->bc_mp, seqno);
59 59
60 ASSERT(ptr->s != 0); 60 ASSERT(ptr->s != 0);
61 61
62 agf->agf_roots[btnum] = ptr->s; 62 agf->agf_roots[btnum] = ptr->s;
63 be32_add_cpu(&agf->agf_levels[btnum], inc); 63 be32_add_cpu(&agf->agf_levels[btnum], inc);
64 pag->pagf_levels[btnum] += inc; 64 pag->pagf_levels[btnum] += inc;
65 xfs_perag_put(pag); 65 xfs_perag_put(pag);
66 66
67 xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); 67 xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
68 } 68 }
69 69
70 STATIC int 70 STATIC int
71 xfs_allocbt_alloc_block( 71 xfs_allocbt_alloc_block(
72 struct xfs_btree_cur *cur, 72 struct xfs_btree_cur *cur,
73 union xfs_btree_ptr *start, 73 union xfs_btree_ptr *start,
74 union xfs_btree_ptr *new, 74 union xfs_btree_ptr *new,
75 int length, 75 int length,
76 int *stat) 76 int *stat)
77 { 77 {
78 int error; 78 int error;
79 xfs_agblock_t bno; 79 xfs_agblock_t bno;
80 80
81 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 81 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
82 82
83 /* Allocate the new block from the freelist. If we can't, give up. */ 83 /* Allocate the new block from the freelist. If we can't, give up. */
84 error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp, 84 error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp,
85 &bno, 1); 85 &bno, 1);
86 if (error) { 86 if (error) {
87 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 87 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
88 return error; 88 return error;
89 } 89 }
90 90
91 if (bno == NULLAGBLOCK) { 91 if (bno == NULLAGBLOCK) {
92 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 92 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
93 *stat = 0; 93 *stat = 0;
94 return 0; 94 return 0;
95 } 95 }
96 96
97 xfs_extent_busy_reuse(cur->bc_mp, cur->bc_private.a.agno, bno, 1, false); 97 xfs_extent_busy_reuse(cur->bc_mp, cur->bc_private.a.agno, bno, 1, false);
98 98
99 xfs_trans_agbtree_delta(cur->bc_tp, 1); 99 xfs_trans_agbtree_delta(cur->bc_tp, 1);
100 new->s = cpu_to_be32(bno); 100 new->s = cpu_to_be32(bno);
101 101
102 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 102 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
103 *stat = 1; 103 *stat = 1;
104 return 0; 104 return 0;
105 } 105 }
106 106
107 STATIC int 107 STATIC int
108 xfs_allocbt_free_block( 108 xfs_allocbt_free_block(
109 struct xfs_btree_cur *cur, 109 struct xfs_btree_cur *cur,
110 struct xfs_buf *bp) 110 struct xfs_buf *bp)
111 { 111 {
112 struct xfs_buf *agbp = cur->bc_private.a.agbp; 112 struct xfs_buf *agbp = cur->bc_private.a.agbp;
113 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); 113 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
114 xfs_agblock_t bno; 114 xfs_agblock_t bno;
115 int error; 115 int error;
116 116
117 bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); 117 bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp));
118 error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); 118 error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1);
119 if (error) 119 if (error)
120 return error; 120 return error;
121 121
122 xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, 122 xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1,
123 XFS_EXTENT_BUSY_SKIP_DISCARD); 123 XFS_EXTENT_BUSY_SKIP_DISCARD);
124 xfs_trans_agbtree_delta(cur->bc_tp, -1); 124 xfs_trans_agbtree_delta(cur->bc_tp, -1);
125 125
126 xfs_trans_binval(cur->bc_tp, bp); 126 xfs_trans_binval(cur->bc_tp, bp);
127 return 0; 127 return 0;
128 } 128 }
129 129
130 /* 130 /*
131 * Update the longest extent in the AGF 131 * Update the longest extent in the AGF
132 */ 132 */
133 STATIC void 133 STATIC void
134 xfs_allocbt_update_lastrec( 134 xfs_allocbt_update_lastrec(
135 struct xfs_btree_cur *cur, 135 struct xfs_btree_cur *cur,
136 struct xfs_btree_block *block, 136 struct xfs_btree_block *block,
137 union xfs_btree_rec *rec, 137 union xfs_btree_rec *rec,
138 int ptr, 138 int ptr,
139 int reason) 139 int reason)
140 { 140 {
141 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); 141 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
142 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); 142 xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
143 struct xfs_perag *pag; 143 struct xfs_perag *pag;
144 __be32 len; 144 __be32 len;
145 int numrecs; 145 int numrecs;
146 146
147 ASSERT(cur->bc_btnum == XFS_BTNUM_CNT); 147 ASSERT(cur->bc_btnum == XFS_BTNUM_CNT);
148 148
149 switch (reason) { 149 switch (reason) {
150 case LASTREC_UPDATE: 150 case LASTREC_UPDATE:
151 /* 151 /*
152 * If this is the last leaf block and it's the last record, 152 * If this is the last leaf block and it's the last record,
153 * then update the size of the longest extent in the AG. 153 * then update the size of the longest extent in the AG.
154 */ 154 */
155 if (ptr != xfs_btree_get_numrecs(block)) 155 if (ptr != xfs_btree_get_numrecs(block))
156 return; 156 return;
157 len = rec->alloc.ar_blockcount; 157 len = rec->alloc.ar_blockcount;
158 break; 158 break;
159 case LASTREC_INSREC: 159 case LASTREC_INSREC:
160 if (be32_to_cpu(rec->alloc.ar_blockcount) <= 160 if (be32_to_cpu(rec->alloc.ar_blockcount) <=
161 be32_to_cpu(agf->agf_longest)) 161 be32_to_cpu(agf->agf_longest))
162 return; 162 return;
163 len = rec->alloc.ar_blockcount; 163 len = rec->alloc.ar_blockcount;
164 break; 164 break;
165 case LASTREC_DELREC: 165 case LASTREC_DELREC:
166 numrecs = xfs_btree_get_numrecs(block); 166 numrecs = xfs_btree_get_numrecs(block);
167 if (ptr <= numrecs) 167 if (ptr <= numrecs)
168 return; 168 return;
169 ASSERT(ptr == numrecs + 1); 169 ASSERT(ptr == numrecs + 1);
170 170
171 if (numrecs) { 171 if (numrecs) {
172 xfs_alloc_rec_t *rrp; 172 xfs_alloc_rec_t *rrp;
173 173
174 rrp = XFS_ALLOC_REC_ADDR(cur->bc_mp, block, numrecs); 174 rrp = XFS_ALLOC_REC_ADDR(cur->bc_mp, block, numrecs);
175 len = rrp->ar_blockcount; 175 len = rrp->ar_blockcount;
176 } else { 176 } else {
177 len = 0; 177 len = 0;
178 } 178 }
179 179
180 break; 180 break;
181 default: 181 default:
182 ASSERT(0); 182 ASSERT(0);
183 return; 183 return;
184 } 184 }
185 185
186 agf->agf_longest = len; 186 agf->agf_longest = len;
187 pag = xfs_perag_get(cur->bc_mp, seqno); 187 pag = xfs_perag_get(cur->bc_mp, seqno);
188 pag->pagf_longest = be32_to_cpu(len); 188 pag->pagf_longest = be32_to_cpu(len);
189 xfs_perag_put(pag); 189 xfs_perag_put(pag);
190 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_LONGEST); 190 xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, XFS_AGF_LONGEST);
191 } 191 }
192 192
193 STATIC int 193 STATIC int
194 xfs_allocbt_get_minrecs( 194 xfs_allocbt_get_minrecs(
195 struct xfs_btree_cur *cur, 195 struct xfs_btree_cur *cur,
196 int level) 196 int level)
197 { 197 {
198 return cur->bc_mp->m_alloc_mnr[level != 0]; 198 return cur->bc_mp->m_alloc_mnr[level != 0];
199 } 199 }
200 200
201 STATIC int 201 STATIC int
202 xfs_allocbt_get_maxrecs( 202 xfs_allocbt_get_maxrecs(
203 struct xfs_btree_cur *cur, 203 struct xfs_btree_cur *cur,
204 int level) 204 int level)
205 { 205 {
206 return cur->bc_mp->m_alloc_mxr[level != 0]; 206 return cur->bc_mp->m_alloc_mxr[level != 0];
207 } 207 }
208 208
209 STATIC void 209 STATIC void
210 xfs_allocbt_init_key_from_rec( 210 xfs_allocbt_init_key_from_rec(
211 union xfs_btree_key *key, 211 union xfs_btree_key *key,
212 union xfs_btree_rec *rec) 212 union xfs_btree_rec *rec)
213 { 213 {
214 ASSERT(rec->alloc.ar_startblock != 0); 214 ASSERT(rec->alloc.ar_startblock != 0);
215 215
216 key->alloc.ar_startblock = rec->alloc.ar_startblock; 216 key->alloc.ar_startblock = rec->alloc.ar_startblock;
217 key->alloc.ar_blockcount = rec->alloc.ar_blockcount; 217 key->alloc.ar_blockcount = rec->alloc.ar_blockcount;
218 } 218 }
219 219
220 STATIC void 220 STATIC void
221 xfs_allocbt_init_rec_from_key( 221 xfs_allocbt_init_rec_from_key(
222 union xfs_btree_key *key, 222 union xfs_btree_key *key,
223 union xfs_btree_rec *rec) 223 union xfs_btree_rec *rec)
224 { 224 {
225 ASSERT(key->alloc.ar_startblock != 0); 225 ASSERT(key->alloc.ar_startblock != 0);
226 226
227 rec->alloc.ar_startblock = key->alloc.ar_startblock; 227 rec->alloc.ar_startblock = key->alloc.ar_startblock;
228 rec->alloc.ar_blockcount = key->alloc.ar_blockcount; 228 rec->alloc.ar_blockcount = key->alloc.ar_blockcount;
229 } 229 }
230 230
231 STATIC void 231 STATIC void
232 xfs_allocbt_init_rec_from_cur( 232 xfs_allocbt_init_rec_from_cur(
233 struct xfs_btree_cur *cur, 233 struct xfs_btree_cur *cur,
234 union xfs_btree_rec *rec) 234 union xfs_btree_rec *rec)
235 { 235 {
236 ASSERT(cur->bc_rec.a.ar_startblock != 0); 236 ASSERT(cur->bc_rec.a.ar_startblock != 0);
237 237
238 rec->alloc.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock); 238 rec->alloc.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
239 rec->alloc.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount); 239 rec->alloc.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
240 } 240 }
241 241
242 STATIC void 242 STATIC void
243 xfs_allocbt_init_ptr_from_cur( 243 xfs_allocbt_init_ptr_from_cur(
244 struct xfs_btree_cur *cur, 244 struct xfs_btree_cur *cur,
245 union xfs_btree_ptr *ptr) 245 union xfs_btree_ptr *ptr)
246 { 246 {
247 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); 247 struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp);
248 248
249 ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno)); 249 ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno));
250 ASSERT(agf->agf_roots[cur->bc_btnum] != 0); 250 ASSERT(agf->agf_roots[cur->bc_btnum] != 0);
251 251
252 ptr->s = agf->agf_roots[cur->bc_btnum]; 252 ptr->s = agf->agf_roots[cur->bc_btnum];
253 } 253 }
254 254
255 STATIC __int64_t 255 STATIC __int64_t
256 xfs_allocbt_key_diff( 256 xfs_allocbt_key_diff(
257 struct xfs_btree_cur *cur, 257 struct xfs_btree_cur *cur,
258 union xfs_btree_key *key) 258 union xfs_btree_key *key)
259 { 259 {
260 xfs_alloc_rec_incore_t *rec = &cur->bc_rec.a; 260 xfs_alloc_rec_incore_t *rec = &cur->bc_rec.a;
261 xfs_alloc_key_t *kp = &key->alloc; 261 xfs_alloc_key_t *kp = &key->alloc;
262 __int64_t diff; 262 __int64_t diff;
263 263
264 if (cur->bc_btnum == XFS_BTNUM_BNO) { 264 if (cur->bc_btnum == XFS_BTNUM_BNO) {
265 return (__int64_t)be32_to_cpu(kp->ar_startblock) - 265 return (__int64_t)be32_to_cpu(kp->ar_startblock) -
266 rec->ar_startblock; 266 rec->ar_startblock;
267 } 267 }
268 268
269 diff = (__int64_t)be32_to_cpu(kp->ar_blockcount) - rec->ar_blockcount; 269 diff = (__int64_t)be32_to_cpu(kp->ar_blockcount) - rec->ar_blockcount;
270 if (diff) 270 if (diff)
271 return diff; 271 return diff;
272 272
273 return (__int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock; 273 return (__int64_t)be32_to_cpu(kp->ar_startblock) - rec->ar_startblock;
274 } 274 }
275 275
276 static bool 276 static bool
277 xfs_allocbt_verify( 277 xfs_allocbt_verify(
278 struct xfs_buf *bp) 278 struct xfs_buf *bp)
279 { 279 {
280 struct xfs_mount *mp = bp->b_target->bt_mount; 280 struct xfs_mount *mp = bp->b_target->bt_mount;
281 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); 281 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
282 struct xfs_perag *pag = bp->b_pag; 282 struct xfs_perag *pag = bp->b_pag;
283 unsigned int level; 283 unsigned int level;
284 284
285 /* 285 /*
286 * magic number and level verification 286 * magic number and level verification
287 * 287 *
288 * During growfs operations, we can't verify the exact level or owner as 288 * During growfs operations, we can't verify the exact level or owner as
289 * the perag is not fully initialised and hence not attached to the 289 * the perag is not fully initialised and hence not attached to the
290 * buffer. In this case, check against the maximum tree depth. 290 * buffer. In this case, check against the maximum tree depth.
291 * 291 *
292 * Similarly, during log recovery we will have a perag structure 292 * Similarly, during log recovery we will have a perag structure
293 * attached, but the agf information will not yet have been initialised 293 * attached, but the agf information will not yet have been initialised
294 * from the on disk AGF. Again, we can only check against maximum limits 294 * from the on disk AGF. Again, we can only check against maximum limits
295 * in this case. 295 * in this case.
296 */ 296 */
297 level = be16_to_cpu(block->bb_level); 297 level = be16_to_cpu(block->bb_level);
298 switch (block->bb_magic) { 298 switch (block->bb_magic) {
299 case cpu_to_be32(XFS_ABTB_CRC_MAGIC): 299 case cpu_to_be32(XFS_ABTB_CRC_MAGIC):
300 if (!xfs_sb_version_hascrc(&mp->m_sb)) 300 if (!xfs_sb_version_hascrc(&mp->m_sb))
301 return false; 301 return false;
302 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) 302 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid))
303 return false; 303 return false;
304 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) 304 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))
305 return false; 305 return false;
306 if (pag && 306 if (pag &&
307 be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) 307 be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno)
308 return false; 308 return false;
309 /* fall through */ 309 /* fall through */
310 case cpu_to_be32(XFS_ABTB_MAGIC): 310 case cpu_to_be32(XFS_ABTB_MAGIC):
311 if (pag && pag->pagf_init) { 311 if (pag && pag->pagf_init) {
312 if (level >= pag->pagf_levels[XFS_BTNUM_BNOi]) 312 if (level >= pag->pagf_levels[XFS_BTNUM_BNOi])
313 return false; 313 return false;
314 } else if (level >= mp->m_ag_maxlevels) 314 } else if (level >= mp->m_ag_maxlevels)
315 return false; 315 return false;
316 break; 316 break;
317 case cpu_to_be32(XFS_ABTC_CRC_MAGIC): 317 case cpu_to_be32(XFS_ABTC_CRC_MAGIC):
318 if (!xfs_sb_version_hascrc(&mp->m_sb)) 318 if (!xfs_sb_version_hascrc(&mp->m_sb))
319 return false; 319 return false;
320 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) 320 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid))
321 return false; 321 return false;
322 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) 322 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))
323 return false; 323 return false;
324 if (pag && 324 if (pag &&
325 be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) 325 be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno)
326 return false; 326 return false;
327 /* fall through */ 327 /* fall through */
328 case cpu_to_be32(XFS_ABTC_MAGIC): 328 case cpu_to_be32(XFS_ABTC_MAGIC):
329 if (pag && pag->pagf_init) { 329 if (pag && pag->pagf_init) {
330 if (level >= pag->pagf_levels[XFS_BTNUM_CNTi]) 330 if (level >= pag->pagf_levels[XFS_BTNUM_CNTi])
331 return false; 331 return false;
332 } else if (level >= mp->m_ag_maxlevels) 332 } else if (level >= mp->m_ag_maxlevels)
333 return false; 333 return false;
334 break; 334 break;
335 default: 335 default:
336 return false; 336 return false;
337 } 337 }
338 338
339 /* numrecs verification */ 339 /* numrecs verification */
340 if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[level != 0]) 340 if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[level != 0])
341 return false; 341 return false;
342 342
343 /* sibling pointer verification */ 343 /* sibling pointer verification */
344 if (!block->bb_u.s.bb_leftsib || 344 if (!block->bb_u.s.bb_leftsib ||
345 (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && 345 (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks &&
346 block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) 346 block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK)))
347 return false; 347 return false;
348 if (!block->bb_u.s.bb_rightsib || 348 if (!block->bb_u.s.bb_rightsib ||
349 (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && 349 (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks &&
350 block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) 350 block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK)))
351 return false; 351 return false;
352 352
353 return true; 353 return true;
354 } 354 }
355 355
356 static void 356 static void
357 xfs_allocbt_read_verify( 357 xfs_allocbt_read_verify(
358 struct xfs_buf *bp) 358 struct xfs_buf *bp)
359 { 359 {
360 if (!(xfs_btree_sblock_verify_crc(bp) && 360 if (!(xfs_btree_sblock_verify_crc(bp) &&
361 xfs_allocbt_verify(bp))) { 361 xfs_allocbt_verify(bp))) {
362 trace_xfs_btree_corrupt(bp, _RET_IP_); 362 trace_xfs_btree_corrupt(bp, _RET_IP_);
363 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, 363 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
364 bp->b_target->bt_mount, bp->b_addr); 364 bp->b_target->bt_mount, bp->b_addr);
365 xfs_buf_ioerror(bp, EFSCORRUPTED); 365 xfs_buf_ioerror(bp, EFSCORRUPTED);
366 } 366 }
367 } 367 }
368 368
369 static void 369 static void
370 xfs_allocbt_write_verify( 370 xfs_allocbt_write_verify(
371 struct xfs_buf *bp) 371 struct xfs_buf *bp)
372 { 372 {
373 if (!xfs_allocbt_verify(bp)) { 373 if (!xfs_allocbt_verify(bp)) {
374 trace_xfs_btree_corrupt(bp, _RET_IP_); 374 trace_xfs_btree_corrupt(bp, _RET_IP_);
375 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, 375 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
376 bp->b_target->bt_mount, bp->b_addr); 376 bp->b_target->bt_mount, bp->b_addr);
377 xfs_buf_ioerror(bp, EFSCORRUPTED); 377 xfs_buf_ioerror(bp, EFSCORRUPTED);
378 } 378 }
379 xfs_btree_sblock_calc_crc(bp); 379 xfs_btree_sblock_calc_crc(bp);
380 380
381 } 381 }
382 382
383 const struct xfs_buf_ops xfs_allocbt_buf_ops = { 383 const struct xfs_buf_ops xfs_allocbt_buf_ops = {
384 .verify_read = xfs_allocbt_read_verify, 384 .verify_read = xfs_allocbt_read_verify,
385 .verify_write = xfs_allocbt_write_verify, 385 .verify_write = xfs_allocbt_write_verify,
386 }; 386 };
387 387
388 388
389 #ifdef DEBUG 389 #if defined(DEBUG) || defined(XFS_WARN)
390 STATIC int 390 STATIC int
391 xfs_allocbt_keys_inorder( 391 xfs_allocbt_keys_inorder(
392 struct xfs_btree_cur *cur, 392 struct xfs_btree_cur *cur,
393 union xfs_btree_key *k1, 393 union xfs_btree_key *k1,
394 union xfs_btree_key *k2) 394 union xfs_btree_key *k2)
395 { 395 {
396 if (cur->bc_btnum == XFS_BTNUM_BNO) { 396 if (cur->bc_btnum == XFS_BTNUM_BNO) {
397 return be32_to_cpu(k1->alloc.ar_startblock) < 397 return be32_to_cpu(k1->alloc.ar_startblock) <
398 be32_to_cpu(k2->alloc.ar_startblock); 398 be32_to_cpu(k2->alloc.ar_startblock);
399 } else { 399 } else {
400 return be32_to_cpu(k1->alloc.ar_blockcount) < 400 return be32_to_cpu(k1->alloc.ar_blockcount) <
401 be32_to_cpu(k2->alloc.ar_blockcount) || 401 be32_to_cpu(k2->alloc.ar_blockcount) ||
402 (k1->alloc.ar_blockcount == k2->alloc.ar_blockcount && 402 (k1->alloc.ar_blockcount == k2->alloc.ar_blockcount &&
403 be32_to_cpu(k1->alloc.ar_startblock) < 403 be32_to_cpu(k1->alloc.ar_startblock) <
404 be32_to_cpu(k2->alloc.ar_startblock)); 404 be32_to_cpu(k2->alloc.ar_startblock));
405 } 405 }
406 } 406 }
407 407
408 STATIC int 408 STATIC int
409 xfs_allocbt_recs_inorder( 409 xfs_allocbt_recs_inorder(
410 struct xfs_btree_cur *cur, 410 struct xfs_btree_cur *cur,
411 union xfs_btree_rec *r1, 411 union xfs_btree_rec *r1,
412 union xfs_btree_rec *r2) 412 union xfs_btree_rec *r2)
413 { 413 {
414 if (cur->bc_btnum == XFS_BTNUM_BNO) { 414 if (cur->bc_btnum == XFS_BTNUM_BNO) {
415 return be32_to_cpu(r1->alloc.ar_startblock) + 415 return be32_to_cpu(r1->alloc.ar_startblock) +
416 be32_to_cpu(r1->alloc.ar_blockcount) <= 416 be32_to_cpu(r1->alloc.ar_blockcount) <=
417 be32_to_cpu(r2->alloc.ar_startblock); 417 be32_to_cpu(r2->alloc.ar_startblock);
418 } else { 418 } else {
419 return be32_to_cpu(r1->alloc.ar_blockcount) < 419 return be32_to_cpu(r1->alloc.ar_blockcount) <
420 be32_to_cpu(r2->alloc.ar_blockcount) || 420 be32_to_cpu(r2->alloc.ar_blockcount) ||
421 (r1->alloc.ar_blockcount == r2->alloc.ar_blockcount && 421 (r1->alloc.ar_blockcount == r2->alloc.ar_blockcount &&
422 be32_to_cpu(r1->alloc.ar_startblock) < 422 be32_to_cpu(r1->alloc.ar_startblock) <
423 be32_to_cpu(r2->alloc.ar_startblock)); 423 be32_to_cpu(r2->alloc.ar_startblock));
424 } 424 }
425 } 425 }
426 #endif /* DEBUG */ 426 #endif /* DEBUG */
427 427
428 static const struct xfs_btree_ops xfs_allocbt_ops = { 428 static const struct xfs_btree_ops xfs_allocbt_ops = {
429 .rec_len = sizeof(xfs_alloc_rec_t), 429 .rec_len = sizeof(xfs_alloc_rec_t),
430 .key_len = sizeof(xfs_alloc_key_t), 430 .key_len = sizeof(xfs_alloc_key_t),
431 431
432 .dup_cursor = xfs_allocbt_dup_cursor, 432 .dup_cursor = xfs_allocbt_dup_cursor,
433 .set_root = xfs_allocbt_set_root, 433 .set_root = xfs_allocbt_set_root,
434 .alloc_block = xfs_allocbt_alloc_block, 434 .alloc_block = xfs_allocbt_alloc_block,
435 .free_block = xfs_allocbt_free_block, 435 .free_block = xfs_allocbt_free_block,
436 .update_lastrec = xfs_allocbt_update_lastrec, 436 .update_lastrec = xfs_allocbt_update_lastrec,
437 .get_minrecs = xfs_allocbt_get_minrecs, 437 .get_minrecs = xfs_allocbt_get_minrecs,
438 .get_maxrecs = xfs_allocbt_get_maxrecs, 438 .get_maxrecs = xfs_allocbt_get_maxrecs,
439 .init_key_from_rec = xfs_allocbt_init_key_from_rec, 439 .init_key_from_rec = xfs_allocbt_init_key_from_rec,
440 .init_rec_from_key = xfs_allocbt_init_rec_from_key, 440 .init_rec_from_key = xfs_allocbt_init_rec_from_key,
441 .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, 441 .init_rec_from_cur = xfs_allocbt_init_rec_from_cur,
442 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, 442 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
443 .key_diff = xfs_allocbt_key_diff, 443 .key_diff = xfs_allocbt_key_diff,
444 .buf_ops = &xfs_allocbt_buf_ops, 444 .buf_ops = &xfs_allocbt_buf_ops,
445 #ifdef DEBUG 445 #if defined(DEBUG) || defined(XFS_WARN)
446 .keys_inorder = xfs_allocbt_keys_inorder, 446 .keys_inorder = xfs_allocbt_keys_inorder,
447 .recs_inorder = xfs_allocbt_recs_inorder, 447 .recs_inorder = xfs_allocbt_recs_inorder,
448 #endif 448 #endif
449 }; 449 };
450 450
451 /* 451 /*
452 * Allocate a new allocation btree cursor. 452 * Allocate a new allocation btree cursor.
453 */ 453 */
454 struct xfs_btree_cur * /* new alloc btree cursor */ 454 struct xfs_btree_cur * /* new alloc btree cursor */
455 xfs_allocbt_init_cursor( 455 xfs_allocbt_init_cursor(
456 struct xfs_mount *mp, /* file system mount point */ 456 struct xfs_mount *mp, /* file system mount point */
457 struct xfs_trans *tp, /* transaction pointer */ 457 struct xfs_trans *tp, /* transaction pointer */
458 struct xfs_buf *agbp, /* buffer for agf structure */ 458 struct xfs_buf *agbp, /* buffer for agf structure */
459 xfs_agnumber_t agno, /* allocation group number */ 459 xfs_agnumber_t agno, /* allocation group number */
460 xfs_btnum_t btnum) /* btree identifier */ 460 xfs_btnum_t btnum) /* btree identifier */
461 { 461 {
462 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); 462 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
463 struct xfs_btree_cur *cur; 463 struct xfs_btree_cur *cur;
464 464
465 ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT); 465 ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT);
466 466
467 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); 467 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
468 468
469 cur->bc_tp = tp; 469 cur->bc_tp = tp;
470 cur->bc_mp = mp; 470 cur->bc_mp = mp;
471 cur->bc_btnum = btnum; 471 cur->bc_btnum = btnum;
472 cur->bc_blocklog = mp->m_sb.sb_blocklog; 472 cur->bc_blocklog = mp->m_sb.sb_blocklog;
473 cur->bc_ops = &xfs_allocbt_ops; 473 cur->bc_ops = &xfs_allocbt_ops;
474 474
475 if (btnum == XFS_BTNUM_CNT) { 475 if (btnum == XFS_BTNUM_CNT) {
476 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]); 476 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
477 cur->bc_flags = XFS_BTREE_LASTREC_UPDATE; 477 cur->bc_flags = XFS_BTREE_LASTREC_UPDATE;
478 } else { 478 } else {
479 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]); 479 cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]);
480 } 480 }
481 481
482 cur->bc_private.a.agbp = agbp; 482 cur->bc_private.a.agbp = agbp;
483 cur->bc_private.a.agno = agno; 483 cur->bc_private.a.agno = agno;
484 484
485 if (xfs_sb_version_hascrc(&mp->m_sb)) 485 if (xfs_sb_version_hascrc(&mp->m_sb))
486 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; 486 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
487 487
488 return cur; 488 return cur;
489 } 489 }
490 490
491 /* 491 /*
492 * Calculate number of records in an alloc btree block. 492 * Calculate number of records in an alloc btree block.
493 */ 493 */
494 int 494 int
495 xfs_allocbt_maxrecs( 495 xfs_allocbt_maxrecs(
496 struct xfs_mount *mp, 496 struct xfs_mount *mp,
497 int blocklen, 497 int blocklen,
498 int leaf) 498 int leaf)
499 { 499 {
500 blocklen -= XFS_ALLOC_BLOCK_LEN(mp); 500 blocklen -= XFS_ALLOC_BLOCK_LEN(mp);
501 501
502 if (leaf) 502 if (leaf)
503 return blocklen / sizeof(xfs_alloc_rec_t); 503 return blocklen / sizeof(xfs_alloc_rec_t);
504 return blocklen / (sizeof(xfs_alloc_key_t) + sizeof(xfs_alloc_ptr_t)); 504 return blocklen / (sizeof(xfs_alloc_key_t) + sizeof(xfs_alloc_ptr_t));
505 } 505 }
506 506
fs/xfs/xfs_bmap_btree.c
1 /* 1 /*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2003,2005 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
6 * modify it under the terms of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
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 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_bit.h" 21 #include "xfs_bit.h"
22 #include "xfs_log.h" 22 #include "xfs_log.h"
23 #include "xfs_trans.h" 23 #include "xfs_trans.h"
24 #include "xfs_sb.h" 24 #include "xfs_sb.h"
25 #include "xfs_ag.h" 25 #include "xfs_ag.h"
26 #include "xfs_mount.h" 26 #include "xfs_mount.h"
27 #include "xfs_bmap_btree.h" 27 #include "xfs_bmap_btree.h"
28 #include "xfs_alloc_btree.h" 28 #include "xfs_alloc_btree.h"
29 #include "xfs_ialloc_btree.h" 29 #include "xfs_ialloc_btree.h"
30 #include "xfs_dinode.h" 30 #include "xfs_dinode.h"
31 #include "xfs_inode.h" 31 #include "xfs_inode.h"
32 #include "xfs_inode_item.h" 32 #include "xfs_inode_item.h"
33 #include "xfs_alloc.h" 33 #include "xfs_alloc.h"
34 #include "xfs_btree.h" 34 #include "xfs_btree.h"
35 #include "xfs_itable.h" 35 #include "xfs_itable.h"
36 #include "xfs_bmap.h" 36 #include "xfs_bmap.h"
37 #include "xfs_error.h" 37 #include "xfs_error.h"
38 #include "xfs_quota.h" 38 #include "xfs_quota.h"
39 #include "xfs_trace.h" 39 #include "xfs_trace.h"
40 #include "xfs_cksum.h" 40 #include "xfs_cksum.h"
41 41
42 /* 42 /*
43 * Determine the extent state. 43 * Determine the extent state.
44 */ 44 */
45 /* ARGSUSED */ 45 /* ARGSUSED */
46 STATIC xfs_exntst_t 46 STATIC xfs_exntst_t
47 xfs_extent_state( 47 xfs_extent_state(
48 xfs_filblks_t blks, 48 xfs_filblks_t blks,
49 int extent_flag) 49 int extent_flag)
50 { 50 {
51 if (extent_flag) { 51 if (extent_flag) {
52 ASSERT(blks != 0); /* saved for DMIG */ 52 ASSERT(blks != 0); /* saved for DMIG */
53 return XFS_EXT_UNWRITTEN; 53 return XFS_EXT_UNWRITTEN;
54 } 54 }
55 return XFS_EXT_NORM; 55 return XFS_EXT_NORM;
56 } 56 }
57 57
58 /* 58 /*
59 * Convert on-disk form of btree root to in-memory form. 59 * Convert on-disk form of btree root to in-memory form.
60 */ 60 */
61 void 61 void
62 xfs_bmdr_to_bmbt( 62 xfs_bmdr_to_bmbt(
63 struct xfs_inode *ip, 63 struct xfs_inode *ip,
64 xfs_bmdr_block_t *dblock, 64 xfs_bmdr_block_t *dblock,
65 int dblocklen, 65 int dblocklen,
66 struct xfs_btree_block *rblock, 66 struct xfs_btree_block *rblock,
67 int rblocklen) 67 int rblocklen)
68 { 68 {
69 struct xfs_mount *mp = ip->i_mount; 69 struct xfs_mount *mp = ip->i_mount;
70 int dmxr; 70 int dmxr;
71 xfs_bmbt_key_t *fkp; 71 xfs_bmbt_key_t *fkp;
72 __be64 *fpp; 72 __be64 *fpp;
73 xfs_bmbt_key_t *tkp; 73 xfs_bmbt_key_t *tkp;
74 __be64 *tpp; 74 __be64 *tpp;
75 75
76 if (xfs_sb_version_hascrc(&mp->m_sb)) 76 if (xfs_sb_version_hascrc(&mp->m_sb))
77 xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL, 77 xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL,
78 XFS_BMAP_CRC_MAGIC, 0, 0, ip->i_ino, 78 XFS_BMAP_CRC_MAGIC, 0, 0, ip->i_ino,
79 XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS); 79 XFS_BTREE_LONG_PTRS | XFS_BTREE_CRC_BLOCKS);
80 else 80 else
81 xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL, 81 xfs_btree_init_block_int(mp, rblock, XFS_BUF_DADDR_NULL,
82 XFS_BMAP_MAGIC, 0, 0, ip->i_ino, 82 XFS_BMAP_MAGIC, 0, 0, ip->i_ino,
83 XFS_BTREE_LONG_PTRS); 83 XFS_BTREE_LONG_PTRS);
84 84
85 rblock->bb_level = dblock->bb_level; 85 rblock->bb_level = dblock->bb_level;
86 ASSERT(be16_to_cpu(rblock->bb_level) > 0); 86 ASSERT(be16_to_cpu(rblock->bb_level) > 0);
87 rblock->bb_numrecs = dblock->bb_numrecs; 87 rblock->bb_numrecs = dblock->bb_numrecs;
88 dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); 88 dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0);
89 fkp = XFS_BMDR_KEY_ADDR(dblock, 1); 89 fkp = XFS_BMDR_KEY_ADDR(dblock, 1);
90 tkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); 90 tkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1);
91 fpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr); 91 fpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr);
92 tpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); 92 tpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen);
93 dmxr = be16_to_cpu(dblock->bb_numrecs); 93 dmxr = be16_to_cpu(dblock->bb_numrecs);
94 memcpy(tkp, fkp, sizeof(*fkp) * dmxr); 94 memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
95 memcpy(tpp, fpp, sizeof(*fpp) * dmxr); 95 memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
96 } 96 }
97 97
98 /* 98 /*
99 * Convert a compressed bmap extent record to an uncompressed form. 99 * Convert a compressed bmap extent record to an uncompressed form.
100 * This code must be in sync with the routines xfs_bmbt_get_startoff, 100 * This code must be in sync with the routines xfs_bmbt_get_startoff,
101 * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state. 101 * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state.
102 */ 102 */
103 STATIC void 103 STATIC void
104 __xfs_bmbt_get_all( 104 __xfs_bmbt_get_all(
105 __uint64_t l0, 105 __uint64_t l0,
106 __uint64_t l1, 106 __uint64_t l1,
107 xfs_bmbt_irec_t *s) 107 xfs_bmbt_irec_t *s)
108 { 108 {
109 int ext_flag; 109 int ext_flag;
110 xfs_exntst_t st; 110 xfs_exntst_t st;
111 111
112 ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN)); 112 ext_flag = (int)(l0 >> (64 - BMBT_EXNTFLAG_BITLEN));
113 s->br_startoff = ((xfs_fileoff_t)l0 & 113 s->br_startoff = ((xfs_fileoff_t)l0 &
114 xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; 114 xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
115 #if XFS_BIG_BLKNOS 115 #if XFS_BIG_BLKNOS
116 s->br_startblock = (((xfs_fsblock_t)l0 & xfs_mask64lo(9)) << 43) | 116 s->br_startblock = (((xfs_fsblock_t)l0 & xfs_mask64lo(9)) << 43) |
117 (((xfs_fsblock_t)l1) >> 21); 117 (((xfs_fsblock_t)l1) >> 21);
118 #else 118 #else
119 #ifdef DEBUG 119 #ifdef DEBUG
120 { 120 {
121 xfs_dfsbno_t b; 121 xfs_dfsbno_t b;
122 122
123 b = (((xfs_dfsbno_t)l0 & xfs_mask64lo(9)) << 43) | 123 b = (((xfs_dfsbno_t)l0 & xfs_mask64lo(9)) << 43) |
124 (((xfs_dfsbno_t)l1) >> 21); 124 (((xfs_dfsbno_t)l1) >> 21);
125 ASSERT((b >> 32) == 0 || isnulldstartblock(b)); 125 ASSERT((b >> 32) == 0 || isnulldstartblock(b));
126 s->br_startblock = (xfs_fsblock_t)b; 126 s->br_startblock = (xfs_fsblock_t)b;
127 } 127 }
128 #else /* !DEBUG */ 128 #else /* !DEBUG */
129 s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21); 129 s->br_startblock = (xfs_fsblock_t)(((xfs_dfsbno_t)l1) >> 21);
130 #endif /* DEBUG */ 130 #endif /* DEBUG */
131 #endif /* XFS_BIG_BLKNOS */ 131 #endif /* XFS_BIG_BLKNOS */
132 s->br_blockcount = (xfs_filblks_t)(l1 & xfs_mask64lo(21)); 132 s->br_blockcount = (xfs_filblks_t)(l1 & xfs_mask64lo(21));
133 /* This is xfs_extent_state() in-line */ 133 /* This is xfs_extent_state() in-line */
134 if (ext_flag) { 134 if (ext_flag) {
135 ASSERT(s->br_blockcount != 0); /* saved for DMIG */ 135 ASSERT(s->br_blockcount != 0); /* saved for DMIG */
136 st = XFS_EXT_UNWRITTEN; 136 st = XFS_EXT_UNWRITTEN;
137 } else 137 } else
138 st = XFS_EXT_NORM; 138 st = XFS_EXT_NORM;
139 s->br_state = st; 139 s->br_state = st;
140 } 140 }
141 141
142 void 142 void
143 xfs_bmbt_get_all( 143 xfs_bmbt_get_all(
144 xfs_bmbt_rec_host_t *r, 144 xfs_bmbt_rec_host_t *r,
145 xfs_bmbt_irec_t *s) 145 xfs_bmbt_irec_t *s)
146 { 146 {
147 __xfs_bmbt_get_all(r->l0, r->l1, s); 147 __xfs_bmbt_get_all(r->l0, r->l1, s);
148 } 148 }
149 149
150 /* 150 /*
151 * Extract the blockcount field from an in memory bmap extent record. 151 * Extract the blockcount field from an in memory bmap extent record.
152 */ 152 */
153 xfs_filblks_t 153 xfs_filblks_t
154 xfs_bmbt_get_blockcount( 154 xfs_bmbt_get_blockcount(
155 xfs_bmbt_rec_host_t *r) 155 xfs_bmbt_rec_host_t *r)
156 { 156 {
157 return (xfs_filblks_t)(r->l1 & xfs_mask64lo(21)); 157 return (xfs_filblks_t)(r->l1 & xfs_mask64lo(21));
158 } 158 }
159 159
160 /* 160 /*
161 * Extract the startblock field from an in memory bmap extent record. 161 * Extract the startblock field from an in memory bmap extent record.
162 */ 162 */
163 xfs_fsblock_t 163 xfs_fsblock_t
164 xfs_bmbt_get_startblock( 164 xfs_bmbt_get_startblock(
165 xfs_bmbt_rec_host_t *r) 165 xfs_bmbt_rec_host_t *r)
166 { 166 {
167 #if XFS_BIG_BLKNOS 167 #if XFS_BIG_BLKNOS
168 return (((xfs_fsblock_t)r->l0 & xfs_mask64lo(9)) << 43) | 168 return (((xfs_fsblock_t)r->l0 & xfs_mask64lo(9)) << 43) |
169 (((xfs_fsblock_t)r->l1) >> 21); 169 (((xfs_fsblock_t)r->l1) >> 21);
170 #else 170 #else
171 #ifdef DEBUG 171 #ifdef DEBUG
172 xfs_dfsbno_t b; 172 xfs_dfsbno_t b;
173 173
174 b = (((xfs_dfsbno_t)r->l0 & xfs_mask64lo(9)) << 43) | 174 b = (((xfs_dfsbno_t)r->l0 & xfs_mask64lo(9)) << 43) |
175 (((xfs_dfsbno_t)r->l1) >> 21); 175 (((xfs_dfsbno_t)r->l1) >> 21);
176 ASSERT((b >> 32) == 0 || isnulldstartblock(b)); 176 ASSERT((b >> 32) == 0 || isnulldstartblock(b));
177 return (xfs_fsblock_t)b; 177 return (xfs_fsblock_t)b;
178 #else /* !DEBUG */ 178 #else /* !DEBUG */
179 return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21); 179 return (xfs_fsblock_t)(((xfs_dfsbno_t)r->l1) >> 21);
180 #endif /* DEBUG */ 180 #endif /* DEBUG */
181 #endif /* XFS_BIG_BLKNOS */ 181 #endif /* XFS_BIG_BLKNOS */
182 } 182 }
183 183
184 /* 184 /*
185 * Extract the startoff field from an in memory bmap extent record. 185 * Extract the startoff field from an in memory bmap extent record.
186 */ 186 */
187 xfs_fileoff_t 187 xfs_fileoff_t
188 xfs_bmbt_get_startoff( 188 xfs_bmbt_get_startoff(
189 xfs_bmbt_rec_host_t *r) 189 xfs_bmbt_rec_host_t *r)
190 { 190 {
191 return ((xfs_fileoff_t)r->l0 & 191 return ((xfs_fileoff_t)r->l0 &
192 xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; 192 xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
193 } 193 }
194 194
195 xfs_exntst_t 195 xfs_exntst_t
196 xfs_bmbt_get_state( 196 xfs_bmbt_get_state(
197 xfs_bmbt_rec_host_t *r) 197 xfs_bmbt_rec_host_t *r)
198 { 198 {
199 int ext_flag; 199 int ext_flag;
200 200
201 ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN)); 201 ext_flag = (int)((r->l0) >> (64 - BMBT_EXNTFLAG_BITLEN));
202 return xfs_extent_state(xfs_bmbt_get_blockcount(r), 202 return xfs_extent_state(xfs_bmbt_get_blockcount(r),
203 ext_flag); 203 ext_flag);
204 } 204 }
205 205
206 /* 206 /*
207 * Extract the blockcount field from an on disk bmap extent record. 207 * Extract the blockcount field from an on disk bmap extent record.
208 */ 208 */
209 xfs_filblks_t 209 xfs_filblks_t
210 xfs_bmbt_disk_get_blockcount( 210 xfs_bmbt_disk_get_blockcount(
211 xfs_bmbt_rec_t *r) 211 xfs_bmbt_rec_t *r)
212 { 212 {
213 return (xfs_filblks_t)(be64_to_cpu(r->l1) & xfs_mask64lo(21)); 213 return (xfs_filblks_t)(be64_to_cpu(r->l1) & xfs_mask64lo(21));
214 } 214 }
215 215
216 /* 216 /*
217 * Extract the startoff field from a disk format bmap extent record. 217 * Extract the startoff field from a disk format bmap extent record.
218 */ 218 */
219 xfs_fileoff_t 219 xfs_fileoff_t
220 xfs_bmbt_disk_get_startoff( 220 xfs_bmbt_disk_get_startoff(
221 xfs_bmbt_rec_t *r) 221 xfs_bmbt_rec_t *r)
222 { 222 {
223 return ((xfs_fileoff_t)be64_to_cpu(r->l0) & 223 return ((xfs_fileoff_t)be64_to_cpu(r->l0) &
224 xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9; 224 xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN)) >> 9;
225 } 225 }
226 226
227 227
228 /* 228 /*
229 * Set all the fields in a bmap extent record from the arguments. 229 * Set all the fields in a bmap extent record from the arguments.
230 */ 230 */
231 void 231 void
232 xfs_bmbt_set_allf( 232 xfs_bmbt_set_allf(
233 xfs_bmbt_rec_host_t *r, 233 xfs_bmbt_rec_host_t *r,
234 xfs_fileoff_t startoff, 234 xfs_fileoff_t startoff,
235 xfs_fsblock_t startblock, 235 xfs_fsblock_t startblock,
236 xfs_filblks_t blockcount, 236 xfs_filblks_t blockcount,
237 xfs_exntst_t state) 237 xfs_exntst_t state)
238 { 238 {
239 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; 239 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
240 240
241 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); 241 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
242 ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); 242 ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0);
243 ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); 243 ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
244 244
245 #if XFS_BIG_BLKNOS 245 #if XFS_BIG_BLKNOS
246 ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); 246 ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0);
247 247
248 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | 248 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
249 ((xfs_bmbt_rec_base_t)startoff << 9) | 249 ((xfs_bmbt_rec_base_t)startoff << 9) |
250 ((xfs_bmbt_rec_base_t)startblock >> 43); 250 ((xfs_bmbt_rec_base_t)startblock >> 43);
251 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | 251 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |
252 ((xfs_bmbt_rec_base_t)blockcount & 252 ((xfs_bmbt_rec_base_t)blockcount &
253 (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); 253 (xfs_bmbt_rec_base_t)xfs_mask64lo(21));
254 #else /* !XFS_BIG_BLKNOS */ 254 #else /* !XFS_BIG_BLKNOS */
255 if (isnullstartblock(startblock)) { 255 if (isnullstartblock(startblock)) {
256 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | 256 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
257 ((xfs_bmbt_rec_base_t)startoff << 9) | 257 ((xfs_bmbt_rec_base_t)startoff << 9) |
258 (xfs_bmbt_rec_base_t)xfs_mask64lo(9); 258 (xfs_bmbt_rec_base_t)xfs_mask64lo(9);
259 r->l1 = xfs_mask64hi(11) | 259 r->l1 = xfs_mask64hi(11) |
260 ((xfs_bmbt_rec_base_t)startblock << 21) | 260 ((xfs_bmbt_rec_base_t)startblock << 21) |
261 ((xfs_bmbt_rec_base_t)blockcount & 261 ((xfs_bmbt_rec_base_t)blockcount &
262 (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); 262 (xfs_bmbt_rec_base_t)xfs_mask64lo(21));
263 } else { 263 } else {
264 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) | 264 r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
265 ((xfs_bmbt_rec_base_t)startoff << 9); 265 ((xfs_bmbt_rec_base_t)startoff << 9);
266 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) | 266 r->l1 = ((xfs_bmbt_rec_base_t)startblock << 21) |
267 ((xfs_bmbt_rec_base_t)blockcount & 267 ((xfs_bmbt_rec_base_t)blockcount &
268 (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); 268 (xfs_bmbt_rec_base_t)xfs_mask64lo(21));
269 } 269 }
270 #endif /* XFS_BIG_BLKNOS */ 270 #endif /* XFS_BIG_BLKNOS */
271 } 271 }
272 272
273 /* 273 /*
274 * Set all the fields in a bmap extent record from the uncompressed form. 274 * Set all the fields in a bmap extent record from the uncompressed form.
275 */ 275 */
276 void 276 void
277 xfs_bmbt_set_all( 277 xfs_bmbt_set_all(
278 xfs_bmbt_rec_host_t *r, 278 xfs_bmbt_rec_host_t *r,
279 xfs_bmbt_irec_t *s) 279 xfs_bmbt_irec_t *s)
280 { 280 {
281 xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock, 281 xfs_bmbt_set_allf(r, s->br_startoff, s->br_startblock,
282 s->br_blockcount, s->br_state); 282 s->br_blockcount, s->br_state);
283 } 283 }
284 284
285 285
286 /* 286 /*
287 * Set all the fields in a disk format bmap extent record from the arguments. 287 * Set all the fields in a disk format bmap extent record from the arguments.
288 */ 288 */
289 void 289 void
290 xfs_bmbt_disk_set_allf( 290 xfs_bmbt_disk_set_allf(
291 xfs_bmbt_rec_t *r, 291 xfs_bmbt_rec_t *r,
292 xfs_fileoff_t startoff, 292 xfs_fileoff_t startoff,
293 xfs_fsblock_t startblock, 293 xfs_fsblock_t startblock,
294 xfs_filblks_t blockcount, 294 xfs_filblks_t blockcount,
295 xfs_exntst_t state) 295 xfs_exntst_t state)
296 { 296 {
297 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1; 297 int extent_flag = (state == XFS_EXT_NORM) ? 0 : 1;
298 298
299 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN); 299 ASSERT(state == XFS_EXT_NORM || state == XFS_EXT_UNWRITTEN);
300 ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0); 300 ASSERT((startoff & xfs_mask64hi(64-BMBT_STARTOFF_BITLEN)) == 0);
301 ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0); 301 ASSERT((blockcount & xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN)) == 0);
302 302
303 #if XFS_BIG_BLKNOS 303 #if XFS_BIG_BLKNOS
304 ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0); 304 ASSERT((startblock & xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN)) == 0);
305 305
306 r->l0 = cpu_to_be64( 306 r->l0 = cpu_to_be64(
307 ((xfs_bmbt_rec_base_t)extent_flag << 63) | 307 ((xfs_bmbt_rec_base_t)extent_flag << 63) |
308 ((xfs_bmbt_rec_base_t)startoff << 9) | 308 ((xfs_bmbt_rec_base_t)startoff << 9) |
309 ((xfs_bmbt_rec_base_t)startblock >> 43)); 309 ((xfs_bmbt_rec_base_t)startblock >> 43));
310 r->l1 = cpu_to_be64( 310 r->l1 = cpu_to_be64(
311 ((xfs_bmbt_rec_base_t)startblock << 21) | 311 ((xfs_bmbt_rec_base_t)startblock << 21) |
312 ((xfs_bmbt_rec_base_t)blockcount & 312 ((xfs_bmbt_rec_base_t)blockcount &
313 (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); 313 (xfs_bmbt_rec_base_t)xfs_mask64lo(21)));
314 #else /* !XFS_BIG_BLKNOS */ 314 #else /* !XFS_BIG_BLKNOS */
315 if (isnullstartblock(startblock)) { 315 if (isnullstartblock(startblock)) {
316 r->l0 = cpu_to_be64( 316 r->l0 = cpu_to_be64(
317 ((xfs_bmbt_rec_base_t)extent_flag << 63) | 317 ((xfs_bmbt_rec_base_t)extent_flag << 63) |
318 ((xfs_bmbt_rec_base_t)startoff << 9) | 318 ((xfs_bmbt_rec_base_t)startoff << 9) |
319 (xfs_bmbt_rec_base_t)xfs_mask64lo(9)); 319 (xfs_bmbt_rec_base_t)xfs_mask64lo(9));
320 r->l1 = cpu_to_be64(xfs_mask64hi(11) | 320 r->l1 = cpu_to_be64(xfs_mask64hi(11) |
321 ((xfs_bmbt_rec_base_t)startblock << 21) | 321 ((xfs_bmbt_rec_base_t)startblock << 21) |
322 ((xfs_bmbt_rec_base_t)blockcount & 322 ((xfs_bmbt_rec_base_t)blockcount &
323 (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); 323 (xfs_bmbt_rec_base_t)xfs_mask64lo(21)));
324 } else { 324 } else {
325 r->l0 = cpu_to_be64( 325 r->l0 = cpu_to_be64(
326 ((xfs_bmbt_rec_base_t)extent_flag << 63) | 326 ((xfs_bmbt_rec_base_t)extent_flag << 63) |
327 ((xfs_bmbt_rec_base_t)startoff << 9)); 327 ((xfs_bmbt_rec_base_t)startoff << 9));
328 r->l1 = cpu_to_be64( 328 r->l1 = cpu_to_be64(
329 ((xfs_bmbt_rec_base_t)startblock << 21) | 329 ((xfs_bmbt_rec_base_t)startblock << 21) |
330 ((xfs_bmbt_rec_base_t)blockcount & 330 ((xfs_bmbt_rec_base_t)blockcount &
331 (xfs_bmbt_rec_base_t)xfs_mask64lo(21))); 331 (xfs_bmbt_rec_base_t)xfs_mask64lo(21)));
332 } 332 }
333 #endif /* XFS_BIG_BLKNOS */ 333 #endif /* XFS_BIG_BLKNOS */
334 } 334 }
335 335
336 /* 336 /*
337 * Set all the fields in a bmap extent record from the uncompressed form. 337 * Set all the fields in a bmap extent record from the uncompressed form.
338 */ 338 */
339 STATIC void 339 STATIC void
340 xfs_bmbt_disk_set_all( 340 xfs_bmbt_disk_set_all(
341 xfs_bmbt_rec_t *r, 341 xfs_bmbt_rec_t *r,
342 xfs_bmbt_irec_t *s) 342 xfs_bmbt_irec_t *s)
343 { 343 {
344 xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock, 344 xfs_bmbt_disk_set_allf(r, s->br_startoff, s->br_startblock,
345 s->br_blockcount, s->br_state); 345 s->br_blockcount, s->br_state);
346 } 346 }
347 347
348 /* 348 /*
349 * Set the blockcount field in a bmap extent record. 349 * Set the blockcount field in a bmap extent record.
350 */ 350 */
351 void 351 void
352 xfs_bmbt_set_blockcount( 352 xfs_bmbt_set_blockcount(
353 xfs_bmbt_rec_host_t *r, 353 xfs_bmbt_rec_host_t *r,
354 xfs_filblks_t v) 354 xfs_filblks_t v)
355 { 355 {
356 ASSERT((v & xfs_mask64hi(43)) == 0); 356 ASSERT((v & xfs_mask64hi(43)) == 0);
357 r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64hi(43)) | 357 r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64hi(43)) |
358 (xfs_bmbt_rec_base_t)(v & xfs_mask64lo(21)); 358 (xfs_bmbt_rec_base_t)(v & xfs_mask64lo(21));
359 } 359 }
360 360
361 /* 361 /*
362 * Set the startblock field in a bmap extent record. 362 * Set the startblock field in a bmap extent record.
363 */ 363 */
364 void 364 void
365 xfs_bmbt_set_startblock( 365 xfs_bmbt_set_startblock(
366 xfs_bmbt_rec_host_t *r, 366 xfs_bmbt_rec_host_t *r,
367 xfs_fsblock_t v) 367 xfs_fsblock_t v)
368 { 368 {
369 #if XFS_BIG_BLKNOS 369 #if XFS_BIG_BLKNOS
370 ASSERT((v & xfs_mask64hi(12)) == 0); 370 ASSERT((v & xfs_mask64hi(12)) == 0);
371 r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64hi(55)) | 371 r->l0 = (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64hi(55)) |
372 (xfs_bmbt_rec_base_t)(v >> 43); 372 (xfs_bmbt_rec_base_t)(v >> 43);
373 r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)) | 373 r->l1 = (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)) |
374 (xfs_bmbt_rec_base_t)(v << 21); 374 (xfs_bmbt_rec_base_t)(v << 21);
375 #else /* !XFS_BIG_BLKNOS */ 375 #else /* !XFS_BIG_BLKNOS */
376 if (isnullstartblock(v)) { 376 if (isnullstartblock(v)) {
377 r->l0 |= (xfs_bmbt_rec_base_t)xfs_mask64lo(9); 377 r->l0 |= (xfs_bmbt_rec_base_t)xfs_mask64lo(9);
378 r->l1 = (xfs_bmbt_rec_base_t)xfs_mask64hi(11) | 378 r->l1 = (xfs_bmbt_rec_base_t)xfs_mask64hi(11) |
379 ((xfs_bmbt_rec_base_t)v << 21) | 379 ((xfs_bmbt_rec_base_t)v << 21) |
380 (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); 380 (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21));
381 } else { 381 } else {
382 r->l0 &= ~(xfs_bmbt_rec_base_t)xfs_mask64lo(9); 382 r->l0 &= ~(xfs_bmbt_rec_base_t)xfs_mask64lo(9);
383 r->l1 = ((xfs_bmbt_rec_base_t)v << 21) | 383 r->l1 = ((xfs_bmbt_rec_base_t)v << 21) |
384 (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21)); 384 (r->l1 & (xfs_bmbt_rec_base_t)xfs_mask64lo(21));
385 } 385 }
386 #endif /* XFS_BIG_BLKNOS */ 386 #endif /* XFS_BIG_BLKNOS */
387 } 387 }
388 388
389 /* 389 /*
390 * Set the startoff field in a bmap extent record. 390 * Set the startoff field in a bmap extent record.
391 */ 391 */
392 void 392 void
393 xfs_bmbt_set_startoff( 393 xfs_bmbt_set_startoff(
394 xfs_bmbt_rec_host_t *r, 394 xfs_bmbt_rec_host_t *r,
395 xfs_fileoff_t v) 395 xfs_fileoff_t v)
396 { 396 {
397 ASSERT((v & xfs_mask64hi(9)) == 0); 397 ASSERT((v & xfs_mask64hi(9)) == 0);
398 r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) xfs_mask64hi(1)) | 398 r->l0 = (r->l0 & (xfs_bmbt_rec_base_t) xfs_mask64hi(1)) |
399 ((xfs_bmbt_rec_base_t)v << 9) | 399 ((xfs_bmbt_rec_base_t)v << 9) |
400 (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64lo(9)); 400 (r->l0 & (xfs_bmbt_rec_base_t)xfs_mask64lo(9));
401 } 401 }
402 402
403 /* 403 /*
404 * Set the extent state field in a bmap extent record. 404 * Set the extent state field in a bmap extent record.
405 */ 405 */
406 void 406 void
407 xfs_bmbt_set_state( 407 xfs_bmbt_set_state(
408 xfs_bmbt_rec_host_t *r, 408 xfs_bmbt_rec_host_t *r,
409 xfs_exntst_t v) 409 xfs_exntst_t v)
410 { 410 {
411 ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN); 411 ASSERT(v == XFS_EXT_NORM || v == XFS_EXT_UNWRITTEN);
412 if (v == XFS_EXT_NORM) 412 if (v == XFS_EXT_NORM)
413 r->l0 &= xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN); 413 r->l0 &= xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN);
414 else 414 else
415 r->l0 |= xfs_mask64hi(BMBT_EXNTFLAG_BITLEN); 415 r->l0 |= xfs_mask64hi(BMBT_EXNTFLAG_BITLEN);
416 } 416 }
417 417
418 /* 418 /*
419 * Convert in-memory form of btree root to on-disk form. 419 * Convert in-memory form of btree root to on-disk form.
420 */ 420 */
421 void 421 void
422 xfs_bmbt_to_bmdr( 422 xfs_bmbt_to_bmdr(
423 struct xfs_mount *mp, 423 struct xfs_mount *mp,
424 struct xfs_btree_block *rblock, 424 struct xfs_btree_block *rblock,
425 int rblocklen, 425 int rblocklen,
426 xfs_bmdr_block_t *dblock, 426 xfs_bmdr_block_t *dblock,
427 int dblocklen) 427 int dblocklen)
428 { 428 {
429 int dmxr; 429 int dmxr;
430 xfs_bmbt_key_t *fkp; 430 xfs_bmbt_key_t *fkp;
431 __be64 *fpp; 431 __be64 *fpp;
432 xfs_bmbt_key_t *tkp; 432 xfs_bmbt_key_t *tkp;
433 __be64 *tpp; 433 __be64 *tpp;
434 434
435 if (xfs_sb_version_hascrc(&mp->m_sb)) { 435 if (xfs_sb_version_hascrc(&mp->m_sb)) {
436 ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_CRC_MAGIC)); 436 ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_CRC_MAGIC));
437 ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)); 437 ASSERT(uuid_equal(&rblock->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid));
438 ASSERT(rblock->bb_u.l.bb_blkno == 438 ASSERT(rblock->bb_u.l.bb_blkno ==
439 cpu_to_be64(XFS_BUF_DADDR_NULL)); 439 cpu_to_be64(XFS_BUF_DADDR_NULL));
440 } else 440 } else
441 ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_MAGIC)); 441 ASSERT(rblock->bb_magic == cpu_to_be32(XFS_BMAP_MAGIC));
442 ASSERT(rblock->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO)); 442 ASSERT(rblock->bb_u.l.bb_leftsib == cpu_to_be64(NULLDFSBNO));
443 ASSERT(rblock->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO)); 443 ASSERT(rblock->bb_u.l.bb_rightsib == cpu_to_be64(NULLDFSBNO));
444 ASSERT(rblock->bb_level != 0); 444 ASSERT(rblock->bb_level != 0);
445 dblock->bb_level = rblock->bb_level; 445 dblock->bb_level = rblock->bb_level;
446 dblock->bb_numrecs = rblock->bb_numrecs; 446 dblock->bb_numrecs = rblock->bb_numrecs;
447 dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0); 447 dmxr = xfs_bmdr_maxrecs(mp, dblocklen, 0);
448 fkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1); 448 fkp = XFS_BMBT_KEY_ADDR(mp, rblock, 1);
449 tkp = XFS_BMDR_KEY_ADDR(dblock, 1); 449 tkp = XFS_BMDR_KEY_ADDR(dblock, 1);
450 fpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen); 450 fpp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, rblocklen);
451 tpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr); 451 tpp = XFS_BMDR_PTR_ADDR(dblock, 1, dmxr);
452 dmxr = be16_to_cpu(dblock->bb_numrecs); 452 dmxr = be16_to_cpu(dblock->bb_numrecs);
453 memcpy(tkp, fkp, sizeof(*fkp) * dmxr); 453 memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
454 memcpy(tpp, fpp, sizeof(*fpp) * dmxr); 454 memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
455 } 455 }
456 456
457 /* 457 /*
458 * Check extent records, which have just been read, for 458 * Check extent records, which have just been read, for
459 * any bit in the extent flag field. ASSERT on debug 459 * any bit in the extent flag field. ASSERT on debug
460 * kernels, as this condition should not occur. 460 * kernels, as this condition should not occur.
461 * Return an error condition (1) if any flags found, 461 * Return an error condition (1) if any flags found,
462 * otherwise return 0. 462 * otherwise return 0.
463 */ 463 */
464 464
465 int 465 int
466 xfs_check_nostate_extents( 466 xfs_check_nostate_extents(
467 xfs_ifork_t *ifp, 467 xfs_ifork_t *ifp,
468 xfs_extnum_t idx, 468 xfs_extnum_t idx,
469 xfs_extnum_t num) 469 xfs_extnum_t num)
470 { 470 {
471 for (; num > 0; num--, idx++) { 471 for (; num > 0; num--, idx++) {
472 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx); 472 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
473 if ((ep->l0 >> 473 if ((ep->l0 >>
474 (64 - BMBT_EXNTFLAG_BITLEN)) != 0) { 474 (64 - BMBT_EXNTFLAG_BITLEN)) != 0) {
475 ASSERT(0); 475 ASSERT(0);
476 return 1; 476 return 1;
477 } 477 }
478 } 478 }
479 return 0; 479 return 0;
480 } 480 }
481 481
482 482
483 STATIC struct xfs_btree_cur * 483 STATIC struct xfs_btree_cur *
484 xfs_bmbt_dup_cursor( 484 xfs_bmbt_dup_cursor(
485 struct xfs_btree_cur *cur) 485 struct xfs_btree_cur *cur)
486 { 486 {
487 struct xfs_btree_cur *new; 487 struct xfs_btree_cur *new;
488 488
489 new = xfs_bmbt_init_cursor(cur->bc_mp, cur->bc_tp, 489 new = xfs_bmbt_init_cursor(cur->bc_mp, cur->bc_tp,
490 cur->bc_private.b.ip, cur->bc_private.b.whichfork); 490 cur->bc_private.b.ip, cur->bc_private.b.whichfork);
491 491
492 /* 492 /*
493 * Copy the firstblock, flist, and flags values, 493 * Copy the firstblock, flist, and flags values,
494 * since init cursor doesn't get them. 494 * since init cursor doesn't get them.
495 */ 495 */
496 new->bc_private.b.firstblock = cur->bc_private.b.firstblock; 496 new->bc_private.b.firstblock = cur->bc_private.b.firstblock;
497 new->bc_private.b.flist = cur->bc_private.b.flist; 497 new->bc_private.b.flist = cur->bc_private.b.flist;
498 new->bc_private.b.flags = cur->bc_private.b.flags; 498 new->bc_private.b.flags = cur->bc_private.b.flags;
499 499
500 return new; 500 return new;
501 } 501 }
502 502
503 STATIC void 503 STATIC void
504 xfs_bmbt_update_cursor( 504 xfs_bmbt_update_cursor(
505 struct xfs_btree_cur *src, 505 struct xfs_btree_cur *src,
506 struct xfs_btree_cur *dst) 506 struct xfs_btree_cur *dst)
507 { 507 {
508 ASSERT((dst->bc_private.b.firstblock != NULLFSBLOCK) || 508 ASSERT((dst->bc_private.b.firstblock != NULLFSBLOCK) ||
509 (dst->bc_private.b.ip->i_d.di_flags & XFS_DIFLAG_REALTIME)); 509 (dst->bc_private.b.ip->i_d.di_flags & XFS_DIFLAG_REALTIME));
510 ASSERT(dst->bc_private.b.flist == src->bc_private.b.flist); 510 ASSERT(dst->bc_private.b.flist == src->bc_private.b.flist);
511 511
512 dst->bc_private.b.allocated += src->bc_private.b.allocated; 512 dst->bc_private.b.allocated += src->bc_private.b.allocated;
513 dst->bc_private.b.firstblock = src->bc_private.b.firstblock; 513 dst->bc_private.b.firstblock = src->bc_private.b.firstblock;
514 514
515 src->bc_private.b.allocated = 0; 515 src->bc_private.b.allocated = 0;
516 } 516 }
517 517
518 STATIC int 518 STATIC int
519 xfs_bmbt_alloc_block( 519 xfs_bmbt_alloc_block(
520 struct xfs_btree_cur *cur, 520 struct xfs_btree_cur *cur,
521 union xfs_btree_ptr *start, 521 union xfs_btree_ptr *start,
522 union xfs_btree_ptr *new, 522 union xfs_btree_ptr *new,
523 int length, 523 int length,
524 int *stat) 524 int *stat)
525 { 525 {
526 xfs_alloc_arg_t args; /* block allocation args */ 526 xfs_alloc_arg_t args; /* block allocation args */
527 int error; /* error return value */ 527 int error; /* error return value */
528 528
529 memset(&args, 0, sizeof(args)); 529 memset(&args, 0, sizeof(args));
530 args.tp = cur->bc_tp; 530 args.tp = cur->bc_tp;
531 args.mp = cur->bc_mp; 531 args.mp = cur->bc_mp;
532 args.fsbno = cur->bc_private.b.firstblock; 532 args.fsbno = cur->bc_private.b.firstblock;
533 args.firstblock = args.fsbno; 533 args.firstblock = args.fsbno;
534 534
535 if (args.fsbno == NULLFSBLOCK) { 535 if (args.fsbno == NULLFSBLOCK) {
536 args.fsbno = be64_to_cpu(start->l); 536 args.fsbno = be64_to_cpu(start->l);
537 args.type = XFS_ALLOCTYPE_START_BNO; 537 args.type = XFS_ALLOCTYPE_START_BNO;
538 /* 538 /*
539 * Make sure there is sufficient room left in the AG to 539 * Make sure there is sufficient room left in the AG to
540 * complete a full tree split for an extent insert. If 540 * complete a full tree split for an extent insert. If
541 * we are converting the middle part of an extent then 541 * we are converting the middle part of an extent then
542 * we may need space for two tree splits. 542 * we may need space for two tree splits.
543 * 543 *
544 * We are relying on the caller to make the correct block 544 * We are relying on the caller to make the correct block
545 * reservation for this operation to succeed. If the 545 * reservation for this operation to succeed. If the
546 * reservation amount is insufficient then we may fail a 546 * reservation amount is insufficient then we may fail a
547 * block allocation here and corrupt the filesystem. 547 * block allocation here and corrupt the filesystem.
548 */ 548 */
549 args.minleft = xfs_trans_get_block_res(args.tp); 549 args.minleft = xfs_trans_get_block_res(args.tp);
550 } else if (cur->bc_private.b.flist->xbf_low) { 550 } else if (cur->bc_private.b.flist->xbf_low) {
551 args.type = XFS_ALLOCTYPE_START_BNO; 551 args.type = XFS_ALLOCTYPE_START_BNO;
552 } else { 552 } else {
553 args.type = XFS_ALLOCTYPE_NEAR_BNO; 553 args.type = XFS_ALLOCTYPE_NEAR_BNO;
554 } 554 }
555 555
556 args.minlen = args.maxlen = args.prod = 1; 556 args.minlen = args.maxlen = args.prod = 1;
557 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; 557 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
558 if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) { 558 if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) {
559 error = XFS_ERROR(ENOSPC); 559 error = XFS_ERROR(ENOSPC);
560 goto error0; 560 goto error0;
561 } 561 }
562 error = xfs_alloc_vextent(&args); 562 error = xfs_alloc_vextent(&args);
563 if (error) 563 if (error)
564 goto error0; 564 goto error0;
565 565
566 if (args.fsbno == NULLFSBLOCK && args.minleft) { 566 if (args.fsbno == NULLFSBLOCK && args.minleft) {
567 /* 567 /*
568 * Could not find an AG with enough free space to satisfy 568 * Could not find an AG with enough free space to satisfy
569 * a full btree split. Try again without minleft and if 569 * a full btree split. Try again without minleft and if
570 * successful activate the lowspace algorithm. 570 * successful activate the lowspace algorithm.
571 */ 571 */
572 args.fsbno = 0; 572 args.fsbno = 0;
573 args.type = XFS_ALLOCTYPE_FIRST_AG; 573 args.type = XFS_ALLOCTYPE_FIRST_AG;
574 args.minleft = 0; 574 args.minleft = 0;
575 error = xfs_alloc_vextent(&args); 575 error = xfs_alloc_vextent(&args);
576 if (error) 576 if (error)
577 goto error0; 577 goto error0;
578 cur->bc_private.b.flist->xbf_low = 1; 578 cur->bc_private.b.flist->xbf_low = 1;
579 } 579 }
580 if (args.fsbno == NULLFSBLOCK) { 580 if (args.fsbno == NULLFSBLOCK) {
581 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 581 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
582 *stat = 0; 582 *stat = 0;
583 return 0; 583 return 0;
584 } 584 }
585 ASSERT(args.len == 1); 585 ASSERT(args.len == 1);
586 cur->bc_private.b.firstblock = args.fsbno; 586 cur->bc_private.b.firstblock = args.fsbno;
587 cur->bc_private.b.allocated++; 587 cur->bc_private.b.allocated++;
588 cur->bc_private.b.ip->i_d.di_nblocks++; 588 cur->bc_private.b.ip->i_d.di_nblocks++;
589 xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE); 589 xfs_trans_log_inode(args.tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
590 xfs_trans_mod_dquot_byino(args.tp, cur->bc_private.b.ip, 590 xfs_trans_mod_dquot_byino(args.tp, cur->bc_private.b.ip,
591 XFS_TRANS_DQ_BCOUNT, 1L); 591 XFS_TRANS_DQ_BCOUNT, 1L);
592 592
593 new->l = cpu_to_be64(args.fsbno); 593 new->l = cpu_to_be64(args.fsbno);
594 594
595 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 595 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
596 *stat = 1; 596 *stat = 1;
597 return 0; 597 return 0;
598 598
599 error0: 599 error0:
600 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 600 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
601 return error; 601 return error;
602 } 602 }
603 603
604 STATIC int 604 STATIC int
605 xfs_bmbt_free_block( 605 xfs_bmbt_free_block(
606 struct xfs_btree_cur *cur, 606 struct xfs_btree_cur *cur,
607 struct xfs_buf *bp) 607 struct xfs_buf *bp)
608 { 608 {
609 struct xfs_mount *mp = cur->bc_mp; 609 struct xfs_mount *mp = cur->bc_mp;
610 struct xfs_inode *ip = cur->bc_private.b.ip; 610 struct xfs_inode *ip = cur->bc_private.b.ip;
611 struct xfs_trans *tp = cur->bc_tp; 611 struct xfs_trans *tp = cur->bc_tp;
612 xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); 612 xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp));
613 613
614 xfs_bmap_add_free(fsbno, 1, cur->bc_private.b.flist, mp); 614 xfs_bmap_add_free(fsbno, 1, cur->bc_private.b.flist, mp);
615 ip->i_d.di_nblocks--; 615 ip->i_d.di_nblocks--;
616 616
617 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 617 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
618 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); 618 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
619 xfs_trans_binval(tp, bp); 619 xfs_trans_binval(tp, bp);
620 return 0; 620 return 0;
621 } 621 }
622 622
623 STATIC int 623 STATIC int
624 xfs_bmbt_get_minrecs( 624 xfs_bmbt_get_minrecs(
625 struct xfs_btree_cur *cur, 625 struct xfs_btree_cur *cur,
626 int level) 626 int level)
627 { 627 {
628 if (level == cur->bc_nlevels - 1) { 628 if (level == cur->bc_nlevels - 1) {
629 struct xfs_ifork *ifp; 629 struct xfs_ifork *ifp;
630 630
631 ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, 631 ifp = XFS_IFORK_PTR(cur->bc_private.b.ip,
632 cur->bc_private.b.whichfork); 632 cur->bc_private.b.whichfork);
633 633
634 return xfs_bmbt_maxrecs(cur->bc_mp, 634 return xfs_bmbt_maxrecs(cur->bc_mp,
635 ifp->if_broot_bytes, level == 0) / 2; 635 ifp->if_broot_bytes, level == 0) / 2;
636 } 636 }
637 637
638 return cur->bc_mp->m_bmap_dmnr[level != 0]; 638 return cur->bc_mp->m_bmap_dmnr[level != 0];
639 } 639 }
640 640
641 int 641 int
642 xfs_bmbt_get_maxrecs( 642 xfs_bmbt_get_maxrecs(
643 struct xfs_btree_cur *cur, 643 struct xfs_btree_cur *cur,
644 int level) 644 int level)
645 { 645 {
646 if (level == cur->bc_nlevels - 1) { 646 if (level == cur->bc_nlevels - 1) {
647 struct xfs_ifork *ifp; 647 struct xfs_ifork *ifp;
648 648
649 ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, 649 ifp = XFS_IFORK_PTR(cur->bc_private.b.ip,
650 cur->bc_private.b.whichfork); 650 cur->bc_private.b.whichfork);
651 651
652 return xfs_bmbt_maxrecs(cur->bc_mp, 652 return xfs_bmbt_maxrecs(cur->bc_mp,
653 ifp->if_broot_bytes, level == 0); 653 ifp->if_broot_bytes, level == 0);
654 } 654 }
655 655
656 return cur->bc_mp->m_bmap_dmxr[level != 0]; 656 return cur->bc_mp->m_bmap_dmxr[level != 0];
657 657
658 } 658 }
659 659
660 /* 660 /*
661 * Get the maximum records we could store in the on-disk format. 661 * Get the maximum records we could store in the on-disk format.
662 * 662 *
663 * For non-root nodes this is equivalent to xfs_bmbt_get_maxrecs, but 663 * For non-root nodes this is equivalent to xfs_bmbt_get_maxrecs, but
664 * for the root node this checks the available space in the dinode fork 664 * for the root node this checks the available space in the dinode fork
665 * so that we can resize the in-memory buffer to match it. After a 665 * so that we can resize the in-memory buffer to match it. After a
666 * resize to the maximum size this function returns the same value 666 * resize to the maximum size this function returns the same value
667 * as xfs_bmbt_get_maxrecs for the root node, too. 667 * as xfs_bmbt_get_maxrecs for the root node, too.
668 */ 668 */
669 STATIC int 669 STATIC int
670 xfs_bmbt_get_dmaxrecs( 670 xfs_bmbt_get_dmaxrecs(
671 struct xfs_btree_cur *cur, 671 struct xfs_btree_cur *cur,
672 int level) 672 int level)
673 { 673 {
674 if (level != cur->bc_nlevels - 1) 674 if (level != cur->bc_nlevels - 1)
675 return cur->bc_mp->m_bmap_dmxr[level != 0]; 675 return cur->bc_mp->m_bmap_dmxr[level != 0];
676 return xfs_bmdr_maxrecs(cur->bc_mp, cur->bc_private.b.forksize, 676 return xfs_bmdr_maxrecs(cur->bc_mp, cur->bc_private.b.forksize,
677 level == 0); 677 level == 0);
678 } 678 }
679 679
680 STATIC void 680 STATIC void
681 xfs_bmbt_init_key_from_rec( 681 xfs_bmbt_init_key_from_rec(
682 union xfs_btree_key *key, 682 union xfs_btree_key *key,
683 union xfs_btree_rec *rec) 683 union xfs_btree_rec *rec)
684 { 684 {
685 key->bmbt.br_startoff = 685 key->bmbt.br_startoff =
686 cpu_to_be64(xfs_bmbt_disk_get_startoff(&rec->bmbt)); 686 cpu_to_be64(xfs_bmbt_disk_get_startoff(&rec->bmbt));
687 } 687 }
688 688
689 STATIC void 689 STATIC void
690 xfs_bmbt_init_rec_from_key( 690 xfs_bmbt_init_rec_from_key(
691 union xfs_btree_key *key, 691 union xfs_btree_key *key,
692 union xfs_btree_rec *rec) 692 union xfs_btree_rec *rec)
693 { 693 {
694 ASSERT(key->bmbt.br_startoff != 0); 694 ASSERT(key->bmbt.br_startoff != 0);
695 695
696 xfs_bmbt_disk_set_allf(&rec->bmbt, be64_to_cpu(key->bmbt.br_startoff), 696 xfs_bmbt_disk_set_allf(&rec->bmbt, be64_to_cpu(key->bmbt.br_startoff),
697 0, 0, XFS_EXT_NORM); 697 0, 0, XFS_EXT_NORM);
698 } 698 }
699 699
700 STATIC void 700 STATIC void
701 xfs_bmbt_init_rec_from_cur( 701 xfs_bmbt_init_rec_from_cur(
702 struct xfs_btree_cur *cur, 702 struct xfs_btree_cur *cur,
703 union xfs_btree_rec *rec) 703 union xfs_btree_rec *rec)
704 { 704 {
705 xfs_bmbt_disk_set_all(&rec->bmbt, &cur->bc_rec.b); 705 xfs_bmbt_disk_set_all(&rec->bmbt, &cur->bc_rec.b);
706 } 706 }
707 707
708 STATIC void 708 STATIC void
709 xfs_bmbt_init_ptr_from_cur( 709 xfs_bmbt_init_ptr_from_cur(
710 struct xfs_btree_cur *cur, 710 struct xfs_btree_cur *cur,
711 union xfs_btree_ptr *ptr) 711 union xfs_btree_ptr *ptr)
712 { 712 {
713 ptr->l = 0; 713 ptr->l = 0;
714 } 714 }
715 715
716 STATIC __int64_t 716 STATIC __int64_t
717 xfs_bmbt_key_diff( 717 xfs_bmbt_key_diff(
718 struct xfs_btree_cur *cur, 718 struct xfs_btree_cur *cur,
719 union xfs_btree_key *key) 719 union xfs_btree_key *key)
720 { 720 {
721 return (__int64_t)be64_to_cpu(key->bmbt.br_startoff) - 721 return (__int64_t)be64_to_cpu(key->bmbt.br_startoff) -
722 cur->bc_rec.b.br_startoff; 722 cur->bc_rec.b.br_startoff;
723 } 723 }
724 724
725 static int 725 static int
726 xfs_bmbt_verify( 726 xfs_bmbt_verify(
727 struct xfs_buf *bp) 727 struct xfs_buf *bp)
728 { 728 {
729 struct xfs_mount *mp = bp->b_target->bt_mount; 729 struct xfs_mount *mp = bp->b_target->bt_mount;
730 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); 730 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
731 unsigned int level; 731 unsigned int level;
732 732
733 switch (block->bb_magic) { 733 switch (block->bb_magic) {
734 case cpu_to_be32(XFS_BMAP_CRC_MAGIC): 734 case cpu_to_be32(XFS_BMAP_CRC_MAGIC):
735 if (!xfs_sb_version_hascrc(&mp->m_sb)) 735 if (!xfs_sb_version_hascrc(&mp->m_sb))
736 return false; 736 return false;
737 if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid)) 737 if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_uuid))
738 return false; 738 return false;
739 if (be64_to_cpu(block->bb_u.l.bb_blkno) != bp->b_bn) 739 if (be64_to_cpu(block->bb_u.l.bb_blkno) != bp->b_bn)
740 return false; 740 return false;
741 /* 741 /*
742 * XXX: need a better way of verifying the owner here. Right now 742 * XXX: need a better way of verifying the owner here. Right now
743 * just make sure there has been one set. 743 * just make sure there has been one set.
744 */ 744 */
745 if (be64_to_cpu(block->bb_u.l.bb_owner) == 0) 745 if (be64_to_cpu(block->bb_u.l.bb_owner) == 0)
746 return false; 746 return false;
747 /* fall through */ 747 /* fall through */
748 case cpu_to_be32(XFS_BMAP_MAGIC): 748 case cpu_to_be32(XFS_BMAP_MAGIC):
749 break; 749 break;
750 default: 750 default:
751 return false; 751 return false;
752 } 752 }
753 753
754 /* 754 /*
755 * numrecs and level verification. 755 * numrecs and level verification.
756 * 756 *
757 * We don't know what fork we belong to, so just verify that the level 757 * We don't know what fork we belong to, so just verify that the level
758 * is less than the maximum of the two. Later checks will be more 758 * is less than the maximum of the two. Later checks will be more
759 * precise. 759 * precise.
760 */ 760 */
761 level = be16_to_cpu(block->bb_level); 761 level = be16_to_cpu(block->bb_level);
762 if (level > max(mp->m_bm_maxlevels[0], mp->m_bm_maxlevels[1])) 762 if (level > max(mp->m_bm_maxlevels[0], mp->m_bm_maxlevels[1]))
763 return false; 763 return false;
764 if (be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0]) 764 if (be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0])
765 return false; 765 return false;
766 766
767 /* sibling pointer verification */ 767 /* sibling pointer verification */
768 if (!block->bb_u.l.bb_leftsib || 768 if (!block->bb_u.l.bb_leftsib ||
769 (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLDFSBNO) && 769 (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLDFSBNO) &&
770 !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_leftsib)))) 770 !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_leftsib))))
771 return false; 771 return false;
772 if (!block->bb_u.l.bb_rightsib || 772 if (!block->bb_u.l.bb_rightsib ||
773 (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLDFSBNO) && 773 (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLDFSBNO) &&
774 !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_rightsib)))) 774 !XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_u.l.bb_rightsib))))
775 return false; 775 return false;
776 776
777 return true; 777 return true;
778 778
779 } 779 }
780 780
781 static void 781 static void
782 xfs_bmbt_read_verify( 782 xfs_bmbt_read_verify(
783 struct xfs_buf *bp) 783 struct xfs_buf *bp)
784 { 784 {
785 if (!(xfs_btree_lblock_verify_crc(bp) && 785 if (!(xfs_btree_lblock_verify_crc(bp) &&
786 xfs_bmbt_verify(bp))) { 786 xfs_bmbt_verify(bp))) {
787 trace_xfs_btree_corrupt(bp, _RET_IP_); 787 trace_xfs_btree_corrupt(bp, _RET_IP_);
788 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, 788 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
789 bp->b_target->bt_mount, bp->b_addr); 789 bp->b_target->bt_mount, bp->b_addr);
790 xfs_buf_ioerror(bp, EFSCORRUPTED); 790 xfs_buf_ioerror(bp, EFSCORRUPTED);
791 } 791 }
792 792
793 } 793 }
794 794
795 static void 795 static void
796 xfs_bmbt_write_verify( 796 xfs_bmbt_write_verify(
797 struct xfs_buf *bp) 797 struct xfs_buf *bp)
798 { 798 {
799 if (!xfs_bmbt_verify(bp)) { 799 if (!xfs_bmbt_verify(bp)) {
800 xfs_warn(bp->b_target->bt_mount, "bmbt daddr 0x%llx failed", bp->b_bn); 800 xfs_warn(bp->b_target->bt_mount, "bmbt daddr 0x%llx failed", bp->b_bn);
801 trace_xfs_btree_corrupt(bp, _RET_IP_); 801 trace_xfs_btree_corrupt(bp, _RET_IP_);
802 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, 802 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
803 bp->b_target->bt_mount, bp->b_addr); 803 bp->b_target->bt_mount, bp->b_addr);
804 xfs_buf_ioerror(bp, EFSCORRUPTED); 804 xfs_buf_ioerror(bp, EFSCORRUPTED);
805 return; 805 return;
806 } 806 }
807 xfs_btree_lblock_calc_crc(bp); 807 xfs_btree_lblock_calc_crc(bp);
808 } 808 }
809 809
810 const struct xfs_buf_ops xfs_bmbt_buf_ops = { 810 const struct xfs_buf_ops xfs_bmbt_buf_ops = {
811 .verify_read = xfs_bmbt_read_verify, 811 .verify_read = xfs_bmbt_read_verify,
812 .verify_write = xfs_bmbt_write_verify, 812 .verify_write = xfs_bmbt_write_verify,
813 }; 813 };
814 814
815 815
816 #ifdef DEBUG 816 #if defined(DEBUG) || defined(XFS_WARN)
817 STATIC int 817 STATIC int
818 xfs_bmbt_keys_inorder( 818 xfs_bmbt_keys_inorder(
819 struct xfs_btree_cur *cur, 819 struct xfs_btree_cur *cur,
820 union xfs_btree_key *k1, 820 union xfs_btree_key *k1,
821 union xfs_btree_key *k2) 821 union xfs_btree_key *k2)
822 { 822 {
823 return be64_to_cpu(k1->bmbt.br_startoff) < 823 return be64_to_cpu(k1->bmbt.br_startoff) <
824 be64_to_cpu(k2->bmbt.br_startoff); 824 be64_to_cpu(k2->bmbt.br_startoff);
825 } 825 }
826 826
827 STATIC int 827 STATIC int
828 xfs_bmbt_recs_inorder( 828 xfs_bmbt_recs_inorder(
829 struct xfs_btree_cur *cur, 829 struct xfs_btree_cur *cur,
830 union xfs_btree_rec *r1, 830 union xfs_btree_rec *r1,
831 union xfs_btree_rec *r2) 831 union xfs_btree_rec *r2)
832 { 832 {
833 return xfs_bmbt_disk_get_startoff(&r1->bmbt) + 833 return xfs_bmbt_disk_get_startoff(&r1->bmbt) +
834 xfs_bmbt_disk_get_blockcount(&r1->bmbt) <= 834 xfs_bmbt_disk_get_blockcount(&r1->bmbt) <=
835 xfs_bmbt_disk_get_startoff(&r2->bmbt); 835 xfs_bmbt_disk_get_startoff(&r2->bmbt);
836 } 836 }
837 #endif /* DEBUG */ 837 #endif /* DEBUG */
838 838
839 static const struct xfs_btree_ops xfs_bmbt_ops = { 839 static const struct xfs_btree_ops xfs_bmbt_ops = {
840 .rec_len = sizeof(xfs_bmbt_rec_t), 840 .rec_len = sizeof(xfs_bmbt_rec_t),
841 .key_len = sizeof(xfs_bmbt_key_t), 841 .key_len = sizeof(xfs_bmbt_key_t),
842 842
843 .dup_cursor = xfs_bmbt_dup_cursor, 843 .dup_cursor = xfs_bmbt_dup_cursor,
844 .update_cursor = xfs_bmbt_update_cursor, 844 .update_cursor = xfs_bmbt_update_cursor,
845 .alloc_block = xfs_bmbt_alloc_block, 845 .alloc_block = xfs_bmbt_alloc_block,
846 .free_block = xfs_bmbt_free_block, 846 .free_block = xfs_bmbt_free_block,
847 .get_maxrecs = xfs_bmbt_get_maxrecs, 847 .get_maxrecs = xfs_bmbt_get_maxrecs,
848 .get_minrecs = xfs_bmbt_get_minrecs, 848 .get_minrecs = xfs_bmbt_get_minrecs,
849 .get_dmaxrecs = xfs_bmbt_get_dmaxrecs, 849 .get_dmaxrecs = xfs_bmbt_get_dmaxrecs,
850 .init_key_from_rec = xfs_bmbt_init_key_from_rec, 850 .init_key_from_rec = xfs_bmbt_init_key_from_rec,
851 .init_rec_from_key = xfs_bmbt_init_rec_from_key, 851 .init_rec_from_key = xfs_bmbt_init_rec_from_key,
852 .init_rec_from_cur = xfs_bmbt_init_rec_from_cur, 852 .init_rec_from_cur = xfs_bmbt_init_rec_from_cur,
853 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, 853 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
854 .key_diff = xfs_bmbt_key_diff, 854 .key_diff = xfs_bmbt_key_diff,
855 .buf_ops = &xfs_bmbt_buf_ops, 855 .buf_ops = &xfs_bmbt_buf_ops,
856 #ifdef DEBUG 856 #if defined(DEBUG) || defined(XFS_WARN)
857 .keys_inorder = xfs_bmbt_keys_inorder, 857 .keys_inorder = xfs_bmbt_keys_inorder,
858 .recs_inorder = xfs_bmbt_recs_inorder, 858 .recs_inorder = xfs_bmbt_recs_inorder,
859 #endif 859 #endif
860 }; 860 };
861 861
862 /* 862 /*
863 * Allocate a new bmap btree cursor. 863 * Allocate a new bmap btree cursor.
864 */ 864 */
865 struct xfs_btree_cur * /* new bmap btree cursor */ 865 struct xfs_btree_cur * /* new bmap btree cursor */
866 xfs_bmbt_init_cursor( 866 xfs_bmbt_init_cursor(
867 struct xfs_mount *mp, /* file system mount point */ 867 struct xfs_mount *mp, /* file system mount point */
868 struct xfs_trans *tp, /* transaction pointer */ 868 struct xfs_trans *tp, /* transaction pointer */
869 struct xfs_inode *ip, /* inode owning the btree */ 869 struct xfs_inode *ip, /* inode owning the btree */
870 int whichfork) /* data or attr fork */ 870 int whichfork) /* data or attr fork */
871 { 871 {
872 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 872 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
873 struct xfs_btree_cur *cur; 873 struct xfs_btree_cur *cur;
874 874
875 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); 875 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
876 876
877 cur->bc_tp = tp; 877 cur->bc_tp = tp;
878 cur->bc_mp = mp; 878 cur->bc_mp = mp;
879 cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1; 879 cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
880 cur->bc_btnum = XFS_BTNUM_BMAP; 880 cur->bc_btnum = XFS_BTNUM_BMAP;
881 cur->bc_blocklog = mp->m_sb.sb_blocklog; 881 cur->bc_blocklog = mp->m_sb.sb_blocklog;
882 882
883 cur->bc_ops = &xfs_bmbt_ops; 883 cur->bc_ops = &xfs_bmbt_ops;
884 cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE; 884 cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;
885 if (xfs_sb_version_hascrc(&mp->m_sb)) 885 if (xfs_sb_version_hascrc(&mp->m_sb))
886 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; 886 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
887 887
888 cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork); 888 cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork);
889 cur->bc_private.b.ip = ip; 889 cur->bc_private.b.ip = ip;
890 cur->bc_private.b.firstblock = NULLFSBLOCK; 890 cur->bc_private.b.firstblock = NULLFSBLOCK;
891 cur->bc_private.b.flist = NULL; 891 cur->bc_private.b.flist = NULL;
892 cur->bc_private.b.allocated = 0; 892 cur->bc_private.b.allocated = 0;
893 cur->bc_private.b.flags = 0; 893 cur->bc_private.b.flags = 0;
894 cur->bc_private.b.whichfork = whichfork; 894 cur->bc_private.b.whichfork = whichfork;
895 895
896 return cur; 896 return cur;
897 } 897 }
898 898
899 /* 899 /*
900 * Calculate number of records in a bmap btree block. 900 * Calculate number of records in a bmap btree block.
901 */ 901 */
902 int 902 int
903 xfs_bmbt_maxrecs( 903 xfs_bmbt_maxrecs(
904 struct xfs_mount *mp, 904 struct xfs_mount *mp,
905 int blocklen, 905 int blocklen,
906 int leaf) 906 int leaf)
907 { 907 {
908 blocklen -= XFS_BMBT_BLOCK_LEN(mp); 908 blocklen -= XFS_BMBT_BLOCK_LEN(mp);
909 909
910 if (leaf) 910 if (leaf)
911 return blocklen / sizeof(xfs_bmbt_rec_t); 911 return blocklen / sizeof(xfs_bmbt_rec_t);
912 return blocklen / (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t)); 912 return blocklen / (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t));
913 } 913 }
914 914
915 /* 915 /*
916 * Calculate number of records in a bmap btree inode root. 916 * Calculate number of records in a bmap btree inode root.
917 */ 917 */
918 int 918 int
919 xfs_bmdr_maxrecs( 919 xfs_bmdr_maxrecs(
920 struct xfs_mount *mp, 920 struct xfs_mount *mp,
921 int blocklen, 921 int blocklen,
922 int leaf) 922 int leaf)
923 { 923 {
924 blocklen -= sizeof(xfs_bmdr_block_t); 924 blocklen -= sizeof(xfs_bmdr_block_t);
925 925
926 if (leaf) 926 if (leaf)
927 return blocklen / sizeof(xfs_bmdr_rec_t); 927 return blocklen / sizeof(xfs_bmdr_rec_t);
928 return blocklen / (sizeof(xfs_bmdr_key_t) + sizeof(xfs_bmdr_ptr_t)); 928 return blocklen / (sizeof(xfs_bmdr_key_t) + sizeof(xfs_bmdr_ptr_t));
929 } 929 }
930 930
1 /* 1 /*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2001,2005 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
6 * modify it under the terms of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
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 */ 17 */
18 #ifndef __XFS_BTREE_H__ 18 #ifndef __XFS_BTREE_H__
19 #define __XFS_BTREE_H__ 19 #define __XFS_BTREE_H__
20 20
21 struct xfs_buf; 21 struct xfs_buf;
22 struct xfs_bmap_free; 22 struct xfs_bmap_free;
23 struct xfs_inode; 23 struct xfs_inode;
24 struct xfs_mount; 24 struct xfs_mount;
25 struct xfs_trans; 25 struct xfs_trans;
26 26
27 extern kmem_zone_t *xfs_btree_cur_zone; 27 extern kmem_zone_t *xfs_btree_cur_zone;
28 28
29 /* 29 /*
30 * This nonsense is to make -wlint happy. 30 * This nonsense is to make -wlint happy.
31 */ 31 */
32 #define XFS_LOOKUP_EQ ((xfs_lookup_t)XFS_LOOKUP_EQi) 32 #define XFS_LOOKUP_EQ ((xfs_lookup_t)XFS_LOOKUP_EQi)
33 #define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi) 33 #define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi)
34 #define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi) 34 #define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi)
35 35
36 #define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi) 36 #define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi)
37 #define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi) 37 #define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi)
38 #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) 38 #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi)
39 #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) 39 #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi)
40 40
41 /* 41 /*
42 * Generic btree header. 42 * Generic btree header.
43 * 43 *
44 * This is a combination of the actual format used on disk for short and long 44 * This is a combination of the actual format used on disk for short and long
45 * format btrees. The first three fields are shared by both format, but the 45 * format btrees. The first three fields are shared by both format, but the
46 * pointers are different and should be used with care. 46 * pointers are different and should be used with care.
47 * 47 *
48 * To get the size of the actual short or long form headers please use the size 48 * To get the size of the actual short or long form headers please use the size
49 * macros below. Never use sizeof(xfs_btree_block). 49 * macros below. Never use sizeof(xfs_btree_block).
50 * 50 *
51 * The blkno, crc, lsn, owner and uuid fields are only available in filesystems 51 * The blkno, crc, lsn, owner and uuid fields are only available in filesystems
52 * with the crc feature bit, and all accesses to them must be conditional on 52 * with the crc feature bit, and all accesses to them must be conditional on
53 * that flag. 53 * that flag.
54 */ 54 */
55 struct xfs_btree_block { 55 struct xfs_btree_block {
56 __be32 bb_magic; /* magic number for block type */ 56 __be32 bb_magic; /* magic number for block type */
57 __be16 bb_level; /* 0 is a leaf */ 57 __be16 bb_level; /* 0 is a leaf */
58 __be16 bb_numrecs; /* current # of data records */ 58 __be16 bb_numrecs; /* current # of data records */
59 union { 59 union {
60 struct { 60 struct {
61 __be32 bb_leftsib; 61 __be32 bb_leftsib;
62 __be32 bb_rightsib; 62 __be32 bb_rightsib;
63 63
64 __be64 bb_blkno; 64 __be64 bb_blkno;
65 __be64 bb_lsn; 65 __be64 bb_lsn;
66 uuid_t bb_uuid; 66 uuid_t bb_uuid;
67 __be32 bb_owner; 67 __be32 bb_owner;
68 __le32 bb_crc; 68 __le32 bb_crc;
69 } s; /* short form pointers */ 69 } s; /* short form pointers */
70 struct { 70 struct {
71 __be64 bb_leftsib; 71 __be64 bb_leftsib;
72 __be64 bb_rightsib; 72 __be64 bb_rightsib;
73 73
74 __be64 bb_blkno; 74 __be64 bb_blkno;
75 __be64 bb_lsn; 75 __be64 bb_lsn;
76 uuid_t bb_uuid; 76 uuid_t bb_uuid;
77 __be64 bb_owner; 77 __be64 bb_owner;
78 __le32 bb_crc; 78 __le32 bb_crc;
79 __be32 bb_pad; /* padding for alignment */ 79 __be32 bb_pad; /* padding for alignment */
80 } l; /* long form pointers */ 80 } l; /* long form pointers */
81 } bb_u; /* rest */ 81 } bb_u; /* rest */
82 }; 82 };
83 83
84 #define XFS_BTREE_SBLOCK_LEN 16 /* size of a short form block */ 84 #define XFS_BTREE_SBLOCK_LEN 16 /* size of a short form block */
85 #define XFS_BTREE_LBLOCK_LEN 24 /* size of a long form block */ 85 #define XFS_BTREE_LBLOCK_LEN 24 /* size of a long form block */
86 86
87 /* sizes of CRC enabled btree blocks */ 87 /* sizes of CRC enabled btree blocks */
88 #define XFS_BTREE_SBLOCK_CRC_LEN (XFS_BTREE_SBLOCK_LEN + 40) 88 #define XFS_BTREE_SBLOCK_CRC_LEN (XFS_BTREE_SBLOCK_LEN + 40)
89 #define XFS_BTREE_LBLOCK_CRC_LEN (XFS_BTREE_LBLOCK_LEN + 48) 89 #define XFS_BTREE_LBLOCK_CRC_LEN (XFS_BTREE_LBLOCK_LEN + 48)
90 90
91 91
92 #define XFS_BTREE_SBLOCK_CRC_OFF \ 92 #define XFS_BTREE_SBLOCK_CRC_OFF \
93 offsetof(struct xfs_btree_block, bb_u.s.bb_crc) 93 offsetof(struct xfs_btree_block, bb_u.s.bb_crc)
94 #define XFS_BTREE_LBLOCK_CRC_OFF \ 94 #define XFS_BTREE_LBLOCK_CRC_OFF \
95 offsetof(struct xfs_btree_block, bb_u.l.bb_crc) 95 offsetof(struct xfs_btree_block, bb_u.l.bb_crc)
96 96
97 97
98 /* 98 /*
99 * Generic key, ptr and record wrapper structures. 99 * Generic key, ptr and record wrapper structures.
100 * 100 *
101 * These are disk format structures, and are converted where necessary 101 * These are disk format structures, and are converted where necessary
102 * by the btree specific code that needs to interpret them. 102 * by the btree specific code that needs to interpret them.
103 */ 103 */
104 union xfs_btree_ptr { 104 union xfs_btree_ptr {
105 __be32 s; /* short form ptr */ 105 __be32 s; /* short form ptr */
106 __be64 l; /* long form ptr */ 106 __be64 l; /* long form ptr */
107 }; 107 };
108 108
109 union xfs_btree_key { 109 union xfs_btree_key {
110 xfs_bmbt_key_t bmbt; 110 xfs_bmbt_key_t bmbt;
111 xfs_bmdr_key_t bmbr; /* bmbt root block */ 111 xfs_bmdr_key_t bmbr; /* bmbt root block */
112 xfs_alloc_key_t alloc; 112 xfs_alloc_key_t alloc;
113 xfs_inobt_key_t inobt; 113 xfs_inobt_key_t inobt;
114 }; 114 };
115 115
116 union xfs_btree_rec { 116 union xfs_btree_rec {
117 xfs_bmbt_rec_t bmbt; 117 xfs_bmbt_rec_t bmbt;
118 xfs_bmdr_rec_t bmbr; /* bmbt root block */ 118 xfs_bmdr_rec_t bmbr; /* bmbt root block */
119 xfs_alloc_rec_t alloc; 119 xfs_alloc_rec_t alloc;
120 xfs_inobt_rec_t inobt; 120 xfs_inobt_rec_t inobt;
121 }; 121 };
122 122
123 /* 123 /*
124 * For logging record fields. 124 * For logging record fields.
125 */ 125 */
126 #define XFS_BB_MAGIC 0x01 126 #define XFS_BB_MAGIC 0x01
127 #define XFS_BB_LEVEL 0x02 127 #define XFS_BB_LEVEL 0x02
128 #define XFS_BB_NUMRECS 0x04 128 #define XFS_BB_NUMRECS 0x04
129 #define XFS_BB_LEFTSIB 0x08 129 #define XFS_BB_LEFTSIB 0x08
130 #define XFS_BB_RIGHTSIB 0x10 130 #define XFS_BB_RIGHTSIB 0x10
131 #define XFS_BB_BLKNO 0x20 131 #define XFS_BB_BLKNO 0x20
132 #define XFS_BB_NUM_BITS 5 132 #define XFS_BB_NUM_BITS 5
133 #define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1) 133 #define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1)
134 #define XFS_BB_NUM_BITS_CRC 8 134 #define XFS_BB_NUM_BITS_CRC 8
135 #define XFS_BB_ALL_BITS_CRC ((1 << XFS_BB_NUM_BITS_CRC) - 1) 135 #define XFS_BB_ALL_BITS_CRC ((1 << XFS_BB_NUM_BITS_CRC) - 1)
136 136
137 /* 137 /*
138 * Generic stats interface 138 * Generic stats interface
139 */ 139 */
140 #define __XFS_BTREE_STATS_INC(type, stat) \ 140 #define __XFS_BTREE_STATS_INC(type, stat) \
141 XFS_STATS_INC(xs_ ## type ## _2_ ## stat) 141 XFS_STATS_INC(xs_ ## type ## _2_ ## stat)
142 #define XFS_BTREE_STATS_INC(cur, stat) \ 142 #define XFS_BTREE_STATS_INC(cur, stat) \
143 do { \ 143 do { \
144 switch (cur->bc_btnum) { \ 144 switch (cur->bc_btnum) { \
145 case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \ 145 case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \
146 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \ 146 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \
147 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ 147 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \
148 case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ 148 case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \
149 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ 149 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
150 } \ 150 } \
151 } while (0) 151 } while (0)
152 152
153 #define __XFS_BTREE_STATS_ADD(type, stat, val) \ 153 #define __XFS_BTREE_STATS_ADD(type, stat, val) \
154 XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val) 154 XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val)
155 #define XFS_BTREE_STATS_ADD(cur, stat, val) \ 155 #define XFS_BTREE_STATS_ADD(cur, stat, val) \
156 do { \ 156 do { \
157 switch (cur->bc_btnum) { \ 157 switch (cur->bc_btnum) { \
158 case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \ 158 case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \
159 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \ 159 case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \
160 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ 160 case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \
161 case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ 161 case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \
162 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ 162 case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
163 } \ 163 } \
164 } while (0) 164 } while (0)
165 165
166 #define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */ 166 #define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */
167 167
168 struct xfs_btree_ops { 168 struct xfs_btree_ops {
169 /* size of the key and record structures */ 169 /* size of the key and record structures */
170 size_t key_len; 170 size_t key_len;
171 size_t rec_len; 171 size_t rec_len;
172 172
173 /* cursor operations */ 173 /* cursor operations */
174 struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *); 174 struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
175 void (*update_cursor)(struct xfs_btree_cur *src, 175 void (*update_cursor)(struct xfs_btree_cur *src,
176 struct xfs_btree_cur *dst); 176 struct xfs_btree_cur *dst);
177 177
178 /* update btree root pointer */ 178 /* update btree root pointer */
179 void (*set_root)(struct xfs_btree_cur *cur, 179 void (*set_root)(struct xfs_btree_cur *cur,
180 union xfs_btree_ptr *nptr, int level_change); 180 union xfs_btree_ptr *nptr, int level_change);
181 181
182 /* block allocation / freeing */ 182 /* block allocation / freeing */
183 int (*alloc_block)(struct xfs_btree_cur *cur, 183 int (*alloc_block)(struct xfs_btree_cur *cur,
184 union xfs_btree_ptr *start_bno, 184 union xfs_btree_ptr *start_bno,
185 union xfs_btree_ptr *new_bno, 185 union xfs_btree_ptr *new_bno,
186 int length, int *stat); 186 int length, int *stat);
187 int (*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp); 187 int (*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp);
188 188
189 /* update last record information */ 189 /* update last record information */
190 void (*update_lastrec)(struct xfs_btree_cur *cur, 190 void (*update_lastrec)(struct xfs_btree_cur *cur,
191 struct xfs_btree_block *block, 191 struct xfs_btree_block *block,
192 union xfs_btree_rec *rec, 192 union xfs_btree_rec *rec,
193 int ptr, int reason); 193 int ptr, int reason);
194 194
195 /* records in block/level */ 195 /* records in block/level */
196 int (*get_minrecs)(struct xfs_btree_cur *cur, int level); 196 int (*get_minrecs)(struct xfs_btree_cur *cur, int level);
197 int (*get_maxrecs)(struct xfs_btree_cur *cur, int level); 197 int (*get_maxrecs)(struct xfs_btree_cur *cur, int level);
198 198
199 /* records on disk. Matter for the root in inode case. */ 199 /* records on disk. Matter for the root in inode case. */
200 int (*get_dmaxrecs)(struct xfs_btree_cur *cur, int level); 200 int (*get_dmaxrecs)(struct xfs_btree_cur *cur, int level);
201 201
202 /* init values of btree structures */ 202 /* init values of btree structures */
203 void (*init_key_from_rec)(union xfs_btree_key *key, 203 void (*init_key_from_rec)(union xfs_btree_key *key,
204 union xfs_btree_rec *rec); 204 union xfs_btree_rec *rec);
205 void (*init_rec_from_key)(union xfs_btree_key *key, 205 void (*init_rec_from_key)(union xfs_btree_key *key,
206 union xfs_btree_rec *rec); 206 union xfs_btree_rec *rec);
207 void (*init_rec_from_cur)(struct xfs_btree_cur *cur, 207 void (*init_rec_from_cur)(struct xfs_btree_cur *cur,
208 union xfs_btree_rec *rec); 208 union xfs_btree_rec *rec);
209 void (*init_ptr_from_cur)(struct xfs_btree_cur *cur, 209 void (*init_ptr_from_cur)(struct xfs_btree_cur *cur,
210 union xfs_btree_ptr *ptr); 210 union xfs_btree_ptr *ptr);
211 211
212 /* difference between key value and cursor value */ 212 /* difference between key value and cursor value */
213 __int64_t (*key_diff)(struct xfs_btree_cur *cur, 213 __int64_t (*key_diff)(struct xfs_btree_cur *cur,
214 union xfs_btree_key *key); 214 union xfs_btree_key *key);
215 215
216 const struct xfs_buf_ops *buf_ops; 216 const struct xfs_buf_ops *buf_ops;
217 217
218 #ifdef DEBUG 218 #if defined(DEBUG) || defined(XFS_WARN)
219 /* check that k1 is lower than k2 */ 219 /* check that k1 is lower than k2 */
220 int (*keys_inorder)(struct xfs_btree_cur *cur, 220 int (*keys_inorder)(struct xfs_btree_cur *cur,
221 union xfs_btree_key *k1, 221 union xfs_btree_key *k1,
222 union xfs_btree_key *k2); 222 union xfs_btree_key *k2);
223 223
224 /* check that r1 is lower than r2 */ 224 /* check that r1 is lower than r2 */
225 int (*recs_inorder)(struct xfs_btree_cur *cur, 225 int (*recs_inorder)(struct xfs_btree_cur *cur,
226 union xfs_btree_rec *r1, 226 union xfs_btree_rec *r1,
227 union xfs_btree_rec *r2); 227 union xfs_btree_rec *r2);
228 #endif 228 #endif
229 }; 229 };
230 230
231 /* 231 /*
232 * Reasons for the update_lastrec method to be called. 232 * Reasons for the update_lastrec method to be called.
233 */ 233 */
234 #define LASTREC_UPDATE 0 234 #define LASTREC_UPDATE 0
235 #define LASTREC_INSREC 1 235 #define LASTREC_INSREC 1
236 #define LASTREC_DELREC 2 236 #define LASTREC_DELREC 2
237 237
238 238
239 /* 239 /*
240 * Btree cursor structure. 240 * Btree cursor structure.
241 * This collects all information needed by the btree code in one place. 241 * This collects all information needed by the btree code in one place.
242 */ 242 */
243 typedef struct xfs_btree_cur 243 typedef struct xfs_btree_cur
244 { 244 {
245 struct xfs_trans *bc_tp; /* transaction we're in, if any */ 245 struct xfs_trans *bc_tp; /* transaction we're in, if any */
246 struct xfs_mount *bc_mp; /* file system mount struct */ 246 struct xfs_mount *bc_mp; /* file system mount struct */
247 const struct xfs_btree_ops *bc_ops; 247 const struct xfs_btree_ops *bc_ops;
248 uint bc_flags; /* btree features - below */ 248 uint bc_flags; /* btree features - below */
249 union { 249 union {
250 xfs_alloc_rec_incore_t a; 250 xfs_alloc_rec_incore_t a;
251 xfs_bmbt_irec_t b; 251 xfs_bmbt_irec_t b;
252 xfs_inobt_rec_incore_t i; 252 xfs_inobt_rec_incore_t i;
253 } bc_rec; /* current insert/search record value */ 253 } bc_rec; /* current insert/search record value */
254 struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ 254 struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */
255 int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ 255 int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */
256 __uint8_t bc_ra[XFS_BTREE_MAXLEVELS]; /* readahead bits */ 256 __uint8_t bc_ra[XFS_BTREE_MAXLEVELS]; /* readahead bits */
257 #define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */ 257 #define XFS_BTCUR_LEFTRA 1 /* left sibling has been read-ahead */
258 #define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */ 258 #define XFS_BTCUR_RIGHTRA 2 /* right sibling has been read-ahead */
259 __uint8_t bc_nlevels; /* number of levels in the tree */ 259 __uint8_t bc_nlevels; /* number of levels in the tree */
260 __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */ 260 __uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */
261 xfs_btnum_t bc_btnum; /* identifies which btree type */ 261 xfs_btnum_t bc_btnum; /* identifies which btree type */
262 union { 262 union {
263 struct { /* needed for BNO, CNT, INO */ 263 struct { /* needed for BNO, CNT, INO */
264 struct xfs_buf *agbp; /* agf/agi buffer pointer */ 264 struct xfs_buf *agbp; /* agf/agi buffer pointer */
265 xfs_agnumber_t agno; /* ag number */ 265 xfs_agnumber_t agno; /* ag number */
266 } a; 266 } a;
267 struct { /* needed for BMAP */ 267 struct { /* needed for BMAP */
268 struct xfs_inode *ip; /* pointer to our inode */ 268 struct xfs_inode *ip; /* pointer to our inode */
269 struct xfs_bmap_free *flist; /* list to free after */ 269 struct xfs_bmap_free *flist; /* list to free after */
270 xfs_fsblock_t firstblock; /* 1st blk allocated */ 270 xfs_fsblock_t firstblock; /* 1st blk allocated */
271 int allocated; /* count of alloced */ 271 int allocated; /* count of alloced */
272 short forksize; /* fork's inode space */ 272 short forksize; /* fork's inode space */
273 char whichfork; /* data or attr fork */ 273 char whichfork; /* data or attr fork */
274 char flags; /* flags */ 274 char flags; /* flags */
275 #define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */ 275 #define XFS_BTCUR_BPRV_WASDEL 1 /* was delayed */
276 } b; 276 } b;
277 } bc_private; /* per-btree type data */ 277 } bc_private; /* per-btree type data */
278 } xfs_btree_cur_t; 278 } xfs_btree_cur_t;
279 279
280 /* cursor flags */ 280 /* cursor flags */
281 #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */ 281 #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */
282 #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */ 282 #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */
283 #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */ 283 #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */
284 #define XFS_BTREE_CRC_BLOCKS (1<<3) /* uses extended btree blocks */ 284 #define XFS_BTREE_CRC_BLOCKS (1<<3) /* uses extended btree blocks */
285 285
286 286
287 #define XFS_BTREE_NOERROR 0 287 #define XFS_BTREE_NOERROR 0
288 #define XFS_BTREE_ERROR 1 288 #define XFS_BTREE_ERROR 1
289 289
290 /* 290 /*
291 * Convert from buffer to btree block header. 291 * Convert from buffer to btree block header.
292 */ 292 */
293 #define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr)) 293 #define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr))
294 294
295 295
296 /* 296 /*
297 * Check that block header is ok. 297 * Check that block header is ok.
298 */ 298 */
299 int 299 int
300 xfs_btree_check_block( 300 xfs_btree_check_block(
301 struct xfs_btree_cur *cur, /* btree cursor */ 301 struct xfs_btree_cur *cur, /* btree cursor */
302 struct xfs_btree_block *block, /* generic btree block pointer */ 302 struct xfs_btree_block *block, /* generic btree block pointer */
303 int level, /* level of the btree block */ 303 int level, /* level of the btree block */
304 struct xfs_buf *bp); /* buffer containing block, if any */ 304 struct xfs_buf *bp); /* buffer containing block, if any */
305 305
306 /* 306 /*
307 * Check that (long) pointer is ok. 307 * Check that (long) pointer is ok.
308 */ 308 */
309 int /* error (0 or EFSCORRUPTED) */ 309 int /* error (0 or EFSCORRUPTED) */
310 xfs_btree_check_lptr( 310 xfs_btree_check_lptr(
311 struct xfs_btree_cur *cur, /* btree cursor */ 311 struct xfs_btree_cur *cur, /* btree cursor */
312 xfs_dfsbno_t ptr, /* btree block disk address */ 312 xfs_dfsbno_t ptr, /* btree block disk address */
313 int level); /* btree block level */ 313 int level); /* btree block level */
314 314
315 /* 315 /*
316 * Delete the btree cursor. 316 * Delete the btree cursor.
317 */ 317 */
318 void 318 void
319 xfs_btree_del_cursor( 319 xfs_btree_del_cursor(
320 xfs_btree_cur_t *cur, /* btree cursor */ 320 xfs_btree_cur_t *cur, /* btree cursor */
321 int error); /* del because of error */ 321 int error); /* del because of error */
322 322
323 /* 323 /*
324 * Duplicate the btree cursor. 324 * Duplicate the btree cursor.
325 * Allocate a new one, copy the record, re-get the buffers. 325 * Allocate a new one, copy the record, re-get the buffers.
326 */ 326 */
327 int /* error */ 327 int /* error */
328 xfs_btree_dup_cursor( 328 xfs_btree_dup_cursor(
329 xfs_btree_cur_t *cur, /* input cursor */ 329 xfs_btree_cur_t *cur, /* input cursor */
330 xfs_btree_cur_t **ncur);/* output cursor */ 330 xfs_btree_cur_t **ncur);/* output cursor */
331 331
332 /* 332 /*
333 * Get a buffer for the block, return it with no data read. 333 * Get a buffer for the block, return it with no data read.
334 * Long-form addressing. 334 * Long-form addressing.
335 */ 335 */
336 struct xfs_buf * /* buffer for fsbno */ 336 struct xfs_buf * /* buffer for fsbno */
337 xfs_btree_get_bufl( 337 xfs_btree_get_bufl(
338 struct xfs_mount *mp, /* file system mount point */ 338 struct xfs_mount *mp, /* file system mount point */
339 struct xfs_trans *tp, /* transaction pointer */ 339 struct xfs_trans *tp, /* transaction pointer */
340 xfs_fsblock_t fsbno, /* file system block number */ 340 xfs_fsblock_t fsbno, /* file system block number */
341 uint lock); /* lock flags for get_buf */ 341 uint lock); /* lock flags for get_buf */
342 342
343 /* 343 /*
344 * Get a buffer for the block, return it with no data read. 344 * Get a buffer for the block, return it with no data read.
345 * Short-form addressing. 345 * Short-form addressing.
346 */ 346 */
347 struct xfs_buf * /* buffer for agno/agbno */ 347 struct xfs_buf * /* buffer for agno/agbno */
348 xfs_btree_get_bufs( 348 xfs_btree_get_bufs(
349 struct xfs_mount *mp, /* file system mount point */ 349 struct xfs_mount *mp, /* file system mount point */
350 struct xfs_trans *tp, /* transaction pointer */ 350 struct xfs_trans *tp, /* transaction pointer */
351 xfs_agnumber_t agno, /* allocation group number */ 351 xfs_agnumber_t agno, /* allocation group number */
352 xfs_agblock_t agbno, /* allocation group block number */ 352 xfs_agblock_t agbno, /* allocation group block number */
353 uint lock); /* lock flags for get_buf */ 353 uint lock); /* lock flags for get_buf */
354 354
355 /* 355 /*
356 * Check for the cursor referring to the last block at the given level. 356 * Check for the cursor referring to the last block at the given level.
357 */ 357 */
358 int /* 1=is last block, 0=not last block */ 358 int /* 1=is last block, 0=not last block */
359 xfs_btree_islastblock( 359 xfs_btree_islastblock(
360 xfs_btree_cur_t *cur, /* btree cursor */ 360 xfs_btree_cur_t *cur, /* btree cursor */
361 int level); /* level to check */ 361 int level); /* level to check */
362 362
363 /* 363 /*
364 * Compute first and last byte offsets for the fields given. 364 * Compute first and last byte offsets for the fields given.
365 * Interprets the offsets table, which contains struct field offsets. 365 * Interprets the offsets table, which contains struct field offsets.
366 */ 366 */
367 void 367 void
368 xfs_btree_offsets( 368 xfs_btree_offsets(
369 __int64_t fields, /* bitmask of fields */ 369 __int64_t fields, /* bitmask of fields */
370 const short *offsets,/* table of field offsets */ 370 const short *offsets,/* table of field offsets */
371 int nbits, /* number of bits to inspect */ 371 int nbits, /* number of bits to inspect */
372 int *first, /* output: first byte offset */ 372 int *first, /* output: first byte offset */
373 int *last); /* output: last byte offset */ 373 int *last); /* output: last byte offset */
374 374
375 /* 375 /*
376 * Get a buffer for the block, return it read in. 376 * Get a buffer for the block, return it read in.
377 * Long-form addressing. 377 * Long-form addressing.
378 */ 378 */
379 int /* error */ 379 int /* error */
380 xfs_btree_read_bufl( 380 xfs_btree_read_bufl(
381 struct xfs_mount *mp, /* file system mount point */ 381 struct xfs_mount *mp, /* file system mount point */
382 struct xfs_trans *tp, /* transaction pointer */ 382 struct xfs_trans *tp, /* transaction pointer */
383 xfs_fsblock_t fsbno, /* file system block number */ 383 xfs_fsblock_t fsbno, /* file system block number */
384 uint lock, /* lock flags for read_buf */ 384 uint lock, /* lock flags for read_buf */
385 struct xfs_buf **bpp, /* buffer for fsbno */ 385 struct xfs_buf **bpp, /* buffer for fsbno */
386 int refval, /* ref count value for buffer */ 386 int refval, /* ref count value for buffer */
387 const struct xfs_buf_ops *ops); 387 const struct xfs_buf_ops *ops);
388 388
389 /* 389 /*
390 * Read-ahead the block, don't wait for it, don't return a buffer. 390 * Read-ahead the block, don't wait for it, don't return a buffer.
391 * Long-form addressing. 391 * Long-form addressing.
392 */ 392 */
393 void /* error */ 393 void /* error */
394 xfs_btree_reada_bufl( 394 xfs_btree_reada_bufl(
395 struct xfs_mount *mp, /* file system mount point */ 395 struct xfs_mount *mp, /* file system mount point */
396 xfs_fsblock_t fsbno, /* file system block number */ 396 xfs_fsblock_t fsbno, /* file system block number */
397 xfs_extlen_t count, /* count of filesystem blocks */ 397 xfs_extlen_t count, /* count of filesystem blocks */
398 const struct xfs_buf_ops *ops); 398 const struct xfs_buf_ops *ops);
399 399
400 /* 400 /*
401 * Read-ahead the block, don't wait for it, don't return a buffer. 401 * Read-ahead the block, don't wait for it, don't return a buffer.
402 * Short-form addressing. 402 * Short-form addressing.
403 */ 403 */
404 void /* error */ 404 void /* error */
405 xfs_btree_reada_bufs( 405 xfs_btree_reada_bufs(
406 struct xfs_mount *mp, /* file system mount point */ 406 struct xfs_mount *mp, /* file system mount point */
407 xfs_agnumber_t agno, /* allocation group number */ 407 xfs_agnumber_t agno, /* allocation group number */
408 xfs_agblock_t agbno, /* allocation group block number */ 408 xfs_agblock_t agbno, /* allocation group block number */
409 xfs_extlen_t count, /* count of filesystem blocks */ 409 xfs_extlen_t count, /* count of filesystem blocks */
410 const struct xfs_buf_ops *ops); 410 const struct xfs_buf_ops *ops);
411 411
412 /* 412 /*
413 * Initialise a new btree block header 413 * Initialise a new btree block header
414 */ 414 */
415 void 415 void
416 xfs_btree_init_block( 416 xfs_btree_init_block(
417 struct xfs_mount *mp, 417 struct xfs_mount *mp,
418 struct xfs_buf *bp, 418 struct xfs_buf *bp,
419 __u32 magic, 419 __u32 magic,
420 __u16 level, 420 __u16 level,
421 __u16 numrecs, 421 __u16 numrecs,
422 __u64 owner, 422 __u64 owner,
423 unsigned int flags); 423 unsigned int flags);
424 424
425 void 425 void
426 xfs_btree_init_block_int( 426 xfs_btree_init_block_int(
427 struct xfs_mount *mp, 427 struct xfs_mount *mp,
428 struct xfs_btree_block *buf, 428 struct xfs_btree_block *buf,
429 xfs_daddr_t blkno, 429 xfs_daddr_t blkno,
430 __u32 magic, 430 __u32 magic,
431 __u16 level, 431 __u16 level,
432 __u16 numrecs, 432 __u16 numrecs,
433 __u64 owner, 433 __u64 owner,
434 unsigned int flags); 434 unsigned int flags);
435 435
436 /* 436 /*
437 * Common btree core entry points. 437 * Common btree core entry points.
438 */ 438 */
439 int xfs_btree_increment(struct xfs_btree_cur *, int, int *); 439 int xfs_btree_increment(struct xfs_btree_cur *, int, int *);
440 int xfs_btree_decrement(struct xfs_btree_cur *, int, int *); 440 int xfs_btree_decrement(struct xfs_btree_cur *, int, int *);
441 int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *); 441 int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *);
442 int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *); 442 int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *);
443 int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *); 443 int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *);
444 int xfs_btree_insert(struct xfs_btree_cur *, int *); 444 int xfs_btree_insert(struct xfs_btree_cur *, int *);
445 int xfs_btree_delete(struct xfs_btree_cur *, int *); 445 int xfs_btree_delete(struct xfs_btree_cur *, int *);
446 int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *); 446 int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *);
447 447
448 /* 448 /*
449 * btree block CRC helpers 449 * btree block CRC helpers
450 */ 450 */
451 void xfs_btree_lblock_calc_crc(struct xfs_buf *); 451 void xfs_btree_lblock_calc_crc(struct xfs_buf *);
452 bool xfs_btree_lblock_verify_crc(struct xfs_buf *); 452 bool xfs_btree_lblock_verify_crc(struct xfs_buf *);
453 void xfs_btree_sblock_calc_crc(struct xfs_buf *); 453 void xfs_btree_sblock_calc_crc(struct xfs_buf *);
454 bool xfs_btree_sblock_verify_crc(struct xfs_buf *); 454 bool xfs_btree_sblock_verify_crc(struct xfs_buf *);
455 455
456 /* 456 /*
457 * Internal btree helpers also used by xfs_bmap.c. 457 * Internal btree helpers also used by xfs_bmap.c.
458 */ 458 */
459 void xfs_btree_log_block(struct xfs_btree_cur *, struct xfs_buf *, int); 459 void xfs_btree_log_block(struct xfs_btree_cur *, struct xfs_buf *, int);
460 void xfs_btree_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, int); 460 void xfs_btree_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, int);
461 461
462 /* 462 /*
463 * Helpers. 463 * Helpers.
464 */ 464 */
465 static inline int xfs_btree_get_numrecs(struct xfs_btree_block *block) 465 static inline int xfs_btree_get_numrecs(struct xfs_btree_block *block)
466 { 466 {
467 return be16_to_cpu(block->bb_numrecs); 467 return be16_to_cpu(block->bb_numrecs);
468 } 468 }
469 469
470 static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block, 470 static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block,
471 __uint16_t numrecs) 471 __uint16_t numrecs)
472 { 472 {
473 block->bb_numrecs = cpu_to_be16(numrecs); 473 block->bb_numrecs = cpu_to_be16(numrecs);
474 } 474 }
475 475
476 static inline int xfs_btree_get_level(struct xfs_btree_block *block) 476 static inline int xfs_btree_get_level(struct xfs_btree_block *block)
477 { 477 {
478 return be16_to_cpu(block->bb_level); 478 return be16_to_cpu(block->bb_level);
479 } 479 }
480 480
481 481
482 /* 482 /*
483 * Min and max functions for extlen, agblock, fileoff, and filblks types. 483 * Min and max functions for extlen, agblock, fileoff, and filblks types.
484 */ 484 */
485 #define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b)) 485 #define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b))
486 #define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b)) 486 #define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b))
487 #define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b)) 487 #define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b))
488 #define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b)) 488 #define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b))
489 #define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b)) 489 #define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b))
490 #define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b)) 490 #define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b))
491 #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b)) 491 #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b))
492 #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b)) 492 #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b))
493 493
494 #define XFS_FSB_SANITY_CHECK(mp,fsb) \ 494 #define XFS_FSB_SANITY_CHECK(mp,fsb) \
495 (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \ 495 (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \
496 XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks) 496 XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks)
497 497
498 /* 498 /*
499 * Trace hooks. Currently not implemented as they need to be ported 499 * Trace hooks. Currently not implemented as they need to be ported
500 * over to the generic tracing functionality, which is some effort. 500 * over to the generic tracing functionality, which is some effort.
501 * 501 *
502 * i,j = integer (32 bit) 502 * i,j = integer (32 bit)
503 * b = btree block buffer (xfs_buf_t) 503 * b = btree block buffer (xfs_buf_t)
504 * p = btree ptr 504 * p = btree ptr
505 * r = btree record 505 * r = btree record
506 * k = btree key 506 * k = btree key
507 */ 507 */
508 #define XFS_BTREE_TRACE_ARGBI(c, b, i) 508 #define XFS_BTREE_TRACE_ARGBI(c, b, i)
509 #define XFS_BTREE_TRACE_ARGBII(c, b, i, j) 509 #define XFS_BTREE_TRACE_ARGBII(c, b, i, j)
510 #define XFS_BTREE_TRACE_ARGI(c, i) 510 #define XFS_BTREE_TRACE_ARGI(c, i)
511 #define XFS_BTREE_TRACE_ARGIPK(c, i, p, s) 511 #define XFS_BTREE_TRACE_ARGIPK(c, i, p, s)
512 #define XFS_BTREE_TRACE_ARGIPR(c, i, p, r) 512 #define XFS_BTREE_TRACE_ARGIPR(c, i, p, r)
513 #define XFS_BTREE_TRACE_ARGIK(c, i, k) 513 #define XFS_BTREE_TRACE_ARGIK(c, i, k)
514 #define XFS_BTREE_TRACE_ARGR(c, r) 514 #define XFS_BTREE_TRACE_ARGR(c, r)
515 #define XFS_BTREE_TRACE_CURSOR(c, t) 515 #define XFS_BTREE_TRACE_CURSOR(c, t)
516 516
517 #endif /* __XFS_BTREE_H__ */ 517 #endif /* __XFS_BTREE_H__ */
518 518
fs/xfs/xfs_dir2_node.c
1 /* 1 /*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * Copyright (c) 2013 Red Hat, Inc. 3 * Copyright (c) 2013 Red Hat, Inc.
4 * All Rights Reserved. 4 * All Rights Reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as 7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it would be useful, 10 * This program is distributed in the hope that it would be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write the Free Software Foundation, 16 * along with this program; if not, write the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */ 18 */
19 #include "xfs.h" 19 #include "xfs.h"
20 #include "xfs_fs.h" 20 #include "xfs_fs.h"
21 #include "xfs_types.h" 21 #include "xfs_types.h"
22 #include "xfs_log.h" 22 #include "xfs_log.h"
23 #include "xfs_trans.h" 23 #include "xfs_trans.h"
24 #include "xfs_sb.h" 24 #include "xfs_sb.h"
25 #include "xfs_ag.h" 25 #include "xfs_ag.h"
26 #include "xfs_mount.h" 26 #include "xfs_mount.h"
27 #include "xfs_da_btree.h" 27 #include "xfs_da_btree.h"
28 #include "xfs_bmap_btree.h" 28 #include "xfs_bmap_btree.h"
29 #include "xfs_dinode.h" 29 #include "xfs_dinode.h"
30 #include "xfs_inode.h" 30 #include "xfs_inode.h"
31 #include "xfs_bmap.h" 31 #include "xfs_bmap.h"
32 #include "xfs_dir2_format.h" 32 #include "xfs_dir2_format.h"
33 #include "xfs_dir2_priv.h" 33 #include "xfs_dir2_priv.h"
34 #include "xfs_error.h" 34 #include "xfs_error.h"
35 #include "xfs_trace.h" 35 #include "xfs_trace.h"
36 #include "xfs_buf_item.h" 36 #include "xfs_buf_item.h"
37 #include "xfs_cksum.h" 37 #include "xfs_cksum.h"
38 38
39 /* 39 /*
40 * Function declarations. 40 * Function declarations.
41 */ 41 */
42 static int xfs_dir2_leafn_add(struct xfs_buf *bp, xfs_da_args_t *args, 42 static int xfs_dir2_leafn_add(struct xfs_buf *bp, xfs_da_args_t *args,
43 int index); 43 int index);
44 static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state, 44 static void xfs_dir2_leafn_rebalance(xfs_da_state_t *state,
45 xfs_da_state_blk_t *blk1, 45 xfs_da_state_blk_t *blk1,
46 xfs_da_state_blk_t *blk2); 46 xfs_da_state_blk_t *blk2);
47 static int xfs_dir2_leafn_remove(xfs_da_args_t *args, struct xfs_buf *bp, 47 static int xfs_dir2_leafn_remove(xfs_da_args_t *args, struct xfs_buf *bp,
48 int index, xfs_da_state_blk_t *dblk, 48 int index, xfs_da_state_blk_t *dblk,
49 int *rval); 49 int *rval);
50 static int xfs_dir2_node_addname_int(xfs_da_args_t *args, 50 static int xfs_dir2_node_addname_int(xfs_da_args_t *args,
51 xfs_da_state_blk_t *fblk); 51 xfs_da_state_blk_t *fblk);
52 52
53 /* 53 /*
54 * Check internal consistency of a leafn block. 54 * Check internal consistency of a leafn block.
55 */ 55 */
56 #ifdef DEBUG 56 #ifdef DEBUG
57 #define xfs_dir3_leaf_check(mp, bp) \ 57 #define xfs_dir3_leaf_check(mp, bp) \
58 do { \ 58 do { \
59 if (!xfs_dir3_leafn_check((mp), (bp))) \ 59 if (!xfs_dir3_leafn_check((mp), (bp))) \
60 ASSERT(0); \ 60 ASSERT(0); \
61 } while (0); 61 } while (0);
62 62
63 static bool 63 static bool
64 xfs_dir3_leafn_check( 64 xfs_dir3_leafn_check(
65 struct xfs_mount *mp, 65 struct xfs_mount *mp,
66 struct xfs_buf *bp) 66 struct xfs_buf *bp)
67 { 67 {
68 struct xfs_dir2_leaf *leaf = bp->b_addr; 68 struct xfs_dir2_leaf *leaf = bp->b_addr;
69 struct xfs_dir3_icleaf_hdr leafhdr; 69 struct xfs_dir3_icleaf_hdr leafhdr;
70 70
71 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); 71 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
72 72
73 if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) { 73 if (leafhdr.magic == XFS_DIR3_LEAFN_MAGIC) {
74 struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; 74 struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
75 if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn) 75 if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
76 return false; 76 return false;
77 } else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC) 77 } else if (leafhdr.magic != XFS_DIR2_LEAFN_MAGIC)
78 return false; 78 return false;
79 79
80 return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf); 80 return xfs_dir3_leaf_check_int(mp, &leafhdr, leaf);
81 } 81 }
82 #else 82 #else
83 #define xfs_dir3_leaf_check(mp, bp) 83 #define xfs_dir3_leaf_check(mp, bp)
84 #endif 84 #endif
85 85
86 static bool 86 static bool
87 xfs_dir3_free_verify( 87 xfs_dir3_free_verify(
88 struct xfs_buf *bp) 88 struct xfs_buf *bp)
89 { 89 {
90 struct xfs_mount *mp = bp->b_target->bt_mount; 90 struct xfs_mount *mp = bp->b_target->bt_mount;
91 struct xfs_dir2_free_hdr *hdr = bp->b_addr; 91 struct xfs_dir2_free_hdr *hdr = bp->b_addr;
92 92
93 if (xfs_sb_version_hascrc(&mp->m_sb)) { 93 if (xfs_sb_version_hascrc(&mp->m_sb)) {
94 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; 94 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
95 95
96 if (hdr3->magic != cpu_to_be32(XFS_DIR3_FREE_MAGIC)) 96 if (hdr3->magic != cpu_to_be32(XFS_DIR3_FREE_MAGIC))
97 return false; 97 return false;
98 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid)) 98 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid))
99 return false; 99 return false;
100 if (be64_to_cpu(hdr3->blkno) != bp->b_bn) 100 if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
101 return false; 101 return false;
102 } else { 102 } else {
103 if (hdr->magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC)) 103 if (hdr->magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC))
104 return false; 104 return false;
105 } 105 }
106 106
107 /* XXX: should bounds check the xfs_dir3_icfree_hdr here */ 107 /* XXX: should bounds check the xfs_dir3_icfree_hdr here */
108 108
109 return true; 109 return true;
110 } 110 }
111 111
112 static void 112 static void
113 xfs_dir3_free_read_verify( 113 xfs_dir3_free_read_verify(
114 struct xfs_buf *bp) 114 struct xfs_buf *bp)
115 { 115 {
116 struct xfs_mount *mp = bp->b_target->bt_mount; 116 struct xfs_mount *mp = bp->b_target->bt_mount;
117 117
118 if ((xfs_sb_version_hascrc(&mp->m_sb) && 118 if ((xfs_sb_version_hascrc(&mp->m_sb) &&
119 !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length), 119 !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
120 XFS_DIR3_FREE_CRC_OFF)) || 120 XFS_DIR3_FREE_CRC_OFF)) ||
121 !xfs_dir3_free_verify(bp)) { 121 !xfs_dir3_free_verify(bp)) {
122 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); 122 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
123 xfs_buf_ioerror(bp, EFSCORRUPTED); 123 xfs_buf_ioerror(bp, EFSCORRUPTED);
124 } 124 }
125 } 125 }
126 126
127 static void 127 static void
128 xfs_dir3_free_write_verify( 128 xfs_dir3_free_write_verify(
129 struct xfs_buf *bp) 129 struct xfs_buf *bp)
130 { 130 {
131 struct xfs_mount *mp = bp->b_target->bt_mount; 131 struct xfs_mount *mp = bp->b_target->bt_mount;
132 struct xfs_buf_log_item *bip = bp->b_fspriv; 132 struct xfs_buf_log_item *bip = bp->b_fspriv;
133 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; 133 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
134 134
135 if (!xfs_dir3_free_verify(bp)) { 135 if (!xfs_dir3_free_verify(bp)) {
136 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); 136 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
137 xfs_buf_ioerror(bp, EFSCORRUPTED); 137 xfs_buf_ioerror(bp, EFSCORRUPTED);
138 return; 138 return;
139 } 139 }
140 140
141 if (!xfs_sb_version_hascrc(&mp->m_sb)) 141 if (!xfs_sb_version_hascrc(&mp->m_sb))
142 return; 142 return;
143 143
144 if (bip) 144 if (bip)
145 hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn); 145 hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
146 146
147 xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_FREE_CRC_OFF); 147 xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_FREE_CRC_OFF);
148 } 148 }
149 149
150 const struct xfs_buf_ops xfs_dir3_free_buf_ops = { 150 const struct xfs_buf_ops xfs_dir3_free_buf_ops = {
151 .verify_read = xfs_dir3_free_read_verify, 151 .verify_read = xfs_dir3_free_read_verify,
152 .verify_write = xfs_dir3_free_write_verify, 152 .verify_write = xfs_dir3_free_write_verify,
153 }; 153 };
154 154
155 155
156 static int 156 static int
157 __xfs_dir3_free_read( 157 __xfs_dir3_free_read(
158 struct xfs_trans *tp, 158 struct xfs_trans *tp,
159 struct xfs_inode *dp, 159 struct xfs_inode *dp,
160 xfs_dablk_t fbno, 160 xfs_dablk_t fbno,
161 xfs_daddr_t mappedbno, 161 xfs_daddr_t mappedbno,
162 struct xfs_buf **bpp) 162 struct xfs_buf **bpp)
163 { 163 {
164 int err; 164 int err;
165 165
166 err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 166 err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
167 XFS_DATA_FORK, &xfs_dir3_free_buf_ops); 167 XFS_DATA_FORK, &xfs_dir3_free_buf_ops);
168 168
169 /* try read returns without an error or *bpp if it lands in a hole */ 169 /* try read returns without an error or *bpp if it lands in a hole */
170 if (!err && tp && *bpp) 170 if (!err && tp && *bpp)
171 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_FREE_BUF); 171 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_FREE_BUF);
172 return err; 172 return err;
173 } 173 }
174 174
175 int 175 int
176 xfs_dir2_free_read( 176 xfs_dir2_free_read(
177 struct xfs_trans *tp, 177 struct xfs_trans *tp,
178 struct xfs_inode *dp, 178 struct xfs_inode *dp,
179 xfs_dablk_t fbno, 179 xfs_dablk_t fbno,
180 struct xfs_buf **bpp) 180 struct xfs_buf **bpp)
181 { 181 {
182 return __xfs_dir3_free_read(tp, dp, fbno, -1, bpp); 182 return __xfs_dir3_free_read(tp, dp, fbno, -1, bpp);
183 } 183 }
184 184
185 static int 185 static int
186 xfs_dir2_free_try_read( 186 xfs_dir2_free_try_read(
187 struct xfs_trans *tp, 187 struct xfs_trans *tp,
188 struct xfs_inode *dp, 188 struct xfs_inode *dp,
189 xfs_dablk_t fbno, 189 xfs_dablk_t fbno,
190 struct xfs_buf **bpp) 190 struct xfs_buf **bpp)
191 { 191 {
192 return __xfs_dir3_free_read(tp, dp, fbno, -2, bpp); 192 return __xfs_dir3_free_read(tp, dp, fbno, -2, bpp);
193 } 193 }
194 194
195 195
196 void 196 void
197 xfs_dir3_free_hdr_from_disk( 197 xfs_dir3_free_hdr_from_disk(
198 struct xfs_dir3_icfree_hdr *to, 198 struct xfs_dir3_icfree_hdr *to,
199 struct xfs_dir2_free *from) 199 struct xfs_dir2_free *from)
200 { 200 {
201 if (from->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)) { 201 if (from->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)) {
202 to->magic = be32_to_cpu(from->hdr.magic); 202 to->magic = be32_to_cpu(from->hdr.magic);
203 to->firstdb = be32_to_cpu(from->hdr.firstdb); 203 to->firstdb = be32_to_cpu(from->hdr.firstdb);
204 to->nvalid = be32_to_cpu(from->hdr.nvalid); 204 to->nvalid = be32_to_cpu(from->hdr.nvalid);
205 to->nused = be32_to_cpu(from->hdr.nused); 205 to->nused = be32_to_cpu(from->hdr.nused);
206 } else { 206 } else {
207 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from; 207 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)from;
208 208
209 to->magic = be32_to_cpu(hdr3->hdr.magic); 209 to->magic = be32_to_cpu(hdr3->hdr.magic);
210 to->firstdb = be32_to_cpu(hdr3->firstdb); 210 to->firstdb = be32_to_cpu(hdr3->firstdb);
211 to->nvalid = be32_to_cpu(hdr3->nvalid); 211 to->nvalid = be32_to_cpu(hdr3->nvalid);
212 to->nused = be32_to_cpu(hdr3->nused); 212 to->nused = be32_to_cpu(hdr3->nused);
213 } 213 }
214 214
215 ASSERT(to->magic == XFS_DIR2_FREE_MAGIC || 215 ASSERT(to->magic == XFS_DIR2_FREE_MAGIC ||
216 to->magic == XFS_DIR3_FREE_MAGIC); 216 to->magic == XFS_DIR3_FREE_MAGIC);
217 } 217 }
218 218
219 static void 219 static void
220 xfs_dir3_free_hdr_to_disk( 220 xfs_dir3_free_hdr_to_disk(
221 struct xfs_dir2_free *to, 221 struct xfs_dir2_free *to,
222 struct xfs_dir3_icfree_hdr *from) 222 struct xfs_dir3_icfree_hdr *from)
223 { 223 {
224 ASSERT(from->magic == XFS_DIR2_FREE_MAGIC || 224 ASSERT(from->magic == XFS_DIR2_FREE_MAGIC ||
225 from->magic == XFS_DIR3_FREE_MAGIC); 225 from->magic == XFS_DIR3_FREE_MAGIC);
226 226
227 if (from->magic == XFS_DIR2_FREE_MAGIC) { 227 if (from->magic == XFS_DIR2_FREE_MAGIC) {
228 to->hdr.magic = cpu_to_be32(from->magic); 228 to->hdr.magic = cpu_to_be32(from->magic);
229 to->hdr.firstdb = cpu_to_be32(from->firstdb); 229 to->hdr.firstdb = cpu_to_be32(from->firstdb);
230 to->hdr.nvalid = cpu_to_be32(from->nvalid); 230 to->hdr.nvalid = cpu_to_be32(from->nvalid);
231 to->hdr.nused = cpu_to_be32(from->nused); 231 to->hdr.nused = cpu_to_be32(from->nused);
232 } else { 232 } else {
233 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to; 233 struct xfs_dir3_free_hdr *hdr3 = (struct xfs_dir3_free_hdr *)to;
234 234
235 hdr3->hdr.magic = cpu_to_be32(from->magic); 235 hdr3->hdr.magic = cpu_to_be32(from->magic);
236 hdr3->firstdb = cpu_to_be32(from->firstdb); 236 hdr3->firstdb = cpu_to_be32(from->firstdb);
237 hdr3->nvalid = cpu_to_be32(from->nvalid); 237 hdr3->nvalid = cpu_to_be32(from->nvalid);
238 hdr3->nused = cpu_to_be32(from->nused); 238 hdr3->nused = cpu_to_be32(from->nused);
239 } 239 }
240 } 240 }
241 241
242 static int 242 static int
243 xfs_dir3_free_get_buf( 243 xfs_dir3_free_get_buf(
244 struct xfs_trans *tp, 244 struct xfs_trans *tp,
245 struct xfs_inode *dp, 245 struct xfs_inode *dp,
246 xfs_dir2_db_t fbno, 246 xfs_dir2_db_t fbno,
247 struct xfs_buf **bpp) 247 struct xfs_buf **bpp)
248 { 248 {
249 struct xfs_mount *mp = dp->i_mount; 249 struct xfs_mount *mp = dp->i_mount;
250 struct xfs_buf *bp; 250 struct xfs_buf *bp;
251 int error; 251 int error;
252 struct xfs_dir3_icfree_hdr hdr; 252 struct xfs_dir3_icfree_hdr hdr;
253 253
254 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno), 254 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno),
255 -1, &bp, XFS_DATA_FORK); 255 -1, &bp, XFS_DATA_FORK);
256 if (error) 256 if (error)
257 return error; 257 return error;
258 258
259 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_FREE_BUF); 259 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_FREE_BUF);
260 bp->b_ops = &xfs_dir3_free_buf_ops; 260 bp->b_ops = &xfs_dir3_free_buf_ops;
261 261
262 /* 262 /*
263 * Initialize the new block to be empty, and remember 263 * Initialize the new block to be empty, and remember
264 * its first slot as our empty slot. 264 * its first slot as our empty slot.
265 */ 265 */
266 hdr.magic = XFS_DIR2_FREE_MAGIC; 266 hdr.magic = XFS_DIR2_FREE_MAGIC;
267 hdr.firstdb = 0; 267 hdr.firstdb = 0;
268 hdr.nused = 0; 268 hdr.nused = 0;
269 hdr.nvalid = 0; 269 hdr.nvalid = 0;
270 if (xfs_sb_version_hascrc(&mp->m_sb)) { 270 if (xfs_sb_version_hascrc(&mp->m_sb)) {
271 struct xfs_dir3_free_hdr *hdr3 = bp->b_addr; 271 struct xfs_dir3_free_hdr *hdr3 = bp->b_addr;
272 272
273 hdr.magic = XFS_DIR3_FREE_MAGIC; 273 hdr.magic = XFS_DIR3_FREE_MAGIC;
274 hdr3->hdr.blkno = cpu_to_be64(bp->b_bn); 274 hdr3->hdr.blkno = cpu_to_be64(bp->b_bn);
275 hdr3->hdr.owner = cpu_to_be64(dp->i_ino); 275 hdr3->hdr.owner = cpu_to_be64(dp->i_ino);
276 uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid); 276 uuid_copy(&hdr3->hdr.uuid, &mp->m_sb.sb_uuid);
277 } 277 }
278 xfs_dir3_free_hdr_to_disk(bp->b_addr, &hdr); 278 xfs_dir3_free_hdr_to_disk(bp->b_addr, &hdr);
279 *bpp = bp; 279 *bpp = bp;
280 return 0; 280 return 0;
281 } 281 }
282 282
283 /* 283 /*
284 * Log entries from a freespace block. 284 * Log entries from a freespace block.
285 */ 285 */
286 STATIC void 286 STATIC void
287 xfs_dir2_free_log_bests( 287 xfs_dir2_free_log_bests(
288 struct xfs_trans *tp, 288 struct xfs_trans *tp,
289 struct xfs_buf *bp, 289 struct xfs_buf *bp,
290 int first, /* first entry to log */ 290 int first, /* first entry to log */
291 int last) /* last entry to log */ 291 int last) /* last entry to log */
292 { 292 {
293 xfs_dir2_free_t *free; /* freespace structure */ 293 xfs_dir2_free_t *free; /* freespace structure */
294 __be16 *bests; 294 __be16 *bests;
295 295
296 free = bp->b_addr; 296 free = bp->b_addr;
297 bests = xfs_dir3_free_bests_p(tp->t_mountp, free); 297 bests = xfs_dir3_free_bests_p(tp->t_mountp, free);
298 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || 298 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
299 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); 299 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
300 xfs_trans_log_buf(tp, bp, 300 xfs_trans_log_buf(tp, bp,
301 (uint)((char *)&bests[first] - (char *)free), 301 (uint)((char *)&bests[first] - (char *)free),
302 (uint)((char *)&bests[last] - (char *)free + 302 (uint)((char *)&bests[last] - (char *)free +
303 sizeof(bests[0]) - 1)); 303 sizeof(bests[0]) - 1));
304 } 304 }
305 305
306 /* 306 /*
307 * Log header from a freespace block. 307 * Log header from a freespace block.
308 */ 308 */
309 static void 309 static void
310 xfs_dir2_free_log_header( 310 xfs_dir2_free_log_header(
311 struct xfs_trans *tp, 311 struct xfs_trans *tp,
312 struct xfs_buf *bp) 312 struct xfs_buf *bp)
313 { 313 {
314 xfs_dir2_free_t *free; /* freespace structure */ 314 xfs_dir2_free_t *free; /* freespace structure */
315 315
316 free = bp->b_addr; 316 free = bp->b_addr;
317 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || 317 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
318 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); 318 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
319 xfs_trans_log_buf(tp, bp, 0, xfs_dir3_free_hdr_size(tp->t_mountp) - 1); 319 xfs_trans_log_buf(tp, bp, 0, xfs_dir3_free_hdr_size(tp->t_mountp) - 1);
320 } 320 }
321 321
322 /* 322 /*
323 * Convert a leaf-format directory to a node-format directory. 323 * Convert a leaf-format directory to a node-format directory.
324 * We need to change the magic number of the leaf block, and copy 324 * We need to change the magic number of the leaf block, and copy
325 * the freespace table out of the leaf block into its own block. 325 * the freespace table out of the leaf block into its own block.
326 */ 326 */
327 int /* error */ 327 int /* error */
328 xfs_dir2_leaf_to_node( 328 xfs_dir2_leaf_to_node(
329 xfs_da_args_t *args, /* operation arguments */ 329 xfs_da_args_t *args, /* operation arguments */
330 struct xfs_buf *lbp) /* leaf buffer */ 330 struct xfs_buf *lbp) /* leaf buffer */
331 { 331 {
332 xfs_inode_t *dp; /* incore directory inode */ 332 xfs_inode_t *dp; /* incore directory inode */
333 int error; /* error return value */ 333 int error; /* error return value */
334 struct xfs_buf *fbp; /* freespace buffer */ 334 struct xfs_buf *fbp; /* freespace buffer */
335 xfs_dir2_db_t fdb; /* freespace block number */ 335 xfs_dir2_db_t fdb; /* freespace block number */
336 xfs_dir2_free_t *free; /* freespace structure */ 336 xfs_dir2_free_t *free; /* freespace structure */
337 __be16 *from; /* pointer to freespace entry */ 337 __be16 *from; /* pointer to freespace entry */
338 int i; /* leaf freespace index */ 338 int i; /* leaf freespace index */
339 xfs_dir2_leaf_t *leaf; /* leaf structure */ 339 xfs_dir2_leaf_t *leaf; /* leaf structure */
340 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ 340 xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
341 xfs_mount_t *mp; /* filesystem mount point */ 341 xfs_mount_t *mp; /* filesystem mount point */
342 int n; /* count of live freespc ents */ 342 int n; /* count of live freespc ents */
343 xfs_dir2_data_off_t off; /* freespace entry value */ 343 xfs_dir2_data_off_t off; /* freespace entry value */
344 __be16 *to; /* pointer to freespace entry */ 344 __be16 *to; /* pointer to freespace entry */
345 xfs_trans_t *tp; /* transaction pointer */ 345 xfs_trans_t *tp; /* transaction pointer */
346 struct xfs_dir3_icfree_hdr freehdr; 346 struct xfs_dir3_icfree_hdr freehdr;
347 347
348 trace_xfs_dir2_leaf_to_node(args); 348 trace_xfs_dir2_leaf_to_node(args);
349 349
350 dp = args->dp; 350 dp = args->dp;
351 mp = dp->i_mount; 351 mp = dp->i_mount;
352 tp = args->trans; 352 tp = args->trans;
353 /* 353 /*
354 * Add a freespace block to the directory. 354 * Add a freespace block to the directory.
355 */ 355 */
356 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) { 356 if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) {
357 return error; 357 return error;
358 } 358 }
359 ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp)); 359 ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp));
360 /* 360 /*
361 * Get the buffer for the new freespace block. 361 * Get the buffer for the new freespace block.
362 */ 362 */
363 error = xfs_dir3_free_get_buf(tp, dp, fdb, &fbp); 363 error = xfs_dir3_free_get_buf(tp, dp, fdb, &fbp);
364 if (error) 364 if (error)
365 return error; 365 return error;
366 366
367 free = fbp->b_addr; 367 free = fbp->b_addr;
368 xfs_dir3_free_hdr_from_disk(&freehdr, free); 368 xfs_dir3_free_hdr_from_disk(&freehdr, free);
369 leaf = lbp->b_addr; 369 leaf = lbp->b_addr;
370 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 370 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
371 ASSERT(be32_to_cpu(ltp->bestcount) <= 371 ASSERT(be32_to_cpu(ltp->bestcount) <=
372 (uint)dp->i_d.di_size / mp->m_dirblksize); 372 (uint)dp->i_d.di_size / mp->m_dirblksize);
373 373
374 /* 374 /*
375 * Copy freespace entries from the leaf block to the new block. 375 * Copy freespace entries from the leaf block to the new block.
376 * Count active entries. 376 * Count active entries.
377 */ 377 */
378 from = xfs_dir2_leaf_bests_p(ltp); 378 from = xfs_dir2_leaf_bests_p(ltp);
379 to = xfs_dir3_free_bests_p(mp, free); 379 to = xfs_dir3_free_bests_p(mp, free);
380 for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) { 380 for (i = n = 0; i < be32_to_cpu(ltp->bestcount); i++, from++, to++) {
381 if ((off = be16_to_cpu(*from)) != NULLDATAOFF) 381 if ((off = be16_to_cpu(*from)) != NULLDATAOFF)
382 n++; 382 n++;
383 *to = cpu_to_be16(off); 383 *to = cpu_to_be16(off);
384 } 384 }
385 385
386 /* 386 /*
387 * Now initialize the freespace block header. 387 * Now initialize the freespace block header.
388 */ 388 */
389 freehdr.nused = n; 389 freehdr.nused = n;
390 freehdr.nvalid = be32_to_cpu(ltp->bestcount); 390 freehdr.nvalid = be32_to_cpu(ltp->bestcount);
391 391
392 xfs_dir3_free_hdr_to_disk(fbp->b_addr, &freehdr); 392 xfs_dir3_free_hdr_to_disk(fbp->b_addr, &freehdr);
393 xfs_dir2_free_log_bests(tp, fbp, 0, freehdr.nvalid - 1); 393 xfs_dir2_free_log_bests(tp, fbp, 0, freehdr.nvalid - 1);
394 xfs_dir2_free_log_header(tp, fbp); 394 xfs_dir2_free_log_header(tp, fbp);
395 395
396 /* 396 /*
397 * Converting the leaf to a leafnode is just a matter of changing the 397 * Converting the leaf to a leafnode is just a matter of changing the
398 * magic number and the ops. Do the change directly to the buffer as 398 * magic number and the ops. Do the change directly to the buffer as
399 * it's less work (and less code) than decoding the header to host 399 * it's less work (and less code) than decoding the header to host
400 * format and back again. 400 * format and back again.
401 */ 401 */
402 if (leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)) 402 if (leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC))
403 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC); 403 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC);
404 else 404 else
405 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); 405 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
406 lbp->b_ops = &xfs_dir3_leafn_buf_ops; 406 lbp->b_ops = &xfs_dir3_leafn_buf_ops;
407 xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF); 407 xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF);
408 xfs_dir3_leaf_log_header(tp, lbp); 408 xfs_dir3_leaf_log_header(tp, lbp);
409 xfs_dir3_leaf_check(mp, lbp); 409 xfs_dir3_leaf_check(mp, lbp);
410 return 0; 410 return 0;
411 } 411 }
412 412
413 /* 413 /*
414 * Add a leaf entry to a leaf block in a node-form directory. 414 * Add a leaf entry to a leaf block in a node-form directory.
415 * The other work necessary is done from the caller. 415 * The other work necessary is done from the caller.
416 */ 416 */
417 static int /* error */ 417 static int /* error */
418 xfs_dir2_leafn_add( 418 xfs_dir2_leafn_add(
419 struct xfs_buf *bp, /* leaf buffer */ 419 struct xfs_buf *bp, /* leaf buffer */
420 xfs_da_args_t *args, /* operation arguments */ 420 xfs_da_args_t *args, /* operation arguments */
421 int index) /* insertion pt for new entry */ 421 int index) /* insertion pt for new entry */
422 { 422 {
423 int compact; /* compacting stale leaves */ 423 int compact; /* compacting stale leaves */
424 xfs_inode_t *dp; /* incore directory inode */ 424 xfs_inode_t *dp; /* incore directory inode */
425 int highstale; /* next stale entry */ 425 int highstale; /* next stale entry */
426 xfs_dir2_leaf_t *leaf; /* leaf structure */ 426 xfs_dir2_leaf_t *leaf; /* leaf structure */
427 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 427 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
428 int lfloghigh; /* high leaf entry logging */ 428 int lfloghigh; /* high leaf entry logging */
429 int lfloglow; /* low leaf entry logging */ 429 int lfloglow; /* low leaf entry logging */
430 int lowstale; /* previous stale entry */ 430 int lowstale; /* previous stale entry */
431 xfs_mount_t *mp; /* filesystem mount point */ 431 xfs_mount_t *mp; /* filesystem mount point */
432 xfs_trans_t *tp; /* transaction pointer */ 432 xfs_trans_t *tp; /* transaction pointer */
433 struct xfs_dir3_icleaf_hdr leafhdr; 433 struct xfs_dir3_icleaf_hdr leafhdr;
434 struct xfs_dir2_leaf_entry *ents; 434 struct xfs_dir2_leaf_entry *ents;
435 435
436 trace_xfs_dir2_leafn_add(args, index); 436 trace_xfs_dir2_leafn_add(args, index);
437 437
438 dp = args->dp; 438 dp = args->dp;
439 mp = dp->i_mount; 439 mp = dp->i_mount;
440 tp = args->trans; 440 tp = args->trans;
441 leaf = bp->b_addr; 441 leaf = bp->b_addr;
442 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); 442 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
443 ents = xfs_dir3_leaf_ents_p(leaf); 443 ents = xfs_dir3_leaf_ents_p(leaf);
444 444
445 /* 445 /*
446 * Quick check just to make sure we are not going to index 446 * Quick check just to make sure we are not going to index
447 * into other peoples memory 447 * into other peoples memory
448 */ 448 */
449 if (index < 0) 449 if (index < 0)
450 return XFS_ERROR(EFSCORRUPTED); 450 return XFS_ERROR(EFSCORRUPTED);
451 451
452 /* 452 /*
453 * If there are already the maximum number of leaf entries in 453 * If there are already the maximum number of leaf entries in
454 * the block, if there are no stale entries it won't fit. 454 * the block, if there are no stale entries it won't fit.
455 * Caller will do a split. If there are stale entries we'll do 455 * Caller will do a split. If there are stale entries we'll do
456 * a compact. 456 * a compact.
457 */ 457 */
458 458
459 if (leafhdr.count == xfs_dir3_max_leaf_ents(mp, leaf)) { 459 if (leafhdr.count == xfs_dir3_max_leaf_ents(mp, leaf)) {
460 if (!leafhdr.stale) 460 if (!leafhdr.stale)
461 return XFS_ERROR(ENOSPC); 461 return XFS_ERROR(ENOSPC);
462 compact = leafhdr.stale > 1; 462 compact = leafhdr.stale > 1;
463 } else 463 } else
464 compact = 0; 464 compact = 0;
465 ASSERT(index == 0 || be32_to_cpu(ents[index - 1].hashval) <= args->hashval); 465 ASSERT(index == 0 || be32_to_cpu(ents[index - 1].hashval) <= args->hashval);
466 ASSERT(index == leafhdr.count || 466 ASSERT(index == leafhdr.count ||
467 be32_to_cpu(ents[index].hashval) >= args->hashval); 467 be32_to_cpu(ents[index].hashval) >= args->hashval);
468 468
469 if (args->op_flags & XFS_DA_OP_JUSTCHECK) 469 if (args->op_flags & XFS_DA_OP_JUSTCHECK)
470 return 0; 470 return 0;
471 471
472 /* 472 /*
473 * Compact out all but one stale leaf entry. Leaves behind 473 * Compact out all but one stale leaf entry. Leaves behind
474 * the entry closest to index. 474 * the entry closest to index.
475 */ 475 */
476 if (compact) 476 if (compact)
477 xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale, 477 xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale,
478 &highstale, &lfloglow, &lfloghigh); 478 &highstale, &lfloglow, &lfloghigh);
479 else if (leafhdr.stale) { 479 else if (leafhdr.stale) {
480 /* 480 /*
481 * Set impossible logging indices for this case. 481 * Set impossible logging indices for this case.
482 */ 482 */
483 lfloglow = leafhdr.count; 483 lfloglow = leafhdr.count;
484 lfloghigh = -1; 484 lfloghigh = -1;
485 } 485 }
486 486
487 /* 487 /*
488 * Insert the new entry, log everything. 488 * Insert the new entry, log everything.
489 */ 489 */
490 lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale, 490 lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale,
491 highstale, &lfloglow, &lfloghigh); 491 highstale, &lfloglow, &lfloghigh);
492 492
493 lep->hashval = cpu_to_be32(args->hashval); 493 lep->hashval = cpu_to_be32(args->hashval);
494 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, 494 lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp,
495 args->blkno, args->index)); 495 args->blkno, args->index));
496 496
497 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); 497 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
498 xfs_dir3_leaf_log_header(tp, bp); 498 xfs_dir3_leaf_log_header(tp, bp);
499 xfs_dir3_leaf_log_ents(tp, bp, lfloglow, lfloghigh); 499 xfs_dir3_leaf_log_ents(tp, bp, lfloglow, lfloghigh);
500 xfs_dir3_leaf_check(mp, bp); 500 xfs_dir3_leaf_check(mp, bp);
501 return 0; 501 return 0;
502 } 502 }
503 503
504 #ifdef DEBUG 504 #ifdef DEBUG
505 static void 505 static void
506 xfs_dir2_free_hdr_check( 506 xfs_dir2_free_hdr_check(
507 struct xfs_mount *mp, 507 struct xfs_mount *mp,
508 struct xfs_buf *bp, 508 struct xfs_buf *bp,
509 xfs_dir2_db_t db) 509 xfs_dir2_db_t db)
510 { 510 {
511 struct xfs_dir3_icfree_hdr hdr; 511 struct xfs_dir3_icfree_hdr hdr;
512 512
513 xfs_dir3_free_hdr_from_disk(&hdr, bp->b_addr); 513 xfs_dir3_free_hdr_from_disk(&hdr, bp->b_addr);
514 514
515 ASSERT((hdr.firstdb % xfs_dir3_free_max_bests(mp)) == 0); 515 ASSERT((hdr.firstdb % xfs_dir3_free_max_bests(mp)) == 0);
516 ASSERT(hdr.firstdb <= db); 516 ASSERT(hdr.firstdb <= db);
517 ASSERT(db < hdr.firstdb + hdr.nvalid); 517 ASSERT(db < hdr.firstdb + hdr.nvalid);
518 } 518 }
519 #else 519 #else
520 #define xfs_dir2_free_hdr_check(mp, dp, db) 520 #define xfs_dir2_free_hdr_check(mp, dp, db)
521 #endif /* DEBUG */ 521 #endif /* DEBUG */
522 522
523 /* 523 /*
524 * Return the last hash value in the leaf. 524 * Return the last hash value in the leaf.
525 * Stale entries are ok. 525 * Stale entries are ok.
526 */ 526 */
527 xfs_dahash_t /* hash value */ 527 xfs_dahash_t /* hash value */
528 xfs_dir2_leafn_lasthash( 528 xfs_dir2_leafn_lasthash(
529 struct xfs_buf *bp, /* leaf buffer */ 529 struct xfs_buf *bp, /* leaf buffer */
530 int *count) /* count of entries in leaf */ 530 int *count) /* count of entries in leaf */
531 { 531 {
532 struct xfs_dir2_leaf *leaf = bp->b_addr; 532 struct xfs_dir2_leaf *leaf = bp->b_addr;
533 struct xfs_dir2_leaf_entry *ents; 533 struct xfs_dir2_leaf_entry *ents;
534 struct xfs_dir3_icleaf_hdr leafhdr; 534 struct xfs_dir3_icleaf_hdr leafhdr;
535 535
536 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); 536 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
537 537
538 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || 538 ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
539 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); 539 leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
540 540
541 if (count) 541 if (count)
542 *count = leafhdr.count; 542 *count = leafhdr.count;
543 if (!leafhdr.count) 543 if (!leafhdr.count)
544 return 0; 544 return 0;
545 545
546 ents = xfs_dir3_leaf_ents_p(leaf); 546 ents = xfs_dir3_leaf_ents_p(leaf);
547 return be32_to_cpu(ents[leafhdr.count - 1].hashval); 547 return be32_to_cpu(ents[leafhdr.count - 1].hashval);
548 } 548 }
549 549
550 /* 550 /*
551 * Look up a leaf entry for space to add a name in a node-format leaf block. 551 * Look up a leaf entry for space to add a name in a node-format leaf block.
552 * The extrablk in state is a freespace block. 552 * The extrablk in state is a freespace block.
553 */ 553 */
554 STATIC int 554 STATIC int
555 xfs_dir2_leafn_lookup_for_addname( 555 xfs_dir2_leafn_lookup_for_addname(
556 struct xfs_buf *bp, /* leaf buffer */ 556 struct xfs_buf *bp, /* leaf buffer */
557 xfs_da_args_t *args, /* operation arguments */ 557 xfs_da_args_t *args, /* operation arguments */
558 int *indexp, /* out: leaf entry index */ 558 int *indexp, /* out: leaf entry index */
559 xfs_da_state_t *state) /* state to fill in */ 559 xfs_da_state_t *state) /* state to fill in */
560 { 560 {
561 struct xfs_buf *curbp = NULL; /* current data/free buffer */ 561 struct xfs_buf *curbp = NULL; /* current data/free buffer */
562 xfs_dir2_db_t curdb = -1; /* current data block number */ 562 xfs_dir2_db_t curdb = -1; /* current data block number */
563 xfs_dir2_db_t curfdb = -1; /* current free block number */ 563 xfs_dir2_db_t curfdb = -1; /* current free block number */
564 xfs_inode_t *dp; /* incore directory inode */ 564 xfs_inode_t *dp; /* incore directory inode */
565 int error; /* error return value */ 565 int error; /* error return value */
566 int fi; /* free entry index */ 566 int fi; /* free entry index */
567 xfs_dir2_free_t *free = NULL; /* free block structure */ 567 xfs_dir2_free_t *free = NULL; /* free block structure */
568 int index; /* leaf entry index */ 568 int index; /* leaf entry index */
569 xfs_dir2_leaf_t *leaf; /* leaf structure */ 569 xfs_dir2_leaf_t *leaf; /* leaf structure */
570 int length; /* length of new data entry */ 570 int length; /* length of new data entry */
571 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 571 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
572 xfs_mount_t *mp; /* filesystem mount point */ 572 xfs_mount_t *mp; /* filesystem mount point */
573 xfs_dir2_db_t newdb; /* new data block number */ 573 xfs_dir2_db_t newdb; /* new data block number */
574 xfs_dir2_db_t newfdb; /* new free block number */ 574 xfs_dir2_db_t newfdb; /* new free block number */
575 xfs_trans_t *tp; /* transaction pointer */ 575 xfs_trans_t *tp; /* transaction pointer */
576 struct xfs_dir2_leaf_entry *ents; 576 struct xfs_dir2_leaf_entry *ents;
577 struct xfs_dir3_icleaf_hdr leafhdr; 577 struct xfs_dir3_icleaf_hdr leafhdr;
578 578
579 dp = args->dp; 579 dp = args->dp;
580 tp = args->trans; 580 tp = args->trans;
581 mp = dp->i_mount; 581 mp = dp->i_mount;
582 leaf = bp->b_addr; 582 leaf = bp->b_addr;
583 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); 583 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
584 ents = xfs_dir3_leaf_ents_p(leaf); 584 ents = xfs_dir3_leaf_ents_p(leaf);
585 585
586 xfs_dir3_leaf_check(mp, bp); 586 xfs_dir3_leaf_check(mp, bp);
587 ASSERT(leafhdr.count > 0); 587 ASSERT(leafhdr.count > 0);
588 588
589 /* 589 /*
590 * Look up the hash value in the leaf entries. 590 * Look up the hash value in the leaf entries.
591 */ 591 */
592 index = xfs_dir2_leaf_search_hash(args, bp); 592 index = xfs_dir2_leaf_search_hash(args, bp);
593 /* 593 /*
594 * Do we have a buffer coming in? 594 * Do we have a buffer coming in?
595 */ 595 */
596 if (state->extravalid) { 596 if (state->extravalid) {
597 /* If so, it's a free block buffer, get the block number. */ 597 /* If so, it's a free block buffer, get the block number. */
598 curbp = state->extrablk.bp; 598 curbp = state->extrablk.bp;
599 curfdb = state->extrablk.blkno; 599 curfdb = state->extrablk.blkno;
600 free = curbp->b_addr; 600 free = curbp->b_addr;
601 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || 601 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
602 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); 602 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
603 } 603 }
604 length = xfs_dir2_data_entsize(args->namelen); 604 length = xfs_dir2_data_entsize(args->namelen);
605 /* 605 /*
606 * Loop over leaf entries with the right hash value. 606 * Loop over leaf entries with the right hash value.
607 */ 607 */
608 for (lep = &ents[index]; 608 for (lep = &ents[index];
609 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; 609 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
610 lep++, index++) { 610 lep++, index++) {
611 /* 611 /*
612 * Skip stale leaf entries. 612 * Skip stale leaf entries.
613 */ 613 */
614 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) 614 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
615 continue; 615 continue;
616 /* 616 /*
617 * Pull the data block number from the entry. 617 * Pull the data block number from the entry.
618 */ 618 */
619 newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 619 newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
620 /* 620 /*
621 * For addname, we're looking for a place to put the new entry. 621 * For addname, we're looking for a place to put the new entry.
622 * We want to use a data block with an entry of equal 622 * We want to use a data block with an entry of equal
623 * hash value to ours if there is one with room. 623 * hash value to ours if there is one with room.
624 * 624 *
625 * If this block isn't the data block we already have 625 * If this block isn't the data block we already have
626 * in hand, take a look at it. 626 * in hand, take a look at it.
627 */ 627 */
628 if (newdb != curdb) { 628 if (newdb != curdb) {
629 __be16 *bests; 629 __be16 *bests;
630 630
631 curdb = newdb; 631 curdb = newdb;
632 /* 632 /*
633 * Convert the data block to the free block 633 * Convert the data block to the free block
634 * holding its freespace information. 634 * holding its freespace information.
635 */ 635 */
636 newfdb = xfs_dir2_db_to_fdb(mp, newdb); 636 newfdb = xfs_dir2_db_to_fdb(mp, newdb);
637 /* 637 /*
638 * If it's not the one we have in hand, read it in. 638 * If it's not the one we have in hand, read it in.
639 */ 639 */
640 if (newfdb != curfdb) { 640 if (newfdb != curfdb) {
641 /* 641 /*
642 * If we had one before, drop it. 642 * If we had one before, drop it.
643 */ 643 */
644 if (curbp) 644 if (curbp)
645 xfs_trans_brelse(tp, curbp); 645 xfs_trans_brelse(tp, curbp);
646 646
647 error = xfs_dir2_free_read(tp, dp, 647 error = xfs_dir2_free_read(tp, dp,
648 xfs_dir2_db_to_da(mp, newfdb), 648 xfs_dir2_db_to_da(mp, newfdb),
649 &curbp); 649 &curbp);
650 if (error) 650 if (error)
651 return error; 651 return error;
652 free = curbp->b_addr; 652 free = curbp->b_addr;
653 653
654 xfs_dir2_free_hdr_check(mp, curbp, curdb); 654 xfs_dir2_free_hdr_check(mp, curbp, curdb);
655 } 655 }
656 /* 656 /*
657 * Get the index for our entry. 657 * Get the index for our entry.
658 */ 658 */
659 fi = xfs_dir2_db_to_fdindex(mp, curdb); 659 fi = xfs_dir2_db_to_fdindex(mp, curdb);
660 /* 660 /*
661 * If it has room, return it. 661 * If it has room, return it.
662 */ 662 */
663 bests = xfs_dir3_free_bests_p(mp, free); 663 bests = xfs_dir3_free_bests_p(mp, free);
664 if (unlikely(bests[fi] == cpu_to_be16(NULLDATAOFF))) { 664 if (unlikely(bests[fi] == cpu_to_be16(NULLDATAOFF))) {
665 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", 665 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
666 XFS_ERRLEVEL_LOW, mp); 666 XFS_ERRLEVEL_LOW, mp);
667 if (curfdb != newfdb) 667 if (curfdb != newfdb)
668 xfs_trans_brelse(tp, curbp); 668 xfs_trans_brelse(tp, curbp);
669 return XFS_ERROR(EFSCORRUPTED); 669 return XFS_ERROR(EFSCORRUPTED);
670 } 670 }
671 curfdb = newfdb; 671 curfdb = newfdb;
672 if (be16_to_cpu(bests[fi]) >= length) 672 if (be16_to_cpu(bests[fi]) >= length)
673 goto out; 673 goto out;
674 } 674 }
675 } 675 }
676 /* Didn't find any space */ 676 /* Didn't find any space */
677 fi = -1; 677 fi = -1;
678 out: 678 out:
679 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); 679 ASSERT(args->op_flags & XFS_DA_OP_OKNOENT);
680 if (curbp) { 680 if (curbp) {
681 /* Giving back a free block. */ 681 /* Giving back a free block. */
682 state->extravalid = 1; 682 state->extravalid = 1;
683 state->extrablk.bp = curbp; 683 state->extrablk.bp = curbp;
684 state->extrablk.index = fi; 684 state->extrablk.index = fi;
685 state->extrablk.blkno = curfdb; 685 state->extrablk.blkno = curfdb;
686 686
687 /* 687 /*
688 * Important: this magic number is not in the buffer - it's for 688 * Important: this magic number is not in the buffer - it's for
689 * buffer type information and therefore only the free/data type 689 * buffer type information and therefore only the free/data type
690 * matters here, not whether CRCs are enabled or not. 690 * matters here, not whether CRCs are enabled or not.
691 */ 691 */
692 state->extrablk.magic = XFS_DIR2_FREE_MAGIC; 692 state->extrablk.magic = XFS_DIR2_FREE_MAGIC;
693 } else { 693 } else {
694 state->extravalid = 0; 694 state->extravalid = 0;
695 } 695 }
696 /* 696 /*
697 * Return the index, that will be the insertion point. 697 * Return the index, that will be the insertion point.
698 */ 698 */
699 *indexp = index; 699 *indexp = index;
700 return XFS_ERROR(ENOENT); 700 return XFS_ERROR(ENOENT);
701 } 701 }
702 702
703 /* 703 /*
704 * Look up a leaf entry in a node-format leaf block. 704 * Look up a leaf entry in a node-format leaf block.
705 * The extrablk in state a data block. 705 * The extrablk in state a data block.
706 */ 706 */
707 STATIC int 707 STATIC int
708 xfs_dir2_leafn_lookup_for_entry( 708 xfs_dir2_leafn_lookup_for_entry(
709 struct xfs_buf *bp, /* leaf buffer */ 709 struct xfs_buf *bp, /* leaf buffer */
710 xfs_da_args_t *args, /* operation arguments */ 710 xfs_da_args_t *args, /* operation arguments */
711 int *indexp, /* out: leaf entry index */ 711 int *indexp, /* out: leaf entry index */
712 xfs_da_state_t *state) /* state to fill in */ 712 xfs_da_state_t *state) /* state to fill in */
713 { 713 {
714 struct xfs_buf *curbp = NULL; /* current data/free buffer */ 714 struct xfs_buf *curbp = NULL; /* current data/free buffer */
715 xfs_dir2_db_t curdb = -1; /* current data block number */ 715 xfs_dir2_db_t curdb = -1; /* current data block number */
716 xfs_dir2_data_entry_t *dep; /* data block entry */ 716 xfs_dir2_data_entry_t *dep; /* data block entry */
717 xfs_inode_t *dp; /* incore directory inode */ 717 xfs_inode_t *dp; /* incore directory inode */
718 int error; /* error return value */ 718 int error; /* error return value */
719 int index; /* leaf entry index */ 719 int index; /* leaf entry index */
720 xfs_dir2_leaf_t *leaf; /* leaf structure */ 720 xfs_dir2_leaf_t *leaf; /* leaf structure */
721 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 721 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
722 xfs_mount_t *mp; /* filesystem mount point */ 722 xfs_mount_t *mp; /* filesystem mount point */
723 xfs_dir2_db_t newdb; /* new data block number */ 723 xfs_dir2_db_t newdb; /* new data block number */
724 xfs_trans_t *tp; /* transaction pointer */ 724 xfs_trans_t *tp; /* transaction pointer */
725 enum xfs_dacmp cmp; /* comparison result */ 725 enum xfs_dacmp cmp; /* comparison result */
726 struct xfs_dir2_leaf_entry *ents; 726 struct xfs_dir2_leaf_entry *ents;
727 struct xfs_dir3_icleaf_hdr leafhdr; 727 struct xfs_dir3_icleaf_hdr leafhdr;
728 728
729 dp = args->dp; 729 dp = args->dp;
730 tp = args->trans; 730 tp = args->trans;
731 mp = dp->i_mount; 731 mp = dp->i_mount;
732 leaf = bp->b_addr; 732 leaf = bp->b_addr;
733 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); 733 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
734 ents = xfs_dir3_leaf_ents_p(leaf); 734 ents = xfs_dir3_leaf_ents_p(leaf);
735 735
736 xfs_dir3_leaf_check(mp, bp); 736 xfs_dir3_leaf_check(mp, bp);
737 ASSERT(leafhdr.count > 0); 737 ASSERT(leafhdr.count > 0);
738 738
739 /* 739 /*
740 * Look up the hash value in the leaf entries. 740 * Look up the hash value in the leaf entries.
741 */ 741 */
742 index = xfs_dir2_leaf_search_hash(args, bp); 742 index = xfs_dir2_leaf_search_hash(args, bp);
743 /* 743 /*
744 * Do we have a buffer coming in? 744 * Do we have a buffer coming in?
745 */ 745 */
746 if (state->extravalid) { 746 if (state->extravalid) {
747 curbp = state->extrablk.bp; 747 curbp = state->extrablk.bp;
748 curdb = state->extrablk.blkno; 748 curdb = state->extrablk.blkno;
749 } 749 }
750 /* 750 /*
751 * Loop over leaf entries with the right hash value. 751 * Loop over leaf entries with the right hash value.
752 */ 752 */
753 for (lep = &ents[index]; 753 for (lep = &ents[index];
754 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; 754 index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
755 lep++, index++) { 755 lep++, index++) {
756 /* 756 /*
757 * Skip stale leaf entries. 757 * Skip stale leaf entries.
758 */ 758 */
759 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) 759 if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
760 continue; 760 continue;
761 /* 761 /*
762 * Pull the data block number from the entry. 762 * Pull the data block number from the entry.
763 */ 763 */
764 newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 764 newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
765 /* 765 /*
766 * Not adding a new entry, so we really want to find 766 * Not adding a new entry, so we really want to find
767 * the name given to us. 767 * the name given to us.
768 * 768 *
769 * If it's a different data block, go get it. 769 * If it's a different data block, go get it.
770 */ 770 */
771 if (newdb != curdb) { 771 if (newdb != curdb) {
772 /* 772 /*
773 * If we had a block before that we aren't saving 773 * If we had a block before that we aren't saving
774 * for a CI name, drop it 774 * for a CI name, drop it
775 */ 775 */
776 if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || 776 if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT ||
777 curdb != state->extrablk.blkno)) 777 curdb != state->extrablk.blkno))
778 xfs_trans_brelse(tp, curbp); 778 xfs_trans_brelse(tp, curbp);
779 /* 779 /*
780 * If needing the block that is saved with a CI match, 780 * If needing the block that is saved with a CI match,
781 * use it otherwise read in the new data block. 781 * use it otherwise read in the new data block.
782 */ 782 */
783 if (args->cmpresult != XFS_CMP_DIFFERENT && 783 if (args->cmpresult != XFS_CMP_DIFFERENT &&
784 newdb == state->extrablk.blkno) { 784 newdb == state->extrablk.blkno) {
785 ASSERT(state->extravalid); 785 ASSERT(state->extravalid);
786 curbp = state->extrablk.bp; 786 curbp = state->extrablk.bp;
787 } else { 787 } else {
788 error = xfs_dir3_data_read(tp, dp, 788 error = xfs_dir3_data_read(tp, dp,
789 xfs_dir2_db_to_da(mp, newdb), 789 xfs_dir2_db_to_da(mp, newdb),
790 -1, &curbp); 790 -1, &curbp);
791 if (error) 791 if (error)
792 return error; 792 return error;
793 } 793 }
794 xfs_dir3_data_check(dp, curbp); 794 xfs_dir3_data_check(dp, curbp);
795 curdb = newdb; 795 curdb = newdb;
796 } 796 }
797 /* 797 /*
798 * Point to the data entry. 798 * Point to the data entry.
799 */ 799 */
800 dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr + 800 dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr +
801 xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); 801 xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
802 /* 802 /*
803 * Compare the entry and if it's an exact match, return 803 * Compare the entry and if it's an exact match, return
804 * EEXIST immediately. If it's the first case-insensitive 804 * EEXIST immediately. If it's the first case-insensitive
805 * match, store the block & inode number and continue looking. 805 * match, store the block & inode number and continue looking.
806 */ 806 */
807 cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); 807 cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen);
808 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { 808 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
809 /* If there is a CI match block, drop it */ 809 /* If there is a CI match block, drop it */
810 if (args->cmpresult != XFS_CMP_DIFFERENT && 810 if (args->cmpresult != XFS_CMP_DIFFERENT &&
811 curdb != state->extrablk.blkno) 811 curdb != state->extrablk.blkno)
812 xfs_trans_brelse(tp, state->extrablk.bp); 812 xfs_trans_brelse(tp, state->extrablk.bp);
813 args->cmpresult = cmp; 813 args->cmpresult = cmp;
814 args->inumber = be64_to_cpu(dep->inumber); 814 args->inumber = be64_to_cpu(dep->inumber);
815 *indexp = index; 815 *indexp = index;
816 state->extravalid = 1; 816 state->extravalid = 1;
817 state->extrablk.bp = curbp; 817 state->extrablk.bp = curbp;
818 state->extrablk.blkno = curdb; 818 state->extrablk.blkno = curdb;
819 state->extrablk.index = (int)((char *)dep - 819 state->extrablk.index = (int)((char *)dep -
820 (char *)curbp->b_addr); 820 (char *)curbp->b_addr);
821 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 821 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
822 curbp->b_ops = &xfs_dir3_data_buf_ops; 822 curbp->b_ops = &xfs_dir3_data_buf_ops;
823 xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); 823 xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF);
824 if (cmp == XFS_CMP_EXACT) 824 if (cmp == XFS_CMP_EXACT)
825 return XFS_ERROR(EEXIST); 825 return XFS_ERROR(EEXIST);
826 } 826 }
827 } 827 }
828 ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT)); 828 ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT));
829 if (curbp) { 829 if (curbp) {
830 if (args->cmpresult == XFS_CMP_DIFFERENT) { 830 if (args->cmpresult == XFS_CMP_DIFFERENT) {
831 /* Giving back last used data block. */ 831 /* Giving back last used data block. */
832 state->extravalid = 1; 832 state->extravalid = 1;
833 state->extrablk.bp = curbp; 833 state->extrablk.bp = curbp;
834 state->extrablk.index = -1; 834 state->extrablk.index = -1;
835 state->extrablk.blkno = curdb; 835 state->extrablk.blkno = curdb;
836 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 836 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
837 curbp->b_ops = &xfs_dir3_data_buf_ops; 837 curbp->b_ops = &xfs_dir3_data_buf_ops;
838 xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); 838 xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF);
839 } else { 839 } else {
840 /* If the curbp is not the CI match block, drop it */ 840 /* If the curbp is not the CI match block, drop it */
841 if (state->extrablk.bp != curbp) 841 if (state->extrablk.bp != curbp)
842 xfs_trans_brelse(tp, curbp); 842 xfs_trans_brelse(tp, curbp);
843 } 843 }
844 } else { 844 } else {
845 state->extravalid = 0; 845 state->extravalid = 0;
846 } 846 }
847 *indexp = index; 847 *indexp = index;
848 return XFS_ERROR(ENOENT); 848 return XFS_ERROR(ENOENT);
849 } 849 }
850 850
851 /* 851 /*
852 * Look up a leaf entry in a node-format leaf block. 852 * Look up a leaf entry in a node-format leaf block.
853 * If this is an addname then the extrablk in state is a freespace block, 853 * If this is an addname then the extrablk in state is a freespace block,
854 * otherwise it's a data block. 854 * otherwise it's a data block.
855 */ 855 */
856 int 856 int
857 xfs_dir2_leafn_lookup_int( 857 xfs_dir2_leafn_lookup_int(
858 struct xfs_buf *bp, /* leaf buffer */ 858 struct xfs_buf *bp, /* leaf buffer */
859 xfs_da_args_t *args, /* operation arguments */ 859 xfs_da_args_t *args, /* operation arguments */
860 int *indexp, /* out: leaf entry index */ 860 int *indexp, /* out: leaf entry index */
861 xfs_da_state_t *state) /* state to fill in */ 861 xfs_da_state_t *state) /* state to fill in */
862 { 862 {
863 if (args->op_flags & XFS_DA_OP_ADDNAME) 863 if (args->op_flags & XFS_DA_OP_ADDNAME)
864 return xfs_dir2_leafn_lookup_for_addname(bp, args, indexp, 864 return xfs_dir2_leafn_lookup_for_addname(bp, args, indexp,
865 state); 865 state);
866 return xfs_dir2_leafn_lookup_for_entry(bp, args, indexp, state); 866 return xfs_dir2_leafn_lookup_for_entry(bp, args, indexp, state);
867 } 867 }
868 868
869 /* 869 /*
870 * Move count leaf entries from source to destination leaf. 870 * Move count leaf entries from source to destination leaf.
871 * Log entries and headers. Stale entries are preserved. 871 * Log entries and headers. Stale entries are preserved.
872 */ 872 */
873 static void 873 static void
874 xfs_dir3_leafn_moveents( 874 xfs_dir3_leafn_moveents(
875 xfs_da_args_t *args, /* operation arguments */ 875 xfs_da_args_t *args, /* operation arguments */
876 struct xfs_buf *bp_s, /* source */ 876 struct xfs_buf *bp_s, /* source */
877 struct xfs_dir3_icleaf_hdr *shdr, 877 struct xfs_dir3_icleaf_hdr *shdr,
878 struct xfs_dir2_leaf_entry *sents, 878 struct xfs_dir2_leaf_entry *sents,
879 int start_s,/* source leaf index */ 879 int start_s,/* source leaf index */
880 struct xfs_buf *bp_d, /* destination */ 880 struct xfs_buf *bp_d, /* destination */
881 struct xfs_dir3_icleaf_hdr *dhdr, 881 struct xfs_dir3_icleaf_hdr *dhdr,
882 struct xfs_dir2_leaf_entry *dents, 882 struct xfs_dir2_leaf_entry *dents,
883 int start_d,/* destination leaf index */ 883 int start_d,/* destination leaf index */
884 int count) /* count of leaves to copy */ 884 int count) /* count of leaves to copy */
885 { 885 {
886 struct xfs_trans *tp = args->trans; 886 struct xfs_trans *tp = args->trans;
887 int stale; /* count stale leaves copied */ 887 int stale; /* count stale leaves copied */
888 888
889 trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count); 889 trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count);
890 890
891 /* 891 /*
892 * Silently return if nothing to do. 892 * Silently return if nothing to do.
893 */ 893 */
894 if (count == 0) 894 if (count == 0)
895 return; 895 return;
896 896
897 /* 897 /*
898 * If the destination index is not the end of the current 898 * If the destination index is not the end of the current
899 * destination leaf entries, open up a hole in the destination 899 * destination leaf entries, open up a hole in the destination
900 * to hold the new entries. 900 * to hold the new entries.
901 */ 901 */
902 if (start_d < dhdr->count) { 902 if (start_d < dhdr->count) {
903 memmove(&dents[start_d + count], &dents[start_d], 903 memmove(&dents[start_d + count], &dents[start_d],
904 (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t)); 904 (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t));
905 xfs_dir3_leaf_log_ents(tp, bp_d, start_d + count, 905 xfs_dir3_leaf_log_ents(tp, bp_d, start_d + count,
906 count + dhdr->count - 1); 906 count + dhdr->count - 1);
907 } 907 }
908 /* 908 /*
909 * If the source has stale leaves, count the ones in the copy range 909 * If the source has stale leaves, count the ones in the copy range
910 * so we can update the header correctly. 910 * so we can update the header correctly.
911 */ 911 */
912 if (shdr->stale) { 912 if (shdr->stale) {
913 int i; /* temp leaf index */ 913 int i; /* temp leaf index */
914 914
915 for (i = start_s, stale = 0; i < start_s + count; i++) { 915 for (i = start_s, stale = 0; i < start_s + count; i++) {
916 if (sents[i].address == 916 if (sents[i].address ==
917 cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) 917 cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
918 stale++; 918 stale++;
919 } 919 }
920 } else 920 } else
921 stale = 0; 921 stale = 0;
922 /* 922 /*
923 * Copy the leaf entries from source to destination. 923 * Copy the leaf entries from source to destination.
924 */ 924 */
925 memcpy(&dents[start_d], &sents[start_s], 925 memcpy(&dents[start_d], &sents[start_s],
926 count * sizeof(xfs_dir2_leaf_entry_t)); 926 count * sizeof(xfs_dir2_leaf_entry_t));
927 xfs_dir3_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1); 927 xfs_dir3_leaf_log_ents(tp, bp_d, start_d, start_d + count - 1);
928 928
929 /* 929 /*
930 * If there are source entries after the ones we copied, 930 * If there are source entries after the ones we copied,
931 * delete the ones we copied by sliding the next ones down. 931 * delete the ones we copied by sliding the next ones down.
932 */ 932 */
933 if (start_s + count < shdr->count) { 933 if (start_s + count < shdr->count) {
934 memmove(&sents[start_s], &sents[start_s + count], 934 memmove(&sents[start_s], &sents[start_s + count],
935 count * sizeof(xfs_dir2_leaf_entry_t)); 935 count * sizeof(xfs_dir2_leaf_entry_t));
936 xfs_dir3_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1); 936 xfs_dir3_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1);
937 } 937 }
938 938
939 /* 939 /*
940 * Update the headers and log them. 940 * Update the headers and log them.
941 */ 941 */
942 shdr->count -= count; 942 shdr->count -= count;
943 shdr->stale -= stale; 943 shdr->stale -= stale;
944 dhdr->count += count; 944 dhdr->count += count;
945 dhdr->stale += stale; 945 dhdr->stale += stale;
946 } 946 }
947 947
948 /* 948 /*
949 * Determine the sort order of two leaf blocks. 949 * Determine the sort order of two leaf blocks.
950 * Returns 1 if both are valid and leaf2 should be before leaf1, else 0. 950 * Returns 1 if both are valid and leaf2 should be before leaf1, else 0.
951 */ 951 */
952 int /* sort order */ 952 int /* sort order */
953 xfs_dir2_leafn_order( 953 xfs_dir2_leafn_order(
954 struct xfs_buf *leaf1_bp, /* leaf1 buffer */ 954 struct xfs_buf *leaf1_bp, /* leaf1 buffer */
955 struct xfs_buf *leaf2_bp) /* leaf2 buffer */ 955 struct xfs_buf *leaf2_bp) /* leaf2 buffer */
956 { 956 {
957 struct xfs_dir2_leaf *leaf1 = leaf1_bp->b_addr; 957 struct xfs_dir2_leaf *leaf1 = leaf1_bp->b_addr;
958 struct xfs_dir2_leaf *leaf2 = leaf2_bp->b_addr; 958 struct xfs_dir2_leaf *leaf2 = leaf2_bp->b_addr;
959 struct xfs_dir2_leaf_entry *ents1; 959 struct xfs_dir2_leaf_entry *ents1;
960 struct xfs_dir2_leaf_entry *ents2; 960 struct xfs_dir2_leaf_entry *ents2;
961 struct xfs_dir3_icleaf_hdr hdr1; 961 struct xfs_dir3_icleaf_hdr hdr1;
962 struct xfs_dir3_icleaf_hdr hdr2; 962 struct xfs_dir3_icleaf_hdr hdr2;
963 963
964 xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1); 964 xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1);
965 xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2); 965 xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2);
966 ents1 = xfs_dir3_leaf_ents_p(leaf1); 966 ents1 = xfs_dir3_leaf_ents_p(leaf1);
967 ents2 = xfs_dir3_leaf_ents_p(leaf2); 967 ents2 = xfs_dir3_leaf_ents_p(leaf2);
968 968
969 if (hdr1.count > 0 && hdr2.count > 0 && 969 if (hdr1.count > 0 && hdr2.count > 0 &&
970 (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) || 970 (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) ||
971 be32_to_cpu(ents2[hdr2.count - 1].hashval) < 971 be32_to_cpu(ents2[hdr2.count - 1].hashval) <
972 be32_to_cpu(ents1[hdr1.count - 1].hashval))) 972 be32_to_cpu(ents1[hdr1.count - 1].hashval)))
973 return 1; 973 return 1;
974 return 0; 974 return 0;
975 } 975 }
976 976
977 /* 977 /*
978 * Rebalance leaf entries between two leaf blocks. 978 * Rebalance leaf entries between two leaf blocks.
979 * This is actually only called when the second block is new, 979 * This is actually only called when the second block is new,
980 * though the code deals with the general case. 980 * though the code deals with the general case.
981 * A new entry will be inserted in one of the blocks, and that 981 * A new entry will be inserted in one of the blocks, and that
982 * entry is taken into account when balancing. 982 * entry is taken into account when balancing.
983 */ 983 */
984 static void 984 static void
985 xfs_dir2_leafn_rebalance( 985 xfs_dir2_leafn_rebalance(
986 xfs_da_state_t *state, /* btree cursor */ 986 xfs_da_state_t *state, /* btree cursor */
987 xfs_da_state_blk_t *blk1, /* first btree block */ 987 xfs_da_state_blk_t *blk1, /* first btree block */
988 xfs_da_state_blk_t *blk2) /* second btree block */ 988 xfs_da_state_blk_t *blk2) /* second btree block */
989 { 989 {
990 xfs_da_args_t *args; /* operation arguments */ 990 xfs_da_args_t *args; /* operation arguments */
991 int count; /* count (& direction) leaves */ 991 int count; /* count (& direction) leaves */
992 int isleft; /* new goes in left leaf */ 992 int isleft; /* new goes in left leaf */
993 xfs_dir2_leaf_t *leaf1; /* first leaf structure */ 993 xfs_dir2_leaf_t *leaf1; /* first leaf structure */
994 xfs_dir2_leaf_t *leaf2; /* second leaf structure */ 994 xfs_dir2_leaf_t *leaf2; /* second leaf structure */
995 int mid; /* midpoint leaf index */ 995 int mid; /* midpoint leaf index */
996 #ifdef DEBUG 996 #if defined(DEBUG) || defined(XFS_WARN)
997 int oldstale; /* old count of stale leaves */ 997 int oldstale; /* old count of stale leaves */
998 #endif 998 #endif
999 int oldsum; /* old total leaf count */ 999 int oldsum; /* old total leaf count */
1000 int swap; /* swapped leaf blocks */ 1000 int swap; /* swapped leaf blocks */
1001 struct xfs_dir2_leaf_entry *ents1; 1001 struct xfs_dir2_leaf_entry *ents1;
1002 struct xfs_dir2_leaf_entry *ents2; 1002 struct xfs_dir2_leaf_entry *ents2;
1003 struct xfs_dir3_icleaf_hdr hdr1; 1003 struct xfs_dir3_icleaf_hdr hdr1;
1004 struct xfs_dir3_icleaf_hdr hdr2; 1004 struct xfs_dir3_icleaf_hdr hdr2;
1005 1005
1006 args = state->args; 1006 args = state->args;
1007 /* 1007 /*
1008 * If the block order is wrong, swap the arguments. 1008 * If the block order is wrong, swap the arguments.
1009 */ 1009 */
1010 if ((swap = xfs_dir2_leafn_order(blk1->bp, blk2->bp))) { 1010 if ((swap = xfs_dir2_leafn_order(blk1->bp, blk2->bp))) {
1011 xfs_da_state_blk_t *tmp; /* temp for block swap */ 1011 xfs_da_state_blk_t *tmp; /* temp for block swap */
1012 1012
1013 tmp = blk1; 1013 tmp = blk1;
1014 blk1 = blk2; 1014 blk1 = blk2;
1015 blk2 = tmp; 1015 blk2 = tmp;
1016 } 1016 }
1017 leaf1 = blk1->bp->b_addr; 1017 leaf1 = blk1->bp->b_addr;
1018 leaf2 = blk2->bp->b_addr; 1018 leaf2 = blk2->bp->b_addr;
1019 xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1); 1019 xfs_dir3_leaf_hdr_from_disk(&hdr1, leaf1);
1020 xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2); 1020 xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf2);
1021 ents1 = xfs_dir3_leaf_ents_p(leaf1); 1021 ents1 = xfs_dir3_leaf_ents_p(leaf1);
1022 ents2 = xfs_dir3_leaf_ents_p(leaf2); 1022 ents2 = xfs_dir3_leaf_ents_p(leaf2);
1023 1023
1024 oldsum = hdr1.count + hdr2.count; 1024 oldsum = hdr1.count + hdr2.count;
1025 #ifdef DEBUG 1025 #if defined(DEBUG) || defined(XFS_WARN)
1026 oldstale = hdr1.stale + hdr2.stale; 1026 oldstale = hdr1.stale + hdr2.stale;
1027 #endif 1027 #endif
1028 mid = oldsum >> 1; 1028 mid = oldsum >> 1;
1029 1029
1030 /* 1030 /*
1031 * If the old leaf count was odd then the new one will be even, 1031 * If the old leaf count was odd then the new one will be even,
1032 * so we need to divide the new count evenly. 1032 * so we need to divide the new count evenly.
1033 */ 1033 */
1034 if (oldsum & 1) { 1034 if (oldsum & 1) {
1035 xfs_dahash_t midhash; /* middle entry hash value */ 1035 xfs_dahash_t midhash; /* middle entry hash value */
1036 1036
1037 if (mid >= hdr1.count) 1037 if (mid >= hdr1.count)
1038 midhash = be32_to_cpu(ents2[mid - hdr1.count].hashval); 1038 midhash = be32_to_cpu(ents2[mid - hdr1.count].hashval);
1039 else 1039 else
1040 midhash = be32_to_cpu(ents1[mid].hashval); 1040 midhash = be32_to_cpu(ents1[mid].hashval);
1041 isleft = args->hashval <= midhash; 1041 isleft = args->hashval <= midhash;
1042 } 1042 }
1043 /* 1043 /*
1044 * If the old count is even then the new count is odd, so there's 1044 * If the old count is even then the new count is odd, so there's
1045 * no preferred side for the new entry. 1045 * no preferred side for the new entry.
1046 * Pick the left one. 1046 * Pick the left one.
1047 */ 1047 */
1048 else 1048 else
1049 isleft = 1; 1049 isleft = 1;
1050 /* 1050 /*
1051 * Calculate moved entry count. Positive means left-to-right, 1051 * Calculate moved entry count. Positive means left-to-right,
1052 * negative means right-to-left. Then move the entries. 1052 * negative means right-to-left. Then move the entries.
1053 */ 1053 */
1054 count = hdr1.count - mid + (isleft == 0); 1054 count = hdr1.count - mid + (isleft == 0);
1055 if (count > 0) 1055 if (count > 0)
1056 xfs_dir3_leafn_moveents(args, blk1->bp, &hdr1, ents1, 1056 xfs_dir3_leafn_moveents(args, blk1->bp, &hdr1, ents1,
1057 hdr1.count - count, blk2->bp, 1057 hdr1.count - count, blk2->bp,
1058 &hdr2, ents2, 0, count); 1058 &hdr2, ents2, 0, count);
1059 else if (count < 0) 1059 else if (count < 0)
1060 xfs_dir3_leafn_moveents(args, blk2->bp, &hdr2, ents2, 0, 1060 xfs_dir3_leafn_moveents(args, blk2->bp, &hdr2, ents2, 0,
1061 blk1->bp, &hdr1, ents1, 1061 blk1->bp, &hdr1, ents1,
1062 hdr1.count, count); 1062 hdr1.count, count);
1063 1063
1064 ASSERT(hdr1.count + hdr2.count == oldsum); 1064 ASSERT(hdr1.count + hdr2.count == oldsum);
1065 ASSERT(hdr1.stale + hdr2.stale == oldstale); 1065 ASSERT(hdr1.stale + hdr2.stale == oldstale);
1066 1066
1067 /* log the changes made when moving the entries */ 1067 /* log the changes made when moving the entries */
1068 xfs_dir3_leaf_hdr_to_disk(leaf1, &hdr1); 1068 xfs_dir3_leaf_hdr_to_disk(leaf1, &hdr1);
1069 xfs_dir3_leaf_hdr_to_disk(leaf2, &hdr2); 1069 xfs_dir3_leaf_hdr_to_disk(leaf2, &hdr2);
1070 xfs_dir3_leaf_log_header(args->trans, blk1->bp); 1070 xfs_dir3_leaf_log_header(args->trans, blk1->bp);
1071 xfs_dir3_leaf_log_header(args->trans, blk2->bp); 1071 xfs_dir3_leaf_log_header(args->trans, blk2->bp);
1072 1072
1073 xfs_dir3_leaf_check(args->dp->i_mount, blk1->bp); 1073 xfs_dir3_leaf_check(args->dp->i_mount, blk1->bp);
1074 xfs_dir3_leaf_check(args->dp->i_mount, blk2->bp); 1074 xfs_dir3_leaf_check(args->dp->i_mount, blk2->bp);
1075 1075
1076 /* 1076 /*
1077 * Mark whether we're inserting into the old or new leaf. 1077 * Mark whether we're inserting into the old or new leaf.
1078 */ 1078 */
1079 if (hdr1.count < hdr2.count) 1079 if (hdr1.count < hdr2.count)
1080 state->inleaf = swap; 1080 state->inleaf = swap;
1081 else if (hdr1.count > hdr2.count) 1081 else if (hdr1.count > hdr2.count)
1082 state->inleaf = !swap; 1082 state->inleaf = !swap;
1083 else 1083 else
1084 state->inleaf = swap ^ (blk1->index <= hdr1.count); 1084 state->inleaf = swap ^ (blk1->index <= hdr1.count);
1085 /* 1085 /*
1086 * Adjust the expected index for insertion. 1086 * Adjust the expected index for insertion.
1087 */ 1087 */
1088 if (!state->inleaf) 1088 if (!state->inleaf)
1089 blk2->index = blk1->index - hdr1.count; 1089 blk2->index = blk1->index - hdr1.count;
1090 1090
1091 /* 1091 /*
1092 * Finally sanity check just to make sure we are not returning a 1092 * Finally sanity check just to make sure we are not returning a
1093 * negative index 1093 * negative index
1094 */ 1094 */
1095 if(blk2->index < 0) { 1095 if(blk2->index < 0) {
1096 state->inleaf = 1; 1096 state->inleaf = 1;
1097 blk2->index = 0; 1097 blk2->index = 0;
1098 xfs_alert(args->dp->i_mount, 1098 xfs_alert(args->dp->i_mount,
1099 "%s: picked the wrong leaf? reverting original leaf: blk1->index %d\n", 1099 "%s: picked the wrong leaf? reverting original leaf: blk1->index %d\n",
1100 __func__, blk1->index); 1100 __func__, blk1->index);
1101 } 1101 }
1102 } 1102 }
1103 1103
1104 static int 1104 static int
1105 xfs_dir3_data_block_free( 1105 xfs_dir3_data_block_free(
1106 xfs_da_args_t *args, 1106 xfs_da_args_t *args,
1107 struct xfs_dir2_data_hdr *hdr, 1107 struct xfs_dir2_data_hdr *hdr,
1108 struct xfs_dir2_free *free, 1108 struct xfs_dir2_free *free,
1109 xfs_dir2_db_t fdb, 1109 xfs_dir2_db_t fdb,
1110 int findex, 1110 int findex,
1111 struct xfs_buf *fbp, 1111 struct xfs_buf *fbp,
1112 int longest) 1112 int longest)
1113 { 1113 {
1114 struct xfs_trans *tp = args->trans; 1114 struct xfs_trans *tp = args->trans;
1115 int logfree = 0; 1115 int logfree = 0;
1116 __be16 *bests; 1116 __be16 *bests;
1117 struct xfs_dir3_icfree_hdr freehdr; 1117 struct xfs_dir3_icfree_hdr freehdr;
1118 1118
1119 xfs_dir3_free_hdr_from_disk(&freehdr, free); 1119 xfs_dir3_free_hdr_from_disk(&freehdr, free);
1120 1120
1121 bests = xfs_dir3_free_bests_p(tp->t_mountp, free); 1121 bests = xfs_dir3_free_bests_p(tp->t_mountp, free);
1122 if (hdr) { 1122 if (hdr) {
1123 /* 1123 /*
1124 * Data block is not empty, just set the free entry to the new 1124 * Data block is not empty, just set the free entry to the new
1125 * value. 1125 * value.
1126 */ 1126 */
1127 bests[findex] = cpu_to_be16(longest); 1127 bests[findex] = cpu_to_be16(longest);
1128 xfs_dir2_free_log_bests(tp, fbp, findex, findex); 1128 xfs_dir2_free_log_bests(tp, fbp, findex, findex);
1129 return 0; 1129 return 0;
1130 } 1130 }
1131 1131
1132 /* One less used entry in the free table. */ 1132 /* One less used entry in the free table. */
1133 freehdr.nused--; 1133 freehdr.nused--;
1134 1134
1135 /* 1135 /*
1136 * If this was the last entry in the table, we can trim the table size 1136 * If this was the last entry in the table, we can trim the table size
1137 * back. There might be other entries at the end referring to 1137 * back. There might be other entries at the end referring to
1138 * non-existent data blocks, get those too. 1138 * non-existent data blocks, get those too.
1139 */ 1139 */
1140 if (findex == freehdr.nvalid - 1) { 1140 if (findex == freehdr.nvalid - 1) {
1141 int i; /* free entry index */ 1141 int i; /* free entry index */
1142 1142
1143 for (i = findex - 1; i >= 0; i--) { 1143 for (i = findex - 1; i >= 0; i--) {
1144 if (bests[i] != cpu_to_be16(NULLDATAOFF)) 1144 if (bests[i] != cpu_to_be16(NULLDATAOFF))
1145 break; 1145 break;
1146 } 1146 }
1147 freehdr.nvalid = i + 1; 1147 freehdr.nvalid = i + 1;
1148 logfree = 0; 1148 logfree = 0;
1149 } else { 1149 } else {
1150 /* Not the last entry, just punch it out. */ 1150 /* Not the last entry, just punch it out. */
1151 bests[findex] = cpu_to_be16(NULLDATAOFF); 1151 bests[findex] = cpu_to_be16(NULLDATAOFF);
1152 logfree = 1; 1152 logfree = 1;
1153 } 1153 }
1154 1154
1155 xfs_dir3_free_hdr_to_disk(free, &freehdr); 1155 xfs_dir3_free_hdr_to_disk(free, &freehdr);
1156 xfs_dir2_free_log_header(tp, fbp); 1156 xfs_dir2_free_log_header(tp, fbp);
1157 1157
1158 /* 1158 /*
1159 * If there are no useful entries left in the block, get rid of the 1159 * If there are no useful entries left in the block, get rid of the
1160 * block if we can. 1160 * block if we can.
1161 */ 1161 */
1162 if (!freehdr.nused) { 1162 if (!freehdr.nused) {
1163 int error; 1163 int error;
1164 1164
1165 error = xfs_dir2_shrink_inode(args, fdb, fbp); 1165 error = xfs_dir2_shrink_inode(args, fdb, fbp);
1166 if (error == 0) { 1166 if (error == 0) {
1167 fbp = NULL; 1167 fbp = NULL;
1168 logfree = 0; 1168 logfree = 0;
1169 } else if (error != ENOSPC || args->total != 0) 1169 } else if (error != ENOSPC || args->total != 0)
1170 return error; 1170 return error;
1171 /* 1171 /*
1172 * It's possible to get ENOSPC if there is no 1172 * It's possible to get ENOSPC if there is no
1173 * space reservation. In this case some one 1173 * space reservation. In this case some one
1174 * else will eventually get rid of this block. 1174 * else will eventually get rid of this block.
1175 */ 1175 */
1176 } 1176 }
1177 1177
1178 /* Log the free entry that changed, unless we got rid of it. */ 1178 /* Log the free entry that changed, unless we got rid of it. */
1179 if (logfree) 1179 if (logfree)
1180 xfs_dir2_free_log_bests(tp, fbp, findex, findex); 1180 xfs_dir2_free_log_bests(tp, fbp, findex, findex);
1181 return 0; 1181 return 0;
1182 } 1182 }
1183 1183
1184 /* 1184 /*
1185 * Remove an entry from a node directory. 1185 * Remove an entry from a node directory.
1186 * This removes the leaf entry and the data entry, 1186 * This removes the leaf entry and the data entry,
1187 * and updates the free block if necessary. 1187 * and updates the free block if necessary.
1188 */ 1188 */
1189 static int /* error */ 1189 static int /* error */
1190 xfs_dir2_leafn_remove( 1190 xfs_dir2_leafn_remove(
1191 xfs_da_args_t *args, /* operation arguments */ 1191 xfs_da_args_t *args, /* operation arguments */
1192 struct xfs_buf *bp, /* leaf buffer */ 1192 struct xfs_buf *bp, /* leaf buffer */
1193 int index, /* leaf entry index */ 1193 int index, /* leaf entry index */
1194 xfs_da_state_blk_t *dblk, /* data block */ 1194 xfs_da_state_blk_t *dblk, /* data block */
1195 int *rval) /* resulting block needs join */ 1195 int *rval) /* resulting block needs join */
1196 { 1196 {
1197 xfs_dir2_data_hdr_t *hdr; /* data block header */ 1197 xfs_dir2_data_hdr_t *hdr; /* data block header */
1198 xfs_dir2_db_t db; /* data block number */ 1198 xfs_dir2_db_t db; /* data block number */
1199 struct xfs_buf *dbp; /* data block buffer */ 1199 struct xfs_buf *dbp; /* data block buffer */
1200 xfs_dir2_data_entry_t *dep; /* data block entry */ 1200 xfs_dir2_data_entry_t *dep; /* data block entry */
1201 xfs_inode_t *dp; /* incore directory inode */ 1201 xfs_inode_t *dp; /* incore directory inode */
1202 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1202 xfs_dir2_leaf_t *leaf; /* leaf structure */
1203 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 1203 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
1204 int longest; /* longest data free entry */ 1204 int longest; /* longest data free entry */
1205 int off; /* data block entry offset */ 1205 int off; /* data block entry offset */
1206 xfs_mount_t *mp; /* filesystem mount point */ 1206 xfs_mount_t *mp; /* filesystem mount point */
1207 int needlog; /* need to log data header */ 1207 int needlog; /* need to log data header */
1208 int needscan; /* need to rescan data frees */ 1208 int needscan; /* need to rescan data frees */
1209 xfs_trans_t *tp; /* transaction pointer */ 1209 xfs_trans_t *tp; /* transaction pointer */
1210 struct xfs_dir2_data_free *bf; /* bestfree table */ 1210 struct xfs_dir2_data_free *bf; /* bestfree table */
1211 struct xfs_dir3_icleaf_hdr leafhdr; 1211 struct xfs_dir3_icleaf_hdr leafhdr;
1212 struct xfs_dir2_leaf_entry *ents; 1212 struct xfs_dir2_leaf_entry *ents;
1213 1213
1214 trace_xfs_dir2_leafn_remove(args, index); 1214 trace_xfs_dir2_leafn_remove(args, index);
1215 1215
1216 dp = args->dp; 1216 dp = args->dp;
1217 tp = args->trans; 1217 tp = args->trans;
1218 mp = dp->i_mount; 1218 mp = dp->i_mount;
1219 leaf = bp->b_addr; 1219 leaf = bp->b_addr;
1220 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); 1220 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
1221 ents = xfs_dir3_leaf_ents_p(leaf); 1221 ents = xfs_dir3_leaf_ents_p(leaf);
1222 1222
1223 /* 1223 /*
1224 * Point to the entry we're removing. 1224 * Point to the entry we're removing.
1225 */ 1225 */
1226 lep = &ents[index]; 1226 lep = &ents[index];
1227 1227
1228 /* 1228 /*
1229 * Extract the data block and offset from the entry. 1229 * Extract the data block and offset from the entry.
1230 */ 1230 */
1231 db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); 1231 db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address));
1232 ASSERT(dblk->blkno == db); 1232 ASSERT(dblk->blkno == db);
1233 off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)); 1233 off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address));
1234 ASSERT(dblk->index == off); 1234 ASSERT(dblk->index == off);
1235 1235
1236 /* 1236 /*
1237 * Kill the leaf entry by marking it stale. 1237 * Kill the leaf entry by marking it stale.
1238 * Log the leaf block changes. 1238 * Log the leaf block changes.
1239 */ 1239 */
1240 leafhdr.stale++; 1240 leafhdr.stale++;
1241 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); 1241 xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
1242 xfs_dir3_leaf_log_header(tp, bp); 1242 xfs_dir3_leaf_log_header(tp, bp);
1243 1243
1244 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); 1244 lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
1245 xfs_dir3_leaf_log_ents(tp, bp, index, index); 1245 xfs_dir3_leaf_log_ents(tp, bp, index, index);
1246 1246
1247 /* 1247 /*
1248 * Make the data entry free. Keep track of the longest freespace 1248 * Make the data entry free. Keep track of the longest freespace
1249 * in the data block in case it changes. 1249 * in the data block in case it changes.
1250 */ 1250 */
1251 dbp = dblk->bp; 1251 dbp = dblk->bp;
1252 hdr = dbp->b_addr; 1252 hdr = dbp->b_addr;
1253 dep = (xfs_dir2_data_entry_t *)((char *)hdr + off); 1253 dep = (xfs_dir2_data_entry_t *)((char *)hdr + off);
1254 bf = xfs_dir3_data_bestfree_p(hdr); 1254 bf = xfs_dir3_data_bestfree_p(hdr);
1255 longest = be16_to_cpu(bf[0].length); 1255 longest = be16_to_cpu(bf[0].length);
1256 needlog = needscan = 0; 1256 needlog = needscan = 0;
1257 xfs_dir2_data_make_free(tp, dbp, off, 1257 xfs_dir2_data_make_free(tp, dbp, off,
1258 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); 1258 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
1259 /* 1259 /*
1260 * Rescan the data block freespaces for bestfree. 1260 * Rescan the data block freespaces for bestfree.
1261 * Log the data block header if needed. 1261 * Log the data block header if needed.
1262 */ 1262 */
1263 if (needscan) 1263 if (needscan)
1264 xfs_dir2_data_freescan(mp, hdr, &needlog); 1264 xfs_dir2_data_freescan(mp, hdr, &needlog);
1265 if (needlog) 1265 if (needlog)
1266 xfs_dir2_data_log_header(tp, dbp); 1266 xfs_dir2_data_log_header(tp, dbp);
1267 xfs_dir3_data_check(dp, dbp); 1267 xfs_dir3_data_check(dp, dbp);
1268 /* 1268 /*
1269 * If the longest data block freespace changes, need to update 1269 * If the longest data block freespace changes, need to update
1270 * the corresponding freeblock entry. 1270 * the corresponding freeblock entry.
1271 */ 1271 */
1272 if (longest < be16_to_cpu(bf[0].length)) { 1272 if (longest < be16_to_cpu(bf[0].length)) {
1273 int error; /* error return value */ 1273 int error; /* error return value */
1274 struct xfs_buf *fbp; /* freeblock buffer */ 1274 struct xfs_buf *fbp; /* freeblock buffer */
1275 xfs_dir2_db_t fdb; /* freeblock block number */ 1275 xfs_dir2_db_t fdb; /* freeblock block number */
1276 int findex; /* index in freeblock entries */ 1276 int findex; /* index in freeblock entries */
1277 xfs_dir2_free_t *free; /* freeblock structure */ 1277 xfs_dir2_free_t *free; /* freeblock structure */
1278 1278
1279 /* 1279 /*
1280 * Convert the data block number to a free block, 1280 * Convert the data block number to a free block,
1281 * read in the free block. 1281 * read in the free block.
1282 */ 1282 */
1283 fdb = xfs_dir2_db_to_fdb(mp, db); 1283 fdb = xfs_dir2_db_to_fdb(mp, db);
1284 error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(mp, fdb), 1284 error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(mp, fdb),
1285 &fbp); 1285 &fbp);
1286 if (error) 1286 if (error)
1287 return error; 1287 return error;
1288 free = fbp->b_addr; 1288 free = fbp->b_addr;
1289 #ifdef DEBUG 1289 #ifdef DEBUG
1290 { 1290 {
1291 struct xfs_dir3_icfree_hdr freehdr; 1291 struct xfs_dir3_icfree_hdr freehdr;
1292 xfs_dir3_free_hdr_from_disk(&freehdr, free); 1292 xfs_dir3_free_hdr_from_disk(&freehdr, free);
1293 ASSERT(freehdr.firstdb == xfs_dir3_free_max_bests(mp) * 1293 ASSERT(freehdr.firstdb == xfs_dir3_free_max_bests(mp) *
1294 (fdb - XFS_DIR2_FREE_FIRSTDB(mp))); 1294 (fdb - XFS_DIR2_FREE_FIRSTDB(mp)));
1295 } 1295 }
1296 #endif 1296 #endif
1297 /* 1297 /*
1298 * Calculate which entry we need to fix. 1298 * Calculate which entry we need to fix.
1299 */ 1299 */
1300 findex = xfs_dir2_db_to_fdindex(mp, db); 1300 findex = xfs_dir2_db_to_fdindex(mp, db);
1301 longest = be16_to_cpu(bf[0].length); 1301 longest = be16_to_cpu(bf[0].length);
1302 /* 1302 /*
1303 * If the data block is now empty we can get rid of it 1303 * If the data block is now empty we can get rid of it
1304 * (usually). 1304 * (usually).
1305 */ 1305 */
1306 if (longest == mp->m_dirblksize - 1306 if (longest == mp->m_dirblksize -
1307 xfs_dir3_data_entry_offset(hdr)) { 1307 xfs_dir3_data_entry_offset(hdr)) {
1308 /* 1308 /*
1309 * Try to punch out the data block. 1309 * Try to punch out the data block.
1310 */ 1310 */
1311 error = xfs_dir2_shrink_inode(args, db, dbp); 1311 error = xfs_dir2_shrink_inode(args, db, dbp);
1312 if (error == 0) { 1312 if (error == 0) {
1313 dblk->bp = NULL; 1313 dblk->bp = NULL;
1314 hdr = NULL; 1314 hdr = NULL;
1315 } 1315 }
1316 /* 1316 /*
1317 * We can get ENOSPC if there's no space reservation. 1317 * We can get ENOSPC if there's no space reservation.
1318 * In this case just drop the buffer and some one else 1318 * In this case just drop the buffer and some one else
1319 * will eventually get rid of the empty block. 1319 * will eventually get rid of the empty block.
1320 */ 1320 */
1321 else if (!(error == ENOSPC && args->total == 0)) 1321 else if (!(error == ENOSPC && args->total == 0))
1322 return error; 1322 return error;
1323 } 1323 }
1324 /* 1324 /*
1325 * If we got rid of the data block, we can eliminate that entry 1325 * If we got rid of the data block, we can eliminate that entry
1326 * in the free block. 1326 * in the free block.
1327 */ 1327 */
1328 error = xfs_dir3_data_block_free(args, hdr, free, 1328 error = xfs_dir3_data_block_free(args, hdr, free,
1329 fdb, findex, fbp, longest); 1329 fdb, findex, fbp, longest);
1330 if (error) 1330 if (error)
1331 return error; 1331 return error;
1332 } 1332 }
1333 1333
1334 xfs_dir3_leaf_check(mp, bp); 1334 xfs_dir3_leaf_check(mp, bp);
1335 /* 1335 /*
1336 * Return indication of whether this leaf block is empty enough 1336 * Return indication of whether this leaf block is empty enough
1337 * to justify trying to join it with a neighbor. 1337 * to justify trying to join it with a neighbor.
1338 */ 1338 */
1339 *rval = (xfs_dir3_leaf_hdr_size(leaf) + 1339 *rval = (xfs_dir3_leaf_hdr_size(leaf) +
1340 (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) < 1340 (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) <
1341 mp->m_dir_magicpct; 1341 mp->m_dir_magicpct;
1342 return 0; 1342 return 0;
1343 } 1343 }
1344 1344
1345 /* 1345 /*
1346 * Split the leaf entries in the old block into old and new blocks. 1346 * Split the leaf entries in the old block into old and new blocks.
1347 */ 1347 */
1348 int /* error */ 1348 int /* error */
1349 xfs_dir2_leafn_split( 1349 xfs_dir2_leafn_split(
1350 xfs_da_state_t *state, /* btree cursor */ 1350 xfs_da_state_t *state, /* btree cursor */
1351 xfs_da_state_blk_t *oldblk, /* original block */ 1351 xfs_da_state_blk_t *oldblk, /* original block */
1352 xfs_da_state_blk_t *newblk) /* newly created block */ 1352 xfs_da_state_blk_t *newblk) /* newly created block */
1353 { 1353 {
1354 xfs_da_args_t *args; /* operation arguments */ 1354 xfs_da_args_t *args; /* operation arguments */
1355 xfs_dablk_t blkno; /* new leaf block number */ 1355 xfs_dablk_t blkno; /* new leaf block number */
1356 int error; /* error return value */ 1356 int error; /* error return value */
1357 xfs_mount_t *mp; /* filesystem mount point */ 1357 xfs_mount_t *mp; /* filesystem mount point */
1358 1358
1359 /* 1359 /*
1360 * Allocate space for a new leaf node. 1360 * Allocate space for a new leaf node.
1361 */ 1361 */
1362 args = state->args; 1362 args = state->args;
1363 mp = args->dp->i_mount; 1363 mp = args->dp->i_mount;
1364 ASSERT(args != NULL); 1364 ASSERT(args != NULL);
1365 ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC); 1365 ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC);
1366 error = xfs_da_grow_inode(args, &blkno); 1366 error = xfs_da_grow_inode(args, &blkno);
1367 if (error) { 1367 if (error) {
1368 return error; 1368 return error;
1369 } 1369 }
1370 /* 1370 /*
1371 * Initialize the new leaf block. 1371 * Initialize the new leaf block.
1372 */ 1372 */
1373 error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(mp, blkno), 1373 error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(mp, blkno),
1374 &newblk->bp, XFS_DIR2_LEAFN_MAGIC); 1374 &newblk->bp, XFS_DIR2_LEAFN_MAGIC);
1375 if (error) 1375 if (error)
1376 return error; 1376 return error;
1377 1377
1378 newblk->blkno = blkno; 1378 newblk->blkno = blkno;
1379 newblk->magic = XFS_DIR2_LEAFN_MAGIC; 1379 newblk->magic = XFS_DIR2_LEAFN_MAGIC;
1380 /* 1380 /*
1381 * Rebalance the entries across the two leaves, link the new 1381 * Rebalance the entries across the two leaves, link the new
1382 * block into the leaves. 1382 * block into the leaves.
1383 */ 1383 */
1384 xfs_dir2_leafn_rebalance(state, oldblk, newblk); 1384 xfs_dir2_leafn_rebalance(state, oldblk, newblk);
1385 error = xfs_da3_blk_link(state, oldblk, newblk); 1385 error = xfs_da3_blk_link(state, oldblk, newblk);
1386 if (error) { 1386 if (error) {
1387 return error; 1387 return error;
1388 } 1388 }
1389 /* 1389 /*
1390 * Insert the new entry in the correct block. 1390 * Insert the new entry in the correct block.
1391 */ 1391 */
1392 if (state->inleaf) 1392 if (state->inleaf)
1393 error = xfs_dir2_leafn_add(oldblk->bp, args, oldblk->index); 1393 error = xfs_dir2_leafn_add(oldblk->bp, args, oldblk->index);
1394 else 1394 else
1395 error = xfs_dir2_leafn_add(newblk->bp, args, newblk->index); 1395 error = xfs_dir2_leafn_add(newblk->bp, args, newblk->index);
1396 /* 1396 /*
1397 * Update last hashval in each block since we added the name. 1397 * Update last hashval in each block since we added the name.
1398 */ 1398 */
1399 oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL); 1399 oldblk->hashval = xfs_dir2_leafn_lasthash(oldblk->bp, NULL);
1400 newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL); 1400 newblk->hashval = xfs_dir2_leafn_lasthash(newblk->bp, NULL);
1401 xfs_dir3_leaf_check(mp, oldblk->bp); 1401 xfs_dir3_leaf_check(mp, oldblk->bp);
1402 xfs_dir3_leaf_check(mp, newblk->bp); 1402 xfs_dir3_leaf_check(mp, newblk->bp);
1403 return error; 1403 return error;
1404 } 1404 }
1405 1405
1406 /* 1406 /*
1407 * Check a leaf block and its neighbors to see if the block should be 1407 * Check a leaf block and its neighbors to see if the block should be
1408 * collapsed into one or the other neighbor. Always keep the block 1408 * collapsed into one or the other neighbor. Always keep the block
1409 * with the smaller block number. 1409 * with the smaller block number.
1410 * If the current block is over 50% full, don't try to join it, return 0. 1410 * If the current block is over 50% full, don't try to join it, return 0.
1411 * If the block is empty, fill in the state structure and return 2. 1411 * If the block is empty, fill in the state structure and return 2.
1412 * If it can be collapsed, fill in the state structure and return 1. 1412 * If it can be collapsed, fill in the state structure and return 1.
1413 * If nothing can be done, return 0. 1413 * If nothing can be done, return 0.
1414 */ 1414 */
1415 int /* error */ 1415 int /* error */
1416 xfs_dir2_leafn_toosmall( 1416 xfs_dir2_leafn_toosmall(
1417 xfs_da_state_t *state, /* btree cursor */ 1417 xfs_da_state_t *state, /* btree cursor */
1418 int *action) /* resulting action to take */ 1418 int *action) /* resulting action to take */
1419 { 1419 {
1420 xfs_da_state_blk_t *blk; /* leaf block */ 1420 xfs_da_state_blk_t *blk; /* leaf block */
1421 xfs_dablk_t blkno; /* leaf block number */ 1421 xfs_dablk_t blkno; /* leaf block number */
1422 struct xfs_buf *bp; /* leaf buffer */ 1422 struct xfs_buf *bp; /* leaf buffer */
1423 int bytes; /* bytes in use */ 1423 int bytes; /* bytes in use */
1424 int count; /* leaf live entry count */ 1424 int count; /* leaf live entry count */
1425 int error; /* error return value */ 1425 int error; /* error return value */
1426 int forward; /* sibling block direction */ 1426 int forward; /* sibling block direction */
1427 int i; /* sibling counter */ 1427 int i; /* sibling counter */
1428 xfs_dir2_leaf_t *leaf; /* leaf structure */ 1428 xfs_dir2_leaf_t *leaf; /* leaf structure */
1429 int rval; /* result from path_shift */ 1429 int rval; /* result from path_shift */
1430 struct xfs_dir3_icleaf_hdr leafhdr; 1430 struct xfs_dir3_icleaf_hdr leafhdr;
1431 struct xfs_dir2_leaf_entry *ents; 1431 struct xfs_dir2_leaf_entry *ents;
1432 1432
1433 /* 1433 /*
1434 * Check for the degenerate case of the block being over 50% full. 1434 * Check for the degenerate case of the block being over 50% full.
1435 * If so, it's not worth even looking to see if we might be able 1435 * If so, it's not worth even looking to see if we might be able
1436 * to coalesce with a sibling. 1436 * to coalesce with a sibling.
1437 */ 1437 */
1438 blk = &state->path.blk[state->path.active - 1]; 1438 blk = &state->path.blk[state->path.active - 1];
1439 leaf = blk->bp->b_addr; 1439 leaf = blk->bp->b_addr;
1440 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); 1440 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
1441 ents = xfs_dir3_leaf_ents_p(leaf); 1441 ents = xfs_dir3_leaf_ents_p(leaf);
1442 xfs_dir3_leaf_check(state->args->dp->i_mount, blk->bp); 1442 xfs_dir3_leaf_check(state->args->dp->i_mount, blk->bp);
1443 1443
1444 count = leafhdr.count - leafhdr.stale; 1444 count = leafhdr.count - leafhdr.stale;
1445 bytes = xfs_dir3_leaf_hdr_size(leaf) + count * sizeof(ents[0]); 1445 bytes = xfs_dir3_leaf_hdr_size(leaf) + count * sizeof(ents[0]);
1446 if (bytes > (state->blocksize >> 1)) { 1446 if (bytes > (state->blocksize >> 1)) {
1447 /* 1447 /*
1448 * Blk over 50%, don't try to join. 1448 * Blk over 50%, don't try to join.
1449 */ 1449 */
1450 *action = 0; 1450 *action = 0;
1451 return 0; 1451 return 0;
1452 } 1452 }
1453 /* 1453 /*
1454 * Check for the degenerate case of the block being empty. 1454 * Check for the degenerate case of the block being empty.
1455 * If the block is empty, we'll simply delete it, no need to 1455 * If the block is empty, we'll simply delete it, no need to
1456 * coalesce it with a sibling block. We choose (arbitrarily) 1456 * coalesce it with a sibling block. We choose (arbitrarily)
1457 * to merge with the forward block unless it is NULL. 1457 * to merge with the forward block unless it is NULL.
1458 */ 1458 */
1459 if (count == 0) { 1459 if (count == 0) {
1460 /* 1460 /*
1461 * Make altpath point to the block we want to keep and 1461 * Make altpath point to the block we want to keep and
1462 * path point to the block we want to drop (this one). 1462 * path point to the block we want to drop (this one).
1463 */ 1463 */
1464 forward = (leafhdr.forw != 0); 1464 forward = (leafhdr.forw != 0);
1465 memcpy(&state->altpath, &state->path, sizeof(state->path)); 1465 memcpy(&state->altpath, &state->path, sizeof(state->path));
1466 error = xfs_da3_path_shift(state, &state->altpath, forward, 0, 1466 error = xfs_da3_path_shift(state, &state->altpath, forward, 0,
1467 &rval); 1467 &rval);
1468 if (error) 1468 if (error)
1469 return error; 1469 return error;
1470 *action = rval ? 2 : 0; 1470 *action = rval ? 2 : 0;
1471 return 0; 1471 return 0;
1472 } 1472 }
1473 /* 1473 /*
1474 * Examine each sibling block to see if we can coalesce with 1474 * Examine each sibling block to see if we can coalesce with
1475 * at least 25% free space to spare. We need to figure out 1475 * at least 25% free space to spare. We need to figure out
1476 * whether to merge with the forward or the backward block. 1476 * whether to merge with the forward or the backward block.
1477 * We prefer coalescing with the lower numbered sibling so as 1477 * We prefer coalescing with the lower numbered sibling so as
1478 * to shrink a directory over time. 1478 * to shrink a directory over time.
1479 */ 1479 */
1480 forward = leafhdr.forw < leafhdr.back; 1480 forward = leafhdr.forw < leafhdr.back;
1481 for (i = 0, bp = NULL; i < 2; forward = !forward, i++) { 1481 for (i = 0, bp = NULL; i < 2; forward = !forward, i++) {
1482 struct xfs_dir3_icleaf_hdr hdr2; 1482 struct xfs_dir3_icleaf_hdr hdr2;
1483 1483
1484 blkno = forward ? leafhdr.forw : leafhdr.back; 1484 blkno = forward ? leafhdr.forw : leafhdr.back;
1485 if (blkno == 0) 1485 if (blkno == 0)
1486 continue; 1486 continue;
1487 /* 1487 /*
1488 * Read the sibling leaf block. 1488 * Read the sibling leaf block.
1489 */ 1489 */
1490 error = xfs_dir3_leafn_read(state->args->trans, state->args->dp, 1490 error = xfs_dir3_leafn_read(state->args->trans, state->args->dp,
1491 blkno, -1, &bp); 1491 blkno, -1, &bp);
1492 if (error) 1492 if (error)
1493 return error; 1493 return error;
1494 1494
1495 /* 1495 /*
1496 * Count bytes in the two blocks combined. 1496 * Count bytes in the two blocks combined.
1497 */ 1497 */
1498 count = leafhdr.count - leafhdr.stale; 1498 count = leafhdr.count - leafhdr.stale;
1499 bytes = state->blocksize - (state->blocksize >> 2); 1499 bytes = state->blocksize - (state->blocksize >> 2);
1500 1500
1501 leaf = bp->b_addr; 1501 leaf = bp->b_addr;
1502 xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf); 1502 xfs_dir3_leaf_hdr_from_disk(&hdr2, leaf);
1503 ents = xfs_dir3_leaf_ents_p(leaf); 1503 ents = xfs_dir3_leaf_ents_p(leaf);
1504 count += hdr2.count - hdr2.stale; 1504 count += hdr2.count - hdr2.stale;
1505 bytes -= count * sizeof(ents[0]); 1505 bytes -= count * sizeof(ents[0]);
1506 1506
1507 /* 1507 /*
1508 * Fits with at least 25% to spare. 1508 * Fits with at least 25% to spare.
1509 */ 1509 */
1510 if (bytes >= 0) 1510 if (bytes >= 0)
1511 break; 1511 break;
1512 xfs_trans_brelse(state->args->trans, bp); 1512 xfs_trans_brelse(state->args->trans, bp);
1513 } 1513 }
1514 /* 1514 /*
1515 * Didn't like either block, give up. 1515 * Didn't like either block, give up.
1516 */ 1516 */
1517 if (i >= 2) { 1517 if (i >= 2) {
1518 *action = 0; 1518 *action = 0;
1519 return 0; 1519 return 0;
1520 } 1520 }
1521 1521
1522 /* 1522 /*
1523 * Make altpath point to the block we want to keep (the lower 1523 * Make altpath point to the block we want to keep (the lower
1524 * numbered block) and path point to the block we want to drop. 1524 * numbered block) and path point to the block we want to drop.
1525 */ 1525 */
1526 memcpy(&state->altpath, &state->path, sizeof(state->path)); 1526 memcpy(&state->altpath, &state->path, sizeof(state->path));
1527 if (blkno < blk->blkno) 1527 if (blkno < blk->blkno)
1528 error = xfs_da3_path_shift(state, &state->altpath, forward, 0, 1528 error = xfs_da3_path_shift(state, &state->altpath, forward, 0,
1529 &rval); 1529 &rval);
1530 else 1530 else
1531 error = xfs_da3_path_shift(state, &state->path, forward, 0, 1531 error = xfs_da3_path_shift(state, &state->path, forward, 0,
1532 &rval); 1532 &rval);
1533 if (error) { 1533 if (error) {
1534 return error; 1534 return error;
1535 } 1535 }
1536 *action = rval ? 0 : 1; 1536 *action = rval ? 0 : 1;
1537 return 0; 1537 return 0;
1538 } 1538 }
1539 1539
1540 /* 1540 /*
1541 * Move all the leaf entries from drop_blk to save_blk. 1541 * Move all the leaf entries from drop_blk to save_blk.
1542 * This is done as part of a join operation. 1542 * This is done as part of a join operation.
1543 */ 1543 */
1544 void 1544 void
1545 xfs_dir2_leafn_unbalance( 1545 xfs_dir2_leafn_unbalance(
1546 xfs_da_state_t *state, /* cursor */ 1546 xfs_da_state_t *state, /* cursor */
1547 xfs_da_state_blk_t *drop_blk, /* dead block */ 1547 xfs_da_state_blk_t *drop_blk, /* dead block */
1548 xfs_da_state_blk_t *save_blk) /* surviving block */ 1548 xfs_da_state_blk_t *save_blk) /* surviving block */
1549 { 1549 {
1550 xfs_da_args_t *args; /* operation arguments */ 1550 xfs_da_args_t *args; /* operation arguments */
1551 xfs_dir2_leaf_t *drop_leaf; /* dead leaf structure */ 1551 xfs_dir2_leaf_t *drop_leaf; /* dead leaf structure */
1552 xfs_dir2_leaf_t *save_leaf; /* surviving leaf structure */ 1552 xfs_dir2_leaf_t *save_leaf; /* surviving leaf structure */
1553 struct xfs_dir3_icleaf_hdr savehdr; 1553 struct xfs_dir3_icleaf_hdr savehdr;
1554 struct xfs_dir3_icleaf_hdr drophdr; 1554 struct xfs_dir3_icleaf_hdr drophdr;
1555 struct xfs_dir2_leaf_entry *sents; 1555 struct xfs_dir2_leaf_entry *sents;
1556 struct xfs_dir2_leaf_entry *dents; 1556 struct xfs_dir2_leaf_entry *dents;
1557 1557
1558 args = state->args; 1558 args = state->args;
1559 ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); 1559 ASSERT(drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
1560 ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC); 1560 ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC);
1561 drop_leaf = drop_blk->bp->b_addr; 1561 drop_leaf = drop_blk->bp->b_addr;
1562 save_leaf = save_blk->bp->b_addr; 1562 save_leaf = save_blk->bp->b_addr;
1563 1563
1564 xfs_dir3_leaf_hdr_from_disk(&savehdr, save_leaf); 1564 xfs_dir3_leaf_hdr_from_disk(&savehdr, save_leaf);
1565 xfs_dir3_leaf_hdr_from_disk(&drophdr, drop_leaf); 1565 xfs_dir3_leaf_hdr_from_disk(&drophdr, drop_leaf);
1566 sents = xfs_dir3_leaf_ents_p(save_leaf); 1566 sents = xfs_dir3_leaf_ents_p(save_leaf);
1567 dents = xfs_dir3_leaf_ents_p(drop_leaf); 1567 dents = xfs_dir3_leaf_ents_p(drop_leaf);
1568 1568
1569 /* 1569 /*
1570 * If there are any stale leaf entries, take this opportunity 1570 * If there are any stale leaf entries, take this opportunity
1571 * to purge them. 1571 * to purge them.
1572 */ 1572 */
1573 if (drophdr.stale) 1573 if (drophdr.stale)
1574 xfs_dir3_leaf_compact(args, &drophdr, drop_blk->bp); 1574 xfs_dir3_leaf_compact(args, &drophdr, drop_blk->bp);
1575 if (savehdr.stale) 1575 if (savehdr.stale)
1576 xfs_dir3_leaf_compact(args, &savehdr, save_blk->bp); 1576 xfs_dir3_leaf_compact(args, &savehdr, save_blk->bp);
1577 1577
1578 /* 1578 /*
1579 * Move the entries from drop to the appropriate end of save. 1579 * Move the entries from drop to the appropriate end of save.
1580 */ 1580 */
1581 drop_blk->hashval = be32_to_cpu(dents[drophdr.count - 1].hashval); 1581 drop_blk->hashval = be32_to_cpu(dents[drophdr.count - 1].hashval);
1582 if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp)) 1582 if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp))
1583 xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0, 1583 xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0,
1584 save_blk->bp, &savehdr, sents, 0, 1584 save_blk->bp, &savehdr, sents, 0,
1585 drophdr.count); 1585 drophdr.count);
1586 else 1586 else
1587 xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0, 1587 xfs_dir3_leafn_moveents(args, drop_blk->bp, &drophdr, dents, 0,
1588 save_blk->bp, &savehdr, sents, 1588 save_blk->bp, &savehdr, sents,
1589 savehdr.count, drophdr.count); 1589 savehdr.count, drophdr.count);
1590 save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval); 1590 save_blk->hashval = be32_to_cpu(sents[savehdr.count - 1].hashval);
1591 1591
1592 /* log the changes made when moving the entries */ 1592 /* log the changes made when moving the entries */
1593 xfs_dir3_leaf_hdr_to_disk(save_leaf, &savehdr); 1593 xfs_dir3_leaf_hdr_to_disk(save_leaf, &savehdr);
1594 xfs_dir3_leaf_hdr_to_disk(drop_leaf, &drophdr); 1594 xfs_dir3_leaf_hdr_to_disk(drop_leaf, &drophdr);
1595 xfs_dir3_leaf_log_header(args->trans, save_blk->bp); 1595 xfs_dir3_leaf_log_header(args->trans, save_blk->bp);
1596 xfs_dir3_leaf_log_header(args->trans, drop_blk->bp); 1596 xfs_dir3_leaf_log_header(args->trans, drop_blk->bp);
1597 1597
1598 xfs_dir3_leaf_check(args->dp->i_mount, save_blk->bp); 1598 xfs_dir3_leaf_check(args->dp->i_mount, save_blk->bp);
1599 xfs_dir3_leaf_check(args->dp->i_mount, drop_blk->bp); 1599 xfs_dir3_leaf_check(args->dp->i_mount, drop_blk->bp);
1600 } 1600 }
1601 1601
1602 /* 1602 /*
1603 * Top-level node form directory addname routine. 1603 * Top-level node form directory addname routine.
1604 */ 1604 */
1605 int /* error */ 1605 int /* error */
1606 xfs_dir2_node_addname( 1606 xfs_dir2_node_addname(
1607 xfs_da_args_t *args) /* operation arguments */ 1607 xfs_da_args_t *args) /* operation arguments */
1608 { 1608 {
1609 xfs_da_state_blk_t *blk; /* leaf block for insert */ 1609 xfs_da_state_blk_t *blk; /* leaf block for insert */
1610 int error; /* error return value */ 1610 int error; /* error return value */
1611 int rval; /* sub-return value */ 1611 int rval; /* sub-return value */
1612 xfs_da_state_t *state; /* btree cursor */ 1612 xfs_da_state_t *state; /* btree cursor */
1613 1613
1614 trace_xfs_dir2_node_addname(args); 1614 trace_xfs_dir2_node_addname(args);
1615 1615
1616 /* 1616 /*
1617 * Allocate and initialize the state (btree cursor). 1617 * Allocate and initialize the state (btree cursor).
1618 */ 1618 */
1619 state = xfs_da_state_alloc(); 1619 state = xfs_da_state_alloc();
1620 state->args = args; 1620 state->args = args;
1621 state->mp = args->dp->i_mount; 1621 state->mp = args->dp->i_mount;
1622 state->blocksize = state->mp->m_dirblksize; 1622 state->blocksize = state->mp->m_dirblksize;
1623 state->node_ents = state->mp->m_dir_node_ents; 1623 state->node_ents = state->mp->m_dir_node_ents;
1624 /* 1624 /*
1625 * Look up the name. We're not supposed to find it, but 1625 * Look up the name. We're not supposed to find it, but
1626 * this gives us the insertion point. 1626 * this gives us the insertion point.
1627 */ 1627 */
1628 error = xfs_da3_node_lookup_int(state, &rval); 1628 error = xfs_da3_node_lookup_int(state, &rval);
1629 if (error) 1629 if (error)
1630 rval = error; 1630 rval = error;
1631 if (rval != ENOENT) { 1631 if (rval != ENOENT) {
1632 goto done; 1632 goto done;
1633 } 1633 }
1634 /* 1634 /*
1635 * Add the data entry to a data block. 1635 * Add the data entry to a data block.
1636 * Extravalid is set to a freeblock found by lookup. 1636 * Extravalid is set to a freeblock found by lookup.
1637 */ 1637 */
1638 rval = xfs_dir2_node_addname_int(args, 1638 rval = xfs_dir2_node_addname_int(args,
1639 state->extravalid ? &state->extrablk : NULL); 1639 state->extravalid ? &state->extrablk : NULL);
1640 if (rval) { 1640 if (rval) {
1641 goto done; 1641 goto done;
1642 } 1642 }
1643 blk = &state->path.blk[state->path.active - 1]; 1643 blk = &state->path.blk[state->path.active - 1];
1644 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); 1644 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
1645 /* 1645 /*
1646 * Add the new leaf entry. 1646 * Add the new leaf entry.
1647 */ 1647 */
1648 rval = xfs_dir2_leafn_add(blk->bp, args, blk->index); 1648 rval = xfs_dir2_leafn_add(blk->bp, args, blk->index);
1649 if (rval == 0) { 1649 if (rval == 0) {
1650 /* 1650 /*
1651 * It worked, fix the hash values up the btree. 1651 * It worked, fix the hash values up the btree.
1652 */ 1652 */
1653 if (!(args->op_flags & XFS_DA_OP_JUSTCHECK)) 1653 if (!(args->op_flags & XFS_DA_OP_JUSTCHECK))
1654 xfs_da3_fixhashpath(state, &state->path); 1654 xfs_da3_fixhashpath(state, &state->path);
1655 } else { 1655 } else {
1656 /* 1656 /*
1657 * It didn't work, we need to split the leaf block. 1657 * It didn't work, we need to split the leaf block.
1658 */ 1658 */
1659 if (args->total == 0) { 1659 if (args->total == 0) {
1660 ASSERT(rval == ENOSPC); 1660 ASSERT(rval == ENOSPC);
1661 goto done; 1661 goto done;
1662 } 1662 }
1663 /* 1663 /*
1664 * Split the leaf block and insert the new entry. 1664 * Split the leaf block and insert the new entry.
1665 */ 1665 */
1666 rval = xfs_da3_split(state); 1666 rval = xfs_da3_split(state);
1667 } 1667 }
1668 done: 1668 done:
1669 xfs_da_state_free(state); 1669 xfs_da_state_free(state);
1670 return rval; 1670 return rval;
1671 } 1671 }
1672 1672
1673 /* 1673 /*
1674 * Add the data entry for a node-format directory name addition. 1674 * Add the data entry for a node-format directory name addition.
1675 * The leaf entry is added in xfs_dir2_leafn_add. 1675 * The leaf entry is added in xfs_dir2_leafn_add.
1676 * We may enter with a freespace block that the lookup found. 1676 * We may enter with a freespace block that the lookup found.
1677 */ 1677 */
1678 static int /* error */ 1678 static int /* error */
1679 xfs_dir2_node_addname_int( 1679 xfs_dir2_node_addname_int(
1680 xfs_da_args_t *args, /* operation arguments */ 1680 xfs_da_args_t *args, /* operation arguments */
1681 xfs_da_state_blk_t *fblk) /* optional freespace block */ 1681 xfs_da_state_blk_t *fblk) /* optional freespace block */
1682 { 1682 {
1683 xfs_dir2_data_hdr_t *hdr; /* data block header */ 1683 xfs_dir2_data_hdr_t *hdr; /* data block header */
1684 xfs_dir2_db_t dbno; /* data block number */ 1684 xfs_dir2_db_t dbno; /* data block number */
1685 struct xfs_buf *dbp; /* data block buffer */ 1685 struct xfs_buf *dbp; /* data block buffer */
1686 xfs_dir2_data_entry_t *dep; /* data entry pointer */ 1686 xfs_dir2_data_entry_t *dep; /* data entry pointer */
1687 xfs_inode_t *dp; /* incore directory inode */ 1687 xfs_inode_t *dp; /* incore directory inode */
1688 xfs_dir2_data_unused_t *dup; /* data unused entry pointer */ 1688 xfs_dir2_data_unused_t *dup; /* data unused entry pointer */
1689 int error; /* error return value */ 1689 int error; /* error return value */
1690 xfs_dir2_db_t fbno; /* freespace block number */ 1690 xfs_dir2_db_t fbno; /* freespace block number */
1691 struct xfs_buf *fbp; /* freespace buffer */ 1691 struct xfs_buf *fbp; /* freespace buffer */
1692 int findex; /* freespace entry index */ 1692 int findex; /* freespace entry index */
1693 xfs_dir2_free_t *free=NULL; /* freespace block structure */ 1693 xfs_dir2_free_t *free=NULL; /* freespace block structure */
1694 xfs_dir2_db_t ifbno; /* initial freespace block no */ 1694 xfs_dir2_db_t ifbno; /* initial freespace block no */
1695 xfs_dir2_db_t lastfbno=0; /* highest freespace block no */ 1695 xfs_dir2_db_t lastfbno=0; /* highest freespace block no */
1696 int length; /* length of the new entry */ 1696 int length; /* length of the new entry */
1697 int logfree; /* need to log free entry */ 1697 int logfree; /* need to log free entry */
1698 xfs_mount_t *mp; /* filesystem mount point */ 1698 xfs_mount_t *mp; /* filesystem mount point */
1699 int needlog; /* need to log data header */ 1699 int needlog; /* need to log data header */
1700 int needscan; /* need to rescan data frees */ 1700 int needscan; /* need to rescan data frees */
1701 __be16 *tagp; /* data entry tag pointer */ 1701 __be16 *tagp; /* data entry tag pointer */
1702 xfs_trans_t *tp; /* transaction pointer */ 1702 xfs_trans_t *tp; /* transaction pointer */
1703 __be16 *bests; 1703 __be16 *bests;
1704 struct xfs_dir3_icfree_hdr freehdr; 1704 struct xfs_dir3_icfree_hdr freehdr;
1705 struct xfs_dir2_data_free *bf; 1705 struct xfs_dir2_data_free *bf;
1706 1706
1707 dp = args->dp; 1707 dp = args->dp;
1708 mp = dp->i_mount; 1708 mp = dp->i_mount;
1709 tp = args->trans; 1709 tp = args->trans;
1710 length = xfs_dir2_data_entsize(args->namelen); 1710 length = xfs_dir2_data_entsize(args->namelen);
1711 /* 1711 /*
1712 * If we came in with a freespace block that means that lookup 1712 * If we came in with a freespace block that means that lookup
1713 * found an entry with our hash value. This is the freespace 1713 * found an entry with our hash value. This is the freespace
1714 * block for that data entry. 1714 * block for that data entry.
1715 */ 1715 */
1716 if (fblk) { 1716 if (fblk) {
1717 fbp = fblk->bp; 1717 fbp = fblk->bp;
1718 /* 1718 /*
1719 * Remember initial freespace block number. 1719 * Remember initial freespace block number.
1720 */ 1720 */
1721 ifbno = fblk->blkno; 1721 ifbno = fblk->blkno;
1722 free = fbp->b_addr; 1722 free = fbp->b_addr;
1723 findex = fblk->index; 1723 findex = fblk->index;
1724 bests = xfs_dir3_free_bests_p(mp, free); 1724 bests = xfs_dir3_free_bests_p(mp, free);
1725 xfs_dir3_free_hdr_from_disk(&freehdr, free); 1725 xfs_dir3_free_hdr_from_disk(&freehdr, free);
1726 1726
1727 /* 1727 /*
1728 * This means the free entry showed that the data block had 1728 * This means the free entry showed that the data block had
1729 * space for our entry, so we remembered it. 1729 * space for our entry, so we remembered it.
1730 * Use that data block. 1730 * Use that data block.
1731 */ 1731 */
1732 if (findex >= 0) { 1732 if (findex >= 0) {
1733 ASSERT(findex < freehdr.nvalid); 1733 ASSERT(findex < freehdr.nvalid);
1734 ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF); 1734 ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
1735 ASSERT(be16_to_cpu(bests[findex]) >= length); 1735 ASSERT(be16_to_cpu(bests[findex]) >= length);
1736 dbno = freehdr.firstdb + findex; 1736 dbno = freehdr.firstdb + findex;
1737 } else { 1737 } else {
1738 /* 1738 /*
1739 * The data block looked at didn't have enough room. 1739 * The data block looked at didn't have enough room.
1740 * We'll start at the beginning of the freespace entries. 1740 * We'll start at the beginning of the freespace entries.
1741 */ 1741 */
1742 dbno = -1; 1742 dbno = -1;
1743 findex = 0; 1743 findex = 0;
1744 } 1744 }
1745 } else { 1745 } else {
1746 /* 1746 /*
1747 * Didn't come in with a freespace block, so no data block. 1747 * Didn't come in with a freespace block, so no data block.
1748 */ 1748 */
1749 ifbno = dbno = -1; 1749 ifbno = dbno = -1;
1750 fbp = NULL; 1750 fbp = NULL;
1751 findex = 0; 1751 findex = 0;
1752 } 1752 }
1753 1753
1754 /* 1754 /*
1755 * If we don't have a data block yet, we're going to scan the 1755 * If we don't have a data block yet, we're going to scan the
1756 * freespace blocks looking for one. Figure out what the 1756 * freespace blocks looking for one. Figure out what the
1757 * highest freespace block number is. 1757 * highest freespace block number is.
1758 */ 1758 */
1759 if (dbno == -1) { 1759 if (dbno == -1) {
1760 xfs_fileoff_t fo; /* freespace block number */ 1760 xfs_fileoff_t fo; /* freespace block number */
1761 1761
1762 if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) 1762 if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK)))
1763 return error; 1763 return error;
1764 lastfbno = xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo); 1764 lastfbno = xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo);
1765 fbno = ifbno; 1765 fbno = ifbno;
1766 } 1766 }
1767 /* 1767 /*
1768 * While we haven't identified a data block, search the freeblock 1768 * While we haven't identified a data block, search the freeblock
1769 * data for a good data block. If we find a null freeblock entry, 1769 * data for a good data block. If we find a null freeblock entry,
1770 * indicating a hole in the data blocks, remember that. 1770 * indicating a hole in the data blocks, remember that.
1771 */ 1771 */
1772 while (dbno == -1) { 1772 while (dbno == -1) {
1773 /* 1773 /*
1774 * If we don't have a freeblock in hand, get the next one. 1774 * If we don't have a freeblock in hand, get the next one.
1775 */ 1775 */
1776 if (fbp == NULL) { 1776 if (fbp == NULL) {
1777 /* 1777 /*
1778 * Happens the first time through unless lookup gave 1778 * Happens the first time through unless lookup gave
1779 * us a freespace block to start with. 1779 * us a freespace block to start with.
1780 */ 1780 */
1781 if (++fbno == 0) 1781 if (++fbno == 0)
1782 fbno = XFS_DIR2_FREE_FIRSTDB(mp); 1782 fbno = XFS_DIR2_FREE_FIRSTDB(mp);
1783 /* 1783 /*
1784 * If it's ifbno we already looked at it. 1784 * If it's ifbno we already looked at it.
1785 */ 1785 */
1786 if (fbno == ifbno) 1786 if (fbno == ifbno)
1787 fbno++; 1787 fbno++;
1788 /* 1788 /*
1789 * If it's off the end we're done. 1789 * If it's off the end we're done.
1790 */ 1790 */
1791 if (fbno >= lastfbno) 1791 if (fbno >= lastfbno)
1792 break; 1792 break;
1793 /* 1793 /*
1794 * Read the block. There can be holes in the 1794 * Read the block. There can be holes in the
1795 * freespace blocks, so this might not succeed. 1795 * freespace blocks, so this might not succeed.
1796 * This should be really rare, so there's no reason 1796 * This should be really rare, so there's no reason
1797 * to avoid it. 1797 * to avoid it.
1798 */ 1798 */
1799 error = xfs_dir2_free_try_read(tp, dp, 1799 error = xfs_dir2_free_try_read(tp, dp,
1800 xfs_dir2_db_to_da(mp, fbno), 1800 xfs_dir2_db_to_da(mp, fbno),
1801 &fbp); 1801 &fbp);
1802 if (error) 1802 if (error)
1803 return error; 1803 return error;
1804 if (!fbp) 1804 if (!fbp)
1805 continue; 1805 continue;
1806 free = fbp->b_addr; 1806 free = fbp->b_addr;
1807 findex = 0; 1807 findex = 0;
1808 } 1808 }
1809 /* 1809 /*
1810 * Look at the current free entry. Is it good enough? 1810 * Look at the current free entry. Is it good enough?
1811 * 1811 *
1812 * The bests initialisation should be where the bufer is read in 1812 * The bests initialisation should be where the bufer is read in
1813 * the above branch. But gcc is too stupid to realise that bests 1813 * the above branch. But gcc is too stupid to realise that bests
1814 * and the freehdr are actually initialised if they are placed 1814 * and the freehdr are actually initialised if they are placed
1815 * there, so we have to do it here to avoid warnings. Blech. 1815 * there, so we have to do it here to avoid warnings. Blech.
1816 */ 1816 */
1817 bests = xfs_dir3_free_bests_p(mp, free); 1817 bests = xfs_dir3_free_bests_p(mp, free);
1818 xfs_dir3_free_hdr_from_disk(&freehdr, free); 1818 xfs_dir3_free_hdr_from_disk(&freehdr, free);
1819 if (be16_to_cpu(bests[findex]) != NULLDATAOFF && 1819 if (be16_to_cpu(bests[findex]) != NULLDATAOFF &&
1820 be16_to_cpu(bests[findex]) >= length) 1820 be16_to_cpu(bests[findex]) >= length)
1821 dbno = freehdr.firstdb + findex; 1821 dbno = freehdr.firstdb + findex;
1822 else { 1822 else {
1823 /* 1823 /*
1824 * Are we done with the freeblock? 1824 * Are we done with the freeblock?
1825 */ 1825 */
1826 if (++findex == freehdr.nvalid) { 1826 if (++findex == freehdr.nvalid) {
1827 /* 1827 /*
1828 * Drop the block. 1828 * Drop the block.
1829 */ 1829 */
1830 xfs_trans_brelse(tp, fbp); 1830 xfs_trans_brelse(tp, fbp);
1831 fbp = NULL; 1831 fbp = NULL;
1832 if (fblk && fblk->bp) 1832 if (fblk && fblk->bp)
1833 fblk->bp = NULL; 1833 fblk->bp = NULL;
1834 } 1834 }
1835 } 1835 }
1836 } 1836 }
1837 /* 1837 /*
1838 * If we don't have a data block, we need to allocate one and make 1838 * If we don't have a data block, we need to allocate one and make
1839 * the freespace entries refer to it. 1839 * the freespace entries refer to it.
1840 */ 1840 */
1841 if (unlikely(dbno == -1)) { 1841 if (unlikely(dbno == -1)) {
1842 /* 1842 /*
1843 * Not allowed to allocate, return failure. 1843 * Not allowed to allocate, return failure.
1844 */ 1844 */
1845 if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) 1845 if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0)
1846 return XFS_ERROR(ENOSPC); 1846 return XFS_ERROR(ENOSPC);
1847 1847
1848 /* 1848 /*
1849 * Allocate and initialize the new data block. 1849 * Allocate and initialize the new data block.
1850 */ 1850 */
1851 if (unlikely((error = xfs_dir2_grow_inode(args, 1851 if (unlikely((error = xfs_dir2_grow_inode(args,
1852 XFS_DIR2_DATA_SPACE, 1852 XFS_DIR2_DATA_SPACE,
1853 &dbno)) || 1853 &dbno)) ||
1854 (error = xfs_dir3_data_init(args, dbno, &dbp)))) 1854 (error = xfs_dir3_data_init(args, dbno, &dbp))))
1855 return error; 1855 return error;
1856 1856
1857 /* 1857 /*
1858 * If (somehow) we have a freespace block, get rid of it. 1858 * If (somehow) we have a freespace block, get rid of it.
1859 */ 1859 */
1860 if (fbp) 1860 if (fbp)
1861 xfs_trans_brelse(tp, fbp); 1861 xfs_trans_brelse(tp, fbp);
1862 if (fblk && fblk->bp) 1862 if (fblk && fblk->bp)
1863 fblk->bp = NULL; 1863 fblk->bp = NULL;
1864 1864
1865 /* 1865 /*
1866 * Get the freespace block corresponding to the data block 1866 * Get the freespace block corresponding to the data block
1867 * that was just allocated. 1867 * that was just allocated.
1868 */ 1868 */
1869 fbno = xfs_dir2_db_to_fdb(mp, dbno); 1869 fbno = xfs_dir2_db_to_fdb(mp, dbno);
1870 error = xfs_dir2_free_try_read(tp, dp, 1870 error = xfs_dir2_free_try_read(tp, dp,
1871 xfs_dir2_db_to_da(mp, fbno), 1871 xfs_dir2_db_to_da(mp, fbno),
1872 &fbp); 1872 &fbp);
1873 if (error) 1873 if (error)
1874 return error; 1874 return error;
1875 1875
1876 /* 1876 /*
1877 * If there wasn't a freespace block, the read will 1877 * If there wasn't a freespace block, the read will
1878 * return a NULL fbp. Allocate and initialize a new one. 1878 * return a NULL fbp. Allocate and initialize a new one.
1879 */ 1879 */
1880 if (!fbp) { 1880 if (!fbp) {
1881 error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, 1881 error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE,
1882 &fbno); 1882 &fbno);
1883 if (error) 1883 if (error)
1884 return error; 1884 return error;
1885 1885
1886 if (unlikely(xfs_dir2_db_to_fdb(mp, dbno) != fbno)) { 1886 if (unlikely(xfs_dir2_db_to_fdb(mp, dbno) != fbno)) {
1887 xfs_alert(mp, 1887 xfs_alert(mp,
1888 "%s: dir ino %llu needed freesp block %lld for\n" 1888 "%s: dir ino %llu needed freesp block %lld for\n"
1889 " data block %lld, got %lld ifbno %llu lastfbno %d", 1889 " data block %lld, got %lld ifbno %llu lastfbno %d",
1890 __func__, (unsigned long long)dp->i_ino, 1890 __func__, (unsigned long long)dp->i_ino,
1891 (long long)xfs_dir2_db_to_fdb(mp, dbno), 1891 (long long)xfs_dir2_db_to_fdb(mp, dbno),
1892 (long long)dbno, (long long)fbno, 1892 (long long)dbno, (long long)fbno,
1893 (unsigned long long)ifbno, lastfbno); 1893 (unsigned long long)ifbno, lastfbno);
1894 if (fblk) { 1894 if (fblk) {
1895 xfs_alert(mp, 1895 xfs_alert(mp,
1896 " fblk 0x%p blkno %llu index %d magic 0x%x", 1896 " fblk 0x%p blkno %llu index %d magic 0x%x",
1897 fblk, 1897 fblk,
1898 (unsigned long long)fblk->blkno, 1898 (unsigned long long)fblk->blkno,
1899 fblk->index, 1899 fblk->index,
1900 fblk->magic); 1900 fblk->magic);
1901 } else { 1901 } else {
1902 xfs_alert(mp, " ... fblk is NULL"); 1902 xfs_alert(mp, " ... fblk is NULL");
1903 } 1903 }
1904 XFS_ERROR_REPORT("xfs_dir2_node_addname_int", 1904 XFS_ERROR_REPORT("xfs_dir2_node_addname_int",
1905 XFS_ERRLEVEL_LOW, mp); 1905 XFS_ERRLEVEL_LOW, mp);
1906 return XFS_ERROR(EFSCORRUPTED); 1906 return XFS_ERROR(EFSCORRUPTED);
1907 } 1907 }
1908 1908
1909 /* 1909 /*
1910 * Get a buffer for the new block. 1910 * Get a buffer for the new block.
1911 */ 1911 */
1912 error = xfs_dir3_free_get_buf(tp, dp, fbno, &fbp); 1912 error = xfs_dir3_free_get_buf(tp, dp, fbno, &fbp);
1913 if (error) 1913 if (error)
1914 return error; 1914 return error;
1915 free = fbp->b_addr; 1915 free = fbp->b_addr;
1916 bests = xfs_dir3_free_bests_p(mp, free); 1916 bests = xfs_dir3_free_bests_p(mp, free);
1917 xfs_dir3_free_hdr_from_disk(&freehdr, free); 1917 xfs_dir3_free_hdr_from_disk(&freehdr, free);
1918 1918
1919 /* 1919 /*
1920 * Remember the first slot as our empty slot. 1920 * Remember the first slot as our empty slot.
1921 */ 1921 */
1922 freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * 1922 freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) *
1923 xfs_dir3_free_max_bests(mp); 1923 xfs_dir3_free_max_bests(mp);
1924 free->hdr.nvalid = 0; 1924 free->hdr.nvalid = 0;
1925 free->hdr.nused = 0; 1925 free->hdr.nused = 0;
1926 } else { 1926 } else {
1927 free = fbp->b_addr; 1927 free = fbp->b_addr;
1928 bests = xfs_dir3_free_bests_p(mp, free); 1928 bests = xfs_dir3_free_bests_p(mp, free);
1929 xfs_dir3_free_hdr_from_disk(&freehdr, free); 1929 xfs_dir3_free_hdr_from_disk(&freehdr, free);
1930 } 1930 }
1931 1931
1932 /* 1932 /*
1933 * Set the freespace block index from the data block number. 1933 * Set the freespace block index from the data block number.
1934 */ 1934 */
1935 findex = xfs_dir2_db_to_fdindex(mp, dbno); 1935 findex = xfs_dir2_db_to_fdindex(mp, dbno);
1936 /* 1936 /*
1937 * If it's after the end of the current entries in the 1937 * If it's after the end of the current entries in the
1938 * freespace block, extend that table. 1938 * freespace block, extend that table.
1939 */ 1939 */
1940 if (findex >= freehdr.nvalid) { 1940 if (findex >= freehdr.nvalid) {
1941 ASSERT(findex < xfs_dir3_free_max_bests(mp)); 1941 ASSERT(findex < xfs_dir3_free_max_bests(mp));
1942 freehdr.nvalid = findex + 1; 1942 freehdr.nvalid = findex + 1;
1943 /* 1943 /*
1944 * Tag new entry so nused will go up. 1944 * Tag new entry so nused will go up.
1945 */ 1945 */
1946 bests[findex] = cpu_to_be16(NULLDATAOFF); 1946 bests[findex] = cpu_to_be16(NULLDATAOFF);
1947 } 1947 }
1948 /* 1948 /*
1949 * If this entry was for an empty data block 1949 * If this entry was for an empty data block
1950 * (this should always be true) then update the header. 1950 * (this should always be true) then update the header.
1951 */ 1951 */
1952 if (bests[findex] == cpu_to_be16(NULLDATAOFF)) { 1952 if (bests[findex] == cpu_to_be16(NULLDATAOFF)) {
1953 freehdr.nused++; 1953 freehdr.nused++;
1954 xfs_dir3_free_hdr_to_disk(fbp->b_addr, &freehdr); 1954 xfs_dir3_free_hdr_to_disk(fbp->b_addr, &freehdr);
1955 xfs_dir2_free_log_header(tp, fbp); 1955 xfs_dir2_free_log_header(tp, fbp);
1956 } 1956 }
1957 /* 1957 /*
1958 * Update the real value in the table. 1958 * Update the real value in the table.
1959 * We haven't allocated the data entry yet so this will 1959 * We haven't allocated the data entry yet so this will
1960 * change again. 1960 * change again.
1961 */ 1961 */
1962 hdr = dbp->b_addr; 1962 hdr = dbp->b_addr;
1963 bf = xfs_dir3_data_bestfree_p(hdr); 1963 bf = xfs_dir3_data_bestfree_p(hdr);
1964 bests[findex] = bf[0].length; 1964 bests[findex] = bf[0].length;
1965 logfree = 1; 1965 logfree = 1;
1966 } 1966 }
1967 /* 1967 /*
1968 * We had a data block so we don't have to make a new one. 1968 * We had a data block so we don't have to make a new one.
1969 */ 1969 */
1970 else { 1970 else {
1971 /* 1971 /*
1972 * If just checking, we succeeded. 1972 * If just checking, we succeeded.
1973 */ 1973 */
1974 if (args->op_flags & XFS_DA_OP_JUSTCHECK) 1974 if (args->op_flags & XFS_DA_OP_JUSTCHECK)
1975 return 0; 1975 return 0;
1976 1976
1977 /* 1977 /*
1978 * Read the data block in. 1978 * Read the data block in.
1979 */ 1979 */
1980 error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno), 1980 error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno),
1981 -1, &dbp); 1981 -1, &dbp);
1982 if (error) 1982 if (error)
1983 return error; 1983 return error;
1984 hdr = dbp->b_addr; 1984 hdr = dbp->b_addr;
1985 bf = xfs_dir3_data_bestfree_p(hdr); 1985 bf = xfs_dir3_data_bestfree_p(hdr);
1986 logfree = 0; 1986 logfree = 0;
1987 } 1987 }
1988 ASSERT(be16_to_cpu(bf[0].length) >= length); 1988 ASSERT(be16_to_cpu(bf[0].length) >= length);
1989 /* 1989 /*
1990 * Point to the existing unused space. 1990 * Point to the existing unused space.
1991 */ 1991 */
1992 dup = (xfs_dir2_data_unused_t *) 1992 dup = (xfs_dir2_data_unused_t *)
1993 ((char *)hdr + be16_to_cpu(bf[0].offset)); 1993 ((char *)hdr + be16_to_cpu(bf[0].offset));
1994 needscan = needlog = 0; 1994 needscan = needlog = 0;
1995 /* 1995 /*
1996 * Mark the first part of the unused space, inuse for us. 1996 * Mark the first part of the unused space, inuse for us.
1997 */ 1997 */
1998 xfs_dir2_data_use_free(tp, dbp, dup, 1998 xfs_dir2_data_use_free(tp, dbp, dup,
1999 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length, 1999 (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
2000 &needlog, &needscan); 2000 &needlog, &needscan);
2001 /* 2001 /*
2002 * Fill in the new entry and log it. 2002 * Fill in the new entry and log it.
2003 */ 2003 */
2004 dep = (xfs_dir2_data_entry_t *)dup; 2004 dep = (xfs_dir2_data_entry_t *)dup;
2005 dep->inumber = cpu_to_be64(args->inumber); 2005 dep->inumber = cpu_to_be64(args->inumber);
2006 dep->namelen = args->namelen; 2006 dep->namelen = args->namelen;
2007 memcpy(dep->name, args->name, dep->namelen); 2007 memcpy(dep->name, args->name, dep->namelen);
2008 tagp = xfs_dir2_data_entry_tag_p(dep); 2008 tagp = xfs_dir2_data_entry_tag_p(dep);
2009 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 2009 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
2010 xfs_dir2_data_log_entry(tp, dbp, dep); 2010 xfs_dir2_data_log_entry(tp, dbp, dep);
2011 /* 2011 /*
2012 * Rescan the block for bestfree if needed. 2012 * Rescan the block for bestfree if needed.
2013 */ 2013 */
2014 if (needscan) 2014 if (needscan)
2015 xfs_dir2_data_freescan(mp, hdr, &needlog); 2015 xfs_dir2_data_freescan(mp, hdr, &needlog);
2016 /* 2016 /*
2017 * Log the data block header if needed. 2017 * Log the data block header if needed.
2018 */ 2018 */
2019 if (needlog) 2019 if (needlog)
2020 xfs_dir2_data_log_header(tp, dbp); 2020 xfs_dir2_data_log_header(tp, dbp);
2021 /* 2021 /*
2022 * If the freespace entry is now wrong, update it. 2022 * If the freespace entry is now wrong, update it.
2023 */ 2023 */
2024 bests = xfs_dir3_free_bests_p(mp, free); /* gcc is so stupid */ 2024 bests = xfs_dir3_free_bests_p(mp, free); /* gcc is so stupid */
2025 if (be16_to_cpu(bests[findex]) != be16_to_cpu(bf[0].length)) { 2025 if (be16_to_cpu(bests[findex]) != be16_to_cpu(bf[0].length)) {
2026 bests[findex] = bf[0].length; 2026 bests[findex] = bf[0].length;
2027 logfree = 1; 2027 logfree = 1;
2028 } 2028 }
2029 /* 2029 /*
2030 * Log the freespace entry if needed. 2030 * Log the freespace entry if needed.
2031 */ 2031 */
2032 if (logfree) 2032 if (logfree)
2033 xfs_dir2_free_log_bests(tp, fbp, findex, findex); 2033 xfs_dir2_free_log_bests(tp, fbp, findex, findex);
2034 /* 2034 /*
2035 * Return the data block and offset in args, then drop the data block. 2035 * Return the data block and offset in args, then drop the data block.
2036 */ 2036 */
2037 args->blkno = (xfs_dablk_t)dbno; 2037 args->blkno = (xfs_dablk_t)dbno;
2038 args->index = be16_to_cpu(*tagp); 2038 args->index = be16_to_cpu(*tagp);
2039 return 0; 2039 return 0;
2040 } 2040 }
2041 2041
2042 /* 2042 /*
2043 * Lookup an entry in a node-format directory. 2043 * Lookup an entry in a node-format directory.
2044 * All the real work happens in xfs_da3_node_lookup_int. 2044 * All the real work happens in xfs_da3_node_lookup_int.
2045 * The only real output is the inode number of the entry. 2045 * The only real output is the inode number of the entry.
2046 */ 2046 */
2047 int /* error */ 2047 int /* error */
2048 xfs_dir2_node_lookup( 2048 xfs_dir2_node_lookup(
2049 xfs_da_args_t *args) /* operation arguments */ 2049 xfs_da_args_t *args) /* operation arguments */
2050 { 2050 {
2051 int error; /* error return value */ 2051 int error; /* error return value */
2052 int i; /* btree level */ 2052 int i; /* btree level */
2053 int rval; /* operation return value */ 2053 int rval; /* operation return value */
2054 xfs_da_state_t *state; /* btree cursor */ 2054 xfs_da_state_t *state; /* btree cursor */
2055 2055
2056 trace_xfs_dir2_node_lookup(args); 2056 trace_xfs_dir2_node_lookup(args);
2057 2057
2058 /* 2058 /*
2059 * Allocate and initialize the btree cursor. 2059 * Allocate and initialize the btree cursor.
2060 */ 2060 */
2061 state = xfs_da_state_alloc(); 2061 state = xfs_da_state_alloc();
2062 state->args = args; 2062 state->args = args;
2063 state->mp = args->dp->i_mount; 2063 state->mp = args->dp->i_mount;
2064 state->blocksize = state->mp->m_dirblksize; 2064 state->blocksize = state->mp->m_dirblksize;
2065 state->node_ents = state->mp->m_dir_node_ents; 2065 state->node_ents = state->mp->m_dir_node_ents;
2066 /* 2066 /*
2067 * Fill in the path to the entry in the cursor. 2067 * Fill in the path to the entry in the cursor.
2068 */ 2068 */
2069 error = xfs_da3_node_lookup_int(state, &rval); 2069 error = xfs_da3_node_lookup_int(state, &rval);
2070 if (error) 2070 if (error)
2071 rval = error; 2071 rval = error;
2072 else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) { 2072 else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) {
2073 /* If a CI match, dup the actual name and return EEXIST */ 2073 /* If a CI match, dup the actual name and return EEXIST */
2074 xfs_dir2_data_entry_t *dep; 2074 xfs_dir2_data_entry_t *dep;
2075 2075
2076 dep = (xfs_dir2_data_entry_t *) 2076 dep = (xfs_dir2_data_entry_t *)
2077 ((char *)state->extrablk.bp->b_addr + 2077 ((char *)state->extrablk.bp->b_addr +
2078 state->extrablk.index); 2078 state->extrablk.index);
2079 rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen); 2079 rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
2080 } 2080 }
2081 /* 2081 /*
2082 * Release the btree blocks and leaf block. 2082 * Release the btree blocks and leaf block.
2083 */ 2083 */
2084 for (i = 0; i < state->path.active; i++) { 2084 for (i = 0; i < state->path.active; i++) {
2085 xfs_trans_brelse(args->trans, state->path.blk[i].bp); 2085 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
2086 state->path.blk[i].bp = NULL; 2086 state->path.blk[i].bp = NULL;
2087 } 2087 }
2088 /* 2088 /*
2089 * Release the data block if we have it. 2089 * Release the data block if we have it.
2090 */ 2090 */
2091 if (state->extravalid && state->extrablk.bp) { 2091 if (state->extravalid && state->extrablk.bp) {
2092 xfs_trans_brelse(args->trans, state->extrablk.bp); 2092 xfs_trans_brelse(args->trans, state->extrablk.bp);
2093 state->extrablk.bp = NULL; 2093 state->extrablk.bp = NULL;
2094 } 2094 }
2095 xfs_da_state_free(state); 2095 xfs_da_state_free(state);
2096 return rval; 2096 return rval;
2097 } 2097 }
2098 2098
2099 /* 2099 /*
2100 * Remove an entry from a node-format directory. 2100 * Remove an entry from a node-format directory.
2101 */ 2101 */
2102 int /* error */ 2102 int /* error */
2103 xfs_dir2_node_removename( 2103 xfs_dir2_node_removename(
2104 xfs_da_args_t *args) /* operation arguments */ 2104 xfs_da_args_t *args) /* operation arguments */
2105 { 2105 {
2106 xfs_da_state_blk_t *blk; /* leaf block */ 2106 xfs_da_state_blk_t *blk; /* leaf block */
2107 int error; /* error return value */ 2107 int error; /* error return value */
2108 int rval; /* operation return value */ 2108 int rval; /* operation return value */
2109 xfs_da_state_t *state; /* btree cursor */ 2109 xfs_da_state_t *state; /* btree cursor */
2110 2110
2111 trace_xfs_dir2_node_removename(args); 2111 trace_xfs_dir2_node_removename(args);
2112 2112
2113 /* 2113 /*
2114 * Allocate and initialize the btree cursor. 2114 * Allocate and initialize the btree cursor.
2115 */ 2115 */
2116 state = xfs_da_state_alloc(); 2116 state = xfs_da_state_alloc();
2117 state->args = args; 2117 state->args = args;
2118 state->mp = args->dp->i_mount; 2118 state->mp = args->dp->i_mount;
2119 state->blocksize = state->mp->m_dirblksize; 2119 state->blocksize = state->mp->m_dirblksize;
2120 state->node_ents = state->mp->m_dir_node_ents; 2120 state->node_ents = state->mp->m_dir_node_ents;
2121 /* 2121 /*
2122 * Look up the entry we're deleting, set up the cursor. 2122 * Look up the entry we're deleting, set up the cursor.
2123 */ 2123 */
2124 error = xfs_da3_node_lookup_int(state, &rval); 2124 error = xfs_da3_node_lookup_int(state, &rval);
2125 if (error) 2125 if (error)
2126 rval = error; 2126 rval = error;
2127 /* 2127 /*
2128 * Didn't find it, upper layer screwed up. 2128 * Didn't find it, upper layer screwed up.
2129 */ 2129 */
2130 if (rval != EEXIST) { 2130 if (rval != EEXIST) {
2131 xfs_da_state_free(state); 2131 xfs_da_state_free(state);
2132 return rval; 2132 return rval;
2133 } 2133 }
2134 blk = &state->path.blk[state->path.active - 1]; 2134 blk = &state->path.blk[state->path.active - 1];
2135 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); 2135 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
2136 ASSERT(state->extravalid); 2136 ASSERT(state->extravalid);
2137 /* 2137 /*
2138 * Remove the leaf and data entries. 2138 * Remove the leaf and data entries.
2139 * Extrablk refers to the data block. 2139 * Extrablk refers to the data block.
2140 */ 2140 */
2141 error = xfs_dir2_leafn_remove(args, blk->bp, blk->index, 2141 error = xfs_dir2_leafn_remove(args, blk->bp, blk->index,
2142 &state->extrablk, &rval); 2142 &state->extrablk, &rval);
2143 if (error) 2143 if (error)
2144 return error; 2144 return error;
2145 /* 2145 /*
2146 * Fix the hash values up the btree. 2146 * Fix the hash values up the btree.
2147 */ 2147 */
2148 xfs_da3_fixhashpath(state, &state->path); 2148 xfs_da3_fixhashpath(state, &state->path);
2149 /* 2149 /*
2150 * If we need to join leaf blocks, do it. 2150 * If we need to join leaf blocks, do it.
2151 */ 2151 */
2152 if (rval && state->path.active > 1) 2152 if (rval && state->path.active > 1)
2153 error = xfs_da3_join(state); 2153 error = xfs_da3_join(state);
2154 /* 2154 /*
2155 * If no errors so far, try conversion to leaf format. 2155 * If no errors so far, try conversion to leaf format.
2156 */ 2156 */
2157 if (!error) 2157 if (!error)
2158 error = xfs_dir2_node_to_leaf(state); 2158 error = xfs_dir2_node_to_leaf(state);
2159 xfs_da_state_free(state); 2159 xfs_da_state_free(state);
2160 return error; 2160 return error;
2161 } 2161 }
2162 2162
2163 /* 2163 /*
2164 * Replace an entry's inode number in a node-format directory. 2164 * Replace an entry's inode number in a node-format directory.
2165 */ 2165 */
2166 int /* error */ 2166 int /* error */
2167 xfs_dir2_node_replace( 2167 xfs_dir2_node_replace(
2168 xfs_da_args_t *args) /* operation arguments */ 2168 xfs_da_args_t *args) /* operation arguments */
2169 { 2169 {
2170 xfs_da_state_blk_t *blk; /* leaf block */ 2170 xfs_da_state_blk_t *blk; /* leaf block */
2171 xfs_dir2_data_hdr_t *hdr; /* data block header */ 2171 xfs_dir2_data_hdr_t *hdr; /* data block header */
2172 xfs_dir2_data_entry_t *dep; /* data entry changed */ 2172 xfs_dir2_data_entry_t *dep; /* data entry changed */
2173 int error; /* error return value */ 2173 int error; /* error return value */
2174 int i; /* btree level */ 2174 int i; /* btree level */
2175 xfs_ino_t inum; /* new inode number */ 2175 xfs_ino_t inum; /* new inode number */
2176 xfs_dir2_leaf_t *leaf; /* leaf structure */ 2176 xfs_dir2_leaf_t *leaf; /* leaf structure */
2177 xfs_dir2_leaf_entry_t *lep; /* leaf entry being changed */ 2177 xfs_dir2_leaf_entry_t *lep; /* leaf entry being changed */
2178 int rval; /* internal return value */ 2178 int rval; /* internal return value */
2179 xfs_da_state_t *state; /* btree cursor */ 2179 xfs_da_state_t *state; /* btree cursor */
2180 2180
2181 trace_xfs_dir2_node_replace(args); 2181 trace_xfs_dir2_node_replace(args);
2182 2182
2183 /* 2183 /*
2184 * Allocate and initialize the btree cursor. 2184 * Allocate and initialize the btree cursor.
2185 */ 2185 */
2186 state = xfs_da_state_alloc(); 2186 state = xfs_da_state_alloc();
2187 state->args = args; 2187 state->args = args;
2188 state->mp = args->dp->i_mount; 2188 state->mp = args->dp->i_mount;
2189 state->blocksize = state->mp->m_dirblksize; 2189 state->blocksize = state->mp->m_dirblksize;
2190 state->node_ents = state->mp->m_dir_node_ents; 2190 state->node_ents = state->mp->m_dir_node_ents;
2191 inum = args->inumber; 2191 inum = args->inumber;
2192 /* 2192 /*
2193 * Lookup the entry to change in the btree. 2193 * Lookup the entry to change in the btree.
2194 */ 2194 */
2195 error = xfs_da3_node_lookup_int(state, &rval); 2195 error = xfs_da3_node_lookup_int(state, &rval);
2196 if (error) { 2196 if (error) {
2197 rval = error; 2197 rval = error;
2198 } 2198 }
2199 /* 2199 /*
2200 * It should be found, since the vnodeops layer has looked it up 2200 * It should be found, since the vnodeops layer has looked it up
2201 * and locked it. But paranoia is good. 2201 * and locked it. But paranoia is good.
2202 */ 2202 */
2203 if (rval == EEXIST) { 2203 if (rval == EEXIST) {
2204 struct xfs_dir2_leaf_entry *ents; 2204 struct xfs_dir2_leaf_entry *ents;
2205 /* 2205 /*
2206 * Find the leaf entry. 2206 * Find the leaf entry.
2207 */ 2207 */
2208 blk = &state->path.blk[state->path.active - 1]; 2208 blk = &state->path.blk[state->path.active - 1];
2209 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); 2209 ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
2210 leaf = blk->bp->b_addr; 2210 leaf = blk->bp->b_addr;
2211 ents = xfs_dir3_leaf_ents_p(leaf); 2211 ents = xfs_dir3_leaf_ents_p(leaf);
2212 lep = &ents[blk->index]; 2212 lep = &ents[blk->index];
2213 ASSERT(state->extravalid); 2213 ASSERT(state->extravalid);
2214 /* 2214 /*
2215 * Point to the data entry. 2215 * Point to the data entry.
2216 */ 2216 */
2217 hdr = state->extrablk.bp->b_addr; 2217 hdr = state->extrablk.bp->b_addr;
2218 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 2218 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
2219 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); 2219 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
2220 dep = (xfs_dir2_data_entry_t *) 2220 dep = (xfs_dir2_data_entry_t *)
2221 ((char *)hdr + 2221 ((char *)hdr +
2222 xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); 2222 xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address)));
2223 ASSERT(inum != be64_to_cpu(dep->inumber)); 2223 ASSERT(inum != be64_to_cpu(dep->inumber));
2224 /* 2224 /*
2225 * Fill in the new inode number and log the entry. 2225 * Fill in the new inode number and log the entry.
2226 */ 2226 */
2227 dep->inumber = cpu_to_be64(inum); 2227 dep->inumber = cpu_to_be64(inum);
2228 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); 2228 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
2229 rval = 0; 2229 rval = 0;
2230 } 2230 }
2231 /* 2231 /*
2232 * Didn't find it, and we're holding a data block. Drop it. 2232 * Didn't find it, and we're holding a data block. Drop it.
2233 */ 2233 */
2234 else if (state->extravalid) { 2234 else if (state->extravalid) {
2235 xfs_trans_brelse(args->trans, state->extrablk.bp); 2235 xfs_trans_brelse(args->trans, state->extrablk.bp);
2236 state->extrablk.bp = NULL; 2236 state->extrablk.bp = NULL;
2237 } 2237 }
2238 /* 2238 /*
2239 * Release all the buffers in the cursor. 2239 * Release all the buffers in the cursor.
2240 */ 2240 */
2241 for (i = 0; i < state->path.active; i++) { 2241 for (i = 0; i < state->path.active; i++) {
2242 xfs_trans_brelse(args->trans, state->path.blk[i].bp); 2242 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
2243 state->path.blk[i].bp = NULL; 2243 state->path.blk[i].bp = NULL;
2244 } 2244 }
2245 xfs_da_state_free(state); 2245 xfs_da_state_free(state);
2246 return rval; 2246 return rval;
2247 } 2247 }
2248 2248
2249 /* 2249 /*
2250 * Trim off a trailing empty freespace block. 2250 * Trim off a trailing empty freespace block.
2251 * Return (in rvalp) 1 if we did it, 0 if not. 2251 * Return (in rvalp) 1 if we did it, 0 if not.
2252 */ 2252 */
2253 int /* error */ 2253 int /* error */
2254 xfs_dir2_node_trim_free( 2254 xfs_dir2_node_trim_free(
2255 xfs_da_args_t *args, /* operation arguments */ 2255 xfs_da_args_t *args, /* operation arguments */
2256 xfs_fileoff_t fo, /* free block number */ 2256 xfs_fileoff_t fo, /* free block number */
2257 int *rvalp) /* out: did something */ 2257 int *rvalp) /* out: did something */
2258 { 2258 {
2259 struct xfs_buf *bp; /* freespace buffer */ 2259 struct xfs_buf *bp; /* freespace buffer */
2260 xfs_inode_t *dp; /* incore directory inode */ 2260 xfs_inode_t *dp; /* incore directory inode */
2261 int error; /* error return code */ 2261 int error; /* error return code */
2262 xfs_dir2_free_t *free; /* freespace structure */ 2262 xfs_dir2_free_t *free; /* freespace structure */
2263 xfs_mount_t *mp; /* filesystem mount point */ 2263 xfs_mount_t *mp; /* filesystem mount point */
2264 xfs_trans_t *tp; /* transaction pointer */ 2264 xfs_trans_t *tp; /* transaction pointer */
2265 struct xfs_dir3_icfree_hdr freehdr; 2265 struct xfs_dir3_icfree_hdr freehdr;
2266 2266
2267 dp = args->dp; 2267 dp = args->dp;
2268 mp = dp->i_mount; 2268 mp = dp->i_mount;
2269 tp = args->trans; 2269 tp = args->trans;
2270 /* 2270 /*
2271 * Read the freespace block. 2271 * Read the freespace block.
2272 */ 2272 */
2273 error = xfs_dir2_free_try_read(tp, dp, fo, &bp); 2273 error = xfs_dir2_free_try_read(tp, dp, fo, &bp);
2274 if (error) 2274 if (error)
2275 return error; 2275 return error;
2276 /* 2276 /*
2277 * There can be holes in freespace. If fo is a hole, there's 2277 * There can be holes in freespace. If fo is a hole, there's
2278 * nothing to do. 2278 * nothing to do.
2279 */ 2279 */
2280 if (!bp) 2280 if (!bp)
2281 return 0; 2281 return 0;
2282 free = bp->b_addr; 2282 free = bp->b_addr;
2283 xfs_dir3_free_hdr_from_disk(&freehdr, free); 2283 xfs_dir3_free_hdr_from_disk(&freehdr, free);
2284 2284
2285 /* 2285 /*
2286 * If there are used entries, there's nothing to do. 2286 * If there are used entries, there's nothing to do.
2287 */ 2287 */
2288 if (freehdr.nused > 0) { 2288 if (freehdr.nused > 0) {
2289 xfs_trans_brelse(tp, bp); 2289 xfs_trans_brelse(tp, bp);
2290 *rvalp = 0; 2290 *rvalp = 0;
2291 return 0; 2291 return 0;
2292 } 2292 }
2293 /* 2293 /*
2294 * Blow the block away. 2294 * Blow the block away.
2295 */ 2295 */
2296 if ((error = 2296 if ((error =
2297 xfs_dir2_shrink_inode(args, xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo), 2297 xfs_dir2_shrink_inode(args, xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo),
2298 bp))) { 2298 bp))) {
2299 /* 2299 /*
2300 * Can't fail with ENOSPC since that only happens with no 2300 * Can't fail with ENOSPC since that only happens with no
2301 * space reservation, when breaking up an extent into two 2301 * space reservation, when breaking up an extent into two
2302 * pieces. This is the last block of an extent. 2302 * pieces. This is the last block of an extent.
2303 */ 2303 */
2304 ASSERT(error != ENOSPC); 2304 ASSERT(error != ENOSPC);
2305 xfs_trans_brelse(tp, bp); 2305 xfs_trans_brelse(tp, bp);
2306 return error; 2306 return error;
2307 } 2307 }
2308 /* 2308 /*
2309 * Return that we succeeded. 2309 * Return that we succeeded.
2310 */ 2310 */
2311 *rvalp = 1; 2311 *rvalp = 1;
2312 return 0; 2312 return 0;
2313 } 2313 }
2314 2314
fs/xfs/xfs_ialloc_btree.c
1 /* 1 /*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2001,2005 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
6 * modify it under the terms of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
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 */ 17 */
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_bit.h" 21 #include "xfs_bit.h"
22 #include "xfs_log.h" 22 #include "xfs_log.h"
23 #include "xfs_trans.h" 23 #include "xfs_trans.h"
24 #include "xfs_sb.h" 24 #include "xfs_sb.h"
25 #include "xfs_ag.h" 25 #include "xfs_ag.h"
26 #include "xfs_mount.h" 26 #include "xfs_mount.h"
27 #include "xfs_bmap_btree.h" 27 #include "xfs_bmap_btree.h"
28 #include "xfs_alloc_btree.h" 28 #include "xfs_alloc_btree.h"
29 #include "xfs_ialloc_btree.h" 29 #include "xfs_ialloc_btree.h"
30 #include "xfs_dinode.h" 30 #include "xfs_dinode.h"
31 #include "xfs_inode.h" 31 #include "xfs_inode.h"
32 #include "xfs_btree.h" 32 #include "xfs_btree.h"
33 #include "xfs_ialloc.h" 33 #include "xfs_ialloc.h"
34 #include "xfs_alloc.h" 34 #include "xfs_alloc.h"
35 #include "xfs_error.h" 35 #include "xfs_error.h"
36 #include "xfs_trace.h" 36 #include "xfs_trace.h"
37 #include "xfs_cksum.h" 37 #include "xfs_cksum.h"
38 38
39 39
40 STATIC int 40 STATIC int
41 xfs_inobt_get_minrecs( 41 xfs_inobt_get_minrecs(
42 struct xfs_btree_cur *cur, 42 struct xfs_btree_cur *cur,
43 int level) 43 int level)
44 { 44 {
45 return cur->bc_mp->m_inobt_mnr[level != 0]; 45 return cur->bc_mp->m_inobt_mnr[level != 0];
46 } 46 }
47 47
48 STATIC struct xfs_btree_cur * 48 STATIC struct xfs_btree_cur *
49 xfs_inobt_dup_cursor( 49 xfs_inobt_dup_cursor(
50 struct xfs_btree_cur *cur) 50 struct xfs_btree_cur *cur)
51 { 51 {
52 return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, 52 return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp,
53 cur->bc_private.a.agbp, cur->bc_private.a.agno); 53 cur->bc_private.a.agbp, cur->bc_private.a.agno);
54 } 54 }
55 55
56 STATIC void 56 STATIC void
57 xfs_inobt_set_root( 57 xfs_inobt_set_root(
58 struct xfs_btree_cur *cur, 58 struct xfs_btree_cur *cur,
59 union xfs_btree_ptr *nptr, 59 union xfs_btree_ptr *nptr,
60 int inc) /* level change */ 60 int inc) /* level change */
61 { 61 {
62 struct xfs_buf *agbp = cur->bc_private.a.agbp; 62 struct xfs_buf *agbp = cur->bc_private.a.agbp;
63 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); 63 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
64 64
65 agi->agi_root = nptr->s; 65 agi->agi_root = nptr->s;
66 be32_add_cpu(&agi->agi_level, inc); 66 be32_add_cpu(&agi->agi_level, inc);
67 xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL); 67 xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL);
68 } 68 }
69 69
70 STATIC int 70 STATIC int
71 xfs_inobt_alloc_block( 71 xfs_inobt_alloc_block(
72 struct xfs_btree_cur *cur, 72 struct xfs_btree_cur *cur,
73 union xfs_btree_ptr *start, 73 union xfs_btree_ptr *start,
74 union xfs_btree_ptr *new, 74 union xfs_btree_ptr *new,
75 int length, 75 int length,
76 int *stat) 76 int *stat)
77 { 77 {
78 xfs_alloc_arg_t args; /* block allocation args */ 78 xfs_alloc_arg_t args; /* block allocation args */
79 int error; /* error return value */ 79 int error; /* error return value */
80 xfs_agblock_t sbno = be32_to_cpu(start->s); 80 xfs_agblock_t sbno = be32_to_cpu(start->s);
81 81
82 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); 82 XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
83 83
84 memset(&args, 0, sizeof(args)); 84 memset(&args, 0, sizeof(args));
85 args.tp = cur->bc_tp; 85 args.tp = cur->bc_tp;
86 args.mp = cur->bc_mp; 86 args.mp = cur->bc_mp;
87 args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno); 87 args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno);
88 args.minlen = 1; 88 args.minlen = 1;
89 args.maxlen = 1; 89 args.maxlen = 1;
90 args.prod = 1; 90 args.prod = 1;
91 args.type = XFS_ALLOCTYPE_NEAR_BNO; 91 args.type = XFS_ALLOCTYPE_NEAR_BNO;
92 92
93 error = xfs_alloc_vextent(&args); 93 error = xfs_alloc_vextent(&args);
94 if (error) { 94 if (error) {
95 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); 95 XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
96 return error; 96 return error;
97 } 97 }
98 if (args.fsbno == NULLFSBLOCK) { 98 if (args.fsbno == NULLFSBLOCK) {
99 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 99 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
100 *stat = 0; 100 *stat = 0;
101 return 0; 101 return 0;
102 } 102 }
103 ASSERT(args.len == 1); 103 ASSERT(args.len == 1);
104 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); 104 XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT);
105 105
106 new->s = cpu_to_be32(XFS_FSB_TO_AGBNO(args.mp, args.fsbno)); 106 new->s = cpu_to_be32(XFS_FSB_TO_AGBNO(args.mp, args.fsbno));
107 *stat = 1; 107 *stat = 1;
108 return 0; 108 return 0;
109 } 109 }
110 110
111 STATIC int 111 STATIC int
112 xfs_inobt_free_block( 112 xfs_inobt_free_block(
113 struct xfs_btree_cur *cur, 113 struct xfs_btree_cur *cur,
114 struct xfs_buf *bp) 114 struct xfs_buf *bp)
115 { 115 {
116 xfs_fsblock_t fsbno; 116 xfs_fsblock_t fsbno;
117 int error; 117 int error;
118 118
119 fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)); 119 fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp));
120 error = xfs_free_extent(cur->bc_tp, fsbno, 1); 120 error = xfs_free_extent(cur->bc_tp, fsbno, 1);
121 if (error) 121 if (error)
122 return error; 122 return error;
123 123
124 xfs_trans_binval(cur->bc_tp, bp); 124 xfs_trans_binval(cur->bc_tp, bp);
125 return error; 125 return error;
126 } 126 }
127 127
128 STATIC int 128 STATIC int
129 xfs_inobt_get_maxrecs( 129 xfs_inobt_get_maxrecs(
130 struct xfs_btree_cur *cur, 130 struct xfs_btree_cur *cur,
131 int level) 131 int level)
132 { 132 {
133 return cur->bc_mp->m_inobt_mxr[level != 0]; 133 return cur->bc_mp->m_inobt_mxr[level != 0];
134 } 134 }
135 135
136 STATIC void 136 STATIC void
137 xfs_inobt_init_key_from_rec( 137 xfs_inobt_init_key_from_rec(
138 union xfs_btree_key *key, 138 union xfs_btree_key *key,
139 union xfs_btree_rec *rec) 139 union xfs_btree_rec *rec)
140 { 140 {
141 key->inobt.ir_startino = rec->inobt.ir_startino; 141 key->inobt.ir_startino = rec->inobt.ir_startino;
142 } 142 }
143 143
144 STATIC void 144 STATIC void
145 xfs_inobt_init_rec_from_key( 145 xfs_inobt_init_rec_from_key(
146 union xfs_btree_key *key, 146 union xfs_btree_key *key,
147 union xfs_btree_rec *rec) 147 union xfs_btree_rec *rec)
148 { 148 {
149 rec->inobt.ir_startino = key->inobt.ir_startino; 149 rec->inobt.ir_startino = key->inobt.ir_startino;
150 } 150 }
151 151
152 STATIC void 152 STATIC void
153 xfs_inobt_init_rec_from_cur( 153 xfs_inobt_init_rec_from_cur(
154 struct xfs_btree_cur *cur, 154 struct xfs_btree_cur *cur,
155 union xfs_btree_rec *rec) 155 union xfs_btree_rec *rec)
156 { 156 {
157 rec->inobt.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino); 157 rec->inobt.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);
158 rec->inobt.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount); 158 rec->inobt.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount);
159 rec->inobt.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free); 159 rec->inobt.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free);
160 } 160 }
161 161
162 /* 162 /*
163 * initial value of ptr for lookup 163 * initial value of ptr for lookup
164 */ 164 */
165 STATIC void 165 STATIC void
166 xfs_inobt_init_ptr_from_cur( 166 xfs_inobt_init_ptr_from_cur(
167 struct xfs_btree_cur *cur, 167 struct xfs_btree_cur *cur,
168 union xfs_btree_ptr *ptr) 168 union xfs_btree_ptr *ptr)
169 { 169 {
170 struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); 170 struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp);
171 171
172 ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno)); 172 ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno));
173 173
174 ptr->s = agi->agi_root; 174 ptr->s = agi->agi_root;
175 } 175 }
176 176
177 STATIC __int64_t 177 STATIC __int64_t
178 xfs_inobt_key_diff( 178 xfs_inobt_key_diff(
179 struct xfs_btree_cur *cur, 179 struct xfs_btree_cur *cur,
180 union xfs_btree_key *key) 180 union xfs_btree_key *key)
181 { 181 {
182 return (__int64_t)be32_to_cpu(key->inobt.ir_startino) - 182 return (__int64_t)be32_to_cpu(key->inobt.ir_startino) -
183 cur->bc_rec.i.ir_startino; 183 cur->bc_rec.i.ir_startino;
184 } 184 }
185 185
186 static int 186 static int
187 xfs_inobt_verify( 187 xfs_inobt_verify(
188 struct xfs_buf *bp) 188 struct xfs_buf *bp)
189 { 189 {
190 struct xfs_mount *mp = bp->b_target->bt_mount; 190 struct xfs_mount *mp = bp->b_target->bt_mount;
191 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); 191 struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
192 struct xfs_perag *pag = bp->b_pag; 192 struct xfs_perag *pag = bp->b_pag;
193 unsigned int level; 193 unsigned int level;
194 194
195 /* 195 /*
196 * During growfs operations, we can't verify the exact owner as the 196 * During growfs operations, we can't verify the exact owner as the
197 * perag is not fully initialised and hence not attached to the buffer. 197 * perag is not fully initialised and hence not attached to the buffer.
198 * 198 *
199 * Similarly, during log recovery we will have a perag structure 199 * Similarly, during log recovery we will have a perag structure
200 * attached, but the agi information will not yet have been initialised 200 * attached, but the agi information will not yet have been initialised
201 * from the on disk AGI. We don't currently use any of this information, 201 * from the on disk AGI. We don't currently use any of this information,
202 * but beware of the landmine (i.e. need to check pag->pagi_init) if we 202 * but beware of the landmine (i.e. need to check pag->pagi_init) if we
203 * ever do. 203 * ever do.
204 */ 204 */
205 switch (block->bb_magic) { 205 switch (block->bb_magic) {
206 case cpu_to_be32(XFS_IBT_CRC_MAGIC): 206 case cpu_to_be32(XFS_IBT_CRC_MAGIC):
207 if (!xfs_sb_version_hascrc(&mp->m_sb)) 207 if (!xfs_sb_version_hascrc(&mp->m_sb))
208 return false; 208 return false;
209 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) 209 if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid))
210 return false; 210 return false;
211 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) 211 if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))
212 return false; 212 return false;
213 if (pag && 213 if (pag &&
214 be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) 214 be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno)
215 return false; 215 return false;
216 /* fall through */ 216 /* fall through */
217 case cpu_to_be32(XFS_IBT_MAGIC): 217 case cpu_to_be32(XFS_IBT_MAGIC):
218 break; 218 break;
219 default: 219 default:
220 return 0; 220 return 0;
221 } 221 }
222 222
223 /* numrecs and level verification */ 223 /* numrecs and level verification */
224 level = be16_to_cpu(block->bb_level); 224 level = be16_to_cpu(block->bb_level);
225 if (level >= mp->m_in_maxlevels) 225 if (level >= mp->m_in_maxlevels)
226 return false; 226 return false;
227 if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[level != 0]) 227 if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[level != 0])
228 return false; 228 return false;
229 229
230 /* sibling pointer verification */ 230 /* sibling pointer verification */
231 if (!block->bb_u.s.bb_leftsib || 231 if (!block->bb_u.s.bb_leftsib ||
232 (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && 232 (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks &&
233 block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) 233 block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK)))
234 return false; 234 return false;
235 if (!block->bb_u.s.bb_rightsib || 235 if (!block->bb_u.s.bb_rightsib ||
236 (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && 236 (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks &&
237 block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) 237 block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK)))
238 return false; 238 return false;
239 239
240 return true; 240 return true;
241 } 241 }
242 242
243 static void 243 static void
244 xfs_inobt_read_verify( 244 xfs_inobt_read_verify(
245 struct xfs_buf *bp) 245 struct xfs_buf *bp)
246 { 246 {
247 if (!(xfs_btree_sblock_verify_crc(bp) && 247 if (!(xfs_btree_sblock_verify_crc(bp) &&
248 xfs_inobt_verify(bp))) { 248 xfs_inobt_verify(bp))) {
249 trace_xfs_btree_corrupt(bp, _RET_IP_); 249 trace_xfs_btree_corrupt(bp, _RET_IP_);
250 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, 250 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
251 bp->b_target->bt_mount, bp->b_addr); 251 bp->b_target->bt_mount, bp->b_addr);
252 xfs_buf_ioerror(bp, EFSCORRUPTED); 252 xfs_buf_ioerror(bp, EFSCORRUPTED);
253 } 253 }
254 } 254 }
255 255
256 static void 256 static void
257 xfs_inobt_write_verify( 257 xfs_inobt_write_verify(
258 struct xfs_buf *bp) 258 struct xfs_buf *bp)
259 { 259 {
260 if (!xfs_inobt_verify(bp)) { 260 if (!xfs_inobt_verify(bp)) {
261 trace_xfs_btree_corrupt(bp, _RET_IP_); 261 trace_xfs_btree_corrupt(bp, _RET_IP_);
262 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, 262 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
263 bp->b_target->bt_mount, bp->b_addr); 263 bp->b_target->bt_mount, bp->b_addr);
264 xfs_buf_ioerror(bp, EFSCORRUPTED); 264 xfs_buf_ioerror(bp, EFSCORRUPTED);
265 } 265 }
266 xfs_btree_sblock_calc_crc(bp); 266 xfs_btree_sblock_calc_crc(bp);
267 267
268 } 268 }
269 269
270 const struct xfs_buf_ops xfs_inobt_buf_ops = { 270 const struct xfs_buf_ops xfs_inobt_buf_ops = {
271 .verify_read = xfs_inobt_read_verify, 271 .verify_read = xfs_inobt_read_verify,
272 .verify_write = xfs_inobt_write_verify, 272 .verify_write = xfs_inobt_write_verify,
273 }; 273 };
274 274
275 #ifdef DEBUG 275 #if defined(DEBUG) || defined(XFS_WARN)
276 STATIC int 276 STATIC int
277 xfs_inobt_keys_inorder( 277 xfs_inobt_keys_inorder(
278 struct xfs_btree_cur *cur, 278 struct xfs_btree_cur *cur,
279 union xfs_btree_key *k1, 279 union xfs_btree_key *k1,
280 union xfs_btree_key *k2) 280 union xfs_btree_key *k2)
281 { 281 {
282 return be32_to_cpu(k1->inobt.ir_startino) < 282 return be32_to_cpu(k1->inobt.ir_startino) <
283 be32_to_cpu(k2->inobt.ir_startino); 283 be32_to_cpu(k2->inobt.ir_startino);
284 } 284 }
285 285
286 STATIC int 286 STATIC int
287 xfs_inobt_recs_inorder( 287 xfs_inobt_recs_inorder(
288 struct xfs_btree_cur *cur, 288 struct xfs_btree_cur *cur,
289 union xfs_btree_rec *r1, 289 union xfs_btree_rec *r1,
290 union xfs_btree_rec *r2) 290 union xfs_btree_rec *r2)
291 { 291 {
292 return be32_to_cpu(r1->inobt.ir_startino) + XFS_INODES_PER_CHUNK <= 292 return be32_to_cpu(r1->inobt.ir_startino) + XFS_INODES_PER_CHUNK <=
293 be32_to_cpu(r2->inobt.ir_startino); 293 be32_to_cpu(r2->inobt.ir_startino);
294 } 294 }
295 #endif /* DEBUG */ 295 #endif /* DEBUG */
296 296
297 static const struct xfs_btree_ops xfs_inobt_ops = { 297 static const struct xfs_btree_ops xfs_inobt_ops = {
298 .rec_len = sizeof(xfs_inobt_rec_t), 298 .rec_len = sizeof(xfs_inobt_rec_t),
299 .key_len = sizeof(xfs_inobt_key_t), 299 .key_len = sizeof(xfs_inobt_key_t),
300 300
301 .dup_cursor = xfs_inobt_dup_cursor, 301 .dup_cursor = xfs_inobt_dup_cursor,
302 .set_root = xfs_inobt_set_root, 302 .set_root = xfs_inobt_set_root,
303 .alloc_block = xfs_inobt_alloc_block, 303 .alloc_block = xfs_inobt_alloc_block,
304 .free_block = xfs_inobt_free_block, 304 .free_block = xfs_inobt_free_block,
305 .get_minrecs = xfs_inobt_get_minrecs, 305 .get_minrecs = xfs_inobt_get_minrecs,
306 .get_maxrecs = xfs_inobt_get_maxrecs, 306 .get_maxrecs = xfs_inobt_get_maxrecs,
307 .init_key_from_rec = xfs_inobt_init_key_from_rec, 307 .init_key_from_rec = xfs_inobt_init_key_from_rec,
308 .init_rec_from_key = xfs_inobt_init_rec_from_key, 308 .init_rec_from_key = xfs_inobt_init_rec_from_key,
309 .init_rec_from_cur = xfs_inobt_init_rec_from_cur, 309 .init_rec_from_cur = xfs_inobt_init_rec_from_cur,
310 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, 310 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur,
311 .key_diff = xfs_inobt_key_diff, 311 .key_diff = xfs_inobt_key_diff,
312 .buf_ops = &xfs_inobt_buf_ops, 312 .buf_ops = &xfs_inobt_buf_ops,
313 #ifdef DEBUG 313 #if defined(DEBUG) || defined(XFS_WARN)
314 .keys_inorder = xfs_inobt_keys_inorder, 314 .keys_inorder = xfs_inobt_keys_inorder,
315 .recs_inorder = xfs_inobt_recs_inorder, 315 .recs_inorder = xfs_inobt_recs_inorder,
316 #endif 316 #endif
317 }; 317 };
318 318
319 /* 319 /*
320 * Allocate a new inode btree cursor. 320 * Allocate a new inode btree cursor.
321 */ 321 */
322 struct xfs_btree_cur * /* new inode btree cursor */ 322 struct xfs_btree_cur * /* new inode btree cursor */
323 xfs_inobt_init_cursor( 323 xfs_inobt_init_cursor(
324 struct xfs_mount *mp, /* file system mount point */ 324 struct xfs_mount *mp, /* file system mount point */
325 struct xfs_trans *tp, /* transaction pointer */ 325 struct xfs_trans *tp, /* transaction pointer */
326 struct xfs_buf *agbp, /* buffer for agi structure */ 326 struct xfs_buf *agbp, /* buffer for agi structure */
327 xfs_agnumber_t agno) /* allocation group number */ 327 xfs_agnumber_t agno) /* allocation group number */
328 { 328 {
329 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); 329 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
330 struct xfs_btree_cur *cur; 330 struct xfs_btree_cur *cur;
331 331
332 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); 332 cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP);
333 333
334 cur->bc_tp = tp; 334 cur->bc_tp = tp;
335 cur->bc_mp = mp; 335 cur->bc_mp = mp;
336 cur->bc_nlevels = be32_to_cpu(agi->agi_level); 336 cur->bc_nlevels = be32_to_cpu(agi->agi_level);
337 cur->bc_btnum = XFS_BTNUM_INO; 337 cur->bc_btnum = XFS_BTNUM_INO;
338 cur->bc_blocklog = mp->m_sb.sb_blocklog; 338 cur->bc_blocklog = mp->m_sb.sb_blocklog;
339 339
340 cur->bc_ops = &xfs_inobt_ops; 340 cur->bc_ops = &xfs_inobt_ops;
341 if (xfs_sb_version_hascrc(&mp->m_sb)) 341 if (xfs_sb_version_hascrc(&mp->m_sb))
342 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; 342 cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
343 343
344 cur->bc_private.a.agbp = agbp; 344 cur->bc_private.a.agbp = agbp;
345 cur->bc_private.a.agno = agno; 345 cur->bc_private.a.agno = agno;
346 346
347 return cur; 347 return cur;
348 } 348 }
349 349
350 /* 350 /*
351 * Calculate number of records in an inobt btree block. 351 * Calculate number of records in an inobt btree block.
352 */ 352 */
353 int 353 int
354 xfs_inobt_maxrecs( 354 xfs_inobt_maxrecs(
355 struct xfs_mount *mp, 355 struct xfs_mount *mp,
356 int blocklen, 356 int blocklen,
357 int leaf) 357 int leaf)
358 { 358 {
359 blocklen -= XFS_INOBT_BLOCK_LEN(mp); 359 blocklen -= XFS_INOBT_BLOCK_LEN(mp);
360 360
361 if (leaf) 361 if (leaf)
362 return blocklen / sizeof(xfs_inobt_rec_t); 362 return blocklen / sizeof(xfs_inobt_rec_t);
363 return blocklen / (sizeof(xfs_inobt_key_t) + sizeof(xfs_inobt_ptr_t)); 363 return blocklen / (sizeof(xfs_inobt_key_t) + sizeof(xfs_inobt_ptr_t));
364 } 364 }
365 365
1 /* 1 /*
2 * Copyright (c) 2000-2006 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
6 * modify it under the terms of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
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 */ 17 */
18 #include <linux/log2.h> 18 #include <linux/log2.h>
19 19
20 #include "xfs.h" 20 #include "xfs.h"
21 #include "xfs_fs.h" 21 #include "xfs_fs.h"
22 #include "xfs_types.h" 22 #include "xfs_types.h"
23 #include "xfs_log.h" 23 #include "xfs_log.h"
24 #include "xfs_inum.h" 24 #include "xfs_inum.h"
25 #include "xfs_trans.h" 25 #include "xfs_trans.h"
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_mount.h" 29 #include "xfs_mount.h"
30 #include "xfs_bmap_btree.h" 30 #include "xfs_bmap_btree.h"
31 #include "xfs_alloc_btree.h" 31 #include "xfs_alloc_btree.h"
32 #include "xfs_ialloc_btree.h" 32 #include "xfs_ialloc_btree.h"
33 #include "xfs_attr_sf.h" 33 #include "xfs_attr_sf.h"
34 #include "xfs_dinode.h" 34 #include "xfs_dinode.h"
35 #include "xfs_inode.h" 35 #include "xfs_inode.h"
36 #include "xfs_buf_item.h" 36 #include "xfs_buf_item.h"
37 #include "xfs_inode_item.h" 37 #include "xfs_inode_item.h"
38 #include "xfs_btree.h" 38 #include "xfs_btree.h"
39 #include "xfs_alloc.h" 39 #include "xfs_alloc.h"
40 #include "xfs_ialloc.h" 40 #include "xfs_ialloc.h"
41 #include "xfs_bmap.h" 41 #include "xfs_bmap.h"
42 #include "xfs_error.h" 42 #include "xfs_error.h"
43 #include "xfs_utils.h" 43 #include "xfs_utils.h"
44 #include "xfs_quota.h" 44 #include "xfs_quota.h"
45 #include "xfs_filestream.h" 45 #include "xfs_filestream.h"
46 #include "xfs_vnodeops.h" 46 #include "xfs_vnodeops.h"
47 #include "xfs_cksum.h" 47 #include "xfs_cksum.h"
48 #include "xfs_trace.h" 48 #include "xfs_trace.h"
49 #include "xfs_icache.h" 49 #include "xfs_icache.h"
50 50
51 kmem_zone_t *xfs_ifork_zone; 51 kmem_zone_t *xfs_ifork_zone;
52 kmem_zone_t *xfs_inode_zone; 52 kmem_zone_t *xfs_inode_zone;
53 53
54 /* 54 /*
55 * Used in xfs_itruncate_extents(). This is the maximum number of extents 55 * Used in xfs_itruncate_extents(). This is the maximum number of extents
56 * freed from a file in a single transaction. 56 * freed from a file in a single transaction.
57 */ 57 */
58 #define XFS_ITRUNC_MAX_EXTENTS 2 58 #define XFS_ITRUNC_MAX_EXTENTS 2
59 59
60 STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *); 60 STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *);
61 STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int); 61 STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int);
62 STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); 62 STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
63 STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); 63 STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
64 64
65 /* 65 /*
66 * helper function to extract extent size hint from inode 66 * helper function to extract extent size hint from inode
67 */ 67 */
68 xfs_extlen_t 68 xfs_extlen_t
69 xfs_get_extsz_hint( 69 xfs_get_extsz_hint(
70 struct xfs_inode *ip) 70 struct xfs_inode *ip)
71 { 71 {
72 if ((ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) && ip->i_d.di_extsize) 72 if ((ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) && ip->i_d.di_extsize)
73 return ip->i_d.di_extsize; 73 return ip->i_d.di_extsize;
74 if (XFS_IS_REALTIME_INODE(ip)) 74 if (XFS_IS_REALTIME_INODE(ip))
75 return ip->i_mount->m_sb.sb_rextsize; 75 return ip->i_mount->m_sb.sb_rextsize;
76 return 0; 76 return 0;
77 } 77 }
78 78
79 /* 79 /*
80 * This is a wrapper routine around the xfs_ilock() routine used to centralize 80 * This is a wrapper routine around the xfs_ilock() routine used to centralize
81 * some grungy code. It is used in places that wish to lock the inode solely 81 * some grungy code. It is used in places that wish to lock the inode solely
82 * for reading the extents. The reason these places can't just call 82 * for reading the extents. The reason these places can't just call
83 * xfs_ilock(SHARED) is that the inode lock also guards to bringing in of the 83 * xfs_ilock(SHARED) is that the inode lock also guards to bringing in of the
84 * extents from disk for a file in b-tree format. If the inode is in b-tree 84 * extents from disk for a file in b-tree format. If the inode is in b-tree
85 * format, then we need to lock the inode exclusively until the extents are read 85 * format, then we need to lock the inode exclusively until the extents are read
86 * in. Locking it exclusively all the time would limit our parallelism 86 * in. Locking it exclusively all the time would limit our parallelism
87 * unnecessarily, though. What we do instead is check to see if the extents 87 * unnecessarily, though. What we do instead is check to see if the extents
88 * have been read in yet, and only lock the inode exclusively if they have not. 88 * have been read in yet, and only lock the inode exclusively if they have not.
89 * 89 *
90 * The function returns a value which should be given to the corresponding 90 * The function returns a value which should be given to the corresponding
91 * xfs_iunlock_map_shared(). This value is the mode in which the lock was 91 * xfs_iunlock_map_shared(). This value is the mode in which the lock was
92 * actually taken. 92 * actually taken.
93 */ 93 */
94 uint 94 uint
95 xfs_ilock_map_shared( 95 xfs_ilock_map_shared(
96 xfs_inode_t *ip) 96 xfs_inode_t *ip)
97 { 97 {
98 uint lock_mode; 98 uint lock_mode;
99 99
100 if ((ip->i_d.di_format == XFS_DINODE_FMT_BTREE) && 100 if ((ip->i_d.di_format == XFS_DINODE_FMT_BTREE) &&
101 ((ip->i_df.if_flags & XFS_IFEXTENTS) == 0)) { 101 ((ip->i_df.if_flags & XFS_IFEXTENTS) == 0)) {
102 lock_mode = XFS_ILOCK_EXCL; 102 lock_mode = XFS_ILOCK_EXCL;
103 } else { 103 } else {
104 lock_mode = XFS_ILOCK_SHARED; 104 lock_mode = XFS_ILOCK_SHARED;
105 } 105 }
106 106
107 xfs_ilock(ip, lock_mode); 107 xfs_ilock(ip, lock_mode);
108 108
109 return lock_mode; 109 return lock_mode;
110 } 110 }
111 111
112 /* 112 /*
113 * This is simply the unlock routine to go with xfs_ilock_map_shared(). 113 * This is simply the unlock routine to go with xfs_ilock_map_shared().
114 * All it does is call xfs_iunlock() with the given lock_mode. 114 * All it does is call xfs_iunlock() with the given lock_mode.
115 */ 115 */
116 void 116 void
117 xfs_iunlock_map_shared( 117 xfs_iunlock_map_shared(
118 xfs_inode_t *ip, 118 xfs_inode_t *ip,
119 unsigned int lock_mode) 119 unsigned int lock_mode)
120 { 120 {
121 xfs_iunlock(ip, lock_mode); 121 xfs_iunlock(ip, lock_mode);
122 } 122 }
123 123
124 /* 124 /*
125 * The xfs inode contains 2 locks: a multi-reader lock called the 125 * The xfs inode contains 2 locks: a multi-reader lock called the
126 * i_iolock and a multi-reader lock called the i_lock. This routine 126 * i_iolock and a multi-reader lock called the i_lock. This routine
127 * allows either or both of the locks to be obtained. 127 * allows either or both of the locks to be obtained.
128 * 128 *
129 * The 2 locks should always be ordered so that the IO lock is 129 * The 2 locks should always be ordered so that the IO lock is
130 * obtained first in order to prevent deadlock. 130 * obtained first in order to prevent deadlock.
131 * 131 *
132 * ip -- the inode being locked 132 * ip -- the inode being locked
133 * lock_flags -- this parameter indicates the inode's locks 133 * lock_flags -- this parameter indicates the inode's locks
134 * to be locked. It can be: 134 * to be locked. It can be:
135 * XFS_IOLOCK_SHARED, 135 * XFS_IOLOCK_SHARED,
136 * XFS_IOLOCK_EXCL, 136 * XFS_IOLOCK_EXCL,
137 * XFS_ILOCK_SHARED, 137 * XFS_ILOCK_SHARED,
138 * XFS_ILOCK_EXCL, 138 * XFS_ILOCK_EXCL,
139 * XFS_IOLOCK_SHARED | XFS_ILOCK_SHARED, 139 * XFS_IOLOCK_SHARED | XFS_ILOCK_SHARED,
140 * XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL, 140 * XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL,
141 * XFS_IOLOCK_EXCL | XFS_ILOCK_SHARED, 141 * XFS_IOLOCK_EXCL | XFS_ILOCK_SHARED,
142 * XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL 142 * XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL
143 */ 143 */
144 void 144 void
145 xfs_ilock( 145 xfs_ilock(
146 xfs_inode_t *ip, 146 xfs_inode_t *ip,
147 uint lock_flags) 147 uint lock_flags)
148 { 148 {
149 trace_xfs_ilock(ip, lock_flags, _RET_IP_); 149 trace_xfs_ilock(ip, lock_flags, _RET_IP_);
150 150
151 /* 151 /*
152 * You can't set both SHARED and EXCL for the same lock, 152 * You can't set both SHARED and EXCL for the same lock,
153 * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED, 153 * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
154 * and XFS_ILOCK_EXCL are valid values to set in lock_flags. 154 * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
155 */ 155 */
156 ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) != 156 ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
157 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); 157 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
158 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != 158 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
159 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); 159 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
160 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0); 160 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
161 161
162 if (lock_flags & XFS_IOLOCK_EXCL) 162 if (lock_flags & XFS_IOLOCK_EXCL)
163 mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags)); 163 mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
164 else if (lock_flags & XFS_IOLOCK_SHARED) 164 else if (lock_flags & XFS_IOLOCK_SHARED)
165 mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags)); 165 mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
166 166
167 if (lock_flags & XFS_ILOCK_EXCL) 167 if (lock_flags & XFS_ILOCK_EXCL)
168 mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags)); 168 mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
169 else if (lock_flags & XFS_ILOCK_SHARED) 169 else if (lock_flags & XFS_ILOCK_SHARED)
170 mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags)); 170 mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
171 } 171 }
172 172
173 /* 173 /*
174 * This is just like xfs_ilock(), except that the caller 174 * This is just like xfs_ilock(), except that the caller
175 * is guaranteed not to sleep. It returns 1 if it gets 175 * is guaranteed not to sleep. It returns 1 if it gets
176 * the requested locks and 0 otherwise. If the IO lock is 176 * the requested locks and 0 otherwise. If the IO lock is
177 * obtained but the inode lock cannot be, then the IO lock 177 * obtained but the inode lock cannot be, then the IO lock
178 * is dropped before returning. 178 * is dropped before returning.
179 * 179 *
180 * ip -- the inode being locked 180 * ip -- the inode being locked
181 * lock_flags -- this parameter indicates the inode's locks to be 181 * lock_flags -- this parameter indicates the inode's locks to be
182 * to be locked. See the comment for xfs_ilock() for a list 182 * to be locked. See the comment for xfs_ilock() for a list
183 * of valid values. 183 * of valid values.
184 */ 184 */
185 int 185 int
186 xfs_ilock_nowait( 186 xfs_ilock_nowait(
187 xfs_inode_t *ip, 187 xfs_inode_t *ip,
188 uint lock_flags) 188 uint lock_flags)
189 { 189 {
190 trace_xfs_ilock_nowait(ip, lock_flags, _RET_IP_); 190 trace_xfs_ilock_nowait(ip, lock_flags, _RET_IP_);
191 191
192 /* 192 /*
193 * You can't set both SHARED and EXCL for the same lock, 193 * You can't set both SHARED and EXCL for the same lock,
194 * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED, 194 * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
195 * and XFS_ILOCK_EXCL are valid values to set in lock_flags. 195 * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
196 */ 196 */
197 ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) != 197 ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
198 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); 198 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
199 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != 199 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
200 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); 200 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
201 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0); 201 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
202 202
203 if (lock_flags & XFS_IOLOCK_EXCL) { 203 if (lock_flags & XFS_IOLOCK_EXCL) {
204 if (!mrtryupdate(&ip->i_iolock)) 204 if (!mrtryupdate(&ip->i_iolock))
205 goto out; 205 goto out;
206 } else if (lock_flags & XFS_IOLOCK_SHARED) { 206 } else if (lock_flags & XFS_IOLOCK_SHARED) {
207 if (!mrtryaccess(&ip->i_iolock)) 207 if (!mrtryaccess(&ip->i_iolock))
208 goto out; 208 goto out;
209 } 209 }
210 if (lock_flags & XFS_ILOCK_EXCL) { 210 if (lock_flags & XFS_ILOCK_EXCL) {
211 if (!mrtryupdate(&ip->i_lock)) 211 if (!mrtryupdate(&ip->i_lock))
212 goto out_undo_iolock; 212 goto out_undo_iolock;
213 } else if (lock_flags & XFS_ILOCK_SHARED) { 213 } else if (lock_flags & XFS_ILOCK_SHARED) {
214 if (!mrtryaccess(&ip->i_lock)) 214 if (!mrtryaccess(&ip->i_lock))
215 goto out_undo_iolock; 215 goto out_undo_iolock;
216 } 216 }
217 return 1; 217 return 1;
218 218
219 out_undo_iolock: 219 out_undo_iolock:
220 if (lock_flags & XFS_IOLOCK_EXCL) 220 if (lock_flags & XFS_IOLOCK_EXCL)
221 mrunlock_excl(&ip->i_iolock); 221 mrunlock_excl(&ip->i_iolock);
222 else if (lock_flags & XFS_IOLOCK_SHARED) 222 else if (lock_flags & XFS_IOLOCK_SHARED)
223 mrunlock_shared(&ip->i_iolock); 223 mrunlock_shared(&ip->i_iolock);
224 out: 224 out:
225 return 0; 225 return 0;
226 } 226 }
227 227
228 /* 228 /*
229 * xfs_iunlock() is used to drop the inode locks acquired with 229 * xfs_iunlock() is used to drop the inode locks acquired with
230 * xfs_ilock() and xfs_ilock_nowait(). The caller must pass 230 * xfs_ilock() and xfs_ilock_nowait(). The caller must pass
231 * in the flags given to xfs_ilock() or xfs_ilock_nowait() so 231 * in the flags given to xfs_ilock() or xfs_ilock_nowait() so
232 * that we know which locks to drop. 232 * that we know which locks to drop.
233 * 233 *
234 * ip -- the inode being unlocked 234 * ip -- the inode being unlocked
235 * lock_flags -- this parameter indicates the inode's locks to be 235 * lock_flags -- this parameter indicates the inode's locks to be
236 * to be unlocked. See the comment for xfs_ilock() for a list 236 * to be unlocked. See the comment for xfs_ilock() for a list
237 * of valid values for this parameter. 237 * of valid values for this parameter.
238 * 238 *
239 */ 239 */
240 void 240 void
241 xfs_iunlock( 241 xfs_iunlock(
242 xfs_inode_t *ip, 242 xfs_inode_t *ip,
243 uint lock_flags) 243 uint lock_flags)
244 { 244 {
245 /* 245 /*
246 * You can't set both SHARED and EXCL for the same lock, 246 * You can't set both SHARED and EXCL for the same lock,
247 * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED, 247 * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED,
248 * and XFS_ILOCK_EXCL are valid values to set in lock_flags. 248 * and XFS_ILOCK_EXCL are valid values to set in lock_flags.
249 */ 249 */
250 ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) != 250 ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) !=
251 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); 251 (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
252 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != 252 ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
253 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); 253 (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
254 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0); 254 ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
255 ASSERT(lock_flags != 0); 255 ASSERT(lock_flags != 0);
256 256
257 if (lock_flags & XFS_IOLOCK_EXCL) 257 if (lock_flags & XFS_IOLOCK_EXCL)
258 mrunlock_excl(&ip->i_iolock); 258 mrunlock_excl(&ip->i_iolock);
259 else if (lock_flags & XFS_IOLOCK_SHARED) 259 else if (lock_flags & XFS_IOLOCK_SHARED)
260 mrunlock_shared(&ip->i_iolock); 260 mrunlock_shared(&ip->i_iolock);
261 261
262 if (lock_flags & XFS_ILOCK_EXCL) 262 if (lock_flags & XFS_ILOCK_EXCL)
263 mrunlock_excl(&ip->i_lock); 263 mrunlock_excl(&ip->i_lock);
264 else if (lock_flags & XFS_ILOCK_SHARED) 264 else if (lock_flags & XFS_ILOCK_SHARED)
265 mrunlock_shared(&ip->i_lock); 265 mrunlock_shared(&ip->i_lock);
266 266
267 trace_xfs_iunlock(ip, lock_flags, _RET_IP_); 267 trace_xfs_iunlock(ip, lock_flags, _RET_IP_);
268 } 268 }
269 269
270 /* 270 /*
271 * give up write locks. the i/o lock cannot be held nested 271 * give up write locks. the i/o lock cannot be held nested
272 * if it is being demoted. 272 * if it is being demoted.
273 */ 273 */
274 void 274 void
275 xfs_ilock_demote( 275 xfs_ilock_demote(
276 xfs_inode_t *ip, 276 xfs_inode_t *ip,
277 uint lock_flags) 277 uint lock_flags)
278 { 278 {
279 ASSERT(lock_flags & (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)); 279 ASSERT(lock_flags & (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL));
280 ASSERT((lock_flags & ~(XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)) == 0); 280 ASSERT((lock_flags & ~(XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)) == 0);
281 281
282 if (lock_flags & XFS_ILOCK_EXCL) 282 if (lock_flags & XFS_ILOCK_EXCL)
283 mrdemote(&ip->i_lock); 283 mrdemote(&ip->i_lock);
284 if (lock_flags & XFS_IOLOCK_EXCL) 284 if (lock_flags & XFS_IOLOCK_EXCL)
285 mrdemote(&ip->i_iolock); 285 mrdemote(&ip->i_iolock);
286 286
287 trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_); 287 trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_);
288 } 288 }
289 289
290 #ifdef DEBUG 290 #if defined(DEBUG) || defined(XFS_WARN)
291 int 291 int
292 xfs_isilocked( 292 xfs_isilocked(
293 xfs_inode_t *ip, 293 xfs_inode_t *ip,
294 uint lock_flags) 294 uint lock_flags)
295 { 295 {
296 if (lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) { 296 if (lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) {
297 if (!(lock_flags & XFS_ILOCK_SHARED)) 297 if (!(lock_flags & XFS_ILOCK_SHARED))
298 return !!ip->i_lock.mr_writer; 298 return !!ip->i_lock.mr_writer;
299 return rwsem_is_locked(&ip->i_lock.mr_lock); 299 return rwsem_is_locked(&ip->i_lock.mr_lock);
300 } 300 }
301 301
302 if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) { 302 if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) {
303 if (!(lock_flags & XFS_IOLOCK_SHARED)) 303 if (!(lock_flags & XFS_IOLOCK_SHARED))
304 return !!ip->i_iolock.mr_writer; 304 return !!ip->i_iolock.mr_writer;
305 return rwsem_is_locked(&ip->i_iolock.mr_lock); 305 return rwsem_is_locked(&ip->i_iolock.mr_lock);
306 } 306 }
307 307
308 ASSERT(0); 308 ASSERT(0);
309 return 0; 309 return 0;
310 } 310 }
311 #endif 311 #endif
312 312
313 void 313 void
314 __xfs_iflock( 314 __xfs_iflock(
315 struct xfs_inode *ip) 315 struct xfs_inode *ip)
316 { 316 {
317 wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IFLOCK_BIT); 317 wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IFLOCK_BIT);
318 DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IFLOCK_BIT); 318 DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IFLOCK_BIT);
319 319
320 do { 320 do {
321 prepare_to_wait_exclusive(wq, &wait.wait, TASK_UNINTERRUPTIBLE); 321 prepare_to_wait_exclusive(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
322 if (xfs_isiflocked(ip)) 322 if (xfs_isiflocked(ip))
323 io_schedule(); 323 io_schedule();
324 } while (!xfs_iflock_nowait(ip)); 324 } while (!xfs_iflock_nowait(ip));
325 325
326 finish_wait(wq, &wait.wait); 326 finish_wait(wq, &wait.wait);
327 } 327 }
328 328
329 #ifdef DEBUG 329 #ifdef DEBUG
330 /* 330 /*
331 * Make sure that the extents in the given memory buffer 331 * Make sure that the extents in the given memory buffer
332 * are valid. 332 * are valid.
333 */ 333 */
334 STATIC void 334 STATIC void
335 xfs_validate_extents( 335 xfs_validate_extents(
336 xfs_ifork_t *ifp, 336 xfs_ifork_t *ifp,
337 int nrecs, 337 int nrecs,
338 xfs_exntfmt_t fmt) 338 xfs_exntfmt_t fmt)
339 { 339 {
340 xfs_bmbt_irec_t irec; 340 xfs_bmbt_irec_t irec;
341 xfs_bmbt_rec_host_t rec; 341 xfs_bmbt_rec_host_t rec;
342 int i; 342 int i;
343 343
344 for (i = 0; i < nrecs; i++) { 344 for (i = 0; i < nrecs; i++) {
345 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); 345 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
346 rec.l0 = get_unaligned(&ep->l0); 346 rec.l0 = get_unaligned(&ep->l0);
347 rec.l1 = get_unaligned(&ep->l1); 347 rec.l1 = get_unaligned(&ep->l1);
348 xfs_bmbt_get_all(&rec, &irec); 348 xfs_bmbt_get_all(&rec, &irec);
349 if (fmt == XFS_EXTFMT_NOSTATE) 349 if (fmt == XFS_EXTFMT_NOSTATE)
350 ASSERT(irec.br_state == XFS_EXT_NORM); 350 ASSERT(irec.br_state == XFS_EXT_NORM);
351 } 351 }
352 } 352 }
353 #else /* DEBUG */ 353 #else /* DEBUG */
354 #define xfs_validate_extents(ifp, nrecs, fmt) 354 #define xfs_validate_extents(ifp, nrecs, fmt)
355 #endif /* DEBUG */ 355 #endif /* DEBUG */
356 356
357 /* 357 /*
358 * Check that none of the inode's in the buffer have a next 358 * Check that none of the inode's in the buffer have a next
359 * unlinked field of 0. 359 * unlinked field of 0.
360 */ 360 */
361 #if defined(DEBUG) 361 #if defined(DEBUG)
362 void 362 void
363 xfs_inobp_check( 363 xfs_inobp_check(
364 xfs_mount_t *mp, 364 xfs_mount_t *mp,
365 xfs_buf_t *bp) 365 xfs_buf_t *bp)
366 { 366 {
367 int i; 367 int i;
368 int j; 368 int j;
369 xfs_dinode_t *dip; 369 xfs_dinode_t *dip;
370 370
371 j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog; 371 j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog;
372 372
373 for (i = 0; i < j; i++) { 373 for (i = 0; i < j; i++) {
374 dip = (xfs_dinode_t *)xfs_buf_offset(bp, 374 dip = (xfs_dinode_t *)xfs_buf_offset(bp,
375 i * mp->m_sb.sb_inodesize); 375 i * mp->m_sb.sb_inodesize);
376 if (!dip->di_next_unlinked) { 376 if (!dip->di_next_unlinked) {
377 xfs_alert(mp, 377 xfs_alert(mp,
378 "Detected bogus zero next_unlinked field in incore inode buffer 0x%p.", 378 "Detected bogus zero next_unlinked field in incore inode buffer 0x%p.",
379 bp); 379 bp);
380 ASSERT(dip->di_next_unlinked); 380 ASSERT(dip->di_next_unlinked);
381 } 381 }
382 } 382 }
383 } 383 }
384 #endif 384 #endif
385 385
386 static void 386 static void
387 xfs_inode_buf_verify( 387 xfs_inode_buf_verify(
388 struct xfs_buf *bp) 388 struct xfs_buf *bp)
389 { 389 {
390 struct xfs_mount *mp = bp->b_target->bt_mount; 390 struct xfs_mount *mp = bp->b_target->bt_mount;
391 int i; 391 int i;
392 int ni; 392 int ni;
393 393
394 /* 394 /*
395 * Validate the magic number and version of every inode in the buffer 395 * Validate the magic number and version of every inode in the buffer
396 */ 396 */
397 ni = XFS_BB_TO_FSB(mp, bp->b_length) * mp->m_sb.sb_inopblock; 397 ni = XFS_BB_TO_FSB(mp, bp->b_length) * mp->m_sb.sb_inopblock;
398 for (i = 0; i < ni; i++) { 398 for (i = 0; i < ni; i++) {
399 int di_ok; 399 int di_ok;
400 xfs_dinode_t *dip; 400 xfs_dinode_t *dip;
401 401
402 dip = (struct xfs_dinode *)xfs_buf_offset(bp, 402 dip = (struct xfs_dinode *)xfs_buf_offset(bp,
403 (i << mp->m_sb.sb_inodelog)); 403 (i << mp->m_sb.sb_inodelog));
404 di_ok = dip->di_magic == cpu_to_be16(XFS_DINODE_MAGIC) && 404 di_ok = dip->di_magic == cpu_to_be16(XFS_DINODE_MAGIC) &&
405 XFS_DINODE_GOOD_VERSION(dip->di_version); 405 XFS_DINODE_GOOD_VERSION(dip->di_version);
406 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, 406 if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
407 XFS_ERRTAG_ITOBP_INOTOBP, 407 XFS_ERRTAG_ITOBP_INOTOBP,
408 XFS_RANDOM_ITOBP_INOTOBP))) { 408 XFS_RANDOM_ITOBP_INOTOBP))) {
409 xfs_buf_ioerror(bp, EFSCORRUPTED); 409 xfs_buf_ioerror(bp, EFSCORRUPTED);
410 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH, 410 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH,
411 mp, dip); 411 mp, dip);
412 #ifdef DEBUG 412 #ifdef DEBUG
413 xfs_emerg(mp, 413 xfs_emerg(mp,
414 "bad inode magic/vsn daddr %lld #%d (magic=%x)", 414 "bad inode magic/vsn daddr %lld #%d (magic=%x)",
415 (unsigned long long)bp->b_bn, i, 415 (unsigned long long)bp->b_bn, i,
416 be16_to_cpu(dip->di_magic)); 416 be16_to_cpu(dip->di_magic));
417 ASSERT(0); 417 ASSERT(0);
418 #endif 418 #endif
419 } 419 }
420 } 420 }
421 xfs_inobp_check(mp, bp); 421 xfs_inobp_check(mp, bp);
422 } 422 }
423 423
424 424
425 static void 425 static void
426 xfs_inode_buf_read_verify( 426 xfs_inode_buf_read_verify(
427 struct xfs_buf *bp) 427 struct xfs_buf *bp)
428 { 428 {
429 xfs_inode_buf_verify(bp); 429 xfs_inode_buf_verify(bp);
430 } 430 }
431 431
432 static void 432 static void
433 xfs_inode_buf_write_verify( 433 xfs_inode_buf_write_verify(
434 struct xfs_buf *bp) 434 struct xfs_buf *bp)
435 { 435 {
436 xfs_inode_buf_verify(bp); 436 xfs_inode_buf_verify(bp);
437 } 437 }
438 438
439 const struct xfs_buf_ops xfs_inode_buf_ops = { 439 const struct xfs_buf_ops xfs_inode_buf_ops = {
440 .verify_read = xfs_inode_buf_read_verify, 440 .verify_read = xfs_inode_buf_read_verify,
441 .verify_write = xfs_inode_buf_write_verify, 441 .verify_write = xfs_inode_buf_write_verify,
442 }; 442 };
443 443
444 444
445 /* 445 /*
446 * This routine is called to map an inode to the buffer containing the on-disk 446 * This routine is called to map an inode to the buffer containing the on-disk
447 * version of the inode. It returns a pointer to the buffer containing the 447 * version of the inode. It returns a pointer to the buffer containing the
448 * on-disk inode in the bpp parameter, and in the dipp parameter it returns a 448 * on-disk inode in the bpp parameter, and in the dipp parameter it returns a
449 * pointer to the on-disk inode within that buffer. 449 * pointer to the on-disk inode within that buffer.
450 * 450 *
451 * If a non-zero error is returned, then the contents of bpp and dipp are 451 * If a non-zero error is returned, then the contents of bpp and dipp are
452 * undefined. 452 * undefined.
453 */ 453 */
454 int 454 int
455 xfs_imap_to_bp( 455 xfs_imap_to_bp(
456 struct xfs_mount *mp, 456 struct xfs_mount *mp,
457 struct xfs_trans *tp, 457 struct xfs_trans *tp,
458 struct xfs_imap *imap, 458 struct xfs_imap *imap,
459 struct xfs_dinode **dipp, 459 struct xfs_dinode **dipp,
460 struct xfs_buf **bpp, 460 struct xfs_buf **bpp,
461 uint buf_flags, 461 uint buf_flags,
462 uint iget_flags) 462 uint iget_flags)
463 { 463 {
464 struct xfs_buf *bp; 464 struct xfs_buf *bp;
465 int error; 465 int error;
466 466
467 buf_flags |= XBF_UNMAPPED; 467 buf_flags |= XBF_UNMAPPED;
468 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, 468 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
469 (int)imap->im_len, buf_flags, &bp, 469 (int)imap->im_len, buf_flags, &bp,
470 &xfs_inode_buf_ops); 470 &xfs_inode_buf_ops);
471 if (error) { 471 if (error) {
472 if (error == EAGAIN) { 472 if (error == EAGAIN) {
473 ASSERT(buf_flags & XBF_TRYLOCK); 473 ASSERT(buf_flags & XBF_TRYLOCK);
474 return error; 474 return error;
475 } 475 }
476 476
477 if (error == EFSCORRUPTED && 477 if (error == EFSCORRUPTED &&
478 (iget_flags & XFS_IGET_UNTRUSTED)) 478 (iget_flags & XFS_IGET_UNTRUSTED))
479 return XFS_ERROR(EINVAL); 479 return XFS_ERROR(EINVAL);
480 480
481 xfs_warn(mp, "%s: xfs_trans_read_buf() returned error %d.", 481 xfs_warn(mp, "%s: xfs_trans_read_buf() returned error %d.",
482 __func__, error); 482 __func__, error);
483 return error; 483 return error;
484 } 484 }
485 485
486 *bpp = bp; 486 *bpp = bp;
487 *dipp = (struct xfs_dinode *)xfs_buf_offset(bp, imap->im_boffset); 487 *dipp = (struct xfs_dinode *)xfs_buf_offset(bp, imap->im_boffset);
488 return 0; 488 return 0;
489 } 489 }
490 490
491 /* 491 /*
492 * Move inode type and inode format specific information from the 492 * Move inode type and inode format specific information from the
493 * on-disk inode to the in-core inode. For fifos, devs, and sockets 493 * on-disk inode to the in-core inode. For fifos, devs, and sockets
494 * this means set if_rdev to the proper value. For files, directories, 494 * this means set if_rdev to the proper value. For files, directories,
495 * and symlinks this means to bring in the in-line data or extent 495 * and symlinks this means to bring in the in-line data or extent
496 * pointers. For a file in B-tree format, only the root is immediately 496 * pointers. For a file in B-tree format, only the root is immediately
497 * brought in-core. The rest will be in-lined in if_extents when it 497 * brought in-core. The rest will be in-lined in if_extents when it
498 * is first referenced (see xfs_iread_extents()). 498 * is first referenced (see xfs_iread_extents()).
499 */ 499 */
500 STATIC int 500 STATIC int
501 xfs_iformat( 501 xfs_iformat(
502 xfs_inode_t *ip, 502 xfs_inode_t *ip,
503 xfs_dinode_t *dip) 503 xfs_dinode_t *dip)
504 { 504 {
505 xfs_attr_shortform_t *atp; 505 xfs_attr_shortform_t *atp;
506 int size; 506 int size;
507 int error = 0; 507 int error = 0;
508 xfs_fsize_t di_size; 508 xfs_fsize_t di_size;
509 509
510 if (unlikely(be32_to_cpu(dip->di_nextents) + 510 if (unlikely(be32_to_cpu(dip->di_nextents) +
511 be16_to_cpu(dip->di_anextents) > 511 be16_to_cpu(dip->di_anextents) >
512 be64_to_cpu(dip->di_nblocks))) { 512 be64_to_cpu(dip->di_nblocks))) {
513 xfs_warn(ip->i_mount, 513 xfs_warn(ip->i_mount,
514 "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", 514 "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.",
515 (unsigned long long)ip->i_ino, 515 (unsigned long long)ip->i_ino,
516 (int)(be32_to_cpu(dip->di_nextents) + 516 (int)(be32_to_cpu(dip->di_nextents) +
517 be16_to_cpu(dip->di_anextents)), 517 be16_to_cpu(dip->di_anextents)),
518 (unsigned long long) 518 (unsigned long long)
519 be64_to_cpu(dip->di_nblocks)); 519 be64_to_cpu(dip->di_nblocks));
520 XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, 520 XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW,
521 ip->i_mount, dip); 521 ip->i_mount, dip);
522 return XFS_ERROR(EFSCORRUPTED); 522 return XFS_ERROR(EFSCORRUPTED);
523 } 523 }
524 524
525 if (unlikely(dip->di_forkoff > ip->i_mount->m_sb.sb_inodesize)) { 525 if (unlikely(dip->di_forkoff > ip->i_mount->m_sb.sb_inodesize)) {
526 xfs_warn(ip->i_mount, "corrupt dinode %Lu, forkoff = 0x%x.", 526 xfs_warn(ip->i_mount, "corrupt dinode %Lu, forkoff = 0x%x.",
527 (unsigned long long)ip->i_ino, 527 (unsigned long long)ip->i_ino,
528 dip->di_forkoff); 528 dip->di_forkoff);
529 XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, 529 XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW,
530 ip->i_mount, dip); 530 ip->i_mount, dip);
531 return XFS_ERROR(EFSCORRUPTED); 531 return XFS_ERROR(EFSCORRUPTED);
532 } 532 }
533 533
534 if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) && 534 if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) &&
535 !ip->i_mount->m_rtdev_targp)) { 535 !ip->i_mount->m_rtdev_targp)) {
536 xfs_warn(ip->i_mount, 536 xfs_warn(ip->i_mount,
537 "corrupt dinode %Lu, has realtime flag set.", 537 "corrupt dinode %Lu, has realtime flag set.",
538 ip->i_ino); 538 ip->i_ino);
539 XFS_CORRUPTION_ERROR("xfs_iformat(realtime)", 539 XFS_CORRUPTION_ERROR("xfs_iformat(realtime)",
540 XFS_ERRLEVEL_LOW, ip->i_mount, dip); 540 XFS_ERRLEVEL_LOW, ip->i_mount, dip);
541 return XFS_ERROR(EFSCORRUPTED); 541 return XFS_ERROR(EFSCORRUPTED);
542 } 542 }
543 543
544 switch (ip->i_d.di_mode & S_IFMT) { 544 switch (ip->i_d.di_mode & S_IFMT) {
545 case S_IFIFO: 545 case S_IFIFO:
546 case S_IFCHR: 546 case S_IFCHR:
547 case S_IFBLK: 547 case S_IFBLK:
548 case S_IFSOCK: 548 case S_IFSOCK:
549 if (unlikely(dip->di_format != XFS_DINODE_FMT_DEV)) { 549 if (unlikely(dip->di_format != XFS_DINODE_FMT_DEV)) {
550 XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, 550 XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW,
551 ip->i_mount, dip); 551 ip->i_mount, dip);
552 return XFS_ERROR(EFSCORRUPTED); 552 return XFS_ERROR(EFSCORRUPTED);
553 } 553 }
554 ip->i_d.di_size = 0; 554 ip->i_d.di_size = 0;
555 ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip); 555 ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip);
556 break; 556 break;
557 557
558 case S_IFREG: 558 case S_IFREG:
559 case S_IFLNK: 559 case S_IFLNK:
560 case S_IFDIR: 560 case S_IFDIR:
561 switch (dip->di_format) { 561 switch (dip->di_format) {
562 case XFS_DINODE_FMT_LOCAL: 562 case XFS_DINODE_FMT_LOCAL:
563 /* 563 /*
564 * no local regular files yet 564 * no local regular files yet
565 */ 565 */
566 if (unlikely(S_ISREG(be16_to_cpu(dip->di_mode)))) { 566 if (unlikely(S_ISREG(be16_to_cpu(dip->di_mode)))) {
567 xfs_warn(ip->i_mount, 567 xfs_warn(ip->i_mount,
568 "corrupt inode %Lu (local format for regular file).", 568 "corrupt inode %Lu (local format for regular file).",
569 (unsigned long long) ip->i_ino); 569 (unsigned long long) ip->i_ino);
570 XFS_CORRUPTION_ERROR("xfs_iformat(4)", 570 XFS_CORRUPTION_ERROR("xfs_iformat(4)",
571 XFS_ERRLEVEL_LOW, 571 XFS_ERRLEVEL_LOW,
572 ip->i_mount, dip); 572 ip->i_mount, dip);
573 return XFS_ERROR(EFSCORRUPTED); 573 return XFS_ERROR(EFSCORRUPTED);
574 } 574 }
575 575
576 di_size = be64_to_cpu(dip->di_size); 576 di_size = be64_to_cpu(dip->di_size);
577 if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { 577 if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) {
578 xfs_warn(ip->i_mount, 578 xfs_warn(ip->i_mount,
579 "corrupt inode %Lu (bad size %Ld for local inode).", 579 "corrupt inode %Lu (bad size %Ld for local inode).",
580 (unsigned long long) ip->i_ino, 580 (unsigned long long) ip->i_ino,
581 (long long) di_size); 581 (long long) di_size);
582 XFS_CORRUPTION_ERROR("xfs_iformat(5)", 582 XFS_CORRUPTION_ERROR("xfs_iformat(5)",
583 XFS_ERRLEVEL_LOW, 583 XFS_ERRLEVEL_LOW,
584 ip->i_mount, dip); 584 ip->i_mount, dip);
585 return XFS_ERROR(EFSCORRUPTED); 585 return XFS_ERROR(EFSCORRUPTED);
586 } 586 }
587 587
588 size = (int)di_size; 588 size = (int)di_size;
589 error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size); 589 error = xfs_iformat_local(ip, dip, XFS_DATA_FORK, size);
590 break; 590 break;
591 case XFS_DINODE_FMT_EXTENTS: 591 case XFS_DINODE_FMT_EXTENTS:
592 error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK); 592 error = xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
593 break; 593 break;
594 case XFS_DINODE_FMT_BTREE: 594 case XFS_DINODE_FMT_BTREE:
595 error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK); 595 error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
596 break; 596 break;
597 default: 597 default:
598 XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW, 598 XFS_ERROR_REPORT("xfs_iformat(6)", XFS_ERRLEVEL_LOW,
599 ip->i_mount); 599 ip->i_mount);
600 return XFS_ERROR(EFSCORRUPTED); 600 return XFS_ERROR(EFSCORRUPTED);
601 } 601 }
602 break; 602 break;
603 603
604 default: 604 default:
605 XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount); 605 XFS_ERROR_REPORT("xfs_iformat(7)", XFS_ERRLEVEL_LOW, ip->i_mount);
606 return XFS_ERROR(EFSCORRUPTED); 606 return XFS_ERROR(EFSCORRUPTED);
607 } 607 }
608 if (error) { 608 if (error) {
609 return error; 609 return error;
610 } 610 }
611 if (!XFS_DFORK_Q(dip)) 611 if (!XFS_DFORK_Q(dip))
612 return 0; 612 return 0;
613 613
614 ASSERT(ip->i_afp == NULL); 614 ASSERT(ip->i_afp == NULL);
615 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS); 615 ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP | KM_NOFS);
616 616
617 switch (dip->di_aformat) { 617 switch (dip->di_aformat) {
618 case XFS_DINODE_FMT_LOCAL: 618 case XFS_DINODE_FMT_LOCAL:
619 atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); 619 atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
620 size = be16_to_cpu(atp->hdr.totsize); 620 size = be16_to_cpu(atp->hdr.totsize);
621 621
622 if (unlikely(size < sizeof(struct xfs_attr_sf_hdr))) { 622 if (unlikely(size < sizeof(struct xfs_attr_sf_hdr))) {
623 xfs_warn(ip->i_mount, 623 xfs_warn(ip->i_mount,
624 "corrupt inode %Lu (bad attr fork size %Ld).", 624 "corrupt inode %Lu (bad attr fork size %Ld).",
625 (unsigned long long) ip->i_ino, 625 (unsigned long long) ip->i_ino,
626 (long long) size); 626 (long long) size);
627 XFS_CORRUPTION_ERROR("xfs_iformat(8)", 627 XFS_CORRUPTION_ERROR("xfs_iformat(8)",
628 XFS_ERRLEVEL_LOW, 628 XFS_ERRLEVEL_LOW,
629 ip->i_mount, dip); 629 ip->i_mount, dip);
630 return XFS_ERROR(EFSCORRUPTED); 630 return XFS_ERROR(EFSCORRUPTED);
631 } 631 }
632 632
633 error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size); 633 error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size);
634 break; 634 break;
635 case XFS_DINODE_FMT_EXTENTS: 635 case XFS_DINODE_FMT_EXTENTS:
636 error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK); 636 error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);
637 break; 637 break;
638 case XFS_DINODE_FMT_BTREE: 638 case XFS_DINODE_FMT_BTREE:
639 error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK); 639 error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
640 break; 640 break;
641 default: 641 default:
642 error = XFS_ERROR(EFSCORRUPTED); 642 error = XFS_ERROR(EFSCORRUPTED);
643 break; 643 break;
644 } 644 }
645 if (error) { 645 if (error) {
646 kmem_zone_free(xfs_ifork_zone, ip->i_afp); 646 kmem_zone_free(xfs_ifork_zone, ip->i_afp);
647 ip->i_afp = NULL; 647 ip->i_afp = NULL;
648 xfs_idestroy_fork(ip, XFS_DATA_FORK); 648 xfs_idestroy_fork(ip, XFS_DATA_FORK);
649 } 649 }
650 return error; 650 return error;
651 } 651 }
652 652
653 /* 653 /*
654 * The file is in-lined in the on-disk inode. 654 * The file is in-lined in the on-disk inode.
655 * If it fits into if_inline_data, then copy 655 * If it fits into if_inline_data, then copy
656 * it there, otherwise allocate a buffer for it 656 * it there, otherwise allocate a buffer for it
657 * and copy the data there. Either way, set 657 * and copy the data there. Either way, set
658 * if_data to point at the data. 658 * if_data to point at the data.
659 * If we allocate a buffer for the data, make 659 * If we allocate a buffer for the data, make
660 * sure that its size is a multiple of 4 and 660 * sure that its size is a multiple of 4 and
661 * record the real size in i_real_bytes. 661 * record the real size in i_real_bytes.
662 */ 662 */
663 STATIC int 663 STATIC int
664 xfs_iformat_local( 664 xfs_iformat_local(
665 xfs_inode_t *ip, 665 xfs_inode_t *ip,
666 xfs_dinode_t *dip, 666 xfs_dinode_t *dip,
667 int whichfork, 667 int whichfork,
668 int size) 668 int size)
669 { 669 {
670 xfs_ifork_t *ifp; 670 xfs_ifork_t *ifp;
671 int real_size; 671 int real_size;
672 672
673 /* 673 /*
674 * If the size is unreasonable, then something 674 * If the size is unreasonable, then something
675 * is wrong and we just bail out rather than crash in 675 * is wrong and we just bail out rather than crash in
676 * kmem_alloc() or memcpy() below. 676 * kmem_alloc() or memcpy() below.
677 */ 677 */
678 if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { 678 if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
679 xfs_warn(ip->i_mount, 679 xfs_warn(ip->i_mount,
680 "corrupt inode %Lu (bad size %d for local fork, size = %d).", 680 "corrupt inode %Lu (bad size %d for local fork, size = %d).",
681 (unsigned long long) ip->i_ino, size, 681 (unsigned long long) ip->i_ino, size,
682 XFS_DFORK_SIZE(dip, ip->i_mount, whichfork)); 682 XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
683 XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW, 683 XFS_CORRUPTION_ERROR("xfs_iformat_local", XFS_ERRLEVEL_LOW,
684 ip->i_mount, dip); 684 ip->i_mount, dip);
685 return XFS_ERROR(EFSCORRUPTED); 685 return XFS_ERROR(EFSCORRUPTED);
686 } 686 }
687 ifp = XFS_IFORK_PTR(ip, whichfork); 687 ifp = XFS_IFORK_PTR(ip, whichfork);
688 real_size = 0; 688 real_size = 0;
689 if (size == 0) 689 if (size == 0)
690 ifp->if_u1.if_data = NULL; 690 ifp->if_u1.if_data = NULL;
691 else if (size <= sizeof(ifp->if_u2.if_inline_data)) 691 else if (size <= sizeof(ifp->if_u2.if_inline_data))
692 ifp->if_u1.if_data = ifp->if_u2.if_inline_data; 692 ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
693 else { 693 else {
694 real_size = roundup(size, 4); 694 real_size = roundup(size, 4);
695 ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS); 695 ifp->if_u1.if_data = kmem_alloc(real_size, KM_SLEEP | KM_NOFS);
696 } 696 }
697 ifp->if_bytes = size; 697 ifp->if_bytes = size;
698 ifp->if_real_bytes = real_size; 698 ifp->if_real_bytes = real_size;
699 if (size) 699 if (size)
700 memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size); 700 memcpy(ifp->if_u1.if_data, XFS_DFORK_PTR(dip, whichfork), size);
701 ifp->if_flags &= ~XFS_IFEXTENTS; 701 ifp->if_flags &= ~XFS_IFEXTENTS;
702 ifp->if_flags |= XFS_IFINLINE; 702 ifp->if_flags |= XFS_IFINLINE;
703 return 0; 703 return 0;
704 } 704 }
705 705
706 /* 706 /*
707 * The file consists of a set of extents all 707 * The file consists of a set of extents all
708 * of which fit into the on-disk inode. 708 * of which fit into the on-disk inode.
709 * If there are few enough extents to fit into 709 * If there are few enough extents to fit into
710 * the if_inline_ext, then copy them there. 710 * the if_inline_ext, then copy them there.
711 * Otherwise allocate a buffer for them and copy 711 * Otherwise allocate a buffer for them and copy
712 * them into it. Either way, set if_extents 712 * them into it. Either way, set if_extents
713 * to point at the extents. 713 * to point at the extents.
714 */ 714 */
715 STATIC int 715 STATIC int
716 xfs_iformat_extents( 716 xfs_iformat_extents(
717 xfs_inode_t *ip, 717 xfs_inode_t *ip,
718 xfs_dinode_t *dip, 718 xfs_dinode_t *dip,
719 int whichfork) 719 int whichfork)
720 { 720 {
721 xfs_bmbt_rec_t *dp; 721 xfs_bmbt_rec_t *dp;
722 xfs_ifork_t *ifp; 722 xfs_ifork_t *ifp;
723 int nex; 723 int nex;
724 int size; 724 int size;
725 int i; 725 int i;
726 726
727 ifp = XFS_IFORK_PTR(ip, whichfork); 727 ifp = XFS_IFORK_PTR(ip, whichfork);
728 nex = XFS_DFORK_NEXTENTS(dip, whichfork); 728 nex = XFS_DFORK_NEXTENTS(dip, whichfork);
729 size = nex * (uint)sizeof(xfs_bmbt_rec_t); 729 size = nex * (uint)sizeof(xfs_bmbt_rec_t);
730 730
731 /* 731 /*
732 * If the number of extents is unreasonable, then something 732 * If the number of extents is unreasonable, then something
733 * is wrong and we just bail out rather than crash in 733 * is wrong and we just bail out rather than crash in
734 * kmem_alloc() or memcpy() below. 734 * kmem_alloc() or memcpy() below.
735 */ 735 */
736 if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) { 736 if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
737 xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %d).", 737 xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %d).",
738 (unsigned long long) ip->i_ino, nex); 738 (unsigned long long) ip->i_ino, nex);
739 XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW, 739 XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW,
740 ip->i_mount, dip); 740 ip->i_mount, dip);
741 return XFS_ERROR(EFSCORRUPTED); 741 return XFS_ERROR(EFSCORRUPTED);
742 } 742 }
743 743
744 ifp->if_real_bytes = 0; 744 ifp->if_real_bytes = 0;
745 if (nex == 0) 745 if (nex == 0)
746 ifp->if_u1.if_extents = NULL; 746 ifp->if_u1.if_extents = NULL;
747 else if (nex <= XFS_INLINE_EXTS) 747 else if (nex <= XFS_INLINE_EXTS)
748 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; 748 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
749 else 749 else
750 xfs_iext_add(ifp, 0, nex); 750 xfs_iext_add(ifp, 0, nex);
751 751
752 ifp->if_bytes = size; 752 ifp->if_bytes = size;
753 if (size) { 753 if (size) {
754 dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); 754 dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
755 xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); 755 xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip));
756 for (i = 0; i < nex; i++, dp++) { 756 for (i = 0; i < nex; i++, dp++) {
757 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); 757 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
758 ep->l0 = get_unaligned_be64(&dp->l0); 758 ep->l0 = get_unaligned_be64(&dp->l0);
759 ep->l1 = get_unaligned_be64(&dp->l1); 759 ep->l1 = get_unaligned_be64(&dp->l1);
760 } 760 }
761 XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); 761 XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork);
762 if (whichfork != XFS_DATA_FORK || 762 if (whichfork != XFS_DATA_FORK ||
763 XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE) 763 XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE)
764 if (unlikely(xfs_check_nostate_extents( 764 if (unlikely(xfs_check_nostate_extents(
765 ifp, 0, nex))) { 765 ifp, 0, nex))) {
766 XFS_ERROR_REPORT("xfs_iformat_extents(2)", 766 XFS_ERROR_REPORT("xfs_iformat_extents(2)",
767 XFS_ERRLEVEL_LOW, 767 XFS_ERRLEVEL_LOW,
768 ip->i_mount); 768 ip->i_mount);
769 return XFS_ERROR(EFSCORRUPTED); 769 return XFS_ERROR(EFSCORRUPTED);
770 } 770 }
771 } 771 }
772 ifp->if_flags |= XFS_IFEXTENTS; 772 ifp->if_flags |= XFS_IFEXTENTS;
773 return 0; 773 return 0;
774 } 774 }
775 775
776 /* 776 /*
777 * The file has too many extents to fit into 777 * The file has too many extents to fit into
778 * the inode, so they are in B-tree format. 778 * the inode, so they are in B-tree format.
779 * Allocate a buffer for the root of the B-tree 779 * Allocate a buffer for the root of the B-tree
780 * and copy the root into it. The i_extents 780 * and copy the root into it. The i_extents
781 * field will remain NULL until all of the 781 * field will remain NULL until all of the
782 * extents are read in (when they are needed). 782 * extents are read in (when they are needed).
783 */ 783 */
784 STATIC int 784 STATIC int
785 xfs_iformat_btree( 785 xfs_iformat_btree(
786 xfs_inode_t *ip, 786 xfs_inode_t *ip,
787 xfs_dinode_t *dip, 787 xfs_dinode_t *dip,
788 int whichfork) 788 int whichfork)
789 { 789 {
790 struct xfs_mount *mp = ip->i_mount; 790 struct xfs_mount *mp = ip->i_mount;
791 xfs_bmdr_block_t *dfp; 791 xfs_bmdr_block_t *dfp;
792 xfs_ifork_t *ifp; 792 xfs_ifork_t *ifp;
793 /* REFERENCED */ 793 /* REFERENCED */
794 int nrecs; 794 int nrecs;
795 int size; 795 int size;
796 796
797 ifp = XFS_IFORK_PTR(ip, whichfork); 797 ifp = XFS_IFORK_PTR(ip, whichfork);
798 dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); 798 dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
799 size = XFS_BMAP_BROOT_SPACE(mp, dfp); 799 size = XFS_BMAP_BROOT_SPACE(mp, dfp);
800 nrecs = be16_to_cpu(dfp->bb_numrecs); 800 nrecs = be16_to_cpu(dfp->bb_numrecs);
801 801
802 /* 802 /*
803 * blow out if -- fork has less extents than can fit in 803 * blow out if -- fork has less extents than can fit in
804 * fork (fork shouldn't be a btree format), root btree 804 * fork (fork shouldn't be a btree format), root btree
805 * block has more records than can fit into the fork, 805 * block has more records than can fit into the fork,
806 * or the number of extents is greater than the number of 806 * or the number of extents is greater than the number of
807 * blocks. 807 * blocks.
808 */ 808 */
809 if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <= 809 if (unlikely(XFS_IFORK_NEXTENTS(ip, whichfork) <=
810 XFS_IFORK_MAXEXT(ip, whichfork) || 810 XFS_IFORK_MAXEXT(ip, whichfork) ||
811 XFS_BMDR_SPACE_CALC(nrecs) > 811 XFS_BMDR_SPACE_CALC(nrecs) >
812 XFS_DFORK_SIZE(dip, mp, whichfork) || 812 XFS_DFORK_SIZE(dip, mp, whichfork) ||
813 XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) { 813 XFS_IFORK_NEXTENTS(ip, whichfork) > ip->i_d.di_nblocks)) {
814 xfs_warn(mp, "corrupt inode %Lu (btree).", 814 xfs_warn(mp, "corrupt inode %Lu (btree).",
815 (unsigned long long) ip->i_ino); 815 (unsigned long long) ip->i_ino);
816 XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW, 816 XFS_CORRUPTION_ERROR("xfs_iformat_btree", XFS_ERRLEVEL_LOW,
817 mp, dip); 817 mp, dip);
818 return XFS_ERROR(EFSCORRUPTED); 818 return XFS_ERROR(EFSCORRUPTED);
819 } 819 }
820 820
821 ifp->if_broot_bytes = size; 821 ifp->if_broot_bytes = size;
822 ifp->if_broot = kmem_alloc(size, KM_SLEEP | KM_NOFS); 822 ifp->if_broot = kmem_alloc(size, KM_SLEEP | KM_NOFS);
823 ASSERT(ifp->if_broot != NULL); 823 ASSERT(ifp->if_broot != NULL);
824 /* 824 /*
825 * Copy and convert from the on-disk structure 825 * Copy and convert from the on-disk structure
826 * to the in-memory structure. 826 * to the in-memory structure.
827 */ 827 */
828 xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork), 828 xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
829 ifp->if_broot, size); 829 ifp->if_broot, size);
830 ifp->if_flags &= ~XFS_IFEXTENTS; 830 ifp->if_flags &= ~XFS_IFEXTENTS;
831 ifp->if_flags |= XFS_IFBROOT; 831 ifp->if_flags |= XFS_IFBROOT;
832 832
833 return 0; 833 return 0;
834 } 834 }
835 835
836 STATIC void 836 STATIC void
837 xfs_dinode_from_disk( 837 xfs_dinode_from_disk(
838 xfs_icdinode_t *to, 838 xfs_icdinode_t *to,
839 xfs_dinode_t *from) 839 xfs_dinode_t *from)
840 { 840 {
841 to->di_magic = be16_to_cpu(from->di_magic); 841 to->di_magic = be16_to_cpu(from->di_magic);
842 to->di_mode = be16_to_cpu(from->di_mode); 842 to->di_mode = be16_to_cpu(from->di_mode);
843 to->di_version = from ->di_version; 843 to->di_version = from ->di_version;
844 to->di_format = from->di_format; 844 to->di_format = from->di_format;
845 to->di_onlink = be16_to_cpu(from->di_onlink); 845 to->di_onlink = be16_to_cpu(from->di_onlink);
846 to->di_uid = be32_to_cpu(from->di_uid); 846 to->di_uid = be32_to_cpu(from->di_uid);
847 to->di_gid = be32_to_cpu(from->di_gid); 847 to->di_gid = be32_to_cpu(from->di_gid);
848 to->di_nlink = be32_to_cpu(from->di_nlink); 848 to->di_nlink = be32_to_cpu(from->di_nlink);
849 to->di_projid_lo = be16_to_cpu(from->di_projid_lo); 849 to->di_projid_lo = be16_to_cpu(from->di_projid_lo);
850 to->di_projid_hi = be16_to_cpu(from->di_projid_hi); 850 to->di_projid_hi = be16_to_cpu(from->di_projid_hi);
851 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); 851 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
852 to->di_flushiter = be16_to_cpu(from->di_flushiter); 852 to->di_flushiter = be16_to_cpu(from->di_flushiter);
853 to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); 853 to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec);
854 to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); 854 to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec);
855 to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); 855 to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec);
856 to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); 856 to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec);
857 to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); 857 to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec);
858 to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); 858 to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec);
859 to->di_size = be64_to_cpu(from->di_size); 859 to->di_size = be64_to_cpu(from->di_size);
860 to->di_nblocks = be64_to_cpu(from->di_nblocks); 860 to->di_nblocks = be64_to_cpu(from->di_nblocks);
861 to->di_extsize = be32_to_cpu(from->di_extsize); 861 to->di_extsize = be32_to_cpu(from->di_extsize);
862 to->di_nextents = be32_to_cpu(from->di_nextents); 862 to->di_nextents = be32_to_cpu(from->di_nextents);
863 to->di_anextents = be16_to_cpu(from->di_anextents); 863 to->di_anextents = be16_to_cpu(from->di_anextents);
864 to->di_forkoff = from->di_forkoff; 864 to->di_forkoff = from->di_forkoff;
865 to->di_aformat = from->di_aformat; 865 to->di_aformat = from->di_aformat;
866 to->di_dmevmask = be32_to_cpu(from->di_dmevmask); 866 to->di_dmevmask = be32_to_cpu(from->di_dmevmask);
867 to->di_dmstate = be16_to_cpu(from->di_dmstate); 867 to->di_dmstate = be16_to_cpu(from->di_dmstate);
868 to->di_flags = be16_to_cpu(from->di_flags); 868 to->di_flags = be16_to_cpu(from->di_flags);
869 to->di_gen = be32_to_cpu(from->di_gen); 869 to->di_gen = be32_to_cpu(from->di_gen);
870 870
871 if (to->di_version == 3) { 871 if (to->di_version == 3) {
872 to->di_changecount = be64_to_cpu(from->di_changecount); 872 to->di_changecount = be64_to_cpu(from->di_changecount);
873 to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec); 873 to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec);
874 to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec); 874 to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec);
875 to->di_flags2 = be64_to_cpu(from->di_flags2); 875 to->di_flags2 = be64_to_cpu(from->di_flags2);
876 to->di_ino = be64_to_cpu(from->di_ino); 876 to->di_ino = be64_to_cpu(from->di_ino);
877 to->di_lsn = be64_to_cpu(from->di_lsn); 877 to->di_lsn = be64_to_cpu(from->di_lsn);
878 memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); 878 memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
879 uuid_copy(&to->di_uuid, &from->di_uuid); 879 uuid_copy(&to->di_uuid, &from->di_uuid);
880 } 880 }
881 } 881 }
882 882
883 void 883 void
884 xfs_dinode_to_disk( 884 xfs_dinode_to_disk(
885 xfs_dinode_t *to, 885 xfs_dinode_t *to,
886 xfs_icdinode_t *from) 886 xfs_icdinode_t *from)
887 { 887 {
888 to->di_magic = cpu_to_be16(from->di_magic); 888 to->di_magic = cpu_to_be16(from->di_magic);
889 to->di_mode = cpu_to_be16(from->di_mode); 889 to->di_mode = cpu_to_be16(from->di_mode);
890 to->di_version = from ->di_version; 890 to->di_version = from ->di_version;
891 to->di_format = from->di_format; 891 to->di_format = from->di_format;
892 to->di_onlink = cpu_to_be16(from->di_onlink); 892 to->di_onlink = cpu_to_be16(from->di_onlink);
893 to->di_uid = cpu_to_be32(from->di_uid); 893 to->di_uid = cpu_to_be32(from->di_uid);
894 to->di_gid = cpu_to_be32(from->di_gid); 894 to->di_gid = cpu_to_be32(from->di_gid);
895 to->di_nlink = cpu_to_be32(from->di_nlink); 895 to->di_nlink = cpu_to_be32(from->di_nlink);
896 to->di_projid_lo = cpu_to_be16(from->di_projid_lo); 896 to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
897 to->di_projid_hi = cpu_to_be16(from->di_projid_hi); 897 to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
898 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); 898 memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
899 to->di_flushiter = cpu_to_be16(from->di_flushiter); 899 to->di_flushiter = cpu_to_be16(from->di_flushiter);
900 to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); 900 to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec);
901 to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); 901 to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec);
902 to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); 902 to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec);
903 to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); 903 to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec);
904 to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); 904 to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec);
905 to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); 905 to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec);
906 to->di_size = cpu_to_be64(from->di_size); 906 to->di_size = cpu_to_be64(from->di_size);
907 to->di_nblocks = cpu_to_be64(from->di_nblocks); 907 to->di_nblocks = cpu_to_be64(from->di_nblocks);
908 to->di_extsize = cpu_to_be32(from->di_extsize); 908 to->di_extsize = cpu_to_be32(from->di_extsize);
909 to->di_nextents = cpu_to_be32(from->di_nextents); 909 to->di_nextents = cpu_to_be32(from->di_nextents);
910 to->di_anextents = cpu_to_be16(from->di_anextents); 910 to->di_anextents = cpu_to_be16(from->di_anextents);
911 to->di_forkoff = from->di_forkoff; 911 to->di_forkoff = from->di_forkoff;
912 to->di_aformat = from->di_aformat; 912 to->di_aformat = from->di_aformat;
913 to->di_dmevmask = cpu_to_be32(from->di_dmevmask); 913 to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
914 to->di_dmstate = cpu_to_be16(from->di_dmstate); 914 to->di_dmstate = cpu_to_be16(from->di_dmstate);
915 to->di_flags = cpu_to_be16(from->di_flags); 915 to->di_flags = cpu_to_be16(from->di_flags);
916 to->di_gen = cpu_to_be32(from->di_gen); 916 to->di_gen = cpu_to_be32(from->di_gen);
917 917
918 if (from->di_version == 3) { 918 if (from->di_version == 3) {
919 to->di_changecount = cpu_to_be64(from->di_changecount); 919 to->di_changecount = cpu_to_be64(from->di_changecount);
920 to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec); 920 to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
921 to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec); 921 to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
922 to->di_flags2 = cpu_to_be64(from->di_flags2); 922 to->di_flags2 = cpu_to_be64(from->di_flags2);
923 to->di_ino = cpu_to_be64(from->di_ino); 923 to->di_ino = cpu_to_be64(from->di_ino);
924 to->di_lsn = cpu_to_be64(from->di_lsn); 924 to->di_lsn = cpu_to_be64(from->di_lsn);
925 memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); 925 memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
926 uuid_copy(&to->di_uuid, &from->di_uuid); 926 uuid_copy(&to->di_uuid, &from->di_uuid);
927 } 927 }
928 } 928 }
929 929
930 STATIC uint 930 STATIC uint
931 _xfs_dic2xflags( 931 _xfs_dic2xflags(
932 __uint16_t di_flags) 932 __uint16_t di_flags)
933 { 933 {
934 uint flags = 0; 934 uint flags = 0;
935 935
936 if (di_flags & XFS_DIFLAG_ANY) { 936 if (di_flags & XFS_DIFLAG_ANY) {
937 if (di_flags & XFS_DIFLAG_REALTIME) 937 if (di_flags & XFS_DIFLAG_REALTIME)
938 flags |= XFS_XFLAG_REALTIME; 938 flags |= XFS_XFLAG_REALTIME;
939 if (di_flags & XFS_DIFLAG_PREALLOC) 939 if (di_flags & XFS_DIFLAG_PREALLOC)
940 flags |= XFS_XFLAG_PREALLOC; 940 flags |= XFS_XFLAG_PREALLOC;
941 if (di_flags & XFS_DIFLAG_IMMUTABLE) 941 if (di_flags & XFS_DIFLAG_IMMUTABLE)
942 flags |= XFS_XFLAG_IMMUTABLE; 942 flags |= XFS_XFLAG_IMMUTABLE;
943 if (di_flags & XFS_DIFLAG_APPEND) 943 if (di_flags & XFS_DIFLAG_APPEND)
944 flags |= XFS_XFLAG_APPEND; 944 flags |= XFS_XFLAG_APPEND;
945 if (di_flags & XFS_DIFLAG_SYNC) 945 if (di_flags & XFS_DIFLAG_SYNC)
946 flags |= XFS_XFLAG_SYNC; 946 flags |= XFS_XFLAG_SYNC;
947 if (di_flags & XFS_DIFLAG_NOATIME) 947 if (di_flags & XFS_DIFLAG_NOATIME)
948 flags |= XFS_XFLAG_NOATIME; 948 flags |= XFS_XFLAG_NOATIME;
949 if (di_flags & XFS_DIFLAG_NODUMP) 949 if (di_flags & XFS_DIFLAG_NODUMP)
950 flags |= XFS_XFLAG_NODUMP; 950 flags |= XFS_XFLAG_NODUMP;
951 if (di_flags & XFS_DIFLAG_RTINHERIT) 951 if (di_flags & XFS_DIFLAG_RTINHERIT)
952 flags |= XFS_XFLAG_RTINHERIT; 952 flags |= XFS_XFLAG_RTINHERIT;
953 if (di_flags & XFS_DIFLAG_PROJINHERIT) 953 if (di_flags & XFS_DIFLAG_PROJINHERIT)
954 flags |= XFS_XFLAG_PROJINHERIT; 954 flags |= XFS_XFLAG_PROJINHERIT;
955 if (di_flags & XFS_DIFLAG_NOSYMLINKS) 955 if (di_flags & XFS_DIFLAG_NOSYMLINKS)
956 flags |= XFS_XFLAG_NOSYMLINKS; 956 flags |= XFS_XFLAG_NOSYMLINKS;
957 if (di_flags & XFS_DIFLAG_EXTSIZE) 957 if (di_flags & XFS_DIFLAG_EXTSIZE)
958 flags |= XFS_XFLAG_EXTSIZE; 958 flags |= XFS_XFLAG_EXTSIZE;
959 if (di_flags & XFS_DIFLAG_EXTSZINHERIT) 959 if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
960 flags |= XFS_XFLAG_EXTSZINHERIT; 960 flags |= XFS_XFLAG_EXTSZINHERIT;
961 if (di_flags & XFS_DIFLAG_NODEFRAG) 961 if (di_flags & XFS_DIFLAG_NODEFRAG)
962 flags |= XFS_XFLAG_NODEFRAG; 962 flags |= XFS_XFLAG_NODEFRAG;
963 if (di_flags & XFS_DIFLAG_FILESTREAM) 963 if (di_flags & XFS_DIFLAG_FILESTREAM)
964 flags |= XFS_XFLAG_FILESTREAM; 964 flags |= XFS_XFLAG_FILESTREAM;
965 } 965 }
966 966
967 return flags; 967 return flags;
968 } 968 }
969 969
970 uint 970 uint
971 xfs_ip2xflags( 971 xfs_ip2xflags(
972 xfs_inode_t *ip) 972 xfs_inode_t *ip)
973 { 973 {
974 xfs_icdinode_t *dic = &ip->i_d; 974 xfs_icdinode_t *dic = &ip->i_d;
975 975
976 return _xfs_dic2xflags(dic->di_flags) | 976 return _xfs_dic2xflags(dic->di_flags) |
977 (XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0); 977 (XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0);
978 } 978 }
979 979
980 uint 980 uint
981 xfs_dic2xflags( 981 xfs_dic2xflags(
982 xfs_dinode_t *dip) 982 xfs_dinode_t *dip)
983 { 983 {
984 return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) | 984 return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) |
985 (XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0); 985 (XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0);
986 } 986 }
987 987
988 static bool 988 static bool
989 xfs_dinode_verify( 989 xfs_dinode_verify(
990 struct xfs_mount *mp, 990 struct xfs_mount *mp,
991 struct xfs_inode *ip, 991 struct xfs_inode *ip,
992 struct xfs_dinode *dip) 992 struct xfs_dinode *dip)
993 { 993 {
994 if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC)) 994 if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
995 return false; 995 return false;
996 996
997 /* only version 3 or greater inodes are extensively verified here */ 997 /* only version 3 or greater inodes are extensively verified here */
998 if (dip->di_version < 3) 998 if (dip->di_version < 3)
999 return true; 999 return true;
1000 1000
1001 if (!xfs_sb_version_hascrc(&mp->m_sb)) 1001 if (!xfs_sb_version_hascrc(&mp->m_sb))
1002 return false; 1002 return false;
1003 if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize, 1003 if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
1004 offsetof(struct xfs_dinode, di_crc))) 1004 offsetof(struct xfs_dinode, di_crc)))
1005 return false; 1005 return false;
1006 if (be64_to_cpu(dip->di_ino) != ip->i_ino) 1006 if (be64_to_cpu(dip->di_ino) != ip->i_ino)
1007 return false; 1007 return false;
1008 if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_uuid)) 1008 if (!uuid_equal(&dip->di_uuid, &mp->m_sb.sb_uuid))
1009 return false; 1009 return false;
1010 return true; 1010 return true;
1011 } 1011 }
1012 1012
1013 void 1013 void
1014 xfs_dinode_calc_crc( 1014 xfs_dinode_calc_crc(
1015 struct xfs_mount *mp, 1015 struct xfs_mount *mp,
1016 struct xfs_dinode *dip) 1016 struct xfs_dinode *dip)
1017 { 1017 {
1018 __uint32_t crc; 1018 __uint32_t crc;
1019 1019
1020 if (dip->di_version < 3) 1020 if (dip->di_version < 3)
1021 return; 1021 return;
1022 1022
1023 ASSERT(xfs_sb_version_hascrc(&mp->m_sb)); 1023 ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
1024 crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize, 1024 crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize,
1025 offsetof(struct xfs_dinode, di_crc)); 1025 offsetof(struct xfs_dinode, di_crc));
1026 dip->di_crc = xfs_end_cksum(crc); 1026 dip->di_crc = xfs_end_cksum(crc);
1027 } 1027 }
1028 1028
1029 /* 1029 /*
1030 * Read the disk inode attributes into the in-core inode structure. 1030 * Read the disk inode attributes into the in-core inode structure.
1031 */ 1031 */
1032 int 1032 int
1033 xfs_iread( 1033 xfs_iread(
1034 xfs_mount_t *mp, 1034 xfs_mount_t *mp,
1035 xfs_trans_t *tp, 1035 xfs_trans_t *tp,
1036 xfs_inode_t *ip, 1036 xfs_inode_t *ip,
1037 uint iget_flags) 1037 uint iget_flags)
1038 { 1038 {
1039 xfs_buf_t *bp; 1039 xfs_buf_t *bp;
1040 xfs_dinode_t *dip; 1040 xfs_dinode_t *dip;
1041 int error; 1041 int error;
1042 1042
1043 /* 1043 /*
1044 * Fill in the location information in the in-core inode. 1044 * Fill in the location information in the in-core inode.
1045 */ 1045 */
1046 error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags); 1046 error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags);
1047 if (error) 1047 if (error)
1048 return error; 1048 return error;
1049 1049
1050 /* 1050 /*
1051 * Get pointers to the on-disk inode and the buffer containing it. 1051 * Get pointers to the on-disk inode and the buffer containing it.
1052 */ 1052 */
1053 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &bp, 0, iget_flags); 1053 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &bp, 0, iget_flags);
1054 if (error) 1054 if (error)
1055 return error; 1055 return error;
1056 1056
1057 /* even unallocated inodes are verified */ 1057 /* even unallocated inodes are verified */
1058 if (!xfs_dinode_verify(mp, ip, dip)) { 1058 if (!xfs_dinode_verify(mp, ip, dip)) {
1059 xfs_alert(mp, "%s: validation failed for inode %lld failed", 1059 xfs_alert(mp, "%s: validation failed for inode %lld failed",
1060 __func__, ip->i_ino); 1060 __func__, ip->i_ino);
1061 1061
1062 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, dip); 1062 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, dip);
1063 error = XFS_ERROR(EFSCORRUPTED); 1063 error = XFS_ERROR(EFSCORRUPTED);
1064 goto out_brelse; 1064 goto out_brelse;
1065 } 1065 }
1066 1066
1067 /* 1067 /*
1068 * If the on-disk inode is already linked to a directory 1068 * If the on-disk inode is already linked to a directory
1069 * entry, copy all of the inode into the in-core inode. 1069 * entry, copy all of the inode into the in-core inode.
1070 * xfs_iformat() handles copying in the inode format 1070 * xfs_iformat() handles copying in the inode format
1071 * specific information. 1071 * specific information.
1072 * Otherwise, just get the truly permanent information. 1072 * Otherwise, just get the truly permanent information.
1073 */ 1073 */
1074 if (dip->di_mode) { 1074 if (dip->di_mode) {
1075 xfs_dinode_from_disk(&ip->i_d, dip); 1075 xfs_dinode_from_disk(&ip->i_d, dip);
1076 error = xfs_iformat(ip, dip); 1076 error = xfs_iformat(ip, dip);
1077 if (error) { 1077 if (error) {
1078 #ifdef DEBUG 1078 #ifdef DEBUG
1079 xfs_alert(mp, "%s: xfs_iformat() returned error %d", 1079 xfs_alert(mp, "%s: xfs_iformat() returned error %d",
1080 __func__, error); 1080 __func__, error);
1081 #endif /* DEBUG */ 1081 #endif /* DEBUG */
1082 goto out_brelse; 1082 goto out_brelse;
1083 } 1083 }
1084 } else { 1084 } else {
1085 /* 1085 /*
1086 * Partial initialisation of the in-core inode. Just the bits 1086 * Partial initialisation of the in-core inode. Just the bits
1087 * that xfs_ialloc won't overwrite or relies on being correct. 1087 * that xfs_ialloc won't overwrite or relies on being correct.
1088 */ 1088 */
1089 ip->i_d.di_magic = be16_to_cpu(dip->di_magic); 1089 ip->i_d.di_magic = be16_to_cpu(dip->di_magic);
1090 ip->i_d.di_version = dip->di_version; 1090 ip->i_d.di_version = dip->di_version;
1091 ip->i_d.di_gen = be32_to_cpu(dip->di_gen); 1091 ip->i_d.di_gen = be32_to_cpu(dip->di_gen);
1092 ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); 1092 ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter);
1093 1093
1094 if (dip->di_version == 3) { 1094 if (dip->di_version == 3) {
1095 ip->i_d.di_ino = be64_to_cpu(dip->di_ino); 1095 ip->i_d.di_ino = be64_to_cpu(dip->di_ino);
1096 uuid_copy(&ip->i_d.di_uuid, &dip->di_uuid); 1096 uuid_copy(&ip->i_d.di_uuid, &dip->di_uuid);
1097 } 1097 }
1098 1098
1099 /* 1099 /*
1100 * Make sure to pull in the mode here as well in 1100 * Make sure to pull in the mode here as well in
1101 * case the inode is released without being used. 1101 * case the inode is released without being used.
1102 * This ensures that xfs_inactive() will see that 1102 * This ensures that xfs_inactive() will see that
1103 * the inode is already free and not try to mess 1103 * the inode is already free and not try to mess
1104 * with the uninitialized part of it. 1104 * with the uninitialized part of it.
1105 */ 1105 */
1106 ip->i_d.di_mode = 0; 1106 ip->i_d.di_mode = 0;
1107 } 1107 }
1108 1108
1109 /* 1109 /*
1110 * The inode format changed when we moved the link count and 1110 * The inode format changed when we moved the link count and
1111 * made it 32 bits long. If this is an old format inode, 1111 * made it 32 bits long. If this is an old format inode,
1112 * convert it in memory to look like a new one. If it gets 1112 * convert it in memory to look like a new one. If it gets
1113 * flushed to disk we will convert back before flushing or 1113 * flushed to disk we will convert back before flushing or
1114 * logging it. We zero out the new projid field and the old link 1114 * logging it. We zero out the new projid field and the old link
1115 * count field. We'll handle clearing the pad field (the remains 1115 * count field. We'll handle clearing the pad field (the remains
1116 * of the old uuid field) when we actually convert the inode to 1116 * of the old uuid field) when we actually convert the inode to
1117 * the new format. We don't change the version number so that we 1117 * the new format. We don't change the version number so that we
1118 * can distinguish this from a real new format inode. 1118 * can distinguish this from a real new format inode.
1119 */ 1119 */
1120 if (ip->i_d.di_version == 1) { 1120 if (ip->i_d.di_version == 1) {
1121 ip->i_d.di_nlink = ip->i_d.di_onlink; 1121 ip->i_d.di_nlink = ip->i_d.di_onlink;
1122 ip->i_d.di_onlink = 0; 1122 ip->i_d.di_onlink = 0;
1123 xfs_set_projid(ip, 0); 1123 xfs_set_projid(ip, 0);
1124 } 1124 }
1125 1125
1126 ip->i_delayed_blks = 0; 1126 ip->i_delayed_blks = 0;
1127 1127
1128 /* 1128 /*
1129 * Mark the buffer containing the inode as something to keep 1129 * Mark the buffer containing the inode as something to keep
1130 * around for a while. This helps to keep recently accessed 1130 * around for a while. This helps to keep recently accessed
1131 * meta-data in-core longer. 1131 * meta-data in-core longer.
1132 */ 1132 */
1133 xfs_buf_set_ref(bp, XFS_INO_REF); 1133 xfs_buf_set_ref(bp, XFS_INO_REF);
1134 1134
1135 /* 1135 /*
1136 * Use xfs_trans_brelse() to release the buffer containing the 1136 * Use xfs_trans_brelse() to release the buffer containing the
1137 * on-disk inode, because it was acquired with xfs_trans_read_buf() 1137 * on-disk inode, because it was acquired with xfs_trans_read_buf()
1138 * in xfs_imap_to_bp() above. If tp is NULL, this is just a normal 1138 * in xfs_imap_to_bp() above. If tp is NULL, this is just a normal
1139 * brelse(). If we're within a transaction, then xfs_trans_brelse() 1139 * brelse(). If we're within a transaction, then xfs_trans_brelse()
1140 * will only release the buffer if it is not dirty within the 1140 * will only release the buffer if it is not dirty within the
1141 * transaction. It will be OK to release the buffer in this case, 1141 * transaction. It will be OK to release the buffer in this case,
1142 * because inodes on disk are never destroyed and we will be 1142 * because inodes on disk are never destroyed and we will be
1143 * locking the new in-core inode before putting it in the hash 1143 * locking the new in-core inode before putting it in the hash
1144 * table where other processes can find it. Thus we don't have 1144 * table where other processes can find it. Thus we don't have
1145 * to worry about the inode being changed just because we released 1145 * to worry about the inode being changed just because we released
1146 * the buffer. 1146 * the buffer.
1147 */ 1147 */
1148 out_brelse: 1148 out_brelse:
1149 xfs_trans_brelse(tp, bp); 1149 xfs_trans_brelse(tp, bp);
1150 return error; 1150 return error;
1151 } 1151 }
1152 1152
1153 /* 1153 /*
1154 * Read in extents from a btree-format inode. 1154 * Read in extents from a btree-format inode.
1155 * Allocate and fill in if_extents. Real work is done in xfs_bmap.c. 1155 * Allocate and fill in if_extents. Real work is done in xfs_bmap.c.
1156 */ 1156 */
1157 int 1157 int
1158 xfs_iread_extents( 1158 xfs_iread_extents(
1159 xfs_trans_t *tp, 1159 xfs_trans_t *tp,
1160 xfs_inode_t *ip, 1160 xfs_inode_t *ip,
1161 int whichfork) 1161 int whichfork)
1162 { 1162 {
1163 int error; 1163 int error;
1164 xfs_ifork_t *ifp; 1164 xfs_ifork_t *ifp;
1165 xfs_extnum_t nextents; 1165 xfs_extnum_t nextents;
1166 1166
1167 if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) { 1167 if (unlikely(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE)) {
1168 XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW, 1168 XFS_ERROR_REPORT("xfs_iread_extents", XFS_ERRLEVEL_LOW,
1169 ip->i_mount); 1169 ip->i_mount);
1170 return XFS_ERROR(EFSCORRUPTED); 1170 return XFS_ERROR(EFSCORRUPTED);
1171 } 1171 }
1172 nextents = XFS_IFORK_NEXTENTS(ip, whichfork); 1172 nextents = XFS_IFORK_NEXTENTS(ip, whichfork);
1173 ifp = XFS_IFORK_PTR(ip, whichfork); 1173 ifp = XFS_IFORK_PTR(ip, whichfork);
1174 1174
1175 /* 1175 /*
1176 * We know that the size is valid (it's checked in iformat_btree) 1176 * We know that the size is valid (it's checked in iformat_btree)
1177 */ 1177 */
1178 ifp->if_bytes = ifp->if_real_bytes = 0; 1178 ifp->if_bytes = ifp->if_real_bytes = 0;
1179 ifp->if_flags |= XFS_IFEXTENTS; 1179 ifp->if_flags |= XFS_IFEXTENTS;
1180 xfs_iext_add(ifp, 0, nextents); 1180 xfs_iext_add(ifp, 0, nextents);
1181 error = xfs_bmap_read_extents(tp, ip, whichfork); 1181 error = xfs_bmap_read_extents(tp, ip, whichfork);
1182 if (error) { 1182 if (error) {
1183 xfs_iext_destroy(ifp); 1183 xfs_iext_destroy(ifp);
1184 ifp->if_flags &= ~XFS_IFEXTENTS; 1184 ifp->if_flags &= ~XFS_IFEXTENTS;
1185 return error; 1185 return error;
1186 } 1186 }
1187 xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip)); 1187 xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip));
1188 return 0; 1188 return 0;
1189 } 1189 }
1190 1190
1191 /* 1191 /*
1192 * Allocate an inode on disk and return a copy of its in-core version. 1192 * Allocate an inode on disk and return a copy of its in-core version.
1193 * The in-core inode is locked exclusively. Set mode, nlink, and rdev 1193 * The in-core inode is locked exclusively. Set mode, nlink, and rdev
1194 * appropriately within the inode. The uid and gid for the inode are 1194 * appropriately within the inode. The uid and gid for the inode are
1195 * set according to the contents of the given cred structure. 1195 * set according to the contents of the given cred structure.
1196 * 1196 *
1197 * Use xfs_dialloc() to allocate the on-disk inode. If xfs_dialloc() 1197 * Use xfs_dialloc() to allocate the on-disk inode. If xfs_dialloc()
1198 * has a free inode available, call xfs_iget() to obtain the in-core 1198 * has a free inode available, call xfs_iget() to obtain the in-core
1199 * version of the allocated inode. Finally, fill in the inode and 1199 * version of the allocated inode. Finally, fill in the inode and
1200 * log its initial contents. In this case, ialloc_context would be 1200 * log its initial contents. In this case, ialloc_context would be
1201 * set to NULL. 1201 * set to NULL.
1202 * 1202 *
1203 * If xfs_dialloc() does not have an available inode, it will replenish 1203 * If xfs_dialloc() does not have an available inode, it will replenish
1204 * its supply by doing an allocation. Since we can only do one 1204 * its supply by doing an allocation. Since we can only do one
1205 * allocation within a transaction without deadlocks, we must commit 1205 * allocation within a transaction without deadlocks, we must commit
1206 * the current transaction before returning the inode itself. 1206 * the current transaction before returning the inode itself.
1207 * In this case, therefore, we will set ialloc_context and return. 1207 * In this case, therefore, we will set ialloc_context and return.
1208 * The caller should then commit the current transaction, start a new 1208 * The caller should then commit the current transaction, start a new
1209 * transaction, and call xfs_ialloc() again to actually get the inode. 1209 * transaction, and call xfs_ialloc() again to actually get the inode.
1210 * 1210 *
1211 * To ensure that some other process does not grab the inode that 1211 * To ensure that some other process does not grab the inode that
1212 * was allocated during the first call to xfs_ialloc(), this routine 1212 * was allocated during the first call to xfs_ialloc(), this routine
1213 * also returns the [locked] bp pointing to the head of the freelist 1213 * also returns the [locked] bp pointing to the head of the freelist
1214 * as ialloc_context. The caller should hold this buffer across 1214 * as ialloc_context. The caller should hold this buffer across
1215 * the commit and pass it back into this routine on the second call. 1215 * the commit and pass it back into this routine on the second call.
1216 * 1216 *
1217 * If we are allocating quota inodes, we do not have a parent inode 1217 * If we are allocating quota inodes, we do not have a parent inode
1218 * to attach to or associate with (i.e. pip == NULL) because they 1218 * to attach to or associate with (i.e. pip == NULL) because they
1219 * are not linked into the directory structure - they are attached 1219 * are not linked into the directory structure - they are attached
1220 * directly to the superblock - and so have no parent. 1220 * directly to the superblock - and so have no parent.
1221 */ 1221 */
1222 int 1222 int
1223 xfs_ialloc( 1223 xfs_ialloc(
1224 xfs_trans_t *tp, 1224 xfs_trans_t *tp,
1225 xfs_inode_t *pip, 1225 xfs_inode_t *pip,
1226 umode_t mode, 1226 umode_t mode,
1227 xfs_nlink_t nlink, 1227 xfs_nlink_t nlink,
1228 xfs_dev_t rdev, 1228 xfs_dev_t rdev,
1229 prid_t prid, 1229 prid_t prid,
1230 int okalloc, 1230 int okalloc,
1231 xfs_buf_t **ialloc_context, 1231 xfs_buf_t **ialloc_context,
1232 xfs_inode_t **ipp) 1232 xfs_inode_t **ipp)
1233 { 1233 {
1234 struct xfs_mount *mp = tp->t_mountp; 1234 struct xfs_mount *mp = tp->t_mountp;
1235 xfs_ino_t ino; 1235 xfs_ino_t ino;
1236 xfs_inode_t *ip; 1236 xfs_inode_t *ip;
1237 uint flags; 1237 uint flags;
1238 int error; 1238 int error;
1239 timespec_t tv; 1239 timespec_t tv;
1240 int filestreams = 0; 1240 int filestreams = 0;
1241 1241
1242 /* 1242 /*
1243 * Call the space management code to pick 1243 * Call the space management code to pick
1244 * the on-disk inode to be allocated. 1244 * the on-disk inode to be allocated.
1245 */ 1245 */
1246 error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, 1246 error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc,
1247 ialloc_context, &ino); 1247 ialloc_context, &ino);
1248 if (error) 1248 if (error)
1249 return error; 1249 return error;
1250 if (*ialloc_context || ino == NULLFSINO) { 1250 if (*ialloc_context || ino == NULLFSINO) {
1251 *ipp = NULL; 1251 *ipp = NULL;
1252 return 0; 1252 return 0;
1253 } 1253 }
1254 ASSERT(*ialloc_context == NULL); 1254 ASSERT(*ialloc_context == NULL);
1255 1255
1256 /* 1256 /*
1257 * Get the in-core inode with the lock held exclusively. 1257 * Get the in-core inode with the lock held exclusively.
1258 * This is because we're setting fields here we need 1258 * This is because we're setting fields here we need
1259 * to prevent others from looking at until we're done. 1259 * to prevent others from looking at until we're done.
1260 */ 1260 */
1261 error = xfs_iget(mp, tp, ino, XFS_IGET_CREATE, 1261 error = xfs_iget(mp, tp, ino, XFS_IGET_CREATE,
1262 XFS_ILOCK_EXCL, &ip); 1262 XFS_ILOCK_EXCL, &ip);
1263 if (error) 1263 if (error)
1264 return error; 1264 return error;
1265 ASSERT(ip != NULL); 1265 ASSERT(ip != NULL);
1266 1266
1267 ip->i_d.di_mode = mode; 1267 ip->i_d.di_mode = mode;
1268 ip->i_d.di_onlink = 0; 1268 ip->i_d.di_onlink = 0;
1269 ip->i_d.di_nlink = nlink; 1269 ip->i_d.di_nlink = nlink;
1270 ASSERT(ip->i_d.di_nlink == nlink); 1270 ASSERT(ip->i_d.di_nlink == nlink);
1271 ip->i_d.di_uid = current_fsuid(); 1271 ip->i_d.di_uid = current_fsuid();
1272 ip->i_d.di_gid = current_fsgid(); 1272 ip->i_d.di_gid = current_fsgid();
1273 xfs_set_projid(ip, prid); 1273 xfs_set_projid(ip, prid);
1274 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); 1274 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
1275 1275
1276 /* 1276 /*
1277 * If the superblock version is up to where we support new format 1277 * If the superblock version is up to where we support new format
1278 * inodes and this is currently an old format inode, then change 1278 * inodes and this is currently an old format inode, then change
1279 * the inode version number now. This way we only do the conversion 1279 * the inode version number now. This way we only do the conversion
1280 * here rather than here and in the flush/logging code. 1280 * here rather than here and in the flush/logging code.
1281 */ 1281 */
1282 if (xfs_sb_version_hasnlink(&mp->m_sb) && 1282 if (xfs_sb_version_hasnlink(&mp->m_sb) &&
1283 ip->i_d.di_version == 1) { 1283 ip->i_d.di_version == 1) {
1284 ip->i_d.di_version = 2; 1284 ip->i_d.di_version = 2;
1285 /* 1285 /*
1286 * We've already zeroed the old link count, the projid field, 1286 * We've already zeroed the old link count, the projid field,
1287 * and the pad field. 1287 * and the pad field.
1288 */ 1288 */
1289 } 1289 }
1290 1290
1291 /* 1291 /*
1292 * Project ids won't be stored on disk if we are using a version 1 inode. 1292 * Project ids won't be stored on disk if we are using a version 1 inode.
1293 */ 1293 */
1294 if ((prid != 0) && (ip->i_d.di_version == 1)) 1294 if ((prid != 0) && (ip->i_d.di_version == 1))
1295 xfs_bump_ino_vers2(tp, ip); 1295 xfs_bump_ino_vers2(tp, ip);
1296 1296
1297 if (pip && XFS_INHERIT_GID(pip)) { 1297 if (pip && XFS_INHERIT_GID(pip)) {
1298 ip->i_d.di_gid = pip->i_d.di_gid; 1298 ip->i_d.di_gid = pip->i_d.di_gid;
1299 if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) { 1299 if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) {
1300 ip->i_d.di_mode |= S_ISGID; 1300 ip->i_d.di_mode |= S_ISGID;
1301 } 1301 }
1302 } 1302 }
1303 1303
1304 /* 1304 /*
1305 * If the group ID of the new file does not match the effective group 1305 * If the group ID of the new file does not match the effective group
1306 * ID or one of the supplementary group IDs, the S_ISGID bit is cleared 1306 * ID or one of the supplementary group IDs, the S_ISGID bit is cleared
1307 * (and only if the irix_sgid_inherit compatibility variable is set). 1307 * (and only if the irix_sgid_inherit compatibility variable is set).
1308 */ 1308 */
1309 if ((irix_sgid_inherit) && 1309 if ((irix_sgid_inherit) &&
1310 (ip->i_d.di_mode & S_ISGID) && 1310 (ip->i_d.di_mode & S_ISGID) &&
1311 (!in_group_p((gid_t)ip->i_d.di_gid))) { 1311 (!in_group_p((gid_t)ip->i_d.di_gid))) {
1312 ip->i_d.di_mode &= ~S_ISGID; 1312 ip->i_d.di_mode &= ~S_ISGID;
1313 } 1313 }
1314 1314
1315 ip->i_d.di_size = 0; 1315 ip->i_d.di_size = 0;
1316 ip->i_d.di_nextents = 0; 1316 ip->i_d.di_nextents = 0;
1317 ASSERT(ip->i_d.di_nblocks == 0); 1317 ASSERT(ip->i_d.di_nblocks == 0);
1318 1318
1319 nanotime(&tv); 1319 nanotime(&tv);
1320 ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; 1320 ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
1321 ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; 1321 ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
1322 ip->i_d.di_atime = ip->i_d.di_mtime; 1322 ip->i_d.di_atime = ip->i_d.di_mtime;
1323 ip->i_d.di_ctime = ip->i_d.di_mtime; 1323 ip->i_d.di_ctime = ip->i_d.di_mtime;
1324 1324
1325 /* 1325 /*
1326 * di_gen will have been taken care of in xfs_iread. 1326 * di_gen will have been taken care of in xfs_iread.
1327 */ 1327 */
1328 ip->i_d.di_extsize = 0; 1328 ip->i_d.di_extsize = 0;
1329 ip->i_d.di_dmevmask = 0; 1329 ip->i_d.di_dmevmask = 0;
1330 ip->i_d.di_dmstate = 0; 1330 ip->i_d.di_dmstate = 0;
1331 ip->i_d.di_flags = 0; 1331 ip->i_d.di_flags = 0;
1332 1332
1333 if (ip->i_d.di_version == 3) { 1333 if (ip->i_d.di_version == 3) {
1334 ASSERT(ip->i_d.di_ino == ino); 1334 ASSERT(ip->i_d.di_ino == ino);
1335 ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid)); 1335 ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid));
1336 ip->i_d.di_crc = 0; 1336 ip->i_d.di_crc = 0;
1337 ip->i_d.di_changecount = 1; 1337 ip->i_d.di_changecount = 1;
1338 ip->i_d.di_lsn = 0; 1338 ip->i_d.di_lsn = 0;
1339 ip->i_d.di_flags2 = 0; 1339 ip->i_d.di_flags2 = 0;
1340 memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2)); 1340 memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2));
1341 ip->i_d.di_crtime = ip->i_d.di_mtime; 1341 ip->i_d.di_crtime = ip->i_d.di_mtime;
1342 } 1342 }
1343 1343
1344 1344
1345 flags = XFS_ILOG_CORE; 1345 flags = XFS_ILOG_CORE;
1346 switch (mode & S_IFMT) { 1346 switch (mode & S_IFMT) {
1347 case S_IFIFO: 1347 case S_IFIFO:
1348 case S_IFCHR: 1348 case S_IFCHR:
1349 case S_IFBLK: 1349 case S_IFBLK:
1350 case S_IFSOCK: 1350 case S_IFSOCK:
1351 ip->i_d.di_format = XFS_DINODE_FMT_DEV; 1351 ip->i_d.di_format = XFS_DINODE_FMT_DEV;
1352 ip->i_df.if_u2.if_rdev = rdev; 1352 ip->i_df.if_u2.if_rdev = rdev;
1353 ip->i_df.if_flags = 0; 1353 ip->i_df.if_flags = 0;
1354 flags |= XFS_ILOG_DEV; 1354 flags |= XFS_ILOG_DEV;
1355 break; 1355 break;
1356 case S_IFREG: 1356 case S_IFREG:
1357 /* 1357 /*
1358 * we can't set up filestreams until after the VFS inode 1358 * we can't set up filestreams until after the VFS inode
1359 * is set up properly. 1359 * is set up properly.
1360 */ 1360 */
1361 if (pip && xfs_inode_is_filestream(pip)) 1361 if (pip && xfs_inode_is_filestream(pip))
1362 filestreams = 1; 1362 filestreams = 1;
1363 /* fall through */ 1363 /* fall through */
1364 case S_IFDIR: 1364 case S_IFDIR:
1365 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { 1365 if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
1366 uint di_flags = 0; 1366 uint di_flags = 0;
1367 1367
1368 if (S_ISDIR(mode)) { 1368 if (S_ISDIR(mode)) {
1369 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) 1369 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
1370 di_flags |= XFS_DIFLAG_RTINHERIT; 1370 di_flags |= XFS_DIFLAG_RTINHERIT;
1371 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { 1371 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
1372 di_flags |= XFS_DIFLAG_EXTSZINHERIT; 1372 di_flags |= XFS_DIFLAG_EXTSZINHERIT;
1373 ip->i_d.di_extsize = pip->i_d.di_extsize; 1373 ip->i_d.di_extsize = pip->i_d.di_extsize;
1374 } 1374 }
1375 } else if (S_ISREG(mode)) { 1375 } else if (S_ISREG(mode)) {
1376 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) 1376 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
1377 di_flags |= XFS_DIFLAG_REALTIME; 1377 di_flags |= XFS_DIFLAG_REALTIME;
1378 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) { 1378 if (pip->i_d.di_flags & XFS_DIFLAG_EXTSZINHERIT) {
1379 di_flags |= XFS_DIFLAG_EXTSIZE; 1379 di_flags |= XFS_DIFLAG_EXTSIZE;
1380 ip->i_d.di_extsize = pip->i_d.di_extsize; 1380 ip->i_d.di_extsize = pip->i_d.di_extsize;
1381 } 1381 }
1382 } 1382 }
1383 if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && 1383 if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
1384 xfs_inherit_noatime) 1384 xfs_inherit_noatime)
1385 di_flags |= XFS_DIFLAG_NOATIME; 1385 di_flags |= XFS_DIFLAG_NOATIME;
1386 if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) && 1386 if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
1387 xfs_inherit_nodump) 1387 xfs_inherit_nodump)
1388 di_flags |= XFS_DIFLAG_NODUMP; 1388 di_flags |= XFS_DIFLAG_NODUMP;
1389 if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) && 1389 if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
1390 xfs_inherit_sync) 1390 xfs_inherit_sync)
1391 di_flags |= XFS_DIFLAG_SYNC; 1391 di_flags |= XFS_DIFLAG_SYNC;
1392 if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) && 1392 if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) &&
1393 xfs_inherit_nosymlinks) 1393 xfs_inherit_nosymlinks)
1394 di_flags |= XFS_DIFLAG_NOSYMLINKS; 1394 di_flags |= XFS_DIFLAG_NOSYMLINKS;
1395 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) 1395 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1396 di_flags |= XFS_DIFLAG_PROJINHERIT; 1396 di_flags |= XFS_DIFLAG_PROJINHERIT;
1397 if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) && 1397 if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) &&
1398 xfs_inherit_nodefrag) 1398 xfs_inherit_nodefrag)
1399 di_flags |= XFS_DIFLAG_NODEFRAG; 1399 di_flags |= XFS_DIFLAG_NODEFRAG;
1400 if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM) 1400 if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM)
1401 di_flags |= XFS_DIFLAG_FILESTREAM; 1401 di_flags |= XFS_DIFLAG_FILESTREAM;
1402 ip->i_d.di_flags |= di_flags; 1402 ip->i_d.di_flags |= di_flags;
1403 } 1403 }
1404 /* FALLTHROUGH */ 1404 /* FALLTHROUGH */
1405 case S_IFLNK: 1405 case S_IFLNK:
1406 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; 1406 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
1407 ip->i_df.if_flags = XFS_IFEXTENTS; 1407 ip->i_df.if_flags = XFS_IFEXTENTS;
1408 ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0; 1408 ip->i_df.if_bytes = ip->i_df.if_real_bytes = 0;
1409 ip->i_df.if_u1.if_extents = NULL; 1409 ip->i_df.if_u1.if_extents = NULL;
1410 break; 1410 break;
1411 default: 1411 default:
1412 ASSERT(0); 1412 ASSERT(0);
1413 } 1413 }
1414 /* 1414 /*
1415 * Attribute fork settings for new inode. 1415 * Attribute fork settings for new inode.
1416 */ 1416 */
1417 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; 1417 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
1418 ip->i_d.di_anextents = 0; 1418 ip->i_d.di_anextents = 0;
1419 1419
1420 /* 1420 /*
1421 * Log the new values stuffed into the inode. 1421 * Log the new values stuffed into the inode.
1422 */ 1422 */
1423 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 1423 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1424 xfs_trans_log_inode(tp, ip, flags); 1424 xfs_trans_log_inode(tp, ip, flags);
1425 1425
1426 /* now that we have an i_mode we can setup inode ops and unlock */ 1426 /* now that we have an i_mode we can setup inode ops and unlock */
1427 xfs_setup_inode(ip); 1427 xfs_setup_inode(ip);
1428 1428
1429 /* now we have set up the vfs inode we can associate the filestream */ 1429 /* now we have set up the vfs inode we can associate the filestream */
1430 if (filestreams) { 1430 if (filestreams) {
1431 error = xfs_filestream_associate(pip, ip); 1431 error = xfs_filestream_associate(pip, ip);
1432 if (error < 0) 1432 if (error < 0)
1433 return -error; 1433 return -error;
1434 if (!error) 1434 if (!error)
1435 xfs_iflags_set(ip, XFS_IFILESTREAM); 1435 xfs_iflags_set(ip, XFS_IFILESTREAM);
1436 } 1436 }
1437 1437
1438 *ipp = ip; 1438 *ipp = ip;
1439 return 0; 1439 return 0;
1440 } 1440 }
1441 1441
1442 /* 1442 /*
1443 * Free up the underlying blocks past new_size. The new size must be smaller 1443 * Free up the underlying blocks past new_size. The new size must be smaller
1444 * than the current size. This routine can be used both for the attribute and 1444 * than the current size. This routine can be used both for the attribute and
1445 * data fork, and does not modify the inode size, which is left to the caller. 1445 * data fork, and does not modify the inode size, which is left to the caller.
1446 * 1446 *
1447 * The transaction passed to this routine must have made a permanent log 1447 * The transaction passed to this routine must have made a permanent log
1448 * reservation of at least XFS_ITRUNCATE_LOG_RES. This routine may commit the 1448 * reservation of at least XFS_ITRUNCATE_LOG_RES. This routine may commit the
1449 * given transaction and start new ones, so make sure everything involved in 1449 * given transaction and start new ones, so make sure everything involved in
1450 * the transaction is tidy before calling here. Some transaction will be 1450 * the transaction is tidy before calling here. Some transaction will be
1451 * returned to the caller to be committed. The incoming transaction must 1451 * returned to the caller to be committed. The incoming transaction must
1452 * already include the inode, and both inode locks must be held exclusively. 1452 * already include the inode, and both inode locks must be held exclusively.
1453 * The inode must also be "held" within the transaction. On return the inode 1453 * The inode must also be "held" within the transaction. On return the inode
1454 * will be "held" within the returned transaction. This routine does NOT 1454 * will be "held" within the returned transaction. This routine does NOT
1455 * require any disk space to be reserved for it within the transaction. 1455 * require any disk space to be reserved for it within the transaction.
1456 * 1456 *
1457 * If we get an error, we must return with the inode locked and linked into the 1457 * If we get an error, we must return with the inode locked and linked into the
1458 * current transaction. This keeps things simple for the higher level code, 1458 * current transaction. This keeps things simple for the higher level code,
1459 * because it always knows that the inode is locked and held in the transaction 1459 * because it always knows that the inode is locked and held in the transaction
1460 * that returns to it whether errors occur or not. We don't mark the inode 1460 * that returns to it whether errors occur or not. We don't mark the inode
1461 * dirty on error so that transactions can be easily aborted if possible. 1461 * dirty on error so that transactions can be easily aborted if possible.
1462 */ 1462 */
1463 int 1463 int
1464 xfs_itruncate_extents( 1464 xfs_itruncate_extents(
1465 struct xfs_trans **tpp, 1465 struct xfs_trans **tpp,
1466 struct xfs_inode *ip, 1466 struct xfs_inode *ip,
1467 int whichfork, 1467 int whichfork,
1468 xfs_fsize_t new_size) 1468 xfs_fsize_t new_size)
1469 { 1469 {
1470 struct xfs_mount *mp = ip->i_mount; 1470 struct xfs_mount *mp = ip->i_mount;
1471 struct xfs_trans *tp = *tpp; 1471 struct xfs_trans *tp = *tpp;
1472 struct xfs_trans *ntp; 1472 struct xfs_trans *ntp;
1473 xfs_bmap_free_t free_list; 1473 xfs_bmap_free_t free_list;
1474 xfs_fsblock_t first_block; 1474 xfs_fsblock_t first_block;
1475 xfs_fileoff_t first_unmap_block; 1475 xfs_fileoff_t first_unmap_block;
1476 xfs_fileoff_t last_block; 1476 xfs_fileoff_t last_block;
1477 xfs_filblks_t unmap_len; 1477 xfs_filblks_t unmap_len;
1478 int committed; 1478 int committed;
1479 int error = 0; 1479 int error = 0;
1480 int done = 0; 1480 int done = 0;
1481 1481
1482 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 1482 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
1483 ASSERT(!atomic_read(&VFS_I(ip)->i_count) || 1483 ASSERT(!atomic_read(&VFS_I(ip)->i_count) ||
1484 xfs_isilocked(ip, XFS_IOLOCK_EXCL)); 1484 xfs_isilocked(ip, XFS_IOLOCK_EXCL));
1485 ASSERT(new_size <= XFS_ISIZE(ip)); 1485 ASSERT(new_size <= XFS_ISIZE(ip));
1486 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); 1486 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
1487 ASSERT(ip->i_itemp != NULL); 1487 ASSERT(ip->i_itemp != NULL);
1488 ASSERT(ip->i_itemp->ili_lock_flags == 0); 1488 ASSERT(ip->i_itemp->ili_lock_flags == 0);
1489 ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); 1489 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
1490 1490
1491 trace_xfs_itruncate_extents_start(ip, new_size); 1491 trace_xfs_itruncate_extents_start(ip, new_size);
1492 1492
1493 /* 1493 /*
1494 * Since it is possible for space to become allocated beyond 1494 * Since it is possible for space to become allocated beyond
1495 * the end of the file (in a crash where the space is allocated 1495 * the end of the file (in a crash where the space is allocated
1496 * but the inode size is not yet updated), simply remove any 1496 * but the inode size is not yet updated), simply remove any
1497 * blocks which show up between the new EOF and the maximum 1497 * blocks which show up between the new EOF and the maximum
1498 * possible file size. If the first block to be removed is 1498 * possible file size. If the first block to be removed is
1499 * beyond the maximum file size (ie it is the same as last_block), 1499 * beyond the maximum file size (ie it is the same as last_block),
1500 * then there is nothing to do. 1500 * then there is nothing to do.
1501 */ 1501 */
1502 first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); 1502 first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
1503 last_block = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); 1503 last_block = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
1504 if (first_unmap_block == last_block) 1504 if (first_unmap_block == last_block)
1505 return 0; 1505 return 0;
1506 1506
1507 ASSERT(first_unmap_block < last_block); 1507 ASSERT(first_unmap_block < last_block);
1508 unmap_len = last_block - first_unmap_block + 1; 1508 unmap_len = last_block - first_unmap_block + 1;
1509 while (!done) { 1509 while (!done) {
1510 xfs_bmap_init(&free_list, &first_block); 1510 xfs_bmap_init(&free_list, &first_block);
1511 error = xfs_bunmapi(tp, ip, 1511 error = xfs_bunmapi(tp, ip,
1512 first_unmap_block, unmap_len, 1512 first_unmap_block, unmap_len,
1513 xfs_bmapi_aflag(whichfork), 1513 xfs_bmapi_aflag(whichfork),
1514 XFS_ITRUNC_MAX_EXTENTS, 1514 XFS_ITRUNC_MAX_EXTENTS,
1515 &first_block, &free_list, 1515 &first_block, &free_list,
1516 &done); 1516 &done);
1517 if (error) 1517 if (error)
1518 goto out_bmap_cancel; 1518 goto out_bmap_cancel;
1519 1519
1520 /* 1520 /*
1521 * Duplicate the transaction that has the permanent 1521 * Duplicate the transaction that has the permanent
1522 * reservation and commit the old transaction. 1522 * reservation and commit the old transaction.
1523 */ 1523 */
1524 error = xfs_bmap_finish(&tp, &free_list, &committed); 1524 error = xfs_bmap_finish(&tp, &free_list, &committed);
1525 if (committed) 1525 if (committed)
1526 xfs_trans_ijoin(tp, ip, 0); 1526 xfs_trans_ijoin(tp, ip, 0);
1527 if (error) 1527 if (error)
1528 goto out_bmap_cancel; 1528 goto out_bmap_cancel;
1529 1529
1530 if (committed) { 1530 if (committed) {
1531 /* 1531 /*
1532 * Mark the inode dirty so it will be logged and 1532 * Mark the inode dirty so it will be logged and
1533 * moved forward in the log as part of every commit. 1533 * moved forward in the log as part of every commit.
1534 */ 1534 */
1535 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1535 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1536 } 1536 }
1537 1537
1538 ntp = xfs_trans_dup(tp); 1538 ntp = xfs_trans_dup(tp);
1539 error = xfs_trans_commit(tp, 0); 1539 error = xfs_trans_commit(tp, 0);
1540 tp = ntp; 1540 tp = ntp;
1541 1541
1542 xfs_trans_ijoin(tp, ip, 0); 1542 xfs_trans_ijoin(tp, ip, 0);
1543 1543
1544 if (error) 1544 if (error)
1545 goto out; 1545 goto out;
1546 1546
1547 /* 1547 /*
1548 * Transaction commit worked ok so we can drop the extra ticket 1548 * Transaction commit worked ok so we can drop the extra ticket
1549 * reference that we gained in xfs_trans_dup() 1549 * reference that we gained in xfs_trans_dup()
1550 */ 1550 */
1551 xfs_log_ticket_put(tp->t_ticket); 1551 xfs_log_ticket_put(tp->t_ticket);
1552 error = xfs_trans_reserve(tp, 0, 1552 error = xfs_trans_reserve(tp, 0,
1553 XFS_ITRUNCATE_LOG_RES(mp), 0, 1553 XFS_ITRUNCATE_LOG_RES(mp), 0,
1554 XFS_TRANS_PERM_LOG_RES, 1554 XFS_TRANS_PERM_LOG_RES,
1555 XFS_ITRUNCATE_LOG_COUNT); 1555 XFS_ITRUNCATE_LOG_COUNT);
1556 if (error) 1556 if (error)
1557 goto out; 1557 goto out;
1558 } 1558 }
1559 1559
1560 /* 1560 /*
1561 * Always re-log the inode so that our permanent transaction can keep 1561 * Always re-log the inode so that our permanent transaction can keep
1562 * on rolling it forward in the log. 1562 * on rolling it forward in the log.
1563 */ 1563 */
1564 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 1564 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1565 1565
1566 trace_xfs_itruncate_extents_end(ip, new_size); 1566 trace_xfs_itruncate_extents_end(ip, new_size);
1567 1567
1568 out: 1568 out:
1569 *tpp = tp; 1569 *tpp = tp;
1570 return error; 1570 return error;
1571 out_bmap_cancel: 1571 out_bmap_cancel:
1572 /* 1572 /*
1573 * If the bunmapi call encounters an error, return to the caller where 1573 * If the bunmapi call encounters an error, return to the caller where
1574 * the transaction can be properly aborted. We just need to make sure 1574 * the transaction can be properly aborted. We just need to make sure
1575 * we're not holding any resources that we were not when we came in. 1575 * we're not holding any resources that we were not when we came in.
1576 */ 1576 */
1577 xfs_bmap_cancel(&free_list); 1577 xfs_bmap_cancel(&free_list);
1578 goto out; 1578 goto out;
1579 } 1579 }
1580 1580
1581 /* 1581 /*
1582 * This is called when the inode's link count goes to 0. 1582 * This is called when the inode's link count goes to 0.
1583 * We place the on-disk inode on a list in the AGI. It 1583 * We place the on-disk inode on a list in the AGI. It
1584 * will be pulled from this list when the inode is freed. 1584 * will be pulled from this list when the inode is freed.
1585 */ 1585 */
1586 int 1586 int
1587 xfs_iunlink( 1587 xfs_iunlink(
1588 xfs_trans_t *tp, 1588 xfs_trans_t *tp,
1589 xfs_inode_t *ip) 1589 xfs_inode_t *ip)
1590 { 1590 {
1591 xfs_mount_t *mp; 1591 xfs_mount_t *mp;
1592 xfs_agi_t *agi; 1592 xfs_agi_t *agi;
1593 xfs_dinode_t *dip; 1593 xfs_dinode_t *dip;
1594 xfs_buf_t *agibp; 1594 xfs_buf_t *agibp;
1595 xfs_buf_t *ibp; 1595 xfs_buf_t *ibp;
1596 xfs_agino_t agino; 1596 xfs_agino_t agino;
1597 short bucket_index; 1597 short bucket_index;
1598 int offset; 1598 int offset;
1599 int error; 1599 int error;
1600 1600
1601 ASSERT(ip->i_d.di_nlink == 0); 1601 ASSERT(ip->i_d.di_nlink == 0);
1602 ASSERT(ip->i_d.di_mode != 0); 1602 ASSERT(ip->i_d.di_mode != 0);
1603 1603
1604 mp = tp->t_mountp; 1604 mp = tp->t_mountp;
1605 1605
1606 /* 1606 /*
1607 * Get the agi buffer first. It ensures lock ordering 1607 * Get the agi buffer first. It ensures lock ordering
1608 * on the list. 1608 * on the list.
1609 */ 1609 */
1610 error = xfs_read_agi(mp, tp, XFS_INO_TO_AGNO(mp, ip->i_ino), &agibp); 1610 error = xfs_read_agi(mp, tp, XFS_INO_TO_AGNO(mp, ip->i_ino), &agibp);
1611 if (error) 1611 if (error)
1612 return error; 1612 return error;
1613 agi = XFS_BUF_TO_AGI(agibp); 1613 agi = XFS_BUF_TO_AGI(agibp);
1614 1614
1615 /* 1615 /*
1616 * Get the index into the agi hash table for the 1616 * Get the index into the agi hash table for the
1617 * list this inode will go on. 1617 * list this inode will go on.
1618 */ 1618 */
1619 agino = XFS_INO_TO_AGINO(mp, ip->i_ino); 1619 agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
1620 ASSERT(agino != 0); 1620 ASSERT(agino != 0);
1621 bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; 1621 bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
1622 ASSERT(agi->agi_unlinked[bucket_index]); 1622 ASSERT(agi->agi_unlinked[bucket_index]);
1623 ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); 1623 ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino);
1624 1624
1625 if (agi->agi_unlinked[bucket_index] != cpu_to_be32(NULLAGINO)) { 1625 if (agi->agi_unlinked[bucket_index] != cpu_to_be32(NULLAGINO)) {
1626 /* 1626 /*
1627 * There is already another inode in the bucket we need 1627 * There is already another inode in the bucket we need
1628 * to add ourselves to. Add us at the front of the list. 1628 * to add ourselves to. Add us at the front of the list.
1629 * Here we put the head pointer into our next pointer, 1629 * Here we put the head pointer into our next pointer,
1630 * and then we fall through to point the head at us. 1630 * and then we fall through to point the head at us.
1631 */ 1631 */
1632 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp, 1632 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp,
1633 0, 0); 1633 0, 0);
1634 if (error) 1634 if (error)
1635 return error; 1635 return error;
1636 1636
1637 ASSERT(dip->di_next_unlinked == cpu_to_be32(NULLAGINO)); 1637 ASSERT(dip->di_next_unlinked == cpu_to_be32(NULLAGINO));
1638 dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; 1638 dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
1639 offset = ip->i_imap.im_boffset + 1639 offset = ip->i_imap.im_boffset +
1640 offsetof(xfs_dinode_t, di_next_unlinked); 1640 offsetof(xfs_dinode_t, di_next_unlinked);
1641 xfs_trans_inode_buf(tp, ibp); 1641 xfs_trans_inode_buf(tp, ibp);
1642 xfs_trans_log_buf(tp, ibp, offset, 1642 xfs_trans_log_buf(tp, ibp, offset,
1643 (offset + sizeof(xfs_agino_t) - 1)); 1643 (offset + sizeof(xfs_agino_t) - 1));
1644 xfs_inobp_check(mp, ibp); 1644 xfs_inobp_check(mp, ibp);
1645 } 1645 }
1646 1646
1647 /* 1647 /*
1648 * Point the bucket head pointer at the inode being inserted. 1648 * Point the bucket head pointer at the inode being inserted.
1649 */ 1649 */
1650 ASSERT(agino != 0); 1650 ASSERT(agino != 0);
1651 agi->agi_unlinked[bucket_index] = cpu_to_be32(agino); 1651 agi->agi_unlinked[bucket_index] = cpu_to_be32(agino);
1652 offset = offsetof(xfs_agi_t, agi_unlinked) + 1652 offset = offsetof(xfs_agi_t, agi_unlinked) +
1653 (sizeof(xfs_agino_t) * bucket_index); 1653 (sizeof(xfs_agino_t) * bucket_index);
1654 xfs_trans_log_buf(tp, agibp, offset, 1654 xfs_trans_log_buf(tp, agibp, offset,
1655 (offset + sizeof(xfs_agino_t) - 1)); 1655 (offset + sizeof(xfs_agino_t) - 1));
1656 return 0; 1656 return 0;
1657 } 1657 }
1658 1658
1659 /* 1659 /*
1660 * Pull the on-disk inode from the AGI unlinked list. 1660 * Pull the on-disk inode from the AGI unlinked list.
1661 */ 1661 */
1662 STATIC int 1662 STATIC int
1663 xfs_iunlink_remove( 1663 xfs_iunlink_remove(
1664 xfs_trans_t *tp, 1664 xfs_trans_t *tp,
1665 xfs_inode_t *ip) 1665 xfs_inode_t *ip)
1666 { 1666 {
1667 xfs_ino_t next_ino; 1667 xfs_ino_t next_ino;
1668 xfs_mount_t *mp; 1668 xfs_mount_t *mp;
1669 xfs_agi_t *agi; 1669 xfs_agi_t *agi;
1670 xfs_dinode_t *dip; 1670 xfs_dinode_t *dip;
1671 xfs_buf_t *agibp; 1671 xfs_buf_t *agibp;
1672 xfs_buf_t *ibp; 1672 xfs_buf_t *ibp;
1673 xfs_agnumber_t agno; 1673 xfs_agnumber_t agno;
1674 xfs_agino_t agino; 1674 xfs_agino_t agino;
1675 xfs_agino_t next_agino; 1675 xfs_agino_t next_agino;
1676 xfs_buf_t *last_ibp; 1676 xfs_buf_t *last_ibp;
1677 xfs_dinode_t *last_dip = NULL; 1677 xfs_dinode_t *last_dip = NULL;
1678 short bucket_index; 1678 short bucket_index;
1679 int offset, last_offset = 0; 1679 int offset, last_offset = 0;
1680 int error; 1680 int error;
1681 1681
1682 mp = tp->t_mountp; 1682 mp = tp->t_mountp;
1683 agno = XFS_INO_TO_AGNO(mp, ip->i_ino); 1683 agno = XFS_INO_TO_AGNO(mp, ip->i_ino);
1684 1684
1685 /* 1685 /*
1686 * Get the agi buffer first. It ensures lock ordering 1686 * Get the agi buffer first. It ensures lock ordering
1687 * on the list. 1687 * on the list.
1688 */ 1688 */
1689 error = xfs_read_agi(mp, tp, agno, &agibp); 1689 error = xfs_read_agi(mp, tp, agno, &agibp);
1690 if (error) 1690 if (error)
1691 return error; 1691 return error;
1692 1692
1693 agi = XFS_BUF_TO_AGI(agibp); 1693 agi = XFS_BUF_TO_AGI(agibp);
1694 1694
1695 /* 1695 /*
1696 * Get the index into the agi hash table for the 1696 * Get the index into the agi hash table for the
1697 * list this inode will go on. 1697 * list this inode will go on.
1698 */ 1698 */
1699 agino = XFS_INO_TO_AGINO(mp, ip->i_ino); 1699 agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
1700 ASSERT(agino != 0); 1700 ASSERT(agino != 0);
1701 bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; 1701 bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS;
1702 ASSERT(agi->agi_unlinked[bucket_index] != cpu_to_be32(NULLAGINO)); 1702 ASSERT(agi->agi_unlinked[bucket_index] != cpu_to_be32(NULLAGINO));
1703 ASSERT(agi->agi_unlinked[bucket_index]); 1703 ASSERT(agi->agi_unlinked[bucket_index]);
1704 1704
1705 if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) { 1705 if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) {
1706 /* 1706 /*
1707 * We're at the head of the list. Get the inode's on-disk 1707 * We're at the head of the list. Get the inode's on-disk
1708 * buffer to see if there is anyone after us on the list. 1708 * buffer to see if there is anyone after us on the list.
1709 * Only modify our next pointer if it is not already NULLAGINO. 1709 * Only modify our next pointer if it is not already NULLAGINO.
1710 * This saves us the overhead of dealing with the buffer when 1710 * This saves us the overhead of dealing with the buffer when
1711 * there is no need to change it. 1711 * there is no need to change it.
1712 */ 1712 */
1713 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp, 1713 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp,
1714 0, 0); 1714 0, 0);
1715 if (error) { 1715 if (error) {
1716 xfs_warn(mp, "%s: xfs_imap_to_bp returned error %d.", 1716 xfs_warn(mp, "%s: xfs_imap_to_bp returned error %d.",
1717 __func__, error); 1717 __func__, error);
1718 return error; 1718 return error;
1719 } 1719 }
1720 next_agino = be32_to_cpu(dip->di_next_unlinked); 1720 next_agino = be32_to_cpu(dip->di_next_unlinked);
1721 ASSERT(next_agino != 0); 1721 ASSERT(next_agino != 0);
1722 if (next_agino != NULLAGINO) { 1722 if (next_agino != NULLAGINO) {
1723 dip->di_next_unlinked = cpu_to_be32(NULLAGINO); 1723 dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
1724 offset = ip->i_imap.im_boffset + 1724 offset = ip->i_imap.im_boffset +
1725 offsetof(xfs_dinode_t, di_next_unlinked); 1725 offsetof(xfs_dinode_t, di_next_unlinked);
1726 xfs_trans_inode_buf(tp, ibp); 1726 xfs_trans_inode_buf(tp, ibp);
1727 xfs_trans_log_buf(tp, ibp, offset, 1727 xfs_trans_log_buf(tp, ibp, offset,
1728 (offset + sizeof(xfs_agino_t) - 1)); 1728 (offset + sizeof(xfs_agino_t) - 1));
1729 xfs_inobp_check(mp, ibp); 1729 xfs_inobp_check(mp, ibp);
1730 } else { 1730 } else {
1731 xfs_trans_brelse(tp, ibp); 1731 xfs_trans_brelse(tp, ibp);
1732 } 1732 }
1733 /* 1733 /*
1734 * Point the bucket head pointer at the next inode. 1734 * Point the bucket head pointer at the next inode.
1735 */ 1735 */
1736 ASSERT(next_agino != 0); 1736 ASSERT(next_agino != 0);
1737 ASSERT(next_agino != agino); 1737 ASSERT(next_agino != agino);
1738 agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino); 1738 agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino);
1739 offset = offsetof(xfs_agi_t, agi_unlinked) + 1739 offset = offsetof(xfs_agi_t, agi_unlinked) +
1740 (sizeof(xfs_agino_t) * bucket_index); 1740 (sizeof(xfs_agino_t) * bucket_index);
1741 xfs_trans_log_buf(tp, agibp, offset, 1741 xfs_trans_log_buf(tp, agibp, offset,
1742 (offset + sizeof(xfs_agino_t) - 1)); 1742 (offset + sizeof(xfs_agino_t) - 1));
1743 } else { 1743 } else {
1744 /* 1744 /*
1745 * We need to search the list for the inode being freed. 1745 * We need to search the list for the inode being freed.
1746 */ 1746 */
1747 next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); 1747 next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);
1748 last_ibp = NULL; 1748 last_ibp = NULL;
1749 while (next_agino != agino) { 1749 while (next_agino != agino) {
1750 struct xfs_imap imap; 1750 struct xfs_imap imap;
1751 1751
1752 if (last_ibp) 1752 if (last_ibp)
1753 xfs_trans_brelse(tp, last_ibp); 1753 xfs_trans_brelse(tp, last_ibp);
1754 1754
1755 imap.im_blkno = 0; 1755 imap.im_blkno = 0;
1756 next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino); 1756 next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino);
1757 1757
1758 error = xfs_imap(mp, tp, next_ino, &imap, 0); 1758 error = xfs_imap(mp, tp, next_ino, &imap, 0);
1759 if (error) { 1759 if (error) {
1760 xfs_warn(mp, 1760 xfs_warn(mp,
1761 "%s: xfs_imap returned error %d.", 1761 "%s: xfs_imap returned error %d.",
1762 __func__, error); 1762 __func__, error);
1763 return error; 1763 return error;
1764 } 1764 }
1765 1765
1766 error = xfs_imap_to_bp(mp, tp, &imap, &last_dip, 1766 error = xfs_imap_to_bp(mp, tp, &imap, &last_dip,
1767 &last_ibp, 0, 0); 1767 &last_ibp, 0, 0);
1768 if (error) { 1768 if (error) {
1769 xfs_warn(mp, 1769 xfs_warn(mp,
1770 "%s: xfs_imap_to_bp returned error %d.", 1770 "%s: xfs_imap_to_bp returned error %d.",
1771 __func__, error); 1771 __func__, error);
1772 return error; 1772 return error;
1773 } 1773 }
1774 1774
1775 last_offset = imap.im_boffset; 1775 last_offset = imap.im_boffset;
1776 next_agino = be32_to_cpu(last_dip->di_next_unlinked); 1776 next_agino = be32_to_cpu(last_dip->di_next_unlinked);
1777 ASSERT(next_agino != NULLAGINO); 1777 ASSERT(next_agino != NULLAGINO);
1778 ASSERT(next_agino != 0); 1778 ASSERT(next_agino != 0);
1779 } 1779 }
1780 1780
1781 /* 1781 /*
1782 * Now last_ibp points to the buffer previous to us on the 1782 * Now last_ibp points to the buffer previous to us on the
1783 * unlinked list. Pull us from the list. 1783 * unlinked list. Pull us from the list.
1784 */ 1784 */
1785 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp, 1785 error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &dip, &ibp,
1786 0, 0); 1786 0, 0);
1787 if (error) { 1787 if (error) {
1788 xfs_warn(mp, "%s: xfs_imap_to_bp(2) returned error %d.", 1788 xfs_warn(mp, "%s: xfs_imap_to_bp(2) returned error %d.",
1789 __func__, error); 1789 __func__, error);
1790 return error; 1790 return error;
1791 } 1791 }
1792 next_agino = be32_to_cpu(dip->di_next_unlinked); 1792 next_agino = be32_to_cpu(dip->di_next_unlinked);
1793 ASSERT(next_agino != 0); 1793 ASSERT(next_agino != 0);
1794 ASSERT(next_agino != agino); 1794 ASSERT(next_agino != agino);
1795 if (next_agino != NULLAGINO) { 1795 if (next_agino != NULLAGINO) {
1796 dip->di_next_unlinked = cpu_to_be32(NULLAGINO); 1796 dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
1797 offset = ip->i_imap.im_boffset + 1797 offset = ip->i_imap.im_boffset +
1798 offsetof(xfs_dinode_t, di_next_unlinked); 1798 offsetof(xfs_dinode_t, di_next_unlinked);
1799 xfs_trans_inode_buf(tp, ibp); 1799 xfs_trans_inode_buf(tp, ibp);
1800 xfs_trans_log_buf(tp, ibp, offset, 1800 xfs_trans_log_buf(tp, ibp, offset,
1801 (offset + sizeof(xfs_agino_t) - 1)); 1801 (offset + sizeof(xfs_agino_t) - 1));
1802 xfs_inobp_check(mp, ibp); 1802 xfs_inobp_check(mp, ibp);
1803 } else { 1803 } else {
1804 xfs_trans_brelse(tp, ibp); 1804 xfs_trans_brelse(tp, ibp);
1805 } 1805 }
1806 /* 1806 /*
1807 * Point the previous inode on the list to the next inode. 1807 * Point the previous inode on the list to the next inode.
1808 */ 1808 */
1809 last_dip->di_next_unlinked = cpu_to_be32(next_agino); 1809 last_dip->di_next_unlinked = cpu_to_be32(next_agino);
1810 ASSERT(next_agino != 0); 1810 ASSERT(next_agino != 0);
1811 offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked); 1811 offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked);
1812 xfs_trans_inode_buf(tp, last_ibp); 1812 xfs_trans_inode_buf(tp, last_ibp);
1813 xfs_trans_log_buf(tp, last_ibp, offset, 1813 xfs_trans_log_buf(tp, last_ibp, offset,
1814 (offset + sizeof(xfs_agino_t) - 1)); 1814 (offset + sizeof(xfs_agino_t) - 1));
1815 xfs_inobp_check(mp, last_ibp); 1815 xfs_inobp_check(mp, last_ibp);
1816 } 1816 }
1817 return 0; 1817 return 0;
1818 } 1818 }
1819 1819
1820 /* 1820 /*
1821 * A big issue when freeing the inode cluster is is that we _cannot_ skip any 1821 * A big issue when freeing the inode cluster is is that we _cannot_ skip any
1822 * inodes that are in memory - they all must be marked stale and attached to 1822 * inodes that are in memory - they all must be marked stale and attached to
1823 * the cluster buffer. 1823 * the cluster buffer.
1824 */ 1824 */
1825 STATIC int 1825 STATIC int
1826 xfs_ifree_cluster( 1826 xfs_ifree_cluster(
1827 xfs_inode_t *free_ip, 1827 xfs_inode_t *free_ip,
1828 xfs_trans_t *tp, 1828 xfs_trans_t *tp,
1829 xfs_ino_t inum) 1829 xfs_ino_t inum)
1830 { 1830 {
1831 xfs_mount_t *mp = free_ip->i_mount; 1831 xfs_mount_t *mp = free_ip->i_mount;
1832 int blks_per_cluster; 1832 int blks_per_cluster;
1833 int nbufs; 1833 int nbufs;
1834 int ninodes; 1834 int ninodes;
1835 int i, j; 1835 int i, j;
1836 xfs_daddr_t blkno; 1836 xfs_daddr_t blkno;
1837 xfs_buf_t *bp; 1837 xfs_buf_t *bp;
1838 xfs_inode_t *ip; 1838 xfs_inode_t *ip;
1839 xfs_inode_log_item_t *iip; 1839 xfs_inode_log_item_t *iip;
1840 xfs_log_item_t *lip; 1840 xfs_log_item_t *lip;
1841 struct xfs_perag *pag; 1841 struct xfs_perag *pag;
1842 1842
1843 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum)); 1843 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum));
1844 if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { 1844 if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {
1845 blks_per_cluster = 1; 1845 blks_per_cluster = 1;
1846 ninodes = mp->m_sb.sb_inopblock; 1846 ninodes = mp->m_sb.sb_inopblock;
1847 nbufs = XFS_IALLOC_BLOCKS(mp); 1847 nbufs = XFS_IALLOC_BLOCKS(mp);
1848 } else { 1848 } else {
1849 blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) / 1849 blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) /
1850 mp->m_sb.sb_blocksize; 1850 mp->m_sb.sb_blocksize;
1851 ninodes = blks_per_cluster * mp->m_sb.sb_inopblock; 1851 ninodes = blks_per_cluster * mp->m_sb.sb_inopblock;
1852 nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster; 1852 nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster;
1853 } 1853 }
1854 1854
1855 for (j = 0; j < nbufs; j++, inum += ninodes) { 1855 for (j = 0; j < nbufs; j++, inum += ninodes) {
1856 blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), 1856 blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum),
1857 XFS_INO_TO_AGBNO(mp, inum)); 1857 XFS_INO_TO_AGBNO(mp, inum));
1858 1858
1859 /* 1859 /*
1860 * We obtain and lock the backing buffer first in the process 1860 * We obtain and lock the backing buffer first in the process
1861 * here, as we have to ensure that any dirty inode that we 1861 * here, as we have to ensure that any dirty inode that we
1862 * can't get the flush lock on is attached to the buffer. 1862 * can't get the flush lock on is attached to the buffer.
1863 * If we scan the in-memory inodes first, then buffer IO can 1863 * If we scan the in-memory inodes first, then buffer IO can
1864 * complete before we get a lock on it, and hence we may fail 1864 * complete before we get a lock on it, and hence we may fail
1865 * to mark all the active inodes on the buffer stale. 1865 * to mark all the active inodes on the buffer stale.
1866 */ 1866 */
1867 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, 1867 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
1868 mp->m_bsize * blks_per_cluster, 1868 mp->m_bsize * blks_per_cluster,
1869 XBF_UNMAPPED); 1869 XBF_UNMAPPED);
1870 1870
1871 if (!bp) 1871 if (!bp)
1872 return ENOMEM; 1872 return ENOMEM;
1873 1873
1874 /* 1874 /*
1875 * This buffer may not have been correctly initialised as we 1875 * This buffer may not have been correctly initialised as we
1876 * didn't read it from disk. That's not important because we are 1876 * didn't read it from disk. That's not important because we are
1877 * only using to mark the buffer as stale in the log, and to 1877 * only using to mark the buffer as stale in the log, and to
1878 * attach stale cached inodes on it. That means it will never be 1878 * attach stale cached inodes on it. That means it will never be
1879 * dispatched for IO. If it is, we want to know about it, and we 1879 * dispatched for IO. If it is, we want to know about it, and we
1880 * want it to fail. We can acheive this by adding a write 1880 * want it to fail. We can acheive this by adding a write
1881 * verifier to the buffer. 1881 * verifier to the buffer.
1882 */ 1882 */
1883 bp->b_ops = &xfs_inode_buf_ops; 1883 bp->b_ops = &xfs_inode_buf_ops;
1884 1884
1885 /* 1885 /*
1886 * Walk the inodes already attached to the buffer and mark them 1886 * Walk the inodes already attached to the buffer and mark them
1887 * stale. These will all have the flush locks held, so an 1887 * stale. These will all have the flush locks held, so an
1888 * in-memory inode walk can't lock them. By marking them all 1888 * in-memory inode walk can't lock them. By marking them all
1889 * stale first, we will not attempt to lock them in the loop 1889 * stale first, we will not attempt to lock them in the loop
1890 * below as the XFS_ISTALE flag will be set. 1890 * below as the XFS_ISTALE flag will be set.
1891 */ 1891 */
1892 lip = bp->b_fspriv; 1892 lip = bp->b_fspriv;
1893 while (lip) { 1893 while (lip) {
1894 if (lip->li_type == XFS_LI_INODE) { 1894 if (lip->li_type == XFS_LI_INODE) {
1895 iip = (xfs_inode_log_item_t *)lip; 1895 iip = (xfs_inode_log_item_t *)lip;
1896 ASSERT(iip->ili_logged == 1); 1896 ASSERT(iip->ili_logged == 1);
1897 lip->li_cb = xfs_istale_done; 1897 lip->li_cb = xfs_istale_done;
1898 xfs_trans_ail_copy_lsn(mp->m_ail, 1898 xfs_trans_ail_copy_lsn(mp->m_ail,
1899 &iip->ili_flush_lsn, 1899 &iip->ili_flush_lsn,
1900 &iip->ili_item.li_lsn); 1900 &iip->ili_item.li_lsn);
1901 xfs_iflags_set(iip->ili_inode, XFS_ISTALE); 1901 xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
1902 } 1902 }
1903 lip = lip->li_bio_list; 1903 lip = lip->li_bio_list;
1904 } 1904 }
1905 1905
1906 1906
1907 /* 1907 /*
1908 * For each inode in memory attempt to add it to the inode 1908 * For each inode in memory attempt to add it to the inode
1909 * buffer and set it up for being staled on buffer IO 1909 * buffer and set it up for being staled on buffer IO
1910 * completion. This is safe as we've locked out tail pushing 1910 * completion. This is safe as we've locked out tail pushing
1911 * and flushing by locking the buffer. 1911 * and flushing by locking the buffer.
1912 * 1912 *
1913 * We have already marked every inode that was part of a 1913 * We have already marked every inode that was part of a
1914 * transaction stale above, which means there is no point in 1914 * transaction stale above, which means there is no point in
1915 * even trying to lock them. 1915 * even trying to lock them.
1916 */ 1916 */
1917 for (i = 0; i < ninodes; i++) { 1917 for (i = 0; i < ninodes; i++) {
1918 retry: 1918 retry:
1919 rcu_read_lock(); 1919 rcu_read_lock();
1920 ip = radix_tree_lookup(&pag->pag_ici_root, 1920 ip = radix_tree_lookup(&pag->pag_ici_root,
1921 XFS_INO_TO_AGINO(mp, (inum + i))); 1921 XFS_INO_TO_AGINO(mp, (inum + i)));
1922 1922
1923 /* Inode not in memory, nothing to do */ 1923 /* Inode not in memory, nothing to do */
1924 if (!ip) { 1924 if (!ip) {
1925 rcu_read_unlock(); 1925 rcu_read_unlock();
1926 continue; 1926 continue;
1927 } 1927 }
1928 1928
1929 /* 1929 /*
1930 * because this is an RCU protected lookup, we could 1930 * because this is an RCU protected lookup, we could
1931 * find a recently freed or even reallocated inode 1931 * find a recently freed or even reallocated inode
1932 * during the lookup. We need to check under the 1932 * during the lookup. We need to check under the
1933 * i_flags_lock for a valid inode here. Skip it if it 1933 * i_flags_lock for a valid inode here. Skip it if it
1934 * is not valid, the wrong inode or stale. 1934 * is not valid, the wrong inode or stale.
1935 */ 1935 */
1936 spin_lock(&ip->i_flags_lock); 1936 spin_lock(&ip->i_flags_lock);
1937 if (ip->i_ino != inum + i || 1937 if (ip->i_ino != inum + i ||
1938 __xfs_iflags_test(ip, XFS_ISTALE)) { 1938 __xfs_iflags_test(ip, XFS_ISTALE)) {
1939 spin_unlock(&ip->i_flags_lock); 1939 spin_unlock(&ip->i_flags_lock);
1940 rcu_read_unlock(); 1940 rcu_read_unlock();
1941 continue; 1941 continue;
1942 } 1942 }
1943 spin_unlock(&ip->i_flags_lock); 1943 spin_unlock(&ip->i_flags_lock);
1944 1944
1945 /* 1945 /*
1946 * Don't try to lock/unlock the current inode, but we 1946 * Don't try to lock/unlock the current inode, but we
1947 * _cannot_ skip the other inodes that we did not find 1947 * _cannot_ skip the other inodes that we did not find
1948 * in the list attached to the buffer and are not 1948 * in the list attached to the buffer and are not
1949 * already marked stale. If we can't lock it, back off 1949 * already marked stale. If we can't lock it, back off
1950 * and retry. 1950 * and retry.
1951 */ 1951 */
1952 if (ip != free_ip && 1952 if (ip != free_ip &&
1953 !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { 1953 !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
1954 rcu_read_unlock(); 1954 rcu_read_unlock();
1955 delay(1); 1955 delay(1);
1956 goto retry; 1956 goto retry;
1957 } 1957 }
1958 rcu_read_unlock(); 1958 rcu_read_unlock();
1959 1959
1960 xfs_iflock(ip); 1960 xfs_iflock(ip);
1961 xfs_iflags_set(ip, XFS_ISTALE); 1961 xfs_iflags_set(ip, XFS_ISTALE);
1962 1962
1963 /* 1963 /*
1964 * we don't need to attach clean inodes or those only 1964 * we don't need to attach clean inodes or those only
1965 * with unlogged changes (which we throw away, anyway). 1965 * with unlogged changes (which we throw away, anyway).
1966 */ 1966 */
1967 iip = ip->i_itemp; 1967 iip = ip->i_itemp;
1968 if (!iip || xfs_inode_clean(ip)) { 1968 if (!iip || xfs_inode_clean(ip)) {
1969 ASSERT(ip != free_ip); 1969 ASSERT(ip != free_ip);
1970 xfs_ifunlock(ip); 1970 xfs_ifunlock(ip);
1971 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1971 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1972 continue; 1972 continue;
1973 } 1973 }
1974 1974
1975 iip->ili_last_fields = iip->ili_fields; 1975 iip->ili_last_fields = iip->ili_fields;
1976 iip->ili_fields = 0; 1976 iip->ili_fields = 0;
1977 iip->ili_logged = 1; 1977 iip->ili_logged = 1;
1978 xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, 1978 xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
1979 &iip->ili_item.li_lsn); 1979 &iip->ili_item.li_lsn);
1980 1980
1981 xfs_buf_attach_iodone(bp, xfs_istale_done, 1981 xfs_buf_attach_iodone(bp, xfs_istale_done,
1982 &iip->ili_item); 1982 &iip->ili_item);
1983 1983
1984 if (ip != free_ip) 1984 if (ip != free_ip)
1985 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1985 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1986 } 1986 }
1987 1987
1988 xfs_trans_stale_inode_buf(tp, bp); 1988 xfs_trans_stale_inode_buf(tp, bp);
1989 xfs_trans_binval(tp, bp); 1989 xfs_trans_binval(tp, bp);
1990 } 1990 }
1991 1991
1992 xfs_perag_put(pag); 1992 xfs_perag_put(pag);
1993 return 0; 1993 return 0;
1994 } 1994 }
1995 1995
1996 /* 1996 /*
1997 * This is called to return an inode to the inode free list. 1997 * This is called to return an inode to the inode free list.
1998 * The inode should already be truncated to 0 length and have 1998 * The inode should already be truncated to 0 length and have
1999 * no pages associated with it. This routine also assumes that 1999 * no pages associated with it. This routine also assumes that
2000 * the inode is already a part of the transaction. 2000 * the inode is already a part of the transaction.
2001 * 2001 *
2002 * The on-disk copy of the inode will have been added to the list 2002 * The on-disk copy of the inode will have been added to the list
2003 * of unlinked inodes in the AGI. We need to remove the inode from 2003 * of unlinked inodes in the AGI. We need to remove the inode from
2004 * that list atomically with respect to freeing it here. 2004 * that list atomically with respect to freeing it here.
2005 */ 2005 */
2006 int 2006 int
2007 xfs_ifree( 2007 xfs_ifree(
2008 xfs_trans_t *tp, 2008 xfs_trans_t *tp,
2009 xfs_inode_t *ip, 2009 xfs_inode_t *ip,
2010 xfs_bmap_free_t *flist) 2010 xfs_bmap_free_t *flist)
2011 { 2011 {
2012 int error; 2012 int error;
2013 int delete; 2013 int delete;
2014 xfs_ino_t first_ino; 2014 xfs_ino_t first_ino;
2015 xfs_dinode_t *dip; 2015 xfs_dinode_t *dip;
2016 xfs_buf_t *ibp; 2016 xfs_buf_t *ibp;
2017 2017
2018 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); 2018 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
2019 ASSERT(ip->i_d.di_nlink == 0); 2019 ASSERT(ip->i_d.di_nlink == 0);
2020 ASSERT(ip->i_d.di_nextents == 0); 2020 ASSERT(ip->i_d.di_nextents == 0);
2021 ASSERT(ip->i_d.di_anextents == 0); 2021 ASSERT(ip->i_d.di_anextents == 0);
2022 ASSERT(ip->i_d.di_size == 0 || !S_ISREG(ip->i_d.di_mode)); 2022 ASSERT(ip->i_d.di_size == 0 || !S_ISREG(ip->i_d.di_mode));
2023 ASSERT(ip->i_d.di_nblocks == 0); 2023 ASSERT(ip->i_d.di_nblocks == 0);
2024 2024
2025 /* 2025 /*
2026 * Pull the on-disk inode from the AGI unlinked list. 2026 * Pull the on-disk inode from the AGI unlinked list.
2027 */ 2027 */
2028 error = xfs_iunlink_remove(tp, ip); 2028 error = xfs_iunlink_remove(tp, ip);
2029 if (error != 0) { 2029 if (error != 0) {
2030 return error; 2030 return error;
2031 } 2031 }
2032 2032
2033 error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino); 2033 error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino);
2034 if (error != 0) { 2034 if (error != 0) {
2035 return error; 2035 return error;
2036 } 2036 }
2037 ip->i_d.di_mode = 0; /* mark incore inode as free */ 2037 ip->i_d.di_mode = 0; /* mark incore inode as free */
2038 ip->i_d.di_flags = 0; 2038 ip->i_d.di_flags = 0;
2039 ip->i_d.di_dmevmask = 0; 2039 ip->i_d.di_dmevmask = 0;
2040 ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ 2040 ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */
2041 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS; 2041 ip->i_d.di_format = XFS_DINODE_FMT_EXTENTS;
2042 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS; 2042 ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
2043 /* 2043 /*
2044 * Bump the generation count so no one will be confused 2044 * Bump the generation count so no one will be confused
2045 * by reincarnations of this inode. 2045 * by reincarnations of this inode.
2046 */ 2046 */
2047 ip->i_d.di_gen++; 2047 ip->i_d.di_gen++;
2048 2048
2049 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 2049 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
2050 2050
2051 error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &dip, &ibp, 2051 error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &dip, &ibp,
2052 0, 0); 2052 0, 0);
2053 if (error) 2053 if (error)
2054 return error; 2054 return error;
2055 2055
2056 /* 2056 /*
2057 * Clear the on-disk di_mode. This is to prevent xfs_bulkstat 2057 * Clear the on-disk di_mode. This is to prevent xfs_bulkstat
2058 * from picking up this inode when it is reclaimed (its incore state 2058 * from picking up this inode when it is reclaimed (its incore state
2059 * initialzed but not flushed to disk yet). The in-core di_mode is 2059 * initialzed but not flushed to disk yet). The in-core di_mode is
2060 * already cleared and a corresponding transaction logged. 2060 * already cleared and a corresponding transaction logged.
2061 * The hack here just synchronizes the in-core to on-disk 2061 * The hack here just synchronizes the in-core to on-disk
2062 * di_mode value in advance before the actual inode sync to disk. 2062 * di_mode value in advance before the actual inode sync to disk.
2063 * This is OK because the inode is already unlinked and would never 2063 * This is OK because the inode is already unlinked and would never
2064 * change its di_mode again for this inode generation. 2064 * change its di_mode again for this inode generation.
2065 * This is a temporary hack that would require a proper fix 2065 * This is a temporary hack that would require a proper fix
2066 * in the future. 2066 * in the future.
2067 */ 2067 */
2068 dip->di_mode = 0; 2068 dip->di_mode = 0;
2069 2069
2070 if (delete) { 2070 if (delete) {
2071 error = xfs_ifree_cluster(ip, tp, first_ino); 2071 error = xfs_ifree_cluster(ip, tp, first_ino);
2072 } 2072 }
2073 2073
2074 return error; 2074 return error;
2075 } 2075 }
2076 2076
2077 /* 2077 /*
2078 * Reallocate the space for if_broot based on the number of records 2078 * Reallocate the space for if_broot based on the number of records
2079 * being added or deleted as indicated in rec_diff. Move the records 2079 * being added or deleted as indicated in rec_diff. Move the records
2080 * and pointers in if_broot to fit the new size. When shrinking this 2080 * and pointers in if_broot to fit the new size. When shrinking this
2081 * will eliminate holes between the records and pointers created by 2081 * will eliminate holes between the records and pointers created by
2082 * the caller. When growing this will create holes to be filled in 2082 * the caller. When growing this will create holes to be filled in
2083 * by the caller. 2083 * by the caller.
2084 * 2084 *
2085 * The caller must not request to add more records than would fit in 2085 * The caller must not request to add more records than would fit in
2086 * the on-disk inode root. If the if_broot is currently NULL, then 2086 * the on-disk inode root. If the if_broot is currently NULL, then
2087 * if we adding records one will be allocated. The caller must also 2087 * if we adding records one will be allocated. The caller must also
2088 * not request that the number of records go below zero, although 2088 * not request that the number of records go below zero, although
2089 * it can go to zero. 2089 * it can go to zero.
2090 * 2090 *
2091 * ip -- the inode whose if_broot area is changing 2091 * ip -- the inode whose if_broot area is changing
2092 * ext_diff -- the change in the number of records, positive or negative, 2092 * ext_diff -- the change in the number of records, positive or negative,
2093 * requested for the if_broot array. 2093 * requested for the if_broot array.
2094 */ 2094 */
2095 void 2095 void
2096 xfs_iroot_realloc( 2096 xfs_iroot_realloc(
2097 xfs_inode_t *ip, 2097 xfs_inode_t *ip,
2098 int rec_diff, 2098 int rec_diff,
2099 int whichfork) 2099 int whichfork)
2100 { 2100 {
2101 struct xfs_mount *mp = ip->i_mount; 2101 struct xfs_mount *mp = ip->i_mount;
2102 int cur_max; 2102 int cur_max;
2103 xfs_ifork_t *ifp; 2103 xfs_ifork_t *ifp;
2104 struct xfs_btree_block *new_broot; 2104 struct xfs_btree_block *new_broot;
2105 int new_max; 2105 int new_max;
2106 size_t new_size; 2106 size_t new_size;
2107 char *np; 2107 char *np;
2108 char *op; 2108 char *op;
2109 2109
2110 /* 2110 /*
2111 * Handle the degenerate case quietly. 2111 * Handle the degenerate case quietly.
2112 */ 2112 */
2113 if (rec_diff == 0) { 2113 if (rec_diff == 0) {
2114 return; 2114 return;
2115 } 2115 }
2116 2116
2117 ifp = XFS_IFORK_PTR(ip, whichfork); 2117 ifp = XFS_IFORK_PTR(ip, whichfork);
2118 if (rec_diff > 0) { 2118 if (rec_diff > 0) {
2119 /* 2119 /*
2120 * If there wasn't any memory allocated before, just 2120 * If there wasn't any memory allocated before, just
2121 * allocate it now and get out. 2121 * allocate it now and get out.
2122 */ 2122 */
2123 if (ifp->if_broot_bytes == 0) { 2123 if (ifp->if_broot_bytes == 0) {
2124 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff); 2124 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, rec_diff);
2125 ifp->if_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS); 2125 ifp->if_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS);
2126 ifp->if_broot_bytes = (int)new_size; 2126 ifp->if_broot_bytes = (int)new_size;
2127 return; 2127 return;
2128 } 2128 }
2129 2129
2130 /* 2130 /*
2131 * If there is already an existing if_broot, then we need 2131 * If there is already an existing if_broot, then we need
2132 * to realloc() it and shift the pointers to their new 2132 * to realloc() it and shift the pointers to their new
2133 * location. The records don't change location because 2133 * location. The records don't change location because
2134 * they are kept butted up against the btree block header. 2134 * they are kept butted up against the btree block header.
2135 */ 2135 */
2136 cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); 2136 cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
2137 new_max = cur_max + rec_diff; 2137 new_max = cur_max + rec_diff;
2138 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max); 2138 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
2139 ifp->if_broot = kmem_realloc(ifp->if_broot, new_size, 2139 ifp->if_broot = kmem_realloc(ifp->if_broot, new_size,
2140 XFS_BMAP_BROOT_SPACE_CALC(mp, cur_max), 2140 XFS_BMAP_BROOT_SPACE_CALC(mp, cur_max),
2141 KM_SLEEP | KM_NOFS); 2141 KM_SLEEP | KM_NOFS);
2142 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, 2142 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
2143 ifp->if_broot_bytes); 2143 ifp->if_broot_bytes);
2144 np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, 2144 np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
2145 (int)new_size); 2145 (int)new_size);
2146 ifp->if_broot_bytes = (int)new_size; 2146 ifp->if_broot_bytes = (int)new_size;
2147 ASSERT(ifp->if_broot_bytes <= 2147 ASSERT(ifp->if_broot_bytes <=
2148 XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ(ip)); 2148 XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ(ip));
2149 memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t)); 2149 memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t));
2150 return; 2150 return;
2151 } 2151 }
2152 2152
2153 /* 2153 /*
2154 * rec_diff is less than 0. In this case, we are shrinking the 2154 * rec_diff is less than 0. In this case, we are shrinking the
2155 * if_broot buffer. It must already exist. If we go to zero 2155 * if_broot buffer. It must already exist. If we go to zero
2156 * records, just get rid of the root and clear the status bit. 2156 * records, just get rid of the root and clear the status bit.
2157 */ 2157 */
2158 ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0)); 2158 ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0));
2159 cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); 2159 cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0);
2160 new_max = cur_max + rec_diff; 2160 new_max = cur_max + rec_diff;
2161 ASSERT(new_max >= 0); 2161 ASSERT(new_max >= 0);
2162 if (new_max > 0) 2162 if (new_max > 0)
2163 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max); 2163 new_size = XFS_BMAP_BROOT_SPACE_CALC(mp, new_max);
2164 else 2164 else
2165 new_size = 0; 2165 new_size = 0;
2166 if (new_size > 0) { 2166 if (new_size > 0) {
2167 new_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS); 2167 new_broot = kmem_alloc(new_size, KM_SLEEP | KM_NOFS);
2168 /* 2168 /*
2169 * First copy over the btree block header. 2169 * First copy over the btree block header.
2170 */ 2170 */
2171 memcpy(new_broot, ifp->if_broot, 2171 memcpy(new_broot, ifp->if_broot,
2172 XFS_BMBT_BLOCK_LEN(ip->i_mount)); 2172 XFS_BMBT_BLOCK_LEN(ip->i_mount));
2173 } else { 2173 } else {
2174 new_broot = NULL; 2174 new_broot = NULL;
2175 ifp->if_flags &= ~XFS_IFBROOT; 2175 ifp->if_flags &= ~XFS_IFBROOT;
2176 } 2176 }
2177 2177
2178 /* 2178 /*
2179 * Only copy the records and pointers if there are any. 2179 * Only copy the records and pointers if there are any.
2180 */ 2180 */
2181 if (new_max > 0) { 2181 if (new_max > 0) {
2182 /* 2182 /*
2183 * First copy the records. 2183 * First copy the records.
2184 */ 2184 */
2185 op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1); 2185 op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1);
2186 np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1); 2186 np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1);
2187 memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); 2187 memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t));
2188 2188
2189 /* 2189 /*
2190 * Then copy the pointers. 2190 * Then copy the pointers.
2191 */ 2191 */
2192 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, 2192 op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1,
2193 ifp->if_broot_bytes); 2193 ifp->if_broot_bytes);
2194 np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1, 2194 np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1,
2195 (int)new_size); 2195 (int)new_size);
2196 memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); 2196 memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t));
2197 } 2197 }
2198 kmem_free(ifp->if_broot); 2198 kmem_free(ifp->if_broot);
2199 ifp->if_broot = new_broot; 2199 ifp->if_broot = new_broot;
2200 ifp->if_broot_bytes = (int)new_size; 2200 ifp->if_broot_bytes = (int)new_size;
2201 ASSERT(ifp->if_broot_bytes <= 2201 ASSERT(ifp->if_broot_bytes <=
2202 XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ(ip)); 2202 XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ(ip));
2203 return; 2203 return;
2204 } 2204 }
2205 2205
2206 2206
2207 /* 2207 /*
2208 * This is called when the amount of space needed for if_data 2208 * This is called when the amount of space needed for if_data
2209 * is increased or decreased. The change in size is indicated by 2209 * is increased or decreased. The change in size is indicated by
2210 * the number of bytes that need to be added or deleted in the 2210 * the number of bytes that need to be added or deleted in the
2211 * byte_diff parameter. 2211 * byte_diff parameter.
2212 * 2212 *
2213 * If the amount of space needed has decreased below the size of the 2213 * If the amount of space needed has decreased below the size of the
2214 * inline buffer, then switch to using the inline buffer. Otherwise, 2214 * inline buffer, then switch to using the inline buffer. Otherwise,
2215 * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer 2215 * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
2216 * to what is needed. 2216 * to what is needed.
2217 * 2217 *
2218 * ip -- the inode whose if_data area is changing 2218 * ip -- the inode whose if_data area is changing
2219 * byte_diff -- the change in the number of bytes, positive or negative, 2219 * byte_diff -- the change in the number of bytes, positive or negative,
2220 * requested for the if_data array. 2220 * requested for the if_data array.
2221 */ 2221 */
2222 void 2222 void
2223 xfs_idata_realloc( 2223 xfs_idata_realloc(
2224 xfs_inode_t *ip, 2224 xfs_inode_t *ip,
2225 int byte_diff, 2225 int byte_diff,
2226 int whichfork) 2226 int whichfork)
2227 { 2227 {
2228 xfs_ifork_t *ifp; 2228 xfs_ifork_t *ifp;
2229 int new_size; 2229 int new_size;
2230 int real_size; 2230 int real_size;
2231 2231
2232 if (byte_diff == 0) { 2232 if (byte_diff == 0) {
2233 return; 2233 return;
2234 } 2234 }
2235 2235
2236 ifp = XFS_IFORK_PTR(ip, whichfork); 2236 ifp = XFS_IFORK_PTR(ip, whichfork);
2237 new_size = (int)ifp->if_bytes + byte_diff; 2237 new_size = (int)ifp->if_bytes + byte_diff;
2238 ASSERT(new_size >= 0); 2238 ASSERT(new_size >= 0);
2239 2239
2240 if (new_size == 0) { 2240 if (new_size == 0) {
2241 if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { 2241 if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
2242 kmem_free(ifp->if_u1.if_data); 2242 kmem_free(ifp->if_u1.if_data);
2243 } 2243 }
2244 ifp->if_u1.if_data = NULL; 2244 ifp->if_u1.if_data = NULL;
2245 real_size = 0; 2245 real_size = 0;
2246 } else if (new_size <= sizeof(ifp->if_u2.if_inline_data)) { 2246 } else if (new_size <= sizeof(ifp->if_u2.if_inline_data)) {
2247 /* 2247 /*
2248 * If the valid extents/data can fit in if_inline_ext/data, 2248 * If the valid extents/data can fit in if_inline_ext/data,
2249 * copy them from the malloc'd vector and free it. 2249 * copy them from the malloc'd vector and free it.
2250 */ 2250 */
2251 if (ifp->if_u1.if_data == NULL) { 2251 if (ifp->if_u1.if_data == NULL) {
2252 ifp->if_u1.if_data = ifp->if_u2.if_inline_data; 2252 ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
2253 } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { 2253 } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
2254 ASSERT(ifp->if_real_bytes != 0); 2254 ASSERT(ifp->if_real_bytes != 0);
2255 memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data, 2255 memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data,
2256 new_size); 2256 new_size);
2257 kmem_free(ifp->if_u1.if_data); 2257 kmem_free(ifp->if_u1.if_data);
2258 ifp->if_u1.if_data = ifp->if_u2.if_inline_data; 2258 ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
2259 } 2259 }
2260 real_size = 0; 2260 real_size = 0;
2261 } else { 2261 } else {
2262 /* 2262 /*
2263 * Stuck with malloc/realloc. 2263 * Stuck with malloc/realloc.
2264 * For inline data, the underlying buffer must be 2264 * For inline data, the underlying buffer must be
2265 * a multiple of 4 bytes in size so that it can be 2265 * a multiple of 4 bytes in size so that it can be
2266 * logged and stay on word boundaries. We enforce 2266 * logged and stay on word boundaries. We enforce
2267 * that here. 2267 * that here.
2268 */ 2268 */
2269 real_size = roundup(new_size, 4); 2269 real_size = roundup(new_size, 4);
2270 if (ifp->if_u1.if_data == NULL) { 2270 if (ifp->if_u1.if_data == NULL) {
2271 ASSERT(ifp->if_real_bytes == 0); 2271 ASSERT(ifp->if_real_bytes == 0);
2272 ifp->if_u1.if_data = kmem_alloc(real_size, 2272 ifp->if_u1.if_data = kmem_alloc(real_size,
2273 KM_SLEEP | KM_NOFS); 2273 KM_SLEEP | KM_NOFS);
2274 } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { 2274 } else if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
2275 /* 2275 /*
2276 * Only do the realloc if the underlying size 2276 * Only do the realloc if the underlying size
2277 * is really changing. 2277 * is really changing.
2278 */ 2278 */
2279 if (ifp->if_real_bytes != real_size) { 2279 if (ifp->if_real_bytes != real_size) {
2280 ifp->if_u1.if_data = 2280 ifp->if_u1.if_data =
2281 kmem_realloc(ifp->if_u1.if_data, 2281 kmem_realloc(ifp->if_u1.if_data,
2282 real_size, 2282 real_size,
2283 ifp->if_real_bytes, 2283 ifp->if_real_bytes,
2284 KM_SLEEP | KM_NOFS); 2284 KM_SLEEP | KM_NOFS);
2285 } 2285 }
2286 } else { 2286 } else {
2287 ASSERT(ifp->if_real_bytes == 0); 2287 ASSERT(ifp->if_real_bytes == 0);
2288 ifp->if_u1.if_data = kmem_alloc(real_size, 2288 ifp->if_u1.if_data = kmem_alloc(real_size,
2289 KM_SLEEP | KM_NOFS); 2289 KM_SLEEP | KM_NOFS);
2290 memcpy(ifp->if_u1.if_data, ifp->if_u2.if_inline_data, 2290 memcpy(ifp->if_u1.if_data, ifp->if_u2.if_inline_data,
2291 ifp->if_bytes); 2291 ifp->if_bytes);
2292 } 2292 }
2293 } 2293 }
2294 ifp->if_real_bytes = real_size; 2294 ifp->if_real_bytes = real_size;
2295 ifp->if_bytes = new_size; 2295 ifp->if_bytes = new_size;
2296 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); 2296 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
2297 } 2297 }
2298 2298
2299 void 2299 void
2300 xfs_idestroy_fork( 2300 xfs_idestroy_fork(
2301 xfs_inode_t *ip, 2301 xfs_inode_t *ip,
2302 int whichfork) 2302 int whichfork)
2303 { 2303 {
2304 xfs_ifork_t *ifp; 2304 xfs_ifork_t *ifp;
2305 2305
2306 ifp = XFS_IFORK_PTR(ip, whichfork); 2306 ifp = XFS_IFORK_PTR(ip, whichfork);
2307 if (ifp->if_broot != NULL) { 2307 if (ifp->if_broot != NULL) {
2308 kmem_free(ifp->if_broot); 2308 kmem_free(ifp->if_broot);
2309 ifp->if_broot = NULL; 2309 ifp->if_broot = NULL;
2310 } 2310 }
2311 2311
2312 /* 2312 /*
2313 * If the format is local, then we can't have an extents 2313 * If the format is local, then we can't have an extents
2314 * array so just look for an inline data array. If we're 2314 * array so just look for an inline data array. If we're
2315 * not local then we may or may not have an extents list, 2315 * not local then we may or may not have an extents list,
2316 * so check and free it up if we do. 2316 * so check and free it up if we do.
2317 */ 2317 */
2318 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { 2318 if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
2319 if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) && 2319 if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) &&
2320 (ifp->if_u1.if_data != NULL)) { 2320 (ifp->if_u1.if_data != NULL)) {
2321 ASSERT(ifp->if_real_bytes != 0); 2321 ASSERT(ifp->if_real_bytes != 0);
2322 kmem_free(ifp->if_u1.if_data); 2322 kmem_free(ifp->if_u1.if_data);
2323 ifp->if_u1.if_data = NULL; 2323 ifp->if_u1.if_data = NULL;
2324 ifp->if_real_bytes = 0; 2324 ifp->if_real_bytes = 0;
2325 } 2325 }
2326 } else if ((ifp->if_flags & XFS_IFEXTENTS) && 2326 } else if ((ifp->if_flags & XFS_IFEXTENTS) &&
2327 ((ifp->if_flags & XFS_IFEXTIREC) || 2327 ((ifp->if_flags & XFS_IFEXTIREC) ||
2328 ((ifp->if_u1.if_extents != NULL) && 2328 ((ifp->if_u1.if_extents != NULL) &&
2329 (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)))) { 2329 (ifp->if_u1.if_extents != ifp->if_u2.if_inline_ext)))) {
2330 ASSERT(ifp->if_real_bytes != 0); 2330 ASSERT(ifp->if_real_bytes != 0);
2331 xfs_iext_destroy(ifp); 2331 xfs_iext_destroy(ifp);
2332 } 2332 }
2333 ASSERT(ifp->if_u1.if_extents == NULL || 2333 ASSERT(ifp->if_u1.if_extents == NULL ||
2334 ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext); 2334 ifp->if_u1.if_extents == ifp->if_u2.if_inline_ext);
2335 ASSERT(ifp->if_real_bytes == 0); 2335 ASSERT(ifp->if_real_bytes == 0);
2336 if (whichfork == XFS_ATTR_FORK) { 2336 if (whichfork == XFS_ATTR_FORK) {
2337 kmem_zone_free(xfs_ifork_zone, ip->i_afp); 2337 kmem_zone_free(xfs_ifork_zone, ip->i_afp);
2338 ip->i_afp = NULL; 2338 ip->i_afp = NULL;
2339 } 2339 }
2340 } 2340 }
2341 2341
2342 /* 2342 /*
2343 * This is called to unpin an inode. The caller must have the inode locked 2343 * This is called to unpin an inode. The caller must have the inode locked
2344 * in at least shared mode so that the buffer cannot be subsequently pinned 2344 * in at least shared mode so that the buffer cannot be subsequently pinned
2345 * once someone is waiting for it to be unpinned. 2345 * once someone is waiting for it to be unpinned.
2346 */ 2346 */
2347 static void 2347 static void
2348 xfs_iunpin( 2348 xfs_iunpin(
2349 struct xfs_inode *ip) 2349 struct xfs_inode *ip)
2350 { 2350 {
2351 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 2351 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
2352 2352
2353 trace_xfs_inode_unpin_nowait(ip, _RET_IP_); 2353 trace_xfs_inode_unpin_nowait(ip, _RET_IP_);
2354 2354
2355 /* Give the log a push to start the unpinning I/O */ 2355 /* Give the log a push to start the unpinning I/O */
2356 xfs_log_force_lsn(ip->i_mount, ip->i_itemp->ili_last_lsn, 0); 2356 xfs_log_force_lsn(ip->i_mount, ip->i_itemp->ili_last_lsn, 0);
2357 2357
2358 } 2358 }
2359 2359
2360 static void 2360 static void
2361 __xfs_iunpin_wait( 2361 __xfs_iunpin_wait(
2362 struct xfs_inode *ip) 2362 struct xfs_inode *ip)
2363 { 2363 {
2364 wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IPINNED_BIT); 2364 wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IPINNED_BIT);
2365 DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IPINNED_BIT); 2365 DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IPINNED_BIT);
2366 2366
2367 xfs_iunpin(ip); 2367 xfs_iunpin(ip);
2368 2368
2369 do { 2369 do {
2370 prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE); 2370 prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
2371 if (xfs_ipincount(ip)) 2371 if (xfs_ipincount(ip))
2372 io_schedule(); 2372 io_schedule();
2373 } while (xfs_ipincount(ip)); 2373 } while (xfs_ipincount(ip));
2374 finish_wait(wq, &wait.wait); 2374 finish_wait(wq, &wait.wait);
2375 } 2375 }
2376 2376
2377 void 2377 void
2378 xfs_iunpin_wait( 2378 xfs_iunpin_wait(
2379 struct xfs_inode *ip) 2379 struct xfs_inode *ip)
2380 { 2380 {
2381 if (xfs_ipincount(ip)) 2381 if (xfs_ipincount(ip))
2382 __xfs_iunpin_wait(ip); 2382 __xfs_iunpin_wait(ip);
2383 } 2383 }
2384 2384
2385 /* 2385 /*
2386 * xfs_iextents_copy() 2386 * xfs_iextents_copy()
2387 * 2387 *
2388 * This is called to copy the REAL extents (as opposed to the delayed 2388 * This is called to copy the REAL extents (as opposed to the delayed
2389 * allocation extents) from the inode into the given buffer. It 2389 * allocation extents) from the inode into the given buffer. It
2390 * returns the number of bytes copied into the buffer. 2390 * returns the number of bytes copied into the buffer.
2391 * 2391 *
2392 * If there are no delayed allocation extents, then we can just 2392 * If there are no delayed allocation extents, then we can just
2393 * memcpy() the extents into the buffer. Otherwise, we need to 2393 * memcpy() the extents into the buffer. Otherwise, we need to
2394 * examine each extent in turn and skip those which are delayed. 2394 * examine each extent in turn and skip those which are delayed.
2395 */ 2395 */
2396 int 2396 int
2397 xfs_iextents_copy( 2397 xfs_iextents_copy(
2398 xfs_inode_t *ip, 2398 xfs_inode_t *ip,
2399 xfs_bmbt_rec_t *dp, 2399 xfs_bmbt_rec_t *dp,
2400 int whichfork) 2400 int whichfork)
2401 { 2401 {
2402 int copied; 2402 int copied;
2403 int i; 2403 int i;
2404 xfs_ifork_t *ifp; 2404 xfs_ifork_t *ifp;
2405 int nrecs; 2405 int nrecs;
2406 xfs_fsblock_t start_block; 2406 xfs_fsblock_t start_block;
2407 2407
2408 ifp = XFS_IFORK_PTR(ip, whichfork); 2408 ifp = XFS_IFORK_PTR(ip, whichfork);
2409 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 2409 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
2410 ASSERT(ifp->if_bytes > 0); 2410 ASSERT(ifp->if_bytes > 0);
2411 2411
2412 nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 2412 nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
2413 XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork); 2413 XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork);
2414 ASSERT(nrecs > 0); 2414 ASSERT(nrecs > 0);
2415 2415
2416 /* 2416 /*
2417 * There are some delayed allocation extents in the 2417 * There are some delayed allocation extents in the
2418 * inode, so copy the extents one at a time and skip 2418 * inode, so copy the extents one at a time and skip
2419 * the delayed ones. There must be at least one 2419 * the delayed ones. There must be at least one
2420 * non-delayed extent. 2420 * non-delayed extent.
2421 */ 2421 */
2422 copied = 0; 2422 copied = 0;
2423 for (i = 0; i < nrecs; i++) { 2423 for (i = 0; i < nrecs; i++) {
2424 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); 2424 xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
2425 start_block = xfs_bmbt_get_startblock(ep); 2425 start_block = xfs_bmbt_get_startblock(ep);
2426 if (isnullstartblock(start_block)) { 2426 if (isnullstartblock(start_block)) {
2427 /* 2427 /*
2428 * It's a delayed allocation extent, so skip it. 2428 * It's a delayed allocation extent, so skip it.
2429 */ 2429 */
2430 continue; 2430 continue;
2431 } 2431 }
2432 2432
2433 /* Translate to on disk format */ 2433 /* Translate to on disk format */
2434 put_unaligned(cpu_to_be64(ep->l0), &dp->l0); 2434 put_unaligned(cpu_to_be64(ep->l0), &dp->l0);
2435 put_unaligned(cpu_to_be64(ep->l1), &dp->l1); 2435 put_unaligned(cpu_to_be64(ep->l1), &dp->l1);
2436 dp++; 2436 dp++;
2437 copied++; 2437 copied++;
2438 } 2438 }
2439 ASSERT(copied != 0); 2439 ASSERT(copied != 0);
2440 xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip)); 2440 xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip));
2441 2441
2442 return (copied * (uint)sizeof(xfs_bmbt_rec_t)); 2442 return (copied * (uint)sizeof(xfs_bmbt_rec_t));
2443 } 2443 }
2444 2444
2445 /* 2445 /*
2446 * Each of the following cases stores data into the same region 2446 * Each of the following cases stores data into the same region
2447 * of the on-disk inode, so only one of them can be valid at 2447 * of the on-disk inode, so only one of them can be valid at
2448 * any given time. While it is possible to have conflicting formats 2448 * any given time. While it is possible to have conflicting formats
2449 * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is 2449 * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is
2450 * in EXTENTS format, this can only happen when the fork has 2450 * in EXTENTS format, this can only happen when the fork has
2451 * changed formats after being modified but before being flushed. 2451 * changed formats after being modified but before being flushed.
2452 * In these cases, the format always takes precedence, because the 2452 * In these cases, the format always takes precedence, because the
2453 * format indicates the current state of the fork. 2453 * format indicates the current state of the fork.
2454 */ 2454 */
2455 /*ARGSUSED*/ 2455 /*ARGSUSED*/
2456 STATIC void 2456 STATIC void
2457 xfs_iflush_fork( 2457 xfs_iflush_fork(
2458 xfs_inode_t *ip, 2458 xfs_inode_t *ip,
2459 xfs_dinode_t *dip, 2459 xfs_dinode_t *dip,
2460 xfs_inode_log_item_t *iip, 2460 xfs_inode_log_item_t *iip,
2461 int whichfork, 2461 int whichfork,
2462 xfs_buf_t *bp) 2462 xfs_buf_t *bp)
2463 { 2463 {
2464 char *cp; 2464 char *cp;
2465 xfs_ifork_t *ifp; 2465 xfs_ifork_t *ifp;
2466 xfs_mount_t *mp; 2466 xfs_mount_t *mp;
2467 static const short brootflag[2] = 2467 static const short brootflag[2] =
2468 { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT }; 2468 { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT };
2469 static const short dataflag[2] = 2469 static const short dataflag[2] =
2470 { XFS_ILOG_DDATA, XFS_ILOG_ADATA }; 2470 { XFS_ILOG_DDATA, XFS_ILOG_ADATA };
2471 static const short extflag[2] = 2471 static const short extflag[2] =
2472 { XFS_ILOG_DEXT, XFS_ILOG_AEXT }; 2472 { XFS_ILOG_DEXT, XFS_ILOG_AEXT };
2473 2473
2474 if (!iip) 2474 if (!iip)
2475 return; 2475 return;
2476 ifp = XFS_IFORK_PTR(ip, whichfork); 2476 ifp = XFS_IFORK_PTR(ip, whichfork);
2477 /* 2477 /*
2478 * This can happen if we gave up in iformat in an error path, 2478 * This can happen if we gave up in iformat in an error path,
2479 * for the attribute fork. 2479 * for the attribute fork.
2480 */ 2480 */
2481 if (!ifp) { 2481 if (!ifp) {
2482 ASSERT(whichfork == XFS_ATTR_FORK); 2482 ASSERT(whichfork == XFS_ATTR_FORK);
2483 return; 2483 return;
2484 } 2484 }
2485 cp = XFS_DFORK_PTR(dip, whichfork); 2485 cp = XFS_DFORK_PTR(dip, whichfork);
2486 mp = ip->i_mount; 2486 mp = ip->i_mount;
2487 switch (XFS_IFORK_FORMAT(ip, whichfork)) { 2487 switch (XFS_IFORK_FORMAT(ip, whichfork)) {
2488 case XFS_DINODE_FMT_LOCAL: 2488 case XFS_DINODE_FMT_LOCAL:
2489 if ((iip->ili_fields & dataflag[whichfork]) && 2489 if ((iip->ili_fields & dataflag[whichfork]) &&
2490 (ifp->if_bytes > 0)) { 2490 (ifp->if_bytes > 0)) {
2491 ASSERT(ifp->if_u1.if_data != NULL); 2491 ASSERT(ifp->if_u1.if_data != NULL);
2492 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); 2492 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
2493 memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); 2493 memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
2494 } 2494 }
2495 break; 2495 break;
2496 2496
2497 case XFS_DINODE_FMT_EXTENTS: 2497 case XFS_DINODE_FMT_EXTENTS:
2498 ASSERT((ifp->if_flags & XFS_IFEXTENTS) || 2498 ASSERT((ifp->if_flags & XFS_IFEXTENTS) ||
2499 !(iip->ili_fields & extflag[whichfork])); 2499 !(iip->ili_fields & extflag[whichfork]));
2500 if ((iip->ili_fields & extflag[whichfork]) && 2500 if ((iip->ili_fields & extflag[whichfork]) &&
2501 (ifp->if_bytes > 0)) { 2501 (ifp->if_bytes > 0)) {
2502 ASSERT(xfs_iext_get_ext(ifp, 0)); 2502 ASSERT(xfs_iext_get_ext(ifp, 0));
2503 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); 2503 ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0);
2504 (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp, 2504 (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,
2505 whichfork); 2505 whichfork);
2506 } 2506 }
2507 break; 2507 break;
2508 2508
2509 case XFS_DINODE_FMT_BTREE: 2509 case XFS_DINODE_FMT_BTREE:
2510 if ((iip->ili_fields & brootflag[whichfork]) && 2510 if ((iip->ili_fields & brootflag[whichfork]) &&
2511 (ifp->if_broot_bytes > 0)) { 2511 (ifp->if_broot_bytes > 0)) {
2512 ASSERT(ifp->if_broot != NULL); 2512 ASSERT(ifp->if_broot != NULL);
2513 ASSERT(ifp->if_broot_bytes <= 2513 ASSERT(ifp->if_broot_bytes <=
2514 (XFS_IFORK_SIZE(ip, whichfork) + 2514 (XFS_IFORK_SIZE(ip, whichfork) +
2515 XFS_BROOT_SIZE_ADJ(ip))); 2515 XFS_BROOT_SIZE_ADJ(ip)));
2516 xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes, 2516 xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes,
2517 (xfs_bmdr_block_t *)cp, 2517 (xfs_bmdr_block_t *)cp,
2518 XFS_DFORK_SIZE(dip, mp, whichfork)); 2518 XFS_DFORK_SIZE(dip, mp, whichfork));
2519 } 2519 }
2520 break; 2520 break;
2521 2521
2522 case XFS_DINODE_FMT_DEV: 2522 case XFS_DINODE_FMT_DEV:
2523 if (iip->ili_fields & XFS_ILOG_DEV) { 2523 if (iip->ili_fields & XFS_ILOG_DEV) {
2524 ASSERT(whichfork == XFS_DATA_FORK); 2524 ASSERT(whichfork == XFS_DATA_FORK);
2525 xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev); 2525 xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev);
2526 } 2526 }
2527 break; 2527 break;
2528 2528
2529 case XFS_DINODE_FMT_UUID: 2529 case XFS_DINODE_FMT_UUID:
2530 if (iip->ili_fields & XFS_ILOG_UUID) { 2530 if (iip->ili_fields & XFS_ILOG_UUID) {
2531 ASSERT(whichfork == XFS_DATA_FORK); 2531 ASSERT(whichfork == XFS_DATA_FORK);
2532 memcpy(XFS_DFORK_DPTR(dip), 2532 memcpy(XFS_DFORK_DPTR(dip),
2533 &ip->i_df.if_u2.if_uuid, 2533 &ip->i_df.if_u2.if_uuid,
2534 sizeof(uuid_t)); 2534 sizeof(uuid_t));
2535 } 2535 }
2536 break; 2536 break;
2537 2537
2538 default: 2538 default:
2539 ASSERT(0); 2539 ASSERT(0);
2540 break; 2540 break;
2541 } 2541 }
2542 } 2542 }
2543 2543
2544 STATIC int 2544 STATIC int
2545 xfs_iflush_cluster( 2545 xfs_iflush_cluster(
2546 xfs_inode_t *ip, 2546 xfs_inode_t *ip,
2547 xfs_buf_t *bp) 2547 xfs_buf_t *bp)
2548 { 2548 {
2549 xfs_mount_t *mp = ip->i_mount; 2549 xfs_mount_t *mp = ip->i_mount;
2550 struct xfs_perag *pag; 2550 struct xfs_perag *pag;
2551 unsigned long first_index, mask; 2551 unsigned long first_index, mask;
2552 unsigned long inodes_per_cluster; 2552 unsigned long inodes_per_cluster;
2553 int ilist_size; 2553 int ilist_size;
2554 xfs_inode_t **ilist; 2554 xfs_inode_t **ilist;
2555 xfs_inode_t *iq; 2555 xfs_inode_t *iq;
2556 int nr_found; 2556 int nr_found;
2557 int clcount = 0; 2557 int clcount = 0;
2558 int bufwasdelwri; 2558 int bufwasdelwri;
2559 int i; 2559 int i;
2560 2560
2561 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); 2561 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
2562 2562
2563 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; 2563 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog;
2564 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); 2564 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
2565 ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS); 2565 ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS);
2566 if (!ilist) 2566 if (!ilist)
2567 goto out_put; 2567 goto out_put;
2568 2568
2569 mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); 2569 mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
2570 first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask; 2570 first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask;
2571 rcu_read_lock(); 2571 rcu_read_lock();
2572 /* really need a gang lookup range call here */ 2572 /* really need a gang lookup range call here */
2573 nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void**)ilist, 2573 nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void**)ilist,
2574 first_index, inodes_per_cluster); 2574 first_index, inodes_per_cluster);
2575 if (nr_found == 0) 2575 if (nr_found == 0)
2576 goto out_free; 2576 goto out_free;
2577 2577
2578 for (i = 0; i < nr_found; i++) { 2578 for (i = 0; i < nr_found; i++) {
2579 iq = ilist[i]; 2579 iq = ilist[i];
2580 if (iq == ip) 2580 if (iq == ip)
2581 continue; 2581 continue;
2582 2582
2583 /* 2583 /*
2584 * because this is an RCU protected lookup, we could find a 2584 * because this is an RCU protected lookup, we could find a
2585 * recently freed or even reallocated inode during the lookup. 2585 * recently freed or even reallocated inode during the lookup.
2586 * We need to check under the i_flags_lock for a valid inode 2586 * We need to check under the i_flags_lock for a valid inode
2587 * here. Skip it if it is not valid or the wrong inode. 2587 * here. Skip it if it is not valid or the wrong inode.
2588 */ 2588 */
2589 spin_lock(&ip->i_flags_lock); 2589 spin_lock(&ip->i_flags_lock);
2590 if (!ip->i_ino || 2590 if (!ip->i_ino ||
2591 (XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) { 2591 (XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) {
2592 spin_unlock(&ip->i_flags_lock); 2592 spin_unlock(&ip->i_flags_lock);
2593 continue; 2593 continue;
2594 } 2594 }
2595 spin_unlock(&ip->i_flags_lock); 2595 spin_unlock(&ip->i_flags_lock);
2596 2596
2597 /* 2597 /*
2598 * Do an un-protected check to see if the inode is dirty and 2598 * Do an un-protected check to see if the inode is dirty and
2599 * is a candidate for flushing. These checks will be repeated 2599 * is a candidate for flushing. These checks will be repeated
2600 * later after the appropriate locks are acquired. 2600 * later after the appropriate locks are acquired.
2601 */ 2601 */
2602 if (xfs_inode_clean(iq) && xfs_ipincount(iq) == 0) 2602 if (xfs_inode_clean(iq) && xfs_ipincount(iq) == 0)
2603 continue; 2603 continue;
2604 2604
2605 /* 2605 /*
2606 * Try to get locks. If any are unavailable or it is pinned, 2606 * Try to get locks. If any are unavailable or it is pinned,
2607 * then this inode cannot be flushed and is skipped. 2607 * then this inode cannot be flushed and is skipped.
2608 */ 2608 */
2609 2609
2610 if (!xfs_ilock_nowait(iq, XFS_ILOCK_SHARED)) 2610 if (!xfs_ilock_nowait(iq, XFS_ILOCK_SHARED))
2611 continue; 2611 continue;
2612 if (!xfs_iflock_nowait(iq)) { 2612 if (!xfs_iflock_nowait(iq)) {
2613 xfs_iunlock(iq, XFS_ILOCK_SHARED); 2613 xfs_iunlock(iq, XFS_ILOCK_SHARED);
2614 continue; 2614 continue;
2615 } 2615 }
2616 if (xfs_ipincount(iq)) { 2616 if (xfs_ipincount(iq)) {
2617 xfs_ifunlock(iq); 2617 xfs_ifunlock(iq);
2618 xfs_iunlock(iq, XFS_ILOCK_SHARED); 2618 xfs_iunlock(iq, XFS_ILOCK_SHARED);
2619 continue; 2619 continue;
2620 } 2620 }
2621 2621
2622 /* 2622 /*
2623 * arriving here means that this inode can be flushed. First 2623 * arriving here means that this inode can be flushed. First
2624 * re-check that it's dirty before flushing. 2624 * re-check that it's dirty before flushing.
2625 */ 2625 */
2626 if (!xfs_inode_clean(iq)) { 2626 if (!xfs_inode_clean(iq)) {
2627 int error; 2627 int error;
2628 error = xfs_iflush_int(iq, bp); 2628 error = xfs_iflush_int(iq, bp);
2629 if (error) { 2629 if (error) {
2630 xfs_iunlock(iq, XFS_ILOCK_SHARED); 2630 xfs_iunlock(iq, XFS_ILOCK_SHARED);
2631 goto cluster_corrupt_out; 2631 goto cluster_corrupt_out;
2632 } 2632 }
2633 clcount++; 2633 clcount++;
2634 } else { 2634 } else {
2635 xfs_ifunlock(iq); 2635 xfs_ifunlock(iq);
2636 } 2636 }
2637 xfs_iunlock(iq, XFS_ILOCK_SHARED); 2637 xfs_iunlock(iq, XFS_ILOCK_SHARED);
2638 } 2638 }
2639 2639
2640 if (clcount) { 2640 if (clcount) {
2641 XFS_STATS_INC(xs_icluster_flushcnt); 2641 XFS_STATS_INC(xs_icluster_flushcnt);
2642 XFS_STATS_ADD(xs_icluster_flushinode, clcount); 2642 XFS_STATS_ADD(xs_icluster_flushinode, clcount);
2643 } 2643 }
2644 2644
2645 out_free: 2645 out_free:
2646 rcu_read_unlock(); 2646 rcu_read_unlock();
2647 kmem_free(ilist); 2647 kmem_free(ilist);
2648 out_put: 2648 out_put:
2649 xfs_perag_put(pag); 2649 xfs_perag_put(pag);
2650 return 0; 2650 return 0;
2651 2651
2652 2652
2653 cluster_corrupt_out: 2653 cluster_corrupt_out:
2654 /* 2654 /*
2655 * Corruption detected in the clustering loop. Invalidate the 2655 * Corruption detected in the clustering loop. Invalidate the
2656 * inode buffer and shut down the filesystem. 2656 * inode buffer and shut down the filesystem.
2657 */ 2657 */
2658 rcu_read_unlock(); 2658 rcu_read_unlock();
2659 /* 2659 /*
2660 * Clean up the buffer. If it was delwri, just release it -- 2660 * Clean up the buffer. If it was delwri, just release it --
2661 * brelse can handle it with no problems. If not, shut down the 2661 * brelse can handle it with no problems. If not, shut down the
2662 * filesystem before releasing the buffer. 2662 * filesystem before releasing the buffer.
2663 */ 2663 */
2664 bufwasdelwri = (bp->b_flags & _XBF_DELWRI_Q); 2664 bufwasdelwri = (bp->b_flags & _XBF_DELWRI_Q);
2665 if (bufwasdelwri) 2665 if (bufwasdelwri)
2666 xfs_buf_relse(bp); 2666 xfs_buf_relse(bp);
2667 2667
2668 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 2668 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
2669 2669
2670 if (!bufwasdelwri) { 2670 if (!bufwasdelwri) {
2671 /* 2671 /*
2672 * Just like incore_relse: if we have b_iodone functions, 2672 * Just like incore_relse: if we have b_iodone functions,
2673 * mark the buffer as an error and call them. Otherwise 2673 * mark the buffer as an error and call them. Otherwise
2674 * mark it as stale and brelse. 2674 * mark it as stale and brelse.
2675 */ 2675 */
2676 if (bp->b_iodone) { 2676 if (bp->b_iodone) {
2677 XFS_BUF_UNDONE(bp); 2677 XFS_BUF_UNDONE(bp);
2678 xfs_buf_stale(bp); 2678 xfs_buf_stale(bp);
2679 xfs_buf_ioerror(bp, EIO); 2679 xfs_buf_ioerror(bp, EIO);
2680 xfs_buf_ioend(bp, 0); 2680 xfs_buf_ioend(bp, 0);
2681 } else { 2681 } else {
2682 xfs_buf_stale(bp); 2682 xfs_buf_stale(bp);
2683 xfs_buf_relse(bp); 2683 xfs_buf_relse(bp);
2684 } 2684 }
2685 } 2685 }
2686 2686
2687 /* 2687 /*
2688 * Unlocks the flush lock 2688 * Unlocks the flush lock
2689 */ 2689 */
2690 xfs_iflush_abort(iq, false); 2690 xfs_iflush_abort(iq, false);
2691 kmem_free(ilist); 2691 kmem_free(ilist);
2692 xfs_perag_put(pag); 2692 xfs_perag_put(pag);
2693 return XFS_ERROR(EFSCORRUPTED); 2693 return XFS_ERROR(EFSCORRUPTED);
2694 } 2694 }
2695 2695
2696 /* 2696 /*
2697 * Flush dirty inode metadata into the backing buffer. 2697 * Flush dirty inode metadata into the backing buffer.
2698 * 2698 *
2699 * The caller must have the inode lock and the inode flush lock held. The 2699 * The caller must have the inode lock and the inode flush lock held. The
2700 * inode lock will still be held upon return to the caller, and the inode 2700 * inode lock will still be held upon return to the caller, and the inode
2701 * flush lock will be released after the inode has reached the disk. 2701 * flush lock will be released after the inode has reached the disk.
2702 * 2702 *
2703 * The caller must write out the buffer returned in *bpp and release it. 2703 * The caller must write out the buffer returned in *bpp and release it.
2704 */ 2704 */
2705 int 2705 int
2706 xfs_iflush( 2706 xfs_iflush(
2707 struct xfs_inode *ip, 2707 struct xfs_inode *ip,
2708 struct xfs_buf **bpp) 2708 struct xfs_buf **bpp)
2709 { 2709 {
2710 struct xfs_mount *mp = ip->i_mount; 2710 struct xfs_mount *mp = ip->i_mount;
2711 struct xfs_buf *bp; 2711 struct xfs_buf *bp;
2712 struct xfs_dinode *dip; 2712 struct xfs_dinode *dip;
2713 int error; 2713 int error;
2714 2714
2715 XFS_STATS_INC(xs_iflush_count); 2715 XFS_STATS_INC(xs_iflush_count);
2716 2716
2717 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 2717 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
2718 ASSERT(xfs_isiflocked(ip)); 2718 ASSERT(xfs_isiflocked(ip));
2719 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 2719 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
2720 ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); 2720 ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK));
2721 2721
2722 *bpp = NULL; 2722 *bpp = NULL;
2723 2723
2724 xfs_iunpin_wait(ip); 2724 xfs_iunpin_wait(ip);
2725 2725
2726 /* 2726 /*
2727 * For stale inodes we cannot rely on the backing buffer remaining 2727 * For stale inodes we cannot rely on the backing buffer remaining
2728 * stale in cache for the remaining life of the stale inode and so 2728 * stale in cache for the remaining life of the stale inode and so
2729 * xfs_imap_to_bp() below may give us a buffer that no longer contains 2729 * xfs_imap_to_bp() below may give us a buffer that no longer contains
2730 * inodes below. We have to check this after ensuring the inode is 2730 * inodes below. We have to check this after ensuring the inode is
2731 * unpinned so that it is safe to reclaim the stale inode after the 2731 * unpinned so that it is safe to reclaim the stale inode after the
2732 * flush call. 2732 * flush call.
2733 */ 2733 */
2734 if (xfs_iflags_test(ip, XFS_ISTALE)) { 2734 if (xfs_iflags_test(ip, XFS_ISTALE)) {
2735 xfs_ifunlock(ip); 2735 xfs_ifunlock(ip);
2736 return 0; 2736 return 0;
2737 } 2737 }
2738 2738
2739 /* 2739 /*
2740 * This may have been unpinned because the filesystem is shutting 2740 * This may have been unpinned because the filesystem is shutting
2741 * down forcibly. If that's the case we must not write this inode 2741 * down forcibly. If that's the case we must not write this inode
2742 * to disk, because the log record didn't make it to disk. 2742 * to disk, because the log record didn't make it to disk.
2743 * 2743 *
2744 * We also have to remove the log item from the AIL in this case, 2744 * We also have to remove the log item from the AIL in this case,
2745 * as we wait for an empty AIL as part of the unmount process. 2745 * as we wait for an empty AIL as part of the unmount process.
2746 */ 2746 */
2747 if (XFS_FORCED_SHUTDOWN(mp)) { 2747 if (XFS_FORCED_SHUTDOWN(mp)) {
2748 error = XFS_ERROR(EIO); 2748 error = XFS_ERROR(EIO);
2749 goto abort_out; 2749 goto abort_out;
2750 } 2750 }
2751 2751
2752 /* 2752 /*
2753 * Get the buffer containing the on-disk inode. 2753 * Get the buffer containing the on-disk inode.
2754 */ 2754 */
2755 error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &bp, XBF_TRYLOCK, 2755 error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &bp, XBF_TRYLOCK,
2756 0); 2756 0);
2757 if (error || !bp) { 2757 if (error || !bp) {
2758 xfs_ifunlock(ip); 2758 xfs_ifunlock(ip);
2759 return error; 2759 return error;
2760 } 2760 }
2761 2761
2762 /* 2762 /*
2763 * First flush out the inode that xfs_iflush was called with. 2763 * First flush out the inode that xfs_iflush was called with.
2764 */ 2764 */
2765 error = xfs_iflush_int(ip, bp); 2765 error = xfs_iflush_int(ip, bp);
2766 if (error) 2766 if (error)
2767 goto corrupt_out; 2767 goto corrupt_out;
2768 2768
2769 /* 2769 /*
2770 * If the buffer is pinned then push on the log now so we won't 2770 * If the buffer is pinned then push on the log now so we won't
2771 * get stuck waiting in the write for too long. 2771 * get stuck waiting in the write for too long.
2772 */ 2772 */
2773 if (xfs_buf_ispinned(bp)) 2773 if (xfs_buf_ispinned(bp))
2774 xfs_log_force(mp, 0); 2774 xfs_log_force(mp, 0);
2775 2775
2776 /* 2776 /*
2777 * inode clustering: 2777 * inode clustering:
2778 * see if other inodes can be gathered into this write 2778 * see if other inodes can be gathered into this write
2779 */ 2779 */
2780 error = xfs_iflush_cluster(ip, bp); 2780 error = xfs_iflush_cluster(ip, bp);
2781 if (error) 2781 if (error)
2782 goto cluster_corrupt_out; 2782 goto cluster_corrupt_out;
2783 2783
2784 *bpp = bp; 2784 *bpp = bp;
2785 return 0; 2785 return 0;
2786 2786
2787 corrupt_out: 2787 corrupt_out:
2788 xfs_buf_relse(bp); 2788 xfs_buf_relse(bp);
2789 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 2789 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
2790 cluster_corrupt_out: 2790 cluster_corrupt_out:
2791 error = XFS_ERROR(EFSCORRUPTED); 2791 error = XFS_ERROR(EFSCORRUPTED);
2792 abort_out: 2792 abort_out:
2793 /* 2793 /*
2794 * Unlocks the flush lock 2794 * Unlocks the flush lock
2795 */ 2795 */
2796 xfs_iflush_abort(ip, false); 2796 xfs_iflush_abort(ip, false);
2797 return error; 2797 return error;
2798 } 2798 }
2799 2799
2800 2800
2801 STATIC int 2801 STATIC int
2802 xfs_iflush_int( 2802 xfs_iflush_int(
2803 struct xfs_inode *ip, 2803 struct xfs_inode *ip,
2804 struct xfs_buf *bp) 2804 struct xfs_buf *bp)
2805 { 2805 {
2806 struct xfs_inode_log_item *iip = ip->i_itemp; 2806 struct xfs_inode_log_item *iip = ip->i_itemp;
2807 struct xfs_dinode *dip; 2807 struct xfs_dinode *dip;
2808 struct xfs_mount *mp = ip->i_mount; 2808 struct xfs_mount *mp = ip->i_mount;
2809 2809
2810 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); 2810 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED));
2811 ASSERT(xfs_isiflocked(ip)); 2811 ASSERT(xfs_isiflocked(ip));
2812 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 2812 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
2813 ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK)); 2813 ip->i_d.di_nextents > XFS_IFORK_MAXEXT(ip, XFS_DATA_FORK));
2814 ASSERT(iip != NULL && iip->ili_fields != 0); 2814 ASSERT(iip != NULL && iip->ili_fields != 0);
2815 2815
2816 /* set *dip = inode's place in the buffer */ 2816 /* set *dip = inode's place in the buffer */
2817 dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); 2817 dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset);
2818 2818
2819 if (XFS_TEST_ERROR(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC), 2819 if (XFS_TEST_ERROR(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC),
2820 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { 2820 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
2821 xfs_alert_tag(mp, XFS_PTAG_IFLUSH, 2821 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
2822 "%s: Bad inode %Lu magic number 0x%x, ptr 0x%p", 2822 "%s: Bad inode %Lu magic number 0x%x, ptr 0x%p",
2823 __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip); 2823 __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip);
2824 goto corrupt_out; 2824 goto corrupt_out;
2825 } 2825 }
2826 if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, 2826 if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC,
2827 mp, XFS_ERRTAG_IFLUSH_2, XFS_RANDOM_IFLUSH_2)) { 2827 mp, XFS_ERRTAG_IFLUSH_2, XFS_RANDOM_IFLUSH_2)) {
2828 xfs_alert_tag(mp, XFS_PTAG_IFLUSH, 2828 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
2829 "%s: Bad inode %Lu, ptr 0x%p, magic number 0x%x", 2829 "%s: Bad inode %Lu, ptr 0x%p, magic number 0x%x",
2830 __func__, ip->i_ino, ip, ip->i_d.di_magic); 2830 __func__, ip->i_ino, ip, ip->i_d.di_magic);
2831 goto corrupt_out; 2831 goto corrupt_out;
2832 } 2832 }
2833 if (S_ISREG(ip->i_d.di_mode)) { 2833 if (S_ISREG(ip->i_d.di_mode)) {
2834 if (XFS_TEST_ERROR( 2834 if (XFS_TEST_ERROR(
2835 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && 2835 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
2836 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), 2836 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE),
2837 mp, XFS_ERRTAG_IFLUSH_3, XFS_RANDOM_IFLUSH_3)) { 2837 mp, XFS_ERRTAG_IFLUSH_3, XFS_RANDOM_IFLUSH_3)) {
2838 xfs_alert_tag(mp, XFS_PTAG_IFLUSH, 2838 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
2839 "%s: Bad regular inode %Lu, ptr 0x%p", 2839 "%s: Bad regular inode %Lu, ptr 0x%p",
2840 __func__, ip->i_ino, ip); 2840 __func__, ip->i_ino, ip);
2841 goto corrupt_out; 2841 goto corrupt_out;
2842 } 2842 }
2843 } else if (S_ISDIR(ip->i_d.di_mode)) { 2843 } else if (S_ISDIR(ip->i_d.di_mode)) {
2844 if (XFS_TEST_ERROR( 2844 if (XFS_TEST_ERROR(
2845 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && 2845 (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) &&
2846 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && 2846 (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
2847 (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL), 2847 (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL),
2848 mp, XFS_ERRTAG_IFLUSH_4, XFS_RANDOM_IFLUSH_4)) { 2848 mp, XFS_ERRTAG_IFLUSH_4, XFS_RANDOM_IFLUSH_4)) {
2849 xfs_alert_tag(mp, XFS_PTAG_IFLUSH, 2849 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
2850 "%s: Bad directory inode %Lu, ptr 0x%p", 2850 "%s: Bad directory inode %Lu, ptr 0x%p",
2851 __func__, ip->i_ino, ip); 2851 __func__, ip->i_ino, ip);
2852 goto corrupt_out; 2852 goto corrupt_out;
2853 } 2853 }
2854 } 2854 }
2855 if (XFS_TEST_ERROR(ip->i_d.di_nextents + ip->i_d.di_anextents > 2855 if (XFS_TEST_ERROR(ip->i_d.di_nextents + ip->i_d.di_anextents >
2856 ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5, 2856 ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5,
2857 XFS_RANDOM_IFLUSH_5)) { 2857 XFS_RANDOM_IFLUSH_5)) {
2858 xfs_alert_tag(mp, XFS_PTAG_IFLUSH, 2858 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
2859 "%s: detected corrupt incore inode %Lu, " 2859 "%s: detected corrupt incore inode %Lu, "
2860 "total extents = %d, nblocks = %Ld, ptr 0x%p", 2860 "total extents = %d, nblocks = %Ld, ptr 0x%p",
2861 __func__, ip->i_ino, 2861 __func__, ip->i_ino,
2862 ip->i_d.di_nextents + ip->i_d.di_anextents, 2862 ip->i_d.di_nextents + ip->i_d.di_anextents,
2863 ip->i_d.di_nblocks, ip); 2863 ip->i_d.di_nblocks, ip);
2864 goto corrupt_out; 2864 goto corrupt_out;
2865 } 2865 }
2866 if (XFS_TEST_ERROR(ip->i_d.di_forkoff > mp->m_sb.sb_inodesize, 2866 if (XFS_TEST_ERROR(ip->i_d.di_forkoff > mp->m_sb.sb_inodesize,
2867 mp, XFS_ERRTAG_IFLUSH_6, XFS_RANDOM_IFLUSH_6)) { 2867 mp, XFS_ERRTAG_IFLUSH_6, XFS_RANDOM_IFLUSH_6)) {
2868 xfs_alert_tag(mp, XFS_PTAG_IFLUSH, 2868 xfs_alert_tag(mp, XFS_PTAG_IFLUSH,
2869 "%s: bad inode %Lu, forkoff 0x%x, ptr 0x%p", 2869 "%s: bad inode %Lu, forkoff 0x%x, ptr 0x%p",
2870 __func__, ip->i_ino, ip->i_d.di_forkoff, ip); 2870 __func__, ip->i_ino, ip->i_d.di_forkoff, ip);
2871 goto corrupt_out; 2871 goto corrupt_out;
2872 } 2872 }
2873 /* 2873 /*
2874 * bump the flush iteration count, used to detect flushes which 2874 * bump the flush iteration count, used to detect flushes which
2875 * postdate a log record during recovery. This is redundant as we now 2875 * postdate a log record during recovery. This is redundant as we now
2876 * log every change and hence this can't happen. Still, it doesn't hurt. 2876 * log every change and hence this can't happen. Still, it doesn't hurt.
2877 */ 2877 */
2878 ip->i_d.di_flushiter++; 2878 ip->i_d.di_flushiter++;
2879 2879
2880 /* 2880 /*
2881 * Copy the dirty parts of the inode into the on-disk 2881 * Copy the dirty parts of the inode into the on-disk
2882 * inode. We always copy out the core of the inode, 2882 * inode. We always copy out the core of the inode,
2883 * because if the inode is dirty at all the core must 2883 * because if the inode is dirty at all the core must
2884 * be. 2884 * be.
2885 */ 2885 */
2886 xfs_dinode_to_disk(dip, &ip->i_d); 2886 xfs_dinode_to_disk(dip, &ip->i_d);
2887 2887
2888 /* Wrap, we never let the log put out DI_MAX_FLUSH */ 2888 /* Wrap, we never let the log put out DI_MAX_FLUSH */
2889 if (ip->i_d.di_flushiter == DI_MAX_FLUSH) 2889 if (ip->i_d.di_flushiter == DI_MAX_FLUSH)
2890 ip->i_d.di_flushiter = 0; 2890 ip->i_d.di_flushiter = 0;
2891 2891
2892 /* 2892 /*
2893 * If this is really an old format inode and the superblock version 2893 * If this is really an old format inode and the superblock version
2894 * has not been updated to support only new format inodes, then 2894 * has not been updated to support only new format inodes, then
2895 * convert back to the old inode format. If the superblock version 2895 * convert back to the old inode format. If the superblock version
2896 * has been updated, then make the conversion permanent. 2896 * has been updated, then make the conversion permanent.
2897 */ 2897 */
2898 ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb)); 2898 ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb));
2899 if (ip->i_d.di_version == 1) { 2899 if (ip->i_d.di_version == 1) {
2900 if (!xfs_sb_version_hasnlink(&mp->m_sb)) { 2900 if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
2901 /* 2901 /*
2902 * Convert it back. 2902 * Convert it back.
2903 */ 2903 */
2904 ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); 2904 ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1);
2905 dip->di_onlink = cpu_to_be16(ip->i_d.di_nlink); 2905 dip->di_onlink = cpu_to_be16(ip->i_d.di_nlink);
2906 } else { 2906 } else {
2907 /* 2907 /*
2908 * The superblock version has already been bumped, 2908 * The superblock version has already been bumped,
2909 * so just make the conversion to the new inode 2909 * so just make the conversion to the new inode
2910 * format permanent. 2910 * format permanent.
2911 */ 2911 */
2912 ip->i_d.di_version = 2; 2912 ip->i_d.di_version = 2;
2913 dip->di_version = 2; 2913 dip->di_version = 2;
2914 ip->i_d.di_onlink = 0; 2914 ip->i_d.di_onlink = 0;
2915 dip->di_onlink = 0; 2915 dip->di_onlink = 0;
2916 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); 2916 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
2917 memset(&(dip->di_pad[0]), 0, 2917 memset(&(dip->di_pad[0]), 0,
2918 sizeof(dip->di_pad)); 2918 sizeof(dip->di_pad));
2919 ASSERT(xfs_get_projid(ip) == 0); 2919 ASSERT(xfs_get_projid(ip) == 0);
2920 } 2920 }
2921 } 2921 }
2922 2922
2923 xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK, bp); 2923 xfs_iflush_fork(ip, dip, iip, XFS_DATA_FORK, bp);
2924 if (XFS_IFORK_Q(ip)) 2924 if (XFS_IFORK_Q(ip))
2925 xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK, bp); 2925 xfs_iflush_fork(ip, dip, iip, XFS_ATTR_FORK, bp);
2926 xfs_inobp_check(mp, bp); 2926 xfs_inobp_check(mp, bp);
2927 2927
2928 /* 2928 /*
2929 * We've recorded everything logged in the inode, so we'd like to clear 2929 * We've recorded everything logged in the inode, so we'd like to clear
2930 * the ili_fields bits so we don't log and flush things unnecessarily. 2930 * the ili_fields bits so we don't log and flush things unnecessarily.
2931 * However, we can't stop logging all this information until the data 2931 * However, we can't stop logging all this information until the data
2932 * we've copied into the disk buffer is written to disk. If we did we 2932 * we've copied into the disk buffer is written to disk. If we did we
2933 * might overwrite the copy of the inode in the log with all the data 2933 * might overwrite the copy of the inode in the log with all the data
2934 * after re-logging only part of it, and in the face of a crash we 2934 * after re-logging only part of it, and in the face of a crash we
2935 * wouldn't have all the data we need to recover. 2935 * wouldn't have all the data we need to recover.
2936 * 2936 *
2937 * What we do is move the bits to the ili_last_fields field. When 2937 * What we do is move the bits to the ili_last_fields field. When
2938 * logging the inode, these bits are moved back to the ili_fields field. 2938 * logging the inode, these bits are moved back to the ili_fields field.
2939 * In the xfs_iflush_done() routine we clear ili_last_fields, since we 2939 * In the xfs_iflush_done() routine we clear ili_last_fields, since we
2940 * know that the information those bits represent is permanently on 2940 * know that the information those bits represent is permanently on
2941 * disk. As long as the flush completes before the inode is logged 2941 * disk. As long as the flush completes before the inode is logged
2942 * again, then both ili_fields and ili_last_fields will be cleared. 2942 * again, then both ili_fields and ili_last_fields will be cleared.
2943 * 2943 *
2944 * We can play with the ili_fields bits here, because the inode lock 2944 * We can play with the ili_fields bits here, because the inode lock
2945 * must be held exclusively in order to set bits there and the flush 2945 * must be held exclusively in order to set bits there and the flush
2946 * lock protects the ili_last_fields bits. Set ili_logged so the flush 2946 * lock protects the ili_last_fields bits. Set ili_logged so the flush
2947 * done routine can tell whether or not to look in the AIL. Also, store 2947 * done routine can tell whether or not to look in the AIL. Also, store
2948 * the current LSN of the inode so that we can tell whether the item has 2948 * the current LSN of the inode so that we can tell whether the item has
2949 * moved in the AIL from xfs_iflush_done(). In order to read the lsn we 2949 * moved in the AIL from xfs_iflush_done(). In order to read the lsn we
2950 * need the AIL lock, because it is a 64 bit value that cannot be read 2950 * need the AIL lock, because it is a 64 bit value that cannot be read
2951 * atomically. 2951 * atomically.
2952 */ 2952 */
2953 iip->ili_last_fields = iip->ili_fields; 2953 iip->ili_last_fields = iip->ili_fields;
2954 iip->ili_fields = 0; 2954 iip->ili_fields = 0;
2955 iip->ili_logged = 1; 2955 iip->ili_logged = 1;
2956 2956
2957 xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, 2957 xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
2958 &iip->ili_item.li_lsn); 2958 &iip->ili_item.li_lsn);
2959 2959
2960 /* 2960 /*
2961 * Attach the function xfs_iflush_done to the inode's 2961 * Attach the function xfs_iflush_done to the inode's
2962 * buffer. This will remove the inode from the AIL 2962 * buffer. This will remove the inode from the AIL
2963 * and unlock the inode's flush lock when the inode is 2963 * and unlock the inode's flush lock when the inode is
2964 * completely written to disk. 2964 * completely written to disk.
2965 */ 2965 */
2966 xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item); 2966 xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item);
2967 2967
2968 /* update the lsn in the on disk inode if required */ 2968 /* update the lsn in the on disk inode if required */
2969 if (ip->i_d.di_version == 3) 2969 if (ip->i_d.di_version == 3)
2970 dip->di_lsn = cpu_to_be64(iip->ili_item.li_lsn); 2970 dip->di_lsn = cpu_to_be64(iip->ili_item.li_lsn);
2971 2971
2972 /* generate the checksum. */ 2972 /* generate the checksum. */
2973 xfs_dinode_calc_crc(mp, dip); 2973 xfs_dinode_calc_crc(mp, dip);
2974 2974
2975 ASSERT(bp->b_fspriv != NULL); 2975 ASSERT(bp->b_fspriv != NULL);
2976 ASSERT(bp->b_iodone != NULL); 2976 ASSERT(bp->b_iodone != NULL);
2977 return 0; 2977 return 0;
2978 2978
2979 corrupt_out: 2979 corrupt_out:
2980 return XFS_ERROR(EFSCORRUPTED); 2980 return XFS_ERROR(EFSCORRUPTED);
2981 } 2981 }
2982 2982
2983 /* 2983 /*
2984 * Return a pointer to the extent record at file index idx. 2984 * Return a pointer to the extent record at file index idx.
2985 */ 2985 */
2986 xfs_bmbt_rec_host_t * 2986 xfs_bmbt_rec_host_t *
2987 xfs_iext_get_ext( 2987 xfs_iext_get_ext(
2988 xfs_ifork_t *ifp, /* inode fork pointer */ 2988 xfs_ifork_t *ifp, /* inode fork pointer */
2989 xfs_extnum_t idx) /* index of target extent */ 2989 xfs_extnum_t idx) /* index of target extent */
2990 { 2990 {
2991 ASSERT(idx >= 0); 2991 ASSERT(idx >= 0);
2992 ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)); 2992 ASSERT(idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
2993 2993
2994 if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) { 2994 if ((ifp->if_flags & XFS_IFEXTIREC) && (idx == 0)) {
2995 return ifp->if_u1.if_ext_irec->er_extbuf; 2995 return ifp->if_u1.if_ext_irec->er_extbuf;
2996 } else if (ifp->if_flags & XFS_IFEXTIREC) { 2996 } else if (ifp->if_flags & XFS_IFEXTIREC) {
2997 xfs_ext_irec_t *erp; /* irec pointer */ 2997 xfs_ext_irec_t *erp; /* irec pointer */
2998 int erp_idx = 0; /* irec index */ 2998 int erp_idx = 0; /* irec index */
2999 xfs_extnum_t page_idx = idx; /* ext index in target list */ 2999 xfs_extnum_t page_idx = idx; /* ext index in target list */
3000 3000
3001 erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); 3001 erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0);
3002 return &erp->er_extbuf[page_idx]; 3002 return &erp->er_extbuf[page_idx];
3003 } else if (ifp->if_bytes) { 3003 } else if (ifp->if_bytes) {
3004 return &ifp->if_u1.if_extents[idx]; 3004 return &ifp->if_u1.if_extents[idx];
3005 } else { 3005 } else {
3006 return NULL; 3006 return NULL;
3007 } 3007 }
3008 } 3008 }
3009 3009
3010 /* 3010 /*
3011 * Insert new item(s) into the extent records for incore inode 3011 * Insert new item(s) into the extent records for incore inode
3012 * fork 'ifp'. 'count' new items are inserted at index 'idx'. 3012 * fork 'ifp'. 'count' new items are inserted at index 'idx'.
3013 */ 3013 */
3014 void 3014 void
3015 xfs_iext_insert( 3015 xfs_iext_insert(
3016 xfs_inode_t *ip, /* incore inode pointer */ 3016 xfs_inode_t *ip, /* incore inode pointer */
3017 xfs_extnum_t idx, /* starting index of new items */ 3017 xfs_extnum_t idx, /* starting index of new items */
3018 xfs_extnum_t count, /* number of inserted items */ 3018 xfs_extnum_t count, /* number of inserted items */
3019 xfs_bmbt_irec_t *new, /* items to insert */ 3019 xfs_bmbt_irec_t *new, /* items to insert */
3020 int state) /* type of extent conversion */ 3020 int state) /* type of extent conversion */
3021 { 3021 {
3022 xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; 3022 xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df;
3023 xfs_extnum_t i; /* extent record index */ 3023 xfs_extnum_t i; /* extent record index */
3024 3024
3025 trace_xfs_iext_insert(ip, idx, new, state, _RET_IP_); 3025 trace_xfs_iext_insert(ip, idx, new, state, _RET_IP_);
3026 3026
3027 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 3027 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
3028 xfs_iext_add(ifp, idx, count); 3028 xfs_iext_add(ifp, idx, count);
3029 for (i = idx; i < idx + count; i++, new++) 3029 for (i = idx; i < idx + count; i++, new++)
3030 xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new); 3030 xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new);
3031 } 3031 }
3032 3032
3033 /* 3033 /*
3034 * This is called when the amount of space required for incore file 3034 * This is called when the amount of space required for incore file
3035 * extents needs to be increased. The ext_diff parameter stores the 3035 * extents needs to be increased. The ext_diff parameter stores the
3036 * number of new extents being added and the idx parameter contains 3036 * number of new extents being added and the idx parameter contains
3037 * the extent index where the new extents will be added. If the new 3037 * the extent index where the new extents will be added. If the new
3038 * extents are being appended, then we just need to (re)allocate and 3038 * extents are being appended, then we just need to (re)allocate and
3039 * initialize the space. Otherwise, if the new extents are being 3039 * initialize the space. Otherwise, if the new extents are being
3040 * inserted into the middle of the existing entries, a bit more work 3040 * inserted into the middle of the existing entries, a bit more work
3041 * is required to make room for the new extents to be inserted. The 3041 * is required to make room for the new extents to be inserted. The
3042 * caller is responsible for filling in the new extent entries upon 3042 * caller is responsible for filling in the new extent entries upon
3043 * return. 3043 * return.
3044 */ 3044 */
3045 void 3045 void
3046 xfs_iext_add( 3046 xfs_iext_add(
3047 xfs_ifork_t *ifp, /* inode fork pointer */ 3047 xfs_ifork_t *ifp, /* inode fork pointer */
3048 xfs_extnum_t idx, /* index to begin adding exts */ 3048 xfs_extnum_t idx, /* index to begin adding exts */
3049 int ext_diff) /* number of extents to add */ 3049 int ext_diff) /* number of extents to add */
3050 { 3050 {
3051 int byte_diff; /* new bytes being added */ 3051 int byte_diff; /* new bytes being added */
3052 int new_size; /* size of extents after adding */ 3052 int new_size; /* size of extents after adding */
3053 xfs_extnum_t nextents; /* number of extents in file */ 3053 xfs_extnum_t nextents; /* number of extents in file */
3054 3054
3055 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3055 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3056 ASSERT((idx >= 0) && (idx <= nextents)); 3056 ASSERT((idx >= 0) && (idx <= nextents));
3057 byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t); 3057 byte_diff = ext_diff * sizeof(xfs_bmbt_rec_t);
3058 new_size = ifp->if_bytes + byte_diff; 3058 new_size = ifp->if_bytes + byte_diff;
3059 /* 3059 /*
3060 * If the new number of extents (nextents + ext_diff) 3060 * If the new number of extents (nextents + ext_diff)
3061 * fits inside the inode, then continue to use the inline 3061 * fits inside the inode, then continue to use the inline
3062 * extent buffer. 3062 * extent buffer.
3063 */ 3063 */
3064 if (nextents + ext_diff <= XFS_INLINE_EXTS) { 3064 if (nextents + ext_diff <= XFS_INLINE_EXTS) {
3065 if (idx < nextents) { 3065 if (idx < nextents) {
3066 memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff], 3066 memmove(&ifp->if_u2.if_inline_ext[idx + ext_diff],
3067 &ifp->if_u2.if_inline_ext[idx], 3067 &ifp->if_u2.if_inline_ext[idx],
3068 (nextents - idx) * sizeof(xfs_bmbt_rec_t)); 3068 (nextents - idx) * sizeof(xfs_bmbt_rec_t));
3069 memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff); 3069 memset(&ifp->if_u2.if_inline_ext[idx], 0, byte_diff);
3070 } 3070 }
3071 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; 3071 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
3072 ifp->if_real_bytes = 0; 3072 ifp->if_real_bytes = 0;
3073 } 3073 }
3074 /* 3074 /*
3075 * Otherwise use a linear (direct) extent list. 3075 * Otherwise use a linear (direct) extent list.
3076 * If the extents are currently inside the inode, 3076 * If the extents are currently inside the inode,
3077 * xfs_iext_realloc_direct will switch us from 3077 * xfs_iext_realloc_direct will switch us from
3078 * inline to direct extent allocation mode. 3078 * inline to direct extent allocation mode.
3079 */ 3079 */
3080 else if (nextents + ext_diff <= XFS_LINEAR_EXTS) { 3080 else if (nextents + ext_diff <= XFS_LINEAR_EXTS) {
3081 xfs_iext_realloc_direct(ifp, new_size); 3081 xfs_iext_realloc_direct(ifp, new_size);
3082 if (idx < nextents) { 3082 if (idx < nextents) {
3083 memmove(&ifp->if_u1.if_extents[idx + ext_diff], 3083 memmove(&ifp->if_u1.if_extents[idx + ext_diff],
3084 &ifp->if_u1.if_extents[idx], 3084 &ifp->if_u1.if_extents[idx],
3085 (nextents - idx) * sizeof(xfs_bmbt_rec_t)); 3085 (nextents - idx) * sizeof(xfs_bmbt_rec_t));
3086 memset(&ifp->if_u1.if_extents[idx], 0, byte_diff); 3086 memset(&ifp->if_u1.if_extents[idx], 0, byte_diff);
3087 } 3087 }
3088 } 3088 }
3089 /* Indirection array */ 3089 /* Indirection array */
3090 else { 3090 else {
3091 xfs_ext_irec_t *erp; 3091 xfs_ext_irec_t *erp;
3092 int erp_idx = 0; 3092 int erp_idx = 0;
3093 int page_idx = idx; 3093 int page_idx = idx;
3094 3094
3095 ASSERT(nextents + ext_diff > XFS_LINEAR_EXTS); 3095 ASSERT(nextents + ext_diff > XFS_LINEAR_EXTS);
3096 if (ifp->if_flags & XFS_IFEXTIREC) { 3096 if (ifp->if_flags & XFS_IFEXTIREC) {
3097 erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 1); 3097 erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 1);
3098 } else { 3098 } else {
3099 xfs_iext_irec_init(ifp); 3099 xfs_iext_irec_init(ifp);
3100 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3100 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3101 erp = ifp->if_u1.if_ext_irec; 3101 erp = ifp->if_u1.if_ext_irec;
3102 } 3102 }
3103 /* Extents fit in target extent page */ 3103 /* Extents fit in target extent page */
3104 if (erp && erp->er_extcount + ext_diff <= XFS_LINEAR_EXTS) { 3104 if (erp && erp->er_extcount + ext_diff <= XFS_LINEAR_EXTS) {
3105 if (page_idx < erp->er_extcount) { 3105 if (page_idx < erp->er_extcount) {
3106 memmove(&erp->er_extbuf[page_idx + ext_diff], 3106 memmove(&erp->er_extbuf[page_idx + ext_diff],
3107 &erp->er_extbuf[page_idx], 3107 &erp->er_extbuf[page_idx],
3108 (erp->er_extcount - page_idx) * 3108 (erp->er_extcount - page_idx) *
3109 sizeof(xfs_bmbt_rec_t)); 3109 sizeof(xfs_bmbt_rec_t));
3110 memset(&erp->er_extbuf[page_idx], 0, byte_diff); 3110 memset(&erp->er_extbuf[page_idx], 0, byte_diff);
3111 } 3111 }
3112 erp->er_extcount += ext_diff; 3112 erp->er_extcount += ext_diff;
3113 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); 3113 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
3114 } 3114 }
3115 /* Insert a new extent page */ 3115 /* Insert a new extent page */
3116 else if (erp) { 3116 else if (erp) {
3117 xfs_iext_add_indirect_multi(ifp, 3117 xfs_iext_add_indirect_multi(ifp,
3118 erp_idx, page_idx, ext_diff); 3118 erp_idx, page_idx, ext_diff);
3119 } 3119 }
3120 /* 3120 /*
3121 * If extent(s) are being appended to the last page in 3121 * If extent(s) are being appended to the last page in
3122 * the indirection array and the new extent(s) don't fit 3122 * the indirection array and the new extent(s) don't fit
3123 * in the page, then erp is NULL and erp_idx is set to 3123 * in the page, then erp is NULL and erp_idx is set to
3124 * the next index needed in the indirection array. 3124 * the next index needed in the indirection array.
3125 */ 3125 */
3126 else { 3126 else {
3127 int count = ext_diff; 3127 int count = ext_diff;
3128 3128
3129 while (count) { 3129 while (count) {
3130 erp = xfs_iext_irec_new(ifp, erp_idx); 3130 erp = xfs_iext_irec_new(ifp, erp_idx);
3131 erp->er_extcount = count; 3131 erp->er_extcount = count;
3132 count -= MIN(count, (int)XFS_LINEAR_EXTS); 3132 count -= MIN(count, (int)XFS_LINEAR_EXTS);
3133 if (count) { 3133 if (count) {
3134 erp_idx++; 3134 erp_idx++;
3135 } 3135 }
3136 } 3136 }
3137 } 3137 }
3138 } 3138 }
3139 ifp->if_bytes = new_size; 3139 ifp->if_bytes = new_size;
3140 } 3140 }
3141 3141
3142 /* 3142 /*
3143 * This is called when incore extents are being added to the indirection 3143 * This is called when incore extents are being added to the indirection
3144 * array and the new extents do not fit in the target extent list. The 3144 * array and the new extents do not fit in the target extent list. The
3145 * erp_idx parameter contains the irec index for the target extent list 3145 * erp_idx parameter contains the irec index for the target extent list
3146 * in the indirection array, and the idx parameter contains the extent 3146 * in the indirection array, and the idx parameter contains the extent
3147 * index within the list. The number of extents being added is stored 3147 * index within the list. The number of extents being added is stored
3148 * in the count parameter. 3148 * in the count parameter.
3149 * 3149 *
3150 * |-------| |-------| 3150 * |-------| |-------|
3151 * | | | | idx - number of extents before idx 3151 * | | | | idx - number of extents before idx
3152 * | idx | | count | 3152 * | idx | | count |
3153 * | | | | count - number of extents being inserted at idx 3153 * | | | | count - number of extents being inserted at idx
3154 * |-------| |-------| 3154 * |-------| |-------|
3155 * | count | | nex2 | nex2 - number of extents after idx + count 3155 * | count | | nex2 | nex2 - number of extents after idx + count
3156 * |-------| |-------| 3156 * |-------| |-------|
3157 */ 3157 */
3158 void 3158 void
3159 xfs_iext_add_indirect_multi( 3159 xfs_iext_add_indirect_multi(
3160 xfs_ifork_t *ifp, /* inode fork pointer */ 3160 xfs_ifork_t *ifp, /* inode fork pointer */
3161 int erp_idx, /* target extent irec index */ 3161 int erp_idx, /* target extent irec index */
3162 xfs_extnum_t idx, /* index within target list */ 3162 xfs_extnum_t idx, /* index within target list */
3163 int count) /* new extents being added */ 3163 int count) /* new extents being added */
3164 { 3164 {
3165 int byte_diff; /* new bytes being added */ 3165 int byte_diff; /* new bytes being added */
3166 xfs_ext_irec_t *erp; /* pointer to irec entry */ 3166 xfs_ext_irec_t *erp; /* pointer to irec entry */
3167 xfs_extnum_t ext_diff; /* number of extents to add */ 3167 xfs_extnum_t ext_diff; /* number of extents to add */
3168 xfs_extnum_t ext_cnt; /* new extents still needed */ 3168 xfs_extnum_t ext_cnt; /* new extents still needed */
3169 xfs_extnum_t nex2; /* extents after idx + count */ 3169 xfs_extnum_t nex2; /* extents after idx + count */
3170 xfs_bmbt_rec_t *nex2_ep = NULL; /* temp list for nex2 extents */ 3170 xfs_bmbt_rec_t *nex2_ep = NULL; /* temp list for nex2 extents */
3171 int nlists; /* number of irec's (lists) */ 3171 int nlists; /* number of irec's (lists) */
3172 3172
3173 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3173 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3174 erp = &ifp->if_u1.if_ext_irec[erp_idx]; 3174 erp = &ifp->if_u1.if_ext_irec[erp_idx];
3175 nex2 = erp->er_extcount - idx; 3175 nex2 = erp->er_extcount - idx;
3176 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3176 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3177 3177
3178 /* 3178 /*
3179 * Save second part of target extent list 3179 * Save second part of target extent list
3180 * (all extents past */ 3180 * (all extents past */
3181 if (nex2) { 3181 if (nex2) {
3182 byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); 3182 byte_diff = nex2 * sizeof(xfs_bmbt_rec_t);
3183 nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS); 3183 nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS);
3184 memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff); 3184 memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff);
3185 erp->er_extcount -= nex2; 3185 erp->er_extcount -= nex2;
3186 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2); 3186 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2);
3187 memset(&erp->er_extbuf[idx], 0, byte_diff); 3187 memset(&erp->er_extbuf[idx], 0, byte_diff);
3188 } 3188 }
3189 3189
3190 /* 3190 /*
3191 * Add the new extents to the end of the target 3191 * Add the new extents to the end of the target
3192 * list, then allocate new irec record(s) and 3192 * list, then allocate new irec record(s) and
3193 * extent buffer(s) as needed to store the rest 3193 * extent buffer(s) as needed to store the rest
3194 * of the new extents. 3194 * of the new extents.
3195 */ 3195 */
3196 ext_cnt = count; 3196 ext_cnt = count;
3197 ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS - erp->er_extcount); 3197 ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS - erp->er_extcount);
3198 if (ext_diff) { 3198 if (ext_diff) {
3199 erp->er_extcount += ext_diff; 3199 erp->er_extcount += ext_diff;
3200 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); 3200 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
3201 ext_cnt -= ext_diff; 3201 ext_cnt -= ext_diff;
3202 } 3202 }
3203 while (ext_cnt) { 3203 while (ext_cnt) {
3204 erp_idx++; 3204 erp_idx++;
3205 erp = xfs_iext_irec_new(ifp, erp_idx); 3205 erp = xfs_iext_irec_new(ifp, erp_idx);
3206 ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS); 3206 ext_diff = MIN(ext_cnt, (int)XFS_LINEAR_EXTS);
3207 erp->er_extcount = ext_diff; 3207 erp->er_extcount = ext_diff;
3208 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff); 3208 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, ext_diff);
3209 ext_cnt -= ext_diff; 3209 ext_cnt -= ext_diff;
3210 } 3210 }
3211 3211
3212 /* Add nex2 extents back to indirection array */ 3212 /* Add nex2 extents back to indirection array */
3213 if (nex2) { 3213 if (nex2) {
3214 xfs_extnum_t ext_avail; 3214 xfs_extnum_t ext_avail;
3215 int i; 3215 int i;
3216 3216
3217 byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); 3217 byte_diff = nex2 * sizeof(xfs_bmbt_rec_t);
3218 ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; 3218 ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;
3219 i = 0; 3219 i = 0;
3220 /* 3220 /*
3221 * If nex2 extents fit in the current page, append 3221 * If nex2 extents fit in the current page, append
3222 * nex2_ep after the new extents. 3222 * nex2_ep after the new extents.
3223 */ 3223 */
3224 if (nex2 <= ext_avail) { 3224 if (nex2 <= ext_avail) {
3225 i = erp->er_extcount; 3225 i = erp->er_extcount;
3226 } 3226 }
3227 /* 3227 /*
3228 * Otherwise, check if space is available in the 3228 * Otherwise, check if space is available in the
3229 * next page. 3229 * next page.
3230 */ 3230 */
3231 else if ((erp_idx < nlists - 1) && 3231 else if ((erp_idx < nlists - 1) &&
3232 (nex2 <= (ext_avail = XFS_LINEAR_EXTS - 3232 (nex2 <= (ext_avail = XFS_LINEAR_EXTS -
3233 ifp->if_u1.if_ext_irec[erp_idx+1].er_extcount))) { 3233 ifp->if_u1.if_ext_irec[erp_idx+1].er_extcount))) {
3234 erp_idx++; 3234 erp_idx++;
3235 erp++; 3235 erp++;
3236 /* Create a hole for nex2 extents */ 3236 /* Create a hole for nex2 extents */
3237 memmove(&erp->er_extbuf[nex2], erp->er_extbuf, 3237 memmove(&erp->er_extbuf[nex2], erp->er_extbuf,
3238 erp->er_extcount * sizeof(xfs_bmbt_rec_t)); 3238 erp->er_extcount * sizeof(xfs_bmbt_rec_t));
3239 } 3239 }
3240 /* 3240 /*
3241 * Final choice, create a new extent page for 3241 * Final choice, create a new extent page for
3242 * nex2 extents. 3242 * nex2 extents.
3243 */ 3243 */
3244 else { 3244 else {
3245 erp_idx++; 3245 erp_idx++;
3246 erp = xfs_iext_irec_new(ifp, erp_idx); 3246 erp = xfs_iext_irec_new(ifp, erp_idx);
3247 } 3247 }
3248 memmove(&erp->er_extbuf[i], nex2_ep, byte_diff); 3248 memmove(&erp->er_extbuf[i], nex2_ep, byte_diff);
3249 kmem_free(nex2_ep); 3249 kmem_free(nex2_ep);
3250 erp->er_extcount += nex2; 3250 erp->er_extcount += nex2;
3251 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2); 3251 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2);
3252 } 3252 }
3253 } 3253 }
3254 3254
3255 /* 3255 /*
3256 * This is called when the amount of space required for incore file 3256 * This is called when the amount of space required for incore file
3257 * extents needs to be decreased. The ext_diff parameter stores the 3257 * extents needs to be decreased. The ext_diff parameter stores the
3258 * number of extents to be removed and the idx parameter contains 3258 * number of extents to be removed and the idx parameter contains
3259 * the extent index where the extents will be removed from. 3259 * the extent index where the extents will be removed from.
3260 * 3260 *
3261 * If the amount of space needed has decreased below the linear 3261 * If the amount of space needed has decreased below the linear
3262 * limit, XFS_IEXT_BUFSZ, then switch to using the contiguous 3262 * limit, XFS_IEXT_BUFSZ, then switch to using the contiguous
3263 * extent array. Otherwise, use kmem_realloc() to adjust the 3263 * extent array. Otherwise, use kmem_realloc() to adjust the
3264 * size to what is needed. 3264 * size to what is needed.
3265 */ 3265 */
3266 void 3266 void
3267 xfs_iext_remove( 3267 xfs_iext_remove(
3268 xfs_inode_t *ip, /* incore inode pointer */ 3268 xfs_inode_t *ip, /* incore inode pointer */
3269 xfs_extnum_t idx, /* index to begin removing exts */ 3269 xfs_extnum_t idx, /* index to begin removing exts */
3270 int ext_diff, /* number of extents to remove */ 3270 int ext_diff, /* number of extents to remove */
3271 int state) /* type of extent conversion */ 3271 int state) /* type of extent conversion */
3272 { 3272 {
3273 xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df; 3273 xfs_ifork_t *ifp = (state & BMAP_ATTRFORK) ? ip->i_afp : &ip->i_df;
3274 xfs_extnum_t nextents; /* number of extents in file */ 3274 xfs_extnum_t nextents; /* number of extents in file */
3275 int new_size; /* size of extents after removal */ 3275 int new_size; /* size of extents after removal */
3276 3276
3277 trace_xfs_iext_remove(ip, idx, state, _RET_IP_); 3277 trace_xfs_iext_remove(ip, idx, state, _RET_IP_);
3278 3278
3279 ASSERT(ext_diff > 0); 3279 ASSERT(ext_diff > 0);
3280 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3280 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3281 new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t); 3281 new_size = (nextents - ext_diff) * sizeof(xfs_bmbt_rec_t);
3282 3282
3283 if (new_size == 0) { 3283 if (new_size == 0) {
3284 xfs_iext_destroy(ifp); 3284 xfs_iext_destroy(ifp);
3285 } else if (ifp->if_flags & XFS_IFEXTIREC) { 3285 } else if (ifp->if_flags & XFS_IFEXTIREC) {
3286 xfs_iext_remove_indirect(ifp, idx, ext_diff); 3286 xfs_iext_remove_indirect(ifp, idx, ext_diff);
3287 } else if (ifp->if_real_bytes) { 3287 } else if (ifp->if_real_bytes) {
3288 xfs_iext_remove_direct(ifp, idx, ext_diff); 3288 xfs_iext_remove_direct(ifp, idx, ext_diff);
3289 } else { 3289 } else {
3290 xfs_iext_remove_inline(ifp, idx, ext_diff); 3290 xfs_iext_remove_inline(ifp, idx, ext_diff);
3291 } 3291 }
3292 ifp->if_bytes = new_size; 3292 ifp->if_bytes = new_size;
3293 } 3293 }
3294 3294
3295 /* 3295 /*
3296 * This removes ext_diff extents from the inline buffer, beginning 3296 * This removes ext_diff extents from the inline buffer, beginning
3297 * at extent index idx. 3297 * at extent index idx.
3298 */ 3298 */
3299 void 3299 void
3300 xfs_iext_remove_inline( 3300 xfs_iext_remove_inline(
3301 xfs_ifork_t *ifp, /* inode fork pointer */ 3301 xfs_ifork_t *ifp, /* inode fork pointer */
3302 xfs_extnum_t idx, /* index to begin removing exts */ 3302 xfs_extnum_t idx, /* index to begin removing exts */
3303 int ext_diff) /* number of extents to remove */ 3303 int ext_diff) /* number of extents to remove */
3304 { 3304 {
3305 int nextents; /* number of extents in file */ 3305 int nextents; /* number of extents in file */
3306 3306
3307 ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); 3307 ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
3308 ASSERT(idx < XFS_INLINE_EXTS); 3308 ASSERT(idx < XFS_INLINE_EXTS);
3309 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3309 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3310 ASSERT(((nextents - ext_diff) > 0) && 3310 ASSERT(((nextents - ext_diff) > 0) &&
3311 (nextents - ext_diff) < XFS_INLINE_EXTS); 3311 (nextents - ext_diff) < XFS_INLINE_EXTS);
3312 3312
3313 if (idx + ext_diff < nextents) { 3313 if (idx + ext_diff < nextents) {
3314 memmove(&ifp->if_u2.if_inline_ext[idx], 3314 memmove(&ifp->if_u2.if_inline_ext[idx],
3315 &ifp->if_u2.if_inline_ext[idx + ext_diff], 3315 &ifp->if_u2.if_inline_ext[idx + ext_diff],
3316 (nextents - (idx + ext_diff)) * 3316 (nextents - (idx + ext_diff)) *
3317 sizeof(xfs_bmbt_rec_t)); 3317 sizeof(xfs_bmbt_rec_t));
3318 memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff], 3318 memset(&ifp->if_u2.if_inline_ext[nextents - ext_diff],
3319 0, ext_diff * sizeof(xfs_bmbt_rec_t)); 3319 0, ext_diff * sizeof(xfs_bmbt_rec_t));
3320 } else { 3320 } else {
3321 memset(&ifp->if_u2.if_inline_ext[idx], 0, 3321 memset(&ifp->if_u2.if_inline_ext[idx], 0,
3322 ext_diff * sizeof(xfs_bmbt_rec_t)); 3322 ext_diff * sizeof(xfs_bmbt_rec_t));
3323 } 3323 }
3324 } 3324 }
3325 3325
3326 /* 3326 /*
3327 * This removes ext_diff extents from a linear (direct) extent list, 3327 * This removes ext_diff extents from a linear (direct) extent list,
3328 * beginning at extent index idx. If the extents are being removed 3328 * beginning at extent index idx. If the extents are being removed
3329 * from the end of the list (ie. truncate) then we just need to re- 3329 * from the end of the list (ie. truncate) then we just need to re-
3330 * allocate the list to remove the extra space. Otherwise, if the 3330 * allocate the list to remove the extra space. Otherwise, if the
3331 * extents are being removed from the middle of the existing extent 3331 * extents are being removed from the middle of the existing extent
3332 * entries, then we first need to move the extent records beginning 3332 * entries, then we first need to move the extent records beginning
3333 * at idx + ext_diff up in the list to overwrite the records being 3333 * at idx + ext_diff up in the list to overwrite the records being
3334 * removed, then remove the extra space via kmem_realloc. 3334 * removed, then remove the extra space via kmem_realloc.
3335 */ 3335 */
3336 void 3336 void
3337 xfs_iext_remove_direct( 3337 xfs_iext_remove_direct(
3338 xfs_ifork_t *ifp, /* inode fork pointer */ 3338 xfs_ifork_t *ifp, /* inode fork pointer */
3339 xfs_extnum_t idx, /* index to begin removing exts */ 3339 xfs_extnum_t idx, /* index to begin removing exts */
3340 int ext_diff) /* number of extents to remove */ 3340 int ext_diff) /* number of extents to remove */
3341 { 3341 {
3342 xfs_extnum_t nextents; /* number of extents in file */ 3342 xfs_extnum_t nextents; /* number of extents in file */
3343 int new_size; /* size of extents after removal */ 3343 int new_size; /* size of extents after removal */
3344 3344
3345 ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); 3345 ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
3346 new_size = ifp->if_bytes - 3346 new_size = ifp->if_bytes -
3347 (ext_diff * sizeof(xfs_bmbt_rec_t)); 3347 (ext_diff * sizeof(xfs_bmbt_rec_t));
3348 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3348 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3349 3349
3350 if (new_size == 0) { 3350 if (new_size == 0) {
3351 xfs_iext_destroy(ifp); 3351 xfs_iext_destroy(ifp);
3352 return; 3352 return;
3353 } 3353 }
3354 /* Move extents up in the list (if needed) */ 3354 /* Move extents up in the list (if needed) */
3355 if (idx + ext_diff < nextents) { 3355 if (idx + ext_diff < nextents) {
3356 memmove(&ifp->if_u1.if_extents[idx], 3356 memmove(&ifp->if_u1.if_extents[idx],
3357 &ifp->if_u1.if_extents[idx + ext_diff], 3357 &ifp->if_u1.if_extents[idx + ext_diff],
3358 (nextents - (idx + ext_diff)) * 3358 (nextents - (idx + ext_diff)) *
3359 sizeof(xfs_bmbt_rec_t)); 3359 sizeof(xfs_bmbt_rec_t));
3360 } 3360 }
3361 memset(&ifp->if_u1.if_extents[nextents - ext_diff], 3361 memset(&ifp->if_u1.if_extents[nextents - ext_diff],
3362 0, ext_diff * sizeof(xfs_bmbt_rec_t)); 3362 0, ext_diff * sizeof(xfs_bmbt_rec_t));
3363 /* 3363 /*
3364 * Reallocate the direct extent list. If the extents 3364 * Reallocate the direct extent list. If the extents
3365 * will fit inside the inode then xfs_iext_realloc_direct 3365 * will fit inside the inode then xfs_iext_realloc_direct
3366 * will switch from direct to inline extent allocation 3366 * will switch from direct to inline extent allocation
3367 * mode for us. 3367 * mode for us.
3368 */ 3368 */
3369 xfs_iext_realloc_direct(ifp, new_size); 3369 xfs_iext_realloc_direct(ifp, new_size);
3370 ifp->if_bytes = new_size; 3370 ifp->if_bytes = new_size;
3371 } 3371 }
3372 3372
3373 /* 3373 /*
3374 * This is called when incore extents are being removed from the 3374 * This is called when incore extents are being removed from the
3375 * indirection array and the extents being removed span multiple extent 3375 * indirection array and the extents being removed span multiple extent
3376 * buffers. The idx parameter contains the file extent index where we 3376 * buffers. The idx parameter contains the file extent index where we
3377 * want to begin removing extents, and the count parameter contains 3377 * want to begin removing extents, and the count parameter contains
3378 * how many extents need to be removed. 3378 * how many extents need to be removed.
3379 * 3379 *
3380 * |-------| |-------| 3380 * |-------| |-------|
3381 * | nex1 | | | nex1 - number of extents before idx 3381 * | nex1 | | | nex1 - number of extents before idx
3382 * |-------| | count | 3382 * |-------| | count |
3383 * | | | | count - number of extents being removed at idx 3383 * | | | | count - number of extents being removed at idx
3384 * | count | |-------| 3384 * | count | |-------|
3385 * | | | nex2 | nex2 - number of extents after idx + count 3385 * | | | nex2 | nex2 - number of extents after idx + count
3386 * |-------| |-------| 3386 * |-------| |-------|
3387 */ 3387 */
3388 void 3388 void
3389 xfs_iext_remove_indirect( 3389 xfs_iext_remove_indirect(
3390 xfs_ifork_t *ifp, /* inode fork pointer */ 3390 xfs_ifork_t *ifp, /* inode fork pointer */
3391 xfs_extnum_t idx, /* index to begin removing extents */ 3391 xfs_extnum_t idx, /* index to begin removing extents */
3392 int count) /* number of extents to remove */ 3392 int count) /* number of extents to remove */
3393 { 3393 {
3394 xfs_ext_irec_t *erp; /* indirection array pointer */ 3394 xfs_ext_irec_t *erp; /* indirection array pointer */
3395 int erp_idx = 0; /* indirection array index */ 3395 int erp_idx = 0; /* indirection array index */
3396 xfs_extnum_t ext_cnt; /* extents left to remove */ 3396 xfs_extnum_t ext_cnt; /* extents left to remove */
3397 xfs_extnum_t ext_diff; /* extents to remove in current list */ 3397 xfs_extnum_t ext_diff; /* extents to remove in current list */
3398 xfs_extnum_t nex1; /* number of extents before idx */ 3398 xfs_extnum_t nex1; /* number of extents before idx */
3399 xfs_extnum_t nex2; /* extents after idx + count */ 3399 xfs_extnum_t nex2; /* extents after idx + count */
3400 int page_idx = idx; /* index in target extent list */ 3400 int page_idx = idx; /* index in target extent list */
3401 3401
3402 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3402 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3403 erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0); 3403 erp = xfs_iext_idx_to_irec(ifp, &page_idx, &erp_idx, 0);
3404 ASSERT(erp != NULL); 3404 ASSERT(erp != NULL);
3405 nex1 = page_idx; 3405 nex1 = page_idx;
3406 ext_cnt = count; 3406 ext_cnt = count;
3407 while (ext_cnt) { 3407 while (ext_cnt) {
3408 nex2 = MAX((erp->er_extcount - (nex1 + ext_cnt)), 0); 3408 nex2 = MAX((erp->er_extcount - (nex1 + ext_cnt)), 0);
3409 ext_diff = MIN(ext_cnt, (erp->er_extcount - nex1)); 3409 ext_diff = MIN(ext_cnt, (erp->er_extcount - nex1));
3410 /* 3410 /*
3411 * Check for deletion of entire list; 3411 * Check for deletion of entire list;
3412 * xfs_iext_irec_remove() updates extent offsets. 3412 * xfs_iext_irec_remove() updates extent offsets.
3413 */ 3413 */
3414 if (ext_diff == erp->er_extcount) { 3414 if (ext_diff == erp->er_extcount) {
3415 xfs_iext_irec_remove(ifp, erp_idx); 3415 xfs_iext_irec_remove(ifp, erp_idx);
3416 ext_cnt -= ext_diff; 3416 ext_cnt -= ext_diff;
3417 nex1 = 0; 3417 nex1 = 0;
3418 if (ext_cnt) { 3418 if (ext_cnt) {
3419 ASSERT(erp_idx < ifp->if_real_bytes / 3419 ASSERT(erp_idx < ifp->if_real_bytes /
3420 XFS_IEXT_BUFSZ); 3420 XFS_IEXT_BUFSZ);
3421 erp = &ifp->if_u1.if_ext_irec[erp_idx]; 3421 erp = &ifp->if_u1.if_ext_irec[erp_idx];
3422 nex1 = 0; 3422 nex1 = 0;
3423 continue; 3423 continue;
3424 } else { 3424 } else {
3425 break; 3425 break;
3426 } 3426 }
3427 } 3427 }
3428 /* Move extents up (if needed) */ 3428 /* Move extents up (if needed) */
3429 if (nex2) { 3429 if (nex2) {
3430 memmove(&erp->er_extbuf[nex1], 3430 memmove(&erp->er_extbuf[nex1],
3431 &erp->er_extbuf[nex1 + ext_diff], 3431 &erp->er_extbuf[nex1 + ext_diff],
3432 nex2 * sizeof(xfs_bmbt_rec_t)); 3432 nex2 * sizeof(xfs_bmbt_rec_t));
3433 } 3433 }
3434 /* Zero out rest of page */ 3434 /* Zero out rest of page */
3435 memset(&erp->er_extbuf[nex1 + nex2], 0, (XFS_IEXT_BUFSZ - 3435 memset(&erp->er_extbuf[nex1 + nex2], 0, (XFS_IEXT_BUFSZ -
3436 ((nex1 + nex2) * sizeof(xfs_bmbt_rec_t)))); 3436 ((nex1 + nex2) * sizeof(xfs_bmbt_rec_t))));
3437 /* Update remaining counters */ 3437 /* Update remaining counters */
3438 erp->er_extcount -= ext_diff; 3438 erp->er_extcount -= ext_diff;
3439 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -ext_diff); 3439 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -ext_diff);
3440 ext_cnt -= ext_diff; 3440 ext_cnt -= ext_diff;
3441 nex1 = 0; 3441 nex1 = 0;
3442 erp_idx++; 3442 erp_idx++;
3443 erp++; 3443 erp++;
3444 } 3444 }
3445 ifp->if_bytes -= count * sizeof(xfs_bmbt_rec_t); 3445 ifp->if_bytes -= count * sizeof(xfs_bmbt_rec_t);
3446 xfs_iext_irec_compact(ifp); 3446 xfs_iext_irec_compact(ifp);
3447 } 3447 }
3448 3448
3449 /* 3449 /*
3450 * Create, destroy, or resize a linear (direct) block of extents. 3450 * Create, destroy, or resize a linear (direct) block of extents.
3451 */ 3451 */
3452 void 3452 void
3453 xfs_iext_realloc_direct( 3453 xfs_iext_realloc_direct(
3454 xfs_ifork_t *ifp, /* inode fork pointer */ 3454 xfs_ifork_t *ifp, /* inode fork pointer */
3455 int new_size) /* new size of extents */ 3455 int new_size) /* new size of extents */
3456 { 3456 {
3457 int rnew_size; /* real new size of extents */ 3457 int rnew_size; /* real new size of extents */
3458 3458
3459 rnew_size = new_size; 3459 rnew_size = new_size;
3460 3460
3461 ASSERT(!(ifp->if_flags & XFS_IFEXTIREC) || 3461 ASSERT(!(ifp->if_flags & XFS_IFEXTIREC) ||
3462 ((new_size >= 0) && (new_size <= XFS_IEXT_BUFSZ) && 3462 ((new_size >= 0) && (new_size <= XFS_IEXT_BUFSZ) &&
3463 (new_size != ifp->if_real_bytes))); 3463 (new_size != ifp->if_real_bytes)));
3464 3464
3465 /* Free extent records */ 3465 /* Free extent records */
3466 if (new_size == 0) { 3466 if (new_size == 0) {
3467 xfs_iext_destroy(ifp); 3467 xfs_iext_destroy(ifp);
3468 } 3468 }
3469 /* Resize direct extent list and zero any new bytes */ 3469 /* Resize direct extent list and zero any new bytes */
3470 else if (ifp->if_real_bytes) { 3470 else if (ifp->if_real_bytes) {
3471 /* Check if extents will fit inside the inode */ 3471 /* Check if extents will fit inside the inode */
3472 if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) { 3472 if (new_size <= XFS_INLINE_EXTS * sizeof(xfs_bmbt_rec_t)) {
3473 xfs_iext_direct_to_inline(ifp, new_size / 3473 xfs_iext_direct_to_inline(ifp, new_size /
3474 (uint)sizeof(xfs_bmbt_rec_t)); 3474 (uint)sizeof(xfs_bmbt_rec_t));
3475 ifp->if_bytes = new_size; 3475 ifp->if_bytes = new_size;
3476 return; 3476 return;
3477 } 3477 }
3478 if (!is_power_of_2(new_size)){ 3478 if (!is_power_of_2(new_size)){
3479 rnew_size = roundup_pow_of_two(new_size); 3479 rnew_size = roundup_pow_of_two(new_size);
3480 } 3480 }
3481 if (rnew_size != ifp->if_real_bytes) { 3481 if (rnew_size != ifp->if_real_bytes) {
3482 ifp->if_u1.if_extents = 3482 ifp->if_u1.if_extents =
3483 kmem_realloc(ifp->if_u1.if_extents, 3483 kmem_realloc(ifp->if_u1.if_extents,
3484 rnew_size, 3484 rnew_size,
3485 ifp->if_real_bytes, KM_NOFS); 3485 ifp->if_real_bytes, KM_NOFS);
3486 } 3486 }
3487 if (rnew_size > ifp->if_real_bytes) { 3487 if (rnew_size > ifp->if_real_bytes) {
3488 memset(&ifp->if_u1.if_extents[ifp->if_bytes / 3488 memset(&ifp->if_u1.if_extents[ifp->if_bytes /
3489 (uint)sizeof(xfs_bmbt_rec_t)], 0, 3489 (uint)sizeof(xfs_bmbt_rec_t)], 0,
3490 rnew_size - ifp->if_real_bytes); 3490 rnew_size - ifp->if_real_bytes);
3491 } 3491 }
3492 } 3492 }
3493 /* 3493 /*
3494 * Switch from the inline extent buffer to a direct 3494 * Switch from the inline extent buffer to a direct
3495 * extent list. Be sure to include the inline extent 3495 * extent list. Be sure to include the inline extent
3496 * bytes in new_size. 3496 * bytes in new_size.
3497 */ 3497 */
3498 else { 3498 else {
3499 new_size += ifp->if_bytes; 3499 new_size += ifp->if_bytes;
3500 if (!is_power_of_2(new_size)) { 3500 if (!is_power_of_2(new_size)) {
3501 rnew_size = roundup_pow_of_two(new_size); 3501 rnew_size = roundup_pow_of_two(new_size);
3502 } 3502 }
3503 xfs_iext_inline_to_direct(ifp, rnew_size); 3503 xfs_iext_inline_to_direct(ifp, rnew_size);
3504 } 3504 }
3505 ifp->if_real_bytes = rnew_size; 3505 ifp->if_real_bytes = rnew_size;
3506 ifp->if_bytes = new_size; 3506 ifp->if_bytes = new_size;
3507 } 3507 }
3508 3508
3509 /* 3509 /*
3510 * Switch from linear (direct) extent records to inline buffer. 3510 * Switch from linear (direct) extent records to inline buffer.
3511 */ 3511 */
3512 void 3512 void
3513 xfs_iext_direct_to_inline( 3513 xfs_iext_direct_to_inline(
3514 xfs_ifork_t *ifp, /* inode fork pointer */ 3514 xfs_ifork_t *ifp, /* inode fork pointer */
3515 xfs_extnum_t nextents) /* number of extents in file */ 3515 xfs_extnum_t nextents) /* number of extents in file */
3516 { 3516 {
3517 ASSERT(ifp->if_flags & XFS_IFEXTENTS); 3517 ASSERT(ifp->if_flags & XFS_IFEXTENTS);
3518 ASSERT(nextents <= XFS_INLINE_EXTS); 3518 ASSERT(nextents <= XFS_INLINE_EXTS);
3519 /* 3519 /*
3520 * The inline buffer was zeroed when we switched 3520 * The inline buffer was zeroed when we switched
3521 * from inline to direct extent allocation mode, 3521 * from inline to direct extent allocation mode,
3522 * so we don't need to clear it here. 3522 * so we don't need to clear it here.
3523 */ 3523 */
3524 memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, 3524 memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
3525 nextents * sizeof(xfs_bmbt_rec_t)); 3525 nextents * sizeof(xfs_bmbt_rec_t));
3526 kmem_free(ifp->if_u1.if_extents); 3526 kmem_free(ifp->if_u1.if_extents);
3527 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; 3527 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
3528 ifp->if_real_bytes = 0; 3528 ifp->if_real_bytes = 0;
3529 } 3529 }
3530 3530
3531 /* 3531 /*
3532 * Switch from inline buffer to linear (direct) extent records. 3532 * Switch from inline buffer to linear (direct) extent records.
3533 * new_size should already be rounded up to the next power of 2 3533 * new_size should already be rounded up to the next power of 2
3534 * by the caller (when appropriate), so use new_size as it is. 3534 * by the caller (when appropriate), so use new_size as it is.
3535 * However, since new_size may be rounded up, we can't update 3535 * However, since new_size may be rounded up, we can't update
3536 * if_bytes here. It is the caller's responsibility to update 3536 * if_bytes here. It is the caller's responsibility to update
3537 * if_bytes upon return. 3537 * if_bytes upon return.
3538 */ 3538 */
3539 void 3539 void
3540 xfs_iext_inline_to_direct( 3540 xfs_iext_inline_to_direct(
3541 xfs_ifork_t *ifp, /* inode fork pointer */ 3541 xfs_ifork_t *ifp, /* inode fork pointer */
3542 int new_size) /* number of extents in file */ 3542 int new_size) /* number of extents in file */
3543 { 3543 {
3544 ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS); 3544 ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS);
3545 memset(ifp->if_u1.if_extents, 0, new_size); 3545 memset(ifp->if_u1.if_extents, 0, new_size);
3546 if (ifp->if_bytes) { 3546 if (ifp->if_bytes) {
3547 memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, 3547 memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext,
3548 ifp->if_bytes); 3548 ifp->if_bytes);
3549 memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * 3549 memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
3550 sizeof(xfs_bmbt_rec_t)); 3550 sizeof(xfs_bmbt_rec_t));
3551 } 3551 }
3552 ifp->if_real_bytes = new_size; 3552 ifp->if_real_bytes = new_size;
3553 } 3553 }
3554 3554
3555 /* 3555 /*
3556 * Resize an extent indirection array to new_size bytes. 3556 * Resize an extent indirection array to new_size bytes.
3557 */ 3557 */
3558 STATIC void 3558 STATIC void
3559 xfs_iext_realloc_indirect( 3559 xfs_iext_realloc_indirect(
3560 xfs_ifork_t *ifp, /* inode fork pointer */ 3560 xfs_ifork_t *ifp, /* inode fork pointer */
3561 int new_size) /* new indirection array size */ 3561 int new_size) /* new indirection array size */
3562 { 3562 {
3563 int nlists; /* number of irec's (ex lists) */ 3563 int nlists; /* number of irec's (ex lists) */
3564 int size; /* current indirection array size */ 3564 int size; /* current indirection array size */
3565 3565
3566 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3566 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3567 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3567 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3568 size = nlists * sizeof(xfs_ext_irec_t); 3568 size = nlists * sizeof(xfs_ext_irec_t);
3569 ASSERT(ifp->if_real_bytes); 3569 ASSERT(ifp->if_real_bytes);
3570 ASSERT((new_size >= 0) && (new_size != size)); 3570 ASSERT((new_size >= 0) && (new_size != size));
3571 if (new_size == 0) { 3571 if (new_size == 0) {
3572 xfs_iext_destroy(ifp); 3572 xfs_iext_destroy(ifp);
3573 } else { 3573 } else {
3574 ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *) 3574 ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *)
3575 kmem_realloc(ifp->if_u1.if_ext_irec, 3575 kmem_realloc(ifp->if_u1.if_ext_irec,
3576 new_size, size, KM_NOFS); 3576 new_size, size, KM_NOFS);
3577 } 3577 }
3578 } 3578 }
3579 3579
3580 /* 3580 /*
3581 * Switch from indirection array to linear (direct) extent allocations. 3581 * Switch from indirection array to linear (direct) extent allocations.
3582 */ 3582 */
3583 STATIC void 3583 STATIC void
3584 xfs_iext_indirect_to_direct( 3584 xfs_iext_indirect_to_direct(
3585 xfs_ifork_t *ifp) /* inode fork pointer */ 3585 xfs_ifork_t *ifp) /* inode fork pointer */
3586 { 3586 {
3587 xfs_bmbt_rec_host_t *ep; /* extent record pointer */ 3587 xfs_bmbt_rec_host_t *ep; /* extent record pointer */
3588 xfs_extnum_t nextents; /* number of extents in file */ 3588 xfs_extnum_t nextents; /* number of extents in file */
3589 int size; /* size of file extents */ 3589 int size; /* size of file extents */
3590 3590
3591 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3591 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3592 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3592 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3593 ASSERT(nextents <= XFS_LINEAR_EXTS); 3593 ASSERT(nextents <= XFS_LINEAR_EXTS);
3594 size = nextents * sizeof(xfs_bmbt_rec_t); 3594 size = nextents * sizeof(xfs_bmbt_rec_t);
3595 3595
3596 xfs_iext_irec_compact_pages(ifp); 3596 xfs_iext_irec_compact_pages(ifp);
3597 ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); 3597 ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ);
3598 3598
3599 ep = ifp->if_u1.if_ext_irec->er_extbuf; 3599 ep = ifp->if_u1.if_ext_irec->er_extbuf;
3600 kmem_free(ifp->if_u1.if_ext_irec); 3600 kmem_free(ifp->if_u1.if_ext_irec);
3601 ifp->if_flags &= ~XFS_IFEXTIREC; 3601 ifp->if_flags &= ~XFS_IFEXTIREC;
3602 ifp->if_u1.if_extents = ep; 3602 ifp->if_u1.if_extents = ep;
3603 ifp->if_bytes = size; 3603 ifp->if_bytes = size;
3604 if (nextents < XFS_LINEAR_EXTS) { 3604 if (nextents < XFS_LINEAR_EXTS) {
3605 xfs_iext_realloc_direct(ifp, size); 3605 xfs_iext_realloc_direct(ifp, size);
3606 } 3606 }
3607 } 3607 }
3608 3608
3609 /* 3609 /*
3610 * Free incore file extents. 3610 * Free incore file extents.
3611 */ 3611 */
3612 void 3612 void
3613 xfs_iext_destroy( 3613 xfs_iext_destroy(
3614 xfs_ifork_t *ifp) /* inode fork pointer */ 3614 xfs_ifork_t *ifp) /* inode fork pointer */
3615 { 3615 {
3616 if (ifp->if_flags & XFS_IFEXTIREC) { 3616 if (ifp->if_flags & XFS_IFEXTIREC) {
3617 int erp_idx; 3617 int erp_idx;
3618 int nlists; 3618 int nlists;
3619 3619
3620 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3620 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3621 for (erp_idx = nlists - 1; erp_idx >= 0 ; erp_idx--) { 3621 for (erp_idx = nlists - 1; erp_idx >= 0 ; erp_idx--) {
3622 xfs_iext_irec_remove(ifp, erp_idx); 3622 xfs_iext_irec_remove(ifp, erp_idx);
3623 } 3623 }
3624 ifp->if_flags &= ~XFS_IFEXTIREC; 3624 ifp->if_flags &= ~XFS_IFEXTIREC;
3625 } else if (ifp->if_real_bytes) { 3625 } else if (ifp->if_real_bytes) {
3626 kmem_free(ifp->if_u1.if_extents); 3626 kmem_free(ifp->if_u1.if_extents);
3627 } else if (ifp->if_bytes) { 3627 } else if (ifp->if_bytes) {
3628 memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * 3628 memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
3629 sizeof(xfs_bmbt_rec_t)); 3629 sizeof(xfs_bmbt_rec_t));
3630 } 3630 }
3631 ifp->if_u1.if_extents = NULL; 3631 ifp->if_u1.if_extents = NULL;
3632 ifp->if_real_bytes = 0; 3632 ifp->if_real_bytes = 0;
3633 ifp->if_bytes = 0; 3633 ifp->if_bytes = 0;
3634 } 3634 }
3635 3635
3636 /* 3636 /*
3637 * Return a pointer to the extent record for file system block bno. 3637 * Return a pointer to the extent record for file system block bno.
3638 */ 3638 */
3639 xfs_bmbt_rec_host_t * /* pointer to found extent record */ 3639 xfs_bmbt_rec_host_t * /* pointer to found extent record */
3640 xfs_iext_bno_to_ext( 3640 xfs_iext_bno_to_ext(
3641 xfs_ifork_t *ifp, /* inode fork pointer */ 3641 xfs_ifork_t *ifp, /* inode fork pointer */
3642 xfs_fileoff_t bno, /* block number to search for */ 3642 xfs_fileoff_t bno, /* block number to search for */
3643 xfs_extnum_t *idxp) /* index of target extent */ 3643 xfs_extnum_t *idxp) /* index of target extent */
3644 { 3644 {
3645 xfs_bmbt_rec_host_t *base; /* pointer to first extent */ 3645 xfs_bmbt_rec_host_t *base; /* pointer to first extent */
3646 xfs_filblks_t blockcount = 0; /* number of blocks in extent */ 3646 xfs_filblks_t blockcount = 0; /* number of blocks in extent */
3647 xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */ 3647 xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */
3648 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ 3648 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
3649 int high; /* upper boundary in search */ 3649 int high; /* upper boundary in search */
3650 xfs_extnum_t idx = 0; /* index of target extent */ 3650 xfs_extnum_t idx = 0; /* index of target extent */
3651 int low; /* lower boundary in search */ 3651 int low; /* lower boundary in search */
3652 xfs_extnum_t nextents; /* number of file extents */ 3652 xfs_extnum_t nextents; /* number of file extents */
3653 xfs_fileoff_t startoff = 0; /* start offset of extent */ 3653 xfs_fileoff_t startoff = 0; /* start offset of extent */
3654 3654
3655 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3655 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3656 if (nextents == 0) { 3656 if (nextents == 0) {
3657 *idxp = 0; 3657 *idxp = 0;
3658 return NULL; 3658 return NULL;
3659 } 3659 }
3660 low = 0; 3660 low = 0;
3661 if (ifp->if_flags & XFS_IFEXTIREC) { 3661 if (ifp->if_flags & XFS_IFEXTIREC) {
3662 /* Find target extent list */ 3662 /* Find target extent list */
3663 int erp_idx = 0; 3663 int erp_idx = 0;
3664 erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx); 3664 erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx);
3665 base = erp->er_extbuf; 3665 base = erp->er_extbuf;
3666 high = erp->er_extcount - 1; 3666 high = erp->er_extcount - 1;
3667 } else { 3667 } else {
3668 base = ifp->if_u1.if_extents; 3668 base = ifp->if_u1.if_extents;
3669 high = nextents - 1; 3669 high = nextents - 1;
3670 } 3670 }
3671 /* Binary search extent records */ 3671 /* Binary search extent records */
3672 while (low <= high) { 3672 while (low <= high) {
3673 idx = (low + high) >> 1; 3673 idx = (low + high) >> 1;
3674 ep = base + idx; 3674 ep = base + idx;
3675 startoff = xfs_bmbt_get_startoff(ep); 3675 startoff = xfs_bmbt_get_startoff(ep);
3676 blockcount = xfs_bmbt_get_blockcount(ep); 3676 blockcount = xfs_bmbt_get_blockcount(ep);
3677 if (bno < startoff) { 3677 if (bno < startoff) {
3678 high = idx - 1; 3678 high = idx - 1;
3679 } else if (bno >= startoff + blockcount) { 3679 } else if (bno >= startoff + blockcount) {
3680 low = idx + 1; 3680 low = idx + 1;
3681 } else { 3681 } else {
3682 /* Convert back to file-based extent index */ 3682 /* Convert back to file-based extent index */
3683 if (ifp->if_flags & XFS_IFEXTIREC) { 3683 if (ifp->if_flags & XFS_IFEXTIREC) {
3684 idx += erp->er_extoff; 3684 idx += erp->er_extoff;
3685 } 3685 }
3686 *idxp = idx; 3686 *idxp = idx;
3687 return ep; 3687 return ep;
3688 } 3688 }
3689 } 3689 }
3690 /* Convert back to file-based extent index */ 3690 /* Convert back to file-based extent index */
3691 if (ifp->if_flags & XFS_IFEXTIREC) { 3691 if (ifp->if_flags & XFS_IFEXTIREC) {
3692 idx += erp->er_extoff; 3692 idx += erp->er_extoff;
3693 } 3693 }
3694 if (bno >= startoff + blockcount) { 3694 if (bno >= startoff + blockcount) {
3695 if (++idx == nextents) { 3695 if (++idx == nextents) {
3696 ep = NULL; 3696 ep = NULL;
3697 } else { 3697 } else {
3698 ep = xfs_iext_get_ext(ifp, idx); 3698 ep = xfs_iext_get_ext(ifp, idx);
3699 } 3699 }
3700 } 3700 }
3701 *idxp = idx; 3701 *idxp = idx;
3702 return ep; 3702 return ep;
3703 } 3703 }
3704 3704
3705 /* 3705 /*
3706 * Return a pointer to the indirection array entry containing the 3706 * Return a pointer to the indirection array entry containing the
3707 * extent record for filesystem block bno. Store the index of the 3707 * extent record for filesystem block bno. Store the index of the
3708 * target irec in *erp_idxp. 3708 * target irec in *erp_idxp.
3709 */ 3709 */
3710 xfs_ext_irec_t * /* pointer to found extent record */ 3710 xfs_ext_irec_t * /* pointer to found extent record */
3711 xfs_iext_bno_to_irec( 3711 xfs_iext_bno_to_irec(
3712 xfs_ifork_t *ifp, /* inode fork pointer */ 3712 xfs_ifork_t *ifp, /* inode fork pointer */
3713 xfs_fileoff_t bno, /* block number to search for */ 3713 xfs_fileoff_t bno, /* block number to search for */
3714 int *erp_idxp) /* irec index of target ext list */ 3714 int *erp_idxp) /* irec index of target ext list */
3715 { 3715 {
3716 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ 3716 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
3717 xfs_ext_irec_t *erp_next; /* next indirection array entry */ 3717 xfs_ext_irec_t *erp_next; /* next indirection array entry */
3718 int erp_idx; /* indirection array index */ 3718 int erp_idx; /* indirection array index */
3719 int nlists; /* number of extent irec's (lists) */ 3719 int nlists; /* number of extent irec's (lists) */
3720 int high; /* binary search upper limit */ 3720 int high; /* binary search upper limit */
3721 int low; /* binary search lower limit */ 3721 int low; /* binary search lower limit */
3722 3722
3723 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3723 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3724 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3724 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3725 erp_idx = 0; 3725 erp_idx = 0;
3726 low = 0; 3726 low = 0;
3727 high = nlists - 1; 3727 high = nlists - 1;
3728 while (low <= high) { 3728 while (low <= high) {
3729 erp_idx = (low + high) >> 1; 3729 erp_idx = (low + high) >> 1;
3730 erp = &ifp->if_u1.if_ext_irec[erp_idx]; 3730 erp = &ifp->if_u1.if_ext_irec[erp_idx];
3731 erp_next = erp_idx < nlists - 1 ? erp + 1 : NULL; 3731 erp_next = erp_idx < nlists - 1 ? erp + 1 : NULL;
3732 if (bno < xfs_bmbt_get_startoff(erp->er_extbuf)) { 3732 if (bno < xfs_bmbt_get_startoff(erp->er_extbuf)) {
3733 high = erp_idx - 1; 3733 high = erp_idx - 1;
3734 } else if (erp_next && bno >= 3734 } else if (erp_next && bno >=
3735 xfs_bmbt_get_startoff(erp_next->er_extbuf)) { 3735 xfs_bmbt_get_startoff(erp_next->er_extbuf)) {
3736 low = erp_idx + 1; 3736 low = erp_idx + 1;
3737 } else { 3737 } else {
3738 break; 3738 break;
3739 } 3739 }
3740 } 3740 }
3741 *erp_idxp = erp_idx; 3741 *erp_idxp = erp_idx;
3742 return erp; 3742 return erp;
3743 } 3743 }
3744 3744
3745 /* 3745 /*
3746 * Return a pointer to the indirection array entry containing the 3746 * Return a pointer to the indirection array entry containing the
3747 * extent record at file extent index *idxp. Store the index of the 3747 * extent record at file extent index *idxp. Store the index of the
3748 * target irec in *erp_idxp and store the page index of the target 3748 * target irec in *erp_idxp and store the page index of the target
3749 * extent record in *idxp. 3749 * extent record in *idxp.
3750 */ 3750 */
3751 xfs_ext_irec_t * 3751 xfs_ext_irec_t *
3752 xfs_iext_idx_to_irec( 3752 xfs_iext_idx_to_irec(
3753 xfs_ifork_t *ifp, /* inode fork pointer */ 3753 xfs_ifork_t *ifp, /* inode fork pointer */
3754 xfs_extnum_t *idxp, /* extent index (file -> page) */ 3754 xfs_extnum_t *idxp, /* extent index (file -> page) */
3755 int *erp_idxp, /* pointer to target irec */ 3755 int *erp_idxp, /* pointer to target irec */
3756 int realloc) /* new bytes were just added */ 3756 int realloc) /* new bytes were just added */
3757 { 3757 {
3758 xfs_ext_irec_t *prev; /* pointer to previous irec */ 3758 xfs_ext_irec_t *prev; /* pointer to previous irec */
3759 xfs_ext_irec_t *erp = NULL; /* pointer to current irec */ 3759 xfs_ext_irec_t *erp = NULL; /* pointer to current irec */
3760 int erp_idx; /* indirection array index */ 3760 int erp_idx; /* indirection array index */
3761 int nlists; /* number of irec's (ex lists) */ 3761 int nlists; /* number of irec's (ex lists) */
3762 int high; /* binary search upper limit */ 3762 int high; /* binary search upper limit */
3763 int low; /* binary search lower limit */ 3763 int low; /* binary search lower limit */
3764 xfs_extnum_t page_idx = *idxp; /* extent index in target list */ 3764 xfs_extnum_t page_idx = *idxp; /* extent index in target list */
3765 3765
3766 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3766 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3767 ASSERT(page_idx >= 0); 3767 ASSERT(page_idx >= 0);
3768 ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t)); 3768 ASSERT(page_idx <= ifp->if_bytes / sizeof(xfs_bmbt_rec_t));
3769 ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc); 3769 ASSERT(page_idx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t) || realloc);
3770 3770
3771 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3771 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3772 erp_idx = 0; 3772 erp_idx = 0;
3773 low = 0; 3773 low = 0;
3774 high = nlists - 1; 3774 high = nlists - 1;
3775 3775
3776 /* Binary search extent irec's */ 3776 /* Binary search extent irec's */
3777 while (low <= high) { 3777 while (low <= high) {
3778 erp_idx = (low + high) >> 1; 3778 erp_idx = (low + high) >> 1;
3779 erp = &ifp->if_u1.if_ext_irec[erp_idx]; 3779 erp = &ifp->if_u1.if_ext_irec[erp_idx];
3780 prev = erp_idx > 0 ? erp - 1 : NULL; 3780 prev = erp_idx > 0 ? erp - 1 : NULL;
3781 if (page_idx < erp->er_extoff || (page_idx == erp->er_extoff && 3781 if (page_idx < erp->er_extoff || (page_idx == erp->er_extoff &&
3782 realloc && prev && prev->er_extcount < XFS_LINEAR_EXTS)) { 3782 realloc && prev && prev->er_extcount < XFS_LINEAR_EXTS)) {
3783 high = erp_idx - 1; 3783 high = erp_idx - 1;
3784 } else if (page_idx > erp->er_extoff + erp->er_extcount || 3784 } else if (page_idx > erp->er_extoff + erp->er_extcount ||
3785 (page_idx == erp->er_extoff + erp->er_extcount && 3785 (page_idx == erp->er_extoff + erp->er_extcount &&
3786 !realloc)) { 3786 !realloc)) {
3787 low = erp_idx + 1; 3787 low = erp_idx + 1;
3788 } else if (page_idx == erp->er_extoff + erp->er_extcount && 3788 } else if (page_idx == erp->er_extoff + erp->er_extcount &&
3789 erp->er_extcount == XFS_LINEAR_EXTS) { 3789 erp->er_extcount == XFS_LINEAR_EXTS) {
3790 ASSERT(realloc); 3790 ASSERT(realloc);
3791 page_idx = 0; 3791 page_idx = 0;
3792 erp_idx++; 3792 erp_idx++;
3793 erp = erp_idx < nlists ? erp + 1 : NULL; 3793 erp = erp_idx < nlists ? erp + 1 : NULL;
3794 break; 3794 break;
3795 } else { 3795 } else {
3796 page_idx -= erp->er_extoff; 3796 page_idx -= erp->er_extoff;
3797 break; 3797 break;
3798 } 3798 }
3799 } 3799 }
3800 *idxp = page_idx; 3800 *idxp = page_idx;
3801 *erp_idxp = erp_idx; 3801 *erp_idxp = erp_idx;
3802 return(erp); 3802 return(erp);
3803 } 3803 }
3804 3804
3805 /* 3805 /*
3806 * Allocate and initialize an indirection array once the space needed 3806 * Allocate and initialize an indirection array once the space needed
3807 * for incore extents increases above XFS_IEXT_BUFSZ. 3807 * for incore extents increases above XFS_IEXT_BUFSZ.
3808 */ 3808 */
3809 void 3809 void
3810 xfs_iext_irec_init( 3810 xfs_iext_irec_init(
3811 xfs_ifork_t *ifp) /* inode fork pointer */ 3811 xfs_ifork_t *ifp) /* inode fork pointer */
3812 { 3812 {
3813 xfs_ext_irec_t *erp; /* indirection array pointer */ 3813 xfs_ext_irec_t *erp; /* indirection array pointer */
3814 xfs_extnum_t nextents; /* number of extents in file */ 3814 xfs_extnum_t nextents; /* number of extents in file */
3815 3815
3816 ASSERT(!(ifp->if_flags & XFS_IFEXTIREC)); 3816 ASSERT(!(ifp->if_flags & XFS_IFEXTIREC));
3817 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3817 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3818 ASSERT(nextents <= XFS_LINEAR_EXTS); 3818 ASSERT(nextents <= XFS_LINEAR_EXTS);
3819 3819
3820 erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS); 3820 erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS);
3821 3821
3822 if (nextents == 0) { 3822 if (nextents == 0) {
3823 ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); 3823 ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS);
3824 } else if (!ifp->if_real_bytes) { 3824 } else if (!ifp->if_real_bytes) {
3825 xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); 3825 xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ);
3826 } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { 3826 } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) {
3827 xfs_iext_realloc_direct(ifp, XFS_IEXT_BUFSZ); 3827 xfs_iext_realloc_direct(ifp, XFS_IEXT_BUFSZ);
3828 } 3828 }
3829 erp->er_extbuf = ifp->if_u1.if_extents; 3829 erp->er_extbuf = ifp->if_u1.if_extents;
3830 erp->er_extcount = nextents; 3830 erp->er_extcount = nextents;
3831 erp->er_extoff = 0; 3831 erp->er_extoff = 0;
3832 3832
3833 ifp->if_flags |= XFS_IFEXTIREC; 3833 ifp->if_flags |= XFS_IFEXTIREC;
3834 ifp->if_real_bytes = XFS_IEXT_BUFSZ; 3834 ifp->if_real_bytes = XFS_IEXT_BUFSZ;
3835 ifp->if_bytes = nextents * sizeof(xfs_bmbt_rec_t); 3835 ifp->if_bytes = nextents * sizeof(xfs_bmbt_rec_t);
3836 ifp->if_u1.if_ext_irec = erp; 3836 ifp->if_u1.if_ext_irec = erp;
3837 3837
3838 return; 3838 return;
3839 } 3839 }
3840 3840
3841 /* 3841 /*
3842 * Allocate and initialize a new entry in the indirection array. 3842 * Allocate and initialize a new entry in the indirection array.
3843 */ 3843 */
3844 xfs_ext_irec_t * 3844 xfs_ext_irec_t *
3845 xfs_iext_irec_new( 3845 xfs_iext_irec_new(
3846 xfs_ifork_t *ifp, /* inode fork pointer */ 3846 xfs_ifork_t *ifp, /* inode fork pointer */
3847 int erp_idx) /* index for new irec */ 3847 int erp_idx) /* index for new irec */
3848 { 3848 {
3849 xfs_ext_irec_t *erp; /* indirection array pointer */ 3849 xfs_ext_irec_t *erp; /* indirection array pointer */
3850 int i; /* loop counter */ 3850 int i; /* loop counter */
3851 int nlists; /* number of irec's (ex lists) */ 3851 int nlists; /* number of irec's (ex lists) */
3852 3852
3853 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3853 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3854 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3854 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3855 3855
3856 /* Resize indirection array */ 3856 /* Resize indirection array */
3857 xfs_iext_realloc_indirect(ifp, ++nlists * 3857 xfs_iext_realloc_indirect(ifp, ++nlists *
3858 sizeof(xfs_ext_irec_t)); 3858 sizeof(xfs_ext_irec_t));
3859 /* 3859 /*
3860 * Move records down in the array so the 3860 * Move records down in the array so the
3861 * new page can use erp_idx. 3861 * new page can use erp_idx.
3862 */ 3862 */
3863 erp = ifp->if_u1.if_ext_irec; 3863 erp = ifp->if_u1.if_ext_irec;
3864 for (i = nlists - 1; i > erp_idx; i--) { 3864 for (i = nlists - 1; i > erp_idx; i--) {
3865 memmove(&erp[i], &erp[i-1], sizeof(xfs_ext_irec_t)); 3865 memmove(&erp[i], &erp[i-1], sizeof(xfs_ext_irec_t));
3866 } 3866 }
3867 ASSERT(i == erp_idx); 3867 ASSERT(i == erp_idx);
3868 3868
3869 /* Initialize new extent record */ 3869 /* Initialize new extent record */
3870 erp = ifp->if_u1.if_ext_irec; 3870 erp = ifp->if_u1.if_ext_irec;
3871 erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); 3871 erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS);
3872 ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; 3872 ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
3873 memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); 3873 memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ);
3874 erp[erp_idx].er_extcount = 0; 3874 erp[erp_idx].er_extcount = 0;
3875 erp[erp_idx].er_extoff = erp_idx > 0 ? 3875 erp[erp_idx].er_extoff = erp_idx > 0 ?
3876 erp[erp_idx-1].er_extoff + erp[erp_idx-1].er_extcount : 0; 3876 erp[erp_idx-1].er_extoff + erp[erp_idx-1].er_extcount : 0;
3877 return (&erp[erp_idx]); 3877 return (&erp[erp_idx]);
3878 } 3878 }
3879 3879
3880 /* 3880 /*
3881 * Remove a record from the indirection array. 3881 * Remove a record from the indirection array.
3882 */ 3882 */
3883 void 3883 void
3884 xfs_iext_irec_remove( 3884 xfs_iext_irec_remove(
3885 xfs_ifork_t *ifp, /* inode fork pointer */ 3885 xfs_ifork_t *ifp, /* inode fork pointer */
3886 int erp_idx) /* irec index to remove */ 3886 int erp_idx) /* irec index to remove */
3887 { 3887 {
3888 xfs_ext_irec_t *erp; /* indirection array pointer */ 3888 xfs_ext_irec_t *erp; /* indirection array pointer */
3889 int i; /* loop counter */ 3889 int i; /* loop counter */
3890 int nlists; /* number of irec's (ex lists) */ 3890 int nlists; /* number of irec's (ex lists) */
3891 3891
3892 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3892 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3893 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3893 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3894 erp = &ifp->if_u1.if_ext_irec[erp_idx]; 3894 erp = &ifp->if_u1.if_ext_irec[erp_idx];
3895 if (erp->er_extbuf) { 3895 if (erp->er_extbuf) {
3896 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, 3896 xfs_iext_irec_update_extoffs(ifp, erp_idx + 1,
3897 -erp->er_extcount); 3897 -erp->er_extcount);
3898 kmem_free(erp->er_extbuf); 3898 kmem_free(erp->er_extbuf);
3899 } 3899 }
3900 /* Compact extent records */ 3900 /* Compact extent records */
3901 erp = ifp->if_u1.if_ext_irec; 3901 erp = ifp->if_u1.if_ext_irec;
3902 for (i = erp_idx; i < nlists - 1; i++) { 3902 for (i = erp_idx; i < nlists - 1; i++) {
3903 memmove(&erp[i], &erp[i+1], sizeof(xfs_ext_irec_t)); 3903 memmove(&erp[i], &erp[i+1], sizeof(xfs_ext_irec_t));
3904 } 3904 }
3905 /* 3905 /*
3906 * Manually free the last extent record from the indirection 3906 * Manually free the last extent record from the indirection
3907 * array. A call to xfs_iext_realloc_indirect() with a size 3907 * array. A call to xfs_iext_realloc_indirect() with a size
3908 * of zero would result in a call to xfs_iext_destroy() which 3908 * of zero would result in a call to xfs_iext_destroy() which
3909 * would in turn call this function again, creating a nasty 3909 * would in turn call this function again, creating a nasty
3910 * infinite loop. 3910 * infinite loop.
3911 */ 3911 */
3912 if (--nlists) { 3912 if (--nlists) {
3913 xfs_iext_realloc_indirect(ifp, 3913 xfs_iext_realloc_indirect(ifp,
3914 nlists * sizeof(xfs_ext_irec_t)); 3914 nlists * sizeof(xfs_ext_irec_t));
3915 } else { 3915 } else {
3916 kmem_free(ifp->if_u1.if_ext_irec); 3916 kmem_free(ifp->if_u1.if_ext_irec);
3917 } 3917 }
3918 ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; 3918 ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
3919 } 3919 }
3920 3920
3921 /* 3921 /*
3922 * This is called to clean up large amounts of unused memory allocated 3922 * This is called to clean up large amounts of unused memory allocated
3923 * by the indirection array. Before compacting anything though, verify 3923 * by the indirection array. Before compacting anything though, verify
3924 * that the indirection array is still needed and switch back to the 3924 * that the indirection array is still needed and switch back to the
3925 * linear extent list (or even the inline buffer) if possible. The 3925 * linear extent list (or even the inline buffer) if possible. The
3926 * compaction policy is as follows: 3926 * compaction policy is as follows:
3927 * 3927 *
3928 * Full Compaction: Extents fit into a single page (or inline buffer) 3928 * Full Compaction: Extents fit into a single page (or inline buffer)
3929 * Partial Compaction: Extents occupy less than 50% of allocated space 3929 * Partial Compaction: Extents occupy less than 50% of allocated space
3930 * No Compaction: Extents occupy at least 50% of allocated space 3930 * No Compaction: Extents occupy at least 50% of allocated space
3931 */ 3931 */
3932 void 3932 void
3933 xfs_iext_irec_compact( 3933 xfs_iext_irec_compact(
3934 xfs_ifork_t *ifp) /* inode fork pointer */ 3934 xfs_ifork_t *ifp) /* inode fork pointer */
3935 { 3935 {
3936 xfs_extnum_t nextents; /* number of extents in file */ 3936 xfs_extnum_t nextents; /* number of extents in file */
3937 int nlists; /* number of irec's (ex lists) */ 3937 int nlists; /* number of irec's (ex lists) */
3938 3938
3939 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3939 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3940 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3940 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3941 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); 3941 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
3942 3942
3943 if (nextents == 0) { 3943 if (nextents == 0) {
3944 xfs_iext_destroy(ifp); 3944 xfs_iext_destroy(ifp);
3945 } else if (nextents <= XFS_INLINE_EXTS) { 3945 } else if (nextents <= XFS_INLINE_EXTS) {
3946 xfs_iext_indirect_to_direct(ifp); 3946 xfs_iext_indirect_to_direct(ifp);
3947 xfs_iext_direct_to_inline(ifp, nextents); 3947 xfs_iext_direct_to_inline(ifp, nextents);
3948 } else if (nextents <= XFS_LINEAR_EXTS) { 3948 } else if (nextents <= XFS_LINEAR_EXTS) {
3949 xfs_iext_indirect_to_direct(ifp); 3949 xfs_iext_indirect_to_direct(ifp);
3950 } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) { 3950 } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) {
3951 xfs_iext_irec_compact_pages(ifp); 3951 xfs_iext_irec_compact_pages(ifp);
3952 } 3952 }
3953 } 3953 }
3954 3954
3955 /* 3955 /*
3956 * Combine extents from neighboring extent pages. 3956 * Combine extents from neighboring extent pages.
3957 */ 3957 */
3958 void 3958 void
3959 xfs_iext_irec_compact_pages( 3959 xfs_iext_irec_compact_pages(
3960 xfs_ifork_t *ifp) /* inode fork pointer */ 3960 xfs_ifork_t *ifp) /* inode fork pointer */
3961 { 3961 {
3962 xfs_ext_irec_t *erp, *erp_next;/* pointers to irec entries */ 3962 xfs_ext_irec_t *erp, *erp_next;/* pointers to irec entries */
3963 int erp_idx = 0; /* indirection array index */ 3963 int erp_idx = 0; /* indirection array index */
3964 int nlists; /* number of irec's (ex lists) */ 3964 int nlists; /* number of irec's (ex lists) */
3965 3965
3966 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 3966 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
3967 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3967 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3968 while (erp_idx < nlists - 1) { 3968 while (erp_idx < nlists - 1) {
3969 erp = &ifp->if_u1.if_ext_irec[erp_idx]; 3969 erp = &ifp->if_u1.if_ext_irec[erp_idx];
3970 erp_next = erp + 1; 3970 erp_next = erp + 1;
3971 if (erp_next->er_extcount <= 3971 if (erp_next->er_extcount <=
3972 (XFS_LINEAR_EXTS - erp->er_extcount)) { 3972 (XFS_LINEAR_EXTS - erp->er_extcount)) {
3973 memcpy(&erp->er_extbuf[erp->er_extcount], 3973 memcpy(&erp->er_extbuf[erp->er_extcount],
3974 erp_next->er_extbuf, erp_next->er_extcount * 3974 erp_next->er_extbuf, erp_next->er_extcount *
3975 sizeof(xfs_bmbt_rec_t)); 3975 sizeof(xfs_bmbt_rec_t));
3976 erp->er_extcount += erp_next->er_extcount; 3976 erp->er_extcount += erp_next->er_extcount;
3977 /* 3977 /*
3978 * Free page before removing extent record 3978 * Free page before removing extent record
3979 * so er_extoffs don't get modified in 3979 * so er_extoffs don't get modified in
3980 * xfs_iext_irec_remove. 3980 * xfs_iext_irec_remove.
3981 */ 3981 */
3982 kmem_free(erp_next->er_extbuf); 3982 kmem_free(erp_next->er_extbuf);
3983 erp_next->er_extbuf = NULL; 3983 erp_next->er_extbuf = NULL;
3984 xfs_iext_irec_remove(ifp, erp_idx + 1); 3984 xfs_iext_irec_remove(ifp, erp_idx + 1);
3985 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 3985 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
3986 } else { 3986 } else {
3987 erp_idx++; 3987 erp_idx++;
3988 } 3988 }
3989 } 3989 }
3990 } 3990 }
3991 3991
3992 /* 3992 /*
3993 * This is called to update the er_extoff field in the indirection 3993 * This is called to update the er_extoff field in the indirection
3994 * array when extents have been added or removed from one of the 3994 * array when extents have been added or removed from one of the
3995 * extent lists. erp_idx contains the irec index to begin updating 3995 * extent lists. erp_idx contains the irec index to begin updating
3996 * at and ext_diff contains the number of extents that were added 3996 * at and ext_diff contains the number of extents that were added
3997 * or removed. 3997 * or removed.
3998 */ 3998 */
3999 void 3999 void
4000 xfs_iext_irec_update_extoffs( 4000 xfs_iext_irec_update_extoffs(
4001 xfs_ifork_t *ifp, /* inode fork pointer */ 4001 xfs_ifork_t *ifp, /* inode fork pointer */
4002 int erp_idx, /* irec index to update */ 4002 int erp_idx, /* irec index to update */
4003 int ext_diff) /* number of new extents */ 4003 int ext_diff) /* number of new extents */
4004 { 4004 {
4005 int i; /* loop counter */ 4005 int i; /* loop counter */
4006 int nlists; /* number of irec's (ex lists */ 4006 int nlists; /* number of irec's (ex lists */
4007 4007
4008 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 4008 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
4009 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; 4009 nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
4010 for (i = erp_idx; i < nlists; i++) { 4010 for (i = erp_idx; i < nlists; i++) {
4011 ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff; 4011 ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff;
4012 } 4012 }
4013 } 4013 }
4014 4014
4015 /* 4015 /*
4016 * Test whether it is appropriate to check an inode for and free post EOF 4016 * Test whether it is appropriate to check an inode for and free post EOF
4017 * blocks. The 'force' parameter determines whether we should also consider 4017 * blocks. The 'force' parameter determines whether we should also consider
4018 * regular files that are marked preallocated or append-only. 4018 * regular files that are marked preallocated or append-only.
4019 */ 4019 */
4020 bool 4020 bool
4021 xfs_can_free_eofblocks(struct xfs_inode *ip, bool force) 4021 xfs_can_free_eofblocks(struct xfs_inode *ip, bool force)
4022 { 4022 {
4023 /* prealloc/delalloc exists only on regular files */ 4023 /* prealloc/delalloc exists only on regular files */
4024 if (!S_ISREG(ip->i_d.di_mode)) 4024 if (!S_ISREG(ip->i_d.di_mode))
4025 return false; 4025 return false;
4026 4026
4027 /* 4027 /*
4028 * Zero sized files with no cached pages and delalloc blocks will not 4028 * Zero sized files with no cached pages and delalloc blocks will not
4029 * have speculative prealloc/delalloc blocks to remove. 4029 * have speculative prealloc/delalloc blocks to remove.
4030 */ 4030 */
4031 if (VFS_I(ip)->i_size == 0 && 4031 if (VFS_I(ip)->i_size == 0 &&
4032 VN_CACHED(VFS_I(ip)) == 0 && 4032 VN_CACHED(VFS_I(ip)) == 0 &&
4033 ip->i_delayed_blks == 0) 4033 ip->i_delayed_blks == 0)
4034 return false; 4034 return false;
4035 4035
4036 /* If we haven't read in the extent list, then don't do it now. */ 4036 /* If we haven't read in the extent list, then don't do it now. */
4037 if (!(ip->i_df.if_flags & XFS_IFEXTENTS)) 4037 if (!(ip->i_df.if_flags & XFS_IFEXTENTS))
4038 return false; 4038 return false;
4039 4039
4040 /* 4040 /*
4041 * Do not free real preallocated or append-only files unless the file 4041 * Do not free real preallocated or append-only files unless the file
4042 * has delalloc blocks and we are forced to remove them. 4042 * has delalloc blocks and we are forced to remove them.
4043 */ 4043 */
4044 if (ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) 4044 if (ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND))
4045 if (!force || ip->i_delayed_blks == 0) 4045 if (!force || ip->i_delayed_blks == 0)
4046 return false; 4046 return false;
4047 4047
4048 return true; 4048 return true;
4049 } 4049 }
4050 4050
4051 4051
1 /* 1 /*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2005 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
6 * modify it under the terms of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
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 */ 17 */
18 #ifndef __XFS_LINUX__ 18 #ifndef __XFS_LINUX__
19 #define __XFS_LINUX__ 19 #define __XFS_LINUX__
20 20
21 #include <linux/types.h> 21 #include <linux/types.h>
22 22
23 /* 23 /*
24 * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits. 24 * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits.
25 * XFS_BIG_INUMS requires XFS_BIG_BLKNOS to be set. 25 * XFS_BIG_INUMS requires XFS_BIG_BLKNOS to be set.
26 */ 26 */
27 #if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64) 27 #if defined(CONFIG_LBDAF) || (BITS_PER_LONG == 64)
28 # define XFS_BIG_BLKNOS 1 28 # define XFS_BIG_BLKNOS 1
29 # define XFS_BIG_INUMS 1 29 # define XFS_BIG_INUMS 1
30 #else 30 #else
31 # define XFS_BIG_BLKNOS 0 31 # define XFS_BIG_BLKNOS 0
32 # define XFS_BIG_INUMS 0 32 # define XFS_BIG_INUMS 0
33 #endif 33 #endif
34 34
35 #include "xfs_types.h" 35 #include "xfs_types.h"
36 36
37 #include "kmem.h" 37 #include "kmem.h"
38 #include "mrlock.h" 38 #include "mrlock.h"
39 #include "time.h" 39 #include "time.h"
40 #include "uuid.h" 40 #include "uuid.h"
41 41
42 #include <linux/semaphore.h> 42 #include <linux/semaphore.h>
43 #include <linux/mm.h> 43 #include <linux/mm.h>
44 #include <linux/kernel.h> 44 #include <linux/kernel.h>
45 #include <linux/blkdev.h> 45 #include <linux/blkdev.h>
46 #include <linux/slab.h> 46 #include <linux/slab.h>
47 #include <linux/crc32c.h> 47 #include <linux/crc32c.h>
48 #include <linux/module.h> 48 #include <linux/module.h>
49 #include <linux/mutex.h> 49 #include <linux/mutex.h>
50 #include <linux/file.h> 50 #include <linux/file.h>
51 #include <linux/swap.h> 51 #include <linux/swap.h>
52 #include <linux/errno.h> 52 #include <linux/errno.h>
53 #include <linux/sched.h> 53 #include <linux/sched.h>
54 #include <linux/bitops.h> 54 #include <linux/bitops.h>
55 #include <linux/major.h> 55 #include <linux/major.h>
56 #include <linux/pagemap.h> 56 #include <linux/pagemap.h>
57 #include <linux/vfs.h> 57 #include <linux/vfs.h>
58 #include <linux/seq_file.h> 58 #include <linux/seq_file.h>
59 #include <linux/init.h> 59 #include <linux/init.h>
60 #include <linux/list.h> 60 #include <linux/list.h>
61 #include <linux/proc_fs.h> 61 #include <linux/proc_fs.h>
62 #include <linux/sort.h> 62 #include <linux/sort.h>
63 #include <linux/cpu.h> 63 #include <linux/cpu.h>
64 #include <linux/notifier.h> 64 #include <linux/notifier.h>
65 #include <linux/delay.h> 65 #include <linux/delay.h>
66 #include <linux/log2.h> 66 #include <linux/log2.h>
67 #include <linux/spinlock.h> 67 #include <linux/spinlock.h>
68 #include <linux/random.h> 68 #include <linux/random.h>
69 #include <linux/ctype.h> 69 #include <linux/ctype.h>
70 #include <linux/writeback.h> 70 #include <linux/writeback.h>
71 #include <linux/capability.h> 71 #include <linux/capability.h>
72 #include <linux/kthread.h> 72 #include <linux/kthread.h>
73 #include <linux/freezer.h> 73 #include <linux/freezer.h>
74 #include <linux/list_sort.h> 74 #include <linux/list_sort.h>
75 #include <linux/ratelimit.h> 75 #include <linux/ratelimit.h>
76 76
77 #include <asm/page.h> 77 #include <asm/page.h>
78 #include <asm/div64.h> 78 #include <asm/div64.h>
79 #include <asm/param.h> 79 #include <asm/param.h>
80 #include <asm/uaccess.h> 80 #include <asm/uaccess.h>
81 #include <asm/byteorder.h> 81 #include <asm/byteorder.h>
82 #include <asm/unaligned.h> 82 #include <asm/unaligned.h>
83 83
84 #include "xfs_vnode.h" 84 #include "xfs_vnode.h"
85 #include "xfs_stats.h" 85 #include "xfs_stats.h"
86 #include "xfs_sysctl.h" 86 #include "xfs_sysctl.h"
87 #include "xfs_iops.h" 87 #include "xfs_iops.h"
88 #include "xfs_aops.h" 88 #include "xfs_aops.h"
89 #include "xfs_super.h" 89 #include "xfs_super.h"
90 #include "xfs_buf.h" 90 #include "xfs_buf.h"
91 #include "xfs_message.h" 91 #include "xfs_message.h"
92 92
93 #ifdef __BIG_ENDIAN 93 #ifdef __BIG_ENDIAN
94 #define XFS_NATIVE_HOST 1 94 #define XFS_NATIVE_HOST 1
95 #else 95 #else
96 #undef XFS_NATIVE_HOST 96 #undef XFS_NATIVE_HOST
97 #endif 97 #endif
98 98
99 /* 99 /*
100 * Feature macros (disable/enable) 100 * Feature macros (disable/enable)
101 */ 101 */
102 #ifdef CONFIG_SMP 102 #ifdef CONFIG_SMP
103 #define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */ 103 #define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
104 #else 104 #else
105 #undef HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */ 105 #undef HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
106 #endif 106 #endif
107 107
108 #define irix_sgid_inherit xfs_params.sgid_inherit.val 108 #define irix_sgid_inherit xfs_params.sgid_inherit.val
109 #define irix_symlink_mode xfs_params.symlink_mode.val 109 #define irix_symlink_mode xfs_params.symlink_mode.val
110 #define xfs_panic_mask xfs_params.panic_mask.val 110 #define xfs_panic_mask xfs_params.panic_mask.val
111 #define xfs_error_level xfs_params.error_level.val 111 #define xfs_error_level xfs_params.error_level.val
112 #define xfs_syncd_centisecs xfs_params.syncd_timer.val 112 #define xfs_syncd_centisecs xfs_params.syncd_timer.val
113 #define xfs_stats_clear xfs_params.stats_clear.val 113 #define xfs_stats_clear xfs_params.stats_clear.val
114 #define xfs_inherit_sync xfs_params.inherit_sync.val 114 #define xfs_inherit_sync xfs_params.inherit_sync.val
115 #define xfs_inherit_nodump xfs_params.inherit_nodump.val 115 #define xfs_inherit_nodump xfs_params.inherit_nodump.val
116 #define xfs_inherit_noatime xfs_params.inherit_noatim.val 116 #define xfs_inherit_noatime xfs_params.inherit_noatim.val
117 #define xfs_buf_timer_centisecs xfs_params.xfs_buf_timer.val 117 #define xfs_buf_timer_centisecs xfs_params.xfs_buf_timer.val
118 #define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val 118 #define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val
119 #define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val 119 #define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
120 #define xfs_rotorstep xfs_params.rotorstep.val 120 #define xfs_rotorstep xfs_params.rotorstep.val
121 #define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val 121 #define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
122 #define xfs_fstrm_centisecs xfs_params.fstrm_timer.val 122 #define xfs_fstrm_centisecs xfs_params.fstrm_timer.val
123 #define xfs_eofb_secs xfs_params.eofb_timer.val 123 #define xfs_eofb_secs xfs_params.eofb_timer.val
124 124
125 #define current_cpu() (raw_smp_processor_id()) 125 #define current_cpu() (raw_smp_processor_id())
126 #define current_pid() (current->pid) 126 #define current_pid() (current->pid)
127 #define current_test_flags(f) (current->flags & (f)) 127 #define current_test_flags(f) (current->flags & (f))
128 #define current_set_flags_nested(sp, f) \ 128 #define current_set_flags_nested(sp, f) \
129 (*(sp) = current->flags, current->flags |= (f)) 129 (*(sp) = current->flags, current->flags |= (f))
130 #define current_clear_flags_nested(sp, f) \ 130 #define current_clear_flags_nested(sp, f) \
131 (*(sp) = current->flags, current->flags &= ~(f)) 131 (*(sp) = current->flags, current->flags &= ~(f))
132 #define current_restore_flags_nested(sp, f) \ 132 #define current_restore_flags_nested(sp, f) \
133 (current->flags = ((current->flags & ~(f)) | (*(sp) & (f)))) 133 (current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
134 134
135 #define spinlock_destroy(lock) 135 #define spinlock_destroy(lock)
136 136
137 #define NBBY 8 /* number of bits per byte */ 137 #define NBBY 8 /* number of bits per byte */
138 138
139 /* 139 /*
140 * Size of block device i/o is parameterized here. 140 * Size of block device i/o is parameterized here.
141 * Currently the system supports page-sized i/o. 141 * Currently the system supports page-sized i/o.
142 */ 142 */
143 #define BLKDEV_IOSHIFT PAGE_CACHE_SHIFT 143 #define BLKDEV_IOSHIFT PAGE_CACHE_SHIFT
144 #define BLKDEV_IOSIZE (1<<BLKDEV_IOSHIFT) 144 #define BLKDEV_IOSIZE (1<<BLKDEV_IOSHIFT)
145 /* number of BB's per block device block */ 145 /* number of BB's per block device block */
146 #define BLKDEV_BB BTOBB(BLKDEV_IOSIZE) 146 #define BLKDEV_BB BTOBB(BLKDEV_IOSIZE)
147 147
148 #define ENOATTR ENODATA /* Attribute not found */ 148 #define ENOATTR ENODATA /* Attribute not found */
149 #define EWRONGFS EINVAL /* Mount with wrong filesystem type */ 149 #define EWRONGFS EINVAL /* Mount with wrong filesystem type */
150 #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ 150 #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
151 151
152 #define SYNCHRONIZE() barrier() 152 #define SYNCHRONIZE() barrier()
153 #define __return_address __builtin_return_address(0) 153 #define __return_address __builtin_return_address(0)
154 154
155 #define XFS_PROJID_DEFAULT 0 155 #define XFS_PROJID_DEFAULT 0
156 #define MAXPATHLEN 1024 156 #define MAXPATHLEN 1024
157 157
158 #define MIN(a,b) (min(a,b)) 158 #define MIN(a,b) (min(a,b))
159 #define MAX(a,b) (max(a,b)) 159 #define MAX(a,b) (max(a,b))
160 #define howmany(x, y) (((x)+((y)-1))/(y)) 160 #define howmany(x, y) (((x)+((y)-1))/(y))
161 161
162 /* 162 /*
163 * Various platform dependent calls that don't fit anywhere else 163 * Various platform dependent calls that don't fit anywhere else
164 */ 164 */
165 #define xfs_sort(a,n,s,fn) sort(a,n,s,fn,NULL) 165 #define xfs_sort(a,n,s,fn) sort(a,n,s,fn,NULL)
166 #define xfs_stack_trace() dump_stack() 166 #define xfs_stack_trace() dump_stack()
167 167
168 168
169 /* Move the kernel do_div definition off to one side */ 169 /* Move the kernel do_div definition off to one side */
170 170
171 #if defined __i386__ 171 #if defined __i386__
172 /* For ia32 we need to pull some tricks to get past various versions 172 /* For ia32 we need to pull some tricks to get past various versions
173 * of the compiler which do not like us using do_div in the middle 173 * of the compiler which do not like us using do_div in the middle
174 * of large functions. 174 * of large functions.
175 */ 175 */
176 static inline __u32 xfs_do_div(void *a, __u32 b, int n) 176 static inline __u32 xfs_do_div(void *a, __u32 b, int n)
177 { 177 {
178 __u32 mod; 178 __u32 mod;
179 179
180 switch (n) { 180 switch (n) {
181 case 4: 181 case 4:
182 mod = *(__u32 *)a % b; 182 mod = *(__u32 *)a % b;
183 *(__u32 *)a = *(__u32 *)a / b; 183 *(__u32 *)a = *(__u32 *)a / b;
184 return mod; 184 return mod;
185 case 8: 185 case 8:
186 { 186 {
187 unsigned long __upper, __low, __high, __mod; 187 unsigned long __upper, __low, __high, __mod;
188 __u64 c = *(__u64 *)a; 188 __u64 c = *(__u64 *)a;
189 __upper = __high = c >> 32; 189 __upper = __high = c >> 32;
190 __low = c; 190 __low = c;
191 if (__high) { 191 if (__high) {
192 __upper = __high % (b); 192 __upper = __high % (b);
193 __high = __high / (b); 193 __high = __high / (b);
194 } 194 }
195 asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); 195 asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper));
196 asm("":"=A" (c):"a" (__low),"d" (__high)); 196 asm("":"=A" (c):"a" (__low),"d" (__high));
197 *(__u64 *)a = c; 197 *(__u64 *)a = c;
198 return __mod; 198 return __mod;
199 } 199 }
200 } 200 }
201 201
202 /* NOTREACHED */ 202 /* NOTREACHED */
203 return 0; 203 return 0;
204 } 204 }
205 205
206 /* Side effect free 64 bit mod operation */ 206 /* Side effect free 64 bit mod operation */
207 static inline __u32 xfs_do_mod(void *a, __u32 b, int n) 207 static inline __u32 xfs_do_mod(void *a, __u32 b, int n)
208 { 208 {
209 switch (n) { 209 switch (n) {
210 case 4: 210 case 4:
211 return *(__u32 *)a % b; 211 return *(__u32 *)a % b;
212 case 8: 212 case 8:
213 { 213 {
214 unsigned long __upper, __low, __high, __mod; 214 unsigned long __upper, __low, __high, __mod;
215 __u64 c = *(__u64 *)a; 215 __u64 c = *(__u64 *)a;
216 __upper = __high = c >> 32; 216 __upper = __high = c >> 32;
217 __low = c; 217 __low = c;
218 if (__high) { 218 if (__high) {
219 __upper = __high % (b); 219 __upper = __high % (b);
220 __high = __high / (b); 220 __high = __high / (b);
221 } 221 }
222 asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); 222 asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper));
223 asm("":"=A" (c):"a" (__low),"d" (__high)); 223 asm("":"=A" (c):"a" (__low),"d" (__high));
224 return __mod; 224 return __mod;
225 } 225 }
226 } 226 }
227 227
228 /* NOTREACHED */ 228 /* NOTREACHED */
229 return 0; 229 return 0;
230 } 230 }
231 #else 231 #else
232 static inline __u32 xfs_do_div(void *a, __u32 b, int n) 232 static inline __u32 xfs_do_div(void *a, __u32 b, int n)
233 { 233 {
234 __u32 mod; 234 __u32 mod;
235 235
236 switch (n) { 236 switch (n) {
237 case 4: 237 case 4:
238 mod = *(__u32 *)a % b; 238 mod = *(__u32 *)a % b;
239 *(__u32 *)a = *(__u32 *)a / b; 239 *(__u32 *)a = *(__u32 *)a / b;
240 return mod; 240 return mod;
241 case 8: 241 case 8:
242 mod = do_div(*(__u64 *)a, b); 242 mod = do_div(*(__u64 *)a, b);
243 return mod; 243 return mod;
244 } 244 }
245 245
246 /* NOTREACHED */ 246 /* NOTREACHED */
247 return 0; 247 return 0;
248 } 248 }
249 249
250 /* Side effect free 64 bit mod operation */ 250 /* Side effect free 64 bit mod operation */
251 static inline __u32 xfs_do_mod(void *a, __u32 b, int n) 251 static inline __u32 xfs_do_mod(void *a, __u32 b, int n)
252 { 252 {
253 switch (n) { 253 switch (n) {
254 case 4: 254 case 4:
255 return *(__u32 *)a % b; 255 return *(__u32 *)a % b;
256 case 8: 256 case 8:
257 { 257 {
258 __u64 c = *(__u64 *)a; 258 __u64 c = *(__u64 *)a;
259 return do_div(c, b); 259 return do_div(c, b);
260 } 260 }
261 } 261 }
262 262
263 /* NOTREACHED */ 263 /* NOTREACHED */
264 return 0; 264 return 0;
265 } 265 }
266 #endif 266 #endif
267 267
268 #undef do_div 268 #undef do_div
269 #define do_div(a, b) xfs_do_div(&(a), (b), sizeof(a)) 269 #define do_div(a, b) xfs_do_div(&(a), (b), sizeof(a))
270 #define do_mod(a, b) xfs_do_mod(&(a), (b), sizeof(a)) 270 #define do_mod(a, b) xfs_do_mod(&(a), (b), sizeof(a))
271 271
272 static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y) 272 static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y)
273 { 273 {
274 x += y - 1; 274 x += y - 1;
275 do_div(x, y); 275 do_div(x, y);
276 return(x * y); 276 return(x * y);
277 } 277 }
278 278
279 static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y) 279 static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y)
280 { 280 {
281 x += y - 1; 281 x += y - 1;
282 do_div(x, y); 282 do_div(x, y);
283 return x; 283 return x;
284 } 284 }
285 285
286 /* ARM old ABI has some weird alignment/padding */ 286 /* ARM old ABI has some weird alignment/padding */
287 #if defined(__arm__) && !defined(__ARM_EABI__) 287 #if defined(__arm__) && !defined(__ARM_EABI__)
288 #define __arch_pack __attribute__((packed)) 288 #define __arch_pack __attribute__((packed))
289 #else 289 #else
290 #define __arch_pack 290 #define __arch_pack
291 #endif 291 #endif
292 292
293 #define ASSERT_ALWAYS(expr) \ 293 #define ASSERT_ALWAYS(expr) \
294 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 294 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
295 295
296 #ifndef DEBUG 296 #ifdef DEBUG
297 #define ASSERT(expr) ((void)0) 297 #define ASSERT(expr) \
298 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
298 299
299 #ifndef STATIC 300 #ifndef STATIC
300 # define STATIC static noinline 301 # define STATIC noinline
301 #endif 302 #endif
302 303
303 #else /* DEBUG */ 304 #else /* !DEBUG */
304 305
306 #ifdef XFS_WARN
307
305 #define ASSERT(expr) \ 308 #define ASSERT(expr) \
306 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 309 (unlikely(expr) ? (void)0 : asswarn(#expr, __FILE__, __LINE__))
307 310
308 #ifndef STATIC 311 #ifndef STATIC
309 # define STATIC noinline 312 # define STATIC static noinline
310 #endif 313 #endif
311 314
315 #else /* !DEBUG && !XFS_WARN */
316
317 #define ASSERT(expr) ((void)0)
318
319 #ifndef STATIC
320 # define STATIC static noinline
321 #endif
322
323 #endif /* XFS_WARN */
312 #endif /* DEBUG */ 324 #endif /* DEBUG */
313 325
314 #endif /* __XFS_LINUX__ */ 326 #endif /* __XFS_LINUX__ */
315 327
fs/xfs/xfs_message.c
1 /* 1 /*
2 * Copyright (c) 2011 Red Hat, Inc. All Rights Reserved. 2 * Copyright (c) 2011 Red Hat, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as 5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 * 7 *
8 * This program is distributed in the hope that it would be useful, 8 * This program is distributed in the hope that it would be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details. 11 * GNU General Public License for more details.
12 * 12 *
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write the Free Software Foundation, 14 * along with this program; if not, write the Free Software Foundation,
15 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 15 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */ 16 */
17 17
18 #include "xfs.h" 18 #include "xfs.h"
19 #include "xfs_fs.h" 19 #include "xfs_fs.h"
20 #include "xfs_types.h" 20 #include "xfs_types.h"
21 #include "xfs_log.h" 21 #include "xfs_log.h"
22 #include "xfs_trans.h" 22 #include "xfs_trans.h"
23 #include "xfs_sb.h" 23 #include "xfs_sb.h"
24 #include "xfs_ag.h" 24 #include "xfs_ag.h"
25 #include "xfs_mount.h" 25 #include "xfs_mount.h"
26 26
27 /* 27 /*
28 * XFS logging functions 28 * XFS logging functions
29 */ 29 */
30 static void 30 static void
31 __xfs_printk( 31 __xfs_printk(
32 const char *level, 32 const char *level,
33 const struct xfs_mount *mp, 33 const struct xfs_mount *mp,
34 struct va_format *vaf) 34 struct va_format *vaf)
35 { 35 {
36 if (mp && mp->m_fsname) { 36 if (mp && mp->m_fsname) {
37 printk("%sXFS (%s): %pV\n", level, mp->m_fsname, vaf); 37 printk("%sXFS (%s): %pV\n", level, mp->m_fsname, vaf);
38 return; 38 return;
39 } 39 }
40 printk("%sXFS: %pV\n", level, vaf); 40 printk("%sXFS: %pV\n", level, vaf);
41 } 41 }
42 42
43 #define define_xfs_printk_level(func, kern_level) \ 43 #define define_xfs_printk_level(func, kern_level) \
44 void func(const struct xfs_mount *mp, const char *fmt, ...) \ 44 void func(const struct xfs_mount *mp, const char *fmt, ...) \
45 { \ 45 { \
46 struct va_format vaf; \ 46 struct va_format vaf; \
47 va_list args; \ 47 va_list args; \
48 \ 48 \
49 va_start(args, fmt); \ 49 va_start(args, fmt); \
50 \ 50 \
51 vaf.fmt = fmt; \ 51 vaf.fmt = fmt; \
52 vaf.va = &args; \ 52 vaf.va = &args; \
53 \ 53 \
54 __xfs_printk(kern_level, mp, &vaf); \ 54 __xfs_printk(kern_level, mp, &vaf); \
55 va_end(args); \ 55 va_end(args); \
56 } \ 56 } \
57 57
58 define_xfs_printk_level(xfs_emerg, KERN_EMERG); 58 define_xfs_printk_level(xfs_emerg, KERN_EMERG);
59 define_xfs_printk_level(xfs_alert, KERN_ALERT); 59 define_xfs_printk_level(xfs_alert, KERN_ALERT);
60 define_xfs_printk_level(xfs_crit, KERN_CRIT); 60 define_xfs_printk_level(xfs_crit, KERN_CRIT);
61 define_xfs_printk_level(xfs_err, KERN_ERR); 61 define_xfs_printk_level(xfs_err, KERN_ERR);
62 define_xfs_printk_level(xfs_warn, KERN_WARNING); 62 define_xfs_printk_level(xfs_warn, KERN_WARNING);
63 define_xfs_printk_level(xfs_notice, KERN_NOTICE); 63 define_xfs_printk_level(xfs_notice, KERN_NOTICE);
64 define_xfs_printk_level(xfs_info, KERN_INFO); 64 define_xfs_printk_level(xfs_info, KERN_INFO);
65 #ifdef DEBUG 65 #ifdef DEBUG
66 define_xfs_printk_level(xfs_debug, KERN_DEBUG); 66 define_xfs_printk_level(xfs_debug, KERN_DEBUG);
67 #endif 67 #endif
68 68
69 void 69 void
70 xfs_alert_tag( 70 xfs_alert_tag(
71 const struct xfs_mount *mp, 71 const struct xfs_mount *mp,
72 int panic_tag, 72 int panic_tag,
73 const char *fmt, ...) 73 const char *fmt, ...)
74 { 74 {
75 struct va_format vaf; 75 struct va_format vaf;
76 va_list args; 76 va_list args;
77 int do_panic = 0; 77 int do_panic = 0;
78 78
79 if (xfs_panic_mask && (xfs_panic_mask & panic_tag)) { 79 if (xfs_panic_mask && (xfs_panic_mask & panic_tag)) {
80 xfs_alert(mp, "Transforming an alert into a BUG."); 80 xfs_alert(mp, "Transforming an alert into a BUG.");
81 do_panic = 1; 81 do_panic = 1;
82 } 82 }
83 83
84 va_start(args, fmt); 84 va_start(args, fmt);
85 85
86 vaf.fmt = fmt; 86 vaf.fmt = fmt;
87 vaf.va = &args; 87 vaf.va = &args;
88 88
89 __xfs_printk(KERN_ALERT, mp, &vaf); 89 __xfs_printk(KERN_ALERT, mp, &vaf);
90 va_end(args); 90 va_end(args);
91 91
92 BUG_ON(do_panic); 92 BUG_ON(do_panic);
93 } 93 }
94 94
95 void 95 void
96 asswarn(char *expr, char *file, int line)
97 {
98 xfs_warn(NULL, "Assertion failed: %s, file: %s, line: %d",
99 expr, file, line);
100 WARN_ON(1);
101 }
102
103 void
96 assfail(char *expr, char *file, int line) 104 assfail(char *expr, char *file, int line)
97 { 105 {
98 xfs_emerg(NULL, "Assertion failed: %s, file: %s, line: %d", 106 xfs_emerg(NULL, "Assertion failed: %s, file: %s, line: %d",
99 expr, file, line); 107 expr, file, line);
100 BUG(); 108 BUG();
101 } 109 }
102 110
103 void 111 void
104 xfs_hex_dump(void *p, int length) 112 xfs_hex_dump(void *p, int length)
105 { 113 {
106 print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_ADDRESS, 16, 1, p, length, 1); 114 print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_ADDRESS, 16, 1, p, length, 1);
107 } 115 }
108 116
fs/xfs/xfs_message.h
1 #ifndef __XFS_MESSAGE_H 1 #ifndef __XFS_MESSAGE_H
2 #define __XFS_MESSAGE_H 1 2 #define __XFS_MESSAGE_H 1
3 3
4 struct xfs_mount; 4 struct xfs_mount;
5 5
6 extern __printf(2, 3) 6 extern __printf(2, 3)
7 void xfs_emerg(const struct xfs_mount *mp, const char *fmt, ...); 7 void xfs_emerg(const struct xfs_mount *mp, const char *fmt, ...);
8 extern __printf(2, 3) 8 extern __printf(2, 3)
9 void xfs_alert(const struct xfs_mount *mp, const char *fmt, ...); 9 void xfs_alert(const struct xfs_mount *mp, const char *fmt, ...);
10 extern __printf(3, 4) 10 extern __printf(3, 4)
11 void xfs_alert_tag(const struct xfs_mount *mp, int tag, const char *fmt, ...); 11 void xfs_alert_tag(const struct xfs_mount *mp, int tag, const char *fmt, ...);
12 extern __printf(2, 3) 12 extern __printf(2, 3)
13 void xfs_crit(const struct xfs_mount *mp, const char *fmt, ...); 13 void xfs_crit(const struct xfs_mount *mp, const char *fmt, ...);
14 extern __printf(2, 3) 14 extern __printf(2, 3)
15 void xfs_err(const struct xfs_mount *mp, const char *fmt, ...); 15 void xfs_err(const struct xfs_mount *mp, const char *fmt, ...);
16 extern __printf(2, 3) 16 extern __printf(2, 3)
17 void xfs_warn(const struct xfs_mount *mp, const char *fmt, ...); 17 void xfs_warn(const struct xfs_mount *mp, const char *fmt, ...);
18 extern __printf(2, 3) 18 extern __printf(2, 3)
19 void xfs_notice(const struct xfs_mount *mp, const char *fmt, ...); 19 void xfs_notice(const struct xfs_mount *mp, const char *fmt, ...);
20 extern __printf(2, 3) 20 extern __printf(2, 3)
21 void xfs_info(const struct xfs_mount *mp, const char *fmt, ...); 21 void xfs_info(const struct xfs_mount *mp, const char *fmt, ...);
22 22
23 #ifdef DEBUG 23 #ifdef DEBUG
24 extern __printf(2, 3) 24 extern __printf(2, 3)
25 void xfs_debug(const struct xfs_mount *mp, const char *fmt, ...); 25 void xfs_debug(const struct xfs_mount *mp, const char *fmt, ...);
26 #else 26 #else
27 static inline __printf(2, 3) 27 static inline __printf(2, 3)
28 void xfs_debug(const struct xfs_mount *mp, const char *fmt, ...) 28 void xfs_debug(const struct xfs_mount *mp, const char *fmt, ...)
29 { 29 {
30 } 30 }
31 #endif 31 #endif
32 32
33 #define xfs_printk_ratelimited(func, dev, fmt, ...) \ 33 #define xfs_printk_ratelimited(func, dev, fmt, ...) \
34 do { \ 34 do { \
35 static DEFINE_RATELIMIT_STATE(_rs, \ 35 static DEFINE_RATELIMIT_STATE(_rs, \
36 DEFAULT_RATELIMIT_INTERVAL, \ 36 DEFAULT_RATELIMIT_INTERVAL, \
37 DEFAULT_RATELIMIT_BURST); \ 37 DEFAULT_RATELIMIT_BURST); \
38 if (__ratelimit(&_rs)) \ 38 if (__ratelimit(&_rs)) \
39 func(dev, fmt, ##__VA_ARGS__); \ 39 func(dev, fmt, ##__VA_ARGS__); \
40 } while (0) 40 } while (0)
41 41
42 #define xfs_emerg_ratelimited(dev, fmt, ...) \ 42 #define xfs_emerg_ratelimited(dev, fmt, ...) \
43 xfs_printk_ratelimited(xfs_emerg, dev, fmt, ##__VA_ARGS__) 43 xfs_printk_ratelimited(xfs_emerg, dev, fmt, ##__VA_ARGS__)
44 #define xfs_alert_ratelimited(dev, fmt, ...) \ 44 #define xfs_alert_ratelimited(dev, fmt, ...) \
45 xfs_printk_ratelimited(xfs_alert, dev, fmt, ##__VA_ARGS__) 45 xfs_printk_ratelimited(xfs_alert, dev, fmt, ##__VA_ARGS__)
46 #define xfs_crit_ratelimited(dev, fmt, ...) \ 46 #define xfs_crit_ratelimited(dev, fmt, ...) \
47 xfs_printk_ratelimited(xfs_crit, dev, fmt, ##__VA_ARGS__) 47 xfs_printk_ratelimited(xfs_crit, dev, fmt, ##__VA_ARGS__)
48 #define xfs_err_ratelimited(dev, fmt, ...) \ 48 #define xfs_err_ratelimited(dev, fmt, ...) \
49 xfs_printk_ratelimited(xfs_err, dev, fmt, ##__VA_ARGS__) 49 xfs_printk_ratelimited(xfs_err, dev, fmt, ##__VA_ARGS__)
50 #define xfs_warn_ratelimited(dev, fmt, ...) \ 50 #define xfs_warn_ratelimited(dev, fmt, ...) \
51 xfs_printk_ratelimited(xfs_warn, dev, fmt, ##__VA_ARGS__) 51 xfs_printk_ratelimited(xfs_warn, dev, fmt, ##__VA_ARGS__)
52 #define xfs_notice_ratelimited(dev, fmt, ...) \ 52 #define xfs_notice_ratelimited(dev, fmt, ...) \
53 xfs_printk_ratelimited(xfs_notice, dev, fmt, ##__VA_ARGS__) 53 xfs_printk_ratelimited(xfs_notice, dev, fmt, ##__VA_ARGS__)
54 #define xfs_info_ratelimited(dev, fmt, ...) \ 54 #define xfs_info_ratelimited(dev, fmt, ...) \
55 xfs_printk_ratelimited(xfs_info, dev, fmt, ##__VA_ARGS__) 55 xfs_printk_ratelimited(xfs_info, dev, fmt, ##__VA_ARGS__)
56 #define xfs_debug_ratelimited(dev, fmt, ...) \ 56 #define xfs_debug_ratelimited(dev, fmt, ...) \
57 xfs_printk_ratelimited(xfs_debug, dev, fmt, ##__VA_ARGS__) 57 xfs_printk_ratelimited(xfs_debug, dev, fmt, ##__VA_ARGS__)
58 58
59 extern void assfail(char *expr, char *f, int l); 59 extern void assfail(char *expr, char *f, int l);
60 extern void asswarn(char *expr, char *f, int l);
60 61
61 extern void xfs_hex_dump(void *p, int length); 62 extern void xfs_hex_dump(void *p, int length);
62 63
63 #endif /* __XFS_MESSAGE_H */ 64 #endif /* __XFS_MESSAGE_H */
64 65
1 /* 1 /*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2002,2005 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
6 * modify it under the terms of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * This program is distributed in the hope that it would be useful, 9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
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 */ 17 */
18 #ifndef __XFS_TRANS_H__ 18 #ifndef __XFS_TRANS_H__
19 #define __XFS_TRANS_H__ 19 #define __XFS_TRANS_H__
20 20
21 struct xfs_log_item; 21 struct xfs_log_item;
22 22
23 /* 23 /*
24 * This is the structure written in the log at the head of 24 * This is the structure written in the log at the head of
25 * every transaction. It identifies the type and id of the 25 * every transaction. It identifies the type and id of the
26 * transaction, and contains the number of items logged by 26 * transaction, and contains the number of items logged by
27 * the transaction so we know how many to expect during recovery. 27 * the transaction so we know how many to expect during recovery.
28 * 28 *
29 * Do not change the below structure without redoing the code in 29 * Do not change the below structure without redoing the code in
30 * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans(). 30 * xlog_recover_add_to_trans() and xlog_recover_add_to_cont_trans().
31 */ 31 */
32 typedef struct xfs_trans_header { 32 typedef struct xfs_trans_header {
33 uint th_magic; /* magic number */ 33 uint th_magic; /* magic number */
34 uint th_type; /* transaction type */ 34 uint th_type; /* transaction type */
35 __int32_t th_tid; /* transaction id (unused) */ 35 __int32_t th_tid; /* transaction id (unused) */
36 uint th_num_items; /* num items logged by trans */ 36 uint th_num_items; /* num items logged by trans */
37 } xfs_trans_header_t; 37 } xfs_trans_header_t;
38 38
39 #define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */ 39 #define XFS_TRANS_HEADER_MAGIC 0x5452414e /* TRAN */
40 40
41 /* 41 /*
42 * Log item types. 42 * Log item types.
43 */ 43 */
44 #define XFS_LI_EFI 0x1236 44 #define XFS_LI_EFI 0x1236
45 #define XFS_LI_EFD 0x1237 45 #define XFS_LI_EFD 0x1237
46 #define XFS_LI_IUNLINK 0x1238 46 #define XFS_LI_IUNLINK 0x1238
47 #define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */ 47 #define XFS_LI_INODE 0x123b /* aligned ino chunks, var-size ibufs */
48 #define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */ 48 #define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */
49 #define XFS_LI_DQUOT 0x123d 49 #define XFS_LI_DQUOT 0x123d
50 #define XFS_LI_QUOTAOFF 0x123e 50 #define XFS_LI_QUOTAOFF 0x123e
51 51
52 #define XFS_LI_TYPE_DESC \ 52 #define XFS_LI_TYPE_DESC \
53 { XFS_LI_EFI, "XFS_LI_EFI" }, \ 53 { XFS_LI_EFI, "XFS_LI_EFI" }, \
54 { XFS_LI_EFD, "XFS_LI_EFD" }, \ 54 { XFS_LI_EFD, "XFS_LI_EFD" }, \
55 { XFS_LI_IUNLINK, "XFS_LI_IUNLINK" }, \ 55 { XFS_LI_IUNLINK, "XFS_LI_IUNLINK" }, \
56 { XFS_LI_INODE, "XFS_LI_INODE" }, \ 56 { XFS_LI_INODE, "XFS_LI_INODE" }, \
57 { XFS_LI_BUF, "XFS_LI_BUF" }, \ 57 { XFS_LI_BUF, "XFS_LI_BUF" }, \
58 { XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \ 58 { XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \
59 { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" } 59 { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" }
60 60
61 /* 61 /*
62 * Transaction types. Used to distinguish types of buffers. 62 * Transaction types. Used to distinguish types of buffers.
63 */ 63 */
64 #define XFS_TRANS_SETATTR_NOT_SIZE 1 64 #define XFS_TRANS_SETATTR_NOT_SIZE 1
65 #define XFS_TRANS_SETATTR_SIZE 2 65 #define XFS_TRANS_SETATTR_SIZE 2
66 #define XFS_TRANS_INACTIVE 3 66 #define XFS_TRANS_INACTIVE 3
67 #define XFS_TRANS_CREATE 4 67 #define XFS_TRANS_CREATE 4
68 #define XFS_TRANS_CREATE_TRUNC 5 68 #define XFS_TRANS_CREATE_TRUNC 5
69 #define XFS_TRANS_TRUNCATE_FILE 6 69 #define XFS_TRANS_TRUNCATE_FILE 6
70 #define XFS_TRANS_REMOVE 7 70 #define XFS_TRANS_REMOVE 7
71 #define XFS_TRANS_LINK 8 71 #define XFS_TRANS_LINK 8
72 #define XFS_TRANS_RENAME 9 72 #define XFS_TRANS_RENAME 9
73 #define XFS_TRANS_MKDIR 10 73 #define XFS_TRANS_MKDIR 10
74 #define XFS_TRANS_RMDIR 11 74 #define XFS_TRANS_RMDIR 11
75 #define XFS_TRANS_SYMLINK 12 75 #define XFS_TRANS_SYMLINK 12
76 #define XFS_TRANS_SET_DMATTRS 13 76 #define XFS_TRANS_SET_DMATTRS 13
77 #define XFS_TRANS_GROWFS 14 77 #define XFS_TRANS_GROWFS 14
78 #define XFS_TRANS_STRAT_WRITE 15 78 #define XFS_TRANS_STRAT_WRITE 15
79 #define XFS_TRANS_DIOSTRAT 16 79 #define XFS_TRANS_DIOSTRAT 16
80 /* 17 was XFS_TRANS_WRITE_SYNC */ 80 /* 17 was XFS_TRANS_WRITE_SYNC */
81 #define XFS_TRANS_WRITEID 18 81 #define XFS_TRANS_WRITEID 18
82 #define XFS_TRANS_ADDAFORK 19 82 #define XFS_TRANS_ADDAFORK 19
83 #define XFS_TRANS_ATTRINVAL 20 83 #define XFS_TRANS_ATTRINVAL 20
84 #define XFS_TRANS_ATRUNCATE 21 84 #define XFS_TRANS_ATRUNCATE 21
85 #define XFS_TRANS_ATTR_SET 22 85 #define XFS_TRANS_ATTR_SET 22
86 #define XFS_TRANS_ATTR_RM 23 86 #define XFS_TRANS_ATTR_RM 23
87 #define XFS_TRANS_ATTR_FLAG 24 87 #define XFS_TRANS_ATTR_FLAG 24
88 #define XFS_TRANS_CLEAR_AGI_BUCKET 25 88 #define XFS_TRANS_CLEAR_AGI_BUCKET 25
89 #define XFS_TRANS_QM_SBCHANGE 26 89 #define XFS_TRANS_QM_SBCHANGE 26
90 /* 90 /*
91 * Dummy entries since we use the transaction type to index into the 91 * Dummy entries since we use the transaction type to index into the
92 * trans_type[] in xlog_recover_print_trans_head() 92 * trans_type[] in xlog_recover_print_trans_head()
93 */ 93 */
94 #define XFS_TRANS_DUMMY1 27 94 #define XFS_TRANS_DUMMY1 27
95 #define XFS_TRANS_DUMMY2 28 95 #define XFS_TRANS_DUMMY2 28
96 #define XFS_TRANS_QM_QUOTAOFF 29 96 #define XFS_TRANS_QM_QUOTAOFF 29
97 #define XFS_TRANS_QM_DQALLOC 30 97 #define XFS_TRANS_QM_DQALLOC 30
98 #define XFS_TRANS_QM_SETQLIM 31 98 #define XFS_TRANS_QM_SETQLIM 31
99 #define XFS_TRANS_QM_DQCLUSTER 32 99 #define XFS_TRANS_QM_DQCLUSTER 32
100 #define XFS_TRANS_QM_QINOCREATE 33 100 #define XFS_TRANS_QM_QINOCREATE 33
101 #define XFS_TRANS_QM_QUOTAOFF_END 34 101 #define XFS_TRANS_QM_QUOTAOFF_END 34
102 #define XFS_TRANS_SB_UNIT 35 102 #define XFS_TRANS_SB_UNIT 35
103 #define XFS_TRANS_FSYNC_TS 36 103 #define XFS_TRANS_FSYNC_TS 36
104 #define XFS_TRANS_GROWFSRT_ALLOC 37 104 #define XFS_TRANS_GROWFSRT_ALLOC 37
105 #define XFS_TRANS_GROWFSRT_ZERO 38 105 #define XFS_TRANS_GROWFSRT_ZERO 38
106 #define XFS_TRANS_GROWFSRT_FREE 39 106 #define XFS_TRANS_GROWFSRT_FREE 39
107 #define XFS_TRANS_SWAPEXT 40 107 #define XFS_TRANS_SWAPEXT 40
108 #define XFS_TRANS_SB_COUNT 41 108 #define XFS_TRANS_SB_COUNT 41
109 #define XFS_TRANS_CHECKPOINT 42 109 #define XFS_TRANS_CHECKPOINT 42
110 #define XFS_TRANS_TYPE_MAX 42 110 #define XFS_TRANS_TYPE_MAX 42
111 /* new transaction types need to be reflected in xfs_logprint(8) */ 111 /* new transaction types need to be reflected in xfs_logprint(8) */
112 112
113 #define XFS_TRANS_TYPES \ 113 #define XFS_TRANS_TYPES \
114 { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \ 114 { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \
115 { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ 115 { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \
116 { XFS_TRANS_INACTIVE, "INACTIVE" }, \ 116 { XFS_TRANS_INACTIVE, "INACTIVE" }, \
117 { XFS_TRANS_CREATE, "CREATE" }, \ 117 { XFS_TRANS_CREATE, "CREATE" }, \
118 { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ 118 { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \
119 { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ 119 { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \
120 { XFS_TRANS_REMOVE, "REMOVE" }, \ 120 { XFS_TRANS_REMOVE, "REMOVE" }, \
121 { XFS_TRANS_LINK, "LINK" }, \ 121 { XFS_TRANS_LINK, "LINK" }, \
122 { XFS_TRANS_RENAME, "RENAME" }, \ 122 { XFS_TRANS_RENAME, "RENAME" }, \
123 { XFS_TRANS_MKDIR, "MKDIR" }, \ 123 { XFS_TRANS_MKDIR, "MKDIR" }, \
124 { XFS_TRANS_RMDIR, "RMDIR" }, \ 124 { XFS_TRANS_RMDIR, "RMDIR" }, \
125 { XFS_TRANS_SYMLINK, "SYMLINK" }, \ 125 { XFS_TRANS_SYMLINK, "SYMLINK" }, \
126 { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \ 126 { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \
127 { XFS_TRANS_GROWFS, "GROWFS" }, \ 127 { XFS_TRANS_GROWFS, "GROWFS" }, \
128 { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \ 128 { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \
129 { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \ 129 { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \
130 { XFS_TRANS_WRITEID, "WRITEID" }, \ 130 { XFS_TRANS_WRITEID, "WRITEID" }, \
131 { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \ 131 { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \
132 { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \ 132 { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \
133 { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \ 133 { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \
134 { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \ 134 { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \
135 { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ 135 { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \
136 { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ 136 { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \
137 { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ 137 { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \
138 { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ 138 { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \
139 { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ 139 { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \
140 { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ 140 { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \
141 { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ 141 { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \
142 { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ 142 { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \
143 { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ 143 { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \
144 { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ 144 { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \
145 { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ 145 { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \
146 { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ 146 { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \
147 { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ 147 { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \
148 { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ 148 { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \
149 { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ 149 { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \
150 { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ 150 { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \
151 { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ 151 { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \
152 { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ 152 { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \
153 { XFS_TRANS_DUMMY1, "DUMMY1" }, \ 153 { XFS_TRANS_DUMMY1, "DUMMY1" }, \
154 { XFS_TRANS_DUMMY2, "DUMMY2" }, \ 154 { XFS_TRANS_DUMMY2, "DUMMY2" }, \
155 { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" } 155 { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" }
156 156
157 /* 157 /*
158 * This structure is used to track log items associated with 158 * This structure is used to track log items associated with
159 * a transaction. It points to the log item and keeps some 159 * a transaction. It points to the log item and keeps some
160 * flags to track the state of the log item. It also tracks 160 * flags to track the state of the log item. It also tracks
161 * the amount of space needed to log the item it describes 161 * the amount of space needed to log the item it describes
162 * once we get to commit processing (see xfs_trans_commit()). 162 * once we get to commit processing (see xfs_trans_commit()).
163 */ 163 */
164 struct xfs_log_item_desc { 164 struct xfs_log_item_desc {
165 struct xfs_log_item *lid_item; 165 struct xfs_log_item *lid_item;
166 struct list_head lid_trans; 166 struct list_head lid_trans;
167 unsigned char lid_flags; 167 unsigned char lid_flags;
168 }; 168 };
169 169
170 #define XFS_LID_DIRTY 0x1 170 #define XFS_LID_DIRTY 0x1
171 171
172 #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ 172 #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */
173 /* 173 /*
174 * Values for t_flags. 174 * Values for t_flags.
175 */ 175 */
176 #define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ 176 #define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */
177 #define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ 177 #define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */
178 #define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ 178 #define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */
179 #define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ 179 #define XFS_TRANS_SYNC 0x08 /* make commit synchronous */
180 #define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */ 180 #define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */
181 #define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */ 181 #define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */
182 #define XFS_TRANS_FREEZE_PROT 0x40 /* Transaction has elevated writer 182 #define XFS_TRANS_FREEZE_PROT 0x40 /* Transaction has elevated writer
183 count in superblock */ 183 count in superblock */
184 184
185 /* 185 /*
186 * Values for call flags parameter. 186 * Values for call flags parameter.
187 */ 187 */
188 #define XFS_TRANS_RELEASE_LOG_RES 0x4 188 #define XFS_TRANS_RELEASE_LOG_RES 0x4
189 #define XFS_TRANS_ABORT 0x8 189 #define XFS_TRANS_ABORT 0x8
190 190
191 /* 191 /*
192 * Field values for xfs_trans_mod_sb. 192 * Field values for xfs_trans_mod_sb.
193 */ 193 */
194 #define XFS_TRANS_SB_ICOUNT 0x00000001 194 #define XFS_TRANS_SB_ICOUNT 0x00000001
195 #define XFS_TRANS_SB_IFREE 0x00000002 195 #define XFS_TRANS_SB_IFREE 0x00000002
196 #define XFS_TRANS_SB_FDBLOCKS 0x00000004 196 #define XFS_TRANS_SB_FDBLOCKS 0x00000004
197 #define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008 197 #define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008
198 #define XFS_TRANS_SB_FREXTENTS 0x00000010 198 #define XFS_TRANS_SB_FREXTENTS 0x00000010
199 #define XFS_TRANS_SB_RES_FREXTENTS 0x00000020 199 #define XFS_TRANS_SB_RES_FREXTENTS 0x00000020
200 #define XFS_TRANS_SB_DBLOCKS 0x00000040 200 #define XFS_TRANS_SB_DBLOCKS 0x00000040
201 #define XFS_TRANS_SB_AGCOUNT 0x00000080 201 #define XFS_TRANS_SB_AGCOUNT 0x00000080
202 #define XFS_TRANS_SB_IMAXPCT 0x00000100 202 #define XFS_TRANS_SB_IMAXPCT 0x00000100
203 #define XFS_TRANS_SB_REXTSIZE 0x00000200 203 #define XFS_TRANS_SB_REXTSIZE 0x00000200
204 #define XFS_TRANS_SB_RBMBLOCKS 0x00000400 204 #define XFS_TRANS_SB_RBMBLOCKS 0x00000400
205 #define XFS_TRANS_SB_RBLOCKS 0x00000800 205 #define XFS_TRANS_SB_RBLOCKS 0x00000800
206 #define XFS_TRANS_SB_REXTENTS 0x00001000 206 #define XFS_TRANS_SB_REXTENTS 0x00001000
207 #define XFS_TRANS_SB_REXTSLOG 0x00002000 207 #define XFS_TRANS_SB_REXTSLOG 0x00002000
208 208
209 209
210 /* 210 /*
211 * Per-extent log reservation for the allocation btree changes 211 * Per-extent log reservation for the allocation btree changes
212 * involved in freeing or allocating an extent. 212 * involved in freeing or allocating an extent.
213 * 2 trees * (2 blocks/level * max depth - 1) * block size 213 * 2 trees * (2 blocks/level * max depth - 1) * block size
214 */ 214 */
215 #define XFS_ALLOCFREE_LOG_RES(mp,nx) \ 215 #define XFS_ALLOCFREE_LOG_RES(mp,nx) \
216 ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1))) 216 ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * XFS_AG_MAXLEVELS(mp) - 1)))
217 #define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ 217 #define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \
218 ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1))) 218 ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1)))
219 219
220 /* 220 /*
221 * Per-directory log reservation for any directory change. 221 * Per-directory log reservation for any directory change.
222 * dir blocks: (1 btree block per level + data block + free block) * dblock size 222 * dir blocks: (1 btree block per level + data block + free block) * dblock size
223 * bmap btree: (levels + 2) * max depth * block size 223 * bmap btree: (levels + 2) * max depth * block size
224 * v2 directory blocks can be fragmented below the dirblksize down to the fsb 224 * v2 directory blocks can be fragmented below the dirblksize down to the fsb
225 * size, so account for that in the DAENTER macros. 225 * size, so account for that in the DAENTER macros.
226 */ 226 */
227 #define XFS_DIROP_LOG_RES(mp) \ 227 #define XFS_DIROP_LOG_RES(mp) \
228 (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \ 228 (XFS_FSB_TO_B(mp, XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK)) + \
229 (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1))) 229 (XFS_FSB_TO_B(mp, XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)))
230 #define XFS_DIROP_LOG_COUNT(mp) \ 230 #define XFS_DIROP_LOG_COUNT(mp) \
231 (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ 231 (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \
232 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) 232 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)
233 233
234 234
235 #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) 235 #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write)
236 #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) 236 #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)
237 #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) 237 #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename)
238 #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) 238 #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link)
239 #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) 239 #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove)
240 #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) 240 #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink)
241 #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) 241 #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create)
242 #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) 242 #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir)
243 #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) 243 #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree)
244 #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) 244 #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange)
245 #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) 245 #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata)
246 #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) 246 #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc)
247 #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) 247 #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero)
248 #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) 248 #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree)
249 #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) 249 #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
250 /* 250 /*
251 * Logging the inode timestamps on an fsync -- same as SWRITE 251 * Logging the inode timestamps on an fsync -- same as SWRITE
252 * as long as SWRITE logs the entire inode core 252 * as long as SWRITE logs the entire inode core
253 */ 253 */
254 #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) 254 #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
255 #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) 255 #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)
256 #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) 256 #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
257 #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) 257 #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval)
258 #define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetm) 258 #define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetm)
259 #define XFS_ATTRSETRT_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetrt) 259 #define XFS_ATTRSETRT_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetrt)
260 #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) 260 #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm)
261 #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) 261 #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi)
262 #define XFS_QM_SBCHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_qm_sbchange) 262 #define XFS_QM_SBCHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_qm_sbchange)
263 #define XFS_QM_SETQLIM_LOG_RES(mp) ((mp)->m_reservations.tr_qm_setqlim) 263 #define XFS_QM_SETQLIM_LOG_RES(mp) ((mp)->m_reservations.tr_qm_setqlim)
264 #define XFS_QM_DQALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_qm_dqalloc) 264 #define XFS_QM_DQALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_qm_dqalloc)
265 #define XFS_QM_QUOTAOFF_LOG_RES(mp) ((mp)->m_reservations.tr_qm_quotaoff) 265 #define XFS_QM_QUOTAOFF_LOG_RES(mp) ((mp)->m_reservations.tr_qm_quotaoff)
266 #define XFS_QM_QUOTAOFF_END_LOG_RES(mp) ((mp)->m_reservations.tr_qm_equotaoff) 266 #define XFS_QM_QUOTAOFF_END_LOG_RES(mp) ((mp)->m_reservations.tr_qm_equotaoff)
267 #define XFS_SB_LOG_RES(mp) ((mp)->m_reservations.tr_sb) 267 #define XFS_SB_LOG_RES(mp) ((mp)->m_reservations.tr_sb)
268 268
269 /* 269 /*
270 * Various log count values. 270 * Various log count values.
271 */ 271 */
272 #define XFS_DEFAULT_LOG_COUNT 1 272 #define XFS_DEFAULT_LOG_COUNT 1
273 #define XFS_DEFAULT_PERM_LOG_COUNT 2 273 #define XFS_DEFAULT_PERM_LOG_COUNT 2
274 #define XFS_ITRUNCATE_LOG_COUNT 2 274 #define XFS_ITRUNCATE_LOG_COUNT 2
275 #define XFS_INACTIVE_LOG_COUNT 2 275 #define XFS_INACTIVE_LOG_COUNT 2
276 #define XFS_CREATE_LOG_COUNT 2 276 #define XFS_CREATE_LOG_COUNT 2
277 #define XFS_MKDIR_LOG_COUNT 3 277 #define XFS_MKDIR_LOG_COUNT 3
278 #define XFS_SYMLINK_LOG_COUNT 3 278 #define XFS_SYMLINK_LOG_COUNT 3
279 #define XFS_REMOVE_LOG_COUNT 2 279 #define XFS_REMOVE_LOG_COUNT 2
280 #define XFS_LINK_LOG_COUNT 2 280 #define XFS_LINK_LOG_COUNT 2
281 #define XFS_RENAME_LOG_COUNT 2 281 #define XFS_RENAME_LOG_COUNT 2
282 #define XFS_WRITE_LOG_COUNT 2 282 #define XFS_WRITE_LOG_COUNT 2
283 #define XFS_ADDAFORK_LOG_COUNT 2 283 #define XFS_ADDAFORK_LOG_COUNT 2
284 #define XFS_ATTRINVAL_LOG_COUNT 1 284 #define XFS_ATTRINVAL_LOG_COUNT 1
285 #define XFS_ATTRSET_LOG_COUNT 3 285 #define XFS_ATTRSET_LOG_COUNT 3
286 #define XFS_ATTRRM_LOG_COUNT 3 286 #define XFS_ATTRRM_LOG_COUNT 3
287 287
288 /* 288 /*
289 * Here we centralize the specification of XFS meta-data buffer 289 * Here we centralize the specification of XFS meta-data buffer
290 * reference count values. This determine how hard the buffer 290 * reference count values. This determine how hard the buffer
291 * cache tries to hold onto the buffer. 291 * cache tries to hold onto the buffer.
292 */ 292 */
293 #define XFS_AGF_REF 4 293 #define XFS_AGF_REF 4
294 #define XFS_AGI_REF 4 294 #define XFS_AGI_REF 4
295 #define XFS_AGFL_REF 3 295 #define XFS_AGFL_REF 3
296 #define XFS_INO_BTREE_REF 3 296 #define XFS_INO_BTREE_REF 3
297 #define XFS_ALLOC_BTREE_REF 2 297 #define XFS_ALLOC_BTREE_REF 2
298 #define XFS_BMAP_BTREE_REF 2 298 #define XFS_BMAP_BTREE_REF 2
299 #define XFS_DIR_BTREE_REF 2 299 #define XFS_DIR_BTREE_REF 2
300 #define XFS_INO_REF 2 300 #define XFS_INO_REF 2
301 #define XFS_ATTR_BTREE_REF 1 301 #define XFS_ATTR_BTREE_REF 1
302 #define XFS_DQUOT_REF 1 302 #define XFS_DQUOT_REF 1
303 303
304 #ifdef __KERNEL__ 304 #ifdef __KERNEL__
305 305
306 struct xfs_buf; 306 struct xfs_buf;
307 struct xfs_buftarg; 307 struct xfs_buftarg;
308 struct xfs_efd_log_item; 308 struct xfs_efd_log_item;
309 struct xfs_efi_log_item; 309 struct xfs_efi_log_item;
310 struct xfs_inode; 310 struct xfs_inode;
311 struct xfs_item_ops; 311 struct xfs_item_ops;
312 struct xfs_log_iovec; 312 struct xfs_log_iovec;
313 struct xfs_log_item_desc; 313 struct xfs_log_item_desc;
314 struct xfs_mount; 314 struct xfs_mount;
315 struct xfs_trans; 315 struct xfs_trans;
316 struct xfs_dquot_acct; 316 struct xfs_dquot_acct;
317 struct xfs_busy_extent; 317 struct xfs_busy_extent;
318 318
319 typedef struct xfs_log_item { 319 typedef struct xfs_log_item {
320 struct list_head li_ail; /* AIL pointers */ 320 struct list_head li_ail; /* AIL pointers */
321 xfs_lsn_t li_lsn; /* last on-disk lsn */ 321 xfs_lsn_t li_lsn; /* last on-disk lsn */
322 struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ 322 struct xfs_log_item_desc *li_desc; /* ptr to current desc*/
323 struct xfs_mount *li_mountp; /* ptr to fs mount */ 323 struct xfs_mount *li_mountp; /* ptr to fs mount */
324 struct xfs_ail *li_ailp; /* ptr to AIL */ 324 struct xfs_ail *li_ailp; /* ptr to AIL */
325 uint li_type; /* item type */ 325 uint li_type; /* item type */
326 uint li_flags; /* misc flags */ 326 uint li_flags; /* misc flags */
327 struct xfs_log_item *li_bio_list; /* buffer item list */ 327 struct xfs_log_item *li_bio_list; /* buffer item list */
328 void (*li_cb)(struct xfs_buf *, 328 void (*li_cb)(struct xfs_buf *,
329 struct xfs_log_item *); 329 struct xfs_log_item *);
330 /* buffer item iodone */ 330 /* buffer item iodone */
331 /* callback func */ 331 /* callback func */
332 const struct xfs_item_ops *li_ops; /* function list */ 332 const struct xfs_item_ops *li_ops; /* function list */
333 333
334 /* delayed logging */ 334 /* delayed logging */
335 struct list_head li_cil; /* CIL pointers */ 335 struct list_head li_cil; /* CIL pointers */
336 struct xfs_log_vec *li_lv; /* active log vector */ 336 struct xfs_log_vec *li_lv; /* active log vector */
337 xfs_lsn_t li_seq; /* CIL commit seq */ 337 xfs_lsn_t li_seq; /* CIL commit seq */
338 } xfs_log_item_t; 338 } xfs_log_item_t;
339 339
340 #define XFS_LI_IN_AIL 0x1 340 #define XFS_LI_IN_AIL 0x1
341 #define XFS_LI_ABORTED 0x2 341 #define XFS_LI_ABORTED 0x2
342 342
343 #define XFS_LI_FLAGS \ 343 #define XFS_LI_FLAGS \
344 { XFS_LI_IN_AIL, "IN_AIL" }, \ 344 { XFS_LI_IN_AIL, "IN_AIL" }, \
345 { XFS_LI_ABORTED, "ABORTED" } 345 { XFS_LI_ABORTED, "ABORTED" }
346 346
347 struct xfs_item_ops { 347 struct xfs_item_ops {
348 uint (*iop_size)(xfs_log_item_t *); 348 uint (*iop_size)(xfs_log_item_t *);
349 void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); 349 void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *);
350 void (*iop_pin)(xfs_log_item_t *); 350 void (*iop_pin)(xfs_log_item_t *);
351 void (*iop_unpin)(xfs_log_item_t *, int remove); 351 void (*iop_unpin)(xfs_log_item_t *, int remove);
352 uint (*iop_push)(struct xfs_log_item *, struct list_head *); 352 uint (*iop_push)(struct xfs_log_item *, struct list_head *);
353 void (*iop_unlock)(xfs_log_item_t *); 353 void (*iop_unlock)(xfs_log_item_t *);
354 xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); 354 xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
355 void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); 355 void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
356 }; 356 };
357 357
358 #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) 358 #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip)
359 #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) 359 #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp)
360 #define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) 360 #define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip)
361 #define IOP_UNPIN(ip, remove) (*(ip)->li_ops->iop_unpin)(ip, remove) 361 #define IOP_UNPIN(ip, remove) (*(ip)->li_ops->iop_unpin)(ip, remove)
362 #define IOP_PUSH(ip, list) (*(ip)->li_ops->iop_push)(ip, list) 362 #define IOP_PUSH(ip, list) (*(ip)->li_ops->iop_push)(ip, list)
363 #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) 363 #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip)
364 #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) 364 #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn)
365 #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) 365 #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn)
366 366
367 /* 367 /*
368 * Return values for the IOP_PUSH() routines. 368 * Return values for the IOP_PUSH() routines.
369 */ 369 */
370 #define XFS_ITEM_SUCCESS 0 370 #define XFS_ITEM_SUCCESS 0
371 #define XFS_ITEM_PINNED 1 371 #define XFS_ITEM_PINNED 1
372 #define XFS_ITEM_LOCKED 2 372 #define XFS_ITEM_LOCKED 2
373 #define XFS_ITEM_FLUSHING 3 373 #define XFS_ITEM_FLUSHING 3
374 374
375 /* 375 /*
376 * This is the type of function which can be given to xfs_trans_callback() 376 * This is the type of function which can be given to xfs_trans_callback()
377 * to be called upon the transaction's commit to disk. 377 * to be called upon the transaction's commit to disk.
378 */ 378 */
379 typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *); 379 typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *);
380 380
381 /* 381 /*
382 * This is the structure maintained for every active transaction. 382 * This is the structure maintained for every active transaction.
383 */ 383 */
384 typedef struct xfs_trans { 384 typedef struct xfs_trans {
385 unsigned int t_magic; /* magic number */ 385 unsigned int t_magic; /* magic number */
386 xfs_log_callback_t t_logcb; /* log callback struct */ 386 xfs_log_callback_t t_logcb; /* log callback struct */
387 unsigned int t_type; /* transaction type */ 387 unsigned int t_type; /* transaction type */
388 unsigned int t_log_res; /* amt of log space resvd */ 388 unsigned int t_log_res; /* amt of log space resvd */
389 unsigned int t_log_count; /* count for perm log res */ 389 unsigned int t_log_count; /* count for perm log res */
390 unsigned int t_blk_res; /* # of blocks resvd */ 390 unsigned int t_blk_res; /* # of blocks resvd */
391 unsigned int t_blk_res_used; /* # of resvd blocks used */ 391 unsigned int t_blk_res_used; /* # of resvd blocks used */
392 unsigned int t_rtx_res; /* # of rt extents resvd */ 392 unsigned int t_rtx_res; /* # of rt extents resvd */
393 unsigned int t_rtx_res_used; /* # of resvd rt extents used */ 393 unsigned int t_rtx_res_used; /* # of resvd rt extents used */
394 struct xlog_ticket *t_ticket; /* log mgr ticket */ 394 struct xlog_ticket *t_ticket; /* log mgr ticket */
395 xfs_lsn_t t_lsn; /* log seq num of start of 395 xfs_lsn_t t_lsn; /* log seq num of start of
396 * transaction. */ 396 * transaction. */
397 xfs_lsn_t t_commit_lsn; /* log seq num of end of 397 xfs_lsn_t t_commit_lsn; /* log seq num of end of
398 * transaction. */ 398 * transaction. */
399 struct xfs_mount *t_mountp; /* ptr to fs mount struct */ 399 struct xfs_mount *t_mountp; /* ptr to fs mount struct */
400 struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ 400 struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */
401 unsigned int t_flags; /* misc flags */ 401 unsigned int t_flags; /* misc flags */
402 int64_t t_icount_delta; /* superblock icount change */ 402 int64_t t_icount_delta; /* superblock icount change */
403 int64_t t_ifree_delta; /* superblock ifree change */ 403 int64_t t_ifree_delta; /* superblock ifree change */
404 int64_t t_fdblocks_delta; /* superblock fdblocks chg */ 404 int64_t t_fdblocks_delta; /* superblock fdblocks chg */
405 int64_t t_res_fdblocks_delta; /* on-disk only chg */ 405 int64_t t_res_fdblocks_delta; /* on-disk only chg */
406 int64_t t_frextents_delta;/* superblock freextents chg*/ 406 int64_t t_frextents_delta;/* superblock freextents chg*/
407 int64_t t_res_frextents_delta; /* on-disk only chg */ 407 int64_t t_res_frextents_delta; /* on-disk only chg */
408 #ifdef DEBUG 408 #if defined(DEBUG) || defined(XFS_WARN)
409 int64_t t_ag_freeblks_delta; /* debugging counter */ 409 int64_t t_ag_freeblks_delta; /* debugging counter */
410 int64_t t_ag_flist_delta; /* debugging counter */ 410 int64_t t_ag_flist_delta; /* debugging counter */
411 int64_t t_ag_btree_delta; /* debugging counter */ 411 int64_t t_ag_btree_delta; /* debugging counter */
412 #endif 412 #endif
413 int64_t t_dblocks_delta;/* superblock dblocks change */ 413 int64_t t_dblocks_delta;/* superblock dblocks change */
414 int64_t t_agcount_delta;/* superblock agcount change */ 414 int64_t t_agcount_delta;/* superblock agcount change */
415 int64_t t_imaxpct_delta;/* superblock imaxpct change */ 415 int64_t t_imaxpct_delta;/* superblock imaxpct change */
416 int64_t t_rextsize_delta;/* superblock rextsize chg */ 416 int64_t t_rextsize_delta;/* superblock rextsize chg */
417 int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */ 417 int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */
418 int64_t t_rblocks_delta;/* superblock rblocks change */ 418 int64_t t_rblocks_delta;/* superblock rblocks change */
419 int64_t t_rextents_delta;/* superblocks rextents chg */ 419 int64_t t_rextents_delta;/* superblocks rextents chg */
420 int64_t t_rextslog_delta;/* superblocks rextslog chg */ 420 int64_t t_rextslog_delta;/* superblocks rextslog chg */
421 struct list_head t_items; /* log item descriptors */ 421 struct list_head t_items; /* log item descriptors */
422 xfs_trans_header_t t_header; /* header for in-log trans */ 422 xfs_trans_header_t t_header; /* header for in-log trans */
423 struct list_head t_busy; /* list of busy extents */ 423 struct list_head t_busy; /* list of busy extents */
424 unsigned long t_pflags; /* saved process flags state */ 424 unsigned long t_pflags; /* saved process flags state */
425 } xfs_trans_t; 425 } xfs_trans_t;
426 426
427 /* 427 /*
428 * XFS transaction mechanism exported interfaces that are 428 * XFS transaction mechanism exported interfaces that are
429 * actually macros. 429 * actually macros.
430 */ 430 */
431 #define xfs_trans_get_log_res(tp) ((tp)->t_log_res) 431 #define xfs_trans_get_log_res(tp) ((tp)->t_log_res)
432 #define xfs_trans_get_log_count(tp) ((tp)->t_log_count) 432 #define xfs_trans_get_log_count(tp) ((tp)->t_log_count)
433 #define xfs_trans_get_block_res(tp) ((tp)->t_blk_res) 433 #define xfs_trans_get_block_res(tp) ((tp)->t_blk_res)
434 #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) 434 #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC)
435 435
436 #ifdef DEBUG 436 #if defined(DEBUG) || defined(XFS_WARN)
437 #define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d) 437 #define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d)
438 #define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d) 438 #define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d)
439 #define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d) 439 #define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d)
440 #else 440 #else
441 #define xfs_trans_agblocks_delta(tp, d) 441 #define xfs_trans_agblocks_delta(tp, d)
442 #define xfs_trans_agflist_delta(tp, d) 442 #define xfs_trans_agflist_delta(tp, d)
443 #define xfs_trans_agbtree_delta(tp, d) 443 #define xfs_trans_agbtree_delta(tp, d)
444 #endif 444 #endif
445 445
446 /* 446 /*
447 * XFS transaction mechanism exported interfaces. 447 * XFS transaction mechanism exported interfaces.
448 */ 448 */
449 xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); 449 xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint);
450 xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, xfs_km_flags_t); 450 xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, xfs_km_flags_t);
451 xfs_trans_t *xfs_trans_dup(xfs_trans_t *); 451 xfs_trans_t *xfs_trans_dup(xfs_trans_t *);
452 int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, 452 int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint,
453 uint, uint); 453 uint, uint);
454 void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); 454 void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t);
455 455
456 struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp, 456 struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp,
457 struct xfs_buftarg *target, 457 struct xfs_buftarg *target,
458 struct xfs_buf_map *map, int nmaps, 458 struct xfs_buf_map *map, int nmaps,
459 uint flags); 459 uint flags);
460 460
461 static inline struct xfs_buf * 461 static inline struct xfs_buf *
462 xfs_trans_get_buf( 462 xfs_trans_get_buf(
463 struct xfs_trans *tp, 463 struct xfs_trans *tp,
464 struct xfs_buftarg *target, 464 struct xfs_buftarg *target,
465 xfs_daddr_t blkno, 465 xfs_daddr_t blkno,
466 int numblks, 466 int numblks,
467 uint flags) 467 uint flags)
468 { 468 {
469 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); 469 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
470 return xfs_trans_get_buf_map(tp, target, &map, 1, flags); 470 return xfs_trans_get_buf_map(tp, target, &map, 1, flags);
471 } 471 }
472 472
473 int xfs_trans_read_buf_map(struct xfs_mount *mp, 473 int xfs_trans_read_buf_map(struct xfs_mount *mp,
474 struct xfs_trans *tp, 474 struct xfs_trans *tp,
475 struct xfs_buftarg *target, 475 struct xfs_buftarg *target,
476 struct xfs_buf_map *map, int nmaps, 476 struct xfs_buf_map *map, int nmaps,
477 xfs_buf_flags_t flags, 477 xfs_buf_flags_t flags,
478 struct xfs_buf **bpp, 478 struct xfs_buf **bpp,
479 const struct xfs_buf_ops *ops); 479 const struct xfs_buf_ops *ops);
480 480
481 static inline int 481 static inline int
482 xfs_trans_read_buf( 482 xfs_trans_read_buf(
483 struct xfs_mount *mp, 483 struct xfs_mount *mp,
484 struct xfs_trans *tp, 484 struct xfs_trans *tp,
485 struct xfs_buftarg *target, 485 struct xfs_buftarg *target,
486 xfs_daddr_t blkno, 486 xfs_daddr_t blkno,
487 int numblks, 487 int numblks,
488 xfs_buf_flags_t flags, 488 xfs_buf_flags_t flags,
489 struct xfs_buf **bpp, 489 struct xfs_buf **bpp,
490 const struct xfs_buf_ops *ops) 490 const struct xfs_buf_ops *ops)
491 { 491 {
492 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); 492 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
493 return xfs_trans_read_buf_map(mp, tp, target, &map, 1, 493 return xfs_trans_read_buf_map(mp, tp, target, &map, 1,
494 flags, bpp, ops); 494 flags, bpp, ops);
495 } 495 }
496 496
497 struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); 497 struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int);
498 498
499 void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); 499 void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *);
500 void xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *); 500 void xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *);
501 void xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *); 501 void xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *);
502 void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *); 502 void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *);
503 void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *); 503 void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *);
504 void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *); 504 void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
505 void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *); 505 void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
506 void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint); 506 void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
507 void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); 507 void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
508 void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); 508 void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int);
509 void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint); 509 void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint);
510 void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); 510 void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
511 void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); 511 void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
512 struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); 512 struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint);
513 void xfs_efi_release(struct xfs_efi_log_item *, uint); 513 void xfs_efi_release(struct xfs_efi_log_item *, uint);
514 void xfs_trans_log_efi_extent(xfs_trans_t *, 514 void xfs_trans_log_efi_extent(xfs_trans_t *,
515 struct xfs_efi_log_item *, 515 struct xfs_efi_log_item *,
516 xfs_fsblock_t, 516 xfs_fsblock_t,
517 xfs_extlen_t); 517 xfs_extlen_t);
518 struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *, 518 struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *,
519 struct xfs_efi_log_item *, 519 struct xfs_efi_log_item *,
520 uint); 520 uint);
521 void xfs_trans_log_efd_extent(xfs_trans_t *, 521 void xfs_trans_log_efd_extent(xfs_trans_t *,
522 struct xfs_efd_log_item *, 522 struct xfs_efd_log_item *,
523 xfs_fsblock_t, 523 xfs_fsblock_t,
524 xfs_extlen_t); 524 xfs_extlen_t);
525 int xfs_trans_commit(xfs_trans_t *, uint flags); 525 int xfs_trans_commit(xfs_trans_t *, uint flags);
526 void xfs_trans_cancel(xfs_trans_t *, int); 526 void xfs_trans_cancel(xfs_trans_t *, int);
527 int xfs_trans_ail_init(struct xfs_mount *); 527 int xfs_trans_ail_init(struct xfs_mount *);
528 void xfs_trans_ail_destroy(struct xfs_mount *); 528 void xfs_trans_ail_destroy(struct xfs_mount *);
529 529
530 extern kmem_zone_t *xfs_trans_zone; 530 extern kmem_zone_t *xfs_trans_zone;
531 extern kmem_zone_t *xfs_log_item_desc_zone; 531 extern kmem_zone_t *xfs_log_item_desc_zone;
532 532
533 #endif /* __KERNEL__ */ 533 #endif /* __KERNEL__ */
534 534
535 void xfs_trans_init(struct xfs_mount *); 535 void xfs_trans_init(struct xfs_mount *);
536 int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); 536 int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *);
537 537
538 #endif /* __XFS_TRANS_H__ */ 538 #endif /* __XFS_TRANS_H__ */
539 539