]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: don't fail directory repairs when grabbing inodes
authorDarrick J. Wong <darrick.wong@oracle.com>
Fri, 9 Mar 2018 02:35:23 +0000 (20:35 -0600)
committerEric Sandeen <sandeen@redhat.com>
Fri, 9 Mar 2018 02:35:23 +0000 (20:35 -0600)
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.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
db/attrset.c
include/xfs_inode.h
libxfs/rdwr.c
libxfs/trans.c
libxfs/util.c
repair/phase6.c

index ad3c8f371dc0886c707c88e43024e57a7ebb5925..457317a7bd863b49020fb3074122d21f1e6c33b9 100644 (file)
@@ -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;
index 92829a2556805a2c1af7c478ba6fac280ad90203..f29f0f0d388cfdad1aa768f13d86b4eef705ef0c 100644 (file)
@@ -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)
index 314209495095249f89c06f3ecade86b76f83644c..ae6198844509d8ec700bd15aef1839a7f45477ef 100644 (file)
@@ -1360,12 +1360,16 @@ extern kmem_zone_t      *xfs_ili_zone;
  */
 bool
 libxfs_inode_verify_forks(
-       struct xfs_inode        *ip)
+       struct xfs_inode        *ip,
+       struct xfs_ifork_ops    *ops)
 {
        struct xfs_ifork        *ifp;
        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) {
                ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
                xfs_inode_verifier_error(ip, -EFSCORRUPTED, "data fork",
@@ -1373,7 +1377,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) {
                ifp = XFS_IFORK_PTR(ip, XFS_ATTR_FORK);
                xfs_inode_verifier_error(ip, -EFSCORRUPTED, "attr fork",
@@ -1385,11 +1389,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)
@@ -1404,7 +1413,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;
        }
index 0e7b7ae0a7b2c93b448ec3ee5ea2c62ce00f83af..67b1117595cefd670c6fa37d2aad14b47dd3821b 100644 (file)
@@ -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);
index aac558cf0cf43981d5f67f3fa07f88612b6a027c..611ab9c02b7fa9a54cc5ebf8a5a1af6afcd3e83a 100644 (file)
@@ -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;
 
        /*
index 1a398aa127c2b47c951e7c2e191654413bcb2504..aff83bc6e80f380d8d9c378faa8ce53e866c1987 100644 (file)
@@ -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(