int irodsRead( const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi ) { int descInx; int status; rodsLog( LOG_DEBUG, "irodsRead: %s", path ); descInx = fi->fh; if ( checkFuseDesc( descInx ) < 0 ) { return -EBADF; } status = _ifuseRead( &IFuseDesc[descInx], buf, size, offset ); return status; }
/************************************************************************** * private functions **************************************************************************/ static int _commitLocalBuffer(const char *iRODSPath, struct fuse_file_info *fi, lazyUploadFileInfo_t *lazyUploadFileInfo) { int status; int desc; char bufferPath[MAX_NAME_LEN]; int descInx; status = _getBufferPath(iRODSPath, bufferPath); if(status < 0) { rodsLog (LOG_DEBUG, "_upload: failed to get Buffered lazy upload file path - %s", iRODSPath); return status; } // close local buffer file handle if(lazyUploadFileInfo->localHandle < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: wrong file descriptor - %s, %d", iRODSPath, lazyUploadFileInfo->localHandle); return -EBADF; } // no write but requested flush if(lazyUploadFileInfo->curOffset == 0) { return 0; } fsync(lazyUploadFileInfo->localHandle); close(lazyUploadFileInfo->localHandle); lazyUploadFileInfo->localHandle = -1; rodsLog (LOG_DEBUG, "_commitLocalBuffer: upload - %s", iRODSPath); if(lazyUploadFileInfo->commitCount == 0) { // put and reopen iRODS file dataObjInp_t dataObjInp; int fd; pathCache_t *tmpPathCache = NULL; iFuseConn_t *iFuseConn = NULL; iFuseDesc_t *desc = NULL; struct stat stbuf; char objPath[MAX_NAME_LEN]; descInx = GET_IFUSE_DESC_INDEX(fi); rodsLog (LOG_DEBUG, "_commitLocalBuffer: closing existing iRODS file handle - %s - %d", iRODSPath, descInx); status = ifuseClose (&IFuseDesc[descInx]); if (status < 0) { int myError; if ((myError = getErrno (status)) > 0) { return (-myError); } else { return -ENOENT; } } // put rodsLog (LOG_DEBUG, "_commitLocalBuffer: uploading buffered file - %s", iRODSPath); status = _upload(iRODSPath); if(status != 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: upload error - %s, %d", iRODSPath, status); return status; } // reopen file rodsLog (LOG_DEBUG, "_commitLocalBuffer: reopening iRODS file handle - %s", iRODSPath); memset (&dataObjInp, 0, sizeof (dataObjInp)); //dataObjInp.openFlags = lazyUploadFileInfo->accmode; dataObjInp.openFlags = O_RDWR | O_APPEND; status = parseRodsPathStr ((char *) iRODSPath, LazyUploadRodsEnv, objPath); rstrcpy(dataObjInp.objPath, objPath, MAX_NAME_LEN); if (status < 0) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: parseRodsPathStr of %s error", iRODSPath); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath((char *) iRODSPath, &status); /* status = getAndUseIFuseConn(&iFuseConn); */ if(status < 0) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: cannot get connection for %s error", iRODSPath); /* use ENOTDIR for this type of error */ return -ENOTDIR; } status = _irodsGetattr (iFuseConn, iRODSPath, &stbuf); fd = rcDataObjOpen (iFuseConn->conn, &dataObjInp); unuseIFuseConn (iFuseConn); if (fd < 0) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: rcDataObjOpen of %s error, status = %d", iRODSPath, fd); return -ENOENT; } fileCache_t *fileCache = addFileCache(fd, objPath, (char *) iRODSPath, NULL, stbuf.st_mode, stbuf.st_size, NO_FILE_CACHE); matchAndLockPathCache(pctable, (char *) iRODSPath, &tmpPathCache); if(tmpPathCache == NULL) { pathExist(pctable, (char *) iRODSPath, fileCache, &stbuf, NULL); } else { _addFileCacheForPath(tmpPathCache, fileCache); UNLOCK_STRUCT(*tmpPathCache); } desc = newIFuseDesc (objPath, (char *) iRODSPath, fileCache, &status); if (desc == NULL) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: allocIFuseDesc of %s error", iRODSPath); return -ENOENT; } SET_IFUSE_DESC_INDEX(fi, desc->index); rodsLog (LOG_DEBUG, "_commitLocalBuffer: created new file handle - %s - %d", iRODSPath, desc->index); } else { // append int localDesc = open (bufferPath, O_RDONLY, 0755); char *buffer = (char*)malloc(FUSE_LAZY_UPLOAD_MEM_BUFFER_SIZE); int grandTotalReadLen = 0; if(localDesc < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: file descriptor error - %s, %d", iRODSPath, localDesc); return -ENOENT; } descInx = GET_IFUSE_DESC_INDEX(fi); if (checkFuseDesc (descInx) < 0) { return -EBADF; } status = 0; while(grandTotalReadLen < lazyUploadFileInfo->curOffset) { int totalReadLen = 0; int totalWriteLen = 0; while(totalReadLen < FUSE_LAZY_UPLOAD_MEM_BUFFER_SIZE) { int readLen = read(localDesc, buffer + totalReadLen, FUSE_LAZY_UPLOAD_MEM_BUFFER_SIZE - totalReadLen); if(readLen > 0) { totalReadLen += readLen; } else if(readLen == 0) { // EOF break; } else if(readLen < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: buffered file read error - %s, %d", iRODSPath, localDesc); status = getErrno (readLen); break; } } if(status >= 0) { while(totalWriteLen < totalReadLen) { int writeLen = _ifuseWrite (&IFuseDesc[descInx], buffer + totalWriteLen, totalReadLen - totalWriteLen, lazyUploadFileInfo->curLocalOffsetStart + totalWriteLen); if(writeLen > 0) { totalWriteLen += writeLen; } else if(writeLen == 0) { // EOF break; } else if(writeLen < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: iRODS file write error - %s", iRODSPath); status = getErrno (writeLen); break; } } } grandTotalReadLen += totalReadLen; } unlockDesc (descInx); free(buffer); close(localDesc); } rodsLog (LOG_DEBUG, "_commitLocalBuffer: reset local buffered file - %s", iRODSPath); // reset local buffer file desc = open (bufferPath, O_RDWR|O_CREAT|O_TRUNC, 0755); lazyUploadFileInfo->localHandle = desc; lazyUploadFileInfo->commitCount++; lazyUploadFileInfo->curLocalOffsetStart += lazyUploadFileInfo->curOffset; lazyUploadFileInfo->curOffset = 0; return (0); }
int writeLazyUploadBufferedFile (const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int status; lazyUploadFileInfo_t *lazyUploadFileInfo = NULL; char iRODSPath[MAX_NAME_LEN]; char bufferPath[MAX_NAME_LEN]; off_t seek_status; int descInx; // convert input path to iRODSPath status = _getiRODSPath(path, iRODSPath); if(status < 0) { rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: failed to get iRODS path - %s", path); return status; } status = _getBufferPath(iRODSPath, bufferPath); if(status < 0) { rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: failed to get buffer path - %s", iRODSPath); return status; } LOCK(LazyUploadLock); // check the given file is Buffered lazyUploadFileInfo = (lazyUploadFileInfo_t *)lookupFromHashTable(LazyUploadBufferedFileTable_Opened, iRODSPath); if(lazyUploadFileInfo != NULL) { // has lazy upload file handle opened if(lazyUploadFileInfo->localHandle < 0) { rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: wrong file descriptor - %s, %d", iRODSPath, lazyUploadFileInfo->localHandle); UNLOCK(LazyUploadLock); return -EBADF; } } else { rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: file is not opened - %s", iRODSPath); UNLOCK(LazyUploadLock); return -EBADF; } if(offset - lazyUploadFileInfo->curLocalOffsetStart < 0) { // backward? // commit local buffered data status = _commitLocalBuffer(iRODSPath, fi, lazyUploadFileInfo); if(status < 0) { rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: failed to commit local buffered data - %s", iRODSPath); UNLOCK(LazyUploadLock); return status; } // rewrite directly to iRODS descInx = GET_IFUSE_DESC_INDEX(fi); if (checkFuseDesc (descInx) < 0) { UNLOCK(LazyUploadLock); return -EBADF; } status = _ifuseWrite (&IFuseDesc[descInx], (char *)buf, size, offset); unlockDesc (descInx); UNLOCK(LazyUploadLock); return status; } // try to write to local buffer seek_status = lseek (lazyUploadFileInfo->localHandle, offset - lazyUploadFileInfo->curLocalOffsetStart, SEEK_SET); if (seek_status != (offset - lazyUploadFileInfo->curLocalOffsetStart)) { status = (int)seek_status; rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: failed to seek file desc - %d, %ld -> %ld", lazyUploadFileInfo->localHandle, offset - lazyUploadFileInfo->curLocalOffsetStart, seek_status); UNLOCK(LazyUploadLock); return status; } // TEST //if (lazyUploadFileInfo->curOffset > 10*1024*1024) { // status = -1; // errno = ENOSPC; //} else { // status = write (lazyUploadFileInfo->localHandle, buf, size); //} // TEST END status = write (lazyUploadFileInfo->localHandle, buf, size); rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: write to opened lazy-upload Buffered file - %d", lazyUploadFileInfo->localHandle); if (status < 0) { // no space? if (errno == ENOSPC) { // handle no space // mode switch status = _commitLocalBuffer(iRODSPath, fi, lazyUploadFileInfo); if(status < 0) { rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: failed to change to appending mode - %s", iRODSPath); UNLOCK(LazyUploadLock); return status; } // write to local buffer again seek_status = lseek (lazyUploadFileInfo->localHandle, offset - lazyUploadFileInfo->curLocalOffsetStart, SEEK_SET); if (seek_status != (offset - lazyUploadFileInfo->curLocalOffsetStart)) { status = (int)seek_status; rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: failed to seek file desc - %d, %ld -> %ld", lazyUploadFileInfo->localHandle, offset - lazyUploadFileInfo->curLocalOffsetStart, seek_status); UNLOCK(LazyUploadLock); return status; } status = write (lazyUploadFileInfo->localHandle, buf, size); rodsLog (LOG_DEBUG, "writeLazyUploadBufferedFile: write to opened lazy-upload Buffered file - %d", lazyUploadFileInfo->localHandle); if(status >= 0) { lazyUploadFileInfo->curOffset += status; } } } else { lazyUploadFileInfo->curOffset += status; } UNLOCK(LazyUploadLock); return status; }