diff options
Diffstat (limited to 'xlators/storage/posix/src/posix.c')
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 85 | 
1 files changed, 51 insertions, 34 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index b124d136201..4eb484bc062 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3502,26 +3502,25 @@ int32_t  posix_readdir (call_frame_t *frame, xlator_t *this,                 fd_t *fd, size_t size, off_t off)  { -	uint64_t          tmp_pfd = 0; -        struct posix_fd * pfd    = NULL; -        DIR *             dir    = NULL; -        int               ret    = -1; -        size_t            filled = 0; -	int               count = 0; - -        int32_t           op_ret   = -1; -        int32_t           op_errno = 0; - -        gf_dirent_t *     this_entry = NULL; -	gf_dirent_t       entries; -        struct dirent *   entry      = NULL; -        off_t             in_case    = -1; -        int32_t           this_size  = -1; - -        char *            real_path      = NULL; -        int               real_path_len  = -1; -        char *            entry_path     = NULL; -        int               entry_path_len = -1; +	uint64_t              tmp_pfd        = 0; +        struct posix_fd      *pfd            = NULL; +        DIR                  *dir            = NULL; +        int                   ret            = -1; +        size_t                filled         = 0; +	int                   count          = 0; +        int32_t               op_ret         = -1; +        int32_t               op_errno       = 0; +        gf_dirent_t          *this_entry     = NULL; +	gf_dirent_t           entries; +        struct dirent        *entry          = NULL; +        off_t                 in_case        = -1; +        int32_t               this_size      = -1; +        char                 *real_path      = NULL; +        int                   real_path_len  = -1; +        char                 *entry_path     = NULL; +        int                   entry_path_len = -1; +        struct posix_private *priv           = NULL; +        struct stat           stbuf          = {0, };          VALIDATE_OR_GOTO (frame, out);          VALIDATE_OR_GOTO (this, out); @@ -3529,6 +3528,8 @@ posix_readdir (call_frame_t *frame, xlator_t *this,  	INIT_LIST_HEAD (&entries.list); +        priv = this->private; +          ret = fd_ctx_get (fd, this, &tmp_pfd);          if (ret < 0) {                  gf_log (this->name, GF_LOG_DEBUG, @@ -3609,25 +3610,41 @@ posix_readdir (call_frame_t *frame, xlator_t *this,                          break;                  } +                strcpy (entry_path + real_path_len + 1, entry->d_name); +                lstat (entry_path, &stbuf); +                /* Make sure we don't access another mountpoint inside export dir. +                 * It may cause inode number to repeat from single export point, +                 * which leads to severe problems.. +                 */ +                if (!priv->span_devices) { +                        if (priv->st_device[0] != stbuf.st_dev) { +                                continue; +                        } +                } else { +                        op_ret = posix_scale_st_ino (priv, &stbuf); +                        if (-1 == op_ret) { +                                continue; +                        } +                } + +                entry->d_ino = stbuf.st_ino; -		this_entry = gf_dirent_for_name (entry->d_name); +                this_entry = gf_dirent_for_name (entry->d_name); -		if (!this_entry) { -			gf_log (this->name, GF_LOG_ERROR, -				"could not create gf_dirent for entry %s: (%s)", -				entry->d_name, strerror (errno)); -			goto out; -		} -		this_entry->d_off = telldir (dir); -		this_entry->d_ino = entry->d_ino; +                if (!this_entry) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "could not create gf_dirent for entry %s: (%s)", +                                entry->d_name, strerror (errno)); +                        goto out; +                } +                this_entry->d_off = telldir (dir); +                this_entry->d_ino = entry->d_ino; +                this_entry->d_stat = stbuf; -		list_add_tail (&this_entry->list, &entries.list); +                list_add_tail (&this_entry->list, &entries.list);                  filled += this_size; -		count ++; - -                strcpy (entry_path + real_path_len + 1, this_entry->d_name); -                lstat (entry_path, &this_entry->d_stat); +                count ++;          }          op_ret = count;  | 
