From: Liu Yuan <tailai.ly at taobao.com> Sheepfs use this shadow file mechanism to mostly manage dentries. We might also make use of those shadow file to cache non-volatile states. Signed-off-by: Liu Yuan <tailai.ly at taobao.com> --- sheepfs/Makefile.am | 2 +- sheepfs/shadow_file.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++ sheepfs/sheepfs.h | 12 ++++ 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 sheepfs/shadow_file.c diff --git a/sheepfs/Makefile.am b/sheepfs/Makefile.am index 17ac0fe..f6201a6 100644 --- a/sheepfs/Makefile.am +++ b/sheepfs/Makefile.am @@ -23,7 +23,7 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include sbin_PROGRAMS = sheepfs -sheepfs_SOURCES = core.c cluster.c vdi.c +sheepfs_SOURCES = core.c cluster.c vdi.c shadow_file.c sheepfs_LDADD = ../lib/libsheepdog.a $(fuse_LIBS) $(LIBS) sheepfs_DEPENDENCIES = ../lib/libsheepdog.a diff --git a/sheepfs/shadow_file.c b/sheepfs/shadow_file.c new file mode 100644 index 0000000..033d4be --- /dev/null +++ b/sheepfs/shadow_file.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2012 Taobao Inc. + * + * Liu Yuan <namei.unix at gmail.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Sheepfs use this shadow file mechanism to mostly manage dentries. We + * might also make use of those shadow file to cache non-volatile states. + */ +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <attr/xattr.h> +#include <syslog.h> +#include <stdlib.h> + +#include "util.h" +#include "sheepfs.h" + +int shadow_file_read(const char *path, char *buf, size_t size, off_t offset) +{ + char p[PATH_MAX]; + int fd, len; + + sprintf(p, "%s%s", sheepfs_shadow, path); + fd = open(p, O_RDONLY); + if (fd < 0) { + syslog(LOG_ERR, "[%s] %m\n", __func__); + return -errno; + } + len = xpread(fd, buf, size, offset); + close(fd); + return len; +} + +size_t shadow_file_write(const char *path, char *buf, size_t size) +{ + char p[PATH_MAX]; + int fd; + size_t len = 0; + + sprintf(p, "%s%s", sheepfs_shadow, path); + fd = open(p, O_WRONLY | O_TRUNC); + if (fd < 0) { + syslog(LOG_ERR, "[%s] %m\n", __func__); + return 0; + } + len = xwrite(fd, buf, size); + if (len != size) { + syslog(LOG_ERR, "[%s] failed to write\n", __func__); + len = 0; + } + close(fd); + return len; +} + +int shadow_file_create(const char *path) +{ + char p[PATH_MAX]; + int fd; + sprintf(p, "%s%s", sheepfs_shadow, path); + fd = creat(p, 0644); + if (fd < 0) { + if (errno != EEXIST) { + syslog(LOG_ERR, "[%s] %m\n", __func__); + return -1; + } + } + close(fd); + return 0; +} + +int shadow_dir_create(const char *path) +{ + char p[PATH_MAX]; + + sprintf(p, "%s%s", sheepfs_shadow, path); + if (mkdir(p, 0755) < 0) { + if (errno != EEXIST) { + syslog(LOG_ERR, "[%s] %m\n", __func__); + return -1; + } + } + return 0; +} + +int shadow_file_setxattr(const char *path, const char *name, + const void *value, size_t size) +{ + char p[PATH_MAX]; + + sprintf(p, "%s%s", sheepfs_shadow, path); + if (setxattr(p, name, value, size, 0) < 0) { + syslog(LOG_ERR, "[%s] %m\n", __func__); + return -1; + } + return 0; +} + +int shadow_file_getxattr(const char *path, const char *name, + void *value, size_t size) +{ + char p[PATH_MAX]; + + sprintf(p, "%s%s", sheepfs_shadow, path); + if (getxattr(p, name, value, size) < 0) { + syslog(LOG_ERR, "[%s] %m\n", __func__); + return -1; + } + return 0; +} + +int shadow_file_delete(const char *path) +{ + char p[PATH_MAX]; + + sprintf(p, "%s%s", sheepfs_shadow, path); + if (unlink(p) < 0) { + if (errno != ENOENT) { + syslog(LOG_ERR, "[%s] %m\n", __func__); + return -1; + } + } + return 0; +} + +int shadow_file_exsit(const char *path) +{ + char p[PATH_MAX]; + + sprintf(p, "%s%s", sheepfs_shadow, path); + if (access(p, R_OK | W_OK) < 0) { + if (errno != ENOENT) + syslog(LOG_ERR, "[%s] %m\n", __func__); + return 0; + } + + return 1; +} diff --git a/sheepfs/sheepfs.h b/sheepfs/sheepfs.h index 4b20807..48f3dbc 100644 --- a/sheepfs/sheepfs.h +++ b/sheepfs/sheepfs.h @@ -13,6 +13,18 @@ extern char sheepfs_shadow[]; extern struct strbuf *sheepfs_run_cmd(const char *command); extern int sheepfs_set_op(const char *path, unsigned opcode); +/* shadow_file.c */ +extern size_t shadow_file_write(const char *path, char *buf, size_t size); +extern int shadow_file_read(const char *, char *buf, size_t size, off_t); +extern int shadow_dir_create(const char *path); +extern int shadow_file_create(const char *path); +extern int shadow_file_setxattr(const char *path, const char *name, + const void *value, size_t size); +extern int shadow_file_getxattr(const char *path, const char *name, + void *value, size_t size); +extern int shadow_file_delete(const char *path); +extern int shadow_file_exsit(const char *path); + /* cluster.c */ extern int cluster_info_read(const char *path, char *buf, size_t size, off_t); extern size_t cluster_info_get_size(const char *path); -- 1.7.10.2 |