There is no need to grab a local copy of the vnode information in the object
cache, as the callers can pass it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 sheep/object_cache.c |   33 ++++++++++++++++-----------------
 sheep/ops.c          |   11 +++++++++--
 sheep/sheep_priv.h   |    8 +++++---
 sheep/store.c        |    9 +++++----
 4 files changed, 35 insertions(+), 26 deletions(-)

Index: sheepdog/sheep/object_cache.c
===================================================================
--- sheepdog.orig/sheep/object_cache.c	2012-05-17 07:02:45.011994743 +0200
+++ sheepdog/sheep/object_cache.c	2012-05-17 09:47:26.723991325 +0200
@@ -397,16 +397,16 @@ out:
 }
 
 /* Fetch the object, cache it in success */
-int object_cache_pull(struct object_cache *oc, uint32_t idx)
+int object_cache_pull(struct vnode_info *vnode_info, struct object_cache *oc,
+		uint32_t idx)
 {
 	int i, fd, ret = SD_RES_NO_MEM;
 	unsigned wlen = 0, rlen, data_length, read_len;
 	uint64_t oid;
 	struct sd_obj_req hdr = { 0 };
 	struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
-	struct vnode_info *vnodes = get_vnode_info();
 	struct sd_vnode *v;
-	struct sd_vnode *obj_vnodes[SD_MAX_COPIES];
+	struct sd_vnode *vnodes[SD_MAX_COPIES];
 	void *buf;
 	int nr_copies;
 
@@ -425,11 +425,11 @@ int object_cache_pull(struct object_cach
 	}
 
 	/* Check if we can read locally */
-	nr_copies = get_nr_copies(vnodes);
-	oid_to_vnodes(vnodes, oid, nr_copies, obj_vnodes);
+	nr_copies = get_nr_copies(vnode_info);
+	oid_to_vnodes(vnode_info, oid, nr_copies, vnodes);
 
 	for (i = 0; i < nr_copies; i++) {
-		v = obj_vnodes[i];
+		v = vnodes[i];
 		if (vnode_is_local(v)) {
 			struct siocb iocb = { 0 };
 			iocb.epoch = sys->epoch;
@@ -454,7 +454,7 @@ int object_cache_pull(struct object_cach
 pull_remote:
 	/* Okay, no luck, let's read remotely */
 	for (i = 0; i < nr_copies; i++) {
-		v = obj_vnodes[i];
+		v = vnodes[i];
 
 		if (vnode_is_local(v))
 			continue;
@@ -488,7 +488,6 @@ out:
 	if (ret == SD_RES_SUCCESS)
 		ret = create_cache_object(oc, idx, buf, read_len);
 	free(buf);
-	put_vnode_info(vnodes);
 	return ret;
 }
 
@@ -500,8 +499,8 @@ static uint64_t idx_to_oid(uint32_t vid,
 		return vid_to_data_oid(vid, idx);
 }
 
-static int push_cache_object(uint32_t vid, uint32_t idx,
-		uint64_t bmap, int create)
+static int push_cache_object(struct vnode_info *vnode_info, uint32_t vid,
+		uint32_t idx, uint64_t bmap, int create)
 {
 	struct request fake_req;
 	struct sd_obj_req *hdr = (struct sd_obj_req *)&fake_req.rq;
@@ -555,21 +554,19 @@ static int push_cache_object(uint32_t vi
 	hdr->epoch = sys->epoch;
 	fake_req.data = buf;
 	fake_req.op = get_sd_op(hdr->opcode);
-	fake_req.vnodes = get_vnode_info();
+	fake_req.vnodes = vnode_info;
 
 	ret = forward_write_obj_req(&fake_req);
 	if (ret != SD_RES_SUCCESS)
 		eprintf("failed to push object %x\n", ret);
 
-	put_vnode_info(fake_req.vnodes);
-
 out:
 	free(buf);
 	return ret;
 }
 
 /* Push back all the dirty objects to sheep cluster storage */
-int object_cache_push(struct object_cache *oc)
+int object_cache_push(struct vnode_info *vnode_info, struct object_cache *oc)
 {
 	struct object_cache_entry *entry, *t;
 	struct rb_root *inactive_dirty_tree;
@@ -589,7 +586,7 @@ int object_cache_push(struct object_cach
 	 * request is issued in one of gateway worker threads
 	 * So we need not to protect inactive dirty tree and list */
 	list_for_each_entry_safe(entry, t, inactive_dirty_list, list) {
-		ret = push_cache_object(oc->vid, entry->idx,
+		ret = push_cache_object(vnode_info, oc->vid, entry->idx,
 				entry->bmap, entry->create);
 		if (ret != SD_RES_SUCCESS)
 			goto push_failed;
@@ -652,7 +649,8 @@ void object_cache_delete(uint32_t vid)
 
 }
 
-int object_cache_flush_and_delete(struct object_cache *oc)
+int object_cache_flush_and_delete(struct vnode_info *vnode_info,
+		struct object_cache *oc)
 {
 	DIR *dir;
 	struct dirent *d;
@@ -680,7 +678,8 @@ int object_cache_flush_and_delete(struct
 		idx = strtoul(d->d_name, NULL, 16);
 		if (idx == ULLONG_MAX)
 			continue;
-		if (push_cache_object(vid, idx, all, 1) != SD_RES_SUCCESS) {
+		if (push_cache_object(vnode_info, vid, idx, all, 1) !=
+				SD_RES_SUCCESS) {
 			dprintf("failed to push %"PRIx64"\n",
 				idx_to_oid(vid, idx));
 			ret = -1;
Index: sheepdog/sheep/ops.c
===================================================================
--- sheepdog.orig/sheep/ops.c	2012-05-17 09:41:06.000000000 +0200
+++ sheepdog/sheep/ops.c	2012-05-17 09:47:26.723991325 +0200
@@ -60,6 +60,7 @@ struct sd_op_template {
 
 struct flush_work {
 	struct object_cache *cache;
+	struct vnode_info *vnode_info;
 	struct work work;
 };
 
@@ -574,14 +575,17 @@ static void flush_vdi_fn(struct work *wo
 	struct flush_work *fw = container_of(work, struct flush_work, work);
 
 	dprintf("flush vdi %"PRIx32"\n", fw->cache->vid);
-	if (object_cache_push(fw->cache) != SD_RES_SUCCESS)
+	if (object_cache_push(fw->vnode_info, fw->cache) != SD_RES_SUCCESS)
 		eprintf("failed to flush vdi %"PRIx32"\n", fw->cache->vid);
 }
 
 static void flush_vdi_done(struct work *work)
 {
 	struct flush_work *fw = container_of(work, struct flush_work, work);
+
 	dprintf("flush vdi %"PRIx32" done\n", fw->cache->vid);
+
+	put_vnode_info(fw->vnode_info);
 	free(fw);
 }
 
@@ -598,12 +602,15 @@ static int local_flush_vdi(struct reques
 	cache = find_object_cache(vid, 0);
 	if (cache) {
 		if (!sys->async_flush)
-			return object_cache_push(cache);
+			return object_cache_push(req->vnodes, cache);
 		else {
 			struct flush_work *fw = xmalloc(sizeof(*fw));
+
 			fw->work.fn = flush_vdi_fn;
 			fw->work.done = flush_vdi_done;
 			fw->cache = cache;
+			fw->vnode_info = grab_vnode_info(req->vnodes);
+
 			queue_work(sys->flush_wqueue, &fw->work);
 		}
 	}
Index: sheepdog/sheep/sheep_priv.h
===================================================================
--- sheepdog.orig/sheep/sheep_priv.h	2012-05-17 09:41:06.000000000 +0200
+++ sheepdog/sheep/sheep_priv.h	2012-05-17 09:47:26.723991325 +0200
@@ -444,11 +444,13 @@ struct object_cache_entry {
 struct object_cache *find_object_cache(uint32_t vid, int create);
 int object_cache_lookup(struct object_cache *oc, uint32_t index, int create);
 int object_cache_rw(struct object_cache *oc, uint32_t idx, struct request *);
-int object_cache_pull(struct object_cache *oc, uint32_t index);
-int object_cache_push(struct object_cache *oc);
+int object_cache_pull(struct vnode_info *vnode_info, struct object_cache *oc,
+		uint32_t index);
+int object_cache_push(struct vnode_info *vnode_info, struct object_cache *oc);
 int object_cache_init(const char *p);
 int object_is_cached(uint64_t oid);
 void object_cache_delete(uint32_t vid);
-int object_cache_flush_and_delete(struct object_cache *oc);
+int object_cache_flush_and_delete(struct vnode_info *vnode_info,
+		struct object_cache *oc);
 
 #endif
Index: sheepdog/sheep/store.c
===================================================================
--- sheepdog.orig/sheep/store.c	2012-05-17 09:40:22.000000000 +0200
+++ sheepdog/sheep/store.c	2012-05-17 09:47:44.163991160 +0200
@@ -367,15 +367,16 @@ static int handle_gateway_request(struct
 		create = 1;
 
 	if (object_cache_lookup(cache, idx, create) < 0) {
-		ret = object_cache_pull(cache, idx);
+		ret = object_cache_pull(req->vnodes, cache, idx);
 		if (ret != SD_RES_SUCCESS)
 			return ret;
 	}
 	return object_cache_rw(cache, idx, req);
 }
 
-static int bypass_object_cache(struct sd_obj_req *hdr)
+static int bypass_object_cache(struct request *req)
 {
+	struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
 	uint64_t oid = hdr->oid;
 
 	if (!(hdr->flags & SD_FLAG_CMD_CACHE)) {
@@ -386,7 +387,7 @@ static int bypass_object_cache(struct sd
 		if (!cache)
 			return 1;
 		if (hdr->flags & SD_FLAG_CMD_WRITE) {
-			object_cache_flush_and_delete(cache);
+			object_cache_flush_and_delete(req->vnodes, cache);
 			return 1;
 		} else  {
 			/* For read requet, we can read cache if any */
@@ -428,7 +429,7 @@ void do_io_request(struct work *work)
 	if (hdr->flags & SD_FLAG_CMD_IO_LOCAL) {
 		ret = do_local_io(req, epoch);
 	} else {
-		if (!sys->enable_write_cache || bypass_object_cache(hdr)) {
+		if (!sys->enable_write_cache || bypass_object_cache(req)) {
 			/* fix object consistency when we read the object for the first time */
 			if (req->check_consistency) {
 				ret = fix_object_consistency(req);


