On 04/13/2012 10:25 AM, yaohaiting.wujue at gmail.com wrote: > From: HaiTing Yao <wujue.yht at taobao.com> > > When create snapshot, write inode of base VDI internally without care of > cache. Then the inode in cache may be wrong from disk > > Signed-off-by: HaiTing Yao <wujue.yht at taobao.com> > --- > sheep/sdnet.c | 12 +++++++++--- > sheep/sheep_priv.h | 3 +++ > sheep/store.c | 39 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 51 insertions(+), 3 deletions(-) > > diff --git a/sheep/sdnet.c b/sheep/sdnet.c > index 5db9f29..d21c12e 100644 > --- a/sheep/sdnet.c > +++ b/sheep/sdnet.c > @@ -623,20 +623,26 @@ int write_object(struct sd_vnode *e, > uint64_t offset, uint16_t flags, int nr, int create) > { > struct sd_obj_req hdr; > - int i, n, fd, ret; > + int i, n, fd, ret, local = -1; > char name[128]; > + uint32_t vid = oid_to_vid(oid); > > if (nr > zones) > nr = zones; > > + if (object_is_cached(oid)) > + local = write_inode_cache(oid, data, datalen, offset, > + flags, nr, node_version, create); > + > for (i = 0; i < nr; i++) { > unsigned rlen = 0, wlen = datalen; > > n = obj_to_sheep(e, vnodes, oid, i); > > if (is_myself(e[n].addr, e[n].port)) { > - ret = write_object_local(oid, data, datalen, offset, > - flags, nr, node_version, create); > + if (local) > + ret = write_object_local(oid, data, datalen, offset, > + flags, nr, node_version, create); > > if (ret != 0) { > eprintf("fail %"PRIx64" %"PRIx32"\n", oid, ret); > diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h > index a9e8440..7fc7c0b 100644 > --- a/sheep/sheep_priv.h > +++ b/sheep/sheep_priv.h > @@ -248,6 +248,9 @@ void do_io_request(struct work *work); > int write_object_local(uint64_t oid, char *data, unsigned int datalen, > uint64_t offset, uint16_t flags, int copies, > uint32_t epoch, int create); > +int write_inode_cache(uint64_t oid, char *data, unsigned int datalen, > + uint64_t offset, uint16_t flags, int copies, > + uint32_t epoch, int create); > int read_object_local(uint64_t oid, char *data, unsigned int datalen, > uint64_t offset, int copies, uint32_t epoch); > int forward_write_obj_req(struct request *req); > diff --git a/sheep/store.c b/sheep/store.c > index 739862c..e226898 100644 > --- a/sheep/store.c > +++ b/sheep/store.c > @@ -551,6 +551,45 @@ int write_object_local(uint64_t oid, char *data, unsigned int datalen, > return ret; > } > > +int write_inode_cache(uint64_t oid, char *data, unsigned int datalen, > + uint64_t offset, uint16_t flags, int copies, > + uint32_t epoch, int create) > +{ > + int ret; > + struct request *req; > + struct sd_obj_req *hdr; > + uint32_t vid = oid_to_vid(oid); > + uint32_t idx = data_oid_to_idx(oid); > + struct object_cache *cache; > + > + idx |= 1 << CACHE_VDI_SHIFT; > + > + cache = find_object_cache(vid, 1); > + > + req = zalloc(sizeof(*req)); > + if (!req) > + return SD_RES_NO_MEM; > + hdr = (struct sd_obj_req *)&req->rq; > + > + hdr->oid = oid; > + if (create) > + hdr->opcode = SD_OP_CREATE_AND_WRITE_OBJ; > + else > + hdr->opcode = SD_OP_WRITE_OBJ; > + hdr->copies = copies; > + hdr->flags = flags | SD_FLAG_CMD_WRITE; > + hdr->offset = offset; > + hdr->data_length = datalen; > + req->data = data; > + req->op = get_sd_op(hdr->opcode); > + > + ret = object_cache_rw(cache, idx, req); > + > + free(req); > + > + return ret; > +} > + > int read_object_local(uint64_t oid, char *data, unsigned int datalen, > uint64_t offset, int copies, uint32_t epoch) > { I think we need to fix qemu-img firstly for creation, conversion and snapshot operation. After that, let's see if there is problem inside sheep. Thanks, Yuan |