gnunet-fuse

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

commit 90989f282e9fa2d866783daa04730d235b8e6aea
parent 7af3b5fb8574b3fe7b7d138458b13c9501d21b93
Author: David Barksdale <amatus.amongus@gmail.com>
Date:   Thu, 19 Jul 2007 05:02:53 +0000

Added file truncation support

Diffstat:
MMakefile.am | 1+
Mgetattr.c | 2+-
Mgnfs.h | 1+
Mmain.c | 1+
Atruncate.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am @@ -13,6 +13,7 @@ gnunet_fs_SOURCES = \ rename.c \ rmdir.c \ special_file.c \ + truncate.c \ unlink.c \ utimens.c \ write.c \ diff --git a/getattr.c b/getattr.c @@ -60,7 +60,7 @@ int gn_getattr(const char *path, struct stat *stbuf) } if(de->de_cached && de->de_type == DE_FILE) { - ret = stat(path, stbuf); + ret = stat(de->de_filename, stbuf); if(ret == -1) { ret = -errno; diff --git a/gnfs.h b/gnfs.h @@ -119,6 +119,7 @@ int gn_mkdir(const char *path, mode_t mode); int gn_unlink(const char *path); int gn_rmdir(const char *path); int gn_rename(const char *from, const char *to); +int gn_truncate(const char *path, off_t size); 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, diff --git a/main.c b/main.c @@ -78,6 +78,7 @@ static struct fuse_operations fops = .unlink = gn_unlink, .rmdir = gn_rmdir, .rename = gn_rename, + .truncate = gn_truncate, .utimens = gn_utimens, .open = gn_open, .read = gn_read, diff --git a/truncate.c b/truncate.c @@ -0,0 +1,84 @@ +/* + * truncate.c - FUSE truncate 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 <errno.h> +#include <unistd.h> +#include <fuse.h> +#include "gnfs.h" + +int gn_truncate(const char *path, off_t size) +{ + struct dirent *de; + int ret = 0; + + GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG, + "%s: called for '%s' %lld bytes\n", __FUNCTION__, path, size); + + /* Check for special file */ + if(gn_exists_special_file(path)) + return -EACCES; + + /* Lookup dirent for path */ + de = gn_dirent_find(path); + if(de == NULL) + { + GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG, + "%s: file not found\n", __FUNCTION__); + return -ENOENT; + } + if(de->de_type != DE_FILE) + { + GE_LOG(ectx, GE_BULK | GE_DEVELOPER | GE_DEBUG, + "%s: not a file\n", __FUNCTION__); + ret = -EISDIR; + goto out; + } + + /* We must be cached */ + if(SEMAPHORE_DOWN(de->de_sema, YES) == SYSERR) + { + ret = -EIO; + goto out; + } + if(!de->de_cached) + { + if(gn_dirent_download_locked(de) == -1) + { + ret = -EIO; + goto out_unlock; + } + } + + /* Perform truncate */ + ret = ftruncate(de->de_fd, size); + if(ret == -1) + { + ret = -errno; + goto out_unlock; + } + + /* Mark us dirty */ + de->de_dirty = 1; +out_unlock: + SEMAPHORE_UP(de->de_sema); +out: + gn_dirent_put(de); + return ret; +}