[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Implement the sync libnetfs stubs.
From: |
Sergiu Ivanov |
Subject: |
[PATCH] Implement the sync libnetfs stubs. |
Date: |
Thu, 19 Nov 2009 11:18:45 +0200 |
User-agent: |
Mutt/1.5.20 (2009-06-14) |
* netfs.c (netfs_attempt_sync): Sync every directory associated
with the supplied node.
(netfs_attempt_syncfs): Send file_syncfs to every directory
maintained by unionfs.
---
Hello,
On Tue, Nov 17, 2009 at 09:58:15PM +0100, olafBuddenhagen@gmx.net wrote:
> On Tue, Nov 17, 2009 at 12:30:56PM +0200, Sergiu Ivanov wrote:
> > On Fri, Nov 06, 2009 at 09:58:31AM +0100, olafBuddenhagen@gmx.net
> > wrote:
>
> > > Well, did you actually test how it behaves with really readonly
> > > filesystems? (Most notably that it doesn't return an error status?)
> >
> > As an example of a readonly filesystem I took xmlfs and took a glance
> > at it's implementation of netfs sync stubs. And then it flashed in my
> > mind that all implementations of sync stubs that I've seen and which
> > did nothing returned 0. I can't remember this being specified as a
> > convention somewhere, though.
>
> OK, misunderstanding here: I didn't mean translators that do not
> implement writing -- I meant filesystems *mounted* readonly.
Ah, I see.
I did the following:
# settrans -a tmp /hurd/ext2fs /dev/hd2
ext2fs: /dev/hd2: warning: FILESYSTEM NOT UNMOUNTED CLEANLY; PLEASE fsck
ext2fs: /dev/hd2: warning: MOUNTED READ-ONLY; MUST USE `fsysopts --writable'
$ settrans -a foo unionfs tmp
$ syncfs foo
$ syncfs foo/home/scolobb
(As a special note I remark that foo/home/scolobb does exist.)
The first warning by ext2fs is due to the fact that I actually
remounted the (already mounted) /home partition. (I hope I haven't
screwed things up.) The second one shows that the filesystem has been
mounted read-only. I guess this is what you mean.
First of all, syncfs foo invokes netfs_attempt_syncfs, wherein all
calls to file_syncfs happily return 0. On the other hand, syncfs
foo/home/scolobb also invokes netfs_attempt_syncfs (not
netfs_attempt_sync as I would suppose).
To invoke netfs_attempt_sync, I sketched the following simple program:
#define _GNU_SOURCE 1
#include <hurd.h>
#include <hurd/fs.h>
#include <fcntl.h>
#include <stdio.h>
int
main (void)
{
mach_port_t p = file_name_lookup ("foo/home/", O_READ, 0);
file_sync (p, 1, 0);
mach_port_deallocate (mach_task_self (), p);
return 0;
} /* main */
Which did cause invocation of netfs_attempt_sync and I could see that
file_sync also returns 0 when invoked on a port to a read-only
filesystem.
Thus, if I did everything correctly, it seems that we have no problems
syncing really read-only filesystems either.
> > + /* The index of the currently analyzed filesystem. */
> > + int i = 0;
>
> You forgot to change it for the second loop...
Ah, yes :-( Fixed.
Regads,
scolobb
---
netfs.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/netfs.c b/netfs.c
index 89d1bf6..4c9f9a3 100644
--- a/netfs.c
+++ b/netfs.c
@@ -1,5 +1,6 @@
/* Hurd unionfs
- Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+
Written by Moritz Schulte <moritz@duesseldorf.ccc.de>.
This program is free software; you can redistribute it and/or
@@ -282,7 +283,45 @@ error_t
netfs_attempt_sync (struct iouser *cred, struct node *np,
int wait)
{
- return EOPNOTSUPP;
+ /* The error we are going to report back (last failure wins). */
+ error_t final_err = 0;
+
+ /* The information about the currently analyzed filesystem. */
+ ulfs_t * ulfs;
+
+ /* The index of the currently analyzed filesystem. */
+ int i;
+
+ mutex_lock (&ulfs_lock);
+
+ /* Sync every directory associated with `np`.
+
+ TODO: Rewrite this after having modified ulfs.c and node.c to
+ store the paths and ports to the underlying directories in one
+ place, because now iterating over both lists looks ugly. */
+ i = 0;
+ node_ulfs_iterate_unlocked (np)
+ {
+ error_t err;
+
+ /* Get the information about the current filesystem. */
+ err = ulfs_get_num (i, &ulfs);
+ assert (!err);
+
+ /* Since `np` may not necessarily be present in every underlying
+ directory, having a null port is perfectly valid. */
+ if (node_ulfs->port != MACH_PORT_NULL)
+ {
+ err = file_sync (node_ulfs->port, wait, 0);
+ if (err)
+ final_err = err;
+ }
+
+ ++i;
+ }
+
+ mutex_unlock (&ulfs_lock);
+ return final_err;
}
/* This should sync the entire remote filesystem. If WAIT is set,
@@ -290,7 +329,43 @@ netfs_attempt_sync (struct iouser *cred, struct node *np,
error_t
netfs_attempt_syncfs (struct iouser *cred, int wait)
{
- return 0;
+ /* The error we are going to report back (last failure wins). */
+ error_t final_err = 0;
+
+ /* The information about the currently analyzed filesystem. */
+ ulfs_t * ulfs;
+
+ /* The index of the currently analyzed filesystem. */
+ int i;
+
+ mutex_lock (&ulfs_lock);
+
+ /* Sync every unioned directory maintained by unionfs.
+
+ TODO: Rewrite this after having modified ulfs.c and node.c to
+ store the paths and ports to the underlying directories in one
+ place, because now iterating over both lists looks ugly. */
+ i = 0;
+ node_ulfs_iterate_unlocked (netfs_root_node)
+ {
+ error_t err;
+
+ /* Get the information about the current filesystem. */
+ err = ulfs_get_num (i, &ulfs);
+ assert (err == 0);
+
+ /* Note that, unlike the situation in netfs_attempt_sync, having a
+ null port on the unionfs root node is abnormal. */
+ assert (node_ulfs->port != MACH_PORT_NULL);
+ err = file_syncfs (node_ulfs->port, wait, 0);
+ if (err)
+ final_err = err;
+
+ ++i;
+ }
+
+ mutex_unlock (&ulfs_lock);
+ return final_err;
}
/* lookup */
--
1.6.5.2