diff options
Diffstat (limited to 'xlators/storage/posix/src/posix.c')
-rw-r--r-- | xlators/storage/posix/src/posix.c | 596 |
1 files changed, 265 insertions, 331 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index d022e4c287f..c4f47049c7e 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -416,6 +416,269 @@ posix_stat (call_frame_t *frame, return 0; } +static int +posix_do_chmod (xlator_t *this, + const char *path, + struct stat *stbuf) +{ + int32_t ret = -1; + + ret = chmod (path, stbuf->st_mode); + if ((ret == -1) && (errno == ENOSYS)) { + ret = chmod (path, stbuf->st_mode); + } + + return ret; +} + +static int +posix_do_chown (xlator_t *this, + const char *path, + struct stat *stbuf, + int32_t valid) +{ + int32_t ret = -1; + uid_t uid = -1; + gid_t gid = -1; + + if (valid & GF_SET_ATTR_UID) + uid = stbuf->st_uid; + + if (valid & GF_SET_ATTR_GID) + gid = stbuf->st_gid; + + ret = chown (path, uid, gid); + + return ret; +} + +static int +posix_do_utimes (xlator_t *this, + const char *path, + struct stat *stbuf) +{ + int32_t ret = -1; + struct timeval tv[2] = {{0,},{0,}}; + + tv[0].tv_sec = stbuf->st_atime; + tv[0].tv_usec = ST_ATIM_NSEC (stbuf) / 1000; + tv[1].tv_sec = stbuf->st_mtime; + tv[1].tv_usec = ST_ATIM_NSEC (stbuf) / 1000; + + ret = utimes (path, tv); + + return ret; +} + +int +posix_setattr (call_frame_t *frame, xlator_t *this, + loc_t *loc, struct stat *stbuf, int32_t valid) +{ + int32_t op_ret = -1; + int32_t op_errno = 0; + char * real_path = 0; + struct stat statpre = {0,}; + struct stat statpost = {0,}; + + DECLARE_OLD_FS_ID_VAR; + + VALIDATE_OR_GOTO (frame, out); + VALIDATE_OR_GOTO (this, out); + VALIDATE_OR_GOTO (loc, out); + + SET_FS_ID (frame->root->uid, frame->root->gid); + MAKE_REAL_PATH (real_path, this, loc->path); + + op_ret = lstat (real_path, &statpre); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "setattr (lstat) on %s failed: %s", real_path, + strerror (op_errno)); + goto out; + } + + if (valid & GF_SET_ATTR_MODE) { + op_ret = posix_do_chmod (this, real_path, stbuf); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "setattr (chmod) on %s failed: %s", real_path, + strerror (op_errno)); + goto out; + } + } + + if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)){ + op_ret = posix_do_chown (this, real_path, stbuf, valid); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "setattr (chown) on %s failed: %s", real_path, + strerror (op_errno)); + goto out; + } + } + + if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { + op_ret = posix_do_utimes (this, real_path, stbuf); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "setattr (utimes) on %s failed: %s", real_path, + strerror (op_errno)); + goto out; + } + } + + op_ret = lstat (real_path, &statpost); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "setattr (lstat) on %s failed: %s", real_path, + strerror (op_errno)); + goto out; + } + + op_ret = 0; + +out: + SET_TO_OLD_FS_ID (); + + STACK_UNWIND (frame, op_ret, op_errno, &statpre, &statpost); + + return 0; +} + +int32_t +posix_do_fchown (xlator_t *this, + int fd, + struct stat *stbuf, + int32_t valid) +{ + int ret = -1; + uid_t uid = -1; + gid_t gid = -1; + + if (valid & GF_SET_ATTR_UID) + uid = stbuf->st_uid; + + if (valid & GF_SET_ATTR_GID) + gid = stbuf->st_gid; + + ret = fchown (fd, uid, gid); + + return ret; +} + + +int32_t +posix_do_fchmod (xlator_t *this, + int fd, struct stat *stbuf) +{ + return fchmod (fd, stbuf->st_mode); +} + +static int +posix_do_futimes (xlator_t *this, + int fd, + struct stat *stbuf) +{ + errno = ENOSYS; + return -1; +} + +int +posix_fsetattr (call_frame_t *frame, xlator_t *this, + fd_t *fd, struct stat *stbuf, int32_t valid) +{ + int32_t op_ret = -1; + int32_t op_errno = 0; + struct stat statpre = {0,}; + struct stat statpost = {0,}; + struct posix_fd *pfd = NULL; + uint64_t tmp_pfd = 0; + int32_t ret = -1; + + DECLARE_OLD_FS_ID_VAR; + + SET_FS_ID (frame->root->uid, frame->root->gid); + + VALIDATE_OR_GOTO (frame, out); + VALIDATE_OR_GOTO (this, out); + VALIDATE_OR_GOTO (fd, out); + + ret = fd_ctx_get (fd, this, &tmp_pfd); + if (ret < 0) { + op_errno = -ret; + gf_log (this->name, GF_LOG_DEBUG, + "pfd is NULL from fd=%p", fd); + goto out; + } + pfd = (struct posix_fd *)(long)tmp_pfd; + + op_ret = fstat (pfd->fd, &statpre); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "fsetattr (fstat) failed on fd=%p: %s", fd, + strerror (op_errno)); + goto out; + } + + if (valid & GF_SET_ATTR_MODE) { + op_ret = posix_do_fchmod (this, pfd->fd, stbuf); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "fsetattr (fchmod) failed on fd=%p: %s", + fd, strerror (op_errno)); + goto out; + } + } + + if (valid & (GF_SET_ATTR_UID | GF_SET_ATTR_GID)) { + op_ret = posix_do_fchown (this, pfd->fd, stbuf, valid); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "fsetattr (fchown) failed on fd=%p: %s", + fd, strerror (op_errno)); + goto out; + } + + } + + if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { + op_ret = posix_do_futimes (this, pfd->fd, stbuf); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "fsetattr (futimes) on failed fd=%p: %s", fd, + strerror (op_errno)); + goto out; + } + } + + op_ret = fstat (pfd->fd, &statpost); + if (op_ret == -1) { + op_errno = errno; + gf_log (this->name, GF_LOG_ERROR, + "fsetattr (fstat) failed on fd=%p: %s", fd, + strerror (op_errno)); + goto out; + } + + op_ret = 0; + +out: + SET_TO_OLD_FS_ID (); + + STACK_UNWIND (frame, op_ret, op_errno, &statpre, &statpost); + + return 0; +} + int32_t posix_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd) @@ -1360,139 +1623,6 @@ posix_link (call_frame_t *frame, xlator_t *this, } -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,}; - struct posix_private *priv = NULL; - - DECLARE_OLD_FS_ID_VAR; - - VALIDATE_OR_GOTO (frame, out); - 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); - - if (S_ISLNK (loc->inode->st_mode)) { - /* chmod on a link should always succeed */ - 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) { - posix_scale_st_ino (priv, &stbuf); - } - - op_ret = 0; - goto out; - } - - op_ret = lchmod (real_path, mode); - if ((op_ret == -1) && (errno == ENOSYS)) { - gf_log (this->name, GF_LOG_TRACE, - "lchmod not implemented, falling back to chmod"); - op_ret = chmod (real_path, mode); - } - - if (op_ret == -1) { - op_errno = errno; - gf_log (this->name, GF_LOG_ERROR, "chmod on %s failed: %s", - loc->path, strerror (op_errno)); - goto out; - } - - 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) { - posix_scale_st_ino (priv, &stbuf); - } - - op_ret = 0; - - out: - SET_TO_OLD_FS_ID (); - - STACK_UNWIND (frame, op_ret, op_errno, &stbuf); - - return 0; -} - - -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,}; - struct posix_private *priv = NULL; - - DECLARE_OLD_FS_ID_VAR; - - VALIDATE_OR_GOTO (frame, out); - 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 = lchown (real_path, uid, gid); - if (op_ret == -1) { - op_errno = errno; - gf_log (this->name, GF_LOG_ERROR, - "lchown on %s failed: %s", - loc->path, strerror (op_errno)); - goto out; - } - - 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) { - posix_scale_st_ino (priv, &stbuf); - } - - op_ret = 0; - - out: - SET_TO_OLD_FS_ID (); - - STACK_UNWIND (frame, op_ret, op_errno, &stbuf); - - return 0; -} - - int32_t posix_truncate (call_frame_t *frame, xlator_t *this, @@ -1549,70 +1679,6 @@ posix_truncate (call_frame_t *frame, } -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,}}; - struct posix_private *priv = NULL; - - DECLARE_OLD_FS_ID_VAR; - - VALIDATE_OR_GOTO (frame, out); - 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); - - tv[0].tv_sec = ts[0].tv_sec; - tv[0].tv_usec = ts[0].tv_nsec / 1000; - tv[1].tv_sec = ts[1].tv_sec; - tv[1].tv_usec = ts[1].tv_nsec / 1000; - - op_ret = lutimes (real_path, tv); - if ((op_ret == -1) && (errno == ENOSYS)) { - op_ret = utimes (real_path, tv); - } - - if (op_ret == -1) { - op_errno = errno; - gf_log (this->name, GF_LOG_ERROR, - "utimes on %s failed: %s", real_path, - strerror (op_errno)); - goto out; - } - - 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) { - posix_scale_st_ino (priv, &stbuf); - } - - op_ret = 0; - - out: - SET_TO_OLD_FS_ID (); - - STACK_UNWIND (frame, op_ret, op_errno, &stbuf); - - return 0; -} - int32_t posix_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, @@ -3382,135 +3448,6 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this, return 0; } -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; - struct posix_private *priv = NULL; - - DECLARE_OLD_FS_ID_VAR; - - SET_FS_ID (frame->root->uid, frame->root->gid); - - VALIDATE_OR_GOTO (frame, out); - 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, - "pfd is NULL, fd=%p", fd); - op_errno = -ret; - goto out; - } - pfd = (struct posix_fd *)(long)tmp_pfd; - - _fd = pfd->fd; - - op_ret = fchown (_fd, uid, gid); - if (op_ret == -1) { - op_errno = errno; - gf_log (this->name, GF_LOG_ERROR, "fchown failed on fd=%p: %s", - fd, strerror (op_errno)); - goto out; - } - - 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", - fd, strerror (op_errno)); - goto out; - } - - if (priv->span_devices) { - posix_scale_st_ino (priv, &buf); - } - - op_ret = 0; - - out: - SET_TO_OLD_FS_ID (); - - STACK_UNWIND (frame, op_ret, op_errno, &buf); - - return 0; -} - - -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; - struct posix_private *priv = NULL; - - DECLARE_OLD_FS_ID_VAR; - - SET_FS_ID (frame->root->uid, frame->root->gid); - - VALIDATE_OR_GOTO (frame, out); - 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, - "pfd is NULL fd=%p", fd); - op_errno = -ret; - goto out; - } - pfd = (struct posix_fd *)(long)tmp_pfd; - - _fd = pfd->fd; - - op_ret = fchmod (_fd, mode); - - if (op_ret == -1) { - op_errno = errno; - gf_log (this->name, GF_LOG_ERROR, - "fchmod failed on fd=%p: %s", fd, strerror (errno)); - goto out; - } - - 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", - fd, strerror (errno)); - goto out; - } - - op_ret = 0; - - out: - SET_TO_OLD_FS_ID (); - - STACK_UNWIND (frame, op_ret, op_errno, &buf); - - return 0; -} - static int same_file_type (mode_t m1, mode_t m2) @@ -4638,10 +4575,7 @@ struct xlator_fops fops = { .symlink = posix_symlink, .rename = posix_rename, .link = posix_link, - .chmod = posix_chmod, - .chown = posix_chown, .truncate = posix_truncate, - .utimens = posix_utimens, .create = posix_create, .open = posix_open, .readv = posix_readv, @@ -4663,14 +4597,14 @@ struct xlator_fops fops = { .finodelk = posix_finodelk, .entrylk = posix_entrylk, .fentrylk = posix_fentrylk, - .fchown = posix_fchown, - .fchmod = posix_fchmod, .setdents = posix_setdents, .getdents = posix_getdents, .checksum = posix_checksum, .rchecksum = posix_rchecksum, .xattrop = posix_xattrop, .fxattrop = posix_fxattrop, + .setattr = posix_setattr, + .fsetattr = posix_fsetattr, }; struct xlator_cbks cbks = { |