diff -uNr 99-pre3-3/ipc/shm.c c3-3/ipc/shm.c --- 99-pre3-3/ipc/shm.c Tue Mar 21 12:08:32 2000 +++ c3-3/ipc/shm.c Tue Mar 21 16:19:59 2000 @@ -1047,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; @@ -1061,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; @@ -1078,7 +1074,6 @@ /* Unlock */ shm_unlock(shmid); up(&shm_ids.sem); - unlock_kernel(); return err; } @@ -1140,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); @@ -1156,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 @@ -1174,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); @@ -1204,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; } /* @@ -1225,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(); @@ -1244,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(); } /* diff -uNr 99-pre3-3/CREDITS c3-3/CREDITS --- 99-pre3-3/CREDITS Tue Mar 21 12:08:32 2000 +++ c3-3/CREDITS Tue Mar 21 16:49:43 2000 @@ -2051,6 +2051,14 @@ S: 7000 Stuttgart 50 S: Germany +N: Christoph Rohland +E: hans-christoph.rohland@sap.com +E: ch.rohland@gmx.net +D: shm fs, SYSV semaphores, af_unix +S: Neue Heimat Str. 8 +S: D-68789 St.Leon-Rot +S: Germany + N: Stephen Rothwell E: sfr@linuxcare.com W: http://linuxcare.com.au/sfr