/** * FSAL_dynamic_fsinfo: * Return dynamic filesystem info such as * used size, free size, number of objects... * * \param filehandle (input): * Handle of an object in the filesystem * whom info is to be retrieved. * \param p_context (input): * Authentication context for the operation (user,...). * \param dynamicinfo (output): * Pointer to the static info of the filesystem. * * \return Major error codes: * - ERR_FSAL_NO_ERROR (no error) * - ERR_FSAL_FAULT (a NULL pointer was passed as mandatory argument) * - Other error codes can be returned : * ERR_FSAL_IO, ... */ fsal_status_t PROXYFSAL_dynamic_fsinfo(proxyfsal_handle_t * filehandle, /* IN */ proxyfsal_op_context_t * p_context, /* IN */ fsal_dynamicfsinfo_t * dynamicinfo /* OUT */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh; bitmap4 bitmap; uint32_t bitmap_val[2]; uint32_t bitmap_res[2]; #define FSAL_FSINFO_NB_OP_ALLOC 2 nfs_argop4 argoparray[FSAL_FSINFO_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_FSINFO_NB_OP_ALLOC]; fsal_proxy_internal_fattr_t fattr_internal; struct timeval timeout = TIMEOUTRPC; /* sanity checks. */ if(!filehandle || !dynamicinfo || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_dynamic_fsinfo); /* >> get attributes from your filesystem << */ /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; fsal_internal_proxy_setup_fattr(&fattr_internal); argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Getattr" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; bitmap.bitmap4_val = bitmap_val; bitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_fsinfo_bitmap(&bitmap); /* Get NFSv4 File handle */ if(fsal_internal_proxy_extract_fh(&nfs4fh, filehandle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs); #define FSAL_FSINFO_IDX_OP_PUTFH 0 #define FSAL_FSINFO_IDX_OP_GETATTR 1 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); resnfs4.resarray.resarray_val[FSAL_FSINFO_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_FSINFO_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_FSINFO_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_FSINFO_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, 0, INDEX_FSAL_dynamic_fsinfo); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_dynamic_fsinfo); /* Use NFSv4 service function to build the FSAL_attr */ if(proxy_Fattr_To_FSAL_dynamic_fsinfo(dynamicinfo, &resnfs4.resarray.resarray_val [FSAL_FSINFO_IDX_OP_GETATTR]. nfs_resop4_u.opgetattr.GETATTR4res_u.resok4. obj_attributes) != 1) { memset((char *)dynamicinfo, 0, sizeof(fsal_dynamicfsinfo_t)); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_dynamic_fsinfo); } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_dynamic_fsinfo); } /* FSAL_dynamic_fsinfo */
fsal_status_t FSAL_proxy_truncate_stateless(proxyfsal_handle_t * filehandle, /* IN */ proxyfsal_op_context_t * p_context, /* IN */ fsal_size_t length, /* IN */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh; fsal_status_t fsal_status; fsal_attrib_list_t open_attrs; 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]; #define FSAL_TRUNCATE_STATELESS_NB_OP_ALLOC 3 nfs_argop4 argoparray[FSAL_TRUNCATE_STATELESS_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_TRUNCATE_STATELESS_NB_OP_ALLOC]; fsal_attrib_list_t fsal_attr_set; fattr4 fattr_set; fsal_proxy_internal_fattr_t fattr_internal; struct timeval timeout = { 25, 0 }; /* sanity checks. * note : object_attributes is optional. */ if(!filehandle || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate); if(filehandle->data.object_type_reminder != FSAL_TYPE_FILE) { Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate); } /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; fsal_internal_proxy_setup_fattr(&fattr_internal); argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Truncate" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; /* Get NFSv4 File handle */ if(fsal_internal_proxy_extract_fh(&nfs4fh, filehandle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate); /* Get prepared for truncate */ fsal_attr_set.asked_attributes = FSAL_ATTR_SIZE; fsal_attr_set.filesize = length; convert_bitmap.bitmap4_val = bitmap_conv_val; convert_bitmap.bitmap4_len = 2; fsal_interval_proxy_fsalattr2bitmap4(&fsal_attr_set, &convert_bitmap); 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(ERR_FSAL_INVAL, -1, INDEX_FSAL_truncate); inbitmap.bitmap4_val = inbitmap_val; inbitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&inbitmap); #define FSAL_TRUNCATE_STATELESS_IDX_OP_PUTFH 0 #define FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR 1 #define FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR 2 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_SETATTR(argnfs4, fattr_set); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, inbitmap); /* For ATTR_SIZE, stateid is needed, we use the stateless "all-0's" stateid here */ argnfs4.argarray.argarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR].nfs_argop4_u. opsetattr.stateid.seqid = 0; memset(argnfs4.argarray.argarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR]. nfs_argop4_u.opsetattr.stateid.other, 0, 12); resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR].nfs_resop4_u. opsetattr.attrsset.bitmap4_val = bitmap_set; resnfs4.resarray.resarray_val[FSAL_TRUNCATE_STATELESS_IDX_OP_SETATTR].nfs_resop4_u. opsetattr.attrsset.bitmap4_len = 2; TakeTokenFSCall(); COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, 0, INDEX_FSAL_truncate); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_truncate); /* >> interpret error code << */ /* >> Optionnaly retrieve post op attributes * If your filesystem truncate call can't return them, * you can proceed like this : << */ if(object_attributes) { if(nfs4_Fattr_To_FSAL_attr(object_attributes, &resnfs4.resarray.resarray_val [FSAL_TRUNCATE_STATELESS_IDX_OP_GETATTR]. nfs_resop4_u.opgetattr.GETATTR4res_u.resok4. obj_attributes) != 1) { FSAL_CLEAR_MASK(object_attributes->asked_attributes); FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate); } } /* No error occured */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_truncate); } /* FSAL_proxy_truncate_stateless */
fsal_status_t PROXYFSAL_lookup(proxyfsal_handle_t * parent_directory_handle, /* IN */ fsal_name_t * p_filename, /* IN */ proxyfsal_op_context_t * p_context, /* IN */ proxyfsal_handle_t * object_handle, /* OUT */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh; bitmap4 bitmap; uint32_t bitmap_val[2]; component4 name; char nameval[MAXNAMLEN]; fsal_attrib_list_t attributes; unsigned int index_getfh = 0; unsigned int index_getattr = 0; #define FSAL_LOOKUP_NB_OP_ALLOC 4 nfs_argop4 argoparray[FSAL_LOOKUP_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_LOOKUP_NB_OP_ALLOC]; uint32_t bitmap_res[2]; fsal_proxy_internal_fattr_t fattr_internal; char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN]; struct timeval timeout = TIMEOUTRPC; /* sanity checks * note : object_attributes is optionnal * parent_directory_handle may be null for getting FS root. */ if(!object_handle || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; fsal_internal_proxy_setup_fattr(&fattr_internal); argnfs4.minorversion = 0; argnfs4.argarray.argarray_len = 0; /* >> retrieve root handle filehandle here << */ bitmap.bitmap4_val = bitmap_val; bitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&bitmap); if(!parent_directory_handle) { /* check that p_filename is NULL, * else, parent_directory_handle should not * be NULL. */ if(p_filename != NULL) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup Root" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; #define FSAL_LOOKUP_IDX_OP_PUTROOTFH 0 #define FSAL_LOOKUP_IDX_OP_GETATTR_ROOT 1 #define FSAL_LOOKUP_IDX_OP_GETFH_ROOT 2 COMPOUNDV4_ARG_ADD_OP_PUTROOTFH(argnfs4); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4); index_getattr = FSAL_LOOKUP_IDX_OP_GETATTR_ROOT; index_getfh = FSAL_LOOKUP_IDX_OP_GETFH_ROOT; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR_ROOT].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR_ROOT].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR_ROOT].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR_ROOT].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETFH_ROOT].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETFH_ROOT].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN; } else /* this is a real lookup(parent, name) */ { PRINT_HANDLE("PROXYFSAL_lookup parent", parent_directory_handle); /* the filename should not be null */ if(p_filename == NULL) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); /* >> Be careful about junction crossing, symlinks, hardlinks,... * You may check the parent type if it's sored into the handle << */ switch (parent_directory_handle->data.object_type_reminder) { case FSAL_TYPE_DIR: /* OK */ break; case FSAL_TYPE_JUNCTION: /* This is a junction */ Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup); case FSAL_TYPE_FILE: case FSAL_TYPE_LNK: case FSAL_TYPE_XATTR: /* not a directory */ Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup); default: Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup); } /* >> Call your filesystem lookup function here << */ if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); memset((char *)&name, 0, sizeof(component4)); name.utf8string_val = nameval; if(fsal_internal_proxy_fsal_name_2_utf8(p_filename, &name) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); if(!FSAL_namecmp(p_filename, (fsal_name_t *) & FSAL_DOT)) { /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup current" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; #define FSAL_LOOKUP_IDX_OP_DOT_PUTFH 0 #define FSAL_LOOKUP_IDX_OP_DOT_GETATTR 1 #define FSAL_LOOKUP_IDX_OP_DOT_GETFH 2 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4); index_getattr = FSAL_LOOKUP_IDX_OP_DOT_GETATTR; index_getfh = FSAL_LOOKUP_IDX_OP_DOT_GETFH; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETFH].nfs_resop4_u. opgetfh.GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_GETFH].nfs_resop4_u. opgetfh.GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN; } else if(!FSAL_namecmp(p_filename, (fsal_name_t *) & FSAL_DOT_DOT)) { /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup parent" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; #define FSAL_LOOKUP_IDX_OP_DOT_DOT_PUTFH 0 #define FSAL_LOOKUP_IDX_OP_DOT_DOT_LOOKUPP 1 #define FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR 2 #define FSAL_LOOKUP_IDX_OP_DOT_DOT_GETFH 3 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_LOOKUPP(argnfs4); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4); index_getattr = FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR; index_getfh = FSAL_LOOKUP_IDX_OP_DOT_DOT_GETFH; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETFH].nfs_resop4_u. opgetfh.GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_DOT_DOT_GETFH].nfs_resop4_u. opgetfh.GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN; } else { /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Lookup name" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; #define FSAL_LOOKUP_IDX_OP_PUTFH 0 #define FSAL_LOOKUP_IDX_OP_LOOKUP 1 #define FSAL_LOOKUP_IDX_OP_GETATTR 2 #define FSAL_LOOKUP_IDX_OP_GETFH 3 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_LOOKUP(argnfs4, name); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4); index_getattr = FSAL_LOOKUP_IDX_OP_GETATTR; index_getfh = FSAL_LOOKUP_IDX_OP_GETFH; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; resnfs4.resarray.resarray_val[FSAL_LOOKUP_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN; } } TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, rc, INDEX_FSAL_lookup); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_lookup); /* Use NFSv4 service function to build the FSAL_attr */ if(nfs4_Fattr_To_FSAL_attr(&attributes, &resnfs4.resarray.resarray_val[index_getattr].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) { FSAL_CLEAR_MASK(object_attributes->asked_attributes); FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookup); } if(object_attributes) { memcpy(object_attributes, &attributes, sizeof(attributes)); } /* Build the handle */ if(fsal_internal_proxy_create_fh (&resnfs4.resarray.resarray_val[index_getfh].nfs_resop4_u.opgetfh.GETFH4res_u. resok4.object, attributes.type, attributes.fileid, object_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); PRINT_HANDLE("PROXYFSAL_lookup object found", object_handle); /* Return attributes if asked */ if(object_attributes) { memcpy(object_attributes, &attributes, sizeof(attributes)); } /* lookup complete ! */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); }
fsal_status_t PROXYFSAL_rename(fsal_handle_t * old_parent, /* IN */ fsal_name_t * p_old_name, /* IN */ fsal_handle_t * new_parent, /* IN */ fsal_name_t * p_new_name, /* IN */ fsal_op_context_t *context, /* IN */ fsal_attrib_list_t * src_dir_attributes, /* [ IN/OUT ] */ fsal_attrib_list_t * tgt_dir_attributes /* [ IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh_old; nfs_fh4 nfs4fh_new; bitmap4 bitmap_old; uint32_t bitmap_val_old[2]; bitmap4 bitmap_new; uint32_t bitmap_val_new[2]; component4 oldname; char oldnameval[MAXNAMLEN]; component4 newname; char newnameval[MAXNAMLEN]; proxyfsal_handle_t * old_parentdir_handle = (proxyfsal_handle_t *)old_parent; proxyfsal_handle_t * new_parentdir_handle = (proxyfsal_handle_t *)new_parent; proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; #define FSAL_RENAME_NB_OP_ALLOC 7 nfs_argop4 argoparray[FSAL_RENAME_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_RENAME_NB_OP_ALLOC]; uint32_t bitmap_res_old[2]; uint32_t bitmap_res_new[2]; fsal_proxy_internal_fattr_t fattr_internal_new; fsal_proxy_internal_fattr_t fattr_internal_old; struct timeval timeout = TIMEOUTRPC; /* sanity checks. * note : src/tgt_dir_attributes are optional. */ if(!old_parentdir_handle || !new_parentdir_handle || !p_old_name || !p_new_name || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename); /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; fsal_internal_proxy_setup_fattr(&fattr_internal_new); fsal_internal_proxy_setup_fattr(&fattr_internal_old); argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Rename" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; /* Prepare the structures */ bitmap_old.bitmap4_val = bitmap_val_old; bitmap_old.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&bitmap_old); if(fsal_internal_proxy_extract_fh(&nfs4fh_old, old_parent) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename); memset((char *)&oldname, 0, sizeof(component4)); oldname.utf8string_val = oldnameval; if(fsal_internal_proxy_fsal_name_2_utf8(p_old_name, &oldname) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename); bitmap_new.bitmap4_val = bitmap_val_new; bitmap_new.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&bitmap_new); if(fsal_internal_proxy_extract_fh(&nfs4fh_new, new_parent) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename); memset((char *)&newname, 0, sizeof(component4)); newname.utf8string_val = newnameval; if(fsal_internal_proxy_fsal_name_2_utf8(p_new_name, &newname) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rename); #define FSAL_RENAME_IDX_OP_PUTFH_OLD 0 #define FSAL_RENAME_IDX_OP_SAVEFH 1 #define FSAL_RENAME_IDX_OP_PUTFH_NEW 2 #define FSAL_RENAME_IDX_OP_RENAME 3 #define FSAL_RENAME_IDX_OP_GETATTR_NEW 4 #define FSAL_RENAME_IDX_OP_RESTOREFH 5 #define FSAL_RENAME_IDX_OP_GETATTR_OLD 6 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_old); COMPOUNDV4_ARG_ADD_OP_SAVEFH(argnfs4); COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_new); COMPOUNDV4_ARG_ADD_OP_RENAME(argnfs4, oldname, newname); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap_new); COMPOUNDV4_ARG_ADD_OP_RESTOREFH(argnfs4); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap_old); resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res_new; resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal_new; resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal_new); resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res_old; resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal_old; resnfs4.resarray.resarray_val[FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal_old); TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, rc, INDEX_FSAL_rename); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_rename); /* >> get last parent post op attributes if asked * For example : << */ if(src_dir_attributes) { if(nfs4_Fattr_To_FSAL_attr(src_dir_attributes, &resnfs4.resarray.resarray_val [FSAL_RENAME_IDX_OP_GETATTR_OLD].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) { FSAL_CLEAR_MASK(src_dir_attributes->asked_attributes); FSAL_SET_MASK(src_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rename); } } /* >> get new parent post op attributes if asked * For example : << */ if(tgt_dir_attributes) { if(nfs4_Fattr_To_FSAL_attr(tgt_dir_attributes, &resnfs4.resarray.resarray_val [FSAL_RENAME_IDX_OP_GETATTR_NEW].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) { FSAL_CLEAR_MASK(tgt_dir_attributes->asked_attributes); FSAL_SET_MASK(tgt_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rename); } } /* OK */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_rename); }
fsal_status_t FSAL_proxy_open_confirm(proxyfsal_file_t * pfd) { fsal_status_t fsal_status; int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh; #define FSAL_PROXY_OPEN_CONFIRM_NB_OP_ALLOC 2 #define FSAL_PROXY_OPEN_CONFIRM_IDX_OP_PUTFH 0 #define FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM 1 nfs_argop4 argoparray[FSAL_PROXY_OPEN_CONFIRM_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_PROXY_OPEN_CONFIRM_NB_OP_ALLOC]; struct timeval timeout = TIMEOUTRPC; if(pfd == NULL) { fsal_status.major = ERR_FSAL_FAULT; fsal_status.minor = 0; return fsal_status; } if(pfd->pcontext == NULL) { LogFullDebug(COMPONENT_FSAL, "===================> FSAL_proxy_open_confirm: Non initialized fd !!!!!"); fsal_status.major = ERR_FSAL_FAULT; fsal_status.minor = 0; return fsal_status; } /* Get NFSv4 File handle */ if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *) &pfd->fhandle) == FALSE) { fsal_status.major = ERR_FSAL_FAULT; fsal_status.minor = 0; return fsal_status; } /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 0; argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); argnfs4.argarray.argarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].argop = NFS4_OP_OPEN_CONFIRM; argnfs4.argarray.argarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].nfs_argop4_u. opopen_confirm.open_stateid.seqid = pfd->stateid.seqid; memcpy((char *)argnfs4.argarray. argarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].nfs_argop4_u. opopen_confirm.open_stateid.other, (char *)pfd->stateid.other, 12); argnfs4.argarray.argarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].nfs_argop4_u. opopen_confirm.seqid = pfd->stateid.seqid + 1; argnfs4.argarray.argarray_len = 2; TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(pfd->pcontext, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); fsal_status.major = ERR_FSAL_IO; fsal_status.minor = resnfs4.status; return fsal_status; } ReleaseTokenFSCall(); /* set the error is res if not NFS4_OK */ if(resnfs4.status != NFS4_OK) { fsal_status.major = ERR_FSAL_IO; fsal_status.minor = resnfs4.status; return fsal_status; } /* Update the file descriptor with the new stateid */ pfd->stateid.seqid = resnfs4.resarray.resarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM]. nfs_resop4_u.opopen_confirm.OPEN_CONFIRM4res_u.resok4.open_stateid.seqid; memcpy((char *)pfd->stateid.other, (char *)resnfs4.resarray. resarray_val[FSAL_PROXY_OPEN_CONFIRM_IDX_OP_OPEN_CONFIRM].nfs_resop4_u. opopen_confirm.OPEN_CONFIRM4res_u.resok4.open_stateid.other, 12); fsal_status.major = ERR_FSAL_NO_ERROR; fsal_status.minor = NFS4_OK; return fsal_status; } /* FSAL_proxy_open_confirm */
/** * FSAL_proxy_clientid_renewer_thread: this thread is made for refreshing the clientid used by the FSAL, automatically. * * This thread is made for refreshing the clientid used by the FSAL, automatically. * * * \return never returns... This is a infinite loop that will die when the daemon stops */ void *FSAL_proxy_clientid_renewer_thread(void *Arg) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; struct timeval timeout = TIMEOUTRPC; fsal_status_t fsal_status; proxyfsal_op_context_t fsal_context; proxyfsal_op_context_t *p_context = &fsal_context; #define FSAL_RENEW_LEASE_NB_OP_ALLOC 1 nfs_argop4 argoparray[FSAL_RENEW_LEASE_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_RENEW_LEASE_NB_OP_ALLOC]; LogEvent(COMPONENT_FSAL, "FSAL_proxy_clientid_refresher_thread: starting..."); sleep(6); /** @todo: use getattr to have an actual value of server's lease duration */ memset(&fsal_context, 0, sizeof(proxyfsal_op_context_t)); fsal_status = PROXYFSAL_InitClientContext((fsal_op_context_t *)p_context); if(FSAL_IS_ERROR(fsal_status)) { LogCrit(COMPONENT_FSAL, "FSAL_proxy_clientid_refresher_thread: FSAL error(%u,%u) during init... exiting", fsal_status.major, fsal_status.minor); exit(1); } /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 0; argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; argnfs4.argarray.argarray_val[0].argop = NFS4_OP_RENEW; argnfs4.argarray.argarray_len = 1; while(1) { sleep(60); /** @todo: use getattr to have an actual value of server's lease duration */ /* Call the NFSv4 function */ TakeTokenFSCall(); argoparray[0].nfs_argop4_u.oprenew.clientid = fsal_clientid; COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); LogCrit(COMPONENT_FSAL, "FSAL_PROXY: /!\\ RPC error when connecting to the server"); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) LogCrit(COMPONENT_FSAL, "FSAL_PROXY: /!\\ NFSv4 error %u occured when trying to renew client id %16llx", resnfs4.status, (long long)argoparray[0].nfs_argop4_u.oprenew.clientid); } /* while( 1 ) */ } /* FSAL_proxy_clientid_renewer_thread */
fsal_status_t PROXYFSAL_readlink(proxyfsal_handle_t * linkhandle, /* IN */ proxyfsal_op_context_t * p_context, /* IN */ fsal_path_t * p_link_content, /* OUT */ fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh; bitmap4 bitmap; uint32_t bitmap_val[2]; fsal_attrib_list_t attributes; #define FSAL_READLINK_NB_OP_ALLOC 4 nfs_argop4 argoparray[FSAL_READLINK_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_READLINK_NB_OP_ALLOC]; uint32_t bitmap_res[2]; fsal_proxy_internal_fattr_t fattr_internal; char padpath[FSAL_MAX_PATH_LEN]; struct timeval timeout = TIMEOUTRPC; /* sanity checks. * note : link_attributes is optional. */ if(!linkhandle || !p_context || !p_link_content) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink); /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; fsal_internal_proxy_setup_fattr(&fattr_internal); argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Readlink" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; /* >> retrieve root handle filehandle here << */ bitmap.bitmap4_val = bitmap_val; bitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&bitmap); if(fsal_internal_proxy_extract_fh(&nfs4fh, linkhandle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink); #define FSAL_READLINK_IDX_OP_PUTFH 0 #define FSAL_READLINK_IDX_OP_READLINK 1 #define FSAL_READLINK_IDX_OP_GETATTR 2 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_READLINK(argnfs4); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_READLINK].nfs_resop4_u.opreadlink. READLINK4res_u.resok4.link.utf8string_val = (char *)padpath; resnfs4.resarray.resarray_val[FSAL_READLINK_IDX_OP_READLINK].nfs_resop4_u.opreadlink. READLINK4res_u.resok4.link.utf8string_len = FSAL_MAX_PATH_LEN; TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, rc, INDEX_FSAL_readlink); } ReleaseTokenFSCall(); /* >> convert error code and return on error << */ if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_readlink); /* >> convert fs output to fsal_path_t * for example, if this is a char * (link_content_out) : */ if(fsal_internal_proxy_fsal_utf8_2_path(p_link_content, &(resnfs4.resarray.resarray_val [FSAL_READLINK_IDX_OP_READLINK]. nfs_resop4_u.opreadlink.READLINK4res_u.resok4. link)) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink); /* retrieves object attributes, if asked */ if(link_attributes) { /* Use NFSv4 service function to build the FSAL_attr */ if(nfs4_Fattr_To_FSAL_attr(&attributes, &resnfs4.resarray. resarray_val[FSAL_READLINK_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) { FSAL_CLEAR_MASK(link_attributes->asked_attributes); FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_readlink); } memcpy(link_attributes, &attributes, sizeof(attributes)); } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink); }
fsal_status_t PROXYFSAL_readdir(fsal_dir_t * dir_desc, /* IN */ fsal_cookie_t start_pos, /* IN */ fsal_attrib_mask_t get_attr_mask, /* IN */ fsal_mdsize_t buffersize, /* IN */ fsal_dirent_t * pdirent, /* OUT */ fsal_cookie_t * end_position, /* OUT */ fsal_count_t * nb_entries, /* OUT */ fsal_boolean_t * end_of_dir /* OUT */ ) { nfs_fh4 nfs4fh; bitmap4 bitmap; uint32_t bitmap_val[2]; count4 nbreaddir; int rc = 0; int i = 0; int cpt = 0; entry4 *piter_entry = NULL; entry4 tabentry4[FSAL_READDIR_SIZE]; //char tabentry4name[FSAL_READDIR_SIZE][MAXNAMLEN]; char * tabentry4name = NULL ; uint32_t tabentry4bitmap[FSAL_READDIR_SIZE][2]; struct timeval timeout = TIMEOUTRPC; //fsal_proxy_internal_fattr_readdir_t tabentry4attr[FSAL_READDIR_SIZE]; fsal_proxy_internal_fattr_readdir_t * tabentry4attr = NULL ; #define FSAL_READDIR_NB_OP_ALLOC 2 nfs_argop4 argoparray[FSAL_READDIR_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_READDIR_NB_OP_ALLOC]; COMPOUND4args argnfs4; COMPOUND4res resnfs4; proxyfsal_dir_t * dir_descriptor = (proxyfsal_dir_t *)dir_desc; proxyfsal_cookie_t start_position; /* sanity checks */ if(!dir_descriptor || !pdirent || !end_position || !nb_entries || !end_of_dir) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); if( ( tabentry4name = Mem_Alloc( FSAL_READDIR_SIZE * MAXNAMLEN ) ) == NULL ) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); if( ( tabentry4attr = (fsal_proxy_internal_fattr_readdir_t *)Mem_Alloc( sizeof( fsal_proxy_internal_fattr_readdir_t ) * FSAL_READDIR_SIZE ) ) == NULL ) { Mem_Free( tabentry4name ) ; Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); } start_position.data = (nfs_cookie4)start_pos.data; LogFullDebug(COMPONENT_FSAL, "---> Readdir Offset=%llu sizeof(entry4)=%lu sizeof(fsal_dirent_t)=%lu \n", (unsigned long long)start_position.data, sizeof(entry4), sizeof(fsal_dirent_t)); /* >> retrieve root handle filehandle here << */ bitmap.bitmap4_len = 2; bitmap.bitmap4_val = bitmap_val; fsal_internal_proxy_create_fattr_readdir_bitmap(&bitmap); /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Readdir" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; #define FSAL_READDIR_IDX_OP_PUTFH 0 #define FSAL_READDIR_IDX_OP_READDIR 1 /* Set up reply structure */ resnfs4.resarray.resarray_val = resoparray; /* How much data should I read ? */ nbreaddir = buffersize / (sizeof(fsal_dirent_t)); if(nbreaddir > FSAL_READDIR_SIZE) nbreaddir = FSAL_READDIR_SIZE; memset((char *)tabentry4, 0, FSAL_READDIR_SIZE * sizeof(entry4)); memset((char *)tabentry4name, 0, FSAL_READDIR_SIZE * MAXNAMLEN); memset((char *)tabentry4attr, 0, FSAL_READDIR_SIZE * sizeof(fsal_proxy_internal_fattr_readdir_t)); for(i = 0; i < nbreaddir; i++) { fsal_internal_proxy_setup_readdir_fattr(&tabentry4attr[i]); tabentry4[i].name.utf8string_val = (char *)(tabentry4name+i*MAXNAMLEN*sizeof(char) ) ; tabentry4[i].name.utf8string_len = MAXNAMLEN; tabentry4[i].attrs.attr_vals.attrlist4_val = (char *)&(tabentry4attr[i]); tabentry4[i].attrs.attr_vals.attrlist4_len = sizeof(fsal_proxy_internal_fattr_readdir_t); tabentry4[i].attrs.attrmask.bitmap4_val = tabentry4bitmap[i]; tabentry4[i].attrs.attrmask.bitmap4_len = 2; } resnfs4.resarray.resarray_val[FSAL_READDIR_IDX_OP_READDIR].nfs_resop4_u.opreaddir. READDIR4res_u.resok4.reply.entries = (entry4 *) tabentry4; /* >> Call your filesystem lookup function here << */ if(fsal_internal_proxy_extract_fh(&nfs4fh, (fsal_handle_t *) &dir_descriptor->fhandle) == FALSE) { Mem_Free( tabentry4attr ) ; Mem_Free( tabentry4name ) ; Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); } /** @todo : use NFS4_OP_VERIFY to implement a cache validator, BUGAZOMEU */ COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_READDIR(argnfs4, start_position.data, nbreaddir, dir_descriptor->verifier, bitmap); TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(dir_descriptor->pcontext, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Mem_Free( tabentry4attr ) ; Mem_Free( tabentry4name ) ; Return(ERR_FSAL_IO, rc, INDEX_FSAL_readdir); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_readdir); /* Set the reply structure */ if(resnfs4.resarray.resarray_val[FSAL_READDIR_IDX_OP_READDIR].nfs_resop4_u.opreaddir. READDIR4res_u.resok4.reply.eof == TRUE) { *end_of_dir = TRUE; } /* >> convert error code and return on error << */ /* >> fill the output dirent array << */ /* until the requested count is reached * or the end of dir is reached... */ /* Don't forget setting output vars : end_position, nb_entries, end_of_dir */ for(piter_entry = resnfs4.resarray.resarray_val[FSAL_READDIR_IDX_OP_READDIR].nfs_resop4_u.opreaddir. READDIR4res_u.resok4.reply.entries; piter_entry != NULL; piter_entry = piter_entry->nextentry) { if(proxy_Fattr_To_FSAL_attr(&pdirent[cpt].attributes, (proxyfsal_handle_t *) &(pdirent[cpt].handle), &(piter_entry->attrs)) != 1) { FSAL_CLEAR_MASK(pdirent[cpt].attributes.asked_attributes); FSAL_SET_MASK(pdirent[cpt].attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR); Mem_Free( tabentry4attr ) ; Mem_Free( tabentry4name ) ; Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); } if(fsal_internal_proxy_fsal_utf8_2_name(&(pdirent[cpt].name), &(piter_entry->name)) == FALSE) { Mem_Free( tabentry4attr ) ; Mem_Free( tabentry4name ) ; Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); } /* Link the entries together */ pdirent[cpt].nextentry = NULL; /* Will be overwritten if there is an entry behind, stay NULL if not */ if(cpt != 0) pdirent[cpt - 1].nextentry = &pdirent[cpt]; /* Set end position */ ((proxyfsal_cookie_t *)end_position)->data = piter_entry->cookie; /* Get ready for next pdirent */ cpt += 1; if(cpt >= FSAL_READDIR_SIZE) break; } /* The number of entries to be returned */ *nb_entries = cpt; Mem_Free( tabentry4attr ) ; Mem_Free( tabentry4name ) ; Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); }
fsal_status_t PROXYFSAL_unlink(proxyfsal_handle_t * parentdir_handle, /* IN */ fsal_name_t * p_object_name, /* IN */ proxyfsal_op_context_t * p_context, /* IN */ fsal_attrib_list_t * parentdir_attributes /* [IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh; bitmap4 bitmap; uint32_t bitmap_val[2]; component4 name; char nameval[MAXNAMLEN]; #define FSAL_UNLINK_NB_OP_ALLOC 3 nfs_argop4 argoparray[FSAL_UNLINK_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_UNLINK_NB_OP_ALLOC]; uint32_t bitmap_res[2]; fsal_proxy_internal_fattr_t fattr_internal; struct timeval timeout = TIMEOUTRPC; /* sanity checks. * note : parentdir_attributes are optional. * parentdir_handle is mandatory, * because, we do not allow to delete FS root ! */ if(!parentdir_handle || !p_context || !p_object_name) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_unlink); /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; fsal_internal_proxy_setup_fattr(&fattr_internal); argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Unlink" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; /* >> retrieve root handle filehandle here << */ bitmap.bitmap4_val = bitmap_val; bitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&bitmap); if(fsal_internal_proxy_extract_fh(&nfs4fh, parentdir_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_unlink); memset((char *)&name, 0, sizeof(component4)); name.utf8string_val = nameval; if(fsal_internal_proxy_fsal_name_2_utf8(p_object_name, &name) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_unlink); #define FSAL_UNLINK_IDX_OP_PUTFH 0 #define FSAL_UNLINK_IDX_OP_REMOVE 1 #define FSAL_UNLINK_IDX_OP_GETATTR 2 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_REMOVE(argnfs4, name); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); resnfs4.resarray.resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, rc, INDEX_FSAL_unlink); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_unlink); /* >> get post op attributes for the parent, if they are asked, * and your filesystem didn't return them << */ if(parentdir_attributes) { if(nfs4_Fattr_To_FSAL_attr(parentdir_attributes, &resnfs4.resarray. resarray_val[FSAL_UNLINK_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) { FSAL_CLEAR_MASK(parentdir_attributes->asked_attributes); FSAL_SET_MASK(parentdir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_unlink); } } /* OK */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_unlink); }
fsal_status_t PROXYFSAL_symlink(proxyfsal_handle_t * parent_directory_handle, /* IN */ fsal_name_t * p_linkname, /* IN */ fsal_path_t * p_linkcontent, /* IN */ proxyfsal_op_context_t * p_context, /* IN */ fsal_accessmode_t accessmode, /* IN (ignored) */ proxyfsal_handle_t * link_handle, /* OUT */ fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh; bitmap4 bitmap; uint32_t bitmap_val[2]; uint32_t bitmap_res[2]; uint32_t bitmap_mkdir[2]; uint32_t bitmap_getattr_res[2]; uint32_t bitmap_conv_val[2]; fattr4 input_attr; bitmap4 convert_bitmap; component4 name; char nameval[MAXNAMLEN]; component4 linkname; char linknameval[MAXNAMLEN]; char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN]; fsal_proxy_internal_fattr_t fattr_internal; fsal_attrib_list_t create_mode_attr; fsal_attrib_list_t attributes; #define FSAL_SYMLINK_NB_OP_ALLOC 4 #define FSAL_SYMLINK_VAL_BUFFER 1024 nfs_argop4 argoparray[FSAL_SYMLINK_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_SYMLINK_NB_OP_ALLOC]; char fattr_val[FSAL_SYMLINK_VAL_BUFFER]; struct timeval timeout = TIMEOUTRPC; /* sanity checks. * note : link_attributes is optional. */ if(!parent_directory_handle || !p_context || !link_handle || !p_linkname || !p_linkcontent) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); /* Tests if symlinking is allowed by configuration. */ if(!global_fs_info.symlink_support) Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_symlink); /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Symlink" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; input_attr.attrmask.bitmap4_val = bitmap_val; input_attr.attrmask.bitmap4_len = 2; input_attr.attr_vals.attrlist4_val = fattr_val; input_attr.attr_vals.attrlist4_len = FSAL_SYMLINK_VAL_BUFFER; fsal_internal_proxy_setup_fattr(&fattr_internal); convert_bitmap.bitmap4_val = bitmap_conv_val; convert_bitmap.bitmap4_len = 2; memset((char *)&name, 0, sizeof(component4)); name.utf8string_val = nameval; if(fsal_internal_proxy_fsal_name_2_utf8(p_linkname, &name) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); memset((char *)&linkname, 0, sizeof(component4)); linkname.utf8string_val = linknameval; if(fsal_internal_proxy_fsal_path_2_utf8(p_linkcontent, &linkname) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); /* Get NFSv4 File handle */ if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); bitmap.bitmap4_val = bitmap_mkdir; bitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&bitmap); create_mode_attr.asked_attributes = FSAL_ATTR_MODE; create_mode_attr.mode = accessmode; fsal_interval_proxy_fsalattr2bitmap4(&create_mode_attr, &convert_bitmap); if(nfs4_FSALattr_To_Fattr(NULL, /* no exportlist required here */ &create_mode_attr, &input_attr, NULL, /* no compound data required here */ NULL, /* No fh here, filehandle is not a settable attribute */ &convert_bitmap) == -1) Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_symlink); #define FSAL_SYMLINK_IDX_OP_PUTFH 0 #define FSAL_SYMLINK_IDX_OP_SYMLINK 1 #define FSAL_SYMLINK_IDX_OP_GETFH 2 #define FSAL_SYMLINK_IDX_OP_GETATTR 3 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_SYMLINK(argnfs4, name, linkname, input_attr); COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_SYMLINK].nfs_resop4_u.opcreate. CREATE4res_u.resok4.attrset.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_SYMLINK].nfs_resop4_u.opcreate. CREATE4res_u.resok4.attrset.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN; resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res; resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, 0, INDEX_FSAL_symlink); } ReleaseTokenFSCall(); /* >> convert error code, and return on error << */ if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_symlink); /* Use NFSv4 service function to build the FSAL_attr */ if(nfs4_Fattr_To_FSAL_attr(&attributes, &resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETATTR]. nfs_resop4_u.opgetattr.GETATTR4res_u.resok4. obj_attributes) != NFS4_OK) { FSAL_CLEAR_MASK(attributes.asked_attributes); FSAL_SET_MASK(attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_symlink); } if(link_attributes) { memcpy(link_attributes, &attributes, sizeof(attributes)); } if(fsal_internal_proxy_create_fh (& (resnfs4.resarray.resarray_val[FSAL_SYMLINK_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object), FSAL_TYPE_LNK, attributes.fileid, link_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink); /* OK */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_symlink); }
/** * FSAL_proxy_clientid_renewer_thread: this thread is made for refreshing the clientid used by the FSAL, automatically. * * This thread is made for refreshing the clientid used by the FSAL, automatically. * * * \return never returns... This is a infinite loop that will die when the daemon stops */ void *FSAL_proxy_clientid_renewer_thread(void *Arg) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; struct timeval timeout = TIMEOUTRPC; fsal_status_t fsal_status; proxyfsal_op_context_t fsal_context; proxyfsal_op_context_t *p_context = &fsal_context; #define FSAL_RENEW_LEASE_NB_OP_ALLOC 1 nfs_argop4 argoparray[FSAL_RENEW_LEASE_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_RENEW_LEASE_NB_OP_ALLOC]; #ifndef _NO_BUDDY_SYSTEM buddy_parameter_t buddy_param = default_buddy_parameter; #endif LogEvent(COMPONENT_FSAL, "FSAL_proxy_clientid_refresher_thread: starting..."); sleep(6); /** @todo: use getattr to have an actual value of server's lease duration */ #ifndef _NO_BUDDY_SYSTEM if((rc = BuddyInit(&buddy_param)) != BUDDY_SUCCESS) { /* Failed init */ LogCrit(COMPONENT_FSAL, "FSAL_proxy_clientid_renewer_thread: Memory manager could not be initialized, exiting..."); exit(1); } #endif memset((char *)&fsal_context, 0, sizeof(proxyfsal_op_context_t)); fsal_status = PROXYFSAL_InitClientContext(p_context); if(FSAL_IS_ERROR(fsal_status)) { LogCrit(COMPONENT_FSAL, "FSAL_proxy_clientid_refresher_thread: FSAL error(%u,%u) during init... exiting", fsal_status.major, fsal_status.minor); exit(1); } /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 0; argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; argnfs4.argarray.argarray_val[0].argop = NFS4_OP_RENEW; argnfs4.argarray.argarray_val[0].nfs_argop4_u.oprenew.clientid = fsal_clientid; argnfs4.argarray.argarray_len = 1; while(1) { sleep(60); /** @todo: use getattr to have an actual value of server's lease duration */ /* Call the NFSv4 function */ TakeTokenFSCall(); COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); LogCrit(COMPONENT_FSAL, "FSAL_PROXY: /!\\ RPC error when connecting to the server"); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) LogCrit(COMPONENT_FSAL, "FSAL_PROXY: /!\\ NFSv4 error %u occured when trying to new clienitf %llu", resnfs4.status, (long long unsigned int)fsal_clientid); } /* while( 1 ) */ } /* FSAL_proxy_clientid_renewer_thread */
/** * FSAL_create: * Create a regular file. * * \param parent_directory_handle (input): * Handle of the parent directory where the file is to be created. * \param p_filename (input): * Pointer to the name of the file to be created. * \param cred (input): * Authentication context for the operation (user, export...). * \param accessmode (input): * Mode for the file to be created. * (the umask defined into the FSAL configuration file * will be applied on it). * \param object_handle (output): * Pointer to the handle of the created file. * \param object_attributes (optionnal input/output): * The postop attributes of the created file. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * Can be NULL. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - ERR_FSAL_STALE (parent_directory_handle does not address an existing object) * - ERR_FSAL_FAULT (a NULL pointer was passed as mandatory argument) * - Other error codes can be returned : * ERR_FSAL_ACCESS, ERR_FSAL_EXIST, ERR_FSAL_IO, ... * * NB: if getting postop attributes failed, * the function does not return an error * but the FSAL_ATTR_RDATTR_ERR bit is set in * the object_attributes->asked_attributes field. */ fsal_status_t PROXYFSAL_create(proxyfsal_handle_t * parent_directory_handle, /* IN */ fsal_name_t * p_filename, /* IN */ proxyfsal_op_context_t * p_context, /* IN */ fsal_accessmode_t accessmode, /* IN */ proxyfsal_handle_t * object_handle, /* OUT */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh; bitmap4 bitmap; uint32_t bitmap_val[2]; uint32_t bitmap_res[2]; uint32_t bitmap_conv_val[2]; uint32_t bitmap_create[2]; uint32_t bitmap_getattr_res[2]; fattr4 input_attr; bitmap4 convert_bitmap; component4 name; char nameval[MAXNAMLEN]; char padfilehandle[FSAL_PROXY_FILEHANDLE_MAX_LEN]; fsal_status_t fsal_status; proxyfsal_file_t fd; #define FSAL_CREATE_NB_OP_ALLOC 4 #define FSAL_CREATE_VAL_BUFFER 1024 fsal_proxy_internal_fattr_t fattr_internal; fsal_attrib_list_t create_mode_attr; fsal_attrib_list_t attributes; nfs_argop4 argoparray[FSAL_CREATE_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_CREATE_NB_OP_ALLOC]; char fattr_val[FSAL_CREATE_VAL_BUFFER]; struct timeval timeout = { 25, 0 }; char owner_val[FSAL_PROXY_OWNER_LEN]; unsigned int owner_len = 0; /* sanity checks. * note : object_attributes is optional. */ if(!parent_directory_handle || !p_context || !object_handle || !p_filename) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create); PRINT_HANDLE("FSAL_create", parent_directory_handle); /* Create the owner */ snprintf(owner_val, FSAL_PROXY_OWNER_LEN, "GANESHA/PROXY: pid=%u ctx=%p file=%llu", getpid(), p_context, (unsigned long long int)p_context->file_counter); owner_len = strnlen(owner_val, FSAL_PROXY_OWNER_LEN); p_context->file_counter += 1; /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Mkdir" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; input_attr.attrmask.bitmap4_val = bitmap_val; input_attr.attrmask.bitmap4_len = 2; input_attr.attr_vals.attrlist4_val = fattr_val; input_attr.attr_vals.attrlist4_len = FSAL_CREATE_VAL_BUFFER; fsal_internal_proxy_setup_fattr(&fattr_internal); convert_bitmap.bitmap4_val = bitmap_conv_val; convert_bitmap.bitmap4_len = 2; memset((char *)&name, 0, sizeof(component4)); name.utf8string_val = nameval; if(fsal_internal_proxy_fsal_name_2_utf8(p_filename, &name) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create); /* Get NFSv4 File handle */ if(fsal_internal_proxy_extract_fh(&nfs4fh, parent_directory_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create); if(isFullDebug(COMPONENT_FSAL)) { char outstr[1024]; nfs4_sprint_fhandle(&nfs4fh, outstr); LogFullDebug(COMPONENT_FSAL, "FSAL_CREATE: extracted server (as client) parent handle=%s\n", outstr); } bitmap.bitmap4_val = bitmap_create; bitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&bitmap); create_mode_attr.asked_attributes = FSAL_ATTR_MODE; create_mode_attr.mode = accessmode; fsal_interval_proxy_fsalattr2bitmap4(&create_mode_attr, &convert_bitmap); if(nfs4_FSALattr_To_Fattr(NULL, /* no exportlist required here */ &create_mode_attr, &input_attr, NULL, /* no compound data required here */ NULL, /* No fh here, filehandle is not a settable attribute */ &convert_bitmap) == -1) Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_create); #define FSAL_CREATE_IDX_OP_PUTFH 0 #define FSAL_CREATE_IDX_OP_OPEN_CREATE 1 #define FSAL_CREATE_IDX_OP_GETFH 2 #define FSAL_CREATE_IDX_OP_GETATTR 3 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_OPEN_CREATE(argnfs4, name, input_attr, p_context->clientid, owner_val, owner_len); COMPOUNDV4_ARG_ADD_OP_GETFH(argnfs4); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen. OPEN4res_u.resok4.attrset.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen. OPEN4res_u.resok4.attrset.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_val = (char *)padfilehandle; resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object.nfs_fh4_len = FSAL_PROXY_FILEHANDLE_MAX_LEN; resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_getattr_res; resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, rc, INDEX_FSAL_create); } ReleaseTokenFSCall(); /* >> convert error code, and return on error << */ if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_create); /* Use NFSv4 service function to build the FSAL_attr */ if(nfs4_Fattr_To_FSAL_attr(&attributes, &resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETATTR]. nfs_resop4_u.opgetattr.GETATTR4res_u.resok4. obj_attributes) != 1) { FSAL_CLEAR_MASK(attributes.asked_attributes); FSAL_SET_MASK(attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_create); } /* Return attributes if asked */ if(object_attributes) { memcpy(object_attributes, &attributes, sizeof(attributes)); } if(isFullDebug(COMPONENT_FSAL)) { char outstr[1024]; nfs4_sprint_fhandle(&nfs4fh, outstr); LogFullDebug(COMPONENT_FSAL, "FSAL_CREATE: extracted server (as client) created file handle=%s\n", outstr); } if(fsal_internal_proxy_create_fh (& (resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_GETFH].nfs_resop4_u.opgetfh. GETFH4res_u.resok4.object), FSAL_TYPE_FILE, attributes.fileid, object_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create); /* Keep the information into the file descriptor as well */ memcpy((char *)&fd.fhandle, (char *)object_handle, sizeof(fd.fhandle)); fd.openflags = FSAL_O_RDWR; fd.current_offset = 0; fd.pcontext = p_context; /* Keep the returned stateid for later use */ fd.stateid.seqid = resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen. OPEN4res_u.resok4.stateid.seqid; memcpy((char *)fd.stateid.other, resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u. opopen.OPEN4res_u.resok4.stateid.other, 12); /* See if a OPEN_CONFIRM is required */ if(resnfs4.resarray.resarray_val[FSAL_CREATE_IDX_OP_OPEN_CREATE].nfs_resop4_u.opopen. OPEN4res_u.resok4.rflags & OPEN4_RESULT_CONFIRM) { fsal_status = FSAL_proxy_open_confirm(&fd); if(FSAL_IS_ERROR(fsal_status)) Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_create); } #ifdef _FSAL_CREATE_CLOSE_FILE /* The craeted file is still opened, to preserve the correct seqid for later use, we close it */ fsal_status = FSAL_close(&fd); if(FSAL_IS_ERROR(fsal_status)) Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_create); #endif /* OK */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_create); } /* FSAL_create */
/** * FSAL_link: * Create a hardlink. * * \param target_handle (input): * Handle of the target object. * \param dir_handle (input): * Pointer to the directory handle where * the hardlink is to be created. * \param p_link_name (input): * Pointer to the name of the hardlink to be created. * \param cred (input): * Authentication context for the operation (user,...). * \param accessmode (input): * Mode for the directory to be created. * (the umask defined into the FSAL configuration file * will be applied on it). * \param attributes (optionnal input/output): * The post_operation attributes of the linked object. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * May be NULL. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - ERR_FSAL_STALE (target_handle or dir_handle does not address an existing object) * - ERR_FSAL_FAULT (a NULL pointer was passed as mandatory argument) * - Other error codes can be returned : * ERR_FSAL_ACCESS, ERR_FSAL_EXIST, ERR_FSAL_IO, ... * * NB: if getting postop attributes failed, * the function does not return an error * but the FSAL_ATTR_RDATTR_ERR bit is set in * the attributes->asked_attributes field. */ fsal_status_t PROXYFSAL_link(proxyfsal_handle_t * target_handle, /* IN */ proxyfsal_handle_t * dir_handle, /* IN */ fsal_name_t * p_link_name, /* IN */ proxyfsal_op_context_t * p_context, /* IN */ fsal_attrib_list_t * attributes /* [ IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh_target; nfs_fh4 nfs4fh_dest; bitmap4 bitmap; uint32_t bitmap_val[2]; uint32_t bitmap_res[2]; component4 name; char nameval[MAXNAMLEN]; fsal_proxy_internal_fattr_t fattr_internal; struct timeval timeout = { 25, 0 }; /* sanity checks. * note : attributes is optional. */ if(!target_handle || !dir_handle || !p_context || !p_link_name) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link); /* Tests if hardlinking is allowed by configuration. */ if(!global_fs_info.link_support) Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_link); #define FSAL_LINK_NB_OP_ALLOC 6 nfs_argop4 argoparray[FSAL_LINK_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_LINK_NB_OP_ALLOC]; /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; fsal_internal_proxy_setup_fattr(&fattr_internal); argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Link" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; bitmap.bitmap4_val = bitmap_val; bitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&bitmap); if(fsal_internal_proxy_extract_fh(&nfs4fh_target, target_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link); if(fsal_internal_proxy_extract_fh(&nfs4fh_dest, dir_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link); memset((char *)&name, 0, sizeof(component4)); name.utf8string_val = nameval; if(fsal_internal_proxy_fsal_name_2_utf8(p_link_name, &name) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link); #define FSAL_LINK_IDX_OP_PUTFH_TARGET 0 #define FSAL_LINK_IDX_OP_SAVEFH 1 #define FSAL_LINK_IDX_OP_PUTFH_DEST 2 #define FSAL_LINK_IDX_OP_LINK 3 #define FSAL_LINK_IDX_OP_RESTOREFH 4 #define FSAL_LINK_IDX_OP_GETATTR 5 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_target); COMPOUNDV4_ARG_ADD_OP_SAVEFH(argnfs4); COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh_dest); COMPOUNDV4_ARG_ADD_OP_LINK(argnfs4, name); COMPOUNDV4_ARG_ADD_OP_RESTOREFH(argnfs4); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, rc, INDEX_FSAL_link); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_link); if(attributes) { /* Use NFSv4 service function to build the FSAL_attr */ if(nfs4_Fattr_To_FSAL_attr(attributes, &resnfs4.resarray. resarray_val[FSAL_LINK_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes) != 1) { FSAL_CLEAR_MASK(attributes->asked_attributes); FSAL_SET_MASK(attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_link); } } /* OK */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_link); }
fsal_status_t PROXYFSAL_truncate(fsal_handle_t * file_hdl, /* IN */ fsal_op_context_t * context, /* IN */ fsal_size_t length, /* IN */ fsal_file_t * file_descriptor, /* [IN|OUT] */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; nfs_fh4 nfs4fh; uint64_t fileid; fsal_status_t fsal_status; fsal_attrib_list_t open_attrs; 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]; proxyfsal_handle_t * filehandle = (proxyfsal_handle_t *)file_hdl; proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; #define FSAL_TRUNCATE_NB_OP_ALLOC 3 nfs_argop4 argoparray[FSAL_TRUNCATE_NB_OP_ALLOC]; nfs_resop4 resoparray[FSAL_TRUNCATE_NB_OP_ALLOC]; fsal_attrib_list_t fsal_attr_set; fattr4 fattr_set; fsal_proxy_internal_fattr_t fattr_internal; struct timeval timeout = TIMEOUTRPC; /* sanity checks. * note : object_attributes is optional. */ if(!filehandle || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate); if(filehandle->data.object_type_reminder != FSAL_TYPE_FILE) { Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate); } if(file_descriptor == NULL) { /* Use the stateless version */ fsal_status = FSAL_proxy_truncate_stateless(file_hdl, context, length, object_attributes); Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate); } /* First, we need to get the fileid on a filehandle base */ fsal_status = FSAL_DigestHandle(context->export_context, FSAL_DIGEST_FILEID4, file_hdl, (caddr_t) & fileid); if(FSAL_IS_ERROR(fsal_status)) { Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate); } /* Then we have of open the file by fileid */ open_attrs.asked_attributes = FSAL_ATTRS_POSIX; fsal_status = FSAL_open_by_fileid(file_hdl, fileid, context, FSAL_O_RDWR, file_descriptor, &open_attrs); if(FSAL_IS_ERROR(fsal_status)) { Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate); } /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; fsal_internal_proxy_setup_fattr(&fattr_internal); argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Truncate" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; /* Get NFSv4 File handle */ if(fsal_internal_proxy_extract_fh(&nfs4fh, file_hdl) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate); /* Get prepared for truncate */ fsal_attr_set.asked_attributes = FSAL_ATTR_SIZE; fsal_attr_set.filesize = length; convert_bitmap.bitmap4_val = bitmap_conv_val; convert_bitmap.bitmap4_len = 2; fsal_interval_proxy_fsalattr2bitmap4(&fsal_attr_set, &convert_bitmap); 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(ERR_FSAL_INVAL, -1, INDEX_FSAL_truncate); inbitmap.bitmap4_val = inbitmap_val; inbitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&inbitmap); #define FSAL_TRUNCATE_IDX_OP_PUTFH 0 #define FSAL_TRUNCATE_IDX_OP_SETATTR 1 #define FSAL_TRUNCATE_IDX_OP_GETATTR 2 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_SETATTR(argnfs4, fattr_set); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, inbitmap); /* For ATTR_SIZE, stateid is needed */ argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u.opsetattr. stateid.seqid = ((proxyfsal_file_t *)file_descriptor)->stateid.seqid; memcpy(argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u. opsetattr.stateid.other, ((proxyfsal_file_t *)file_descriptor)->stateid.other, 12); resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u.opsetattr. attrsset.bitmap4_val = bitmap_set; resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u.opsetattr. attrsset.bitmap4_len = 2; TakeTokenFSCall(); COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, 0, INDEX_FSAL_truncate); } ReleaseTokenFSCall(); if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_truncate); /* >> interpret error code << */ /* >> Optionnaly retrieve post op attributes * If your filesystem truncate call can't return them, * you can proceed like this : << */ if(object_attributes) { if(nfs4_Fattr_To_FSAL_attr(object_attributes, &resnfs4.resarray. resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) { FSAL_CLEAR_MASK(object_attributes->asked_attributes); FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate); } } /* Close the previously opened filedescriptor */ fsal_status = FSAL_close_by_fileid(file_descriptor, fileid); if(FSAL_IS_ERROR(fsal_status)) { Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate); } /* No error occured */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_truncate); }
/** * PROXYFSAL_access : * Tests whether the user or entity identified by the p_context structure * can access the object identified by object_handle, * as indicated by the access_type parameter. * * \param object_handle (input): * The handle of the object to test permissions on. * \param p_context (input): * Authentication context for the operation (export entry, user,...). * \param access_type (input): * Indicates the permissions to be tested. * This is an inclusive OR of the permissions * to be checked for the user specified by p_context. * Permissions constants are : * - FSAL_R_OK : test for read permission * - FSAL_W_OK : test for write permission * - FSAL_X_OK : test for exec permission * - FSAL_F_OK : test for file existence * \param object_attributes (optional input/output): * The post operation attributes for the object. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * Can be NULL. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error, asked permission is granted) * - ERR_FSAL_ACCESS (object permissions doesn't fit asked access type) * - ERR_FSAL_STALE (object_handle does not address an existing object) * - ERR_FSAL_FAULT (a NULL pointer was passed as mandatory argument) * - Other error codes when something anormal occurs. */ fsal_status_t PROXYFSAL_access(fsal_handle_t * object_handle, /* IN */ fsal_op_context_t *context, /* IN */ fsal_accessflags_t access_type, /* IN */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { int rc; COMPOUND4args argnfs4; COMPOUND4res resnfs4; bitmap4 bitmap; uint32_t bitmap_val[2]; uint32_t bitmap_res[2]; uint32_t accessflag = 0; proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; fsal_proxy_internal_fattr_t fattr_internal; struct timeval __attribute__ ((__unused__)) timeout = TIMEOUTRPC; nfs_fh4 nfs4fh; #define FSAL_ACCESS_NB_OP_ACCESS 3 nfs_argop4 argoparray[FSAL_ACCESS_NB_OP_ACCESS]; nfs_resop4 resoparray[FSAL_ACCESS_NB_OP_ACCESS]; /* sanity checks. * note : object_attributes is optional in PROXYFSAL_access. */ if(!object_handle || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_access); /* Setup results structures */ argnfs4.argarray.argarray_val = argoparray; resnfs4.resarray.resarray_val = resoparray; fsal_internal_proxy_setup_fattr(&fattr_internal); argnfs4.minorversion = 0; /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Access" ; */ argnfs4.tag.utf8string_val = NULL; argnfs4.tag.utf8string_len = 0; argnfs4.argarray.argarray_len = 0; bitmap.bitmap4_val = bitmap_val; bitmap.bitmap4_len = 2; fsal_internal_proxy_create_fattr_bitmap(&bitmap); /* Set up access flags */ if(access_type & FSAL_R_OK) accessflag |= ACCESS4_READ; if(access_type & FSAL_X_OK) accessflag |= ACCESS4_LOOKUP; if(access_type & FSAL_W_OK) accessflag |= (ACCESS4_MODIFY & ACCESS4_EXTEND); if(access_type & FSAL_F_OK) accessflag |= ACCESS4_LOOKUP; /* >> convert your fsal access type to your FS access type << */ /* Get NFSv4 File handle */ if(fsal_internal_proxy_extract_fh(&nfs4fh, object_handle) == FALSE) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_access); #define FSAL_ACCESS_IDX_OP_PUTFH 0 #define FSAL_ACCESS_IDX_OP_ACCESS 1 #define FSAL_ACCESS_IDX_OP_GETATTR 2 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); COMPOUNDV4_ARG_ADD_OP_ACCESS(argnfs4, accessflag); COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, bitmap); resnfs4.resarray.resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; resnfs4.resarray.resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; resnfs4.resarray.resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = (char *)&fattr_internal; resnfs4.resarray.resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = sizeof(fattr_internal); TakeTokenFSCall(); /* Call the NFSv4 function */ COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); if(rc != RPC_SUCCESS) { ReleaseTokenFSCall(); Return(ERR_FSAL_IO, resnfs4.status, INDEX_FSAL_access); } ReleaseTokenFSCall(); /* >> convert the returned code, an return it on error << */ if(resnfs4.status != NFS4_OK) return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_access); /* get attributes if object_attributes is not null. * If an error occures during getattr operation, * an error bit is set in the output structure. */ if(object_attributes) { /* Use NFSv4 service function to build the FSAL_attr */ if(nfs4_Fattr_To_FSAL_attr(object_attributes, &resnfs4.resarray. resarray_val[FSAL_ACCESS_IDX_OP_GETATTR].nfs_resop4_u. opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) { FSAL_CLEAR_MASK(object_attributes->asked_attributes); FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_access); } } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_access); }