| 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 ---
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> |
|---|---|---|
| ||
| Previous by Date: | PARTIAL TAKE 907982 - plug memory leak in libxfs, Eric Sandeen |
|---|---|
| Next by Date: | TAKE 907752 - xfsprogs, Nathan Scott |
| Previous by Thread: | PARTIAL TAKE 907982 - plug memory leak in libxfs, Eric Sandeen |
| Next by Thread: | TAKE 907752 - xfsprogs, Nathan Scott |
| Indexes: | [Date] [Thread] [Top] [All Lists] |