[Gluster-devel] FIRST_CHILD(frame->this)->fops->create

Ian Latter ian.latter at midnightcode.org
Tue Aug 4 15:22:20 UTC 2009


  A friend and I nutted out the logic for a new module for 
GlusterFS about 10 days ago, and while the idea was simple
enough, it seems that I've spent more than a fair amount of 
time grappling with the GlusterFS internal framework to get it 

  My problem seems to start with the idea of performing
fops without the requesting (parent) layer driving them. 
I.e. a 
user works with a file on my brick, and I want to;

 1) manipulate the data on the existing file descriptor 
     (my_xlator->write = no problems there, and
      FIRST_CHILD(frame->this)->fops->write = no probs 
      there either)

 2) create a sub-directory or two 
     (FIRST_CHILD(frame->this)->fops->mkdir = 
      no problems there)

 3) create a new private meta-data file
     (FIRST_CHILD(frame->this)->fops->create = FAIL)

And this seems to be a serious sticking place.  I've
worked through all of the previous hiccups via examples
that I've found in the existing code base - but there is
no example of a child->create, and I'm not familiar enough
with either the Gluster internals, or the low level FS 
interface to work through it.

My child->create outcomes vary from hanging to outright 
crashes of the glusterfsd (if I use "fd_create()" to
an fd).  In the hanging cases the file is created, with the
mode, but Gluster never hands off to my Callback routine.  In 
the crash cases I don't see the file created - and in some of
those crash cases I can get an "invalid fd" from the underlying
posix layer.

Is there anyone able to provide some advice or an example
of a functional non-parent driven child->create fop (i.e. a 
"create" on a non create event handler, with a new fd)?

Example code for the "hang" case, from my prototype (inside
a function called from inside the xlator->write handler);

        loc_t data_loc;
        char path[255];
        char name[255];
        char * data_path;
        char * data_name;
        int32_t flags;
        mode_t mode;
        fd_t * fd;

        memset(path, 0, sizeof(path));
        if(snprintf(path, sizeof(path) - 1, "/data.db") <= 0)
          return -1;

        memset(name, 0, sizeof(name));
        if(snprintf(name, sizeof(name) - 1, "data.db") <= 0)
          return -1;

        data_path = CALLOC(1, strlen(path) + 1);
        memset(data_path, 0, sizeof(data_path));
        memcpy(data_path, path, strlen(path));

        data_name = CALLOC(1, strlen(name) + 1);
        memset(data_name, 0, sizeof(data_name));
        memcpy(data_name, name, strlen(name));

        memset(&data_loc, 0, sizeof(data_loc));
        data_loc.inode = NULL;  // redundant
        data_loc.path = data_path;
        data_loc.name = data_name;

        flags = O_CREAT | O_RDWR | O_EXCL;

        mode = (mode_t)0700;

        memset(fd, 0, sizeof(fd_t));

                    &data_loc, flags, mode, &fd);

        gf_log(this->name, GF_LOG_WARNING, "Hung above me");


Ian Latter
Late night coder ..

More information about the Gluster-devel mailing list