Merge branch 'xfs-misc-fixes-4.6-2' into for-next

This commit is contained in:
Dave Chinner
2016-03-07 09:34:54 +11:00
9 changed files with 306 additions and 284 deletions

View File

@@ -5210,7 +5210,7 @@ xfs_bunmapi(
* This is better than zeroing it. * This is better than zeroing it.
*/ */
ASSERT(del.br_state == XFS_EXT_NORM); ASSERT(del.br_state == XFS_EXT_NORM);
ASSERT(xfs_trans_get_block_res(tp) > 0); ASSERT(tp->t_blk_res > 0);
/* /*
* If this spans a realtime extent boundary, * If this spans a realtime extent boundary,
* chop it back to the start of the one we end at. * chop it back to the start of the one we end at.
@@ -5241,7 +5241,7 @@ xfs_bunmapi(
del.br_startblock += mod; del.br_startblock += mod;
} else if ((del.br_startoff == start && } else if ((del.br_startoff == start &&
(del.br_state == XFS_EXT_UNWRITTEN || (del.br_state == XFS_EXT_UNWRITTEN ||
xfs_trans_get_block_res(tp) == 0)) || tp->t_blk_res == 0)) ||
!xfs_sb_version_hasextflgbit(&mp->m_sb)) { !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
/* /*
* Can't make it unwritten. There isn't * Can't make it unwritten. There isn't
@@ -5332,7 +5332,7 @@ xfs_bunmapi(
* conversion to btree format, since the transaction * conversion to btree format, since the transaction
* will be dirty. * will be dirty.
*/ */
if (!wasdel && xfs_trans_get_block_res(tp) == 0 && if (!wasdel && tp->t_blk_res == 0 &&
XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */
XFS_IFORK_MAXEXT(ip, whichfork) && XFS_IFORK_MAXEXT(ip, whichfork) &&

View File

@@ -461,7 +461,7 @@ xfs_bmbt_alloc_block(
* reservation amount is insufficient then we may fail a * reservation amount is insufficient then we may fail a
* block allocation here and corrupt the filesystem. * block allocation here and corrupt the filesystem.
*/ */
args.minleft = xfs_trans_get_block_res(args.tp); args.minleft = args.tp->t_blk_res;
} else if (cur->bc_private.b.flist->xbf_low) { } else if (cur->bc_private.b.flist->xbf_low) {
args.type = XFS_ALLOCTYPE_START_BNO; args.type = XFS_ALLOCTYPE_START_BNO;
} else { } else {
@@ -470,7 +470,7 @@ xfs_bmbt_alloc_block(
args.minlen = args.maxlen = args.prod = 1; args.minlen = args.maxlen = args.prod = 1;
args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
if (!args.wasdel && xfs_trans_get_block_res(args.tp) == 0) { if (!args.wasdel && args.tp->t_blk_res == 0) {
error = -ENOSPC; error = -ENOSPC;
goto error0; goto error0;
} }

View File

@@ -202,8 +202,10 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
sbp->namelen, sbp->namelen,
sbp->valuelen, sbp->valuelen,
&sbp->name[sbp->namelen]); &sbp->name[sbp->namelen]);
if (error) if (error) {
kmem_free(sbuf);
return error; return error;
}
if (context->seen_enough) if (context->seen_enough)
break; break;
cursor->offset++; cursor->offset++;
@@ -454,14 +456,13 @@ xfs_attr3_leaf_list_int(
args.rmtblkcnt = xfs_attr3_rmt_blocks( args.rmtblkcnt = xfs_attr3_rmt_blocks(
args.dp->i_mount, valuelen); args.dp->i_mount, valuelen);
retval = xfs_attr_rmtval_get(&args); retval = xfs_attr_rmtval_get(&args);
if (retval) if (!retval)
return retval; retval = context->put_listent(context,
retval = context->put_listent(context, entry->flags,
entry->flags, name_rmt->name,
name_rmt->name, (int)name_rmt->namelen,
(int)name_rmt->namelen, valuelen,
valuelen, args.value);
args.value);
kmem_free(args.value); kmem_free(args.value);
} else { } else {
retval = context->put_listent(context, retval = context->put_listent(context,

View File

@@ -227,7 +227,7 @@ xfs_discard_extents(
GFP_NOFS, 0); GFP_NOFS, 0);
if (error && error != -EOPNOTSUPP) { if (error && error != -EOPNOTSUPP) {
xfs_info(mp, xfs_info(mp,
"discard failed for extent [0x%llu,%u], error %d", "discard failed for extent [0x%llx,%u], error %d",
(unsigned long long)busyp->bno, (unsigned long long)busyp->bno,
busyp->length, busyp->length,
error); error);

View File

@@ -185,9 +185,6 @@ xfs_initialize_perag(
xfs_agnumber_t index; xfs_agnumber_t index;
xfs_agnumber_t first_initialised = 0; xfs_agnumber_t first_initialised = 0;
xfs_perag_t *pag; xfs_perag_t *pag;
xfs_agino_t agino;
xfs_ino_t ino;
xfs_sb_t *sbp = &mp->m_sb;
int error = -ENOMEM; int error = -ENOMEM;
/* /*
@@ -230,22 +227,7 @@ xfs_initialize_perag(
radix_tree_preload_end(); radix_tree_preload_end();
} }
/* index = xfs_set_inode_alloc(mp, agcount);
* If we mount with the inode64 option, or no inode overflows
* the legacy 32-bit address space clear the inode32 option.
*/
agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
mp->m_flags |= XFS_MOUNT_32BITINODES;
else
mp->m_flags &= ~XFS_MOUNT_32BITINODES;
if (mp->m_flags & XFS_MOUNT_32BITINODES)
index = xfs_set_inode32(mp, agcount);
else
index = xfs_set_inode64(mp, agcount);
if (maxagi) if (maxagi)
*maxagi = index; *maxagi = index;

View File

@@ -166,9 +166,8 @@ typedef struct xfs_mount {
#define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */ #define XFS_MOUNT_GRPID (1ULL << 9) /* group-ID assigned from directory */
#define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */ #define XFS_MOUNT_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */
#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */ #define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */
#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above #define XFS_MOUNT_SMALL_INUMS (1ULL << 14) /* user wants 32bit inodes */
* 32 bits in size */ #define XFS_MOUNT_32BITINODES (1ULL << 15) /* inode32 allocator active */
#define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */
#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */
#define XFS_MOUNT_BARRIER (1ULL << 17) #define XFS_MOUNT_BARRIER (1ULL << 17)
#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ #define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/

View File

@@ -65,83 +65,85 @@ static struct kset *xfs_kset; /* top-level xfs sysfs dir */
static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */
#endif #endif
#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */
#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
#define MNTOPT_LOGDEV "logdev" /* log device */
#define MNTOPT_RTDEV "rtdev" /* realtime I/O device */
#define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */
#define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */
#define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */
#define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */
#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
#define MNTOPT_GRPID "grpid" /* group-ID from parent directory */
#define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */
#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */
#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */
#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
* unwritten extent conversion */
#define MNTOPT_NOBARRIER "nobarrier" /* .. disable */
#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
#define MNTOPT_32BITINODE "inode32" /* inode allocation limited to
* XFS_MAXINUMBER_32 */
#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */
#define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes
* in stat(). */
#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */
#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
#define MNTOPT_NOQUOTA "noquota" /* no quotas */
#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
#define MNTOPT_DISCARD "discard" /* Discard unused blocks */
#define MNTOPT_NODISCARD "nodiscard" /* Do not discard unused blocks */
#define MNTOPT_DAX "dax" /* Enable direct access to bdev pages */
/* /*
* Table driven mount option parser. * Table driven mount option parser.
*
* Currently only used for remount, but it will be used for mount
* in the future, too.
*/ */
enum { enum {
Opt_barrier, Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
Opt_nobarrier, Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid,
Opt_inode64, Opt_mtpt, Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups,
Opt_inode32, Opt_allocsize, Opt_norecovery, Opt_barrier, Opt_nobarrier,
Opt_err Opt_inode64, Opt_inode32, Opt_ikeep, Opt_noikeep,
Opt_largeio, Opt_nolargeio, Opt_attr2, Opt_noattr2, Opt_filestreams,
Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota, Opt_prjquota,
Opt_uquota, Opt_gquota, Opt_pquota,
Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce,
Opt_discard, Opt_nodiscard, Opt_dax, Opt_err,
}; };
static const match_table_t tokens = { static const match_table_t tokens = {
{Opt_barrier, "barrier"}, {Opt_logbufs, "logbufs=%u"}, /* number of XFS log buffers */
{Opt_nobarrier, "nobarrier"}, {Opt_logbsize, "logbsize=%s"}, /* size of XFS log buffers */
{Opt_inode64, "inode64"}, {Opt_logdev, "logdev=%s"}, /* log device */
{Opt_inode32, "inode32"}, {Opt_rtdev, "rtdev=%s"}, /* realtime I/O device */
{Opt_err, NULL} {Opt_biosize, "biosize=%u"}, /* log2 of preferred buffered io size */
{Opt_wsync, "wsync"}, /* safe-mode nfs compatible mount */
{Opt_noalign, "noalign"}, /* turn off stripe alignment */
{Opt_swalloc, "swalloc"}, /* turn on stripe width allocation */
{Opt_sunit, "sunit=%u"}, /* data volume stripe unit */
{Opt_swidth, "swidth=%u"}, /* data volume stripe width */
{Opt_nouuid, "nouuid"}, /* ignore filesystem UUID */
{Opt_mtpt, "mtpt"}, /* filesystem mount point */
{Opt_grpid, "grpid"}, /* group-ID from parent directory */
{Opt_nogrpid, "nogrpid"}, /* group-ID from current process */
{Opt_bsdgroups, "bsdgroups"}, /* group-ID from parent directory */
{Opt_sysvgroups,"sysvgroups"}, /* group-ID from current process */
{Opt_allocsize, "allocsize=%s"},/* preferred allocation size */
{Opt_norecovery,"norecovery"}, /* don't run XFS recovery */
{Opt_barrier, "barrier"}, /* use writer barriers for log write and
* unwritten extent conversion */
{Opt_nobarrier, "nobarrier"}, /* .. disable */
{Opt_inode64, "inode64"}, /* inodes can be allocated anywhere */
{Opt_inode32, "inode32"}, /* inode allocation limited to
* XFS_MAXINUMBER_32 */
{Opt_ikeep, "ikeep"}, /* do not free empty inode clusters */
{Opt_noikeep, "noikeep"}, /* free empty inode clusters */
{Opt_largeio, "largeio"}, /* report large I/O sizes in stat() */
{Opt_nolargeio, "nolargeio"}, /* do not report large I/O sizes
* in stat(). */
{Opt_attr2, "attr2"}, /* do use attr2 attribute format */
{Opt_noattr2, "noattr2"}, /* do not use attr2 attribute format */
{Opt_filestreams,"filestreams"},/* use filestreams allocator */
{Opt_quota, "quota"}, /* disk quotas (user) */
{Opt_noquota, "noquota"}, /* no quotas */
{Opt_usrquota, "usrquota"}, /* user quota enabled */
{Opt_grpquota, "grpquota"}, /* group quota enabled */
{Opt_prjquota, "prjquota"}, /* project quota enabled */
{Opt_uquota, "uquota"}, /* user quota (IRIX variant) */
{Opt_gquota, "gquota"}, /* group quota (IRIX variant) */
{Opt_pquota, "pquota"}, /* project quota (IRIX variant) */
{Opt_uqnoenforce,"uqnoenforce"},/* user quota limit enforcement */
{Opt_gqnoenforce,"gqnoenforce"},/* group quota limit enforcement */
{Opt_pqnoenforce,"pqnoenforce"},/* project quota limit enforcement */
{Opt_qnoenforce, "qnoenforce"}, /* same as uqnoenforce */
{Opt_discard, "discard"}, /* Discard unused blocks */
{Opt_nodiscard, "nodiscard"}, /* Do not discard unused blocks */
{Opt_dax, "dax"}, /* Enable direct access to bdev pages */
{Opt_err, NULL},
}; };
STATIC int STATIC int
suffix_kstrtoint(char *s, unsigned int base, int *res) suffix_kstrtoint(const substring_t *s, unsigned int base, int *res)
{ {
int last, shift_left_factor = 0, _res; int last, shift_left_factor = 0, _res;
char *value = s; char *value;
int ret = 0;
value = match_strdup(s);
if (!value)
return -ENOMEM;
last = strlen(value) - 1; last = strlen(value) - 1;
if (value[last] == 'K' || value[last] == 'k') { if (value[last] == 'K' || value[last] == 'k') {
@@ -157,10 +159,11 @@ suffix_kstrtoint(char *s, unsigned int base, int *res)
value[last] = '\0'; value[last] = '\0';
} }
if (kstrtoint(s, base, &_res)) if (kstrtoint(value, base, &_res))
return -EINVAL; ret = -EINVAL;
kfree(value);
*res = _res << shift_left_factor; *res = _res << shift_left_factor;
return 0; return ret;
} }
/* /*
@@ -169,14 +172,19 @@ suffix_kstrtoint(char *s, unsigned int base, int *res)
* *
* Note that this function leaks the various device name allocations on * Note that this function leaks the various device name allocations on
* failure. The caller takes care of them. * failure. The caller takes care of them.
*
* *sb is const because this is also used to test options on the remount
* path, and we don't want this to have any side effects at remount time.
* Today this function does not change *sb, but just to future-proof...
*/ */
STATIC int STATIC int
xfs_parseargs( xfs_parseargs(
struct xfs_mount *mp, struct xfs_mount *mp,
char *options) char *options)
{ {
struct super_block *sb = mp->m_super; const struct super_block *sb = mp->m_super;
char *this_char, *value; char *p;
substring_t args[MAX_OPT_ARGS];
int dsunit = 0; int dsunit = 0;
int dswidth = 0; int dswidth = 0;
int iosize = 0; int iosize = 0;
@@ -217,152 +225,152 @@ xfs_parseargs(
if (!options) if (!options)
goto done; goto done;
while ((this_char = strsep(&options, ",")) != NULL) { while ((p = strsep(&options, ",")) != NULL) {
if (!*this_char) int token;
continue;
if ((value = strchr(this_char, '=')) != NULL)
*value++ = 0;
if (!strcmp(this_char, MNTOPT_LOGBUFS)) { if (!*p)
if (!value || !*value) { continue;
xfs_warn(mp, "%s option requires an argument",
this_char); token = match_token(p, tokens, args);
switch (token) {
case Opt_logbufs:
if (match_int(args, &mp->m_logbufs))
return -EINVAL; return -EINVAL;
} break;
if (kstrtoint(value, 10, &mp->m_logbufs)) case Opt_logbsize:
if (suffix_kstrtoint(args, 10, &mp->m_logbsize))
return -EINVAL; return -EINVAL;
} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { break;
if (!value || !*value) { case Opt_logdev:
xfs_warn(mp, "%s option requires an argument", mp->m_logname = match_strdup(args);
this_char);
return -EINVAL;
}
if (suffix_kstrtoint(value, 10, &mp->m_logbsize))
return -EINVAL;
} else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
if (!value || !*value) {
xfs_warn(mp, "%s option requires an argument",
this_char);
return -EINVAL;
}
mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
if (!mp->m_logname) if (!mp->m_logname)
return -ENOMEM; return -ENOMEM;
} else if (!strcmp(this_char, MNTOPT_MTPT)) { break;
xfs_warn(mp, "%s option not allowed on this system", case Opt_mtpt:
this_char); xfs_warn(mp, "%s option not allowed on this system", p);
return -EINVAL; return -EINVAL;
} else if (!strcmp(this_char, MNTOPT_RTDEV)) { case Opt_rtdev:
if (!value || !*value) { mp->m_rtname = match_strdup(args);
xfs_warn(mp, "%s option requires an argument",
this_char);
return -EINVAL;
}
mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
if (!mp->m_rtname) if (!mp->m_rtname)
return -ENOMEM; return -ENOMEM;
} else if (!strcmp(this_char, MNTOPT_ALLOCSIZE) || break;
!strcmp(this_char, MNTOPT_BIOSIZE)) { case Opt_allocsize:
if (!value || !*value) { case Opt_biosize:
xfs_warn(mp, "%s option requires an argument", if (suffix_kstrtoint(args, 10, &iosize))
this_char);
return -EINVAL;
}
if (suffix_kstrtoint(value, 10, &iosize))
return -EINVAL; return -EINVAL;
iosizelog = ffs(iosize) - 1; iosizelog = ffs(iosize) - 1;
} else if (!strcmp(this_char, MNTOPT_GRPID) || break;
!strcmp(this_char, MNTOPT_BSDGROUPS)) { case Opt_grpid:
case Opt_bsdgroups:
mp->m_flags |= XFS_MOUNT_GRPID; mp->m_flags |= XFS_MOUNT_GRPID;
} else if (!strcmp(this_char, MNTOPT_NOGRPID) || break;
!strcmp(this_char, MNTOPT_SYSVGROUPS)) { case Opt_nogrpid:
case Opt_sysvgroups:
mp->m_flags &= ~XFS_MOUNT_GRPID; mp->m_flags &= ~XFS_MOUNT_GRPID;
} else if (!strcmp(this_char, MNTOPT_WSYNC)) { break;
case Opt_wsync:
mp->m_flags |= XFS_MOUNT_WSYNC; mp->m_flags |= XFS_MOUNT_WSYNC;
} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) { break;
case Opt_norecovery:
mp->m_flags |= XFS_MOUNT_NORECOVERY; mp->m_flags |= XFS_MOUNT_NORECOVERY;
} else if (!strcmp(this_char, MNTOPT_NOALIGN)) { break;
case Opt_noalign:
mp->m_flags |= XFS_MOUNT_NOALIGN; mp->m_flags |= XFS_MOUNT_NOALIGN;
} else if (!strcmp(this_char, MNTOPT_SWALLOC)) { break;
case Opt_swalloc:
mp->m_flags |= XFS_MOUNT_SWALLOC; mp->m_flags |= XFS_MOUNT_SWALLOC;
} else if (!strcmp(this_char, MNTOPT_SUNIT)) { break;
if (!value || !*value) { case Opt_sunit:
xfs_warn(mp, "%s option requires an argument", if (match_int(args, &dsunit))
this_char);
return -EINVAL; return -EINVAL;
} break;
if (kstrtoint(value, 10, &dsunit)) case Opt_swidth:
if (match_int(args, &dswidth))
return -EINVAL; return -EINVAL;
} else if (!strcmp(this_char, MNTOPT_SWIDTH)) { break;
if (!value || !*value) { case Opt_inode32:
xfs_warn(mp, "%s option requires an argument",
this_char);
return -EINVAL;
}
if (kstrtoint(value, 10, &dswidth))
return -EINVAL;
} else if (!strcmp(this_char, MNTOPT_32BITINODE)) {
mp->m_flags |= XFS_MOUNT_SMALL_INUMS; mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
} else if (!strcmp(this_char, MNTOPT_64BITINODE)) { break;
case Opt_inode64:
mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS; mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
} else if (!strcmp(this_char, MNTOPT_NOUUID)) { break;
case Opt_nouuid:
mp->m_flags |= XFS_MOUNT_NOUUID; mp->m_flags |= XFS_MOUNT_NOUUID;
} else if (!strcmp(this_char, MNTOPT_BARRIER)) { break;
case Opt_barrier:
mp->m_flags |= XFS_MOUNT_BARRIER; mp->m_flags |= XFS_MOUNT_BARRIER;
} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { break;
case Opt_nobarrier:
mp->m_flags &= ~XFS_MOUNT_BARRIER; mp->m_flags &= ~XFS_MOUNT_BARRIER;
} else if (!strcmp(this_char, MNTOPT_IKEEP)) { break;
case Opt_ikeep:
mp->m_flags |= XFS_MOUNT_IKEEP; mp->m_flags |= XFS_MOUNT_IKEEP;
} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { break;
case Opt_noikeep:
mp->m_flags &= ~XFS_MOUNT_IKEEP; mp->m_flags &= ~XFS_MOUNT_IKEEP;
} else if (!strcmp(this_char, MNTOPT_LARGEIO)) { break;
case Opt_largeio:
mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE; mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
} else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { break;
case Opt_nolargeio:
mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
} else if (!strcmp(this_char, MNTOPT_ATTR2)) { break;
case Opt_attr2:
mp->m_flags |= XFS_MOUNT_ATTR2; mp->m_flags |= XFS_MOUNT_ATTR2;
} else if (!strcmp(this_char, MNTOPT_NOATTR2)) { break;
case Opt_noattr2:
mp->m_flags &= ~XFS_MOUNT_ATTR2; mp->m_flags &= ~XFS_MOUNT_ATTR2;
mp->m_flags |= XFS_MOUNT_NOATTR2; mp->m_flags |= XFS_MOUNT_NOATTR2;
} else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { break;
case Opt_filestreams:
mp->m_flags |= XFS_MOUNT_FILESTREAMS; mp->m_flags |= XFS_MOUNT_FILESTREAMS;
} else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { break;
case Opt_noquota:
mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
} else if (!strcmp(this_char, MNTOPT_QUOTA) || break;
!strcmp(this_char, MNTOPT_UQUOTA) || case Opt_quota:
!strcmp(this_char, MNTOPT_USRQUOTA)) { case Opt_uquota:
case Opt_usrquota:
mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
XFS_UQUOTA_ENFD); XFS_UQUOTA_ENFD);
} else if (!strcmp(this_char, MNTOPT_QUOTANOENF) || break;
!strcmp(this_char, MNTOPT_UQUOTANOENF)) { case Opt_qnoenforce:
case Opt_uqnoenforce:
mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
mp->m_qflags &= ~XFS_UQUOTA_ENFD; mp->m_qflags &= ~XFS_UQUOTA_ENFD;
} else if (!strcmp(this_char, MNTOPT_PQUOTA) || break;
!strcmp(this_char, MNTOPT_PRJQUOTA)) { case Opt_pquota:
case Opt_prjquota:
mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
XFS_PQUOTA_ENFD); XFS_PQUOTA_ENFD);
} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) { break;
case Opt_pqnoenforce:
mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
mp->m_qflags &= ~XFS_PQUOTA_ENFD; mp->m_qflags &= ~XFS_PQUOTA_ENFD;
} else if (!strcmp(this_char, MNTOPT_GQUOTA) || case Opt_gquota:
!strcmp(this_char, MNTOPT_GRPQUOTA)) { case Opt_grpquota:
mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
XFS_GQUOTA_ENFD); XFS_GQUOTA_ENFD);
} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) { break;
case Opt_gqnoenforce:
mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
mp->m_qflags &= ~XFS_GQUOTA_ENFD; mp->m_qflags &= ~XFS_GQUOTA_ENFD;
} else if (!strcmp(this_char, MNTOPT_DISCARD)) { break;
case Opt_discard:
mp->m_flags |= XFS_MOUNT_DISCARD; mp->m_flags |= XFS_MOUNT_DISCARD;
} else if (!strcmp(this_char, MNTOPT_NODISCARD)) { break;
case Opt_nodiscard:
mp->m_flags &= ~XFS_MOUNT_DISCARD; mp->m_flags &= ~XFS_MOUNT_DISCARD;
break;
#ifdef CONFIG_FS_DAX #ifdef CONFIG_FS_DAX
} else if (!strcmp(this_char, MNTOPT_DAX)) { case Opt_dax:
mp->m_flags |= XFS_MOUNT_DAX; mp->m_flags |= XFS_MOUNT_DAX;
break;
#endif #endif
} else { default:
xfs_warn(mp, "unknown mount option [%s].", this_char); xfs_warn(mp, "unknown mount option [%s].", p);
return -EINVAL; return -EINVAL;
} }
} }
@@ -461,25 +469,25 @@ xfs_showargs(
{ {
static struct proc_xfs_info xfs_info_set[] = { static struct proc_xfs_info xfs_info_set[] = {
/* the few simple ones we can get from the mount struct */ /* the few simple ones we can get from the mount struct */
{ XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, { XFS_MOUNT_IKEEP, ",ikeep" },
{ XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, { XFS_MOUNT_WSYNC, ",wsync" },
{ XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, { XFS_MOUNT_NOALIGN, ",noalign" },
{ XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC }, { XFS_MOUNT_SWALLOC, ",swalloc" },
{ XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, { XFS_MOUNT_NOUUID, ",nouuid" },
{ XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, { XFS_MOUNT_NORECOVERY, ",norecovery" },
{ XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 }, { XFS_MOUNT_ATTR2, ",attr2" },
{ XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM }, { XFS_MOUNT_FILESTREAMS, ",filestreams" },
{ XFS_MOUNT_GRPID, "," MNTOPT_GRPID }, { XFS_MOUNT_GRPID, ",grpid" },
{ XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD }, { XFS_MOUNT_DISCARD, ",discard" },
{ XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE }, { XFS_MOUNT_SMALL_INUMS, ",inode32" },
{ XFS_MOUNT_DAX, "," MNTOPT_DAX }, { XFS_MOUNT_DAX, ",dax" },
{ 0, NULL } { 0, NULL }
}; };
static struct proc_xfs_info xfs_info_unset[] = { static struct proc_xfs_info xfs_info_unset[] = {
/* the few simple ones we can get from the mount struct */ /* the few simple ones we can get from the mount struct */
{ XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, { XFS_MOUNT_COMPAT_IOSIZE, ",largeio" },
{ XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, { XFS_MOUNT_BARRIER, ",nobarrier" },
{ XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, { XFS_MOUNT_SMALL_INUMS, ",inode64" },
{ 0, NULL } { 0, NULL }
}; };
struct proc_xfs_info *xfs_infop; struct proc_xfs_info *xfs_infop;
@@ -494,46 +502,46 @@ xfs_showargs(
} }
if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", seq_printf(m, ",allocsize=%dk",
(int)(1 << mp->m_writeio_log) >> 10); (int)(1 << mp->m_writeio_log) >> 10);
if (mp->m_logbufs > 0) if (mp->m_logbufs > 0)
seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); seq_printf(m, ",logbufs=%d", mp->m_logbufs);
if (mp->m_logbsize > 0) if (mp->m_logbsize > 0)
seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); seq_printf(m, ",logbsize=%dk", mp->m_logbsize >> 10);
if (mp->m_logname) if (mp->m_logname)
seq_show_option(m, MNTOPT_LOGDEV, mp->m_logname); seq_show_option(m, "logdev", mp->m_logname);
if (mp->m_rtname) if (mp->m_rtname)
seq_show_option(m, MNTOPT_RTDEV, mp->m_rtname); seq_show_option(m, "rtdev", mp->m_rtname);
if (mp->m_dalign > 0) if (mp->m_dalign > 0)
seq_printf(m, "," MNTOPT_SUNIT "=%d", seq_printf(m, ",sunit=%d",
(int)XFS_FSB_TO_BB(mp, mp->m_dalign)); (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
if (mp->m_swidth > 0) if (mp->m_swidth > 0)
seq_printf(m, "," MNTOPT_SWIDTH "=%d", seq_printf(m, ",swidth=%d",
(int)XFS_FSB_TO_BB(mp, mp->m_swidth)); (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD)) if (mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD))
seq_puts(m, "," MNTOPT_USRQUOTA); seq_puts(m, ",usrquota");
else if (mp->m_qflags & XFS_UQUOTA_ACCT) else if (mp->m_qflags & XFS_UQUOTA_ACCT)
seq_puts(m, "," MNTOPT_UQUOTANOENF); seq_puts(m, ",uqnoenforce");
if (mp->m_qflags & XFS_PQUOTA_ACCT) { if (mp->m_qflags & XFS_PQUOTA_ACCT) {
if (mp->m_qflags & XFS_PQUOTA_ENFD) if (mp->m_qflags & XFS_PQUOTA_ENFD)
seq_puts(m, "," MNTOPT_PRJQUOTA); seq_puts(m, ",prjquota");
else else
seq_puts(m, "," MNTOPT_PQUOTANOENF); seq_puts(m, ",pqnoenforce");
} }
if (mp->m_qflags & XFS_GQUOTA_ACCT) { if (mp->m_qflags & XFS_GQUOTA_ACCT) {
if (mp->m_qflags & XFS_GQUOTA_ENFD) if (mp->m_qflags & XFS_GQUOTA_ENFD)
seq_puts(m, "," MNTOPT_GRPQUOTA); seq_puts(m, ",grpquota");
else else
seq_puts(m, "," MNTOPT_GQUOTANOENF); seq_puts(m, ",gqnoenforce");
} }
if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
seq_puts(m, "," MNTOPT_NOQUOTA); seq_puts(m, ",noquota");
return 0; return 0;
} }
@@ -572,23 +580,35 @@ xfs_max_file_offset(
} }
/* /*
* xfs_set_inode32() and xfs_set_inode64() are passed an agcount * Set parameters for inode allocation heuristics, taking into account
* because in the growfs case, mp->m_sb.sb_agcount is not updated * filesystem size and inode32/inode64 mount options; i.e. specifically
* yet to the potentially higher ag count. * whether or not XFS_MOUNT_SMALL_INUMS is set.
*
* Inode allocation patterns are altered only if inode32 is requested
* (XFS_MOUNT_SMALL_INUMS), and the filesystem is sufficiently large.
* If altered, XFS_MOUNT_32BITINODES is set as well.
*
* An agcount independent of that in the mount structure is provided
* because in the growfs case, mp->m_sb.sb_agcount is not yet updated
* to the potentially higher ag count.
*
* Returns the maximum AG index which may contain inodes.
*/ */
xfs_agnumber_t xfs_agnumber_t
xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount) xfs_set_inode_alloc(
struct xfs_mount *mp,
xfs_agnumber_t agcount)
{ {
xfs_agnumber_t index = 0; xfs_agnumber_t index;
xfs_agnumber_t maxagi = 0; xfs_agnumber_t maxagi = 0;
xfs_sb_t *sbp = &mp->m_sb; xfs_sb_t *sbp = &mp->m_sb;
xfs_agnumber_t max_metadata; xfs_agnumber_t max_metadata;
xfs_agino_t agino; xfs_agino_t agino;
xfs_ino_t ino; xfs_ino_t ino;
xfs_perag_t *pag;
/* Calculate how much should be reserved for inodes to meet /*
* the max inode percentage. * Calculate how much should be reserved for inodes to meet
* the max inode percentage. Used only for inode32.
*/ */
if (mp->m_maxicount) { if (mp->m_maxicount) {
__uint64_t icount; __uint64_t icount;
@@ -602,54 +622,48 @@ xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
max_metadata = agcount; max_metadata = agcount;
} }
/* Get the last possible inode in the filesystem */
agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0); agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);
for (index = 0; index < agcount; index++) { /*
ino = XFS_AGINO_TO_INO(mp, index, agino); * If user asked for no more than 32-bit inodes, and the fs is
* sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
if (ino > XFS_MAXINUMBER_32) { * the allocator to accommodate the request.
pag = xfs_perag_get(mp, index); */
pag->pagi_inodeok = 0; if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)
pag->pagf_metadata = 0; mp->m_flags |= XFS_MOUNT_32BITINODES;
xfs_perag_put(pag); else
continue; mp->m_flags &= ~XFS_MOUNT_32BITINODES;
}
pag = xfs_perag_get(mp, index);
pag->pagi_inodeok = 1;
maxagi++;
if (index < max_metadata)
pag->pagf_metadata = 1;
xfs_perag_put(pag);
}
mp->m_flags |= (XFS_MOUNT_32BITINODES |
XFS_MOUNT_SMALL_INUMS);
return maxagi;
}
xfs_agnumber_t
xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount)
{
xfs_agnumber_t index = 0;
for (index = 0; index < agcount; index++) { for (index = 0; index < agcount; index++) {
struct xfs_perag *pag; struct xfs_perag *pag;
ino = XFS_AGINO_TO_INO(mp, index, agino);
pag = xfs_perag_get(mp, index); pag = xfs_perag_get(mp, index);
pag->pagi_inodeok = 1;
pag->pagf_metadata = 0; if (mp->m_flags & XFS_MOUNT_32BITINODES) {
if (ino > XFS_MAXINUMBER_32) {
pag->pagi_inodeok = 0;
pag->pagf_metadata = 0;
} else {
pag->pagi_inodeok = 1;
maxagi++;
if (index < max_metadata)
pag->pagf_metadata = 1;
else
pag->pagf_metadata = 0;
}
} else {
pag->pagi_inodeok = 1;
pag->pagf_metadata = 0;
}
xfs_perag_put(pag); xfs_perag_put(pag);
} }
/* There is no need for lock protection on m_flags, return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
* the rw_semaphore of the VFS superblock is locked
* during mount/umount/remount operations, so this is
* enough to avoid concurency on the m_flags field
*/
mp->m_flags &= ~(XFS_MOUNT_32BITINODES |
XFS_MOUNT_SMALL_INUMS);
return index;
} }
STATIC int STATIC int
@@ -1165,6 +1179,27 @@ xfs_quiesce_attr(
xfs_log_quiesce(mp); xfs_log_quiesce(mp);
} }
STATIC int
xfs_test_remount_options(
struct super_block *sb,
struct xfs_mount *mp,
char *options)
{
int error = 0;
struct xfs_mount *tmp_mp;
tmp_mp = kmem_zalloc(sizeof(*tmp_mp), KM_MAYFAIL);
if (!tmp_mp)
return -ENOMEM;
tmp_mp->m_super = sb;
error = xfs_parseargs(tmp_mp, options);
xfs_free_fsname(tmp_mp);
kfree(tmp_mp);
return error;
}
STATIC int STATIC int
xfs_fs_remount( xfs_fs_remount(
struct super_block *sb, struct super_block *sb,
@@ -1177,6 +1212,11 @@ xfs_fs_remount(
char *p; char *p;
int error; int error;
/* First, check for complete junk; i.e. invalid options */
error = xfs_test_remount_options(sb, mp, options);
if (error)
return error;
sync_filesystem(sb); sync_filesystem(sb);
while ((p = strsep(&options, ",")) != NULL) { while ((p = strsep(&options, ",")) != NULL) {
int token; int token;
@@ -1193,10 +1233,12 @@ xfs_fs_remount(
mp->m_flags &= ~XFS_MOUNT_BARRIER; mp->m_flags &= ~XFS_MOUNT_BARRIER;
break; break;
case Opt_inode64: case Opt_inode64:
mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount); mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
break; break;
case Opt_inode32: case Opt_inode32:
mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount); mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
mp->m_maxagi = xfs_set_inode_alloc(mp, sbp->sb_agcount);
break; break;
default: default:
/* /*
@@ -1344,9 +1386,8 @@ xfs_finish_flags(
*/ */
if (xfs_sb_version_hascrc(&mp->m_sb) && if (xfs_sb_version_hascrc(&mp->m_sb) &&
(mp->m_flags & XFS_MOUNT_NOATTR2)) { (mp->m_flags & XFS_MOUNT_NOATTR2)) {
xfs_warn(mp, xfs_warn(mp, "Cannot mount a V5 filesystem as noattr2. "
"Cannot mount a V5 filesystem as %s. %s is always enabled for V5 filesystems.", "attr2 is always enabled for V5 filesystems.");
MNTOPT_NOATTR2, MNTOPT_ATTR2);
return -EINVAL; return -EINVAL;
} }

View File

@@ -65,8 +65,8 @@ extern __uint64_t xfs_max_file_offset(unsigned int);
extern void xfs_flush_inodes(struct xfs_mount *mp); extern void xfs_flush_inodes(struct xfs_mount *mp);
extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount); extern xfs_agnumber_t xfs_set_inode_alloc(struct xfs_mount *,
extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount); xfs_agnumber_t agcount);
extern const struct export_operations xfs_export_operations; extern const struct export_operations xfs_export_operations;
extern const struct xattr_handler *xfs_xattr_handlers[]; extern const struct xattr_handler *xfs_xattr_handlers[];

View File

@@ -133,7 +133,6 @@ typedef struct xfs_trans {
* XFS transaction mechanism exported interfaces that are * XFS transaction mechanism exported interfaces that are
* actually macros. * actually macros.
*/ */
#define xfs_trans_get_block_res(tp) ((tp)->t_blk_res)
#define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC)
#if defined(DEBUG) || defined(XFS_WARN) #if defined(DEBUG) || defined(XFS_WARN)