* @param dentry Dentry of file
* @return Pointer to the created img_file struct
*/
-struct img_file *create_img_file(struct dentry *dentry)
+struct img_file *img_file_create(struct dentry *dentry)
{
struct img_file *file;
file->dentry = dentry;
INIT_LIST_HEAD(&file->ip_list);
INIT_LIST_HEAD(&file->list);
+ atomic_set(&file->use, 1);
return file;
}
* @param file remove object
* @return Void
*/
-void free_img_file(struct img_file *file)
+static void img_file_free(struct img_file *file)
{
struct img_ip *ip, *tmp;
list_del(&ip->list);
}
+void img_file_get(struct img_file *file)
+{
+ WARN_ON(!atomic_read(&file->use));
+ atomic_inc(&file->use);
+}
+
+void img_file_put(struct img_file *file)
+{
+ if (atomic_dec_and_test(&file->use))
+ img_file_free(file);
+
+ return;
+}
+
static struct img_ip *find_img_ip(struct img_file *file, unsigned long addr,
struct probe_desc *pd)
{
struct list_head list; /**< For img_proc */
struct dentry *dentry; /**< Dentry of file */
struct list_head ip_list; /**< For img_ip */
+ atomic_t use;
};
-struct img_file *create_img_file(struct dentry *dentry);
-void free_img_file(struct img_file *ip);
+struct img_file *img_file_create(struct dentry *dentry);
+void img_file_get(struct img_file *file);
+void img_file_put(struct img_file *file);
int img_file_add_ip(struct img_file *file, unsigned long addr,
struct probe_desc *pd);
{
struct img_file *file, *tmp;
+ write_lock(&proc->rwlock);
list_for_each_entry_safe(file, tmp, &proc->file_list, list) {
img_del_file_by_list(file);
- free_img_file(file);
+ img_file_put(file);
}
+ write_unlock(&proc->rwlock);
kfree(proc);
}
}
/* called with read_[lock/unlock](&proc->rwlock) */
-static struct img_file *find_img_file(struct img_proc *proc,
- struct dentry *dentry)
+static struct img_file *img_file_find_get(struct img_proc *proc,
+ struct dentry *dentry)
{
struct img_file *file;
list_for_each_entry(file, &proc->file_list, list) {
- if (file->dentry == dentry)
+ if (file->dentry == dentry) {
+ img_file_get(file);
return file;
+ }
}
return NULL;
struct img_file *file;
write_lock(&proc->rwlock);
- file = find_img_file(proc, dentry);
- if (file) {
- ret = img_file_add_ip(file, addr, pd);
- goto unlock;
- }
+ file = img_file_find_get(proc, dentry);
+ write_unlock(&proc->rwlock);
+
+ if (!file) {
+ file = img_file_create(dentry);
+ if (!file)
+ return -ENOMEM;
- file = create_img_file(dentry);
- if (file == NULL) {
- ret = -ENOMEM;
- goto unlock;
+ img_file_get(file);
+ write_lock(&proc->rwlock);
+ img_add_file_by_list(proc, file);
+ write_unlock(&proc->rwlock);
}
ret = img_file_add_ip(file, addr, pd);
- if (ret) {
+ if (ret)
printk(KERN_INFO "Cannot add ip to img file\n");
- free_img_file(file);
- } else {
- img_add_file_by_list(proc, file);
- }
-unlock:
- write_unlock(&proc->rwlock);
+ img_file_put(file);
return ret;
}
struct img_file *file;
write_lock(&proc->rwlock);
- file = find_img_file(proc, dentry);
- if (file == NULL) {
- ret = -EINVAL;
- goto unlock;
- }
+ file = img_file_find_get(proc, dentry);
+ write_unlock(&proc->rwlock);
+
+ if (!file)
+ return -EINVAL;
ret = img_file_del_ip(file, addr, pd);
if (ret == 0 && img_file_empty(file)) {
+ write_lock(&proc->rwlock);
img_del_file_by_list(file);
- free_img_file(file);
+ write_unlock(&proc->rwlock);
+ img_file_put(file);
}
-unlock:
- write_unlock(&proc->rwlock);
- return ret;
+ img_file_put(file);
+
+ return 0;
}
void img_proc_copy_to_sspt(struct img_proc *i_proc, struct sspt_proc *proc)