#ifdef HAVE_LIBATTR
# include <attr/attributes.h>
#endif
+#include <linux/fs.h>
#include "handle.h"
#include "list.h"
#include "path.h"
return *pmoveon ? 0 : XFS_ITERATE_INODES_ABORT;
}
+#ifndef FS_IOC_GETFSLABEL
+# define FSLABEL_MAX 256
+# define FS_IOC_GETFSLABEL _IOR(0x94, 49, char[FSLABEL_MAX])
+#endif /* FS_IOC_GETFSLABEL */
+
+/*
+ * Check the filesystem label for Unicode normalization problems or misleading
+ * sequences.
+ */
+static bool
+xfs_scrub_fs_label(
+ struct scrub_ctx *ctx)
+{
+ char label[FSLABEL_MAX];
+ struct unicrash *uc = NULL;
+ bool moveon = true;
+ int error;
+
+ moveon = unicrash_fs_label_init(&uc, ctx);
+ if (!moveon)
+ return false;
+
+ /* Retrieve label; quietly bail if we don't support that. */
+ error = ioctl(ctx->mnt_fd, FS_IOC_GETFSLABEL, &label);
+ if (error) {
+ if (errno != EOPNOTSUPP && errno != ENOTTY) {
+ moveon = false;
+ perror(ctx->mntpoint);
+ }
+ goto out;
+ }
+
+ /* Ignore empty labels. */
+ if (label[0] == 0)
+ goto out;
+
+ /* Otherwise check for weirdness. */
+ if (uc)
+ moveon = unicrash_check_fs_label(uc, ctx->mntpoint, label);
+ else
+ moveon = xfs_scrub_check_name(ctx, ctx->mntpoint,
+ _("filesystem label"), label);
+ if (!moveon)
+ goto out;
+out:
+ unicrash_free(uc);
+ return moveon;
+}
+
/* Check directory connectivity. */
bool
xfs_scan_connections(
return true;
}
+ moveon = xfs_scrub_fs_label(ctx);
+ if (!moveon)
+ return false;
+
ret = xfs_scan_all_inodes(ctx, xfs_scrub_connections, &moveon);
if (!ret)
moveon = false;
is_only_root_writable(bstat));
}
+/* Initialize the collision detector for a filesystem label. */
+bool
+unicrash_fs_label_init(
+ struct unicrash **ucp,
+ struct scrub_ctx *ctx)
+{
+ return unicrash_init(ucp, ctx, false, 16, true);
+}
+
/* Free the crash detector. */
void
unicrash_free(
return __unicrash_check_name(uc, descr, _("extended attribute"),
attrname, 0);
}
+
+/*
+ * Check the fs label for unicode normalization problems or misleading bits.
+ */
+bool
+unicrash_check_fs_label(
+ struct unicrash *uc,
+ const char *descr,
+ const char *label)
+{
+ if (!uc)
+ return true;
+ return __unicrash_check_name(uc, descr, _("filesystem label"),
+ label, 0);
+}
struct xfs_bstat *bstat);
bool unicrash_xattr_init(struct unicrash **ucp, struct scrub_ctx *ctx,
struct xfs_bstat *bstat);
+bool unicrash_fs_label_init(struct unicrash **ucp, struct scrub_ctx *ctx);
void unicrash_free(struct unicrash *uc);
bool unicrash_check_dir_name(struct unicrash *uc, const char *descr,
struct dirent *dirent);
bool unicrash_check_xattr_name(struct unicrash *uc, const char *descr,
const char *attrname);
+bool unicrash_check_fs_label(struct unicrash *uc, const char *descr,
+ const char *label);
#else
# define unicrash_dir_init(u, c, b) (true)
# define unicrash_xattr_init(u, c, b) (true)
+# define unicrash_label_init(u, c) (true)
# define unicrash_free(u) do {(u) = (u);} while (0)
# define unicrash_check_dir_name(u, d, n) (true)
# define unicrash_check_xattr_name(u, d, n) (true)
+# define unicrash_check_fs_label(u, d, n) (true)
#endif /* HAVE_LIBICU */
#endif /* XFS_SCRUB_UNICRASH_H_ */