xfs
[Top] [All Lists]

dm_write_invis() blocking problem

To: linux-xfs@xxxxxxxxxxx
Subject: dm_write_invis() blocking problem
From: Mike Montour <mmontour@xxxxxxxxxx>
Date: Mon, 19 Jan 2004 18:22:28 -0800
Sender: linux-xfs-bounce@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031007
Hello,

I am developing an application using XFS/DMAPI on Linux 2.4.

My application registers for DM_EVENT_READ and DM_EVENT_WRITE events
on a file, then calls dm_punch_hole() on that file. The event handlers
use dm_write_invis() to re-populate the file data on demand (including
re-populating all of the original file data before allowing the
first write operation to continue).

This works fine for READ events. However, whenever I get a WRITE
event, the call to dm_write_invis() blocks my program. If I kill
(ctrl-C) the application that triggered the WRITE event, then the
dm_write_invis() call returns successfully and my program continues.

I have attached a test program that illustrates this behaviour.
The XFS filesystem is mounted on /mnt and I use a file "/mnt/TESTFILE".
Reading from the file works:

---
mmontour:/home/mmontour# dd if=/mnt/TESTFILE bs=100 count=1
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB1+0records in
1+0 records out
---


and my DMAPI program produces the following output:
---
mmontour:/home/mmontour# ./a.out
SGI DMAPI (XDSM) API, Release 1.0.
Waiting for event...
Got DM_EVENT_READ, de_offset 0, de_length 100
Requesting DM_RIGHT_EXCL
Calling dm_write_invis()
dm_write_invis() returns 100
Sending DM_RESP_CONTINUE
Done
---


However, when I try to write: --- mmontour:/home/mmontour# dd if=/dev/zero of=/mnt/TESTFILE bs=100 count=1 ---

my DMAPI program hangs after:
---
mmontour:/home/mmontour# ./a.out
SGI DMAPI (XDSM) API, Release 1.0.
Waiting for event...
Got DM_EVENT_WRITE, de_offset 0, de_length 100
Requesting DM_RIGHT_EXCL
Calling dm_write_invis()
---

--------------------------------
Kernel is 2.4.24-pre1 plus the xfs-2.4.24-pre1-all-i386.bz2 patch.

From dmesg:
SGI XFS snapshot 2.4.24-pre1-2003-12-11_23:47_UTC with ACLs, no debug enabled


XFS config options are:
CONFIG_XFS_FS=y
# CONFIG_XFS_QUOTA is not set
CONFIG_XFS_POSIX_ACL=y
# CONFIG_XFS_RT is not set
CONFIG_XFS_DMAPI=y
# CONFIG_XFS_TRACE is not set
# CONFIG_XFS_DEBUG is not set

Additional information is available on request. Am I doing something
wrong in my program, is this a known limitation of Linux/XFS/DMAPI,
or is this a bug?

        -Mike Montour <mmontour@xxxxxxxxxx>

--------------------------------

#include <stdio.h>
#include <assert.h>
#include <fcntl.h>
#include <errno.h>
#include <xfs/dmapi.h>

#define MTPT "/mnt"
#define TESTFILE "/mnt/TESTFILE"

int main(int argc, char *argv[])
{
        char *str = NULL;
        int rc = 0;
        int myfile;
        char *data = NULL;
        int nbytes;
        char buf[256];
        size_t bufBytes;
        dm_sessid_t     Session;
        dm_eventset_t    eSet;
        void *fsHandle;
        size_t fsHandle_len;
        void *fileHandle;
        size_t fileHandle_len;
        void *eventHandle;
        size_t eventHandle_len;
        dm_boolean_t exactflag;
        dm_region_t rFlags;
        dm_eventmsg_t   *eventMsg;
        dm_data_event_t *dataEvent;
        
        /* Setup */
        rc = dm_init_service(&str);
        assert(rc == 0);
        printf("%s\n", str);
        
        rc = dm_create_session(DM_NO_SESSION, "test", &Session);
        assert(rc == 0);
        
        rc = dm_path_to_fshandle(MTPT, &fsHandle, &fsHandle_len);
        assert(rc == 0);
        
        DMEV_ZERO(eSet);
        DMEV_SET(DM_EVENT_READ, eSet);
        DMEV_SET(DM_EVENT_WRITE, eSet);
        rc = dm_set_disp(Session, fsHandle, fsHandle_len, DM_NO_TOKEN, &eSet, 
DM_EVENT_MAX);
        assert(rc == 0);
        
        /* Create file (removing old one if present) */
        rc = unlink(TESTFILE);
        assert((rc == 0) || (errno == ENOENT));
        
        myfile = open(TESTFILE, O_WRONLY | O_CREAT, 0644);
        data = (char *)malloc(100);
        memset(data,'A',100);
        nbytes = write(myfile, data, 100);
        assert (nbytes == 100);
        close(myfile);
        free(data);
        
        /* Register for notification and punch hole */
        rc = dm_path_to_handle(TESTFILE, &fileHandle, &fileHandle_len);
        assert(rc == 0);
        
        rFlags.rg_offset = 0;
        rFlags.rg_size = 0;
        rFlags.rg_flags = DM_REGION_READ | DM_REGION_WRITE;
        rc = dm_set_region(Session, fileHandle, fileHandle_len, DM_NO_TOKEN, 1, 
&rFlags, &exactflag);
        assert(rc == 0);
        rc = dm_punch_hole(Session, fileHandle, fileHandle_len, DM_NO_TOKEN, 0, 
0);
        assert(rc == 0);
        
        /* Get event */
        printf("Waiting for event...\n");
        fflush(stdout);
        
        rc = dm_get_events(Session,1,DM_EV_WAIT,256,buf,&bufBytes);
        assert(rc == 0);

        eventMsg = (dm_eventmsg_t *)buf;
        switch(eventMsg->ev_type)
        {
                case DM_EVENT_READ:
                        printf("Got DM_EVENT_READ, ");
                        break;
                case DM_EVENT_WRITE:
                        printf("Got DM_EVENT_WRITE, ");
                        break;
                default:
                        assert(0);
        }
        
        dataEvent = DM_GET_VALUE(eventMsg, ev_data, dm_data_event_t *);
        printf("de_offset %lld, de_length %lld\n", dataEvent->de_offset, 
dataEvent->de_length);
        fflush(stdout);
        
        eventHandle = DM_GET_VALUE(dataEvent, de_handle, void *);
        eventHandle_len = DM_GET_LEN(dataEvent, de_handle);
        
        /* Put data into file */
        
        printf("Requesting DM_RIGHT_EXCL\n");
        fflush(stdout);
        rc = dm_request_right(Session, eventHandle, eventHandle_len, 
eventMsg->ev_token, DM_RR_WAIT, DM_RIGHT_EXCL);
        assert(rc == 0);
        
        data = (char *)malloc(100);
        memset(data,'B',100);
        
        printf("Calling dm_write_invis()\n");
        fflush(stdout);
        rc = dm_write_invis(Session, eventHandle, eventHandle_len, 
eventMsg->ev_token, 0, 0, 100, data);
        printf("dm_write_invis() returns %d\n", rc);
        fflush(stdout);
        
        rc = dm_release_right(Session, eventHandle, eventHandle_len, 
eventMsg->ev_token);
        assert(rc == 0);

        /* Respond to event*/
        printf("Sending DM_RESP_CONTINUE\n");
        fflush(stdout);
        rc = dm_respond_event(Session, eventMsg->ev_token, DM_RESP_CONTINUE, 0, 
0, NULL); 
        assert(rc == 0);
        
        /* Shutdown */
        
        dm_destroy_session(Session);
        printf("Done\n");
        fflush(stdout);
        return 0;
}
<Prev in Thread] Current Thread [Next in Thread>
  • dm_write_invis() blocking problem, Mike Montour <=