fsal_status_t MFSL_open_by_name(mfsl_object_t * dirhandle, /* IN */ fsal_name_t * filename, /* 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_name(&dirhandle->handle, filename, p_context, openflags, file_descriptor, file_attributes); } /* MFSL_open_by_name */
fsal_status_t MFSL_open_by_name(mfsl_object_t * dirhandle, /* IN */ fsal_name_t * filename, /* 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_name(&dirhandle->handle, filename, 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_name */
cache_inode_status_t cache_inode_open_by_name(cache_entry_t * pentry_dir, fsal_name_t * pname, cache_entry_t * pentry_file, cache_inode_client_t * pclient, fsal_openflags_t openflags, fsal_op_context_t * pcontext, cache_inode_status_t * pstatus) { fsal_status_t fsal_status; fsal_size_t save_filesize = 0; fsal_size_t save_spaceused = 0; fsal_time_t save_mtime = { .seconds = 0, .nseconds = 0 }; if((pentry_dir == NULL) || (pname == NULL) || (pentry_file == NULL) || (pclient == NULL) || (pcontext == NULL) || (pstatus == NULL)) return CACHE_INODE_INVALID_ARGUMENT; if((pentry_dir->internal_md.type != DIRECTORY)) { *pstatus = CACHE_INODE_BAD_TYPE; return *pstatus; } if(pentry_file->internal_md.type != REGULAR_FILE) { *pstatus = CACHE_INODE_BAD_TYPE; return *pstatus; } /* Open file need to be closed, unless it is already open as read/write */ if((pentry_file->object.file.open_fd.openflags != FSAL_O_RDWR) && (pentry_file->object.file.open_fd.openflags != 0) && (pentry_file->object.file.open_fd.fileno >= 0) && (pentry_file->object.file.open_fd.openflags != openflags)) { #ifdef _USE_MFSL fsal_status = MFSL_close(&(pentry_file->object.file.open_fd.mfsl_fd), &pclient->mfsl_context, NULL); #else fsal_status = FSAL_close(&(pentry_file->object.file.open_fd.fd)); #endif if(FSAL_IS_ERROR(fsal_status) && (fsal_status.major != ERR_FSAL_NOT_OPENED)) { *pstatus = cache_inode_error_convert(fsal_status); LogDebug(COMPONENT_CACHE_INODE, "cache_inode_open_by_name: returning %d(%s) from FSAL_close", *pstatus, cache_inode_err_str(*pstatus)); return *pstatus; } pentry_file->object.file.open_fd.last_op = 0; pentry_file->object.file.open_fd.fileno = 0; } if(pentry_file->object.file.open_fd.last_op == 0 || pentry_file->object.file.open_fd.fileno == 0) { LogDebug(COMPONENT_FSAL, "cache_inode_open_by_name: pentry %p: lastop=0", pentry_file); /* Keep coherency with the cache_content */ if(pentry_file->object.file.pentry_content != NULL) { save_filesize = pentry_file->object.file.attributes.filesize; save_spaceused = pentry_file->object.file.attributes.spaceused; save_mtime = pentry_file->object.file.attributes.mtime; } /* opened file is not preserved yet */ #ifdef _USE_MFSL fsal_status = MFSL_open_by_name(&(pentry_dir->mobject), pname, pcontext, &pclient->mfsl_context, openflags, &pentry_file->object.file.open_fd.mfsl_fd, &(pentry_file->object.file.attributes), #ifdef _USE_PNFS &pentry_file->object.file.pnfs_file ) ; #else NULL ); #endif /* _USE_PNFS */ #else fsal_status = FSAL_open_by_name(&(pentry_dir->object.file.handle), pname, pcontext, openflags, &pentry_file->object.file.open_fd.fd, &(pentry_file->object.file.attributes)); #endif if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); LogDebug(COMPONENT_CACHE_INODE, "cache_inode_open_by_name: returning %d(%s) from FSAL_open_by_name", *pstatus, cache_inode_err_str(*pstatus)); return *pstatus; } #ifdef _USE_PROXY /* If proxy if used, we should keep the name of the file to do FSAL_rcp if needed */ if((pentry_file->object.file.pname = (fsal_name_t *) Mem_Alloc_Label(sizeof(fsal_name_t), "fsal_name_t")) == NULL) { *pstatus = CACHE_INODE_MALLOC_ERROR; return *pstatus; } pentry_file->object.file.pentry_parent_open = pentry_dir; pentry_file->object.file.pname->len = pname->len; memcpy((char *)(pentry_file->object.file.pname->name), (char *)(pname->name), FSAL_MAX_NAME_LEN); #endif /* Keep coherency with the cache_content */ if(pentry_file->object.file.pentry_content != NULL) { pentry_file->object.file.attributes.filesize = save_filesize; pentry_file->object.file.attributes.spaceused = save_spaceused; pentry_file->object.file.attributes.mtime = save_mtime; } #ifdef _USE_MFSL pentry_file->object.file.open_fd.fileno = (int)FSAL_FILENO(&(pentry_file->object.file.open_fd.mfsl_fd.fsal_file)); #else pentry_file->object.file.open_fd.fileno = (int)FSAL_FILENO(&(pentry_file->object.file.open_fd.fd)); #endif pentry_file->object.file.open_fd.last_op = time(NULL); pentry_file->object.file.open_fd.openflags = openflags; LogDebug(COMPONENT_FSAL, "cache_inode_open_by_name: pentry %p: fd=%u", pentry_file, pentry_file->object.file.open_fd.fileno); } /* regular exit */ pentry_file->object.file.open_fd.last_op = time(NULL); /* if file descriptor is too high, garbage collect FDs */ if(pclient->use_fd_cache && (pentry_file->object.file.open_fd.fileno > pclient->max_fd)) { if(cache_inode_gc_fd(pclient, pstatus) != CACHE_INODE_SUCCESS) { LogCrit(COMPONENT_CACHE_INODE_GC, "FAILURE performing FD garbage collection"); return *pstatus; } } *pstatus = CACHE_INODE_SUCCESS; return *pstatus; } /* cache_inode_open_by_name */
fsal_status_t PROXYFSAL_rcp_by_name(proxyfsal_handle_t * filehandle, /* IN */ fsal_name_t * pfilename, /* 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_name(filehandle, pfilename, 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(&fs_fd); /* return status. */ Return(st.major, st.minor, INDEX_FSAL_rcp); } /* FSAL_rcp_by_name */
fsal_status_t MFSL_open_by_name(mfsl_object_t * dirhandle, /* IN */ fsal_name_t * filename, /* 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 ) { fsal_status_t fsal_status ; int pnfs_status; pnfs_fileloc_t pnfs_location ; fsal_status = FSAL_open_by_name(&dirhandle->handle, filename, p_context, openflags, &file_descriptor->fsal_file, file_attributes); if( FSAL_IS_ERROR( fsal_status ) ) return fsal_status ; if(! pnfs_get_location( &p_mfsl_context->pnfsclient, &file_descriptor->fsal_file.handle, NULL, &pnfs_location ) ) { LogDebug(COMPONENT_MFSL, "LOOKUP PNFS support : can't build pnfs_location" ) ; fsal_status.major = ERR_FSAL_IO ; fsal_status.minor = 0 ; return fsal_status ; } if((pnfs_status = pnfs_lookup_file( &p_mfsl_context->pnfsclient, &pnfs_location, &file_descriptor->pnfs_file ) ) != NFS4_OK ) { LogDebug(COMPONENT_CACHE_INODE, "OPEN PNFS LOOKUP DS FILE : Error %u", pnfs_status); if(pnfs_status == NFS4ERR_NOENT) { if((pnfs_status = pnfs_create_file(&p_mfsl_context->pnfsclient, &pnfs_location, &file_descriptor->pnfs_file ) ) != NFS4_OK ) { LogDebug(COMPONENT_CACHE_INODE, "OPEN PNFS CREATE DS FILE : Error %u", pnfs_status ) ; fsal_status.major = ERR_FSAL_IO ; fsal_status.minor = 0 ; return fsal_status ; } } else { fsal_status.major = ERR_FSAL_IO ; fsal_status.minor = 0 ; return fsal_status ; } } if( pextra != NULL ) memcpy( (char *)pextra, (char *)&file_descriptor->pnfs_file, sizeof( pnfs_file_t ) ) ; /* SUCCES */ fsal_status.major = ERR_FSAL_NO_ERROR ; fsal_status.minor = 0 ; return fsal_status ; } /* MFSL_open_by_name */
cache_inode_status_t cache_inode_open_by_name(cache_entry_t * pentry_dir, fsal_name_t * pname, cache_entry_t * pentry_file, cache_inode_client_t * pclient, fsal_openflags_t openflags, fsal_op_context_t * pcontext, cache_inode_status_t * pstatus) { fsal_status_t fsal_status; fsal_size_t save_filesize = 0; fsal_size_t save_spaceused = 0; fsal_time_t save_mtime = { .seconds = 0, .nseconds = 0 }; if((pentry_dir == NULL) || (pname == NULL) || (pentry_file == NULL) || (pclient == NULL) || (pcontext == NULL) || (pstatus == NULL)) return CACHE_INODE_INVALID_ARGUMENT; if((pentry_dir->internal_md.type != DIRECTORY)) { *pstatus = CACHE_INODE_BAD_TYPE; return *pstatus; } if(pentry_file->internal_md.type != REGULAR_FILE) { *pstatus = CACHE_INODE_BAD_TYPE; return *pstatus; } /* Open file need to be closed, unless it is already open as read/write */ if((pentry_file->object.file.open_fd.openflags != FSAL_O_RDWR) && (pentry_file->object.file.open_fd.openflags != 0) && (pentry_file->object.file.open_fd.fileno != 0) && (pentry_file->object.file.open_fd.openflags != openflags)) { #ifdef _USE_MFSL fsal_status = MFSL_close(&(pentry_file->object.file.open_fd.mfsl_fd), &pclient->mfsl_context, NULL); #else fsal_status = FSAL_close(&(pentry_file->object.file.open_fd.fd)); #endif if(FSAL_IS_ERROR(fsal_status) && (fsal_status.major != ERR_FSAL_NOT_OPENED)) { *pstatus = cache_inode_error_convert(fsal_status); LogDebug(COMPONENT_CACHE_INODE, "cache_inode_open_by_name: returning %d(%s) from FSAL_close", *pstatus, cache_inode_err_str(*pstatus)); return *pstatus; } pentry_file->object.file.open_fd.last_op = 0; pentry_file->object.file.open_fd.fileno = 0; } if(pentry_file->object.file.open_fd.last_op == 0 || pentry_file->object.file.open_fd.fileno == 0) { LogFullDebug(COMPONENT_FSAL, "cache_inode_open_by_name: pentry %p: lastop=0", pentry_file); /* Keep coherency with the cache_content */ if(pentry_file->object.file.pentry_content != NULL) { save_filesize = pentry_file->attributes.filesize; save_spaceused = pentry_file->attributes.spaceused; save_mtime = pentry_file->attributes.mtime; } /* opened file is not preserved yet */ #ifdef _USE_MFSL fsal_status = MFSL_open_by_name(&(pentry_dir->mobject), pname, pcontext, &pclient->mfsl_context, openflags, &pentry_file->object.file.open_fd.mfsl_fd, &(pentry_file->attributes), NULL ); #else fsal_status = FSAL_open_by_name(&(pentry_dir->handle), pname, pcontext, openflags, &pentry_file->object.file.open_fd.fd, &(pentry_file->attributes)); #endif if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); LogDebug(COMPONENT_CACHE_INODE, "cache_inode_open_by_name: returning %d(%s) from FSAL_open_by_name", *pstatus, cache_inode_err_str(*pstatus)); return *pstatus; } #ifdef _USE_PROXY /* If proxy if used, we should keep the name of the file to do FSAL_rcp if needed */ if((pentry_file->object.file.pname = (fsal_name_t *) Mem_Alloc_Label(sizeof(fsal_name_t), "fsal_name_t")) == NULL) { *pstatus = CACHE_INODE_MALLOC_ERROR; return *pstatus; } pentry_file->object.file.pentry_parent_open = pentry_dir; pentry_file->object.file.pname->len = pname->len; memcpy((char *)(pentry_file->object.file.pname->name), (char *)(pname->name), FSAL_MAX_NAME_LEN); #endif /* Keep coherency with the cache_content */ if(pentry_file->object.file.pentry_content != NULL) { pentry_file->attributes.filesize = save_filesize; pentry_file->attributes.spaceused = save_spaceused; pentry_file->attributes.mtime = save_mtime; } #ifdef _USE_MFSL pentry_file->object.file.open_fd.fileno = (int)FSAL_FILENO(&(pentry_file->object.file.open_fd.mfsl_fd.fsal_file)); #else pentry_file->object.file.open_fd.fileno = (int)FSAL_FILENO(&(pentry_file->object.file.open_fd.fd)); #endif pentry_file->object.file.open_fd.last_op = time(NULL); pentry_file->object.file.open_fd.openflags = openflags; LogFullDebug(COMPONENT_FSAL, "cache_inode_open_by_name: pentry %p: fd=%u", pentry_file, pentry_file->object.file.open_fd.fileno); } /* regular exit */ pentry_file->object.file.open_fd.last_op = time(NULL); /* if file descriptor is too high, garbage collect FDs */ if(pclient->use_fd_cache && (pentry_file->object.file.open_fd.fileno > pclient->max_fd)) { if(cache_inode_gc_fd(pclient, pstatus) != CACHE_INODE_SUCCESS) { LogCrit(COMPONENT_CACHE_INODE_GC, "FAILURE performing FD garbage collection"); return *pstatus; } } *pstatus = CACHE_INODE_SUCCESS; return *pstatus; } /* cache_inode_open_by_name */ /** * * cache_inode_close: closes the local fd in the FSAL. * * Closes the local fd in the FSAL. * * No lock management is done in this layer: the related pentry in the cache inode layer is * locked and will prevent from concurent accesses. * * @param pentry [IN] entry in file content layer whose content is to be accessed. * @param pclient [IN] ressource allocated by the client for the nfs management. * @pstatus [OUT] returned status. * * @return CACHE_CONTENT_SUCCESS is successful . * */ cache_inode_status_t cache_inode_close(cache_entry_t * pentry, cache_inode_client_t * pclient, cache_inode_status_t * pstatus) { fsal_status_t fsal_status; if((pentry == NULL) || (pclient == NULL) || (pstatus == NULL)) return CACHE_CONTENT_INVALID_ARGUMENT; if(pentry->internal_md.type != REGULAR_FILE) { *pstatus = CACHE_INODE_BAD_TYPE; return *pstatus; } /* if nothing is opened, do nothing */ if(pentry->object.file.open_fd.fileno < 0) { *pstatus = CACHE_INODE_SUCCESS; return *pstatus; } /* if locks are held in the file, do not close */ if( cache_inode_file_holds_state( pentry ) ) { *pstatus = CACHE_INODE_SUCCESS; /** @todo : PhD : May be CACHE_INODE_STATE_CONFLICTS would be better ? */ return *pstatus; } if((pclient->use_fd_cache == 0) || (time(NULL) - pentry->object.file.open_fd.last_op > pclient->retention) || (pentry->object.file.open_fd.fileno > (int)(pclient->max_fd))) { LogFullDebug(COMPONENT_CACHE_INODE, "cache_inode_close: pentry %p, fileno = %d, lastop=%d ago", pentry, pentry->object.file.open_fd.fileno, (int)(time(NULL) - pentry->object.file.open_fd.last_op)); #ifdef _USE_MFSL fsal_status = MFSL_close(&(pentry->object.file.open_fd.mfsl_fd), &pclient->mfsl_context, NULL); #else fsal_status = FSAL_close(&(pentry->object.file.open_fd.fd)); #endif pentry->object.file.open_fd.fileno = 0; pentry->object.file.open_fd.last_op = 0; if(FSAL_IS_ERROR(fsal_status) && (fsal_status.major != ERR_FSAL_NOT_OPENED)) { *pstatus = cache_inode_error_convert(fsal_status); LogDebug(COMPONENT_CACHE_INODE, "cache_inode_close: returning %d(%s) from FSAL_close", *pstatus, cache_inode_err_str(*pstatus)); return *pstatus; } } #ifdef _USE_PROXY /* If proxy if used, free the name if needed */ if(pentry->object.file.pname != NULL) { Mem_Free((char *)(pentry->object.file.pname)); pentry->object.file.pname = NULL; } pentry->object.file.pentry_parent_open = NULL; #endif *pstatus = CACHE_CONTENT_SUCCESS; return *pstatus; } /* cache_content_close */