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

Ian Latter ian.latter at midnightcode.org
Mon Aug 10 17:08:44 UTC 2009



Hello Avati,


  In the write fop, I have an fd.  That fd->inode->table does
exist (is not null) but does not contain references to
directories 
that I had previously created on that volume (prior to a 
glusterfsd restart, for example).  I am attempting to dump all 
contents of that inode table to see what it does contain .. but 
I'm out of time again this evening.

  One other quick test has shown that mop->setvolume is 
not being called on my xlator.  So there is no alternative 
avenue there.


  I guess the question is - Is this the best path for attempting
to create/read/write/remove files in an autonomous 
management function (i.e. event driven, but without user/
upper level control over the target file/path)?  I am only at 
this juncture because to create a file required a new inode 
and inode data of the parent.  Is there another way to create
a file in GlusterFS?  I.e. can I get into the context of the
child and then perform an open() call (as opposed to an
open fop)?


Thanks,



----- Original Message -----
>From: "Anand Avati" <avati at gluster.com>
>To: "Ian Latter" <ian.latter at midnightcode.org>
>Subject:  Re: [Gluster-devel]
FIRST_CHILD(frame->this)->fops->create
>Date: Thu, 06 Aug 2009 23:19:39 -0700
>
> > �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
> 


--
Ian Latter
Late night coder ..
http://midnightcode.org/





More information about the Gluster-devel mailing list