> 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