Date: Fri, 29 Mar 2002 11:57:42 -0800 (PST) From: "Dorr H. Clark" <dclark@applmath.scu.edu> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/36504: crash/panic vm_object_allocate under file system code w/fix Message-ID: <200203291957.g2TJvg114596@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 36504
>Category: kern
>Synopsis: crash/panic vm_object_allocate under file system code w/fix
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Mar 29 12:00:10 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: Dorr H. Clark
>Release: 4.4
>Organization:
Santa Clara University
>Environment:
FreeBSD 4.4 on i386, also 4.5 & current have same issue
>Description:
The problem is that unlike other parts of the kernel,
vnode_pager_alloc assumes that the call to vm_object_allocate
will succeed. If the allocation fails, the kernel
crashes immediately. I have put in a defensive check
for this, and also changed the error handling in
the calling routine to account for the allocation failure.
>How-To-Repeat:
hard to do - it's intermittent under heavy load w/almost no memory
>Fix:
My fix touches two files, vm/vnode_pager.c and kern/vfs_default.c,
I chose to minimize code changes but I think vfs_default.c could be
favorably restructured a little in this area. Sorry for the grody
diff but I'm on HPUX here.
First file change vm/vnode_pager.c:
*** 143,149 ****
* And an object of the appropriate size
*/
object = vm_object_allocate(OBJT_VNODE, OFF_TO_IDX(round_page(s
ize)));
+ if (object) {
object->flags = 0;
object->un_pager.vnp.vnp_size = size;
--- 143,148 ----
***************
*** 151,157 ****
object->handle = handle;
vp->v_object = object;
vp->v_usecount++;
+ }
} else {
object->ref_count++;
vp->v_usecount++;
--- 150,155 ----
Second file change kern/vfs_default.c:
***************
*** 516,524 ****
retry:
if ((object = vp->v_object) == NULL) {
if (vp->v_type == VREG || vp->v_type == VDIR) {
! if (((error = VOP_GETATTR(vp, &vat, cred, p)) != 0) ||
! (!(object = vnode_pager_alloc(vp, vat.va_size, 0, 0))))
goto retn;
} else if (devsw(vp->v_rdev) != NULL) {
/*
* This simply allocates the biggest object possible
--- 518,526 ----
retry:
if ((object = vp->v_object) == NULL) {
if (vp->v_type == VREG || vp->v_type == VDIR) {
! if ((error = VOP_GETATTR(vp, &vat, cred, p)) != 0)
goto retn;
+ object = vnode_pager_alloc(vp, vat.va_size, 0, 0);
} else if (devsw(vp->v_rdev) != NULL) {
/*
* This simply allocates the biggest object possible
***************
*** 525,532 ****
* for a disk vnode. This should be fixed, but doesn't
* cause any problems (yet).
*/
! if (!(object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX
), 0, 0)))
! goto retn;
} else {
goto retn;
}
--- 527,533 ----
* for a disk vnode. This should be fixed, but doesn
't
* cause any problems (yet).
*/
! object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX), 0
, 0);
} else {
goto retn;
}
***************
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200203291957.g2TJvg114596>
