patch-2.3.99-pre3 linux/ipc/shm.c
Next file: linux/kernel/Makefile
Previous file: linux/include/net/irda/parameters.h
Back to the patch index
Back to the overall index
- Lines: 153
- Date:
Tue Mar 21 12:30:00 2000
- Orig file:
v2.3.99-pre2/linux/ipc/shm.c
- Orig date:
Sun Mar 19 18:35:31 2000
diff -u --recursive --new-file v2.3.99-pre2/linux/ipc/shm.c linux/ipc/shm.c
@@ -30,6 +30,7 @@
*/
#include <linux/config.h>
+#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/shm.h>
#include <linux/swap.h>
@@ -1046,12 +1047,10 @@
*/
if ((shmid % SEQ_MULTIPLIER) == zero_id)
return -EINVAL;
- lock_kernel();
down(&shm_ids.sem);
shp = shm_lock(shmid);
if (shp == NULL) {
up(&shm_ids.sem);
- unlock_kernel();
return -EINVAL;
}
err = -EIDRM;
@@ -1060,14 +1059,12 @@
int id=shp->id;
shm_unlock(shmid);
up(&shm_ids.sem);
- /* The kernel lock prevents new attaches from
- * being happening. We can't hold shm_lock here
- * else we will deadlock in shm_lookup when we
+ /*
+ * We can't hold shm_lock here else we
+ * will deadlock in shm_lookup when we
* try to recursively grab it.
*/
- err = shm_remove_name(id);
- unlock_kernel();
- return err;
+ return shm_remove_name(id);
}
/* Do not find me any more */
shp->shm_perm.mode |= SHM_DEST;
@@ -1077,7 +1074,6 @@
/* Unlock */
shm_unlock(shmid);
up(&shm_ids.sem);
- unlock_kernel();
return err;
}
@@ -1139,8 +1135,8 @@
static int shm_mmap(struct file * file, struct vm_area_struct * vma)
{
- if (!(vma->vm_flags & VM_SHARED))
- return -EINVAL; /* we cannot do private mappings */
+ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED))
+ return -EINVAL; /* we cannot do private writable mappings */
UPDATE_ATIME(file->f_dentry->d_inode);
vma->vm_ops = &shm_vm_ops;
shm_inc(file->f_dentry->d_inode->i_ino);
@@ -1155,15 +1151,16 @@
unsigned long addr;
struct file * file;
int err;
- int flags;
+ unsigned long flags;
+ unsigned long prot;
+ unsigned long o_flags;
char name[SHM_FMT_LEN+1];
if (!shm_sb || (shmid % SEQ_MULTIPLIER) == zero_id)
return -EINVAL;
- if ((addr = (ulong)shmaddr))
- {
- if(addr & (SHMLBA-1)) {
+ if ((addr = (ulong)shmaddr)) {
+ if (addr & (SHMLBA-1)) {
if (shmflg & SHM_RND)
addr &= ~(SHMLBA-1); /* round down */
else
@@ -1173,14 +1170,22 @@
} else
flags = MAP_SHARED;
- sprintf (name, SHM_FMT, shmid);
+ if (shmflg & SHM_RDONLY) {
+ prot = PROT_READ;
+ o_flags = O_RDONLY;
+ } else {
+ prot = PROT_READ | PROT_WRITE;
+ o_flags = O_RDWR;
+ }
+
+ sprintf (name, SHM_FMT, shmid);
+
lock_kernel();
- file = filp_open(name, O_RDWR, 0, dget(shm_sb->s_root));
+ file = filp_open(name, o_flags, 0, dget(shm_sb->s_root));
if (IS_ERR (file))
goto bad_file;
*raddr = do_mmap (file, addr, file->f_dentry->d_inode->i_size,
- (shmflg & SHM_RDONLY ? PROT_READ :
- PROT_READ | PROT_WRITE), flags, 0);
+ prot, flags, 0);
unlock_kernel();
if (IS_ERR(*raddr))
err = PTR_ERR(*raddr);
@@ -1203,14 +1208,18 @@
}
/*
- * Remove a name. Must be called with lock_kernel
+ * Remove a name.
*/
static int shm_remove_name(int id)
{
+ int err;
char name[SHM_FMT_LEN+1];
sprintf (name, SHM_FMT, id);
- return do_unlink (name, dget(shm_sb->s_root));
+ lock_kernel();
+ err = do_unlink (name, dget(shm_sb->s_root));
+ unlock_kernel();
+ return err;
}
/*
@@ -1224,8 +1233,6 @@
int id = shmd->vm_file->f_dentry->d_inode->i_ino;
struct shmid_kernel *shp;
- lock_kernel();
-
/* remove from the list of attaches of the shm segment */
if(!(shp = shm_lock(id)))
BUG();
@@ -1243,14 +1250,12 @@
* try to recursively grab it.
*/
err = shm_remove_name(pid);
- if(err && err != -ENOENT)
+ if(err && err != -EINVAL && err != -ENOENT)
printk(KERN_ERR "Unlink of SHM id %d failed (%d).\n", pid, err);
} else {
shm_unlock(id);
}
-
- unlock_kernel();
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)