diff options
| author | Mohit Agrawal <moagrawal@redhat.com> | 2019-10-14 15:42:31 +0530 | 
|---|---|---|
| committer | hari gowtham <hari.gowtham005@gmail.com> | 2019-11-13 04:57:32 +0000 | 
| commit | 7767d14699999dfb82c690b911e83b698b820e19 (patch) | |
| tree | 545478d0480ae88f7b68b80df931b5629adedfb2 /xlators/cluster/dht/src/dht-common.c | |
| parent | 4b02b98d6a628936643e236d73836749d32332da (diff) | |
dht: Rebalance causing IO Error - File descriptor in bad state
Problem : When a file is migrated, dht attempts to re-open all open
          fds on the new cached subvol. Earlier, if dht had not opened the fd,
          the client xlator would be unable to find the remote fd and would
          fall back to using an anon fd for the fop. That behavior changed with
          https://review.gluster.org/#/c/glusterfs/+/15804, causing fops to fail
          with EBADFD if the fd was not available on the cached subvol.
          The client xlator returns EBADFD if the remote fd is not found but
          dht only checks for EBADF before re-opening fds on the new cached subvol.
Solution: Handle EBADFD at dht code path to avoid the issue
> Change-Id: I43c51995cdd48d05b12e4b2889c8dbe2bb2a72d8
> Fixes: bz#1758579
> (cherry picked from commit 9314a9fbf487614c736cf6c4c1b93078d37bb9df)
> (Reviewed on upstream link https://review.gluster.org/23518)
Change-Id: I43c51995cdd48d05b12e4b2889c8dbe2bb2a72d8
Fixes: bz#1761910
Diffstat (limited to 'xlators/cluster/dht/src/dht-common.c')
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 27 | 
1 files changed, 23 insertions, 4 deletions
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index d9c6af27298..0ce2da34cb7 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -51,6 +51,17 @@ dht_set_dir_xattr_req(xlator_t *this, loc_t *loc, dict_t *xattr_req);  int  dht_do_fresh_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc); +/* Check the xdata to make sure EBADF has been set by client xlator */ +int32_t +dht_check_remote_fd_failed_error(dht_local_t *local, int op_ret, int op_errno) +{ +    if (op_ret == -1 && (op_errno == EBADF || op_errno == EBADFD) && +        !(local->fd_checked)) { +        return 1; +    } +    return 0; +} +  /* Sets the blocks and size values to fixed values. This is to be called   * only for dirs. The caller is responsible for checking the type   */ @@ -4527,6 +4538,7 @@ dht_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,      int this_call_cnt = 0;      dht_local_t *local = NULL;      dht_conf_t *conf = NULL; +    int ret = 0;      VALIDATE_OR_GOTO(frame, err);      VALIDATE_OR_GOTO(frame->local, err); @@ -4535,6 +4547,13 @@ dht_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,      conf = this->private;      local = frame->local; +    if (dht_check_remote_fd_failed_error(local, op_ret, op_errno)) { +        ret = dht_check_and_open_fd_on_subvol(this, frame); +        if (ret) +            goto err; +        return 0; +    } +      LOCK(&frame->lock);      {          if (!xattr || (op_ret == -1)) { @@ -5202,8 +5221,8 @@ dht_file_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,      local->op_errno = op_errno; -    if ((local->fop == GF_FOP_FSETXATTR) && op_ret == -1 && -        (op_errno == EBADF) && !(local->fd_checked)) { +    if ((local->fop == GF_FOP_FSETXATTR) && +        dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {          ret = dht_check_and_open_fd_on_subvol(this, frame);          if (ret)              goto out; @@ -5927,8 +5946,8 @@ dht_file_removexattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,      local->op_errno = op_errno; -    if ((local->fop == GF_FOP_FREMOVEXATTR) && (op_ret == -1) && -        (op_errno == EBADF) && !(local->fd_checked)) { +    if ((local->fop == GF_FOP_FREMOVEXATTR) && +        dht_check_remote_fd_failed_error(local, op_ret, op_errno)) {          ret = dht_check_and_open_fd_on_subvol(this, frame);          if (ret)              goto out;  | 
