Exemple #1
0
struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args)
{
	struct fuse_chan *ch;
	int fd;

	/*
	 * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
	 * would ensue.
	 */
	do {
		fd = open("/dev/null", O_RDWR);
		if (fd > 2)
			close(fd);
	} while (fd >= 0 && fd <= 2);

	fd = fuse_kern_mount(mountpoint, args);
	if (fd == -1)
		return NULL;

	ch = fuse_chan_new(fd);
	if (!ch)
		fuse_kern_unmount(mountpoint, fd);

	return ch;
}
Exemple #2
0
struct fuse_chan *fuse_kern_chan_new(int fd)
{
	struct fuse_chan_ops op = {
		.receive = fuse_kern_chan_receive,
		.send = fuse_kern_chan_send,
		.destroy = fuse_kern_chan_destroy,
	};
	size_t bufsize = getpagesize() + 0x1000;
	bufsize = bufsize < MIN_BUFSIZE ? MIN_BUFSIZE : bufsize;
	return fuse_chan_new(&op, fd, bufsize, NULL);
}
Exemple #3
0
int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
{
    int res;
    struct procdata pd;
    struct fuse_session *prevse = fuse_get_session(f);
    struct fuse_session *se;
    struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
    struct fuse_chan *ch;
    struct fuse_session_ops sop = {
        .exit = mt_session_exit,
        .exited = mt_session_exited,
        .process = mt_session_proc,
    };
    struct fuse_chan_ops cop = {
        .receive = mt_chan_receive,
        .send = mt_chan_send,
    };

    pd.f = f;
    pd.prevch = prevch;
    pd.prevse = prevse;
    pd.proc = proc;
    pd.data = data;

    se = fuse_session_new(&sop, &pd);
    if (se == NULL)
        return -1;

    ch = fuse_chan_new(&cop, fuse_chan_fd(prevch), sizeof(struct fuse_cmd *),
                       &pd);
    if (ch == NULL) {
        fuse_session_destroy(se);
        return -1;
    }
    fuse_session_add_chan(se, ch);
    res = fuse_session_loop_mt(se);
    fuse_session_destroy(se);
    return res;
}
Exemple #4
0
/**
*  Init of the pseudo fuse thread 

  @param ch : initial channel
  @param se : initial session
  @param rozofs_fuse_buffer_count : number of request buffers (corresponds to the number of fuse save context)  
  
  @retval 0 on success
  @retval -1 on error
*/
int rozofs_fuse_init(struct fuse_chan *ch,struct fuse_session *se,int rozofs_fuse_buffer_count)
{
  int status = 0;
  
//   return 0;
   
  int fileflags;
  rozofs_fuse_ctx_p = malloc(sizeof (rozofs_fuse_ctx_t));
  if (rozofs_fuse_ctx_p == NULL) 
  {
    /*
    ** cannot allocate memory for fuse rozofs context
    */
    return -1;
  }
  /*
  ** clear read/write merge stats table
  */
  memset(rozofs_write_merge_stats_tab,0,sizeof(uint64_t)*RZ_FUSE_WRITE_MAX);
  memset (rozofs_write_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX);
  memset (rozofs_read_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX);
  memset(&rozofs_fuse_read_write_stats_buf,0,sizeof(rozofs_fuse_read_write_stats));
  /*
  ** init of the context
  */
  rozofs_fuse_ctx_p->fuseReqPoolRef = NULL;
  rozofs_fuse_ctx_p->ch             = NULL;
  rozofs_fuse_ctx_p->se             = se;
  rozofs_fuse_ctx_p->bufsize        = 0; 
  rozofs_fuse_ctx_p->buf_fuse_req_p = NULL;
  rozofs_fuse_ctx_p->initBufCount   = rozofs_fuse_buffer_count;
  
  while (1)
  {
     /*
     ** get the receive buffer size for former channel in order to create the request distributor
     */
     int bufsize = fuse_chan_bufsize(ch);
     rozofs_fuse_ctx_p->bufsize = bufsize;
     /*
     ** create the pool
     */
     rozofs_fuse_ctx_p->fuseReqPoolRef = ruc_buf_poolCreate(rozofs_fuse_buffer_count,sizeof(rozofs_fuse_save_ctx_t));
     if (rozofs_fuse_ctx_p->fuseReqPoolRef == NULL)
     {
        ERRLOG "rozofs_fuse_init buffer pool creation error(%d,%d)", (int)rozofs_fuse_buffer_count, (int)sizeof(rozofs_fuse_save_ctx_t) ENDERRLOG ;
        status = -1;
        break;
     }
     /*
     ** allocate a buffer for receiving the fuse request
     */
     rozofs_fuse_ctx_p->buf_fuse_req_p = malloc(bufsize);
     if (rozofs_fuse_ctx_p == NULL) 
     {     
        ERRLOG "rozofs_fuse_init out of memory %d", bufsize ENDERRLOG ;
        status = -1;
        break;     
     }
     /*
     ** get the fd of the channel
     */
     rozofs_fuse_ctx_p->fd = fuse_chan_fd(ch);
     /*
     ** create a new channel with the specific operation for rozofs (non-blocking)
     */  
     rozofs_fuse_ctx_p->ch = fuse_chan_new(&rozofs_fuse_ch_ops,fuse_chan_fd(ch),fuse_chan_bufsize(ch),rozofs_fuse_ctx_p);  
     if (rozofs_fuse_ctx_p->ch == NULL)
     {
        ERRLOG "rozofs_fuse_init fuse_chan_new error"  ENDERRLOG ;
        status = -1;
        break;          
     }
     /*
     ** remove the association between the initial session and channel
     */
     fuse_session_remove_chan(ch);  
     /*
     ** OK, now add the new channel
     */
     fuse_session_add_chan(se,rozofs_fuse_ctx_p->ch );  
     /*
     ** set the channel in non blocking mode
     */
     if((fileflags=fcntl(rozofs_fuse_ctx_p->fd,F_GETFL,0))==-1)
     {
       RUC_WARNING(errno);
       status = -1; 
       break;   
     }

     if((fcntl(rozofs_fuse_ctx_p->fd,F_SETFL,fileflags|O_NDELAY))==-1)
     {
       RUC_WARNING(errno);
       status = -1; 
       break;   
     }
     /*
     ** perform the connection with the socket controller
     */
   /*
   ** OK, we are almost done, just need to connect with the socket controller
   */
   rozofs_fuse_ctx_p->connectionId = ruc_sockctl_connect(rozofs_fuse_ctx_p->fd,  // Reference of the socket
                                              "rozofs_fuse",                 // name of the socket
                                              3,                             // Priority within the socket controller
                                              (void*)rozofs_fuse_ctx_p,      // user param for socketcontroller callback
                                              &rozofs_fuse_callBack_sock);   // Default callbacks
    if (rozofs_fuse_ctx_p->connectionId == NULL)
    {
       /*
       ** Fail to connect with the socket controller
       */
       RUC_WARNING(-1);
       status = -1; 
       break;   
    } 

     status = 0;
     break;
  }
  
  uma_dbg_addTopic("fuse", rozofs_fuse_show);
  return status;
  
}
Exemple #5
0
/**
*  Init of the pseudo fuse thread 

  @param ch : initial channel
  @param se : initial session
  @param rozofs_fuse_buffer_count : number of request buffers (corresponds to the number of fuse save context)  
  
  @retval 0 on success
  @retval -1 on error
*/
int rozofs_fuse_init(struct fuse_chan *ch,struct fuse_session *se,int rozofs_fuse_buffer_count)
{
  int status = 0;
  int i;
  
//   return 0;

  fuse_sharemem_init_done = 0;   
  
  int fileflags;
  rozofs_fuse_ctx_p = malloc(sizeof (rozofs_fuse_ctx_t));
  if (rozofs_fuse_ctx_p == NULL) 
  {
    /*
    ** cannot allocate memory for fuse rozofs context
    */
    return -1;
  }
  memset(rozofs_fuse_ctx_p,0,sizeof (rozofs_fuse_ctx_t));
  /*
  ** clear read/write merge stats table
  */
  memset(rozofs_write_merge_stats_tab,0,sizeof(uint64_t)*RZ_FUSE_WRITE_MAX);
  memset (rozofs_write_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX);
  memset (rozofs_read_buf_section_table,0,sizeof(uint64_t)*ROZOFS_FUSE_NB_OF_BUSIZE_SECTION_MAX);
  memset(&rozofs_fuse_read_write_stats_buf,0,sizeof(rozofs_fuse_read_write_stats));
  /*
  ** init of the context
  */
  rozofs_fuse_ctx_p->fuseReqPoolRef = NULL;
  rozofs_fuse_ctx_p->ch             = NULL;
  rozofs_fuse_ctx_p->se             = se;
  rozofs_fuse_ctx_p->bufsize        = 0; 
  rozofs_fuse_ctx_p->buf_fuse_req_p = NULL;
  rozofs_fuse_ctx_p->dir_attr_invalidate = 0;
  rozofs_fuse_ctx_p->initBufCount   = rozofs_fuse_buffer_count;
  
  while (1)
  {
     /*
     ** get the receive buffer size for former channel in order to create the request distributor:
     ** note: by default the fuse buffer is 4K+128K: for RozoFS the payload can reach 512K (x4)
     */
     int bufsize = fuse_chan_bufsize(ch)*4;
     rozofs_fuse_ctx_p->bufsize = bufsize;
     /*
     ** create the distributor fro receiving data from fuse kernel
     */
     status = rozofs_fuse_init_rcv_buffer_pool(ROZOFS_FUSE_RECV_BUF_COUNT,bufsize);
     if (status < 0)
     {
        severe( "rozofs_fuse_init fuse buffer pool creation error(%d,%d)", (int)ROZOFS_FUSE_RECV_BUF_COUNT, (int)bufsize ) ;
        status = -1;
        break;     
     
     }
     /*
     ** create the pool
     */
     rozofs_fuse_ctx_p->fuseReqPoolRef = ruc_buf_poolCreate(rozofs_fuse_buffer_count,sizeof(rozofs_fuse_save_ctx_t));
     if (rozofs_fuse_ctx_p->fuseReqPoolRef == NULL)
     {
        severe( "rozofs_fuse_init buffer pool creation error(%d,%d)", (int)rozofs_fuse_buffer_count, (int)sizeof(rozofs_fuse_save_ctx_t) ) ;
        status = -1;
        break;
     }
     ruc_buffer_debug_register_pool("fuseCtx",  rozofs_fuse_ctx_p->fuseReqPoolRef);
     /*
     ** Allocate a head of list for queueing pending lookup requests
     */
     for (i=0; i< ROZOFS_MAX_LKUP_QUEUE ; i++)
     {
       ruc_listHdrInit(&rozofs_lookup_queue[i]);
     }
     
     
     /*
     ** allocate a buffer for receiving the fuse request
     */
     rozofs_fuse_ctx_p->buf_fuse_req_p = malloc(bufsize);
     if (rozofs_fuse_ctx_p == NULL) 
     {     
        severe( "rozofs_fuse_init out of memory %d", bufsize ) ;
        status = -1;
        break;     
     }
     /*
     ** get the fd of the channel
     */
     rozofs_fuse_ctx_p->fd = fuse_chan_fd(ch);
     /*
     ** wait the end of the share memroy init prior providing it to fuse
     */
     while (rozofs_shared_mem_init_done == 0) sleep(1);  
     /*
     ** create a new channel with the specific operation for rozofs (non-blocking)
     */  
     rozofs_fuse_ctx_p->ch = fuse_chan_new(&rozofs_fuse_ch_ops,fuse_chan_fd(ch),bufsize,rozofs_fuse_ctx_p);  
     if (rozofs_fuse_ctx_p->ch == NULL)
     {
        severe( "rozofs_fuse_init fuse_chan_new error"  ) ;
        status = -1;
        break;          
     }
     /*
     ** remove the association between the initial session and channel
     */
     fuse_session_remove_chan(ch);  
     /*
     ** OK, now add the new channel
     */
     fuse_session_add_chan(se,rozofs_fuse_ctx_p->ch );  
     /*
     ** set the channel in non blocking mode
     */
     if((fileflags=fcntl(rozofs_fuse_ctx_p->fd,F_GETFL,0))==-1)
     {
       RUC_WARNING(errno);
       status = -1; 
       break;   
     }

     if((fcntl(rozofs_fuse_ctx_p->fd,F_SETFL,fileflags|O_NDELAY))==-1)
     {
       RUC_WARNING(errno);
       status = -1; 
       break;   
     }
     /*
     ** send XON to the fuse channel
     */
     {
        int ret;
	rozofs_fuse_ctx_p->ioctl_supported = 1;
	rozofs_fuse_ctx_p->data_xon        = 1;
     
        while(1)
	{	
	  ret = ioctl(rozofs_fuse_ctx_p->fd,1,NULL);
	  if (ret < 0) 
	  {
	     warning("ioctl error %s",strerror(errno));
	     rozofs_fuse_ctx_p->ioctl_supported = 0;
	     break;

	  }
          if (rozofs_fuse_ctx_p->dir_attr_invalidate == 0)
	  {
	    ret = ioctl(rozofs_fuse_ctx_p->fd,3,NULL);
	    if (ret < 0) 
	    {
	       warning("ioctl error %s",strerror(errno));
//	       rozofs_fuse_ctx_p->ioctl_supported = 0;
	       rozofs_fuse_ctx_p->dir_attr_invalidate = 1;
	       break;
	    }		
	  }
	  break;     
        }
     }
     /*
     ** perform the connection with the socket controller
     */
   /*
   ** OK, we are almost done, just need to connect with the socket controller
   */
   rozofs_fuse_ctx_p->connectionId = ruc_sockctl_connect(rozofs_fuse_ctx_p->fd,  // Reference of the socket
                                              "rozofs_fuse",                 // name of the socket
                                              3,                             // Priority within the socket controller
                                              (void*)rozofs_fuse_ctx_p,      // user param for socketcontroller callback
                                              &rozofs_fuse_callBack_sock);   // Default callbacks
    if (rozofs_fuse_ctx_p->connectionId == NULL)
    {
       /*
       ** Fail to connect with the socket controller
       */
       RUC_WARNING(-1);
       status = -1; 
       break;   
    } 
    rozofs_fuse_get_ticker();

     status = 0;
     break;
  }
  /*
  ** attach the callback on socket controller
  */
//#warning no poller
  ruc_sockCtrl_attach_applicative_poller(rozofs_fuse_scheduler_entry_point); 
  for(i = 0; i < 3;i++) fuse_profile[i] = 0;
  
  uma_dbg_addTopic("fuse", rozofs_fuse_show);
  return status;
  
}