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

Commit a4241aeb authored by Dave Chinner's avatar Dave Chinner
Browse files

Merge branch 'xfs-misc-fixes-for-3.18-1' into for-next

parents 41b9d726 ab6978c2
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -2209,6 +2209,10 @@ xfs_agf_verify(
	      be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)))
	      be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)))
		return false;
		return false;


	if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS)
		return false;

	/*
	/*
	 * during growfs operations, the perag is not fully initialised,
	 * during growfs operations, the perag is not fully initialised,
	 * so we can't use it for any useful checking. growfs ensures we can't
	 * so we can't use it for any useful checking. growfs ensures we can't
+12 −55
Original line number Original line Diff line number Diff line
@@ -237,7 +237,8 @@ xfs_dir_init(
}
}


/*
/*
  Enter a name in a directory.
 * Enter a name in a directory, or check for available space.
 * If inum is 0, only the available space test is performed.
 */
 */
int
int
xfs_dir_createname(
xfs_dir_createname(
@@ -254,10 +255,12 @@ xfs_dir_createname(
	int			v;		/* type-checking value */
	int			v;		/* type-checking value */


	ASSERT(S_ISDIR(dp->i_d.di_mode));
	ASSERT(S_ISDIR(dp->i_d.di_mode));
	if (inum) {
		rval = xfs_dir_ino_validate(tp->t_mountp, inum);
		rval = xfs_dir_ino_validate(tp->t_mountp, inum);
		if (rval)
		if (rval)
			return rval;
			return rval;
		XFS_STATS_INC(xs_dir_create);
		XFS_STATS_INC(xs_dir_create);
	}


	args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
	args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
	if (!args)
	if (!args)
@@ -276,6 +279,8 @@ xfs_dir_createname(
	args->whichfork = XFS_DATA_FORK;
	args->whichfork = XFS_DATA_FORK;
	args->trans = tp;
	args->trans = tp;
	args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
	args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
	if (!inum)
		args->op_flags |= XFS_DA_OP_JUSTCHECK;


	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
		rval = xfs_dir2_sf_addname(args);
		rval = xfs_dir2_sf_addname(args);
@@ -535,62 +540,14 @@ xfs_dir_replace(


/*
/*
 * See if this entry can be added to the directory without allocating space.
 * See if this entry can be added to the directory without allocating space.
 * First checks that the caller couldn't reserve enough space (resblks = 0).
 */
 */
int
int
xfs_dir_canenter(
xfs_dir_canenter(
	xfs_trans_t	*tp,
	xfs_trans_t	*tp,
	xfs_inode_t	*dp,
	xfs_inode_t	*dp,
	struct xfs_name	*name,		/* name of entry to add */
	struct xfs_name	*name)		/* name of entry to add */
	uint		resblks)
{
{
	struct xfs_da_args *args;
	return xfs_dir_createname(tp, dp, name, 0, NULL, NULL, 0);
	int		rval;
	int		v;		/* type-checking value */

	if (resblks)
		return 0;

	ASSERT(S_ISDIR(dp->i_d.di_mode));

	args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
	if (!args)
		return -ENOMEM;

	args->geo = dp->i_mount->m_dir_geo;
	args->name = name->name;
	args->namelen = name->len;
	args->filetype = name->type;
	args->hashval = dp->i_mount->m_dirnameops->hashname(name);
	args->dp = dp;
	args->whichfork = XFS_DATA_FORK;
	args->trans = tp;
	args->op_flags = XFS_DA_OP_JUSTCHECK | XFS_DA_OP_ADDNAME |
							XFS_DA_OP_OKNOENT;

	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
		rval = xfs_dir2_sf_addname(args);
		goto out_free;
	}

	rval = xfs_dir2_isblock(args, &v);
	if (rval)
		goto out_free;
	if (v) {
		rval = xfs_dir2_block_addname(args);
		goto out_free;
	}

	rval = xfs_dir2_isleaf(args, &v);
	if (rval)
		goto out_free;
	if (v)
		rval = xfs_dir2_leaf_addname(args);
	else
		rval = xfs_dir2_node_addname(args);
out_free:
	kmem_free(args);
	return rval;
}
}


/*
/*
+1 −1
Original line number Original line Diff line number Diff line
@@ -136,7 +136,7 @@ extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
				xfs_fsblock_t *first,
				xfs_fsblock_t *first,
				struct xfs_bmap_free *flist, xfs_extlen_t tot);
				struct xfs_bmap_free *flist, xfs_extlen_t tot);
extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
				struct xfs_name *name, uint resblks);
				struct xfs_name *name);


/*
/*
 * Direct call from the bmap code, bypassing the generic directory layer.
 * Direct call from the bmap code, bypassing the generic directory layer.
+2 −0
Original line number Original line Diff line number Diff line
@@ -2051,6 +2051,8 @@ xfs_agi_verify(
	if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)))
	if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)))
		return false;
		return false;


	if (be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS)
		return false;
	/*
	/*
	 * during growfs operations, the perag is not fully initialised,
	 * during growfs operations, the perag is not fully initialised,
	 * so we can't use it for any useful checking. growfs ensures we can't
	 * so we can't use it for any useful checking. growfs ensures we can't
+35 −14
Original line number Original line Diff line number Diff line
@@ -424,20 +424,24 @@ xfs_rtfind_forw(
}
}


/*
/*
 * Read and modify the summary information for a given extent size,
 * Read and/or modify the summary information for a given extent size,
 * bitmap block combination.
 * bitmap block combination.
 * Keeps track of a current summary block, so we don't keep reading
 * Keeps track of a current summary block, so we don't keep reading
 * it from the buffer cache.
 * it from the buffer cache.
 *
 * Summary information is returned in *sum if specified.
 * If no delta is specified, returns summary only.
 */
 */
int
int
xfs_rtmodify_summary(
xfs_rtmodify_summary_int(
	xfs_mount_t	*mp,		/* file system mount point */
	xfs_mount_t	*mp,		/* file system mount structure */
	xfs_trans_t	*tp,		/* transaction pointer */
	xfs_trans_t	*tp,		/* transaction pointer */
	int		log,		/* log2 of extent size */
	int		log,		/* log2 of extent size */
	xfs_rtblock_t	bbno,		/* bitmap block number */
	xfs_rtblock_t	bbno,		/* bitmap block number */
	int		delta,		/* change to make to summary info */
	int		delta,		/* change to make to summary info */
	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
	xfs_fsblock_t	*rsb)		/* in/out: summary block number */
	xfs_fsblock_t	*rsb,		/* in/out: summary block number */
	xfs_suminfo_t	*sum)		/* out: summary info for this block */
{
{
	xfs_buf_t	*bp;		/* buffer for the summary block */
	xfs_buf_t	*bp;		/* buffer for the summary block */
	int		error;		/* error value */
	int		error;		/* error value */
@@ -456,7 +460,7 @@ xfs_rtmodify_summary(
	/*
	/*
	 * If we have an old buffer, and the block number matches, use that.
	 * If we have an old buffer, and the block number matches, use that.
	 */
	 */
	if (rbpp && *rbpp && *rsb == sb)
	if (*rbpp && *rsb == sb)
		bp = *rbpp;
		bp = *rbpp;
	/*
	/*
	 * Otherwise we have to get the buffer.
	 * Otherwise we have to get the buffer.
@@ -465,7 +469,7 @@ xfs_rtmodify_summary(
		/*
		/*
		 * If there was an old one, get rid of it first.
		 * If there was an old one, get rid of it first.
		 */
		 */
		if (rbpp && *rbpp)
		if (*rbpp)
			xfs_trans_brelse(tp, *rbpp);
			xfs_trans_brelse(tp, *rbpp);
		error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
		error = xfs_rtbuf_get(mp, tp, sb, 1, &bp);
		if (error) {
		if (error) {
@@ -474,21 +478,38 @@ xfs_rtmodify_summary(
		/*
		/*
		 * Remember this buffer and block for the next call.
		 * Remember this buffer and block for the next call.
		 */
		 */
		if (rbpp) {
		*rbpp = bp;
		*rbpp = bp;
		*rsb = sb;
		*rsb = sb;
	}
	}
	}
	/*
	/*
	 * Point to the summary information, modify and log it.
	 * Point to the summary information, modify/log it, and/or copy it out.
	 */
	 */
	sp = XFS_SUMPTR(mp, bp, so);
	sp = XFS_SUMPTR(mp, bp, so);
	if (delta) {
		uint first = (uint)((char *)sp - (char *)bp->b_addr);

		*sp += delta;
		*sp += delta;
	xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)bp->b_addr),
		xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1);
		(uint)((char *)sp - (char *)bp->b_addr + sizeof(*sp) - 1));
	}
	if (sum)
		*sum = *sp;
	return 0;
	return 0;
}
}


int
xfs_rtmodify_summary(
	xfs_mount_t	*mp,		/* file system mount structure */
	xfs_trans_t	*tp,		/* transaction pointer */
	int		log,		/* log2 of extent size */
	xfs_rtblock_t	bbno,		/* bitmap block number */
	int		delta,		/* change to make to summary info */
	xfs_buf_t	**rbpp,		/* in/out: summary block buffer */
	xfs_fsblock_t	*rsb)		/* in/out: summary block number */
{
	return xfs_rtmodify_summary_int(mp, tp, log, bbno,
					delta, rbpp, rsb, NULL);
}

/*
/*
 * Set the given range of bitmap bits to the given value.
 * Set the given range of bitmap bits to the given value.
 * Do whatever I/O and logging is required.
 * Do whatever I/O and logging is required.
Loading