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

📄 afr.c

📁 分布式文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		int32_t op_ret,		int32_t op_errno,		inode_t *inode,		struct stat *buf,		dict_t *xattr){  char *child_errno = NULL;  data_t *errno_data = NULL;  int32_t callcnt, i, latest = -1, first = -1;  afr_local_t *local = frame->local;  afr_private_t *pvt = this->private;  xlator_t **children = pvt->children;  int32_t child_count = pvt->child_count;  call_frame_t *prev_frame = cookie;  struct stat *statptr = local->statptr;  afr_selfheal_t *ashptr = local->ashptr;  AFR_DEBUG_FMT(this, "op_ret = %d op_errno = %d, inode = %p, returned from %s", 		op_ret, op_errno, inode, prev_frame->this->name);  if (op_ret != 0 && op_errno != ENOTCONN)    local->op_errno = op_errno;  /* 'i' will be the index indicating us, which child node has returned to us */  for (i = 0; i < child_count; i++)    if (children[i] == prev_frame->this)      break;  /* child_errno is an array of one bytes, each byte corresponding to the errno returned by a child node   * child_errno array is initialized during the first succesful return call from a child.   */  errno_data = dict_get (local->loc->inode->ctx, this->name);  if (errno_data)    child_errno = data_to_ptr (errno_data);  if (child_errno == NULL) {    /* first time lookup and success */    child_errno = calloc (child_count, sizeof (char));	    dict_set (local->loc->inode->ctx, this->name, data_from_dynptr (child_errno, child_count));  }  /* child_errno[i] is either 0 indicating success or op_errno indicating failure */  if (op_ret == 0) {    data_t *ctime_data, *version_data;    local->op_ret = 0;    if (inode && list_empty (&inode->fds)) {      child_errno[i] = 0;    }    GF_BUG_ON (!inode);    GF_BUG_ON (!buf);    statptr[i] = *buf;    if (pvt->self_heal && xattr) {      /* self heal is 'on' and we also recieved the xattr that we requested from our children.       * store ctime and version returned by each child */      ctime_data = dict_get (xattr, GLUSTERFS_CREATETIME);      if (ctime_data) {	ashptr[i].ctime = data_to_uint32 (ctime_data);      }      version_data = dict_get (xattr, GLUSTERFS_VERSION);      if (version_data) {	ashptr[i].version = data_to_uint32 (version_data);      }      if (ashptr[i].ctime > local->latest_ctime || 	  (ashptr[i].ctime == local->latest_ctime && ashptr[i].version > local->latest_version)) {	local->latest_ctime = ashptr[i].ctime;	local->latest_version = ashptr[i].version;	if (local->latest_xattr)	  dict_unref (local->latest_xattr);	local->latest_xattr = dict_ref (xattr);      }      AFR_DEBUG_FMT (this, "child %s ctime %d version %d", 		     prev_frame->this->name, ashptr[i].ctime, ashptr[i].version);    }  } else if (inode && list_empty (&inode->fds)) {    /* either self-heal is turned 'off' or we didn't recieve xattr, which we requested for */    child_errno[i] = op_errno;  }  LOCK (&frame->lock);  {    callcnt = --local->call_count;  }  UNLOCK (&frame->lock);  if (callcnt == 0) {    if (local->op_ret == 0) {      if (pvt->self_heal) {	for (i = 0; i < child_count; i++) {	  if (child_errno[i] == 0)	    break;	}	if (i < child_count) {	  afr_check_ctime_version (frame);	  return 0;	}      }    }    /* child_errno will be freed when dict is destroyed */    if (local->op_ret == 0) {      for (i = 0; i < child_count; i++) {	if (child_errno[i] == 0) {	  if (latest == -1) {	    /* first will be the first valid stat, latest will be the stat with latest mtime */	    first = i;	    latest = i;	    continue;	  }	  /* FIXME use ctime/version 	  if (statptr[i].ctime > statptr[latest].ctime ||	      (statptr[i].ctime == statptr[latest].ctime && statptr[i].version > statptr[latest]))	  */	  if (statptr[i].st_mtime > statptr[latest].st_mtime)	    latest = i;	}      }    }    if (first == -1) {      first = latest = 0;    } else {      /* FIXME: we preserve the ino num (whatever that was got during the initial lookup(?) */      if (local->ino)	statptr[latest].st_ino = local->ino;      else	statptr[latest].st_ino = statptr[first].st_ino;    }    afr_loc_free(local->loc);    afr_free_ashptr (local->ashptr, child_count, local->latest);    STACK_UNWIND (frame,		  local->op_ret,		  local->op_errno,		  inode,		  &statptr[latest],		  xattr);    freee (statptr);  }  return 0;}int32_tafr_lookup (call_frame_t *frame,	    xlator_t *this,	    loc_t *loc,	    int32_t need_xattr){  afr_local_t *local = calloc (1, sizeof (*local));  afr_private_t *pvt = this->private;  xlator_t **children = pvt->children;  int32_t child_count = pvt->child_count, i;  AFR_DEBUG_FMT (this, "loc->path = %s loc->inode = %p", loc->path, loc->inode);  frame->local = local;  local->op_ret = -1;  local->op_errno = ENOTCONN;  local->loc = afr_loc_dup (loc);  /* statptr[] array is used for selfheal */  local->statptr = calloc (child_count, sizeof (struct stat));  local->ashptr  = calloc (child_count, sizeof (afr_selfheal_t));  local->call_count = child_count;  local->ino = loc->ino;  for (i = 0; i < child_count; i ++) {    /* request for extended attributes if self heal is 'on' */    int32_t need_xattr = pvt->self_heal;    STACK_WIND (frame,		afr_lookup_cbk,		children[i],		children[i]->fops->lookup,		loc,		need_xattr);  }  return 0;}int32_tafr_incver_cbk (call_frame_t *frame,		void *cookie,		xlator_t *this,		int32_t op_ret,		int32_t op_errno){  int32_t callcnt = 0;  afr_local_t *local = frame->local;  if (op_ret > local->op_ret)    local->op_ret = op_ret;  LOCK (&frame->lock);  {    callcnt = --local->call_count;  }  UNLOCK (&frame->lock);  if (callcnt == 0) {    STACK_UNWIND (frame, local->op_ret, local->op_errno);  }  return 0;}int32_tafr_incver (call_frame_t *frame,	    xlator_t *this,	    const char *path){  afr_local_t *local = calloc (1, sizeof (afr_local_t));;  afr_private_t *pvt = frame->this->private;  int32_t child_count = pvt->child_count, i;  xlator_t **children = pvt->children;  char *state = pvt->state;  frame->local = local;  local->op_ret = -1;  for (i = 0; i < child_count; i++) {    if (state[i])      local->call_count++;  }  if (local->call_count == 0) {    GF_ERROR (this, "all children are down, returning ENOTCONN");    STACK_UNWIND (frame, -1, ENOTCONN);    return 0;  }  for (i = 0; i < child_count; i++) {    if (state[i]) {      STACK_WIND (frame,		  afr_incver_cbk,		  children[i],		  children[i]->fops->incver,		  path);    }  }  return 0;}int32_tafr_incver_internal_unlock_cbk (call_frame_t *frame,				void *cookie,				xlator_t *this,				int32_t op_ret,				int32_t op_errno){  afr_local_t *local = frame->local;  freee (local->path);  STACK_DESTROY (frame->root);  return 0;}int32_tafr_incver_internal_incver_cbk (call_frame_t *frame,				void *cookie,				xlator_t *this,				int32_t op_ret,				int32_t op_errno){  afr_local_t *local = frame->local;  int32_t callcnt;  LOCK (&frame->lock);  callcnt = --local->call_count;  UNLOCK (&frame->lock);  if (callcnt == 0) {    char *lock_path = NULL;    asprintf (&lock_path, "/%s%s", local->lock_node->name, local->path);    STACK_WIND (frame,		afr_incver_internal_unlock_cbk,		local->lock_node,		local->lock_node->mops->unlock,		lock_path);    freee (lock_path);  }  return 0;}int32_tafr_incver_internal_lock_cbk (call_frame_t *frame,			      void *cookie,			      xlator_t *this,			      int32_t op_ret,			      int32_t op_errno){  afr_local_t *local = frame->local;  afr_private_t *pvt = frame->this->private;  int32_t child_count = pvt->child_count, i;  xlator_t **children = pvt->children;  char *state = pvt->state;  for (i = 0; i < child_count; i++) {    if (state[i])      local->call_count++;  }  /* handle call_count == 0 */  for (i = 0; i < child_count; i++) {    if (state[i]) {      STACK_WIND (frame,		  afr_incver_internal_incver_cbk,		  children[i],		  children[i]->fops->incver,		  local->path);    }  }  return 0;}int32_tafr_incver_internal (call_frame_t *frame,		     xlator_t *this,		     const char *path){  call_frame_t *incver_frame;  afr_local_t *local;  afr_private_t *pvt = frame->this->private;  int32_t child_count = pvt->child_count, i, call_count = 0;  xlator_t **children = pvt->children;  char *state = pvt->state;  char *lock_path = NULL;  if (pvt->self_heal == 0)    return 0;  for (i = 0; i < child_count; i++) {    if (state[i])      call_count++;  }  /* we wont incver if all children are down or if all children are up */  if (call_count == 0 || call_count == child_count) {    return 0;  }  for (i = 0; i < child_count; i++) {    if (state[i])      break;  }  local = calloc (1, sizeof (afr_local_t));  incver_frame = copy_frame (frame);  incver_frame->local = local;  local->lock_node = children[i];  local->path = dirname (strdup(path));  asprintf (&lock_path, "/%s%s", local->lock_node->name, local->path);  STACK_WIND (incver_frame,	      afr_incver_internal_lock_cbk,	      local->lock_node,	      local->lock_node->mops->lock,	      lock_path);  freee (lock_path);  return 0;}/* no need to do anything in forget, as the mem will be just free'd in dict_destroy(inode->ctx) */int32_tafr_forget (call_frame_t *frame,	    xlator_t *this,	    inode_t *inode){  return 0;}int32_tafr_setxattr_cbk (call_frame_t *frame,		  void *cookie,		  xlator_t *this,		  int32_t op_ret,		  int32_t op_errno){  afr_local_t *local = (afr_local_t *) frame->local;  call_frame_t *prev_frame = cookie;  int32_t callcnt;  AFR_DEBUG(this);  if (op_ret != 0  && op_errno != ENOTCONN) {    local->op_errno = op_errno;  }  if (op_ret == 0) {    local->op_ret = op_ret;  } else {    GF_ERROR (this, "(path=%s child=%s) op_ret=%d op_errno=%d", 	      local->loc->path, prev_frame->this->name, op_ret, op_errno);  }  LOCK (&frame->lock);  {    callcnt = --local->call_count;  }  UNLOCK (&frame->lock);  if (callcnt == 0) {    afr_loc_free (local->loc);    STACK_UNWIND (frame, local->op_ret, local->op_errno);  }  return 0;}int32_tafr_setxattr (call_frame_t *frame,	      xlator_t *this,	      loc_t *loc,	      dict_t *dict,	      int32_t flags){  afr_local_t *local = (void *) calloc (1, sizeof (afr_local_t));  afr_private_t *pvt = this->private;  char *afr_errno = NULL;  xlator_t **children = pvt->children;  int32_t child_count = pvt->child_count, i;  char *child_errno = NULL;  AFR_DEBUG_FMT (this, "loc->path = %s", loc->path);  afr_errno = data_to_ptr (dict_get (loc->inode->ctx, this->name));   AFR_ERRNO_DUP(child_errno, afr_errno, child_count);  frame->local = local;  local->op_ret = -1;  local->op_errno = ENOTCONN;  local->loc = afr_loc_dup (loc);  for (i = 0; i < child_count; i++) {    if (child_errno[i] == 0)      ++local->call_count;  }  if (local->call_count == 0) {    GF_ERROR (this, "child_errno[] is not 0, returning ENOTCONN");    STACK_UNWIND (frame, -1, ENOTCONN);    return 0;  }  for (i = 0; i < child_count; i++) {    if (child_errno[i] == 0)      STACK_WIND(frame,		 afr_setxattr_cbk,		 children[i],		 children[i]->fops->setxattr,		 loc,		 dict,		 flags);  }  return 0;}int32_tafr_getxattr_cbk (call_frame_t *frame,		  void *cookie,		  xlator_t *this,		  int32_t op_ret,		  int32_t op_errno,		  dict_t *dict){  call_frame_t *prev_frame = cookie;  AFR_DEBUG(this);  if (op_ret >= 0) {    GF_BUG_ON (!dict);  } else if (op_errno != ENODATA) {    GF_ERROR (this, "(path=%s child=%s) op_ret=%d op_errno=%d", 	      frame->local, prev_frame->this->name, op_ret, op_errno);  }  STACK_UNWIND (frame, op_ret, op_errno, dict);  return 0;}int32_tafr_getxattr (call_frame_t *frame,	      xlator_t *this,	      loc_t *loc){  afr_private_t *pvt = this->private;  char *afr_errno = NULL;  xlator_t **children = pvt->children;  int32_t child_count = pvt->child_count, i;  char *child_errno = NULL;  AFR_DEBUG_FMT (this, "loc->path = %s", loc->path);  afr_errno = data_to_ptr (dict_get (loc->inode->ctx, this->name));  AFR_ERRNO_DUP(child_errno, afr_errno, child_count);  frame->local = strdup (loc->path);  for (i = 0; i < child_count; i++) {    if (child_errno[i] == 0)      break;  }  if (i == child_count) {    STACK_UNWIND (frame, -1, ENOTCONN, NULL);    return 0;  }  /* send getxattr command to the first child where the file is available */  STACK_WIND (frame,	      afr_getxattr_cbk,	      children[i],	      children[i]->fops->getxattr,	      loc);  return 0;}int32_tafr_removexattr_cbk (call_frame_t *frame,		     void *cookie,		     xlator_t *this,		     int32_t op_ret,		     int32_t op_errno){  int32_t callcnt = 0;  afr_local_t *local = frame->local;

⌨️ 快捷键说明

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