At Wed, 21 Dec 2011 16:48:26 +0800, Liu Yuan wrote: > > From: Liu Yuan <tailai.ly at taobao.com> > > In recovery, sheep needs to atomically write the object to the store > that is being recovered. This operation assume underlying store layout, > so we need to abstract it out. > > Signed-off-by: Liu Yuan <tailai.ly at taobao.com> > --- > sheep/sheep_priv.h | 1 + > sheep/simple_store.c | 41 +++++++++++++++++++++++++++++++++++++++++ > sheep/store.c | 36 ++++++------------------------------ > 3 files changed, 48 insertions(+), 30 deletions(-) > > diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h > index 29ffd74..8a39d1b 100644 > --- a/sheep/sheep_priv.h > +++ b/sheep/sheep_priv.h > @@ -175,6 +175,7 @@ struct store_driver { > /* Operations in recovery */ > int (*get_objlist)(struct siocb *); > int (*link)(uint64_t oid, struct siocb *, int tgt_epoch); > + int (*atomic_put)(uint64_t oid, struct siocb *); > }; > > extern void register_store_driver(struct store_driver *); > diff --git a/sheep/simple_store.c b/sheep/simple_store.c > index 36c45b3..ec77a8d 100644 > --- a/sheep/simple_store.c > +++ b/sheep/simple_store.c > @@ -198,6 +198,46 @@ static int simple_store_link(uint64_t oid, struct siocb *iocb, int tgt_epoch) > return SD_RES_EIO; > } > > +static int simple_store_atomic_put(uint64_t oid, struct siocb *iocb) > +{ > + char path[PATH_MAX], tmp_path[PATH_MAX]; > + int flags = O_DSYNC | O_RDWR | O_CREAT; > + int ret = SD_RES_EIO, epoch = iocb->epoch, fd; > + uint32_t len = iocb->length; > + > + snprintf(path, sizeof(path), "%s%08u/%016" PRIx64, obj_path, > + epoch, oid); > + snprintf(tmp_path, sizeof(tmp_path), "%s%08u/%016" PRIx64 ".tmp", > + obj_path, epoch, oid); > + > + fd = open(tmp_path, flags, def_fmode); > + if (fd < 0) { > + eprintf("failed to open %s: %m\n", tmp_path); > + goto out; > + } > + > + ret = write(fd, iocb->buf, len); > + if (ret != len) { > + eprintf("failed to write object. %m\n"); > + ret = SD_RES_EIO; > + goto out_close; > + } > + > + > + ret = rename(tmp_path, path); > + if (ret < 0) { > + eprintf("failed to rename %s to %s: %m\n", tmp_path, path); > + ret = SD_RES_EIO; > + goto out_close; > + } > + dprintf("%"PRIx64"\n", oid); > + ret = SD_RES_SUCCESS; > +out_close: > + close(fd); > +out: > + return ret; > +} > + > struct store_driver store = { > .driver_name = "simple", > .init = simple_store_init, > @@ -207,6 +247,7 @@ struct store_driver store = { > .close = simple_store_close, > .get_objlist = simple_store_get_objlist, > .link = simple_store_link, > + .atomic_put = simple_store_atomic_put, > }; > > void register_store_driver(struct store_driver *driver) > diff --git a/sheep/store.c b/sheep/store.c > index 4adae51..8c857f9 100644 > --- a/sheep/store.c > +++ b/sheep/store.c > @@ -1186,6 +1186,7 @@ static int recover_object_from_replica(uint64_t oid, > unsigned wlen = 0, rlen; > int fd, ret; > void *buf; > + struct siocb iocb = { 0 }; > > buf = alloc_buffer_for(oid); > if (!buf) { > @@ -1194,8 +1195,6 @@ static int recover_object_from_replica(uint64_t oid, > } > > if (is_myself(entry->addr, entry->port)) { > - struct siocb iocb = { 0 }; > - > iocb.epoch = epoch; > ret = store.link(oid, &iocb, tgt_epoch); > if (ret == SD_RES_SUCCESS) { > @@ -1242,34 +1241,11 @@ static int recover_object_from_replica(uint64_t oid, > rsp = (struct sd_obj_rsp *)&hdr; > > if (rsp->result == SD_RES_SUCCESS) { > - char path[PATH_MAX], tmp_path[PATH_MAX]; > - int flags = O_DSYNC | O_RDWR | O_CREAT; > - > - snprintf(path, sizeof(path), "%s%08u/%016" PRIx64, obj_path, > - epoch, oid); > - snprintf(tmp_path, sizeof(tmp_path), "%s%08u/%016" PRIx64 ".tmp", > - obj_path, epoch, oid); > - > - fd = open(tmp_path, flags, def_fmode); > - if (fd < 0) { > - eprintf("failed to open %s: %m\n", tmp_path); > - ret = -1; > - goto out; > - } > - > - ret = write(fd, buf, rlen); > - if (ret != rlen) { > - eprintf("failed to write object\n"); > - ret = -1; > - goto out; > - } > - > - close(fd); > - > - dprintf("rename %s to %s\n", tmp_path, path); > - ret = rename(tmp_path, path); > - if (ret < 0) { > - eprintf("failed to rename %s to %s: %m\n", tmp_path, path); > + iocb.epoch = epoch; > + iocb.length = rlen; > + iocb.buf = buf; > + ret = store.atomic_put(oid, &iocb); > + if (ret!= SD_RES_SUCCESS) { Missing a space before '!='. I've applied after fixing this. Thanks, Kazutaka |