[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r5305 - gnunet-fuse
From: |
gnunet |
Subject: |
[GNUnet-SVN] r5305 - gnunet-fuse |
Date: |
Thu, 12 Jul 2007 21:05:51 -0600 (MDT) |
Author: amatus
Date: 2007-07-12 21:05:50 -0600 (Thu, 12 Jul 2007)
New Revision: 5305
Added:
gnunet-fuse/mkdir.c
gnunet-fuse/rmdir.c
gnunet-fuse/unlink.c
gnunet-fuse/utimens.c
Modified:
gnunet-fuse/ChangeLog
gnunet-fuse/Makefile.am
gnunet-fuse/directory.c
gnunet-fuse/dirent.c
gnunet-fuse/getattr.c
gnunet-fuse/gnfs.h
gnunet-fuse/main.c
gnunet-fuse/mknod.c
gnunet-fuse/read.c
Log:
Added support for unlinking files, creating directories, and removing
directories
Modified: gnunet-fuse/ChangeLog
===================================================================
--- gnunet-fuse/ChangeLog 2007-07-12 11:48:20 UTC (rev 5304)
+++ gnunet-fuse/ChangeLog 2007-07-13 03:05:50 UTC (rev 5305)
@@ -1,3 +1,6 @@
+2007-07-12 David Barksdale <address@hidden> 0.7.2-3
+* Added support for unlinking files, creating directories, and removing
+directories
2007-07-12 David Barksdale <address@hidden> 0.7.2-2
* Added support for creating and modifying files
2007-06-18 David Barksdale <address@hidden> 0.7.2-1
Modified: gnunet-fuse/Makefile.am
===================================================================
--- gnunet-fuse/Makefile.am 2007-07-12 11:48:20 UTC (rev 5304)
+++ gnunet-fuse/Makefile.am 2007-07-13 03:05:50 UTC (rev 5305)
@@ -4,12 +4,16 @@
dirent.c \
getattr.c \
main.c \
+ mkdir.c \
mknod.c \
open.c \
read.c \
readdir.c \
release.c \
+ rmdir.c \
special_file.c \
+ unlink.c \
+ utimens.c \
write.c \
gnfs.h \
gettext.h
Modified: gnunet-fuse/directory.c
===================================================================
--- gnunet-fuse/directory.c 2007-07-12 11:48:20 UTC (rev 5304)
+++ gnunet-fuse/directory.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -96,7 +96,7 @@
/* NB: the lock on deparent is enough to guarantee that another
* thread hasn't added this dirent to the cache in the time
* between the above check and this insert */
- gn_dirent_cache(de);
+ gn_dirent_cache_insert(de);
}
/* Add it to the directory's list (steals our ref)*/
@@ -245,13 +245,54 @@
g_hash_table_replace(de->de_dir_hash, dechild->de_basename, dechild);
/* Cache the dirent */
- gn_dirent_cache(dechild);
+ gn_dirent_cache_insert(dechild);
/* Mark our path dirty */
gn_unlock_path(de, GN_UNLOCK_ALL_DIRTY);
return 0;
}
+int gn_directory_remove(struct dirent *de, struct dirent *dechild)
+{
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, dechild->de_path);
+
+ /* Lock our path */
+ if(gn_lock_path(de) == -1)
+ return -1;
+
+ /* Cache ourselfs (because we're going to become dirty) */
+ if(!de->de_cached)
+ {
+ if(directory_cache_locked(de) == -1)
+ {
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_ERROR,
+ "%s: failed to cache parent dir\n",
+ __FUNCTION__);
+ goto out_err;
+ }
+ }
+
+ /* Remove from dir_hash */
+ if(!g_hash_table_remove(de->de_dir_hash, dechild->de_basename))
+ {
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_ERROR,
+ "%s: not found in dir_hash\n",
+ __FUNCTION__);
+ goto out_err;
+ }
+
+ /* Remove from dirent cache */
+ gn_dirent_cache_remove(dechild);
+
+ /* Mark our path dirty */
+ gn_unlock_path(de, GN_UNLOCK_ALL_DIRTY);
+ return 0;
+out_err:
+ gn_unlock_path(de, GN_UNLOCK_CLEAN);
+ return -1;
+}
+
static void upcb(guint64 totalBytes, guint64 completedBytes, cron_t eta,
void *closure)
{
Modified: gnunet-fuse/dirent.c
===================================================================
--- gnunet-fuse/dirent.c 2007-07-12 11:48:20 UTC (rev 5304)
+++ gnunet-fuse/dirent.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -133,7 +133,8 @@
}
else
{
- g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+ de->de_dir_hash = g_hash_table_new_full(g_str_hash,
+ g_str_equal, NULL,
(GDestroyNotify)gn_dirent_put);
}
}
@@ -147,7 +148,7 @@
/*
* Add a dirent to the cache
*/
-void gn_dirent_cache(struct dirent *de)
+void gn_dirent_cache_insert(struct dirent *de)
{
/* TODO: Here we need to see if the cache has gotten too big and empty
* it.
@@ -161,6 +162,17 @@
}
/*
+ * Remove a dirent from the cache
+ */
+void gn_dirent_cache_remove(struct dirent *de)
+{
+ if(SEMAPHORE_DOWN(path_sema, YES) == SYSERR)
+ return;
+ g_hash_table_remove(path_hash, de->de_path);
+ SEMAPHORE_UP(path_sema);
+}
+
+/*
* Call 'cb' for each element in 'path', treats the empty string as "/"
*/
int gn_path_foreach(const gchar *path, gn_dir_foreach_callback cb, void *data)
Modified: gnunet-fuse/getattr.c
===================================================================
--- gnunet-fuse/getattr.c 2007-07-12 11:48:20 UTC (rev 5304)
+++ gnunet-fuse/getattr.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -27,7 +27,7 @@
int gn_getattr(const char *path, struct stat *stbuf)
{
struct dirent *de;
- guint64 size = 0;
+ int ret = 0;
GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG, "%s: for '%s'\n",
__FUNCTION__, path);
@@ -52,31 +52,35 @@
return -ENOENT;
}
- memset(stbuf, 0, sizeof(*stbuf));
- stbuf->st_mode = 0777;
- stbuf->st_mode |= de->de_type == DE_DIR ? S_IFDIR : S_IFREG;
- stbuf->st_nlink = 1;
+ /* If it's a cached file just call stat */
if(SEMAPHORE_DOWN(de->de_sema, YES) == SYSERR)
+ {
+ gn_dirent_put(de);
return -EIO;
- if(de->de_cached)
+ }
+ if(de->de_cached && de->de_type == DE_FILE)
{
- if(de->de_type == DE_FILE && disk_file_size(ectx,
- de->de_filename, &size, NO) == SYSERR)
+ ret = stat(path, stbuf);
+ if(ret == -1)
{
- GE_LOG(ectx, GE_BULK | GE_USER | GE_ERROR,
- "%s: disk_file_size failed for '%s'\n",
- __FUNCTION__, de->de_filename);
- SEMAPHORE_UP(de->de_sema);
- gn_dirent_put(de);
- return -EIO;
+ ret = -errno;
+ GE_LOG_STRERROR(ectx, GE_BULK | GE_USER | GE_ERROR,
+ "stat");
+ goto out;
}
+ goto out;
}
+
+ memset(stbuf, 0, sizeof(*stbuf));
+ stbuf->st_mode = 0777;
+ stbuf->st_mode |= de->de_type == DE_DIR ? S_IFDIR : S_IFREG;
+ stbuf->st_nlink = 1;
+ if(de->de_fi.uri != NULL)
+ stbuf->st_size = ECRS_fileSize(de->de_fi.uri);
else
- {
- size = ECRS_fileSize(de->de_fi.uri);
- }
+ stbuf->st_size = 0;
+out:
SEMAPHORE_UP(de->de_sema);
gn_dirent_put(de);
- stbuf->st_size = size;
- return 0;
+ return ret;
}
Modified: gnunet-fuse/gnfs.h
===================================================================
--- gnunet-fuse/gnfs.h 2007-07-12 11:48:20 UTC (rev 5304)
+++ gnunet-fuse/gnfs.h 2007-07-13 03:05:50 UTC (rev 5305)
@@ -87,7 +87,8 @@
void gn_dirent_ref(struct dirent *de);
void gn_dirent_put(struct dirent *de);
void gn_dirent_cache_init(void);
-void gn_dirent_cache(struct dirent *de);
+void gn_dirent_cache_insert(struct dirent *de);
+void gn_dirent_cache_remove(struct dirent *de);
struct dirent *gn_dirent_find(const gchar *path);
int gn_lock_path(struct dirent *de);
int gn_unlock_path(struct dirent *de, int dirty);
@@ -101,6 +102,7 @@
void *data);
struct dirent *gn_directory_find(struct dirent *de, const gchar *filename);
int gn_directory_insert(struct dirent *de, struct dirent *dechild);
+int gn_directory_remove(struct dirent *de, struct dirent *dechild);
int gn_directory_upload_locked(struct dirent *de);
/* FUSE function files */
@@ -108,6 +110,10 @@
int gn_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi);
int gn_mknod(const char *path, mode_t mode, dev_t rdev);
+int gn_mkdir(const char *path, mode_t mode);
+int gn_unlink(const char *path);
+int gn_rmdir(const char *path);
+int gn_utimens(const char *path, const struct timespec ts[2]);
int gn_open(const char *path, struct fuse_file_info *fi);
int gn_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi);
Modified: gnunet-fuse/main.c
===================================================================
--- gnunet-fuse/main.c 2007-07-12 11:48:20 UTC (rev 5304)
+++ gnunet-fuse/main.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -74,6 +74,10 @@
.getattr = gn_getattr,
.readdir = gn_readdir,
.mknod = gn_mknod,
+ .mkdir = gn_mkdir,
+ .unlink = gn_unlink,
+ .rmdir = gn_rmdir,
+ .utimens = gn_utimens,
.open = gn_open,
.read = gn_read,
.write = gn_write,
Added: gnunet-fuse/mkdir.c
===================================================================
--- gnunet-fuse/mkdir.c (rev 0)
+++ gnunet-fuse/mkdir.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -0,0 +1,71 @@
+/*
+ * mkdir.c - FUSE mkdir function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_mkdir(const char *path, mode_t mode)
+{
+ struct dirent *de, *newde;
+ struct ECRS_MetaData *meta;
+ char *parent, *file;
+ int ret;
+
+ (void)mode;
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ return -EEXIST;
+
+ /* Check for existing file */
+ de = gn_dirent_find(path);
+ if(de != NULL)
+ {
+ gn_dirent_put(de);
+ return -EEXIST;
+ }
+
+ /* Create new directory */
+ parent = gn_dirname(path, &file);
+ de = gn_dirent_find(parent);
+ if(de == NULL)
+ {
+ FREE(parent);
+ return -ENOENT;
+ }
+ meta = ECRS_createMetaData();
+ ECRS_addToMetaData(meta, EXTRACTOR_FILENAME, file);
+ ECRS_addToMetaData(meta, EXTRACTOR_MIMETYPE, GNUNET_DIRECTORY_MIME);
+ newde = gn_dirent_new(path, NULL, meta, DE_DIR);
+ ECRS_freeMetaData(meta);
+ ret = gn_directory_insert(de, newde);
+ gn_dirent_put(de);
+ gn_dirent_put(newde);
+ FREE(parent);
+ if(ret == -1)
+ return -EIO;
+ return 0;
+}
Modified: gnunet-fuse/mknod.c
===================================================================
--- gnunet-fuse/mknod.c 2007-07-12 11:48:20 UTC (rev 5304)
+++ gnunet-fuse/mknod.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -64,13 +64,13 @@
uri = ECRS_stringToUri(ectx, GN_EMPTY_FILE_URI);
meta = ECRS_createMetaData();
ECRS_addToMetaData(meta, EXTRACTOR_FILENAME, file);
+ FREE(parent);
newde = gn_dirent_new(path, uri, meta, DE_FILE);
ECRS_freeMetaData(meta);
ECRS_freeUri(uri);
ret = gn_directory_insert(de, newde);
gn_dirent_put(de);
gn_dirent_put(newde);
- FREE(parent);
if(ret == -1)
return -EIO;
return 0;
Modified: gnunet-fuse/read.c
===================================================================
--- gnunet-fuse/read.c 2007-07-12 11:48:20 UTC (rev 5304)
+++ gnunet-fuse/read.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -45,9 +45,18 @@
(void)completedBytes;
(void)eta;
- GE_ASSERT(ectx, !(block_end < d->offset));
- GE_ASSERT(ectx, !(lastBlockOffset > buf_end));
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG,
+ "%s: lastBlockOffset %llu lastBlockSize %d\n", __FUNCTION__,
+ lastBlockOffset, lastBlockSize);
+ /* Check if this block is entirely before the buffer */
+ if(block_end < d->offset)
+ return;
+
+ /* Check if this block is entirely after the buffer */
+ if(lastBlockOffset > buf_end)
+ return;
+
/* Chop off residue at beginning of block */
if(lastBlockOffset < d->offset)
{
@@ -83,7 +92,8 @@
(void)fi;
GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG,
- "%s: called for '%s' %d bytes\n", __FUNCTION__, path, size);
+ "%s: called for '%s' %u bytes %lld offset\n", __FUNCTION__,
+ path, size, offset);
/* Check for special file */
special = gn_get_special_file(path);
@@ -146,8 +156,14 @@
d.buf = buf;
d.size = size;
d.offset = offset;
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG,
+ "%s: calling ECRS_downloadPartialFile %u bytes %lld offset\n",
+ __FUNCTION__, size, offset);
ret = ECRS_downloadPartialFile(ectx, cfg, de->de_fi.uri, "/dev/null",
anonymity, offset, size, YES, dpcb, &d, tt, NULL);
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG,
+ "%s: ECRS_downloadPartialFile returned %d\n",
+ __FUNCTION__, ret);
if(ret != OK)
{
GE_LOG(ectx, GE_BULK | GE_USER | GE_ERROR,
Added: gnunet-fuse/rmdir.c
===================================================================
--- gnunet-fuse/rmdir.c (rev 0)
+++ gnunet-fuse/rmdir.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -0,0 +1,78 @@
+/*
+ * rmdir.c - FUSE rmdir function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+static gboolean rmdir_callback(struct dirent *de, void *data)
+{
+ int *empty = data;
+
+ (void)de;
+ *empty = 0;
+ return 1;
+}
+
+int gn_rmdir(const char *path)
+{
+ struct dirent *de, *dechild;
+ char *parent, *file;
+ int ret, empty = 1;
+
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ return -ENOTDIR;
+
+ /* Check for existing file */
+ dechild = gn_dirent_find(path);
+ if(dechild == NULL)
+ return -ENOENT;
+
+ /* Can't rmdir a non-empty directory */
+ gn_directory_foreach(dechild, rmdir_callback, &empty);
+ if(!empty)
+ {
+ gn_dirent_put(dechild);
+ return -ENOTEMPTY;
+ }
+
+ /* Remove directory */
+ parent = gn_dirname(path, &file);
+ de = gn_dirent_find(parent);
+ FREE(parent);
+ if(de == NULL)
+ {
+ gn_dirent_put(dechild);
+ return -ENOENT;
+ }
+ ret = gn_directory_remove(de, dechild);
+ gn_dirent_put(dechild);
+ gn_dirent_put(de);
+ if(ret == -1)
+ return -EIO;
+ return 0;
+}
Added: gnunet-fuse/unlink.c
===================================================================
--- gnunet-fuse/unlink.c (rev 0)
+++ gnunet-fuse/unlink.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -0,0 +1,68 @@
+/*
+ * unlink.c - FUSE unlink function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_unlink(const char *path)
+{
+ struct dirent *de, *dechild;
+ char *parent, *file;
+ int ret;
+
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check for special file */
+ if(gn_exists_special_file(path))
+ return -EPERM;
+
+ /* Check for existing file */
+ dechild = gn_dirent_find(path);
+ if(dechild == NULL)
+ return -ENOENT;
+
+ /* Can't unlink a directory */
+ if(dechild->de_type != DE_FILE)
+ {
+ gn_dirent_put(dechild);
+ return -EPERM;
+ }
+
+ /* Remove file from parent dir */
+ parent = gn_dirname(path, &file);
+ de = gn_dirent_find(parent);
+ FREE(parent);
+ if(de == NULL)
+ {
+ gn_dirent_put(dechild);
+ return -ENOENT;
+ }
+ ret = gn_directory_remove(de, dechild);
+ gn_dirent_put(dechild);
+ gn_dirent_put(de);
+ if(ret == -1)
+ return -EIO;
+ return 0;
+}
Added: gnunet-fuse/utimens.c
===================================================================
--- gnunet-fuse/utimens.c (rev 0)
+++ gnunet-fuse/utimens.c 2007-07-13 03:05:50 UTC (rev 5305)
@@ -0,0 +1,72 @@
+/*
+ * utimens.c - FUSE utimens function
+ *
+ * This file is part of gnunet-fuse.
+ * Copyright (C) 2007 David Barksdale
+ *
+ * gnunet-fuse is free software; you can redistribute it and/or
+ * modify if under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#define _GNU_SOURCE
+#include <sys/time.h>
+#include <string.h>
+#include <errno.h>
+#include <fuse.h>
+#include "gnfs.h"
+
+int gn_utimens(const char *path, const struct timespec ts[2])
+{
+ struct dirent *de;
+ struct timeval tv[2];
+ int ret = 0;
+
+ GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG, "%s: for '%s'\n",
+ __FUNCTION__, path);
+
+ /* Check to see if this is a special file */
+ if(gn_exists_special_file(path))
+ return -EACCES;
+
+ /* Get file or dir */
+ de = gn_dirent_find(path);
+ if(de == NULL)
+ return -ENOENT;
+
+ /* If it's a cached file just call utime */
+ if(SEMAPHORE_DOWN(de->de_sema, YES) == SYSERR)
+ {
+ gn_dirent_put(de);
+ return -EIO;
+ }
+ if(de->de_cached && de->de_type == DE_FILE)
+ {
+ TIMESPEC_TO_TIMEVAL(&tv[0], &ts[0]);
+ TIMESPEC_TO_TIMEVAL(&tv[1], &ts[1]);
+ ret = utimes(path, tv);
+ if(ret == -1)
+ {
+ ret = -errno;
+ GE_LOG_STRERROR(ectx, GE_BULK | GE_USER | GE_ERROR,
+ "utimes");
+ goto out;
+ }
+ goto out;
+ }
+
+ /* For now we do nothing otherwise */
+out:
+ SEMAPHORE_UP(de->de_sema);
+ gn_dirent_put(de);
+ return ret;
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r5305 - gnunet-fuse,
gnunet <=