Resource manager query

Hi,

Am trying to implement a resource manager for my own filesystem and looking at how to hook my own ftruncate or truncate to resource manager? For open, read, write etc. I see resource manager hooks(iofunc_t etc.) but for ftruncate() I do not see a vector to register my own function.

Please help.

-G

Hello,
Please use

io_funcs.space = io_space;

Check the example below, this will process ftruncate().
Regards,
Yuriy

#include <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>

int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb);
int io_write (resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb);
int io_space (resmgr_context_t *ctp, io_space_t *msg, iofunc_ocb_t ocb/, int *nonblock */);

static char mock_device[ BUFSIZ];

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

int global_integer = 0;
int main(int argc, char *argv)
{
/
declare variables we’ll be using */
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
dispatch_context_t *ctp;
int id;

memcpy ( mock_device, "Hello world\n", sizeof ("Hello world\n"));

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL) {
    fprintf(stderr, "%s: Unable to allocate dispatch handle.\n",
            argv[0]);
    return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
                 _RESMGR_IO_NFUNCS, &io_funcs);
io_funcs.read = io_read;
io_funcs.write = io_write;                                                     
io_funcs.space = io_space;                                                     

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
attr.nbytes = strlen(mock_device)+1;

/* attach our device name */
if((id = resmgr_attach(dpp, &resmgr_attr, "/dev/sample", _FTYPE_ANY, 0,
             &connect_funcs, &io_funcs, &attr)) == -1) {
    fprintf(stderr, "%s: Unable to attach name.\n", argv[0]);
    return EXIT_FAILURE;
}

/* allocate a context structure */
ctp = dispatch_context_alloc(dpp);

/* start the resource manager message loop */
while(1) 
{
    if((ctp = dispatch_block(ctp)) == NULL) 
    {
        fprintf(stderr, "block error\n");
        return EXIT_FAILURE;
    }
    fprintf (stderr, ".");
    dispatch_handler(ctp);
}

}

int
io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb)
{
int nleft;
int nbytes;
int nparts;
int status;

if ((status = iofunc_read_verify (ctp, msg, ocb, NULL)) != EOK)
    return (status);
    
if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE)
    return (ENOSYS);
   fprintf (stderr, "io_read hex %0x dec %d\n", msg->i.type, msg->i.type);

/*
 *  On all reads (first and subsequent), calculate
 *  how many bytes we can return to the client,
 *  based upon the number of bytes available (nleft)
 *  and the client's mock_device size
 */

// attr.nbytes = strlen(mock_device)+1;

nleft = ocb->attr->nbytes - ocb->offset;
nbytes = min (msg->i.nbytes, nleft);

if (nbytes > 0) {
    /* set up the return data IOV */
    SETIOV (ctp->iov, mock_device + ocb->offset, nbytes);

    /* set up the number of bytes (returned by client's read()) */
    _IO_SET_READ_NBYTES (ctp, nbytes);

    /*
     * advance the offset by the number of bytes
     * returned to the client.
     */

    ocb->offset += nbytes;
    
    nparts = 1;
} else {
    /*
     * they've asked for zero bytes or they've already previously
     * read everything
     */
    
    _IO_SET_READ_NBYTES (ctp, 0);
    
    nparts = 0;
}

/* mark the access time as invalid (we just accessed it) */

if (msg->i.nbytes > 0)
    ocb->attr->flags |= IOFUNC_ATTR_ATIME;

return (_RESMGR_NPARTS (nparts));

}

int
io_write (resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb)
{
int status;
char *buf;

if ((status = iofunc_write_verify(ctp, msg, ocb, NULL)) != EOK)
    return (status);

if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE)
    return(ENOSYS);

   fprintf (stderr, "io_write hex %0x dec %d\n", msg->i.type, msg->i.type);

/* set up the number of bytes (returned by client's write()) */

_IO_SET_WRITE_NBYTES (ctp, msg->i.nbytes);

buf = (char *) malloc(msg->i.nbytes + 1);
if (buf == NULL)
{
    return(ENOMEM);
}

if ( msg->i.nbytes >   BUFSIZ )
{
   return(ENOMEM);
	
}        

/*
 *  Reread the data from the sender's message buffer.
 *  We're not assuming that all of the data fit into the
 *  resource manager library's receive mock_device.
 */

if ( msg->i.nbytes >   BUFSIZ )
{
   return(ENOMEM);
	
}
resmgr_msgread(ctp, buf, msg->i.nbytes, sizeof(msg->i));
buf [msg->i.nbytes] = '\0'; /* just in case the text is not NULL terminated */

// printf (“Received %d bytes = ‘%s’\n”, msg → i.nbytes, buf);
memcpy ( mock_device, buf, msg → i.nbytes);

attr.nbytes = msg -> i.nbytes;
ocb->offset = 0;

free(buf);

if (msg->i.nbytes > 0)
    ocb->attr->flags |= IOFUNC_ATTR_MTIME | IOFUNC_ATTR_CTIME;

return (_RESMGR_NPARTS (0));

}

int io_space (resmgr_context_t *ctp, io_space_t *msg, iofunc_ocb_t ocb /, int *nonblock */)
{

fprintf (stderr, "io_space type=%d combine_len=%d subtype=%d whence=%d start=%d len=%d \n",     
    (int)msg->i.type, 
	(int)msg->i.combine_len,
	(int)msg->i.subtype,
	(int)msg->i.whence,
	(int)msg->i.start,
	(int)msg->i.len 	) ;  
return  iofunc_space_verify( ctp,  msg, ocb, NULL ); 

}