diff options
Diffstat (limited to 'litmus/fdso.c')
-rw-r--r-- | litmus/fdso.c | 51 |
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 | ||
28 | static void* fdso_create(obj_type_t type) | 28 | static 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 | ||
36 | static void fdso_destroy(obj_type_t type, void* obj) | 36 | static 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 */ |
58 | static struct inode_obj_id* alloc_inode_obj(struct inode* inode, | 58 | static 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) | |||
169 | static int do_sys_od_open(struct file* file, obj_type_t type, int id, | 178 | static 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 | ||