[Prev][Next][Index][Thread]
Re: linux_fs + freebsd_c
On 1999-1-10 Matthew Flatt <mflatt@cs.rice.edu> wrote:
> I have OSKit's linux_fs + freebsd_c working in MzScheme, sortof. Some
> things that I've tried work fine, such as testing for the existence of
> files/directories (via stat()), creating directories (via mkdir()),
> and reading files (via fopen()). But I've encountered a few things
> that don't work for me:
>
> * After sucessfully reading the content of a directory, closedir()
> triggers an assert failure in lmm_free.c, line 61.
Thanks for the bug report. I've attached a couple of patches
that will be in the next release. The first fixes this closedir
problem, where the Linux glue code was freeing something that
the caller is responsible for. The second is described below.
> * fopen("new-file", "w") always returns NULL; errno contains
> OSKIT_E_INVALIDARG. stat() immediately after reports that the file
> exists.
Leigh has addressed that in a previous message.
> * Creating a directory works, but the directory doesn't survive
> reboots. Neither do the files that are apparently created by
> fopen(). Is there some sort of sync() function I need to call?
> (The obvious one, sync(), doesn't seem to be there.)
This is because you never do oskit_filesystem_release nor sync
on the oskit_filesystem_t returned by fs_linux_mount. The code
should go like
assert(fs_linux_mount(part, 0, &fs) == 0);
assert(oskit_filesystem_getroot(fs, &root) == 0);
...use them...
assert(oskit_directory_release(root) == 0);
assert(oskit_filesystem_sync(fs) == 0);
assert(oskit_filesystem_release(fs) == 0);
The sync call isn't absolutely necessary, since release calls
unmount, which calls the Linux internal fsync_dev, which will
wait until everything is written out. But fsync_dev may fail to
sync everything if there is some sort of I/O error (see comments
in linux/src/fs/buffer.c:sync_buffers()).
However, the oskit_filesystem_release method for Linux
filesystems has the wait value reversed. The second patch below
fixes this.
--- linux/fs/file.c~ Mon Dec 7 03:58:11 1998
+++ linux/fs/file.c Mon Jan 11 20:40:51 1999
@@ -1336,7 +1336,8 @@
for (i = 0; i < nentries; i++)
if (out_dirents->dirents[i].name)
kfree(out_dirents->dirents[i].name);
- kfree(out_dirents->dirents);
+ if (err)
+ kfree(out_dirents->dirents);
cleanup_current:
fs_linux_destroy_current();
return err;
--- linux/fs/filesystem.c~ Mon Dec 7 03:58:11 1998
+++ linux/fs/filesystem.c Mon Jan 11 21:02:54 1999
@@ -147,7 +147,6 @@
oskit_error_t err;
struct task_struct ts;
kdev_t dev;
- int retry;
fs = (gfilesystem_t *)f;
VERIFY1(fs, fs->sb);
@@ -157,20 +156,11 @@
return err;
dev = fs->sb->s_dev;
- if (wait)
+ if (wait && fsync_dev(dev) != 0)
+ /* fsync_dev can return 1 if there was an IO error. */
+ return OSKIT_EIO;
+ else
sync_dev(dev);
- else {
- for (retry = 0; retry < 5; retry++)
- if (fsync_dev(dev) == 0)
- break;
- if (retry == 5) {
- printk(KERN_WARNING
- "%s(%d,%d): fsync_dev never succeeded\n",
- __FUNCTION__, MAJOR(dev), MINOR(dev));
- fs_linux_destroy_current();
- return OSKIT_E_FAIL;
- }
- }
fs_linux_destroy_current();
-- bart
Follow-Ups:
References: