static NTSTATUS PvfsFindParentFCB( PPVFS_FCB *ppParentFcb, PCSTR pszFilename ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; PPVFS_FCB pFcb = NULL; PSTR pszDirname = NULL; PPVFS_CB_TABLE_ENTRY pBucket = NULL; if (LwRtlCStringIsEqual(pszFilename, "/", TRUE)) { ntError = STATUS_SUCCESS; *ppParentFcb = NULL; goto cleanup; } ntError = PvfsFileDirname(&pszDirname, pszFilename); BAIL_ON_NT_STATUS(ntError); ntError = PvfsCbTableGetBucket(&pBucket, &gPvfsDriverState.FcbTable, pszDirname); BAIL_ON_NT_STATUS(ntError); ntError = PvfsCbTableLookup((PPVFS_CONTROL_BLOCK*)OUT_PPVOID(&pFcb), pBucket, pszDirname); if (ntError == STATUS_OBJECT_NAME_NOT_FOUND) { ntError = PvfsCreateFCB( &pFcb, pszDirname, FALSE, 0, 0); } BAIL_ON_NT_STATUS(ntError); *ppParentFcb = PvfsReferenceFCB(pFcb); cleanup: if (pFcb) { PvfsReleaseFCB(&pFcb); } if (pszDirname) { LwRtlCStringFree(&pszDirname); } return ntError; error: goto cleanup; }
NTSTATUS PvfsFileSplitPath( PSTR *ppszDirname, PSTR *ppszBasename, PCSTR pszPath ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; ntError = PvfsFileDirname(ppszDirname, pszPath); BAIL_ON_NT_STATUS(ntError); ntError = PvfsFileBasename(ppszBasename, pszPath); BAIL_ON_NT_STATUS(ntError); cleanup: return ntError; error: goto cleanup; }
NTSTATUS PvfsSysOpenByFileName( OUT int *pFd, OUT PBOOLEAN pbCreateOwnerFile, IN PPVFS_FILE_NAME pFileName, IN int iFlags, IN mode_t Mode ) { NTSTATUS ntError = STATUS_SUCCESS; int fd = -1; int unixerr = 0; PSTR pszFilename = NULL; PVFS_STAT Stat = {0}; int Ownerfd = -1; PSTR pszStreamDirectoryName = NULL; PSTR pszMetadataPath = NULL; BOOLEAN bCreateOwnerFile = FALSE; // Need make sure the object (file/directory) exists // Before non-default stream objects can be created if (!PvfsIsDefaultStreamName(pFileName)) { ntError = PvfsSysStat(pFileName->FileName, &Stat); if (LW_STATUS_OBJECT_NAME_NOT_FOUND == ntError) { ntError = PvfsSysOpen( &Ownerfd, pFileName->FileName, iFlags, Mode); if (STATUS_SUCCESS == ntError) { bCreateOwnerFile = TRUE; } } BAIL_ON_NT_STATUS(ntError); ntError = PvfsLookupStreamDirectoryPath(&pszStreamDirectoryName, pFileName); BAIL_ON_NT_STATUS(ntError); ntError = PvfsFileDirname(&pszMetadataPath, pszStreamDirectoryName); BAIL_ON_NT_STATUS(ntError); ntError = PvfsSysOpenDir(pszMetadataPath, NULL); if (LW_STATUS_OBJECT_NAME_NOT_FOUND == ntError) { // create meta data directory ntError = PvfsSysMkDir( pszMetadataPath, (mode_t)gPvfsDriverConfig.CreateDirectoryMode); BAIL_ON_NT_STATUS(ntError); } BAIL_ON_NT_STATUS(ntError); ntError = PvfsSysOpenDir(pszStreamDirectoryName, NULL); if (LW_STATUS_OBJECT_NAME_NOT_FOUND == ntError) { // create stream directory for an object ntError = PvfsSysMkDir( pszStreamDirectoryName, (mode_t)gPvfsDriverConfig.CreateDirectoryMode); BAIL_ON_NT_STATUS(ntError); } BAIL_ON_NT_STATUS(ntError); ntError = LwRtlCStringAllocatePrintf( &pszFilename, "%s/%s", pszStreamDirectoryName, PvfsGetCStringBaseStreamName(pFileName)); BAIL_ON_NT_STATUS(ntError); } else { ntError = LwRtlCStringDuplicate(&pszFilename, PvfsGetCStringBaseFileName(pFileName)); BAIL_ON_NT_STATUS(ntError); } if ((fd = open(pszFilename, iFlags, Mode)) == -1) { PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError); } *pFd = fd; *pbCreateOwnerFile = bCreateOwnerFile; cleanup: if (pszFilename) { LwRtlCStringFree(&pszFilename); } if (pszStreamDirectoryName) { LwRtlCStringFree(&pszStreamDirectoryName); } if (pszMetadataPath) { LwRtlCStringFree(&pszMetadataPath); } if (Ownerfd != -1) { PvfsSysClose(Ownerfd); } return ntError; error: if (fd != -1) { PvfsSysClose(fd); } goto cleanup; }
NTSTATUS PvfsSysRenameByFileName( IN PPVFS_FILE_NAME OriginalFileName, IN PPVFS_FILE_NAME NewFileName ) { NTSTATUS ntError = STATUS_SUCCESS; int unixerr = 0; PSTR oldFilename = NULL; PSTR newFilename = NULL; PSTR oldStreamDir = NULL; PSTR newStreamDir = NULL; PSTR newStreamDirParent = NULL; PVFS_STAT streamDirStat = { 0 }; ntError = PvfsLookupStreamDiskFileName(&oldFilename, OriginalFileName); BAIL_ON_NT_STATUS(ntError); ntError = PvfsLookupStreamDiskFileName(&newFilename, NewFileName); BAIL_ON_NT_STATUS(ntError); if (rename(oldFilename, newFilename) == -1 ) { PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError); } if (PvfsIsDefaultStreamName(OriginalFileName)) { // Have to rename the stream directory as well ntError = PvfsLookupStreamDirectoryPath(&oldStreamDir, OriginalFileName); BAIL_ON_NT_STATUS(ntError); ntError = PvfsLookupStreamDirectoryPath(&newStreamDir, NewFileName); BAIL_ON_NT_STATUS(ntError); ntError = PvfsSysStat(oldStreamDir, &streamDirStat); if (ntError == STATUS_SUCCESS) { ntError = PvfsFileDirname(&newStreamDirParent, newStreamDir); BAIL_ON_NT_STATUS(ntError); LwRtlZeroMemory(&streamDirStat, sizeof(streamDirStat)); ntError = PvfsSysStat(newStreamDirParent, &streamDirStat); switch (ntError) { case STATUS_SUCCESS: if (!S_ISDIR(streamDirStat.s_mode)) { ntError = STATUS_NOT_A_DIRECTORY; } break; case STATUS_OBJECT_NAME_NOT_FOUND: ntError = PvfsSysMkDir( newStreamDirParent, (mode_t)gPvfsDriverConfig.CreateDirectoryMode); break; default: break; } BAIL_ON_NT_STATUS(ntError); if (rename(oldStreamDir, newStreamDir) == -1) { // We are now in an inconstsent state -- What should we do? // We cannot safely roll back to the original name // as someone else may have it. Let's BAIL for now although // in the future we may decide that this should just log an error // but not fail PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError); } } // Squash the error is the stream directory did not exist ntError = STATUS_SUCCESS; } error: if (oldFilename) { LwRtlCStringFree(&oldFilename); } if (newFilename) { LwRtlCStringFree(&newFilename); } if (oldStreamDir) { LwRtlCStringFree(&oldStreamDir); } if (newStreamDir) { LwRtlCStringFree(&newStreamDir); } if (newStreamDirParent) { LwRtlCStringFree(&newStreamDirParent); } return ntError; }