diff options
| -rwxr-xr-x | libglusterfsclient/src/libglusterfsclient-internals.h | 17 | ||||
| -rwxr-xr-x | libglusterfsclient/src/libglusterfsclient.c | 73 | 
2 files changed, 29 insertions, 61 deletions
diff --git a/libglusterfsclient/src/libglusterfsclient-internals.h b/libglusterfsclient/src/libglusterfsclient-internals.h index 4cdde26e78b..40ad6f6929f 100755 --- a/libglusterfsclient/src/libglusterfsclient-internals.h +++ b/libglusterfsclient/src/libglusterfsclient-internals.h @@ -83,6 +83,11 @@ typedef struct {          pthread_mutex_t lock;          off_t offset;          libglusterfs_client_ctx_t *ctx; +        /* `man readdir` says readdir is non-re-entrant +         * only if two readdirs are racing on the same +         * handle. +         */ +	struct dirent dirp;  } libglusterfs_client_fd_ctx_t;  typedef struct libglusterfs_client_async_local { @@ -231,16 +236,4 @@ struct vmp_entry {  }; -/* Internal directory handle inited in opendir. - * This is needed in order to store a per-handle - * dirent structure. - */ -struct libgf_dir_handle { -        fd_t *dirfd; -        struct dirent dirp; -}; - - - -  #endif diff --git a/libglusterfsclient/src/libglusterfsclient.c b/libglusterfsclient/src/libglusterfsclient.c index f16dcb4d1de..0cfc23e9ef2 100755 --- a/libglusterfsclient/src/libglusterfsclient.c +++ b/libglusterfsclient/src/libglusterfsclient.c @@ -2120,7 +2120,6 @@ glusterfs_glh_open (glusterfs_handle_t handle, const char *path, int flags,...)          mode_t mode = 0;          va_list ap;          char *pathres = NULL; -        glusterfs_file_t *fh = NULL;          GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out);          GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); @@ -2191,22 +2190,13 @@ glusterfs_glh_open (glusterfs_handle_t handle, const char *path, int flags,...)                  va_end (ap);                  op_ret = libgf_client_creat (ctx, &loc, fd, flags, mode);          } else { -                if (S_ISDIR (loc.inode->st_mode)) { -                        /* This could be optimized a bit by finding -                         * the common functionality between -                         * glusterfs_glh_open and -                         * glusterfs_glh_opendir. -                         */ -                        fh = glusterfs_glh_opendir (ctx, path); -                        goto out; -                } else +                if (S_ISDIR (loc.inode->st_mode)) +                        op_ret = libgf_client_opendir (ctx, &loc, fd); +                else                          op_ret = libgf_client_open (ctx, &loc, fd, flags);          }  op_over: -        /* For a directory all this is done inside -         * glusterfs_glh_opendir. -         */          if (op_ret == -1) {                  fd_unref (fd);                  fd = NULL; @@ -2229,12 +2219,6 @@ op_over:                  }          } -        /* This assignment will happen if the pathname to be opened is -         * a file, otherwise, if it is a directory, we'll jump to out: -         * right after the call to glusterfs_glh_opendir above. -         */ -        fh = (glusterfs_file_t)fd; -  out:          libgf_client_loc_wipe (&loc); @@ -2245,7 +2229,7 @@ out:          if (pathres)                  FREE (pathres); -        return fh; +        return fd;  }  glusterfs_file_t @@ -3375,9 +3359,8 @@ glusterfs_readdir (glusterfs_dir_t dirfd)          off_t offset = 0;          libglusterfs_client_fd_ctx_t *fd_ctx = NULL;          struct dirent *dirp = NULL; -        struct libgf_dir_handle *dir = (struct libgf_dir_handle *)dirfd; -        fd_ctx = libgf_get_fd_ctx (dir->dirfd); +        fd_ctx = libgf_get_fd_ctx (dirfd);          if (!fd_ctx) {                  errno = EBADF;  		goto out; @@ -3387,12 +3370,12 @@ glusterfs_readdir (glusterfs_dir_t dirfd)          {                  ctx = fd_ctx->ctx;                  offset = fd_ctx->offset; +                dirp = &fd_ctx->dirp;          }          pthread_mutex_unlock (&fd_ctx->lock); -        dirp = &dir->dirp;          memset (dirp, 0, sizeof (struct dirent)); -        op_ret = libgf_client_readdir (ctx, dir->dirfd, dirp, +        op_ret = libgf_client_readdir (ctx, (fd_t *)dirfd, dirp,                                         LIBGF_READDIR_BLOCK, &offset, 1);          if (op_ret <= 0) { @@ -4611,7 +4594,6 @@ glusterfs_glh_opendir (glusterfs_handle_t handle, const char *path)          loc_t                           loc = {0, };          fd_t                            *dirfd = NULL;          char                            *name = NULL; -        struct libgf_dir_handle         *dir = NULL;          GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ctx, out);          GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO (LIBGF_XL_NAME, path, out); @@ -4638,40 +4620,34 @@ glusterfs_glh_opendir (glusterfs_handle_t handle, const char *path)                  goto out;          } -        dir = CALLOC (1, sizeof (struct libgf_dir_handle)); -        if (!dir) { -                op_ret = -1; -                goto out; -        } - -        dir->dirfd = fd_create (loc.inode, 0); -        op_ret = libgf_client_opendir (ctx, &loc, dir->dirfd); - -        if (op_ret == -1) -                goto out; +        dirfd = fd_create (loc.inode, 0); +        op_ret = libgf_client_opendir (ctx, &loc, dirfd); -        if (libgf_get_fd_ctx (dir->dirfd)) +        if (op_ret == -1) { +                fd_unref (dirfd); +                dirfd = NULL;                  goto out; +        } -        if (!(libgf_alloc_fd_ctx (ctx, dir->dirfd))) { -                op_ret = -1; -                errno = EINVAL; -                goto out; +        if (!libgf_get_fd_ctx (dirfd)) { +                if (!(libgf_alloc_fd_ctx (ctx, dirfd))) { +                        op_ret = -1; +                        errno = EINVAL; +                        goto out; +                }          } -        op_ret = 0;  out:          if (name)                  FREE (name);          if (op_ret == -1) { -                FREE (dir);                  fd_unref (dirfd); -                dir = NULL; +                dirfd = NULL;          }          libgf_client_loc_wipe (&loc); -        return (glusterfs_dir_t)dir; +        return dirfd;  }  glusterfs_dir_t @@ -4704,7 +4680,7 @@ glusterfs_closedir (glusterfs_dir_t dirfd)          libglusterfs_client_fd_ctx_t    *fdctx = NULL;          GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, dirfd, out); -        fdctx = libgf_get_fd_ctx (((struct libgf_dir_handle *)dirfd)->dirfd); +        fdctx = libgf_get_fd_ctx (dirfd);          if (fdctx == NULL) {                  errno = EBADF; @@ -4712,9 +4688,8 @@ glusterfs_closedir (glusterfs_dir_t dirfd)                  goto out;          } -        op_ret = libgf_client_flush (fdctx->ctx, -                                    ((struct libgf_dir_handle *)dirfd)->dirfd); -        fd_unref (((struct libgf_dir_handle *)dirfd)->dirfd); +        op_ret = libgf_client_flush (fdctx->ctx, (fd_t *)dirfd); +        fd_unref ((fd_t *)dirfd);  out:          return op_ret;  | 
