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
commit 3c1a79f5ff
9 changed files with 306 additions and 284 deletions

View File

@ -5210,7 +5210,7 @@ xfs_bunmapi(
* This is better than zeroing it.
*/
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,
* chop it back to the start of the one we end at.
@ -5241,7 +5241,7 @@ xfs_bunmapi(
del.br_startblock += mod;
} else if ((del.br_startoff == start &&
(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)) {
/*
* Can't make it unwritten. There isn't
@ -5332,7 +5332,7 @@ xfs_bunmapi(
* conversion to btree format, since the transaction
* 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_NEXTENTS(ip, whichfork) >= /* Note the >= */
XFS_IFORK_MAXEXT(ip, whichfork) &&

View File

@ -461,7 +461,7 @@ xfs_bmbt_alloc_block(
* reservation amount is insufficient then we may fail a
* 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) {
args.type = XFS_ALLOCTYPE_START_BNO;
} else {
@ -470,7 +470,7 @@ xfs_bmbt_alloc_block(
args.minlen = args.maxlen = args.prod = 1;
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;
goto error0;
}

View File

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

View File

@ -227,7 +227,7 @@ xfs_discard_extents(
GFP_NOFS, 0);
if (error && error != -EOPNOTSUPP) {
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,
busyp->length,
error);

View File

@ -185,9 +185,6 @@ xfs_initialize_perag(
xfs_agnumber_t index;
xfs_agnumber_t first_initialised = 0;
xfs_perag_t *pag;
xfs_agino_t agino;
xfs_ino_t ino;
xfs_sb_t *sbp = &mp->m_sb;
int error = -ENOMEM;
/*
@ -230,22 +227,7 @@ xfs_initialize_perag(
radix_tree_preload_end();
}
/*
* 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);
index = xfs_set_inode_alloc(mp, agcount);
if (maxagi)
*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_NORECOVERY (1ULL << 10) /* no recovery - dirty fs */
#define XFS_MOUNT_DFLT_IOSIZE (1ULL << 12) /* set default i/o size */
#define XFS_MOUNT_32BITINODES (1ULL << 14) /* do not create inodes above
* 32 bits in size */
#define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */
#define XFS_MOUNT_SMALL_INUMS (1ULL << 14) /* user wants 32bit inodes */
#define XFS_MOUNT_32BITINODES (1ULL << 15) /* inode32 allocator active */
#define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */
#define XFS_MOUNT_BARRIER (1ULL << 17)
#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 */
#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.
*
* Currently only used for remount, but it will be used for mount
* in the future, too.
*/
enum {
Opt_barrier,
Opt_nobarrier,
Opt_inode64,
Opt_inode32,
Opt_err
Opt_logbufs, Opt_logbsize, Opt_logdev, Opt_rtdev, Opt_biosize,
Opt_wsync, Opt_noalign, Opt_swalloc, Opt_sunit, Opt_swidth, Opt_nouuid,
Opt_mtpt, Opt_grpid, Opt_nogrpid, Opt_bsdgroups, Opt_sysvgroups,
Opt_allocsize, Opt_norecovery, Opt_barrier, Opt_nobarrier,
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 = {
{Opt_barrier, "barrier"},
{Opt_nobarrier, "nobarrier"},
{Opt_inode64, "inode64"},
{Opt_inode32, "inode32"},
{Opt_err, NULL}
{Opt_logbufs, "logbufs=%u"}, /* number of XFS log buffers */
{Opt_logbsize, "logbsize=%s"}, /* size of XFS log buffers */
{Opt_logdev, "logdev=%s"}, /* log device */
{Opt_rtdev, "rtdev=%s"}, /* realtime I/O device */
{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
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;
char *value = s;
char *value;
int ret = 0;
value = match_strdup(s);
if (!value)
return -ENOMEM;
last = strlen(value) - 1;
if (value[last] == 'K' || value[last] == 'k') {
@ -157,10 +159,11 @@ suffix_kstrtoint(char *s, unsigned int base, int *res)
value[last] = '\0';
}
if (kstrtoint(s, base, &_res))
return -EINVAL;
if (kstrtoint(value, base, &_res))
ret = -EINVAL;
kfree(value);
*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
* 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
xfs_parseargs(
struct xfs_mount *mp,
char *options)
{
struct super_block *sb = mp->m_super;
char *this_char, *value;
const struct super_block *sb = mp->m_super;
char *p;
substring_t args[MAX_OPT_ARGS];
int dsunit = 0;
int dswidth = 0;
int iosize = 0;
@ -217,152 +225,152 @@ xfs_parseargs(
if (!options)
goto done;
while ((this_char = strsep(&options, ",")) != NULL) {
if (!*this_char)
continue;
if ((value = strchr(this_char, '=')) != NULL)
*value++ = 0;
while ((p = strsep(&options, ",")) != NULL) {
int token;
if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
if (!value || !*value) {
xfs_warn(mp, "%s option requires an argument",
this_char);
if (!*p)
continue;
token = match_token(p, tokens, args);
switch (token) {
case Opt_logbufs:
if (match_int(args, &mp->m_logbufs))
return -EINVAL;
}
if (kstrtoint(value, 10, &mp->m_logbufs))
break;
case Opt_logbsize:
if (suffix_kstrtoint(args, 10, &mp->m_logbsize))
return -EINVAL;
} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
if (!value || !*value) {
xfs_warn(mp, "%s option requires an argument",
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);
break;
case Opt_logdev:
mp->m_logname = match_strdup(args);
if (!mp->m_logname)
return -ENOMEM;
} else if (!strcmp(this_char, MNTOPT_MTPT)) {
xfs_warn(mp, "%s option not allowed on this system",
this_char);
break;
case Opt_mtpt:
xfs_warn(mp, "%s option not allowed on this system", p);
return -EINVAL;
} else if (!strcmp(this_char, MNTOPT_RTDEV)) {
if (!value || !*value) {
xfs_warn(mp, "%s option requires an argument",
this_char);
return -EINVAL;
}
mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
case Opt_rtdev:
mp->m_rtname = match_strdup(args);
if (!mp->m_rtname)
return -ENOMEM;
} else if (!strcmp(this_char, MNTOPT_ALLOCSIZE) ||
!strcmp(this_char, MNTOPT_BIOSIZE)) {
if (!value || !*value) {
xfs_warn(mp, "%s option requires an argument",
this_char);
return -EINVAL;
}
if (suffix_kstrtoint(value, 10, &iosize))
break;
case Opt_allocsize:
case Opt_biosize:
if (suffix_kstrtoint(args, 10, &iosize))
return -EINVAL;
iosizelog = ffs(iosize) - 1;
} else if (!strcmp(this_char, MNTOPT_GRPID) ||
!strcmp(this_char, MNTOPT_BSDGROUPS)) {
break;
case Opt_grpid:
case Opt_bsdgroups:
mp->m_flags |= XFS_MOUNT_GRPID;
} else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
!strcmp(this_char, MNTOPT_SYSVGROUPS)) {
break;
case Opt_nogrpid:
case Opt_sysvgroups:
mp->m_flags &= ~XFS_MOUNT_GRPID;
} else if (!strcmp(this_char, MNTOPT_WSYNC)) {
break;
case Opt_wsync:
mp->m_flags |= XFS_MOUNT_WSYNC;
} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
break;
case Opt_norecovery:
mp->m_flags |= XFS_MOUNT_NORECOVERY;
} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
break;
case Opt_noalign:
mp->m_flags |= XFS_MOUNT_NOALIGN;
} else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
break;
case Opt_swalloc:
mp->m_flags |= XFS_MOUNT_SWALLOC;
} else if (!strcmp(this_char, MNTOPT_SUNIT)) {
if (!value || !*value) {
xfs_warn(mp, "%s option requires an argument",
this_char);
break;
case Opt_sunit:
if (match_int(args, &dsunit))
return -EINVAL;
}
if (kstrtoint(value, 10, &dsunit))
break;
case Opt_swidth:
if (match_int(args, &dswidth))
return -EINVAL;
} else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
if (!value || !*value) {
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)) {
break;
case Opt_inode32:
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;
} else if (!strcmp(this_char, MNTOPT_NOUUID)) {
break;
case Opt_nouuid:
mp->m_flags |= XFS_MOUNT_NOUUID;
} else if (!strcmp(this_char, MNTOPT_BARRIER)) {
break;
case Opt_barrier:
mp->m_flags |= XFS_MOUNT_BARRIER;
} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
break;
case Opt_nobarrier:
mp->m_flags &= ~XFS_MOUNT_BARRIER;
} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
break;
case Opt_ikeep:
mp->m_flags |= XFS_MOUNT_IKEEP;
} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
break;
case Opt_noikeep:
mp->m_flags &= ~XFS_MOUNT_IKEEP;
} else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
break;
case Opt_largeio:
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;
} else if (!strcmp(this_char, MNTOPT_ATTR2)) {
break;
case Opt_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_NOATTR2;
} else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
break;
case Opt_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_ENFD;
mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
} else if (!strcmp(this_char, MNTOPT_QUOTA) ||
!strcmp(this_char, MNTOPT_UQUOTA) ||
!strcmp(this_char, MNTOPT_USRQUOTA)) {
break;
case Opt_quota:
case Opt_uquota:
case Opt_usrquota:
mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
XFS_UQUOTA_ENFD);
} else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
!strcmp(this_char, MNTOPT_UQUOTANOENF)) {
break;
case Opt_qnoenforce:
case Opt_uqnoenforce:
mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
mp->m_qflags &= ~XFS_UQUOTA_ENFD;
} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
!strcmp(this_char, MNTOPT_PRJQUOTA)) {
break;
case Opt_pquota:
case Opt_prjquota:
mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
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_ENFD;
} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
!strcmp(this_char, MNTOPT_GRPQUOTA)) {
case Opt_gquota:
case Opt_grpquota:
mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
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_ENFD;
} else if (!strcmp(this_char, MNTOPT_DISCARD)) {
break;
case Opt_discard:
mp->m_flags |= XFS_MOUNT_DISCARD;
} else if (!strcmp(this_char, MNTOPT_NODISCARD)) {
break;
case Opt_nodiscard:
mp->m_flags &= ~XFS_MOUNT_DISCARD;
break;
#ifdef CONFIG_FS_DAX
} else if (!strcmp(this_char, MNTOPT_DAX)) {
case Opt_dax:
mp->m_flags |= XFS_MOUNT_DAX;
break;
#endif
} else {
xfs_warn(mp, "unknown mount option [%s].", this_char);
default:
xfs_warn(mp, "unknown mount option [%s].", p);
return -EINVAL;
}
}
@ -461,25 +469,25 @@ xfs_showargs(
{
static struct proc_xfs_info xfs_info_set[] = {
/* the few simple ones we can get from the mount struct */
{ XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP },
{ XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC },
{ XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
{ XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC },
{ XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
{ XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
{ XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 },
{ XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM },
{ XFS_MOUNT_GRPID, "," MNTOPT_GRPID },
{ XFS_MOUNT_DISCARD, "," MNTOPT_DISCARD },
{ XFS_MOUNT_SMALL_INUMS, "," MNTOPT_32BITINODE },
{ XFS_MOUNT_DAX, "," MNTOPT_DAX },
{ XFS_MOUNT_IKEEP, ",ikeep" },
{ XFS_MOUNT_WSYNC, ",wsync" },
{ XFS_MOUNT_NOALIGN, ",noalign" },
{ XFS_MOUNT_SWALLOC, ",swalloc" },
{ XFS_MOUNT_NOUUID, ",nouuid" },
{ XFS_MOUNT_NORECOVERY, ",norecovery" },
{ XFS_MOUNT_ATTR2, ",attr2" },
{ XFS_MOUNT_FILESTREAMS, ",filestreams" },
{ XFS_MOUNT_GRPID, ",grpid" },
{ XFS_MOUNT_DISCARD, ",discard" },
{ XFS_MOUNT_SMALL_INUMS, ",inode32" },
{ XFS_MOUNT_DAX, ",dax" },
{ 0, NULL }
};
static struct proc_xfs_info xfs_info_unset[] = {
/* the few simple ones we can get from the mount struct */
{ XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO },
{ XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER },
{ XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE },
{ XFS_MOUNT_COMPAT_IOSIZE, ",largeio" },
{ XFS_MOUNT_BARRIER, ",nobarrier" },
{ XFS_MOUNT_SMALL_INUMS, ",inode64" },
{ 0, NULL }
};
struct proc_xfs_info *xfs_infop;
@ -494,46 +502,46 @@ xfs_showargs(
}
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);
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)
seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
seq_printf(m, ",logbsize=%dk", mp->m_logbsize >> 10);
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)
seq_show_option(m, MNTOPT_RTDEV, mp->m_rtname);
seq_show_option(m, "rtdev", mp->m_rtname);
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));
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));
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)
seq_puts(m, "," MNTOPT_UQUOTANOENF);
seq_puts(m, ",uqnoenforce");
if (mp->m_qflags & XFS_PQUOTA_ACCT) {
if (mp->m_qflags & XFS_PQUOTA_ENFD)
seq_puts(m, "," MNTOPT_PRJQUOTA);
seq_puts(m, ",prjquota");
else
seq_puts(m, "," MNTOPT_PQUOTANOENF);
seq_puts(m, ",pqnoenforce");
}
if (mp->m_qflags & XFS_GQUOTA_ACCT) {
if (mp->m_qflags & XFS_GQUOTA_ENFD)
seq_puts(m, "," MNTOPT_GRPQUOTA);
seq_puts(m, ",grpquota");
else
seq_puts(m, "," MNTOPT_GQUOTANOENF);
seq_puts(m, ",gqnoenforce");
}
if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
seq_puts(m, "," MNTOPT_NOQUOTA);
seq_puts(m, ",noquota");
return 0;
}
@ -572,23 +580,35 @@ xfs_max_file_offset(
}
/*
* xfs_set_inode32() and xfs_set_inode64() are passed an agcount
* because in the growfs case, mp->m_sb.sb_agcount is not updated
* yet to the potentially higher ag count.
* Set parameters for inode allocation heuristics, taking into account
* filesystem size and inode32/inode64 mount options; i.e. specifically
* 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_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_sb_t *sbp = &mp->m_sb;
xfs_agnumber_t max_metadata;
xfs_agino_t agino;
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) {
__uint64_t icount;
@ -602,54 +622,48 @@ xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
max_metadata = agcount;
}
/* Get the last possible inode in the filesystem */
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 (ino > XFS_MAXINUMBER_32) {
pag = xfs_perag_get(mp, index);
pag->pagi_inodeok = 0;
pag->pagf_metadata = 0;
xfs_perag_put(pag);
continue;
}
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;
/*
* If user asked for no more than 32-bit inodes, and the fs is
* sufficiently large, set XFS_MOUNT_32BITINODES if we must alter
* the allocator to accommodate the request.
*/
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;
for (index = 0; index < agcount; index++) {
struct xfs_perag *pag;
ino = XFS_AGINO_TO_INO(mp, index, agino);
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);
}
/* There is no need for lock protection on m_flags,
* 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;
return (mp->m_flags & XFS_MOUNT_32BITINODES) ? maxagi : agcount;
}
STATIC int
@ -1165,6 +1179,27 @@ xfs_quiesce_attr(
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
xfs_fs_remount(
struct super_block *sb,
@ -1177,6 +1212,11 @@ xfs_fs_remount(
char *p;
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);
while ((p = strsep(&options, ",")) != NULL) {
int token;
@ -1193,10 +1233,12 @@ xfs_fs_remount(
mp->m_flags &= ~XFS_MOUNT_BARRIER;
break;
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;
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;
default:
/*
@ -1344,9 +1386,8 @@ xfs_finish_flags(
*/
if (xfs_sb_version_hascrc(&mp->m_sb) &&
(mp->m_flags & XFS_MOUNT_NOATTR2)) {
xfs_warn(mp,
"Cannot mount a V5 filesystem as %s. %s is always enabled for V5 filesystems.",
MNTOPT_NOATTR2, MNTOPT_ATTR2);
xfs_warn(mp, "Cannot mount a V5 filesystem as noattr2. "
"attr2 is always enabled for V5 filesystems.");
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_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_inode64(struct xfs_mount *, xfs_agnumber_t agcount);
extern xfs_agnumber_t xfs_set_inode_alloc(struct xfs_mount *,
xfs_agnumber_t agcount);
extern const struct export_operations xfs_export_operations;
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
* 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)
#if defined(DEBUG) || defined(XFS_WARN)