fsal_status_t MFSL_open_by_fileid(mfsl_object_t * filehandle, /* IN */ fsal_u64_t fileid, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_openflags_t openflags, /* IN */ fsal_file_t * file_descriptor, /* OUT */ fsal_attrib_list_t * file_attributes /* [ IN/OUT ] */ ) { return FSAL_open_by_fileid(&filehandle->handle, fileid, p_context, openflags, file_descriptor, file_attributes); } /* MFSL_open_by_fileid */
fsal_status_t MFSL_open_by_fileid(mfsl_object_t * filehandle, /* IN */ fsal_u64_t fileid, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_openflags_t openflags, /* IN */ mfsl_file_t * file_descriptor, /* OUT */ fsal_attrib_list_t * file_attributes, /* [ IN/OUT ] */ void * pextra ) { struct timeval start, stop, delta ; fsal_status_t fsal_status = { ERR_FSAL_NO_ERROR, 0 } ; gettimeofday( &start, 0 ) ; fsal_status = FSAL_open_by_fileid(&filehandle->handle, fileid, p_context, openflags, &file_descriptor->fsal_file, file_attributes); gettimeofday( &stop, 0 ) ; delta = mfsl_timer_diff( &stop, &start ) ; LogFullDebug( COMPONENT_MFSL, "%s: duration=%ld.%06ld", __FUNCTION__, delta.tv_sec, delta.tv_usec ) ; return fsal_status ; } /* MFSL_open_by_fileid */
fsal_status_t PROXYFSAL_truncate(proxyfsal_handle_t * filehandle, /* IN */ proxyfsal_op_context_t * p_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]; #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 = { 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); } if(file_descriptor == NULL) { /* Use the stateless version */ fsal_status = FSAL_proxy_truncate_stateless(filehandle, p_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(p_context->export_context, FSAL_DIGEST_FILEID4, filehandle, (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(filehandle, fileid, p_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, 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_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 = file_descriptor->stateid.seqid; memcpy(argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u. opsetattr.stateid.other, 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) != 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); } } /* 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); }
fsal_status_t PROXYFSAL_rcp_by_fileid(proxyfsal_handle_t * filehandle, /* IN */ fsal_u64_t fileid, /* IN */ proxyfsal_op_context_t * p_context, /* IN */ fsal_path_t * p_local_path, /* IN */ fsal_rcpflag_t transfer_opt /* IN */ ) { int local_fd; int local_flags; proxyfsal_file_t fs_fd; fsal_openflags_t fs_flags; fsal_status_t st = FSAL_STATUS_NO_ERROR; /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> * This is a template implementation of rcp based on FSAL_read and FSAL_write * function. You may chose keeping it or doing your own implementation * that is optimal for your filesystems. * <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */ caddr_t IObuffer; int to_local = FALSE; int to_fs = FALSE; int eof = FALSE; ssize_t local_size; fsal_size_t fs_size; /* sanity checks. */ if(!filehandle || !p_context || !p_local_path) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rcp); to_local = ((transfer_opt & FSAL_RCP_FS_TO_LOCAL) == FSAL_RCP_FS_TO_LOCAL); to_fs = ((transfer_opt & FSAL_RCP_LOCAL_TO_FS) == FSAL_RCP_LOCAL_TO_FS); if(to_local) LogFullDebug(COMPONENT_FSAL, "FSAL_rcp: FSAL -> local file (%s)", p_local_path->path); if(to_fs) LogFullDebug(COMPONENT_FSAL, "FSAL_rcp: local file -> FSAL (%s)", p_local_path->path); /* must give the sens of transfert (exactly one) */ if((!to_local && !to_fs) || (to_local && to_fs)) Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rcp); /* first, open local file with the correct flags */ if(to_fs) { local_flags = O_RDONLY; } else { local_flags = O_WRONLY | O_TRUNC; if((transfer_opt & FSAL_RCP_LOCAL_CREAT) == FSAL_RCP_LOCAL_CREAT) local_flags |= O_CREAT; if((transfer_opt & FSAL_RCP_LOCAL_EXCL) == FSAL_RCP_LOCAL_EXCL) local_flags |= O_EXCL; } if(isFullDebug(COMPONENT_FSAL)) { char msg[1024]; msg[0] = '\0'; if((local_flags & O_RDONLY) == O_RDONLY) strcat(msg, "O_RDONLY "); if((local_flags & O_WRONLY) == O_WRONLY) strcat(msg, "O_WRONLY "); if((local_flags & O_TRUNC) == O_TRUNC) strcat(msg, "O_TRUNC "); if((local_flags & O_CREAT) == O_CREAT) strcat(msg, "O_CREAT "); if((local_flags & O_EXCL) == O_EXCL) strcat(msg, "O_EXCL "); LogFullDebug(COMPONENT_FSAL, "Openning local file %s with flags: %s", p_local_path->path, msg); } local_fd = open(p_local_path->path, local_flags, 0644); if(local_fd == -1) { /** @todo : put a function in fsal_convert.c that convert your local * filesystem errors to an FSAL error code. * So you will have a call like : * Return( unix2fsal_error(errno) , errno , INDEX_FSAL_rcp ); */ Return(ERR_FSAL_SERVERFAULT, errno, INDEX_FSAL_rcp); } /* call FSAL_open with the correct flags */ if(to_fs) { fs_flags = FSAL_O_WRONLY | FSAL_O_TRUNC; /* invalid flags for local to filesystem */ if(((transfer_opt & FSAL_RCP_LOCAL_CREAT) == FSAL_RCP_LOCAL_CREAT) || ((transfer_opt & FSAL_RCP_LOCAL_EXCL) == FSAL_RCP_LOCAL_EXCL)) { /* clean & return */ close(local_fd); Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rcp); } } else { fs_flags = FSAL_O_RDONLY; } if(isFullDebug(COMPONENT_FSAL)) { char msg[1024]; msg[0] = '\0'; if((fs_flags & FSAL_O_RDONLY) == FSAL_O_RDONLY) strcat(msg, "FSAL_O_RDONLY "); if((fs_flags & FSAL_O_WRONLY) == FSAL_O_WRONLY) strcat(msg, "FSAL_O_WRONLY "); if((fs_flags & FSAL_O_TRUNC) == FSAL_O_TRUNC) strcat(msg, "FSAL_O_TRUNC "); LogFullDebug(COMPONENT_FSAL, "Openning FSAL file with flags: %s", msg); } st = FSAL_open_by_fileid(filehandle, fileid, p_context, fs_flags, &fs_fd, NULL); if(FSAL_IS_ERROR(st)) { /* clean & return */ close(local_fd); Return(st.major, st.minor, INDEX_FSAL_rcp); } LogFullDebug(COMPONENT_FSAL, "Allocating IO buffer of size %llu", (unsigned long long)RCP_BUFFER_SIZE); /* Allocates buffer */ IObuffer = (caddr_t) Mem_Alloc(RCP_BUFFER_SIZE); if(IObuffer == NULL) { /* clean & return */ close(local_fd); FSAL_close(&fs_fd); Return(ERR_FSAL_NOMEM, Mem_Errno, INDEX_FSAL_rcp); } /* read/write loop */ while(!eof) { /* initialize error code */ st = FSAL_STATUS_NO_ERROR; LogFullDebug(COMPONENT_FSAL, "Read a block from source"); /* read */ if(to_fs) /* from local filesystem */ { local_size = read(local_fd, IObuffer, RCP_BUFFER_SIZE); if(local_size == -1) { st.major = ERR_FSAL_IO; st.minor = errno; break; /* exit loop */ } eof = (local_size == 0); } else /* from FSAL filesystem */ { fs_size = 0; st = FSAL_read(&fs_fd, NULL, RCP_BUFFER_SIZE, IObuffer, &fs_size, &eof); if(FSAL_IS_ERROR(st)) break; /* exit loop */ } /* write (if not eof) */ if(!eof || ((!to_fs) && (fs_size > 0))) { LogFullDebug(COMPONENT_FSAL, "Write a block to destination"); if(to_fs) /* to FSAL filesystem */ { st = FSAL_write(&fs_fd, NULL, local_size, IObuffer, &fs_size); if(FSAL_IS_ERROR(st)) break; /* exit loop */ } else /* to local filesystem */ { local_size = write(local_fd, IObuffer, fs_size); if(local_size == -1) { st.major = ERR_FSAL_IO; st.minor = errno; break; /* exit loop */ } } /* if to_fs */ } /* if eof */ else LogFullDebug(COMPONENT_FSAL, "End of source file reached"); } /* while !eof */ /* Clean */ Mem_Free(IObuffer); close(local_fd); FSAL_close_by_fileid(&fs_fd, fileid); /* return status. */ Return(st.major, st.minor, INDEX_FSAL_rcp); } /* FSAL_rcp_by_name */