aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/fdso.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/fdso.c')
-rw-r--r--litmus/fdso.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/litmus/fdso.c b/litmus/fdso.c
index b3a95f13d651..aa7b384264e3 100644
--- a/litmus/fdso.c
+++ b/litmus/fdso.c
@@ -25,12 +25,12 @@ static const struct fdso_ops* fdso_ops[] = {
25 &generic_lock_ops, /* SRP_SEM */ 25 &generic_lock_ops, /* SRP_SEM */
26}; 26};
27 27
28static void* fdso_create(obj_type_t type) 28static int fdso_create(void** obj_ref, obj_type_t type, void* __user config)
29{ 29{
30 if (fdso_ops[type]->create) 30 if (fdso_ops[type]->create)
31 return fdso_ops[type]->create(type); 31 return fdso_ops[type]->create(obj_ref, type, config);
32 else 32 else
33 return NULL; 33 return -EINVAL;
34} 34}
35 35
36static void fdso_destroy(obj_type_t type, void* obj) 36static void fdso_destroy(obj_type_t type, void* obj)
@@ -55,20 +55,27 @@ static int fdso_close(struct od_table_entry* entry)
55} 55}
56 56
57/* inode must be locked already */ 57/* inode must be locked already */
58static struct inode_obj_id* alloc_inode_obj(struct inode* inode, 58static int alloc_inode_obj(struct inode_obj_id** obj_ref,
59 obj_type_t type, 59 struct inode* inode,
60 unsigned int id) 60 obj_type_t type,
61 unsigned int id,
62 void* __user config)
61{ 63{
62 struct inode_obj_id* obj; 64 struct inode_obj_id* obj;
63 void* raw_obj; 65 void* raw_obj;
64 66 int err;
65 raw_obj = fdso_create(type);
66 if (!raw_obj)
67 return NULL;
68 67
69 obj = kmalloc(sizeof(*obj), GFP_KERNEL); 68 obj = kmalloc(sizeof(*obj), GFP_KERNEL);
70 if (!obj) 69 if (!obj) {
71 return NULL; 70 return -ENOMEM;
71 }
72
73 err = fdso_create(&raw_obj, type, config);
74 if (err != 0) {
75 kfree(obj);
76 return err;
77 }
78
72 INIT_LIST_HEAD(&obj->list); 79 INIT_LIST_HEAD(&obj->list);
73 atomic_set(&obj->count, 1); 80 atomic_set(&obj->count, 1);
74 obj->type = type; 81 obj->type = type;
@@ -80,7 +87,9 @@ static struct inode_obj_id* alloc_inode_obj(struct inode* inode,
80 atomic_inc(&inode->i_count); 87 atomic_inc(&inode->i_count);
81 88
82 printk(KERN_DEBUG "alloc_inode_obj(%p, %d, %d): object created\n", inode, type, id); 89 printk(KERN_DEBUG "alloc_inode_obj(%p, %d, %d): object created\n", inode, type, id);
83 return obj; 90
91 *obj_ref = obj;
92 return 0;
84} 93}
85 94
86/* inode must be locked already */ 95/* inode must be locked already */
@@ -169,7 +178,7 @@ void exit_od_table(struct task_struct* t)
169static int do_sys_od_open(struct file* file, obj_type_t type, int id, 178static int do_sys_od_open(struct file* file, obj_type_t type, int id,
170 void* __user config) 179 void* __user config)
171{ 180{
172 int idx = 0, err; 181 int idx = 0, err = 0;
173 struct inode* inode; 182 struct inode* inode;
174 struct inode_obj_id* obj = NULL; 183 struct inode_obj_id* obj = NULL;
175 struct od_table_entry* entry; 184 struct od_table_entry* entry;
@@ -183,9 +192,10 @@ static int do_sys_od_open(struct file* file, obj_type_t type, int id,
183 mutex_lock(&inode->i_obj_mutex); 192 mutex_lock(&inode->i_obj_mutex);
184 obj = get_inode_obj(inode, type, id); 193 obj = get_inode_obj(inode, type, id);
185 if (!obj) 194 if (!obj)
186 obj = alloc_inode_obj(inode, type, id); 195 err = alloc_inode_obj(&obj, inode, type, id, config);
187 if (!obj) { 196 if (err != 0) {
188 idx = -ENOMEM; 197 obj = NULL;
198 idx = err;
189 entry->used = 0; 199 entry->used = 0;
190 } else { 200 } else {
191 entry->obj = obj; 201 entry->obj = obj;
@@ -195,12 +205,15 @@ static int do_sys_od_open(struct file* file, obj_type_t type, int id,
195 205
196 mutex_unlock(&inode->i_obj_mutex); 206 mutex_unlock(&inode->i_obj_mutex);
197 207
198 err = fdso_open(entry, config); 208 /* open only if creation succeeded */
209 if (!err)
210 err = fdso_open(entry, config);
199 if (err < 0) { 211 if (err < 0) {
200 /* The class rejected the open call. 212 /* The class rejected the open call.
201 * We need to clean up and tell user space. 213 * We need to clean up and tell user space.
202 */ 214 */
203 put_od_entry(entry); 215 if (obj)
216 put_od_entry(entry);
204 idx = err; 217 idx = err;
205 } 218 }
206 219