diff options
| author | Anand V. Avati <avati@blackhole.gluster.com> | 2009-10-16 07:30:26 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2009-10-16 06:22:21 -0700 | 
| commit | d56c6a81ba22e5caca68bfa6fc0eb5f3079c9d22 (patch) | |
| tree | e55f4a7be201ca265c0827baac865c7b3e757cf9 /xlators/storage/posix/src | |
| parent | 355150088d688fafd82c54af80a583a26732d0da (diff) | |
posix - generation number support
- use sequential gen counter
- move span_devices handling and generation assignment to common functions
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 315 (generation number support)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=315
Diffstat (limited to 'xlators/storage/posix/src')
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 516 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.h | 7 | 
2 files changed, 229 insertions, 294 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 3bd7fe025e3..87bf755cff6 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -192,32 +192,6 @@ _posix_xattr_get_set (dict_t *xattr_req,  } -dict_t * -posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc, -    			 dict_t *xattr_req, struct stat *buf) -{ -    	dict_t     *xattr             = NULL; -    	posix_xattr_filler_t filler   = {0, }; - -    	xattr = get_new_dict(); -    	if (!xattr) { -    		gf_log (this->name, GF_LOG_ERROR, -    			"Out of memory."); -    		goto out; -    	} - -    	filler.this      = this; -    	filler.real_path = real_path; -    	filler.xattr     = xattr; -    	filler.stbuf     = buf; -	filler.loc       = loc; - -    	dict_foreach (xattr_req, _posix_xattr_get_set, &filler); -out: -    	return xattr; -} - -  static int   posix_scale_st_ino (struct posix_private *priv, struct stat *buf)  { @@ -242,11 +216,154 @@ posix_scale_st_ino (struct posix_private *priv, struct stat *buf)          buf->st_ino = temp_ino;          ret = 0; - out: +out:          return ret;  } +int +posix_lstat_with_gen (xlator_t *this, const char *path, struct stat *stbuf_p) +{ +        struct posix_private  *priv    = NULL; +        int                    ret     = 0; +        char                   gen_key[256] = {0, }; +        uint64_t               gen_val_be = 0; +        uint64_t               gen_val = 0; +        struct stat            stbuf = {0, }; + +        priv = this->private; + +        ret = lstat (path, &stbuf); +        if (ret == -1) +                return -1; + +        ret = posix_scale_st_ino (priv, &stbuf); +        if (ret == -1) { +                gf_log (this->name, GF_LOG_WARNING, +                        "Access to %s (on dev %lld) is crossing device (%lld)", +                        path, (unsigned long long) stbuf.st_dev, +                        (unsigned long long) priv->st_device[0]); +                errno = EXDEV; +                return -1; +        } + +        ret = snprintf (gen_key, 1024, "trusted.%s.gen", this->name); + +        if (ret == 1024) +                return -1; + +        ret = sys_lgetxattr (path, gen_key, (void *) &gen_val_be, +                             sizeof (gen_val_be)); +        if (ret == -1) { +                LOCK (&priv->gen_lock); +                { +                        gen_val = ++priv->gen_seq; +                } +                UNLOCK (&priv->gen_lock); + +                gen_val_be = hton64 (gen_val); + +                ret = sys_lsetxattr (path, gen_key, &gen_val_be, +                                     sizeof (gen_val_be), 0); +        } else { +                gen_val = ntoh64 (gen_val_be); +        } + +        if (ret >= 0) { +                stbuf.st_dev = gen_val; +                if (stbuf_p) +                        *stbuf_p = stbuf; +        } + +        return ret; +} + + +int +posix_fstat_with_gen (xlator_t *this, int fd, struct stat *stbuf_p) +{ +        struct posix_private  *priv    = NULL; +        int                    ret     = 0; +        char                   gen_key[256] = {0, }; +        uint64_t               gen_val_be = 0; +        uint64_t               gen_val = 0; +        struct stat            stbuf = {0, }; + +        priv = this->private; + +        ret = fstat (fd, &stbuf); +        if (ret == -1) +                return -1; + +        ret = posix_scale_st_ino (priv, &stbuf); +        if (ret == -1) { +                gf_log (this->name, GF_LOG_WARNING, +                        "Access to fd %d (on dev %lld) is crossing device (%lld)", +                        fd, (unsigned long long) stbuf.st_dev, +                        (unsigned long long) priv->st_device[0]); +                errno = EXDEV; +                return -1; +        } + + +        ret = snprintf (gen_key, 1024, "trusted.%s.gen", this->name); + +        if (ret == 1024) +                return -1; + +        ret = sys_fgetxattr (fd, gen_key, (void *) &gen_val_be, +                             sizeof (gen_val_be)); +        if (ret == -1) { +                LOCK (&priv->gen_lock); +                { +                        gen_val = ++priv->gen_seq; +                } +                UNLOCK (&priv->gen_lock); + +                gen_val_be = hton64 (gen_val); + +                ret = sys_fsetxattr (fd, gen_key, &gen_val_be, +                                     sizeof (gen_val_be), 0); +        } else { +                gen_val = ntoh64 (gen_val_be); +        } + +        if (ret >= 0) { +                stbuf.st_dev = gen_val; +                if (stbuf_p) +                        *stbuf_p = stbuf; +        } + +        return ret; +} + + +dict_t * +posix_lookup_xattr_fill (xlator_t *this, const char *real_path, loc_t *loc, +    			 dict_t *xattr_req, struct stat *buf) +{ +    	dict_t     *xattr             = NULL; +    	posix_xattr_filler_t filler   = {0, }; + +    	xattr = get_new_dict(); +    	if (!xattr) { +    		gf_log (this->name, GF_LOG_ERROR, +    			"Out of memory."); +    		goto out; +    	} + +    	filler.this      = this; +    	filler.real_path = real_path; +    	filler.xattr     = xattr; +    	filler.stbuf     = buf; +	filler.loc       = loc; + +    	dict_foreach (xattr_req, _posix_xattr_get_set, &filler); +out: +    	return xattr; +} + +  /*   * If the parent directory of {real_path} has the setgid bit set,   * then set {gid} to the gid of the parent. Otherwise, @@ -254,7 +371,7 @@ posix_scale_st_ino (struct posix_private *priv, struct stat *buf)   */  int -setgid_override (char *real_path, gid_t *gid) +setgid_override (xlator_t *this, char *real_path, gid_t *gid)  {          char *                 tmp_path     = NULL;          char *                 parent_path  = NULL; @@ -272,7 +389,7 @@ setgid_override (char *real_path, gid_t *gid)          parent_path = dirname (tmp_path); -        op_ret = lstat (parent_path, &parent_stbuf); +        op_ret = posix_lstat_with_gen (this, parent_path, &parent_stbuf);          if (op_ret == -1) {                  op_ret = -errno; @@ -323,7 +440,7 @@ posix_lookup (call_frame_t *frame, xlator_t *this,          priv = this->private; -        op_ret   = lstat (real_path, &buf); +        op_ret   = posix_lstat_with_gen (this, real_path, &buf);          op_errno = errno;          if (op_ret == -1) { @@ -337,47 +454,26 @@ posix_lookup (call_frame_t *frame, xlator_t *this,                  goto parent;          } -	/* Make sure we don't access another mountpoint inside export dir. -	 * It may cause inode number to repeat from single export point, -	 * which leads to severe problems.. -	 */ -        if (!priv->span_devices) { -                if (priv->st_device[0] != buf.st_dev) { -                        op_errno = ENOENT; -                        gf_log (this->name, GF_LOG_ERROR, -                                "%s: different mountpoint/device, returning " -                                "ENOENT", loc->path); -                        goto out; -                } -        } else { -                op_ret = posix_scale_st_ino (priv, &buf); -                if (-1 == op_ret) { -                        op_errno = ENOENT; -                        gf_log (this->name, GF_LOG_ERROR, -                                "%s: from different mountpoint", -                                loc->path); -                        goto out; -                } -        } -          if (xattr_req && (op_ret == 0)) {  		xattr = posix_lookup_xattr_fill (this, real_path, loc,  						 xattr_req, &buf);          }  parent: -        pathdup = strdup (real_path); -        GF_VALIDATE_OR_GOTO (this->name, pathdup, out); +        if (loc->parent) { +                pathdup = strdup (real_path); +                GF_VALIDATE_OR_GOTO (this->name, pathdup, out); -        parentpath = dirname (pathdup); +                parentpath = dirname (pathdup); -        op_ret = lstat (parentpath, &postparent); -        if (op_ret == -1) { -                op_errno = errno; -                gf_log (this->name, GF_LOG_ERROR, -                        "post-operation lstat on parent of %s failed: %s", -                        loc->path, strerror (op_errno)); -                goto out; +                op_ret = posix_lstat_with_gen (this, parentpath, &postparent); +                if (op_ret == -1) { +                        op_errno = errno; +                        gf_log (this->name, GF_LOG_ERROR, +                                "post-operation lstat on parent of %s failed: %s", +                                loc->path, strerror (op_errno)); +                        goto out; +                }          }          op_ret = entry_ret; @@ -421,7 +517,7 @@ posix_stat (call_frame_t *frame,          SET_FS_ID (frame->root->uid, frame->root->gid);          MAKE_REAL_PATH (real_path, this, loc->path); -        op_ret = lstat (real_path, &buf); +        op_ret = posix_lstat_with_gen (this, real_path, &buf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -430,10 +526,6 @@ posix_stat (call_frame_t *frame,                  goto out;          } -        if (priv->span_devices) { -                posix_scale_st_ino (priv, &buf); -        } -          op_ret = 0;   out: @@ -516,7 +608,7 @@ posix_setattr (call_frame_t *frame, xlator_t *this,          SET_FS_ID (frame->root->uid, frame->root->gid);          MAKE_REAL_PATH (real_path, this, loc->path); -        op_ret = lstat (real_path, &statpre); +        op_ret = posix_lstat_with_gen (this, real_path, &statpre);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -558,7 +650,7 @@ posix_setattr (call_frame_t *frame, xlator_t *this,                  }          } -        op_ret = lstat (real_path, &statpost); +        op_ret = posix_lstat_with_gen (this, real_path, &statpost);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -645,7 +737,7 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this,          }  	pfd = (struct posix_fd *)(long)tmp_pfd; -        op_ret = fstat (pfd->fd, &statpre); +        op_ret = posix_fstat_with_gen (this, pfd->fd, &statpre);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -688,7 +780,7 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this,                  }          } -        op_ret = fstat (pfd->fd, &statpost); +        op_ret = posix_fstat_with_gen (this, pfd->fd, &statpost);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -886,23 +978,13 @@ posix_getdents (call_frame_t *frame, xlator_t *this,                  strncat (tmp_real_path, dirent->d_name,                           ZR_PATH_MAX - (strlen (tmp_real_path) + 1)); -                ret = lstat (tmp_real_path, &buf); +                ret = posix_lstat_with_gen (this, tmp_real_path, &buf);                  if ((flag == GF_GET_DIR_ONLY)                      && (ret != -1 && !S_ISDIR(buf.st_mode))) {                          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) { @@ -1074,7 +1156,7 @@ posix_readlink (call_frame_t *frame, xlator_t *this,          dest[op_ret] = 0; -        op_ret = lstat (real_path, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &stbuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1121,12 +1203,12 @@ posix_mknod (call_frame_t *frame, xlator_t *this,          gid = frame->root->gid; -        op_ret = lstat (real_path, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &stbuf);          if ((op_ret == -1) && (errno == ENOENT)){                  was_present = 0;          } -        op_ret = setgid_override (real_path, &gid); +        op_ret = setgid_override (this, real_path, &gid);          if (op_ret < 0)                  goto out; @@ -1136,7 +1218,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this,          parentpath = dirname (pathdup); -        op_ret = lstat (parentpath, &preparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &preparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1176,7 +1258,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this,          }  #endif -        op_ret = lstat (real_path, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &stbuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1185,26 +1267,7 @@ 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 = lstat (parentpath, &postparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &postparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1260,12 +1323,12 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,          gid = frame->root->gid; -        op_ret = lstat (real_path, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &stbuf);          if ((op_ret == -1) && (errno == ENOENT)) {                  was_present = 0;          } -        op_ret = setgid_override (real_path, &gid); +        op_ret = setgid_override (this, real_path, &gid);          if (op_ret < 0)                  goto out; @@ -1275,7 +1338,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,          parentpath = dirname (pathdup); -        op_ret = lstat (parentpath, &preparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &preparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1304,7 +1367,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,          }  #endif -        op_ret = lstat (real_path, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &stbuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1313,26 +1376,7 @@ 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 = lstat (parentpath, &postparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &postparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1388,7 +1432,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this,          parentpath = dirname (pathdup); -        op_ret = lstat (parentpath, &preparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &preparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1421,7 +1465,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this,                  goto out;          } -        op_ret = lstat (parentpath, &postparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &postparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1474,7 +1518,7 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,          parentpath = dirname (pathdup); -        op_ret = lstat (parentpath, &preparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &preparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1500,7 +1544,7 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,          if (op_ret == -1)                  goto out; -        op_ret = lstat (parentpath, &postparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &postparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1549,14 +1593,14 @@ posix_symlink (call_frame_t *frame, xlator_t *this,          MAKE_REAL_PATH (real_path, this, loc->path); -        op_ret = lstat (real_path, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &stbuf);          if ((op_ret == -1) && (errno == ENOENT)){                  was_present = 0;          }          gid = frame->root->gid; -        op_ret = setgid_override (real_path, &gid); +        op_ret = setgid_override (this, real_path, &gid);          if (op_ret < 0)                  goto out; @@ -1566,7 +1610,7 @@ posix_symlink (call_frame_t *frame, xlator_t *this,          parentpath = dirname (pathdup); -        op_ret = lstat (parentpath, &preparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &preparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1595,7 +1639,7 @@ posix_symlink (call_frame_t *frame, xlator_t *this,                  goto out;          }  #endif -        op_ret = lstat (real_path, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &stbuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1604,26 +1648,7 @@ 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 = lstat (parentpath, &postparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &postparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1690,7 +1715,7 @@ posix_rename (call_frame_t *frame, xlator_t *this,          oldparentpath = dirname (oldpathdup); -        op_ret = lstat (oldparentpath, &preoldparent); +        op_ret = posix_lstat_with_gen (this, oldparentpath, &preoldparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1704,7 +1729,7 @@ posix_rename (call_frame_t *frame, xlator_t *this,          newparentpath = dirname (newpathdup); -        op_ret = lstat (newparentpath, &prenewparent); +        op_ret = posix_lstat_with_gen (this, newparentpath, &prenewparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1713,7 +1738,7 @@ posix_rename (call_frame_t *frame, xlator_t *this,                  goto out;          } -        op_ret = lstat (real_newpath, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_newpath, &stbuf);          if ((op_ret == -1) && (errno == ENOENT)){                  was_present = 0;          } @@ -1728,7 +1753,7 @@ posix_rename (call_frame_t *frame, xlator_t *this,                  goto out;          } -        op_ret = lstat (real_newpath, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_newpath, &stbuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1737,26 +1762,7 @@ 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 = lstat (oldparentpath, &postoldparent); +        op_ret = posix_lstat_with_gen (this, oldparentpath, &postoldparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1765,7 +1771,7 @@ posix_rename (call_frame_t *frame, xlator_t *this,                  goto out;          } -        op_ret = lstat (newparentpath, &postnewparent); +        op_ret = posix_lstat_with_gen (this, newparentpath, &postnewparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1828,7 +1834,7 @@ posix_link (call_frame_t *frame, xlator_t *this,          MAKE_REAL_PATH (real_oldpath, this, oldloc->path);          MAKE_REAL_PATH (real_newpath, this, newloc->path); -        op_ret = lstat (real_newpath, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_newpath, &stbuf);          if ((op_ret == -1) && (errno = ENOENT)) {                  was_present = 0;          } @@ -1841,7 +1847,7 @@ posix_link (call_frame_t *frame, xlator_t *this,          }          newparentpath = dirname (newpathdup); -        op_ret = lstat (newparentpath, &preparent); +        op_ret = posix_lstat_with_gen (this, newparentpath, &preparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, "lstat failed: %s: %s", @@ -1858,7 +1864,7 @@ posix_link (call_frame_t *frame, xlator_t *this,                  goto out;          } -        op_ret = lstat (real_newpath, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_newpath, &stbuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1867,7 +1873,7 @@ posix_link (call_frame_t *frame, xlator_t *this,                  goto out;          } -        op_ret = lstat (newparentpath, &postparent); +        op_ret = posix_lstat_with_gen (this, newparentpath, &postparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, "lstat failed: %s: %s", @@ -1875,25 +1881,6 @@ 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: @@ -1921,7 +1908,6 @@ posix_truncate (call_frame_t *frame,          int32_t               op_ret    = -1;          int32_t               op_errno  = 0;          char                 *real_path = 0; -        struct stat           stbuf     = {0,};          struct posix_private *priv      = NULL;          struct stat           prebuf    = {0,};          struct stat           postbuf   = {0,}; @@ -1938,7 +1924,7 @@ posix_truncate (call_frame_t *frame,          SET_FS_ID (frame->root->uid, frame->root->gid);          MAKE_REAL_PATH (real_path, this, loc->path); -        op_ret = lstat (real_path, &prebuf); +        op_ret = posix_lstat_with_gen (this, real_path, &prebuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -1956,7 +1942,7 @@ posix_truncate (call_frame_t *frame,                  goto out;          } -        op_ret = lstat (real_path, &postbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &postbuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, "lstat on %s failed: %s", @@ -1964,10 +1950,6 @@ posix_truncate (call_frame_t *frame,                  goto out;          } -        if (priv->span_devices) { -                posix_scale_st_ino (priv, &stbuf); -        } -          op_ret = 0;   out: @@ -2016,7 +1998,7 @@ posix_create (call_frame_t *frame, xlator_t *this,          gid = frame->root->gid; -        op_ret = setgid_override (real_path, &gid); +        op_ret = setgid_override (this, real_path, &gid);          if (op_ret < 0) {                  goto out; @@ -2028,7 +2010,7 @@ posix_create (call_frame_t *frame, xlator_t *this,          parentpath = dirname (pathdup); -        op_ret = lstat (parentpath, &preparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &preparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -2044,7 +2026,7 @@ posix_create (call_frame_t *frame, xlator_t *this,                  _flags = flags | O_CREAT;          } -        op_ret = lstat (real_path, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &stbuf);          if ((op_ret == -1) && (errno == ENOENT)) {                  was_present = 0;          } @@ -2072,7 +2054,7 @@ posix_create (call_frame_t *frame, xlator_t *this,          }  #endif -        op_ret = fstat (_fd, &stbuf); +        op_ret = posix_fstat_with_gen (this, _fd, &stbuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -2080,26 +2062,7 @@ 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 = lstat (parentpath, &postparent); +        op_ret = posix_lstat_with_gen (this, parentpath, &postparent);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -2177,7 +2140,7 @@ posix_open (call_frame_t *frame, xlator_t *this,          MAKE_REAL_PATH (real_path, this, loc->path); -        op_ret = setgid_override (real_path, &gid); +        op_ret = setgid_override (this, real_path, &gid);          if (op_ret < 0)                  goto out; @@ -2186,7 +2149,7 @@ posix_open (call_frame_t *frame, xlator_t *this,          if (priv->o_direct)                  flags |= O_DIRECT; -        op_ret = lstat (real_path, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_path, &stbuf);          if ((op_ret == -1) && (errno == ENOENT)) {                  was_present = 0;          } @@ -2229,32 +2192,13 @@ posix_open (call_frame_t *frame, xlator_t *this,  #endif          if (flags & O_CREAT) { -                op_ret = lstat (real_path, &stbuf); +                op_ret = posix_lstat_with_gen (this, 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; -                        } -                }          }          LOCK (&priv->lock); @@ -2374,7 +2318,7 @@ posix_readv (call_frame_t *frame, xlator_t *this,           *  we read from           */ -        op_ret = fstat (_fd, &stbuf); +        op_ret = posix_fstat_with_gen (this, _fd, &stbuf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -2383,12 +2327,8 @@ posix_readv (call_frame_t *frame, xlator_t *this,                  goto out;          } -        if (priv->span_devices) { -                posix_scale_st_ino (priv, &stbuf); -        } -  	op_ret = vec.iov_len; - out: +out:          STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno,                               &vec, 1, &stbuf, iobref); @@ -2445,7 +2385,7 @@ posix_writev (call_frame_t *frame, xlator_t *this,          _fd = pfd->fd; -        op_ret = fstat (_fd, &preop); +        op_ret = posix_fstat_with_gen (this, _fd, &preop);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -2538,7 +2478,7 @@ posix_writev (call_frame_t *frame, xlator_t *this,                          fsync (_fd);                  } -                ret = fstat (_fd, &postop); +                ret = posix_fstat_with_gen (this, _fd, &postop);                  if (ret == -1) {  			op_ret = -1;                          op_errno = errno; @@ -2547,11 +2487,6 @@ posix_writev (call_frame_t *frame, xlator_t *this,                                  fd, strerror (op_errno));                          goto out;                  } - -                if (priv->span_devices) { -                        posix_scale_st_ino (priv, &preop); -                        posix_scale_st_ino (priv, &postop); -                }          }   out: @@ -2747,7 +2682,7 @@ posix_fsync (call_frame_t *frame, xlator_t *this,          _fd = pfd->fd; -        op_ret = fstat (_fd, &preop); +        op_ret = posix_fstat_with_gen (this, _fd, &preop);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_DEBUG, @@ -2772,7 +2707,7 @@ posix_fsync (call_frame_t *frame, xlator_t *this,                  }          } -        op_ret = fstat (_fd, &postop); +        op_ret = posix_fstat_with_gen (this, _fd, &postop);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_DEBUG, @@ -2978,7 +2913,7 @@ get_file_contents (xlator_t *this, char *real_path,          key = (char *) &(name[15]);          sprintf (real_filepath, "%s/%s", real_path, key); -        op_ret = lstat (real_filepath, &stbuf); +        op_ret = posix_lstat_with_gen (this, real_filepath, &stbuf);          if (op_ret == -1) {                  op_ret = -errno;                  gf_log (this->name, GF_LOG_ERROR, "lstat failed on %s: %s", @@ -3789,7 +3724,7 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this,          _fd = pfd->fd; -        op_ret = fstat (_fd, &preop); +        op_ret = posix_fstat_with_gen (this, _fd, &preop);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -3808,7 +3743,7 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this,                  goto out;          } -        op_ret = fstat (_fd, &postop); +        op_ret = posix_fstat_with_gen (this, _fd, &postop);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -3817,11 +3752,6 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this,                  goto out;          } -        if (priv->span_devices) { -                posix_scale_st_ino (priv, &preop); -                posix_scale_st_ino (priv, &postop); -        } -          op_ret = 0;   out: @@ -3847,7 +3777,7 @@ ensure_file_type (xlator_t *this, char *pathname, mode_t mode)          int         op_ret = 0;          int         ret    = -1; -        ret = lstat (pathname, &stbuf); +        ret = posix_lstat_with_gen (this, pathname, &stbuf);          if (ret == -1) {                  op_ret = -errno;                  gf_log (this->name, GF_LOG_ERROR, @@ -4161,7 +4091,7 @@ posix_fstat (call_frame_t *frame, xlator_t *this,          _fd = pfd->fd; -        op_ret = fstat (_fd, &buf); +        op_ret = posix_fstat_with_gen (this, _fd, &buf);          if (op_ret == -1) {                  op_errno = errno;                  gf_log (this->name, GF_LOG_ERROR, "fstat failed on fd=%p: %s", @@ -4169,13 +4099,9 @@ 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: +out:          SET_TO_OLD_FS_ID ();          STACK_UNWIND_STRICT (fstat, frame, op_ret, op_errno, &buf); @@ -4371,8 +4297,7 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this,                   */                  if ((whichop == GF_FOP_READDIRP) || (priv->span_devices)) {                          strcpy (entry_path + real_path_len + 1, entry->d_name); -                        lstat (entry_path, &stbuf); -                        op_ret = posix_scale_st_ino (priv, &stbuf); +                        op_ret = posix_lstat_with_gen (this, entry_path, &stbuf);                          if (-1 == op_ret)                                  continue;                  } else @@ -4583,7 +4508,7 @@ posix_checksum (call_frame_t *frame, xlator_t *this,                  strcpy (tmp_real_path, real_path);                  strcat (tmp_real_path, "/");                  strcat (tmp_real_path, dirent->d_name); -                ret = lstat (tmp_real_path, &buf); +                ret = posix_lstat_with_gen (this, tmp_real_path, &buf);                  if (ret == -1)                          continue; @@ -4917,6 +4842,9 @@ init (xlator_t *this)          /* Start with the base */          _private->st_device[0] = buf.st_dev; +        LOCK_INIT (&_private->gen_lock); +        _private->gen_seq = (time (NULL) << 32); +  #ifndef GF_DARWIN_HOST_OS          {                  struct rlimit lim; diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 156bad85ae5..b16800c5c93 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -29,6 +29,7 @@  #include <unistd.h>  #include <sys/types.h>  #include <dirent.h> +#include <time.h>  #ifdef linux  #ifdef __GLIBC__ @@ -107,6 +108,12 @@ struct posix_private {          int             num_devices_to_span;          dev_t          *st_device; + +/* a global generation number sequence is used to assign generation numbers in  +   sequence. +*/ +        uint64_t        gen_seq; +        gf_lock_t       gen_lock;  };  #define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path)  | 
