/*******************************************************************************
 **
 **_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 ;
}
Example #2
0
void
Transaction::KeepNode(Node* node)
{
	ASSERT(fID >= 0);

	NodeInfo* info = _GetNodeInfo(node);
	if (info == NULL)
		return;

	info->flags &= ~(uint32)TRANSACTION_DELETE_NODE;
}
Example #3
0
void
Transaction::UpdateNodeFlags(Node* node, uint32 flags)
{
	ASSERT(fID >= 0);

	NodeInfo* info = _GetNodeInfo(node);
	if (info == NULL)
		return;

	info->flags = flags;
}
Example #4
0
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;
}
Example #5
0
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 ;
}