/** Initializes filesystem, security management... */ static int FS_Specific_Init(fusefs_specific_initinfo_t * fs_init_info) { int rc = 0; fsal_op_context_t ctx; struct stat stbuf; unsigned int root_gen; struct ganefuse_conn_info conn = { .proto_major = 0, /* XXX is another value necessary ? */ .proto_minor = 0, /* XXX is another value necessary ? */ .async_read = 0, .max_write = global_fs_info.maxwrite, .max_readahead = global_fs_info.maxread, .reserved = {0} }; /* set filesystems operations and opaque info */ p_fs_ops = fs_init_info->fs_ops; fs_user_data = fs_init_info->user_data; /* create a "fake" context in case init use it */ fs_private_data = NULL; FUSEFSAL_InitClientContext(&ctx); fsal_set_thread_context(&ctx); /* call filesystem's init */ if(p_fs_ops->init) { fs_private_data = p_fs_ops->init(&conn); } /* reset context now fs_private_data is known */ FUSEFSAL_InitClientContext(&ctx); fsal_set_thread_context(&ctx); /* initialize namespace by getting root inode number * getattr is mandatory ! */ if(!p_fs_ops->getattr) return -ENOSYS; rc = p_fs_ops->getattr("/", &stbuf); if(rc) { LogCrit(COMPONENT_FSAL, "FSAL INIT: Could not call initial 'getattr' on filesystem root"); return rc; } /* generation based on ctime for avoiding stale handles */ root_gen = stbuf.st_ctime; if(stbuf.st_ino == 0) { /* filesystem does not provide inodes ! */ LogCrit(COMPONENT_FSAL, "WARNING in lookup: filesystem does not provide inode numbers"); /* root will have inode nbr 1 */ stbuf.st_ino = 1; } /* initialize namespace */ rc = NamespaceInit(stbuf.st_ino, stbuf.st_dev, &root_gen); return rc; } /** * FSAL_Init : Initializes the FileSystem Abstraction Layer. * * \param init_info (input, fsal_parameter_t *) : * Pointer to a structure that contains * all initialization parameters for the FSAL. * Specifically, it contains settings about * the filesystem on which the FSAL is based, * security settings, logging policy and outputs, * and other general FSAL options. * * \return Major error codes : * ERR_FSAL_NO_ERROR (initialisation OK) * ERR_FSAL_FAULT (init_info pointer is null) * ERR_FSAL_SERVERFAULT (misc FSAL error) * ERR_FSAL_ALREADY_INIT (The FS is already initialized) * ERR_FSAL_BAD_INIT (FS specific init error, * minor error code gives the reason * for this error.) * ERR_FSAL_SEC_INIT (Security context init error). */ fsal_status_t FUSEFSAL_Init(fsal_parameter_t * init_info /* IN */ ) { fsal_status_t status; int rc; /* sanity check. */ if(!init_info) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_Init); /* proceeds FSAL internal status initialization */ status = fsal_internal_init_global(&(init_info->fsal_info), &(init_info->fs_common_info)); if(FSAL_IS_ERROR(status)) Return(status.major, status.minor, INDEX_FSAL_Init); /* initialize filesystem stuff */ if(rc = FS_Specific_Init((fusefs_specific_initinfo_t *) &init_info->fs_specific_info)) Return(ERR_FSAL_BAD_INIT, -rc, INDEX_FSAL_Init); /* Everything went OK. */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_Init); }
int main(int argc, char **argv) { int rc, i; ns_testset_t *p_test; char path[FSAL_MAX_PATH_LEN]; unsigned int gen = 0; unsigned int dev = DEV; /* Init logging */ SetNamePgm("test_ns"); SetDefaultLogging("TEST"); SetNameFunction("main"); InitLogging(); /* namespace init */ rc = NamespaceInit(ROOT_INODE, DEV, &gen); if(rc) { LogTest("NamespaceInit rc=%d\n", rc); exit(1); } for(i = 0; i < 2; i++) { /* creation des entrees */ for(p_test = testset; p_test->name != NULL; p_test++) { rc = NamespaceAdd(p_test->parent_inode, DEV, gen, p_test->name, p_test->entry_inode, DEV, &gen); LogTest("NamespaceAdd(%lu,%s->%lu) = %d\n", p_test->parent_inode, p_test->name, p_test->entry_inode, rc); if(rc) exit(1); /* This is an error */ } /* tentative de recreation */ for(p_test = testset; p_test->name != NULL; p_test++) { rc = NamespaceAdd(p_test->parent_inode, DEV, gen, p_test->name, p_test->entry_inode, DEV, &gen); LogTest("Redundant NamespaceAdd(%lu,%s->%lu) = %d\n", p_test->parent_inode, p_test->name, p_test->entry_inode, rc); if(rc) exit(1); /* This is an error */ } /* recolte du chemin complet de root */ rc = NamespacePath(ROOT_INODE, DEV, gen, path); if(rc) { LogTest("NamespacePath(%lu) rc=%d\n", ROOT_INODE, rc); exit(1); } else LogTest("NamespacePath(%lu) => \"%s\"\n", ROOT_INODE, path); /* recolte du chemin complet des entrees */ for(p_test = testset; p_test->name != NULL; p_test++) { rc = NamespacePath(p_test->entry_inode, DEV, gen, path); if(rc) { LogTest("NamespacePath(%lu) rc=%d\n", p_test->entry_inode, rc); exit(1); } else LogTest("NamespacePath(%lu) => \"%s\"\n", p_test->entry_inode, path); } /* on efface les entrees en ordre inverse */ for(p_test--; p_test >= testset; p_test--) { rc = NamespaceRemove(p_test->parent_inode, DEV, gen, p_test->name); LogTest("NamespaceRemove(%lu,%s) = %d\n", p_test->parent_inode, p_test->name, rc); } /* on essaye d'obtenir leur nom */ for(p_test = testset; p_test->name != NULL; p_test++) { rc = NamespacePath(p_test->entry_inode, DEV, gen, path); if(rc == 0) { LogTest("NamespacePath(%lu) => \"%s\"\n", p_test->entry_inode, path); exit(1); } else if(rc != ENOENT) { LogTest("NamespacePath(%lu) rc=%d\n", p_test->entry_inode, rc); exit(1); } else LogTest("NamespacePath(%lu) rc=%d (ENOENT)\n", p_test->entry_inode, rc); } } /* now create/remove a hardlink to a file N times */ rc = NamespaceAdd(ROOT_INODE, DEV, gen, "dir", ROOT_INODE + 1, DEV, &gen); if(rc) { LogTest("NamespaceAdd error %d line %d\n", rc, __LINE__ - 1); exit(1); } rc = NamespaceAdd(ROOT_INODE + 1, DEV, gen, "subdir", ROOT_INODE + 2, DEV, &gen); if(rc) { LogTest("NamespaceAdd error %d line %d\n", rc, __LINE__ - 1); exit(1); } rc = NamespaceAdd(ROOT_INODE + 2, DEV, gen, "entry", ROOT_INODE + 3, DEV, &gen); if(rc) { LogTest("NamespaceAdd error %d line %d\n", rc, __LINE__ - 1); exit(1); } /* create hardlinks and lookup */ for(i = 0; i < 3; i++) { char name[FSAL_MAX_NAME_LEN]; sprintf(name, "entry.hl%d", i); rc = NamespaceAdd(ROOT_INODE + 2, DEV, gen, name, ROOT_INODE + 3, DEV, &gen); LogTest("NamespaceAdd(%lu,%s->%lu) = %d\n", ROOT_INODE + 2, name, ROOT_INODE + 3, rc); if(rc) exit(1); rc = NamespacePath(ROOT_INODE + 3, DEV, gen, path); if(rc) { LogTest("NamespacePath(%lu) rc=%d\n", ROOT_INODE + 3, rc); exit(1); } else LogTest("NamespacePath(%lu) => \"%s\"\n", ROOT_INODE + 3, path); } /* delete hardlinks and lookup */ for(i = 0; i < 3; i++) { char name[FSAL_MAX_NAME_LEN]; sprintf(name, "entry.hl%d", i); rc = NamespaceRemove(ROOT_INODE + 2, DEV, gen, name); LogTest("NamespaceRemove(%lu,%s) = %d\n", ROOT_INODE + 2, name, rc); if(rc) exit(1); rc = NamespacePath(ROOT_INODE + 3, DEV, gen, path); if(rc) { LogTest("NamespacePath(%lu) rc=%d\n", ROOT_INODE + 3, rc); exit(1); } else LogTest("NamespacePath(%lu) => \"%s\"\n", ROOT_INODE + 3, path); } return 0; }