Commit 2ea0392983a82f7dc3055568ae0f2558724d119b
Committed by
Ben Myers
1 parent
4056c1d08d
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
xfs: Make inode32 a remountable option
As inode64 is the default option now, and was also made remountable previously, inode32 can also be remounted on-the-fly when it is needed. Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Showing 1 changed file with 9 additions and 1 deletions Inline Diff
fs/xfs/xfs_super.c
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | 3 | * All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it would be useful, | 9 | * This program is distributed in the hope that it would be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "xfs.h" | 19 | #include "xfs.h" |
20 | #include "xfs_log.h" | 20 | #include "xfs_log.h" |
21 | #include "xfs_inum.h" | 21 | #include "xfs_inum.h" |
22 | #include "xfs_trans.h" | 22 | #include "xfs_trans.h" |
23 | #include "xfs_sb.h" | 23 | #include "xfs_sb.h" |
24 | #include "xfs_ag.h" | 24 | #include "xfs_ag.h" |
25 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
26 | #include "xfs_alloc.h" | 26 | #include "xfs_alloc.h" |
27 | #include "xfs_quota.h" | 27 | #include "xfs_quota.h" |
28 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
29 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
30 | #include "xfs_alloc_btree.h" | 30 | #include "xfs_alloc_btree.h" |
31 | #include "xfs_ialloc_btree.h" | 31 | #include "xfs_ialloc_btree.h" |
32 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
33 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
34 | #include "xfs_btree.h" | 34 | #include "xfs_btree.h" |
35 | #include "xfs_ialloc.h" | 35 | #include "xfs_ialloc.h" |
36 | #include "xfs_bmap.h" | 36 | #include "xfs_bmap.h" |
37 | #include "xfs_rtalloc.h" | 37 | #include "xfs_rtalloc.h" |
38 | #include "xfs_error.h" | 38 | #include "xfs_error.h" |
39 | #include "xfs_itable.h" | 39 | #include "xfs_itable.h" |
40 | #include "xfs_fsops.h" | 40 | #include "xfs_fsops.h" |
41 | #include "xfs_attr.h" | 41 | #include "xfs_attr.h" |
42 | #include "xfs_buf_item.h" | 42 | #include "xfs_buf_item.h" |
43 | #include "xfs_utils.h" | 43 | #include "xfs_utils.h" |
44 | #include "xfs_vnodeops.h" | 44 | #include "xfs_vnodeops.h" |
45 | #include "xfs_log_priv.h" | 45 | #include "xfs_log_priv.h" |
46 | #include "xfs_trans_priv.h" | 46 | #include "xfs_trans_priv.h" |
47 | #include "xfs_filestream.h" | 47 | #include "xfs_filestream.h" |
48 | #include "xfs_da_btree.h" | 48 | #include "xfs_da_btree.h" |
49 | #include "xfs_extfree_item.h" | 49 | #include "xfs_extfree_item.h" |
50 | #include "xfs_mru_cache.h" | 50 | #include "xfs_mru_cache.h" |
51 | #include "xfs_inode_item.h" | 51 | #include "xfs_inode_item.h" |
52 | #include "xfs_sync.h" | 52 | #include "xfs_sync.h" |
53 | #include "xfs_trace.h" | 53 | #include "xfs_trace.h" |
54 | 54 | ||
55 | #include <linux/namei.h> | 55 | #include <linux/namei.h> |
56 | #include <linux/init.h> | 56 | #include <linux/init.h> |
57 | #include <linux/slab.h> | 57 | #include <linux/slab.h> |
58 | #include <linux/mount.h> | 58 | #include <linux/mount.h> |
59 | #include <linux/mempool.h> | 59 | #include <linux/mempool.h> |
60 | #include <linux/writeback.h> | 60 | #include <linux/writeback.h> |
61 | #include <linux/kthread.h> | 61 | #include <linux/kthread.h> |
62 | #include <linux/freezer.h> | 62 | #include <linux/freezer.h> |
63 | #include <linux/parser.h> | 63 | #include <linux/parser.h> |
64 | 64 | ||
65 | static const struct super_operations xfs_super_operations; | 65 | static const struct super_operations xfs_super_operations; |
66 | static kmem_zone_t *xfs_ioend_zone; | 66 | static kmem_zone_t *xfs_ioend_zone; |
67 | mempool_t *xfs_ioend_pool; | 67 | mempool_t *xfs_ioend_pool; |
68 | 68 | ||
69 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ | 69 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ |
70 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ | 70 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ |
71 | #define MNTOPT_LOGDEV "logdev" /* log device */ | 71 | #define MNTOPT_LOGDEV "logdev" /* log device */ |
72 | #define MNTOPT_RTDEV "rtdev" /* realtime I/O device */ | 72 | #define MNTOPT_RTDEV "rtdev" /* realtime I/O device */ |
73 | #define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */ | 73 | #define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */ |
74 | #define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */ | 74 | #define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */ |
75 | #define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */ | 75 | #define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */ |
76 | #define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */ | 76 | #define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */ |
77 | #define MNTOPT_SUNIT "sunit" /* data volume stripe unit */ | 77 | #define MNTOPT_SUNIT "sunit" /* data volume stripe unit */ |
78 | #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ | 78 | #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ |
79 | #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ | 79 | #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ |
80 | #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ | 80 | #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ |
81 | #define MNTOPT_GRPID "grpid" /* group-ID from parent directory */ | 81 | #define MNTOPT_GRPID "grpid" /* group-ID from parent directory */ |
82 | #define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */ | 82 | #define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */ |
83 | #define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ | 83 | #define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ |
84 | #define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ | 84 | #define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ |
85 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ | 85 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ |
86 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ | 86 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ |
87 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and | 87 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and |
88 | * unwritten extent conversion */ | 88 | * unwritten extent conversion */ |
89 | #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ | 89 | #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ |
90 | #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ | 90 | #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ |
91 | #define MNTOPT_32BITINODE "inode32" /* inode allocation limited to | 91 | #define MNTOPT_32BITINODE "inode32" /* inode allocation limited to |
92 | * XFS_MAXINUMBER_32 */ | 92 | * XFS_MAXINUMBER_32 */ |
93 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ | 93 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ |
94 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ | 94 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ |
95 | #define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */ | 95 | #define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */ |
96 | #define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes | 96 | #define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes |
97 | * in stat(). */ | 97 | * in stat(). */ |
98 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ | 98 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ |
99 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ | 99 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ |
100 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ | 100 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ |
101 | #define MNTOPT_QUOTA "quota" /* disk quotas (user) */ | 101 | #define MNTOPT_QUOTA "quota" /* disk quotas (user) */ |
102 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ | 102 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ |
103 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ | 103 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ |
104 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ | 104 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ |
105 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ | 105 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ |
106 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ | 106 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ |
107 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ | 107 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ |
108 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ | 108 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ |
109 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ | 109 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ |
110 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | 110 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ |
111 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | 111 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ |
112 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | 112 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ |
113 | #define MNTOPT_DELAYLOG "delaylog" /* Delayed logging enabled */ | 113 | #define MNTOPT_DELAYLOG "delaylog" /* Delayed logging enabled */ |
114 | #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed logging disabled */ | 114 | #define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed logging disabled */ |
115 | #define MNTOPT_DISCARD "discard" /* Discard unused blocks */ | 115 | #define MNTOPT_DISCARD "discard" /* Discard unused blocks */ |
116 | #define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */ | 116 | #define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */ |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * Table driven mount option parser. | 119 | * Table driven mount option parser. |
120 | * | 120 | * |
121 | * Currently only used for remount, but it will be used for mount | 121 | * Currently only used for remount, but it will be used for mount |
122 | * in the future, too. | 122 | * in the future, too. |
123 | */ | 123 | */ |
124 | enum { | 124 | enum { |
125 | Opt_barrier, Opt_nobarrier, Opt_inode64, Opt_err | 125 | Opt_barrier, |
126 | Opt_nobarrier, | ||
127 | Opt_inode64, | ||
128 | Opt_inode32, | ||
129 | Opt_err | ||
126 | }; | 130 | }; |
127 | 131 | ||
128 | static const match_table_t tokens = { | 132 | static const match_table_t tokens = { |
129 | {Opt_barrier, "barrier"}, | 133 | {Opt_barrier, "barrier"}, |
130 | {Opt_nobarrier, "nobarrier"}, | 134 | {Opt_nobarrier, "nobarrier"}, |
131 | {Opt_inode64, "inode64"}, | 135 | {Opt_inode64, "inode64"}, |
136 | {Opt_inode32, "inode32"}, | ||
132 | {Opt_err, NULL} | 137 | {Opt_err, NULL} |
133 | }; | 138 | }; |
134 | 139 | ||
135 | 140 | ||
136 | STATIC unsigned long | 141 | STATIC unsigned long |
137 | suffix_strtoul(char *s, char **endp, unsigned int base) | 142 | suffix_strtoul(char *s, char **endp, unsigned int base) |
138 | { | 143 | { |
139 | int last, shift_left_factor = 0; | 144 | int last, shift_left_factor = 0; |
140 | char *value = s; | 145 | char *value = s; |
141 | 146 | ||
142 | last = strlen(value) - 1; | 147 | last = strlen(value) - 1; |
143 | if (value[last] == 'K' || value[last] == 'k') { | 148 | if (value[last] == 'K' || value[last] == 'k') { |
144 | shift_left_factor = 10; | 149 | shift_left_factor = 10; |
145 | value[last] = '\0'; | 150 | value[last] = '\0'; |
146 | } | 151 | } |
147 | if (value[last] == 'M' || value[last] == 'm') { | 152 | if (value[last] == 'M' || value[last] == 'm') { |
148 | shift_left_factor = 20; | 153 | shift_left_factor = 20; |
149 | value[last] = '\0'; | 154 | value[last] = '\0'; |
150 | } | 155 | } |
151 | if (value[last] == 'G' || value[last] == 'g') { | 156 | if (value[last] == 'G' || value[last] == 'g') { |
152 | shift_left_factor = 30; | 157 | shift_left_factor = 30; |
153 | value[last] = '\0'; | 158 | value[last] = '\0'; |
154 | } | 159 | } |
155 | 160 | ||
156 | return simple_strtoul((const char *)s, endp, base) << shift_left_factor; | 161 | return simple_strtoul((const char *)s, endp, base) << shift_left_factor; |
157 | } | 162 | } |
158 | 163 | ||
159 | /* | 164 | /* |
160 | * This function fills in xfs_mount_t fields based on mount args. | 165 | * This function fills in xfs_mount_t fields based on mount args. |
161 | * Note: the superblock has _not_ yet been read in. | 166 | * Note: the superblock has _not_ yet been read in. |
162 | * | 167 | * |
163 | * Note that this function leaks the various device name allocations on | 168 | * Note that this function leaks the various device name allocations on |
164 | * failure. The caller takes care of them. | 169 | * failure. The caller takes care of them. |
165 | */ | 170 | */ |
166 | STATIC int | 171 | STATIC int |
167 | xfs_parseargs( | 172 | xfs_parseargs( |
168 | struct xfs_mount *mp, | 173 | struct xfs_mount *mp, |
169 | char *options) | 174 | char *options) |
170 | { | 175 | { |
171 | struct super_block *sb = mp->m_super; | 176 | struct super_block *sb = mp->m_super; |
172 | char *this_char, *value, *eov; | 177 | char *this_char, *value, *eov; |
173 | int dsunit = 0; | 178 | int dsunit = 0; |
174 | int dswidth = 0; | 179 | int dswidth = 0; |
175 | int iosize = 0; | 180 | int iosize = 0; |
176 | __uint8_t iosizelog = 0; | 181 | __uint8_t iosizelog = 0; |
177 | 182 | ||
178 | /* | 183 | /* |
179 | * set up the mount name first so all the errors will refer to the | 184 | * set up the mount name first so all the errors will refer to the |
180 | * correct device. | 185 | * correct device. |
181 | */ | 186 | */ |
182 | mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL); | 187 | mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL); |
183 | if (!mp->m_fsname) | 188 | if (!mp->m_fsname) |
184 | return ENOMEM; | 189 | return ENOMEM; |
185 | mp->m_fsname_len = strlen(mp->m_fsname) + 1; | 190 | mp->m_fsname_len = strlen(mp->m_fsname) + 1; |
186 | 191 | ||
187 | /* | 192 | /* |
188 | * Copy binary VFS mount flags we are interested in. | 193 | * Copy binary VFS mount flags we are interested in. |
189 | */ | 194 | */ |
190 | if (sb->s_flags & MS_RDONLY) | 195 | if (sb->s_flags & MS_RDONLY) |
191 | mp->m_flags |= XFS_MOUNT_RDONLY; | 196 | mp->m_flags |= XFS_MOUNT_RDONLY; |
192 | if (sb->s_flags & MS_DIRSYNC) | 197 | if (sb->s_flags & MS_DIRSYNC) |
193 | mp->m_flags |= XFS_MOUNT_DIRSYNC; | 198 | mp->m_flags |= XFS_MOUNT_DIRSYNC; |
194 | if (sb->s_flags & MS_SYNCHRONOUS) | 199 | if (sb->s_flags & MS_SYNCHRONOUS) |
195 | mp->m_flags |= XFS_MOUNT_WSYNC; | 200 | mp->m_flags |= XFS_MOUNT_WSYNC; |
196 | 201 | ||
197 | /* | 202 | /* |
198 | * Set some default flags that could be cleared by the mount option | 203 | * Set some default flags that could be cleared by the mount option |
199 | * parsing. | 204 | * parsing. |
200 | */ | 205 | */ |
201 | mp->m_flags |= XFS_MOUNT_BARRIER; | 206 | mp->m_flags |= XFS_MOUNT_BARRIER; |
202 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | 207 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
203 | #if !XFS_BIG_INUMS | 208 | #if !XFS_BIG_INUMS |
204 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | 209 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
205 | #endif | 210 | #endif |
206 | 211 | ||
207 | /* | 212 | /* |
208 | * These can be overridden by the mount option parsing. | 213 | * These can be overridden by the mount option parsing. |
209 | */ | 214 | */ |
210 | mp->m_logbufs = -1; | 215 | mp->m_logbufs = -1; |
211 | mp->m_logbsize = -1; | 216 | mp->m_logbsize = -1; |
212 | 217 | ||
213 | if (!options) | 218 | if (!options) |
214 | goto done; | 219 | goto done; |
215 | 220 | ||
216 | while ((this_char = strsep(&options, ",")) != NULL) { | 221 | while ((this_char = strsep(&options, ",")) != NULL) { |
217 | if (!*this_char) | 222 | if (!*this_char) |
218 | continue; | 223 | continue; |
219 | if ((value = strchr(this_char, '=')) != NULL) | 224 | if ((value = strchr(this_char, '=')) != NULL) |
220 | *value++ = 0; | 225 | *value++ = 0; |
221 | 226 | ||
222 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { | 227 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { |
223 | if (!value || !*value) { | 228 | if (!value || !*value) { |
224 | xfs_warn(mp, "%s option requires an argument", | 229 | xfs_warn(mp, "%s option requires an argument", |
225 | this_char); | 230 | this_char); |
226 | return EINVAL; | 231 | return EINVAL; |
227 | } | 232 | } |
228 | mp->m_logbufs = simple_strtoul(value, &eov, 10); | 233 | mp->m_logbufs = simple_strtoul(value, &eov, 10); |
229 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { | 234 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { |
230 | if (!value || !*value) { | 235 | if (!value || !*value) { |
231 | xfs_warn(mp, "%s option requires an argument", | 236 | xfs_warn(mp, "%s option requires an argument", |
232 | this_char); | 237 | this_char); |
233 | return EINVAL; | 238 | return EINVAL; |
234 | } | 239 | } |
235 | mp->m_logbsize = suffix_strtoul(value, &eov, 10); | 240 | mp->m_logbsize = suffix_strtoul(value, &eov, 10); |
236 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { | 241 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { |
237 | if (!value || !*value) { | 242 | if (!value || !*value) { |
238 | xfs_warn(mp, "%s option requires an argument", | 243 | xfs_warn(mp, "%s option requires an argument", |
239 | this_char); | 244 | this_char); |
240 | return EINVAL; | 245 | return EINVAL; |
241 | } | 246 | } |
242 | mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); | 247 | mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); |
243 | if (!mp->m_logname) | 248 | if (!mp->m_logname) |
244 | return ENOMEM; | 249 | return ENOMEM; |
245 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { | 250 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { |
246 | xfs_warn(mp, "%s option not allowed on this system", | 251 | xfs_warn(mp, "%s option not allowed on this system", |
247 | this_char); | 252 | this_char); |
248 | return EINVAL; | 253 | return EINVAL; |
249 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { | 254 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { |
250 | if (!value || !*value) { | 255 | if (!value || !*value) { |
251 | xfs_warn(mp, "%s option requires an argument", | 256 | xfs_warn(mp, "%s option requires an argument", |
252 | this_char); | 257 | this_char); |
253 | return EINVAL; | 258 | return EINVAL; |
254 | } | 259 | } |
255 | mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); | 260 | mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); |
256 | if (!mp->m_rtname) | 261 | if (!mp->m_rtname) |
257 | return ENOMEM; | 262 | return ENOMEM; |
258 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { | 263 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { |
259 | if (!value || !*value) { | 264 | if (!value || !*value) { |
260 | xfs_warn(mp, "%s option requires an argument", | 265 | xfs_warn(mp, "%s option requires an argument", |
261 | this_char); | 266 | this_char); |
262 | return EINVAL; | 267 | return EINVAL; |
263 | } | 268 | } |
264 | iosize = simple_strtoul(value, &eov, 10); | 269 | iosize = simple_strtoul(value, &eov, 10); |
265 | iosizelog = ffs(iosize) - 1; | 270 | iosizelog = ffs(iosize) - 1; |
266 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { | 271 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { |
267 | if (!value || !*value) { | 272 | if (!value || !*value) { |
268 | xfs_warn(mp, "%s option requires an argument", | 273 | xfs_warn(mp, "%s option requires an argument", |
269 | this_char); | 274 | this_char); |
270 | return EINVAL; | 275 | return EINVAL; |
271 | } | 276 | } |
272 | iosize = suffix_strtoul(value, &eov, 10); | 277 | iosize = suffix_strtoul(value, &eov, 10); |
273 | iosizelog = ffs(iosize) - 1; | 278 | iosizelog = ffs(iosize) - 1; |
274 | } else if (!strcmp(this_char, MNTOPT_GRPID) || | 279 | } else if (!strcmp(this_char, MNTOPT_GRPID) || |
275 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { | 280 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { |
276 | mp->m_flags |= XFS_MOUNT_GRPID; | 281 | mp->m_flags |= XFS_MOUNT_GRPID; |
277 | } else if (!strcmp(this_char, MNTOPT_NOGRPID) || | 282 | } else if (!strcmp(this_char, MNTOPT_NOGRPID) || |
278 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { | 283 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { |
279 | mp->m_flags &= ~XFS_MOUNT_GRPID; | 284 | mp->m_flags &= ~XFS_MOUNT_GRPID; |
280 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { | 285 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { |
281 | mp->m_flags |= XFS_MOUNT_WSYNC; | 286 | mp->m_flags |= XFS_MOUNT_WSYNC; |
282 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { | 287 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { |
283 | mp->m_flags |= XFS_MOUNT_NORECOVERY; | 288 | mp->m_flags |= XFS_MOUNT_NORECOVERY; |
284 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { | 289 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { |
285 | mp->m_flags |= XFS_MOUNT_NOALIGN; | 290 | mp->m_flags |= XFS_MOUNT_NOALIGN; |
286 | } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { | 291 | } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { |
287 | mp->m_flags |= XFS_MOUNT_SWALLOC; | 292 | mp->m_flags |= XFS_MOUNT_SWALLOC; |
288 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { | 293 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { |
289 | if (!value || !*value) { | 294 | if (!value || !*value) { |
290 | xfs_warn(mp, "%s option requires an argument", | 295 | xfs_warn(mp, "%s option requires an argument", |
291 | this_char); | 296 | this_char); |
292 | return EINVAL; | 297 | return EINVAL; |
293 | } | 298 | } |
294 | dsunit = simple_strtoul(value, &eov, 10); | 299 | dsunit = simple_strtoul(value, &eov, 10); |
295 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { | 300 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { |
296 | if (!value || !*value) { | 301 | if (!value || !*value) { |
297 | xfs_warn(mp, "%s option requires an argument", | 302 | xfs_warn(mp, "%s option requires an argument", |
298 | this_char); | 303 | this_char); |
299 | return EINVAL; | 304 | return EINVAL; |
300 | } | 305 | } |
301 | dswidth = simple_strtoul(value, &eov, 10); | 306 | dswidth = simple_strtoul(value, &eov, 10); |
302 | } else if (!strcmp(this_char, MNTOPT_32BITINODE)) { | 307 | } else if (!strcmp(this_char, MNTOPT_32BITINODE)) { |
303 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | 308 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
304 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { | 309 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { |
305 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; | 310 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
306 | #if !XFS_BIG_INUMS | 311 | #if !XFS_BIG_INUMS |
307 | xfs_warn(mp, "%s option not allowed on this system", | 312 | xfs_warn(mp, "%s option not allowed on this system", |
308 | this_char); | 313 | this_char); |
309 | return EINVAL; | 314 | return EINVAL; |
310 | #endif | 315 | #endif |
311 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { | 316 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { |
312 | mp->m_flags |= XFS_MOUNT_NOUUID; | 317 | mp->m_flags |= XFS_MOUNT_NOUUID; |
313 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { | 318 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { |
314 | mp->m_flags |= XFS_MOUNT_BARRIER; | 319 | mp->m_flags |= XFS_MOUNT_BARRIER; |
315 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { | 320 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { |
316 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 321 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
317 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { | 322 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { |
318 | mp->m_flags |= XFS_MOUNT_IKEEP; | 323 | mp->m_flags |= XFS_MOUNT_IKEEP; |
319 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { | 324 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { |
320 | mp->m_flags &= ~XFS_MOUNT_IKEEP; | 325 | mp->m_flags &= ~XFS_MOUNT_IKEEP; |
321 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { | 326 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { |
322 | mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; | 327 | mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; |
323 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { | 328 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { |
324 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | 329 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
325 | } else if (!strcmp(this_char, MNTOPT_ATTR2)) { | 330 | } else if (!strcmp(this_char, MNTOPT_ATTR2)) { |
326 | mp->m_flags |= XFS_MOUNT_ATTR2; | 331 | mp->m_flags |= XFS_MOUNT_ATTR2; |
327 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { | 332 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { |
328 | mp->m_flags &= ~XFS_MOUNT_ATTR2; | 333 | mp->m_flags &= ~XFS_MOUNT_ATTR2; |
329 | mp->m_flags |= XFS_MOUNT_NOATTR2; | 334 | mp->m_flags |= XFS_MOUNT_NOATTR2; |
330 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { | 335 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { |
331 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | 336 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; |
332 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { | 337 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { |
333 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; | 338 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; |
334 | mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; | 339 | mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; |
335 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; | 340 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; |
336 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || | 341 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || |
337 | !strcmp(this_char, MNTOPT_UQUOTA) || | 342 | !strcmp(this_char, MNTOPT_UQUOTA) || |
338 | !strcmp(this_char, MNTOPT_USRQUOTA)) { | 343 | !strcmp(this_char, MNTOPT_USRQUOTA)) { |
339 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | | 344 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | |
340 | XFS_UQUOTA_ENFD); | 345 | XFS_UQUOTA_ENFD); |
341 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || | 346 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || |
342 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { | 347 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { |
343 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); | 348 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); |
344 | mp->m_qflags &= ~XFS_UQUOTA_ENFD; | 349 | mp->m_qflags &= ~XFS_UQUOTA_ENFD; |
345 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | 350 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || |
346 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | 351 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { |
347 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | | 352 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | |
348 | XFS_OQUOTA_ENFD); | 353 | XFS_OQUOTA_ENFD); |
349 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | 354 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { |
350 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | 355 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); |
351 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; | 356 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; |
352 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | 357 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || |
353 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | 358 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { |
354 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | | 359 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | |
355 | XFS_OQUOTA_ENFD); | 360 | XFS_OQUOTA_ENFD); |
356 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { | 361 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { |
357 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | 362 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); |
358 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; | 363 | mp->m_qflags &= ~XFS_OQUOTA_ENFD; |
359 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { | 364 | } else if (!strcmp(this_char, MNTOPT_DELAYLOG)) { |
360 | xfs_warn(mp, | 365 | xfs_warn(mp, |
361 | "delaylog is the default now, option is deprecated."); | 366 | "delaylog is the default now, option is deprecated."); |
362 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { | 367 | } else if (!strcmp(this_char, MNTOPT_NODELAYLOG)) { |
363 | xfs_warn(mp, | 368 | xfs_warn(mp, |
364 | "nodelaylog support has been removed, option is deprecated."); | 369 | "nodelaylog support has been removed, option is deprecated."); |
365 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { | 370 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { |
366 | mp->m_flags |= XFS_MOUNT_DISCARD; | 371 | mp->m_flags |= XFS_MOUNT_DISCARD; |
367 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { | 372 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { |
368 | mp->m_flags &= ~XFS_MOUNT_DISCARD; | 373 | mp->m_flags &= ~XFS_MOUNT_DISCARD; |
369 | } else if (!strcmp(this_char, "ihashsize")) { | 374 | } else if (!strcmp(this_char, "ihashsize")) { |
370 | xfs_warn(mp, | 375 | xfs_warn(mp, |
371 | "ihashsize no longer used, option is deprecated."); | 376 | "ihashsize no longer used, option is deprecated."); |
372 | } else if (!strcmp(this_char, "osyncisdsync")) { | 377 | } else if (!strcmp(this_char, "osyncisdsync")) { |
373 | xfs_warn(mp, | 378 | xfs_warn(mp, |
374 | "osyncisdsync has no effect, option is deprecated."); | 379 | "osyncisdsync has no effect, option is deprecated."); |
375 | } else if (!strcmp(this_char, "osyncisosync")) { | 380 | } else if (!strcmp(this_char, "osyncisosync")) { |
376 | xfs_warn(mp, | 381 | xfs_warn(mp, |
377 | "osyncisosync has no effect, option is deprecated."); | 382 | "osyncisosync has no effect, option is deprecated."); |
378 | } else if (!strcmp(this_char, "irixsgid")) { | 383 | } else if (!strcmp(this_char, "irixsgid")) { |
379 | xfs_warn(mp, | 384 | xfs_warn(mp, |
380 | "irixsgid is now a sysctl(2) variable, option is deprecated."); | 385 | "irixsgid is now a sysctl(2) variable, option is deprecated."); |
381 | } else { | 386 | } else { |
382 | xfs_warn(mp, "unknown mount option [%s].", this_char); | 387 | xfs_warn(mp, "unknown mount option [%s].", this_char); |
383 | return EINVAL; | 388 | return EINVAL; |
384 | } | 389 | } |
385 | } | 390 | } |
386 | 391 | ||
387 | /* | 392 | /* |
388 | * no recovery flag requires a read-only mount | 393 | * no recovery flag requires a read-only mount |
389 | */ | 394 | */ |
390 | if ((mp->m_flags & XFS_MOUNT_NORECOVERY) && | 395 | if ((mp->m_flags & XFS_MOUNT_NORECOVERY) && |
391 | !(mp->m_flags & XFS_MOUNT_RDONLY)) { | 396 | !(mp->m_flags & XFS_MOUNT_RDONLY)) { |
392 | xfs_warn(mp, "no-recovery mounts must be read-only."); | 397 | xfs_warn(mp, "no-recovery mounts must be read-only."); |
393 | return EINVAL; | 398 | return EINVAL; |
394 | } | 399 | } |
395 | 400 | ||
396 | if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) { | 401 | if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) { |
397 | xfs_warn(mp, | 402 | xfs_warn(mp, |
398 | "sunit and swidth options incompatible with the noalign option"); | 403 | "sunit and swidth options incompatible with the noalign option"); |
399 | return EINVAL; | 404 | return EINVAL; |
400 | } | 405 | } |
401 | 406 | ||
402 | #ifndef CONFIG_XFS_QUOTA | 407 | #ifndef CONFIG_XFS_QUOTA |
403 | if (XFS_IS_QUOTA_RUNNING(mp)) { | 408 | if (XFS_IS_QUOTA_RUNNING(mp)) { |
404 | xfs_warn(mp, "quota support not available in this kernel."); | 409 | xfs_warn(mp, "quota support not available in this kernel."); |
405 | return EINVAL; | 410 | return EINVAL; |
406 | } | 411 | } |
407 | #endif | 412 | #endif |
408 | 413 | ||
409 | if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) && | 414 | if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) && |
410 | (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) { | 415 | (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) { |
411 | xfs_warn(mp, "cannot mount with both project and group quota"); | 416 | xfs_warn(mp, "cannot mount with both project and group quota"); |
412 | return EINVAL; | 417 | return EINVAL; |
413 | } | 418 | } |
414 | 419 | ||
415 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { | 420 | if ((dsunit && !dswidth) || (!dsunit && dswidth)) { |
416 | xfs_warn(mp, "sunit and swidth must be specified together"); | 421 | xfs_warn(mp, "sunit and swidth must be specified together"); |
417 | return EINVAL; | 422 | return EINVAL; |
418 | } | 423 | } |
419 | 424 | ||
420 | if (dsunit && (dswidth % dsunit != 0)) { | 425 | if (dsunit && (dswidth % dsunit != 0)) { |
421 | xfs_warn(mp, | 426 | xfs_warn(mp, |
422 | "stripe width (%d) must be a multiple of the stripe unit (%d)", | 427 | "stripe width (%d) must be a multiple of the stripe unit (%d)", |
423 | dswidth, dsunit); | 428 | dswidth, dsunit); |
424 | return EINVAL; | 429 | return EINVAL; |
425 | } | 430 | } |
426 | 431 | ||
427 | done: | 432 | done: |
428 | if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) { | 433 | if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) { |
429 | /* | 434 | /* |
430 | * At this point the superblock has not been read | 435 | * At this point the superblock has not been read |
431 | * in, therefore we do not know the block size. | 436 | * in, therefore we do not know the block size. |
432 | * Before the mount call ends we will convert | 437 | * Before the mount call ends we will convert |
433 | * these to FSBs. | 438 | * these to FSBs. |
434 | */ | 439 | */ |
435 | if (dsunit) { | 440 | if (dsunit) { |
436 | mp->m_dalign = dsunit; | 441 | mp->m_dalign = dsunit; |
437 | mp->m_flags |= XFS_MOUNT_RETERR; | 442 | mp->m_flags |= XFS_MOUNT_RETERR; |
438 | } | 443 | } |
439 | 444 | ||
440 | if (dswidth) | 445 | if (dswidth) |
441 | mp->m_swidth = dswidth; | 446 | mp->m_swidth = dswidth; |
442 | } | 447 | } |
443 | 448 | ||
444 | if (mp->m_logbufs != -1 && | 449 | if (mp->m_logbufs != -1 && |
445 | mp->m_logbufs != 0 && | 450 | mp->m_logbufs != 0 && |
446 | (mp->m_logbufs < XLOG_MIN_ICLOGS || | 451 | (mp->m_logbufs < XLOG_MIN_ICLOGS || |
447 | mp->m_logbufs > XLOG_MAX_ICLOGS)) { | 452 | mp->m_logbufs > XLOG_MAX_ICLOGS)) { |
448 | xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]", | 453 | xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]", |
449 | mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); | 454 | mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); |
450 | return XFS_ERROR(EINVAL); | 455 | return XFS_ERROR(EINVAL); |
451 | } | 456 | } |
452 | if (mp->m_logbsize != -1 && | 457 | if (mp->m_logbsize != -1 && |
453 | mp->m_logbsize != 0 && | 458 | mp->m_logbsize != 0 && |
454 | (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE || | 459 | (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE || |
455 | mp->m_logbsize > XLOG_MAX_RECORD_BSIZE || | 460 | mp->m_logbsize > XLOG_MAX_RECORD_BSIZE || |
456 | !is_power_of_2(mp->m_logbsize))) { | 461 | !is_power_of_2(mp->m_logbsize))) { |
457 | xfs_warn(mp, | 462 | xfs_warn(mp, |
458 | "invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", | 463 | "invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", |
459 | mp->m_logbsize); | 464 | mp->m_logbsize); |
460 | return XFS_ERROR(EINVAL); | 465 | return XFS_ERROR(EINVAL); |
461 | } | 466 | } |
462 | 467 | ||
463 | if (iosizelog) { | 468 | if (iosizelog) { |
464 | if (iosizelog > XFS_MAX_IO_LOG || | 469 | if (iosizelog > XFS_MAX_IO_LOG || |
465 | iosizelog < XFS_MIN_IO_LOG) { | 470 | iosizelog < XFS_MIN_IO_LOG) { |
466 | xfs_warn(mp, "invalid log iosize: %d [not %d-%d]", | 471 | xfs_warn(mp, "invalid log iosize: %d [not %d-%d]", |
467 | iosizelog, XFS_MIN_IO_LOG, | 472 | iosizelog, XFS_MIN_IO_LOG, |
468 | XFS_MAX_IO_LOG); | 473 | XFS_MAX_IO_LOG); |
469 | return XFS_ERROR(EINVAL); | 474 | return XFS_ERROR(EINVAL); |
470 | } | 475 | } |
471 | 476 | ||
472 | mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; | 477 | mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; |
473 | mp->m_readio_log = iosizelog; | 478 | mp->m_readio_log = iosizelog; |
474 | mp->m_writeio_log = iosizelog; | 479 | mp->m_writeio_log = iosizelog; |
475 | } | 480 | } |
476 | 481 | ||
477 | return 0; | 482 | return 0; |
478 | } | 483 | } |
479 | 484 | ||
480 | struct proc_xfs_info { | 485 | struct proc_xfs_info { |
481 | int flag; | 486 | int flag; |
482 | char *str; | 487 | char *str; |
483 | }; | 488 | }; |
484 | 489 | ||
485 | STATIC int | 490 | STATIC int |
486 | xfs_showargs( | 491 | xfs_showargs( |
487 | struct xfs_mount *mp, | 492 | struct xfs_mount *mp, |
488 | struct seq_file *m) | 493 | struct seq_file *m) |
489 | { | 494 | { |
490 | static struct proc_xfs_info xfs_info_set[] = { | 495 | static struct proc_xfs_info xfs_info_set[] = { |
491 | /* the few simple ones we can get from the mount struct */ | 496 | /* the few simple ones we can get from the mount struct */ |
492 | { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, | 497 | { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, |
493 | { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, | 498 | { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, |
494 | { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, | 499 | { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, |
495 | { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, | 500 | { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, |
496 | { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, | 501 | { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, |
497 | { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, | 502 | { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, |
498 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, | 503 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, |
499 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, | 504 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, |
500 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, | 505 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, |
501 | { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, | 506 | { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, |
502 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE }, | 507 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE }, |
503 | { 0, NULL } | 508 | { 0, NULL } |
504 | }; | 509 | }; |
505 | static struct proc_xfs_info xfs_info_unset[] = { | 510 | static struct proc_xfs_info xfs_info_unset[] = { |
506 | /* the few simple ones we can get from the mount struct */ | 511 | /* the few simple ones we can get from the mount struct */ |
507 | { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, | 512 | { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, |
508 | { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, | 513 | { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, |
509 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, | 514 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, |
510 | { 0, NULL } | 515 | { 0, NULL } |
511 | }; | 516 | }; |
512 | struct proc_xfs_info *xfs_infop; | 517 | struct proc_xfs_info *xfs_infop; |
513 | 518 | ||
514 | for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) { | 519 | for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) { |
515 | if (mp->m_flags & xfs_infop->flag) | 520 | if (mp->m_flags & xfs_infop->flag) |
516 | seq_puts(m, xfs_infop->str); | 521 | seq_puts(m, xfs_infop->str); |
517 | } | 522 | } |
518 | for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) { | 523 | for (xfs_infop = xfs_info_unset; xfs_infop->flag; xfs_infop++) { |
519 | if (!(mp->m_flags & xfs_infop->flag)) | 524 | if (!(mp->m_flags & xfs_infop->flag)) |
520 | seq_puts(m, xfs_infop->str); | 525 | seq_puts(m, xfs_infop->str); |
521 | } | 526 | } |
522 | 527 | ||
523 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) | 528 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) |
524 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", | 529 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", |
525 | (int)(1 << mp->m_writeio_log) >> 10); | 530 | (int)(1 << mp->m_writeio_log) >> 10); |
526 | 531 | ||
527 | if (mp->m_logbufs > 0) | 532 | if (mp->m_logbufs > 0) |
528 | seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); | 533 | seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); |
529 | if (mp->m_logbsize > 0) | 534 | if (mp->m_logbsize > 0) |
530 | seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); | 535 | seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); |
531 | 536 | ||
532 | if (mp->m_logname) | 537 | if (mp->m_logname) |
533 | seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname); | 538 | seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname); |
534 | if (mp->m_rtname) | 539 | if (mp->m_rtname) |
535 | seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname); | 540 | seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname); |
536 | 541 | ||
537 | if (mp->m_dalign > 0) | 542 | if (mp->m_dalign > 0) |
538 | seq_printf(m, "," MNTOPT_SUNIT "=%d", | 543 | seq_printf(m, "," MNTOPT_SUNIT "=%d", |
539 | (int)XFS_FSB_TO_BB(mp, mp->m_dalign)); | 544 | (int)XFS_FSB_TO_BB(mp, mp->m_dalign)); |
540 | if (mp->m_swidth > 0) | 545 | if (mp->m_swidth > 0) |
541 | seq_printf(m, "," MNTOPT_SWIDTH "=%d", | 546 | seq_printf(m, "," MNTOPT_SWIDTH "=%d", |
542 | (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); | 547 | (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); |
543 | 548 | ||
544 | if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) | 549 | if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) |
545 | seq_puts(m, "," MNTOPT_USRQUOTA); | 550 | seq_puts(m, "," MNTOPT_USRQUOTA); |
546 | else if (mp->m_qflags & XFS_UQUOTA_ACCT) | 551 | else if (mp->m_qflags & XFS_UQUOTA_ACCT) |
547 | seq_puts(m, "," MNTOPT_UQUOTANOENF); | 552 | seq_puts(m, "," MNTOPT_UQUOTANOENF); |
548 | 553 | ||
549 | /* Either project or group quotas can be active, not both */ | 554 | /* Either project or group quotas can be active, not both */ |
550 | 555 | ||
551 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { | 556 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { |
552 | if (mp->m_qflags & XFS_OQUOTA_ENFD) | 557 | if (mp->m_qflags & XFS_OQUOTA_ENFD) |
553 | seq_puts(m, "," MNTOPT_PRJQUOTA); | 558 | seq_puts(m, "," MNTOPT_PRJQUOTA); |
554 | else | 559 | else |
555 | seq_puts(m, "," MNTOPT_PQUOTANOENF); | 560 | seq_puts(m, "," MNTOPT_PQUOTANOENF); |
556 | } else if (mp->m_qflags & XFS_GQUOTA_ACCT) { | 561 | } else if (mp->m_qflags & XFS_GQUOTA_ACCT) { |
557 | if (mp->m_qflags & XFS_OQUOTA_ENFD) | 562 | if (mp->m_qflags & XFS_OQUOTA_ENFD) |
558 | seq_puts(m, "," MNTOPT_GRPQUOTA); | 563 | seq_puts(m, "," MNTOPT_GRPQUOTA); |
559 | else | 564 | else |
560 | seq_puts(m, "," MNTOPT_GQUOTANOENF); | 565 | seq_puts(m, "," MNTOPT_GQUOTANOENF); |
561 | } | 566 | } |
562 | 567 | ||
563 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) | 568 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) |
564 | seq_puts(m, "," MNTOPT_NOQUOTA); | 569 | seq_puts(m, "," MNTOPT_NOQUOTA); |
565 | 570 | ||
566 | return 0; | 571 | return 0; |
567 | } | 572 | } |
568 | __uint64_t | 573 | __uint64_t |
569 | xfs_max_file_offset( | 574 | xfs_max_file_offset( |
570 | unsigned int blockshift) | 575 | unsigned int blockshift) |
571 | { | 576 | { |
572 | unsigned int pagefactor = 1; | 577 | unsigned int pagefactor = 1; |
573 | unsigned int bitshift = BITS_PER_LONG - 1; | 578 | unsigned int bitshift = BITS_PER_LONG - 1; |
574 | 579 | ||
575 | /* Figure out maximum filesize, on Linux this can depend on | 580 | /* Figure out maximum filesize, on Linux this can depend on |
576 | * the filesystem blocksize (on 32 bit platforms). | 581 | * the filesystem blocksize (on 32 bit platforms). |
577 | * __block_write_begin does this in an [unsigned] long... | 582 | * __block_write_begin does this in an [unsigned] long... |
578 | * page->index << (PAGE_CACHE_SHIFT - bbits) | 583 | * page->index << (PAGE_CACHE_SHIFT - bbits) |
579 | * So, for page sized blocks (4K on 32 bit platforms), | 584 | * So, for page sized blocks (4K on 32 bit platforms), |
580 | * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is | 585 | * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is |
581 | * (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) | 586 | * (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) |
582 | * but for smaller blocksizes it is less (bbits = log2 bsize). | 587 | * but for smaller blocksizes it is less (bbits = log2 bsize). |
583 | * Note1: get_block_t takes a long (implicit cast from above) | 588 | * Note1: get_block_t takes a long (implicit cast from above) |
584 | * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch | 589 | * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch |
585 | * can optionally convert the [unsigned] long from above into | 590 | * can optionally convert the [unsigned] long from above into |
586 | * an [unsigned] long long. | 591 | * an [unsigned] long long. |
587 | */ | 592 | */ |
588 | 593 | ||
589 | #if BITS_PER_LONG == 32 | 594 | #if BITS_PER_LONG == 32 |
590 | # if defined(CONFIG_LBDAF) | 595 | # if defined(CONFIG_LBDAF) |
591 | ASSERT(sizeof(sector_t) == 8); | 596 | ASSERT(sizeof(sector_t) == 8); |
592 | pagefactor = PAGE_CACHE_SIZE; | 597 | pagefactor = PAGE_CACHE_SIZE; |
593 | bitshift = BITS_PER_LONG; | 598 | bitshift = BITS_PER_LONG; |
594 | # else | 599 | # else |
595 | pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift); | 600 | pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift); |
596 | # endif | 601 | # endif |
597 | #endif | 602 | #endif |
598 | 603 | ||
599 | return (((__uint64_t)pagefactor) << bitshift) - 1; | 604 | return (((__uint64_t)pagefactor) << bitshift) - 1; |
600 | } | 605 | } |
601 | 606 | ||
602 | xfs_agnumber_t | 607 | xfs_agnumber_t |
603 | xfs_set_inode32(struct xfs_mount *mp) | 608 | xfs_set_inode32(struct xfs_mount *mp) |
604 | { | 609 | { |
605 | xfs_agnumber_t index = 0; | 610 | xfs_agnumber_t index = 0; |
606 | xfs_agnumber_t maxagi = 0; | 611 | xfs_agnumber_t maxagi = 0; |
607 | xfs_sb_t *sbp = &mp->m_sb; | 612 | xfs_sb_t *sbp = &mp->m_sb; |
608 | xfs_agnumber_t max_metadata; | 613 | xfs_agnumber_t max_metadata; |
609 | xfs_agino_t agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0); | 614 | xfs_agino_t agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0); |
610 | xfs_ino_t ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino); | 615 | xfs_ino_t ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino); |
611 | xfs_perag_t *pag; | 616 | xfs_perag_t *pag; |
612 | 617 | ||
613 | /* Calculate how much should be reserved for inodes to meet | 618 | /* Calculate how much should be reserved for inodes to meet |
614 | * the max inode percentage. | 619 | * the max inode percentage. |
615 | */ | 620 | */ |
616 | if (mp->m_maxicount) { | 621 | if (mp->m_maxicount) { |
617 | __uint64_t icount; | 622 | __uint64_t icount; |
618 | 623 | ||
619 | icount = sbp->sb_dblocks * sbp->sb_imax_pct; | 624 | icount = sbp->sb_dblocks * sbp->sb_imax_pct; |
620 | do_div(icount, 100); | 625 | do_div(icount, 100); |
621 | icount += sbp->sb_agblocks - 1; | 626 | icount += sbp->sb_agblocks - 1; |
622 | do_div(icount, sbp->sb_agblocks); | 627 | do_div(icount, sbp->sb_agblocks); |
623 | max_metadata = icount; | 628 | max_metadata = icount; |
624 | } else { | 629 | } else { |
625 | max_metadata = sbp->sb_agcount; | 630 | max_metadata = sbp->sb_agcount; |
626 | } | 631 | } |
627 | 632 | ||
628 | for (index = 0; index < sbp->sb_agcount; index++) { | 633 | for (index = 0; index < sbp->sb_agcount; index++) { |
629 | ino = XFS_AGINO_TO_INO(mp, index, agino); | 634 | ino = XFS_AGINO_TO_INO(mp, index, agino); |
630 | 635 | ||
631 | if (ino > XFS_MAXINUMBER_32) { | 636 | if (ino > XFS_MAXINUMBER_32) { |
632 | pag = xfs_perag_get(mp, index); | 637 | pag = xfs_perag_get(mp, index); |
633 | pag->pagi_inodeok = 0; | 638 | pag->pagi_inodeok = 0; |
634 | pag->pagf_metadata = 0; | 639 | pag->pagf_metadata = 0; |
635 | xfs_perag_put(pag); | 640 | xfs_perag_put(pag); |
636 | continue; | 641 | continue; |
637 | } | 642 | } |
638 | 643 | ||
639 | pag = xfs_perag_get(mp, index); | 644 | pag = xfs_perag_get(mp, index); |
640 | pag->pagi_inodeok = 1; | 645 | pag->pagi_inodeok = 1; |
641 | maxagi++; | 646 | maxagi++; |
642 | if (index < max_metadata) | 647 | if (index < max_metadata) |
643 | pag->pagf_metadata = 1; | 648 | pag->pagf_metadata = 1; |
644 | xfs_perag_put(pag); | 649 | xfs_perag_put(pag); |
645 | } | 650 | } |
646 | mp->m_flags |= (XFS_MOUNT_32BITINODES | | 651 | mp->m_flags |= (XFS_MOUNT_32BITINODES | |
647 | XFS_MOUNT_SMALL_INUMS); | 652 | XFS_MOUNT_SMALL_INUMS); |
648 | 653 | ||
649 | return maxagi; | 654 | return maxagi; |
650 | } | 655 | } |
651 | 656 | ||
652 | xfs_agnumber_t | 657 | xfs_agnumber_t |
653 | xfs_set_inode64(struct xfs_mount *mp) | 658 | xfs_set_inode64(struct xfs_mount *mp) |
654 | { | 659 | { |
655 | xfs_agnumber_t index = 0; | 660 | xfs_agnumber_t index = 0; |
656 | 661 | ||
657 | for (index = 0; index < mp->m_sb.sb_agcount; index++) { | 662 | for (index = 0; index < mp->m_sb.sb_agcount; index++) { |
658 | struct xfs_perag *pag; | 663 | struct xfs_perag *pag; |
659 | 664 | ||
660 | pag = xfs_perag_get(mp, index); | 665 | pag = xfs_perag_get(mp, index); |
661 | pag->pagi_inodeok = 1; | 666 | pag->pagi_inodeok = 1; |
662 | pag->pagf_metadata = 0; | 667 | pag->pagf_metadata = 0; |
663 | xfs_perag_put(pag); | 668 | xfs_perag_put(pag); |
664 | } | 669 | } |
665 | 670 | ||
666 | /* There is no need for lock protection on m_flags, | 671 | /* There is no need for lock protection on m_flags, |
667 | * the rw_semaphore of the VFS superblock is locked | 672 | * the rw_semaphore of the VFS superblock is locked |
668 | * during mount/umount/remount operations, so this is | 673 | * during mount/umount/remount operations, so this is |
669 | * enough to avoid concurency on the m_flags field | 674 | * enough to avoid concurency on the m_flags field |
670 | */ | 675 | */ |
671 | mp->m_flags &= ~(XFS_MOUNT_32BITINODES | | 676 | mp->m_flags &= ~(XFS_MOUNT_32BITINODES | |
672 | XFS_MOUNT_SMALL_INUMS); | 677 | XFS_MOUNT_SMALL_INUMS); |
673 | return index; | 678 | return index; |
674 | } | 679 | } |
675 | 680 | ||
676 | STATIC int | 681 | STATIC int |
677 | xfs_blkdev_get( | 682 | xfs_blkdev_get( |
678 | xfs_mount_t *mp, | 683 | xfs_mount_t *mp, |
679 | const char *name, | 684 | const char *name, |
680 | struct block_device **bdevp) | 685 | struct block_device **bdevp) |
681 | { | 686 | { |
682 | int error = 0; | 687 | int error = 0; |
683 | 688 | ||
684 | *bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL, | 689 | *bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL, |
685 | mp); | 690 | mp); |
686 | if (IS_ERR(*bdevp)) { | 691 | if (IS_ERR(*bdevp)) { |
687 | error = PTR_ERR(*bdevp); | 692 | error = PTR_ERR(*bdevp); |
688 | xfs_warn(mp, "Invalid device [%s], error=%d\n", name, error); | 693 | xfs_warn(mp, "Invalid device [%s], error=%d\n", name, error); |
689 | } | 694 | } |
690 | 695 | ||
691 | return -error; | 696 | return -error; |
692 | } | 697 | } |
693 | 698 | ||
694 | STATIC void | 699 | STATIC void |
695 | xfs_blkdev_put( | 700 | xfs_blkdev_put( |
696 | struct block_device *bdev) | 701 | struct block_device *bdev) |
697 | { | 702 | { |
698 | if (bdev) | 703 | if (bdev) |
699 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); | 704 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); |
700 | } | 705 | } |
701 | 706 | ||
702 | void | 707 | void |
703 | xfs_blkdev_issue_flush( | 708 | xfs_blkdev_issue_flush( |
704 | xfs_buftarg_t *buftarg) | 709 | xfs_buftarg_t *buftarg) |
705 | { | 710 | { |
706 | blkdev_issue_flush(buftarg->bt_bdev, GFP_NOFS, NULL); | 711 | blkdev_issue_flush(buftarg->bt_bdev, GFP_NOFS, NULL); |
707 | } | 712 | } |
708 | 713 | ||
709 | STATIC void | 714 | STATIC void |
710 | xfs_close_devices( | 715 | xfs_close_devices( |
711 | struct xfs_mount *mp) | 716 | struct xfs_mount *mp) |
712 | { | 717 | { |
713 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { | 718 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { |
714 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; | 719 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; |
715 | xfs_free_buftarg(mp, mp->m_logdev_targp); | 720 | xfs_free_buftarg(mp, mp->m_logdev_targp); |
716 | xfs_blkdev_put(logdev); | 721 | xfs_blkdev_put(logdev); |
717 | } | 722 | } |
718 | if (mp->m_rtdev_targp) { | 723 | if (mp->m_rtdev_targp) { |
719 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; | 724 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; |
720 | xfs_free_buftarg(mp, mp->m_rtdev_targp); | 725 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
721 | xfs_blkdev_put(rtdev); | 726 | xfs_blkdev_put(rtdev); |
722 | } | 727 | } |
723 | xfs_free_buftarg(mp, mp->m_ddev_targp); | 728 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
724 | } | 729 | } |
725 | 730 | ||
726 | /* | 731 | /* |
727 | * The file system configurations are: | 732 | * The file system configurations are: |
728 | * (1) device (partition) with data and internal log | 733 | * (1) device (partition) with data and internal log |
729 | * (2) logical volume with data and log subvolumes. | 734 | * (2) logical volume with data and log subvolumes. |
730 | * (3) logical volume with data, log, and realtime subvolumes. | 735 | * (3) logical volume with data, log, and realtime subvolumes. |
731 | * | 736 | * |
732 | * We only have to handle opening the log and realtime volumes here if | 737 | * We only have to handle opening the log and realtime volumes here if |
733 | * they are present. The data subvolume has already been opened by | 738 | * they are present. The data subvolume has already been opened by |
734 | * get_sb_bdev() and is stored in sb->s_bdev. | 739 | * get_sb_bdev() and is stored in sb->s_bdev. |
735 | */ | 740 | */ |
736 | STATIC int | 741 | STATIC int |
737 | xfs_open_devices( | 742 | xfs_open_devices( |
738 | struct xfs_mount *mp) | 743 | struct xfs_mount *mp) |
739 | { | 744 | { |
740 | struct block_device *ddev = mp->m_super->s_bdev; | 745 | struct block_device *ddev = mp->m_super->s_bdev; |
741 | struct block_device *logdev = NULL, *rtdev = NULL; | 746 | struct block_device *logdev = NULL, *rtdev = NULL; |
742 | int error; | 747 | int error; |
743 | 748 | ||
744 | /* | 749 | /* |
745 | * Open real time and log devices - order is important. | 750 | * Open real time and log devices - order is important. |
746 | */ | 751 | */ |
747 | if (mp->m_logname) { | 752 | if (mp->m_logname) { |
748 | error = xfs_blkdev_get(mp, mp->m_logname, &logdev); | 753 | error = xfs_blkdev_get(mp, mp->m_logname, &logdev); |
749 | if (error) | 754 | if (error) |
750 | goto out; | 755 | goto out; |
751 | } | 756 | } |
752 | 757 | ||
753 | if (mp->m_rtname) { | 758 | if (mp->m_rtname) { |
754 | error = xfs_blkdev_get(mp, mp->m_rtname, &rtdev); | 759 | error = xfs_blkdev_get(mp, mp->m_rtname, &rtdev); |
755 | if (error) | 760 | if (error) |
756 | goto out_close_logdev; | 761 | goto out_close_logdev; |
757 | 762 | ||
758 | if (rtdev == ddev || rtdev == logdev) { | 763 | if (rtdev == ddev || rtdev == logdev) { |
759 | xfs_warn(mp, | 764 | xfs_warn(mp, |
760 | "Cannot mount filesystem with identical rtdev and ddev/logdev."); | 765 | "Cannot mount filesystem with identical rtdev and ddev/logdev."); |
761 | error = EINVAL; | 766 | error = EINVAL; |
762 | goto out_close_rtdev; | 767 | goto out_close_rtdev; |
763 | } | 768 | } |
764 | } | 769 | } |
765 | 770 | ||
766 | /* | 771 | /* |
767 | * Setup xfs_mount buffer target pointers | 772 | * Setup xfs_mount buffer target pointers |
768 | */ | 773 | */ |
769 | error = ENOMEM; | 774 | error = ENOMEM; |
770 | mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, 0, mp->m_fsname); | 775 | mp->m_ddev_targp = xfs_alloc_buftarg(mp, ddev, 0, mp->m_fsname); |
771 | if (!mp->m_ddev_targp) | 776 | if (!mp->m_ddev_targp) |
772 | goto out_close_rtdev; | 777 | goto out_close_rtdev; |
773 | 778 | ||
774 | if (rtdev) { | 779 | if (rtdev) { |
775 | mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, 1, | 780 | mp->m_rtdev_targp = xfs_alloc_buftarg(mp, rtdev, 1, |
776 | mp->m_fsname); | 781 | mp->m_fsname); |
777 | if (!mp->m_rtdev_targp) | 782 | if (!mp->m_rtdev_targp) |
778 | goto out_free_ddev_targ; | 783 | goto out_free_ddev_targ; |
779 | } | 784 | } |
780 | 785 | ||
781 | if (logdev && logdev != ddev) { | 786 | if (logdev && logdev != ddev) { |
782 | mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, 1, | 787 | mp->m_logdev_targp = xfs_alloc_buftarg(mp, logdev, 1, |
783 | mp->m_fsname); | 788 | mp->m_fsname); |
784 | if (!mp->m_logdev_targp) | 789 | if (!mp->m_logdev_targp) |
785 | goto out_free_rtdev_targ; | 790 | goto out_free_rtdev_targ; |
786 | } else { | 791 | } else { |
787 | mp->m_logdev_targp = mp->m_ddev_targp; | 792 | mp->m_logdev_targp = mp->m_ddev_targp; |
788 | } | 793 | } |
789 | 794 | ||
790 | return 0; | 795 | return 0; |
791 | 796 | ||
792 | out_free_rtdev_targ: | 797 | out_free_rtdev_targ: |
793 | if (mp->m_rtdev_targp) | 798 | if (mp->m_rtdev_targp) |
794 | xfs_free_buftarg(mp, mp->m_rtdev_targp); | 799 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
795 | out_free_ddev_targ: | 800 | out_free_ddev_targ: |
796 | xfs_free_buftarg(mp, mp->m_ddev_targp); | 801 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
797 | out_close_rtdev: | 802 | out_close_rtdev: |
798 | if (rtdev) | 803 | if (rtdev) |
799 | xfs_blkdev_put(rtdev); | 804 | xfs_blkdev_put(rtdev); |
800 | out_close_logdev: | 805 | out_close_logdev: |
801 | if (logdev && logdev != ddev) | 806 | if (logdev && logdev != ddev) |
802 | xfs_blkdev_put(logdev); | 807 | xfs_blkdev_put(logdev); |
803 | out: | 808 | out: |
804 | return error; | 809 | return error; |
805 | } | 810 | } |
806 | 811 | ||
807 | /* | 812 | /* |
808 | * Setup xfs_mount buffer target pointers based on superblock | 813 | * Setup xfs_mount buffer target pointers based on superblock |
809 | */ | 814 | */ |
810 | STATIC int | 815 | STATIC int |
811 | xfs_setup_devices( | 816 | xfs_setup_devices( |
812 | struct xfs_mount *mp) | 817 | struct xfs_mount *mp) |
813 | { | 818 | { |
814 | int error; | 819 | int error; |
815 | 820 | ||
816 | error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, | 821 | error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, |
817 | mp->m_sb.sb_sectsize); | 822 | mp->m_sb.sb_sectsize); |
818 | if (error) | 823 | if (error) |
819 | return error; | 824 | return error; |
820 | 825 | ||
821 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { | 826 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { |
822 | unsigned int log_sector_size = BBSIZE; | 827 | unsigned int log_sector_size = BBSIZE; |
823 | 828 | ||
824 | if (xfs_sb_version_hassector(&mp->m_sb)) | 829 | if (xfs_sb_version_hassector(&mp->m_sb)) |
825 | log_sector_size = mp->m_sb.sb_logsectsize; | 830 | log_sector_size = mp->m_sb.sb_logsectsize; |
826 | error = xfs_setsize_buftarg(mp->m_logdev_targp, | 831 | error = xfs_setsize_buftarg(mp->m_logdev_targp, |
827 | mp->m_sb.sb_blocksize, | 832 | mp->m_sb.sb_blocksize, |
828 | log_sector_size); | 833 | log_sector_size); |
829 | if (error) | 834 | if (error) |
830 | return error; | 835 | return error; |
831 | } | 836 | } |
832 | if (mp->m_rtdev_targp) { | 837 | if (mp->m_rtdev_targp) { |
833 | error = xfs_setsize_buftarg(mp->m_rtdev_targp, | 838 | error = xfs_setsize_buftarg(mp->m_rtdev_targp, |
834 | mp->m_sb.sb_blocksize, | 839 | mp->m_sb.sb_blocksize, |
835 | mp->m_sb.sb_sectsize); | 840 | mp->m_sb.sb_sectsize); |
836 | if (error) | 841 | if (error) |
837 | return error; | 842 | return error; |
838 | } | 843 | } |
839 | 844 | ||
840 | return 0; | 845 | return 0; |
841 | } | 846 | } |
842 | 847 | ||
843 | STATIC int | 848 | STATIC int |
844 | xfs_init_mount_workqueues( | 849 | xfs_init_mount_workqueues( |
845 | struct xfs_mount *mp) | 850 | struct xfs_mount *mp) |
846 | { | 851 | { |
847 | mp->m_data_workqueue = alloc_workqueue("xfs-data/%s", | 852 | mp->m_data_workqueue = alloc_workqueue("xfs-data/%s", |
848 | WQ_MEM_RECLAIM, 0, mp->m_fsname); | 853 | WQ_MEM_RECLAIM, 0, mp->m_fsname); |
849 | if (!mp->m_data_workqueue) | 854 | if (!mp->m_data_workqueue) |
850 | goto out; | 855 | goto out; |
851 | 856 | ||
852 | mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s", | 857 | mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s", |
853 | WQ_MEM_RECLAIM, 0, mp->m_fsname); | 858 | WQ_MEM_RECLAIM, 0, mp->m_fsname); |
854 | if (!mp->m_unwritten_workqueue) | 859 | if (!mp->m_unwritten_workqueue) |
855 | goto out_destroy_data_iodone_queue; | 860 | goto out_destroy_data_iodone_queue; |
856 | 861 | ||
857 | mp->m_cil_workqueue = alloc_workqueue("xfs-cil/%s", | 862 | mp->m_cil_workqueue = alloc_workqueue("xfs-cil/%s", |
858 | WQ_MEM_RECLAIM, 0, mp->m_fsname); | 863 | WQ_MEM_RECLAIM, 0, mp->m_fsname); |
859 | if (!mp->m_cil_workqueue) | 864 | if (!mp->m_cil_workqueue) |
860 | goto out_destroy_unwritten; | 865 | goto out_destroy_unwritten; |
861 | return 0; | 866 | return 0; |
862 | 867 | ||
863 | out_destroy_unwritten: | 868 | out_destroy_unwritten: |
864 | destroy_workqueue(mp->m_unwritten_workqueue); | 869 | destroy_workqueue(mp->m_unwritten_workqueue); |
865 | out_destroy_data_iodone_queue: | 870 | out_destroy_data_iodone_queue: |
866 | destroy_workqueue(mp->m_data_workqueue); | 871 | destroy_workqueue(mp->m_data_workqueue); |
867 | out: | 872 | out: |
868 | return -ENOMEM; | 873 | return -ENOMEM; |
869 | } | 874 | } |
870 | 875 | ||
871 | STATIC void | 876 | STATIC void |
872 | xfs_destroy_mount_workqueues( | 877 | xfs_destroy_mount_workqueues( |
873 | struct xfs_mount *mp) | 878 | struct xfs_mount *mp) |
874 | { | 879 | { |
875 | destroy_workqueue(mp->m_cil_workqueue); | 880 | destroy_workqueue(mp->m_cil_workqueue); |
876 | destroy_workqueue(mp->m_data_workqueue); | 881 | destroy_workqueue(mp->m_data_workqueue); |
877 | destroy_workqueue(mp->m_unwritten_workqueue); | 882 | destroy_workqueue(mp->m_unwritten_workqueue); |
878 | } | 883 | } |
879 | 884 | ||
880 | /* Catch misguided souls that try to use this interface on XFS */ | 885 | /* Catch misguided souls that try to use this interface on XFS */ |
881 | STATIC struct inode * | 886 | STATIC struct inode * |
882 | xfs_fs_alloc_inode( | 887 | xfs_fs_alloc_inode( |
883 | struct super_block *sb) | 888 | struct super_block *sb) |
884 | { | 889 | { |
885 | BUG(); | 890 | BUG(); |
886 | return NULL; | 891 | return NULL; |
887 | } | 892 | } |
888 | 893 | ||
889 | /* | 894 | /* |
890 | * Now that the generic code is guaranteed not to be accessing | 895 | * Now that the generic code is guaranteed not to be accessing |
891 | * the linux inode, we can reclaim the inode. | 896 | * the linux inode, we can reclaim the inode. |
892 | */ | 897 | */ |
893 | STATIC void | 898 | STATIC void |
894 | xfs_fs_destroy_inode( | 899 | xfs_fs_destroy_inode( |
895 | struct inode *inode) | 900 | struct inode *inode) |
896 | { | 901 | { |
897 | struct xfs_inode *ip = XFS_I(inode); | 902 | struct xfs_inode *ip = XFS_I(inode); |
898 | 903 | ||
899 | trace_xfs_destroy_inode(ip); | 904 | trace_xfs_destroy_inode(ip); |
900 | 905 | ||
901 | XFS_STATS_INC(vn_reclaim); | 906 | XFS_STATS_INC(vn_reclaim); |
902 | 907 | ||
903 | /* bad inode, get out here ASAP */ | 908 | /* bad inode, get out here ASAP */ |
904 | if (is_bad_inode(inode)) | 909 | if (is_bad_inode(inode)) |
905 | goto out_reclaim; | 910 | goto out_reclaim; |
906 | 911 | ||
907 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); | 912 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); |
908 | 913 | ||
909 | /* | 914 | /* |
910 | * We should never get here with one of the reclaim flags already set. | 915 | * We should never get here with one of the reclaim flags already set. |
911 | */ | 916 | */ |
912 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | 917 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); |
913 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); | 918 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); |
914 | 919 | ||
915 | /* | 920 | /* |
916 | * We always use background reclaim here because even if the | 921 | * We always use background reclaim here because even if the |
917 | * inode is clean, it still may be under IO and hence we have | 922 | * inode is clean, it still may be under IO and hence we have |
918 | * to take the flush lock. The background reclaim path handles | 923 | * to take the flush lock. The background reclaim path handles |
919 | * this more efficiently than we can here, so simply let background | 924 | * this more efficiently than we can here, so simply let background |
920 | * reclaim tear down all inodes. | 925 | * reclaim tear down all inodes. |
921 | */ | 926 | */ |
922 | out_reclaim: | 927 | out_reclaim: |
923 | xfs_inode_set_reclaim_tag(ip); | 928 | xfs_inode_set_reclaim_tag(ip); |
924 | } | 929 | } |
925 | 930 | ||
926 | /* | 931 | /* |
927 | * Slab object creation initialisation for the XFS inode. | 932 | * Slab object creation initialisation for the XFS inode. |
928 | * This covers only the idempotent fields in the XFS inode; | 933 | * This covers only the idempotent fields in the XFS inode; |
929 | * all other fields need to be initialised on allocation | 934 | * all other fields need to be initialised on allocation |
930 | * from the slab. This avoids the need to repeatedly initialise | 935 | * from the slab. This avoids the need to repeatedly initialise |
931 | * fields in the xfs inode that left in the initialise state | 936 | * fields in the xfs inode that left in the initialise state |
932 | * when freeing the inode. | 937 | * when freeing the inode. |
933 | */ | 938 | */ |
934 | STATIC void | 939 | STATIC void |
935 | xfs_fs_inode_init_once( | 940 | xfs_fs_inode_init_once( |
936 | void *inode) | 941 | void *inode) |
937 | { | 942 | { |
938 | struct xfs_inode *ip = inode; | 943 | struct xfs_inode *ip = inode; |
939 | 944 | ||
940 | memset(ip, 0, sizeof(struct xfs_inode)); | 945 | memset(ip, 0, sizeof(struct xfs_inode)); |
941 | 946 | ||
942 | /* vfs inode */ | 947 | /* vfs inode */ |
943 | inode_init_once(VFS_I(ip)); | 948 | inode_init_once(VFS_I(ip)); |
944 | 949 | ||
945 | /* xfs inode */ | 950 | /* xfs inode */ |
946 | atomic_set(&ip->i_pincount, 0); | 951 | atomic_set(&ip->i_pincount, 0); |
947 | spin_lock_init(&ip->i_flags_lock); | 952 | spin_lock_init(&ip->i_flags_lock); |
948 | 953 | ||
949 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | 954 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, |
950 | "xfsino", ip->i_ino); | 955 | "xfsino", ip->i_ino); |
951 | } | 956 | } |
952 | 957 | ||
953 | STATIC void | 958 | STATIC void |
954 | xfs_fs_evict_inode( | 959 | xfs_fs_evict_inode( |
955 | struct inode *inode) | 960 | struct inode *inode) |
956 | { | 961 | { |
957 | xfs_inode_t *ip = XFS_I(inode); | 962 | xfs_inode_t *ip = XFS_I(inode); |
958 | 963 | ||
959 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); | 964 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); |
960 | 965 | ||
961 | trace_xfs_evict_inode(ip); | 966 | trace_xfs_evict_inode(ip); |
962 | 967 | ||
963 | truncate_inode_pages(&inode->i_data, 0); | 968 | truncate_inode_pages(&inode->i_data, 0); |
964 | clear_inode(inode); | 969 | clear_inode(inode); |
965 | XFS_STATS_INC(vn_rele); | 970 | XFS_STATS_INC(vn_rele); |
966 | XFS_STATS_INC(vn_remove); | 971 | XFS_STATS_INC(vn_remove); |
967 | XFS_STATS_DEC(vn_active); | 972 | XFS_STATS_DEC(vn_active); |
968 | 973 | ||
969 | xfs_inactive(ip); | 974 | xfs_inactive(ip); |
970 | } | 975 | } |
971 | 976 | ||
972 | /* | 977 | /* |
973 | * We do an unlocked check for XFS_IDONTCACHE here because we are already | 978 | * We do an unlocked check for XFS_IDONTCACHE here because we are already |
974 | * serialised against cache hits here via the inode->i_lock and igrab() in | 979 | * serialised against cache hits here via the inode->i_lock and igrab() in |
975 | * xfs_iget_cache_hit(). Hence a lookup that might clear this flag will not be | 980 | * xfs_iget_cache_hit(). Hence a lookup that might clear this flag will not be |
976 | * racing with us, and it avoids needing to grab a spinlock here for every inode | 981 | * racing with us, and it avoids needing to grab a spinlock here for every inode |
977 | * we drop the final reference on. | 982 | * we drop the final reference on. |
978 | */ | 983 | */ |
979 | STATIC int | 984 | STATIC int |
980 | xfs_fs_drop_inode( | 985 | xfs_fs_drop_inode( |
981 | struct inode *inode) | 986 | struct inode *inode) |
982 | { | 987 | { |
983 | struct xfs_inode *ip = XFS_I(inode); | 988 | struct xfs_inode *ip = XFS_I(inode); |
984 | 989 | ||
985 | return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE); | 990 | return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE); |
986 | } | 991 | } |
987 | 992 | ||
988 | STATIC void | 993 | STATIC void |
989 | xfs_free_fsname( | 994 | xfs_free_fsname( |
990 | struct xfs_mount *mp) | 995 | struct xfs_mount *mp) |
991 | { | 996 | { |
992 | kfree(mp->m_fsname); | 997 | kfree(mp->m_fsname); |
993 | kfree(mp->m_rtname); | 998 | kfree(mp->m_rtname); |
994 | kfree(mp->m_logname); | 999 | kfree(mp->m_logname); |
995 | } | 1000 | } |
996 | 1001 | ||
997 | STATIC void | 1002 | STATIC void |
998 | xfs_fs_put_super( | 1003 | xfs_fs_put_super( |
999 | struct super_block *sb) | 1004 | struct super_block *sb) |
1000 | { | 1005 | { |
1001 | struct xfs_mount *mp = XFS_M(sb); | 1006 | struct xfs_mount *mp = XFS_M(sb); |
1002 | 1007 | ||
1003 | xfs_filestream_unmount(mp); | 1008 | xfs_filestream_unmount(mp); |
1004 | cancel_delayed_work_sync(&mp->m_sync_work); | 1009 | cancel_delayed_work_sync(&mp->m_sync_work); |
1005 | xfs_unmountfs(mp); | 1010 | xfs_unmountfs(mp); |
1006 | xfs_syncd_stop(mp); | 1011 | xfs_syncd_stop(mp); |
1007 | xfs_freesb(mp); | 1012 | xfs_freesb(mp); |
1008 | xfs_icsb_destroy_counters(mp); | 1013 | xfs_icsb_destroy_counters(mp); |
1009 | xfs_destroy_mount_workqueues(mp); | 1014 | xfs_destroy_mount_workqueues(mp); |
1010 | xfs_close_devices(mp); | 1015 | xfs_close_devices(mp); |
1011 | xfs_free_fsname(mp); | 1016 | xfs_free_fsname(mp); |
1012 | kfree(mp); | 1017 | kfree(mp); |
1013 | } | 1018 | } |
1014 | 1019 | ||
1015 | STATIC int | 1020 | STATIC int |
1016 | xfs_fs_sync_fs( | 1021 | xfs_fs_sync_fs( |
1017 | struct super_block *sb, | 1022 | struct super_block *sb, |
1018 | int wait) | 1023 | int wait) |
1019 | { | 1024 | { |
1020 | struct xfs_mount *mp = XFS_M(sb); | 1025 | struct xfs_mount *mp = XFS_M(sb); |
1021 | int error; | 1026 | int error; |
1022 | 1027 | ||
1023 | /* | 1028 | /* |
1024 | * Doing anything during the async pass would be counterproductive. | 1029 | * Doing anything during the async pass would be counterproductive. |
1025 | */ | 1030 | */ |
1026 | if (!wait) | 1031 | if (!wait) |
1027 | return 0; | 1032 | return 0; |
1028 | 1033 | ||
1029 | error = xfs_quiesce_data(mp); | 1034 | error = xfs_quiesce_data(mp); |
1030 | if (error) | 1035 | if (error) |
1031 | return -error; | 1036 | return -error; |
1032 | 1037 | ||
1033 | if (laptop_mode) { | 1038 | if (laptop_mode) { |
1034 | /* | 1039 | /* |
1035 | * The disk must be active because we're syncing. | 1040 | * The disk must be active because we're syncing. |
1036 | * We schedule xfssyncd now (now that the disk is | 1041 | * We schedule xfssyncd now (now that the disk is |
1037 | * active) instead of later (when it might not be). | 1042 | * active) instead of later (when it might not be). |
1038 | */ | 1043 | */ |
1039 | flush_delayed_work_sync(&mp->m_sync_work); | 1044 | flush_delayed_work_sync(&mp->m_sync_work); |
1040 | } | 1045 | } |
1041 | 1046 | ||
1042 | return 0; | 1047 | return 0; |
1043 | } | 1048 | } |
1044 | 1049 | ||
1045 | STATIC int | 1050 | STATIC int |
1046 | xfs_fs_statfs( | 1051 | xfs_fs_statfs( |
1047 | struct dentry *dentry, | 1052 | struct dentry *dentry, |
1048 | struct kstatfs *statp) | 1053 | struct kstatfs *statp) |
1049 | { | 1054 | { |
1050 | struct xfs_mount *mp = XFS_M(dentry->d_sb); | 1055 | struct xfs_mount *mp = XFS_M(dentry->d_sb); |
1051 | xfs_sb_t *sbp = &mp->m_sb; | 1056 | xfs_sb_t *sbp = &mp->m_sb; |
1052 | struct xfs_inode *ip = XFS_I(dentry->d_inode); | 1057 | struct xfs_inode *ip = XFS_I(dentry->d_inode); |
1053 | __uint64_t fakeinos, id; | 1058 | __uint64_t fakeinos, id; |
1054 | xfs_extlen_t lsize; | 1059 | xfs_extlen_t lsize; |
1055 | __int64_t ffree; | 1060 | __int64_t ffree; |
1056 | 1061 | ||
1057 | statp->f_type = XFS_SB_MAGIC; | 1062 | statp->f_type = XFS_SB_MAGIC; |
1058 | statp->f_namelen = MAXNAMELEN - 1; | 1063 | statp->f_namelen = MAXNAMELEN - 1; |
1059 | 1064 | ||
1060 | id = huge_encode_dev(mp->m_ddev_targp->bt_dev); | 1065 | id = huge_encode_dev(mp->m_ddev_targp->bt_dev); |
1061 | statp->f_fsid.val[0] = (u32)id; | 1066 | statp->f_fsid.val[0] = (u32)id; |
1062 | statp->f_fsid.val[1] = (u32)(id >> 32); | 1067 | statp->f_fsid.val[1] = (u32)(id >> 32); |
1063 | 1068 | ||
1064 | xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); | 1069 | xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); |
1065 | 1070 | ||
1066 | spin_lock(&mp->m_sb_lock); | 1071 | spin_lock(&mp->m_sb_lock); |
1067 | statp->f_bsize = sbp->sb_blocksize; | 1072 | statp->f_bsize = sbp->sb_blocksize; |
1068 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; | 1073 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; |
1069 | statp->f_blocks = sbp->sb_dblocks - lsize; | 1074 | statp->f_blocks = sbp->sb_dblocks - lsize; |
1070 | statp->f_bfree = statp->f_bavail = | 1075 | statp->f_bfree = statp->f_bavail = |
1071 | sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); | 1076 | sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); |
1072 | fakeinos = statp->f_bfree << sbp->sb_inopblog; | 1077 | fakeinos = statp->f_bfree << sbp->sb_inopblog; |
1073 | statp->f_files = | 1078 | statp->f_files = |
1074 | MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER); | 1079 | MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER); |
1075 | if (mp->m_maxicount) | 1080 | if (mp->m_maxicount) |
1076 | statp->f_files = min_t(typeof(statp->f_files), | 1081 | statp->f_files = min_t(typeof(statp->f_files), |
1077 | statp->f_files, | 1082 | statp->f_files, |
1078 | mp->m_maxicount); | 1083 | mp->m_maxicount); |
1079 | 1084 | ||
1080 | /* make sure statp->f_ffree does not underflow */ | 1085 | /* make sure statp->f_ffree does not underflow */ |
1081 | ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); | 1086 | ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); |
1082 | statp->f_ffree = max_t(__int64_t, ffree, 0); | 1087 | statp->f_ffree = max_t(__int64_t, ffree, 0); |
1083 | 1088 | ||
1084 | spin_unlock(&mp->m_sb_lock); | 1089 | spin_unlock(&mp->m_sb_lock); |
1085 | 1090 | ||
1086 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && | 1091 | if ((ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && |
1087 | ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) == | 1092 | ((mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))) == |
1088 | (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) | 1093 | (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD)) |
1089 | xfs_qm_statvfs(ip, statp); | 1094 | xfs_qm_statvfs(ip, statp); |
1090 | return 0; | 1095 | return 0; |
1091 | } | 1096 | } |
1092 | 1097 | ||
1093 | STATIC void | 1098 | STATIC void |
1094 | xfs_save_resvblks(struct xfs_mount *mp) | 1099 | xfs_save_resvblks(struct xfs_mount *mp) |
1095 | { | 1100 | { |
1096 | __uint64_t resblks = 0; | 1101 | __uint64_t resblks = 0; |
1097 | 1102 | ||
1098 | mp->m_resblks_save = mp->m_resblks; | 1103 | mp->m_resblks_save = mp->m_resblks; |
1099 | xfs_reserve_blocks(mp, &resblks, NULL); | 1104 | xfs_reserve_blocks(mp, &resblks, NULL); |
1100 | } | 1105 | } |
1101 | 1106 | ||
1102 | STATIC void | 1107 | STATIC void |
1103 | xfs_restore_resvblks(struct xfs_mount *mp) | 1108 | xfs_restore_resvblks(struct xfs_mount *mp) |
1104 | { | 1109 | { |
1105 | __uint64_t resblks; | 1110 | __uint64_t resblks; |
1106 | 1111 | ||
1107 | if (mp->m_resblks_save) { | 1112 | if (mp->m_resblks_save) { |
1108 | resblks = mp->m_resblks_save; | 1113 | resblks = mp->m_resblks_save; |
1109 | mp->m_resblks_save = 0; | 1114 | mp->m_resblks_save = 0; |
1110 | } else | 1115 | } else |
1111 | resblks = xfs_default_resblks(mp); | 1116 | resblks = xfs_default_resblks(mp); |
1112 | 1117 | ||
1113 | xfs_reserve_blocks(mp, &resblks, NULL); | 1118 | xfs_reserve_blocks(mp, &resblks, NULL); |
1114 | } | 1119 | } |
1115 | 1120 | ||
1116 | STATIC int | 1121 | STATIC int |
1117 | xfs_fs_remount( | 1122 | xfs_fs_remount( |
1118 | struct super_block *sb, | 1123 | struct super_block *sb, |
1119 | int *flags, | 1124 | int *flags, |
1120 | char *options) | 1125 | char *options) |
1121 | { | 1126 | { |
1122 | struct xfs_mount *mp = XFS_M(sb); | 1127 | struct xfs_mount *mp = XFS_M(sb); |
1123 | substring_t args[MAX_OPT_ARGS]; | 1128 | substring_t args[MAX_OPT_ARGS]; |
1124 | char *p; | 1129 | char *p; |
1125 | int error; | 1130 | int error; |
1126 | 1131 | ||
1127 | while ((p = strsep(&options, ",")) != NULL) { | 1132 | while ((p = strsep(&options, ",")) != NULL) { |
1128 | int token; | 1133 | int token; |
1129 | 1134 | ||
1130 | if (!*p) | 1135 | if (!*p) |
1131 | continue; | 1136 | continue; |
1132 | 1137 | ||
1133 | token = match_token(p, tokens, args); | 1138 | token = match_token(p, tokens, args); |
1134 | switch (token) { | 1139 | switch (token) { |
1135 | case Opt_barrier: | 1140 | case Opt_barrier: |
1136 | mp->m_flags |= XFS_MOUNT_BARRIER; | 1141 | mp->m_flags |= XFS_MOUNT_BARRIER; |
1137 | break; | 1142 | break; |
1138 | case Opt_nobarrier: | 1143 | case Opt_nobarrier: |
1139 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 1144 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
1140 | break; | 1145 | break; |
1141 | case Opt_inode64: | 1146 | case Opt_inode64: |
1142 | mp->m_maxagi = xfs_set_inode64(mp); | 1147 | mp->m_maxagi = xfs_set_inode64(mp); |
1148 | break; | ||
1149 | case Opt_inode32: | ||
1150 | mp->m_maxagi = xfs_set_inode32(mp); | ||
1143 | break; | 1151 | break; |
1144 | default: | 1152 | default: |
1145 | /* | 1153 | /* |
1146 | * Logically we would return an error here to prevent | 1154 | * Logically we would return an error here to prevent |
1147 | * users from believing they might have changed | 1155 | * users from believing they might have changed |
1148 | * mount options using remount which can't be changed. | 1156 | * mount options using remount which can't be changed. |
1149 | * | 1157 | * |
1150 | * But unfortunately mount(8) adds all options from | 1158 | * But unfortunately mount(8) adds all options from |
1151 | * mtab and fstab to the mount arguments in some cases | 1159 | * mtab and fstab to the mount arguments in some cases |
1152 | * so we can't blindly reject options, but have to | 1160 | * so we can't blindly reject options, but have to |
1153 | * check for each specified option if it actually | 1161 | * check for each specified option if it actually |
1154 | * differs from the currently set option and only | 1162 | * differs from the currently set option and only |
1155 | * reject it if that's the case. | 1163 | * reject it if that's the case. |
1156 | * | 1164 | * |
1157 | * Until that is implemented we return success for | 1165 | * Until that is implemented we return success for |
1158 | * every remount request, and silently ignore all | 1166 | * every remount request, and silently ignore all |
1159 | * options that we can't actually change. | 1167 | * options that we can't actually change. |
1160 | */ | 1168 | */ |
1161 | #if 0 | 1169 | #if 0 |
1162 | xfs_info(mp, | 1170 | xfs_info(mp, |
1163 | "mount option \"%s\" not supported for remount\n", p); | 1171 | "mount option \"%s\" not supported for remount\n", p); |
1164 | return -EINVAL; | 1172 | return -EINVAL; |
1165 | #else | 1173 | #else |
1166 | break; | 1174 | break; |
1167 | #endif | 1175 | #endif |
1168 | } | 1176 | } |
1169 | } | 1177 | } |
1170 | 1178 | ||
1171 | /* ro -> rw */ | 1179 | /* ro -> rw */ |
1172 | if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { | 1180 | if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { |
1173 | mp->m_flags &= ~XFS_MOUNT_RDONLY; | 1181 | mp->m_flags &= ~XFS_MOUNT_RDONLY; |
1174 | 1182 | ||
1175 | /* | 1183 | /* |
1176 | * If this is the first remount to writeable state we | 1184 | * If this is the first remount to writeable state we |
1177 | * might have some superblock changes to update. | 1185 | * might have some superblock changes to update. |
1178 | */ | 1186 | */ |
1179 | if (mp->m_update_flags) { | 1187 | if (mp->m_update_flags) { |
1180 | error = xfs_mount_log_sb(mp, mp->m_update_flags); | 1188 | error = xfs_mount_log_sb(mp, mp->m_update_flags); |
1181 | if (error) { | 1189 | if (error) { |
1182 | xfs_warn(mp, "failed to write sb changes"); | 1190 | xfs_warn(mp, "failed to write sb changes"); |
1183 | return error; | 1191 | return error; |
1184 | } | 1192 | } |
1185 | mp->m_update_flags = 0; | 1193 | mp->m_update_flags = 0; |
1186 | } | 1194 | } |
1187 | 1195 | ||
1188 | /* | 1196 | /* |
1189 | * Fill out the reserve pool if it is empty. Use the stashed | 1197 | * Fill out the reserve pool if it is empty. Use the stashed |
1190 | * value if it is non-zero, otherwise go with the default. | 1198 | * value if it is non-zero, otherwise go with the default. |
1191 | */ | 1199 | */ |
1192 | xfs_restore_resvblks(mp); | 1200 | xfs_restore_resvblks(mp); |
1193 | } | 1201 | } |
1194 | 1202 | ||
1195 | /* rw -> ro */ | 1203 | /* rw -> ro */ |
1196 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { | 1204 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { |
1197 | /* | 1205 | /* |
1198 | * After we have synced the data but before we sync the | 1206 | * After we have synced the data but before we sync the |
1199 | * metadata, we need to free up the reserve block pool so that | 1207 | * metadata, we need to free up the reserve block pool so that |
1200 | * the used block count in the superblock on disk is correct at | 1208 | * the used block count in the superblock on disk is correct at |
1201 | * the end of the remount. Stash the current reserve pool size | 1209 | * the end of the remount. Stash the current reserve pool size |
1202 | * so that if we get remounted rw, we can return it to the same | 1210 | * so that if we get remounted rw, we can return it to the same |
1203 | * size. | 1211 | * size. |
1204 | */ | 1212 | */ |
1205 | 1213 | ||
1206 | xfs_quiesce_data(mp); | 1214 | xfs_quiesce_data(mp); |
1207 | xfs_save_resvblks(mp); | 1215 | xfs_save_resvblks(mp); |
1208 | xfs_quiesce_attr(mp); | 1216 | xfs_quiesce_attr(mp); |
1209 | mp->m_flags |= XFS_MOUNT_RDONLY; | 1217 | mp->m_flags |= XFS_MOUNT_RDONLY; |
1210 | } | 1218 | } |
1211 | 1219 | ||
1212 | return 0; | 1220 | return 0; |
1213 | } | 1221 | } |
1214 | 1222 | ||
1215 | /* | 1223 | /* |
1216 | * Second stage of a freeze. The data is already frozen so we only | 1224 | * Second stage of a freeze. The data is already frozen so we only |
1217 | * need to take care of the metadata. Once that's done write a dummy | 1225 | * need to take care of the metadata. Once that's done write a dummy |
1218 | * record to dirty the log in case of a crash while frozen. | 1226 | * record to dirty the log in case of a crash while frozen. |
1219 | */ | 1227 | */ |
1220 | STATIC int | 1228 | STATIC int |
1221 | xfs_fs_freeze( | 1229 | xfs_fs_freeze( |
1222 | struct super_block *sb) | 1230 | struct super_block *sb) |
1223 | { | 1231 | { |
1224 | struct xfs_mount *mp = XFS_M(sb); | 1232 | struct xfs_mount *mp = XFS_M(sb); |
1225 | 1233 | ||
1226 | xfs_save_resvblks(mp); | 1234 | xfs_save_resvblks(mp); |
1227 | xfs_quiesce_attr(mp); | 1235 | xfs_quiesce_attr(mp); |
1228 | return -xfs_fs_log_dummy(mp); | 1236 | return -xfs_fs_log_dummy(mp); |
1229 | } | 1237 | } |
1230 | 1238 | ||
1231 | STATIC int | 1239 | STATIC int |
1232 | xfs_fs_unfreeze( | 1240 | xfs_fs_unfreeze( |
1233 | struct super_block *sb) | 1241 | struct super_block *sb) |
1234 | { | 1242 | { |
1235 | struct xfs_mount *mp = XFS_M(sb); | 1243 | struct xfs_mount *mp = XFS_M(sb); |
1236 | 1244 | ||
1237 | xfs_restore_resvblks(mp); | 1245 | xfs_restore_resvblks(mp); |
1238 | return 0; | 1246 | return 0; |
1239 | } | 1247 | } |
1240 | 1248 | ||
1241 | STATIC int | 1249 | STATIC int |
1242 | xfs_fs_show_options( | 1250 | xfs_fs_show_options( |
1243 | struct seq_file *m, | 1251 | struct seq_file *m, |
1244 | struct dentry *root) | 1252 | struct dentry *root) |
1245 | { | 1253 | { |
1246 | return -xfs_showargs(XFS_M(root->d_sb), m); | 1254 | return -xfs_showargs(XFS_M(root->d_sb), m); |
1247 | } | 1255 | } |
1248 | 1256 | ||
1249 | /* | 1257 | /* |
1250 | * This function fills in xfs_mount_t fields based on mount args. | 1258 | * This function fills in xfs_mount_t fields based on mount args. |
1251 | * Note: the superblock _has_ now been read in. | 1259 | * Note: the superblock _has_ now been read in. |
1252 | */ | 1260 | */ |
1253 | STATIC int | 1261 | STATIC int |
1254 | xfs_finish_flags( | 1262 | xfs_finish_flags( |
1255 | struct xfs_mount *mp) | 1263 | struct xfs_mount *mp) |
1256 | { | 1264 | { |
1257 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); | 1265 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); |
1258 | 1266 | ||
1259 | /* Fail a mount where the logbuf is smaller than the log stripe */ | 1267 | /* Fail a mount where the logbuf is smaller than the log stripe */ |
1260 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { | 1268 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { |
1261 | if (mp->m_logbsize <= 0 && | 1269 | if (mp->m_logbsize <= 0 && |
1262 | mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) { | 1270 | mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE) { |
1263 | mp->m_logbsize = mp->m_sb.sb_logsunit; | 1271 | mp->m_logbsize = mp->m_sb.sb_logsunit; |
1264 | } else if (mp->m_logbsize > 0 && | 1272 | } else if (mp->m_logbsize > 0 && |
1265 | mp->m_logbsize < mp->m_sb.sb_logsunit) { | 1273 | mp->m_logbsize < mp->m_sb.sb_logsunit) { |
1266 | xfs_warn(mp, | 1274 | xfs_warn(mp, |
1267 | "logbuf size must be greater than or equal to log stripe size"); | 1275 | "logbuf size must be greater than or equal to log stripe size"); |
1268 | return XFS_ERROR(EINVAL); | 1276 | return XFS_ERROR(EINVAL); |
1269 | } | 1277 | } |
1270 | } else { | 1278 | } else { |
1271 | /* Fail a mount if the logbuf is larger than 32K */ | 1279 | /* Fail a mount if the logbuf is larger than 32K */ |
1272 | if (mp->m_logbsize > XLOG_BIG_RECORD_BSIZE) { | 1280 | if (mp->m_logbsize > XLOG_BIG_RECORD_BSIZE) { |
1273 | xfs_warn(mp, | 1281 | xfs_warn(mp, |
1274 | "logbuf size for version 1 logs must be 16K or 32K"); | 1282 | "logbuf size for version 1 logs must be 16K or 32K"); |
1275 | return XFS_ERROR(EINVAL); | 1283 | return XFS_ERROR(EINVAL); |
1276 | } | 1284 | } |
1277 | } | 1285 | } |
1278 | 1286 | ||
1279 | /* | 1287 | /* |
1280 | * mkfs'ed attr2 will turn on attr2 mount unless explicitly | 1288 | * mkfs'ed attr2 will turn on attr2 mount unless explicitly |
1281 | * told by noattr2 to turn it off | 1289 | * told by noattr2 to turn it off |
1282 | */ | 1290 | */ |
1283 | if (xfs_sb_version_hasattr2(&mp->m_sb) && | 1291 | if (xfs_sb_version_hasattr2(&mp->m_sb) && |
1284 | !(mp->m_flags & XFS_MOUNT_NOATTR2)) | 1292 | !(mp->m_flags & XFS_MOUNT_NOATTR2)) |
1285 | mp->m_flags |= XFS_MOUNT_ATTR2; | 1293 | mp->m_flags |= XFS_MOUNT_ATTR2; |
1286 | 1294 | ||
1287 | /* | 1295 | /* |
1288 | * prohibit r/w mounts of read-only filesystems | 1296 | * prohibit r/w mounts of read-only filesystems |
1289 | */ | 1297 | */ |
1290 | if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) { | 1298 | if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) { |
1291 | xfs_warn(mp, | 1299 | xfs_warn(mp, |
1292 | "cannot mount a read-only filesystem as read-write"); | 1300 | "cannot mount a read-only filesystem as read-write"); |
1293 | return XFS_ERROR(EROFS); | 1301 | return XFS_ERROR(EROFS); |
1294 | } | 1302 | } |
1295 | 1303 | ||
1296 | return 0; | 1304 | return 0; |
1297 | } | 1305 | } |
1298 | 1306 | ||
1299 | STATIC int | 1307 | STATIC int |
1300 | xfs_fs_fill_super( | 1308 | xfs_fs_fill_super( |
1301 | struct super_block *sb, | 1309 | struct super_block *sb, |
1302 | void *data, | 1310 | void *data, |
1303 | int silent) | 1311 | int silent) |
1304 | { | 1312 | { |
1305 | struct inode *root; | 1313 | struct inode *root; |
1306 | struct xfs_mount *mp = NULL; | 1314 | struct xfs_mount *mp = NULL; |
1307 | int flags = 0, error = ENOMEM; | 1315 | int flags = 0, error = ENOMEM; |
1308 | 1316 | ||
1309 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); | 1317 | mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); |
1310 | if (!mp) | 1318 | if (!mp) |
1311 | goto out; | 1319 | goto out; |
1312 | 1320 | ||
1313 | spin_lock_init(&mp->m_sb_lock); | 1321 | spin_lock_init(&mp->m_sb_lock); |
1314 | mutex_init(&mp->m_growlock); | 1322 | mutex_init(&mp->m_growlock); |
1315 | atomic_set(&mp->m_active_trans, 0); | 1323 | atomic_set(&mp->m_active_trans, 0); |
1316 | 1324 | ||
1317 | mp->m_super = sb; | 1325 | mp->m_super = sb; |
1318 | sb->s_fs_info = mp; | 1326 | sb->s_fs_info = mp; |
1319 | 1327 | ||
1320 | error = xfs_parseargs(mp, (char *)data); | 1328 | error = xfs_parseargs(mp, (char *)data); |
1321 | if (error) | 1329 | if (error) |
1322 | goto out_free_fsname; | 1330 | goto out_free_fsname; |
1323 | 1331 | ||
1324 | sb_min_blocksize(sb, BBSIZE); | 1332 | sb_min_blocksize(sb, BBSIZE); |
1325 | sb->s_xattr = xfs_xattr_handlers; | 1333 | sb->s_xattr = xfs_xattr_handlers; |
1326 | sb->s_export_op = &xfs_export_operations; | 1334 | sb->s_export_op = &xfs_export_operations; |
1327 | #ifdef CONFIG_XFS_QUOTA | 1335 | #ifdef CONFIG_XFS_QUOTA |
1328 | sb->s_qcop = &xfs_quotactl_operations; | 1336 | sb->s_qcop = &xfs_quotactl_operations; |
1329 | #endif | 1337 | #endif |
1330 | sb->s_op = &xfs_super_operations; | 1338 | sb->s_op = &xfs_super_operations; |
1331 | 1339 | ||
1332 | if (silent) | 1340 | if (silent) |
1333 | flags |= XFS_MFSI_QUIET; | 1341 | flags |= XFS_MFSI_QUIET; |
1334 | 1342 | ||
1335 | error = xfs_open_devices(mp); | 1343 | error = xfs_open_devices(mp); |
1336 | if (error) | 1344 | if (error) |
1337 | goto out_free_fsname; | 1345 | goto out_free_fsname; |
1338 | 1346 | ||
1339 | error = xfs_init_mount_workqueues(mp); | 1347 | error = xfs_init_mount_workqueues(mp); |
1340 | if (error) | 1348 | if (error) |
1341 | goto out_close_devices; | 1349 | goto out_close_devices; |
1342 | 1350 | ||
1343 | error = xfs_icsb_init_counters(mp); | 1351 | error = xfs_icsb_init_counters(mp); |
1344 | if (error) | 1352 | if (error) |
1345 | goto out_destroy_workqueues; | 1353 | goto out_destroy_workqueues; |
1346 | 1354 | ||
1347 | error = xfs_readsb(mp, flags); | 1355 | error = xfs_readsb(mp, flags); |
1348 | if (error) | 1356 | if (error) |
1349 | goto out_destroy_counters; | 1357 | goto out_destroy_counters; |
1350 | 1358 | ||
1351 | error = xfs_finish_flags(mp); | 1359 | error = xfs_finish_flags(mp); |
1352 | if (error) | 1360 | if (error) |
1353 | goto out_free_sb; | 1361 | goto out_free_sb; |
1354 | 1362 | ||
1355 | error = xfs_setup_devices(mp); | 1363 | error = xfs_setup_devices(mp); |
1356 | if (error) | 1364 | if (error) |
1357 | goto out_free_sb; | 1365 | goto out_free_sb; |
1358 | 1366 | ||
1359 | error = xfs_filestream_mount(mp); | 1367 | error = xfs_filestream_mount(mp); |
1360 | if (error) | 1368 | if (error) |
1361 | goto out_free_sb; | 1369 | goto out_free_sb; |
1362 | 1370 | ||
1363 | /* | 1371 | /* |
1364 | * we must configure the block size in the superblock before we run the | 1372 | * we must configure the block size in the superblock before we run the |
1365 | * full mount process as the mount process can lookup and cache inodes. | 1373 | * full mount process as the mount process can lookup and cache inodes. |
1366 | * For the same reason we must also initialise the syncd and register | 1374 | * For the same reason we must also initialise the syncd and register |
1367 | * the inode cache shrinker so that inodes can be reclaimed during | 1375 | * the inode cache shrinker so that inodes can be reclaimed during |
1368 | * operations like a quotacheck that iterate all inodes in the | 1376 | * operations like a quotacheck that iterate all inodes in the |
1369 | * filesystem. | 1377 | * filesystem. |
1370 | */ | 1378 | */ |
1371 | sb->s_magic = XFS_SB_MAGIC; | 1379 | sb->s_magic = XFS_SB_MAGIC; |
1372 | sb->s_blocksize = mp->m_sb.sb_blocksize; | 1380 | sb->s_blocksize = mp->m_sb.sb_blocksize; |
1373 | sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; | 1381 | sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; |
1374 | sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); | 1382 | sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); |
1375 | sb->s_max_links = XFS_MAXLINK; | 1383 | sb->s_max_links = XFS_MAXLINK; |
1376 | sb->s_time_gran = 1; | 1384 | sb->s_time_gran = 1; |
1377 | set_posix_acl_flag(sb); | 1385 | set_posix_acl_flag(sb); |
1378 | 1386 | ||
1379 | error = xfs_syncd_init(mp); | 1387 | error = xfs_syncd_init(mp); |
1380 | if (error) | 1388 | if (error) |
1381 | goto out_filestream_unmount; | 1389 | goto out_filestream_unmount; |
1382 | 1390 | ||
1383 | error = xfs_mountfs(mp); | 1391 | error = xfs_mountfs(mp); |
1384 | if (error) | 1392 | if (error) |
1385 | goto out_syncd_stop; | 1393 | goto out_syncd_stop; |
1386 | 1394 | ||
1387 | root = igrab(VFS_I(mp->m_rootip)); | 1395 | root = igrab(VFS_I(mp->m_rootip)); |
1388 | if (!root) { | 1396 | if (!root) { |
1389 | error = ENOENT; | 1397 | error = ENOENT; |
1390 | goto out_unmount; | 1398 | goto out_unmount; |
1391 | } | 1399 | } |
1392 | if (is_bad_inode(root)) { | 1400 | if (is_bad_inode(root)) { |
1393 | error = EINVAL; | 1401 | error = EINVAL; |
1394 | goto out_unmount; | 1402 | goto out_unmount; |
1395 | } | 1403 | } |
1396 | sb->s_root = d_make_root(root); | 1404 | sb->s_root = d_make_root(root); |
1397 | if (!sb->s_root) { | 1405 | if (!sb->s_root) { |
1398 | error = ENOMEM; | 1406 | error = ENOMEM; |
1399 | goto out_unmount; | 1407 | goto out_unmount; |
1400 | } | 1408 | } |
1401 | 1409 | ||
1402 | return 0; | 1410 | return 0; |
1403 | out_syncd_stop: | 1411 | out_syncd_stop: |
1404 | xfs_syncd_stop(mp); | 1412 | xfs_syncd_stop(mp); |
1405 | out_filestream_unmount: | 1413 | out_filestream_unmount: |
1406 | xfs_filestream_unmount(mp); | 1414 | xfs_filestream_unmount(mp); |
1407 | out_free_sb: | 1415 | out_free_sb: |
1408 | xfs_freesb(mp); | 1416 | xfs_freesb(mp); |
1409 | out_destroy_counters: | 1417 | out_destroy_counters: |
1410 | xfs_icsb_destroy_counters(mp); | 1418 | xfs_icsb_destroy_counters(mp); |
1411 | out_destroy_workqueues: | 1419 | out_destroy_workqueues: |
1412 | xfs_destroy_mount_workqueues(mp); | 1420 | xfs_destroy_mount_workqueues(mp); |
1413 | out_close_devices: | 1421 | out_close_devices: |
1414 | xfs_close_devices(mp); | 1422 | xfs_close_devices(mp); |
1415 | out_free_fsname: | 1423 | out_free_fsname: |
1416 | xfs_free_fsname(mp); | 1424 | xfs_free_fsname(mp); |
1417 | kfree(mp); | 1425 | kfree(mp); |
1418 | out: | 1426 | out: |
1419 | return -error; | 1427 | return -error; |
1420 | 1428 | ||
1421 | out_unmount: | 1429 | out_unmount: |
1422 | xfs_filestream_unmount(mp); | 1430 | xfs_filestream_unmount(mp); |
1423 | xfs_unmountfs(mp); | 1431 | xfs_unmountfs(mp); |
1424 | xfs_syncd_stop(mp); | 1432 | xfs_syncd_stop(mp); |
1425 | goto out_free_sb; | 1433 | goto out_free_sb; |
1426 | } | 1434 | } |
1427 | 1435 | ||
1428 | STATIC struct dentry * | 1436 | STATIC struct dentry * |
1429 | xfs_fs_mount( | 1437 | xfs_fs_mount( |
1430 | struct file_system_type *fs_type, | 1438 | struct file_system_type *fs_type, |
1431 | int flags, | 1439 | int flags, |
1432 | const char *dev_name, | 1440 | const char *dev_name, |
1433 | void *data) | 1441 | void *data) |
1434 | { | 1442 | { |
1435 | return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); | 1443 | return mount_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); |
1436 | } | 1444 | } |
1437 | 1445 | ||
1438 | static int | 1446 | static int |
1439 | xfs_fs_nr_cached_objects( | 1447 | xfs_fs_nr_cached_objects( |
1440 | struct super_block *sb) | 1448 | struct super_block *sb) |
1441 | { | 1449 | { |
1442 | return xfs_reclaim_inodes_count(XFS_M(sb)); | 1450 | return xfs_reclaim_inodes_count(XFS_M(sb)); |
1443 | } | 1451 | } |
1444 | 1452 | ||
1445 | static void | 1453 | static void |
1446 | xfs_fs_free_cached_objects( | 1454 | xfs_fs_free_cached_objects( |
1447 | struct super_block *sb, | 1455 | struct super_block *sb, |
1448 | int nr_to_scan) | 1456 | int nr_to_scan) |
1449 | { | 1457 | { |
1450 | xfs_reclaim_inodes_nr(XFS_M(sb), nr_to_scan); | 1458 | xfs_reclaim_inodes_nr(XFS_M(sb), nr_to_scan); |
1451 | } | 1459 | } |
1452 | 1460 | ||
1453 | static const struct super_operations xfs_super_operations = { | 1461 | static const struct super_operations xfs_super_operations = { |
1454 | .alloc_inode = xfs_fs_alloc_inode, | 1462 | .alloc_inode = xfs_fs_alloc_inode, |
1455 | .destroy_inode = xfs_fs_destroy_inode, | 1463 | .destroy_inode = xfs_fs_destroy_inode, |
1456 | .evict_inode = xfs_fs_evict_inode, | 1464 | .evict_inode = xfs_fs_evict_inode, |
1457 | .drop_inode = xfs_fs_drop_inode, | 1465 | .drop_inode = xfs_fs_drop_inode, |
1458 | .put_super = xfs_fs_put_super, | 1466 | .put_super = xfs_fs_put_super, |
1459 | .sync_fs = xfs_fs_sync_fs, | 1467 | .sync_fs = xfs_fs_sync_fs, |
1460 | .freeze_fs = xfs_fs_freeze, | 1468 | .freeze_fs = xfs_fs_freeze, |
1461 | .unfreeze_fs = xfs_fs_unfreeze, | 1469 | .unfreeze_fs = xfs_fs_unfreeze, |
1462 | .statfs = xfs_fs_statfs, | 1470 | .statfs = xfs_fs_statfs, |
1463 | .remount_fs = xfs_fs_remount, | 1471 | .remount_fs = xfs_fs_remount, |
1464 | .show_options = xfs_fs_show_options, | 1472 | .show_options = xfs_fs_show_options, |
1465 | .nr_cached_objects = xfs_fs_nr_cached_objects, | 1473 | .nr_cached_objects = xfs_fs_nr_cached_objects, |
1466 | .free_cached_objects = xfs_fs_free_cached_objects, | 1474 | .free_cached_objects = xfs_fs_free_cached_objects, |
1467 | }; | 1475 | }; |
1468 | 1476 | ||
1469 | static struct file_system_type xfs_fs_type = { | 1477 | static struct file_system_type xfs_fs_type = { |
1470 | .owner = THIS_MODULE, | 1478 | .owner = THIS_MODULE, |
1471 | .name = "xfs", | 1479 | .name = "xfs", |
1472 | .mount = xfs_fs_mount, | 1480 | .mount = xfs_fs_mount, |
1473 | .kill_sb = kill_block_super, | 1481 | .kill_sb = kill_block_super, |
1474 | .fs_flags = FS_REQUIRES_DEV, | 1482 | .fs_flags = FS_REQUIRES_DEV, |
1475 | }; | 1483 | }; |
1476 | 1484 | ||
1477 | STATIC int __init | 1485 | STATIC int __init |
1478 | xfs_init_zones(void) | 1486 | xfs_init_zones(void) |
1479 | { | 1487 | { |
1480 | 1488 | ||
1481 | xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend"); | 1489 | xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend"); |
1482 | if (!xfs_ioend_zone) | 1490 | if (!xfs_ioend_zone) |
1483 | goto out; | 1491 | goto out; |
1484 | 1492 | ||
1485 | xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE, | 1493 | xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE, |
1486 | xfs_ioend_zone); | 1494 | xfs_ioend_zone); |
1487 | if (!xfs_ioend_pool) | 1495 | if (!xfs_ioend_pool) |
1488 | goto out_destroy_ioend_zone; | 1496 | goto out_destroy_ioend_zone; |
1489 | 1497 | ||
1490 | xfs_log_ticket_zone = kmem_zone_init(sizeof(xlog_ticket_t), | 1498 | xfs_log_ticket_zone = kmem_zone_init(sizeof(xlog_ticket_t), |
1491 | "xfs_log_ticket"); | 1499 | "xfs_log_ticket"); |
1492 | if (!xfs_log_ticket_zone) | 1500 | if (!xfs_log_ticket_zone) |
1493 | goto out_destroy_ioend_pool; | 1501 | goto out_destroy_ioend_pool; |
1494 | 1502 | ||
1495 | xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t), | 1503 | xfs_bmap_free_item_zone = kmem_zone_init(sizeof(xfs_bmap_free_item_t), |
1496 | "xfs_bmap_free_item"); | 1504 | "xfs_bmap_free_item"); |
1497 | if (!xfs_bmap_free_item_zone) | 1505 | if (!xfs_bmap_free_item_zone) |
1498 | goto out_destroy_log_ticket_zone; | 1506 | goto out_destroy_log_ticket_zone; |
1499 | 1507 | ||
1500 | xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t), | 1508 | xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t), |
1501 | "xfs_btree_cur"); | 1509 | "xfs_btree_cur"); |
1502 | if (!xfs_btree_cur_zone) | 1510 | if (!xfs_btree_cur_zone) |
1503 | goto out_destroy_bmap_free_item_zone; | 1511 | goto out_destroy_bmap_free_item_zone; |
1504 | 1512 | ||
1505 | xfs_da_state_zone = kmem_zone_init(sizeof(xfs_da_state_t), | 1513 | xfs_da_state_zone = kmem_zone_init(sizeof(xfs_da_state_t), |
1506 | "xfs_da_state"); | 1514 | "xfs_da_state"); |
1507 | if (!xfs_da_state_zone) | 1515 | if (!xfs_da_state_zone) |
1508 | goto out_destroy_btree_cur_zone; | 1516 | goto out_destroy_btree_cur_zone; |
1509 | 1517 | ||
1510 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); | 1518 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); |
1511 | if (!xfs_ifork_zone) | 1519 | if (!xfs_ifork_zone) |
1512 | goto out_destroy_da_state_zone; | 1520 | goto out_destroy_da_state_zone; |
1513 | 1521 | ||
1514 | xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans"); | 1522 | xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans"); |
1515 | if (!xfs_trans_zone) | 1523 | if (!xfs_trans_zone) |
1516 | goto out_destroy_ifork_zone; | 1524 | goto out_destroy_ifork_zone; |
1517 | 1525 | ||
1518 | xfs_log_item_desc_zone = | 1526 | xfs_log_item_desc_zone = |
1519 | kmem_zone_init(sizeof(struct xfs_log_item_desc), | 1527 | kmem_zone_init(sizeof(struct xfs_log_item_desc), |
1520 | "xfs_log_item_desc"); | 1528 | "xfs_log_item_desc"); |
1521 | if (!xfs_log_item_desc_zone) | 1529 | if (!xfs_log_item_desc_zone) |
1522 | goto out_destroy_trans_zone; | 1530 | goto out_destroy_trans_zone; |
1523 | 1531 | ||
1524 | /* | 1532 | /* |
1525 | * The size of the zone allocated buf log item is the maximum | 1533 | * The size of the zone allocated buf log item is the maximum |
1526 | * size possible under XFS. This wastes a little bit of memory, | 1534 | * size possible under XFS. This wastes a little bit of memory, |
1527 | * but it is much faster. | 1535 | * but it is much faster. |
1528 | */ | 1536 | */ |
1529 | xfs_buf_item_zone = kmem_zone_init(sizeof(struct xfs_buf_log_item), | 1537 | xfs_buf_item_zone = kmem_zone_init(sizeof(struct xfs_buf_log_item), |
1530 | "xfs_buf_item"); | 1538 | "xfs_buf_item"); |
1531 | if (!xfs_buf_item_zone) | 1539 | if (!xfs_buf_item_zone) |
1532 | goto out_destroy_log_item_desc_zone; | 1540 | goto out_destroy_log_item_desc_zone; |
1533 | 1541 | ||
1534 | xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + | 1542 | xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + |
1535 | ((XFS_EFD_MAX_FAST_EXTENTS - 1) * | 1543 | ((XFS_EFD_MAX_FAST_EXTENTS - 1) * |
1536 | sizeof(xfs_extent_t))), "xfs_efd_item"); | 1544 | sizeof(xfs_extent_t))), "xfs_efd_item"); |
1537 | if (!xfs_efd_zone) | 1545 | if (!xfs_efd_zone) |
1538 | goto out_destroy_buf_item_zone; | 1546 | goto out_destroy_buf_item_zone; |
1539 | 1547 | ||
1540 | xfs_efi_zone = kmem_zone_init((sizeof(xfs_efi_log_item_t) + | 1548 | xfs_efi_zone = kmem_zone_init((sizeof(xfs_efi_log_item_t) + |
1541 | ((XFS_EFI_MAX_FAST_EXTENTS - 1) * | 1549 | ((XFS_EFI_MAX_FAST_EXTENTS - 1) * |
1542 | sizeof(xfs_extent_t))), "xfs_efi_item"); | 1550 | sizeof(xfs_extent_t))), "xfs_efi_item"); |
1543 | if (!xfs_efi_zone) | 1551 | if (!xfs_efi_zone) |
1544 | goto out_destroy_efd_zone; | 1552 | goto out_destroy_efd_zone; |
1545 | 1553 | ||
1546 | xfs_inode_zone = | 1554 | xfs_inode_zone = |
1547 | kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", | 1555 | kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", |
1548 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD, | 1556 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD, |
1549 | xfs_fs_inode_init_once); | 1557 | xfs_fs_inode_init_once); |
1550 | if (!xfs_inode_zone) | 1558 | if (!xfs_inode_zone) |
1551 | goto out_destroy_efi_zone; | 1559 | goto out_destroy_efi_zone; |
1552 | 1560 | ||
1553 | xfs_ili_zone = | 1561 | xfs_ili_zone = |
1554 | kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", | 1562 | kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili", |
1555 | KM_ZONE_SPREAD, NULL); | 1563 | KM_ZONE_SPREAD, NULL); |
1556 | if (!xfs_ili_zone) | 1564 | if (!xfs_ili_zone) |
1557 | goto out_destroy_inode_zone; | 1565 | goto out_destroy_inode_zone; |
1558 | 1566 | ||
1559 | return 0; | 1567 | return 0; |
1560 | 1568 | ||
1561 | out_destroy_inode_zone: | 1569 | out_destroy_inode_zone: |
1562 | kmem_zone_destroy(xfs_inode_zone); | 1570 | kmem_zone_destroy(xfs_inode_zone); |
1563 | out_destroy_efi_zone: | 1571 | out_destroy_efi_zone: |
1564 | kmem_zone_destroy(xfs_efi_zone); | 1572 | kmem_zone_destroy(xfs_efi_zone); |
1565 | out_destroy_efd_zone: | 1573 | out_destroy_efd_zone: |
1566 | kmem_zone_destroy(xfs_efd_zone); | 1574 | kmem_zone_destroy(xfs_efd_zone); |
1567 | out_destroy_buf_item_zone: | 1575 | out_destroy_buf_item_zone: |
1568 | kmem_zone_destroy(xfs_buf_item_zone); | 1576 | kmem_zone_destroy(xfs_buf_item_zone); |
1569 | out_destroy_log_item_desc_zone: | 1577 | out_destroy_log_item_desc_zone: |
1570 | kmem_zone_destroy(xfs_log_item_desc_zone); | 1578 | kmem_zone_destroy(xfs_log_item_desc_zone); |
1571 | out_destroy_trans_zone: | 1579 | out_destroy_trans_zone: |
1572 | kmem_zone_destroy(xfs_trans_zone); | 1580 | kmem_zone_destroy(xfs_trans_zone); |
1573 | out_destroy_ifork_zone: | 1581 | out_destroy_ifork_zone: |
1574 | kmem_zone_destroy(xfs_ifork_zone); | 1582 | kmem_zone_destroy(xfs_ifork_zone); |
1575 | out_destroy_da_state_zone: | 1583 | out_destroy_da_state_zone: |
1576 | kmem_zone_destroy(xfs_da_state_zone); | 1584 | kmem_zone_destroy(xfs_da_state_zone); |
1577 | out_destroy_btree_cur_zone: | 1585 | out_destroy_btree_cur_zone: |
1578 | kmem_zone_destroy(xfs_btree_cur_zone); | 1586 | kmem_zone_destroy(xfs_btree_cur_zone); |
1579 | out_destroy_bmap_free_item_zone: | 1587 | out_destroy_bmap_free_item_zone: |
1580 | kmem_zone_destroy(xfs_bmap_free_item_zone); | 1588 | kmem_zone_destroy(xfs_bmap_free_item_zone); |
1581 | out_destroy_log_ticket_zone: | 1589 | out_destroy_log_ticket_zone: |
1582 | kmem_zone_destroy(xfs_log_ticket_zone); | 1590 | kmem_zone_destroy(xfs_log_ticket_zone); |
1583 | out_destroy_ioend_pool: | 1591 | out_destroy_ioend_pool: |
1584 | mempool_destroy(xfs_ioend_pool); | 1592 | mempool_destroy(xfs_ioend_pool); |
1585 | out_destroy_ioend_zone: | 1593 | out_destroy_ioend_zone: |
1586 | kmem_zone_destroy(xfs_ioend_zone); | 1594 | kmem_zone_destroy(xfs_ioend_zone); |
1587 | out: | 1595 | out: |
1588 | return -ENOMEM; | 1596 | return -ENOMEM; |
1589 | } | 1597 | } |
1590 | 1598 | ||
1591 | STATIC void | 1599 | STATIC void |
1592 | xfs_destroy_zones(void) | 1600 | xfs_destroy_zones(void) |
1593 | { | 1601 | { |
1594 | kmem_zone_destroy(xfs_ili_zone); | 1602 | kmem_zone_destroy(xfs_ili_zone); |
1595 | kmem_zone_destroy(xfs_inode_zone); | 1603 | kmem_zone_destroy(xfs_inode_zone); |
1596 | kmem_zone_destroy(xfs_efi_zone); | 1604 | kmem_zone_destroy(xfs_efi_zone); |
1597 | kmem_zone_destroy(xfs_efd_zone); | 1605 | kmem_zone_destroy(xfs_efd_zone); |
1598 | kmem_zone_destroy(xfs_buf_item_zone); | 1606 | kmem_zone_destroy(xfs_buf_item_zone); |
1599 | kmem_zone_destroy(xfs_log_item_desc_zone); | 1607 | kmem_zone_destroy(xfs_log_item_desc_zone); |
1600 | kmem_zone_destroy(xfs_trans_zone); | 1608 | kmem_zone_destroy(xfs_trans_zone); |
1601 | kmem_zone_destroy(xfs_ifork_zone); | 1609 | kmem_zone_destroy(xfs_ifork_zone); |
1602 | kmem_zone_destroy(xfs_da_state_zone); | 1610 | kmem_zone_destroy(xfs_da_state_zone); |
1603 | kmem_zone_destroy(xfs_btree_cur_zone); | 1611 | kmem_zone_destroy(xfs_btree_cur_zone); |
1604 | kmem_zone_destroy(xfs_bmap_free_item_zone); | 1612 | kmem_zone_destroy(xfs_bmap_free_item_zone); |
1605 | kmem_zone_destroy(xfs_log_ticket_zone); | 1613 | kmem_zone_destroy(xfs_log_ticket_zone); |
1606 | mempool_destroy(xfs_ioend_pool); | 1614 | mempool_destroy(xfs_ioend_pool); |
1607 | kmem_zone_destroy(xfs_ioend_zone); | 1615 | kmem_zone_destroy(xfs_ioend_zone); |
1608 | 1616 | ||
1609 | } | 1617 | } |
1610 | 1618 | ||
1611 | STATIC int __init | 1619 | STATIC int __init |
1612 | xfs_init_workqueues(void) | 1620 | xfs_init_workqueues(void) |
1613 | { | 1621 | { |
1614 | /* | 1622 | /* |
1615 | * We never want to the same work item to run twice, reclaiming inodes | 1623 | * We never want to the same work item to run twice, reclaiming inodes |
1616 | * or idling the log is not going to get any faster by multiple CPUs | 1624 | * or idling the log is not going to get any faster by multiple CPUs |
1617 | * competing for ressources. Use the default large max_active value | 1625 | * competing for ressources. Use the default large max_active value |
1618 | * so that even lots of filesystems can perform these task in parallel. | 1626 | * so that even lots of filesystems can perform these task in parallel. |
1619 | */ | 1627 | */ |
1620 | xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_NON_REENTRANT, 0); | 1628 | xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_NON_REENTRANT, 0); |
1621 | if (!xfs_syncd_wq) | 1629 | if (!xfs_syncd_wq) |
1622 | return -ENOMEM; | 1630 | return -ENOMEM; |
1623 | 1631 | ||
1624 | /* | 1632 | /* |
1625 | * The allocation workqueue can be used in memory reclaim situations | 1633 | * The allocation workqueue can be used in memory reclaim situations |
1626 | * (writepage path), and parallelism is only limited by the number of | 1634 | * (writepage path), and parallelism is only limited by the number of |
1627 | * AGs in all the filesystems mounted. Hence use the default large | 1635 | * AGs in all the filesystems mounted. Hence use the default large |
1628 | * max_active value for this workqueue. | 1636 | * max_active value for this workqueue. |
1629 | */ | 1637 | */ |
1630 | xfs_alloc_wq = alloc_workqueue("xfsalloc", WQ_MEM_RECLAIM, 0); | 1638 | xfs_alloc_wq = alloc_workqueue("xfsalloc", WQ_MEM_RECLAIM, 0); |
1631 | if (!xfs_alloc_wq) | 1639 | if (!xfs_alloc_wq) |
1632 | goto out_destroy_syncd; | 1640 | goto out_destroy_syncd; |
1633 | 1641 | ||
1634 | return 0; | 1642 | return 0; |
1635 | 1643 | ||
1636 | out_destroy_syncd: | 1644 | out_destroy_syncd: |
1637 | destroy_workqueue(xfs_syncd_wq); | 1645 | destroy_workqueue(xfs_syncd_wq); |
1638 | return -ENOMEM; | 1646 | return -ENOMEM; |
1639 | } | 1647 | } |
1640 | 1648 | ||
1641 | STATIC void | 1649 | STATIC void |
1642 | xfs_destroy_workqueues(void) | 1650 | xfs_destroy_workqueues(void) |
1643 | { | 1651 | { |
1644 | destroy_workqueue(xfs_alloc_wq); | 1652 | destroy_workqueue(xfs_alloc_wq); |
1645 | destroy_workqueue(xfs_syncd_wq); | 1653 | destroy_workqueue(xfs_syncd_wq); |
1646 | } | 1654 | } |
1647 | 1655 | ||
1648 | STATIC int __init | 1656 | STATIC int __init |
1649 | init_xfs_fs(void) | 1657 | init_xfs_fs(void) |
1650 | { | 1658 | { |
1651 | int error; | 1659 | int error; |
1652 | 1660 | ||
1653 | printk(KERN_INFO XFS_VERSION_STRING " with " | 1661 | printk(KERN_INFO XFS_VERSION_STRING " with " |
1654 | XFS_BUILD_OPTIONS " enabled\n"); | 1662 | XFS_BUILD_OPTIONS " enabled\n"); |
1655 | 1663 | ||
1656 | xfs_dir_startup(); | 1664 | xfs_dir_startup(); |
1657 | 1665 | ||
1658 | error = xfs_init_zones(); | 1666 | error = xfs_init_zones(); |
1659 | if (error) | 1667 | if (error) |
1660 | goto out; | 1668 | goto out; |
1661 | 1669 | ||
1662 | error = xfs_init_workqueues(); | 1670 | error = xfs_init_workqueues(); |
1663 | if (error) | 1671 | if (error) |
1664 | goto out_destroy_zones; | 1672 | goto out_destroy_zones; |
1665 | 1673 | ||
1666 | error = xfs_mru_cache_init(); | 1674 | error = xfs_mru_cache_init(); |
1667 | if (error) | 1675 | if (error) |
1668 | goto out_destroy_wq; | 1676 | goto out_destroy_wq; |
1669 | 1677 | ||
1670 | error = xfs_filestream_init(); | 1678 | error = xfs_filestream_init(); |
1671 | if (error) | 1679 | if (error) |
1672 | goto out_mru_cache_uninit; | 1680 | goto out_mru_cache_uninit; |
1673 | 1681 | ||
1674 | error = xfs_buf_init(); | 1682 | error = xfs_buf_init(); |
1675 | if (error) | 1683 | if (error) |
1676 | goto out_filestream_uninit; | 1684 | goto out_filestream_uninit; |
1677 | 1685 | ||
1678 | error = xfs_init_procfs(); | 1686 | error = xfs_init_procfs(); |
1679 | if (error) | 1687 | if (error) |
1680 | goto out_buf_terminate; | 1688 | goto out_buf_terminate; |
1681 | 1689 | ||
1682 | error = xfs_sysctl_register(); | 1690 | error = xfs_sysctl_register(); |
1683 | if (error) | 1691 | if (error) |
1684 | goto out_cleanup_procfs; | 1692 | goto out_cleanup_procfs; |
1685 | 1693 | ||
1686 | error = xfs_qm_init(); | 1694 | error = xfs_qm_init(); |
1687 | if (error) | 1695 | if (error) |
1688 | goto out_sysctl_unregister; | 1696 | goto out_sysctl_unregister; |
1689 | 1697 | ||
1690 | error = register_filesystem(&xfs_fs_type); | 1698 | error = register_filesystem(&xfs_fs_type); |
1691 | if (error) | 1699 | if (error) |
1692 | goto out_qm_exit; | 1700 | goto out_qm_exit; |
1693 | return 0; | 1701 | return 0; |
1694 | 1702 | ||
1695 | out_qm_exit: | 1703 | out_qm_exit: |
1696 | xfs_qm_exit(); | 1704 | xfs_qm_exit(); |
1697 | out_sysctl_unregister: | 1705 | out_sysctl_unregister: |
1698 | xfs_sysctl_unregister(); | 1706 | xfs_sysctl_unregister(); |
1699 | out_cleanup_procfs: | 1707 | out_cleanup_procfs: |
1700 | xfs_cleanup_procfs(); | 1708 | xfs_cleanup_procfs(); |
1701 | out_buf_terminate: | 1709 | out_buf_terminate: |
1702 | xfs_buf_terminate(); | 1710 | xfs_buf_terminate(); |
1703 | out_filestream_uninit: | 1711 | out_filestream_uninit: |
1704 | xfs_filestream_uninit(); | 1712 | xfs_filestream_uninit(); |
1705 | out_mru_cache_uninit: | 1713 | out_mru_cache_uninit: |
1706 | xfs_mru_cache_uninit(); | 1714 | xfs_mru_cache_uninit(); |
1707 | out_destroy_wq: | 1715 | out_destroy_wq: |
1708 | xfs_destroy_workqueues(); | 1716 | xfs_destroy_workqueues(); |
1709 | out_destroy_zones: | 1717 | out_destroy_zones: |
1710 | xfs_destroy_zones(); | 1718 | xfs_destroy_zones(); |
1711 | out: | 1719 | out: |
1712 | return error; | 1720 | return error; |
1713 | } | 1721 | } |
1714 | 1722 | ||
1715 | STATIC void __exit | 1723 | STATIC void __exit |
1716 | exit_xfs_fs(void) | 1724 | exit_xfs_fs(void) |
1717 | { | 1725 | { |
1718 | xfs_qm_exit(); | 1726 | xfs_qm_exit(); |
1719 | unregister_filesystem(&xfs_fs_type); | 1727 | unregister_filesystem(&xfs_fs_type); |
1720 | xfs_sysctl_unregister(); | 1728 | xfs_sysctl_unregister(); |
1721 | xfs_cleanup_procfs(); | 1729 | xfs_cleanup_procfs(); |
1722 | xfs_buf_terminate(); | 1730 | xfs_buf_terminate(); |
1723 | xfs_filestream_uninit(); | 1731 | xfs_filestream_uninit(); |
1724 | xfs_mru_cache_uninit(); | 1732 | xfs_mru_cache_uninit(); |
1725 | xfs_destroy_workqueues(); | 1733 | xfs_destroy_workqueues(); |
1726 | xfs_destroy_zones(); | 1734 | xfs_destroy_zones(); |
1727 | } | 1735 | } |
1728 | 1736 | ||
1729 | module_init(init_xfs_fs); | 1737 | module_init(init_xfs_fs); |
1730 | module_exit(exit_xfs_fs); | 1738 | module_exit(exit_xfs_fs); |
1731 | 1739 | ||
1732 | MODULE_AUTHOR("Silicon Graphics, Inc."); | 1740 | MODULE_AUTHOR("Silicon Graphics, Inc."); |
1733 | MODULE_DESCRIPTION(XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled"); | 1741 | MODULE_DESCRIPTION(XFS_VERSION_STRING " with " XFS_BUILD_OPTIONS " enabled"); |
1734 | MODULE_LICENSE("GPL"); | 1742 | MODULE_LICENSE("GPL"); |
1735 | 1743 |