Commit 3ebe7d2d73179c4874aee4f32e043eb5acd9fa0f

Authored by Dave Chinner
Committed by Ben Myers
1 parent 5f6bed76c0

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

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