diff --git a/qtfs/log.h b/qtfs/log.h index d4d0d928a4c24cfa927be530413e2d2ec0d7e2b4..bd1d60fd20a0ffe4115a889c8e8aebd835f0c32c 100644 --- a/qtfs/log.h +++ b/qtfs/log.h @@ -13,6 +13,12 @@ enum level { extern int log_level; +#define qtfs_crit(fmt, ...) \ + {\ + pr_crit("[%s::%s:%4d] " fmt,\ + KBUILD_MODNAME, kbasename(__FILE__), __LINE__, ##__VA_ARGS__);\ + } + #define qtfs_err(fmt, ...) \ ( \ { \ diff --git a/qtfs/qtfs/sb.c b/qtfs/qtfs/sb.c index e10e7cdb89b765c458defda338b2ad0917ff442b..3c694d5bf84aee05e3cd9346d662ee8b77c05639 100644 --- a/qtfs/qtfs/sb.c +++ b/qtfs/qtfs/sb.c @@ -304,7 +304,8 @@ ssize_t qtfs_readiter(struct kiocb *kio, struct iov_iter *iov) return PTR_ERR(rsp); } if (rsp->d.ret == QTFS_ERR || rsp->d.len <= 0) { - qtfs_info("qtfs readiter error."); + if (rsp->d.len != 0) + qtfs_info("qtfs readiter error."); ret = (ssize_t)rsp->d.len; qtfs_conn_put_param(pvar); return ret; diff --git a/qtfs/qtfs/xattr.c b/qtfs/qtfs/xattr.c index 12398d1283cba43e421878dd8a140c34f50245f0..a0d394ac2b8f47b9cb590f82bff9f3672638e543 100644 --- a/qtfs/qtfs/xattr.c +++ b/qtfs/qtfs/xattr.c @@ -69,6 +69,100 @@ 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, + size_t size, int flags); + +static int +qtfs_xattr_user_set(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, const void *value, + size_t size, int flags) + +{ + return qtfs_xattr_set(handler, unused, inode, name, value, size, flags); +} + +static int +qtfs_xattr_trusted_set(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, const void *value, + size_t size, int flags) +{ + return qtfs_xattr_set(handler, unused, inode, name, value, size, flags); +} + +static int +qtfs_xattr_security_set(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, const void *value, + size_t size, int flags) +{ + return qtfs_xattr_set(handler, unused, inode, name, value, size, flags); +} + +static int +qtfs_xattr_hurd_set(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, const void *value, + size_t size, int flags) +{ + return qtfs_xattr_set(handler, unused, inode, name, value, size, flags); +} + +static int qtfs_xattr_set(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, const void *value, + size_t size, int flags) +{ + struct qtreq_xattrset *req; + struct qtrsp_xattrset *rsp; + struct qtfs_sock_var_s *pvar = qtfs_conn_get_param(); + int ret; + + if (!pvar) { + qtfs_err("failed to get qtfs sock var"); + return -ENOMEM; + } + if (dentry == NULL) { + qtfs_conn_put_param(pvar); + return -ENOENT; + } + req = qtfs_sock_msg_buf(pvar, QTFS_SEND); + if (qtfs_fullname(req->buf, dentry) < 0) { + qtfs_err("xattr set get fullname failed."); + qtfs_conn_put_param(pvar); + return -EFAULT; + } + req->d.size = size; + req->d.flags = flags; + req->d.pathlen = strlen(req->buf) + 1; + req->d.namelen = strlen(name) + strlen(handler->prefix) + 1; + qtfs_info("xattr set path:%s name:%s size:%lu", req->buf, name, size); + if (req->d.pathlen + req->d.namelen + strlen(handler->prefix) + size > sizeof(req->buf)) { + qtfs_err("xattr set namelen:%d size:%lu is too long", req->d.namelen, size); + qtfs_conn_put_param(pvar); + return -EFAULT; + } + strncpy(&req->buf[req->d.pathlen], handler->prefix, strlen(handler->prefix)); + strcat(&req->buf[req->d.pathlen], name); + memcpy(&req->buf[req->d.pathlen + req->d.namelen], value, size); + rsp = qtfs_remote_run(pvar, QTFS_REQ_XATTRSET, sizeof(struct qtreq_xattrset) - sizeof(req->buf) + req->d.pathlen + req->d.namelen + req->d.size); + if (IS_ERR(rsp) || rsp == NULL) { + qtfs_conn_put_param(pvar); + return PTR_ERR(rsp); + } + if (rsp->errno < 0) { + qtfs_err("xattr set failed file:%s name:%s", req->buf, name); + } else { + qtfs_info("xattr set successed file:%s name:%s", req->buf, name); + } + ret = rsp->errno; + qtfs_conn_put_param(pvar); + return ret; +} + static int qtfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size) @@ -83,12 +177,15 @@ 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) { + /*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."); qtfs_conn_put_param(pvar); return 0; } @@ -114,18 +211,18 @@ static int qtfs_xattr_get(const struct xattr_handler *handler, req->d.pos = rsp->d.pos; req->d.size = size; rsp = qtfs_remote_run(pvar, QTFS_REQ_XATTRGET, QTFS_SEND_SIZE(struct qtreq_xattrget, req->path)); - if (IS_ERR(rsp) || rsp == NULL) { + if (IS_ERR(rsp) || rsp == NULL) { + qtfs_err("rsp invalid, file:%s", req->path); 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) { + 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; } - if (rsp->d.size > 0 && rsp->d.size <= leftlen) { + if (size > 0 && rsp->d.size <= leftlen) { memcpy(&buf[size - leftlen], rsp->buf, rsp->d.size); - } else { - qtfs_err("qtfs xattr get error <%s>, rsp size:%ld leftlen:%lu", req->path, rsp->d.size, leftlen); - break; } leftlen -= rsp->d.size; } while (leftlen > 0 && rsp->d.size > 0); @@ -144,26 +241,26 @@ const struct xattr_handler qtfs_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .list = qtfs_xattr_user_list, .get = qtfs_xattr_get, - //.set = qtfs_xattr_set, + .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_set, + .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_set, + .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_set, + .set = qtfs_xattr_hurd_set, }; diff --git a/qtfs/qtfs_server/fsops.c b/qtfs/qtfs_server/fsops.c index f1705b2226fccfbedbde964106c0fbdd925bbcdf..50a5e2d59102fbd2911c0eaf40e0866099a5d9f4 100644 --- a/qtfs/qtfs_server/fsops.c +++ b/qtfs/qtfs_server/fsops.c @@ -803,6 +803,31 @@ err_handle: return sizeof(struct qtrsp_xattrlist); } +int handle_xattrset(struct qtserver_arg *arg) +{ + struct qtreq_xattrset *req = (struct qtreq_xattrset *)REQ(arg); + struct qtrsp_xattrset *rsp = (struct qtrsp_xattrset *)RSP(arg); + struct path path; + int ret = 0; + + ret = kern_path(req->buf, 0, &path); + if (ret) { + qtfs_err("handle xattrset path error, file:%s.\n", req->buf); + rsp->errno = -ENOENT; + rsp->ret = QTFS_ERR; + goto err_handle; + } + + rsp->errno = vfs_setxattr(path.dentry, &req->buf[req->d.pathlen], &req->buf[req->d.pathlen + req->d.namelen], req->d.size, req->d.flags); + qtfs_info("handle xattrset path:%s name:%s value:%s ret:%d size:%lu flags:%d", req->buf, + &req->buf[req->d.pathlen], &req->buf[req->d.pathlen + req->d.namelen], rsp->errno, + req->d.size, req->d.flags); + return sizeof(struct qtrsp_xattrset); + +err_handle: + return sizeof(struct qtrsp_xattrset); +} + int handle_xattrget(struct qtserver_arg *arg) { struct qtreq_xattrget *req = (struct qtreq_xattrget *)REQ(arg); @@ -820,15 +845,17 @@ int handle_xattrget(struct qtserver_arg *arg) goto err_handle; } - if (req->d.size > XATTR_SIZE_MAX) - req->d.size = XATTR_SIZE_MAX; - kvalue = (char *)kvzalloc(req->d.size, GFP_KERNEL); - if (!kvalue) { - qtfs_err("handle xattrget kvzalloc failed, size:%d.\n", req->d.size); - rsp->d.ret = QTFS_ERR; - rsp->d.errno = -ENOMEM; - path_put(&path); - goto err_handle; + if (req->d.size != 0) { + if (req->d.size > XATTR_SIZE_MAX) + req->d.size = XATTR_SIZE_MAX; + kvalue = (char *)kvzalloc(req->d.size, GFP_KERNEL); + if (!kvalue) { + qtfs_err("handle xattrget kvzalloc failed, size:%d.\n", req->d.size); + rsp->d.ret = QTFS_ERR; + rsp->d.errno = -ENOMEM; + path_put(&path); + goto err_handle; + } } error = vfs_getxattr(path.dentry, req->d.prefix_name, kvalue, req->d.size); @@ -841,9 +868,11 @@ 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); - memcpy(rsp->buf, &kvalue[req->d.pos], 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; - rsp->d.size = len; } else { rsp->d.ret = QTFS_ERR; rsp->d.errno = error; @@ -851,19 +880,16 @@ int handle_xattrget(struct qtserver_arg *arg) goto err_handle; } end: + qtfs_info("handle getxattr successed file:%s result:%s", req->path, rsp->buf); kvfree(kvalue); rsp->d.ret = QTFS_OK; return sizeof(struct qtrsp_xattrget) - sizeof(rsp->buf) + len; err_handle: + qtfs_err("handle getxattr failed, file:%s", req->path); return sizeof(struct qtrsp_xattrget) - sizeof(rsp->buf); } -int handle_xattrset(struct qtserver_arg *arg) -{ - return 0; -} - long qtfs_do_mount(const char *dev_name, const char *dir_name, const char *type_page, unsigned long flags, void *data_page) { @@ -1122,9 +1148,10 @@ int qtfs_sock_server_run(struct qtfs_sock_var_s *pvar) qtinfo_recvinc(req->type); } if (rsp->len > QTFS_REQ_MAX_LEN) { - qtfs_err("handle rsp len error type:%d len:%lu", rsp->type, rsp->len); + qtfs_crit("handle rsp len error type:%d len:%lu", rsp->type, rsp->len); WARN_ON(1); - continue; + rsp->len = QTFS_REQ_MAX_LEN - 1; + rsp->err = QTFS_ERR; } rsp->seq_num = req->seq_num; pvar->vec_send.iov_len = QTFS_MSG_LEN - QTFS_REQ_MAX_LEN + rsp->len; diff --git a/qtfs/req.h b/qtfs/req.h index 7e89ce4f586fe8c977a93da52b3e6401f99d3324..9c4cd8b80760b3155af8043e704547e1324fc42b 100644 --- a/qtfs/req.h +++ b/qtfs/req.h @@ -459,6 +459,23 @@ struct qtrsp_xattrget { }d; char buf[QTFS_TAIL_LEN(struct qtrsp_xattrget_len)]; }; + +struct qtreq_xattrset { + struct qtreq_xattrset_len { + size_t size; + int flags; + int pathlen; + int namelen; + int valuelen; + } d; + /* buf: file path + name + value */ + char buf[QTFS_TAIL_LEN(struct qtreq_xattrset_len)]; +}; + +struct qtrsp_xattrset { + int ret; + int errno; +}; // xattr end struct qtreq_sysmount {