⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 posix-locks.c

📁 分布式文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	      FIRST_CHILD(this), FIRST_CHILD(this)->fops->fstat, 	      fd);  return 0;}int32_t pl_close_cbk (call_frame_t *frame, void *cookie, xlator_t *this,	      int32_t op_ret, int32_t op_errno){  GF_ERROR_IF_NULL (this);  STACK_UNWIND (frame, op_ret, op_errno);  return 0;}int32_t pl_close (call_frame_t *frame, xlator_t *this,	  fd_t *fd){  GF_ERROR_IF_NULL (this);  GF_ERROR_IF_NULL (fd);  posix_locks_private_t *priv = (posix_locks_private_t *)this->private;  pthread_mutex_lock (&priv->mutex);  struct flock nulllock = {0, };  data_t *fd_data = dict_get (fd->ctx, this->name);  if (fd_data == NULL) {    pthread_mutex_unlock (&priv->mutex);    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF, &nulllock);    return 0;  }  pl_fd_t *pfd = (pl_fd_t *)data_to_bin (fd_data);  data_t *inode_data = dict_get (fd->inode->ctx, this->name);  if (inode_data == NULL) {    pthread_mutex_unlock (&priv->mutex);    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF, &nulllock);    return 0;  }  pl_inode_t *inode = (pl_inode_t *)data_to_bin (inode_data);  dict_del (fd->ctx, this->name);  do_blocked_rw (inode);  grant_blocked_locks (inode);  free (pfd);  pthread_mutex_unlock (&priv->mutex);  STACK_WIND (frame, pl_close_cbk, 	      FIRST_CHILD(this), FIRST_CHILD(this)->fops->close, 	      fd);  return 0;}int32_t pl_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,	      int32_t op_ret, int32_t op_errno){  STACK_UNWIND (frame, op_ret, op_errno);  return 0;}static voiddelete_locks_of_owner (pl_inode_t *inode, transport_t *transport,		       pid_t pid){  posix_lock_t *l = inode->locks;  while (l) {    posix_lock_t *tmp = l;    l = l->next;    if ((tmp->transport == transport) && 	(tmp->client_pid == pid)) {      delete_lock (inode, tmp);      destroy_lock (tmp);    }  }}int32_t pl_flush (call_frame_t *frame, xlator_t *this,	  fd_t *fd){  data_t *inode_data = dict_get (fd->inode->ctx, this->name);  if (inode_data == NULL) {    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF);    return 0;  }  pl_inode_t *inode = (pl_inode_t *)data_to_bin (inode_data);  delete_locks_of_owner (inode, frame->root->trans, frame->root->pid);  do_blocked_rw (inode);  grant_blocked_locks (inode);  STACK_WIND (frame, pl_flush_cbk, 	      FIRST_CHILD(this), FIRST_CHILD(this)->fops->flush, 	      fd);  return 0;}struct _flags {  int32_t flags;};int32_t pl_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,	     int32_t op_ret, int32_t op_errno, fd_t *fd){  GF_ERROR_IF_NULL (frame);  GF_ERROR_IF_NULL (this);  GF_ERROR_NO_RETURN_IF_NULL (fd);  posix_locks_private_t *priv = (posix_locks_private_t *)this->private;  pthread_mutex_lock (&priv->mutex);  if (op_ret >= 0) {    pl_fd_t *pfd = calloc (1, sizeof (pl_fd_t));    pl_inode_t *inode;    struct _flags *local = frame->local;    if (frame->local)      pfd->nonblocking = local->flags & O_NONBLOCK;    if (!fd->inode) {      gf_log (this->name, GF_LOG_ERROR, "fd->inode is NULL! returning EBADFD");      STACK_UNWIND (frame, -1, EBADFD, fd);    }    data_t *inode_data = dict_get (fd->inode->ctx, this->name);    if (inode_data == NULL) {      pl_inode_t *inode = calloc (1, sizeof (pl_inode_t));      mode_t st_mode = fd->inode->st_mode;      if ((st_mode & S_ISGID) && !(st_mode & S_IXGRP))	inode->mandatory = 1;      dict_set (fd->inode->ctx, this->name, bin_to_data (inode, sizeof (inode)));    }    else {      inode = data_to_bin (inode_data);    }        dict_set (fd->ctx, this->name, bin_to_data (pfd, sizeof (pfd)));  }  pthread_mutex_unlock (&priv->mutex);  STACK_UNWIND (frame, op_ret, op_errno, fd);  return 0;}int32_t pl_open (call_frame_t *frame, xlator_t *this,	 loc_t *loc, int32_t flags, fd_t *fd){  GF_ERROR_IF_NULL (frame);  GF_ERROR_IF_NULL (this);  GF_ERROR_IF_NULL (loc);  struct _flags *f = calloc (1, sizeof (struct _flags));  f->flags = flags;  if (flags & O_RDONLY)    f->flags &= ~O_TRUNC;  frame->local = f;  STACK_WIND (frame, pl_open_cbk,               FIRST_CHILD(this), FIRST_CHILD(this)->fops->open,               loc, flags & ~O_TRUNC, fd);  return 0;}int32_tpl_create_cbk (call_frame_t *frame, void *cookie,	       xlator_t *this, int32_t op_ret, int32_t op_errno,	       fd_t *fd, inode_t *inode, struct stat *buf){  if (op_ret >= 0) {    pl_inode_t *pinode = calloc (1, sizeof (pl_inode_t));    pl_fd_t *pfd = calloc (1, sizeof (pl_fd_t));        dict_set (fd->inode->ctx, this->name, bin_to_data (pinode, sizeof (pinode)));    dict_set (fd->ctx, this->name, bin_to_data (pfd, sizeof (pfd)));  }  STACK_UNWIND (frame, op_ret, op_errno, fd, inode, buf);  return 0;}int32_t pl_create (call_frame_t *frame, xlator_t *this,	   loc_t *loc, int32_t flags, mode_t mode, fd_t *fd){  GF_ERROR_IF_NULL (frame);  GF_ERROR_IF_NULL (this);  GF_ERROR_IF_NULL (loc->path);  STACK_WIND (frame, pl_create_cbk,              FIRST_CHILD (this),              FIRST_CHILD (this)->fops->create, 	      loc, flags, mode, fd);  return 0;}int32_tpl_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,	      int32_t op_ret, int32_t op_errno,	      struct iovec *vector, int32_t count, struct stat *stbuf){  GF_ERROR_IF_NULL (this);  GF_ERROR_IF_NULL (vector);  STACK_UNWIND (frame, op_ret, op_errno, vector, count, stbuf);  return 0;}int32_tpl_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, 	       int32_t op_ret, int32_t op_errno, struct stat *stbuf){  GF_ERROR_IF_NULL (this);  STACK_UNWIND (frame, op_ret, op_errno, stbuf);  return 0;}static voiddo_blocked_rw (pl_inode_t *inode){  pl_rw_req_t *rw = inode->rw_reqs;  while (rw) {    if (rw_allowable (inode, rw->region, rw->op)) {      switch (rw->op) {      case OP_READ:	STACK_WIND (rw->frame, pl_readv_cbk,		    FIRST_CHILD (rw->this), FIRST_CHILD (rw->this)->fops->readv,		    rw->fd, rw->size, rw->region->fl_start);	break;      case OP_WRITE: 	{	  dict_t *req_refs = rw->frame->root->req_refs;	  STACK_WIND (rw->frame, pl_writev_cbk,		      FIRST_CHILD (rw->this), 		      FIRST_CHILD (rw->this)->fops->writev,		      rw->fd, rw->vector, rw->size, rw->region->fl_start);	  dict_unref (req_refs);	  break;	}      }            delete_rw_req (inode, rw);      free (rw);    }        rw = rw->next;  }}static intrw_allowable (pl_inode_t *inode, posix_lock_t *region,	      rw_op_t op){  posix_lock_t *l = inode->locks;  while (l) {    if (locks_overlap (l, region) && !same_owner (l, region)) {      if ((op == OP_READ) && (l->fl_type != F_WRLCK))	continue;      return 0;    }    l = l->next;  }  return 1;}int32_tpl_readv (call_frame_t *frame, xlator_t *this,	  fd_t *fd, size_t size, off_t offset){  GF_ERROR_IF_NULL (this);  GF_ERROR_IF_NULL (fd);  posix_locks_private_t *priv = (posix_locks_private_t *)this->private;  struct stat nullbuf = {0, };  pthread_mutex_lock (&priv->mutex);  data_t *fd_data = dict_get (fd->ctx, this->name);  if (fd_data == NULL) {    pthread_mutex_unlock (&priv->mutex);    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF, &nullbuf);    return 0;  }  pl_fd_t *pfd = (pl_fd_t *) data_to_bin (fd_data);  data_t *inode_data = dict_get (fd->inode->ctx, this->name);  if (inode_data == NULL) {    pthread_mutex_unlock (&priv->mutex);    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF, &nullbuf);    return 0;  }  pl_inode_t *inode = (pl_inode_t *)data_to_bin (inode_data);  if (priv->mandatory && inode->mandatory) {    posix_lock_t *region = calloc (1, sizeof (posix_lock_t));    region->fl_start = offset;    region->fl_end   = offset + size - 1;    region->transport = frame->root->trans;    region->client_pid = frame->root->pid;        if (!rw_allowable (inode, region, OP_READ)) {      if (pfd->nonblocking) {	pthread_mutex_unlock (&priv->mutex);	gf_log (this->name, GF_LOG_ERROR, "returning EWOULDBLOCK");	STACK_UNWIND (frame, -1, EWOULDBLOCK, &nullbuf);	return -1;      }      pl_rw_req_t *rw = calloc (1, sizeof (pl_rw_req_t));      rw->frame  = frame;      rw->this   = this;      rw->fd     = fd;      rw->op     = OP_READ;      rw->size   = size;      rw->region = region;      insert_rw_req (inode, rw);      pthread_mutex_unlock (&priv->mutex);      return 0;    }  }  pthread_mutex_unlock (&priv->mutex);  STACK_WIND (frame, pl_readv_cbk, 	      FIRST_CHILD (this), FIRST_CHILD (this)->fops->readv,	      fd, size, offset);  return 0;}static int32_tiovec_total_length (struct iovec *vector, int count){  int32_t i;  int32_t total_length = 0;  for (i = 0; i < count; i++) {    total_length += vector[i].iov_len;  }  return total_length;}int32_t pl_writev (call_frame_t *frame, xlator_t *this,	   fd_t *fd, struct iovec *vector, int32_t count, off_t offset){  GF_ERROR_IF_NULL (this);  GF_ERROR_IF_NULL (fd);  GF_ERROR_IF_NULL (vector);  posix_locks_private_t *priv = (posix_locks_private_t *)this->private;  struct stat nullbuf = {0, };  pthread_mutex_lock (&priv->mutex);  data_t *fd_data = dict_get (fd->ctx, this->name);  if (fd_data == NULL) {    pthread_mutex_unlock (&priv->mutex);    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF, &nullbuf);    return 0;  }  pl_fd_t *pfd = (pl_fd_t *)data_to_bin (fd_data);  data_t *inode_data = dict_get (fd->inode->ctx, this->name);  if (inode_data == NULL) {    pthread_mutex_unlock (&priv->mutex);    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF, &nullbuf);    return 0;  }  pl_inode_t *inode = (pl_inode_t *)data_to_bin (inode_data);  if (priv->mandatory && inode->mandatory) {    int size = iovec_total_length (vector, count);    posix_lock_t *region = calloc (1, sizeof (posix_lock_t));    region->fl_start = offset;    region->fl_end   = offset + size - 1;    region->transport = frame->root->trans;    region->client_pid = frame->root->pid;    if (!rw_allowable (inode, region, OP_WRITE)) {      if (pfd->nonblocking) {	pthread_mutex_unlock (&priv->mutex);	gf_log (this->name, GF_LOG_ERROR, "returning EWOULDBLOCK");	STACK_UNWIND (frame, -1, EWOULDBLOCK, &nullbuf);	return -1;      }      pl_rw_req_t *rw = calloc (1, sizeof (pl_rw_req_t));      dict_ref (frame->root->req_refs);      rw->frame  = frame;      rw->this   = this;      rw->fd     = fd;      rw->op     = OP_WRITE;      rw->size   = count;      rw->vector = iov_dup (vector, count);      rw->region = region;      insert_rw_req (inode, rw);      pthread_mutex_unlock (&priv->mutex);      return 0;    }  }  pthread_mutex_unlock (&priv->mutex);  STACK_WIND (frame, pl_writev_cbk,	      FIRST_CHILD(this), FIRST_CHILD(this)->fops->writev, 	      fd, vector, count, offset);  return 0;}int32_tpl_lk (call_frame_t *frame, xlator_t *this,       fd_t *fd, int32_t cmd,       struct flock *flock){  GF_ERROR_IF_NULL (frame);  GF_ERROR_IF_NULL (this);  GF_ERROR_IF_NULL (fd);  GF_ERROR_IF_NULL (flock);  transport_t *transport = frame->root->trans;  pid_t client_pid = frame->root->pid;  posix_locks_private_t *priv = (posix_locks_private_t *)this->private;  pthread_mutex_lock (&priv->mutex);  struct flock nulllock = {0, };  data_t *fd_data = dict_get (fd->ctx, this->name);  if (fd_data == NULL) {    pthread_mutex_unlock (&priv->mutex);    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF, &nulllock);    return 0;  }  pl_fd_t *pfd = (pl_fd_t *)data_to_bin (fd_data);  if (!pfd) {    pthread_mutex_unlock (&priv->mutex);    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF, nulllock);    return -1;  }  data_t *inode_data = dict_get (fd->inode->ctx, this->name);  if (inode_data == NULL) {    pthread_mutex_unlock (&priv->mutex);    gf_log (this->name, GF_LOG_ERROR, "returning EBADF");    STACK_UNWIND (frame, -1, EBADF, &nulllock);    return 0;  }  pl_inode_t *inode = (pl_inode_t *)data_to_bin (inode_data);    posix_lock_t *reqlock = new_posix_lock (flock, transport, client_pid);  int can_block = 0;  switch (cmd) {#if F_GETLK != F_GETLK64  case F_GETLK64:#endif  case F_GETLK: {    posix_lock_t *conf = posix_getlk (inode, reqlock);    posix_lock_to_flock (conf, flock);    pthread_mutex_unlock (&priv->mutex);    destroy_lock (reqlock);#ifdef _POSIX_LOCKS_DEBUG    printf ("[GET] "); print_lock (reqlock);#endif    STACK_UNWIND (frame, 0, 0, flock);    return 0;  }#if F_SETLKW != F_SETLKW64  case F_SETLKW64:#endif  case F_SETLKW:    can_block = 1;    reqlock->frame = frame;    reqlock->this  = this;    reqlock->fd    = fd;    reqlock->user_flock = calloc (1, sizeof (struct flock));    memcpy (reqlock->user_flock, flock, sizeof (struct flock));#if F_SETLK != F_SETLK64  case F_SETLK64:#endif  case F_SETLK: {    int ret = posix_setlk (inode, reqlock, can_block);#ifdef _POSIX_LOCKS_DEBUG    printf ("[SET] (ret=%d)", ret); print_lock (reqlock);#endif    pthread_mutex_unlock (&priv->mutex);    if (ret == -1) {      if (can_block)	return -1;      gf_log (this->name, GF_LOG_ERROR, "returning EAGAIN");      STACK_UNWIND (frame, ret, EAGAIN, flock);      return -1;    }    if (ret == 0) {      STACK_UNWIND (frame, ret, 0, flock);      return 0;    }  }  }  pthread_mutex_unlock (&priv->mutex);  gf_log (this->name, GF_LOG_ERROR, "returning EINVAL");  STACK_UNWIND (frame, -1, EINVAL, flock); /* Normally this shouldn't be reached */  return -1;}int32_tpl_forget (call_frame_t *frame,	   xlator_t *this,	   inode_t *inode){  data_t *inode_data = dict_get (inode->ctx, this->name);  if (inode_data) {    pl_inode_t *pl_inode = (pl_inode_t *)data_to_bin (inode_data);    if (pl_inode->rw_reqs) {      gf_log (this->name, GF_LOG_ERROR,	      "Pending R/W requests found!");    }    if (pl_inode->locks) {      gf_log (this->name, GF_LOG_ERROR,	      "Active locks found!");    }    free (pl_inode);  }  return 0;}int32_tinit (xlator_t *this){  posix_locks_private_t *priv = NULL;  data_t *mandatory = NULL;  if (!this->children) {    gf_log (this->name, 	    GF_LOG_ERROR, 	    "FATAL: posix-locks should have exactly one child");    return -1;  }  if (this->children->next) {    gf_log (this->name, 	    GF_LOG_ERROR, 	    "FATAL: posix-locks should have exactly one child");    return -1;  }  priv = calloc (1, sizeof (posix_locks_private_t));  pthread_mutex_init (&priv->mutex, NULL);  mandatory = dict_get (this->options, "mandatory");  if (mandatory) {    if (strcasecmp (mandatory->data, "on") == 0)      priv->mandatory = 1;  }  this->private = priv;  return 0;}int32_tfini (xlator_t *this){  posix_locks_private_t *priv = this->private;  free (priv);  return 0;}struct xlator_fops fops = {  .create      = pl_create,  .truncate    = pl_truncate,  .ftruncate   = pl_ftruncate,  .open        = pl_open,  .readv       = pl_readv,  .writev      = pl_writev,  .close       = pl_close,  .lk          = pl_lk,  .flush       = pl_flush,  .forget      = pl_forget};struct xlator_mops mops = {};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -