summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-03-24 01:14:54 +0000
committerRoland McGrath <roland@gnu.org>2002-03-24 01:14:54 +0000
commitfcaacbd5216dffa24ef55bb843618e2b893e4a07 (patch)
tree6e9cb02093d25c1aec004c09fc4ba6598938bfc2
parentd09f4ead65d295e976252869225e7fe591d5e9c0 (diff)
2002-03-23 Roland McGrath <roland@frob.com>
* node.c: Include "default_pager_U.h", not <mach/default_pager.h>. (diskfs_truncate): Return early if page-rounded size is unchanged. Call default_pager_object_set_size on the memory object. (diskfs_grow): Likewise.
-rw-r--r--tmpfs/node.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/tmpfs/node.c b/tmpfs/node.c
index 75c1e188..934b6797 100644
--- a/tmpfs/node.c
+++ b/tmpfs/node.c
@@ -1,5 +1,5 @@
/* Node state and file contents for tmpfs.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000,01,02 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -23,7 +23,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <fcntl.h>
#include <hurd/hurd_types.h>
#include <hurd/store.h>
-#include <mach/default_pager.h>
+#include "default_pager_U.h"
unsigned int num_files;
static unsigned int gen;
@@ -400,11 +400,22 @@ diskfs_truncate (struct node *np, off_t size)
np->dn_stat.st_size = size;
size = round_page (size);
+ if (size == np->allocsize)
+ return 0;
if (np->dn->u.reg.memobj != MACH_PORT_NULL)
{
- /* XXX We have no way to truncate the memory object. */
- return 0;
+ error_t err = default_pager_object_set_size (np->dn->u.reg.memobj, size);
+ if (err == MIG_BAD_ID)
+ /* This is an old default pager. We have no way to truncate the
+ memory object. Note that the behavior here will be wrong in
+ two ways: user accesses past the end won't fault; and, more
+ importantly, later growing the file won't zero the contents
+ past the size we just supposedly truncated to. For proper
+ behavior, use a new default pager. */
+ return 0;
+ if (err)
+ return err;
}
/* Otherwise it never had any real contents. */
@@ -434,6 +445,16 @@ diskfs_grow (struct node *np, off_t size, struct protid *cred)
if (default_pager == MACH_PORT_NULL)
return EIO;
+ if (np->dn->u.reg.memobj != MACH_PORT_NULL)
+ {
+ /* Increase the limit the memory object will allow to be accessed. */
+ error_t err = default_pager_object_set_size (np->dn->u.reg.memobj, size);
+ if (err == MIG_BAD_ID) /* Old default pager, never limited it. */
+ err = 0;
+ if (err)
+ return err;
+ }
+
adjust_used (size - np->allocsize);
np->dn_stat.st_blocks += (size - np->allocsize) / 512;
np->allocsize = size;
@@ -463,9 +484,7 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
pager how big to make its bitmaps. This is just an optimization for
the default pager; the memory object can be expanded at any time just
by accessing more of it. (It also optimizes the case of empty files
- so we might never make a memory object at all.) If a user accesses
- areas outside the bounds of the file, he will just get to diddle the
- contents of the future larger file. */
+ so we might never make a memory object at all.) */
if (np->dn->u.reg.memobj == MACH_PORT_NULL)
{
error_t err = default_pager_object_create (default_pager,
@@ -477,6 +496,10 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
return MACH_PORT_NULL;
}
assert (np->dn->u.reg.memobj != MACH_PORT_NULL);
+ /* A new-fangled default pager lets us prevent user accesses
+ past the specified size of the file. */
+ err = default_pager_object_set_size (np->dn->u.reg.memobj,
+ np->allocsize);
}
/* XXX always writable */