From ef8ea2672c14ae19b0ae421cf53a701f89f4f192 Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Thu, 10 Sep 2009 04:36:19 +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 | 642 +++++++++++++++++++++++++++++--------- 1 file changed, 489 insertions(+), 153 deletions(-) (limited to 'xlators/storage/posix/src/posix.c') diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index f5f6803c2..8839c4975 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; -- cgit