bug-hurd
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]