From ece4e80b2d2326aa5fadc46c866947c9644622a7 Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Tue, 15 Sep 2009 01:15:14 +0000 Subject: 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 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 --- xlators/storage/posix/src/posix.c | 579 +++++++++++++++++++++++++++++--------- 1 file changed, 446 insertions(+), 133 deletions(-) diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 2d6673e64e5..ef68aa72e3f 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: -- cgit