/******************************************************************************* ** **_DebugFSWrite ** *******************************************************************************/ static ssize_t _DebugFSWrite ( struct file *file , const char __user * buffer , size_t length , loff_t * offset ) { caddr_t message = NULL ; int n ; gcsDebugFileSystemNode*node ; /* get the metadata about this log */ if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL ) { return - EIO ; } if ( down_interruptible ( gcmkNODE_SEM ( node ) ) ) { return - ERESTARTSYS ; } /* if the message is longer than the buffer, just take the beginning * of it, in hopes that the reader (if any) will have time to read * before we wrap around and obliterate it */ n = gcmkMIN ( length , node->size - 1 ) ; /* make sure we have the memory for it */ if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL ) { up ( gcmkNODE_SEM ( node ) ) ; return - ENOMEM ; } /* copy into our temp buffer */ if ( copy_from_user ( message , buffer , n ) > 0 ) { up ( gcmkNODE_SEM ( node ) ) ; kfree ( message ) ; return - EFAULT ; } /* now copy it into the circular buffer and free our temp copy */ _WriteToNode ( node , message , n ) ; kfree ( message ) ; up ( gcmkNODE_SEM ( node ) ) ; /* wake up any readers that might be waiting for the data. we call * schedule in the vague hope that a reader will run before the * writer's next write, to avoid losing data. */ wake_up_interruptible ( gcmkNODE_READQ ( node ) ) ; return n ; }
void Transaction::KeepNode(Node* node) { ASSERT(fID >= 0); NodeInfo* info = _GetNodeInfo(node); if (info == NULL) return; info->flags &= ~(uint32)TRANSACTION_DELETE_NODE; }
void Transaction::UpdateNodeFlags(Node* node, uint32 flags) { ASSERT(fID >= 0); NodeInfo* info = _GetNodeInfo(node); if (info == NULL) return; info->flags = flags; }
bool Transaction::RemoveNode(Node* node) { ASSERT(fID >= 0); NodeInfo* info = _GetNodeInfo(node); if (info == NULL) return false; fNodeInfos.Remove(info); _DeleteNodeInfoAndUnlock(info, false); return true; }
status_t Transaction::AddNode(Node* node, uint32 flags) { ASSERT(fID >= 0); NodeInfo* info = _GetNodeInfo(node); if (info != NULL) return B_OK; info = new(std::nothrow) NodeInfo; if (info == NULL) return B_NO_MEMORY; if ((flags & TRANSACTION_NODE_ALREADY_LOCKED) == 0) node->WriteLock(); info->node = node; info->oldNodeData = node->NodeData(); info->flags = flags; fNodeInfos.Add(info); return B_OK; }
/******************************************************************************* ** ** _DebugFSRead ** *******************************************************************************/ static ssize_t _DebugFSRead ( struct file *file , char __user * buffer , size_t length , loff_t * offset ) { int retval ; caddr_t data_to_return ; gcsDebugFileSystemNode* node ; /* get the metadata about this emlog */ if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL ) { printk ( "debugfs_read: record not found\n" ) ; return - EIO ; } if ( down_interruptible ( gcmkNODE_SEM ( node ) ) ) { return - ERESTARTSYS ; } /* wait until there's data available (unless we do nonblocking reads) */ while ( *offset >= gcmkNODE_FIRST_EMPTY_BYTE ( node ) ) { up ( gcmkNODE_SEM ( node ) ) ; if ( file->f_flags & O_NONBLOCK ) { return - EAGAIN ; } if ( wait_event_interruptible ( ( *( gcmkNODE_READQ ( node ) ) ) , ( *offset < gcmkNODE_FIRST_EMPTY_BYTE ( node ) ) ) ) { return - ERESTARTSYS ; /* signal: tell the fs layer to handle it */ } /* otherwise loop, but first reacquire the lock */ if ( down_interruptible ( gcmkNODE_SEM ( node ) ) ) { return - ERESTARTSYS ; } } data_to_return = _ReadFromNode ( node , &length , offset ) ; if ( data_to_return == NULL ) { retval = 0 ; goto unlock ; } if ( copy_to_user ( buffer , data_to_return , length ) > 0 ) { retval = - EFAULT ; } else { retval = length ; } kfree ( data_to_return ) ; unlock: up ( gcmkNODE_SEM ( node ) ) ; wake_up_interruptible ( gcmkNODE_WRITEQ ( node ) ) ; return retval ; }