summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2009-08-23 22:37:10 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-09-08 01:43:01 -0700
commita5c829a3aa1d2f66dc85350bd4c163ef12507d44 (patch)
tree87fa7d05badb07a434a9f9b8fc4d5fc226a65b5b /xlators
parent727c933a62e6b436c0aabcf80b6cd67620ee5429 (diff)
storage/posix: handle dentries from different mount points in readdir
- If posix translator is configured to have export directories to span accross different mount points, inode number is transformed in the dentry returned. Otherwise, the entry is not added to list of entries returned in readdir callback. - storage/posix returns ENOENT if the file is on different mount point other than that of exported directory and is not configured for export directory spanning across multiple mountpoints during lookup. But, since stat-prefetch shortcuts lookup calls, its necessary that readdir return only valid dentries. Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 221 (stat prefetch implementation) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=221
Diffstat (limited to 'xlators')
-rw-r--r--xlators/storage/posix/src/posix.c85
1 files changed, 51 insertions, 34 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index b124d1362..4eb484bc0 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;