[Gluster-devel] FIRST_CHILD(frame->this)->fops->create
Anand Avati
avati at gluster.com
Fri Aug 7 06:19:39 UTC 2009
> my function;
> itable = (inode_table_t *)this->itable;
>
> // Skipping string code ..
> // The test case outcomes are;
> // data_path = "/"
> // data_name = "file.txt"
> // data_path_name = "/file.txt"
> // The production case outcomes are;
> // data_path = "/a/b/c/d"
> // data_name = "file.txt"
> // data_path_name = "/a/b/c/d/file.txt"
>
> data_loc.inode = inode_new(itable);
> data_loc.parent = inode_from_path(itable, data_path);
> data_loc.path = data_path_name;
> data_loc.name = data_name;
>
> fd = fd_create(data_loc.inode, frame->root->pid);
>
> flags = O_CREAT | O_RDWR | O_EXCL;
> mode = (mode_t)0700;
> fd->flags = flags;
> fd = fd_ref(fd); // not sure about this yet, haven't
> looked it up
>
> // STACK_WIND(child->fops->create)
> // With: &data_loc, flags, mode, fd
The above stuff looks alright
> init;
> this->itable = inode_table_new(0, this);
>
> I have a problem, however. My inode table looks to be a
> private/local inode table, which doesn't make sense. And
> per my expectation, if I try to child->create to a directory
> that
> is outside of the root directory (i.e. parent path = "/"),
> or that
> I didn't create in this session (i.e. killall glusterfsd;
> mkdir -p /gluster-test-mount/a/b/c/d"; glusterfsd;) the
> inode_from_path function fails to recover an inode for that
> parent path (because it isn't in my local table).
>
> I tried to get myself access to a "real" inode table, per the
> trace source, with the following in init;
>
> this->itable = FIRST_CHILD(this)->itable;
>
>
> However, that itable is null in my case (glusterfs-2.0.2,
> child
> brick is a single locks brick, on a single posix brick,
> running on
> Linux).
For reasons explained further below, it is not "right" to create your
inodes from a globally-reachable inode table (which does not exist
anyway). Almost all the time, you would be creating these new
files/directories in the context of a particular call, or have it
triggered by a similar call. So most of the times, the right inode
table should be taken from loc->inode->itable, or fd->inode->itable
according to the particular fop in picture.
> The only xlator that looks like it may initialise a global
> inode
> table is the server xlater. In server-protocol.c there is a
> "mop_setvolume" that contains the following initialiser;
>
> if ((conn->bound_xl != NULL) &&
> (ret >= 0) &&
> (conn->bound_xl->itable == NULL)) {
>
> /* create inode table for this bound_xl, if one doesn't
> already exist */
> lru_limit = INODE_LRU_LIMIT (frame->this);
>
> gf_log (trans->xl->name, GF_LOG_TRACE,
> "creating inode table with lru_limit=%"PRId32", "
> "xlator=%s", lru_limit, conn->bound_xl->name);
>
> conn->bound_xl->itable =
> inode_table_new (lru_limit, conn->bound_xl);
> }
>
>
> However, I'm not clear on what mops are for, or how
> they're used. I can see that a mop is a "Management
> OPeration", but what is setvolume intended to do? And
> when is it called? If this is an initalising routine, then why
> couldn't this code be in init? (and if it can, then what am
> I doing wrong with my current initialiser, which is the
> same one used in the fuse mount xlator's init function?)
There is a reason why just a few @this have itable while others do
not. On the client side, only the fuse's @this has a proper itable
initialized at mount time. On the server side, each subvolume of
protcol/server has a different itable of its own. Since two posix
exports from a single backend cannot share the same itable, each of
their itable is stored in their respective @this structures. And this
itable is initialized only when the first client attaches to this as
its remote-subvolume (i.e, during the setvolume MOP, which is the
handshake + authentication).
Thanks,
Avati
More information about the Gluster-devel
mailing list