summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2009-09-15 01:15:14 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-09-15 00:01:54 -0700
commitece4e80b2d2326aa5fadc46c866947c9644622a7 (patch)
treea703ebd7a0c666975224498216910f600724ecb9 /xlators/storage/posix
parenta5f0b3d7d1b23053ce9327be91323e92ce554b32 (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')
-rw-r--r--xlators/storage/posix/src/posix.c579
1 files changed, 446 insertions, 133 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 2d6673e64..ef68aa72e 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -374,10 +374,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;
@@ -385,11 +386,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,
@@ -398,6 +401,10 @@ posix_stat (call_frame_t *frame,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &buf);
+ }
+
op_ret = 0;
out:
@@ -492,23 +499,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 ;
@@ -516,6 +524,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);
@@ -579,7 +590,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)
@@ -587,6 +599,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) {
@@ -614,15 +636,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)) {
@@ -776,13 +790,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;
@@ -790,10 +805,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;
@@ -832,7 +855,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,
@@ -841,6 +863,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:
@@ -848,6 +889,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;
}
@@ -855,12 +900,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;
@@ -868,10 +914,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;
@@ -907,6 +961,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:
@@ -914,6 +987,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;
}
@@ -1018,12 +1095,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;
@@ -1032,8 +1110,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);
@@ -1071,6 +1157,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:
@@ -1078,6 +1183,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;
}
@@ -1086,11 +1195,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;
@@ -1099,10 +1210,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;
@@ -1122,6 +1241,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:
@@ -1129,6 +1267,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;
}
@@ -1137,12 +1279,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;
@@ -1151,10 +1294,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;
@@ -1173,6 +1324,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:
@@ -1180,6 +1350,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;
}
@@ -1188,10 +1362,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;
@@ -1199,6 +1374,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);
@@ -1212,6 +1390,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;
}
@@ -1238,6 +1421,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:
@@ -1253,10 +1440,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;
@@ -1264,6 +1452,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);
@@ -1285,6 +1476,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:
@@ -1302,10 +1497,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;
@@ -1313,6 +1509,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);
@@ -1333,6 +1532,10 @@ posix_truncate (call_frame_t *frame,
goto out;
}
+ if (priv->span_devices) {
+ posix_scale_st_ino (priv, &stbuf);
+ }
+
op_ret = 0;
out:
@@ -1348,11 +1551,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;
@@ -1360,6 +1564,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);
@@ -1390,6 +1597,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:
@@ -1405,16 +1616,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;
@@ -1425,6 +1637,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);
@@ -1445,6 +1658,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;
@@ -1476,6 +1694,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));
@@ -1502,9 +1739,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;
@@ -1514,14 +1756,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;
@@ -1532,6 +1775,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);
@@ -1544,6 +1788,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;
@@ -1585,6 +1834,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:
@@ -1628,6 +1906,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) {
@@ -1703,7 +1982,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:
@@ -1846,6 +2129,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:
@@ -2997,9 +3284,9 @@ int
posix_access (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t mask)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = NULL;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = NULL;
DECLARE_OLD_FS_ID_VAR;
SET_FS_ID (frame->root->uid, frame->root->gid);
@@ -3017,7 +3304,6 @@ posix_access (call_frame_t *frame, xlator_t *this,
loc->path, strerror (op_errno));
goto out;
}
-
op_ret = 0;
out:
@@ -3032,13 +3318,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);
@@ -3047,6 +3334,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,
@@ -3076,6 +3366,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:
@@ -3090,13 +3384,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;
@@ -3106,6 +3401,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,
@@ -3133,6 +3431,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:
@@ -3148,13 +3450,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;
@@ -3164,6 +3467,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,
@@ -3502,13 +3808,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);
@@ -3517,6 +3824,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,
@@ -3529,7 +3839,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",
@@ -3537,6 +3846,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: