Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ff0b97c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'xfs-4.14-fixes-5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Darrick Wong:

 - Fix a stale kernel memory exposure when logging inodes.

 - Fix some build problems with CONFIG_XFS_RT=n

 - Don't change inode mode if the acl write fails, leaving the file
   totally inaccessible.

 - Fix a dangling pointer problem when removing an attr fork under
   memory pressure.

 - Don't crash while trying to invalidate a null buffer associated with
   a corrupt metadata pointer.

* tag 'xfs-4.14-fixes-5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  xfs: handle error if xfs_btree_get_bufs fails
  xfs: reinit btree pointer on attr tree inactivation walk
  xfs: Fix bool initialization/comparison
  xfs: don't change inode mode if ACL update fails
  xfs: move more RT specific code under CONFIG_XFS_RT
  xfs: Don't log uninitialised fields in inode structures
parents 2aab9c3c 93e8befc
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1584,6 +1584,10 @@ xfs_alloc_ag_vextent_small(

				bp = xfs_btree_get_bufs(args->mp, args->tp,
					args->agno, fbno, 0);
				if (!bp) {
					error = -EFSCORRUPTED;
					goto error0;
				}
				xfs_trans_binval(args->tp, bp);
			}
			args->len = 1;
@@ -2141,6 +2145,10 @@ xfs_alloc_fix_freelist(
		if (error)
			goto out_agbp_relse;
		bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0);
		if (!bp) {
			error = -EFSCORRUPTED;
			goto out_agbp_relse;
		}
		xfs_trans_binval(tp, bp);
	}

+2 −2
Original line number Diff line number Diff line
@@ -1477,14 +1477,14 @@ xfs_bmap_isaeof(
	int			is_empty;
	int			error;

	bma->aeof = 0;
	bma->aeof = false;
	error = xfs_bmap_last_extent(NULL, bma->ip, whichfork, &rec,
				     &is_empty);
	if (error)
		return error;

	if (is_empty) {
		bma->aeof = 1;
		bma->aeof = true;
		return 0;
	}

+2 −2
Original line number Diff line number Diff line
@@ -1962,7 +1962,7 @@ xfs_difree_inobt(
	if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
	    rec.ir_free == XFS_INOBT_ALL_FREE &&
	    mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK) {
		xic->deleted = 1;
		xic->deleted = true;
		xic->first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
		xic->alloc = xfs_inobt_irec_to_allocmask(&rec);

@@ -1989,7 +1989,7 @@ xfs_difree_inobt(

		xfs_difree_inode_chunk(mp, agno, &rec, dfops);
	} else {
		xic->deleted = 0;
		xic->deleted = false;

		error = xfs_inobt_update(cur, &rec);
		if (error) {
+8 −19
Original line number Diff line number Diff line
@@ -270,6 +270,7 @@ typedef struct xfs_inode_log_format {
	uint32_t		ilf_fields;	/* flags for fields logged */
	uint16_t		ilf_asize;	/* size of attr d/ext/root */
	uint16_t		ilf_dsize;	/* size of data/ext/root */
	uint32_t		ilf_pad;	/* pad for 64 bit boundary */
	uint64_t		ilf_ino;	/* inode number */
	union {
		uint32_t	ilfu_rdev;	/* rdev value for dev inode*/
@@ -280,29 +281,17 @@ typedef struct xfs_inode_log_format {
	int32_t			ilf_boffset;	/* off of inode in buffer */
} xfs_inode_log_format_t;

typedef struct xfs_inode_log_format_32 {
	uint16_t		ilf_type;	/* inode log item type */
	uint16_t		ilf_size;	/* size of this item */
	uint32_t		ilf_fields;	/* flags for fields logged */
	uint16_t		ilf_asize;	/* size of attr d/ext/root */
	uint16_t		ilf_dsize;	/* size of data/ext/root */
	uint64_t		ilf_ino;	/* inode number */
	union {
		uint32_t	ilfu_rdev;	/* rdev value for dev inode*/
		uuid_t		ilfu_uuid;	/* mount point value */
	} ilf_u;
	int64_t			ilf_blkno;	/* blkno of inode buffer */
	int32_t			ilf_len;	/* len of inode buffer */
	int32_t			ilf_boffset;	/* off of inode in buffer */
} __attribute__((packed)) xfs_inode_log_format_32_t;

typedef struct xfs_inode_log_format_64 {
/*
 * Old 32 bit systems will log in this format without the 64 bit
 * alignment padding. Recovery will detect this and convert it to the
 * correct format.
 */
struct xfs_inode_log_format_32 {
	uint16_t		ilf_type;	/* inode log item type */
	uint16_t		ilf_size;	/* size of this item */
	uint32_t		ilf_fields;	/* flags for fields logged */
	uint16_t		ilf_asize;	/* size of attr d/ext/root */
	uint16_t		ilf_dsize;	/* size of data/ext/root */
	uint32_t		ilf_pad;	/* pad for 64 bit boundary */
	uint64_t		ilf_ino;	/* inode number */
	union {
		uint32_t	ilfu_rdev;	/* rdev value for dev inode*/
@@ -311,7 +300,7 @@ typedef struct xfs_inode_log_format_64 {
	int64_t			ilf_blkno;	/* blkno of inode buffer */
	int32_t			ilf_len;	/* len of inode buffer */
	int32_t			ilf_boffset;	/* off of inode in buffer */
} xfs_inode_log_format_64_t;
} __attribute__((packed));


/*
+16 −6
Original line number Diff line number Diff line
@@ -247,6 +247,8 @@ xfs_set_mode(struct inode *inode, umode_t mode)
int
xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
	umode_t mode;
	bool set_mode = false;
	int error = 0;

	if (!acl)
@@ -257,16 +259,24 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
		return error;

	if (type == ACL_TYPE_ACCESS) {
		umode_t mode;

		error = posix_acl_update_mode(inode, &mode, &acl);
		if (error)
			return error;
		error = xfs_set_mode(inode, mode);
		if (error)
			return error;
		set_mode = true;
	}

 set_acl:
	return __xfs_set_acl(inode, acl, type);
	error =  __xfs_set_acl(inode, acl, type);
	if (error)
		return error;

	/*
	 * We set the mode after successfully updating the ACL xattr because the
	 * xattr update can fail at ENOSPC and we don't want to change the mode
	 * if the ACL update hasn't been applied.
	 */
	if (set_mode)
		error = xfs_set_mode(inode, mode);

	return error;
}
Loading