Re: Files full of zeros with coreutils-8.11 and xfs (FIEMAP related?)

Markus Trippelsdorf
2011-04-14T16:44:51Z

On 2011.04.14 at 11:31 -0500, Eric Sandeen wrote:
> On 4/14/11 11:28 AM, Markus Trippelsdorf wrote:
>
> <snip>
>
> > Yes, but we're still trying to find out what caused the zeros in the
> > binaries that coreutils installed on my system.
> >
> > Now the failure only happens when I use "gold" as my linker. With GNU ld
> > everything is OK. But I thought this must be a timing issue, because
> > gold is faster and the binaries in coreutils-8.11/src are all fine.
>
> maybe xfs_bmap (or filefrag) of the binaries with both linkers would be instructive; are they laid out significantly differently?
>
> does gold preallocate?

Just checked and yes it does. That should explain the issue I was
seeing.

bool
Output_file::map_no_anonymous()
{
const int o = this->o_;

// If the output file is not a regular file, don't try to mmap it;
// instead, we'll mmap a block of memory (an anonymous buffer), and
// then later write the buffer to the file.
void* base;
struct stat statbuf;
if (o == STDOUT_FILENO || o == STDERR_FILENO
|| ::fstat(o, &statbuf) != 0
|| !S_ISREG(statbuf.st_mode)
|| this->is_temporary_)
return false;

// Ensure that we have disk space available for the file. If we
// don't do this, it is possible that we will call munmap, close,
// and exit with dirty buffers still in the cache with no assigned
// disk blocks. If the disk is out of space at that point, the
// output file will wind up incomplete, but we will have already
// exited. The alternative to fallocate would be to use fdatasync,
// but that would be a more significant performance hit.
if (::posix_fallocate(o, 0, this->file_size_) < 0)
gold_fatal(_("%s: %s"), this->name_, strerror(errno));

// Map the file into memory.
base = ::mmap(NULL, this->file_size_, PROT_READ | PROT_WRITE,
MAP_SHARED, o, 0);

// The mmap call might fail because of file system issues: the file
// system might not support mmap at all, or it might not support
// mmap with PROT_WRITE.
if (base == MAP_FAILED)
return false;

this->map_is_anonymous_ = false;
this->base_ = static_cast<unsigned char*>(base);
return true;
}

--
Markus