Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Sep 1998 18:49:34 -0700 (PDT)
From:      Julian Elischer <julian@whistle.com>
To:        Terry Lambert <tlambert@primenet.com>
Cc:        dg@root.com, current@FreeBSD.ORG
Subject:   Re: VM mmap file extension bug still exists?
Message-ID:  <Pine.BSF.3.95.980929182706.11107L-100000@current1.whistle.com>
In-Reply-To: <199809280631.XAA22753@usr07.primenet.com>

next in thread | previous in thread | raw e-mail | index | archive | help
> 
> It's definitely a workaround.  The real fix is to add a parementer to
> the mapping function.

Ok here's the patch done the 'correct way'
I have looked at the problem with terry and he has convinced me that
there IS a problem there.

certainly the value ov va_size is set to be the next page boundary in some
cases and teh end of the file in others.
In the case where the baking object is a file, there is code
that assumes that it's the end of the file, and some cases of code that
SETS it to the end of the file, yet in others it's set to 
teh next page boundary. One of these has to be wrong, ans setting it to
the next page boundary breaks the code that assumes that it's
at the end of the backing file.

here's a patch that does it


> 
> The real fix is to set the size based on the real size, not rounded to
> a page boundary.
> 
> I think the race window is actually NULL.
> 
> Would you commit a change based on a adding a parameter?  I think I
> could get whistle to pay for the time, if your answer was "yes".

well seeing that I did it at work, I guess they did :-)

> 
> 
> 					Terry Lambert
> 					terry@lambert.org


This patch is in testing and I will commit it if testing proves that 
it removes the corrupted file problem we are seeing.

Matt Dillon and others are also seeing this problem and results from
anyone seeing file corruption when mmap is in use will be welcome.


julian
----------------
? rc
? compile/LINT
? dev/dpt/x.tar
? i386/conf/DPT
? i386/conf/SLICE
? i386/conf/GENERIC.DPT
? i386/isa/sr.part1
? i386/isa/sr.part2a
? i386/isa/sr.part2b
? i386/isa/if_sr.c.netgraph
? kern/vfs_conf.c.x
? netatalk/netbsd.diffs.uu
? scsi/x.diff
? sys/netscape-3.0.core
? ufs/ffs/ffs_vnops.c.spl
? ufs/ffs/ffs_softdep.c
? ufs/ffs/softdep.h
Index: kern/sysv_shm.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sysv_shm.c,v
retrieving revision 1.38
diff -c -r1.38 sysv_shm.c
*** sysv_shm.c	1998/08/24 08:39:38	1.38
--- sysv_shm.c	1998/09/30 01:47:20
***************
*** 502,508 ****
  	 */
  	shm_handle->shm_object =
  		vm_pager_allocate(OBJT_SWAP, 0, OFF_TO_IDX(size),
! 			VM_PROT_DEFAULT, 0);
  	vm_object_clear_flag(shm_handle->shm_object, OBJ_ONEMAPPING);
  	vm_object_set_flag(shm_handle->shm_object, OBJ_NOSPLIT);
  
--- 502,508 ----
  	 */
  	shm_handle->shm_object =
  		vm_pager_allocate(OBJT_SWAP, 0, OFF_TO_IDX(size),
! 			VM_PROT_DEFAULT, 0, size);
  	vm_object_clear_flag(shm_handle->shm_object, OBJ_ONEMAPPING);
  	vm_object_set_flag(shm_handle->shm_object, OBJ_NOSPLIT);
  
Index: kern/vfs_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_subr.c,v
retrieving revision 1.163
diff -c -r1.163 vfs_subr.c
*** vfs_subr.c	1998/09/14 19:56:40	1.163
--- vfs_subr.c	1998/09/30 01:47:22
***************
*** 2529,2542 ****
  			if ((error = VOP_GETATTR(vp, &vat, cred, p)) != 0)
  				goto retn;
  			object = vnode_pager_alloc(vp,
! 				OFF_TO_IDX(round_page(vat.va_size)), 0, 0);
  		} else if (major(vp->v_rdev) < nblkdev) {
  			/*
  			 * This simply allocates the biggest object possible
  			 * for a VBLK vnode.  This should be fixed, but doesn't
  			 * cause any problems (yet).
  			 */
! 			object = vnode_pager_alloc(vp, INT_MAX, 0, 0);
  		}
  		object->ref_count--;
  		vp->v_usecount--;
--- 2529,2544 ----
  			if ((error = VOP_GETATTR(vp, &vat, cred, p)) != 0)
  				goto retn;
  			object = vnode_pager_alloc(vp,
! 				OFF_TO_IDX(round_page(vat.va_size)),
! 						0, 0, vat.va_size);
  		} else if (major(vp->v_rdev) < nblkdev) {
  			/*
  			 * This simply allocates the biggest object possible
  			 * for a VBLK vnode.  This should be fixed, but doesn't
  			 * cause any problems (yet).
  			 */
! 			object = vnode_pager_alloc(vp, INT_MAX,
! 					0, 0, (off_t) INT_MAX * PAGE_SIZE);
  		}
  		object->ref_count--;
  		vp->v_usecount--;
Index: vm/default_pager.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/default_pager.c,v
retrieving revision 1.15
diff -c -r1.15 default_pager.c
*** default_pager.c	1998/02/06 12:14:20	1.15
--- default_pager.c	1998/09/30 01:47:27
***************
*** 45,51 ****
  #include <vm/swap_pager.h>
  
  static vm_object_t default_pager_alloc __P((void *, vm_size_t, vm_prot_t,
! 		vm_ooffset_t));
  static void default_pager_dealloc __P((vm_object_t));
  static int default_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
  static int default_pager_putpages __P((vm_object_t, vm_page_t *, int, 
--- 45,51 ----
  #include <vm/swap_pager.h>
  
  static vm_object_t default_pager_alloc __P((void *, vm_size_t, vm_prot_t,
! 		vm_ooffset_t, off_t size_in_bytes));
  static void default_pager_dealloc __P((vm_object_t));
  static int default_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
  static int default_pager_putpages __P((vm_object_t, vm_page_t *, int, 
***************
*** 70,76 ****
   */
  static vm_object_t
  default_pager_alloc(void *handle, vm_size_t size, vm_prot_t prot,
! 		    vm_ooffset_t offset)
  {
  	if (handle != NULL)
  		panic("default_pager_alloc: handle specified");
--- 70,76 ----
   */
  static vm_object_t
  default_pager_alloc(void *handle, vm_size_t size, vm_prot_t prot,
! 		    vm_ooffset_t offset, off_t size_in_bytes)
  {
  	if (handle != NULL)
  		panic("default_pager_alloc: handle specified");
Index: vm/device_pager.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/device_pager.c,v
retrieving revision 1.31
diff -c -r1.31 device_pager.c
*** device_pager.c	1998/07/15 02:32:35	1.31
--- device_pager.c	1998/09/30 01:47:27
***************
*** 53,59 ****
  
  static void dev_pager_init __P((void));
  static vm_object_t dev_pager_alloc __P((void *, vm_size_t, vm_prot_t,
! 		vm_ooffset_t));
  static void dev_pager_dealloc __P((vm_object_t));
  static int dev_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
  static int dev_pager_putpages __P((vm_object_t, vm_page_t *, int, 
--- 53,59 ----
  
  static void dev_pager_init __P((void));
  static vm_object_t dev_pager_alloc __P((void *, vm_size_t, vm_prot_t,
! 		vm_ooffset_t, off_t size_in_bytes));
  static void dev_pager_dealloc __P((vm_object_t));
  static int dev_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
  static int dev_pager_putpages __P((vm_object_t, vm_page_t *, int, 
***************
*** 90,96 ****
  }
  
  static vm_object_t
! dev_pager_alloc(void *handle, vm_size_t size, vm_prot_t prot, vm_ooffset_t foff)
  {
  	dev_t dev;
  	d_mmap_t *mapfunc;
--- 90,97 ----
  }
  
  static vm_object_t
! dev_pager_alloc(void *handle, vm_size_t size, vm_prot_t prot,
! 			vm_ooffset_t foff, off_t size_in_bytes)
  {
  	dev_t dev;
  	d_mmap_t *mapfunc;
Index: vm/swap_pager.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/swap_pager.c,v
retrieving revision 1.101
diff -c -r1.101 swap_pager.c
*** swap_pager.c	1998/09/04 08:06:56	1.101
--- swap_pager.c	1998/09/30 01:47:27
***************
*** 137,143 ****
   */
  static vm_object_t
  		swap_pager_alloc __P((void *handle, vm_size_t size,
! 				      vm_prot_t prot, vm_ooffset_t offset));
  static void	swap_pager_dealloc __P((vm_object_t object));
  static boolean_t
  		swap_pager_haspage __P((vm_object_t object, vm_pindex_t pindex,
--- 137,144 ----
   */
  static vm_object_t
  		swap_pager_alloc __P((void *handle, vm_size_t size,
! 				      vm_prot_t prot, vm_ooffset_t
! 				      offset, off_t size_in_bytes));
  static void	swap_pager_dealloc __P((vm_object_t object));
  static boolean_t
  		swap_pager_haspage __P((vm_object_t object, vm_pindex_t pindex,
***************
*** 296,302 ****
   */
  static vm_object_t
  swap_pager_alloc(void *handle, vm_size_t size, vm_prot_t prot,
! 		 vm_ooffset_t offset)
  {
  	vm_object_t object;
  
--- 297,303 ----
   */
  static vm_object_t
  swap_pager_alloc(void *handle, vm_size_t size, vm_prot_t prot,
! 		 vm_ooffset_t offset, off_t size_in_bytes)
  {
  	vm_object_t object;
  
Index: vm/vm_map.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_map.c,v
retrieving revision 1.135
diff -c -r1.135 vm_map.c
*** vm_map.c	1998/09/04 08:06:57	1.135
--- vm_map.c	1998/09/30 01:47:28
***************
*** 1965,1971 ****
  	size = offidxend - offidxstart;
  
  	new_object = vm_pager_allocate(orig_object->type,
! 		NULL, size, VM_PROT_ALL, 0LL);
  	if (new_object == NULL)
  		return;
  
--- 1965,1971 ----
  	size = offidxend - offidxstart;
  
  	new_object = vm_pager_allocate(orig_object->type,
! 		NULL, size, VM_PROT_ALL, 0LL, (vm_ooffset_t) size * PAGE_SIZE);
  	if (new_object == NULL)
  		return;
  
Index: vm/vm_mmap.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_mmap.c,v
retrieving revision 1.83
diff -c -r1.83 vm_mmap.c
*** vm_mmap.c	1998/09/04 08:06:57	1.83
--- vm_mmap.c	1998/09/30 01:47:28
***************
*** 929,939 ****
  	vm_ooffset_t objsize;
  	int docow;
  	struct proc *p = curproc;
  
  	if (size == 0)
  		return (0);
  
! 	objsize = size = round_page(size);
  
  	/*
  	 * We currently can only deal with page aligned file offsets.
--- 929,940 ----
  	vm_ooffset_t objsize;
  	int docow;
  	struct proc *p = curproc;
+ 	struct vattr vat;
  
  	if (size == 0)
  		return (0);
  
! 	vat.va_size = objsize = size = round_page(size);
  
  	/*
  	 * We currently can only deal with page aligned file offsets.
***************
*** 972,978 ****
  			type = OBJT_DEVICE;
  			handle = (void *)(intptr_t)vp->v_rdev;
  		} else {
- 			struct vattr vat;
  			int error;
  
  			error = VOP_GETATTR(vp, &vat, p->p_ucred, p);
--- 973,978 ----
***************
*** 987,993 ****
  		object = NULL;
  	} else {
  		object = vm_pager_allocate(type,
! 			handle, OFF_TO_IDX(objsize), prot, foff);
  		if (object == NULL)
  			return (type == OBJT_DEVICE ? EINVAL : ENOMEM);
  	}
--- 987,993 ----
  		object = NULL;
  	} else {
  		object = vm_pager_allocate(type,
! 			handle, OFF_TO_IDX(objsize), prot, foff, vat.va_size);
  		if (object == NULL)
  			return (type == OBJT_DEVICE ? EINVAL : ENOMEM);
  	}
Index: vm/vm_pager.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_pager.c,v
retrieving revision 1.37
diff -c -r1.37 vm_pager.c
*** vm_pager.c	1998/03/16 01:56:01	1.37
--- vm_pager.c	1998/09/30 01:47:28
***************
*** 92,98 ****
  
  static int dead_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
  static vm_object_t dead_pager_alloc __P((void *, vm_size_t, vm_prot_t,
! 	vm_ooffset_t));
  static int dead_pager_putpages __P((vm_object_t, vm_page_t *, int, int, int *));
  static boolean_t dead_pager_haspage __P((vm_object_t, vm_pindex_t, int *, int *));
  static void dead_pager_dealloc __P((vm_object_t));
--- 92,98 ----
  
  static int dead_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
  static vm_object_t dead_pager_alloc __P((void *, vm_size_t, vm_prot_t,
! 	vm_ooffset_t, off_t));
  static int dead_pager_putpages __P((vm_object_t, vm_page_t *, int, int, int *));
  static boolean_t dead_pager_haspage __P((vm_object_t, vm_pindex_t, int *, int *));
  static void dead_pager_dealloc __P((vm_object_t));
***************
*** 108,118 ****
  }
  
  vm_object_t
! dead_pager_alloc(handle, size, prot, off)
  	void *handle;
  	vm_size_t size;
  	vm_prot_t prot;
  	vm_ooffset_t off;
  {
  	return NULL;
  }
--- 108,119 ----
  }
  
  vm_object_t
! dead_pager_alloc(handle, size, prot, off, size_in_bytes)
  	void *handle;
  	vm_size_t size;
  	vm_prot_t prot;
  	vm_ooffset_t off;
+ 	off_t	size_in_bytes;
  {
  	return NULL;
  }
***************
*** 228,240 ****
   */
  vm_object_t
  vm_pager_allocate(objtype_t type, void *handle, vm_size_t size, vm_prot_t prot,
! 		  vm_ooffset_t off)
  {
  	struct pagerops *ops;
  
  	ops = pagertab[type];
  	if (ops)
! 		return ((*ops->pgo_alloc) (handle, size, prot, off));
  	return (NULL);
  }
  
--- 229,241 ----
   */
  vm_object_t
  vm_pager_allocate(objtype_t type, void *handle, vm_size_t size, vm_prot_t prot,
! 		  vm_ooffset_t off, off_t size_in_bytes)
  {
  	struct pagerops *ops;
  
  	ops = pagertab[type];
  	if (ops)
! 		return ((*ops->pgo_alloc) (handle, size, prot, off, size_in_bytes));
  	return (NULL);
  }
  
Index: vm/vm_pager.h
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_pager.h,v
retrieving revision 1.16
diff -c -r1.16 vm_pager.h
*** vm_pager.h	1998/03/07 21:37:27	1.16
--- vm_pager.h	1998/09/30 01:47:28
***************
*** 52,58 ****
  
  struct pagerops {
  	void (*pgo_init) __P((void));		/* Initialize pager. */
! 	vm_object_t (*pgo_alloc) __P((void *, vm_size_t, vm_prot_t, vm_ooffset_t));	/* Allocate pager. */
  	void (*pgo_dealloc) __P((vm_object_t));	/* Disassociate. */
  	int (*pgo_getpages) __P((vm_object_t, vm_page_t *, int, int));	/* Get (read) page. */
  	int (*pgo_putpages) __P((vm_object_t, vm_page_t *, int, int, int *)); /* Put (write) page. */
--- 52,59 ----
  
  struct pagerops {
  	void (*pgo_init) __P((void));		/* Initialize pager. */
! 	vm_object_t (*pgo_alloc) __P((void *, vm_size_t, vm_prot_t,
! 				vm_ooffset_t, off_t));	/* Allocate pager. */
  	void (*pgo_dealloc) __P((vm_object_t));	/* Disassociate. */
  	int (*pgo_getpages) __P((vm_object_t, vm_page_t *, int, int));	/* Get (read) page. */
  	int (*pgo_putpages) __P((vm_object_t, vm_page_t *, int, int, int *)); /* Put (write) page. */
***************
*** 88,94 ****
  extern vm_map_t pager_map;
  extern int pager_map_size;
  
! vm_object_t vm_pager_allocate __P((objtype_t, void *, vm_size_t, vm_prot_t, vm_ooffset_t));
  void vm_pager_bufferinit __P((void));
  void vm_pager_deallocate __P((vm_object_t));
  int vm_pager_get_pages __P((vm_object_t, vm_page_t *, int, int));
--- 89,96 ----
  extern vm_map_t pager_map;
  extern int pager_map_size;
  
! vm_object_t vm_pager_allocate __P((objtype_t, void *, vm_size_t,
! 					vm_prot_t, vm_ooffset_t, off_t ));
  void vm_pager_bufferinit __P((void));
  void vm_pager_deallocate __P((vm_object_t));
  int vm_pager_get_pages __P((vm_object_t, vm_page_t *, int, int));
Index: vm/vnode_pager.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vnode_pager.c,v
retrieving revision 1.99
diff -c -r1.99 vnode_pager.c
*** vnode_pager.c	1998/09/28 23:58:10	1.99
--- vnode_pager.c	1998/09/30 01:47:28
***************
*** 95,101 ****
   */
  vm_object_t
  vnode_pager_alloc(void *handle, vm_size_t size, vm_prot_t prot,
! 		  vm_ooffset_t offset)
  {
  	vm_object_t object;
  	struct vnode *vp;
--- 95,101 ----
   */
  vm_object_t
  vnode_pager_alloc(void *handle, vm_size_t size, vm_prot_t prot,
! 		  vm_ooffset_t offset, off_t size_in_bytes)
  {
  	vm_object_t object;
  	struct vnode *vp;
***************
*** 137,143 ****
  		object = vm_object_allocate(OBJT_VNODE, size);
  		object->flags = 0;
  
! 		object->un_pager.vnp.vnp_size = (vm_ooffset_t) size * PAGE_SIZE;
  
  		object->handle = handle;
  		vp->v_object = object;
--- 137,143 ----
  		object = vm_object_allocate(OBJT_VNODE, size);
  		object->flags = 0;
  
! 		object->un_pager.vnp.vnp_size = size_in_bytes;
  
  		object->handle = handle;
  		vp->v_object = object;
Index: vm/vnode_pager.h
===================================================================
RCS file: /home/ncvs/src/sys/vm/vnode_pager.h,v
retrieving revision 1.11
diff -c -r1.11 vnode_pager.h
*** vnode_pager.h	1998/02/26 06:39:59	1.11
--- vnode_pager.h	1998/09/30 01:47:28
***************
*** 43,49 ****
  #define	_VNODE_PAGER_	1
  
  #ifdef KERNEL
! vm_object_t vnode_pager_alloc __P((void *, vm_size_t, vm_prot_t, vm_ooffset_t));
  void vnode_pager_freepage __P((vm_page_t m));
  struct vnode *vnode_pager_lock __P((vm_object_t));
  
--- 43,49 ----
  #define	_VNODE_PAGER_	1
  
  #ifdef KERNEL
! vm_object_t vnode_pager_alloc __P((void *, vm_size_t, vm_prot_t, vm_ooffset_t, off_t));
  void vnode_pager_freepage __P((vm_page_t m));
  struct vnode *vnode_pager_lock __P((vm_object_t));

0000 end of file 0000

  


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95.980929182706.11107L-100000>