diff options
Diffstat (limited to 'fs/xfs/xfs_super.c')
-rw-r--r-- | fs/xfs/xfs_super.c | 528 |
1 files changed, 286 insertions, 242 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 59c9b7bd958d..d760934109b5 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "xfs_filestream.h" | 45 | #include "xfs_filestream.h" |
46 | #include "xfs_quota.h" | 46 | #include "xfs_quota.h" |
47 | #include "xfs_sysfs.h" | 47 | #include "xfs_sysfs.h" |
48 | #include "xfs_ondisk.h" | ||
48 | 49 | ||
49 | #include <linux/namei.h> | 50 | #include <linux/namei.h> |
50 | #include <linux/init.h> | 51 | #include <linux/init.h> |
@@ -65,83 +66,85 @@ static struct kset *xfs_kset; /* top-level xfs sysfs dir */ | |||
65 | static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ | 66 | static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ |
66 | #endif | 67 | #endif |
67 | 68 | ||
68 | #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ | ||
69 | #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ | ||
70 | #define MNTOPT_LOGDEV "logdev" /* log device */ | ||
71 | #define MNTOPT_RTDEV "rtdev" /* realtime I/O device */ | ||
72 | #define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */ | ||
73 | #define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */ | ||
74 | #define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */ | ||
75 | #define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */ | ||
76 | #define MNTOPT_SUNIT "sunit" /* data volume stripe unit */ | ||
77 | #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ | ||
78 | #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ | ||
79 | #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ | ||
80 | #define MNTOPT_GRPID "grpid" /* group-ID from parent directory */ | ||
81 | #define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */ | ||
82 | #define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */ | ||
83 | #define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */ | ||
84 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ | ||
85 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ | ||
86 | #define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and | ||
87 | * unwritten extent conversion */ | ||
88 | #define MNTOPT_NOBARRIER "nobarrier" /* .. disable */ | ||
89 | #define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */ | ||
90 | #define MNTOPT_32BITINODE "inode32" /* inode allocation limited to | ||
91 | * XFS_MAXINUMBER_32 */ | ||
92 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ | ||
93 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ | ||
94 | #define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */ | ||
95 | #define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes | ||
96 | * in stat(). */ | ||
97 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ | ||
98 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ | ||
99 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ | ||
100 | #define MNTOPT_QUOTA "quota" /* disk quotas (user) */ | ||
101 | #define MNTOPT_NOQUOTA "noquota" /* no quotas */ | ||
102 | #define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ | ||
103 | #define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ | ||
104 | #define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */ | ||
105 | #define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ | ||
106 | #define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ | ||
107 | #define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */ | ||
108 | #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ | ||
109 | #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ | ||
110 | #define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */ | ||
111 | #define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ | ||
112 | #define MNTOPT_DISCARD "discard" /* Discard unused blocks */ | ||
113 | #define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */ | ||
114 | |||
115 | #define MNTOPT_DAX "dax" /* Enable direct access to bdev pages */ | ||
116 | |||
117 | /* | 69 | /* |
118 | * Table driven mount option parser. | 70 | * Table driven mount option parser. |
119 | * | ||
120 | * Currently only used for remount, but it will be used for mount | ||
121 | * in the future, too. | ||
122 | */ | 71 | */ |
123 | enum { | 72 | enum { |
124 | Opt_barrier, | 73 | Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize, |
125 | Opt_nobarrier, | 74 | Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid, |
126 | Opt_inode64, | 75 | Opt_mtpt, Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups, |
127 | Opt_inode32, | 76 | Opt_allocsize, Opt_norecovery, Opt_barrier, Opt_nobarrier, |
128 | Opt_err | 77 | Opt_inode64, Opt_inode32, Opt_ikeep, Opt_noikeep, |
78 | Opt_largeio, Opt_nolargeio, Opt_attr2, Opt_noattr2, Opt_filestreams, | ||
79 | Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota, Opt_prjquota, | ||
80 | Opt_uquota, Opt_gquota, Opt_pquota, | ||
81 | Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce, | ||
82 | Opt_discard, Opt_nodiscard, Opt_dax, Opt_err, | ||
129 | }; | 83 | }; |
130 | 84 | ||
131 | static const match_table_t tokens = { | 85 | static const match_table_t tokens = { |
132 | {Opt_barrier, "barrier"}, | 86 | {Opt_logbufs, "logbufs=%u"}, /* number of XFS log buffers */ |
133 | {Opt_nobarrier, "nobarrier"}, | 87 | {Opt_logbsize, "logbsize=%s"}, /* size of XFS log buffers */ |
134 | {Opt_inode64, "inode64"}, | 88 | {Opt_logdev, "logdev=%s"}, /* log device */ |
135 | {Opt_inode32, "inode32"}, | 89 | {Opt_rtdev, "rtdev=%s"}, /* realtime I/O device */ |
136 | {Opt_err, NULL} | 90 | {Opt_biosize, "biosize=%u"}, /* log2 of preferred buffered io size */ |
91 | {Opt_wsync, "wsync"}, /* safe-mode nfs compatible mount */ | ||
92 | {Opt_noalign, "noalign"}, /* turn off stripe alignment */ | ||
93 | {Opt_swalloc, "swalloc"}, /* turn on stripe width allocation */ | ||
94 | {Opt_sunit, "sunit=%u"}, /* data volume stripe unit */ | ||
95 | {Opt_swidth, "swidth=%u"}, /* data volume stripe width */ | ||
96 | {Opt_nouuid, "nouuid"}, /* ignore filesystem UUID */ | ||
97 | {Opt_mtpt, "mtpt"}, /* filesystem mount point */ | ||
98 | {Opt_grpid, "grpid"}, /* group-ID from parent directory */ | ||
99 | {Opt_nogrpid, "nogrpid"}, /* group-ID from current process */ | ||
100 | {Opt_bsdgroups, "bsdgroups"}, /* group-ID from parent directory */ | ||
101 | {Opt_sysvgroups,"sysvgroups"}, /* group-ID from current process */ | ||
102 | {Opt_allocsize, "allocsize=%s"},/* preferred allocation size */ | ||
103 | {Opt_norecovery,"norecovery"}, /* don't run XFS recovery */ | ||
104 | {Opt_barrier, "barrier"}, /* use writer barriers for log write and | ||
105 | * unwritten extent conversion */ | ||
106 | {Opt_nobarrier, "nobarrier"}, /* .. disable */ | ||
107 | {Opt_inode64, "inode64"}, /* inodes can be allocated anywhere */ | ||
108 | {Opt_inode32, "inode32"}, /* inode allocation limited to | ||
109 | * XFS_MAXINUMBER_32 */ | ||
110 | {Opt_ikeep, "ikeep"}, /* do not free empty inode clusters */ | ||
111 | {Opt_noikeep, "noikeep"}, /* free empty inode clusters */ | ||
112 | {Opt_largeio, "largeio"}, /* report large I/O sizes in stat() */ | ||
113 | {Opt_nolargeio, "nolargeio"}, /* do not report large I/O sizes | ||
114 | * in stat(). */ | ||
115 | {Opt_attr2, "attr2"}, /* do use attr2 attribute format */ | ||
116 | {Opt_noattr2, "noattr2"}, /* do not use attr2 attribute format */ | ||
117 | {Opt_filestreams,"filestreams"},/* use filestreams allocator */ | ||
118 | {Opt_quota, "quota"}, /* disk quotas (user) */ | ||
119 | {Opt_noquota, "noquota"}, /* no quotas */ | ||
120 | {Opt_usrquota, "usrquota"}, /* user quota enabled */ | ||
121 | {Opt_grpquota, "grpquota"}, /* group quota enabled */ | ||
122 | {Opt_prjquota, "prjquota"}, /* project quota enabled */ | ||
123 | {Opt_uquota, "uquota"}, /* user quota (IRIX variant) */ | ||
124 | {Opt_gquota, "gquota"}, /* group quota (IRIX variant) */ | ||
125 | {Opt_pquota, "pquota"}, /* project quota (IRIX variant) */ | ||
126 | {Opt_uqnoenforce,"uqnoenforce"},/* user quota limit enforcement */ | ||
127 | {Opt_gqnoenforce,"gqnoenforce"},/* group quota limit enforcement */ | ||
128 | {Opt_pqnoenforce,"pqnoenforce"},/* project quota limit enforcement */ | ||
129 | {Opt_qnoenforce, "qnoenforce"}, /* same as uqnoenforce */ | ||
130 | {Opt_discard, "discard"}, /* Discard unused blocks */ | ||
131 | {Opt_nodiscard, "nodiscard"}, /* Do not discard unused blocks */ | ||
132 | |||
133 | {Opt_dax, "dax"}, /* Enable direct access to bdev pages */ | ||
134 | {Opt_err, NULL}, | ||
137 | }; | 135 | }; |
138 | 136 | ||
139 | 137 | ||
140 | STATIC int | 138 | STATIC int |
141 | suffix_kstrtoint(char *s, unsigned int base, int *res) | 139 | suffix_kstrtoint(const substring_t *s, unsigned int base, int *res) |
142 | { | 140 | { |
143 | int last, shift_left_factor = 0, _res; | 141 | int last, shift_left_factor = 0, _res; |
144 | char *value = s; | 142 | char *value; |
143 | int ret = 0; | ||
144 | |||
145 | value = match_strdup(s); | ||
146 | if (!value) | ||
147 | return -ENOMEM; | ||
145 | 148 | ||
146 | last = strlen(value) - 1; | 149 | last = strlen(value) - 1; |
147 | if (value[last] == 'K' || value[last] == 'k') { | 150 | if (value[last] == 'K' || value[last] == 'k') { |
@@ -157,10 +160,11 @@ suffix_kstrtoint(char *s, unsigned int base, int *res) | |||
157 | value[last] = '\0'; | 160 | value[last] = '\0'; |
158 | } | 161 | } |
159 | 162 | ||
160 | if (kstrtoint(s, base, &_res)) | 163 | if (kstrtoint(value, base, &_res)) |
161 | return -EINVAL; | 164 | ret = -EINVAL; |
165 | kfree(value); | ||
162 | *res = _res << shift_left_factor; | 166 | *res = _res << shift_left_factor; |
163 | return 0; | 167 | return ret; |
164 | } | 168 | } |
165 | 169 | ||
166 | /* | 170 | /* |
@@ -169,14 +173,19 @@ suffix_kstrtoint(char *s, unsigned int base, int *res) | |||
169 | * | 173 | * |
170 | * Note that this function leaks the various device name allocations on | 174 | * Note that this function leaks the various device name allocations on |
171 | * failure. The caller takes care of them. | 175 | * failure. The caller takes care of them. |
176 | * | ||
177 | * *sb is const because this is also used to test options on the remount | ||
178 | * path, and we don't want this to have any side effects at remount time. | ||
179 | * Today this function does not change *sb, but just to future-proof... | ||
172 | */ | 180 | */ |
173 | STATIC int | 181 | STATIC int |
174 | xfs_parseargs( | 182 | xfs_parseargs( |
175 | struct xfs_mount *mp, | 183 | struct xfs_mount *mp, |
176 | char *options) | 184 | char *options) |
177 | { | 185 | { |
178 | struct super_block *sb = mp->m_super; | 186 | const struct super_block *sb = mp->m_super; |
179 | char *this_char, *value; | 187 | char *p; |
188 | substring_t args[MAX_OPT_ARGS]; | ||
180 | int dsunit = 0; | 189 | int dsunit = 0; |
181 | int dswidth = 0; | 190 | int dswidth = 0; |
182 | int iosize = 0; | 191 | int iosize = 0; |
@@ -217,152 +226,152 @@ xfs_parseargs( | |||
217 | if (!options) | 226 | if (!options) |
218 | goto done; | 227 | goto done; |
219 | 228 | ||
220 | while ((this_char = strsep(&options, ",")) != NULL) { | 229 | while ((p = strsep(&options, ",")) != NULL) { |
221 | if (!*this_char) | 230 | int token; |
231 | |||
232 | if (!*p) | ||
222 | continue; | 233 | continue; |
223 | if ((value = strchr(this_char, '=')) != NULL) | ||
224 | *value++ = 0; | ||
225 | 234 | ||
226 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { | 235 | token = match_token(p, tokens, args); |
227 | if (!value || !*value) { | 236 | switch (token) { |
228 | xfs_warn(mp, "%s option requires an argument", | 237 | case Opt_logbufs: |
229 | this_char); | 238 | if (match_int(args, &mp->m_logbufs)) |
230 | return -EINVAL; | ||
231 | } | ||
232 | if (kstrtoint(value, 10, &mp->m_logbufs)) | ||
233 | return -EINVAL; | ||
234 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { | ||
235 | if (!value || !*value) { | ||
236 | xfs_warn(mp, "%s option requires an argument", | ||
237 | this_char); | ||
238 | return -EINVAL; | ||
239 | } | ||
240 | if (suffix_kstrtoint(value, 10, &mp->m_logbsize)) | ||
241 | return -EINVAL; | 239 | return -EINVAL; |
242 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { | 240 | break; |
243 | if (!value || !*value) { | 241 | case Opt_logbsize: |
244 | xfs_warn(mp, "%s option requires an argument", | 242 | if (suffix_kstrtoint(args, 10, &mp->m_logbsize)) |
245 | this_char); | ||
246 | return -EINVAL; | 243 | return -EINVAL; |
247 | } | 244 | break; |
248 | mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); | 245 | case Opt_logdev: |
246 | mp->m_logname = match_strdup(args); | ||
249 | if (!mp->m_logname) | 247 | if (!mp->m_logname) |
250 | return -ENOMEM; | 248 | return -ENOMEM; |
251 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { | 249 | break; |
252 | xfs_warn(mp, "%s option not allowed on this system", | 250 | case Opt_mtpt: |
253 | this_char); | 251 | xfs_warn(mp, "%s option not allowed on this system", p); |
254 | return -EINVAL; | 252 | return -EINVAL; |
255 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { | 253 | case Opt_rtdev: |
256 | if (!value || !*value) { | 254 | mp->m_rtname = match_strdup(args); |
257 | xfs_warn(mp, "%s option requires an argument", | ||
258 | this_char); | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); | ||
262 | if (!mp->m_rtname) | 255 | if (!mp->m_rtname) |
263 | return -ENOMEM; | 256 | return -ENOMEM; |
264 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE) || | 257 | break; |
265 | !strcmp(this_char, MNTOPT_BIOSIZE)) { | 258 | case Opt_allocsize: |
266 | if (!value || !*value) { | 259 | case Opt_biosize: |
267 | xfs_warn(mp, "%s option requires an argument", | 260 | if (suffix_kstrtoint(args, 10, &iosize)) |
268 | this_char); | ||
269 | return -EINVAL; | ||
270 | } | ||
271 | if (suffix_kstrtoint(value, 10, &iosize)) | ||
272 | return -EINVAL; | 261 | return -EINVAL; |
273 | iosizelog = ffs(iosize) - 1; | 262 | iosizelog = ffs(iosize) - 1; |
274 | } else if (!strcmp(this_char, MNTOPT_GRPID) || | 263 | break; |
275 | !strcmp(this_char, MNTOPT_BSDGROUPS)) { | 264 | case Opt_grpid: |
265 | case Opt_bsdgroups: | ||
276 | mp->m_flags |= XFS_MOUNT_GRPID; | 266 | mp->m_flags |= XFS_MOUNT_GRPID; |
277 | } else if (!strcmp(this_char, MNTOPT_NOGRPID) || | 267 | break; |
278 | !strcmp(this_char, MNTOPT_SYSVGROUPS)) { | 268 | case Opt_nogrpid: |
269 | case Opt_sysvgroups: | ||
279 | mp->m_flags &= ~XFS_MOUNT_GRPID; | 270 | mp->m_flags &= ~XFS_MOUNT_GRPID; |
280 | } else if (!strcmp(this_char, MNTOPT_WSYNC)) { | 271 | break; |
272 | case Opt_wsync: | ||
281 | mp->m_flags |= XFS_MOUNT_WSYNC; | 273 | mp->m_flags |= XFS_MOUNT_WSYNC; |
282 | } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { | 274 | break; |
275 | case Opt_norecovery: | ||
283 | mp->m_flags |= XFS_MOUNT_NORECOVERY; | 276 | mp->m_flags |= XFS_MOUNT_NORECOVERY; |
284 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { | 277 | break; |
278 | case Opt_noalign: | ||
285 | mp->m_flags |= XFS_MOUNT_NOALIGN; | 279 | mp->m_flags |= XFS_MOUNT_NOALIGN; |
286 | } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { | 280 | break; |
281 | case Opt_swalloc: | ||
287 | mp->m_flags |= XFS_MOUNT_SWALLOC; | 282 | mp->m_flags |= XFS_MOUNT_SWALLOC; |
288 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { | 283 | break; |
289 | if (!value || !*value) { | 284 | case Opt_sunit: |
290 | xfs_warn(mp, "%s option requires an argument", | 285 | if (match_int(args, &dsunit)) |
291 | this_char); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | if (kstrtoint(value, 10, &dsunit)) | ||
295 | return -EINVAL; | ||
296 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { | ||
297 | if (!value || !*value) { | ||
298 | xfs_warn(mp, "%s option requires an argument", | ||
299 | this_char); | ||
300 | return -EINVAL; | 286 | return -EINVAL; |
301 | } | 287 | break; |
302 | if (kstrtoint(value, 10, &dswidth)) | 288 | case Opt_swidth: |
289 | if (match_int(args, &dswidth)) | ||
303 | return -EINVAL; | 290 | return -EINVAL; |
304 | } else if (!strcmp(this_char, MNTOPT_32BITINODE)) { | 291 | break; |
292 | case Opt_inode32: | ||
305 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; | 293 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
306 | } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { | 294 | break; |
295 | case Opt_inode64: | ||
307 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; | 296 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
308 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { | 297 | break; |
298 | case Opt_nouuid: | ||
309 | mp->m_flags |= XFS_MOUNT_NOUUID; | 299 | mp->m_flags |= XFS_MOUNT_NOUUID; |
310 | } else if (!strcmp(this_char, MNTOPT_BARRIER)) { | 300 | break; |
301 | case Opt_barrier: | ||
311 | mp->m_flags |= XFS_MOUNT_BARRIER; | 302 | mp->m_flags |= XFS_MOUNT_BARRIER; |
312 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { | 303 | break; |
304 | case Opt_nobarrier: | ||
313 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 305 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
314 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { | 306 | break; |
307 | case Opt_ikeep: | ||
315 | mp->m_flags |= XFS_MOUNT_IKEEP; | 308 | mp->m_flags |= XFS_MOUNT_IKEEP; |
316 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { | 309 | break; |
310 | case Opt_noikeep: | ||
317 | mp->m_flags &= ~XFS_MOUNT_IKEEP; | 311 | mp->m_flags &= ~XFS_MOUNT_IKEEP; |
318 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { | 312 | break; |
313 | case Opt_largeio: | ||
319 | mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; | 314 | mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; |
320 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { | 315 | break; |
316 | case Opt_nolargeio: | ||
321 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | 317 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; |
322 | } else if (!strcmp(this_char, MNTOPT_ATTR2)) { | 318 | break; |
319 | case Opt_attr2: | ||
323 | mp->m_flags |= XFS_MOUNT_ATTR2; | 320 | mp->m_flags |= XFS_MOUNT_ATTR2; |
324 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { | 321 | break; |
322 | case Opt_noattr2: | ||
325 | mp->m_flags &= ~XFS_MOUNT_ATTR2; | 323 | mp->m_flags &= ~XFS_MOUNT_ATTR2; |
326 | mp->m_flags |= XFS_MOUNT_NOATTR2; | 324 | mp->m_flags |= XFS_MOUNT_NOATTR2; |
327 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { | 325 | break; |
326 | case Opt_filestreams: | ||
328 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | 327 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; |
329 | } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { | 328 | break; |
329 | case Opt_noquota: | ||
330 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; | 330 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; |
331 | mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; | 331 | mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; |
332 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; | 332 | mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; |
333 | } else if (!strcmp(this_char, MNTOPT_QUOTA) || | 333 | break; |
334 | !strcmp(this_char, MNTOPT_UQUOTA) || | 334 | case Opt_quota: |
335 | !strcmp(this_char, MNTOPT_USRQUOTA)) { | 335 | case Opt_uquota: |
336 | case Opt_usrquota: | ||
336 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | | 337 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | |
337 | XFS_UQUOTA_ENFD); | 338 | XFS_UQUOTA_ENFD); |
338 | } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || | 339 | break; |
339 | !strcmp(this_char, MNTOPT_UQUOTANOENF)) { | 340 | case Opt_qnoenforce: |
341 | case Opt_uqnoenforce: | ||
340 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); | 342 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); |
341 | mp->m_qflags &= ~XFS_UQUOTA_ENFD; | 343 | mp->m_qflags &= ~XFS_UQUOTA_ENFD; |
342 | } else if (!strcmp(this_char, MNTOPT_PQUOTA) || | 344 | break; |
343 | !strcmp(this_char, MNTOPT_PRJQUOTA)) { | 345 | case Opt_pquota: |
346 | case Opt_prjquota: | ||
344 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | | 347 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | |
345 | XFS_PQUOTA_ENFD); | 348 | XFS_PQUOTA_ENFD); |
346 | } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { | 349 | break; |
350 | case Opt_pqnoenforce: | ||
347 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | 351 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); |
348 | mp->m_qflags &= ~XFS_PQUOTA_ENFD; | 352 | mp->m_qflags &= ~XFS_PQUOTA_ENFD; |
349 | } else if (!strcmp(this_char, MNTOPT_GQUOTA) || | 353 | case Opt_gquota: |
350 | !strcmp(this_char, MNTOPT_GRPQUOTA)) { | 354 | case Opt_grpquota: |
351 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | | 355 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | |
352 | XFS_GQUOTA_ENFD); | 356 | XFS_GQUOTA_ENFD); |
353 | } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { | 357 | break; |
358 | case Opt_gqnoenforce: | ||
354 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | 359 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); |
355 | mp->m_qflags &= ~XFS_GQUOTA_ENFD; | 360 | mp->m_qflags &= ~XFS_GQUOTA_ENFD; |
356 | } else if (!strcmp(this_char, MNTOPT_DISCARD)) { | 361 | break; |
362 | case Opt_discard: | ||
357 | mp->m_flags |= XFS_MOUNT_DISCARD; | 363 | mp->m_flags |= XFS_MOUNT_DISCARD; |
358 | } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { | 364 | break; |
365 | case Opt_nodiscard: | ||
359 | mp->m_flags &= ~XFS_MOUNT_DISCARD; | 366 | mp->m_flags &= ~XFS_MOUNT_DISCARD; |
367 | break; | ||
360 | #ifdef CONFIG_FS_DAX | 368 | #ifdef CONFIG_FS_DAX |
361 | } else if (!strcmp(this_char, MNTOPT_DAX)) { | 369 | case Opt_dax: |
362 | mp->m_flags |= XFS_MOUNT_DAX; | 370 | mp->m_flags |= XFS_MOUNT_DAX; |
371 | break; | ||
363 | #endif | 372 | #endif |
364 | } else { | 373 | default: |
365 | xfs_warn(mp, "unknown mount option [%s].", this_char); | 374 | xfs_warn(mp, "unknown mount option [%s].", p); |
366 | return -EINVAL; | 375 | return -EINVAL; |
367 | } | 376 | } |
368 | } | 377 | } |
@@ -461,25 +470,25 @@ xfs_showargs( | |||
461 | { | 470 | { |
462 | static struct proc_xfs_info xfs_info_set[] = { | 471 | static struct proc_xfs_info xfs_info_set[] = { |
463 | /* the few simple ones we can get from the mount struct */ | 472 | /* the few simple ones we can get from the mount struct */ |
464 | { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, | 473 | { XFS_MOUNT_IKEEP, ",ikeep" }, |
465 | { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, | 474 | { XFS_MOUNT_WSYNC, ",wsync" }, |
466 | { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, | 475 | { XFS_MOUNT_NOALIGN, ",noalign" }, |
467 | { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, | 476 | { XFS_MOUNT_SWALLOC, ",swalloc" }, |
468 | { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, | 477 | { XFS_MOUNT_NOUUID, ",nouuid" }, |
469 | { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, | 478 | { XFS_MOUNT_NORECOVERY, ",norecovery" }, |
470 | { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, | 479 | { XFS_MOUNT_ATTR2, ",attr2" }, |
471 | { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, | 480 | { XFS_MOUNT_FILESTREAMS, ",filestreams" }, |
472 | { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, | 481 | { XFS_MOUNT_GRPID, ",grpid" }, |
473 | { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, | 482 | { XFS_MOUNT_DISCARD, ",discard" }, |
474 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE }, | 483 | { XFS_MOUNT_SMALL_INUMS, ",inode32" }, |
475 | { XFS_MOUNT_DAX, "," MNTOPT_DAX }, | 484 | { XFS_MOUNT_DAX, ",dax" }, |
476 | { 0, NULL } | 485 | { 0, NULL } |
477 | }; | 486 | }; |
478 | static struct proc_xfs_info xfs_info_unset[] = { | 487 | static struct proc_xfs_info xfs_info_unset[] = { |
479 | /* the few simple ones we can get from the mount struct */ | 488 | /* the few simple ones we can get from the mount struct */ |
480 | { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, | 489 | { XFS_MOUNT_COMPAT_IOSIZE, ",largeio" }, |
481 | { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, | 490 | { XFS_MOUNT_BARRIER, ",nobarrier" }, |
482 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, | 491 | { XFS_MOUNT_SMALL_INUMS, ",inode64" }, |
483 | { 0, NULL } | 492 | { 0, NULL } |
484 | }; | 493 | }; |
485 | struct proc_xfs_info *xfs_infop; | 494 | struct proc_xfs_info *xfs_infop; |
@@ -494,46 +503,46 @@ xfs_showargs( | |||
494 | } | 503 | } |
495 | 504 | ||
496 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) | 505 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) |
497 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", | 506 | seq_printf(m, ",allocsize=%dk", |
498 | (int)(1 << mp->m_writeio_log) >> 10); | 507 | (int)(1 << mp->m_writeio_log) >> 10); |
499 | 508 | ||
500 | if (mp->m_logbufs > 0) | 509 | if (mp->m_logbufs > 0) |
501 | seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); | 510 | seq_printf(m, ",logbufs=%d", mp->m_logbufs); |
502 | if (mp->m_logbsize > 0) | 511 | if (mp->m_logbsize > 0) |
503 | seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); | 512 | seq_printf(m, ",logbsize=%dk", mp->m_logbsize >> 10); |
504 | 513 | ||
505 | if (mp->m_logname) | 514 | if (mp->m_logname) |
506 | seq_show_option(m, MNTOPT_LOGDEV, mp->m_logname); | 515 | seq_show_option(m, "logdev", mp->m_logname); |
507 | if (mp->m_rtname) | 516 | if (mp->m_rtname) |
508 | seq_show_option(m, MNTOPT_RTDEV, mp->m_rtname); | 517 | seq_show_option(m, "rtdev", mp->m_rtname); |
509 | 518 | ||
510 | if (mp->m_dalign > 0) | 519 | if (mp->m_dalign > 0) |
511 | seq_printf(m, "," MNTOPT_SUNIT "=%d", | 520 | seq_printf(m, ",sunit=%d", |
512 | (int)XFS_FSB_TO_BB(mp, mp->m_dalign)); | 521 | (int)XFS_FSB_TO_BB(mp, mp->m_dalign)); |
513 | if (mp->m_swidth > 0) | 522 | if (mp->m_swidth > 0) |
514 | seq_printf(m, "," MNTOPT_SWIDTH "=%d", | 523 | seq_printf(m, ",swidth=%d", |
515 | (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); | 524 | (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); |
516 | 525 | ||
517 | if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) | 526 | if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) |
518 | seq_puts(m, "," MNTOPT_USRQUOTA); | 527 | seq_puts(m, ",usrquota"); |
519 | else if (mp->m_qflags & XFS_UQUOTA_ACCT) | 528 | else if (mp->m_qflags & XFS_UQUOTA_ACCT) |
520 | seq_puts(m, "," MNTOPT_UQUOTANOENF); | 529 | seq_puts(m, ",uqnoenforce"); |
521 | 530 | ||
522 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { | 531 | if (mp->m_qflags & XFS_PQUOTA_ACCT) { |
523 | if (mp->m_qflags & XFS_PQUOTA_ENFD) | 532 | if (mp->m_qflags & XFS_PQUOTA_ENFD) |
524 | seq_puts(m, "," MNTOPT_PRJQUOTA); | 533 | seq_puts(m, ",prjquota"); |
525 | else | 534 | else |
526 | seq_puts(m, "," MNTOPT_PQUOTANOENF); | 535 | seq_puts(m, ",pqnoenforce"); |
527 | } | 536 | } |
528 | if (mp->m_qflags & XFS_GQUOTA_ACCT) { | 537 | if (mp->m_qflags & XFS_GQUOTA_ACCT) { |
529 | if (mp->m_qflags & XFS_GQUOTA_ENFD) | 538 | if (mp->m_qflags & XFS_GQUOTA_ENFD) |
530 | seq_puts(m, "," MNTOPT_GRPQUOTA); | 539 | seq_puts(m, ",grpquota"); |
531 | else | 540 | else |
532 | seq_puts(m, "," MNTOPT_GQUOTANOENF); | 541 | seq_puts(m, ",gqnoenforce"); |
533 | } | 542 | } |
534 | 543 | ||
535 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) | 544 | if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) |
536 | seq_puts(m, "," MNTOPT_NOQUOTA); | 545 | seq_puts(m, ",noquota"); |
537 | 546 | ||
538 | return 0; | 547 | return 0; |
539 | } | 548 | } |
@@ -572,23 +581,35 @@ xfs_max_file_offset( | |||
572 | } | 581 | } |
573 | 582 | ||
574 | /* | 583 | /* |
575 | * xfs_set_inode32() and xfs_set_inode64() are passed an agcount | 584 | * Set parameters for inode allocation heuristics, taking into account |
576 | * because in the growfs case, mp->m_sb.sb_agcount is not updated | 585 | * filesystem size and inode32/inode64 mount options; i.e. specifically |
577 | * yet to the potentially higher ag count. | 586 | * whether or not XFS_MOUNT_SMALL_INUMS is set. |
587 | * | ||
588 | * Inode allocation patterns are altered only if inode32 is requested | ||
589 | * (XFS_MOUNT_SMALL_INUMS), and the filesystem is sufficiently large. | ||
590 | * If altered, XFS_MOUNT_32BITINODES is set as well. | ||
591 | * | ||
592 | * An agcount independent of that in the mount structure is provided | ||
593 | * because in the growfs case, mp->m_sb.sb_agcount is not yet updated | ||
594 | * to the potentially higher ag count. | ||
595 | * | ||
596 | * Returns the maximum AG index which may contain inodes. | ||
578 | */ | 597 | */ |
579 | xfs_agnumber_t | 598 | xfs_agnumber_t |
580 | xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount) | 599 | xfs_set_inode_alloc( |
600 | struct xfs_mount *mp, | ||
601 | xfs_agnumber_t agcount) | ||
581 | { | 602 | { |
582 | xfs_agnumber_t index = 0; | 603 | xfs_agnumber_t index; |
583 | xfs_agnumber_t maxagi = 0; | 604 | xfs_agnumber_t maxagi = 0; |
584 | xfs_sb_t *sbp = &mp->m_sb; | 605 | xfs_sb_t *sbp = &mp->m_sb; |
585 | xfs_agnumber_t max_metadata; | 606 | xfs_agnumber_t max_metadata; |
586 | xfs_agino_t agino; | 607 | xfs_agino_t agino; |
587 | xfs_ino_t ino; | 608 | xfs_ino_t ino; |
588 | xfs_perag_t *pag; | ||
589 | 609 | ||
590 | /* Calculate how much should be reserved for inodes to meet | 610 | /* |
591 | * the max inode percentage. | 611 | * Calculate how much should be reserved for inodes to meet |
612 | * the max inode percentage. Used only for inode32. | ||
592 | */ | 613 | */ |
593 | if (mp->m_maxicount) { | 614 | if (mp->m_maxicount) { |
594 | __uint64_t icount; | 615 | __uint64_t icount; |
@@ -602,54 +623,48 @@ xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount) | |||
602 | max_metadata = agcount; | 623 | max_metadata = agcount; |
603 | } | 624 | } |
604 | 625 | ||
626 | /* Get the last possible inode in the filesystem */ | ||
605 | agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); | 627 | agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); |
628 | ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino); | ||
629 | |||
630 | /* | ||
631 | * If user asked for no more than 32-bit inodes, and the fs is | ||
632 | * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter | ||
633 | * the allocator to accommodate the request. | ||
634 | */ | ||
635 | if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32) | ||
636 | mp->m_flags |= XFS_MOUNT_32BITINODES; | ||
637 | else | ||
638 | mp->m_flags &= ~XFS_MOUNT_32BITINODES; | ||
606 | 639 | ||
607 | for (index = 0; index < agcount; index++) { | 640 | for (index = 0; index < agcount; index++) { |
608 | ino = XFS_AGINO_TO_INO(mp, index, agino); | 641 | struct xfs_perag *pag; |
609 | 642 | ||
610 | if (ino > XFS_MAXINUMBER_32) { | 643 | ino = XFS_AGINO_TO_INO(mp, index, agino); |
611 | pag = xfs_perag_get(mp, index); | ||
612 | pag->pagi_inodeok = 0; | ||
613 | pag->pagf_metadata = 0; | ||
614 | xfs_perag_put(pag); | ||
615 | continue; | ||
616 | } | ||
617 | 644 | ||
618 | pag = xfs_perag_get(mp, index); | 645 | pag = xfs_perag_get(mp, index); |
619 | pag->pagi_inodeok = 1; | ||
620 | maxagi++; | ||
621 | if (index < max_metadata) | ||
622 | pag->pagf_metadata = 1; | ||
623 | xfs_perag_put(pag); | ||
624 | } | ||
625 | mp->m_flags |= (XFS_MOUNT_32BITINODES | | ||
626 | XFS_MOUNT_SMALL_INUMS); | ||
627 | 646 | ||
628 | return maxagi; | 647 | if (mp->m_flags & XFS_MOUNT_32BITINODES) { |
629 | } | 648 | if (ino > XFS_MAXINUMBER_32) { |
630 | 649 | pag->pagi_inodeok = 0; | |
631 | xfs_agnumber_t | 650 | pag->pagf_metadata = 0; |
632 | xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount) | 651 | } else { |
633 | { | 652 | pag->pagi_inodeok = 1; |
634 | xfs_agnumber_t index = 0; | 653 | maxagi++; |
635 | 654 | if (index < max_metadata) | |
636 | for (index = 0; index < agcount; index++) { | 655 | pag->pagf_metadata = 1; |
637 | struct xfs_perag *pag; | 656 | else |
657 | pag->pagf_metadata = 0; | ||
658 | } | ||
659 | } else { | ||
660 | pag->pagi_inodeok = 1; | ||
661 | pag->pagf_metadata = 0; | ||
662 | } | ||
638 | 663 | ||
639 | pag = xfs_perag_get(mp, index); | ||
640 | pag->pagi_inodeok = 1; | ||
641 | pag->pagf_metadata = 0; | ||
642 | xfs_perag_put(pag); | 664 | xfs_perag_put(pag); |
643 | } | 665 | } |
644 | 666 | ||
645 | /* There is no need for lock protection on m_flags, | 667 | return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount; |
646 | * the rw_semaphore of the VFS superblock is locked | ||
647 | * during mount/umount/remount operations, so this is | ||
648 | * enough to avoid concurency on the m_flags field | ||
649 | */ | ||
650 | mp->m_flags &= ~(XFS_MOUNT_32BITINODES | | ||
651 | XFS_MOUNT_SMALL_INUMS); | ||
652 | return index; | ||
653 | } | 668 | } |
654 | 669 | ||
655 | STATIC int | 670 | STATIC int |
@@ -1166,6 +1181,27 @@ xfs_quiesce_attr( | |||
1166 | } | 1181 | } |
1167 | 1182 | ||
1168 | STATIC int | 1183 | STATIC int |
1184 | xfs_test_remount_options( | ||
1185 | struct super_block *sb, | ||
1186 | struct xfs_mount *mp, | ||
1187 | char *options) | ||
1188 | { | ||
1189 | int error = 0; | ||
1190 | struct xfs_mount *tmp_mp; | ||
1191 | |||
1192 | tmp_mp = kmem_zalloc(sizeof(*tmp_mp), KM_MAYFAIL); | ||
1193 | if (!tmp_mp) | ||
1194 | return -ENOMEM; | ||
1195 | |||
1196 | tmp_mp->m_super = sb; | ||
1197 | error = xfs_parseargs(tmp_mp, options); | ||
1198 | xfs_free_fsname(tmp_mp); | ||
1199 | kfree(tmp_mp); | ||
1200 | |||
1201 | return error; | ||
1202 | } | ||
1203 | |||
1204 | STATIC int | ||
1169 | xfs_fs_remount( | 1205 | xfs_fs_remount( |
1170 | struct super_block *sb, | 1206 | struct super_block *sb, |
1171 | int *flags, | 1207 | int *flags, |
@@ -1177,6 +1213,11 @@ xfs_fs_remount( | |||
1177 | char *p; | 1213 | char *p; |
1178 | int error; | 1214 | int error; |
1179 | 1215 | ||
1216 | /* First, check for complete junk; i.e. invalid options */ | ||
1217 | error = xfs_test_remount_options(sb, mp, options); | ||
1218 | if (error) | ||
1219 | return error; | ||
1220 | |||
1180 | sync_filesystem(sb); | 1221 | sync_filesystem(sb); |
1181 | while ((p = strsep(&options, ",")) != NULL) { | 1222 | while ((p = strsep(&options, ",")) != NULL) { |
1182 | int token; | 1223 | int token; |
@@ -1193,10 +1234,12 @@ xfs_fs_remount( | |||
1193 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 1234 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
1194 | break; | 1235 | break; |
1195 | case Opt_inode64: | 1236 | case Opt_inode64: |
1196 | mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount); | 1237 | mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; |
1238 | mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); | ||
1197 | break; | 1239 | break; |
1198 | case Opt_inode32: | 1240 | case Opt_inode32: |
1199 | mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount); | 1241 | mp->m_flags |= XFS_MOUNT_SMALL_INUMS; |
1242 | mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount); | ||
1200 | break; | 1243 | break; |
1201 | default: | 1244 | default: |
1202 | /* | 1245 | /* |
@@ -1344,9 +1387,8 @@ xfs_finish_flags( | |||
1344 | */ | 1387 | */ |
1345 | if (xfs_sb_version_hascrc(&mp->m_sb) && | 1388 | if (xfs_sb_version_hascrc(&mp->m_sb) && |
1346 | (mp->m_flags & XFS_MOUNT_NOATTR2)) { | 1389 | (mp->m_flags & XFS_MOUNT_NOATTR2)) { |
1347 | xfs_warn(mp, | 1390 | xfs_warn(mp, "Cannot mount a V5 filesystem as noattr2. " |
1348 | "Cannot mount a V5 filesystem as %s. %s is always enabled for V5 filesystems.", | 1391 | "attr2 is always enabled for V5 filesystems."); |
1349 | MNTOPT_NOATTR2, MNTOPT_ATTR2); | ||
1350 | return -EINVAL; | 1392 | return -EINVAL; |
1351 | } | 1393 | } |
1352 | 1394 | ||
@@ -1817,6 +1859,8 @@ init_xfs_fs(void) | |||
1817 | { | 1859 | { |
1818 | int error; | 1860 | int error; |
1819 | 1861 | ||
1862 | xfs_check_ondisk_structs(); | ||
1863 | |||
1820 | printk(KERN_INFO XFS_VERSION_STRING " with " | 1864 | printk(KERN_INFO XFS_VERSION_STRING " with " |
1821 | XFS_BUILD_OPTIONS " enabled\n"); | 1865 | XFS_BUILD_OPTIONS " enabled\n"); |
1822 | 1866 | ||