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

Commit 155cd433 authored by Dave Chinner's avatar Dave Chinner
Browse files

Merge branch 'xfs-4.9-log-recovery-fixes' into for-next

parents a1f45e66 5cd9cee9
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -258,7 +258,7 @@ xfs_alloc_compute_diff(
	xfs_agblock_t	wantbno,	/* target starting block */
	xfs_extlen_t	wantlen,	/* target length */
	xfs_extlen_t	alignment,	/* target alignment */
	char		userdata,	/* are we allocating data? */
	int		datatype,	/* are we allocating data? */
	xfs_agblock_t	freebno,	/* freespace's starting block */
	xfs_extlen_t	freelen,	/* freespace's length */
	xfs_agblock_t	*newbnop)	/* result: best start block from free */
@@ -269,6 +269,7 @@ xfs_alloc_compute_diff(
	xfs_extlen_t	newlen1=0;	/* length with newbno1 */
	xfs_extlen_t	newlen2=0;	/* length with newbno2 */
	xfs_agblock_t	wantend;	/* end of target extent */
	bool		userdata = xfs_alloc_is_userdata(datatype);

	ASSERT(freelen >= wantlen);
	freeend = freebno + freelen;
@@ -924,7 +925,7 @@ xfs_alloc_find_best_extent(

			sdiff = xfs_alloc_compute_diff(args->agbno, args->len,
						       args->alignment,
						       args->userdata, *sbnoa,
						       args->datatype, *sbnoa,
						       *slena, &new);

			/*
@@ -1108,7 +1109,7 @@ xfs_alloc_ag_vextent_near(
			if (args->len < blen)
				continue;
			ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
				args->alignment, args->userdata, ltbnoa,
				args->alignment, args->datatype, ltbnoa,
				ltlena, &ltnew);
			if (ltnew != NULLAGBLOCK &&
			    (args->len > blen || ltdiff < bdiff)) {
@@ -1261,7 +1262,7 @@ xfs_alloc_ag_vextent_near(
			args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
			xfs_alloc_fix_len(args);
			ltdiff = xfs_alloc_compute_diff(args->agbno, args->len,
				args->alignment, args->userdata, ltbnoa,
				args->alignment, args->datatype, ltbnoa,
				ltlena, &ltnew);

			error = xfs_alloc_find_best_extent(args,
@@ -1278,7 +1279,7 @@ xfs_alloc_ag_vextent_near(
			args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen);
			xfs_alloc_fix_len(args);
			gtdiff = xfs_alloc_compute_diff(args->agbno, args->len,
				args->alignment, args->userdata, gtbnoa,
				args->alignment, args->datatype, gtbnoa,
				gtlena, &gtnew);

			error = xfs_alloc_find_best_extent(args,
@@ -1338,7 +1339,7 @@ xfs_alloc_ag_vextent_near(
	}
	rlen = args->len;
	(void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
				     args->userdata, ltbnoa, ltlena, &ltnew);
				     args->datatype, ltbnoa, ltlena, &ltnew);
	ASSERT(ltnew >= ltbno);
	ASSERT(ltnew + rlen <= ltbnoa + ltlena);
	ASSERT(ltnew + rlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
@@ -1617,9 +1618,9 @@ xfs_alloc_ag_vextent_small(
			goto error0;
		if (fbno != NULLAGBLOCK) {
			xfs_extent_busy_reuse(args->mp, args->agno, fbno, 1,
					     args->userdata);
			      xfs_alloc_allow_busy_reuse(args->datatype));

			if (args->userdata) {
			if (xfs_alloc_is_userdata(args->datatype)) {
				xfs_buf_t	*bp;

				bp = xfs_btree_get_bufs(args->mp, args->tp,
@@ -2099,7 +2100,7 @@ xfs_alloc_fix_freelist(
	 * somewhere else if we are not being asked to try harder at this
	 * point
	 */
	if (pag->pagf_metadata && args->userdata &&
	if (pag->pagf_metadata && xfs_alloc_is_userdata(args->datatype) &&
	    (flags & XFS_ALLOC_FLAG_TRYLOCK)) {
		ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
		goto out_agbp_relse;
@@ -2675,7 +2676,7 @@ xfs_alloc_vextent(
		 * Try near allocation first, then anywhere-in-ag after
		 * the first a.g. fails.
		 */
		if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) &&
		if ((args->datatype & XFS_ALLOC_INITIAL_USER_DATA) &&
		    (mp->m_flags & XFS_MOUNT_32BITINODES)) {
			args->fsbno = XFS_AGB_TO_FSB(mp,
					((mp->m_agfrotor / rotorstep) %
@@ -2808,7 +2809,7 @@ xfs_alloc_vextent(
#endif

		/* Zero the extent if we were asked to do so */
		if (args->userdata & XFS_ALLOC_USERDATA_ZERO) {
		if (args->datatype & XFS_ALLOC_USERDATA_ZERO) {
			error = xfs_zero_extent(args->ip, args->fsbno, args->len);
			if (error)
				goto error0;
+15 −2
Original line number Diff line number Diff line
@@ -85,20 +85,33 @@ typedef struct xfs_alloc_arg {
	xfs_extlen_t	len;		/* output: actual size of extent */
	xfs_alloctype_t	type;		/* allocation type XFS_ALLOCTYPE_... */
	xfs_alloctype_t	otype;		/* original allocation type */
	int		datatype;	/* mask defining data type treatment */
	char		wasdel;		/* set if allocation was prev delayed */
	char		wasfromfl;	/* set if allocation is from freelist */
	char		userdata;	/* mask defining userdata treatment */
	xfs_fsblock_t	firstblock;	/* io first block allocated */
	struct xfs_owner_info	oinfo;	/* owner of blocks being allocated */
	enum xfs_ag_resv_type	resv;	/* block reservation to use */
} xfs_alloc_arg_t;

/*
 * Defines for userdata
 * Defines for datatype
 */
#define XFS_ALLOC_USERDATA		(1 << 0)/* allocation is for user data*/
#define XFS_ALLOC_INITIAL_USER_DATA	(1 << 1)/* special case start of file */
#define XFS_ALLOC_USERDATA_ZERO		(1 << 2)/* zero extent on allocation */
#define XFS_ALLOC_NOBUSY		(1 << 3)/* Busy extents not allowed */

static inline bool
xfs_alloc_is_userdata(int datatype)
{
	return (datatype & ~XFS_ALLOC_NOBUSY) != 0;
}

static inline bool
xfs_alloc_allow_busy_reuse(int datatype)
{
	return (datatype & XFS_ALLOC_NOBUSY) == 0;
}

/* freespace limit calculations */
#define XFS_ALLOC_AGFL_RESERVE	4
+26 −15
Original line number Diff line number Diff line
@@ -3348,7 +3348,8 @@ xfs_bmap_adjacent(

	mp = ap->ip->i_mount;
	nullfb = *ap->firstblock == NULLFSBLOCK;
	rt = XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata;
	rt = XFS_IS_REALTIME_INODE(ap->ip) &&
		xfs_alloc_is_userdata(ap->datatype);
	fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
	/*
	 * If allocating at eof, and there's a previous real block,
@@ -3624,7 +3625,7 @@ xfs_bmap_btalloc(
{
	xfs_mount_t	*mp;		/* mount point structure */
	xfs_alloctype_t	atype = 0;	/* type for allocation routines */
	xfs_extlen_t	align;		/* minimum allocation alignment */
	xfs_extlen_t	align = 0;	/* minimum allocation alignment */
	xfs_agnumber_t	fb_agno;	/* ag number of ap->firstblock */
	xfs_agnumber_t	ag;
	xfs_alloc_arg_t	args;
@@ -3647,7 +3648,8 @@ xfs_bmap_btalloc(
	else if (mp->m_dalign)
		stripe_align = mp->m_dalign;

	align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0;
	if (xfs_alloc_is_userdata(ap->datatype))
		align = xfs_get_extsz_hint(ap->ip);
	if (unlikely(align)) {
		error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
						align, 0, ap->eof, 0, ap->conv,
@@ -3660,7 +3662,8 @@ xfs_bmap_btalloc(
	nullfb = *ap->firstblock == NULLFSBLOCK;
	fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
	if (nullfb) {
		if (ap->userdata && xfs_inode_is_filestream(ap->ip)) {
		if (xfs_alloc_is_userdata(ap->datatype) &&
		    xfs_inode_is_filestream(ap->ip)) {
			ag = xfs_filestream_lookup_ag(ap->ip);
			ag = (ag != NULLAGNUMBER) ? ag : 0;
			ap->blkno = XFS_AGB_TO_FSB(mp, ag, 0);
@@ -3700,7 +3703,8 @@ xfs_bmap_btalloc(
		 * enough for the request.  If one isn't found, then adjust
		 * the minimum allocation size to the largest space found.
		 */
		if (ap->userdata && xfs_inode_is_filestream(ap->ip))
		if (xfs_alloc_is_userdata(ap->datatype) &&
		    xfs_inode_is_filestream(ap->ip))
			error = xfs_bmap_btalloc_filestreams(ap, &args, &blen);
		else
			error = xfs_bmap_btalloc_nullfb(ap, &args, &blen);
@@ -3784,8 +3788,8 @@ xfs_bmap_btalloc(
	args.minleft = ap->minleft;
	args.wasdel = ap->wasdel;
	args.resv = XFS_AG_RESV_NONE;
	args.userdata = ap->userdata;
	if (ap->userdata & XFS_ALLOC_USERDATA_ZERO)
	args.datatype = ap->datatype;
	if (ap->datatype & XFS_ALLOC_USERDATA_ZERO)
		args.ip = ap->ip;

	error = xfs_alloc_vextent(&args);
@@ -3879,7 +3883,8 @@ STATIC int
xfs_bmap_alloc(
	struct xfs_bmalloca	*ap)	/* bmap alloc argument struct */
{
	if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata)
	if (XFS_IS_REALTIME_INODE(ap->ip) &&
	    xfs_alloc_is_userdata(ap->datatype))
		return xfs_bmap_rtalloc(ap);
	return xfs_bmap_btalloc(ap);
}
@@ -4204,15 +4209,21 @@ xfs_bmapi_allocate(
	}

	/*
	 * Indicate if this is the first user data in the file, or just any
	 * user data. And if it is userdata, indicate whether it needs to
	 * be initialised to zero during allocation.
	 * Set the data type being allocated. For the data fork, the first data
	 * in the file is treated differently to all other allocations. For the
	 * attribute fork, we only need to ensure the allocated range is not on
	 * the busy list.
	 */
	if (!(bma->flags & XFS_BMAPI_METADATA)) {
		bma->userdata = (bma->offset == 0) ?
			XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA;
		bma->datatype = XFS_ALLOC_NOBUSY;
		if (whichfork == XFS_DATA_FORK) {
			if (bma->offset == 0)
				bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA;
			else
				bma->datatype |= XFS_ALLOC_USERDATA;
		}
		if (bma->flags & XFS_BMAPI_ZERO)
			bma->userdata |= XFS_ALLOC_USERDATA_ZERO;
			bma->datatype |= XFS_ALLOC_USERDATA_ZERO;
	}

	bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1;
@@ -4482,7 +4493,7 @@ xfs_bmapi_write(
	bma.tp = tp;
	bma.ip = ip;
	bma.total = total;
	bma.userdata = 0;
	bma.datatype = 0;
	bma.dfops = dfops;
	bma.firstblock = firstblock;

+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ struct xfs_bmalloca {
	bool			wasdel;	/* replacing a delayed allocation */
	bool			aeof;	/* allocated space at eof */
	bool			conv;	/* overwriting unwritten extents */
	char			userdata;/* userdata mask */
	int			datatype;/* data type being allocated */
	int			flags;
};

+1 −1
Original line number Diff line number Diff line
@@ -182,7 +182,7 @@ xfs_bmap_rtalloc(
					XFS_TRANS_DQ_RTBCOUNT, (long) ralen);

		/* Zero the extent if we were asked to do so */
		if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) {
		if (ap->datatype & XFS_ALLOC_USERDATA_ZERO) {
			error = xfs_zero_extent(ap->ip, ap->blkno, ap->length);
			if (error)
				return error;
Loading