All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tao Ma <tao.ma@oracle.com>
To: Eric Sandeen <sandeen@redhat.com>
Cc: linux-ext4@vger.kernel.org, Theodore Tso <tytso@mit.edu>,
	linux-kernel@vger.kernel.org
Subject: Re: fiemap is broken for sparse file in ext4?
Date: Fri, 11 Jun 2010 13:05:32 +0800	[thread overview]
Message-ID: <4C11C41C.9070000@oracle.com> (raw)
In-Reply-To: <4C11B6D8.8070909@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1702 bytes --]

Hi Eric,
	Thanks for the quick response.

On 06/11/2010 12:08 PM, Eric Sandeen wrote:
> Tao Ma wrote:
>> Hi Ted and other ext4 gurus,
>>      I found fiemap may be broken for sparse files in ext4. Here is a
>> simple example.
>>
>> dd if=/dev/zero of=testfile1 bs=1M count=1
>> using fiemap shows that it has a delalloc extent.
>> Logical: 0 Ext length: 1048576    Physical: 0    flags: 7
>>
>> flags 7 means FIEMAP_EXTENT_LAST, FIEMAP_EXTENT_UNKNOWN and
>> FIEMAP_EXTENT_DELALLOC,
>>
>> while if we create a sparse file, fiemap will not show the delalloc extent.
>> dd if=/dev/zero of=testfile1 bs=1M count=1 seek=1
>> using fiemap shows that it has no extent for the file. while we should
>> have some output like:
>> Logical: 1048576 Ext length: 1048576    Physical: 0    flags: 7
>>
>> So we have different output with sparse and non-sparse file. Is it a bug
>> for ext4?
>
> What are you using to call fiemap?  Here it seems to be working:
I just wrote a simple test program by calling ioctl. It is attached. 
btw, you need to call it immediately after dd so that we have a chance 
that ext4 don't have time to allocate extents. ;)
>
> # dd if=/dev/zero of=testfile1 bs=1M count=1 seek=1;
>
> # filefrag -v testfile1
> Filesystem type is: ef53
> Filesystem cylinder groups is approximately 119
> File size of testfile1 is 2097152 (512 blocks, blocksize 4096)
>   ext logical physical expected length flags
>     0     256   151946               1 merged
>     1     257   151951   151946      2 merged
>     2     259   152434   151952    253 merged,eof
> testfile1: 4 extents found
I guess maybe filefrag use the diffrent ioctl flag, maybe 
FIEMAP_FLAG_SYNC to let ext4 sync first.

Regards,
Tao

[-- Attachment #2: fiemap.c --]
[-- Type: text/x-csrc, Size: 2751 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>

#include "fiemap.h"

#define FS_IOC_FIEMAP	_IOWR('f', 11, struct fiemap)

static unsigned int num_extents	= 1024;
static unsigned int estimate_extents = 1;

static unsigned long long map_start = 0ULL;
static unsigned long long map_len = FIEMAP_MAX_OFFSET;
static char *fname;
static unsigned int blocksize = 4096;

static void usage(void)
{
	printf("Usage: fiemap filename\n");
	exit(1);
}

static void print_extent(struct fiemap_extent *extent)
{
	__u64 val;

	printf("Logical: ###[%8"PRIu64"]\t", extent->fe_logical);
	printf("Ext length: ###[%8"PRIu64"]\t", extent->fe_length);
	printf("Physical: ###[%8"PRIu64"]\t", extent->fe_physical);
	printf("flags: %u\t", extent->fe_flags);

	if (extent->fe_flags & FIEMAP_EXTENT_SHARED)
		printf("Yeah, found an shared extent\n");
	if (extent->fe_flags & FIEMAP_EXTENT_UNWRITTEN)
		printf("Yeah, you are hole?\n");

	printf("\n");
}

static void show_results(struct fiemap *fiemap)
{
	int i;

	printf("Extents returned: %u\n", fiemap->fm_mapped_extents);
	if (fiemap->fm_extent_count == 0 || fiemap->fm_mapped_extents == 0)
		return;

	for (i = 0; i < fiemap->fm_mapped_extents; i++)
		print_extent(&fiemap->fm_extents[i]);

}

static int
figure_extents(int fd, unsigned int *num)
{
	int ret;
	struct fiemap fiemap = { 0, };

	fiemap.fm_start = map_start;
	fiemap.fm_length = map_len;
	fiemap.fm_flags = 0;

	ret = ioctl(fd, FS_IOC_FIEMAP, &fiemap);
	if (ret == -1) {
		fprintf(stderr, "fiemap get count error %d: \"%s\"\n", errno,
			strerror(errno));
		return -1;
	}

	*num = fiemap.fm_mapped_extents;

	return 0;
}

int
main(int argc, char **argv)
{
	int ret, fd;
	struct fiemap *fiemap;

	fd = open(argv[1], O_RDONLY);
	if (fd == -1) {
		fprintf(stderr, "open error %d: \"%s\"\n", errno,
			strerror(errno));
		return -1;
	}

	if (figure_extents(fd, &num_extents))
		return -1;

	printf("Extents in file \"%s\":    %u\n", argv[1], num_extents);

	fiemap = malloc(sizeof(fiemap) +
			num_extents * sizeof(struct fiemap_extent));
	if (fiemap == NULL) {
		fprintf(stderr, "malloc error %d: \"%s\"\n", errno,
			strerror(errno));
		return -1;
	}

	fiemap->fm_start = map_start;
	fiemap->fm_length = map_len;
	fiemap->fm_extent_count = num_extents;

	ret = ioctl(fd, FS_IOC_FIEMAP, fiemap);
	if (ret == -1) {
		if (errno == EBADR) {
			fprintf(stderr, "Kernel does not support the flags: 0x%x\n",
				fiemap->fm_flags);
			return -1;
		}
		fprintf(stderr, "fiemap error %d: \"%s\"\n", errno,
			strerror(errno));
		return -1;
	}

	show_results(fiemap);

	close(fd);

	return 0;
}

  reply	other threads:[~2010-06-11  5:06 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-11  2:15 fiemap is broken for sparse file in ext4? Tao Ma
2010-06-11  4:08 ` Eric Sandeen
2010-06-11  5:05   ` Tao Ma [this message]
2010-06-11 13:43     ` Eric Sandeen
2010-06-11 15:46     ` Eric Sandeen
2010-06-11 16:46       ` Greg Freemyer
2010-06-11 16:46         ` Greg Freemyer
2010-06-11 16:56         ` Eric Sandeen
2010-06-11 23:46           ` Tao Ma
2010-06-11 23:55             ` Eric Sandeen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C11C41C.9070000@oracle.com \
    --to=tao.ma@oracle.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sandeen@redhat.com \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.