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 |