parser: fix dentry usage 28/191028/2
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Wed, 26 Sep 2018 17:50:57 +0000 (20:50 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 11 Oct 2018 18:51:50 +0000 (21:51 +0300)
Change-Id: I4beceae4c89d962345788200c9479d0cf90c293d
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
modules/parser/msg_parser.c
modules/parser/msg_parser.h
modules/parser/us_inst.c

index 285da4df08942144c9691d1f7f3142723d987abf..72e8328c9af689abcea5bacde76552d32333943f 100644 (file)
@@ -982,7 +982,6 @@ struct pr_app_desc *pr_app_desc_create(struct msg_buf *mb)
        }
 
        app->info = app_info;
-       app->pfg = NULL;
        INIT_LIST_HEAD(&app->list);
        INIT_LIST_HEAD(&app->bin_head);
 
@@ -1010,6 +1009,10 @@ struct pr_app_desc *pr_app_desc_create(struct msg_buf *mb)
                goto free_bins;
        }
 
+       /* init private fields */
+       app->priv.pfg = NULL;
+       app->priv.dentry = NULL;
+
        return app;
 
 free_bins:
@@ -1029,6 +1032,9 @@ free_app_inst:
  */
 void pr_app_desc_free(struct pr_app_desc *app)
 {
+       /* check private fields */
+       BUG_ON(app->priv.pfg || app->priv.dentry);
+
        bin_info_list_free(&app->bin_head);
        pr_app_info_free(app->info);
        kfree(app);
index 9620e65d697441a5388029e2478f8d19fe92959a..1367a85cdb5d20c96c5ee7da81b06775b8975f00 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/types.h>
 #include <us_manager/probes/probes.h>
 
+struct dentry;
 struct img_ip;
 struct msg_buf;
 
@@ -90,9 +91,21 @@ struct pr_bin_info {
 struct pr_app_desc {
        struct list_head list;
 
+       /*
+        * Common fields that describe information
+        * about instrumentation points.
+        */
        struct pr_app_info *info;
-       struct pf_group *pfg;
        struct list_head bin_head;
+
+       /*
+        * Private fields that describe the structures
+        * to be held during instrumentation
+        */
+       struct {
+               struct pf_group *pfg;
+               struct dentry *dentry;
+       } priv;
 };
 
 /**
index 78e5dd873de2eb2b189b9939991198b0c6402cd1..082f8fe7381b12830d28599381c3289b0cd0db65 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/errno.h>
 #include <us_manager/pf/pf_group.h>
 #include <us_manager/probes/probes.h>
+#include <us_manager/swap_dcache.h>
 
 #include "msg_parser.h"
 #include "us_inst.h"
@@ -81,54 +82,64 @@ static void bin_inst_unreg(struct pr_bin_desc *bin, struct pf_group *pfg)
 
 static int bin_inst_reg(struct pr_bin_desc *bin, struct pf_group *pfg)
 {
+       int ret = 0;
        struct pr_probe_desc *probe, *n;
        struct dentry *dentry;
        LIST_HEAD(reg_head);
 
-       dentry = dentry_by_path(bin->info->path);
+       dentry = swap_dget_by_path(bin->info->path);
        if (dentry == NULL) {
                pr_warn("Cannot get dentry by path %s\n", bin->info->path);
                return -EINVAL;
        }
 
        list_for_each_entry_safe(probe, n, &bin->probe_head, list) {
-               int ret;
-
                ret = probe_inst_reg(probe, pfg, dentry);
                if (!ret) {
                        list_move(&probe->list, &reg_head);
                } else {
                        do_bin_inst_unreg(&reg_head, pfg);
-                       return ret;
+                       goto put_dentry;
                }
        }
 
        list_splice(&reg_head, &bin->probe_head);
-       return 0;
+put_dentry:
+       swap_dput(dentry);
+       return ret;
 }
 
-static struct pf_group *get_pfg_by_app_info(struct pr_app_info *app)
+static int app_desc_get_priv(struct pr_app_desc *app)
 {
-       struct pf_group *pfg = ERR_PTR(-EINVAL);
+       struct pr_app_info *info = app->info;
+       struct pf_group *pfg = NULL;
        struct dentry *dentry;
 
-       dentry = dentry_by_path(app->path);
-       if (dentry == NULL)
-               return pfg;
+       dentry = swap_dget_by_path(info->path);
+       if (dentry == NULL) {
+               pr_err("Cannot get dentry by path: %s\n", info->path);
+               return -EINVAL;
+       }
 
-       switch (app->type) {
+       switch (info->type) {
        case AT_PID:
-               if (app->tgid == 0) {
-                       if (app->path[0] == '\0')
+               if (info->tgid == 0) {
+                       if (info->path[0] == '\0') {
+                               /*
+                                * FIXME:
+                                *   It is impossible case because
+                                *   swap_dget_by_path("\0") always NULL.
+                                */
                                pfg = get_pf_group_dumb(dentry);
-                       else
+                       } else {
                                goto pf_dentry;
+                       }
                } else {
-                       pfg = get_pf_group_by_tgid(app->tgid, dentry);
+                       pfg = get_pf_group_by_tgid(info->tgid, dentry);
                }
                break;
        case AT_TIZEN_WEB_APP:
-               pfg = get_pf_group_by_comm(app->id, dentry);
+               pfg = get_pf_group_by_comm(info->id, dentry);
                break;
        case AT_TIZEN_NATIVE_APP:
        case AT_COMMON_EXEC:
@@ -136,19 +147,35 @@ static struct pf_group *get_pfg_by_app_info(struct pr_app_info *app)
                pfg = get_pf_group_by_dentry(dentry, dentry);
                break;
        default:
-               pr_info("ERROR: app_type=0x%x\n", app->type);
+               pr_err("Incorrect app_type=0x%x\n", info->type);
                break;
        }
 
-       if (!pfg)
-               pfg = ERR_PTR(-ENOMEM);
-
-       if (!IS_ERR(pfg)) {
-               /* TODO: move to other location and chack return value */
-               pfg_msg_cb_set(pfg, &msg_cb);
+       if (!pfg) {
+               pr_err("Cannot get pfg by: tgid=%d id=%s path=%s\n",
+                      info->tgid, info->id, info->path);
+               swap_dput(dentry);
+               return -ENOMEM;
        }
 
-       return pfg;
+       /* TODO: move to other location and chack return value */
+       pfg_msg_cb_set(pfg, &msg_cb);
+
+       app->priv.pfg = pfg;
+       app->priv.dentry = dentry;
+
+       return 0;
+}
+
+static void app_desc_put_priv(struct pr_app_desc *app)
+{
+       BUG_ON(!app->priv.pfg || !app->priv.dentry);
+
+       put_pf_group(app->priv.pfg);
+       app->priv.pfg = NULL;
+
+       swap_dput(app->priv.dentry);
+       app->priv.dentry = NULL;
 }
 
 static void do_us_app_inst_unreg(struct pr_app_desc *app,
@@ -157,10 +184,10 @@ static void do_us_app_inst_unreg(struct pr_app_desc *app,
        struct pr_bin_desc *bin;
 
        list_for_each_entry(bin, head, list) {
-               bin_inst_unreg(bin, app->pfg);
+               bin_inst_unreg(bin, app->priv.pfg);
        }
-       put_pf_group(app->pfg);
-       app->pfg = NULL;
+
+       app_desc_put_priv(app);
 }
 
 static void us_app_inst_unreg(struct pr_app_desc *app)
@@ -170,19 +197,16 @@ static void us_app_inst_unreg(struct pr_app_desc *app)
 
 static int us_app_inst_reg(struct pr_app_desc *app)
 {
-       struct pf_group *pfg;
+       int ret;
        struct pr_bin_desc *bin, *n;
        LIST_HEAD(reg_head);
 
-       pfg = get_pfg_by_app_info(app->info);
-       if (IS_ERR(pfg))
-               return PTR_ERR(pfg);
+       ret = app_desc_get_priv(app);
+       if (ret)
+               return ret;
 
-       app->pfg = pfg;
        list_for_each_entry_safe(bin, n, &app->bin_head, list) {
-               int ret;
-
-               ret = bin_inst_reg(bin, app->pfg);
+               ret = bin_inst_reg(bin, app->priv.pfg);
                if (!ret) {
                        list_move(&bin->list, &reg_head);
                } else {
@@ -346,7 +370,7 @@ static void app_list_splice(struct list_head *list, struct list_head *head)
                        bin_list_splice(&new_app->bin_head, &app->bin_head);
 
                        list_del(&new_app->list);
-                       put_pf_group(app->pfg);
+                       app_desc_put_priv(new_app);
                        pr_app_desc_free(new_app);
                } else {
                        list_move(&new_app->list, head);