linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Xiang Wang <xiangw@google.com>
To: Eric Sandeen <sandeen@redhat.com>
Cc: Curt Wohlgemuth <curtw@google.com>, linux-ext4@vger.kernel.org
Subject: Re: Using O_DIRECT in ext4
Date: Tue, 21 Jul 2009 13:46:24 -0700	[thread overview]
Message-ID: <d5ca277e0907211346u65282484ye6ee5da38c1b9d71@mail.gmail.com> (raw)
In-Reply-To: <4A65EEF3.9090507@redhat.com>

On Tue, Jul 21, 2009 at 9:38 AM, Eric Sandeen<sandeen@redhat.com> wrote:
> Curt Wohlgemuth wrote:
>> On Mon, Jul 20, 2009 at 8:41 PM, Eric Sandeen<sandeen@redhat.com> wrote:
>>> Xiang Wang wrote:
>
>>>> For comparison, I did the same experiment on an ext2 partition,
>>>> resulting in each file having only 1 extent.
>>> Interestinng, not sure I would have expected that.
>>
>> Same with us; we're looking into more variables to understand it.
>
> To be more clear, I would not have expected ext2 to deal well with it
> either, is more what I meant ;)  I'm not terribly surprised that ext4
> gets fragmented.
>
> For the numbers posted, how big were the files (how many 1m chunks were
> written?)
>
> Just FWIW; I did something like:
>
> # for I in `seq 1 16`; do dd if=/dev/zero of=testfile$I bs=1M count=16
> oflag=direct & done
>
> on a rhel5.4 beta kernel and got:
>
> ~5 extents per file on ext4 (per filefrag output)
> between 41 and 234 extents on ext2.
> ~6 extents per file on ext3.
> ~16 extents per file on xfs
>

I repeated this test(bs=1M count=16) by tuning some parameters in my
test program. And I got the following results(per filefrag output):
ext4:
5 extents per file

ext2:
file0: 5 extents found, perfection would be 1 extent
file1: 5 extents found, perfection would be 1 extent
file2: 6 extents found, perfection would be 1 extent
file3: 4 extents found, perfection would be 1 extent
file4: 4 extents found, perfection would be 1 extent
file5: 6 extents found, perfection would be 1 extent
file6: 4 extents found, perfection would be 1 extent
file7: 5 extents found, perfection would be 1 extent
file8: 6 extents found, perfection would be 1 extent
file9: 4 extents found, perfection would be 1 extent
file10: 5 extents found, perfection would be 1 extent
file11: 6 extents found, perfection would be 1 extent
file12: 6 extents found, perfection would be 1 extent
file13: 8 extents found, perfection would be 1 extent
file14: 4 extents found, perfection would be 1 extent
file15: 7 extents found, perfection would be 1 extent

The results on ext4 look comparable to yours while the results on ext2
look very different.
I am attaching the test program I use in case you want to try it. It
is at the end of the message.
I invoked it like: ./mt_writes 16 1 to have 16 threads writing using O_DIRECT.

> if I created a subdir for each file:
>
> # for I in `seq 1 16`; do mkdir dir$I; dd if=/dev/zero
> of=dir$I/testfile$I bs=1M count=16 oflag=direct & done
>
> ~5 extents per file on ext4
> 1 or 2 extents per file on ext2
> 1 or 2 extents per file on ext3
> ~16 extents per file on xfs.
>
> -Eric
>

======
/*
 * mt_write.c -- multiple threads extending files concurrently.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <sys/stat.h>
#include <fcntl.h>

#define _XOPEN_SOURCE 600
#define O_DIRECT        00040000        /* direct disk access hint */

#define MAX_THREAD 1000
#define BUFSIZE 1048576
#define COUNT 16

typedef struct {
        int id;
        int odirect;
} parm;

void *expand(void *arg)
{
        char *buf;
        char fname[16];
        int fd;
        int i, count;
        parm *p = (parm *)arg;

        // O_DIRECT needs to work with aligned memory
        if (posix_memalign((void *) &buf, 512, BUFSIZE) != 0) {
                fprintf(stderr, "cannot allocate aligned mem!\n");
                return NULL;
        }

        sprintf(fname, "file%d", p->id);
        if (p->odirect)
                fd = open(fname, O_RDWR|O_CREAT|O_APPEND|O_DIRECT);
        else
                fd = open(fname, O_RDWR|O_CREAT|O_APPEND);

        if (fd == -1) {
                fprintf(stderr, "Open %s failed!\n", fname);
                return NULL;
        }

        for(i = 0; i < COUNT; i++) {
                count = write(fd, buf, BUFSIZE);
                if (count == -1) {
                        fprintf(stderr, "Only able to finish %d blocks
of data\n", i);
                        return NULL;
                }
        }

        if (!p->odirect) {
                fsync(fd);
        }
        printf("Done with writing %d blocks of data\n", COUNT);
        close(fd);
        free(buf);
        return NULL;
}

int main(int argc, char* argv[]) {
        int n,i, odirect;
        pthread_t *threads;
        pthread_attr_t pthread_custom_attr;
        parm *p;

        if (argc != 3)
        {
                printf ("Usage: %s <# of threads> <O_DIRECT? 1:0>\n",argv[0]);
                exit(1);
        }

        n=atoi(argv[1]);
        odirect = atoi(argv[2]);

        if ((n < 1) || (n > MAX_THREAD))
        {
                printf ("The # of thread should between 1 and
%d.\n",MAX_THREAD);
                exit(1);
        }

        threads=(pthread_t *)malloc(n*sizeof(*threads));
        pthread_attr_init(&pthread_custom_attr);

        p=(parm *)malloc(sizeof(parm)*n);
        /* Start up thread */
        for (i = 0; i < n; i++)
        {
                p[i].id = i;
                p[i].odirect = odirect;
                pthread_create(&threads[i], &pthread_custom_attr,
expand, (void *)(p+i));
        }

        /* Synchronize the completion of each thread. */

        for (i=0; i<n; i++)
        {
                pthread_join(threads[i],NULL);
        }
        free(p);
        return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2009-07-21 20:46 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-21  1:41 Using O_DIRECT in ext4 Xiang Wang
2009-07-21  3:41 ` Eric Sandeen
2009-07-21 14:45   ` Curt Wohlgemuth
2009-07-21 16:38     ` Eric Sandeen
2009-07-21 20:46       ` Xiang Wang [this message]
2009-07-21 21:08       ` Frank Mayhar
2009-07-21 23:46         ` Mingming Cao

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=d5ca277e0907211346u65282484ye6ee5da38c1b9d71@mail.gmail.com \
    --to=xiangw@google.com \
    --cc=curtw@google.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=sandeen@redhat.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).