gnunet-fuse

GNUnet file-sharing directory mounting via FUSE
Log | Files | Refs | Submodules | README | LICENSE

commit 0a3cf0aef5660e1fef46cd9165a2436b09a24bb0
parent 133f47d94b3209c337f986d24fd1f58ff47ec07b
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon,  4 Jun 2012 14:47:27 +0000

-misc fixes, adding logging

Diffstat:
Msrc/fuse/Makefile.am | 28+++++++++++++++-------------
Msrc/fuse/getattr.c | 43+++++++++++++++++++++++++++++--------------
Msrc/fuse/gfs_download.c | 4++--
Msrc/fuse/gnunet-fuse.c | 17+++++++++++------
Msrc/fuse/open.c | 53+++++++++++++++++++++++++++++++----------------------
Msrc/fuse/read.c | 137++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msrc/fuse/readdir.c | 24+++++++++++++++---------
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);