1 |
/* Node state and file contents for tmpfs. |
/* Node state and file contents for tmpfs. |
2 |
Copyright (C) 2000, 2001 Free Software Foundation, Inc. |
Copyright (C) 2000,01,02 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of the GNU Hurd. |
This file is part of the GNU Hurd. |
5 |
|
|
23 |
#include <fcntl.h> |
#include <fcntl.h> |
24 |
#include <hurd/hurd_types.h> |
#include <hurd/hurd_types.h> |
25 |
#include <hurd/store.h> |
#include <hurd/store.h> |
26 |
#include <mach/default_pager.h> |
#include "default_pager_U.h" |
27 |
|
|
28 |
unsigned int num_files; |
unsigned int num_files; |
29 |
static unsigned int gen; |
static unsigned int gen; |
400 |
np->dn_stat.st_size = size; |
np->dn_stat.st_size = size; |
401 |
|
|
402 |
size = round_page (size); |
size = round_page (size); |
403 |
|
if (size == np->allocsize) |
404 |
|
return 0; |
405 |
|
|
406 |
if (np->dn->u.reg.memobj != MACH_PORT_NULL) |
if (np->dn->u.reg.memobj != MACH_PORT_NULL) |
407 |
{ |
{ |
408 |
/* XXX We have no way to truncate the memory object. */ |
error_t err = default_pager_object_set_size (np->dn->u.reg.memobj, size); |
409 |
return 0; |
if (err == MIG_BAD_ID) |
410 |
|
/* This is an old default pager. We have no way to truncate the |
411 |
|
memory object. Note that the behavior here will be wrong in |
412 |
|
two ways: user accesses past the end won't fault; and, more |
413 |
|
importantly, later growing the file won't zero the contents |
414 |
|
past the size we just supposedly truncated to. For proper |
415 |
|
behavior, use a new default pager. */ |
416 |
|
return 0; |
417 |
|
if (err) |
418 |
|
return err; |
419 |
} |
} |
420 |
/* Otherwise it never had any real contents. */ |
/* Otherwise it never had any real contents. */ |
421 |
|
|
445 |
if (default_pager == MACH_PORT_NULL) |
if (default_pager == MACH_PORT_NULL) |
446 |
return EIO; |
return EIO; |
447 |
|
|
448 |
|
if (np->dn->u.reg.memobj != MACH_PORT_NULL) |
449 |
|
{ |
450 |
|
/* Increase the limit the memory object will allow to be accessed. */ |
451 |
|
error_t err = default_pager_object_set_size (np->dn->u.reg.memobj, size); |
452 |
|
if (err == MIG_BAD_ID) /* Old default pager, never limited it. */ |
453 |
|
err = 0; |
454 |
|
if (err) |
455 |
|
return err; |
456 |
|
} |
457 |
|
|
458 |
adjust_used (size - np->allocsize); |
adjust_used (size - np->allocsize); |
459 |
np->dn_stat.st_blocks += (size - np->allocsize) / 512; |
np->dn_stat.st_blocks += (size - np->allocsize) / 512; |
460 |
np->allocsize = size; |
np->allocsize = size; |
484 |
pager how big to make its bitmaps. This is just an optimization for |
pager how big to make its bitmaps. This is just an optimization for |
485 |
the default pager; the memory object can be expanded at any time just |
the default pager; the memory object can be expanded at any time just |
486 |
by accessing more of it. (It also optimizes the case of empty files |
by accessing more of it. (It also optimizes the case of empty files |
487 |
so we might never make a memory object at all.) If a user accesses |
so we might never make a memory object at all.) */ |
|
areas outside the bounds of the file, he will just get to diddle the |
|
|
contents of the future larger file. */ |
|
488 |
if (np->dn->u.reg.memobj == MACH_PORT_NULL) |
if (np->dn->u.reg.memobj == MACH_PORT_NULL) |
489 |
{ |
{ |
490 |
error_t err = default_pager_object_create (default_pager, |
error_t err = default_pager_object_create (default_pager, |
496 |
return MACH_PORT_NULL; |
return MACH_PORT_NULL; |
497 |
} |
} |
498 |
assert (np->dn->u.reg.memobj != MACH_PORT_NULL); |
assert (np->dn->u.reg.memobj != MACH_PORT_NULL); |
499 |
|
/* A new-fangled default pager lets us prevent user accesses |
500 |
|
past the specified size of the file. */ |
501 |
|
err = default_pager_object_set_size (np->dn->u.reg.memobj, |
502 |
|
np->allocsize); |
503 |
} |
} |
504 |
|
|
505 |
/* XXX always writable */ |
/* XXX always writable */ |