void nfs3_reply(struct xid_map *xm, struct tuple4 *addr, u_char *buf, int len) { XDR xdrs; struct LOOKUP3res lres; struct READ3res rres; switch (xm->proc) { case NFSPROC3_LOOKUP: xdrmem_create(&xdrs, buf, len, XDR_DECODE); memset(&lres, 0, sizeof(lres)); if (xdr_LOOKUP3res(&xdrs, &lres)) { if (lres.status == NFS3_OK) { fh_map_add((char *)xm->data, lres.LOOKUP3res_u.resok.object.data.data_val, lres.LOOKUP3res_u.resok.object.data.data_len); } } xdr_destroy(&xdrs); break; case NFSPROC3_READ: xdrmem_create(&xdrs, buf, len, XDR_DECODE); memset(&rres, 0, sizeof(rres)); if (xdr_READ3res(&xdrs, &rres)) { if (rres.status == NFS3_OK) { nfs_save(addr, (struct myreadargs *)xm->data, rres.READ3res_u.resok.data.data_val, rres.READ3res_u.resok.data.data_len); } } xdr_destroy(&xdrs); break; } }
LOOKUP3res * xdr_to_LOOKUP3res(char *msg, int len) { XDR xdr; LOOKUP3res *lres = NULL; if(msg == NULL) return NULL; xdrmem_create(&xdr, msg, len, XDR_DECODE); lres = (LOOKUP3res *)mem_alloc(sizeof(LOOKUP3res)); if(lres == NULL) return NULL; lres->LOOKUP3res_u.resok.object.data.data_val = NULL; if(!xdr_LOOKUP3res(&xdr, lres)) { mem_free(lres, sizeof(LOOKUP3res)); return NULL; } return lres; }
static void lookup_callback (void *arg, struct nfs_client *client, LOOKUP3res *result) { LOOKUP3resok *resok = &result->LOOKUP3res_u.resok; err_t r; struct http_cache_entry *e = arg; DEBUGPRINT ("inside lookup_callback_file for file %s\n", e->name); assert(result != NULL ); /* initiate a read for every regular file */ if ( result->status == NFS3_OK && resok->obj_attributes.attributes_follow && resok->obj_attributes.post_op_attr_u.attributes.type == NF3REG) { /* FIXME: check if the file is recently modified or not. */ // resok->obj_attributes.post_op_attr_u.attributes.ctime; DEBUGPRINT("Copying %s of size %lu\n", e->name, resok->obj_attributes.post_op_attr_u.attributes.size ); /* Store the nfs directory handle in current_session (cs) */ nfs_copyfh (&e->file_handle, resok->object); /* GLOBAL: Storing the global reference for cache entry */ /* NOTE: this memory is freed in reset_cache_entry() */ /* Allocate memory for holding the file-content */ /* Allocate the buff_holder */ e->hbuff = allocate_buff_holder( resok->obj_attributes.post_op_attr_u.attributes.size ); /* NOTE: this memory will be freed by decrement_buff_holder_ref */ /* increment buff_holder reference */ increment_buff_holder_ref (e->hbuff); e->hbuff->len = resok->obj_attributes.post_op_attr_u.attributes.size; /* Set the size of the how much data is read till now. */ e->copied = 0; r = nfs_read (client, e->file_handle, 0, MAX_NFS_READ, read_callback, e); assert (r == ERR_OK); // free arguments xdr_LOOKUP3res(&xdr_free, result); return; } /* Most probably the file does not exist */ DEBUGPRINT ("Error: file [%s] does not exist, or wrong type\n", e->name); #ifdef PRELOAD_WEB_CACHE if (cache_loading_phase){ ++cache_loading_probs; handle_cache_load_done(); return; } #endif // PRELOAD_WEB_CACHE if (e->conn == NULL) { /* No connection is waiting for this loading */ return; } /* as file does not exist, send all the http_conns to error page. */ error_cache->conn = e->conn; error_cache->last = e->last; handle_pending_list (error_cache); /* done! */ /* free this cache entry as it is pointing to invalid page */ e->conn = NULL; e->last = NULL; delete_cacheline_from_cachelist (e); if (e->name != NULL ) free(e->name); free(e); // free arguments xdr_LOOKUP3res(&xdr_free, result); return; } /* end function: lookup_callback_file */