/** * Export lookup That API attempts to find out the fid associated with a parent fid and a name */ void expgw_lookup_1_svc(epgw_lookup_arg_t * arg, expgw_ctx_t *req_ctx_p) { static epgw_mattr_ret_t ret; expgw_fid_key_t key; expgw_fid_cache_t *cache_fid_entry_p; expgw_attr_cache_t *cache_attr_entry_p; int export_lbg_id; int status; int local; ret.parent_attr.status = EP_EMPTY; /** * Get the lbg_id associated with the exportd */ export_lbg_id = expgw_get_exportd_lbg(arg->arg_gw.eid); if (export_lbg_id < 0) { expgw_reply_error_no_such_eid(req_ctx_p,arg->arg_gw.eid); expgw_release_context(req_ctx_p); return; } /* ** check if the fid is handled by the current export gateway ** if the fid is not handled by it must operates in passthrough mode ** and must not update the cache */ local = expgw_check_local(arg->arg_gw.eid,(unsigned char *)arg->arg_gw.parent); if (local != 0) { /* ** the export gateway must operate in passthrough mode */ status = expgw_routing_rq_common(req_ctx_p,arg->arg_gw.eid,(unsigned char *)arg->arg_gw.parent,0,0,expgw_lookup_cbk,req_ctx_p); if (status < 0) { goto error; } goto out; } /* ** OK, the fid is handled by this server, so attempt to get the child fid ** from the cache */ expgw_fid_build_key(&key,(unsigned char *)arg->arg_gw.parent,arg->arg_gw.name); /* ** do the lookup */ cache_fid_entry_p = com_cache_bucket_search_entry(expgw_fid_cache_p,&key); if (cache_fid_entry_p == NULL) { /* ** entry has not be found in the cache, needs to interrogate the exportd ** pre-allocate a cache fid entry */ req_ctx_p->fid_cache_entry = expgw_fid_alloc_entry((unsigned char*)arg->arg_gw.parent,arg->arg_gw.name,NULL); status = expgw_forward_rq_common(req_ctx_p,export_lbg_id,0,0,expgw_lookup_cbk,req_ctx_p); if (status < 0) { goto error; } goto out; } /* ** OK, there is a match, check if it is the same export gateway that handles the ** attributes: if it is not the case, the system replies with an empty attribute array */ local = expgw_check_local(arg->arg_gw.eid,cache_fid_entry_p->fid); if (local == 0) { /* ** do the lookup on the attributes cache */ cache_attr_entry_p = com_cache_bucket_search_entry(expgw_attr_cache_p,cache_fid_entry_p->fid); if (cache_attr_entry_p != NULL) { /* ** entry has been found, copy the attributes in the response buffer */ memcpy(&ret.status_gw.ep_mattr_ret_t_u.attrs, &cache_attr_entry_p->attr, sizeof (mattr_t)); ret.status_gw.status = EP_SUCCESS; /* ** use the receive buffer for the reply */ req_ctx_p->xmitBuf = req_ctx_p->recv_buf; req_ctx_p->recv_buf = NULL; expgw_forward_reply(req_ctx_p,(char*)&ret); /* ** release the context */ expgw_release_context(req_ctx_p); goto out; } } /* ** either the attributes are not in the cache or the gateway is not the owner of the slice ** need to request the attributes from the exportd */ epgw_mfile_arg_t arg_attr; req_ctx_p->response_cbk = expgw_lookup_cbk; arg_attr.arg_gw.eid = arg->arg_gw.eid; memcpy(arg_attr.arg_gw.fid, cache_fid_entry_p->fid, sizeof (uuid_t)); /* ** route the request either to the target export gateway or to the master exportd */ #if 1 status = expgw_export_build_and_route_common( arg->arg_gw.eid,(unsigned char *)cache_fid_entry_p->fid, EXPORT_PROGRAM,EXPORT_VERSION, EP_GETATTR, (xdrproc_t)xdr_epgw_mfile_arg_t , &arg_attr, expgw_generic_export_reply_cbk,req_ctx_p) ; #else status = expgw_export_build_and_send_common( lbg_id,EXPORT_PROGRAM,EXPORT_VERSION, EP_GETATTR, (xdrproc_t)xdr_epgw_mfile_arg_t , &arg_attr, expgw_generic_export_reply_cbk,req_ctx_p) ; #endif if (status < 0) { goto error; } goto out; error: expgw_reply_error(req_ctx_p,errno); /* ** release the context */ expgw_release_context(req_ctx_p); out: return; }
/** Application callBack: THis the callback that is activated upon the recption of an exportd request from a rozofsmount client @param socket_ctx_p: pointer to the af unix socket @param socketId: reference of the socket (not used) @retval : TRUE-> xmit ready event expected @retval : FALSE-> xmit ready event not expected */ void expgw_rozofs_req_rcv_cbk(void *userRef,uint32_t socket_ctx_idx, void *recv_buf) { uint32_t *com_hdr_p; rozofs_rpc_call_hdr_t hdr; expgw_ctx_t *expgw_ctx_p = NULL; com_hdr_p = (uint32_t*) ruc_buf_getPayload(recv_buf); com_hdr_p +=1; /* skip the size of the rpc message */ memcpy(&hdr,com_hdr_p,sizeof(rozofs_rpc_call_hdr_t)); scv_call_hdr_ntoh(&hdr); /* ** allocate a context for the duration of the transaction since it might be possible ** that the gateway needs to interrogate the exportd and thus needs to save the current ** request until receiving the response from the exportd */ expgw_ctx_p = expgw_alloc_context(); if (expgw_ctx_p == NULL) { fatal(" Out of exportd gateway context"); } /* ** save the initial transaction id, received buffer and reference of the connection */ expgw_ctx_p->src_transaction_id = hdr.hdr.xid; expgw_ctx_p->recv_buf = recv_buf; expgw_ctx_p->socketRef = socket_ctx_idx; union { ep_path_t ep_mount_1_arg; uint32_t ep_umount_1_arg; uint32_t ep_statfs_1_arg; epgw_lookup_arg_t ep_lookup_1_arg; epgw_mfile_arg_t ep_getattr_1_arg; epgw_setattr_arg_t ep_setattr_1_arg; epgw_mfile_arg_t ep_readlink_1_arg; epgw_mknod_arg_t ep_mknod_1_arg; epgw_mkdir_arg_t ep_mkdir_1_arg; epgw_unlink_arg_t ep_unlink_1_arg; epgw_rmdir_arg_t ep_rmdir_1_arg; epgw_symlink_arg_t ep_symlink_1_arg; epgw_rename_arg_t ep_rename_1_arg; epgw_readdir_arg_t ep_readdir_1_arg; epgw_io_arg_t ep_read_block_1_arg; epgw_write_block_arg_t ep_write_block_1_arg; epgw_link_arg_t ep_link_1_arg; epgw_setxattr_arg_t ep_setxattr_1_arg; epgw_getxattr_arg_t ep_getxattr_1_arg; epgw_removexattr_arg_t ep_removexattr_1_arg; epgw_listxattr_arg_t ep_listxattr_1_arg; uint16_t ep_list_cluster_1_arg; } argument; xdrproc_t _xdr_argument, _xdr_result; char *(*local)(char *, struct svc_req *); switch (hdr.proc) { #if 0 case EP_NULL: _xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_void; local = (char *(*)(char *, struct svc_req *)) ep_null_1_svc; break; case EP_MOUNT: _xdr_argument = (xdrproc_t) xdr_ep_path_t; _xdr_result = (xdrproc_t) xdr_ep_mount_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_mount_1_svc; break; case EP_UMOUNT: _xdr_argument = (xdrproc_t) xdr_uint32_t; _xdr_result = (xdrproc_t) xdr_epgw_status_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_umount_1_svc; break; case EP_STATFS: _xdr_argument = (xdrproc_t) xdr_uint32_t; _xdr_result = (xdrproc_t) xdr_ep_statfs_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_statfs_1_svc; break; #endif case EP_LOOKUP: START_PROFILING_EXPGW(expgw_ctx_p,ep_lookup); _xdr_argument = (xdrproc_t) xdr_epgw_lookup_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_mattr_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_lookup_1_svc; break; case EP_GETATTR: START_PROFILING_EXPGW(expgw_ctx_p,ep_getattr); _xdr_argument = (xdrproc_t) xdr_epgw_mfile_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_mattr_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_getattr_1_svc; break; case EP_SETATTR: START_PROFILING_EXPGW(expgw_ctx_p,ep_setattr); _xdr_argument = (xdrproc_t) xdr_epgw_setattr_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_mattr_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_setattr_1_svc; break; #if 0 case EP_READLINK: START_PROFILING_EXPGW(expgw_ctx_p,ep_readlink); _xdr_argument = (xdrproc_t) xdr_ep_mfile_arg_t; _xdr_result = (xdrproc_t) xdr_ep_readlink_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_readlink_1_svc; break; #endif case EP_MKNOD: START_PROFILING_EXPGW(expgw_ctx_p,ep_mknod); _xdr_argument = (xdrproc_t) xdr_epgw_mknod_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_mattr_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_mknod_1_svc; break; case EP_MKDIR: START_PROFILING_EXPGW(expgw_ctx_p,ep_mkdir); _xdr_argument = (xdrproc_t) xdr_epgw_mkdir_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_mattr_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_mkdir_1_svc; break; case EP_UNLINK: START_PROFILING_EXPGW(expgw_ctx_p,ep_unlink); _xdr_argument = (xdrproc_t) xdr_epgw_unlink_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_fid_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_unlink_1_svc; break; case EP_RMDIR: START_PROFILING_EXPGW(expgw_ctx_p,ep_rmdir); _xdr_argument = (xdrproc_t) xdr_epgw_rmdir_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_fid_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_rmdir_1_svc; break; case EP_SYMLINK: START_PROFILING_EXPGW(expgw_ctx_p,ep_symlink); _xdr_argument = (xdrproc_t) xdr_epgw_symlink_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_mattr_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_symlink_1_svc; break; #if 0 case EP_RENAME: START_PROFILING_EXPGW(expgw_ctx_p,ep_rename); _xdr_argument = (xdrproc_t) xdr_ep_rename_arg_t; _xdr_result = (xdrproc_t) xdr_ep_fid_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_rename_1_svc; break; case EP_READDIR: START_PROFILING_EXPGW(expgw_ctx_p,ep_readdir); _xdr_argument = (xdrproc_t) xdr_ep_readdir_arg_t; _xdr_result = (xdrproc_t) xdr_ep_readdir_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_readdir_1_svc; break; case EP_READ_BLOCK: START_PROFILING_EXPGW(expgw_ctx_p,ep_read_block); _xdr_argument = (xdrproc_t) xdr_ep_io_arg_t; _xdr_result = (xdrproc_t) xdr_ep_read_block_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_read_block_1_svc; break; #endif case EP_WRITE_BLOCK: START_PROFILING_EXPGW(expgw_ctx_p,ep_write_block); _xdr_argument = (xdrproc_t) xdr_epgw_write_block_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_mattr_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_write_block_1_svc; break; case EP_LINK: START_PROFILING_EXPGW(expgw_ctx_p,ep_link); _xdr_argument = (xdrproc_t) xdr_epgw_link_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_mattr_ret_t; local = (char *(*)(char *, struct svc_req *)) expgw_link_1_svc; break; #if 0 case EP_SETXATTR: START_PROFILING_EXPGW(expgw_ctx_p,ep_setxattr); _xdr_argument = (xdrproc_t) xdr_ep_setxattr_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_status_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_setxattr_1_svc; break; case EP_GETXATTR: START_PROFILING_EXPGW(expgw_ctx_p,ep_getxattr); _xdr_argument = (xdrproc_t) xdr_ep_getxattr_arg_t; _xdr_result = (xdrproc_t) xdr_ep_getxattr_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_getxattr_1_svc; break; case EP_REMOVEXATTR: START_PROFILING_EXPGW(expgw_ctx_p,ep_removexattr); _xdr_argument = (xdrproc_t) xdr_ep_removexattr_arg_t; _xdr_result = (xdrproc_t) xdr_epgw_status_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_removexattr_1_svc; break; case EP_LISTXATTR: START_PROFILING_EXPGW(expgw_ctx_p,ep_listxattr); _xdr_argument = (xdrproc_t) xdr_ep_listxattr_arg_t; _xdr_result = (xdrproc_t) xdr_ep_listxattr_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_listxattr_1_svc; break; case EP_LIST_CLUSTER: _xdr_argument = (xdrproc_t) xdr_uint16_t; _xdr_result = (xdrproc_t) xdr_ep_cluster_ret_t; local = (char *(*)(char *, struct svc_req *)) ep_list_cluster_1_svc; break; #endif default: expgw_ctx_p->xmitBuf = expgw_ctx_p->recv_buf; expgw_ctx_p->recv_buf = NULL; errno = EPROTO; expgw_reply_error(expgw_ctx_p,errno); expgw_release_context(expgw_ctx_p); return; } memset ((char *)&argument, 0, sizeof (argument)); /* ** save the result encoding/decoding function */ expgw_ctx_p->xdr_result = _xdr_result; if (!expgw_getargs (recv_buf, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { expgw_ctx_p->xmitBuf = expgw_ctx_p->recv_buf; expgw_ctx_p->recv_buf = NULL; expgw_reply_error(expgw_ctx_p,errno); /* ** release the context */ xdr_free((xdrproc_t)_xdr_argument, (caddr_t) &argument); expgw_release_context(expgw_ctx_p); return; } /* ** call the user call-back */ (*local)((char *)&argument, (void*)expgw_ctx_p); /* ** release any data allocated while decoding */ xdr_free((xdrproc_t)_xdr_argument, (caddr_t) &argument); }