ssize_t xixfs_file_readv( struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *ppos ) { struct address_space *mapping = filp->f_mapping; struct inode *inode = mapping->host; PXIXFS_LINUX_FCB pFCB = NULL; XIXCORE_ASSERT(inode); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR DELETED FILE \n")); return -EPERM; } DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_file_readv (%s).\n", filp->f_dentry->d_name.name)); return generic_file_readv(filp, iov, nr_segs, ppos); }
int xixfs_file_open( struct inode * inode, struct file * filp ) { struct super_block *sb = NULL; PXIXFS_LINUX_VCB pVCB = NULL; PXIXFS_LINUX_FCB pFCB = NULL; int RC = 0; sb = inode->i_sb; XIXCORE_ASSERT(sb); pVCB = XIXFS_SB(sb); XIXFS_ASSERT_VCB(pVCB); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_file_open (%s). MODE(0x%x). %d(%p)\n", filp->f_dentry->d_name.name, filp->f_flags, inode->i_ino, inode)); if( pFCB->XixcoreFcb.FCBType == FCB_TYPE_FILE) { if(XIXCORE_TEST_FLAGS(filp->f_flags, (O_WRONLY|O_RDWR| O_TRUNC|O_APPEND)) ){ if(pFCB->XixcoreFcb.HasLock != INODE_FILE_LOCK_HAS) { RC = xixcore_LotLock( &pVCB->XixcoreVcb, pFCB->XixcoreFcb.LotNumber, &pFCB->XixcoreFcb.HasLock, 1, 1 ); /* if( RC < 0 ) { return -EINVAL; } */ } } } return generic_file_open(inode, filp); }
ssize_t xixfs_file_read( struct file *filp, char __user *buf, size_t count, loff_t *ppos ) { #if LINUX_VERSION_25_ABOVE struct address_space *mapping = filp->f_mapping; #else struct address_space *mapping = filp->f_dentry->d_inode->i_mapping; #endif struct inode *inode = mapping->host; PXIXFS_LINUX_FCB pFCB = NULL; ssize_t ret = 0; XIXCORE_ASSERT(inode); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_file_read (%s).\n", filp->f_dentry->d_name.name)); if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR DELETED FILE \n")); //printk(KERN_DEBUG "xixfs_file_read ERROR\n"); return -EPERM; } //ret = do_sync_read(filp, buf, count, ppos); #if LINUX_VERSION_2_6_19_REPLACE_INTERFACE ret = do_sync_read(filp, buf, count, ppos); #else ret = generic_file_read(filp, buf, count, ppos); #endif //printk(KERN_DEBUG "xixfs_file_read ret (0x%x)\n", ret); return ret; }
VOID xixfs_FCBTLBRemovePrefix ( IN BOOLEAN CanWait, IN PXIXFS_LCB Lcb ) { PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB), ("Enter xixfs_FCBTLBRemovePrefix \n" )); // // Check inputs. // ASSERT_LCB( Lcb ); // // Check the acquisition of the two Fcbs. // ASSERT_EXCLUSIVE_FCB_OR_VCB( Lcb->ParentFcb ); ASSERT_EXCLUSIVE_FCB_OR_VCB( Lcb->ChildFcb ); // // Now remove the linkage and delete the Lcb. // RemoveEntryList( &Lcb->ParentFcbLinks ); RemoveEntryList( &Lcb->ChildFcbLinks ); if(XIXCORE_TEST_FLAGS(Lcb->LCBFlags, XIFSD_LCB_STATE_IGNORE_CASE_SET)){ Lcb->ParentFcb->IgnoreCaseRoot = RtlDelete( &Lcb->IgnoreCaseLinks); } Lcb->ParentFcb->Root = RtlDelete( &Lcb->Links ); xixfs_FreeLCB(Lcb); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB), ("Exit xixfs_FCBTLBRemovePrefix \n" )); return; }
ssize_t xixfs_file_aio_read( struct kiocb *iocb, #if LINUX_VERSION_2_6_19_REPLACE_INTERFACE const struct iovec *iov, unsigned long count, #else char __user *buf, size_t count, #endif loff_t pos ) { struct address_space *mapping = iocb->ki_filp->f_mapping; struct inode *inode = mapping->host; PXIXFS_LINUX_FCB pFCB = NULL; ssize_t ret = 0; XIXCORE_ASSERT(inode); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR DELETED FILE \n")); //printk(KERN_DEBUG "xixfs_file_aio_read ERROR\n"); return -EPERM; } DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_file_aio_read .\n")); #if LINUX_VERSION_2_6_19_REPLACE_INTERFACE ret = generic_file_aio_read(iocb, iov, count, pos); #else ret = generic_file_aio_read(iocb, buf, count, pos); #endif //printk(KERN_DEBUG "xixfs_file_aio_read ret (0x%x)\n", ret); return ret; }
void xixcore_call xixcore_FreeBuffer(PXIXCORE_BUFFER xixfsBuffer) { PXIX_BUF xbuf = container_of(xixfsBuffer, XIX_BUF, xixcore_buffer); if(xbuf->xix_page){ free_pages( (unsigned long)xbuf->xixcore_buffer.xcb_data, get_order(xbuf->xixcore_buffer.xcb_size)); xbuf->xix_page = NULL; xbuf->xixcore_buffer.xcb_data = NULL; } if(XIXCORE_TEST_FLAGS(xixfsBuffer->xcb_flags,XIXCORE_BUFF_ALLOC_F_MEMORY)){ kfree(xbuf); }else{ kmem_cache_free(xbuf_cachep, xbuf); } return; }
VOID xixfs_SetFileObject( IN PXIXFS_IRPCONTEXT IrpContext, IN PFILE_OBJECT FileObject, IN TYPE_OF_OPEN TypeOfOpen, IN PXIXFS_FCB pFCB OPTIONAL, IN PXIXFS_CCB pCCB OPTIONAL ) { PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Enter xixfs_SetFileObject\n")); ASSERT(!XIXCORE_TEST_FLAGS(((ULONG_PTR)pCCB), TYPE_OF_OPEN_MASK)); if(TypeOfOpen == UnopenedFileObject){ DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("xixfs_SetFileObject UnopenedFileObject\n")); FileObject->FsContext = FileObject->FsContext2 = NULL; return; } FileObject->FsContext = pFCB; FileObject->FsContext2 = pCCB; FileObject->CurrentByteOffset.QuadPart = 0; XIXCORE_SET_FLAGS(((ULONG_PTR)FileObject->FsContext2), TypeOfOpen); FileObject->Vpb = pFCB->PtrVCB->PtrVPB; DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Exit xixfs_SetFileObject\n")); return; }
NTSTATUS xixfs_CommonQueryVolumeInformation( IN PXIXFS_IRPCONTEXT pIrpContext ) { NTSTATUS RC = STATUS_SUCCESS; PIRP pIrp = NULL; PIO_STACK_LOCATION pIrpSp = NULL; PXIXFS_VCB pVCB = NULL; PXIXFS_FCB pFCB = NULL; PXIXFS_CCB pCCB = NULL; PFILE_OBJECT pFileObject = NULL; BOOLEAN Wait = FALSE; uint32 BytesToReturn = 0; uint32 Length = 0; TYPE_OF_OPEN TypeOfOpen = UnopenedFileObject; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT), ("Enter xixfs_CommonQueryVolumeInformation \n")); ASSERT(pIrpContext); pIrp = pIrpContext->Irp; ASSERT(pIrp); pIrpSp = IoGetCurrentIrpStackLocation(pIrp); ASSERT(pIrp); pFileObject = pIrpSp->FileObject; ASSERT(pFileObject); TypeOfOpen = xixfs_DecodeFileObject( pFileObject, &pFCB, &pCCB ); if (TypeOfOpen == UnopenedFileObject) { RC = STATUS_INVALID_PARAMETER; xixfs_CompleteRequest( pIrpContext, STATUS_INVALID_PARAMETER, 0 ); return RC; } DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, ("!!!!VolumeInformation pCCB(%p)\n", pCCB)); pVCB = pFCB->PtrVCB; ASSERT_VCB(pVCB); Wait = XIXCORE_TEST_FLAGS(pIrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT); if(!ExAcquireResourceSharedLite(&(pVCB->VCBResource), Wait)){ DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT), ("PostRequest IrpContext(%p) Irp(%p)\n", pIrpContext, pIrp)); RC = xixfs_PostRequest(pIrpContext, pIrp); return RC; } try{ Length = pIrpSp->Parameters.QueryVolume.Length ; DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT), ("pIrpSp->Parameters.QueryVolume.FsInformationClass (0x%x)\n", pIrpSp->Parameters.QueryVolume.FsInformationClass)); switch (pIrpSp->Parameters.QueryVolume.FsInformationClass) { case FileFsSizeInformation: { RC = xixfs_QueryFsSizeInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn ); xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn); break; } case FileFsVolumeInformation: { RC = xixfs_QueryFsVolumeInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn ); xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn); break; } case FileFsDeviceInformation: { RC = xixfs_QueryFsDeviceInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn ); xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn); break; } case FileFsAttributeInformation: { RC = xixfs_QueryFsAttributeInfo( pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn ); xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn); break; } case FileFsFullSizeInformation: { RC = xixfs_QueryFsFullSizeInfo(pIrpContext, pVCB, pIrp->AssociatedIrp.SystemBuffer, Length, &BytesToReturn); xixfs_CompleteRequest(pIrpContext, RC, BytesToReturn); break; } default: DebugTrace( DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("default Not supported Volume Info %ld\n",pIrpSp->Parameters.QueryVolume.FsInformationClass)); RC = STATUS_INVALID_PARAMETER; xixfs_CompleteRequest(pIrpContext, RC, 0); break; } }finally{ ExReleaseResourceLite(&(pVCB->VCBResource)); } DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_VOLINFO|DEBUG_TARGET_IRPCONTEXT), ("Exit xixfs_CommonQueryVolumeInformation \n")); return RC; }
PXIXFS_LCB xixfs_FCBTLBInsertPrefix ( IN PXIXFS_IRPCONTEXT IrpContext, IN PXIXFS_FCB Fcb, IN PUNICODE_STRING Name, IN PXIXFS_FCB ParentFcb ) { PXIXFS_LCB Lcb; PRTL_SPLAY_LINKS *TreeRoot; PLIST_ENTRY ListLinks; PWCHAR NameBuffer; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB), ("Enter xixfs_FCBTLBInsertPrefix \n" )); // // Check inputs. // ASSERT_IRPCONTEXT( IrpContext ); ASSERT_FCB( Fcb ); ASSERT_EXCLUSIVE_FCB( Fcb ); ASSERT_EXCLUSIVE_FCB( ParentFcb ); ASSERT( ParentFcb->XixcoreFcb.FCBType == FCB_TYPE_DIR); // // It must be the case that an index Fcb is only referenced by a single index. Now // we walk the child's Lcb queue to insure that if any prefixes have already been // inserted, they all refer to the index Fcb we are linking to. This is the only way // we can detect directory cross-linkage. // if (Fcb->XixcoreFcb.FCBType == FCB_TYPE_DIR) { for (ListLinks = Fcb->ParentLcbQueue.Flink; ListLinks != &Fcb->ParentLcbQueue; ListLinks = ListLinks->Flink) { Lcb = CONTAINING_RECORD( ListLinks, XIXFS_LCB, ChildFcbLinks ); if (Lcb->ParentFcb != ParentFcb) { XifsdRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); } } } // // Allocate space for the Lcb. // Lcb = xixfs_AllocateLCB(Name->Length); // // Initialize the name-based file attributes. // Lcb->FileAttributes = 0; // // Set up the filename in the Lcb. // RtlCopyMemory( Lcb->FileName.Buffer, Name->Buffer, Name->Length ); // // Capture the separate cases. // TreeRoot = &ParentFcb->Root; // // Insert the Lcb into the prefix tree. // if (!xixfs_NLInsertNameLink( IrpContext, TreeRoot, Lcb )) { // // This will very rarely occur. // xixfs_FreeLCB( Lcb ); Lcb = xixfs_NLFindNameLink( IrpContext, TreeRoot, Name ); if (Lcb == NULL) { // // Even worse. // XifsdRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR ); } if(!XIXCORE_TEST_FLAGS(Lcb->LCBFlags, XIFSD_LCB_STATE_IGNORE_CASE_SET)){ XifsdRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR ); } return Lcb; } // // Capture the separate cases. // TreeRoot = &ParentFcb->IgnoreCaseRoot; // // Set up the filename in the Lcb. // RtlDowncaseUnicodeString(&(Lcb->IgnoreCaseFileName), Name, FALSE); if(!xixfs_NLInsertNameLinkIgnoreCase( IrpContext, TreeRoot, Lcb )){ XifsdRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR ); } XIXCORE_SET_FLAGS(Lcb->LCBFlags, XIFSD_LCB_STATE_IGNORE_CASE_SET); // // Link the Fcbs together through the Lcb. // Lcb->ParentFcb = ParentFcb; Lcb->ChildFcb = Fcb; InsertHeadList( &ParentFcb->ChildLcbQueue, &Lcb->ParentFcbLinks ); InsertHeadList( &Fcb->ParentLcbQueue, &Lcb->ChildFcbLinks ); // // Initialize the reference count. // Lcb->Reference = 0; //DbgPrint(" !!!Insert LCB FileName(%wZ) IgnoreFileName(%wZ) .\n", &Lcb->FileName, &Lcb->IgnoreCaseFileName); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB), ("Exit xixfs_FCBTLBInsertPrefix \n" )); return Lcb; }
PXIXFS_LCB xixfs_FCBTLBFindPrefix ( IN PXIXFS_IRPCONTEXT IrpContext, IN OUT PXIXFS_FCB *CurrentFcb, IN OUT PUNICODE_STRING RemainingName, IN BOOLEAN bIgnoreCase ) { UNICODE_STRING LocalRemainingName; UNICODE_STRING FinalName; PXIXFS_LCB NameLink; PXIXFS_LCB CurrentLcb = NULL; BOOLEAN Waitable = FALSE; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB), ("Enter xixfs_FCBTLBFindPrefix \n" )); // // Check inputs. // ASSERT_IRPCONTEXT( IrpContext ); ASSERT_FCB( *CurrentFcb ); ASSERT_EXCLUSIVE_FCB( *CurrentFcb ); Waitable = XIXCORE_TEST_FLAGS(IrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT); try{ // // Make a local copy of the input strings. // LocalRemainingName = *RemainingName; // // Loop until we find the longest matching prefix. // while (TRUE) { // // If there are no characters left or we are not at an IndexFcb then // return immediately. // if ((LocalRemainingName.Length == 0) || (XifsSafeNodeType( *CurrentFcb ) != XIFS_NODE_FCB)) { try_return(TRUE); // return CurrentLcb; } if((*CurrentFcb)->XixcoreFcb.FCBType != FCB_TYPE_DIR){ try_return(TRUE); //return CurrentLcb; } // // Split off the next component from the name. // FsRtlDissectName( LocalRemainingName, &FinalName, &LocalRemainingName); // // Check if this name is in the splay tree for this Fcb. // if(bIgnoreCase){ NameLink = xixfs_NLFindNameLinkIgnoreCase( IrpContext, &(*CurrentFcb)->IgnoreCaseRoot, &FinalName ); }else{ NameLink = xixfs_NLFindNameLink( IrpContext, &(*CurrentFcb)->Root, &FinalName ); } // // If we didn't find a match then exit. // if (NameLink == NULL) { break; } // // // //if ( XIXCORE_TEST_FLAGS(NameLink->LCBFlags, // (XIFSD_LCB_STATE_LINK_IS_GONE)) ) //{ // break; //} CurrentLcb = NameLink; // // Update the caller's remaining name string to reflect the fact that we found // a match. // *RemainingName = LocalRemainingName; // // Move down to the next component in the tree. Acquire without waiting. // If this fails then lock the Fcb to reference this Fcb and then drop // the parent and acquire the child. // ASSERT( NameLink->ParentFcb == *CurrentFcb ); if (!XifsdAcquireFcbExclusive( Waitable, NameLink->ChildFcb, FALSE )) { // // If we can't wait then raise CANT_WAIT. // if ( Waitable) { XifsdRaiseStatus( IrpContext, STATUS_CANT_WAIT ); } XifsdLockVcb( IrpContext, IrpContext->VCB ); NameLink->ChildFcb->FCBReference += 1; NameLink->Reference += 1; XifsdUnlockVcb( IrpContext, IrpContext->VCB ); XifsdReleaseFcb( IrpContext, *CurrentFcb ); XifsdAcquireFcbExclusive( Waitable, NameLink->ChildFcb, FALSE ); XifsdLockVcb( IrpContext, IrpContext->VCB ); NameLink->ChildFcb->FCBReference -= 1; NameLink->Reference -= 1; XifsdUnlockVcb( IrpContext, IrpContext->VCB ); } else { XifsdReleaseFcb( IrpContext, *CurrentFcb ); } *CurrentFcb = NameLink->ChildFcb; } }finally{ if(AbnormalTermination()){ ExRaiseStatus(STATUS_CANT_WAIT); } } DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CREATE|DEBUG_TARGET_CLOSE| DEBUG_TARGET_FCB), ("Exit xixfs_FCBTLBFindPrefix \n" )); return CurrentLcb; }
NTSTATUS xixfs_FlusVolume( IN PXIXFS_IRPCONTEXT IrpContext, IN PXIXFS_VCB pVCB ) { PVOID RestartKey = NULL; PXIXFS_FCB ThisFcb = NULL; PXIXFS_FCB NextFcb = NULL; BOOLEAN RemovedFcb = FALSE; BOOLEAN CanWait = FALSE; uint32 lockedVcbValue = 0; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Enter xixfs_FlusVolume\n")); ASSERT_EXCLUSIVE_VCB(pVCB); CanWait = XIXCORE_TEST_FLAGS(IrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT); xixfs_RealCloseFCB(pVCB); while (TRUE) { XifsdLockVcb( IrpContext, pVCB ); NextFcb = xixfs_FCBTLBGetNextEntry(pVCB, &RestartKey ); // // Reference the NextFcb if present. // if (NextFcb != NULL) { NextFcb->FCBReference += 1; } // // If the last Fcb is present then decrement reference count and call teardown // to see if it should be removed. // if (ThisFcb != NULL) { ThisFcb->FCBReference -= 1; XifsdUnlockVcb( IrpContext, pVCB ); } else { XifsdUnlockVcb( IrpContext, pVCB ); } // // Break out of the loop if no more Fcb's. // if (NextFcb == NULL) { break; } // // Move to the next Fcb. // ThisFcb = NextFcb; // // If there is a image section then see if that can be closed. // if(ThisFcb->XixcoreFcb.FCBType == FCB_TYPE_FILE){ DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("XifsdPurgeVolume FCB(%I64d) \n", ThisFcb->XixcoreFcb.LotNumber)); XifsdAcquireFcbExclusive(TRUE, ThisFcb, FALSE); //ExAcquireResourceShared(ThisFcb->PagingIoResource, TRUE); if(XIXCORE_TEST_FLAGS(ThisFcb->XixcoreFcb.FCBFlags, XIXCORE_FCB_CACHED_FILE)){ // Added by ILGU HONG for readonly 09052006 if(!ThisFcb->PtrVCB->XixcoreVcb.IsVolumeWriteProtected){ CcFlushCache(&ThisFcb->SectionObject, NULL, 0, NULL); } // Added by ILGU HONG for readonly end } //ExReleaseResource(ThisFcb->PagingIoResource); XifsdReleaseFcb(TRUE, ThisFcb); } } DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Exit xixfs_FlusVolume\n")); return STATUS_SUCCESS; }
ssize_t xixfs_file_writev( struct file *file, const struct iovec *iov, unsigned long nr_segs, loff_t *ppos ) { ssize_t RC = 0; int64 index = 0; struct address_space *mapping = file->f_mapping; struct inode *inode = mapping->host; PXIXFS_LINUX_FCB pFCB = NULL; PXIXFS_LINUX_VCB pVCB = NULL; XIXCORE_ASSERT(inode); pVCB = XIXFS_SB(inode->i_sb); XIXFS_ASSERT_VCB(pVCB); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_file_writev (%s).\n", file->f_dentry->d_name.name)); if(pVCB->XixcoreVcb.IsVolumeWriteProtected){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR xixfs_file_writev : is read only .\n")); return -EPERM; } if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR DELETED FILE \n")); return -EPERM; } XIXCORE_ASSERT(pFCB->XixcoreFcb.FCBType == FCB_TYPE_FILE); if(pFCB->XixcoreFcb.HasLock == INODE_FILE_LOCK_HAS) { index =(int64) (*ppos); RC = generic_file_writev(file, iov, nr_segs, ppos); if(RC > 0 ) { if(pFCB->XixcoreFcb.WriteStartOffset == -1) { pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } if(pFCB->XixcoreFcb.WriteStartOffset > index ){ pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } } DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("EXIT xixfs_file_writev (%d).\n", RC)); return RC; } DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("EXIT xixfs_file_writev ERROR.\n")); return -EPERM; }
int xixfs_sync_inode(struct inode *inode) { struct writeback_control wbc = { .sync_mode = WB_SYNC_ALL, .nr_to_write = 0, /* sys_fsync did this */ }; return sync_inode(inode, &wbc); } #endif int xixfs_sync_file( struct file *file, struct dentry *dentry, int datasync ) { struct inode *inode = dentry->d_inode; PXIXFS_LINUX_FCB pFCB = NULL; PXIXFS_LINUX_VCB pVCB = NULL; int err = 0; int ret = 0; XIXCORE_ASSERT(inode); pVCB = XIXFS_SB(inode->i_sb); XIXFS_ASSERT_VCB(pVCB); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_sync_file (%s).\n", file->f_dentry->d_name.name)); if(pVCB->XixcoreVcb.IsVolumeWriteProtected){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR xixfs_sync_file : is read only .\n")); return -EPERM; } if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR DELETED FILE \n")); return -EPERM; } XIXCORE_ASSERT(pFCB->XixcoreFcb.FCBType == FCB_TYPE_FILE); if(pFCB->XixcoreFcb.HasLock == INODE_FILE_LOCK_HAS) { #if LINUX_VERSION_25_ABOVE ret = sync_mapping_buffers(inode->i_mapping); if (!(inode->i_state & I_DIRTY)) return ret; if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) return ret; xixfs_sync_inode(inode); #endif if(XIXCORE_TEST_FLAGS(pFCB->XixcoreFcb.FCBFlags,XIXCORE_FCB_MODIFIED_FILE)){ #if LINUX_VERSION_25_ABOVE err = xixfs_write_inode(inode, 1); #else xixfs_write_inode(inode, 1); #endif if(pFCB->XixcoreFcb.WriteStartOffset != -1){ printk(KERN_DEBUG "Set Update Information!!!\n"); xixfs_SendFileChangeRC( pVCB->XixcoreVcb.HostMac, pFCB->XixcoreFcb.LotNumber, pVCB->XixcoreVcb.VolumeId, i_size_read(inode), pFCB->XixcoreFcb.RealAllocationSize, pFCB->XixcoreFcb.WriteStartOffset ); pFCB->XixcoreFcb.WriteStartOffset = -1; } if (ret == 0) ret = err; return ret; } }else { return -EPERM; } return ret; } #if LINUX_VERSION_25_ABOVE #if LINUX_VERSION_2_6_19_REPLACE_INTERFACE ssize_t xixfs_file_splice_read( struct file *in, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags ) { return generic_file_splice_read(in, ppos, pipe, len, flags); } ssize_t xixfs_file_splice_write( struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags ) { ssize_t RC = 0; int64 index = 0; struct address_space *mapping = out->f_mapping; struct inode *inode = mapping->host; PXIXFS_LINUX_FCB pFCB = NULL; PXIXFS_LINUX_VCB pVCB = NULL; XIXCORE_ASSERT(inode); pVCB = XIXFS_SB(inode->i_sb); XIXFS_ASSERT_VCB(pVCB); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_file_splice_write (%s).\n", out->f_dentry->d_name.name)); if(pVCB->XixcoreVcb.IsVolumeWriteProtected){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR xixfs_file_splice_write : is read only .\n")); return -EPERM; } if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR DELETED FILE \n")); return -EPERM; } XIXCORE_ASSERT(pFCB->XixcoreFcb.FCBType == FCB_TYPE_FILE); if(pFCB->XixcoreFcb.HasLock == INODE_FILE_LOCK_HAS) { index =(int64) (*ppos); RC = generic_file_splice_write(pipe, out, ppos, len, flags); if(RC > 0 ) { if(pFCB->XixcoreFcb.WriteStartOffset == -1) { pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } if(pFCB->XixcoreFcb.WriteStartOffset > index ){ pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } } DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("EXIT xixfs_file_writev (%d).\n", RC)); return RC; } DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("EXIT xixfs_file_writev ERROR.\n")); return -EPERM; }
ssize_t xixfs_file_aio_write( struct kiocb *iocb, #if LINUX_VERSION_2_6_19_REPLACE_INTERFACE const struct iovec *iov, unsigned long count, #else const char __user *buf, size_t count, #endif loff_t pos ) { ssize_t RC = 0; int64 index = 0; struct address_space *mapping = iocb->ki_filp->f_mapping; struct inode *inode = mapping->host; PXIXFS_LINUX_FCB pFCB = NULL; PXIXFS_LINUX_VCB pVCB = NULL; XIXCORE_ASSERT(inode); pVCB = XIXFS_SB(inode->i_sb); XIXFS_ASSERT_VCB(pVCB); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_file_aio_write .\n")); if(pVCB->XixcoreVcb.IsVolumeWriteProtected){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR xixfs_file_aio_write : is read only .\n")); return -EPERM; } XIXCORE_ASSERT(pFCB->XixcoreFcb.FCBType == FCB_TYPE_FILE); if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR DELETED FILE \n")); return -EPERM; } if( pFCB->XixcoreFcb.HasLock == INODE_FILE_LOCK_HAS) { index =(int64) pos; #if LINUX_VERSION_2_6_19_REPLACE_INTERFACE RC = generic_file_aio_write(iocb, iov, count, pos); #else RC = generic_file_aio_write(iocb, buf, count, pos); #endif if(RC > 0) { if(pFCB->XixcoreFcb.WriteStartOffset == -1) { pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } if(pFCB->XixcoreFcb.WriteStartOffset > index ){ pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } return RC; } } else { return -EPERM; } DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("EXIT xixfs_file_aio_write .\n")); return RC; }
NTSTATUS xixfs_CommonClose( IN PXIXFS_IRPCONTEXT pIrpContext ) { NTSTATUS RC = STATUS_SUCCESS; PXIXFS_FCB pFCB = NULL; PXIXFS_CCB pCCB = NULL; PXIXFS_VCB pVCB = NULL; PFILE_OBJECT pFileObject = NULL; PIRP pIrp = NULL; PIO_STACK_LOCATION pIrpSp = NULL; BOOLEAN OpenVCB = FALSE; BOOLEAN PotentialVCBUnmount = FALSE; BOOLEAN CanWait = FALSE; BOOLEAN ForceDismount = FALSE; BOOLEAN bUserReference = FALSE; TYPE_OF_OPEN TypeOfOpen = UnopenedFileObject; BOOLEAN bVcbAcq = FALSE; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT), ("Enter xixfs_CommonClose IrpContext(%p)\n", pIrpContext)); ASSERT_IRPCONTEXT(pIrpContext); pIrp = pIrpContext->Irp; ASSERT(pIrp); // check if open request is releated to file system CDO { PDEVICE_OBJECT DeviceObject = pIrpContext->TargetDeviceObject; ASSERT(DeviceObject); if (DeviceObject == XiGlobalData.XifsControlDeviceObject) { RC = STATUS_SUCCESS; DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT), ("CDO Device Close DevObj(%p).\n", DeviceObject)); xixfs_CompleteRequest(pIrpContext,RC,0); return(RC); } } if(pIrpContext->VCB == NULL) { DebugTrace(DEBUG_LEVEL_INFO, DEBUG_TARGET_CLOSE, ("pIrpContext->VCB == NULL.\n")); RC = STATUS_SUCCESS; xixfs_CompleteRequest(pIrpContext, RC, 0); return RC; } CanWait = XIXCORE_TEST_FLAGS(pIrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT); pIrpSp = IoGetCurrentIrpStackLocation(pIrp); ASSERT(pIrpSp); pFileObject = pIrpSp->FileObject; ASSERT(pFileObject); TypeOfOpen = xixfs_DecodeFileObject(pFileObject, &pFCB, &pCCB); if(TypeOfOpen == UnopenedFileObject) { DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT), ("TypeOfOpen <= StreamFileOpen.\n")); xixfs_CompleteRequest(pIrpContext, STATUS_SUCCESS, 0); return STATUS_SUCCESS; } if(TypeOfOpen == UserVolumeOpen) { ForceDismount = XIXCORE_TEST_FLAGS( pCCB->CCBFlags, XIXFSD_CCB_DISMOUNT_ON_CLOSE); if(ForceDismount) { if(!CanWait) { DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT), ("Force Dismount with Non Waitable Context.\n")); RC = xixfs_PostRequest(pIrpContext, pIrp); return RC; } } } DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_ALL, ("!!!!Close pCCB(%p) FileObject(%p)\n", pCCB, pFileObject)); ASSERT_FCB(pFCB); pVCB = pFCB->PtrVCB; ASSERT_VCB(pVCB); if( (pVCB->VCBCleanup == 0) && (pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_MOUNTED) ) { if(!CanWait) { DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT), ("Force Dismount with Non Waitable Context.\n")); RC = xixfs_PostRequest(pIrpContext, pIrp); return RC; } } // // Clean up any CCB associated with this open. // try { if( ((TypeOfOpen == UserDirectoryOpen) || (TypeOfOpen == UserFileOpen) || (TypeOfOpen == UserVolumeOpen)) && (pCCB != NULL) ) { bUserReference = TRUE; DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_CCB), ("XifsdCommonClose Delete CCB (%x)\n", pCCB)); // Test //XifsdLockFcb(NULL, pFCB); //RemoveEntryList(&pCCB->LinkToFCB); //XifsdUnlockFcb(NULL, pFCB); xixfs_FreeCCB( pCCB ); } DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB), ("XifsdCommonClose GenINFO Fcb LotNumber(%I64d) TypeOfOpen (%ld) Fcb %d/%d Vcb %d/%d \n", pFCB->XixcoreFcb.LotNumber, TypeOfOpen, pFCB->FCBReference, pFCB->FCBUserReference, pVCB->VCBReference, pVCB->VCBUserReference)); /* if(CanWait){ if(TypeOfOpen == UserFileOpen){ if(pFCB->FCBCleanup == 0){ if(pFCB->SectionObject.DataSectionObject != NULL) { CcFlushCache(&(pFCB->SectionObject), NULL, 0, NULL); CcPurgeCacheSection( &(pFCB->SectionObject), NULL, 0, FALSE ); } if(XIXCORE_TEST_FLAGS(pFCB->FCBFlags,XIXCORE_FCB_MODIFIED_FILE)){ xixfs_LastUpdateFileFromFCB(pFCB); } } } } */ if((pVCB->VCBState == XIFSD_VCB_STATE_VOLUME_MOUNTED) && ((TypeOfOpen == UserFileOpen) || (TypeOfOpen == UserDirectoryOpen)) && (pFCB != pVCB->RootDirFCB)) { DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_FCB), ("XifsdCommonClose Destroy FCB (%x)\n", pFCB)); DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE|DEBUG_TARGET_REFCOUNT|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB), ("XifsdCommonClose, Fcb %08x Vcb %d/%d Fcb %d/%d\n", pFCB, pVCB->VCBReference, pVCB->VCBUserReference, pFCB->FCBReference, pFCB->FCBUserReference )); xixfs_TryClose(CanWait, bUserReference, pFCB); RC = STATUS_SUCCESS; try_return(RC); } else { if( ((pVCB->VCBCleanup == 0) || ForceDismount) && (pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_MOUNTED)) { if(ForceDismount) { FsRtlNotifyVolumeEvent(pFileObject, FSRTL_VOLUME_DISMOUNT); } if( ((pVCB->VCBCleanup == 0) || ForceDismount) && (pVCB->VCBState != XIFSD_VCB_STATE_VOLUME_MOUNTED)) { PotentialVCBUnmount = TRUE; if(bVcbAcq)XifsdReleaseVcb(TRUE,pVCB); XifsdAcquireGData(pIrpContext); DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_RESOURCE), ("XifsdCommonClose Acquire exclusive GData(%p)\n", &XiGlobalData.DataResource)); bVcbAcq = XifsdAcquireVcbExclusive(TRUE,pVCB, FALSE); DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_VCB|DEBUG_TARGET_RESOURCE), ("XifsdCommonClose Acquire exclusive VCBResource(%p)\n", pVCB->VCBResource)); } } if(PotentialVCBUnmount && bVcbAcq) { if(!xixfs_CheckForDismount(pIrpContext, pVCB, TRUE)) { bVcbAcq = FALSE; RC = STATUS_SUCCESS; try_return(RC); } } RC = xixfs_TryClose(CanWait, bUserReference, pFCB); if(NT_SUCCESS(RC)) { if(PotentialVCBUnmount && bVcbAcq) { if(!xixfs_CheckForDismount(pIrpContext, pVCB, FALSE)) { bVcbAcq = FALSE; RC = STATUS_SUCCESS; try_return(RC); } } } RC = STATUS_SUCCESS; } ; } finally{ if(bVcbAcq) { XifsdReleaseVcb(TRUE, pVCB); } if(PotentialVCBUnmount) { XifsdReleaseGData(pIrpContext); PotentialVCBUnmount = FALSE; } } xixfs_CompleteRequest(pIrpContext, RC, 0); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_CLOSE| DEBUG_TARGET_IRPCONTEXT), ("Exit xixfs_CommonClose \n")); return RC; }
NTSTATUS xixfs_PurgeVolume( IN PXIXFS_IRPCONTEXT IrpContext, IN PXIXFS_VCB pVCB, IN BOOLEAN DismountForce ) { NTSTATUS Status = STATUS_SUCCESS; PVOID RestartKey = NULL; PXIXFS_FCB ThisFcb = NULL; PXIXFS_FCB NextFcb = NULL; BOOLEAN RemovedFcb = FALSE; BOOLEAN CanWait = FALSE; uint32 lockedVcbValue = 0; PAGED_CODE(); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Enter xixfs_PurgeVolume\n")); ASSERT_EXCLUSIVE_VCB(pVCB); CanWait = XIXCORE_TEST_FLAGS(IrpContext->IrpContextFlags, XIFSD_IRP_CONTEXT_WAIT); // // Force any remaining Fcb's in the delayed close queue to be closed. // xixfs_RealCloseFCB(pVCB); // // Acquire the global file resource. // //XifsdAcquireAllFiles( CanWait, pVCB ); // // Loop through each Fcb in the Fcb Table and perform the flush. // while (TRUE) { // // Lock the Vcb to lookup the next Fcb. // XifsdLockVcb( IrpContext, pVCB ); NextFcb = xixfs_FCBTLBGetNextEntry(pVCB, &RestartKey ); // // Reference the NextFcb if present. // if (NextFcb != NULL) { NextFcb->FCBReference += 1; } // // If the last Fcb is present then decrement reference count and call teardown // to see if it should be removed. // if (ThisFcb != NULL) { ThisFcb->FCBReference -= 1; XifsdUnlockVcb( IrpContext, pVCB ); DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_PNP|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO|DEBUG_TARGET_REFCOUNT), ("XifsdPurgeVolume FCB(%I64d) VCB %d/%d FCB %d/%d\n", ThisFcb->XixcoreFcb.LotNumber, pVCB->VCBReference, pVCB->VCBUserReference, ThisFcb->FCBReference, ThisFcb->FCBUserReference )); DebugTrace(DEBUG_LEVEL_CRITICAL, DEBUG_TARGET_PNP|DEBUG_TARGET_FCB|DEBUG_TARGET_VCB|DEBUG_TARGET_REFCOUNT, ("XifsdPurgeVolume FCBLotNumber(%I64d) FCBCleanUp(%ld) VCBCleanup(%ld)\n", ThisFcb->XixcoreFcb.LotNumber, ThisFcb->FCBCleanup, pVCB->VCBCleanup)); xixfs_TeardownStructures( CanWait, ThisFcb, FALSE, &RemovedFcb ); } else { XifsdUnlockVcb( IrpContext, pVCB ); } // // Break out of the loop if no more Fcb's. // if (NextFcb == NULL) { break; } // // Move to the next Fcb. // ThisFcb = NextFcb; // // If there is a image section then see if that can be closed. // if(ThisFcb->XixcoreFcb.FCBType == FCB_TYPE_FILE){ DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("XifsdPurgeVolume FCB(%I64d) \n", ThisFcb->XixcoreFcb.LotNumber)); XifsdAcquireFcbExclusive(TRUE, ThisFcb, FALSE); // Added by ILGU HONG for readonly 09052006 if(!ThisFcb->PtrVCB->XixcoreVcb.IsVolumeWriteProtected){ if (ThisFcb->SectionObject.ImageSectionObject != NULL) { MmFlushImageSection( &ThisFcb->SectionObject, MmFlushForWrite ); } // // If there is a data section then purge this. If there is an image // section then we won't be able to. Remember this if it is our first // error. // CcFlushCache(&ThisFcb->SectionObject, NULL, 0, NULL); //DbgPrint("CcFlush 3 File(%wZ)\n", &ThisFcb->FCBFullPath); } // Added by ILGU HONG for readonly end ExAcquireResourceSharedLite(ThisFcb->PagingIoResource, TRUE); ExReleaseResourceLite( ThisFcb->PagingIoResource ); if ((ThisFcb->SectionObject.DataSectionObject != NULL) && !CcPurgeCacheSection( &ThisFcb->SectionObject, NULL, 0, FALSE ) && (Status == STATUS_SUCCESS)) { Status = STATUS_UNABLE_TO_DELETE_SECTION; } XifsdReleaseFcb(TRUE, ThisFcb); } // // Dereference the internal stream if dismounting. // if (DismountForce && (ThisFcb->XixcoreFcb.FCBType != FCB_TYPE_FILE) && (ThisFcb->XixcoreFcb.FCBType != FCB_TYPE_DIR) && (ThisFcb->FileObject != NULL)) { xixfs_DeleteInternalStream( CanWait, ThisFcb ); } } // // Now look at the Root Index, Metadata, Volume Dasd and VAT Fcbs. // Note that we usually hit the Root Index in the loop above, but // it is possible miss it if it didn't get into the Fcb table in the // first place! // DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("xixfs_PurgeVolume DismountFore (%s)\n", ((DismountForce)?"TRUE":"FALSE"))); if (DismountForce) { if (pVCB->RootDirFCB != NULL) { DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Deal with RootFCB \n")); ThisFcb = pVCB->RootDirFCB; InterlockedIncrement( &ThisFcb->FCBReference ); if ((ThisFcb->SectionObject.DataSectionObject != NULL) && !CcPurgeCacheSection( &ThisFcb->SectionObject, NULL, 0, FALSE ) && (Status == STATUS_SUCCESS)) { Status = STATUS_UNABLE_TO_DELETE_SECTION; } InterlockedDecrement( &ThisFcb->FCBReference ); /* DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("pVCB->RootDirFCB FCB(%I64d) VCB %d/%d FCB %d/%d\n", ThisFcb->LotNumber, pVCB->VCBReference, pVCB->VCBUserReference, ThisFcb->FCBReference, ThisFcb->FCBUserReference )); XifsdLockVcb(IrpContext, pVCB); XifsdDecRefCount(ThisFcb, 1, 1); XifsdUnlockVcb(IrpContext, pVCB); */ DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("pVCB->RootDirFCB FCB(%I64d) VCB %d/%d FCB %d/%d\n", ThisFcb->XixcoreFcb.LotNumber, pVCB->VCBReference, pVCB->VCBUserReference, ThisFcb->FCBReference, ThisFcb->FCBUserReference )); xixfs_TeardownStructures( CanWait, ThisFcb, FALSE, &RemovedFcb ); } if (pVCB->MetaFCB != NULL) { DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Deal with pVCB->MetaFCB \n")); ThisFcb = pVCB->MetaFCB; InterlockedIncrement( &ThisFcb->FCBReference ); if ((ThisFcb->SectionObject.DataSectionObject != NULL) && !CcPurgeCacheSection( &ThisFcb->SectionObject, NULL, 0, FALSE ) && (Status == STATUS_SUCCESS)) { Status = STATUS_UNABLE_TO_DELETE_SECTION; } xixfs_DeleteInternalStream( CanWait, ThisFcb ); InterlockedDecrement( &ThisFcb->FCBReference ); /* DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("pVCB->MetaFCB FCB(%I64d) VCB %d/%d FCB %d/%d\n", ThisFcb->LotNumber, pVCB->VCBReference, pVCB->VCBUserReference, ThisFcb->FCBReference, ThisFcb->FCBUserReference )); XifsdLockVcb(IrpContext, pVCB); XifsdDecRefCount(ThisFcb, 1, 1); XifsdUnlockVcb(IrpContext, pVCB); */ DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("pVCB->MetaFCB FCB(%I64d) VCB %d/%d FCB %d/%d\n", ThisFcb->XixcoreFcb.LotNumber, pVCB->VCBReference, pVCB->VCBUserReference, ThisFcb->FCBReference, ThisFcb->FCBUserReference )); xixfs_TeardownStructures( CanWait, ThisFcb, FALSE, &RemovedFcb ); } if (pVCB->VolumeDasdFCB != NULL) { DebugTrace(DEBUG_LEVEL_INFO, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Deal with pVCB->VolumeDasdFCB \n")); ThisFcb = pVCB->VolumeDasdFCB; InterlockedIncrement( &ThisFcb->FCBReference ); if ((ThisFcb->SectionObject.DataSectionObject != NULL) && !CcPurgeCacheSection( &ThisFcb->SectionObject, NULL, 0, FALSE ) && (Status == STATUS_SUCCESS)) { Status = STATUS_UNABLE_TO_DELETE_SECTION; } xixfs_DeleteInternalStream( CanWait, ThisFcb ); InterlockedDecrement( &ThisFcb->FCBReference ); /* DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("pVCB->VolumeDasdFCB FCB(%I64d) VCB %d/%d FCB %d/%d\n", ThisFcb->LotNumber, pVCB->VCBReference, pVCB->VCBUserReference, ThisFcb->FCBReference, ThisFcb->FCBUserReference )); XifsdLockVcb(IrpContext, pVCB); XifsdDecRefCount(ThisFcb, 1, 1); XifsdUnlockVcb(IrpContext, pVCB); */ DebugTrace(DEBUG_LEVEL_CRITICAL, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("pVCB->VolumeDasdFCB FCB(%I64d) VCB %d/%d FCB %d/%d\n", ThisFcb->XixcoreFcb.LotNumber, pVCB->VCBReference, pVCB->VCBUserReference, ThisFcb->FCBReference, ThisFcb->FCBUserReference )); xixfs_TeardownStructures( CanWait, ThisFcb, FALSE, &RemovedFcb ); } } // // Release all of the files. // //XifsdReleaseAllFiles( CanWait, pVCB ); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_DIRINFO|DEBUG_TARGET_FCB|DEBUG_TARGET_FILEINFO), ("Exit xixfs_PurgeVolume\n")); return Status; }
int xixfs_ResourceThreadFunction( void *lpParameter ) { PXIXFS_LINUX_VCB pVCB = NULL; PXIXFS_LINUX_META_CTX pCtx = NULL; PXIXCORE_META_CTX xixcoreCtx = NULL; int RC =0; #if LINUX_VERSION_25_ABOVE int TimeOut; #endif unsigned long flags; DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO ), ("Enter xixfs_ResourceThreadFunction .\n")); #if defined(NDAS_ORG2423) || defined(NDAS_SIGPENDING_OLD) spin_lock_irqsave(¤t->sigmask_lock, flags); siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGTERM)); recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); #else spin_lock_irqsave(¤t->sighand->siglock, flags); siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGTERM)); recalc_sigpending(); spin_unlock_irqrestore(¤t->sighand->siglock, flags); #endif #if LINUX_VERSION_25_ABOVE daemonize("XixMetaThread"); #else daemonize(); #endif pCtx = (PXIXFS_LINUX_META_CTX)lpParameter; XIXCORE_ASSERT(pCtx); pVCB = pCtx->VCBCtx; XIXFS_ASSERT_VCB(pVCB); xixcoreCtx = &pVCB->XixcoreVcb.MetaContext; while(1){ if(signal_pending(current)) { flush_signals(current); } #if LINUX_VERSION_25_ABOVE TimeOut = DEFAULT_XIXFS_UPDATEWAIT; RC = wait_event_timeout(pCtx->VCBMetaEvent, XIXCORE_TEST_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_MASK), TimeOut); #else mod_timer(&(pCtx->VCBMetaTimeOut), jiffies+ 180*HZ); wait_event(pCtx->VCBMetaEvent, XIXCORE_TEST_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_MASK)); #endif DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO ), ("!!!!! Wake up HELLOE ResourceThreadFunction .\n")); //printk(KERN_DEBUG "!!!!! Wake UP HELLOE ResourceThreadFunction .\n"); spin_lock(&(pCtx->MetaLock)); //DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CHECK, // ("spin_lock(&(pCtx->MetaLock)) pCtx(%p)\n", pCtx )); #if LINUX_VERSION_25_ABOVE if(RC == 0 ) { #else if(XIXCORE_TEST_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_TIMEOUT)) { XIXCORE_CLEAR_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_TIMEOUT); #endif DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO |DEBUG_TARGET_ALL), ("Request Call timeout : xixfs_ResourceThreadFunction .\n")); spin_unlock(&(pCtx->MetaLock)); //DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CHECK, // ("spin_unlock(&(pCtx->MetaLock)) pCtx(%p)\n", pCtx )); if(XIXCORE_TEST_FLAGS(xixcoreCtx->ResourceFlag, XIXCORE_META_RESOURCE_NEED_UPDATE)){ XIXCORE_CLEAR_FLAGS(xixcoreCtx->ResourceFlag, XIXCORE_META_RESOURCE_NEED_UPDATE); RC = xixfs_UpdateMetaData(pCtx); if( RC <0 ) { DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO |DEBUG_TARGET_ALL), ("fail(0x%x) xixfs_ResourceThreadFunction --> xixfs_UpdateMetaData .\n", RC)); } } #if LINUX_VERSION_25_ABOVE continue; }else if(XIXCORE_TEST_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_UPDATE)) { #else } if(XIXCORE_TEST_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_UPDATE)) { #endif XIXCORE_CLEAR_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_UPDATE); spin_unlock(&(pCtx->MetaLock)); //DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CHECK, // ("spin_unlock(&(pCtx->MetaLock)) pCtx(%p)\n", pCtx )); if(XIXCORE_TEST_FLAGS(xixcoreCtx->ResourceFlag, XIXCORE_META_RESOURCE_NEED_UPDATE)){ XIXCORE_CLEAR_FLAGS(xixcoreCtx->ResourceFlag, XIXCORE_META_RESOURCE_NEED_UPDATE); RC = xixfs_UpdateMetaData(pCtx); if( RC <0 ) { DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO |DEBUG_TARGET_ALL), ("fail(0x%x) xixfs_ResourceThreadFunction --> xixfs_UpdateMetaData .\n", RC)); } } xixfs_wakeup_resource_waiter(pCtx); continue; }else if(XIXCORE_TEST_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_KILL_THREAD)) { XIXCORE_CLEAR_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_RECHECK_RESOURCES); XIXCORE_SET_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_INSUFFICIENT_RESOURCES); spin_unlock(&(pCtx->MetaLock)); //DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CHECK, // ("spin_unlock(&(pCtx->MetaLock)) pCtx(%p)\n", pCtx )); DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO |DEBUG_TARGET_ALL), ("Stop Thread : xixfs_ResourceThreadFunction .\n")); xixfs_wakeup_resource_waiter(pCtx); #if LINUX_VERSION_25_ABOVE complete_all(&(pCtx->VCBMetaThreadStopCompletion)); #else del_timer(&(pCtx->VCBMetaTimeOut)); xixfs_wakeup_metaThread_stop_waiter(pCtx); #endif break; }else if( XIXCORE_TEST_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_RECHECK_RESOURCES)){ spin_unlock(&(pCtx->MetaLock)); //DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CHECK, // ("spin_unlock(&(pCtx->MetaLock)) pCtx(%p)\n", pCtx )); DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO |DEBUG_TARGET_ALL), ("get more resource : xixfs_ResourceThreadFunction .\n")); RC = xixfs_GetMoreCheckOutLotMap(pCtx); DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO |DEBUG_TARGET_ALL), ("End xixfs_GetMoreCheckOutLotMap .\n")); if( RC <0 ) { DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO |DEBUG_TARGET_ALL), ("fail(0x%x) xixfs_ResourceThreadFunction --> xixfs_GetMoreCheckOutLotMap .\n", RC)); }else { spin_lock(&(pCtx->MetaLock)); //DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CHECK, // ("spin_lock(&(pCtx->MetaLock)) pCtx(%p)\n", pCtx )); XIXCORE_CLEAR_FLAGS(xixcoreCtx->VCBMetaFlags, XIXCORE_META_FLAGS_RECHECK_RESOURCES); spin_unlock(&(pCtx->MetaLock)); //DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CHECK, // ("spin_unlock(&(pCtx->MetaLock)) pCtx(%p)\n", pCtx )); DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO |DEBUG_TARGET_ALL), ("WAKE UP WAITING THREAD!! .\n")); xixfs_wakeup_resource_waiter(pCtx); } continue; }else { DebugTrace(DEBUG_LEVEL_ALL, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO |DEBUG_TARGET_ALL), ("Request Call Unrecognized : xixfs_ResourceThreadFunction .\n")); spin_unlock(&(pCtx->MetaLock)); //DebugTrace(DEBUG_LEVEL_TRACE, DEBUG_TARGET_CHECK, // ("spin_unlock(&(pCtx->MetaLock)) pCtx(%p)\n", pCtx )); } } DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_FSCTL|DEBUG_TARGET_VOLINFO ), ("Exit xixfs_ResourceThreadFunction .\n")); return 0; }
ssize_t xixfs_file_write( struct file *file, const char __user *buf, size_t count, loff_t *ppos ) { ssize_t RC = 0; int64 index = 0; #if LINUX_VERSION_25_ABOVE struct address_space *mapping = file->f_mapping; #else struct address_space *mapping = file->f_dentry->d_inode->i_mapping; #endif struct inode *inode = mapping->host; PXIXFS_LINUX_FCB pFCB = NULL; PXIXFS_LINUX_VCB pVCB = NULL; XIXCORE_ASSERT(inode); pVCB = XIXFS_SB(inode->i_sb); XIXFS_ASSERT_VCB(pVCB); pFCB = XIXFS_I(inode); XIXFS_ASSERT_FCB(pFCB); DebugTrace(DEBUG_LEVEL_TRACE, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("ENTER xixfs_file_write (%s).\n", file->f_dentry->d_name.name)); if(pVCB->XixcoreVcb.IsVolumeWriteProtected){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR xixfs_file_write : is read only .\n")); return -EPERM; } XIXCORE_ASSERT(pFCB->XixcoreFcb.FCBType == FCB_TYPE_FILE); if(XIXCORE_TEST_FLAGS( pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_CHANGE_DELETED )){ DebugTrace(DEBUG_LEVEL_ERROR, DEBUG_TARGET_ALL, ("ERROR DELETED FILE \n")); return -EPERM; } if( pFCB->XixcoreFcb.HasLock == INODE_FILE_LOCK_HAS) { index =(int64) (*ppos); #if LINUX_VERSION_2_6_19_REPLACE_INTERFACE RC = do_sync_write(file, buf, count, ppos); #else RC = generic_file_write(file, buf, count, ppos); #endif if(RC > 0) { if(pFCB->XixcoreFcb.WriteStartOffset == -1) { pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } if(pFCB->XixcoreFcb.WriteStartOffset > index ){ pFCB->XixcoreFcb.WriteStartOffset = index; XIXCORE_SET_FLAGS(pFCB->XixcoreFcb.FCBFlags, XIXCORE_FCB_MODIFIED_FILE_SIZE); } } return RC; } else { return -EPERM; } DebugTrace(DEBUG_LEVEL_ERROR, (DEBUG_TARGET_FCB|DEBUG_TARGET_VFSAPIT), ("EXIT xixfs_file_write .\n")); return RC; }