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@xxxxxxxxxxx> >To: "Ian Latter" <ian.latter@xxxxxxxxxxxxxxxx> >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/