]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - fs/xfs/xfs_inode_item.c
s390/crypto: Fix return code checking in cbc_paes_crypt()
[mirror_ubuntu-bionic-kernel.git] / fs / xfs / xfs_inode_item.c
index a705f34b58fad089659a019dcdd1caecffd01aa3..6ee5c3bf19ad9e7940d03e882625c2955962a24d 100644 (file)
@@ -72,7 +72,6 @@ xfs_inode_item_data_fork_size(
                break;
 
        case XFS_DINODE_FMT_DEV:
-       case XFS_DINODE_FMT_UUID:
                break;
        default:
                ASSERT(0);
@@ -156,15 +155,13 @@ xfs_inode_item_format_data_fork(
        switch (ip->i_d.di_format) {
        case XFS_DINODE_FMT_EXTENTS:
                iip->ili_fields &=
-                       ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
-                         XFS_ILOG_DEV | XFS_ILOG_UUID);
+                       ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV);
 
                if ((iip->ili_fields & XFS_ILOG_DEXT) &&
                    ip->i_d.di_nextents > 0 &&
                    ip->i_df.if_bytes > 0) {
                        struct xfs_bmbt_rec *p;
 
-                       ASSERT(ip->i_df.if_u1.if_extents != NULL);
                        ASSERT(xfs_iext_count(&ip->i_df) > 0);
 
                        p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IEXT);
@@ -181,8 +178,7 @@ xfs_inode_item_format_data_fork(
                break;
        case XFS_DINODE_FMT_BTREE:
                iip->ili_fields &=
-                       ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT |
-                         XFS_ILOG_DEV | XFS_ILOG_UUID);
+                       ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | XFS_ILOG_DEV);
 
                if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
                    ip->i_df.if_broot_bytes > 0) {
@@ -200,8 +196,7 @@ xfs_inode_item_format_data_fork(
                break;
        case XFS_DINODE_FMT_LOCAL:
                iip->ili_fields &=
-                       ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT |
-                         XFS_ILOG_DEV | XFS_ILOG_UUID);
+                       ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | XFS_ILOG_DEV);
                if ((iip->ili_fields & XFS_ILOG_DDATA) &&
                    ip->i_df.if_bytes > 0) {
                        /*
@@ -224,17 +219,9 @@ xfs_inode_item_format_data_fork(
                break;
        case XFS_DINODE_FMT_DEV:
                iip->ili_fields &=
-                       ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
-                         XFS_ILOG_DEXT | XFS_ILOG_UUID);
+                       ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEXT);
                if (iip->ili_fields & XFS_ILOG_DEV)
-                       ilf->ilf_u.ilfu_rdev = ip->i_df.if_u2.if_rdev;
-               break;
-       case XFS_DINODE_FMT_UUID:
-               iip->ili_fields &=
-                       ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
-                         XFS_ILOG_DEXT | XFS_ILOG_DEV);
-               if (iip->ili_fields & XFS_ILOG_UUID)
-                       ilf->ilf_u.ilfu_uuid = ip->i_df.if_u2.if_uuid;
+                       ilf->ilf_u.ilfu_rdev = sysv_encode_dev(VFS_I(ip)->i_rdev);
                break;
        default:
                ASSERT(0);
@@ -264,7 +251,6 @@ xfs_inode_item_format_attr_fork(
 
                        ASSERT(xfs_iext_count(ip->i_afp) ==
                                ip->i_d.di_anextents);
-                       ASSERT(ip->i_afp->if_u1.if_extents != NULL);
 
                        p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT);
                        data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK);
@@ -364,6 +350,9 @@ xfs_inode_to_log_dinode(
        to->di_dmstate = from->di_dmstate;
        to->di_flags = from->di_flags;
 
+       /* log a dummy value to ensure log structure is fully initialised */
+       to->di_next_unlinked = NULLAGINO;
+
        if (from->di_version == 3) {
                to->di_changecount = inode->i_version;
                to->di_crtime.t_sec = from->di_crtime.t_sec;
@@ -404,6 +393,11 @@ xfs_inode_item_format_core(
  * the second with the on-disk inode structure, and a possible third and/or
  * fourth with the inode data/extents/b-tree root and inode attributes
  * data/extents/b-tree root.
+ *
+ * Note: Always use the 64 bit inode log format structure so we don't
+ * leave an uninitialised hole in the format item on 64 bit systems. Log
+ * recovery on 32 bit systems handles this just fine, so there's no reason
+ * for not using an initialising the properly padded structure all the time.
  */
 STATIC void
 xfs_inode_item_format(
@@ -412,8 +406,8 @@ xfs_inode_item_format(
 {
        struct xfs_inode_log_item *iip = INODE_ITEM(lip);
        struct xfs_inode        *ip = iip->ili_inode;
-       struct xfs_inode_log_format *ilf;
        struct xfs_log_iovec    *vecp = NULL;
+       struct xfs_inode_log_format *ilf;
 
        ASSERT(ip->i_d.di_version > 1);
 
@@ -425,7 +419,17 @@ xfs_inode_item_format(
        ilf->ilf_boffset = ip->i_imap.im_boffset;
        ilf->ilf_fields = XFS_ILOG_CORE;
        ilf->ilf_size = 2; /* format + core */
-       xlog_finish_iovec(lv, vecp, sizeof(struct xfs_inode_log_format));
+
+       /*
+        * make sure we don't leak uninitialised data into the log in the case
+        * when we don't log every field in the inode.
+        */
+       ilf->ilf_dsize = 0;
+       ilf->ilf_asize = 0;
+       ilf->ilf_pad = 0;
+       memset(&ilf->ilf_u, 0, sizeof(ilf->ilf_u));
+
+       xlog_finish_iovec(lv, vecp, sizeof(*ilf));
 
        xfs_inode_item_format_core(ip, lv, &vecp);
        xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp);
@@ -855,44 +859,28 @@ xfs_istale_done(
 }
 
 /*
- * convert an xfs_inode_log_format struct from either 32 or 64 bit versions
- * (which can have different field alignments) to the native version
+ * convert an xfs_inode_log_format struct from the old 32 bit version
+ * (which can have different field alignments) to the native 64 bit version
  */
 int
 xfs_inode_item_format_convert(
-       xfs_log_iovec_t         *buf,
-       xfs_inode_log_format_t  *in_f)
+       struct xfs_log_iovec            *buf,
+       struct xfs_inode_log_format     *in_f)
 {
-       if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) {
-               xfs_inode_log_format_32_t *in_f32 = buf->i_addr;
-
-               in_f->ilf_type = in_f32->ilf_type;
-               in_f->ilf_size = in_f32->ilf_size;
-               in_f->ilf_fields = in_f32->ilf_fields;
-               in_f->ilf_asize = in_f32->ilf_asize;
-               in_f->ilf_dsize = in_f32->ilf_dsize;
-               in_f->ilf_ino = in_f32->ilf_ino;
-               /* copy biggest field of ilf_u */
-               uuid_copy(&in_f->ilf_u.ilfu_uuid, &in_f32->ilf_u.ilfu_uuid);
-               in_f->ilf_blkno = in_f32->ilf_blkno;
-               in_f->ilf_len = in_f32->ilf_len;
-               in_f->ilf_boffset = in_f32->ilf_boffset;
-               return 0;
-       } else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){
-               xfs_inode_log_format_64_t *in_f64 = buf->i_addr;
-
-               in_f->ilf_type = in_f64->ilf_type;
-               in_f->ilf_size = in_f64->ilf_size;
-               in_f->ilf_fields = in_f64->ilf_fields;
-               in_f->ilf_asize = in_f64->ilf_asize;
-               in_f->ilf_dsize = in_f64->ilf_dsize;
-               in_f->ilf_ino = in_f64->ilf_ino;
-               /* copy biggest field of ilf_u */
-               uuid_copy(&in_f->ilf_u.ilfu_uuid, &in_f64->ilf_u.ilfu_uuid);
-               in_f->ilf_blkno = in_f64->ilf_blkno;
-               in_f->ilf_len = in_f64->ilf_len;
-               in_f->ilf_boffset = in_f64->ilf_boffset;
-               return 0;
-       }
-       return -EFSCORRUPTED;
+       struct xfs_inode_log_format_32  *in_f32 = buf->i_addr;
+
+       if (buf->i_len != sizeof(*in_f32))
+               return -EFSCORRUPTED;
+
+       in_f->ilf_type = in_f32->ilf_type;
+       in_f->ilf_size = in_f32->ilf_size;
+       in_f->ilf_fields = in_f32->ilf_fields;
+       in_f->ilf_asize = in_f32->ilf_asize;
+       in_f->ilf_dsize = in_f32->ilf_dsize;
+       in_f->ilf_ino = in_f32->ilf_ino;
+       memcpy(&in_f->ilf_u, &in_f32->ilf_u, sizeof(in_f->ilf_u));
+       in_f->ilf_blkno = in_f32->ilf_blkno;
+       in_f->ilf_len = in_f32->ilf_len;
+       in_f->ilf_boffset = in_f32->ilf_boffset;
+       return 0;
 }