gfapi: return pre/post attributes from glfs_pread/pwrite

As nfs-ganesha, a wcc data contains pre/post attributes is return
in read/write rpc reply. nfs-ganesha get those attributes by
two getattr between the real read/write right now.

But, gluster has return pre/post attributes from glusterfsd,
those attributes are skipped in syncop/gfapi, if gfapi return them,
the upper user (nfs-ganesha) can use them directly without any
duplicate getattr.

Updates: #389
Change-Id: I7b643ae4241cfe2aeb17063de00192d81674024a
Signed-off-by: Kinglong Mee <mijinlong@open-fs.com>
This commit is contained in:
Kinglong Mee 2018-02-12 15:13:49 +08:00 committed by Amar Tumballi
parent bfb66cc535
commit d01f7244e9
15 changed files with 129 additions and 52 deletions

View File

@ -24,8 +24,8 @@ _pub_glfs_readv _glfs_readv$GFAPI_3.4.0
_pub_glfs_writev _glfs_writev$GFAPI_3.4.0
_pub_glfs_readv_async _glfs_readv_async$GFAPI_3.4.0
_pub_glfs_writev_async _glfs_writev_async$GFAPI_3.4.0
_pub_glfs_pread _glfs_pread$GFAPI_3.4.0
_pub_glfs_pwrite _glfs_pwrite$GFAPI_3.4.0
_pub_glfs_pread34 _glfs_pread$GFAPI_3.4.0
_pub_glfs_pwrite34 _glfs_pwrite$GFAPI_3.4.0
_pub_glfs_pread_async _glfs_pread_async$GFAPI_3.4.0
_pub_glfs_pwrite_async _glfs_pwrite_async$GFAPI_3.4.0
_pub_glfs_preadv _glfs_preadv$GFAPI_3.4.0
@ -172,3 +172,5 @@ _pub_glfs_setfsleaseid _glfs_setfsleaseid$GFAPI_4.0.0
_pub_glfs_file_lock _glfs_file_lock$GFAPI_4.0.0
_pub_glfs_lease _glfs_lease$GFAPI_4.0.0
_pub_glfs_h_lease _glfs_h_lease$GFAPI_4.0.0
_pub_glfs_pread _glfs_pread$GFAPI_4.0.0
_pub_glfs_pwrite _glfs_pwrite$GFAPI_4.0.0

View File

@ -30,8 +30,6 @@ GFAPI_3.4.0 {
glfs_writev;
glfs_readv_async;
glfs_writev_async;
glfs_pread;
glfs_pwrite;
glfs_pread_async;
glfs_pwrite_async;
glfs_preadv;
@ -227,4 +225,6 @@ GFAPI_4.0.0 {
glfs_file_lock;
glfs_lease;
glfs_h_lease;
glfs_pread;
glfs_pwrite;
} GFAPI_3.13.0;

View File

@ -694,9 +694,9 @@ invalid_fs:
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_lseek, 3.4.0);
ssize_t
pub_glfs_preadv (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
off_t offset, int flags)
static ssize_t
glfs_preadv_common (struct glfs_fd *glfd, const struct iovec *iovec,
int iovcnt, off_t offset, int flags, struct stat *poststat)
{
xlator_t *subvol = NULL;
ssize_t ret = -1;
@ -705,6 +705,7 @@ pub_glfs_preadv (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
int cnt = 0;
struct iobref *iobref = NULL;
fd_t *fd = NULL;
struct iatt iatt = {0, };
DECLARE_OLD_THIS;
__GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
@ -728,8 +729,12 @@ pub_glfs_preadv (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
size = iov_length (iovec, iovcnt);
ret = syncop_readv (subvol, fd, size, offset, 0, &iov, &cnt, &iobref,
NULL, NULL);
&iatt, NULL, NULL);
DECODE_SYNCOP_ERR (ret);
if (ret >= 0 && poststat)
glfs_iatt_to_stat (glfd->fs, &iatt, poststat);
if (ret <= 0)
goto out;
@ -757,6 +762,13 @@ invalid_fs:
return ret;
}
ssize_t
pub_glfs_preadv (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
off_t offset, int flags)
{
return glfs_preadv_common (glfd, iovec, iovcnt, offset, flags, NULL);
}
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_preadv, 3.4.0);
@ -778,8 +790,8 @@ GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_read, 3.4.0);
ssize_t
pub_glfs_pread (struct glfs_fd *glfd, void *buf, size_t count, off_t offset,
int flags)
pub_glfs_pread34 (struct glfs_fd *glfd, void *buf, size_t count, off_t offset,
int flags)
{
struct iovec iov = {0, };
ssize_t ret = 0;
@ -792,7 +804,25 @@ pub_glfs_pread (struct glfs_fd *glfd, void *buf, size_t count, off_t offset,
return ret;
}
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread, 3.4.0);
GFAPI_SYMVER_PUBLIC(glfs_pread34, glfs_pread, 3.4.0);
ssize_t
pub_glfs_pread (struct glfs_fd *glfd, void *buf, size_t count, off_t offset,
int flags, struct stat *poststat)
{
struct iovec iov = {0, };
ssize_t ret = 0;
iov.iov_base = buf;
iov.iov_len = count;
ret = glfs_preadv_common (glfd, &iov, 1, offset, flags, poststat);
return ret;
}
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pread, 4.0.0);
ssize_t
@ -1081,9 +1111,10 @@ out:
}
ssize_t
pub_glfs_pwritev (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
off_t offset, int flags)
static ssize_t
glfs_pwritev_common (struct glfs_fd *glfd, const struct iovec *iovec,
int iovcnt, off_t offset, int flags,
struct stat *prestat, struct stat *poststat)
{
xlator_t *subvol = NULL;
int ret = -1;
@ -1091,6 +1122,7 @@ pub_glfs_pwritev (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
struct iobuf *iobuf = NULL;
struct iovec iov = {0, };
fd_t *fd = NULL;
struct iatt preiatt = {0, }, postiatt = {0, };
DECLARE_OLD_THIS;
__GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs);
@ -1115,15 +1147,21 @@ pub_glfs_pwritev (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
if (ret)
goto out;
ret = syncop_writev (subvol, fd, &iov, 1, offset, iobref, flags, NULL,
NULL);
ret = syncop_writev (subvol, fd, &iov, 1, offset, iobref, flags,
&preiatt, &postiatt, NULL, NULL);
DECODE_SYNCOP_ERR (ret);
if (ret >= 0) {
if (prestat)
glfs_iatt_to_stat (glfd->fs, &preiatt, prestat);
if (poststat)
glfs_iatt_to_stat (glfd->fs, &postiatt, poststat);
}
if (ret <= 0)
goto out;
glfd->offset = (offset + iov.iov_len);
out:
if (iobuf)
iobuf_unref (iobuf);
@ -1142,6 +1180,14 @@ invalid_fs:
return ret;
}
ssize_t
pub_glfs_pwritev (struct glfs_fd *glfd, const struct iovec *iovec, int iovcnt,
off_t offset, int flags)
{
return glfs_pwritev_common (glfd, iovec, iovcnt, offset, flags,
NULL, NULL);
}
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwritev, 3.4.0);
@ -1177,8 +1223,8 @@ GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_writev, 3.4.0);
ssize_t
pub_glfs_pwrite (struct glfs_fd *glfd, const void *buf, size_t count,
off_t offset, int flags)
pub_glfs_pwrite34 (struct glfs_fd *glfd, const void *buf, size_t count,
off_t offset, int flags)
{
struct iovec iov = {0, };
ssize_t ret = 0;
@ -1191,8 +1237,26 @@ pub_glfs_pwrite (struct glfs_fd *glfd, const void *buf, size_t count,
return ret;
}
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite, 3.4.0);
GFAPI_SYMVER_PUBLIC(glfs_pwrite34, glfs_pwrite, 3.4.0);
ssize_t
pub_glfs_pwrite (struct glfs_fd *glfd, const void *buf, size_t count,
off_t offset, int flags, struct stat *prestat,
struct stat *poststat)
{
struct iovec iov = {0, };
ssize_t ret = 0;
iov.iov_base = (void *) buf;
iov.iov_len = count;
ret = glfs_pwritev_common (glfd, &iov, 1, offset, flags,
prestat, poststat);
return ret;
}
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_pwrite, 4.0.0);
extern glfs_t *pub_glfs_from_glfd (glfs_fd_t *);
@ -4746,7 +4810,7 @@ glfs_anonymous_pwritev (struct glfs *fs, struct glfs_object *object,
iov.iov_len = size;
ret = syncop_writev (subvol, fd, &iov, 1, offset, iobref, flags,
NULL, NULL);
NULL, NULL, NULL, NULL);
DECODE_SYNCOP_ERR (ret);
iobuf_unref (iobuf);
@ -4815,7 +4879,7 @@ glfs_anonymous_preadv (struct glfs *fs, struct glfs_object *object,
size = iov_length (iovec, iovcnt);
ret = syncop_readv (subvol, fd, size, offset, flags, &iov, &cnt,
&iobref, NULL, NULL);
&iobref, NULL, NULL, NULL);
DECODE_SYNCOP_ERR (ret);
if (ret <= 0)
goto out;

View File

@ -534,11 +534,12 @@ int glfs_writev_async (glfs_fd_t *fd, const struct iovec *iov, int count,
// glfs_p{read,write}[_async]
ssize_t glfs_pread (glfs_fd_t *fd, void *buf, size_t count, off_t offset,
int flags) __THROW
GFAPI_PUBLIC(glfs_pread, 3.4.0);
int flags, struct stat *poststat) __THROW
GFAPI_PUBLIC(glfs_pread, 4.0.0);
ssize_t glfs_pwrite (glfs_fd_t *fd, const void *buf, size_t count,
off_t offset, int flags) __THROW
GFAPI_PUBLIC(glfs_pwrite, 3.4.0);
off_t offset, int flags, struct stat *prestat,
struct stat *poststat) __THROW
GFAPI_PUBLIC(glfs_pwrite, 4.0.0);
int glfs_pread_async (glfs_fd_t *fd, void *buf, size_t count, off_t offset,
int flags, glfs_io_cbk fn, void *data) __THROW
GFAPI_PUBLIC(glfs_pread_async, 3.4.0);

View File

@ -142,6 +142,8 @@ ops['writev'] = (
('fop-arg', 'off', 'off_t', 'offset'),
('fop-arg', 'flags', 'uint32_t', 'flags'),
('fop-arg', 'iobref', 'struct iobref *'),
('extra', 'preop', 'struct iatt', '&preop'),
('extra', 'postop', 'struct iatt', '&postop'),
('fop-arg', 'xdata', 'dict_t *', 'xdata'),
('cbk-arg', 'prebuf', 'struct iatt *'),
('cbk-arg', 'postbuf', 'struct iatt *'),
@ -154,6 +156,7 @@ ops['readv'] = (
('fop-arg', 'size', 'size_t'),
('fop-arg', 'offset', 'off_t'),
('fop-arg', 'flags', 'uint32_t'),
('extra', 'iatt', 'struct iatt', '&iatt'),
('fop-arg', 'xdata', 'dict_t *'),
('cbk-arg', 'vector', 'struct iovec *'),
('cbk-arg', 'count', 'int32_t'),

View File

@ -1914,6 +1914,7 @@ syncop_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
args->iobref = iobref_ref (iobref);
args->vector = iov_dup (vector, count);
args->count = count;
args->iatt1 = *stbuf;
}
__wake (args);
@ -1925,7 +1926,8 @@ syncop_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
uint32_t flags, struct iovec **vector, int *count,
struct iobref **iobref, dict_t *xdata_in, dict_t **xdata_out)
struct iobref **iobref, struct iatt *iatt,
dict_t *xdata_in, dict_t **xdata_out)
{
struct syncargs args = {0, };
@ -1937,6 +1939,9 @@ syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
else if (args.xdata)
dict_unref (args.xdata);
if (iatt)
*iatt = args.iatt1;
if (args.op_ret < 0)
goto out;
@ -1958,7 +1963,6 @@ out:
if (args.op_ret < 0)
return -args.op_errno;
return args.op_ret;
}
int
@ -1975,6 +1979,11 @@ syncop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (xdata)
args->xdata = dict_ref (xdata);
if (op_ret >= 0) {
args->iatt1 = *prebuf;
args->iatt2 = *postbuf;
}
__wake (args);
return 0;
@ -1983,7 +1992,8 @@ syncop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
syncop_writev (xlator_t *subvol, fd_t *fd, const struct iovec *vector,
int32_t count, off_t offset, struct iobref *iobref,
uint32_t flags, dict_t *xdata_in, dict_t **xdata_out)
uint32_t flags, struct iatt *preiatt, struct iatt *postiatt,
dict_t *xdata_in, dict_t **xdata_out)
{
struct syncargs args = {0, };
@ -1991,6 +2001,11 @@ syncop_writev (xlator_t *subvol, fd_t *fd, const struct iovec *vector,
fd, (struct iovec *) vector, count, offset, flags, iobref,
xdata_in);
if (preiatt)
*preiatt = args.iatt1;
if (postiatt)
*postiatt = args.iatt2;
if (xdata_out)
*xdata_out = args.xdata;
else if (args.xdata)

View File

@ -460,13 +460,14 @@ int syncop_write (xlator_t *subvol, fd_t *fd, const char *buf, int size,
int syncop_writev (xlator_t *subvol, fd_t *fd, const struct iovec *vector,
int32_t count, off_t offset, struct iobref *iobref,
uint32_t flags, dict_t *xdata_in, dict_t **xdata_out);
uint32_t flags, struct iatt *preiatt, struct iatt *postiatt,
dict_t *xdata_in, dict_t **xdata_out);
int syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off,
uint32_t flags,
/* out */
struct iovec **vector, int *count, struct iobref **iobref,
dict_t *xdata_in, dict_t **xdata_out);
struct iatt *iatt, dict_t *xdata_in, dict_t **xdata_out);
int syncop_ftruncate (xlator_t *subvol, fd_t *fd, off_t offset,
dict_t *xdata_in, dict_t **xdata_out);

View File

@ -137,7 +137,7 @@ main (int argc, char *argv[])
LOG_ERR ("glfs_lseek", ret);
memset (readbuf, 0, sizeof(readbuf));
ret = glfs_pread (fd_tmp2, readbuf, 4, 0, 0);
ret = glfs_pread (fd_tmp2, readbuf, 4, 0, 0, NULL);
if (ret <= 0) {
ret = -1;

View File

@ -117,7 +117,7 @@ int perform_io (glfs_t *fs, glfs_t *fs2, int cnt)
LOG_ERR ("glfs_lseek", ret);
memset (readbuf, 0, sizeof(readbuf));
ret = glfs_pread (fd_tmp2, readbuf, 4, 0, 0);
ret = glfs_pread (fd_tmp2, readbuf, 4, 0, 0, NULL);
if (ret <= 0) {
ret = -1;

View File

@ -102,7 +102,7 @@ main (int argc, char *argv[])
buf = (char *) malloc (5);
ret = glfs_pread (fd, buf, 5, 0, 0);
ret = glfs_pread (fd, buf, 5, 0, 0, NULL);
if (ret < 0) {
fprintf (stderr, "Read(%s): %d (%s)\n", "test", ret,
strerror (errno));

View File

@ -128,7 +128,7 @@ __afr_is_sink_zero_filled (xlator_t *this, fd_t *fd, size_t size,
priv = this->private;
ret = syncop_readv (priv->children[sink], fd, size, offset, 0, &iovec,
&count, &iobref, NULL, NULL);
&count, &iobref, NULL, NULL, NULL);
if (ret < 0)
goto out;
ret = iov_0filled (iovec, count);
@ -158,7 +158,7 @@ __afr_selfheal_data_read_write (call_frame_t *frame, xlator_t *this, fd_t *fd,
priv = this->private;
ret = syncop_readv (priv->children[source], fd, size, offset, 0,
&iovec, &count, &iobref, NULL, NULL);
&iovec, &count, &iobref, NULL, NULL, NULL);
if (ret <= 0)
return ret;
@ -207,7 +207,7 @@ __afr_selfheal_data_read_write (call_frame_t *frame, xlator_t *this, fd_t *fd,
}
ret = syncop_writev (priv->children[i], fd, iovec, count,
offset, iobref, 0, NULL, NULL);
offset, iobref, 0, NULL, NULL, NULL, NULL);
if (ret != iov_length (iovec, count)) {
/* write() failed on this sink. unset the corresponding
member in sinks[] (which is healed_sinks[] in the

View File

@ -1159,7 +1159,7 @@ __dht_rebalance_migrate_data (xlator_t *this, gf_defrag_info_t *defrag,
ret = syncop_readv (from, src, read_size,
offset, 0, &vector, &count, &iobref, NULL,
NULL);
NULL, NULL);
if (!ret || (ret < 0)) {
*fop_errno = -ret;
break;
@ -1205,7 +1205,8 @@ __dht_rebalance_migrate_data (xlator_t *this, gf_defrag_info_t *defrag,
}
ret = syncop_writev (to, dst, vector, count,
offset, iobref, 0, xdata, NULL);
offset, iobref, 0, NULL, NULL,
xdata, NULL);
if (ret < 0) {
*fop_errno = -ret;
}

View File

@ -141,7 +141,7 @@ def get_special_subs (name, args, fop_type):
# is not stored in or read from the journal. There are other ways to
# do that, but this is the only place we need anything similar and we
# already have to treat it as a special case so this is simplest.
s_args_str = 'fd, &vector, 1, off, iobref, flags, xdata'
s_args_str = 'fd, &vector, 1, off, iobref, flags, &preop, &postop, xdata'
elif name == 'symlink':
# Swap 'linkpath' and 'loc'.
s_args_str = '&loc, linkpath, &iatt, xdata'

View File

@ -296,7 +296,7 @@ br_object_read_block_and_sign (xlator_t *this, fd_t *fd, br_child_t *child,
ret = syncop_readv (child->xl, fd,
size, offset, 0, &iovec, &count, &iobref, NULL,
NULL);
NULL, NULL);
if (ret < 0) {
gf_msg (this->name, GF_LOG_ERROR, errno, BRB_MSG_READV_FAILED,

View File

@ -1990,7 +1990,7 @@ svs_readv (call_frame_t *frame, xlator_t *this,
goto out;
}
ret = glfs_pread (glfd, iobuf->ptr, size, offset, 0);
ret = glfs_pread (glfd, iobuf->ptr, size, offset, 0, &fstatbuf);
if (ret < 0) {
op_ret = -1;
op_errno = errno;
@ -2005,16 +2005,6 @@ svs_readv (call_frame_t *frame, xlator_t *this,
iobref = iobref_new ();
iobref_add (iobref, iobuf);
ret = glfs_fstat (glfd, &fstatbuf);
if (ret) {
op_ret = -1;
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR, "glfs_fstat failed after "
"readv on %s", uuid_utoa (fd->inode->gfid));
goto out;
}
iatt_from_stat (&stbuf, &fstatbuf);
gf_uuid_copy (stbuf.ia_gfid, fd->inode->gfid);
svs_fill_ino_from_gfid (&stbuf);