diff options
Diffstat (limited to 'fs/xfs/libxfs')
| -rw-r--r-- | fs/xfs/libxfs/xfs_ag_resv.c | 12 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 8 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 32 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.h | 1 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_cksum.h | 1 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 4 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_log_format.h | 27 | 
7 files changed, 45 insertions, 40 deletions
| diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c index b008ff3250eb..df3e600835e8 100644 --- a/fs/xfs/libxfs/xfs_ag_resv.c +++ b/fs/xfs/libxfs/xfs_ag_resv.c @@ -156,7 +156,8 @@ __xfs_ag_resv_free(  	trace_xfs_ag_resv_free(pag, type, 0);  	resv = xfs_perag_resv(pag, type); -	pag->pag_mount->m_ag_max_usable += resv->ar_asked; +	if (pag->pag_agno == 0) +		pag->pag_mount->m_ag_max_usable += resv->ar_asked;  	/*  	 * AGFL blocks are always considered "free", so whatever  	 * was reserved at mount time must be given back at umount. @@ -216,7 +217,14 @@ __xfs_ag_resv_init(  		return error;  	} -	mp->m_ag_max_usable -= ask; +	/* +	 * Reduce the maximum per-AG allocation length by however much we're +	 * trying to reserve for an AG.  Since this is a filesystem-wide +	 * counter, we only make the adjustment for AG 0.  This assumes that +	 * there aren't any AGs hungrier for per-AG reservation than AG 0. +	 */ +	if (pag->pag_agno == 0) +		mp->m_ag_max_usable -= ask;  	resv = xfs_perag_resv(pag, type);  	resv->ar_asked = ask; diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 744dcaec34cc..f965ce832bc0 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -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);  	} diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 459f4b4f08fe..89263797cf32 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -49,7 +49,6 @@  #include "xfs_rmap.h"  #include "xfs_ag_resv.h"  #include "xfs_refcount.h" -#include "xfs_rmap_btree.h"  #include "xfs_icache.h" @@ -192,12 +191,8 @@ xfs_bmap_worst_indlen(  	int		maxrecs;	/* maximum record count at this level */  	xfs_mount_t	*mp;		/* mount structure */  	xfs_filblks_t	rval;		/* return value */ -	xfs_filblks_t   orig_len;  	mp = ip->i_mount; - -	/* Calculate the worst-case size of the bmbt. */ -	orig_len = len;  	maxrecs = mp->m_bmap_dmxr[0];  	for (level = 0, rval = 0;  	     level < XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK); @@ -205,20 +200,12 @@ xfs_bmap_worst_indlen(  		len += maxrecs - 1;  		do_div(len, maxrecs);  		rval += len; -		if (len == 1) { -			rval += XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - +		if (len == 1) +			return rval + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) -  				level - 1; -			break; -		}  		if (level == 0)  			maxrecs = mp->m_bmap_dmxr[1];  	} - -	/* Calculate the worst-case size of the rmapbt. */ -	if (xfs_sb_version_hasrmapbt(&mp->m_sb)) -		rval += 1 + xfs_rmapbt_calc_size(mp, orig_len) + -				mp->m_rmap_maxlevels; -  	return rval;  } @@ -1490,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;  	} @@ -3865,6 +3852,17 @@ xfs_trim_extent(  	}  } +/* trim extent to within eof */ +void +xfs_trim_extent_eof( +	struct xfs_bmbt_irec	*irec, +	struct xfs_inode	*ip) + +{ +	xfs_trim_extent(irec, 0, XFS_B_TO_FSB(ip->i_mount, +					      i_size_read(VFS_I(ip)))); +} +  /*   * Trim the returned map to the required bounds   */ diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 851982a5dfbc..502e0d8fb4ff 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -208,6 +208,7 @@ void	xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt,  void	xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno,  		xfs_filblks_t len); +void	xfs_trim_extent_eof(struct xfs_bmbt_irec *, struct xfs_inode *);  int	xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);  void	xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork);  void	xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_defer_ops *dfops, diff --git a/fs/xfs/libxfs/xfs_cksum.h b/fs/xfs/libxfs/xfs_cksum.h index 8211f48b98e6..999a290cfd72 100644 --- a/fs/xfs/libxfs/xfs_cksum.h +++ b/fs/xfs/libxfs/xfs_cksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef _XFS_CKSUM_H  #define _XFS_CKSUM_H 1 diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 988bb3f31446..dfd643909f85 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -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) { diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h index 8372e9bcd7b6..71de185735e0 100644 --- a/fs/xfs/libxfs/xfs_log_format.h +++ b/fs/xfs/libxfs/xfs_log_format.h @@ -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));  /* |