/** * @brief Free memory allocated for GETATTR result * * This function frees any memory allocated for the result of the * NFS4_OP_GETATTR operation. * * @param[in,out] resp nfs4_op results */ void nfs4_op_getattr_Free(nfs_resop4 *res) { GETATTR4res *resp = &res->nfs_resop4_u.opgetattr; if (resp->status == NFS4_OK) nfs4_Fattr_Free(&resp->GETATTR4res_u.resok4.obj_attributes); } /* nfs4_op_getattr_Free */
int nfs4_op_nverify(struct nfs_argop4 *op, compound_data_t *data, struct nfs_resop4 *resp) { NVERIFY4args * const arg_NVERIFY4 = &op->nfs_argop4_u.opnverify; NVERIFY4res * const res_NVERIFY4 = &resp->nfs_resop4_u.opnverify; fattr4 file_attr4; int rc = 0; resp->resop = NFS4_OP_NVERIFY; res_NVERIFY4->status = NFS4_OK; /* Do basic checks on a filehandle */ res_NVERIFY4->status = nfs4_sanity_check_FH(data, NO_FILE_TYPE, false); if (res_NVERIFY4->status != NFS4_OK) return res_NVERIFY4->status; /* operation is always permitted on pseudofs */ if (nfs4_Is_Fh_Pseudo(&(data->currentFH))) { res_NVERIFY4->status = NFS4_OK; return res_NVERIFY4->status; } /* Get only attributes that are allowed to be read */ if (!nfs4_Fattr_Check_Access(&arg_NVERIFY4->obj_attributes, FATTR4_ATTR_READ)) { res_NVERIFY4->status = NFS4ERR_INVAL; return res_NVERIFY4->status; } /* Ask only for supported attributes */ if (!nfs4_Fattr_Supported(&arg_NVERIFY4->obj_attributes)) { res_NVERIFY4->status = NFS4ERR_ATTRNOTSUPP; return res_NVERIFY4->status; } res_NVERIFY4->status = cache_entry_To_Fattr(data->current_entry, &file_attr4, data, &(data->currentFH), &(arg_NVERIFY4->obj_attributes.attrmask)); if (res_NVERIFY4->status != NFS4_OK) return res_NVERIFY4->status; rc = nfs4_Fattr_cmp(&arg_NVERIFY4->obj_attributes, &file_attr4); if (rc == false) { res_NVERIFY4->status = NFS4_OK; } else { if (rc == -1) res_NVERIFY4->status = NFS4ERR_INVAL; else res_NVERIFY4->status = NFS4ERR_SAME; } nfs4_Fattr_Free(&file_attr4); return res_NVERIFY4->status; } /* nfs4_op_nverify */
/** * nfs4_op_getattr_Free: frees what was allocared to handle nfs4_op_getattr. * * Frees what was allocared to handle nfs4_op_getattr. * * @param resp [INOUT] Pointer to nfs4_op results * * @return nothing (void function ) * */ void nfs4_op_getattr_Free(GETATTR4res * resp) { if(resp->status == NFS4_OK) nfs4_Fattr_Free(&resp->GETATTR4res_u.resok4.obj_attributes); return; } /* nfs4_op_getattr_Free */
int nfs4_op_verify(struct nfs_argop4 *op, compound_data_t *data, struct nfs_resop4 *resp) { VERIFY4args * const arg_VERIFY4 = &op->nfs_argop4_u.opverify; VERIFY4res * const res_VERIFY4 = &resp->nfs_resop4_u.opverify; fattr4 file_attr4; int rc = 0; struct attrlist attrs; resp->resop = NFS4_OP_VERIFY; res_VERIFY4->status = NFS4_OK; /* Do basic checks on a filehandle */ res_VERIFY4->status = nfs4_sanity_check_FH(data, NO_FILE_TYPE, false); if (res_VERIFY4->status != NFS4_OK) return res_VERIFY4->status; /* Get only attributes that are allowed to be read */ if (!nfs4_Fattr_Check_Access (&arg_VERIFY4->obj_attributes, FATTR4_ATTR_READ)) { res_VERIFY4->status = NFS4ERR_INVAL; return res_VERIFY4->status; } /* Ask only for supported attributes */ if (!nfs4_Fattr_Supported(&arg_VERIFY4->obj_attributes)) { res_VERIFY4->status = NFS4ERR_ATTRNOTSUPP; return res_VERIFY4->status; } fsal_prepare_attrs(&attrs, 0); res_VERIFY4->status = bitmap4_to_attrmask_t(&arg_VERIFY4->obj_attributes.attrmask, &attrs.mask); if (res_VERIFY4->status != NFS4_OK) return res_VERIFY4->status; res_VERIFY4->status = file_To_Fattr(data, attrs.mask, &attrs, &file_attr4, &arg_VERIFY4->obj_attributes.attrmask); if (res_VERIFY4->status != NFS4_OK) return res_VERIFY4->status; /* Done with the attrs */ fsal_release_attrs(&attrs); rc = nfs4_Fattr_cmp(&(arg_VERIFY4->obj_attributes), &file_attr4); if (rc == true) res_VERIFY4->status = NFS4_OK; else if (rc == -1) res_VERIFY4->status = NFS4ERR_INVAL; else res_VERIFY4->status = NFS4ERR_NOT_SAME; nfs4_Fattr_Free(&file_attr4); return res_VERIFY4->status; } /* nfs4_op_verify */
int nfs4_op_verify(struct nfs_argop4 *op, compound_data_t * data, struct nfs_resop4 *resp) { char __attribute__ ((__unused__)) funcname[] = "nfs4_op_verify"; fsal_attrib_list_t file_attr; cache_inode_status_t cache_status; fattr4 file_attr4; int rc = 0; resp->resop = NFS4_OP_VERIFY; res_VERIFY4.status = NFS4_OK; /* Do basic checks on a filehandle */ res_VERIFY4.status = nfs4_sanity_check_FH(data, 0LL); if(res_VERIFY4.status != NFS4_OK) return res_VERIFY4.status; /* operation is always permitted on pseudofs */ if(nfs4_Is_Fh_Pseudo(&(data->currentFH))) { res_VERIFY4.status = NFS4_OK; return res_VERIFY4.status; } /* Get only attributes that are allowed to be read */ if(!nfs4_Fattr_Check_Access(&arg_VERIFY4.obj_attributes, FATTR4_ATTR_READ)) { res_VERIFY4.status = NFS4ERR_INVAL; return res_VERIFY4.status; } /* Ask only for supported attributes */ if(!nfs4_Fattr_Supported(&arg_VERIFY4.obj_attributes)) { res_VERIFY4.status = NFS4ERR_ATTRNOTSUPP; return res_VERIFY4.status; } /* Get the cache inode attribute */ if((cache_status = cache_inode_getattr(data->current_entry, &file_attr, data->pcontext, &cache_status)) != CACHE_INODE_SUCCESS) { res_VERIFY4.status = NFS4ERR_INVAL; return res_VERIFY4.status; } if(nfs4_FSALattr_To_Fattr(data->pexport, &file_attr, &file_attr4, data, &(data->currentFH), &(arg_VERIFY4.obj_attributes.attrmask)) != 0) { res_VERIFY4.status = NFS4ERR_SERVERFAULT; return res_VERIFY4.status; } if((rc = nfs4_Fattr_cmp(&(arg_VERIFY4.obj_attributes), &file_attr4)) == TRUE) res_VERIFY4.status = NFS4_OK; else { if(rc == -1) res_VERIFY4.status = NFS4ERR_INVAL; else res_VERIFY4.status = NFS4ERR_NOT_SAME; } nfs4_Fattr_Free(&file_attr4); return res_VERIFY4.status; } /* nfs4_op_verify */
fsal_status_t PROXYFSAL_symlink(fsal_handle_t * parent_directory_handle, /* IN */ fsal_name_t * p_linkname, /* IN */ fsal_path_t * p_linkcontent, /* IN */ fsal_op_context_t *context, /* IN */ fsal_accessmode_t accessmode, /* IN (ignored) */ fsal_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_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+1]; component4 linkname; char linknameval[MAXNAMLEN+1]; 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; proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; #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]; 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; 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; name.utf8string_len = sizeof(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); nfs4_Fattr_Free(&input_attr); 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, ANON_UID, ANON_GID) != 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); }