diff options
| author | Raghavendra G <raghavendra@gluster.com> | 2009-09-15 01:15:14 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2009-09-15 00:01:54 -0700 | 
| commit | ece4e80b2d2326aa5fadc46c866947c9644622a7 (patch) | |
| tree | a703ebd7a0c666975224498216910f600724ecb9 | |
| parent | a5f0b3d7d1b23053ce9327be91323e92ce554b32 (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
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 579 | 
1 files 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:  | 
