aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/shm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/shm.c')
-rw-r--r--ipc/shm.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index 6f9615c09fb2..f806a2e314e0 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -30,6 +30,7 @@
30#include <linux/capability.h> 30#include <linux/capability.h>
31#include <linux/ptrace.h> 31#include <linux/ptrace.h>
32#include <linux/seq_file.h> 32#include <linux/seq_file.h>
33#include <linux/mutex.h>
33 34
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
35 36
@@ -109,7 +110,7 @@ static void shm_open (struct vm_area_struct *shmd)
109 * 110 *
110 * @shp: struct to free 111 * @shp: struct to free
111 * 112 *
112 * It has to be called with shp and shm_ids.sem locked, 113 * It has to be called with shp and shm_ids.mutex locked,
113 * but returns with shp unlocked and freed. 114 * but returns with shp unlocked and freed.
114 */ 115 */
115static void shm_destroy (struct shmid_kernel *shp) 116static void shm_destroy (struct shmid_kernel *shp)
@@ -139,7 +140,7 @@ static void shm_close (struct vm_area_struct *shmd)
139 int id = file->f_dentry->d_inode->i_ino; 140 int id = file->f_dentry->d_inode->i_ino;
140 struct shmid_kernel *shp; 141 struct shmid_kernel *shp;
141 142
142 down (&shm_ids.sem); 143 mutex_lock(&shm_ids.mutex);
143 /* remove from the list of attaches of the shm segment */ 144 /* remove from the list of attaches of the shm segment */
144 if(!(shp = shm_lock(id))) 145 if(!(shp = shm_lock(id)))
145 BUG(); 146 BUG();
@@ -151,7 +152,7 @@ static void shm_close (struct vm_area_struct *shmd)
151 shm_destroy (shp); 152 shm_destroy (shp);
152 else 153 else
153 shm_unlock(shp); 154 shm_unlock(shp);
154 up (&shm_ids.sem); 155 mutex_unlock(&shm_ids.mutex);
155} 156}
156 157
157static int shm_mmap(struct file * file, struct vm_area_struct * vma) 158static int shm_mmap(struct file * file, struct vm_area_struct * vma)
@@ -270,7 +271,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
270 struct shmid_kernel *shp; 271 struct shmid_kernel *shp;
271 int err, id = 0; 272 int err, id = 0;
272 273
273 down(&shm_ids.sem); 274 mutex_lock(&shm_ids.mutex);
274 if (key == IPC_PRIVATE) { 275 if (key == IPC_PRIVATE) {
275 err = newseg(key, shmflg, size); 276 err = newseg(key, shmflg, size);
276 } else if ((id = ipc_findkey(&shm_ids, key)) == -1) { 277 } else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
@@ -296,7 +297,7 @@ asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
296 } 297 }
297 shm_unlock(shp); 298 shm_unlock(shp);
298 } 299 }
299 up(&shm_ids.sem); 300 mutex_unlock(&shm_ids.mutex);
300 301
301 return err; 302 return err;
302} 303}
@@ -467,14 +468,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
467 return err; 468 return err;
468 469
469 memset(&shm_info,0,sizeof(shm_info)); 470 memset(&shm_info,0,sizeof(shm_info));
470 down(&shm_ids.sem); 471 mutex_lock(&shm_ids.mutex);
471 shm_info.used_ids = shm_ids.in_use; 472 shm_info.used_ids = shm_ids.in_use;
472 shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp); 473 shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
473 shm_info.shm_tot = shm_tot; 474 shm_info.shm_tot = shm_tot;
474 shm_info.swap_attempts = 0; 475 shm_info.swap_attempts = 0;
475 shm_info.swap_successes = 0; 476 shm_info.swap_successes = 0;
476 err = shm_ids.max_id; 477 err = shm_ids.max_id;
477 up(&shm_ids.sem); 478 mutex_unlock(&shm_ids.mutex);
478 if(copy_to_user (buf, &shm_info, sizeof(shm_info))) { 479 if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
479 err = -EFAULT; 480 err = -EFAULT;
480 goto out; 481 goto out;
@@ -583,7 +584,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
583 * Instead we set a destroyed flag, and then blow 584 * Instead we set a destroyed flag, and then blow
584 * the name away when the usage hits zero. 585 * the name away when the usage hits zero.
585 */ 586 */
586 down(&shm_ids.sem); 587 mutex_lock(&shm_ids.mutex);
587 shp = shm_lock(shmid); 588 shp = shm_lock(shmid);
588 err = -EINVAL; 589 err = -EINVAL;
589 if (shp == NULL) 590 if (shp == NULL)
@@ -610,7 +611,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
610 shm_unlock(shp); 611 shm_unlock(shp);
611 } else 612 } else
612 shm_destroy (shp); 613 shm_destroy (shp);
613 up(&shm_ids.sem); 614 mutex_unlock(&shm_ids.mutex);
614 goto out; 615 goto out;
615 } 616 }
616 617
@@ -620,12 +621,13 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
620 err = -EFAULT; 621 err = -EFAULT;
621 goto out; 622 goto out;
622 } 623 }
623 down(&shm_ids.sem); 624 mutex_lock(&shm_ids.mutex);
624 shp = shm_lock(shmid); 625 shp = shm_lock(shmid);
625 err=-EINVAL; 626 err=-EINVAL;
626 if(shp==NULL) 627 if(shp==NULL)
627 goto out_up; 628 goto out_up;
628 if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, &(shp->shm_perm)))) 629 if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid,
630 setbuf.mode, &(shp->shm_perm))))
629 goto out_unlock_up; 631 goto out_unlock_up;
630 err = shm_checkid(shp,shmid); 632 err = shm_checkid(shp,shmid);
631 if(err) 633 if(err)
@@ -658,7 +660,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
658out_unlock_up: 660out_unlock_up:
659 shm_unlock(shp); 661 shm_unlock(shp);
660out_up: 662out_up:
661 up(&shm_ids.sem); 663 mutex_unlock(&shm_ids.mutex);
662 goto out; 664 goto out;
663out_unlock: 665out_unlock:
664 shm_unlock(shp); 666 shm_unlock(shp);
@@ -771,7 +773,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
771invalid: 773invalid:
772 up_write(&current->mm->mmap_sem); 774 up_write(&current->mm->mmap_sem);
773 775
774 down (&shm_ids.sem); 776 mutex_lock(&shm_ids.mutex);
775 if(!(shp = shm_lock(shmid))) 777 if(!(shp = shm_lock(shmid)))
776 BUG(); 778 BUG();
777 shp->shm_nattch--; 779 shp->shm_nattch--;
@@ -780,7 +782,7 @@ invalid:
780 shm_destroy (shp); 782 shm_destroy (shp);
781 else 783 else
782 shm_unlock(shp); 784 shm_unlock(shp);
783 up (&shm_ids.sem); 785 mutex_unlock(&shm_ids.mutex);
784 786
785 *raddr = (unsigned long) user_addr; 787 *raddr = (unsigned long) user_addr;
786 err = 0; 788 err = 0;