summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1996-01-18 23:53:57 +0000
committerMiles Bader <miles@gnu.org>1996-01-18 23:53:57 +0000
commit3b66d445cfb0646820a887720c20e095cbbd454c (patch)
treeb5cd29cbebdc8e3a4ef90ca9c8dcb4ac514618d3
parent2c06b6c6bfe7053a89ce14a25c8443da7167d6bc (diff)
(diskfs_file_update): Ext2fs doesn't require that the last block in the file
always be allocated, so don't. (diskfs_grow, pager_unlock_page): Don't set last_block_allocated.
-rw-r--r--ext2fs/pager.c63
1 files changed, 26 insertions, 37 deletions
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index 8cd0659a..e9131304 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -407,8 +407,8 @@ pager_unlock_page (struct user_pager_info *pager, vm_offset_t page)
struct disknode *dn = node->dn;
rwlock_writer_lock (&dn->alloc_lock);
- err = diskfs_catch_exception ();
+ err = diskfs_catch_exception ();
if (!err)
{
int left = vm_page_size;
@@ -424,15 +424,15 @@ pager_unlock_page (struct user_pager_info *pager, vm_offset_t page)
while (left > 0)
{
block_t disk_block;
- err = ext2_getblk(node, block++, 1, &disk_block);
+ err = ext2_getblk (node, block++, 1, &disk_block);
if (err)
- break;
+ {
+ dn->last_page_partially_writable = (left < vm_page_size);
+ break;
+ }
left -= block_size;
}
- if (page + vm_page_size >= node->allocsize)
- dn->last_block_allocated = 1;
-
#ifdef EXT2FS_DEBUG
if (dn->last_page_partially_writable)
ext2_debug ("made page %u[%lu] in inode %d partially writable",
@@ -442,12 +442,15 @@ pager_unlock_page (struct user_pager_info *pager, vm_offset_t page)
page, vm_page_size, dn->number);
#endif
}
-
diskfs_end_catch_exception ();
+
rwlock_writer_unlock (&dn->alloc_lock);
if (err == ENOSPC)
ext2_warning ("This filesystem is out of space, and will now crash. Bye!");
+ else if (err)
+ ext2_warning ("inode=%d, page=0x%x: %s",
+ dn->number, page, strerror (err));
return err;
}
@@ -468,15 +471,15 @@ diskfs_grow (struct node *node, off_t size, struct protid *cred)
{
error_t err;
struct disknode *dn = node->dn;
- vm_offset_t old_size = node->allocsize;
- vm_offset_t new_size = round_block (size);
+ off_t old_size = node->allocsize;
+ volatile off_t new_size = round_block (size);
ext2_debug ("growing inode %d to %u bytes (from %u)", dn->number,
new_size, old_size);
rwlock_writer_lock (&dn->alloc_lock);
- err = diskfs_catch_exception ();
+ err = diskfs_catch_exception ();
if (!err)
{
if (dn->last_page_partially_writable)
@@ -489,12 +492,6 @@ diskfs_grow (struct node *node, off_t size, struct protid *cred)
block_t block = old_size >> log2_block_size;
int count = trunc_page (old_size) + vm_page_size - old_size;
- if (old_size + count < new_size)
- /* The page we're unlocking (and therefore creating) doesn't
- extend all the way to the end of the file, so there's some
- unallocated space left there. */
- dn->last_block_allocated = 0;
-
if (old_size + count > new_size)
/* This growth won't create the whole of the last page. */
count = new_size - old_size;
@@ -511,20 +508,28 @@ diskfs_grow (struct node *node, off_t size, struct protid *cred)
block_t disk_block;
err = ext2_getblk(node, block++, 1, &disk_block);
if (err)
- break;
+ /* We've failed to make the whole last page writable. */
+ {
+ new_size -= count; /* Ensure we get re-called later. */
+ dn->last_page_partially_writable = 1; /* still */
+ break;
+ }
count -= block_size;
}
- ext2_debug ("new state: page %s, last block %sallocated",
+ ext2_debug ("new state: page %s",
dn->last_page_partially_writable
- ? "still partial" : "completely allocated",
- dn->last_block_allocated ? "" : "now un");
+ ? "still partial" : "completely allocated");
+
+ if (err)
+ ext2_warning ("inode=%d, target=%ld: %s",
+ dn->number, new_size + count, strerror (err));
}
node->allocsize = new_size;
}
-
diskfs_end_catch_exception ();
+
rwlock_writer_unlock (&dn->alloc_lock);
return err;
@@ -542,22 +547,6 @@ diskfs_file_update (struct node *node, int wait)
{
struct pager *pager;
- if (!node->dn->last_block_allocated)
- /* Allocate the last block in the file to maintain consistency with the
- file size. */
- {
- rwlock_writer_lock (&node->dn->alloc_lock);
- if (!node->dn->last_block_allocated) /* check again with the lock */
- {
- block_t disk_block;
- block_t block = (node->allocsize >> log2_block_size) - 1;
- ext2_debug ("allocating final block %lu", block);
- if (ext2_getblk (node, block, 1, &disk_block) == 0)
- node->dn->last_block_allocated = 1;
- }
- rwlock_writer_unlock (&node->dn->alloc_lock);
- }
-
spin_lock (&node_to_page_lock);
pager = node->dn->pager;
if (pager)