patch-2.3.25 linux/ipc/shm.c

Next file: linux/ipc/util.c
Previous file: linux/ipc/sem.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.24/linux/ipc/shm.c linux/ipc/shm.c
@@ -27,7 +27,7 @@
 
 extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
 static int findkey (key_t key);
-static int newseg (key_t key, int shmflg, int size);
+static int newseg (key_t key, int shmflg, size_t size);
 static int shm_map (struct vm_area_struct *shmd);
 static void killseg (int id);
 static void shm_open (struct vm_area_struct *shmd);
@@ -57,17 +57,13 @@
 void __init shm_init (void)
 {
 	int id;
-#ifdef CONFIG_PROC_FS
-	struct proc_dir_entry *ent;
-#endif
 
 	for (id = 0; id < SHMMNI; id++)
 		shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
 	shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0;
 	init_waitqueue_head(&shm_wait);
 #ifdef CONFIG_PROC_FS
-	ent = create_proc_entry("sysvipc/shm", 0, 0);
-	ent->read_proc = sysvipc_shm_read_proc;
+	create_proc_read_entry("sysvipc/shm", 0, 0, sysvipc_shm_read_proc, NULL);
 #endif
 	return;
 }
@@ -104,7 +100,7 @@
 /*
  * allocate new shmid_kernel and pgtable. protected by shm_segs[id] = NOID.
  */
-static int newseg (key_t key, int shmflg, int size)
+static int newseg (key_t key, int shmflg, size_t size)
 {
 	struct shmid_kernel *shp;
 	int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
@@ -168,16 +164,16 @@
 	return (unsigned int) shp->u.shm_perm.seq * SHMMNI + id;
 }
 
-int shmmax = SHMMAX;
+size_t shmmax = SHMMAX;
 
-asmlinkage long sys_shmget (key_t key, int size, int shmflg)
+asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
 {
 	struct shmid_kernel *shp;
 	int err, id = 0;
 
 	down(&current->mm->mmap_sem);
 	spin_lock(&shm_lock);
-	if (size < 0 || size > shmmax) {
+	if (size > shmmax) {
 		err = -EINVAL;
 	} else if (key == IPC_PRIVATE) {
 		err = newseg(key, shmflg, size);
@@ -237,7 +233,7 @@
 			rss++;
 		} else {
 			lock_kernel();
-			swap_free(pte);
+			swap_free(pte_to_swp_entry(pte));
 			unlock_kernel();
 			swp++;
 		}
@@ -409,7 +405,7 @@
  * shmd->vm_end		multiple of SHMLBA
  * shmd->vm_next	next attach for task
  * shmd->vm_next_share	next attach for segment
- * shmd->vm_offset	offset into segment
+ * shmd->vm_pgoff	offset into segment (in pages)
  * shmd->vm_private_data		signature for this attach
  */
 
@@ -494,7 +490,7 @@
 		err = -ENOMEM;
 		addr = 0;
 	again:
-		if (!(addr = get_unmapped_area(addr, shp->u.shm_segsz)))
+		if (!(addr = get_unmapped_area(addr, (unsigned long)shp->u.shm_segsz)))
 			goto out;
 		if(addr & (SHMLBA - 1)) {
 			addr = (addr + (SHMLBA - 1)) & ~(SHMLBA - 1);
@@ -520,7 +516,7 @@
 	if (addr < current->mm->start_stack &&
 	    addr > current->mm->start_stack - PAGE_SIZE*(shp->shm_npages + 4))
 		goto out;
-	if (!(shmflg & SHM_REMAP) && find_vma_intersection(current->mm, addr, addr + shp->u.shm_segsz))
+	if (!(shmflg & SHM_REMAP) && find_vma_intersection(current->mm, addr, addr + (unsigned long)shp->u.shm_segsz))
 		goto out;
 
 	err = -EACCES;
@@ -551,7 +547,7 @@
 			 | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC
 			 | ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE);
 	shmd->vm_file = NULL;
-	shmd->vm_offset = 0;
+	shmd->vm_pgoff = 0;
 	shmd->vm_ops = &shm_vm_ops;
 
 	shp->u.shm_nattch++;	    /* prevent destruction */
@@ -631,7 +627,7 @@
 	for (shmd = current->mm->mmap; shmd; shmd = shmdnext) {
 		shmdnext = shmd->vm_next;
 		if (shmd->vm_ops == &shm_vm_ops
-		    && shmd->vm_start - shmd->vm_offset == (ulong) shmaddr)
+		    && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr)
 			do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
 	}
 	up(&current->mm->mmap_sem);
@@ -662,7 +658,8 @@
 	struct page * page;
 
 	shp = *(struct shmid_kernel **) shmd->vm_private_data;
-	idx = (address - shmd->vm_start + shmd->vm_offset) >> PAGE_SHIFT;
+	idx = (address - shmd->vm_start) >> PAGE_SHIFT;
+	idx += shmd->vm_pgoff;
 
 	spin_lock(&shm_lock);
 again:
@@ -678,7 +675,7 @@
 			if (pte_val(pte) != pte_val(shp->shm_pages[idx]))
 				goto changed;
 		} else {
-			pte_t entry = pte;
+			swp_entry_t entry = pte_to_swp_entry(pte);
 
 			spin_unlock(&shm_lock);
 			page = lookup_swap_cache(entry);
@@ -735,15 +732,18 @@
 {
 	pte_t page;
 	struct shmid_kernel *shp;
-	pte_t swap_entry;
+	swp_entry_t swap_entry;
 	unsigned long id, idx;
 	int loop = 0;
 	int counter;
 	struct page * page_map;
 	
 	counter = shm_rss >> prio;
+	if (!counter)
+		return 0;
 	lock_kernel();
-	if (!counter || !pte_val(swap_entry = get_swap_page())) {
+	swap_entry = get_swap_page();
+	if (!swap_entry.val) {
 		unlock_kernel();
 		return 0;
 	}
@@ -792,7 +792,7 @@
 		goto check_table;
 	if (!(page_map = prepare_highmem_swapout(page_map)))
 		goto check_table;
-	shp->shm_pages[idx] = swap_entry;
+	shp->shm_pages[idx] = swp_entry_to_pte(swap_entry);
 	swap_successes++;
 	shm_swp++;
 	shm_rss--;
@@ -812,7 +812,7 @@
  * Free the swap entry and set the new pte for the shm page.
  */
 static void shm_unuse_page(struct shmid_kernel *shp, unsigned long idx,
-			pte_t entry, struct page *page)
+			swp_entry_t entry, struct page *page)
 {
 	pte_t pte;
 
@@ -832,7 +832,7 @@
 /*
  * unuse_shm() search for an eventually swapped out shm page.
  */
-void shm_unuse(pte_t entry, struct page *page)
+void shm_unuse(swp_entry_t entry, struct page *page)
 {
 	int i, n;
 
@@ -841,11 +841,16 @@
 		struct shmid_kernel *seg = shm_segs[i];
 		if ((seg == IPC_UNUSED) || (seg == IPC_NOID))
 			continue;
-		for (n = 0; n < seg->shm_npages; n++)
-			if (pte_val(seg->shm_pages[n]) == pte_val(entry)) {
+		for (n = 0; n < seg->shm_npages; n++) {
+			if (pte_none(seg->shm_pages[n]))
+				continue;
+			if (pte_present(seg->shm_pages[n]))
+				continue;
+			if (pte_to_swp_entry(seg->shm_pages[n]).val == entry.val) {
 				shm_unuse_page(seg, n, entry, page);
 				return;
 			}
+		}
 	}
 	spin_unlock(&shm_lock);
 }
@@ -862,7 +867,15 @@
 	spin_lock(&shm_lock);
     	for(i = 0; i < SHMMNI; i++)
 		if(shm_segs[i] != IPC_UNUSED) {
-	    		len += sprintf(buffer + len, "%10d %10d  %4o %10d %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\n"
+#define BIG_STRING   "%10d %10d  %4o %21u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
+			char *format;
+
+			if (sizeof(size_t) <= sizeof(int))
+				format = SMALL_STRING;
+			else
+				format = BIG_STRING;
+	    		len += sprintf(buffer + len, format,
 			shm_segs[i]->u.shm_perm.key,
 			shm_segs[i]->u.shm_perm.seq * SHMMNI + i,
 			shm_segs[i]->u.shm_perm.mode,

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)