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

Commit f7ca3522 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: create a separate cow extent size hint for the allocator



Create a per-inode extent size allocator hint for copy-on-write.  This
hint is separate from the existing extent size hint so that CoW can
take advantage of the fragmentation-reducing properties of extent size
hints without disabling delalloc for regular writes.

The extent size hint that's fed to the allocator during a copy on
write operation is the greater of the cowextsize and regular extsize
hint.

During reflink, if we're sharing the entire source file to the entire
destination file and the destination file doesn't already have a
cowextsize hint, propagate the source file's cowextsize hint to the
destination file.

Furthermore, zero the bulkstat buffer prior to setting the fields
so that we don't copy kernel memory contents into userspace.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 98cc2db5
Loading
Loading
Loading
Loading
+7 −2
Original line number Original line Diff line number Diff line
@@ -3666,7 +3666,9 @@ xfs_bmap_btalloc(
	else if (mp->m_dalign)
	else if (mp->m_dalign)
		stripe_align = mp->m_dalign;
		stripe_align = mp->m_dalign;


	if (xfs_alloc_is_userdata(ap->datatype))
	if (ap->flags & XFS_BMAPI_COWFORK)
		align = xfs_get_cowextsz_hint(ap->ip);
	else if (xfs_alloc_is_userdata(ap->datatype))
		align = xfs_get_extsz_hint(ap->ip);
		align = xfs_get_extsz_hint(ap->ip);
	if (unlikely(align)) {
	if (unlikely(align)) {
		error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
		error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
@@ -4192,6 +4194,9 @@ xfs_bmapi_reserve_delalloc(
		alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);
		alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff);


	/* Figure out the extent size, adjust alen */
	/* Figure out the extent size, adjust alen */
	if (whichfork == XFS_COW_FORK)
		extsz = xfs_get_cowextsz_hint(ip);
	else
		extsz = xfs_get_extsz_hint(ip);
		extsz = xfs_get_extsz_hint(ip);
	if (extsz) {
	if (extsz) {
		error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof,
		error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof,
+2 −1
Original line number Original line Diff line number Diff line
@@ -901,7 +901,8 @@ typedef struct xfs_dinode {
	__be64		di_changecount;	/* number of attribute changes */
	__be64		di_changecount;	/* number of attribute changes */
	__be64		di_lsn;		/* flush sequence */
	__be64		di_lsn;		/* flush sequence */
	__be64		di_flags2;	/* more random flags */
	__be64		di_flags2;	/* more random flags */
	__u8		di_pad2[16];	/* more padding for future expansion */
	__be32		di_cowextsize;	/* basic cow extent size for file */
	__u8		di_pad2[12];	/* more padding for future expansion */


	/* fields only written to during inode creation */
	/* fields only written to during inode creation */
	xfs_timestamp_t	di_crtime;	/* time created */
	xfs_timestamp_t	di_crtime;	/* time created */
+2 −1
Original line number Original line Diff line number Diff line
@@ -278,7 +278,8 @@ typedef struct xfs_bstat {
#define	bs_projid	bs_projid_lo	/* (previously just bs_projid)	*/
#define	bs_projid	bs_projid_lo	/* (previously just bs_projid)	*/
	__u16		bs_forkoff;	/* inode fork offset in bytes	*/
	__u16		bs_forkoff;	/* inode fork offset in bytes	*/
	__u16		bs_projid_hi;	/* higher part of project id	*/
	__u16		bs_projid_hi;	/* higher part of project id	*/
	unsigned char	bs_pad[10];	/* pad space, unused		*/
	unsigned char	bs_pad[6];	/* pad space, unused		*/
	__u32		bs_cowextsize;	/* cow extent size		*/
	__u32		bs_dmevmask;	/* DMIG event mask		*/
	__u32		bs_dmevmask;	/* DMIG event mask		*/
	__u16		bs_dmstate;	/* DMIG state info		*/
	__u16		bs_dmstate;	/* DMIG state info		*/
	__u16		bs_aextents;	/* attribute number of extents	*/
	__u16		bs_aextents;	/* attribute number of extents	*/
+3 −1
Original line number Original line Diff line number Diff line
@@ -256,6 +256,7 @@ xfs_inode_from_disk(
		to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec);
		to->di_crtime.t_sec = be32_to_cpu(from->di_crtime.t_sec);
		to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec);
		to->di_crtime.t_nsec = be32_to_cpu(from->di_crtime.t_nsec);
		to->di_flags2 = be64_to_cpu(from->di_flags2);
		to->di_flags2 = be64_to_cpu(from->di_flags2);
		to->di_cowextsize = be32_to_cpu(from->di_cowextsize);
	}
	}
}
}


@@ -305,7 +306,7 @@ xfs_inode_to_disk(
		to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
		to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
		to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
		to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
		to->di_flags2 = cpu_to_be64(from->di_flags2);
		to->di_flags2 = cpu_to_be64(from->di_flags2);

		to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
		to->di_ino = cpu_to_be64(ip->i_ino);
		to->di_ino = cpu_to_be64(ip->i_ino);
		to->di_lsn = cpu_to_be64(lsn);
		to->di_lsn = cpu_to_be64(lsn);
		memset(to->di_pad2, 0, sizeof(to->di_pad2));
		memset(to->di_pad2, 0, sizeof(to->di_pad2));
@@ -357,6 +358,7 @@ xfs_log_dinode_to_disk(
		to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
		to->di_crtime.t_sec = cpu_to_be32(from->di_crtime.t_sec);
		to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
		to->di_crtime.t_nsec = cpu_to_be32(from->di_crtime.t_nsec);
		to->di_flags2 = cpu_to_be64(from->di_flags2);
		to->di_flags2 = cpu_to_be64(from->di_flags2);
		to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
		to->di_ino = cpu_to_be64(from->di_ino);
		to->di_ino = cpu_to_be64(from->di_ino);
		to->di_lsn = cpu_to_be64(from->di_lsn);
		to->di_lsn = cpu_to_be64(from->di_lsn);
		memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
		memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
+1 −0
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ struct xfs_icdinode {
	__uint16_t	di_flags;	/* random flags, XFS_DIFLAG_... */
	__uint16_t	di_flags;	/* random flags, XFS_DIFLAG_... */


	__uint64_t	di_flags2;	/* more random flags */
	__uint64_t	di_flags2;	/* more random flags */
	__uint32_t	di_cowextsize;	/* basic cow extent size for file */


	xfs_ictimestamp_t di_crtime;	/* time created */
	xfs_ictimestamp_t di_crtime;	/* time created */
};
};
Loading