/* * This needs to undo what gfile_create does. * See also dir_release. */ static OSKIT_COMDECL_U file_release(oskit_file_t *f) { gfile_t *file; unsigned newcount; file = (gfile_t *)f; VERIFY_OR_PANIC(file, "file"); newcount = --file->count; if (newcount == 0) { int rc; oskit_filesystem_release(&file->fs->fsi); rc = hashtab_remove(dentrytab, (hashtab_key_t) file->dentry, 0, 0); assert(rc == HASHTAB_SUCCESS); dput(file->dentry); kfree(file); } return newcount; }
oskit_error_t fini(void) { if (fs) { oskit_filesystem_release(fs); fs = 0; } return 0; }
/* * Must release the filesystem namespace upon exit so that everything * gets cleared away. With all the references cleared, the actual * filesystem can by sync'ed to disk, and then it can be released! */ static void start_fs_cleanup(void *arg) { oskit_filesystem_t *fs = arg; int count; oskit_clientos_setfsnamespace(NULL); printf("Syncing disks ... "); oskit_filesystem_sync(fs, 1); printf("Done!\n"); if ((count = oskit_filesystem_release(fs)) != 0) { printf("WARNING: " "start_fs_cleanup: filesystem not RELEASED(%d)!\n", count); } }
void start_fs_on_blkio(oskit_blkio_t *part) { oskit_dir_t *root; oskit_filesystem_t *fs; oskit_fsnamespace_t *fsn; int rc; osenv_process_lock(); /* initialize the file system code */ rc = fs_netbsd_init(start_osenv()); if (rc) { printf("fs_netbsd_init() failed: errno 0x%x\n", rc); exit(rc); } /* mount a filesystem */ rc = fs_netbsd_mount(part, 0, &fs); if (rc) { printf("fs_netbsd_mount() failed: errno 0x%x\n", rc); exit(rc); } if (!oskit_usermode_simulation) { /* Don't need the part anymore, the filesystem has a ref. */ oskit_blkio_release(part); } #ifdef PTHREADS { oskit_filesystem_t *wrappedfs; /* Wrap it up! */ rc = oskit_wrap_filesystem(fs, (void (*)(void *))osenv_process_lock, (void (*)(void *))osenv_process_unlock, 0, &wrappedfs); if (rc) { printf("oskit_wrap_filesystem() failed: errno 0x%x\n", rc); exit(rc); } /* Don't need the fs anymore, the wrapper has a ref. */ oskit_filesystem_release(fs); fs = wrappedfs; /* * oskit_filesystem_getroot will return a wrapped root dir. */ } #endif osenv_process_unlock(); rc = oskit_filesystem_getroot(fs, &root); if (rc) { printf("oskit_filesystem_getroot() failed: errno 0x%x\n", rc); exit(rc); } /* Create the initial filesystem namespace from the root directory */ rc = oskit_create_fsnamespace(root, root, &fsn); if (rc) { printf("oskit_create_fsnamespace() failed: errbo 0x%x\n", rc); exit(rc); } /* Don't need the root anymore, fsnamespace took a couple of refs. */ oskit_dir_release(root); /* Initialize the filesystem namespace for the program. */ oskit_clientos_setfsnamespace(fsn); /* And release our reference since the clientos took one. */ oskit_fsnamespace_release(fsn); /* Set up to clear out the clientos fsname handle at exit. */ startup_atexit(start_fs_cleanup, fs); }
int main(int argc, char **argv) { oskit_filesystem_t *fs; oskit_dir_t *root, *cwd = 0, *last_cwd; oskit_file_t *file; oskit_openfile_t *ofile; oskit_absio_t *absfile; oskit_identity_t id; oskit_stat_t sb; oskit_u32_t actual; #if 0 oskit_u32_t mask; #endif oskit_error_t rc; int i; #ifndef KNIT oskit_clientos_init(); start_clock(); #endif /* initialize the file system code */ printf(">>>Initializing the file system\n"); #ifndef KNIT rc = oskit_memfs_init(start_osenv(), &fs); #else rc = oskit_memfs_init(&fs); #endif if (rc) { printf("oskit_memfs_init() failed: errno 0x%x\n", rc); exit(rc); } /* establish client identity */ printf(">>>Establishing client identity\n"); id.uid = 0; id.gid = 0; id.ngroups = 0; id.groups = 0; rc = oskit_principal_create(&id, &cur_principal); if (rc) { printf("oskit_principal_create() failed: errno 0x%x\n", rc); exit(rc); } rc = oskit_filesystem_getroot(fs, &root); if (rc) { printf("oskit_filesystem_getroot() failed: errno 0x%x\n", rc); exit(rc); } rc = bmod_populate(root, NULL, NULL); if (rc) { printf("bmod_populate() failed: errno 0x%x\n", rc); exit(rc); } /* this is a quick, incomplete test of getdirentries */ { oskit_u32_t offset = 0; int count; struct oskit_dirents *dirents; oskit_file_t *ff; oskit_error_t rc = oskit_dir_getdirentries(root, &offset, 6, &dirents); if (rc) { printf("oskit_dir_getdirentries failed (0x%x)\n", rc); goto bailout; } oskit_dirents_getcount(dirents, &count); printf(">>>First %d entries of /\n", count); for (i = 0; i < count; i++) { char buf[256]; struct oskit_dirent *fd = (struct oskit_dirent *) buf; fd->namelen = (256-sizeof(*fd)); oskit_dirents_getnext(dirents, fd); printf(" %d %s\n", fd->ino, fd->name); } oskit_dirents_release(dirents); printf(">>>Trying to look up .. in /\n"); rc = oskit_dir_lookup(root, "..", &ff); if (rc) { printf("oskit_dir_lookup failed (0x%x)\n", rc); goto bailout; } oskit_file_release(ff); } #if 0 /* Doesn't make much sense - but maybe we'll implement it later... */ /* remount the file system read-write */ rc = oskit_filesystem_remount(fs, 0); if (rc) { printf("oskit_filesystem_remount() failed: errno 0x%x\n", rc); exit(rc); } #endif /* create a directory */ printf(">>>Creating /a\n"); rc = oskit_dir_mkdir(root, "a", 0755); if (rc) { printf("mkdir(/a) failed: errno 0x%x\n", rc); exit(rc); } printf(">>>Obtaining a handle to /a\n"); rc = oskit_dir_lookup(root, "a", (oskit_file_t **)&cwd); if (rc) { printf("lookup(/a) failed: errno 0x%x\n", rc); exit(rc); } /* create a subdirectory */ printf(">>>Creating /a/b\n"); rc = oskit_dir_mkdir(cwd, "b", 0700); if (rc) { printf("mkdir(/a/b) failed: errno 0x%x\n", rc); exit(rc); } printf(">>>Obtaining a handle to /a/b\n"); last_cwd = cwd; rc = oskit_dir_lookup(cwd, "b", (oskit_file_t **)&cwd); if (rc) { printf("lookup(/a/b) failed: errno 0x%x\n", rc); exit(rc); } /* create a file in the subdirectory */ printf(">>>Creating foo\n"); rc = oskit_dir_create(cwd, "foo", 0, 0600, &file); if (rc) { printf("create(foo) failed: errno 0x%x\n", rc); exit(rc); } /* open the file - should fail */ printf(">>>Opening /foo\n"); rc = oskit_file_open(file, OSKIT_O_RDWR, &ofile); if (rc) { printf("open(foo) failed: errno 0x%x\n", rc); exit(rc); } if (ofile) { /* * At the time of writing, the memfs didn't support per-open state. * If this changes, change this and add some tests. */ printf("open(foo) returned %p\n", ofile); exit(1); } /* open the file */ printf(">>>Getting absio interface for foo\n"); rc = oskit_file_query(file,&oskit_absio_iid,(void**)&absfile); if (rc) { printf("query(foo,absio) failed: errno 0x%x\n", rc); exit(rc); } /* fill the buffer with a nonrepeating integer sequence */ for (i = 0; i < sizeof(buf)/sizeof(unsigned int); i++) buf[i] = i; /* write the sequence */ printf(">>>Writing to foo\n"); rc = oskit_absio_write(absfile, buf, 0, sizeof(buf), &actual); if (rc) { printf("write failed: errno 0x%x\n", rc); exit(rc); } if (actual != sizeof(buf)) { printf("only wrote %d bytes of %d total\n", actual, sizeof(buf)); exit(1); } /* reopen the file */ printf(">>>Getting absio interface for foo again\n"); rc = oskit_file_query(file,&oskit_absio_iid,(void**)&absfile); if (rc) { printf("query(foo,absio) failed: errno 0x%x\n", rc); exit(rc); } bzero(buf, sizeof(buf)); /* read the file contents */ printf(">>>Reading foo\n"); rc = oskit_absio_read(absfile, buf, 0, sizeof(buf), &actual); if (rc) { printf("read failed: errno 0x%x\n", rc); exit(rc); } if (actual != sizeof(buf)) { printf("only read %d bytes of %d total\n", actual, sizeof(buf)); exit(1); } oskit_absio_release(absfile); /* check the file contents */ printf(">>>Checking foo's contents\n"); for (i = 0; i < sizeof(buf)/sizeof(unsigned int); i++) { if (buf[i] != i) { printf("word %d of file was corrupted\n", i); exit(1); } } /* lots of other tests */ printf(">>>Linking bar to foo\n"); rc = oskit_dir_link(cwd, "bar", file); if (rc != OSKIT_E_NOTIMPL) { printf("link(foo, bar) should be unimplemented: errno 0x%x\n", rc); exit(rc); } printf(">>>Renaming bar to rab\n"); rc = oskit_dir_rename(cwd, "bar", cwd, "rab"); if (rc != OSKIT_E_NOTIMPL) { printf("rename(bar, rab) should be unimplemented: errno 0x%x\n", rc); exit(rc); } printf(">>>Stat'ing foo\n"); bzero(&sb, sizeof(sb)); rc = oskit_file_stat(file, &sb); if (rc) { printf("stat(foo) failed: errno 0x%x\n", rc); exit(rc); } printf(">>>Checking foo's mode and link count\n"); if (!OSKIT_S_ISREG(sb.mode) || ((sb.mode & 0777) != 0777)) { printf("foo has the wrong mode (0x%x)\n", sb.mode); exit(1); } if ((sb.nlink != 1)) { printf("foo does not have 1 link, nlink=%d\n", sb.nlink); exit(1); } printf(">>>Stat'ing .\n"); bzero(&sb, sizeof(sb)); rc = oskit_dir_stat(cwd, &sb); if (rc) { printf("stat(a/b) failed: errno 0x%x\n", rc); exit(rc); } printf(">>>Checking .'s mode and link count\n"); if (!OSKIT_S_ISDIR(sb.mode) || ((sb.mode & 0777) != 0777)) { printf("a/b has the wrong mode (0x%x)\n", sb.mode); exit(1); } if ((sb.nlink != 2)) { printf("a/b does not have 2 links?, nlink=%d\n", sb.nlink); exit(1); } printf(">>>Stat'ing ..\n"); bzero(&sb, sizeof(sb)); rc = oskit_dir_stat(last_cwd, &sb); if (rc) { printf("stat(a) failed: errno 0x%x\n", rc); exit(rc); } printf(">>>Checking ..'s mode and link count\n"); if (!OSKIT_S_ISDIR(sb.mode) || ((sb.mode & 0777) != 0777)) { printf("a has the wrong mode (0x%x)\n", sb.mode); exit(1); } if ((sb.nlink != 3)) { printf("a does not have 3 links?, nlink=%d\n", sb.nlink); exit(1); } #if 0 printf(">>>Changing foo's mode\n"); mask = OSKIT_STAT_MODE; sb.mode = 0666; rc = oskit_file_setstat(file, mask, &sb); if (rc) { printf("chmod(foo) failed: errno 0x%x\n", rc); exit(rc); } printf(">>>Changing foo's user and group\n"); mask = OSKIT_STAT_UID | OSKIT_STAT_GID; sb.uid = 5458; sb.gid = 101; rc = oskit_file_setstat(file, mask, &sb); if (rc) { printf("chown(foo) failed: errno 0x%x\n", rc); exit(rc); } printf(">>>Stat'ing foo\n"); bzero(&sb, sizeof(sb)); rc = oskit_file_stat(file, &sb); if (rc) { printf("stat(foo) failed: errno 0x%x\n", rc); exit(rc); } printf(">>>Checking foo's mode and ownership\n"); if (!OSKIT_S_ISREG(sb.mode) || ((sb.mode & 0777) != 0666)) { printf("chmod(foo) didn't work properly\n"); exit(1); } if (sb.uid != 5458) { printf("chown(foo) didn't work properly\n"); exit(1); } if (sb.gid != 101) { printf("chown(foo) didn't work properly\n"); exit(1); } #endif printf(">>>Unlinking foo\n"); oskit_file_release(file); rc = oskit_dir_unlink(cwd, "foo"); if (rc) { printf("unlink(foo) didn't work properly: errno 0x%x\n", rc); exit(rc); } #if 0 /* We no longer create it, so we shouldn't remove it. */ printf(">>>Unlinking bar\n"); rc = oskit_dir_unlink(cwd, "bar"); if (rc) { printf("unlink(bar) didn't work properly: errno 0x%x\n", rc); exit(rc); } #endif printf(">>>Changing cwd to ..\n"); oskit_dir_release(cwd); cwd = last_cwd; printf(">>>Removing b\n"); rc = oskit_dir_rmdir(cwd, "b"); if (rc) { printf("rmdir(b) didn't work properly\n"); exit(rc); } printf(">>>Changing cwd to ..\n"); oskit_dir_release(cwd); cwd = root; printf(">>>Removing a\n"); rc = oskit_dir_rmdir(cwd, "a"); if (rc) { printf("rmdir(a) didn't work properly\n"); exit(rc); } bailout: printf(">>>Syncing\n"); if (cwd) oskit_dir_release(cwd); oskit_filesystem_sync(fs,TRUE); printf(">>>Unmounting\n"); oskit_filesystem_release(fs); printf(">>>Exiting\n"); exit(0); }