ipc_rcu_putref(sma);
}
-static inline void sem_read_lock_and_putref(struct sem_array *sma)
-{
- ipc_read_lock_by_ptr(&sma->sem_perm);
- ipc_rcu_putref(sma);
-}
-
static inline void sem_getref_and_unlock(struct sem_array *sma)
{
ipc_rcu_getref(sma);
ushort* sem_io = fast_sem_io;
int nsems;
struct list_head tasks;
- int write_locked = 0;
- sma = sem_read_lock_check(ns, semid);
+ sma = sem_lock_check(ns, semid);
if (IS_ERR(sma))
return PTR_ERR(sma);
int i;
if(nsems > SEMMSL_FAST) {
- sem_getref_and_read_unlock(sma);
+ sem_getref_and_unlock(sma);
sem_io = ipc_alloc(sizeof(ushort)*nsems);
if(sem_io == NULL) {
return -ENOMEM;
}
- sem_read_lock_and_putref(sma);
+ sem_lock_and_putref(sma);
if (sma->sem_perm.deleted) {
+ sem_unlock(sma);
err = -EIDRM;
- goto out_unlock;
+ goto out_free;
}
}
for (i = 0; i < sma->sem_nsems; i++)
sem_io[i] = sma->sem_base[i].semval;
- sem_read_unlock(sma);
+ sem_unlock(sma);
err = 0;
if(copy_to_user(array, sem_io, nsems*sizeof(ushort)))
err = -EFAULT;
struct sem_undo *un;
LIST_HEAD(pending);
- sem_getref_and_read_unlock(sma);
+ sem_getref_and_unlock(sma);
if(nsems > SEMMSL_FAST) {
sem_io = ipc_alloc(sizeof(ushort)*nsems);
goto out_free;
}
}
- sem_read_lock_and_putref(sma);
-
- /* no new undos can come in while we have the read lock
- * but we have to take the write lock if there are any
- */
- if (!list_empty(&sma->list_id)) {
- sem_getref_and_read_unlock(sma);
- sem_lock_and_putref(sma);
- write_locked = 1;
- }
+ sem_lock_and_putref(sma);
if (sma->sem_perm.deleted) {
+ sem_unlock(sma);
err = -EIDRM;
- goto out_unlock;
+ goto out_free;
}
for (i = 0; i < nsems; i++) {
if (val > SEMVMX || val < 0)
goto out_unlock;
- if (!list_empty(&sma->list_id)) {
- sem_getref_and_read_unlock(sma);
- sem_lock_and_putref(sma);
- write_locked = 1;
- }
- if (sma->sem_perm.deleted) {
- err = -EIDRM;
- goto out_unlock;
- }
-
+ //assert_spin_locked(&sma->sem_perm.lock);
list_for_each_entry(un, &sma->list_id, list_id)
un->semadj[semnum] = 0;
}
}
out_unlock:
- if (write_locked)
- sem_unlock(sma);
- else
- sem_read_unlock(sma);
+ sem_unlock(sma);
wake_up_sem_queue_do(&tasks);
out_free: