Merge branch 'tizen_2.4' into tizen_2.4_dev
[kernel/swap-modules.git] / us_manager / img / img_file.c
1 /*
2  *  SWAP uprobe manager
3  *  modules/us_manager/img/img_file.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2013
20  *
21  * 2013  Vyacheslav Cherkashin: SWAP us_manager implement
22  *
23  */
24
25
26 #include "img_file.h"
27 #include "img_ip.h"
28 #include <linux/slab.h>
29 #include <linux/dcache.h>
30
31
32 static void img_del_ip_by_list(struct img_ip *ip);
33
34 /**
35  * @brief Create img_file struct
36  *
37  * @param dentry Dentry of file
38  * @return Pointer to the created img_file struct
39  */
40 struct img_file *create_img_file(struct dentry *dentry)
41 {
42         struct img_file *file;
43
44         file = kmalloc(sizeof(*file), GFP_ATOMIC);
45         if (file == NULL) {
46                 pr_err("%s: failed to allocate memory\n", __func__);
47                 return NULL;
48         }
49
50         file->dentry = dentry;
51         INIT_LIST_HEAD(&file->ip_list);
52         INIT_LIST_HEAD(&file->list);
53
54         return file;
55 }
56
57 /**
58  * @brief Remove img_file struct
59  *
60  * @param file remove object
61  * @return Void
62  */
63 void free_img_file(struct img_file *file)
64 {
65         struct img_ip *ip, *tmp;
66
67         list_for_each_entry_safe(ip, tmp, &file->ip_list, list) {
68                 img_del_ip_by_list(ip);
69                 free_img_ip(ip);
70         }
71
72         kfree(file);
73 }
74
75 static void img_add_ip_by_list(struct img_file *file, struct img_ip *ip)
76 {
77         list_add(&ip->list, &file->ip_list);
78 }
79
80 static void img_del_ip_by_list(struct img_ip *ip)
81 {
82         list_del(&ip->list);
83 }
84
85 static struct img_ip *find_img_ip(struct img_file *file, unsigned long addr,
86                                   struct probe_desc *pd)
87 {
88         struct img_ip *ip;
89
90         list_for_each_entry(ip, &file->ip_list, list) {
91                 if ((ip->addr == addr) &&
92                     (ip->desc == pd))
93                         return ip;
94         }
95
96         return NULL;
97 }
98
99 /**
100  * @brief Add instrumentation pointer
101  *
102  * @param file Pointer to the img_file struct
103  * @param addr Function address
104  * @param probe_Pointer to a probe_info structure with an information about
105  * the probe.
106  * @return Error code
107  */
108 int img_file_add_ip(struct img_file *file, unsigned long addr,
109                     struct probe_desc *pd)
110 {
111         struct img_ip *ip;
112
113         ip = find_img_ip(file, addr, pd);
114         if (ip) {
115                 /* ip already exists in img */
116                 return 0;
117         }
118
119         ip = create_img_ip(addr, pd);
120         if (ip == NULL)
121                 return -ENOMEM;
122         img_add_ip_by_list(file, ip);
123
124         return 0;
125 }
126
127 /**
128  * @brief Delete img_ip struct from img_file struct
129  *
130  * @param file Pointer to the img_file struct
131  * @param addr Function address
132  * @return Error code
133  */
134 int img_file_del_ip(struct img_file *file, unsigned long addr,
135                     struct probe_desc *pd)
136 {
137         struct img_ip *ip;
138
139         ip = find_img_ip(file, addr, pd);
140         if (ip == NULL) {
141                 printk(KERN_INFO "Warning: no ip found in img, addr = %lx\n",
142                        addr);
143                 return -EINVAL;
144         }
145
146         img_del_ip_by_list(ip);
147         free_img_ip(ip);
148
149         return 0;
150 }
151
152 /**
153  * @brief Check on absence img_ip structs in img_file struct
154  *
155  * @param file Pointer to the img_file struct
156  * @return
157  *       - 0 - not empty
158  *       - 1 - empty
159  */
160 int img_file_empty(struct img_file *file)
161 {
162         return list_empty(&file->ip_list);
163 }
164
165 /**
166  * @brief For debug
167  *
168  * @param file Pointer to the img_file struct
169  * @return Void
170  */
171
172 /* debug */
173 void img_file_print(struct img_file *file)
174 {
175         struct img_ip *ip;
176
177         printk(KERN_INFO "###      d_iname=%s\n", file->dentry->d_iname);
178
179         list_for_each_entry(ip, &file->ip_list, list) {
180                 img_ip_print(ip);
181         }
182 }
183 /* debug */