Hello community,

here is the log from the commit of package xfsprogs for openSUSE:Leap:15.2 
checked in at 2020-02-27 06:41:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/xfsprogs (Old)
 and      /work/SRC/openSUSE:Leap:15.2/.xfsprogs.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "xfsprogs"

Thu Feb 27 06:41:31 2020 rev:35 rq:779123 version:4.15.0

Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/xfsprogs/xfsprogs.changes      2020-01-15 
16:30:40.772829703 +0100
+++ /work/SRC/openSUSE:Leap:15.2/.xfsprogs.new.26092/xfsprogs.changes   
2020-02-27 06:41:32.565614533 +0100
@@ -1,0 +2,28 @@
+Tue Jan 28 14:22:35 UTC 2020 - Anthony Iliopoulos <ailiopou...@suse.com>
+
+- mkfs.xfs: validate extent size hint parameters (bsc#1158509)
+  * Add xfsprogs-mkfs-validate-extent-size-hint-parameters.patch
+  * Add xfsprogs-xfs-move-inode-extent-size-hint-validation-to-libxfs.patch
+  * Add xfsprogs-xfs_repair-use-libxfs-extsize-cowextsize-validation-.patch
+
+-------------------------------------------------------------------
+Sun Jan  5 16:24:49 UTC 2020 - Anthony Iliopoulos <ailiopou...@suse.com>
+
+- xfs_repair: don't fail recovery of orphaned shortform directories
+  (bsc#1158504)
+  * Add xfsprogs-xfs-create-structure-verifier-function-for-short-for.patch
+  * Add xfsprogs-xfs-create-structure-verifier-function-for-shortform.patch
+  * Add xfsprogs-xfs-provide-a-centralized-method-for-verifying-inlin.patch
+  * Add xfsprogs-xfs-refactor-short-form-directory-structure-verifier.patch
+  * Add xfsprogs-xfs_repair-don-t-fail-directory-repairs-when-grabbin.patch
+  * Add xfsprogs-xfs_repair-implement-custom-ifork-verifiers.patch
+  * Add xfsprogs-xfs_repair-use-custom-ifork-verifier-in-mv_orphanage.patch
+
+-------------------------------------------------------------------
+Sun Jan  5 12:38:16 UTC 2020 - Anthony Iliopoulos <ailiopou...@suse.com>
+
+- xfs_quota: fix false error reporting of project inheritance flag is
+  not set (bsc#1158758)
+  * Add xfsprogs-xfs_quota-fix-false-error-reporting-of-project-inher.patch
+
+-------------------------------------------------------------------

New:
----
  xfsprogs-mkfs-validate-extent-size-hint-parameters.patch
  xfsprogs-xfs-create-structure-verifier-function-for-short-for.patch
  xfsprogs-xfs-create-structure-verifier-function-for-shortform.patch
  xfsprogs-xfs-move-inode-extent-size-hint-validation-to-libxfs.patch
  xfsprogs-xfs-provide-a-centralized-method-for-verifying-inlin.patch
  xfsprogs-xfs-refactor-short-form-directory-structure-verifier.patch
  xfsprogs-xfs_quota-fix-false-error-reporting-of-project-inher.patch
  xfsprogs-xfs_repair-don-t-fail-directory-repairs-when-grabbin.patch
  xfsprogs-xfs_repair-implement-custom-ifork-verifiers.patch
  xfsprogs-xfs_repair-use-custom-ifork-verifier-in-mv_orphanage.patch
  xfsprogs-xfs_repair-use-libxfs-extsize-cowextsize-validation-.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ xfsprogs.spec ++++++
--- /var/tmp/diff_new_pack.yDFEc9/_old  2020-02-27 06:41:33.145615740 +0100
+++ /var/tmp/diff_new_pack.yDFEc9/_new  2020-02-27 06:41:33.149615749 +0100
@@ -46,6 +46,18 @@
 Patch13:       xfsprogs-mkfs-use-geometry-generation-helper-functions.patch
 Patch14:       xfsprogs-xfs_info-call-xfs_db-for-offline-filesystems.patch
 Patch15:       
xfsprogs-xfs_info-use-findmnt-to-handle-mounted-block-devices.patch
+Patch16:       
xfsprogs-xfs_quota-fix-false-error-reporting-of-project-inher.patch
+Patch17:       
xfsprogs-xfs-create-structure-verifier-function-for-shortform.patch
+Patch18:       
xfsprogs-xfs-create-structure-verifier-function-for-short-for.patch
+Patch19:       
xfsprogs-xfs-refactor-short-form-directory-structure-verifier.patch
+Patch20:       
xfsprogs-xfs-provide-a-centralized-method-for-verifying-inlin.patch
+Patch21:       
xfsprogs-xfs_repair-don-t-fail-directory-repairs-when-grabbin.patch
+Patch22:       xfsprogs-xfs_repair-implement-custom-ifork-verifiers.patch
+Patch23:       
xfsprogs-xfs_repair-use-custom-ifork-verifier-in-mv_orphanage.patch
+Patch24:       
xfsprogs-xfs-move-inode-extent-size-hint-validation-to-libxfs.patch
+Patch25:       
xfsprogs-xfs_repair-use-libxfs-extsize-cowextsize-validation-.patch
+Patch26:       xfsprogs-mkfs-validate-extent-size-hint-parameters.patch
+
 BuildRequires:  autoconf
 BuildRequires:  automake
 BuildRequires:  libblkid-devel
@@ -109,6 +121,17 @@
 %patch13 -p1
 %patch14 -p1
 %patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
 %endif
 
 %build


++++++ xfsprogs-mkfs-validate-extent-size-hint-parameters.patch ++++++
>From 5786ad73fc1640239c7f08c8f705be48ea3aa04b Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.w...@oracle.com>
Date: Thu, 18 Apr 2019 13:19:39 -0500
Subject: [PATCH] mkfs: validate extent size hint parameters
Git-commit: 9cfe71bae43451bf5cc6b6688b94c88336e1ea00
Patch-mainline: v5.0.0-rc1
References: bsc#1158509

Validate extent and cow extent size hints that are passed to mkfs so
that we avoid formatting a filesystem that will never mount.

Signed-off-by: Darrick J. Wong <darrick.w...@oracle.com>
Reviewed-by: Eric Sandeen <sand...@redhat.com>
[sandeen: use DIFLAG macros for now to be consistent, fixed later]
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 mkfs/xfs_mkfs.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 050381f4..b2bfec26 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2208,6 +2208,85 @@ validate_rtextsize(
        ASSERT(cfg->rtextblocks);
 }
 
+/* Validate the incoming extsize hint. */
+static void
+validate_extsize_hint(
+       struct xfs_mount        *mp,
+       struct cli_params       *cli)
+{
+       xfs_failaddr_t          fa;
+       uint16_t                flags = 0;
+
+       /*
+        * First we validate the extent size inherit hint on a directory so
+        * that we know that we'll be propagating a correct hint and flag to
+        * new files on the data device.
+        */
+       if (cli->fsx.fsx_xflags & XFS_DIFLAG_EXTSZINHERIT)
+               flags |= XFS_DIFLAG_EXTSZINHERIT;
+
+       fa = libxfs_inode_validate_extsize(mp, cli->fsx.fsx_extsize, S_IFDIR,
+                       flags);
+       if (fa) {
+               fprintf(stderr,
+_("illegal extent size hint %lld, must be less than %u.\n"),
+                               (long long)cli->fsx.fsx_extsize,
+                               min(MAXEXTLEN, mp->m_sb.sb_agblocks / 2));
+               usage();
+       }
+
+       /*
+        * Now we do it again with a realtime file so that we know the hint and
+        * flag that get passed on to realtime files will be correct.
+        */
+       if (mp->m_sb.sb_rextsize == 0)
+               return;
+
+       flags = XFS_DIFLAG_REALTIME;
+       if (cli->fsx.fsx_xflags & XFS_DIFLAG_EXTSIZE)
+               flags |= XFS_DIFLAG_EXTSIZE;
+
+       fa = libxfs_inode_validate_extsize(mp, cli->fsx.fsx_extsize, S_IFREG,
+                       flags);
+
+       if (fa) {
+               fprintf(stderr,
+_("illegal extent size hint %lld, must be less than %u and a multiple of 
%u.\n"),
+                               (long long)cli->fsx.fsx_extsize,
+                               min(MAXEXTLEN, mp->m_sb.sb_agblocks / 2),
+                               mp->m_sb.sb_rextsize);
+               usage();
+       }
+}
+
+/* Validate the incoming CoW extsize hint. */
+static void
+validate_cowextsize_hint(
+       struct xfs_mount        *mp,
+       struct cli_params       *cli)
+{
+       xfs_failaddr_t          fa;
+       uint64_t                flags2 = 0;
+
+       /*
+        * Validate the copy on write extent size inherit hint on a directory
+        * so that we know that we'll be propagating a correct hint and flag to
+        * new files on the data device.
+        */
+       if (cli->fsx.fsx_xflags & FS_XFLAG_COWEXTSIZE)
+               flags2 |= XFS_DIFLAG2_COWEXTSIZE;
+
+       fa = libxfs_inode_validate_cowextsize(mp, cli->fsx.fsx_cowextsize,
+                       S_IFDIR, 0, flags2);
+       if (fa) {
+               fprintf(stderr,
+_("illegal CoW extent size hint %lld, must be less than %u.\n"),
+                               (long long)cli->fsx.fsx_cowextsize,
+                               min(MAXEXTLEN, mp->m_sb.sb_agblocks / 2));
+               usage();
+       }
+}
+
 /*
  * Validate the configured stripe geometry, or is none is specified, pull
  * the configuration from the underlying device.
@@ -3944,6 +4023,10 @@ main(
 
        finish_superblock_setup(&cfg, mp, sbp);
 
+       /* Validate the extent size hints now that @mp is fully set up. */
+       validate_extsize_hint(mp, &cli);
+       validate_cowextsize_hint(mp, &cli);
+
        /* Print the intended geometry of the fs. */
        if (!quiet || dry_run) {
                struct xfs_fsop_geom    geo;
-- 
2.16.4

++++++ xfsprogs-xfs-create-structure-verifier-function-for-short-for.patch 
++++++
>From 31337a6ef7d39381f0407620cbcc0b82ea6ac6be Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.w...@oracle.com>
Date: Mon, 26 Feb 2018 22:43:17 -0600
Subject: [PATCH] xfs: create structure verifier function for short form
 symlinks
Git-commit: 6db3a8007a2493d6887cf45a5edfaa6a770b8492
Patch-mainline: v4.16.0-rc1
References: bsc#1158504

Source kernel commit: 0795e004fd4f2723f3dbf09a195cd7ccf3c74c58

Create a function to check the structure of short form symlink targets.

Signed-off-by: Darrick J. Wong <darrick.w...@oracle.com>
Reviewed-by: Dave Chinner <dchin...@redhat.com>
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 libxfs/xfs_shared.h         |  1 +
 libxfs/xfs_symlink_remote.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h
index c6f4eb4..67ccb1a 100644
--- a/libxfs/xfs_shared.h
+++ b/libxfs/xfs_shared.h
@@ -143,5 +143,6 @@ bool xfs_symlink_hdr_ok(xfs_ino_t ino, uint32_t offset,
                        uint32_t size, struct xfs_buf *bp);
 void xfs_symlink_local_to_remote(struct xfs_trans *tp, struct xfs_buf *bp,
                                 struct xfs_inode *ip, struct xfs_ifork *ifp);
+xfs_failaddr_t xfs_symlink_shortform_verify(struct xfs_inode *ip);
 
 #endif /* __XFS_SHARED_H__ */
diff --git a/libxfs/xfs_symlink_remote.c b/libxfs/xfs_symlink_remote.c
index d638530..5a7afd3 100644
--- a/libxfs/xfs_symlink_remote.c
+++ b/libxfs/xfs_symlink_remote.c
@@ -203,3 +203,37 @@ xfs_symlink_local_to_remote(
        xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsymlink_hdr) +
                                        ifp->if_bytes - 1);
 }
+
+/* Verify the consistency of an inline symlink. */
+xfs_failaddr_t
+xfs_symlink_shortform_verify(
+       struct xfs_inode        *ip)
+{
+       char                    *sfp;
+       char                    *endp;
+       struct xfs_ifork        *ifp;
+       int                     size;
+
+       ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL);
+       ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
+       sfp = (char *)ifp->if_u1.if_data;
+       size = ifp->if_bytes;
+       endp = sfp + size;
+
+       /* Zero length symlinks can exist while we're deleting a remote one. */
+       if (size == 0)
+               return NULL;
+
+       /* No negative sizes or overly long symlink targets. */
+       if (size < 0 || size > XFS_SYMLINK_MAXLEN)
+               return __this_address;
+
+       /* No NULLs in the target either. */
+       if (memchr(sfp, 0, size - 1))
+               return __this_address;
+
+       /* We /did/ null-terminate the buffer, right? */
+       if (*endp != 0)
+               return __this_address;
+       return NULL;
+}
-- 
2.16.4

++++++ xfsprogs-xfs-create-structure-verifier-function-for-shortform.patch 
++++++
>From 7b605756fd25385061e2e6c1d8f722e1d4f39aa8 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.w...@oracle.com>
Date: Mon, 26 Feb 2018 22:43:17 -0600
Subject: [PATCH] xfs: create structure verifier function for shortform xattrs
Git-commit: c7a710b7beeb21c5d84ab5e3c6a6aa9c96631fcc
Patch-mainline: v4.16.0-rc1
References: bsc#1158504

Source kernel commit: 1e1bbd8e7ee0624034e9bf1e91ac11a7aaa2f8a6

Create a function to perform structure verification for short form
extended attributes.

Signed-off-by: Darrick J. Wong <darrick.w...@oracle.com>
Reviewed-by: Dave Chinner <dchin...@redhat.com>
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 libxfs/libxfs_priv.h   |  1 +
 libxfs/util.c          |  7 +++++
 libxfs/xfs_attr_leaf.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
 libxfs/xfs_attr_leaf.h |  1 +
 4 files changed, 83 insertions(+)

diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h
index 82ae2e9..082963b 100644
--- a/libxfs/libxfs_priv.h
+++ b/libxfs/libxfs_priv.h
@@ -525,5 +525,6 @@ bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t);
 #define XFS_STATS_ADD_OFF(mp, off, val)
 
 typedef unsigned char u8;
+unsigned int hweight8(unsigned int w);
 
 #endif /* __LIBXFS_INTERNAL_XFS_H__ */
diff --git a/libxfs/util.c b/libxfs/util.c
index 5f49b82..7e42fb1 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -812,3 +812,10 @@ libxfs_zero_extent(
        return libxfs_device_zero(xfs_find_bdev_for_inode(ip), sector, size);
 }
 
+unsigned int
+hweight8(unsigned int w)
+{
+       unsigned int res = w - ((w >> 1) & 0x55);
+       res = (res & 0x33) + ((res >> 2) & 0x33);
+       return (res + (res >> 4)) & 0x0F;
+}
diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c
index 2f24567..62cb035 100644
--- a/libxfs/xfs_attr_leaf.c
+++ b/libxfs/xfs_attr_leaf.c
@@ -865,6 +865,80 @@ xfs_attr_shortform_allfit(
        return xfs_attr_shortform_bytesfit(dp, bytes);
 }
 
+/* Verify the consistency of an inline attribute fork. */
+xfs_failaddr_t
+xfs_attr_shortform_verify(
+       struct xfs_inode                *ip)
+{
+       struct xfs_attr_shortform       *sfp;
+       struct xfs_attr_sf_entry        *sfep;
+       struct xfs_attr_sf_entry        *next_sfep;
+       char                            *endp;
+       struct xfs_ifork                *ifp;
+       int                             i;
+       int                             size;
+
+       ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL);
+       ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK);
+       sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
+       size = ifp->if_bytes;
+
+       /*
+        * Give up if the attribute is way too short.
+        */
+       if (size < sizeof(struct xfs_attr_sf_hdr))
+               return __this_address;
+
+       endp = (char *)sfp + size;
+
+       /* Check all reported entries */
+       sfep = &sfp->list[0];
+       for (i = 0; i < sfp->hdr.count; i++) {
+               /*
+                * struct xfs_attr_sf_entry has a variable length.
+                * Check the fixed-offset parts of the structure are
+                * within the data buffer.
+                */
+               if (((char *)sfep + sizeof(*sfep)) >= endp)
+                       return __this_address;
+
+               /* Don't allow names with known bad length. */
+               if (sfep->namelen == 0)
+                       return __this_address;
+
+               /*
+                * Check that the variable-length part of the structure is
+                * within the data buffer.  The next entry starts after the
+                * name component, so nextentry is an acceptable test.
+                */
+               next_sfep = XFS_ATTR_SF_NEXTENTRY(sfep);
+               if ((char *)next_sfep > endp)
+                       return __this_address;
+
+               /*
+                * Check for unknown flags.  Short form doesn't support
+                * the incomplete or local bits, so we can use the namespace
+                * mask here.
+                */
+               if (sfep->flags & ~XFS_ATTR_NSP_ONDISK_MASK)
+                       return __this_address;
+
+               /*
+                * Check for invalid namespace combinations.  We only allow
+                * one namespace flag per xattr, so we can just count the
+                * bits (i.e. hweight) here.
+                */
+               if (hweight8(sfep->flags & XFS_ATTR_NSP_ONDISK_MASK) > 1)
+                       return __this_address;
+
+               sfep = next_sfep;
+       }
+       if ((void *)sfep != (void *)endp)
+               return __this_address;
+
+       return NULL;
+}
+
 /*
  * Convert a leaf attribute list to shortform attribute list
  */
diff --git a/libxfs/xfs_attr_leaf.h b/libxfs/xfs_attr_leaf.h
index 894124e..4da08af 100644
--- a/libxfs/xfs_attr_leaf.h
+++ b/libxfs/xfs_attr_leaf.h
@@ -53,6 +53,7 @@ int   xfs_attr_shortform_to_leaf(struct xfs_da_args *args,
 int    xfs_attr_shortform_remove(struct xfs_da_args *args);
 int    xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp);
 int    xfs_attr_shortform_bytesfit(struct xfs_inode *dp, int bytes);
+xfs_failaddr_t xfs_attr_shortform_verify(struct xfs_inode *ip);
 void   xfs_attr_fork_remove(struct xfs_inode *ip, struct xfs_trans *tp);
 
 /*
-- 
2.16.4

++++++ xfsprogs-xfs-move-inode-extent-size-hint-validation-to-libxfs.patch 
++++++
>From 5365dcd5e7aacda2dac9d28cb9e3762789f77e03 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.w...@oracle.com>
Date: Wed, 18 Apr 2018 14:46:07 -0500
Subject: [PATCH] xfs: move inode extent size hint validation to libxfs
Git-commit: fd0c360d19c8c1e7235e3d3aa09b600553ddf6a1
Patch-mainline: v4.17.0-rc1
References: bsc#1158509

Source kernel commit: 8bb82bc12a9e75dd47047d9a2e53135cc5e5787b

Extent size hint validation is used by scrub to decide if there's an
error, and it will be used by repair to decide to remove the hint.
Since these use the same validation functions, move them to libxfs.

Signed-off-by: Darrick J. Wong <darrick.w...@oracle.com>
Reviewed-by: Brian Foster <bfos...@redhat.com>
Signed-off-by: Eric Sandeen <sand...@redhat.com>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 libxfs/xfs_inode_buf.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
 libxfs/xfs_inode_buf.h |   5 +++
 2 files changed, 110 insertions(+)

diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index a3a5239b..8d3a818f 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -576,3 +576,108 @@ xfs_iread(
        xfs_trans_brelse(tp, bp);
        return error;
 }
+
+/*
+ * Validate di_extsize hint.
+ *
+ * The rules are documented at xfs_ioctl_setattr_check_extsize().
+ * These functions must be kept in sync with each other.
+ */
+xfs_failaddr_t
+xfs_inode_validate_extsize(
+       struct xfs_mount                *mp,
+       uint32_t                        extsize,
+       uint16_t                        mode,
+       uint16_t                        flags)
+{
+       bool                            rt_flag;
+       bool                            hint_flag;
+       bool                            inherit_flag;
+       uint32_t                        extsize_bytes;
+       uint32_t                        blocksize_bytes;
+
+       rt_flag = (flags & XFS_DIFLAG_REALTIME);
+       hint_flag = (flags & XFS_DIFLAG_EXTSIZE);
+       inherit_flag = (flags & XFS_DIFLAG_EXTSZINHERIT);
+       extsize_bytes = XFS_FSB_TO_B(mp, extsize);
+
+       if (rt_flag)
+               blocksize_bytes = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
+       else
+               blocksize_bytes = mp->m_sb.sb_blocksize;
+
+       if ((hint_flag || inherit_flag) && !(S_ISDIR(mode) || S_ISREG(mode)))
+               return __this_address;
+
+       if (hint_flag && !S_ISREG(mode))
+               return __this_address;
+
+       if (inherit_flag && !S_ISDIR(mode))
+               return __this_address;
+
+       if ((hint_flag || inherit_flag) && extsize == 0)
+               return __this_address;
+
+       if (!(hint_flag || inherit_flag) && extsize != 0)
+               return __this_address;
+
+       if (extsize_bytes % blocksize_bytes)
+               return __this_address;
+
+       if (extsize > MAXEXTLEN)
+               return __this_address;
+
+       if (!rt_flag && extsize > mp->m_sb.sb_agblocks / 2)
+               return __this_address;
+
+       return NULL;
+}
+
+/*
+ * Validate di_cowextsize hint.
+ *
+ * The rules are documented at xfs_ioctl_setattr_check_cowextsize().
+ * These functions must be kept in sync with each other.
+ */
+xfs_failaddr_t
+xfs_inode_validate_cowextsize(
+       struct xfs_mount                *mp,
+       uint32_t                        cowextsize,
+       uint16_t                        mode,
+       uint16_t                        flags,
+       uint64_t                        flags2)
+{
+       bool                            rt_flag;
+       bool                            hint_flag;
+       uint32_t                        cowextsize_bytes;
+
+       rt_flag = (flags & XFS_DIFLAG_REALTIME);
+       hint_flag = (flags2 & XFS_DIFLAG2_COWEXTSIZE);
+       cowextsize_bytes = XFS_FSB_TO_B(mp, cowextsize);
+
+       if (hint_flag && !xfs_sb_version_hasreflink(&mp->m_sb))
+               return __this_address;
+
+       if (hint_flag && !(S_ISDIR(mode) || S_ISREG(mode)))
+               return __this_address;
+
+       if (hint_flag && cowextsize == 0)
+               return __this_address;
+
+       if (!hint_flag && cowextsize != 0)
+               return __this_address;
+
+       if (hint_flag && rt_flag)
+               return __this_address;
+
+       if (cowextsize_bytes % mp->m_sb.sb_blocksize)
+               return __this_address;
+
+       if (cowextsize > MAXEXTLEN)
+               return __this_address;
+
+       if (cowextsize > mp->m_sb.sb_agblocks / 2)
+               return __this_address;
+
+       return NULL;
+}
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index a9c97a35..35161515 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -84,5 +84,10 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
 
 bool   xfs_dinode_verify(struct xfs_mount *mp, xfs_ino_t ino,
                          struct xfs_dinode *dip);
+xfs_failaddr_t xfs_inode_validate_extsize(struct xfs_mount *mp,
+               uint32_t extsize, uint16_t mode, uint16_t flags);
+xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp,
+               uint32_t cowextsize, uint16_t mode, uint16_t flags,
+               uint64_t flags2);
 
 #endif /* __XFS_INODE_BUF_H__ */
-- 
2.16.4

++++++ xfsprogs-xfs-provide-a-centralized-method-for-verifying-inlin.patch 
++++++
>From 08da938ab771dc644e48909dcba04b0223871546 Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.w...@oracle.com>
Date: Mon, 26 Feb 2018 22:43:17 -0600
Subject: [PATCH] xfs: provide a centralized method for verifying inline fork
 data
Git-commit: 20e882d4fe6a7fdd0efbb61b3f10fb5b8ee8316a
Patch-mainline: v4.16.0-rc1
References: bsc#1158504

Source kernel commit: 9cfb9b47479e237d217dbcfafe034cbf98f45909

Replace the current haphazard dir2 shortform verifier callsites with a
centralized verifier function that can be called either with the default
verifier functions or with a custom set.  This helps us strengthen
integrity checking while providing us with flexibility for repair tools.

xfs_repair wants this to be able to supply its own verifier functions
when trying to fix possibly corrupt metadata.

Signed-off-by: Darrick J. Wong <darrick.w...@oracle.com>
Reviewed-by: Dave Chinner <dchin...@redhat.com>
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 include/xfs_inode.h     |  1 +
 libxfs/rdwr.c           | 33 +++++++++++++++++++++++++
 libxfs/util.c           |  6 ++---
 libxfs/xfs_inode_fork.c | 64 +++++++++++++++++++++++++++++++++----------------
 libxfs/xfs_inode_fork.h | 14 +++++++++++
 5 files changed, 94 insertions(+), 24 deletions(-)

diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 11a549e..92829a2 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -162,6 +162,7 @@ extern void libxfs_trans_ichgtime(struct xfs_trans *,
 extern int     libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
 
 /* Inode Cache Interfaces */
+extern bool    libxfs_inode_verify_forks(struct xfs_inode *ip);
 extern int     libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
                                uint, struct xfs_inode **);
 extern void    libxfs_iput(struct xfs_inode *);
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 474e5eb..14afece 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -1336,6 +1336,34 @@ struct cache_operations libxfs_bcache_operations = {
 extern kmem_zone_t     *xfs_ili_zone;
 extern kmem_zone_t     *xfs_inode_zone;
 
+/*
+ * If there are inline format data / attr forks attached to this inode,
+ * make sure they're not corrupt.
+ */
+bool
+libxfs_inode_verify_forks(
+       struct xfs_inode        *ip)
+{
+       xfs_failaddr_t          fa;
+
+       fa = xfs_ifork_verify_data(ip, &xfs_default_ifork_ops);
+       if (fa) {
+               xfs_alert(ip->i_mount,
+                               "%s: bad inode %Lu inline data fork at %pF",
+                               __func__, ip->i_ino, fa);
+               return false;
+       }
+
+       fa = xfs_ifork_verify_attr(ip, &xfs_default_ifork_ops);
+       if (fa) {
+               xfs_alert(ip->i_mount,
+                               "%s: bad inode %Lu inline attr fork at %pF",
+                               __func__, ip->i_ino, fa);
+               return false;
+       }
+       return true;
+}
+
 int
 libxfs_iget(xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t ino, uint lock_flags,
                xfs_inode_t **ipp)
@@ -1356,6 +1384,11 @@ libxfs_iget(xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t 
ino, uint lock_flags,
                return error;
        }
 
+       if (!libxfs_inode_verify_forks(ip)) {
+               libxfs_iput(ip);
+               return -EFSCORRUPTED;
+       }
+
        /*
         * set up the inode ops structure that the libxfs code relies on
         */
diff --git a/libxfs/util.c b/libxfs/util.c
index 7e42fb1..2dcce57 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -493,10 +493,8 @@ libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp)
        if (ip->i_d.di_version == 3)
                VFS_I(ip)->i_version++;
 
-       /* Check the inline directory data. */
-       if (S_ISDIR(VFS_I(ip)->i_mode) &&
-           ip->i_d.di_format == XFS_DINODE_FMT_LOCAL &&
-           xfs_dir2_sf_verify(ip))
+       /* Check the inline fork data before we write out. */
+       if (!libxfs_inode_verify_forks(ip))
                return -EFSCORRUPTED;
 
        /*
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index b2bd8c7..063dab6 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -31,6 +31,8 @@
 #include "xfs_da_format.h"
 #include "xfs_da_btree.h"
 #include "xfs_dir2_priv.h"
+#include "xfs_attr_leaf.h"
+#include "xfs_shared.h"
 
 
 kmem_zone_t *xfs_ifork_zone;
@@ -180,14 +182,6 @@ xfs_iformat_fork(
        if (error)
                return error;
 
-       /* Check inline dir contents. */
-       if (S_ISDIR(inode->i_mode) && dip->di_format == XFS_DINODE_FMT_LOCAL) {
-               if (xfs_dir2_sf_verify(ip)) {
-                       xfs_idestroy_fork(ip, XFS_DATA_FORK);
-                       return -EFSCORRUPTED;
-               }
-       }
-
        if (xfs_is_reflink_inode(ip)) {
                ASSERT(ip->i_cowfp == NULL);
                xfs_ifork_init_cow(ip);
@@ -204,18 +198,6 @@ xfs_iformat_fork(
                atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
                size = be16_to_cpu(atp->hdr.totsize);
 
-               if (unlikely(size < sizeof(struct xfs_attr_sf_hdr))) {
-                       xfs_warn(ip->i_mount,
-                               "corrupt inode %Lu (bad attr fork size %Ld).",
-                               (unsigned long long) ip->i_ino,
-                               (long long) size);
-                       XFS_CORRUPTION_ERROR("xfs_iformat(8)",
-                                            XFS_ERRLEVEL_LOW,
-                                            ip->i_mount, dip);
-                       error = -EFSCORRUPTED;
-                       break;
-               }
-
                error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK, size);
                break;
        case XFS_DINODE_FMT_EXTENTS:
@@ -823,3 +805,45 @@ xfs_ifork_init_cow(
        ip->i_cformat = XFS_DINODE_FMT_EXTENTS;
        ip->i_cnextents = 0;
 }
+
+/* Default fork content verifiers. */
+struct xfs_ifork_ops xfs_default_ifork_ops = {
+       .verify_attr    = xfs_attr_shortform_verify,
+       .verify_dir     = xfs_dir2_sf_verify,
+       .verify_symlink = xfs_symlink_shortform_verify,
+};
+
+/* Verify the inline contents of the data fork of an inode. */
+xfs_failaddr_t
+xfs_ifork_verify_data(
+       struct xfs_inode        *ip,
+       struct xfs_ifork_ops    *ops)
+{
+       /* Non-local data fork, we're done. */
+       if (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
+               return NULL;
+
+       /* Check the inline data fork if there is one. */
+       switch (VFS_I(ip)->i_mode & S_IFMT) {
+       case S_IFDIR:
+               return ops->verify_dir(ip);
+       case S_IFLNK:
+               return ops->verify_symlink(ip);
+       default:
+               return NULL;
+       }
+}
+
+/* Verify the inline contents of the attr fork of an inode. */
+xfs_failaddr_t
+xfs_ifork_verify_attr(
+       struct xfs_inode        *ip,
+       struct xfs_ifork_ops    *ops)
+{
+       /* There has to be an attr fork allocated if aformat is local. */
+       if (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)
+               return NULL;
+       if (!XFS_IFORK_PTR(ip, XFS_ATTR_FORK))
+               return __this_address;
+       return ops->verify_attr(ip);
+}
diff --git a/libxfs/xfs_inode_fork.h b/libxfs/xfs_inode_fork.h
index b9f0098..dd8aba0 100644
--- a/libxfs/xfs_inode_fork.h
+++ b/libxfs/xfs_inode_fork.h
@@ -186,4 +186,18 @@ extern struct kmem_zone    *xfs_ifork_zone;
 
 extern void xfs_ifork_init_cow(struct xfs_inode *ip);
 
+typedef xfs_failaddr_t (*xfs_ifork_verifier_t)(struct xfs_inode *);
+
+struct xfs_ifork_ops {
+       xfs_ifork_verifier_t    verify_symlink;
+       xfs_ifork_verifier_t    verify_dir;
+       xfs_ifork_verifier_t    verify_attr;
+};
+extern struct xfs_ifork_ops    xfs_default_ifork_ops;
+
+xfs_failaddr_t xfs_ifork_verify_data(struct xfs_inode *ip,
+               struct xfs_ifork_ops *ops);
+xfs_failaddr_t xfs_ifork_verify_attr(struct xfs_inode *ip,
+               struct xfs_ifork_ops *ops);
+
 #endif /* __XFS_INODE_FORK_H__ */
-- 
2.16.4

++++++ xfsprogs-xfs-refactor-short-form-directory-structure-verifier.patch 
++++++
>From 590ec7c1de3f8fa708fef15d23c0787f0125e93d Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.w...@oracle.com>
Date: Mon, 26 Feb 2018 22:43:17 -0600
Subject: [PATCH] xfs: refactor short form directory structure verifier
 function
Git-commit: 1f98251ffd56f2d78fff582568e984dec952d89c
Patch-mainline: v4.16.0-rc1
References: bsc#1158504

Source kernel commit: dc042c2d8ff629dd411e9a60bce9c379e2f8aaf8

Change the short form directory structure verifier function to return
the instruction pointer of a failing check or NULL if everything's ok.

Signed-off-by: Darrick J. Wong <darrick.w...@oracle.com>
Reviewed-by: Dave Chinner <dchin...@redhat.com>
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 libxfs/xfs_dir2_priv.h  |  2 +-
 libxfs/xfs_dir2_sf.c    | 26 +++++++++++++-------------
 libxfs/xfs_inode_fork.c |  5 ++---
 3 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/libxfs/xfs_dir2_priv.h b/libxfs/xfs_dir2_priv.h
index 4badd26..1fca1c2 100644
--- a/libxfs/xfs_dir2_priv.h
+++ b/libxfs/xfs_dir2_priv.h
@@ -127,7 +127,7 @@ extern int xfs_dir2_sf_create(struct xfs_da_args *args, 
xfs_ino_t pino);
 extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
 extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
 extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
-extern int xfs_dir2_sf_verify(struct xfs_inode *ip);
+extern xfs_failaddr_t xfs_dir2_sf_verify(struct xfs_inode *ip);
 
 /* xfs_dir2_readdir.c */
 extern int xfs_readdir(struct xfs_trans *tp, struct xfs_inode *dp,
diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c
index 0c45398..cf352b6 100644
--- a/libxfs/xfs_dir2_sf.c
+++ b/libxfs/xfs_dir2_sf.c
@@ -628,7 +628,7 @@ xfs_dir2_sf_check(
 #endif /* DEBUG */
 
 /* Verify the consistency of an inline directory. */
-int
+xfs_failaddr_t
 xfs_dir2_sf_verify(
        struct xfs_inode                *ip)
 {
@@ -663,7 +663,7 @@ xfs_dir2_sf_verify(
         */
        if (size <= offsetof(struct xfs_dir2_sf_hdr, parent) ||
            size < xfs_dir2_sf_hdr_size(sfp->i8count))
-               return -EFSCORRUPTED;
+               return __this_address;
 
        endp = (char *)sfp + size;
 
@@ -672,7 +672,7 @@ xfs_dir2_sf_verify(
        i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
        error = xfs_dir_ino_validate(mp, ino);
        if (error)
-               return error;
+               return __this_address;
        offset = dops->data_first_offset;
 
        /* Check all reported entries */
@@ -684,11 +684,11 @@ xfs_dir2_sf_verify(
                 * within the data buffer.
                 */
                if (((char *)sfep + sizeof(*sfep)) >= endp)
-                       return -EFSCORRUPTED;
+                       return __this_address;
 
                /* Don't allow names with known bad length. */
                if (sfep->namelen == 0)
-                       return -EFSCORRUPTED;
+                       return __this_address;
 
                /*
                 * Check that the variable-length part of the structure is
@@ -697,23 +697,23 @@ xfs_dir2_sf_verify(
                 */
                next_sfep = dops->sf_nextentry(sfp, sfep);
                if (endp < (char *)next_sfep)
-                       return -EFSCORRUPTED;
+                       return __this_address;
 
                /* Check that the offsets always increase. */
                if (xfs_dir2_sf_get_offset(sfep) < offset)
-                       return -EFSCORRUPTED;
+                       return __this_address;
 
                /* Check the inode number. */
                ino = dops->sf_get_ino(sfp, sfep);
                i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
                error = xfs_dir_ino_validate(mp, ino);
                if (error)
-                       return error;
+                       return __this_address;
 
                /* Check the file type. */
                filetype = dops->sf_get_ftype(sfep);
                if (filetype >= XFS_DIR3_FT_MAX)
-                       return -EFSCORRUPTED;
+                       return __this_address;
 
                offset = xfs_dir2_sf_get_offset(sfep) +
                                dops->data_entsize(sfep->namelen);
@@ -721,16 +721,16 @@ xfs_dir2_sf_verify(
                sfep = next_sfep;
        }
        if (i8count != sfp->i8count)
-               return -EFSCORRUPTED;
+               return __this_address;
        if ((void *)sfep != (void *)endp)
-               return -EFSCORRUPTED;
+               return __this_address;
 
        /* Make sure this whole thing ought to be in local format. */
        if (offset + (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
            (uint)sizeof(xfs_dir2_block_tail_t) > mp->m_dir_geo->blksize)
-               return -EFSCORRUPTED;
+               return __this_address;
 
-       return 0;
+       return NULL;
 }
 
 /*
diff --git a/libxfs/xfs_inode_fork.c b/libxfs/xfs_inode_fork.c
index 3c0be58..b2bd8c7 100644
--- a/libxfs/xfs_inode_fork.c
+++ b/libxfs/xfs_inode_fork.c
@@ -182,10 +182,9 @@ xfs_iformat_fork(
 
        /* Check inline dir contents. */
        if (S_ISDIR(inode->i_mode) && dip->di_format == XFS_DINODE_FMT_LOCAL) {
-               error = xfs_dir2_sf_verify(ip);
-               if (error) {
+               if (xfs_dir2_sf_verify(ip)) {
                        xfs_idestroy_fork(ip, XFS_DATA_FORK);
-                       return error;
+                       return -EFSCORRUPTED;
                }
        }
 
-- 
2.16.4

++++++ xfsprogs-xfs_quota-fix-false-error-reporting-of-project-inher.patch 
++++++
>From b136f48b19a5b8e788aceb4b80e97d6ae9edd0ea Mon Sep 17 00:00:00 2001
From: Achilles Gaikwad <agaik...@redhat.com>
Date: Mon, 28 Jan 2019 13:03:08 -0600
Subject: [PATCH] xfs_quota: fix false error reporting of project inheritance
 flag is not set
Git-commit: b136f48b19a5b8e788aceb4b80e97d6ae9edd0ea
Patch-mainline: v4.20.0-rc1
References: bsc#1158758

After kernel commit:

9336e3a7 "xfs: project id inheritance is a directory only flag"

xfs stopped setting the project inheritance flag on regular files, but
userspace quota code still checks for it and will now issue the error:

"project inheritance flag is not set"

for every regular file during quotacheck.  Fix this by only checking
for the flag on directories.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1663502
Reported-by: Steven Gardner <sgard...@redhat.com>
Signed-off-by: Achilles Gaikwad <agaik...@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.w...@oracle.com>
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 quota/project.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/quota/project.c b/quota/project.c
index 78ede9e5..7c22947c 100644
--- a/quota/project.c
+++ b/quota/project.c
@@ -114,7 +114,7 @@ check_project(
                        printf(_("%s - project identifier is not set"
                                 " (inode=%u, tree=%u)\n"),
                                path, fsx.fsx_projid, (unsigned int)prid);
-               if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT))
+               if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT) && 
S_ISDIR(stat->st_mode))
                        printf(_("%s - project inheritance flag is not set\n"),
                                path);
        }
-- 
2.16.4

++++++ xfsprogs-xfs_repair-don-t-fail-directory-repairs-when-grabbin.patch 
++++++
>From b825809fdccde5f441858f05e0c3cf128f21b57a Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.w...@oracle.com>
Date: Thu, 8 Mar 2018 20:35:23 -0600
Subject: [PATCH] xfs_repair: don't fail directory repairs when grabbing inodes
Git-commit: 12ac6e048a0fbf987820ee613465eecf884a8528
Patch-mainline: v4.16.0-rc1
References: bsc#1158504

There are a few places where xfs_repair needs to be able to load a
damaged directory inode to perform repairs.  Since inline data fork
verifiers can now be customized, refactor libxfs_iget to enable
repair to get at this so that we don't crash in phase 6.

Signed-off-by: Darrick J. Wong <darrick.w...@oracle.com>
Reviewed-by: Eric Sandeen <sand...@redhat.com>
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 db/attrset.c        |  6 ++++--
 include/xfs_inode.h |  6 ++++--
 libxfs/rdwr.c       | 25 +++++++++++++++++--------
 libxfs/trans.c      |  6 ++++--
 libxfs/util.c       |  2 +-
 repair/phase6.c     | 16 +++++++++++-----
 6 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/db/attrset.c b/db/attrset.c
index ad3c8f3..457317a 100644
--- a/db/attrset.c
+++ b/db/attrset.c
@@ -151,7 +151,8 @@ attr_set_f(
                value = NULL;
        }
 
-       if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip)) {
+       if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip,
+                       &xfs_default_ifork_ops)) {
                dbprintf(_("failed to iget inode %llu\n"),
                        (unsigned long long)iocur_top->ino);
                goto out;
@@ -226,7 +227,8 @@ attr_remove_f(
 
        name = argv[optind];
 
-       if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip)) {
+       if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip,
+                       &xfs_default_ifork_ops)) {
                dbprintf(_("failed to iget inode %llu\n"),
                        (unsigned long long)iocur_top->ino);
                goto out;
diff --git a/include/xfs_inode.h b/include/xfs_inode.h
index 92829a2..f29f0f0 100644
--- a/include/xfs_inode.h
+++ b/include/xfs_inode.h
@@ -162,9 +162,11 @@ extern void        libxfs_trans_ichgtime(struct xfs_trans 
*,
 extern int     libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
 
 /* Inode Cache Interfaces */
-extern bool    libxfs_inode_verify_forks(struct xfs_inode *ip);
+extern bool    libxfs_inode_verify_forks(struct xfs_inode *ip,
+                               struct xfs_ifork_ops *);
 extern int     libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
-                               uint, struct xfs_inode **);
+                               uint, struct xfs_inode **,
+                               struct xfs_ifork_ops *);
 extern void    libxfs_iput(struct xfs_inode *);
 
 #define IRELE(ip) libxfs_iput(ip)
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 14afece..04ddd74 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -1342,11 +1342,15 @@ extern kmem_zone_t      *xfs_inode_zone;
  */
 bool
 libxfs_inode_verify_forks(
-       struct xfs_inode        *ip)
+       struct xfs_inode        *ip,
+       struct xfs_ifork_ops    *ops)
 {
        xfs_failaddr_t          fa;
 
-       fa = xfs_ifork_verify_data(ip, &xfs_default_ifork_ops);
+       if (!ops)
+               return true;
+
+       fa = xfs_ifork_verify_data(ip, ops);
        if (fa) {
                xfs_alert(ip->i_mount,
                                "%s: bad inode %Lu inline data fork at %pF",
@@ -1354,7 +1358,7 @@ libxfs_inode_verify_forks(
                return false;
        }
 
-       fa = xfs_ifork_verify_attr(ip, &xfs_default_ifork_ops);
+       fa = xfs_ifork_verify_attr(ip, ops);
        if (fa) {
                xfs_alert(ip->i_mount,
                                "%s: bad inode %Lu inline attr fork at %pF",
@@ -1365,11 +1369,16 @@ libxfs_inode_verify_forks(
 }
 
 int
-libxfs_iget(xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t ino, uint lock_flags,
-               xfs_inode_t **ipp)
+libxfs_iget(
+       struct xfs_mount        *mp,
+       struct xfs_trans        *tp,
+       xfs_ino_t               ino,
+       uint                    lock_flags,
+       struct xfs_inode        **ipp,
+       struct xfs_ifork_ops    *ifork_ops)
 {
-       xfs_inode_t     *ip;
-       int             error = 0;
+       struct xfs_inode        *ip;
+       int                     error = 0;
 
        ip = kmem_zone_zalloc(xfs_inode_zone, 0);
        if (!ip)
@@ -1384,7 +1393,7 @@ libxfs_iget(xfs_mount_t *mp, xfs_trans_t *tp, xfs_ino_t 
ino, uint lock_flags,
                return error;
        }
 
-       if (!libxfs_inode_verify_forks(ip)) {
+       if (!libxfs_inode_verify_forks(ip, ifork_ops)) {
                libxfs_iput(ip);
                return -EFSCORRUPTED;
        }
diff --git a/libxfs/trans.c b/libxfs/trans.c
index f330d4b..af568ba 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -243,9 +243,11 @@ libxfs_trans_iget(
        xfs_inode_log_item_t    *iip;
 
        if (tp == NULL)
-               return libxfs_iget(mp, tp, ino, lock_flags, ipp);
+               return libxfs_iget(mp, tp, ino, lock_flags, ipp,
+                               &xfs_default_ifork_ops);
 
-       error = libxfs_iget(mp, tp, ino, lock_flags, &ip);
+       error = libxfs_iget(mp, tp, ino, lock_flags, &ip,
+                       &xfs_default_ifork_ops);
        if (error)
                return error;
        ASSERT(ip != NULL);
diff --git a/libxfs/util.c b/libxfs/util.c
index 2dcce57..16db612 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -494,7 +494,7 @@ libxfs_iflush_int(xfs_inode_t *ip, xfs_buf_t *bp)
                VFS_I(ip)->i_version++;
 
        /* Check the inline fork data before we write out. */
-       if (!libxfs_inode_verify_forks(ip))
+       if (!libxfs_inode_verify_forks(ip, &xfs_default_ifork_ops))
                return -EFSCORRUPTED;
 
        /*
diff --git a/repair/phase6.c b/repair/phase6.c
index 1a398aa..aff83bc 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -927,7 +927,9 @@ mk_orphanage(xfs_mount_t *mp)
         * would have been cleared in phase3 and phase4.
         */
 
-       if ((i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip)))
+       i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip,
+                       &xfs_default_ifork_ops);
+       if (i)
                do_error(_("%d - couldn't iget root inode to obtain %s\n"),
                        i, ORPHANAGE);
 
@@ -951,7 +953,9 @@ mk_orphanage(xfs_mount_t *mp)
         * use iget/ijoin instead of trans_iget because the ialloc
         * wrapper can commit the transaction and start a new one
         */
-/*     if ((i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip)))
+/*     i = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &pip,
+                       &xfs_default_ifork_ops);
+       if (i)
                do_error(_("%d - couldn't iget root inode to make %s\n"),
                        i, ORPHANAGE);*/
 
@@ -1066,7 +1070,8 @@ mv_orphanage(
        xname.len = snprintf((char *)fname, sizeof(fname), "%llu",
                                (unsigned long long)ino);
 
-       err = -libxfs_iget(mp, NULL, orphanage_ino, 0, &orphanage_ip);
+       err = -libxfs_iget(mp, NULL, orphanage_ino, 0, &orphanage_ip,
+                       &xfs_default_ifork_ops);
        if (err)
                do_error(_("%d - couldn't iget orphanage inode\n"), err);
        /*
@@ -1078,7 +1083,8 @@ mv_orphanage(
                xname.len = snprintf((char *)fname, sizeof(fname), "%llu.%d",
                                        (unsigned long long)ino, ++incr);
 
-       if ((err = -libxfs_iget(mp, NULL, ino, 0, &ino_p)))
+       err = -libxfs_iget(mp, NULL, ino, 0, &ino_p, &xfs_default_ifork_ops);
+       if (err)
                do_error(_("%d - couldn't iget disconnected inode\n"), err);
 
        xname.type = libxfs_mode_to_ftype(VFS_I(ino_p)->i_mode);
@@ -2827,7 +2833,7 @@ process_dir_inode(
 
        ASSERT(!is_inode_refchecked(irec, ino_offset) || dotdot_update);
 
-       error = -libxfs_iget(mp, NULL, ino, 0, &ip);
+       error = -libxfs_iget(mp, NULL, ino, 0, &ip, NULL);
        if (error) {
                if (!no_modify)
                        do_error(
-- 
2.16.4

++++++ xfsprogs-xfs_repair-implement-custom-ifork-verifiers.patch ++++++
>From 78ccf903dc85056d1e47c732337a2f1387a69cad Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.w...@oracle.com>
Date: Mon, 26 Mar 2018 21:27:28 -0500
Subject: [PATCH] xfs_repair: implement custom ifork verifiers
Git-commit: 3452f451b2ecd91ca2c6609c150779e32a8a1442
Patch-mainline: v4.16.0-rc1
References: bsc#1158504

There are a few cases where an early stage of xfs_repair will write an
invalid inode fork buffer to signal to a later stage that it needs to
correct the value.  This happens in phase 4 when we detect an inline
format directory with an invalid .. pointer.  To avoid triggering the
ifork verifiers on this, inject a custom verifier for phase 6 that lets
this pass for now.

Signed-off-by: Darrick J. Wong <darrick.w...@oracle.com>
Reviewed-by: Eric Sandeen <sand...@redhat.com>
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 libxfs/libxfs_api_defs.h |  2 ++
 repair/phase6.c          | 57 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 709632f..8b8f007 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -151,5 +151,7 @@
 #define xfs_refc_block                 libxfs_refc_block
 #define xfs_rmap_compare               libxfs_rmap_compare
 #define xfs_fs_geometry                        libxfs_fs_geometry
+#define xfs_dir_get_ops                        libxfs_dir_get_ops
+#define xfs_default_ifork_ops          libxfs_default_ifork_ops
 
 #endif /* __LIBXFS_API_DEFS_H__ */
diff --git a/repair/phase6.c b/repair/phase6.c
index aff83bc..ed005e8 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -38,6 +38,61 @@ static struct xfs_name               xfs_name_dot = 
{(unsigned char *)".",
                                                1,
                                                XFS_DIR3_FT_DIR};
 
+/*
+ * When we're checking directory inodes, we're allowed to set a directory's
+ * dotdot entry to zero to signal that the parent needs to be reconnected
+ * during phase 6.  If we're handling a shortform directory the ifork
+ * verifiers will fail, so temporarily patch out this canary so that we can
+ * verify the rest of the fork and move on to fixing the dir.
+ */
+static xfs_failaddr_t
+phase6_verify_dir(
+       struct xfs_inode                *ip)
+{
+       struct xfs_mount                *mp = ip->i_mount;
+       const struct xfs_dir_ops        *dops;
+       struct xfs_ifork                *ifp;
+       struct xfs_dir2_sf_hdr          *sfp;
+       xfs_failaddr_t                  fa;
+       xfs_ino_t                       old_parent;
+       bool                            parent_bypass = false;
+       int                             size;
+
+       dops = libxfs_dir_get_ops(mp, NULL);
+
+       ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
+       sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data;
+       size = ifp->if_bytes;
+
+       /*
+        * If this is a shortform directory, phase4 may have set the parent
+        * inode to zero to indicate that it must be fixed.  Temporarily
+        * set a valid parent so that the directory verifier will pass.
+        */
+       if (size > offsetof(struct xfs_dir2_sf_hdr, parent) &&
+           size >= xfs_dir2_sf_hdr_size(sfp->i8count)) {
+               old_parent = dops->sf_get_parent_ino(sfp);
+               if (old_parent == 0) {
+                       dops->sf_put_parent_ino(sfp, mp->m_sb.sb_rootino);
+                       parent_bypass = true;
+               }
+       }
+
+       fa = libxfs_default_ifork_ops.verify_dir(ip);
+
+       /* Put it back. */
+       if (parent_bypass)
+               dops->sf_put_parent_ino(sfp, old_parent);
+
+       return fa;
+}
+
+static struct xfs_ifork_ops phase6_ifork_ops = {
+       .verify_attr    = xfs_attr_shortform_verify,
+       .verify_dir     = phase6_verify_dir,
+       .verify_symlink = xfs_symlink_shortform_verify,
+};
+
 /*
  * Data structures used to keep track of directories where the ".."
  * entries are updated. These must be rebuilt after the initial pass
@@ -2833,7 +2888,7 @@ process_dir_inode(
 
        ASSERT(!is_inode_refchecked(irec, ino_offset) || dotdot_update);
 
-       error = -libxfs_iget(mp, NULL, ino, 0, &ip, NULL);
+       error = -libxfs_iget(mp, NULL, ino, 0, &ip, &phase6_ifork_ops);
        if (error) {
                if (!no_modify)
                        do_error(
-- 
2.16.4

++++++ xfsprogs-xfs_repair-use-custom-ifork-verifier-in-mv_orphanage.patch 
++++++
>From 24212da4f9362ab2fc02ee498953f7cd6e6032a9 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sand...@redhat.com>
Date: Mon, 26 Mar 2018 21:27:28 -0500
Subject: [PATCH] xfs_repair: use custom ifork verifier in mv_orphanage
Git-commit: f8cd7da8eec39dddbdeebac8617b64f2a1a2deb0
Patch-mainline: v4.16.0-rc1
References: bsc#1158504

Now that we have a custom verifier which can ignore parent
inode numbers, use it in mv_orphanage() as well; orphan inodes
may have invalid parents, and we're about to reconnect
them anyway, so override that test when we get them off disk.

Signed-off-by: Eric Sandeen <sand...@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.w...@oracle.com>
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 repair/phase6.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/repair/phase6.c b/repair/phase6.c
index ed005e8..498a3b5 100644
--- a/repair/phase6.c
+++ b/repair/phase6.c
@@ -1138,7 +1138,8 @@ mv_orphanage(
                xname.len = snprintf((char *)fname, sizeof(fname), "%llu.%d",
                                        (unsigned long long)ino, ++incr);
 
-       err = -libxfs_iget(mp, NULL, ino, 0, &ino_p, &xfs_default_ifork_ops);
+       /* Orphans may not have a proper parent, so use custom ops here */
+       err = -libxfs_iget(mp, NULL, ino, 0, &ino_p, &phase6_ifork_ops);
        if (err)
                do_error(_("%d - couldn't iget disconnected inode\n"), err);
 
-- 
2.16.4

++++++ xfsprogs-xfs_repair-use-libxfs-extsize-cowextsize-validation-.patch 
++++++
>From e45ab8b8e5921fa3fa763a5e9729d90d342dcbcc Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <darrick.w...@oracle.com>
Date: Wed, 1 Aug 2018 17:06:44 -0500
Subject: [PATCH] xfs_repair: use libxfs extsize/cowextsize validation helpers
Git-commit: db3d080b40ecce86ec6755a04544bbc59aa344da
Patch-mainline: v4.18.0-rc1
References: bsc#1158509

Now that we've ported the extent size hint verifiers to libxfs, call
them from xfs_repair instead of open-coding the checks.  Tweak the
repair message slightly to reflect the fact that we zero the field and
clear the inode flag if the hint is garbage or is inconsistent with the
inode flags.

Signed-off-by: Darrick J. Wong <darrick.w...@oracle.com>
Reviewed-by: Eric Sandeen <sand...@redhat.com>
Signed-off-by: Eric Sandeen <sand...@sandeen.net>
Acked-by: Anthony Iliopoulos <ailiopou...@suse.com>

---
 libxfs/libxfs_api_defs.h |  2 ++
 repair/dinode.c          | 75 +++++++++++++++++-------------------------------
 2 files changed, 28 insertions(+), 49 deletions(-)

diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 8b8f0071..ab2b7c42 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -106,6 +106,8 @@
 #define xfs_dinode_calc_crc            libxfs_dinode_calc_crc
 #define xfs_idata_realloc              libxfs_idata_realloc
 #define xfs_idestroy_fork              libxfs_idestroy_fork
+#define xfs_inode_validate_extsize     libxfs_inode_validate_extsize
+#define xfs_inode_validate_cowextsize  libxfs_inode_validate_cowextsize
 
 #define xfs_rmap_ag_owner              libxfs_rmap_ag_owner
 #define xfs_rmap_alloc                 libxfs_rmap_alloc
diff --git a/repair/dinode.c b/repair/dinode.c
index af4d740d..0f7bf354 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2829,24 +2829,21 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 
"\n"),
         * only regular files with REALTIME or EXTSIZE flags set can have
         * extsize set, or directories with EXTSZINHERIT.
         */
-       if (be32_to_cpu(dino->di_extsize) != 0) {
-               if ((type == XR_INO_RTDATA) ||
-                   (type == XR_INO_DIR && (be16_to_cpu(dino->di_flags) &
-                                       XFS_DIFLAG_EXTSZINHERIT)) ||
-                   (type == XR_INO_DATA && (be16_to_cpu(dino->di_flags) &
-                                XFS_DIFLAG_EXTSIZE)))  {
-                       /* s'okay */ ;
-               } else {
-                       do_warn(
-_("bad non-zero extent size %u for non-realtime/extsize inode %" PRIu64 ", "),
-                                       be32_to_cpu(dino->di_extsize), lino);
-                       if (!no_modify)  {
-                               do_warn(_("resetting to zero\n"));
-                               dino->di_extsize = 0;
-                               *dirty = 1;
-                       } else
-                               do_warn(_("would reset to zero\n"));
-               }
+       if (libxfs_inode_validate_extsize(mp,
+                       be32_to_cpu(dino->di_extsize),
+                       be16_to_cpu(dino->di_mode),
+                       be16_to_cpu(dino->di_flags)) != NULL) {
+               do_warn(
+_("Bad extent size %u on inode %" PRIu64 ", "),
+                               be32_to_cpu(dino->di_extsize), lino);
+               if (!no_modify)  {
+                       do_warn(_("resetting to zero\n"));
+                       dino->di_extsize = 0;
+                       dino->di_flags &= ~cpu_to_be16(XFS_DIFLAG_EXTSIZE |
+                                                      XFS_DIFLAG_EXTSZINHERIT);
+                       *dirty = 1;
+               } else
+                       do_warn(_("would reset to zero\n"));
        }
 
        /*
@@ -2854,41 +2851,21 @@ _("bad non-zero extent size %u for non-realtime/extsize 
inode %" PRIu64 ", "),
         * set can have extsize set.
         */
        if (dino->di_version >= 3 &&
-           be32_to_cpu(dino->di_cowextsize) != 0) {
-               if ((type == XR_INO_DIR || type == XR_INO_DATA) &&
-                   (be64_to_cpu(dino->di_flags2) &
-                                       XFS_DIFLAG2_COWEXTSIZE)) {
-                       /* s'okay */ ;
-               } else {
-                       do_warn(
-_("Cannot have non-zero CoW extent size %u on non-cowextsize inode %" PRIu64 
", "),
-                                       be32_to_cpu(dino->di_cowextsize), lino);
-                       if (!no_modify)  {
-                               do_warn(_("resetting to zero\n"));
-                               dino->di_flags2 &= 
~cpu_to_be64(XFS_DIFLAG2_COWEXTSIZE);
-                               dino->di_cowextsize = 0;
-                               *dirty = 1;
-                       } else
-                               do_warn(_("would reset to zero\n"));
-               }
-       }
-
-       /*
-        * Can't have the COWEXTSIZE flag set with no hint.
-        */
-       if (dino->di_version >= 3 &&
-           be32_to_cpu(dino->di_cowextsize) == 0 &&
-           (be64_to_cpu(dino->di_flags2) & XFS_DIFLAG2_COWEXTSIZE)) {
+           libxfs_inode_validate_cowextsize(mp,
+                       be32_to_cpu(dino->di_cowextsize),
+                       be16_to_cpu(dino->di_mode),
+                       be16_to_cpu(dino->di_flags),
+                       be64_to_cpu(dino->di_flags2)) != NULL) {
                do_warn(
-_("Cannot have CoW extent size of zero on cowextsize inode %" PRIu64 ", "),
-                               lino);
+_("Bad CoW extent size %u on inode %" PRIu64 ", "),
+                               be32_to_cpu(dino->di_cowextsize), lino);
                if (!no_modify)  {
-                       do_warn(_("clearing cowextsize flag\n"));
+                       do_warn(_("resetting to zero\n"));
                        dino->di_flags2 &= ~cpu_to_be64(XFS_DIFLAG2_COWEXTSIZE);
+                       dino->di_cowextsize = 0;
                        *dirty = 1;
-               } else {
-                       do_warn(_("would clear cowextsize flag\n"));
-               }
+               } else
+                       do_warn(_("would reset to zero\n"));
        }
 
        /*
-- 
2.16.4



Reply via email to