[sheepdog] [PATCH v3 14/15] sheepfs: teach volume to read/write COW objects
Liu Yuan
namei.unix at gmail.com
Mon May 21 17:25:58 CEST 2012
From: Liu Yuan <tailai.ly at taobao.com>
Now we can opreate on the volume with cloned vdi, for e.g, we can boot up vdi
named of 'clone' by below command:
$ qemu-system-x86_64 --enable-kvm -m 1024 -drive \
file=sheepfs_dir/volume/clone,cache=writeback
tailai.ly at taobao:~/sheepdog$ cat sheepfs_dir/vdi/list
Name Id Size Used Shared Creation time VDI id Tag
c clone 1 20 MB 0.0 MB 20 MB 2012-05-14 12:01 72a1e2
s test1 1 20 MB 20 MB 0.0 MB 2012-05-14 11:57 fd32fc snap
test1 2 20 MB 0.0 MB 20 MB 2012-05-14 11:58 fd32fd
- add an option to disable 'object cache' for volumes
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
sheepfs/core.c | 8 +++++++-
sheepfs/sheepfs.h | 1 +
sheepfs/volume.c | 22 +++++++++++++++++++---
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/sheepfs/core.c b/sheepfs/core.c
index 5bd96ac..06ba346 100644
--- a/sheepfs/core.c
+++ b/sheepfs/core.c
@@ -34,6 +34,7 @@ char sheepfs_shadow[PATH_MAX];
static int sheepfs_debug;
static int sheepfs_fg;
int sheepfs_page_cache = 0;
+int sheepfs_object_cache = 1;
const char *sdhost = "localhost";
int sdport = SD_LISTEN_PORT;
@@ -43,11 +44,12 @@ static struct option const long_options[] = {
{"help", no_argument, NULL, 'h'},
{"foreground", no_argument, NULL, 'f'},
{"pagecache", no_argument, NULL, 'k'},
+ {"no-object-cache", no_argument, NULL, 'n'},
{"port", required_argument, NULL, 'p'},
{NULL, 0, NULL, 0},
};
-static const char *short_options = "a:dfhkp:";
+static const char *short_options = "a:dfhknp:";
static struct sheepfs_file_operation {
int (*read)(const char *path, char *buf, size_t size, off_t);
@@ -264,6 +266,7 @@ Options:\n\
-d, --debug enable debug output (implies -f)\n\
-f, --foreground sheepfs run in the foreground\n\
-k, --pagecache use local kernel's page cache to access volume\n\
+ -n --no-object-cache disable object cache of the attached volumes\n\
-p --port specify the sheep port (default: 7000)\n\
-h, --help display this help and exit\n\
");
@@ -295,6 +298,9 @@ int main(int argc, char **argv)
case 'k':
sheepfs_page_cache = 1;
break;
+ case 'n':
+ sheepfs_object_cache = 0;
+ break;
case 'p':
sdport = strtol(optarg, NULL, 10);
if (sdport < 1 || sdport > UINT16_MAX) {
diff --git a/sheepfs/sheepfs.h b/sheepfs/sheepfs.h
index c17ec55..e1ed8ae 100644
--- a/sheepfs/sheepfs.h
+++ b/sheepfs/sheepfs.h
@@ -18,6 +18,7 @@ enum sheepfs_opcode {
extern char sheepfs_shadow[];
extern int sheepfs_page_cache;
+extern int sheepfs_object_cache;
extern const char *sdhost;
extern int sdport;
diff --git a/sheepfs/volume.c b/sheepfs/volume.c
index d56fcd1..fcd9bb2 100644
--- a/sheepfs/volume.c
+++ b/sheepfs/volume.c
@@ -145,6 +145,7 @@ static int volume_rw_object(char *buf, uint64_t oid, size_t size,
uint32_t vid = oid_to_vid(oid);
struct vdi_inode *vdi;
unsigned long idx = 0;
+ uint64_t cow_oid = 0;
pthread_rwlock_rdlock(&vdi_inode_tree_lock);
vdi = vdi_inode_tree_search(vid);
@@ -165,6 +166,19 @@ static int volume_rw_object(char *buf, uint64_t oid, size_t size,
goto done;
}
create = 1;
+ } else {
+ if (rw == VOLUME_READ) {
+ oid = vid_to_data_oid(
+ vdi->inode->data_vdi_id[idx],
+ idx);
+ /* in case we are writing a COW object */
+ } else if (!is_data_obj_writeable(vdi->inode, idx)) {
+ cow_oid = vid_to_data_oid(
+ vdi->inode->data_vdi_id[idx],
+ idx);
+ hdr.flags |= SD_FLAG_CMD_COW;
+ create = 1;
+ }
}
}
@@ -180,8 +194,10 @@ static int volume_rw_object(char *buf, uint64_t oid, size_t size,
hdr.obj.oid = oid;
hdr.obj.offset = off;
+ hdr.obj.cow_oid = cow_oid;
hdr.data_length = size;
- hdr.flags |= SD_FLAG_CMD_CACHE;
+ if (sheepfs_object_cache)
+ hdr.flags |= SD_FLAG_CMD_CACHE;
fd = get_socket_fd(vdi, &sock_idx);
ret = exec_req(fd, &hdr, buf, &wlen, &rlen);
@@ -311,7 +327,7 @@ int volume_sync(const char *path)
if (shadow_file_getxattr(path, SH_VID_NAME, &vid, SH_VID_SIZE) < 0)
return -EIO;
- if (volume_do_sync(vid) < 0)
+ if (sheepfs_object_cache && volume_do_sync(vid) < 0)
return -EIO;
return 0;
@@ -491,7 +507,7 @@ int volume_remove_entry(const char *entry)
if (shadow_file_getxattr(path, SH_VID_NAME, &vid, SH_VID_SIZE) < 0)
return -1;
- if (volume_sync_and_delete(vid) < 0)
+ if (sheepfs_object_cache && volume_sync_and_delete(vid) < 0)
return -1;
pthread_rwlock_rdlock(&vdi_inode_tree_lock);
--
1.7.10.2
More information about the sheepdog
mailing list