/** * * proxy_Fattr_To_FSAL_attr: Converts NFSv4 attributes buffer to a FSAL attributes structure. * * Converts NFSv4 attributes buffer to a FSAL attributes structure. * * @param pFSAL_attr [OUT] pointer to FSAL attributes. * @param Fattr [IN] pointer to NFSv4 attributes. * * @return 1 if successful, 0 if not supported, -1 if argument is badly formed * */ int proxy_Fattr_To_FSAL_attr(fsal_attrib_list_t * pFSAL_attr, proxyfsal_handle_t * phandle, fattr4 * Fattr) { nfs_fh4 hdl4; if (Fattr4_To_FSAL_attr(pFSAL_attr, Fattr, &hdl4) != NFS4_OK) return -1; return fsal_internal_proxy_create_fh(&hdl4, pFSAL_attr->type, pFSAL_attr->fileid, (fsal_handle_t *)phandle); } /* proxy_Fattr_To_FSAL_attr */
/** * * proxy_Fattr_To_FSAL_attr: Converts NFSv4 attributes buffer to a FSAL attributes structure. * * Converts NFSv4 attributes buffer to a FSAL attributes structure. * * @param pFSAL_attr [OUT] pointer to FSAL attributes. * @param Fattr [IN] pointer to NFSv4 attributes. * * @return 1 if successful, 0 if not supported, -1 if argument is badly formed * */ int proxy_Fattr_To_FSAL_attr(fsal_attrib_list_t * pFSAL_attr, proxyfsal_handle_t * phandle, fattr4 * Fattr) { u_int LastOffset = 0; unsigned int i = 0; char __attribute__ ((__unused__)) funcname[] = "proxy_Fattr_To_FSAL_attr"; uint32_t attrmasklist[FATTR4_MOUNTED_ON_FILEID]; /* List cannot be longer than FATTR4_MOUNTED_ON_FILEID */ uint32_t attrmasklen = 0; uint32_t attribute_to_set = 0; int len; char buffer[MAXNAMLEN]; utf8string utf8buffer; fattr4_type attr_type; fattr4_fsid attr_fsid; fattr4_fileid attr_fileid; fattr4_time_modify_set attr_time_set; fattr4_rdattr_error rdattr_error; nfstime4 attr_time; fattr4_size attr_size; fattr4_change attr_change; fattr4_numlinks attr_numlinks; fattr4_rawdev attr_rawdev; fattr4_space_used attr_space_used; fattr4_time_access attr_time_access; fattr4_time_modify attr_time_modify; fattr4_time_metadata attr_time_metadata; nfs_fh4 nfshandle; bool_t compute_fh = FALSE; if(pFSAL_attr == NULL || Fattr == NULL) return -1; /* Check attributes data */ if(Fattr->attr_vals.attrlist4_val == NULL) return -1; /* Convert the attribute bitmap to an attribute list */ nfs4_bitmap4_to_list(&(Fattr->attrmask), &attrmasklen, attrmasklist); LogFullDebug(COMPONENT_NFS_V4, "nfs4_bitmap4_to_list ====> attrmasklen = %d\n", attrmasklen); /* Init */ pFSAL_attr->asked_attributes = 0; for(i = 0; i < attrmasklen; i++) { attribute_to_set = attrmasklist[i]; if(attrmasklist[i] > FATTR4_MOUNTED_ON_FILEID) { /* Erroneous value... skip */ continue; } LogFullDebug(COMPONENT_NFS_V4, "=================> nfs4_Fattr_To_FSAL_attr: i=%u attr=%u\n", i, attrmasklist[i]); LogFullDebug(COMPONENT_NFS_V4, "Flag for Operation = %d|%d is ON, name = %s reply_size = %d\n", attrmasklist[i], fattr4tab[attribute_to_set].val, fattr4tab[attribute_to_set].name, fattr4tab[attribute_to_set].size_fattr4); switch (attribute_to_set) { case FATTR4_TYPE: /* Used only by FSAL_PROXY to reverse convert */ memcpy((char *)&attr_type, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_type)); switch (ntohl(attr_type)) { case NF4REG: pFSAL_attr->type = FSAL_TYPE_FILE; break; case NF4DIR: pFSAL_attr->type = FSAL_TYPE_DIR; break; case NF4BLK: pFSAL_attr->type = FSAL_TYPE_BLK; break; case NF4CHR: pFSAL_attr->type = FSAL_TYPE_CHR; break; case NF4LNK: pFSAL_attr->type = FSAL_TYPE_LNK; break; case NF4SOCK: pFSAL_attr->type = FSAL_TYPE_SOCK; break; case NF4FIFO: pFSAL_attr->type = FSAL_TYPE_FIFO; break; default: /* For wanting of a better solution */ pFSAL_attr->type = 0; break; } /* switch( pattr->type ) */ pFSAL_attr->asked_attributes |= FSAL_ATTR_TYPE; LastOffset += fattr4tab[attribute_to_set].size_fattr4; LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le type %d\n", (int)pFSAL_attr->filesize); break; case FATTR4_FILEID: /* Used only by FSAL_PROXY to reverse convert */ /* The analog to the inode number. RFC3530 says "a number uniquely identifying the file within the filesystem" * I use hpss_GetObjId to extract this information from the Name Server's handle */ memcpy((char *)&attr_fileid, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_fileid)); pFSAL_attr->fileid = nfs_ntohl64(attr_fileid); pFSAL_attr->asked_attributes |= FSAL_ATTR_FILEID; LastOffset += fattr4tab[attribute_to_set].size_fattr4; break; case FATTR4_FSID: /* Used only by FSAL_PROXY to reverse convert */ memcpy((char *)&attr_fsid, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_fsid)); pFSAL_attr->fsid.major = nfs_ntohl64(attr_fsid.major); pFSAL_attr->fsid.minor = nfs_ntohl64(attr_fsid.minor); pFSAL_attr->asked_attributes |= FSAL_ATTR_FSID; LastOffset += fattr4tab[attribute_to_set].size_fattr4; break; case FATTR4_NUMLINKS: /* Used only by FSAL_PROXY to reverse convert */ memcpy((char *)&attr_numlinks, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_numlinks)); pFSAL_attr->numlinks = ntohl(attr_numlinks); pFSAL_attr->asked_attributes |= FSAL_ATTR_FILEID; LastOffset += fattr4tab[attribute_to_set].size_fattr4; break; case FATTR4_SIZE: memcpy((char *)&attr_size, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_size)); /* Do not forget the XDR marshalling for the fattr4 stuff */ pFSAL_attr->filesize = nfs_ntohl64(attr_size); pFSAL_attr->asked_attributes |= FSAL_ATTR_SIZE; LastOffset += fattr4tab[attribute_to_set].size_fattr4; LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit la taille %d\n", (int)pFSAL_attr->filesize); break; case FATTR4_MODE: memcpy((char *)&(pFSAL_attr->mode), (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_mode)); /* Do not forget the XDR marshalling for the fattr4 stuff */ pFSAL_attr->mode = ntohl(pFSAL_attr->mode); pFSAL_attr->asked_attributes |= FSAL_ATTR_MODE; LastOffset += fattr4tab[attribute_to_set].size_fattr4; LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le mode 0%o\n", pFSAL_attr->mode); break; case FATTR4_OWNER: memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(u_int)); len = ntohl(len); /* xdr marshalling on fattr4 */ LastOffset += sizeof(u_int); memcpy(buffer, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), len); buffer[len] = '\0'; /* Do not forget that xdr_opaque are aligned on 32bit long words */ while((len % 4) != 0) len += 1; LastOffset += len; utf8buffer.utf8string_val = buffer; utf8buffer.utf8string_len = strlen(buffer); utf82uid(&utf8buffer, &(pFSAL_attr->owner)); pFSAL_attr->asked_attributes |= FSAL_ATTR_OWNER; LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le owner %s len = %d\n", buffer, len); LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le owner %d\n", pFSAL_attr->owner); break; case FATTR4_OWNER_GROUP: memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(u_int)); len = ntohl(len); LastOffset += sizeof(u_int); memcpy(buffer, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), len); buffer[len] = '\0'; /* Do not forget that xdr_opaque are aligned on 32bit long words */ while((len % 4) != 0) len += 1; LastOffset += len; utf8buffer.utf8string_val = buffer; utf8buffer.utf8string_len = strlen(buffer); utf82gid(&utf8buffer, &(pFSAL_attr->group)); pFSAL_attr->asked_attributes |= FSAL_ATTR_GROUP; LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le owner_group %s len = %d\n", buffer, len); LogFullDebug(COMPONENT_NFS_V4, "SATTR: On voit le owner_group %d\n", pFSAL_attr->group); break; case FATTR4_CHANGE: memcpy((char *)&attr_change, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_change)); pFSAL_attr->chgtime.seconds = (uint32_t) nfs_ntohl64(attr_change); pFSAL_attr->chgtime.nseconds = 0; pFSAL_attr->change = nfs_ntohl64(attr_change); pFSAL_attr->asked_attributes |= FSAL_ATTR_CHGTIME; pFSAL_attr->asked_attributes |= FSAL_ATTR_CHANGE; LastOffset += fattr4tab[attribute_to_set].size_fattr4; break; case FATTR4_RAWDEV: /* Used only by FSAL_PROXY to reverse convert */ memcpy((char *)&attr_rawdev, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_rawdev)); pFSAL_attr->rawdev.major = (uint32_t) nfs_ntohl64(attr_rawdev.specdata1); pFSAL_attr->rawdev.minor = (uint32_t) nfs_ntohl64(attr_rawdev.specdata2); pFSAL_attr->asked_attributes |= FSAL_ATTR_RAWDEV; LastOffset += fattr4tab[attribute_to_set].size_fattr4; break; case FATTR4_SPACE_USED: /* Used only by FSAL_PROXY to reverse convert */ memcpy((char *)&attr_space_used, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_space_used)); pFSAL_attr->spaceused = (uint32_t) nfs_ntohl64(attr_space_used); pFSAL_attr->asked_attributes |= FSAL_ATTR_SPACEUSED; LastOffset += fattr4tab[attribute_to_set].size_fattr4; break; case FATTR4_TIME_ACCESS: /* Used only by FSAL_PROXY to reverse convert */ memcpy((char *)&attr_time_access.seconds, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(uint64_t)); LastOffset += sizeof( uint64_t ) ; memcpy((char *)&attr_time_access.nseconds, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(uint32_t)); LastOffset += sizeof( uint32_t ) ; pFSAL_attr->atime.seconds = (uint32_t) nfs_ntohl64(attr_time_access.seconds); pFSAL_attr->atime.nseconds = (uint32_t) ntohl(attr_time_access.nseconds); pFSAL_attr->asked_attributes |= FSAL_ATTR_ATIME; break; case FATTR4_TIME_METADATA: /* Used only by FSAL_PROXY to reverse convert */ memcpy((char *)&attr_time_metadata.seconds, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(uint64_t)); LastOffset += sizeof( uint64_t ) ; memcpy((char *)&attr_time_metadata.nseconds, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(uint32_t)); LastOffset += sizeof( uint32_t ) ; pFSAL_attr->ctime.seconds = (uint32_t) nfs_ntohl64(attr_time_metadata.seconds); pFSAL_attr->ctime.nseconds = (uint32_t) ntohl(attr_time_metadata.nseconds); pFSAL_attr->asked_attributes |= FSAL_ATTR_CTIME; break; case FATTR4_TIME_MODIFY: /* Used only by FSAL_PROXY to reverse convert */ memcpy( (char *)&attr_time_modify.seconds, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof( uint64_t ) ); LastOffset += sizeof( uint64_t ) ; memcpy((char *)&attr_time_modify.nseconds, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(uint32_t) ); LastOffset += sizeof( uint32_t ) ; pFSAL_attr->mtime.seconds = (uint32_t) nfs_ntohl64(attr_time_modify.seconds); pFSAL_attr->mtime.nseconds = (uint32_t) ntohl(attr_time_modify.nseconds); pFSAL_attr->asked_attributes |= FSAL_ATTR_MTIME; break; case FATTR4_TIME_ACCESS_SET: memcpy((char *)&attr_time_set, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_time_access_set)); if(ntohl(attr_time_set.set_it) == SET_TO_SERVER_TIME4) { pFSAL_attr->atime.seconds = time(NULL); /* Use current server's time */ pFSAL_attr->atime.nseconds = 0; } else { /* Take care of XDR when dealing with fattr4 */ attr_time = attr_time_set.settime4_u.time; attr_time.seconds = nfs_ntohl64(attr_time.seconds); attr_time.nseconds = ntohl(attr_time.nseconds); pFSAL_attr->atime.seconds = attr_time.seconds; pFSAL_attr->atime.nseconds = attr_time.nseconds; } pFSAL_attr->asked_attributes |= FSAL_ATTR_ATIME; LastOffset += fattr4tab[attribute_to_set].size_fattr4; break; case FATTR4_TIME_MODIFY_SET: memcpy((char *)&attr_time, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_time_modify_set)); if(ntohl(attr_time_set.set_it) == SET_TO_SERVER_TIME4) { pFSAL_attr->mtime.seconds = time(NULL); /* Use current server's time */ pFSAL_attr->mtime.nseconds = 0; } else { /* Take care of XDR when dealing with fattr4 */ attr_time = attr_time_set.settime4_u.time; attr_time.seconds = nfs_ntohl64(attr_time.seconds); attr_time.nseconds = ntohl(attr_time.nseconds); pFSAL_attr->mtime.seconds = attr_time.seconds; pFSAL_attr->mtime.nseconds = attr_time.nseconds; } pFSAL_attr->asked_attributes |= FSAL_ATTR_MTIME; LastOffset += fattr4tab[attribute_to_set].size_fattr4; break; case FATTR4_FILEHANDLE: memcpy(&len, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(u_int)); len = ntohl(len); LastOffset += sizeof(u_int); /* Extract the file handle */ nfshandle.nfs_fh4_len = len; nfshandle.nfs_fh4_val = (char *)(Fattr->attr_vals.attrlist4_val + LastOffset); /* Bogus there: FATTR4_FILEHANDLE = 19 < FATTR4_FILEID = 20... This means that the FH is * is processed BEFORE the fileid. At this point, pFSAL_attr->fileid has not yet been set * and has the value 0. A flag is kept in variable compute_fh to add the fileid later */ fsal_internal_proxy_create_fh(&nfshandle, pFSAL_attr->type, pFSAL_attr->fileid, phandle); LastOffset += len; LogFullDebug(COMPONENT_NFS_V4, "SATTR: On a demande le filehandle len =%u\n", len); compute_fh = TRUE; break; case FATTR4_RDATTR_ERROR: memcpy((char *)&rdattr_error, (char *)(Fattr->attr_vals.attrlist4_val + LastOffset), sizeof(fattr4_rdattr_error)); rdattr_error = ntohl(rdattr_error); LastOffset += fattr4tab[attribute_to_set].size_fattr4; break; default: LogFullDebug(COMPONENT_NFS_V4, "SATTR: Attribut no supporte %d name=%s\n", attribute_to_set, fattr4tab[attribute_to_set].name); LastOffset += fattr4tab[attribute_to_set].size_fattr4; /* return 0 ; *//* Should not stop processing */ break; } /* switch */ } /* for */ if(compute_fh) { phandle->data.fileid4 = pFSAL_attr->fileid; } return 1; } /* proxy_Fattr_To_FSAL_attr */
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_ExpandHandle : * Convert a buffer extracted from NFS handles * to an FSAL handle. * * \param in_type (input): * Indicates the type of digest to be expanded. * \param in_buff (input): * Pointer to the digest to be expanded. * \param out_fsal_handle (output): * The handle built from digest. * * \return The major code is ERR_FSAL_NO_ERROR is no error occured. * Else, it is a non null value. */ fsal_status_t PROXYFSAL_ExpandHandle(proxyfsal_export_context_t * p_expcontext, /* IN */ fsal_digesttype_t in_type, /* IN */ caddr_t in_buff, /* IN */ proxyfsal_handle_t * out_fsal_handle /* OUT */ ) { fsal_nodetype_t nodetype; fsal_u64_t fileid; nfs_fh4 nfs4fh; #ifdef _HANDLE_MAPPING nfs23_map_handle_t map_hdl; proxyfsal_handle_t tmp_hdl; int rc; #endif /* sanity checks */ if(!out_fsal_handle || !in_buff || !p_expcontext) ReturnCode(ERR_FSAL_FAULT, 0); switch (in_type) { case FSAL_DIGEST_NFSV2: case FSAL_DIGEST_NFSV3: #ifdef _HANDLE_MAPPING if(!global_fsal_proxy_specific_info.enable_handle_mapping) ReturnCode(ERR_FSAL_NOTSUPP, 0); /* retrieve significant info */ memcpy(&map_hdl, in_buff, sizeof(nfs23_map_handle_t)); rc = HandleMap_GetFH(&map_hdl, &tmp_hdl); if(isFullDebug(COMPONENT_FSAL)) { if(rc == HANDLEMAP_STALE) LogFullDebug(COMPONENT_FSAL, "File id=%llu : HandleMap_GetFH returns HANDLEMAP_STALE\n", map_hdl.object_id); else if(rc == 0) LogFullDebug(COMPONENT_FSAL, "File id=%llu : HandleMap_GetFH returns HANDLEMAP_SUCCESS\n", map_hdl.object_id); else LogFullDebug(COMPONENT_FSAL, "File id=%llu : HandleMap_GetFH returns error %d\n", map_hdl.object_id, rc); } if(rc == HANDLEMAP_STALE) ReturnCode(ERR_FSAL_STALE, rc); else if(rc != 0) ReturnCode(ERR_FSAL_SERVERFAULT, rc); /* The fsal_handle we get may not be up-to-date * so we pass an extract of its content to fsal_internal_proxy_create_fh() */ fsal_internal_proxy_extract_fh(&nfs4fh, &tmp_hdl); if(fsal_internal_proxy_create_fh (&nfs4fh, tmp_hdl.data.object_type_reminder, tmp_hdl.data.fileid4, out_fsal_handle) != TRUE) ReturnCode(ERR_FSAL_FAULT, 0); #else /* Proxy works only on NFSv4 requests */ ReturnCode(ERR_FSAL_NOTSUPP, 0); #endif break; case FSAL_DIGEST_NFSV4: /* take the file id */ memcpy((char *)&fileid, in_buff, sizeof(fsal_u64_t)); /* Keep the type of then object at the beginning */ memcpy((char *)&nodetype, (char *)(in_buff + sizeof(fsal_u64_t)), sizeof(unsigned int)); /* Then the len of the file handle */ memcpy((char *)&(nfs4fh.nfs_fh4_len), (char *)(in_buff + sizeof(fsal_u64_t) + sizeof(unsigned int)), sizeof(unsigned int)); /* Then keep the value of the buff */ nfs4fh.nfs_fh4_val = (char *)(in_buff + sizeof(fsal_u64_t) + 2 * sizeof(unsigned int)); if(fsal_internal_proxy_create_fh(&nfs4fh, nodetype, fileid, out_fsal_handle) != TRUE) ReturnCode(ERR_FSAL_FAULT, 0); break; default: /* Invalid input digest type. */ ReturnCode(ERR_FSAL_INVAL, 0); } ReturnCode(ERR_FSAL_NO_ERROR, 0); }
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_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 */