linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] get rid of vm_private_data and win posix shm
@ 1999-12-28 17:32 Christoph Rohland
  1999-12-28 17:50 ` Alan Cox
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Christoph Rohland @ 1999-12-28 17:32 UTC (permalink / raw)
  To: MM mailing list, Linux Kernel Mailing List; +Cc: Eric W. Biederman

[-- Attachment #1: Type: text/plain, Size: 524 bytes --]

Hi folks,

Here is my first version of using file semantics in shared
memory. This obsoletes vm_private_data in vm_area_struct and allows
posix shared memory.

I implemented posix shm with its own namespace by extending filp_open
and do_unlink by an additional parameter for the root inode.

Also extending this to a complete filesystem should be easy (but not
my target).

Greetings
		Christoph

P.S. this version is only tested on UP since I cannot access my SMP machine
     from home. I will stress test SMP next week.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: patch-shm_open3 --]
[-- Type: text/x-patch, Size: 37719 bytes --]

diff -uNr 2.3.34/arch/i386/kernel/entry.S c34/arch/i386/kernel/entry.S
--- 2.3.34/arch/i386/kernel/entry.S	Thu Dec 23 20:41:44 1999
+++ c34/arch/i386/kernel/entry.S	Thu Dec 23 20:44:59 1999
@@ -598,7 +598,9 @@
 	.long SYMBOL_NAME(sys_stat64)		/* 195 */
 	.long SYMBOL_NAME(sys_lstat64)
 	.long SYMBOL_NAME(sys_fstat64)
-
+        .long SYMBOL_NAME(sys_shm_open)
+        .long SYMBOL_NAME(sys_shm_unlink)
+	/* 200 */
 
 	/*
 	 * NOTE!! This doesn't have to be exact - we just have
@@ -606,6 +608,6 @@
 	 * entries. Don't panic if you notice that this hasn't
 	 * been shrunk every time we add a new system call.
 	 */
-	.rept NR_syscalls-197
+	.rept NR_syscalls-199
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
diff -uNr 2.3.34/arch/sparc/kernel/sys_sunos.c c34/arch/sparc/kernel/sys_sunos.c
--- 2.3.34/arch/sparc/kernel/sys_sunos.c	Sat Sep 18 20:49:20 1999
+++ c34/arch/sparc/kernel/sys_sunos.c	Mon Dec 27 11:38:28 1999
@@ -722,7 +722,6 @@
 
 
 extern int do_mount(kdev_t, const char *, const char *, char *, int, void *);
-extern dev_t get_unnamed_dev(void);
 extern void put_unnamed_dev(dev_t);
 extern asmlinkage int sys_mount(char *, char *, char *, unsigned long, void *);
 extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
diff -uNr 2.3.34/arch/sparc64/kernel/sys_sparc32.c c34/arch/sparc64/kernel/sys_sparc32.c
--- 2.3.34/arch/sparc64/kernel/sys_sparc32.c	Sat Dec 18 10:25:11 1999
+++ c34/arch/sparc64/kernel/sys_sparc32.c	Thu Dec 23 20:42:19 1999
@@ -2775,7 +2775,7 @@
 	for (i=0 ; i<MAX_ARG_PAGES ; i++)	/* clear page-table */
 		bprm.page[i] = 0;
 
-	dentry = open_namei(filename, 0, 0);
+	dentry = open_namei(filename, 0, 0, NULL);
 	retval = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		return retval;
diff -uNr 2.3.34/arch/sparc64/kernel/sys_sunos32.c c34/arch/sparc64/kernel/sys_sunos32.c
--- 2.3.34/arch/sparc64/kernel/sys_sunos32.c	Sat Sep 18 20:49:21 1999
+++ c34/arch/sparc64/kernel/sys_sunos32.c	Mon Dec 27 11:38:20 1999
@@ -686,7 +686,6 @@
 };
 
 extern int do_mount(kdev_t, const char *, const char *, char *, int, void *);
-extern dev_t get_unnamed_dev(void);
 extern void put_unnamed_dev(dev_t);
 extern asmlinkage int sys_mount(char *, char *, char *, unsigned long, void *);
 extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
diff -uNr 2.3.34/fs/binfmt_elf.c c34/fs/binfmt_elf.c
--- 2.3.34/fs/binfmt_elf.c	Wed Dec  8 21:00:42 1999
+++ c34/fs/binfmt_elf.c	Thu Dec 23 20:42:19 1999
@@ -503,12 +503,12 @@
 					
 				current->personality = PER_SVR4;
 				interpreter_dentry = open_namei(elf_interpreter,
-								0, 0);
+								0, 0, NULL);
 				current->personality = old_pers;
 			} else
 #endif					
 				interpreter_dentry = open_namei(elf_interpreter,
-								0, 0);
+								0, 0, NULL);
 			set_fs(old_fs);
 			retval = PTR_ERR(interpreter_dentry);
 			if (IS_ERR(interpreter_dentry))
diff -uNr 2.3.34/fs/binfmt_em86.c c34/fs/binfmt_em86.c
--- 2.3.34/fs/binfmt_em86.c	Sun Nov  7 11:41:32 1999
+++ c34/fs/binfmt_em86.c	Thu Dec 23 20:42:19 1999
@@ -79,7 +79,7 @@
 	 * Note that we use open_namei() as the name is now in kernel
 	 * space, and we don't need to copy it.
 	 */
-	dentry = open_namei(interp, 0, 0);
+	dentry = open_namei(interp, 0, 0, NULL);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
diff -uNr 2.3.34/fs/binfmt_misc.c c34/fs/binfmt_misc.c
--- 2.3.34/fs/binfmt_misc.c	Wed Dec  8 21:00:50 1999
+++ c34/fs/binfmt_misc.c	Thu Dec 23 20:42:19 1999
@@ -214,7 +214,7 @@
 	bprm->argc++;
 	bprm->filename = iname;	/* for binfmt_script */
 
-	dentry = open_namei(iname, 0, 0);
+	dentry = open_namei(iname, 0, 0, NULL);
 	retval = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto _ret;
diff -uNr 2.3.34/fs/binfmt_script.c c34/fs/binfmt_script.c
--- 2.3.34/fs/binfmt_script.c	Tue Aug  3 19:18:39 1999
+++ c34/fs/binfmt_script.c	Thu Dec 23 20:42:19 1999
@@ -80,7 +80,7 @@
 	/*
 	 * OK, now restart the process with the interpreter's dentry.
 	 */
-	dentry = open_namei(interp, 0, 0);
+	dentry = open_namei(interp, 0, 0, NULL);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
diff -uNr 2.3.34/fs/dquot.c c34/fs/dquot.c
--- 2.3.34/fs/dquot.c	Wed Dec  8 21:00:50 1999
+++ c34/fs/dquot.c	Thu Dec 23 20:42:19 1999
@@ -1486,7 +1486,7 @@
 	if (IS_ERR(tmp))
 		goto out_lock;
 
-	f = filp_open(tmp, O_RDWR, 0600);
+	f = filp_open(tmp, O_RDWR, 0600, NULL);
 	putname(tmp);
 
 	error = PTR_ERR(f);
diff -uNr 2.3.34/fs/exec.c c34/fs/exec.c
--- 2.3.34/fs/exec.c	Thu Dec 23 20:41:45 1999
+++ c34/fs/exec.c	Thu Dec 23 20:42:19 1999
@@ -287,7 +287,6 @@
 		mpnt->vm_ops = NULL;
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
-		mpnt->vm_private_data = (void *) 0;
 		vmlist_modify_lock(current->mm);
 		insert_vm_struct(current->mm, mpnt);
 		vmlist_modify_unlock(current->mm);
@@ -710,7 +709,7 @@
 	        for (i = 0 ; i < MAX_ARG_PAGES ; i++)	/* clear page-table */
                     bprm_loader.page[i] = NULL;
 
-		dentry = open_namei(dynloader[0], 0, 0);
+		dentry = open_namei(dynloader[0], 0, 0, NULL);
 		retval = PTR_ERR(dentry);
 		if (IS_ERR(dentry))
 			return retval;
@@ -775,7 +774,7 @@
 	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
 	memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
 
-	dentry = open_namei(filename, 0, 0);
+	dentry = open_namei(filename, 0, 0, NULL);
 	retval = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		return retval;
@@ -855,7 +854,7 @@
 #else
 	corename[4] = '\0';
 #endif
-	file = filp_open(corename, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
+	file = filp_open(corename, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600, NULL);
 	if (IS_ERR(file))
 		goto fail;
 	dentry = file->f_dentry;
diff -uNr 2.3.34/fs/namei.c c34/fs/namei.c
--- 2.3.34/fs/namei.c	Sat Dec 18 10:25:23 1999
+++ c34/fs/namei.c	Fri Dec 24 16:18:29 1999
@@ -680,7 +680,7 @@
  * which is a lot more logical, and also allows the "no perm" needed
  * for symlinks (where the permissions are checked later).
  */
-struct dentry * open_namei(const char * pathname, int flag, int mode)
+struct dentry * open_namei(const char * pathname, int flag, int mode, struct dentry *root)
 {
 	int acc_mode, error;
 	struct inode *inode;
@@ -689,7 +689,7 @@
 	mode &= S_IALLUGO & ~current->fs->umask;
 	mode |= S_IFREG;
 
-	dentry = lookup_dentry(pathname, NULL, lookup_flags(flag));
+	dentry = lookup_dentry(pathname, root, lookup_flags(flag));
 	if (IS_ERR(dentry))
 		return dentry;
 
@@ -1067,13 +1067,13 @@
 	return error;
 }
 
-static inline int do_unlink(const char * name)
+int do_unlink(const char * name, struct dentry *root)
 {
 	int error;
 	struct dentry *dir;
 	struct dentry *dentry;
 
-	dentry = lookup_dentry(name, NULL, 0);
+	dentry = lookup_dentry(name, root, 0);
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto exit;
@@ -1098,7 +1098,7 @@
 	tmp = getname(pathname);
 	error = PTR_ERR(tmp);
 	if (!IS_ERR(tmp)) {
-		error = do_unlink(tmp);
+		error = do_unlink(tmp, NULL);
 		putname(tmp);
 	}
 	unlock_kernel();
diff -uNr 2.3.34/fs/open.c c34/fs/open.c
--- 2.3.34/fs/open.c	Wed Dec  8 21:01:51 1999
+++ c34/fs/open.c	Sat Dec 25 20:00:49 1999
@@ -656,7 +656,7 @@
  * for the internal routines (ie open_namei()/follow_link() etc). 00 is
  * used by symlinks.
  */
-struct file *filp_open(const char * filename, int flags, int mode)
+struct file *filp_open(const char * filename, int flags, int mode, struct dentry *dent)
 {
 	struct inode * inode;
 	struct dentry * dentry;
@@ -673,7 +673,7 @@
 		flag++;
 	if (flag & O_TRUNC)
 		flag |= 2;
-	dentry = open_namei(filename,flag,mode);
+	dentry = open_namei(filename,flag,mode,dent);
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto cleanup_file;
@@ -796,7 +796,7 @@
 		if (fd >= 0) {
 			struct file * f;
 			lock_kernel();
-			f = filp_open(tmp, flags, mode);
+			f = filp_open(tmp, flags, mode, NULL);
 			unlock_kernel();
 			error = PTR_ERR(f);
 			if (IS_ERR(f))
diff -uNr 2.3.34/include/asm-i386/unistd.h c34/include/asm-i386/unistd.h
--- 2.3.34/include/asm-i386/unistd.h	Thu Dec 23 20:41:46 1999
+++ c34/include/asm-i386/unistd.h	Thu Dec 23 20:45:40 1999
@@ -202,6 +202,8 @@
 #define __NR_stat64		195
 #define __NR_lstat64		196
 #define __NR_fstat64		197
+#define __NR_shm_open    	198
+#define __NR_shm_unlink 	199
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
diff -uNr 2.3.34/include/linux/fs.h c34/include/linux/fs.h
--- 2.3.34/include/linux/fs.h	Thu Dec 23 20:41:46 1999
+++ c34/include/linux/fs.h	Tue Dec 28 18:03:25 1999
@@ -736,7 +736,7 @@
 extern int get_unused_fd(void);
 extern void put_unused_fd(unsigned int);
 
-extern struct file *filp_open(const char *, int, int);
+extern struct file *filp_open(const char *, int, int, struct dentry *);
 extern int filp_close(struct file *, fl_owner_t id);
 
 extern char * getname(const char *);
@@ -840,9 +840,10 @@
 extern int permission(struct inode *, int);
 extern int get_write_access(struct inode *);
 extern void put_write_access(struct inode *);
-extern struct dentry * open_namei(const char *, int, int);
+extern struct dentry * open_namei(const char *, int, int, struct dentry *);
 extern struct dentry * do_mknod(const char *, int, dev_t);
 extern int do_pipe(int *);
+extern int do_unlink(const char * name, struct dentry *root);
 
 /* fs/dcache.c -- generic fs support functions */
 extern int is_subdir(struct dentry *, struct dentry *);
@@ -972,6 +973,7 @@
 extern void put_super(kdev_t);
 unsigned long generate_cluster(kdev_t, int b[], int);
 unsigned long generate_cluster_swab32(kdev_t, int b[], int);
+extern kdev_t get_unnamed_dev(void);
 extern kdev_t ROOT_DEV;
 
 extern void show_buffers(void);
diff -uNr 2.3.34/include/linux/mm.h c34/include/linux/mm.h
--- 2.3.34/include/linux/mm.h	Sat Dec 18 11:00:50 1999
+++ c34/include/linux/mm.h	Tue Dec 28 18:03:25 1999
@@ -60,7 +60,6 @@
 	struct vm_operations_struct * vm_ops;
 	unsigned long vm_pgoff;		/* offset in PAGE_SIZE units, *not* PAGE_CACHE_SIZE */
 	struct file * vm_file;
-	void * vm_private_data;		/* was vm_pte (shared mem) */
 };
 
 /*
diff -uNr 2.3.34/ipc/shm.c c34/ipc/shm.c
--- 2.3.34/ipc/shm.c	Thu Dec 23 20:41:46 1999
+++ c34/ipc/shm.c	Tue Dec 28 17:56:41 1999
@@ -9,8 +9,8 @@
  * BIGMEM support, Andrea Arcangeli <andrea@suse.de>
  * SMP thread shm, Jean-Luc Boyard <jean-luc.boyard@siemens.fr>
  * HIGHMEM support, Ingo Molnar <mingo@redhat.com>
- * avoid vmalloc and make shmmax, shmall, shmmni sysctl'able,
- *                         Christoph Rohland <hans-christoph.rohland@sap.com>
+ * avoid vmalloc, use file semantics, implement posix shm,
+ *			Christoph Rohland <hans-christoph.rohland@sap.com>
  */
 
 #include <linux/config.h>
@@ -19,6 +19,8 @@
 #include <linux/swap.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
+#include <linux/file.h>
+#include <linux/mman.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/proc_fs.h>
@@ -29,14 +31,23 @@
 
 #include "util.h"
 
+static int	      shm_create   (struct inode *,struct dentry *,int);
+static struct dentry *shm_lookup   (struct inode *,struct dentry *);
+static int	      shm_unlink   (struct inode *,struct dentry *);
+static int	      shm_notify   (struct dentry *dent, struct iattr *attr);
+static void	      shm_delete   (struct inode *);
+static int	      shm_mmap	   (struct file *, struct vm_area_struct *);
+static void	      shm_readi	   (struct inode *);
+
+#define SHM_NAME_LEN NAME_MAX
+
 struct shmid_kernel /* extend struct shmis_ds with private fields */
 {	
 	struct shmid_ds		u;
 	unsigned long		shm_npages; /* size of segment (pages) */
-	pte_t			**shm_dir;  /* ptr to array of ptrs to frames -> SHMMAX */ 
-	struct vm_area_struct	*attaches;  /* descriptors for attaches */
-	int                     id; /* backreference to id for shm_close */
-	struct semaphore sem;
+	pte_t			**shm_dir;  /* ptr to array of ptrs to frames */ 
+	int			namelen;
+	char			name[0];
 };
 
 static struct ipc_ids shm_ids;
@@ -52,9 +63,7 @@
 #define shm_buildid(id, seq) \
 	ipc_buildid(&shm_ids, id, seq)
 
-static int newseg (key_t key, int shmflg, size_t size);
-static int shm_map (struct vm_area_struct *shmd);
-static void killseg (int shmid);
+static int newseg (key_t key, const char *name, int namelen, int shmflg, size_t size);
 static void shm_open (struct vm_area_struct *shmd);
 static void shm_close (struct vm_area_struct *shmd);
 static struct page * shm_nopage(struct vm_area_struct *, unsigned long, int);
@@ -63,6 +72,53 @@
 static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
 #endif
 
+static struct super_block * shm_sb;
+
+static struct super_operations shm_sops = {
+	shm_readi,		/* read_inode */
+	NULL,			/* write_inode */
+	NULL,			/* put_inode */
+	shm_delete,		/* delete_inode */
+	shm_notify,		/* notify_change */
+};
+
+static struct file_operations shm_root_operations = {
+};
+
+static struct inode_operations shm_root_inode_operations = {
+	&shm_root_operations,	/* file operations */
+	shm_create,		/* create */
+	shm_lookup,		/* lookup */
+	NULL,			/* link */
+	shm_unlink,		/* unlink */
+};
+
+static struct file_operations shm_operations = {
+	NULL,			/* llseek */
+	NULL,			/* read */
+	NULL,			/* write */
+	NULL,			/* readdir */
+	NULL,			/* poll */
+	NULL,			/* ioctl */
+	shm_mmap,		/* mmap */
+};
+
+static struct inode_operations shm_inode_operations = {
+	&shm_operations,	/* file operations */
+};
+
+static struct vm_operations_struct shm_vm_ops = {
+	shm_open,		/* open - callback for a new vm-area open */
+	shm_close,		/* close - callback for when the vm-area is released */
+	NULL,			/* no need to sync pages at unmap */
+	NULL,			/* protect */
+	NULL,			/* sync */
+	NULL,			/* advise */
+	shm_nopage,		/* nopage */
+	NULL,			/* wppage */
+	shm_swapout		/* swapout */
+};
+
 size_t shm_ctlmax = SHMMAX;
 int shm_ctlall = SHMALL;
 int shm_ctlmni = SHMMNI;
@@ -75,7 +131,7 @@
 	pagecache_lock
 	shm_lock()/shm_lockall()
 	kernel lock
-	shp->sem
+	inode->i_sem
 	sem_ids.sem
 	mmap_sem
 
@@ -93,13 +149,172 @@
 
 void __init shm_init (void)
 {
+	struct inode * inode;
+
 	ipc_init_ids(&shm_ids, shm_ctlmni);
+
+	if (!(shm_sb = get_empty_super()))
+		BUG();
+	shm_sb->s_dev = get_unnamed_dev();
+	shm_sb->s_op = &shm_sops;
+	if (!(inode = iget (shm_sb, SEQ_MULTIPLIER)))
+		BUG();
+	inode->i_op = &shm_root_inode_operations;
+	inode->i_sb = shm_sb;
+	if (!(shm_sb->s_root = d_alloc_root(inode)))
+		BUG();
+
 #ifdef CONFIG_PROC_FS
 	create_proc_read_entry("sysvipc/shm", 0, 0, sysvipc_shm_read_proc, NULL);
 #endif
 	return;
 }
 
+static void shm_readi (struct inode *ino){}
+
+static int shm_dget (int id, struct dentry *dent)
+{
+	struct shmid_kernel *shp;
+	struct inode * inode;
+	
+	inode = iget (shm_sb, id % SEQ_MULTIPLIER);/* we use the plain id so
+						      we can use the upper
+						      space for directory
+						      inodes */
+	if (!inode)
+		return -ENOMEM;
+
+	shp = shm_lock (id);
+	inode->i_mode = shp->u.shm_perm.mode;
+	inode->i_uid  = shp->u.shm_perm.uid;
+	inode->i_gid  = shp->u.shm_perm.gid;
+	inode->i_size = shp->u.shm_segsz;
+	shm_unlock (id);
+	inode->i_op   = &shm_inode_operations;
+
+	d_instantiate(dent, inode);
+	return 0;
+}
+
+static int shm_create (struct inode *dir, struct dentry *dent, int mode)
+{
+	int id;
+
+	down(&shm_ids.sem);
+	id = newseg (IPC_PRIVATE, dent->d_name.name, dent->d_name.len,
+			 mode, 0);
+	if (id >= 0)
+		id = shm_dget (id, dent);
+
+	up(&shm_ids.sem);
+
+	return id;
+}
+
+static struct dentry *shm_lookup (struct inode *dir, struct dentry *dent)
+{
+	int i, err;
+	struct shmid_kernel* shp;
+
+#ifdef SHM_DEBUG
+	if (dir != shm_sb->s_root->d_inode)
+		BUG();
+	if (dent->d_parent != shm_sb->s_root)
+		BUG();
+#endif
+
+	if (dent->d_name.len > SHM_NAME_LEN)
+		return ERR_PTR(-ENAMETOOLONG);
+
+	down(&shm_ids.sem);
+	for(i = 0; i <= shm_ids.max_id; i++) {
+		if (!(shp = shm_lock(i)))
+		    continue;
+		if (!(shp->u.shm_perm.mode & SHM_DEST ||
+		      strncmp(dent->d_name.name, shp->name, shp->namelen)))
+			goto found;
+		shm_unlock(i);
+	}
+	err = 0;
+	goto out;
+
+found:
+	shm_unlock(i);
+	err = shm_dget (i, dent);
+out:
+	if (err == 0)
+		d_rehash (dent);
+	up (&shm_ids.sem);
+	return ERR_PTR(err);
+}
+
+static int shm_unlink (struct inode *dir, struct dentry *dent)
+{
+	struct inode * inode = dent->d_inode;
+	struct shmid_kernel *shp;
+
+	down (&shm_ids.sem);
+	if (!(shp = shm_lock (inode->i_ino)))
+		BUG();
+	shp->u.shm_perm.mode |= SHM_DEST;
+	shp->u.shm_perm.key = IPC_PRIVATE; /* Do not find it any more */
+	shm_unlock (inode->i_ino);
+	up (&shm_ids.sem);
+	inode->i_nlink -= 1;
+	d_delete (dent);
+	return 0;
+}
+
+asmlinkage long sys_shm_open(const char * filename, int flags, int mode)
+{
+	char * tmp, *tmp2;
+	int fd, error;
+
+	tmp2 = tmp = getname(filename);
+
+	fd = PTR_ERR(tmp);
+	if (!IS_ERR(tmp)) {
+		while (*tmp && *tmp == '/')
+			tmp++;
+
+		fd = get_unused_fd();
+		if (fd >= 0) {
+			struct file * f;
+			lock_kernel();
+			f = filp_open(tmp, flags, mode, dget(shm_sb->s_root));
+			unlock_kernel();
+			error = PTR_ERR(f);
+			if (IS_ERR(f))
+				goto out_error;
+			fd_install(fd, f);
+		}
+out:
+		putname(tmp2);
+	}
+	return fd;
+
+out_error:
+	put_unused_fd(fd);
+	fd = error;
+	goto out;
+}
+
+asmlinkage long sys_shm_unlink(const char * pathname)
+{
+	int error;
+	char * tmp;
+
+	lock_kernel();
+	tmp = getname(pathname);
+	error = PTR_ERR(tmp);
+	if (!IS_ERR(tmp)) {
+		error = do_unlink(tmp, dget (shm_sb->s_root));
+		putname(tmp);
+	}
+	unlock_kernel();
+	return error;
+}
+
 #define SHM_ENTRY(shp, index) (shp)->shm_dir[(index)/PTRS_PER_PTE][(index)%PTRS_PER_PTE]
 
 static pte_t **shm_alloc(unsigned long pages)
@@ -108,9 +323,12 @@
 	unsigned short last = pages % PTRS_PER_PTE;
 	pte_t **ret, **ptr;
 
+	if (pages == 0)
+		return NULL;
+
 	ret = kmalloc ((dir+1) * sizeof(pte_t *), GFP_KERNEL);
 	if (!ret)
-		goto out;
+		goto nomem;
 
 	for (ptr = ret; ptr < ret+dir ; ptr++)
 	{
@@ -127,7 +345,6 @@
 			goto free;
 		memset (*ptr, 0, last*sizeof(pte_t));
 	}
-out:	
 	return ret;
 
 free:
@@ -136,66 +353,111 @@
 		free_page ((unsigned long)*ptr);
 
 	kfree (ret);
-	return NULL;
+nomem:
+	return ERR_PTR(-ENOMEM);
 }
 
-
 static void shm_free(pte_t** dir, unsigned long pages)
 {
 	pte_t **ptr = dir+pages/PTRS_PER_PTE;
 
+	if (!dir)
+		return;
+
 	/* first the last page */
 	if (pages%PTRS_PER_PTE)
 		kfree (*ptr);
 	/* now the whole pages */
 	while (--ptr >= dir)
-		free_page ((unsigned long)*ptr);
+		if (*ptr)
+			free_page ((unsigned long)*ptr);
 
 	/* Now the indirect block */
 	kfree (dir);
 }
 
-static int shm_revalidate(struct shmid_kernel* shp, int shmid, int pagecount, int flg)
+static 	int shm_notify (struct dentry *dentry, struct iattr *attr)
 {
-	struct shmid_kernel* new;
-	new = shm_lock(shmid);
-	if(new==NULL) {
-		return -EIDRM;
-	}
-	if(new!=shp || shm_checkid(shp, shmid) || shp->shm_npages != pagecount) {
-		shm_unlock(shmid);
-		return -EIDRM;
-	}
-	if (ipcperms(&shp->u.shm_perm, flg)) {
-		shm_unlock(shmid);
-		return -EACCES;
+	int error;
+	struct inode *inode = dentry->d_inode;
+	struct shmid_kernel *shp;
+	unsigned long new_pages, old_pages;
+	pte_t **new_dir, **old_dir;
+
+	if ((error = inode_change_ok(inode, attr)))
+		return error;
+	if (!(attr->ia_valid & ATTR_SIZE))
+		goto set_attr;
+	if (attr->ia_size > shm_ctlmax)
+		return -EFBIG;
+
+	/* We set old_pages and old_dir for easier cleanup */
+	old_pages = new_pages = (attr->ia_size  + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	if (shm_tot + new_pages >= shm_ctlall)
+		return -ENOSPC;
+	if (IS_ERR(old_dir = new_dir = shm_alloc(new_pages)))
+		return PTR_ERR(new_dir);
+
+	if (!(shp = shm_lock(inode->i_ino)))
+		BUG();
+	if (shp->u.shm_segsz == attr->ia_size)
+		goto out;
+	old_dir = shp->shm_dir;
+	old_pages = shp->shm_npages;
+	if (old_dir){
+		pte_t *swap;
+		int i,j;
+		i = old_pages < new_pages ? old_pages : new_pages;
+		j = i % PTRS_PER_PTE;
+		i /= PTRS_PER_PTE;
+		if (j)
+			memcpy (new_dir[i], old_dir[i], j * sizeof (pte_t));
+		while (i--) {
+			swap = new_dir[i];
+			new_dir[i] = old_dir[i];
+			old_dir[i] = swap;
+		}
 	}
+	shp->shm_dir = new_dir;
+	shp->shm_npages = new_pages;
+	shp->u.shm_segsz = attr->ia_size;
+out:
+	shm_unlock(inode->i_ino);
+	shm_lockall();
+	shm_tot += new_pages - old_pages;
+	shm_unlockall();
+	shm_free (old_dir, old_pages);
+set_attr:
+	inode_setattr(inode, attr);
 	return 0;
 }
 
-static int newseg (key_t key, int shmflg, size_t size)
+static int newseg (key_t key, const char *name, int namelen,
+		   int shmflg, size_t size)
 {
 	struct shmid_kernel *shp;
 	int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
 	int id;
 
-	if (size < SHMMIN)
-		return -EINVAL;
+	if (namelen > SHM_NAME_LEN)
+		return -ENAMETOOLONG;
 
 	if (size > shm_ctlmax)
 		return -EINVAL;
 	if (shm_tot + numpages >= shm_ctlall)
 		return -ENOSPC;
 
-	shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_KERNEL);
+	shp = (struct shmid_kernel *) /* sizeof(".IPC_%08x") == 14 */
+		kmalloc (sizeof (*shp) + (namelen ? namelen : 14), GFP_KERNEL);
 	if (!shp)
 		return -ENOMEM;
 
-	shp->shm_dir = shm_alloc (numpages);
-	if (!shp->shm_dir) {
+	if (IS_ERR(shp->shm_dir = shm_alloc (numpages))){
+		int error = PTR_ERR(shp->shm_dir);
 		kfree(shp);
-		return -ENOMEM;
+		return error;
 	}
+
 	id = ipc_addid(&shm_ids, &shp->u.shm_perm, shm_ctlmni);
 	if(id == -1) {
 		shm_free(shp->shm_dir,numpages);
@@ -206,18 +468,24 @@
 	shp->u.shm_perm.mode = (shmflg & S_IRWXUGO);
 	shp->u.shm_segsz = size;
 	shp->u.shm_cpid = current->pid;
-	shp->attaches = NULL;
-	shp->u.shm_lpid = shp->u.shm_nattch = 0;
+	shp->u.shm_lpid = 0;
 	shp->u.shm_atime = shp->u.shm_dtime = 0;
 	shp->u.shm_ctime = CURRENT_TIME;
+	shp->u.shm_nattch = 0;
 	shp->shm_npages = numpages;
-	shp->id = shm_buildid(id,shp->u.shm_perm.seq);
-	init_MUTEX(&shp->sem);
+	id = shm_buildid(id,shp->u.shm_perm.seq);
+	if (namelen != 0) {
+		shp->namelen = namelen;
+		memcpy (shp->name, name, namelen);		  
+	} else {
+		shp->namelen = sprintf (shp->name, ".IPC_%08x", id);
+	}
 
 	shm_tot += numpages;
+	used_segs++;
 	shm_unlock(id);
-
-	return shm_buildid(id,shp->u.shm_perm.seq);
+	
+	return id;
 }
 
 asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
@@ -225,14 +493,17 @@
 	struct shmid_kernel *shp;
 	int err, id = 0;
 
+	if (size < SHMMIN)
+		return -EINVAL;
+
 	down(&shm_ids.sem);
 	if (key == IPC_PRIVATE) {
-		err = newseg(key, shmflg, size);
+		err = newseg(key, NULL, 0, shmflg, size);
 	} else if ((id = ipc_findkey(&shm_ids,key)) == -1) {
 		if (!(shmflg & IPC_CREAT))
 			err = -ENOENT;
 		else
-			err = newseg(key, shmflg, size);
+			err = newseg(key, NULL, 0, shmflg, size);
 	} else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
 		err = -EEXIST;
 	} else {
@@ -249,12 +520,9 @@
 	return err;
 }
 
-/*
- * Only called after testing nattch and SHM_DEST.
- * Here pages, pgtable and shmid_kernel are freed.
- */
-static void killseg (int shmid)
+static void shm_delete (struct inode *ino)
 {
+	int shmid = ino->i_ino;
 	struct shmid_kernel *shp;
 	int i, numpages;
 	int rss, swp;
@@ -262,20 +530,9 @@
 	down(&shm_ids.sem);
 	shp = shm_lock(shmid);
 	if(shp==NULL) {
-out_up:
-		up(&shm_ids.sem);
-		return;
-	}
-	if(shm_checkid(shp,shmid) || shp->u.shm_nattch > 0 ||
-	    !(shp->u.shm_perm.mode & SHM_DEST)) {
-		shm_unlock(shmid);
-		goto out_up;
+		BUG();
 	}
 	shp = shm_rmid(shmid);
-	if(shp==NULL)
-		BUG();
-	if (!shp->shm_dir)
-		BUG();
 	shm_unlock(shmid);
 	up(&shm_ids.sem);
 
@@ -299,6 +556,7 @@
 	shm_rss -= rss;
 	shm_swp -= swp;
 	shm_tot -= numpages;
+	used_segs--;
 	shm_unlockall();
 	return;
 }
@@ -444,12 +702,17 @@
 		shp->u.shm_ctime = CURRENT_TIME;
 		break;
 	case IPC_RMID:
-		shp->u.shm_perm.mode |= SHM_DEST;
-		if (shp->u.shm_nattch <= 0) {
-			shm_unlock(shmid);
+		if (shp->u.shm_perm.mode & SHM_DEST) {
+			err = -EIDRM;
+			goto out_unlock_up;
+		}
+		{
+			char   name[SHM_NAME_LEN];
+			
+			strncpy (name, shp->name, SHM_NAME_LEN);
+			shm_unlock (shmid);
 			up(&shm_ids.sem);
-			killseg (shmid);
-			return 0;
+			return do_unlink (name, dget (shm_sb->s_root));
 		}
 	}
 	err = 0;
@@ -463,70 +726,24 @@
 	return err;
 }
 
-/*
- * The per process internal structure for managing segments is
- * `struct vm_area_struct'.
- * A shmat will add to and shmdt will remove from the list.
- * shmd->vm_mm		the attacher
- * shmd->vm_start	virt addr of attach, multiple of SHMLBA
- * shmd->vm_end		multiple of SHMLBA
- * shmd->vm_next	next attach for task
- * shmd->vm_next_share	next attach for segment
- * shmd->vm_pgoff	offset into segment (in pages)
- * shmd->vm_private_data		signature for this attach
- */
-
-static struct vm_operations_struct shm_vm_ops = {
-	shm_open,		/* open - callback for a new vm-area open */
-	shm_close,		/* close - callback for when the vm-area is released */
-	NULL,			/* no need to sync pages at unmap */
-	NULL,			/* protect */
-	NULL,			/* sync */
-	NULL,			/* advise */
-	shm_nopage,		/* nopage */
-	NULL,			/* wppage */
-	shm_swapout		/* swapout */
-};
-
-/* Insert shmd into the list shp->attaches */
-static inline void insert_attach (struct shmid_kernel * shp, struct vm_area_struct * shmd)
-{
-	if((shmd->vm_next_share = shp->attaches) != NULL)
-		shp->attaches->vm_pprev_share = &shmd->vm_next_share;
-	shp->attaches = shmd;
-	shmd->vm_pprev_share = &shp->attaches;
-}
+static inline void shm_inc (int id) {
+	struct shmid_kernel *shp;
 
-/* Remove shmd from list shp->attaches */
-static inline void remove_attach (struct shmid_kernel * shp, struct vm_area_struct * shmd)
-{
-	if(shmd->vm_next_share)
-		shmd->vm_next_share->vm_pprev_share = shmd->vm_pprev_share;
-	*shmd->vm_pprev_share = shmd->vm_next_share;
+	if(!(shp = shm_lock(id)))
+		BUG();
+	shp->u.shm_atime = CURRENT_TIME;
+	shp->u.shm_lpid = current->pid;
+	shp->u.shm_nattch++;
+	shm_unlock(id);
 }
 
-/*
- * ensure page tables exist
- * mark page table entries with shm_sgn.
- */
-static int shm_map (struct vm_area_struct *shmd)
+static int shm_mmap(struct file * file, struct vm_area_struct * vma)
 {
-	unsigned long tmp;
-
-	/* clear old mappings */
-	do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
-
-	/* add new mapping */
-	tmp = shmd->vm_end - shmd->vm_start;
-	if((current->mm->total_vm << PAGE_SHIFT) + tmp
-	   > (unsigned long) current->rlim[RLIMIT_AS].rlim_cur)
-		return -ENOMEM;
-	current->mm->total_vm += tmp >> PAGE_SHIFT;
-	vmlist_modify_lock(current->mm);
-	insert_vm_struct(current->mm, shmd);
-	merge_segments(current->mm, shmd->vm_start, shmd->vm_end);
-	vmlist_modify_unlock(current->mm);
-
+	if (!(vma->vm_flags & VM_SHARED))
+		return -EINVAL; /* we cannot do private mappings */
+	UPDATE_ATIME(file->f_dentry->d_inode);
+	vma->vm_ops = &shm_vm_ops;
+	shm_inc(file->f_dentry->d_inode->i_ino);
 	return 0;
 }
 
@@ -535,135 +752,73 @@
  */
 asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
 {
-	struct shmid_kernel *shp;
-	struct vm_area_struct *shmd;
-	int err;
 	unsigned long addr;
-	unsigned long len;
-	short flg = shmflg & SHM_RDONLY ? S_IRUGO : S_IRUGO|S_IWUGO;
+	size_t len;
+	struct shmid_kernel * shp;
+	struct file * file;
+	int    err;
+	int    flags;
+	char   name[SHM_NAME_LEN];
 
+	if ((addr = (ulong)shmaddr))
+	{
+		if(addr & (SHMLBA-1)) {
+			if (shmflg & SHM_RND)
+				addr &= ~(SHMLBA-1);	   /* round down */
+			else
+				return -EINVAL;
+		}
+		flags = MAP_SHARED | MAP_FIXED;
+	} else
+		flags = MAP_SHARED;
 
-	if (shmid < 0)
-		return -EINVAL;
+	file = get_empty_filp ();
+	if (!file)
+		return -ENOMEM;
 
-	down(&current->mm->mmap_sem);
 	err = -EINVAL;
-	shp = shm_lock(shmid);
-	if (!shp)
-		goto out_up;
-
-	err = -EACCES;
-	if (ipcperms(&shp->u.shm_perm, flg))
-		goto out_unlock_up;
-
-	err = -EIDRM;
-	if (shm_checkid(shp,shmid))
-		goto out_unlock_up;
-
-	if (!(addr = (ulong) shmaddr)) {
-		if (shmflg & SHM_REMAP)
-			goto out_unlock_up;
-		err = -ENOMEM;
-		addr = 0;
-	again:
-		if (!(addr = get_unmapped_area(addr, (unsigned long)shp->u.shm_segsz)))
-			goto out_unlock_up;
-		if(addr & (SHMLBA - 1)) {
-			addr = (addr + (SHMLBA - 1)) & ~(SHMLBA - 1);
-			goto again;
-		}
-	} else if (addr & (SHMLBA-1)) {
-		err=-EINVAL;
-		if (shmflg & SHM_RND)
-			addr &= ~(SHMLBA-1);       /* round down */
+	if (!(shp = shm_lock (shmid)))
+		goto put;
+	if(shm_checkid(shp,shmid)) {
+		err = -EIDRM;
+		shm_unlock (shmid);
+		goto put;
+	}
+
+	strncpy (name, shp->name, SHM_NAME_LEN);
+	len = shp->u.shm_segsz;
+	shm_unlock (shmid);
+	file->f_op = &shm_operations;
+	file->f_mode = shmflg & SHM_RDONLY ? FMODE_READ : FMODE_READ|FMODE_WRITE;
+	file->f_pos  = 0;
+	file->f_dentry = lookup_dentry (name, dget (shm_sb->s_root), 0);
+	if (IS_ERR (file->f_dentry)) {
+		err = PTR_ERR (file->f_dentry);
+		goto put;
+	}
+
+	if (addr && !(shmflg & SHM_REMAP) &&
+	    find_vma_intersection(current->mm, addr, addr + len)) {
+		err = -EINVAL;
+	} else {
+		*raddr = do_mmap (file, addr, len,
+				  (shmflg & SHM_RDONLY ? PROT_READ :
+				   PROT_READ | PROT_WRITE), flags, 0);
+		if (IS_ERR(*raddr))
+			err = PTR_ERR(*raddr);
 		else
-			goto out_unlock_up;
-	}
-	/*
-	 * Check if addr exceeds TASK_SIZE (from do_mmap)
-	 */
-	len = PAGE_SIZE*shp->shm_npages;
-	err = -EINVAL;
-	if (addr >= TASK_SIZE || len > TASK_SIZE  || addr > TASK_SIZE - len)
-		goto out_unlock_up;
-	/*
-	 * If shm segment goes below stack, make sure there is some
-	 * space left for the stack to grow (presently 4 pages).
-	 */
-	if (addr < current->mm->start_stack &&
-	    addr > current->mm->start_stack - PAGE_SIZE*(shp->shm_npages + 4))
-		goto out_unlock_up;
-	if (!(shmflg & SHM_REMAP) && find_vma_intersection(current->mm, addr, addr + (unsigned long)shp->u.shm_segsz))
-		goto out_unlock_up;
-
-	shm_unlock(shmid);
-	err = -ENOMEM;
-	shmd = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-	err = shm_revalidate(shp, shmid, len/PAGE_SIZE,flg);
-	if(err)	{
-		kmem_cache_free(vm_area_cachep, shmd);
-		goto out_up;
+			err = 0;
 	}
 
-	shmd->vm_private_data = shp;
-	shmd->vm_start = addr;
-	shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE;
-	shmd->vm_mm = current->mm;
-	shmd->vm_page_prot = (shmflg & SHM_RDONLY) ? PAGE_READONLY : PAGE_SHARED;
-	shmd->vm_flags = VM_SHM | VM_MAYSHARE | VM_SHARED
-			 | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC
-			 | ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE);
-	shmd->vm_file = NULL;
-	shmd->vm_pgoff = 0;
-	shmd->vm_ops = &shm_vm_ops;
-
-	shp->u.shm_nattch++;	    /* prevent destruction */
-	shm_unlock(shp->id);
-	err = shm_map (shmd);
-	shm_lock(shmid); /* cannot fail */
-	if (err)
-		goto failed_shm_map;
-
-	insert_attach(shp,shmd);  /* insert shmd into shp->attaches */
-
-	shp->u.shm_lpid = current->pid;
-	shp->u.shm_atime = CURRENT_TIME;
-
-	*raddr = addr;
-	err = 0;
-out_unlock_up:
-	shm_unlock(shmid);
-out_up:
-	up(&current->mm->mmap_sem);
+put:
+	put_filp (file);
 	return err;
-
-failed_shm_map:
-	{
-		int delete = 0;
-		if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
-			delete = 1;
-		shm_unlock(shmid);
-		up(&current->mm->mmap_sem);
-		kmem_cache_free(vm_area_cachep, shmd);
-		if(delete)
-			killseg(shmid);
-		return err;
-	}
 }
 
 /* This is called by fork, once for every shm attach. */
 static void shm_open (struct vm_area_struct *shmd)
 {
-	struct shmid_kernel *shp;
-
-	shp = (struct shmid_kernel *) shmd->vm_private_data;
-	if(shp != shm_lock(shp->id))
-		BUG();
-	insert_attach(shp,shmd);  /* insert shmd into shp->attaches */
-	shp->u.shm_nattch++;
-	shp->u.shm_atime = CURRENT_TIME;
-	shp->u.shm_lpid = current->pid;
-	shm_unlock(shp->id);
+	shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
 }
 
 /*
@@ -674,22 +829,16 @@
  */
 static void shm_close (struct vm_area_struct *shmd)
 {
+	int id = shmd->vm_file->f_dentry->d_inode->i_ino;
 	struct shmid_kernel *shp;
-	int id;
 
 	/* remove from the list of attaches of the shm segment */
-	shp = (struct shmid_kernel *) shmd->vm_private_data;
-	if(shp != shm_lock(shp->id))
+	if(!(shp = shm_lock(id)))
 		BUG();
-	remove_attach(shp,shmd);  /* remove from shp->attaches */
-  	shp->u.shm_lpid = current->pid;
+	shp->u.shm_lpid = current->pid;
 	shp->u.shm_dtime = CURRENT_TIME;
-	id=-1;
-	if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
-		id=shp->id;
-	shm_unlock(shp->id);
-	if(id!=-1)
-		killseg(id);
+	shp->u.shm_nattch--;
+	shm_unlock(id);
 }
 
 /*
@@ -733,32 +882,35 @@
 	struct shmid_kernel *shp;
 	unsigned int idx;
 	struct page * page;
+	struct inode * inode = shmd->vm_file->f_dentry->d_inode;
 
-	shp = (struct shmid_kernel *) shmd->vm_private_data;
 	idx = (address - shmd->vm_start) >> PAGE_SHIFT;
 	idx += shmd->vm_pgoff;
 
-	down(&shp->sem);
-	if(shp != shm_lock(shp->id))
+	if(!(shp = shm_lock(inode->i_ino)))
 		BUG();
 
+	if (idx >= shp->shm_npages)
+		goto sigbus;
+
+	down(&inode->i_sem);
 	pte = SHM_ENTRY(shp,idx);
 	if (!pte_present(pte)) {
 		/* page not present so shm_swap can't race with us
 		   and the semaphore protects us by other tasks that
 		   could potentially fault on our pte under us */
 		if (pte_none(pte)) {
-			shm_unlock(shp->id);
+			shm_unlock(inode->i_ino);
 			page = alloc_page(GFP_HIGHUSER);
 			if (!page)
 				goto oom;
 			clear_highpage(page);
-			if(shp != shm_lock(shp->id))
+			if(shp != shm_lock(inode->i_ino))
 				BUG();
 		} else {
 			swp_entry_t entry = pte_to_swp_entry(pte);
 
-			shm_unlock(shp->id);
+			shm_unlock(inode->i_ino);
 			page = lookup_swap_cache(entry);
 			if (!page) {
 				lock_kernel();
@@ -771,7 +923,7 @@
 			delete_from_swap_cache(page);
 			page = replace_with_highmem(page);
 			swap_free(entry);
-			if(shp != shm_lock(shp->id))
+			if(shp != shm_lock(inode->i_ino))
 				BUG();
 			shm_swp--;
 		}
@@ -783,14 +935,17 @@
 
 	/* pte_val(pte) == SHM_ENTRY (shp, idx) */
 	get_page(pte_page(pte));
-	shm_unlock(shp->id);
-	up(&shp->sem);
+	shm_unlock(inode->i_ino);
+	up(&inode->i_sem);
 	current->min_flt++;
 	return pte_page(pte);
 
 oom:
-	up(&shp->sem);
+	up(&inode->i_sem);
 	return NOPAGE_OOM;
+sigbus:
+	shm_unlock(inode->i_ino);
+	return NOPAGE_SIGBUS;
 }
 
 /*
@@ -940,20 +1095,20 @@
 	int i, len = 0;
 
 	down(&shm_ids.sem);
-	len += sprintf(buffer, "       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n");
+	len += sprintf(buffer, "       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime name\n");
 
-    	for(i = 0; i <= shm_ids.max_id; i++) {
+	for(i = 0; i <= shm_ids.max_id; i++) {
 		struct shmid_kernel* shp = shm_lock(i);
 		if(shp!=NULL) {
-#define SMALL_STRING "%10d %10d  %4o %10u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
-#define BIG_STRING   "%10d %10d  %4o %21u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
+#define SMALL_STRING "%10d %10d  %4o %10u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu %.*s\n"
+#define BIG_STRING   "%10d %10d  %4o %21u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu %.*s\n"
 			char *format;
 
 			if (sizeof(size_t) <= sizeof(int))
 				format = SMALL_STRING;
 			else
 				format = BIG_STRING;
-	    		len += sprintf(buffer + len, format,
+			len += sprintf(buffer + len, format,
 				shp->u.shm_perm.key,
 				shm_buildid(i, shp->u.shm_perm.seq),
 				shp->u.shm_perm.mode,
@@ -967,7 +1122,9 @@
 				shp->u.shm_perm.cgid,
 				shp->u.shm_atime,
 				shp->u.shm_dtime,
-				shp->u.shm_ctime);
+				shp->u.shm_ctime,
+				shp->namelen,
+				shp->name);
 			shm_unlock(i);
 
 			pos += len;
diff -uNr 2.3.34/kernel/acct.c c34/kernel/acct.c
--- 2.3.34/kernel/acct.c	Wed Dec  8 21:01:51 1999
+++ c34/kernel/acct.c	Thu Dec 23 20:42:19 1999
@@ -162,7 +162,7 @@
 		if (IS_ERR(tmp))
 			goto out;
 		/* Difference from BSD - they don't do O_APPEND */
-		file = filp_open(tmp, O_WRONLY|O_APPEND, 0);
+		file = filp_open(tmp, O_WRONLY|O_APPEND, 0, NULL);
 		putname(tmp);
 		if (IS_ERR(file)) {
 			error = PTR_ERR(file);
diff -uNr 2.3.34/mm/mmap.c c34/mm/mmap.c
--- 2.3.34/mm/mmap.c	Thu Dec 23 20:41:46 1999
+++ c34/mm/mmap.c	Thu Dec 23 20:42:19 1999
@@ -271,7 +271,6 @@
 	vma->vm_ops = NULL;
 	vma->vm_pgoff = pgoff;
 	vma->vm_file = NULL;
-	vma->vm_private_data = NULL;
 
 	/* Clear old maps */
 	error = -ENOMEM;
@@ -547,7 +546,6 @@
 		mpnt->vm_ops = area->vm_ops;
 		mpnt->vm_pgoff = area->vm_pgoff + ((end - area->vm_start) >> PAGE_SHIFT);
 		mpnt->vm_file = area->vm_file;
-		mpnt->vm_private_data = area->vm_private_data;
 		if (mpnt->vm_file)
 			get_file(mpnt->vm_file);
 		if (mpnt->vm_ops && mpnt->vm_ops->open)
@@ -780,7 +778,6 @@
 	vma->vm_ops = NULL;
 	vma->vm_pgoff = 0;
 	vma->vm_file = NULL;
-	vma->vm_private_data = NULL;
 
 	/*
 	 * merge_segments may merge our vma, so we can't refer to it
@@ -927,7 +924,6 @@
 
 		/* To share, we must have the same file, operations.. */
 		if ((mpnt->vm_file != prev->vm_file)||
-		    (mpnt->vm_private_data != prev->vm_private_data)	||
 		    (mpnt->vm_ops != prev->vm_ops)	||
 		    (mpnt->vm_flags != prev->vm_flags)	||
 		    (prev->vm_end != mpnt->vm_start))
diff -uNr 2.3.34/net/khttpd/security.c c34/net/khttpd/security.c
--- 2.3.34/net/khttpd/security.c	Sat Sep 18 20:49:06 1999
+++ c34/net/khttpd/security.c	Thu Dec 23 20:42:19 1999
@@ -115,7 +115,7 @@
 
 	
 		
-	filp = filp_open(Filename,00,O_RDONLY);
+	filp = filp_open(Filename,00,O_RDONLY,NULL);
 	
 	
 	if ((IS_ERR(filp))||(filp==NULL)||(filp->f_dentry==NULL))
diff -uNr 2.3.34/net/unix/af_unix.c c34/net/unix/af_unix.c
--- 2.3.34/net/unix/af_unix.c	Sun Nov  7 11:41:39 1999
+++ c34/net/unix/af_unix.c	Thu Dec 23 20:42:19 1999
@@ -572,7 +572,7 @@
 
 		/* Do not believe to VFS, grab kernel lock */
 		lock_kernel();
-		dentry = open_namei(sunname->sun_path, 2|O_NOFOLLOW, S_IFSOCK);
+		dentry = open_namei(sunname->sun_path, 2|O_NOFOLLOW, S_IFSOCK, NULL);
 		if (IS_ERR(dentry)) {
 			*error = PTR_ERR(dentry);
 			unlock_kernel();

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1999-12-31 16:58 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-12-28 17:32 [PATCH] get rid of vm_private_data and win posix shm Christoph Rohland
1999-12-28 17:50 ` Alan Cox
1999-12-28 18:38   ` Christoph Rohland
     [not found] ` <199912281914.LAA02201@penguin.transmeta.com>
1999-12-28 20:48   ` Christoph Rohland
1999-12-31 16:58 ` [PATCH] get rid of vm_private_data and win posix shm version 2 Christoph Rohland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox