From: Richard W.M. Jones Date: Wed, 23 Oct 2013 07:26:42 +0000 (+0100) Subject: Avoid ext4 auto_da_alloc flush on close (v2). X-Git-Url: http://git.annexia.org/?a=commitdiff_plain;h=8b88d6a25dccb0e086f3d2b1d3cab99d722912aa;p=pxzcat.git Avoid ext4 auto_da_alloc flush on close (v2). This updates commit 68640d56b2ea96401a1355ab56603b0837058d21. Don't unlink the file: As Florian Weimer pointed out, this would cause problems if someone uses '-o /dev/null' (it could delete /dev/null). Don't write a byte. The exact condition which causes the auto_da_alloc misbehaviour is truncating a file from a large size to 0 size. So this write was not necessary. Thanks: Florian Weimer, Eric Sandeen, Eric Blake. --- diff --git a/pxzcat.c b/pxzcat.c index 7e036d0..1285ed1 100644 --- a/pxzcat.c +++ b/pxzcat.c @@ -166,16 +166,21 @@ xzfile_uncompress (const char *filename, const char *outputfile, debug ("uncompressed size = %" PRIu64 " bytes", size); /* Avoid annoying ext4 auto_da_alloc which causes a flush on close - * unless we are very careful about not truncating the file when it - * has zero size. (Thanks Eric Sandeen) + * unless we are very careful about not truncating a regular file + * from non-zero size to zero size. (Thanks Eric Sandeen) */ - unlink (outputfile); - - ofd = open (outputfile, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0644); + ofd = open (outputfile, O_WRONLY|O_CREAT|O_NOCTTY, 0644); if (ofd == -1) error (EXIT_FAILURE, errno, "open: %s", outputfile); - /* See above about auto_da_alloc. */ - write (ofd, "\0", 1); + + if (ftruncate (ofd, 1) == -1) + error (EXIT_FAILURE, errno, "ftruncate (1 byte): %s", outputfile); + + if (lseek (ofd, 0, SEEK_SET) == -1) + error (EXIT_FAILURE, errno, "lseek: %s", outputfile); + + if (write (ofd, "\0", 1) == -1) + error (EXIT_FAILURE, errno, "write: %s", outputfile); if (ftruncate (ofd, size) == -1) error (EXIT_FAILURE, errno, "ftruncate: %s", outputfile);