|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|