diff options
author | Dave Chinner <david@fromorbit.com> | 2016-03-06 17:34:54 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-03-06 17:34:54 -0500 |
commit | 3c1a79f5fff9b5ef653dc8b900ce818860c1f710 (patch) | |
tree | 9d955a4a921a3c08082f15da740fe369647c32dd | |
parent | 85a9f38d382bf06e995f2b1bf114596bac08d14d (diff) | |
parent | a7e5d03ba8882aa772c691f16690fe7e73cee257 (diff) |
Merge branch 'xfs-misc-fixes-4.6-2' into for-next
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 6 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap_btree.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_attr_list.c | 19 | ||||
-rw-r--r-- | fs/xfs/xfs_discard.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 20 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 525 | ||||
-rw-r--r-- | fs/xfs/xfs_super.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.h | 1 |
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 */ | |||
65 | static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ | 65 | static 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 | */ |
123 | enum { | 71 | enum { |
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 | ||
131 | static const match_table_t tokens = { | 84 | static 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 | ||
140 | STATIC int | 137 | STATIC int |
141 | suffix_kstrtoint(char *s, unsigned int base, int *res) | 138 | suffix_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 | */ |
173 | STATIC int | 180 | STATIC int |
174 | xfs_parseargs( | 181 | xfs_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 | */ |
579 | xfs_agnumber_t | 597 | xfs_agnumber_t |
580 | xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount) | 598 | xfs_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 | ||
631 | xfs_agnumber_t | 646 | if (mp->m_flags & XFS_MOUNT_32BITINODES) { |
632 | xfs_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 | ||
655 | STATIC int | 669 | STATIC int |
@@ -1166,6 +1180,27 @@ xfs_quiesce_attr( | |||
1166 | } | 1180 | } |
1167 | 1181 | ||
1168 | STATIC int | 1182 | STATIC int |
1183 | xfs_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 | |||
1203 | STATIC int | ||
1169 | xfs_fs_remount( | 1204 | xfs_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 | ||
66 | extern void xfs_flush_inodes(struct xfs_mount *mp); | 66 | extern void xfs_flush_inodes(struct xfs_mount *mp); |
67 | extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); | 67 | extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); |
68 | extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount); | 68 | extern xfs_agnumber_t xfs_set_inode_alloc(struct xfs_mount *, |
69 | extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount); | 69 | xfs_agnumber_t agcount); |
70 | 70 | ||
71 | extern const struct export_operations xfs_export_operations; | 71 | extern const struct export_operations xfs_export_operations; |
72 | extern const struct xattr_handler *xfs_xattr_handlers[]; | 72 | extern 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) |