static int pnfs_unlink_ds_partfile(pnfs_ds_client_t * pnfsdsclient, component4 name, pnfs_part_file_t * ppartfile) { COMPOUND4args argnfs4; COMPOUND4res resnfs4; struct timeval timeout = { 25, 0 }; nfs_argop4 argoparray[PNFS_LAYOUTFILE_NB_OP_UNLINK_DS_FILE]; nfs_resop4 resoparray[PNFS_LAYOUTFILE_NB_OP_UNLINK_DS_FILE]; unsigned int i; if(!pnfsdsclient || !ppartfile ) return NFS4ERR_SERVERFAULT; /* Step 1 OP4_OPEN as OPEN4_CREATE */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 1; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Mkdir" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; COMPOUNDV41_ARG_ADD_OP_SEQUENCE(argnfs4, pnfsdsclient->session, pnfsdsclient->sequence); COMPOUNDV41_ARG_ADD_OP_PUTFH(argnfs4, pnfsdsclient->ds_rootfh); COMPOUNDV41_ARG_ADD_OP_REMOVE(argnfs4, name); /* Call the NFSv4 function */ if(clnt_call(pnfsdsclient->rpc_client, NFSPROC4_COMPOUND, (xdrproc_t) xdr_COMPOUND4args, (caddr_t) & argnfs4, (xdrproc_t) xdr_COMPOUND4res, (caddr_t) & resnfs4, timeout) != RPC_SUCCESS) { return NFS4ERR_IO; /* @todo: For wanting of something more appropriate */ } if(resnfs4.status != NFS4_OK) return resnfs4.status; pnfsdsclient->sequence += 1; /* Free the ressources */ Mem_Free((char *)ppartfile->handle.nfs_fh4_val); return NFS4_OK; } /* pnfs_ds_unlink_file */
static int pnfs_create_ds_partfile(pnfs_ds_client_t * pnfsdsclient, component4 name, pnfs_ds_loc_t * plocation, pnfs_part_file_t * ppartfile) { COMPOUND4args argnfs4; COMPOUND4res resnfs4; struct timeval timeout = { 25, 0 }; nfs_argop4 argoparray_open_ds_file[PNFS_LAYOUTFILE_NB_OP_OPEN_DS_FILE]; nfs_resop4 resoparray_open_ds_file[PNFS_LAYOUTFILE_NB_OP_OPEN_DS_FILE]; nfs_argop4 argoparray_close_ds_file[PNFS_LAYOUTFILE_NB_OP_CLOSE_DS_FILE]; nfs_resop4 resoparray_close_ds_file[PNFS_LAYOUTFILE_NB_OP_CLOSE_DS_FILE]; char owner_val[PNFS_LAYOUTFILE_OWNER_LEN]; unsigned int owner_len = 0; unsigned int bitmap_val[2]; unsigned int bitmap_res[2]; fattr4_mode buffmode; fattr4 inattr; unsigned int i; char tmp[1024]; #define PNFS_LAYOUTFILE_CREATE_IDX_OP_SEQUENCE 0 #define PNFS_LAYOUTFILE_CREATE_IDX_OP_PUTFH 1 #define PNFS_LAYOUTFILE_CREATE_IDX_OP_OPEN 2 #define PNFS_LAYOUTFILE_CREATE_IDX_OP_GETFH 3 if(!pnfsdsclient || !ppartfile || !plocation ) return NFS4ERR_SERVERFAULT; /* Create the owner */ snprintf(owner_val, PNFS_LAYOUTFILE_OWNER_LEN, "GANESHA/PNFS: pid=%u FH=%s", getpid(), plocation->str_mds_handle); owner_len = strnlen(owner_val, PNFS_LAYOUTFILE_OWNER_LEN); inattr.attrmask.bitmap4_len = 2; inattr.attrmask.bitmap4_val = bitmap_val; bitmap_val[0] = 0; bitmap_val[1] = 2; /* FATTR4_MODE == 33 = 32+1 */ inattr.attr_vals.attrlist4_len = sizeof(fattr4_mode); buffmode = htonl(0644); inattr.attr_vals.attrlist4_val = (char *)&buffmode; /* Step 1 OP4_OPEN as OPEN4_CREATE */ argnfs4.argarray.argarray_val = argoparray_open_ds_file; resnfs4.resarray.resarray_val = resoparray_open_ds_file; argnfs4.minorversion = 1; argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; resnfs4.resarray.resarray_val[PNFS_LAYOUTFILE_CREATE_IDX_OP_GETFH].nfs_resop4_u. opgetfh.GETFH4res_u.resok4.object.nfs_fh4_val = (char *)Mem_Alloc(PNFS_LAYOUTFILE_FILEHANDLE_MAX_LEN); resnfs4.resarray.resarray_val[PNFS_LAYOUTFILE_CREATE_IDX_OP_OPEN].nfs_resop4_u.opopen. OPEN4res_u.resok4.attrset.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[PNFS_LAYOUTFILE_CREATE_IDX_OP_OPEN].nfs_resop4_u.opopen. OPEN4res_u.resok4.attrset.bitmap4_len = 2; COMPOUNDV41_ARG_ADD_OP_SEQUENCE(argnfs4, pnfsdsclient->session, pnfsdsclient->sequence); pnfsdsclient->sequence += 1; /* In all cases, failure or not, increment the sequence counter */ COMPOUNDV41_ARG_ADD_OP_PUTFH(argnfs4, pnfsdsclient->ds_rootfh); COMPOUNDV41_ARG_ADD_OP_OPEN_CREATE(argnfs4, name, inattr, owner_val, owner_len); COMPOUNDV41_ARG_ADD_OP_GETFH(argnfs4); /* Call the NFSv4 function */ if(clnt_call(pnfsdsclient->rpc_client, NFSPROC4_COMPOUND, (xdrproc_t) xdr_COMPOUND4args, (caddr_t) & argnfs4, (xdrproc_t) xdr_COMPOUND4res, (caddr_t) & resnfs4, timeout) != RPC_SUCCESS) { return NFS4ERR_IO; /* @todo: For wanting of something more appropriate */ } /* Get information from reply */ ppartfile->stateid.seqid = resnfs4.resarray.resarray_val[PNFS_LAYOUTFILE_CREATE_IDX_OP_OPEN]. nfs_resop4_u.opopen.OPEN4res_u.resok4.stateid.seqid; memcpy((char *)ppartfile->stateid.other, (char *)resnfs4.resarray. resarray_val[PNFS_LAYOUTFILE_CREATE_IDX_OP_OPEN].nfs_resop4_u.opopen.OPEN4res_u. resok4.stateid.other, 12); ppartfile->handle.nfs_fh4_len = resnfs4.resarray.resarray_val[PNFS_LAYOUTFILE_CREATE_IDX_OP_GETFH]. nfs_resop4_u.opgetfh.GETFH4res_u.resok4.object.nfs_fh4_len; ppartfile->handle.nfs_fh4_val = resnfs4.resarray.resarray_val[PNFS_LAYOUTFILE_CREATE_IDX_OP_GETFH]. nfs_resop4_u.opgetfh.GETFH4res_u.resok4.object.nfs_fh4_val; ppartfile->deviceid = 1; ppartfile->is_ganesha = FALSE; if(resnfs4.status != NFS4_OK) { printf( "+-+-+-+-> pnfs_create_ds_partfile: error=%u\n", resnfs4.status ) ; return resnfs4.status; } /* Close the file */ argnfs4.argarray.argarray_val = argoparray_close_ds_file; resnfs4.resarray.resarray_val = resoparray_close_ds_file; argnfs4.argarray.argarray_len = 0; COMPOUNDV41_ARG_ADD_OP_SEQUENCE(argnfs4, pnfsdsclient->session, pnfsdsclient->sequence); pnfsdsclient->sequence += 1; /* In all cases, failure or not, increment the sequence counter */ COMPOUNDV41_ARG_ADD_OP_PUTFH(argnfs4, ppartfile->handle); COMPOUNDV41_ARG_ADD_OP_CLOSE(argnfs4, ppartfile->stateid); /* Call the NFSv4 function */ if(clnt_call(pnfsdsclient->rpc_client, NFSPROC4_COMPOUND, (xdrproc_t) xdr_COMPOUND4args, (caddr_t) & argnfs4, (xdrproc_t) xdr_COMPOUND4res, (caddr_t) & resnfs4, timeout) != RPC_SUCCESS) { return NFS4ERR_IO; /* @todo: For wanting of something more appropriate */ } if(resnfs4.status != NFS4_OK) return resnfs4.status; return NFS4_OK; } /* pnfs_create_ds_partfile */
static int pnfs_truncate_ds_partfile(pnfs_ds_client_t * pnfsdsclient, size_t newsize, pnfs_part_file_t * ppartfile) { COMPOUND4args argnfs4; COMPOUND4res resnfs4; struct timeval timeout = { 25, 0 }; nfs_argop4 argoparray[PNFS_LAYOUTFILE_NB_OP_TRUNCATE_DS_FILE]; nfs_resop4 resoparray[PNFS_LAYOUTFILE_NB_OP_TRUNCATE_DS_FILE]; fsal_attrib_list_t fsal_attr_set; fattr4 fattr_set; bitmap4 inbitmap; bitmap4 convert_bitmap; uint32_t inbitmap_val[2]; uint32_t bitmap_res[2]; uint32_t bitmap_set[2]; uint32_t bitmap_conv_val[2]; unsigned int i; if(!pnfsdsclient || !ppartfile ) return NFS4ERR_SERVERFAULT; /* Step 1 OP4_OPEN as OPEN4_CREATE */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 1; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Mkdir" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; memset( (char *)&fsal_attr_set, 0, sizeof( fsal_attr_set ) ); fsal_attr_set.asked_attributes = FSAL_ATTR_SIZE; fsal_attr_set.filesize = newsize; convert_bitmap.bitmap4_val = bitmap_conv_val; convert_bitmap.bitmap4_len = 2; convert_bitmap.bitmap4_val[0] = 1 << FATTR4_SIZE ; convert_bitmap.bitmap4_val[1] = 0 ; if(nfs4_FSALattr_To_Fattr(NULL, /* no exportlist required here */ &fsal_attr_set, &fattr_set, NULL, /* no compound data required here */ NULL, /* No fh here, filehandle is not a settable attribute */ &convert_bitmap) == -1) return NFS4ERR_INVAL ; #define PNFS_LAYOUTFILE_TRUNCATE_IDX_OP_SEQUENCE 0 #define PNFS_LAYOUTFILE_TRUNCATE_IDX_OP_PUTFH 1 #define PNFS_LAYOUTFILE_TRUNCATE_IDX_OP_SETATTR 2 COMPOUNDV41_ARG_ADD_OP_SEQUENCE(argnfs4, pnfsdsclient->session, pnfsdsclient->sequence); COMPOUNDV41_ARG_ADD_OP_PUTFH(argnfs4, ppartfile->handle); COMPOUNDV41_ARG_ADD_OP_SETATTR(argnfs4, fattr_set); /* For ATTR_SIZE, stateid is needed, we use the stateless "all-0's" stateid here */ argnfs4.argarray.argarray_val[PNFS_LAYOUTFILE_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u. opsetattr.stateid.seqid = 0; memset(argnfs4.argarray.argarray_val[PNFS_LAYOUTFILE_TRUNCATE_IDX_OP_SETATTR]. nfs_argop4_u.opsetattr.stateid.other, 0, 12); resnfs4.resarray.resarray_val[PNFS_LAYOUTFILE_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u. opsetattr.attrsset.bitmap4_val = bitmap_set; resnfs4.resarray.resarray_val[PNFS_LAYOUTFILE_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u. opsetattr.attrsset.bitmap4_len = 2; /* Call the NFSv4 function */ if(clnt_call(pnfsdsclient->rpc_client, NFSPROC4_COMPOUND, (xdrproc_t) xdr_COMPOUND4args, (caddr_t) & argnfs4, (xdrproc_t) xdr_COMPOUND4res, (caddr_t) & resnfs4, timeout) != RPC_SUCCESS) { return NFS4ERR_IO; /* @todo: For wanting of something more appropriate */ } if(resnfs4.status != NFS4_OK) return resnfs4.status; pnfsdsclient->sequence += 1; return NFS4_OK; } /* pnfs_ds_unlink_file */
/** * * pnfs_lookup: looks up for a path's component. * * Looks up for a path's component. * * @param pnfsclient [IN] pointer to the pnfsclient structure (client to the ds). * @param parent_directory_handle [IN] the NFSv4 file handle for the parent directory * @param filename [IN] the path's component to be looked up * @param object_handle [OUT] the resulting NFSv4 file handle * * @return NFS4_OK if successful * @return a NFSv4 error (positive value) if failed. * */ int pnfs_lookup(pnfs_ds_client_t * pnfsdsclient, nfs_fh4 * parent_directory_handle, /* IN */ char *filename, /* IN */ nfs_fh4 * object_handle) { int rc; nfs_fh4 nfs4fh; component4 name; char nameval[MAXNAMLEN]; unsigned int index_getfh = 0; COMPOUND4args argnfs4; COMPOUND4res resnfs4; struct timeval timeout = { 25, 0 }; #define PNFS_LAYOUTFILE_NB_OP_ALLOC 4 nfs_argop4 argoparray[PNFS_LAYOUTFILE_NB_OP_ALLOC]; nfs_resop4 resoparray[PNFS_LAYOUTFILE_NB_OP_ALLOC]; uint32_t bitmap_res[2]; char padfilehandle[PNFS_LAYOUTFILE_FILEHANDLE_MAX_LEN]; /* sanity checks * note : object_attributes is optionnal * parent_directory_handle may be null for getting FS root. */ if(!object_handle || !filename || !object_handle) return NFS4ERR_INVAL; /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 1; argnfs4.argarray.argarray_len = 0; name.utf8string_val = nameval; name.utf8string_len = 0; if(!parent_directory_handle) { /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup Root" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; #define PNFS_LOOKUP_IDX_OP_SEQUENCE 0 #define PNFS_LOOKUP_IDX_OP_PUTROOTFH 1 #define PNFS_LOOKUP_IDX_OP_GETFH_ROOT 2 COMPOUNDV41_ARG_ADD_OP_SEQUENCE(argnfs4, pnfsdsclient->session, pnfsdsclient->sequence); COMPOUNDV41_ARG_ADD_OP_PUTROOTFH(argnfs4); COMPOUNDV41_ARG_ADD_OP_GETFH(argnfs4); index_getfh = PNFS_LOOKUP_IDX_OP_GETFH_ROOT; resnfs4.resarray.resarray_val[PNFS_LOOKUP_IDX_OP_GETFH_ROOT].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; resnfs4.resarray.resarray_val[PNFS_LOOKUP_IDX_OP_GETFH_ROOT].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_len = PNFS_LAYOUTFILE_FILEHANDLE_MAX_LEN; } else /* this is a real lookup(parent, name) */ { /* the filename should not be null */ if(filename == NULL) return NFS4ERR_INVAL; if(str2utf8(filename, &name) == -1) return NFS4ERR_SERVERFAULT; nfs4fh.nfs_fh4_len = parent_directory_handle->nfs_fh4_len; nfs4fh.nfs_fh4_val = parent_directory_handle->nfs_fh4_val; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup name" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; #define PNFS_LOOKUP_IDX_OP_SEQUENCE 0 #define PNFS_LOOKUP_IDX_OP_PUTFH 1 #define PNFS_LOOKUP_IDX_OP_LOOKUP 2 #define PNFS_LOOKUP_IDX_OP_GETFH 3 COMPOUNDV41_ARG_ADD_OP_SEQUENCE(argnfs4, pnfsdsclient->session, pnfsdsclient->sequence); COMPOUNDV41_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV41_ARG_ADD_OP_LOOKUP(argnfs4, name); COMPOUNDV41_ARG_ADD_OP_GETFH(argnfs4); index_getfh = PNFS_LOOKUP_IDX_OP_GETFH; resnfs4.resarray.resarray_val[PNFS_LOOKUP_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; resnfs4.resarray.resarray_val[PNFS_LOOKUP_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_len = PNFS_LAYOUTFILE_FILEHANDLE_MAX_LEN; } /* Call the NFSv4 function */ if(clnt_call(pnfsdsclient->rpc_client, NFSPROC4_COMPOUND, (xdrproc_t) xdr_COMPOUND4args, (caddr_t) & argnfs4, (xdrproc_t) xdr_COMPOUND4res, (caddr_t) & resnfs4, timeout) != RPC_SUCCESS) { return NFS4ERR_IO; /* @todo: For wanting of something more appropriate */ } /* Increment the sequence */ pnfsdsclient->sequence += 1; if(resnfs4.status != NFS4_OK) { return resnfs4.status; } object_handle->nfs_fh4_len = resnfs4.resarray.resarray_val[index_getfh].nfs_resop4_u.opgetfh.GETFH4res_u.resok4. object.nfs_fh4_len; memcpy((char *)object_handle->nfs_fh4_val, (char *)resnfs4.resarray.resarray_val[index_getfh].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_val, resnfs4.resarray.resarray_val[index_getfh].nfs_resop4_u.opgetfh.GETFH4res_u. resok4.object.nfs_fh4_len); /* lookup complete ! */ return NFS4_OK; }