summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix-entry-ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage/posix/src/posix-entry-ops.c')
-rw-r--r--xlators/storage/posix/src/posix-entry-ops.c75
1 files changed, 71 insertions, 4 deletions
diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c
index 1f1e05f1dc9..8cc3ccf8c00 100644
--- a/xlators/storage/posix/src/posix-entry-ops.c
+++ b/xlators/storage/posix/src/posix-entry-ops.c
@@ -176,6 +176,7 @@ posix_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
struct posix_private *priv = NULL;
posix_inode_ctx_t *ctx = NULL;
int ret = 0;
+ int dfd = -1;
VALIDATE_OR_GOTO(frame, out);
VALIDATE_OR_GOTO(this, out);
@@ -197,6 +198,19 @@ posix_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
goto out;
}
+#ifdef __NetBSD__
+ /* Same for NetBSD's .attribute directory */
+ if (__is_root_gfid(loc->pargfid) && loc->name &&
+ (strcmp(loc->name, ".attribute") == 0)) {
+ gf_msg(this->name, GF_LOG_WARNING, EPERM, P_MSG_LOOKUP_NOT_PERMITTED,
+ "Lookup issued on .attribute,"
+ " which is not permitted");
+ op_errno = EPERM;
+ op_ret = -1;
+ goto out;
+ }
+#endif /* __NetBSD__ */
+
op_ret = dict_get_int32_sizen(xdata, GF_GFIDLESS_LOOKUP, &gfidless);
op_ret = -1;
if (gf_uuid_is_null(loc->pargfid) || (loc->name == NULL)) {
@@ -232,12 +246,12 @@ posix_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
if (!op_errno)
op_errno = ESTALE;
loc_gfid(loc, gfid);
- MAKE_HANDLE_ABSPATH(gfid_path, this, gfid);
- ret = sys_stat(gfid_path, &statbuf);
+ MAKE_HANDLE_ABSPATH_FD(gfid_path, this, gfid, dfd);
+ ret = sys_fstatat(dfd, gfid_path, &statbuf, 0);
if (ret == 0 && ((statbuf.st_mode & S_IFMT) == S_IFDIR))
/*Don't unset if it was a symlink to a dir.*/
goto parent;
- ret = sys_lstat(gfid_path, &statbuf);
+ ret = sys_fstatat(dfd, gfid_path, &statbuf, AT_SYMLINK_NOFOLLOW);
if (ret == 0 && statbuf.st_nlink == 1) {
gf_msg(this->name, GF_LOG_WARNING, op_errno,
P_MSG_HANDLE_DELETE,
@@ -649,6 +663,19 @@ posix_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
goto out;
}
+#ifdef __NetBSD__
+ /* Same for NetBSD's .attribute directory */
+ if (__is_root_gfid(loc->pargfid) &&
+ (strcmp(loc->name, ".attribute") == 0)) {
+ gf_msg(this->name, GF_LOG_WARNING, EPERM, P_MSG_MKDIR_NOT_PERMITTED,
+ "mkdir issued on .attribute, which"
+ "is not permitted");
+ op_errno = EPERM;
+ op_ret = -1;
+ goto out;
+ }
+#endif
+
priv = this->private;
VALIDATE_OR_GOTO(priv, out);
GFID_NULL_CHECK_AND_GOTO(frame, this, loc, xdata, op_ret, op_errno,
@@ -1415,6 +1442,19 @@ posix_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
goto out;
}
+#ifdef __NetBSD__
+ /* Same for NetBSD's .attribute directory */
+ if (__is_root_gfid(loc->pargfid) &&
+ (strcmp(loc->name, ".attribute") == 0)) {
+ gf_msg(this->name, GF_LOG_WARNING, EPERM, P_MSG_RMDIR_NOT_PERMITTED,
+ "rmdir issued on .attribute, which"
+ "is not permitted");
+ op_errno = EPERM;
+ op_ret = -1;
+ goto out;
+ }
+#endif
+
priv = this->private;
MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, &stbuf);
@@ -2145,6 +2185,8 @@ posix_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
0,
};
+ dict_t *xdata_rsp = dict_ref(xdata);
+
DECLARE_OLD_FS_ID_VAR;
VALIDATE_OR_GOTO(frame, out);
@@ -2194,6 +2236,28 @@ posix_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
was_present = 0;
}
+ if (!was_present) {
+ if (posix_is_layout_stale(xdata, par_path, this)) {
+ op_ret = -1;
+ op_errno = EIO;
+ if (!xdata_rsp) {
+ xdata_rsp = dict_new();
+ if (!xdata_rsp) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ if (dict_set_int32_sizen(xdata_rsp, GF_PREOP_CHECK_FAILED, 1) ==
+ -1) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_DICT_SET_FAILED,
+ "setting key %s in dict failed", GF_PREOP_CHECK_FAILED);
+ }
+
+ goto out;
+ }
+ }
+
if (priv->o_direct)
_flags |= O_DIRECT;
@@ -2313,7 +2377,10 @@ out:
STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd,
(loc) ? loc->inode : NULL, &stbuf, &preparent,
- &postparent, xdata);
+ &postparent, xdata_rsp);
+
+ if (xdata_rsp)
+ dict_unref(xdata_rsp);
return 0;
}