summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix.c
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2009-09-10 04:36:19 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-09-15 00:02:01 -0700
commitef8ea2672c14ae19b0ae421cf53a701f89f4f192 (patch)
treea0a411b2f1c14e6cd53851f82f1004b45f3886fe /xlators/storage/posix/src/posix.c
parentbcca4200218b45b547135a2e84a955062bc40089 (diff)
storage/posix: transform inode number in stat structure
- when export directory is configured to span across multiple mountpoints, the inode number has to be transformed in order to make it unique. Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 254 (storage/posix has to do inode number transformation wherever it unwinds with a stat structure) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=254
Diffstat (limited to 'xlators/storage/posix/src/posix.c')
-rw-r--r--xlators/storage/posix/src/posix.c642
1 files changed, 489 insertions, 153 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index f5f6803..8839c49 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -372,10 +372,11 @@ posix_stat (call_frame_t *frame,
xlator_t *this,
loc_t *loc)
{
- struct stat buf = {0,};
- char * real_path = NULL;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
+ struct stat buf = {0,};
+ char * real_path = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -383,11 +384,13 @@ posix_stat (call_frame_t *frame,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
SET_FS_ID (frame->root->uid, frame->root->gid);
MAKE_REAL_PATH (real_path, this, loc->path);
op_ret = lstat (real_path, &buf);
-
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -396,6 +399,10 @@ posix_stat (call_frame_t *frame,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &buf);
+ }
+
op_ret = 0;
out:
@@ -490,23 +497,24 @@ int32_t
posix_getdents (call_frame_t *frame, xlator_t *this,
fd_t *fd, size_t size, off_t off, int32_t flag)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = NULL;
- dir_entry_t entries = {0, };
- dir_entry_t * tmp = NULL;
- DIR * dir = NULL;
- struct dirent * dirent = NULL;
- int real_path_len = -1;
- int entry_path_len = -1;
- char * entry_path = NULL;
- int count = 0;
- struct posix_fd * pfd = NULL;
- uint64_t tmp_pfd = 0;
- struct stat buf = {0,};
- int ret = -1;
- char tmp_real_path[ZR_PATH_MAX];
- char linkpath[ZR_PATH_MAX];
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = NULL;
+ dir_entry_t entries = {0, };
+ dir_entry_t *tmp = NULL;
+ DIR *dir = NULL;
+ struct dirent *dirent = NULL;
+ int real_path_len = -1;
+ int entry_path_len = -1;
+ char *entry_path = NULL;
+ int count = 0;
+ struct posix_fd *pfd = NULL;
+ uint64_t tmp_pfd = 0;
+ struct stat buf = {0,};
+ int ret = -1;
+ char tmp_real_path[ZR_PATH_MAX];
+ char linkpath[ZR_PATH_MAX];
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR ;
@@ -514,6 +522,9 @@ posix_getdents (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
SET_FS_ID (frame->root->uid, frame->root->gid);
ret = fd_ctx_get (fd, this, &tmp_pfd);
@@ -577,7 +588,8 @@ posix_getdents (call_frame_t *frame, xlator_t *this,
ZR_PATH_MAX - strlen (tmp_real_path));
strncat (tmp_real_path, dirent->d_name,
- ZR_PATH_MAX - strlen (tmp_real_path));
+ ZR_PATH_MAX - (strlen (tmp_real_path) + 1));
+
ret = lstat (tmp_real_path, &buf);
if ((flag == GF_GET_DIR_ONLY)
@@ -585,6 +597,16 @@ posix_getdents (call_frame_t *frame, xlator_t *this,
continue;
}
+ if ((!priv->span_devices)
+ && (priv->st_device[0] != buf.st_dev)) {
+ continue;
+ } else {
+ op_ret = posix_scale_st_ino (priv, &buf);
+ if (-1 == op_ret) {
+ continue;
+ }
+ }
+
tmp = CALLOC (1, sizeof (*tmp));
if (!tmp) {
@@ -612,15 +634,7 @@ posix_getdents (call_frame_t *frame, xlator_t *this,
strcpy (&entry_path[real_path_len+1], tmp->name);
- ret = lstat (entry_path, &tmp->buf);
-
- if (ret == -1) {
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "lstat on %s failed: %s",
- entry_path, strerror (op_errno));
- goto out;
- }
+ tmp->buf = buf;
if (S_ISLNK(tmp->buf.st_mode)) {
@@ -774,13 +788,14 @@ int32_t
posix_mknod (call_frame_t *frame, xlator_t *this,
loc_t *loc, mode_t mode, dev_t dev)
{
- int tmp_fd = 0;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = 0;
- struct stat stbuf = { 0, };
-
- gid_t gid = 0;
+ int tmp_fd = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = 0;
+ struct stat stbuf = { 0, };
+ char was_present = 1;
+ struct posix_private *priv = NULL;
+ gid_t gid = 0;
DECLARE_OLD_FS_ID_VAR;
@@ -788,10 +803,18 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
MAKE_REAL_PATH (real_path, this, loc->path);
gid = frame->root->gid;
+ op_ret = lstat (real_path, &stbuf);
+ if ((op_ret == -1) && (errno == ENOENT)){
+ was_present = 0;
+ }
+
op_ret = setgid_override (real_path, &gid);
if (op_ret < 0)
goto out;
@@ -830,7 +853,6 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
#endif
op_ret = lstat (real_path, &stbuf);
-
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -839,6 +861,25 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (!priv->span_devices) {
+ if (priv->st_device[0] != stbuf.st_dev) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: different mountpoint/device, returning "
+ "EPERM", loc->path);
+ goto out;
+ }
+ } else {
+ op_ret = posix_scale_st_ino (priv, &stbuf);
+ if (-1 == op_ret) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: from different mountpoint",
+ loc->path);
+ goto out;
+ }
+ }
+
op_ret = 0;
out:
@@ -846,6 +887,10 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
+ if ((op_ret == -1) && (!was_present)) {
+ unlink (real_path);
+ }
+
return 0;
}
@@ -853,12 +898,13 @@ int32_t
posix_mkdir (call_frame_t *frame, xlator_t *this,
loc_t *loc, mode_t mode)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = NULL;
- struct stat stbuf = {0, };
-
- gid_t gid = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = NULL;
+ struct stat stbuf = {0, };
+ char was_present = 1;
+ struct posix_private *priv = NULL;
+ gid_t gid = 0;
DECLARE_OLD_FS_ID_VAR;
@@ -866,10 +912,18 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
MAKE_REAL_PATH (real_path, this, loc->path);
gid = frame->root->gid;
+ op_ret = lstat (real_path, &stbuf);
+ if ((op_ret == -1) && (errno == ENOENT)) {
+ was_present = 0;
+ }
+
op_ret = setgid_override (real_path, &gid);
if (op_ret < 0)
goto out;
@@ -905,6 +959,25 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (!priv->span_devices) {
+ if (priv->st_device[0] != stbuf.st_dev) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: different mountpoint/device, returning "
+ "EPERM", loc->path);
+ goto out;
+ }
+ } else {
+ op_ret = posix_scale_st_ino (priv, &stbuf);
+ if (-1 == op_ret) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: from different mountpoint",
+ loc->path);
+ goto out;
+ }
+ }
+
op_ret = 0;
out:
@@ -912,6 +985,10 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
+ if ((op_ret == -1) && (!was_present)) {
+ unlink (real_path);
+ }
+
return 0;
}
@@ -1016,12 +1093,13 @@ int32_t
posix_symlink (call_frame_t *frame, xlator_t *this,
const char *linkname, loc_t *loc)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = 0;
- struct stat stbuf = { 0, };
-
- gid_t gid = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char * real_path = 0;
+ struct stat stbuf = { 0, };
+ struct posix_private *priv = NULL;
+ gid_t gid = 0;
+ char was_present = 1;
DECLARE_OLD_FS_ID_VAR;
@@ -1030,8 +1108,16 @@ posix_symlink (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (linkname, out);
VALIDATE_OR_GOTO (loc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
MAKE_REAL_PATH (real_path, this, loc->path);
+ op_ret = lstat (real_path, &stbuf);
+ if ((op_ret == -1) && (errno == ENOENT)){
+ was_present = 0;
+ }
+
gid = frame->root->gid;
op_ret = setgid_override (real_path, &gid);
@@ -1069,6 +1155,25 @@ posix_symlink (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (!priv->span_devices) {
+ if (priv->st_device[0] != stbuf.st_dev) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: different mountpoint/device, returning "
+ "EPERM", loc->path);
+ goto out;
+ }
+ } else {
+ op_ret = posix_scale_st_ino (priv, &stbuf);
+ if (-1 == op_ret) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: from different mountpoint",
+ loc->path);
+ goto out;
+ }
+ }
+
op_ret = 0;
out:
@@ -1076,6 +1181,10 @@ posix_symlink (call_frame_t *frame, xlator_t *this,
STACK_UNWIND (frame, op_ret, op_errno, loc->inode, &stbuf);
+ if ((op_ret == -1) && (!was_present)) {
+ unlink (real_path);
+ }
+
return 0;
}
@@ -1084,11 +1193,13 @@ int
posix_rename (call_frame_t *frame, xlator_t *this,
loc_t *oldloc, loc_t *newloc)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_oldpath = NULL;
- char * real_newpath = NULL;
- struct stat stbuf = {0, };
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_oldpath = NULL;
+ char *real_newpath = NULL;
+ struct stat stbuf = {0, };
+ struct posix_private *priv = NULL;
+ char was_present = 1;
DECLARE_OLD_FS_ID_VAR;
@@ -1097,10 +1208,18 @@ posix_rename (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (oldloc, out);
VALIDATE_OR_GOTO (newloc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
SET_FS_ID (frame->root->uid, frame->root->gid);
MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
MAKE_REAL_PATH (real_newpath, this, newloc->path);
+ op_ret = lstat (real_newpath, &stbuf);
+ if ((op_ret == -1) && (errno == ENOENT)){
+ was_present = 0;
+ }
+
op_ret = rename (real_oldpath, real_newpath);
if (op_ret == -1) {
op_errno = errno;
@@ -1120,6 +1239,25 @@ posix_rename (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (!priv->span_devices) {
+ if (priv->st_device[0] != stbuf.st_dev) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: different mountpoint/device, returning "
+ "EPERM", newloc->path);
+ goto out;
+ }
+ } else {
+ op_ret = posix_scale_st_ino (priv, &stbuf);
+ if (-1 == op_ret) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: from different mountpoint",
+ newloc->path);
+ goto out;
+ }
+ }
+
op_ret = 0;
out:
@@ -1127,6 +1265,10 @@ posix_rename (call_frame_t *frame, xlator_t *this,
STACK_UNWIND (frame, op_ret, op_errno, &stbuf);
+ if ((op_ret == -1) && !was_present) {
+ unlink (real_newpath);
+ }
+
return 0;
}
@@ -1135,12 +1277,13 @@ int
posix_link (call_frame_t *frame, xlator_t *this,
loc_t *oldloc, loc_t *newloc)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_oldpath = 0;
- char * real_newpath = 0;
- struct stat stbuf = {0, };
-
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_oldpath = 0;
+ char *real_newpath = 0;
+ struct stat stbuf = {0, };
+ struct posix_private *priv = NULL;
+ char was_present = 1;
DECLARE_OLD_FS_ID_VAR;
@@ -1149,10 +1292,18 @@ posix_link (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (oldloc, out);
VALIDATE_OR_GOTO (newloc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
SET_FS_ID (frame->root->uid, frame->root->gid);
MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
MAKE_REAL_PATH (real_newpath, this, newloc->path);
+ op_ret = lstat (real_newpath, &stbuf);
+ if ((op_ret == -1) && (errno = ENOENT)) {
+ was_present = 0;
+ }
+
op_ret = link (real_oldpath, real_newpath);
if (op_ret == -1) {
op_errno = errno;
@@ -1171,6 +1322,25 @@ posix_link (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (!priv->span_devices) {
+ if (priv->st_device[0] != stbuf.st_dev) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: different mountpoint/device, returning "
+ "EPERM", newloc->path);
+ goto out;
+ }
+ } else {
+ op_ret = posix_scale_st_ino (priv, &stbuf);
+ if (-1 == op_ret) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: from different mountpoint",
+ newloc->path);
+ goto out;
+ }
+ }
+
op_ret = 0;
out:
@@ -1178,6 +1348,10 @@ posix_link (call_frame_t *frame, xlator_t *this,
STACK_UNWIND (frame, op_ret, op_errno, oldloc->inode, &stbuf);
+ if ((op_ret == -1) && (!was_present)) {
+ unlink (real_newpath);
+ }
+
return 0;
}
@@ -1186,10 +1360,11 @@ int
posix_chmod (call_frame_t *frame, xlator_t *this,
loc_t *loc, mode_t mode)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = 0;
- struct stat stbuf = {0,};
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = 0;
+ struct stat stbuf = {0,};
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -1197,6 +1372,9 @@ posix_chmod (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
SET_FS_ID (frame->root->uid, frame->root->gid);
MAKE_REAL_PATH (real_path, this, loc->path);
@@ -1210,6 +1388,11 @@ posix_chmod (call_frame_t *frame, xlator_t *this,
real_path, strerror (op_errno));
goto out;
}
+
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &stbuf);
+ }
+
op_ret = 0;
goto out;
}
@@ -1236,6 +1419,10 @@ posix_chmod (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &stbuf);
+ }
+
op_ret = 0;
out:
@@ -1251,10 +1438,11 @@ int
posix_chown (call_frame_t *frame, xlator_t *this,
loc_t *loc, uid_t uid, gid_t gid)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = 0;
- struct stat stbuf = {0,};
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = 0;
+ struct stat stbuf = {0,};
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -1262,6 +1450,9 @@ posix_chown (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
SET_FS_ID (frame->root->uid, frame->root->gid);
MAKE_REAL_PATH (real_path, this, loc->path);
@@ -1283,6 +1474,10 @@ posix_chown (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &stbuf);
+ }
+
op_ret = 0;
out:
@@ -1300,10 +1495,11 @@ posix_truncate (call_frame_t *frame,
loc_t *loc,
off_t offset)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = 0;
- struct stat stbuf = {0,};
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = 0;
+ struct stat stbuf = {0,};
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -1311,6 +1507,9 @@ posix_truncate (call_frame_t *frame,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
SET_FS_ID (frame->root->uid, frame->root->gid);
MAKE_REAL_PATH (real_path, this, loc->path);
@@ -1331,6 +1530,10 @@ posix_truncate (call_frame_t *frame,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &stbuf);
+ }
+
op_ret = 0;
out:
@@ -1346,11 +1549,12 @@ int
posix_utimens (call_frame_t *frame, xlator_t *this,
loc_t *loc, struct timespec ts[2])
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = 0;
- struct stat stbuf = {0,};
- struct timeval tv[2] = {{0,},{0,}};
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = 0;
+ struct stat stbuf = {0,};
+ struct timeval tv[2] = {{0,},{0,}};
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -1358,6 +1562,9 @@ posix_utimens (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
SET_FS_ID (frame->root->uid, frame->root->gid);
MAKE_REAL_PATH (real_path, this, loc->path);
@@ -1388,6 +1595,10 @@ posix_utimens (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &stbuf);
+ }
+
op_ret = 0;
out:
@@ -1403,16 +1614,17 @@ posix_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int32_t _fd = -1;
- int _flags = 0;
- char * real_path = NULL;
- struct stat stbuf = {0, };
- struct posix_fd * pfd = NULL;
- struct posix_private * priv = NULL;
-
- gid_t gid = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ int32_t _fd = -1;
+ int _flags = 0;
+ char * real_path = NULL;
+ struct stat stbuf = {0, };
+ struct posix_fd * pfd = NULL;
+ struct posix_private * priv = NULL;
+ char was_present = 1;
+
+ gid_t gid = 0;
DECLARE_OLD_FS_ID_VAR;
@@ -1423,6 +1635,7 @@ posix_create (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (fd, out);
priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
MAKE_REAL_PATH (real_path, this, loc->path);
@@ -1443,6 +1656,11 @@ posix_create (call_frame_t *frame, xlator_t *this,
_flags = flags | O_CREAT;
}
+ op_ret = lstat (real_path, &stbuf);
+ if ((op_ret == -1) && (errno == ENOENT)) {
+ was_present = 0;
+ }
+
if (priv->o_direct)
_flags |= O_DIRECT;
@@ -1474,6 +1692,25 @@ posix_create (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (!priv->span_devices) {
+ if (priv->st_device[0] != stbuf.st_dev) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: different mountpoint/device, returning "
+ "EPERM", loc->path);
+ goto out;
+ }
+ } else {
+ op_ret = posix_scale_st_ino (priv, &stbuf);
+ if (-1 == op_ret) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: from different mountpoint",
+ loc->path);
+ goto out;
+ }
+ }
+
op_ret = -1;
pfd = CALLOC (1, sizeof (*pfd));
@@ -1496,9 +1733,14 @@ posix_create (call_frame_t *frame, xlator_t *this,
out:
SET_TO_OLD_FS_ID ();
- if ((-1 == op_ret) && (_fd != -1))
+ if ((-1 == op_ret) && (_fd != -1)) {
close (_fd);
+ if (!was_present) {
+ unlink (real_path);
+ }
+ }
+
STACK_UNWIND (frame, op_ret, op_errno, fd, loc->inode, &stbuf);
return 0;
@@ -1508,14 +1750,15 @@ int32_t
posix_open (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, fd_t *fd)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = NULL;
- int32_t _fd = -1;
- struct posix_fd * pfd = NULL;
- struct posix_private * priv = NULL;
-
- gid_t gid = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = NULL;
+ int32_t _fd = -1;
+ struct posix_fd *pfd = NULL;
+ struct posix_private *priv = NULL;
+ char was_present = 1;
+ gid_t gid = 0;
+ struct stat stbuf = {0, };
DECLARE_OLD_FS_ID_VAR;
@@ -1526,6 +1769,7 @@ posix_open (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (fd, out);
priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
MAKE_REAL_PATH (real_path, this, loc->path);
@@ -1538,6 +1782,11 @@ posix_open (call_frame_t *frame, xlator_t *this,
if (priv->o_direct)
flags |= O_DIRECT;
+ op_ret = lstat (real_path, &stbuf);
+ if ((op_ret == -1) && (errno == ENOENT)) {
+ was_present = 0;
+ }
+
_fd = open (real_path, flags, 0);
if (_fd == -1) {
op_errno = errno;
@@ -1575,6 +1824,35 @@ posix_open (call_frame_t *frame, xlator_t *this,
}
#endif
+ if (flags & O_CREAT) {
+ op_ret = lstat (real_path, &stbuf);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_log (this->name, GF_LOG_ERROR, "lstat on (%s) "
+ "failed: %s", real_path, strerror (op_errno));
+ goto out;
+ }
+
+ if (!priv->span_devices) {
+ if (priv->st_device[0] != stbuf.st_dev) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: different mountpoint/device, "
+ "returning EPERM", loc->path);
+ goto out;
+ }
+ } else {
+ op_ret = posix_scale_st_ino (priv, &stbuf);
+ if (-1 == op_ret) {
+ op_errno = EPERM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: from different mountpoint",
+ loc->path);
+ goto out;
+ }
+ }
+ }
+
op_ret = 0;
out:
@@ -1618,6 +1896,7 @@ posix_readv (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this->private, out);
priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
ret = fd_ctx_get (fd, this, &tmp_pfd);
if (ret < 0) {
@@ -1689,7 +1968,11 @@ posix_readv (call_frame_t *frame, xlator_t *this,
strerror (op_errno));
goto out;
}
-
+
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &stbuf);
+ }
+
op_ret = vec.iov_len;
out:
@@ -1828,6 +2111,10 @@ posix_writev (call_frame_t *frame, xlator_t *this,
fd, strerror (op_errno));
goto out;
}
+
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &stbuf);
+ }
}
out:
@@ -2993,13 +3280,14 @@ int32_t
posix_ftruncate (call_frame_t *frame, xlator_t *this,
fd_t *fd, off_t offset)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int _fd = -1;
- struct stat buf = {0,};
- struct posix_fd * pfd = NULL;
- int ret = -1;
- uint64_t tmp_pfd = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ int _fd = -1;
+ struct stat buf = {0,};
+ struct posix_fd *pfd = NULL;
+ int ret = -1;
+ uint64_t tmp_pfd = 0;
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
SET_FS_ID (frame->root->uid, frame->root->gid);
@@ -3008,6 +3296,9 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
ret = fd_ctx_get (fd, this, &tmp_pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -3037,6 +3328,10 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &buf);
+ }
+
op_ret = 0;
out:
@@ -3051,13 +3346,14 @@ int32_t
posix_fchown (call_frame_t *frame, xlator_t *this,
fd_t *fd, uid_t uid, gid_t gid)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int _fd = -1;
- struct stat buf = {0,};
- struct posix_fd * pfd = NULL;
- int ret = -1;
- uint64_t tmp_pfd = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ int _fd = -1;
+ struct stat buf = {0,};
+ struct posix_fd *pfd = NULL;
+ int ret = -1;
+ uint64_t tmp_pfd = 0;
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -3067,6 +3363,9 @@ posix_fchown (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
ret = fd_ctx_get (fd, this, &tmp_pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -3094,6 +3393,10 @@ posix_fchown (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &buf);
+ }
+
op_ret = 0;
out:
@@ -3109,13 +3412,14 @@ int32_t
posix_fchmod (call_frame_t *frame, xlator_t *this,
fd_t *fd, mode_t mode)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int _fd = -1;
- struct stat buf = {0,};
- struct posix_fd * pfd = NULL;
- int ret = -1;
- uint64_t tmp_pfd = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ int _fd = -1;
+ struct stat buf = {0,};
+ struct posix_fd *pfd = NULL;
+ int ret = -1;
+ uint64_t tmp_pfd = 0;
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -3125,6 +3429,9 @@ posix_fchmod (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
ret = fd_ctx_get (fd, this, &tmp_pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -3154,6 +3461,10 @@ posix_fchmod (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &buf);
+ }
+
op_ret = 0;
out:
@@ -3463,13 +3774,14 @@ int32_t
posix_fstat (call_frame_t *frame, xlator_t *this,
fd_t *fd)
{
- int _fd = -1;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- struct stat buf = {0,};
- struct posix_fd * pfd = NULL;
- uint64_t tmp_pfd = 0;
- int ret = -1;
+ int _fd = -1;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ struct stat buf = {0,};
+ struct posix_fd *pfd = NULL;
+ uint64_t tmp_pfd = 0;
+ int ret = -1;
+ struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
SET_FS_ID (frame->root->uid, frame->root->gid);
@@ -3478,6 +3790,9 @@ posix_fstat (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
ret = fd_ctx_get (fd, this, &tmp_pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_DEBUG,
@@ -3490,7 +3805,6 @@ posix_fstat (call_frame_t *frame, xlator_t *this,
_fd = pfd->fd;
op_ret = fstat (_fd, &buf);
-
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR, "fstat failed on fd=%p: %s",
@@ -3498,6 +3812,10 @@ posix_fstat (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &buf);
+ }
+
op_ret = 0;
out:
@@ -3582,31 +3900,35 @@ 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);
VALIDATE_OR_GOTO (fd, out);
+ priv = this->private;
+ VALIDATE_OR_GOTO (priv, out);
+
INIT_LIST_HEAD (&entries.list);
ret = fd_ctx_get (fd, this, &tmp_pfd);
@@ -3682,6 +4004,23 @@ posix_readdir (call_frame_t *frame, xlator_t *this,
break;
}
+ strcpy (entry_path + real_path_len + 1, entry->d_name);
+
+ ret = lstat (entry_path, &stbuf);
+ if (ret == -1) {
+ continue;
+ }
+
+ if (!priv->span_devices
+ && (priv->st_device[0] != stbuf.st_dev)) {
+ continue;
+ } else {
+ op_ret = posix_scale_st_ino (priv, &stbuf);
+ if (-1 == op_ret) {
+ continue;
+ }
+ }
+
this_size = dirent_size (entry);
if (this_size + filled > size) {
@@ -3689,7 +4028,6 @@ posix_readdir (call_frame_t *frame, xlator_t *this,
break;
}
-
this_entry = gf_dirent_for_name (entry->d_name);
if (!this_entry) {
@@ -3700,14 +4038,12 @@ posix_readdir (call_frame_t *frame, xlator_t *this,
}
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);
filled += this_size;
count ++;
-
- strcpy (entry_path + real_path_len + 1, this_entry->d_name);
- lstat (entry_path, &this_entry->d_stat);
}
op_ret = count;