diff --git a/qtfs/qtfs/sb.c b/qtfs/qtfs/sb.c index 46b30c2969a89e0a81ac1ef65d9bfae79aa8107d..40d25f72f4b0cf7436b7a3dcb6510c30b8454555 100644 --- a/qtfs/qtfs/sb.c +++ b/qtfs/qtfs/sb.c @@ -18,7 +18,7 @@ static struct inode_operations qtfs_inode_ops; static struct inode_operations qtfs_symlink_inode_ops; struct inode *qtfs_iget(struct super_block *sb, struct inode_info *ii); - +extern ssize_t qtfs_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size); int qtfs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct qtfs_sock_var_s *pvar = qtfs_conn_get_param(); @@ -1338,12 +1338,14 @@ static struct inode_operations qtfs_inode_ops = { .getattr = qtfs_getattr, .setattr = qtfs_setattr, .rename = qtfs_rename, + .listxattr = qtfs_xattr_list, }; static struct inode_operations qtfs_symlink_inode_ops = { .get_link = qtfs_getlink, .getattr = qtfs_getattr, .setattr = qtfs_setattr, + .listxattr = qtfs_xattr_list, }; const struct xattr_handler *qtfs_xattr_handlers[] = { diff --git a/qtfs/qtfs/xattr.c b/qtfs/qtfs/xattr.c index a0d394ac2b8f47b9cb590f82bff9f3672638e543..a2a605d3d36b56fe3c75b8cc77e9bd0569342344 100644 --- a/qtfs/qtfs/xattr.c +++ b/qtfs/qtfs/xattr.c @@ -6,69 +6,52 @@ #include "req.h" #include "log.h" -static bool qtfs_xattr_list(struct dentry *dentry) +ssize_t qtfs_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size) { struct qtreq_xattrlist *req; struct qtrsp_xattrlist *rsp; struct qtfs_sock_var_s *pvar = qtfs_conn_get_param(); - bool ret; + ssize_t ret; if (!pvar) { qtfs_err("qtfs_xattr_list Failed to get qtfs sock var"); - return -EINVAL; + return 0; } if (dentry == NULL) { qtfs_err("qtfs_xattr_list dentry is NULL."); qtfs_conn_put_param(pvar); - return false; + return 0; } req = qtfs_sock_msg_buf(pvar, QTFS_SEND); if (qtfs_fullname(req->path, dentry) < 0) { qtfs_err("qtfs fullname failed"); qtfs_conn_put_param(pvar); - return false; + return 0; } - - rsp = qtfs_remote_run(pvar, QTFS_REQ_XATTRLIST, strlen(req->path) + 1); + req->buffer_size = buffer_size; + rsp = qtfs_remote_run(pvar, QTFS_REQ_XATTRLIST, QTFS_SEND_SIZE(struct qtreq_xattrlist, req->path)); if (IS_ERR(rsp) || rsp == NULL) { qtfs_err("qtfs_xattr_list remote run failed."); qtfs_conn_put_param(pvar); - return false; + return 0; } if (rsp->d.ret == QTFS_ERR) { qtfs_err("qtfs_xattr_list failed with ret:%d.", rsp->d.ret); - ret = rsp->d.result; + ret = rsp->d.size; qtfs_conn_put_param(pvar); return ret; } - ret = rsp->d.result; + ret = rsp->d.size; + if (buffer != NULL) { + memcpy(buffer, rsp->name, buffer_size); + } qtfs_conn_put_param(pvar); return ret; } -static bool qtfs_xattr_user_list(struct dentry *dentry) -{ - return qtfs_xattr_list(dentry); -} - -static bool qtfs_xattr_trusted_list(struct dentry *dentry) -{ - return qtfs_xattr_list(dentry); -} - -static bool qtfs_xattr_security_list(struct dentry *dentry) -{ - return qtfs_xattr_list(dentry); -} - -static bool qtfs_xattr_hurd_list(struct dentry *dentry) -{ - return qtfs_xattr_list(dentry); -} - static int qtfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, const void *value, @@ -177,12 +160,6 @@ static int qtfs_xattr_get(const struct xattr_handler *handler, qtfs_err("Failed to get qtfs sock var"); return 0; } - /*if (buf == NULL || size <= 0) { - qtfs_err("xattr get failed, buf:%lx size:%d name:%s dentry:%lx", - (unsigned long)buf, size, (name == NULL) ? "NULL" : name, (unsigned long)dentry); - qtfs_conn_put_param(pvar); - return 0; - }*/ if (dentry == NULL) { qtfs_err("xattr get dentry is NULL."); @@ -216,7 +193,7 @@ static int qtfs_xattr_get(const struct xattr_handler *handler, qtfs_conn_put_param(pvar); return PTR_ERR(rsp); } - if (rsp->d.ret == QTFS_ERR || rsp->d.size > req->d.size || leftlen < rsp->d.size) { + if (rsp->d.ret == QTFS_ERR || (size !=0 && (rsp->d.size > req->d.size || leftlen < rsp->d.size))) { qtfs_err("ret:%d rsp size:%ld req size:%d leftlen:%lu", rsp->d.ret, rsp->d.size, req->d.size, leftlen); goto err_end; @@ -239,28 +216,24 @@ err_end: const struct xattr_handler qtfs_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, - .list = qtfs_xattr_user_list, .get = qtfs_xattr_get, .set = qtfs_xattr_user_set, }; const struct xattr_handler qtfs_xattr_trusted_handler = { .prefix = XATTR_TRUSTED_PREFIX, - .list = qtfs_xattr_trusted_list, .get = qtfs_xattr_get, .set = qtfs_xattr_trusted_set, }; const struct xattr_handler qtfs_xattr_security_handler = { .prefix = XATTR_SECURITY_PREFIX, - .list = qtfs_xattr_security_list, .get = qtfs_xattr_get, .set = qtfs_xattr_security_set, }; const struct xattr_handler qtfs_xattr_hurd_handler = { .prefix = XATTR_HURD_PREFIX, - .list = qtfs_xattr_hurd_list, .get = qtfs_xattr_get, .set = qtfs_xattr_hurd_set, }; diff --git a/qtfs/qtfs_server/fsops.c b/qtfs/qtfs_server/fsops.c index d00db6d2f38645f3bb90e7438ff204dddf178840..60dfae16b35a0d3bbf9892efe8106bf9f217613a 100644 --- a/qtfs/qtfs_server/fsops.c +++ b/qtfs/qtfs_server/fsops.c @@ -866,26 +866,27 @@ int handle_xattrlist(struct qtserver_arg *arg) struct qtrsp_xattrlist *rsp = (struct qtrsp_xattrlist *)RSP(arg); struct path path; int ret; - ssize_t size; + ssize_t size, buffer_size; int i; + buffer_size = req->buffer_size; ret = kern_path(req->path, 0, &path); if (ret) { qtfs_err("handle xattr list path error.\n"); - rsp->d.errno = -ENOENT; + rsp->d.size = -ENOENT; goto err_handle; } - size = generic_listxattr(path.dentry, rsp->name, sizeof(rsp->name)); + size = vfs_listxattr(path.dentry, buffer_size == 0 ? NULL : rsp->name, buffer_size); path_put(&path); if (size < 0) { qtfs_err("handle list xattr failed, errno:%ld.\n", size); - rsp->d.errno = size; + rsp->d.size = size; goto err_handle; } if (size == 0) goto err_handle; rsp->d.ret = QTFS_OK; - rsp->d.result = true; + rsp->d.size = size; while (i < size) { qtfs_info("handle list xattr result:%s\n", &rsp->name[i]); i += strlen(&rsp->name[i]) + 1; @@ -894,7 +895,7 @@ int handle_xattrlist(struct qtserver_arg *arg) err_handle: rsp->d.ret = QTFS_ERR; - rsp->d.result = false; + rsp->d.size = size; return sizeof(struct qtrsp_xattrlist); } @@ -970,9 +971,9 @@ int handle_xattrget(struct qtserver_arg *arg) } qtfs_info("handle getxattr: path:%s prefix name:%s : (%s - 0x%llx), size:%ld, reqpos:%d\n", req->path, req->d.prefix_name, kvalue, (__u64)kvalue, error, req->d.pos); len = (error - req->d.pos)>sizeof(rsp->buf)? sizeof(rsp->buf):(error - req->d.pos); + rsp->d.size = len; if (req->d.size > 0) { memcpy(rsp->buf, &kvalue[req->d.pos], len); - rsp->d.size = len; } rsp->d.pos = req->d.pos + len; } else { diff --git a/qtfs/req.h b/qtfs/req.h index 82759edb3e0979342ed85f41d52b4d00b45e6fb3..a4b0a3f19e6a47b695108b27f7129f3634830a12 100644 --- a/qtfs/req.h +++ b/qtfs/req.h @@ -414,14 +414,14 @@ struct qtrsp_rename { // xattr def #define QTFS_XATTR_LEN 64 struct qtreq_xattrlist { + size_t buffer_size; char path[MAX_PATH_LEN]; }; struct qtrsp_xattrlist { struct qtrsp_xattrlist_len { int ret; - int errno; - bool result; + ssize_t size; }d; char name[QTFS_TAIL_LEN(struct qtrsp_xattrlist_len)]; };