aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_super.c')
-rw-r--r--fs/xfs/xfs_super.c528
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 */
65static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ 66static 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 */
123enum { 72enum {
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
131static const match_table_t tokens = { 85static 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
140STATIC int 138STATIC int
141suffix_kstrtoint(char *s, unsigned int base, int *res) 139suffix_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 */
173STATIC int 181STATIC int
174xfs_parseargs( 182xfs_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 */
579xfs_agnumber_t 598xfs_agnumber_t
580xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount) 599xfs_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;
631xfs_agnumber_t 650 pag->pagf_metadata = 0;
632xfs_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
655STATIC int 670STATIC int
@@ -1166,6 +1181,27 @@ xfs_quiesce_attr(
1166} 1181}
1167 1182
1168STATIC int 1183STATIC int
1184xfs_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
1204STATIC int
1169xfs_fs_remount( 1205xfs_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