Whamcloud - gitweb
LU-13508 mdc: chlg device could be used after free
[fs/lustre-release.git] / lustre / mdc / mdc_request.c
index 6c7163f..82d1b5e 100644 (file)
@@ -40,6 +40,8 @@
 #include <linux/utsname.h>
 #include <linux/delay.h>
 #include <linux/uidgid.h>
+#include <linux/device.h>
+#include <linux/xarray.h>
 
 #include <lustre_errno.h>
 
@@ -47,6 +49,7 @@
 #include <llog_swab.h>
 #include <lprocfs_status.h>
 #include <lustre_acl.h>
+#include <lustre_compat.h>
 #include <lustre_fid.h>
 #include <uapi/linux/lustre/lustre_ioctl.h>
 #include <lustre_kernelcomm.h>
@@ -542,9 +545,6 @@ static int mdc_unpack_acl(struct ptlrpc_request *req, struct lustre_md *md)
 #else
 #define mdc_unpack_acl(req, md) 0
 #endif
-#ifdef HAVE_XA_IS_VALUE
-# include <linux/xarray.h>
-#endif
 
 int mdc_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req,
                       struct obd_export *dt_exp, struct obd_export *md_exp,
@@ -1141,14 +1141,14 @@ static struct page *mdc_page_locate(struct address_space *mapping, __u64 *hash,
        unsigned long flags;
        int found;
 
-       xa_lock_irqsave(&mapping->i_pages, flags);
+       ll_xa_lock_irqsave(&mapping->i_pages, flags);
        found = radix_tree_gang_lookup(&mapping->page_tree,
                                       (void **)&page, offset, 1);
-       if (found > 0 && !xa_is_value(page)) {
+       if (found > 0 && !ll_xa_is_value(page)) {
                struct lu_dirpage *dp;
 
                get_page(page);
-               xa_unlock_irqrestore(&mapping->i_pages, flags);
+               ll_xa_unlock_irqrestore(&mapping->i_pages, flags);
                /*
                 * In contrast to find_lock_page() we are sure that directory
                 * page cannot be truncated (while DLM lock is held) and,
@@ -1197,7 +1197,7 @@ static struct page *mdc_page_locate(struct address_space *mapping, __u64 *hash,
                        page = ERR_PTR(-EIO);
                }
        } else {
-               xa_unlock_irqrestore(&mapping->i_pages, flags);
+               ll_xa_unlock_irqrestore(&mapping->i_pages, flags);
                page = NULL;
        }
        return page;
@@ -1347,7 +1347,7 @@ static int mdc_read_page_remote(void *data, struct page *page0)
        fid = &op_data->op_fid1;
        LASSERT(inode != NULL);
 
-       OBD_ALLOC(page_pool, sizeof(page_pool[0]) * max_pages);
+       OBD_ALLOC_PTR_ARRAY(page_pool, max_pages);
        if (page_pool != NULL) {
                page_pool[0] = page0;
        } else {
@@ -1416,7 +1416,7 @@ static int mdc_read_page_remote(void *data, struct page *page0)
        }
 
        if (page_pool != &page0)
-               OBD_FREE(page_pool, sizeof(page_pool[0]) * max_pages);
+               OBD_FREE_PTR_ARRAY(page_pool, max_pages);
 
        RETURN(rc);
 }
@@ -1822,6 +1822,7 @@ static int mdc_ioc_hsm_ct_register(struct obd_import *imp, __u32 archive_count,
                *archive_array = archive_count;
 
        ptlrpc_request_set_replen(req);
+       req->rq_no_resend = 1;
 
        rc = mdc_queue_wait(req);
        GOTO(out, rc);
@@ -2044,34 +2045,51 @@ static int mdc_ioc_hsm_ct_start(struct obd_export *exp,
 static int mdc_quotactl(struct obd_device *unused, struct obd_export *exp,
                         struct obd_quotactl *oqctl)
 {
-       struct ptlrpc_request   *req;
-       struct obd_quotactl     *oqc;
-       int                      rc;
+       struct ptlrpc_request *req;
+       struct obd_quotactl *oqc;
+       int rc;
        ENTRY;
 
-       req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp),
-                                       &RQF_MDS_QUOTACTL, LUSTRE_MDS_VERSION,
-                                       MDS_QUOTACTL);
+       req = ptlrpc_request_alloc(class_exp2cliimp(exp), &RQF_MDS_QUOTACTL);
        if (req == NULL)
                RETURN(-ENOMEM);
 
+
+       if (LUSTRE_Q_CMD_IS_POOL(oqctl->qc_cmd))
+               req_capsule_set_size(&req->rq_pill,
+                                    &RMF_OBD_QUOTACTL,
+                                    RCL_CLIENT,
+                                    sizeof(*oqc) + LOV_MAXPOOLNAME + 1);
+
+       rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION,
+                                MDS_QUOTACTL);
+       if (rc) {
+               ptlrpc_request_free(req);
+               RETURN(rc);
+       }
+
        oqc = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL);
-       *oqc = *oqctl;
+       QCTL_COPY(oqc, oqctl);
 
        ptlrpc_request_set_replen(req);
        ptlrpc_at_set_req_timeout(req);
 
        rc = ptlrpc_queue_wait(req);
-       if (rc)
-               CERROR("ptlrpc_queue_wait failed, rc: %d\n", rc);
+       if (rc) {
+               CERROR("%s: ptlrpc_queue_wait failed: rc = %d\n",
+                      exp->exp_obd->obd_name, rc);
+               GOTO(out, rc);
+       }
 
        if (req->rq_repmsg &&
            (oqc = req_capsule_server_get(&req->rq_pill, &RMF_OBD_QUOTACTL))) {
-               *oqctl = *oqc;
+               QCTL_COPY(oqctl, oqc);
        } else if (!rc) {
-               CERROR ("Can't unpack obd_quotactl\n");
                rc = -EPROTO;
+               CERROR("%s: cannot unpack obd_quotactl: rc = %d\n",
+                       exp->exp_obd->obd_name, rc);
        }
+out:
        ptlrpc_req_finished(req);
 
        RETURN(rc);
@@ -2957,15 +2975,43 @@ static const struct md_ops mdc_md_ops = {
        .m_rmfid                = mdc_rmfid,
 };
 
+dev_t mdc_changelog_dev;
+struct class *mdc_changelog_class;
 static int __init mdc_init(void)
 {
-       return class_register_type(&mdc_obd_ops, &mdc_md_ops, true, NULL,
-                                  LUSTRE_MDC_NAME, &mdc_device_type);
+       int rc = 0;
+       rc = alloc_chrdev_region(&mdc_changelog_dev, 0,
+                                MDC_CHANGELOG_DEV_COUNT,
+                                MDC_CHANGELOG_DEV_NAME);
+       if (rc)
+               return rc;
+
+       mdc_changelog_class = class_create(THIS_MODULE, MDC_CHANGELOG_DEV_NAME);
+       if (IS_ERR(mdc_changelog_class)) {
+               rc = PTR_ERR(mdc_changelog_class);
+               goto out_dev;
+       }
+
+       rc = class_register_type(&mdc_obd_ops, &mdc_md_ops, true, NULL,
+                                LUSTRE_MDC_NAME, &mdc_device_type);
+       if (rc)
+               goto out_class;
+
+       return 0;
+
+out_class:
+       class_destroy(mdc_changelog_class);
+out_dev:
+       unregister_chrdev_region(mdc_changelog_dev, MDC_CHANGELOG_DEV_COUNT);
+       return rc;
 }
 
 static void __exit mdc_exit(void)
 {
-        class_unregister_type(LUSTRE_MDC_NAME);
+       class_unregister_type(LUSTRE_MDC_NAME);
+       class_destroy(mdc_changelog_class);
+       unregister_chrdev_region(mdc_changelog_dev, MDC_CHANGELOG_DEV_COUNT);
+       idr_destroy(&mdc_changelog_minor_idr);
 }
 
 MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");