[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