commit 0a3cf0aef5660e1fef46cd9165a2436b09a24bb0
parent 133f47d94b3209c337f986d24fd1f58ff47ec07b
Author: Christian Grothoff <christian@grothoff.org>
Date: Mon, 4 Jun 2012 14:47:27 +0000
-misc fixes, adding logging
Diffstat:
7 files changed, 194 insertions(+), 112 deletions(-)
diff --git a/src/fuse/Makefile.am b/src/fuse/Makefile.am
@@ -12,19 +12,21 @@ gnunet_fuse_SOURCES = \
gnunet-fuse.c \
gfs_download.c gfs_download.h \
mutex.c mutex.h \
- readdir.c \
- mkdir.c \
- mknod.c \
- release.c \
- rename.c \
- rmdir.c \
- truncate.c \
- unlink.c \
- utimens.c \
- write.c \
- read.c \
- open.c \
- getattr.c
+ readdir.c \
+ read.c \
+ open.c \
+ getattr.c
+#
+# mkdir.c \
+# mknod.c \
+# release.c \
+# rename.c \
+# rmdir.c \
+# truncate.c \
+# unlink.c \
+# utimens.c \
+# write.c
+
gnunet_fuse_LDADD = \
-lgnunetutil \
-lfuse \
diff --git a/src/fuse/getattr.c b/src/fuse/getattr.c
@@ -1,4 +1,23 @@
/*
+ This file is part of gnunet-fuse.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ gnunet-fuse is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ gnunet-fuse is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+/*
* getattr.c - FUSE getattr function
*
* Created on: Mar 14, 2012
@@ -11,25 +30,21 @@
* ignored. The 'st_ino' field is ignored except if the 'use_ino'
* mount option is given.
*/
-
-#include <sys/stat.h>
-//#include <string.h>
-//#include <errno.h>
-#include <fuse.h>
-#include <gnunet-fuse.h>
+#include "gnunet-fuse.h"
+#include "gfs_download.h"
int
gn_getattr (const char *path, struct stat *stbuf)
{
+ struct GNUNET_FUSE_PathInfo *pi;
-
- memset (stbuf, 0, sizeof (*stbuf));
-
- stbuf->st_mode = S_IFDIR | 0555;
- stbuf->st_nlink = 1;
-
+ pi = GNUNET_FUSE_path_info_get (path);
+ if (NULL == pi)
+ return - ENOENT;
+ *stbuf = pi->stbuf;
+ GNUNET_FUSE_path_info_done (pi);
return 0;
+}
+/* end of getattr.c */
-
-}
diff --git a/src/fuse/gfs_download.c b/src/fuse/gfs_download.c
@@ -223,9 +223,9 @@ GNUNET_FUSE_download_file (struct GNUNET_FUSE_PathInfo *path_info,
}
if (0 != pid)
{
- while ( (0 != (ret = waitpid (pid, &status, 0))) &&
+ while ( (-1 == (ret = waitpid (pid, &status, 0))) &&
(EINTR == errno) ) ;
- if (0 != ret)
+ if (pid != ret)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "waitpid");
(void) kill (pid, SIGKILL);
diff --git a/src/fuse/gnunet-fuse.c b/src/fuse/gnunet-fuse.c
@@ -83,7 +83,8 @@ GNUNET_FUSE_path_info_get (const char *path)
GNUNET_CRYPTO_hash (path, strlen (path), &path_hash);
GNUNET_mutex_lock (map_mutex);
pi = GNUNET_CONTAINER_multihashmap_get (map, &path_hash);
- ++pi->rc;
+ if (NULL != pi)
+ ++pi->rc;
GNUNET_mutex_unlock (map_mutex);
return pi;
}
@@ -122,13 +123,16 @@ GNUNET_FUSE_path_info_create (const char *path,
&path_hash,
pi,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
- pi->stbuf.st_size = (off_t) GNUNET_FS_uri_chk_get_file_size (uri);
- pi->stbuf.st_blocks = 1 + ((pi->stbuf.st_size) / 512);
- pi->stbuf.st_blksize = 32 * 1024;
pi->stbuf.st_mode = (S_IRUSR | S_IRGRP | S_IROTH); /* read-only */
if (GNUNET_YES == is_directory)
- pi->stbuf.st_mode |= (S_IXUSR | S_IXGRP | S_IXOTH); /* allow traversal */
- pi->stbuf.st_mode |= S_IFREG; /* regular file */
+ {
+ pi->stbuf.st_mode |= S_IFDIR | (S_IXUSR | S_IXGRP | S_IXOTH); /* allow traversal */
+ }
+ else
+ {
+ pi->stbuf.st_mode |= S_IFREG; /* regular file */
+ pi->stbuf.st_size = (off_t) GNUNET_FS_uri_chk_get_file_size (uri);
+ }
GNUNET_mutex_unlock (map_mutex);
return pi;
}
@@ -325,6 +329,7 @@ main (int argc, char *const *argv)
&GNUNET_GETOPT_set_one, &single_threaded},
GNUNET_GETOPT_OPTION_END
};
+ GNUNET_log_setup ("gnunet-fuse", "DEBUG", NULL);
return (GNUNET_OK ==
GNUNET_PROGRAM_run2 (argc,
argv,
diff --git a/src/fuse/open.c b/src/fuse/open.c
@@ -1,4 +1,23 @@
/*
+ This file is part of gnunet-fuse.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ gnunet-fuse is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ gnunet-fuse is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+/*
* open.c - FUSE open function
*
* Created on: Mar 14, 2012
@@ -22,32 +41,22 @@
* Changed in version 2.2
*/
-//#include <string.h>
-//#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fuse.h>
-#include <gnunet-fuse.h>
-
+#include "gnunet-fuse.h"
+#include "gfs_download.h"
int
gn_open (const char *path, struct fuse_file_info *fi)
{
-
-
- //if (strcmp(path, "/home/mg/gnunet-fuse2/gnunet-fuse/src/ext/monti") == 0)
- // return 0;
-//
-// else if ((fi->flags & 3) != O_RDONLY)
-// return -EACCES;
-
-
-// else return 0;
-
-
-/*
- * when user is allowed to open, return 0
- */
+ struct GNUNET_FUSE_PathInfo *pi;
+
+ pi = GNUNET_FUSE_path_info_get (path);
+ if (NULL == pi)
+ return - ENOENT;
+ GNUNET_FUSE_path_info_done (pi);
+ if (O_RDONLY != (fi->flags & 3))
+ return - EACCES;
return 0;
}
+
+/* end of open.c */
diff --git a/src/fuse/read.c b/src/fuse/read.c
@@ -1,11 +1,29 @@
/*
+ This file is part of gnunet-fuse.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ gnunet-fuse is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ gnunet-fuse is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+/*
* read.c - FUSE read function
*
* Created on: Mar 14, 2012
* Author: mg
*
-
- Read data from an open file
+ * Read data from an open file
*
* Read should return exactly the number of bytes requested except
* on EOF or error, otherwise the rest of the data will be
@@ -16,9 +34,8 @@
*
* Changed in version 2.2
*/
-
#include "gnunet-fuse.h"
-
+#include "gfs_download.h"
@@ -26,47 +43,75 @@ int
gn_read (const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
-/* (void) fi;
- size_t len;
-
-//until now read-function isn't used....
-
-if(strcmp(path, "/") == 0)
-{
- len = strlen("/");
- if (offset < len)
- {
- if (offset + size > len)
- size = len - offset;
- memcpy(buf, "/" + offset, size);
- }
- else
- size = 0;
-
- return size;
- }
-
-
-if (strcmp(path, "/home/mg/gnunet-fuse2/gnunet-fuse/fuse/src/ext/monti/prueba") == 0)
- {
-
- len = strlen("test");
-
- if (offset < len)
- {
- if (offset + size > len)
- size = len - offset;
- memcpy(buf, "test" + offset, size);
- }
- else
- size = 0;
-
- return size;
- }
-
+ struct GNUNET_FUSE_PathInfo *path_info;
+ uint64_t fsize;
+ struct GNUNET_DISK_FileHandle *fh;
+
+ path_info = GNUNET_FUSE_path_info_get (path);
+ if (NULL == path_info)
+ {
+ /* FIXME: we might need to check which of the ancestors
+ exist and possibly download ancestral directories,
+ instead of directly giving up here... */
+ return - ENOENT;
+ }
+ if (NULL == path_info->tmpfile)
+ {
+ /* store to temporary file */
+ path_info->tmpfile = GNUNET_DISK_mktemp ("gnunet-fuse-tempfile");
+ if (GNUNET_OK != GNUNET_FUSE_download_file (path_info,
+ offset,
+ size))
+ {
+ UNLINK (path_info->tmpfile);
+ GNUNET_free (path_info->tmpfile);
+ path_info->tmpfile = NULL;
+ GNUNET_FUSE_path_info_done (path_info);
+ return - EIO; /* low level IO error */
+ }
+ }
+
+ fsize = GNUNET_FS_uri_chk_get_file_size (path_info->uri);
+ fh = GNUNET_DISK_file_open (path_info->tmpfile,
+ GNUNET_DISK_OPEN_READ,
+ GNUNET_DISK_PERM_NONE);
+ if (NULL == fh)
+ {
+ GNUNET_FUSE_path_info_done (path_info);
+ return - EBADF;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to read bytes %llu-%llu/%llu of file `%s'\n",
+ (unsigned long long) offset,
+ (unsigned long long) offset + size,
+ (unsigned long long) fsize,
+ path);
+ if (offset != GNUNET_DISK_file_seek (fh, offset, GNUNET_DISK_SEEK_SET))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "No data available at offset %llu of file `%s'\n",
+ (unsigned long long) offset,
+ path);
+ GNUNET_DISK_file_close (fh);
+ GNUNET_FUSE_path_info_done (path_info);
+ return 0;
+ }
+ size = GNUNET_MIN (size, fsize - offset);
+ if (GNUNET_SYSERR == (size = GNUNET_DISK_file_read (fh, buf, size)))
+ {
+ int eno = errno;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Error reading from file `%s': %s\n",
+ path,
+ STRERROR (errno));
+ GNUNET_DISK_file_close (fh);
+ GNUNET_FUSE_path_info_done (path_info);
+ return - eno;
+ }
+ GNUNET_DISK_file_close (fh);
+ GNUNET_FUSE_path_info_done (path_info);
+ return size;
+}
+/* end of read.c */
-else return -ENOENT;
-*/
- return -ENOENT;
-}
diff --git a/src/fuse/readdir.c b/src/fuse/readdir.c
@@ -100,18 +100,26 @@ process_directory_entry (void *cls,
char *path;
int is_directory;
+ if (NULL == filename)
+ return; /* info about the directory itself */
GNUNET_asprintf (&path,
- "%s/%s",
+ "%s%s",
dc->path,
filename);
is_directory = GNUNET_FS_meta_data_test_for_directory (meta);
if (GNUNET_SYSERR == is_directory)
is_directory = GNUNET_NO; /* if in doubt, say no */
- pi = GNUNET_FUSE_path_info_create (path, uri, is_directory);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Listing filename `%s' in directory `%s' (%s)\n",
+ filename,
+ dc->path,
+ path);
+ pi = GNUNET_FUSE_path_info_create (path, uri, is_directory);
dc->filler (dc->buf,
filename,
&pi->stbuf,
0);
+ GNUNET_FUSE_path_info_done (pi);
}
@@ -154,6 +162,7 @@ gn_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
dc.filler = filler;
dc.path = path;
+ dc.buf = buf;
size = (size_t) GNUNET_FS_uri_chk_get_file_size (path_info->uri);
fh = GNUNET_DISK_file_open (path_info->tmpfile,
GNUNET_DISK_OPEN_READ,
@@ -173,18 +182,15 @@ gn_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
GNUNET_FUSE_path_info_done (path_info);
return -EBADF;
}
+ filler (buf, ".", NULL, 0);
+ filler (buf, "..", NULL, 0);
+ ret = 0;
if (GNUNET_OK !=
GNUNET_FS_directory_list_contents (size,
data, 0LL,
&process_directory_entry,
&dc))
- ret = - EBADF;
- else
- {
- filler (buf, ".", NULL, 0);
- filler (buf, "..", NULL, 0);
- ret = 0;
- }
+ ret = - EIO;
GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_unmap (mh));
GNUNET_DISK_file_close (fh);
GNUNET_FUSE_path_info_done (path_info);