int irodsMkdir (const char *path, mode_t mode) { collInp_t collCreateInp; int status; iFuseConn_t *iFuseConn = NULL; rodsLog (LOG_DEBUG, "irodsMkdir: %s", path); memset (&collCreateInp, 0, sizeof (collCreateInp)); status = parseRodsPathStr ((char *) (path + 1) , &MyRodsEnv, collCreateInp.collName); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsMkdir: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } getAndUseIFuseConn (&iFuseConn, &MyRodsEnv); status = rcCollCreate (iFuseConn->conn, &collCreateInp); if (status < 0) { if (isReadMsgError (status)) { ifuseReconnect (iFuseConn); status = rcCollCreate (iFuseConn->conn, &collCreateInp); } unuseIFuseConn (iFuseConn); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsMkdir: rcCollCreate of %s error", path); return -ENOENT; } #ifdef CACHE_FUSE_PATH } else { struct stat stbuf; uint mytime = time (0); bzero (&stbuf, sizeof (struct stat)); fillDirStat (&stbuf, mytime, mytime, mytime); pathExist ((char *) path, NULL, &stbuf, NULL); #endif unuseIFuseConn (iFuseConn); } return (0); }
int irodsTruncate (const char *path, off_t size) { dataObjInp_t dataObjInp; int status; pathCache_t *tmpPathCache; iFuseConn_t *iFuseConn = NULL; rodsLog (LOG_DEBUG, "irodsTruncate: %s", path); if (matchAndLockPathCache ((char *) path, &tmpPathCache) == 1) { if(tmpPathCache->fileCache != NULL) { LOCK_STRUCT(*tmpPathCache->fileCache); if(tmpPathCache->fileCache->state == HAVE_NEWLY_CREATED_CACHE) { status = truncate (tmpPathCache->fileCache->fileCachePath, size); if (status >= 0) { updatePathCacheStatFromFileCache (tmpPathCache); UNLOCK_STRUCT(*(tmpPathCache->fileCache)); UNLOCK_STRUCT(*tmpPathCache); return (0); } } UNLOCK_STRUCT(*(tmpPathCache->fileCache)); } } UNLOCK_STRUCT(*tmpPathCache); memset (&dataObjInp, 0, sizeof (dataObjInp)); status = parseRodsPathStr ((char *) (path + 1) , &MyRodsEnv, dataObjInp.objPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsTruncate: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } dataObjInp.dataSize = size; getAndUseIFuseConn (&iFuseConn, &MyRodsEnv); RECONNECT_IF_NECESSARY(status, iFuseConn, rcDataObjTruncate (iFuseConn->conn, &dataObjInp)); if (status >= 0) { pathCache_t *tmpPathCache; if (matchAndLockPathCache ((char *) path, &tmpPathCache) == 1) { tmpPathCache->stbuf.st_size = size; } UNLOCK_STRUCT(*tmpPathCache); status = 0; } else { rodsLogError (LOG_ERROR, status, "irodsTruncate: rcDataObjTruncate of %s error", path); status = -ENOENT; } unuseIFuseConn (iFuseConn); return (status); }
int irodsGetattr( const char *path, struct stat *stbuf ) { int status; iFuseConn_t *iFuseConn = NULL; iFuseConn = getAndUseConnByPath( ( char * ) path, &MyRodsEnv, &status ); status = _irodsGetattr( iFuseConn, path, stbuf ); unuseIFuseConn( iFuseConn ); return ( status ); }
int _ifuseFileCacheRead( fileCache_t *fileCache, char *buf, size_t size, off_t offset ) { int status, myError; status = _iFuseFileCacheLseek( fileCache, offset ); if ( status < 0 ) { if ( ( myError = getErrno( status ) ) > 0 ) { return -myError; } else { return -ENOENT; } } if ( fileCache->state == NO_FILE_CACHE ) { iFuseConn_t *conn; openedDataObjInp_t dataObjReadInp; bytesBuf_t dataObjReadOutBBuf; int myError; bzero( &dataObjReadInp, sizeof( dataObjReadInp ) ); dataObjReadOutBBuf.buf = buf; dataObjReadOutBBuf.len = size; dataObjReadInp.l1descInx = fileCache->iFd; dataObjReadInp.len = size; //UNLOCK_STRUCT(*fileCache); conn = getAndUseConnByPath( fileCache->localPath, &status ); //LOCK_STRUCT(*fileCache); status = rcDataObjRead( conn->conn, &dataObjReadInp, &dataObjReadOutBBuf ); unuseIFuseConn( conn ); if ( status < 0 ) { if ( ( myError = getErrno( status ) ) > 0 ) { return -myError; } else { return -ENOENT; } } } else { status = read( fileCache->iFd, buf, size ); if ( status < 0 ) { return errno ? ( -1 * errno ) : -1; } } fileCache->offset += status; return status; }
int irodsUnlink (const char *path) { dataObjInp_t dataObjInp; int status; iFuseConn_t *iFuseConn = NULL; rodsLog (LOG_DEBUG, "irodsUnlink: %s", path); memset (&dataObjInp, 0, sizeof (dataObjInp)); status = parseRodsPathStr ((char *) (path + 1) , &MyRodsEnv, dataObjInp.objPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsUnlink: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } addKeyVal (&dataObjInp.condInput, FORCE_FLAG_KW, ""); getAndUseIFuseConn (&iFuseConn, &MyRodsEnv); status = rcDataObjUnlink (iFuseConn->conn, &dataObjInp); if (status >= 0) { #ifdef CACHE_FUSE_PATH pathNotExist ((char *) path); #endif status = 0; } else { if (isReadMsgError (status)) { ifuseReconnect (iFuseConn); status = rcDataObjUnlink (iFuseConn->conn, &dataObjInp); } if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsUnlink: rcDataObjUnlink of %s error", path); status = -ENOENT; } } unuseIFuseConn (iFuseConn); clearKeyVal (&dataObjInp.condInput); return (status); }
int irodsRmdir (const char *path) { collInp_t collInp; int status; iFuseConn_t *iFuseConn = NULL; rodsLog (LOG_DEBUG, "irodsRmdir: %s", path); memset (&collInp, 0, sizeof (collInp)); status = parseRodsPathStr ((char *) (path + 1) , &MyRodsEnv, collInp.collName); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsRmdir: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } addKeyVal (&collInp.condInput, FORCE_FLAG_KW, ""); getAndUseIFuseConn (&iFuseConn, &MyRodsEnv); RECONNECT_IF_NECESSARY(status, iFuseConn, rcRmColl (iFuseConn->conn, &collInp, 0)); if (status >= 0) { #ifdef CACHE_FUSE_PATH pathNotExist ((char *) path); #endif status = 0; } else { rodsLogError (LOG_ERROR, status, "irodsRmdir: rcRmColl of %s error", path); status = -ENOENT; } unuseIFuseConn (iFuseConn); clearKeyVal (&collInp.condInput); return (status); }
/* close any open files inside the file cache */ int ifuseFileCacheClose( fileCache_t *fileCache ) { int status = 0; LOCK_STRUCT( *fileCache ); if ( fileCache->state == NO_FILE_CACHE ) { /* close remote file */ //UNLOCK_STRUCT( *fileCache ); iFuseConn_t *conn = getAndUseConnByPath( fileCache->localPath, &status ); //LOCK_STRUCT( *fileCache ); status = closeIrodsFd( conn->conn, fileCache->iFd ); unuseIFuseConn( conn ); fileCache->offset = 0; } else { /* close local file */ status = close( fileCache->iFd ); fileCache->iFd = 0; fileCache->offset = 0; } UNLOCK_STRUCT( *fileCache ); return status; }
int _iFuseFileCacheLseek( fileCache_t *fileCache, off_t offset ) { int status; if ( offset == fileCache->offset ) { return 0; } if ( fileCache->state == NO_FILE_CACHE ) { iFuseConn_t *conn = getAndUseConnByPath( fileCache->localPath, &status ); openedDataObjInp_t dataObjLseekInp; fileLseekOut_t *dataObjLseekOut = NULL; bzero( &dataObjLseekInp, sizeof( dataObjLseekInp ) ); dataObjLseekInp.l1descInx = fileCache->iFd; dataObjLseekInp.offset = offset; dataObjLseekInp.whence = SEEK_SET; status = rcDataObjLseek( conn->conn, &dataObjLseekInp, &dataObjLseekOut ); unuseIFuseConn( conn ); if ( dataObjLseekOut != NULL ) { free( dataObjLseekOut ); } } else { rodsLong_t lstatus; lstatus = lseek( fileCache->iFd, offset, SEEK_SET ); if ( lstatus >= 0 ) { status = 0; } else { status = lstatus; } } fileCache->offset = offset; return status; }
int _ifuseFileCacheWrite( fileCache_t *fileCache, char *buf, size_t size, off_t offset ) { int status, myError; openedDataObjInp_t dataObjWriteInp; bytesBuf_t dataObjWriteInpBBuf; iFuseConn_t *conn; bzero( &dataObjWriteInp, sizeof( dataObjWriteInp ) ); /* lseek to the right offset in case this cache is share by multiple descs */ status = _iFuseFileCacheLseek( fileCache, offset ); if ( status < 0 ) { if ( ( myError = getErrno( status ) ) > 0 ) { return -myError; } else { return -ENOENT; } } if ( fileCache->state == NO_FILE_CACHE ) { /* no file cache */ dataObjWriteInpBBuf.buf = ( void * ) buf; dataObjWriteInpBBuf.len = size; dataObjWriteInp.l1descInx = fileCache->iFd; dataObjWriteInp.len = size; conn = getAndUseConnByPath( fileCache->localPath, &status ); status = rcDataObjWrite( conn->conn, &dataObjWriteInp, &dataObjWriteInpBBuf ); unuseIFuseConn( conn ); if ( status < 0 ) { if ( ( myError = getErrno( status ) ) > 0 ) { return -myError; } else { return -ENOENT; } } else if ( status != ( int ) size ) { rodsLog( LOG_ERROR, "ifuseWrite: IFuseDesc[descInx].conn for %s is NULL", fileCache->localPath ); return -ENOENT; } fileCache->offset += status; if ( fileCache->offset > fileCache->fileSize ) { fileCache->fileSize = fileCache->offset; } } else { status = write( fileCache->iFd, buf, size ); if ( status < 0 ) { return errno ? ( -1 * errno ) : -1; } fileCache->offset += status; if ( fileCache->offset > fileCache->fileSize ) { fileCache->fileSize = fileCache->offset; } if ( fileCache->offset >= MAX_NEWLY_CREATED_CACHE_SIZE ) { _iFuseFileCacheFlush( fileCache ); fileCache->iFd = 0; /* reopen file */ dataObjInp_t dataObjOpenInp; memset( &dataObjOpenInp, 0, sizeof( dataObjOpenInp ) ); rstrcpy( dataObjOpenInp.objPath, fileCache->objPath, MAX_NAME_LEN ); dataObjOpenInp.openFlags = O_RDWR; int status; conn = getAndUseConnByPath( fileCache->localPath, &status ); status = rcDataObjOpen( conn->conn, &dataObjOpenInp ); unuseIFuseConn( conn ); if ( status < 0 ) { rodsLog( LOG_ERROR, "iFuseWrite: rcDataObjOpen of %s error. status = %d", fileCache->objPath, status ); return -ENOENT; } fileCache->iFd = status; } } return status; }
int irodsOpen (const char *path, struct fuse_file_info *fi) { dataObjInp_t dataObjInp; int status; int fd; iFuseConn_t *iFuseConn = NULL; iFuseDesc_t *desc = NULL; pathCache_t *tmpPathCache = NULL; struct stat stbuf; char cachePath[MAX_NAME_LEN]; char objPath[MAX_NAME_LEN]; int flags = fi->flags; rodsLog (LOG_DEBUG, "irodsOpen: %s, flags = %d", path, fi->flags); matchAndLockPathCache((char *) path, &tmpPathCache); if(tmpPathCache!= NULL) { if(tmpPathCache->fileCache != NULL) { LOCK_STRUCT(*(tmpPathCache->fileCache)); if (tmpPathCache->fileCache->state != NO_FILE_CACHE) { rodsLog (LOG_DEBUG, "irodsOpen: a match for %s", path); desc = newIFuseDesc(tmpPathCache->fileCache->objPath, (char *) path, tmpPathCache->fileCache, &status); if (status < 0) { UNLOCK_STRUCT(*(tmpPathCache->fileCache)); UNLOCK_STRUCT(*tmpPathCache); rodsLogError (LOG_ERROR, status, "irodsOpen: create descriptor of %s error", dataObjInp.objPath); return status; } fi->fh = desc->index; if(tmpPathCache->fileCache->iFd == 0) { tmpPathCache->fileCache->iFd = open(tmpPathCache->fileCache->fileCachePath, O_RDWR); } UNLOCK_STRUCT(*(tmpPathCache->fileCache)); UNLOCK_STRUCT(*tmpPathCache); return (0); } UNLOCK_STRUCT(*(tmpPathCache->fileCache)); } UNLOCK_STRUCT(*tmpPathCache); } memset (&dataObjInp, 0, sizeof (dataObjInp)); dataObjInp.openFlags = flags; status = parseRodsPathStr ((char *) (path + 1) , &MyRodsEnv, objPath); rstrcpy(dataObjInp.objPath, objPath, MAX_NAME_LEN); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsOpen: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath((char *) path, &MyRodsEnv, &status); /* status = getAndUseIFuseConn(&iFuseConn, &MyRodsEnv); */ if(status < 0) { rodsLogError (LOG_ERROR, status, "irodsOpen: cannot get connection for %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } /* do only O_RDONLY (0) */ status = _irodsGetattr (iFuseConn, path, &stbuf); if ((flags & (O_WRONLY | O_RDWR)) != 0 || status < 0 || stbuf.st_size > MAX_READ_CACHE_SIZE) { fd = rcDataObjOpen (iFuseConn->conn, &dataObjInp); unuseIFuseConn (iFuseConn); if (fd < 0) { rodsLogError (LOG_ERROR, status, "irodsOpen: rcDataObjOpen of %s error, status = %d", path, fd); return -ENOENT; } fileCache_t *fileCache = addFileCache(fd, objPath, (char *) path, NULL, stbuf.st_mode, stbuf.st_size, NO_FILE_CACHE); matchAndLockPathCache((char *) path, &tmpPathCache); if(tmpPathCache == NULL) { pathExist((char *) path, fileCache, &stbuf, NULL); } else { _addFileCacheForPath(tmpPathCache, fileCache); UNLOCK_STRUCT(*tmpPathCache); } desc = newIFuseDesc (objPath, (char *) path, fileCache, &status); if (desc == NULL) { rodsLogError (LOG_ERROR, status, "irodsOpen: allocIFuseDesc of %s error", path); return -ENOENT; } } else { rodsLog (LOG_DEBUG, "irodsOpenWithReadCache: caching %s", path); if ((status = getFileCachePath (path, cachePath)) < 0) { unuseIFuseConn(iFuseConn); return status; } /* get the file to local cache */ dataObjInp.dataSize = stbuf.st_size; status = rcDataObjGet (iFuseConn->conn, &dataObjInp, cachePath); unuseIFuseConn(iFuseConn); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsOpenWithReadCache: rcDataObjGet of %s error", dataObjInp.objPath); return status; } int fd = open(cachePath, O_RDWR); fileCache_t *fileCache = addFileCache(fd, objPath, (char *) path, cachePath, stbuf.st_mode, stbuf.st_size, HAVE_READ_CACHE); matchAndLockPathCache((char *) path, &tmpPathCache); if(tmpPathCache == NULL) { pathExist((char *) path, fileCache, &stbuf, NULL); } else { _addFileCacheForPath(tmpPathCache, fileCache); UNLOCK_STRUCT(*tmpPathCache); } desc = newIFuseDesc(objPath, (char *) path,fileCache, &status); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsOpen: create descriptor of %s error", dataObjInp.objPath); return status; } } fi->fh = desc->index; return (0); }
int irodsChmod (const char *path, mode_t mode) { int status; modDataObjMeta_t modDataObjMetaInp; keyValPair_t regParam; dataObjInfo_t dataObjInfo; char dataMode[SHORT_STR_LEN]; pathCache_t *tmpPathCache; iFuseConn_t *iFuseConn = NULL; rodsLog (LOG_DEBUG, "irodsChmod: %s", path); matchAndLockPathCache((char *) path, &tmpPathCache); if (tmpPathCache->fileCache != NULL) { LOCK_STRUCT(*tmpPathCache->fileCache); if(tmpPathCache->fileCache->state == HAVE_NEWLY_CREATED_CACHE) { /* has not actually been created yet */ tmpPathCache->fileCache->mode = mode; UNLOCK_STRUCT(*tmpPathCache->fileCache); UNLOCK_STRUCT(*tmpPathCache); return (0); } UNLOCK_STRUCT(*tmpPathCache->fileCache); } UNLOCK_STRUCT(*tmpPathCache); if(tmpPathCache->stbuf.st_nlink != 1) { rodsLog (LOG_NOTICE, "irodsChmod: modification of the mode of non file object is currently not supported", path); return 0; } memset (®Param, 0, sizeof (regParam)); snprintf (dataMode, SHORT_STR_LEN, "%d", mode); addKeyVal (®Param, DATA_MODE_KW, dataMode); addKeyVal (®Param, ALL_KW, ""); memset(&dataObjInfo, 0, sizeof(dataObjInfo)); status = parseRodsPathStr ((char *) (path + 1) , &MyRodsEnv, dataObjInfo.objPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsChmod: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } modDataObjMetaInp.regParam = ®Param; modDataObjMetaInp.dataObjInfo = &dataObjInfo; getAndUseIFuseConn (&iFuseConn, &MyRodsEnv); RECONNECT_IF_NECESSARY(status, iFuseConn, rcModDataObjMeta(iFuseConn->conn, &modDataObjMetaInp)); if (status >= 0) { #ifdef CACHE_FUSE_PATH pathCache_t *tmpPathCache; if (matchAndLockPathCache ((char *) path, &tmpPathCache) == 1) { tmpPathCache->stbuf.st_mode &= 0xfffffe00; tmpPathCache->stbuf.st_mode |= (mode & 0777); UNLOCK_STRUCT(*tmpPathCache); } #endif status = 0; } else { rodsLogError(LOG_ERROR, status, "irodsChmod: rcModDataObjMeta failure"); status = -ENOENT; } unuseIFuseConn (iFuseConn); clearKeyVal (®Param); 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 irodsSymlink (const char *to, const char *from) { int status; iFuseConn_t *iFuseConn = NULL; int l1descInx; dataObjInp_t dataObjOpenInp; openedDataObjInp_t dataObjWriteInp; bytesBuf_t dataObjWriteOutBBuf; char collPath[MAX_NAME_LEN]; struct stat stbuf; rodsLog (LOG_DEBUG, "irodsSymlink: %s to %s", from, to); status = parseRodsPathStr ((char *) (from + 1), &MyRodsEnv, collPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsReaddir: parseRodsPathStr of %s error", from); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath ((char *) from, &MyRodsEnv, &status); status = _irodsGetattr(iFuseConn, (char *) from, &stbuf); memset (&dataObjOpenInp, 0, sizeof (dataObjOpenInp)); rstrcpy (dataObjOpenInp.objPath, collPath, MAX_NAME_LEN); if(status != -ENOENT) { if (status < 0) { return status; } dataObjOpenInp.dataSize = 0; status = rcDataObjTruncate(iFuseConn->conn, &dataObjOpenInp); if (status < 0) { rodsLog (LOG_ERROR, "irodsReadlink: rcDataObjTruncate of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } } memset (&dataObjOpenInp, 0, sizeof (dataObjOpenInp)); rstrcpy (dataObjOpenInp.objPath, collPath, MAX_NAME_LEN); dataObjOpenInp.openFlags = O_WRONLY | O_CREAT; dataObjOpenInp.createMode = S_IFLNK; status = rcDataObjOpen (iFuseConn->conn, &dataObjOpenInp); if (status < 0) { rodsLog (LOG_ERROR, "irodsSymlink: rcDataObjOpen of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } l1descInx = status; memset(&dataObjWriteInp, 0, sizeof (dataObjWriteInp)); memset(&dataObjWriteOutBBuf, 0, sizeof (bytesBuf_t)); dataObjWriteInp.l1descInx = l1descInx; dataObjWriteInp.len = strlen(to); dataObjWriteOutBBuf.len = strlen(to); dataObjWriteOutBBuf.buf = strdup(to); status = rcDataObjWrite (iFuseConn->conn, &dataObjWriteInp, &dataObjWriteOutBBuf); free(dataObjWriteOutBBuf.buf); if (status < 0) { rodsLog (LOG_ERROR, "irodsSymlink: rcDataObjWrite of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } rcDataObjClose(iFuseConn->conn, &dataObjWriteInp); unuseIFuseConn (iFuseConn); return (0); }
int irodsMknod (const char *path, mode_t mode, dev_t rdev) { pathCache_t *tmpPathCache = NULL; struct stat stbuf; int status = -1; char cachePath[MAX_NAME_LEN]; char objPath[MAX_NAME_LEN]; iFuseConn_t *iFuseConn = NULL; fileCache_t *fileCache = NULL; /* iFuseDesc_t *desc = NULL; */ int localFd; rodsLog (LOG_DEBUG, "irodsMknod: %s", path); if (irodsGetattr (path, &stbuf) >= 0) return -EEXIST; status = irodsMknodWithCache ((char *)path, mode, cachePath); localFd = status; status = parseRodsPathStr ((char *) (path + 1) , &MyRodsEnv, objPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "dataObjCreateByFusePath: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } getAndUseIFuseConn (&iFuseConn, &MyRodsEnv); if (status < 0) { status = dataObjCreateByFusePath (iFuseConn->conn, (char *) path, mode, objPath); if (status < 0) { if (isReadMsgError (status)) { ifuseReconnect (iFuseConn); status = dataObjCreateByFusePath (iFuseConn->conn, (char *) path, mode, objPath); } if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsMknod: rcDataObjCreate of %s error", path); unuseIFuseConn (iFuseConn); return -ENOENT; } } } fileCache = addFileCache(localFd, objPath, (char *) path, cachePath, mode, 0, HAVE_NEWLY_CREATED_CACHE); stbuf.st_mode = mode; pathExist ((char *) path, fileCache, &stbuf, &tmpPathCache); /* desc = newIFuseDesc (objPath, (char *) path, fileCache, &status); */ if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsMknod: allocIFuseDesc of %s error", path); closeIrodsFd (iFuseConn->conn, status); unuseIFuseConn (iFuseConn); return 0; } /* rodsLog (LOG_ERROR, "irodsMknod: %s conn: %p", path, iFuseConn);*/ unuseIFuseConn (iFuseConn); return (0); }
int irodsReaddir (const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { char collPath[MAX_NAME_LEN]; collHandle_t collHandle; collEnt_t collEnt; int status; #ifdef CACHE_FUSE_PATH struct stat stbuf; pathCache_t *tmpPathCache; #endif /* don't know why we need this. the example have them */ (void) offset; (void) fi; iFuseConn_t *iFuseConn = NULL; rodsLog (LOG_DEBUG, "irodsReaddir: %s", path); filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); status = parseRodsPathStr ((char *) (path + 1), &MyRodsEnv, collPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsReaddir: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath ((char *) path, &MyRodsEnv, &status); status = rclOpenCollection (iFuseConn->conn, collPath, 0, &collHandle); if (status < 0) { if (isReadMsgError (status)) { ifuseReconnect (iFuseConn); status = rclOpenCollection (iFuseConn->conn, collPath, 0, &collHandle); } if (status < 0) { rodsLog (LOG_ERROR, "irodsReaddir: rclOpenCollection of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } } while ((status = rclReadCollection (iFuseConn->conn, &collHandle, &collEnt)) >= 0) { char myDir[MAX_NAME_LEN], mySubDir[MAX_NAME_LEN]; #ifdef CACHE_FUSE_PATH char childPath[MAX_NAME_LEN]; bzero (&stbuf, sizeof (struct stat)); #endif if (collEnt.objType == DATA_OBJ_T) { filler (buf, collEnt.dataName, NULL, 0); #ifdef CACHE_FUSE_PATH if (strcmp (path, "/") == 0) { snprintf (childPath, MAX_NAME_LEN, "/%s", collEnt.dataName); } else { snprintf (childPath, MAX_NAME_LEN, "%s/%s", path, collEnt.dataName); } if (lookupPathExist ((char *) childPath, &tmpPathCache) != 1) { fillFileStat (&stbuf, collEnt.dataMode, collEnt.dataSize, atoi (collEnt.createTime), atoi (collEnt.modifyTime), atoi (collEnt.modifyTime)); pathExist (childPath, NULL, &stbuf, &tmpPathCache); } #endif } else if (collEnt.objType == COLL_OBJ_T) { splitPathByKey (collEnt.collName, myDir, mySubDir, '/'); if(mySubDir[0] != '\0') { filler (buf, mySubDir, NULL, 0); #ifdef CACHE_FUSE_PATH if (strcmp (path, "/") == 0) { snprintf (childPath, MAX_NAME_LEN, "/%s", mySubDir); } else { snprintf (childPath, MAX_NAME_LEN, "%s/%s", path, mySubDir); } if (lookupPathExist ((char *) childPath, &tmpPathCache) != 1) { fillDirStat (&stbuf, atoi (collEnt.createTime), atoi (collEnt.modifyTime), atoi (collEnt.modifyTime)); pathExist (childPath, NULL, &stbuf, &tmpPathCache); } #endif } } } rclCloseCollection (&collHandle); unuseIFuseConn (iFuseConn); return (0); }
int irodsReadlink (const char *path, char *buf, size_t size) { int status; iFuseConn_t *iFuseConn = NULL; int l1descInx; dataObjInp_t dataObjOpenInp; openedDataObjInp_t dataObjReadInp; bytesBuf_t dataObjReadOutBBuf; char collPath[MAX_NAME_LEN]; rodsLog (LOG_DEBUG, "irodsReadlink: %s", path); status = parseRodsPathStr ((char *) (path + 1), &MyRodsEnv, collPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsReaddir: parseRodsPathStr of %s error", path); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath ((char *) path, &MyRodsEnv, &status); memset (&dataObjOpenInp, 0, sizeof (dataObjOpenInp)); rstrcpy (dataObjOpenInp.objPath, collPath, MAX_NAME_LEN); dataObjOpenInp.openFlags = O_RDONLY; status = rcDataObjOpen (iFuseConn->conn, &dataObjOpenInp); if (status < 0) { if (isReadMsgError (status)) { ifuseReconnect (iFuseConn); status = rcDataObjOpen (iFuseConn->conn, &dataObjOpenInp); } if (status < 0) { rodsLog (LOG_ERROR, "irodsReadlink: rcDataObjOpen of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } } l1descInx = status; memset(&dataObjReadInp, 0, sizeof (dataObjReadInp)); memset(&dataObjReadOutBBuf, 0, sizeof (bytesBuf_t)); dataObjReadInp.l1descInx = l1descInx; dataObjReadInp.len = size - 1; status = rcDataObjRead(iFuseConn->conn, &dataObjReadInp, &dataObjReadOutBBuf); if (status < 0) { rodsLog (LOG_ERROR, "irodsReadlink: rcDataObjRead of %s error. status = %d", collPath, status); unuseIFuseConn (iFuseConn); return -ENOENT; } memcpy(buf, dataObjReadOutBBuf.buf, status); buf[status] = '\0'; rcDataObjClose(iFuseConn->conn, &dataObjReadInp); unuseIFuseConn (iFuseConn); return (0); }
int _iFuseFileCacheFlush( fileCache_t *fileCache ) { int status = 0; int objFd; /* simply return if no file cache or the file cache hasn't been updated */ if ( fileCache->state != HAVE_NEWLY_CREATED_CACHE ) { //UNLOCK_STRUCT( *fileCache ); return 0; } /* no need to flush cache file as we are using low-level io */ /*status = fsync (fileCache->iFd); if (status < 0) { status = (errno ? (-1 * errno) : -1); rodsLog (LOG_ERROR, "ifuseFlush: flush of cache file for %s error, status = %d", fileCache->localPath, status); return -EBADF; }*/ struct stat stbuf; int error_code = stat( fileCache->fileCachePath, &stbuf ); if ( error_code != 0 ) { rodsLog( LOG_ERROR, "stat failed in _iFuseFileCacheFlush with status %d", error_code ); } /* put cache file to server */ //UNLOCK_STRUCT( *fileCache ); iFuseConn_t *conn = getAndUseConnByPath( fileCache->localPath, &status ); //LOCK_STRUCT( *fileCache ); RECONNECT_IF_NECESSARY( status, conn, ifusePut( conn->conn, fileCache->objPath, fileCache->fileCachePath, fileCache->mode, stbuf.st_size ) ); unuseIFuseConn( conn ); if ( status < 0 ) { rodsLog( LOG_ERROR, "ifuseClose: ifusePut of %s error, status = %d", fileCache->localPath, status ); status = -EBADF; return status; } objFd = status; if ( stbuf.st_size > MAX_READ_CACHE_SIZE ) { /* too big to keep */ /* close cache file */ status = close( fileCache->iFd ); if ( status < 0 ) { status = ( errno ? ( -1 * errno ) : -1 ); rodsLog( LOG_ERROR, "ifuseClose: close of cache file for %s error, status = %d", fileCache->localPath, status ); return -EBADF; } fileCache->iFd = objFd; fileCache->state = NO_FILE_CACHE; fileCache->offset = 0; status = objFd; } else { fileCache->state = HAVE_READ_CACHE; } return status; }
int irodsRename (const char *from, const char *to) { dataObjCopyInp_t dataObjRenameInp; int status; iFuseConn_t *iFuseConn = NULL; rodsLog (LOG_DEBUG, "irodsRename: %s to %s", from, to); /* test rcDataObjRename */ memset (&dataObjRenameInp, 0, sizeof (dataObjRenameInp)); status = parseRodsPathStr ((char *) (from + 1) , &MyRodsEnv, dataObjRenameInp.srcDataObjInp.objPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsRename: parseRodsPathStr of %s error", from); /* use ENOTDIR for this type of error */ return -ENOTDIR; } status = parseRodsPathStr ((char *) (to + 1) , &MyRodsEnv, dataObjRenameInp.destDataObjInp.objPath); if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsRename: parseRodsPathStr of %s error", to); /* use ENOTDIR for this type of error */ return -ENOTDIR; } char *toIrodsPath = strdup(dataObjRenameInp.destDataObjInp.objPath); addKeyVal (&dataObjRenameInp.destDataObjInp.condInput, FORCE_FLAG_KW, ""); dataObjRenameInp.srcDataObjInp.oprType = dataObjRenameInp.destDataObjInp.oprType = RENAME_UNKNOWN_TYPE; getAndUseIFuseConn (&iFuseConn, &MyRodsEnv); /* rodsLog (LOG_ERROR, "irodsRenme: %s -> %s conn: %p", from, to, iFuseConn);*/ status = rcDataObjRename (iFuseConn->conn, &dataObjRenameInp); if (status == CAT_NAME_EXISTS_AS_DATAOBJ || status == SYS_DEST_SPEC_COLL_SUB_EXIST) { rcDataObjUnlink (iFuseConn->conn, &dataObjRenameInp.destDataObjInp); status = rcDataObjRename (iFuseConn->conn, &dataObjRenameInp); } if (status >= 0) { #ifdef CACHE_FUSE_PATH status = renmeLocalPath ((char *) from, (char *) to, (char *) toIrodsPath); #endif } else { if (isReadMsgError (status)) { ifuseReconnect (iFuseConn); status = rcDataObjRename (iFuseConn->conn, &dataObjRenameInp); } if (status < 0) { rodsLogError (LOG_ERROR, status, "irodsRename: rcDataObjRename of %s to %s error", from, to); status = -ENOENT; } } unuseIFuseConn (iFuseConn); free(toIrodsPath); return (status); }