aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/fdso.c
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2011-01-29 15:50:52 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2011-02-01 16:53:21 -0500
commit7f0bd4c213ff8dca0eb3bdd887f5c62c8d30fab5 (patch)
tree99b45b5466dc27308e6d65751baf5e109eb37385 /litmus/fdso.c
parentfab768a4cdc49ad7886cac0d0361f8432965a817 (diff)
fdso: pass userpsace config argument to object constructor
As Glenn pointed out, it is useful for some protocols (e.g., k-exclusion protocols) to know the userspace configuration at object creation time. This patch changes the fdso API to pass the parameter to the object constructor, which is then in turn passed to the lock allocater. The return code from the lock allocater is passed to userspace in return. This also fixes some null pointer dereferences in the FDSO code found by the test suite in liblitmus.
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