From: Darrick J. Wong <djwong@xxxxxxxxxx> Not sure why block device targets don't get O_DIRECT in !buffered mode, but it's misleading when the copy completes instantly only to stall forever due to fsync-on-close. Adjust the "write last sector" code to allocate a properly aligned buffer. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- copy/xfs_copy.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index 79f65946709..26de6b2ee1c 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -854,6 +854,8 @@ main(int argc, char **argv) progname, target[i].name, progname); exit(1); } + if (!buffered_output) + open_flags |= O_DIRECT; } target[i].fd = open(target[i].name, open_flags, 0644); @@ -887,20 +889,22 @@ main(int argc, char **argv) } } } else { - char *lb[XFS_MAX_SECTORSIZE] = { NULL }; + char *lb = memalign(wbuf_align, XFS_MAX_SECTORSIZE); off64_t off; /* ensure device files are sufficiently large */ + memset(lb, 0, XFS_MAX_SECTORSIZE); off = mp->m_sb.sb_dblocks * source_blocksize; - off -= sizeof(lb); - if (pwrite(target[i].fd, lb, sizeof(lb), off) < 0) { + off -= XFS_MAX_SECTORSIZE; + if (pwrite(target[i].fd, lb, XFS_MAX_SECTORSIZE, off) < 0) { do_log(_("%s: failed to write last block\n"), progname); do_log(_("\tIs target \"%s\" too small?\n"), target[i].name); die_perror(); } + free(lb); } }