summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSusant Palai <spalai@redhat.com>2017-08-22 13:44:52 +0530
committerAmar Tumballi <amarts@redhat.com>2017-12-05 21:23:57 +0000
commitefad78260379f0ca836e8a2327b97dd620acd098 (patch)
treea80201543e9e1851fa05580b0f9b7f1e75b2e9b1
parentee20190a3a6e36b97c4914e0fa486017e72b0375 (diff)
rio/everywhere: add icreate/namelink fop
icreate creates inode, while namelink links the basename to it's parent gfid. For now mkdir is the primary user of these fops. Better distribution is acheived by creating the inode on ,(say) mds1 and linking the basename to it's parent gfid on mds2. The inode serves readdirp, stat etc. More details about the fops are present at: https://review.gluster.org/#/c/13395/3/design/DHT2/DHT2_Icreate_Namelink_Notes.md This backport of three patches from experimental branch. 1- https://review.gluster.org/#/c/18085/ 2- https://review.gluster.org/#/c/18086/ 3- https://review.gluster.org/#/c/18094/ Updates gluster/glusterfs#243 Change-Id: I1bd3d5a441a3cfab1acfeb52f15c6c867d362592 Signed-off-by: Susant Palai <spalai@redhat.com>
-rw-r--r--libglusterfs/src/call-stub.c120
-rw-r--r--libglusterfs/src/call-stub.h24
-rw-r--r--libglusterfs/src/common-utils.c3
-rw-r--r--libglusterfs/src/default-args.c23
-rw-r--r--libglusterfs/src/default-args.h8
-rw-r--r--libglusterfs/src/defaults-tmpl.c2
-rw-r--r--libglusterfs/src/defaults.h32
-rwxr-xr-xlibglusterfs/src/generator.py17
-rw-r--r--libglusterfs/src/globals.c2
-rw-r--r--libglusterfs/src/glusterfs.h1
-rw-r--r--libglusterfs/src/syncop.c76
-rw-r--r--libglusterfs/src/syncop.h10
-rw-r--r--libglusterfs/src/xlator.c2
-rw-r--r--libglusterfs/src/xlator.h20
-rw-r--r--rpc/rpc-lib/src/protocol-common.h2
-rw-r--r--rpc/xdr/src/glusterfs-fops.x2
-rw-r--r--rpc/xdr/src/glusterfs4-xdr.x27
-rw-r--r--xlators/performance/io-threads/src/io-threads.c2
-rw-r--r--xlators/protocol/client/src/client-rpc-fops.c198
-rw-r--r--xlators/protocol/client/src/client.c56
-rw-r--r--xlators/protocol/server/src/server-rpc-fops.c234
21 files changed, 860 insertions, 1 deletions
diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c
index 74a6429..d5c4f13 100644
--- a/libglusterfs/src/call-stub.c
+++ b/libglusterfs/src/call-stub.c
@@ -2009,6 +2009,126 @@ out:
return stub;
}
+call_stub_t *
+fop_icreate_stub (call_frame_t *frame, fop_icreate_t fn,
+ loc_t *loc, mode_t mode, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+
+ stub = stub_new (frame, 1, GF_FOP_ICREATE);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn.icreate = fn;
+
+ stub->args.mode = mode;
+ if (loc)
+ loc_copy (&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+
+ out:
+ return stub;
+}
+
+static void
+args_icreate_store_cbk (default_args_cbk_t *args,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (inode)
+ args->inode = inode_ref (inode);
+ if (buf)
+ args->stat = *buf;
+ if (xdata)
+ args->xdata = dict_ref (xdata);
+}
+
+call_stub_t *
+fop_icreate_cbk_stub (call_frame_t *frame,
+ fop_icreate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+
+ stub = stub_new (frame, 0, GF_FOP_ICREATE);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn_cbk.icreate = fn;
+ args_icreate_store_cbk (&stub->args_cbk,
+ op_ret, op_errno, inode, buf, xdata);
+
+ out:
+ return stub;
+}
+
+call_stub_t *
+fop_namelink_stub (call_frame_t *frame,
+ fop_namelink_t fn, loc_t *loc, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+
+ stub = stub_new (frame, 1, GF_FOP_NAMELINK);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn.namelink = fn;
+
+ if (loc)
+ loc_copy (&stub->args.loc, loc);
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+
+ out:
+ return stub;
+}
+
+static void
+args_namelink_store_cbk (default_args_cbk_t *args,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+{
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (prebuf)
+ args->prestat = *prebuf;
+ if (postbuf)
+ args->poststat = *postbuf;
+ if (xdata)
+ args->xdata = dict_ref (xdata);
+}
+
+call_stub_t *
+fop_namelink_cbk_stub (call_frame_t *frame,
+ fop_namelink_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+
+ stub = stub_new (frame, 0, GF_FOP_NAMELINK);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn_cbk.namelink = fn;
+ args_namelink_store_cbk (&stub->args_cbk,
+ op_ret, op_errno, prebuf, postbuf, xdata);
+
+ out:
+ return stub;
+}
+
void
call_resume_wind (call_stub_t *stub)
{
diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h
index 4d86a51..e20f6a5 100644
--- a/libglusterfs/src/call-stub.h
+++ b/libglusterfs/src/call-stub.h
@@ -78,6 +78,8 @@ typedef struct _call_stub {
fop_getactivelk_t getactivelk;
fop_setactivelk_t setactivelk;
fop_put_t put;
+ fop_icreate_t icreate;
+ fop_namelink_t namelink;
} fn;
union {
@@ -131,6 +133,8 @@ typedef struct _call_stub {
fop_getactivelk_cbk_t getactivelk;
fop_setactivelk_cbk_t setactivelk;
fop_put_cbk_t put;
+ fop_icreate_cbk_t icreate;
+ fop_namelink_cbk_t namelink;
} fn_cbk;
default_args_t args;
@@ -776,6 +780,26 @@ fop_put_cbk_stub (call_frame_t *frame, fop_put_cbk_t fn, int32_t op_ret,
struct iatt *preparent, struct iatt *postparent,
dict_t *xdata);
+call_stub_t *
+fop_icreate_stub (call_frame_t *frame, fop_icreate_t fn,
+ loc_t *loc, mode_t mode, dict_t *xdata);
+
+call_stub_t *
+fop_namelink_stub (call_frame_t *frame,
+ fop_namelink_t fn, loc_t *loc, dict_t *xdata);
+
+call_stub_t *
+fop_icreate_cbk_stub (call_frame_t *frame,
+ fop_icreate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xdata);
+
+call_stub_t *
+fop_namelink_cbk_stub (call_frame_t *frame,
+ fop_namelink_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata);
+
void call_resume (call_stub_t *stub);
void call_resume_keep_stub (call_stub_t *stub);
void call_stub_destroy (call_stub_t *stub);
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 68d2e24..ad0359d 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -4591,6 +4591,8 @@ fop_enum_to_pri_string (glusterfs_fop_t fop)
case GF_FOP_READDIRP:
case GF_FOP_GETACTIVELK:
case GF_FOP_SETACTIVELK:
+ case GF_FOP_ICREATE:
+ case GF_FOP_NAMELINK:
return "HIGH";
case GF_FOP_CREATE:
@@ -4940,4 +4942,3 @@ get_struct_variable (int mem_num, gf_gsync_status_t *sts_val)
out:
return NULL;
}
-
diff --git a/libglusterfs/src/default-args.c b/libglusterfs/src/default-args.c
index 9ac0f40..20cd05e 100644
--- a/libglusterfs/src/default-args.c
+++ b/libglusterfs/src/default-args.c
@@ -1580,6 +1580,29 @@ args_lease_cbk_store (default_args_cbk_t *args,
args->xdata = dict_ref (xdata);
}
+int
+args_icreate_store (default_args_t *args,
+ loc_t *loc, mode_t mode, dict_t *xdata)
+{
+ loc_copy (&args->loc, loc);
+ args->mode = mode;
+
+ if (xdata)
+ args->xdata = dict_ref (xdata);
+ return 0;
+}
+
+int
+args_namelink_store (default_args_t *args,
+ loc_t *loc, dict_t *xdata)
+{
+ loc_copy (&args->loc, loc);
+
+ if (xdata)
+ args->xdata = dict_ref (xdata);
+ return 0;
+}
+
void
args_cbk_wipe (default_args_cbk_t *args_cbk)
{
diff --git a/libglusterfs/src/default-args.h b/libglusterfs/src/default-args.h
index f97d883..7d46fef 100644
--- a/libglusterfs/src/default-args.h
+++ b/libglusterfs/src/default-args.h
@@ -488,6 +488,14 @@ args_getactivelk_cbk_store (default_args_cbk_t *args,
int
args_setactivelk_store (default_args_t *args, loc_t *loc,
lock_migration_info_t *locklist, dict_t *xdata);
+
+int
+args_icreate_store (default_args_t *args,
+ loc_t *loc, mode_t mode, dict_t *xdata);
+
+int
+args_namelink_store (default_args_t *args, loc_t *loc, dict_t *xdata);
+
void
args_cbk_init (default_args_cbk_t *args_cbk);
#endif /* _DEFAULT_ARGS_H */
diff --git a/libglusterfs/src/defaults-tmpl.c b/libglusterfs/src/defaults-tmpl.c
index 21b99d9..b9f6274 100644
--- a/libglusterfs/src/defaults-tmpl.c
+++ b/libglusterfs/src/defaults-tmpl.c
@@ -82,6 +82,8 @@ struct xlator_fops _default_fops = {
.getactivelk = default_getactivelk,
.setactivelk = default_setactivelk,
.put = default_put,
+ .icreate = default_icreate,
+ .namelink = default_namelink,
};
struct xlator_fops *default_fops = &_default_fops;
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
index c202dbe..5e56cc2 100644
--- a/libglusterfs/src/defaults.h
+++ b/libglusterfs/src/defaults.h
@@ -359,6 +359,12 @@ default_put (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,
off_t off, struct iobref *iobref, dict_t *xattr, dict_t *xdata);
+int32_t default_icreate (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, dict_t *xdata);
+
+int32_t default_namelink (call_frame_t *frame,
+ xlator_t *this, loc_t *loc, dict_t *xdata);
+
/* Resume */
int32_t default_getspec_resume (call_frame_t *frame,
xlator_t *this,
@@ -912,6 +918,14 @@ default_put_cbk_resume (call_frame_t *frame, void *cookie, xlator_t *this,
struct iatt *buf, struct iatt *preparent,
struct iatt *postparent, dict_t *xdata);
+int32_t
+default_icreate_resume (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, dict_t *xdata);
+
+int32_t
+default_namelink_resume (call_frame_t *frame,
+ xlator_t *this, loc_t *loc, dict_t *xdata);
+
/* _CBK */
int32_t
default_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@@ -1166,6 +1180,18 @@ default_put_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct iatt *postparent, dict_t *xdata);
int32_t
+default_icreate_cbk (call_frame_t *frame,
+ void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xdata);
+
+int32_t
+default_namelink_cbk (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata);
+
+int32_t
default_lookup_failure_cbk (call_frame_t *frame, int32_t op_errno);
int32_t
@@ -1321,6 +1347,12 @@ int32_t
default_put_failure_cbk (call_frame_t *frame, int32_t op_errno);
int32_t
+default_icreate_failure_cbk (call_frame_t *frame, int32_t op_errno);
+
+int32_t
+default_namelink_failure_cbk (call_frame_t *frame, int32_t op_errno);
+
+int32_t
default_mem_acct_init (xlator_t *this);
void
diff --git a/libglusterfs/src/generator.py b/libglusterfs/src/generator.py
index d9262e4..7fa5f43 100755
--- a/libglusterfs/src/generator.py
+++ b/libglusterfs/src/generator.py
@@ -575,6 +575,23 @@ ops['put'] = (
('cbk-arg', 'xdata', 'dict_t *'),
)
+ops['icreate'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'mode', 'mode_t'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'inode', 'inode_t *'),
+ ('cbk-arg', 'buf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
+ops['namelink'] = (
+ ('fop-arg', 'loc', 'loc_t *'),
+ ('fop-arg', 'xdata', 'dict_t *'),
+ ('cbk-arg', 'prebuf', 'struct iatt *'),
+ ('cbk-arg', 'postbuf', 'struct iatt *'),
+ ('cbk-arg', 'xdata', 'dict_t *'),
+)
+
#####################################################################
xlator_cbks['forget'] = (
('fn-arg', 'this', 'xlator_t *'),
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c
index 1c57446..6bed1b5 100644
--- a/libglusterfs/src/globals.c
+++ b/libglusterfs/src/globals.c
@@ -75,6 +75,8 @@ const char *gf_fop_list[GF_FOP_MAXVALUE] = {
[GF_FOP_GETACTIVELK] = "GETACTIVELK",
[GF_FOP_SETACTIVELK] = "SETACTIVELK",
[GF_FOP_PUT] = "PUT",
+ [GF_FOP_ICREATE] = "ICREATE",
+ [GF_FOP_NAMELINK] = "NAMELINK",
};
const char *gf_upcall_list[GF_UPCALL_FLAGS_MAXVALUE] = {
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index ad8e396..aa28b80 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -306,6 +306,7 @@ const char *fop_enum_to_pri_string (glusterfs_fop_t fop);
#define GF_SET_OVERWRITE 0x2 /* Overwrite with the buf given */
#define GF_SET_DIR_ONLY 0x4
#define GF_SET_EPOCH_TIME 0x8 /* used by afr dir lookup selfheal */
+#define GF_AUXILLARY_PARGFID 0xd /* RIO dummy parent gfid */
/* key value which quick read uses to get small files in lookup cbk */
#define GF_CONTENT_KEY "glusterfs.content"
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index a4882f5..58c606b 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -3251,3 +3251,79 @@ syncop_setactivelk (xlator_t *subvol, loc_t *loc,
return args.op_ret;
}
+
+int
+syncop_icreate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+ if (xdata)
+ args->xdata = dict_ref (xdata);
+
+ if (buf)
+ args->iatt1 = *buf;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_namelink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ if (xdata)
+ args->xdata = dict_ref (xdata);
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_icreate (xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *xdata)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_icreate_cbk, subvol->fops->icreate,
+ loc, mode, xdata);
+
+ if (xdata)
+ xdata = args.xdata;
+ else if (args.xdata)
+ dict_unref (args.xdata);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+int
+syncop_namelink (xlator_t *subvol, loc_t *loc, dict_t *xdata)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_namelink_cbk, subvol->fops->namelink,
+ loc, xdata);
+
+ if (xdata)
+ xdata = args.xdata;
+ else if (args.xdata)
+ dict_unref (args.xdata);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h
index 8f84cb7..3b25565 100644
--- a/libglusterfs/src/syncop.h
+++ b/libglusterfs/src/syncop.h
@@ -569,4 +569,14 @@ syncop_put (xlator_t *subvol, loc_t *loc, mode_t mode, mode_t umask,
off_t offset, struct iobref *iobref, dict_t *xattr,
struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out);
+int
+syncop_setactivelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata);
+
+int
+syncop_icreate (xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *xdata_out);
+
+int
+syncop_namelink (xlator_t *subvol, loc_t *loc, dict_t *xdata_out);
+
#endif /* _SYNCOP_H */
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index 677dd6c..3e10831 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -106,6 +106,8 @@ fill_defaults (xlator_t *xl)
SET_DEFAULT_FOP (put);
SET_DEFAULT_FOP (getspec);
+ SET_DEFAULT_FOP (icreate);
+ SET_DEFAULT_FOP (namelink);
if (!xl->cbks)
xl->cbks = &default_cbks;
diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
index a3115f0..81199bd 100644
--- a/libglusterfs/src/xlator.h
+++ b/libglusterfs/src/xlator.h
@@ -471,6 +471,16 @@ typedef int32_t (*fop_put_cbk_t) (call_frame_t *frame, void *cookie,
struct iatt *buf, struct iatt *preparent,
struct iatt *postparent, dict_t *xdata);
+typedef int32_t (*fop_icreate_cbk_t) (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xdata);
+
+typedef int32_t (*fop_namelink_cbk_t) (call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata);
+
typedef int32_t (*fop_lookup_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
@@ -737,6 +747,12 @@ typedef int32_t (*fop_put_t) (call_frame_t *frame, xlator_t *this, loc_t *loc,
struct iobref *iobref, dict_t *xattr,
dict_t *xdata);
+typedef int32_t (*fop_icreate_t) (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, mode_t mode, dict_t *xdata);
+
+typedef int32_t (*fop_namelink_t) (call_frame_t *frame, xlator_t *this,
+ loc_t *loc, dict_t *xdata);
+
/* WARNING: make sure the list is in order with FOP definition in
`rpc/xdr/src/glusterfs-fops.x`.
If it is not in order, mainly the metrics related feature would be broken */
@@ -799,6 +815,8 @@ struct xlator_fops {
fop_getactivelk_t getactivelk;
fop_setactivelk_t setactivelk;
fop_put_t put;
+ fop_icreate_t icreate;
+ fop_namelink_t namelink;
/* these entries are used for a typechecking hack in STACK_WIND _only_ */
/* make sure to add _cbk variables only after defining regular fops as
@@ -861,6 +879,8 @@ struct xlator_fops {
fop_getactivelk_cbk_t getactivelk_cbk;
fop_setactivelk_cbk_t setactivelk_cbk;
fop_put_cbk_t put_cbk;
+ fop_icreate_cbk_t icreate_cbk;
+ fop_namelink_cbk_t namelink_cbk;
};
typedef int32_t (*cbk_forget_t) (xlator_t *this,
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index ccb3c50..ebfb651 100644
--- a/rpc/rpc-lib/src/protocol-common.h
+++ b/rpc/rpc-lib/src/protocol-common.h
@@ -65,6 +65,8 @@ enum gf_fop_procnum {
GFS3_OP_LEASE,
GFS3_OP_GETACTIVELK,
GFS3_OP_SETACTIVELK,
+ GFS3_OP_ICREATE,
+ GFS3_OP_NAMELINK,
GFS3_OP_MAXVALUE,
};
diff --git a/rpc/xdr/src/glusterfs-fops.x b/rpc/xdr/src/glusterfs-fops.x
index b14a6e6..5b5c590 100644
--- a/rpc/xdr/src/glusterfs-fops.x
+++ b/rpc/xdr/src/glusterfs-fops.x
@@ -75,6 +75,8 @@ enum glusterfs_fop_t {
GF_FOP_GETACTIVELK,
GF_FOP_SETACTIVELK,
GF_FOP_PUT,
+ GF_FOP_ICREATE,
+ GF_FOP_NAMELINK,
GF_FOP_MAXVALUE
};
diff --git a/rpc/xdr/src/glusterfs4-xdr.x b/rpc/xdr/src/glusterfs4-xdr.x
index 6d0c500..a4fc9b2 100644
--- a/rpc/xdr/src/glusterfs4-xdr.x
+++ b/rpc/xdr/src/glusterfs4-xdr.x
@@ -31,3 +31,30 @@
unsigned int len;
opaque xdata<>; /* Extra data */
} ;
+
+struct gfs4_icreate_rsp {
+ int op_ret;
+ int op_errno;
+ gf_iatt stat;
+ opaque xdata<>;
+};
+
+struct gfs4_icreate_req {
+ opaque gfid[16];
+ unsigned int mode;
+ opaque xdata<>;
+};
+
+struct gfs4_namelink_rsp {
+ int op_ret;
+ int op_errno;
+ gf_iatt preparent;
+ gf_iatt postparent;
+ opaque xdata<>;
+};
+
+struct gfs4_namelink_req {
+ opaque pargfid[16];
+ string bname<>;
+ opaque xdata<>;
+};
diff --git a/xlators/performance/io-threads/src/io-threads.c b/xlators/performance/io-threads/src/io-threads.c
index 7c020e2..7aafc8a 100644
--- a/xlators/performance/io-threads/src/io-threads.c
+++ b/xlators/performance/io-threads/src/io-threads.c
@@ -299,6 +299,8 @@ iot_schedule (call_frame_t *frame, xlator_t *this, call_stub_t *stub)
case GF_FOP_READDIRP:
case GF_FOP_GETACTIVELK:
case GF_FOP_SETACTIVELK:
+ case GF_FOP_ICREATE:
+ case GF_FOP_NAMELINK:
pri = IOT_PRI_HI;
break;
diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c
index 9f0a752..30e0699 100644
--- a/xlators/protocol/client/src/client-rpc-fops.c
+++ b/xlators/protocol/client/src/client-rpc-fops.c
@@ -3150,6 +3150,102 @@ out:
return 0;
}
+int32_t
+client3_3_namelink_cbk (struct rpc_req *req,
+ struct iovec *iov, int count, void *myframe)
+{
+ int32_t ret = 0;
+ xlator_t *this = NULL;
+ struct iatt prebuf = {0,};
+ struct iatt postbuf = {0,};
+ dict_t *xdata = NULL;
+ call_frame_t *frame = NULL;
+ gfs4_namelink_rsp rsp = {0,};
+
+ this = THIS;
+ frame = myframe;
+
+ if (req->rpc_status == -1) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs4_namelink_rsp);
+ if (ret < 0) {
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret != -1) {
+ gf_stat_to_iatt (&rsp.preparent, &prebuf);
+ gf_stat_to_iatt (&rsp.postparent, &postbuf);
+ }
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+ out:
+ CLIENT_STACK_UNWIND (namelink, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno),
+ &prebuf, &postbuf, xdata);
+ free (rsp.xdata.xdata_val);
+ if (xdata)
+ dict_unref (xdata);
+ return 0;
+}
+
+int32_t
+client3_3_icreate_cbk (struct rpc_req *req,
+ struct iovec *iov, int count, void *myframe)
+{
+ int32_t ret = 0;
+ inode_t *inode = NULL;
+ clnt_local_t *local = NULL;
+ xlator_t *this = NULL;
+ struct iatt stbuf = {0,};
+ dict_t *xdata = NULL;
+ call_frame_t *frame = NULL;
+ gfs4_icreate_rsp rsp = {0,};
+
+ this = THIS;
+ frame = myframe;
+ local = frame->local;
+
+ inode = local->loc.inode;
+
+ if (req->rpc_status == -1) {
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs4_icreate_rsp);
+ if (ret < 0) {
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret != -1)
+ gf_stat_to_iatt (&rsp.stat, &stbuf);
+
+ GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val),
+ (rsp.xdata.xdata_len), ret,
+ rsp.op_errno, out);
+
+ out:
+ CLIENT_STACK_UNWIND (icreate, frame, rsp.op_ret,
+ gf_error_to_errno (rsp.op_errno),
+ inode, &stbuf, xdata);
+ free (rsp.xdata.xdata_val);
+ if (xdata)
+ dict_unref (xdata);
+ return 0;
+}
+
int
client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx)
{
@@ -6250,6 +6346,104 @@ unwind:
}
int32_t
+client3_3_namelink (call_frame_t *frame, xlator_t *this, void *data)
+{
+ int32_t ret = 0;
+ int32_t op_errno = EINVAL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ gfs4_namelink_req req = {{0,},};
+
+ GF_ASSERT (frame);
+
+ args = data;
+ conf = this->private;
+
+ if (!(args->loc && args->loc->parent))
+ goto unwind;
+
+ if (!gf_uuid_is_null (args->loc->parent->gfid))
+ memcpy (req.pargfid, args->loc->parent->gfid, sizeof (uuid_t));
+ else
+ memcpy (req.pargfid, args->loc->pargfid, sizeof (uuid_t));
+
+ GF_ASSERT_AND_GOTO_WITH_ERROR (this->name,
+ !gf_uuid_is_null (*((uuid_t *)req.pargfid)),
+ unwind, op_errno, EINVAL);
+
+ req.bname = (char *)args->loc->name;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_NAMELINK, client3_3_namelink_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs4_namelink_req);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED,
+ "failed to send the fop");
+ }
+
+ GF_FREE (req.xdata.xdata_val);
+ return 0;
+
+ unwind:
+ CLIENT_STACK_UNWIND (namelink, frame, -1, op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int32_t
+client3_3_icreate (call_frame_t *frame, xlator_t *this, void *data)
+{
+ int32_t ret = 0;
+ int32_t op_errno = EINVAL;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t *args = NULL;
+ clnt_local_t *local = NULL;
+ gfs4_icreate_req req = {{0,},};
+
+ GF_ASSERT (frame);
+
+ args = data;
+ conf = this->private;
+
+ if (!(args->loc && args->loc->inode))
+ goto unwind;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ frame->local = local;
+
+ loc_copy (&local->loc, args->loc);
+
+ req.mode = args->mode;
+ memcpy (req.gfid, args->loc->gfid, sizeof (uuid_t));
+
+ op_errno = ESTALE;
+ GF_PROTOCOL_DICT_SERIALIZE (this, args->xdata, (&req.xdata.xdata_val),
+ req.xdata.xdata_len, op_errno, unwind);
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_ICREATE, client3_3_icreate_cbk,
+ NULL, NULL, 0, NULL, 0, NULL,
+ (xdrproc_t) xdr_gfs4_icreate_req);
+ if (ret)
+ goto free_reqdata;
+ GF_FREE (req.xdata.xdata_val);
+ return 0;
+
+ free_reqdata:
+ GF_FREE (req.xdata.xdata_val);
+ unwind:
+ CLIENT_STACK_UNWIND (icreate, frame,
+ -1, op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int32_t
client4_0_fsetattr (call_frame_t *frame, xlator_t *this, void *data)
{
clnt_args_t *args = NULL;
@@ -6456,6 +6650,8 @@ char *clnt3_3_fop_names[GFS3_OP_MAXVALUE] = {
[GFS3_OP_GETACTIVELK] = "GETACTIVELK",
[GFS3_OP_SETACTIVELK] = "SETACTIVELK",
[GFS3_OP_COMPOUND] = "COMPOUND",
+ [GFS3_OP_ICREATE] = "ICREATE",
+ [GFS3_OP_NAMELINK] = "NAMELINK",
};
rpc_clnt_prog_t clnt3_3_fop_prog = {
@@ -6522,6 +6718,8 @@ rpc_clnt_procedure_t clnt4_0_fop_actors[GF_FOP_MAXVALUE] = {
[GF_FOP_GETACTIVELK] = { "GETACTIVELK", client3_3_getactivelk},
[GF_FOP_SETACTIVELK] = { "SETACTIVELK", client3_3_setactivelk},
[GF_FOP_COMPOUND] = { "COMPOUND", client3_3_compound },
+ [GF_FOP_ICREATE] = { "ICREATE", client3_3_icreate},
+ [GF_FOP_NAMELINK] = { "NAMELINK", client3_3_namelink},
};
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c
index b8b0ddb..8df697e 100644
--- a/xlators/protocol/client/src/client.c
+++ b/xlators/protocol/client/src/client.c
@@ -2181,6 +2181,60 @@ out:
return 0;
}
+int32_t
+client_namelink (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
+{
+ int32_t ret = -1;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t args = {0,};
+ rpc_clnt_procedure_t *proc = NULL;
+
+ conf = this->private;
+ if (!conf || !conf->fops || !conf->handshake)
+ goto out;
+
+ args.loc = loc;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_NAMELINK];
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+
+ out:
+ if (ret)
+ STACK_UNWIND_STRICT (namelink, frame,
+ -1, EINVAL, NULL, NULL, NULL);
+ return 0;
+}
+
+int32_t
+client_icreate (call_frame_t *frame,
+ xlator_t *this, loc_t *loc, mode_t mode, dict_t *xdata)
+{
+ int32_t ret = -1;
+ clnt_conf_t *conf = NULL;
+ clnt_args_t args = {0,};
+ rpc_clnt_procedure_t *proc = NULL;
+
+ conf = this->private;
+ if (!conf || !conf->fops || !conf->handshake)
+ goto out;
+
+ args.loc = loc;
+ args.mode = mode;
+ args.xdata = xdata;
+
+ proc = &conf->fops->proctable[GF_FOP_ICREATE];
+ if (proc->fn)
+ ret = proc->fn (frame, this, &args);
+
+ out:
+ if (ret)
+ STACK_UNWIND_STRICT (icreate, frame,
+ -1, EINVAL, NULL, NULL, NULL);
+ return 0;
+}
+
int
client_mark_fd_bad (xlator_t *this)
{
@@ -2960,6 +3014,8 @@ struct xlator_fops fops = {
.compound = client_compound,
.getactivelk = client_getactivelk,
.setactivelk = client_setactivelk,
+ .icreate = client_icreate,
+ .namelink = client_namelink,
};
diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c
index 1adb262..1b87aba 100644
--- a/xlators/protocol/server/src/server-rpc-fops.c
+++ b/xlators/protocol/server/src/server-rpc-fops.c
@@ -2207,6 +2207,97 @@ out:
return 0;
}
+int
+server_namelink_cbk (call_frame_t *frame,
+ void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata)
+{
+ gfs4_namelink_rsp rsp = {0,};
+ rpcsvc_request_t *req = NULL;
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ if (op_ret < 0)
+ goto out;
+
+ gf_stat_from_iatt (&rsp.preparent, prebuf);
+ gf_stat_from_iatt (&rsp.postparent, postbuf);
+
+ /**
+ * no point in linking inode here -- there's no stbuf anyway and a
+ * lookup() for this name entry would be a negative lookup.
+ */
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs4_namelink_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
+int
+server_icreate_cbk (call_frame_t *frame,
+ void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *stbuf, dict_t *xdata)
+{
+ server_state_t *state = NULL;
+ inode_t *link_inode = NULL;
+ rpcsvc_request_t *req = NULL;
+ gfs3_create_rsp rsp = {0,};
+
+ GF_PROTOCOL_DICT_SERIALIZE (this, xdata, &rsp.xdata.xdata_val,
+ rsp.xdata.xdata_len, op_errno, out);
+
+ state = CALL_STATE (frame);
+
+ if (op_ret < 0) {
+ gf_msg (this->name, GF_LOG_INFO, op_errno, PS_MSG_CREATE_INFO,
+ "%"PRId64": ICREATE [%s] ==> (%s)",
+ frame->root->unique, uuid_utoa (state->resolve.gfid),
+ strerror (op_errno));
+ goto out;
+ }
+
+ gf_msg_trace (frame->root->client->bound_xl->name, 0, "%"PRId64": "
+ "ICREATE [%s]", frame->root->unique,
+ uuid_utoa (stbuf->ia_gfid));
+
+ link_inode = inode_link (inode,
+ state->loc.parent, state->loc.name, stbuf);
+
+ if (!link_inode) {
+ op_ret = -1;
+ op_errno = ENOENT;
+ goto out;
+ }
+
+ inode_lookup (link_inode);
+ inode_unref (link_inode);
+
+ gf_stat_from_iatt (&rsp.stat, stbuf);
+
+out:
+ rsp.op_ret = op_ret;
+ rsp.op_errno = gf_errno_to_error (op_errno);
+
+ req = frame->local;
+ server_submit_reply (frame, req, &rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfs4_icreate_rsp);
+
+ GF_FREE (rsp.xdata.xdata_val);
+
+ return 0;
+}
+
/* Resume function section */
int
@@ -3452,6 +3543,53 @@ err:
return ret;
}
+int
+server_namelink_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_namelink_cbk,
+ bound_xl, bound_xl->fops->namelink,
+ &(state->loc), state->xdata);
+ return 0;
+
+ err:
+ server_namelink_cbk (frame, NULL,
+ frame->this,
+ state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
+
+int
+server_icreate_resume (call_frame_t *frame, xlator_t *bound_xl)
+{
+ server_state_t *state = NULL;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
+ state->loc.inode = inode_new (state->itable);
+
+ STACK_WIND (frame, server_icreate_cbk,
+ bound_xl, bound_xl->fops->icreate,
+ &(state->loc), state->mode, state->xdata);
+
+ return 0;
+err:
+ server_icreate_cbk (frame, NULL, frame->this, state->resolve.op_ret,
+ state->resolve.op_errno, NULL, NULL, NULL);
+ return 0;
+}
/* Fop section */
static inline int
@@ -6091,6 +6229,100 @@ out:
}
int
+server3_3_namelink (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs4_namelink_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common (req, &frame, &state, NULL, &args,
+ xdr_gfs4_namelink_req, GF_FOP_NAMELINK);
+
+ if (ret != 0)
+ goto out;
+
+ state->resolve.bname = gf_strdup (args.bname);
+ memcpy (state->resolve.pargfid, args.pargfid, sizeof (uuid_t));
+
+ state->resolve.type = RESOLVE_NOT;
+
+ /* TODO: can do alloca for xdata field instead of stdalloc */
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_namelink_resume);
+
+out:
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+
+}
+
+int
+server3_3_icreate (rpcsvc_request_t *req)
+{
+ server_state_t *state = NULL;
+ call_frame_t *frame = NULL;
+ gfs4_icreate_req args = {{0,},};
+ int ret = -1;
+ int op_errno = 0;
+ uuid_t gfid = {0,};
+
+ if (!req)
+ return ret;
+
+ ret = rpc_receive_common (req, &frame, &state, NULL, &args,
+ xdr_gfs4_icreate_req, GF_FOP_ICREATE);
+
+ if (ret != 0)
+ goto out;
+
+ memcpy (gfid, args.gfid, sizeof (uuid_t));
+
+ state->mode = args.mode;
+ gf_asprintf (&state->resolve.bname, INODE_PATH_FMT, uuid_utoa (gfid));
+
+ /* parent is an auxillary inode number */
+ memset (state->resolve.pargfid, 0, sizeof (uuid_t));
+ state->resolve.pargfid[15] = GF_AUXILLARY_PARGFID;
+
+ state->resolve.type = RESOLVE_NOT;
+
+ /* TODO: can do alloca for xdata field instead of stdalloc */
+ GF_PROTOCOL_DICT_UNSERIALIZE (frame->root->client->bound_xl,
+ state->xdata,
+ args.xdata.xdata_val,
+ args.xdata.xdata_len, ret,
+ op_errno, out);
+
+ ret = 0;
+ resolve_and_resume (frame, server_icreate_resume);
+
+out:
+ /* memory allocated by libc, don't use GF_FREE */
+ free (args.xdata.xdata_val);
+
+ if (op_errno)
+ SERVER_REQ_SET_ERROR (req, ret);
+
+ return ret;
+}
+
+int
server4_0_fsetattr (rpcsvc_request_t *req)
{
server_state_t *state = NULL;
@@ -6297,6 +6529,8 @@ rpcsvc_actor_t glusterfs4_0_fop_actors[] = {
[GFS3_OP_GETACTIVELK] = {"GETACTIVELK", GFS3_OP_GETACTIVELK, server3_3_getactivelk, NULL, 0, DRC_NA},
[GFS3_OP_SETACTIVELK] = {"SETACTIVELK", GFS3_OP_SETACTIVELK, server3_3_setactivelk, NULL, 0, DRC_NA},
[GFS3_OP_COMPOUND] = {"COMPOUND", GFS3_OP_COMPOUND, server3_3_compound, NULL, 0, DRC_NA},
+ [GFS3_OP_ICREATE] = {"ICREATE", GFS3_OP_ICREATE, server3_3_icreate, NULL, 0, DRC_NA},
+ [GFS3_OP_NAMELINK] = {"NAMELINK", GFS3_OP_NAMELINK, server3_3_namelink, NULL, 0, DRC_NA},
};