aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2016-03-06 17:34:54 -0500
committerDave Chinner <david@fromorbit.com>2016-03-06 17:34:54 -0500
commit3c1a79f5fff9b5ef653dc8b900ce818860c1f710 (patch)
tree9d955a4a921a3c08082f15da740fe369647c32dd
parent85a9f38d382bf06e995f2b1bf114596bac08d14d (diff)
parenta7e5d03ba8882aa772c691f16690fe7e73cee257 (diff)
Merge branch 'xfs-misc-fixes-4.6-2' into for-next
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c6
-rw-r--r--fs/xfs/libxfs/xfs_bmap_btree.c4
-rw-r--r--fs/xfs/xfs_attr_list.c19
-rw-r--r--fs/xfs/xfs_discard.c2
-rw-r--r--fs/xfs/xfs_mount.c20
-rw-r--r--fs/xfs/xfs_mount.h5
-rw-r--r--fs/xfs/xfs_super.c525
-rw-r--r--fs/xfs/xfs_super.h4
-rw-r--r--fs/xfs/xfs_trans.h1
9 files changed, 304 insertions, 282 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 6a051662d8f9..cb58d728a4d0 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -5210,7 +5210,7 @@ xfs_bunmapi(
5210 * This is better than zeroing it. 5210 * This is better than zeroing it.
5211 */ 5211 */
5212 ASSERT(del.br_state == XFS_EXT_NORM); 5212 ASSERT(del.br_state == XFS_EXT_NORM);
5213 ASSERT(xfs_trans_get_block_res(tp) > 0); 5213 ASSERT(tp->t_blk_res > 0);
5214 /* 5214 /*
5215 * If this spans a realtime extent boundary, 5215 * If this spans a realtime extent boundary,
5216 * chop it back to the start of the one we end at. 5216 * chop it back to the start of the one we end at.
@@ -5241,7 +5241,7 @@ xfs_bunmapi(
5241 del.br_startblock += mod; 5241 del.br_startblock += mod;
5242 } else if ((del.br_startoff == start && 5242 } else if ((del.br_startoff == start &&
5243 (del.br_state == XFS_EXT_UNWRITTEN || 5243 (del.br_state == XFS_EXT_UNWRITTEN ||
5244 xfs_trans_get_block_res(tp) == 0)) || 5244 tp->t_blk_res == 0)) ||
5245 !xfs_sb_version_hasextflgbit(&mp->m_sb)) { 5245 !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
5246 /* 5246 /*
5247 * Can't make it unwritten. There isn't 5247 * Can't make it unwritten. There isn't
@@ -5332,7 +5332,7 @@ xfs_bunmapi(
5332 * conversion to btree format, since the transaction 5332 * conversion to btree format, since the transaction
5333 * will be dirty. 5333 * will be dirty.
5334 */ 5334 */
5335 if (!wasdel && xfs_trans_get_block_res(tp) == 0 && 5335 if (!wasdel && tp->t_blk_res == 0 &&
5336 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && 5336 XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
5337 XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ 5337 XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */
5338 XFS_IFORK_MAXEXT(ip, whichfork) && 5338 XFS_IFORK_MAXEXT(ip, whichfork) &&
diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c
index e37508ae589b..6282f6e708af 100644
--- a/fs/xfs/libxfs/xfs_bmap_btree.c
+++ b/fs/xfs/libxfs/xfs_bmap_btree.c
@@ -461,7 +461,7 @@ xfs_bmbt_alloc_block(
461 * reservation amount is insufficient then we may fail a 461 * reservation amount is insufficient then we may fail a
462 * block allocation here and corrupt the filesystem. 462 * block allocation here and corrupt the filesystem.
463 */ 463 */
464 args.minleft = xfs_trans_get_block_res(args.tp); 464 args.minleft = args.tp->t_blk_res;
465 } else if (cur->bc_private.b.flist->xbf_low) { 465 } else if (cur->bc_private.b.flist->xbf_low) {
466 args.type = XFS_ALLOCTYPE_START_BNO; 466 args.type = XFS_ALLOCTYPE_START_BNO;
467 } else { 467 } else {
@@ -470,7 +470,7 @@ xfs_bmbt_alloc_block(
470 470
471 args.minlen = args.maxlen = args.prod = 1; 471 args.minlen = args.maxlen = args.prod = 1;
472 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; 472 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
473 if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) { 473 if (!args.wasdel && args.tp->t_blk_res == 0) {
474 error = -ENOSPC; 474 error = -ENOSPC;
475 goto error0; 475 goto error0;
476 } 476 }
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 0ef7c2ed3f8a..4fa14820e2e2 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -202,8 +202,10 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
202 sbp->namelen, 202 sbp->namelen,
203 sbp->valuelen, 203 sbp->valuelen,
204 &sbp->name[sbp->namelen]); 204 &sbp->name[sbp->namelen]);
205 if (error) 205 if (error) {
206 kmem_free(sbuf);
206 return error; 207 return error;
208 }
207 if (context->seen_enough) 209 if (context->seen_enough)
208 break; 210 break;
209 cursor->offset++; 211 cursor->offset++;
@@ -454,14 +456,13 @@ xfs_attr3_leaf_list_int(
454 args.rmtblkcnt = xfs_attr3_rmt_blocks( 456 args.rmtblkcnt = xfs_attr3_rmt_blocks(
455 args.dp->i_mount, valuelen); 457 args.dp->i_mount, valuelen);
456 retval = xfs_attr_rmtval_get(&args); 458 retval = xfs_attr_rmtval_get(&args);
457 if (retval) 459 if (!retval)
458 return retval; 460 retval = context->put_listent(context,
459 retval = context->put_listent(context, 461 entry->flags,
460 entry->flags, 462 name_rmt->name,
461 name_rmt->name, 463 (int)name_rmt->namelen,
462 (int)name_rmt->namelen, 464 valuelen,
463 valuelen, 465 args.value);
464 args.value);
465 kmem_free(args.value); 466 kmem_free(args.value);
466 } else { 467 } else {
467 retval = context->put_listent(context, 468 retval = context->put_listent(context,
diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c
index e85a9519a5ae..272c3f8b6f7d 100644
--- a/fs/xfs/xfs_discard.c
+++ b/fs/xfs/xfs_discard.c
@@ -227,7 +227,7 @@ xfs_discard_extents(
227 GFP_NOFS, 0); 227 GFP_NOFS, 0);
228 if (error && error != -EOPNOTSUPP) { 228 if (error && error != -EOPNOTSUPP) {
229 xfs_info(mp, 229 xfs_info(mp,
230 "discard failed for extent [0x%llu,%u], error %d", 230 "discard failed for extent [0x%llx,%u], error %d",
231 (unsigned long long)busyp->bno, 231 (unsigned long long)busyp->bno,
232 busyp->length, 232 busyp->length,
233 error); 233 error);
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 986290c4b7ab..536a0ee9cd5a 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -185,9 +185,6 @@ xfs_initialize_perag(
185 xfs_agnumber_t index; 185 xfs_agnumber_t index;
186 xfs_agnumber_t first_initialised = 0; 186 xfs_agnumber_t first_initialised = 0;
187 xfs_perag_t *pag; 187 xfs_perag_t *pag;
188 xfs_agino_t agino;
189 xfs_ino_t ino;
190 xfs_sb_t *sbp = &mp->m_sb;
191 int error = -ENOMEM; 188 int error = -ENOMEM;
192 189
193 /* 190 /*
@@ -230,22 +227,7 @@ xfs_initialize_perag(
230 radix_tree_preload_end(); 227 radix_tree_preload_end();
231 } 228 }
232 229
233 /* 230 index = xfs_set_inode_alloc(mp, agcount);
234 * If we mount with the inode64 option, or no inode overflows
235 * the legacy 32-bit address space clear the inode32 option.
236 */
237 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
238 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
239
240 if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
241 mp->m_flags |= XFS_MOUNT_32BITINODES;
242 else
243 mp->m_flags &= ~XFS_MOUNT_32BITINODES;
244
245 if (mp->m_flags & XFS_MOUNT_32BITINODES)
246 index = xfs_set_inode32(mp, agcount);
247 else
248 index = xfs_set_inode64(mp, agcount);
249 231
250 if (maxagi) 232 if (maxagi)
251 *maxagi = index; 233 *maxagi = index;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index a4e03ab50342..1c8611f6b464 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -166,9 +166,8 @@ typedef struct xfs_mount {
166#define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */ 166#define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */
167#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ 167#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */
168#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ 168#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */
169#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above 169#define XFS_MOUNT_SMALL_INUMS (1ULL << 14) /* user wants 32bit inodes */
170 * 32 bits in size */ 170#define XFS_MOUNT_32BITINODES (1ULL << 15) /* inode32 allocator active */
171#define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */
172#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ 171#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */
173#define XFS_MOUNT_BARRIER (1ULL << 17) 172#define XFS_MOUNT_BARRIER (1ULL << 17)
174#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ 173#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 59c9b7bd958d..d85087bc0c40 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -65,83 +65,85 @@ static struct kset *xfs_kset; /* top-level xfs sysfs dir */
65static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ 65static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */
66#endif 66#endif
67 67
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/* 68/*
118 * Table driven mount option parser. 69 * 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 */ 70 */
123enum { 71enum {
124 Opt_barrier, 72 Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
125 Opt_nobarrier, 73 Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid,
126 Opt_inode64, 74 Opt_mtpt, Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups,
127 Opt_inode32, 75 Opt_allocsize, Opt_norecovery, Opt_barrier, Opt_nobarrier,
128 Opt_err 76 Opt_inode64, Opt_inode32, Opt_ikeep, Opt_noikeep,
77 Opt_largeio, Opt_nolargeio, Opt_attr2, Opt_noattr2, Opt_filestreams,
78 Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota, Opt_prjquota,
79 Opt_uquota, Opt_gquota, Opt_pquota,
80 Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce,
81 Opt_discard, Opt_nodiscard, Opt_dax, Opt_err,
129}; 82};
130 83
131static const match_table_t tokens = { 84static const match_table_t tokens = {
132 {Opt_barrier, "barrier"}, 85 {Opt_logbufs, "logbufs=%u"}, /* number of XFS log buffers */
133 {Opt_nobarrier, "nobarrier"}, 86 {Opt_logbsize, "logbsize=%s"}, /* size of XFS log buffers */
134 {Opt_inode64, "inode64"}, 87 {Opt_logdev, "logdev=%s"}, /* log device */
135 {Opt_inode32, "inode32"}, 88 {Opt_rtdev, "rtdev=%s"}, /* realtime I/O device */
136 {Opt_err, NULL} 89 {Opt_biosize, "biosize=%u"}, /* log2 of preferred buffered io size */
90 {Opt_wsync, "wsync"}, /* safe-mode nfs compatible mount */
91 {Opt_noalign, "noalign"}, /* turn off stripe alignment */
92 {Opt_swalloc, "swalloc"}, /* turn on stripe width allocation */
93 {Opt_sunit, "sunit=%u"}, /* data volume stripe unit */
94 {Opt_swidth, "swidth=%u"}, /* data volume stripe width */
95 {Opt_nouuid, "nouuid"}, /* ignore filesystem UUID */
96 {Opt_mtpt, "mtpt"}, /* filesystem mount point */
97 {Opt_grpid, "grpid"}, /* group-ID from parent directory */
98 {Opt_nogrpid, "nogrpid"}, /* group-ID from current process */
99 {Opt_bsdgroups, "bsdgroups"}, /* group-ID from parent directory */
100 {Opt_sysvgroups,"sysvgroups"}, /* group-ID from current process */
101 {Opt_allocsize, "allocsize=%s"},/* preferred allocation size */
102 {Opt_norecovery,"norecovery"}, /* don't run XFS recovery */
103 {Opt_barrier, "barrier"}, /* use writer barriers for log write and
104 * unwritten extent conversion */
105 {Opt_nobarrier, "nobarrier"}, /* .. disable */
106 {Opt_inode64, "inode64"}, /* inodes can be allocated anywhere */
107 {Opt_inode32, "inode32"}, /* inode allocation limited to
108 * XFS_MAXINUMBER_32 */
109 {Opt_ikeep, "ikeep"}, /* do not free empty inode clusters */
110 {Opt_noikeep, "noikeep"}, /* free empty inode clusters */
111 {Opt_largeio, "largeio"}, /* report large I/O sizes in stat() */
112 {Opt_nolargeio, "nolargeio"}, /* do not report large I/O sizes
113 * in stat(). */
114 {Opt_attr2, "attr2"}, /* do use attr2 attribute format */
115 {Opt_noattr2, "noattr2"}, /* do not use attr2 attribute format */
116 {Opt_filestreams,"filestreams"},/* use filestreams allocator */
117 {Opt_quota, "quota"}, /* disk quotas (user) */
118 {Opt_noquota, "noquota"}, /* no quotas */
119 {Opt_usrquota, "usrquota"}, /* user quota enabled */
120 {Opt_grpquota, "grpquota"}, /* group quota enabled */
121 {Opt_prjquota, "prjquota"}, /* project quota enabled */
122 {Opt_uquota, "uquota"}, /* user quota (IRIX variant) */
123 {Opt_gquota, "gquota"}, /* group quota (IRIX variant) */
124 {Opt_pquota, "pquota"}, /* project quota (IRIX variant) */
125 {Opt_uqnoenforce,"uqnoenforce"},/* user quota limit enforcement */
126 {Opt_gqnoenforce,"gqnoenforce"},/* group quota limit enforcement */
127 {Opt_pqnoenforce,"pqnoenforce"},/* project quota limit enforcement */
128 {Opt_qnoenforce, "qnoenforce"}, /* same as uqnoenforce */
129 {Opt_discard, "discard"}, /* Discard unused blocks */
130 {Opt_nodiscard, "nodiscard"}, /* Do not discard unused blocks */
131
132 {Opt_dax, "dax"}, /* Enable direct access to bdev pages */
133 {Opt_err, NULL},
137}; 134};
138 135
139 136
140STATIC int 137STATIC int
141suffix_kstrtoint(char *s, unsigned int base, int *res) 138suffix_kstrtoint(const substring_t *s, unsigned int base, int *res)
142{ 139{
143 int last, shift_left_factor = 0, _res; 140 int last, shift_left_factor = 0, _res;
144 char *value = s; 141 char *value;
142 int ret = 0;
143
144 value = match_strdup(s);
145 if (!value)
146 return -ENOMEM;
145 147
146 last = strlen(value) - 1; 148 last = strlen(value) - 1;
147 if (value[last] == 'K' || value[last] == 'k') { 149 if (value[last] == 'K' || value[last] == 'k') {
@@ -157,10 +159,11 @@ suffix_kstrtoint(char *s, unsigned int base, int *res)
157 value[last] = '\0'; 159 value[last] = '\0';
158 } 160 }
159 161
160 if (kstrtoint(s, base, &_res)) 162 if (kstrtoint(value, base, &_res))
161 return -EINVAL; 163 ret = -EINVAL;
164 kfree(value);
162 *res = _res << shift_left_factor; 165 *res = _res << shift_left_factor;
163 return 0; 166 return ret;
164} 167}
165 168
166/* 169/*
@@ -169,14 +172,19 @@ suffix_kstrtoint(char *s, unsigned int base, int *res)
169 * 172 *
170 * Note that this function leaks the various device name allocations on 173 * Note that this function leaks the various device name allocations on
171 * failure. The caller takes care of them. 174 * failure. The caller takes care of them.
175 *
176 * *sb is const because this is also used to test options on the remount
177 * path, and we don't want this to have any side effects at remount time.
178 * Today this function does not change *sb, but just to future-proof...
172 */ 179 */
173STATIC int 180STATIC int
174xfs_parseargs( 181xfs_parseargs(
175 struct xfs_mount *mp, 182 struct xfs_mount *mp,
176 char *options) 183 char *options)
177{ 184{
178 struct super_block *sb = mp->m_super; 185 const struct super_block *sb = mp->m_super;
179 char *this_char, *value; 186 char *p;
187 substring_t args[MAX_OPT_ARGS];
180 int dsunit = 0; 188 int dsunit = 0;
181 int dswidth = 0; 189 int dswidth = 0;
182 int iosize = 0; 190 int iosize = 0;
@@ -217,152 +225,152 @@ xfs_parseargs(
217 if (!options) 225 if (!options)
218 goto done; 226 goto done;
219 227
220 while ((this_char = strsep(&options, ",")) != NULL) { 228 while ((p = strsep(&options, ",")) != NULL) {
221 if (!*this_char) 229 int token;
230
231 if (!*p)
222 continue; 232 continue;
223 if ((value = strchr(this_char, '=')) != NULL)
224 *value++ = 0;
225 233
226 if (!strcmp(this_char, MNTOPT_LOGBUFS)) { 234 token = match_token(p, tokens, args);
227 if (!value || !*value) { 235 switch (token) {
228 xfs_warn(mp, "%s option requires an argument", 236 case Opt_logbufs:
229 this_char); 237 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; 238 return -EINVAL;
242 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { 239 break;
243 if (!value || !*value) { 240 case Opt_logbsize:
244 xfs_warn(mp, "%s option requires an argument", 241 if (suffix_kstrtoint(args, 10, &mp->m_logbsize))
245 this_char);
246 return -EINVAL; 242 return -EINVAL;
247 } 243 break;
248 mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL); 244 case Opt_logdev:
245 mp->m_logname = match_strdup(args);
249 if (!mp->m_logname) 246 if (!mp->m_logname)
250 return -ENOMEM; 247 return -ENOMEM;
251 } else if (!strcmp(this_char, MNTOPT_MTPT)) { 248 break;
252 xfs_warn(mp, "%s option not allowed on this system", 249 case Opt_mtpt:
253 this_char); 250 xfs_warn(mp, "%s option not allowed on this system", p);
254 return -EINVAL; 251 return -EINVAL;
255 } else if (!strcmp(this_char, MNTOPT_RTDEV)) { 252 case Opt_rtdev:
256 if (!value || !*value) { 253 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) 254 if (!mp->m_rtname)
263 return -ENOMEM; 255 return -ENOMEM;
264 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE) || 256 break;
265 !strcmp(this_char, MNTOPT_BIOSIZE)) { 257 case Opt_allocsize:
266 if (!value || !*value) { 258 case Opt_biosize:
267 xfs_warn(mp, "%s option requires an argument", 259 if (suffix_kstrtoint(args, 10, &iosize))
268 this_char);
269 return -EINVAL;
270 }
271 if (suffix_kstrtoint(value, 10, &iosize))
272 return -EINVAL; 260 return -EINVAL;
273 iosizelog = ffs(iosize) - 1; 261 iosizelog = ffs(iosize) - 1;
274 } else if (!strcmp(this_char, MNTOPT_GRPID) || 262 break;
275 !strcmp(this_char, MNTOPT_BSDGROUPS)) { 263 case Opt_grpid:
264 case Opt_bsdgroups:
276 mp->m_flags |= XFS_MOUNT_GRPID; 265 mp->m_flags |= XFS_MOUNT_GRPID;
277 } else if (!strcmp(this_char, MNTOPT_NOGRPID) || 266 break;
278 !strcmp(this_char, MNTOPT_SYSVGROUPS)) { 267 case Opt_nogrpid:
268 case Opt_sysvgroups:
279 mp->m_flags &= ~XFS_MOUNT_GRPID; 269 mp->m_flags &= ~XFS_MOUNT_GRPID;
280 } else if (!strcmp(this_char, MNTOPT_WSYNC)) { 270 break;
271 case Opt_wsync:
281 mp->m_flags |= XFS_MOUNT_WSYNC; 272 mp->m_flags |= XFS_MOUNT_WSYNC;
282 } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { 273 break;
274 case Opt_norecovery:
283 mp->m_flags |= XFS_MOUNT_NORECOVERY; 275 mp->m_flags |= XFS_MOUNT_NORECOVERY;
284 } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { 276 break;
277 case Opt_noalign:
285 mp->m_flags |= XFS_MOUNT_NOALIGN; 278 mp->m_flags |= XFS_MOUNT_NOALIGN;
286 } else if (!strcmp(this_char, MNTOPT_SWALLOC)) { 279 break;
280 case Opt_swalloc:
287 mp->m_flags |= XFS_MOUNT_SWALLOC; 281 mp->m_flags |= XFS_MOUNT_SWALLOC;
288 } else if (!strcmp(this_char, MNTOPT_SUNIT)) { 282 break;
289 if (!value || !*value) { 283 case Opt_sunit:
290 xfs_warn(mp, "%s option requires an argument", 284 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; 285 return -EINVAL;
301 } 286 break;
302 if (kstrtoint(value, 10, &dswidth)) 287 case Opt_swidth:
288 if (match_int(args, &dswidth))
303 return -EINVAL; 289 return -EINVAL;
304 } else if (!strcmp(this_char, MNTOPT_32BITINODE)) { 290 break;
291 case Opt_inode32:
305 mp->m_flags |= XFS_MOUNT_SMALL_INUMS; 292 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
306 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { 293 break;
294 case Opt_inode64:
307 mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; 295 mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
308 } else if (!strcmp(this_char, MNTOPT_NOUUID)) { 296 break;
297 case Opt_nouuid:
309 mp->m_flags |= XFS_MOUNT_NOUUID; 298 mp->m_flags |= XFS_MOUNT_NOUUID;
310 } else if (!strcmp(this_char, MNTOPT_BARRIER)) { 299 break;
300 case Opt_barrier:
311 mp->m_flags |= XFS_MOUNT_BARRIER; 301 mp->m_flags |= XFS_MOUNT_BARRIER;
312 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { 302 break;
303 case Opt_nobarrier:
313 mp->m_flags &= ~XFS_MOUNT_BARRIER; 304 mp->m_flags &= ~XFS_MOUNT_BARRIER;
314 } else if (!strcmp(this_char, MNTOPT_IKEEP)) { 305 break;
306 case Opt_ikeep:
315 mp->m_flags |= XFS_MOUNT_IKEEP; 307 mp->m_flags |= XFS_MOUNT_IKEEP;
316 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { 308 break;
309 case Opt_noikeep:
317 mp->m_flags &= ~XFS_MOUNT_IKEEP; 310 mp->m_flags &= ~XFS_MOUNT_IKEEP;
318 } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { 311 break;
312 case Opt_largeio:
319 mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; 313 mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
320 } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { 314 break;
315 case Opt_nolargeio:
321 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; 316 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
322 } else if (!strcmp(this_char, MNTOPT_ATTR2)) { 317 break;
318 case Opt_attr2:
323 mp->m_flags |= XFS_MOUNT_ATTR2; 319 mp->m_flags |= XFS_MOUNT_ATTR2;
324 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { 320 break;
321 case Opt_noattr2:
325 mp->m_flags &= ~XFS_MOUNT_ATTR2; 322 mp->m_flags &= ~XFS_MOUNT_ATTR2;
326 mp->m_flags |= XFS_MOUNT_NOATTR2; 323 mp->m_flags |= XFS_MOUNT_NOATTR2;
327 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { 324 break;
325 case Opt_filestreams:
328 mp->m_flags |= XFS_MOUNT_FILESTREAMS; 326 mp->m_flags |= XFS_MOUNT_FILESTREAMS;
329 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { 327 break;
328 case Opt_noquota:
330 mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; 329 mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
331 mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; 330 mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
332 mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; 331 mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
333 } else if (!strcmp(this_char, MNTOPT_QUOTA) || 332 break;
334 !strcmp(this_char, MNTOPT_UQUOTA) || 333 case Opt_quota:
335 !strcmp(this_char, MNTOPT_USRQUOTA)) { 334 case Opt_uquota:
335 case Opt_usrquota:
336 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | 336 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
337 XFS_UQUOTA_ENFD); 337 XFS_UQUOTA_ENFD);
338 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || 338 break;
339 !strcmp(this_char, MNTOPT_UQUOTANOENF)) { 339 case Opt_qnoenforce:
340 case Opt_uqnoenforce:
340 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); 341 mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
341 mp->m_qflags &= ~XFS_UQUOTA_ENFD; 342 mp->m_qflags &= ~XFS_UQUOTA_ENFD;
342 } else if (!strcmp(this_char, MNTOPT_PQUOTA) || 343 break;
343 !strcmp(this_char, MNTOPT_PRJQUOTA)) { 344 case Opt_pquota:
345 case Opt_prjquota:
344 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | 346 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
345 XFS_PQUOTA_ENFD); 347 XFS_PQUOTA_ENFD);
346 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { 348 break;
349 case Opt_pqnoenforce:
347 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); 350 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
348 mp->m_qflags &= ~XFS_PQUOTA_ENFD; 351 mp->m_qflags &= ~XFS_PQUOTA_ENFD;
349 } else if (!strcmp(this_char, MNTOPT_GQUOTA) || 352 case Opt_gquota:
350 !strcmp(this_char, MNTOPT_GRPQUOTA)) { 353 case Opt_grpquota:
351 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | 354 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
352 XFS_GQUOTA_ENFD); 355 XFS_GQUOTA_ENFD);
353 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { 356 break;
357 case Opt_gqnoenforce:
354 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); 358 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
355 mp->m_qflags &= ~XFS_GQUOTA_ENFD; 359 mp->m_qflags &= ~XFS_GQUOTA_ENFD;
356 } else if (!strcmp(this_char, MNTOPT_DISCARD)) { 360 break;
361 case Opt_discard:
357 mp->m_flags |= XFS_MOUNT_DISCARD; 362 mp->m_flags |= XFS_MOUNT_DISCARD;
358 } else if (!strcmp(this_char, MNTOPT_NODISCARD)) { 363 break;
364 case Opt_nodiscard:
359 mp->m_flags &= ~XFS_MOUNT_DISCARD; 365 mp->m_flags &= ~XFS_MOUNT_DISCARD;
366 break;
360#ifdef CONFIG_FS_DAX 367#ifdef CONFIG_FS_DAX
361 } else if (!strcmp(this_char, MNTOPT_DAX)) { 368 case Opt_dax:
362 mp->m_flags |= XFS_MOUNT_DAX; 369 mp->m_flags |= XFS_MOUNT_DAX;
370 break;
363#endif 371#endif
364 } else { 372 default:
365 xfs_warn(mp, "unknown mount option [%s].", this_char); 373 xfs_warn(mp, "unknown mount option [%s].", p);
366 return -EINVAL; 374 return -EINVAL;
367 } 375 }
368 } 376 }
@@ -461,25 +469,25 @@ xfs_showargs(
461{ 469{
462 static struct proc_xfs_info xfs_info_set[] = { 470 static struct proc_xfs_info xfs_info_set[] = {
463 /* the few simple ones we can get from the mount struct */ 471 /* the few simple ones we can get from the mount struct */
464 { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, 472 { XFS_MOUNT_IKEEP, ",ikeep" },
465 { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, 473 { XFS_MOUNT_WSYNC, ",wsync" },
466 { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, 474 { XFS_MOUNT_NOALIGN, ",noalign" },
467 { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, 475 { XFS_MOUNT_SWALLOC, ",swalloc" },
468 { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, 476 { XFS_MOUNT_NOUUID, ",nouuid" },
469 { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, 477 { XFS_MOUNT_NORECOVERY, ",norecovery" },
470 { XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, 478 { XFS_MOUNT_ATTR2, ",attr2" },
471 { XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, 479 { XFS_MOUNT_FILESTREAMS, ",filestreams" },
472 { XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, 480 { XFS_MOUNT_GRPID, ",grpid" },
473 { XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, 481 { XFS_MOUNT_DISCARD, ",discard" },
474 { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE }, 482 { XFS_MOUNT_SMALL_INUMS, ",inode32" },
475 { XFS_MOUNT_DAX, "," MNTOPT_DAX }, 483 { XFS_MOUNT_DAX, ",dax" },
476 { 0, NULL } 484 { 0, NULL }
477 }; 485 };
478 static struct proc_xfs_info xfs_info_unset[] = { 486 static struct proc_xfs_info xfs_info_unset[] = {
479 /* the few simple ones we can get from the mount struct */ 487 /* the few simple ones we can get from the mount struct */
480 { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, 488 { XFS_MOUNT_COMPAT_IOSIZE, ",largeio" },
481 { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, 489 { XFS_MOUNT_BARRIER, ",nobarrier" },
482 { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, 490 { XFS_MOUNT_SMALL_INUMS, ",inode64" },
483 { 0, NULL } 491 { 0, NULL }
484 }; 492 };
485 struct proc_xfs_info *xfs_infop; 493 struct proc_xfs_info *xfs_infop;
@@ -494,46 +502,46 @@ xfs_showargs(
494 } 502 }
495 503
496 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) 504 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
497 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", 505 seq_printf(m, ",allocsize=%dk",
498 (int)(1 << mp->m_writeio_log) >> 10); 506 (int)(1 << mp->m_writeio_log) >> 10);
499 507
500 if (mp->m_logbufs > 0) 508 if (mp->m_logbufs > 0)
501 seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); 509 seq_printf(m, ",logbufs=%d", mp->m_logbufs);
502 if (mp->m_logbsize > 0) 510 if (mp->m_logbsize > 0)
503 seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); 511 seq_printf(m, ",logbsize=%dk", mp->m_logbsize >> 10);
504 512
505 if (mp->m_logname) 513 if (mp->m_logname)
506 seq_show_option(m, MNTOPT_LOGDEV, mp->m_logname); 514 seq_show_option(m, "logdev", mp->m_logname);
507 if (mp->m_rtname) 515 if (mp->m_rtname)
508 seq_show_option(m, MNTOPT_RTDEV, mp->m_rtname); 516 seq_show_option(m, "rtdev", mp->m_rtname);
509 517
510 if (mp->m_dalign > 0) 518 if (mp->m_dalign > 0)
511 seq_printf(m, "," MNTOPT_SUNIT "=%d", 519 seq_printf(m, ",sunit=%d",
512 (int)XFS_FSB_TO_BB(mp, mp->m_dalign)); 520 (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
513 if (mp->m_swidth > 0) 521 if (mp->m_swidth > 0)
514 seq_printf(m, "," MNTOPT_SWIDTH "=%d", 522 seq_printf(m, ",swidth=%d",
515 (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); 523 (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
516 524
517 if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) 525 if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD))
518 seq_puts(m, "," MNTOPT_USRQUOTA); 526 seq_puts(m, ",usrquota");
519 else if (mp->m_qflags & XFS_UQUOTA_ACCT) 527 else if (mp->m_qflags & XFS_UQUOTA_ACCT)
520 seq_puts(m, "," MNTOPT_UQUOTANOENF); 528 seq_puts(m, ",uqnoenforce");
521 529
522 if (mp->m_qflags & XFS_PQUOTA_ACCT) { 530 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
523 if (mp->m_qflags & XFS_PQUOTA_ENFD) 531 if (mp->m_qflags & XFS_PQUOTA_ENFD)
524 seq_puts(m, "," MNTOPT_PRJQUOTA); 532 seq_puts(m, ",prjquota");
525 else 533 else
526 seq_puts(m, "," MNTOPT_PQUOTANOENF); 534 seq_puts(m, ",pqnoenforce");
527 } 535 }
528 if (mp->m_qflags & XFS_GQUOTA_ACCT) { 536 if (mp->m_qflags & XFS_GQUOTA_ACCT) {
529 if (mp->m_qflags & XFS_GQUOTA_ENFD) 537 if (mp->m_qflags & XFS_GQUOTA_ENFD)
530 seq_puts(m, "," MNTOPT_GRPQUOTA); 538 seq_puts(m, ",grpquota");
531 else 539 else
532 seq_puts(m, "," MNTOPT_GQUOTANOENF); 540 seq_puts(m, ",gqnoenforce");
533 } 541 }
534 542
535 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) 543 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
536 seq_puts(m, "," MNTOPT_NOQUOTA); 544 seq_puts(m, ",noquota");
537 545
538 return 0; 546 return 0;
539} 547}
@@ -572,23 +580,35 @@ xfs_max_file_offset(
572} 580}
573 581
574/* 582/*
575 * xfs_set_inode32() and xfs_set_inode64() are passed an agcount 583 * Set parameters for inode allocation heuristics, taking into account
576 * because in the growfs case, mp->m_sb.sb_agcount is not updated 584 * filesystem size and inode32/inode64 mount options; i.e. specifically
577 * yet to the potentially higher ag count. 585 * whether or not XFS_MOUNT_SMALL_INUMS is set.
586 *
587 * Inode allocation patterns are altered only if inode32 is requested
588 * (XFS_MOUNT_SMALL_INUMS), and the filesystem is sufficiently large.
589 * If altered, XFS_MOUNT_32BITINODES is set as well.
590 *
591 * An agcount independent of that in the mount structure is provided
592 * because in the growfs case, mp->m_sb.sb_agcount is not yet updated
593 * to the potentially higher ag count.
594 *
595 * Returns the maximum AG index which may contain inodes.
578 */ 596 */
579xfs_agnumber_t 597xfs_agnumber_t
580xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount) 598xfs_set_inode_alloc(
599 struct xfs_mount *mp,
600 xfs_agnumber_t agcount)
581{ 601{
582 xfs_agnumber_t index = 0; 602 xfs_agnumber_t index;
583 xfs_agnumber_t maxagi = 0; 603 xfs_agnumber_t maxagi = 0;
584 xfs_sb_t *sbp = &mp->m_sb; 604 xfs_sb_t *sbp = &mp->m_sb;
585 xfs_agnumber_t max_metadata; 605 xfs_agnumber_t max_metadata;
586 xfs_agino_t agino; 606 xfs_agino_t agino;
587 xfs_ino_t ino; 607 xfs_ino_t ino;
588 xfs_perag_t *pag;
589 608
590 /* Calculate how much should be reserved for inodes to meet 609 /*
591 * the max inode percentage. 610 * Calculate how much should be reserved for inodes to meet
611 * the max inode percentage. Used only for inode32.
592 */ 612 */
593 if (mp->m_maxicount) { 613 if (mp->m_maxicount) {
594 __uint64_t icount; 614 __uint64_t icount;
@@ -602,54 +622,48 @@ xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
602 max_metadata = agcount; 622 max_metadata = agcount;
603 } 623 }
604 624
625 /* Get the last possible inode in the filesystem */
605 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); 626 agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
627 ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
628
629 /*
630 * If user asked for no more than 32-bit inodes, and the fs is
631 * sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
632 * the allocator to accommodate the request.
633 */
634 if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
635 mp->m_flags |= XFS_MOUNT_32BITINODES;
636 else
637 mp->m_flags &= ~XFS_MOUNT_32BITINODES;
606 638
607 for (index = 0; index < agcount; index++) { 639 for (index = 0; index < agcount; index++) {
608 ino = XFS_AGINO_TO_INO(mp, index, agino); 640 struct xfs_perag *pag;
609 641
610 if (ino > XFS_MAXINUMBER_32) { 642 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 643
618 pag = xfs_perag_get(mp, index); 644 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
628 return maxagi;
629}
630 645
631xfs_agnumber_t 646 if (mp->m_flags & XFS_MOUNT_32BITINODES) {
632xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount) 647 if (ino > XFS_MAXINUMBER_32) {
633{ 648 pag->pagi_inodeok = 0;
634 xfs_agnumber_t index = 0; 649 pag->pagf_metadata = 0;
635 650 } else {
636 for (index = 0; index < agcount; index++) { 651 pag->pagi_inodeok = 1;
637 struct xfs_perag *pag; 652 maxagi++;
653 if (index < max_metadata)
654 pag->pagf_metadata = 1;
655 else
656 pag->pagf_metadata = 0;
657 }
658 } else {
659 pag->pagi_inodeok = 1;
660 pag->pagf_metadata = 0;
661 }
638 662
639 pag = xfs_perag_get(mp, index);
640 pag->pagi_inodeok = 1;
641 pag->pagf_metadata = 0;
642 xfs_perag_put(pag); 663 xfs_perag_put(pag);
643 } 664 }
644 665
645 /* There is no need for lock protection on m_flags, 666 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} 667}
654 668
655STATIC int 669STATIC int
@@ -1166,6 +1180,27 @@ xfs_quiesce_attr(
1166} 1180}
1167 1181
1168STATIC int 1182STATIC int
1183xfs_test_remount_options(
1184 struct super_block *sb,
1185 struct xfs_mount *mp,
1186 char *options)
1187{
1188 int error = 0;
1189 struct xfs_mount *tmp_mp;
1190
1191 tmp_mp = kmem_zalloc(sizeof(*tmp_mp), KM_MAYFAIL);
1192 if (!tmp_mp)
1193 return -ENOMEM;
1194
1195 tmp_mp->m_super = sb;
1196 error = xfs_parseargs(tmp_mp, options);
1197 xfs_free_fsname(tmp_mp);
1198 kfree(tmp_mp);
1199
1200 return error;
1201}
1202
1203STATIC int
1169xfs_fs_remount( 1204xfs_fs_remount(
1170 struct super_block *sb, 1205 struct super_block *sb,
1171 int *flags, 1206 int *flags,
@@ -1177,6 +1212,11 @@ xfs_fs_remount(
1177 char *p; 1212 char *p;
1178 int error; 1213 int error;
1179 1214
1215 /* First, check for complete junk; i.e. invalid options */
1216 error = xfs_test_remount_options(sb, mp, options);
1217 if (error)
1218 return error;
1219
1180 sync_filesystem(sb); 1220 sync_filesystem(sb);
1181 while ((p = strsep(&options, ",")) != NULL) { 1221 while ((p = strsep(&options, ",")) != NULL) {
1182 int token; 1222 int token;
@@ -1193,10 +1233,12 @@ xfs_fs_remount(
1193 mp->m_flags &= ~XFS_MOUNT_BARRIER; 1233 mp->m_flags &= ~XFS_MOUNT_BARRIER;
1194 break; 1234 break;
1195 case Opt_inode64: 1235 case Opt_inode64:
1196 mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount); 1236 mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
1237 mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
1197 break; 1238 break;
1198 case Opt_inode32: 1239 case Opt_inode32:
1199 mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount); 1240 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
1241 mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
1200 break; 1242 break;
1201 default: 1243 default:
1202 /* 1244 /*
@@ -1344,9 +1386,8 @@ xfs_finish_flags(
1344 */ 1386 */
1345 if (xfs_sb_version_hascrc(&mp->m_sb) && 1387 if (xfs_sb_version_hascrc(&mp->m_sb) &&
1346 (mp->m_flags & XFS_MOUNT_NOATTR2)) { 1388 (mp->m_flags & XFS_MOUNT_NOATTR2)) {
1347 xfs_warn(mp, 1389 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.", 1390 "attr2 is always enabled for V5 filesystems.");
1349 MNTOPT_NOATTR2, MNTOPT_ATTR2);
1350 return -EINVAL; 1391 return -EINVAL;
1351 } 1392 }
1352 1393
diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h
index 499058fea303..2dfb1ce4585f 100644
--- a/fs/xfs/xfs_super.h
+++ b/fs/xfs/xfs_super.h
@@ -65,8 +65,8 @@ extern __uint64_t xfs_max_file_offset(unsigned int);
65 65
66extern void xfs_flush_inodes(struct xfs_mount *mp); 66extern void xfs_flush_inodes(struct xfs_mount *mp);
67extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); 67extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
68extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount); 68extern xfs_agnumber_t xfs_set_inode_alloc(struct xfs_mount *,
69extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount); 69 xfs_agnumber_t agcount);
70 70
71extern const struct export_operations xfs_export_operations; 71extern const struct export_operations xfs_export_operations;
72extern const struct xattr_handler *xfs_xattr_handlers[]; 72extern const struct xattr_handler *xfs_xattr_handlers[];
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 4643070d7cae..e7c49cf43fbc 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -133,7 +133,6 @@ typedef struct xfs_trans {
133 * XFS transaction mechanism exported interfaces that are 133 * XFS transaction mechanism exported interfaces that are
134 * actually macros. 134 * actually macros.
135 */ 135 */
136#define xfs_trans_get_block_res(tp) ((tp)->t_blk_res)
137#define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) 136#define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC)
138 137
139#if defined(DEBUG) || defined(XFS_WARN) 138#if defined(DEBUG) || defined(XFS_WARN)