Commit 3ebe7d2d73179c4874aee4f32e043eb5acd9fa0f
Committed by
Ben Myers
1 parent
5f6bed76c0
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
xfs: Inode create log items
Introduce the inode create log item type for logical inode create logging. Instead of logging the changes in buffers, pass the range to be initialised through the log by a new transaction type. This reduces the amount of log space required to record initialisation during allocation from about 128 bytes per inode to a small fixed amount per inode extent to be initialised. This requires a new log item type to track it through the log and the AIL. This is a relatively simple item - most callbacks are noops as this item has the same life cycle as the transaction. Signed-off-by: Dave Chinner <david@fromorbit.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Showing 6 changed files with 261 additions and 2 deletions Inline Diff
fs/xfs/Makefile
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 | 18 | ||
19 | ccflags-y += -I$(src) # needed for trace events | 19 | ccflags-y += -I$(src) # needed for trace events |
20 | 20 | ||
21 | ccflags-$(CONFIG_XFS_DEBUG) += -g | 21 | ccflags-$(CONFIG_XFS_DEBUG) += -g |
22 | 22 | ||
23 | obj-$(CONFIG_XFS_FS) += xfs.o | 23 | obj-$(CONFIG_XFS_FS) += xfs.o |
24 | 24 | ||
25 | # this one should be compiled first, as the tracing macros can easily blow up | 25 | # this one should be compiled first, as the tracing macros can easily blow up |
26 | xfs-y += xfs_trace.o | 26 | xfs-y += xfs_trace.o |
27 | 27 | ||
28 | # highlevel code | 28 | # highlevel code |
29 | xfs-y += xfs_aops.o \ | 29 | xfs-y += xfs_aops.o \ |
30 | xfs_bit.o \ | 30 | xfs_bit.o \ |
31 | xfs_buf.o \ | 31 | xfs_buf.o \ |
32 | xfs_dfrag.o \ | 32 | xfs_dfrag.o \ |
33 | xfs_discard.o \ | 33 | xfs_discard.o \ |
34 | xfs_error.o \ | 34 | xfs_error.o \ |
35 | xfs_export.o \ | 35 | xfs_export.o \ |
36 | xfs_extent_busy.o \ | 36 | xfs_extent_busy.o \ |
37 | xfs_file.o \ | 37 | xfs_file.o \ |
38 | xfs_filestream.o \ | 38 | xfs_filestream.o \ |
39 | xfs_fsops.o \ | 39 | xfs_fsops.o \ |
40 | xfs_globals.o \ | 40 | xfs_globals.o \ |
41 | xfs_icache.o \ | 41 | xfs_icache.o \ |
42 | xfs_ioctl.o \ | 42 | xfs_ioctl.o \ |
43 | xfs_iomap.o \ | 43 | xfs_iomap.o \ |
44 | xfs_iops.o \ | 44 | xfs_iops.o \ |
45 | xfs_itable.o \ | 45 | xfs_itable.o \ |
46 | xfs_message.o \ | 46 | xfs_message.o \ |
47 | xfs_mru_cache.o \ | 47 | xfs_mru_cache.o \ |
48 | xfs_rename.o \ | 48 | xfs_rename.o \ |
49 | xfs_super.o \ | 49 | xfs_super.o \ |
50 | xfs_utils.o \ | 50 | xfs_utils.o \ |
51 | xfs_vnodeops.o \ | 51 | xfs_vnodeops.o \ |
52 | xfs_xattr.o \ | 52 | xfs_xattr.o \ |
53 | kmem.o \ | 53 | kmem.o \ |
54 | uuid.o | 54 | uuid.o |
55 | 55 | ||
56 | # code shared with libxfs | 56 | # code shared with libxfs |
57 | xfs-y += xfs_alloc.o \ | 57 | xfs-y += xfs_alloc.o \ |
58 | xfs_alloc_btree.o \ | 58 | xfs_alloc_btree.o \ |
59 | xfs_attr.o \ | 59 | xfs_attr.o \ |
60 | xfs_attr_leaf.o \ | 60 | xfs_attr_leaf.o \ |
61 | xfs_attr_remote.o \ | 61 | xfs_attr_remote.o \ |
62 | xfs_bmap.o \ | 62 | xfs_bmap.o \ |
63 | xfs_bmap_btree.o \ | 63 | xfs_bmap_btree.o \ |
64 | xfs_btree.o \ | 64 | xfs_btree.o \ |
65 | xfs_da_btree.o \ | 65 | xfs_da_btree.o \ |
66 | xfs_dir2.o \ | 66 | xfs_dir2.o \ |
67 | xfs_dir2_block.o \ | 67 | xfs_dir2_block.o \ |
68 | xfs_dir2_data.o \ | 68 | xfs_dir2_data.o \ |
69 | xfs_dir2_leaf.o \ | 69 | xfs_dir2_leaf.o \ |
70 | xfs_dir2_node.o \ | 70 | xfs_dir2_node.o \ |
71 | xfs_dir2_sf.o \ | 71 | xfs_dir2_sf.o \ |
72 | xfs_ialloc.o \ | 72 | xfs_ialloc.o \ |
73 | xfs_ialloc_btree.o \ | 73 | xfs_ialloc_btree.o \ |
74 | xfs_icreate_item.o \ | ||
74 | xfs_inode.o \ | 75 | xfs_inode.o \ |
75 | xfs_log_recover.o \ | 76 | xfs_log_recover.o \ |
76 | xfs_mount.o \ | 77 | xfs_mount.o \ |
77 | xfs_symlink.o \ | 78 | xfs_symlink.o \ |
78 | xfs_trans.o | 79 | xfs_trans.o |
79 | 80 | ||
80 | # low-level transaction/log code | 81 | # low-level transaction/log code |
81 | xfs-y += xfs_log.o \ | 82 | xfs-y += xfs_log.o \ |
82 | xfs_log_cil.o \ | 83 | xfs_log_cil.o \ |
83 | xfs_buf_item.o \ | 84 | xfs_buf_item.o \ |
84 | xfs_extfree_item.o \ | 85 | xfs_extfree_item.o \ |
85 | xfs_inode_item.o \ | 86 | xfs_inode_item.o \ |
86 | xfs_trans_ail.o \ | 87 | xfs_trans_ail.o \ |
87 | xfs_trans_buf.o \ | 88 | xfs_trans_buf.o \ |
88 | xfs_trans_extfree.o \ | 89 | xfs_trans_extfree.o \ |
89 | xfs_trans_inode.o \ | 90 | xfs_trans_inode.o \ |
90 | 91 | ||
91 | # optional features | 92 | # optional features |
92 | xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \ | 93 | xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \ |
93 | xfs_dquot_item.o \ | 94 | xfs_dquot_item.o \ |
94 | xfs_trans_dquot.o \ | 95 | xfs_trans_dquot.o \ |
95 | xfs_qm_syscalls.o \ | 96 | xfs_qm_syscalls.o \ |
96 | xfs_qm_bhv.o \ | 97 | xfs_qm_bhv.o \ |
97 | xfs_qm.o \ | 98 | xfs_qm.o \ |
98 | xfs_quotaops.o | 99 | xfs_quotaops.o |
99 | xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o | 100 | xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o |
100 | xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o | 101 | xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o |
101 | xfs-$(CONFIG_PROC_FS) += xfs_stats.o | 102 | xfs-$(CONFIG_PROC_FS) += xfs_stats.o |
102 | xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o | 103 | xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o |
103 | xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o | 104 | xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o |
104 | 105 |
fs/xfs/xfs_icreate_item.c
File was created | 1 | /* | |
2 | * Copyright (c) 2008-2010, 2013 Dave Chinner | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_fs.h" | ||
20 | #include "xfs_types.h" | ||
21 | #include "xfs_bit.h" | ||
22 | #include "xfs_log.h" | ||
23 | #include "xfs_inum.h" | ||
24 | #include "xfs_trans.h" | ||
25 | #include "xfs_buf_item.h" | ||
26 | #include "xfs_sb.h" | ||
27 | #include "xfs_ag.h" | ||
28 | #include "xfs_dir2.h" | ||
29 | #include "xfs_mount.h" | ||
30 | #include "xfs_trans_priv.h" | ||
31 | #include "xfs_bmap_btree.h" | ||
32 | #include "xfs_alloc_btree.h" | ||
33 | #include "xfs_ialloc_btree.h" | ||
34 | #include "xfs_attr_sf.h" | ||
35 | #include "xfs_dinode.h" | ||
36 | #include "xfs_inode.h" | ||
37 | #include "xfs_inode_item.h" | ||
38 | #include "xfs_btree.h" | ||
39 | #include "xfs_ialloc.h" | ||
40 | #include "xfs_error.h" | ||
41 | #include "xfs_icreate_item.h" | ||
42 | |||
43 | kmem_zone_t *xfs_icreate_zone; /* inode create item zone */ | ||
44 | |||
45 | static inline struct xfs_icreate_item *ICR_ITEM(struct xfs_log_item *lip) | ||
46 | { | ||
47 | return container_of(lip, struct xfs_icreate_item, ic_item); | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * This returns the number of iovecs needed to log the given inode item. | ||
52 | * | ||
53 | * We only need one iovec for the icreate log structure. | ||
54 | */ | ||
55 | STATIC uint | ||
56 | xfs_icreate_item_size( | ||
57 | struct xfs_log_item *lip) | ||
58 | { | ||
59 | return 1; | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * This is called to fill in the vector of log iovecs for the | ||
64 | * given inode create log item. | ||
65 | */ | ||
66 | STATIC void | ||
67 | xfs_icreate_item_format( | ||
68 | struct xfs_log_item *lip, | ||
69 | struct xfs_log_iovec *log_vector) | ||
70 | { | ||
71 | struct xfs_icreate_item *icp = ICR_ITEM(lip); | ||
72 | |||
73 | log_vector->i_addr = (xfs_caddr_t)&icp->ic_format; | ||
74 | log_vector->i_len = sizeof(struct xfs_icreate_log); | ||
75 | log_vector->i_type = XLOG_REG_TYPE_ICREATE; | ||
76 | } | ||
77 | |||
78 | |||
79 | /* Pinning has no meaning for the create item, so just return. */ | ||
80 | STATIC void | ||
81 | xfs_icreate_item_pin( | ||
82 | struct xfs_log_item *lip) | ||
83 | { | ||
84 | } | ||
85 | |||
86 | |||
87 | /* pinning has no meaning for the create item, so just return. */ | ||
88 | STATIC void | ||
89 | xfs_icreate_item_unpin( | ||
90 | struct xfs_log_item *lip, | ||
91 | int remove) | ||
92 | { | ||
93 | } | ||
94 | |||
95 | STATIC void | ||
96 | xfs_icreate_item_unlock( | ||
97 | struct xfs_log_item *lip) | ||
98 | { | ||
99 | struct xfs_icreate_item *icp = ICR_ITEM(lip); | ||
100 | |||
101 | if (icp->ic_item.li_flags & XFS_LI_ABORTED) | ||
102 | kmem_zone_free(xfs_icreate_zone, icp); | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * Because we have ordered buffers being tracked in the AIL for the inode | ||
108 | * creation, we don't need the create item after this. Hence we can free | ||
109 | * the log item and return -1 to tell the caller we're done with the item. | ||
110 | */ | ||
111 | STATIC xfs_lsn_t | ||
112 | xfs_icreate_item_committed( | ||
113 | struct xfs_log_item *lip, | ||
114 | xfs_lsn_t lsn) | ||
115 | { | ||
116 | struct xfs_icreate_item *icp = ICR_ITEM(lip); | ||
117 | |||
118 | kmem_zone_free(xfs_icreate_zone, icp); | ||
119 | return (xfs_lsn_t)-1; | ||
120 | } | ||
121 | |||
122 | /* item can never get into the AIL */ | ||
123 | STATIC uint | ||
124 | xfs_icreate_item_push( | ||
125 | struct xfs_log_item *lip, | ||
126 | struct list_head *buffer_list) | ||
127 | { | ||
128 | ASSERT(0); | ||
129 | return XFS_ITEM_SUCCESS; | ||
130 | } | ||
131 | |||
132 | /* Ordered buffers do the dependency tracking here, so this does nothing. */ | ||
133 | STATIC void | ||
134 | xfs_icreate_item_committing( | ||
135 | struct xfs_log_item *lip, | ||
136 | xfs_lsn_t lsn) | ||
137 | { | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * This is the ops vector shared by all buf log items. | ||
142 | */ | ||
143 | static struct xfs_item_ops xfs_icreate_item_ops = { | ||
144 | .iop_size = xfs_icreate_item_size, | ||
145 | .iop_format = xfs_icreate_item_format, | ||
146 | .iop_pin = xfs_icreate_item_pin, | ||
147 | .iop_unpin = xfs_icreate_item_unpin, | ||
148 | .iop_push = xfs_icreate_item_push, | ||
149 | .iop_unlock = xfs_icreate_item_unlock, | ||
150 | .iop_committed = xfs_icreate_item_committed, | ||
151 | .iop_committing = xfs_icreate_item_committing, | ||
152 | }; | ||
153 | |||
154 | |||
155 | /* | ||
156 | * Initialize the inode log item for a newly allocated (in-core) inode. | ||
157 | * | ||
158 | * Inode extents can only reside within an AG. Hence specify the starting | ||
159 | * block for the inode chunk by offset within an AG as well as the | ||
160 | * length of the allocated extent. | ||
161 | * | ||
162 | * This joins the item to the transaction and marks it dirty so | ||
163 | * that we don't need a separate call to do this, nor does the | ||
164 | * caller need to know anything about the icreate item. | ||
165 | */ | ||
166 | void | ||
167 | xfs_icreate_log( | ||
168 | struct xfs_trans *tp, | ||
169 | xfs_agnumber_t agno, | ||
170 | xfs_agblock_t agbno, | ||
171 | unsigned int count, | ||
172 | unsigned int inode_size, | ||
173 | xfs_agblock_t length, | ||
174 | unsigned int generation) | ||
175 | { | ||
176 | struct xfs_icreate_item *icp; | ||
177 | |||
178 | icp = kmem_zone_zalloc(xfs_icreate_zone, KM_SLEEP); | ||
179 | |||
180 | xfs_log_item_init(tp->t_mountp, &icp->ic_item, XFS_LI_ICREATE, | ||
181 | &xfs_icreate_item_ops); | ||
182 | |||
183 | icp->ic_format.icl_type = XFS_LI_ICREATE; | ||
184 | icp->ic_format.icl_size = 1; /* single vector */ | ||
185 | icp->ic_format.icl_ag = cpu_to_be32(agno); | ||
186 | icp->ic_format.icl_agbno = cpu_to_be32(agbno); | ||
187 | icp->ic_format.icl_count = cpu_to_be32(count); | ||
188 | icp->ic_format.icl_isize = cpu_to_be32(inode_size); | ||
189 | icp->ic_format.icl_length = cpu_to_be32(length); | ||
190 | icp->ic_format.icl_gen = cpu_to_be32(generation); | ||
191 | |||
192 | xfs_trans_add_item(tp, &icp->ic_item); | ||
193 | tp->t_flags |= XFS_TRANS_DIRTY; | ||
194 | icp->ic_item.li_desc->lid_flags |= XFS_LID_DIRTY; | ||
195 | } | ||
196 |
fs/xfs/xfs_icreate_item.h
File was created | 1 | /* | |
2 | * Copyright (c) 2008-2010, Dave Chinner | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef XFS_ICREATE_ITEM_H | ||
19 | #define XFS_ICREATE_ITEM_H 1 | ||
20 | |||
21 | /* | ||
22 | * on disk log item structure | ||
23 | * | ||
24 | * Log recovery assumes the first two entries are the type and size and they fit | ||
25 | * in 32 bits. Also in host order (ugh) so they have to be 32 bit aligned so | ||
26 | * decoding can be done correctly. | ||
27 | */ | ||
28 | struct xfs_icreate_log { | ||
29 | __uint16_t icl_type; /* type of log format structure */ | ||
30 | __uint16_t icl_size; /* size of log format structure */ | ||
31 | __be32 icl_ag; /* ag being allocated in */ | ||
32 | __be32 icl_agbno; /* start block of inode range */ | ||
33 | __be32 icl_count; /* number of inodes to initialise */ | ||
34 | __be32 icl_isize; /* size of inodes */ | ||
35 | __be32 icl_length; /* length of extent to initialise */ | ||
36 | __be32 icl_gen; /* inode generation number to use */ | ||
37 | }; | ||
38 | |||
39 | /* in memory log item structure */ | ||
40 | struct xfs_icreate_item { | ||
41 | struct xfs_log_item ic_item; | ||
42 | struct xfs_icreate_log ic_format; | ||
43 | }; | ||
44 | |||
45 | extern kmem_zone_t *xfs_icreate_zone; /* inode create item zone */ | ||
46 | |||
47 | void xfs_icreate_log(struct xfs_trans *tp, xfs_agnumber_t agno, | ||
48 | xfs_agblock_t agbno, unsigned int count, | ||
49 | unsigned int inode_size, xfs_agblock_t length, | ||
50 | unsigned int generation); | ||
51 | |||
52 | #endif /* XFS_ICREATE_ITEM_H */ | ||
53 |
fs/xfs/xfs_log.h
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_LOG_H__ | 18 | #ifndef __XFS_LOG_H__ |
19 | #define __XFS_LOG_H__ | 19 | #define __XFS_LOG_H__ |
20 | 20 | ||
21 | /* get lsn fields */ | 21 | /* get lsn fields */ |
22 | #define CYCLE_LSN(lsn) ((uint)((lsn)>>32)) | 22 | #define CYCLE_LSN(lsn) ((uint)((lsn)>>32)) |
23 | #define BLOCK_LSN(lsn) ((uint)(lsn)) | 23 | #define BLOCK_LSN(lsn) ((uint)(lsn)) |
24 | 24 | ||
25 | /* this is used in a spot where we might otherwise double-endian-flip */ | 25 | /* this is used in a spot where we might otherwise double-endian-flip */ |
26 | #define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0]) | 26 | #define CYCLE_LSN_DISK(lsn) (((__be32 *)&(lsn))[0]) |
27 | 27 | ||
28 | #ifdef __KERNEL__ | 28 | #ifdef __KERNEL__ |
29 | /* | 29 | /* |
30 | * By comparing each component, we don't have to worry about extra | 30 | * By comparing each component, we don't have to worry about extra |
31 | * endian issues in treating two 32 bit numbers as one 64 bit number | 31 | * endian issues in treating two 32 bit numbers as one 64 bit number |
32 | */ | 32 | */ |
33 | static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) | 33 | static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) |
34 | { | 34 | { |
35 | if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2)) | 35 | if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2)) |
36 | return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999; | 36 | return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999; |
37 | 37 | ||
38 | if (BLOCK_LSN(lsn1) != BLOCK_LSN(lsn2)) | 38 | if (BLOCK_LSN(lsn1) != BLOCK_LSN(lsn2)) |
39 | return (BLOCK_LSN(lsn1)<BLOCK_LSN(lsn2))? -999 : 999; | 39 | return (BLOCK_LSN(lsn1)<BLOCK_LSN(lsn2))? -999 : 999; |
40 | 40 | ||
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | #define XFS_LSN_CMP(x,y) _lsn_cmp(x,y) | 44 | #define XFS_LSN_CMP(x,y) _lsn_cmp(x,y) |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * Macros, structures, prototypes for interface to the log manager. | 47 | * Macros, structures, prototypes for interface to the log manager. |
48 | */ | 48 | */ |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Flags to xfs_log_done() | 51 | * Flags to xfs_log_done() |
52 | */ | 52 | */ |
53 | #define XFS_LOG_REL_PERM_RESERV 0x1 | 53 | #define XFS_LOG_REL_PERM_RESERV 0x1 |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Flags to xfs_log_force() | 56 | * Flags to xfs_log_force() |
57 | * | 57 | * |
58 | * XFS_LOG_SYNC: Synchronous force in-core log to disk | 58 | * XFS_LOG_SYNC: Synchronous force in-core log to disk |
59 | */ | 59 | */ |
60 | #define XFS_LOG_SYNC 0x1 | 60 | #define XFS_LOG_SYNC 0x1 |
61 | 61 | ||
62 | #endif /* __KERNEL__ */ | 62 | #endif /* __KERNEL__ */ |
63 | 63 | ||
64 | 64 | ||
65 | /* Log Clients */ | 65 | /* Log Clients */ |
66 | #define XFS_TRANSACTION 0x69 | 66 | #define XFS_TRANSACTION 0x69 |
67 | #define XFS_VOLUME 0x2 | 67 | #define XFS_VOLUME 0x2 |
68 | #define XFS_LOG 0xaa | 68 | #define XFS_LOG 0xaa |
69 | 69 | ||
70 | 70 | ||
71 | /* Region types for iovec's i_type */ | 71 | /* Region types for iovec's i_type */ |
72 | #define XLOG_REG_TYPE_BFORMAT 1 | 72 | #define XLOG_REG_TYPE_BFORMAT 1 |
73 | #define XLOG_REG_TYPE_BCHUNK 2 | 73 | #define XLOG_REG_TYPE_BCHUNK 2 |
74 | #define XLOG_REG_TYPE_EFI_FORMAT 3 | 74 | #define XLOG_REG_TYPE_EFI_FORMAT 3 |
75 | #define XLOG_REG_TYPE_EFD_FORMAT 4 | 75 | #define XLOG_REG_TYPE_EFD_FORMAT 4 |
76 | #define XLOG_REG_TYPE_IFORMAT 5 | 76 | #define XLOG_REG_TYPE_IFORMAT 5 |
77 | #define XLOG_REG_TYPE_ICORE 6 | 77 | #define XLOG_REG_TYPE_ICORE 6 |
78 | #define XLOG_REG_TYPE_IEXT 7 | 78 | #define XLOG_REG_TYPE_IEXT 7 |
79 | #define XLOG_REG_TYPE_IBROOT 8 | 79 | #define XLOG_REG_TYPE_IBROOT 8 |
80 | #define XLOG_REG_TYPE_ILOCAL 9 | 80 | #define XLOG_REG_TYPE_ILOCAL 9 |
81 | #define XLOG_REG_TYPE_IATTR_EXT 10 | 81 | #define XLOG_REG_TYPE_IATTR_EXT 10 |
82 | #define XLOG_REG_TYPE_IATTR_BROOT 11 | 82 | #define XLOG_REG_TYPE_IATTR_BROOT 11 |
83 | #define XLOG_REG_TYPE_IATTR_LOCAL 12 | 83 | #define XLOG_REG_TYPE_IATTR_LOCAL 12 |
84 | #define XLOG_REG_TYPE_QFORMAT 13 | 84 | #define XLOG_REG_TYPE_QFORMAT 13 |
85 | #define XLOG_REG_TYPE_DQUOT 14 | 85 | #define XLOG_REG_TYPE_DQUOT 14 |
86 | #define XLOG_REG_TYPE_QUOTAOFF 15 | 86 | #define XLOG_REG_TYPE_QUOTAOFF 15 |
87 | #define XLOG_REG_TYPE_LRHEADER 16 | 87 | #define XLOG_REG_TYPE_LRHEADER 16 |
88 | #define XLOG_REG_TYPE_UNMOUNT 17 | 88 | #define XLOG_REG_TYPE_UNMOUNT 17 |
89 | #define XLOG_REG_TYPE_COMMIT 18 | 89 | #define XLOG_REG_TYPE_COMMIT 18 |
90 | #define XLOG_REG_TYPE_TRANSHDR 19 | 90 | #define XLOG_REG_TYPE_TRANSHDR 19 |
91 | #define XLOG_REG_TYPE_MAX 19 | 91 | #define XLOG_REG_TYPE_ICREATE 20 |
92 | #define XLOG_REG_TYPE_MAX 20 | ||
92 | 93 | ||
93 | typedef struct xfs_log_iovec { | 94 | typedef struct xfs_log_iovec { |
94 | void *i_addr; /* beginning address of region */ | 95 | void *i_addr; /* beginning address of region */ |
95 | int i_len; /* length in bytes of region */ | 96 | int i_len; /* length in bytes of region */ |
96 | uint i_type; /* type of region */ | 97 | uint i_type; /* type of region */ |
97 | } xfs_log_iovec_t; | 98 | } xfs_log_iovec_t; |
98 | 99 | ||
99 | struct xfs_log_vec { | 100 | struct xfs_log_vec { |
100 | struct xfs_log_vec *lv_next; /* next lv in build list */ | 101 | struct xfs_log_vec *lv_next; /* next lv in build list */ |
101 | int lv_niovecs; /* number of iovecs in lv */ | 102 | int lv_niovecs; /* number of iovecs in lv */ |
102 | struct xfs_log_iovec *lv_iovecp; /* iovec array */ | 103 | struct xfs_log_iovec *lv_iovecp; /* iovec array */ |
103 | struct xfs_log_item *lv_item; /* owner */ | 104 | struct xfs_log_item *lv_item; /* owner */ |
104 | char *lv_buf; /* formatted buffer */ | 105 | char *lv_buf; /* formatted buffer */ |
105 | int lv_buf_len; /* size of formatted buffer */ | 106 | int lv_buf_len; /* size of formatted buffer */ |
106 | }; | 107 | }; |
107 | 108 | ||
108 | #define XFS_LOG_VEC_ORDERED (-1) | 109 | #define XFS_LOG_VEC_ORDERED (-1) |
109 | 110 | ||
110 | /* | 111 | /* |
111 | * Structure used to pass callback function and the function's argument | 112 | * Structure used to pass callback function and the function's argument |
112 | * to the log manager. | 113 | * to the log manager. |
113 | */ | 114 | */ |
114 | typedef struct xfs_log_callback { | 115 | typedef struct xfs_log_callback { |
115 | struct xfs_log_callback *cb_next; | 116 | struct xfs_log_callback *cb_next; |
116 | void (*cb_func)(void *, int); | 117 | void (*cb_func)(void *, int); |
117 | void *cb_arg; | 118 | void *cb_arg; |
118 | } xfs_log_callback_t; | 119 | } xfs_log_callback_t; |
119 | 120 | ||
120 | 121 | ||
121 | #ifdef __KERNEL__ | 122 | #ifdef __KERNEL__ |
122 | /* Log manager interfaces */ | 123 | /* Log manager interfaces */ |
123 | struct xfs_mount; | 124 | struct xfs_mount; |
124 | struct xlog_in_core; | 125 | struct xlog_in_core; |
125 | struct xlog_ticket; | 126 | struct xlog_ticket; |
126 | struct xfs_log_item; | 127 | struct xfs_log_item; |
127 | struct xfs_item_ops; | 128 | struct xfs_item_ops; |
128 | struct xfs_trans; | 129 | struct xfs_trans; |
129 | 130 | ||
130 | void xfs_log_item_init(struct xfs_mount *mp, | 131 | void xfs_log_item_init(struct xfs_mount *mp, |
131 | struct xfs_log_item *item, | 132 | struct xfs_log_item *item, |
132 | int type, | 133 | int type, |
133 | const struct xfs_item_ops *ops); | 134 | const struct xfs_item_ops *ops); |
134 | 135 | ||
135 | xfs_lsn_t xfs_log_done(struct xfs_mount *mp, | 136 | xfs_lsn_t xfs_log_done(struct xfs_mount *mp, |
136 | struct xlog_ticket *ticket, | 137 | struct xlog_ticket *ticket, |
137 | struct xlog_in_core **iclog, | 138 | struct xlog_in_core **iclog, |
138 | uint flags); | 139 | uint flags); |
139 | int _xfs_log_force(struct xfs_mount *mp, | 140 | int _xfs_log_force(struct xfs_mount *mp, |
140 | uint flags, | 141 | uint flags, |
141 | int *log_forced); | 142 | int *log_forced); |
142 | void xfs_log_force(struct xfs_mount *mp, | 143 | void xfs_log_force(struct xfs_mount *mp, |
143 | uint flags); | 144 | uint flags); |
144 | int _xfs_log_force_lsn(struct xfs_mount *mp, | 145 | int _xfs_log_force_lsn(struct xfs_mount *mp, |
145 | xfs_lsn_t lsn, | 146 | xfs_lsn_t lsn, |
146 | uint flags, | 147 | uint flags, |
147 | int *log_forced); | 148 | int *log_forced); |
148 | void xfs_log_force_lsn(struct xfs_mount *mp, | 149 | void xfs_log_force_lsn(struct xfs_mount *mp, |
149 | xfs_lsn_t lsn, | 150 | xfs_lsn_t lsn, |
150 | uint flags); | 151 | uint flags); |
151 | int xfs_log_mount(struct xfs_mount *mp, | 152 | int xfs_log_mount(struct xfs_mount *mp, |
152 | struct xfs_buftarg *log_target, | 153 | struct xfs_buftarg *log_target, |
153 | xfs_daddr_t start_block, | 154 | xfs_daddr_t start_block, |
154 | int num_bblocks); | 155 | int num_bblocks); |
155 | int xfs_log_mount_finish(struct xfs_mount *mp); | 156 | int xfs_log_mount_finish(struct xfs_mount *mp); |
156 | xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); | 157 | xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); |
157 | xfs_lsn_t xlog_assign_tail_lsn_locked(struct xfs_mount *mp); | 158 | xfs_lsn_t xlog_assign_tail_lsn_locked(struct xfs_mount *mp); |
158 | void xfs_log_space_wake(struct xfs_mount *mp); | 159 | void xfs_log_space_wake(struct xfs_mount *mp); |
159 | int xfs_log_notify(struct xfs_mount *mp, | 160 | int xfs_log_notify(struct xfs_mount *mp, |
160 | struct xlog_in_core *iclog, | 161 | struct xlog_in_core *iclog, |
161 | xfs_log_callback_t *callback_entry); | 162 | xfs_log_callback_t *callback_entry); |
162 | int xfs_log_release_iclog(struct xfs_mount *mp, | 163 | int xfs_log_release_iclog(struct xfs_mount *mp, |
163 | struct xlog_in_core *iclog); | 164 | struct xlog_in_core *iclog); |
164 | int xfs_log_reserve(struct xfs_mount *mp, | 165 | int xfs_log_reserve(struct xfs_mount *mp, |
165 | int length, | 166 | int length, |
166 | int count, | 167 | int count, |
167 | struct xlog_ticket **ticket, | 168 | struct xlog_ticket **ticket, |
168 | __uint8_t clientid, | 169 | __uint8_t clientid, |
169 | bool permanent, | 170 | bool permanent, |
170 | uint t_type); | 171 | uint t_type); |
171 | int xfs_log_regrant(struct xfs_mount *mp, struct xlog_ticket *tic); | 172 | int xfs_log_regrant(struct xfs_mount *mp, struct xlog_ticket *tic); |
172 | int xfs_log_unmount_write(struct xfs_mount *mp); | 173 | int xfs_log_unmount_write(struct xfs_mount *mp); |
173 | void xfs_log_unmount(struct xfs_mount *mp); | 174 | void xfs_log_unmount(struct xfs_mount *mp); |
174 | int xfs_log_force_umount(struct xfs_mount *mp, int logerror); | 175 | int xfs_log_force_umount(struct xfs_mount *mp, int logerror); |
175 | int xfs_log_need_covered(struct xfs_mount *mp); | 176 | int xfs_log_need_covered(struct xfs_mount *mp); |
176 | 177 | ||
177 | void xlog_iodone(struct xfs_buf *); | 178 | void xlog_iodone(struct xfs_buf *); |
178 | 179 | ||
179 | struct xlog_ticket *xfs_log_ticket_get(struct xlog_ticket *ticket); | 180 | struct xlog_ticket *xfs_log_ticket_get(struct xlog_ticket *ticket); |
180 | void xfs_log_ticket_put(struct xlog_ticket *ticket); | 181 | void xfs_log_ticket_put(struct xlog_ticket *ticket); |
181 | 182 | ||
182 | int xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp, | 183 | int xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp, |
183 | xfs_lsn_t *commit_lsn, int flags); | 184 | xfs_lsn_t *commit_lsn, int flags); |
184 | bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip); | 185 | bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip); |
185 | 186 | ||
186 | void xfs_log_work_queue(struct xfs_mount *mp); | 187 | void xfs_log_work_queue(struct xfs_mount *mp); |
187 | void xfs_log_worker(struct work_struct *work); | 188 | void xfs_log_worker(struct work_struct *work); |
188 | void xfs_log_quiesce(struct xfs_mount *mp); | 189 | void xfs_log_quiesce(struct xfs_mount *mp); |
189 | 190 | ||
190 | #endif | 191 | #endif |
191 | #endif /* __XFS_LOG_H__ */ | 192 | #endif /* __XFS_LOG_H__ */ |
192 | 193 |
fs/xfs/xfs_super.c
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 | 18 | ||
19 | #include "xfs.h" | 19 | #include "xfs.h" |
20 | #include "xfs_log.h" | 20 | #include "xfs_log.h" |
21 | #include "xfs_inum.h" | 21 | #include "xfs_inum.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_dir2.h" | 25 | #include "xfs_dir2.h" |
26 | #include "xfs_alloc.h" | 26 | #include "xfs_alloc.h" |
27 | #include "xfs_quota.h" | 27 | #include "xfs_quota.h" |
28 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
29 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
30 | #include "xfs_alloc_btree.h" | 30 | #include "xfs_alloc_btree.h" |
31 | #include "xfs_ialloc_btree.h" | 31 | #include "xfs_ialloc_btree.h" |
32 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
33 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
34 | #include "xfs_btree.h" | 34 | #include "xfs_btree.h" |
35 | #include "xfs_ialloc.h" | 35 | #include "xfs_ialloc.h" |
36 | #include "xfs_bmap.h" | 36 | #include "xfs_bmap.h" |
37 | #include "xfs_rtalloc.h" | 37 | #include "xfs_rtalloc.h" |
38 | #include "xfs_error.h" | 38 | #include "xfs_error.h" |
39 | #include "xfs_itable.h" | 39 | #include "xfs_itable.h" |
40 | #include "xfs_fsops.h" | 40 | #include "xfs_fsops.h" |
41 | #include "xfs_attr.h" | 41 | #include "xfs_attr.h" |
42 | #include "xfs_buf_item.h" | 42 | #include "xfs_buf_item.h" |
43 | #include "xfs_utils.h" | 43 | #include "xfs_utils.h" |
44 | #include "xfs_vnodeops.h" | 44 | #include "xfs_vnodeops.h" |
45 | #include "xfs_log_priv.h" | 45 | #include "xfs_log_priv.h" |
46 | #include "xfs_trans_priv.h" | 46 | #include "xfs_trans_priv.h" |
47 | #include "xfs_filestream.h" | 47 | #include "xfs_filestream.h" |
48 | #include "xfs_da_btree.h" | 48 | #include "xfs_da_btree.h" |
49 | #include "xfs_extfree_item.h" | 49 | #include "xfs_extfree_item.h" |
50 | #include "xfs_mru_cache.h" | 50 | #include "xfs_mru_cache.h" |
51 | #include "xfs_inode_item.h" | 51 | #include "xfs_inode_item.h" |
52 | #include "xfs_icache.h" | 52 | #include "xfs_icache.h" |
53 | #include "xfs_trace.h" | 53 | #include "xfs_trace.h" |
54 | #include "xfs_icreate_item.h" | ||
54 | 55 | ||
55 | #include <linux/namei.h> | 56 | #include <linux/namei.h> |
56 | #include <linux/init.h> | 57 | #include <linux/init.h> |
57 | #include <linux/slab.h> | 58 | #include <linux/slab.h> |
58 | #include <linux/mount.h> | 59 | #include <linux/mount.h> |
59 | #include <linux/mempool.h> | 60 | #include <linux/mempool.h> |
60 | #include <linux/writeback.h> | 61 | #include <linux/writeback.h> |
61 | #include <linux/kthread.h> | 62 | #include <linux/kthread.h> |
62 | #include <linux/freezer.h> | 63 | #include <linux/freezer.h> |
63 | #include <linux/parser.h> | 64 | #include <linux/parser.h> |
64 | 65 | ||
65 | static const struct super_operations xfs_super_operations; | 66 | static const struct super_operations xfs_super_operations; |
66 | static kmem_zone_t *xfs_ioend_zone; | 67 | static kmem_zone_t *xfs_ioend_zone; |
67 | mempool_t *xfs_ioend_pool; | 68 | mempool_t *xfs_ioend_pool; |
68 | 69 | ||
69 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ | 70 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ |
70 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ | 71 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ |
71 | #define MNTOPT_LOGDEV "logdev" /* log device */ | 72 | #define MNTOPT_LOGDEV "logdev" /* log device */ |
72 | #define MNTOPT_RTDEV "rtdev" /* realtime I/O device */ | 73 | #define MNTOPT_RTDEV "rtdev" /* realtime I/O device */ |
73 | #define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */ | 74 | #define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */ |
74 | #define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */ | 75 | #define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */ |
75 | #define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */ | 76 | #define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */ |
76 | #define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */ | 77 | #define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */ |
77 | #define MNTOPT_SUNIT "sunit" /* data volume stripe unit */ | 78 | #define MNTOPT_SUNIT "sunit" /* data volume stripe unit */ |
78 | #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ | 79 | #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ |
79 | #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ | 80 | #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ |
80 | #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ | 81 | #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ |
81 | #define MNTOPT_GRPID "grpid" /* group-ID from parent directory */ | 82 | #define MNTOPT_GRPID "grpid" /* group-ID from parent directory */ |
82 | #define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */ | 83 | #define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */ |
83 | #define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ | 84 | #define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ |
84 | #define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ | 85 | #define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ |
85 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ | 86 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ |
86 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ | 87 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ |
87 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and | 88 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and |
88 | * unwritten extent conversion */ | 89 | * unwritten extent conversion */ |
89 | #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ | 90 | #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ |
90 | #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ | 91 | #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ |
91 | #define MNTOPT_32BITINODE "inode32" /* inode allocation limited to | 92 | #define MNTOPT_32BITINODE "inode32" /* inode allocation limited to |
92 | * XFS_MAXINUMBER_32 */ | 93 | * XFS_MAXINUMBER_32 */ |
93 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ | 94 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ |
94 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ | 95 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ |
95 | #define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */ | 96 | #define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */ |
96 | #define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes | 97 | #define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes |
97 | * in stat(). */ | 98 | * in stat(). */ |
98 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ | 99 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ |
99 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ | 100 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ |
100 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ | 101 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ |
101 | #define MNTOPT_QUOTA "quota" /* disk quotas (user) */ | 102 | #define MNTOPT_QUOTA "quota" /* disk quotas (user) */ |
102 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ | 103 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ |
103 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ | 104 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ |
104 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ | 105 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ |
105 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ | 106 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ |
106 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ | 107 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ |
107 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ | 108 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ |
108 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ | 109 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ |
109 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ | 110 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ |
110 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | 111 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ |
111 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | 112 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ |
112 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | 113 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ |
113 | #define MNTOPT_DELAYLOG "delaylog" /* Delayed logging enabled */ | 114 | #define MNTOPT_DELAYLOG "delaylog" /* Delayed logging enabled */ |
114 | #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed logging disabled */ | 115 | #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed logging disabled */ |
115 | #define MNTOPT_DISCARD "discard" /* Discard unused blocks */ | 116 | #define MNTOPT_DISCARD "discard" /* Discard unused blocks */ |
116 | #define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */ | 117 | #define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */ |
117 | 118 | ||
118 | /* | 119 | /* |
119 | * Table driven mount option parser. | 120 | * Table driven mount option parser. |
120 | * | 121 | * |
121 | * Currently only used for remount, but it will be used for mount | 122 | * Currently only used for remount, but it will be used for mount |
122 | * in the future, too. | 123 | * in the future, too. |
123 | */ | 124 | */ |
124 | enum { | 125 | enum { |
125 | Opt_barrier, | 126 | Opt_barrier, |
126 | Opt_nobarrier, | 127 | Opt_nobarrier, |
127 | Opt_inode64, | 128 | Opt_inode64, |
128 | Opt_inode32, | 129 | Opt_inode32, |
129 | Opt_err | 130 | Opt_err |
130 | }; | 131 | }; |
131 | 132 | ||
132 | static const match_table_t tokens = { | 133 | static const match_table_t tokens = { |
133 | {Opt_barrier, "barrier"}, | 134 | {Opt_barrier, "barrier"}, |
134 | {Opt_nobarrier, "nobarrier"}, | 135 | {Opt_nobarrier, "nobarrier"}, |
135 | {Opt_inode64, "inode64"}, | 136 | {Opt_inode64, "inode64"}, |
136 | {Opt_inode32, "inode32"}, | 137 | {Opt_inode32, "inode32"}, |
137 | {Opt_err, NULL} | 138 | {Opt_err, NULL} |
138 | }; | 139 | }; |
139 | 140 | ||
140 | 141 | ||
141 | STATIC unsigned long | 142 | STATIC unsigned long |
142 | suffix_kstrtoint(char *s, unsigned int base, int *res) | 143 | suffix_kstrtoint(char *s, unsigned int base, int *res) |
143 | { | 144 | { |
144 | int last, shift_left_factor = 0, _res; | 145 | int last, shift_left_factor = 0, _res; |
145 | char *value = s; | 146 | char *value = s; |
146 | 147 | ||
147 | last = strlen(value) - 1; | 148 | last = strlen(value) - 1; |
148 | if (value[last] == 'K' || value[last] == 'k') { | 149 | if (value[last] == 'K' || value[last] == 'k') { |
149 | shift_left_factor = 10; | 150 | shift_left_factor = 10; |
150 | value[last] = '\0'; | 151 | value[last] = '\0'; |
151 | } | 152 | } |
152 | if (value[last] == 'M' || value[last] == 'm') { | 153 | if (value[last] == 'M' || value[last] == 'm') { |
153 | shift_left_factor = 20; | 154 | shift_left_factor = 20; |
154 | value[last] = '\0'; | 155 | value[last] = '\0'; |
155 | } | 156 | } |
156 | if (value[last] == 'G' || value[last] == 'g') { | 157 | if (value[last] == 'G' || value[last] == 'g') { |
157 | shift_left_factor = 30; | 158 | shift_left_factor = 30; |
158 | value[last] = '\0'; | 159 | value[last] = '\0'; |
159 | } | 160 | } |
160 | 161 | ||
161 | if (kstrtoint(s, base, &_res)) | 162 | if (kstrtoint(s, base, &_res)) |
162 | return -EINVAL; | 163 | return -EINVAL; |
163 | *res = _res << shift_left_factor; | 164 | *res = _res << shift_left_factor; |
164 | return 0; | 165 | return 0; |
165 | } | 166 | } |
166 | 167 | ||
167 | /* | 168 | /* |
168 | * This function fills in xfs_mount_t fields based on mount args. | 169 | * This function fills in xfs_mount_t fields based on mount args. |
169 | * Note: the superblock has _not_ yet been read in. | 170 | * Note: the superblock has _not_ yet been read in. |
170 | * | 171 | * |
171 | * Note that this function leaks the various device name allocations on | 172 | * Note that this function leaks the various device name allocations on |
172 | * failure. The caller takes care of them. | 173 | * failure. The caller takes care of them. |
173 | */ | 174 | */ |
174 | STATIC int | 175 | STATIC int |
175 | xfs_parseargs( | 176 | xfs_parseargs( |
176 | struct xfs_mount *mp, | 177 | struct xfs_mount *mp, |
177 | char *options) | 178 | char *options) |
178 | { | 179 | { |
179 | struct super_block *sb = mp->m_super; | 180 | struct super_block *sb = mp->m_super; |
180 | char *this_char, *value; | 181 | char *this_char, *value; |
181 | int dsunit = 0; | 182 | int dsunit = 0; |
182 | int dswidth = 0; | 183 | int dswidth = 0; |
183 | int iosize = 0; | 184 | int iosize = 0; |
184 | __uint8_t iosizelog = 0; | 185 | __uint8_t iosizelog = 0; |
185 | 186 | ||
186 | /* | 187 | /* |
187 | * set up the mount name first so all the errors will refer to the | 188 | * set up the mount name first so all the errors will refer to the |
188 | * correct device. | 189 | * correct device. |
189 | */ | 190 | */ |
190 | mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL); | 191 | mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL); |
191 | if (!mp->m_fsname) | 192 | if (!mp->m_fsname) |
192 | return ENOMEM; | 193 | return ENOMEM; |
193 | mp->m_fsname_len = strlen(mp->m_fsname) + 1; | 194 | mp->m_fsname_len = strlen(mp->m_fsname) + 1; |
194 | 195 | ||
195 | /* | 196 | /* |
196 | * Copy binary VFS mount flags we are interested in. | 197 | * Copy binary VFS mount flags we are interested in. |
197 | */ | 198 | */ |
198 | if (sb->s_flags & MS_RDONLY) | 199 | if (sb->s_flags & MS_RDONLY) |
199 | mp->m_flags |= XFS_MOUNT_RDONLY; | 200 | mp->m_flags |= XFS_MOUNT_RDONLY; |
200 | if (sb->s_flags & MS_DIRSYNC) | 201 | if (sb->s_flags & MS_DIRSYNC) |
201 | mp->m_flags |= XFS_MOUNT_DIRSYNC; | 202 | mp->m_flags |= XFS_MOUNT_DIRSYNC; |
202 | if (sb->s_flags & MS_SYNCHRONOUS) | 203 | if (sb->s_flags & MS_SYNCHRONOUS) |
203 | mp->m_flags |= XFS_MOUNT_WSYNC; | 204 | mp->m_flags |= XFS_MOUNT_WSYNC; |
204 | 205 | ||
205 | /* | 206 | /* |
206 | * Set some default flags that could be cleared by the mount option | 207 | * Set some default flags that could be cleared by the mount option |
207 | * parsing. | 208 | * parsing. |
208 | */ | 209 | */ |
209 | mp->m_flags |= XFS_MOUNT_BARRIER; | 210 | mp->m_flags |= XFS_MOUNT_BARRIER; |
210 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | 211 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
211 | #if !XFS_BIG_INUMS | 212 | #if !XFS_BIG_INUMS |
212 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | 213 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
213 | #endif | 214 | #endif |
214 | 215 | ||
215 | /* | 216 | /* |
216 | * These can be overridden by the mount option parsing. | 217 | * These can be overridden by the mount option parsing. |
217 | */ | 218 | */ |
218 | mp->m_logbufs = -1; | 219 | mp->m_logbufs = -1; |
219 | mp->m_logbsize = -1; | 220 | mp->m_logbsize = -1; |
220 | 221 | ||
221 | if (!options) | 222 | if (!options) |
222 | goto done; | 223 | goto done; |
223 | 224 | ||
224 | while ((this_char = strsep(&options, ",")) != NULL) { | 225 | while ((this_char = strsep(&options, ",")) != NULL) { |
225 | if (!*this_char) | 226 | if (!*this_char) |
226 | continue; | 227 | continue; |
227 | if ((value = strchr(this_char, '=')) != NULL) | 228 | if ((value = strchr(this_char, '=')) != NULL) |
228 | *value++ = 0; | 229 | *value++ = 0; |
229 | 230 | ||
230 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { | 231 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { |
231 | if (!value || !*value) { | 232 | if (!value || !*value) { |
232 | xfs_warn(mp, "%s option requires an argument", | 233 | xfs_warn(mp, "%s option requires an argument", |
233 | this_char); | 234 | this_char); |
234 | return EINVAL; | 235 | return EINVAL; |
235 | } | 236 | } |
236 | if (kstrtoint(value, 10, &mp->m_logbufs)) | 237 | if (kstrtoint(value, 10, &mp->m_logbufs)) |
237 | return EINVAL; | 238 | return EINVAL; |
238 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { | 239 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { |
239 | if (!value || !*value) { | 240 | if (!value || !*value) { |
240 | xfs_warn(mp, "%s option requires an argument", | 241 | xfs_warn(mp, "%s option requires an argument", |
241 | this_char); | 242 | this_char); |
242 | return EINVAL; | 243 | return EINVAL; |
243 | } | 244 | } |
244 | if (suffix_kstrtoint(value, 10, &mp->m_logbsize)) | 245 | if (suffix_kstrtoint(value, 10, &mp->m_logbsize)) |
245 | return EINVAL; | 246 | return EINVAL; |
246 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { | 247 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { |
247 | if (!value || !*value) { | 248 | if (!value || !*value) { |
248 | xfs_warn(mp, "%s option requires an argument", | 249 | xfs_warn(mp, "%s option requires an argument", |
249 | this_char); | 250 | this_char); |
250 | return EINVAL; | 251 | return EINVAL; |
251 | } | 252 | } |
252 | mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); | 253 | mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); |
253 | if (!mp->m_logname) | 254 | if (!mp->m_logname) |
254 | return ENOMEM; | 255 | return ENOMEM; |
255 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { | 256 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { |
256 | xfs_warn(mp, "%s option not allowed on this system", | 257 | xfs_warn(mp, "%s option not allowed on this system", |
257 | this_char); | 258 | this_char); |
258 | return EINVAL; | 259 | return EINVAL; |
259 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { | 260 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { |
260 | if (!value || !*value) { | 261 | if (!value || !*value) { |
261 | xfs_warn(mp, "%s option requires an argument", | 262 | xfs_warn(mp, "%s option requires an argument", |
262 | this_char); | 263 | this_char); |
263 | return EINVAL; | 264 | return EINVAL; |
264 | } | 265 | } |
265 | mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); | 266 | mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); |
266 | if (!mp->m_rtname) | 267 | if (!mp->m_rtname) |
267 | return ENOMEM; | 268 | return ENOMEM; |
268 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { | 269 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { |
269 | if (!value || !*value) { | 270 | if (!value || !*value) { |
270 | xfs_warn(mp, "%s option requires an argument", | 271 | xfs_warn(mp, "%s option requires an argument", |
271 | this_char); | 272 | this_char); |
272 | return EINVAL; | 273 | return EINVAL; |
273 | } | 274 | } |
274 | if (kstrtoint(value, 10, &iosize)) | 275 | if (kstrtoint(value, 10, &iosize)) |
275 | return EINVAL; | 276 | return EINVAL; |
276 | iosizelog = ffs(iosize) - 1; | 277 | iosizelog = ffs(iosize) - 1; |
277 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { | 278 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { |
278 | if (!value || !*value) { | 279 | if (!value || !*value) { |
279 | xfs_warn(mp, "%s option requires an argument", | 280 | xfs_warn(mp, "%s option requires an argument", |
280 | this_char); | 281 | this_char); |
281 | return EINVAL; | 282 | return EINVAL; |
282 | } | 283 | } |
283 | if (suffix_kstrtoint(value, 10, &iosize)) | 284 | if (suffix_kstrtoint(value, 10, &iosize)) |
284 | return EINVAL; | 285 | return EINVAL; |
285 | iosizelog = ffs(iosize) - 1; | 286 | iosizelog = ffs(iosize) - 1; |
286 | } else if (!strcmp(this_char, MNTOPT_GRPID) || | 287 | } else if (!strcmp(this_char, MNTOPT_GRPID) || |
287 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { | 288 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { |
288 | mp->m_flags |= XFS_MOUNT_GRPID; | 289 | mp->m_flags |= XFS_MOUNT_GRPID; |
289 | } else if (!strcmp(this_char, MNTOPT_NOGRPID) || | 290 | } else if (!strcmp(this_char, MNTOPT_NOGRPID) || |
290 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { | 291 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { |
291 | mp->m_flags &= ~XFS_MOUNT_GRPID; | 292 | mp->m_flags &= ~XFS_MOUNT_GRPID; |
292 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { | 293 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { |
293 | mp->m_flags |= XFS_MOUNT_WSYNC; | 294 | mp->m_flags |= XFS_MOUNT_WSYNC; |
294 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { | 295 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { |
295 | mp->m_flags |= XFS_MOUNT_NORECOVERY; | 296 | mp->m_flags |= XFS_MOUNT_NORECOVERY; |
296 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { | 297 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { |
297 | mp->m_flags |= XFS_MOUNT_NOALIGN; | 298 | mp->m_flags |= XFS_MOUNT_NOALIGN; |
298 | } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { | 299 | } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { |
299 | mp->m_flags |= XFS_MOUNT_SWALLOC; | 300 | mp->m_flags |= XFS_MOUNT_SWALLOC; |
300 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { | 301 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { |
301 | if (!value || !*value) { | 302 | if (!value || !*value) { |
302 | xfs_warn(mp, "%s option requires an argument", | 303 | xfs_warn(mp, "%s option requires an argument", |
303 | this_char); | 304 | this_char); |
304 | return EINVAL; | 305 | return EINVAL; |
305 | } | 306 | } |
306 | if (kstrtoint(value, 10, &dsunit)) | 307 | if (kstrtoint(value, 10, &dsunit)) |
307 | return EINVAL; | 308 | return EINVAL; |
308 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { | 309 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { |
309 | if (!value || !*value) { | 310 | if (!value || !*value) { |
310 | xfs_warn(mp, "%s option requires an argument", | 311 | xfs_warn(mp, "%s option requires an argument", |
311 | this_char); | 312 | this_char); |
312 | return EINVAL; | 313 | return EINVAL; |
313 | } | 314 | } |
314 | if (kstrtoint(value, 10, &dswidth)) | 315 | if (kstrtoint(value, 10, &dswidth)) |
315 | return EINVAL; | 316 | return EINVAL; |
316 | } else if (!strcmp(this_char, MNTOPT_32BITINODE)) { | 317 | } else if (!strcmp(this_char, MNTOPT_32BITINODE)) { |
317 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | 318 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
318 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { | 319 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { |
319 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; | 320 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
320 | #if !XFS_BIG_INUMS | 321 | #if !XFS_BIG_INUMS |
321 | xfs_warn(mp, "%s option not allowed on this system", | 322 | xfs_warn(mp, "%s option not allowed on this system", |
322 | this_char); | 323 | this_char); |
323 | return EINVAL; | 324 | return EINVAL; |
324 | #endif | 325 | #endif |
325 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { | 326 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { |
326 | mp->m_flags |= XFS_MOUNT_NOUUID; | 327 | mp->m_flags |= XFS_MOUNT_NOUUID; |
327 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { | 328 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { |
328 | mp->m_flags |= XFS_MOUNT_BARRIER; | 329 | mp->m_flags |= XFS_MOUNT_BARRIER; |
329 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { | 330 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { |
330 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 331 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
331 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { | 332 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { |
332 | mp->m_flags |= XFS_MOUNT_IKEEP; | 333 | mp->m_flags |= XFS_MOUNT_IKEEP; |
333 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { | 334 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { |
334 | mp->m_flags &= ~XFS_MOUNT_IKEEP; | 335 | mp->m_flags &= ~XFS_MOUNT_IKEEP; |
335 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { | 336 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { |
336 | mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; | 337 | mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; |
337 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { | 338 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { |
338 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | 339 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
339 | } else if (!strcmp(this_char, MNTOPT_ATTR2)) { | 340 | } else if (!strcmp(this_char, MNTOPT_ATTR2)) { |
340 | mp->m_flags |= XFS_MOUNT_ATTR2; | 341 | mp->m_flags |= XFS_MOUNT_ATTR2; |
341 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { | 342 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { |
342 | mp->m_flags &= ~XFS_MOUNT_ATTR2; | 343 | mp->m_flags &= ~XFS_MOUNT_ATTR2; |
343 | mp->m_flags |= XFS_MOUNT_NOATTR2; | 344 | mp->m_flags |= XFS_MOUNT_NOATTR2; |
344 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { | 345 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { |
345 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | 346 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; |
346 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { | 347 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { |
347 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; | 348 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; |
348 | mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; | 349 | mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; |
349 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; | 350 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; |
350 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || | 351 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || |
351 | !strcmp(this_char, MNTOPT_UQUOTA) || | 352 | !strcmp(this_char, MNTOPT_UQUOTA) || |
352 | !strcmp(this_char, MNTOPT_USRQUOTA)) { | 353 | !strcmp(this_char, MNTOPT_USRQUOTA)) { |
353 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | | 354 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | |
354 | XFS_UQUOTA_ENFD); | 355 | XFS_UQUOTA_ENFD); |
355 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || | 356 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || |
356 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { | 357 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { |
357 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); | 358 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); |
358 | mp->m_qflags &= ~XFS_UQUOTA_ENFD; | 359 | mp->m_qflags &= ~XFS_UQUOTA_ENFD; |
359 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | 360 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || |
360 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | 361 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { |
361 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | | 362 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | |
362 | XFS_OQUOTA_ENFD); | 363 | XFS_OQUOTA_ENFD); |
363 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | 364 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { |
364 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | 365 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); |
365 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; | 366 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; |
366 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | 367 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || |
367 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | 368 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { |
368 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | | 369 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | |
369 | XFS_OQUOTA_ENFD); | 370 | XFS_OQUOTA_ENFD); |
370 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { | 371 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { |
371 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | 372 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); |
372 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; | 373 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; |
373 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { | 374 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { |
374 | xfs_warn(mp, | 375 | xfs_warn(mp, |
375 | "delaylog is the default now, option is deprecated."); | 376 | "delaylog is the default now, option is deprecated."); |
376 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { | 377 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { |
377 | xfs_warn(mp, | 378 | xfs_warn(mp, |
378 | "nodelaylog support has been removed, option is deprecated."); | 379 | "nodelaylog support has been removed, option is deprecated."); |
379 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { | 380 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { |
380 | mp->m_flags |= XFS_MOUNT_DISCARD; | 381 | mp->m_flags |= XFS_MOUNT_DISCARD; |
381 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { | 382 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { |
382 | mp->m_flags &= ~XFS_MOUNT_DISCARD; | 383 | mp->m_flags &= ~XFS_MOUNT_DISCARD; |
383 | } else if (!strcmp(this_char, "ihashsize")) { | 384 | } else if (!strcmp(this_char, "ihashsize")) { |
384 | xfs_warn(mp, | 385 | xfs_warn(mp, |
385 | "ihashsize no longer used, option is deprecated."); | 386 | "ihashsize no longer used, option is deprecated."); |
386 | } else if (!strcmp(this_char, "osyncisdsync")) { | 387 | } else if (!strcmp(this_char, "osyncisdsync")) { |
387 | xfs_warn(mp, | 388 | xfs_warn(mp, |
388 | "osyncisdsync has no effect, option is deprecated."); | 389 | "osyncisdsync has no effect, option is deprecated."); |
389 | } else if (!strcmp(this_char, "osyncisosync")) { | 390 | } else if (!strcmp(this_char, "osyncisosync")) { |
390 | xfs_warn(mp, | 391 | xfs_warn(mp, |
391 | "osyncisosync has no effect, option is deprecated."); | 392 | "osyncisosync has no effect, option is deprecated."); |
392 | } else if (!strcmp(this_char, "irixsgid")) { | 393 | } else if (!strcmp(this_char, "irixsgid")) { |
393 | xfs_warn(mp, | 394 | xfs_warn(mp, |
394 | "irixsgid is now a sysctl(2) variable, option is deprecated."); | 395 | "irixsgid is now a sysctl(2) variable, option is deprecated."); |
395 | } else { | 396 | } else { |
396 | xfs_warn(mp, "unknown mount option [%s].", this_char); | 397 | xfs_warn(mp, "unknown mount option [%s].", this_char); |
397 | return EINVAL; | 398 | return EINVAL; |
398 | } | 399 | } |
399 | } | 400 | } |
400 | 401 | ||
401 | /* | 402 | /* |
402 | * no recovery flag requires a read-only mount | 403 | * no recovery flag requires a read-only mount |
403 | */ | 404 | */ |
404 | if ((mp->m_flags & XFS_MOUNT_NORECOVERY) && | 405 | if ((mp->m_flags & XFS_MOUNT_NORECOVERY) && |
405 | !(mp->m_flags & XFS_MOUNT_RDONLY)) { | 406 | !(mp->m_flags & XFS_MOUNT_RDONLY)) { |
406 | xfs_warn(mp, "no-recovery mounts must be read-only."); | 407 | xfs_warn(mp, "no-recovery mounts must be read-only."); |
407 | return EINVAL; | 408 | return EINVAL; |
408 | } | 409 | } |
409 | 410 | ||
410 | if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) { | 411 | if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) { |
411 | xfs_warn(mp, | 412 | xfs_warn(mp, |
412 | "sunit and swidth options incompatible with the noalign option"); | 413 | "sunit and swidth options incompatible with the noalign option"); |
413 | return EINVAL; | 414 | return EINVAL; |
414 | } | 415 | } |
415 | 416 | ||
416 | #ifndef CONFIG_XFS_QUOTA | 417 | #ifndef CONFIG_XFS_QUOTA |
417 | if (XFS_IS_QUOTA_RUNNING(mp)) { | 418 | if (XFS_IS_QUOTA_RUNNING(mp)) { |
418 | xfs_warn(mp, "quota support not available in this kernel."); | 419 | xfs_warn(mp, "quota support not available in this kernel."); |
419 | return EINVAL; | 420 | return EINVAL; |
420 | } | 421 | } |
421 | #endif | 422 | #endif |
422 | 423 | ||
423 | if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) && | 424 | if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) && |
424 | (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) { | 425 | (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) { |
425 | xfs_warn(mp, "cannot mount with both project and group quota"); | 426 | xfs_warn(mp, "cannot mount with both project and group quota"); |
426 | return EINVAL; | 427 | return EINVAL; |
427 | } | 428 | } |
428 | 429 | ||
429 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { | 430 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { |
430 | xfs_warn(mp, "sunit and swidth must be specified together"); | 431 | xfs_warn(mp, "sunit and swidth must be specified together"); |
431 | return EINVAL; | 432 | return EINVAL; |
432 | } | 433 | } |
433 | 434 | ||
434 | if (dsunit && (dswidth % dsunit != 0)) { | 435 | if (dsunit && (dswidth % dsunit != 0)) { |
435 | xfs_warn(mp, | 436 | xfs_warn(mp, |
436 | "stripe width (%d) must be a multiple of the stripe unit (%d)", | 437 | "stripe width (%d) must be a multiple of the stripe unit (%d)", |
437 | dswidth, dsunit); | 438 | dswidth, dsunit); |
438 | return EINVAL; | 439 | return EINVAL; |
439 | } | 440 | } |
440 | 441 | ||
441 | done: | 442 | done: |
442 | if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) { | 443 | if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) { |
443 | /* | 444 | /* |
444 | * At this point the superblock has not been read | 445 | * At this point the superblock has not been read |
445 | * in, therefore we do not know the block size. | 446 | * in, therefore we do not know the block size. |
446 | * Before the mount call ends we will convert | 447 | * Before the mount call ends we will convert |
447 | * these to FSBs. | 448 | * these to FSBs. |
448 | */ | 449 | */ |
449 | mp->m_dalign = dsunit; | 450 | mp->m_dalign = dsunit; |
450 | mp->m_swidth = dswidth; | 451 | mp->m_swidth = dswidth; |
451 | } | 452 | } |
452 | 453 | ||
453 | if (mp->m_logbufs != -1 && | 454 | if (mp->m_logbufs != -1 && |
454 | mp->m_logbufs != 0 && | 455 | mp->m_logbufs != 0 && |
455 | (mp->m_logbufs < XLOG_MIN_ICLOGS || | 456 | (mp->m_logbufs < XLOG_MIN_ICLOGS || |
456 | mp->m_logbufs > XLOG_MAX_ICLOGS)) { | 457 | mp->m_logbufs > XLOG_MAX_ICLOGS)) { |
457 | xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]", | 458 | xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]", |
458 | mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); | 459 | mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); |
459 | return XFS_ERROR(EINVAL); | 460 | return XFS_ERROR(EINVAL); |
460 | } | 461 | } |
461 | if (mp->m_logbsize != -1 && | 462 | if (mp->m_logbsize != -1 && |
462 | mp->m_logbsize != 0 && | 463 | mp->m_logbsize != 0 && |
463 | (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE || | 464 | (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE || |
464 | mp->m_logbsize > XLOG_MAX_RECORD_BSIZE || | 465 | mp->m_logbsize > XLOG_MAX_RECORD_BSIZE || |
465 | !is_power_of_2(mp->m_logbsize))) { | 466 | !is_power_of_2(mp->m_logbsize))) { |
466 | xfs_warn(mp, | 467 | xfs_warn(mp, |
467 | "invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", | 468 | "invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", |
468 | mp->m_logbsize); | 469 | mp->m_logbsize); |
469 | return XFS_ERROR(EINVAL); | 470 | return XFS_ERROR(EINVAL); |
470 | } | 471 | } |
471 | 472 | ||
472 | if (iosizelog) { | 473 | if (iosizelog) { |
473 | if (iosizelog > XFS_MAX_IO_LOG || | 474 | if (iosizelog > XFS_MAX_IO_LOG || |
474 | iosizelog < XFS_MIN_IO_LOG) { | 475 | iosizelog < XFS_MIN_IO_LOG) { |
475 | xfs_warn(mp, "invalid log iosize: %d [not %d-%d]", | 476 | xfs_warn(mp, "invalid log iosize: %d [not %d-%d]", |
476 | iosizelog, XFS_MIN_IO_LOG, | 477 | iosizelog, XFS_MIN_IO_LOG, |
477 | XFS_MAX_IO_LOG); | 478 | XFS_MAX_IO_LOG); |
478 | return XFS_ERROR(EINVAL); | 479 | return XFS_ERROR(EINVAL); |
479 | } | 480 | } |
480 | 481 | ||
481 | mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; | 482 | mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; |
482 | mp->m_readio_log = iosizelog; | 483 | mp->m_readio_log = iosizelog; |
483 | mp->m_writeio_log = iosizelog; | 484 | mp->m_writeio_log = iosizelog; |
484 | } | 485 | } |
485 | 486 | ||
486 | return 0; | 487 | return 0; |
487 | } | 488 | } |
488 | 489 | ||
489 | struct proc_xfs_info { | 490 | struct proc_xfs_info { |
490 | int flag; | 491 | int flag; |
491 | char *str; | 492 | char *str; |
492 | }; | 493 | }; |
493 | 494 | ||
494 | STATIC int | 495 | STATIC int |
495 | xfs_showargs( | 496 | xfs_showargs( |
496 | struct xfs_mount *mp, | 497 | struct xfs_mount *mp, |
497 | struct seq_file *m) | 498 | struct seq_file *m) |
498 | { | 499 | { |
499 | static struct proc_xfs_info xfs_info_set[] = { | 500 | static struct proc_xfs_info xfs_info_set[] = { |
500 | /* the few simple ones we can get from the mount struct */ | 501 | /* the few simple ones we can get from the mount struct */ |
501 | { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, | 502 | { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, |
502 | { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, | 503 | { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, |
503 | { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, | 504 | { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, |
504 | { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, | 505 | { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, |
505 | { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, | 506 | { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, |
506 | { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, | 507 | { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, |
507 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, | 508 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, |
508 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, | 509 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, |
509 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, | 510 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, |
510 | { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, | 511 | { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, |
511 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE }, | 512 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE }, |
512 | { 0, NULL } | 513 | { 0, NULL } |
513 | }; | 514 | }; |
514 | static struct proc_xfs_info xfs_info_unset[] = { | 515 | static struct proc_xfs_info xfs_info_unset[] = { |
515 | /* the few simple ones we can get from the mount struct */ | 516 | /* the few simple ones we can get from the mount struct */ |
516 | { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, | 517 | { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, |
517 | { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, | 518 | { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, |
518 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, | 519 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, |
519 | { 0, NULL } | 520 | { 0, NULL } |
520 | }; | 521 | }; |
521 | struct proc_xfs_info *xfs_infop; | 522 | struct proc_xfs_info *xfs_infop; |
522 | 523 | ||
523 | for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) { | 524 | for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) { |
524 | if (mp->m_flags & xfs_infop->flag) | 525 | if (mp->m_flags & xfs_infop->flag) |
525 | seq_puts(m, xfs_infop->str); | 526 | seq_puts(m, xfs_infop->str); |
526 | } | 527 | } |
527 | for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) { | 528 | for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) { |
528 | if (!(mp->m_flags & xfs_infop->flag)) | 529 | if (!(mp->m_flags & xfs_infop->flag)) |
529 | seq_puts(m, xfs_infop->str); | 530 | seq_puts(m, xfs_infop->str); |
530 | } | 531 | } |
531 | 532 | ||
532 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) | 533 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) |
533 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", | 534 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", |
534 | (int)(1 << mp->m_writeio_log) >> 10); | 535 | (int)(1 << mp->m_writeio_log) >> 10); |
535 | 536 | ||
536 | if (mp->m_logbufs > 0) | 537 | if (mp->m_logbufs > 0) |
537 | seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); | 538 | seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); |
538 | if (mp->m_logbsize > 0) | 539 | if (mp->m_logbsize > 0) |
539 | seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); | 540 | seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); |
540 | 541 | ||
541 | if (mp->m_logname) | 542 | if (mp->m_logname) |
542 | seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname); | 543 | seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname); |
543 | if (mp->m_rtname) | 544 | if (mp->m_rtname) |
544 | seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname); | 545 | seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname); |
545 | 546 | ||
546 | if (mp->m_dalign > 0) | 547 | if (mp->m_dalign > 0) |
547 | seq_printf(m, "," MNTOPT_SUNIT "=%d", | 548 | seq_printf(m, "," MNTOPT_SUNIT "=%d", |
548 | (int)XFS_FSB_TO_BB(mp, mp->m_dalign)); | 549 | (int)XFS_FSB_TO_BB(mp, mp->m_dalign)); |
549 | if (mp->m_swidth > 0) | 550 | if (mp->m_swidth > 0) |
550 | seq_printf(m, "," MNTOPT_SWIDTH "=%d", | 551 | seq_printf(m, "," MNTOPT_SWIDTH "=%d", |
551 | (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); | 552 | (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); |
552 | 553 | ||
553 | if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) | 554 | if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) |
554 | seq_puts(m, "," MNTOPT_USRQUOTA); | 555 | seq_puts(m, "," MNTOPT_USRQUOTA); |
555 | else if (mp->m_qflags & XFS_UQUOTA_ACCT) | 556 | else if (mp->m_qflags & XFS_UQUOTA_ACCT) |
556 | seq_puts(m, "," MNTOPT_UQUOTANOENF); | 557 | seq_puts(m, "," MNTOPT_UQUOTANOENF); |
557 | 558 | ||
558 | /* Either project or group quotas can be active, not both */ | 559 | /* Either project or group quotas can be active, not both */ |
559 | 560 | ||
560 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { | 561 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { |
561 | if (mp->m_qflags & XFS_OQUOTA_ENFD) | 562 | if (mp->m_qflags & XFS_OQUOTA_ENFD) |
562 | seq_puts(m, "," MNTOPT_PRJQUOTA); | 563 | seq_puts(m, "," MNTOPT_PRJQUOTA); |
563 | else | 564 | else |
564 | seq_puts(m, "," MNTOPT_PQUOTANOENF); | 565 | seq_puts(m, "," MNTOPT_PQUOTANOENF); |
565 | } else if (mp->m_qflags & XFS_GQUOTA_ACCT) { | 566 | } else if (mp->m_qflags & XFS_GQUOTA_ACCT) { |
566 | if (mp->m_qflags & XFS_OQUOTA_ENFD) | 567 | if (mp->m_qflags & XFS_OQUOTA_ENFD) |
567 | seq_puts(m, "," MNTOPT_GRPQUOTA); | 568 | seq_puts(m, "," MNTOPT_GRPQUOTA); |
568 | else | 569 | else |
569 | seq_puts(m, "," MNTOPT_GQUOTANOENF); | 570 | seq_puts(m, "," MNTOPT_GQUOTANOENF); |
570 | } | 571 | } |
571 | 572 | ||
572 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) | 573 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) |
573 | seq_puts(m, "," MNTOPT_NOQUOTA); | 574 | seq_puts(m, "," MNTOPT_NOQUOTA); |
574 | 575 | ||
575 | return 0; | 576 | return 0; |
576 | } | 577 | } |
577 | __uint64_t | 578 | __uint64_t |
578 | xfs_max_file_offset( | 579 | xfs_max_file_offset( |
579 | unsigned int blockshift) | 580 | unsigned int blockshift) |
580 | { | 581 | { |
581 | unsigned int pagefactor = 1; | 582 | unsigned int pagefactor = 1; |
582 | unsigned int bitshift = BITS_PER_LONG - 1; | 583 | unsigned int bitshift = BITS_PER_LONG - 1; |
583 | 584 | ||
584 | /* Figure out maximum filesize, on Linux this can depend on | 585 | /* Figure out maximum filesize, on Linux this can depend on |
585 | * the filesystem blocksize (on 32 bit platforms). | 586 | * the filesystem blocksize (on 32 bit platforms). |
586 | * __block_write_begin does this in an [unsigned] long... | 587 | * __block_write_begin does this in an [unsigned] long... |
587 | * page->index << (PAGE_CACHE_SHIFT - bbits) | 588 | * page->index << (PAGE_CACHE_SHIFT - bbits) |
588 | * So, for page sized blocks (4K on 32 bit platforms), | 589 | * So, for page sized blocks (4K on 32 bit platforms), |
589 | * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is | 590 | * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is |
590 | * (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) | 591 | * (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) |
591 | * but for smaller blocksizes it is less (bbits = log2 bsize). | 592 | * but for smaller blocksizes it is less (bbits = log2 bsize). |
592 | * Note1: get_block_t takes a long (implicit cast from above) | 593 | * Note1: get_block_t takes a long (implicit cast from above) |
593 | * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch | 594 | * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch |
594 | * can optionally convert the [unsigned] long from above into | 595 | * can optionally convert the [unsigned] long from above into |
595 | * an [unsigned] long long. | 596 | * an [unsigned] long long. |
596 | */ | 597 | */ |
597 | 598 | ||
598 | #if BITS_PER_LONG == 32 | 599 | #if BITS_PER_LONG == 32 |
599 | # if defined(CONFIG_LBDAF) | 600 | # if defined(CONFIG_LBDAF) |
600 | ASSERT(sizeof(sector_t) == 8); | 601 | ASSERT(sizeof(sector_t) == 8); |
601 | pagefactor = PAGE_CACHE_SIZE; | 602 | pagefactor = PAGE_CACHE_SIZE; |
602 | bitshift = BITS_PER_LONG; | 603 | bitshift = BITS_PER_LONG; |
603 | # else | 604 | # else |
604 | pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift); | 605 | pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift); |
605 | # endif | 606 | # endif |
606 | #endif | 607 | #endif |
607 | 608 | ||
608 | return (((__uint64_t)pagefactor) << bitshift) - 1; | 609 | return (((__uint64_t)pagefactor) << bitshift) - 1; |
609 | } | 610 | } |
610 | 611 | ||
611 | xfs_agnumber_t | 612 | xfs_agnumber_t |
612 | xfs_set_inode32(struct xfs_mount *mp) | 613 | xfs_set_inode32(struct xfs_mount *mp) |
613 | { | 614 | { |
614 | xfs_agnumber_t index = 0; | 615 | xfs_agnumber_t index = 0; |
615 | xfs_agnumber_t maxagi = 0; | 616 | xfs_agnumber_t maxagi = 0; |
616 | xfs_sb_t *sbp = &mp->m_sb; | 617 | xfs_sb_t *sbp = &mp->m_sb; |
617 | xfs_agnumber_t max_metadata; | 618 | xfs_agnumber_t max_metadata; |
618 | xfs_agino_t agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0); | 619 | xfs_agino_t agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0); |
619 | xfs_ino_t ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino); | 620 | xfs_ino_t ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino); |
620 | xfs_perag_t *pag; | 621 | xfs_perag_t *pag; |
621 | 622 | ||
622 | /* Calculate how much should be reserved for inodes to meet | 623 | /* Calculate how much should be reserved for inodes to meet |
623 | * the max inode percentage. | 624 | * the max inode percentage. |
624 | */ | 625 | */ |
625 | if (mp->m_maxicount) { | 626 | if (mp->m_maxicount) { |
626 | __uint64_t icount; | 627 | __uint64_t icount; |
627 | 628 | ||
628 | icount = sbp->sb_dblocks * sbp->sb_imax_pct; | 629 | icount = sbp->sb_dblocks * sbp->sb_imax_pct; |
629 | do_div(icount, 100); | 630 | do_div(icount, 100); |
630 | icount += sbp->sb_agblocks - 1; | 631 | icount += sbp->sb_agblocks - 1; |
631 | do_div(icount, sbp->sb_agblocks); | 632 | do_div(icount, sbp->sb_agblocks); |
632 | max_metadata = icount; | 633 | max_metadata = icount; |
633 | } else { | 634 | } else { |
634 | max_metadata = sbp->sb_agcount; | 635 | max_metadata = sbp->sb_agcount; |
635 | } | 636 | } |
636 | 637 | ||
637 | for (index = 0; index < sbp->sb_agcount; index++) { | 638 | for (index = 0; index < sbp->sb_agcount; index++) { |
638 | ino = XFS_AGINO_TO_INO(mp, index, agino); | 639 | ino = XFS_AGINO_TO_INO(mp, index, agino); |
639 | 640 | ||
640 | if (ino > XFS_MAXINUMBER_32) { | 641 | if (ino > XFS_MAXINUMBER_32) { |
641 | pag = xfs_perag_get(mp, index); | 642 | pag = xfs_perag_get(mp, index); |
642 | pag->pagi_inodeok = 0; | 643 | pag->pagi_inodeok = 0; |
643 | pag->pagf_metadata = 0; | 644 | pag->pagf_metadata = 0; |
644 | xfs_perag_put(pag); | 645 | xfs_perag_put(pag); |
645 | continue; | 646 | continue; |
646 | } | 647 | } |
647 | 648 | ||
648 | pag = xfs_perag_get(mp, index); | 649 | pag = xfs_perag_get(mp, index); |
649 | pag->pagi_inodeok = 1; | 650 | pag->pagi_inodeok = 1; |
650 | maxagi++; | 651 | maxagi++; |
651 | if (index < max_metadata) | 652 | if (index < max_metadata) |
652 | pag->pagf_metadata = 1; | 653 | pag->pagf_metadata = 1; |
653 | xfs_perag_put(pag); | 654 | xfs_perag_put(pag); |
654 | } | 655 | } |
655 | mp->m_flags |= (XFS_MOUNT_32BITINODES | | 656 | mp->m_flags |= (XFS_MOUNT_32BITINODES | |
656 | XFS_MOUNT_SMALL_INUMS); | 657 | XFS_MOUNT_SMALL_INUMS); |
657 | 658 | ||
658 | return maxagi; | 659 | return maxagi; |
659 | } | 660 | } |
660 | 661 | ||
661 | xfs_agnumber_t | 662 | xfs_agnumber_t |
662 | xfs_set_inode64(struct xfs_mount *mp) | 663 | xfs_set_inode64(struct xfs_mount *mp) |
663 | { | 664 | { |
664 | xfs_agnumber_t index = 0; | 665 | xfs_agnumber_t index = 0; |
665 | 666 | ||
666 | for (index = 0; index < mp->m_sb.sb_agcount; index++) { | 667 | for (index = 0; index < mp->m_sb.sb_agcount; index++) { |
667 | struct xfs_perag *pag; | 668 | struct xfs_perag *pag; |
668 | 669 | ||
669 | pag = xfs_perag_get(mp, index); | 670 | pag = xfs_perag_get(mp, index); |
670 | pag->pagi_inodeok = 1; | 671 | pag->pagi_inodeok = 1; |
671 | pag->pagf_metadata = 0; | 672 | pag->pagf_metadata = 0; |
672 | xfs_perag_put(pag); | 673 | xfs_perag_put(pag); |
673 | } | 674 | } |
674 | 675 | ||
675 | /* There is no need for lock protection on m_flags, | 676 | /* There is no need for lock protection on m_flags, |
676 | * the rw_semaphore of the VFS superblock is locked | 677 | * the rw_semaphore of the VFS superblock is locked |
677 | * during mount/umount/remount operations, so this is | 678 | * during mount/umount/remount operations, so this is |
678 | * enough to avoid concurency on the m_flags field | 679 | * enough to avoid concurency on the m_flags field |
679 | */ | 680 | */ |
680 | mp->m_flags &= ~(XFS_MOUNT_32BITINODES | | 681 | mp->m_flags &= ~(XFS_MOUNT_32BITINODES | |
681 | XFS_MOUNT_SMALL_INUMS); | 682 | XFS_MOUNT_SMALL_INUMS); |
682 | return index; | 683 | return index; |
683 | } | 684 | } |
684 | 685 | ||
685 | STATIC int | 686 | STATIC int |
686 | xfs_blkdev_get( | 687 | xfs_blkdev_get( |
687 | xfs_mount_t *mp, | 688 | xfs_mount_t *mp, |
688 | const char *name, | 689 | const char *name, |
689 | struct block_device **bdevp) | 690 | struct block_device **bdevp) |
690 | { | 691 | { |
691 | int error = 0; | 692 | int error = 0; |
692 | 693 | ||
693 | *bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL, | 694 | *bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL, |
694 | mp); | 695 | mp); |
695 | if (IS_ERR(*bdevp)) { | 696 | if (IS_ERR(*bdevp)) { |
696 | error = PTR_ERR(*bdevp); | 697 | error = PTR_ERR(*bdevp); |
697 | xfs_warn(mp, "Invalid device [%s], error=%d\n", name, error); | 698 | xfs_warn(mp, "Invalid device [%s], error=%d\n", name, error); |
698 | } | 699 | } |
699 | 700 | ||
700 | return -error; | 701 | return -error; |
701 | } | 702 | } |
702 | 703 | ||
703 | STATIC void | 704 | STATIC void |
704 | xfs_blkdev_put( | 705 | xfs_blkdev_put( |
705 | struct block_device *bdev) | 706 | struct block_device *bdev) |
706 | { | 707 | { |
707 | if (bdev) | 708 | if (bdev) |
708 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); | 709 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
709 | } | 710 | } |
710 | 711 | ||
711 | void | 712 | void |
712 | xfs_blkdev_issue_flush( | 713 | xfs_blkdev_issue_flush( |
713 | xfs_buftarg_t *buftarg) | 714 | xfs_buftarg_t *buftarg) |
714 | { | 715 | { |
715 | blkdev_issue_flush(buftarg->bt_bdev, GFP_NOFS, NULL); | 716 | blkdev_issue_flush(buftarg->bt_bdev, GFP_NOFS, NULL); |
716 | } | 717 | } |
717 | 718 | ||
718 | STATIC void | 719 | STATIC void |
719 | xfs_close_devices( | 720 | xfs_close_devices( |
720 | struct xfs_mount *mp) | 721 | struct xfs_mount *mp) |
721 | { | 722 | { |
722 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { | 723 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { |
723 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; | 724 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; |
724 | xfs_free_buftarg(mp, mp->m_logdev_targp); | 725 | xfs_free_buftarg(mp, mp->m_logdev_targp); |
725 | xfs_blkdev_put(logdev); | 726 | xfs_blkdev_put(logdev); |
726 | } | 727 | } |
727 | if (mp->m_rtdev_targp) { | 728 | if (mp->m_rtdev_targp) { |
728 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; | 729 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; |
729 | xfs_free_buftarg(mp, mp->m_rtdev_targp); | 730 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
730 | xfs_blkdev_put(rtdev); | 731 | xfs_blkdev_put(rtdev); |
731 | } | 732 | } |
732 | xfs_free_buftarg(mp, mp->m_ddev_targp); | 733 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
733 | } | 734 | } |
734 | 735 | ||
735 | /* | 736 | /* |
736 | * The file system configurations are: | 737 | * The file system configurations are: |
737 | * (1) device (partition) with data and internal log | 738 | * (1) device (partition) with data and internal log |
738 | * (2) logical volume with data and log subvolumes. | 739 | * (2) logical volume with data and log subvolumes. |
739 | * (3) logical volume with data, log, and realtime subvolumes. | 740 | * (3) logical volume with data, log, and realtime subvolumes. |
740 | * | 741 | * |
741 | * We only have to handle opening the log and realtime volumes here if | 742 | * We only have to handle opening the log and realtime volumes here if |
742 | * they are present. The data subvolume has already been opened by | 743 | * they are present. The data subvolume has already been opened by |
743 | * get_sb_bdev() and is stored in sb->s_bdev. | 744 | * get_sb_bdev() and is stored in sb->s_bdev. |
744 | */ | 745 | */ |
745 | STATIC int | 746 | STATIC int |
746 | xfs_open_devices( | 747 | xfs_open_devices( |
747 | struct xfs_mount *mp) | 748 | struct xfs_mount *mp) |
748 | { | 749 | { |
749 | struct block_device *ddev = mp->m_super->s_bdev; | 750 | struct block_device *ddev = mp->m_super->s_bdev; |
750 | struct block_device *logdev = NULL, *rtdev = NULL; | 751 | struct block_device *logdev = NULL, *rtdev = NULL; |
751 | int error; | 752 | int error; |
752 | 753 | ||
753 | /* | 754 | /* |
754 | * Open real time and log devices - order is important. | 755 | * Open real time and log devices - order is important. |
755 | */ | 756 | */ |
756 | if (mp->m_logname) { | 757 | if (mp->m_logname) { |
757 | error = xfs_blkdev_get(mp, mp->m_logname, &logdev); | 758 | error = xfs_blkdev_get(mp, mp->m_logname, &logdev); |
758 | if (error) | 759 | if (error) |
759 | goto out; | 760 | goto out; |
760 | } | 761 | } |
761 | 762 | ||
762 | if (mp->m_rtname) { | 763 | if (mp->m_rtname) { |
763 | error = xfs_blkdev_get(mp, mp->m_rtname, &rtdev); | 764 | error = xfs_blkdev_get(mp, mp->m_rtname, &rtdev); |
764 | if (error) | 765 | if (error) |
765 | goto out_close_logdev; | 766 | goto out_close_logdev; |
766 | 767 | ||
767 | if (rtdev == ddev || rtdev == logdev) { | 768 | if (rtdev == ddev || rtdev == logdev) { |
768 | xfs_warn(mp, | 769 | xfs_warn(mp, |
769 | "Cannot mount filesystem with identical rtdev and ddev/logdev."); | 770 | "Cannot mount filesystem with identical rtdev and ddev/logdev."); |
770 | error = EINVAL; | 771 | error = EINVAL; |
771 | goto out_close_rtdev; | 772 | goto out_close_rtdev; |
772 | } | 773 | } |
773 | } | 774 | } |
774 | 775 | ||
775 | /* | 776 | /* |
776 | * Setup xfs_mount buffer target pointers | 777 | * Setup xfs_mount buffer target pointers |
777 | */ | 778 | */ |
778 | error = ENOMEM; | 779 | error = ENOMEM; |
779 | mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, 0, mp->m_fsname); | 780 | mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, 0, mp->m_fsname); |
780 | if (!mp->m_ddev_targp) | 781 | if (!mp->m_ddev_targp) |
781 | goto out_close_rtdev; | 782 | goto out_close_rtdev; |
782 | 783 | ||
783 | if (rtdev) { | 784 | if (rtdev) { |
784 | mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, 1, | 785 | mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, 1, |
785 | mp->m_fsname); | 786 | mp->m_fsname); |
786 | if (!mp->m_rtdev_targp) | 787 | if (!mp->m_rtdev_targp) |
787 | goto out_free_ddev_targ; | 788 | goto out_free_ddev_targ; |
788 | } | 789 | } |
789 | 790 | ||
790 | if (logdev && logdev != ddev) { | 791 | if (logdev && logdev != ddev) { |
791 | mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, 1, | 792 | mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, 1, |
792 | mp->m_fsname); | 793 | mp->m_fsname); |
793 | if (!mp->m_logdev_targp) | 794 | if (!mp->m_logdev_targp) |
794 | goto out_free_rtdev_targ; | 795 | goto out_free_rtdev_targ; |
795 | } else { | 796 | } else { |
796 | mp->m_logdev_targp = mp->m_ddev_targp; | 797 | mp->m_logdev_targp = mp->m_ddev_targp; |
797 | } | 798 | } |
798 | 799 | ||
799 | return 0; | 800 | return 0; |
800 | 801 | ||
801 | out_free_rtdev_targ: | 802 | out_free_rtdev_targ: |
802 | if (mp->m_rtdev_targp) | 803 | if (mp->m_rtdev_targp) |
803 | xfs_free_buftarg(mp, mp->m_rtdev_targp); | 804 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
804 | out_free_ddev_targ: | 805 | out_free_ddev_targ: |
805 | xfs_free_buftarg(mp, mp->m_ddev_targp); | 806 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
806 | out_close_rtdev: | 807 | out_close_rtdev: |
807 | if (rtdev) | 808 | if (rtdev) |
808 | xfs_blkdev_put(rtdev); | 809 | xfs_blkdev_put(rtdev); |
809 | out_close_logdev: | 810 | out_close_logdev: |
810 | if (logdev && logdev != ddev) | 811 | if (logdev && logdev != ddev) |
811 | xfs_blkdev_put(logdev); | 812 | xfs_blkdev_put(logdev); |
812 | out: | 813 | out: |
813 | return error; | 814 | return error; |
814 | } | 815 | } |
815 | 816 | ||
816 | /* | 817 | /* |
817 | * Setup xfs_mount buffer target pointers based on superblock | 818 | * Setup xfs_mount buffer target pointers based on superblock |
818 | */ | 819 | */ |
819 | STATIC int | 820 | STATIC int |
820 | xfs_setup_devices( | 821 | xfs_setup_devices( |
821 | struct xfs_mount *mp) | 822 | struct xfs_mount *mp) |
822 | { | 823 | { |
823 | int error; | 824 | int error; |
824 | 825 | ||
825 | error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, | 826 | error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, |
826 | mp->m_sb.sb_sectsize); | 827 | mp->m_sb.sb_sectsize); |
827 | if (error) | 828 | if (error) |
828 | return error; | 829 | return error; |
829 | 830 | ||
830 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { | 831 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { |
831 | unsigned int log_sector_size = BBSIZE; | 832 | unsigned int log_sector_size = BBSIZE; |
832 | 833 | ||
833 | if (xfs_sb_version_hassector(&mp->m_sb)) | 834 | if (xfs_sb_version_hassector(&mp->m_sb)) |
834 | log_sector_size = mp->m_sb.sb_logsectsize; | 835 | log_sector_size = mp->m_sb.sb_logsectsize; |
835 | error = xfs_setsize_buftarg(mp->m_logdev_targp, | 836 | error = xfs_setsize_buftarg(mp->m_logdev_targp, |
836 | mp->m_sb.sb_blocksize, | 837 | mp->m_sb.sb_blocksize, |
837 | log_sector_size); | 838 | log_sector_size); |
838 | if (error) | 839 | if (error) |
839 | return error; | 840 | return error; |
840 | } | 841 | } |
841 | if (mp->m_rtdev_targp) { | 842 | if (mp->m_rtdev_targp) { |
842 | error = xfs_setsize_buftarg(mp->m_rtdev_targp, | 843 | error = xfs_setsize_buftarg(mp->m_rtdev_targp, |
843 | mp->m_sb.sb_blocksize, | 844 | mp->m_sb.sb_blocksize, |
844 | mp->m_sb.sb_sectsize); | 845 | mp->m_sb.sb_sectsize); |
845 | if (error) | 846 | if (error) |
846 | return error; | 847 | return error; |
847 | } | 848 | } |
848 | 849 | ||
849 | return 0; | 850 | return 0; |
850 | } | 851 | } |
851 | 852 | ||
852 | STATIC int | 853 | STATIC int |
853 | xfs_init_mount_workqueues( | 854 | xfs_init_mount_workqueues( |
854 | struct xfs_mount *mp) | 855 | struct xfs_mount *mp) |
855 | { | 856 | { |
856 | mp->m_data_workqueue = alloc_workqueue("xfs-data/%s", | 857 | mp->m_data_workqueue = alloc_workqueue("xfs-data/%s", |
857 | WQ_MEM_RECLAIM, 0, mp->m_fsname); | 858 | WQ_MEM_RECLAIM, 0, mp->m_fsname); |
858 | if (!mp->m_data_workqueue) | 859 | if (!mp->m_data_workqueue) |
859 | goto out; | 860 | goto out; |
860 | 861 | ||
861 | mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s", | 862 | mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s", |
862 | WQ_MEM_RECLAIM, 0, mp->m_fsname); | 863 | WQ_MEM_RECLAIM, 0, mp->m_fsname); |
863 | if (!mp->m_unwritten_workqueue) | 864 | if (!mp->m_unwritten_workqueue) |
864 | goto out_destroy_data_iodone_queue; | 865 | goto out_destroy_data_iodone_queue; |
865 | 866 | ||
866 | mp->m_cil_workqueue = alloc_workqueue("xfs-cil/%s", | 867 | mp->m_cil_workqueue = alloc_workqueue("xfs-cil/%s", |
867 | WQ_MEM_RECLAIM, 0, mp->m_fsname); | 868 | WQ_MEM_RECLAIM, 0, mp->m_fsname); |
868 | if (!mp->m_cil_workqueue) | 869 | if (!mp->m_cil_workqueue) |
869 | goto out_destroy_unwritten; | 870 | goto out_destroy_unwritten; |
870 | 871 | ||
871 | mp->m_reclaim_workqueue = alloc_workqueue("xfs-reclaim/%s", | 872 | mp->m_reclaim_workqueue = alloc_workqueue("xfs-reclaim/%s", |
872 | WQ_NON_REENTRANT, 0, mp->m_fsname); | 873 | WQ_NON_REENTRANT, 0, mp->m_fsname); |
873 | if (!mp->m_reclaim_workqueue) | 874 | if (!mp->m_reclaim_workqueue) |
874 | goto out_destroy_cil; | 875 | goto out_destroy_cil; |
875 | 876 | ||
876 | mp->m_log_workqueue = alloc_workqueue("xfs-log/%s", | 877 | mp->m_log_workqueue = alloc_workqueue("xfs-log/%s", |
877 | WQ_NON_REENTRANT, 0, mp->m_fsname); | 878 | WQ_NON_REENTRANT, 0, mp->m_fsname); |
878 | if (!mp->m_log_workqueue) | 879 | if (!mp->m_log_workqueue) |
879 | goto out_destroy_reclaim; | 880 | goto out_destroy_reclaim; |
880 | 881 | ||
881 | mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s", | 882 | mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s", |
882 | WQ_NON_REENTRANT, 0, mp->m_fsname); | 883 | WQ_NON_REENTRANT, 0, mp->m_fsname); |
883 | if (!mp->m_eofblocks_workqueue) | 884 | if (!mp->m_eofblocks_workqueue) |
884 | goto out_destroy_log; | 885 | goto out_destroy_log; |
885 | 886 | ||
886 | return 0; | 887 | return 0; |
887 | 888 | ||
888 | out_destroy_log: | 889 | out_destroy_log: |
889 | destroy_workqueue(mp->m_log_workqueue); | 890 | destroy_workqueue(mp->m_log_workqueue); |
890 | out_destroy_reclaim: | 891 | out_destroy_reclaim: |
891 | destroy_workqueue(mp->m_reclaim_workqueue); | 892 | destroy_workqueue(mp->m_reclaim_workqueue); |
892 | out_destroy_cil: | 893 | out_destroy_cil: |
893 | destroy_workqueue(mp->m_cil_workqueue); | 894 | destroy_workqueue(mp->m_cil_workqueue); |
894 | out_destroy_unwritten: | 895 | out_destroy_unwritten: |
895 | destroy_workqueue(mp->m_unwritten_workqueue); | 896 | destroy_workqueue(mp->m_unwritten_workqueue); |
896 | out_destroy_data_iodone_queue: | 897 | out_destroy_data_iodone_queue: |
897 | destroy_workqueue(mp->m_data_workqueue); | 898 | destroy_workqueue(mp->m_data_workqueue); |
898 | out: | 899 | out: |
899 | return -ENOMEM; | 900 | return -ENOMEM; |
900 | } | 901 | } |
901 | 902 | ||
902 | STATIC void | 903 | STATIC void |
903 | xfs_destroy_mount_workqueues( | 904 | xfs_destroy_mount_workqueues( |
904 | struct xfs_mount *mp) | 905 | struct xfs_mount *mp) |
905 | { | 906 | { |
906 | destroy_workqueue(mp->m_eofblocks_workqueue); | 907 | destroy_workqueue(mp->m_eofblocks_workqueue); |
907 | destroy_workqueue(mp->m_log_workqueue); | 908 | destroy_workqueue(mp->m_log_workqueue); |
908 | destroy_workqueue(mp->m_reclaim_workqueue); | 909 | destroy_workqueue(mp->m_reclaim_workqueue); |
909 | destroy_workqueue(mp->m_cil_workqueue); | 910 | destroy_workqueue(mp->m_cil_workqueue); |
910 | destroy_workqueue(mp->m_data_workqueue); | 911 | destroy_workqueue(mp->m_data_workqueue); |
911 | destroy_workqueue(mp->m_unwritten_workqueue); | 912 | destroy_workqueue(mp->m_unwritten_workqueue); |
912 | } | 913 | } |
913 | 914 | ||
914 | /* | 915 | /* |
915 | * Flush all dirty data to disk. Must not be called while holding an XFS_ILOCK | 916 | * Flush all dirty data to disk. Must not be called while holding an XFS_ILOCK |
916 | * or a page lock. We use sync_inodes_sb() here to ensure we block while waiting | 917 | * or a page lock. We use sync_inodes_sb() here to ensure we block while waiting |
917 | * for IO to complete so that we effectively throttle multiple callers to the | 918 | * for IO to complete so that we effectively throttle multiple callers to the |
918 | * rate at which IO is completing. | 919 | * rate at which IO is completing. |
919 | */ | 920 | */ |
920 | void | 921 | void |
921 | xfs_flush_inodes( | 922 | xfs_flush_inodes( |
922 | struct xfs_mount *mp) | 923 | struct xfs_mount *mp) |
923 | { | 924 | { |
924 | struct super_block *sb = mp->m_super; | 925 | struct super_block *sb = mp->m_super; |
925 | 926 | ||
926 | if (down_read_trylock(&sb->s_umount)) { | 927 | if (down_read_trylock(&sb->s_umount)) { |
927 | sync_inodes_sb(sb); | 928 | sync_inodes_sb(sb); |
928 | up_read(&sb->s_umount); | 929 | up_read(&sb->s_umount); |
929 | } | 930 | } |
930 | } | 931 | } |
931 | 932 | ||
932 | /* Catch misguided souls that try to use this interface on XFS */ | 933 | /* Catch misguided souls that try to use this interface on XFS */ |
933 | STATIC struct inode * | 934 | STATIC struct inode * |
934 | xfs_fs_alloc_inode( | 935 | xfs_fs_alloc_inode( |
935 | struct super_block *sb) | 936 | struct super_block *sb) |
936 | { | 937 | { |
937 | BUG(); | 938 | BUG(); |
938 | return NULL; | 939 | return NULL; |
939 | } | 940 | } |
940 | 941 | ||
941 | /* | 942 | /* |
942 | * Now that the generic code is guaranteed not to be accessing | 943 | * Now that the generic code is guaranteed not to be accessing |
943 | * the linux inode, we can reclaim the inode. | 944 | * the linux inode, we can reclaim the inode. |
944 | */ | 945 | */ |
945 | STATIC void | 946 | STATIC void |
946 | xfs_fs_destroy_inode( | 947 | xfs_fs_destroy_inode( |
947 | struct inode *inode) | 948 | struct inode *inode) |
948 | { | 949 | { |
949 | struct xfs_inode *ip = XFS_I(inode); | 950 | struct xfs_inode *ip = XFS_I(inode); |
950 | 951 | ||
951 | trace_xfs_destroy_inode(ip); | 952 | trace_xfs_destroy_inode(ip); |
952 | 953 | ||
953 | XFS_STATS_INC(vn_reclaim); | 954 | XFS_STATS_INC(vn_reclaim); |
954 | 955 | ||
955 | /* bad inode, get out here ASAP */ | 956 | /* bad inode, get out here ASAP */ |
956 | if (is_bad_inode(inode)) | 957 | if (is_bad_inode(inode)) |
957 | goto out_reclaim; | 958 | goto out_reclaim; |
958 | 959 | ||
959 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); | 960 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); |
960 | 961 | ||
961 | /* | 962 | /* |
962 | * We should never get here with one of the reclaim flags already set. | 963 | * We should never get here with one of the reclaim flags already set. |
963 | */ | 964 | */ |
964 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | 965 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); |
965 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); | 966 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); |
966 | 967 | ||
967 | /* | 968 | /* |
968 | * We always use background reclaim here because even if the | 969 | * We always use background reclaim here because even if the |
969 | * inode is clean, it still may be under IO and hence we have | 970 | * inode is clean, it still may be under IO and hence we have |
970 | * to take the flush lock. The background reclaim path handles | 971 | * to take the flush lock. The background reclaim path handles |
971 | * this more efficiently than we can here, so simply let background | 972 | * this more efficiently than we can here, so simply let background |
972 | * reclaim tear down all inodes. | 973 | * reclaim tear down all inodes. |
973 | */ | 974 | */ |
974 | out_reclaim: | 975 | out_reclaim: |
975 | xfs_inode_set_reclaim_tag(ip); | 976 | xfs_inode_set_reclaim_tag(ip); |
976 | } | 977 | } |
977 | 978 | ||
978 | /* | 979 | /* |
979 | * Slab object creation initialisation for the XFS inode. | 980 | * Slab object creation initialisation for the XFS inode. |
980 | * This covers only the idempotent fields in the XFS inode; | 981 | * This covers only the idempotent fields in the XFS inode; |
981 | * all other fields need to be initialised on allocation | 982 | * all other fields need to be initialised on allocation |
982 | * from the slab. This avoids the need to repeatedly initialise | 983 | * from the slab. This avoids the need to repeatedly initialise |
983 | * fields in the xfs inode that left in the initialise state | 984 | * fields in the xfs inode that left in the initialise state |
984 | * when freeing the inode. | 985 | * when freeing the inode. |
985 | */ | 986 | */ |
986 | STATIC void | 987 | STATIC void |
987 | xfs_fs_inode_init_once( | 988 | xfs_fs_inode_init_once( |
988 | void *inode) | 989 | void *inode) |
989 | { | 990 | { |
990 | struct xfs_inode *ip = inode; | 991 | struct xfs_inode *ip = inode; |
991 | 992 | ||
992 | memset(ip, 0, sizeof(struct xfs_inode)); | 993 | memset(ip, 0, sizeof(struct xfs_inode)); |
993 | 994 | ||
994 | /* vfs inode */ | 995 | /* vfs inode */ |
995 | inode_init_once(VFS_I(ip)); | 996 | inode_init_once(VFS_I(ip)); |
996 | 997 | ||
997 | /* xfs inode */ | 998 | /* xfs inode */ |
998 | atomic_set(&ip->i_pincount, 0); | 999 | atomic_set(&ip->i_pincount, 0); |
999 | spin_lock_init(&ip->i_flags_lock); | 1000 | spin_lock_init(&ip->i_flags_lock); |
1000 | 1001 | ||
1001 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | 1002 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, |
1002 | "xfsino", ip->i_ino); | 1003 | "xfsino", ip->i_ino); |
1003 | } | 1004 | } |
1004 | 1005 | ||
1005 | STATIC void | 1006 | STATIC void |
1006 | xfs_fs_evict_inode( | 1007 | xfs_fs_evict_inode( |
1007 | struct inode *inode) | 1008 | struct inode *inode) |
1008 | { | 1009 | { |
1009 | xfs_inode_t *ip = XFS_I(inode); | 1010 | xfs_inode_t *ip = XFS_I(inode); |
1010 | 1011 | ||
1011 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); | 1012 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); |
1012 | 1013 | ||
1013 | trace_xfs_evict_inode(ip); | 1014 | trace_xfs_evict_inode(ip); |
1014 | 1015 | ||
1015 | truncate_inode_pages(&inode->i_data, 0); | 1016 | truncate_inode_pages(&inode->i_data, 0); |
1016 | clear_inode(inode); | 1017 | clear_inode(inode); |
1017 | XFS_STATS_INC(vn_rele); | 1018 | XFS_STATS_INC(vn_rele); |
1018 | XFS_STATS_INC(vn_remove); | 1019 | XFS_STATS_INC(vn_remove); |
1019 | XFS_STATS_DEC(vn_active); | 1020 | XFS_STATS_DEC(vn_active); |
1020 | 1021 | ||
1021 | xfs_inactive(ip); | 1022 | xfs_inactive(ip); |
1022 | } | 1023 | } |
1023 | 1024 | ||
1024 | /* | 1025 | /* |
1025 | * We do an unlocked check for XFS_IDONTCACHE here because we are already | 1026 | * We do an unlocked check for XFS_IDONTCACHE here because we are already |
1026 | * serialised against cache hits here via the inode->i_lock and igrab() in | 1027 | * serialised against cache hits here via the inode->i_lock and igrab() in |
1027 | * xfs_iget_cache_hit(). Hence a lookup that might clear this flag will not be | 1028 | * xfs_iget_cache_hit(). Hence a lookup that might clear this flag will not be |
1028 | * racing with us, and it avoids needing to grab a spinlock here for every inode | 1029 | * racing with us, and it avoids needing to grab a spinlock here for every inode |
1029 | * we drop the final reference on. | 1030 | * we drop the final reference on. |
1030 | */ | 1031 | */ |
1031 | STATIC int | 1032 | STATIC int |
1032 | xfs_fs_drop_inode( | 1033 | xfs_fs_drop_inode( |
1033 | struct inode *inode) | 1034 | struct inode *inode) |
1034 | { | 1035 | { |
1035 | struct xfs_inode *ip = XFS_I(inode); | 1036 | struct xfs_inode *ip = XFS_I(inode); |
1036 | 1037 | ||
1037 | return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE); | 1038 | return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE); |
1038 | } | 1039 | } |
1039 | 1040 | ||
1040 | STATIC void | 1041 | STATIC void |
1041 | xfs_free_fsname( | 1042 | xfs_free_fsname( |
1042 | struct xfs_mount *mp) | 1043 | struct xfs_mount *mp) |
1043 | { | 1044 | { |
1044 | kfree(mp->m_fsname); | 1045 | kfree(mp->m_fsname); |
1045 | kfree(mp->m_rtname); | 1046 | kfree(mp->m_rtname); |
1046 | kfree(mp->m_logname); | 1047 | kfree(mp->m_logname); |
1047 | } | 1048 | } |
1048 | 1049 | ||
1049 | STATIC void | 1050 | STATIC void |
1050 | xfs_fs_put_super( | 1051 | xfs_fs_put_super( |
1051 | struct super_block *sb) | 1052 | struct super_block *sb) |
1052 | { | 1053 | { |
1053 | struct xfs_mount *mp = XFS_M(sb); | 1054 | struct xfs_mount *mp = XFS_M(sb); |
1054 | 1055 | ||
1055 | xfs_filestream_unmount(mp); | 1056 | xfs_filestream_unmount(mp); |
1056 | xfs_unmountfs(mp); | 1057 | xfs_unmountfs(mp); |
1057 | 1058 | ||
1058 | xfs_freesb(mp); | 1059 | xfs_freesb(mp); |
1059 | xfs_icsb_destroy_counters(mp); | 1060 | xfs_icsb_destroy_counters(mp); |
1060 | xfs_destroy_mount_workqueues(mp); | 1061 | xfs_destroy_mount_workqueues(mp); |
1061 | xfs_close_devices(mp); | 1062 | xfs_close_devices(mp); |
1062 | xfs_free_fsname(mp); | 1063 | xfs_free_fsname(mp); |
1063 | kfree(mp); | 1064 | kfree(mp); |
1064 | } | 1065 | } |
1065 | 1066 | ||
1066 | STATIC int | 1067 | STATIC int |
1067 | xfs_fs_sync_fs( | 1068 | xfs_fs_sync_fs( |
1068 | struct super_block *sb, | 1069 | struct super_block *sb, |
1069 | int wait) | 1070 | int wait) |
1070 | { | 1071 | { |
1071 | struct xfs_mount *mp = XFS_M(sb); | 1072 | struct xfs_mount *mp = XFS_M(sb); |
1072 | 1073 | ||
1073 | /* | 1074 | /* |
1074 | * Doing anything during the async pass would be counterproductive. | 1075 | * Doing anything during the async pass would be counterproductive. |
1075 | */ | 1076 | */ |
1076 | if (!wait) | 1077 | if (!wait) |
1077 | return 0; | 1078 | return 0; |
1078 | 1079 | ||
1079 | xfs_log_force(mp, XFS_LOG_SYNC); | 1080 | xfs_log_force(mp, XFS_LOG_SYNC); |
1080 | if (laptop_mode) { | 1081 | if (laptop_mode) { |
1081 | /* | 1082 | /* |
1082 | * The disk must be active because we're syncing. | 1083 | * The disk must be active because we're syncing. |
1083 | * We schedule log work now (now that the disk is | 1084 | * We schedule log work now (now that the disk is |
1084 | * active) instead of later (when it might not be). | 1085 | * active) instead of later (when it might not be). |
1085 | */ | 1086 | */ |
1086 | flush_delayed_work(&mp->m_log->l_work); | 1087 | flush_delayed_work(&mp->m_log->l_work); |
1087 | } | 1088 | } |
1088 | 1089 | ||
1089 | return 0; | 1090 | return 0; |
1090 | } | 1091 | } |
1091 | 1092 | ||
1092 | STATIC int | 1093 | STATIC int |
1093 | xfs_fs_statfs( | 1094 | xfs_fs_statfs( |
1094 | struct dentry *dentry, | 1095 | struct dentry *dentry, |
1095 | struct kstatfs *statp) | 1096 | struct kstatfs *statp) |
1096 | { | 1097 | { |
1097 | struct xfs_mount *mp = XFS_M(dentry->d_sb); | 1098 | struct xfs_mount *mp = XFS_M(dentry->d_sb); |
1098 | xfs_sb_t *sbp = &mp->m_sb; | 1099 | xfs_sb_t *sbp = &mp->m_sb; |
1099 | struct xfs_inode *ip = XFS_I(dentry->d_inode); | 1100 | struct xfs_inode *ip = XFS_I(dentry->d_inode); |
1100 | __uint64_t fakeinos, id; | 1101 | __uint64_t fakeinos, id; |
1101 | xfs_extlen_t lsize; | 1102 | xfs_extlen_t lsize; |
1102 | __int64_t ffree; | 1103 | __int64_t ffree; |
1103 | 1104 | ||
1104 | statp->f_type = XFS_SB_MAGIC; | 1105 | statp->f_type = XFS_SB_MAGIC; |
1105 | statp->f_namelen = MAXNAMELEN - 1; | 1106 | statp->f_namelen = MAXNAMELEN - 1; |
1106 | 1107 | ||
1107 | id = huge_encode_dev(mp->m_ddev_targp->bt_dev); | 1108 | id = huge_encode_dev(mp->m_ddev_targp->bt_dev); |
1108 | statp->f_fsid.val[0] = (u32)id; | 1109 | statp->f_fsid.val[0] = (u32)id; |
1109 | statp->f_fsid.val[1] = (u32)(id >> 32); | 1110 | statp->f_fsid.val[1] = (u32)(id >> 32); |
1110 | 1111 | ||
1111 | xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); | 1112 | xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); |
1112 | 1113 | ||
1113 | spin_lock(&mp->m_sb_lock); | 1114 | spin_lock(&mp->m_sb_lock); |
1114 | statp->f_bsize = sbp->sb_blocksize; | 1115 | statp->f_bsize = sbp->sb_blocksize; |
1115 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; | 1116 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; |
1116 | statp->f_blocks = sbp->sb_dblocks - lsize; | 1117 | statp->f_blocks = sbp->sb_dblocks - lsize; |
1117 | statp->f_bfree = statp->f_bavail = | 1118 | statp->f_bfree = statp->f_bavail = |
1118 | sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); | 1119 | sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); |
1119 | fakeinos = statp->f_bfree << sbp->sb_inopblog; | 1120 | fakeinos = statp->f_bfree << sbp->sb_inopblog; |
1120 | statp->f_files = | 1121 | statp->f_files = |
1121 | MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER); | 1122 | MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER); |
1122 | if (mp->m_maxicount) | 1123 | if (mp->m_maxicount) |
1123 | statp->f_files = min_t(typeof(statp->f_files), | 1124 | statp->f_files = min_t(typeof(statp->f_files), |
1124 | statp->f_files, | 1125 | statp->f_files, |
1125 | mp->m_maxicount); | 1126 | mp->m_maxicount); |
1126 | 1127 | ||
1127 | /* make sure statp->f_ffree does not underflow */ | 1128 | /* make sure statp->f_ffree does not underflow */ |
1128 | ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); | 1129 | ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); |
1129 | statp->f_ffree = max_t(__int64_t, ffree, 0); | 1130 | statp->f_ffree = max_t(__int64_t, ffree, 0); |
1130 | 1131 | ||
1131 | spin_unlock(&mp->m_sb_lock); | 1132 | spin_unlock(&mp->m_sb_lock); |
1132 | 1133 | ||
1133 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && | 1134 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && |
1134 | ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) == | 1135 | ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) == |
1135 | (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) | 1136 | (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) |
1136 | xfs_qm_statvfs(ip, statp); | 1137 | xfs_qm_statvfs(ip, statp); |
1137 | return 0; | 1138 | return 0; |
1138 | } | 1139 | } |
1139 | 1140 | ||
1140 | STATIC void | 1141 | STATIC void |
1141 | xfs_save_resvblks(struct xfs_mount *mp) | 1142 | xfs_save_resvblks(struct xfs_mount *mp) |
1142 | { | 1143 | { |
1143 | __uint64_t resblks = 0; | 1144 | __uint64_t resblks = 0; |
1144 | 1145 | ||
1145 | mp->m_resblks_save = mp->m_resblks; | 1146 | mp->m_resblks_save = mp->m_resblks; |
1146 | xfs_reserve_blocks(mp, &resblks, NULL); | 1147 | xfs_reserve_blocks(mp, &resblks, NULL); |
1147 | } | 1148 | } |
1148 | 1149 | ||
1149 | STATIC void | 1150 | STATIC void |
1150 | xfs_restore_resvblks(struct xfs_mount *mp) | 1151 | xfs_restore_resvblks(struct xfs_mount *mp) |
1151 | { | 1152 | { |
1152 | __uint64_t resblks; | 1153 | __uint64_t resblks; |
1153 | 1154 | ||
1154 | if (mp->m_resblks_save) { | 1155 | if (mp->m_resblks_save) { |
1155 | resblks = mp->m_resblks_save; | 1156 | resblks = mp->m_resblks_save; |
1156 | mp->m_resblks_save = 0; | 1157 | mp->m_resblks_save = 0; |
1157 | } else | 1158 | } else |
1158 | resblks = xfs_default_resblks(mp); | 1159 | resblks = xfs_default_resblks(mp); |
1159 | 1160 | ||
1160 | xfs_reserve_blocks(mp, &resblks, NULL); | 1161 | xfs_reserve_blocks(mp, &resblks, NULL); |
1161 | } | 1162 | } |
1162 | 1163 | ||
1163 | /* | 1164 | /* |
1164 | * Trigger writeback of all the dirty metadata in the file system. | 1165 | * Trigger writeback of all the dirty metadata in the file system. |
1165 | * | 1166 | * |
1166 | * This ensures that the metadata is written to their location on disk rather | 1167 | * This ensures that the metadata is written to their location on disk rather |
1167 | * than just existing in transactions in the log. This means after a quiesce | 1168 | * than just existing in transactions in the log. This means after a quiesce |
1168 | * there is no log replay required to write the inodes to disk - this is the | 1169 | * there is no log replay required to write the inodes to disk - this is the |
1169 | * primary difference between a sync and a quiesce. | 1170 | * primary difference between a sync and a quiesce. |
1170 | * | 1171 | * |
1171 | * Note: xfs_log_quiesce() stops background log work - the callers must ensure | 1172 | * Note: xfs_log_quiesce() stops background log work - the callers must ensure |
1172 | * it is started again when appropriate. | 1173 | * it is started again when appropriate. |
1173 | */ | 1174 | */ |
1174 | void | 1175 | void |
1175 | xfs_quiesce_attr( | 1176 | xfs_quiesce_attr( |
1176 | struct xfs_mount *mp) | 1177 | struct xfs_mount *mp) |
1177 | { | 1178 | { |
1178 | int error = 0; | 1179 | int error = 0; |
1179 | 1180 | ||
1180 | /* wait for all modifications to complete */ | 1181 | /* wait for all modifications to complete */ |
1181 | while (atomic_read(&mp->m_active_trans) > 0) | 1182 | while (atomic_read(&mp->m_active_trans) > 0) |
1182 | delay(100); | 1183 | delay(100); |
1183 | 1184 | ||
1184 | /* force the log to unpin objects from the now complete transactions */ | 1185 | /* force the log to unpin objects from the now complete transactions */ |
1185 | xfs_log_force(mp, XFS_LOG_SYNC); | 1186 | xfs_log_force(mp, XFS_LOG_SYNC); |
1186 | 1187 | ||
1187 | /* reclaim inodes to do any IO before the freeze completes */ | 1188 | /* reclaim inodes to do any IO before the freeze completes */ |
1188 | xfs_reclaim_inodes(mp, 0); | 1189 | xfs_reclaim_inodes(mp, 0); |
1189 | xfs_reclaim_inodes(mp, SYNC_WAIT); | 1190 | xfs_reclaim_inodes(mp, SYNC_WAIT); |
1190 | 1191 | ||
1191 | /* Push the superblock and write an unmount record */ | 1192 | /* Push the superblock and write an unmount record */ |
1192 | error = xfs_log_sbcount(mp); | 1193 | error = xfs_log_sbcount(mp); |
1193 | if (error) | 1194 | if (error) |
1194 | xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. " | 1195 | xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. " |
1195 | "Frozen image may not be consistent."); | 1196 | "Frozen image may not be consistent."); |
1196 | /* | 1197 | /* |
1197 | * Just warn here till VFS can correctly support | 1198 | * Just warn here till VFS can correctly support |
1198 | * read-only remount without racing. | 1199 | * read-only remount without racing. |
1199 | */ | 1200 | */ |
1200 | WARN_ON(atomic_read(&mp->m_active_trans) != 0); | 1201 | WARN_ON(atomic_read(&mp->m_active_trans) != 0); |
1201 | 1202 | ||
1202 | xfs_log_quiesce(mp); | 1203 | xfs_log_quiesce(mp); |
1203 | } | 1204 | } |
1204 | 1205 | ||
1205 | STATIC int | 1206 | STATIC int |
1206 | xfs_fs_remount( | 1207 | xfs_fs_remount( |
1207 | struct super_block *sb, | 1208 | struct super_block *sb, |
1208 | int *flags, | 1209 | int *flags, |
1209 | char *options) | 1210 | char *options) |
1210 | { | 1211 | { |
1211 | struct xfs_mount *mp = XFS_M(sb); | 1212 | struct xfs_mount *mp = XFS_M(sb); |
1212 | substring_t args[MAX_OPT_ARGS]; | 1213 | substring_t args[MAX_OPT_ARGS]; |
1213 | char *p; | 1214 | char *p; |
1214 | int error; | 1215 | int error; |
1215 | 1216 | ||
1216 | while ((p = strsep(&options, ",")) != NULL) { | 1217 | while ((p = strsep(&options, ",")) != NULL) { |
1217 | int token; | 1218 | int token; |
1218 | 1219 | ||
1219 | if (!*p) | 1220 | if (!*p) |
1220 | continue; | 1221 | continue; |
1221 | 1222 | ||
1222 | token = match_token(p, tokens, args); | 1223 | token = match_token(p, tokens, args); |
1223 | switch (token) { | 1224 | switch (token) { |
1224 | case Opt_barrier: | 1225 | case Opt_barrier: |
1225 | mp->m_flags |= XFS_MOUNT_BARRIER; | 1226 | mp->m_flags |= XFS_MOUNT_BARRIER; |
1226 | break; | 1227 | break; |
1227 | case Opt_nobarrier: | 1228 | case Opt_nobarrier: |
1228 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 1229 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
1229 | break; | 1230 | break; |
1230 | case Opt_inode64: | 1231 | case Opt_inode64: |
1231 | mp->m_maxagi = xfs_set_inode64(mp); | 1232 | mp->m_maxagi = xfs_set_inode64(mp); |
1232 | break; | 1233 | break; |
1233 | case Opt_inode32: | 1234 | case Opt_inode32: |
1234 | mp->m_maxagi = xfs_set_inode32(mp); | 1235 | mp->m_maxagi = xfs_set_inode32(mp); |
1235 | break; | 1236 | break; |
1236 | default: | 1237 | default: |
1237 | /* | 1238 | /* |
1238 | * Logically we would return an error here to prevent | 1239 | * Logically we would return an error here to prevent |
1239 | * users from believing they might have changed | 1240 | * users from believing they might have changed |
1240 | * mount options using remount which can't be changed. | 1241 | * mount options using remount which can't be changed. |
1241 | * | 1242 | * |
1242 | * But unfortunately mount(8) adds all options from | 1243 | * But unfortunately mount(8) adds all options from |
1243 | * mtab and fstab to the mount arguments in some cases | 1244 | * mtab and fstab to the mount arguments in some cases |
1244 | * so we can't blindly reject options, but have to | 1245 | * so we can't blindly reject options, but have to |
1245 | * check for each specified option if it actually | 1246 | * check for each specified option if it actually |
1246 | * differs from the currently set option and only | 1247 | * differs from the currently set option and only |
1247 | * reject it if that's the case. | 1248 | * reject it if that's the case. |
1248 | * | 1249 | * |
1249 | * Until that is implemented we return success for | 1250 | * Until that is implemented we return success for |
1250 | * every remount request, and silently ignore all | 1251 | * every remount request, and silently ignore all |
1251 | * options that we can't actually change. | 1252 | * options that we can't actually change. |
1252 | */ | 1253 | */ |
1253 | #if 0 | 1254 | #if 0 |
1254 | xfs_info(mp, | 1255 | xfs_info(mp, |
1255 | "mount option \"%s\" not supported for remount\n", p); | 1256 | "mount option \"%s\" not supported for remount\n", p); |
1256 | return -EINVAL; | 1257 | return -EINVAL; |
1257 | #else | 1258 | #else |
1258 | break; | 1259 | break; |
1259 | #endif | 1260 | #endif |
1260 | } | 1261 | } |
1261 | } | 1262 | } |
1262 | 1263 | ||
1263 | /* ro -> rw */ | 1264 | /* ro -> rw */ |
1264 | if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { | 1265 | if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { |
1265 | mp->m_flags &= ~XFS_MOUNT_RDONLY; | 1266 | mp->m_flags &= ~XFS_MOUNT_RDONLY; |
1266 | 1267 | ||
1267 | /* | 1268 | /* |
1268 | * If this is the first remount to writeable state we | 1269 | * If this is the first remount to writeable state we |
1269 | * might have some superblock changes to update. | 1270 | * might have some superblock changes to update. |
1270 | */ | 1271 | */ |
1271 | if (mp->m_update_flags) { | 1272 | if (mp->m_update_flags) { |
1272 | error = xfs_mount_log_sb(mp, mp->m_update_flags); | 1273 | error = xfs_mount_log_sb(mp, mp->m_update_flags); |
1273 | if (error) { | 1274 | if (error) { |
1274 | xfs_warn(mp, "failed to write sb changes"); | 1275 | xfs_warn(mp, "failed to write sb changes"); |
1275 | return error; | 1276 | return error; |
1276 | } | 1277 | } |
1277 | mp->m_update_flags = 0; | 1278 | mp->m_update_flags = 0; |
1278 | } | 1279 | } |
1279 | 1280 | ||
1280 | /* | 1281 | /* |
1281 | * Fill out the reserve pool if it is empty. Use the stashed | 1282 | * Fill out the reserve pool if it is empty. Use the stashed |
1282 | * value if it is non-zero, otherwise go with the default. | 1283 | * value if it is non-zero, otherwise go with the default. |
1283 | */ | 1284 | */ |
1284 | xfs_restore_resvblks(mp); | 1285 | xfs_restore_resvblks(mp); |
1285 | xfs_log_work_queue(mp); | 1286 | xfs_log_work_queue(mp); |
1286 | } | 1287 | } |
1287 | 1288 | ||
1288 | /* rw -> ro */ | 1289 | /* rw -> ro */ |
1289 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { | 1290 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { |
1290 | /* | 1291 | /* |
1291 | * Before we sync the metadata, we need to free up the reserve | 1292 | * Before we sync the metadata, we need to free up the reserve |
1292 | * block pool so that the used block count in the superblock on | 1293 | * block pool so that the used block count in the superblock on |
1293 | * disk is correct at the end of the remount. Stash the current | 1294 | * disk is correct at the end of the remount. Stash the current |
1294 | * reserve pool size so that if we get remounted rw, we can | 1295 | * reserve pool size so that if we get remounted rw, we can |
1295 | * return it to the same size. | 1296 | * return it to the same size. |
1296 | */ | 1297 | */ |
1297 | xfs_save_resvblks(mp); | 1298 | xfs_save_resvblks(mp); |
1298 | xfs_quiesce_attr(mp); | 1299 | xfs_quiesce_attr(mp); |
1299 | mp->m_flags |= XFS_MOUNT_RDONLY; | 1300 | mp->m_flags |= XFS_MOUNT_RDONLY; |
1300 | } | 1301 | } |
1301 | 1302 | ||
1302 | return 0; | 1303 | return 0; |
1303 | } | 1304 | } |
1304 | 1305 | ||
1305 | /* | 1306 | /* |
1306 | * Second stage of a freeze. The data is already frozen so we only | 1307 | * Second stage of a freeze. The data is already frozen so we only |
1307 | * need to take care of the metadata. Once that's done write a dummy | 1308 | * need to take care of the metadata. Once that's done write a dummy |
1308 | * record to dirty the log in case of a crash while frozen. | 1309 | * record to dirty the log in case of a crash while frozen. |
1309 | */ | 1310 | */ |
1310 | STATIC int | 1311 | STATIC int |
1311 | xfs_fs_freeze( | 1312 | xfs_fs_freeze( |
1312 | struct super_block *sb) | 1313 | struct super_block *sb) |
1313 | { | 1314 | { |
1314 | struct xfs_mount *mp = XFS_M(sb); | 1315 | struct xfs_mount *mp = XFS_M(sb); |
1315 | 1316 | ||
1316 | xfs_save_resvblks(mp); | 1317 | xfs_save_resvblks(mp); |
1317 | xfs_quiesce_attr(mp); | 1318 | xfs_quiesce_attr(mp); |
1318 | return -xfs_fs_log_dummy(mp); | 1319 | return -xfs_fs_log_dummy(mp); |
1319 | } | 1320 | } |
1320 | 1321 | ||
1321 | STATIC int | 1322 | STATIC int |
1322 | xfs_fs_unfreeze( | 1323 | xfs_fs_unfreeze( |
1323 | struct super_block *sb) | 1324 | struct super_block *sb) |
1324 | { | 1325 | { |
1325 | struct xfs_mount *mp = XFS_M(sb); | 1326 | struct xfs_mount *mp = XFS_M(sb); |
1326 | 1327 | ||
1327 | xfs_restore_resvblks(mp); | 1328 | xfs_restore_resvblks(mp); |
1328 | xfs_log_work_queue(mp); | 1329 | xfs_log_work_queue(mp); |
1329 | return 0; | 1330 | return 0; |
1330 | } | 1331 | } |
1331 | 1332 | ||
1332 | STATIC int | 1333 | STATIC int |
1333 | xfs_fs_show_options( | 1334 | xfs_fs_show_options( |
1334 | struct seq_file *m, | 1335 | struct seq_file *m, |
1335 | struct dentry *root) | 1336 | struct dentry *root) |
1336 | { | 1337 | { |
1337 | return -xfs_showargs(XFS_M(root->d_sb), m); | 1338 | return -xfs_showargs(XFS_M(root->d_sb), m); |
1338 | } | 1339 | } |
1339 | 1340 | ||
1340 | /* | 1341 | /* |
1341 | * This function fills in xfs_mount_t fields based on mount args. | 1342 | * This function fills in xfs_mount_t fields based on mount args. |
1342 | * Note: the superblock _has_ now been read in. | 1343 | * Note: the superblock _has_ now been read in. |
1343 | */ | 1344 | */ |
1344 | STATIC int | 1345 | STATIC int |
1345 | xfs_finish_flags( | 1346 | xfs_finish_flags( |
1346 | struct xfs_mount *mp) | 1347 | struct xfs_mount *mp) |
1347 | { | 1348 | { |
1348 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); | 1349 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); |
1349 | 1350 | ||
1350 | /* Fail a mount where the logbuf is smaller than the log stripe */ | 1351 | /* Fail a mount where the logbuf is smaller than the log stripe */ |
1351 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { | 1352 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { |
1352 | if (mp->m_logbsize <= 0 && | 1353 | if (mp->m_logbsize <= 0 && |
1353 | mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) { | 1354 | mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) { |
1354 | mp->m_logbsize = mp->m_sb.sb_logsunit; | 1355 | mp->m_logbsize = mp->m_sb.sb_logsunit; |
1355 | } else if (mp->m_logbsize > 0 && | 1356 | } else if (mp->m_logbsize > 0 && |
1356 | mp->m_logbsize < mp->m_sb.sb_logsunit) { | 1357 | mp->m_logbsize < mp->m_sb.sb_logsunit) { |
1357 | xfs_warn(mp, | 1358 | xfs_warn(mp, |
1358 | "logbuf size must be greater than or equal to log stripe size"); | 1359 | "logbuf size must be greater than or equal to log stripe size"); |
1359 | return XFS_ERROR(EINVAL); | 1360 | return XFS_ERROR(EINVAL); |
1360 | } | 1361 | } |
1361 | } else { | 1362 | } else { |
1362 | /* Fail a mount if the logbuf is larger than 32K */ | 1363 | /* Fail a mount if the logbuf is larger than 32K */ |
1363 | if (mp->m_logbsize > XLOG_BIG_RECORD_BSIZE) { | 1364 | if (mp->m_logbsize > XLOG_BIG_RECORD_BSIZE) { |
1364 | xfs_warn(mp, | 1365 | xfs_warn(mp, |
1365 | "logbuf size for version 1 logs must be 16K or 32K"); | 1366 | "logbuf size for version 1 logs must be 16K or 32K"); |
1366 | return XFS_ERROR(EINVAL); | 1367 | return XFS_ERROR(EINVAL); |
1367 | } | 1368 | } |
1368 | } | 1369 | } |
1369 | 1370 | ||
1370 | /* | 1371 | /* |
1371 | * V5 filesystems always use attr2 format for attributes. | 1372 | * V5 filesystems always use attr2 format for attributes. |
1372 | */ | 1373 | */ |
1373 | if (xfs_sb_version_hascrc(&mp->m_sb) && | 1374 | if (xfs_sb_version_hascrc(&mp->m_sb) && |
1374 | (mp->m_flags & XFS_MOUNT_NOATTR2)) { | 1375 | (mp->m_flags & XFS_MOUNT_NOATTR2)) { |
1375 | xfs_warn(mp, | 1376 | xfs_warn(mp, |
1376 | "Cannot mount a V5 filesystem as %s. %s is always enabled for V5 filesystems.", | 1377 | "Cannot mount a V5 filesystem as %s. %s is always enabled for V5 filesystems.", |
1377 | MNTOPT_NOATTR2, MNTOPT_ATTR2); | 1378 | MNTOPT_NOATTR2, MNTOPT_ATTR2); |
1378 | return XFS_ERROR(EINVAL); | 1379 | return XFS_ERROR(EINVAL); |
1379 | } | 1380 | } |
1380 | 1381 | ||
1381 | /* | 1382 | /* |
1382 | * mkfs'ed attr2 will turn on attr2 mount unless explicitly | 1383 | * mkfs'ed attr2 will turn on attr2 mount unless explicitly |
1383 | * told by noattr2 to turn it off | 1384 | * told by noattr2 to turn it off |
1384 | */ | 1385 | */ |
1385 | if (xfs_sb_version_hasattr2(&mp->m_sb) && | 1386 | if (xfs_sb_version_hasattr2(&mp->m_sb) && |
1386 | !(mp->m_flags & XFS_MOUNT_NOATTR2)) | 1387 | !(mp->m_flags & XFS_MOUNT_NOATTR2)) |
1387 | mp->m_flags |= XFS_MOUNT_ATTR2; | 1388 | mp->m_flags |= XFS_MOUNT_ATTR2; |
1388 | 1389 | ||
1389 | /* | 1390 | /* |
1390 | * prohibit r/w mounts of read-only filesystems | 1391 | * prohibit r/w mounts of read-only filesystems |
1391 | */ | 1392 | */ |
1392 | if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) { | 1393 | if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) { |
1393 | xfs_warn(mp, | 1394 | xfs_warn(mp, |
1394 | "cannot mount a read-only filesystem as read-write"); | 1395 | "cannot mount a read-only filesystem as read-write"); |
1395 | return XFS_ERROR(EROFS); | 1396 | return XFS_ERROR(EROFS); |
1396 | } | 1397 | } |
1397 | 1398 | ||
1398 | return 0; | 1399 | return 0; |
1399 | } | 1400 | } |
1400 | 1401 | ||
1401 | STATIC int | 1402 | STATIC int |
1402 | xfs_fs_fill_super( | 1403 | xfs_fs_fill_super( |
1403 | struct super_block *sb, | 1404 | struct super_block *sb, |
1404 | void *data, | 1405 | void *data, |
1405 | int silent) | 1406 | int silent) |
1406 | { | 1407 | { |
1407 | struct inode *root; | 1408 | struct inode *root; |
1408 | struct xfs_mount *mp = NULL; | 1409 | struct xfs_mount *mp = NULL; |
1409 | int flags = 0, error = ENOMEM; | 1410 | int flags = 0, error = ENOMEM; |
1410 | 1411 | ||
1411 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); | 1412 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); |
1412 | if (!mp) | 1413 | if (!mp) |
1413 | goto out; | 1414 | goto out; |
1414 | 1415 | ||
1415 | spin_lock_init(&mp->m_sb_lock); | 1416 | spin_lock_init(&mp->m_sb_lock); |
1416 | mutex_init(&mp->m_growlock); | 1417 | mutex_init(&mp->m_growlock); |
1417 | atomic_set(&mp->m_active_trans, 0); | 1418 | atomic_set(&mp->m_active_trans, 0); |
1418 | INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); | 1419 | INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); |
1419 | INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); | 1420 | INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); |
1420 | 1421 | ||
1421 | mp->m_super = sb; | 1422 | mp->m_super = sb; |
1422 | sb->s_fs_info = mp; | 1423 | sb->s_fs_info = mp; |
1423 | 1424 | ||
1424 | error = xfs_parseargs(mp, (char *)data); | 1425 | error = xfs_parseargs(mp, (char *)data); |
1425 | if (error) | 1426 | if (error) |
1426 | goto out_free_fsname; | 1427 | goto out_free_fsname; |
1427 | 1428 | ||
1428 | sb_min_blocksize(sb, BBSIZE); | 1429 | sb_min_blocksize(sb, BBSIZE); |
1429 | sb->s_xattr = xfs_xattr_handlers; | 1430 | sb->s_xattr = xfs_xattr_handlers; |
1430 | sb->s_export_op = &xfs_export_operations; | 1431 | sb->s_export_op = &xfs_export_operations; |
1431 | #ifdef CONFIG_XFS_QUOTA | 1432 | #ifdef CONFIG_XFS_QUOTA |
1432 | sb->s_qcop = &xfs_quotactl_operations; | 1433 | sb->s_qcop = &xfs_quotactl_operations; |
1433 | #endif | 1434 | #endif |
1434 | sb->s_op = &xfs_super_operations; | 1435 | sb->s_op = &xfs_super_operations; |
1435 | 1436 | ||
1436 | if (silent) | 1437 | if (silent) |
1437 | flags |= XFS_MFSI_QUIET; | 1438 | flags |= XFS_MFSI_QUIET; |
1438 | 1439 | ||
1439 | error = xfs_open_devices(mp); | 1440 | error = xfs_open_devices(mp); |
1440 | if (error) | 1441 | if (error) |
1441 | goto out_free_fsname; | 1442 | goto out_free_fsname; |
1442 | 1443 | ||
1443 | error = xfs_init_mount_workqueues(mp); | 1444 | error = xfs_init_mount_workqueues(mp); |
1444 | if (error) | 1445 | if (error) |
1445 | goto out_close_devices; | 1446 | goto out_close_devices; |
1446 | 1447 | ||
1447 | error = xfs_icsb_init_counters(mp); | 1448 | error = xfs_icsb_init_counters(mp); |
1448 | if (error) | 1449 | if (error) |
1449 | goto out_destroy_workqueues; | 1450 | goto out_destroy_workqueues; |
1450 | 1451 | ||
1451 | error = xfs_readsb(mp, flags); | 1452 | error = xfs_readsb(mp, flags); |
1452 | if (error) | 1453 | if (error) |
1453 | goto out_destroy_counters; | 1454 | goto out_destroy_counters; |
1454 | 1455 | ||
1455 | error = xfs_finish_flags(mp); | 1456 | error = xfs_finish_flags(mp); |
1456 | if (error) | 1457 | if (error) |
1457 | goto out_free_sb; | 1458 | goto out_free_sb; |
1458 | 1459 | ||
1459 | error = xfs_setup_devices(mp); | 1460 | error = xfs_setup_devices(mp); |
1460 | if (error) | 1461 | if (error) |
1461 | goto out_free_sb; | 1462 | goto out_free_sb; |
1462 | 1463 | ||
1463 | error = xfs_filestream_mount(mp); | 1464 | error = xfs_filestream_mount(mp); |
1464 | if (error) | 1465 | if (error) |
1465 | goto out_free_sb; | 1466 | goto out_free_sb; |
1466 | 1467 | ||
1467 | /* | 1468 | /* |
1468 | * we must configure the block size in the superblock before we run the | 1469 | * we must configure the block size in the superblock before we run the |
1469 | * full mount process as the mount process can lookup and cache inodes. | 1470 | * full mount process as the mount process can lookup and cache inodes. |
1470 | */ | 1471 | */ |
1471 | sb->s_magic = XFS_SB_MAGIC; | 1472 | sb->s_magic = XFS_SB_MAGIC; |
1472 | sb->s_blocksize = mp->m_sb.sb_blocksize; | 1473 | sb->s_blocksize = mp->m_sb.sb_blocksize; |
1473 | sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; | 1474 | sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; |
1474 | sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); | 1475 | sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); |
1475 | sb->s_max_links = XFS_MAXLINK; | 1476 | sb->s_max_links = XFS_MAXLINK; |
1476 | sb->s_time_gran = 1; | 1477 | sb->s_time_gran = 1; |
1477 | set_posix_acl_flag(sb); | 1478 | set_posix_acl_flag(sb); |
1478 | 1479 | ||
1479 | error = xfs_mountfs(mp); | 1480 | error = xfs_mountfs(mp); |
1480 | if (error) | 1481 | if (error) |
1481 | goto out_filestream_unmount; | 1482 | goto out_filestream_unmount; |
1482 | 1483 | ||
1483 | root = igrab(VFS_I(mp->m_rootip)); | 1484 | root = igrab(VFS_I(mp->m_rootip)); |
1484 | if (!root) { | 1485 | if (!root) { |
1485 | error = ENOENT; | 1486 | error = ENOENT; |
1486 | goto out_unmount; | 1487 | goto out_unmount; |
1487 | } | 1488 | } |
1488 | if (is_bad_inode(root)) { | 1489 | if (is_bad_inode(root)) { |
1489 | error = EINVAL; | 1490 | error = EINVAL; |
1490 | goto out_unmount; | 1491 | goto out_unmount; |
1491 | } | 1492 | } |
1492 | sb->s_root = d_make_root(root); | 1493 | sb->s_root = d_make_root(root); |
1493 | if (!sb->s_root) { | 1494 | if (!sb->s_root) { |
1494 | error = ENOMEM; | 1495 | error = ENOMEM; |
1495 | goto out_unmount; | 1496 | goto out_unmount; |
1496 | } | 1497 | } |
1497 | 1498 | ||
1498 | return 0; | 1499 | return 0; |
1499 | 1500 | ||
1500 | out_filestream_unmount: | 1501 | out_filestream_unmount: |
1501 | xfs_filestream_unmount(mp); | 1502 | xfs_filestream_unmount(mp); |
1502 | out_free_sb: | 1503 | out_free_sb: |
1503 | xfs_freesb(mp); | 1504 | xfs_freesb(mp); |
1504 | out_destroy_counters: | 1505 | out_destroy_counters: |
1505 | xfs_icsb_destroy_counters(mp); | 1506 | xfs_icsb_destroy_counters(mp); |
1506 | out_destroy_workqueues: | 1507 | out_destroy_workqueues: |
1507 | xfs_destroy_mount_workqueues(mp); | 1508 | xfs_destroy_mount_workqueues(mp); |
1508 | out_close_devices: | 1509 | out_close_devices: |
1509 | xfs_close_devices(mp); | 1510 | xfs_close_devices(mp); |
1510 | out_free_fsname: | 1511 | out_free_fsname: |
1511 | xfs_free_fsname(mp); | 1512 | xfs_free_fsname(mp); |
1512 | kfree(mp); | 1513 | kfree(mp); |
1513 | out: | 1514 | out: |
1514 | return -error; | 1515 | return -error; |
1515 | 1516 | ||
1516 | out_unmount: | 1517 | out_unmount: |
1517 | xfs_filestream_unmount(mp); | 1518 | xfs_filestream_unmount(mp); |
1518 | xfs_unmountfs(mp); | 1519 | xfs_unmountfs(mp); |
1519 | goto out_free_sb; | 1520 | goto out_free_sb; |
1520 | } | 1521 | } |
1521 | 1522 | ||
1522 | STATIC struct dentry * | 1523 | STATIC struct dentry * |
1523 | xfs_fs_mount( | 1524 | xfs_fs_mount( |
1524 | struct file_system_type *fs_type, | 1525 | struct file_system_type *fs_type, |
1525 | int flags, | 1526 | int flags, |
1526 | const char *dev_name, | 1527 | const char *dev_name, |
1527 | void *data) | 1528 | void *data) |
1528 | { | 1529 | { |
1529 | return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); | 1530 | return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); |
1530 | } | 1531 | } |
1531 | 1532 | ||
1532 | static int | 1533 | static int |
1533 | xfs_fs_nr_cached_objects( | 1534 | xfs_fs_nr_cached_objects( |
1534 | struct super_block *sb) | 1535 | struct super_block *sb) |
1535 | { | 1536 | { |
1536 | return xfs_reclaim_inodes_count(XFS_M(sb)); | 1537 | return xfs_reclaim_inodes_count(XFS_M(sb)); |
1537 | } | 1538 | } |
1538 | 1539 | ||
1539 | static void | 1540 | static void |
1540 | xfs_fs_free_cached_objects( | 1541 | xfs_fs_free_cached_objects( |
1541 | struct super_block *sb, | 1542 | struct super_block *sb, |
1542 | int nr_to_scan) | 1543 | int nr_to_scan) |
1543 | { | 1544 | { |
1544 | xfs_reclaim_inodes_nr(XFS_M(sb), nr_to_scan); | 1545 | xfs_reclaim_inodes_nr(XFS_M(sb), nr_to_scan); |
1545 | } | 1546 | } |
1546 | 1547 | ||
1547 | static const struct super_operations xfs_super_operations = { | 1548 | static const struct super_operations xfs_super_operations = { |
1548 | .alloc_inode = xfs_fs_alloc_inode, | 1549 | .alloc_inode = xfs_fs_alloc_inode, |
1549 | .destroy_inode = xfs_fs_destroy_inode, | 1550 | .destroy_inode = xfs_fs_destroy_inode, |
1550 | .evict_inode = xfs_fs_evict_inode, | 1551 | .evict_inode = xfs_fs_evict_inode, |
1551 | .drop_inode = xfs_fs_drop_inode, | 1552 | .drop_inode = xfs_fs_drop_inode, |
1552 | .put_super = xfs_fs_put_super, | 1553 | .put_super = xfs_fs_put_super, |
1553 | .sync_fs = xfs_fs_sync_fs, | 1554 | .sync_fs = xfs_fs_sync_fs, |
1554 | .freeze_fs = xfs_fs_freeze, | 1555 | .freeze_fs = xfs_fs_freeze, |
1555 | .unfreeze_fs = xfs_fs_unfreeze, | 1556 | .unfreeze_fs = xfs_fs_unfreeze, |
1556 | .statfs = xfs_fs_statfs, | 1557 | .statfs = xfs_fs_statfs, |
1557 | .remount_fs = xfs_fs_remount, | 1558 | .remount_fs = xfs_fs_remount, |
1558 | .show_options = xfs_fs_show_options, | 1559 | .show_options = xfs_fs_show_options, |
1559 | .nr_cached_objects = xfs_fs_nr_cached_objects, | 1560 | .nr_cached_objects = xfs_fs_nr_cached_objects, |
1560 | .free_cached_objects = xfs_fs_free_cached_objects, | 1561 | .free_cached_objects = xfs_fs_free_cached_objects, |
1561 | }; | 1562 | }; |
1562 | 1563 | ||
1563 | static struct file_system_type xfs_fs_type = { | 1564 | static struct file_system_type xfs_fs_type = { |
1564 | .owner = THIS_MODULE, | 1565 | .owner = THIS_MODULE, |
1565 | .name = "xfs", | 1566 | .name = "xfs", |
1566 | .mount = xfs_fs_mount, | 1567 | .mount = xfs_fs_mount, |
1567 | .kill_sb = kill_block_super, | 1568 | .kill_sb = kill_block_super, |
1568 | .fs_flags = FS_REQUIRES_DEV, | 1569 | .fs_flags = FS_REQUIRES_DEV, |
1569 | }; | 1570 | }; |
1570 | MODULE_ALIAS_FS("xfs"); | 1571 | MODULE_ALIAS_FS("xfs"); |
1571 | 1572 | ||
1572 | STATIC int __init | 1573 | STATIC int __init |
1573 | xfs_init_zones(void) | 1574 | xfs_init_zones(void) |
1574 | { | 1575 | { |
1575 | 1576 | ||
1576 | xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend"); | 1577 | xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend"); |
1577 | if (!xfs_ioend_zone) | 1578 | if (!xfs_ioend_zone) |
1578 | goto out; | 1579 | goto out; |
1579 | 1580 | ||
1580 | xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE, | 1581 | xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE, |
1581 | xfs_ioend_zone); | 1582 | xfs_ioend_zone); |
1582 | if (!xfs_ioend_pool) | 1583 | if (!xfs_ioend_pool) |
1583 | goto out_destroy_ioend_zone; | 1584 | goto out_destroy_ioend_zone; |
1584 | 1585 | ||
1585 | xfs_log_ticket_zone = kmem_zone_init(sizeof(xlog_ticket_t), | 1586 | xfs_log_ticket_zone = kmem_zone_init(sizeof(xlog_ticket_t), |
1586 | "xfs_log_ticket"); | 1587 | "xfs_log_ticket"); |
1587 | if (!xfs_log_ticket_zone) | 1588 | if (!xfs_log_ticket_zone) |
1588 | goto out_destroy_ioend_pool; | 1589 | goto out_destroy_ioend_pool; |
1589 | 1590 | ||
1590 | xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t), | 1591 | xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t), |
1591 | "xfs_bmap_free_item"); | 1592 | "xfs_bmap_free_item"); |
1592 | if (!xfs_bmap_free_item_zone) | 1593 | if (!xfs_bmap_free_item_zone) |
1593 | goto out_destroy_log_ticket_zone; | 1594 | goto out_destroy_log_ticket_zone; |
1594 | 1595 | ||
1595 | xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t), | 1596 | xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t), |
1596 | "xfs_btree_cur"); | 1597 | "xfs_btree_cur"); |
1597 | if (!xfs_btree_cur_zone) | 1598 | if (!xfs_btree_cur_zone) |
1598 | goto out_destroy_bmap_free_item_zone; | 1599 | goto out_destroy_bmap_free_item_zone; |
1599 | 1600 | ||
1600 | xfs_da_state_zone = kmem_zone_init(sizeof(xfs_da_state_t), | 1601 | xfs_da_state_zone = kmem_zone_init(sizeof(xfs_da_state_t), |
1601 | "xfs_da_state"); | 1602 | "xfs_da_state"); |
1602 | if (!xfs_da_state_zone) | 1603 | if (!xfs_da_state_zone) |
1603 | goto out_destroy_btree_cur_zone; | 1604 | goto out_destroy_btree_cur_zone; |
1604 | 1605 | ||
1605 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); | 1606 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); |
1606 | if (!xfs_ifork_zone) | 1607 | if (!xfs_ifork_zone) |
1607 | goto out_destroy_da_state_zone; | 1608 | goto out_destroy_da_state_zone; |
1608 | 1609 | ||
1609 | xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans"); | 1610 | xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans"); |
1610 | if (!xfs_trans_zone) | 1611 | if (!xfs_trans_zone) |
1611 | goto out_destroy_ifork_zone; | 1612 | goto out_destroy_ifork_zone; |
1612 | 1613 | ||
1613 | xfs_log_item_desc_zone = | 1614 | xfs_log_item_desc_zone = |
1614 | kmem_zone_init(sizeof(struct xfs_log_item_desc), | 1615 | kmem_zone_init(sizeof(struct xfs_log_item_desc), |
1615 | "xfs_log_item_desc"); | 1616 | "xfs_log_item_desc"); |
1616 | if (!xfs_log_item_desc_zone) | 1617 | if (!xfs_log_item_desc_zone) |
1617 | goto out_destroy_trans_zone; | 1618 | goto out_destroy_trans_zone; |
1618 | 1619 | ||
1619 | /* | 1620 | /* |
1620 | * The size of the zone allocated buf log item is the maximum | 1621 | * The size of the zone allocated buf log item is the maximum |
1621 | * size possible under XFS. This wastes a little bit of memory, | 1622 | * size possible under XFS. This wastes a little bit of memory, |
1622 | * but it is much faster. | 1623 | * but it is much faster. |
1623 | */ | 1624 | */ |
1624 | xfs_buf_item_zone = kmem_zone_init(sizeof(struct xfs_buf_log_item), | 1625 | xfs_buf_item_zone = kmem_zone_init(sizeof(struct xfs_buf_log_item), |
1625 | "xfs_buf_item"); | 1626 | "xfs_buf_item"); |
1626 | if (!xfs_buf_item_zone) | 1627 | if (!xfs_buf_item_zone) |
1627 | goto out_destroy_log_item_desc_zone; | 1628 | goto out_destroy_log_item_desc_zone; |
1628 | 1629 | ||
1629 | xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + | 1630 | xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + |
1630 | ((XFS_EFD_MAX_FAST_EXTENTS - 1) * | 1631 | ((XFS_EFD_MAX_FAST_EXTENTS - 1) * |
1631 | sizeof(xfs_extent_t))), "xfs_efd_item"); | 1632 | sizeof(xfs_extent_t))), "xfs_efd_item"); |
1632 | if (!xfs_efd_zone) | 1633 | if (!xfs_efd_zone) |
1633 | goto out_destroy_buf_item_zone; | 1634 | goto out_destroy_buf_item_zone; |
1634 | 1635 | ||
1635 | xfs_efi_zone = kmem_zone_init((sizeof(xfs_efi_log_item_t) + | 1636 | xfs_efi_zone = kmem_zone_init((sizeof(xfs_efi_log_item_t) + |
1636 | ((XFS_EFI_MAX_FAST_EXTENTS - 1) * | 1637 | ((XFS_EFI_MAX_FAST_EXTENTS - 1) * |
1637 | sizeof(xfs_extent_t))), "xfs_efi_item"); | 1638 | sizeof(xfs_extent_t))), "xfs_efi_item"); |
1638 | if (!xfs_efi_zone) | 1639 | if (!xfs_efi_zone) |
1639 | goto out_destroy_efd_zone; | 1640 | goto out_destroy_efd_zone; |
1640 | 1641 | ||
1641 | xfs_inode_zone = | 1642 | xfs_inode_zone = |
1642 | kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", | 1643 | kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", |
1643 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD, | 1644 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD, |
1644 | xfs_fs_inode_init_once); | 1645 | xfs_fs_inode_init_once); |
1645 | if (!xfs_inode_zone) | 1646 | if (!xfs_inode_zone) |
1646 | goto out_destroy_efi_zone; | 1647 | goto out_destroy_efi_zone; |
1647 | 1648 | ||
1648 | xfs_ili_zone = | 1649 | xfs_ili_zone = |
1649 | kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", | 1650 | kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", |
1650 | KM_ZONE_SPREAD, NULL); | 1651 | KM_ZONE_SPREAD, NULL); |
1651 | if (!xfs_ili_zone) | 1652 | if (!xfs_ili_zone) |
1652 | goto out_destroy_inode_zone; | 1653 | goto out_destroy_inode_zone; |
1654 | xfs_icreate_zone = kmem_zone_init(sizeof(struct xfs_icreate_item), | ||
1655 | "xfs_icr"); | ||
1656 | if (!xfs_icreate_zone) | ||
1657 | goto out_destroy_ili_zone; | ||
1653 | 1658 | ||
1654 | return 0; | 1659 | return 0; |
1655 | 1660 | ||
1661 | out_destroy_ili_zone: | ||
1662 | kmem_zone_destroy(xfs_ili_zone); | ||
1656 | out_destroy_inode_zone: | 1663 | out_destroy_inode_zone: |
1657 | kmem_zone_destroy(xfs_inode_zone); | 1664 | kmem_zone_destroy(xfs_inode_zone); |
1658 | out_destroy_efi_zone: | 1665 | out_destroy_efi_zone: |
1659 | kmem_zone_destroy(xfs_efi_zone); | 1666 | kmem_zone_destroy(xfs_efi_zone); |
1660 | out_destroy_efd_zone: | 1667 | out_destroy_efd_zone: |
1661 | kmem_zone_destroy(xfs_efd_zone); | 1668 | kmem_zone_destroy(xfs_efd_zone); |
1662 | out_destroy_buf_item_zone: | 1669 | out_destroy_buf_item_zone: |
1663 | kmem_zone_destroy(xfs_buf_item_zone); | 1670 | kmem_zone_destroy(xfs_buf_item_zone); |
1664 | out_destroy_log_item_desc_zone: | 1671 | out_destroy_log_item_desc_zone: |
1665 | kmem_zone_destroy(xfs_log_item_desc_zone); | 1672 | kmem_zone_destroy(xfs_log_item_desc_zone); |
1666 | out_destroy_trans_zone: | 1673 | out_destroy_trans_zone: |
1667 | kmem_zone_destroy(xfs_trans_zone); | 1674 | kmem_zone_destroy(xfs_trans_zone); |
1668 | out_destroy_ifork_zone: | 1675 | out_destroy_ifork_zone: |
1669 | kmem_zone_destroy(xfs_ifork_zone); | 1676 | kmem_zone_destroy(xfs_ifork_zone); |
1670 | out_destroy_da_state_zone: | 1677 | out_destroy_da_state_zone: |
1671 | kmem_zone_destroy(xfs_da_state_zone); | 1678 | kmem_zone_destroy(xfs_da_state_zone); |
1672 | out_destroy_btree_cur_zone: | 1679 | out_destroy_btree_cur_zone: |
1673 | kmem_zone_destroy(xfs_btree_cur_zone); | 1680 | kmem_zone_destroy(xfs_btree_cur_zone); |
1674 | out_destroy_bmap_free_item_zone: | 1681 | out_destroy_bmap_free_item_zone: |
1675 | kmem_zone_destroy(xfs_bmap_free_item_zone); | 1682 | kmem_zone_destroy(xfs_bmap_free_item_zone); |
1676 | out_destroy_log_ticket_zone: | 1683 | out_destroy_log_ticket_zone: |
1677 | kmem_zone_destroy(xfs_log_ticket_zone); | 1684 | kmem_zone_destroy(xfs_log_ticket_zone); |
1678 | out_destroy_ioend_pool: | 1685 | out_destroy_ioend_pool: |
1679 | mempool_destroy(xfs_ioend_pool); | 1686 | mempool_destroy(xfs_ioend_pool); |
1680 | out_destroy_ioend_zone: | 1687 | out_destroy_ioend_zone: |
1681 | kmem_zone_destroy(xfs_ioend_zone); | 1688 | kmem_zone_destroy(xfs_ioend_zone); |
1682 | out: | 1689 | out: |
1683 | return -ENOMEM; | 1690 | return -ENOMEM; |
1684 | } | 1691 | } |
1685 | 1692 | ||
1686 | STATIC void | 1693 | STATIC void |
1687 | xfs_destroy_zones(void) | 1694 | xfs_destroy_zones(void) |
1688 | { | 1695 | { |
1689 | /* | 1696 | /* |
1690 | * Make sure all delayed rcu free are flushed before we | 1697 | * Make sure all delayed rcu free are flushed before we |
1691 | * destroy caches. | 1698 | * destroy caches. |
1692 | */ | 1699 | */ |
1693 | rcu_barrier(); | 1700 | rcu_barrier(); |
1701 | kmem_zone_destroy(xfs_icreate_zone); | ||
1694 | kmem_zone_destroy(xfs_ili_zone); | 1702 | kmem_zone_destroy(xfs_ili_zone); |
1695 | kmem_zone_destroy(xfs_inode_zone); | 1703 | kmem_zone_destroy(xfs_inode_zone); |
1696 | kmem_zone_destroy(xfs_efi_zone); | 1704 | kmem_zone_destroy(xfs_efi_zone); |
1697 | kmem_zone_destroy(xfs_efd_zone); | 1705 | kmem_zone_destroy(xfs_efd_zone); |
1698 | kmem_zone_destroy(xfs_buf_item_zone); | 1706 | kmem_zone_destroy(xfs_buf_item_zone); |
1699 | kmem_zone_destroy(xfs_log_item_desc_zone); | 1707 | kmem_zone_destroy(xfs_log_item_desc_zone); |
1700 | kmem_zone_destroy(xfs_trans_zone); | 1708 | kmem_zone_destroy(xfs_trans_zone); |
1701 | kmem_zone_destroy(xfs_ifork_zone); | 1709 | kmem_zone_destroy(xfs_ifork_zone); |
1702 | kmem_zone_destroy(xfs_da_state_zone); | 1710 | kmem_zone_destroy(xfs_da_state_zone); |
1703 | kmem_zone_destroy(xfs_btree_cur_zone); | 1711 | kmem_zone_destroy(xfs_btree_cur_zone); |
1704 | kmem_zone_destroy(xfs_bmap_free_item_zone); | 1712 | kmem_zone_destroy(xfs_bmap_free_item_zone); |
1705 | kmem_zone_destroy(xfs_log_ticket_zone); | 1713 | kmem_zone_destroy(xfs_log_ticket_zone); |
1706 | mempool_destroy(xfs_ioend_pool); | 1714 | mempool_destroy(xfs_ioend_pool); |
1707 | kmem_zone_destroy(xfs_ioend_zone); | 1715 | kmem_zone_destroy(xfs_ioend_zone); |
1708 | 1716 | ||
1709 | } | 1717 | } |
1710 | 1718 | ||
1711 | STATIC int __init | 1719 | STATIC int __init |
1712 | xfs_init_workqueues(void) | 1720 | xfs_init_workqueues(void) |
1713 | { | 1721 | { |
1714 | /* | 1722 | /* |
1715 | * The allocation workqueue can be used in memory reclaim situations | 1723 | * The allocation workqueue can be used in memory reclaim situations |
1716 | * (writepage path), and parallelism is only limited by the number of | 1724 | * (writepage path), and parallelism is only limited by the number of |
1717 | * AGs in all the filesystems mounted. Hence use the default large | 1725 | * AGs in all the filesystems mounted. Hence use the default large |
1718 | * max_active value for this workqueue. | 1726 | * max_active value for this workqueue. |
1719 | */ | 1727 | */ |
1720 | xfs_alloc_wq = alloc_workqueue("xfsalloc", WQ_MEM_RECLAIM, 0); | 1728 | xfs_alloc_wq = alloc_workqueue("xfsalloc", WQ_MEM_RECLAIM, 0); |
1721 | if (!xfs_alloc_wq) | 1729 | if (!xfs_alloc_wq) |
1722 | return -ENOMEM; | 1730 | return -ENOMEM; |
1723 | 1731 | ||
1724 | return 0; | 1732 | return 0; |
1725 | } | 1733 | } |
1726 | 1734 | ||
1727 | STATIC void | 1735 | STATIC void |
1728 | xfs_destroy_workqueues(void) | 1736 | xfs_destroy_workqueues(void) |
1729 | { | 1737 | { |
1730 | destroy_workqueue(xfs_alloc_wq); | 1738 | destroy_workqueue(xfs_alloc_wq); |
1731 | } | 1739 | } |
1732 | 1740 | ||
1733 | STATIC int __init | 1741 | STATIC int __init |
1734 | init_xfs_fs(void) | 1742 | init_xfs_fs(void) |
1735 | { | 1743 | { |
1736 | int error; | 1744 | int error; |
1737 | 1745 | ||
1738 | printk(KERN_INFO XFS_VERSION_STRING " with " | 1746 | printk(KERN_INFO XFS_VERSION_STRING " with " |
1739 | XFS_BUILD_OPTIONS " enabled\n"); | 1747 | XFS_BUILD_OPTIONS " enabled\n"); |
1740 | 1748 | ||
1741 | xfs_dir_startup(); | 1749 | xfs_dir_startup(); |
1742 | 1750 | ||
1743 | error = xfs_init_zones(); | 1751 | error = xfs_init_zones(); |
1744 | if (error) | 1752 | if (error) |
1745 | goto out; | 1753 | goto out; |
1746 | 1754 | ||
1747 | error = xfs_init_workqueues(); | 1755 | error = xfs_init_workqueues(); |
1748 | if (error) | 1756 | if (error) |
1749 | goto out_destroy_zones; | 1757 | goto out_destroy_zones; |
1750 | 1758 | ||
1751 | error = xfs_mru_cache_init(); | 1759 | error = xfs_mru_cache_init(); |
1752 | if (error) | 1760 | if (error) |
1753 | goto out_destroy_wq; | 1761 | goto out_destroy_wq; |
1754 | 1762 | ||
1755 | error = xfs_filestream_init(); | 1763 | error = xfs_filestream_init(); |
1756 | if (error) | 1764 | if (error) |
1757 | goto out_mru_cache_uninit; | 1765 | goto out_mru_cache_uninit; |
1758 | 1766 | ||
1759 | error = xfs_buf_init(); | 1767 | error = xfs_buf_init(); |
1760 | if (error) | 1768 | if (error) |
1761 | goto out_filestream_uninit; | 1769 | goto out_filestream_uninit; |
1762 | 1770 | ||
1763 | error = xfs_init_procfs(); | 1771 | error = xfs_init_procfs(); |
1764 | if (error) | 1772 | if (error) |
1765 | goto out_buf_terminate; | 1773 | goto out_buf_terminate; |
1766 | 1774 | ||
1767 | error = xfs_sysctl_register(); | 1775 | error = xfs_sysctl_register(); |
1768 | if (error) | 1776 | if (error) |
1769 | goto out_cleanup_procfs; | 1777 | goto out_cleanup_procfs; |
1770 | 1778 | ||
1771 | error = xfs_qm_init(); | 1779 | error = xfs_qm_init(); |
1772 | if (error) | 1780 | if (error) |
1773 | goto out_sysctl_unregister; | 1781 | goto out_sysctl_unregister; |
1774 | 1782 | ||
1775 | error = register_filesystem(&xfs_fs_type); | 1783 | error = register_filesystem(&xfs_fs_type); |
1776 | if (error) | 1784 | if (error) |
1777 | goto out_qm_exit; | 1785 | goto out_qm_exit; |
1778 | return 0; | 1786 | return 0; |
1779 | 1787 | ||
1780 | out_qm_exit: | 1788 | out_qm_exit: |
1781 | xfs_qm_exit(); | 1789 | xfs_qm_exit(); |
1782 | out_sysctl_unregister: | 1790 | out_sysctl_unregister: |
1783 | xfs_sysctl_unregister(); | 1791 | xfs_sysctl_unregister(); |
1784 | out_cleanup_procfs: | 1792 | out_cleanup_procfs: |
1785 | xfs_cleanup_procfs(); | 1793 | xfs_cleanup_procfs(); |
1786 | out_buf_terminate: | 1794 | out_buf_terminate: |
1787 | xfs_buf_terminate(); | 1795 | xfs_buf_terminate(); |
1788 | out_filestream_uninit: | 1796 | out_filestream_uninit: |
1789 | xfs_filestream_uninit(); | 1797 | xfs_filestream_uninit(); |
1790 | out_mru_cache_uninit: | 1798 | out_mru_cache_uninit: |
1791 | xfs_mru_cache_uninit(); | 1799 | xfs_mru_cache_uninit(); |
1792 | out_destroy_wq: | 1800 | out_destroy_wq: |
1793 | xfs_destroy_workqueues(); | 1801 | xfs_destroy_workqueues(); |
1794 | out_destroy_zones: | 1802 | out_destroy_zones: |
1795 | xfs_destroy_zones(); | 1803 | xfs_destroy_zones(); |
1796 | out: | 1804 | out: |
1797 | return error; | 1805 | return error; |
1798 | } | 1806 | } |
1799 | 1807 | ||
1800 | STATIC void __exit | 1808 | STATIC void __exit |
1801 | exit_xfs_fs(void) | 1809 | exit_xfs_fs(void) |
1802 | { | 1810 | { |
1803 | xfs_qm_exit(); | 1811 | xfs_qm_exit(); |
1804 | unregister_filesystem(&xfs_fs_type); | 1812 | unregister_filesystem(&xfs_fs_type); |
1805 | xfs_sysctl_unregister(); | 1813 | xfs_sysctl_unregister(); |
1806 | xfs_cleanup_procfs(); | 1814 | xfs_cleanup_procfs(); |
1807 | xfs_buf_terminate(); | 1815 | xfs_buf_terminate(); |
1808 | xfs_filestream_uninit(); | 1816 | xfs_filestream_uninit(); |
1809 | xfs_mru_cache_uninit(); | 1817 | xfs_mru_cache_uninit(); |
1810 | xfs_destroy_workqueues(); | 1818 | xfs_destroy_workqueues(); |
1811 | xfs_destroy_zones(); | 1819 | xfs_destroy_zones(); |
1812 | } | 1820 | } |
1813 | 1821 | ||
1814 | module_init(init_xfs_fs); | 1822 | module_init(init_xfs_fs); |
1815 | module_exit(exit_xfs_fs); | 1823 | module_exit(exit_xfs_fs); |
1816 | 1824 | ||
1817 | MODULE_AUTHOR("Silicon Graphics, Inc."); | 1825 | MODULE_AUTHOR("Silicon Graphics, Inc."); |
1818 | MODULE_DESCRIPTION(XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled"); | 1826 | MODULE_DESCRIPTION(XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled"); |
1819 | MODULE_LICENSE("GPL"); | 1827 | MODULE_LICENSE("GPL"); |
1820 | 1828 |
fs/xfs/xfs_trans.h
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 | #define XFS_LI_ICREATE 0x123f | ||
51 | 52 | ||
52 | #define XFS_LI_TYPE_DESC \ | 53 | #define XFS_LI_TYPE_DESC \ |
53 | { XFS_LI_EFI, "XFS_LI_EFI" }, \ | 54 | { XFS_LI_EFI, "XFS_LI_EFI" }, \ |
54 | { XFS_LI_EFD, "XFS_LI_EFD" }, \ | 55 | { XFS_LI_EFD, "XFS_LI_EFD" }, \ |
55 | { XFS_LI_IUNLINK, "XFS_LI_IUNLINK" }, \ | 56 | { XFS_LI_IUNLINK, "XFS_LI_IUNLINK" }, \ |
56 | { XFS_LI_INODE, "XFS_LI_INODE" }, \ | 57 | { XFS_LI_INODE, "XFS_LI_INODE" }, \ |
57 | { XFS_LI_BUF, "XFS_LI_BUF" }, \ | 58 | { XFS_LI_BUF, "XFS_LI_BUF" }, \ |
58 | { XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \ | 59 | { XFS_LI_DQUOT, "XFS_LI_DQUOT" }, \ |
59 | { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" } | 60 | { XFS_LI_QUOTAOFF, "XFS_LI_QUOTAOFF" } |
60 | 61 | ||
61 | /* | 62 | /* |
62 | * Transaction types. Used to distinguish types of buffers. | 63 | * Transaction types. Used to distinguish types of buffers. |
63 | */ | 64 | */ |
64 | #define XFS_TRANS_SETATTR_NOT_SIZE 1 | 65 | #define XFS_TRANS_SETATTR_NOT_SIZE 1 |
65 | #define XFS_TRANS_SETATTR_SIZE 2 | 66 | #define XFS_TRANS_SETATTR_SIZE 2 |
66 | #define XFS_TRANS_INACTIVE 3 | 67 | #define XFS_TRANS_INACTIVE 3 |
67 | #define XFS_TRANS_CREATE 4 | 68 | #define XFS_TRANS_CREATE 4 |
68 | #define XFS_TRANS_CREATE_TRUNC 5 | 69 | #define XFS_TRANS_CREATE_TRUNC 5 |
69 | #define XFS_TRANS_TRUNCATE_FILE 6 | 70 | #define XFS_TRANS_TRUNCATE_FILE 6 |
70 | #define XFS_TRANS_REMOVE 7 | 71 | #define XFS_TRANS_REMOVE 7 |
71 | #define XFS_TRANS_LINK 8 | 72 | #define XFS_TRANS_LINK 8 |
72 | #define XFS_TRANS_RENAME 9 | 73 | #define XFS_TRANS_RENAME 9 |
73 | #define XFS_TRANS_MKDIR 10 | 74 | #define XFS_TRANS_MKDIR 10 |
74 | #define XFS_TRANS_RMDIR 11 | 75 | #define XFS_TRANS_RMDIR 11 |
75 | #define XFS_TRANS_SYMLINK 12 | 76 | #define XFS_TRANS_SYMLINK 12 |
76 | #define XFS_TRANS_SET_DMATTRS 13 | 77 | #define XFS_TRANS_SET_DMATTRS 13 |
77 | #define XFS_TRANS_GROWFS 14 | 78 | #define XFS_TRANS_GROWFS 14 |
78 | #define XFS_TRANS_STRAT_WRITE 15 | 79 | #define XFS_TRANS_STRAT_WRITE 15 |
79 | #define XFS_TRANS_DIOSTRAT 16 | 80 | #define XFS_TRANS_DIOSTRAT 16 |
80 | /* 17 was XFS_TRANS_WRITE_SYNC */ | 81 | /* 17 was XFS_TRANS_WRITE_SYNC */ |
81 | #define XFS_TRANS_WRITEID 18 | 82 | #define XFS_TRANS_WRITEID 18 |
82 | #define XFS_TRANS_ADDAFORK 19 | 83 | #define XFS_TRANS_ADDAFORK 19 |
83 | #define XFS_TRANS_ATTRINVAL 20 | 84 | #define XFS_TRANS_ATTRINVAL 20 |
84 | #define XFS_TRANS_ATRUNCATE 21 | 85 | #define XFS_TRANS_ATRUNCATE 21 |
85 | #define XFS_TRANS_ATTR_SET 22 | 86 | #define XFS_TRANS_ATTR_SET 22 |
86 | #define XFS_TRANS_ATTR_RM 23 | 87 | #define XFS_TRANS_ATTR_RM 23 |
87 | #define XFS_TRANS_ATTR_FLAG 24 | 88 | #define XFS_TRANS_ATTR_FLAG 24 |
88 | #define XFS_TRANS_CLEAR_AGI_BUCKET 25 | 89 | #define XFS_TRANS_CLEAR_AGI_BUCKET 25 |
89 | #define XFS_TRANS_QM_SBCHANGE 26 | 90 | #define XFS_TRANS_QM_SBCHANGE 26 |
90 | /* | 91 | /* |
91 | * Dummy entries since we use the transaction type to index into the | 92 | * Dummy entries since we use the transaction type to index into the |
92 | * trans_type[] in xlog_recover_print_trans_head() | 93 | * trans_type[] in xlog_recover_print_trans_head() |
93 | */ | 94 | */ |
94 | #define XFS_TRANS_DUMMY1 27 | 95 | #define XFS_TRANS_DUMMY1 27 |
95 | #define XFS_TRANS_DUMMY2 28 | 96 | #define XFS_TRANS_DUMMY2 28 |
96 | #define XFS_TRANS_QM_QUOTAOFF 29 | 97 | #define XFS_TRANS_QM_QUOTAOFF 29 |
97 | #define XFS_TRANS_QM_DQALLOC 30 | 98 | #define XFS_TRANS_QM_DQALLOC 30 |
98 | #define XFS_TRANS_QM_SETQLIM 31 | 99 | #define XFS_TRANS_QM_SETQLIM 31 |
99 | #define XFS_TRANS_QM_DQCLUSTER 32 | 100 | #define XFS_TRANS_QM_DQCLUSTER 32 |
100 | #define XFS_TRANS_QM_QINOCREATE 33 | 101 | #define XFS_TRANS_QM_QINOCREATE 33 |
101 | #define XFS_TRANS_QM_QUOTAOFF_END 34 | 102 | #define XFS_TRANS_QM_QUOTAOFF_END 34 |
102 | #define XFS_TRANS_SB_UNIT 35 | 103 | #define XFS_TRANS_SB_UNIT 35 |
103 | #define XFS_TRANS_FSYNC_TS 36 | 104 | #define XFS_TRANS_FSYNC_TS 36 |
104 | #define XFS_TRANS_GROWFSRT_ALLOC 37 | 105 | #define XFS_TRANS_GROWFSRT_ALLOC 37 |
105 | #define XFS_TRANS_GROWFSRT_ZERO 38 | 106 | #define XFS_TRANS_GROWFSRT_ZERO 38 |
106 | #define XFS_TRANS_GROWFSRT_FREE 39 | 107 | #define XFS_TRANS_GROWFSRT_FREE 39 |
107 | #define XFS_TRANS_SWAPEXT 40 | 108 | #define XFS_TRANS_SWAPEXT 40 |
108 | #define XFS_TRANS_SB_COUNT 41 | 109 | #define XFS_TRANS_SB_COUNT 41 |
109 | #define XFS_TRANS_CHECKPOINT 42 | 110 | #define XFS_TRANS_CHECKPOINT 42 |
110 | #define XFS_TRANS_TYPE_MAX 42 | 111 | #define XFS_TRANS_ICREATE 43 |
112 | #define XFS_TRANS_TYPE_MAX 43 | ||
111 | /* new transaction types need to be reflected in xfs_logprint(8) */ | 113 | /* new transaction types need to be reflected in xfs_logprint(8) */ |
112 | 114 | ||
113 | #define XFS_TRANS_TYPES \ | 115 | #define XFS_TRANS_TYPES \ |
114 | { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \ | 116 | { XFS_TRANS_SETATTR_NOT_SIZE, "SETATTR_NOT_SIZE" }, \ |
115 | { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ | 117 | { XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \ |
116 | { XFS_TRANS_INACTIVE, "INACTIVE" }, \ | 118 | { XFS_TRANS_INACTIVE, "INACTIVE" }, \ |
117 | { XFS_TRANS_CREATE, "CREATE" }, \ | 119 | { XFS_TRANS_CREATE, "CREATE" }, \ |
118 | { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ | 120 | { XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \ |
119 | { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ | 121 | { XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \ |
120 | { XFS_TRANS_REMOVE, "REMOVE" }, \ | 122 | { XFS_TRANS_REMOVE, "REMOVE" }, \ |
121 | { XFS_TRANS_LINK, "LINK" }, \ | 123 | { XFS_TRANS_LINK, "LINK" }, \ |
122 | { XFS_TRANS_RENAME, "RENAME" }, \ | 124 | { XFS_TRANS_RENAME, "RENAME" }, \ |
123 | { XFS_TRANS_MKDIR, "MKDIR" }, \ | 125 | { XFS_TRANS_MKDIR, "MKDIR" }, \ |
124 | { XFS_TRANS_RMDIR, "RMDIR" }, \ | 126 | { XFS_TRANS_RMDIR, "RMDIR" }, \ |
125 | { XFS_TRANS_SYMLINK, "SYMLINK" }, \ | 127 | { XFS_TRANS_SYMLINK, "SYMLINK" }, \ |
126 | { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \ | 128 | { XFS_TRANS_SET_DMATTRS, "SET_DMATTRS" }, \ |
127 | { XFS_TRANS_GROWFS, "GROWFS" }, \ | 129 | { XFS_TRANS_GROWFS, "GROWFS" }, \ |
128 | { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \ | 130 | { XFS_TRANS_STRAT_WRITE, "STRAT_WRITE" }, \ |
129 | { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \ | 131 | { XFS_TRANS_DIOSTRAT, "DIOSTRAT" }, \ |
130 | { XFS_TRANS_WRITEID, "WRITEID" }, \ | 132 | { XFS_TRANS_WRITEID, "WRITEID" }, \ |
131 | { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \ | 133 | { XFS_TRANS_ADDAFORK, "ADDAFORK" }, \ |
132 | { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \ | 134 | { XFS_TRANS_ATTRINVAL, "ATTRINVAL" }, \ |
133 | { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \ | 135 | { XFS_TRANS_ATRUNCATE, "ATRUNCATE" }, \ |
134 | { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \ | 136 | { XFS_TRANS_ATTR_SET, "ATTR_SET" }, \ |
135 | { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ | 137 | { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ |
136 | { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ | 138 | { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ |
137 | { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ | 139 | { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ |
138 | { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ | 140 | { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ |
139 | { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ | 141 | { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ |
140 | { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ | 142 | { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ |
141 | { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ | 143 | { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ |
142 | { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ | 144 | { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ |
143 | { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ | 145 | { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ |
144 | { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ | 146 | { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ |
145 | { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ | 147 | { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ |
146 | { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ | 148 | { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ |
147 | { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ | 149 | { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ |
148 | { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ | 150 | { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ |
149 | { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ | 151 | { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ |
150 | { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ | 152 | { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ |
151 | { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ | 153 | { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ |
152 | { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ | 154 | { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ |
153 | { XFS_TRANS_DUMMY1, "DUMMY1" }, \ | 155 | { XFS_TRANS_DUMMY1, "DUMMY1" }, \ |
154 | { XFS_TRANS_DUMMY2, "DUMMY2" }, \ | 156 | { XFS_TRANS_DUMMY2, "DUMMY2" }, \ |
155 | { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" } | 157 | { XLOG_UNMOUNT_REC_TYPE, "UNMOUNT" } |
156 | 158 | ||
157 | /* | 159 | /* |
158 | * This structure is used to track log items associated with | 160 | * This structure is used to track log items associated with |
159 | * a transaction. It points to the log item and keeps some | 161 | * a transaction. It points to the log item and keeps some |
160 | * flags to track the state of the log item. It also tracks | 162 | * flags to track the state of the log item. It also tracks |
161 | * the amount of space needed to log the item it describes | 163 | * the amount of space needed to log the item it describes |
162 | * once we get to commit processing (see xfs_trans_commit()). | 164 | * once we get to commit processing (see xfs_trans_commit()). |
163 | */ | 165 | */ |
164 | struct xfs_log_item_desc { | 166 | struct xfs_log_item_desc { |
165 | struct xfs_log_item *lid_item; | 167 | struct xfs_log_item *lid_item; |
166 | struct list_head lid_trans; | 168 | struct list_head lid_trans; |
167 | unsigned char lid_flags; | 169 | unsigned char lid_flags; |
168 | }; | 170 | }; |
169 | 171 | ||
170 | #define XFS_LID_DIRTY 0x1 | 172 | #define XFS_LID_DIRTY 0x1 |
171 | 173 | ||
172 | #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ | 174 | #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ |
173 | /* | 175 | /* |
174 | * Values for t_flags. | 176 | * Values for t_flags. |
175 | */ | 177 | */ |
176 | #define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ | 178 | #define XFS_TRANS_DIRTY 0x01 /* something needs to be logged */ |
177 | #define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ | 179 | #define XFS_TRANS_SB_DIRTY 0x02 /* superblock is modified */ |
178 | #define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ | 180 | #define XFS_TRANS_PERM_LOG_RES 0x04 /* xact took a permanent log res */ |
179 | #define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ | 181 | #define XFS_TRANS_SYNC 0x08 /* make commit synchronous */ |
180 | #define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */ | 182 | #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 */ | 183 | #define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */ |
182 | #define XFS_TRANS_FREEZE_PROT 0x40 /* Transaction has elevated writer | 184 | #define XFS_TRANS_FREEZE_PROT 0x40 /* Transaction has elevated writer |
183 | count in superblock */ | 185 | count in superblock */ |
184 | 186 | ||
185 | /* | 187 | /* |
186 | * Values for call flags parameter. | 188 | * Values for call flags parameter. |
187 | */ | 189 | */ |
188 | #define XFS_TRANS_RELEASE_LOG_RES 0x4 | 190 | #define XFS_TRANS_RELEASE_LOG_RES 0x4 |
189 | #define XFS_TRANS_ABORT 0x8 | 191 | #define XFS_TRANS_ABORT 0x8 |
190 | 192 | ||
191 | /* | 193 | /* |
192 | * Field values for xfs_trans_mod_sb. | 194 | * Field values for xfs_trans_mod_sb. |
193 | */ | 195 | */ |
194 | #define XFS_TRANS_SB_ICOUNT 0x00000001 | 196 | #define XFS_TRANS_SB_ICOUNT 0x00000001 |
195 | #define XFS_TRANS_SB_IFREE 0x00000002 | 197 | #define XFS_TRANS_SB_IFREE 0x00000002 |
196 | #define XFS_TRANS_SB_FDBLOCKS 0x00000004 | 198 | #define XFS_TRANS_SB_FDBLOCKS 0x00000004 |
197 | #define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008 | 199 | #define XFS_TRANS_SB_RES_FDBLOCKS 0x00000008 |
198 | #define XFS_TRANS_SB_FREXTENTS 0x00000010 | 200 | #define XFS_TRANS_SB_FREXTENTS 0x00000010 |
199 | #define XFS_TRANS_SB_RES_FREXTENTS 0x00000020 | 201 | #define XFS_TRANS_SB_RES_FREXTENTS 0x00000020 |
200 | #define XFS_TRANS_SB_DBLOCKS 0x00000040 | 202 | #define XFS_TRANS_SB_DBLOCKS 0x00000040 |
201 | #define XFS_TRANS_SB_AGCOUNT 0x00000080 | 203 | #define XFS_TRANS_SB_AGCOUNT 0x00000080 |
202 | #define XFS_TRANS_SB_IMAXPCT 0x00000100 | 204 | #define XFS_TRANS_SB_IMAXPCT 0x00000100 |
203 | #define XFS_TRANS_SB_REXTSIZE 0x00000200 | 205 | #define XFS_TRANS_SB_REXTSIZE 0x00000200 |
204 | #define XFS_TRANS_SB_RBMBLOCKS 0x00000400 | 206 | #define XFS_TRANS_SB_RBMBLOCKS 0x00000400 |
205 | #define XFS_TRANS_SB_RBLOCKS 0x00000800 | 207 | #define XFS_TRANS_SB_RBLOCKS 0x00000800 |
206 | #define XFS_TRANS_SB_REXTENTS 0x00001000 | 208 | #define XFS_TRANS_SB_REXTENTS 0x00001000 |
207 | #define XFS_TRANS_SB_REXTSLOG 0x00002000 | 209 | #define XFS_TRANS_SB_REXTSLOG 0x00002000 |
208 | 210 | ||
209 | 211 | ||
210 | /* | 212 | /* |
211 | * Per-extent log reservation for the allocation btree changes | 213 | * Per-extent log reservation for the allocation btree changes |
212 | * involved in freeing or allocating an extent. | 214 | * involved in freeing or allocating an extent. |
213 | * 2 trees * (2 blocks/level * max depth - 1) | 215 | * 2 trees * (2 blocks/level * max depth - 1) |
214 | */ | 216 | */ |
215 | #define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ | 217 | #define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ |
216 | ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1))) | 218 | ((nx) * (2 * (2 * XFS_AG_MAXLEVELS(mp) - 1))) |
217 | 219 | ||
218 | /* | 220 | /* |
219 | * Per-directory log reservation for any directory change. | 221 | * Per-directory log reservation for any directory change. |
220 | * dir blocks: (1 btree block per level + data block + free block) | 222 | * dir blocks: (1 btree block per level + data block + free block) |
221 | * bmap btree: (levels + 2) * max depth | 223 | * bmap btree: (levels + 2) * max depth |
222 | * 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 |
223 | * size, so account for that in the DAENTER macros. | 225 | * size, so account for that in the DAENTER macros. |
224 | */ | 226 | */ |
225 | #define XFS_DIROP_LOG_COUNT(mp) \ | 227 | #define XFS_DIROP_LOG_COUNT(mp) \ |
226 | (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ | 228 | (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \ |
227 | XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) | 229 | XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1) |
228 | 230 | ||
229 | 231 | ||
230 | #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) | 232 | #define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write) |
231 | #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) | 233 | #define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate) |
232 | #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) | 234 | #define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename) |
233 | #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) | 235 | #define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link) |
234 | #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) | 236 | #define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove) |
235 | #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) | 237 | #define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink) |
236 | #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) | 238 | #define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create) |
237 | #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) | 239 | #define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir) |
238 | #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) | 240 | #define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree) |
239 | #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) | 241 | #define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange) |
240 | #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) | 242 | #define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata) |
241 | #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) | 243 | #define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc) |
242 | #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) | 244 | #define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero) |
243 | #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) | 245 | #define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree) |
244 | #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) | 246 | #define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) |
245 | /* | 247 | /* |
246 | * Logging the inode timestamps on an fsync -- same as SWRITE | 248 | * Logging the inode timestamps on an fsync -- same as SWRITE |
247 | * as long as SWRITE logs the entire inode core | 249 | * as long as SWRITE logs the entire inode core |
248 | */ | 250 | */ |
249 | #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) | 251 | #define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) |
250 | #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) | 252 | #define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite) |
251 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) | 253 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) |
252 | #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) | 254 | #define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval) |
253 | #define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetm) | 255 | #define XFS_ATTRSETM_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetm) |
254 | #define XFS_ATTRSETRT_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetrt) | 256 | #define XFS_ATTRSETRT_LOG_RES(mp) ((mp)->m_reservations.tr_attrsetrt) |
255 | #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) | 257 | #define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm) |
256 | #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) | 258 | #define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi) |
257 | #define XFS_QM_SBCHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_qm_sbchange) | 259 | #define XFS_QM_SBCHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_qm_sbchange) |
258 | #define XFS_QM_SETQLIM_LOG_RES(mp) ((mp)->m_reservations.tr_qm_setqlim) | 260 | #define XFS_QM_SETQLIM_LOG_RES(mp) ((mp)->m_reservations.tr_qm_setqlim) |
259 | #define XFS_QM_DQALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_qm_dqalloc) | 261 | #define XFS_QM_DQALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_qm_dqalloc) |
260 | #define XFS_QM_QUOTAOFF_LOG_RES(mp) ((mp)->m_reservations.tr_qm_quotaoff) | 262 | #define XFS_QM_QUOTAOFF_LOG_RES(mp) ((mp)->m_reservations.tr_qm_quotaoff) |
261 | #define XFS_QM_QUOTAOFF_END_LOG_RES(mp) ((mp)->m_reservations.tr_qm_equotaoff) | 263 | #define XFS_QM_QUOTAOFF_END_LOG_RES(mp) ((mp)->m_reservations.tr_qm_equotaoff) |
262 | #define XFS_SB_LOG_RES(mp) ((mp)->m_reservations.tr_sb) | 264 | #define XFS_SB_LOG_RES(mp) ((mp)->m_reservations.tr_sb) |
263 | 265 | ||
264 | /* | 266 | /* |
265 | * Various log count values. | 267 | * Various log count values. |
266 | */ | 268 | */ |
267 | #define XFS_DEFAULT_LOG_COUNT 1 | 269 | #define XFS_DEFAULT_LOG_COUNT 1 |
268 | #define XFS_DEFAULT_PERM_LOG_COUNT 2 | 270 | #define XFS_DEFAULT_PERM_LOG_COUNT 2 |
269 | #define XFS_ITRUNCATE_LOG_COUNT 2 | 271 | #define XFS_ITRUNCATE_LOG_COUNT 2 |
270 | #define XFS_INACTIVE_LOG_COUNT 2 | 272 | #define XFS_INACTIVE_LOG_COUNT 2 |
271 | #define XFS_CREATE_LOG_COUNT 2 | 273 | #define XFS_CREATE_LOG_COUNT 2 |
272 | #define XFS_MKDIR_LOG_COUNT 3 | 274 | #define XFS_MKDIR_LOG_COUNT 3 |
273 | #define XFS_SYMLINK_LOG_COUNT 3 | 275 | #define XFS_SYMLINK_LOG_COUNT 3 |
274 | #define XFS_REMOVE_LOG_COUNT 2 | 276 | #define XFS_REMOVE_LOG_COUNT 2 |
275 | #define XFS_LINK_LOG_COUNT 2 | 277 | #define XFS_LINK_LOG_COUNT 2 |
276 | #define XFS_RENAME_LOG_COUNT 2 | 278 | #define XFS_RENAME_LOG_COUNT 2 |
277 | #define XFS_WRITE_LOG_COUNT 2 | 279 | #define XFS_WRITE_LOG_COUNT 2 |
278 | #define XFS_ADDAFORK_LOG_COUNT 2 | 280 | #define XFS_ADDAFORK_LOG_COUNT 2 |
279 | #define XFS_ATTRINVAL_LOG_COUNT 1 | 281 | #define XFS_ATTRINVAL_LOG_COUNT 1 |
280 | #define XFS_ATTRSET_LOG_COUNT 3 | 282 | #define XFS_ATTRSET_LOG_COUNT 3 |
281 | #define XFS_ATTRRM_LOG_COUNT 3 | 283 | #define XFS_ATTRRM_LOG_COUNT 3 |
282 | 284 | ||
283 | /* | 285 | /* |
284 | * Here we centralize the specification of XFS meta-data buffer | 286 | * Here we centralize the specification of XFS meta-data buffer |
285 | * reference count values. This determine how hard the buffer | 287 | * reference count values. This determine how hard the buffer |
286 | * cache tries to hold onto the buffer. | 288 | * cache tries to hold onto the buffer. |
287 | */ | 289 | */ |
288 | #define XFS_AGF_REF 4 | 290 | #define XFS_AGF_REF 4 |
289 | #define XFS_AGI_REF 4 | 291 | #define XFS_AGI_REF 4 |
290 | #define XFS_AGFL_REF 3 | 292 | #define XFS_AGFL_REF 3 |
291 | #define XFS_INO_BTREE_REF 3 | 293 | #define XFS_INO_BTREE_REF 3 |
292 | #define XFS_ALLOC_BTREE_REF 2 | 294 | #define XFS_ALLOC_BTREE_REF 2 |
293 | #define XFS_BMAP_BTREE_REF 2 | 295 | #define XFS_BMAP_BTREE_REF 2 |
294 | #define XFS_DIR_BTREE_REF 2 | 296 | #define XFS_DIR_BTREE_REF 2 |
295 | #define XFS_INO_REF 2 | 297 | #define XFS_INO_REF 2 |
296 | #define XFS_ATTR_BTREE_REF 1 | 298 | #define XFS_ATTR_BTREE_REF 1 |
297 | #define XFS_DQUOT_REF 1 | 299 | #define XFS_DQUOT_REF 1 |
298 | 300 | ||
299 | #ifdef __KERNEL__ | 301 | #ifdef __KERNEL__ |
300 | 302 | ||
301 | struct xfs_buf; | 303 | struct xfs_buf; |
302 | struct xfs_buftarg; | 304 | struct xfs_buftarg; |
303 | struct xfs_efd_log_item; | 305 | struct xfs_efd_log_item; |
304 | struct xfs_efi_log_item; | 306 | struct xfs_efi_log_item; |
305 | struct xfs_inode; | 307 | struct xfs_inode; |
306 | struct xfs_item_ops; | 308 | struct xfs_item_ops; |
307 | struct xfs_log_iovec; | 309 | struct xfs_log_iovec; |
308 | struct xfs_log_item_desc; | 310 | struct xfs_log_item_desc; |
309 | struct xfs_mount; | 311 | struct xfs_mount; |
310 | struct xfs_trans; | 312 | struct xfs_trans; |
311 | struct xfs_dquot_acct; | 313 | struct xfs_dquot_acct; |
312 | struct xfs_busy_extent; | 314 | struct xfs_busy_extent; |
313 | 315 | ||
314 | typedef struct xfs_log_item { | 316 | typedef struct xfs_log_item { |
315 | struct list_head li_ail; /* AIL pointers */ | 317 | struct list_head li_ail; /* AIL pointers */ |
316 | xfs_lsn_t li_lsn; /* last on-disk lsn */ | 318 | xfs_lsn_t li_lsn; /* last on-disk lsn */ |
317 | struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ | 319 | struct xfs_log_item_desc *li_desc; /* ptr to current desc*/ |
318 | struct xfs_mount *li_mountp; /* ptr to fs mount */ | 320 | struct xfs_mount *li_mountp; /* ptr to fs mount */ |
319 | struct xfs_ail *li_ailp; /* ptr to AIL */ | 321 | struct xfs_ail *li_ailp; /* ptr to AIL */ |
320 | uint li_type; /* item type */ | 322 | uint li_type; /* item type */ |
321 | uint li_flags; /* misc flags */ | 323 | uint li_flags; /* misc flags */ |
322 | struct xfs_log_item *li_bio_list; /* buffer item list */ | 324 | struct xfs_log_item *li_bio_list; /* buffer item list */ |
323 | void (*li_cb)(struct xfs_buf *, | 325 | void (*li_cb)(struct xfs_buf *, |
324 | struct xfs_log_item *); | 326 | struct xfs_log_item *); |
325 | /* buffer item iodone */ | 327 | /* buffer item iodone */ |
326 | /* callback func */ | 328 | /* callback func */ |
327 | const struct xfs_item_ops *li_ops; /* function list */ | 329 | const struct xfs_item_ops *li_ops; /* function list */ |
328 | 330 | ||
329 | /* delayed logging */ | 331 | /* delayed logging */ |
330 | struct list_head li_cil; /* CIL pointers */ | 332 | struct list_head li_cil; /* CIL pointers */ |
331 | struct xfs_log_vec *li_lv; /* active log vector */ | 333 | struct xfs_log_vec *li_lv; /* active log vector */ |
332 | xfs_lsn_t li_seq; /* CIL commit seq */ | 334 | xfs_lsn_t li_seq; /* CIL commit seq */ |
333 | } xfs_log_item_t; | 335 | } xfs_log_item_t; |
334 | 336 | ||
335 | #define XFS_LI_IN_AIL 0x1 | 337 | #define XFS_LI_IN_AIL 0x1 |
336 | #define XFS_LI_ABORTED 0x2 | 338 | #define XFS_LI_ABORTED 0x2 |
337 | 339 | ||
338 | #define XFS_LI_FLAGS \ | 340 | #define XFS_LI_FLAGS \ |
339 | { XFS_LI_IN_AIL, "IN_AIL" }, \ | 341 | { XFS_LI_IN_AIL, "IN_AIL" }, \ |
340 | { XFS_LI_ABORTED, "ABORTED" } | 342 | { XFS_LI_ABORTED, "ABORTED" } |
341 | 343 | ||
342 | struct xfs_item_ops { | 344 | struct xfs_item_ops { |
343 | uint (*iop_size)(xfs_log_item_t *); | 345 | uint (*iop_size)(xfs_log_item_t *); |
344 | void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); | 346 | void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); |
345 | void (*iop_pin)(xfs_log_item_t *); | 347 | void (*iop_pin)(xfs_log_item_t *); |
346 | void (*iop_unpin)(xfs_log_item_t *, int remove); | 348 | void (*iop_unpin)(xfs_log_item_t *, int remove); |
347 | uint (*iop_push)(struct xfs_log_item *, struct list_head *); | 349 | uint (*iop_push)(struct xfs_log_item *, struct list_head *); |
348 | void (*iop_unlock)(xfs_log_item_t *); | 350 | void (*iop_unlock)(xfs_log_item_t *); |
349 | xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); | 351 | xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); |
350 | void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); | 352 | void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); |
351 | }; | 353 | }; |
352 | 354 | ||
353 | #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) | 355 | #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) |
354 | #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) | 356 | #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) |
355 | #define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) | 357 | #define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip) |
356 | #define IOP_UNPIN(ip, remove) (*(ip)->li_ops->iop_unpin)(ip, remove) | 358 | #define IOP_UNPIN(ip, remove) (*(ip)->li_ops->iop_unpin)(ip, remove) |
357 | #define IOP_PUSH(ip, list) (*(ip)->li_ops->iop_push)(ip, list) | 359 | #define IOP_PUSH(ip, list) (*(ip)->li_ops->iop_push)(ip, list) |
358 | #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) | 360 | #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) |
359 | #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) | 361 | #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) |
360 | #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) | 362 | #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) |
361 | 363 | ||
362 | /* | 364 | /* |
363 | * Return values for the IOP_PUSH() routines. | 365 | * Return values for the IOP_PUSH() routines. |
364 | */ | 366 | */ |
365 | #define XFS_ITEM_SUCCESS 0 | 367 | #define XFS_ITEM_SUCCESS 0 |
366 | #define XFS_ITEM_PINNED 1 | 368 | #define XFS_ITEM_PINNED 1 |
367 | #define XFS_ITEM_LOCKED 2 | 369 | #define XFS_ITEM_LOCKED 2 |
368 | #define XFS_ITEM_FLUSHING 3 | 370 | #define XFS_ITEM_FLUSHING 3 |
369 | 371 | ||
370 | /* | 372 | /* |
371 | * This is the type of function which can be given to xfs_trans_callback() | 373 | * This is the type of function which can be given to xfs_trans_callback() |
372 | * to be called upon the transaction's commit to disk. | 374 | * to be called upon the transaction's commit to disk. |
373 | */ | 375 | */ |
374 | typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *); | 376 | typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *); |
375 | 377 | ||
376 | /* | 378 | /* |
377 | * This is the structure maintained for every active transaction. | 379 | * This is the structure maintained for every active transaction. |
378 | */ | 380 | */ |
379 | typedef struct xfs_trans { | 381 | typedef struct xfs_trans { |
380 | unsigned int t_magic; /* magic number */ | 382 | unsigned int t_magic; /* magic number */ |
381 | xfs_log_callback_t t_logcb; /* log callback struct */ | 383 | xfs_log_callback_t t_logcb; /* log callback struct */ |
382 | unsigned int t_type; /* transaction type */ | 384 | unsigned int t_type; /* transaction type */ |
383 | unsigned int t_log_res; /* amt of log space resvd */ | 385 | unsigned int t_log_res; /* amt of log space resvd */ |
384 | unsigned int t_log_count; /* count for perm log res */ | 386 | unsigned int t_log_count; /* count for perm log res */ |
385 | unsigned int t_blk_res; /* # of blocks resvd */ | 387 | unsigned int t_blk_res; /* # of blocks resvd */ |
386 | unsigned int t_blk_res_used; /* # of resvd blocks used */ | 388 | unsigned int t_blk_res_used; /* # of resvd blocks used */ |
387 | unsigned int t_rtx_res; /* # of rt extents resvd */ | 389 | unsigned int t_rtx_res; /* # of rt extents resvd */ |
388 | unsigned int t_rtx_res_used; /* # of resvd rt extents used */ | 390 | unsigned int t_rtx_res_used; /* # of resvd rt extents used */ |
389 | struct xlog_ticket *t_ticket; /* log mgr ticket */ | 391 | struct xlog_ticket *t_ticket; /* log mgr ticket */ |
390 | xfs_lsn_t t_lsn; /* log seq num of start of | 392 | xfs_lsn_t t_lsn; /* log seq num of start of |
391 | * transaction. */ | 393 | * transaction. */ |
392 | xfs_lsn_t t_commit_lsn; /* log seq num of end of | 394 | xfs_lsn_t t_commit_lsn; /* log seq num of end of |
393 | * transaction. */ | 395 | * transaction. */ |
394 | struct xfs_mount *t_mountp; /* ptr to fs mount struct */ | 396 | struct xfs_mount *t_mountp; /* ptr to fs mount struct */ |
395 | struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ | 397 | struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */ |
396 | unsigned int t_flags; /* misc flags */ | 398 | unsigned int t_flags; /* misc flags */ |
397 | int64_t t_icount_delta; /* superblock icount change */ | 399 | int64_t t_icount_delta; /* superblock icount change */ |
398 | int64_t t_ifree_delta; /* superblock ifree change */ | 400 | int64_t t_ifree_delta; /* superblock ifree change */ |
399 | int64_t t_fdblocks_delta; /* superblock fdblocks chg */ | 401 | int64_t t_fdblocks_delta; /* superblock fdblocks chg */ |
400 | int64_t t_res_fdblocks_delta; /* on-disk only chg */ | 402 | int64_t t_res_fdblocks_delta; /* on-disk only chg */ |
401 | int64_t t_frextents_delta;/* superblock freextents chg*/ | 403 | int64_t t_frextents_delta;/* superblock freextents chg*/ |
402 | int64_t t_res_frextents_delta; /* on-disk only chg */ | 404 | int64_t t_res_frextents_delta; /* on-disk only chg */ |
403 | #if defined(DEBUG) || defined(XFS_WARN) | 405 | #if defined(DEBUG) || defined(XFS_WARN) |
404 | int64_t t_ag_freeblks_delta; /* debugging counter */ | 406 | int64_t t_ag_freeblks_delta; /* debugging counter */ |
405 | int64_t t_ag_flist_delta; /* debugging counter */ | 407 | int64_t t_ag_flist_delta; /* debugging counter */ |
406 | int64_t t_ag_btree_delta; /* debugging counter */ | 408 | int64_t t_ag_btree_delta; /* debugging counter */ |
407 | #endif | 409 | #endif |
408 | int64_t t_dblocks_delta;/* superblock dblocks change */ | 410 | int64_t t_dblocks_delta;/* superblock dblocks change */ |
409 | int64_t t_agcount_delta;/* superblock agcount change */ | 411 | int64_t t_agcount_delta;/* superblock agcount change */ |
410 | int64_t t_imaxpct_delta;/* superblock imaxpct change */ | 412 | int64_t t_imaxpct_delta;/* superblock imaxpct change */ |
411 | int64_t t_rextsize_delta;/* superblock rextsize chg */ | 413 | int64_t t_rextsize_delta;/* superblock rextsize chg */ |
412 | int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */ | 414 | int64_t t_rbmblocks_delta;/* superblock rbmblocks chg */ |
413 | int64_t t_rblocks_delta;/* superblock rblocks change */ | 415 | int64_t t_rblocks_delta;/* superblock rblocks change */ |
414 | int64_t t_rextents_delta;/* superblocks rextents chg */ | 416 | int64_t t_rextents_delta;/* superblocks rextents chg */ |
415 | int64_t t_rextslog_delta;/* superblocks rextslog chg */ | 417 | int64_t t_rextslog_delta;/* superblocks rextslog chg */ |
416 | struct list_head t_items; /* log item descriptors */ | 418 | struct list_head t_items; /* log item descriptors */ |
417 | xfs_trans_header_t t_header; /* header for in-log trans */ | 419 | xfs_trans_header_t t_header; /* header for in-log trans */ |
418 | struct list_head t_busy; /* list of busy extents */ | 420 | struct list_head t_busy; /* list of busy extents */ |
419 | unsigned long t_pflags; /* saved process flags state */ | 421 | unsigned long t_pflags; /* saved process flags state */ |
420 | } xfs_trans_t; | 422 | } xfs_trans_t; |
421 | 423 | ||
422 | /* | 424 | /* |
423 | * XFS transaction mechanism exported interfaces that are | 425 | * XFS transaction mechanism exported interfaces that are |
424 | * actually macros. | 426 | * actually macros. |
425 | */ | 427 | */ |
426 | #define xfs_trans_get_log_res(tp) ((tp)->t_log_res) | 428 | #define xfs_trans_get_log_res(tp) ((tp)->t_log_res) |
427 | #define xfs_trans_get_log_count(tp) ((tp)->t_log_count) | 429 | #define xfs_trans_get_log_count(tp) ((tp)->t_log_count) |
428 | #define xfs_trans_get_block_res(tp) ((tp)->t_blk_res) | 430 | #define xfs_trans_get_block_res(tp) ((tp)->t_blk_res) |
429 | #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) | 431 | #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) |
430 | 432 | ||
431 | #if defined(DEBUG) || defined(XFS_WARN) | 433 | #if defined(DEBUG) || defined(XFS_WARN) |
432 | #define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d) | 434 | #define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d) |
433 | #define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d) | 435 | #define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d) |
434 | #define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d) | 436 | #define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d) |
435 | #else | 437 | #else |
436 | #define xfs_trans_agblocks_delta(tp, d) | 438 | #define xfs_trans_agblocks_delta(tp, d) |
437 | #define xfs_trans_agflist_delta(tp, d) | 439 | #define xfs_trans_agflist_delta(tp, d) |
438 | #define xfs_trans_agbtree_delta(tp, d) | 440 | #define xfs_trans_agbtree_delta(tp, d) |
439 | #endif | 441 | #endif |
440 | 442 | ||
441 | /* | 443 | /* |
442 | * XFS transaction mechanism exported interfaces. | 444 | * XFS transaction mechanism exported interfaces. |
443 | */ | 445 | */ |
444 | xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); | 446 | xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); |
445 | xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, xfs_km_flags_t); | 447 | xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, xfs_km_flags_t); |
446 | xfs_trans_t *xfs_trans_dup(xfs_trans_t *); | 448 | xfs_trans_t *xfs_trans_dup(xfs_trans_t *); |
447 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, | 449 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, |
448 | uint, uint); | 450 | uint, uint); |
449 | void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); | 451 | void xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t); |
450 | 452 | ||
451 | struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp, | 453 | struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp, |
452 | struct xfs_buftarg *target, | 454 | struct xfs_buftarg *target, |
453 | struct xfs_buf_map *map, int nmaps, | 455 | struct xfs_buf_map *map, int nmaps, |
454 | uint flags); | 456 | uint flags); |
455 | 457 | ||
456 | static inline struct xfs_buf * | 458 | static inline struct xfs_buf * |
457 | xfs_trans_get_buf( | 459 | xfs_trans_get_buf( |
458 | struct xfs_trans *tp, | 460 | struct xfs_trans *tp, |
459 | struct xfs_buftarg *target, | 461 | struct xfs_buftarg *target, |
460 | xfs_daddr_t blkno, | 462 | xfs_daddr_t blkno, |
461 | int numblks, | 463 | int numblks, |
462 | uint flags) | 464 | uint flags) |
463 | { | 465 | { |
464 | DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); | 466 | DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); |
465 | return xfs_trans_get_buf_map(tp, target, &map, 1, flags); | 467 | return xfs_trans_get_buf_map(tp, target, &map, 1, flags); |
466 | } | 468 | } |
467 | 469 | ||
468 | int xfs_trans_read_buf_map(struct xfs_mount *mp, | 470 | int xfs_trans_read_buf_map(struct xfs_mount *mp, |
469 | struct xfs_trans *tp, | 471 | struct xfs_trans *tp, |
470 | struct xfs_buftarg *target, | 472 | struct xfs_buftarg *target, |
471 | struct xfs_buf_map *map, int nmaps, | 473 | struct xfs_buf_map *map, int nmaps, |
472 | xfs_buf_flags_t flags, | 474 | xfs_buf_flags_t flags, |
473 | struct xfs_buf **bpp, | 475 | struct xfs_buf **bpp, |
474 | const struct xfs_buf_ops *ops); | 476 | const struct xfs_buf_ops *ops); |
475 | 477 | ||
476 | static inline int | 478 | static inline int |
477 | xfs_trans_read_buf( | 479 | xfs_trans_read_buf( |
478 | struct xfs_mount *mp, | 480 | struct xfs_mount *mp, |
479 | struct xfs_trans *tp, | 481 | struct xfs_trans *tp, |
480 | struct xfs_buftarg *target, | 482 | struct xfs_buftarg *target, |
481 | xfs_daddr_t blkno, | 483 | xfs_daddr_t blkno, |
482 | int numblks, | 484 | int numblks, |
483 | xfs_buf_flags_t flags, | 485 | xfs_buf_flags_t flags, |
484 | struct xfs_buf **bpp, | 486 | struct xfs_buf **bpp, |
485 | const struct xfs_buf_ops *ops) | 487 | const struct xfs_buf_ops *ops) |
486 | { | 488 | { |
487 | DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); | 489 | DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); |
488 | return xfs_trans_read_buf_map(mp, tp, target, &map, 1, | 490 | return xfs_trans_read_buf_map(mp, tp, target, &map, 1, |
489 | flags, bpp, ops); | 491 | flags, bpp, ops); |
490 | } | 492 | } |
491 | 493 | ||
492 | struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); | 494 | struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); |
493 | 495 | ||
494 | void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); | 496 | void xfs_trans_brelse(xfs_trans_t *, struct xfs_buf *); |
495 | void xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *); | 497 | void xfs_trans_bjoin(xfs_trans_t *, struct xfs_buf *); |
496 | void xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *); | 498 | void xfs_trans_bhold(xfs_trans_t *, struct xfs_buf *); |
497 | void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *); | 499 | void xfs_trans_bhold_release(xfs_trans_t *, struct xfs_buf *); |
498 | void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *); | 500 | void xfs_trans_binval(xfs_trans_t *, struct xfs_buf *); |
499 | void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *); | 501 | void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *); |
500 | void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *); | 502 | void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *); |
501 | void xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *); | 503 | void xfs_trans_ordered_buf(xfs_trans_t *, struct xfs_buf *); |
502 | void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint); | 504 | void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint); |
503 | void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); | 505 | void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); |
504 | void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); | 506 | void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); |
505 | void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint); | 507 | void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint); |
506 | void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); | 508 | void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); |
507 | void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); | 509 | void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); |
508 | struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); | 510 | struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); |
509 | void xfs_efi_release(struct xfs_efi_log_item *, uint); | 511 | void xfs_efi_release(struct xfs_efi_log_item *, uint); |
510 | void xfs_trans_log_efi_extent(xfs_trans_t *, | 512 | void xfs_trans_log_efi_extent(xfs_trans_t *, |
511 | struct xfs_efi_log_item *, | 513 | struct xfs_efi_log_item *, |
512 | xfs_fsblock_t, | 514 | xfs_fsblock_t, |
513 | xfs_extlen_t); | 515 | xfs_extlen_t); |
514 | struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *, | 516 | struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *, |
515 | struct xfs_efi_log_item *, | 517 | struct xfs_efi_log_item *, |
516 | uint); | 518 | uint); |
517 | void xfs_trans_log_efd_extent(xfs_trans_t *, | 519 | void xfs_trans_log_efd_extent(xfs_trans_t *, |
518 | struct xfs_efd_log_item *, | 520 | struct xfs_efd_log_item *, |
519 | xfs_fsblock_t, | 521 | xfs_fsblock_t, |
520 | xfs_extlen_t); | 522 | xfs_extlen_t); |
521 | int xfs_trans_commit(xfs_trans_t *, uint flags); | 523 | int xfs_trans_commit(xfs_trans_t *, uint flags); |
522 | void xfs_trans_cancel(xfs_trans_t *, int); | 524 | void xfs_trans_cancel(xfs_trans_t *, int); |
523 | int xfs_trans_ail_init(struct xfs_mount *); | 525 | int xfs_trans_ail_init(struct xfs_mount *); |
524 | void xfs_trans_ail_destroy(struct xfs_mount *); | 526 | void xfs_trans_ail_destroy(struct xfs_mount *); |
525 | 527 | ||
526 | extern kmem_zone_t *xfs_trans_zone; | 528 | extern kmem_zone_t *xfs_trans_zone; |
527 | extern kmem_zone_t *xfs_log_item_desc_zone; | 529 | extern kmem_zone_t *xfs_log_item_desc_zone; |
528 | 530 | ||
529 | #endif /* __KERNEL__ */ | 531 | #endif /* __KERNEL__ */ |
530 | 532 | ||
531 | void xfs_trans_init(struct xfs_mount *); | 533 | void xfs_trans_init(struct xfs_mount *); |
532 | int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); | 534 | int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); |
533 | 535 | ||
534 | #endif /* __XFS_TRANS_H__ */ | 536 | #endif /* __XFS_TRANS_H__ */ |
535 | 537 |