From 38b825eb63efa534965edc4df26aaf391b40ebb6 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 8 Feb 1994 19:48:55 +0000 Subject: Initial revision --- ufs/hyper.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 ufs/hyper.c (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c new file mode 100644 index 00000000..9f5cae8d --- /dev/null +++ b/ufs/hyper.c @@ -0,0 +1,43 @@ +/* Fetching and storing the hypermetadata (superblock and cg summary info). + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +void +get_hypermetadata (void) +{ + error_t err; + + err = dev_read_sync (SBLOCK, (vm_address_t *)&sblock, SBSIZE); + assert (!err); + + /* If this is an old filesystem, then we have some more + work to do; some crucial constants might not be set; we + are therefore forced to set them here. */ + if (sblock->fs_npsect < sblock->fs_nsect) + sblock->fs_npsect = sblock->fs_nsect; + if (sblock->fs_interleave < 1) + sblock->fs_interleave = 1; + if (sblock->fs_postblformat == FS_42POSTBLFMT) + sblock->fs_nrpos = 8; + + err = dev_read_sync (fsbtodb (sblock->fs_csaddr), (vm_address_t *) &csum, + sblock->fs_fsize * howmany (sblock->fs_cssize, + sblock->fs_fsize)); + assert (!err); +} + + -- cgit v1.2.3 From 6a0c7935a3dcc4e244cc696bb5fe712cd5b80e39 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 8 Feb 1994 19:53:41 +0000 Subject: Formerly hyper.c.~2~ --- ufs/hyper.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 9f5cae8d..2793985e 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -40,4 +40,31 @@ get_hypermetadata (void) assert (!err); } - +/* Write the superblock and cg summary info to disk. If WAIT is set, + we must wait for everything to hit the disk; if CLEAN is set, then + mark the clean bit. */ +void +diskfs_set_hypermetadata (int wait, int clean) +{ + error_t (*writefn) (daddr_t, vm_address_t, vm_size_t); + writefn = (wait ? dev_write_sync : dev_write); + + (*writefn)(fsbtodb (sblock->fs_csaddr), (vm_address_t) csum, + sblock->fs_fsize * howmany (sblock->fs_cssize, + sblock->fs_fssize)); + + if (clean) + sblock->fs_clean = 1; + if (sblock->fs_postblformat == FS_42POSTBLFMT) + { + char sblockcopy[SBSIZE]; + bcopy (sblock, sblockcopy, SBSIZE); + ((struct fs *)sblockcopy)->fs_nrpos = -1; + (*writefn) (SBLOCK, (vm_address_t) sblockcopy, SBSIZE); + } + else + (*writefn) (SBLOCK, (vm_address_t) sblock, SBSIZE); + sblock->fs_clean = 0; +} + + -- cgit v1.2.3 From 8cb8d253067c9d0591ee98e387f0fd8cd27e8ca2 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 8 Feb 1994 19:58:40 +0000 Subject: Initial revision --- ufs/consts.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 ufs/consts.c (limited to 'ufs') diff --git a/ufs/consts.c b/ufs/consts.c new file mode 100644 index 00000000..dd4d03de --- /dev/null +++ b/ufs/consts.c @@ -0,0 +1,25 @@ +/* Various constants wanted by the diskfs library + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +size_t diskfs_dirstat_size = sizeof (struct dirstat); +int diskfs_link_max = LINK_MAX; +int diskfs_maxsymlinks = 8; +int diskfs_shortcut_symlink = 1; +int diskfs_shortcut_chrdev = 1; +int diskfs_shortcut_blkdev = 1; +int diskfs_shortcut_fifo = 1; +int diskfs_shortcut_ifsock = 1; -- cgit v1.2.3 From 085fc9bbf1ebf12a8fdf554df4625bd985e65ad6 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 9 Feb 1994 19:40:25 +0000 Subject: Formerly consts.c.~2~ --- ufs/consts.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ufs') diff --git a/ufs/consts.c b/ufs/consts.c index dd4d03de..54aa82de 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -size_t diskfs_dirstat_size = sizeof (struct dirstat); int diskfs_link_max = LINK_MAX; int diskfs_maxsymlinks = 8; int diskfs_shortcut_symlink = 1; -- cgit v1.2.3 From 3d8feee8b3c3180e4f98f351e7014d79d8403847 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 18:38:52 +0000 Subject: Initial revision --- ufs/devio.c | 74 +++++++++++++++++++++++ ufs/subr.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ufs/tables.c | 122 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 383 insertions(+) create mode 100644 ufs/devio.c create mode 100644 ufs/subr.c create mode 100644 ufs/tables.c (limited to 'ufs') diff --git a/ufs/devio.c b/ufs/devio.c new file mode 100644 index 00000000..957f2504 --- /dev/null +++ b/ufs/devio.c @@ -0,0 +1,74 @@ +/* Device input and output + Copyright (C) 1992, 1993, 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Michael I. Bushnell. */ + +#include "ufs.h" +#include +#include +#include +#include + +/* Write disk block ADDR with DATA of LEN bytes, waiting for completion. */ +error_t +dev_write_sync (daddr_t addr, + vm_address_t data, + long len) +{ + int foo; + assert (!readonly); + if (device_write (ufs_device, 0, addr, (io_buf_ptr_t) data, len, &foo) + || foo != len) + return EIO; + return 0; +} + +/* Write diskblock ADDR with DATA of LEN bytes; don't bother waiting + for completion. */ +error_t +dev_write (daddr_t addr, + vm_address_t data, + long len) +{ + int foo; + assert (!readonly); + if (device_write_request (ufs_device, MACH_PORT_NULL, 0, addr, + (io_buf_ptr_t) data, len, &foo) + || foo != len) + return EIO; + return 0; +} + +static int deverr; + +/* Read disk block ADDR; put the address of the data in DATA; read LEN + bytes. Always *DATA should be a full page no matter what. */ +error_t +dev_read_sync (daddr_t addr, + vm_address_t *data, + long len) +{ + int foo; + deverr = device_read (ufs_device, 0, addr, len, (io_buf_ptr_t *)data, + (u_int *)&foo); + if (deverr || foo != len) + return EIO; + return 0; +} + diff --git a/ufs/subr.c b/ufs/subr.c new file mode 100644 index 00000000..b61b09d6 --- /dev/null +++ b/ufs/subr.c @@ -0,0 +1,187 @@ +/* Miscellaneous map manipulation routines + Copyright (C) 1991, 1992, 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Slightly modified from UCB by Michael I. Bushnell. */ + +/* + * Copyright (c) 1982, 1986, 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution is only permitted until one year after the first shipment + * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and + * binary forms are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)ufs_subr.c 7.13 (Berkeley) 6/28/90 + */ + + +#include + +extern int around[9]; +extern int inside[9]; +extern u_char *fragtbl[]; + +/* + * Update the frsum fields to reflect addition or deletion + * of some frags. + */ +void +fragacct(int fragmap, + long fraglist[], + int cnt) +{ + int inblk; + int field, subfield; + int siz, pos; + + inblk = (int)(fragtbl[sblock->fs_frag][fragmap]) << 1; + fragmap <<= 1; + for (siz = 1; siz < sblock->fs_frag; siz++) { + if ((inblk & (1 << (siz + (sblock->fs_frag % NBBY)))) == 0) + continue; + field = around[siz]; + subfield = inside[siz]; + for (pos = siz; pos <= sblock->fs_frag; pos++) { + if ((fragmap & field) == subfield) { + fraglist[siz] += cnt; + pos += siz; + field <<= siz; + subfield <<= siz; + } + field <<= 1; + subfield <<= 1; + } + } +} + +/* + * block operations + * + * check if a block is available + */ +int +isblock(u_char *cp, + daddr_t h) +{ + u_char mask; + + switch ((int)sblock->fs_frag) { + case 8: + return (cp[h] == 0xff); + case 4: + mask = 0x0f << ((h & 0x1) << 2); + return ((cp[h >> 1] & mask) == mask); + case 2: + mask = 0x03 << ((h & 0x3) << 1); + return ((cp[h >> 2] & mask) == mask); + case 1: + mask = 0x01 << (h & 0x7); + return ((cp[h >> 3] & mask) == mask); + default: + assert (0); + } +} + +/* + * take a block out of the map + */ +void +clrblock(u_char *cp, + daddr_t h) +{ + + switch ((int)sblock->fs_frag) { + case 8: + cp[h] = 0; + return; + case 4: + cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); + return; + case 2: + cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); + return; + case 1: + cp[h >> 3] &= ~(0x01 << (h & 0x7)); + return; + default: + assert (0); + } +} + +/* + * put a block into the map + */ +void +setblock(u_char *cp, + daddr_t h) +{ + switch ((int)sblock->fs_frag) { + + case 8: + cp[h] = 0xff; + return; + case 4: + cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); + return; + case 2: + cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); + return; + case 1: + cp[h >> 3] |= (0x01 << (h & 0x7)); + return; + default: + assert (0); + } +} + +int +skpc(u_char mask, + u_int size, + u_char *cp) +{ + u_char *end = &cp[size]; + + while (cp < end && *cp == mask) + cp++; + return (end - cp); +} + +int +scanc(u_int size, + u_char *cp, + u_char table[], + u_char mask) +{ + register u_char *end = &cp[size]; + + while (cp < end && (table[*cp] & mask) == 0) + cp++; + return (end - cp); +} diff --git a/ufs/tables.c b/ufs/tables.c new file mode 100644 index 00000000..42badaed --- /dev/null +++ b/ufs/tables.c @@ -0,0 +1,122 @@ +/* Tables for fast computation */ +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. + * + * Redistribution is only permitted until one year after the first shipment + * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and + * binary forms are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)ufs_tables.c 7.4 (Berkeley) 6/28/90 + */ + +/* + * Bit patterns for identifying fragments in the block map + * used as ((map & around) == inside) + */ +int around[9] = { + 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff +}; +int inside[9] = { + 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe +}; + +/* + * Given a block map bit pattern, the frag tables tell whether a + * particular size fragment is available. + * + * used as: + * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] { + * at least one fragment of the indicated size is available + * } + * + * These tables are used by the scanc instruction on the VAX to + * quickly find an appropriate fragment. + */ +u_char fragtbl124[256] = { + 0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e, + 0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a, + 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, + 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, + 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, + 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, + 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, + 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, + 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, + 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, + 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, + 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, + 0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e, + 0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae, + 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, + 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, + 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, + 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, + 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, + 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, + 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, + 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, + 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, + 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, + 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, + 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, + 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, + 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, + 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, + 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, + 0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce, + 0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a, +}; + +u_char fragtbl8[256] = { + 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, + 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, + 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, + 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, + 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, + 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, + 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, + 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, + 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, + 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, + 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, + 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, + 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, + 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, + 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, + 0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40, + 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, + 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, + 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, + 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, + 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, + 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, + 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, + 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, + 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, + 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12, + 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, + 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c, + 0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c, + 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, +}; + +/* + * The actual fragtbl array. + */ +u_char *fragtbl[MAXFRAG + 1] = { + 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8, +}; -- cgit v1.2.3 From 73b5d5fec8e66debd74b963310dc635b9e995e14 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 18:39:04 +0000 Subject: Formerly devio.c.~2~ --- ufs/devio.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'ufs') diff --git a/ufs/devio.c b/ufs/devio.c index 957f2504..81423d73 100644 --- a/ufs/devio.c +++ b/ufs/devio.c @@ -19,12 +19,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Written by Michael I. Bushnell. */ -#include "ufs.h" -#include -#include -#include -#include - /* Write disk block ADDR with DATA of LEN bytes, waiting for completion. */ error_t dev_write_sync (daddr_t addr, -- cgit v1.2.3 From e78eb00a4ec04c666c505cf674d58b1f492b1ac6 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 19:19:12 +0000 Subject: Initial revision --- ufs/Makefile | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 ufs/Makefile (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile new file mode 100644 index 00000000..11b82256 --- /dev/null +++ b/ufs/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (C) 1994 Free Software Foundation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +dir := ufs + +include ../Makeconf + -- cgit v1.2.3 From 5c0128e3a3c729bc4d333967575ab95503d142ea Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 20:28:20 +0000 Subject: Initial revision --- ufs/dinode.h | 122 ++++++++++++++++ ufs/fs.h | 454 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 576 insertions(+) create mode 100644 ufs/dinode.h create mode 100644 ufs/fs.h (limited to 'ufs') diff --git a/ufs/dinode.h b/ufs/dinode.h new file mode 100644 index 00000000..dfde2050 --- /dev/null +++ b/ufs/dinode.h @@ -0,0 +1,122 @@ +/* Format of an inode on disk + Copyright (C) 1991, 1993 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Modified from UCB by Michael I. Bushnell. */ + +/* + * Copyright (c) 1982, 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution is only permitted until one year after the first shipment + * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and + * binary forms are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)dinode.h 7.9 (Berkeley) 6/28/90 + */ + +/* + * This structure defines the on-disk format of an inode. + */ + +#define NDADDR 12 /* direct addresses in inode */ +#define NIADDR 3 /* indirect addresses in inode */ + +/* Indexes into di_ib */ +#define INDIR_SINGLE 0 +#define INDIR_DOUBLE 1 +#define INDIR_TRIPLE 2 /* NOT SUPPORTED */ + +struct dinode { + u_short di_model; /* 0: mode and type of file (low bits) */ + nlink_t di_nlink; /* 2: number of links to file */ + u_short di_uidl; /* 4: owner's user id (low bits) */ + u_short di_gidl; /* 6: owner's group id (low bits) */ + u_quad di_qsize; /* 8: number of bytes in file */ + time_t di_atime; /* 16: time last accessed */ + long di_atusec; + time_t di_mtime; /* 24: time last modified */ + long di_mtusec; + time_t di_ctime; /* 32: last time inode changed */ + long di_ctusec; + daddr_t di_db[NDADDR]; /* 40: disk block addresses */ + daddr_t di_ib[NIADDR]; /* 88: indirect blocks */ + long di_flags; /* 100: status, currently unused */ + long di_blocks; /* 104: blocks actually held */ + long di_gen; /* 108: generation number */ + long di_trans; /* 112: filesystem tranlator */ + uid_t di_author; /* 116: author id */ + u_short di_uidh; /* 120: user id (high bits) */ + u_short di_gidh; /* 122: group id (high bits) */ + u_short di_modeh; /* 124: mode (high bits) */ + short di_spare; /* 126: reserved, currently unused */ +}; + +#define DI_UID(di) ((di)->di_uidl | ((int)(di)->di_uidh << 16)) +#define DI_GID(di) ((di)->di_gidl | ((int)(di)->di_gidh << 16)) +#define DI_MODE(di) ((di)->di_model | ((int)(di)->di_modeh << 16)) + +#define LINK_MAX 32767 /* limited by width of nlink_t == 16 bits */ + +#if BYTE_ORDER == LITTLE_ENDIAN || defined(tahoe) /* ugh! -- must be fixed */ +#define di_size di_qsize.val[0] +#else /* BYTE_ORDER == BIG_ENDIAN */ +#define di_size di_qsize.val[1] +#endif +#define di_rdev di_db[0] + +/* file modes -- these are known to match appropriate values in gnu/stat.h */ +#define IFMT 000000170000 /* type of file */ +#define IFIFO 000000010000 /* named pipe (fifo) */ +#define IFCHR 000000020000 /* character special */ +#define IFDIR 000000040000 /* directory */ +#define IFBLK 000000060000 /* block special */ +#define IFREG 000000100000 /* regular */ +#define IFLNK 000000120000 /* symbolic link */ +#define IFSOCK 000000140000 /* socket */ + +#define ISPEC 000000607000 /* special user-changeable bits */ +#define INOCACHE 000000400000 /* don't cache contents */ +#define IUSEUNK 000000200000 /* use IUNK in pref to IKNOWN */ +#define ISUID 000000004000 /* set user id on execution */ +#define ISGID 000000002000 /* set group id on execution */ +#define ISVTX 000000001000 /* caching preference / append only dir */ + +/* masks for various sets of permissions: */ +#define IOWNER 000000000700 /* owner of file */ +#define IGROUP 000000000070 /* group of file */ +#define IKNOWN 000000000007 /* anyone who possesses a uid */ +#define IUNKNOWN 000007000000 /* anyone who doesn't possess a uid */ + +#define ISPARE 037770000000 /* unused (yet) */ + +#define IREAD 0400 /* read, write, execute permissions */ +#define IWRITE 0200 +#define IEXEC 0100 + diff --git a/ufs/fs.h b/ufs/fs.h new file mode 100644 index 00000000..c1dd5681 --- /dev/null +++ b/ufs/fs.h @@ -0,0 +1,454 @@ +/* Format of a filesystem on disk (superblock and cylinder groups) + Copyright (C) 1991, 1993 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Modified from UCB by Michael I. Bushnell. */ + +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. + * + * Redistribution is only permitted until one year after the first shipment + * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and + * binary forms are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)fs.h 7.10 (Berkeley) 6/28/90 + */ + +/* + * Each disk drive contains some number of file systems. + * A file system consists of a number of cylinder groups. + * Each cylinder group has inodes and data. + * + * A file system is described by its super-block, which in turn + * describes the cylinder groups. The super-block is critical + * data and is replicated in each cylinder group to protect against + * catastrophic loss. This is done at `newfs' time and the critical + * super-block data does not change, so the copies need not be + * referenced further unless disaster strikes. + * + * For file system fs, the offsets of the various blocks of interest + * are given in the super block as: + * [fs->fs_sblkno] Super-block + * [fs->fs_cblkno] Cylinder group block + * [fs->fs_iblkno] Inode blocks + * [fs->fs_dblkno] Data blocks + * The beginning of cylinder group cg in fs, is given by + * the ``cgbase(fs, cg)'' macro. + * + * The first boot and super blocks are given in absolute disk addresses. + * The byte-offset forms are preferred, as they don't imply a sector size. + */ +#define BBSIZE 8192 +#define SBSIZE 8192 +#define BBOFF ((off_t)(0)) +#define SBOFF ((off_t)(BBOFF + BBSIZE)) +#define BBLOCK ((daddr_t)(0)) +#define SBLOCK ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE)) + +/* + * Addresses stored in inodes are capable of addressing fragments + * of `blocks'. File system blocks of at most size MAXBSIZE can + * be optionally broken into 2, 4, or 8 pieces, each of which is + * addressible; these pieces may be DEV_BSIZE, or some multiple of + * a DEV_BSIZE unit. + * + * Large files consist of exclusively large data blocks. To avoid + * undue wasted disk space, the last data block of a small file may be + * allocated as only as many fragments of a large block as are + * necessary. The file system format retains only a single pointer + * to such a fragment, which is a piece of a single large block that + * has been divided. The size of such a fragment is determinable from + * information in the inode, using the ``blksize(fs, ip, lbn)'' macro. + * + * The file system records space availability at the fragment level; + * to determine block availability, aligned fragments are examined. + * + * The root inode is the root of the file system. + * Inode 0 can't be used for normal purposes and + * historically bad blocks were linked to inode 1, + * thus the root inode is 2. (inode 1 is no longer used for + * this purpose, however numerous dump tapes make this + * assumption, so we are stuck with it) + */ +#define ROOTINO ((ino_t)2) /* i number of all roots */ + +/* + * MINBSIZE is the smallest allowable block size. + * In order to insure that it is possible to create files of size + * 2^32 with only two levels of indirection, MINBSIZE is set to 4096. + * MINBSIZE must be big enough to hold a cylinder group block, + * thus changes to (struct cg) must keep its size within MINBSIZE. + * Note that super blocks are always of size SBSIZE, + * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE. + */ +#define MINBSIZE 4096 + +/* + * The path name on which the file system is mounted is maintained + * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in + * the super block for this name. + * The limit on the amount of summary information per file system + * is defined by MAXCSBUFS. It is currently parameterized for a + * maximum of two million cylinders. + */ +#define MAXMNTLEN 512 +#define MAXCSBUFS 32 +#define MAXFRAG 8 + +/* + * Per cylinder group information; summarized in blocks allocated + * from first cylinder group data blocks. These blocks have to be + * read in from fs_csaddr (size fs_cssize) in addition to the + * super block. + * + * N.B. sizeof(struct csum) must be a power of two in order for + * the ``fs_cs'' macro to work (see below). + */ +struct csum { + long cs_ndir; /* number of directories */ + long cs_nbfree; /* number of free blocks */ + long cs_nifree; /* number of free inodes */ + long cs_nffree; /* number of free frags */ +}; + +/* + * Super block for a file system. + */ +#define FS_MAGIC 0x011954 +#define FSOKAY 0x7c269d38 +struct fs +{ + struct fs *fs_link; /* linked list of file systems */ + struct fs *fs_rlink; /* used for incore super blocks */ + daddr_t fs_sblkno; /* addr of super-block in filesys */ + daddr_t fs_cblkno; /* offset of cyl-block in filesys */ + daddr_t fs_iblkno; /* offset of inode-blocks in filesys */ + daddr_t fs_dblkno; /* offset of first data after cg */ + long fs_cgoffset; /* cylinder group offset in cylinder */ + long fs_cgmask; /* used to calc mod fs_ntrak */ + long fs_time; /* last time written */ + long fs_size; /* number of blocks in fs */ + long fs_dsize; /* number of data blocks in fs */ + long fs_ncg; /* number of cylinder groups */ + long fs_bsize; /* size of basic blocks in fs */ + long fs_fsize; /* size of frag blocks in fs */ + long fs_frag; /* number of frags in a block in fs */ +/* these are configuration parameters */ + long fs_minfree; /* minimum percentage of free blocks */ + long fs_rotdelay; /* num of ms for optimal next block */ + long fs_rps; /* disk revolutions per second */ +/* these fields can be computed from the others */ + long fs_bmask; /* ``blkoff'' calc of blk offsets */ + long fs_fmask; /* ``fragoff'' calc of frag offsets */ + long fs_bshift; /* ``lblkno'' calc of logical blkno */ + long fs_fshift; /* ``numfrags'' calc number of frags */ +/* these are configuration parameters */ + long fs_maxcontig; /* max number of contiguous blks */ + long fs_maxbpg; /* max number of blks per cyl group */ +/* these fields can be computed from the others */ + long fs_fragshift; /* block to frag shift */ + long fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ + long fs_sbsize; /* actual size of super block */ + long fs_csmask; /* csum block offset */ + long fs_csshift; /* csum block number */ + long fs_nindir; /* value of NINDIR */ + long fs_inopb; /* value of INOPB */ + long fs_nspf; /* value of NSPF */ +/* yet another configuration parameter */ + long fs_optim; /* optimization preference, see below */ +/* these fields are derived from the hardware */ + long fs_npsect; /* # sectors/track including spares */ + long fs_interleave; /* hardware sector interleave */ + long fs_trackskew; /* sector 0 skew, per track */ + long fs_headswitch; /* head switch time, usec */ + long fs_trkseek; /* track-to-track seek, usec */ +/* sizes determined by number of cylinder groups and their sizes */ + daddr_t fs_csaddr; /* blk addr of cyl grp summary area */ + long fs_cssize; /* size of cyl grp summary area */ + long fs_cgsize; /* cylinder group size */ +/* these fields are derived from the hardware */ + long fs_ntrak; /* tracks per cylinder */ + long fs_nsect; /* sectors per track */ + long fs_spc; /* sectors per cylinder */ +/* this comes from the disk driver partitioning */ + long fs_ncyl; /* cylinders in file system */ +/* these fields can be computed from the others */ + long fs_cpg; /* cylinders per group */ + long fs_ipg; /* inodes per group */ + long fs_fpg; /* blocks per group * fs_frag */ +/* this data must be re-computed after crashes */ + struct csum fs_cstotal; /* cylinder summary information */ +/* these fields are cleared at mount time */ + char fs_fmod; /* super block modified flag */ + char fs_clean; /* file system is clean flag */ + char fs_ronly; /* mounted read-only flag */ + char fs_flags; /* currently unused flag */ + char fs_fsmnt[MAXMNTLEN]; /* name mounted on */ +/* these fields retain the current block allocation info */ + long fs_cgrotor; /* last cg searched */ + struct csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */ + long fs_cpc; /* cyl per cycle in postbl */ + short fs_opostbl[16][8]; /* old rotation block list head */ + long fs_sparecon[55]; /* reserved for future constants */ + long fs_state; /* validate fs_clean field */ + quad fs_qbmask; /* ~fs_bmask - for use with quad size */ + quad fs_qfmask; /* ~fs_fmask - for use with quad size */ + long fs_postblformat; /* format of positional layout tables */ + long fs_nrpos; /* number of rotaional positions */ + long fs_postbloff; /* (short) rotation block list head */ + long fs_rotbloff; /* (u_char) blocks for each rotation */ + long fs_magic; /* magic number */ + unsigned char fs_space[1]; /* list of blocks for each rotation */ +/* actually longer */ +}; +/* + * Preference for optimization. + */ +#define FS_OPTTIME 0 /* minimize allocation time */ +#define FS_OPTSPACE 1 /* minimize disk fragmentation */ + +/* + * Rotational layout table format types + */ +#define FS_42POSTBLFMT -1 /* 4.2BSD rotational table format */ +#define FS_DYNAMICPOSTBLFMT 1 /* dynamic rotational table format */ +/* + * Macros for access to superblock array structures + */ +#define fs_postbl(cylno) \ + ((sblock->fs_postblformat == FS_42POSTBLFMT) \ + ? (sblock->fs_opostbl[cylno]) \ + : ((short *)((char *)sblock + sblock->fs_postbloff) \ + + (cylno) * sblock->fs_nrpos)) +#define fs_rotbl \ + ((sblock->fs_postblformat == FS_42POSTBLFMT) \ + ? (sblock->fs_space) \ + : ((unsigned char *)((char *)sblock + sblock->fs_rotbloff))) + +/* + * Convert cylinder group to base address of its global summary info. + * + * N.B. This macro assumes that sizeof(struct csum) is a power of two. + */ +#define fs_cs(indx) \ + fs_csp[(indx) >> sblock->fs_csshift][(indx) & ~sblock->fs_csmask] + +/* + * Cylinder group block for a file system. + */ +#define CG_MAGIC 0x090255 +struct cg { + struct cg *cg_link; /* linked list of cyl groups */ + long cg_magic; /* magic number */ + long cg_time; /* time last written */ + long cg_cgx; /* we are the cgx'th cylinder group */ + short cg_ncyl; /* number of cyl's this cg */ + short cg_niblk; /* number of inode blocks this cg */ + long cg_ndblk; /* number of data blocks this cg */ + struct csum cg_cs; /* cylinder summary information */ + long cg_rotor; /* position of last used block */ + long cg_frotor; /* position of last used frag */ + long cg_irotor; /* position of last used inode */ + long cg_frsum[MAXFRAG]; /* counts of available frags */ + long cg_btotoff; /* (long) block totals per cylinder */ + long cg_boff; /* (short) free block positions */ + long cg_iusedoff; /* (char) used inode map */ + long cg_freeoff; /* (u_char) free block map */ + long cg_nextfreeoff; /* (u_char) next available space */ + long cg_sparecon[16]; /* reserved for future use */ + unsigned char cg_space[1]; /* space for cylinder group maps */ +/* actually longer */ +}; +/* + * Macros for access to cylinder group array structures + */ +#define cg_blktot(cgp) \ + (((cgp)->cg_magic != CG_MAGIC) \ + ? (((struct ocg *)(cgp))->cg_btot) \ + : ((long *)((char *)(cgp) + (cgp)->cg_btotoff))) +#define cg_blks(cgp, cylno) \ + (((cgp)->cg_magic != CG_MAGIC) \ + ? (((struct ocg *)(cgp))->cg_b[cylno]) \ + : ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * sblock->fs_nrpos)) +#define cg_inosused(cgp) \ + (((cgp)->cg_magic != CG_MAGIC) \ + ? (((struct ocg *)(cgp))->cg_iused) \ + : ((char *)((char *)(cgp) + (cgp)->cg_iusedoff))) +#define cg_blksfree(cgp) \ + (((cgp)->cg_magic != CG_MAGIC) \ + ? (((struct ocg *)(cgp))->cg_free) \ + : ((unsigned char *)((char *)(cgp) + (cgp)->cg_freeoff))) +#define cg_chkmagic(cgp) \ + ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC) + +/* + * The following structure is defined + * for compatibility with old file systems. + */ +struct ocg { + struct ocg *cg_link; /* linked list of cyl groups */ + struct ocg *cg_rlink; /* used for incore cyl groups */ + long cg_time; /* time last written */ + long cg_cgx; /* we are the cgx'th cylinder group */ + short cg_ncyl; /* number of cyl's this cg */ + short cg_niblk; /* number of inode blocks this cg */ + long cg_ndblk; /* number of data blocks this cg */ + struct csum cg_cs; /* cylinder summary information */ + long cg_rotor; /* position of last used block */ + long cg_frotor; /* position of last used frag */ + long cg_irotor; /* position of last used inode */ + long cg_frsum[8]; /* counts of available frags */ + long cg_btot[32]; /* block totals per cylinder */ + short cg_b[32][8]; /* positions of free blocks */ + char cg_iused[256]; /* used inode map */ + long cg_magic; /* magic number */ + unsigned char cg_free[1]; /* free block map */ +/* actually longer */ +}; + +/* + * Turn file system block numbers into disk block addresses. + * This maps file system blocks to device size blocks. + */ +#define fsbtodb(b) ((b) << sblock->fs_fsbtodb) +#define dbtofsb(b) ((b) >> sblock->fs_fsbtodb) + +/* + * Cylinder group macros to locate things in cylinder groups. + * They calc file system addresses of cylinder group data structures. + */ +#define cgbase(c) ((daddr_t)(sblock->fs_fpg * (c))) +#define cgstart(c) \ + (cgbase(c) + sblock->fs_cgoffset * ((c) & ~(sblock->fs_cgmask))) +#define cgsblock(c) (cgstart(c) + sblock->fs_sblkno) /* super blk */ +#define cgtod(c) (cgstart(c) + sblock->fs_cblkno) /* cg block */ +#define cgimin(c) (cgstart(c) + sblock->fs_iblkno) /* inode blk */ +#define cgdmin(c) (cgstart(c) + sblock->fs_dblkno) /* 1st data */ + +/* + * Macros for handling inode numbers: + * inode number to file system block offset. + * inode number to cylinder group number. + * inode number to file system block address. + */ +#define itoo(x) ((x) % INOPB) +#define itog(x) ((x) / sblock->fs_ipg) +#define itod(x) \ + ((daddr_t)(cgimin(itog(x)) + \ + (blkstofrags((((x) % sblock->fs_ipg) / INOPB))))) + +/* + * Give cylinder group number for a file system block. + * Give cylinder group block number for a file system block. + */ +#define dtog(d) ((d) / sblock->fs_fpg) +#define dtogd(d) ((d) % sblock->fs_fpg) + +/* + * Extract the bits for a block from a map. + * Compute the cylinder and rotational position of a cyl block addr. + */ +#define blkmap(map, loc) \ + (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - sblock->fs_frag))) +#define cbtocylno(bno) \ + ((bno) * NSPF / sblock->fs_spc) +#define cbtorpos(bno) \ + (((bno) * NSPF % sblock->fs_spc / sblock->fs_nsect * sblock->fs_trackskew + \ + (bno) * NSPF % sblock->fs_spc % sblock->fs_nsect * sblock->fs_interleave) % \ + sblock->fs_nsect * sblock->fs_nrpos / sblock->fs_npsect) + +/* + * The following macros optimize certain frequently calculated + * quantities by using shifts and masks in place of divisions + * modulos and multiplications. + */ +#define blkoff(loc) /* calculates (loc % fs->fs_bsize) */ \ + ((loc) & ~sblock->fs_bmask) +#define fragoff(loc) /* calculates (loc % fs->fs_fsize) */ \ + ((loc) & ~sblock->fs_fmask) +#define lblktosize(blk) /* calculates (blk * fs->fs_bsize) */ \ + ((blk) << sblock->fs_bshift) +#define lblkno(loc) /* calculates (loc / fs->fs_bsize) */ \ + ((loc) >> sblock->fs_bshift) +#define numfrags(loc) /* calculates (loc / fs->fs_fsize) */ \ + ((loc) >> sblock->fs_fshift) +#define blkroundup(size) /* calculates roundup(size, fs->fs_bsize) */ \ + (((size) + sblock->fs_bsize - 1) & sblock->fs_bmask) +#define fragroundup(size) /* calculates roundup(size, fs->fs_fsize) */ \ + (((size) + sblock->fs_fsize - 1) & sblock->fs_fmask) +#define fragstoblks(frags) /* calculates (frags / fs->fs_frag) */ \ + ((frags) >> sblock->fs_fragshift) +#define blkstofrags(blks) /* calculates (blks * fs->fs_frag) */ \ + ((blks) << sblock->fs_fragshift) +#define fragnum(fsb) /* calculates (fsb % fs->fs_frag) */ \ + ((fsb) & (sblock->fs_frag - 1)) +#define blknum(fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \ + ((fsb) &~ (sblock->fs_frag - 1)) + +/* + * Determine the number of available frags given a + * percentage to hold in reserve + */ +#define freespace(percentreserved) \ + (blkstofrags(sblock->fs_cstotal.cs_nbfree) + \ + sblock->fs_cstotal.cs_nffree - (sblock->fs_dsize * (percentreserved) / 100)) + +/* + * Determining the size of a file block in the file system. + */ +#define blksize(ip, lbn) \ + (((lbn) >= NDADDR || (ip)->i_allocsize >= ((lbn) + 1) << sblock->fs_bshift) \ + ? sblock->fs_bsize \ + : (fragroundup(blkoff((ip)->i_allocsize)))) +#define dblksize(dip, lbn) \ + (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << sblock->fs_bshift) \ + ? sblock->fs_bsize \ + : (fragroundup(blkoff((dip)->di_size)))) + +/* + * Number of disk sectors per block; assumes DEV_BSIZE byte sector size. + */ +#define NSPB (sblock->fs_nspf << sblock->fs_fragshift) +#define NSPF (sblock->fs_nspf) + +/* + * INOPB is the number of inodes in a secondary storage block. + */ +#define INOPB (sblock->fs_inopb) +#define INOPF (sblock->fs_inopb >> sblock->fs_fragshift) + +/* + * NINDIR is the number of indirects in a file system block. + */ +#define NINDIR (sblock->fs_nindir) + +#ifdef KERNEL +struct fs *getfs(); +#endif -- cgit v1.2.3 From cc72a838ef149364e787a804fb86d35bb6a2d4cb Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 20:49:26 +0000 Subject: Formerly consts.c.~3~ --- ufs/consts.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ufs') diff --git a/ufs/consts.c b/ufs/consts.c index 54aa82de..dd63b410 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -15,6 +15,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "ufs.h" +#include "dinode.h" + int diskfs_link_max = LINK_MAX; int diskfs_maxsymlinks = 8; int diskfs_shortcut_symlink = 1; -- cgit v1.2.3 From 4fc263fd16e28c759c6e0967a30ca02b97e30257 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 22:05:14 +0000 Subject: entered into RCS --- ufs/devio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/devio.c b/ufs/devio.c index 81423d73..2e5cc332 100644 --- a/ufs/devio.c +++ b/ufs/devio.c @@ -19,6 +19,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Written by Michael I. Bushnell. */ +#include "ufs.h" +#include +#include + /* Write disk block ADDR with DATA of LEN bytes, waiting for completion. */ error_t dev_write_sync (daddr_t addr, @@ -26,7 +30,7 @@ dev_write_sync (daddr_t addr, long len) { int foo; - assert (!readonly); + assert (!diskfs_readonly); if (device_write (ufs_device, 0, addr, (io_buf_ptr_t) data, len, &foo) || foo != len) return EIO; @@ -40,11 +44,9 @@ dev_write (daddr_t addr, vm_address_t data, long len) { - int foo; - assert (!readonly); + assert (!diskfs_readonly); if (device_write_request (ufs_device, MACH_PORT_NULL, 0, addr, - (io_buf_ptr_t) data, len, &foo) - || foo != len) + (io_buf_ptr_t) data, len)) return EIO; return 0; } -- cgit v1.2.3 From c2e9f68ae30d9f4e73931fc3d62aaca65a4fb812 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 22:13:51 +0000 Subject: Formerly hyper.c.~3~ --- ufs/hyper.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 2793985e..dfe76bcf 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -15,6 +15,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "ufs.h" +#include "fs.h" +#include void get_hypermetadata (void) @@ -46,12 +49,12 @@ get_hypermetadata (void) void diskfs_set_hypermetadata (int wait, int clean) { - error_t (*writefn) (daddr_t, vm_address_t, vm_size_t); + error_t (*writefn) (daddr_t, vm_address_t, long); writefn = (wait ? dev_write_sync : dev_write); (*writefn)(fsbtodb (sblock->fs_csaddr), (vm_address_t) csum, sblock->fs_fsize * howmany (sblock->fs_cssize, - sblock->fs_fssize)); + sblock->fs_fsize)); if (clean) sblock->fs_clean = 1; -- cgit v1.2.3 From c7ad3c1c1cb38db62050ccb04914d1e34b1d33f7 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 22:25:42 +0000 Subject: Formerly fs.h.~2~ --- ufs/fs.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/fs.h b/ufs/fs.h index c1dd5681..2efc6910 100644 --- a/ufs/fs.h +++ b/ufs/fs.h @@ -1,5 +1,5 @@ /* Format of a filesystem on disk (superblock and cylinder groups) - Copyright (C) 1991, 1993 Free Software Foundation + Copyright (C) 1991, 1993, 1994 Free Software Foundation This file is part of the GNU Hurd. @@ -423,10 +423,10 @@ struct ocg { /* * Determining the size of a file block in the file system. */ -#define blksize(ip, lbn) \ - (((lbn) >= NDADDR || (ip)->i_allocsize >= ((lbn) + 1) << sblock->fs_bshift) \ +#define blksize(np, lbn) \ + (((lbn) >= NDADDR || (np)->allocsize >= ((lbn) + 1) << sblock->fs_bshift) \ ? sblock->fs_bsize \ - : (fragroundup(blkoff((ip)->i_allocsize)))) + : (fragroundup(blkoff((np)->allocsize)))) #define dblksize(dip, lbn) \ (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << sblock->fs_bshift) \ ? sblock->fs_bsize \ -- cgit v1.2.3 From 8107f1ff5809374655541190c1ccc1cb05ba12ef Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 22:34:41 +0000 Subject: Formerly subr.c.~2~ --- ufs/subr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/subr.c b/ufs/subr.c index b61b09d6..25990835 100644 --- a/ufs/subr.c +++ b/ufs/subr.c @@ -41,8 +41,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * @(#)ufs_subr.c 7.13 (Berkeley) 6/28/90 */ +#include "ufs.h" +#include "fs.h" -#include extern int around[9]; extern int inside[9]; -- cgit v1.2.3 From ffcb07b0b67eb70cdcd62a232d75bde7dd29e99e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Feb 1994 22:36:44 +0000 Subject: Formerly Makefile.~2~ --- ufs/Makefile | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 11b82256..cf4d2be1 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -19,3 +19,36 @@ dir := ufs include ../Makeconf +SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ + subr.c tables.c + +DISTFILES=$(SRCS) ufs.h Makefile + +OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o + +LIBS= $(libdiskfs) $(libpager) $(libioserver) $(libfshelp) \ + $(libports) $(libthreads) + +all: ufs + +ufs: $(OBJS) $(LIBS) + $(link) + +exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs + ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o + +$(OBJS): ufs.h +$(OBJS): $(addprefix $(headers)/hurd/,diskfs.h pager.h ioserver.h \ + fshelp.h ports.h) +alloc.o: fs.h dinode.h +consts.o: dinode.h +dir.o: dir.h +hyper.o: fs.h +inode.o: dinode.h fs.h +main.o: fs.h +pager.o: fs.h dinode.h +subr.o: fs.h +tables.o: fs.h + +$(foreach dir,mkbootfs exec,../$(dir)/%): FORCE + $(MAKE) -C $(@D) $(@F) -- cgit v1.2.3 From 50cefe1c1ec69dee59590f666c0e34d7cbbe505c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 11 Feb 1994 20:52:12 +0000 Subject: Formerly Makefile.~3~ --- ufs/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index cf4d2be1..90e567b2 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -26,8 +26,9 @@ DISTFILES=$(SRCS) ufs.h Makefile OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o -LIBS= $(libdiskfs) $(libpager) $(libioserver) $(libfshelp) \ - $(libports) $(libthreads) +LIBS= $(libdiskfs) $(libpager) $(libioserver) $(libports) $(libfshelp) \ + $(libthreads) +EXTRALIBS=$(libdiskfs) all: ufs -- cgit v1.2.3 From b4b43fec2f277ef5d9312ff4fcba3ca1f26df41f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 14 Feb 1994 22:57:09 +0000 Subject: Formerly Makefile.~4~ --- ufs/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 90e567b2..3e235668 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -20,15 +20,16 @@ dir := ufs include ../Makeconf SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ - subr.c tables.c + sizes.c subr.c tables.c -DISTFILES=$(SRCS) ufs.h Makefile +DISTFILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o +PRELIBS = $(libdiskfs) $(libports) LIBS= $(libdiskfs) $(libpager) $(libioserver) $(libports) $(libfshelp) \ $(libthreads) -EXTRALIBS=$(libdiskfs) +POSTLIBS=$(libdiskfs) all: ufs @@ -48,6 +49,7 @@ hyper.o: fs.h inode.o: dinode.h fs.h main.o: fs.h pager.o: fs.h dinode.h +sizes.o: fs.h dinode.h subr.o: fs.h tables.o: fs.h -- cgit v1.2.3 From 138ff83c86dec85093e68b075b13e15ea742916a Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 15 Feb 1994 17:37:52 +0000 Subject: Formerly Makefile.~5~ --- ufs/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 3e235668..7d767c79 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -26,16 +26,16 @@ DISTFILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o -PRELIBS = $(libdiskfs) $(libports) -LIBS= $(libdiskfs) $(libpager) $(libioserver) $(libports) $(libfshelp) \ - $(libthreads) -POSTLIBS=$(libdiskfs) +LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ + $(libports) $(libfshelp) $(libthreads) $(libdiskfs) all: ufs -ufs: $(OBJS) $(LIBS) +ufs: $(OBJS) $(link) +ufs: $(LIBS) + exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o -- cgit v1.2.3 From 773e0f944fc77a8dbc30a1ebda337c8b67a8e8f3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 15 Feb 1994 17:48:00 +0000 Subject: Formerly Makefile.~6~ --- ufs/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 7d767c79..97a48df3 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -27,15 +27,13 @@ DISTFILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ - $(libports) $(libfshelp) $(libthreads) $(libdiskfs) + $(libfshelp) $(libdiskfs) $(libthreads) all: ufs -ufs: $(OBJS) +ufs: $(OBJS) $(LIBS) $(link) -ufs: $(LIBS) - exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o -- cgit v1.2.3 From dd6e2d59aa6fe10fec7f7cc642a4570d6e7355f8 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 15 Feb 1994 17:59:41 +0000 Subject: Formerly consts.c.~4~ --- ufs/consts.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/consts.c b/ufs/consts.c index dd63b410..0004230f 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -25,3 +25,7 @@ int diskfs_shortcut_chrdev = 1; int diskfs_shortcut_blkdev = 1; int diskfs_shortcut_fifo = 1; int diskfs_shortcut_ifsock = 1; +char *diskfs_server_name = "ufs"; +int diskfs_major_version = 0; +int diskfs_minor_version = 0; +int diskfs_edit_version = 0; -- cgit v1.2.3 From 1d1c5649b56d3a32400fa81cd3ea70ee5f119812 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 16 Feb 1994 17:42:47 +0000 Subject: Formerly Makefile.~7~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 97a48df3..284befb9 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -27,7 +27,7 @@ DISTFILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ - $(libfshelp) $(libdiskfs) $(libthreads) + $(libfshelp) $(libdiskfs) $(libthreads) $(libports) all: ufs -- cgit v1.2.3 From ac3b794b9a8dadbdae074fd4b56df8d0330a91b0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 28 Feb 1994 23:30:11 +0000 Subject: Formerly Makefile.~8~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 284befb9..d89b75b8 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -22,7 +22,7 @@ include ../Makeconf SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c -DISTFILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h +DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o -- cgit v1.2.3 From ba27e1d6005e62917e0b9f2e17f329a10c6cf335 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 1 Mar 1994 19:07:29 +0000 Subject: Formerly Makefile.~9~ --- ufs/Makefile | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index d89b75b8..d718e390 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -1,41 +1,4 @@ -# -# Copyright (C) 1994 Free Software Foundation -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2, or (at -# your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -dir := ufs - -include ../Makeconf - -SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ - sizes.c subr.c tables.c - -DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h - -OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o - -LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ - $(libfshelp) $(libdiskfs) $(libthreads) $(libports) - -all: ufs - -ufs: $(OBJS) $(LIBS) - $(link) - -exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs - ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o + rm -f *.o ufs $(OBJS): ufs.h $(OBJS): $(addprefix $(headers)/hurd/,diskfs.h pager.h ioserver.h \ -- cgit v1.2.3 From ab0a73bb86ebfee4404d436aa05a649292435b4f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 1 Mar 1994 19:11:17 +0000 Subject: Formerly Makefile.~10~ --- ufs/Makefile | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index d718e390..160e98f4 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -1,3 +1,43 @@ + +# Copyright (C) 1994 Free Software Foundation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +dir := ufs + +include ../Makeconf + +SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ + sizes.c subr.c tables.c + +DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h + +OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o + +LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ + $(libfshelp) $(libdiskfs) $(libthreads) $(libports) + +all: ufs + +ufs: $(OBJS) $(LIBS) + $(link) + +exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs + ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o + +clean: rm -f *.o ufs $(OBJS): ufs.h -- cgit v1.2.3 From 08f49203ca7a559f4a784e2bf1dc77d9c536a8d9 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 2 Mar 1994 20:46:41 +0000 Subject: Formerly Makefile.~11~ --- ufs/Makefile | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 160e98f4..2676862e 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -26,8 +26,9 @@ DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o -LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ - $(libfshelp) $(libdiskfs) $(libthreads) $(libports) +LIBS = $(hurdinst)/lib/libdiskfscombined.a $(libthreads) + +LIBPARTS = $(libdiskfs) $(libports) $(libpager) $(libioserver) $(libfshelp) all: ufs @@ -54,5 +55,16 @@ sizes.o: fs.h dinode.h subr.o: fs.h tables.o: fs.h +$(hurdinst)/lib/libdiskfscombined.a: $(LIBPARTS) + -mkdir foo + cd foo; $(AR) x $(libdiskfs) + cd foo; $(AR) x $(libports) + cd foo; $(AR) x $(libpager) + cd foo; $(AR) x $(libioserver) + cd foo; $(AR) x $(libfshelp) + cd foo; $(AR) cr $(hurdinst)/lib/libdiskfscombined.a * + rm -rf foo + $(RANLIB) $(hurdinst)/lib/libdiskfscombined.a + $(foreach dir,mkbootfs exec,../$(dir)/%): FORCE $(MAKE) -C $(@D) $(@F) -- cgit v1.2.3 From 64fdd3a5cfdc7b8796e7ee2bc5ca2d883ddc6c95 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 4 Mar 1994 21:29:58 +0000 Subject: Formerly Makefile.~13~ --- ufs/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 2676862e..313bd838 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -26,7 +26,9 @@ DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o -LIBS = $(hurdinst)/lib/libdiskfscombined.a $(libthreads) +#LIBS = $(hurdinst)/lib/libdiskfscombined.a $(libthreads) +LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ + $(libfshelp) $(libdiskfs) $(libthreads) $(libports) LIBPARTS = $(libdiskfs) $(libports) $(libpager) $(libioserver) $(libfshelp) -- cgit v1.2.3 From d035d62ceaae7f05fdceb36870654842661a4071 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 8 Mar 1994 19:42:10 +0000 Subject: Formerly Makefile.~14~ --- ufs/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 313bd838..03628376 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -19,12 +19,14 @@ dir := ufs include ../Makeconf +VPATH=.:../machine + SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h -OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o +OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o boot_machdep.o #LIBS = $(hurdinst)/lib/libdiskfscombined.a $(libthreads) LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ -- cgit v1.2.3 From 2251c0527db1bb2230d7af971b3671cc749cd696 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 8 Mar 1994 23:28:32 +0000 Subject: Formerly Makefile.~15~ --- ufs/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 03628376..b6b006f6 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -40,6 +40,7 @@ ufs: $(OBJS) $(LIBS) $(link) exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs + rsh $(mighost) cd `pwd` \; \ ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o clean: -- cgit v1.2.3 From 1c93aeda573a9ba671377c235a861d0e8ccd02a8 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 31 Mar 1994 18:15:33 +0000 Subject: Formerly Makefile.~16~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index b6b006f6..9ec865b3 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -26,7 +26,7 @@ SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h -OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o boot_machdep.o +OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o #LIBS = $(hurdinst)/lib/libdiskfscombined.a $(libthreads) LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ -- cgit v1.2.3 From 542a6daceb6c4177eff3877f37cda66af5a12484 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 5 Apr 1994 19:02:45 +0000 Subject: Formerly Makefile.~17~ --- ufs/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 9ec865b3..3698b7bd 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -36,6 +36,8 @@ LIBPARTS = $(libdiskfs) $(libports) $(libpager) $(libioserver) $(libfshelp) all: ufs +LDFLAGS=--no-keep-memory + ufs: $(OBJS) $(LIBS) $(link) -- cgit v1.2.3 From f4fc5fcda4fc24a31aef39ab8de44c441d41d342 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 5 Apr 1994 19:24:20 +0000 Subject: Formerly hyper.c.~4~ --- ufs/hyper.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index dfe76bcf..bd58b7e4 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -18,6 +18,7 @@ #include "ufs.h" #include "fs.h" #include +#include void get_hypermetadata (void) @@ -26,7 +27,26 @@ get_hypermetadata (void) err = dev_read_sync (SBLOCK, (vm_address_t *)&sblock, SBSIZE); assert (!err); - + + if (sblock->fs_magic != FS_MAGIC) + { + fprintf (stderr, "Bad magic number %#lx (should be %#x)\n", + sblock->fs_magic, FS_MAGIC); + exit (1); + } + if (sblock->fs_bsize > 8192) + { + fprintf (stderr, "Block size %ld is too big (max is 8192 bytes)\n", + sblock->fs_bsize); + exit (1); + } + if (sblock->fs_bsize < sizeof (struct fs)) + { + fprintf (stderr, "Block size %ld is too small (min is %ld bytes)\n", + sblock->fs_bsize, sizeof (struct fs)); + exit (1); + } + /* If this is an old filesystem, then we have some more work to do; some crucial constants might not be set; we are therefore forced to set them here. */ -- cgit v1.2.3 From 528f76fbf80b0d3561057748e72f0de60c158583 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 7 Apr 1994 18:42:53 +0000 Subject: Formerly Makefile.~18~ --- ufs/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 3698b7bd..a0ce7c7b 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -47,6 +47,8 @@ exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs clean: rm -f *.o ufs +relink: + rm -f ufs $(OBJS): ufs.h $(OBJS): $(addprefix $(headers)/hurd/,diskfs.h pager.h ioserver.h \ -- cgit v1.2.3 From 9e48841058d912535a84a9c8787f454dcf3bb89a Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 7 Apr 1994 19:00:57 +0000 Subject: Formerly Makefile.~19~ --- ufs/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index a0ce7c7b..f671d906 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -45,6 +45,8 @@ exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs rsh $(mighost) cd `pwd` \; \ ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o +install: + clean: rm -f *.o ufs relink: -- cgit v1.2.3 From e1d9f34e9e60cc1beb2aa8cf350b281e6e087522 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 2 May 1994 20:49:32 +0000 Subject: Formerly Makefile.~20~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index f671d906..7f673092 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -24,7 +24,7 @@ VPATH=.:../machine SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c -DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h +DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h ChangeLog OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o -- cgit v1.2.3 From 9f5ef8cf555806912ef24062f4a34b19c08b0cbb Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 5 May 1994 11:39:59 +0000 Subject: Formerly Makefile.~21~ --- ufs/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 7f673092..98e6391f 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -53,8 +53,8 @@ relink: rm -f ufs $(OBJS): ufs.h -$(OBJS): $(addprefix $(headers)/hurd/,diskfs.h pager.h ioserver.h \ - fshelp.h ports.h) +$(OBJS): $(addprefix $(includedir)/hurd/,diskfs.h pager.h ioserver.h \ + fshelp.h ports.h) alloc.o: fs.h dinode.h consts.o: dinode.h dir.o: dir.h -- cgit v1.2.3 From 1837dae205818d8546f54d2b43817cc4295db155 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 5 May 1994 23:06:48 +0000 Subject: Formerly Makefile.~22~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 98e6391f..67ac3b16 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -42,7 +42,7 @@ ufs: $(OBJS) $(LIBS) $(link) exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs - rsh $(mighost) cd `pwd` \; \ + rsh -n $(mighost) cd `pwd` \; \ ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o install: -- cgit v1.2.3 From f30e0393f2b8efd5cec170fe1749af81b2c27822 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 24 May 1994 02:31:52 +0000 Subject: Formerly Makefile.~23~ --- ufs/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 67ac3b16..7c3c6ca7 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -42,10 +42,10 @@ ufs: $(OBJS) $(LIBS) $(link) exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs - rsh -n $(mighost) cd `pwd` \; \ + rsh $(mighost) -n cd `pwd` \; \ ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o -install: +install: clean: rm -f *.o ufs -- cgit v1.2.3 From 2b40767b8a493e25f0d7214f6fc72f5ecdc57732 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 26 May 1994 18:10:27 +0000 Subject: Initial revision --- ufs/alloc.c | 1053 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1053 insertions(+) create mode 100644 ufs/alloc.c (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c new file mode 100644 index 00000000..161edcb8 --- /dev/null +++ b/ufs/alloc.c @@ -0,0 +1,1053 @@ +/* Disk allocation routines + Copyright (C) 1993, 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Modified from UCB by Michael I. Bushnell. */ + +/* + * Copyright (c) 1982, 1986, 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution is only permitted until one year after the first shipment + * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and + * binary forms are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)ufs_alloc.c 7.20 (Berkeley) 6/28/90 + */ + +#include "ufs.h" +#include "fs.h" +#include "dinode.h" + +#include + +static u_long alloccg (int, daddr_t, int); +static u_long ialloccg (int, daddr_t, int); +static u_long hashalloc (int, long, int, u_long(*)(int, daddr_t, int)); +static daddr_t fragextend (int, long, int, int); +static daddr_t alloccgblk (struct cg *, daddr_t); +static daddr_t mapsearch (struct cg *, daddr_t, int); +static ino_t dirpref (); + +/* These are in tables.c. */ +extern int inside[], around[]; +extern unsigned char *fragtbl[]; + +static spin_lock_t alloclock = SPIN_LOCK_INITIALIZER; + +/* + * Allocate a block in the file system. + * + * The size of the requested block is given, which must be some + * multiple of fs_fsize and <= fs_bsize. + * A preference may be optionally specified. If a preference is given + * the following hierarchy is used to allocate a block: + * 1) allocate the requested block. + * 2) allocate a rotationally optimal block in the same cylinder. + * 3) allocate a block in the same cylinder group. + * 4) quadradically rehash into other cylinder groups, until an + * available block is located. + * If no block preference is given the following heirarchy is used + * to allocate a block: + * 1) allocate a block in the cylinder group that contains the + * inode for the file. + * 2) quadradically rehash into other cylinder groups, until an + * available block is located. + */ +error_t +alloc(struct node *np, + daddr_t lbn, + daddr_t bpref, + int size, + daddr_t *bnp, + struct protid *cred) +{ + int cg; + daddr_t bno; + + *bnp = 0; + assert ("Alloc of bad sized block" && (unsigned) size <= sblock->fs_bsize + && !fragoff(size)); + + spin_lock (&alloclock); + + if (size == sblock->fs_bsize && sblock->fs_cstotal.cs_nbfree == 0) + goto nospace; + if (cred && !diskfs_isuid (0, cred) && freespace(sblock->fs_minfree) <= 0) + goto nospace; + + if (bpref >= sblock->fs_size) + bpref = 0; + if (bpref == 0) + cg = itog(np->dn->number); + else + cg = dtog(bpref); + bno = (daddr_t)hashalloc(cg, (long)bpref, size, alloccg); + + spin_unlock (&alloclock); + + if (bno > 0) + { + np->dn_stat.st_blocks += btodb(size); + np->dn_set_mtime = 1; + np->dn_set_ctime = 1; + *bnp = bno; + return 0; + } + + nospace: + spin_unlock (&alloclock); + printf("file system full\n"); + return (ENOSPC); +} + +/* + * Reallocate a fragment to a bigger size + * + * The number and size of the old block is given, and a preference + * and new size is also specified. The allocator attempts to extend + * the original block. Failing that, the regular block allocator is + * invoked to get an appropriate block. + */ +error_t +realloccg(struct node *np, + daddr_t lbprev, + volatile daddr_t bpref, + int osize, + int nsize, + daddr_t *pbn, + struct protid *cred) +{ + volatile int cg, request; + daddr_t bprev, bno; + error_t error; + + *pbn = 0; + assert ("bad old size" && (unsigned) osize <= sblock->fs_bsize + && !fragoff (osize)); + assert ("bad new size" && (unsigned) nsize <= sblock->fs_bsize + && !fragoff (nsize)); + + spin_lock (&alloclock); + + if (cred && !diskfs_isuid (0, cred) && freespace(sblock->fs_minfree) <= 0) + { + spin_unlock (&alloclock); + goto nospace; + } + + if (error = diskfs_catch_exception ()) + return error; + bprev = dinodes[np->dn->number].di_db[lbprev]; + diskfs_end_catch_exception (); + assert ("old block not allocated" && bprev); + + /* + * Check for extension in the existing location. + */ + cg = dtog(bprev); + if (bno = fragextend(cg, (long)bprev, osize, nsize)) + { + spin_unlock (&alloclock); + assert ("fragextend behaved incorrectly" && bprev == bno); + np->dn_stat.st_blocks += btodb(nsize - osize); + np->dn_set_mtime = 1; + np->dn_set_ctime = 1; + *pbn = bno; + return (0); + } + /* + * Allocate a new disk location. + */ + if (bpref >= sblock->fs_size) + bpref = 0; + switch ((int)sblock->fs_optim) + { + case FS_OPTSPACE: + /* + * Allocate an exact sized fragment. Although this makes + * best use of space, we will waste time relocating it if + * the file continues to grow. If the fragmentation is + * less than half of the minimum free reserve, we choose + * to begin optimizing for time. + */ + request = nsize; + if (sblock->fs_minfree < 5 || + sblock->fs_cstotal.cs_nffree > + sblock->fs_dsize * sblock->fs_minfree / (2 * 100)) + break; + printf("optimization changed from SPACE to TIME\n"); + sblock->fs_optim = FS_OPTTIME; + break; + case FS_OPTTIME: + /* + * At this point we have discovered a file that is trying + * to grow a small fragment to a larger fragment. To save + * time, we allocate a full sized block, then free the + * unused portion. If the file continues to grow, the + * `fragextend' call above will be able to grow it in place + * without further copying. If aberrant programs cause + * disk fragmentation to grow within 2% of the free reserve, + * we choose to begin optimizing for space. + */ + request = sblock->fs_bsize; + if (sblock->fs_cstotal.cs_nffree < + sblock->fs_dsize * (sblock->fs_minfree - 2) / 100) + break; + printf("%s: optimization changed from TIME to SPACE\n", + sblock->fs_fsmnt); + sblock->fs_optim = FS_OPTSPACE; + break; + default: + assert ("filesystem opitimazation bad value" && 0); + } + + bno = (daddr_t)hashalloc(cg, (long)bpref, request, + (u_long (*)())alloccg); + + spin_unlock (&alloclock); + + if (bno > 0) + { + blkfree(bprev, (off_t)osize); + if (nsize < request) + blkfree(bno + numfrags(nsize), (off_t)(request - nsize)); + np->dn_stat.st_blocks += btodb (nsize - osize); + np->dn_set_mtime = 1; + np->dn_set_ctime = 1; + *pbn = bno; + return (0); + } + nospace: + /* + * no space available + */ + printf("file system full\n"); + return (ENOSPC); +} + + +/* Implement the diskfs_alloc_node callback from the diskfs library. + See for the interface description. */ +error_t +diskfs_alloc_node(struct node *dir, + mode_t mode, + struct node **npp) +{ + int ino; + struct node *np; + int cg; + error_t error; + int ipref; + + if (S_ISDIR (mode)) + ipref = dirpref (); + else + ipref = dir->dn->number; + + *npp = 0; + + if (sblock->fs_cstotal.cs_nifree == 0) + goto noinodes; + if (ipref >= sblock->fs_ncg * sblock->fs_ipg) + ipref = 0; + cg = itog(ipref); + spin_lock (&alloclock); + ino = (int)hashalloc(cg, (long)ipref, mode, ialloccg); + spin_unlock (&alloclock); + if (ino == 0) + goto noinodes; + if (error = iget(ino, &np)) + return error; + *npp = np; + assert ("duplicate allocation" && !np->dn_stat.st_mode); + if (np->dn_stat.st_blocks) + { + printf("free inode %d had %d blocks\n", ino, np->dn_stat.st_blocks); + np->dn_stat.st_blocks = 0; + np->dn_set_ctime = 1; + } + /* + * Set up a new generation number for this inode. + */ + spin_lock (&gennumberlock); + if (++nextgennumber < (u_long)diskfs_mtime->seconds) + nextgennumber = diskfs_mtime->seconds; + np->dn_stat.st_gen = nextgennumber; + spin_unlock (&gennumberlock); + return (0); + noinodes: + printf("out of inodes\n"); + return (ENOSPC); +} + +/* + * Find a cylinder to place a directory. + * + * The policy implemented by this algorithm is to select from + * among those cylinder groups with above the average number of + * free inodes, the one with the smallest number of directories. + */ +static ino_t +dirpref() +{ + int cg, minndir, mincg, avgifree; + + spin_lock (&alloclock); + avgifree = sblock->fs_cstotal.cs_nifree / sblock->fs_ncg; + minndir = sblock->fs_ipg; + mincg = 0; + for (cg = 0; cg < sblock->fs_ncg; cg++) + if (csum[cg].cs_ndir < minndir && csum[cg].cs_nifree >= avgifree) + { + mincg = cg; + minndir = csum[cg].cs_ndir; + } + spin_unlock (&alloclock); + return ((int)(sblock->fs_ipg * mincg)); +} + +/* + * Select the desired position for the next block in a file. The file is + * logically divided into sections. The first section is composed of the + * direct blocks. Each additional section contains fs_maxbpg blocks. + * + * If no blocks have been allocated in the first section, the policy is to + * request a block in the same cylinder group as the inode that describes + * the file. If no blocks have been allocated in any other section, the + * policy is to place the section in a cylinder group with a greater than + * average number of free blocks. An appropriate cylinder group is found + * by using a rotor that sweeps the cylinder groups. When a new group of + * blocks is needed, the sweep begins in the cylinder group following the + * cylinder group from which the previous allocation was made. The sweep + * continues until a cylinder group with greater than the average number + * of free blocks is found. If the allocation is for the first block in an + * indirect block, the information on the previous allocation is unavailable; + * here a best guess is made based upon the logical block number being + * allocated. + * + * If a section is already partially allocated, the policy is to + * contiguously allocate fs_maxcontig blocks. The end of one of these + * contiguous blocks and the beginning of the next is physically separated + * so that the disk head will be in transit between them for at least + * fs_rotdelay milliseconds. This is to allow time for the processor to + * schedule another I/O transfer. + */ +daddr_t +blkpref(struct node *np, + daddr_t lbn, + int indx, + daddr_t *bap) +{ + int cg; + int avgbfree, startcg; + daddr_t nextblk; + + spin_lock (&alloclock); + if (indx % sblock->fs_maxbpg == 0 || bap[indx - 1] == 0) + { + if (lbn < NDADDR) + { + spin_unlock (&alloclock); + cg = itog(np->dn->number); + return (sblock->fs_fpg * cg + sblock->fs_frag); + } + /* + * Find a cylinder with greater than average number of + * unused data blocks. + */ + if (indx == 0 || bap[indx - 1] == 0) + startcg = itog(np->dn->number) + lbn / sblock->fs_maxbpg; + else + startcg = dtog(bap[indx - 1]) + 1; + startcg %= sblock->fs_ncg; + avgbfree = sblock->fs_cstotal.cs_nbfree / sblock->fs_ncg; + for (cg = startcg; cg < sblock->fs_ncg; cg++) + if (csum[cg].cs_nbfree >= avgbfree) + { + spin_unlock (&alloclock); + sblock->fs_cgrotor = cg; + return (sblock->fs_fpg * cg + sblock->fs_frag); + } + for (cg = 0; cg <= startcg; cg++) + if (csum[cg].cs_nbfree >= avgbfree) + { + spin_unlock (&alloclock); + sblock->fs_cgrotor = cg; + return (sblock->fs_fpg * cg + sblock->fs_frag); + } + spin_unlock (&alloclock); + return 0; + } + + spin_unlock (&alloclock); + + /* + * One or more previous blocks have been laid out. If less + * than fs_maxcontig previous blocks are contiguous, the + * next block is requested contiguously, otherwise it is + * requested rotationally delayed by fs_rotdelay milliseconds. + */ + nextblk = bap[indx - 1] + sblock->fs_frag; + if (indx > sblock->fs_maxcontig && + bap[indx - sblock->fs_maxcontig] + blkstofrags(sblock->fs_maxcontig) + != nextblk) + return (nextblk); + if (sblock->fs_rotdelay != 0) + /* + * Here we convert ms of delay to frags as: + * (frags) = (ms) * (rev/sec) * (sect/rev) / + * ((sect/frag) * (ms/sec)) + * then round up to the next block. + */ + nextblk += roundup(sblock->fs_rotdelay * sblock->fs_rps + * sblock->fs_nsect / (NSPF * 1000), sblock->fs_frag); + return (nextblk); +} + +/* + * Implement the cylinder overflow algorithm. + * + * The policy implemented by this algorithm is: + * 1) allocate the block in its requested cylinder group. + * 2) quadradically rehash on the cylinder group number. + * 3) brute force search for a free block. + */ +/*VARARGS5*/ +static u_long +hashalloc(int cg, + long pref, + int size, /* size for data blocks, mode for inodes */ + u_long (*allocator)(int, daddr_t, int)) +{ + long result; + int i, icg = cg; + + /* + * 1: preferred cylinder group + */ + result = (*allocator)(cg, pref, size); + if (result) + return (result); + /* + * 2: quadratic rehash + */ + for (i = 1; i < sblock->fs_ncg; i *= 2) + { + cg += i; + if (cg >= sblock->fs_ncg) + cg -= sblock->fs_ncg; + result = (*allocator)(cg, 0, size); + if (result) + return (result); + } + /* + * 3: brute force search + * Note that we start at i == 2, since 0 was checked initially, + * and 1 is always checked in the quadratic rehash. + */ + cg = (icg + 2) % sblock->fs_ncg; + for (i = 2; i < sblock->fs_ncg; i++) + { + result = (*allocator)(cg, 0, size); + if (result) + return (result); + cg++; + if (cg == sblock->fs_ncg) + cg = 0; + } + return 0; +} + +/* + * Determine whether a fragment can be extended. + * + * Check to see if the necessary fragments are available, and + * if they are, allocate them. + */ +static daddr_t +fragextend(int cg, + long bprev, + int osize, + int nsize) +{ + struct cg *cgp; + long bno; + int frags, bbase; + int i; + + if (csum[cg].cs_nffree < numfrags(nsize - osize)) + return 0; + frags = numfrags(nsize); + bbase = fragnum(bprev); + if (bbase > fragnum((bprev + frags - 1))) + /* cannot extend across a block boundary */ + return 0; + + cgp = (struct cg *) (cgs + sblock->fs_bsize * cg); + + if (diskfs_catch_exception ()) + return 0; /* bogus, but that's what BSD does... */ + + if (!cg_chkmagic(cgp)) + { + printf ("Cylinder group %d bad magic number: %ld/%ld\n", + cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); + diskfs_end_catch_exception (); + return 0; + } + cgp->cg_time = diskfs_mtime->seconds; + bno = dtogd(bprev); + for (i = numfrags(osize); i < frags; i++) + if (isclr(cg_blksfree(cgp), bno + i)) + { + diskfs_end_catch_exception (); + return 0; + } + + /* + * the current fragment can be extended + * deduct the count on fragment being extended into + * increase the count on the remaining fragment (if any) + * allocate the extended piece + */ + for (i = frags; i < sblock->fs_frag - bbase; i++) + if (isclr(cg_blksfree(cgp), bno + i)) + break; + cgp->cg_frsum[i - numfrags(osize)]--; + if (i != frags) + cgp->cg_frsum[i - frags]++; + for (i = numfrags(osize); i < frags; i++) + { + clrbit(cg_blksfree(cgp), bno + i); + cgp->cg_cs.cs_nffree--; + sblock->fs_cstotal.cs_nffree--; + csum[cg].cs_nffree--; + } + diskfs_end_catch_exception (); + return (bprev); +} + +/* + * Determine whether a block can be allocated. + * + * Check to see if a block of the apprpriate size is available, + * and if it is, allocate it. + */ +static u_long +alloccg(int cg, + volatile daddr_t bpref, + int size) +{ + struct cg *cgp; + int i; + int bno, frags, allocsiz; + + if (csum[cg].cs_nbfree == 0 && size == sblock->fs_bsize) + return 0; + cgp = (struct cg *) (cgs + sblock->fs_bsize * cg); + + if (diskfs_catch_exception ()) + return 0; + + if (!cg_chkmagic(cgp) || + (cgp->cg_cs.cs_nbfree == 0 && size == sblock->fs_bsize)) + { + printf ("Cylinder group %d bad magic number: %ld/%ld\n", + cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); + diskfs_end_catch_exception (); + return 0; + } + cgp->cg_time = diskfs_mtime->seconds; + if (size == sblock->fs_bsize) + { + bno = alloccgblk(cgp, bpref); + diskfs_end_catch_exception (); + return (u_long) (bno); + } + /* + * check to see if any fragments are already available + * allocsiz is the size which will be allocated, hacking + * it down to a smaller size if necessary + */ + frags = numfrags(size); + for (allocsiz = frags; allocsiz < sblock->fs_frag; allocsiz++) + if (cgp->cg_frsum[allocsiz] != 0) + break; + if (allocsiz == sblock->fs_frag) + { + /* + * no fragments were available, so a block will be + * allocated, and hacked up + */ + if (cgp->cg_cs.cs_nbfree == 0) + { + diskfs_end_catch_exception (); + return 0; + } + + bno = alloccgblk(cgp, bpref); + bpref = dtogd(bno); + for (i = frags; i < sblock->fs_frag; i++) + setbit(cg_blksfree(cgp), bpref + i); + i = sblock->fs_frag - frags; + cgp->cg_cs.cs_nffree += i; + sblock->fs_cstotal.cs_nffree += i; + csum[cg].cs_nffree += i; + cgp->cg_frsum[i]++; + return (u_long)(bno); + } + bno = mapsearch(cgp, bpref, allocsiz); + if (bno < 0) + { + diskfs_end_catch_exception (); + return 0; + } + + for (i = 0; i < frags; i++) + clrbit(cg_blksfree(cgp), bno + i); + cgp->cg_cs.cs_nffree -= frags; + sblock->fs_cstotal.cs_nffree -= frags; + csum[cg].cs_nffree -= frags; + cgp->cg_frsum[allocsiz]--; + if (frags != allocsiz) + cgp->cg_frsum[allocsiz - frags]++; + diskfs_end_catch_exception (); + return (u_long) (cg * sblock->fs_fpg + bno); +} + +/* + * Allocate a block in a cylinder group. + * + * This algorithm implements the following policy: + * 1) allocate the requested block. + * 2) allocate a rotationally optimal block in the same cylinder. + * 3) allocate the next available block on the block rotor for the + * specified cylinder group. + * Note that this routine only allocates fs_bsize blocks; these + * blocks may be fragmented by the routine that allocates them. + */ +static daddr_t +alloccgblk(struct cg *cgp, + volatile daddr_t bpref) +{ + daddr_t bno; + int cylno, pos, delta; + short *cylbp; + int i; + daddr_t ret; + + if (diskfs_catch_exception ()) + return 0; + + if (bpref == 0) + { + bpref = cgp->cg_rotor; + goto norot; + } + bpref = blknum(bpref); + bpref = dtogd(bpref); + /* + * if the requested block is available, use it + */ + if (isblock(cg_blksfree(cgp), fragstoblks(bpref))) + { + bno = bpref; + goto gotit; + } + /* + * check for a block available on the same cylinder + */ + cylno = cbtocylno(bpref); + if (cg_blktot(cgp)[cylno] == 0) + goto norot; + if (sblock->fs_cpc == 0) + { + /* + * block layout info is not available, so just have + * to take any block in this cylinder. + */ + bpref = howmany(sblock->fs_spc * cylno, NSPF); + goto norot; + } + /* + * check the summary information to see if a block is + * available in the requested cylinder starting at the + * requested rotational position and proceeding around. + */ + cylbp = cg_blks(cgp, cylno); + pos = cbtorpos(bpref); + for (i = pos; i < sblock->fs_nrpos; i++) + if (cylbp[i] > 0) + break; + if (i == sblock->fs_nrpos) + for (i = 0; i < pos; i++) + if (cylbp[i] > 0) + break; + if (cylbp[i] > 0) + { + /* + * found a rotational position, now find the actual + * block. A panic if none is actually there. + */ + pos = cylno % sblock->fs_cpc; + bno = (cylno - pos) * sblock->fs_spc / NSPB; + assert ("postbl table bad" &&fs_postbl(pos)[i] != -1); + for (i = fs_postbl(pos)[i];; ) + { + if (isblock(cg_blksfree(cgp), bno + i)) + { + bno = blkstofrags(bno + i); + goto gotit; + } + delta = fs_rotbl[i]; + if (delta <= 0 || + delta + i > fragstoblks(sblock->fs_fpg)) + break; + i += delta; + } + assert ("Inconsistent rotbl table" && 0); + } + norot: + /* + * no blocks in the requested cylinder, so take next + * available one in this cylinder group. + */ + bno = mapsearch(cgp, bpref, (int)sblock->fs_frag); + if (bno < 0) + { + diskfs_end_catch_exception (); + return 0; + } + cgp->cg_rotor = bno; + gotit: + clrblock(cg_blksfree(cgp), (long)fragstoblks(bno)); + cgp->cg_cs.cs_nbfree--; + sblock->fs_cstotal.cs_nbfree--; + csum[cgp->cg_cgx].cs_nbfree--; + cylno = cbtocylno(bno); + cg_blks(cgp, cylno)[cbtorpos(bno)]--; + cg_blktot(cgp)[cylno]--; + ret = cgp->cg_cgx * sblock->fs_fpg + bno; + diskfs_end_catch_exception (); + return ret; +} + +/* + * Determine whether an inode can be allocated. + * + * Check to see if an inode is available, and if it is, + * allocate it using the following policy: + * 1) allocate the requested inode. + * 2) allocate the next available inode after the requested + * inode in the specified cylinder group. + */ +static u_long +ialloccg(int cg, + volatile daddr_t ipref, + int modein) +{ + struct cg *cgp; + int start, len, loc, map, i; + mode_t mode = (mode_t) modein; + + if (csum[cg].cs_nifree == 0) + return 0; + + cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); + + if (diskfs_catch_exception ()) + return 0; + + if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) + { + printf ("Cylinder group %d bad magic number: %ld/%ld\n", + cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); + diskfs_end_catch_exception (); + return 0; + } + cgp->cg_time = diskfs_mtime->seconds; + if (ipref) + { + ipref %= sblock->fs_ipg; + if (isclr(cg_inosused(cgp), ipref)) + goto gotit; + } + start = cgp->cg_irotor / NBBY; + len = howmany(sblock->fs_ipg - cgp->cg_irotor, NBBY); + loc = skpc(0xff, len, (u_char *) &cg_inosused(cgp)[start]); + if (loc == 0) + { + len = start + 1; + start = 0; + loc = skpc(0xff, len, (u_char *) &cg_inosused(cgp)[0]); + assert ("inconsistent cg_inosused table" && loc); + } + i = start + len - loc; + map = cg_inosused(cgp)[i]; + ipref = i * NBBY; + for (i = 1; i < (1 << NBBY); i <<= 1, ipref++) + { + if ((map & i) == 0) + { + cgp->cg_irotor = ipref; + goto gotit; + } + } + assert ("inconsistent cg_inosused table" && 0); + gotit: + setbit(cg_inosused(cgp), ipref); + cgp->cg_cs.cs_nifree--; + sblock->fs_cstotal.cs_nifree--; + csum[cg].cs_nifree--; + if ((mode & IFMT) == IFDIR) + { + cgp->cg_cs.cs_ndir++; + sblock->fs_cstotal.cs_ndir++; + csum[cg].cs_ndir++; + } + diskfs_end_catch_exception (); + return (u_long)(cg * sblock->fs_ipg + ipref); +} + +/* + * Free a block or fragment. + * + * The specified block or fragment is placed back in the + * free map. If a fragment is deallocated, a possible + * block reassembly is checked. + */ +void +blkfree(volatile daddr_t bno, + int size) +{ + struct cg *cgp; + int cg, blk, frags, bbase; + int i; + + assert ("free of bad sized block" &&(unsigned) size <= sblock->fs_bsize + && !fragoff (size)); + cg = dtog(bno); + if ((unsigned)bno >= sblock->fs_size) + { + printf("bad block %ld\n", bno); + return; + } + + cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); + + spin_lock (&alloclock); + + if (diskfs_catch_exception ()) + { + spin_unlock (&alloclock); + return; + } + + if (!cg_chkmagic(cgp)) + { + spin_unlock (&alloclock); + printf ("Cylinder group %d bad magic number: %ld/%ld\n", + cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); + diskfs_end_catch_exception (); + return; + } + cgp->cg_time = diskfs_mtime->seconds; + bno = dtogd(bno); + if (size == sblock->fs_bsize) + { + assert ("inconsistent cg_blskfree table" + && !isblock (cg_blksfree (cgp), fragstoblks (bno))); + setblock(cg_blksfree(cgp), fragstoblks(bno)); + cgp->cg_cs.cs_nbfree++; + sblock->fs_cstotal.cs_nbfree++; + csum[cg].cs_nbfree++; + i = cbtocylno(bno); + cg_blks(cgp, i)[cbtorpos(bno)]++; + cg_blktot(cgp)[i]++; + } + else + { + bbase = bno - fragnum(bno); + /* + * decrement the counts associated with the old frags + */ + blk = blkmap(cg_blksfree(cgp), bbase); + fragacct(blk, cgp->cg_frsum, -1); + /* + * deallocate the fragment + */ + frags = numfrags(size); + for (i = 0; i < frags; i++) + { + assert ("inconsistent cg_blksfree table" + && !isset (cg_blksfree (cgp), bno + i)); + setbit(cg_blksfree(cgp), bno + i); + } + cgp->cg_cs.cs_nffree += i; + sblock->fs_cstotal.cs_nffree += i; + csum[cg].cs_nffree += i; + /* + * add back in counts associated with the new frags + */ + blk = blkmap(cg_blksfree(cgp), bbase); + fragacct(blk, cgp->cg_frsum, 1); + /* + * if a complete block has been reassembled, account for it + */ + if (isblock(cg_blksfree(cgp), (daddr_t)fragstoblks(bbase))) + { + cgp->cg_cs.cs_nffree -= sblock->fs_frag; + sblock->fs_cstotal.cs_nffree -= sblock->fs_frag; + csum[cg].cs_nffree -= sblock->fs_frag; + cgp->cg_cs.cs_nbfree++; + sblock->fs_cstotal.cs_nbfree++; + csum[cg].cs_nbfree++; + i = cbtocylno(bbase); + cg_blks(cgp, i)[cbtorpos(bbase)]++; + cg_blktot(cgp)[i]++; + } + } + spin_unlock (&alloclock); + diskfs_end_catch_exception (); +} + +/* + * Free an inode. + * + * The specified inode is placed back in the free map. + */ +void +diskfs_free_node(struct node *np, mode_t mode) +{ + struct cg *cgp; + int cg; + volatile int ino = np->dn->number; + + assert ("invalid inode number" && ino < sblock->fs_ipg * sblock->fs_ncg); + + cg = itog(ino); + cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); + + spin_lock (&alloclock); + if (diskfs_catch_exception ()) + { + spin_unlock (&alloclock); + return; + } + + if (!cg_chkmagic(cgp)) + { + spin_unlock (&alloclock); + printf ("Cylinder group %d bad magic number: %ld/%ld\n", + cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); + diskfs_end_catch_exception (); + return; + } + cgp->cg_time = diskfs_mtime->seconds; + ino %= sblock->fs_ipg; + assert ("inconsistent cg_inosused table" && !isclr (cg_inosused (cgp), ino)); + clrbit(cg_inosused(cgp), ino); + if (ino < cgp->cg_irotor) + cgp->cg_irotor = ino; + cgp->cg_cs.cs_nifree++; + sblock->fs_cstotal.cs_nifree++; + csum[cg].cs_nifree++; + if ((mode & IFMT) == IFDIR) + { + cgp->cg_cs.cs_ndir--; + sblock->fs_cstotal.cs_ndir--; + csum[cg].cs_ndir--; + } + spin_unlock (&alloclock); + diskfs_end_catch_exception (); +} + + +/* + * Find a block of the specified size in the specified cylinder group. + * + * It is a panic if a request is made to find a block if none are + * available. + */ +/* This routine expects to be called from inside a diskfs_catch_exception */ +static daddr_t +mapsearch(struct cg *cgp, + daddr_t bpref, + int allocsiz) +{ + daddr_t bno; + int start, len, loc, i; + int blk, field, subfield, pos; + + /* + * find the fragment by searching through the free block + * map for an appropriate bit pattern + */ + if (bpref) + start = dtogd(bpref) / NBBY; + else + start = cgp->cg_frotor / NBBY; + len = howmany(sblock->fs_fpg, NBBY) - start; + loc = scanc((unsigned)len, (u_char *)&cg_blksfree(cgp)[start], + (u_char *)fragtbl[sblock->fs_frag], + (u_char)(1 << (allocsiz - 1 + (sblock->fs_frag % NBBY)))); + if (loc == 0) + { + len = start + 1; + start = 0; + loc = scanc((unsigned)len, (u_char *)&cg_blksfree(cgp)[0], + (u_char *)fragtbl[sblock->fs_frag], + (u_char)(1 << (allocsiz - 1 + (sblock->fs_frag % NBBY)))); + assert ("incosistent cg_blksfree table" && loc); + } + bno = (start + len - loc) * NBBY; + cgp->cg_frotor = bno; + /* + * found the byte in the map + * sift through the bits to find the selected frag + */ + for (i = bno + NBBY; bno < i; bno += sblock->fs_frag) + { + blk = blkmap(cg_blksfree(cgp), bno); + blk <<= 1; + field = around[allocsiz]; + subfield = inside[allocsiz]; + for (pos = 0; pos <= sblock->fs_frag - allocsiz; pos++) + { + if ((blk & field) == subfield) + return (bno + pos); + field <<= 1; + subfield <<= 1; + } + } + assert ("inconsistent cg_blksfree table" && 0); +} + + -- cgit v1.2.3 From 8017cc8bfda4b6e5735db0cd2f1c260e4a84e182 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 31 May 1994 15:53:29 +0000 Subject: Formerly Makefile.~24~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 7c3c6ca7..44ae79b6 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -36,7 +36,7 @@ LIBPARTS = $(libdiskfs) $(libports) $(libpager) $(libioserver) $(libfshelp) all: ufs -LDFLAGS=--no-keep-memory +LDFLAGS=--no-keep-memory -y_hurd_rlimits -y__hurd_rlimits ufs: $(OBJS) $(LIBS) $(link) -- cgit v1.2.3 From 890a81fa732f4c1e654ca492ef1fdae170c7bdf3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 1 Jun 1994 18:02:51 +0000 Subject: Formerly alloc.c.~10~ --- ufs/alloc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 161edcb8..193e0f31 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -93,7 +93,7 @@ alloc(struct node *np, *bnp = 0; assert ("Alloc of bad sized block" && (unsigned) size <= sblock->fs_bsize - && !fragoff(size)); + && !fragoff(size) && size != 0); spin_lock (&alloclock); @@ -150,9 +150,9 @@ realloccg(struct node *np, *pbn = 0; assert ("bad old size" && (unsigned) osize <= sblock->fs_bsize - && !fragoff (osize)); + && !fragoff (osize) && osize != 0 ); assert ("bad new size" && (unsigned) nsize <= sblock->fs_bsize - && !fragoff (nsize)); + && !fragoff (nsize) && nsize != 0); spin_lock (&alloclock); @@ -273,12 +273,15 @@ diskfs_alloc_node(struct node *dir, *npp = 0; + spin_lock (&alloclock); if (sblock->fs_cstotal.cs_nifree == 0) - goto noinodes; + { + spin_unlock (&alloclock); + goto noinodes; + } if (ipref >= sblock->fs_ncg * sblock->fs_ipg) ipref = 0; cg = itog(ipref); - spin_lock (&alloclock); ino = (int)hashalloc(cg, (long)ipref, mode, ialloccg); spin_unlock (&alloclock); if (ino == 0) @@ -852,7 +855,7 @@ blkfree(volatile daddr_t bno, int i; assert ("free of bad sized block" &&(unsigned) size <= sblock->fs_bsize - && !fragoff (size)); + && !fragoff (size) && size != 0); cg = dtog(bno); if ((unsigned)bno >= sblock->fs_size) { -- cgit v1.2.3 From d3e07ca3f3efa6afef110b527993bf28cfe48a89 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 2 Jun 1994 17:21:37 +0000 Subject: Initial revision --- ufs/main.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 ufs/main.c (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c new file mode 100644 index 00000000..8c6114ed --- /dev/null +++ b/ufs/main.c @@ -0,0 +1,181 @@ +/* + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +#include "ufs.h" +#include "fs.h" +#include +#include +#include +#include + +char *ufs_version = "0.0 pre-alpha"; + +mach_port_t diskfs_dotdot_file; +static char **save_argv; + +/* Parse the arguments for ufs when started as a translator. */ +char * +trans_parse_args (int argc, char **arg) +{ + #ifdef notyet + /* When started as a translator, we are called with + the device name and an optional argument -r, which + signifies read-only. */ + if (argc < 2 || argc > 3) + usage_trans (); + if (argc == 2) + devname = argv[1]; + else if (argc == 3) + { + if (argv[1][0] == '-' && argv[1][1] == 'r') + { + diskfs_readonly = 1; + devname = argv[2]; + } + else if (argv[2][0] == '-' && argv[2][1] == 'r') + { + diskfs_readonly = 1; + devname = argv[1]; + } + else + usage_trans (); + } + + get_privileged_ports (&host_priv_port, &master_device_port); + if (!master_device_port) + { + fprintf (stderr, "%s: Cannot get master device port\n", + argv[0]); + exit (1); + } + /* We only need the host port if we are a bootstrap filesystem. */ + if (host_priv_port) + mach_port_deallocate (mach_task_self (), host_priv_port); + + mach_port_insert_right (mach_task_self (), ufs_control_port, + ufs_control_port, MACH_MSG_TYPE_MAKE_SEND); + fsys_startup (bootstrap, ufs_control_port, &ufs_realnode, + &diskfs_dotdot_file); + mach_port_deallocate (mach_task_self (), ufs_control_port); +#else + task_terminate (mach_task_self ()); + for (;;); +#endif +} + +struct node *diskfs_root_node; + +/* Set diskfs_root_node to the root inode. */ +static void +warp_root (void) +{ + error_t err; + err = iget (2, &diskfs_root_node); + assert (!err); + mutex_unlock (&diskfs_root_node->lock); +} + +/* XXX */ +struct mutex printf_lock; +int printf (const char *fmt, ...) +{ + va_list arg; + int done; + va_start (arg, fmt); + mutex_lock (&printf_lock); + done = vprintf (fmt, arg); + mutex_unlock (&printf_lock); + va_end (arg); + return done; +} + +int diskfs_readonly; + +void +main (int argc, char **argv) +{ + char *devname; + mach_port_t bootstrap; + error_t err; + + save_argv = argv; + + mutex_init (&printf_lock); /* XXX */ + + task_get_bootstrap_port (mach_task_self (), &bootstrap); + + if (bootstrap) + devname = trans_parse_args (argc, argv); + else + { + devname = diskfs_parse_bootargs (argc, argv); + diskfs_dotdot_file = MACH_PORT_NULL; + } + + diskfs_init_diskfs (); + + err = device_open (diskfs_master_device, + (diskfs_readonly ? 0 : D_WRITE) | D_READ, + devname, &ufs_device); + assert (!err); + + get_hypermetadata (); + + if (!diskfs_readonly) + { + sblock->fs_clean = 0; + strcpy (sblock->fs_fsmnt, "Hurd /"); + sblock_dirty = 1; + diskfs_set_hypermetadata (1, 0); + } + + inode_init (); + pager_init (); + + diskfs_spawn_first_thread (); + + warp_root (); + + if (!bootstrap) + diskfs_start_bootstrap (); + + diskfs_main_request_loop (); +} + + +void +diskfs_init_completed () +{ + mach_port_t proc, startup; + error_t err; + + _hurd_proc_init (save_argv); + proc = getproc(); + proc_register_version (proc, diskfs_host_priv, "ufs", HURD_RELEASE, + ufs_version); + err = proc_getmsgport (proc, 1, &startup); + if (!err) + { + startup_essential_task (startup, mach_task_self (), MACH_PORT_NULL, + "ufs", diskfs_host_priv); + mach_port_deallocate (mach_task_self (), startup); + } + mach_port_deallocate (mach_task_self (), proc); +} + + -- cgit v1.2.3 From 423954be7b659e3f2b8cf6fde12dbd8947875161 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 2 Jun 1994 17:31:45 +0000 Subject: Formerly hyper.c.~5~ --- ufs/hyper.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index bd58b7e4..7bb8d7c8 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -72,22 +72,42 @@ diskfs_set_hypermetadata (int wait, int clean) error_t (*writefn) (daddr_t, vm_address_t, long); writefn = (wait ? dev_write_sync : dev_write); - (*writefn)(fsbtodb (sblock->fs_csaddr), (vm_address_t) csum, - sblock->fs_fsize * howmany (sblock->fs_cssize, - sblock->fs_fsize)); + spin_lock (&alloclock); + if (csum_dirty) + { + (*writefn)(fsbtodb (sblock->fs_csaddr), (vm_address_t) csum, + sblock->fs_fsize * howmany (sblock->fs_cssize, + sblock->fs_fsize)); + csum_dirty = 0; + } if (clean) - sblock->fs_clean = 1; - if (sblock->fs_postblformat == FS_42POSTBLFMT) { - char sblockcopy[SBSIZE]; - bcopy (sblock, sblockcopy, SBSIZE); - ((struct fs *)sblockcopy)->fs_nrpos = -1; - (*writefn) (SBLOCK, (vm_address_t) sblockcopy, SBSIZE); + sblock->fs_clean = 1; + sblock_dirty = 1; + } + + if (sblock_dirty) + { + if (sblock->fs_postblformat == FS_42POSTBLFMT) + { + char sblockcopy[SBSIZE]; + bcopy (sblock, sblockcopy, SBSIZE); + ((struct fs *)sblockcopy)->fs_nrpos = -1; + (*writefn) (SBLOCK, (vm_address_t) sblockcopy, SBSIZE); + } + else + (*writefn) (SBLOCK, (vm_address_t) sblock, SBSIZE); + sblock_dirty = 0; } - else - (*writefn) (SBLOCK, (vm_address_t) sblock, SBSIZE); - sblock->fs_clean = 0; + + if (clean) + { + sblock->fs_clean = 0; + sblock_dirty = 1; + } + + spin_unlock (&alloclock); } -- cgit v1.2.3 From 0325d858a8b0d685250ee224ac2283eedbff0e6f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 9 Jun 1994 16:59:49 +0000 Subject: Formerly Makefile.~25~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 44ae79b6..7c3c6ca7 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -36,7 +36,7 @@ LIBPARTS = $(libdiskfs) $(libports) $(libpager) $(libioserver) $(libfshelp) all: ufs -LDFLAGS=--no-keep-memory -y_hurd_rlimits -y__hurd_rlimits +LDFLAGS=--no-keep-memory ufs: $(OBJS) $(LIBS) $(link) -- cgit v1.2.3 From fd3e546dd6c0c41553f0073fb877e06921d2cdfa Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 9 Jun 1994 17:18:08 +0000 Subject: Initial revision --- ufs/sizes.c | 474 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 474 insertions(+) create mode 100644 ufs/sizes.c (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c new file mode 100644 index 00000000..d8429fcc --- /dev/null +++ b/ufs/sizes.c @@ -0,0 +1,474 @@ +/* File growth and truncation + Copyright (C) 1993, 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Michael I. Bushnell. */ + +#include "ufs.h" +#include "fs.h" +#include "dinode.h" + +#ifdef DONT_CACHE_MEMORY_OBJECTS +#define MAY_CACHE 0 +#else +#define MAY_CACHE 1 +#endif + +static void dindir_drop (struct node *); +static void sindir_drop (struct node *, int, int); +static void poke_pages (memory_object_t, vm_offset_t, vm_offset_t); + +/* Truncate node NP to be at most LENGTH bytes. */ +/* The inode must be locked, and we must have the conch. */ +/* This is a pain. Sigh. */ +error_t +diskfs_truncate (struct node *np, + off_t length) +{ + daddr_t lastblock, olastblock, bn; + off_t osize; + int bsize, idx; + mach_port_t obj; + + osize = np->dn_stat.st_size; + if (length >= osize) + return 0; + + /* Calculate block number of last block */ + lastblock = lblkno (length + sblock->fs_bsize - 1) - 1; + olastblock = lblkno (osize + sblock->fs_bsize - 1) - 1; + + /* If the prune is not to a block boundary, zero the bit upto the + next block boundary. */ + if (blkoff (length)) + diskfs_node_rdwr (np, (void *) zeroblock, length, + blksize (np, lastblock) - blkoff (length), 1, 0, 0); + + /* We are going to throw away the block pointers for the blocks + olastblock+1 through lastblock. This will cause the underlying + data to become zeroes, because of the behavior of pager_read_page + (in ufs/pager.c). Consequently, we have to take action to force + the kernel to immediately undertake any delayed copies that + implicitly depend on the data we are flushing. We also have to + prevent any new delayed copies from being undertaken until we + have finished the flush. */ + if (np->dn->fileinfo) + { + pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, + MEMORY_OBJECT_COPY_NONE, 1); + obj = diskfs_get_filemap (np); + mach_port_insert_right (mach_task_self (), obj, obj, + MACH_MSG_TYPE_MAKE_SEND); + poke_pages (obj, round_page (length), round_page (osize)); + mach_port_deallocate (mach_task_self (), obj); + } + + mutex_lock (&np->dn->datalock); + + /* Update the size now. If we crash, fsck can finish freeing the + blocks. */ + np->dn_stat.st_size = length; + np->dn_stat_dirty = 1; + + /* Flush the old data. */ + if (np->dn->fileinfo) + pager_flush_some (np->dn->fileinfo->p, + (lastblock == -1 ? 0 : lastblock) * sblock->fs_bsize, + (olastblock - lastblock) * sblock->fs_bsize, 1); + + /* Drop data blocks mapped by indirect blocks */ + if (olastblock >= NDADDR) + { + daddr_t first2free; + + if (!np->dn->sinloc) + sin_map (np); + + if (lastblock + 1 > NDADDR) + first2free = lastblock + 1; + else + first2free = NDADDR; + + for (idx = first2free; idx <= olastblock; idx ++) + { + if (np->dn->sinloc[idx - NDADDR]) + { + blkfree (np->dn->sinloc[idx - NDADDR], sblock->fs_bsize); + np->dn->sinloc[idx - NDADDR] = 0; + np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; + np->dn_stat_dirty = 1; + } + } + + /* Prune the block pointers handled by the sindir pager. This will + free all the indirect blocks and such as necessary. */ + sindir_drop (np, lblkno((first2free - NDADDR) * sizeof (daddr_t)), + lblkno ((olastblock - NDADDR) * sizeof (daddr_t))); + + if (!np->dn->fileinfo) + sin_unmap (np); + } + + /* Prune the blocks mapped directly from the inode */ + for (idx = lastblock + 1; idx < NDADDR; idx++) + { + bn = dinodes[np->dn->number].di_db[idx]; + if (bn) + { + dinodes[np->dn->number].di_db[idx] = 0; + assert (idx <= olastblock); + if (idx == olastblock) + bsize = blksize (np, idx); + else + bsize = sblock->fs_bsize; + blkfree (bn, bsize); + np->dn_stat.st_blocks -= bsize / DEV_BSIZE; + np->dn_stat_dirty = 1; + } + } + + if (lastblock >= 0 && lastblock < NDADDR) + { + /* Look for a change in the size of the last direct block */ + bn = dinodes[np->dn->number].di_db[lastblock]; + if (bn) + { + off_t oldspace, newspace; + + oldspace = blksize (np, lastblock); + newspace = fragroundup (blkoff (length));; + assert (newspace); + if (oldspace - newspace) + { + bn += numfrags (newspace); + blkfree (bn, oldspace - newspace); + np->dn_stat.st_blocks -= (oldspace - newspace) / DEV_BSIZE; + np->dn_stat_dirty = 1; + } + } + } + + if (lastblock < NDADDR) + np->allocsize = fragroundup (length); + else + np->allocsize = blkroundup (length); + + mutex_unlock (&np->dn->datalock); + + /* Now we can allow delayed copies again */ + if (np->dn->fileinfo) + pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, + MEMORY_OBJECT_COPY_DELAY, 0); + + diskfs_file_update (np, 1); + return 0; +} + +/* Deallocate the double indirect block of the file NP. */ +static void +dindir_drop (struct node *np) +{ + mutex_lock (&np->dn->dinlock); + + pager_flush_some (dinpager->p, np->dn->number * sblock->fs_bsize, + sblock->fs_bsize, 1); + + if (dinodes[np->dn->number].di_ib[INDIR_DOUBLE]) + { + blkfree (dinodes[np->dn->number].di_ib[INDIR_DOUBLE], sblock->fs_bsize); + dinodes[np->dn->number].di_ib[INDIR_DOUBLE] = 0; + np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; + } + + mutex_unlock (&np->dn->dinlock); +} + + +/* Deallocate the single indirect blocks of file IP from + FIRST through LAST inclusive. */ +static void +sindir_drop (struct node *np, + int first, + int last) +{ + int idx; + + mutex_lock (&np->dn->sinlock); + + pager_flush_some (np->dn->sininfo->p, first * sblock->fs_bsize, + (last - first + 1) * sblock->fs_bsize, 1); + + /* Drop indirect blocks found in the double indirect block */ + if (last > 1) + { + if (!np->dn->dinloc) + din_map (np); + for (idx = first; idx = last; idx++) + { + if (np->dn->dinloc[idx - 1]) + { + blkfree (np->dn->dinloc[idx - 1], sblock->fs_bsize); + np->dn->dinloc[idx - 1] = 0; + np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; + } + } + + /* If we no longer need the double indirect block, drop it. */ + if (first <= 1) + dindir_drop (np); + if (!np->dn->sininfo) + din_unmap (np); + } + + /* Drop the block from the inode if we don't need it any more */ + if (first == 0 && dinodes[np->dn->number].di_ib[INDIR_SINGLE]) + { + blkfree (dinodes[np->dn->number].di_ib[INDIR_SINGLE], sblock->fs_bsize); + dinodes[np->dn->number].di_ib[INDIR_SINGLE] = 0; + np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; + } + mutex_unlock (&np->dn->sinlock); +} + +/* Write something to each page from START to END inclusive of memory + object OBJ, but make sure the data doesns't actually change. */ +static void +poke_pages (memory_object_t obj, + vm_offset_t start, + vm_offset_t end) +{ + vm_address_t addr, poke; + vm_size_t len; + error_t err; + + while (start < end) + { + len = 8 * vm_page_size; + if (len > end - start) + len = end - start; + addr = 0; + err = vm_map (mach_task_self (), &addr, len, 0, 1, obj, start, 0, + VM_PROT_WRITE|VM_PROT_READ, VM_PROT_READ|VM_PROT_WRITE, 0); + if (!err) + { + for (poke = addr; poke < addr + len; poke += vm_page_size) + *(volatile int *)poke = *(volatile int *)poke; + vm_deallocate (mach_task_self (), addr, len); + } + start += len; + } +} + + +/* Implement the diskfs_grow callback; see for the + interface description. */ +error_t +diskfs_grow (struct node *np, + off_t end, + struct protid *cred) +{ + daddr_t lbn, pbn, nb; + int osize, size; + int err; + volatile daddr_t dealloc_on_error = 0; + volatile int dealloc_size = 0; + volatile off_t zero_off1 = 0, zero_off2 = 0; + volatile int zero_len1 = 0, zero_len2 = 0; + volatile off_t poke_off1 = 0, poke_off2 = 0; + volatile off_t poke_len1 = 0, poke_len2 = 0; + vm_address_t zerobuf; + + if (end <= np->allocsize) + return 0; + + mutex_lock (&np->dn->datalock); + + /* This deallocation works for the calls to alloc, but not for + realloccg. I'm not sure how to prune the fragment down, especially if + we grew a fragment and then couldn't allocate the piece later. + freeing it all up is a royal pain, largely punted right now... -mib. + */ + if (err = diskfs_catch_exception()) + { + if (dealloc_on_error) + blkfree (dealloc_on_error, dealloc_size); + goto out; + } + + /* This is the logical block number of what will be the last block. */ + lbn = lblkno (end + sblock->fs_bsize - 1) - 1; + + /* This is the size to be of that block if it is in the NDADDR array. */ + size = fragroundup (blkoff (end)); + if (size == 0) + size = sblock->fs_bsize; + + /* if we are writing a new block, then an old one may need to be + reallocated into a full block. */ + + nb = lblkno (np->allocsize + sblock->fs_bsize - 1) - 1; + if (np->allocsize && nb < NDADDR && nb < lbn) + { + osize = blksize (np, nb); + if (osize < sblock->fs_bsize && osize > 0) + { + daddr_t old_pbn; + err = realloccg (np, nb, + blkpref (np, nb, (int)nb, + dinodes[np->dn->number].di_db), + osize, sblock->fs_bsize, &pbn, cred); + if (err) + goto out; + np->allocsize = (nb + 1) * sblock->fs_bsize; + old_pbn = dinodes[np->dn->number].di_db[nb]; + dinodes[np->dn->number].di_db[nb] = pbn; + + /* The new disk blocks should be zeros but might not be. + This is a sanity measure that I'm not sure is necessary. */ + zero_off1 = nb * sblock->fs_bsize + osize; + zero_len1 = nb * sblock->fs_bsize + sblock->fs_bsize - zero_off1; + + if (pbn != old_pbn) + { + /* Make sure that the old contents get written out by + poking the pages. */ + poke_off1 = nb * sblock->fs_bsize; + poke_len1 = osize; + } + } + } + + /* allocate this block */ + if (lbn < NDADDR) + { + nb = dinodes[np->dn->number].di_db[lbn]; + + if (nb != 0) + { + /* consider need to reallocate a fragment. */ + osize = blkoff (np->allocsize); + if (osize == 0) + osize = sblock->fs_bsize; + if (size > osize) + { + err = realloccg (np, lbn, + blkpref (np, lbn, lbn, + dinodes[np->dn->number].di_db), + osize, size, &pbn, cred); + if (err) + goto out; + dinodes[np->dn->number].di_db[lbn] = pbn; + + /* The new disk blocks should be zeros but might not be. + This is a sanity measure that I'm not sure is necessary. */ + zero_off2 = lbn * sblock->fs_bsize + osize; + zero_len2 = lbn * sblock->fs_bsize + size - zero_off2; + + if (pbn != nb) + { + /* Make sure that the old contents get written out by + poking the pages. */ + poke_off2 = lbn * sblock->fs_bsize; + poke_len2 = osize; + } + } + } + else + { + err = alloc (np, lbn, + blkpref (np, lbn, lbn, dinodes[np->dn->number].di_db), + size, &pbn, cred); + if (err) + goto out; + dealloc_on_error = pbn; + dealloc_size = size; + dinodes[np->dn->number].di_db[lbn] = pbn; + } + np->allocsize = fragroundup (end); + } + else + { + /* Make user the sindir area is mapped at the right size. */ + if (np->dn->sinloc) + { + sin_remap (np, end); + np->allocsize = blkroundup (end); + } + else + { + np->allocsize = blkroundup (end); + sin_map (np); + } + + lbn -= NDADDR; + if (!np->dn->sinloc[lbn]) + { + err = alloc (np, lbn, blkpref (np, lbn + NDADDR, lbn, + np->dn->sinloc), + sblock->fs_bsize, &pbn, cred); + if (err) + goto out; + dealloc_on_error = pbn; + dealloc_size = sblock->fs_bsize; + np->dn->sinloc[lbn] = pbn; + } + if (!np->dn->fileinfo) + sin_unmap (np); + } + + if (np->conch.holder) + ioserver_put_shared_data (np->conch.holder); + + out: + diskfs_end_catch_exception (); + mutex_unlock (&np->dn->datalock); + + /* Do the pokes and zeros that we requested before; they have to be + done here because we can't cause a page while holding datalock. */ + if (zero_len1 || zero_len2) + { + vm_allocate (mach_task_self (), &zerobuf, + zero_len1 > zero_len2 ? zero_len1 : zero_len2, 1); + if (zero_len1) + diskfs_node_rdwr (np, (char *) zerobuf, zero_off1, + zero_len1, 1, cred, 0); + if (zero_len2) + diskfs_node_rdwr (np, (char *) zerobuf, zero_off2, + zero_len2, 1, cred, 0); + vm_deallocate (mach_task_self (), zerobuf, + zero_len1 > zero_len2 ? zero_len1 : zero_len2); + } + if (poke_len1 || poke_len2) + { + mach_port_t obj; + obj = diskfs_get_filemap (np); + mach_port_insert_right (mach_task_self (), obj, obj, + MACH_MSG_TYPE_MAKE_SEND); + if (poke_len1) + poke_pages (obj, trunc_page (poke_off1), + round_page (poke_off1 + poke_len1)); + if (poke_len2) + poke_pages (obj, trunc_page (poke_off2), + round_page (poke_off2 + poke_len2)); + mach_port_deallocate (mach_task_self (), obj); + } + + diskfs_file_update (np, 0); + + return err; +} -- cgit v1.2.3 From d299e41b9211411f4e9d8a9c1f258752ecd55887 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 13 Jun 1994 19:30:36 +0000 Subject: Formerly sizes.c.~14~ --- ufs/sizes.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index d8429fcc..423c13bb 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -78,7 +78,7 @@ diskfs_truncate (struct node *np, mach_port_deallocate (mach_task_self (), obj); } - mutex_lock (&np->dn->datalock); + rwlock_writer_lock (&np->dn->datalock, np->dn); /* Update the size now. If we crash, fsck can finish freeing the blocks. */ @@ -96,6 +96,7 @@ diskfs_truncate (struct node *np, { daddr_t first2free; + mutex_lock (&sinmaplock); if (!np->dn->sinloc) sin_map (np); @@ -122,6 +123,7 @@ diskfs_truncate (struct node *np, if (!np->dn->fileinfo) sin_unmap (np); + mutex_unlock (&sinmaplock); } /* Prune the blocks mapped directly from the inode */ @@ -168,7 +170,7 @@ diskfs_truncate (struct node *np, else np->allocsize = blkroundup (length); - mutex_unlock (&np->dn->datalock); + rwlock_writer_unlock (&np->dn->datalock, np->dn); /* Now we can allow delayed copies again */ if (np->dn->fileinfo) @@ -183,7 +185,7 @@ diskfs_truncate (struct node *np, static void dindir_drop (struct node *np) { - mutex_lock (&np->dn->dinlock); + rwlock_writer_lock (&np->dn->dinlock, np->dn); pager_flush_some (dinpager->p, np->dn->number * sblock->fs_bsize, sblock->fs_bsize, 1); @@ -195,7 +197,7 @@ dindir_drop (struct node *np) np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; } - mutex_unlock (&np->dn->dinlock); + rwlock_writer_unlock (&np->dn->dinlock, np->dn); } @@ -208,7 +210,7 @@ sindir_drop (struct node *np, { int idx; - mutex_lock (&np->dn->sinlock); + rwlock_writer_lock (&np->dn->sinlock, np->dn); pager_flush_some (np->dn->sininfo->p, first * sblock->fs_bsize, (last - first + 1) * sblock->fs_bsize, 1); @@ -216,6 +218,7 @@ sindir_drop (struct node *np, /* Drop indirect blocks found in the double indirect block */ if (last > 1) { + mutex_lock (&dinmaplock); if (!np->dn->dinloc) din_map (np); for (idx = first; idx = last; idx++) @@ -231,8 +234,11 @@ sindir_drop (struct node *np, /* If we no longer need the double indirect block, drop it. */ if (first <= 1) dindir_drop (np); + + mutex_lock (&dinmaplock); if (!np->dn->sininfo) din_unmap (np); + mutex_unlock (&dinmaplock); } /* Drop the block from the inode if we don't need it any more */ @@ -242,7 +248,7 @@ sindir_drop (struct node *np, dinodes[np->dn->number].di_ib[INDIR_SINGLE] = 0; np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; } - mutex_unlock (&np->dn->sinlock); + rwlock_writer_unlock (&np->dn->sinlock, np->dn); } /* Write something to each page from START to END inclusive of memory @@ -296,7 +302,7 @@ diskfs_grow (struct node *np, if (end <= np->allocsize) return 0; - mutex_lock (&np->dn->datalock); + rwlock_writer_lock (&np->dn->datalock, np->dn); /* This deallocation works for the calls to alloc, but not for realloccg. I'm not sure how to prune the fragment down, especially if @@ -404,6 +410,7 @@ diskfs_grow (struct node *np, else { /* Make user the sindir area is mapped at the right size. */ + mutex_lock (&sinmaplock); if (np->dn->sinloc) { sin_remap (np, end); @@ -429,6 +436,7 @@ diskfs_grow (struct node *np, } if (!np->dn->fileinfo) sin_unmap (np); + mutex_unlock (&sinmaplock); } if (np->conch.holder) @@ -436,7 +444,7 @@ diskfs_grow (struct node *np, out: diskfs_end_catch_exception (); - mutex_unlock (&np->dn->datalock); + rwlock_writer_unlock (&np->dn->datalock, np->dn); /* Do the pokes and zeros that we requested before; they have to be done here because we can't cause a page while holding datalock. */ -- cgit v1.2.3 From db845bd31c563c05c718392a4de0d0900308a77c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 14 Jun 1994 18:41:03 +0000 Subject: Initial revision --- ufs/ufs.h | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 ufs/ufs.h (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h new file mode 100644 index 00000000..920134ef --- /dev/null +++ b/ufs/ufs.h @@ -0,0 +1,231 @@ +/* + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define this if memory objects should not be cached by the kernel. + Normally, don't define it, but defining it causes a much greater rate + of paging requests, which may be helpful in catching bugs. */ + +/* #undef DONT_CACHE_MEMORY_OBJECTS */ + + +/* Simple reader/writer lock. */ +struct rwlock +{ + int readers; + int writers_waiting; + int readers_waiting; +}; + +struct disknode +{ + ino_t number; + + /* For a directory, this array holds the number of directory entries in + each DIRBLKSIZE piece of the directory. */ + int *dirents; + + /* Links on hash list. */ + struct node *hnext, **hprevp; + + struct mutex rwlock_master; + struct condition rwlock_wakeup; + + struct rwlock dinlock; /* locks INDIR_DOUBLE pointer */ + + /* sinlock locks INDIR_SINGLE pointer and all the pointers in + the double indir block. */ + struct rwlock sinlock; + + /* datalock locks all the direct block pointers and all the pointers + in all the single indir blocks */ + struct rwlock datalock; + + /* These pointers are locked by sinmaplock and dinmaplock for all nodes. */ + daddr_t *dinloc; + daddr_t *sinloc; + + /* These two pointers are locked by pagernplock in pager.c for + all nodes. */ + struct user_pager_info *sininfo; + struct user_pager_info *fileinfo; +}; + +/* Get a reader lock on reader-writer lock LOCK for disknode DN */ +extern inline void +rwlock_reader_lock (struct rwlock *lock, + struct disknode *dn) +{ + mutex_lock (&dn->rwlock_master); + if (lock->readers == -1 || lock->writers_waiting) + { + lock->readers_waiting++; + do + condition_wait (&dn->rwlock_wakeup, &dn->rwlock_master); + while (lock->readers == -1 || lock->writers_waiting); + lock->readers_waiting--; + } + lock->readers++; + mutex_unlock (&dn->rwlock_master); +} + +/* Get a writer lock on reader-writer lock LOCK for disknode DN */ +extern inline void +rwlock_writer_lock (struct rwlock *lock, + struct disknode *dn) +{ + mutex_lock (&dn->rwlock_master); + if (lock->readers) + { + lock->writers_waiting++; + do + condition_wait (&dn->rwlock_wakeup, &dn->rwlock_master); + while (lock->readers); + lock->writers_waiting--; + } + lock->readers = -1; + mutex_unlock (&dn->rwlock_master); +} + +/* Release a reader lock on reader-writer lock LOCK for disknode DN */ +extern inline void +rwlock_reader_unlock (struct rwlock *lock, + struct disknode *dn) +{ + mutex_lock (&dn->rwlock_master); + assert (lock->readers); + lock->readers--; + if (lock->readers_waiting || lock->writers_waiting) + condition_broadcast (&dn->rwlock_wakeup); + mutex_unlock (&dn->rwlock_master); +} + +/* Release a writer lock on reader-writer lock LOCK for disknode DN */ +extern inline void +rwlock_writer_unlock (struct rwlock *lock, + struct disknode *dn) +{ + mutex_lock (&dn->rwlock_master); + assert (lock->readers == -1); + lock->readers = 0; + if (lock->readers_waiting || lock->writers_waiting) + condition_broadcast (&dn->rwlock_wakeup); + mutex_unlock (&dn->rwlock_master); +} + +/* Initialize reader-writer lock LOCK */ +extern inline void +rwlock_init (struct rwlock *lock) +{ + lock->readers = 0; + lock->readers_waiting = 0; + lock->writers_waiting = 0; +} + +struct user_pager_info +{ + struct node *np; + enum pager_type + { + DINODE, + CG, + SINDIR, + DINDIR, + FILE_DATA, + } type; + struct pager *p; + struct user_pager_info *next, **prevp; +}; + +struct user_pager_info *dinpager, *dinodepager, *cgpager; + +vm_address_t zeroblock; + +struct fs *sblock; +struct dinode *dinodes; +vm_address_t cgs; +struct csum *csum; +int sblock_dirty; +int csum_dirty; +spin_lock_t alloclock; + +struct mutex dinmaplock; +struct mutex sinmaplock; + +spin_lock_t gennumberlock; +int nextgennumber; + +mach_port_t ufs_device; + +#define DEV_BSIZE 512 +#define NBBY 8 +#define btodb(n) ((n) / DEV_BSIZE) +#define howmany(x,y) (((x)+((y)-1))/(y)) +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#define isclr(a, i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) +#define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) +#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) +#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<(i)%NBBY)) + +/* From alloc.c: */ +error_t alloc (struct node *, daddr_t, daddr_t, int, daddr_t *, + struct protid *); +void blkfree(volatile daddr_t bno, int size); +daddr_t blkpref (struct node *, daddr_t, int, daddr_t *); +error_t realloccg(struct node *, daddr_t, daddr_t, + int, int, daddr_t *, struct protid *); + +/* From devio.c: */ +error_t dev_write_sync (daddr_t addr, vm_address_t data, long len); +error_t dev_write (daddr_t addr, vm_address_t data, long len); +error_t dev_read_sync (daddr_t addr, vm_address_t *data, long len); + +/* From hyper.c: */ +void get_hypermetadata (void); + +/* From inode.c: */ +error_t iget (ino_t ino, struct node **NP); +struct node *ifind (ino_t ino); +void inode_init (void); +void write_all_disknodes (void); + +/* From pager.c: */ +void sync_dinode (struct node *, int); +void pager_init (void); +void din_map (struct node *); +void sin_map (struct node *); +void sin_remap (struct node *, int); +void sin_unmap (struct node *); +void din_unmap (struct node *); +void drop_pager_softrefs (struct node *); +void allow_pager_softrefs (struct node *); + +/* From subr.c: */ +void fragacct (int, long [], int); +int isblock(u_char *, daddr_t); +void clrblock(u_char *, daddr_t); +void setblock (u_char *, daddr_t); +int skpc (u_char, u_int, u_char *); +int scanc (u_int, u_char *, u_char [], u_char); -- cgit v1.2.3 From 4d7139cd7fc0425f9bd6fe11bf1e695ad39f04d4 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 15 Jun 1994 20:52:03 +0000 Subject: Formerly main.c.~11~ --- ufs/main.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 8c6114ed..e47586e7 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -112,6 +112,9 @@ main (int argc, char **argv) char *devname; mach_port_t bootstrap; error_t err; + int sizes[DEV_GET_SIZE_COUNT]; + u_int sizescnt = 2; + save_argv = argv; @@ -133,9 +136,31 @@ main (int argc, char **argv) (diskfs_readonly ? 0 : D_WRITE) | D_READ, devname, &ufs_device); assert (!err); + + /* Check to make sure device sector size is reasonable. */ + err = device_get_status (ufs_device, DEV_GET_SIZE, sizes, &sizescnt); + assert (sizescnt == DEV_GET_SIZE_COUNT); + if (sizes[DEV_GET_SIZE_RECORD_SIZE] != DEV_BSIZE) + { + fprintf (stderr, "Bad device record size %d (should be %d)\n", + sizes[DEV_GET_SIZE_RECORD_SIZE], DEV_BSIZE); + exit (1); + } get_hypermetadata (); + /* Check to make sure device size is big enough. */ + if (sizes[DEV_GET_SIZE_DEVICE_SIZE] != 0) + if (sizes[DEV_GET_SIZE_DEVICE_SIZE] < sblock->fs_size * sblock->fs_fsize) + { + fprintf (stderr, + "Disk size %d less than necessary " + "(superblock says we need %ld)\n", + sizes[DEV_GET_SIZE_DEVICE_SIZE], + sblock->fs_size * sblock->fs_fsize); + exit (1); + } + if (!diskfs_readonly) { sblock->fs_clean = 0; -- cgit v1.2.3 From 7efd71c161dd5fd099ec65db51c4b6fe972ffe90 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 21 Jun 1994 17:44:54 +0000 Subject: Initial revision --- ufs/dir.c | 861 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 861 insertions(+) create mode 100644 ufs/dir.c (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c new file mode 100644 index 00000000..d088778e --- /dev/null +++ b/ufs/dir.c @@ -0,0 +1,861 @@ +/* Directory management routines + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "ufs.h" +#include "dir.h" + +#include +#include + +enum slot_status +{ + /* This means we haven't yet found room for a new entry. */ + LOOKING, + + /* This means that the specified entry is free and should be used. */ + TAKE, + + /* This means that the specified entry has enough room at the end + to hold the new entry. */ + SHRINK, + + /* This means that there is enough space in the block, but not in + any one single entry, so they all have to be shifted to make + room. */ + COMPRESS, + + /* This means that the directory will have to be grown to hold the + entry. */ + EXTEND, + + /* For removal and rename, this means that this is the location + of the entry found. */ + HERE_TIS, +}; + +struct dirstat +{ + /* Type of followp operation expected */ + enum lookup_type type; + + /* One of the statuses above */ + enum slot_status stat; + + /* Mapped address and length of directory */ + vm_address_t mapbuf; + vm_size_t mapextent; + + /* Index of this directory block. */ + int idx; + + /* For stat COMPRESS, this is the address (inside mapbuf) + of the first direct in the directory block to be compressed. */ + /* For stat HERE_TIS, SHRINK, and TAKE, this is the entry referenced. */ + struct direct *entry; + + /* For stat HERE_TIS, type REMOVE, this is the address of the immediately + previous direct in this directory block, or zero if this is the first. */ + struct direct *preventry; +}; + +size_t diskfs_dirstat_size = sizeof (struct dirstat); + +static error_t +dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, + int namelen, enum lookup_type type, struct dirstat *ds, + ino_t *inum); + +/* Implement the diskfs_lookup from the diskfs library. See + for the interface specification. */ +error_t +diskfs_lookup (struct node *dp, char *name, enum lookup_type type, + struct node **npp, struct dirstat *ds, struct protid *cred) +{ + error_t err; + ino_t inum; + int namelen; + int spec_dotdot; + struct node *np = 0; + int retry_dotdot = 0; + memory_object_t memobj; + vm_address_t buf; + vm_size_t buflen; + int blockaddr; + int idx; + + if (npp) + *npp = 0; + + spec_dotdot = type & SPEC_DOTDOT; + type &= ~SPEC_DOTDOT; + + namelen = strlen (name); + + if (!S_ISDIR (dp->dn_stat.st_mode)) + return ENOTDIR; + err = diskfs_access (dp, S_IEXEC, cred); + if (err) + return err; + + try_again: + if (ds) + { + ds->type = LOOKUP; + ds->mapbuf = 0; + ds->mapextent = 0; + } + if (ds && (type == CREATE || type == RENAME)) + ds->stat = LOOKING; + + /* Map in the directory contents. */ + memobj = diskfs_get_filemap (dp); + mach_port_insert_right (mach_task_self (), memobj, memobj, + MACH_MSG_TYPE_MAKE_SEND); + buf = 0; + /* We allow extra space in case we have to do an EXTEND. */ + buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); + if (type == LOOKUP) + /* Map read-only; we won't be writing */ + err = vm_map (mach_task_self (), &buf, buflen, 0, 1, memobj, 0, 0, + VM_PROT_READ, VM_PROT_READ, 0); + else + err = vm_map (mach_task_self (), &buf, buflen, 0, 1, memobj, 0, 0, + VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0); + mach_port_deallocate (mach_task_self (), memobj); + + inum = 0; + + for (blockaddr = buf, idx = 0; + blockaddr - buf < dp->dn_stat.st_size; + blockaddr += DIRBLKSIZ, idx++) + { + err = dirscanblock (blockaddr, dp, idx, name, namelen, type, ds, &inum); + if (!err) + break; + if (err != ENOENT) + { + vm_deallocate (mach_task_self (), buf, buflen); + return err; + } + } + + /* If err is set here, it's ENOENT, and we don't want to + think about that as an error yet. */ + err = 0; + + if (inum) + { + if (namelen != 2 || name[0] != '.' || name[1] != '.') + { + if (inum == dp->dn->number) + { + np = dp; + diskfs_nref (np); + } + else + { + err = iget (inum, &np); + if (err) + goto out; + } + } + + /* We are looking up .. */ + /* Check to see if this is the root of the filesystem. */ + else if (dp->dn->number == 2) + { + err = EAGAIN; + goto out; + } + + /* We can't just do iget, because we would then deadlock. + So we do this. Ick. */ + else if (retry_dotdot) + { + /* Check to see that we got the same answer as last time. */ + if (inum != retry_dotdot) + { + /* Drop what we *thought* was .. (but isn't any more) and + try *again*. */ + diskfs_nput (np); + mutex_unlock (&dp->lock); + err = iget (inum, &np); + mutex_lock (&dp->lock); + if (err) + goto out; + retry_dotdot = inum; + goto try_again; + } + /* Otherwise, we got it fine and np is already set properly. */ + } + else if (!spec_dotdot) + { + /* Lock them in the proper order, and then + repeat the directory scan to see if this is still + right. */ + mutex_unlock (&dp->lock); + err = iget (inum, &np); + mutex_lock (&dp->lock); + if (err) + goto out; + retry_dotdot = inum; + goto try_again; + } + + /* Here below are the spec dotdot cases. */ + else if (type == RENAME || type == REMOVE) + np = ifind (inum); + + else if (type == LOOKUP) + { + diskfs_nput (dp); + err = iget (inum, &np); + if (err) + goto out; + } + else + assert (0); + } + + /* If we will be modifying the directory, make sure it's allowed. */ + if (type == RENAME + || (type == REMOVE && np) + || (type == CREATE && !np)) + { + err = diskfs_checkdirmod (dp, np, cred); + if (err) + goto out; + } + + if ((type == CREATE || type == RENAME) && !np && ds && ds->type == LOOKING) + { + /* We didn't find any room, so mark ds to extend the dir */ + ds->type = CREATE; + ds->stat = EXTEND; + ds->idx = idx; + } + + /* Return to the user; if we can't, release the reference + (and lock) we acquired above. */ + out: + /* Deallocate or save the mapping. */ + if ((err && err != ENOENT) + || !ds + || ds->type == LOOKUP) + vm_deallocate (mach_task_self (), buf, buflen); + else + { + ds->mapbuf = buf; + ds->mapextent = buflen; + } + + if (np) + { + if (err || !npp) + { + if (!spec_dotdot) + { + /* Normal case */ + if (np == dp) + diskfs_nrele (np); + else + diskfs_nput (np); + } + else if (type == RENAME || type == REMOVE) + /* We just did ifind to get np; that allocates + no new references, so we don't have anything to do */ + ; + else if (type == LOOKUP) + /* We did iget */ + diskfs_nput (np); + } + else if (npp) + *npp = np; + } + + return err ? : np ? 0 : ENOENT; +} + +/* Scan block at address BLKADDR (of node DP; block index IDX), for + name NAME of length NAMELEN. Args TYPE, DS are as for + diskfs_lookup. If found, set *INUM to the inode number, else + return ENOENT. */ +static error_t +dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, + int namelen, enum lookup_type type, + struct dirstat *ds, ino_t *inum) +{ + int nfree = 0; + int needed = 0; + int countup = 0; + vm_address_t currentoff, prevoff; + struct direct *entry; + int nentries = 0; + + if (ds && ds->stat == LOOKING) + { + countup = 1; + needed = DIRSIZ (namelen); + } + + for (currentoff = blockaddr, prevoff = blockaddr; + currentoff < blockaddr + DIRBLKSIZ; + prevoff = currentoff, currentoff += entry->d_reclen) + { + entry = (struct direct *)currentoff; + + if (!entry->d_reclen + || entry->d_reclen % 4 + || entry->d_namlen > MAXNAMLEN + || currentoff + entry->d_reclen > blockaddr + DIRBLKSIZ + || entry->d_name[entry->d_namlen] + || DIRSIZ (entry->d_namlen) > entry->d_reclen + || memchr (entry->d_name, '\0', entry->d_namlen)) + { + fprintf (stderr, "Bad directory entry: inode: %ld offset: %d\n", + dp->dn->number, currentoff - blockaddr); + return ENOENT; + } + + if (countup) + { + int thisfree; + + if (entry->d_ino == 0) + thisfree = entry->d_reclen; + else + thisfree = entry->d_reclen - DIRSIZ (entry->d_namlen); + + if (thisfree >= needed) + { + ds->type = CREATE; + ds->stat = entry->d_ino == 0 ? TAKE : SHRINK; + ds->entry = entry; + ds->idx = idx; + countup = 0; + } + else + { + nfree += thisfree; + if (nfree >= needed) + { + ds->type = CREATE; + ds->stat = COMPRESS; + ds->entry = (struct direct *) blockaddr; + ds->idx = idx; + countup = 0; + } + } + } + + if (entry->d_ino) + nentries++; + + if (entry->d_namlen == namelen + && entry->d_name[0] == name[0] + && entry->d_ino + && !bcmp (entry->d_name, name, namelen)) + break; + } + + if (currentoff >= blockaddr + DIRBLKSIZ) + { + int i; + /* The name is not in this block. */ + + /* Because we scanned the entire block, we should write + down how many entries there were. */ + if (!dp->dn->dirents) + { + dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ + 1) + * sizeof (int)); + for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) + dp->dn->dirents[i] = -1; + } + /* Make sure the count is correct if there is one now. */ + assert (dp->dn->dirents[idx] == -1 + || dp->dn->dirents[idx] == nentries); + dp->dn->dirents[idx] = nentries; + + return ENOENT; + } + + /* We have found the required name. */ + + if (ds && type == CREATE) + ds->type = LOOKUP; /* it's invalid now */ + else if (ds && (type == REMOVE || type == RENAME)) + { + ds->type = type; + ds->stat = HERE_TIS; + ds->entry = entry; + ds->idx = idx; + ds->preventry = (struct direct *) prevoff; + } + + *inum = entry->d_ino; + return 0; +} + +/* Following a lookup call for CREATE, this adds a node to a directory. + DP is the directory to be modified; NAME is the name to be entered; + NP is the node being linked in; DS is the cached information returned + by lookup; CRED describes the user making the call. This call may + only be made if the directory has been held locked continuously since + the preceding lookup call, and only if that call returned ENOENT. */ +error_t +diskfs_direnter(struct node *dp, + char *name, + struct node *np, + struct dirstat *ds, + struct protid *cred) +{ + struct direct *new; + int namelen = strlen (name); + int needed = DIRSIZ (namelen); + int oldneeded; + vm_address_t fromoff, tooff; + int totfreed; + error_t err; + + assert (ds->type == CREATE); + + switch (ds->stat) + { + case TAKE: + /* We are supposed to consume this slot. */ + assert (ds->entry->d_ino == 0 && ds->entry->d_reclen >= needed); + + ds->entry->d_ino = np->dn->number; + ds->entry->d_namlen = namelen; + bcopy (name, ds->entry->d_name, namelen + 1); + + break; + + case SHRINK: + /* We are supposed to take the extra space at the end + of this slot. */ + oldneeded = DIRSIZ (ds->entry->d_namlen); + assert (ds->entry->d_reclen - oldneeded >= needed); + + new = (struct direct *) ((vm_address_t) ds->entry + oldneeded); + + new->d_ino = np->dn->number; + new->d_reclen = ds->entry->d_reclen - oldneeded; + new->d_namlen = namelen; + bcopy (name, new->d_name, namelen + 1); + + ds->entry->d_reclen = oldneeded; + + break; + + case COMPRESS: + /* We are supposed to move all the entries to the + front of the block, giving each the minimum + necessary room. This should free up enough space + for the new entry. */ + fromoff = tooff = (vm_address_t) ds->entry; + + while (fromoff < (vm_address_t) ds->entry + DIRBLKSIZ) + { + struct direct *from = (struct direct *)fromoff; + struct direct *to = (struct direct *) tooff; + int fromreclen = from->d_reclen; + + if (from->d_ino != 0) + { + assert (fromoff >= tooff); + + bcopy (from, to, fromreclen); + to->d_reclen = DIRSIZ (to->d_namlen); + + tooff += to->d_reclen; + } + fromoff += fromreclen; + } + + totfreed = (vm_address_t) ds->entry + DIRBLKSIZ - tooff; + assert (totfreed >= needed); + + new = (struct direct *) tooff; + new->d_ino = np->dn->number; + new->d_reclen = totfreed; + new->d_namlen = namelen; + bcopy (name, new->d_name, namelen + 1); + break; + + case EXTEND: + /* Extend the file. */ + while (dp->dn_stat.st_size + DIRBLKSIZ > dp->allocsize) + if (err = diskfs_grow (dp, dp->dn_stat.st_size + DIRBLKSIZ, cred)) + { + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + return err; + } + + new = (struct direct *) (ds->mapbuf + dp->dn_stat.st_size); + + dp->dn_stat.st_size += DIRBLKSIZ; + dp->dn_set_ctime = 1; + + new->d_ino = np->dn->number; + new->d_reclen = DIRBLKSIZ; + new->d_namlen = namelen; + bcopy (name, new->d_name, namelen + 1); + break; + + default: + assert (0); + } + + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + + if (ds->stat != EXTEND) + { + /* If we are keeping count of this block, then keep the count up + to date. */ + if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) + dp->dn->dirents[ds->idx]++; + } + else + { + /* It's cheap, so start a count here even if we aren't counting + anything at all. */ + if (dp->dn->dirents) + { + dp->dn->dirents = realloc (dp->dn->dirents, + (ds->idx + 1) * sizeof (int)); + dp->dn->dirents[ds->idx] = 1; + } + else + { + int i; + dp->dn->dirents = malloc ((ds->idx + 1) * sizeof (int)); + for (i = 0; i < ds->idx; i++) + dp->dn->dirents[i] = -1; + dp->dn->dirents[ds->idx] = 1; + } + } + + diskfs_file_update (dp, 1); + + if (dp->dirmod_reqs) + diskfs_notice_dirchange (dp, DIR_CHANGED_NEW, name); + + return 0; +} + +/* Following a lookup call for REMOVE, this removes the link from the + directory. DP is the directory being changed and DS is the cached + information returned from lookup. This call is only valid if the + directory has been locked continously since the call to lookup, and + only if that call succeeded. */ +error_t +diskfs_dirremove(struct node *dp, + struct dirstat *ds) +{ + assert (ds->type == REMOVE); + assert (ds->stat == HERE_TIS); + + if (ds->preventry == 0) + ds->entry->d_ino = 0; + else + { + assert ((vm_address_t )ds->entry - (vm_address_t)ds->preventry + == ds->preventry->d_reclen); + ds->preventry->d_reclen += ds->entry->d_reclen; + } + + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + + /* If we are keeping count of this block, then keep the count up + to date. */ + if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) + dp->dn->dirents[ds->idx]--; + + diskfs_file_update (dp, 1); + + if (dp->dirmod_reqs) + diskfs_notice_dirchange (dp, DIR_CHANGED_UNLINK, ds->entry->d_name); + + return 0; +} + + +/* Following a lookup call for RENAME, this changes the inode number + on a directory entry. DP is the directory being changed; NP is + the new node being linked in; DP is the cached information returned + by lookup. This call is only valid if the directory has been locked + continuously since the call to lookup, and only if that call + succeeded. */ +error_t +diskfs_dirrewrite(struct node *dp, + struct node *np, + struct dirstat *ds) +{ + assert (ds->type == RENAME); + assert (ds->stat == HERE_TIS); + + ds->entry->d_ino = np->dn->number; + + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + + diskfs_file_update (dp, 1); + + if (dp->dirmod_reqs) + diskfs_notice_dirchange (dp, DIR_CHANGED_RENUMBER, ds->entry->d_name); + + return 0; +} + +/* Tell if DP is an empty directory (has only "." and ".." entries). */ +/* This routine must be called from inside a catch_exception (). */ +int +diskfs_dirempty(struct node *dp, + struct protid *cred) +{ + struct direct *entry; + int curoff; + vm_address_t buf; + memory_object_t memobj; + error_t err; + + memobj = diskfs_get_filemap (dp); + mach_port_insert_right (mach_task_self (), memobj, memobj, + MACH_MSG_TYPE_MAKE_SEND); + buf = 0; + + err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, + 1, memobj, 0, 0, VM_PROT_READ, VM_PROT_READ, 0); + mach_port_deallocate (mach_task_self (), memobj); + assert (!err); + + for (curoff = buf; + curoff < buf + dp->dn_stat.st_size; + curoff += entry->d_reclen) + { + entry = (struct direct *) curoff; + + if (entry->d_ino != 0 + && (entry->d_namlen > 2 + || entry->d_name[0] != '.' + || (entry->d_name[1] != '.' + && entry->d_name[1] != '\0'))) + { + vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + return 0; + } + } + vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + return 1; +} + +/* Make DS an invalid dirstat. */ +error_t +diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) +{ + if (ds->type != LOOKUP) + { + assert (ds->mapbuf); + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + ds->type = LOOKUP; + } + return 0; +} + + +/* Count the entries in directory block NB for directory DP and + write the answer down in its dirents array. As a side affect + fill BUF with the block. */ +static error_t +count_dirents (struct node *dp, int nb, char *buf) +{ + int amt; + char *offinblk; + struct direct *entry; + int count = 0; + error_t err; + + assert (dp->dn->dirents); + assert ((nb + 1) * DIRBLKSIZ <= dp->dn_stat.st_size); + + err = diskfs_node_rdwr (dp, buf, nb * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &amt); + if (err) + return err; + assert (amt == DIRBLKSIZ); + + for (offinblk = buf; + offinblk < buf + DIRBLKSIZ; + offinblk += entry->d_reclen) + { + entry = (struct direct *) offinblk; + if (entry->d_ino) + count++; + } + + assert (dp->dn->dirents[nb] == -1 || dp->dn->dirents[nb] == count); + dp->dn->dirents[nb] = count; + return 0; +} + +/* Implement the disikfs_get_directs callback as described in + . */ +error_t +diskfs_get_directs (struct node *dp, + int entry, + int nentries, + char **data, + u_int *datacnt, + vm_size_t bufsiz, + int *amt) +{ + int blkno; + int nblks; + int curentry; + char buf[DIRBLKSIZ]; + char *bufp; + int bufvalid; + error_t err; + int i; + char *datap; + struct direct *entryp; + int allocsize; + int checklen; + + nblks = dp->dn_stat.st_size/DIRBLKSIZ; + + if (!dp->dn->dirents) + { + dp->dn->dirents = malloc (nblks * sizeof (int)); + for (i = 0; i < nblks; i++) + dp->dn->dirents[i] = -1; + } + + /* Allocate enough space to hold the maximum we might return */ + if (!bufsiz || bufsiz > dp->dn_stat.st_size) + allocsize = round_page (dp->dn_stat.st_size); + else + allocsize = round_page (bufsiz); + + if (allocsize > *datacnt) + vm_allocate (mach_task_self (), (vm_address_t *) data, allocsize, 1); + + /* Scan through the entries to find ENTRY. If we encounter + a -1 in the process then stop to fill it. When we run + off the end, ENTRY is too big. */ + curentry = 0; + bufvalid = 0; + for (blkno = 0; blkno < nblks; blkno++) + { + if (dp->dn->dirents[blkno] == -1) + { + err = count_dirents (dp, blkno, buf); + if (err) + return err; + bufvalid = 1; + } + + if (curentry + dp->dn->dirents[blkno] > entry) + /* ENTRY starts in this block. */ + break; + + curentry += dp->dn->dirents[blkno]; + + bufvalid = 0; + } + + if (blkno == nblks) + { + *datacnt = 0; + *amt = 0; + return 0; + } + + /* Set bufp appropriately */ + bufp = buf; + if (curentry != entry) + { + /* Look through the block to find out where to start, + setting bufp appropriately. */ + if (!bufvalid) + { + err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, + 0, 0, &checklen); + if (err) + return err; + assert (checklen == DIRBLKSIZ); + bufvalid = 1; + } + for (i = 0, bufp = buf; + i < entry - curentry && bufp - buf < DIRBLKSIZ; + bufp += ((struct direct *)bufp)->d_reclen, i++) + ; + /* Make sure we didn't run off the end. */ + assert (bufp - buf < DIRBLKSIZ); + } + + i = 0; + datap = *data; + + /* Copy the entries, one at a time. */ + while (((nentries == -1) || (i < nentries)) + && (!bufsiz || (datap - *data < bufsiz) ) + && blkno < nblks) + { + if (!bufvalid) + { + err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, + 0, 0, &checklen); + if (err) + return err; + assert (checklen == DIRBLKSIZ); + bufvalid = 1; + bufp = buf; + } + + entryp = (struct direct *)bufp; + + if (entryp->d_ino) + { + bcopy (bufp, datap, DIRSIZ (entryp->d_namlen)); + i++; + datap += DIRSIZ (entryp->d_namlen); + } + + bufp += entryp->d_reclen; + if (bufp - buf == DIRBLKSIZ) + { + blkno++; + bufvalid = 0; + } + } + + /* We've copied all we can. If we allocated our own array + but didn't fill all of it, then free whatever memory we didn't use. */ + if (allocsize > *datacnt) + { + if (round_page (datap - *data) < allocsize) + vm_deallocate (mach_task_self (), + (vm_address_t) (*data + round_page (datap - *data)), + allocsize - round_page (datap - *data)); + } + + /* Set variables for return */ + *datacnt = datap - *data; + *amt = i; + return 0; +} -- cgit v1.2.3 From b1dfa8a8ab7adcfa953bd6cccff63bd224159471 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 5 Jul 1994 18:07:34 +0000 Subject: Formerly Makefile.~26~ --- ufs/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 7c3c6ca7..14a1260c 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -24,6 +24,8 @@ VPATH=.:../machine SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c +TAGSLIBS=libdiskfs libports libpager libioserver libfshelp libthreads + DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h ChangeLog OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o -- cgit v1.2.3 From 0188170d4e1ab74f3f0d1bb439de263beed1df2e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 6 Jul 1994 18:47:34 +0000 Subject: Formerly dir.c.~20~ --- ufs/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index d088778e..62bf3302 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -312,7 +312,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, needed = DIRSIZ (namelen); } - for (currentoff = blockaddr, prevoff = blockaddr; + for (currentoff = blockaddr, prevoff = 0; currentoff < blockaddr + DIRBLKSIZ; prevoff = currentoff, currentoff += entry->d_reclen) { @@ -575,7 +575,7 @@ diskfs_dirremove(struct node *dp, ds->entry->d_ino = 0; else { - assert ((vm_address_t )ds->entry - (vm_address_t)ds->preventry + assert ((vm_address_t) ds->entry - (vm_address_t) ds->preventry == ds->preventry->d_reclen); ds->preventry->d_reclen += ds->entry->d_reclen; } -- cgit v1.2.3 From b98b3ceaa0eb2636ae351c69eaafece9d51ac6fa Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 11 Jul 1994 22:14:23 +0000 Subject: Formerly dir.c.~21~ --- ufs/dir.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 62bf3302..c67d2ee1 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -832,6 +832,7 @@ diskfs_get_directs (struct node *dp, if (entryp->d_ino) { bcopy (bufp, datap, DIRSIZ (entryp->d_namlen)); + ((struct direct *)bufp)->d_reclen = DIRSIZ (entryp->d_namlen); i++; datap += DIRSIZ (entryp->d_namlen); } -- cgit v1.2.3 From 3aae8b86527ca8e2937d17827f0114087e8d250e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 16:35:21 +0000 Subject: Initial revision --- ufs/dir.h | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 ufs/dir.h (limited to 'ufs') diff --git a/ufs/dir.h b/ufs/dir.h new file mode 100644 index 00000000..c51bd1cf --- /dev/null +++ b/ufs/dir.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)dir.h 8.2 (Berkeley) 1/21/94 + */ + +#ifndef _DIR_H_ +#define _DIR_H_ + +/* + * A directory consists of some number of blocks of DIRBLKSIZ + * bytes, where DIRBLKSIZ is chosen such that it can be transferred + * to disk in a single atomic operation (e.g. 512 bytes on most machines). + * + * Each DIRBLKSIZ byte block contains some number of directory entry + * structures, which are of variable length. Each directory entry has + * a struct direct at the front of it, containing its inode number, + * the length of the entry, and the length of the name contained in + * the entry. These are followed by the name padded to a 4 byte boundary + * with null bytes. All names are guaranteed null terminated. + * The maximum length of a name in a directory is MAXNAMLEN. + * + * The macro DIRSIZ(fmt, dp) gives the amount of space required to represent + * a directory entry. Free space in a directory is represented by + * entries which have dp->d_reclen > DIRSIZ(fmt, dp). All DIRBLKSIZ bytes + * in a directory block are claimed by the directory entries. This + * usually results in the last entry in a directory having a large + * dp->d_reclen. When entries are deleted from a directory, the + * space is returned to the previous entry in the same directory + * block by increasing its dp->d_reclen. If the first entry of + * a directory block is free, then its dp->d_ino is set to 0. + * Entries other than the first in a directory do not normally have + * dp->d_ino set to 0. + */ +#define DIRBLKSIZ DEV_BSIZE +#define MAXNAMLEN 255 + +struct direct { + u_long d_ino; /* inode number of entry */ + u_short d_reclen; /* length of this record */ + u_char d_type; /* file type, see below */ + u_char d_namlen; /* length of string in d_name */ + char d_name[MAXNAMLEN + 1]; /* name with length <= MAXNAMLEN */ +}; + +/* + * File types + */ +#define DT_UNKNOWN 0 +#define DT_FIFO 1 +#define DT_CHR 2 +#define DT_DIR 4 +#define DT_BLK 6 +#define DT_REG 8 +#define DT_LNK 10 +#define DT_SOCK 12 + +/* + * Convert between stat structure types and directory types. + */ +#define IFTODT(mode) (((mode) & 0170000) >> 12) +#define DTTOIF(dirtype) ((dirtype) << 12) + +/* + * The DIRSIZ macro gives the minimum record length which will hold + * the directory entry. This requires the amount of space in struct direct + * without the d_name field, plus enough space for the name with a terminating + * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. + */ +#if (BYTE_ORDER == LITTLE_ENDIAN) +#define DIRSIZ(oldfmt, dp) \ + ((oldfmt) ? \ + ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_type+1 + 3) &~ 3)) : \ + ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))) +#else +#define DIRSIZ(oldfmt, dp) \ + ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) +#endif +#define OLDDIRFMT 1 +#define NEWDIRFMT 0 + +/* + * Template for manipulating directories. + * Should use struct direct's, but the name field + * is MAXNAMLEN - 1, and this just won't do. + */ +struct dirtemplate { + u_long dot_ino; + short dot_reclen; + u_char dot_type; + u_char dot_namlen; + char dot_name[4]; /* must be multiple of 4 */ + u_long dotdot_ino; + short dotdot_reclen; + u_char dotdot_type; + u_char dotdot_namlen; + char dotdot_name[4]; /* ditto */ +}; + +/* + * This is the old format of directories, sanz type element. + */ +struct odirtemplate { + u_long dot_ino; + short dot_reclen; + u_short dot_namlen; + char dot_name[4]; /* must be multiple of 4 */ + u_long dotdot_ino; + short dotdot_reclen; + u_short dotdot_namlen; + char dotdot_name[4]; /* ditto */ +}; +#endif /* !_DIR_H_ */ -- cgit v1.2.3 From 6894fbf72d3a6dd1bcd7eb86a1c7dbf9cdfb053a Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 16:56:24 +0000 Subject: Formerly dir.h.~2~ --- ufs/dir.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'ufs') diff --git a/ufs/dir.h b/ufs/dir.h index c51bd1cf..3fbb511a 100644 --- a/ufs/dir.h +++ b/ufs/dir.h @@ -1,3 +1,4 @@ +/* Modified from BSD by Michael I. Bushnell for GNU Hurd ufs server. */ /* * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -41,6 +42,8 @@ #ifndef _DIR_H_ #define _DIR_H_ +#include + /* * A directory consists of some number of blocks of DIRBLKSIZ * bytes, where DIRBLKSIZ is chosen such that it can be transferred @@ -95,12 +98,31 @@ struct direct { #define IFTODT(mode) (((mode) & 0170000) >> 12) #define DTTOIF(dirtype) ((dirtype) << 12) +/* Return the type from a struct direct, paying attention to whether + this filesystem supports the type extension */ +#define DIRECT_TYPE(dp) (direct_symlink_extension ? (dp)->d_type : DT_UNKNOWN) + +/* Return the namlen from a struct direct, paying attention to whether + this filesystem supports the type extension */ +#if (BYTE_ORDER == LITTLE_ENDIAN) +#define DIRECT_NAMLEN(dp) (direct_symlink_extension ? (dp)->d_namlen : \ + (dp)->d_type) +#else +#define DIRECT_NAMLEN(dp) ((dp)->d_namlen) +#endif + /* * The DIRSIZ macro gives the minimum record length which will hold * the directory entry. This requires the amount of space in struct direct * without the d_name field, plus enough space for the name with a terminating * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. */ +/* In BSD this macro takes a struct direct. Modified by MIB here to + take the namelen (as computed by strlen). */ +#define DIRSIZ(namelen) \ + ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((namelen)+1 + 3) &~ 3)) + +#if 0 /* This is the BSD definition */ #if (BYTE_ORDER == LITTLE_ENDIAN) #define DIRSIZ(oldfmt, dp) \ ((oldfmt) ? \ @@ -110,9 +132,12 @@ struct direct { #define DIRSIZ(oldfmt, dp) \ ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) #endif +#endif /* 0 */ + #define OLDDIRFMT 1 #define NEWDIRFMT 0 +#if 0 /* Not used in GNU */ /* * Template for manipulating directories. * Should use struct direct's, but the name field @@ -144,4 +169,6 @@ struct odirtemplate { u_short dotdot_namlen; char dotdot_name[4]; /* ditto */ }; +#endif /* 0 */ + #endif /* !_DIR_H_ */ -- cgit v1.2.3 From 260c89b51118b7f7e8d0119bd86c38e5fb9462de Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 17:05:43 +0000 Subject: Formerly dir.c.~22~ --- ufs/dir.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index c67d2ee1..9cbb42d5 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -320,11 +320,11 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, if (!entry->d_reclen || entry->d_reclen % 4 - || entry->d_namlen > MAXNAMLEN + || DIRECT_NAMLEN (entry) > MAXNAMLEN || currentoff + entry->d_reclen > blockaddr + DIRBLKSIZ - || entry->d_name[entry->d_namlen] - || DIRSIZ (entry->d_namlen) > entry->d_reclen - || memchr (entry->d_name, '\0', entry->d_namlen)) + || entry->d_name[DIRECT_NAMLEN (entry)] + || DIRSIZ (DIRECT_NAMLEN (entry)) > entry->d_reclen + || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { fprintf (stderr, "Bad directory entry: inode: %ld offset: %d\n", dp->dn->number, currentoff - blockaddr); @@ -338,7 +338,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, if (entry->d_ino == 0) thisfree = entry->d_reclen; else - thisfree = entry->d_reclen - DIRSIZ (entry->d_namlen); + thisfree = entry->d_reclen - DIRSIZ (DIRECT_NAMLEN (entry)); if (thisfree >= needed) { @@ -365,7 +365,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, if (entry->d_ino) nentries++; - if (entry->d_namlen == namelen + if (DIRECT_NAMLEN (entry) == namelen && entry->d_name[0] == name[0] && entry->d_ino && !bcmp (entry->d_name, name, namelen)) @@ -441,7 +441,9 @@ diskfs_direnter(struct node *dp, assert (ds->entry->d_ino == 0 && ds->entry->d_reclen >= needed); ds->entry->d_ino = np->dn->number; - ds->entry->d_namlen = namelen; + DIRECT_NAMLEN (ds->entry) = namelen; + if (direct_symlink_extension) + ds->d_type = IFTODT (np->dn->dn_stat.st_mode); bcopy (name, ds->entry->d_name, namelen + 1); break; @@ -449,14 +451,16 @@ diskfs_direnter(struct node *dp, case SHRINK: /* We are supposed to take the extra space at the end of this slot. */ - oldneeded = DIRSIZ (ds->entry->d_namlen); + oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); assert (ds->entry->d_reclen - oldneeded >= needed); new = (struct direct *) ((vm_address_t) ds->entry + oldneeded); new->d_ino = np->dn->number; new->d_reclen = ds->entry->d_reclen - oldneeded; - new->d_namlen = namelen; + DIRECT_NAMLEN (new) = namelen; + if (direct_symlink_extension) + ds->d_type = IFTODT (np->dn->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); ds->entry->d_reclen = oldneeded; @@ -481,7 +485,7 @@ diskfs_direnter(struct node *dp, assert (fromoff >= tooff); bcopy (from, to, fromreclen); - to->d_reclen = DIRSIZ (to->d_namlen); + to->d_reclen = DIRSIZ (DIRECT_NAMLEN (to)); tooff += to->d_reclen; } @@ -494,7 +498,9 @@ diskfs_direnter(struct node *dp, new = (struct direct *) tooff; new->d_ino = np->dn->number; new->d_reclen = totfreed; - new->d_namlen = namelen; + DIRECT_NAMLEN (new) = namelen; + if (direct_symlink_extension) + new->d_type = IFTODT (np->dn->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; @@ -514,7 +520,9 @@ diskfs_direnter(struct node *dp, new->d_ino = np->dn->number; new->d_reclen = DIRBLKSIZ; - new->d_namlen = namelen; + DIRECT_NAMLEN (new) = namelen; + if (direct_symlink_extension) + new->d_type = IFTODT (np->dn->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; @@ -611,6 +619,8 @@ diskfs_dirrewrite(struct node *dp, assert (ds->stat == HERE_TIS); ds->entry->d_ino = np->dn->number; + if (direct_symlink_extension) + ds->entry->d_type = IFTODT (np->dn->dn_stat.st_mode); vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); @@ -651,7 +661,7 @@ diskfs_dirempty(struct node *dp, entry = (struct direct *) curoff; if (entry->d_ino != 0 - && (entry->d_namlen > 2 + && (DIRECT_NAMLEN (entry) > 2 || entry->d_name[0] != '.' || (entry->d_name[1] != '.' && entry->d_name[1] != '\0'))) @@ -831,10 +841,10 @@ diskfs_get_directs (struct node *dp, if (entryp->d_ino) { - bcopy (bufp, datap, DIRSIZ (entryp->d_namlen)); - ((struct direct *)bufp)->d_reclen = DIRSIZ (entryp->d_namlen); + bcopy (bufp, datap, DIRSIZ (DIRECT_NAMLEN (entryp))); + ((struct direct *)bufp)->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); i++; - datap += DIRSIZ (entryp->d_namlen); + datap += DIRSIZ (DIRECT_NAMLEN (entryp)); } bufp += entryp->d_reclen; -- cgit v1.2.3 From 73612522ff8f67265361821d7ec757ad8b9bf5a8 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 17:06:33 +0000 Subject: Formerly dinode.h.~2~ --- ufs/dinode.h | 202 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 94 insertions(+), 108 deletions(-) (limited to 'ufs') diff --git a/ufs/dinode.h b/ufs/dinode.h index dfde2050..5b9915d9 100644 --- a/ufs/dinode.h +++ b/ufs/dinode.h @@ -1,122 +1,108 @@ -/* Format of an inode on disk - Copyright (C) 1991, 1993 Free Software Foundation - -This file is part of the GNU Hurd. - -The GNU Hurd is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -The GNU Hurd is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU Hurd; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Modified from UCB by Michael I. Bushnell. */ - /* - * Copyright (c) 1982, 1989 The Regents of the University of California. - * All rights reserved. + * Copyright (c) 1982, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * Redistribution is only permitted until one year after the first shipment - * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and - * binary forms are permitted provided that: (1) source distributions retain - * this entire copyright notice and comment, and (2) distributions including - * binaries display the following acknowledgement: This product includes - * software developed by the University of California, Berkeley and its - * contributors'' in the documentation or other materials provided with the - * distribution and in all advertising materials mentioning features or use - * of this software. Neither the name of the University nor the names of - * its contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. * - * @(#)dinode.h 7.9 (Berkeley) 6/28/90 + * @(#)dinode.h 8.3 (Berkeley) 1/21/94 */ /* - * This structure defines the on-disk format of an inode. + * The root inode is the root of the file system. Inode 0 can't be used for + * normal purposes and historically bad blocks were linked to inode 1, thus + * the root inode is 2. (Inode 1 is no longer used for this purpose, however + * numerous dump tapes make this assumption, so we are stuck with it). */ +#define ROOTINO ((ino_t)2) -#define NDADDR 12 /* direct addresses in inode */ -#define NIADDR 3 /* indirect addresses in inode */ +/* + * A dinode contains all the meta-data associated with a UFS file. + * This structure defines the on-disk format of a dinode. + */ -/* Indexes into di_ib */ -#define INDIR_SINGLE 0 -#define INDIR_DOUBLE 1 -#define INDIR_TRIPLE 2 /* NOT SUPPORTED */ +#define NDADDR 12 /* Direct addresses in inode. */ +#define NIADDR 3 /* Indirect addresses in inode. */ struct dinode { - u_short di_model; /* 0: mode and type of file (low bits) */ - nlink_t di_nlink; /* 2: number of links to file */ - u_short di_uidl; /* 4: owner's user id (low bits) */ - u_short di_gidl; /* 6: owner's group id (low bits) */ - u_quad di_qsize; /* 8: number of bytes in file */ - time_t di_atime; /* 16: time last accessed */ - long di_atusec; - time_t di_mtime; /* 24: time last modified */ - long di_mtusec; - time_t di_ctime; /* 32: last time inode changed */ - long di_ctusec; - daddr_t di_db[NDADDR]; /* 40: disk block addresses */ - daddr_t di_ib[NIADDR]; /* 88: indirect blocks */ - long di_flags; /* 100: status, currently unused */ - long di_blocks; /* 104: blocks actually held */ - long di_gen; /* 108: generation number */ - long di_trans; /* 112: filesystem tranlator */ - uid_t di_author; /* 116: author id */ - u_short di_uidh; /* 120: user id (high bits) */ - u_short di_gidh; /* 122: group id (high bits) */ - u_short di_modeh; /* 124: mode (high bits) */ - short di_spare; /* 126: reserved, currently unused */ + u_short di_mode; /* 0: IFMT and permissions. */ + short di_nlink; /* 2: File link count. */ + union { + u_short oldids[2]; /* 4: Ffs: old user and group ids. */ + ino_t inumber; /* 4: Lfs: inode number. */ + } di_u; + u_quad_t di_size; /* 8: File byte count. */ + struct timespec di_atime; /* 16: Last access time. */ + struct timespec di_mtime; /* 24: Last modified time. */ + struct timespec di_ctime; /* 32: Last inode change time. */ + daddr_t di_db[NDADDR]; /* 40: Direct disk blocks. */ + daddr_t di_ib[NIADDR]; /* 88: Indirect disk blocks. */ + u_long di_flags; /* 100: Status flags (chflags). */ + long di_blocks; /* 104: Blocks actually held. */ + long di_gen; /* 108: Generation number. */ + u_long di_uid; /* 112: File owner. */ + u_long di_gid; /* 116: File group. */ + long di_spare[2]; /* 120: Reserved; currently unused */ }; -#define DI_UID(di) ((di)->di_uidl | ((int)(di)->di_uidh << 16)) -#define DI_GID(di) ((di)->di_gidl | ((int)(di)->di_gidh << 16)) -#define DI_MODE(di) ((di)->di_model | ((int)(di)->di_modeh << 16)) - -#define LINK_MAX 32767 /* limited by width of nlink_t == 16 bits */ - -#if BYTE_ORDER == LITTLE_ENDIAN || defined(tahoe) /* ugh! -- must be fixed */ -#define di_size di_qsize.val[0] -#else /* BYTE_ORDER == BIG_ENDIAN */ -#define di_size di_qsize.val[1] -#endif +/* + * The di_db fields may be overlaid with other information for + * file types that do not have associated disk storage. Block + * and character devices overlay the first data block with their + * dev_t value. Short symbolic links place their path in the + * di_db area. + */ +#define di_inumber di_u.inumber +#define di_ogid di_u.oldids[1] +#define di_ouid di_u.oldids[0] #define di_rdev di_db[0] - -/* file modes -- these are known to match appropriate values in gnu/stat.h */ -#define IFMT 000000170000 /* type of file */ -#define IFIFO 000000010000 /* named pipe (fifo) */ -#define IFCHR 000000020000 /* character special */ -#define IFDIR 000000040000 /* directory */ -#define IFBLK 000000060000 /* block special */ -#define IFREG 000000100000 /* regular */ -#define IFLNK 000000120000 /* symbolic link */ -#define IFSOCK 000000140000 /* socket */ - -#define ISPEC 000000607000 /* special user-changeable bits */ -#define INOCACHE 000000400000 /* don't cache contents */ -#define IUSEUNK 000000200000 /* use IUNK in pref to IKNOWN */ -#define ISUID 000000004000 /* set user id on execution */ -#define ISGID 000000002000 /* set group id on execution */ -#define ISVTX 000000001000 /* caching preference / append only dir */ - -/* masks for various sets of permissions: */ -#define IOWNER 000000000700 /* owner of file */ -#define IGROUP 000000000070 /* group of file */ -#define IKNOWN 000000000007 /* anyone who possesses a uid */ -#define IUNKNOWN 000007000000 /* anyone who doesn't possess a uid */ - -#define ISPARE 037770000000 /* unused (yet) */ - -#define IREAD 0400 /* read, write, execute permissions */ -#define IWRITE 0200 -#define IEXEC 0100 - +#define di_shortlink di_db +#define MAXSYMLINKLEN ((NDADDR + NIADDR) * sizeof(daddr_t)) + +/* File modes. */ +#define IEXEC 0000100 /* Executable. */ +#define IWRITE 0000200 /* Writeable. */ +#define IREAD 0000400 /* Readable. */ +#define ISVTX 0001000 /* Sticky bit. */ +#define ISGID 0002000 /* Set-gid. */ +#define ISUID 0004000 /* Set-uid. */ + +/* File types. */ +#define IFMT 0170000 /* Mask of file type. */ +#define IFIFO 0010000 /* Named pipe (fifo). */ +#define IFCHR 0020000 /* Character device. */ +#define IFDIR 0040000 /* Directory file. */ +#define IFBLK 0060000 /* Block device. */ +#define IFREG 0100000 /* Regular file. */ +#define IFLNK 0120000 /* Symbolic link. */ +#define IFSOCK 0140000 /* UNIX domain socket. */ -- cgit v1.2.3 From f51bc401c3c327cd0548fdcbcd246b1e7c61e3c3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 19:06:35 +0000 Subject: Formerly main.c.~13~ --- ufs/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index e47586e7..de90cea8 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -33,6 +33,8 @@ char * trans_parse_args (int argc, char **arg) { #ifdef notyet + /* Option to set compat_mode should be provided here. */ + /* When started as a translator, we are called with the device name and an optional argument -r, which signifies read-only. */ @@ -128,6 +130,7 @@ main (int argc, char **argv) { devname = diskfs_parse_bootargs (argc, argv); diskfs_dotdot_file = MACH_PORT_NULL; + compat_mode = COMPAT_GNU; } diskfs_init_diskfs (); @@ -161,6 +164,13 @@ main (int argc, char **argv) exit (1); } + /* If the filesystem has new features in it, don't pay attention to + the user's request not to use them. */ + if ((sblock->fs_inodefmt == FS_44INODEFMT + || direct_symlink_extension) + && compat_mode == COMPAT_BSD42) + compat_mode = COMPAT_BSD44; + if (!diskfs_readonly) { sblock->fs_clean = 0; -- cgit v1.2.3 From 3de0751576921a5a92e23a6918ec4dcb3db3c670 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 19:50:21 +0000 Subject: Formerly hyper.c.~6~ --- ufs/hyper.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 7bb8d7c8..c9ffcc63 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -47,6 +47,13 @@ get_hypermetadata (void) exit (1); } + if (sblock->fs_maxsymlinklen > MAXSYMLINKLEN) + { + fprintf (stderr, "Max shortcut symlinklen %d is too big (max is %d)\n", + sblock->fs_maxsymlinklen, MAXSYMLINKLEN); + exit (1); + } + /* If this is an old filesystem, then we have some more work to do; some crucial constants might not be set; we are therefore forced to set them here. */ @@ -57,6 +64,12 @@ get_hypermetadata (void) if (sblock->fs_postblformat == FS_42POSTBLFMT) sblock->fs_nrpos = 8; + /* Find out if we support the 4.4 symlink/dirtype extension */ + if (sblock->fs_maxsymlinklen > 0) + direct_symlink_extension = 1; + else + direct_symlink_extension = 0; + err = dev_read_sync (fsbtodb (sblock->fs_csaddr), (vm_address_t *) &csum, sblock->fs_fsize * howmany (sblock->fs_cssize, sblock->fs_fsize)); -- cgit v1.2.3 From f786431d22c1a23eee19cd95a5e11400d21b5972 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 19:57:04 +0000 Subject: Formerly tables.c.~2~ --- ufs/tables.c | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) (limited to 'ufs') diff --git a/ufs/tables.c b/ufs/tables.c index 42badaed..8cf46b01 100644 --- a/ufs/tables.c +++ b/ufs/tables.c @@ -1,26 +1,40 @@ -/* Tables for fast computation */ /* - * Copyright (c) 1982, 1986 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. * - * Redistribution is only permitted until one year after the first shipment - * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and - * binary forms are permitted provided that: (1) source distributions retain - * this entire copyright notice and comment, and (2) distributions including - * binaries display the following acknowledgement: This product includes - * software developed by the University of California, Berkeley and its - * contributors'' in the documentation or other materials provided with the - * distribution and in all advertising materials mentioning features or use - * of this software. Neither the name of the University nor the names of - * its contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * @(#)ufs_tables.c 7.4 (Berkeley) 6/28/90 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ffs_tables.c 8.1 (Berkeley) 6/11/93 */ +#include + /* * Bit patterns for identifying fragments in the block map * used as ((map & around) == inside) -- cgit v1.2.3 From 402cdd294459937e6c5d17778321930f3d0f971f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 19:59:03 +0000 Subject: Formerly subr.c.~3~ --- ufs/subr.c | 230 +++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 140 insertions(+), 90 deletions(-) (limited to 'ufs') diff --git a/ufs/subr.c b/ufs/subr.c index 25990835..c251b16e 100644 --- a/ufs/subr.c +++ b/ufs/subr.c @@ -1,75 +1,109 @@ -/* Miscellaneous map manipulation routines - Copyright (C) 1991, 1992, 1994 Free Software Foundation - -This file is part of the GNU Hurd. - -The GNU Hurd is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -The GNU Hurd is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU Hurd; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Slightly modified from UCB by Michael I. Bushnell. */ - /* - * Copyright (c) 1982, 1986, 1989 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * Redistribution is only permitted until one year after the first shipment - * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and - * binary forms are permitted provided that: (1) source distributions retain - * this entire copyright notice and comment, and (2) distributions including - * binaries display the following acknowledgement: This product includes - * software developed by the University of California, Berkeley and its - * contributors'' in the documentation or other materials provided with the - * distribution and in all advertising materials mentioning features or use - * of this software. Neither the name of the University nor the names of - * its contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. * - * @(#)ufs_subr.c 7.13 (Berkeley) 6/28/90 + * @(#)ffs_subr.c 8.2 (Berkeley) 9/21/93 */ -#include "ufs.h" -#include "fs.h" +#include +#include +#ifdef KERNEL +#include +#include +#include +#include +#include +#include -extern int around[9]; -extern int inside[9]; -extern u_char *fragtbl[]; +/* + * Return buffer with the contents of block "offset" from the beginning of + * directory "ip". If "res" is non-zero, fill it in with a pointer to the + * remaining space in the directory. + */ +int +ffs_blkatoff(ap) + struct vop_blkatoff_args /* { + struct vnode *a_vp; + off_t a_offset; + char **a_res; + struct buf **a_bpp; + } */ *ap; +{ + struct inode *ip; + register struct fs *fs; + struct buf *bp; + daddr_t lbn; + int bsize, error; + + ip = VTOI(ap->a_vp); + fs = ip->i_fs; + lbn = lblkno(fs, ap->a_offset); + bsize = blksize(fs, ip, lbn); + + *ap->a_bpp = NULL; + if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) { + brelse(bp); + return (error); + } + if (ap->a_res) + *ap->a_res = (char *)bp->b_data + blkoff(fs, ap->a_offset); + *ap->a_bpp = bp; + return (0); +} +#endif /* * Update the frsum fields to reflect addition or deletion * of some frags. */ void -fragacct(int fragmap, - long fraglist[], - int cnt) +ffs_fragacct(fs, fragmap, fraglist, cnt) + struct fs *fs; + int fragmap; + long fraglist[]; + int cnt; { int inblk; - int field, subfield; - int siz, pos; + register int field, subfield; + register int siz, pos; - inblk = (int)(fragtbl[sblock->fs_frag][fragmap]) << 1; + inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1; fragmap <<= 1; - for (siz = 1; siz < sblock->fs_frag; siz++) { - if ((inblk & (1 << (siz + (sblock->fs_frag % NBBY)))) == 0) + for (siz = 1; siz < fs->fs_frag; siz++) { + if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) continue; field = around[siz]; subfield = inside[siz]; - for (pos = siz; pos <= sblock->fs_frag; pos++) { + for (pos = siz; pos <= fs->fs_frag; pos++) { if ((fragmap & field) == subfield) { fraglist[siz] += cnt; pos += siz; @@ -82,18 +116,54 @@ fragacct(int fragmap, } } +#if defined(KERNEL) && defined(DIAGNOSTIC) +void +ffs_checkoverlap(bp, ip) + struct buf *bp; + struct inode *ip; +{ + register struct buf *ebp, *ep; + register daddr_t start, last; + struct vnode *vp; + + ebp = &buf[nbuf]; + start = bp->b_blkno; + last = start + btodb(bp->b_bcount) - 1; + for (ep = buf; ep < ebp; ep++) { + if (ep == bp || (ep->b_flags & B_INVAL) || + ep->b_vp == NULLVP) + continue; + if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL)) + continue; + if (vp != ip->i_devvp) + continue; + /* look for overlap */ + if (ep->b_bcount == 0 || ep->b_blkno > last || + ep->b_blkno + btodb(ep->b_bcount) <= start) + continue; + vprint("Disk overlap", vp); + (void)printf("\tstart %d, end %d overlap start %d, end %d\n", + start, last, ep->b_blkno, + ep->b_blkno + btodb(ep->b_bcount) - 1); + panic("Disk buffer overlap"); + } +} +#endif /* DIAGNOSTIC */ + /* * block operations * * check if a block is available */ int -isblock(u_char *cp, - daddr_t h) +ffs_isblock(fs, cp, h) + struct fs *fs; + unsigned char *cp; + daddr_t h; { - u_char mask; + unsigned char mask; - switch ((int)sblock->fs_frag) { + switch ((int)fs->fs_frag) { case 8: return (cp[h] == 0xff); case 4: @@ -106,7 +176,7 @@ isblock(u_char *cp, mask = 0x01 << (h & 0x7); return ((cp[h >> 3] & mask) == mask); default: - assert (0); + panic("ffs_isblock"); } } @@ -114,11 +184,13 @@ isblock(u_char *cp, * take a block out of the map */ void -clrblock(u_char *cp, - daddr_t h) +ffs_clrblock(fs, cp, h) + struct fs *fs; + u_char *cp; + daddr_t h; { - switch ((int)sblock->fs_frag) { + switch ((int)fs->fs_frag) { case 8: cp[h] = 0; return; @@ -132,7 +204,7 @@ clrblock(u_char *cp, cp[h >> 3] &= ~(0x01 << (h & 0x7)); return; default: - assert (0); + panic("ffs_clrblock"); } } @@ -140,10 +212,13 @@ clrblock(u_char *cp, * put a block into the map */ void -setblock(u_char *cp, - daddr_t h) +ffs_setblock(fs, cp, h) + struct fs *fs; + unsigned char *cp; + daddr_t h; { - switch ((int)sblock->fs_frag) { + + switch ((int)fs->fs_frag) { case 8: cp[h] = 0xff; @@ -158,31 +233,6 @@ setblock(u_char *cp, cp[h >> 3] |= (0x01 << (h & 0x7)); return; default: - assert (0); + panic("ffs_setblock"); } } - -int -skpc(u_char mask, - u_int size, - u_char *cp) -{ - u_char *end = &cp[size]; - - while (cp < end && *cp == mask) - cp++; - return (end - cp); -} - -int -scanc(u_int size, - u_char *cp, - u_char table[], - u_char mask) -{ - register u_char *end = &cp[size]; - - while (cp < end && (table[*cp] & mask) == 0) - cp++; - return (end - cp); -} -- cgit v1.2.3 From c47254e1358967fbaeb572f1c9ee1b8f9aae0250 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 19:59:56 +0000 Subject: Formerly tables.c.~3~ --- ufs/tables.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/tables.c b/ufs/tables.c index 8cf46b01..81e3c25c 100644 --- a/ufs/tables.c +++ b/ufs/tables.c @@ -1,3 +1,4 @@ +/* Modified from BSD for GNU Hurd ufs server by Michael I. Bushnell. */ /* * Copyright (c) 1982, 1986, 1993 * The Regents of the University of California. All rights reserved. @@ -33,7 +34,8 @@ * @(#)ffs_tables.c 8.1 (Berkeley) 6/11/93 */ -#include +#include "ufs.h" +#include "fs.h" /* * Bit patterns for identifying fragments in the block map -- cgit v1.2.3 From aa2749bf3335097364c7ff4e607bb5d544646b18 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 20:00:26 +0000 Subject: Formerly dinode.h.~3~ --- ufs/dinode.h | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'ufs') diff --git a/ufs/dinode.h b/ufs/dinode.h index 5b9915d9..8f9dae0e 100644 --- a/ufs/dinode.h +++ b/ufs/dinode.h @@ -1,3 +1,20 @@ +/* + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* * Copyright (c) 1982, 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -55,12 +72,13 @@ #define NIADDR 3 /* Indirect addresses in inode. */ struct dinode { - u_short di_mode; /* 0: IFMT and permissions. */ + u_short di_model; /* 0: IFMT and permissions. */ short di_nlink; /* 2: File link count. */ - union { - u_short oldids[2]; /* 4: Ffs: old user and group ids. */ - ino_t inumber; /* 4: Lfs: inode number. */ - } di_u; + union + { + u_long diu_author; /* 4: File author */ + u_short diu_oldids[2]; /* Old format uid and gid */ + } di_u; u_quad_t di_size; /* 8: File byte count. */ struct timespec di_atime; /* 16: Last access time. */ struct timespec di_mtime; /* 24: Last modified time. */ @@ -72,9 +90,15 @@ struct dinode { long di_gen; /* 108: Generation number. */ u_long di_uid; /* 112: File owner. */ u_long di_gid; /* 116: File group. */ - long di_spare[2]; /* 120: Reserved; currently unused */ + u_short di_modeh; /* 120: Mode high bits */ + u_short di_spare; /* 122: unused */ + long di_trans; /* 124: filesystem translator */ }; +#define di_author di_u.diu_author /* GNU extension */ +#define di_ouid di_u.diu_oldids[0] +#define di_ogid di_u.diu_oldids[1] + /* * The di_db fields may be overlaid with other information for * file types that do not have associated disk storage. Block @@ -82,9 +106,6 @@ struct dinode { * dev_t value. Short symbolic links place their path in the * di_db area. */ -#define di_inumber di_u.inumber -#define di_ogid di_u.oldids[1] -#define di_ouid di_u.oldids[0] #define di_rdev di_db[0] #define di_shortlink di_db #define MAXSYMLINKLEN ((NDADDR + NIADDR) * sizeof(daddr_t)) -- cgit v1.2.3 From 8f9cbf53b9c8da56e2ea60b638627597f08cc175 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 20:06:40 +0000 Subject: Formerly fs.h.~3~ --- ufs/fs.h | 317 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 176 insertions(+), 141 deletions(-) (limited to 'ufs') diff --git a/ufs/fs.h b/ufs/fs.h index 2efc6910..bef052fe 100644 --- a/ufs/fs.h +++ b/ufs/fs.h @@ -1,44 +1,36 @@ -/* Format of a filesystem on disk (superblock and cylinder groups) - Copyright (C) 1991, 1993, 1994 Free Software Foundation - -This file is part of the GNU Hurd. - -The GNU Hurd is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -The GNU Hurd is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU Hurd; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Modified from UCB by Michael I. Bushnell. */ - /* - * Copyright (c) 1982, 1986 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * Redistribution is only permitted until one year after the first shipment - * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and - * binary forms are permitted provided that: (1) source distributions retain - * this entire copyright notice and comment, and (2) distributions including - * binaries display the following acknowledgement: This product includes - * software developed by the University of California, Berkeley and its - * contributors'' in the documentation or other materials provided with the - * distribution and in all advertising materials mentioning features or use - * of this software. Neither the name of the University nor the names of - * its contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. * - * @(#)fs.h 7.10 (Berkeley) 6/28/90 + * @(#)fs.h 8.7 (Berkeley) 4/19/94 */ /* @@ -89,15 +81,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ * * The file system records space availability at the fragment level; * to determine block availability, aligned fragments are examined. - * - * The root inode is the root of the file system. - * Inode 0 can't be used for normal purposes and - * historically bad blocks were linked to inode 1, - * thus the root inode is 2. (inode 1 is no longer used for - * this purpose, however numerous dump tapes make this - * assumption, so we are stuck with it) */ -#define ROOTINO ((ino_t)2) /* i number of all roots */ /* * MINBSIZE is the smallest allowable block size. @@ -120,7 +104,29 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ */ #define MAXMNTLEN 512 #define MAXCSBUFS 32 -#define MAXFRAG 8 + +/* + * A summary of contiguous blocks of various sizes is maintained + * in each cylinder group. Normally this is set by the initial + * value of fs_maxcontig. To conserve space, a maximum summary size + * is set by FS_MAXCONTIG. + */ +#define FS_MAXCONTIG 16 + +/* + * MINFREE gives the minimum acceptable percentage of file system + * blocks which may be free. If the freelist drops below this level + * only the superuser may continue to allocate blocks. This may + * be set to 0 if no reserve of free blocks is deemed necessary, + * however throughput drops by fifty percent if the file system + * is run at between 95% and 100% full; thus the minimum default + * value of fs_minfree is 5%. However, to get good clustering + * performance, 10% is a better choice. hence we use 10% as our + * default value. With 10% free space, fragmentation is not a + * problem, so we choose to optimize for time. + */ +#define MINFREE 5 +#define DEFAULTOPT FS_OPTTIME /* * Per cylinder group information; summarized in blocks allocated @@ -141,10 +147,7 @@ struct csum { /* * Super block for a file system. */ -#define FS_MAGIC 0x011954 -#define FSOKAY 0x7c269d38 -struct fs -{ +struct fs { struct fs *fs_link; /* linked list of file systems */ struct fs *fs_rlink; /* used for incore super blocks */ daddr_t fs_sblkno; /* addr of super-block in filesys */ @@ -153,7 +156,7 @@ struct fs daddr_t fs_dblkno; /* offset of first data after cg */ long fs_cgoffset; /* cylinder group offset in cylinder */ long fs_cgmask; /* used to calc mod fs_ntrak */ - long fs_time; /* last time written */ + time_t fs_time; /* last time written */ long fs_size; /* number of blocks in fs */ long fs_dsize; /* number of data blocks in fs */ long fs_ncg; /* number of cylinder groups */ @@ -216,18 +219,29 @@ struct fs struct csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */ long fs_cpc; /* cyl per cycle in postbl */ short fs_opostbl[16][8]; /* old rotation block list head */ - long fs_sparecon[55]; /* reserved for future constants */ + long fs_sparecon[50]; /* reserved for future constants */ + long fs_contigsumsize; /* size of cluster summary array */ + long fs_maxsymlinklen; /* max length of an internal symlink */ + long fs_inodefmt; /* format of on-disk inodes */ + u_quad_t fs_maxfilesize; /* maximum representable file size */ + quad_t fs_qbmask; /* ~fs_bmask - for use with quad size */ + quad_t fs_qfmask; /* ~fs_fmask - for use with quad size */ long fs_state; /* validate fs_clean field */ - quad fs_qbmask; /* ~fs_bmask - for use with quad size */ - quad fs_qfmask; /* ~fs_fmask - for use with quad size */ long fs_postblformat; /* format of positional layout tables */ - long fs_nrpos; /* number of rotaional positions */ + long fs_nrpos; /* number of rotational positions */ long fs_postbloff; /* (short) rotation block list head */ long fs_rotbloff; /* (u_char) blocks for each rotation */ long fs_magic; /* magic number */ - unsigned char fs_space[1]; /* list of blocks for each rotation */ + u_char fs_space[1]; /* list of blocks for each rotation */ /* actually longer */ }; +/* + * Filesystem idetification + */ +#define FS_MAGIC 0x011954 /* the fast filesystem magic number */ +#define FS_OKAY 0x7c269d38 /* superblock checksum */ +#define FS_42INODEFMT -1 /* 4.2BSD inode format */ +#define FS_44INODEFMT 2 /* 4.4BSD inode format */ /* * Preference for optimization. */ @@ -242,23 +256,38 @@ struct fs /* * Macros for access to superblock array structures */ -#define fs_postbl(cylno) \ - ((sblock->fs_postblformat == FS_42POSTBLFMT) \ - ? (sblock->fs_opostbl[cylno]) \ - : ((short *)((char *)sblock + sblock->fs_postbloff) \ - + (cylno) * sblock->fs_nrpos)) -#define fs_rotbl \ - ((sblock->fs_postblformat == FS_42POSTBLFMT) \ - ? (sblock->fs_space) \ - : ((unsigned char *)((char *)sblock + sblock->fs_rotbloff))) +#define fs_postbl(fs, cylno) \ + (((fs)->fs_postblformat == FS_42POSTBLFMT) \ + ? ((fs)->fs_opostbl[cylno]) \ + : ((short *)((char *)(fs) + (fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos)) +#define fs_rotbl(fs) \ + (((fs)->fs_postblformat == FS_42POSTBLFMT) \ + ? ((fs)->fs_space) \ + : ((u_char *)((char *)(fs) + (fs)->fs_rotbloff))) + +/* + * The size of a cylinder group is calculated by CGSIZE. The maximum size + * is limited by the fact that cylinder groups are at most one block. + * Its size is derived from the size of the maps maintained in the + * cylinder group and the (struct cg) size. + */ +#define CGSIZE(fs) \ + /* base cg */ (sizeof(struct cg) + sizeof(long) + \ + /* blktot size */ (fs)->fs_cpg * sizeof(long) + \ + /* blks size */ (fs)->fs_cpg * (fs)->fs_nrpos * sizeof(short) + \ + /* inode map */ howmany((fs)->fs_ipg, NBBY) + \ + /* block map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY) +\ + /* if present */ ((fs)->fs_contigsumsize <= 0 ? 0 : \ + /* cluster sum */ (fs)->fs_contigsumsize * sizeof(long) + \ + /* cluster map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPB(fs), NBBY))) /* * Convert cylinder group to base address of its global summary info. * * N.B. This macro assumes that sizeof(struct csum) is a power of two. */ -#define fs_cs(indx) \ - fs_csp[(indx) >> sblock->fs_csshift][(indx) & ~sblock->fs_csmask] +#define fs_cs(fs, indx) \ + fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask] /* * Cylinder group block for a file system. @@ -267,7 +296,7 @@ struct fs struct cg { struct cg *cg_link; /* linked list of cyl groups */ long cg_magic; /* magic number */ - long cg_time; /* time last written */ + time_t cg_time; /* time last written */ long cg_cgx; /* we are the cgx'th cylinder group */ short cg_ncyl; /* number of cyl's this cg */ short cg_niblk; /* number of inode blocks this cg */ @@ -282,8 +311,11 @@ struct cg { long cg_iusedoff; /* (char) used inode map */ long cg_freeoff; /* (u_char) free block map */ long cg_nextfreeoff; /* (u_char) next available space */ - long cg_sparecon[16]; /* reserved for future use */ - unsigned char cg_space[1]; /* space for cylinder group maps */ + long cg_clustersumoff; /* (long) counts of avail clusters */ + long cg_clusteroff; /* (char) free cluster map */ + long cg_nclusterblks; /* number of clusters this cg */ + long cg_sparecon[13]; /* reserved for future use */ + u_char cg_space[1]; /* space for cylinder group maps */ /* actually longer */ }; /* @@ -293,10 +325,10 @@ struct cg { (((cgp)->cg_magic != CG_MAGIC) \ ? (((struct ocg *)(cgp))->cg_btot) \ : ((long *)((char *)(cgp) + (cgp)->cg_btotoff))) -#define cg_blks(cgp, cylno) \ +#define cg_blks(fs, cgp, cylno) \ (((cgp)->cg_magic != CG_MAGIC) \ ? (((struct ocg *)(cgp))->cg_b[cylno]) \ - : ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * sblock->fs_nrpos)) + : ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos)) #define cg_inosused(cgp) \ (((cgp)->cg_magic != CG_MAGIC) \ ? (((struct ocg *)(cgp))->cg_iused) \ @@ -304,9 +336,13 @@ struct cg { #define cg_blksfree(cgp) \ (((cgp)->cg_magic != CG_MAGIC) \ ? (((struct ocg *)(cgp))->cg_free) \ - : ((unsigned char *)((char *)(cgp) + (cgp)->cg_freeoff))) + : ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff))) #define cg_chkmagic(cgp) \ ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC) +#define cg_clustersfree(cgp) \ + ((u_char *)((char *)(cgp) + (cgp)->cg_clusteroff)) +#define cg_clustersum(cgp) \ + ((long *)((char *)(cgp) + (cgp)->cg_clustersumoff)) /* * The following structure is defined @@ -315,7 +351,7 @@ struct cg { struct ocg { struct ocg *cg_link; /* linked list of cyl groups */ struct ocg *cg_rlink; /* used for incore cyl groups */ - long cg_time; /* time last written */ + time_t cg_time; /* time last written */ long cg_cgx; /* we are the cgx'th cylinder group */ short cg_ncyl; /* number of cyl's this cg */ short cg_niblk; /* number of inode blocks this cg */ @@ -329,7 +365,7 @@ struct ocg { short cg_b[32][8]; /* positions of free blocks */ char cg_iused[256]; /* used inode map */ long cg_magic; /* magic number */ - unsigned char cg_free[1]; /* free block map */ + u_char cg_free[1]; /* free block map */ /* actually longer */ }; @@ -337,20 +373,20 @@ struct ocg { * Turn file system block numbers into disk block addresses. * This maps file system blocks to device size blocks. */ -#define fsbtodb(b) ((b) << sblock->fs_fsbtodb) -#define dbtofsb(b) ((b) >> sblock->fs_fsbtodb) +#define fsbtodb(fs, b) ((b) << (fs)->fs_fsbtodb) +#define dbtofsb(fs, b) ((b) >> (fs)->fs_fsbtodb) /* * Cylinder group macros to locate things in cylinder groups. * They calc file system addresses of cylinder group data structures. */ -#define cgbase(c) ((daddr_t)(sblock->fs_fpg * (c))) -#define cgstart(c) \ - (cgbase(c) + sblock->fs_cgoffset * ((c) & ~(sblock->fs_cgmask))) -#define cgsblock(c) (cgstart(c) + sblock->fs_sblkno) /* super blk */ -#define cgtod(c) (cgstart(c) + sblock->fs_cblkno) /* cg block */ -#define cgimin(c) (cgstart(c) + sblock->fs_iblkno) /* inode blk */ -#define cgdmin(c) (cgstart(c) + sblock->fs_dblkno) /* 1st data */ +#define cgbase(fs, c) ((daddr_t)((fs)->fs_fpg * (c))) +#define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */ +#define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */ +#define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */ +#define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */ +#define cgstart(fs, c) \ + (cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask))) /* * Macros for handling inode numbers: @@ -358,97 +394,96 @@ struct ocg { * inode number to cylinder group number. * inode number to file system block address. */ -#define itoo(x) ((x) % INOPB) -#define itog(x) ((x) / sblock->fs_ipg) -#define itod(x) \ - ((daddr_t)(cgimin(itog(x)) + \ - (blkstofrags((((x) % sblock->fs_ipg) / INOPB))))) +#define ino_to_cg(fs, x) ((x) / (fs)->fs_ipg) +#define ino_to_fsba(fs, x) \ + ((daddr_t)(cgimin(fs, ino_to_cg(fs, x)) + \ + (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs)))))) +#define ino_to_fsbo(fs, x) ((x) % INOPB(fs)) /* * Give cylinder group number for a file system block. * Give cylinder group block number for a file system block. */ -#define dtog(d) ((d) / sblock->fs_fpg) -#define dtogd(d) ((d) % sblock->fs_fpg) +#define dtog(fs, d) ((d) / (fs)->fs_fpg) +#define dtogd(fs, d) ((d) % (fs)->fs_fpg) /* * Extract the bits for a block from a map. * Compute the cylinder and rotational position of a cyl block addr. */ -#define blkmap(map, loc) \ - (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - sblock->fs_frag))) -#define cbtocylno(bno) \ - ((bno) * NSPF / sblock->fs_spc) -#define cbtorpos(bno) \ - (((bno) * NSPF % sblock->fs_spc / sblock->fs_nsect * sblock->fs_trackskew + \ - (bno) * NSPF % sblock->fs_spc % sblock->fs_nsect * sblock->fs_interleave) % \ - sblock->fs_nsect * sblock->fs_nrpos / sblock->fs_npsect) +#define blkmap(fs, map, loc) \ + (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag))) +#define cbtocylno(fs, bno) \ + ((bno) * NSPF(fs) / (fs)->fs_spc) +#define cbtorpos(fs, bno) \ + (((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \ + (bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \ + (fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect) /* * The following macros optimize certain frequently calculated * quantities by using shifts and masks in place of divisions * modulos and multiplications. */ -#define blkoff(loc) /* calculates (loc % fs->fs_bsize) */ \ - ((loc) & ~sblock->fs_bmask) -#define fragoff(loc) /* calculates (loc % fs->fs_fsize) */ \ - ((loc) & ~sblock->fs_fmask) -#define lblktosize(blk) /* calculates (blk * fs->fs_bsize) */ \ - ((blk) << sblock->fs_bshift) -#define lblkno(loc) /* calculates (loc / fs->fs_bsize) */ \ - ((loc) >> sblock->fs_bshift) -#define numfrags(loc) /* calculates (loc / fs->fs_fsize) */ \ - ((loc) >> sblock->fs_fshift) -#define blkroundup(size) /* calculates roundup(size, fs->fs_bsize) */ \ - (((size) + sblock->fs_bsize - 1) & sblock->fs_bmask) -#define fragroundup(size) /* calculates roundup(size, fs->fs_fsize) */ \ - (((size) + sblock->fs_fsize - 1) & sblock->fs_fmask) -#define fragstoblks(frags) /* calculates (frags / fs->fs_frag) */ \ - ((frags) >> sblock->fs_fragshift) -#define blkstofrags(blks) /* calculates (blks * fs->fs_frag) */ \ - ((blks) << sblock->fs_fragshift) -#define fragnum(fsb) /* calculates (fsb % fs->fs_frag) */ \ - ((fsb) & (sblock->fs_frag - 1)) -#define blknum(fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \ - ((fsb) &~ (sblock->fs_frag - 1)) +#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \ + ((loc) & (fs)->fs_qbmask) +#define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \ + ((loc) & (fs)->fs_qfmask) +#define lblktosize(fs, blk) /* calculates (blk * fs->fs_bsize) */ \ + ((blk) << (fs)->fs_bshift) +#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \ + ((loc) >> (fs)->fs_bshift) +#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ + ((loc) >> (fs)->fs_fshift) +#define blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \ + (((size) + (fs)->fs_qbmask) & (fs)->fs_bmask) +#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \ + (((size) + (fs)->fs_qfmask) & (fs)->fs_fmask) +#define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \ + ((frags) >> (fs)->fs_fragshift) +#define blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \ + ((blks) << (fs)->fs_fragshift) +#define fragnum(fs, fsb) /* calculates (fsb % fs->fs_frag) */ \ + ((fsb) & ((fs)->fs_frag - 1)) +#define blknum(fs, fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \ + ((fsb) &~ ((fs)->fs_frag - 1)) /* * Determine the number of available frags given a * percentage to hold in reserve */ -#define freespace(percentreserved) \ - (blkstofrags(sblock->fs_cstotal.cs_nbfree) + \ - sblock->fs_cstotal.cs_nffree - (sblock->fs_dsize * (percentreserved) / 100)) +#define freespace(fs, percentreserved) \ + (blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \ + (fs)->fs_cstotal.cs_nffree - ((fs)->fs_dsize * (percentreserved) / 100)) /* * Determining the size of a file block in the file system. */ -#define blksize(np, lbn) \ - (((lbn) >= NDADDR || (np)->allocsize >= ((lbn) + 1) << sblock->fs_bshift) \ - ? sblock->fs_bsize \ - : (fragroundup(blkoff((np)->allocsize)))) -#define dblksize(dip, lbn) \ - (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << sblock->fs_bshift) \ - ? sblock->fs_bsize \ - : (fragroundup(blkoff((dip)->di_size)))) +#define blksize(fs, ip, lbn) \ + (((lbn) >= NDADDR || (ip)->i_size >= ((lbn) + 1) << (fs)->fs_bshift) \ + ? (fs)->fs_bsize \ + : (fragroundup(fs, blkoff(fs, (ip)->i_size)))) +#define dblksize(fs, dip, lbn) \ + (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->fs_bshift) \ + ? (fs)->fs_bsize \ + : (fragroundup(fs, blkoff(fs, (dip)->di_size)))) /* * Number of disk sectors per block; assumes DEV_BSIZE byte sector size. */ -#define NSPB (sblock->fs_nspf << sblock->fs_fragshift) -#define NSPF (sblock->fs_nspf) +#define NSPB(fs) ((fs)->fs_nspf << (fs)->fs_fragshift) +#define NSPF(fs) ((fs)->fs_nspf) /* * INOPB is the number of inodes in a secondary storage block. */ -#define INOPB (sblock->fs_inopb) -#define INOPF (sblock->fs_inopb >> sblock->fs_fragshift) +#define INOPB(fs) ((fs)->fs_inopb) +#define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift) /* * NINDIR is the number of indirects in a file system block. */ -#define NINDIR (sblock->fs_nindir) +#define NINDIR(fs) ((fs)->fs_nindir) -#ifdef KERNEL -struct fs *getfs(); -#endif +extern int inside[], around[]; +extern u_char *fragtbl[]; -- cgit v1.2.3 From 749a832c68edbd3c83505e8c255249cc4aa21689 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 20:08:55 +0000 Subject: Formerly subr.c.~4~ --- ufs/subr.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'ufs') diff --git a/ufs/subr.c b/ufs/subr.c index c251b16e..1730e737 100644 --- a/ufs/subr.c +++ b/ufs/subr.c @@ -33,17 +33,10 @@ * @(#)ffs_subr.c 8.2 (Berkeley) 9/21/93 */ -#include -#include - -#ifdef KERNEL -#include -#include -#include -#include -#include -#include +#include "ufs.h" +#include "fs.h" +#if 0 /* Not needed in GNU Hurd ufs. */ /* * Return buffer with the contents of block "offset" from the beginning of * directory "ip". If "res" is non-zero, fill it in with a pointer to the @@ -79,7 +72,7 @@ ffs_blkatoff(ap) *ap->a_bpp = bp; return (0); } -#endif +#endif /* 0 */ /* * Update the frsum fields to reflect addition or deletion @@ -87,7 +80,7 @@ ffs_blkatoff(ap) */ void ffs_fragacct(fs, fragmap, fraglist, cnt) - struct fs *fs; + struct fs *fs; int fragmap; long fraglist[]; int cnt; @@ -116,7 +109,7 @@ ffs_fragacct(fs, fragmap, fraglist, cnt) } } -#if defined(KERNEL) && defined(DIAGNOSTIC) +#if 0 /* Not needed in GNU Hurd ufs. */ void ffs_checkoverlap(bp, ip) struct buf *bp; @@ -148,7 +141,7 @@ ffs_checkoverlap(bp, ip) panic("Disk buffer overlap"); } } -#endif /* DIAGNOSTIC */ +#endif /* 0 */ /* * block operations -- cgit v1.2.3 From 021e49868b745d1c0d20bca96fab3b5ed3decfc2 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 20:09:50 +0000 Subject: Formerly alloc.c.~11~ --- ufs/alloc.c | 2150 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 1284 insertions(+), 866 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 193e0f31..cdd2e4b2 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -1,65 +1,67 @@ -/* Disk allocation routines - Copyright (C) 1993, 1994 Free Software Foundation - -This file is part of the GNU Hurd. - -The GNU Hurd is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -The GNU Hurd is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU Hurd; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Modified from UCB by Michael I. Bushnell. */ - /* - * Copyright (c) 1982, 1986, 1989 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. * - * Redistribution is only permitted until one year after the first shipment - * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and - * binary forms are permitted provided that: (1) source distributions retain - * this entire copyright notice and comment, and (2) distributions including - * binaries display the following acknowledgement: This product includes - * software developed by the University of California, Berkeley and its - * contributors'' in the documentation or other materials provided with the - * distribution and in all advertising materials mentioning features or use - * of this software. Neither the name of the University nor the names of - * its contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * @(#)ufs_alloc.c 7.20 (Berkeley) 6/28/90 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ffs_alloc.c 8.8 (Berkeley) 2/21/94 */ -#include "ufs.h" -#include "fs.h" -#include "dinode.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include -#include +#include +#include -static u_long alloccg (int, daddr_t, int); -static u_long ialloccg (int, daddr_t, int); -static u_long hashalloc (int, long, int, u_long(*)(int, daddr_t, int)); -static daddr_t fragextend (int, long, int, int); -static daddr_t alloccgblk (struct cg *, daddr_t); -static daddr_t mapsearch (struct cg *, daddr_t, int); -static ino_t dirpref (); +#include +#include -/* These are in tables.c. */ -extern int inside[], around[]; -extern unsigned char *fragtbl[]; +extern u_long nextgennumber; -static spin_lock_t alloclock = SPIN_LOCK_INITIALIZER; +static daddr_t ffs_alloccg __P((struct inode *, int, daddr_t, int)); +static daddr_t ffs_alloccgblk __P((struct fs *, struct cg *, daddr_t)); +static daddr_t ffs_clusteralloc __P((struct inode *, int, daddr_t, int)); +static ino_t ffs_dirpref __P((struct fs *)); +static daddr_t ffs_fragextend __P((struct inode *, int, long, int, int)); +static void ffs_fserr __P((struct fs *, u_int, char *)); +static u_long ffs_hashalloc + __P((struct inode *, int, long, int, u_long (*)())); +static ino_t ffs_nodealloccg __P((struct inode *, int, daddr_t, int)); +static daddr_t ffs_mapsearch __P((struct fs *, struct cg *, daddr_t, int)); /* * Allocate a block in the file system. @@ -80,51 +82,60 @@ static spin_lock_t alloclock = SPIN_LOCK_INITIALIZER; * 2) quadradically rehash into other cylinder groups, until an * available block is located. */ -error_t -alloc(struct node *np, - daddr_t lbn, - daddr_t bpref, - int size, - daddr_t *bnp, - struct protid *cred) +ffs_alloc(ip, lbn, bpref, size, cred, bnp) + register struct inode *ip; + daddr_t lbn, bpref; + int size; + struct ucred *cred; + daddr_t *bnp; { - int cg; - daddr_t bno; - - *bnp = 0; - assert ("Alloc of bad sized block" && (unsigned) size <= sblock->fs_bsize - && !fragoff(size) && size != 0); - - spin_lock (&alloclock); - - if (size == sblock->fs_bsize && sblock->fs_cstotal.cs_nbfree == 0) - goto nospace; - if (cred && !diskfs_isuid (0, cred) && freespace(sblock->fs_minfree) <= 0) - goto nospace; - - if (bpref >= sblock->fs_size) - bpref = 0; - if (bpref == 0) - cg = itog(np->dn->number); - else - cg = dtog(bpref); - bno = (daddr_t)hashalloc(cg, (long)bpref, size, alloccg); - - spin_unlock (&alloclock); - - if (bno > 0) - { - np->dn_stat.st_blocks += btodb(size); - np->dn_set_mtime = 1; - np->dn_set_ctime = 1; - *bnp = bno; - return 0; - } - - nospace: - spin_unlock (&alloclock); - printf("file system full\n"); - return (ENOSPC); + register struct fs *fs; + daddr_t bno; + int cg, error; + + *bnp = 0; + fs = ip->i_fs; +#ifdef DIAGNOSTIC + if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) { + printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n", + ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt); + panic("ffs_alloc: bad size"); + } + if (cred == NOCRED) + panic("ffs_alloc: missing credential\n"); +#endif /* DIAGNOSTIC */ + if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0) + goto nospace; + if (cred->cr_uid != 0 && freespace(fs, fs->fs_minfree) <= 0) + goto nospace; +#ifdef QUOTA + if (error = chkdq(ip, (long)btodb(size), cred, 0)) + return (error); +#endif + if (bpref >= fs->fs_size) + bpref = 0; + if (bpref == 0) + cg = ino_to_cg(fs, ip->i_number); + else + cg = dtog(fs, bpref); + bno = (daddr_t)ffs_hashalloc(ip, cg, (long)bpref, size, + (u_long (*)())ffs_alloccg); + if (bno > 0) { + ip->i_blocks += btodb(size); + ip->i_flag |= IN_CHANGE | IN_UPDATE; + *bnp = bno; + return (0); + } +#ifdef QUOTA + /* + * Restore user's disk quota because allocation failed. + */ + (void) chkdq(ip, (long)-btodb(size), cred, FORCE); +#endif +nospace: + ffs_fserr(fs, cred->cr_uid, "file system full"); + uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); + return (ENOSPC); } /* @@ -135,179 +146,386 @@ alloc(struct node *np, * the original block. Failing that, the regular block allocator is * invoked to get an appropriate block. */ -error_t -realloccg(struct node *np, - daddr_t lbprev, - volatile daddr_t bpref, - int osize, - int nsize, - daddr_t *pbn, - struct protid *cred) +ffs_realloccg(ip, lbprev, bpref, osize, nsize, cred, bpp) + register struct inode *ip; + daddr_t lbprev; + daddr_t bpref; + int osize, nsize; + struct ucred *cred; + struct buf **bpp; { - volatile int cg, request; - daddr_t bprev, bno; - error_t error; - - *pbn = 0; - assert ("bad old size" && (unsigned) osize <= sblock->fs_bsize - && !fragoff (osize) && osize != 0 ); - assert ("bad new size" && (unsigned) nsize <= sblock->fs_bsize - && !fragoff (nsize) && nsize != 0); - - spin_lock (&alloclock); - - if (cred && !diskfs_isuid (0, cred) && freespace(sblock->fs_minfree) <= 0) - { - spin_unlock (&alloclock); - goto nospace; - } - - if (error = diskfs_catch_exception ()) - return error; - bprev = dinodes[np->dn->number].di_db[lbprev]; - diskfs_end_catch_exception (); - assert ("old block not allocated" && bprev); + register struct fs *fs; + struct buf *bp; + int cg, request, error; + daddr_t bprev, bno; + + *bpp = 0; + fs = ip->i_fs; +#ifdef DIAGNOSTIC + if ((u_int)osize > fs->fs_bsize || fragoff(fs, osize) != 0 || + (u_int)nsize > fs->fs_bsize || fragoff(fs, nsize) != 0) { + printf( + "dev = 0x%x, bsize = %d, osize = %d, nsize = %d, fs = %s\n", + ip->i_dev, fs->fs_bsize, osize, nsize, fs->fs_fsmnt); + panic("ffs_realloccg: bad size"); + } + if (cred == NOCRED) + panic("ffs_realloccg: missing credential\n"); +#endif /* DIAGNOSTIC */ + if (cred->cr_uid != 0 && freespace(fs, fs->fs_minfree) <= 0) + goto nospace; + if ((bprev = ip->i_db[lbprev]) == 0) { + printf("dev = 0x%x, bsize = %d, bprev = %d, fs = %s\n", + ip->i_dev, fs->fs_bsize, bprev, fs->fs_fsmnt); + panic("ffs_realloccg: bad bprev"); + } + /* + * Allocate the extra space in the buffer. + */ + if (error = bread(ITOV(ip), lbprev, osize, NOCRED, &bp)) { + brelse(bp); + return (error); + } +#ifdef QUOTA + if (error = chkdq(ip, (long)btodb(nsize - osize), cred, 0)) { + brelse(bp); + return (error); + } +#endif + /* + * Check for extension in the existing location. + */ + cg = dtog(fs, bprev); + if (bno = ffs_fragextend(ip, cg, (long)bprev, osize, nsize)) { + if (bp->b_blkno != fsbtodb(fs, bno)) + panic("bad blockno"); + ip->i_blocks += btodb(nsize - osize); + ip->i_flag |= IN_CHANGE | IN_UPDATE; + allocbuf(bp, nsize); + bp->b_flags |= B_DONE; + bzero((char *)bp->b_data + osize, (u_int)nsize - osize); + *bpp = bp; + return (0); + } + /* + * Allocate a new disk location. + */ + if (bpref >= fs->fs_size) + bpref = 0; + switch ((int)fs->fs_optim) { + case FS_OPTSPACE: + /* + * Allocate an exact sized fragment. Although this makes + * best use of space, we will waste time relocating it if + * the file continues to grow. If the fragmentation is + * less than half of the minimum free reserve, we choose + * to begin optimizing for time. + */ + request = nsize; + if (fs->fs_minfree < 5 || + fs->fs_cstotal.cs_nffree > + fs->fs_dsize * fs->fs_minfree / (2 * 100)) + break; + log(LOG_NOTICE, "%s: optimization changed from SPACE to TIME\n", + fs->fs_fsmnt); + fs->fs_optim = FS_OPTTIME; + break; + case FS_OPTTIME: + /* + * At this point we have discovered a file that is trying to + * grow a small fragment to a larger fragment. To save time, + * we allocate a full sized block, then free the unused portion. + * If the file continues to grow, the `ffs_fragextend' call + * above will be able to grow it in place without further + * copying. If aberrant programs cause disk fragmentation to + * grow within 2% of the free reserve, we choose to begin + * optimizing for space. + */ + request = fs->fs_bsize; + if (fs->fs_cstotal.cs_nffree < + fs->fs_dsize * (fs->fs_minfree - 2) / 100) + break; + log(LOG_NOTICE, "%s: optimization changed from TIME to SPACE\n", + fs->fs_fsmnt); + fs->fs_optim = FS_OPTSPACE; + break; + default: + printf("dev = 0x%x, optim = %d, fs = %s\n", + ip->i_dev, fs->fs_optim, fs->fs_fsmnt); + panic("ffs_realloccg: bad optim"); + /* NOTREACHED */ + } + bno = (daddr_t)ffs_hashalloc(ip, cg, (long)bpref, request, + (u_long (*)())ffs_alloccg); + if (bno > 0) { + bp->b_blkno = fsbtodb(fs, bno); + (void) vnode_pager_uncache(ITOV(ip)); + ffs_blkfree(ip, bprev, (long)osize); + if (nsize < request) + ffs_blkfree(ip, bno + numfrags(fs, nsize), + (long)(request - nsize)); + ip->i_blocks += btodb(nsize - osize); + ip->i_flag |= IN_CHANGE | IN_UPDATE; + allocbuf(bp, nsize); + bp->b_flags |= B_DONE; + bzero((char *)bp->b_data + osize, (u_int)nsize - osize); + *bpp = bp; + return (0); + } +#ifdef QUOTA + /* + * Restore user's disk quota because allocation failed. + */ + (void) chkdq(ip, (long)-btodb(nsize - osize), cred, FORCE); +#endif + brelse(bp); +nospace: + /* + * no space available + */ + ffs_fserr(fs, cred->cr_uid, "file system full"); + uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); + return (ENOSPC); +} - /* - * Check for extension in the existing location. - */ - cg = dtog(bprev); - if (bno = fragextend(cg, (long)bprev, osize, nsize)) - { - spin_unlock (&alloclock); - assert ("fragextend behaved incorrectly" && bprev == bno); - np->dn_stat.st_blocks += btodb(nsize - osize); - np->dn_set_mtime = 1; - np->dn_set_ctime = 1; - *pbn = bno; - return (0); - } - /* - * Allocate a new disk location. - */ - if (bpref >= sblock->fs_size) - bpref = 0; - switch ((int)sblock->fs_optim) - { - case FS_OPTSPACE: - /* - * Allocate an exact sized fragment. Although this makes - * best use of space, we will waste time relocating it if - * the file continues to grow. If the fragmentation is - * less than half of the minimum free reserve, we choose - * to begin optimizing for time. - */ - request = nsize; - if (sblock->fs_minfree < 5 || - sblock->fs_cstotal.cs_nffree > - sblock->fs_dsize * sblock->fs_minfree / (2 * 100)) - break; - printf("optimization changed from SPACE to TIME\n"); - sblock->fs_optim = FS_OPTTIME; - break; - case FS_OPTTIME: - /* - * At this point we have discovered a file that is trying - * to grow a small fragment to a larger fragment. To save - * time, we allocate a full sized block, then free the - * unused portion. If the file continues to grow, the - * `fragextend' call above will be able to grow it in place - * without further copying. If aberrant programs cause - * disk fragmentation to grow within 2% of the free reserve, - * we choose to begin optimizing for space. - */ - request = sblock->fs_bsize; - if (sblock->fs_cstotal.cs_nffree < - sblock->fs_dsize * (sblock->fs_minfree - 2) / 100) - break; - printf("%s: optimization changed from TIME to SPACE\n", - sblock->fs_fsmnt); - sblock->fs_optim = FS_OPTSPACE; - break; - default: - assert ("filesystem opitimazation bad value" && 0); - } - - bno = (daddr_t)hashalloc(cg, (long)bpref, request, - (u_long (*)())alloccg); +/* + * Reallocate a sequence of blocks into a contiguous sequence of blocks. + * + * The vnode and an array of buffer pointers for a range of sequential + * logical blocks to be made contiguous is given. The allocator attempts + * to find a range of sequential blocks starting as close as possible to + * an fs_rotdelay offset from the end of the allocation for the logical + * block immediately preceeding the current range. If successful, the + * physical block numbers in the buffer pointers and in the inode are + * changed to reflect the new allocation. If unsuccessful, the allocation + * is left unchanged. The success in doing the reallocation is returned. + * Note that the error return is not reflected back to the user. Rather + * the previous block allocation will be used. + */ +#include +int doasyncfree = 1; +struct ctldebug debug14 = { "doasyncfree", &doasyncfree }; +int +ffs_reallocblks(ap) + struct vop_reallocblks_args /* { + struct vnode *a_vp; + struct cluster_save *a_buflist; + } */ *ap; +{ + struct fs *fs; + struct inode *ip; + struct vnode *vp; + struct buf *sbp, *ebp; + daddr_t *bap, *sbap, *ebap; + struct cluster_save *buflist; + daddr_t start_lbn, end_lbn, soff, eoff, newblk, blkno; + struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp; + int i, len, start_lvl, end_lvl, pref, ssize; - spin_unlock (&alloclock); + vp = ap->a_vp; + ip = VTOI(vp); + fs = ip->i_fs; + if (fs->fs_contigsumsize <= 0) + return (ENOSPC); + buflist = ap->a_buflist; + len = buflist->bs_nchildren; + start_lbn = buflist->bs_children[0]->b_lblkno; + end_lbn = start_lbn + len - 1; +#ifdef DIAGNOSTIC + for (i = 1; i < len; i++) + if (buflist->bs_children[i]->b_lblkno != start_lbn + i) + panic("ffs_reallocblks: non-cluster"); +#endif + /* + * If the latest allocation is in a new cylinder group, assume that + * the filesystem has decided to move and do not force it back to + * the previous cylinder group. + */ + if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) != + dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno))) + return (ENOSPC); + if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) || + ufs_getlbns(vp, end_lbn, end_ap, &end_lvl)) + return (ENOSPC); + /* + * Get the starting offset and block map for the first block. + */ + if (start_lvl == 0) { + sbap = &ip->i_db[0]; + soff = start_lbn; + } else { + idp = &start_ap[start_lvl - 1]; + if (bread(vp, idp->in_lbn, (int)fs->fs_bsize, NOCRED, &sbp)) { + brelse(sbp); + return (ENOSPC); + } + sbap = (daddr_t *)sbp->b_data; + soff = idp->in_off; + } + /* + * Find the preferred location for the cluster. + */ + pref = ffs_blkpref(ip, start_lbn, soff, sbap); + /* + * If the block range spans two block maps, get the second map. + */ + if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) { + ssize = len; + } else { +#ifdef DIAGNOSTIC + if (start_ap[start_lvl-1].in_lbn == idp->in_lbn) + panic("ffs_reallocblk: start == end"); +#endif + ssize = len - (idp->in_off + 1); + if (bread(vp, idp->in_lbn, (int)fs->fs_bsize, NOCRED, &ebp)) + goto fail; + ebap = (daddr_t *)ebp->b_data; + } + /* + * Search the block map looking for an allocation of the desired size. + */ + if ((newblk = (daddr_t)ffs_hashalloc(ip, dtog(fs, pref), (long)pref, + len, (u_long (*)())ffs_clusteralloc)) == 0) + goto fail; + /* + * We have found a new contiguous block. + * + * First we have to replace the old block pointers with the new + * block pointers in the inode and indirect blocks associated + * with the file. + */ + blkno = newblk; + for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->fs_frag) { + if (i == ssize) + bap = ebap; +#ifdef DIAGNOSTIC + if (buflist->bs_children[i]->b_blkno != fsbtodb(fs, *bap)) + panic("ffs_reallocblks: alloc mismatch"); +#endif + *bap++ = blkno; + } + /* + * Next we must write out the modified inode and indirect blocks. + * For strict correctness, the writes should be synchronous since + * the old block values may have been written to disk. In practise + * they are almost never written, but if we are concerned about + * strict correctness, the `doasyncfree' flag should be set to zero. + * + * The test on `doasyncfree' should be changed to test a flag + * that shows whether the associated buffers and inodes have + * been written. The flag should be set when the cluster is + * started and cleared whenever the buffer or inode is flushed. + * We can then check below to see if it is set, and do the + * synchronous write only when it has been cleared. + */ + if (sbap != &ip->i_db[0]) { + if (doasyncfree) + bdwrite(sbp); + else + bwrite(sbp); + } else { + ip->i_flag |= IN_CHANGE | IN_UPDATE; + if (!doasyncfree) + VOP_UPDATE(vp, &time, &time, MNT_WAIT); + } + if (ssize < len) + if (doasyncfree) + bdwrite(ebp); + else + bwrite(ebp); + /* + * Last, free the old blocks and assign the new blocks to the buffers. + */ + for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) { + ffs_blkfree(ip, dbtofsb(fs, buflist->bs_children[i]->b_blkno), + fs->fs_bsize); + buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno); + } + return (0); - if (bno > 0) - { - blkfree(bprev, (off_t)osize); - if (nsize < request) - blkfree(bno + numfrags(nsize), (off_t)(request - nsize)); - np->dn_stat.st_blocks += btodb (nsize - osize); - np->dn_set_mtime = 1; - np->dn_set_ctime = 1; - *pbn = bno; - return (0); - } - nospace: - /* - * no space available - */ - printf("file system full\n"); - return (ENOSPC); +fail: + if (ssize < len) + brelse(ebp); + if (sbap != &ip->i_db[0]) + brelse(sbp); + return (ENOSPC); } - -/* Implement the diskfs_alloc_node callback from the diskfs library. - See for the interface description. */ -error_t -diskfs_alloc_node(struct node *dir, - mode_t mode, - struct node **npp) +/* + * Allocate an inode in the file system. + * + * If allocating a directory, use ffs_dirpref to select the inode. + * If allocating in a directory, the following hierarchy is followed: + * 1) allocate the preferred inode. + * 2) allocate an inode in the same cylinder group. + * 3) quadradically rehash into other cylinder groups, until an + * available inode is located. + * If no inode preference is given the following heirarchy is used + * to allocate an inode: + * 1) allocate an inode in cylinder group 0. + * 2) quadradically rehash into other cylinder groups, until an + * available inode is located. + */ +ffs_valloc(ap) + struct vop_valloc_args /* { + struct vnode *a_pvp; + int a_mode; + struct ucred *a_cred; + struct vnode **a_vpp; + } */ *ap; { - int ino; - struct node *np; - int cg; - error_t error; - int ipref; - - if (S_ISDIR (mode)) - ipref = dirpref (); - else - ipref = dir->dn->number; - - *npp = 0; + register struct vnode *pvp = ap->a_pvp; + register struct inode *pip; + register struct fs *fs; + register struct inode *ip; + mode_t mode = ap->a_mode; + ino_t ino, ipref; + int cg, error; + + *ap->a_vpp = NULL; + pip = VTOI(pvp); + fs = pip->i_fs; + if (fs->fs_cstotal.cs_nifree == 0) + goto noinodes; - spin_lock (&alloclock); - if (sblock->fs_cstotal.cs_nifree == 0) - { - spin_unlock (&alloclock); - goto noinodes; - } - if (ipref >= sblock->fs_ncg * sblock->fs_ipg) - ipref = 0; - cg = itog(ipref); - ino = (int)hashalloc(cg, (long)ipref, mode, ialloccg); - spin_unlock (&alloclock); - if (ino == 0) - goto noinodes; - if (error = iget(ino, &np)) - return error; - *npp = np; - assert ("duplicate allocation" && !np->dn_stat.st_mode); - if (np->dn_stat.st_blocks) - { - printf("free inode %d had %d blocks\n", ino, np->dn_stat.st_blocks); - np->dn_stat.st_blocks = 0; - np->dn_set_ctime = 1; - } - /* - * Set up a new generation number for this inode. - */ - spin_lock (&gennumberlock); - if (++nextgennumber < (u_long)diskfs_mtime->seconds) - nextgennumber = diskfs_mtime->seconds; - np->dn_stat.st_gen = nextgennumber; - spin_unlock (&gennumberlock); - return (0); - noinodes: - printf("out of inodes\n"); - return (ENOSPC); + if ((mode & IFMT) == IFDIR) + ipref = ffs_dirpref(fs); + else + ipref = pip->i_number; + if (ipref >= fs->fs_ncg * fs->fs_ipg) + ipref = 0; + cg = ino_to_cg(fs, ipref); + ino = (ino_t)ffs_hashalloc(pip, cg, (long)ipref, mode, ffs_nodealloccg); + if (ino == 0) + goto noinodes; + error = VFS_VGET(pvp->v_mount, ino, ap->a_vpp); + if (error) { + VOP_VFREE(pvp, ino, mode); + return (error); + } + ip = VTOI(*ap->a_vpp); + if (ip->i_mode) { + printf("mode = 0%o, inum = %d, fs = %s\n", + ip->i_mode, ip->i_number, fs->fs_fsmnt); + panic("ffs_valloc: dup alloc"); + } + if (ip->i_blocks) { /* XXX */ + printf("free inode %s/%d had %d blocks\n", + fs->fs_fsmnt, ino, ip->i_blocks); + ip->i_blocks = 0; + } + ip->i_flags = 0; + /* + * Set up a new generation number for this inode. + */ + if (++nextgennumber < (u_long)time.tv_sec) + nextgennumber = time.tv_sec; + ip->i_gen = nextgennumber; + return (0); +noinodes: + ffs_fserr(fs, ap->a_cred->cr_uid, "out of inodes"); + uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt); + return (ENOSPC); } /* @@ -318,22 +536,21 @@ diskfs_alloc_node(struct node *dir, * free inodes, the one with the smallest number of directories. */ static ino_t -dirpref() +ffs_dirpref(fs) + register struct fs *fs; { - int cg, minndir, mincg, avgifree; - - spin_lock (&alloclock); - avgifree = sblock->fs_cstotal.cs_nifree / sblock->fs_ncg; - minndir = sblock->fs_ipg; - mincg = 0; - for (cg = 0; cg < sblock->fs_ncg; cg++) - if (csum[cg].cs_ndir < minndir && csum[cg].cs_nifree >= avgifree) - { - mincg = cg; - minndir = csum[cg].cs_ndir; - } - spin_unlock (&alloclock); - return ((int)(sblock->fs_ipg * mincg)); + int cg, minndir, mincg, avgifree; + + avgifree = fs->fs_cstotal.cs_nifree / fs->fs_ncg; + minndir = fs->fs_ipg; + mincg = 0; + for (cg = 0; cg < fs->fs_ncg; cg++) + if (fs->fs_cs(fs, cg).cs_ndir < minndir && + fs->fs_cs(fs, cg).cs_nifree >= avgifree) { + mincg = cg; + minndir = fs->fs_cs(fs, cg).cs_ndir; + } + return ((ino_t)(fs->fs_ipg * mincg)); } /* @@ -363,75 +580,66 @@ dirpref() * schedule another I/O transfer. */ daddr_t -blkpref(struct node *np, - daddr_t lbn, - int indx, - daddr_t *bap) +ffs_blkpref(ip, lbn, indx, bap) + struct inode *ip; + daddr_t lbn; + int indx; + daddr_t *bap; { - int cg; - int avgbfree, startcg; - daddr_t nextblk; - - spin_lock (&alloclock); - if (indx % sblock->fs_maxbpg == 0 || bap[indx - 1] == 0) - { - if (lbn < NDADDR) - { - spin_unlock (&alloclock); - cg = itog(np->dn->number); - return (sblock->fs_fpg * cg + sblock->fs_frag); - } - /* - * Find a cylinder with greater than average number of - * unused data blocks. - */ - if (indx == 0 || bap[indx - 1] == 0) - startcg = itog(np->dn->number) + lbn / sblock->fs_maxbpg; - else - startcg = dtog(bap[indx - 1]) + 1; - startcg %= sblock->fs_ncg; - avgbfree = sblock->fs_cstotal.cs_nbfree / sblock->fs_ncg; - for (cg = startcg; cg < sblock->fs_ncg; cg++) - if (csum[cg].cs_nbfree >= avgbfree) - { - spin_unlock (&alloclock); - sblock->fs_cgrotor = cg; - return (sblock->fs_fpg * cg + sblock->fs_frag); - } - for (cg = 0; cg <= startcg; cg++) - if (csum[cg].cs_nbfree >= avgbfree) - { - spin_unlock (&alloclock); - sblock->fs_cgrotor = cg; - return (sblock->fs_fpg * cg + sblock->fs_frag); - } - spin_unlock (&alloclock); - return 0; - } + register struct fs *fs; + register int cg; + int avgbfree, startcg; + daddr_t nextblk; - spin_unlock (&alloclock); - - /* - * One or more previous blocks have been laid out. If less - * than fs_maxcontig previous blocks are contiguous, the - * next block is requested contiguously, otherwise it is - * requested rotationally delayed by fs_rotdelay milliseconds. - */ - nextblk = bap[indx - 1] + sblock->fs_frag; - if (indx > sblock->fs_maxcontig && - bap[indx - sblock->fs_maxcontig] + blkstofrags(sblock->fs_maxcontig) - != nextblk) - return (nextblk); - if (sblock->fs_rotdelay != 0) - /* - * Here we convert ms of delay to frags as: - * (frags) = (ms) * (rev/sec) * (sect/rev) / - * ((sect/frag) * (ms/sec)) - * then round up to the next block. - */ - nextblk += roundup(sblock->fs_rotdelay * sblock->fs_rps - * sblock->fs_nsect / (NSPF * 1000), sblock->fs_frag); - return (nextblk); + fs = ip->i_fs; + if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) { + if (lbn < NDADDR) { + cg = ino_to_cg(fs, ip->i_number); + return (fs->fs_fpg * cg + fs->fs_frag); + } + /* + * Find a cylinder with greater than average number of + * unused data blocks. + */ + if (indx == 0 || bap[indx - 1] == 0) + startcg = + ino_to_cg(fs, ip->i_number) + lbn / fs->fs_maxbpg; + else + startcg = dtog(fs, bap[indx - 1]) + 1; + startcg %= fs->fs_ncg; + avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg; + for (cg = startcg; cg < fs->fs_ncg; cg++) + if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) { + fs->fs_cgrotor = cg; + return (fs->fs_fpg * cg + fs->fs_frag); + } + for (cg = 0; cg <= startcg; cg++) + if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) { + fs->fs_cgrotor = cg; + return (fs->fs_fpg * cg + fs->fs_frag); + } + return (NULL); + } + /* + * One or more previous blocks have been laid out. If less + * than fs_maxcontig previous blocks are contiguous, the + * next block is requested contiguously, otherwise it is + * requested rotationally delayed by fs_rotdelay milliseconds. + */ + nextblk = bap[indx - 1] + fs->fs_frag; + if (indx < fs->fs_maxcontig || bap[indx - fs->fs_maxcontig] + + blkstofrags(fs, fs->fs_maxcontig) != nextblk) + return (nextblk); + if (fs->fs_rotdelay != 0) + /* + * Here we convert ms of delay to frags as: + * (frags) = (ms) * (rev/sec) * (sect/rev) / + * ((sect/frag) * (ms/sec)) + * then round up to the next block. + */ + nextblk += roundup(fs->fs_rotdelay * fs->fs_rps * fs->fs_nsect / + (NSPF(fs) * 1000), fs->fs_frag); + return (nextblk); } /* @@ -444,48 +652,50 @@ blkpref(struct node *np, */ /*VARARGS5*/ static u_long -hashalloc(int cg, - long pref, - int size, /* size for data blocks, mode for inodes */ - u_long (*allocator)(int, daddr_t, int)) +ffs_hashalloc(ip, cg, pref, size, allocator) + struct inode *ip; + int cg; + long pref; + int size; /* size for data blocks, mode for inodes */ + u_long (*allocator)(); { - long result; - int i, icg = cg; - - /* - * 1: preferred cylinder group - */ - result = (*allocator)(cg, pref, size); - if (result) - return (result); - /* - * 2: quadratic rehash - */ - for (i = 1; i < sblock->fs_ncg; i *= 2) - { - cg += i; - if (cg >= sblock->fs_ncg) - cg -= sblock->fs_ncg; - result = (*allocator)(cg, 0, size); - if (result) - return (result); - } - /* - * 3: brute force search - * Note that we start at i == 2, since 0 was checked initially, - * and 1 is always checked in the quadratic rehash. - */ - cg = (icg + 2) % sblock->fs_ncg; - for (i = 2; i < sblock->fs_ncg; i++) - { - result = (*allocator)(cg, 0, size); - if (result) - return (result); - cg++; - if (cg == sblock->fs_ncg) - cg = 0; - } - return 0; + register struct fs *fs; + long result; + int i, icg = cg; + + fs = ip->i_fs; + /* + * 1: preferred cylinder group + */ + result = (*allocator)(ip, cg, pref, size); + if (result) + return (result); + /* + * 2: quadratic rehash + */ + for (i = 1; i < fs->fs_ncg; i *= 2) { + cg += i; + if (cg >= fs->fs_ncg) + cg -= fs->fs_ncg; + result = (*allocator)(ip, cg, 0, size); + if (result) + return (result); + } + /* + * 3: brute force search + * Note that we start at i == 2, since 0 was checked initially, + * and 1 is always checked in the quadratic rehash. + */ + cg = (icg + 2) % fs->fs_ncg; + for (i = 2; i < fs->fs_ncg; i++) { + result = (*allocator)(ip, cg, 0, size); + if (result) + return (result); + cg++; + if (cg == fs->fs_ncg) + cg = 0; + } + return (NULL); } /* @@ -495,154 +705,156 @@ hashalloc(int cg, * if they are, allocate them. */ static daddr_t -fragextend(int cg, - long bprev, - int osize, - int nsize) +ffs_fragextend(ip, cg, bprev, osize, nsize) + struct inode *ip; + int cg; + long bprev; + int osize, nsize; { - struct cg *cgp; - long bno; - int frags, bbase; - int i; - - if (csum[cg].cs_nffree < numfrags(nsize - osize)) - return 0; - frags = numfrags(nsize); - bbase = fragnum(bprev); - if (bbase > fragnum((bprev + frags - 1))) - /* cannot extend across a block boundary */ - return 0; + register struct fs *fs; + register struct cg *cgp; + struct buf *bp; + long bno; + int frags, bbase; + int i, error; - cgp = (struct cg *) (cgs + sblock->fs_bsize * cg); - - if (diskfs_catch_exception ()) - return 0; /* bogus, but that's what BSD does... */ - - if (!cg_chkmagic(cgp)) - { - printf ("Cylinder group %d bad magic number: %ld/%ld\n", - cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); - diskfs_end_catch_exception (); - return 0; - } - cgp->cg_time = diskfs_mtime->seconds; - bno = dtogd(bprev); - for (i = numfrags(osize); i < frags; i++) - if (isclr(cg_blksfree(cgp), bno + i)) - { - diskfs_end_catch_exception (); - return 0; - } - - /* - * the current fragment can be extended - * deduct the count on fragment being extended into - * increase the count on the remaining fragment (if any) - * allocate the extended piece - */ - for (i = frags; i < sblock->fs_frag - bbase; i++) - if (isclr(cg_blksfree(cgp), bno + i)) - break; - cgp->cg_frsum[i - numfrags(osize)]--; - if (i != frags) - cgp->cg_frsum[i - frags]++; - for (i = numfrags(osize); i < frags; i++) - { - clrbit(cg_blksfree(cgp), bno + i); - cgp->cg_cs.cs_nffree--; - sblock->fs_cstotal.cs_nffree--; - csum[cg].cs_nffree--; - } - diskfs_end_catch_exception (); - return (bprev); + fs = ip->i_fs; + if (fs->fs_cs(fs, cg).cs_nffree < numfrags(fs, nsize - osize)) + return (NULL); + frags = numfrags(fs, nsize); + bbase = fragnum(fs, bprev); + if (bbase > fragnum(fs, (bprev + frags - 1))) { + /* cannot extend across a block boundary */ + return (NULL); + } + error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), + (int)fs->fs_cgsize, NOCRED, &bp); + if (error) { + brelse(bp); + return (NULL); + } + cgp = (struct cg *)bp->b_data; + if (!cg_chkmagic(cgp)) { + brelse(bp); + return (NULL); + } + cgp->cg_time = time.tv_sec; + bno = dtogd(fs, bprev); + for (i = numfrags(fs, osize); i < frags; i++) + if (isclr(cg_blksfree(cgp), bno + i)) { + brelse(bp); + return (NULL); + } + /* + * the current fragment can be extended + * deduct the count on fragment being extended into + * increase the count on the remaining fragment (if any) + * allocate the extended piece + */ + for (i = frags; i < fs->fs_frag - bbase; i++) + if (isclr(cg_blksfree(cgp), bno + i)) + break; + cgp->cg_frsum[i - numfrags(fs, osize)]--; + if (i != frags) + cgp->cg_frsum[i - frags]++; + for (i = numfrags(fs, osize); i < frags; i++) { + clrbit(cg_blksfree(cgp), bno + i); + cgp->cg_cs.cs_nffree--; + fs->fs_cstotal.cs_nffree--; + fs->fs_cs(fs, cg).cs_nffree--; + } + fs->fs_fmod = 1; + bdwrite(bp); + return (bprev); } /* * Determine whether a block can be allocated. * - * Check to see if a block of the apprpriate size is available, + * Check to see if a block of the appropriate size is available, * and if it is, allocate it. */ -static u_long -alloccg(int cg, - volatile daddr_t bpref, - int size) +static daddr_t +ffs_alloccg(ip, cg, bpref, size) + struct inode *ip; + int cg; + daddr_t bpref; + int size; { - struct cg *cgp; - int i; - int bno, frags, allocsiz; - - if (csum[cg].cs_nbfree == 0 && size == sblock->fs_bsize) - return 0; - cgp = (struct cg *) (cgs + sblock->fs_bsize * cg); + register struct fs *fs; + register struct cg *cgp; + struct buf *bp; + register int i; + int error, bno, frags, allocsiz; - if (diskfs_catch_exception ()) - return 0; - - if (!cg_chkmagic(cgp) || - (cgp->cg_cs.cs_nbfree == 0 && size == sblock->fs_bsize)) - { - printf ("Cylinder group %d bad magic number: %ld/%ld\n", - cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); - diskfs_end_catch_exception (); - return 0; - } - cgp->cg_time = diskfs_mtime->seconds; - if (size == sblock->fs_bsize) - { - bno = alloccgblk(cgp, bpref); - diskfs_end_catch_exception (); - return (u_long) (bno); - } - /* - * check to see if any fragments are already available - * allocsiz is the size which will be allocated, hacking - * it down to a smaller size if necessary - */ - frags = numfrags(size); - for (allocsiz = frags; allocsiz < sblock->fs_frag; allocsiz++) - if (cgp->cg_frsum[allocsiz] != 0) - break; - if (allocsiz == sblock->fs_frag) - { - /* - * no fragments were available, so a block will be - * allocated, and hacked up - */ - if (cgp->cg_cs.cs_nbfree == 0) - { - diskfs_end_catch_exception (); - return 0; + fs = ip->i_fs; + if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize) + return (NULL); + error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), + (int)fs->fs_cgsize, NOCRED, &bp); + if (error) { + brelse(bp); + return (NULL); } - - bno = alloccgblk(cgp, bpref); - bpref = dtogd(bno); - for (i = frags; i < sblock->fs_frag; i++) - setbit(cg_blksfree(cgp), bpref + i); - i = sblock->fs_frag - frags; - cgp->cg_cs.cs_nffree += i; - sblock->fs_cstotal.cs_nffree += i; - csum[cg].cs_nffree += i; - cgp->cg_frsum[i]++; - return (u_long)(bno); - } - bno = mapsearch(cgp, bpref, allocsiz); - if (bno < 0) - { - diskfs_end_catch_exception (); - return 0; - } - - for (i = 0; i < frags; i++) - clrbit(cg_blksfree(cgp), bno + i); - cgp->cg_cs.cs_nffree -= frags; - sblock->fs_cstotal.cs_nffree -= frags; - csum[cg].cs_nffree -= frags; - cgp->cg_frsum[allocsiz]--; - if (frags != allocsiz) - cgp->cg_frsum[allocsiz - frags]++; - diskfs_end_catch_exception (); - return (u_long) (cg * sblock->fs_fpg + bno); + cgp = (struct cg *)bp->b_data; + if (!cg_chkmagic(cgp) || + (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) { + brelse(bp); + return (NULL); + } + cgp->cg_time = time.tv_sec; + if (size == fs->fs_bsize) { + bno = ffs_alloccgblk(fs, cgp, bpref); + bdwrite(bp); + return (bno); + } + /* + * check to see if any fragments are already available + * allocsiz is the size which will be allocated, hacking + * it down to a smaller size if necessary + */ + frags = numfrags(fs, size); + for (allocsiz = frags; allocsiz < fs->fs_frag; allocsiz++) + if (cgp->cg_frsum[allocsiz] != 0) + break; + if (allocsiz == fs->fs_frag) { + /* + * no fragments were available, so a block will be + * allocated, and hacked up + */ + if (cgp->cg_cs.cs_nbfree == 0) { + brelse(bp); + return (NULL); + } + bno = ffs_alloccgblk(fs, cgp, bpref); + bpref = dtogd(fs, bno); + for (i = frags; i < fs->fs_frag; i++) + setbit(cg_blksfree(cgp), bpref + i); + i = fs->fs_frag - frags; + cgp->cg_cs.cs_nffree += i; + fs->fs_cstotal.cs_nffree += i; + fs->fs_cs(fs, cg).cs_nffree += i; + fs->fs_fmod = 1; + cgp->cg_frsum[i]++; + bdwrite(bp); + return (bno); + } + bno = ffs_mapsearch(fs, cgp, bpref, allocsiz); + if (bno < 0) { + brelse(bp); + return (NULL); + } + for (i = 0; i < frags; i++) + clrbit(cg_blksfree(cgp), bno + i); + cgp->cg_cs.cs_nffree -= frags; + fs->fs_cstotal.cs_nffree -= frags; + fs->fs_cs(fs, cg).cs_nffree -= frags; + fs->fs_fmod = 1; + cgp->cg_frsum[allocsiz]--; + if (frags != allocsiz) + cgp->cg_frsum[allocsiz - frags]++; + bdwrite(bp); + return (cg * fs->fs_fpg + bno); } /* @@ -657,109 +869,196 @@ alloccg(int cg, * blocks may be fragmented by the routine that allocates them. */ static daddr_t -alloccgblk(struct cg *cgp, - volatile daddr_t bpref) +ffs_alloccgblk(fs, cgp, bpref) + register struct fs *fs; + register struct cg *cgp; + daddr_t bpref; { - daddr_t bno; - int cylno, pos, delta; - short *cylbp; - int i; - daddr_t ret; - - if (diskfs_catch_exception ()) - return 0; - - if (bpref == 0) - { - bpref = cgp->cg_rotor; - goto norot; - } - bpref = blknum(bpref); - bpref = dtogd(bpref); - /* - * if the requested block is available, use it - */ - if (isblock(cg_blksfree(cgp), fragstoblks(bpref))) - { - bno = bpref; - goto gotit; - } - /* - * check for a block available on the same cylinder - */ - cylno = cbtocylno(bpref); - if (cg_blktot(cgp)[cylno] == 0) - goto norot; - if (sblock->fs_cpc == 0) - { - /* - * block layout info is not available, so just have - * to take any block in this cylinder. - */ - bpref = howmany(sblock->fs_spc * cylno, NSPF); - goto norot; - } - /* - * check the summary information to see if a block is - * available in the requested cylinder starting at the - * requested rotational position and proceeding around. - */ - cylbp = cg_blks(cgp, cylno); - pos = cbtorpos(bpref); - for (i = pos; i < sblock->fs_nrpos; i++) - if (cylbp[i] > 0) - break; - if (i == sblock->fs_nrpos) - for (i = 0; i < pos; i++) - if (cylbp[i] > 0) - break; - if (cylbp[i] > 0) - { - /* - * found a rotational position, now find the actual - * block. A panic if none is actually there. - */ - pos = cylno % sblock->fs_cpc; - bno = (cylno - pos) * sblock->fs_spc / NSPB; - assert ("postbl table bad" &&fs_postbl(pos)[i] != -1); - for (i = fs_postbl(pos)[i];; ) - { - if (isblock(cg_blksfree(cgp), bno + i)) - { - bno = blkstofrags(bno + i); - goto gotit; - } - delta = fs_rotbl[i]; - if (delta <= 0 || - delta + i > fragstoblks(sblock->fs_fpg)) - break; - i += delta; + daddr_t bno, blkno; + int cylno, pos, delta; + short *cylbp; + register int i; + + if (bpref == 0 || dtog(fs, bpref) != cgp->cg_cgx) { + bpref = cgp->cg_rotor; + goto norot; } - assert ("Inconsistent rotbl table" && 0); - } - norot: - /* - * no blocks in the requested cylinder, so take next - * available one in this cylinder group. - */ - bno = mapsearch(cgp, bpref, (int)sblock->fs_frag); - if (bno < 0) - { - diskfs_end_catch_exception (); - return 0; - } - cgp->cg_rotor = bno; - gotit: - clrblock(cg_blksfree(cgp), (long)fragstoblks(bno)); - cgp->cg_cs.cs_nbfree--; - sblock->fs_cstotal.cs_nbfree--; - csum[cgp->cg_cgx].cs_nbfree--; - cylno = cbtocylno(bno); - cg_blks(cgp, cylno)[cbtorpos(bno)]--; - cg_blktot(cgp)[cylno]--; - ret = cgp->cg_cgx * sblock->fs_fpg + bno; - diskfs_end_catch_exception (); - return ret; + bpref = blknum(fs, bpref); + bpref = dtogd(fs, bpref); + /* + * if the requested block is available, use it + */ + if (ffs_isblock(fs, cg_blksfree(cgp), fragstoblks(fs, bpref))) { + bno = bpref; + goto gotit; + } + /* + * check for a block available on the same cylinder + */ + cylno = cbtocylno(fs, bpref); + if (cg_blktot(cgp)[cylno] == 0) + goto norot; + if (fs->fs_cpc == 0) { + /* + * Block layout information is not available. + * Leaving bpref unchanged means we take the + * next available free block following the one + * we just allocated. Hopefully this will at + * least hit a track cache on drives of unknown + * geometry (e.g. SCSI). + */ + goto norot; + } + /* + * check the summary information to see if a block is + * available in the requested cylinder starting at the + * requested rotational position and proceeding around. + */ + cylbp = cg_blks(fs, cgp, cylno); + pos = cbtorpos(fs, bpref); + for (i = pos; i < fs->fs_nrpos; i++) + if (cylbp[i] > 0) + break; + if (i == fs->fs_nrpos) + for (i = 0; i < pos; i++) + if (cylbp[i] > 0) + break; + if (cylbp[i] > 0) { + /* + * found a rotational position, now find the actual + * block. A panic if none is actually there. + */ + pos = cylno % fs->fs_cpc; + bno = (cylno - pos) * fs->fs_spc / NSPB(fs); + if (fs_postbl(fs, pos)[i] == -1) { + printf("pos = %d, i = %d, fs = %s\n", + pos, i, fs->fs_fsmnt); + panic("ffs_alloccgblk: cyl groups corrupted"); + } + for (i = fs_postbl(fs, pos)[i];; ) { + if (ffs_isblock(fs, cg_blksfree(cgp), bno + i)) { + bno = blkstofrags(fs, (bno + i)); + goto gotit; + } + delta = fs_rotbl(fs)[i]; + if (delta <= 0 || + delta + i > fragstoblks(fs, fs->fs_fpg)) + break; + i += delta; + } + printf("pos = %d, i = %d, fs = %s\n", pos, i, fs->fs_fsmnt); + panic("ffs_alloccgblk: can't find blk in cyl"); + } +norot: + /* + * no blocks in the requested cylinder, so take next + * available one in this cylinder group. + */ + bno = ffs_mapsearch(fs, cgp, bpref, (int)fs->fs_frag); + if (bno < 0) + return (NULL); + cgp->cg_rotor = bno; +gotit: + blkno = fragstoblks(fs, bno); + ffs_clrblock(fs, cg_blksfree(cgp), (long)blkno); + ffs_clusteracct(fs, cgp, blkno, -1); + cgp->cg_cs.cs_nbfree--; + fs->fs_cstotal.cs_nbfree--; + fs->fs_cs(fs, cgp->cg_cgx).cs_nbfree--; + cylno = cbtocylno(fs, bno); + cg_blks(fs, cgp, cylno)[cbtorpos(fs, bno)]--; + cg_blktot(cgp)[cylno]--; + fs->fs_fmod = 1; + return (cgp->cg_cgx * fs->fs_fpg + bno); +} + +/* + * Determine whether a cluster can be allocated. + * + * We do not currently check for optimal rotational layout if there + * are multiple choices in the same cylinder group. Instead we just + * take the first one that we find following bpref. + */ +static daddr_t +ffs_clusteralloc(ip, cg, bpref, len) + struct inode *ip; + int cg; + daddr_t bpref; + int len; +{ + register struct fs *fs; + register struct cg *cgp; + struct buf *bp; + int i, run, bno, bit, map; + u_char *mapp; + + fs = ip->i_fs; + if (fs->fs_cs(fs, cg).cs_nbfree < len) + return (NULL); + if (bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize, + NOCRED, &bp)) + goto fail; + cgp = (struct cg *)bp->b_data; + if (!cg_chkmagic(cgp)) + goto fail; + /* + * Check to see if a cluster of the needed size (or bigger) is + * available in this cylinder group. + */ + for (i = len; i <= fs->fs_contigsumsize; i++) + if (cg_clustersum(cgp)[i] > 0) + break; + if (i > fs->fs_contigsumsize) + goto fail; + /* + * Search the cluster map to find a big enough cluster. + * We take the first one that we find, even if it is larger + * than we need as we prefer to get one close to the previous + * block allocation. We do not search before the current + * preference point as we do not want to allocate a block + * that is allocated before the previous one (as we will + * then have to wait for another pass of the elevator + * algorithm before it will be read). We prefer to fail and + * be recalled to try an allocation in the next cylinder group. + */ + if (dtog(fs, bpref) != cg) + bpref = 0; + else + bpref = fragstoblks(fs, dtogd(fs, blknum(fs, bpref))); + mapp = &cg_clustersfree(cgp)[bpref / NBBY]; + map = *mapp++; + bit = 1 << (bpref % NBBY); + for (run = 0, i = bpref; i < cgp->cg_nclusterblks; i++) { + if ((map & bit) == 0) { + run = 0; + } else { + run++; + if (run == len) + break; + } + if ((i & (NBBY - 1)) != (NBBY - 1)) { + bit <<= 1; + } else { + map = *mapp++; + bit = 1; + } + } + if (i == cgp->cg_nclusterblks) + goto fail; + /* + * Allocate the cluster that we have found. + */ + bno = cg * fs->fs_fpg + blkstofrags(fs, i - run + 1); + len = blkstofrags(fs, len); + for (i = 0; i < len; i += fs->fs_frag) + if (ffs_alloccgblk(fs, cgp, bno + i) != bno + i) + panic("ffs_clusteralloc: lost block"); + brelse(bp); + return (bno); + +fail: + brelse(bp); + return (0); } /* @@ -771,72 +1070,77 @@ alloccgblk(struct cg *cgp, * 2) allocate the next available inode after the requested * inode in the specified cylinder group. */ -static u_long -ialloccg(int cg, - volatile daddr_t ipref, - int modein) +static ino_t +ffs_nodealloccg(ip, cg, ipref, mode) + struct inode *ip; + int cg; + daddr_t ipref; + int mode; { - struct cg *cgp; - int start, len, loc, map, i; - mode_t mode = (mode_t) modein; - - if (csum[cg].cs_nifree == 0) - return 0; - - cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); + register struct fs *fs; + register struct cg *cgp; + struct buf *bp; + int error, start, len, loc, map, i; - if (diskfs_catch_exception ()) - return 0; - - if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) - { - printf ("Cylinder group %d bad magic number: %ld/%ld\n", - cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); - diskfs_end_catch_exception (); - return 0; - } - cgp->cg_time = diskfs_mtime->seconds; - if (ipref) - { - ipref %= sblock->fs_ipg; - if (isclr(cg_inosused(cgp), ipref)) - goto gotit; - } - start = cgp->cg_irotor / NBBY; - len = howmany(sblock->fs_ipg - cgp->cg_irotor, NBBY); - loc = skpc(0xff, len, (u_char *) &cg_inosused(cgp)[start]); - if (loc == 0) - { - len = start + 1; - start = 0; - loc = skpc(0xff, len, (u_char *) &cg_inosused(cgp)[0]); - assert ("inconsistent cg_inosused table" && loc); - } - i = start + len - loc; - map = cg_inosused(cgp)[i]; - ipref = i * NBBY; - for (i = 1; i < (1 << NBBY); i <<= 1, ipref++) - { - if ((map & i) == 0) - { - cgp->cg_irotor = ipref; - goto gotit; + fs = ip->i_fs; + if (fs->fs_cs(fs, cg).cs_nifree == 0) + return (NULL); + error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), + (int)fs->fs_cgsize, NOCRED, &bp); + if (error) { + brelse(bp); + return (NULL); + } + cgp = (struct cg *)bp->b_data; + if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) { + brelse(bp); + return (NULL); + } + cgp->cg_time = time.tv_sec; + if (ipref) { + ipref %= fs->fs_ipg; + if (isclr(cg_inosused(cgp), ipref)) + goto gotit; + } + start = cgp->cg_irotor / NBBY; + len = howmany(fs->fs_ipg - cgp->cg_irotor, NBBY); + loc = skpc(0xff, len, &cg_inosused(cgp)[start]); + if (loc == 0) { + len = start + 1; + start = 0; + loc = skpc(0xff, len, &cg_inosused(cgp)[0]); + if (loc == 0) { + printf("cg = %d, irotor = %d, fs = %s\n", + cg, cgp->cg_irotor, fs->fs_fsmnt); + panic("ffs_nodealloccg: map corrupted"); + /* NOTREACHED */ + } + } + i = start + len - loc; + map = cg_inosused(cgp)[i]; + ipref = i * NBBY; + for (i = 1; i < (1 << NBBY); i <<= 1, ipref++) { + if ((map & i) == 0) { + cgp->cg_irotor = ipref; + goto gotit; + } + } + printf("fs = %s\n", fs->fs_fsmnt); + panic("ffs_nodealloccg: block not in map"); + /* NOTREACHED */ +gotit: + setbit(cg_inosused(cgp), ipref); + cgp->cg_cs.cs_nifree--; + fs->fs_cstotal.cs_nifree--; + fs->fs_cs(fs, cg).cs_nifree--; + fs->fs_fmod = 1; + if ((mode & IFMT) == IFDIR) { + cgp->cg_cs.cs_ndir++; + fs->fs_cstotal.cs_ndir++; + fs->fs_cs(fs, cg).cs_ndir++; } - } - assert ("inconsistent cg_inosused table" && 0); - gotit: - setbit(cg_inosused(cgp), ipref); - cgp->cg_cs.cs_nifree--; - sblock->fs_cstotal.cs_nifree--; - csum[cg].cs_nifree--; - if ((mode & IFMT) == IFDIR) - { - cgp->cg_cs.cs_ndir++; - sblock->fs_cstotal.cs_ndir++; - csum[cg].cs_ndir++; - } - diskfs_end_catch_exception (); - return (u_long)(cg * sblock->fs_ipg + ipref); + bdwrite(bp); + return (cg * fs->fs_ipg + ipref); } /* @@ -846,99 +1150,103 @@ ialloccg(int cg, * free map. If a fragment is deallocated, a possible * block reassembly is checked. */ -void -blkfree(volatile daddr_t bno, - int size) +ffs_blkfree(ip, bno, size) + register struct inode *ip; + daddr_t bno; + long size; { - struct cg *cgp; - int cg, blk, frags, bbase; - int i; - - assert ("free of bad sized block" &&(unsigned) size <= sblock->fs_bsize - && !fragoff (size) && size != 0); - cg = dtog(bno); - if ((unsigned)bno >= sblock->fs_size) - { - printf("bad block %ld\n", bno); - return; - } + register struct fs *fs; + register struct cg *cgp; + struct buf *bp; + daddr_t blkno; + int i, error, cg, blk, frags, bbase; - cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); - - spin_lock (&alloclock); - - if (diskfs_catch_exception ()) - { - spin_unlock (&alloclock); - return; - } - - if (!cg_chkmagic(cgp)) - { - spin_unlock (&alloclock); - printf ("Cylinder group %d bad magic number: %ld/%ld\n", - cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); - diskfs_end_catch_exception (); - return; - } - cgp->cg_time = diskfs_mtime->seconds; - bno = dtogd(bno); - if (size == sblock->fs_bsize) - { - assert ("inconsistent cg_blskfree table" - && !isblock (cg_blksfree (cgp), fragstoblks (bno))); - setblock(cg_blksfree(cgp), fragstoblks(bno)); - cgp->cg_cs.cs_nbfree++; - sblock->fs_cstotal.cs_nbfree++; - csum[cg].cs_nbfree++; - i = cbtocylno(bno); - cg_blks(cgp, i)[cbtorpos(bno)]++; - cg_blktot(cgp)[i]++; - } - else - { - bbase = bno - fragnum(bno); - /* - * decrement the counts associated with the old frags - */ - blk = blkmap(cg_blksfree(cgp), bbase); - fragacct(blk, cgp->cg_frsum, -1); - /* - * deallocate the fragment - */ - frags = numfrags(size); - for (i = 0; i < frags; i++) - { - assert ("inconsistent cg_blksfree table" - && !isset (cg_blksfree (cgp), bno + i)); - setbit(cg_blksfree(cgp), bno + i); + fs = ip->i_fs; + if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) { + printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n", + ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt); + panic("blkfree: bad size"); + } + cg = dtog(fs, bno); + if ((u_int)bno >= fs->fs_size) { + printf("bad block %d, ino %d\n", bno, ip->i_number); + ffs_fserr(fs, ip->i_uid, "bad block"); + return; } - cgp->cg_cs.cs_nffree += i; - sblock->fs_cstotal.cs_nffree += i; - csum[cg].cs_nffree += i; - /* - * add back in counts associated with the new frags - */ - blk = blkmap(cg_blksfree(cgp), bbase); - fragacct(blk, cgp->cg_frsum, 1); - /* - * if a complete block has been reassembled, account for it - */ - if (isblock(cg_blksfree(cgp), (daddr_t)fragstoblks(bbase))) - { - cgp->cg_cs.cs_nffree -= sblock->fs_frag; - sblock->fs_cstotal.cs_nffree -= sblock->fs_frag; - csum[cg].cs_nffree -= sblock->fs_frag; - cgp->cg_cs.cs_nbfree++; - sblock->fs_cstotal.cs_nbfree++; - csum[cg].cs_nbfree++; - i = cbtocylno(bbase); - cg_blks(cgp, i)[cbtorpos(bbase)]++; - cg_blktot(cgp)[i]++; + error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), + (int)fs->fs_cgsize, NOCRED, &bp); + if (error) { + brelse(bp); + return; } - } - spin_unlock (&alloclock); - diskfs_end_catch_exception (); + cgp = (struct cg *)bp->b_data; + if (!cg_chkmagic(cgp)) { + brelse(bp); + return; + } + cgp->cg_time = time.tv_sec; + bno = dtogd(fs, bno); + if (size == fs->fs_bsize) { + blkno = fragstoblks(fs, bno); + if (ffs_isblock(fs, cg_blksfree(cgp), blkno)) { + printf("dev = 0x%x, block = %d, fs = %s\n", + ip->i_dev, bno, fs->fs_fsmnt); + panic("blkfree: freeing free block"); + } + ffs_setblock(fs, cg_blksfree(cgp), blkno); + ffs_clusteracct(fs, cgp, blkno, 1); + cgp->cg_cs.cs_nbfree++; + fs->fs_cstotal.cs_nbfree++; + fs->fs_cs(fs, cg).cs_nbfree++; + i = cbtocylno(fs, bno); + cg_blks(fs, cgp, i)[cbtorpos(fs, bno)]++; + cg_blktot(cgp)[i]++; + } else { + bbase = bno - fragnum(fs, bno); + /* + * decrement the counts associated with the old frags + */ + blk = blkmap(fs, cg_blksfree(cgp), bbase); + ffs_fragacct(fs, blk, cgp->cg_frsum, -1); + /* + * deallocate the fragment + */ + frags = numfrags(fs, size); + for (i = 0; i < frags; i++) { + if (isset(cg_blksfree(cgp), bno + i)) { + printf("dev = 0x%x, block = %d, fs = %s\n", + ip->i_dev, bno + i, fs->fs_fsmnt); + panic("blkfree: freeing free frag"); + } + setbit(cg_blksfree(cgp), bno + i); + } + cgp->cg_cs.cs_nffree += i; + fs->fs_cstotal.cs_nffree += i; + fs->fs_cs(fs, cg).cs_nffree += i; + /* + * add back in counts associated with the new frags + */ + blk = blkmap(fs, cg_blksfree(cgp), bbase); + ffs_fragacct(fs, blk, cgp->cg_frsum, 1); + /* + * if a complete block has been reassembled, account for it + */ + blkno = fragstoblks(fs, bbase); + if (ffs_isblock(fs, cg_blksfree(cgp), blkno)) { + cgp->cg_cs.cs_nffree -= fs->fs_frag; + fs->fs_cstotal.cs_nffree -= fs->fs_frag; + fs->fs_cs(fs, cg).cs_nffree -= fs->fs_frag; + ffs_clusteracct(fs, cgp, blkno, 1); + cgp->cg_cs.cs_nbfree++; + fs->fs_cstotal.cs_nbfree++; + fs->fs_cs(fs, cg).cs_nbfree++; + i = cbtocylno(fs, bbase); + cg_blks(fs, cgp, i)[cbtorpos(fs, bbase)]++; + cg_blktot(cgp)[i]++; + } + } + fs->fs_fmod = 1; + bdwrite(bp); } /* @@ -946,111 +1254,221 @@ blkfree(volatile daddr_t bno, * * The specified inode is placed back in the free map. */ -void -diskfs_free_node(struct node *np, mode_t mode) +int +ffs_vfree(ap) + struct vop_vfree_args /* { + struct vnode *a_pvp; + ino_t a_ino; + int a_mode; + } */ *ap; { - struct cg *cgp; - int cg; - volatile int ino = np->dn->number; - - assert ("invalid inode number" && ino < sblock->fs_ipg * sblock->fs_ncg); - - cg = itog(ino); - cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); + register struct fs *fs; + register struct cg *cgp; + register struct inode *pip; + ino_t ino = ap->a_ino; + struct buf *bp; + int error, cg; - spin_lock (&alloclock); - if (diskfs_catch_exception ()) - { - spin_unlock (&alloclock); - return; - } - - if (!cg_chkmagic(cgp)) - { - spin_unlock (&alloclock); - printf ("Cylinder group %d bad magic number: %ld/%ld\n", - cg, cgp->cg_magic, ((struct ocg *)(cgp))->cg_magic); - diskfs_end_catch_exception (); - return; - } - cgp->cg_time = diskfs_mtime->seconds; - ino %= sblock->fs_ipg; - assert ("inconsistent cg_inosused table" && !isclr (cg_inosused (cgp), ino)); - clrbit(cg_inosused(cgp), ino); - if (ino < cgp->cg_irotor) - cgp->cg_irotor = ino; - cgp->cg_cs.cs_nifree++; - sblock->fs_cstotal.cs_nifree++; - csum[cg].cs_nifree++; - if ((mode & IFMT) == IFDIR) - { - cgp->cg_cs.cs_ndir--; - sblock->fs_cstotal.cs_ndir--; - csum[cg].cs_ndir--; - } - spin_unlock (&alloclock); - diskfs_end_catch_exception (); + pip = VTOI(ap->a_pvp); + fs = pip->i_fs; + if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) + panic("ifree: range: dev = 0x%x, ino = %d, fs = %s\n", + pip->i_dev, ino, fs->fs_fsmnt); + cg = ino_to_cg(fs, ino); + error = bread(pip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), + (int)fs->fs_cgsize, NOCRED, &bp); + if (error) { + brelse(bp); + return (0); + } + cgp = (struct cg *)bp->b_data; + if (!cg_chkmagic(cgp)) { + brelse(bp); + return (0); + } + cgp->cg_time = time.tv_sec; + ino %= fs->fs_ipg; + if (isclr(cg_inosused(cgp), ino)) { + printf("dev = 0x%x, ino = %d, fs = %s\n", + pip->i_dev, ino, fs->fs_fsmnt); + if (fs->fs_ronly == 0) + panic("ifree: freeing free inode"); + } + clrbit(cg_inosused(cgp), ino); + if (ino < cgp->cg_irotor) + cgp->cg_irotor = ino; + cgp->cg_cs.cs_nifree++; + fs->fs_cstotal.cs_nifree++; + fs->fs_cs(fs, cg).cs_nifree++; + if ((ap->a_mode & IFMT) == IFDIR) { + cgp->cg_cs.cs_ndir--; + fs->fs_cstotal.cs_ndir--; + fs->fs_cs(fs, cg).cs_ndir--; + } + fs->fs_fmod = 1; + bdwrite(bp); + return (0); } - /* * Find a block of the specified size in the specified cylinder group. * * It is a panic if a request is made to find a block if none are * available. */ -/* This routine expects to be called from inside a diskfs_catch_exception */ static daddr_t -mapsearch(struct cg *cgp, - daddr_t bpref, - int allocsiz) +ffs_mapsearch(fs, cgp, bpref, allocsiz) + register struct fs *fs; + register struct cg *cgp; + daddr_t bpref; + int allocsiz; +{ + daddr_t bno; + int start, len, loc, i; + int blk, field, subfield, pos; + + /* + * find the fragment by searching through the free block + * map for an appropriate bit pattern + */ + if (bpref) + start = dtogd(fs, bpref) / NBBY; + else + start = cgp->cg_frotor / NBBY; + len = howmany(fs->fs_fpg, NBBY) - start; + loc = scanc((u_int)len, (u_char *)&cg_blksfree(cgp)[start], + (u_char *)fragtbl[fs->fs_frag], + (u_char)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY)))); + if (loc == 0) { + len = start + 1; + start = 0; + loc = scanc((u_int)len, (u_char *)&cg_blksfree(cgp)[0], + (u_char *)fragtbl[fs->fs_frag], + (u_char)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY)))); + if (loc == 0) { + printf("start = %d, len = %d, fs = %s\n", + start, len, fs->fs_fsmnt); + panic("ffs_alloccg: map corrupted"); + /* NOTREACHED */ + } + } + bno = (start + len - loc) * NBBY; + cgp->cg_frotor = bno; + /* + * found the byte in the map + * sift through the bits to find the selected frag + */ + for (i = bno + NBBY; bno < i; bno += fs->fs_frag) { + blk = blkmap(fs, cg_blksfree(cgp), bno); + blk <<= 1; + field = around[allocsiz]; + subfield = inside[allocsiz]; + for (pos = 0; pos <= fs->fs_frag - allocsiz; pos++) { + if ((blk & field) == subfield) + return (bno + pos); + field <<= 1; + subfield <<= 1; + } + } + printf("bno = %d, fs = %s\n", bno, fs->fs_fsmnt); + panic("ffs_alloccg: block not in map"); + return (-1); +} + +/* + * Update the cluster map because of an allocation or free. + * + * Cnt == 1 means free; cnt == -1 means allocating. + */ +ffs_clusteracct(fs, cgp, blkno, cnt) + struct fs *fs; + struct cg *cgp; + daddr_t blkno; + int cnt; { - daddr_t bno; - int start, len, loc, i; - int blk, field, subfield, pos; - - /* - * find the fragment by searching through the free block - * map for an appropriate bit pattern - */ - if (bpref) - start = dtogd(bpref) / NBBY; - else - start = cgp->cg_frotor / NBBY; - len = howmany(sblock->fs_fpg, NBBY) - start; - loc = scanc((unsigned)len, (u_char *)&cg_blksfree(cgp)[start], - (u_char *)fragtbl[sblock->fs_frag], - (u_char)(1 << (allocsiz - 1 + (sblock->fs_frag % NBBY)))); - if (loc == 0) - { - len = start + 1; - start = 0; - loc = scanc((unsigned)len, (u_char *)&cg_blksfree(cgp)[0], - (u_char *)fragtbl[sblock->fs_frag], - (u_char)(1 << (allocsiz - 1 + (sblock->fs_frag % NBBY)))); - assert ("incosistent cg_blksfree table" && loc); - } - bno = (start + len - loc) * NBBY; - cgp->cg_frotor = bno; - /* - * found the byte in the map - * sift through the bits to find the selected frag - */ - for (i = bno + NBBY; bno < i; bno += sblock->fs_frag) - { - blk = blkmap(cg_blksfree(cgp), bno); - blk <<= 1; - field = around[allocsiz]; - subfield = inside[allocsiz]; - for (pos = 0; pos <= sblock->fs_frag - allocsiz; pos++) - { - if ((blk & field) == subfield) - return (bno + pos); - field <<= 1; - subfield <<= 1; + long *sump; + u_char *freemapp, *mapp; + int i, start, end, forw, back, map, bit; + + if (fs->fs_contigsumsize <= 0) + return; + freemapp = cg_clustersfree(cgp); + sump = cg_clustersum(cgp); + /* + * Allocate or clear the actual block. + */ + if (cnt > 0) + setbit(freemapp, blkno); + else + clrbit(freemapp, blkno); + /* + * Find the size of the cluster going forward. + */ + start = blkno + 1; + end = start + fs->fs_contigsumsize; + if (end >= cgp->cg_nclusterblks) + end = cgp->cg_nclusterblks; + mapp = &freemapp[start / NBBY]; + map = *mapp++; + bit = 1 << (start % NBBY); + for (i = start; i < end; i++) { + if ((map & bit) == 0) + break; + if ((i & (NBBY - 1)) != (NBBY - 1)) { + bit <<= 1; + } else { + map = *mapp++; + bit = 1; + } + } + forw = i - start; + /* + * Find the size of the cluster going backward. + */ + start = blkno - 1; + end = start - fs->fs_contigsumsize; + if (end < 0) + end = -1; + mapp = &freemapp[start / NBBY]; + map = *mapp--; + bit = 1 << (start % NBBY); + for (i = start; i > end; i--) { + if ((map & bit) == 0) + break; + if ((i & (NBBY - 1)) != 0) { + bit >>= 1; + } else { + map = *mapp--; + bit = 1 << (NBBY - 1); + } } - } - assert ("inconsistent cg_blksfree table" && 0); + back = start - i; + /* + * Account for old cluster and the possibly new forward and + * back clusters. + */ + i = back + forw + 1; + if (i > fs->fs_contigsumsize) + i = fs->fs_contigsumsize; + sump[i] += cnt; + if (back > 0) + sump[back] -= cnt; + if (forw > 0) + sump[forw] -= cnt; } +/* + * Fserr prints the name of a file system with an error diagnostic. + * + * The form of the error message is: + * fs: error message + */ +static void +ffs_fserr(fs, uid, cp) + struct fs *fs; + u_int uid; + char *cp; +{ + log(LOG_ERR, "uid %d on %s: %s\n", uid, fs->fs_fsmnt, cp); +} -- cgit v1.2.3 From 45a96b9898b4a57446a70bbb49c9d3da114f1a58 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 21:12:31 +0000 Subject: Formerly fs.h.~4~ --- ufs/fs.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ufs') diff --git a/ufs/fs.h b/ufs/fs.h index bef052fe..7a4e6d7c 100644 --- a/ufs/fs.h +++ b/ufs/fs.h @@ -281,6 +281,7 @@ struct fs { /* cluster sum */ (fs)->fs_contigsumsize * sizeof(long) + \ /* cluster map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPB(fs), NBBY))) +#if 0 /* Wrong for GNU Hurd ufs; we don't use fs_csp at all. */ /* * Convert cylinder group to base address of its global summary info. * @@ -288,6 +289,11 @@ struct fs { */ #define fs_cs(fs, indx) \ fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask] +#else +/* Global variable csum is declared in ufs.h; use it instead + of fs_cs stuff. */ +#define fs_cs(fs, indx) this will generate a syntax error. +#endif /* * Cylinder group block for a file system. -- cgit v1.2.3 From af1078995f8e299fcd3c054cb24622dd08dbb699 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 21:36:26 +0000 Subject: Formerly ufs.h.~15~ --- ufs/ufs.h | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 920134ef..f6769916 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -179,6 +179,22 @@ int nextgennumber; mach_port_t ufs_device; +/* The compat_mode specifies whether or not we write + extensions onto the disk. */ +enum compat_mode +{ + COMPAT_GNU = 0, + COMPAT_BSD42 = 1, + COMPAT_BSD44 = 2, +}; + +/* If this is set, then this filesystem has two extensions: + 1) directory entries include the type field. + 2) symlink targets might be written directly in the di_db field + of the dinode. */ +int direct_symlink_extension; + + #define DEV_BSIZE 512 #define NBBY 8 #define btodb(n) ((n) / DEV_BSIZE) @@ -190,11 +206,11 @@ mach_port_t ufs_device; #define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<(i)%NBBY)) /* From alloc.c: */ -error_t alloc (struct node *, daddr_t, daddr_t, int, daddr_t *, - struct protid *); -void blkfree(volatile daddr_t bno, int size); -daddr_t blkpref (struct node *, daddr_t, int, daddr_t *); -error_t realloccg(struct node *, daddr_t, daddr_t, +error_t ffs_alloc (struct node *, daddr_t, daddr_t, int, daddr_t *, + struct protid *); +void ffs_blkfree(struct node *, volatile daddr_t bno, int size); +daddr_t ffs_blkpref (struct node *, daddr_t, int, daddr_t *); +error_t ffs_realloccg(struct node *, daddr_t, daddr_t, int, int, daddr_t *, struct protid *); /* From devio.c: */ -- cgit v1.2.3 From 556b10d5fc783b7f8059856315de9a4232b339c7 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 21:40:31 +0000 Subject: Formerly sizes.c.~15~ --- ufs/sizes.c | 56 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 423c13bb..d7f132c0 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -49,6 +49,25 @@ diskfs_truncate (struct node *np, if (length >= osize) return 0; + /* Check to see if this is a kludged symlink. */ + if (direct_symlink_extension && S_ISLNK (np->dn_stat.st_mode) + && osize < sblock->fs_maxsymlinklen) + { + error_t err; + + /* Prune it here */ + err = diskfs_catch_exception (); + if (err) + return err; + + bzero (dinodes[np->dn->number].di_shortlink + length, + osize - length); + diskfs_end_catch_exception (); + np->dn_stat.st_size = length; + np->dn_set_ctime = 1; + np->dn_set_mtime = 1; + } + /* Calculate block number of last block */ lastblock = lblkno (length + sblock->fs_bsize - 1) - 1; olastblock = lblkno (osize + sblock->fs_bsize - 1) - 1; @@ -109,7 +128,7 @@ diskfs_truncate (struct node *np, { if (np->dn->sinloc[idx - NDADDR]) { - blkfree (np->dn->sinloc[idx - NDADDR], sblock->fs_bsize); + ffs_blkfree (np, np->dn->sinloc[idx - NDADDR], sblock->fs_bsize); np->dn->sinloc[idx - NDADDR] = 0; np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; np->dn_stat_dirty = 1; @@ -138,7 +157,7 @@ diskfs_truncate (struct node *np, bsize = blksize (np, idx); else bsize = sblock->fs_bsize; - blkfree (bn, bsize); + ffs_blkfree (np, bn, bsize); np->dn_stat.st_blocks -= bsize / DEV_BSIZE; np->dn_stat_dirty = 1; } @@ -158,7 +177,7 @@ diskfs_truncate (struct node *np, if (oldspace - newspace) { bn += numfrags (newspace); - blkfree (bn, oldspace - newspace); + ffs_blkfree (np, bn, oldspace - newspace); np->dn_stat.st_blocks -= (oldspace - newspace) / DEV_BSIZE; np->dn_stat_dirty = 1; } @@ -192,7 +211,8 @@ dindir_drop (struct node *np) if (dinodes[np->dn->number].di_ib[INDIR_DOUBLE]) { - blkfree (dinodes[np->dn->number].di_ib[INDIR_DOUBLE], sblock->fs_bsize); + ffs_blkfree (np, dinodes[np->dn->number].di_ib[INDIR_DOUBLE], + sblock->fs_bsize); dinodes[np->dn->number].di_ib[INDIR_DOUBLE] = 0; np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; } @@ -225,7 +245,7 @@ sindir_drop (struct node *np, { if (np->dn->dinloc[idx - 1]) { - blkfree (np->dn->dinloc[idx - 1], sblock->fs_bsize); + ffs_blkfree (np, np->dn->dinloc[idx - 1], sblock->fs_bsize); np->dn->dinloc[idx - 1] = 0; np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; } @@ -244,7 +264,8 @@ sindir_drop (struct node *np, /* Drop the block from the inode if we don't need it any more */ if (first == 0 && dinodes[np->dn->number].di_ib[INDIR_SINGLE]) { - blkfree (dinodes[np->dn->number].di_ib[INDIR_SINGLE], sblock->fs_bsize); + ffs_blkfree (np, dinodes[np->dn->number].di_ib[INDIR_SINGLE], + sblock->fs_bsize); dinodes[np->dn->number].di_ib[INDIR_SINGLE] = 0; np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; } @@ -312,7 +333,7 @@ diskfs_grow (struct node *np, if (err = diskfs_catch_exception()) { if (dealloc_on_error) - blkfree (dealloc_on_error, dealloc_size); + ffs_blkfree (np, dealloc_on_error, dealloc_size); goto out; } @@ -334,8 +355,8 @@ diskfs_grow (struct node *np, if (osize < sblock->fs_bsize && osize > 0) { daddr_t old_pbn; - err = realloccg (np, nb, - blkpref (np, nb, (int)nb, + err = ffs_realloccg (np, nb, + ffs_blkpref (np, nb, (int)nb, dinodes[np->dn->number].di_db), osize, sblock->fs_bsize, &pbn, cred); if (err) @@ -372,8 +393,8 @@ diskfs_grow (struct node *np, osize = sblock->fs_bsize; if (size > osize) { - err = realloccg (np, lbn, - blkpref (np, lbn, lbn, + err = ffs_realloccg (np, lbn, + ffs_blkpref (np, lbn, lbn, dinodes[np->dn->number].di_db), osize, size, &pbn, cred); if (err) @@ -396,9 +417,10 @@ diskfs_grow (struct node *np, } else { - err = alloc (np, lbn, - blkpref (np, lbn, lbn, dinodes[np->dn->number].di_db), - size, &pbn, cred); + err = ffs_alloc (np, lbn, + ffs_blkpref (np, lbn, lbn, + dinodes[np->dn->number].di_db), + size, &pbn, cred); if (err) goto out; dealloc_on_error = pbn; @@ -425,9 +447,9 @@ diskfs_grow (struct node *np, lbn -= NDADDR; if (!np->dn->sinloc[lbn]) { - err = alloc (np, lbn, blkpref (np, lbn + NDADDR, lbn, - np->dn->sinloc), - sblock->fs_bsize, &pbn, cred); + err = ffs_alloc (np, lbn, ffs_blkpref (np, lbn + NDADDR, lbn, + np->dn->sinloc), + sblock->fs_bsize, &pbn, cred); if (err) goto out; dealloc_on_error = pbn; -- cgit v1.2.3 From 7b0c5fe429fd598011edd4c2c0cae008263b8467 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 21:45:29 +0000 Subject: Formerly alloc.c.~12~ --- ufs/alloc.c | 531 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 275 insertions(+), 256 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index cdd2e4b2..7dfe5785 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -1,3 +1,23 @@ +/* Disk allocation routines + Copyright (C) 1993, 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Modified from UCB by Michael I. Bushnell. */ /* * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -33,35 +53,18 @@ * @(#)ffs_alloc.c 8.8 (Berkeley) 2/21/94 */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include "ufs.h" +#include "fs.h" +#include "dinode.h" +#include -#include -#include - -#include -#include +/* These don't work *at all* here; don't even try setting them. */ +#undef DIAGNOSTIC +#undef QUOTA extern u_long nextgennumber; -static daddr_t ffs_alloccg __P((struct inode *, int, daddr_t, int)); -static daddr_t ffs_alloccgblk __P((struct fs *, struct cg *, daddr_t)); -static daddr_t ffs_clusteralloc __P((struct inode *, int, daddr_t, int)); -static ino_t ffs_dirpref __P((struct fs *)); -static daddr_t ffs_fragextend __P((struct inode *, int, long, int, int)); -static void ffs_fserr __P((struct fs *, u_int, char *)); -static u_long ffs_hashalloc - __P((struct inode *, int, long, int, u_long (*)())); -static ino_t ffs_nodealloccg __P((struct inode *, int, daddr_t, int)); -static daddr_t ffs_mapsearch __P((struct fs *, struct cg *, daddr_t, int)); +spin_lock_t alloclock = SPIN_LOCK_INITIALIZER; /* * Allocate a block in the file system. @@ -82,31 +85,32 @@ static daddr_t ffs_mapsearch __P((struct fs *, struct cg *, daddr_t, int)); * 2) quadradically rehash into other cylinder groups, until an * available block is located. */ -ffs_alloc(ip, lbn, bpref, size, cred, bnp) - register struct inode *ip; - daddr_t lbn, bpref; - int size; - struct ucred *cred; - daddr_t *bnp; +ffs_alloc(register struct node *np, + daddr_t lbn, + daddr_t bpref, + int size, + daddr_t *bnp, + struct protid *cred) { register struct fs *fs; daddr_t bno; int cg, error; *bnp = 0; - fs = ip->i_fs; + fs = sblock; #ifdef DIAGNOSTIC if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) { printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n", ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt); panic("ffs_alloc: bad size"); } - if (cred == NOCRED) - panic("ffs_alloc: missing credential\n"); + assert (cred); #endif /* DIAGNOSTIC */ + spin_lock (&alloclock); if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0) goto nospace; - if (cred->cr_uid != 0 && freespace(fs, fs->fs_minfree) <= 0) + if (cred && !diskfs_isuid (0, cred) + && freespace(fs, fs->fs_minfree) <= 0) goto nospace; #ifdef QUOTA if (error = chkdq(ip, (long)btodb(size), cred, 0)) @@ -115,14 +119,16 @@ ffs_alloc(ip, lbn, bpref, size, cred, bnp) if (bpref >= fs->fs_size) bpref = 0; if (bpref == 0) - cg = ino_to_cg(fs, ip->i_number); + cg = ino_to_cg(fs, np->dn->number); else cg = dtog(fs, bpref); - bno = (daddr_t)ffs_hashalloc(ip, cg, (long)bpref, size, + bno = (daddr_t)ffs_hashalloc(np, cg, (long)bpref, size, (u_long (*)())ffs_alloccg); if (bno > 0) { - ip->i_blocks += btodb(size); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + spin_unlock (&alloclock); + np->dn_stat.st_blocks += btodb(size); + np->dn_set_ctime = 1; + np->dn_set_mtime = 1; *bnp = bno; return (0); } @@ -133,8 +139,10 @@ ffs_alloc(ip, lbn, bpref, size, cred, bnp) (void) chkdq(ip, (long)-btodb(size), cred, FORCE); #endif nospace: - ffs_fserr(fs, cred->cr_uid, "file system full"); - uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); + spin_unlock (&alloclock); + printf ("file system full"); +/* ffs_fserr(fs, cred->cr_uid, "file system full"); */ +/* uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); */ return (ENOSPC); } @@ -146,21 +154,20 @@ nospace: * the original block. Failing that, the regular block allocator is * invoked to get an appropriate block. */ -ffs_realloccg(ip, lbprev, bpref, osize, nsize, cred, bpp) - register struct inode *ip; - daddr_t lbprev; - daddr_t bpref; - int osize, nsize; - struct ucred *cred; - struct buf **bpp; +ffs_realloccg(register struct node *np, + daddr_t lbprev, + daddr_t bpref, + int osize, + int nsize, + daddr_t *pbn, + struct protid *cred) { register struct fs *fs; - struct buf *bp; int cg, request, error; daddr_t bprev, bno; - *bpp = 0; - fs = ip->i_fs; + *pbn = 0; + fs = sblock; #ifdef DIAGNOSTIC if ((u_int)osize > fs->fs_bsize || fragoff(fs, osize) != 0 || (u_int)nsize > fs->fs_bsize || fragoff(fs, nsize) != 0) { @@ -172,13 +179,18 @@ ffs_realloccg(ip, lbprev, bpref, osize, nsize, cred, bpp) if (cred == NOCRED) panic("ffs_realloccg: missing credential\n"); #endif /* DIAGNOSTIC */ - if (cred->cr_uid != 0 && freespace(fs, fs->fs_minfree) <= 0) + + spin_lock (&alloclock); + + if (!isuid (0, cred) && freespace(fs, fs->fs_minfree) <= 0) goto nospace; - if ((bprev = ip->i_db[lbprev]) == 0) { - printf("dev = 0x%x, bsize = %d, bprev = %d, fs = %s\n", - ip->i_dev, fs->fs_bsize, bprev, fs->fs_fsmnt); - panic("ffs_realloccg: bad bprev"); - } + if (error = diskfs_catch_exception ()) + return error; + bprev = dinodes[np->dn->number].di_db[lbprev]; + diskfs_end_catch_exception (); + assert ("old block not allocated" && bprev); + +#if 0 /* Not needed in GNU Hurd ufs */ /* * Allocate the extra space in the buffer. */ @@ -192,19 +204,25 @@ ffs_realloccg(ip, lbprev, bpref, osize, nsize, cred, bpp) return (error); } #endif +#endif /* 0 */ + /* * Check for extension in the existing location. */ cg = dtog(fs, bprev); - if (bno = ffs_fragextend(ip, cg, (long)bprev, osize, nsize)) { - if (bp->b_blkno != fsbtodb(fs, bno)) - panic("bad blockno"); - ip->i_blocks += btodb(nsize - osize); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + if (bno = ffs_fragextend(np, cg, (long)bprev, osize, nsize)) { + assert (bno == bprev); + spin_unlock (&alloclock); + np->dn_stat.st_blocks += btodb(nsize - osize); + np->dn_set_ctime = 1; + np->dn_set_mtime = 1; + *pbn = bno; +#if 0 /* Not done this way in GNU Hurd ufs. */ allocbuf(bp, nsize); bp->b_flags |= B_DONE; bzero((char *)bp->b_data + osize, (u_int)nsize - osize); *bpp = bp; +#endif return (0); } /* @@ -252,24 +270,31 @@ ffs_realloccg(ip, lbprev, bpref, osize, nsize, cred, bpp) default: printf("dev = 0x%x, optim = %d, fs = %s\n", ip->i_dev, fs->fs_optim, fs->fs_fsmnt); - panic("ffs_realloccg: bad optim"); + assert (0); /* NOTREACHED */ } - bno = (daddr_t)ffs_hashalloc(ip, cg, (long)bpref, request, + bno = (daddr_t)ffs_hashalloc(np, cg, (long)bpref, request, (u_long (*)())ffs_alloccg); if (bno > 0) { +#if 0 /* Not necessary in GNU Hurd ufs */ bp->b_blkno = fsbtodb(fs, bno); (void) vnode_pager_uncache(ITOV(ip)); - ffs_blkfree(ip, bprev, (long)osize); +#endif + ffs_blkfree(np, bprev, (long)osize); if (nsize < request) - ffs_blkfree(ip, bno + numfrags(fs, nsize), + ffs_blkfree(np, bno + numfrags(fs, nsize), (long)(request - nsize)); - ip->i_blocks += btodb(nsize - osize); - ip->i_flag |= IN_CHANGE | IN_UPDATE; + spin_unlock (&alloclock); + np->dn_stat.st_blocks += btodb(nsize - osize); + np->dn_set_mtime = 1; + np->dn_set_ctime = 1; + *pbn = bno; +#if 0 /* Not done this way in GNU Hurd ufs */ allocbuf(bp, nsize); bp->b_flags |= B_DONE; bzero((char *)bp->b_data + osize, (u_int)nsize - osize); *bpp = bp; +#endif /* 0 */ return (0); } #ifdef QUOTA @@ -278,16 +303,21 @@ ffs_realloccg(ip, lbprev, bpref, osize, nsize, cred, bpp) */ (void) chkdq(ip, (long)-btodb(nsize - osize), cred, FORCE); #endif +#if 0 /* Not necesarry in GNU Hurd ufs */ brelse(bp); +#endif nospace: /* * no space available */ - ffs_fserr(fs, cred->cr_uid, "file system full"); - uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); + spin_unlock (&alloclock); + printf ("file system full"); +/* ffs_fserr(fs, cred->cr_uid, "file system full"); */ +/* uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt); */ return (ENOSPC); } +#if 0 /* Not used (yet?) in GNU Hurd ufs */ /* * Reallocate a sequence of blocks into a contiguous sequence of blocks. * @@ -450,6 +480,7 @@ fail: brelse(sbp); return (ENOSPC); } +#endif /* 0 */ /* * Allocate an inode in the file system. @@ -466,65 +497,64 @@ fail: * 2) quadradically rehash into other cylinder groups, until an * available inode is located. */ -ffs_valloc(ap) - struct vop_valloc_args /* { - struct vnode *a_pvp; - int a_mode; - struct ucred *a_cred; - struct vnode **a_vpp; - } */ *ap; +/* This is now the diskfs_alloc_node callback from the diskfs library + (described in ). It used to be ffs_valloc in BSD. */ +error_t +diskfs_alloc_node (struct node *dir, + mode_t mode, + struct node **npp) { - register struct vnode *pvp = ap->a_pvp; - register struct inode *pip; register struct fs *fs; - register struct inode *ip; - mode_t mode = ap->a_mode; + register struct node *np; ino_t ino, ipref; int cg, error; - *ap->a_vpp = NULL; - pip = VTOI(pvp); - fs = pip->i_fs; + fs = sblock; + + + spin_lock (&alloclock); + if (fs->fs_cstotal.cs_nifree == 0) - goto noinodes; + { + spin_unlock (&alloclock); + goto noinodes; + } - if ((mode & IFMT) == IFDIR) + if (S_ISDIR (mode)) ipref = ffs_dirpref(fs); else - ipref = pip->i_number; + ipref = dir->dn->number; + if (ipref >= fs->fs_ncg * fs->fs_ipg) ipref = 0; cg = ino_to_cg(fs, ipref); - ino = (ino_t)ffs_hashalloc(pip, cg, (long)ipref, mode, ffs_nodealloccg); + ino = (ino_t)ffs_hashalloc(dir, cg, (long)ipref, + mode, ffs_nodealloccg); + spin_unlock (&alloclock); if (ino == 0) goto noinodes; - error = VFS_VGET(pvp->v_mount, ino, ap->a_vpp); - if (error) { - VOP_VFREE(pvp, ino, mode); - return (error); - } - ip = VTOI(*ap->a_vpp); - if (ip->i_mode) { - printf("mode = 0%o, inum = %d, fs = %s\n", - ip->i_mode, ip->i_number, fs->fs_fsmnt); - panic("ffs_valloc: dup alloc"); - } - if (ip->i_blocks) { /* XXX */ - printf("free inode %s/%d had %d blocks\n", - fs->fs_fsmnt, ino, ip->i_blocks); - ip->i_blocks = 0; + error = iget (ino, &np); + assert ("duplicate allocation" && !np->dn_stat.st_mode); + if (np->dn_stat.st_blocks) { + printf("free inode %d had %d blocks\n", + ino, ip->i_blocks); + np->dn_stat.st_blocks = 0; + np->dn_set_ctime = 1; } ip->i_flags = 0; /* * Set up a new generation number for this inode. */ + spin_lock (&gennumberlock); if (++nextgennumber < (u_long)time.tv_sec) nextgennumber = time.tv_sec; ip->i_gen = nextgennumber; + spin_unlock (&gennumberlock); return (0); noinodes: - ffs_fserr(fs, ap->a_cred->cr_uid, "out of inodes"); - uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt); + printf ("out of inodes"); +/* ffs_fserr(fs, ap->a_cred->cr_uid, "out of inodes"); */ +/* uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt);*/ return (ENOSPC); } @@ -536,8 +566,7 @@ noinodes: * free inodes, the one with the smallest number of directories. */ static ino_t -ffs_dirpref(fs) - register struct fs *fs; +ffs_dirpref(register struct fs *fs) { int cg, minndir, mincg, avgifree; @@ -545,10 +574,10 @@ ffs_dirpref(fs) minndir = fs->fs_ipg; mincg = 0; for (cg = 0; cg < fs->fs_ncg; cg++) - if (fs->fs_cs(fs, cg).cs_ndir < minndir && - fs->fs_cs(fs, cg).cs_nifree >= avgifree) { + if (csum[cg].cs_ndir < minndir && + csum[cg].cs_nifree >= avgifree) { mincg = cg; - minndir = fs->fs_cs(fs, cg).cs_ndir; + minndir = csum[cg].cs_ndir; } return ((ino_t)(fs->fs_ipg * mincg)); } @@ -580,21 +609,22 @@ ffs_dirpref(fs) * schedule another I/O transfer. */ daddr_t -ffs_blkpref(ip, lbn, indx, bap) - struct inode *ip; - daddr_t lbn; - int indx; - daddr_t *bap; +ffs_blkpref(struct node *np, + daddr_t lbn, + int indx, + daddr_t *bap) { register struct fs *fs; register int cg; int avgbfree, startcg; daddr_t nextblk; - fs = ip->i_fs; + fs = sblock; + spin_lock (&alloclock); if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) { if (lbn < NDADDR) { - cg = ino_to_cg(fs, ip->i_number); + cg = ino_to_cg(fs, np->dn->number); + spin_unlock (&alloclock); return (fs->fs_fpg * cg + fs->fs_frag); } /* @@ -603,23 +633,28 @@ ffs_blkpref(ip, lbn, indx, bap) */ if (indx == 0 || bap[indx - 1] == 0) startcg = - ino_to_cg(fs, ip->i_number) + lbn / fs->fs_maxbpg; + (ino_to_cg(fs, np->dn->number) + + lbn / fs->fs_maxbpg); else startcg = dtog(fs, bap[indx - 1]) + 1; startcg %= fs->fs_ncg; avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg; for (cg = startcg; cg < fs->fs_ncg; cg++) - if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) { + if (csum[cg].cs_nbfree >= avgbfree) { fs->fs_cgrotor = cg; + spin_unlock (&alloclock); return (fs->fs_fpg * cg + fs->fs_frag); } for (cg = 0; cg <= startcg; cg++) - if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) { + if (csum[cg].cs_nbfree >= avgbfree) { fs->fs_cgrotor = cg; + spin_unlock (&alloclock); return (fs->fs_fpg * cg + fs->fs_frag); } + spin_unlock (&alloclock); return (NULL); } + spin_unlock (&alloclock); /* * One or more previous blocks have been laid out. If less * than fs_maxcontig previous blocks are contiguous, the @@ -629,7 +664,9 @@ ffs_blkpref(ip, lbn, indx, bap) nextblk = bap[indx - 1] + fs->fs_frag; if (indx < fs->fs_maxcontig || bap[indx - fs->fs_maxcontig] + blkstofrags(fs, fs->fs_maxcontig) != nextblk) - return (nextblk); + { + return (nextblk); + } if (fs->fs_rotdelay != 0) /* * Here we convert ms of delay to frags as: @@ -652,22 +689,21 @@ ffs_blkpref(ip, lbn, indx, bap) */ /*VARARGS5*/ static u_long -ffs_hashalloc(ip, cg, pref, size, allocator) - struct inode *ip; - int cg; - long pref; - int size; /* size for data blocks, mode for inodes */ - u_long (*allocator)(); +ffs_hashalloc(struct node *np, + int cg, + long pref, + int size, /* size for data blocks, mode for inodes */ + u_long (*allocator)()) { register struct fs *fs; long result; int i, icg = cg; - fs = ip->i_fs; + fs = sblock; /* * 1: preferred cylinder group */ - result = (*allocator)(ip, cg, pref, size); + result = (*allocator)(np, cg, pref, size); if (result) return (result); /* @@ -677,7 +713,7 @@ ffs_hashalloc(ip, cg, pref, size, allocator) cg += i; if (cg >= fs->fs_ncg) cg -= fs->fs_ncg; - result = (*allocator)(ip, cg, 0, size); + result = (*allocator)(np, cg, 0, size); if (result) return (result); } @@ -688,7 +724,7 @@ ffs_hashalloc(ip, cg, pref, size, allocator) */ cg = (icg + 2) % fs->fs_ncg; for (i = 2; i < fs->fs_ncg; i++) { - result = (*allocator)(ip, cg, 0, size); + result = (*allocator)(np, cg, 0, size); if (result) return (result); cg++; @@ -705,11 +741,11 @@ ffs_hashalloc(ip, cg, pref, size, allocator) * if they are, allocate them. */ static daddr_t -ffs_fragextend(ip, cg, bprev, osize, nsize) - struct inode *ip; - int cg; - long bprev; - int osize, nsize; +ffs_fragextend(struct node *np, + int cg, + long bprev, + int osize, + int nsize) { register struct fs *fs; register struct cg *cgp; @@ -718,8 +754,8 @@ ffs_fragextend(ip, cg, bprev, osize, nsize) int frags, bbase; int i, error; - fs = ip->i_fs; - if (fs->fs_cs(fs, cg).cs_nffree < numfrags(fs, nsize - osize)) + fs = sblock; + if (csum[cg].cs_nffree < numfrags(fs, nsize - osize)) return (NULL); frags = numfrags(fs, nsize); bbase = fragnum(fs, bprev); @@ -727,6 +763,7 @@ ffs_fragextend(ip, cg, bprev, osize, nsize) /* cannot extend across a block boundary */ return (NULL); } +#if 0 /* Wrong for GNU Hurd ufs */ error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize, NOCRED, &bp); if (error) { @@ -734,15 +771,18 @@ ffs_fragextend(ip, cg, bprev, osize, nsize) return (NULL); } cgp = (struct cg *)bp->b_data; +#else + cgp = (struct cg *) (cgs + sblock->fs_bsize * cg); +#endif if (!cg_chkmagic(cgp)) { - brelse(bp); +/* brelse(bp); */ return (NULL); } - cgp->cg_time = time.tv_sec; + cgp->cg_time = diskfs_mtime->seconds; bno = dtogd(fs, bprev); for (i = numfrags(fs, osize); i < frags; i++) if (isclr(cg_blksfree(cgp), bno + i)) { - brelse(bp); +/* brelse(bp); */ return (NULL); } /* @@ -761,10 +801,10 @@ ffs_fragextend(ip, cg, bprev, osize, nsize) clrbit(cg_blksfree(cgp), bno + i); cgp->cg_cs.cs_nffree--; fs->fs_cstotal.cs_nffree--; - fs->fs_cs(fs, cg).cs_nffree--; + csum[cg].cs_nffree--; } fs->fs_fmod = 1; - bdwrite(bp); +/* bdwrite(bp); */ return (bprev); } @@ -775,11 +815,10 @@ ffs_fragextend(ip, cg, bprev, osize, nsize) * and if it is, allocate it. */ static daddr_t -ffs_alloccg(ip, cg, bpref, size) - struct inode *ip; - int cg; - daddr_t bpref; - int size; +ffs_alloccg(struct node *np, + int cg, + daddr_t bpref, + int size) { register struct fs *fs; register struct cg *cgp; @@ -787,9 +826,10 @@ ffs_alloccg(ip, cg, bpref, size) register int i; int error, bno, frags, allocsiz; - fs = ip->i_fs; - if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize) + fs = sblock; + if (csum[cg].cs_nbfree == 0 && size == fs->fs_bsize) return (NULL); +#if 0 /* Not this way in GNU Hurd ufs */ error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize, NOCRED, &bp); if (error) { @@ -797,15 +837,18 @@ ffs_alloccg(ip, cg, bpref, size) return (NULL); } cgp = (struct cg *)bp->b_data; +#else + cgp = (struct cg *) (cgs + sblock->fs_bsize * cg); +#endif if (!cg_chkmagic(cgp) || (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) { - brelse(bp); +/* brelse(bp); */ return (NULL); } - cgp->cg_time = time.tv_sec; + cgp->cg_time = diskfs_mtime->seconds; if (size == fs->fs_bsize) { bno = ffs_alloccgblk(fs, cgp, bpref); - bdwrite(bp); +/* bdwrite(bp); */ return (bno); } /* @@ -823,7 +866,7 @@ ffs_alloccg(ip, cg, bpref, size) * allocated, and hacked up */ if (cgp->cg_cs.cs_nbfree == 0) { - brelse(bp); +/* brelse(bp); */ return (NULL); } bno = ffs_alloccgblk(fs, cgp, bpref); @@ -833,27 +876,27 @@ ffs_alloccg(ip, cg, bpref, size) i = fs->fs_frag - frags; cgp->cg_cs.cs_nffree += i; fs->fs_cstotal.cs_nffree += i; - fs->fs_cs(fs, cg).cs_nffree += i; + csum[cg].cs_nffree += i; fs->fs_fmod = 1; cgp->cg_frsum[i]++; - bdwrite(bp); +/* bdwrite(bp); */ return (bno); } bno = ffs_mapsearch(fs, cgp, bpref, allocsiz); if (bno < 0) { - brelse(bp); +/* brelse(bp);* / return (NULL); } for (i = 0; i < frags; i++) clrbit(cg_blksfree(cgp), bno + i); cgp->cg_cs.cs_nffree -= frags; fs->fs_cstotal.cs_nffree -= frags; - fs->fs_cs(fs, cg).cs_nffree -= frags; + csum[cg].cs_nffree -= frags; fs->fs_fmod = 1; cgp->cg_frsum[allocsiz]--; if (frags != allocsiz) cgp->cg_frsum[allocsiz - frags]++; - bdwrite(bp); +/* bdwrite(bp); */ return (cg * fs->fs_fpg + bno); } @@ -869,10 +912,9 @@ ffs_alloccg(ip, cg, bpref, size) * blocks may be fragmented by the routine that allocates them. */ static daddr_t -ffs_alloccgblk(fs, cgp, bpref) - register struct fs *fs; - register struct cg *cgp; - daddr_t bpref; +ffs_alloccgblk(register struct fs *fs, + register struct cg *cgp, + daddr_t bpref) { daddr_t bno, blkno; int cylno, pos, delta; @@ -930,11 +972,7 @@ ffs_alloccgblk(fs, cgp, bpref) */ pos = cylno % fs->fs_cpc; bno = (cylno - pos) * fs->fs_spc / NSPB(fs); - if (fs_postbl(fs, pos)[i] == -1) { - printf("pos = %d, i = %d, fs = %s\n", - pos, i, fs->fs_fsmnt); - panic("ffs_alloccgblk: cyl groups corrupted"); - } + assert (fs_postbl(fs, pos)[i] != -1); for (i = fs_postbl(fs, pos)[i];; ) { if (ffs_isblock(fs, cg_blksfree(cgp), bno + i)) { bno = blkstofrags(fs, (bno + i)); @@ -947,7 +985,7 @@ ffs_alloccgblk(fs, cgp, bpref) i += delta; } printf("pos = %d, i = %d, fs = %s\n", pos, i, fs->fs_fsmnt); - panic("ffs_alloccgblk: can't find blk in cyl"); + assert (0); } norot: /* @@ -964,7 +1002,7 @@ gotit: ffs_clusteracct(fs, cgp, blkno, -1); cgp->cg_cs.cs_nbfree--; fs->fs_cstotal.cs_nbfree--; - fs->fs_cs(fs, cgp->cg_cgx).cs_nbfree--; + csum[cgp->cg_cgx].cs_nbfree--; cylno = cbtocylno(fs, bno); cg_blks(fs, cgp, cylno)[cbtorpos(fs, bno)]--; cg_blktot(cgp)[cylno]--; @@ -972,6 +1010,7 @@ gotit: return (cgp->cg_cgx * fs->fs_fpg + bno); } +#if 0 /* Not needed in GNU Hurd ufs (yet?) */ /* * Determine whether a cluster can be allocated. * @@ -1060,6 +1099,7 @@ fail: brelse(bp); return (0); } +#endif /* * Determine whether an inode can be allocated. @@ -1071,20 +1111,20 @@ fail: * inode in the specified cylinder group. */ static ino_t -ffs_nodealloccg(ip, cg, ipref, mode) - struct inode *ip; - int cg; - daddr_t ipref; - int mode; +ffs_nodealloccg(struct node *np, + int cg, + daddr_t ipref, + int mode) { register struct fs *fs; register struct cg *cgp; struct buf *bp; int error, start, len, loc, map, i; - fs = ip->i_fs; - if (fs->fs_cs(fs, cg).cs_nifree == 0) + fs = sblock; + if (csum[cg].cs_nifree == 0) return (NULL); +#if 0 /* Not this way in GNU Hurd ufs */ error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize, NOCRED, &bp); if (error) { @@ -1092,8 +1132,11 @@ ffs_nodealloccg(ip, cg, ipref, mode) return (NULL); } cgp = (struct cg *)bp->b_data; +#else + cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); +#endif if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) { - brelse(bp); +/* brelse(bp); */ return (NULL); } cgp->cg_time = time.tv_sec; @@ -1109,12 +1152,7 @@ ffs_nodealloccg(ip, cg, ipref, mode) len = start + 1; start = 0; loc = skpc(0xff, len, &cg_inosused(cgp)[0]); - if (loc == 0) { - printf("cg = %d, irotor = %d, fs = %s\n", - cg, cgp->cg_irotor, fs->fs_fsmnt); - panic("ffs_nodealloccg: map corrupted"); - /* NOTREACHED */ - } + assert (loc != 0); } i = start + len - loc; map = cg_inosused(cgp)[i]; @@ -1125,21 +1163,20 @@ ffs_nodealloccg(ip, cg, ipref, mode) goto gotit; } } - printf("fs = %s\n", fs->fs_fsmnt); - panic("ffs_nodealloccg: block not in map"); + assort (0); /* NOTREACHED */ gotit: setbit(cg_inosused(cgp), ipref); cgp->cg_cs.cs_nifree--; fs->fs_cstotal.cs_nifree--; - fs->fs_cs(fs, cg).cs_nifree--; + csum[cg].cs_nifree--; fs->fs_fmod = 1; if ((mode & IFMT) == IFDIR) { cgp->cg_cs.cs_ndir++; fs->fs_cstotal.cs_ndir++; - fs->fs_cs(fs, cg).cs_ndir++; + csum[cg].cs_ndir++; } - bdwrite(bp); +/* bdwrite(bp); */ return (cg * fs->fs_ipg + ipref); } @@ -1150,10 +1187,9 @@ gotit: * free map. If a fragment is deallocated, a possible * block reassembly is checked. */ -ffs_blkfree(ip, bno, size) - register struct inode *ip; - daddr_t bno; - long size; +ffs_blkfree(register struct node *np, + daddr_t bno, + long size) { register struct fs *fs; register struct cg *cgp; @@ -1161,18 +1197,15 @@ ffs_blkfree(ip, bno, size) daddr_t blkno; int i, error, cg, blk, frags, bbase; - fs = ip->i_fs; - if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) { - printf("dev = 0x%x, bsize = %d, size = %d, fs = %s\n", - ip->i_dev, fs->fs_bsize, size, fs->fs_fsmnt); - panic("blkfree: bad size"); - } + fs = sblock; + assert ((u_int)size <= fs->fs_bsize && !fragoff (fs, size)); cg = dtog(fs, bno); if ((u_int)bno >= fs->fs_size) { - printf("bad block %d, ino %d\n", bno, ip->i_number); - ffs_fserr(fs, ip->i_uid, "bad block"); + printf("bad block %d, ino %d\n", bno, np->dn->number); +/* ffs_fserr(fs, ip->i_uid, "bad block"); */ return; } +#if 0 /* Not this way in GNU Hurd ufs */ error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize, NOCRED, &bp); if (error) { @@ -1180,24 +1213,23 @@ ffs_blkfree(ip, bno, size) return; } cgp = (struct cg *)bp->b_data; +#else + cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); +#endif if (!cg_chkmagic(cgp)) { - brelse(bp); +/* brelse(bp); */ return; } cgp->cg_time = time.tv_sec; bno = dtogd(fs, bno); if (size == fs->fs_bsize) { blkno = fragstoblks(fs, bno); - if (ffs_isblock(fs, cg_blksfree(cgp), blkno)) { - printf("dev = 0x%x, block = %d, fs = %s\n", - ip->i_dev, bno, fs->fs_fsmnt); - panic("blkfree: freeing free block"); - } + assert (!ffs_isblock(fs, cg_blksfree (cgp), blkno)); ffs_setblock(fs, cg_blksfree(cgp), blkno); ffs_clusteracct(fs, cgp, blkno, 1); cgp->cg_cs.cs_nbfree++; fs->fs_cstotal.cs_nbfree++; - fs->fs_cs(fs, cg).cs_nbfree++; + csum[cg].cs_nbfree++; i = cbtocylno(fs, bno); cg_blks(fs, cgp, i)[cbtorpos(fs, bno)]++; cg_blktot(cgp)[i]++; @@ -1213,16 +1245,12 @@ ffs_blkfree(ip, bno, size) */ frags = numfrags(fs, size); for (i = 0; i < frags; i++) { - if (isset(cg_blksfree(cgp), bno + i)) { - printf("dev = 0x%x, block = %d, fs = %s\n", - ip->i_dev, bno + i, fs->fs_fsmnt); - panic("blkfree: freeing free frag"); - } - setbit(cg_blksfree(cgp), bno + i); + assert (!isset (cg_blksfree(cgp, bno + i))); + setbit(cg_blksfree(cgp), bno + i); } cgp->cg_cs.cs_nffree += i; fs->fs_cstotal.cs_nffree += i; - fs->fs_cs(fs, cg).cs_nffree += i; + csum[cg].cs_nffree += i; /* * add back in counts associated with the new frags */ @@ -1235,18 +1263,18 @@ ffs_blkfree(ip, bno, size) if (ffs_isblock(fs, cg_blksfree(cgp), blkno)) { cgp->cg_cs.cs_nffree -= fs->fs_frag; fs->fs_cstotal.cs_nffree -= fs->fs_frag; - fs->fs_cs(fs, cg).cs_nffree -= fs->fs_frag; + csum[cg].cs_nffree -= fs->fs_frag; ffs_clusteracct(fs, cgp, blkno, 1); cgp->cg_cs.cs_nbfree++; fs->fs_cstotal.cs_nbfree++; - fs->fs_cs(fs, cg).cs_nbfree++; + csum[cg].cs_nbfree++; i = cbtocylno(fs, bbase); cg_blks(fs, cgp, i)[cbtorpos(fs, bbase)]++; cg_blktot(cgp)[i]++; } } fs->fs_fmod = 1; - bdwrite(bp); +/* bdwrite(bp); */ } /* @@ -1254,27 +1282,21 @@ ffs_blkfree(ip, bno, size) * * The specified inode is placed back in the free map. */ -int -ffs_vfree(ap) - struct vop_vfree_args /* { - struct vnode *a_pvp; - ino_t a_ino; - int a_mode; - } */ *ap; +/* Implement diskfs call back diskfs_free_node (described in + . This was called ffs_vfree in BSD. */ +void +diskfs_free_node (struct node *np, mode_t mode) { register struct fs *fs; register struct cg *cgp; - register struct inode *pip; - ino_t ino = ap->a_ino; + ino_t ino = np->dn->number; struct buf *bp; int error, cg; - pip = VTOI(ap->a_pvp); - fs = pip->i_fs; - if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) - panic("ifree: range: dev = 0x%x, ino = %d, fs = %s\n", - pip->i_dev, ino, fs->fs_fsmnt); + fs = sblock; + assert (ino < fs->fs_ipg * fs->fs_ncg); cg = ino_to_cg(fs, ino); +#if 0 /* Not this way in GNU Hurd ufs */ error = bread(pip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize, NOCRED, &bp); if (error) { @@ -1282,8 +1304,11 @@ ffs_vfree(ap) return (0); } cgp = (struct cg *)bp->b_data; +#else + cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); +#endif if (!cg_chkmagic(cgp)) { - brelse(bp); +/* brelse(bp); */ return (0); } cgp->cg_time = time.tv_sec; @@ -1291,22 +1316,21 @@ ffs_vfree(ap) if (isclr(cg_inosused(cgp), ino)) { printf("dev = 0x%x, ino = %d, fs = %s\n", pip->i_dev, ino, fs->fs_fsmnt); - if (fs->fs_ronly == 0) - panic("ifree: freeing free inode"); + assert (diskfs_readonly); } clrbit(cg_inosused(cgp), ino); if (ino < cgp->cg_irotor) cgp->cg_irotor = ino; cgp->cg_cs.cs_nifree++; fs->fs_cstotal.cs_nifree++; - fs->fs_cs(fs, cg).cs_nifree++; + csum[cg].cs_nifree++; if ((ap->a_mode & IFMT) == IFDIR) { cgp->cg_cs.cs_ndir--; fs->fs_cstotal.cs_ndir--; - fs->fs_cs(fs, cg).cs_ndir--; + csum[cg].cs_ndir--; } fs->fs_fmod = 1; - bdwrite(bp); +/* bdwrite(bp); */ return (0); } @@ -1317,11 +1341,10 @@ ffs_vfree(ap) * available. */ static daddr_t -ffs_mapsearch(fs, cgp, bpref, allocsiz) - register struct fs *fs; - register struct cg *cgp; - daddr_t bpref; - int allocsiz; +ffs_mapsearch(register struct fs *fs, + register struct cg *cgp, + daddr_t bpref, + int allocsiz) { daddr_t bno; int start, len, loc, i; @@ -1345,12 +1368,8 @@ ffs_mapsearch(fs, cgp, bpref, allocsiz) loc = scanc((u_int)len, (u_char *)&cg_blksfree(cgp)[0], (u_char *)fragtbl[fs->fs_frag], (u_char)(1 << (allocsiz - 1 + (fs->fs_frag % NBBY)))); - if (loc == 0) { - printf("start = %d, len = %d, fs = %s\n", - start, len, fs->fs_fsmnt); - panic("ffs_alloccg: map corrupted"); - /* NOTREACHED */ - } + assert (loc); + } bno = (start + len - loc) * NBBY; cgp->cg_frotor = bno; @@ -1370,8 +1389,7 @@ ffs_mapsearch(fs, cgp, bpref, allocsiz) subfield <<= 1; } } - printf("bno = %d, fs = %s\n", bno, fs->fs_fsmnt); - panic("ffs_alloccg: block not in map"); + assert (0); return (-1); } @@ -1380,11 +1398,10 @@ ffs_mapsearch(fs, cgp, bpref, allocsiz) * * Cnt == 1 means free; cnt == -1 means allocating. */ -ffs_clusteracct(fs, cgp, blkno, cnt) - struct fs *fs; - struct cg *cgp; - daddr_t blkno; - int cnt; +ffs_clusteracct(struct fs *fs, + struct cg *cgp, + daddr_t blkno, + int cnt) { long *sump; u_char *freemapp, *mapp; @@ -1457,6 +1474,7 @@ ffs_clusteracct(fs, cgp, blkno, cnt) sump[forw] -= cnt; } +#if 0 /* * Fserr prints the name of a file system with an error diagnostic. * @@ -1472,3 +1490,4 @@ ffs_fserr(fs, uid, cp) log(LOG_ERR, "uid %d on %s: %s\n", uid, fs->fs_fsmnt, cp); } +#endif -- cgit v1.2.3 From ca6d84dd97fc2a772609f40962c52f8ed726dbbb Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 16:28:07 +0000 Subject: Formerly ufs.h.~16~ --- ufs/ufs.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index f6769916..c79aaeb7 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -24,6 +24,10 @@ #include #include +/* XXX */ +typedef unsigned long long u_quad_t; + + /* Define this if memory objects should not be cached by the kernel. Normally, don't define it, but defining it causes a much greater rate of paging requests, which may be helpful in catching bugs. */ -- cgit v1.2.3 From 343851b0b1768bda70ef6d1b997bb608d31ac8c9 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 16:42:43 +0000 Subject: Formerly main.c.~14~ --- ufs/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index de90cea8..dc58a20e 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -133,7 +133,7 @@ main (int argc, char **argv) compat_mode = COMPAT_GNU; } - diskfs_init_diskfs (); + diskfs_init_diskfs (bootstrap); err = device_open (diskfs_master_device, (diskfs_readonly ? 0 : D_WRITE) | D_READ, -- cgit v1.2.3 From 722776a1b5997cfc5a0dbf936fae9f4e20f600c1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 16:50:51 +0000 Subject: Formerly subr.c.~5~ --- ufs/subr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/subr.c b/ufs/subr.c index 1730e737..5a6acd88 100644 --- a/ufs/subr.c +++ b/ufs/subr.c @@ -169,7 +169,7 @@ ffs_isblock(fs, cp, h) mask = 0x01 << (h & 0x7); return ((cp[h >> 3] & mask) == mask); default: - panic("ffs_isblock"); + assert (0); } } -- cgit v1.2.3 From cc079a24d3a2f6fc68e4f4c712164613de1af8d7 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 17:22:18 +0000 Subject: Formerly ufs.h.~17~ --- ufs/ufs.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index c79aaeb7..2fb825cc 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -26,6 +26,12 @@ /* XXX */ typedef unsigned long long u_quad_t; +typedef long long quad_t; +struct timespec +{ + long ts_sec; + long ts_nsec; +}; /* Define this if memory objects should not be cached by the kernel. @@ -179,7 +185,7 @@ struct mutex dinmaplock; struct mutex sinmaplock; spin_lock_t gennumberlock; -int nextgennumber; +u_long nextgennumber; mach_port_t ufs_device; @@ -190,7 +196,7 @@ enum compat_mode COMPAT_GNU = 0, COMPAT_BSD42 = 1, COMPAT_BSD44 = 2, -}; +} compat_mode; /* If this is set, then this filesystem has two extensions: 1) directory entries include the type field. @@ -212,7 +218,7 @@ int direct_symlink_extension; /* From alloc.c: */ error_t ffs_alloc (struct node *, daddr_t, daddr_t, int, daddr_t *, struct protid *); -void ffs_blkfree(struct node *, volatile daddr_t bno, int size); +void ffs_blkfree(struct node *, daddr_t bno, long size); daddr_t ffs_blkpref (struct node *, daddr_t, int, daddr_t *); error_t ffs_realloccg(struct node *, daddr_t, daddr_t, int, int, daddr_t *, struct protid *); @@ -243,9 +249,9 @@ void drop_pager_softrefs (struct node *); void allow_pager_softrefs (struct node *); /* From subr.c: */ -void fragacct (int, long [], int); -int isblock(u_char *, daddr_t); -void clrblock(u_char *, daddr_t); -void setblock (u_char *, daddr_t); +void ffs_fragacct (struct fs *, int, long [], int); +int ffs_isblock(struct fs *, u_char *, daddr_t); +void ffs_clrblock(struct fs *, u_char *, daddr_t); +void ffs_setblock (struct fs *, u_char *, daddr_t); int skpc (u_char, u_int, u_char *); int scanc (u_int, u_char *, u_char [], u_char); -- cgit v1.2.3 From 2cfce87e9a8b27de0eeac18be9fa90b24bda6565 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 17:23:00 +0000 Subject: Formerly alloc.c.~13~ --- ufs/alloc.c | 112 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 51 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 7dfe5785..8afa6aa7 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -66,6 +66,17 @@ extern u_long nextgennumber; spin_lock_t alloclock = SPIN_LOCK_INITIALIZER; +/* Forward declarations */ +static u_long ffs_hashalloc (struct node *, int, long, int, + u_long (*)(struct node *, int, daddr_t, int)); +static u_long ffs_alloccg (struct node *, int, daddr_t, int); +static daddr_t ffs_fragextend (struct node *, int, long, int, int); +static ino_t ffs_dirpref (struct fs *); +static u_long ffs_nodealloccg (struct node *, int, daddr_t, int); +static daddr_t ffs_alloccgblk (struct fs *, struct cg *, daddr_t); +static daddr_t ffs_mapsearch (struct fs *, struct cg *, daddr_t, int); +void ffs_clusteracct (struct fs *, struct cg *, daddr_t, int); + /* * Allocate a block in the file system. * @@ -85,6 +96,7 @@ spin_lock_t alloclock = SPIN_LOCK_INITIALIZER; * 2) quadradically rehash into other cylinder groups, until an * available block is located. */ +error_t ffs_alloc(register struct node *np, daddr_t lbn, daddr_t bpref, @@ -94,7 +106,7 @@ ffs_alloc(register struct node *np, { register struct fs *fs; daddr_t bno; - int cg, error; + int cg; *bnp = 0; fs = sblock; @@ -154,16 +166,18 @@ nospace: * the original block. Failing that, the regular block allocator is * invoked to get an appropriate block. */ +error_t ffs_realloccg(register struct node *np, daddr_t lbprev, - daddr_t bpref, + volatile daddr_t bpref, int osize, int nsize, daddr_t *pbn, struct protid *cred) { register struct fs *fs; - int cg, request, error; + int cg, error; + volatile int request; daddr_t bprev, bno; *pbn = 0; @@ -182,7 +196,7 @@ ffs_realloccg(register struct node *np, spin_lock (&alloclock); - if (!isuid (0, cred) && freespace(fs, fs->fs_minfree) <= 0) + if (!diskfs_isuid (0, cred) && freespace(fs, fs->fs_minfree) <= 0) goto nospace; if (error = diskfs_catch_exception ()) return error; @@ -244,7 +258,7 @@ ffs_realloccg(register struct node *np, fs->fs_cstotal.cs_nffree > fs->fs_dsize * fs->fs_minfree / (2 * 100)) break; - log(LOG_NOTICE, "%s: optimization changed from SPACE to TIME\n", + printf ("%s: optimization changed from SPACE to TIME\n", fs->fs_fsmnt); fs->fs_optim = FS_OPTTIME; break; @@ -263,13 +277,11 @@ ffs_realloccg(register struct node *np, if (fs->fs_cstotal.cs_nffree < fs->fs_dsize * (fs->fs_minfree - 2) / 100) break; - log(LOG_NOTICE, "%s: optimization changed from TIME to SPACE\n", + printf ("%s: optimization changed from TIME to SPACE\n", fs->fs_fsmnt); fs->fs_optim = FS_OPTSPACE; break; default: - printf("dev = 0x%x, optim = %d, fs = %s\n", - ip->i_dev, fs->fs_optim, fs->fs_fsmnt); assert (0); /* NOTREACHED */ } @@ -505,9 +517,10 @@ diskfs_alloc_node (struct node *dir, struct node **npp) { register struct fs *fs; - register struct node *np; + struct node *np; ino_t ino, ipref; int cg, error; + int sex; fs = sblock; @@ -537,18 +550,19 @@ diskfs_alloc_node (struct node *dir, assert ("duplicate allocation" && !np->dn_stat.st_mode); if (np->dn_stat.st_blocks) { printf("free inode %d had %d blocks\n", - ino, ip->i_blocks); + ino, np->dn_stat.st_blocks); np->dn_stat.st_blocks = 0; np->dn_set_ctime = 1; } - ip->i_flags = 0; + np->dn_stat.st_flags = 0; /* * Set up a new generation number for this inode. */ spin_lock (&gennumberlock); - if (++nextgennumber < (u_long)time.tv_sec) - nextgennumber = time.tv_sec; - ip->i_gen = nextgennumber; + sex = diskfs_mtime->seconds; + if (++nextgennumber < (u_long)sex) + nextgennumber = sex; + np->dn_stat.st_gen = nextgennumber; spin_unlock (&gennumberlock); return (0); noinodes: @@ -652,7 +666,7 @@ ffs_blkpref(struct node *np, return (fs->fs_fpg * cg + fs->fs_frag); } spin_unlock (&alloclock); - return (NULL); + return 0; } spin_unlock (&alloclock); /* @@ -731,7 +745,7 @@ ffs_hashalloc(struct node *np, if (cg == fs->fs_ncg) cg = 0; } - return (NULL); + return 0; } /* @@ -749,19 +763,18 @@ ffs_fragextend(struct node *np, { register struct fs *fs; register struct cg *cgp; - struct buf *bp; long bno; int frags, bbase; - int i, error; + int i; fs = sblock; if (csum[cg].cs_nffree < numfrags(fs, nsize - osize)) - return (NULL); + return 0; frags = numfrags(fs, nsize); bbase = fragnum(fs, bprev); if (bbase > fragnum(fs, (bprev + frags - 1))) { /* cannot extend across a block boundary */ - return (NULL); + return 0; } #if 0 /* Wrong for GNU Hurd ufs */ error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), @@ -776,14 +789,14 @@ ffs_fragextend(struct node *np, #endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ - return (NULL); + return 0; } cgp->cg_time = diskfs_mtime->seconds; bno = dtogd(fs, bprev); for (i = numfrags(fs, osize); i < frags; i++) if (isclr(cg_blksfree(cgp), bno + i)) { /* brelse(bp); */ - return (NULL); + return 0; } /* * the current fragment can be extended @@ -814,7 +827,7 @@ ffs_fragextend(struct node *np, * Check to see if a block of the appropriate size is available, * and if it is, allocate it. */ -static daddr_t +static u_long ffs_alloccg(struct node *np, int cg, daddr_t bpref, @@ -822,13 +835,12 @@ ffs_alloccg(struct node *np, { register struct fs *fs; register struct cg *cgp; - struct buf *bp; register int i; - int error, bno, frags, allocsiz; + int bno, frags, allocsiz; fs = sblock; if (csum[cg].cs_nbfree == 0 && size == fs->fs_bsize) - return (NULL); + return 0; #if 0 /* Not this way in GNU Hurd ufs */ error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize, NOCRED, &bp); @@ -843,7 +855,7 @@ ffs_alloccg(struct node *np, if (!cg_chkmagic(cgp) || (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) { /* brelse(bp); */ - return (NULL); + return 0; } cgp->cg_time = diskfs_mtime->seconds; if (size == fs->fs_bsize) { @@ -867,7 +879,7 @@ ffs_alloccg(struct node *np, */ if (cgp->cg_cs.cs_nbfree == 0) { /* brelse(bp); */ - return (NULL); + return 0; } bno = ffs_alloccgblk(fs, cgp, bpref); bpref = dtogd(fs, bno); @@ -884,8 +896,8 @@ ffs_alloccg(struct node *np, } bno = ffs_mapsearch(fs, cgp, bpref, allocsiz); if (bno < 0) { -/* brelse(bp);* / - return (NULL); +/* brelse(bp); */ + return 0; } for (i = 0; i < frags; i++) clrbit(cg_blksfree(cgp), bno + i); @@ -994,7 +1006,7 @@ norot: */ bno = ffs_mapsearch(fs, cgp, bpref, (int)fs->fs_frag); if (bno < 0) - return (NULL); + return 0; cgp->cg_rotor = bno; gotit: blkno = fragstoblks(fs, bno); @@ -1110,7 +1122,7 @@ fail: * 2) allocate the next available inode after the requested * inode in the specified cylinder group. */ -static ino_t +static u_long ffs_nodealloccg(struct node *np, int cg, daddr_t ipref, @@ -1118,12 +1130,11 @@ ffs_nodealloccg(struct node *np, { register struct fs *fs; register struct cg *cgp; - struct buf *bp; - int error, start, len, loc, map, i; + int start, len, loc, map, i; fs = sblock; if (csum[cg].cs_nifree == 0) - return (NULL); + return 0; #if 0 /* Not this way in GNU Hurd ufs */ error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize, NOCRED, &bp); @@ -1137,9 +1148,9 @@ ffs_nodealloccg(struct node *np, #endif if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) { /* brelse(bp); */ - return (NULL); + return 0; } - cgp->cg_time = time.tv_sec; + cgp->cg_time = diskfs_mtime->seconds; if (ipref) { ipref %= fs->fs_ipg; if (isclr(cg_inosused(cgp), ipref)) @@ -1163,7 +1174,7 @@ ffs_nodealloccg(struct node *np, goto gotit; } } - assort (0); + assert (0); /* NOTREACHED */ gotit: setbit(cg_inosused(cgp), ipref); @@ -1187,21 +1198,21 @@ gotit: * free map. If a fragment is deallocated, a possible * block reassembly is checked. */ +void ffs_blkfree(register struct node *np, daddr_t bno, long size) { register struct fs *fs; register struct cg *cgp; - struct buf *bp; daddr_t blkno; - int i, error, cg, blk, frags, bbase; + int i, cg, blk, frags, bbase; fs = sblock; assert ((u_int)size <= fs->fs_bsize && !fragoff (fs, size)); cg = dtog(fs, bno); if ((u_int)bno >= fs->fs_size) { - printf("bad block %d, ino %d\n", bno, np->dn->number); + printf("bad block %ld, ino %d\n", bno, np->dn->number); /* ffs_fserr(fs, ip->i_uid, "bad block"); */ return; } @@ -1220,7 +1231,7 @@ ffs_blkfree(register struct node *np, /* brelse(bp); */ return; } - cgp->cg_time = time.tv_sec; + cgp->cg_time = diskfs_mtime->seconds; bno = dtogd(fs, bno); if (size == fs->fs_bsize) { blkno = fragstoblks(fs, bno); @@ -1245,7 +1256,7 @@ ffs_blkfree(register struct node *np, */ frags = numfrags(fs, size); for (i = 0; i < frags; i++) { - assert (!isset (cg_blksfree(cgp, bno + i))); + assert (!isset (cg_blksfree(cgp), bno + i)); setbit(cg_blksfree(cgp), bno + i); } cgp->cg_cs.cs_nffree += i; @@ -1290,8 +1301,7 @@ diskfs_free_node (struct node *np, mode_t mode) register struct fs *fs; register struct cg *cgp; ino_t ino = np->dn->number; - struct buf *bp; - int error, cg; + int cg; fs = sblock; assert (ino < fs->fs_ipg * fs->fs_ncg); @@ -1309,13 +1319,13 @@ diskfs_free_node (struct node *np, mode_t mode) #endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ - return (0); + return; } - cgp->cg_time = time.tv_sec; + cgp->cg_time = diskfs_mtime->seconds; ino %= fs->fs_ipg; if (isclr(cg_inosused(cgp), ino)) { - printf("dev = 0x%x, ino = %d, fs = %s\n", - pip->i_dev, ino, fs->fs_fsmnt); +/* printf("dev = 0x%x, ino = %d, fs = %s\n", + pip->i_dev, ino, fs->fs_fsmnt); */ assert (diskfs_readonly); } clrbit(cg_inosused(cgp), ino); @@ -1324,14 +1334,13 @@ diskfs_free_node (struct node *np, mode_t mode) cgp->cg_cs.cs_nifree++; fs->fs_cstotal.cs_nifree++; csum[cg].cs_nifree++; - if ((ap->a_mode & IFMT) == IFDIR) { + if ((mode & IFMT) == IFDIR) { cgp->cg_cs.cs_ndir--; fs->fs_cstotal.cs_ndir--; csum[cg].cs_ndir--; } fs->fs_fmod = 1; /* bdwrite(bp); */ - return (0); } /* @@ -1398,6 +1407,7 @@ ffs_mapsearch(register struct fs *fs, * * Cnt == 1 means free; cnt == -1 means allocating. */ +void ffs_clusteracct(struct fs *fs, struct cg *cgp, daddr_t blkno, -- cgit v1.2.3 From 7490c7f6549dd620ffc24f396b6fd36151ba0f58 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 17:28:01 +0000 Subject: Formerly dir.c.~23~ --- ufs/dir.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 9cbb42d5..7c793d84 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -326,7 +326,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, || DIRSIZ (DIRECT_NAMLEN (entry)) > entry->d_reclen || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { - fprintf (stderr, "Bad directory entry: inode: %ld offset: %d\n", + fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", dp->dn->number, currentoff - blockaddr); return ENOENT; } @@ -443,7 +443,7 @@ diskfs_direnter(struct node *dp, ds->entry->d_ino = np->dn->number; DIRECT_NAMLEN (ds->entry) = namelen; if (direct_symlink_extension) - ds->d_type = IFTODT (np->dn->dn_stat.st_mode); + ds->entry->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, ds->entry->d_name, namelen + 1); break; @@ -460,7 +460,7 @@ diskfs_direnter(struct node *dp, new->d_reclen = ds->entry->d_reclen - oldneeded; DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) - ds->d_type = IFTODT (np->dn->dn_stat.st_mode); + new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); ds->entry->d_reclen = oldneeded; @@ -500,7 +500,7 @@ diskfs_direnter(struct node *dp, new->d_reclen = totfreed; DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) - new->d_type = IFTODT (np->dn->dn_stat.st_mode); + new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; @@ -522,7 +522,7 @@ diskfs_direnter(struct node *dp, new->d_reclen = DIRBLKSIZ; DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) - new->d_type = IFTODT (np->dn->dn_stat.st_mode); + new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; @@ -620,7 +620,7 @@ diskfs_dirrewrite(struct node *dp, ds->entry->d_ino = np->dn->number; if (direct_symlink_extension) - ds->entry->d_type = IFTODT (np->dn->dn_stat.st_mode); + ds->entry->d_type = IFTODT (np->dn_stat.st_mode); vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); -- cgit v1.2.3 From 28f85f65a9b3e1044006394e3862c95017aa7ad6 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 17:36:29 +0000 Subject: entered into RCS --- ufs/dinode.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'ufs') diff --git a/ufs/dinode.h b/ufs/dinode.h index 8f9dae0e..00be0d94 100644 --- a/ufs/dinode.h +++ b/ufs/dinode.h @@ -71,6 +71,14 @@ #define NDADDR 12 /* Direct addresses in inode. */ #define NIADDR 3 /* Indirect addresses in inode. */ +/* Maximum value of di_nlink field. */ +#define LINK_MAX 32767 + +/* Indexes into di_ib */ +#define INDIR_SINGLE 0 +#define INDIR_DOUBLE 1 +#define INDIR_TRIPLE 2 /* NOT SUPPORTED */ + struct dinode { u_short di_model; /* 0: IFMT and permissions. */ short di_nlink; /* 2: File link count. */ -- cgit v1.2.3 From a8b691bf8231ff07a1074bd8a254be368b616f21 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 17:45:34 +0000 Subject: entered into RCS --- ufs/fs.h | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/fs.h b/ufs/fs.h index 7a4e6d7c..a2a3cc9b 100644 --- a/ufs/fs.h +++ b/ufs/fs.h @@ -83,6 +83,16 @@ * to determine block availability, aligned fragments are examined. */ +/* + * The file system is made out of blocks of at most MAXBSIZE units, with + * smaller units (fragments) only in the last direct block. MAXBSIZE + * primarily determines the size of buffers in the buffer pool. It may be + * made larger without any effect on existing file systems; however making + * it smaller make make some file systems unmountable. + */ +#define MAXBSIZE MAXPHYS +#define MAXFRAG 8 + /* * MINBSIZE is the smallest allowable block size. * In order to insure that it is possible to create files of size @@ -465,14 +475,18 @@ struct ocg { /* * Determining the size of a file block in the file system. */ -#define blksize(fs, ip, lbn) \ - (((lbn) >= NDADDR || (ip)->i_size >= ((lbn) + 1) << (fs)->fs_bshift) \ +/* Changed from BSD to use allocsize instead of i_size. */ +#define blksize(fs, np, lbn) \ + (((lbn) >= NDADDR || (np)->allocsize >= ((lbn) + 1) << (fs)->fs_bshift) \ ? (fs)->fs_bsize \ - : (fragroundup(fs, blkoff(fs, (ip)->i_size)))) + : (fragroundup(fs, blkoff(fs, (np)->allocsize)))) + +#if 0 /* Don't use this */ #define dblksize(fs, dip, lbn) \ (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->fs_bshift) \ ? (fs)->fs_bsize \ : (fragroundup(fs, blkoff(fs, (dip)->di_size)))) +#endif /* * Number of disk sectors per block; assumes DEV_BSIZE byte sector size. -- cgit v1.2.3 From 2428fdffd15b737a0fa4c2714c44c99d7223e735 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 17:49:36 +0000 Subject: Formerly sizes.c.~16~ --- ufs/sizes.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index d7f132c0..c34474f5 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -22,6 +22,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" #include "fs.h" #include "dinode.h" +#include #ifdef DONT_CACHE_MEMORY_OBJECTS #define MAY_CACHE 0 @@ -69,14 +70,16 @@ diskfs_truncate (struct node *np, } /* Calculate block number of last block */ - lastblock = lblkno (length + sblock->fs_bsize - 1) - 1; - olastblock = lblkno (osize + sblock->fs_bsize - 1) - 1; + lastblock = lblkno (sblock, length + sblock->fs_bsize - 1) - 1; + olastblock = lblkno (sblock, osize + sblock->fs_bsize - 1) - 1; /* If the prune is not to a block boundary, zero the bit upto the next block boundary. */ - if (blkoff (length)) + if (blkoff (sblock, length)) diskfs_node_rdwr (np, (void *) zeroblock, length, - blksize (np, lastblock) - blkoff (length), 1, 0, 0); + (blksize (sblock, np, lastblock) + - blkoff (sblock, length)), + 1, 0, 0); /* We are going to throw away the block pointers for the blocks olastblock+1 through lastblock. This will cause the underlying @@ -137,8 +140,9 @@ diskfs_truncate (struct node *np, /* Prune the block pointers handled by the sindir pager. This will free all the indirect blocks and such as necessary. */ - sindir_drop (np, lblkno((first2free - NDADDR) * sizeof (daddr_t)), - lblkno ((olastblock - NDADDR) * sizeof (daddr_t))); + sindir_drop (np, lblkno(sblock, + (first2free - NDADDR) * sizeof (daddr_t)), + lblkno (sblock, (olastblock - NDADDR) * sizeof (daddr_t))); if (!np->dn->fileinfo) sin_unmap (np); @@ -154,7 +158,7 @@ diskfs_truncate (struct node *np, dinodes[np->dn->number].di_db[idx] = 0; assert (idx <= olastblock); if (idx == olastblock) - bsize = blksize (np, idx); + bsize = blksize (sblock, np, idx); else bsize = sblock->fs_bsize; ffs_blkfree (np, bn, bsize); @@ -171,12 +175,12 @@ diskfs_truncate (struct node *np, { off_t oldspace, newspace; - oldspace = blksize (np, lastblock); - newspace = fragroundup (blkoff (length));; + oldspace = blksize (sblock, np, lastblock); + newspace = fragroundup (sblock, blkoff (sblock, length));; assert (newspace); if (oldspace - newspace) { - bn += numfrags (newspace); + bn += numfrags (sblock, newspace); ffs_blkfree (np, bn, oldspace - newspace); np->dn_stat.st_blocks -= (oldspace - newspace) / DEV_BSIZE; np->dn_stat_dirty = 1; @@ -185,9 +189,9 @@ diskfs_truncate (struct node *np, } if (lastblock < NDADDR) - np->allocsize = fragroundup (length); + np->allocsize = fragroundup (sblock, length); else - np->allocsize = blkroundup (length); + np->allocsize = blkroundup (sblock, length); rwlock_writer_unlock (&np->dn->datalock, np->dn); @@ -338,20 +342,20 @@ diskfs_grow (struct node *np, } /* This is the logical block number of what will be the last block. */ - lbn = lblkno (end + sblock->fs_bsize - 1) - 1; + lbn = lblkno (sblock, end + sblock->fs_bsize - 1) - 1; /* This is the size to be of that block if it is in the NDADDR array. */ - size = fragroundup (blkoff (end)); + size = fragroundup (sblock, blkoff (sblock, end)); if (size == 0) size = sblock->fs_bsize; /* if we are writing a new block, then an old one may need to be reallocated into a full block. */ - nb = lblkno (np->allocsize + sblock->fs_bsize - 1) - 1; + nb = lblkno (sblock, np->allocsize + sblock->fs_bsize - 1) - 1; if (np->allocsize && nb < NDADDR && nb < lbn) { - osize = blksize (np, nb); + osize = blksize (sblock, np, nb); if (osize < sblock->fs_bsize && osize > 0) { daddr_t old_pbn; @@ -388,7 +392,7 @@ diskfs_grow (struct node *np, if (nb != 0) { /* consider need to reallocate a fragment. */ - osize = blkoff (np->allocsize); + osize = blkoff (sblock, np->allocsize); if (osize == 0) osize = sblock->fs_bsize; if (size > osize) @@ -427,7 +431,7 @@ diskfs_grow (struct node *np, dealloc_size = size; dinodes[np->dn->number].di_db[lbn] = pbn; } - np->allocsize = fragroundup (end); + np->allocsize = fragroundup (sblock, end); } else { @@ -436,11 +440,11 @@ diskfs_grow (struct node *np, if (np->dn->sinloc) { sin_remap (np, end); - np->allocsize = blkroundup (end); + np->allocsize = blkroundup (sblock, end); } else { - np->allocsize = blkroundup (end); + np->allocsize = blkroundup (sblock, end); sin_map (np); } -- cgit v1.2.3 From dbc48a1fc573f362b3afc7e76b261044aef5a698 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 17:54:51 +0000 Subject: Formerly hyper.c.~7~ --- ufs/hyper.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index c9ffcc63..a1a19706 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -17,6 +17,7 @@ #include "ufs.h" #include "fs.h" +#include "dinode.h" #include #include @@ -49,7 +50,7 @@ get_hypermetadata (void) if (sblock->fs_maxsymlinklen > MAXSYMLINKLEN) { - fprintf (stderr, "Max shortcut symlinklen %d is too big (max is %d)\n", + fprintf (stderr, "Max shortcut symlinklen %ld is too big (max is %ld)\n", sblock->fs_maxsymlinklen, MAXSYMLINKLEN); exit (1); } @@ -70,7 +71,8 @@ get_hypermetadata (void) else direct_symlink_extension = 0; - err = dev_read_sync (fsbtodb (sblock->fs_csaddr), (vm_address_t *) &csum, + err = dev_read_sync (fsbtodb (sblock, sblock->fs_csaddr), + (vm_address_t *) &csum, sblock->fs_fsize * howmany (sblock->fs_cssize, sblock->fs_fsize)); assert (!err); @@ -88,7 +90,7 @@ diskfs_set_hypermetadata (int wait, int clean) spin_lock (&alloclock); if (csum_dirty) { - (*writefn)(fsbtodb (sblock->fs_csaddr), (vm_address_t) csum, + (*writefn)(fsbtodb (sblock, sblock->fs_csaddr), (vm_address_t) csum, sblock->fs_fsize * howmany (sblock->fs_cssize, sblock->fs_fsize)); csum_dirty = 0; -- cgit v1.2.3 From b36c0f1892a2c5d66b9fc12faea7479678593872 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 17:58:08 +0000 Subject: Formerly subr.c.~6~ --- ufs/subr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/subr.c b/ufs/subr.c index 5a6acd88..5833dfef 100644 --- a/ufs/subr.c +++ b/ufs/subr.c @@ -197,7 +197,7 @@ ffs_clrblock(fs, cp, h) cp[h >> 3] &= ~(0x01 << (h & 0x7)); return; default: - panic("ffs_clrblock"); + assert (0); } } -- cgit v1.2.3 From 5a98ad25014b20f4303abba4c3e3db0a2c8e5a4e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 18 Jul 1994 20:01:23 +0000 Subject: Formerly subr.c.~7~ --- ufs/subr.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/subr.c b/ufs/subr.c index 5833dfef..6c7ea5f2 100644 --- a/ufs/subr.c +++ b/ufs/subr.c @@ -226,6 +226,40 @@ ffs_setblock(fs, cp, h) cp[h >> 3] |= (0x01 << (h & 0x7)); return; default: - panic("ffs_setblock"); + assert (0); } } + +/* Taken from 4.4 BSD sys/libkern/skpc.c: + @(#)skpc.c 8.1 (Berkeley) 6/10/93 +*/ +int +skpc(mask0, size, cp0) + int mask0; + int size; + char *cp0; +{ + register u_char *cp, *end, mask; + + mask = mask0; + cp = (u_char *)cp0; + for (end = &cp[size]; cp < end && *cp == mask; ++cp); + return (end - cp); +} + +/* Taken from 4.4 BSD sys/libkern/scanc.c: + @(#)scanc.c 8.1 (Berkeley) 6/10/93 +*/ +int +scanc(size, cp, table, mask0) + u_int size; + register u_char *cp, table[]; + int mask0; +{ + register u_char *end; + register u_char mask; + + mask = mask0; + for (end = &cp[size]; cp < end && (table[*cp] & mask) == 0; ++cp); + return (end - cp); +} -- cgit v1.2.3 From efca89c3f5a5bd907d7328e0a1b4208b07511e82 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 18 Jul 1994 20:28:31 +0000 Subject: Formerly ufs.h.~18~ --- ufs/ufs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 2fb825cc..2ffa835d 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -253,5 +253,5 @@ void ffs_fragacct (struct fs *, int, long [], int); int ffs_isblock(struct fs *, u_char *, daddr_t); void ffs_clrblock(struct fs *, u_char *, daddr_t); void ffs_setblock (struct fs *, u_char *, daddr_t); -int skpc (u_char, u_int, u_char *); -int scanc (u_int, u_char *, u_char [], u_char); +int skpc (int, int, char *); +int scanc (u_int, u_char *, u_char [], int); -- cgit v1.2.3 From 3f2794eb61e97bbf2890944dcf335ed241d9f4f0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 19 Jul 1994 00:19:10 +0000 Subject: Initial revision --- ufs/pager.c | 937 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 937 insertions(+) create mode 100644 ufs/pager.c (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c new file mode 100644 index 00000000..7aea0f9d --- /dev/null +++ b/ufs/pager.c @@ -0,0 +1,937 @@ +/* Pager for ufs + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "ufs.h" +#include "fs.h" +#include "dinode.h" +#include +#include + +mach_port_t dinport; +mach_port_t dinodeport; +mach_port_t cgport; + +/* Filesystem blocks of inodes per cylinder group */ +static int infsb_pcg; + +spin_lock_t pagerlistlock = SPIN_LOCK_INITIALIZER; +struct user_pager_info *filelist, *sinlist; + +static void enqueue_pager (struct user_pager_info *); +static void dequeue_pager (struct user_pager_info *); +static daddr_t indir_alloc (struct node *, int, int); + +/* Locks all nodes' sininfo and fileinfo fields. */ +static struct mutex pagernplock = MUTEX_INITIALIZER; + +#ifdef DONT_CACHE_MEMORY_OBJECTS +#define MAY_CACHE 0 +#else +#define MAY_CACHE 1 +#endif + +/* Find the location on disk of page OFFSET in pager UPI. Return the + disk address (in disk block) in *ADDR. If *NPLOCK is set on + return, then release that mutex after I/O on the data has + completed. Set DISKSIZE to be the amount of valid data on disk. + (If this is an unallocated block, then set *ADDR to zero.) */ +static error_t +find_address (struct user_pager_info *upi, + vm_address_t offset, + daddr_t *addr, + int *disksize, + struct rwlock **nplock, + struct disknode **dnp) +{ + int vblkno = lblkno (sblock, offset); + int fsbaddr; + struct node *volatile np; + error_t err; + struct mutex *maplock = 0; + + if (upi->type != FILE_DATA) + *disksize = __vm_page_size; + + switch (upi->type) + { + default: + assert (0); + + case CG: + fsbaddr = cgtod (sblock, vblkno); + *nplock = 0; + break; + + case DINODE: + fsbaddr = (cgimin (sblock, vblkno / infsb_pcg) + + blkstofrags (sblock, vblkno % infsb_pcg)); + *nplock = 0; + break; + + case DINDIR: + np = ifind (vblkno); + + rwlock_reader_lock (&np->dn->dinlock, np->dn); + *nplock = &np->dn->dinlock; + *dnp = np->dn; + if (err = diskfs_catch_exception ()) + goto error; + + fsbaddr = dinodes[np->dn->number].di_ib[INDIR_DOUBLE]; + diskfs_end_catch_exception (); + break; + + case SINDIR: + np = upi->np; + + rwlock_reader_lock (&np->dn->sinlock, np->dn); + *nplock = &np->dn->sinlock; + *dnp = np->dn; + + if (err = diskfs_catch_exception ()) + goto error; + + if (vblkno == 0) + fsbaddr = dinodes[np->dn->number].di_ib[INDIR_SINGLE]; + else + { + mutex_lock (&dinmaplock); + maplock = &dinmaplock; + if (!np->dn->dinloc) + din_map (np); + fsbaddr = np->dn->dinloc[vblkno - 1]; + mutex_unlock (&dinmaplock); + } + + diskfs_end_catch_exception (); + break; + + case FILE_DATA: + np = upi->np; + + rwlock_reader_lock (&np->dn->datalock, np->dn); + *nplock = &np->dn->datalock; + *dnp = np->dn; + + if (offset >= np->allocsize) + { + err = EIO; + goto error; + } + + if (offset + __vm_page_size > np->allocsize) + *disksize = np->allocsize - offset; + else + *disksize = __vm_page_size; + + if (err = diskfs_catch_exception ()) + goto error; + + if (vblkno < NDADDR) + fsbaddr = dinodes[np->dn->number].di_db[vblkno]; + else + { + mutex_lock (&sinmaplock); + maplock = &sinmaplock; + if (!np->dn->sinloc) + sin_map (np); + fsbaddr = np->dn->sinloc[vblkno - NDADDR]; + mutex_unlock (&sinmaplock); + } + diskfs_end_catch_exception (); + break; + } + + if (fsbaddr) + *addr = fsbtodb (sblock, fsbaddr) + blkoff (sblock, offset) / DEV_BSIZE; + else + *addr = 0; + + return 0; + + error: + if (*nplock) + rwlock_reader_unlock (*nplock, *dnp); + if (maplock) + mutex_unlock (maplock); + return err; +} + +/* Implement the pager_read_page callback from the pager library. See + for the interface description. */ +error_t +pager_read_page (struct user_pager_info *pager, + vm_offset_t page, + vm_address_t *buf, + int *writelock) +{ + error_t err; + struct rwlock *nplock; + daddr_t addr; + int disksize; + struct disknode *dn; + + err = find_address (pager, page, &addr, &disksize, &nplock, &dn); + if (err) + return err; + + if (addr) + { + err = dev_read_sync (addr, (void *)buf, disksize); + if (!err && disksize != __vm_page_size) + bzero ((void *)(*buf + disksize), __vm_page_size - disksize); + *writelock = 0; + } + else + { + vm_allocate (mach_task_self (), buf, __vm_page_size, 1); + *writelock = 1; + } + + if (nplock) + rwlock_reader_unlock (nplock, dn); + + return err; +} + +/* Implement the pager_write_page callback from the pager library. See + for the interface description. */ +error_t +pager_write_page (struct user_pager_info *pager, + vm_offset_t page, + vm_address_t buf) +{ + daddr_t addr; + int disksize; + struct rwlock *nplock; + error_t err; + struct disknode *dn; + + err = find_address (pager, page, &addr, &disksize, &nplock, &dn); + if (err) + return err; + + if (addr) + err = dev_write_sync (addr, buf, disksize); + else + { + printf ("Attempt to write unallocated disk\n."); + err = 0; /* unallocated disk; + error would be pointless */ + } + + if (nplock) + rwlock_reader_unlock (nplock, dn); + + return err; +} + +/* Implement the pager_unlock_page callback from the pager library. See + for the interface description. */ +error_t +pager_unlock_page (struct user_pager_info *pager, + vm_offset_t address) +{ + struct node *volatile np; + error_t err; + daddr_t vblkno; + daddr_t *slot, *table; + daddr_t newblk; + + /* Problem--where to get cred values for allocation here? */ + + vblkno = address / sblock->fs_bsize; + + switch (pager->type) + { + case DINDIR: + np = ifind (vblkno); + + rwlock_writer_lock (&np->dn->dinlock, np->dn); + if (diskfs_catch_exception ()) + err = EIO; + else + { + if (dinodes[np->dn->number].di_ib[INDIR_DOUBLE]) + err = 0; + else + { + newblk = indir_alloc (np, INDIR_DOUBLE, 0); + if (newblk) + { + dinodes[np->dn->number].di_ib[INDIR_DOUBLE] = newblk; + err = 0; + } + else + err = ENOSPC; + } + diskfs_end_catch_exception (); + } + rwlock_writer_unlock (&np->dn->dinlock, np->dn); + break; + + case SINDIR: + np = pager->np; + rwlock_writer_lock (&np->dn->sinlock, np->dn); + + if (diskfs_catch_exception ()) + err = EIO; + else + { + mutex_lock (&dinmaplock); + if (vblkno == 0) + slot = &dinodes[np->dn->number].di_ib[INDIR_SINGLE]; + else + { + if (!np->dn->dinloc) + din_map (np); + slot = &np->dn->dinloc[vblkno - 1]; + } + + if (*slot) + err = 0; + else + { + newblk = indir_alloc (np, INDIR_SINGLE, vblkno); + if (newblk) + { + *slot = newblk; + err = 0; + } + else + err = ENOSPC; + } + mutex_unlock (&dinmaplock); + diskfs_end_catch_exception (); + } + rwlock_writer_unlock (&np->dn->sinlock, np->dn); + break; + + case FILE_DATA: + np = pager->np; + rwlock_writer_lock (&np->dn->datalock, np->dn); + + /* If this is the last block, we don't let it get unlocked. */ + if (address + __vm_page_size + > blkroundup (sblock, np->allocsize) - sblock->fs_bsize) + { + printf ("attempt to unlock at last block denied\n"); + rwlock_writer_unlock (&np->dn->datalock, np->dn); + return EIO; + } + + if (diskfs_catch_exception ()) + err = EIO; + else + { + mutex_lock (&sinmaplock); + if (vblkno < NDADDR) + { + slot = &dinodes[np->dn->number].di_db[vblkno]; + table = dinodes[np->dn->number].di_db; + } + else + { + if (!np->dn->sinloc) + sin_map (np); + slot = &np->dn->sinloc[vblkno - NDADDR]; + table = np->dn->sinloc; + } + + if (*slot) + err = 0; + else + { + ffs_alloc (np, vblkno, + ffs_blkpref (np, vblkno, slot - table, table), + sblock->fs_bsize, &newblk, 0); + if (newblk) + { + *slot = newblk; + err = 0; + } + else + err = ENOSPC; + } + mutex_unlock (&sinmaplock); + diskfs_end_catch_exception (); + } + rwlock_writer_unlock (&np->dn->datalock, np->dn); + break; + + default: + err = 0; + } + + return err; +} + +/* Implement the pager_report_extent callback from the pager library. See + for the interface description. */ +inline error_t +pager_report_extent (struct user_pager_info *pager, + vm_address_t *offset, + vm_size_t *size) +{ + int sizet; + + *offset = 0; + switch (pager->type) + { + case DINODE: + *size = sblock->fs_ipg * sblock->fs_ncg * sizeof (struct dinode); + break; + + case CG: + *size = sblock->fs_bsize * sblock->fs_ncg; + break; + + case DINDIR: + *size = sblock->fs_ipg * sblock->fs_ncg * sblock->fs_bsize; + break; + + case SINDIR: + sizet = pager->np->allocsize; + sizet = (sizet + sblock->fs_bsize - 1) / sblock->fs_bsize; + sizet -= NDADDR; + sizet *= sizeof (daddr_t); + sizet = (sizet + sblock->fs_bsize - 1) / sblock->fs_bsize; + *size = sizet; + break; + + case FILE_DATA: + *size = pager->np->allocsize; + break; + } + + *size = round_page (*size); + return 0; +} + +/* Implement the pager_clear_user_data callback from the pager library. + See for the interface description. */ +void +pager_clear_user_data (struct user_pager_info *upi) +{ + struct node *np = upi->np; + + switch (upi->type) + { + case FILE_DATA: + mutex_lock (&sinmaplock); + mutex_lock (&pagernplock); + np->dn->fileinfo = 0; + mutex_unlock (&pagernplock); + if (np->dn->sinloc) + sin_unmap (np); + mutex_unlock (&sinmaplock); + break; + + case SINDIR: + mutex_lock (&dinmaplock); + mutex_lock (&pagernplock); + np->dn->sininfo = 0; + mutex_unlock (&pagernplock); + if (np->dn->dinloc) + din_unmap (np); + mutex_unlock (&dinmaplock); + break; + + case DINDIR: + dinpager = 0; + return; + case CG: + cgpager = 0; + return; + case DINODE: + dinodepager = 0; + return; + } + + if (np) + diskfs_nrele_light (np); + dequeue_pager (upi); + free (upi); +} + + +/* This is called (with sinmaplock held) to map the contents of the + single indirect blocks of node NP. */ +void +sin_map (struct node *np) +{ + int err; + struct user_pager_info *upi; + mach_port_t port; + vm_address_t offset; + vm_size_t extent; + + assert (!np->dn->sinloc); + + mutex_lock (&pagernplock); + if (np->dn->sininfo) + { + upi = np->dn->sininfo; + port = pager_get_port (upi->p); + mach_port_insert_right (mach_task_self (), port, port, + MACH_MSG_TYPE_MAKE_SEND); + } + else + { + upi = malloc (sizeof (struct user_pager_info)); + upi->type = SINDIR; + upi->np = np; + diskfs_nref_light (np); + + upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); + np->dn->sininfo = upi; + enqueue_pager (upi); + port = pager_get_port (upi->p); + mach_port_insert_right (mach_task_self (), port, port, + MACH_MSG_TYPE_MAKE_SEND); + } + mutex_unlock (&pagernplock); + + pager_report_extent (upi, &offset, &extent); + + err = vm_map (mach_task_self (), (vm_address_t *)&np->dn->sinloc, + extent, 0, 1, port, offset, 0, VM_PROT_READ|VM_PROT_WRITE, + VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); + mach_port_deallocate (mach_task_self (), port); + + assert (!err); + + diskfs_register_memory_fault_area (np->dn->sininfo->p, offset, + np->dn->sinloc, extent); +} + +/* This is caled when a file (NP) grows (to size NEWSIZE) to see + if the single indirect mapping needs to grow to. sinmaplock + must be held. + The caller must set ip->i_allocsize to reflect newsize. */ +void +sin_remap (struct node *np, + int newsize) +{ + struct user_pager_info *upi; + int err; + vm_address_t offset; + vm_size_t size; + mach_port_t port; + + mutex_lock (&pagernplock); + upi = np->dn->sininfo; + + pager_report_extent (upi, &offset, &size); + + /* This is the same calculation as in pager_report_extent + for the SINDIR case. */ + newsize = (newsize + sblock->fs_bsize - 1) / sblock->fs_bsize; + newsize -= NDADDR; + newsize *= sizeof (daddr_t); + newsize = (newsize + sblock->fs_bsize - 1) / sblock->fs_bsize; + newsize = round_page (newsize); + + assert (newsize >= size); + if (newsize != size) + { + diskfs_unregister_memory_fault_area (np->dn->sinloc, size); + vm_deallocate (mach_task_self (), (u_int) np->dn->sinloc, size); + + port = pager_get_port (upi->p); + mach_port_insert_right (mach_task_self (), port, port, + MACH_MSG_TYPE_MAKE_SEND); + err = vm_map (mach_task_self (), (u_int *)&np->dn->sinloc, size, + 0, 1, port, 0, 0, VM_PROT_READ|VM_PROT_WRITE, + VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); + mach_port_deallocate (mach_task_self (), port); + assert (!err); + diskfs_register_memory_fault_area (np->dn->sininfo->p, 0, + np->dn->sinloc, size); + } + mutex_unlock (&pagernplock); +} + +/* This is called (with sinmaplock set) to unmap the + single indirect block mapping of node NP. */ +void +sin_unmap (struct node *np) +{ + vm_offset_t start; + vm_size_t len; + + assert (np->dn->sinloc); + pager_report_extent (np->dn->sininfo, &start, &len); + diskfs_unregister_memory_fault_area (np->dn->sinloc, len); + vm_deallocate (mach_task_self (), (u_int) np->dn->sinloc, len); + np->dn->sinloc = 0; +} + +/* This is called (with dinmaplock set) to map the contents + of the double indirect block of node NP. */ +void +din_map (struct node *np) +{ + int err; + + assert (!np->dn->dinloc); + + err = vm_map (mach_task_self (), (vm_address_t *)&np->dn->dinloc, + sblock->fs_bsize, 0, 1, dinport, + np->dn->number * sblock->fs_bsize, 0, + VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, + VM_INHERIT_NONE); + assert (!err); + diskfs_register_memory_fault_area (dinpager->p, + np->dn->number * sblock->fs_bsize, + np->dn->dinloc, sblock->fs_bsize); +} + +/* This is called (with dinmaplock set) to unmap the double + indirect block mapping of node NP. */ +void +din_unmap (struct node *np) +{ + diskfs_unregister_memory_fault_area (np->dn->dinloc, sblock->fs_bsize); + vm_deallocate (mach_task_self (), (u_int) np->dn->dinloc, sblock->fs_bsize); + np->dn->dinloc = 0; +} + +/* Initialize the pager subsystem. */ +void +pager_init () +{ + struct user_pager_info *upi; + vm_address_t offset; + vm_size_t size; + error_t err; + + /* firewalls: */ + assert ((DEV_BSIZE % sizeof (struct dinode)) == 0); + assert ((__vm_page_size % DEV_BSIZE) == 0); + assert ((sblock->fs_bsize % DEV_BSIZE) == 0); + assert ((sblock->fs_ipg % sblock->fs_inopb) == 0); + assert (__vm_page_size <= sblock->fs_bsize); + + infsb_pcg = sblock->fs_ipg / sblock->fs_inopb; + + vm_allocate (mach_task_self (), &zeroblock, sblock->fs_bsize, 1); + + upi = malloc (sizeof (struct user_pager_info)); + upi->type = DINODE; + upi->np = 0; + upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); + dinodepager = upi; + dinodeport = pager_get_port (upi->p); + mach_port_insert_right (mach_task_self (), dinodeport, dinodeport, + MACH_MSG_TYPE_MAKE_SEND); + pager_report_extent (upi, &offset, &size); + err = vm_map (mach_task_self (), (vm_address_t *)&dinodes, size, + 0, 1, dinodeport, offset, 0, VM_PROT_READ|VM_PROT_WRITE, + VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); + assert (!err); + diskfs_register_memory_fault_area (dinodepager->p, 0, dinodes, size); + + upi = malloc (sizeof (struct user_pager_info)); + upi->type = CG; + upi->np = 0; + upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); + cgpager = upi; + cgport = pager_get_port (upi->p); + mach_port_insert_right (mach_task_self (), cgport, cgport, + MACH_MSG_TYPE_MAKE_SEND); + pager_report_extent (upi, &offset, &size); + err = vm_map (mach_task_self (), &cgs, size, + 0, 1, cgport, offset, 0, VM_PROT_READ|VM_PROT_WRITE, + VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); + assert (!err); + diskfs_register_memory_fault_area (cgpager->p, 0, (void *)cgs, size); + + upi = malloc (sizeof (struct user_pager_info)); + upi->type = DINDIR; + upi->np = 0; + upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); + dinpager = upi; + dinport = pager_get_port (upi->p); + mach_port_insert_right (mach_task_self (), dinport, dinport, + MACH_MSG_TYPE_MAKE_SEND); +} + +/* Allocate one indirect block for NP. TYPE is either INDIR_DOUBLE or + INDIR_SINGLE; IND is (for INDIR_SINGLE) the index of the block + (The first block is 0, the next 1, etc.). */ +static daddr_t +indir_alloc (struct node *np, + int type, + int ind) +{ + daddr_t bn; + daddr_t lbn; + int error; + + switch (type) + { + case INDIR_DOUBLE: + lbn = NDADDR + sblock->fs_bsize / sizeof (daddr_t); + break; + case INDIR_SINGLE: + if (ind == 0) + lbn = NDADDR; + else + lbn = NDADDR + ind * sblock->fs_bsize / sizeof (daddr_t); + break; + default: + assert (0); + } + + if (error = ffs_alloc (np, NDADDR, + ffs_blkpref (np, lbn, 0, (daddr_t *)0), + sblock->fs_bsize, &bn, 0)) + return 0; + + /* We do this write synchronously so that the inode never + points at an indirect block full of garbage */ + if (dev_write_sync (fsbtodb (sblock, bn), zeroblock, sblock->fs_bsize)) + { + ffs_blkfree (np, bn, sblock->fs_bsize); + return 0; + } + else + return bn; +} + +/* Write a single dinode (NP->dn->number) to disk. This might sync more + than actually necessary; it's really just an attempt to avoid syncing + all the inodes. Return immediately if WAIT is clear. */ +void +sync_dinode (struct node *np, + int wait) +{ + vm_offset_t offset, offsetpg; + + offset = np->dn->number * sizeof (struct dinode); + offsetpg = offset / __vm_page_size; + offset = offsetpg * __vm_page_size; + + pager_sync_some (dinodepager->p, offset, __vm_page_size, wait); +} + +/* This syncs a single file (NP) to disk. Wait for all I/O to complete + if WAIT is set. NP->lock must be held. */ +void +diskfs_file_update (struct node *np, + int wait) +{ + mutex_lock (&pagernplock); + if (np->dn->fileinfo) + pager_sync (np->dn->fileinfo->p, wait); + mutex_unlock (&pagernplock); + + mutex_lock (&pagernplock); + if (np->dn->sininfo) + pager_sync (np->dn->sininfo->p, wait); + mutex_unlock (&pagernplock); + + pager_sync_some (dinpager->p, np->dn->number * sblock->fs_bsize, + sblock->fs_bsize, wait); + + diskfs_node_update (np, wait); +} + +/* Call this to create a FILE_DATA pager and return a send right. + NP must be locked. The toplock must be locked. */ +mach_port_t +diskfs_get_filemap (struct node *np) +{ + struct user_pager_info *upi; + mach_port_t right; + + assert (S_ISDIR (np->dn_stat.st_mode) + || S_ISREG (np->dn_stat.st_mode) + || (S_ISLNK (np->dn_stat.st_mode) + && (!direct_symlink_extension + || np->dn_stat.st_size >= sblock->fs_maxsymlinklen))); + + mutex_lock (&pagernplock); + if (!np->dn->fileinfo) + { + upi = malloc (sizeof (struct user_pager_info)); + upi->type = FILE_DATA; + upi->np = np; + diskfs_nref_light (np); + upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); + np->dn->fileinfo = upi; + enqueue_pager (upi); + } + right = pager_get_port (np->dn->fileinfo->p); + mutex_unlock (&pagernplock); + mach_port_insert_right (mach_task_self (), right, right, + MACH_MSG_TYPE_MAKE_SEND); + + return right; +} + +/* Call this when we should turn off caching so that unused memory object + ports get freed. */ +void +drop_pager_softrefs (struct node *np) +{ + if (MAY_CACHE) + { + mutex_lock (&pagernplock); + if (np->dn->fileinfo) + pager_change_attributes (np->dn->fileinfo->p, 0, + MEMORY_OBJECT_COPY_DELAY, 0); + if (np->dn->sininfo) + pager_change_attributes (np->dn->sininfo->p, 0, + MEMORY_OBJECT_COPY_DELAY, 0); + mutex_unlock (&pagernplock); + } +} + +/* Call this when we should turn on caching because it's no longer + important for unused memory object ports to get freed. */ +void +allow_pager_softrefs (struct node *np) +{ + if (MAY_CACHE) + { + mutex_lock (&pagernplock); + if (np->dn->fileinfo) + pager_change_attributes (np->dn->fileinfo->p, 1, + MEMORY_OBJECT_COPY_DELAY, 0); + if (np->dn->sininfo) + pager_change_attributes (np->dn->sininfo->p, 1, + MEMORY_OBJECT_COPY_DELAY, 0); + } +} + +/* Call this to find out the struct pager * corresponding to the + FILE_DATA pager of inode IP. This should be used *only* as a subsequent + argument to register_memory_fault_area, and will be deleted when + the kernel interface is fixed. */ +struct pager * +diskfs_get_filemap_pager_struct (struct node *np) +{ + struct pager *p; + mutex_unlock (&pagernplock); + p = np->dn->fileinfo->p; + mutex_unlock (&pagernplock); + return p; +} + +/* Add pager P to the appropriate list (filelist or sinlist) of pagers + of its type. */ +static void +enqueue_pager (struct user_pager_info *p) +{ + struct user_pager_info **listp; + + if (p->type == FILE_DATA) + listp = &filelist; + else if (p->type == SINDIR) + listp = &filelist; + else + return; + + spin_lock (&pagerlistlock); + + p->next = *listp; + p->prevp = listp; + *listp = p; + if (p->next) + p->next->prevp = &p->next; + + spin_unlock (&pagerlistlock); +} + +/* Remove pager P from the linked list it was placed on with enqueue_pager. */ +static void +dequeue_pager (struct user_pager_info *p) +{ + spin_lock (&pagerlistlock); + if (p->next) + p->next->prevp = p->prevp; + *p->prevp = p->next; + spin_unlock (&pagerlistlock); +} + +/* Call function FUNC (which takes one argument, a pager) on each pager, with + all file pagers being processed before sindir pagers, and then the dindir, + dinode, and cg pagers (in that order). Make the calls while holding + no locks. */ +static void +pager_traverse (void (*func)(struct user_pager_info *)) +{ + struct user_pager_info *p; + struct item {struct item *next; struct user_pager_info *p;} *list = 0; + struct item *i; + int looped; + + /* Putting SINDIR's on first means they will be removed last; after + the FILE_DATA pagers. */ + spin_lock (&pagerlistlock); + for (p = sinlist, looped = 0; + p || (!looped && (looped = 1, p = filelist)); + p = p->next) + { + i = alloca (sizeof (struct item)); + i->next = list; + list = i; + pager_reference (p->p); + i->p = p; + } + spin_unlock (&pagerlistlock); + + for (i = list; i; i = i->next) + { + (*func)(i->p); + pager_unreference (i->p->p); + } + + (*func)(dinpager); + (*func)(dinodepager); + (*func)(cgpager); +} + + +/* Shutdown all the pagers. */ +void +diskfs_shutdown_pager () +{ + void shutdown_one (struct user_pager_info *p) + { + pager_shutdown (p->p); + } + + write_all_disknodes (); + pager_traverse (shutdown_one); +} + +/* Sync all the pagers. */ +void +diskfs_sync_everything (int wait) +{ + void sync_one (struct user_pager_info *p) + { + pager_sync (p->p, wait); + } + + write_all_disknodes (); + pager_traverse (sync_one); +} + -- cgit v1.2.3 From 1872f7caee0355c300a27caa99f93609e492fa63 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 19 Jul 1994 01:02:20 +0000 Subject: Formerly hyper.c.~8~ --- ufs/hyper.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index a1a19706..b39848ee 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -21,6 +21,8 @@ #include #include +static int oldformat = 0; + void get_hypermetadata (void) { @@ -48,7 +50,7 @@ get_hypermetadata (void) exit (1); } - if (sblock->fs_maxsymlinklen > MAXSYMLINKLEN) + if (sblock->fs_maxsymlinklen > (long)MAXSYMLINKLEN) { fprintf (stderr, "Max shortcut symlinklen %ld is too big (max is %ld)\n", sblock->fs_maxsymlinklen, MAXSYMLINKLEN); @@ -58,13 +60,32 @@ get_hypermetadata (void) /* If this is an old filesystem, then we have some more work to do; some crucial constants might not be set; we are therefore forced to set them here. */ + if (sblock->fs_npsect < sblock->fs_nsect) sblock->fs_npsect = sblock->fs_nsect; + if (sblock->fs_interleave < 1) sblock->fs_interleave = 1; + if (sblock->fs_postblformat == FS_42POSTBLFMT) sblock->fs_nrpos = 8; + if (sblock->fs_inodefmt < FS_44INODEFMT) + { + quad_t sizepb = sblock->fs_bsize; + int i; + + oldformat = 1; + sblock->fs_maxfilesize = sblock->fs_bsize * NDADDR - 1; + for (i = 0; i < NIADDR; i++) + { + sizepb *= NINDIR (sblock); + sblock->fs_maxfilesize += sizepb; + } + sblock->fs_qbmask = ~sblock->fs_bmask; + sblock->fs_qfmask = ~sblock->fs_fmask; + } + /* Find out if we support the 4.4 symlink/dirtype extension */ if (sblock->fs_maxsymlinklen > 0) direct_symlink_extension = 1; @@ -104,11 +125,20 @@ diskfs_set_hypermetadata (int wait, int clean) if (sblock_dirty) { - if (sblock->fs_postblformat == FS_42POSTBLFMT) + if (sblock->fs_postblformat == FS_42POSTBLFMT + || oldformat) { char sblockcopy[SBSIZE]; + struct fs *sbcopy = (struct fs *)sblockcopy; bcopy (sblock, sblockcopy, SBSIZE); - ((struct fs *)sblockcopy)->fs_nrpos = -1; + if (sblock->fs_postblformat == FS_42POSTBLFMT) + sbcopy->fs_nrpos = -1; + if (oldformat) + { + sbcopy->fs_maxfilesize = -1; + sbcopy->fs_qbmask = -1; + sbcopy->fs_qfmask = -1; + } (*writefn) (SBLOCK, (vm_address_t) sblockcopy, SBSIZE); } else -- cgit v1.2.3 From d9fc33c37a55ac8d84023ac0dd0ddd9e10cd3a4c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 19 Jul 1994 02:35:07 +0000 Subject: Formerly dir.c.~24~ --- ufs/dir.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 7c793d84..f4bb4c63 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -722,6 +722,16 @@ count_dirents (struct node *dp, int nb, char *buf) return 0; } +/* XXX */ +struct olddirect +{ + u_long d_ino; + u_short d_reclen; + u_short d_namlen; + char d_name[MAXNAMLEN + 1]; +}; + + /* Implement the disikfs_get_directs callback as described in . */ error_t @@ -841,8 +851,22 @@ diskfs_get_directs (struct node *dp, if (entryp->d_ino) { +#ifdef notyet bcopy (bufp, datap, DIRSIZ (DIRECT_NAMLEN (entryp))); - ((struct direct *)bufp)->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); + if (!direct_symlink_extension) + { + /* Fix up fields into new format */ + ((struct direct *)datap)->d_namlen = DIRECT_NAMLEN (entryp); + ((struct direct *)datap)->d_type = DT_UNKNOWN; + } + ((struct direct *)datap)->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); +#else + struct olddirect *userd; + userd = (struct olddirect *)datap; + userd->d_ino = entryp->d_ino; + userd->d_reclen = userd->d_namlen = DIRECT_NAMLEN (entryp); + bcopy (entryp->d_name, userd->d_name, DIRECT_NAMLEN (entryp) + 1); +#endif i++; datap += DIRSIZ (DIRECT_NAMLEN (entryp)); } -- cgit v1.2.3 From 9401289a7a00f2ae71974466155df89b77ac3b27 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 19 Jul 1994 16:48:29 +0000 Subject: Formerly Makefile.~27~ --- ufs/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 14a1260c..79b8f45e 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -38,10 +38,9 @@ LIBPARTS = $(libdiskfs) $(libports) $(libpager) $(libioserver) $(libfshelp) all: ufs -LDFLAGS=--no-keep-memory - +# Don't use $^ in this rule; it will omit the duplicates in $(LIBS). ufs: $(OBJS) $(LIBS) - $(link) + $(CC) -Xlinker --no-keep-memory $(CFLAGS) -o $@ $(OBJS) $(LIBS) exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs rsh $(mighost) -n cd `pwd` \; \ -- cgit v1.2.3 From 02288d5d114ab3557e2a415771b35e670ac35912 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 19 Jul 1994 22:08:06 +0000 Subject: Formerly Makefile.~28~ --- ufs/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 79b8f45e..5beca669 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -40,7 +40,8 @@ all: ufs # Don't use $^ in this rule; it will omit the duplicates in $(LIBS). ufs: $(OBJS) $(LIBS) - $(CC) -Xlinker --no-keep-memory $(CFLAGS) -o $@ $(OBJS) $(LIBS) + $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) +# -Xlinker --no-keep-memory exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs rsh $(mighost) -n cd `pwd` \; \ -- cgit v1.2.3 From 1b08bf90da78eb0909b5562347e1d3d921dee78b Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 19 Jul 1994 23:34:36 +0000 Subject: Formerly main.c.~15~ --- ufs/main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index dc58a20e..19963a9a 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -25,7 +25,6 @@ char *ufs_version = "0.0 pre-alpha"; -mach_port_t diskfs_dotdot_file; static char **save_argv; /* Parse the arguments for ufs when started as a translator. */ @@ -71,8 +70,7 @@ trans_parse_args (int argc, char **arg) mach_port_insert_right (mach_task_self (), ufs_control_port, ufs_control_port, MACH_MSG_TYPE_MAKE_SEND); - fsys_startup (bootstrap, ufs_control_port, &ufs_realnode, - &diskfs_dotdot_file); + fsys_startup (bootstrap, ufs_control_port, &ufs_realnode); mach_port_deallocate (mach_task_self (), ufs_control_port); #else task_terminate (mach_task_self ()); -- cgit v1.2.3 From c8282f9bd0f423e9e51d6fffc1cb4d75fa098f85 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 20 Jul 1994 01:53:07 +0000 Subject: Formerly ufs.h.~19~ --- ufs/ufs.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 2ffa835d..a9766422 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -24,15 +24,6 @@ #include #include -/* XXX */ -typedef unsigned long long u_quad_t; -typedef long long quad_t; -struct timespec -{ - long ts_sec; - long ts_nsec; -}; - /* Define this if memory objects should not be cached by the kernel. Normally, don't define it, but defining it causes a much greater rate -- cgit v1.2.3 From 2b474e2589a83801bbac0c8d438a82fdb29ce3ab Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 20 Jul 1994 20:01:28 +0000 Subject: Formerly main.c.~16~ --- ufs/main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 19963a9a..1ae0d749 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -127,7 +127,6 @@ main (int argc, char **argv) else { devname = diskfs_parse_bootargs (argc, argv); - diskfs_dotdot_file = MACH_PORT_NULL; compat_mode = COMPAT_GNU; } -- cgit v1.2.3 From ff4c54baf383829094aa518ad5039cdfc0c269f6 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 20 Jul 1994 21:25:23 +0000 Subject: Formerly Makefile.~29~ --- ufs/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 5beca669..e2e4fdcf 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -33,6 +33,7 @@ OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o #LIBS = $(hurdinst)/lib/libdiskfscombined.a $(libthreads) LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ $(libfshelp) $(libdiskfs) $(libthreads) $(libports) +#LIBS = $(LIBPARTS) LIBPARTS = $(libdiskfs) $(libports) $(libpager) $(libioserver) $(libfshelp) @@ -40,7 +41,7 @@ all: ufs # Don't use $^ in this rule; it will omit the duplicates in $(LIBS). ufs: $(OBJS) $(LIBS) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) + $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) # -Xlinker --no-keep-memory exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs -- cgit v1.2.3 From b11ffcd8476b5179f59b08383b06188856966e7b Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 22 Jul 1994 19:19:07 +0000 Subject: Formerly Makefile.~30~ --- ufs/Makefile | 52 ++++++++++------------------------------------------ 1 file changed, 10 insertions(+), 42 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index e2e4fdcf..7b353160 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -16,48 +16,27 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. dir := ufs - -include ../Makeconf - -VPATH=.:../machine +makemode := server SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c - -TAGSLIBS=libdiskfs libports libpager libioserver libfshelp libthreads - -DIST_FILES=$(SRCS) ufs.h Makefile fs.h dinode.h dir.h ChangeLog - OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o +LCLHDRS = ufs.h fs.h dinode.h dir.h +REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ + ../hurd/ioserver.h ../hurd/fshelp.h +HURDLIBS = libdiskfs libports libdiskfs libpager libioserver \ + libfshelp libdiskfs libthreads libports +#HURDLIBS = libdiskfs libports libpager libioserver libfshelp +target = ufs -#LIBS = $(hurdinst)/lib/libdiskfscombined.a $(libthreads) -LIBS = $(libdiskfs) $(libports) $(libdiskfs) $(libpager) $(libioserver) \ - $(libfshelp) $(libdiskfs) $(libthreads) $(libports) -#LIBS = $(LIBPARTS) - -LIBPARTS = $(libdiskfs) $(libports) $(libpager) $(libioserver) $(libfshelp) - -all: ufs - -# Don't use $^ in this rule; it will omit the duplicates in $(LIBS). -ufs: $(OBJS) $(LIBS) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) -# -Xlinker --no-keep-memory +include ../Makeconf exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs rsh $(mighost) -n cd `pwd` \; \ ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o -install: - -clean: - rm -f *.o ufs -relink: - rm -f ufs - $(OBJS): ufs.h -$(OBJS): $(addprefix $(includedir)/hurd/,diskfs.h pager.h ioserver.h \ - fshelp.h ports.h) +$(OBJS): $(REMHDRS) alloc.o: fs.h dinode.h consts.o: dinode.h dir.o: dir.h @@ -69,16 +48,5 @@ sizes.o: fs.h dinode.h subr.o: fs.h tables.o: fs.h -$(hurdinst)/lib/libdiskfscombined.a: $(LIBPARTS) - -mkdir foo - cd foo; $(AR) x $(libdiskfs) - cd foo; $(AR) x $(libports) - cd foo; $(AR) x $(libpager) - cd foo; $(AR) x $(libioserver) - cd foo; $(AR) x $(libfshelp) - cd foo; $(AR) cr $(hurdinst)/lib/libdiskfscombined.a * - rm -rf foo - $(RANLIB) $(hurdinst)/lib/libdiskfscombined.a - $(foreach dir,mkbootfs exec,../$(dir)/%): FORCE $(MAKE) -C $(@D) $(@F) -- cgit v1.2.3 From e4e7540de195bc58311434179d225bb324db4fe0 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 23 Jul 1994 07:03:32 +0000 Subject: Formerly Makefile.~31~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 7b353160..9e5fe941 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -26,7 +26,7 @@ REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ ../hurd/ioserver.h ../hurd/fshelp.h HURDLIBS = libdiskfs libports libdiskfs libpager libioserver \ libfshelp libdiskfs libthreads libports -#HURDLIBS = libdiskfs libports libpager libioserver libfshelp +#HURDLIBS = libdiskfs libports libpager libioserver libfshelp libthreads target = ufs include ../Makeconf -- cgit v1.2.3 From 5a92483b8ff9718ef86ada672c7aa244641177f6 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 5 Aug 1994 19:54:21 +0000 Subject: Formerly dir.c.~25~ --- ufs/dir.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index f4bb4c63..a3b0b7f6 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -104,6 +104,9 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, type &= ~SPEC_DOTDOT; namelen = strlen (name); + + if (namelen > MAXNAMLEN) + return ENAMETOOLONG; if (!S_ISDIR (dp->dn_stat.st_mode)) return ENOTDIR; @@ -506,6 +509,8 @@ diskfs_direnter(struct node *dp, case EXTEND: /* Extend the file. */ + assert (needed <= DIRBLKSIZ); + while (dp->dn_stat.st_size + DIRBLKSIZ > dp->allocsize) if (err = diskfs_grow (dp, dp->dn_stat.st_size + DIRBLKSIZ, cred)) { @@ -864,7 +869,8 @@ diskfs_get_directs (struct node *dp, struct olddirect *userd; userd = (struct olddirect *)datap; userd->d_ino = entryp->d_ino; - userd->d_reclen = userd->d_namlen = DIRECT_NAMLEN (entryp); + userd->d_namlen = DIRECT_NAMLEN (entryp); + userd->d_reclen = DIRSIZ (userd->d_namlen); bcopy (entryp->d_name, userd->d_name, DIRECT_NAMLEN (entryp) + 1); #endif i++; -- cgit v1.2.3 From 080f2c714857fd99f198924532af339d6dc770c4 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 16 Aug 1994 18:04:35 +0000 Subject: Formerly Makefile.~33~ --- ufs/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 9e5fe941..2cb7e84e 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -27,6 +27,7 @@ REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ HURDLIBS = libdiskfs libports libdiskfs libpager libioserver \ libfshelp libdiskfs libthreads libports #HURDLIBS = libdiskfs libports libpager libioserver libfshelp libthreads +LDFLAGS = -Wl,--no-keep-memory target = ufs include ../Makeconf -- cgit v1.2.3 From 5c1e6655a532185b661a90fd6380b9334575f77e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 18 Aug 1994 16:40:57 +0000 Subject: Formerly alloc.c.~14~ --- ufs/alloc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 8afa6aa7..19389afe 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -564,6 +564,8 @@ diskfs_alloc_node (struct node *dir, nextgennumber = sex; np->dn_stat.st_gen = nextgennumber; spin_unlock (&gennumberlock); + + *npp = np; return (0); noinodes: printf ("out of inodes"); -- cgit v1.2.3 From 538566e5a53f2738660bc49bc97b6215831b054c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 18 Aug 1994 16:41:42 +0000 Subject: Formerly Makefile.~34~ --- ufs/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 2cb7e84e..17bcf3f4 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -24,9 +24,9 @@ OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o LCLHDRS = ufs.h fs.h dinode.h dir.h REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ ../hurd/ioserver.h ../hurd/fshelp.h -HURDLIBS = libdiskfs libports libdiskfs libpager libioserver \ - libfshelp libdiskfs libthreads libports -#HURDLIBS = libdiskfs libports libpager libioserver libfshelp libthreads +#HURDLIBS = libdiskfs libports libdiskfs libpager libioserver \ +# libfshelp libdiskfs libthreads libports +HURDLIBS = libdiskfs libports libpager libioserver libfshelp libthreads LDFLAGS = -Wl,--no-keep-memory target = ufs -- cgit v1.2.3 From 0057b128c0661dbc6ba01acc49eadcec6a9b8493 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 30 Aug 1994 17:36:23 +0000 Subject: Initial revision --- ufs/inode.c | 510 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 510 insertions(+) create mode 100644 ufs/inode.c (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c new file mode 100644 index 00000000..113f42d9 --- /dev/null +++ b/ufs/inode.c @@ -0,0 +1,510 @@ +/* Inode management routines + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "ufs.h" +#include "dinode.h" +#include "fs.h" +#include + +#define INOHSZ 512 +#if ((INOHSZ&(INOHSZ-1)) == 0) +#define INOHASH(ino) ((ino)&(INOHSZ-1)) +#else +#define INOHASH(ino) (((unsigned)(ino))%INOHSZ) +#endif + +static struct node *nodehash[INOHSZ]; +static error_t read_disknode (struct node *np); + +spin_lock_t gennumberlock = SPIN_LOCK_INITIALIZER; + +/* Initialize the inode hash table. */ +void +inode_init () +{ + int n; + for (n = 0; n < INOHSZ; n++) + nodehash[n] = 0; + mutex_init (&dinmaplock); + mutex_init (&sinmaplock); +} + +/* Fetch inode INUM, set *NPP to the node structure; + gain one user reference and lock the node. */ +error_t +iget (ino_t inum, struct node **npp) +{ + struct disknode *dn; + struct node *np; + error_t err; + + spin_lock (&diskfs_node_refcnt_lock); + for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) + { + if (np->dn->number != inum) + continue; + + np->references++; + spin_unlock (&diskfs_node_refcnt_lock); + mutex_lock (&np->lock); + *npp = np; + return 0; + } + + dn = malloc (sizeof (struct disknode)); + + dn->number = inum; + dn->dirents = 0; + + mutex_init (&dn->rwlock_master); + condition_init (&dn->rwlock_wakeup); + rwlock_init (&dn->dinlock); + rwlock_init (&dn->sinlock); + rwlock_init (&dn->datalock); + dn->dinloc = 0; + dn->sinloc = 0; + dn->sininfo = 0; + dn->fileinfo = 0; + + np = diskfs_make_node (dn); + mutex_lock (&np->lock); + dn->hnext = nodehash[INOHASH(inum)]; + if (dn->hnext) + dn->hnext->dn->hprevp = &dn->hnext; + dn->hprevp = &nodehash[INOHASH(inum)]; + nodehash[INOHASH(inum)] = np; + spin_unlock (&diskfs_node_refcnt_lock); + + err = read_disknode (np); + if (lblkno (sblock, np->dn_stat.st_size) < NDADDR) + np->allocsize = fragroundup (sblock, np->dn_stat.st_size); + else + np->allocsize = blkroundup (sblock, np->dn_stat.st_size); + + /* XXX */ + assert (np->allocsize || !dinodes[np->dn->number].di_db[0]); + + if (!diskfs_readonly && !np->dn_stat.st_gen) + { + spin_lock (&gennumberlock); + if (++nextgennumber < diskfs_mtime->seconds) + nextgennumber = diskfs_mtime->seconds; + np->dn_stat.st_gen = nextgennumber; + spin_unlock (&gennumberlock); + np->dn_set_ctime = 1; + } + + if (err) + return err; + else + { + *npp = np; + return 0; + } +} + +/* Lookup node INUM (which must have a reference already) and return it + without allocating any new references. */ +struct node * +ifind (ino_t inum) +{ + struct node *np; + + spin_lock (&diskfs_node_refcnt_lock); + for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) + { + if (np->dn->number != inum) + continue; + + assert (np->references); + spin_unlock (&diskfs_node_refcnt_lock); + return np; + } + assert (0); +} + +/* The last reference to a node has gone away; drop + it from the hash table and clean all state in the dn structure. */ +void +diskfs_node_norefs (struct node *np) +{ + *np->dn->hprevp = np->dn->hnext; + if (np->dn->hnext) + np->dn->hnext->dn->hprevp = np->dn->hprevp; + if (np->dn->dirents) + free (np->dn->dirents); + assert (!np->dn->sininfo && !np->dn->fileinfo); + assert (!np->dn->dinloc && !np->dn->sinloc); + free (np->dn); + free (np); +} + +/* The last hard referencs to a node has gone away; arrange to have + all the weak references dropped that can be. */ +void +diskfs_lost_hardrefs (struct node *np) +{ + drop_pager_softrefs (np); +} + +/* A new hard reference to a node has been created; it's now OK to + have unused weak references. */ +void +diskfs_new_hardrefs (struct node *np) +{ + allow_pager_softrefs (np); +} + +/* Read stat information out of the dinode. */ +static error_t +read_disknode (struct node *np) +{ + struct stat *st = &np->dn_stat; + struct dinode *di = &dinodes[np->dn->number]; + error_t err; + + err = diskfs_catch_exception (); + if (err) + return err; + + st->st_fstype = FSTYPE_UFS; + st->st_fsid = 0; /* XXX should fill this */ + st->st_ino = np->dn->number; + st->st_gen = di->di_gen; + st->st_rdev = di->di_rdev; + st->st_mode = di->di_model | (di->di_modeh << 16); + st->st_nlink = di->di_nlink; + st->st_size = di->di_size; +#ifdef notyet + st->st_atimespec = di->di_atime; + st->st_mtimespec = di->di_mtime; + st->st_ctimespec = di->di_ctime; +#else + st->st_atime = di->di_atime.ts_sec; + st->st_atime_usec = di->di_atime.ts_nsec / 1000; + st->st_mtime = di->di_mtime.ts_sec; + st->st_mtime_usec = di->di_mtime.ts_nsec / 1000; + st->st_ctime = di->di_ctime.ts_sec; + st->st_ctime_usec = di->di_ctime.ts_nsec / 1000; +#endif + st->st_blksize = sblock->fs_bsize; + st->st_blocks = di->di_blocks; + st->st_flags = di->di_flags; + + if (sblock->fs_inodefmt < FS_44INODEFMT) + { + st->st_uid = di->di_ouid; + st->st_gid = di->di_ogid; + st->st_author = 0; + } + else + { + st->st_uid = di->di_uid; + st->st_gid = di->di_gid; + st->st_author = di->di_author; + if (st->st_author == -1) + st->st_author = st->st_uid; + } + + diskfs_end_catch_exception (); + if (!S_ISBLK (st->st_mode) && !S_ISCHR (st->st_mode)) + st->st_rdev = 0; + return 0; +} + +static void +write_node (struct node *np) +{ + struct stat *st = &np->dn_stat; + struct dinode *di = &dinodes[np->dn->number]; + error_t err; + + assert (!np->dn_set_ctime && !np->dn_set_atime && !np->dn_set_mtime); + if (np->dn_stat_dirty) + { + assert (!diskfs_readonly); + + err = diskfs_catch_exception (); + if (err) + return; + + di->di_gen = st->st_gen; + + if (S_ISBLK (st->st_mode) || S_ISCHR (st->st_mode)) + di->di_rdev = st->st_rdev; + + /* We happen to know that the stat mode bits are the same + as the ufs mode bits. */ + + if (compat_mode == COMPAT_GNU) + { + di->di_model = st->st_mode & 0xffff; + di->di_modeh = (st->st_mode >> 16) & 0xffff; + } + else + { + di->di_model = st->st_mode & 0xffff; + di->di_modeh = 0; + } + + if (compat_mode != COMPAT_BSD42) + { + di->di_uid = st->st_uid; + di->di_gid = st->st_gid; + } + + if (sblock->fs_inodefmt < FS_44INODEFMT) + { + di->di_ouid = st->st_uid & 0xffff; + di->di_ogid = st->st_gid & 0xffff; + } + else if (compat_mode == COMPAT_GNU) + di->di_author = st->st_author; + + di->di_nlink = st->st_nlink; + di->di_size = st->st_size; +#ifdef notyet + di->di_atime = st->st_atimespec; + di->di_mtime = st->st_mtimespec; + di->di_ctime = st->st_ctimespec; +#else + di->di_atime.ts_sec = st->st_atime; + di->di_atime.ts_nsec = st->st_atime_usec * 1000; + di->di_mtime.ts_sec = st->st_mtime; + di->di_mtime.ts_nsec = st->st_mtime_usec * 1000; + di->di_ctime.ts_sec = st->st_ctime; + di->di_ctime.ts_nsec = st->st_ctime_usec * 1000; +#endif + di->di_blocks = st->st_blocks; + di->di_flags = st->st_flags; + + diskfs_end_catch_exception (); + np->dn_stat_dirty = 0; + } +} + +/* See if we should create a symlink by writing it directly into + the block pointer array. Returning EINVAL tells diskfs to do it + the usual way. */ +static error_t +create_symlink_hook (struct node *np, char *target) +{ + int len = strlen (target); + error_t err; + + if (!direct_symlink_extension) + return EINVAL; + + assert (!COMPAT_BSD42); + + if (len >= sblock->fs_maxsymlinklen) + return EINVAL; + + err = diskfs_catch_exception (); + if (err) + return err; + + bcopy (target, dinodes[np->dn->number].di_shortlink, len); + np->dn_stat.st_size = len; + np->dn_set_ctime = 1; + np->dn_set_mtime = 1; + + diskfs_end_catch_exception (); + return 0; +} +error_t (*diskfs_create_symlink_hook)(struct node *, char *) + = create_symlink_hook; + +/* Check if this symlink is stored directly in the block pointer array. + Returning EINVAL tells diskfs to do it the usual way. */ +static error_t +read_symlink_hook (struct node *np, + char *buf) +{ + error_t err; + + if (!direct_symlink_extension + || np->dn_stat.st_size >= sblock->fs_maxsymlinklen) + return EINVAL; + + err = diskfs_catch_exception (); + if (err) + return err; + + bcopy (dinodes[np->dn->number].di_shortlink, buf, np->dn_stat.st_size); + np->dn_set_atime = 1; + + diskfs_end_catch_exception (); + return 0; +} +error_t (*diskfs_read_symlink_hook)(struct node *, char *) + = read_symlink_hook; + + +/* Write all active disknodes into the dinode pager. */ +void +write_all_disknodes () +{ + int n; + struct node *np; + + spin_lock (&diskfs_node_refcnt_lock); + for (n = 0; n < INOHSZ; n++) + for (np = nodehash[n]; np; np = np->dn->hnext) + { + diskfs_set_node_times (np); + write_node (np); + } + spin_unlock (&diskfs_node_refcnt_lock); +} + +void +diskfs_write_disknode (struct node *np, int wait) +{ + write_node (np); + sync_dinode (np, wait); +} + + +/* Implement the diskfs_set_statfs callback from the diskfs library; + see for the interface description. */ +error_t +diskfs_set_statfs (struct fsys_statfsbuf *st) +{ + st->fsys_stb_type = FSTYPE_UFS; + st->fsys_stb_bsize = sblock->fs_bsize; + st->fsys_stb_fsize = sblock->fs_fsize; + st->fsys_stb_blocks = sblock->fs_dsize; + st->fsys_stb_bfree = (sblock->fs_cstotal.cs_nbfree * sblock->fs_frag + + sblock->fs_cstotal.cs_nffree); + st->fsys_stb_bavail = ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100) + - (sblock->fs_dsize - st->fsys_stb_bfree)); + st->fsys_stb_files = sblock->fs_ncg * sblock->fs_ipg - 2; /* not 0 or 1 */ + st->fsys_stb_ffree = sblock->fs_cstotal.cs_nifree; + st->fsys_stb_fsid = 0; + return 0; +} + +/* Implement the diskfs_set_translator callback from the diskfs + library; see for the interface description. */ +error_t +diskfs_set_translator (struct node *np, char *name, u_int namelen, + struct protid *cred) +{ + daddr_t blkno; + error_t err; + char buf[sblock->fs_bsize]; + + if (compat_mode != COMPAT_GNU) + return EOPNOTSUPP; + + if (namelen + sizeof (u_int) > sblock->fs_bsize) + return ENAMETOOLONG; + + err = diskfs_catch_exception (); + if (err) + return err; + + blkno = dinodes[np->dn->number].di_trans; + + if (namelen && !blkno) + { + /* Allocate block for translator */ + err = ffs_alloc (np, 0, 0, sblock->fs_bsize, &blkno, cred); + if (err) + { + diskfs_end_catch_exception (); + return err; + } + dinodes[np->dn->number].di_trans = blkno; + np->dn_set_ctime = 1; + } + else if (!namelen && blkno) + { + /* Clear block for translator going away. */ + ffs_blkfree (np, blkno, sblock->fs_bsize); + dinodes[np->dn->number].di_trans = 0; + np->dn_set_ctime = 1; + } + + diskfs_end_catch_exception (); + + if (namelen) + { + bcopy (&namelen, buf, sizeof (u_int)); + bcopy (name, buf + sizeof (u_int), namelen); + err = dev_write_sync (fsbtodb (sblock, blkno), + (vm_address_t)buf, sblock->fs_bsize); + np->dn_set_ctime = 1; + } + return err; +} + +/* Implement the diskfs_get_translator callback from the diskfs library. + See for the interface description. */ +error_t +diskfs_get_translator (struct node *np, char **namep, u_int *namelen) +{ + error_t err; + daddr_t blkno; + char *buf; + u_int datalen; + + err = diskfs_catch_exception (); + if (err) + return err; + blkno = dinodes[np->dn->number].di_trans; + diskfs_end_catch_exception (); + + assert (blkno); + + err = dev_read_sync (fsbtodb (sblock, blkno), (vm_address_t *)&buf, + sblock->fs_bsize); + if (err) + return err; + + datalen = *(u_int *)buf; + if (datalen > *namelen) + vm_allocate (mach_task_self (), (vm_address_t *) namep, datalen, 1); + bcopy (buf + sizeof (u_int), *namep, datalen); + *namelen = datalen; + return 0; +} + +/* Implement the diskfs_node_translated callback from the diskfs library. + See for the interface description. */ +int +diskfs_node_translated (struct node *np) +{ + int ret; + + if (diskfs_catch_exception ()) + return 0; + + ret = !! dinodes[np->dn->number].di_trans; + diskfs_end_catch_exception (); + return ret; +} + +/* Called when all hard ports have gone away. */ +void +diskfs_shutdown_soft_ports () +{ + /* Should initiate termination of internally held pager ports + (the only things that should be soft) XXX */ +} + -- cgit v1.2.3 From bf2eeb5c23810e91ebed3ab0104e63e88d869382 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 1 Sep 1994 15:39:31 +0000 Subject: entered into RCS --- ufs/tables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/tables.c b/ufs/tables.c index 81e3c25c..d345b9e4 100644 --- a/ufs/tables.c +++ b/ufs/tables.c @@ -34,7 +34,7 @@ * @(#)ffs_tables.c 8.1 (Berkeley) 6/11/93 */ -#include "ufs.h" +#include #include "fs.h" /* -- cgit v1.2.3 From 1a8d2047c10aae430523154ef02db5b255d634e9 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 6 Sep 1994 15:29:52 +0000 Subject: Formerly inode.c.~31~ --- ufs/inode.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 113f42d9..bfa50ece 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -95,9 +95,6 @@ iget (ino_t inum, struct node **npp) else np->allocsize = blkroundup (sblock, np->dn_stat.st_size); - /* XXX */ - assert (np->allocsize || !dinodes[np->dn->number].di_db[0]); - if (!diskfs_readonly && !np->dn_stat.st_gen) { spin_lock (&gennumberlock); -- cgit v1.2.3 From ce8b85a4435d0de91ead90975b05a39e44235c3b Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 9 Sep 1994 17:06:40 +0000 Subject: Formerly main.c.~17~ --- ufs/main.c | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 1ae0d749..98f9c50e 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -29,18 +29,18 @@ static char **save_argv; /* Parse the arguments for ufs when started as a translator. */ char * -trans_parse_args (int argc, char **arg) +trans_parse_args (int argc, char **argv) { - #ifdef notyet - /* Option to set compat_mode should be provided here. */ - + char *devname; /* When started as a translator, we are called with the device name and an optional argument -r, which signifies read-only. */ if (argc < 2 || argc > 3) - usage_trans (); + exit (1); + if (argc == 2) devname = argv[1]; + else if (argc == 3) { if (argv[1][0] == '-' && argv[1][1] == 'r') @@ -54,28 +54,10 @@ trans_parse_args (int argc, char **arg) devname = argv[1]; } else - usage_trans (); - } - - get_privileged_ports (&host_priv_port, &master_device_port); - if (!master_device_port) - { - fprintf (stderr, "%s: Cannot get master device port\n", - argv[0]); - exit (1); + exit (1); } - /* We only need the host port if we are a bootstrap filesystem. */ - if (host_priv_port) - mach_port_deallocate (mach_task_self (), host_priv_port); - - mach_port_insert_right (mach_task_self (), ufs_control_port, - ufs_control_port, MACH_MSG_TYPE_MAKE_SEND); - fsys_startup (bootstrap, ufs_control_port, &ufs_realnode); - mach_port_deallocate (mach_task_self (), ufs_control_port); -#else - task_terminate (mach_task_self ()); - for (;;); -#endif + + return devname; } struct node *diskfs_root_node; -- cgit v1.2.3 From 562b01b6103129dfb9e7264d16899298fec3bb4b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 10 Sep 1994 16:28:00 +0000 Subject: Formerly main.c.~18~ --- ufs/main.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 98f9c50e..ee0e2268 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include char *ufs_version = "0.0 pre-alpha"; @@ -105,14 +107,28 @@ main (int argc, char **argv) task_get_bootstrap_port (mach_task_self (), &bootstrap); if (bootstrap) - devname = trans_parse_args (argc, argv); + { + devname = trans_parse_args (argc, argv); + + { + /* XXX let us see errors */ + int fd = open ("/dev/console", O_RDWR); + assert (fd == 0); + fd = dup (0); + assert (fd == 1); + fd = dup (1); + assert (fd == 2); + } + } else { devname = diskfs_parse_bootargs (argc, argv); compat_mode = COMPAT_GNU; } - diskfs_init_diskfs (bootstrap); + /* Initialize the diskfs library. This must come before + any other diskfs call. */ + diskfs_init_diskfs (); err = device_open (diskfs_master_device, (diskfs_readonly ? 0 : D_WRITE) | D_READ, @@ -148,26 +164,38 @@ main (int argc, char **argv) if ((sblock->fs_inodefmt == FS_44INODEFMT || direct_symlink_extension) && compat_mode == COMPAT_BSD42) + /* XXX should syslog to this effect */ compat_mode = COMPAT_BSD44; if (!diskfs_readonly) { sblock->fs_clean = 0; - strcpy (sblock->fs_fsmnt, "Hurd /"); + strcpy (sblock->fs_fsmnt, "Hurd /"); /* XXX */ sblock_dirty = 1; diskfs_set_hypermetadata (1, 0); } + /* Initiialize our pagers so we can begin using them. */ inode_init (); pager_init (); - + + /* Start the first request thread, to handle RPCs and page requests + resulting from warp_root below. */ diskfs_spawn_first_thread (); - + + /* Find our root node. */ warp_root (); - - if (!bootstrap) + + /* Now that we are all set up to handle requests, and diskfs_root_node is + set properly, it is safe to export our fsys control port to the + outside world. */ + (void) diskfs_startup_diskfs (bootstrap); + + if (bootstrap == MACH_PORT_NULL) + /* We are the bootstrap filesystem; do special boot-time setup. */ diskfs_start_bootstrap (); + /* Now become a generic request thread. */ diskfs_main_request_loop (); } -- cgit v1.2.3 From cc158c8b21f911617d09ab3bcde369d45d70ebf0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 12 Sep 1994 15:30:33 +0000 Subject: Formerly hyper.c.~9~ --- ufs/hyper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index b39848ee..74415b63 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -107,7 +107,7 @@ diskfs_set_hypermetadata (int wait, int clean) { error_t (*writefn) (daddr_t, vm_address_t, long); writefn = (wait ? dev_write_sync : dev_write); - + spin_lock (&alloclock); if (csum_dirty) { @@ -117,7 +117,7 @@ diskfs_set_hypermetadata (int wait, int clean) csum_dirty = 0; } - if (clean) + if (clean && !diskfs_readonly) { sblock->fs_clean = 1; sblock_dirty = 1; @@ -146,7 +146,7 @@ diskfs_set_hypermetadata (int wait, int clean) sblock_dirty = 0; } - if (clean) + if (clean && !diskfs_readonly) { sblock->fs_clean = 0; sblock_dirty = 1; -- cgit v1.2.3 From e3a1889ecaf82f1c2291f2f939c3d71996b9b0a7 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 16 Sep 1994 14:33:29 +0000 Subject: Formerly dir.h.~3~ --- ufs/dir.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.h b/ufs/dir.h index 3fbb511a..c6535342 100644 --- a/ufs/dir.h +++ b/ufs/dir.h @@ -72,7 +72,10 @@ #define DIRBLKSIZ DEV_BSIZE #define MAXNAMLEN 255 -struct direct { +/* Don't call this struct DIRECT because the library defines that + (sometimes) in a possible different way. */ + +struct directory_entry { u_long d_ino; /* inode number of entry */ u_short d_reclen; /* length of this record */ u_char d_type; /* file type, see below */ @@ -98,7 +101,7 @@ struct direct { #define IFTODT(mode) (((mode) & 0170000) >> 12) #define DTTOIF(dirtype) ((dirtype) << 12) -/* Return the type from a struct direct, paying attention to whether +/* Return the type from a struct directory_entry, paying attention to whether this filesystem supports the type extension */ #define DIRECT_TYPE(dp) (direct_symlink_extension ? (dp)->d_type : DT_UNKNOWN) @@ -120,7 +123,7 @@ struct direct { /* In BSD this macro takes a struct direct. Modified by MIB here to take the namelen (as computed by strlen). */ #define DIRSIZ(namelen) \ - ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((namelen)+1 + 3) &~ 3)) + ((sizeof (struct directory_entry) - (MAXNAMLEN+1)) + (((namelen)+1 + 3) &~ 3)) #if 0 /* This is the BSD definition */ #if (BYTE_ORDER == LITTLE_ENDIAN) -- cgit v1.2.3 From 0963f46775c7f8eaea3bc6086b2217f8ebab8af8 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 16 Sep 1994 15:58:55 +0000 Subject: Formerly inode.c.~32~ --- ufs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index bfa50ece..f3f17086 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -179,7 +179,7 @@ read_disknode (struct node *np) return err; st->st_fstype = FSTYPE_UFS; - st->st_fsid = 0; /* XXX should fill this */ + st->st_fsid = getpid (); st->st_ino = np->dn->number; st->st_gen = di->di_gen; st->st_rdev = di->di_rdev; @@ -392,7 +392,7 @@ diskfs_set_statfs (struct fsys_statfsbuf *st) - (sblock->fs_dsize - st->fsys_stb_bfree)); st->fsys_stb_files = sblock->fs_ncg * sblock->fs_ipg - 2; /* not 0 or 1 */ st->fsys_stb_ffree = sblock->fs_cstotal.cs_nifree; - st->fsys_stb_fsid = 0; + st->fsys_stb_fsid = getpid (); return 0; } -- cgit v1.2.3 From 7923c99c3fb6536f4c7d575ff47becfb63e63d2f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 16 Sep 1994 17:24:59 +0000 Subject: Formerly dir.c.~26~ --- ufs/dir.c | 79 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 32 insertions(+), 47 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index a3b0b7f6..d0bf151d 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -65,11 +65,11 @@ struct dirstat /* For stat COMPRESS, this is the address (inside mapbuf) of the first direct in the directory block to be compressed. */ /* For stat HERE_TIS, SHRINK, and TAKE, this is the entry referenced. */ - struct direct *entry; + struct directory_entry *entry; /* For stat HERE_TIS, type REMOVE, this is the address of the immediately previous direct in this directory block, or zero if this is the first. */ - struct direct *preventry; + struct director_entry *preventry; }; size_t diskfs_dirstat_size = sizeof (struct dirstat); @@ -306,7 +306,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, int needed = 0; int countup = 0; vm_address_t currentoff, prevoff; - struct direct *entry; + struct directory_entry *entry; int nentries = 0; if (ds && ds->stat == LOOKING) @@ -319,7 +319,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, currentoff < blockaddr + DIRBLKSIZ; prevoff = currentoff, currentoff += entry->d_reclen) { - entry = (struct direct *)currentoff; + entry = (struct directory_entry *)currentoff; if (!entry->d_reclen || entry->d_reclen % 4 @@ -358,7 +358,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, { ds->type = CREATE; ds->stat = COMPRESS; - ds->entry = (struct direct *) blockaddr; + ds->entry = (struct directory_entry *) blockaddr; ds->idx = idx; countup = 0; } @@ -407,7 +407,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, ds->stat = HERE_TIS; ds->entry = entry; ds->idx = idx; - ds->preventry = (struct direct *) prevoff; + ds->preventry = (struct directory_entry *) prevoff; } *inum = entry->d_ino; @@ -427,13 +427,14 @@ diskfs_direnter(struct node *dp, struct dirstat *ds, struct protid *cred) { - struct direct *new; + struct directory_entry *new; int namelen = strlen (name); int needed = DIRSIZ (namelen); int oldneeded; vm_address_t fromoff, tooff; int totfreed; error_t err; + off_t newsize; assert (ds->type == CREATE); @@ -457,7 +458,7 @@ diskfs_direnter(struct node *dp, oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); assert (ds->entry->d_reclen - oldneeded >= needed); - new = (struct direct *) ((vm_address_t) ds->entry + oldneeded); + new = (struct directory_entry *) ((vm_address_t) ds->entry + oldneeded); new->d_ino = np->dn->number; new->d_reclen = ds->entry->d_reclen - oldneeded; @@ -479,8 +480,8 @@ diskfs_direnter(struct node *dp, while (fromoff < (vm_address_t) ds->entry + DIRBLKSIZ) { - struct direct *from = (struct direct *)fromoff; - struct direct *to = (struct direct *) tooff; + struct directory_entry *from = (struct directory_entry *)fromoff; + struct directory_entry *to = (struct directory_entry *) tooff; int fromreclen = from->d_reclen; if (from->d_ino != 0) @@ -498,7 +499,7 @@ diskfs_direnter(struct node *dp, totfreed = (vm_address_t) ds->entry + DIRBLKSIZ - tooff; assert (totfreed >= needed); - new = (struct direct *) tooff; + new = (struct directory_entry *) tooff; new->d_ino = np->dn->number; new->d_reclen = totfreed; DIRECT_NAMLEN (new) = namelen; @@ -511,14 +512,15 @@ diskfs_direnter(struct node *dp, /* Extend the file. */ assert (needed <= DIRBLKSIZ); - while (dp->dn_stat.st_size + DIRBLKSIZ > dp->allocsize) - if (err = diskfs_grow (dp, dp->dn_stat.st_size + DIRBLKSIZ, cred)) + newsize = dp->dn_stat.st_size + DIRBLKSIZ; + while (newsize > dp->allocsize) + if (err = diskfs_grow (dp, newsize, cred)) { vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); return err; } - new = (struct direct *) (ds->mapbuf + dp->dn_stat.st_size); + new = (struct directory_entry *) (ds->mapbuf + dp->dn_stat.st_size); dp->dn_stat.st_size += DIRBLKSIZ; dp->dn_set_ctime = 1; @@ -643,7 +645,7 @@ int diskfs_dirempty(struct node *dp, struct protid *cred) { - struct direct *entry; + struct directory_entry *entry; int curoff; vm_address_t buf; memory_object_t memobj; @@ -663,7 +665,7 @@ diskfs_dirempty(struct node *dp, curoff < buf + dp->dn_stat.st_size; curoff += entry->d_reclen) { - entry = (struct direct *) curoff; + entry = (struct directory_entry *) curoff; if (entry->d_ino != 0 && (DIRECT_NAMLEN (entry) > 2 @@ -701,7 +703,7 @@ count_dirents (struct node *dp, int nb, char *buf) { int amt; char *offinblk; - struct direct *entry; + struct directory_entry *entry; int count = 0; error_t err; @@ -717,7 +719,7 @@ count_dirents (struct node *dp, int nb, char *buf) offinblk < buf + DIRBLKSIZ; offinblk += entry->d_reclen) { - entry = (struct direct *) offinblk; + entry = (struct directory_entry *) offinblk; if (entry->d_ino) count++; } @@ -727,16 +729,6 @@ count_dirents (struct node *dp, int nb, char *buf) return 0; } -/* XXX */ -struct olddirect -{ - u_long d_ino; - u_short d_reclen; - u_short d_namlen; - char d_name[MAXNAMLEN + 1]; -}; - - /* Implement the disikfs_get_directs callback as described in . */ error_t @@ -757,10 +749,11 @@ diskfs_get_directs (struct node *dp, error_t err; int i; char *datap; - struct direct *entryp; + struct directory_entry *entryp; int allocsize; int checklen; - + struct dirent *userp; + nblks = dp->dn_stat.st_size/DIRBLKSIZ; if (!dp->dn->dirents) @@ -827,7 +820,7 @@ diskfs_get_directs (struct node *dp, } for (i = 0, bufp = buf; i < entry - curentry && bufp - buf < DIRBLKSIZ; - bufp += ((struct direct *)bufp)->d_reclen, i++) + bufp += ((struct directory_entry *)bufp)->d_reclen, i++) ; /* Make sure we didn't run off the end. */ assert (bufp - buf < DIRBLKSIZ); @@ -852,26 +845,18 @@ diskfs_get_directs (struct node *dp, bufp = buf; } - entryp = (struct direct *)bufp; + entryp = (struct directory_entry *)bufp; if (entryp->d_ino) { + userp = (struct dirent *) datap; + + userp->d_fileno = entryp->d_fileno; + userp->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); + userp->d_namlen = DIRECT_NAMLEN (entryp); + bcopy (entryp->d_name, userp->d_name, DIRECT_NAMLEN (entryp) + 1); #ifdef notyet - bcopy (bufp, datap, DIRSIZ (DIRECT_NAMLEN (entryp))); - if (!direct_symlink_extension) - { - /* Fix up fields into new format */ - ((struct direct *)datap)->d_namlen = DIRECT_NAMLEN (entryp); - ((struct direct *)datap)->d_type = DT_UNKNOWN; - } - ((struct direct *)datap)->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); -#else - struct olddirect *userd; - userd = (struct olddirect *)datap; - userd->d_ino = entryp->d_ino; - userd->d_namlen = DIRECT_NAMLEN (entryp); - userd->d_reclen = DIRSIZ (userd->d_namlen); - bcopy (entryp->d_name, userd->d_name, DIRECT_NAMLEN (entryp) + 1); + userp->d_type = entryp->d_type; #endif i++; datap += DIRSIZ (DIRECT_NAMLEN (entryp)); -- cgit v1.2.3 From 1ea101365f74d5df1372e0360d46cd16a13bc602 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 16 Sep 1994 18:48:26 +0000 Subject: Formerly dir.c.~27~ --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index d0bf151d..35760842 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -330,7 +330,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", - dp->dn->number, currentoff - blockaddr); + dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } -- cgit v1.2.3 From 8f5be4556fc63e831b3ebcf6de5d3515f5b311ed Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 19 Sep 1994 22:14:36 +0000 Subject: Formerly dir.c.~28~ --- ufs/dir.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 35760842..e4d54cdf 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -20,6 +20,9 @@ #include #include +#include + +#undef d_ino enum slot_status { @@ -69,7 +72,7 @@ struct dirstat /* For stat HERE_TIS, type REMOVE, this is the address of the immediately previous direct in this directory block, or zero if this is the first. */ - struct director_entry *preventry; + struct directory_entry *preventry; }; size_t diskfs_dirstat_size = sizeof (struct dirstat); @@ -434,7 +437,7 @@ diskfs_direnter(struct node *dp, vm_address_t fromoff, tooff; int totfreed; error_t err; - off_t newsize; + off_t oldsize; assert (ds->type == CREATE); @@ -512,17 +515,17 @@ diskfs_direnter(struct node *dp, /* Extend the file. */ assert (needed <= DIRBLKSIZ); - newsize = dp->dn_stat.st_size + DIRBLKSIZ; - while (newsize > dp->allocsize) - if (err = diskfs_grow (dp, newsize, cred)) + oldsize = dp->dn_stat.st_size; + while (oldsize + DIRBLKSIZ > dp->allocsize) + if (err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred)) { vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); return err; } - new = (struct directory_entry *) (ds->mapbuf + dp->dn_stat.st_size); + new = (struct directory_entry *) (ds->mapbuf + oldsize); - dp->dn_stat.st_size += DIRBLKSIZ; + dp->dn_stat.st_size = oldsize + DIRBLKSIZ; dp->dn_set_ctime = 1; new->d_ino = np->dn->number; @@ -851,7 +854,7 @@ diskfs_get_directs (struct node *dp, { userp = (struct dirent *) datap; - userp->d_fileno = entryp->d_fileno; + userp->d_fileno = entryp->d_ino; userp->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); userp->d_namlen = DIRECT_NAMLEN (entryp); bcopy (entryp->d_name, userp->d_name, DIRECT_NAMLEN (entryp) + 1); -- cgit v1.2.3 From 13843f409047b9458c3ea2fb0a390773afcef5f7 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 19 Sep 1994 23:13:07 +0000 Subject: Formerly inode.c.~33~ --- ufs/inode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index f3f17086..72bdc313 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -19,6 +19,7 @@ #include "dinode.h" #include "fs.h" #include +#include #define INOHSZ 512 #if ((INOHSZ&(INOHSZ-1)) == 0) @@ -173,13 +174,14 @@ read_disknode (struct node *np) struct stat *st = &np->dn_stat; struct dinode *di = &dinodes[np->dn->number]; error_t err; + volatile long long pid = getpid (); err = diskfs_catch_exception (); if (err) return err; st->st_fstype = FSTYPE_UFS; - st->st_fsid = getpid (); + st->st_fsid = pid; st->st_ino = np->dn->number; st->st_gen = di->di_gen; st->st_rdev = di->di_rdev; @@ -306,7 +308,7 @@ create_symlink_hook (struct node *np, char *target) if (!direct_symlink_extension) return EINVAL; - assert (!COMPAT_BSD42); + assert (compat_mode != COMPAT_BSD42); if (len >= sblock->fs_maxsymlinklen) return EINVAL; -- cgit v1.2.3 From 6337cbc4e5f5e0bdb6c41428fc4e15bc7791133c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 20 Sep 1994 19:53:01 +0000 Subject: Formerly pager.c.~27~ --- ufs/pager.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 7aea0f9d..994d65ee 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -387,8 +387,6 @@ pager_report_extent (struct user_pager_info *pager, vm_address_t *offset, vm_size_t *size) { - int sizet; - *offset = 0; switch (pager->type) { @@ -405,12 +403,24 @@ pager_report_extent (struct user_pager_info *pager, break; case SINDIR: - sizet = pager->np->allocsize; - sizet = (sizet + sblock->fs_bsize - 1) / sblock->fs_bsize; - sizet -= NDADDR; - sizet *= sizeof (daddr_t); - sizet = (sizet + sblock->fs_bsize - 1) / sblock->fs_bsize; - *size = sizet; + { + int sizet; + + /* sizet = disk size of the file */ + sizet = pager->np->allocsize; + + /* sizet = number of fs blocks in file */ + sizet = (sizet + sblock->fs_bsize - 1) / sblock->fs_bsize; + + /* sizet = number of fs blocks not list in di_db */ + sizet -= NDADDR; + + /* sizet = space to hold that many pointers */ + sizet *= sizeof (daddr_t); + + /* And that's the size of the sindir area for the file. */ + *size = sizet; + } break; case FILE_DATA: @@ -543,7 +553,6 @@ sin_remap (struct node *np, newsize = (newsize + sblock->fs_bsize - 1) / sblock->fs_bsize; newsize -= NDADDR; newsize *= sizeof (daddr_t); - newsize = (newsize + sblock->fs_bsize - 1) / sblock->fs_bsize; newsize = round_page (newsize); assert (newsize >= size); -- cgit v1.2.3 From 3f1568c61e2af535260364356338cc6adfff22d2 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Sep 1994 04:27:44 +0000 Subject: Formerly pager.c.~28~ --- ufs/pager.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 994d65ee..d94fd5ff 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -404,6 +404,9 @@ pager_report_extent (struct user_pager_info *pager, case SINDIR: { + /* This computation is known to sin_remap below, as + is the static `*offset = 0' assignment above. */ + int sizet; /* sizet = disk size of the file */ @@ -564,13 +567,13 @@ sin_remap (struct node *np, port = pager_get_port (upi->p); mach_port_insert_right (mach_task_self (), port, port, MACH_MSG_TYPE_MAKE_SEND); - err = vm_map (mach_task_self (), (u_int *)&np->dn->sinloc, size, + err = vm_map (mach_task_self (), (u_int *)&np->dn->sinloc, newsize, 0, 1, port, 0, 0, VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); mach_port_deallocate (mach_task_self (), port); assert (!err); diskfs_register_memory_fault_area (np->dn->sininfo->p, 0, - np->dn->sinloc, size); + np->dn->sinloc, newsize); } mutex_unlock (&pagernplock); } -- cgit v1.2.3 From 5e000c6f02312a721761e665a5b8db173d29996e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Sep 1994 17:38:49 +0000 Subject: Formerly inode.c.~34~ --- ufs/inode.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 72bdc313..55cef7d9 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -78,6 +78,8 @@ iget (ino_t inum, struct node **npp) rwlock_init (&dn->datalock); dn->dinloc = 0; dn->sinloc = 0; + dn->dinloclen = 0; + dn->sinloclen = 0; dn->sininfo = 0; dn->fileinfo = 0; @@ -147,6 +149,7 @@ diskfs_node_norefs (struct node *np) free (np->dn->dirents); assert (!np->dn->sininfo && !np->dn->fileinfo); assert (!np->dn->dinloc && !np->dn->sinloc); + assert (!np->dn->dinloclen && !np->dn->sinloclen); free (np->dn); free (np); } -- cgit v1.2.3 From 3f3454117144e15671fdd5a7618cbffb10cffb41 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Sep 1994 17:47:41 +0000 Subject: Formerly ufs.h.~20~ --- ufs/ufs.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index a9766422..1087c104 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -67,6 +67,9 @@ struct disknode /* These pointers are locked by sinmaplock and dinmaplock for all nodes. */ daddr_t *dinloc; daddr_t *sinloc; + + size_t dinloclen; + size_t sinloclen; /* These two pointers are locked by pagernplock in pager.c for all nodes. */ -- cgit v1.2.3 From d28ca40ffe939c84179f1377489949306f565335 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Sep 1994 19:26:23 +0000 Subject: Formerly sizes.c.~17~ --- ufs/sizes.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index c34474f5..bde73dee 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -129,6 +129,7 @@ diskfs_truncate (struct node *np, for (idx = first2free; idx <= olastblock; idx ++) { + assert (idx - NDADDR < np->dn->sinloclen); if (np->dn->sinloc[idx - NDADDR]) { ffs_blkfree (np, np->dn->sinloc[idx - NDADDR], sblock->fs_bsize); @@ -247,6 +248,7 @@ sindir_drop (struct node *np, din_map (np); for (idx = first; idx = last; idx++) { + assert (idx - 1 < np->dn->dinloclen); if (np->dn->dinloc[idx - 1]) { ffs_blkfree (np, np->dn->dinloc[idx - 1], sblock->fs_bsize); @@ -449,6 +451,7 @@ diskfs_grow (struct node *np, } lbn -= NDADDR; + assert (lbn < np->dn->sinloclen); if (!np->dn->sinloc[lbn]) { err = ffs_alloc (np, lbn, ffs_blkpref (np, lbn + NDADDR, lbn, @@ -501,8 +504,10 @@ diskfs_grow (struct node *np, round_page (poke_off2 + poke_len2)); mach_port_deallocate (mach_task_self (), obj); } - + +#if 0 diskfs_file_update (np, 0); +#endif return err; } -- cgit v1.2.3 From c9c5b4e8c965e94e22dae337238d9d6cffab8bdb Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Sep 1994 19:27:32 +0000 Subject: Formerly pager.c.~29~ --- ufs/pager.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index d94fd5ff..4de29518 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -44,6 +44,8 @@ static struct mutex pagernplock = MUTEX_INITIALIZER; #define MAY_CACHE 1 #endif +char typechars[] = "ICSDF"; + /* Find the location on disk of page OFFSET in pager UPI. Return the disk address (in disk block) in *ADDR. If *NPLOCK is set on return, then release that mutex after I/O on the data has @@ -113,6 +115,7 @@ find_address (struct user_pager_info *upi, maplock = &dinmaplock; if (!np->dn->dinloc) din_map (np); + assert (vblkno - 1 < np->dn->dinloclen); fsbaddr = np->dn->dinloc[vblkno - 1]; mutex_unlock (&dinmaplock); } @@ -149,6 +152,7 @@ find_address (struct user_pager_info *upi, maplock = &sinmaplock; if (!np->dn->sinloc) sin_map (np); + assert (vblkno - NDADDR < np->dn->sinloclen); fsbaddr = np->dn->sinloc[vblkno - NDADDR]; mutex_unlock (&sinmaplock); } @@ -221,6 +225,9 @@ pager_write_page (struct user_pager_info *pager, error_t err; struct disknode *dn; + printf ("%c", typechars[pager->type]); + fflush (stdout); + err = find_address (pager, page, &addr, &disksize, &nplock, &dn); if (err) return err; @@ -230,6 +237,7 @@ pager_write_page (struct user_pager_info *pager, else { printf ("Attempt to write unallocated disk\n."); + fflush (stdout); err = 0; /* unallocated disk; error would be pointless */ } @@ -299,6 +307,7 @@ pager_unlock_page (struct user_pager_info *pager, { if (!np->dn->dinloc) din_map (np); + assert (vblkno - 1 < np->dn->dinloclen); slot = &np->dn->dinloc[vblkno - 1]; } @@ -330,6 +339,7 @@ pager_unlock_page (struct user_pager_info *pager, > blkroundup (sblock, np->allocsize) - sblock->fs_bsize) { printf ("attempt to unlock at last block denied\n"); + fflush (stdout); rwlock_writer_unlock (&np->dn->datalock, np->dn); return EIO; } @@ -348,6 +358,7 @@ pager_unlock_page (struct user_pager_info *pager, { if (!np->dn->sinloc) sin_map (np); + assert (vblkno - NDADDR < np->dn->sinloclen); slot = &np->dn->sinloc[vblkno - NDADDR]; table = np->dn->sinloc; } @@ -527,7 +538,8 @@ sin_map (struct node *np) mach_port_deallocate (mach_task_self (), port); assert (!err); - + np->dn->sinloclen = extent / sizeof (daddr_t); + diskfs_register_memory_fault_area (np->dn->sininfo->p, offset, np->dn->sinloc, extent); } @@ -572,6 +584,7 @@ sin_remap (struct node *np, VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); mach_port_deallocate (mach_task_self (), port); assert (!err); + np->dn->sinloclen = newsize / sizeof (daddr_t); diskfs_register_memory_fault_area (np->dn->sininfo->p, 0, np->dn->sinloc, newsize); } @@ -590,6 +603,7 @@ sin_unmap (struct node *np) pager_report_extent (np->dn->sininfo, &start, &len); diskfs_unregister_memory_fault_area (np->dn->sinloc, len); vm_deallocate (mach_task_self (), (u_int) np->dn->sinloc, len); + np->dn->sinloclen = 0; np->dn->sinloc = 0; } @@ -608,6 +622,7 @@ din_map (struct node *np) VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); assert (!err); + np->dn->dinloclen = sblock->fs_bsize / sizeof (daddr_t); diskfs_register_memory_fault_area (dinpager->p, np->dn->number * sblock->fs_bsize, np->dn->dinloc, sblock->fs_bsize); @@ -620,6 +635,7 @@ din_unmap (struct node *np) { diskfs_unregister_memory_fault_area (np->dn->dinloc, sblock->fs_bsize); vm_deallocate (mach_task_self (), (u_int) np->dn->dinloc, sblock->fs_bsize); + np->dn->dinloclen = 0; np->dn->dinloc = 0; } -- cgit v1.2.3 From 9faf3438c0da06bb0bcf74e176479245fbd33619 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Sep 1994 20:16:07 +0000 Subject: Formerly sizes.c.~18~ --- ufs/sizes.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index bde73dee..cc25f680 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -505,9 +505,5 @@ diskfs_grow (struct node *np, mach_port_deallocate (mach_task_self (), obj); } -#if 0 - diskfs_file_update (np, 0); -#endif - return err; } -- cgit v1.2.3 From 06e3d2005d0b71a75974deffb66a93e396c00c04 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Sep 1994 20:18:44 +0000 Subject: Formerly pager.c.~30~ --- ufs/pager.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 4de29518..1916a79e 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -46,6 +46,13 @@ static struct mutex pagernplock = MUTEX_INITIALIZER; char typechars[] = "ICSDF"; +/* Limit the number of outstanding FILE_DATA paging requests. + Otherwise the kernel can send all the data at once and overwhelm us. */ +#define DATA_MAX_THREADS 10 +static int ndatapagethreads; +static struct mutex ndpthreads_lock = MUTEX_INITIALIZER; +static struct condition ndpthreads_wait = CONDITION_INITIALIZER; + /* Find the location on disk of page OFFSET in pager UPI. Return the disk address (in disk block) in *ADDR. If *NPLOCK is set on return, then release that mutex after I/O on the data has -- cgit v1.2.3 From a6d70799e9be91095fef56d6724daf00a079e6fa Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Sep 1994 02:35:30 +0000 Subject: Formerly ufs.h.~21~ --- ufs/ufs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 1087c104..76ab1e06 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -71,8 +71,7 @@ struct disknode size_t dinloclen; size_t sinloclen; - /* These two pointers are locked by pagernplock in pager.c for - all nodes. */ + /* These two pointers are locked by pagernplock for all nodes. */ struct user_pager_info *sininfo; struct user_pager_info *fileinfo; }; @@ -177,6 +176,7 @@ spin_lock_t alloclock; struct mutex dinmaplock; struct mutex sinmaplock; +struct mutex pagernplock; spin_lock_t gennumberlock; u_long nextgennumber; -- cgit v1.2.3 From 852149ee4f1e3390491149ed8c5e250d1076ca5c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Sep 1994 02:35:36 +0000 Subject: Formerly pager.c.~31~ --- ufs/pager.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 1916a79e..e6f3c08b 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -35,8 +35,7 @@ static void enqueue_pager (struct user_pager_info *); static void dequeue_pager (struct user_pager_info *); static daddr_t indir_alloc (struct node *, int, int); -/* Locks all nodes' sininfo and fileinfo fields. */ -static struct mutex pagernplock = MUTEX_INITIALIZER; +struct mutex pagernplock = MUTEX_INITIALIZER; #ifdef DONT_CACHE_MEMORY_OBJECTS #define MAY_CACHE 0 @@ -46,13 +45,6 @@ static struct mutex pagernplock = MUTEX_INITIALIZER; char typechars[] = "ICSDF"; -/* Limit the number of outstanding FILE_DATA paging requests. - Otherwise the kernel can send all the data at once and overwhelm us. */ -#define DATA_MAX_THREADS 10 -static int ndatapagethreads; -static struct mutex ndpthreads_lock = MUTEX_INITIALIZER; -static struct condition ndpthreads_wait = CONDITION_INITIALIZER; - /* Find the location on disk of page OFFSET in pager UPI. Return the disk address (in disk block) in *ADDR. If *NPLOCK is set on return, then release that mutex after I/O on the data has @@ -209,6 +201,8 @@ pager_read_page (struct user_pager_info *pager, } else { + printf ("Write-locked pagein Object %#x\tOffset %#x\n", pager, page); + fflush (stdout); vm_allocate (mach_task_self (), buf, __vm_page_size, 1); *writelock = 1; } @@ -232,8 +226,10 @@ pager_write_page (struct user_pager_info *pager, error_t err; struct disknode *dn; +#if 0 printf ("%c", typechars[pager->type]); fflush (stdout); +#endif err = find_address (pager, page, &addr, &disksize, &nplock, &dn); if (err) @@ -244,6 +240,7 @@ pager_write_page (struct user_pager_info *pager, else { printf ("Attempt to write unallocated disk\n."); + printf ("Object %#x\tOffset %#x\n", pager, page); fflush (stdout); err = 0; /* unallocated disk; error would be pointless */ @@ -271,6 +268,9 @@ pager_unlock_page (struct user_pager_info *pager, vblkno = address / sblock->fs_bsize; + printf ("Unlock page request, Object %#x\tOffset %#x...", pager, address); + fflush (stdout); + switch (pager->type) { case DINDIR: @@ -395,6 +395,12 @@ pager_unlock_page (struct user_pager_info *pager, err = 0; } + if (err) + printf ("denied\n"); + else + printf ("succeeded\n"); + fflush (stdout); + return err; } @@ -535,8 +541,6 @@ sin_map (struct node *np) mach_port_insert_right (mach_task_self (), port, port, MACH_MSG_TYPE_MAKE_SEND); } - mutex_unlock (&pagernplock); - pager_report_extent (upi, &offset, &extent); err = vm_map (mach_task_self (), (vm_address_t *)&np->dn->sinloc, @@ -549,6 +553,7 @@ sin_map (struct node *np) diskfs_register_memory_fault_area (np->dn->sininfo->p, offset, np->dn->sinloc, extent); + mutex_unlock (&pagernplock); } /* This is caled when a file (NP) grows (to size NEWSIZE) to see @@ -852,6 +857,7 @@ allow_pager_softrefs (struct node *np) if (np->dn->sininfo) pager_change_attributes (np->dn->sininfo->p, 1, MEMORY_OBJECT_COPY_DELAY, 0); + mutex_unlock (&pagernplock); } } -- cgit v1.2.3 From c3d5befb7e6321f6f28cc991e3024d71fffe1ea8 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Sep 1994 02:39:27 +0000 Subject: Formerly sizes.c.~19~ --- ufs/sizes.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index cc25f680..0bc0e547 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -505,5 +505,7 @@ diskfs_grow (struct node *np, mach_port_deallocate (mach_task_self (), obj); } + diskfs_file_update (np, 0); + return err; } -- cgit v1.2.3 From 8efcb72f07e27ab625ede2bc16abdfd5c7572f88 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Sep 1994 02:51:36 +0000 Subject: Formerly inode.c.~35~ --- ufs/inode.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 55cef7d9..757d8821 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -20,6 +20,7 @@ #include "fs.h" #include #include +#include #define INOHSZ 512 #if ((INOHSZ&(INOHSZ-1)) == 0) @@ -147,9 +148,19 @@ diskfs_node_norefs (struct node *np) np->dn->hnext->dn->hprevp = np->dn->hprevp; if (np->dn->dirents) free (np->dn->dirents); - assert (!np->dn->sininfo && !np->dn->fileinfo); - assert (!np->dn->dinloc && !np->dn->sinloc); - assert (!np->dn->dinloclen && !np->dn->sinloclen); + if (np->dn->sininfo || np->dn->fileinfo || np->dn->dinloc + || np->dn->sinloc || np->dn->dinloclen || np->dn->sinloclen) + { + printf ("I=%d\n", np->dn->number); + printf ("Hard %d\tSoft %d\n", np->references, np->light_references); + fflush (stdout); + } + assert (!np->dn->sininfo); + assert (!np->dn->fileinfo); + assert (!np->dn->dinloc); + assert (!np->dn->sinloc); + assert (!np->dn->dinloclen); + assert (!np->dn->sinloclen); free (np->dn); free (np); } -- cgit v1.2.3 From daf73bd08805ab863709eeb5488fd99aaeb128da Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Sep 1994 15:45:13 +0000 Subject: Formerly inode.c.~36~ --- ufs/inode.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 757d8821..67037450 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -72,8 +72,6 @@ iget (ino_t inum, struct node **npp) dn->number = inum; dn->dirents = 0; - mutex_init (&dn->rwlock_master); - condition_init (&dn->rwlock_wakeup); rwlock_init (&dn->dinlock); rwlock_init (&dn->sinlock); rwlock_init (&dn->datalock); -- cgit v1.2.3 From fbecadaf75d933aa3633a023c591b8fa8ec7611c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Sep 1994 15:56:24 +0000 Subject: Formerly ufs.h.~22~ --- ufs/ufs.h | 77 +++++++++++++++++++++++++-------------------------------------- 1 file changed, 30 insertions(+), 47 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 76ab1e06..fb9913ca 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -31,10 +31,11 @@ /* #undef DONT_CACHE_MEMORY_OBJECTS */ - /* Simple reader/writer lock. */ struct rwlock { + struct mutex master; + struct condition wakeup; int readers; int writers_waiting; int readers_waiting; @@ -51,97 +52,81 @@ struct disknode /* Links on hash list. */ struct node *hnext, **hprevp; - struct mutex rwlock_master; - struct condition rwlock_wakeup; - - struct rwlock dinlock; /* locks INDIR_DOUBLE pointer */ - - /* sinlock locks INDIR_SINGLE pointer and all the pointers in - the double indir block. */ - struct rwlock sinlock; - - /* datalock locks all the direct block pointers and all the pointers - in all the single indir blocks */ - struct rwlock datalock; + struct rwlock allocptrlock; - /* These pointers are locked by sinmaplock and dinmaplock for all nodes. */ daddr_t *dinloc; daddr_t *sinloc; size_t dinloclen; size_t sinloclen; - /* These two pointers are locked by pagernplock for all nodes. */ - struct user_pager_info *sininfo; struct user_pager_info *fileinfo; }; /* Get a reader lock on reader-writer lock LOCK for disknode DN */ extern inline void -rwlock_reader_lock (struct rwlock *lock, - struct disknode *dn) +rwlock_reader_lock (struct rwlock *lock) { - mutex_lock (&dn->rwlock_master); + mutex_lock (&lock->master); if (lock->readers == -1 || lock->writers_waiting) { lock->readers_waiting++; do - condition_wait (&dn->rwlock_wakeup, &dn->rwlock_master); + condition_wait (&lock->wakeup, &lock->master); while (lock->readers == -1 || lock->writers_waiting); lock->readers_waiting--; } lock->readers++; - mutex_unlock (&dn->rwlock_master); + mutex_unlock (&lock->master); } /* Get a writer lock on reader-writer lock LOCK for disknode DN */ extern inline void -rwlock_writer_lock (struct rwlock *lock, - struct disknode *dn) +rwlock_writer_lock (struct rwlock *lock) { - mutex_lock (&dn->rwlock_master); + mutex_lock (&lock->master); if (lock->readers) { lock->writers_waiting++; do - condition_wait (&dn->rwlock_wakeup, &dn->rwlock_master); + condition_wait (&lock->wakeup, &lock->master); while (lock->readers); lock->writers_waiting--; } lock->readers = -1; - mutex_unlock (&dn->rwlock_master); + mutex_unlock (&lock->master); } /* Release a reader lock on reader-writer lock LOCK for disknode DN */ extern inline void -rwlock_reader_unlock (struct rwlock *lock, - struct disknode *dn) +rwlock_reader_unlock (struct rwlock *lock) { - mutex_lock (&dn->rwlock_master); + mutex_lock (&lock->master); assert (lock->readers); lock->readers--; if (lock->readers_waiting || lock->writers_waiting) - condition_broadcast (&dn->rwlock_wakeup); - mutex_unlock (&dn->rwlock_master); + condition_broadcast (&lock->wakeup); + mutex_unlock (&lock->master); } /* Release a writer lock on reader-writer lock LOCK for disknode DN */ extern inline void -rwlock_writer_unlock (struct rwlock *lock, - struct disknode *dn) +rwlock_writer_unlock (struct rwlock *lock) { - mutex_lock (&dn->rwlock_master); + mutex_lock (&lock->master); assert (lock->readers == -1); lock->readers = 0; if (lock->readers_waiting || lock->writers_waiting) - condition_broadcast (&dn->rwlock_wakeup); - mutex_unlock (&dn->rwlock_master); + condition_broadcast (&lock->wakeup); + mutex_unlock (&lock->master); } /* Initialize reader-writer lock LOCK */ extern inline void rwlock_init (struct rwlock *lock) { + mutex_init (&lock->master); + condition_init (&lock->wakeup); lock->readers = 0; lock->readers_waiting = 0; lock->writers_waiting = 0; @@ -152,31 +137,29 @@ struct user_pager_info struct node *np; enum pager_type { - DINODE, - CG, - SINDIR, - DINDIR, + DISK, FILE_DATA, } type; struct pager *p; struct user_pager_info *next, **prevp; }; -struct user_pager_info *dinpager, *dinodepager, *cgpager; +struct user_pager_info *diskpager; vm_address_t zeroblock; +/* These are copies (not mapped) of the hypermetadata; maintained + by hypen.c. */ struct fs *sblock; -struct dinode *dinodes; -vm_address_t cgs; struct csum *csum; int sblock_dirty; int csum_dirty; -spin_lock_t alloclock; -struct mutex dinmaplock; -struct mutex sinmaplock; -struct mutex pagernplock; +/* These are both mapped from the disk appropriately. */ +struct dinode *dinodes; +vm_address_t cgs; + +spin_lock_t alloclock; spin_lock_t gennumberlock; u_long nextgennumber; -- cgit v1.2.3 From 26e07e59b4ab80c174e51975e275c95eb88f5518 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Sep 1994 16:43:13 +0000 Subject: Formerly pager.c.~32~ --- ufs/pager.c | 307 ++++++++++++++++++++---------------------------------------- 1 file changed, 99 insertions(+), 208 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index e6f3c08b..9b883b2b 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -21,15 +21,11 @@ #include #include -mach_port_t dinport; -mach_port_t dinodeport; -mach_port_t cgport; - /* Filesystem blocks of inodes per cylinder group */ static int infsb_pcg; spin_lock_t pagerlistlock = SPIN_LOCK_INITIALIZER; -struct user_pager_info *filelist, *sinlist; +struct user_pager_info *filepagerlist; static void enqueue_pager (struct user_pager_info *); static void dequeue_pager (struct user_pager_info *); @@ -43,8 +39,6 @@ struct mutex pagernplock = MUTEX_INITIALIZER; #define MAY_CACHE 1 #endif -char typechars[] = "ICSDF"; - /* Find the location on disk of page OFFSET in pager UPI. Return the disk address (in disk block) in *ADDR. If *NPLOCK is set on return, then release that mutex after I/O on the data has @@ -55,84 +49,34 @@ find_address (struct user_pager_info *upi, vm_address_t offset, daddr_t *addr, int *disksize, - struct rwlock **nplock, - struct disknode **dnp) + struct rwlock **nplock) { - int vblkno = lblkno (sblock, offset); - int fsbaddr; - struct node *volatile np; - error_t err; - struct mutex *maplock = 0; - - if (upi->type != FILE_DATA) - *disksize = __vm_page_size; + assert (upi->type == DISK || upi->type == FILE_DATA); - switch (upi->type) + if (upi->type == DISK) { - default: - assert (0); - - case CG: - fsbaddr = cgtod (sblock, vblkno); + *disksize = __vm_page_size; + *addr = offset / DEV_BSIZE; *nplock = 0; - break; - - case DINODE: - fsbaddr = (cgimin (sblock, vblkno / infsb_pcg) - + blkstofrags (sblock, vblkno % infsb_pcg)); - *nplock = 0; - break; - - case DINDIR: - np = ifind (vblkno); - - rwlock_reader_lock (&np->dn->dinlock, np->dn); - *nplock = &np->dn->dinlock; - *dnp = np->dn; - if (err = diskfs_catch_exception ()) - goto error; - - fsbaddr = dinodes[np->dn->number].di_ib[INDIR_DOUBLE]; - diskfs_end_catch_exception (); - break; - - case SINDIR: - np = upi->np; - - rwlock_reader_lock (&np->dn->sinlock, np->dn); - *nplock = &np->dn->sinlock; - *dnp = np->dn; - - if (err = diskfs_catch_exception ()) - goto error; - - if (vblkno == 0) - fsbaddr = dinodes[np->dn->number].di_ib[INDIR_SINGLE]; - else - { - mutex_lock (&dinmaplock); - maplock = &dinmaplock; - if (!np->dn->dinloc) - din_map (np); - assert (vblkno - 1 < np->dn->dinloclen); - fsbaddr = np->dn->dinloc[vblkno - 1]; - mutex_unlock (&dinmaplock); - } - - diskfs_end_catch_exception (); - break; - - case FILE_DATA: + return 0; + } + else + { + int vblkno = lblkno (sblock, offset); + int fsbaddr; + struct node *volatile np; + error_t err; + np = upi->np; - rwlock_reader_lock (&np->dn->datalock, np->dn); - *nplock = &np->dn->datalock; - *dnp = np->dn; + rwlock_reader_lock (&np->dn->allocptrlock); + *nplock = &np->dn->allocptrlock; if (offset >= np->allocsize) { err = EIO; - goto error; + rwlock_reader_unlock (&np->dn->allocptrlock); + return err; } if (offset + __vm_page_size > np->allocsize) @@ -141,39 +85,50 @@ find_address (struct user_pager_info *upi, *disksize = __vm_page_size; if (err = diskfs_catch_exception ()) - goto error; + { + rwlock_reader_unlock (&np->dn->allocptrlock); + return err; + } if (vblkno < NDADDR) fsbaddr = dinodes[np->dn->number].di_db[vblkno]; else { - mutex_lock (&sinmaplock); - maplock = &sinmaplock; - if (!np->dn->sinloc) - sin_map (np); - assert (vblkno - NDADDR < np->dn->sinloclen); - fsbaddr = np->dn->sinloc[vblkno - NDADDR]; - mutex_unlock (&sinmaplock); + vblkno -= NDADDR; + assert (vblkno < np->dn->sinloclen); + int alloc = 1; + + /* It's in the INDIR_DOUBLE area */ + if (vblkno >= sblock->fs_bsize / sizeof (daddr_t)) + { + /* Check if the double indirect block is allocated. */ + if (dinodes[np->dn->number].di_ib[INDIR_DOUBLE] == 0) + alloc = 0; + + /* Check if the appropriate single indirect block is + allocated. */ + else if (np->dinloc[vblkno / sblock->fs_bsize - 1] == 0) + alloc = 0; + } + else + if (dinodes[np->dn->number].di_ib[INDIR_SINGLE] == 0) + alloc = 0; + + fsbaddr = alloc ? np->dn->sinloc[vblkno - NDADDR] : 0; } diskfs_end_catch_exception (); - break; - } - if (fsbaddr) - *addr = fsbtodb (sblock, fsbaddr) + blkoff (sblock, offset) / DEV_BSIZE; - else - *addr = 0; + if (fsbaddr) + *addr = (fsbtodb (sblock, fsbaddr) + + blkoff (sblock, offset) / DEV_BSIZE); + else + *addr = 0; - return 0; - - error: - if (*nplock) - rwlock_reader_unlock (*nplock, *dnp); - if (maplock) - mutex_unlock (maplock); - return err; + return 0; + } } + /* Implement the pager_read_page callback from the pager library. See for the interface description. */ error_t @@ -186,9 +141,8 @@ pager_read_page (struct user_pager_info *pager, struct rwlock *nplock; daddr_t addr; int disksize; - struct disknode *dn; - err = find_address (pager, page, &addr, &disksize, &nplock, &dn); + err = find_address (pager, page, &addr, &disksize, &nplock); if (err) return err; @@ -208,7 +162,7 @@ pager_read_page (struct user_pager_info *pager, } if (nplock) - rwlock_reader_unlock (nplock, dn); + rwlock_reader_unlock (nplock); return err; } @@ -224,14 +178,8 @@ pager_write_page (struct user_pager_info *pager, int disksize; struct rwlock *nplock; error_t err; - struct disknode *dn; -#if 0 - printf ("%c", typechars[pager->type]); - fflush (stdout); -#endif - - err = find_address (pager, page, &addr, &disksize, &nplock, &dn); + err = find_address (pager, page, &addr, &disksize, &nplock); if (err) return err; @@ -247,7 +195,7 @@ pager_write_page (struct user_pager_info *pager, } if (nplock) - rwlock_reader_unlock (nplock, dn); + rwlock_reader_unlock (nplock); return err; } @@ -258,120 +206,63 @@ error_t pager_unlock_page (struct user_pager_info *pager, vm_offset_t address) { - struct node *volatile np; + struct node *np; error_t err; daddr_t vblkno; daddr_t *slot, *table; daddr_t newblk; + struct disknode *dn; /* Problem--where to get cred values for allocation here? */ - vblkno = address / sblock->fs_bsize; + vblkno = lblkno (address); printf ("Unlock page request, Object %#x\tOffset %#x...", pager, address); fflush (stdout); - switch (pager->type) - { - case DINDIR: - np = ifind (vblkno); - - rwlock_writer_lock (&np->dn->dinlock, np->dn); - if (diskfs_catch_exception ()) - err = EIO; - else - { - if (dinodes[np->dn->number].di_ib[INDIR_DOUBLE]) - err = 0; - else - { - newblk = indir_alloc (np, INDIR_DOUBLE, 0); - if (newblk) - { - dinodes[np->dn->number].di_ib[INDIR_DOUBLE] = newblk; - err = 0; - } - else - err = ENOSPC; - } - diskfs_end_catch_exception (); - } - rwlock_writer_unlock (&np->dn->dinlock, np->dn); - break; - - case SINDIR: - np = pager->np; - rwlock_writer_lock (&np->dn->sinlock, np->dn); - - if (diskfs_catch_exception ()) - err = EIO; - else - { - mutex_lock (&dinmaplock); - if (vblkno == 0) - slot = &dinodes[np->dn->number].di_ib[INDIR_SINGLE]; - else - { - if (!np->dn->dinloc) - din_map (np); - assert (vblkno - 1 < np->dn->dinloclen); - slot = &np->dn->dinloc[vblkno - 1]; - } - - if (*slot) - err = 0; - else - { - newblk = indir_alloc (np, INDIR_SINGLE, vblkno); - if (newblk) - { - *slot = newblk; - err = 0; - } - else - err = ENOSPC; - } - mutex_unlock (&dinmaplock); - diskfs_end_catch_exception (); - } - rwlock_writer_unlock (&np->dn->sinlock, np->dn); - break; + if (pager->type == DISK) + return 0; + + np = pager->np; + dn = np->dn; - case FILE_DATA: - np = pager->np; - rwlock_writer_lock (&np->dn->datalock, np->dn); + rwlock_writer_lock (&dn->allocptrlock); + + /* If this is the last block, we don't let it get unlocked. */ + if (address + __vm_page_size + > blkroundup (sblock, np->allocsize) - sblock->fs_bsize) + { + printf ("attempt to unlock at last block denied\n"); + fflush (stdout); + rwlock_writer_unlock (&np->dn->datalock, np->dn); + return EIO; + } + + if (diskfs_catch_exception ()) + { + rwlock_writer_unlock (&dn->allocptrlock); + return EIO; + } - /* If this is the last block, we don't let it get unlocked. */ - if (address + __vm_page_size - > blkroundup (sblock, np->allocsize) - sblock->fs_bsize) - { - printf ("attempt to unlock at last block denied\n"); - fflush (stdout); - rwlock_writer_unlock (&np->dn->datalock, np->dn); - return EIO; - } - - if (diskfs_catch_exception ()) - err = EIO; - else - { - mutex_lock (&sinmaplock); - if (vblkno < NDADDR) - { - slot = &dinodes[np->dn->number].di_db[vblkno]; - table = dinodes[np->dn->number].di_db; - } - else - { - if (!np->dn->sinloc) - sin_map (np); - assert (vblkno - NDADDR < np->dn->sinloclen); - slot = &np->dn->sinloc[vblkno - NDADDR]; - table = np->dn->sinloc; - } + if (vblkno < NDADDR) + { + slot = &dinodes[np->dn->number].di_db[vblkno]; + table = dinodes[np->dn->number].di_db; + } + else + { + assert (vblkno - NDADDR < np->dn->sinloclen); + slot = &np->dn->sinloc[vblkno - NDADDR]; + table = np->dn->sinloc; + } - if (*slot) - err = 0; + if (*slot) + { + diskfs_end_catch_exception (); + rwlock_write_unlock (&dn->allocptrlock); + return 0; + } + else { ffs_alloc (np, vblkno, -- cgit v1.2.3 From c05ecc35ea3ffb8fa8ec8cb91b5936859c716055 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 00:30:19 +0000 Subject: Formerly hyper.c.~10~ --- ufs/hyper.c | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 74415b63..4cdfa2dc 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -28,8 +28,7 @@ get_hypermetadata (void) { error_t err; - err = dev_read_sync (SBLOCK, (vm_address_t *)&sblock, SBSIZE); - assert (!err); + sblock = (struct fs *) disk_image + SBOFF; if (sblock->fs_magic != FS_MAGIC) { @@ -67,23 +66,32 @@ get_hypermetadata (void) if (sblock->fs_interleave < 1) sblock->fs_interleave = 1; - if (sblock->fs_postblformat == FS_42POSTBLFMT) - sblock->fs_nrpos = 8; - - if (sblock->fs_inodefmt < FS_44INODEFMT) + if (sblock->fs_postblformat == FS_42POSTBLFMT + || sblock->fs_inodefmt < FS_44INODEFMT) { - quad_t sizepb = sblock->fs_bsize; - int i; + /* Make a local copy so we don't write our different + values into the old format disk. */ + sblock = malloc (SBSIZE); + bcopy (disk_image + SBOFF, sblock, SBSIZE); + + if (sblock->fs_postblformat == FS_42POSTBLFMT) + sblock->fs_nrpos = 8; - oldformat = 1; - sblock->fs_maxfilesize = sblock->fs_bsize * NDADDR - 1; - for (i = 0; i < NIADDR; i++) + if (sblock->fs_inodefmt < FS_44INODEFMT) { - sizepb *= NINDIR (sblock); - sblock->fs_maxfilesize += sizepb; + quad_t sizepb = sblock->fs_bsize; + int i; + + oldformat = 1; + sblock->fs_maxfilesize = sblock->fs_bsize * NDADDR - 1; + for (i = 0; i < NIADDR; i++) + { + sizepb *= NINDIR (sblock); + sblock->fs_maxfilesize += sizepb; + } + sblock->fs_qbmask = ~sblock->fs_bmask; + sblock->fs_qfmask = ~sblock->fs_fmask; } - sblock->fs_qbmask = ~sblock->fs_bmask; - sblock->fs_qfmask = ~sblock->fs_fmask; } /* Find out if we support the 4.4 symlink/dirtype extension */ @@ -92,11 +100,9 @@ get_hypermetadata (void) else direct_symlink_extension = 0; - err = dev_read_sync (fsbtodb (sblock, sblock->fs_csaddr), - (vm_address_t *) &csum, - sblock->fs_fsize * howmany (sblock->fs_cssize, - sblock->fs_fsize)); - assert (!err); + csum = (struct csum *) + (disk_image + + howmany (sblock->fs_cssize, sblock->fs_fsize) * sblock->fs_fsize); } /* Write the superblock and cg summary info to disk. If WAIT is set, @@ -109,13 +115,6 @@ diskfs_set_hypermetadata (int wait, int clean) writefn = (wait ? dev_write_sync : dev_write); spin_lock (&alloclock); - if (csum_dirty) - { - (*writefn)(fsbtodb (sblock, sblock->fs_csaddr), (vm_address_t) csum, - sblock->fs_fsize * howmany (sblock->fs_cssize, - sblock->fs_fsize)); - csum_dirty = 0; - } if (clean && !diskfs_readonly) { @@ -139,6 +138,7 @@ diskfs_set_hypermetadata (int wait, int clean) sbcopy->fs_qbmask = -1; sbcopy->fs_qfmask = -1; } + bcopy (sbcopy, disk_image + SBOFF, SBSIZE) (*writefn) (SBLOCK, (vm_address_t) sblockcopy, SBSIZE); } else -- cgit v1.2.3 From dccd60ad78dc70619507c72c68f1a123827c4e99 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 00:44:18 +0000 Subject: Formerly hyper.c.~11~ --- ufs/hyper.c | 79 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 35 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 4cdfa2dc..a59637fb 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -28,8 +28,12 @@ get_hypermetadata (void) { error_t err; - sblock = (struct fs *) disk_image + SBOFF; + sblock = malloc (SBSIZE); + assert (!diskfs_catch_exception ()); + bcopy (disk_image + SBOFF, sblock, SBSIZE); + diskfs_end_catch_exception (); + if (sblock->fs_magic != FS_MAGIC) { fprintf (stderr, "Bad magic number %#lx (should be %#x)\n", @@ -66,32 +70,23 @@ get_hypermetadata (void) if (sblock->fs_interleave < 1) sblock->fs_interleave = 1; - if (sblock->fs_postblformat == FS_42POSTBLFMT - || sblock->fs_inodefmt < FS_44INODEFMT) - { - /* Make a local copy so we don't write our different - values into the old format disk. */ - sblock = malloc (SBSIZE); - bcopy (disk_image + SBOFF, sblock, SBSIZE); + if (sblock->fs_postblformat == FS_42POSTBLFMT) + sblock->fs_nrpos = 8; - if (sblock->fs_postblformat == FS_42POSTBLFMT) - sblock->fs_nrpos = 8; + if (sblock->fs_inodefmt < FS_44INODEFMT) + { + quad_t sizepb = sblock->fs_bsize; + int i; - if (sblock->fs_inodefmt < FS_44INODEFMT) + oldformat = 1; + sblock->fs_maxfilesize = sblock->fs_bsize * NDADDR - 1; + for (i = 0; i < NIADDR; i++) { - quad_t sizepb = sblock->fs_bsize; - int i; - - oldformat = 1; - sblock->fs_maxfilesize = sblock->fs_bsize * NDADDR - 1; - for (i = 0; i < NIADDR; i++) - { - sizepb *= NINDIR (sblock); - sblock->fs_maxfilesize += sizepb; - } - sblock->fs_qbmask = ~sblock->fs_bmask; - sblock->fs_qfmask = ~sblock->fs_fmask; + sizepb *= NINDIR (sblock); + sblock->fs_maxfilesize += sizepb; } + sblock->fs_qbmask = ~sblock->fs_bmask; + sblock->fs_qfmask = ~sblock->fs_fmask; } /* Find out if we support the 4.4 symlink/dirtype extension */ @@ -100,21 +95,35 @@ get_hypermetadata (void) else direct_symlink_extension = 0; - csum = (struct csum *) - (disk_image - + howmany (sblock->fs_cssize, sblock->fs_fsize) * sblock->fs_fsize); + csum = malloc (fsaddr (sblock, howmany (sblock->fs_cssize, + sblock->fs_fsize))); + + assert (!diskfs_catch_exception ()); + bcopy (disk_image + fsaddr (sblock, sblock->fs_csaddr), + csum, + fsaddr (sblock, howmany (sblock->fs_cssize, sblock->fs_fsize))); + diskfs_end_catch_exception (); } -/* Write the superblock and cg summary info to disk. If WAIT is set, - we must wait for everything to hit the disk; if CLEAN is set, then - mark the clean bit. */ +/* We don't need this callback; all our data is backed by pagers. */ void diskfs_set_hypermetadata (int wait, int clean) { - error_t (*writefn) (daddr_t, vm_address_t, long); - writefn = (wait ? dev_write_sync : dev_write); +} + +/* Copy the sblock and csum into the disk */ +void +copy_sblock () +{ + assert (!diskfs_catch_exception ()); spin_lock (&alloclock); + if (csum_dirty) + { + bcopy (csum, disk_image + fsaddr (sblock, sblock->fs_csaddr), + fsaddr (sblock, howmany (sblock->fs_cssize, sblock->fs_fsize))); + csum_dirty = 0; + } if (clean && !diskfs_readonly) { @@ -138,11 +147,10 @@ diskfs_set_hypermetadata (int wait, int clean) sbcopy->fs_qbmask = -1; sbcopy->fs_qfmask = -1; } - bcopy (sbcopy, disk_image + SBOFF, SBSIZE) - (*writefn) (SBLOCK, (vm_address_t) sblockcopy, SBSIZE); + bcopy (sbcopy, disk_image + SBOFF, SBSIZE); } else - (*writefn) (SBLOCK, (vm_address_t) sblock, SBSIZE); + bcopy (sblock, disk_image + SBOFF, SBSIZE); sblock_dirty = 0; } @@ -151,8 +159,9 @@ diskfs_set_hypermetadata (int wait, int clean) sblock->fs_clean = 0; sblock_dirty = 1; } - + spin_unlock (&alloclock); + diskfs_end_catch_exception (); } -- cgit v1.2.3 From 5fbf0f632993ae920b695b2be3585fcd80f5baf1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 01:29:06 +0000 Subject: Formerly alloc.c.~15~ --- ufs/alloc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 19389afe..2d27c1e7 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -200,7 +200,7 @@ ffs_realloccg(register struct node *np, goto nospace; if (error = diskfs_catch_exception ()) return error; - bprev = dinodes[np->dn->number].di_db[lbprev]; + bprev = (dino (np->dn->number))->di_db[lbprev]; diskfs_end_catch_exception (); assert ("old block not allocated" && bprev); @@ -787,7 +787,7 @@ ffs_fragextend(struct node *np, } cgp = (struct cg *)bp->b_data; #else - cgp = (struct cg *) (cgs + sblock->fs_bsize * cg); + cgp = cg_locate (cg); #endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ @@ -852,7 +852,7 @@ ffs_alloccg(struct node *np, } cgp = (struct cg *)bp->b_data; #else - cgp = (struct cg *) (cgs + sblock->fs_bsize * cg); + cgp = cg_locate (cg); #endif if (!cg_chkmagic(cgp) || (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) { @@ -1146,7 +1146,7 @@ ffs_nodealloccg(struct node *np, } cgp = (struct cg *)bp->b_data; #else - cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); + cgp = cg_locate (cg); #endif if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) { /* brelse(bp); */ @@ -1227,7 +1227,7 @@ ffs_blkfree(register struct node *np, } cgp = (struct cg *)bp->b_data; #else - cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); + cgp = cg_locate (cg); #endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ @@ -1317,7 +1317,7 @@ diskfs_free_node (struct node *np, mode_t mode) } cgp = (struct cg *)bp->b_data; #else - cgp = (struct cg *)(cgs + sblock->fs_bsize * cg); + cgp = cg_locate (cg); #endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ -- cgit v1.2.3 From e008ef767254409f7ebefb4e41180300b310a8dd Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 01:48:24 +0000 Subject: Initial revision --- ufs/bmap.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 ufs/bmap.c (limited to 'ufs') diff --git a/ufs/bmap.c b/ufs/bmap.c new file mode 100644 index 00000000..8b544e40 --- /dev/null +++ b/ufs/bmap.c @@ -0,0 +1,24 @@ +/* Interpretation of indirect block structure + Copyright (C) 1994 Free Software Foundation, Inc. + Written by Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +#include "ufs.h" +#include "dinode.h" +#include "fs.h" -- cgit v1.2.3 From 3c2e2b076f48a787345f217c18a6c0e9a542c941 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 02:08:14 +0000 Subject: Formerly bmap.c.~2~ --- ufs/bmap.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'ufs') diff --git a/ufs/bmap.c b/ufs/bmap.c index 8b544e40..c2eea356 100644 --- a/ufs/bmap.c +++ b/ufs/bmap.c @@ -22,3 +22,82 @@ #include "ufs.h" #include "dinode.h" #include "fs.h" + +/* Number of block pointers that fit in a single disk block */ +#define NIPTR (sblock->fs_bsize / sizeof (daddr_t)) + +/* For logical block number LBN of file NP, look it the block address, + giving the "path" of indirect blocks to the file, starting + with the least indirect. Fill *INDIRS with information for + the block. */ +error_t +fetch_indir_spec (struct node *np, daddr_t lbn, struct iblock_spec *indirs) +{ + struct dinode *di = dino (np->dn->number); + int boff; + error_t err; + daddr_t *siblock; + + if (err = diskfs_catch_exception ()) + return err; + + if (lbn < NDADDR) + { + indirs[0].bno = di->di_db[lbn]; + indirs[0].offset = -1; + + diskfs_end_catch_exception (); + return 0; + } + + lbn -= NDADDR; + + indirs[0].offset = lbn % NIPTR; + + if (lbn / NIPTR) + { + /* We will use the double indirect block */ + int ibn; + daddr_t *diblock; + + ibn = lbn / NIPTR - 1; + + indirs[1].offset = ibn % NIPTR; + + /* We don't support triple indirect blocks, but this + is where we'd do it. */ + assert (!(ibn / NIPTR)); + + indirs[2].offset = -1; + indirs[2].bno = di->di_ib[INDIR_DOUBLE]; + + if (indirs[2].bno) + { + diblock = indir_block (indirs[2].bno); + indirs[1].bno = diblock[indirs[1].offset]; + } + else + indirs[1].bno = 0; + } + else + { + indirs[1].offset = -1; + indirs[1].bno = di->di_ib[INDIR_DOUBLE]; + } + + if (indirs[1].bno) + { + siblock = indir_block (indirs[1].bno); + indirs[0].bno = siblock[indirs[0].offset]; + } + else + indirs[0].bno = 0; + + diskfs_end_catch_exception (); + return 0; +} + + + + + -- cgit v1.2.3 From 6e7220dc1dcbde1a12984d5cb9899ccbc473eecb Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 02:51:16 +0000 Subject: Formerly ufs.h.~23~ --- ufs/ufs.h | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 15 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index fb9913ca..a1186531 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -54,12 +54,6 @@ struct disknode struct rwlock allocptrlock; - daddr_t *dinloc; - daddr_t *sinloc; - - size_t dinloclen; - size_t sinloclen; - struct user_pager_info *fileinfo; }; @@ -80,6 +74,17 @@ rwlock_reader_lock (struct rwlock *lock) mutex_unlock (&lock->master); } +/* Identifies a particular block and where it's found + when interpreting indirect block structure. */ +struct iblock_spec +{ + /* Disk address of block */ + daddr_t bno; + + /* Offset in next block up; -1 if it's in the inode itself. */ + int offset; +}; + /* Get a writer lock on reader-writer lock LOCK for disknode DN */ extern inline void rwlock_writer_lock (struct rwlock *lock) @@ -145,19 +150,15 @@ struct user_pager_info }; struct user_pager_info *diskpager; +mach_port_t diskpagerport; +off_t diskpagersize; vm_address_t zeroblock; -/* These are copies (not mapped) of the hypermetadata; maintained - by hypen.c. */ struct fs *sblock; struct csum *csum; -int sblock_dirty; -int csum_dirty; -/* These are both mapped from the disk appropriately. */ -struct dinode *dinodes; -vm_address_t cgs; +void *disk_image; spin_lock_t alloclock; @@ -181,7 +182,8 @@ enum compat_mode of the dinode. */ int direct_symlink_extension; - + +/* Handy macros */ #define DEV_BSIZE 512 #define NBBY 8 #define btodb(n) ((n) / DEV_BSIZE) @@ -191,6 +193,48 @@ int direct_symlink_extension; #define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) #define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) #define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<(i)%NBBY)) +#define fsaddr(fs,n) (fsbtodb(fs,n)*DEV_BSIZE) + + +/* Functions for looking inside disk_image */ + +/* Convert an inode number to the dinode on disk. */ +extern inline struct dinode * +dino (ino_t inum) +{ + return (struct disknode *) + (disk_image + + fsaddr (sblock, ino_to_fsba (sblock, inum)) + + ino_to_fsbo (sblock, inum)); +} + +/* Convert a indirect block number to a daddr_t table. */ +extern inline daddr_t * +indir_block (daddr_t bno) +{ + return (daddr_t *) (disk_image + fsaddr (fsbtodb (bno))); +} + +/* Convert a cg number to the cylinder group. */ +extern inline struct cg * +cg_locate (int ncg) +{ + return (struct cg *) (disk_image + fsaddr (cgtod (sblock, ncg))); +} + +/* Sync part of the disk */ +extern inline void +sync_disk_blocks (daddr_t blkno, size_t nbytes, int wait) +{ + pager_sync_some (diskpager->p, fsaddr (blkno), nbytes, wait); +} + +/* Sync an disk inode */ +extern inline void +sync_dinode (int inum, int wait) +{ + sync_disk_blocks (ino_to_fsba (sblock, inum), sblock->fs_fsize, wait); +} /* From alloc.c: */ error_t ffs_alloc (struct node *, daddr_t, daddr_t, int, daddr_t *, @@ -215,7 +259,6 @@ void inode_init (void); void write_all_disknodes (void); /* From pager.c: */ -void sync_dinode (struct node *, int); void pager_init (void); void din_map (struct node *); void sin_map (struct node *); -- cgit v1.2.3 From d0370cb4e0e430b6300a8545b3a78dcc5de1dfb0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 02:52:58 +0000 Subject: Formerly main.c.~19~ --- ufs/main.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index ee0e2268..5fd1ff11 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -98,7 +98,6 @@ main (int argc, char **argv) error_t err; int sizes[DEV_GET_SIZE_COUNT]; u_int sizescnt = 2; - save_argv = argv; @@ -145,6 +144,29 @@ main (int argc, char **argv) exit (1); } + diskpagersize = sizes[DEV_GET_SIZE_DEVICE_SIZE]; + assert (diskpagersize >= SBSIZE + SBOFF); + + /* Map the entire disk. */ + create_disk_pager (); + + err = vm_map (mach_task_self (), (vm_address_t *)&disk_image, + diskpagersize, 0, 1, diskpagerport, 0, 0, + VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), + VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), + VM_INHERIT_NONE); + assert (!err); + + if (diskpagersize < sblock->fs_size * sblock->fs_fsize) + { + fprintf (stderr, + "Disk size %d less than necessary " + "(superblock says we need %ld)\n", + sizes[DEV_GET_SIZE_DEVICE_SIZE], + sblock->fs_size * sblock->fs_fsize); + exit (1); + } + get_hypermetadata (); /* Check to make sure device size is big enough. */ -- cgit v1.2.3 From 2c6a8c23ec0177814ae0e9db526826d2def081cd Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 04:40:30 +0000 Subject: Formerly inode.c.~37~ --- ufs/inode.c | 126 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 69 insertions(+), 57 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 67037450..d5c17e99 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -72,14 +72,7 @@ iget (ino_t inum, struct node **npp) dn->number = inum; dn->dirents = 0; - rwlock_init (&dn->dinlock); - rwlock_init (&dn->sinlock); - rwlock_init (&dn->datalock); - dn->dinloc = 0; - dn->sinloc = 0; - dn->dinloclen = 0; - dn->sinloclen = 0; - dn->sininfo = 0; + rwlock_init (&dn->allocptrlock); dn->fileinfo = 0; np = diskfs_make_node (dn); @@ -92,6 +85,7 @@ iget (ino_t inum, struct node **npp) spin_unlock (&diskfs_node_refcnt_lock); err = read_disknode (np); + if (lblkno (sblock, np->dn_stat.st_size) < NDADDR) np->allocsize = fragroundup (sblock, np->dn_stat.st_size); else @@ -146,31 +140,63 @@ diskfs_node_norefs (struct node *np) np->dn->hnext->dn->hprevp = np->dn->hprevp; if (np->dn->dirents) free (np->dn->dirents); - if (np->dn->sininfo || np->dn->fileinfo || np->dn->dinloc - || np->dn->sinloc || np->dn->dinloclen || np->dn->sinloclen) - { - printf ("I=%d\n", np->dn->number); - printf ("Hard %d\tSoft %d\n", np->references, np->light_references); - fflush (stdout); - } - assert (!np->dn->sininfo); assert (!np->dn->fileinfo); - assert (!np->dn->dinloc); - assert (!np->dn->sinloc); - assert (!np->dn->dinloclen); - assert (!np->dn->sinloclen); free (np->dn); free (np); } -/* The last hard referencs to a node has gone away; arrange to have +/* The last hard reference to a node has gone away; arrange to have all the weak references dropped that can be. */ void -diskfs_lost_hardrefs (struct node *np) +diskfs_try_dropping_softrefs (struct node *np) { drop_pager_softrefs (np); } +/* The last hard reference to a node has gone away. */ +void +diskfs_lost_hardrefs (struct node *np) +{ + /* Check and see if there is a pager which has only + one reference (ours). If so, then drop that reference, + breaking the cycle. The complexity in this routine + is all due to this cycle. */ + + if (np->dn->fileinfo) + { + spin_lock (&_libports_portrefcntlock); + if (np->fileinfo->p->pi.refcnt == 1) + { + struct pager *p; + + /* The only way to get a new reference to the pager + in this state is to call diskfs_get_filemap; this + can't happen as long as we hold NP locked. So + we can safely unlock _libports_portrefcntlock for + the following call. */ + spin_unlock (&_libports_portrefcntlock); + + /* Right now the node is locked with no hard refs; + this is an anomolous situation. Before messing with + the reference count on the file pager, we have to + give ourselves a reference back so that we are really + allowed to hold the lock. Then we can do the + unreference. */ + p = np->fileinfo->p; + np->fileinfo = 0; + diskfs_nref (np); + pager_unreference (p); + + assert (np->references == 1 && np->light_references == 0); + + /* This will do the real deallocate. Whew. */ + diskfs_nput (np); + } + else + spin_unlock (&_libports_portrefcntlock); + } +} + /* A new hard reference to a node has been created; it's now OK to have unused weak references. */ void @@ -184,7 +210,7 @@ static error_t read_disknode (struct node *np) { struct stat *st = &np->dn_stat; - struct dinode *di = &dinodes[np->dn->number]; + struct dinode *di = dino (np->dn->number); error_t err; volatile long long pid = getpid (); @@ -192,6 +218,8 @@ read_disknode (struct node *np) if (err) return err; + np->istranslated = !! di->translator; + st->st_fstype = FSTYPE_UFS; st->st_fsid = pid; st->st_ino = np->dn->number; @@ -241,7 +269,7 @@ static void write_node (struct node *np) { struct stat *st = &np->dn_stat; - struct dinode *di = &dinodes[np->dn->number]; + struct dinode *di = dino (np->dn->number); error_t err; assert (!np->dn_set_ctime && !np->dn_set_atime && !np->dn_set_mtime); @@ -329,7 +357,7 @@ create_symlink_hook (struct node *np, char *target) if (err) return err; - bcopy (target, dinodes[np->dn->number].di_shortlink, len); + bcopy (target, (dino (np->dn->number))->di_shortlink, len); np->dn_stat.st_size = len; np->dn_set_ctime = 1; np->dn_set_mtime = 1; @@ -356,7 +384,7 @@ read_symlink_hook (struct node *np, if (err) return err; - bcopy (dinodes[np->dn->number].di_shortlink, buf, np->dn_stat.st_size); + bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); np->dn_set_atime = 1; diskfs_end_catch_exception (); @@ -387,10 +415,9 @@ void diskfs_write_disknode (struct node *np, int wait) { write_node (np); - sync_dinode (np, wait); + sync_dinode (np->dn->number, wait); } - /* Implement the diskfs_set_statfs callback from the diskfs library; see for the interface description. */ error_t @@ -430,7 +457,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, if (err) return err; - blkno = dinodes[np->dn->number].di_trans; + blkno = (dino (np->dn->number))->di_trans; if (namelen && !blkno) { @@ -441,27 +468,31 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, diskfs_end_catch_exception (); return err; } - dinodes[np->dn->number].di_trans = blkno; + (dino (np->dn->number))->di_trans = blkno; np->dn_set_ctime = 1; } else if (!namelen && blkno) { /* Clear block for translator going away. */ ffs_blkfree (np, blkno, sblock->fs_bsize); - dinodes[np->dn->number].di_trans = 0; + (dino (np->dn->number))->di_trans = 0; + np->istranslated = 0; np->dn_set_ctime = 1; } - diskfs_end_catch_exception (); - if (namelen) { bcopy (&namelen, buf, sizeof (u_int)); bcopy (name, buf + sizeof (u_int), namelen); - err = dev_write_sync (fsbtodb (sblock, blkno), - (vm_address_t)buf, sblock->fs_bsize); + + bcopy (buf, fsaddr (sblock, blkno), sblock->fs_bsize); + sync_disk_blocks (blkno, sblock->fs_bsize, 1); + + np->istranslated = 1; np->dn_set_ctime = 1; } + + diskfs_end_catch_exception (); return err; } @@ -478,15 +509,11 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) err = diskfs_catch_exception (); if (err) return err; - blkno = dinodes[np->dn->number].di_trans; - diskfs_end_catch_exception (); + blkno = (dino (np->dn->number))->di_trans; assert (blkno); - - err = dev_read_sync (fsbtodb (sblock, blkno), (vm_address_t *)&buf, - sblock->fs_bsize); - if (err) - return err; + bcopy (fsaddr (sblock, blkno), buf, sblock->fs_bsize); + diskfs_end_catch_exception (); datalen = *(u_int *)buf; if (datalen > *namelen) @@ -496,21 +523,6 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) return 0; } -/* Implement the diskfs_node_translated callback from the diskfs library. - See for the interface description. */ -int -diskfs_node_translated (struct node *np) -{ - int ret; - - if (diskfs_catch_exception ()) - return 0; - - ret = !! dinodes[np->dn->number].di_trans; - diskfs_end_catch_exception (); - return ret; -} - /* Called when all hard ports have gone away. */ void diskfs_shutdown_soft_ports () -- cgit v1.2.3 From e05d7cfc35960065686a8e27b921bf508bcace36 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 04:52:31 +0000 Subject: Formerly pager.c.~33~ --- ufs/pager.c | 595 ++++++++++++++---------------------------------------------- 1 file changed, 139 insertions(+), 456 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 9b883b2b..6f7ecc9f 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -21,18 +21,9 @@ #include #include -/* Filesystem blocks of inodes per cylinder group */ -static int infsb_pcg; - spin_lock_t pagerlistlock = SPIN_LOCK_INITIALIZER; struct user_pager_info *filepagerlist; -static void enqueue_pager (struct user_pager_info *); -static void dequeue_pager (struct user_pager_info *); -static daddr_t indir_alloc (struct node *, int, int); - -struct mutex pagernplock = MUTEX_INITIALIZER; - #ifdef DONT_CACHE_MEMORY_OBJECTS #define MAY_CACHE 0 #else @@ -62,10 +53,8 @@ find_address (struct user_pager_info *upi, } else { - int vblkno = lblkno (sblock, offset); - int fsbaddr; - struct node *volatile np; - error_t err; + struct iblock_spec indirs[NINDIR + 1]; + struct node *np; np = upi->np; @@ -74,9 +63,8 @@ find_address (struct user_pager_info *upi, if (offset >= np->allocsize) { - err = EIO; rwlock_reader_unlock (&np->dn->allocptrlock); - return err; + return EIO; } if (offset + __vm_page_size > np->allocsize) @@ -84,47 +72,19 @@ find_address (struct user_pager_info *upi, else *disksize = __vm_page_size; - if (err = diskfs_catch_exception ()) - { - rwlock_reader_unlock (&np->dn->allocptrlock); - return err; - } - - if (vblkno < NDADDR) - fsbaddr = dinodes[np->dn->number].di_db[vblkno]; + err = fetch_indir_spec (np, lblkno (offset), indirs); + if (err) + rwlock_reader_unlock (&np->dn->allocptrlock); else { - vblkno -= NDADDR; - assert (vblkno < np->dn->sinloclen); - int alloc = 1; - - /* It's in the INDIR_DOUBLE area */ - if (vblkno >= sblock->fs_bsize / sizeof (daddr_t)) - { - /* Check if the double indirect block is allocated. */ - if (dinodes[np->dn->number].di_ib[INDIR_DOUBLE] == 0) - alloc = 0; - - /* Check if the appropriate single indirect block is - allocated. */ - else if (np->dinloc[vblkno / sblock->fs_bsize - 1] == 0) - alloc = 0; - } + if (indirs[0].bno) + *addr = (fsbtodb (sblock, indirs[0].bno) + + blkoff (sblkc, offset) / DEV_BSIZE); else - if (dinodes[np->dn->number].di_ib[INDIR_SINGLE] == 0) - alloc = 0; - - fsbaddr = alloc ? np->dn->sinloc[vblkno - NDADDR] : 0; + *addr = 0; } - diskfs_end_catch_exception (); - - if (fsbaddr) - *addr = (fsbtodb (sblock, fsbaddr) - + blkoff (sblock, offset) / DEV_BSIZE); - else - *addr = 0; - - return 0; + + return err; } } @@ -208,15 +168,21 @@ pager_unlock_page (struct user_pager_info *pager, { struct node *np; error_t err; - daddr_t vblkno; - daddr_t *slot, *table; - daddr_t newblk; - struct disknode *dn; + struct iblock_spec indirs[NINDIR + 1]; + daddr_t bno; + + /* Zero an sblock->fs_bsize piece of disk starting at BNO, + synchronously. We do this on newly allocated indirect + blocks before setting the pointer to them to ensure that an + indirect block absolutely never points to garbage. */ + void zero_disk_block (int bno) + { + bzero (indir_block (bno), sblock->fs_bsize); + sync_disk_blocks (bno, sblock->fs_bsize, 1); + }; /* Problem--where to get cred values for allocation here? */ - vblkno = lblkno (address); - printf ("Unlock page request, Object %#x\tOffset %#x...", pager, address); fflush (stdout); @@ -238,60 +204,106 @@ pager_unlock_page (struct user_pager_info *pager, return EIO; } - if (diskfs_catch_exception ()) + err = fetch_indir_spec (np, lblkno (address), indirs); + if (err) { rwlock_writer_unlock (&dn->allocptrlock); return EIO; } - if (vblkno < NDADDR) - { - slot = &dinodes[np->dn->number].di_db[vblkno]; - table = dinodes[np->dn->number].di_db; - } - else + /* See if we need a triple indirect block; fail if we do. */ + assert (indirs[0].offset == -1 + || indirs[1].offset == -1 + || indirs[2].offset == -1); + + /* Check to see if this block is allocated. */ + if (indirs[0].bno == 0) { - assert (vblkno - NDADDR < np->dn->sinloclen); - slot = &np->dn->sinloc[vblkno - NDADDR]; - table = np->dn->sinloc; - } + if (indirs[0].offset == -1) + { + err = ffs_alloc (np, lblkno (address), + ffs_blkpref (np, lblkno (address), + lblkno (address), di->di_db), + sblock->fs_bsize, &bno, 0); + if (err) + goto out; + assert (lblkno (address) < NDADDR); + indirs[0].bno = di->di_db[lblkno (address)] = bno; + } + else + { + daddr_t *siblock; - if (*slot) - { - diskfs_end_catch_exception (); - rwlock_write_unlock (&dn->allocptrlock); - return 0; - } - - else + /* We need to set siblock to the single indirect block + array; see if the single indirect block is allocated. */ + if (indirs[1].bno == 0) { - ffs_alloc (np, vblkno, - ffs_blkpref (np, vblkno, slot - table, table), - sblock->fs_bsize, &newblk, 0); - if (newblk) + if (indirs[1].offset == -1) { - *slot = newblk; - err = 0; + err = ffs_alloc (np, lblkno (address), + ffs_blkpref (np, lblkno (address), + INDIR_SINGLE, di->di_ib), + sblock->fs_bsize, &bno, 0); + if (err) + goto out; + zero_disk_block (bno); + indirs[1].bno = di->di_ib[INDIR_SINGLE] = bno; } else - err = ENOSPC; + { + daddr_t *diblock; + + /* We need to set diblock to the double indirect + block array; see if the double indirect block is + allocated. */ + if (indirs[2].bno == 0) + { + /* This assert because triple indirection is + not supported. */ + assert (indirs[2].offset == -1); + + err = ffs_alloc (np, lblkno (address), + ffs_blkpref (np, lblkno (address), + INDIR_DOUBLE, di->di_ib), + sblock->fs_bsize, &bno, 0); + if (err) + goto out; + zero_disk_block (bno); + indirs[2].bno = di->di_ib[INDIR_DOUBLE] = bno; + } + + diblock = indir_block (indirs[2].bno); + + /* Now we can allocate the single indirect block */ + + err = ffs_alloc (np, lblkno (address), + ffs_blkpref (np, lblkno (address), + indirs[1].offset, diblock), + sblock->fs_bsize, &bno, 0); + if (err) + goto out; + zero_disk_block (bno); + indirs[1].bno = diblock[indirs[1].offset] = bno; + } } - mutex_unlock (&sinmaplock); - diskfs_end_catch_exception (); + + siblock = indir_block (indirs[1].bno); + + /* Now we can allocate the data block. */ + + err = ffs_alloc (np, lblkno (address), + ffs_blkpref (np, lblkno (address), + indirs[0].offset, siblock), + sblock->fs_bsize, &bno, 0); + if (err) + goto out; + indirs[0].bno = siblock[indirs[0].offset] = bno; } - rwlock_writer_unlock (&np->dn->datalock, np->dn); - break; - - default: - err = 0; } - if (err) - printf ("denied\n"); - else - printf ("succeeded\n"); - fflush (stdout); - + out: + diskfs_end_catch_exception (); + rwlock_writer_unlock (&np->dn->datalock, np->dn); return err; } @@ -302,51 +314,15 @@ pager_report_extent (struct user_pager_info *pager, vm_address_t *offset, vm_size_t *size) { - *offset = 0; - switch (pager->type) - { - case DINODE: - *size = sblock->fs_ipg * sblock->fs_ncg * sizeof (struct dinode); - break; - - case CG: - *size = sblock->fs_bsize * sblock->fs_ncg; - break; - - case DINDIR: - *size = sblock->fs_ipg * sblock->fs_ncg * sblock->fs_bsize; - break; - - case SINDIR: - { - /* This computation is known to sin_remap below, as - is the static `*offset = 0' assignment above. */ - - int sizet; - - /* sizet = disk size of the file */ - sizet = pager->np->allocsize; - - /* sizet = number of fs blocks in file */ - sizet = (sizet + sblock->fs_bsize - 1) / sblock->fs_bsize; + assert (pager->type == DISK || pager->type == FILE_DATA); - /* sizet = number of fs blocks not list in di_db */ - sizet -= NDADDR; - - /* sizet = space to hold that many pointers */ - sizet *= sizeof (daddr_t); + *offset = 0; - /* And that's the size of the sindir area for the file. */ - *size = sizet; - } - break; - - case FILE_DATA: - *size = pager->np->allocsize; - break; - } + if (pager->type == DISK) + *size = diskpagersize; + else + *size = pager->np->allocsize; - *size = round_page (*size); return 0; } @@ -355,192 +331,15 @@ pager_report_extent (struct user_pager_info *pager, void pager_clear_user_data (struct user_pager_info *upi) { - struct node *np = upi->np; - - switch (upi->type) - { - case FILE_DATA: - mutex_lock (&sinmaplock); - mutex_lock (&pagernplock); - np->dn->fileinfo = 0; - mutex_unlock (&pagernplock); - if (np->dn->sinloc) - sin_unmap (np); - mutex_unlock (&sinmaplock); - break; - - case SINDIR: - mutex_lock (&dinmaplock); - mutex_lock (&pagernplock); - np->dn->sininfo = 0; - mutex_unlock (&pagernplock); - if (np->dn->dinloc) - din_unmap (np); - mutex_unlock (&dinmaplock); - break; - - case DINDIR: - dinpager = 0; - return; - case CG: - cgpager = 0; - return; - case DINODE: - dinodepager = 0; - return; - } - - if (np) - diskfs_nrele_light (np); - dequeue_pager (upi); + assert (upi->type == FILE_DATA); + diskfs_nrele_light (upi->np); + *upi->prevp = upi->next; + if (upi->next) + upi->next->prevp = upi->prevp; free (upi); } -/* This is called (with sinmaplock held) to map the contents of the - single indirect blocks of node NP. */ -void -sin_map (struct node *np) -{ - int err; - struct user_pager_info *upi; - mach_port_t port; - vm_address_t offset; - vm_size_t extent; - - assert (!np->dn->sinloc); - - mutex_lock (&pagernplock); - if (np->dn->sininfo) - { - upi = np->dn->sininfo; - port = pager_get_port (upi->p); - mach_port_insert_right (mach_task_self (), port, port, - MACH_MSG_TYPE_MAKE_SEND); - } - else - { - upi = malloc (sizeof (struct user_pager_info)); - upi->type = SINDIR; - upi->np = np; - diskfs_nref_light (np); - - upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); - np->dn->sininfo = upi; - enqueue_pager (upi); - port = pager_get_port (upi->p); - mach_port_insert_right (mach_task_self (), port, port, - MACH_MSG_TYPE_MAKE_SEND); - } - pager_report_extent (upi, &offset, &extent); - - err = vm_map (mach_task_self (), (vm_address_t *)&np->dn->sinloc, - extent, 0, 1, port, offset, 0, VM_PROT_READ|VM_PROT_WRITE, - VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); - mach_port_deallocate (mach_task_self (), port); - - assert (!err); - np->dn->sinloclen = extent / sizeof (daddr_t); - - diskfs_register_memory_fault_area (np->dn->sininfo->p, offset, - np->dn->sinloc, extent); - mutex_unlock (&pagernplock); -} - -/* This is caled when a file (NP) grows (to size NEWSIZE) to see - if the single indirect mapping needs to grow to. sinmaplock - must be held. - The caller must set ip->i_allocsize to reflect newsize. */ -void -sin_remap (struct node *np, - int newsize) -{ - struct user_pager_info *upi; - int err; - vm_address_t offset; - vm_size_t size; - mach_port_t port; - - mutex_lock (&pagernplock); - upi = np->dn->sininfo; - - pager_report_extent (upi, &offset, &size); - - /* This is the same calculation as in pager_report_extent - for the SINDIR case. */ - newsize = (newsize + sblock->fs_bsize - 1) / sblock->fs_bsize; - newsize -= NDADDR; - newsize *= sizeof (daddr_t); - newsize = round_page (newsize); - - assert (newsize >= size); - if (newsize != size) - { - diskfs_unregister_memory_fault_area (np->dn->sinloc, size); - vm_deallocate (mach_task_self (), (u_int) np->dn->sinloc, size); - - port = pager_get_port (upi->p); - mach_port_insert_right (mach_task_self (), port, port, - MACH_MSG_TYPE_MAKE_SEND); - err = vm_map (mach_task_self (), (u_int *)&np->dn->sinloc, newsize, - 0, 1, port, 0, 0, VM_PROT_READ|VM_PROT_WRITE, - VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); - mach_port_deallocate (mach_task_self (), port); - assert (!err); - np->dn->sinloclen = newsize / sizeof (daddr_t); - diskfs_register_memory_fault_area (np->dn->sininfo->p, 0, - np->dn->sinloc, newsize); - } - mutex_unlock (&pagernplock); -} - -/* This is called (with sinmaplock set) to unmap the - single indirect block mapping of node NP. */ -void -sin_unmap (struct node *np) -{ - vm_offset_t start; - vm_size_t len; - - assert (np->dn->sinloc); - pager_report_extent (np->dn->sininfo, &start, &len); - diskfs_unregister_memory_fault_area (np->dn->sinloc, len); - vm_deallocate (mach_task_self (), (u_int) np->dn->sinloc, len); - np->dn->sinloclen = 0; - np->dn->sinloc = 0; -} - -/* This is called (with dinmaplock set) to map the contents - of the double indirect block of node NP. */ -void -din_map (struct node *np) -{ - int err; - - assert (!np->dn->dinloc); - - err = vm_map (mach_task_self (), (vm_address_t *)&np->dn->dinloc, - sblock->fs_bsize, 0, 1, dinport, - np->dn->number * sblock->fs_bsize, 0, - VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, - VM_INHERIT_NONE); - assert (!err); - np->dn->dinloclen = sblock->fs_bsize / sizeof (daddr_t); - diskfs_register_memory_fault_area (dinpager->p, - np->dn->number * sblock->fs_bsize, - np->dn->dinloc, sblock->fs_bsize); -} - -/* This is called (with dinmaplock set) to unmap the double - indirect block mapping of node NP. */ -void -din_unmap (struct node *np) -{ - diskfs_unregister_memory_fault_area (np->dn->dinloc, sblock->fs_bsize); - vm_deallocate (mach_task_self (), (u_int) np->dn->dinloc, sblock->fs_bsize); - np->dn->dinloclen = 0; - np->dn->dinloc = 0; -} /* Initialize the pager subsystem. */ void @@ -602,89 +401,22 @@ pager_init () MACH_MSG_TYPE_MAKE_SEND); } -/* Allocate one indirect block for NP. TYPE is either INDIR_DOUBLE or - INDIR_SINGLE; IND is (for INDIR_SINGLE) the index of the block - (The first block is 0, the next 1, etc.). */ -static daddr_t -indir_alloc (struct node *np, - int type, - int ind) -{ - daddr_t bn; - daddr_t lbn; - int error; - - switch (type) - { - case INDIR_DOUBLE: - lbn = NDADDR + sblock->fs_bsize / sizeof (daddr_t); - break; - case INDIR_SINGLE: - if (ind == 0) - lbn = NDADDR; - else - lbn = NDADDR + ind * sblock->fs_bsize / sizeof (daddr_t); - break; - default: - assert (0); - } - - if (error = ffs_alloc (np, NDADDR, - ffs_blkpref (np, lbn, 0, (daddr_t *)0), - sblock->fs_bsize, &bn, 0)) - return 0; - - /* We do this write synchronously so that the inode never - points at an indirect block full of garbage */ - if (dev_write_sync (fsbtodb (sblock, bn), zeroblock, sblock->fs_bsize)) - { - ffs_blkfree (np, bn, sblock->fs_bsize); - return 0; - } - else - return bn; -} - -/* Write a single dinode (NP->dn->number) to disk. This might sync more - than actually necessary; it's really just an attempt to avoid syncing - all the inodes. Return immediately if WAIT is clear. */ -void -sync_dinode (struct node *np, - int wait) -{ - vm_offset_t offset, offsetpg; - - offset = np->dn->number * sizeof (struct dinode); - offsetpg = offset / __vm_page_size; - offset = offsetpg * __vm_page_size; - - pager_sync_some (dinodepager->p, offset, __vm_page_size, wait); -} - /* This syncs a single file (NP) to disk. Wait for all I/O to complete if WAIT is set. NP->lock must be held. */ void diskfs_file_update (struct node *np, int wait) { - mutex_lock (&pagernplock); if (np->dn->fileinfo) pager_sync (np->dn->fileinfo->p, wait); - mutex_unlock (&pagernplock); - mutex_lock (&pagernplock); - if (np->dn->sininfo) - pager_sync (np->dn->sininfo->p, wait); - mutex_unlock (&pagernplock); - - pager_sync_some (dinpager->p, np->dn->number * sblock->fs_bsize, - sblock->fs_bsize, wait); + /* XXX FIXME sync indirect blocks XXX */ diskfs_node_update (np, wait); } /* Call this to create a FILE_DATA pager and return a send right. - NP must be locked. The toplock must be locked. */ + NP must be locked. */ mach_port_t diskfs_get_filemap (struct node *np) { @@ -697,7 +429,6 @@ diskfs_get_filemap (struct node *np) && (!direct_symlink_extension || np->dn_stat.st_size >= sblock->fs_maxsymlinklen))); - mutex_lock (&pagernplock); if (!np->dn->fileinfo) { upi = malloc (sizeof (struct user_pager_info)); @@ -706,7 +437,15 @@ diskfs_get_filemap (struct node *np) diskfs_nref_light (np); upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); np->dn->fileinfo = upi; - enqueue_pager (upi); + ports_port_ref (p); + + spin_lock (&pagerlistlock); + upi->next = filepagerlist; + upi->prevp = &filepagerlist; + if (upi->next) + upi->next->prevp = &upi->next; + filepagerlist = upi; + spin_unlock (&pagerlistlock); } right = pager_get_port (np->dn->fileinfo->p); mutex_unlock (&pagernplock); @@ -721,17 +460,9 @@ diskfs_get_filemap (struct node *np) void drop_pager_softrefs (struct node *np) { - if (MAY_CACHE) - { - mutex_lock (&pagernplock); - if (np->dn->fileinfo) - pager_change_attributes (np->dn->fileinfo->p, 0, - MEMORY_OBJECT_COPY_DELAY, 0); - if (np->dn->sininfo) - pager_change_attributes (np->dn->sininfo->p, 0, - MEMORY_OBJECT_COPY_DELAY, 0); - mutex_unlock (&pagernplock); - } + if (MAY_CACHE && np->dn->fileinfo) + pager_change_attributes (np->dn->fileinfo->p, 0, + MEMORY_OBJECT_COPY_DELAY, 0); } /* Call this when we should turn on caching because it's no longer @@ -739,67 +470,19 @@ drop_pager_softrefs (struct node *np) void allow_pager_softrefs (struct node *np) { - if (MAY_CACHE) - { - mutex_lock (&pagernplock); - if (np->dn->fileinfo) - pager_change_attributes (np->dn->fileinfo->p, 1, - MEMORY_OBJECT_COPY_DELAY, 0); - if (np->dn->sininfo) - pager_change_attributes (np->dn->sininfo->p, 1, - MEMORY_OBJECT_COPY_DELAY, 0); - mutex_unlock (&pagernplock); - } + if (MAY_CACHE && np->dn->fileinfo) + pager_change_attributes (np->dn->fileinfo->p, 1, + MEMORY_OBJECT_COPY_DELAY, 0); } /* Call this to find out the struct pager * corresponding to the FILE_DATA pager of inode IP. This should be used *only* as a subsequent argument to register_memory_fault_area, and will be deleted when - the kernel interface is fixed. */ + the kernel interface is fixed. NP must be locked. */ struct pager * diskfs_get_filemap_pager_struct (struct node *np) { - struct pager *p; - mutex_unlock (&pagernplock); - p = np->dn->fileinfo->p; - mutex_unlock (&pagernplock); - return p; -} - -/* Add pager P to the appropriate list (filelist or sinlist) of pagers - of its type. */ -static void -enqueue_pager (struct user_pager_info *p) -{ - struct user_pager_info **listp; - - if (p->type == FILE_DATA) - listp = &filelist; - else if (p->type == SINDIR) - listp = &filelist; - else - return; - - spin_lock (&pagerlistlock); - - p->next = *listp; - p->prevp = listp; - *listp = p; - if (p->next) - p->next->prevp = &p->next; - - spin_unlock (&pagerlistlock); -} - -/* Remove pager P from the linked list it was placed on with enqueue_pager. */ -static void -dequeue_pager (struct user_pager_info *p) -{ - spin_lock (&pagerlistlock); - if (p->next) - p->next->prevp = p->prevp; - *p->prevp = p->next; - spin_unlock (&pagerlistlock); + return np->dn->fileinfo->p; } /* Call function FUNC (which takes one argument, a pager) on each pager, with -- cgit v1.2.3 From 1fefc1704f3653c72bcc4963be6afd19621f0093 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 21:40:50 +0000 Subject: Formerly main.c.~20~ --- ufs/main.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 5fd1ff11..2f3aad09 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -150,6 +150,9 @@ main (int argc, char **argv) /* Map the entire disk. */ create_disk_pager (); + /* Start the first request thread, to handle RPCs and page requests. */ + diskfs_spawn_first_thread (); + err = vm_map (mach_task_self (), (vm_address_t *)&disk_image, diskpagersize, 0, 1, diskpagerport, 0, 0, VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), @@ -157,30 +160,20 @@ main (int argc, char **argv) VM_INHERIT_NONE); assert (!err); - if (diskpagersize < sblock->fs_size * sblock->fs_fsize) - { - fprintf (stderr, - "Disk size %d less than necessary " - "(superblock says we need %ld)\n", - sizes[DEV_GET_SIZE_DEVICE_SIZE], - sblock->fs_size * sblock->fs_fsize); - exit (1); - } - get_hypermetadata (); - /* Check to make sure device size is big enough. */ - if (sizes[DEV_GET_SIZE_DEVICE_SIZE] != 0) - if (sizes[DEV_GET_SIZE_DEVICE_SIZE] < sblock->fs_size * sblock->fs_fsize) + if (diskpagersize < sblock->fs_size * sblock->fs_fsize) { fprintf (stderr, - "Disk size %d less than necessary " + "Disk size (%d) less than necessary " "(superblock says we need %ld)\n", sizes[DEV_GET_SIZE_DEVICE_SIZE], sblock->fs_size * sblock->fs_fsize); exit (1); } + vm_allocate (mach_task_self (), &zeroblock, sblock->fs_bsize, 1); + /* If the filesystem has new features in it, don't pay attention to the user's request not to use them. */ if ((sblock->fs_inodefmt == FS_44INODEFMT @@ -201,10 +194,6 @@ main (int argc, char **argv) inode_init (); pager_init (); - /* Start the first request thread, to handle RPCs and page requests - resulting from warp_root below. */ - diskfs_spawn_first_thread (); - /* Find our root node. */ warp_root (); -- cgit v1.2.3 From 422856454093ef77ba75ed7d23c3a50743e1fa1c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 21:41:31 +0000 Subject: Formerly sizes.c.~20~ --- ufs/sizes.c | 719 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 357 insertions(+), 362 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 0bc0e547..a349eb40 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -30,283 +30,236 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define MAY_CACHE 1 #endif -static void dindir_drop (struct node *); -static void sindir_drop (struct node *, int, int); -static void poke_pages (memory_object_t, vm_offset_t, vm_offset_t); - -/* Truncate node NP to be at most LENGTH bytes. */ -/* The inode must be locked, and we must have the conch. */ -/* This is a pain. Sigh. */ + +/* Implement the diskfs_truncate callback; sse for the + interface description. */ error_t diskfs_truncate (struct node *np, off_t length) { - daddr_t lastblock, olastblock, bn; - off_t osize; - int bsize, idx; - mach_port_t obj; - - osize = np->dn_stat.st_size; - if (length >= osize) + int offset; + daddr_t lastiblock[NIADDR], lastblock, bn; + struct dinode *di = dino (np->dn->number); + int blocksfreed = 0; + + if (length >= np->dn_stat.st_size) return 0; - /* Check to see if this is a kludged symlink. */ + assert (!diskfs_readonly); + + /* First check to see if this is a kludged symlink; if so + this is special. */ if (direct_symlink_extension && S_ISLNK (np->dn_stat.st_mode) - && osize < sblock->fs_maxsymlinklen) + && np->dn_stat.st_size < sblock->fs_maxsymlinklen) { error_t err; - - /* Prune it here */ - err = diskfs_catch_exception (); - if (err) + + if (err = diskfs_catch_exception ()) return err; - - bzero (dinodes[np->dn->number].di_shortlink + length, - osize - length); + bzero (di->di_shortlink + length, np->dn_stat.st_size - length); diskfs_end_catch_exception (); np->dn_stat.st_size = length; - np->dn_set_ctime = 1; - np->dn_set_mtime = 1; + np->dn_set_ctime = np->dn_set_mtime = 1; + return 0; + } + + /* If the file is not being trucated to a block boundary, + the zero the partial bit in the new last block. */ + offset = blkoff (sblock, length); + if (offset) + { + int bsize; /* size of new last block */ + int savesize = np->allocsize; + + np->allocsize = length; /* temporary */ + bsize = blksize (sblock, np, lbkno (sblock, length)); + np->allocsize = savesize; + diskfs_node_rdwr (np, zeroblock, length, bsize - offset, 1, 0, 0); + diskfs_file_update (np, 1); } - /* Calculate block number of last block */ - lastblock = lblkno (sblock, length + sblock->fs_bsize - 1) - 1; - olastblock = lblkno (sblock, osize + sblock->fs_bsize - 1) - 1; - - /* If the prune is not to a block boundary, zero the bit upto the - next block boundary. */ - if (blkoff (sblock, length)) - diskfs_node_rdwr (np, (void *) zeroblock, length, - (blksize (sblock, np, lastblock) - - blkoff (sblock, length)), - 1, 0, 0); - - /* We are going to throw away the block pointers for the blocks - olastblock+1 through lastblock. This will cause the underlying - data to become zeroes, because of the behavior of pager_read_page - (in ufs/pager.c). Consequently, we have to take action to force - the kernel to immediately undertake any delayed copies that - implicitly depend on the data we are flushing. We also have to - prevent any new delayed copies from being undertaken until we - have finished the flush. */ + rwlock_writer_lock (&np->allocptrlock); + + /* Now flush all the data past the new size from the kernel. + Also force any delayed copies of this data to take place + immediately. (We are changing the data implicitly to zeros + and doing it without the kernels immediate knowledge; + this forces us to help out the kernel thusly.) */ if (np->dn->fileinfo) { - pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, + pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np); - mach_port_insert_right (mach_task_self (), obj, obj, + mach_port_insert_right (mach_task_self (), obj, obj, MACH_MSG_TYPE_MAKE_SEND); - poke_pages (obj, round_page (length), round_page (osize)); + poke_pages (obj, round_page (length), round_page (np->allocsize)); mach_port_deallocate (mach_task_self (), obj); + pager_flush_some (np->fileinfo->p, round_page (length), + np->allocsize - length, 1); } + + /* Calculate index into node's block list of direct + and indirect blocks which we want to keep. Lastblock + is -1 when the file is truncated to 0. */ + lastblock = lblkno (sblock, length + sblock->fs_bsize - 1) - 1; + lastiblock[INDIR_SINGLE] = lastblock - NDADDR; + lastiblock[INDIR_DOUBLE] = lastiblock[INDIR_SINGLE] - NINDIR (sblock); + lastiblock[INDIR_TRIPLE] = (lastiblock[INDIR_DOUBLE] + - NINDIR (sblock) * NINDIR (sblock)); - rwlock_writer_lock (&np->dn->datalock, np->dn); + /* Normalize to -1 indicating that this block will not be needed. */ + for (level = INDIR_TRIPLE; level >= INDIR_SINGLE; level--) + if (lastiblock[level] < 0) + lastiblock[level] = -1; - /* Update the size now. If we crash, fsck can finish freeing the - blocks. */ + /* Update the size on disk; fsck will finish freeing blocks if necessary + should we crash. */ np->dn_stat.st_size = length; - np->dn_stat_dirty = 1; + np->dn_set_mtime = 1; + np->dn_set_ctime = 1; + diskfs_node_update (np, 1); - /* Flush the old data. */ - if (np->dn->fileinfo) - pager_flush_some (np->dn->fileinfo->p, - (lastblock == -1 ? 0 : lastblock) * sblock->fs_bsize, - (olastblock - lastblock) * sblock->fs_bsize, 1); + /* Free the blocks. */ + + err = diskfs_catch_exception (); + if (err) + { + rwlock_writer_unlock (&np->allocptrlock); + return err; + } - /* Drop data blocks mapped by indirect blocks */ - if (olastblock >= NDADDR) + /* Indirect blocks first. */ + for (level = INDIR_TRIPLE; level >= INDIR_SINGLE; level--) + if (lastiblock[level] == -1 && di->di_ib[level]) + { + int count; + count = free_indir (np, di->di_ib[level], level); + blocksfreed += count; + di->di_ib[level] = 0; + } + + /* Whole direct blocks or frags */ + for (i = NDADDR - 1; i > lastblock; i--) { - daddr_t first2free; + long bsize; - mutex_lock (&sinmaplock); - if (!np->dn->sinloc) - sin_map (np); + bn = dn->di_db[i]; + if (bn == 0) + continue; - if (lastblock + 1 > NDADDR) - first2free = lastblock + 1; - else - first2free = NDADDR; - - for (idx = first2free; idx <= olastblock; idx ++) - { - assert (idx - NDADDR < np->dn->sinloclen); - if (np->dn->sinloc[idx - NDADDR]) - { - ffs_blkfree (np, np->dn->sinloc[idx - NDADDR], sblock->fs_bsize); - np->dn->sinloc[idx - NDADDR] = 0; - np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; - np->dn_stat_dirty = 1; - } - } + bsize = blksize (sblock, np, i); + ffs_blkfree (sblock, bn, bsize); + blocksfreed += btodb (bsize); - /* Prune the block pointers handled by the sindir pager. This will - free all the indirect blocks and such as necessary. */ - sindir_drop (np, lblkno(sblock, - (first2free - NDADDR) * sizeof (daddr_t)), - lblkno (sblock, (olastblock - NDADDR) * sizeof (daddr_t))); - - if (!np->dn->fileinfo) - sin_unmap (np); - mutex_unlock (&sinmaplock); + dn->di_db[i] = 0; } - /* Prune the blocks mapped directly from the inode */ - for (idx = lastblock + 1; idx < NDADDR; idx++) + /* Finally, check to see if the new last direct block is + changing size; if so release any frags necessary. */ + if (lastblock >= 0 + && dn->di_db[lastblock]) { - bn = dinodes[np->dn->number].di_db[idx]; - if (bn) + bn = dn->di_db[lastblock]; + long oldspace, newspace; + + oldspace = blksize (sblock, np, lastblock); + np->allocsize = length; + newspace = blksize (sblock, np, lastblock); + + assert (newspace); + + if (oldspace - newspace) { - dinodes[np->dn->number].di_db[idx] = 0; - assert (idx <= olastblock); - if (idx == olastblock) - bsize = blksize (sblock, np, idx); - else - bsize = sblock->fs_bsize; - ffs_blkfree (np, bn, bsize); - np->dn_stat.st_blocks -= bsize / DEV_BSIZE; - np->dn_stat_dirty = 1; + bn += numfrags (sblock, newspace); + ffs_blkfree (np, bn, oldspace - newspace); + blocksfreed += btodb (oldspace - newspace) } } + else + np->allocsize = length; - if (lastblock >= 0 && lastblock < NDADDR) - { - /* Look for a change in the size of the last direct block */ - bn = dinodes[np->dn->number].di_db[lastblock]; - if (bn) - { - off_t oldspace, newspace; - - oldspace = blksize (sblock, np, lastblock); - newspace = fragroundup (sblock, blkoff (sblock, length));; - assert (newspace); - if (oldspace - newspace) - { - bn += numfrags (sblock, newspace); - ffs_blkfree (np, bn, oldspace - newspace); - np->dn_stat.st_blocks -= (oldspace - newspace) / DEV_BSIZE; - np->dn_stat_dirty = 1; - } - } - } + diskfs_end_catch_exception (); - if (lastblock < NDADDR) - np->allocsize = fragroundup (sblock, length); - else - np->allocsize = blkroundup (sblock, length); + np->dn_set_ctime = 1; + diskfs_node_update (np, 1); - rwlock_writer_unlock (&np->dn->datalock, np->dn); + rwlock_writer_unlock (&np->allocptrlock); - /* Now we can allow delayed copies again */ + /* Now we can permit delayed copies again. */ if (np->dn->fileinfo) pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY, 0); - - diskfs_file_update (np, 1); - return 0; -} - -/* Deallocate the double indirect block of the file NP. */ -static void -dindir_drop (struct node *np) -{ - rwlock_writer_lock (&np->dn->dinlock, np->dn); - pager_flush_some (dinpager->p, np->dn->number * sblock->fs_bsize, - sblock->fs_bsize, 1); - - if (dinodes[np->dn->number].di_ib[INDIR_DOUBLE]) - { - ffs_blkfree (np, dinodes[np->dn->number].di_ib[INDIR_DOUBLE], - sblock->fs_bsize); - dinodes[np->dn->number].di_ib[INDIR_DOUBLE] = 0; - np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; - } - - rwlock_writer_unlock (&np->dn->dinlock, np->dn); + return 0; } - -/* Deallocate the single indirect blocks of file IP from - FIRST through LAST inclusive. */ -static void -sindir_drop (struct node *np, - int first, - int last) +/* Free indirect block BNO of level LEVEL; recursing if necessary + to free other indirect blocks. Return the number of disk + blocks freed. */ +static int +free_indir (struct node *np, daddr_t bno, int level) { - int idx; + int count = 0; + daddr_t *addrs; + int i; + struct indir_dirty *d, *prev, *nxt; - rwlock_writer_lock (&np->dn->sinlock, np->dn); + assert (bno); - pager_flush_some (np->dn->sininfo->p, first * sblock->fs_bsize, - (last - first + 1) * sblock->fs_bsize, 1); + addrs = indir_block (bno); + for (i = 0; i < NINDIR (sblock); i++) + if (addrs[i]) + { + if (level == INDIR_SINGLE) + { + ffs_blkfree (np, addrs[i], sblock->fs_bsize); + count += btodb (sblock->fs_bsize); + } + else + count += free_indir (addrs[i], level - 1); + } - /* Drop indirect blocks found in the double indirect block */ - if (last > 1) + /* Subtlety: this block is no longer necessary; the information + the kernel has cached corresponding to ADDRS is now unimportant. + Consider that if this block is allocated to a file, it will then + be double cached and the kernel might decide to write out + the disk_image version of the block. So we have to flush + the block from the kernel's memory, making sure we do it + synchronously--and BEFORE we attach it to the free list + with ffs_blkfree. */ + pager_flush_some (diskpager->p, fsaddr (bno), sblock->fs_bsize, 1); + + /* We should also take this block off the inode's list of + dirty indirect blocks if it's there. */ + prev = 0; + d = np->dirty; + while (d) { - mutex_lock (&dinmaplock); - if (!np->dn->dinloc) - din_map (np); - for (idx = first; idx = last; idx++) + next = d->next; + if (d->bno == bno) { - assert (idx - 1 < np->dn->dinloclen); - if (np->dn->dinloc[idx - 1]) - { - ffs_blkfree (np, np->dn->dinloc[idx - 1], sblock->fs_bsize); - np->dn->dinloc[idx - 1] = 0; - np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; - } + if (prev) + prev->next = next; + else + np->dirty = next; + free (d); } - - /* If we no longer need the double indirect block, drop it. */ - if (first <= 1) - dindir_drop (np); - - mutex_lock (&dinmaplock); - if (!np->dn->sininfo) - din_unmap (np); - mutex_unlock (&dinmaplock); - } - - /* Drop the block from the inode if we don't need it any more */ - if (first == 0 && dinodes[np->dn->number].di_ib[INDIR_SINGLE]) - { - ffs_blkfree (np, dinodes[np->dn->number].di_ib[INDIR_SINGLE], - sblock->fs_bsize); - dinodes[np->dn->number].di_ib[INDIR_SINGLE] = 0; - np->dn_stat.st_blocks -= sblock->fs_bsize / DEV_BSIZE; - } - rwlock_writer_unlock (&np->dn->sinlock, np->dn); -} - -/* Write something to each page from START to END inclusive of memory - object OBJ, but make sure the data doesns't actually change. */ -static void -poke_pages (memory_object_t obj, - vm_offset_t start, - vm_offset_t end) -{ - vm_address_t addr, poke; - vm_size_t len; - error_t err; - - while (start < end) - { - len = 8 * vm_page_size; - if (len > end - start) - len = end - start; - addr = 0; - err = vm_map (mach_task_self (), &addr, len, 0, 1, obj, start, 0, - VM_PROT_WRITE|VM_PROT_READ, VM_PROT_READ|VM_PROT_WRITE, 0); - if (!err) + else { - for (poke = addr; poke < addr + len; poke += vm_page_size) - *(volatile int *)poke = *(volatile int *)poke; - vm_deallocate (mach_task_self (), addr, len); + prev = d; + next = d->next; } - start += len; + d = next; } + + /* Free designated block */ + ffs_blkfree (np, bno, sblock->fs_bsize); + count += btodb (sblock->fs_bsize); + + return count; } + /* Implement the diskfs_grow callback; see for the interface description. */ @@ -315,197 +268,239 @@ diskfs_grow (struct node *np, off_t end, struct protid *cred) { - daddr_t lbn, pbn, nb; - int osize, size; - int err; - volatile daddr_t dealloc_on_error = 0; - volatile int dealloc_size = 0; - volatile off_t zero_off1 = 0, zero_off2 = 0; - volatile int zero_len1 = 0, zero_len2 = 0; - volatile off_t poke_off1 = 0, poke_off2 = 0; - volatile off_t poke_len1 = 0, poke_len2 = 0; - vm_address_t zerobuf; + daddr_t lbn, olbn; + int size, osize; + error_t err; + struct dinode *di = dino (np->dn->number); + off_t poke_off; + size_t poke_len = 0; + + /* Zero an sblock->fs_bsize piece of disk starting at BNO, + synchronously. We do this on newly allocated indirect + blocks before setting the pointer to them to ensure that an + indirect block absolutely never points to garbage. */ + void zero_disk_block (int bno) + { + bzero (indir_block (bno), sblock->fs_bsize); + sync_disk_blocks (bno, sblock->fs_bsize, 1); + }; + /* Check to see if we don't actually have to do anything */ if (end <= np->allocsize) return 0; - - rwlock_writer_lock (&np->dn->datalock, np->dn); - - /* This deallocation works for the calls to alloc, but not for - realloccg. I'm not sure how to prune the fragment down, especially if - we grew a fragment and then couldn't allocate the piece later. - freeing it all up is a royal pain, largely punted right now... -mib. - */ - if (err = diskfs_catch_exception()) - { - if (dealloc_on_error) - ffs_blkfree (np, dealloc_on_error, dealloc_size); - goto out; - } - /* This is the logical block number of what will be the last block. */ + assert (!diskfs_readonly); + + /* The new last block of the file. */ lbn = lblkno (sblock, end + sblock->fs_bsize - 1) - 1; - /* This is the size to be of that block if it is in the NDADDR array. */ + /* This is the size of that block if it is in the NDADDR array. */ size = fragroundup (sblock, blkoff (sblock, end)); if (size == 0) size = sblock->fs_bsize; - /* if we are writing a new block, then an old one may need to be - reallocated into a full block. */ + rwlock_writer_lock (&np->dn->allocptrlock); - nb = lblkno (sblock, np->allocsize + sblock->fs_bsize - 1) - 1; - if (np->allocsize && nb < NDADDR && nb < lbn) + /* The old last block of the file. */ + olbn = lbkno (sblock, np->allocsize + sblock->fs_bsize - 1) - 1; + + /* This is the size of that block if it is in the NDADDR array. */ + osize = fragroundup (sblock, blkoff (sblock, np->allocsize)); + if (osize == 0) + osize = sblock->fs_bsize; + + /* If this end point is a new block and the file currently + has a fragment, then expand the fragment to a full block. */ + if (np->allocsize && olbn < NDADDR && olbn < lbn) { - osize = blksize (sblock, np, nb); - if (osize < sblock->fs_bsize && osize > 0) + if (osize < sblock->fs_bsize) { - daddr_t old_pbn; + daddr_t olb_pbn, bno; err = ffs_realloccg (np, nb, - ffs_blkpref (np, nb, (int)nb, - dinodes[np->dn->number].di_db), - osize, sblock->fs_bsize, &pbn, cred); + ffs_blkpref (np, lbn, lbn, di->di_db), + osize, sblock->fs_bsize, &bno, cred); if (err) goto out; - np->allocsize = (nb + 1) * sblock->fs_bsize; - old_pbn = dinodes[np->dn->number].di_db[nb]; - dinodes[np->dn->number].di_db[nb] = pbn; - - /* The new disk blocks should be zeros but might not be. - This is a sanity measure that I'm not sure is necessary. */ - zero_off1 = nb * sblock->fs_bsize + osize; - zero_len1 = nb * sblock->fs_bsize + sblock->fs_bsize - zero_off1; + old_pbn = di->di_db + di->di_db[nb] = bno; + np->dn_set_ctime = 1; + + dev_write_sync (fsbtodb (bno) + btodb (osize), + zeroblock, sblock->fs_bsize - osize); if (pbn != old_pbn) { - /* Make sure that the old contents get written out by - poking the pages. */ - poke_off1 = nb * sblock->fs_bsize; - poke_len1 = osize; + /* Make sure the old contents get written out + to the new address by poking the pages. */ + poke_off = nb * sblock->fs_bsize; + poke_len = osize; } } } - - /* allocate this block */ + if (lbn < NDADDR) { - nb = dinodes[np->dn->number].di_db[lbn]; - - if (nb != 0) + daddr_t bno, old_pbn = di->di_db[lbn]; + + if (old_pbn != 0) { - /* consider need to reallocate a fragment. */ - osize = blkoff (sblock, np->allocsize); - if (osize == 0) - osize = sblock->fs_bsize; - if (size > osize) - { - err = ffs_realloccg (np, lbn, - ffs_blkpref (np, lbn, lbn, - dinodes[np->dn->number].di_db), - osize, size, &pbn, cred); - if (err) - goto out; - dinodes[np->dn->number].di_db[lbn] = pbn; - - /* The new disk blocks should be zeros but might not be. - This is a sanity measure that I'm not sure is necessary. */ - zero_off2 = lbn * sblock->fs_bsize + osize; - zero_len2 = lbn * sblock->fs_bsize + size - zero_off2; + /* The last block is already allocated. Therefore we + must be expanding the fragment. Make sure that's really + what we're up to. */ + assert (size > osize); + assert (lbn == olbn); + + err = ffs_realloccg (np, lbn, + ffs_blkpref (np, lbn, lbn, di->di_db), + osize, size, &bno, cred); + if (err) + goto out; + + di->di_db[lbn] = bno; + np->dn_sat_ctime = 1; + + dev_write_sync (fsbtodb (bno) + btodb (osize), + zeroblock, size - osize); - if (pbn != nb) - { - /* Make sure that the old contents get written out by - poking the pages. */ - poke_off2 = lbn * sblock->fs_bsize; - poke_len2 = osize; - } + if (pbn != old_pbn) + { + assert (!poke_len); + + /* Make sure the old contents get written out to + the new address by poking the pages. */ + poke_off = lbn * sblock->fs_bsize; + poke_len = osize; } } else { - err = ffs_alloc (np, lbn, - ffs_blkpref (np, lbn, lbn, - dinodes[np->dn->number].di_db), - size, &pbn, cred); + /* Allocate a new last block. */ + err = ffs_alloc (np, lbn, + ffs_blkpref (np, lbn, lbn, di->di_db), + size, &bno, cred); if (err) goto out; - dealloc_on_error = pbn; - dealloc_size = size; - dinodes[np->dn->number].di_db[lbn] = pbn; + + di->di_db[lbn] = pbn; + np->dn_set_ctime = 1; + + dev_write_sync (fsbtodb (bno), zeroblock, size); } - np->allocsize = fragroundup (sblock, end); } else { - /* Make user the sindir area is mapped at the right size. */ - mutex_lock (&sinmaplock); - if (np->dn->sinloc) - { - sin_remap (np, end); - np->allocsize = blkroundup (sblock, end); - } - else - { - np->allocsize = blkroundup (sblock, end); - sin_map (np); - } + struct iblock_spec indirs[NINDIR + 1]; + int i; + daddr_t *siblock; + + /* Count the number of levels of indirection. */ + err = fetch_indir_spec (np, lbn, indirs); + if (err) + goto out; - lbn -= NDADDR; - assert (lbn < np->dn->sinloclen); - if (!np->dn->sinloc[lbn]) + /* Make sure we didn't miss the NDADDR case + above somehow. */ + assert (indirs[0].offset != -1); + + /* See if we need a triple indirect block; fail if so. */ + assert (indirs[1].offset == -1 || indirs[2].offset == -1); + + /* Check to see if this block is allocated. If it is + that's an error. */ + assert (indirs[0].bno == 0); + + /* We need to set SIBLOCK to the single indirect block + array; see if the single indirect block is allocated. */ + if (indirs[1].bno == 0) { - err = ffs_alloc (np, lbn, ffs_blkpref (np, lbn + NDADDR, lbn, - np->dn->sinloc), - sblock->fs_bsize, &pbn, cred); - if (err) - goto out; - dealloc_on_error = pbn; - dealloc_size = sblock->fs_bsize; - np->dn->sinloc[lbn] = pbn; + /* Allocate it. */ + if (indirs[1].offset == -1) + { + err = ffs_alloc (np, lbn, + ffs_blkpref (np, lbn, INDIR_SINGLE, di->di_ib), + sblock->fs_bsize, &bno, 0); + if (err) + goto out; + zero_disk_block (bno); + indirs[1].bno = di->di_ib[INDIR_SINGLE] = bno; + } + else + { + daddr_t *diblock; + + /* We need to set diblock to the double indirect block + array; see if the double indirect block is allocated. */ + if (indirs[2].bno == 0) + { + /* This assert because triple indirection is not + supported. */ + assert (indirs[2].offset == -1); + err = ffs_alloc (np, lbn + ffs_blkpref (np, lbn, + INDIR_DOUBLE, di->di_ib), + sblock->fs_bsize, &bno, 0); + if (err) + goto out; + zero_disk_block (bno); + indirs[2].bno = di->di_ib[INDIR_DOUBLE] = bno; + } + + diblock = indir_block (indirs[2].bno); + mark_indir_dirty (indirs[2].bno); + + /* Now we can allocate the single indirect block */ + err = ffs_alloc (np, lbn, + ffs_blkpref (np, lbn, + indirs[1].offset, diblock), + sblock->fs_bsize, &bno, 0); + if (err) + goto out; + zero_disk_block (bno); + indirs[1].bno = diblock[indirs[1].offset] = bno; + } } - if (!np->dn->fileinfo) - sin_unmap (np); - mutex_unlock (&sinmaplock); - } + + siblock = indir_block (indirs[1].bno); + mark_indir_dirty (np, indirs[1].bno); - if (np->conch.holder) - ioserver_put_shared_data (np->conch.holder); + /* Now we can allocate the data block. */ + err = ffs_alloc (np, lbn, + ffs_blkpref (np, lbn, indirs[0].offset, siblock), + sblock->fn_bsize, &bno, 0); + if (err) + goto out; + indirs[0].bno = siblock[indirs[0].offset] = bno; + dev_write_sync (fsbtodb (bno), zeroblock, sblock->fs_bsize); + } out: - diskfs_end_catch_exception (); - rwlock_writer_unlock (&np->dn->datalock, np->dn); - - /* Do the pokes and zeros that we requested before; they have to be - done here because we can't cause a page while holding datalock. */ - if (zero_len1 || zero_len2) + if (!err) { - vm_allocate (mach_task_self (), &zerobuf, - zero_len1 > zero_len2 ? zero_len1 : zero_len2, 1); - if (zero_len1) - diskfs_node_rdwr (np, (char *) zerobuf, zero_off1, - zero_len1, 1, cred, 0); - if (zero_len2) - diskfs_node_rdwr (np, (char *) zerobuf, zero_off2, - zero_len2, 1, cred, 0); - vm_deallocate (mach_task_self (), zerobuf, - zero_len1 > zero_len2 ? zero_len1 : zero_len2); + int newallocsize; + if (lbn < NDADDR) + newallocsize = (lbn - 1) * sblock->fs_bsize + size; + else + newallocsize = lbn * sblock->fs_bsize; + assert (newallocsize > np->allocsize); + np->allocsize = newallocsize; } - if (poke_len1 || poke_len2) + + rwlock_writer_unlock (&np->allocptrlock); + + /* If we expanded a fragment, then POKE_LEN will be set. + We need to poke the requested amount of the memory object + so that the kernel will write out the data to the new location + at a suitable time. */ + if (poke_len) { - mach_port_t obj; obj = diskfs_get_filemap (np); - mach_port_insert_right (mach_task_self (), obj, obj, + mach_port_insert_reght (mach_task_self (), obj, obj, MACH_MSG_TYPE_MAKE_SEND); - if (poke_len1) - poke_pages (obj, trunc_page (poke_off1), - round_page (poke_off1 + poke_len1)); - if (poke_len2) - poke_pages (obj, trunc_page (poke_off2), - round_page (poke_off2 + poke_len2)); + poke_pages (obj, trunc_page (poke_off), + round_page (poke_off + poke_len)); mach_port_deallocate (mach_task_self (), obj); } - diskfs_file_update (np, 0); - return err; -} +} + -- cgit v1.2.3 From d7c2d027981d86ff9d5370dbd424650ea2c37fbc Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 21:49:57 +0000 Subject: Formerly ufs.h.~24~ --- ufs/ufs.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index a1186531..a4f0579c 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -23,6 +23,7 @@ #include #include #include +#include "fs.h" /* Define this if memory objects should not be cached by the kernel. @@ -54,6 +55,8 @@ struct disknode struct rwlock allocptrlock; + struct dirty_indir *dirty; + struct user_pager_info *fileinfo; }; @@ -85,6 +88,14 @@ struct iblock_spec int offset; }; +/* Identifies an indirect block owned by this file which + might be dirty. */ +struct dirty_indir +{ + daddr_t bno; /* Disk address of block. */ + struct dirty_indir *next; +}; + /* Get a writer lock on reader-writer lock LOCK for disknode DN */ extern inline void rwlock_writer_lock (struct rwlock *lock) @@ -202,7 +213,7 @@ int direct_symlink_extension; extern inline struct dinode * dino (ino_t inum) { - return (struct disknode *) + return (struct dinode *) (disk_image + fsaddr (sblock, ino_to_fsba (sblock, inum)) + ino_to_fsbo (sblock, inum)); @@ -212,21 +223,21 @@ dino (ino_t inum) extern inline daddr_t * indir_block (daddr_t bno) { - return (daddr_t *) (disk_image + fsaddr (fsbtodb (bno))); + return (daddr_t *) (disk_image + fsaddr (sblock, bno)); } /* Convert a cg number to the cylinder group. */ extern inline struct cg * cg_locate (int ncg) { - return (struct cg *) (disk_image + fsaddr (cgtod (sblock, ncg))); + return (struct cg *) (disk_image + fsaddr (sblock, cgtod (sblock, ncg))); } /* Sync part of the disk */ extern inline void sync_disk_blocks (daddr_t blkno, size_t nbytes, int wait) { - pager_sync_some (diskpager->p, fsaddr (blkno), nbytes, wait); + pager_sync_some (diskpager->p, fsaddr (sblock, blkno), nbytes, wait); } /* Sync an disk inode */ -- cgit v1.2.3 From 7d0599b3ffb4a08bfdcdaf8e0383f05c58517b51 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 21:50:13 +0000 Subject: Formerly alloc.c.~16~ --- ufs/alloc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 2d27c1e7..b7c1ec40 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -54,7 +54,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ */ #include "ufs.h" -#include "fs.h" #include "dinode.h" #include -- cgit v1.2.3 From 8a847cdca4840b9834994782789b1e4f69749ae3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 21:50:32 +0000 Subject: Formerly inode.c.~38~ --- ufs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index d5c17e99..e5e74736 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -17,7 +17,6 @@ #include "ufs.h" #include "dinode.h" -#include "fs.h" #include #include #include @@ -73,6 +72,7 @@ iget (ino_t inum, struct node **npp) dn->dirents = 0; rwlock_init (&dn->allocptrlock); + dn->dirty = 0; dn->fileinfo = 0; np = diskfs_make_node (dn); -- cgit v1.2.3 From d4d738ac07a1b6280b2cbcca64ec5757071fa846 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 21:50:43 +0000 Subject: Formerly hyper.c.~12~ --- ufs/hyper.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index a59637fb..e63e9eff 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -16,7 +16,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" -#include "fs.h" #include "dinode.h" #include #include @@ -60,6 +59,10 @@ get_hypermetadata (void) exit (1); } + assert ((__vm_page_size % DEV_BSIZE) == 0); + assert ((sblock->fs_bsize % DEV_BSIZE) == 0); + assert (__vm_page_size <= sblock->fs_bsize); + /* If this is an old filesystem, then we have some more work to do; some crucial constants might not be set; we are therefore forced to set them here. */ -- cgit v1.2.3 From 71cbb9b6c50902866147c6c01e15b825c5dac93c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 21:50:56 +0000 Subject: Formerly bmap.c.~3~ --- ufs/bmap.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/bmap.c b/ufs/bmap.c index c2eea356..58ec06f4 100644 --- a/ufs/bmap.c +++ b/ufs/bmap.c @@ -21,10 +21,6 @@ #include "ufs.h" #include "dinode.h" -#include "fs.h" - -/* Number of block pointers that fit in a single disk block */ -#define NIPTR (sblock->fs_bsize / sizeof (daddr_t)) /* For logical block number LBN of file NP, look it the block address, giving the "path" of indirect blocks to the file, starting @@ -52,21 +48,21 @@ fetch_indir_spec (struct node *np, daddr_t lbn, struct iblock_spec *indirs) lbn -= NDADDR; - indirs[0].offset = lbn % NIPTR; + indirs[0].offset = lbn % NINDIR (sblock) - if (lbn / NIPTR) + if (lbn / NINBIR (sblock)) { /* We will use the double indirect block */ int ibn; daddr_t *diblock; - ibn = lbn / NIPTR - 1; + ibn = lbn / NINDIR (sblock) - 1; - indirs[1].offset = ibn % NIPTR; + indirs[1].offset = ibn % NINDIR (sblock); /* We don't support triple indirect blocks, but this is where we'd do it. */ - assert (!(ibn / NIPTR)); + assert (!(ibn / NINDIR (sblock))); indirs[2].offset = -1; indirs[2].bno = di->di_ib[INDIR_DOUBLE]; @@ -97,7 +93,21 @@ fetch_indir_spec (struct node *np, daddr_t lbn, struct iblock_spec *indirs) return 0; } + +/* Mark indirect block BNO as dirty on node NP's list. NP must + be locked. */ +void +mark_indir_dirty (struct node *np, daddr_t bno) +{ + struct dirty_indir *d; + for (d = np->dn->dirty; d; d = d->next) + if (d->bno == bno) + return; - + d = malloc (sizeof (struct dirty_indir)); + d->bno = bno; + d->next = np->dn->dirty; + np->dn->dirty = d; +} -- cgit v1.2.3 From e35942f33cbf6e41afae957bd59a787a81fa34dd Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 21:50:58 +0000 Subject: Formerly pager.c.~34~ --- ufs/pager.c | 95 ++++++++++++++++--------------------------------------------- 1 file changed, 24 insertions(+), 71 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 6f7ecc9f..d5b3849f 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -16,7 +16,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" -#include "fs.h" #include "dinode.h" #include #include @@ -273,6 +272,7 @@ pager_unlock_page (struct user_pager_info *pager, } diblock = indir_block (indirs[2].bno); + mark_indir_dirty (indirs[2].bno); /* Now we can allocate the single indirect block */ @@ -288,6 +288,7 @@ pager_unlock_page (struct user_pager_info *pager, } siblock = indir_block (indirs[1].bno); + mark_indir_dirty (np, indirs[1].bno); /* Now we can allocate the data block. */ @@ -341,65 +342,18 @@ pager_clear_user_data (struct user_pager_info *upi) -/* Initialize the pager subsystem. */ +/* Create a the DISK pager, initializing DISKPAGER, and DISKPAGERPORT */ void -pager_init () +create_disk_pager () { - struct user_pager_info *upi; - vm_address_t offset; - vm_size_t size; - error_t err; - - /* firewalls: */ - assert ((DEV_BSIZE % sizeof (struct dinode)) == 0); - assert ((__vm_page_size % DEV_BSIZE) == 0); - assert ((sblock->fs_bsize % DEV_BSIZE) == 0); - assert ((sblock->fs_ipg % sblock->fs_inopb) == 0); - assert (__vm_page_size <= sblock->fs_bsize); - - infsb_pcg = sblock->fs_ipg / sblock->fs_inopb; - - vm_allocate (mach_task_self (), &zeroblock, sblock->fs_bsize, 1); - - upi = malloc (sizeof (struct user_pager_info)); - upi->type = DINODE; - upi->np = 0; - upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); - dinodepager = upi; - dinodeport = pager_get_port (upi->p); - mach_port_insert_right (mach_task_self (), dinodeport, dinodeport, + diskpager = malloc (sizeof (struct user_pager_info)); + diskpager->type = DISK; + diskpager->np = 0; + diskpager->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); + diskpagerport = pager_get_port (upi->p); + mach_port_insert_right (mach_task_self (), diskpagerport, diskpagerport, MACH_MSG_TYPE_MAKE_SEND); - pager_report_extent (upi, &offset, &size); - err = vm_map (mach_task_self (), (vm_address_t *)&dinodes, size, - 0, 1, dinodeport, offset, 0, VM_PROT_READ|VM_PROT_WRITE, - VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); - assert (!err); - diskfs_register_memory_fault_area (dinodepager->p, 0, dinodes, size); - - upi = malloc (sizeof (struct user_pager_info)); - upi->type = CG; - upi->np = 0; - upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); - cgpager = upi; - cgport = pager_get_port (upi->p); - mach_port_insert_right (mach_task_self (), cgport, cgport, - MACH_MSG_TYPE_MAKE_SEND); - pager_report_extent (upi, &offset, &size); - err = vm_map (mach_task_self (), &cgs, size, - 0, 1, cgport, offset, 0, VM_PROT_READ|VM_PROT_WRITE, - VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE); - assert (!err); - diskfs_register_memory_fault_area (cgpager->p, 0, (void *)cgs, size); - - upi = malloc (sizeof (struct user_pager_info)); - upi->type = DINDIR; - upi->np = 0; - upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); - dinpager = upi; - dinport = pager_get_port (upi->p); - mach_port_insert_right (mach_task_self (), dinport, dinport, - MACH_MSG_TYPE_MAKE_SEND); -} +} /* This syncs a single file (NP) to disk. Wait for all I/O to complete if WAIT is set. NP->lock must be held. */ @@ -407,10 +361,18 @@ void diskfs_file_update (struct node *np, int wait) { + struct indir_dirty *d, *tmp; + if (np->dn->fileinfo) pager_sync (np->dn->fileinfo->p, wait); - /* XXX FIXME sync indirect blocks XXX */ + for (d = np->dn->dirty; d; d = tmp) + { + sync_disk_blocks (d->bno, sblock->fs_bsize, wait); + tmp = d->next; + free (d); + } + np->dn->dirty = 0; diskfs_node_update (np, wait); } @@ -486,23 +448,17 @@ diskfs_get_filemap_pager_struct (struct node *np) } /* Call function FUNC (which takes one argument, a pager) on each pager, with - all file pagers being processed before sindir pagers, and then the dindir, - dinode, and cg pagers (in that order). Make the calls while holding - no locks. */ + all file pagers being processed before the disk pager. Make the calls + while holding no locks. */ static void pager_traverse (void (*func)(struct user_pager_info *)) { struct user_pager_info *p; struct item {struct item *next; struct user_pager_info *p;} *list = 0; struct item *i; - int looped; - /* Putting SINDIR's on first means they will be removed last; after - the FILE_DATA pagers. */ spin_lock (&pagerlistlock); - for (p = sinlist, looped = 0; - p || (!looped && (looped = 1, p = filelist)); - p = p->next) + for (p = filepagerlit; p; p = p->next) { i = alloca (sizeof (struct item)); i->next = list; @@ -518,11 +474,8 @@ pager_traverse (void (*func)(struct user_pager_info *)) pager_unreference (i->p->p); } - (*func)(dinpager); - (*func)(dinodepager); - (*func)(cgpager); + (*func)(diskpager); } - /* Shutdown all the pagers. */ void -- cgit v1.2.3 From 75ba58c3a5a613bfdda55938e9e2c38b922dfc13 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 22:04:08 +0000 Subject: Formerly hyper.c.~13~ --- ufs/hyper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index e63e9eff..a5d05bc8 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -25,8 +25,6 @@ static int oldformat = 0; void get_hypermetadata (void) { - error_t err; - sblock = malloc (SBSIZE); assert (!diskfs_catch_exception ()); @@ -118,6 +116,8 @@ diskfs_set_hypermetadata (int wait, int clean) void copy_sblock () { + int clean = 1; /* XXX wrong... */ + assert (!diskfs_catch_exception ()); spin_lock (&alloclock); -- cgit v1.2.3 From 703bd469dfdc4bd41d987fb2cd08a662090f750a Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 22:06:02 +0000 Subject: Formerly main.c.~21~ --- ufs/main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 2f3aad09..b5e05f41 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -17,7 +17,6 @@ #include "ufs.h" -#include "fs.h" #include #include #include -- cgit v1.2.3 From 2b0776c062bea2d2e8b509c40832f5e4051aa64d Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 22:08:49 +0000 Subject: Formerly ufs.h.~25~ --- ufs/ufs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index a4f0579c..3088b2a2 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -168,6 +168,8 @@ vm_address_t zeroblock; struct fs *sblock; struct csum *csum; +int sblock_dirty; +int csum_dirty; void *disk_image; @@ -270,7 +272,7 @@ void inode_init (void); void write_all_disknodes (void); /* From pager.c: */ -void pager_init (void); +void create_disk_pager (void); void din_map (struct node *); void sin_map (struct node *); void sin_remap (struct node *, int); -- cgit v1.2.3 From a02e74948d63c82185875d40b201c3633a8ee3df Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 22:08:50 +0000 Subject: Formerly inode.c.~39~ --- ufs/inode.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index e5e74736..1caf947e 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -40,8 +40,6 @@ inode_init () int n; for (n = 0; n < INOHSZ; n++) nodehash[n] = 0; - mutex_init (&dinmaplock); - mutex_init (&sinmaplock); } /* Fetch inode INUM, set *NPP to the node structure; @@ -165,7 +163,7 @@ diskfs_lost_hardrefs (struct node *np) if (np->dn->fileinfo) { spin_lock (&_libports_portrefcntlock); - if (np->fileinfo->p->pi.refcnt == 1) + if (np->dn->fileinfo->p->pi.refcnt == 1) { struct pager *p; @@ -182,8 +180,8 @@ diskfs_lost_hardrefs (struct node *np) give ourselves a reference back so that we are really allowed to hold the lock. Then we can do the unreference. */ - p = np->fileinfo->p; - np->fileinfo = 0; + p = np->dn->fileinfo->p; + np->dn->fileinfo = 0; diskfs_nref (np); pager_unreference (p); @@ -218,7 +216,7 @@ read_disknode (struct node *np) if (err) return err; - np->istranslated = !! di->translator; + np->istranslated = !! di->di_translator; st->st_fstype = FSTYPE_UFS; st->st_fsid = pid; @@ -485,7 +483,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, bcopy (&namelen, buf, sizeof (u_int)); bcopy (name, buf + sizeof (u_int), namelen); - bcopy (buf, fsaddr (sblock, blkno), sblock->fs_bsize); + bcopy (buf, disk_image + fsaddr (sblock, blkno), sblock->fs_bsize); sync_disk_blocks (blkno, sblock->fs_bsize, 1); np->istranslated = 1; @@ -512,7 +510,7 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) blkno = (dino (np->dn->number))->di_trans; assert (blkno); - bcopy (fsaddr (sblock, blkno), buf, sblock->fs_bsize); + bcopy (disk_image + fsaddr (sblock, blkno), buf, sblock->fs_bsize); diskfs_end_catch_exception (); datalen = *(u_int *)buf; -- cgit v1.2.3 From 7f3059c7939bde35e4b7d1798834306c8bc7af8e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 23 Sep 1994 22:10:03 +0000 Subject: Formerly pager.c.~35~ --- ufs/pager.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index d5b3849f..e4abf85d 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -41,6 +41,8 @@ find_address (struct user_pager_info *upi, int *disksize, struct rwlock **nplock) { + error_t err; + assert (upi->type == DISK || upi->type == FILE_DATA); if (upi->type == DISK) @@ -52,7 +54,7 @@ find_address (struct user_pager_info *upi, } else { - struct iblock_spec indirs[NINDIR + 1]; + struct iblock_spec indirs[NIADDR + 1]; struct node *np; np = upi->np; @@ -71,14 +73,14 @@ find_address (struct user_pager_info *upi, else *disksize = __vm_page_size; - err = fetch_indir_spec (np, lblkno (offset), indirs); + err = fetch_indir_spec (np, lblkno (sblock, offset), indirs); if (err) rwlock_reader_unlock (&np->dn->allocptrlock); else { if (indirs[0].bno) *addr = (fsbtodb (sblock, indirs[0].bno) - + blkoff (sblkc, offset) / DEV_BSIZE); + + blkoff (sblkoc, offset) / DEV_BSIZE); else *addr = 0; } @@ -167,8 +169,9 @@ pager_unlock_page (struct user_pager_info *pager, { struct node *np; error_t err; - struct iblock_spec indirs[NINDIR + 1]; + struct iblock_spec indirs[NIADDR + 1]; daddr_t bno; + struct disknode *dn; /* Zero an sblock->fs_bsize piece of disk starting at BNO, synchronously. We do this on newly allocated indirect @@ -199,11 +202,11 @@ pager_unlock_page (struct user_pager_info *pager, { printf ("attempt to unlock at last block denied\n"); fflush (stdout); - rwlock_writer_unlock (&np->dn->datalock, np->dn); + rwlock_writer_unlock (&dn->allocptrlock); return EIO; } - err = fetch_indir_spec (np, lblkno (address), indirs); + err = fetch_indir_spec (np, lblkno (sblock, address), indirs); if (err) { rwlock_writer_unlock (&dn->allocptrlock); @@ -220,14 +223,14 @@ pager_unlock_page (struct user_pager_info *pager, { if (indirs[0].offset == -1) { - err = ffs_alloc (np, lblkno (address), - ffs_blkpref (np, lblkno (address), - lblkno (address), di->di_db), + err = ffs_alloc (np, lblkno (sblock, address), + ffs_blkpref (np, lblkno (sblock, address), + lblkno (sblock, address), di->di_db), sblock->fs_bsize, &bno, 0); if (err) goto out; - assert (lblkno (address) < NDADDR); - indirs[0].bno = di->di_db[lblkno (address)] = bno; + assert (lblkno (sblock, address) < NDADDR); + indirs[0].bno = di->di_db[lblkno (sblock, address)] = bno; } else { @@ -239,8 +242,8 @@ pager_unlock_page (struct user_pager_info *pager, { if (indirs[1].offset == -1) { - err = ffs_alloc (np, lblkno (address), - ffs_blkpref (np, lblkno (address), + err = ffs_alloc (np, lblkno (sblock, address), + ffs_blkpref (np, lblkno (sblock, address), INDIR_SINGLE, di->di_ib), sblock->fs_bsize, &bno, 0); if (err) @@ -261,8 +264,9 @@ pager_unlock_page (struct user_pager_info *pager, not supported. */ assert (indirs[2].offset == -1); - err = ffs_alloc (np, lblkno (address), - ffs_blkpref (np, lblkno (address), + err = ffs_alloc (np, lblkno (sblock, address), + ffs_blkpref (np, lblkno (sblock, + address), INDIR_DOUBLE, di->di_ib), sblock->fs_bsize, &bno, 0); if (err) @@ -276,8 +280,8 @@ pager_unlock_page (struct user_pager_info *pager, /* Now we can allocate the single indirect block */ - err = ffs_alloc (np, lblkno (address), - ffs_blkpref (np, lblkno (address), + err = ffs_alloc (np, lblkno (sblock, address), + ffs_blkpref (np, lblkno (sblock, address), indirs[1].offset, diblock), sblock->fs_bsize, &bno, 0); if (err) @@ -292,12 +296,15 @@ pager_unlock_page (struct user_pager_info *pager, /* Now we can allocate the data block. */ - err = ffs_alloc (np, lblkno (address), - ffs_blkpref (np, lblkno (address), + err = ffs_alloc (np, lblkno (sblock, address), + ffs_blkpref (np, lblkno (sblock, address), indirs[0].offset, siblock), sblock->fs_bsize, &bno, 0); if (err) goto out; + + dev_write_sync (fsbtodb (bno), zeroblock, sblock->fs_bsize); + indirs[0].bno = siblock[indirs[0].offset] = bno; } } -- cgit v1.2.3 From d8f33f64f398997cbf7e35a93ccd4bf7b42787b1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 26 Sep 1994 16:51:55 +0000 Subject: Formerly inode.c.~40~ --- ufs/inode.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 1caf947e..3edb697f 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -155,6 +155,7 @@ diskfs_try_dropping_softrefs (struct node *np) void diskfs_lost_hardrefs (struct node *np) { + struct port_info *pi; /* Check and see if there is a pager which has only one reference (ours). If so, then drop that reference, breaking the cycle. The complexity in this routine @@ -163,9 +164,9 @@ diskfs_lost_hardrefs (struct node *np) if (np->dn->fileinfo) { spin_lock (&_libports_portrefcntlock); - if (np->dn->fileinfo->p->pi.refcnt == 1) + pi = np->dn->fileinfo->p; + if (pi->refcnt == 1) { - struct pager *p; /* The only way to get a new reference to the pager in this state is to call diskfs_get_filemap; this @@ -216,7 +217,7 @@ read_disknode (struct node *np) if (err) return err; - np->istranslated = !! di->di_translator; + np->istranslated = !! di->di_trans; st->st_fstype = FSTYPE_UFS; st->st_fsid = pid; @@ -499,6 +500,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, error_t diskfs_get_translator (struct node *np, char **namep, u_int *namelen) { + XXX FIXME error_t err; daddr_t blkno; char *buf; -- cgit v1.2.3 From e67942011aa05d0fed6baed98556b3a207ce7c54 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 01:30:00 +0000 Subject: entered into RCS --- ufs/subr.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ufs') diff --git a/ufs/subr.c b/ufs/subr.c index 6c7ea5f2..2b356ddc 100644 --- a/ufs/subr.c +++ b/ufs/subr.c @@ -34,7 +34,6 @@ */ #include "ufs.h" -#include "fs.h" #if 0 /* Not needed in GNU Hurd ufs. */ /* -- cgit v1.2.3 From d813134b3217dcbf47a938659f9acd7dbfe1127f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:04:19 +0000 Subject: Formerly main.c.~22~ --- ufs/main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index b5e05f41..5f41265b 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -189,9 +189,7 @@ main (int argc, char **argv) diskfs_set_hypermetadata (1, 0); } - /* Initiialize our pagers so we can begin using them. */ inode_init (); - pager_init (); /* Find our root node. */ warp_root (); -- cgit v1.2.3 From 33c30e925639806931dbc124ee7c94a8cbd83c16 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:04:42 +0000 Subject: Formerly Makefile.~35~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 17bcf3f4..941452ff 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -19,7 +19,7 @@ dir := ufs makemode := server SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ - sizes.c subr.c tables.c + sizes.c subr.c tables.c bmap.c OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o LCLHDRS = ufs.h fs.h dinode.h dir.h REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ -- cgit v1.2.3 From 0692f912df6d760fdc7310a5733d07f63376aad4 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:51:13 +0000 Subject: Formerly ufs.h.~26~ --- ufs/ufs.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 3088b2a2..6d706100 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -24,7 +24,7 @@ #include #include #include "fs.h" - +#include "dinode.h" /* Define this if memory objects should not be cached by the kernel. Normally, don't define it, but defining it causes a much greater rate @@ -218,7 +218,7 @@ dino (ino_t inum) return (struct dinode *) (disk_image + fsaddr (sblock, ino_to_fsba (sblock, inum)) - + ino_to_fsbo (sblock, inum)); + + ino_to_fsbo (sblock, inum) * sizeof (struct dinode)); } /* Convert a indirect block number to a daddr_t table. */ @@ -257,6 +257,10 @@ daddr_t ffs_blkpref (struct node *, daddr_t, int, daddr_t *); error_t ffs_realloccg(struct node *, daddr_t, daddr_t, int, int, daddr_t *, struct protid *); +/* From bmap.c */ +error_t fetch_indir_spec (struct node *, daddr_t, struct iblock_spec *); +void mark_indir_dirty (struct node *, daddr_t); + /* From devio.c: */ error_t dev_write_sync (daddr_t addr, vm_address_t data, long len); error_t dev_write (daddr_t addr, vm_address_t data, long len); -- cgit v1.2.3 From 6ef59be7e2ab2cdb8a80356ea45e4b1218610c62 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:51:54 +0000 Subject: Formerly alloc.c.~17~ --- ufs/alloc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index b7c1ec40..c881454b 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -54,7 +54,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ */ #include "ufs.h" -#include "dinode.h" #include /* These don't work *at all* here; don't even try setting them. */ -- cgit v1.2.3 From 33cb86f397d267719d3aa68c40b15abb3c31c465 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:51:57 +0000 Subject: Formerly bmap.c.~4~ --- ufs/bmap.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/bmap.c b/ufs/bmap.c index 58ec06f4..18c53662 100644 --- a/ufs/bmap.c +++ b/ufs/bmap.c @@ -18,19 +18,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include "ufs.h" -#include "dinode.h" /* For logical block number LBN of file NP, look it the block address, giving the "path" of indirect blocks to the file, starting with the least indirect. Fill *INDIRS with information for the block. */ error_t -fetch_indir_spec (struct node *np, daddr_t lbn, struct iblock_spec *indirs) +fetch_indir_spec (struct node *np, volatile daddr_t lbn, + struct iblock_spec *indirs) { struct dinode *di = dino (np->dn->number); - int boff; error_t err; daddr_t *siblock; @@ -48,9 +46,9 @@ fetch_indir_spec (struct node *np, daddr_t lbn, struct iblock_spec *indirs) lbn -= NDADDR; - indirs[0].offset = lbn % NINDIR (sblock) + indirs[0].offset = lbn % NINDIR (sblock); - if (lbn / NINBIR (sblock)) + if (lbn / NINDIR (sblock)) { /* We will use the double indirect block */ int ibn; -- cgit v1.2.3 From a58816f05792722823d8907de36c8b08e2ffb134 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:52:27 +0000 Subject: Formerly sizes.c.~21~ --- ufs/sizes.c | 134 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 50 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index a349eb40..11efc2b8 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -20,8 +20,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Written by Michael I. Bushnell. */ #include "ufs.h" -#include "fs.h" -#include "dinode.h" #include #ifdef DONT_CACHE_MEMORY_OBJECTS @@ -30,6 +28,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define MAY_CACHE 1 #endif +static int free_indir (struct node *np, daddr_t bno, int level); +static void poke_pages (memory_object_t, vm_offset_t, vm_offset_t); /* Implement the diskfs_truncate callback; sse for the interface description. */ @@ -41,7 +41,10 @@ diskfs_truncate (struct node *np, daddr_t lastiblock[NIADDR], lastblock, bn; struct dinode *di = dino (np->dn->number); int blocksfreed = 0; - + error_t err; + int level; + int i; + if (length >= np->dn_stat.st_size) return 0; @@ -72,13 +75,14 @@ diskfs_truncate (struct node *np, int savesize = np->allocsize; np->allocsize = length; /* temporary */ - bsize = blksize (sblock, np, lbkno (sblock, length)); + bsize = blksize (sblock, np, lblkno (sblock, length)); np->allocsize = savesize; - diskfs_node_rdwr (np, zeroblock, length, bsize - offset, 1, 0, 0); + diskfs_node_rdwr (np, (void *) zeroblock, length, + bsize - offset, 1, 0, 0); diskfs_file_update (np, 1); } - rwlock_writer_lock (&np->allocptrlock); + rwlock_writer_lock (&np->dn->allocptrlock); /* Now flush all the data past the new size from the kernel. Also force any delayed copies of this data to take place @@ -87,6 +91,8 @@ diskfs_truncate (struct node *np, this forces us to help out the kernel thusly.) */ if (np->dn->fileinfo) { + mach_port_t obj; + pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np); @@ -94,23 +100,20 @@ diskfs_truncate (struct node *np, MACH_MSG_TYPE_MAKE_SEND); poke_pages (obj, round_page (length), round_page (np->allocsize)); mach_port_deallocate (mach_task_self (), obj); - pager_flush_some (np->fileinfo->p, round_page (length), + pager_flush_some (np->dn->fileinfo->p, round_page (length), np->allocsize - length, 1); } /* Calculate index into node's block list of direct and indirect blocks which we want to keep. Lastblock is -1 when the file is truncated to 0. */ - lastblock = lblkno (sblock, length + sblock->fs_bsize - 1) - 1; + lastblock = lblkno (sblock, length - 1); lastiblock[INDIR_SINGLE] = lastblock - NDADDR; lastiblock[INDIR_DOUBLE] = lastiblock[INDIR_SINGLE] - NINDIR (sblock); lastiblock[INDIR_TRIPLE] = (lastiblock[INDIR_DOUBLE] - NINDIR (sblock) * NINDIR (sblock)); - /* Normalize to -1 indicating that this block will not be needed. */ - for (level = INDIR_TRIPLE; level >= INDIR_SINGLE; level--) - if (lastiblock[level] < 0) - lastiblock[level] = -1; + /* lastiblock will now be negative for elements that we should free. */ /* Update the size on disk; fsck will finish freeing blocks if necessary should we crash. */ @@ -124,13 +127,13 @@ diskfs_truncate (struct node *np, err = diskfs_catch_exception (); if (err) { - rwlock_writer_unlock (&np->allocptrlock); + rwlock_writer_unlock (&np->dn->allocptrlock); return err; } /* Indirect blocks first. */ for (level = INDIR_TRIPLE; level >= INDIR_SINGLE; level--) - if (lastiblock[level] == -1 && di->di_ib[level]) + if (lastiblock[level] < 0 && di->di_ib[level]) { int count; count = free_indir (np, di->di_ib[level], level); @@ -143,27 +146,27 @@ diskfs_truncate (struct node *np, { long bsize; - bn = dn->di_db[i]; + bn = di->di_db[i]; if (bn == 0) continue; bsize = blksize (sblock, np, i); - ffs_blkfree (sblock, bn, bsize); + ffs_blkfree (np, bn, bsize); blocksfreed += btodb (bsize); - dn->di_db[i] = 0; + di->di_db[i] = 0; } /* Finally, check to see if the new last direct block is changing size; if so release any frags necessary. */ if (lastblock >= 0 - && dn->di_db[lastblock]) + && di->di_db[lastblock]) { - bn = dn->di_db[lastblock]; long oldspace, newspace; + bn = di->di_db[lastblock]; oldspace = blksize (sblock, np, lastblock); - np->allocsize = length; + np->allocsize = fragroundup (sblock, length); newspace = blksize (sblock, np, lastblock); assert (newspace); @@ -172,18 +175,18 @@ diskfs_truncate (struct node *np, { bn += numfrags (sblock, newspace); ffs_blkfree (np, bn, oldspace - newspace); - blocksfreed += btodb (oldspace - newspace) + blocksfreed += btodb (oldspace - newspace); } } else - np->allocsize = length; + np->allocsize = fragroundup (sblock, length); diskfs_end_catch_exception (); np->dn_set_ctime = 1; diskfs_node_update (np, 1); - rwlock_writer_unlock (&np->allocptrlock); + rwlock_writer_unlock (&np->dn->allocptrlock); /* Now we can permit delayed copies again. */ if (np->dn->fileinfo) @@ -202,7 +205,7 @@ free_indir (struct node *np, daddr_t bno, int level) int count = 0; daddr_t *addrs; int i; - struct indir_dirty *d, *prev, *nxt; + struct dirty_indir *d, *prev, *next; assert (bno); @@ -216,7 +219,7 @@ free_indir (struct node *np, daddr_t bno, int level) count += btodb (sblock->fs_bsize); } else - count += free_indir (addrs[i], level - 1); + count += free_indir (np, addrs[i], level - 1); } /* Subtlety: this block is no longer necessary; the information @@ -227,12 +230,12 @@ free_indir (struct node *np, daddr_t bno, int level) the block from the kernel's memory, making sure we do it synchronously--and BEFORE we attach it to the free list with ffs_blkfree. */ - pager_flush_some (diskpager->p, fsaddr (bno), sblock->fs_bsize, 1); + pager_flush_some (diskpager->p, fsaddr (sblock, bno), sblock->fs_bsize, 1); /* We should also take this block off the inode's list of dirty indirect blocks if it's there. */ prev = 0; - d = np->dirty; + d = np->dn->dirty; while (d) { next = d->next; @@ -241,7 +244,7 @@ free_indir (struct node *np, daddr_t bno, int level) if (prev) prev->next = next; else - np->dirty = next; + np->dn->dirty = next; free (d); } else @@ -292,7 +295,7 @@ diskfs_grow (struct node *np, assert (!diskfs_readonly); /* The new last block of the file. */ - lbn = lblkno (sblock, end + sblock->fs_bsize - 1) - 1; + lbn = lblkno (sblock, end - 1); /* This is the size of that block if it is in the NDADDR array. */ size = fragroundup (sblock, blkoff (sblock, end)); @@ -302,7 +305,7 @@ diskfs_grow (struct node *np, rwlock_writer_lock (&np->dn->allocptrlock); /* The old last block of the file. */ - olbn = lbkno (sblock, np->allocsize + sblock->fs_bsize - 1) - 1; + olbn = lblkno (sblock, np->allocsize - 1); /* This is the size of that block if it is in the NDADDR array. */ osize = fragroundup (sblock, blkoff (sblock, np->allocsize)); @@ -315,24 +318,24 @@ diskfs_grow (struct node *np, { if (osize < sblock->fs_bsize) { - daddr_t olb_pbn, bno; - err = ffs_realloccg (np, nb, + daddr_t old_pbn, bno; + err = ffs_realloccg (np, olbn, ffs_blkpref (np, lbn, lbn, di->di_db), osize, sblock->fs_bsize, &bno, cred); if (err) goto out; - old_pbn = di->di_db - di->di_db[nb] = bno; + old_pbn = di->di_db[olbn]; + di->di_db[olbn] = bno; np->dn_set_ctime = 1; - dev_write_sync (fsbtodb (bno) + btodb (osize), + dev_write_sync (fsbtodb (sblock, bno) + btodb (osize), zeroblock, sblock->fs_bsize - osize); - if (pbn != old_pbn) + if (bno != old_pbn) { /* Make sure the old contents get written out to the new address by poking the pages. */ - poke_off = nb * sblock->fs_bsize; + poke_off = olbn * sblock->fs_bsize; poke_len = osize; } } @@ -357,12 +360,12 @@ diskfs_grow (struct node *np, goto out; di->di_db[lbn] = bno; - np->dn_sat_ctime = 1; + np->dn_set_ctime = 1; - dev_write_sync (fsbtodb (bno) + btodb (osize), + dev_write_sync (fsbtodb (sblock, bno) + btodb (osize), zeroblock, size - osize); - if (pbn != old_pbn) + if (bno != old_pbn) { assert (!poke_len); @@ -381,17 +384,17 @@ diskfs_grow (struct node *np, if (err) goto out; - di->di_db[lbn] = pbn; + di->di_db[lbn] = bno; np->dn_set_ctime = 1; - dev_write_sync (fsbtodb (bno), zeroblock, size); + dev_write_sync (fsbtodb (sblock, bno), zeroblock, size); } } else { - struct iblock_spec indirs[NINDIR + 1]; - int i; + struct iblock_spec indirs[NIADDR + 1]; daddr_t *siblock; + daddr_t bno; /* Count the number of levels of indirection. */ err = fetch_indir_spec (np, lbn, indirs); @@ -435,7 +438,7 @@ diskfs_grow (struct node *np, /* This assert because triple indirection is not supported. */ assert (indirs[2].offset == -1); - err = ffs_alloc (np, lbn + err = ffs_alloc (np, lbn, ffs_blkpref (np, lbn, INDIR_DOUBLE, di->di_ib), sblock->fs_bsize, &bno, 0); @@ -446,7 +449,7 @@ diskfs_grow (struct node *np, } diblock = indir_block (indirs[2].bno); - mark_indir_dirty (indirs[2].bno); + mark_indir_dirty (np, indirs[2].bno); /* Now we can allocate the single indirect block */ err = ffs_alloc (np, lbn, @@ -466,11 +469,11 @@ diskfs_grow (struct node *np, /* Now we can allocate the data block. */ err = ffs_alloc (np, lbn, ffs_blkpref (np, lbn, indirs[0].offset, siblock), - sblock->fn_bsize, &bno, 0); + sblock->fs_bsize, &bno, 0); if (err) goto out; indirs[0].bno = siblock[indirs[0].offset] = bno; - dev_write_sync (fsbtodb (bno), zeroblock, sblock->fs_bsize); + dev_write_sync (fsbtodb (sblock, bno), zeroblock, sblock->fs_bsize); } out: @@ -485,7 +488,7 @@ diskfs_grow (struct node *np, np->allocsize = newallocsize; } - rwlock_writer_unlock (&np->allocptrlock); + rwlock_writer_unlock (&np->dn->allocptrlock); /* If we expanded a fragment, then POKE_LEN will be set. We need to poke the requested amount of the memory object @@ -493,8 +496,10 @@ diskfs_grow (struct node *np, at a suitable time. */ if (poke_len) { + mach_port_t obj; + obj = diskfs_get_filemap (np); - mach_port_insert_reght (mach_task_self (), obj, obj, + mach_port_insert_right (mach_task_self (), obj, obj, MACH_MSG_TYPE_MAKE_SEND); poke_pages (obj, trunc_page (poke_off), round_page (poke_off + poke_len)); @@ -504,3 +509,32 @@ diskfs_grow (struct node *np, return err; } +/* Write something to each page from START to END inclusive of memory + object OBJ, but make sure the data doesns't actually change. */ +static void +poke_pages (memory_object_t obj, + vm_offset_t start, + vm_offset_t end) +{ + vm_address_t addr, poke; + vm_size_t len; + error_t err; + + while (start < end) + { + len = 8 * vm_page_size; + if (len > end - start) + len = end - start; + addr = 0; + err = vm_map (mach_task_self (), &addr, len, 0, 1, obj, start, 0, + VM_PROT_WRITE|VM_PROT_READ, VM_PROT_READ|VM_PROT_WRITE, 0); + if (!err) + { + for (poke = addr; poke < addr + len; poke += vm_page_size) + *(volatile int *)poke = *(volatile int *)poke; + vm_deallocate (mach_task_self (), addr, len); + } + start += len; + } +} + -- cgit v1.2.3 From c8ee2836ff8d5eda9d3976a9ee4ca36df19f3283 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:52:30 +0000 Subject: Formerly pager.c.~38~ --- ufs/pager.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index e4abf85d..b5a98e79 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -16,7 +16,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" -#include "dinode.h" #include #include @@ -80,7 +79,7 @@ find_address (struct user_pager_info *upi, { if (indirs[0].bno) *addr = (fsbtodb (sblock, indirs[0].bno) - + blkoff (sblkoc, offset) / DEV_BSIZE); + + blkoff (sblock, offset) / DEV_BSIZE); else *addr = 0; } @@ -172,6 +171,7 @@ pager_unlock_page (struct user_pager_info *pager, struct iblock_spec indirs[NIADDR + 1]; daddr_t bno; struct disknode *dn; + struct dinode *di; /* Zero an sblock->fs_bsize piece of disk starting at BNO, synchronously. We do this on newly allocated indirect @@ -193,6 +193,7 @@ pager_unlock_page (struct user_pager_info *pager, np = pager->np; dn = np->dn; + di = dino (dn->number); rwlock_writer_lock (&dn->allocptrlock); @@ -276,7 +277,7 @@ pager_unlock_page (struct user_pager_info *pager, } diblock = indir_block (indirs[2].bno); - mark_indir_dirty (indirs[2].bno); + mark_indir_dirty (np, indirs[2].bno); /* Now we can allocate the single indirect block */ @@ -303,7 +304,7 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; - dev_write_sync (fsbtodb (bno), zeroblock, sblock->fs_bsize); + dev_write_sync (fsbtodb (sblock, bno), zeroblock, sblock->fs_bsize); indirs[0].bno = siblock[indirs[0].offset] = bno; } @@ -311,7 +312,7 @@ pager_unlock_page (struct user_pager_info *pager, out: diskfs_end_catch_exception (); - rwlock_writer_unlock (&np->dn->datalock, np->dn); + rwlock_writer_unlock (&dn->allocptrlock); return err; } @@ -356,8 +357,8 @@ create_disk_pager () diskpager = malloc (sizeof (struct user_pager_info)); diskpager->type = DISK; diskpager->np = 0; - diskpager->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); - diskpagerport = pager_get_port (upi->p); + diskpager->p = pager_create (diskpager, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); + diskpagerport = pager_get_port (diskpager->p); mach_port_insert_right (mach_task_self (), diskpagerport, diskpagerport, MACH_MSG_TYPE_MAKE_SEND); } @@ -368,7 +369,7 @@ void diskfs_file_update (struct node *np, int wait) { - struct indir_dirty *d, *tmp; + struct dirty_indir *d, *tmp; if (np->dn->fileinfo) pager_sync (np->dn->fileinfo->p, wait); @@ -406,7 +407,7 @@ diskfs_get_filemap (struct node *np) diskfs_nref_light (np); upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); np->dn->fileinfo = upi; - ports_port_ref (p); + ports_port_ref (upi->p); spin_lock (&pagerlistlock); upi->next = filepagerlist; @@ -417,7 +418,6 @@ diskfs_get_filemap (struct node *np) spin_unlock (&pagerlistlock); } right = pager_get_port (np->dn->fileinfo->p); - mutex_unlock (&pagernplock); mach_port_insert_right (mach_task_self (), right, right, MACH_MSG_TYPE_MAKE_SEND); @@ -465,7 +465,7 @@ pager_traverse (void (*func)(struct user_pager_info *)) struct item *i; spin_lock (&pagerlistlock); - for (p = filepagerlit; p; p = p->next) + for (p = filepagerlist; p; p = p->next) { i = alloca (sizeof (struct item)); i->next = list; -- cgit v1.2.3 From e54bb543df6526896794b97f367cdd1d4569c694 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:52:31 +0000 Subject: Formerly inode.c.~41~ --- ufs/inode.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 3edb697f..91963c16 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -16,7 +16,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" -#include "dinode.h" #include #include #include @@ -156,6 +155,8 @@ void diskfs_lost_hardrefs (struct node *np) { struct port_info *pi; + struct pager *p; + /* Check and see if there is a pager which has only one reference (ours). If so, then drop that reference, breaking the cycle. The complexity in this routine @@ -164,7 +165,7 @@ diskfs_lost_hardrefs (struct node *np) if (np->dn->fileinfo) { spin_lock (&_libports_portrefcntlock); - pi = np->dn->fileinfo->p; + pi = (struct port_info *) np->dn->fileinfo->p; if (pi->refcnt == 1) { @@ -500,25 +501,26 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, error_t diskfs_get_translator (struct node *np, char **namep, u_int *namelen) { - XXX FIXME error_t err; daddr_t blkno; - char *buf; u_int datalen; + void *transloc; err = diskfs_catch_exception (); if (err) return err; + blkno = (dino (np->dn->number))->di_trans; - assert (blkno); - bcopy (disk_image + fsaddr (sblock, blkno), buf, sblock->fs_bsize); - diskfs_end_catch_exception (); + transloc = disk_image + fsaddr (sblock, blkno); - datalen = *(u_int *)buf; + datalen = *(u_int *)transloc; if (datalen > *namelen) vm_allocate (mach_task_self (), (vm_address_t *) namep, datalen, 1); - bcopy (buf + sizeof (u_int), *namep, datalen); + bcopy (transloc + sizeof (u_int), *namep, datalen); + + diskfs_end_catch_exception (); + *namelen = datalen; return 0; } -- cgit v1.2.3 From c7a908bb80c55dcdfae4f13dd945d6b95441e0c1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:52:32 +0000 Subject: entered into RCS --- ufs/consts.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ufs') diff --git a/ufs/consts.c b/ufs/consts.c index 0004230f..2062a07f 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -16,7 +16,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" -#include "dinode.h" int diskfs_link_max = LINK_MAX; int diskfs_maxsymlinks = 8; -- cgit v1.2.3 From ab87c35f13c27216d1e6e5c9c47afdc6a394b6e7 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 02:52:34 +0000 Subject: Formerly hyper.c.~14~ --- ufs/hyper.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index a5d05bc8..e73f78b8 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -16,7 +16,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" -#include "dinode.h" #include #include -- cgit v1.2.3 From a291563796dc0e60b318dd2e7aea61e55a7320c5 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 15:58:12 +0000 Subject: Formerly bmap.c.~5~ --- ufs/bmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/bmap.c b/ufs/bmap.c index 18c53662..e43a648c 100644 --- a/ufs/bmap.c +++ b/ufs/bmap.c @@ -76,7 +76,7 @@ fetch_indir_spec (struct node *np, volatile daddr_t lbn, else { indirs[1].offset = -1; - indirs[1].bno = di->di_ib[INDIR_DOUBLE]; + indirs[1].bno = di->di_ib[INDIR_SINGLE]; } if (indirs[1].bno) -- cgit v1.2.3 From c427330289e857525ac44e0f428343868bba405e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Sep 1994 19:24:51 +0000 Subject: Formerly sizes.c.~22~ --- ufs/sizes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 11efc2b8..0f0fd427 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -481,9 +481,9 @@ diskfs_grow (struct node *np, { int newallocsize; if (lbn < NDADDR) - newallocsize = (lbn - 1) * sblock->fs_bsize + size; + newallocsize = lbn * sblock->fs_bsize + size; else - newallocsize = lbn * sblock->fs_bsize; + newallocsize = (lbn + 1) * sblock->fs_bsize; assert (newallocsize > np->allocsize); np->allocsize = newallocsize; } -- cgit v1.2.3 From 0ee74b5b66d79eba411f8fc57545a1140b0bd799 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 29 Sep 1994 22:17:57 +0000 Subject: Formerly main.c.~23~ --- ufs/main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 5f41265b..65da85bb 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -23,6 +23,7 @@ #include #include #include +#include char *ufs_version = "0.0 pre-alpha"; @@ -102,10 +103,10 @@ main (int argc, char **argv) mutex_init (&printf_lock); /* XXX */ - task_get_bootstrap_port (mach_task_self (), &bootstrap); - - if (bootstrap) + if (getpid () > 0) { + /* We are in a normal Hurd universe, started as a translator. */ + devname = trans_parse_args (argc, argv); { @@ -120,10 +121,13 @@ main (int argc, char **argv) } else { + /* We are the bootstrap filesystem. */ devname = diskfs_parse_bootargs (argc, argv); compat_mode = COMPAT_GNU; } + task_get_bootstrap_port (mach_task_self (), &bootstrap); + /* Initialize the diskfs library. This must come before any other diskfs call. */ diskfs_init_diskfs (); -- cgit v1.2.3 From 661267c4ad4f5724340d5167d2b25f3e26547fb3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 30 Sep 1994 15:25:32 +0000 Subject: Formerly dir.c.~29~ --- ufs/dir.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index e4d54cdf..2f215974 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -858,9 +858,7 @@ diskfs_get_directs (struct node *dp, userp->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); userp->d_namlen = DIRECT_NAMLEN (entryp); bcopy (entryp->d_name, userp->d_name, DIRECT_NAMLEN (entryp) + 1); -#ifdef notyet - userp->d_type = entryp->d_type; -#endif + userp->d_type = DT_UNKNOWN; /* until fixed */ i++; datap += DIRSIZ (DIRECT_NAMLEN (entryp)); } -- cgit v1.2.3 From 02e17dd72bc35481855708a6184d083aa324129a Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 30 Sep 1994 15:27:08 +0000 Subject: entered into RCS --- ufs/dir.h | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.h b/ufs/dir.h index c6535342..193e167b 100644 --- a/ufs/dir.h +++ b/ufs/dir.h @@ -83,24 +83,6 @@ struct directory_entry { char d_name[MAXNAMLEN + 1]; /* name with length <= MAXNAMLEN */ }; -/* - * File types - */ -#define DT_UNKNOWN 0 -#define DT_FIFO 1 -#define DT_CHR 2 -#define DT_DIR 4 -#define DT_BLK 6 -#define DT_REG 8 -#define DT_LNK 10 -#define DT_SOCK 12 - -/* - * Convert between stat structure types and directory types. - */ -#define IFTODT(mode) (((mode) & 0170000) >> 12) -#define DTTOIF(dirtype) ((dirtype) << 12) - /* Return the type from a struct directory_entry, paying attention to whether this filesystem supports the type extension */ #define DIRECT_TYPE(dp) (direct_symlink_extension ? (dp)->d_type : DT_UNKNOWN) -- cgit v1.2.3 From 8ed965f0767037b11167315ae43c879061d55d4b Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 3 Oct 1994 18:51:49 +0000 Subject: Initial revision --- ufs/mapbuf.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 ufs/mapbuf.c (limited to 'ufs') diff --git a/ufs/mapbuf.c b/ufs/mapbuf.c new file mode 100644 index 00000000..a323bdbc --- /dev/null +++ b/ufs/mapbuf.c @@ -0,0 +1,33 @@ +/* Cache mappings of the disk + Copyright (C) 1994 Free Software Foundation, Inc. + Written by Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +#include "ufs.h" + +#define MAXMAPMEM (1024 * 1024 * 1024) /* one Gb */ + +struct mapbuf +{ + vm_size_t length; + vm_offset_t diskaddr; +}; + +void * +map_region -- cgit v1.2.3 From 05a19cf1799badd6446ac0524c649b5572f2f349 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 3 Oct 1994 18:54:58 +0000 Subject: entered into RCS --- ufs/mapbuf.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/mapbuf.c b/ufs/mapbuf.c index a323bdbc..edf432a5 100644 --- a/ufs/mapbuf.c +++ b/ufs/mapbuf.c @@ -21,13 +21,16 @@ #include "ufs.h" -#define MAXMAPMEM (1024 * 1024 * 1024) /* one Gb */ +struct mapbuf *mblist; +spin_lock_t mblistlock = SPIN_LOCK_INITIALIZER; -struct mapbuf +struct mapbuf * +map_region (vm_offset_t diskloc, vm_size_t length) { - vm_size_t length; - vm_offset_t diskaddr; -}; + struct mapbuf *mb; + + /* Check to see if we are already mapping this region */ + spin_lock (&mblistlock); + for (mb = mblist; mb; mb = mb->next) + { -void * -map_region -- cgit v1.2.3 From d97f48fc688d937e7f2ae68098789dbb7d9256bf Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 3 Oct 1994 19:03:08 +0000 Subject: Initial revision --- ufs/pokeloc.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 ufs/pokeloc.c (limited to 'ufs') diff --git a/ufs/pokeloc.c b/ufs/pokeloc.c new file mode 100644 index 00000000..bf3c9add --- /dev/null +++ b/ufs/pokeloc.c @@ -0,0 +1,63 @@ +/* Remember where we've written the disk to speed up sync + Copyright (C) 1994 Free Software Foundation, Inc. + Written by Michael I. Bushnell. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "ufs.h" + +struct pokeloc +{ + vm_offset_t offset; + vm_size_t length; + struct pokeloc *next; +}; + +struct pokeloc *pokelist; +spin_lock_t pokelistlock = SPIN_LOCK_INITIAILIZER; + +/* Remember that data here on the disk has been modified. */ +void +record_poke (vm_offset_t offset, vm_size_t length) +{ + struct pokeloc *pl = malloc (sizeof (struct pokeloc)); + pl->offset = trunc_page (offset); + pl->length = round_page (offset + length) - pl->offset; + + spin_lock (&pokelistlock); + pl->next = pokelist; + pokelist = pl; + spin_unlock (&pokelistlock); +} + +/* Sync all the modified pieces of disk */ +void +sync_disk (int wait) +{ + struct pokeloc *pl, *tmp; + + spin_lock (&pokelistlock); + for (pl = pokelist; pl; pl = tmp) + { + pager_sync_some (diskpager->p, pl->offset, pl->length, wait); + tmp = pl->next; + free (pl); + } + pokelist = 0; + spin_unlock (&pokelistlock); +} + -- cgit v1.2.3 From 8af736c549ec9d5eb69487f41222950d6f366193 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 3 Oct 1994 19:06:29 +0000 Subject: Formerly pokeloc.c.~2~ --- ufs/pokeloc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/pokeloc.c b/ufs/pokeloc.c index bf3c9add..cc1f364c 100644 --- a/ufs/pokeloc.c +++ b/ufs/pokeloc.c @@ -32,9 +32,12 @@ spin_lock_t pokelistlock = SPIN_LOCK_INITIAILIZER; /* Remember that data here on the disk has been modified. */ void -record_poke (vm_offset_t offset, vm_size_t length) +record_poke (void *loc, vm_size_t length) { struct pokeloc *pl = malloc (sizeof (struct pokeloc)); + vm_offset_t offset; + + offset = loc - disk_image; pl->offset = trunc_page (offset); pl->length = round_page (offset + length) - pl->offset; -- cgit v1.2.3 From 0ae2901ce73d17da45be0af289dc4b50b0d207e8 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 3 Oct 1994 19:06:38 +0000 Subject: Formerly ufs.h.~27~ --- ufs/ufs.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 6d706100..20f67203 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -292,3 +292,7 @@ void ffs_clrblock(struct fs *, u_char *, daddr_t); void ffs_setblock (struct fs *, u_char *, daddr_t); int skpc (int, int, char *); int scanc (u_int, u_char *, u_char [], int); + +/* From pokeloc.c: */ +void record_poke (void *, vm_size_t); +void sync_disk (int); -- cgit v1.2.3 From 820bedd006fb925b4043f60b5809e9441e79031b Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 3 Oct 1994 19:09:11 +0000 Subject: Formerly inode.c.~42~ --- ufs/inode.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 91963c16..ba720b48 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -333,6 +333,7 @@ write_node (struct node *np) diskfs_end_catch_exception (); np->dn_stat_dirty = 0; + record_poke (di, sizeof (struct dinode)); } } @@ -344,6 +345,7 @@ create_symlink_hook (struct node *np, char *target) { int len = strlen (target); error_t err; + struct dinode *di; if (!direct_symlink_extension) return EINVAL; @@ -357,10 +359,12 @@ create_symlink_hook (struct node *np, char *target) if (err) return err; - bcopy (target, (dino (np->dn->number))->di_shortlink, len); + di = dino (np->dn->number); + bcopy (target, di->di_shortlink, len); np->dn_stat.st_size = len; np->dn_set_ctime = 1; np->dn_set_mtime = 1; + record_poke (di, sizeof (struct dinode)); diskfs_end_catch_exception (); return 0; @@ -446,7 +450,8 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, daddr_t blkno; error_t err; char buf[sblock->fs_bsize]; - + struct dinode *di; + if (compat_mode != COMPAT_GNU) return EOPNOTSUPP; @@ -457,7 +462,8 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, if (err) return err; - blkno = (dino (np->dn->number))->di_trans; + di = dino (np->dn->number); + blkno = di->di_trans; if (namelen && !blkno) { @@ -468,14 +474,16 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, diskfs_end_catch_exception (); return err; } - (dino (np->dn->number))->di_trans = blkno; + di->di_trans = blkno; + record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; } else if (!namelen && blkno) { /* Clear block for translator going away. */ ffs_blkfree (np, blkno, sblock->fs_bsize); - (dino (np->dn->number))->di_trans = 0; + di->di_trans = 0; + record_poke (di, sizeof (struct dinode)); np->istranslated = 0; np->dn_set_ctime = 1; } -- cgit v1.2.3 From e7c7fde09edf3a831daedd42afab061502b59871 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 3 Oct 1994 21:15:48 +0000 Subject: entered into RCS --- ufs/bmap.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/bmap.c b/ufs/bmap.c index e43a648c..0b3574b8 100644 --- a/ufs/bmap.c +++ b/ufs/bmap.c @@ -35,10 +35,18 @@ fetch_indir_spec (struct node *np, volatile daddr_t lbn, if (err = diskfs_catch_exception ()) return err; + indirs[0].offset = -2; + indirs[1].offset = -2; + indirs[2].offset = -2; + indirs[3].offset = -2; + if (lbn < NDADDR) { - indirs[0].bno = di->di_db[lbn]; - indirs[0].offset = -1; + if (lbn >= 0) + { + indirs[0].bno = di->di_db[lbn]; + indirs[0].offset = -1; + } diskfs_end_catch_exception (); return 0; -- cgit v1.2.3 From b6bff823d8d4504af1ec6521e6a25f752ecc8fdf Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 3 Oct 1994 21:18:00 +0000 Subject: Formerly sizes.c.~23~ --- ufs/sizes.c | 181 ++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 126 insertions(+), 55 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 0f0fd427..8f6174af 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -28,7 +28,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define MAY_CACHE 1 #endif -static int free_indir (struct node *np, daddr_t bno, int level); +static int indir_release (struct node *np, daddr_t bno, int level); static void poke_pages (memory_object_t, vm_offset_t, vm_offset_t); /* Implement the diskfs_truncate callback; sse for the @@ -38,12 +38,12 @@ diskfs_truncate (struct node *np, off_t length) { int offset; - daddr_t lastiblock[NIADDR], lastblock, bn; struct dinode *di = dino (np->dn->number); int blocksfreed = 0; error_t err; - int level; int i; + struct iblock_spec indirs[NIADDR + 1]; + daddr_t lbn; if (length >= np->dn_stat.st_size) return 0; @@ -104,17 +104,6 @@ diskfs_truncate (struct node *np, np->allocsize - length, 1); } - /* Calculate index into node's block list of direct - and indirect blocks which we want to keep. Lastblock - is -1 when the file is truncated to 0. */ - lastblock = lblkno (sblock, length - 1); - lastiblock[INDIR_SINGLE] = lastblock - NDADDR; - lastiblock[INDIR_DOUBLE] = lastiblock[INDIR_SINGLE] - NINDIR (sblock); - lastiblock[INDIR_TRIPLE] = (lastiblock[INDIR_DOUBLE] - - NINDIR (sblock) * NINDIR (sblock)); - - /* lastiblock will now be negative for elements that we should free. */ - /* Update the size on disk; fsck will finish freeing blocks if necessary should we crash. */ np->dn_stat.st_size = length; @@ -122,52 +111,98 @@ diskfs_truncate (struct node *np, np->dn_set_ctime = 1; diskfs_node_update (np, 1); - /* Free the blocks. */ + /* Find out the location information for the last block to + be retained */ + lbn = lblkno (sblock, length - 1); + err = fetch_indir_spec (np, lbn, indirs); + /* err XXX */ + + /* We don't support triple indirs */ + assert (indirs[0].offset == -1 + || indirs[1].offset == -1 + || indirs[2].offset == -1); + + /* BSD carefully finds out how far to clear; it's vastly simpler + to just clear everything after the new last block. */ - err = diskfs_catch_exception (); - if (err) + /* Free direct blocks */ + if (indirs[0].offset < 0) { - rwlock_writer_unlock (&np->dn->allocptrlock); - return err; + /* ...mapped from the inode. */ + for (i = lbn + 1; i < NDADDR; i++) + if (di->di_db[i]) + { + long bsize = blksize (sblock, np, i); + ffs_blkfree (np, di->di_db[i], bsize); + di->di_db[i] = 0; + blocksfreed += btodb (bsize); + } } - - /* Indirect blocks first. */ - for (level = INDIR_TRIPLE; level >= INDIR_SINGLE; level--) - if (lastiblock[level] < 0 && di->di_ib[level]) - { - int count; - count = free_indir (np, di->di_ib[level], level); - blocksfreed += count; - di->di_ib[level] = 0; - } - - /* Whole direct blocks or frags */ - for (i = NDADDR - 1; i > lastblock; i--) + else { - long bsize; - - bn = di->di_db[i]; - if (bn == 0) - continue; - - bsize = blksize (sblock, np, i); - ffs_blkfree (np, bn, bsize); - blocksfreed += btodb (bsize); - - di->di_db[i] = 0; + /* ... or mapped from sindir */ + if (indirs[1].bno) + { + daddr_t *sindir = indir_block (indirs[1].bno); + for (i = indirs[0].offset + 1; i < NINDIR (sblock); i++) + { + ffs_blkfree (np, sindir[i], sblock->fs_bsize); + sindir[i] = 0; + blocksfreed += btodb (sblock->fs_bsize); + } + record_poke (sindir, sblock->fs_bsize); + } } - + + /* Free single indirect blocks */ + if (indirs[1].offset < 0) + { + /* ...mapped from the inode */ + if (di->di_ib[INDIR_SINGLE] && indirs[1].offset == -2) + { + blocksfreed += indir_release (np, di->di_ib[INDIR_SINGLE], + INDIR_SINGLE); + di->di_ib[INDIR_SINGLE] = 0; + } + } + else + { + /* ...or mapped from dindir */ + if (indirs[2].bno) + { + daddr_t *dindir = indir_block (indirs[2].bno); + for (i = indirs[1].offset + 1; i < NINDIR (sblock); i++) + { + blocksfreed += indir_release (np, dindir[i], INDIR_SINGLE); + dindir[i] = 0; + } + record_poke (dindir, sblock->fs_bsize); + } + } + + /* Free double indirect block */ + assert (indirs[2].offset < 0); /* which must be mapped from the inode */ + if (indirs[2].offset == -2) + { + if (di->di_ib[INDIR_DOUBLE]) + { + blocksfreed += indir_release (np, di->di_ib[INDIR_DOUBLE], + INDIR_DOUBLE); + di->di_ib[INDIR_DOUBLE] = 0; + } + } + /* Finally, check to see if the new last direct block is changing size; if so release any frags necessary. */ - if (lastblock >= 0 - && di->di_db[lastblock]) + if (lbn >= 0 && lbn < NDADDR && di->di_db[lbn]) { long oldspace, newspace; + daddr_t bn; - bn = di->di_db[lastblock]; - oldspace = blksize (sblock, np, lastblock); + bn = di->di_db[lbn]; + oldspace = blksize (sblock, np, lbn); np->allocsize = fragroundup (sblock, length); - newspace = blksize (sblock, np, lastblock); + newspace = blksize (sblock, np, lbn); assert (newspace); @@ -179,28 +214,56 @@ diskfs_truncate (struct node *np, } } else - np->allocsize = fragroundup (sblock, length); - - diskfs_end_catch_exception (); + { + if (lbn > NDADDR) + np->allocsize = blkroundup (sblock, length); + else + np->allocsize = fragroundup (sblock, length); + } + + record_poke (di, sizeof (struct dinode)); + np->dn_stat.st_blocks -= blocksfreed; np->dn_set_ctime = 1; diskfs_node_update (np, 1); rwlock_writer_unlock (&np->dn->allocptrlock); + /* At this point the last block (as defined by np->allocsize) + might not be allocated. We need to allocate it to maintain + the rule that the last block of a file is always allocated. */ + + if (np->allocsize && indirs[0].bno == 0) + { + /* The strategy is to reduce LBN until we get one that's allocated; + then reduce allocsize accordingly, then call diskfs_grow. */ + + do + err = fetch_indir_spec (np, --lbn, indirs); + /* err XXX */ + while (indirs[0].bno == 0 && lbn >= 0); + + assert ((lbn + 1) * sblock->fs_bsize < np->allocsize); + np->allocsize = (lbn + 1) * sblock->fs_bsize; + + diskfs_grow (np, length, 0); + } + + diskfs_end_catch_exception (); + /* Now we can permit delayed copies again. */ if (np->dn->fileinfo) pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY, 0); - return 0; + return err; } /* Free indirect block BNO of level LEVEL; recursing if necessary to free other indirect blocks. Return the number of disk blocks freed. */ static int -free_indir (struct node *np, daddr_t bno, int level) +indir_release (struct node *np, daddr_t bno, int level) { int count = 0; daddr_t *addrs; @@ -219,7 +282,7 @@ free_indir (struct node *np, daddr_t bno, int level) count += btodb (sblock->fs_bsize); } else - count += free_indir (np, addrs[i], level - 1); + count += indir_release (np, addrs[i], level - 1); } /* Subtlety: this block is no longer necessary; the information @@ -263,6 +326,7 @@ free_indir (struct node *np, daddr_t bno, int level) } + /* Implement the diskfs_grow callback; see for the interface description. */ @@ -326,6 +390,7 @@ diskfs_grow (struct node *np, goto out; old_pbn = di->di_db[olbn]; di->di_db[olbn] = bno; + record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; dev_write_sync (fsbtodb (sblock, bno) + btodb (osize), @@ -360,6 +425,7 @@ diskfs_grow (struct node *np, goto out; di->di_db[lbn] = bno; + record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; dev_write_sync (fsbtodb (sblock, bno) + btodb (osize), @@ -385,6 +451,7 @@ diskfs_grow (struct node *np, goto out; di->di_db[lbn] = bno; + record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; dev_write_sync (fsbtodb (sblock, bno), zeroblock, size); @@ -426,6 +493,7 @@ diskfs_grow (struct node *np, goto out; zero_disk_block (bno); indirs[1].bno = di->di_ib[INDIR_SINGLE] = bno; + record_poke (di, sizeof (struct dinode)); } else { @@ -446,6 +514,7 @@ diskfs_grow (struct node *np, goto out; zero_disk_block (bno); indirs[2].bno = di->di_ib[INDIR_DOUBLE] = bno; + record_poke (di, sizeof (struct dinode)); } diblock = indir_block (indirs[2].bno); @@ -460,6 +529,7 @@ diskfs_grow (struct node *np, goto out; zero_disk_block (bno); indirs[1].bno = diblock[indirs[1].offset] = bno; + record_poke (diblock, sblock->fs_bsize); } } @@ -473,6 +543,7 @@ diskfs_grow (struct node *np, if (err) goto out; indirs[0].bno = siblock[indirs[0].offset] = bno; + record_poke (siblock, sblock->fs_bsize); dev_write_sync (fsbtodb (sblock, bno), zeroblock, sblock->fs_bsize); } -- cgit v1.2.3 From cd9220f84279dd9cd0d64e7910637c73431a38be Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 4 Oct 1994 04:15:39 +0000 Subject: Formerly Makefile.~36~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 941452ff..3dac8b98 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -19,7 +19,7 @@ dir := ufs makemode := server SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ - sizes.c subr.c tables.c bmap.c + sizes.c subr.c tables.c bmap.c pokeloc.c OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o LCLHDRS = ufs.h fs.h dinode.h dir.h REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ -- cgit v1.2.3 From 0d9a65449c21d6bc4a1dd4dbe5e5fc5eb8169bdd Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 4 Oct 1994 04:18:06 +0000 Subject: entered into RCS --- ufs/pokeloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/pokeloc.c b/ufs/pokeloc.c index cc1f364c..0e7235ad 100644 --- a/ufs/pokeloc.c +++ b/ufs/pokeloc.c @@ -28,7 +28,7 @@ struct pokeloc }; struct pokeloc *pokelist; -spin_lock_t pokelistlock = SPIN_LOCK_INITIAILIZER; +spin_lock_t pokelistlock = SPIN_LOCK_INITIALIZER; /* Remember that data here on the disk has been modified. */ void -- cgit v1.2.3 From 0e1359c5b9e65131dfff28f1054fc838f6fa35a8 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 4 Oct 1994 06:16:27 +0000 Subject: Formerly inode.c.~43~ --- ufs/inode.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index ba720b48..9321d2e8 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -154,6 +154,7 @@ diskfs_try_dropping_softrefs (struct node *np) void diskfs_lost_hardrefs (struct node *np) { +#ifdef notanymore struct port_info *pi; struct pager *p; @@ -195,6 +196,7 @@ diskfs_lost_hardrefs (struct node *np) else spin_unlock (&_libports_portrefcntlock); } +#endif } /* A new hard reference to a node has been created; it's now OK to -- cgit v1.2.3 From ba3b952dd16e913bcf611881906b0a7ee0a0a41d Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 4 Oct 1994 06:30:08 +0000 Subject: Formerly ufs.h.~28~ --- ufs/ufs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 20f67203..3301e703 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -173,6 +173,8 @@ int csum_dirty; void *disk_image; +spin_lock_t node2pagelock; + spin_lock_t alloclock; spin_lock_t gennumberlock; -- cgit v1.2.3 From b2d95e7216075bc9e4caff1c70ba880801d770a2 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 4 Oct 1994 06:34:16 +0000 Subject: Formerly sizes.c.~24~ --- ufs/sizes.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 8f6174af..7225a851 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -39,11 +39,12 @@ diskfs_truncate (struct node *np, { int offset; struct dinode *di = dino (np->dn->number); - int blocksfreed = 0; + volatile int blocksfreed = 0; error_t err; int i; struct iblock_spec indirs[NIADDR + 1]; - daddr_t lbn; + volatile daddr_t lbn; + struct user_pager_info *upi; if (length >= np->dn_stat.st_size) return 0; @@ -89,19 +90,26 @@ diskfs_truncate (struct node *np, immediately. (We are changing the data implicitly to zeros and doing it without the kernels immediate knowledge; this forces us to help out the kernel thusly.) */ - if (np->dn->fileinfo) + spin_lock (&node2pagelock); + upi = np->dn->fileinfo; + if (upi) + pager_reference (upi->p); + spin_unlock (&node2pagelock); + + if (upi) { mach_port_t obj; - pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, + pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np); mach_port_insert_right (mach_task_self (), obj, obj, MACH_MSG_TYPE_MAKE_SEND); poke_pages (obj, round_page (length), round_page (np->allocsize)); mach_port_deallocate (mach_task_self (), obj); - pager_flush_some (np->dn->fileinfo->p, round_page (length), + pager_flush_some (upi->p, round_page (length), np->allocsize - length, 1); + pager_unreference (upi->p); } /* Update the size on disk; fsck will finish freeing blocks if necessary @@ -118,9 +126,10 @@ diskfs_truncate (struct node *np, /* err XXX */ /* We don't support triple indirs */ - assert (indirs[0].offset == -1 - || indirs[1].offset == -1 - || indirs[2].offset == -1); + assert (indirs[3].offset == -2); + + err = diskfs_catch_exception (); + /* err XXX */ /* BSD carefully finds out how far to clear; it's vastly simpler to just clear everything after the new last block. */ @@ -252,9 +261,17 @@ diskfs_truncate (struct node *np, diskfs_end_catch_exception (); /* Now we can permit delayed copies again. */ - if (np->dn->fileinfo) - pager_change_attributes (np->dn->fileinfo->p, MAY_CACHE, - MEMORY_OBJECT_COPY_DELAY, 0); + spin_lock (&node2pagelock); + upi = np->dn->fileinfo; + if (upi) + pager_reference (upi->p); + spin_unlock (&node2pagelock); + if (upi) + { + pager_change_attributes (upi->p, MAY_CACHE, + MEMORY_OBJECT_COPY_DELAY, 0); + pager_unreference (upi->p); + } return err; } -- cgit v1.2.3 From c05ba8d85217e41af0b1a5538372a493fa4da76b Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 4 Oct 1994 07:29:34 +0000 Subject: Formerly pager.c.~39~ --- ufs/pager.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 11 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index b5a98e79..90e5d985 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -22,6 +22,8 @@ spin_lock_t pagerlistlock = SPIN_LOCK_INITIALIZER; struct user_pager_info *filepagerlist; +spin_lock_t node2pagelock = SPIN_LOCK_INITIALIZER; + #ifdef DONT_CACHE_MEMORY_OBJECTS #define MAY_CACHE 0 #else @@ -232,6 +234,7 @@ pager_unlock_page (struct user_pager_info *pager, goto out; assert (lblkno (sblock, address) < NDADDR); indirs[0].bno = di->di_db[lblkno (sblock, address)] = bno; + record_poke (di, sizeof (struct dinode)); } else { @@ -251,6 +254,7 @@ pager_unlock_page (struct user_pager_info *pager, goto out; zero_disk_block (bno); indirs[1].bno = di->di_ib[INDIR_SINGLE] = bno; + record_poke (di, sizeof (struct dinode)); } else { @@ -274,6 +278,7 @@ pager_unlock_page (struct user_pager_info *pager, goto out; zero_disk_block (bno); indirs[2].bno = di->di_ib[INDIR_DOUBLE] = bno; + record_poke (di, sizeof (struct dinode)); } diblock = indir_block (indirs[2].bno); @@ -289,6 +294,7 @@ pager_unlock_page (struct user_pager_info *pager, goto out; zero_disk_block (bno); indirs[1].bno = diblock[indirs[1].offset] = bno; + record_poke (diblock, sblock->fs_bsize); } } @@ -307,6 +313,7 @@ pager_unlock_page (struct user_pager_info *pager, dev_write_sync (fsbtodb (sblock, bno), zeroblock, sblock->fs_bsize); indirs[0].bno = siblock[indirs[0].offset] = bno; + record_poke (siblock, sblock->fs_bsize); } } @@ -341,6 +348,9 @@ void pager_clear_user_data (struct user_pager_info *upi) { assert (upi->type == FILE_DATA); + spin_lock (&node2pagelock); + upi->np->dn->fileinfo = 0; + spin_unlock (&node2pagelock); diskfs_nrele_light (upi->np); *upi->prevp = upi->next; if (upi->next) @@ -370,10 +380,20 @@ diskfs_file_update (struct node *np, int wait) { struct dirty_indir *d, *tmp; - - if (np->dn->fileinfo) - pager_sync (np->dn->fileinfo->p, wait); + struct user_pager_info *upi; + spin_lock (&node2pagelock); + upi = np->dn->fileinfo; + if (upi) + pager_reference (upi->p); + spin_unlock (&node2pagelock); + + if (upi) + { + pager_sync (upi->p, wait); + pager_unreference (upi->p); + } + for (d = np->dn->dirty; d; d = tmp) { sync_disk_blocks (d->bno, sblock->fs_bsize, wait); @@ -399,6 +419,7 @@ diskfs_get_filemap (struct node *np) && (!direct_symlink_extension || np->dn_stat.st_size >= sblock->fs_maxsymlinklen))); + spin_lock (&node2pagelock); if (!np->dn->fileinfo) { upi = malloc (sizeof (struct user_pager_info)); @@ -407,7 +428,6 @@ diskfs_get_filemap (struct node *np) diskfs_nref_light (np); upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); np->dn->fileinfo = upi; - ports_port_ref (upi->p); spin_lock (&pagerlistlock); upi->next = filepagerlist; @@ -418,6 +438,8 @@ diskfs_get_filemap (struct node *np) spin_unlock (&pagerlistlock); } right = pager_get_port (np->dn->fileinfo->p); + spin_unlock (&node2pagelock); + mach_port_insert_right (mach_task_self (), right, right, MACH_MSG_TYPE_MAKE_SEND); @@ -429,9 +451,18 @@ diskfs_get_filemap (struct node *np) void drop_pager_softrefs (struct node *np) { - if (MAY_CACHE && np->dn->fileinfo) - pager_change_attributes (np->dn->fileinfo->p, 0, - MEMORY_OBJECT_COPY_DELAY, 0); + struct user_pager_info *upi; + + spin_lock (&node2pagelock); + upi = np->dn->fileinfo; + if (upi) + pager_reference (upi->p); + spin_unlock (&node2pagelock); + + if (MAY_CACHE && upi) + pager_change_attributes (upi->p, 0, MEMORY_OBJECT_COPY_DELAY, 0); + if (upi) + pager_unreference (upi->p); } /* Call this when we should turn on caching because it's no longer @@ -439,9 +470,18 @@ drop_pager_softrefs (struct node *np) void allow_pager_softrefs (struct node *np) { - if (MAY_CACHE && np->dn->fileinfo) - pager_change_attributes (np->dn->fileinfo->p, 1, - MEMORY_OBJECT_COPY_DELAY, 0); + struct user_pager_info *upi; + + spin_lock (&node2pagelock); + upi = np->dn->fileinfo; + if (upi) + pager_reference (upi->p); + spin_unlock (&node2pagelock); + + if (MAY_CACHE && upi) + pager_change_attributes (upi->p, 1, MEMORY_OBJECT_COPY_DELAY, 0); + if (upi) + pager_unreference (upi->p); } /* Call this to find out the struct pager * corresponding to the @@ -451,6 +491,8 @@ allow_pager_softrefs (struct node *np) struct pager * diskfs_get_filemap_pager_struct (struct node *np) { + /* This is safe because fileinfo can't be cleared; there must be + an active mapping for this to be called. */ return np->dn->fileinfo->p; } @@ -503,7 +545,10 @@ diskfs_sync_everything (int wait) { void sync_one (struct user_pager_info *p) { - pager_sync (p->p, wait); + if (p != diskpager) + pager_sync (p->p, wait); + else + sync_disk (wait); } write_all_disknodes (); -- cgit v1.2.3 From 016352f721dd20c128333af12abc4660939c59b1 Mon Sep 17 00:00:00 2001 From: Hurd Maintainers Date: Tue, 4 Oct 1994 22:46:15 +0000 Subject: Formerly pager.c.~40~ --- ufs/pager.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 90e5d985..fd148d8d 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -117,8 +117,10 @@ pager_read_page (struct user_pager_info *pager, } else { +#if 0 printf ("Write-locked pagein Object %#x\tOffset %#x\n", pager, page); fflush (stdout); +#endif vm_allocate (mach_task_self (), buf, __vm_page_size, 1); *writelock = 1; } @@ -187,8 +189,10 @@ pager_unlock_page (struct user_pager_info *pager, /* Problem--where to get cred values for allocation here? */ +#if 0 printf ("Unlock page request, Object %#x\tOffset %#x...", pager, address); fflush (stdout); +#endif if (pager->type == DISK) return 0; @@ -216,6 +220,13 @@ pager_unlock_page (struct user_pager_info *pager, return EIO; } + err = diskfs_catch_exception (); + if (err) + { + rwlock_writer_unlock (&dn->allocptrlock); + return EIO; + } + /* See if we need a triple indirect block; fail if we do. */ assert (indirs[0].offset == -1 || indirs[1].offset == -1 -- cgit v1.2.3 From da152d2b61bf591ce23d89b40db10a92989159b5 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 5 Oct 1994 16:58:39 +0000 Subject: Formerly alloc.c.~18~ --- ufs/alloc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index c881454b..4464dfa0 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -546,6 +546,7 @@ diskfs_alloc_node (struct node *dir, goto noinodes; error = iget (ino, &np); assert ("duplicate allocation" && !np->dn_stat.st_mode); + assert (!np->istranslated); if (np->dn_stat.st_blocks) { printf("free inode %d had %d blocks\n", ino, np->dn_stat.st_blocks); -- cgit v1.2.3 From 587b384923f3968f5a96841550e9af81c91a0b21 Mon Sep 17 00:00:00 2001 From: Hurd Maintainers Date: Thu, 6 Oct 1994 02:18:38 +0000 Subject: entered into RCS --- ufs/inode.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 9321d2e8..e5ba31c9 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -211,10 +211,10 @@ diskfs_new_hardrefs (struct node *np) static error_t read_disknode (struct node *np) { + static int fsid, fsidset; struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; - volatile long long pid = getpid (); err = diskfs_catch_exception (); if (err) @@ -222,8 +222,14 @@ read_disknode (struct node *np) np->istranslated = !! di->di_trans; + if (!fsidset) + { + fsid = getpid (); + fsidset = 1; + } + st->st_fstype = FSTYPE_UFS; - st->st_fsid = pid; + st->st_fsid = fsid; st->st_ino = np->dn->number; st->st_gen = di->di_gen; st->st_rdev = di->di_rdev; -- cgit v1.2.3 From 0c57cb06c351c701818d4dcd2e45249486447672 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 7 Oct 1994 05:45:42 +0000 Subject: Formerly main.c.~24~ --- ufs/main.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 65da85bb..7fcfa43b 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -27,7 +27,6 @@ char *ufs_version = "0.0 pre-alpha"; -static char **save_argv; /* Parse the arguments for ufs when started as a translator. */ char * @@ -98,8 +97,6 @@ main (int argc, char **argv) error_t err; int sizes[DEV_GET_SIZE_COUNT]; u_int sizescnt = 2; - - save_argv = argv; mutex_init (&printf_lock); /* XXX */ @@ -205,7 +202,7 @@ main (int argc, char **argv) if (bootstrap == MACH_PORT_NULL) /* We are the bootstrap filesystem; do special boot-time setup. */ - diskfs_start_bootstrap (); + diskfs_start_bootstrap (argv); /* Now become a generic request thread. */ diskfs_main_request_loop (); @@ -218,8 +215,7 @@ diskfs_init_completed () mach_port_t proc, startup; error_t err; - _hurd_proc_init (save_argv); - proc = getproc(); + proc = getproc (); proc_register_version (proc, diskfs_host_priv, "ufs", HURD_RELEASE, ufs_version); err = proc_getmsgport (proc, 1, &startup); -- cgit v1.2.3 From 8f28a49e601297336c761b8de1c3ce964f8d7371 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 8 Oct 1994 00:49:28 +0000 Subject: Formerly Makefile.~37~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 3dac8b98..59965946 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -20,7 +20,7 @@ makemode := server SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c bmap.c pokeloc.c -OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o +OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o /gd3/gnu/libc/i386/devstream.o LCLHDRS = ufs.h fs.h dinode.h dir.h REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ ../hurd/ioserver.h ../hurd/fshelp.h -- cgit v1.2.3 From cab6f58508b5a1b0d44a742bf754bf8a1c99c088 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 10 Oct 1994 06:05:48 +0000 Subject: Formerly Makefile.~38~ --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 59965946..3dac8b98 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -20,7 +20,7 @@ makemode := server SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c bmap.c pokeloc.c -OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o /gd3/gnu/libc/i386/devstream.o +OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o LCLHDRS = ufs.h fs.h dinode.h dir.h REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ ../hurd/ioserver.h ../hurd/fshelp.h -- cgit v1.2.3 From 20bc9b801818cad5fd7d0ff47ce7427bf256e2ed Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 17 Oct 1994 20:36:23 +0000 Subject: entered into RCS --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 3dac8b98..59965946 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -20,7 +20,7 @@ makemode := server SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c bmap.c pokeloc.c -OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o +OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o /gd3/gnu/libc/i386/devstream.o LCLHDRS = ufs.h fs.h dinode.h dir.h REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ ../hurd/ioserver.h ../hurd/fshelp.h -- cgit v1.2.3 From 59fe81bbe11821d0c0f70e3caecb6164437d7ae5 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 25 Oct 1994 16:54:36 +0000 Subject: entered into RCS --- ufs/alloc.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 4464dfa0..b82d6065 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -817,6 +817,9 @@ ffs_fragextend(struct node *np, fs->fs_cstotal.cs_nffree--; csum[cg].cs_nffree--; } + record_poke (cgp, sblock->fs_cgsize); + csum_dirty = 1; + sblock_dirty = 1; fs->fs_fmod = 1; /* bdwrite(bp); */ return (bprev); @@ -892,6 +895,10 @@ ffs_alloccg(struct node *np, csum[cg].cs_nffree += i; fs->fs_fmod = 1; cgp->cg_frsum[i]++; + + record_poke (cgp, sblock->fs_cgsize); + csum_dirty = 1; + sblock_dirty = 1; /* bdwrite(bp); */ return (bno); } @@ -909,6 +916,9 @@ ffs_alloccg(struct node *np, cgp->cg_frsum[allocsiz]--; if (frags != allocsiz) cgp->cg_frsum[allocsiz - frags]++; + record_poke (cgp, sblock->fs_cgsize); + csum_dirty = 1; + sblock_dirty = 1; /* bdwrite(bp); */ return (cg * fs->fs_fpg + bno); } @@ -1020,6 +1030,9 @@ gotit: cg_blks(fs, cgp, cylno)[cbtorpos(fs, bno)]--; cg_blktot(cgp)[cylno]--; fs->fs_fmod = 1; + record_poke (cgp, sblock->fs_cgsize); + csum_dirty = 1; + sblock_dirty = 1; return (cgp->cg_cgx * fs->fs_fpg + bno); } @@ -1188,6 +1201,9 @@ gotit: fs->fs_cstotal.cs_ndir++; csum[cg].cs_ndir++; } + record_poke (cgp, sblock->fs_cgsize); + csum_dirty = 1; + sblock_dirty = 1; /* bdwrite(bp); */ return (cg * fs->fs_ipg + ipref); } @@ -1285,6 +1301,9 @@ ffs_blkfree(register struct node *np, cg_blktot(cgp)[i]++; } } + record_poke (cgp, sblock->fs_cgsize); + csum_dirty = 1; + sblock_dirty = 1; fs->fs_fmod = 1; /* bdwrite(bp); */ } @@ -1340,6 +1359,9 @@ diskfs_free_node (struct node *np, mode_t mode) fs->fs_cstotal.cs_ndir--; csum[cg].cs_ndir--; } + record_poke (cgp, sblock->fs_cgsize); + csum_dirty = 1; + sblock_dirty = 1; fs->fs_fmod = 1; /* bdwrite(bp); */ } -- cgit v1.2.3 From ca358f9be145942c38d645f0bca24e5637794962 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 25 Oct 1994 19:06:32 +0000 Subject: Formerly hyper.c.~15~ --- ufs/hyper.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index e73f78b8..5e9eb12f 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -123,7 +123,9 @@ copy_sblock () if (csum_dirty) { bcopy (csum, disk_image + fsaddr (sblock, sblock->fs_csaddr), - fsaddr (sblock, howmany (sblock->fs_cssize, sblock->fs_fsize))); + fragroundup (sblock, sblock->fs_cssize)); + record_poke (disk_image + fsaddr (sblock, sblock->fs_csaddr), + fragroundup (sblock, sblock->fs_cssize)); csum_dirty = 0; } @@ -153,6 +155,7 @@ copy_sblock () } else bcopy (sblock, disk_image + SBOFF, SBSIZE); + record_poke (disk_image + SBOFF, SBSIZE); sblock_dirty = 0; } -- cgit v1.2.3 From 6968b16f1bb86a90b525636987501c7094d070d3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 25 Oct 1994 19:48:58 +0000 Subject: Formerly pager.c.~41~ --- ufs/pager.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index fd148d8d..73f1b5d7 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -546,6 +546,7 @@ diskfs_shutdown_pager () pager_shutdown (p->p); } + copy_sblock (); write_all_disknodes (); pager_traverse (shutdown_one); } @@ -562,6 +563,7 @@ diskfs_sync_everything (int wait) sync_disk (wait); } + copy_sblock (); write_all_disknodes (); pager_traverse (sync_one); } -- cgit v1.2.3 From 28cd2c87c77fe466592f265bcb22601f747e28c0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 28 Oct 1994 00:58:57 +0000 Subject: entered into RCS --- ufs/sizes.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 7225a851..bf9e2c38 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -103,8 +103,6 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np); - mach_port_insert_right (mach_task_self (), obj, obj, - MACH_MSG_TYPE_MAKE_SEND); poke_pages (obj, round_page (length), round_page (np->allocsize)); mach_port_deallocate (mach_task_self (), obj); pager_flush_some (upi->p, round_page (length), @@ -587,8 +585,6 @@ diskfs_grow (struct node *np, mach_port_t obj; obj = diskfs_get_filemap (np); - mach_port_insert_right (mach_task_self (), obj, obj, - MACH_MSG_TYPE_MAKE_SEND); poke_pages (obj, trunc_page (poke_off), round_page (poke_off + poke_len)); mach_port_deallocate (mach_task_self (), obj); -- cgit v1.2.3 From 1e025ef8df752af1c26ababf60ff96ed38d599d1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 28 Oct 1994 01:15:47 +0000 Subject: entered into RCS --- ufs/dir.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 2f215974..83eae80d 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -129,8 +129,6 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, /* Map in the directory contents. */ memobj = diskfs_get_filemap (dp); - mach_port_insert_right (mach_task_self (), memobj, memobj, - MACH_MSG_TYPE_MAKE_SEND); buf = 0; /* We allow extra space in case we have to do an EXTEND. */ buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); @@ -655,8 +653,6 @@ diskfs_dirempty(struct node *dp, error_t err; memobj = diskfs_get_filemap (dp); - mach_port_insert_right (mach_task_self (), memobj, memobj, - MACH_MSG_TYPE_MAKE_SEND); buf = 0; err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, -- cgit v1.2.3 From 50e3959d6d8fa7ade5f82ea85c6f65777eee0f5f Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 28 Oct 1994 22:23:22 +0000 Subject: entered into RCS --- ufs/main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 7fcfa43b..4c617193 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -163,14 +163,14 @@ main (int argc, char **argv) get_hypermetadata (); if (diskpagersize < sblock->fs_size * sblock->fs_fsize) - { - fprintf (stderr, - "Disk size (%d) less than necessary " - "(superblock says we need %ld)\n", - sizes[DEV_GET_SIZE_DEVICE_SIZE], - sblock->fs_size * sblock->fs_fsize); - exit (1); - } + { + fprintf (stderr, + "Disk size (%d) less than necessary " + "(superblock says we need %ld)\n", + sizes[DEV_GET_SIZE_DEVICE_SIZE], + sblock->fs_size * sblock->fs_fsize); + exit (1); + } vm_allocate (mach_task_self (), &zeroblock, sblock->fs_bsize, 1); -- cgit v1.2.3 From b20e126405a6679ed645df02f6d12d0e932a7b93 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 2 Nov 1994 21:08:19 +0000 Subject: entered into RCS --- ufs/hyper.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 5e9eb12f..1317e8b6 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -105,13 +105,24 @@ get_hypermetadata (void) diskfs_end_catch_exception (); } -/* We don't need this callback; all our data is backed by pagers. */ +/* Write the csum data. This isn't backed by a pager because it is + taken from ordinary data blocks and might not be an even number + of pages; in that case writing it through the pager would nuke whatever + pages came after it on the disk and were backed by file pagers. */ void diskfs_set_hypermetadata (int wait, int clean) { + spin_lock (&alloclock); + if (csum_dirty) + (wait ? dev_write_sync : dev_write) (fsbtodb (sblock, sblock->fs_csaddr), + (vm_address_t) csum, + fragroundup (sblock, + sblock->fs_cssize)); + csum_dirty = 0; + spin_unlock (&alloclock); } -/* Copy the sblock and csum into the disk */ +/* Copy the sblock into the disk */ void copy_sblock () { @@ -120,14 +131,6 @@ copy_sblock () assert (!diskfs_catch_exception ()); spin_lock (&alloclock); - if (csum_dirty) - { - bcopy (csum, disk_image + fsaddr (sblock, sblock->fs_csaddr), - fragroundup (sblock, sblock->fs_cssize)); - record_poke (disk_image + fsaddr (sblock, sblock->fs_csaddr), - fragroundup (sblock, sblock->fs_cssize)); - csum_dirty = 0; - } if (clean && !diskfs_readonly) { -- cgit v1.2.3 From 88129f99b2e25f38cb7be3f8f50494842b853309 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 8 Nov 1994 05:04:32 +0000 Subject: entered into RCS --- ufs/pager.c | 2 +- ufs/ufs.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 73f1b5d7..d41b792d 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -152,7 +152,7 @@ pager_write_page (struct user_pager_info *pager, else { printf ("Attempt to write unallocated disk\n."); - printf ("Object %#x\tOffset %#x\n", pager, page); + printf ("Object %p\tOffset %#x\n", pager, page); fflush (stdout); err = 0; /* unallocated disk; error would be pointless */ diff --git a/ufs/ufs.h b/ufs/ufs.h index 3301e703..a7c9a891 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -270,6 +270,7 @@ error_t dev_read_sync (daddr_t addr, vm_address_t *data, long len); /* From hyper.c: */ void get_hypermetadata (void); +void copy_sblock (void); /* From inode.c: */ error_t iget (ino_t ino, struct node **NP); -- cgit v1.2.3 From 9aaa8d2a028e054848cfe1e244f6a32b4e225d09 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 9 Nov 1994 10:43:07 +0000 Subject: (main): Behave more reasonably if we can't open DEVNAME. --- ufs/main.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 4c617193..0e6bd19d 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -129,10 +129,32 @@ main (int argc, char **argv) any other diskfs call. */ diskfs_init_diskfs (); - err = device_open (diskfs_master_device, - (diskfs_readonly ? 0 : D_WRITE) | D_READ, - devname, &ufs_device); - assert (!err); + do + { + char *line = 0; + size_t linesz = 0; + ssize_t len; + + err = device_open (diskfs_master_device, + (diskfs_readonly ? 0 : D_WRITE) | D_READ, + devname, &ufs_device); + if (err == D_NO_SUCH_DEVICE && getpid () <= 0) + { + /* Prompt the user to give us another name rather + than just crashing */ + printf ("Cannot open device %s\n", devname); + len = getline (&line, &linesz, stdin); + if (len > 2) + devname = line; + } + } + while (err && err == D_NO_SUCH_DEVICE && getpid () <= 0); + + if (err) + { + perror (devname); + exit (1); + } /* Check to make sure device sector size is reasonable. */ err = device_get_status (ufs_device, DEV_GET_SIZE, sizes, &sizescnt); -- cgit v1.2.3 From a7cb22de8543981acf8101cc70cc4b14c4742242 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Nov 1994 18:27:05 +0000 Subject: (diskfs_set_hypermetadata): Copy CSUM into a page-aligned page-sized buffer for disk write to avoid inane kernel bug. --- ufs/hyper.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 1317e8b6..9f8bd8d5 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -112,13 +112,31 @@ get_hypermetadata (void) void diskfs_set_hypermetadata (int wait, int clean) { + vm_address_t buf; + vm_size_t bufsize; + error_t err; + spin_lock (&alloclock); - if (csum_dirty) - (wait ? dev_write_sync : dev_write) (fsbtodb (sblock, sblock->fs_csaddr), - (vm_address_t) csum, - fragroundup (sblock, - sblock->fs_cssize)); - csum_dirty = 0; + + if (!csum_dirty) + { + spin_unlock (&alloclock); + return; + } + + /* Copy into a page-aligned buffer to avoid bugs in kernel device code. */ + + bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); + + err = dev_read_sync (fsbtodb (sblock, sblock->fs_csaddr), &buf, bufsize); + if (!err) + { + bcopy (csum, (void *) buf, sblock->fs_cssize); + (wait ? dev_write_sync : dev_write) (fsbtodb (sblock, sblock->fs_csaddr), + buf, bufsize); + csum_dirty = 0; + } + spin_unlock (&alloclock); } -- cgit v1.2.3 From 44eca97cf3027b2078c6954131753e315a6ed577 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 10 Nov 1994 18:33:47 +0000 Subject: (main): Issue decent prompt. --- ufs/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 0e6bd19d..5905cbb0 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -143,6 +143,8 @@ main (int argc, char **argv) /* Prompt the user to give us another name rather than just crashing */ printf ("Cannot open device %s\n", devname); + printf ("Open instead: "); + fflush (stdout); len = getline (&line, &linesz, stdin); if (len > 2) devname = line; -- cgit v1.2.3 From 33f49d636fa6189f04e7d1ed5b690e34a4c3205e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 11 Nov 1994 16:45:33 +0000 Subject: (diskfs_set_hypermetadata): Always use dev_write_sync to avoid device_write bug that says you can't modify the buffer until device_write returns. Also remember to deallocate BUF. --- ufs/hyper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 9f8bd8d5..94fd209c 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -132,10 +132,10 @@ diskfs_set_hypermetadata (int wait, int clean) if (!err) { bcopy (csum, (void *) buf, sblock->fs_cssize); - (wait ? dev_write_sync : dev_write) (fsbtodb (sblock, sblock->fs_csaddr), - buf, bufsize); + dev_write_sync (fsbtodb (sblock, sblock->fs_csaddr), buf, bufsize); csum_dirty = 0; } + vm_deallocate (mach_task_self (), buf, bufsize); spin_unlock (&alloclock); } -- cgit v1.2.3 From 625da34c7cbb8896caa4b17fca8d16284ee48132 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 11 Nov 1994 16:46:04 +0000 Subject: (diskfs_set_hypermetadata): Deallocate BUF in the right place. --- ufs/hyper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 94fd209c..8a556cef 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -134,8 +134,8 @@ diskfs_set_hypermetadata (int wait, int clean) bcopy (csum, (void *) buf, sblock->fs_cssize); dev_write_sync (fsbtodb (sblock, sblock->fs_csaddr), buf, bufsize); csum_dirty = 0; + vm_deallocate (mach_task_self (), buf, bufsize); } - vm_deallocate (mach_task_self (), buf, bufsize); spin_unlock (&alloclock); } -- cgit v1.2.3 From cc4f4d5aa696bc5c3d66b6460596dbcc1848e094 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 28 Jan 1995 19:59:24 +0000 Subject: (OBJS): Remove reference to libc's devstream.o. --- ufs/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 59965946..7ad7cb65 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -1,5 +1,5 @@ -# Copyright (C) 1994 Free Software Foundation +# Copyright (C) 1994, 1995 Free Software Foundation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -18,9 +18,9 @@ dir := ufs makemode := server -SRCS=alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ - sizes.c subr.c tables.c bmap.c pokeloc.c -OBJS=$(subst .c,.o,$(SRCS)) exec_server_image.o /gd3/gnu/libc/i386/devstream.o +SRCS = alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ + sizes.c subr.c tables.c bmap.c pokeloc.c +OBJS = $(SRCS:.c=.o) exec_server_image.o LCLHDRS = ufs.h fs.h dinode.h dir.h REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ ../hurd/ioserver.h ../hurd/fshelp.h -- cgit v1.2.3 From 28d8598ef9e75e22031141cae694ece08af6730e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 17 Mar 1995 19:31:00 +0000 Subject: (ffs_clusteracct): Make static. (alloc_sync): New function. (ffs_alloc): Call alloc_sync. (ffs_realloccg): Likewise. (diskfs_alloc_node): Likewise. (ffs_blkfree): Likewise. (diskfs_free_node): Likewise. --- ufs/alloc.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index b82d6065..9fa517ed 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -1,5 +1,5 @@ /* Disk allocation routines - Copyright (C) 1993, 1994 Free Software Foundation + Copyright (C) 1993, 1994, 1995 Free Software Foundation This file is part of the GNU Hurd. @@ -73,7 +73,21 @@ static ino_t ffs_dirpref (struct fs *); static u_long ffs_nodealloccg (struct node *, int, daddr_t, int); static daddr_t ffs_alloccgblk (struct fs *, struct cg *, daddr_t); static daddr_t ffs_mapsearch (struct fs *, struct cg *, daddr_t, int); -void ffs_clusteracct (struct fs *, struct cg *, daddr_t, int); +static void ffs_clusteracct (struct fs *, struct cg *, daddr_t, int); + +/* Sync all allocation information and nod eNP if diskfs_synchronous. */ +inline +alloc_sync (struct diskfs_node *np) +{ + if (diskfs_syncronous) + { + if (np) + diskfs_node_update (np, 1); + copy_sblock (); + diskfs_set_dypermetadata (1, 0); + sync_disk (1); + } +} /* * Allocate a block in the file system. @@ -140,6 +154,7 @@ ffs_alloc(register struct node *np, np->dn_set_ctime = 1; np->dn_set_mtime = 1; *bnp = bno; + alloc_sync (np); return (0); } #ifdef QUOTA @@ -235,6 +250,7 @@ ffs_realloccg(register struct node *np, bzero((char *)bp->b_data + osize, (u_int)nsize - osize); *bpp = bp; #endif + alloc_sync (np); return (0); } /* @@ -305,6 +321,7 @@ ffs_realloccg(register struct node *np, bzero((char *)bp->b_data + osize, (u_int)nsize - osize); *bpp = bp; #endif /* 0 */ + alloc_sync (np); return (0); } #ifdef QUOTA @@ -565,6 +582,7 @@ diskfs_alloc_node (struct node *dir, spin_unlock (&gennumberlock); *npp = np; + alloc_sync (np); return (0); noinodes: printf ("out of inodes"); @@ -1305,6 +1323,7 @@ ffs_blkfree(register struct node *np, csum_dirty = 1; sblock_dirty = 1; fs->fs_fmod = 1; + alloc_sync (np); /* bdwrite(bp); */ } @@ -1363,6 +1382,7 @@ diskfs_free_node (struct node *np, mode_t mode) csum_dirty = 1; sblock_dirty = 1; fs->fs_fmod = 1; + alloc_sync (np, 1); /* bdwrite(bp); */ } @@ -1430,7 +1450,7 @@ ffs_mapsearch(register struct fs *fs, * * Cnt == 1 means free; cnt == -1 means allocating. */ -void +static void ffs_clusteracct(struct fs *fs, struct cg *cgp, daddr_t blkno, -- cgit v1.2.3 From 08eb992b1fdc4285ca49b31fb51a0a844ba03c42 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 17 Mar 1995 19:36:46 +0000 Subject: (alloc_sync): Typo. --- ufs/alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 9fa517ed..39344501 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -77,7 +77,7 @@ static void ffs_clusteracct (struct fs *, struct cg *, daddr_t, int); /* Sync all allocation information and nod eNP if diskfs_synchronous. */ inline -alloc_sync (struct diskfs_node *np) +alloc_sync (struct node *np) { if (diskfs_syncronous) { -- cgit v1.2.3 From bb2bd7c4d2c7e834529383b0036373faf4cd035d Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 17 Mar 1995 19:37:52 +0000 Subject: More typos. --- ufs/alloc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 39344501..87b0b45a 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -76,15 +76,15 @@ static daddr_t ffs_mapsearch (struct fs *, struct cg *, daddr_t, int); static void ffs_clusteracct (struct fs *, struct cg *, daddr_t, int); /* Sync all allocation information and nod eNP if diskfs_synchronous. */ -inline +inline void alloc_sync (struct node *np) { - if (diskfs_syncronous) + if (diskfs_synchronous) { if (np) diskfs_node_update (np, 1); copy_sblock (); - diskfs_set_dypermetadata (1, 0); + diskfs_set_hypermetadata (1, 0); sync_disk (1); } } @@ -1382,7 +1382,7 @@ diskfs_free_node (struct node *np, mode_t mode) csum_dirty = 1; sblock_dirty = 1; fs->fs_fmod = 1; - alloc_sync (np, 1); + alloc_sync (np); /* bdwrite(bp); */ } -- cgit v1.2.3 From bf193e411495df70c055c9b22e02f4ac18353df5 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 20 Mar 1995 18:58:39 +0000 Subject: (diskfs_synchronous): New variable. --- ufs/consts.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/consts.c b/ufs/consts.c index 2062a07f..6698c5f4 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -1,5 +1,5 @@ /* Various constants wanted by the diskfs library - Copyright (C) 1994 Free Software Foundation + Copyright (C) 1994, 1995 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -28,3 +28,4 @@ char *diskfs_server_name = "ufs"; int diskfs_major_version = 0; int diskfs_minor_version = 0; int diskfs_edit_version = 0; +int diskfs_synchronous = 0; -- cgit v1.2.3 From bee30b19142cc6a0f9ca98c8936d3c439f0b9d16 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 31 Mar 1995 18:43:23 +0000 Subject: (diskfs_truncate): Don't acquire writer lock on NP->dn->allocptrlock until after forcing delayed copies through; otherwise the pageins will deadlock attempting to get a reader lock to service them. This is safe, because we only need NP->allocsize here, and that can't change as long as we hold NP->lock. --- ufs/sizes.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index bf9e2c38..ef7666b1 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -1,5 +1,5 @@ /* File growth and truncation - Copyright (C) 1993, 1994 Free Software Foundation + Copyright (C) 1993, 1994, 1995 Free Software Foundation This file is part of the GNU Hurd. @@ -83,13 +83,11 @@ diskfs_truncate (struct node *np, diskfs_file_update (np, 1); } - rwlock_writer_lock (&np->dn->allocptrlock); - /* Now flush all the data past the new size from the kernel. Also force any delayed copies of this data to take place - immediately. (We are changing the data implicitly to zeros - and doing it without the kernels immediate knowledge; - this forces us to help out the kernel thusly.) */ + immediately. (We are implicitly changing the data to zeros + and doing it without the kernel's immediate knowledge; + accordingl we must help out the kernel thusly.) */ spin_lock (&node2pagelock); upi = np->dn->fileinfo; if (upi) @@ -110,6 +108,8 @@ diskfs_truncate (struct node *np, pager_unreference (upi->p); } + rwlock_writer_lock (&np->dn->allocptrlock); + /* Update the size on disk; fsck will finish freeing blocks if necessary should we crash. */ np->dn_stat.st_size = length; -- cgit v1.2.3 From 5fb8321441b128744285e783e8468a8a0ee10698 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 5 Apr 1995 00:08:14 +0000 Subject: (diskfs_set_translator): When freeing passive translator, account for blocks freed in NP->dn_stat.st_blocks. --- ufs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index e5ba31c9..80a5fcff 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,5 @@ /* Inode management routines - Copyright (C) 1994 Free Software Foundation + Copyright (C) 1994, 1995 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -492,6 +492,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, ffs_blkfree (np, blkno, sblock->fs_bsize); di->di_trans = 0; record_poke (di, sizeof (struct dinode)); + np->dn_stat.st_blocks -= btodb (sblock->fs_bsize); np->istranslated = 0; np->dn_set_ctime = 1; } -- cgit v1.2.3 From 358d5da97c37c814af4124e099fb50e2189c6d1f Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 13 Apr 1995 22:38:52 +0000 Subject: (main): Don't abort if a std file descriptor is already open. --- ufs/main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 5905cbb0..772f82ff 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -109,11 +109,10 @@ main (int argc, char **argv) { /* XXX let us see errors */ int fd = open ("/dev/console", O_RDWR); - assert (fd == 0); - fd = dup (0); - assert (fd == 1); - fd = dup (1); - assert (fd == 2); + while (fd >= 0 && fd < 2) + fd = dup(fd); + if (fd > 2) + close (fd); } } else -- cgit v1.2.3 From 529ef4b137e4280fed13cb7b38d60c93cdd40886 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 28 Apr 1995 23:01:57 +0000 Subject: (write_all_disknodes): We have to really lock the nodes around the calls to diskfs_set_node_times and write_node; this in turn forces us to have real refereces. --- ufs/inode.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 80a5fcff..afe712f5 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -412,15 +412,31 @@ write_all_disknodes () { int n; struct node *np; - + struct item {struct item *next; struct node *np;} *list = 0; + struct item *i; + + /* Acquire a reference on all the nodes in the hash table + and enter them into a list on the stack. */ spin_lock (&diskfs_node_refcnt_lock); for (n = 0; n < INOHSZ; n++) for (np = nodehash[n]; np; np = np->dn->hnext) { - diskfs_set_node_times (np); - write_node (np); + np->references++; + i = alloc (sizeof (struct item)); + i->next = list; + i->np = np; + list = i; } spin_unlock (&diskfs_node_refcnt_lock); + + /* Update each node. */ + for (i = list; i; i = i->next) + { + mutex_lock (&i->np->lock); + diskfs_set_node_times (i->np); + write_node (i->np); + diskfs_nput (i->np); + } } void -- cgit v1.2.3 From c8de1463ad38c0e85eb722fa658d8b3ec1c9757f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 2 May 1995 15:59:06 +0000 Subject: (pager_clear_user_data): Acquire pagerlistlock around modifications to UPI->next/prevp list structure. --- ufs/pager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index d41b792d..f403df64 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -1,5 +1,5 @@ /* Pager for ufs - Copyright (C) 1994 Free Software Foundation + Copyright (C) 1994, 1995 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -363,9 +363,11 @@ pager_clear_user_data (struct user_pager_info *upi) upi->np->dn->fileinfo = 0; spin_unlock (&node2pagelock); diskfs_nrele_light (upi->np); + spin_lock (&pagerlistlock); *upi->prevp = upi->next; if (upi->next) upi->next->prevp = upi->prevp; + spin_unlock (&pagerlistlock); free (upi); } -- cgit v1.2.3 From a59ba4531f53f13c86243cf0bbb42e919459a1ff Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 8 May 1995 13:30:46 +0000 Subject: (write_all_disknodes): Fix typo `alloc' --> `alloca'. --- ufs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index afe712f5..6976ef78 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -422,7 +422,7 @@ write_all_disknodes () for (np = nodehash[n]; np; np = np->dn->hnext) { np->references++; - i = alloc (sizeof (struct item)); + i = alloca (sizeof (struct item)); i->next = list; i->np = np; list = i; -- cgit v1.2.3 From 4c51401dcc09332dae33bc0de3dd9fb7c14627f1 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 8 May 1995 13:32:20 +0000 Subject: (diskfs_lookup): When looping back to try_again: because we're looking up "..", be sure and trash the mapping we made of the directory's pager -- otherwise the reference to the pager never gets dropped and we can never free the node. (diskfs_lookup): ds->type was being compared to LOOKING, which value it can never have. Compare ds->stat against LOOKING instead. --- ufs/dir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 83eae80d..aeaa5abc 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -95,7 +95,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, struct node *np = 0; int retry_dotdot = 0; memory_object_t memobj; - vm_address_t buf; + vm_address_t buf = 0; vm_size_t buflen; int blockaddr; int idx; @@ -124,6 +124,11 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, ds->mapbuf = 0; ds->mapextent = 0; } + if (buf) + { + vm_deallocate (mach_task_self (), buf, buflen); + buf = 0; + } if (ds && (type == CREATE || type == RENAME)) ds->stat = LOOKING; @@ -245,7 +250,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, goto out; } - if ((type == CREATE || type == RENAME) && !np && ds && ds->type == LOOKING) + if ((type == CREATE || type == RENAME) && !np && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ ds->type = CREATE; -- cgit v1.2.3 From e06111c17de78853d266ec48860e7db1dfbd701a Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 8 May 1995 13:32:51 +0000 Subject: (pager_clear_user_data): Don't die when called on the disk pager. --- ufs/pager.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index f403df64..35bf1d22 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -358,16 +358,18 @@ pager_report_extent (struct user_pager_info *pager, void pager_clear_user_data (struct user_pager_info *upi) { - assert (upi->type == FILE_DATA); - spin_lock (&node2pagelock); - upi->np->dn->fileinfo = 0; - spin_unlock (&node2pagelock); - diskfs_nrele_light (upi->np); - spin_lock (&pagerlistlock); - *upi->prevp = upi->next; - if (upi->next) - upi->next->prevp = upi->prevp; - spin_unlock (&pagerlistlock); + if (upi->type == FILE_DATA) + { + spin_lock (&node2pagelock); + upi->np->dn->fileinfo = 0; + spin_unlock (&node2pagelock); + diskfs_nrele_light (upi->np); + spin_lock (&pagerlistlock); + *upi->prevp = upi->next; + if (upi->next) + upi->next->prevp = upi->prevp; + spin_unlock (&pagerlistlock); + } free (upi); } -- cgit v1.2.3 From 0b6693ea4058ee760740a656d832507b5bf1f9d3 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 13 May 1995 09:04:01 +0000 Subject: (OBJS): Remove exec_server_image.o. (exec_server_image.o): Rule removed. --- ufs/Makefile | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 7ad7cb65..f0022c91 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -20,7 +20,7 @@ makemode := server SRCS = alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c bmap.c pokeloc.c -OBJS = $(SRCS:.c=.o) exec_server_image.o +OBJS = $(SRCS:.c=.o) LCLHDRS = ufs.h fs.h dinode.h dir.h REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ ../hurd/ioserver.h ../hurd/fshelp.h @@ -32,10 +32,6 @@ target = ufs include ../Makeconf -exec_server_image.o: ../exec/exec ../mkbootfs/mkbootfs - rsh $(mighost) -n cd `pwd` \; \ - ../mkbootfs/mkbootfs ../exec/exec exec_server_image.o - $(OBJS): ufs.h $(OBJS): $(REMHDRS) alloc.o: fs.h dinode.h @@ -48,6 +44,3 @@ pager.o: fs.h dinode.h sizes.o: fs.h dinode.h subr.o: fs.h tables.o: fs.h - -$(foreach dir,mkbootfs exec,../$(dir)/%): FORCE - $(MAKE) -C $(@D) $(@F) -- cgit v1.2.3 From 763cca7a08c3935945e8c29d2569e4cd85a35829 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 15 May 1995 17:14:45 +0000 Subject: (pager_clear_user_data): Doc fix. --- ufs/pager.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 35bf1d22..3e9747b8 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -358,6 +358,7 @@ pager_report_extent (struct user_pager_info *pager, void pager_clear_user_data (struct user_pager_info *upi) { + /* XXX Do the right thing for the disk pager here too. */ if (upi->type == FILE_DATA) { spin_lock (&node2pagelock); -- cgit v1.2.3 From 0f348a6d19189b691dfd35cb13a18940dae82c97 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 20 May 1995 04:38:37 +0000 Subject: (CPPFLAGS): Add -I../lib, to get include lib include files, and $(CPPFLAGS-$(notdir $<)) to get file-specific cpp options. Add a vpath for %.c to ../lib, so we can use source files from there. --- ufs/Makefile | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index f0022c91..d351caab 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -30,6 +30,10 @@ HURDLIBS = libdiskfs libports libpager libioserver libfshelp libthreads LDFLAGS = -Wl,--no-keep-memory target = ufs +CPPFLAGS += -I../lib +CPPFLAGS += $(CPPFLAGS-$(notdir $<)) +vpath %.c ../lib + include ../Makeconf $(OBJS): ufs.h -- cgit v1.2.3 From 518e36e2049626337778af39c7cd64e4deba59ff Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 20 May 1995 04:39:22 +0000 Subject: (trans_parse_args): Use options_parse & diskfs_standard_startup_options to parse our translator options. (usage): New function. (parse_opt): New function. --- ufs/main.c | 78 ++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 22 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 772f82ff..d5699d51 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -26,40 +26,74 @@ #include char *ufs_version = "0.0 pre-alpha"; + +/* ---------------------------------------------------------------- */ +#define USAGE "Usage: %s [OPTION...] DEVICE\n" + +static void +usage(int status) +{ + if (status != 0) + fprintf(stderr, "Try `%s --help' for more information.\n", + program_invocation_name); + else + { + printf(USAGE, program_invocation_name); + printf("\ +\n\ + -r, --readonly disable writing to DEVICE\n\ + -w, --writable enable writing to DEVICE\n\ + -s, --sync[=INTERVAL] with an argument, sync every INTERVAL seconds,\n\ + otherwise operate in synchronous mode\n\ + -n, --nosync never sync the filesystem\n\ + --help display this help and exit\n\ + --version output version information and exit\n\ +"); + } + exit (status); +} + +#define SHORT_OPTS "" + +static struct option long_opts[] = +{ + {"help", no_argument, 0, '?'}, + {0, 0, 0, 0} +}; + +static error_t +parse_opt (int opt, char *arg) +{ + /* We currently only deal with one option... */ + if (opt != '?') + return EINVAL; + usage (0); /* never returns */ + return 0; +} /* Parse the arguments for ufs when started as a translator. */ char * trans_parse_args (int argc, char **argv) { - char *devname; - /* When started as a translator, we are called with - the device name and an optional argument -r, which - signifies read-only. */ - if (argc < 2 || argc > 3) - exit (1); + int argind; /* ARGV index of the first argument. */ + struct options options = + { SHORT_OPTS, long_opts, parse_opt, diskfs_standard_startup_options }; - if (argc == 2) - devname = argv[1]; + /* Parse our command line. */ + if (options_parse (&options, argc, argv, OPTIONS_PRINT_ERRS, &argind)) + usage (1); - else if (argc == 3) + if (argc - argind != 1) { - if (argv[1][0] == '-' && argv[1][1] == 'r') - { - diskfs_readonly = 1; - devname = argv[2]; - } - else if (argv[2][0] == '-' && argv[2][1] == 'r') - { - diskfs_readonly = 1; - devname = argv[1]; - } - else - exit (1); + fprintf (stderr, USAGE, program_invocation_name); + usage (1); } - return devname; + return argv[argind]; } + +/* ---------------------------------------------------------------- */ struct node *diskfs_root_node; -- cgit v1.2.3 From 45fb882198a129b3174548433ab635e7ec66417c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 14 Jun 1995 20:19:46 +0000 Subject: (diskfs_get_translator): Conform to new memory usage semantic. --- ufs/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 6976ef78..7f302e47 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -548,8 +548,7 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) transloc = disk_image + fsaddr (sblock, blkno); datalen = *(u_int *)transloc; - if (datalen > *namelen) - vm_allocate (mach_task_self (), (vm_address_t *) namep, datalen, 1); + *namep = malloc (datalen); bcopy (transloc + sizeof (u_int), *namep, datalen); diskfs_end_catch_exception (); -- cgit v1.2.3 From 8422cad93ec0d573e0de38d8d2771980aaa1554d Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 20 Jun 1995 01:17:19 +0000 Subject: (diskfs_node_iterate): New function. (write_all_disknodes): Use it. --- ufs/inode.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 7f302e47..df5fec17 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -404,17 +404,15 @@ read_symlink_hook (struct node *np, } error_t (*diskfs_read_symlink_hook)(struct node *, char *) = read_symlink_hook; - -/* Write all active disknodes into the dinode pager. */ -void -write_all_disknodes () +error_t +diskfs_node_iterate (error_t (*fun)(struct node *)) { - int n; struct node *np; struct item {struct item *next; struct node *np;} *list = 0; struct item *i; - + error_t err; + /* Acquire a reference on all the nodes in the hash table and enter them into a list on the stack. */ spin_lock (&diskfs_node_refcnt_lock); @@ -428,16 +426,33 @@ write_all_disknodes () list = i; } spin_unlock (&diskfs_node_refcnt_lock); - - /* Update each node. */ + + err = 0; for (i = list; i; i = i->next) { - mutex_lock (&i->np->lock); - diskfs_set_node_times (i->np); - write_node (i->np); - diskfs_nput (i->np); + if (!err) + { + mutex_lock (&i->np->lock); + err = (*fun)(i->np); + mutex_unlock (&i->np->lock); + } + diskfs_nrele (i->np); } } + +/* Write all active disknodes into the dinode pager. */ +void +write_all_disknodes () +{ + error_t + helper (struct node *np) + { + diskfs_set_node_times (np); + write_node (np); + } + + diskfs_node_iterate (helper); +} void diskfs_write_disknode (struct node *np, int wait) -- cgit v1.2.3 From 8ad6fc41b13f33ed47eb9ae01cdd6230af2de327 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 20 Jun 1995 01:21:01 +0000 Subject: (write_all_disknodes): Typos. --- ufs/inode.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index df5fec17..488b2785 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -412,6 +412,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) struct item {struct item *next; struct node *np;} *list = 0; struct item *i; error_t err; + int n; /* Acquire a reference on all the nodes in the hash table and enter them into a list on the stack. */ @@ -438,6 +439,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) } diskfs_nrele (i->np); } + return err; } /* Write all active disknodes into the dinode pager. */ @@ -449,6 +451,7 @@ write_all_disknodes () { diskfs_set_node_times (np); write_node (np); + return 0; } diskfs_node_iterate (helper); -- cgit v1.2.3 From 12235ec5d3b87c11782d39732209a39bb1e55381 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 20 Jun 1995 15:48:44 +0000 Subject: (ffs_realloccg): Remove assignments from if tests. --- ufs/alloc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 87b0b45a..add588ee 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -211,7 +211,8 @@ ffs_realloccg(register struct node *np, if (!diskfs_isuid (0, cred) && freespace(fs, fs->fs_minfree) <= 0) goto nospace; - if (error = diskfs_catch_exception ()) + error = diskfs_catch_exception (); + if (error) return error; bprev = (dino (np->dn->number))->di_db[lbprev]; diskfs_end_catch_exception (); @@ -237,7 +238,8 @@ ffs_realloccg(register struct node *np, * Check for extension in the existing location. */ cg = dtog(fs, bprev); - if (bno = ffs_fragextend(np, cg, (long)bprev, osize, nsize)) { + bno = ffs_fragextend(np, cg, (long)bprev, osize, nsize); + if (bno) assert (bno == bprev); spin_unlock (&alloclock); np->dn_stat.st_blocks += btodb(nsize - osize); -- cgit v1.2.3 From c727e27413678eeadbc1a33df0c884a6e7775a9a Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 20 Jun 1995 15:50:14 +0000 Subject: (diskfs_truncate): Remove assignment from if test. --- ufs/sizes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index ef7666b1..8657ce13 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -58,7 +58,8 @@ diskfs_truncate (struct node *np, { error_t err; - if (err = diskfs_catch_exception ()) + err = diskfs_catch_exception (); + if (err) return err; bzero (di->di_shortlink + length, np->dn_stat.st_size - length); diskfs_end_catch_exception (); -- cgit v1.2.3 From 7605778aa6ae9594482df2001af816e568eb9745 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 20 Jun 1995 15:51:08 +0000 Subject: (fetch_indir_spec): Remove assignment from if test. --- ufs/bmap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/bmap.c b/ufs/bmap.c index 0b3574b8..11756a66 100644 --- a/ufs/bmap.c +++ b/ufs/bmap.c @@ -1,5 +1,5 @@ /* Interpretation of indirect block structure - Copyright (C) 1994 Free Software Foundation, Inc. + Copyright (C) 1994, 1995 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -32,7 +32,8 @@ fetch_indir_spec (struct node *np, volatile daddr_t lbn, error_t err; daddr_t *siblock; - if (err = diskfs_catch_exception ()) + err = diskfs_catch_exception (); + if (err) return err; indirs[0].offset = -2; -- cgit v1.2.3 From 84752530e00bd9cbd7d1864154802b0261a15df5 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 20 Jun 1995 16:02:30 +0000 Subject: (ffs_realloccg): Fix typo. --- ufs/alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index add588ee..8f6a5baf 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -239,7 +239,7 @@ ffs_realloccg(register struct node *np, */ cg = dtog(fs, bprev); bno = ffs_fragextend(np, cg, (long)bprev, osize, nsize); - if (bno) + if (bno) { assert (bno == bprev); spin_unlock (&alloclock); np->dn_stat.st_blocks += btodb(nsize - osize); -- cgit v1.2.3 From bbb64744674f66556e4edf9082a11c7151876f7f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 20 Jun 1995 16:07:20 +0000 Subject: (diskfs_grow): Provide initialization of POKE_OFF. --- ufs/sizes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 8657ce13..62360e3c 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -355,7 +355,7 @@ diskfs_grow (struct node *np, int size, osize; error_t err; struct dinode *di = dino (np->dn->number); - off_t poke_off; + off_t poke_off = 0; size_t poke_len = 0; /* Zero an sblock->fs_bsize piece of disk starting at BNO, -- cgit v1.2.3 From 0c65f6707ccf315961f964c55f692e08dd894ac1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 16:19:57 +0000 Subject: (diskfs_lookup): Provide initialization for BUFLEN. (diskfs_direnter): Move assignment out of if test. --- ufs/dir.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index aeaa5abc..1d7004d8 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994 Free Software Foundation + Copyright (C) 1994, 1995 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -96,7 +96,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, int retry_dotdot = 0; memory_object_t memobj; vm_address_t buf = 0; - vm_size_t buflen; + vm_size_t buflen = 0; int blockaddr; int idx; @@ -520,11 +520,14 @@ diskfs_direnter(struct node *dp, oldsize = dp->dn_stat.st_size; while (oldsize + DIRBLKSIZ > dp->allocsize) - if (err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred)) - { - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - return err; - } + { + err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred); + if (err) + { + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + return err; + } + } new = (struct directory_entry *) (ds->mapbuf + oldsize); -- cgit v1.2.3 From 2f234620dce0c51e6f779fc3612ad3308c814a48 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 17:20:21 +0000 Subject: (diskfs_truncate): Use ports reference calls directly instead of pager wrappers. --- ufs/sizes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 62360e3c..0e6b893e 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -92,7 +92,7 @@ diskfs_truncate (struct node *np, spin_lock (&node2pagelock); upi = np->dn->fileinfo; if (upi) - pager_reference (upi->p); + ports_port_ref (upi->p); spin_unlock (&node2pagelock); if (upi) @@ -106,7 +106,7 @@ diskfs_truncate (struct node *np, mach_port_deallocate (mach_task_self (), obj); pager_flush_some (upi->p, round_page (length), np->allocsize - length, 1); - pager_unreference (upi->p); + ports_port_deref (upi->p); } rwlock_writer_lock (&np->dn->allocptrlock); @@ -263,13 +263,13 @@ diskfs_truncate (struct node *np, spin_lock (&node2pagelock); upi = np->dn->fileinfo; if (upi) - pager_reference (upi->p); + ports_port_ref (upi->p); spin_unlock (&node2pagelock); if (upi) { pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY, 0); - pager_unreference (upi->p); + ports_port_deref (upi->p); } return err; -- cgit v1.2.3 From a5e9c6b33951823a7bdd22dde0d6fe592068d9f8 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 17:20:53 +0000 Subject: (pager_bucket): New variable. (create_disk_pager): Provide pager_bucket in call to pager_create. (diskfs_get_filemap): Likewise. (diskfs_file_update): Use ports reference calls directly instead of pager wrappers. --- ufs/pager.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 3e9747b8..935983f5 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -30,6 +30,8 @@ spin_lock_t node2pagelock = SPIN_LOCK_INITIALIZER; #define MAY_CACHE 1 #endif +struct port_bucket *pager_bucket; + /* Find the location on disk of page OFFSET in pager UPI. Return the disk address (in disk block) in *ADDR. If *NPLOCK is set on return, then release that mutex after I/O on the data has @@ -383,7 +385,8 @@ create_disk_pager () diskpager = malloc (sizeof (struct user_pager_info)); diskpager->type = DISK; diskpager->np = 0; - diskpager->p = pager_create (diskpager, MAY_CACHE, MEMORY_OBJECT_COPY_NONE); + diskpager->p = pager_create (diskpager, pager_bucket, + MAY_CACHE, MEMORY_OBJECT_COPY_NONE); diskpagerport = pager_get_port (diskpager->p); mach_port_insert_right (mach_task_self (), diskpagerport, diskpagerport, MACH_MSG_TYPE_MAKE_SEND); @@ -401,13 +404,13 @@ diskfs_file_update (struct node *np, spin_lock (&node2pagelock); upi = np->dn->fileinfo; if (upi) - pager_reference (upi->p); + ports_port_ref (upi->p); spin_unlock (&node2pagelock); if (upi) { pager_sync (upi->p, wait); - pager_unreference (upi->p); + port_port_deref (upi->p); } for (d = np->dn->dirty; d; d = tmp) @@ -442,7 +445,8 @@ diskfs_get_filemap (struct node *np) upi->type = FILE_DATA; upi->np = np; diskfs_nref_light (np); - upi->p = pager_create (upi, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); + upi->p = pager_create (upi, pager_bucket, + MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); np->dn->fileinfo = upi; spin_lock (&pagerlistlock); -- cgit v1.2.3 From 08518ce71e29f27ff5d1dc4d0de1ba5438c44931 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 17:22:16 +0000 Subject: (create_disk_pager): Initialize pager_bucket. --- ufs/pager.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 935983f5..cdfecf95 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -382,6 +382,8 @@ pager_clear_user_data (struct user_pager_info *upi) void create_disk_pager () { + pager_bucket = ports_create_bucket (); + diskpager = malloc (sizeof (struct user_pager_info)); diskpager->type = DISK; diskpager->np = 0; -- cgit v1.2.3 From 0a05b968659e214011eb69e7ff262cde98d84b5d Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 17:27:03 +0000 Subject: (create_disk_pager): Fork off service thread for pager ports. --- ufs/pager.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index cdfecf95..d972eb0f 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -382,8 +382,21 @@ pager_clear_user_data (struct user_pager_info *upi) void create_disk_pager () { + void + thread_function (any_t foo __attribute__ ((unused))) + { + for (;;) + ports_manage_port_operations_multithread (pager_bucket, + pager_demuxer, + 1000 * 60 * 2, + 1000 * 60 * 10, + 1, MACH_PORT_NULL); + } + pager_bucket = ports_create_bucket (); + cthread_detach (cthread_fork ((cthread_fn_t) thread_function, (any_t) 0)); + diskpager = malloc (sizeof (struct user_pager_info)); diskpager->type = DISK; diskpager->np = 0; -- cgit v1.2.3 From 06f996372c9d0e6d2d1ec5800eb4f0f9cfab1cc3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 17:33:49 +0000 Subject: (drop_pager_softrefs): Use ports reference calls directly instead of pager wrappers. (allow_pager_softrefs): Likewise. (pager_traverse): Likewise. (diskfs_file_update): Fix typo. --- ufs/pager.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index d972eb0f..a430c761 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -425,7 +425,7 @@ diskfs_file_update (struct node *np, if (upi) { pager_sync (upi->p, wait); - port_port_deref (upi->p); + ports_port_deref (upi->p); } for (d = np->dn->dirty; d; d = tmp) @@ -491,13 +491,13 @@ drop_pager_softrefs (struct node *np) spin_lock (&node2pagelock); upi = np->dn->fileinfo; if (upi) - pager_reference (upi->p); + ports_port_ref (upi->p); spin_unlock (&node2pagelock); if (MAY_CACHE && upi) pager_change_attributes (upi->p, 0, MEMORY_OBJECT_COPY_DELAY, 0); if (upi) - pager_unreference (upi->p); + ports_port_deref (upi->p); } /* Call this when we should turn on caching because it's no longer @@ -510,13 +510,13 @@ allow_pager_softrefs (struct node *np) spin_lock (&node2pagelock); upi = np->dn->fileinfo; if (upi) - pager_reference (upi->p); + ports_port_ref (upi->p); spin_unlock (&node2pagelock); if (MAY_CACHE && upi) pager_change_attributes (upi->p, 1, MEMORY_OBJECT_COPY_DELAY, 0); if (upi) - pager_unreference (upi->p); + ports_port_deref (upi->p); } /* Call this to find out the struct pager * corresponding to the @@ -547,7 +547,7 @@ pager_traverse (void (*func)(struct user_pager_info *)) i = alloca (sizeof (struct item)); i->next = list; list = i; - pager_reference (p->p); + ports_port_ref (p->p); i->p = p; } spin_unlock (&pagerlistlock); @@ -555,7 +555,7 @@ pager_traverse (void (*func)(struct user_pager_info *)) for (i = list; i; i = i->next) { (*func)(i->p); - pager_unreference (i->p->p); + ports_port_deref (i->p->p); } (*func)(diskpager); -- cgit v1.2.3 From 8863b992cab5e2aa552f043f3ccf6a9f77fc86b7 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 18:49:52 +0000 Subject: (pager_clear_user_data): Don't maintain pager linked list. (diskfs_get_filemap): Don't maintain pager linked list. (pager_dropweak): New function. (pager_traverse): Delete function. (diskfs_shutdown_pager): Use ports_bucket_iterate instead of pager_traverse. (diskfs_sync_everything): Use ports_bucket_iterate instead of pager_traverse. --- ufs/pager.c | 73 ++++++++++++++++--------------------------------------------- 1 file changed, 19 insertions(+), 54 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index a430c761..ea5c1e66 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -19,9 +19,6 @@ #include #include -spin_lock_t pagerlistlock = SPIN_LOCK_INITIALIZER; -struct user_pager_info *filepagerlist; - spin_lock_t node2pagelock = SPIN_LOCK_INITIALIZER; #ifdef DONT_CACHE_MEMORY_OBJECTS @@ -367,15 +364,16 @@ pager_clear_user_data (struct user_pager_info *upi) upi->np->dn->fileinfo = 0; spin_unlock (&node2pagelock); diskfs_nrele_light (upi->np); - spin_lock (&pagerlistlock); - *upi->prevp = upi->next; - if (upi->next) - upi->next->prevp = upi->prevp; - spin_unlock (&pagerlistlock); } free (upi); } +void +pager_dropweak (struct user_pager_info *upi __attribute__ ((unused))) +{ +} + + /* Create a the DISK pager, initializing DISKPAGER, and DISKPAGERPORT */ @@ -463,14 +461,6 @@ diskfs_get_filemap (struct node *np) upi->p = pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); np->dn->fileinfo = upi; - - spin_lock (&pagerlistlock); - upi->next = filepagerlist; - upi->prevp = &filepagerlist; - if (upi->next) - upi->next->prevp = &upi->next; - filepagerlist = upi; - spin_unlock (&pagerlistlock); } right = pager_get_port (np->dn->fileinfo->p); spin_unlock (&node2pagelock); @@ -531,64 +521,39 @@ diskfs_get_filemap_pager_struct (struct node *np) return np->dn->fileinfo->p; } -/* Call function FUNC (which takes one argument, a pager) on each pager, with - all file pagers being processed before the disk pager. Make the calls - while holding no locks. */ -static void -pager_traverse (void (*func)(struct user_pager_info *)) -{ - struct user_pager_info *p; - struct item {struct item *next; struct user_pager_info *p;} *list = 0; - struct item *i; - - spin_lock (&pagerlistlock); - for (p = filepagerlist; p; p = p->next) - { - i = alloca (sizeof (struct item)); - i->next = list; - list = i; - ports_port_ref (p->p); - i->p = p; - } - spin_unlock (&pagerlistlock); - - for (i = list; i; i = i->next) - { - (*func)(i->p); - ports_port_deref (i->p->p); - } - - (*func)(diskpager); -} - /* Shutdown all the pagers. */ void diskfs_shutdown_pager () { - void shutdown_one (struct user_pager_info *p) + error_t shutdown_one (struct pager *p) { - pager_shutdown (p->p); + /* Make sure the disk pager is done last. */ + if (p->upi != diskpager) + pager_shutdown (p); + return 0; } copy_sblock (); write_all_disknodes (); - pager_traverse (shutdown_one); + ports_bucket_iterate (pager_bucket, shutdown_one); + pager_shutdown (diskpager->p); } /* Sync all the pagers. */ void diskfs_sync_everything (int wait) { - void sync_one (struct user_pager_info *p) + error_t sync_one (struct pager *p) { + /* Make sure the disk pager is done last. */ if (p != diskpager) - pager_sync (p->p, wait); - else - sync_disk (wait); + pager_sync (p, wait); + return 0; } copy_sblock (); write_all_disknodes (); - pager_traverse (sync_one); + ports_bucket_iterate (pager_bucket, sync_one); + sync_disk (wait); } -- cgit v1.2.3 From 7e6d5b48ba4bc11693a2c61908fb1a8693c96bb0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 18:50:31 +0000 Subject: (struct user_pager_info): Drop members next and prevp. --- ufs/ufs.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index a7c9a891..aaaf4daa 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1994 Free Software Foundation + Copyright (C) 1994, 1995 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -157,7 +157,6 @@ struct user_pager_info FILE_DATA, } type; struct pager *p; - struct user_pager_info *next, **prevp; }; struct user_pager_info *diskpager; -- cgit v1.2.3 From d19a8d58ffb63f921c279e60a3fbb7092952527e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 18:57:36 +0000 Subject: (diskfs_shutdown_pager): Typos. --- ufs/pager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index ea5c1e66..5237c671 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -528,7 +528,7 @@ diskfs_shutdown_pager () error_t shutdown_one (struct pager *p) { /* Make sure the disk pager is done last. */ - if (p->upi != diskpager) + if (p != diskpager->p) pager_shutdown (p); return 0; } @@ -546,7 +546,7 @@ diskfs_sync_everything (int wait) error_t sync_one (struct pager *p) { /* Make sure the disk pager is done last. */ - if (p != diskpager) + if (p != diskpager->p) pager_sync (p, wait); return 0; } -- cgit v1.2.3 From 8cced7ac1796db55319a593bb60586f68d567ecb Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 19:11:17 +0000 Subject: (diskfs_sync_everything, diskfs_shutdown_pager): Conform to prototype. --- ufs/pager.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 5237c671..938e1127 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -525,8 +525,9 @@ diskfs_get_filemap_pager_struct (struct node *np) void diskfs_shutdown_pager () { - error_t shutdown_one (struct pager *p) + error_t shutdown_one (void *arg) { + struct pager *p = arg; /* Make sure the disk pager is done last. */ if (p != diskpager->p) pager_shutdown (p); @@ -543,8 +544,9 @@ diskfs_shutdown_pager () void diskfs_sync_everything (int wait) { - error_t sync_one (struct pager *p) + error_t sync_one (void *arg) { + struct pager *p = arg; /* Make sure the disk pager is done last. */ if (p != diskpager->p) pager_sync (p, wait); -- cgit v1.2.3 From 6add63967766c1078cd6c8962371c284057a192d Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Jun 1995 15:41:01 +0000 Subject: (main): Have main thread exit when done instead of calling a diskfs function. --- ufs/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index d5699d51..7f507351 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994 Free Software Foundation + Copyright (C) 1994, 1995 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -261,8 +261,8 @@ main (int argc, char **argv) /* We are the bootstrap filesystem; do special boot-time setup. */ diskfs_start_bootstrap (argv); - /* Now become a generic request thread. */ - diskfs_main_request_loop (); + /* And this thread is done with its work. */ + cthread_exit (0); } -- cgit v1.2.3 From b7e13bdf41a7c95aa9c2b7981c1e2f24e077d90e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Jun 1995 15:41:32 +0000 Subject: (HURDLIBS): Add libihash. --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index d351caab..04bb15fd 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -26,7 +26,7 @@ REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ ../hurd/ioserver.h ../hurd/fshelp.h #HURDLIBS = libdiskfs libports libdiskfs libpager libioserver \ # libfshelp libdiskfs libthreads libports -HURDLIBS = libdiskfs libports libpager libioserver libfshelp libthreads +HURDLIBS = libdiskfs libports libpager libioserver libfshelp libthreads libihash LDFLAGS = -Wl,--no-keep-memory target = ufs -- cgit v1.2.3 From 0740779ab1fda6298869b58ae3a6ad9a8440b2c8 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Jun 1995 16:05:53 +0000 Subject: (thread_cancel): New function (HACK). --- ufs/main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 7f507351..b7a795f0 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -286,3 +286,7 @@ diskfs_init_completed () } +void +thread_cancel (mach_thread_t foo __attribute__ ((unused))) +{ +} -- cgit v1.2.3 From 2d9280333f1bf42d6a49f7a2c9772b76dee62700 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Jun 1995 16:07:56 +0000 Subject: (thread_cancel): Typo. --- ufs/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index b7a795f0..9541c956 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -287,6 +287,6 @@ diskfs_init_completed () void -thread_cancel (mach_thread_t foo __attribute__ ((unused))) +thread_cancel (thread_t foo __attribute__ ((unused))) { } -- cgit v1.2.3 From 7adec76824d5f9dfc7e46a114b03521aa877d505 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 22 Jun 1995 17:29:12 +0000 Subject: (thread_function): Move thread_function to be non-local, of course, because it needs to live even after create_disk_pager returns. --- ufs/pager.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 938e1127..355af46c 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -375,22 +375,21 @@ pager_dropweak (struct user_pager_info *upi __attribute__ ((unused))) +static void +thread_function (any_t foo __attribute__ ((unused))) +{ + for (;;) + ports_manage_port_operations_multithread (pager_bucket, + pager_demuxer, + 1000 * 60 * 2, + 1000 * 60 * 10, + 1, MACH_PORT_NULL); +} /* Create a the DISK pager, initializing DISKPAGER, and DISKPAGERPORT */ void create_disk_pager () { - void - thread_function (any_t foo __attribute__ ((unused))) - { - for (;;) - ports_manage_port_operations_multithread (pager_bucket, - pager_demuxer, - 1000 * 60 * 2, - 1000 * 60 * 10, - 1, MACH_PORT_NULL); - } - pager_bucket = ports_create_bucket (); cthread_detach (cthread_fork ((cthread_fn_t) thread_function, (any_t) 0)); -- cgit v1.2.3 From 55e97e3364d6dc1541814444f4116974c2013637 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Jun 1995 00:17:38 +0000 Subject: (diskfs_pager_users): New function. --- ufs/pager.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 355af46c..34c4d232 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -508,6 +508,73 @@ allow_pager_softrefs (struct node *np) ports_port_deref (upi->p); } +/* Tell diskfs if there are pagers exported, and if none, then + prevent any new ones from showing up. */ +int +diskfs_pager_users () +{ + int npagers; + + error_t block_cache (void *arg) + { + struct pager *p = arg; + + pager_change_attributes (p, 0, MEMORY_OBJECT_COPY_DELAY, 1); + return 0; + } + + error_t enable_cache (void *arg) + { + struct pager *p = arg; + struct user_pager_info *upi = pager_get_upi (p); + + pager_change_attributes (p, 1, MEMORY_OBJECT_COPY_DELAY, 0); + + /* It's possible that we didn't have caching on before, because + the user here is the only reference to the underlying node + (actually, that's quite likely inside this particular + routine), and if that node has no links. So dinkle the node + ref counting scheme here, which will cause caching to be + turned off, if that's really necessary. */ + if (upi->pager_type == FILE_DATA) + { + diskfs_nref (upi->np); + diskfs_nrele (upi->np); + } + + return 0; + } + + npagers = ports_count_bucket (pager_bucket); + if (npagers == 0) + return 0; + + if (MAY_CACHE == 0) + { + ports_enable_bucket (pager_bucket); + return 1 + } + + /* Loop through the pagers and turn off caching one by one, + synchronously. That should cause termination of each pager. */ + ports_bucket_iterate (pager_bucket, block_cache); + + /* Give it a second; the kernel doesn't actually shutdown + immediately. XXX */ + sleep (1); + + npagers = ports_count_bucket (pager_bucket); + + if (npagers == 0) + return 0; + + /* Darn, there are actual honest users. Turn caching back on, + and return failure. */ + ports_bucket_iterate (pager_bucket, enable_cache); + return 1; +} + + /* Call this to find out the struct pager * corresponding to the FILE_DATA pager of inode IP. This should be used *only* as a subsequent argument to register_memory_fault_area, and will be deleted when -- cgit v1.2.3 From 91bc35fb4300a4da5474c68f6c6558ca8533f7ba Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 27 Jun 1995 00:20:51 +0000 Subject: (diskfs_pager_users/enable_cache): Fix typo. Include . --- ufs/pager.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 34c4d232..de5e1d18 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -18,6 +18,7 @@ #include "ufs.h" #include #include +#include spin_lock_t node2pagelock = SPIN_LOCK_INITIALIZER; @@ -536,7 +537,7 @@ diskfs_pager_users () routine), and if that node has no links. So dinkle the node ref counting scheme here, which will cause caching to be turned off, if that's really necessary. */ - if (upi->pager_type == FILE_DATA) + if (upi->type == FILE_DATA) { diskfs_nref (upi->np); diskfs_nrele (upi->np); @@ -552,7 +553,7 @@ diskfs_pager_users () if (MAY_CACHE == 0) { ports_enable_bucket (pager_bucket); - return 1 + return 1; } /* Loop through the pagers and turn off caching one by one, -- cgit v1.2.3 From 0cbb481f3c31a306d1df4944a4668780258b8bde Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 6 Jul 1995 19:43:11 +0000 Subject: Removed dependencies that are now automatically generated. --- bsdfsck/Makefile | 4 +--- ufs-fsck/Makefile | 4 +--- ufs/Makefile | 12 ------------ 3 files changed, 2 insertions(+), 18 deletions(-) (limited to 'ufs') diff --git a/bsdfsck/Makefile b/bsdfsck/Makefile index 28adbbd1..6bc18889 100644 --- a/bsdfsck/Makefile +++ b/bsdfsck/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 1994 Free Software Foundation +# Copyright (C) 1994, 1995 Free Software Foundation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -27,7 +27,5 @@ target = bsdfsck include ../Makeconf -$(OBJS): fsck.h - tables.o: ../ufs/tables.c $(CC) $(CFLAGS) -c -o $@ $< diff --git a/ufs-fsck/Makefile b/ufs-fsck/Makefile index ef8919a9..d581cda3 100644 --- a/ufs-fsck/Makefile +++ b/ufs-fsck/Makefile @@ -1,5 +1,5 @@ # -# Copyright (C) 1994 Free Software Foundation +# Copyright (C) 1994, 1995 Free Software Foundation # Written by Michael I. Bushnell. # # This file is part of the GNU Hurd. @@ -29,7 +29,5 @@ target = fsck include ../Makeconf -$(OBJS): fsck.h - tables.o: ../ufs/tables.c $(CC) $(CFLAGS) -c -o $@ $< diff --git a/ufs/Makefile b/ufs/Makefile index 04bb15fd..33582409 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -36,15 +36,3 @@ vpath %.c ../lib include ../Makeconf -$(OBJS): ufs.h -$(OBJS): $(REMHDRS) -alloc.o: fs.h dinode.h -consts.o: dinode.h -dir.o: dir.h -hyper.o: fs.h -inode.o: dinode.h fs.h -main.o: fs.h -pager.o: fs.h dinode.h -sizes.o: fs.h dinode.h -subr.o: fs.h -tables.o: fs.h -- cgit v1.2.3 From a618e283c3ccc837ed7c2aac5ee5c3d7a92160c9 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 17 Jul 1995 18:35:14 +0000 Subject: (thread_function): Don't have any global timeout here; we don't use it anyhow. --- ufs/pager.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index de5e1d18..52e77f05 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -380,10 +380,8 @@ static void thread_function (any_t foo __attribute__ ((unused))) { for (;;) - ports_manage_port_operations_multithread (pager_bucket, - pager_demuxer, - 1000 * 60 * 2, - 1000 * 60 * 10, + ports_manage_port_operations_multithread (pager_bucket, pager_demuxer, + 1000 * 60 * 2, 0, 1, MACH_PORT_NULL); } -- cgit v1.2.3 From 13e34674ce5c20de9a499c7a25f26a57a0ed9a44 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 21 Jul 1995 21:51:25 +0000 Subject: (diskfs_get_filemap): Free initial reference created by pager_create. --- ufs/pager.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 52e77f05..139e5723 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -459,8 +459,16 @@ diskfs_get_filemap (struct node *np) upi->p = pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); np->dn->fileinfo = upi; + right = pager_get_port (np->dn->fileinfo->p); + ports_port_deref (np->dn->fileinfo->p); } - right = pager_get_port (np->dn->fileinfo->p); + else + /* There is a race condition here. If there are no references + to NP->dn->fileinfo->p, then the clean routine might be + blocked trying to get into node2pagelock, and this call is + invalid. XXX */ + right = pager_get_port (np->dn->fileinfo->p); + spin_unlock (&node2pagelock); mach_port_insert_right (mach_task_self (), right, right, -- cgit v1.2.3 From 9003138387cca2e16d004b952c5d0f65a9364cc0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 21 Jul 1995 21:58:08 +0000 Subject: (diskfs_get_filemap): Drop initial reference created by pager_create. (pager_clear_user_data): Only clear UPI->np->dn->fileinfo if it still points to us. --- ufs/pager.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 139e5723..cac6836a 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -362,7 +362,8 @@ pager_clear_user_data (struct user_pager_info *upi) if (upi->type == FILE_DATA) { spin_lock (&node2pagelock); - upi->np->dn->fileinfo = 0; + if (upi->np->dn->fileinfo == upi) + upi->np->dn->fileinfo = 0; spin_unlock (&node2pagelock); diskfs_nrele_light (upi->np); } @@ -450,24 +451,30 @@ diskfs_get_filemap (struct node *np) || np->dn_stat.st_size >= sblock->fs_maxsymlinklen))); spin_lock (&node2pagelock); - if (!np->dn->fileinfo) - { - upi = malloc (sizeof (struct user_pager_info)); - upi->type = FILE_DATA; - upi->np = np; - diskfs_nref_light (np); - upi->p = pager_create (upi, pager_bucket, - MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); - np->dn->fileinfo = upi; - right = pager_get_port (np->dn->fileinfo->p); - ports_port_deref (np->dn->fileinfo->p); - } - else - /* There is a race condition here. If there are no references - to NP->dn->fileinfo->p, then the clean routine might be - blocked trying to get into node2pagelock, and this call is - invalid. XXX */ - right = pager_get_port (np->dn->fileinfo->p); + do + if (!np->dn->fileinfo) + { + upi = malloc (sizeof (struct user_pager_info)); + upi->type = FILE_DATA; + upi->np = np; + diskfs_nref_light (np); + upi->p = pager_create (upi, pager_bucket, + MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); + np->dn->fileinfo = upi; + right = pager_get_port (np->dn->fileinfo->p); + ports_port_deref (np->dn->fileinfo->p); + } + else + { + /* Because NP->dn->fileinfo->p is not a real reference, + this might be nearly deallocated. If that's so, then + the port right will be null. In that case, clear here + and loop. The deallocation will complete separately. */ + right = pager_get_port (np->dn->fileinfo->p); + if (right == MACH_PORT_NULL) + np->dn->fileinfo = 0; + } + while (right == MACH_PORT_NULL); spin_unlock (&node2pagelock); -- cgit v1.2.3 From e22e0f279d0f5c7c5ad18df7f8c12ed610743c1c Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 24 Aug 1995 14:23:29 +0000 Subject: (ufs): Add explicit dependencies. (HURDLIBS, LDFLAGS, REMHDRS): Removed. Rules associated with ../lib removed. --- ufs/Makefile | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 33582409..a7763efc 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -18,21 +18,13 @@ dir := ufs makemode := server +target = ufs SRCS = alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c bmap.c pokeloc.c -OBJS = $(SRCS:.c=.o) LCLHDRS = ufs.h fs.h dinode.h dir.h -REMHDRS = ../hurd/diskfs.h ../hurd/ports.h ../hurd/pager.h\ - ../hurd/ioserver.h ../hurd/fshelp.h -#HURDLIBS = libdiskfs libports libdiskfs libpager libioserver \ -# libfshelp libdiskfs libthreads libports -HURDLIBS = libdiskfs libports libpager libioserver libfshelp libthreads libihash -LDFLAGS = -Wl,--no-keep-memory -target = ufs -CPPFLAGS += -I../lib -CPPFLAGS += $(CPPFLAGS-$(notdir $<)) -vpath %.c ../lib +OBJS = $(SRCS:.c=.o) -include ../Makeconf +ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libioserver/libioserver.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a +include ../Makeconf -- cgit v1.2.3 From 4d67eb6e36ed6ebf0dcd8a2b8eecfe29f1b4f4f4 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 25 Aug 1995 21:15:41 +0000 Subject: (indir_release): When freeing direct blocks mentioned in a single indirect block, or single indirect blocks mentioned in a double, only call the free routine (ffs_blkfree or indir_release, respectively) if the block is actually allocated. --- ufs/sizes.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 0e6b893e..8fc0b029 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -153,11 +153,12 @@ diskfs_truncate (struct node *np, { daddr_t *sindir = indir_block (indirs[1].bno); for (i = indirs[0].offset + 1; i < NINDIR (sblock); i++) - { - ffs_blkfree (np, sindir[i], sblock->fs_bsize); - sindir[i] = 0; - blocksfreed += btodb (sblock->fs_bsize); - } + if (sindir[i]) + { + ffs_blkfree (np, sindir[i], sblock->fs_bsize); + sindir[i] = 0; + blocksfreed += btodb (sblock->fs_bsize); + } record_poke (sindir, sblock->fs_bsize); } } @@ -180,10 +181,11 @@ diskfs_truncate (struct node *np, { daddr_t *dindir = indir_block (indirs[2].bno); for (i = indirs[1].offset + 1; i < NINDIR (sblock); i++) - { - blocksfreed += indir_release (np, dindir[i], INDIR_SINGLE); - dindir[i] = 0; - } + if (dindir[i]) + { + blocksfreed += indir_release (np, dindir[i], INDIR_SINGLE); + dindir[i] = 0; + } record_poke (dindir, sblock->fs_bsize); } } -- cgit v1.2.3 From d59e4a59c84b65f3d2396816b78ae72d46f0c628 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 28 Aug 1995 21:07:31 +0000 Subject: (ufs): Depend on ../libshouldbeinlibc/libshouldbeinlibc.a. --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index a7763efc..28a30507 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -25,6 +25,6 @@ LCLHDRS = ufs.h fs.h dinode.h dir.h OBJS = $(SRCS:.c=.o) -ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libioserver/libioserver.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a +ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libioserver/libioserver.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a include ../Makeconf -- cgit v1.2.3 From b95f1f346c1db856ad260e20b9f873eae61d7f6d Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Wed, 6 Sep 1995 15:03:28 +0000 Subject: (diskfs_pager_users): Ignore the disk pager when seeing if there are any active pagers. --- ufs/pager.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index cac6836a..51cfc6f3 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -560,7 +560,7 @@ diskfs_pager_users () } npagers = ports_count_bucket (pager_bucket); - if (npagers == 0) + if (npagers <= 1) return 0; if (MAY_CACHE == 0) @@ -578,8 +578,7 @@ diskfs_pager_users () sleep (1); npagers = ports_count_bucket (pager_bucket); - - if (npagers == 0) + if (npagers <= 1) return 0; /* Darn, there are actual honest users. Turn caching back on, -- cgit v1.2.3 From b6d7707a397cec1abccdf558ba180112cd04a149 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 13 Sep 1995 16:30:20 +0000 Subject: (diskfs_lookup): Don't attempt to lock NP if NPP is not set. Don't even set NP if NPP is not set; use INUM as "lookup succeeded flag" instead. Lookups for REMOVE now *must* set NPP. --- ufs/dir.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 1d7004d8..ab98d4bb 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -100,6 +100,9 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, int blockaddr; int idx; + if (type == REMOVE) + assert (npp); + if (npp) *npp = 0; @@ -166,7 +169,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, think about that as an error yet. */ err = 0; - if (inum) + if (inum && npp) { if (namelen != 2 || name[0] != '.' || name[1] != '.') { @@ -242,15 +245,15 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, /* If we will be modifying the directory, make sure it's allowed. */ if (type == RENAME - || (type == REMOVE && np) - || (type == CREATE && !np)) + || (type == REMOVE && inum) + || (type == CREATE && !inum)) { err = diskfs_checkdirmod (dp, np, cred); if (err) goto out; } - if ((type == CREATE || type == RENAME) && !np && ds && ds->stat == LOOKING) + if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ ds->type = CREATE; @@ -274,7 +277,8 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, if (np) { - if (err || !npp) + assert (npp); + if (err) { if (!spec_dotdot) { @@ -292,11 +296,11 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, /* We did iget */ diskfs_nput (np); } - else if (npp) + else *npp = np; } - return err ? : np ? 0 : ENOENT; + return err ? : inum ? 0 : ENOENT; } /* Scan block at address BLKADDR (of node DP; block index IDX), for -- cgit v1.2.3 From 639d32ce79bfb66727ccefd136cfb5f3486d79ec Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 13 Sep 1995 16:38:40 +0000 Subject: (diskfs_lookup): Require NPP set for RENAME too. --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index ab98d4bb..ff79cc1e 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -100,7 +100,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, int blockaddr; int idx; - if (type == REMOVE) + if ((type == REMOVE) || (type == RENAME)) assert (npp); if (npp) -- cgit v1.2.3 From efe0caaa20d0075f7232fc022e5aecc141726413 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 22 Sep 1995 17:22:34 +0000 Subject: (get_hypermetadata): Use %Zd format for result of sizeof. --- ufs/hyper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 8a556cef..36d71728 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -1,5 +1,5 @@ /* Fetching and storing the hypermetadata (superblock and cg summary info). - Copyright (C) 1994 Free Software Foundation + Copyright (C) 1994, 1995 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -44,7 +44,7 @@ get_hypermetadata (void) } if (sblock->fs_bsize < sizeof (struct fs)) { - fprintf (stderr, "Block size %ld is too small (min is %ld bytes)\n", + fprintf (stderr, "Block size %ld is too small (min is %Zd bytes)\n", sblock->fs_bsize, sizeof (struct fs)); exit (1); } @@ -52,7 +52,7 @@ get_hypermetadata (void) if (sblock->fs_maxsymlinklen > (long)MAXSYMLINKLEN) { fprintf (stderr, "Max shortcut symlinklen %ld is too big (max is %ld)\n", - sblock->fs_maxsymlinklen, MAXSYMLINKLEN); + sblock->fs_maxsymlinklen, (long)MAXSYMLINKLEN); exit (1); } -- cgit v1.2.3 From a2fb0a994b568f719ac1121cf1e85220e4c13072 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 22 Sep 1995 17:32:18 +0000 Subject: (LDFLAGS): New variable. --- ufs/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 28a30507..68c57928 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -25,6 +25,8 @@ LCLHDRS = ufs.h fs.h dinode.h dir.h OBJS = $(SRCS:.c=.o) +LDFLAGS += -static + ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libioserver/libioserver.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a include ../Makeconf -- cgit v1.2.3 From c276c3936b9485063793d51edf435589c3629d0e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 26 Sep 1995 15:54:30 +0000 Subject: (ufs_device_name): New var. --- ufs/ufs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index aaaf4daa..34608c86 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -180,6 +180,7 @@ spin_lock_t gennumberlock; u_long nextgennumber; mach_port_t ufs_device; +char *ufs_device_name; /* The compat_mode specifies whether or not we write extensions onto the disk. */ -- cgit v1.2.3 From 14f50278054b7b5dfc465cef3e5c1afde1215629 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 26 Sep 1995 15:55:36 +0000 Subject: (main): Delete var `devname'. Use `ufs_device_name' throughout instead. --- ufs/main.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 9541c956..59fb2822 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -126,7 +126,6 @@ int diskfs_readonly; void main (int argc, char **argv) { - char *devname; mach_port_t bootstrap; error_t err; int sizes[DEV_GET_SIZE_COUNT]; @@ -138,7 +137,7 @@ main (int argc, char **argv) { /* We are in a normal Hurd universe, started as a translator. */ - devname = trans_parse_args (argc, argv); + ufs_device_name = trans_parse_args (argc, argv); { /* XXX let us see errors */ @@ -152,7 +151,7 @@ main (int argc, char **argv) else { /* We are the bootstrap filesystem. */ - devname = diskfs_parse_bootargs (argc, argv); + ufs_device_name = diskfs_parse_bootargs (argc, argv); compat_mode = COMPAT_GNU; } @@ -170,24 +169,24 @@ main (int argc, char **argv) err = device_open (diskfs_master_device, (diskfs_readonly ? 0 : D_WRITE) | D_READ, - devname, &ufs_device); + ufs_device_name, &ufs_device); if (err == D_NO_SUCH_DEVICE && getpid () <= 0) { /* Prompt the user to give us another name rather than just crashing */ - printf ("Cannot open device %s\n", devname); + printf ("Cannot open device %s\n", ufs_device_name); printf ("Open instead: "); fflush (stdout); len = getline (&line, &linesz, stdin); if (len > 2) - devname = line; + ufs_device_name = line; } } while (err && err == D_NO_SUCH_DEVICE && getpid () <= 0); if (err) { - perror (devname); + perror (ufs_device_name); exit (1); } -- cgit v1.2.3 From c8ced2b9d72916cb0f7f670ca43307665fca87b4 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 26 Sep 1995 16:01:55 +0000 Subject: (diskfs_S_file_get_storage_info): New function. --- ufs/inode.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 488b2785..d6dbb1f8 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -583,3 +583,109 @@ diskfs_shutdown_soft_ports () (the only things that should be soft) XXX */ } +/* Return a description of the storage of the file. */ +/* In STORAGE_DATA are the following, in network byte order: + + Inode number (4 bytes) + disk address of transator spec (4 bytes) + disk address of inode structure (4 bytes) + offset into inode block holding inode (4 bytes) */ +void +diskfs_S_file_get_storage_info (struct protid *cred, + int *class, + int **addresses, + u_int *naddresses, + char *storage_name, + mach_port_t *storage_port, + mach_msg_type_name_t *storage_port_type, + char **storage_data, + u_int *storage_data_len) +{ + error_t err; + struct node *np; + int i; + struct dinode *di; + void *cp; + + np = cred->po->np; + mutex_lock (&np->lock); + + /* See if this file fits in the direct block pointers. If not, punt + for now. (Reading indir blocks is a pain, and I'm postponing + pain.) XXX */ + + if (np->allocsize > NDADDR * sblock->fs_bsize) + { + mutex_unlock (&np->lock); + return EINVAL; + } + + if (*naddresses < NDADDR * 2) + vm_allocate (mach_task_self (), addresses, sizeof (int) * NDADDR * 2, 1); + else + bzero (addresses, *naddresses * 2 * sizeof (int)); + *naddresses = NDADDR * 2; + + if (*storage_data_len < 4 * sizeof (int)) + vm_allocate (mach_task_self (), storage_data, sizeof (int) * 4, 1); + *storage_data_len = 4 * sizeof (int); + + di = dino (np->dn->number); + + err = diskfs_catch_exception (); + if (err) + { + mutex_unlock (&np->lock); + return err; + } + + /* Copy the block pointers */ + + if (!direct_symlink_extension + || np->dn_stat.st_size >= sblock->fs_maxsymlinklen + || !S_ISLNK (np->dn_stat.st_mode)) + { + for (i = 0; i < NDADDR; i++) + { + addresses[2 * i] = fsbtodb (di->di_db[i]); + if ((i + 1) * sblock->fs_bsize > np->allocsize) + addresses[2 * i + 1] = np->allocsize - i * sblock->fs_bsize; + else + addresses[2 * i + 1] = sblock->fs_bsize; + } + } + + /* Fill in the aux data */ + cp = *storage_data; + + *(int *)cp = htonl (np->dn->number); + cp += sizeof (int); + + *(int *)cp = htonl (di->di_trans); + cp += sizeof (int); + + *(int *)cp = htonl (fsbtodb (ino_to_fsba (sblock, np->dn->number))); + cp += sizeof (int); + + *(int *)cp = htonl (ino_to_fsbo (sblock, np->dn->number) + * sizeof (struct dinode)); + + + diskfs_end_catch_exception (); + + *class = STORAGE_DEVICE; + + strcpy (storage_name, ufs_device_name); + + if (diskfs_isuid (0, cred)) + *storage_port = ufs_device; + else + *storage_port = MACH_PORT_NULL; + *storage_port_type = MACH_MSG_TYPE_COPY_SEND; + + mutex_unlock (&np->lock); + + return 0; +} + + -- cgit v1.2.3 From 9ccc4c2d44b7ccb78ce432d0bd0b482dc9551edd Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 26 Sep 1995 19:08:05 +0000 Subject: Include . Fix trivial errors in previous change. --- ufs/inode.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index d6dbb1f8..ec4ee10b 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -19,6 +19,7 @@ #include #include #include +#include #define INOHSZ 512 #if ((INOHSZ&(INOHSZ-1)) == 0) @@ -590,7 +591,7 @@ diskfs_shutdown_soft_ports () disk address of transator spec (4 bytes) disk address of inode structure (4 bytes) offset into inode block holding inode (4 bytes) */ -void +error_t diskfs_S_file_get_storage_info (struct protid *cred, int *class, int **addresses, @@ -621,13 +622,15 @@ diskfs_S_file_get_storage_info (struct protid *cred, } if (*naddresses < NDADDR * 2) - vm_allocate (mach_task_self (), addresses, sizeof (int) * NDADDR * 2, 1); + vm_allocate (mach_task_self (), (vm_address_t *) addresses, + sizeof (int) * NDADDR * 2, 1); else bzero (addresses, *naddresses * 2 * sizeof (int)); *naddresses = NDADDR * 2; if (*storage_data_len < 4 * sizeof (int)) - vm_allocate (mach_task_self (), storage_data, sizeof (int) * 4, 1); + vm_allocate (mach_task_self (), (vm_address_t *) storage_data, + sizeof (int) * 4, 1); *storage_data_len = 4 * sizeof (int); di = dino (np->dn->number); @@ -647,11 +650,11 @@ diskfs_S_file_get_storage_info (struct protid *cred, { for (i = 0; i < NDADDR; i++) { - addresses[2 * i] = fsbtodb (di->di_db[i]); + (*addresses)[2 * i] = fsbtodb (sblock, di->di_db[i]); if ((i + 1) * sblock->fs_bsize > np->allocsize) - addresses[2 * i + 1] = np->allocsize - i * sblock->fs_bsize; + (*addresses)[2 * i + 1] = np->allocsize - i * sblock->fs_bsize; else - addresses[2 * i + 1] = sblock->fs_bsize; + (*addresses)[2 * i + 1] = sblock->fs_bsize; } } @@ -664,7 +667,7 @@ diskfs_S_file_get_storage_info (struct protid *cred, *(int *)cp = htonl (di->di_trans); cp += sizeof (int); - *(int *)cp = htonl (fsbtodb (ino_to_fsba (sblock, np->dn->number))); + *(int *)cp = htonl (fsbtodb (sblock, ino_to_fsba (sblock, np->dn->number))); cp += sizeof (int); *(int *)cp = htonl (ino_to_fsbo (sblock, np->dn->number) -- cgit v1.2.3 From 2259b90b008f59de33003044c51c73f54df0bf1c Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Wed, 4 Oct 1995 21:22:49 +0000 Subject: (parse_opt): Rearrange slightly. --- ufs/main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 59fb2822..26defc33 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -66,9 +66,13 @@ static error_t parse_opt (int opt, char *arg) { /* We currently only deal with one option... */ - if (opt != '?') - return EINVAL; - usage (0); /* never returns */ + switch (opt) + { + case '?': + usage (0); /* never returns */ + default: + return EINVAL; + } return 0; } -- cgit v1.2.3 From d9b8f15366f3b97743dc51e85d9c22c6874ad2aa Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 5 Oct 1995 00:05:02 +0000 Subject: (diskfs_set_statfs): fsys_stb_bsize -> fsys_stb_iosize. fsys_stb_fsize -> fsys_stb_bsize. --- ufs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index ec4ee10b..2c1c7278 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -471,8 +471,8 @@ error_t diskfs_set_statfs (struct fsys_statfsbuf *st) { st->fsys_stb_type = FSTYPE_UFS; - st->fsys_stb_bsize = sblock->fs_bsize; - st->fsys_stb_fsize = sblock->fs_fsize; + st->fsys_stb_iosize = sblock->fs_bsize; + st->fsys_stb_bsize = sblock->fs_fsize; st->fsys_stb_blocks = sblock->fs_dsize; st->fsys_stb_bfree = (sblock->fs_cstotal.cs_nbfree * sblock->fs_frag + sblock->fs_cstotal.cs_nffree); -- cgit v1.2.3 From 3f0f59294d186bacd41056b48ce843056bcb5316 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 7 Oct 1995 00:26:55 +0000 Subject: (diskfs_S_file_get_storage_info): Change type of ADDRESSES to off_t **, and add the BLOCK_SIZE parameter. --- ufs/inode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 2c1c7278..db1ef96d 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -594,8 +594,9 @@ diskfs_shutdown_soft_ports () error_t diskfs_S_file_get_storage_info (struct protid *cred, int *class, - int **addresses, + off_t **addresses, u_int *naddresses, + size_t *block_size, char *storage_name, mach_port_t *storage_port, mach_msg_type_name_t *storage_port_type, @@ -677,7 +678,8 @@ diskfs_S_file_get_storage_info (struct protid *cred, diskfs_end_catch_exception (); *class = STORAGE_DEVICE; - + *block_size = DEV_BSIZE; + strcpy (storage_name, ufs_device_name); if (diskfs_isuid (0, cred)) -- cgit v1.2.3 From 975e0c9d698594d76b62be79788b4a0dacecab77 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 13 Oct 1995 23:17:16 +0000 Subject: (diskfs_S_file_get_storage_info): Use DISKFS_DEVICE instead of UFS_DEVICE, and DISKFS_DEVICE_NAME instead of UFS_DEVICE_NAME. --- ufs/inode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index db1ef96d..b15c9848 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -680,10 +680,11 @@ diskfs_S_file_get_storage_info (struct protid *cred, *class = STORAGE_DEVICE; *block_size = DEV_BSIZE; - strcpy (storage_name, ufs_device_name); + if (diskfs_device_name) + strcpy (storage_name, diskfs_device_name); if (diskfs_isuid (0, cred)) - *storage_port = ufs_device; + *storage_port = diskfs_device; else *storage_port = MACH_PORT_NULL; *storage_port_type = MACH_MSG_TYPE_COPY_SEND; -- cgit v1.2.3 From f61ca041068bd161d5011d58518625f860e2cc25 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 13 Oct 1995 23:18:06 +0000 Subject: (diskfs_grow): Use diskfs_device_{read,write}_synce instead of dev_{read,write}_sync. --- ufs/sizes.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 8fc0b029..f4f81393 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -411,7 +411,7 @@ diskfs_grow (struct node *np, record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - dev_write_sync (fsbtodb (sblock, bno) + btodb (osize), + diskfs_device_write_sync (fsbtodb (sblock, bno) + btodb (osize), zeroblock, sblock->fs_bsize - osize); if (bno != old_pbn) @@ -446,7 +446,7 @@ diskfs_grow (struct node *np, record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - dev_write_sync (fsbtodb (sblock, bno) + btodb (osize), + diskfs_device_write_sync (fsbtodb (sblock, bno) + btodb (osize), zeroblock, size - osize); if (bno != old_pbn) @@ -472,7 +472,7 @@ diskfs_grow (struct node *np, record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - dev_write_sync (fsbtodb (sblock, bno), zeroblock, size); + diskfs_device_write_sync (fsbtodb (sblock, bno), zeroblock, size); } } else @@ -562,7 +562,8 @@ diskfs_grow (struct node *np, goto out; indirs[0].bno = siblock[indirs[0].offset] = bno; record_poke (siblock, sblock->fs_bsize); - dev_write_sync (fsbtodb (sblock, bno), zeroblock, sblock->fs_bsize); + diskfs_device_write_sync (fsbtodb (sblock, bno), + zeroblock, sblock->fs_bsize); } out: -- cgit v1.2.3 From 6825e15589f025492e22d89a693df7638f2cd8d3 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 13 Oct 1995 23:19:13 +0000 Subject: (pager_unlock_page, pager_write_page, pager_read_page): Use diskfs_device_{read,write}_synce instead of dev_{read,write}_sync. (pager_report_extent): Calculate the pager size. --- ufs/pager.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 51cfc6f3..3456d404 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -110,7 +110,7 @@ pager_read_page (struct user_pager_info *pager, if (addr) { - err = dev_read_sync (addr, (void *)buf, disksize); + err = diskfs_device_read_sync (addr, (void *)buf, disksize); if (!err && disksize != __vm_page_size) bzero ((void *)(*buf + disksize), __vm_page_size - disksize); *writelock = 0; @@ -148,7 +148,7 @@ pager_write_page (struct user_pager_info *pager, return err; if (addr) - err = dev_write_sync (addr, buf, disksize); + err = diskfs_device_write_sync (addr, buf, disksize); else { printf ("Attempt to write unallocated disk\n."); @@ -321,7 +321,8 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; - dev_write_sync (fsbtodb (sblock, bno), zeroblock, sblock->fs_bsize); + diskfs_device_write_sync (fsbtodb (sblock, bno), + zeroblock, sblock->fs_bsize); indirs[0].bno = siblock[indirs[0].offset] = bno; record_poke (siblock, sblock->fs_bsize); @@ -346,7 +347,7 @@ pager_report_extent (struct user_pager_info *pager, *offset = 0; if (pager->type == DISK) - *size = diskpagersize; + *size = diskfs_device_size << diskfs_log2_device_block_size; else *size = pager->np->allocsize; -- cgit v1.2.3 From c8980395c30ffeaf8709d94d931438819d1c0e09 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 13 Oct 1995 23:20:07 +0000 Subject: (diskfs_set_hypermetadata): Use diskfs_device_{read,write}_synce instead of dev_{read,write}_sync. --- ufs/hyper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 36d71728..0aab1819 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -128,11 +128,13 @@ diskfs_set_hypermetadata (int wait, int clean) bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); - err = dev_read_sync (fsbtodb (sblock, sblock->fs_csaddr), &buf, bufsize); + err = diskfs_device_read_sync (fsbtodb (sblock, sblock->fs_csaddr), + &buf, bufsize); if (!err) { bcopy (csum, (void *) buf, sblock->fs_cssize); - dev_write_sync (fsbtodb (sblock, sblock->fs_csaddr), buf, bufsize); + diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr), + buf, bufsize); csum_dirty = 0; vm_deallocate (mach_task_self (), buf, bufsize); } -- cgit v1.2.3 From 56ea0379f4e7a01374bf1de6de96cafa2d0a2bfa Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 13 Oct 1995 23:20:41 +0000 Subject: (dev_read_sync, dev_write_sync, dev_write, diskpagersize): Decls removed. --- ufs/ufs.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 34608c86..d0000e34 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -161,7 +161,6 @@ struct user_pager_info struct user_pager_info *diskpager; mach_port_t diskpagerport; -off_t diskpagersize; vm_address_t zeroblock; @@ -179,9 +178,6 @@ spin_lock_t alloclock; spin_lock_t gennumberlock; u_long nextgennumber; -mach_port_t ufs_device; -char *ufs_device_name; - /* The compat_mode specifies whether or not we write extensions onto the disk. */ enum compat_mode @@ -263,11 +259,6 @@ error_t ffs_realloccg(struct node *, daddr_t, daddr_t, error_t fetch_indir_spec (struct node *, daddr_t, struct iblock_spec *); void mark_indir_dirty (struct node *, daddr_t); -/* From devio.c: */ -error_t dev_write_sync (daddr_t addr, vm_address_t data, long len); -error_t dev_write (daddr_t addr, vm_address_t data, long len); -error_t dev_read_sync (daddr_t addr, vm_address_t *data, long len); - /* From hyper.c: */ void get_hypermetadata (void); void copy_sblock (void); -- cgit v1.2.3 From 99646ccb3e0420df928e863544995366a58f0af0 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 13 Oct 1995 23:21:22 +0000 Subject: (SRCS): Remove devio.c. --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 68c57928..a4601cce 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -19,7 +19,7 @@ dir := ufs makemode := server target = ufs -SRCS = alloc.c consts.c devio.c dir.c hyper.c inode.c main.c pager.c \ +SRCS = alloc.c consts.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c bmap.c pokeloc.c LCLHDRS = ufs.h fs.h dinode.h dir.h -- cgit v1.2.3 From cca7d86ff87cc09c30f882f49e2e13d58aec8c00 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 13 Oct 1995 23:25:14 +0000 Subject: (main): Use new handy diskfs routines and get rid of tons of junk. Main should be almost all ufs-specific now. (USAGE, usage, SHORT_OPTS, long_opts, parse_opt, trans_parse_arg): RIP. (printf_lock): Initialize. (diskfs_init_completed): Function deleted (now in libdiskfs). (thread_cancel): Function deleted. --- ufs/main.c | 213 +++++++++++-------------------------------------------------- 1 file changed, 38 insertions(+), 175 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 26defc33..f360220b 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -19,86 +19,14 @@ #include "ufs.h" #include #include +#include #include -#include #include #include #include char *ufs_version = "0.0 pre-alpha"; -/* ---------------------------------------------------------------- */ - -#define USAGE "Usage: %s [OPTION...] DEVICE\n" - -static void -usage(int status) -{ - if (status != 0) - fprintf(stderr, "Try `%s --help' for more information.\n", - program_invocation_name); - else - { - printf(USAGE, program_invocation_name); - printf("\ -\n\ - -r, --readonly disable writing to DEVICE\n\ - -w, --writable enable writing to DEVICE\n\ - -s, --sync[=INTERVAL] with an argument, sync every INTERVAL seconds,\n\ - otherwise operate in synchronous mode\n\ - -n, --nosync never sync the filesystem\n\ - --help display this help and exit\n\ - --version output version information and exit\n\ -"); - } - exit (status); -} - -#define SHORT_OPTS "" - -static struct option long_opts[] = -{ - {"help", no_argument, 0, '?'}, - {0, 0, 0, 0} -}; - -static error_t -parse_opt (int opt, char *arg) -{ - /* We currently only deal with one option... */ - switch (opt) - { - case '?': - usage (0); /* never returns */ - default: - return EINVAL; - } - return 0; -} - -/* Parse the arguments for ufs when started as a translator. */ -char * -trans_parse_args (int argc, char **argv) -{ - int argind; /* ARGV index of the first argument. */ - struct options options = - { SHORT_OPTS, long_opts, parse_opt, diskfs_standard_startup_options }; - - /* Parse our command line. */ - if (options_parse (&options, argc, argv, OPTIONS_PRINT_ERRS, &argind)) - usage (1); - - if (argc - argind != 1) - { - fprintf (stderr, USAGE, program_invocation_name); - usage (1); - } - - return argv[argind]; -} - -/* ---------------------------------------------------------------- */ - struct node *diskfs_root_node; /* Set diskfs_root_node to the root inode. */ @@ -112,7 +40,7 @@ warp_root (void) } /* XXX */ -struct mutex printf_lock; +struct mutex printf_lock = MUTEX_INITIALIZER; int printf (const char *fmt, ...) { va_list arg; @@ -126,86 +54,50 @@ int printf (const char *fmt, ...) } int diskfs_readonly; - -void + +int main (int argc, char **argv) { - mach_port_t bootstrap; error_t err; - int sizes[DEV_GET_SIZE_COUNT]; - u_int sizescnt = 2; - - mutex_init (&printf_lock); /* XXX */ + off_t disk_size; + mach_port_t bootstrap; - if (getpid () > 0) - { - /* We are in a normal Hurd universe, started as a translator. */ + argp_parse (diskfs_device_startup_argp, argc, argv, 0, 0); - ufs_device_name = trans_parse_args (argc, argv); + /* This must come after the args have been parsed, as this is where the + host priv ports are set for booting. */ + diskfs_console_stdio (); - { - /* XXX let us see errors */ - int fd = open ("/dev/console", O_RDWR); - while (fd >= 0 && fd < 2) - fd = dup(fd); - if (fd > 2) - close (fd); - } - } - else + if (diskfs_boot_flags) { /* We are the bootstrap filesystem. */ - ufs_device_name = diskfs_parse_bootargs (argc, argv); + bootstrap = MACH_PORT_NULL; + diskfs_use_mach_device = 1; compat_mode = COMPAT_GNU; } - - task_get_bootstrap_port (mach_task_self (), &bootstrap); - - /* Initialize the diskfs library. This must come before - any other diskfs call. */ - diskfs_init_diskfs (); - - do + else { - char *line = 0; - size_t linesz = 0; - ssize_t len; - - err = device_open (diskfs_master_device, - (diskfs_readonly ? 0 : D_WRITE) | D_READ, - ufs_device_name, &ufs_device); - if (err == D_NO_SUCH_DEVICE && getpid () <= 0) - { - /* Prompt the user to give us another name rather - than just crashing */ - printf ("Cannot open device %s\n", ufs_device_name); - printf ("Open instead: "); - fflush (stdout); - len = getline (&line, &linesz, stdin); - if (len > 2) - ufs_device_name = line; - } + task_get_bootstrap_port (mach_task_self (), &bootstrap); + if (bootstrap == MACH_PORT_NULL) + error (2, 0, "Must be started as a translator"); } - while (err && err == D_NO_SUCH_DEVICE && getpid () <= 0); - + + /* Initialize the diskfs library. Must come before any other diskfs call. */ + diskfs_init_diskfs (); + + err = diskfs_device_open (); if (err) - { - perror (ufs_device_name); - exit (1); - } + error (3, err, "%s", diskfs_device_arg); - /* Check to make sure device sector size is reasonable. */ - err = device_get_status (ufs_device, DEV_GET_SIZE, sizes, &sizescnt); - assert (sizescnt == DEV_GET_SIZE_COUNT); - if (sizes[DEV_GET_SIZE_RECORD_SIZE] != DEV_BSIZE) - { - fprintf (stderr, "Bad device record size %d (should be %d)\n", - sizes[DEV_GET_SIZE_RECORD_SIZE], DEV_BSIZE); - exit (1); - } - - diskpagersize = sizes[DEV_GET_SIZE_DEVICE_SIZE]; - assert (diskpagersize >= SBSIZE + SBOFF); + if (diskfs_device_block_size != DEV_BSIZE) + error (4, err, "%s: Bad device record size %d (should be %d)", + diskfs_device_arg, diskfs_device_block_size, DEV_BSIZE); + if (diskfs_log2_device_block_size == 0) + error (4, err, "%s: Device block size (%d) not a power of 2", + diskfs_device_arg, diskfs_device_block_size); + + disk_size = diskfs_device_size << diskfs_log2_device_block_size; + assert (disk_size >= SBSIZE + SBOFF); /* Map the entire disk. */ create_disk_pager (); @@ -214,7 +106,7 @@ main (int argc, char **argv) diskfs_spawn_first_thread (); err = vm_map (mach_task_self (), (vm_address_t *)&disk_image, - diskpagersize, 0, 1, diskpagerport, 0, 0, + disk_size, 0, 1, diskpagerport, 0, 0, VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), VM_INHERIT_NONE); @@ -222,13 +114,12 @@ main (int argc, char **argv) get_hypermetadata (); - if (diskpagersize < sblock->fs_size * sblock->fs_fsize) + if (disk_size < sblock->fs_size * sblock->fs_fsize) { fprintf (stderr, - "Disk size (%d) less than necessary " + "Disk size (%ld) less than necessary " "(superblock says we need %ld)\n", - sizes[DEV_GET_SIZE_DEVICE_SIZE], - sblock->fs_size * sblock->fs_fsize); + disk_size, sblock->fs_size * sblock->fs_fsize); exit (1); } @@ -258,38 +149,10 @@ main (int argc, char **argv) /* Now that we are all set up to handle requests, and diskfs_root_node is set properly, it is safe to export our fsys control port to the outside world. */ - (void) diskfs_startup_diskfs (bootstrap); - - if (bootstrap == MACH_PORT_NULL) - /* We are the bootstrap filesystem; do special boot-time setup. */ - diskfs_start_bootstrap (argv); + diskfs_startup_diskfs (bootstrap); /* And this thread is done with its work. */ cthread_exit (0); -} - - -void -diskfs_init_completed () -{ - mach_port_t proc, startup; - error_t err; - - proc = getproc (); - proc_register_version (proc, diskfs_host_priv, "ufs", HURD_RELEASE, - ufs_version); - err = proc_getmsgport (proc, 1, &startup); - if (!err) - { - startup_essential_task (startup, mach_task_self (), MACH_PORT_NULL, - "ufs", diskfs_host_priv); - mach_port_deallocate (mach_task_self (), startup); - } - mach_port_deallocate (mach_task_self (), proc); -} - -void -thread_cancel (thread_t foo __attribute__ ((unused))) -{ + return 0; } -- cgit v1.2.3 From 99e1a1cbb3b4cb72e794d48735280a106c28f1c8 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 19 Oct 1995 20:23:12 +0000 Subject: (diskfs_lookup, diskfs_dirempty): Give diskfs_get_filemap a protection arg. --- ufs/dir.c | 15 ++++++--------- ufs/sizes.c | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index ff79cc1e..f8150d64 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -95,6 +95,8 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, struct node *np = 0; int retry_dotdot = 0; memory_object_t memobj; + vm_prot_t prot = + (type == LOOKUP) ? VM_PROT_READ : (VM_PROT_READ | VM_PROT_WRITE); vm_address_t buf = 0; vm_size_t buflen = 0; int blockaddr; @@ -136,17 +138,12 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, ds->stat = LOOKING; /* Map in the directory contents. */ - memobj = diskfs_get_filemap (dp); + memobj = diskfs_get_filemap (dp, prot); buf = 0; /* We allow extra space in case we have to do an EXTEND. */ buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); - if (type == LOOKUP) - /* Map read-only; we won't be writing */ - err = vm_map (mach_task_self (), &buf, buflen, 0, 1, memobj, 0, 0, - VM_PROT_READ, VM_PROT_READ, 0); - else - err = vm_map (mach_task_self (), &buf, buflen, 0, 1, memobj, 0, 0, - VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0); + err = vm_map (mach_task_self (), + &buf, buflen, 0, 1, memobj, 0, 0, prot, prot, 0); mach_port_deallocate (mach_task_self (), memobj); inum = 0; @@ -664,7 +661,7 @@ diskfs_dirempty(struct node *dp, memory_object_t memobj; error_t err; - memobj = diskfs_get_filemap (dp); + memobj = diskfs_get_filemap (dp, VM_PROT_READ); buf = 0; err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, diff --git a/ufs/sizes.c b/ufs/sizes.c index f4f81393..0dadac28 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -101,7 +101,7 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); - obj = diskfs_get_filemap (np); + obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); poke_pages (obj, round_page (length), round_page (np->allocsize)); mach_port_deallocate (mach_task_self (), obj); pager_flush_some (upi->p, round_page (length), @@ -588,7 +588,7 @@ diskfs_grow (struct node *np, { mach_port_t obj; - obj = diskfs_get_filemap (np); + obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); poke_pages (obj, trunc_page (poke_off), round_page (poke_off + poke_len)); mach_port_deallocate (mach_task_self (), obj); -- cgit v1.2.3 From 896c358bc0391572de2a635d9c2ddd91d4a90671 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 19 Oct 1995 20:28:46 +0000 Subject: (diskfs_readonly_changed): New function. (get_hypermetadata): Move compat_mode futzing & disk size validation here from main. Only allocate SBLOCK if not already done. Deallocate any old ZEROBLOCK and CSUM storage. (zeroblock, sblock, csum): Define (were common). (diskfs_readonly_changed): New function. --- ufs/hyper.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 0aab1819..d8064a29 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -21,10 +21,22 @@ static int oldformat = 0; +vm_address_t zeroblock = 0; + +struct fs *sblock = 0; +struct csum *csum = 0; + void get_hypermetadata (void) { - sblock = malloc (SBSIZE); + if (!sblock) + sblock = malloc (SBSIZE); + + /* Free previous values. */ + if (zeroblock) + vm_deallocate (mach_task_self (), zeroblock, sblock->fs_bsize); + if (csum) + free (csum); assert (!diskfs_catch_exception ()); bcopy (disk_image + SBOFF, sblock, SBSIZE); @@ -95,7 +107,7 @@ get_hypermetadata (void) else direct_symlink_extension = 0; - csum = malloc (fsaddr (sblock, howmany (sblock->fs_cssize, + csum = malloc (fsaddr (sblock, howmany (sblock->fs_cssize, sblock->fs_fsize))); assert (!diskfs_catch_exception ()); @@ -103,6 +115,27 @@ get_hypermetadata (void) csum, fsaddr (sblock, howmany (sblock->fs_cssize, sblock->fs_fsize))); diskfs_end_catch_exception (); + + if ((diskfs_device_size << diskfs_log2_device_block_size) + < sblock->fs_size * sblock->fs_fsize) + { + fprintf (stderr, + "Disk size (%ld) less than necessary " + "(superblock says we need %ld)\n", + diskfs_device_size << diskfs_log2_device_block_size, + sblock->fs_size * sblock->fs_fsize); + exit (1); + } + + vm_allocate (mach_task_self (), &zeroblock, sblock->fs_bsize, 1); + + /* If the filesystem has new features in it, don't pay attention to + the user's request not to use them. */ + if ((sblock->fs_inodefmt == FS_44INODEFMT + || direct_symlink_extension) + && compat_mode == COMPAT_BSD42) + /* XXX should syslog to this effect */ + compat_mode = COMPAT_BSD44; } /* Write the csum data. This isn't backed by a pager because it is @@ -192,4 +225,20 @@ copy_sblock () diskfs_end_catch_exception (); } +void diskfs_readonly_changed (int readonly) +{ + vm_protect (mach_task_self (), + (vm_address_t)disk_image, + diskfs_device_size << diskfs_log2_device_block_size, + 0, VM_PROT_READ | (readonly ? 0 : VM_PROT_WRITE)); + if (readonly) + sblock_dirty = 0; + else + { + sblock->fs_clean = 0; + strcpy (sblock->fs_fsmnt, "Hurd /"); /* XXX */ + sblock_dirty = 1; + diskfs_set_hypermetadata (1, 0); + } +} -- cgit v1.2.3 From e167a21a91011a3612558160d85ce53931b47ba5 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 19 Oct 1995 20:30:59 +0000 Subject: (diskfs_get_filemap): Add PROT parameter, & use it. (diskfs_pager_users): Split out block_caching & enable_caching. (block_caching, enable_caching, diskfs_max_user_pager_prot): New functions. (flush_node_pager): New function. --- ufs/pager.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 107 insertions(+), 27 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 3456d404..10ce2a10 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -437,10 +437,40 @@ diskfs_file_update (struct node *np, diskfs_node_update (np, wait); } +/* Invalidate any pager data associated with NODE. */ +void +flush_node_pager (struct node *node) +{ + struct user_pager_info *upi; + struct disknode *dn = node->dn; + struct dirty_indir *dirty = dn->dirty; + + spin_lock (&node2pagelock); + upi = dn->fileinfo; + if (upi) + ports_port_ref (upi->p); + spin_unlock (&node2pagelock); + + if (upi) + { + pager_flush (upi->p, 1); + ports_port_deref (upi->p); + } + + dn->dirty = 0; + + while (dirty) + { + struct dirty_indir *next = dirty->next; + free (dirty); + dirty = next; + } +} + /* Call this to create a FILE_DATA pager and return a send right. - NP must be locked. */ + NP must be locked. PROT is the max protection desired. */ mach_port_t -diskfs_get_filemap (struct node *np) +diskfs_get_filemap (struct node *np, vm_prot_t prot) { struct user_pager_info *upi; mach_port_t right; @@ -458,6 +488,7 @@ diskfs_get_filemap (struct node *np) upi = malloc (sizeof (struct user_pager_info)); upi->type = FILE_DATA; upi->np = np; + upi->max_prot = prot; diskfs_nref_light (np); upi->p = pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); @@ -467,6 +498,8 @@ diskfs_get_filemap (struct node *np) } else { + np->dn->fileinfo->max_prot |= prot; + /* Because NP->dn->fileinfo->p is not a real reference, this might be nearly deallocated. If that's so, then the port right will be null. In that case, clear here @@ -523,13 +556,9 @@ allow_pager_softrefs (struct node *np) ports_port_deref (upi->p); } -/* Tell diskfs if there are pagers exported, and if none, then - prevent any new ones from showing up. */ -int -diskfs_pager_users () +static void +block_caching () { - int npagers; - error_t block_cache (void *arg) { struct pager *p = arg; @@ -538,6 +567,14 @@ diskfs_pager_users () return 0; } + /* Loop through the pagers and turn off caching one by one, + synchronously. That should cause termination of each pager. */ + ports_bucket_iterate (pager_bucket, block_cache); +} + +static void +enable_caching () +{ error_t enable_cache (void *arg) { struct pager *p = arg; @@ -560,34 +597,78 @@ diskfs_pager_users () return 0; } - npagers = ports_count_bucket (pager_bucket); + ports_bucket_iterate (pager_bucket, enable_cache); +} + +/* Tell diskfs if there are pagers exported, and if none, then + prevent any new ones from showing up. */ +int +diskfs_pager_users () +{ + int npagers = ports_count_bucket (pager_bucket); + if (npagers <= 1) return 0; - if (MAY_CACHE == 0) + if (MAY_CACHE) { - ports_enable_bucket (pager_bucket); - return 1; - } - - /* Loop through the pagers and turn off caching one by one, - synchronously. That should cause termination of each pager. */ - ports_bucket_iterate (pager_bucket, block_cache); + block_caching (); - /* Give it a second; the kernel doesn't actually shutdown - immediately. XXX */ - sleep (1); + /* Give it a second; the kernel doesn't actually shutdown + immediately. XXX */ + sleep (1); - npagers = ports_count_bucket (pager_bucket); - if (npagers <= 1) - return 0; + npagers = ports_count_bucket (pager_bucket); + if (npagers <= 1) + return 0; + + /* Darn, there are actual honest users. Turn caching back on, + and return failure. */ + enable_caching (); + } - /* Darn, there are actual honest users. Turn caching back on, - and return failure. */ - ports_bucket_iterate (pager_bucket, enable_cache); + ports_enable_bucket (pager_bucket); + return 1; } +/* Return the bitwise or of the maximum prot parameter (the second arg to + diskfs_get_filemap) for all active user pagers. */ +vm_prot_t +diskfs_max_user_pager_prot () +{ + vm_prot_t max_prot = 0; + int npagers = ports_count_bucket (pager_bucket); + + if (npagers > 1) + /* More than just the disk pager. */ + { + error_t add_pager_max_prot (void *v_p) + { + struct pager *p = v_p; + struct user_pager_info *upi = pager_get_upi (p); + if (upi->type == FILE_DATA) + max_prot |= upi->max_prot; + /* Stop iterating if MAX_PROT is as filled as it's going to get. */ + return + (max_prot == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE)) ? 1 : 0; + } + + block_caching (); /* Make any silly pagers go away. */ + + /* Give it a second; the kernel doesn't actually shutdown + immediately. XXX */ + sleep (1); + + ports_bucket_iterate (pager_bucket, add_pager_max_prot); + + enable_caching (); + } + + ports_enable_bucket (pager_bucket); + + return 1; +} /* Call this to find out the struct pager * corresponding to the FILE_DATA pager of inode IP. This should be used *only* as a subsequent @@ -638,4 +719,3 @@ diskfs_sync_everything (int wait) ports_bucket_iterate (pager_bucket, sync_one); sync_disk (wait); } - -- cgit v1.2.3 From 0794f9e13cd2cf1bfc87c81006c9c275bd337f5d Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 19 Oct 1995 20:46:01 +0000 Subject: (struct user_pager_info): Add max_prot field. (struct rwlock): Structure deleted. (rwlock_init, rwlock_reader_unlock, rwlock_reader_lock, rwlock_writer_lock, rwlock_writer_unlock): Functions deleted. (zeroblock, sblock, csum): Declare extern. (flush_node_pager, flush_pokes): New declarations. --- ufs/ufs.h | 88 +++++---------------------------------------------------------- 1 file changed, 6 insertions(+), 82 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index d0000e34..8771c372 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -32,16 +32,6 @@ /* #undef DONT_CACHE_MEMORY_OBJECTS */ -/* Simple reader/writer lock. */ -struct rwlock -{ - struct mutex master; - struct condition wakeup; - int readers; - int writers_waiting; - int readers_waiting; -}; - struct disknode { ino_t number; @@ -60,23 +50,6 @@ struct disknode struct user_pager_info *fileinfo; }; -/* Get a reader lock on reader-writer lock LOCK for disknode DN */ -extern inline void -rwlock_reader_lock (struct rwlock *lock) -{ - mutex_lock (&lock->master); - if (lock->readers == -1 || lock->writers_waiting) - { - lock->readers_waiting++; - do - condition_wait (&lock->wakeup, &lock->master); - while (lock->readers == -1 || lock->writers_waiting); - lock->readers_waiting--; - } - lock->readers++; - mutex_unlock (&lock->master); -} - /* Identifies a particular block and where it's found when interpreting indirect block structure. */ struct iblock_spec @@ -96,58 +69,6 @@ struct dirty_indir struct dirty_indir *next; }; -/* Get a writer lock on reader-writer lock LOCK for disknode DN */ -extern inline void -rwlock_writer_lock (struct rwlock *lock) -{ - mutex_lock (&lock->master); - if (lock->readers) - { - lock->writers_waiting++; - do - condition_wait (&lock->wakeup, &lock->master); - while (lock->readers); - lock->writers_waiting--; - } - lock->readers = -1; - mutex_unlock (&lock->master); -} - -/* Release a reader lock on reader-writer lock LOCK for disknode DN */ -extern inline void -rwlock_reader_unlock (struct rwlock *lock) -{ - mutex_lock (&lock->master); - assert (lock->readers); - lock->readers--; - if (lock->readers_waiting || lock->writers_waiting) - condition_broadcast (&lock->wakeup); - mutex_unlock (&lock->master); -} - -/* Release a writer lock on reader-writer lock LOCK for disknode DN */ -extern inline void -rwlock_writer_unlock (struct rwlock *lock) -{ - mutex_lock (&lock->master); - assert (lock->readers == -1); - lock->readers = 0; - if (lock->readers_waiting || lock->writers_waiting) - condition_broadcast (&lock->wakeup); - mutex_unlock (&lock->master); -} - -/* Initialize reader-writer lock LOCK */ -extern inline void -rwlock_init (struct rwlock *lock) -{ - mutex_init (&lock->master); - condition_init (&lock->wakeup); - lock->readers = 0; - lock->readers_waiting = 0; - lock->writers_waiting = 0; -} - struct user_pager_info { struct node *np; @@ -157,15 +78,16 @@ struct user_pager_info FILE_DATA, } type; struct pager *p; + vm_prot_t max_prot; }; struct user_pager_info *diskpager; mach_port_t diskpagerport; -vm_address_t zeroblock; +extern vm_address_t zeroblock; -struct fs *sblock; -struct csum *csum; +extern struct fs *sblock; +extern struct csum *csum; int sblock_dirty; int csum_dirty; @@ -278,6 +200,7 @@ void sin_unmap (struct node *); void din_unmap (struct node *); void drop_pager_softrefs (struct node *); void allow_pager_softrefs (struct node *); +void flush_node_pager (struct node *); /* From subr.c: */ void ffs_fragacct (struct fs *, int, long [], int); @@ -290,3 +213,4 @@ int scanc (u_int, u_char *, u_char [], int); /* From pokeloc.c: */ void record_poke (void *, vm_size_t); void sync_disk (int); +void flush_pokes (); -- cgit v1.2.3 From b614f2c8bb637f0e12a1786b8bb15248be441626 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 19 Oct 1995 20:47:24 +0000 Subject: (main): Always include VM_PROT_WRITE in max prot. Move stuff into get_hypermetadata. Writable init code moved to diskfs_readonly_changed. (diskfs_reload_global_state): New function. --- ufs/main.c | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index f360220b..5a447f94 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -108,39 +108,12 @@ main (int argc, char **argv) err = vm_map (mach_task_self (), (vm_address_t *)&disk_image, disk_size, 0, 1, diskpagerport, 0, 0, VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), - VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), + VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_NONE); assert (!err); get_hypermetadata (); - if (disk_size < sblock->fs_size * sblock->fs_fsize) - { - fprintf (stderr, - "Disk size (%ld) less than necessary " - "(superblock says we need %ld)\n", - disk_size, sblock->fs_size * sblock->fs_fsize); - exit (1); - } - - vm_allocate (mach_task_self (), &zeroblock, sblock->fs_bsize, 1); - - /* If the filesystem has new features in it, don't pay attention to - the user's request not to use them. */ - if ((sblock->fs_inodefmt == FS_44INODEFMT - || direct_symlink_extension) - && compat_mode == COMPAT_BSD42) - /* XXX should syslog to this effect */ - compat_mode = COMPAT_BSD44; - - if (!diskfs_readonly) - { - sblock->fs_clean = 0; - strcpy (sblock->fs_fsmnt, "Hurd /"); /* XXX */ - sblock_dirty = 1; - diskfs_set_hypermetadata (1, 0); - } - inode_init (); /* Find our root node. */ @@ -156,3 +129,12 @@ main (int argc, char **argv) return 0; } + +error_t +diskfs_reload_global_state () +{ + flush_pokes (); + pager_flush (diskpager->p, 1); + get_hypermetadata (); + return 0; +} -- cgit v1.2.3 From d77d7cbde90553aa4178cba7e1591e0e6d4818c5 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 19 Oct 1995 20:49:33 +0000 Subject: (diskfs_node_reload): New function. (iget): Move allocsize setting into read_disknode. --- ufs/inode.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index b15c9848..179a85bc 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -83,11 +83,6 @@ iget (ino_t inum, struct node **npp) spin_unlock (&diskfs_node_refcnt_lock); err = read_disknode (np); - - if (lblkno (sblock, np->dn_stat.st_size) < NDADDR) - np->allocsize = fragroundup (sblock, np->dn_stat.st_size); - else - np->allocsize = blkroundup (sblock, np->dn_stat.st_size); if (!diskfs_readonly && !np->dn_stat.st_gen) { @@ -271,6 +266,24 @@ read_disknode (struct node *np) diskfs_end_catch_exception (); if (!S_ISBLK (st->st_mode) && !S_ISCHR (st->st_mode)) st->st_rdev = 0; + + if (lblkno (sblock, np->dn_stat.st_size) < NDADDR) + np->allocsize = fragroundup (sblock, np->dn_stat.st_size); + else + np->allocsize = blkroundup (sblock, np->dn_stat.st_size); + + return 0; +} + +error_t diskfs_node_reload (struct node *node) +{ + if (node->dn->dirents) + { + free (node->dn->dirents); + node->dn->dirents = 0; + } + flush_node_pager (node); + read_disknode (node); return 0; } -- cgit v1.2.3 From 200ab835f25a0e4c5612d30fdf113e0fc62e841a Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 19 Oct 1995 20:53:28 +0000 Subject: (flush_pokes): New function. --- ufs/pokeloc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'ufs') diff --git a/ufs/pokeloc.c b/ufs/pokeloc.c index 0e7235ad..e137090f 100644 --- a/ufs/pokeloc.c +++ b/ufs/pokeloc.c @@ -47,6 +47,25 @@ record_poke (void *loc, vm_size_t length) spin_unlock (&pokelistlock); } +/* Get rid of any outstanding pokes. */ +void +flush_pokes () +{ + struct pokeloc *pl; + + spin_lock (&pokelistlock); + pl = pokelist; + pokelist = 0; + spin_unlock (&pokelistlock); + + while (pl) + { + struct pokeloc *next = pl->next; + free (pl); + pl = next; + } +} + /* Sync all the modified pieces of disk */ void sync_disk (int wait) -- cgit v1.2.3 From bc0d016208fdadf1efbd42c23015388df2718d15 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 21 Oct 1995 00:18:53 +0000 Subject: (diskfs_max_user_pager_prot): Return what we discovered, instead of 1. --- ufs/pager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 10ce2a10..87217908 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -667,7 +667,7 @@ diskfs_max_user_pager_prot () ports_enable_bucket (pager_bucket); - return 1; + return max_prot; } /* Call this to find out the struct pager * corresponding to the -- cgit v1.2.3 From b61796c023e118c77fc9e2c618d5610376095cf7 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 6 Nov 1995 21:14:46 +0000 Subject: (main): Add FLAGS arg to diskfs_startup_diskfs call. --- ufs/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 5a447f94..bb002208 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -122,7 +122,7 @@ main (int argc, char **argv) /* Now that we are all set up to handle requests, and diskfs_root_node is set properly, it is safe to export our fsys control port to the outside world. */ - diskfs_startup_diskfs (bootstrap); + diskfs_startup_diskfs (bootstrap, 0); /* And this thread is done with its work. */ cthread_exit (0); -- cgit v1.2.3 From b97f588ea5284d2a126d38953a4e373db1312772 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 6 Nov 1995 21:15:08 +0000 Subject: (diskfs_S_file_get_storage_info): Add FLAGS argument. --- ufs/inode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 179a85bc..08438e70 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -614,7 +614,8 @@ diskfs_S_file_get_storage_info (struct protid *cred, mach_port_t *storage_port, mach_msg_type_name_t *storage_port_type, char **storage_data, - u_int *storage_data_len) + u_int *storage_data_len, + int *flags) { error_t err; struct node *np; @@ -691,6 +692,7 @@ diskfs_S_file_get_storage_info (struct protid *cred, diskfs_end_catch_exception (); *class = STORAGE_DEVICE; + *flags = 0; *block_size = DEV_BSIZE; if (diskfs_device_name) -- cgit v1.2.3 From 4c972b4fb48bdb7e8177bd56b6e4b412c01ebb73 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 9 Nov 1995 19:19:06 +0000 Subject: (struct dirstat): New member `nbytes'. (dirscanblock): If DS->type is COMPRESS, still look for TAKE/SHRINK possibilities. Also, if it's COMPRESS, still look to see if the current block can be compressed with fewer byte copies. --- ufs/dir.c | 58 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index f8150d64..5906cb01 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -73,6 +73,10 @@ struct dirstat /* For stat HERE_TIS, type REMOVE, this is the address of the immediately previous direct in this directory block, or zero if this is the first. */ struct directory_entry *preventry; + + /* For stat COMPRESS, this is the number of bytes needed to be copied + in order to undertake the compression. */ + size_t nbytes; }; size_t diskfs_dirstat_size = sizeof (struct dirstat); @@ -311,17 +315,22 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, { int nfree = 0; int needed = 0; - int countup = 0; vm_address_t currentoff, prevoff; - struct directory_entry *entry; + struct directory_entry *entry = 0; int nentries = 0; - - if (ds && ds->stat == LOOKING) + size_t nbytes = 0; + int looking = 0; + int countcopies = 0; + int consider_compress = 0; + + if (ds && (ds->stat == LOOKING + || ds->stat == COMPRESS)) { - countup = 1; + looking = 1; + countcopies = 1; needed = DIRSIZ (namelen); } - + for (currentoff = blockaddr, prevoff = 0; currentoff < blockaddr + DIRBLKSIZ; prevoff = currentoff, currentoff += entry->d_reclen) @@ -341,35 +350,41 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, return ENOENT; } - if (countup) + if (looking || countcopies) { int thisfree; + /* Count how much free space this entry has in it. */ if (entry->d_ino == 0) thisfree = entry->d_reclen; else thisfree = entry->d_reclen - DIRSIZ (DIRECT_NAMLEN (entry)); + + /* If this isn't at the front of the block, then it will + have to be copied if we do a compression; count the + number of bytes there too. */ + if (countcopies && currentoff != blockaddr) + nbytes += DIRSIZ (DIRECT_NAMLEN (entry)); + if (ds->stat == COMPRESS && nbytes > ds->nbytes) + /* The previously found compress is better than + this one, so don't bother counting any more. */ + countcopies = 0; + if (thisfree >= needed) { ds->type = CREATE; ds->stat = entry->d_ino == 0 ? TAKE : SHRINK; ds->entry = entry; ds->idx = idx; - countup = 0; + looking = countcopies = 0; } else { nfree += thisfree; if (nfree >= needed) - { - ds->type = CREATE; - ds->stat = COMPRESS; - ds->entry = (struct directory_entry *) blockaddr; - ds->idx = idx; - countup = 0; - } - } + consider_compress = 1; + } } if (entry->d_ino) @@ -382,6 +397,17 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, break; } + if (consider_compress + && (ds->type == LOOKING + || (ds->type == COMPRESS && ds->nbytes > nbytes))) + { + ds->type = CREATE; + ds->stat = COMPRESS; + ds->entry = (struct directory_entry *) blockaddr; + ds->idx = idx; + ds->nbytes = nbytes; + } + if (currentoff >= blockaddr + DIRBLKSIZ) { int i; -- cgit v1.2.3 From 748c574a54af4bbc87e548b6f6bb8cfddccb6ccf Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Dec 1995 18:14:33 +0000 Subject: (diskfs_lookup): If we are returning an error, then set the dirstat to be ignored by drop_dirstat. --- ufs/dir.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 5906cb01..b2147007 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -269,7 +269,11 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, if ((err && err != ENOENT) || !ds || ds->type == LOOKUP) - vm_deallocate (mach_task_self (), buf, buflen); + { + vm_deallocate (mach_task_self (), buf, buflen); + if (ds) + ds->type = LOOKUP; /* set to be ignored by drop_dirstat */ + } else { ds->mapbuf = buf; -- cgit v1.2.3 From 8854b41ec40b311f04cf2711e50302c5c0340207 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 1 Jan 1996 21:38:04 +0000 Subject: (pager_unlock_page): When allocating block in direct array, clear it synchronously just like we do when it goes in the indirect array. --- ufs/pager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 87217908..26f5f322 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -1,5 +1,5 @@ /* Pager for ufs - Copyright (C) 1994, 1995 Free Software Foundation + Copyright (C) 1994, 1995, 1996 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -244,6 +244,8 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; assert (lblkno (sblock, address) < NDADDR); + diskfs_device_write_sync (fsbtodb (sblock, bno), + zeroblock, sblock->fs_bsize); indirs[0].bno = di->di_db[lblkno (sblock, address)] = bno; record_poke (di, sizeof (struct dinode)); } -- cgit v1.2.3 From da8b4a25a4634e497d0d7758a55f2a8818ccc469 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 5 Jan 1996 00:10:02 +0000 Subject: (main): Don't map disk image here; create_disk_pager now does it. --- ufs/main.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index bb002208..59e56df4 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -1,5 +1,5 @@ -/* - Copyright (C) 1994, 1995 Free Software Foundation +/* + Copyright (C) 1994, 1995, 1996 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -81,7 +81,7 @@ main (int argc, char **argv) if (bootstrap == MACH_PORT_NULL) error (2, 0, "Must be started as a translator"); } - + /* Initialize the diskfs library. Must come before any other diskfs call. */ diskfs_init_diskfs (); @@ -105,13 +105,6 @@ main (int argc, char **argv) /* Start the first request thread, to handle RPCs and page requests. */ diskfs_spawn_first_thread (); - err = vm_map (mach_task_self (), (vm_address_t *)&disk_image, - disk_size, 0, 1, diskpagerport, 0, 0, - VM_PROT_READ | (diskfs_readonly ? 0 : VM_PROT_WRITE), - VM_PROT_READ | VM_PROT_WRITE, - VM_INHERIT_NONE); - assert (!err); - get_hypermetadata (); inode_init (); @@ -123,14 +116,14 @@ main (int argc, char **argv) set properly, it is safe to export our fsys control port to the outside world. */ diskfs_startup_diskfs (bootstrap, 0); - + /* And this thread is done with its work. */ cthread_exit (0); return 0; } -error_t +error_t diskfs_reload_global_state () { flush_pokes (); -- cgit v1.2.3 From 1426f83a3331dc74ac9b9b5e29c78d88186adb04 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 5 Jan 1996 00:24:25 +0000 Subject: (get_hypermetadata, copy_sblock): Don't put diskfs_catch_exception () inside assert, bonehead! Use assert_perror on a variable of its result. --- ufs/hyper.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index d8064a29..01c06b89 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -1,5 +1,5 @@ /* Fetching and storing the hypermetadata (superblock and cg summary info). - Copyright (C) 1994, 1995 Free Software Foundation + Copyright (C) 1994, 1995, 1996 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -29,6 +29,8 @@ struct csum *csum = 0; void get_hypermetadata (void) { + error_t err; + if (!sblock) sblock = malloc (SBSIZE); @@ -38,10 +40,11 @@ get_hypermetadata (void) if (csum) free (csum); - assert (!diskfs_catch_exception ()); + err = diskfs_catch_exception (); + assert_perror (err); bcopy (disk_image + SBOFF, sblock, SBSIZE); diskfs_end_catch_exception (); - + if (sblock->fs_magic != FS_MAGIC) { fprintf (stderr, "Bad magic number %#lx (should be %#x)\n", @@ -109,7 +112,7 @@ get_hypermetadata (void) csum = malloc (fsaddr (sblock, howmany (sblock->fs_cssize, sblock->fs_fsize))); - + assert (!diskfs_catch_exception ()); bcopy (disk_image + fsaddr (sblock, sblock->fs_csaddr), csum, @@ -119,7 +122,7 @@ get_hypermetadata (void) if ((diskfs_device_size << diskfs_log2_device_block_size) < sblock->fs_size * sblock->fs_fsize) { - fprintf (stderr, + fprintf (stderr, "Disk size (%ld) less than necessary " "(superblock says we need %ld)\n", diskfs_device_size << diskfs_log2_device_block_size, @@ -158,20 +161,20 @@ diskfs_set_hypermetadata (int wait, int clean) } /* Copy into a page-aligned buffer to avoid bugs in kernel device code. */ - + bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); err = diskfs_device_read_sync (fsbtodb (sblock, sblock->fs_csaddr), &buf, bufsize); if (!err) - { + { bcopy (csum, (void *) buf, sblock->fs_cssize); diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr), buf, bufsize); csum_dirty = 0; vm_deallocate (mach_task_self (), buf, bufsize); } - + spin_unlock (&alloclock); } @@ -179,9 +182,12 @@ diskfs_set_hypermetadata (int wait, int clean) void copy_sblock () { + error_t err; + int clean = 1; /* XXX wrong... */ - - assert (!diskfs_catch_exception ()); + + err = diskfs_catch_exception (); + assert_perror (err); spin_lock (&alloclock); -- cgit v1.2.3 From 44d8dbf91974525971fa8a6e041a8d8de7142c72 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 6 Jan 1996 16:50:10 +0000 Subject: (diskfs_reload_global_state): Use `disk_pager' in place of `diskpager->p'. --- ufs/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 59e56df4..b7dd13c5 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -127,7 +127,7 @@ error_t diskfs_reload_global_state () { flush_pokes (); - pager_flush (diskpager->p, 1); + pager_flush (disk_pager, 1); get_hypermetadata (); return 0; } -- cgit v1.2.3 From e8ece98bb0e5bbecece2456549a7a47842eb2c37 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 6 Jan 1996 16:51:10 +0000 Subject: (indir_release): Use `disk_pager' in place of `diskpager->p'. --- ufs/sizes.c | 116 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 58 insertions(+), 58 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 0dadac28..0ecc7d31 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -1,5 +1,5 @@ /* File growth and truncation - Copyright (C) 1993, 1994, 1995 Free Software Foundation + Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation This file is part of the GNU Hurd. @@ -8,7 +8,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. -The GNU Hurd is distributed in the hope that it will be useful, +The GNU Hurd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -67,7 +67,7 @@ diskfs_truncate (struct node *np, np->dn_set_ctime = np->dn_set_mtime = 1; return 0; } - + /* If the file is not being trucated to a block boundary, the zero the partial bit in the new last block. */ offset = blkoff (sblock, length); @@ -75,11 +75,11 @@ diskfs_truncate (struct node *np, { int bsize; /* size of new last block */ int savesize = np->allocsize; - + np->allocsize = length; /* temporary */ bsize = blksize (sblock, np, lblkno (sblock, length)); np->allocsize = savesize; - diskfs_node_rdwr (np, (void *) zeroblock, length, + diskfs_node_rdwr (np, (void *) zeroblock, length, bsize - offset, 1, 0, 0); diskfs_file_update (np, 1); } @@ -94,11 +94,11 @@ diskfs_truncate (struct node *np, if (upi) ports_port_ref (upi->p); spin_unlock (&node2pagelock); - + if (upi) { mach_port_t obj; - + pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); @@ -123,7 +123,7 @@ diskfs_truncate (struct node *np, lbn = lblkno (sblock, length - 1); err = fetch_indir_spec (np, lbn, indirs); /* err XXX */ - + /* We don't support triple indirs */ assert (indirs[3].offset == -2); @@ -132,7 +132,7 @@ diskfs_truncate (struct node *np, /* BSD carefully finds out how far to clear; it's vastly simpler to just clear everything after the new last block. */ - + /* Free direct blocks */ if (indirs[0].offset < 0) { @@ -162,14 +162,14 @@ diskfs_truncate (struct node *np, record_poke (sindir, sblock->fs_bsize); } } - + /* Free single indirect blocks */ if (indirs[1].offset < 0) { /* ...mapped from the inode */ if (di->di_ib[INDIR_SINGLE] && indirs[1].offset == -2) { - blocksfreed += indir_release (np, di->di_ib[INDIR_SINGLE], + blocksfreed += indir_release (np, di->di_ib[INDIR_SINGLE], INDIR_SINGLE); di->di_ib[INDIR_SINGLE] = 0; } @@ -189,33 +189,33 @@ diskfs_truncate (struct node *np, record_poke (dindir, sblock->fs_bsize); } } - + /* Free double indirect block */ assert (indirs[2].offset < 0); /* which must be mapped from the inode */ if (indirs[2].offset == -2) { if (di->di_ib[INDIR_DOUBLE]) { - blocksfreed += indir_release (np, di->di_ib[INDIR_DOUBLE], + blocksfreed += indir_release (np, di->di_ib[INDIR_DOUBLE], INDIR_DOUBLE); di->di_ib[INDIR_DOUBLE] = 0; } } - - /* Finally, check to see if the new last direct block is + + /* Finally, check to see if the new last direct block is changing size; if so release any frags necessary. */ if (lbn >= 0 && lbn < NDADDR && di->di_db[lbn]) { long oldspace, newspace; daddr_t bn; - + bn = di->di_db[lbn]; oldspace = blksize (sblock, np, lbn); np->allocsize = fragroundup (sblock, length); newspace = blksize (sblock, np, lbn); - + assert (newspace); - + if (oldspace - newspace) { bn += numfrags (sblock, newspace); @@ -247,18 +247,18 @@ diskfs_truncate (struct node *np, { /* The strategy is to reduce LBN until we get one that's allocated; then reduce allocsize accordingly, then call diskfs_grow. */ - + do err = fetch_indir_spec (np, --lbn, indirs); /* err XXX */ while (indirs[0].bno == 0 && lbn >= 0); - + assert ((lbn + 1) * sblock->fs_bsize < np->allocsize); np->allocsize = (lbn + 1) * sblock->fs_bsize; diskfs_grow (np, length, 0); } - + diskfs_end_catch_exception (); /* Now we can permit delayed copies again. */ @@ -273,7 +273,7 @@ diskfs_truncate (struct node *np, MEMORY_OBJECT_COPY_DELAY, 0); ports_port_deref (upi->p); } - + return err; } @@ -287,9 +287,9 @@ indir_release (struct node *np, daddr_t bno, int level) daddr_t *addrs; int i; struct dirty_indir *d, *prev, *next; - + assert (bno); - + addrs = indir_block (bno); for (i = 0; i < NINDIR (sblock); i++) if (addrs[i]) @@ -302,7 +302,7 @@ indir_release (struct node *np, daddr_t bno, int level) else count += indir_release (np, addrs[i], level - 1); } - + /* Subtlety: this block is no longer necessary; the information the kernel has cached corresponding to ADDRS is now unimportant. Consider that if this block is allocated to a file, it will then @@ -311,9 +311,9 @@ indir_release (struct node *np, daddr_t bno, int level) the block from the kernel's memory, making sure we do it synchronously--and BEFORE we attach it to the free list with ffs_blkfree. */ - pager_flush_some (diskpager->p, fsaddr (sblock, bno), sblock->fs_bsize, 1); + pager_flush_some (disk_pager, fsaddr (sblock, bno), sblock->fs_bsize, 1); - /* We should also take this block off the inode's list of + /* We should also take this block off the inode's list of dirty indirect blocks if it's there. */ prev = 0; d = np->dn->dirty; @@ -346,7 +346,7 @@ indir_release (struct node *np, daddr_t bno, int level) -/* Implement the diskfs_grow callback; see for the +/* Implement the diskfs_grow callback; see for the interface description. */ error_t diskfs_grow (struct node *np, @@ -359,8 +359,8 @@ diskfs_grow (struct node *np, struct dinode *di = dino (np->dn->number); off_t poke_off = 0; size_t poke_len = 0; - - /* Zero an sblock->fs_bsize piece of disk starting at BNO, + + /* Zero an sblock->fs_bsize piece of disk starting at BNO, synchronously. We do this on newly allocated indirect blocks before setting the pointer to them to ensure that an indirect block absolutely never points to garbage. */ @@ -383,12 +383,12 @@ diskfs_grow (struct node *np, size = fragroundup (sblock, blkoff (sblock, end)); if (size == 0) size = sblock->fs_bsize; - + rwlock_writer_lock (&np->dn->allocptrlock); /* The old last block of the file. */ olbn = lblkno (sblock, np->allocsize - 1); - + /* This is the size of that block if it is in the NDADDR array. */ osize = fragroundup (sblock, blkoff (sblock, np->allocsize)); if (osize == 0) @@ -410,7 +410,7 @@ diskfs_grow (struct node *np, di->di_db[olbn] = bno; record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - + diskfs_device_write_sync (fsbtodb (sblock, bno) + btodb (osize), zeroblock, sblock->fs_bsize - osize); @@ -427,7 +427,7 @@ diskfs_grow (struct node *np, if (lbn < NDADDR) { daddr_t bno, old_pbn = di->di_db[lbn]; - + if (old_pbn != 0) { /* The last block is already allocated. Therefore we @@ -435,24 +435,24 @@ diskfs_grow (struct node *np, what we're up to. */ assert (size > osize); assert (lbn == olbn); - - err = ffs_realloccg (np, lbn, + + err = ffs_realloccg (np, lbn, ffs_blkpref (np, lbn, lbn, di->di_db), osize, size, &bno, cred); if (err) goto out; - + di->di_db[lbn] = bno; - record_poke (di, sizeof (struct dinode)); + record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - + diskfs_device_write_sync (fsbtodb (sblock, bno) + btodb (osize), zeroblock, size - osize); if (bno != old_pbn) { assert (!poke_len); - + /* Make sure the old contents get written out to the new address by poking the pages. */ poke_off = lbn * sblock->fs_bsize; @@ -462,12 +462,12 @@ diskfs_grow (struct node *np, else { /* Allocate a new last block. */ - err = ffs_alloc (np, lbn, + err = ffs_alloc (np, lbn, ffs_blkpref (np, lbn, lbn, di->di_db), size, &bno, cred); if (err) goto out; - + di->di_db[lbn] = bno; record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; @@ -480,23 +480,23 @@ diskfs_grow (struct node *np, struct iblock_spec indirs[NIADDR + 1]; daddr_t *siblock; daddr_t bno; - + /* Count the number of levels of indirection. */ err = fetch_indir_spec (np, lbn, indirs); if (err) goto out; - + /* Make sure we didn't miss the NDADDR case above somehow. */ assert (indirs[0].offset != -1); - + /* See if we need a triple indirect block; fail if so. */ assert (indirs[1].offset == -1 || indirs[2].offset == -1); - + /* Check to see if this block is allocated. If it is that's an error. */ assert (indirs[0].bno == 0); - + /* We need to set SIBLOCK to the single indirect block array; see if the single indirect block is allocated. */ if (indirs[1].bno == 0) @@ -516,7 +516,7 @@ diskfs_grow (struct node *np, else { daddr_t *diblock; - + /* We need to set diblock to the double indirect block array; see if the double indirect block is allocated. */ if (indirs[2].bno == 0) @@ -525,7 +525,7 @@ diskfs_grow (struct node *np, supported. */ assert (indirs[2].offset == -1); err = ffs_alloc (np, lbn, - ffs_blkpref (np, lbn, + ffs_blkpref (np, lbn, INDIR_DOUBLE, di->di_ib), sblock->fs_bsize, &bno, 0); if (err) @@ -534,13 +534,13 @@ diskfs_grow (struct node *np, indirs[2].bno = di->di_ib[INDIR_DOUBLE] = bno; record_poke (di, sizeof (struct dinode)); } - + diblock = indir_block (indirs[2].bno); mark_indir_dirty (np, indirs[2].bno); - + /* Now we can allocate the single indirect block */ - err = ffs_alloc (np, lbn, - ffs_blkpref (np, lbn, + err = ffs_alloc (np, lbn, + ffs_blkpref (np, lbn, indirs[1].offset, diblock), sblock->fs_bsize, &bno, 0); if (err) @@ -550,12 +550,12 @@ diskfs_grow (struct node *np, record_poke (diblock, sblock->fs_bsize); } } - + siblock = indir_block (indirs[1].bno); mark_indir_dirty (np, indirs[1].bno); /* Now we can allocate the data block. */ - err = ffs_alloc (np, lbn, + err = ffs_alloc (np, lbn, ffs_blkpref (np, lbn, indirs[0].offset, siblock), sblock->fs_bsize, &bno, 0); if (err) @@ -565,7 +565,7 @@ diskfs_grow (struct node *np, diskfs_device_write_sync (fsbtodb (sblock, bno), zeroblock, sblock->fs_bsize); } - + out: if (!err) { @@ -587,7 +587,7 @@ diskfs_grow (struct node *np, if (poke_len) { mach_port_t obj; - + obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); poke_pages (obj, trunc_page (poke_off), round_page (poke_off + poke_len)); @@ -607,7 +607,7 @@ poke_pages (memory_object_t obj, vm_address_t addr, poke; vm_size_t len; error_t err; - + while (start < end) { len = 8 * vm_page_size; -- cgit v1.2.3 From 0e2ced4de1118fed20b94191e6b294b81906930a Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 6 Jan 1996 16:52:06 +0000 Subject: (sync_disk): Use `disk_pager' in place of `diskpager->p'. --- ufs/pokeloc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/pokeloc.c b/ufs/pokeloc.c index e137090f..d09942e8 100644 --- a/ufs/pokeloc.c +++ b/ufs/pokeloc.c @@ -1,5 +1,5 @@ /* Remember where we've written the disk to speed up sync - Copyright (C) 1994 Free Software Foundation, Inc. + Copyright (C) 1994, 1996 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -20,7 +20,7 @@ #include "ufs.h" -struct pokeloc +struct pokeloc { vm_offset_t offset; vm_size_t length; @@ -36,7 +36,7 @@ record_poke (void *loc, vm_size_t length) { struct pokeloc *pl = malloc (sizeof (struct pokeloc)); vm_offset_t offset; - + offset = loc - disk_image; pl->offset = trunc_page (offset); pl->length = round_page (offset + length) - pl->offset; @@ -71,11 +71,11 @@ void sync_disk (int wait) { struct pokeloc *pl, *tmp; - + spin_lock (&pokelistlock); for (pl = pokelist; pl; pl = tmp) { - pager_sync_some (diskpager->p, pl->offset, pl->length, wait); + pager_sync_some (disk_pager, pl->offset, pl->length, wait); tmp = pl->next; free (pl); } -- cgit v1.2.3 From 6eebcfcac97283bb0024e1a7dff24493eb7a1490 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 6 Jan 1996 16:54:03 +0000 Subject: (diskfs_shutdown_pager, diskfs_sync_everything): Use `disk_pager' in place of `diskpager->p'. (create_disk_pager): Rewritten using disk_pager_setup. --- ufs/pager.c | 136 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 65 insertions(+), 71 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 26f5f322..695a006b 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -43,7 +43,7 @@ find_address (struct user_pager_info *upi, struct rwlock **nplock) { error_t err; - + assert (upi->type == DISK || upi->type == FILE_DATA); if (upi->type == DISK) @@ -53,13 +53,13 @@ find_address (struct user_pager_info *upi, *nplock = 0; return 0; } - else + else { struct iblock_spec indirs[NIADDR + 1]; struct node *np; - + np = upi->np; - + rwlock_reader_lock (&np->dn->allocptrlock); *nplock = &np->dn->allocptrlock; @@ -68,12 +68,12 @@ find_address (struct user_pager_info *upi, rwlock_reader_unlock (&np->dn->allocptrlock); return EIO; } - + if (offset + __vm_page_size > np->allocsize) *disksize = np->allocsize - offset; else *disksize = __vm_page_size; - + err = fetch_indir_spec (np, lblkno (sblock, offset), indirs); if (err) rwlock_reader_unlock (&np->dn->allocptrlock); @@ -85,13 +85,13 @@ find_address (struct user_pager_info *upi, else *addr = 0; } - + return err; } } -/* Implement the pager_read_page callback from the pager library. See +/* Implement the pager_read_page callback from the pager library. See for the interface description. */ error_t pager_read_page (struct user_pager_info *pager, @@ -103,11 +103,11 @@ pager_read_page (struct user_pager_info *pager, struct rwlock *nplock; daddr_t addr; int disksize; - + err = find_address (pager, page, &addr, &disksize, &nplock); if (err) return err; - + if (addr) { err = diskfs_device_read_sync (addr, (void *)buf, disksize); @@ -124,14 +124,14 @@ pager_read_page (struct user_pager_info *pager, vm_allocate (mach_task_self (), buf, __vm_page_size, 1); *writelock = 1; } - + if (nplock) rwlock_reader_unlock (nplock); - + return err; } -/* Implement the pager_write_page callback from the pager library. See +/* Implement the pager_write_page callback from the pager library. See for the interface description. */ error_t pager_write_page (struct user_pager_info *pager, @@ -142,11 +142,11 @@ pager_write_page (struct user_pager_info *pager, int disksize; struct rwlock *nplock; error_t err; - + err = find_address (pager, page, &addr, &disksize, &nplock); if (err) return err; - + if (addr) err = diskfs_device_write_sync (addr, buf, disksize); else @@ -154,17 +154,17 @@ pager_write_page (struct user_pager_info *pager, printf ("Attempt to write unallocated disk\n."); printf ("Object %p\tOffset %#x\n", pager, page); fflush (stdout); - err = 0; /* unallocated disk; + err = 0; /* unallocated disk; error would be pointless */ } - + if (nplock) rwlock_reader_unlock (nplock); - + return err; } -/* Implement the pager_unlock_page callback from the pager library. See +/* Implement the pager_unlock_page callback from the pager library. See for the interface description. */ error_t pager_unlock_page (struct user_pager_info *pager, @@ -177,7 +177,7 @@ pager_unlock_page (struct user_pager_info *pager, struct disknode *dn; struct dinode *di; - /* Zero an sblock->fs_bsize piece of disk starting at BNO, + /* Zero an sblock->fs_bsize piece of disk starting at BNO, synchronously. We do this on newly allocated indirect blocks before setting the pointer to them to ensure that an indirect block absolutely never points to garbage. */ @@ -196,13 +196,13 @@ pager_unlock_page (struct user_pager_info *pager, if (pager->type == DISK) return 0; - + np = pager->np; dn = np->dn; di = dino (dn->number); rwlock_writer_lock (&dn->allocptrlock); - + /* If this is the last block, we don't let it get unlocked. */ if (address + __vm_page_size > blkroundup (sblock, np->allocsize) - sblock->fs_bsize) @@ -212,7 +212,7 @@ pager_unlock_page (struct user_pager_info *pager, rwlock_writer_unlock (&dn->allocptrlock); return EIO; } - + err = fetch_indir_spec (np, lblkno (sblock, address), indirs); if (err) { @@ -228,10 +228,10 @@ pager_unlock_page (struct user_pager_info *pager, } /* See if we need a triple indirect block; fail if we do. */ - assert (indirs[0].offset == -1 - || indirs[1].offset == -1 + assert (indirs[0].offset == -1 + || indirs[1].offset == -1 || indirs[2].offset == -1); - + /* Check to see if this block is allocated. */ if (indirs[0].bno == 0) { @@ -252,7 +252,7 @@ pager_unlock_page (struct user_pager_info *pager, else { daddr_t *siblock; - + /* We need to set siblock to the single indirect block array; see if the single indirect block is allocated. */ if (indirs[1].bno == 0) @@ -272,7 +272,7 @@ pager_unlock_page (struct user_pager_info *pager, else { daddr_t *diblock; - + /* We need to set diblock to the double indirect block array; see if the double indirect block is allocated. */ @@ -281,7 +281,7 @@ pager_unlock_page (struct user_pager_info *pager, /* This assert because triple indirection is not supported. */ assert (indirs[2].offset == -1); - + err = ffs_alloc (np, lblkno (sblock, address), ffs_blkpref (np, lblkno (sblock, address), @@ -296,9 +296,9 @@ pager_unlock_page (struct user_pager_info *pager, diblock = indir_block (indirs[2].bno); mark_indir_dirty (np, indirs[2].bno); - + /* Now we can allocate the single indirect block */ - + err = ffs_alloc (np, lblkno (sblock, address), ffs_blkpref (np, lblkno (sblock, address), indirs[1].offset, diblock), @@ -310,7 +310,7 @@ pager_unlock_page (struct user_pager_info *pager, record_poke (diblock, sblock->fs_bsize); } } - + siblock = indir_block (indirs[1].bno); mark_indir_dirty (np, indirs[1].bno); @@ -330,14 +330,14 @@ pager_unlock_page (struct user_pager_info *pager, record_poke (siblock, sblock->fs_bsize); } } - + out: diskfs_end_catch_exception (); rwlock_writer_unlock (&dn->allocptrlock); return err; } -/* Implement the pager_report_extent callback from the pager library. See +/* Implement the pager_report_extent callback from the pager library. See for the interface description. */ inline error_t pager_report_extent (struct user_pager_info *pager, @@ -352,7 +352,7 @@ pager_report_extent (struct user_pager_info *pager, *size = diskfs_device_size << diskfs_log2_device_block_size; else *size = pager->np->allocsize; - + return 0; } @@ -377,7 +377,7 @@ void pager_dropweak (struct user_pager_info *upi __attribute__ ((unused))) { } - + static void @@ -389,23 +389,17 @@ thread_function (any_t foo __attribute__ ((unused))) 1, MACH_PORT_NULL); } -/* Create a the DISK pager, initializing DISKPAGER, and DISKPAGERPORT */ +/* Create the DISK pager. */ void -create_disk_pager () +create_disk_pager (void) { - pager_bucket = ports_create_bucket (); - - cthread_detach (cthread_fork ((cthread_fn_t) thread_function, (any_t) 0)); - - diskpager = malloc (sizeof (struct user_pager_info)); - diskpager->type = DISK; - diskpager->np = 0; - diskpager->p = pager_create (diskpager, pager_bucket, - MAY_CACHE, MEMORY_OBJECT_COPY_NONE); - diskpagerport = pager_get_port (diskpager->p); - mach_port_insert_right (mach_task_self (), diskpagerport, diskpagerport, - MACH_MSG_TYPE_MAKE_SEND); -} + struct user_pager_info *upi = malloc (sizeof (struct user_pager_info)); + + upi->type = DISK; + upi->np = 0; + disk_pager_setup (upi, MAY_CACHE); + upi->p = disk_pager; +} /* This syncs a single file (NP) to disk. Wait for all I/O to complete if WAIT is set. NP->lock must be held. */ @@ -421,13 +415,13 @@ diskfs_file_update (struct node *np, if (upi) ports_port_ref (upi->p); spin_unlock (&node2pagelock); - + if (upi) { pager_sync (upi->p, wait); ports_port_deref (upi->p); } - + for (d = np->dn->dirty; d; d = tmp) { sync_disk_blocks (d->bno, sblock->fs_bsize, wait); @@ -452,13 +446,13 @@ flush_node_pager (struct node *node) if (upi) ports_port_ref (upi->p); spin_unlock (&node2pagelock); - + if (upi) { pager_flush (upi->p, 1); ports_port_deref (upi->p); } - + dn->dirty = 0; while (dirty) @@ -480,7 +474,7 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot) assert (S_ISDIR (np->dn_stat.st_mode) || S_ISREG (np->dn_stat.st_mode) || (S_ISLNK (np->dn_stat.st_mode) - && (!direct_symlink_extension + && (!direct_symlink_extension || np->dn_stat.st_size >= sblock->fs_maxsymlinklen))); spin_lock (&node2pagelock); @@ -513,12 +507,12 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot) while (right == MACH_PORT_NULL); spin_unlock (&node2pagelock); - + mach_port_insert_right (mach_task_self (), right, right, MACH_MSG_TYPE_MAKE_SEND); return right; -} +} /* Call this when we should turn off caching so that unused memory object ports get freed. */ @@ -526,7 +520,7 @@ void drop_pager_softrefs (struct node *np) { struct user_pager_info *upi; - + spin_lock (&node2pagelock); upi = np->dn->fileinfo; if (upi) @@ -545,13 +539,13 @@ void allow_pager_softrefs (struct node *np) { struct user_pager_info *upi; - + spin_lock (&node2pagelock); upi = np->dn->fileinfo; if (upi) ports_port_ref (upi->p); spin_unlock (&node2pagelock); - + if (MAY_CACHE && upi) pager_change_attributes (upi->p, 1, MEMORY_OBJECT_COPY_DELAY, 0); if (upi) @@ -564,11 +558,11 @@ block_caching () error_t block_cache (void *arg) { struct pager *p = arg; - + pager_change_attributes (p, 0, MEMORY_OBJECT_COPY_DELAY, 1); return 0; } - + /* Loop through the pagers and turn off caching one by one, synchronously. That should cause termination of each pager. */ ports_bucket_iterate (pager_bucket, block_cache); @@ -581,7 +575,7 @@ enable_caching () { struct pager *p = arg; struct user_pager_info *upi = pager_get_upi (p); - + pager_change_attributes (p, 1, MEMORY_OBJECT_COPY_DELAY, 0); /* It's possible that we didn't have caching on before, because @@ -619,7 +613,7 @@ diskfs_pager_users () /* Give it a second; the kernel doesn't actually shutdown immediately. XXX */ sleep (1); - + npagers = ports_count_bucket (pager_bucket); if (npagers <= 1) return 0; @@ -628,7 +622,7 @@ diskfs_pager_users () and return failure. */ enable_caching (); } - + ports_enable_bucket (pager_bucket); return 1; @@ -674,7 +668,7 @@ diskfs_max_user_pager_prot () /* Call this to find out the struct pager * corresponding to the FILE_DATA pager of inode IP. This should be used *only* as a subsequent - argument to register_memory_fault_area, and will be deleted when + argument to register_memory_fault_area, and will be deleted when the kernel interface is fixed. NP must be locked. */ struct pager * diskfs_get_filemap_pager_struct (struct node *np) @@ -692,7 +686,7 @@ diskfs_shutdown_pager () { struct pager *p = arg; /* Make sure the disk pager is done last. */ - if (p != diskpager->p) + if (p != disk_pager) pager_shutdown (p); return 0; } @@ -700,7 +694,7 @@ diskfs_shutdown_pager () copy_sblock (); write_all_disknodes (); ports_bucket_iterate (pager_bucket, shutdown_one); - pager_shutdown (diskpager->p); + pager_shutdown (disk_pager); } /* Sync all the pagers. */ @@ -711,11 +705,11 @@ diskfs_sync_everything (int wait) { struct pager *p = arg; /* Make sure the disk pager is done last. */ - if (p != diskpager->p) + if (p != disk_pager) pager_sync (p, wait); return 0; } - + copy_sblock (); write_all_disknodes (); ports_bucket_iterate (pager_bucket, sync_one); -- cgit v1.2.3 From f581c957585a4ed88422839bd1526b6ef651b2c1 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 6 Jan 1996 16:55:44 +0000 Subject: (diskpager, diskpagerport, disk_image): Variables removed. Include instead. (sync_disk_blocks): Use `disk_pager' in place of `diskpager->p'. --- ufs/ufs.h | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 8771c372..0f310d1b 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -1,5 +1,5 @@ -/* - Copyright (C) 1994, 1995 Free Software Foundation +/* + Copyright (C) 1994, 1995, 1996 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -32,7 +32,7 @@ /* #undef DONT_CACHE_MEMORY_OBJECTS */ -struct disknode +struct disknode { ino_t number; @@ -48,7 +48,7 @@ struct disknode struct dirty_indir *dirty; struct user_pager_info *fileinfo; -}; +}; /* Identifies a particular block and where it's found when interpreting indirect block structure. */ @@ -69,10 +69,10 @@ struct dirty_indir struct dirty_indir *next; }; -struct user_pager_info +struct user_pager_info { struct node *np; - enum pager_type + enum pager_type { DISK, FILE_DATA, @@ -81,8 +81,7 @@ struct user_pager_info vm_prot_t max_prot; }; -struct user_pager_info *diskpager; -mach_port_t diskpagerport; +#include extern vm_address_t zeroblock; @@ -91,8 +90,6 @@ extern struct csum *csum; int sblock_dirty; int csum_dirty; -void *disk_image; - spin_lock_t node2pagelock; spin_lock_t alloclock; @@ -111,7 +108,7 @@ enum compat_mode /* If this is set, then this filesystem has two extensions: 1) directory entries include the type field. - 2) symlink targets might be written directly in the di_db field + 2) symlink targets might be written directly in the di_db field of the dinode. */ int direct_symlink_extension; @@ -136,7 +133,7 @@ extern inline struct dinode * dino (ino_t inum) { return (struct dinode *) - (disk_image + (disk_image + fsaddr (sblock, ino_to_fsba (sblock, inum)) + ino_to_fsbo (sblock, inum) * sizeof (struct dinode)); } @@ -159,7 +156,7 @@ cg_locate (int ncg) extern inline void sync_disk_blocks (daddr_t blkno, size_t nbytes, int wait) { - pager_sync_some (diskpager->p, fsaddr (sblock, blkno), nbytes, wait); + pager_sync_some (disk_pager, fsaddr (sblock, blkno), nbytes, wait); } /* Sync an disk inode */ @@ -170,7 +167,7 @@ sync_dinode (int inum, int wait) } /* From alloc.c: */ -error_t ffs_alloc (struct node *, daddr_t, daddr_t, int, daddr_t *, +error_t ffs_alloc (struct node *, daddr_t, daddr_t, int, daddr_t *, struct protid *); void ffs_blkfree(struct node *, daddr_t bno, long size); daddr_t ffs_blkpref (struct node *, daddr_t, int, daddr_t *); -- cgit v1.2.3 From 9b82dd57efc2370720627abb5ba3f79f4b9c2e69 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 17 Feb 1996 21:06:50 +0000 Subject: (main): Check error return from diskfs_init_diskfs. --- ufs/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index b7dd13c5..ea43acce 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -83,7 +83,9 @@ main (int argc, char **argv) } /* Initialize the diskfs library. Must come before any other diskfs call. */ - diskfs_init_diskfs (); + err = diskfs_init_diskfs (); + if (err) + error (4, err, "init"); err = diskfs_device_open (); if (err) -- cgit v1.2.3 From fd66050fcf2ba9fc8c3c81e222fcc99a7bf03d42 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 21 Feb 1996 10:57:07 +0000 Subject: Implement proper handling of the filesystem `clean bit'. (ufs_clean): New variable. (get_hypermetadata): Set it from the fs_clean flag. If not clean, complain and force read-only. Complain when ignoring COMPAT_BSD42. (diskfs_set_hypermetadata): Set the clean flag in the superblock when CLEAN and fs was clean to start with. (copy_sblock): Remove bogus clean flag frobnication. --- ufs/hyper.c | 107 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 36 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 01c06b89..fc2bb1ed 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -18,13 +18,16 @@ #include "ufs.h" #include #include +#include -static int oldformat = 0; +static int ufs_clean; /* fs clean before we started writing? */ -vm_address_t zeroblock = 0; +static int oldformat; -struct fs *sblock = 0; -struct csum *csum = 0; +vm_address_t zeroblock; + +struct fs *sblock; +struct csum *csum; void get_hypermetadata (void) @@ -75,6 +78,18 @@ get_hypermetadata (void) assert ((sblock->fs_bsize % DEV_BSIZE) == 0); assert (__vm_page_size <= sblock->fs_bsize); + /* Examine the clean bit and force read-only if unclean. */ + ufs_clean = sblock->fs_clean; + if (! ufs_clean) + { + error (0, 0, "warning: FILESYSTEM NOT UNMOUNTED CLEANLY; PLEASE fsck"); + if (! diskfs_readonly) + { + diskfs_readonly = 1; + error (0, 0, "MOUNTED READ-ONLY; MUST USE `fsysopts --writable'"); + } + } + /* If this is an old filesystem, then we have some more work to do; some crucial constants might not be set; we are therefore forced to set them here. */ @@ -137,8 +152,11 @@ get_hypermetadata (void) if ((sblock->fs_inodefmt == FS_44INODEFMT || direct_symlink_extension) && compat_mode == COMPAT_BSD42) - /* XXX should syslog to this effect */ - compat_mode = COMPAT_BSD44; + { + compat_mode = COMPAT_BSD44; + error (0, 0, + "4.2 compat mode requested on 4.4 fs--switched to 4.4 mode"); + } } /* Write the csum data. This isn't backed by a pager because it is @@ -154,28 +172,36 @@ diskfs_set_hypermetadata (int wait, int clean) spin_lock (&alloclock); - if (!csum_dirty) + if (csum_dirty) { - spin_unlock (&alloclock); - return; - } + /* Copy into a page-aligned buffer to avoid bugs in kernel device + code. */ - /* Copy into a page-aligned buffer to avoid bugs in kernel device code. */ + bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); - bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); + err = diskfs_device_read_sync (fsbtodb (sblock, sblock->fs_csaddr), + &buf, bufsize); + if (!err) + { + bcopy (csum, (void *) buf, sblock->fs_cssize); + diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr), + buf, bufsize); + csum_dirty = 0; + vm_deallocate (mach_task_self (), buf, bufsize); + } + } - err = diskfs_device_read_sync (fsbtodb (sblock, sblock->fs_csaddr), - &buf, bufsize); - if (!err) + if (clean && ufs_clean && !sblock->fs_clean) { - bcopy (csum, (void *) buf, sblock->fs_cssize); - diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr), - buf, bufsize); - csum_dirty = 0; - vm_deallocate (mach_task_self (), buf, bufsize); + /* The filesystem is clean, so set the clean flag. */ + sblock->fs_clean = 1; + sblock_dirty = 1; } spin_unlock (&alloclock); + + /* Update the superblock if necessary (clean bit was just set). */ + copy_sblock (); } /* Copy the sblock into the disk */ @@ -184,21 +210,15 @@ copy_sblock () { error_t err; - int clean = 1; /* XXX wrong... */ - err = diskfs_catch_exception (); assert_perror (err); spin_lock (&alloclock); - if (clean && !diskfs_readonly) - { - sblock->fs_clean = 1; - sblock_dirty = 1; - } - if (sblock_dirty) { + assert (! diskfs_readonly); + if (sblock->fs_postblformat == FS_42POSTBLFMT || oldformat) { @@ -221,17 +241,23 @@ copy_sblock () sblock_dirty = 0; } - if (clean && !diskfs_readonly) + if (!diskfs_readonly && sblock->fs_clean) { + /* We just sync'd with the clean flag set, but we are still a + writable filesystem. Clear the flag in core, but don't write the + superblock yet. This should ensure that the flag will be written + as clear as soon as we make any modifications. */ sblock->fs_clean = 0; sblock_dirty = 1; } spin_unlock (&alloclock); + diskfs_end_catch_exception (); } -void diskfs_readonly_changed (int readonly) +void +diskfs_readonly_changed (int readonly) { vm_protect (mach_task_self (), (vm_address_t)disk_image, @@ -239,12 +265,21 @@ void diskfs_readonly_changed (int readonly) 0, VM_PROT_READ | (readonly ? 0 : VM_PROT_WRITE)); if (readonly) - sblock_dirty = 0; - else { - sblock->fs_clean = 0; - strcpy (sblock->fs_fsmnt, "Hurd /"); /* XXX */ - sblock_dirty = 1; - diskfs_set_hypermetadata (1, 0); + /* We know we are sync'd now. The superblock is marked as dirty + because we cleared the clean flag immediately after sync'ing. + But now we want to leave it marked clean and not touch it further. */ + sblock_dirty = 0; + return; } + + strcpy (sblock->fs_fsmnt, "Hurd /"); /* XXX */ + + if (sblock->fs_clean) + sblock->fs_clean = 0; + else + error (0, 0, "WARNING: UNCLEANED FILESYSTEM NOW WRITABLE"); + + sblock_dirty = 1; + diskfs_set_hypermetadata (1, 0); } -- cgit v1.2.3 From fbf3f8beef691c62d1d1432b732512fa63c4bead Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 23 Feb 1996 20:27:01 +0000 Subject: (get_hypermetadata): Use diskfs_device_arg in unclean msgs. --- ufs/hyper.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index fc2bb1ed..be51b360 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -82,11 +82,15 @@ get_hypermetadata (void) ufs_clean = sblock->fs_clean; if (! ufs_clean) { - error (0, 0, "warning: FILESYSTEM NOT UNMOUNTED CLEANLY; PLEASE fsck"); + error (0, 0, + "%s: warning: FILESYSTEM NOT UNMOUNTED CLEANLY; PLEASE fsck", + diskfs_device_arg); if (! diskfs_readonly) { diskfs_readonly = 1; - error (0, 0, "MOUNTED READ-ONLY; MUST USE `fsysopts --writable'"); + error (0, 0, + "%s: MOUNTED READ-ONLY; MUST USE `fsysopts --writable'", + diskfs_device_arg); } } -- cgit v1.2.3 From 77b32ea8095faf6ca609c6f95119214a55db0d10 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 18 Mar 1996 17:33:48 +0000 Subject: (diskfs_max_user_pager_prot) [add_pager_max_prot]: (a == b) ? 1 : 0 ====> (a == b). --- ufs/pager.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 695a006b..8834f911 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -646,8 +646,7 @@ diskfs_max_user_pager_prot () if (upi->type == FILE_DATA) max_prot |= upi->max_prot; /* Stop iterating if MAX_PROT is as filled as it's going to get. */ - return - (max_prot == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE)) ? 1 : 0; + return max_prot == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE); } block_caching (); /* Make any silly pagers go away. */ -- cgit v1.2.3 From 2115f0d8dbbdbe1a85cf1e3c0fad75657d9d94a4 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Tue, 19 Mar 1996 00:51:01 +0000 Subject: (main): Pass new arg to argp_parse. --- ufs/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index ea43acce..787cb749 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -62,7 +62,7 @@ main (int argc, char **argv) off_t disk_size; mach_port_t bootstrap; - argp_parse (diskfs_device_startup_argp, argc, argv, 0, 0); + argp_parse (diskfs_device_startup_argp, argc, argv, 0, 0, 0); /* This must come after the args have been parsed, as this is where the host priv ports are set for booting. */ -- cgit v1.2.3 From e802372ce7210fe006b9207f810bc274d3dd9ff3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 20 Mar 1996 19:36:27 +0000 Subject: (diskfs_dirrewrite_hard): Renamed from diskfs_dirrewrite. No longer call modification tracking routines. (diskfs_dirremove_hard): Renamed from diskfs_dirremove. No longer call modification tracking routines. (diskfs_direnter_hard): Renamed from diskfs_direnter. No longer call modification tracking routines. (diskfs_lookup_hard): Renamed from diskfs_lookup. --- ufs/dir.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index b2147007..16364071 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995 Free Software Foundation + Copyright (C) 1994, 1995, 1996 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -89,8 +89,8 @@ dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, /* Implement the diskfs_lookup from the diskfs library. See for the interface specification. */ error_t -diskfs_lookup (struct node *dp, char *name, enum lookup_type type, - struct node **npp, struct dirstat *ds, struct protid *cred) +diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, + struct node **npp, struct dirstat *ds, struct protid *cred) { error_t err; ino_t inum; @@ -458,11 +458,11 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, only be made if the directory has been held locked continuously since the preceding lookup call, and only if that call returned ENOENT. */ error_t -diskfs_direnter(struct node *dp, - char *name, - struct node *np, - struct dirstat *ds, - struct protid *cred) +diskfs_direnter_hard(struct node *dp, + char *name, + struct node *np, + struct dirstat *ds, + struct protid *cred) { struct directory_entry *new; int namelen = strlen (name); @@ -608,9 +608,6 @@ diskfs_direnter(struct node *dp, diskfs_file_update (dp, 1); - if (dp->dirmod_reqs) - diskfs_notice_dirchange (dp, DIR_CHANGED_NEW, name); - return 0; } @@ -620,8 +617,8 @@ diskfs_direnter(struct node *dp, directory has been locked continously since the call to lookup, and only if that call succeeded. */ error_t -diskfs_dirremove(struct node *dp, - struct dirstat *ds) +diskfs_dirremove_hard(struct node *dp, + struct dirstat *ds) { assert (ds->type == REMOVE); assert (ds->stat == HERE_TIS); @@ -644,9 +641,6 @@ diskfs_dirremove(struct node *dp, diskfs_file_update (dp, 1); - if (dp->dirmod_reqs) - diskfs_notice_dirchange (dp, DIR_CHANGED_UNLINK, ds->entry->d_name); - return 0; } @@ -658,9 +652,9 @@ diskfs_dirremove(struct node *dp, continuously since the call to lookup, and only if that call succeeded. */ error_t -diskfs_dirrewrite(struct node *dp, - struct node *np, - struct dirstat *ds) +diskfs_dirrewrite_hard(struct node *dp, + struct node *np, + struct dirstat *ds) { assert (ds->type == RENAME); assert (ds->stat == HERE_TIS); @@ -673,9 +667,6 @@ diskfs_dirrewrite(struct node *dp, diskfs_file_update (dp, 1); - if (dp->dirmod_reqs) - diskfs_notice_dirchange (dp, DIR_CHANGED_RENUMBER, ds->entry->d_name); - return 0; } -- cgit v1.2.3 From a14a84d7bfba8c138367a433cc6f562895ce5b54 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 20 Mar 1996 21:02:17 +0000 Subject: (diskfs_lookup_hard): Don't do initial permission checking here. --- ufs/dir.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 16364071..73ed5f02 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -120,12 +120,6 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, if (namelen > MAXNAMLEN) return ENAMETOOLONG; - if (!S_ISDIR (dp->dn_stat.st_mode)) - return ENOTDIR; - err = diskfs_access (dp, S_IEXEC, cred); - if (err) - return err; - try_again: if (ds) { -- cgit v1.2.3 From 4591952861c94f2ae928ac560753b14283aac365 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 20 Mar 1996 21:13:17 +0000 Subject: (diskfs_lookup_hard): Don't do final permission checking here. --- ufs/dir.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 73ed5f02..843735c2 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -238,16 +238,6 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, assert (0); } - /* If we will be modifying the directory, make sure it's allowed. */ - if (type == RENAME - || (type == REMOVE && inum) - || (type == CREATE && !inum)) - { - err = diskfs_checkdirmod (dp, np, cred); - if (err) - goto out; - } - if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ -- cgit v1.2.3 From 4046ebcfba13acea67b27e2ecdcd217e6dca80c5 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 23 Mar 1996 04:45:02 +0000 Subject: (read_symlink_hook): Only set NP's atime if !readonly. --- ufs/inode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 08438e70..81fc8f75 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,5 @@ /* Inode management routines - Copyright (C) 1994, 1995 Free Software Foundation + Copyright (C) 1994, 1995, 1996 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -411,7 +411,9 @@ read_symlink_hook (struct node *np, return err; bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); - np->dn_set_atime = 1; + + if (! diskfs_readonly) + np->dn_set_atime = 1; diskfs_end_catch_exception (); return 0; -- cgit v1.2.3 From 612d539a3edb9ab67412c0df900dd459da8525de Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 25 Mar 1996 18:08:16 +0000 Subject: (diskfs_null_dirstat): New function. --- ufs/dir.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 843735c2..8fb2b39b 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -81,6 +81,14 @@ struct dirstat size_t diskfs_dirstat_size = sizeof (struct dirstat); +/* The user must define this function. Initialize DS such that + diskfs_drop_dirstat will ignore it. */ +void +diskfs_null_dirstat (struct dirstat *ds) +{ + ds->type = LOOKUP; +} + static error_t dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, int namelen, enum lookup_type type, struct dirstat *ds, -- cgit v1.2.3 From 2eb9f242fcddff34edf23c1dac966da7d2dda419 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 25 Mar 1996 18:08:40 +0000 Subject: (diskfs_null_dirstat): doc fix --- ufs/dir.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 8fb2b39b..e5c2e6e2 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -81,8 +81,7 @@ struct dirstat size_t diskfs_dirstat_size = sizeof (struct dirstat); -/* The user must define this function. Initialize DS such that - diskfs_drop_dirstat will ignore it. */ +/* Initialize DS such that diskfs_drop_dirstat will ignore it. */ void diskfs_null_dirstat (struct dirstat *ds) { -- cgit v1.2.3 From fd6a62408f06410d2b54426fa70bd4356dfea20c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 29 Mar 1996 21:52:25 +0000 Subject: (diskfs_truncate): Cast DI->di_shortlink to correct type before adding a character count to it. --- ufs/sizes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 0ecc7d31..249b0ff9 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -61,7 +61,7 @@ diskfs_truncate (struct node *np, err = diskfs_catch_exception (); if (err) return err; - bzero (di->di_shortlink + length, np->dn_stat.st_size - length); + bzero ((char *)di->di_shortlink + length, np->dn_stat.st_size - length); diskfs_end_catch_exception (); np->dn_stat.st_size = length; np->dn_set_ctime = np->dn_set_mtime = 1; -- cgit v1.2.3 From 7fe42b6346b8ea3189470088c20448b09aa03a60 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 3 Apr 1996 21:03:46 +0000 Subject: (iget): Initialize NP->cache_id. --- ufs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 81fc8f75..9c1e1c7e 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -66,7 +66,7 @@ iget (ino_t inum, struct node **npp) dn = malloc (sizeof (struct disknode)); - dn->number = inum; + np->cache_id = dn->number = inum; dn->dirents = 0; rwlock_init (&dn->allocptrlock); -- cgit v1.2.3 From 4cd22ece29676a8581764de37c9be07e4b68d87f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 3 Apr 1996 21:07:50 +0000 Subject: (diskfs_lookup_hard): --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index e5c2e6e2..0a109c0c 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -182,7 +182,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } else { - err = iget (inum, &np); + err = diskfs_cached_lookup (inum, &np); if (err) goto out; } -- cgit v1.2.3 From 10a64e4de4c86ddc50b1e7e48cd61acf3b09f386 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 3 Apr 1996 21:08:48 +0000 Subject: (warp_root): --- ufs/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 787cb749..2173be01 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -34,7 +34,7 @@ static void warp_root (void) { error_t err; - err = iget (2, &diskfs_root_node); + err = diskfs_cached_lookup (2, &diskfs_root_node); assert (!err); mutex_unlock (&diskfs_root_node->lock); } -- cgit v1.2.3 From 85ae67dbee7e957c859144a1e09cba5a38275568 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 3 Apr 1996 21:08:58 +0000 Subject: (diskfs_lookup_hard): --- ufs/dir.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 0a109c0c..136b470f 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -196,7 +196,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, goto out; } - /* We can't just do iget, because we would then deadlock. + /* We can't just do diskfs_cached_lookup, because we would then deadlock. So we do this. Ick. */ else if (retry_dotdot) { @@ -207,7 +207,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, try *again*. */ diskfs_nput (np); mutex_unlock (&dp->lock); - err = iget (inum, &np); + err = diskfs_cached_lookup (inum, &np); mutex_lock (&dp->lock); if (err) goto out; @@ -222,7 +222,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, repeat the directory scan to see if this is still right. */ mutex_unlock (&dp->lock); - err = iget (inum, &np); + err = diskfs_cached_lookup (inum, &np); mutex_lock (&dp->lock); if (err) goto out; @@ -237,7 +237,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, else if (type == LOOKUP) { diskfs_nput (dp); - err = iget (inum, &np); + err = diskfs_cached_lookup (inum, &np); if (err) goto out; } @@ -289,7 +289,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, no new references, so we don't have anything to do */ ; else if (type == LOOKUP) - /* We did iget */ + /* We did diskfs_cached_lookup */ diskfs_nput (np); } else -- cgit v1.2.3 From 500050260d63d846228e3cfc38d45f7ab13eb2f0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 3 Apr 1996 21:09:33 +0000 Subject: (diskfs_cached_lookup): Renamed from `iget'. All callers changed. --- ufs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 9c1e1c7e..ef0d9241 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -45,7 +45,7 @@ inode_init () /* Fetch inode INUM, set *NPP to the node structure; gain one user reference and lock the node. */ error_t -iget (ino_t inum, struct node **npp) +diskfs_cached_lookup (int inum, struct node **npp) { struct disknode *dn; struct node *np; -- cgit v1.2.3 From d4f032eb68dae4f9883a93d3a734c235dcd7ab56 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 3 Apr 1996 21:10:07 +0000 Subject: *** empty log message *** --- ufs/ufs.h | 1 - 1 file changed, 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 0f310d1b..ca186434 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -183,7 +183,6 @@ void get_hypermetadata (void); void copy_sblock (void); /* From inode.c: */ -error_t iget (ino_t ino, struct node **NP); struct node *ifind (ino_t ino); void inode_init (void); void write_all_disknodes (void); -- cgit v1.2.3 From 0bb6f48ecc0aa8a8136760706fd7bca235e10f2d Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 4 Apr 1996 21:39:51 +0000 Subject: (diskfs_cached_lookup): Intialize NP->cache_id *after* NP exists. --- ufs/inode.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index ef0d9241..e4b26f81 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -66,7 +66,7 @@ diskfs_cached_lookup (int inum, struct node **npp) dn = malloc (sizeof (struct disknode)); - np->cache_id = dn->number = inum; + dn->number = inum; dn->dirents = 0; rwlock_init (&dn->allocptrlock); @@ -74,6 +74,8 @@ diskfs_cached_lookup (int inum, struct node **npp) dn->fileinfo = 0; np = diskfs_make_node (dn); + np->cache_id = inum; + mutex_lock (&np->lock); dn->hnext = nodehash[INOHASH(inum)]; if (dn->hnext) -- cgit v1.2.3 From 1cfd3fd7e356a0a4a4374ddba5294f2791a50f2d Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 16 Apr 1996 19:19:57 +0000 Subject: (diskfs_write_disknode): Only do sync if WAIT is set. --- ufs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index e4b26f81..88f89a37 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -479,7 +479,8 @@ void diskfs_write_disknode (struct node *np, int wait) { write_node (np); - sync_dinode (np->dn->number, wait); + if (wait) + sync_dinode (np->dn->number, 1); } /* Implement the diskfs_set_statfs callback from the diskfs library; -- cgit v1.2.3 From f8849fe3bc59296bee95db4a5b13a1275edaf2e5 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 16 Apr 1996 19:35:27 +0000 Subject: (diskfs_lookup_hard): Set atime appropriately, and sync the new atime if we are running synchronously (!). (diskfs_dirempty): Likewise. (diskfs_direnter_hard): Set mtime appropriately. (diskfs_dirremove_hard): Likewise. (diskfs_dirrewrite_hard): Likewise. --- ufs/dir.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 136b470f..67b3645e 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -153,6 +153,9 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, inum = 0; + if (!diskfs_readonly) + dp->dn_set_atime = 1; + for (blockaddr = buf, idx = 0; blockaddr - buf < dp->dn_stat.st_size; blockaddr += DIRBLKSIZ, idx++) @@ -167,6 +170,11 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } } + if (!diskfs_readonly) + dp->dn_set_atime = 1; + if (diskfs_synchronous) + diskfs_node_update (dp, 1); + /* If err is set here, it's ENOENT, and we don't want to think about that as an error yet. */ err = 0; @@ -466,6 +474,8 @@ diskfs_direnter_hard(struct node *dp, assert (ds->type == CREATE); + dp->dn_set_mtime = 1; + switch (ds->stat) { case TAKE: @@ -568,6 +578,8 @@ diskfs_direnter_hard(struct node *dp, assert (0); } + dp->dn_set_mtime = 1; + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); if (ds->stat != EXTEND) @@ -614,6 +626,8 @@ diskfs_dirremove_hard(struct node *dp, assert (ds->type == REMOVE); assert (ds->stat == HERE_TIS); + dp->dn_set_mtime = 1; + if (ds->preventry == 0) ds->entry->d_ino = 0; else @@ -623,6 +637,8 @@ diskfs_dirremove_hard(struct node *dp, ds->preventry->d_reclen += ds->entry->d_reclen; } + dp->dn_set_mtime = 1; + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); /* If we are keeping count of this block, then keep the count up @@ -650,9 +666,11 @@ diskfs_dirrewrite_hard(struct node *dp, assert (ds->type == RENAME); assert (ds->stat == HERE_TIS); + dp->dn_set_mtime = 1; ds->entry->d_ino = np->dn->number; if (direct_symlink_extension) ds->entry->d_type = IFTODT (np->dn_stat.st_mode); + dp->dn_set_mtime = 1; vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); @@ -681,6 +699,9 @@ diskfs_dirempty(struct node *dp, mach_port_deallocate (mach_task_self (), memobj); assert (!err); + if (!diskfs_readonly) + dp->dn_set_atime = 1; + for (curoff = buf; curoff < buf + dp->dn_stat.st_size; curoff += entry->d_reclen) @@ -694,9 +715,17 @@ diskfs_dirempty(struct node *dp, && entry->d_name[1] != '\0'))) { vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + if (!diskfs_readonly) + dp->dn_set_atime = 1; + if (diskfs_synchronous) + node_update (dp, 1); return 0; } } + if (!diskfs_readonly) + dp->dn_set_atime = 1; + if (diskfs_synchronous) + node_update (dp, 1); vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); return 1; } -- cgit v1.2.3 From b69508c00daf432e4d21e72800ac58f950b967d4 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 18 Apr 1996 19:06:20 +0000 Subject: (ffs_realloccg): If we are allocating a new block, don't actually free the old one here. --- ufs/alloc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 8f6a5baf..4cbac331 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -1,5 +1,5 @@ /* Disk allocation routines - Copyright (C) 1993, 1994, 1995 Free Software Foundation + Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation This file is part of the GNU Hurd. @@ -308,7 +308,10 @@ ffs_realloccg(register struct node *np, bp->b_blkno = fsbtodb(fs, bno); (void) vnode_pager_uncache(ITOV(ip)); #endif - ffs_blkfree(np, bprev, (long)osize); +/* Commented out here for Hurd; we don't want to free this until we've + saved the old contents. Callers are responsible for freeing the + block when they are done with it. */ +/* ffs_blkfree(np, bprev, (long)osize); */ if (nsize < request) ffs_blkfree(np, bno + numfrags(fs, nsize), (long)(request - nsize)); @@ -563,7 +566,7 @@ diskfs_alloc_node (struct node *dir, spin_unlock (&alloclock); if (ino == 0) goto noinodes; - error = iget (ino, &np); + error = diskfs_cached_lookup (ino, &np); assert ("duplicate allocation" && !np->dn_stat.st_mode); assert (!np->istranslated); if (np->dn_stat.st_blocks) { -- cgit v1.2.3 From f526bb2287fe7b8901a74aae0645701435026312 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 18 Apr 1996 19:38:26 +0000 Subject: (diskfs_grow): New variable `pagerpt'. (offer_zeroes, block_extended): New functions. (diskfs_grow): In initializing newly allocated data disk blocks with zeroes, use less aggressive offer_zeroes instead of immediate synchronous writes. After ffs_realloccg succeeds, use block_extended to handle the magic. Get rid of old poke calls. --- ufs/sizes.c | 113 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 43 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 249b0ff9..87346175 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -65,6 +65,7 @@ diskfs_truncate (struct node *np, diskfs_end_catch_exception (); np->dn_stat.st_size = length; np->dn_set_ctime = np->dn_set_mtime = 1; + diskfs_node_update (np, 1); return 0; } @@ -343,9 +344,67 @@ indir_release (struct node *np, daddr_t bno, int level) return count; } + +/* Offer data at BUF from START of LEN bytes of file NP. */ +void +offer_data (struct node *np, + off_t start, + size_t len, + vm_address_t buf) +{ + vm_address_t addr; + + len = round_page (size); + + assert (start % vm_page_size == 0); + + assert (np->dn->fileinfo); + for (addr = start; addr < start + len; addr += vm_page_size) + pager_offer_page (np->dn->fileinfo->p, 1, 0, start, buf + (addr - start)); +} + +/* Logical block LBN of node NP has been extended with ffs_realloccg. + It used to be allocated at OLD_PBN and is now at NEW_PBN. The old + size was OLD_SIZE; it is now NEW_SIZE bytes long. Arrange for the data + on disk to be kept consistent, and free the old block if it has moved. */ +void +block_extended (struct node *np, + daddr_t lbn, + daddr_t old_pbn, + daddr_t new_pbn, + size_t old_size, + size_t new_size) +{ + vm_address_t buf; + daddr_t off; + + /* Make sure that any pages of this block which just became allocated + don't get paged in from disk. */ + if (round_page (old_size) < round_page (new_size)) + offer_data (np, lbn * sblock->fs_bsize + round_page (old_size), + round_page (new_size) - round_page (old_size), zeroblock); + + if (old_pbn != new_pbn) + { + /* Fetch the old data for the part that has moved and offer it + to the kernel, to make sure it's paged in before + we deallocate the old block. */ + for (off = 0; off < round_page (old_size); off += vm_page_size) + { + diskfs_device_read_sync (fsbtodb (old_pbn) + off / DEV_BSIZE, + (void *) &buf, vm_page_size); + /* If this page is the last one, then zero the excess first */ + if (off + vm_page_size > old_size) + bzero (buf + old_size - off, vm_page_size - (old_size - off)); + offer_data (np, lbn * sblock->fs_bsize + off, vm_page_size, buf); + } + + /* And deallocate the old block */ + ffs_blkfree (np, old_pbn, old_size); + } +} - /* Implement the diskfs_grow callback; see for the interface description. */ error_t @@ -357,8 +416,7 @@ diskfs_grow (struct node *np, int size, osize; error_t err; struct dinode *di = dino (np->dn->number); - off_t poke_off = 0; - size_t poke_len = 0; + mach_port_t pagerpt; /* Zero an sblock->fs_bsize piece of disk starting at BNO, synchronously. We do this on newly allocated indirect @@ -376,6 +434,9 @@ diskfs_grow (struct node *np, assert (!diskfs_readonly); + /* This reference will ensure that NP->dn->fileinfo stays allocated. */ + pagerpt = diskfs_get_filemap (np, VM_PROT_WRITE|VM_PROT_READ); + /* The new last block of the file. */ lbn = lblkno (sblock, end - 1); @@ -411,16 +472,7 @@ diskfs_grow (struct node *np, record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - diskfs_device_write_sync (fsbtodb (sblock, bno) + btodb (osize), - zeroblock, sblock->fs_bsize - osize); - - if (bno != old_pbn) - { - /* Make sure the old contents get written out - to the new address by poking the pages. */ - poke_off = olbn * sblock->fs_bsize; - poke_len = osize; - } + block_extended (np, olbn, old_pbn, bno, osize, sblock->fs_bsize); } } @@ -446,18 +498,7 @@ diskfs_grow (struct node *np, record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - diskfs_device_write_sync (fsbtodb (sblock, bno) + btodb (osize), - zeroblock, size - osize); - - if (bno != old_pbn) - { - assert (!poke_len); - - /* Make sure the old contents get written out to - the new address by poking the pages. */ - poke_off = lbn * sblock->fs_bsize; - poke_len = osize; - } + block_extended (np, lbn, old_pbn, bno, osize, size); } else { @@ -471,8 +512,8 @@ diskfs_grow (struct node *np, di->di_db[lbn] = bno; record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - - diskfs_device_write_sync (fsbtodb (sblock, bno), zeroblock, size); + + offer_data (np, lbn * sblock->fs_bsize, size, zeroblock); } } else @@ -562,11 +603,11 @@ diskfs_grow (struct node *np, goto out; indirs[0].bno = siblock[indirs[0].offset] = bno; record_poke (siblock, sblock->fs_bsize); - diskfs_device_write_sync (fsbtodb (sblock, bno), - zeroblock, sblock->fs_bsize); + offer_data (np, lbn, sblock->fs_bsize, zeroblock); } out: + mach_port_deallocate (mach_task_self (), pagerpt); if (!err) { int newallocsize; @@ -580,20 +621,6 @@ diskfs_grow (struct node *np, rwlock_writer_unlock (&np->dn->allocptrlock); - /* If we expanded a fragment, then POKE_LEN will be set. - We need to poke the requested amount of the memory object - so that the kernel will write out the data to the new location - at a suitable time. */ - if (poke_len) - { - mach_port_t obj; - - obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); - poke_pages (obj, trunc_page (poke_off), - round_page (poke_off + poke_len)); - mach_port_deallocate (mach_task_self (), obj); - } - return err; } -- cgit v1.2.3 From 3003ecec8c44251f02d39d8233b2103a0cc7426b Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 15:28:35 +0000 Subject: (swab_disk): New variable. (swab_short, swab_long): New functions. --- ufs/ufs.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index ca186434..68a5dece 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -112,6 +112,9 @@ enum compat_mode of the dinode. */ int direct_symlink_extension; +/* If this is set, then the disk is byteswapped from native order. */ +int swab_disk; + /* Handy macros */ #define DEV_BSIZE 512 @@ -165,6 +168,26 @@ sync_dinode (int inum, int wait) { sync_disk_blocks (ino_to_fsba (sblock, inum), sblock->fs_fsize, wait); } + + +/* Functions for byte swapping */ +extern inline short +swab_short (short arg) +{ + return (((arg & 0xff) << 8) + | ((arg & 0xff00) >> 8)); +} + +extern inline long +swab_long (long arg) +{ + return (((arg & 0xff) << 24) + | ((arg & 0xff00) << 8) + | ((arg & 0xff0000) >> 8) + | ((arg & 0xff000000) >> 24)); +} + + /* From alloc.c: */ error_t ffs_alloc (struct node *, daddr_t, daddr_t, int, daddr_t *, -- cgit v1.2.3 From ce8b74e2cfc6ec5a1512058fd48569193dfafc87 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 15:57:05 +0000 Subject: (swab_sblock, swab_csums): New functions. (get_hypermetadata): If this is a swapped filesystem, set swab_disk. Also swap csum and sblock after reading them. (diskfs_set_hypermetadata): If swab_disk, swap the csums back before writing them. (copy_sblock): If swab_disk, swap the sblock before writing it. --- ufs/hyper.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index be51b360..283a7e14 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -29,6 +29,106 @@ vm_address_t zeroblock; struct fs *sblock; struct csum *csum; +void +swab_sblock (struct fs *sblock) +{ + int i, j; + + sblock->fs_sblkno = swab_long (sblock->fs_sblkno); + sblock->fs_cblkno = swab_long (sblock->fs_cblkno); + sblock->fs_iblkno = swab_long (sblock->fs_iblkno); + sblock->fs_dblkno = swab_long (sblock->fs_dblkno); + sblock->fs_cgoffset = swab_long (sblock->fs_cgoffset); + sblock->fs_cgmask = swab_long (sblock->fs_cgmask); + sblock->fs_time = swab_long (sblock->fs_time); + sblock->fs_size = swab_long (sblock->fs_size); + sblock->fs_dsize = swab_long (sblock->fs_dsize); + sblock->fs_ncg = swab_long (sblock->fs_ncg); + sblock->fs_bsize = swab_long (sblock->fs_bsize); + sblock->fs_fsize = swab_long (sblock->fs_fsize); + sblock->fs_frag = swab_long (sblock->fs_frag); + sblock->fs_minfree = swab_long (sblock->fs_minfree); + sblock->fs_rotdelay = swab_long (sblock->fs_rotdelay); + sblock->fs_rps = swab_long (sblock->fs_rps); + sblock->fs_bmask = swab_long (sblock->fs_bmask); + sblock->fs_fmask = swab_long (sblock->fs_fmask); + sblock->fs_bshift = swab_long (sblock->fs_bshift); + sblock->fs_fshift = swab_long (sblock->fs_fshift); + sblock->fs_maxcontig = swab_long (sblock->fs_maxcontig); + sblock->fs_maxbpg = swab_long (sblock->fs_maxbpg); + sblock->fs_fragshift = swab_long (sblock->fs_fragshift); + sblock->fs_fsbtodb = swab_long (sblock->fs_fsbtodb); + sblock->fs_sbsize = swab_long (sblock->fs_sbsize); + sblock->fs_csmask = swab_long (sblock->fs_csmask); + sblock->fs_csshift = swab_long (sblock->fs_csshift); + sblock->fs_nindir = swab_long (sblock->fs_nindir); + sblock->fs_inopb = swab_long (sblock->fs_inopb); + sblock->fs_nspf = swab_long (sblock->fs_nspf); + sblock->fs_optim = swab_long (sblock->fs_optim); + sblock->fs_npsect = swab_long (sblock->fs_npsect); + sblock->fs_interleave = swab_long (sblock->fs_interleave); + sblock->fs_trackskew = swab_long (sblock->fs_trackskew); + sblock->fs_headswitch = swab_long (sblock->fs_headswitch); + sblock->fs_trkseek = swab_long (sblock->fs_trkseek); + sblock->fs_csaddr = swab_long (sblock->fs_csaddr); + sblock->fs_cssize = swab_long (sblock->fs_cssize); + sblock->fs_cgsize = swab_long (sblock->fs_cgsize); + sblock->fs_ntrak = swab_long (sblock->fs_ntrak); + sblock->fs_nsect = swab_long (sblock->fs_nsect); + sblock->fs_spc = swab_long (sblock->fs_spc); + sblock->fs_ncyl = swab_long (sblock->fs_ncyl); + sblock->fs_cpg = swab_long (sblock->fs_cpg); + sblock->fs_ipg = swab_long (sblock->fs_ipg); + sblock->fs_fpg = swab_long (sblock->fs_fpg); + sblock->fs_cstotal.cs_ndir = swab_long (sblock->fs_cstotal.cs_ndir); + sblock->fs_cstotal.cs_nbfree = swab_long (sblock->fs_cstotal.cs_nbfree); + sblock->fs_cstotal.cs_nifree = swab_long (sblock->fs_cstotal.cs_nifree); + sblock->fs_cstotal.cs_nffree = swab_long (sblock->fs_cstotal.cs_nffree); + /* fs_fmod, fs_clean, fs_ronly, fs_flags, fs_fsmnt are all char */ + sblock->fs_cgrotor = swab_long (sblock->fs_cgrotor); + sblock->fs_cpc = swab_long (sblock->fs_cpc); + sblock->fs_contigsumsize = swab_long (sblock->fs_contigsumsize); + sblock->fs_maysymlinksen = swab_long (sblock->fs_maysymlinksen); + sblock->fs_inodefmt = swab_long (sblock->fs_inodefmt); + sblock->fs_maxfilesize.val[0] = swab_long (sblock->fs_maxfilesize.val[0]); + sblock->fs_maxfilesize.val[1] = swab_long (sblock->fs_maxfilesize.val[1]); + sblock->fs_qbmask.val[0] = swab_long (sblock->fs_qbmask.val[0]); + sblock->fs_qbmask.val[1] = swab_long (sblock->fs_qbmask.val[1]); + sblock->fs_state = swab_long (sblock->fs_state); + sblock->fs_postblformat = swab_long (sblock->fs_postblformat); + sblock->fs_nrpos = swab_long (sblock->fs_nrpos); + sblock->fs_postbloff = swab_long (sblock->fs_postbloff); + sblock->fs_rotbloff = swab_long (sblock->fs_rotbloff); + sblock->fs_magic = swab_long (sblock->fs_magic); + + /* Tables */ + if (sblock->fs_postblformat == FS_42POSTBLFMT) + for (i = 0; i < 16; i++) + for (j = 0; j < 8; j++) + sblock->fs_opostbl[i][j] = swab_short (sblock->fs_opostbl[i][j]); + else + for (i = 0; i < sblock->fs_cpc; i++) + for (j = 0; j < sblock->fs_nrpos; j++) + fs_postbl(sblock, j)[i] + = swab_short (sblock->fs_postbl (sblock, j)[i]); + + /* The rot table is all chars */ +} + +void +swab_csums (struct csum *csum) +{ + int i; + + for (i = 0; i < fs_ncg; i++) + { + csum[i].cs_ndir = swab_long (csum[i].cs_ndir); + csum[i].cs_nbfree = swab_long (csum[i].cs_nbfree); + csum[i].cs_nifree = swab_long (csum[i].cs_nifree); + csum[i].cs_nffree = swab_long (csum[i].cs_nffree); + } +} + void get_hypermetadata (void) { @@ -48,6 +148,14 @@ get_hypermetadata (void) bcopy (disk_image + SBOFF, sblock, SBSIZE); diskfs_end_catch_exception (); + if ((swab_long (sblock->fs_magic)) == FS_MAGIC) + { + swab_disk = 1; + swab_sblock (sblock); + } + else + swab_disk = 0; + if (sblock->fs_magic != FS_MAGIC) { fprintf (stderr, "Bad magic number %#lx (should be %#x)\n", @@ -138,6 +246,9 @@ get_hypermetadata (void) fsaddr (sblock, howmany (sblock->fs_cssize, sblock->fs_fsize))); diskfs_end_catch_exception (); + if (swab_disk) + swab_csums (csum); + if ((diskfs_device_size << diskfs_log2_device_block_size) < sblock->fs_size * sblock->fs_fsize) { @@ -188,6 +299,8 @@ diskfs_set_hypermetadata (int wait, int clean) if (!err) { bcopy (csum, (void *) buf, sblock->fs_cssize); + if (swab_disk) + swab_csums ((struct csum *)buf); diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr), buf, bufsize); csum_dirty = 0; @@ -224,7 +337,8 @@ copy_sblock () assert (! diskfs_readonly); if (sblock->fs_postblformat == FS_42POSTBLFMT - || oldformat) + || oldformat + || swab_disk) { char sblockcopy[SBSIZE]; struct fs *sbcopy = (struct fs *)sblockcopy; @@ -237,6 +351,8 @@ copy_sblock () sbcopy->fs_qbmask = -1; sbcopy->fs_qfmask = -1; } + if (swab_disk) + swab_sblock (sbcopy); bcopy (sbcopy, disk_image + SBOFF, SBSIZE); } else -- cgit v1.2.3 From 61f4a11558fc9436b48307fb9ca5c3bc3bb26182 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 16:02:54 +0000 Subject: (read_disk_entry): New macro. --- ufs/ufs.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 68a5dece..ba778e1d 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -186,6 +186,21 @@ swab_long (long arg) | ((arg & 0xff0000) >> 8) | ((arg & 0xff000000) >> 24)); } + +/* Return *ENTRYP, after byteswapping it if necessary */ +#define read_disk_entry(entryp) \ +({ \ + if (!swab_disk || sizeof (*entryp) == 1) \ + *entryp; \ + else if (sizeof (*entryp) == 2) \ + swab_short (*entryp); \ + else if (sizeof (*entry) == 4) \ + swab_long (*entryp); \ + else \ + abort; \ +}) + + -- cgit v1.2.3 From 5f9cfa422098196ff6b98656fe192193d4f699bb Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 17:59:46 +0000 Subject: (ffs_realloccg): Use read/write_disk_entry when reading/writing on-disk inode fields. (ffs_blkpref): Use read_disk_entry when reading from BAP array. (swab_cg, read_cg, release_cg): New functions. (ffs_fragextend, ffs_alloccg, ffs_nodealloccg, ffs_blkfree, diskfs_free_node): Use new cg access functions. --- ufs/alloc.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 158 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 4cbac331..fdd0aa59 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -89,6 +89,117 @@ alloc_sync (struct node *np) } } +/* Byteswap everything in CGP. */ +void +swab_cg (struct cg *cgp) +{ + int i, j; + + if (swab_long (cg->cg_magic) == CG_MAGIC + || cg->cg_magic == CG_MAGIC) + { + cg->cg_magic = swab_long (cg->cg_magic); + cg->cg_time = swab_long (cg->cg_time); + cg->cg_cgx = swab_long (cg->cg_cgx); + cg->cg_ncyl = swab_short (cg->cg_ncyl); + cg->cg_niblk = swab_short (cg->cg_niblk); + cg->cg_cs.cs_ndir = swab_long (cg->cg_cs.cs_ndir); + cg->cg_cs.cs_nbfree = swab_long (cg->cg_cs.cs_nbfree); + cg->cg_cs.cs_nifree = swab_long (cg->cg_cs.cs_nifree); + cg->cg_cs.cs_nffree = swab_long (cg->cg_cs.cs_nffree); + cg->cg_rotor = swab_long (cg->cg_rotor); + cg->cg_irotor = swab_long (cg->cg_irotor); + for (i = 0; i < MAXFRAG; i++) + cg->cg_frsum[i] = swab_long (cg->cg_frsum[i]); + cg->cg_btotoff = swab_long (cg->cg_btotoff); + cg->cg_boff = swab_long (cg->cg_boff); + cg->cg_iusedoff = swab_long (cg->cg_iusedoff); + cg->cg_freeoff = swab_long (cg->cg_freeoff); + cg->cg_nextfreeoff = swab_long (cg->cg_nextfreeoff); + cg->cg_clustersumoff = swab_long (cg->cg_clustersumoff); + cg->cg_clusteroff = swab_long (cg->cg_clusteroff); + cg->cg_nclusterblks = swab_long (cg->cg_nclusterblks); + + /* blktot map */ + for (i = 0; i < cg->cg_ncyl; i++) + cg_blktot(cg)[i] = swab_long (cg_blktot(cg)[i]); + + /* blks map */ + for (i = 0; i < cg->cg_ncyl; i++) + for (j = 0; j < sblock->fs_nrpos; j++) + cg_blks(sblock, cg, i)[j] = swab_short (cg_blks (sblock, cg, i)[j]); + + for (i = 0; i < sblock->fs_contigsumsize; i++) + cg_clustersum(cg)[i] = swab_long (cg_clustersum(cg)[i]); + + /* inosused, blksfree, and cg_clustersfree are char arrays */ + } + else + { + /* Old format cylinder group... */ + struct ocg *ocg = cg; + + if (swab_long (ocg->cg_magic) != CG_MAGIC + && ocg->cg_magic != CG_MAGIC) + return; + + ocg->cg_time = swab_long (ocg->cg_time); + ocg->cg_cgx = swab_long (ocg->cg_cgx); + ocg->cg_ncyl = swab_short (ocg->cg_ncyl); + ocg->cg_niblk = swab_short (ocg->cg_niblk); + ocg->cg_ndblk = swab_long (ocg->cg_ndblk); + ocg->cg_cs.cs_ndir = swab_long (ocg->cg_cs.cs_ndir); + ocg->cg_cs.cs_nbfree = swab_long (ocg->cg_cs.cs_nbfree); + ocg->cg_cs.cs_nifree = swab_long (ocg->cg_cs.cs_nifree); + ocg->cg_cs.cs_nffree = swab_long (ocg->cg_cs.cs_nffree); + ocg->cg_rotor = swab_long (ocg->cg_rotor); + ocg->cg_frotor = swab_long (ocg->cg_frotor); + ocg->cg_irotor = swab_long (ocg->cg_irotor); + for (i = 0; i < 8; i++) + ocg->cg_frsum[i] = swab_long (ocg->cg_frsum[i]); + for (i = 0; i < 32; i++) + ocg->cg_btot[i] = swab_long (ocg->cg_btot[i]); + for (i = 0; i < 32; i++) + for (j = 0; j < 8; j++) + ocg->cg_b[i][j] = swab_short (ocg->cg_b[i][j]); + ocg->cg_magic = swab_long (ocg->cg_magic); + } +} + + +/* Read cylinder group indexed CG. Set *CGPP to point at it. + Return 1 if caller should call release_cgp when we're done with it; + otherwise zero. */ +int +read_cg (int cg, struct cg **cgpp) +{ + struct cg *diskcg = cg_locate (cg); + + if (swab_disk) + { + *cgp = malloc (sblock->fs_cgsize); + bcopy (diskcg, *cgp, sblock->fs_cgsize); + swab_cg (*cgp); + return 1; + } + else + { + *cgp = diskcg; + return 0; + } +} + +/* Caller of read_cg is done with cg; write it back to disk (swapping it + along the way) and free the memory allocated in read_cg. */ +void +release_cgp (struct cg *cgp) +{ + swab_cg (cgp); + bcopy (cgp, cg_locate (cg), sblock->fs_cgsize); + free (cgp); +} + + /* * Allocate a block in the file system. * @@ -214,7 +325,7 @@ ffs_realloccg(register struct node *np, error = diskfs_catch_exception (); if (error) return error; - bprev = (dino (np->dn->number))->di_db[lbprev]; + bprev = read_disk_entry ((dino (np->dn->number))->di_db[lbprev]); diskfs_end_catch_exception (); assert ("old block not allocated" && bprev); @@ -674,7 +785,8 @@ ffs_blkpref(struct node *np, (ino_to_cg(fs, np->dn->number) + lbn / fs->fs_maxbpg); else - startcg = dtog(fs, bap[indx - 1]) + 1; + startcg = dtog(fs, + read_disk_entry (bap[indx - 1])) + 1; startcg %= fs->fs_ncg; avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg; for (cg = startcg; cg < fs->fs_ncg; cg++) @@ -699,9 +811,10 @@ ffs_blkpref(struct node *np, * next block is requested contiguously, otherwise it is * requested rotationally delayed by fs_rotdelay milliseconds. */ - nextblk = bap[indx - 1] + fs->fs_frag; - if (indx < fs->fs_maxcontig || bap[indx - fs->fs_maxcontig] + - blkstofrags(fs, fs->fs_maxcontig) != nextblk) + nextblk = read_disk_entry (bap[indx - 1]) + fs->fs_frag; + if (indx < fs->fs_maxcontig + || (read_disk_entry (bap[indx - fs->fs_maxcontig]) + + blkstofrags(fs, fs->fs_maxcontig) != nextblk)) { return (nextblk); } @@ -790,6 +903,7 @@ ffs_fragextend(struct node *np, long bno; int frags, bbase; int i; + int releasecg; fs = sblock; if (csum[cg].cs_nffree < numfrags(fs, nsize - osize)) @@ -809,10 +923,12 @@ ffs_fragextend(struct node *np, } cgp = (struct cg *)bp->b_data; #else - cgp = cg_locate (cg); + releasecg = read_cg (cg, &cgp); #endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ + if (releasecg) + release_cg (cgp); return 0; } cgp->cg_time = diskfs_mtime->seconds; @@ -820,6 +936,8 @@ ffs_fragextend(struct node *np, for (i = numfrags(fs, osize); i < frags; i++) if (isclr(cg_blksfree(cgp), bno + i)) { /* brelse(bp); */ + if (releasecg) + release_cg (cgp); return 0; } /* @@ -840,6 +958,8 @@ ffs_fragextend(struct node *np, fs->fs_cstotal.cs_nffree--; csum[cg].cs_nffree--; } + if (releasecg) + release_cg (cgp); record_poke (cgp, sblock->fs_cgsize); csum_dirty = 1; sblock_dirty = 1; @@ -864,6 +984,7 @@ ffs_alloccg(struct node *np, register struct cg *cgp; register int i; int bno, frags, allocsiz; + int releasecg; fs = sblock; if (csum[cg].cs_nbfree == 0 && size == fs->fs_bsize) @@ -877,17 +998,21 @@ ffs_alloccg(struct node *np, } cgp = (struct cg *)bp->b_data; #else - cgp = cg_locate (cg); + releasecg = read_cg (cg, &cgp); #endif if (!cg_chkmagic(cgp) || (cgp->cg_cs.cs_nbfree == 0 && size == fs->fs_bsize)) { /* brelse(bp); */ + if (releasecg) + release_cg (cgp); return 0; } cgp->cg_time = diskfs_mtime->seconds; if (size == fs->fs_bsize) { bno = ffs_alloccgblk(fs, cgp, bpref); /* bdwrite(bp); */ + if (releasecg) + release_cg (cgp); return (bno); } /* @@ -906,6 +1031,8 @@ ffs_alloccg(struct node *np, */ if (cgp->cg_cs.cs_nbfree == 0) { /* brelse(bp); */ + if (releasecg) + release_cg (cgp); return 0; } bno = ffs_alloccgblk(fs, cgp, bpref); @@ -919,6 +1046,8 @@ ffs_alloccg(struct node *np, fs->fs_fmod = 1; cgp->cg_frsum[i]++; + if (releasecg) + release_cg (cgp) record_poke (cgp, sblock->fs_cgsize); csum_dirty = 1; sblock_dirty = 1; @@ -928,6 +1057,8 @@ ffs_alloccg(struct node *np, bno = ffs_mapsearch(fs, cgp, bpref, allocsiz); if (bno < 0) { /* brelse(bp); */ + if (releasecg) + release_cg (cgp); return 0; } for (i = 0; i < frags; i++) @@ -939,6 +1070,8 @@ ffs_alloccg(struct node *np, cgp->cg_frsum[allocsiz]--; if (frags != allocsiz) cgp->cg_frsum[allocsiz - frags]++; + if (releasecg) + release_cg (cgp); record_poke (cgp, sblock->fs_cgsize); csum_dirty = 1; sblock_dirty = 1; @@ -1168,6 +1301,7 @@ ffs_nodealloccg(struct node *np, register struct fs *fs; register struct cg *cgp; int start, len, loc, map, i; + int releasecg; fs = sblock; if (csum[cg].cs_nifree == 0) @@ -1181,10 +1315,12 @@ ffs_nodealloccg(struct node *np, } cgp = (struct cg *)bp->b_data; #else - cgp = cg_locate (cg); + releasecg = read_cg (cg, &cgp); #endif if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) { /* brelse(bp); */ + if (releasecg) + release_cg (cg); return 0; } cgp->cg_time = diskfs_mtime->seconds; @@ -1224,6 +1360,8 @@ gotit: fs->fs_cstotal.cs_ndir++; csum[cg].cs_ndir++; } + if (releasecg) + release_cg (cgp); record_poke (cgp, sblock->fs_cgsize); csum_dirty = 1; sblock_dirty = 1; @@ -1247,6 +1385,7 @@ ffs_blkfree(register struct node *np, register struct cg *cgp; daddr_t blkno; int i, cg, blk, frags, bbase; + int releasecg; fs = sblock; assert ((u_int)size <= fs->fs_bsize && !fragoff (fs, size)); @@ -1265,10 +1404,12 @@ ffs_blkfree(register struct node *np, } cgp = (struct cg *)bp->b_data; #else - cgp = cg_locate (cg); + releasecg = cg_read (cg, &cgp); #endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ + if (releasecg) + release_cg (cgp); return; } cgp->cg_time = diskfs_mtime->seconds; @@ -1324,6 +1465,8 @@ ffs_blkfree(register struct node *np, cg_blktot(cgp)[i]++; } } + if (releasecg) + release_cg (cgp); record_poke (cgp, sblock->fs_cgsize); csum_dirty = 1; sblock_dirty = 1; @@ -1346,6 +1489,7 @@ diskfs_free_node (struct node *np, mode_t mode) register struct cg *cgp; ino_t ino = np->dn->number; int cg; + int releasecg; fs = sblock; assert (ino < fs->fs_ipg * fs->fs_ncg); @@ -1359,10 +1503,12 @@ diskfs_free_node (struct node *np, mode_t mode) } cgp = (struct cg *)bp->b_data; #else - cgp = cg_locate (cg); + releasecg = read_cg (cg, &cgp); #endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ + if (releasecg) + release_cg (cgp); return; } cgp->cg_time = diskfs_mtime->seconds; @@ -1383,6 +1529,8 @@ diskfs_free_node (struct node *np, mode_t mode) fs->fs_cstotal.cs_ndir--; csum[cg].cs_ndir--; } + if (releasecg) + release_cg (cgp); record_poke (cgp, sblock->fs_cgsize); csum_dirty = 1; sblock_dirty = 1; -- cgit v1.2.3 From 86bfb36dd0eacd54abe136718bd666e7459105fb Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:00:25 +0000 Subject: (swab_disk): New variable. (swab_short, swab_long): New functions. (read_disk_entry, write_disk_entry): New macros. --- ufs/ufs.h | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index ba778e1d..dba7acd9 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -187,19 +187,32 @@ swab_long (long arg) | ((arg & 0xff000000) >> 24)); } -/* Return *ENTRYP, after byteswapping it if necessary */ -#define read_disk_entry(entryp) \ +/* Return ENTRY, after byteswapping it if necessary */ +#define read_disk_entry(entry) \ ({ \ - if (!swab_disk || sizeof (*entryp) == 1) \ - *entryp; \ - else if (sizeof (*entryp) == 2) \ - swab_short (*entryp); \ - else if (sizeof (*entry) == 4) \ - swab_long (*entryp); \ + if (!swab_disk || sizeof (entry) == 1) \ + (entry); \ + else if (sizeof (entry) == 2) \ + swab_short (entry); \ + else if (sizeof (entry) == 4) \ + swab_long (entry); \ else \ - abort; \ + abort (); \ }) +/* Execute A = B, but byteswap it along the way if necessary */ +#define write_disk_entry(a,b) \ +({ \ + if (!swab_disk || sizeof (a) == 1) \ + ((a) = (b)); \ + else if (sizeof (a) == 2) \ + ((a) = (swab_short (b))); \ + else if (sizeof (a) == 4) \ + ((a) = (swab_long (b))); \ + else \ + abort (); \ +}) + -- cgit v1.2.3 From cd6391ab4b5ebb5e053f9cd00d34f2328ced41d0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:01:49 +0000 Subject: (diskfs_truncate): Use read/write_disk_entry when reading/writing on-disk indirect blocks. (diskfs_grow): Likewise. (indir_release): Likewise. (diskfs_truncate): Use read/write_disk_entry when reading/writing on-disk inode fields. (diskfs_grow): Likewise. --- ufs/sizes.c | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 87346175..a5be68ea 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -142,7 +142,7 @@ diskfs_truncate (struct node *np, if (di->di_db[i]) { long bsize = blksize (sblock, np, i); - ffs_blkfree (np, di->di_db[i], bsize); + ffs_blkfree (np, read_disk_entry (di->di_db[i]), bsize); di->di_db[i] = 0; blocksfreed += btodb (bsize); } @@ -156,7 +156,8 @@ diskfs_truncate (struct node *np, for (i = indirs[0].offset + 1; i < NINDIR (sblock); i++) if (sindir[i]) { - ffs_blkfree (np, sindir[i], sblock->fs_bsize); + ffs_blkfree (np, read_disk_entry (sindir[i]), + sblock->fs_bsize); sindir[i] = 0; blocksfreed += btodb (sblock->fs_bsize); } @@ -170,7 +171,9 @@ diskfs_truncate (struct node *np, /* ...mapped from the inode */ if (di->di_ib[INDIR_SINGLE] && indirs[1].offset == -2) { - blocksfreed += indir_release (np, di->di_ib[INDIR_SINGLE], + blocksfreed += indir_release (np, + read_disk_entry (di->di_ib + [INDIR_SINGLE]), INDIR_SINGLE); di->di_ib[INDIR_SINGLE] = 0; } @@ -184,7 +187,9 @@ diskfs_truncate (struct node *np, for (i = indirs[1].offset + 1; i < NINDIR (sblock); i++) if (dindir[i]) { - blocksfreed += indir_release (np, dindir[i], INDIR_SINGLE); + blocksfreed += indir_release (np, + read_disk_entry (dindir[i]), + INDIR_SINGLE); dindir[i] = 0; } record_poke (dindir, sblock->fs_bsize); @@ -197,7 +202,9 @@ diskfs_truncate (struct node *np, { if (di->di_ib[INDIR_DOUBLE]) { - blocksfreed += indir_release (np, di->di_ib[INDIR_DOUBLE], + blocksfreed += indir_release (np, + read_disk_entry (di->di_ib + [INDIR_DOUBLE]), INDIR_DOUBLE); di->di_ib[INDIR_DOUBLE] = 0; } @@ -210,7 +217,7 @@ diskfs_truncate (struct node *np, long oldspace, newspace; daddr_t bn; - bn = di->di_db[lbn]; + bn = read_disk_entry (di->di_db[lbn]); oldspace = blksize (sblock, np, lbn); np->allocsize = fragroundup (sblock, length); newspace = blksize (sblock, np, lbn); @@ -297,11 +304,11 @@ indir_release (struct node *np, daddr_t bno, int level) { if (level == INDIR_SINGLE) { - ffs_blkfree (np, addrs[i], sblock->fs_bsize); + ffs_blkfree (np, read_disk_entry (addrs[i]), sblock->fs_bsize); count += btodb (sblock->fs_bsize); } else - count += indir_release (np, addrs[i], level - 1); + count += indir_release (np, read_disk_entry (addrs[i]), level - 1); } /* Subtlety: this block is no longer necessary; the information @@ -391,7 +398,7 @@ block_extended (struct node *np, we deallocate the old block. */ for (off = 0; off < round_page (old_size); off += vm_page_size) { - diskfs_device_read_sync (fsbtodb (old_pbn) + off / DEV_BSIZE, + diskfs_device_read_sync (fsbtodb (sblock, old_pbn) + off / DEV_BSIZE, (void *) &buf, vm_page_size); /* If this page is the last one, then zero the excess first */ if (off + vm_page_size > old_size) @@ -467,8 +474,8 @@ diskfs_grow (struct node *np, osize, sblock->fs_bsize, &bno, cred); if (err) goto out; - old_pbn = di->di_db[olbn]; - di->di_db[olbn] = bno; + old_pbn = read_disk_entry (di->di_db[olbn]); + write_disk_entry (di->di_db[olbn], bno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; @@ -478,7 +485,7 @@ diskfs_grow (struct node *np, if (lbn < NDADDR) { - daddr_t bno, old_pbn = di->di_db[lbn]; + daddr_t bno, old_pbn = read_disk_entry (di->di_db[lbn]); if (old_pbn != 0) { @@ -494,7 +501,7 @@ diskfs_grow (struct node *np, if (err) goto out; - di->di_db[lbn] = bno; + write_disk_entry (di->di_db[lbn], bno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; @@ -509,7 +516,7 @@ diskfs_grow (struct node *np, if (err) goto out; - di->di_db[lbn] = bno; + write_disk_entry (di->di_db[lbn], bno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; @@ -551,7 +558,8 @@ diskfs_grow (struct node *np, if (err) goto out; zero_disk_block (bno); - indirs[1].bno = di->di_ib[INDIR_SINGLE] = bno; + indirs[1].bno = bno; + write_disk_entry (di->di_ib[INDIR_SINGLE], bno); record_poke (di, sizeof (struct dinode)); } else @@ -572,7 +580,8 @@ diskfs_grow (struct node *np, if (err) goto out; zero_disk_block (bno); - indirs[2].bno = di->di_ib[INDIR_DOUBLE] = bno; + indirs[2].bno = bno; + write_disk_entry (di->di_ib[INDIR_DOUBLE], bno); record_poke (di, sizeof (struct dinode)); } @@ -587,7 +596,8 @@ diskfs_grow (struct node *np, if (err) goto out; zero_disk_block (bno); - indirs[1].bno = diblock[indirs[1].offset] = bno; + indirs[1].bno = bno; + write_disk_entry (diblock[indirs[1].offset], bno); record_poke (diblock, sblock->fs_bsize); } } @@ -601,7 +611,8 @@ diskfs_grow (struct node *np, sblock->fs_bsize, &bno, 0); if (err) goto out; - indirs[0].bno = siblock[indirs[0].offset] = bno; + indirs[0].bno = bno; + write_disk_entry (siblock[indirs[0].offset], bno); record_poke (siblock, sblock->fs_bsize); offer_data (np, lbn, sblock->fs_bsize, zeroblock); } -- cgit v1.2.3 From 4056e0b628cbdbf394876ca9ebdde453f460ea4c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:08:24 +0000 Subject: (pager_unlock_page): Use read/write_disk_entry when reading/writing on-disk inode fields and indirect blocks. --- ufs/pager.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 8834f911..d4bc87c5 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -246,7 +246,8 @@ pager_unlock_page (struct user_pager_info *pager, assert (lblkno (sblock, address) < NDADDR); diskfs_device_write_sync (fsbtodb (sblock, bno), zeroblock, sblock->fs_bsize); - indirs[0].bno = di->di_db[lblkno (sblock, address)] = bno; + indirs[0].bno = bno; + write_disk_entry (di->di_db[lblkno (sblock, address)], bno); record_poke (di, sizeof (struct dinode)); } else @@ -266,7 +267,8 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; zero_disk_block (bno); - indirs[1].bno = di->di_ib[INDIR_SINGLE] = bno; + indirs[1].bno = bno; + write_disk_entry (di->di_ib[INDIR_SINGLE], bno); record_poke (di, sizeof (struct dinode)); } else @@ -290,7 +292,8 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; zero_disk_block (bno); - indirs[2].bno = di->di_ib[INDIR_DOUBLE] = bno; + indirs[2].bno = bno; + write_disk_entry (di->di_ib[INDIR_DOUBLE], bno); record_poke (di, sizeof (struct dinode)); } @@ -306,7 +309,8 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; zero_disk_block (bno); - indirs[1].bno = diblock[indirs[1].offset] = bno; + indirs[1].bno = bno; + write_disk_entry (diblock[indirs[1].offset], bno); record_poke (diblock, sblock->fs_bsize); } } @@ -326,7 +330,8 @@ pager_unlock_page (struct user_pager_info *pager, diskfs_device_write_sync (fsbtodb (sblock, bno), zeroblock, sblock->fs_bsize); - indirs[0].bno = siblock[indirs[0].offset] = bno; + indirs[0].bno = bno; + write_disk_entry (siblock[indirs[0].offset], bno); record_poke (siblock, sblock->fs_bsize); } } -- cgit v1.2.3 From 1b51f9842dd2ab2cc5c8366e443c39c2f8417234 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:09:23 +0000 Subject: (fetch_indir_spec): Use read/write_disk_entry when reading/writing on-disk inode fields and indirect blocks. --- ufs/bmap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/bmap.c b/ufs/bmap.c index 11756a66..1a138f39 100644 --- a/ufs/bmap.c +++ b/ufs/bmap.c @@ -1,5 +1,5 @@ /* Interpretation of indirect block structure - Copyright (C) 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. Written by Michael I. Bushnell. This file is part of the GNU Hurd. @@ -45,7 +45,7 @@ fetch_indir_spec (struct node *np, volatile daddr_t lbn, { if (lbn >= 0) { - indirs[0].bno = di->di_db[lbn]; + indirs[0].bno = read_disk_entry (di->di_db[lbn]); indirs[0].offset = -1; } @@ -72,12 +72,12 @@ fetch_indir_spec (struct node *np, volatile daddr_t lbn, assert (!(ibn / NINDIR (sblock))); indirs[2].offset = -1; - indirs[2].bno = di->di_ib[INDIR_DOUBLE]; + indirs[2].bno = read_disk_entry (di->di_ib[INDIR_DOUBLE]); if (indirs[2].bno) { diblock = indir_block (indirs[2].bno); - indirs[1].bno = diblock[indirs[1].offset]; + indirs[1].bno = read_disk_entry (diblock[indirs[1].offset]); } else indirs[1].bno = 0; @@ -85,13 +85,13 @@ fetch_indir_spec (struct node *np, volatile daddr_t lbn, else { indirs[1].offset = -1; - indirs[1].bno = di->di_ib[INDIR_SINGLE]; + indirs[1].bno = read_disk_entry (di->di_ib[INDIR_SINGLE]); } if (indirs[1].bno) { siblock = indir_block (indirs[1].bno); - indirs[0].bno = siblock[indirs[0].offset]; + indirs[0].bno = read_disk_entry (siblock[indirs[0].offset]); } else indirs[0].bno = 0; -- cgit v1.2.3 From 675192bc5f687f4956da875ef1c54a5e61bf5d54 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:11:37 +0000 Subject: (read_disknode): Use read/write_disk_entry when reading/writing on-disk inode fields. (write_node): Likewise. (diskfs_set_translator): Likewise. (diskfs_get_translator): Likewise. (diskfs_S_file_get_storage_info): Likewise. --- ufs/inode.c | 86 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 44 insertions(+), 42 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 88f89a37..b34c2f07 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -229,38 +229,39 @@ read_disknode (struct node *np) st->st_fstype = FSTYPE_UFS; st->st_fsid = fsid; st->st_ino = np->dn->number; - st->st_gen = di->di_gen; - st->st_rdev = di->di_rdev; - st->st_mode = di->di_model | (di->di_modeh << 16); - st->st_nlink = di->di_nlink; - st->st_size = di->di_size; + st->st_gen = read_disk_entry (di->di_gen); + st->st_rdev = read_disk_entry(di->di_rdev); + st->st_mode = (read_disk_entry (di->di_model) + | (read_disk_entry (di->di_modeh) << 16); + st->st_nlink = read_disk_entry (di->di_nlink); + st->st_size = read_disk_entry (di->di_size); #ifdef notyet st->st_atimespec = di->di_atime; st->st_mtimespec = di->di_mtime; st->st_ctimespec = di->di_ctime; #else - st->st_atime = di->di_atime.ts_sec; - st->st_atime_usec = di->di_atime.ts_nsec / 1000; - st->st_mtime = di->di_mtime.ts_sec; - st->st_mtime_usec = di->di_mtime.ts_nsec / 1000; - st->st_ctime = di->di_ctime.ts_sec; - st->st_ctime_usec = di->di_ctime.ts_nsec / 1000; + st->st_atime = read_disk_entry (di->di_atime.ts_sec); + st->st_atime_usec = read_disk_entry (di->di_atime.ts_nsec) / 1000; + st->st_mtime = read_disk_entry (di->di_mtime.ts_sec); + st->st_mtime_usec = read_disk_entry (di->di_mtime.ts_nsec) / 1000; + st->st_ctime = read_disk_entry (di->di_ctime.ts_sec); + st->st_ctime_usec = read_disk_entry (di->di_ctime.ts_nsec) / 1000; #endif st->st_blksize = sblock->fs_bsize; - st->st_blocks = di->di_blocks; - st->st_flags = di->di_flags; + st->st_blocks = read_disk_entry (di->di_blocks); + st->st_flags = read_disk_entry (di->di_flags); if (sblock->fs_inodefmt < FS_44INODEFMT) { - st->st_uid = di->di_ouid; - st->st_gid = di->di_ogid; + st->st_uid = read_disk_entry (di->di_ouid); + st->st_gid = read_disk_entry (di->di_ogid); st->st_author = 0; } else { - st->st_uid = di->di_uid; - st->st_gid = di->di_gid; - st->st_author = di->di_author; + st->st_uid = read_disk_entry (di->di_uid); + st->st_gid = read_disk_entry (di->di_gid); + st->st_author = read_disk_entry (di->di_author); if (st->st_author == -1) st->st_author = st->st_uid; } @@ -305,55 +306,55 @@ write_node (struct node *np) if (err) return; - di->di_gen = st->st_gen; + write_disk_entry (di->di_gen, st->st_gen); if (S_ISBLK (st->st_mode) || S_ISCHR (st->st_mode)) - di->di_rdev = st->st_rdev; + write_disk_entry (di->di_rdev, st->st_rdev); /* We happen to know that the stat mode bits are the same as the ufs mode bits. */ if (compat_mode == COMPAT_GNU) { - di->di_model = st->st_mode & 0xffff; - di->di_modeh = (st->st_mode >> 16) & 0xffff; + write_disk_entry (di->di_model, st->st_mode & 0xffff); + write_disk_entry (di->di_modeh, (st->st_mode >> 16) & 0xffff); } else { - di->di_model = st->st_mode & 0xffff; + write_disk_entry (di->di_model, st->st_mode & 0xffff); di->di_modeh = 0; } if (compat_mode != COMPAT_BSD42) { - di->di_uid = st->st_uid; - di->di_gid = st->st_gid; + write_disk_entry (di->di_uid, st->st_uid); + write_disk_entry (di->di_gid, st->st_gid); } if (sblock->fs_inodefmt < FS_44INODEFMT) { - di->di_ouid = st->st_uid & 0xffff; - di->di_ogid = st->st_gid & 0xffff; + write_disk_entry (di->di_ouid, st->st_uid & 0xffff); + write_disk_entry (di->di_ogid, st->st_gid & 0xffff); } else if (compat_mode == COMPAT_GNU) - di->di_author = st->st_author; + write_disk_entry (di->di_author, st->st_author); - di->di_nlink = st->st_nlink; - di->di_size = st->st_size; + write_disk_entry (di->di_nlink, st->st_nlink); + write_disk_entry (di->di_size, st->st_size); #ifdef notyet di->di_atime = st->st_atimespec; di->di_mtime = st->st_mtimespec; di->di_ctime = st->st_ctimespec; #else - di->di_atime.ts_sec = st->st_atime; - di->di_atime.ts_nsec = st->st_atime_usec * 1000; - di->di_mtime.ts_sec = st->st_mtime; - di->di_mtime.ts_nsec = st->st_mtime_usec * 1000; - di->di_ctime.ts_sec = st->st_ctime; - di->di_ctime.ts_nsec = st->st_ctime_usec * 1000; + write_disk_entry (di->di_atime.ts_sec, st->st_atime); + write_disk_entry (di->di_atime.ts_nsec, st->st_atime_usec * 1000); + write_disk_entry (di->di_mtime.ts_sec, st->st_mtime); + write_disk_entry (di->di_mtime.ts_nsec, st->st_mtime_usec * 1000); + write_disk_entry (di->di_ctime.ts_sec, st->st_ctime); + write_disk_entry (di->di_ctime.ts_nsec, st->st_ctime_usec * 1000); #endif - di->di_blocks = st->st_blocks; - di->di_flags = st->st_flags; + write_disk_entry (di->di_blocks, st->st_blocks); + write_disk_entry (di->di_flags, st->st_flags); diskfs_end_catch_exception (); np->dn_stat_dirty = 0; @@ -524,7 +525,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, return err; di = dino (np->dn->number); - blkno = di->di_trans; + blkno = read_disk_entry (di->di_trans); if (namelen && !blkno) { @@ -535,7 +536,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, diskfs_end_catch_exception (); return err; } - di->di_trans = blkno; + write_disk_entry (di->di_trans, blkno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; } @@ -580,7 +581,7 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) if (err) return err; - blkno = (dino (np->dn->number))->di_trans; + blkno = read_disk_entry ((dino (np->dn->number))->di_trans); assert (blkno); transloc = disk_image + fsaddr (sblock, blkno); @@ -670,7 +671,8 @@ diskfs_S_file_get_storage_info (struct protid *cred, { for (i = 0; i < NDADDR; i++) { - (*addresses)[2 * i] = fsbtodb (sblock, di->di_db[i]); + (*addresses)[2 * i] = fsbtodb (sblock, + read_disk_entry (di->di_db[i])); if ((i + 1) * sblock->fs_bsize > np->allocsize) (*addresses)[2 * i + 1] = np->allocsize - i * sblock->fs_bsize; else -- cgit v1.2.3 From 4e2aa139eaca196f8479e52bb73a30029d534a8e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:17:36 +0000 Subject: Include . Fixup. --- ufs/alloc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index fdd0aa59..9efd2eb3 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -55,6 +55,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" #include +#include + /* These don't work *at all* here; don't even try setting them. */ #undef DIAGNOSTIC @@ -91,7 +93,7 @@ alloc_sync (struct node *np) /* Byteswap everything in CGP. */ void -swab_cg (struct cg *cgp) +swab_cg (struct cg *cg) { int i, j; @@ -177,14 +179,14 @@ read_cg (int cg, struct cg **cgpp) if (swab_disk) { - *cgp = malloc (sblock->fs_cgsize); - bcopy (diskcg, *cgp, sblock->fs_cgsize); - swab_cg (*cgp); + *cgpp = malloc (sblock->fs_cgsize); + bcopy (diskcg, *cgpp, sblock->fs_cgsize); + swab_cg (*cgpp); return 1; } else { - *cgp = diskcg; + *cgpp = diskcg; return 0; } } @@ -194,8 +196,9 @@ read_cg (int cg, struct cg **cgpp) void release_cgp (struct cg *cgp) { + int cgx = cgp->cg_cgx; swab_cg (cgp); - bcopy (cgp, cg_locate (cg), sblock->fs_cgsize); + bcopy (cgp, cg_locate (cgx), sblock->fs_cgsize); free (cgp); } -- cgit v1.2.3 From dbfeebc5456f832d8b6daf0b563587b5e4ca4f91 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:20:26 +0000 Subject: (read_disk_entry): Proper syntax. --- ufs/ufs.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index dba7acd9..2c1a3fde 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -190,14 +190,16 @@ swab_long (long arg) /* Return ENTRY, after byteswapping it if necessary */ #define read_disk_entry(entry) \ ({ \ + typeof (entry) ret; \ if (!swab_disk || sizeof (entry) == 1) \ - (entry); \ + ret = (entry); \ else if (sizeof (entry) == 2) \ - swab_short (entry); \ + ret = swab_short (entry); \ else if (sizeof (entry) == 4) \ - swab_long (entry); \ + ret = swab_long (entry); \ else \ abort (); \ + ret; \ }) /* Execute A = B, but byteswap it along the way if necessary */ -- cgit v1.2.3 From 15ec6058ff8a845747c1f59e815806304b7c7e57 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:32:36 +0000 Subject: (ffs_blkfree): final fixup. --- ufs/alloc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 9efd2eb3..90ce68f5 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -139,7 +139,7 @@ swab_cg (struct cg *cg) else { /* Old format cylinder group... */ - struct ocg *ocg = cg; + struct ocg *ocg = (struct ocg *) cg; if (swab_long (ocg->cg_magic) != CG_MAGIC && ocg->cg_magic != CG_MAGIC) @@ -194,7 +194,7 @@ read_cg (int cg, struct cg **cgpp) /* Caller of read_cg is done with cg; write it back to disk (swapping it along the way) and free the memory allocated in read_cg. */ void -release_cgp (struct cg *cgp) +release_cg (struct cg *cgp) { int cgx = cgp->cg_cgx; swab_cg (cgp); @@ -902,7 +902,7 @@ ffs_fragextend(struct node *np, int nsize) { register struct fs *fs; - register struct cg *cgp; + struct cg *cgp; long bno; int frags, bbase; int i; @@ -984,7 +984,7 @@ ffs_alloccg(struct node *np, int size) { register struct fs *fs; - register struct cg *cgp; + struct cg *cgp; register int i; int bno, frags, allocsiz; int releasecg; @@ -1050,7 +1050,7 @@ ffs_alloccg(struct node *np, cgp->cg_frsum[i]++; if (releasecg) - release_cg (cgp) + release_cg (cgp); record_poke (cgp, sblock->fs_cgsize); csum_dirty = 1; sblock_dirty = 1; @@ -1302,7 +1302,7 @@ ffs_nodealloccg(struct node *np, int mode) { register struct fs *fs; - register struct cg *cgp; + struct cg *cgp; int start, len, loc, map, i; int releasecg; @@ -1323,7 +1323,7 @@ ffs_nodealloccg(struct node *np, if (!cg_chkmagic(cgp) || cgp->cg_cs.cs_nifree == 0) { /* brelse(bp); */ if (releasecg) - release_cg (cg); + release_cg (cgp); return 0; } cgp->cg_time = diskfs_mtime->seconds; @@ -1385,7 +1385,7 @@ ffs_blkfree(register struct node *np, long size) { register struct fs *fs; - register struct cg *cgp; + struct cg *cgp; daddr_t blkno; int i, cg, blk, frags, bbase; int releasecg; @@ -1407,7 +1407,7 @@ ffs_blkfree(register struct node *np, } cgp = (struct cg *)bp->b_data; #else - releasecg = cg_read (cg, &cgp); + releasecg = read_cg (cg, &cgp); #endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ @@ -1489,7 +1489,7 @@ void diskfs_free_node (struct node *np, mode_t mode) { register struct fs *fs; - register struct cg *cgp; + struct cg *cgp; ino_t ino = np->dn->number; int cg; int releasecg; -- cgit v1.2.3 From 1f5db073a1c103fc54f9568c53d3d0c17fd32767 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:35:14 +0000 Subject: (diskfs_dirempty): node_update -> diskfs_node_update. --- ufs/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 67b3645e..ed7ac212 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -718,14 +718,14 @@ diskfs_dirempty(struct node *dp, if (!diskfs_readonly) dp->dn_set_atime = 1; if (diskfs_synchronous) - node_update (dp, 1); + diskfs_node_update (dp, 1); return 0; } } if (!diskfs_readonly) dp->dn_set_atime = 1; if (diskfs_synchronous) - node_update (dp, 1); + diskfs_node_update (dp, 1); vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); return 1; } -- cgit v1.2.3 From 6aa169da3b5c81865dd35e7e19db0b29ba446f5b Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:40:42 +0000 Subject: fixup. --- ufs/hyper.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 283a7e14..f198ff43 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -88,12 +88,10 @@ swab_sblock (struct fs *sblock) sblock->fs_cgrotor = swab_long (sblock->fs_cgrotor); sblock->fs_cpc = swab_long (sblock->fs_cpc); sblock->fs_contigsumsize = swab_long (sblock->fs_contigsumsize); - sblock->fs_maysymlinksen = swab_long (sblock->fs_maysymlinksen); + sblock->fs_maxsymlinklen = swab_long (sblock->fs_maxsymlinklen); sblock->fs_inodefmt = swab_long (sblock->fs_inodefmt); - sblock->fs_maxfilesize.val[0] = swab_long (sblock->fs_maxfilesize.val[0]); - sblock->fs_maxfilesize.val[1] = swab_long (sblock->fs_maxfilesize.val[1]); - sblock->fs_qbmask.val[0] = swab_long (sblock->fs_qbmask.val[0]); - sblock->fs_qbmask.val[1] = swab_long (sblock->fs_qbmask.val[1]); + sblock->fs_maxfilesize = swab_long_long (sblock->fs_maxfilesize); + sblock->fs_qbmask = swab_long_long (sblock->fs_qbmask); sblock->fs_state = swab_long (sblock->fs_state); sblock->fs_postblformat = swab_long (sblock->fs_postblformat); sblock->fs_nrpos = swab_long (sblock->fs_nrpos); @@ -110,7 +108,7 @@ swab_sblock (struct fs *sblock) for (i = 0; i < sblock->fs_cpc; i++) for (j = 0; j < sblock->fs_nrpos; j++) fs_postbl(sblock, j)[i] - = swab_short (sblock->fs_postbl (sblock, j)[i]); + = swab_short (fs_postbl (sblock, j)[i]); /* The rot table is all chars */ } @@ -120,7 +118,7 @@ swab_csums (struct csum *csum) { int i; - for (i = 0; i < fs_ncg; i++) + for (i = 0; i < sblock->fs_ncg; i++) { csum[i].cs_ndir = swab_long (csum[i].cs_ndir); csum[i].cs_nbfree = swab_long (csum[i].cs_nbfree); -- cgit v1.2.3 From b9050c0aaed61138e1df38d094e1c3bbf8d91e6a Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:43:36 +0000 Subject: (read_disknode): typo --- ufs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index b34c2f07..ab19668f 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -232,7 +232,7 @@ read_disknode (struct node *np) st->st_gen = read_disk_entry (di->di_gen); st->st_rdev = read_disk_entry(di->di_rdev); st->st_mode = (read_disk_entry (di->di_model) - | (read_disk_entry (di->di_modeh) << 16); + | (read_disk_entry (di->di_modeh) << 16)); st->st_nlink = read_disk_entry (di->di_nlink); st->st_size = read_disk_entry (di->di_size); #ifdef notyet -- cgit v1.2.3 From eb186a7fc9ce5b4c35986128e52372142af8fc37 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:46:41 +0000 Subject: (swab_long): Cleaner now. (swab_long_long): New function. --- ufs/ufs.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 2c1a3fde..c09ddeeb 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -181,10 +181,15 @@ swab_short (short arg) extern inline long swab_long (long arg) { - return (((arg & 0xff) << 24) - | ((arg & 0xff00) << 8) - | ((arg & 0xff0000) >> 8) - | ((arg & 0xff000000) >> 24)); + return ((swab_short (arg & 0xffff) << 16) + | swab_short ((arg & 0xffff0000) >> 16)); +} + +extern inline long long +swab_long_long (long long arg) +{ + return ((swab_long (arg & 0xffffffff) << 32) + | swab_long ((arg & 0xffffffff00000000) >> 32)); } /* Return ENTRY, after byteswapping it if necessary */ -- cgit v1.2.3 From 8d744ba53bed7d40baab38f390df7b60a00fd9fc Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:47:47 +0000 Subject: fixup --- ufs/sizes.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index a5be68ea..8e4a85e9 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -361,7 +361,7 @@ offer_data (struct node *np, { vm_address_t addr; - len = round_page (size); + len = round_page (len); assert (start % vm_page_size == 0); @@ -402,7 +402,8 @@ block_extended (struct node *np, (void *) &buf, vm_page_size); /* If this page is the last one, then zero the excess first */ if (off + vm_page_size > old_size) - bzero (buf + old_size - off, vm_page_size - (old_size - off)); + bzero ((vod *)(buf + old_size - off), + vm_page_size - (old_size - off)); offer_data (np, lbn * sblock->fs_bsize + off, vm_page_size, buf); } -- cgit v1.2.3 From f2acd811f5a476bfbf37a4bbbfcf45ca96bde450 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:50:13 +0000 Subject: (swab_long_long, swab_long): better now. --- ufs/ufs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index c09ddeeb..19ea89c3 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -181,14 +181,14 @@ swab_short (short arg) extern inline long swab_long (long arg) { - return ((swab_short (arg & 0xffff) << 16) + return ((long) (swab_short (arg & 0xffff) << 16) | swab_short ((arg & 0xffff0000) >> 16)); } extern inline long long swab_long_long (long long arg) { - return ((swab_long (arg & 0xffffffff) << 32) + return ((long long)(swab_long (arg & 0xffffffff) << 32) | swab_long ((arg & 0xffffffff00000000) >> 32)); } -- cgit v1.2.3 From 2805a17914524c003abc82c42ca2abdd98235518 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:51:31 +0000 Subject: and even better --- ufs/ufs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 19ea89c3..9fa312e6 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -181,14 +181,14 @@ swab_short (short arg) extern inline long swab_long (long arg) { - return ((long) (swab_short (arg & 0xffff) << 16) + return (((long) swab_short (arg & 0xffff) << 16) | swab_short ((arg & 0xffff0000) >> 16)); } extern inline long long swab_long_long (long long arg) { - return ((long long)(swab_long (arg & 0xffffffff) << 32) + return (((long long) swab_long (arg & 0xffffffff) << 32) | swab_long ((arg & 0xffffffff00000000) >> 32)); } -- cgit v1.2.3 From c6edef3af846eae6e278a2930eb139a306f98108 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:53:41 +0000 Subject: (swab_long_long): one more time --- ufs/ufs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 9fa312e6..06255960 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -189,7 +189,7 @@ extern inline long long swab_long_long (long long arg) { return (((long long) swab_long (arg & 0xffffffff) << 32) - | swab_long ((arg & 0xffffffff00000000) >> 32)); + | swab_long ((arg & 0xffffffff00000000lL) >> 32)); } /* Return ENTRY, after byteswapping it if necessary */ -- cgit v1.2.3 From 8ac35134d6621e4753547c3ff201a653327f3b5f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 19:00:00 +0000 Subject: (block_extended): --- ufs/sizes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 8e4a85e9..98ec49d1 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -402,7 +402,7 @@ block_extended (struct node *np, (void *) &buf, vm_page_size); /* If this page is the last one, then zero the excess first */ if (off + vm_page_size > old_size) - bzero ((vod *)(buf + old_size - off), + bzero ((void *)(buf + old_size - off), vm_page_size - (old_size - off)); offer_data (np, lbn * sblock->fs_bsize + off, vm_page_size, buf); } -- cgit v1.2.3 From 71d8cb41e179e2359cf178493f34bbbb8f8c78d1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 24 Apr 1996 18:24:17 +0000 Subject: (DIRECT_NAMLEN) [LITTLE_ENDIAN]: Deal with case correctly where it was written without the extension on a big endian machine. --- ufs/dir.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.h b/ufs/dir.h index 193e167b..1c35768a 100644 --- a/ufs/dir.h +++ b/ufs/dir.h @@ -90,8 +90,9 @@ struct directory_entry { /* Return the namlen from a struct direct, paying attention to whether this filesystem supports the type extension */ #if (BYTE_ORDER == LITTLE_ENDIAN) -#define DIRECT_NAMLEN(dp) (direct_symlink_extension ? (dp)->d_namlen : \ - (dp)->d_type) +#define DIRECT_NAMLEN(dp) (direct_symlink_extension || swab_disk \ + ? (dp)->d_namlen \ + : (dp)->(dp)->d_type) #else #define DIRECT_NAMLEN(dp) ((dp)->d_namlen) #endif -- cgit v1.2.3 From 39a70332f87c9b83c6c18a4a4d8c23b4aaad69e0 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 24 Apr 1996 18:26:16 +0000 Subject: (DIRECT_NAMLEN) [! LITTLE_ENDIAN]: Deal correctly with the case where it was written on a little endian machine without the extension. --- ufs/dir.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.h b/ufs/dir.h index 1c35768a..2b1e3469 100644 --- a/ufs/dir.h +++ b/ufs/dir.h @@ -92,9 +92,11 @@ struct directory_entry { #if (BYTE_ORDER == LITTLE_ENDIAN) #define DIRECT_NAMLEN(dp) (direct_symlink_extension || swab_disk \ ? (dp)->d_namlen \ - : (dp)->(dp)->d_type) + : (dp)->d_type) #else -#define DIRECT_NAMLEN(dp) ((dp)->d_namlen) +#define DIRECT_NAMLEN(dp) (!direct_symlink_extension && swab_disk \ + ? (dp)->d_type \ + : (dp)->d_namlen) #endif /* -- cgit v1.2.3 From 3d3e9226d2a674801babedc7b439faeef8c68f1f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 26 Apr 1996 20:09:04 +0000 Subject: (makemode): Now `servers'. (targets): Renamed from `target'; now include ufs.static. (ufs.static-LDFLAGS): Renamed from `LDFLAGS'. (ufs.static): Depend on same things as `ufs'. (include ../Makeconf): Must come before dependency information. --- ufs/Makefile | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index a4601cce..280e155c 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -1,5 +1,5 @@ -# Copyright (C) 1994, 1995 Free Software Foundation +# Copyright (C) 1994, 1995, 1996 Free Software Foundation # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -16,17 +16,18 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. dir := ufs -makemode := server +makemode := servers -target = ufs +targets = ufs ufs.static SRCS = alloc.c consts.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c bmap.c pokeloc.c LCLHDRS = ufs.h fs.h dinode.h dir.h OBJS = $(SRCS:.c=.o) -LDFLAGS += -static - -ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libioserver/libioserver.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a +ufs.static-LDFLAGS += -static include ../Makeconf + +ufs.static ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libioserver/libioserver.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a + -- cgit v1.2.3 From 2817245407b6cf0cfcb6864ebe3e3cd4506db61c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 30 Apr 1996 17:38:37 +0000 Subject: (diskfs_grow): In last offer_data, don't offer a block number as an address. --- ufs/sizes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 98ec49d1..5694c0b5 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -615,7 +615,7 @@ diskfs_grow (struct node *np, indirs[0].bno = bno; write_disk_entry (siblock[indirs[0].offset], bno); record_poke (siblock, sblock->fs_bsize); - offer_data (np, lbn, sblock->fs_bsize, zeroblock); + offer_data (np, lbn * sblock->fs_bsize, sblock->fs_bsize, zeroblock); } out: -- cgit v1.2.3 From 865f3d52f7513d33b680a3396dbc98674eb107d1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 2 May 1996 14:56:04 +0000 Subject: (offer_data): Offer pages at ADDR each time through the loop, not the same page over and over. --- ufs/sizes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 5694c0b5..8bacb590 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -367,7 +367,7 @@ offer_data (struct node *np, assert (np->dn->fileinfo); for (addr = start; addr < start + len; addr += vm_page_size) - pager_offer_page (np->dn->fileinfo->p, 1, 0, start, buf + (addr - start)); + pager_offer_page (np->dn->fileinfo->p, 1, 0, addr, buf + (addr - start)); } /* Logical block LBN of node NP has been extended with ffs_realloccg. -- cgit v1.2.3 From 5b224569367f605c7c1bbf19f01f3a1e323205cc Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 2 May 1996 16:25:49 +0000 Subject: (block_extended): When moving data, sync in-core pager both before reading from disk and after providing data to kernel. (diskfs_grow): Always call block_extended or offer_data before adjusting block pointer. --- ufs/sizes.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 8bacb590..ee69c566 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -398,13 +398,31 @@ block_extended (struct node *np, we deallocate the old block. */ for (off = 0; off < round_page (old_size); off += vm_page_size) { + + /* There's *got* to be a better way to do this... */ + + /* Force it out to disk */ + assert (np->fileinfo); + pager_sync_some (np->fileinfo->p, lbn * sblock->fs_bsize + off, + vm_page_size, 1); + + /* Read it back in */ diskfs_device_read_sync (fsbtodb (sblock, old_pbn) + off / DEV_BSIZE, (void *) &buf, vm_page_size); /* If this page is the last one, then zero the excess first */ if (off + vm_page_size > old_size) bzero ((void *)(buf + old_size - off), vm_page_size - (old_size - off)); + + /* And make sure it's in core. */ offer_data (np, lbn * sblock->fs_bsize + off, vm_page_size, buf); + + /* And now, make sure it's on disk. (Why? Because a previous + write of this file, maybe even one from before we started + running may have been fsynced. We can't cause data already + on disk to be lossy at any time in the future while we move it. */ + pager_sync_some (np->fileinfo->p, lbn * sblock->fs_bsize + off, + vm_page_size, 1); } /* And deallocate the old block */ @@ -475,12 +493,13 @@ diskfs_grow (struct node *np, osize, sblock->fs_bsize, &bno, cred); if (err) goto out; + + block_extended (np, olbn, old_pbn, bno, osize, sblock->fs_bsize); + old_pbn = read_disk_entry (di->di_db[olbn]); write_disk_entry (di->di_db[olbn], bno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - - block_extended (np, olbn, old_pbn, bno, osize, sblock->fs_bsize); } } @@ -502,11 +521,11 @@ diskfs_grow (struct node *np, if (err) goto out; + block_extended (np, lbn, old_pbn, bno, osize, size); + write_disk_entry (di->di_db[lbn], bno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - - block_extended (np, lbn, old_pbn, bno, osize, size); } else { @@ -517,11 +536,11 @@ diskfs_grow (struct node *np, if (err) goto out; + + offer_data (np, lbn * sblock->fs_bsize, size, zeroblock); write_disk_entry (di->di_db[lbn], bno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; - - offer_data (np, lbn * sblock->fs_bsize, size, zeroblock); } } else @@ -612,10 +631,10 @@ diskfs_grow (struct node *np, sblock->fs_bsize, &bno, 0); if (err) goto out; + offer_data (np, lbn * sblock->fs_bsize, sblock->fs_bsize, zeroblock); indirs[0].bno = bno; write_disk_entry (siblock[indirs[0].offset], bno); record_poke (siblock, sblock->fs_bsize); - offer_data (np, lbn * sblock->fs_bsize, sblock->fs_bsize, zeroblock); } out: -- cgit v1.2.3 From 40db0923390045daf72e04f332ecb3017be2df1c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 2 May 1996 16:28:10 +0000 Subject: fixup --- ufs/sizes.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index ee69c566..4237ea56 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -402,8 +402,8 @@ block_extended (struct node *np, /* There's *got* to be a better way to do this... */ /* Force it out to disk */ - assert (np->fileinfo); - pager_sync_some (np->fileinfo->p, lbn * sblock->fs_bsize + off, + assert (np->dn->fileinfo); + pager_sync_some (np->dn->fileinfo->p, lbn * sblock->fs_bsize + off, vm_page_size, 1); /* Read it back in */ @@ -421,7 +421,7 @@ block_extended (struct node *np, write of this file, maybe even one from before we started running may have been fsynced. We can't cause data already on disk to be lossy at any time in the future while we move it. */ - pager_sync_some (np->fileinfo->p, lbn * sblock->fs_bsize + off, + pager_sync_some (np->dn->fileinfo->p, lbn * sblock->fs_bsize + off, vm_page_size, 1); } @@ -494,9 +494,10 @@ diskfs_grow (struct node *np, if (err) goto out; + old_pbn = read_disk_entry (di->di_db[olbn]); + block_extended (np, olbn, old_pbn, bno, osize, sblock->fs_bsize); - old_pbn = read_disk_entry (di->di_db[olbn]); write_disk_entry (di->di_db[olbn], bno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; -- cgit v1.2.3 From 31da7bd62ef8f315db44ad47ee423c55fc46cf27 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 3 May 1996 13:15:27 +0000 Subject: (struct user_pager_info): New members `allow_unlocked_pagein' and `unlocked_pagein_length'. (unlocked_pagein_lock): New variable. --- ufs/ufs.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 06255960..ddf7283b 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -79,6 +79,9 @@ struct user_pager_info } type; struct pager *p; vm_prot_t max_prot; + + vm_offset_t allow_unlocked_pagein; + vm_size_t unlocked_pagein_length; }; #include @@ -97,6 +100,8 @@ spin_lock_t alloclock; spin_lock_t gennumberlock; u_long nextgennumber; +spin_lock_t unlocked_pagein_lock; + /* The compat_mode specifies whether or not we write extensions onto the disk. */ enum compat_mode -- cgit v1.2.3 From 5163242b569179a9d875c9aefcc3ee5c317e1c55 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 3 May 1996 13:31:52 +0000 Subject: (diskfs_get_filemap): Initialize UPI->allow_unlocked_pagein and UPI->unlocked_pagein_length. (unlocked_pagein_lock): New variable. (find_address): New parameter `isread'; all callers changed. If ISREAD and we are in the unlocked pagein region, don't attempt to acquire NP->dn->allocptrlock. --- ufs/pager.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 9 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index d4bc87c5..0da2609e 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -22,6 +22,8 @@ spin_lock_t node2pagelock = SPIN_LOCK_INITIALIZER; +spin_lock_t unlocked_pagein_lock = SPIN_LOCK_INITIALIZER; + #ifdef DONT_CACHE_MEMORY_OBJECTS #define MAY_CACHE 0 #else @@ -34,15 +36,18 @@ struct port_bucket *pager_bucket; disk address (in disk block) in *ADDR. If *NPLOCK is set on return, then release that mutex after I/O on the data has completed. Set DISKSIZE to be the amount of valid data on disk. - (If this is an unallocated block, then set *ADDR to zero.) */ + (If this is an unallocated block, then set *ADDR to zero.) + ISREAD is non-zero iff this is for a pagein. */ static error_t find_address (struct user_pager_info *upi, vm_address_t offset, daddr_t *addr, int *disksize, - struct rwlock **nplock) + struct rwlock **nplock, + int isread) { error_t err; + struct rwlock *lock; assert (upi->type == DISK || upi->type == FILE_DATA); @@ -60,12 +65,58 @@ find_address (struct user_pager_info *upi, np = upi->np; - rwlock_reader_lock (&np->dn->allocptrlock); - *nplock = &np->dn->allocptrlock; + if (isread) + { + try_again: + + /* If we should allow an unlocked pagein, do so. (This + still has a slight race; there could be a pageout in progress + which is blocked on NP->np->allocptrlock itself. In that + case the pagein that should proceed unimpeded is blocked + in the pager library waiting for the pageout to complete. + I think this is sufficiently rare to put it off for the time + being.) */ + + spin_lock (&unlocked_pagein_lock); + if (offset >= upi->allow_unlocked_pagein + && (offset + vm_page_size + <= upi->allow_unlocked_pagein + upi->unlocked_pagein_length)) + { + spin_unlock (&unlocked_pagein_lock); + *nplock = 0; + goto have_lock; + } + spin_unlock (&unlocked_pagein_lock); + + /* Block on the rwlock if necessary; but when we wake up, + don't acquire it; check again from the top. + This is mutated inline from rwlock.h. */ + lock = &np->dn->allocptrlock; + mutex_lock (&lock->master); + if (lock->readers == -1 || lock->writers_waiting) + { + lock->readers_waiting++; + condition_wait (&lock->wakeup, &lock->master); + lock->readers_waiting--; + mutex_unlock (&lock->master); + goto try_again; + } + lock->readers++; + mutex_unlock (&lock->master); + *nplock = lock; + } + else + { + rwlock_reader_lock (&np->dn->allocptrlock); + *nplock = &np->dn->allocptrlock; + } + have_lock: + if (offset >= np->allocsize) { - rwlock_reader_unlock (&np->dn->allocptrlock); + if (*nplock) + rwlock_reader_unlock (*nplock); return EIO; } @@ -75,8 +126,8 @@ find_address (struct user_pager_info *upi, *disksize = __vm_page_size; err = fetch_indir_spec (np, lblkno (sblock, offset), indirs); - if (err) - rwlock_reader_unlock (&np->dn->allocptrlock); + if (err && *nplock) + rwlock_reader_unlock (*nplock); else { if (indirs[0].bno) @@ -104,7 +155,7 @@ pager_read_page (struct user_pager_info *pager, daddr_t addr; int disksize; - err = find_address (pager, page, &addr, &disksize, &nplock); + err = find_address (pager, page, &addr, &disksize, &nplock, 1); if (err) return err; @@ -143,7 +194,7 @@ pager_write_page (struct user_pager_info *pager, struct rwlock *nplock; error_t err; - err = find_address (pager, page, &addr, &disksize, &nplock); + err = find_address (pager, page, &addr, &disksize, &nplock, 0); if (err) return err; @@ -490,6 +541,8 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot) upi->type = FILE_DATA; upi->np = np; upi->max_prot = prot; + upi->allow_unlocked_pagein = 0; + upi->unlocked_pagein_length = 0; diskfs_nref_light (np); upi->p = pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); -- cgit v1.2.3 From 4f244438de694a265f0714b7f490eac190472cb4 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 3 May 1996 17:49:14 +0000 Subject: (block_extended): Rewrite code that moves pages to be more efficient, and not deadlock too, using unlocked pagein permission feature (read "hack"). Return value now indicates whether we expect a sync. (diskfs_grow): If a call to block_extended returns nonzero, then sync the file before returning. --- ufs/sizes.c | 92 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 37 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 4237ea56..ad14f5cc 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -373,8 +373,9 @@ offer_data (struct node *np, /* Logical block LBN of node NP has been extended with ffs_realloccg. It used to be allocated at OLD_PBN and is now at NEW_PBN. The old size was OLD_SIZE; it is now NEW_SIZE bytes long. Arrange for the data - on disk to be kept consistent, and free the old block if it has moved. */ -void + on disk to be kept consistent, and free the old block if it has moved. + Return one iff we've actually moved data around on disk. */ +int block_extended (struct node *np, daddr_t lbn, daddr_t old_pbn, @@ -393,42 +394,54 @@ block_extended (struct node *np, if (old_pbn != new_pbn) { - /* Fetch the old data for the part that has moved and offer it - to the kernel, to make sure it's paged in before - we deallocate the old block. */ - for (off = 0; off < round_page (old_size); off += vm_page_size) - { - - /* There's *got* to be a better way to do this... */ - - /* Force it out to disk */ - assert (np->dn->fileinfo); - pager_sync_some (np->dn->fileinfo->p, lbn * sblock->fs_bsize + off, - vm_page_size, 1); - - /* Read it back in */ - diskfs_device_read_sync (fsbtodb (sblock, old_pbn) + off / DEV_BSIZE, - (void *) &buf, vm_page_size); - /* If this page is the last one, then zero the excess first */ - if (off + vm_page_size > old_size) - bzero ((void *)(buf + old_size - off), - vm_page_size - (old_size - off)); - - /* And make sure it's in core. */ - offer_data (np, lbn * sblock->fs_bsize + off, vm_page_size, buf); - - /* And now, make sure it's on disk. (Why? Because a previous - write of this file, maybe even one from before we started - running may have been fsynced. We can't cause data already - on disk to be lossy at any time in the future while we move it. */ - pager_sync_some (np->dn->fileinfo->p, lbn * sblock->fs_bsize + off, - vm_page_size, 1); - } + vm_object_t mapobj; + error_t err; + vm_address_t mapaddr; + volatile int *pokeaddr; + + /* Map in this part of the file */ + mapobj = diskfs_get_filemap (np, VM_PROT_WRITE | VM_PROT_READ); + err = vm_map (mach_task_self (), &mapaddr, round_page (old_size), 0, 1, + mapobj, lbn * sblock->fs_bsize, 0, + VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0); + assert_perror (err); - /* And deallocate the old block */ + /* Allow these pageins to occur even though we're holding the lock */ + spin_lock (&unlocked_pagein_lock); + np->dn->fileinfo->allow_unlocked_pagein = lbn * sblock->fs_bsize; + np->dn->fileinfo->unlocked_pagein_length = round_page (old_size); + spin_unlock (&unlocked_pagein_lock); + + /* Make sure all waiting pageins see this change. */ + mutex_lock (&np->allocptrlock->master); + condition_broadcast (&np->allocptrlock->wakeup); + mutex_unlock (&np->allocptrlock->master); + + /* Force the pages in core and make sure they are dirty */ + for (pokeaddr = (char *)mapaddr; + pokeaddr < mapaddr + round_page (old_size); + pokeaddr += vm_page_size / sizeof (*pokeaddr)) + *pokeaddr = *pokeaddr; + + /* Turn off the special pagein permission */ + spin_lock (&unlocked_pagein_lock); + np->dn->fileinfo->allow_unlocked_pagein = 0; + np->dn->fileinfo->unlocked_pagein_length = 0; + spin_unlock (&unlocked_pagein_lock); + + /* Undo mapping */ + mach_port_deallocate (mach_task_self (), mapobj); + vm_deallocate (mach_task_self (), mapaddr, round_page (old_size); + + /* Now it's OK to free the old block */ ffs_blkfree (np, old_pbn, old_size); + + /* Tell caller that we've moved data */ + return 1; } -} + else + return 0; +} /* Implement the diskfs_grow callback; see for the @@ -443,6 +456,7 @@ diskfs_grow (struct node *np, error_t err; struct dinode *di = dino (np->dn->number); mach_port_t pagerpt; + int needsync = 0; /* Zero an sblock->fs_bsize piece of disk starting at BNO, synchronously. We do this on newly allocated indirect @@ -496,7 +510,8 @@ diskfs_grow (struct node *np, old_pbn = read_disk_entry (di->di_db[olbn]); - block_extended (np, olbn, old_pbn, bno, osize, sblock->fs_bsize); + need_sync = block_extended (np, olbn, old_pbn, bno, + osize, sblock->fs_bsize); write_disk_entry (di->di_db[olbn], bno); record_poke (di, sizeof (struct dinode)); @@ -522,7 +537,7 @@ diskfs_grow (struct node *np, if (err) goto out; - block_extended (np, lbn, old_pbn, bno, osize, size); + need_sync = block_extended (np, lbn, old_pbn, bno, osize, size); write_disk_entry (di->di_db[lbn], bno); record_poke (di, sizeof (struct dinode)); @@ -653,6 +668,9 @@ diskfs_grow (struct node *np, rwlock_writer_unlock (&np->dn->allocptrlock); + if (need_sync) + diskfs_file_update (np, 1); + return err; } -- cgit v1.2.3 From 31912148eee69012791e591a061dd76e8e09b659 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 3 May 1996 18:10:58 +0000 Subject: fixup --- ufs/sizes.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index ad14f5cc..af765945 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -383,9 +383,6 @@ block_extended (struct node *np, size_t old_size, size_t new_size) { - vm_address_t buf; - daddr_t off; - /* Make sure that any pages of this block which just became allocated don't get paged in from disk. */ if (round_page (old_size) < round_page (new_size)) @@ -394,7 +391,7 @@ block_extended (struct node *np, if (old_pbn != new_pbn) { - vm_object_t mapobj; + memory_object_t mapobj; error_t err; vm_address_t mapaddr; volatile int *pokeaddr; @@ -413,12 +410,12 @@ block_extended (struct node *np, spin_unlock (&unlocked_pagein_lock); /* Make sure all waiting pageins see this change. */ - mutex_lock (&np->allocptrlock->master); - condition_broadcast (&np->allocptrlock->wakeup); - mutex_unlock (&np->allocptrlock->master); + mutex_lock (&np->dn->allocptrlock->master); + condition_broadcast (&np->dn->allocptrlock->wakeup); + mutex_unlock (&np->dn->allocptrlock->master); /* Force the pages in core and make sure they are dirty */ - for (pokeaddr = (char *)mapaddr; + for (pokeaddr = (int *)mapaddr; pokeaddr < mapaddr + round_page (old_size); pokeaddr += vm_page_size / sizeof (*pokeaddr)) *pokeaddr = *pokeaddr; @@ -431,7 +428,7 @@ block_extended (struct node *np, /* Undo mapping */ mach_port_deallocate (mach_task_self (), mapobj); - vm_deallocate (mach_task_self (), mapaddr, round_page (old_size); + vm_deallocate (mach_task_self (), mapaddr, round_page (old_size)); /* Now it's OK to free the old block */ ffs_blkfree (np, old_pbn, old_size); @@ -456,7 +453,7 @@ diskfs_grow (struct node *np, error_t err; struct dinode *di = dino (np->dn->number); mach_port_t pagerpt; - int needsync = 0; + int need_sync = 0; /* Zero an sblock->fs_bsize piece of disk starting at BNO, synchronously. We do this on newly allocated indirect -- cgit v1.2.3 From 57ffe5ad51eec9910e2c0b3e4bdf971db09b57f4 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 3 May 1996 18:12:48 +0000 Subject: (block_extended): more fixup --- ufs/sizes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index af765945..f98ceb94 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -410,13 +410,13 @@ block_extended (struct node *np, spin_unlock (&unlocked_pagein_lock); /* Make sure all waiting pageins see this change. */ - mutex_lock (&np->dn->allocptrlock->master); - condition_broadcast (&np->dn->allocptrlock->wakeup); - mutex_unlock (&np->dn->allocptrlock->master); + mutex_lock (&np->dn->allocptrlock.master); + condition_broadcast (&np->dn->allocptrlock.wakeup); + mutex_unlock (&np->dn->allocptrlock.master); /* Force the pages in core and make sure they are dirty */ for (pokeaddr = (int *)mapaddr; - pokeaddr < mapaddr + round_page (old_size); + pokeaddr < (int *) (mapaddr + round_page (old_size)); pokeaddr += vm_page_size / sizeof (*pokeaddr)) *pokeaddr = *pokeaddr; -- cgit v1.2.3 From b40493575ad94645591b9294436012da248282e6 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 6 May 1996 18:23:48 +0000 Subject: (ufs_version): Upgrade to 0.0. --- ufs/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 2173be01..5ba1b318 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -25,7 +25,7 @@ #include #include -char *ufs_version = "0.0 pre-alpha"; +char *ufs_version = "0.0"; struct node *diskfs_root_node; -- cgit v1.2.3 From b4b71df7ac62246208bbbdc4318a660934cb9474 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 9 May 1996 15:54:08 +0000 Subject: ioserver.h -> iohelp.h. --- ufs/ufs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index ddf7283b..ea13475e 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include "fs.h" -- cgit v1.2.3 From b2aecd50c2d7ed75af2bac0d4edce6a6bd0b845a Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 9 May 1996 23:37:47 +0000 Subject: (diskfs_set_statfs): Use and fill in new statfs structure. --- ufs/inode.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index ab19668f..4011ff55 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -487,19 +487,19 @@ diskfs_write_disknode (struct node *np, int wait) /* Implement the diskfs_set_statfs callback from the diskfs library; see for the interface description. */ error_t -diskfs_set_statfs (struct fsys_statfsbuf *st) +diskfs_set_statfs (struct statfs *st) { - st->fsys_stb_type = FSTYPE_UFS; - st->fsys_stb_iosize = sblock->fs_bsize; - st->fsys_stb_bsize = sblock->fs_fsize; - st->fsys_stb_blocks = sblock->fs_dsize; - st->fsys_stb_bfree = (sblock->fs_cstotal.cs_nbfree * sblock->fs_frag - + sblock->fs_cstotal.cs_nffree); - st->fsys_stb_bavail = ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100) - - (sblock->fs_dsize - st->fsys_stb_bfree)); - st->fsys_stb_files = sblock->fs_ncg * sblock->fs_ipg - 2; /* not 0 or 1 */ - st->fsys_stb_ffree = sblock->fs_cstotal.cs_nifree; - st->fsys_stb_fsid = getpid (); + st->f_type = FSTYPE_UFS; + st->f_bsize = sblock->fs_bsize; + st->f_blocks = sblock->fs_dsize * sblock->fs_frag; + st->f_bfree = (sblock->fs_cstotal.cs_nbfree * sblock->fs_frag + + sblock->fs_cstotal.cs_nffree); + st->f_bavail = ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100) + - (sblock->fs_dsize - st->fsys_stb_bfree)); + st->f_files = sblock->fs_ncg * sblock->fs_ipg - 2; /* not 0 or 1 */ + st->f_ffree = sblock->fs_cstotal.cs_nifree; + st->f_fsid = getpid (); + st->f_namelen = 0; return 0; } -- cgit v1.2.3 From fc2b2d7272fff570399f6fd1e6a9df7294199b9e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 9 May 1996 23:44:44 +0000 Subject: (ufs.static ufs): s/ioserver/iohelp/g --- ufs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 280e155c..d9375989 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -29,5 +29,5 @@ ufs.static-LDFLAGS += -static include ../Makeconf -ufs.static ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libioserver/libioserver.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a +ufs.static ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libiohelp/libiohelp.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a -- cgit v1.2.3 From 6c7e0eddfc5f46f168b21d6748e3988f656a5542 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 10 May 1996 13:28:57 +0000 Subject: (diskfs_set_statfs): Fix one reference to old name of ST member. --- ufs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 4011ff55..51af3446 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -495,7 +495,7 @@ diskfs_set_statfs (struct statfs *st) st->f_bfree = (sblock->fs_cstotal.cs_nbfree * sblock->fs_frag + sblock->fs_cstotal.cs_nffree); st->f_bavail = ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100) - - (sblock->fs_dsize - st->fsys_stb_bfree)); + - (sblock->fs_dsize - st->f_bfree)); st->f_files = sblock->fs_ncg * sblock->fs_ipg - 2; /* not 0 or 1 */ st->f_ffree = sblock->fs_cstotal.cs_nifree; st->f_fsid = getpid (); -- cgit v1.2.3 From d233bdfd39e968e4cffc9af6b21ba2f4ce24df22 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 14 May 1996 12:57:14 +0000 Subject: foo. --- devio/MAKEDEV | 18 ++++++++++++---- ufs/dir.c | 66 +++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 51 insertions(+), 33 deletions(-) (limited to 'ufs') diff --git a/devio/MAKEDEV b/devio/MAKEDEV index bf5217dc..d992d06a 100644 --- a/devio/MAKEDEV +++ b/devio/MAKEDEV @@ -18,19 +18,28 @@ for I; do console|tty[0-9]?|tty[0-9a-f]) $ST $I /hurd/term $_CWD/$I device $I;; null) - $ST $I /hurd/null ;; + $ST $I /hurd/null + chmod 666 $I + ;; zero) - $ST $I /hurd/null -z ;; + $ST $I /hurd/null -z + chmod 666 $I + ;; tty) - $ST $I /hurd/magic tty ;; + $ST $I /hurd/magic tty + chmod 666 $I + ;; fd) $ST $I /hurd/magic fd + chmod 666 $I ln -f -s fd/0 stdin ln -f -s fd/1 stdout ln -f -s fd/2 stderr ;; time) - $ST $I /hurd/devport time ;; + $ST $I /hurd/devport time + chmod 666 $I + ;; # ptys [pt]ty[pqPQ]?) @@ -38,6 +47,7 @@ for I; do ID="`expr substr $I 4 99`" $ST pty$ID /hurd/term $_CWD/pty$ID pty-master $_CWD/tty$ID $ST tty$ID /hurd/term $_CWD/tty$ID pty-slave $_CWD/pty$ID + chmod 666 pty$ID tty$ID ;; [pt]ty[pqPQ]) # Make a bunch of ptys diff --git a/ufs/dir.c b/ufs/dir.c index ed7ac212..9abcdbea 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -336,16 +336,17 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, for (currentoff = blockaddr, prevoff = 0; currentoff < blockaddr + DIRBLKSIZ; - prevoff = currentoff, currentoff += entry->d_reclen) + prevoff = currentoff, currentoff += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *)currentoff; if (!entry->d_reclen - || entry->d_reclen % 4 + || read_disk_entry (entry->d_reclen) % 4 || DIRECT_NAMLEN (entry) > MAXNAMLEN - || currentoff + entry->d_reclen > blockaddr + DIRBLKSIZ + || (currentoff + read_disk_entry (entry->d_reclen) + > blockaddr + DIRBLKSIZ) || entry->d_name[DIRECT_NAMLEN (entry)] - || DIRSIZ (DIRECT_NAMLEN (entry)) > entry->d_reclen + || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", @@ -359,9 +360,10 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, /* Count how much free space this entry has in it. */ if (entry->d_ino == 0) - thisfree = entry->d_reclen; + thisfree = read_disk_entry (entry->d_reclen); else - thisfree = entry->d_reclen - DIRSIZ (DIRECT_NAMLEN (entry)); + thisfree = (read_disk_entry (entry->d_reclen) + - DIRSIZ (DIRECT_NAMLEN (entry))); /* If this isn't at the front of the block, then it will have to be copied if we do a compression; count the @@ -377,7 +379,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, if (thisfree >= needed) { ds->type = CREATE; - ds->stat = entry->d_ino == 0 ? TAKE : SHRINK; + ds->stat = read_disk_entry (entry->d_ino) == 0 ? TAKE : SHRINK; ds->entry = entry; ds->idx = idx; looking = countcopies = 0; @@ -446,7 +448,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, ds->preventry = (struct directory_entry *) prevoff; } - *inum = entry->d_ino; + *inum = read_disk_entry (entry->d_ino); return 0; } @@ -480,9 +482,10 @@ diskfs_direnter_hard(struct node *dp, { case TAKE: /* We are supposed to consume this slot. */ - assert (ds->entry->d_ino == 0 && ds->entry->d_reclen >= needed); + assert (ds->entry->d_ino == 0 + && read_disk_entry (ds->entry->d_reclen) >= needed); - ds->entry->d_ino = np->dn->number; + write_disk_entry (ds->entry->d_ino, np->dn->number); DIRECT_NAMLEN (ds->entry) = namelen; if (direct_symlink_extension) ds->entry->d_type = IFTODT (np->dn_stat.st_mode); @@ -494,18 +497,19 @@ diskfs_direnter_hard(struct node *dp, /* We are supposed to take the extra space at the end of this slot. */ oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); - assert (ds->entry->d_reclen - oldneeded >= needed); + assert (read_disk_entry (ds->entry->d_reclen) - oldneeded >= needed); new = (struct directory_entry *) ((vm_address_t) ds->entry + oldneeded); - new->d_ino = np->dn->number; - new->d_reclen = ds->entry->d_reclen - oldneeded; + write_disk_entry (new->d_ino, np->dn->number); + write_disk_entry (new->d_reclen, + read_disk_entry (ds->entry->d_reclen) - oldneeded); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); - ds->entry->d_reclen = oldneeded; + write_disk_entry (ds->entry->d_reclen, oldneeded); break; @@ -520,16 +524,16 @@ diskfs_direnter_hard(struct node *dp, { struct directory_entry *from = (struct directory_entry *)fromoff; struct directory_entry *to = (struct directory_entry *) tooff; - int fromreclen = from->d_reclen; + int fromreclen = read_disk_entry (from->d_reclen); if (from->d_ino != 0) { assert (fromoff >= tooff); bcopy (from, to, fromreclen); - to->d_reclen = DIRSIZ (DIRECT_NAMLEN (to)); + write_disk_entry (to->d_reclen, DIRSIZ (DIRECT_NAMLEN (to))); - tooff += to->d_reclen; + tooff += read_disk_entry (to->d_reclen); } fromoff += fromreclen; } @@ -538,8 +542,8 @@ diskfs_direnter_hard(struct node *dp, assert (totfreed >= needed); new = (struct directory_entry *) tooff; - new->d_ino = np->dn->number; - new->d_reclen = totfreed; + write_disk_entry (new->d_ino, np->dn->number); + write_disk_entry (new->d_reclen, totfreed); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); @@ -566,8 +570,8 @@ diskfs_direnter_hard(struct node *dp, dp->dn_stat.st_size = oldsize + DIRBLKSIZ; dp->dn_set_ctime = 1; - new->d_ino = np->dn->number; - new->d_reclen = DIRBLKSIZ; + write_disk_entry (new->d_ino, np->dn->number); + write_disk_entry (new->d_reclen, DIRBLKSIZ); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); @@ -633,8 +637,10 @@ diskfs_dirremove_hard(struct node *dp, else { assert ((vm_address_t) ds->entry - (vm_address_t) ds->preventry - == ds->preventry->d_reclen); - ds->preventry->d_reclen += ds->entry->d_reclen; + == read_disk_entry (ds->preventry->d_reclen)); + write_disk_entry (ds->preventry->d_reclen, + (read_disk_entry (ds->preventry->d_reclen) + + read_disk_entry (ds->entry->d_reclen))); } dp->dn_set_mtime = 1; @@ -667,7 +673,7 @@ diskfs_dirrewrite_hard(struct node *dp, assert (ds->stat == HERE_TIS); dp->dn_set_mtime = 1; - ds->entry->d_ino = np->dn->number; + write_disk_entry (ds->entry->d_ino, np->dn->number); if (direct_symlink_extension) ds->entry->d_type = IFTODT (np->dn_stat.st_mode); dp->dn_set_mtime = 1; @@ -704,7 +710,7 @@ diskfs_dirempty(struct node *dp, for (curoff = buf; curoff < buf + dp->dn_stat.st_size; - curoff += entry->d_reclen) + curoff += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *) curoff; @@ -766,7 +772,7 @@ count_dirents (struct node *dp, int nb, char *buf) for (offinblk = buf; offinblk < buf + DIRBLKSIZ; - offinblk += entry->d_reclen) + offinblk += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *) offinblk; if (entry->d_ino) @@ -869,7 +875,9 @@ diskfs_get_directs (struct node *dp, } for (i = 0, bufp = buf; i < entry - curentry && bufp - buf < DIRBLKSIZ; - bufp += ((struct directory_entry *)bufp)->d_reclen, i++) + (bufp + += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), + i++) ; /* Make sure we didn't run off the end. */ assert (bufp - buf < DIRBLKSIZ); @@ -900,7 +908,7 @@ diskfs_get_directs (struct node *dp, { userp = (struct dirent *) datap; - userp->d_fileno = entryp->d_ino; + userp->d_fileno = read_disk_entry (entryp->d_ino); userp->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); userp->d_namlen = DIRECT_NAMLEN (entryp); bcopy (entryp->d_name, userp->d_name, DIRECT_NAMLEN (entryp) + 1); @@ -909,7 +917,7 @@ diskfs_get_directs (struct node *dp, datap += DIRSIZ (DIRECT_NAMLEN (entryp)); } - bufp += entryp->d_reclen; + bufp += read_disk_entry (entryp->d_reclen); if (bufp - buf == DIRBLKSIZ) { blkno++; -- cgit v1.2.3 From c45594bacc24c92f76d76902f556537ff69a15fa Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 15 Jun 1996 18:52:43 +0000 Subject: (options): New variable. (parse_opt): New function. (main): Parse ufs-specific options too. : New include. --- ufs/main.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 5ba1b318..58c6f427 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -24,6 +24,7 @@ #include #include #include +#include char *ufs_version = "0.0"; @@ -55,14 +56,49 @@ int printf (const char *fmt, ...) int diskfs_readonly; +/* Ufs-specific options. XXX this should be moved so it can be done at + runtime as well as startup. */ +static struct argp_option +options[] = +{ + {"compat", 'C', "FMT", 0, + "FMT may be GNU, 4.4, or 4.2, and determines which filesystem extensions" + " are written onto the disk (default is GNU)"}, + {0} +}; + +/* Parse a command line option. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'C': + if (strcasecmp (arg, "gnu") == 0) + compat_mode = COMPAT_GNU; + else if (strcmp (arg, "4.4") == 0) + compat_mode = COMPAT_BSD44; + else if (strcmp (arg, "4.2") == 0) + compat_mode = COMPAT_BSD42; + else + argp_error (state, "%s: Unknown compatibility mode", arg); + break; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + int main (int argc, char **argv) { error_t err; off_t disk_size; mach_port_t bootstrap; + const struct argp *argp_parents[] = { diskfs_device_startup_argp, 0 }; + struct argp argp = {options, parse_opt, 0, 0, argp_parents}; - argp_parse (diskfs_device_startup_argp, argc, argv, 0, 0, 0); + argp_parse (&argp, argc, argv, 0, 0, 0); /* This must come after the args have been parsed, as this is where the host priv ports are set for booting. */ -- cgit v1.2.3 From b2c16baabefa5b84faf80f7c8113043447815083 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 21 Jun 1996 06:05:13 +0000 Subject: (parse_opt): Handle runtime invalid selection of 4.2 mode. Save select mode until we're done to correctly deal with external errors at runtime. (startup_parents, startup_argp, runtime_parents, runtime_argp): New variables. (main): Argp vars made global. (startup_parents): diskfs_device_startup_argp --> &diskfs_std_device_startup_argp. --- ufs/main.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 58c6f427..ac3a34bb 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -73,32 +73,69 @@ parse_opt (int key, char *arg, struct argp_state *state) { switch (key) { + enum compat_mode mode; + case 'C': if (strcasecmp (arg, "gnu") == 0) - compat_mode = COMPAT_GNU; + mode = COMPAT_GNU; else if (strcmp (arg, "4.4") == 0) - compat_mode = COMPAT_BSD44; + mode = COMPAT_BSD44; else if (strcmp (arg, "4.2") == 0) - compat_mode = COMPAT_BSD42; + { + if (sblock + && (sblock->fs_inodefmt == FS_44INODEFMT + || direct_symlink_extension)) + { + argp_failure (state, 0, 0, + "4.2 compat mode requested on 4.4 fs"); + return EINVAL; + } + mode = COMPAT_BSD42; + } else - argp_error (state, "%s: Unknown compatibility mode", arg); + { + argp_error (state, "%s: Unknown compatibility mode", arg); + return EINVAL; + } + + state->hook = (void *)mode; /* Save it for the end. */ break; + + case ARGP_KEY_INIT: + state->hook = (void *)compat_mode; break; + case ARGP_KEY_SUCCESS: + compat_mode = (enum compat_mode)state->hook; break; + default: return ARGP_ERR_UNKNOWN; } return 0; } +static const struct argp *startup_parents[] = { + &diskfs_std_device_startup_argp, 0 +}; +static const struct argp startup_argp = { + options, parse_opt, 0, 0, startup_parents +}; + +static const struct argp *runtime_parents[] = { + &diskfs_std_runtime_argp, 0 +}; +static const struct argp runtime_argp = { + options, parse_opt, 0, 0, runtime_parents +}; + +struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; + int main (int argc, char **argv) { error_t err; off_t disk_size; mach_port_t bootstrap; - const struct argp *argp_parents[] = { diskfs_device_startup_argp, 0 }; - struct argp argp = {options, parse_opt, 0, 0, argp_parents}; - argp_parse (&argp, argc, argv, 0, 0, 0); + argp_parse (&startup_argp, argc, argv, 0, 0, 0); /* This must come after the args have been parsed, as this is where the host priv ports are set for booting. */ -- cgit v1.2.3 From 821993cf17d309df2bb103d21ef1122fd8cce77f Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 22 Jun 1996 21:45:52 +0000 Subject: (diskfs_get_options): New function. --- ufs/main.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index ac3a34bb..617796d8 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -111,23 +111,40 @@ parse_opt (int key, char *arg, struct argp_state *state) } return 0; } - -static const struct argp *startup_parents[] = { - &diskfs_std_device_startup_argp, 0 -}; -static const struct argp startup_argp = { - options, parse_opt, 0, 0, startup_parents -}; -static const struct argp *runtime_parents[] = { - &diskfs_std_runtime_argp, 0 -}; -static const struct argp runtime_argp = { - options, parse_opt, 0, 0, runtime_parents -}; +/* Add our startup arguments to the standard diskfs set. */ +static struct argp *startup_parents[] = { &diskfs_std_device_startup_argp, 0}; +static struct argp startup_argp = {options, parse_opt, 0, 0, startup_parents}; + +/* Similarly at runtime. */ +static struct argp *runtime_parents[] = {&diskfs_std_runtime_argp, 0}; +static struct argp runtime_argp = {options, parse_opt, 0, 0, runtime_parents}; struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; +/* Override the standard diskfs routine so we can add our own output. */ +error_t +diskfs_get_options (char **argz, unsigned *argz_len) +{ + error_t err; + + *argz = 0; + *argz_len = 0; + + /* Get the standard things. */ + err = diskfs_append_std_options (argz, argz_len); + + if (!err && compat_mode != COMPAT_GNU) + { + char *mode = (compat_mode == COMPAT_BSD42) ? "4.2" : "4.4"; + err = argz_add (argz, argz_len, mode); + if (err) + free (argz); /* Deallocate what diskfs returned. */ + } + + return err; +} + int main (int argc, char **argv) { -- cgit v1.2.3 From c98140b68e9c197e1cd5a9a46a3ed62ed8c49853 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 22 Jun 1996 21:50:14 +0000 Subject: (options): Make const. --- ufs/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 617796d8..1e7a87bc 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -58,7 +58,7 @@ int diskfs_readonly; /* Ufs-specific options. XXX this should be moved so it can be done at runtime as well as startup. */ -static struct argp_option +static const struct argp_option options[] = { {"compat", 'C', "FMT", 0, -- cgit v1.2.3 From 6ae06cb4a632dbdf3fae000b1930e4c517ac71a6 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 24 Jun 1996 20:59:05 +0000 Subject: (diskfs_shutdown_pager): Don't shutdown DISKPAGER ever, just sync it instead. --- ufs/pager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 0da2609e..bea290ab 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -742,7 +742,7 @@ diskfs_shutdown_pager () error_t shutdown_one (void *arg) { struct pager *p = arg; - /* Make sure the disk pager is done last. */ + /* Don't ever shut down the disk pager. */ if (p != disk_pager) pager_shutdown (p); return 0; @@ -751,7 +751,7 @@ diskfs_shutdown_pager () copy_sblock (); write_all_disknodes (); ports_bucket_iterate (pager_bucket, shutdown_one); - pager_shutdown (disk_pager); + sync_disk (1); } /* Sync all the pagers. */ -- cgit v1.2.3 From b3a2a116f9e9199f2138d5add98780d8cf0fb24d Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 24 Jun 1996 21:23:42 +0000 Subject: (diskfs_set_hypermetadata): If CLEAN is not set, make sure we clear the clean bit on disk. Always call sync_disk (with appropriate WAIT). (diskfs_readonly_changed): Don't do set_hypermetadata here. (copy_sblock): Don't track clean state here. --- ufs/hyper.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index f198ff43..e4f58249 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -312,11 +312,20 @@ diskfs_set_hypermetadata (int wait, int clean) sblock->fs_clean = 1; sblock_dirty = 1; } + else if (!clean && sblock->fs_clean) + { + /* Clear the clean flag */ + sblock->fs_clean = 0; + sblock_dirty = 1; + wait = 1; /* must be synchronous */ + } spin_unlock (&alloclock); /* Update the superblock if necessary (clean bit was just set). */ copy_sblock (); + + sync_disk (wait); } /* Copy the sblock into the disk */ @@ -359,16 +368,6 @@ copy_sblock () sblock_dirty = 0; } - if (!diskfs_readonly && sblock->fs_clean) - { - /* We just sync'd with the clean flag set, but we are still a - writable filesystem. Clear the flag in core, but don't write the - superblock yet. This should ensure that the flag will be written - as clear as soon as we make any modifications. */ - sblock->fs_clean = 0; - sblock_dirty = 1; - } - spin_unlock (&alloclock); diskfs_end_catch_exception (); @@ -393,11 +392,6 @@ diskfs_readonly_changed (int readonly) strcpy (sblock->fs_fsmnt, "Hurd /"); /* XXX */ - if (sblock->fs_clean) - sblock->fs_clean = 0; - else + if (!sblock->fs_clean) error (0, 0, "WARNING: UNCLEANED FILESYSTEM NOW WRITABLE"); - - sblock_dirty = 1; - diskfs_set_hypermetadata (1, 0); } -- cgit v1.2.3 From 41e7ae8cc4056eb04dd7cd65002b079d3d7d2cb1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 24 Jun 1996 21:24:12 +0000 Subject: (diskfs_truncate): Call diskfs_check_readonly. (diskfs_grow): Likewise. --- ufs/sizes.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index f98ceb94..39717384 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -49,6 +49,7 @@ diskfs_truncate (struct node *np, if (length >= np->dn_stat.st_size) return 0; + diskfs_check_readonly (); assert (!diskfs_readonly); /* First check to see if this is a kludged symlink; if so @@ -469,6 +470,7 @@ diskfs_grow (struct node *np, if (end <= np->allocsize) return 0; + diskfs_check_readonly (); assert (!diskfs_readonly); /* This reference will ensure that NP->dn->fileinfo stays allocated. */ -- cgit v1.2.3 From 9505b47ffb5ca90b143a09b2602b7adceef1ad59 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 24 Jun 1996 21:24:48 +0000 Subject: (diskfs_cached_lookup): Use diskfs_check_readonly instead of diskfs_readonly. (read_symlink_hook): Likewise. --- ufs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 51af3446..c3eec832 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -86,7 +86,7 @@ diskfs_cached_lookup (int inum, struct node **npp) err = read_disknode (np); - if (!diskfs_readonly && !np->dn_stat.st_gen) + if (!diskfs_check_readonly () && !np->dn_stat.st_gen) { spin_lock (&gennumberlock); if (++nextgennumber < diskfs_mtime->seconds) @@ -415,7 +415,7 @@ read_symlink_hook (struct node *np, bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); - if (! diskfs_readonly) + if (! diskfs_check_readonly ()) np->dn_set_atime = 1; diskfs_end_catch_exception (); -- cgit v1.2.3 From f99f473d18563d7167793f9391e73f9c6d802cc3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 24 Jun 1996 21:25:22 +0000 Subject: (diskfs_lookup_hard): Use diskfs_check_readonly instead of diskfs_readonly. (diskfs_dirempty): Likewise. --- ufs/dir.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 9abcdbea..d015a6c6 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -153,7 +153,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, inum = 0; - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; for (blockaddr = buf, idx = 0; @@ -170,7 +170,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } } - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); @@ -705,7 +705,7 @@ diskfs_dirempty(struct node *dp, mach_port_deallocate (mach_task_self (), memobj); assert (!err); - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; for (curoff = buf; @@ -721,14 +721,14 @@ diskfs_dirempty(struct node *dp, && entry->d_name[1] != '\0'))) { vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); return 0; } } - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); -- cgit v1.2.3 From a850cdd2b54a1aeda985ff60ac9c87024d5dce1e Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Tue, 25 Jun 1996 18:02:37 +0000 Subject: (diskfs_get_options): Include `--compat=' in options. --- ufs/main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 1e7a87bc..e62834dc 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -136,8 +136,11 @@ diskfs_get_options (char **argz, unsigned *argz_len) if (!err && compat_mode != COMPAT_GNU) { - char *mode = (compat_mode == COMPAT_BSD42) ? "4.2" : "4.4"; - err = argz_add (argz, argz_len, mode); + err = + argz_add (argz, argz_len, + ((compat_mode == COMPAT_BSD42) + ? "--compat=4.2" + : "--compat=4.4")); if (err) free (argz); /* Deallocate what diskfs returned. */ } -- cgit v1.2.3 From fbfb38b6e5f7aff900b2303cf0d0c727665a2774 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 3 Jul 1996 17:26:54 +0000 Subject: Include . (startup_parents, runtime_parents): Declare const. --- ufs/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index e62834dc..24a5723d 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -25,6 +25,7 @@ #include #include #include +#include char *ufs_version = "0.0"; @@ -113,11 +114,11 @@ parse_opt (int key, char *arg, struct argp_state *state) } /* Add our startup arguments to the standard diskfs set. */ -static struct argp *startup_parents[] = { &diskfs_std_device_startup_argp, 0}; +static const struct argp *startup_parents[] = { &diskfs_std_device_startup_argp, 0}; static struct argp startup_argp = {options, parse_opt, 0, 0, startup_parents}; /* Similarly at runtime. */ -static struct argp *runtime_parents[] = {&diskfs_std_runtime_argp, 0}; +static const struct argp *runtime_parents[] = {&diskfs_std_runtime_argp, 0}; static struct argp runtime_argp = {options, parse_opt, 0, 0, runtime_parents}; struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; -- cgit v1.2.3 From 8a42898a06d44fcf29899b1341404eb14767cf60 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Sat, 6 Jul 1996 16:45:23 +0000 Subject: (diskfs_truncate): Call record_poke after truncating a kludged symlink. --- ufs/sizes.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index 39717384..a0b090d3 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -63,6 +63,7 @@ diskfs_truncate (struct node *np, if (err) return err; bzero ((char *)di->di_shortlink + length, np->dn_stat.st_size - length); + record_poke (di, sizeof (struct dinode)); diskfs_end_catch_exception (); np->dn_stat.st_size = length; np->dn_set_ctime = np->dn_set_mtime = 1; -- cgit v1.2.3 From 6bf2b7eeb6a41032bf61e482460bd204c225b71c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Sat, 6 Jul 1996 17:28:09 +0000 Subject: (read_disknode): Don't set allocsize based on st->size for kludged symlinks. --- ufs/inode.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index c3eec832..aa2f3a8c 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -270,10 +270,17 @@ read_disknode (struct node *np) if (!S_ISBLK (st->st_mode) && !S_ISCHR (st->st_mode)) st->st_rdev = 0; - if (lblkno (sblock, np->dn_stat.st_size) < NDADDR) - np->allocsize = fragroundup (sblock, np->dn_stat.st_size); + if (S_ISLNK (st->st_mode) + && direct_symlink_extension + && st->st_size < sblock->fs_maxsymlinklen) + np->allocsize = 0; else - np->allocsize = blkroundup (sblock, np->dn_stat.st_size); + { + if (lblkno (sblock, np->dn_stat.st_size) < NDADDR) + np->allocsize = fragroundup (sblock, st->st_size); + else + np->allocsize = blkroundup (sblock, st->st_size); + } return 0; } -- cgit v1.2.3 From aee9ee88393ebb83a6359c9be867ea7285df31a2 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Sat, 6 Jul 1996 20:14:25 +0000 Subject: (ufs_version): Variable removed. --- ufs/main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 24a5723d..353a1852 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -26,8 +26,6 @@ #include #include #include - -char *ufs_version = "0.0"; struct node *diskfs_root_node; -- cgit v1.2.3 From 3a154d3cbff6b7110a67cf8a7dd12356a2a2a289 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 17 Jul 1996 22:55:08 +0000 Subject: Initial revision --- bsdfsck/ChangeLog | 98 ++++ devio/ChangeLog | 253 ++++++++ libmom/ChangeLog | 31 + mkbootfs/ChangeLog | 22 + ufs-fsck/ChangeLog | 245 ++++++++ ufs-utils/ChangeLog | 104 ++++ ufs/ChangeLog | 1586 +++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 2339 insertions(+) create mode 100644 bsdfsck/ChangeLog create mode 100644 devio/ChangeLog create mode 100644 libmom/ChangeLog create mode 100644 mkbootfs/ChangeLog create mode 100644 ufs-fsck/ChangeLog create mode 100644 ufs-utils/ChangeLog create mode 100644 ufs/ChangeLog (limited to 'ufs') diff --git a/bsdfsck/ChangeLog b/bsdfsck/ChangeLog new file mode 100644 index 00000000..0a948518 --- /dev/null +++ b/bsdfsck/ChangeLog @@ -0,0 +1,98 @@ +Thu Jul 6 15:30:43 1995 Michael I Bushnell + + * Makefile (tables.o): Delete target. + (vpath tables.c): Tell where to find tables.c. + + * Makefile: Removed dependencies that are now automatically + generated. + +Thu Nov 3 17:18:35 1994 Michael I Bushnell + + * Makefile (dir): Changed to bsdfsck. + (target): Changed to bsdfsck. + +Thu Oct 6 13:19:25 1994 Michael I Bushnell + + * dir.c (dircheck): Fix from Charles Hannum: dircheck() shouldn't + be looking at d_type or d_namlen in blank entries *at all*. Not + only is it wrong, but it causes a serious problem on little-endian + machines, since after -c2 conversion, d_type will often be > 15. + +Wed Oct 5 12:53:45 1994 Michael I Bushnell + + * pass1.c (checkinode) [mode == 0]: Check that di_trans + is also clear here. + + * fsck.h (IFTODT): Provide macro here. + * inode.c: Not here. + +Tue Oct 4 22:42:54 1994 Michael I Bushnell + + * inode.c (ckinode) [dino.di_trans set]: Only call IDESC->id_func + if IDESC->id_type is ADDR (meaning call function for each block). + If it's DATA, then that means call dirscan on each data block, + something entirely different. + + * inode.c (IFTODT): Provide macro. + +Fri Sep 30 21:28:57 1994 Roland McGrath + + * Makefile (LCLHDRS): Define. + +Fri Sep 16 10:57:04 1994 Michael I Bushnell + + * fsck.h (direct): Define macro. + +Thu Sep 1 14:51:23 1994 Michael I Bushnell + + * inode.c (ckinode): Don't pay attention to fs_maxsymlinklen + if it's -1. + * pass1.c (checkinode): Likewise. + + * fsck.h (DI_MODE): Use | not & for bitwise disjunction. + +Fri Aug 26 12:35:21 1994 Michael I Bushnell + + * main.c (main): Don't call checkblock. + + * pass5.c (ffs_fragacct): Copy in function from ../ufs/subr.c. + + * inode.c (ckinode): Call IDESC->id_func for passive translator + if it's set. + +Thu Aug 25 11:07:05 1994 Michael I Bushnell + + * setup.c: Don't include . + (setup): Comment out variable LP and label fetching code. + (calcsb, getdisklabel): Comment out functions. Replace + calcsb with one returning constant zero. + + * main.c: Don't include or . + (main): Don't run checkfstab; just print an error in that case. + (docheck): Comment out this function. + (checkfilesys): Comment out special code for HOTROOT. + +Wed Aug 24 11:11:23 1994 Michael I Bushnell + + * fsck.h (NBBY): Define macro. + +Tue Aug 23 15:54:49 1994 Michael I Bushnell + + * dir.c (fileerror): Use DI_MODE instead of di_mode member. + (adjust): Likewise. + (linkup): Likewise. + * inode.c (ckinode): Likewise. + (clri): Likewise. + (pinode): Likewise. + * pass1.c (checkinode): Likewise. + * pass2.c (pass2check): Likewise. + * utilities.c (ftypeok): Likewise. + + * inode.c (allocino): Set di_model and di_modeh instead of di_mode. + * pass1.c (checkinode): Likewise. + * pass2.c (pass2): Likewise. + + * fsck.h (DIRSIZ): Replace ufs version with old BSD version. + (struct dirtemplate, struct odirtemplate): Proved old BSD types. + (DEV_BSIZE, MAXPATHLEN): Provide definitions. + (DI_MODE): New macro. diff --git a/devio/ChangeLog b/devio/ChangeLog new file mode 100644 index 00000000..98362b44 --- /dev/null +++ b/devio/ChangeLog @@ -0,0 +1,253 @@ +Wed Jul 17 10:00:04 1996 Miles Bader + + * MAKEDEV (st): New function. + Use new st function (get rid of chmods). + Accept disk device names without partitions, & with slice + partition. + +Sat Jun 15 14:13:24 1996 Michael I. Bushnell, p/BSG + + * MAKEDEV ([hrs]d*): Allow user to specify slice as well. Patch + from Gord Matzigkeit, gord@enci.ucalgary.ca. + +Thu May 9 12:15:47 1996 Miles Bader + + * io.c (trivfs_S_io_select): Remove TAG arg. + (trivfs_S_file_get_storage_info): Fix param type. + +Tue May 7 16:41:48 1996 Miles Bader + + * io.c (trivfs_S_file_get_storage_info): Swap PORTS_TYPE & NUM_PORTS. + +Mon May 6 20:14:43 1996 Miles Bader + + * io.c (trivfs_S_file_get_storage_info): Enable new version. + +Fri May 3 15:09:00 1996 Miles Bader + + * io.c [0] (trivfs_S_file_get_storage_info): Rewrite for new interface. + +Tue Apr 30 10:03:50 1996 Michael I. Bushnell, p/BSG + + * Makefile (include ../Makeconf): BEFORE dependencies. + ($(prefix)/dev/MAKEDEV): Find MAKEDEV in $(srcdir). + +Fri Feb 16 19:28:32 1996 Miles Bader + + * MAKEDEV: Add rule for `time', and add `time' to std. + +Tue Jan 30 12:34:28 1996 Roland McGrath + + * MAKEDEV: Grok `tty'. + +Thu Jan 25 18:10:24 1996 Miles Bader + + * devio.c (trivfs_goaway): Handle errors from ports_inhibit_class_rpcs. + Allow rpcs to resume if we're going to return EBUSY. + +Tue Jan 16 16:19:51 1996 Miles Bader + + * devio.c (trivfs_modify_stat): The peropen hook holds a struct + open, not a struct dev. + +Fri Dec 29 23:41:39 1995 Miles Bader + + * MAKEDEV (std): Make `fd' one of the standard devices. + +Fri Dec 15 13:30:33 1995 Miles Bader + + * MAKEDEV (ST): Variable holding the proper settrans command, + which use. + (_CWD): Use this variable to pass down the current directory to + sub MAKEDEVS. + (console): Use the new term syntax. + (tty[0-9]?|tty[0-9a-f]): New rule for normal ttys. + ([pt]ty[pqPQ]?): New rule for ptys (both master and slave). + ([pt]ty[pqPQ]): New rule for making sets of ptys. + +Mon Dec 4 15:17:14 1995 Miles Bader + + * io.c (trivfs_S_file_set_size, trivfs_S_file_sync, + trivfs_S_file_syncfs, trivfs_S_file_get_storage_info): Add totally + gratuitous, annoying, and trouble-making reply-port args. + + * io.c (trivfs_S_file_get_storage_info): Use inline return if possible. + +Wed Nov 8 16:44:05 1995 Miles Bader + + * io.c (trivfs_S_file_set_size): Renamed from trivfs_S_file_truncate. + +Sun Nov 5 10:00:56 1995 Miles Bader + + * devio.c (main): Add FLAGS arg to trivfs_startup call. + +Sat Nov 4 20:03:05 1995 Miles Bader + + * io.c (trivfs_S_file_get_storage_info): Add FLAGS argument. + +Fri Oct 6 17:25:37 1995 Miles Bader + + * io.c (trivfs_S_file_get_storage_info): Change type of ADDRESSES + to off_t **, and add BLOCK_SIZE parameter. + +Sun Oct 1 16:20:45 1995 Miles Bader + + * devio.c (main, trivfs_S_fsys_syncfs): Get rid of debugging noise. + * rdwr.c (open_write, open_read): Ditto. + * dev.c (dev_open, dev_sync, dev_write, dev_read): Ditto. + * io.c (trivfs_S_file_syncfs, trivfs_S_file_sync): Ditto. + * devpager.c (pager_write_page, pager_read_page): Ditto. + * window.c (position): Ditto. + +Tue Sep 26 15:33:14 1995 Miles Bader + + * io.c (trivfs_S_file_get_storage_info): New function. + * dev.c (dev_open): Record NAME in the returned dev structure. + * dev.h (struct dev): Add the NAME field. + +Thu Aug 24 10:28:00 1995 Miles Bader + + * Makefile (devio): Put all dependencies here. + (HURDLIBS): Removed. + +Tue Aug 22 10:45:31 1995 Miles Bader + + * Makefile (HURDLIBS): Add libshouldbeinlibc. + (OBJS): Get rid of error.o. + Get rid of rules dealing with error.o. + ($(prefix)/dev/MAKEDEV): Use $(INSTALL_PROGRAM) instead of + $(INSTALL_DATA) + `chmod +x'. + + * devio.c (trivfs_modify_stat): Get the device from CRED now that + we have it. + +Mon Aug 21 16:34:29 1995 Miles Bader + + * devio.c (trivfs_goaway, trivfs_modify_stat): Update arguments. + +Tue Aug 15 19:47:57 1995 Roland McGrath + + * MAKEDEV ([hrs]d*): Fixed partition parsing: use glob pattern, + not regexp. + +Sun Aug 13 10:57:03 1995 Miles Bader + + * devio.c (trivfs_peropen_create_hook): This now returns an error_t. + (open_hook): And thus this does as well. + +Sat Jul 22 18:32:03 1995 Miles Bader + + * rdwr.c (open_read, open_write): Clean up STATE before returning + with an error. + * devpager.c (dev_get_memory_object): A new pager now comes with 1 + ref, so we allocate a ref ourselves when we're using an old one, + and once we've created the send right, remove a reference. + +Mon Jul 10 15:15:45 1995 Miles Bader + + * rdwr.c (open_seek): New function. + (raw_read, raw_write): Return EINVAL if *OFFS isn't a block boundary. + * open.h: Add declaration for open_seek. + * io.c (trivfs_S_io_seek): Call open_seek instead of doing ourselves. + +Sat Jul 8 18:35:17 1995 Miles Bader + + * MAKEDEV (fd): Put the fd server on `fd', not `stdin'. + * MAKEDEV (console): Give /hurd/term a ttyname argument. + +Thu Jul 6 15:33:33 1995 Miles Bader + + * Makefile: Remove include dependencies. + +Wed Jun 28 19:22:47 1995 Miles Bader + + * Makefile (HURDLIBS): Add libihash. + + * iostate.c (io_state_sync): Remember that we've synced the buffer. + * devpager.c (dev_stop_paging): New function. + (pager_dropweak): New function. + * dev.h (struct dev): Add the pager_port_bucket field. + Declare dev_stop_paging (). + * devio.c (trivfs_goaway): Make trivfs_goaway do the right thing. + (clean_exit, close_device): Deleted functions. + (thread_cancel): New function. + + * devpager.c (pager_port_type): Deleted var. + (pager_port_bucket, pager_port_class): New vars. + (dev_get_memory_object): Moved here from dev.c. Also, call + init_dev_pager if necessary. + (service_paging_requests): New function. + (init_dev_pager): New function. + * dev.c (dev_get_memory_object): Moved function to devpager.c. + + * devio.c (fsys_port_class, root_port_class, port_bucket): New vars. + (trivfs_protid_portclasses, trivfs_cntl_portclasses, + trivfs_protid_nportclasses, trivfs_cntl_nportclasses): New vars. + (main): Initialize *portclasses vars, and convert to new trivfs lib. + (trivfs_protid_porttypes, trivfs_cntl_porttypes, + trivfs_protid_nporttypes, trivfs_cntl_nporttypes): Deleted vars. + (trivfs_goaway): Convert args for new trivfs lib. + (ports_cleanroutines): Delete var. + (ports_demuxer, ports_notice_idle, ports_no_live_ports, + ports_no_hard_ports): Delete functions. + * ptypes.h: Deleted file. + +Wed Jun 28 15:51:51 1995 Michael I Bushnell + + * Makefile: Repair mangled include-file dependencies. + +Fri Apr 21 14:17:19 1995 Roland McGrath + + * MAKEDEV: Split out `std' into individual device-makers it calls. + Rewrote /dev/fd stuff (still commented out). Use case built-in + instead of expr program. + +Tue Apr 11 15:46:35 1995 Michael I Bushnell + + * Makefile (DIST_FILES): New var, for MAKEDEV. + (install): Depend on $(prefix)/dev/MAKEDEV. + ($(prefix)/dev/MAKEDEV): New target. + * MAKEDEV: New file. + +Mon Apr 10 10:22:26 1995 Miles Bader + + * rdwr.c (open_write, open_read): Bounds check I/O. + + * io.c (trivfs_S_file_truncate): Always return 0, so O_TRUNC works. + + * devio.c (main, check_open_hook, close_device, trivfs_goaway): + Add a new lock, device_lock, and use it to control access to the + DEVICE variable. + (open_hook, trivfs_modify_stat, trivfs_S_fys_syncfs): Copy DEVICE + before using it, so it doesn't change underneath us. + + * devio.c (clean_exit): Add a new argument that says whether to + aquire a lock before doing our work. + (ports_notice_idle, ports_no_live_ports): Use it. + + * devio.c (close_device): New function, closes DEVICE cleanly. + (clean_exit, ports_no_hard_ports): Use close_device. + + * devio.c (main): Use trivfs_startup instead of doing it manually. + + * devio.c (trivfs_goaway): Try and do it better, paying attention + to flags, etc.; this still isn't right though, we may want to wait + for the ports library to be fixed first. + + * devio.c (DEBUG): New macro, executes its arg with debug_lock locked. + (most everything): use DEBUG instead of doing things manually. + + * open.c (open_create): Supply our dev's size when creating a window. + +Sun Apr 9 14:49:33 1995 Miles Bader + + * window.h: Add a new window field, max_pos. Rename the location + field `pos'. + * window.c (position): Use a shorter than normal window if + necessary to avoid going past the end of the device. + (window_create): Initialize the new MAX_POS field. + (window_create, position, window_write, window_read): Rename the + location field `pos'. + + * devpager.c (pager_read_page, pager_write_page): Read or write + partial pages at the end of the device. + diff --git a/libmom/ChangeLog b/libmom/ChangeLog new file mode 100644 index 00000000..f04006c5 --- /dev/null +++ b/libmom/ChangeLog @@ -0,0 +1,31 @@ +Sat May 25 17:25:09 1996 Michael I. Bushnell, p/BSG + + * refs-identical.c (mom_ports_identical): Omit uses of deleted + members of struct mom_port_ref.c. + + * ref-destroy.c (mom_ref_destroy): Omit uses of deleted members of + struct mom_port_ref.c. + + * mach-port-set.c (mom_mach_port_set): Omit uses of deleted + members of struct mom_port_ref.c. + + * fetch-mach-port.c (mom_fetch_mach_port): Omit uses of deleted + members of struct mom_port_ref.c. + + * copy-ref.c (mom_copy_ref): Likewise. + + * mom-kerndep.h (struct mom_port_ref): Delete members `lock' and + `refcnt'. + * Makefile (SRCS): Delete add-ref.c and drop-ref.c. + * mom.h (mom_add_ref, mom_drop_ref): Delete functions. + * add-ref.c, drop-ref.c: Delete files. + +Fri May 24 16:14:54 1996 Michael I. Bushnell, p/BSG + + * mom.h: Include . + * error-trans.c: New file. + * mom-kerndep.h (mom_error_translate_mach): New function. + * Makefile (LCLHDRS, installhdrs): Add mom-errors.h. + (SRCS): Add error-trans.c. + * mom-errors.h: New file. + diff --git a/mkbootfs/ChangeLog b/mkbootfs/ChangeLog new file mode 100644 index 00000000..787943a2 --- /dev/null +++ b/mkbootfs/ChangeLog @@ -0,0 +1,22 @@ +Fri Jul 22 10:38:17 1994 Michael I Bushnell + + * Makefile: Rewritten in accord with new scheme. + +Wed Jul 20 16:24:08 1994 Michael I Bushnell + + * Makefile (mkbootfs): Put -n after hostname for compat with + old broken rsh. + Use gcc literally instead of MIGHOSTCC. + +Tue Jul 5 14:22:00 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * Makefile (SRCS): New variable. + +Fri May 6 13:25:47 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * Makefile (mkbootfs): Use MIGHOSTCC instead of CC. + +Thu May 5 19:06:21 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * Makefile (mkbootfs): Call rsh with -n flag. + diff --git a/ufs-fsck/ChangeLog b/ufs-fsck/ChangeLog new file mode 100644 index 00000000..1ea09c4a --- /dev/null +++ b/ufs-fsck/ChangeLog @@ -0,0 +1,245 @@ +Sat Jul 6 19:59:27 1996 Miles Bader + + * main.c (argp_program_version): New variable. + : New include. + +Mon Jul 1 12:55:48 1996 Michael I. Bushnell, p/BSG + + * pass2.c (pass2): Don't skip empty directories in `.' and `..' + correctness check; we don't clear them the way BSD does, so we + want `.' and `..' to get created for us. Also handle `.' before + `..' so that they get created in the usual order for empty + directories. + + * dir.c (makeentry): After successful directory expansion, write + out modified directory inode. + + * pass4.c (pass4): If a reconnect fails while we are preening, + give up. + +Mon Jun 24 10:19:39 1996 Michael I. Bushnell, p/BSG + + * utilities.c (errexit, punt): Exit with status 8 for catastrophic + failures. + +Thu May 23 14:12:21 1996 Michael I. Bushnell, p/BSG + + * pass2.c (pass2): Don't clear all node types in directories, just + clear those that are wrong. + +Tue May 14 16:49:46 1996 Miles Bader + + * pass2.c (pass2): Fix up test in preen case. + +Tue May 14 15:29:36 1996 Michael I. Bushnell, p/BSG + + * pass2.c (pass2): Handle directory entry type fields better for + Hurd. + +Sat May 11 01:07:49 1996 Miles Bader + + * main.c (parse_opt): Use ARGP_ERR_UNKNOWN instead of EINVAL. + +Thu May 9 20:12:51 1996 Michael I. Bushnell, p/BSG + + * pass1b.c (pass1b): Bother to initialize NUMBER. + +Fri May 3 00:48:39 1996 Miles Bader + + * main.c (nice_size, show_stats): New functions. + (main): Use show_stats. + +Wed May 1 13:59:06 1996 Miles Bader + + * main.c (main): Shorten summary message so that it fits on one line. + * utilities.c (no_preen): New function. + (problem, warning, pinode): Use it. + (warning): Don't flush all pending problems, just our own. + * dir.c (linkup): Consistently put quotes around filenames. + + * main.c (preen, num_files): New variables. + (main): Implement clean-bit checking in preen mode, and print + summary statistics. + (main, options): Add --force & --silent options. + * pass1.c (pass1): Increment NUM_FILES. + When clearing inode due to bad blocks, continue. + * inode.c (allocino, freeino): Frob NUM_FILES. + * fsck.h (force): New declaration. + * pass5.c (pass5): Vary clean msg depending on whether FSMODIFIED. + * setup.c (setup): Use error to print error msgs. + , : New includes. + + * utilities.c (problem, warning, pextend, pfail): New functions. + (pinode, pfix, reply): Use new problem recording stuff. + (push_problem, resolve_problem, flush_problems): New functions. + (struct problem): New type. + (problems, free_problems): New variables. + (retch, punt): New functions. + * fsck.h (problem, warning, pextend, pfail): New declarations. + (pinode): Update declaration. + * dir.c (validdir, makeentry, linkup): Use new printing functions. + * pass1.c (pass1): Likewise. + * pass1b.c (pass1b): Likewise. + * pass2.c (pass2): Likewise. + * pass3.c (pass3): Likewise. + * pass4.c (pass4): Likewise. + * pass5.c (pass5): Likewise. + * setup.c (setup): Likewise. + +Tue Apr 30 19:06:42 1996 Miles Bader + + * pass5.c (pass5): Be sure to call pwarn before pfix. + * main.c (main): Don't print large obnoxious banner if PREEN. + +Fri Apr 26 16:20:37 1996 Michael I. Bushnell, p/BSG + + * inode.c (allocino): Parenthesize test correctly. + + * fsck.h (swab_disk): Define as constant zero. + + * pass5.c (pass5): If not marked clean, but now it is, then offer + to mark it clean. + * utilities.c (reply): Set fix_denied anytime we return 0. + * fsck.h (fix_denied): New variable. + +Wed Apr 24 13:32:39 1996 Michael I. Bushnell, p/BSG + + * pass1.c (pass1): Don't print block numbers as we go anymore. + +Tue Apr 23 10:11:49 1996 Michael I. Bushnell, p/BSG + + * pass5.c (pass5): Correctly track contig summaries even though + they aren't used by the filesystem; we still need to preserve the + format. + +Mon Apr 15 12:51:41 1996 Michael I. Bushnell, p/BSG + + * Makefile (vpath tables.c): Find ufs directory in $(top_srcdir). + +Tue Apr 2 09:00:53 1996 Michael I. Bushnell, p/BSG + + * pass1.c (pass1): Print mode correctly in unknown file type case. + Recognize inode type IFSOCK too. + +Mon Mar 18 19:48:39 1996 Miles Bader + + * main.c (main): Pass new arg to argp_parse. Use argp_usage correctly. + +Thu Oct 19 17:45:12 1995 Miles Bader + + * main.c (main): Exit with a non-zero status if we fixed anything. + Use argp to parse options. + (options): Converted to argp format. + (args_doc): New variable. + (USAGE, usage, SHORT_OPTIONS): Removed. + Include instead of . + * Makefile ($(target)): Depend on libshouldbeinlibc.a. + +Fri Sep 22 16:55:03 1995 Miles Bader + + * utilities.c (pfix): New function. + (pfatal, pwarn, errexit): Print DEVICE_NAME too if in preen mode. + * fsck.h: Declare DEVICE_NAME. + * setup.c (setup): Set DEVICE_NAME. + * pass1.c, pass2.c, pass3.c, pass4.c, pass5.c (pass1, pass2, + pass3, pass4, pass5): Call pfix instead of printf. + * pass1.c (pass1): Only print progress report if not in preen mode. + * main.c (main): Only print section headers if not in preen mode. + +Wed Sep 20 09:11:59 1995 Miles Bader + + * utilities.c (pinode): Take a message & args to print as well. + * fsck.h: Change declaration of pinode. + * pass2.c (pass2): Use changed pinode. + * pass3.c (pass3): Use changed pinode. + * pass4.c (pass4): Use changed pinode. + +Tue Sep 19 15:37:02 1995 Miles Bader + + * pass1.c (pass1): Change the extent of DBWARN & IBWARN so that + they actually work. + * pass2.c (pass2): Adjust our record of link counts when we + add/change dir entries; also print error messages when we can't. + * pass4.c (pass4): If an unlinked file can't be reconnected, offer + to clear it. Once a reconnect attempt fails, don't try again. + * dir.c (linkup): Print the value of LFNAME rather than `lost+found'. + (searchdir, changeino): Fix backward compare. + (linkup): Don't fail when makeentry succeeds. + (searchdir): Make searchdir return zero if there's an error + during the search. + (linkup): Print appropiate error messages if searchdir fails. + (validdir): Get rid of extra newlines in error messages -- + everyone who calls this routine prints extra information if it + fails, which should immediately follow. + * main.c (main): Use getopt to parse command line options. + (usage): New function. + (options): New variable. + (lfname, lfmode): Variables moved here from setup.c. + (lfname): Made into a char* so that we can change it. + (lfmode): Get rid of IFDIR; it's added when necessary. + * fsck.h: Change LFNAME to char*. + * setup.c (lfname, lfmode): Variables moved to main.c. + +Sat Sep 9 12:12:59 1995 Miles Bader + + * Makefile (target): Changed to `fsck.ufs'. + (installationdir): New variable, install into $(sbindir). + +Thu Jul 6 15:33:46 1995 Michael I Bushnell + + * fsck.h (lookup_directory): New decl. + + * pass1.c (pass1): Remove assignment from if test. + * utilities.c (pinode): Likewise. + + * Makefile (tables.o): Delete rule. + (vpath tables.c): Tell where to find tables.c. + + * Makefile: Removed dependencies that are now automatically + generated. + +Thu Nov 3 17:19:03 1994 Michael I Bushnell + + * Makefile (dir): Changed to fsck. + (target): Changed to fsck. + +Wed Nov 2 14:39:13 1994 Michael I Bushnell + + * pass2.c (pass2): Use DIRECT_NAMLEN instead of d_namlen + throughout. + * dir.c (searchdir): Likewise. + (changeino): Likewise. + (makeentry): Likewise. + +Mon Oct 17 16:07:56 1994 Michael I Bushnell + + * inode.c (inode_iterate): FN takes new third arg. + Keep track of new var `offset' and pass it to FN. + * pass2.c (pass2/checkdirblock): New third arg. + Only scan DIRBLKSIZ chunks to the total size of the file. + * dir.c (searchdir/checkdirblock): Likewise. + (changeino/checkdirblock): Likewise. + (makeentry/checkdirblock): Likewise. + * pass1.c (pass1/checkblock): New third arg (ignored). + * pass1b.c (pass1b/checkblock): Likewise. + + * inode.c (inode_iterate): Compute MAXB correctly. + + * utilities.c (getinode): Multiple ino_to_fsbo by + sizeof (struct dinode). + (write_inode): Likewise. + (getinode): Inode buffer needs to be a full block, not a + fragment. + +Fri Oct 14 21:07:09 1994 Michael I Bushnell + + * utilities.c (lastifrag): New variable. + (getinode): Use lastifrag instead of buf; Only I/O new block + if lastifrag isn't what we want. + (write_inode): Likewise. + +Fri Oct 14 17:44:59 1994 Michael I Bushnell + + * setup.c (setup): Test ISCHR, not ISDIR. + Fix NCYL against NCG * CPG test. + Bother to set MAXFSBLOCK, MAXINO, and DIRECT_SYMLINK_EXTENSION. diff --git a/ufs-utils/ChangeLog b/ufs-utils/ChangeLog new file mode 100644 index 00000000..d6d58f5d --- /dev/null +++ b/ufs-utils/ChangeLog @@ -0,0 +1,104 @@ +Fri Jun 21 02:12:16 1996 Miles Bader + + * dlabel.c (fd_get_device): Supply new args to store_create. + +Sat May 11 01:20:18 1996 Miles Bader + + * mkfs.c (parse_opt): Use ARGP_ERR_UNKNOWN instead of EINVAL. + +Fri May 10 15:50:38 1996 Miles Bader + + * dlabel.c (fd_get_device): Update to use libstore. + : New include. + * Makefile (mkfs.ufs): Depend on ../libstore/libstore.a. + +Tue Apr 30 10:06:21 1996 Michael I. Bushnell, p/BSG + + * Makefile (include ../Makeconf): BEFORE dependencies. + (all): Delete target. + ($(targets)): Each target depends on its associated .o. + +Wed Apr 3 16:31:13 1996 Miles Bader + + * mkfs.c (main): In `Can't get disklabel' error message, specify + which flag the user can use to supply the needed information. + (mkfs): Fiddle with info message. + +Sun Mar 31 14:34:28 1996 Miles Bader + + * stati.c (mode_rep): Prefix octal number with `0'. + +Fri Mar 29 11:56:52 1996 Miles Bader + + * stati.c (main): Print mode & {in,}direct blocks too. + (mode_rep): New function. + (timespec_rep): P shouldn't be static. + + * mkfs.c (main): Argp interface changes. + +Wed Mar 13 18:30:55 1996 Miles Bader + + * mkfs.c (options, args_doc, doc): New variables for option parsing. + (struct amark): New type. + (amarks_add, amarks_contains): New functions. + (default_disklabel): New variable. + (main): Most arguments are now options (and optional). Allow many + more parameters to be specified. Consult the disk label for some + defaults. + (most functions): Add explicit return type declarations. Fix + printf format specifications. Get rid of #ifdefs for MFS. + (started, malloc, realloc, calloc, free): Functions removed. + (mfs, membase): Variables removed. + , , , , , + : New includes + * dlabel.c: New file. + * Makefile (SRCS): Add dlabel.c. + (mkfs.ufs): New target. + +Tue Feb 27 14:52:00 1996 Miles Bader + + * clri.c: Move here from ../utils. + + [Entire directory renamed to `ufs-utils' from `newfs'] + +Sat Sep 9 12:17:11 1995 Miles Bader + + * Makefile (target): Changed to `mkfs.ufs'. + (installationdir): New variable, install into $(sbindir). + +Thu Nov 24 18:39:30 1994 Roland McGrath + + * mkfs.c: Protect all mfs code with #ifdef MFS. + +Wed Oct 12 12:59:01 1994 Michael I Bushnell + + * mkfs.c (main): MAXCONTIG should be zero because we don't + do clustering. + +Fri Sep 9 09:45:23 1994 Michael I Bushnell + + * mkfs.c: Include and . + (main): New function. Punt newfs.c for now. + * Makefile (SRCS, OBJS): Comment out uses of newfs.c. + (target): Build mkfs, not newfs. + + * newfs.c (mopts): Comment out. + (mntflags): Comment out. + (main): Omit check for `mfs'. Omit var `partition'. + (main) [case 'o']: Comment out mfs specific code. + (main): Comment out check for already-mounted partition. + (main): Comment out MFS specific open of FSI. + + * mkfs.c (fsinit): Use DI_MODE to read mode from NODE, and + set di_model and di_modeh instead of di_mode. + (mkfs): Don't set fields in *PP. + + * newfs.c: Include ufs header files with "../ufs/foo.h" instead of + . Don't include , , + or "mntopts.h". + +Thu Sep 8 15:52:05 1994 Michael I Bushnell + + * mkfs.c: Include ufs header files with "../ufs/foo.h" instead of + . Don't include . + diff --git a/ufs/ChangeLog b/ufs/ChangeLog new file mode 100644 index 00000000..368a2f59 --- /dev/null +++ b/ufs/ChangeLog @@ -0,0 +1,1586 @@ +Sat Jul 6 16:14:10 1996 Miles Bader + + * main.c (ufs_version): Variable removed. + +Sat Jul 6 12:45:36 1996 Michael I. Bushnell, p/BSG + + * inode.c (read_disknode): Don't set allocsize based on st->size + for kludged symlinks. + + * sizes.c (diskfs_truncate): Call record_poke after truncating a + kludged symlink. + +Wed Jul 3 13:27:04 1996 Michael I. Bushnell, p/BSG + + * main.c: Include . + (startup_parents, runtime_parents): Declare const. + +Tue Jun 25 14:02:02 1996 Miles Bader + + * main.c (diskfs_get_options): Include `--compat=' in options. + +Mon Jun 24 16:59:12 1996 Michael I. Bushnell, p/BSG + + * dir.c (diskfs_lookup_hard): Use diskfs_check_readonly instead of + diskfs_readonly. + (diskfs_dirempty): Likewise. + + * dir.c (diskfs_lookup_hard): Use diskfs_check_readonly instead of + diskfs_readonly. + (diskfs_dirempty): Likewise. + * inode.c (diskfs_cached_lookup): Likewise. + (read_symlink_hook): Likewise. + * sizes.c (diskfs_truncate): Call diskfs_check_readonly. + (diskfs_grow): Likewise. + * hyper.c (diskfs_set_hypermetadata): If CLEAN is not set, make + sure we clear the clean bit on disk. Always call sync_disk (with + appropriate WAIT). + (diskfs_readonly_changed): Don't do set_hypermetadata here. + (copy_sblock): Don't track clean state here. + + * pager.c (diskfs_shutdown_pager): Don't shutdown DISKPAGER ever, + just sync it instead. + +Sat Jun 22 17:45:34 1996 Miles Bader + + * main.c (diskfs_get_options): New function. + (options): Make const. + +Fri Jun 21 01:32:09 1996 Miles Bader + + * main.c (parse_opt): Handle runtime invalid selection of 4.2 mode. + Save select mode until we're done to correctly deal with external + errors at runtime. + (startup_parents, startup_argp, runtime_parents, runtime_argp): + New variables. + (main): Argp vars made global. + (argp_parents): diskfs_device_startup_argp --> + &diskfs_std_device_startup_argp. + +Sat Jun 15 13:57:27 1996 Miles Bader + + * main.c (options): New variable. + (parse_opt): New function. + (main): Parse ufs-specific options too. + : New include. + +Fri May 10 09:29:03 1996 Michael I. Bushnell, p/BSG + + * inode.c (diskfs_set_statfs): Fix one reference to old name of ST + member. + +Thu May 9 11:54:13 1996 Michael I. Bushnell, p/BSG + + * Makefile (ufs.static ufs): s/ioserver/iohelp/g + * ufs.h: ioserver.h -> iohelp.h. + + * inode.c (diskfs_set_statfs): Use and fill in new statfs + structure. + +Mon May 6 14:23:54 1996 Michael I. Bushnell, p/BSG + + * main.c (ufs_version): Upgrade to 0.0. + +Fri May 3 09:15:33 1996 Michael I. Bushnell, p/BSG + + * sizes.c (block_extended): Rewrite code that moves pages + to be more efficient, and not deadlock too, using unlocked + pagein permission feature (read "hack"). Return value + now indicates whether we expect a sync. + (diskfs_grow): If a call to block_extended returns nonzero, + then sync the file before returning. + * pager.c (diskfs_get_filemap): Initialize + UPI->allow_unlocked_pagein and UPI->unlocked_pagein_length. + (unlocked_pagein_lock): New variable. + (find_address): New parameter `isread'; all callers changed. + If ISREAD and we are in the unlocked pagein region, don't + attempt to acquire NP->dn->allocptrlock. + * ufs.h (struct user_pager_info): New members + `allow_unlocked_pagein' and `unlocked_pagein_length'. + (unlocked_pagein_lock): New variable. + +Thu May 2 10:56:10 1996 Michael I. Bushnell, p/BSG + + * sizes.c (offer_data): Offer pages at ADDR each time through the + loop, not the same page over and over. + (block_extended): When moving data, sync in-core pager both before + reading from disk and after providing data to kernel. + (diskfs_grow): Always call block_extended or offer_data before + adjusting block pointer. + +Tue Apr 30 13:38:42 1996 Michael I. Bushnell, p/BSG + + * sizes.c (diskfs_grow): In last offer_data, don't offer a block + number as an address. + +Fri Apr 26 15:35:53 1996 Michael I. Bushnell, p/BSG + + * Makefile (makemode): Now `servers'. + (targets): Renamed from `target'; now include ufs.static. + (ufs.static-LDFLAGS): Renamed from `LDFLAGS'. + (ufs.static): Depend on same things as `ufs'. + (include ../Makeconf): Must come before dependency information. + +Wed Apr 24 14:05:48 1996 Michael I. Bushnell, p/BSG + + * dir.h (DIRECT_NAMLEN) [! LITTLE_ENDIAN]: Deal correctly with the + case where it was written on a little endian machine without the + extension. + (DIRECT_NAMLEN) [LITTLE_ENDIAN]: Deal with case correctly where it + was written without the extension on a big endian machine. + * dir.c (dirscanblock): Use read/write_disk_entry when reading or + writing fields from directory entries. + (diskfs_direnter_hard): Likewise. + (diskfs_dirremove_hard): Likewise. + (diskfs_dirrewrite_hard): Likewise. + (diskfs_get_directs): Likewise. + (diskfs_dirempty): Likewise. + (count_dirents): Likewise. + +Tue Apr 23 11:28:42 1996 Michael I. Bushnell, p/BSG + + * dir.c (diskfs_dirempty): node_update -> diskfs_node_update. + + * hyper.c (swab_sblock, swab_csums): New functions. + (get_hypermetadata): If this is a swapped filesystem, set swab_disk. + Also swap csum and sblock after reading them. + (diskfs_set_hypermetadata): If swab_disk, swap the csums back before + writing them. + (copy_sblock): If swab_disk, swap the sblock before writing it. + * ufs.h (swab_disk): New variable. + (swab_short, swab_long, swab_long_long): New functions. + (read_disk_entry, write_disk_entry): New macros. + * alloc.c (ffs_realloccg): Use read/write_disk_entry when + reading/writing on-disk inode fields. + * bmap.c (fetch_indir_spec): Likewise. + * inode.c (read_disknode): Likewise. + (write_node): Likewise. + (diskfs_set_translator): Likewise. + (diskfs_get_translator): Likewise. + (diskfs_S_file_get_storage_info): Likewise. + * sizes.c (diskfs_truncate): Likewise. + (diskfs_grow): Likewise. + * pager.c (pager_unlock_page): Likewise. + * bmap.c (fetch_indir_spec): Use read/write_disk_entry when + reading/writing on-disk indirect blocks. + * sizes.c (diskfs_truncate): Likewise. + (indir_release): Likewise. + (diskfs_grow): Likewise. + * pager.c (pager_unlock_page): Likewise. + * alloc.c: Include + (ffs_blkpref): Use read_disk_entry when reading from BAP array. + (swab_cg, read_cg, release_cg): New functions. + (ffs_fragextend, ffs_alloccg, ffs_nodealloccg, ffs_blkfree, + diskfs_free_node): Use new cg access functions. + +Thu Apr 18 14:50:30 1996 Michael I. Bushnell, p/BSG + + * sizes.c (diskfs_grow): New variable `pagerpt'. + (offer_zeroes, block_extended): New functions. + (diskfs_grow): In initializing newly allocated data disk blocks with + zeroes, use less aggressive offer_zeroes instead of immediate + synchronous writes. After ffs_realloccg succeeds, use + block_extended to handle the magic. Get rid of old poke calls. + * alloc.c (ffs_realloccg): If we are allocating a new block, don't + actually free the old one here. + * sizes.c (diskfs_grow): New variable `pagerpt'. + (offer_zeroes, block_extended): New functions. + (diskfs_grow): In initializing newly allocated data disk blocks + with zeroes, use less aggressive offer_zeroes instead of immediate + synchronous writes. After ffs_realloccg succeeds, use + block_extended to handle the magic. Get rid of old poke calls. + +Tue Apr 16 15:20:07 1996 Michael I. Bushnell, p/BSG + + * dir.c (diskfs_lookup_hard): Set atime appropriately, and sync + the new atime if we are running synchronously (!). + (diskfs_dirempty): Likewise. + (diskfs_direnter_hard): Set mtime appropriately. + (diskfs_dirremove_hard): Likewise. + (diskfs_dirrewrite_hard): Likewise. + + * inode.c (diskfs_write_disknode): Only do sync if WAIT is set. + +Thu Apr 4 16:39:22 1996 Miles Bader + + * inode.c (diskfs_cached_lookup): Intialize NP->cache_id *after* + NP exists. + +Wed Apr 3 16:03:51 1996 Michael I. Bushnell, p/BSG + + * inode.c (diskfs_cached_lookup): Renamed from `iget'. All + callers changed. Initialize NP->cache_id. + +Fri Mar 29 16:52:31 1996 Michael I. Bushnell, p/BSG + + * sizes.c (diskfs_truncate): Cast DI->di_shortlink to correct type + before adding a character count to it. + +Mon Mar 25 13:08:10 1996 Michael I. Bushnell, p/BSG + + * dir.c (diskfs_null_dirstat): New function. + +Fri Mar 22 23:43:53 1996 Miles Bader + + * inode.c (read_symlink_hook): Only set NP's atime if !readonly. + +Wed Mar 20 14:36:31 1996 Michael I. Bushnell, p/BSG + + * dir.c (diskfs_lookup_hard): Don't do initial or final permission + checking here. + * dir.c (diskfs_dirrewrite_hard): Renamed from diskfs_dirrewrite. + No longer call modification tracking routines. + (diskfs_dirremove_hard): Renamed from diskfs_dirremove. No longer call + modification tracking routines. + (diskfs_direnter_hard): Renamed from diskfs_direnter. No longer call + modification tracking routines. + (diskfs_lookup_hard): Renamed from diskfs_lookup. + +Mon Mar 18 19:50:41 1996 Miles Bader + + * main.c (main): Pass new arg to argp_parse. + +Mon Mar 18 12:33:06 1996 Michael I. Bushnell, p/BSG + + * pager.c (diskfs_max_user_pager_prot) [add_pager_max_prot]: + (a == b) ? 1 : 0 ====> (a == b). + +Fri Feb 23 15:27:05 1996 Roland McGrath + + * hyper.c (get_hypermetadata): Use diskfs_device_arg in unclean msgs. + +Wed Feb 21 05:57:12 1996 Roland McGrath + + * hyper.c: Implement proper handling of the filesystem `clean bit'. + (ufs_clean): New variable. + (get_hypermetadata): Set it from the fs_clean flag. If not clean, + complain and force read-only. Complain when ignoring COMPAT_BSD42. + (diskfs_set_hypermetadata): Set the clean flag in the superblock + when CLEAN and fs was clean to start with. + (copy_sblock): Remove bogus clean flag frobnication. + +Fri Feb 16 17:05:36 1996 Miles Bader + + * main.c (main): Check error return from diskfs_init_diskfs. + +Sat Jan 6 11:50:14 1996 Roland McGrath + + * ufs.h (diskpager, diskpagerport, disk_image): Variables removed. + Include instead. + (sync_disk_blocks): Use `disk_pager' in place of `diskpager->p'. + * pager.c (diskfs_shutdown_pager, diskfs_sync_everything): Use + `disk_pager' in place of `diskpager->p'. + (create_disk_pager): Rewritten using disk_pager_setup. + * pokeloc.c (sync_disk): Use `disk_pager' in place of `diskpager->p'. + * sizes.c (indir_release): Likewise. + * main.c (diskfs_reload_global_state): Likewise. + +Thu Jan 4 19:10:11 1996 Roland McGrath + + * main.c (main): Don't map disk image here; create_disk_pager now + does it. + + * hyper.c (get_hypermetadata, copy_sblock): Don't put + diskfs_catch_exception () inside assert, bonehead! Use + assert_perror on a variable of its result. + +Mon Jan 1 16:38:14 1996 Michael I. Bushnell, p/BSG + + * pager.c (pager_unlock_page): When allocating block in direct + array, clear it synchronously just like we do when it goes in the + indirect array. + +Thu Nov 9 14:01:30 1995 Michael I. Bushnell, p/BSG + + * dir.c (struct dirstat): New member `nbytes'. + (dirscanblock): If DS->type is COMPRESS, still look + for TAKE/SHRINK possibilities. Also, if it's COMPRESS, + still look to see if the current block can be compressed + with fewer byte copies. + +Sun Nov 5 02:08:38 1995 Miles Bader + + * main.c (main): Add flags arg to diskfs_startup_diskfs call. + +Sat Nov 4 20:01:58 1995 Miles Bader + + * inode.c (diskfs_S_file_get_storage_info): Add FLAGS argument. + +Thu Oct 19 12:50:11 1995 Miles Bader + + * pager.c (diskfs_max_user_pager_prot): Return what we discovered, + instead of 1. + + * dir.c (diskfs_lookup, diskfs_dirempty): Give diskfs_get_filemap + a protection arg. + * sizes.c (diskfs_truncate, diskfs_grow): Ditto. + + * hyper.c (diskfs_readonly_changed): Give the 2nd arg to + vm_protect an appropiate type. + + * pager.c (diskfs_max_user_pager_prot): Stop iterating early if poss. + +Wed Oct 18 16:28:42 1995 Miles Bader + + * ufs.h (struct user_pager_info): Add max_prot field. + * pager.c (diskfs_get_filemap): Add PROT parameter, & use it. + (diskfs_pager_users): Split out block_caching & enable_caching. + (block_caching, enable_caching): New function. + (diskfs_max_user_pager_prot): New function. + + * main.c (main): Always include VM_PROT_WRITE in max prot. + * hyper.c (diskfs_readonly_changed): Change the protection of + DISK_IMAGE to reflect the new state. Clear SBLOCK_DIRTY if readonly. + + * inode.c (read_disknode): Bother to set the allocsize field. + + * ufs.h (struct rwlock): Structure deleted. + (rwlock_init, rwlock_reader_unlock, rwlock_reader_lock, + rwlock_writer_lock, rwlock_writer_unlock): Functions deleted. + + +Tue Oct 17 14:49:43 1995 Miles Bader + + * inode.c (diskfs_node_reload): New function. + (iget): Move allocsize setting into read_disknode. + * pager.c (flush_node_pager): New function. + * ufs.h (zeroblock, sblock, csum): Declare extern. + (flush_node_pager, flush_pokes): New declarations. + * pokeloc.c (flush_pokes): New function. + * hyper.c (diskfs_readonly_changed): New function. + (get_hypermetadata): Move compat_mode futzing & disk size + validation here from main. + (zeroblock, sblock, csum): Define (were common). + (get_hypermetadata): Only allocate SBLOCK if not already done. + Deallocate any old ZEROBLOCK and CSUM storage. + (diskfs_readonly_changed): New function. + * main.c (main): Move stuff into get_hypermetadata. + Writable init code moved to diskfs_readonly_changed. + (diskfs_reload_global_state): New function. + +Fri Oct 13 15:03:37 1995 Miles Bader + + * main.c (main): Use new handy diskfs routines and get rid of + tons of junk. Main should be almost all ufs-specific now. + (USAGE, usage, SHORT_OPTS, long_opts, parse_opt, trans_parse_arg): RIP. + (printf_lock): Initialize. + +Thu Oct 12 18:48:04 1995 Miles Bader + + * pager.c (pager_unlock_page, pager_write_page, pager_read_page): + Use diskfs_device_{read,write}_sync instead of dev_{read,write}_sync. + * hyper.c (diskfs_set_hypermetadata): Ditto. + * sizes.c (diskfs_grow): Ditto. + * pager.c (pager_report_extent): Calculate the pager size. + * ufs.h (dev_read_sync, dev_write_sync, dev_write, diskpagersize): + Decls removed. + + * Makefile (SRCS): Remove devio.c. + * ufs.h (ufs_device, ufs_device_name): Variables removed. + * inode.c (diskfs_S_file_get_storage_info): Use DISKFS_DEVICE + instead of UFS_DEVICE, and DISKFS_DEVICE_NAME instead of + UFS_DEVICE_NAME. + +Sat Oct 7 20:47:56 1995 Miles Bader + + * main.c (diskfs_init_completed): Function deleted (now in libdiskfs). + (thread_cancel): Function deleted. + +Fri Oct 6 17:30:23 1995 Miles Bader + + * inode.c (diskfs_S_file_get_storage_info): Change type of + ADDRESSES to off_t **, and add the BLOCK_SIZE parameter. + +Wed Oct 4 17:21:33 1995 Miles Bader + + * inode.c (diskfs_set_statfs): fsys_stb_bsize -> fsys_stb_iosize. + fsys_stb_fsize -> fsys_stb_bsize. + + * main.c (parse_opt): Rearrange slightly. + +Tue Sep 26 11:54:35 1995 Michael I. Bushnell, p/BSG + + * inode.c: Include . + (diskfs_S_file_get_storage_info): New function. + * main.c (main): Delete var `devname'. Use `ufs_device_name' + throughout instead. + * ufs.h (ufs_device_name): New var. + +Fri Sep 22 13:22:42 1995 Roland McGrath + + * hyper.c (get_hypermetadata): Use %Zd format for result of sizeof. + +Tue Sep 19 13:41:46 1995 Miles Bader + + * Makefile (LDFLAGS): New variable. + +Wed Sep 13 12:30:23 1995 Michael I. Bushnell, p/BSG + + * dir.c (diskfs_lookup): Don't attempt to lock NP if NPP is not + set. Don't even set NP if NPP is not set; use INUM as "lookup + succeeded flag" instead. Lookups for REMOVE and RENAME now *must* + set NPP. + +Wed Sep 6 11:01:50 1995 Miles Bader + + * pager.c (diskfs_pager_users): Ignore the disk pager when seeing + if there are any active pagers. + +Mon Aug 28 17:07:36 1995 Roland McGrath + + * Makefile (ufs): Depend on ../libshouldbeinlibc/libshouldbeinlibc.a. + +Fri Aug 25 17:14:09 1995 Michael I. Bushnell, p/BSG + + * sizes.c (diskfs_truncate): When freeing direct blocks mentioned + in a single indirect block, or single indirect blocks mentioned in + a double, only call the free routine (ffs_blkfree or + indir_release, respectively) if the block is actually allocated. + +Wed Aug 23 12:24:07 1995 Miles Bader + + * Makefile (ufs): Add explicit dependencies. + (HURDLIBS, LDFLAGS, REMHDRS): Removed. + Rules associated with ../lib removed. + +Fri Jul 21 17:48:12 1995 Michael I Bushnell + + * pager.c (diskfs_get_filemap): Drop initial reference created by + pager_create. + + * pager.c (diskfs_get_filemap): Avoid race with simultaneous + termination by looping until we win. + (pager_clear_user_data): Only clear UPI->np->dn->fileinfo if it + still points to us. + +Mon Jul 17 14:35:25 1995 Michael I Bushnell + + * pager.c (thread_function): Don't have any global timeout here; + we don't use it anyhow. + +Thu Jul 6 15:42:52 1995 Michael I Bushnell + + * Makefile: Removed dependencies that are now automatically + generated. + +Mon Jun 26 20:17:42 1995 Michael I Bushnell + + * pager.c: Include . + (diskfs_pager_users): New function. + +Thu Jun 22 11:41:04 1995 Michael I Bushnell + + * pager.c (thread_function): Move thread_function to be non-local, + of course, because it needs to live even after create_disk_pager + returns. + + * main.c (thread_cancel): New function (HACK). + + * Makefile (HURDLIBS): Add libihash. + + * main.c (main): Have main thread exit when done instead of + calling a diskfs function. + +Wed Jun 21 12:20:01 1995 Michael I Bushnell + + * ufs.h (user_pager_info): Removed members next and prevp. + * pager.c (pager_clear_user_data): Don't maintain pager linked + list. + (diskfs_get_filemap): Don't maintain pager linked list. + (pager_dropweak): New function. + (pager_traverse): Delete function. + (diskfs_shutdown_pager): Use ports_bucket_iterate instead of + pager_traverse. + (diskfs_sync_everything): Likewise. + + * pager.c (pager_bucket): New variable. + (create_disk_pager): Provide pager_bucket in call to pager_create. + (diskfs_get_filemap): Likewise. + (diskfs_file_update): Use ports reference calls directly instead + of pager wrappers. + (drop_pager_softrefs): Likewise. + (allow_pager_softrefs): Likewise. + (pager_traverse): Likewise. + (create_disk_pager): Initialize pager_bucket here and fork off + service thread for pager ports. + + * sizes.c (diskfs_truncate): Likewise. + + * dir.c (diskfs_lookup): Provide initialization for BUFLEN. + (diskfs_direnter): Move assignment out of if test. + +Tue Jun 20 11:48:06 1995 Michael I Bushnell + + * sizes.c (diskfs_grow): Provide initialization of POKE_OFF. + * alloc.c (ffs_realloccg): Remove assignment from if tests. + * sizes.c (diskfs_truncate): Likewise. + * bmap.c (fetch_indir_spec): Likewise. + +Mon Jun 19 21:17:21 1995 Michael I Bushnell + + * inode.c (diskfs_node_iterate): New function. + (write_all_disknodes): Use it. + +Wed Jun 14 16:18:55 1995 Michael I Bushnell + + * inode.c (diskfs_get_translator): Conform to new memory usage + semantic. + +Sat May 20 00:17:30 1995 Miles Bader + + * main.c (trans_parse_args): Use options_parse & + diskfs_standard_startup_options to parse our translator options. + (usage): New function. + (parse_opt): New function. + + * Makefile (CPPFLAGS): Add -I../lib, to get include lib include files, + and $(CPPFLAGS-$(notdir $<)) to get file-specific cpp options. + Add a vpath for %.c to ../lib, so we can use source files from there. + +Mon May 15 13:14:48 1995 Michael I Bushnell + + * pager.c (pager_clear_user_data): Doc fix. + +Sat May 13 05:04:11 1995 Roland McGrath + + * Makefile (OBJS): Remove exec_server_image.o. + (exec_server_image.o): Rule removed. + +Mon May 8 08:43:43 1995 Miles Bader + + * dir.c (diskfs_lookup): When looping back to try_again: because + we're looking up "..", be sure and trash the mapping we made of + the directory's pager -- otherwise the reference to the pager + never gets dropped and we can never free the node. + + * dir.c (diskfs_lookup): ds->type was being compared to LOOKING, which + value it can never have. Compare ds->stat against LOOKING instead. + + * pager.c (pager_clear_user_data): Don't die when called on the + disk pager. + + * inode.c (write_all_disknodes): Fix typo `alloc' --> `alloca'. + +Tue May 2 11:59:09 1995 Michael I Bushnell + + * pager.c (pager_clear_user_data): Acquire pagerlistlock around + modifications to UPI->next/prevp list structure. + +Fri Apr 28 19:02:05 1995 Michael I Bushnell + + * inode.c (write_all_disknodes): We have to really lock the nodes + around the calls to diskfs_set_node_times and write_node; this in + turn forces us to have real refereces. + +Thu Apr 13 16:36:57 1995 Miles Bader + + * main.c (main): Don't abort if a std file descriptor is already open. + +Tue Apr 4 20:08:25 1995 Michael I Bushnell + + * inode.c (diskfs_set_translator): When freeing passive + translator, account for blocks freed in NP->dn_stat.st_blocks. + +Fri Mar 31 13:43:27 1995 Michael I Bushnell + + * sizes.c (diskfs_truncate): Don't acquire writer lock on + NP->dn->allocptrlock until after forcing delayed copies through; + otherwise the pageins will deadlock attempting to get a reader + lock to service them. This is safe, because we only need + NP->allocsize here, and that can't change as long as we hold + NP->lock. + +Mon Mar 20 13:58:44 1995 Michael I Bushnell + + * consts.c (diskfs_synchronous): New variable. + +Fri Mar 17 14:31:04 1995 Michael I Bushnell + + * alloc.c (ffs_clusteracct): Make static. + (alloc_sync): New function. + (ffs_alloc): Call alloc_sync. + (ffs_realloccg): Likewise. + (diskfs_alloc_node): Likewise. + (ffs_blkfree): Likewise. + (diskfs_free_node): Likewise. + +Sat Jan 28 14:59:26 1995 Roland McGrath + + * Makefile (OBJS): Remove reference to libc's devstream.o. + +Fri Nov 11 11:45:38 1994 Michael I Bushnell + + * hyper.c (diskfs_set_hypermetadata): Always use dev_write_sync to + avoid device_write bug that says you can't modify the buffer until + device_write returns. Also remember to deallocate BUF. + +Thu Nov 10 13:27:09 1994 Michael I Bushnell + + * main.c (main): Issue decent prompt. + + * hyper.c (diskfs_set_hypermetadata): Copy CSUM into a + page-aligned page-sized buffer for disk write to avoid inane + kernel bug. + +Wed Nov 9 05:43:14 1994 Michael I Bushnell + + * main.c (main): Behave more reasonably if we can't open DEVNAME. + +Tue Nov 8 00:03:20 1994 Roland McGrath + + * pager.c (pager_write_page): Use %p for printing PAGER. + + * ufs.h: Declare copy_sblock. + +Wed Nov 2 16:06:10 1994 Michael I Bushnell + + * hyper.c (copy_sblock): Don't copy csum here. + (diskfs_set_hypermetadata): Write csum directly to disk here. + +Thu Oct 27 20:58:08 1994 Michael I Bushnell + + * dir.c (diskfs_lookup): diskfs_get_filemap returns a send right, + so don't create an additional one here. + (diskfs_dirempty): Likewise. + * sizes.c (diskfs_truncate): Likewise. + (diskfs_grow): Likewise. + +Tue Oct 25 12:49:41 1994 Michael I Bushnell + + * hyper.c (copy_sblock): Call record_poke for csum and superblock + after modifying them. + + * pager.c (diskfs_shutdown_pager): Call copy_sblock. + (diskfs_sync_everything): Likewise. + + * alloc.c (ffs_fragextend): Call record_poke for CG after + modifying it. Also set CSUM_DIRTY and SBLOCK_DIRTY. + (ffs_alloccg): Likewise. + (ffs_alloccgblk): Likewise. + (ffs_nodealloccg): Likewise. + (ffs_blkfree): Likewise. + (diskfs_free_node): Likewise. + +Fri Oct 7 01:32:56 1994 Roland McGrath + + * main.c (diskfs_init_completed): Don't call _hurd_proc_init. + (saved_argv): Variable removed. + (main): Don't set saved_argv. Pass ARGV to diskfs_start_bootstrap. + +Wed Oct 5 22:18:46 1994 Michael I Bushnell + + * inode.c (read_disknode): If we are the bootstrap filesystem, + then getpid changes once proc starts up. So only call getpid + once, thus not allowing st_dev values to mysteriously change. + +Wed Oct 5 12:56:53 1994 Michael I Bushnell + + * alloc.c (diskfs_alloc_node): Abort if free inode has + translator attached. + +Tue Oct 4 18:33:35 1994 Michael I Bushnell + + * pager.c (pager_unlock_page): Call diskfs_catch_exception. + +Tue Oct 4 00:16:04 1994 Michael I Bushnell + + * inode.c (diskfs_lost_hardrefs): Comment out body. + * ufs.h (node2pagelock): New variable. + * pager.c (node2pagelock): Initialize. + (diskfs_get_filemap): Don't let node hold a reference to the pager. + (pager_clear_user_data): Acquire node2pagelock and clear + the node's reference to the pager. + (diskfs_file_update): Hold node2pagelock for reference + of NP->dn->fileinfo. + (drop_pager_softrefs): Likewise. + (allow_pager_softrefs): Likewise. + (diskfs_get_filemap): Likewise. + * sizes.c (diskfs_truncate): Likewise. + + * Makefile (SRCS): Added pokeloc.c. + +Mon Oct 3 15:03:38 1994 Michael I Bushnell + + * sizes.c (diskfs_truncate): Rewritten. + + * bmap.c (fetch_indir_spec): Initialize OFFSET values to -2, + meaning that the entry is not needed. If LBN is negative, + then don't set values for the data block. + + * inode.c (write_node): Call record_poke after writing + dinode. + (create_symlink_hook): Likewise. + (diskfs_set_translator): Likewise. + * pager.c (pager_unlock_page): Likewise. + * sizes.c (diskfs_truncate): Likewise. + * pager.c (pager_unlock_page): Call record_poke after writing + indirect block. + * sizes.c (diskfs_grow): Likewise. + (diskfs_grow): Likewise. + * pager.c (diskfs_sync_everything) [sync_one]: If this is the + disk pager, call sync_disk instead. + * pokeloc.c: New file. + +Fri Sep 30 11:25:36 1994 Michael I Bushnell + + * dir.h: Delete DT_* definitions; they are now in . + * dir.c (diskfs_get_directs): Set USERP->d_type as DT_UNKNOWN. + When the bugs in the type fields are fixed (dealing with + multiple links and mode changes) then this can actually return + the value. + +Thu Sep 29 17:16:58 1994 Roland McGrath + + * main.c (main): Test getpid()>0 to decide we are a normal + translator instead of the boot fs. Fetch bootstrap port after + possibly calling diskfs_parse_bootargs, not before. + +Tue Sep 27 15:24:58 1994 Michael I Bushnell + + * sizes.c (diskfs_grow) [computation of newallocsize]: Last block + number is one less than the total number of blocks. + +Tue Sep 27 11:58:44 1994 Michael I Bushnell + + * bmap.c (fetch_indir_spec): Single indirect block pointer is + in the INDIR_SINGLE slot, not the INDIR_DOUBLE slot. + +Mon Sep 26 20:47:30 1994 Michael I Bushnell + + * Makefile (SRCS): Added bmap.c. + + * main.c (main): Don't call pager_init. + + * inode.c (diskfs_get_translator): Repair to read translator + correctly. + + * sizes.c (diskfs_grow): Compute block numbers in a more clean + (and confidently correct) fashion. + (diskfs_truncate): Set NP->allocsize from a properly rounded + value. + +Mon Sep 26 12:50:38 1994 Michael I Bushnell + + * inode.c (diskfs_lost_hardrefs): "Know" that a pager starts + with a portinfo; we don't actually have access to the pager + struct here. + +Fri Sep 23 14:21:55 1994 Michael I Bushnell + + [ Continuing yesterday's changes. ] + * ufs.h (struct dirty_indir): New type. + (struct disknode): New member `dirty'. + * inode.c (iget): Initialize DN->dirty. + * bmap.c (mark_indir_dirty): New function. + * pager.c (pager_unlock_page): Call mark_indir_dirty before + writing into indirect blocks. + (diskfs_file_update): Sync indirect blocks here. + (pager_traverse): Simplify; do FILE_DATA and diskpager. + (pager_init): Removed function. + (create_disk_pager): New function. + * sizes.c: Completely rewritten. + * main.c (main): Spawn first thread sooner so we can + map and look at the disk image. + * hyper.c (get_hypermetadata): Moved firewall asserts + here from pager_init. + +Thu Sep 22 11:28:46 1994 Michael I Bushnell + + [This long series of changes deletes the DINODE, CG, SINDIR, + and DINDIR pagers and adds a new pager type DISK.] + * ufs.h (struct disknode) Removed DINLOCK, SINLOCK, and + SININFO members. New member ALLOCPTRLOCK renamed from DATALOCK. + Removed SINLOC, DINLOC, SINLOCLEN, and DINLOCLEN. + (struct user_pager_info) [enum pager_type]: Removed types + DINODE, CG, SINDIR and DINDIR; added type DISK. + (dinpager, dinodepager, cgpager): Deleted vars. + (diskpager): New var. + (dinmaplock, sinmaplock, pagernplock): Deleted vars. + (sblock_dirty, csum_dirty, cgs, dinodes): Deleted vars. + (fsaddr): New macro. + (dino, indir_block, cg_locate): New inline functions. + (sync_disk_blocks, sync_dinode): New inline functions. + (struct iblock_spec): New type. + * pager.c (dinport, dinodeport, cgport, sinlist): Deleted vars. + (filepagerlist): Renamed from filelist. + (pagernplock): Deleted variable. + (find_address): Removed switch; support only DISK and FILE_DATA. + (pager_report_extent): Likewise. + (pager_unlock_page): Removed switch. Return without comment for + DISK; allocate indirect blocks as necessary right here for + FILE_DATA. + (sin_map, sin_remap, sin_unmap, din_map, din_unmap): Deleted + functions. + (indir_alloc, sync_dinode): Deleted functions. + (enqueue_pager, dequeue_pager): Deleted functions. + (diskfs_file_update): No longer lock pagernplock; nothing + to do with sininfo. + (drop_pager_softrefs): Likewise. + (allow_pager_softrefs): Likewise. + (diskfs_get_filemap): Put pager on filepagerlist right here + instead of through pager_enqueue. + (pager_clear_user_data): Likewise, mutatis mutandis. + * main.c (main): Call create_disk_pager and then map the + entire disk into disk_image. + * hyper.c (get_hypermetadata): Use bcopy instead of dev_read_sync. + (diskfs_set_hypermetadata): NOP out function. + (copy_sblock): New function, substance of code is from old + diskfs_set_hypermetadata. + * inode.c (iget): Don't initialize deleted disknode fields. + (diskfs_node_norefs): Don't verify that deleted disknode + fields are not set. + (read_disknode): Get dinode from DINO, not DINODES array. + (write_node): Likewise. + (create_symlink_hook): Likewise. + (read_symlink_hook): Likewise. + (diskfs_set_translator): Likewise. + (diskfs_get_translator): Likewise. + (diskfs_node_translated): Likewise. + * alloc.c (ffs_realloccg): Likewise. + (ffs_fragextend): Use cg_locate instead of cgs array. + (ffs_alloccg): Likewise. + (ffs_nodealloccg): Likewise. + (ffs_blkfree): Likewise. + (diskfs_free_node): Likewise. + * inode.c (diskfs_set_translator): Use bcopy and sync_disk_blocks + instead of dev_write_sync. + (diskfs_get_translator): Likewise, mutatis mutandis. + (read_disknode): Initialize NP->istranslated. + (diskfs_set_translator): Set/clear NP->istranslated as appropriate. + (diskfs_node_translated): Removed function. + * bmap.c: New file. + + [This improves the RWLOCK mechanism and makes it more + orthogonal. It should probably be moved into a library.] + * ufs.h (struct rwlock): Added MASTER and WAKEUP members. + (struct disknode): Removed RWLOCK_MASTER and RWLOCK_WAKEUP + fields. + (rwlock_reader_lock): Ommitted arg DN; use new MASTER and WAKEUP + members inside LOCK instead. + (rwlock_writer_lock): Likewise. + (rwlock_reader_unlock): Likewise. + (rwlock_init): Initialize new MASTER and WAKEUP fields. + * inode.c (iget): Don't deal with RWLOCK_MASTER and RWLOCK_WAKEUP. + * pager.c (find_address): Deleted arg DNP. Only pass one + arg to rwlock functions. + (pager_read_page): Deleted var DN; only pass one arg to rwlock + functions. + (pager_write_page): Likewise. + +Wed Sep 21 00:26:25 1994 Michael I Bushnell + + * pager.c (allow_pager_softrefs): Unlock PAGERNPLOCK when + we're done with it. + (sin_map): Hold PAGERNPLOCK all the way until we're done + with the sininfo pointer. + (pagernplock): No longer static. + * ufs.h (pagernplock): Declare here. + + * sizes.c (diskfs_grow): Don't call diskfs_file_update here. + This was done to prevent too much dirty data from accumulating + and then overwhelming the pager later. But that's really the + pager's responsibility. + + * ufs.h (struct disknode): New members `dinloclen' and `sinloclen'. + * inode.c (iget): Initialize DN->dinloclen and DN->sinloclen. + (diskfs_node_norefs): Verify that DN->dinloclen and DN->sinloclen + are both zero. + * pager.c (find_address) [SINDIR]: Verify that reference is + within bounds of NP->dn->dinloc. + (pager_unlock_page) [SINDIR]: Likewise. + (din_map): Set NP->dn->dinloclen. + (din_unmap): Clear NP->dn->dinloclen. + (find_address) [FILE_DATA]: Verify that reference is within + bounds of NP->dn->sinloc. + (pager_unlock_page) [FILE_DATE]: Likewise. + (sin_map): Set NP->dn->sinloclen. + (sin_remap): Reset NP->dn->sinloclen. + (sin_unmap): Clean NP->dn->sinloclen. + + * pager.c (pager_write_page): Flush stdout after printf. + (pager_unlock_page) [FILE_DATA]: Likewise. + + * sizes.c (diskfs_truncate): In all references to sinloc and + dinloc arrays, verify that references are within allocated bounds. + (diskfs_grow): Likewise. + (sindir_drop): Likewise. + + * pager.c: Create new mapping with extent NEWSIZE, not SIZE (which + was the old size of the mapping). + +Tue Sep 20 15:51:35 1994 Michael I Bushnell + + * pager.c (pager_report_extent) [SINDIR]: Remove erroneous extra + division by block size. + (sin_remap): Likewise. + +Mon Sep 19 17:34:11 1994 Michael I Bushnell + + * inode.c (create_symlink_hook): Write assert test correctly. + + * dir.c (diskfs_direnter) [EXTEND]: Reference file size only + *once*; don't rely on the behavior if diskfs_grow vis a vis + file size. + +Fri Sep 16 10:29:42 1994 Michael I Bushnell + + * dir.c (dirscanblock): Compute offset correctly for mangled + entry notice. + + * dir.c (diskfs_direnter) [EXTEND]: Reference file size only + once before calling diskfs_grow in case diskfs_grow actually + increases the size. + + * inode.c (diskfs_set_statfs): Set fsid from getpid. + (read_disknode): Likewise. + + * dir.h (struct directory_entry): Renamed from struct direct. + * dir.c: All uses of struct direct changed to use + struct directory_entry. + (diskfs_get_directs): New var `userp'. Copy from *ENTRYP into + it (set at DATAP) more cleanly. + +Mon Sep 12 11:30:48 1994 Michael I Bushnell + + * hyper.c (diskfs_set_hypermetadata): Don't frob clean and dirty + bits if we are readonly. + +Sat Sep 10 11:41:06 1994 Roland McGrath + + * main.c (main): When started up as a passive translator, + open fds 0, 1, and 2 on /dev/console for debugging messages. + Call diskfs_init_diskfs with no args; after warp_root, call + diskfs_startup_diskfs on BOOTSTRAP. Compare BOOTSTRAP to + MACH_PORT_NULL instead of zero. + +Fri Sep 9 13:02:33 1994 Michael I Bushnell + + * main.c (trans_parse_args): Fix and enable. + +Tue Sep 6 11:29:55 1994 Michael I Bushnell + + * inode.c (iget): Remove old assert test that checked for bad + inode block allocations. + +Thu Sep 1 11:39:12 1994 Michael I Bushnell + + * tables.c: Don't include "ufs.h"; include . Then + this file can be used unmodified by fsck. + +Tue Aug 30 13:36:37 1994 Michael I Bushnell + + * inode.c (diskfs_set_translator): ffs_blkfree doesn't have + a return value. + +Mon Aug 29 12:49:17 1994 Michael I Bushnell + + * inode.c (diskfs_set_translator): If NAMELEN is zero, then + make the node have no translator. + +Fri Aug 26 12:28:20 1994 Michael I Bushnell + + * inode.c (read_disknode): 4.4 fsck sometimes sets the author + field to -1 to mean "ignore old uid location"; take that to mean + "author == uid". + (diskfs_set_translator): If we are allocating a new block for + the translator, then account for it in st_blocks. + +Thu Aug 18 12:41:12 1994 Michael I Bushnell + + * Makefile (HURDLIBS): Use short version. + + * alloc.c (diskfs_alloc_node): Bother to set *NPP before + returning. + +Tue Aug 16 10:48:04 1994 Michael I Bushnell + + * Makefile (LDFLAGS): New variable. + +Fri Aug 5 15:51:09 1994 Michael I Bushnell + + * dir.c (diskfs_direnter) [EXTEND]: Crash if the entry won't + fit in the new block. + (diskfs_lookup): Return ENAMETOOLONG if the name is bigger than + MAXNAMLEN. + + * dir.c (diskfs_get_directs): Set USERD->d_reclen correctly. + +Fri Jul 22 15:12:35 1994 Michael I Bushnell + + * Makefile: Rewritten in accord with new scheme. + +Wed Jul 20 13:28:38 1994 Michael I Bushnell + + * main.c (main): Don't set diskfs_dotdot_file. + +Tue Jul 19 21:51:54 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * ufs.h: Removed defns of u_quad_t, quad_t; now in . + Removed defn of struct timespec; now in . + +Tue Jul 19 12:47:31 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * main.c (main): Deleted var `diskfs_dotdot_file'. + (trans_parse_args): Don't set diskfs_dotdot_file; don't expect + dotdot from fsys_getroot. + + * Makefile (LDFLAGS): Moved to rule for `ufs' and commented out. + (ufs): Don't use variable $(link) anymore. + +Mon Jul 18 14:55:17 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * dir.c (diskfs_get_directs): Return data to user in old format. + Add new code for new format, maintaining compatibility correctly, + but comment it out until the library is ready. + + * hyper.c (diskfs_set_hypermetadata): If we presumed to + set new values of fs_maxfilesize, fs_qbmask, and fs_qfmask, + then restore the originals before writing out the superblock. + + * pager.c (diskfs_get_filemap): Test should be S_ISLNK, not + S_ISSOCK. + + * hyper.c (get_hypermetadata): Set new constants in filesystems + which don't have them yet. + (get_hypermetadata): Cast MAXSYMLINKLEN to long to avoid + converting sblock->fs_maxsymlinklen into an unsigned. + + * subr.c (scanc, skipc): New functions. + (ffs_setblock): Use assert instead of panic. + + * inode.c (read_disknode): Set old stat structure until the header + file gets changed. + +Fri Jul 15 12:07:15 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sizes.c: Include for bzero. + * fs.h (blksize): Comment out dblksize macro. In blksize + macro, use NP->allocsize instead of IP->i_size. + + * dinode.h (INDIR_SINGLE, INDIR_DOUBLE, INDIR_TRIPLE): New macros. + + * inode.c (read_disknode, write_node): Use new stat and dinode + fields for times. + + * ufs.h: Change `nextgennumber' to be `u_long' instead of int. + Change prototypes of some alloc.c functions. + * alloc.c (ffs_alloc): Declare to return error_t. + (ffs_realloccg): Likewise. + (ffs_hashalloc, ffs_alloccg, ffs_fragextend, ffs_alloccg, + ffs_dirpref, ffs_nodealloccg, ffs_allccgblk, ffs_mapsearch, + ffs_clusteracct): Provide forward declarations. + (ffs_realloccg): Use printf instead of log. + Make BPREF volatile for setjmp safety. + (diskfs_alloc_node): Use diskfs global variable instead of TIME. + (ffs_nodealloccg): Likewise. + (ffs_blkfree): Likewise. + (diskfs_free_node): Likewise. + (ffs_blkfree, ffs_clusteracct): Declare as void. + (ffs_alloccg, ffs_nodealloccg): Declare as u_long. + + * ufs.h: Change prototypes of some subr.c functions. + * subr.c (ffs_isblock): Use assert instead of panic. + (ffs_clrblock): Likewise. + + * hyper.c: Include "dinode.h". + + * dinode.h (LINK_MAX): New macro, from BSD sys/sys/syslimits.h. + * fs.h (MAXBSIZE, MAXFRAG): New macros, from BSD sys/sys/param.h. + + * hyper.c (get_hypermetadata): Provide first arg in call to + fsbtodb. + (diskfs_set_hypermetadata): Likewise. + * inode.c (diskfs_set_translator): Likewise. + (diskfs_get_translator): Likewise. + * pager.c (find_address): Likewise. + (indir_alloc): Likewise. + * inode.c (iget): Provide first arg in call to lblkno. + * sizes.c (diskfs_truncate): Likewise. + * pager.c (find_address): Likewise. + * sizes.c (diskfs_grow): Likewise. + * inode.c (iget): Provide first arg in call to fragroundup. + * sizes.c (diskfs_trucate): Likewise. + * sizes.c (diskfs_grow): Likewise. + * inode.c (iget): Provide first arg in call to blkroundup. + * pager.c (pager_unlock_page): Likewise. + * sizes.c (diskfs_truncate): Likewise. + * sizes.c (diskfs_grow): Likewise. + * pager.c (find_address): Provide first arg in call to cgtod. + * pager.c (find_address): Provide first arg in call to cgimin. + * pager.c (find_address): Provide first arg in call to blktofrags. + * pager.c (find_address): Provide first arg in call to blkoff. + * sizes.c (diskfs_truncate): Likewise. + * sizes.c (diskfs_grow): Likewise. + * sizes.c (diskfs_truncate): Provide first arg in call to blksize. + * sizes.c (diskfs_grow): Likewise. + * sizes.c (diskfs_truncate): Provide first arg in call to numfrags. + + * ufs.h: Added temporary declarations of `u_quad_t', `quad_t', and + `struct timespec'. + + * pager.c (diskfs_get_filemap): Make sure that this is + a kind of node that can be validly read. + + * inode.c (create_symlink_hook): Renamed from symlink_hook. + (read_symlink_hook): New function. + (diskfs_read_symlink_hook): Initialize. + +Thu Jul 14 12:23:45 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * alloc.c: New from 4.4 BSD; BSD version `8.8 2/21/94'. + Remove old includes; include "ufs.h", "fs.h", "dinode.h", + and . Replace panics with asserts and comment out + uprintfs. Use prototypes throughout. Replace calls + to ffs_fserr with printf. + (alloclock): New variable. + (ffs_alloc): Variable struct inode *IP is now struct node *NP; + refer to it appropriately. Initialize FS to sblock. + Lock alloclock around actual allocation steps. Reverse order + of BNP and CRED arguments; declare CRED as a protid and use + accordingly. Permit CRED to be null. + (ffs_realloccg): Variable struct inode *IP is now struct node *NP; + refer to it accordingly. Comment out U*x buffer management code. + Lock alloclock around actual allocation steps. Initialize FS + from sblock. Declare CRED as a protid and use it accordingly. + Change BUF arg to PBN (physical block number); return new block + there. + (ffs_reallocblks): Comment out. + (diskfs_alloc_node): Renamed from ialloc. Initialize FS from + sblock. Use calling sequence from . Acquire + alloclock aroud actual allocation steps. Deleted vars + `pip', `pvp' (use dir instead). Use iget instead of VFS_VGET. + Var struct inode *IP now struct node *NP. Lock gennumberlock + around frobbing of nextgennumber. + (ffs_blkpref): Arg struct inode *ip is now struct node *np; + refer to it accordingly. Initialize FS to sblock. Lock + alloclock during actual work. Use csum instead of fs_cs macro. + (ffs_hashalloc): Arg struct inode *IP is now struct node *NP; + use it accordingly. Initialize FS from sblock. + (ffs_fragextend): Arg struct inode *IP is now struct node *NP; + use it accordingly. Initialize FS from sblock. Initialize + CGP from cgs array; don't use bread. Comment out calls to brelse + and bdwrite. Set CGP->time from diskfs global var. Use csum + instead of fs_cs macro. + (ffs_alloccg): Arg struct inode *IP is now struct node *NP. + Initialize FS from sblock. Initialize CGP from cgs array; + don't use bread. Comment out calls to brelse and bdwrite. + Set CGP->time from diskfs global var. Use csum instead of + fs_cs macro. + (ffs_nodealloccg): Arg struct inode *IP is now struct node *NP. + Initialize FS from sblock. Initialize CGP from cgs array; + don't use bread. Comment out calls to brelse and bdwrite. Use + csum instead of fs_cs macro. + (ffs_blkfree): Arg struct inode *IP is now struct node *NP. + Initialize FS from sblock. Initialize CGP from cgs array; + don't use bread. Comment out calls to brelse and bdwrite. Use + csum instead of fs_cs macro. + (diskfs_free_node): Renamed from ffs_vfree. Use calling + sequence from . Initialize FS from sblock. + Deleted vars pip,pvp (use NP instead). Initialize CGP from + cgs array; don't use bread. Comment out calls to brelse and + bdwrite. Use csum instead of fs_cs macro. + (ffs_fserr): Commented out. + (ffs_dirpref): Use csum instead of fs_cs macro. + + * ufs.h (ffs_alloc): Renamed from alloc; all callers changed. + (ffs_blkfree): New arg NP; renamed from blkfree; all callers changed. + (ffs_blkpref): Renamed from blkpref; all callers changed. + (ffs_realloocg): Rename from realloccg; all callers changed. + + * fs.h: New from 4.4 BSD; BSD version `8.7 4/19/94'. + (fs_cs): Don't use fs_csp; use global csum instead. + + * subr.c: New from 4.4 BSD; BSD version `8.2 9/21/93'. + Remove old includes. Include "ufs.h" and "fs.h". + (ffs_blkatoff, ffs_checkoverlap): Comment out. + + * tables.c: New from 4.4 BSD; BSD version `8.1 6/11/93'. + Don't include ; do include "ufs.h" and "fs.h". + + * dinode.h: New from 4.4 BSD; BSD version `8.3 1/21/94'. + Remove oldids/inum union; replace with author. + Renamed di_mode to be di_model; allocated di_modeh from spare. + Allocate di_trans from spare. + (di_inumber): Remove macro. + * inode.c (read_disknode): Fetch uid and gid from new (long) + fields in dinode unless we are the old inode format, in which + case fetch them from the old fields. + (write_node): Only set new uid and gid fields if we are not + COMPAT_BSD4. Set old fields if the superblock says to. + (symlink_hook): New function. + (diskfs_create_symlink_hook): Initialize. + * sizes.c (diskfs_truncate): Deal with truncation of short + symlink properly. + + * dir.h: New from 4.4 BSD; BSD version `8.2 1/21/94'. + Substitute our version of DIRSIZ which uses the namelen. + Comment out declarations of struct dirtemplate and struct + odirtemplate. + (DIRECT_TYPE, DIRECT_NAMLEN): New macros. + * ufs.h (direct_symlink_extension): New variable. + * hyper.c (get_hypermetadata): Set direct_symlink_extension. + * dir.c (dirscanblock): Use DIRECT_NAMLEN instead of d_namlen. + (diskfs_direnter): Likewise. + (diskfs_dirempty): Likewise. + (diskfs_get_directs): Likewise. + (diskfs_direnter): Set d_type field of new slot if + direct_symlink_extension is set. + (diskfs_dirrewrite): Likewise. + + * ufs.h (compat_mode): New variable. + * main.c (main): Set compat_mode to zero if we are the bootstrap + filesystem. + * inode.c (diskfs_set_translator): Return error if compat_mode + is set. + (write_node): Don't set GNU dinode field extensions unless + compat_mode is COMPAT_GNU. + +Mon Jul 11 18:14:26 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * dir.c (diskfs_get_directs): When copying entries into DATAP, + set the d_reclen parameter of the copy to the minimum length + (because that's all we use) rather than the size that it had + in the directory itself. + +Wed Jul 6 14:41:48 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * dir.c (dirscanblock): In main loop, initialize PREVOFF + to zero, not BLOCKADDR. Otherwise, the wrong value is + stored into DS->prevoff and then diskfs_dirremove crashes. + +Tue Jul 5 14:07:38 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * dinode.h: Include before test of BYTE_ORDER. + + * Makefile (TAGSLIBS): New variable. + +Tue Jun 21 13:45:04 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * dir.c (diskfs_direnter): Update dirents of DP, not NP. + +Mon Jun 20 16:43:48 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * dir.c (diskfs_direnter) [case SHRINK]: NEW should be set to + OLDNEEDED past DS->entry, not to the start of the next entry. + + * dir.c (diskfs_direnter) [case EXTEND]: Cast in assignment + to NEW needs proper scope. + + * inode.c (diskfs_node_norefs): Free dirents list of structure + being deallocated. Also add assert checks to make sure other + state is already clean. + +Thu Jun 16 11:38:17 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * dir.c (diskfs_dirempty): Map directory contents ourselves + instead of using diskfs_node_rdwr. + (struct dirstat): New structure to cache mapping between + lookup and commit operation and avoid use of diskfs_node_rdwr. + (diskfs_lookup): Map directory ourselves. Keep mapping in + DS if DS is nonzero and we might use it in direnter, dirremove, + or dirrewrite. Deallocate mapped buffer if we return some + error (other than ENOENT), or if DS is zero, or if there is + no possible commit operation to follow. When setting DS->stat + to EXTEND, do it the new way. + (dirscanblock): Changed BLKOFF to be virtual address of mapped + block and renamed it BLKADDR. New arg IDX. Use mapped block + instead of calling diskfs_node_rdwr. Set DS according to the new + rules. + (diskfs_direnter): Interpret new dirstat format. + (diskfs_dirremove): Likewise. + (diskfs_dirrewrite): Likewise. + (diskfs_drop_dirstat): Deallocate cached mapping here. + + * dir.c (dirscanblock): When we find the node for type CREATE, + invalidate DS by setting type to LOOKUP, not LOOKING. + + * dir.c (diskfs_direnter, diskfs_dirremove, diskfs_dirrewrite): + Call diskfs_notice_dirchange when appropriate. + + * dir.c (diskfs_get_directs): Deal properly with case where + BUFSIZ==0 and where NENTRIES==-1. + +Wed Jun 15 16:40:12 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * main.c (main): Check device sector size and media size + on startup. + +Tue Jun 14 14:41:17 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * ufs.h (struct disknode) [dirents]: New member. + * inode.c (iget): Initialize DN->dirents. + * dir.c (diskfs_direnter, diskfs_dirremove): Keep track + of dirents member. + (dirscanblock): New var `nentries'; use it to count the + number of directory entries in this block and set it if + we end up scanning the entire block. + (count_dirents): New function. + (diskfs_get_directs): New function. + +Mon Jun 13 13:50:00 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * ufs.h (sinmaplock, dinmaplock): New global vars. + * inode.c (inode_init): Initialize sinmaplock and dinmaplock. + * pager.c (find_address, pager_unlock_page): Protect use + if dinloc array with dinmaplock. + (din_map, din_unmap): Doc fix. + (find_address, pager_unlock_page): Protect use of sinloc array + with sinmaplock. + (sin_map, sin_remap, sin_unmap): Doc fix. + (pager_clear_user_data): Acquire sinmaplock and dinmaplock + instead of NP->dn->datalock and NP->dn->sinlock respectively. + + * sizes.c (diskfs_truncate, diskfs_grow): Protect use of sinloc + and sindir mapping functions with sinmaplock. + (sindir_drop): Protect use of dinloc and dindir mapping functions + with dinmaplock. + + * ufs.h (struct rwlock): New type. + (struct disknode) [dinlock, sinlock, datalock]: Use read-write lock. + Change comments so that these don't lock dinloc and sinloc anymore. + [rwlock_master, rwlock_wakeup]: New members. + (rwlock_reader_lock, rwlock_writer_lock, rwlock_reader_unlock, + rwlock_writer_unlock, rwlock_init): New functions. + * inode.c (iget): Initialize DN->rwlock_master and + DN->rwlock_wakeup. Change initialization of DN->dinlock, + DN->sinlock, and DN->datalock to use rwlock_init. + * pager.c (find_address): Lock NP->dn->dinlock, NP->dn->sinlock, + and NP->dn->datalock with rwlock_reader_lock. Change type of + parameter NPLOCK to be a read-write lock. New parm DNP. Callers + changed. + (pager_read_page, pager_write_page): Change type of NPLOCK to be + read-write lock; call rwlock_reader_unlock instead of + mutex_unlock. New variable DN. + (pager_unlock_page): Use rwlock_writer_lock to lock + NP->dn->dinlock, NP->dn->sinlock, and NP->dn->datalock. + * sizes.c (diskfs_truncate, diskfs_grow): Change locks of DATALOCK + field to use rwlock_writer_{un,}lock. + (sindir_drop): Ditto for SINLOCK field. + (dindir_drop): Ditto for DINLOCK field. + +Mon Jun 6 19:23:26 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sizes.c (diskfs_grow): After realloccg, zero new data (which I'm + not sure is really necessary, but until I figure it out, this is + safest). Also poke old data (the latter only if the block has + moved)--otherwise the kernel won't know to page it out to the new + location. + (poke_pages): When poking, be careful not to actually change the data. + LEN should be end - start, not start - end. + +Fri Jun 3 12:37:27 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * inode.c (iget): When we find the node in the table, acquire the + mutex *after* incrementing NP->references and unlocking + diskfs_node_refcnt_lock; otherwise we can deadlock against + diskfs_nput. + +Thu Jun 2 12:16:09 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * ufs.h (sblock_dirty, csum_dirty, alloclock): New global variables. + * alloc.c (alloclock): Remove static keyword.. + * alloc.c (realloccg): Set sblock_dirty after changing sblock. + (blkpref): Likewise. + (fragextend): Likewise. + (alloccg): Likewise. + (alloccgblk): Likewise. + (ialloccg): Likewise. + (blkfree): Likewise. + (diskfs_free_node): Likewise. + * hyper.c (diskfs_set_hypermetadata): Likewise. + * alloc.c (fragextend): Set csum_dirty after changi csum. + (alloccg): Likewise. + (alloccgblk): Likewise. + (ialloccg): Likewise. + (blkfree): Likewise. + (diskfs_free_node): Likewise. + * hyper.c (diskfs_set_hypermetadata): Acquire alloclock while + writing hypermetadata. Only write csum and sblock if + csum_dirty or sblock_dirty, respectively, is set, and then + clear it after starting the write. + + * main.c (main): Likewise. + + * sizes.c (diskfs_truncate): Don't turn off caching; the new + light reference system takes care of this. + * pager.c (diskfs_get_filemap): No longer necessary to turn + on caching here, because truncate no longer turns it off. + + * inode.c (diskfs_lost_hardrefs, diskfs_new_hardrefs): New functions. + * pager.c (drop_pager_softrefs, allow_pager_softrefs): New functions. + (sin_map): Use diskfs_nref_light, not diskfs_nref. + (diskfs_get_filemap): Use diskfs_nref_light, not diskfs_nref. + (pager_clear_user_data): Use diskfs_nrele_light, not diskfs_nrele. + * ufs.h (drop_pager_softrefs, allow_pager_softrefs): New + declarations. + +Wed Jun 1 13:35:11 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sizes.c (diskfs_truncate): After calling sin_unmap, turn + off caching on the sininfo pager so that it gets freed promptly + (there's generally no value in keeping it around because there + is no live fileinfo pager). + * pager.c (diskfs_get_filemap): Make sure we turn caching back on + here, however, if we start using the file pager. + + * pager.c (sin_map): When np->dn->sininfo is set, we have + to insert a valid send right after fetching the receive name. + + * pager.c (sin_unmap, din_unmap): New functions. + (pager_clear_user_data): Call sin_unmap and din_unmap + instead of doing it right here. + + * sizes.c (diskfs_truncate): Call sin_unmap instead of + doing it right here. + (sindir_drop): Call din_unmap instead of doing it right + here. Also, call it always, not just when wo do dindir_drop. + + * sizes.c (diskfs_grow): After alloc into sindir area, + unmap it if we don't have an active data pager. + * ufs.h (sin_unmap, din_unmap): New declarations. + + * sizes.c (diskfs_grow): In computing OSIZE in the realloc + case of lbn < NDADDR, deal correctly with the case where + np->allocsize is already an integral number of blocks. + + * sizes.c (diskfs_grow): Compute SIZE correctly. + + * alloc.c (alloc, realloccg, blkfree): When checking validity + of size arguments, also make sure the size isn't zero. + + * alloc.c (diskfs_alloc_node): Lock ALLOCLOCK before checking + sblock->fs_cstotal.cs_nifree. + +Tue May 31 18:47:42 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) + + * ufs.h (DONT_CACHE_MEMORY_OBJECTS): Define it. + + * dir.c (diskfs_direnter: case TAKE): Assert that OLD->d_reclen >= + NEEDED, not that it is strictly >. + +Tue May 31 11:10:28 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sizes.c (diskfs_grow): Call diskfs_node_update (but don't wait) + after successful completion to prevent old data from hanging around + too long and getting flushed all at once from the kernel. + + * sizes.c (diskfs_grow): Change SIZE to be the size of the last + block allocated. Delete variable NSIZE; use SIZE instead. + +Fri May 27 13:15:26 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sizes.c (diskfs_truncate): Set NP->dn_stat_dirty after each + modification of NP->dn_stat. + + * sizes.c (diskfs_truncate): Compute new value of NP->allocsize + correctly. + + * inode.c (iget): Set NP->allocsize to be the *actual* allocsize. + +Thu May 26 11:51:45 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * sizes.c (diskfs_truncate): In blkfree loop of blocks past + NDADDR, subtract NDADDR from idx to index correctly into + sinloc array. Start this loop with idx not less than NDADDR. + (diskfs_truncate): If olastblock == NDADDR, then we also + need to truncate blocks (one) mapped by single indirect blocks. + (diskfs_truncate): New variable `first2free'. Use in place + of older losing calculations involving lastblock. + (sindir_drop): Rename parameters to be FIRST and LAST. Change + interpretation of FIRST by one to correspond with changed call + in diskfs_truncate. + + * pager.c (sin_remap): When computing NEWSIZE, round up to + a page boundary, thus mimicing the SINDIR computation in + pager_report_extent properly. + + * pager.c (pager_unlock_page) [case SINDIR; vblkno == 0]: Read + from ....di_ib[INDIR_SINGLE] rather than invalid data before + NP->dn->dinloc. + + * alloc.c (alloc) [nospace]: Unlock alloclock. + (realloccg): Unlock alloclock before jumping to nospace. + (blkpref) [!(lbn < NDADDR)]: Unlock alloclock before returning + success. + + * sizes.c (diskfs_grow): When allocing a block past NDADDR, the + tbl arg to blkpref is the table of direct block pointers + NP->dn->sinloc, not the table of indirect block pointers + ...->di_ib. + + * sizes.c (diskfs_grow): When writing into the SINDIR area, call + sin_map instead of sin_remap if the sindir isn't already mapped. + Also set np->allocsize *before* calling sin_map, but *after* + calling sin_remap, to meet the requirements of those separate + routines. + + * sizes.c (diskfs_grow): If END isn't bigger than NP->allocsize, + then don't try and do anything. In computation of LBN and the + first use of NB, round up to block boundary correctly. Don't + attempt to realloc an old block if the size is 0 (in which case + NB is -1 and unsigned comparison rules might foul things up). + +Mon May 23 13:18:33 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * Makefile (ufs): Give -n in the proper order to rsh. + + * main.c: Include . + + * ufs.h (DONT_CACHE_MEMORY_OBJECTS): New compilation flag. + * pager.c (pager_report_attributes): Deleted function. + (MAY_CACHE): New macro; more useful form for using + DONT_CACHE_MEMORY_OBJECTS. + (sin_map, pager_init, diskfs_get_filemap): Provide new + args in calls to pager_create. + * sizes.c (MAY_CACHE): New macro; more useful form for + using DONT_CACHE_MEMORY_OBJECTS. + (diskfs_truncate): Use MAY_CACHE in calls to pager_change_attributes. + +Fri May 20 18:52:41 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * sizes.c (diskfs_truncate): Force any delayed copies of the + vanishing region to be taken immediately before stopping, and + prevent any new delayed copies from being made until we are done + manipulating things. + (poke_pages): New function. + * pager.c (pager_report_attributes): New function. + +Wed May 18 15:51:40 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * alloc.c (alloc, realloccg, diskfs_alloc_node, alloccgblk, + blkfree, diskfs_free_node, mapsearch): Added helpful strings to + asserts. + (realloccg): Split up assert. + +Tue May 17 13:26:22 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * main.c (main): Delete unused variable PROC. + +Mon May 16 15:32:07 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) + + * alloc.c (realloccg): When fragextend succeeds, bother to set + *PBN. + + * sizes.c (diskfs_grow): In fragment growth case, NSIZE should + not be the amount to hold SIZE (SIZE is the amount the file is + growing by), but rather the old size of the fragment plus the + SIZE. + + * dir.c (diskfs_direnter case COMPRESS): Rewrite loop to deal + properly with the case where from and to overlap. + +Mon May 9 16:51:44 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * main.c (ufs_version): New variable. + (save_argv): New variable. + (main): Set save_argv. + (diskfs_init_completed): New function. + +Thu May 5 19:06:54 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * Makefile (exec_server_image.o): Use -n when calling rsh. + +Thu May 5 07:39:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) + + * Makefile ($(OBJS)): Use $(includedir) instead of $(headers) in deps. + -- cgit v1.2.3 From a904d903276ac928bd18f33a3fbef1fbb372ac63 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Tue, 23 Jul 1996 20:07:04 +0000 Subject: . --- ufs/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 368a2f59..2ccd6c11 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +Tue Jul 23 15:58:28 1996 Miles Bader + + * inode.c (write_node, read_disknode): `struct timespec' now uses + a field prefix of `tv_'. + Sat Jul 6 16:14:10 1996 Miles Bader * main.c (ufs_version): Variable removed. -- cgit v1.2.3 From dd7ab33b151f5f710e4a8d41a35a73fb0a771a07 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Tue, 23 Jul 1996 20:08:16 +0000 Subject: (write_node, read_disknode): `struct timespec' now uses a field prefix of `tv_'. --- ufs/inode.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index aa2f3a8c..640e6b6f 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -240,12 +240,12 @@ read_disknode (struct node *np) st->st_mtimespec = di->di_mtime; st->st_ctimespec = di->di_ctime; #else - st->st_atime = read_disk_entry (di->di_atime.ts_sec); - st->st_atime_usec = read_disk_entry (di->di_atime.ts_nsec) / 1000; - st->st_mtime = read_disk_entry (di->di_mtime.ts_sec); - st->st_mtime_usec = read_disk_entry (di->di_mtime.ts_nsec) / 1000; - st->st_ctime = read_disk_entry (di->di_ctime.ts_sec); - st->st_ctime_usec = read_disk_entry (di->di_ctime.ts_nsec) / 1000; + st->st_atime = read_disk_entry (di->di_atime.tv_sec); + st->st_atime_usec = read_disk_entry (di->di_atime.tv_nsec) / 1000; + st->st_mtime = read_disk_entry (di->di_mtime.tv_sec); + st->st_mtime_usec = read_disk_entry (di->di_mtime.tv_nsec) / 1000; + st->st_ctime = read_disk_entry (di->di_ctime.tv_sec); + st->st_ctime_usec = read_disk_entry (di->di_ctime.tv_nsec) / 1000; #endif st->st_blksize = sblock->fs_bsize; st->st_blocks = read_disk_entry (di->di_blocks); @@ -353,12 +353,12 @@ write_node (struct node *np) di->di_mtime = st->st_mtimespec; di->di_ctime = st->st_ctimespec; #else - write_disk_entry (di->di_atime.ts_sec, st->st_atime); - write_disk_entry (di->di_atime.ts_nsec, st->st_atime_usec * 1000); - write_disk_entry (di->di_mtime.ts_sec, st->st_mtime); - write_disk_entry (di->di_mtime.ts_nsec, st->st_mtime_usec * 1000); - write_disk_entry (di->di_ctime.ts_sec, st->st_ctime); - write_disk_entry (di->di_ctime.ts_nsec, st->st_ctime_usec * 1000); + write_disk_entry (di->di_atime.tv_sec, st->st_atime); + write_disk_entry (di->di_atime.tv_nsec, st->st_atime_usec * 1000); + write_disk_entry (di->di_mtime.tv_sec, st->st_mtime); + write_disk_entry (di->di_mtime.tv_nsec, st->st_mtime_usec * 1000); + write_disk_entry (di->di_ctime.tv_sec, st->st_ctime); + write_disk_entry (di->di_ctime.tv_nsec, st->st_ctime_usec * 1000); #endif write_disk_entry (di->di_blocks, st->st_blocks); write_disk_entry (di->di_flags, st->st_flags); -- cgit v1.2.3 From 23f405001b6d3dff8607115c5d731126c54f4b9e Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Wed, 7 Aug 1996 19:03:53 +0000 Subject: *** empty log message *** --- ufs/ChangeLog | 13 +++++++ ufs/inode.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 2ccd6c11..c541523e 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,16 @@ +Wed Aug 7 13:00:30 1996 Thomas Bushnell, n/BSG + + * inode.c (struct ufs_fhandle): Layout filehandle more like Unixy + NFSD. + (diskfs_S_file_getfh): Bother to clear unused parts of a + file handle so that they always compare equal. + +Tue Aug 6 12:19:38 1996 Thomas Bushnell, n/BSG + + * inode.c: Include . + (struct ufs_fhandle): New type. + (diskfs_S_fsys_getfile, diskfs_S_file_getfh): New functions. + Tue Jul 23 15:58:28 1996 Miles Bader * inode.c (write_node, read_disknode): `struct timespec' now uses diff --git a/ufs/inode.c b/ufs/inode.c index 640e6b6f..27f7c3bb 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -20,6 +20,7 @@ #include #include #include +#include #define INOHSZ 512 #if ((INOHSZ&(INOHSZ-1)) == 0) @@ -723,4 +724,125 @@ diskfs_S_file_get_storage_info (struct protid *cred, return 0; } +/* Must be exactly 28 bytes long */ +struct ufs_fhandle +{ + int filler1; + ino_t inum; + long gen; + int filler2[4]; +}; + +/* Return an NFS file handle */ + +error_t +diskfs_S_file_getfh (struct protid *cred, + char **fh, + u_int *fh_len) +{ + struct node *np; + error_t err; + struct ufs_fhandle *f; + + if (!cred) + return EOPNOTSUPP; + + if (!diskfs_isuid (0, cred)) + return EPERM; + + np = cred->po->np; + + mutex_lock (&np->lock); + + if (*fh_len < sizeof (struct ufs_fhandle)) + vm_allocate (mach_task_self (), (vm_address_t *) fh, + sizeof (struct ufs_fhandle), 1); + *fh_len = sizeof (struct ufs_fhandle); + + f = (struct ufs_fhandle *) *fh; + f->inum = np->dn->number; + f->gen = np->dn_stat.st_gen; + f->filler1 = 0; + f->filler2[0] = f->filler2[1] = f->filler2[2] = f->filler2[3] = 0; + mutex_unlock (&np->lock); + return 0; +} + +/* Lookup an NFS file handle */ +error_t +diskfs_S_fsys_getfile (mach_port_t fsys, + mach_port_t reply, + mach_msg_type_name_t replytype, + uid_t *uids, + u_int nuids, + uid_t *gids, + u_int ngids, + char *handle, + u_int handlelen, + mach_port_t *file, + mach_msg_type_name_t *filetype) +{ + struct port_info *pt = ports_lookup_port (diskfs_port_bucket, fsys, + diskfs_control_class); + struct node *np; + struct ufs_fhandle *f; + error_t err; + int flags; + struct protid fakecred, *newpi; + + if (!pt) + return EOPNOTSUPP; + + if (handlelen != sizeof (struct ufs_fhandle)) + { + ports_port_deref (pt); + return EINVAL; + } + + f = (struct ufs_fhandle *) handle; + + err = diskfs_cached_lookup (f->inum, &np); + if (err) + { + ports_port_deref (pt); + return err; + } + + if (np->dn_stat.st_gen != f->gen) + { + diskfs_nput (np); + ports_port_deref (pt); + return ESTALE; + } + + /* This call should have a flags arg, but until then... */ + fakecred.uids = uids; + fakecred.gids = gids; + fakecred.nuids = nuids; + fakecred.ngids = ngids; + + flags = 0; + if (!diskfs_access (np, S_IREAD, &fakecred)) + flags |= O_READ; + if (!diskfs_access (np, S_IEXEC, &fakecred)) + flags |= O_EXEC; + if (!diskfs_access (np, S_IWRITE, &fakecred) + && !S_ISDIR (np->dn_stat.st_mode) + && !diskfs_check_readonly ()) + flags |= O_WRITE; + + err = diskfs_create_protid (diskfs_make_peropen (np, flags, MACH_PORT_NULL), + uids, nuids, gids, ngids, &newpi); + + diskfs_nput (np); + ports_port_deref (pt); + + if (!err) + { + *file = ports_get_right (newpi); + *filetype = MACH_MSG_TYPE_MAKE_SEND; + } + return err; +} + -- cgit v1.2.3 From 9bcf73b12b79ee9c321a27338677942f6faa05d5 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Mon, 12 Aug 1996 18:31:04 +0000 Subject: *** empty log message *** --- ufs-fsck/ChangeLog | 4 ++++ ufs-fsck/Makefile | 2 +- ufs/ChangeLog | 11 +++++++++ ufs/devio.c | 70 ------------------------------------------------------ ufs/hyper.c | 25 ++++++++++++------- ufs/inode.c | 4 ++-- 6 files changed, 34 insertions(+), 82 deletions(-) delete mode 100644 ufs/devio.c (limited to 'ufs') diff --git a/ufs-fsck/ChangeLog b/ufs-fsck/ChangeLog index 8fcde4b2..615e6458 100644 --- a/ufs-fsck/ChangeLog +++ b/ufs-fsck/ChangeLog @@ -1,3 +1,7 @@ +Mon Aug 12 11:39:12 1996 Thomas Bushnell, n/BSG + + * Makefile (dir): Now ufs-fsck. + Tue Jul 23 19:32:09 1996 Miles Bader * inode.c (allocino): `struct timespec' now uses a field prefix diff --git a/ufs-fsck/Makefile b/ufs-fsck/Makefile index f68fe52a..8725de8e 100644 --- a/ufs-fsck/Makefile +++ b/ufs-fsck/Makefile @@ -18,7 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -dir := fsck +dir := ufs-fsck makemode := utility SRCS = dir.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \ diff --git a/ufs/ChangeLog b/ufs/ChangeLog index c541523e..2b964cf9 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,5 +1,16 @@ +Mon Aug 12 13:43:46 1996 Thomas Bushnell, n/BSG + + * hyper.c (diskfs_set_hypermetadata): Bother to return 0 at end of + function. + Wed Aug 7 13:00:30 1996 Thomas Bushnell, n/BSG + * inode.c (diskfs_set_statfs): Compute st->f_blocks correctly; set + bsize to be fs_fsize, not fs_bsize. + + * hyper.c (diskfs_set_hypermetadata): Return an error as + appropriate. + * inode.c (struct ufs_fhandle): Layout filehandle more like Unixy NFSD. (diskfs_S_file_getfh): Bother to clear unused parts of a diff --git a/ufs/devio.c b/ufs/devio.c deleted file mode 100644 index 2e5cc332..00000000 --- a/ufs/devio.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Device input and output - Copyright (C) 1992, 1993, 1994 Free Software Foundation - -This file is part of the GNU Hurd. - -The GNU Hurd is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -The GNU Hurd is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with the GNU Hurd; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Written by Michael I. Bushnell. */ - -#include "ufs.h" -#include -#include - -/* Write disk block ADDR with DATA of LEN bytes, waiting for completion. */ -error_t -dev_write_sync (daddr_t addr, - vm_address_t data, - long len) -{ - int foo; - assert (!diskfs_readonly); - if (device_write (ufs_device, 0, addr, (io_buf_ptr_t) data, len, &foo) - || foo != len) - return EIO; - return 0; -} - -/* Write diskblock ADDR with DATA of LEN bytes; don't bother waiting - for completion. */ -error_t -dev_write (daddr_t addr, - vm_address_t data, - long len) -{ - assert (!diskfs_readonly); - if (device_write_request (ufs_device, MACH_PORT_NULL, 0, addr, - (io_buf_ptr_t) data, len)) - return EIO; - return 0; -} - -static int deverr; - -/* Read disk block ADDR; put the address of the data in DATA; read LEN - bytes. Always *DATA should be a full page no matter what. */ -error_t -dev_read_sync (daddr_t addr, - vm_address_t *data, - long len) -{ - int foo; - deverr = device_read (ufs_device, 0, addr, len, (io_buf_ptr_t *)data, - (u_int *)&foo); - if (deverr || foo != len) - return EIO; - return 0; -} - diff --git a/ufs/hyper.c b/ufs/hyper.c index e4f58249..cb644797 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -276,7 +276,7 @@ get_hypermetadata (void) taken from ordinary data blocks and might not be an even number of pages; in that case writing it through the pager would nuke whatever pages came after it on the disk and were backed by file pagers. */ -void +error_t diskfs_set_hypermetadata (int wait, int clean) { vm_address_t buf; @@ -294,16 +294,22 @@ diskfs_set_hypermetadata (int wait, int clean) err = diskfs_device_read_sync (fsbtodb (sblock, sblock->fs_csaddr), &buf, bufsize); - if (!err) + if (err) + return err; + + bcopy (csum, (void *) buf, sblock->fs_cssize); + if (swab_disk) + swab_csums ((struct csum *)buf); + err = diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr), + buf, bufsize); + vm_deallocate (mach_task_self (), buf, bufsize); + + if (err) { - bcopy (csum, (void *) buf, sblock->fs_cssize); - if (swab_disk) - swab_csums ((struct csum *)buf); - diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr), - buf, bufsize); - csum_dirty = 0; - vm_deallocate (mach_task_self (), buf, bufsize); + spin_unlock (&alloclock); + return err; } + csum_dirty = 0; } if (clean && ufs_clean && !sblock->fs_clean) @@ -326,6 +332,7 @@ diskfs_set_hypermetadata (int wait, int clean) copy_sblock (); sync_disk (wait); + return 0; } /* Copy the sblock into the disk */ diff --git a/ufs/inode.c b/ufs/inode.c index 27f7c3bb..ae323a8c 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -498,8 +498,8 @@ error_t diskfs_set_statfs (struct statfs *st) { st->f_type = FSTYPE_UFS; - st->f_bsize = sblock->fs_bsize; - st->f_blocks = sblock->fs_dsize * sblock->fs_frag; + st->f_bsize = sblock->fs_fsize; + st->f_blocks = sblock->fs_dsize; st->f_bfree = (sblock->fs_cstotal.cs_nbfree * sblock->fs_frag + sblock->fs_cstotal.cs_nffree); st->f_bavail = ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100) -- cgit v1.2.3 From 2729a2406f00c668611d0151b142d97d3607e599 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Thu, 29 Aug 1996 20:14:18 +0000 Subject: *** empty log message *** --- ufs/ChangeLog | 21 +++++++++++++++++++++ ufs/dir.c | 53 +++++++++++++++++++++++++++++++++++++++++------------ ufs/inode.c | 1 + ufs/ufs.h | 2 ++ 4 files changed, 65 insertions(+), 12 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 2b964cf9..934c9856 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,24 @@ +Thu Aug 29 16:07:07 1996 Thomas Bushnell, n/BSG + + * dir.c (diskfs_lookup_hard): When setting ds->stat to EXTEND, set + ds->idx by looking at the size of the file. (IDX itself is no + longer at the end because of the change on Aug 16 1996.) + +Wed Aug 28 12:15:15 1996 Thomas Bushnell, n/BSG + + * dir.c (dirscanblock): Size dirents correctly when mallocing it. + (diskfs_direnter_hard): Be more careful when sizing or resizing + dirents. Correctly set to -1 all the new entries we create after + realloc call. + +Fri Aug 16 18:51:31 1996 Thomas Bushnell, n/BSG + + * ufs.h (struct disknode): New member `dir_idx'. + * inode.c (diskfs_cached_lookup): Initialize DN->dir_idx. + * dir.c (diskfs_lookup_hard): After successful dirscanblock, + record index where we finished in DP->dn->dir_idx. Start searches + at that index. + Mon Aug 12 13:43:46 1996 Thomas Bushnell, n/BSG * hyper.c (diskfs_set_hypermetadata): Bother to return 0 at end of diff --git a/ufs/dir.c b/ufs/dir.c index d015a6c6..397481d0 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -111,7 +111,8 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, vm_address_t buf = 0; vm_size_t buflen = 0; int blockaddr; - int idx; + int idx, lastidx; + int looped; if ((type == REMOVE) || (type == RENAME)) assert (npp); @@ -156,18 +157,39 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; - for (blockaddr = buf, idx = 0; - blockaddr - buf < dp->dn_stat.st_size; - blockaddr += DIRBLKSIZ, idx++) + /* Start the lookup at DP->dn->dir_idx. */ + idx = dp->dn->dir_idx; + if (idx * DIRBLKSIZ > dp->dn_stat.st_size) + idx = 0; /* just in case */ + blockaddr = buf + idx * DIRBLKSIZ; + looped = (idx == 0); + lastidx = idx; + if (lastidx == 0) + lastidx = dp->dn_stat.st_size / DIRBLKSIZ; + + while (!looped || idx < lastidx) { err = dirscanblock (blockaddr, dp, idx, name, namelen, type, ds, &inum); if (!err) - break; + { + dp->dn->dir_idx = idx; + break; + } if (err != ENOENT) { vm_deallocate (mach_task_self (), buf, buflen); return err; } + + blockaddr += DIRBLKSIZ; + idx++; + if (blockaddr - buf >= dp->dn_stat.st_size && !looped) + { + /* We've gotten to the end; start back at the beginning */ + looped = 1; + blockaddr = buf; + idx = 0; + } } if (!diskfs_check_readonly ()) @@ -258,7 +280,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, /* We didn't find any room, so mark ds to extend the dir */ ds->type = CREATE; ds->stat = EXTEND; - ds->idx = idx; + ds->idx = dp->dn_stat.st_size / DIRBLKSIZ; } /* Return to the user; if we can't, release the reference @@ -422,8 +444,8 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, down how many entries there were. */ if (!dp->dn->dirents) { - dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ + 1) - * sizeof (int)); + dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) + * sizeof (int)); for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; } @@ -595,19 +617,26 @@ diskfs_direnter_hard(struct node *dp, } else { + int i; /* It's cheap, so start a count here even if we aren't counting anything at all. */ if (dp->dn->dirents) { dp->dn->dirents = realloc (dp->dn->dirents, - (ds->idx + 1) * sizeof (int)); + (dp->dn_stat.st_size / DIRBLKSIZ + * sizeof (int))); + for (i = oldsize / DIRBLKSIZ; + i < dp->dn_stat.st_size / DIRBLKSIZ; + i++) + dp->dn->dirents[i] = -1; + dp->dn->dirents[ds->idx] = 1; } else { - int i; - dp->dn->dirents = malloc ((ds->idx + 1) * sizeof (int)); - for (i = 0; i < ds->idx; i++) + dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ + * sizeof (int)); + for (i = 0; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; dp->dn->dirents[ds->idx] = 1; } diff --git a/ufs/inode.c b/ufs/inode.c index ae323a8c..b06cb8d4 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -69,6 +69,7 @@ diskfs_cached_lookup (int inum, struct node **npp) dn->number = inum; dn->dirents = 0; + dn->dir_idx = 0; rwlock_init (&dn->allocptrlock); dn->dirty = 0; diff --git a/ufs/ufs.h b/ufs/ufs.h index ea13475e..f4b36ea5 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -36,6 +36,8 @@ struct disknode { ino_t number; + int dir_idx; + /* For a directory, this array holds the number of directory entries in each DIRBLKSIZE piece of the directory. */ int *dirents; -- cgit v1.2.3 From fa7a1850df5b233ac58e9ab4110a94601319fdea Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Fri, 6 Sep 1996 22:19:58 +0000 Subject: *** empty log message *** --- ufs-fsck/ChangeLog | 4 ++++ ufs-fsck/main.c | 2 +- ufs/ChangeLog | 7 +++++++ ufs/consts.c | 7 +++---- 4 files changed, 15 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs-fsck/ChangeLog b/ufs-fsck/ChangeLog index d4e404b2..6c1e84a2 100644 --- a/ufs-fsck/ChangeLog +++ b/ufs-fsck/ChangeLog @@ -1,3 +1,7 @@ +Fri Sep 6 16:44:07 1996 Thomas Bushnell, n/BSG + + * main.c (argp_program_version): Fix typo. + Thu Sep 5 11:42:21 1996 Thomas Bushnell, n/BSG * main.c: Include . diff --git a/ufs-fsck/main.c b/ufs-fsck/main.c index c159b170..ed651795 100644 --- a/ufs-fsck/main.c +++ b/ufs-fsck/main.c @@ -25,7 +25,7 @@ #include "fsck.h" -char *argp_program_version = STANDARD_HURD_VERSION (fsck.ufs) +char *argp_program_version = STANDARD_HURD_VERSION (fsck.ufs); char *lfname = "lost+found"; mode_t lfmode = 0755; diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 934c9856..896297d4 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,10 @@ +Fri Sep 6 16:00:42 1996 Thomas Bushnell, n/BSG + + * consts.c: Include . + (diskfs_major_version, diskfs_minor_version, diskfs_edit_version): + Deleted variables. + (diskfs_server_version): New variable. + Thu Aug 29 16:07:07 1996 Thomas Bushnell, n/BSG * dir.c (diskfs_lookup_hard): When setting ds->stat to EXTEND, set diff --git a/ufs/consts.c b/ufs/consts.c index 6698c5f4..1e855fba 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -1,5 +1,5 @@ /* Various constants wanted by the diskfs library - Copyright (C) 1994, 1995 Free Software Foundation + Copyright (C) 1994, 1995, 1996 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -16,6 +16,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" +#include int diskfs_link_max = LINK_MAX; int diskfs_maxsymlinks = 8; @@ -25,7 +26,5 @@ int diskfs_shortcut_blkdev = 1; int diskfs_shortcut_fifo = 1; int diskfs_shortcut_ifsock = 1; char *diskfs_server_name = "ufs"; -int diskfs_major_version = 0; -int diskfs_minor_version = 0; -int diskfs_edit_version = 0; +char *diskfs_server_version = HURD_VERSION; int diskfs_synchronous = 0; -- cgit v1.2.3 From 447352af2fb7582f49e0efaf48d5b2360be8c514 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Tue, 17 Sep 1996 16:43:48 +0000 Subject: *** empty log message *** --- ufs-fsck/ChangeLog | 8 ++++++++ ufs-fsck/Makefile | 6 +++--- ufs/ChangeLog | 6 ++++++ ufs/Makefile | 3 ++- 4 files changed, 19 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs-fsck/ChangeLog b/ufs-fsck/ChangeLog index 6c1e84a2..096d8c07 100644 --- a/ufs-fsck/ChangeLog +++ b/ufs-fsck/ChangeLog @@ -1,3 +1,11 @@ +Thu Sep 12 16:40:10 1996 Thomas Bushnell, n/BSG + + * Makefile (HURDLIBS): New variable. + ($(target)): Delete special depedency. + + * Makefile (vpath tables.c): Put after Makeconf inclusion to catch + setting of $(top_srcdir). + Fri Sep 6 16:44:07 1996 Thomas Bushnell, n/BSG * main.c (argp_program_version): Fix typo. diff --git a/ufs-fsck/Makefile b/ufs-fsck/Makefile index 8725de8e..a484428e 100644 --- a/ufs-fsck/Makefile +++ b/ufs-fsck/Makefile @@ -27,9 +27,9 @@ OBJS = $(subst .c,.o,$(SRCS)) tables.o LCLHDRS = fsck.h target = fsck.ufs installationdir = $(sbindir) +HURDLIBS=shouldbeinlibc -vpath tables.c $(top_srcdir)/ufs +include ../Makeconf -$(target): ../libshouldbeinlibc/libshouldbeinlibc.a +vpath tables.c $(top_srcdir)/ufs -include ../Makeconf diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 896297d4..e74328ce 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,9 @@ +Thu Sep 12 16:36:19 1996 Thomas Bushnell, n/BSG + + * Makefile (HURDLIBS): New variable. + (ufs.static ufs): Depend on $(library_deps) instead of long list + of libraries. + Fri Sep 6 16:00:42 1996 Thomas Bushnell, n/BSG * consts.c: Include . diff --git a/ufs/Makefile b/ufs/Makefile index d9375989..8d99925b 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -24,10 +24,11 @@ SRCS = alloc.c consts.c dir.c hyper.c inode.c main.c pager.c \ LCLHDRS = ufs.h fs.h dinode.h dir.h OBJS = $(SRCS:.c=.o) +HURDLIBS = diskfs ports pager iohelp fshelp threads ihash shouldbeinlibc ufs.static-LDFLAGS += -static include ../Makeconf -ufs.static ufs: $(OBJS) ../libdiskfs/libdiskfs.a ../libports/libports.a ../libpager/libpager.a ../libiohelp/libiohelp.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a ../libihash/libihash.a ../libshouldbeinlibc/libshouldbeinlibc.a +ufs.static ufs: $(OBJS) $(library_deps) -- cgit v1.2.3 From e4ecfc6a5c7636050767f285f3f8cf26bfca11bf Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:24:53 +0000 Subject: (diskfs_extra_version): New variable. --- ufs/consts.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs') diff --git a/ufs/consts.c b/ufs/consts.c index 1e855fba..8806049e 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -27,4 +27,5 @@ int diskfs_shortcut_fifo = 1; int diskfs_shortcut_ifsock = 1; char *diskfs_server_name = "ufs"; char *diskfs_server_version = HURD_VERSION; +char *diskfs_extra_version = "GNU Hurd"; int diskfs_synchronous = 0; -- cgit v1.2.3 From 39eaa6a47b81c641181528a1c31e9e01cfffecca Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:24:57 +0000 Subject: (diskfs_direnter_hard): Initialize OLDSIZE to shut up gcc. --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 397481d0..6c44932d 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -494,7 +494,7 @@ diskfs_direnter_hard(struct node *dp, vm_address_t fromoff, tooff; int totfreed; error_t err; - off_t oldsize; + off_t oldsize = 0; assert (ds->type == CREATE); -- cgit v1.2.3 From d1fe71f88f6f38fab0bb482cb600eea2e3afe26b Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:25:01 +0000 Subject: (zeroblock): Change type to `void *'. (diskfs_set_hypermetadata): Use store_{read,write} instead of diskfs_device_{read,write}_sync. (get_hypermetadata): Cast ZEROBLOCK when vm_{de,}allocating. Use DISKFS_DISK_NAME instead of DISKFS_DEVICE_ARG. (get_hypermetadata, diskfs_readonly_changed): Use fields in STORE instead of DISKFS_DEVICE_* variables. --- ufs/hyper.c | 58 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 25 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index cb644797..052bc220 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -19,12 +19,13 @@ #include #include #include +#include static int ufs_clean; /* fs clean before we started writing? */ static int oldformat; -vm_address_t zeroblock; +void *zeroblock; struct fs *sblock; struct csum *csum; @@ -137,7 +138,8 @@ get_hypermetadata (void) /* Free previous values. */ if (zeroblock) - vm_deallocate (mach_task_self (), zeroblock, sblock->fs_bsize); + vm_deallocate (mach_task_self(), + (vm_address_t)zeroblock, sblock->fs_bsize); if (csum) free (csum); @@ -190,13 +192,13 @@ get_hypermetadata (void) { error (0, 0, "%s: warning: FILESYSTEM NOT UNMOUNTED CLEANLY; PLEASE fsck", - diskfs_device_arg); + diskfs_disk_name); if (! diskfs_readonly) { diskfs_readonly = 1; error (0, 0, "%s: MOUNTED READ-ONLY; MUST USE `fsysopts --writable'", - diskfs_device_arg); + diskfs_disk_name); } } @@ -247,18 +249,17 @@ get_hypermetadata (void) if (swab_disk) swab_csums (csum); - if ((diskfs_device_size << diskfs_log2_device_block_size) - < sblock->fs_size * sblock->fs_fsize) + if (store->size < sblock->fs_size * sblock->fs_fsize) { fprintf (stderr, - "Disk size (%ld) less than necessary " + "Disk size (%Zd) less than necessary " "(superblock says we need %ld)\n", - diskfs_device_size << diskfs_log2_device_block_size, - sblock->fs_size * sblock->fs_fsize); + store->size, sblock->fs_size * sblock->fs_fsize); exit (1); } - vm_allocate (mach_task_self (), &zeroblock, sblock->fs_bsize, 1); + vm_allocate (mach_task_self (), + (vm_address_t *)&zeroblock, sblock->fs_bsize, 1); /* If the filesystem has new features in it, don't pay attention to the user's request not to use them. */ @@ -279,8 +280,6 @@ get_hypermetadata (void) error_t diskfs_set_hypermetadata (int wait, int clean) { - vm_address_t buf; - vm_size_t bufsize; error_t err; spin_lock (&alloclock); @@ -289,26 +288,36 @@ diskfs_set_hypermetadata (int wait, int clean) { /* Copy into a page-aligned buffer to avoid bugs in kernel device code. */ + void *buf = 0; + size_t read = 0; + size_t bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); - bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); - - err = diskfs_device_read_sync (fsbtodb (sblock, sblock->fs_csaddr), - &buf, bufsize); + err = store_read (store, fsbtodb (sblock, sblock->fs_csaddr), bufsize, + &buf, &read); if (err) return err; - - bcopy (csum, (void *) buf, sblock->fs_cssize); - if (swab_disk) - swab_csums ((struct csum *)buf); - err = diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr), - buf, bufsize); - vm_deallocate (mach_task_self (), buf, bufsize); + else if (read != bufsize) + err = EIO; + else + { + size_t wrote; + bcopy (csum, buf, sblock->fs_cssize); + if (swab_disk) + swab_csums ((struct csum *)buf); + err = store_write (store, fsbtodb (sblock, sblock->fs_csaddr), + buf, bufsize, &wrote); + if (!err && wrote != bufsize) + err = EIO; + } + + vm_deallocate (mach_task_self (), (vm_address_t)buf, read); if (err) { spin_unlock (&alloclock); return err; } + csum_dirty = 0; } @@ -384,8 +393,7 @@ void diskfs_readonly_changed (int readonly) { vm_protect (mach_task_self (), - (vm_address_t)disk_image, - diskfs_device_size << diskfs_log2_device_block_size, + (vm_address_t)disk_image, store->size, 0, VM_PROT_READ | (readonly ? 0 : VM_PROT_WRITE)); if (readonly) -- cgit v1.2.3 From f866671014ce5015022af04defaac3000c8f0be3 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:25:05 +0000 Subject: (diskfs_S_file_getfh): Variable ERR removed. (diskfs_S_file_get_storage_info): Narrow scope of RUN. Coalesce adjacent blocks when constructing RUNS. Set *PORTS_TYPE, not *STORAGE_PORT_TYPE. Use fields in STORE instead of DISKFS_DEVICE_* variables. Rewrite to use libstore functions (still has NDADDR block limit, though). --- ufs/inode.c | 134 +++++++++++++++++++++++------------------------------------- 1 file changed, 50 insertions(+), 84 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index b06cb8d4..47aa6ac9 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -21,6 +21,7 @@ #include #include #include +#include #define INOHSZ 512 #if ((INOHSZ&(INOHSZ-1)) == 0) @@ -621,108 +622,76 @@ diskfs_shutdown_soft_ports () offset into inode block holding inode (4 bytes) */ error_t diskfs_S_file_get_storage_info (struct protid *cred, - int *class, - off_t **addresses, - u_int *naddresses, - size_t *block_size, - char *storage_name, - mach_port_t *storage_port, - mach_msg_type_name_t *storage_port_type, - char **storage_data, - u_int *storage_data_len, - int *flags) + mach_port_t **ports, + mach_msg_type_name_t *ports_type, + mach_msg_type_number_t *num_ports, + int **ints, mach_msg_type_number_t *num_ints, + off_t **offsets, + mach_msg_type_number_t *num_offsets, + char **data, mach_msg_type_number_t *data_len) { error_t err; struct node *np; - int i; - struct dinode *di; - void *cp; + struct store *file_store; + struct store_run runs[NDADDR]; + size_t num_runs = 0; + if (! cred) + return EOPNOTSUPP; + np = cred->po->np; mutex_lock (&np->lock); /* See if this file fits in the direct block pointers. If not, punt for now. (Reading indir blocks is a pain, and I'm postponing pain.) XXX */ - if (np->allocsize > NDADDR * sblock->fs_bsize) { mutex_unlock (&np->lock); return EINVAL; } - - if (*naddresses < NDADDR * 2) - vm_allocate (mach_task_self (), (vm_address_t *) addresses, - sizeof (int) * NDADDR * 2, 1); - else - bzero (addresses, *naddresses * 2 * sizeof (int)); - *naddresses = NDADDR * 2; - if (*storage_data_len < 4 * sizeof (int)) - vm_allocate (mach_task_self (), (vm_address_t *) storage_data, - sizeof (int) * 4, 1); - *storage_data_len = 4 * sizeof (int); - - di = dino (np->dn->number); - err = diskfs_catch_exception (); - if (err) - { - mutex_unlock (&np->lock); - return err; - } - - /* Copy the block pointers */ - - if (!direct_symlink_extension - || np->dn_stat.st_size >= sblock->fs_maxsymlinklen - || !S_ISLNK (np->dn_stat.st_mode)) - { - for (i = 0; i < NDADDR; i++) - { - (*addresses)[2 * i] = fsbtodb (sblock, - read_disk_entry (di->di_db[i])); - if ((i + 1) * sblock->fs_bsize > np->allocsize) - (*addresses)[2 * i + 1] = np->allocsize - i * sblock->fs_bsize; - else - (*addresses)[2 * i + 1] = sblock->fs_bsize; - } - } - - /* Fill in the aux data */ - cp = *storage_data; - - *(int *)cp = htonl (np->dn->number); - cp += sizeof (int); - - *(int *)cp = htonl (di->di_trans); - cp += sizeof (int); - - *(int *)cp = htonl (fsbtodb (sblock, ino_to_fsba (sblock, np->dn->number))); - cp += sizeof (int); - - *(int *)cp = htonl (ino_to_fsbo (sblock, np->dn->number) - * sizeof (struct dinode)); - - + if (! err) + if (!direct_symlink_extension + || np->dn_stat.st_size >= sblock->fs_maxsymlinklen + || !S_ISLNK (np->dn_stat.st_mode)) + /* Copy the block pointers */ + { + int i; + struct store_run *run = runs; + struct dinode *di = dino (np->dn->number); + + for (i = 0; i < NDADDR; i++) + { + off_t start = fsbtodb (sblock, read_disk_entry (di->di_db[i])); + off_t length = + (((i + 1) * sblock->fs_bsize > np->allocsize) + ? np->allocsize - i * sblock->fs_bsize + : sblock->fs_bsize); + if (num_runs == 0 || run->start + run->length != start) + *run++ = (struct store_run){ start, length }; + else + run->length += length; + } + } diskfs_end_catch_exception (); - - *class = STORAGE_DEVICE; - *flags = 0; - *block_size = DEV_BSIZE; - if (diskfs_device_name) - strcpy (storage_name, diskfs_device_name); - - if (diskfs_isuid (0, cred)) - *storage_port = diskfs_device; - else - *storage_port = MACH_PORT_NULL; - *storage_port_type = MACH_MSG_TYPE_COPY_SEND; - mutex_unlock (&np->lock); - return 0; + if (! err) + err = store_clone (store, &file_store); + if (! err) + { + err = store_remap (file_store, runs, num_runs, &file_store); + if (! err) + err = store_return (file_store, ports, num_ports, ints, num_ints, + offsets, num_offsets, data, data_len); + store_free (file_store); + } + *ports_type = MACH_MSG_TYPE_COPY_SEND; + + return err; } /* Must be exactly 28 bytes long */ @@ -742,7 +711,6 @@ diskfs_S_file_getfh (struct protid *cred, u_int *fh_len) { struct node *np; - error_t err; struct ufs_fhandle *f; if (!cred) @@ -845,5 +813,3 @@ diskfs_S_fsys_getfile (mach_port_t fsys, } return err; } - - -- cgit v1.2.3 From 2209a97405c148f8a6a6d02950d0c7c738b1f332 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:25:09 +0000 Subject: (parse_opt): Propagate our input to the first child parser. (diskfs_append_args): New function. (diskfs_get_options): Function removed. (diskfs_reload_global_state): Use DISKFS_DISK_PAGER instead of DISK_PAGER. (startup_parents): Use DISKFS_STORE_STARTUP_ARGP instead of DISKFS_STD_DEVICE_STARTUP_ARGP. (store, store_parsed, diskfs_disk_name): New variables. (main): Remove CLASSES argument to store_parsed_open. Use STORE_PARAMS variable to get result from parsing STORE_ARGP. Don't force COMPAT_GNU on bootstrap filesystems (it's the default anyway). Don't set DISKFS_USE_MACH_DEVICE (which is no longer). Use DISKFS_DISK_NAME instead of DISKFS_DEVICE_ARG. Use fields in STORE instead of DISKFS_DEVICE_* variables. , : New includes. --- ufs/main.c | 66 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 353a1852..a42f8158 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -26,9 +26,16 @@ #include #include #include +#include +#include struct node *diskfs_root_node; +struct store *store = 0; +struct store_parsed *store_parsed = 0; + +char *diskfs_disk_name = 0; + /* Set diskfs_root_node to the root inode. */ static void warp_root (void) @@ -66,7 +73,7 @@ options[] = {0} }; -/* Parse a command line option. */ +/* Parse a ufs-specific command line option. */ static error_t parse_opt (int key, char *arg, struct argp_state *state) { @@ -101,6 +108,7 @@ parse_opt (int key, char *arg, struct argp_state *state) break; case ARGP_KEY_INIT: + state->child_inputs[0] = state->input; state->hook = (void *)compat_mode; break; case ARGP_KEY_SUCCESS: compat_mode = (enum compat_mode)state->hook; break; @@ -112,7 +120,7 @@ parse_opt (int key, char *arg, struct argp_state *state) } /* Add our startup arguments to the standard diskfs set. */ -static const struct argp *startup_parents[] = { &diskfs_std_device_startup_argp, 0}; +static const struct argp *startup_parents[] = { &diskfs_store_startup_argp, 0}; static struct argp startup_argp = {options, parse_opt, 0, 0, startup_parents}; /* Similarly at runtime. */ @@ -123,26 +131,21 @@ struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; /* Override the standard diskfs routine so we can add our own output. */ error_t -diskfs_get_options (char **argz, unsigned *argz_len) +diskfs_append_args (char **argz, unsigned *argz_len) { error_t err; - *argz = 0; - *argz_len = 0; - /* Get the standard things. */ err = diskfs_append_std_options (argz, argz_len); if (!err && compat_mode != COMPAT_GNU) - { - err = - argz_add (argz, argz_len, - ((compat_mode == COMPAT_BSD42) - ? "--compat=4.2" - : "--compat=4.4")); - if (err) - free (argz); /* Deallocate what diskfs returned. */ - } + err = argz_add (argz, argz_len, + ((compat_mode == COMPAT_BSD42) + ? "--compat=4.2" + : "--compat=4.4")); + + if (! err) + err = store_parsed_append_args (store_parsed, argz, argz_len); return err; } @@ -151,22 +154,23 @@ int main (int argc, char **argv) { error_t err; - off_t disk_size; mach_port_t bootstrap; + struct store_argp_params store_params = { 0 }; + + argp_parse (&startup_argp, argc, argv, 0, 0, &store_params); + store_parsed = store_params.result; - argp_parse (&startup_argp, argc, argv, 0, 0, 0); + err = store_parsed_name (store_parsed, &diskfs_disk_name); + if (err) + error (2, err, "store_parsed_name"); /* This must come after the args have been parsed, as this is where the host priv ports are set for booting. */ diskfs_console_stdio (); if (diskfs_boot_flags) - { /* We are the bootstrap filesystem. */ - bootstrap = MACH_PORT_NULL; - diskfs_use_mach_device = 1; - compat_mode = COMPAT_GNU; - } + bootstrap = MACH_PORT_NULL; else { task_get_bootstrap_port (mach_task_self (), &bootstrap); @@ -179,19 +183,19 @@ main (int argc, char **argv) if (err) error (4, err, "init"); - err = diskfs_device_open (); + err = store_parsed_open (store_parsed, diskfs_readonly ? STORE_READONLY : 0, + &store); if (err) - error (3, err, "%s", diskfs_device_arg); + error (3, err, "%s", diskfs_disk_name); - if (diskfs_device_block_size != DEV_BSIZE) + if (store->block_size != DEV_BSIZE) error (4, err, "%s: Bad device record size %d (should be %d)", - diskfs_device_arg, diskfs_device_block_size, DEV_BSIZE); - if (diskfs_log2_device_block_size == 0) + diskfs_disk_name, store->block_size, DEV_BSIZE); + if (store->log2_block_size == 0) error (4, err, "%s: Device block size (%d) not a power of 2", - diskfs_device_arg, diskfs_device_block_size); + diskfs_disk_name, store->block_size); - disk_size = diskfs_device_size << diskfs_log2_device_block_size; - assert (disk_size >= SBSIZE + SBOFF); + assert (store->size >= SBSIZE + SBOFF); /* Map the entire disk. */ create_disk_pager (); @@ -221,7 +225,7 @@ error_t diskfs_reload_global_state () { flush_pokes (); - pager_flush (disk_pager, 1); + pager_flush (diskfs_disk_pager, 1); get_hypermetadata (); return 0; } -- cgit v1.2.3 From cf859f986749059fbd818d487dac638eb4ca4f43 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:25:13 +0000 Subject: (pager_report_extent): Use fields in STORE instead of DISKFS_DEVICE_* variables. (pager_read_page, pager_write_page, pager_unlock_page): Use store_{read,write} instead of diskfs_device_{read,write}_sync. (create_disk_pager): Create PAGER_BUCKET. Use diskfs_start_disk_pager instead of disk_pager_setup. (thread_function): Function removed. (disk_image): New variable. (create_disk_pager, diskfs_shutdown_pager, diskfs_sync_everything): Use DISKFS_DISK_PAGER instead of DISK_PAGER. --- ufs/pager.c | 57 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 20 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index bea290ab..11d5eade 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -19,6 +19,7 @@ #include #include #include +#include spin_lock_t node2pagelock = SPIN_LOCK_INITIALIZER; @@ -32,6 +33,9 @@ spin_lock_t unlocked_pagein_lock = SPIN_LOCK_INITIALIZER; struct port_bucket *pager_bucket; +/* Mapped image of the disk. */ +void *disk_image; + /* Find the location on disk of page OFFSET in pager UPI. Return the disk address (in disk block) in *ADDR. If *NPLOCK is set on return, then release that mutex after I/O on the data has @@ -161,7 +165,10 @@ pager_read_page (struct user_pager_info *pager, if (addr) { - err = diskfs_device_read_sync (addr, (void *)buf, disksize); + size_t read = 0; + err = store_read (store, addr, disksize, (void **)buf, &read); + if (read != disksize) + err = EIO; if (!err && disksize != __vm_page_size) bzero ((void *)(*buf + disksize), __vm_page_size - disksize); *writelock = 0; @@ -199,7 +206,12 @@ pager_write_page (struct user_pager_info *pager, return err; if (addr) - err = diskfs_device_write_sync (addr, buf, disksize); + { + size_t wrote; + err = store_write (store, addr, (void *)buf, disksize, &wrote); + if (wrote != disksize) + err = EIO; + } else { printf ("Attempt to write unallocated disk\n."); @@ -286,6 +298,8 @@ pager_unlock_page (struct user_pager_info *pager, /* Check to see if this block is allocated. */ if (indirs[0].bno == 0) { + size_t wrote; + if (indirs[0].offset == -1) { err = ffs_alloc (np, lblkno (sblock, address), @@ -294,9 +308,15 @@ pager_unlock_page (struct user_pager_info *pager, sblock->fs_bsize, &bno, 0); if (err) goto out; + assert (lblkno (sblock, address) < NDADDR); - diskfs_device_write_sync (fsbtodb (sblock, bno), - zeroblock, sblock->fs_bsize); + err = store_write (store, fsbtodb (sblock, bno), + zeroblock, sblock->fs_bsize, &wrote); + if (!err && wrote != sblock->fs_bsize) + err = EIO; + if (err) + goto out; + indirs[0].bno = bno; write_disk_entry (di->di_db[lblkno (sblock, address)], bno); record_poke (di, sizeof (struct dinode)); @@ -378,8 +398,12 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; - diskfs_device_write_sync (fsbtodb (sblock, bno), - zeroblock, sblock->fs_bsize); + err = store_write (store, fsbtodb (sblock, bno), + zeroblock, sblock->fs_bsize, &wrote); + if (!err && wrote != sblock->fs_bsize) + err = EIO; + if (err) + goto out; indirs[0].bno = bno; write_disk_entry (siblock[indirs[0].offset], bno); @@ -405,7 +429,7 @@ pager_report_extent (struct user_pager_info *pager, *offset = 0; if (pager->type == DISK) - *size = diskfs_device_size << diskfs_log2_device_block_size; + *size = store->size; else *size = pager->np->allocsize; @@ -436,15 +460,6 @@ pager_dropweak (struct user_pager_info *upi __attribute__ ((unused))) -static void -thread_function (any_t foo __attribute__ ((unused))) -{ - for (;;) - ports_manage_port_operations_multithread (pager_bucket, pager_demuxer, - 1000 * 60 * 2, 0, - 1, MACH_PORT_NULL); -} - /* Create the DISK pager. */ void create_disk_pager (void) @@ -453,8 +468,10 @@ create_disk_pager (void) upi->type = DISK; upi->np = 0; - disk_pager_setup (upi, MAY_CACHE); - upi->p = disk_pager; + pager_bucket = ports_create_bucket (); + diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, store->size, + &disk_image); + upi->p = diskfs_disk_pager; } /* This syncs a single file (NP) to disk. Wait for all I/O to complete @@ -743,7 +760,7 @@ diskfs_shutdown_pager () { struct pager *p = arg; /* Don't ever shut down the disk pager. */ - if (p != disk_pager) + if (p != diskfs_disk_pager) pager_shutdown (p); return 0; } @@ -762,7 +779,7 @@ diskfs_sync_everything (int wait) { struct pager *p = arg; /* Make sure the disk pager is done last. */ - if (p != disk_pager) + if (p != diskfs_disk_pager) pager_sync (p, wait); return 0; } -- cgit v1.2.3 From c4668bbf0c8caa00875a701673fc26d4623ff9cc Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:25:16 +0000 Subject: (sync_disk): Use DISKFS_DISK_PAGER instead of DISK_PAGER. --- ufs/pokeloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/pokeloc.c b/ufs/pokeloc.c index d09942e8..267aa106 100644 --- a/ufs/pokeloc.c +++ b/ufs/pokeloc.c @@ -75,7 +75,7 @@ sync_disk (int wait) spin_lock (&pokelistlock); for (pl = pokelist; pl; pl = tmp) { - pager_sync_some (disk_pager, pl->offset, pl->length, wait); + pager_sync_some (diskfs_disk_pager, pl->offset, pl->length, wait); tmp = pl->next; free (pl); } -- cgit v1.2.3 From 606962e7195f975c6e8506dd7008b99e4624edf6 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:25:20 +0000 Subject: (block_extended, diskfs_grow): Do cast it to offer_data. (diskfs_truncate): Don't cast ZEROBLOCK to diskfs_node_rw. (indir_release): Use DISKFS_DISK_PAGER instead of DISK_PAGER. --- ufs/sizes.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/sizes.c b/ufs/sizes.c index a0b090d3..84c2493d 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -82,8 +82,7 @@ diskfs_truncate (struct node *np, np->allocsize = length; /* temporary */ bsize = blksize (sblock, np, lblkno (sblock, length)); np->allocsize = savesize; - diskfs_node_rdwr (np, (void *) zeroblock, length, - bsize - offset, 1, 0, 0); + diskfs_node_rdwr (np, zeroblock, length, bsize - offset, 1, 0, 0); diskfs_file_update (np, 1); } @@ -321,7 +320,7 @@ indir_release (struct node *np, daddr_t bno, int level) the block from the kernel's memory, making sure we do it synchronously--and BEFORE we attach it to the free list with ffs_blkfree. */ - pager_flush_some (disk_pager, fsaddr (sblock, bno), sblock->fs_bsize, 1); + pager_flush_some (diskfs_disk_pager, fsaddr (sblock, bno), sblock->fs_bsize, 1); /* We should also take this block off the inode's list of dirty indirect blocks if it's there. */ @@ -389,7 +388,8 @@ block_extended (struct node *np, don't get paged in from disk. */ if (round_page (old_size) < round_page (new_size)) offer_data (np, lbn * sblock->fs_bsize + round_page (old_size), - round_page (new_size) - round_page (old_size), zeroblock); + round_page (new_size) - round_page (old_size), + (vm_address_t)zeroblock); if (old_pbn != new_pbn) { @@ -553,7 +553,8 @@ diskfs_grow (struct node *np, goto out; - offer_data (np, lbn * sblock->fs_bsize, size, zeroblock); + offer_data (np, lbn * sblock->fs_bsize, size, + (vm_address_t)zeroblock); write_disk_entry (di->di_db[lbn], bno); record_poke (di, sizeof (struct dinode)); np->dn_set_ctime = 1; @@ -647,7 +648,8 @@ diskfs_grow (struct node *np, sblock->fs_bsize, &bno, 0); if (err) goto out; - offer_data (np, lbn * sblock->fs_bsize, sblock->fs_bsize, zeroblock); + offer_data (np, lbn * sblock->fs_bsize, sblock->fs_bsize, + (vm_address_t)zeroblock); indirs[0].bno = bno; write_disk_entry (siblock[indirs[0].offset], bno); record_poke (siblock, sblock->fs_bsize); -- cgit v1.2.3 From 3171166730cc3532b4099a0030c463ec7c8e6b3b Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:25:24 +0000 Subject: (store, store_parsed, disk_image): New declarations. (zeroblock): Change type to `void *'. (sync_disk_blocks): Use DISKFS_DISK_PAGER instead of DISK_PAGER. --- ufs/ufs.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index f4b36ea5..db2cf12b 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -88,7 +88,15 @@ struct user_pager_info #include -extern vm_address_t zeroblock; +/* The physical media. */ +extern struct store *store; +/* What the user specified. */ +extern struct store_parsed *store_parsed; + +/* Mapped image of the disk. */ +extern void *disk_image; + +extern void *zeroblock; extern struct fs *sblock; extern struct csum *csum; @@ -166,7 +174,7 @@ cg_locate (int ncg) extern inline void sync_disk_blocks (daddr_t blkno, size_t nbytes, int wait) { - pager_sync_some (disk_pager, fsaddr (sblock, blkno), nbytes, wait); + pager_sync_some (diskfs_disk_pager, fsaddr (sblock, blkno), nbytes, wait); } /* Sync an disk inode */ -- cgit v1.2.3 From 6c96cc2fe98de6e03786a211ce89e6925cffba54 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:26:21 +0000 Subject: (HURDLIBS): Add store. --- ufs/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 8d99925b..202316f8 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -24,11 +24,10 @@ SRCS = alloc.c consts.c dir.c hyper.c inode.c main.c pager.c \ LCLHDRS = ufs.h fs.h dinode.h dir.h OBJS = $(SRCS:.c=.o) -HURDLIBS = diskfs ports pager iohelp fshelp threads ihash shouldbeinlibc +HURDLIBS = diskfs iohelp fshelp store pager ports threads ihash shouldbeinlibc ufs.static-LDFLAGS += -static include ../Makeconf ufs.static ufs: $(OBJS) $(library_deps) - -- cgit v1.2.3 From db7941c146278cd195b850b659d8ec82e5aa8347 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:26:31 +0000 Subject: . --- ufs/ChangeLog | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index e74328ce..40d03163 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,80 @@ +Thu Sep 19 18:02:40 1996 Miles Bader + + * Makefile (HURDLIBS): Add store. + +Wed Sep 18 15:30:00 1996 Miles Bader + + * inode.c (diskfs_S_file_get_storage_info): Narrow scope of RUN. + + * consts.c (diskfs_extra_version): New variable. + + * main.c (main): Remove CLASSES argument to store_parsed_open. + Use STORE_PARAMS variable to get result from parsing STORE_ARGP. + Don't force COMPAT_GNU on bootstrap filesystems (it's the default + anyway). + +Mon Sep 16 13:27:38 1996 Miles Bader + + * Makefile (ufs.static ufs): Add ../libstore/libstore.a. + + * hyper.c (zeroblock): Change type to `void *'. + (get_hypermetadata): Cast ZEROBLOCK when vm_{de,}allocating. + * ufs.h (zeroblock): Change type to `void *'. + * sizes.c (diskfs_truncate): Don't cast ZEROBLOCK to diskfs_node_rw. + (block_extended, diskfs_grow): Do cast it to offer_data. + + * main.c (main): Don't set DISKFS_USE_MACH_DEVICE (which is no longer). + + * inode.c (diskfs_S_file_get_storage_info): Coalesce adjacent + blocks when constructing RUNS. + Set *PORTS_TYPE, not *STORAGE_PORT_TYPE. + * inode.c (diskfs_S_file_getfh): Variable ERR removed. + + * sizes.c (indir_release): Use DISKFS_DISK_PAGER instead of DISK_PAGER. + * ufs.h (sync_disk_blocks): Likewise. + * pokeloc.c (sync_disk): Likewise. + * main.c (diskfs_reload_global_state): Likewise. + * pager.c (create_disk_pager, diskfs_shutdown_pager, + diskfs_sync_everything): Likewise. + * main.c , : New includes. + * hyper.c, pager.c, inode.c : New include. + (get_hypermetadata): Use %Zd for printfing size_t. + (diskfs_set_hypermetadata): Return EIO for incomplete writes. + Cast BUF when calling vm_deallocate. + + * dir.c (diskfs_direnter_hard): Initialize OLDSIZE to shut up gcc. + +Sat Sep 14 20:38:47 1996 Miles Bader + + * ufs.h (store, store_parsed, disk_image): New declarations. + + * pager.c (thread_function): Function removed. + (create_disk_pager): Create PAGER_BUCKET. + Use diskfs_start_disk_pager instead of disk_pager_setup. + (disk_image): New variable. + + * main.c (store, store_parsed, diskfs_disk_name): New variables. + (parse_opt): Propagate our input to the first child parser. + (diskfs_append_args): New function. + (diskfs_get_options): Function removed. + (startup_parents): Use DISKFS_STORE_STARTUP_ARGP instead of + DISKFS_STD_DEVICE_STARTUP_ARGP. + + * hyper.c (get_hypermetadata): Use DISKFS_DISK_NAME instead of + DISKFS_DEVICE_ARG. + * main.c (main): Likewise. + + * hyper.c (get_hypermetadata, diskfs_readonly_changed): Use + fields in STORE instead of DISKFS_DEVICE_* variables. + * inode.c (diskfs_S_file_get_storage_info): Likewise. + * pager.c (pager_report_extent): Likewise. + * main.c (main): Likewise. + * pager.c (pager_read_page, pager_write_page, pager_unlock_page): + Use store_{read,write} instead of diskfs_device_{read,write}_sync. + * hyper.c (diskfs_set_hypermetadata): Likewise. + * inode.c (diskfs_S_file_get_storage_info): Rewrite to use + libstore functions (still has NDADDR block limit, though). + Thu Sep 12 16:36:19 1996 Thomas Bushnell, n/BSG * Makefile (HURDLIBS): New variable. -- cgit v1.2.3 From 771467d73865b27e02692a457e57c4000e820b3e Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 24 Oct 1996 22:43:08 +0000 Subject: (startup_children, runtime_children): New variables. (startup_parents, runtime_parents): Variables removed. (startup_argp, runtime_argp): Use new *_CHILDREN variables instead of corresponding *_PARENT ones. --- ufs/main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index a42f8158..f0ffa3f5 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -120,12 +120,14 @@ parse_opt (int key, char *arg, struct argp_state *state) } /* Add our startup arguments to the standard diskfs set. */ -static const struct argp *startup_parents[] = { &diskfs_store_startup_argp, 0}; -static struct argp startup_argp = {options, parse_opt, 0, 0, startup_parents}; +static const struct argp_child startup_children[] = + {{&diskfs_store_startup_argp}, {0}}; +static struct argp startup_argp = {options, parse_opt, 0, 0, startup_children}; /* Similarly at runtime. */ -static const struct argp *runtime_parents[] = {&diskfs_std_runtime_argp, 0}; -static struct argp runtime_argp = {options, parse_opt, 0, 0, runtime_parents}; +static const struct argp_child runtime_children[] = + {{&diskfs_std_runtime_argp}, {0}}; +static struct argp runtime_argp = {options, parse_opt, 0, 0, runtime_children}; struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; -- cgit v1.2.3 From 082a3a45cd55b33d05223b6942c804de8f844384 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 24 Oct 1996 22:43:50 +0000 Subject: . --- ufs/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 40d03163..2c81dbc3 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,10 @@ +Thu Oct 24 16:07:17 1996 Miles Bader + + * main.c (startup_children, runtime_children): New variables. + (startup_parents, runtime_parents): Variables removed. + (startup_argp, runtime_argp): Use new *_CHILDREN variables instead of + corresponding *_PARENT ones. + Thu Sep 19 18:02:40 1996 Miles Bader * Makefile (HURDLIBS): Add store. -- cgit v1.2.3 From 00b56b8817816a221ed49d07c14d5c93a079da4d Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Mon, 18 Nov 1996 23:59:08 +0000 Subject: Sat Nov 16 17:21:40 1996 Thomas Bushnell, n/BSG * inode.c (diskfs_S_fsys_getfile): Delete var `fakecred'. diskfs_access -> fshelp_access. * alloc.c (ffs_alloc): diskfs_isuid -> idvec_contains. (ffs_realloccg): Likewise. Thu Nov 14 16:43:36 1996 Thomas Bushnell, n/BSG * inode.c (diskfs_S_file_getfh): diskfs_isuid -> idvec_contains. (diskfs_S_fsys_getfile): Use idvecs and iousers. --- ufs/ChangeLog | 12 ++++++++++++ ufs/alloc.c | 5 +++-- ufs/inode.c | 27 ++++++++++++++++----------- 3 files changed, 31 insertions(+), 13 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 2c81dbc3..4ca29dee 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,15 @@ +Sat Nov 16 17:21:40 1996 Thomas Bushnell, n/BSG + + * inode.c (diskfs_S_fsys_getfile): Delete var `fakecred'. + diskfs_access -> fshelp_access. + * alloc.c (ffs_alloc): diskfs_isuid -> idvec_contains. + (ffs_realloccg): Likewise. + +Thu Nov 14 16:43:36 1996 Thomas Bushnell, n/BSG + + * inode.c (diskfs_S_file_getfh): diskfs_isuid -> idvec_contains. + (diskfs_S_fsys_getfile): Use idvecs and iousers. + Thu Oct 24 16:07:17 1996 Miles Bader * main.c (startup_children, runtime_children): New variables. diff --git a/ufs/alloc.c b/ufs/alloc.c index 90ce68f5..15d53180 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -247,7 +247,7 @@ ffs_alloc(register struct node *np, spin_lock (&alloclock); if (size == fs->fs_bsize && fs->fs_cstotal.cs_nbfree == 0) goto nospace; - if (cred && !diskfs_isuid (0, cred) + if (cred && !idvec_contains (cred->user->uids, 0) && freespace(fs, fs->fs_minfree) <= 0) goto nospace; #ifdef QUOTA @@ -323,7 +323,8 @@ ffs_realloccg(register struct node *np, spin_lock (&alloclock); - if (!diskfs_isuid (0, cred) && freespace(fs, fs->fs_minfree) <= 0) + if (!idvec_contains (cred->user->uids, 0) + && freespace(fs, fs->fs_minfree) <= 0) goto nospace; error = diskfs_catch_exception (); if (error) diff --git a/ufs/inode.c b/ufs/inode.c index 47aa6ac9..a0f16642 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -716,7 +716,7 @@ diskfs_S_file_getfh (struct protid *cred, if (!cred) return EOPNOTSUPP; - if (!diskfs_isuid (0, cred)) + if (!idvec_contains (cred->user->uids, 0)) return EPERM; np = cred->po->np; @@ -757,7 +757,9 @@ diskfs_S_fsys_getfile (mach_port_t fsys, struct ufs_fhandle *f; error_t err; int flags; - struct protid fakecred, *newpi; + struct protid *newpi; + struct idvec *uvec, *gvec; + struct iouser *user; if (!pt) return EOPNOTSUPP; @@ -784,24 +786,27 @@ diskfs_S_fsys_getfile (mach_port_t fsys, return ESTALE; } - /* This call should have a flags arg, but until then... */ - fakecred.uids = uids; - fakecred.gids = gids; - fakecred.nuids = nuids; - fakecred.ngids = ngids; + uvec = make_idvec (); + gvec = make_idvec (); + idvec_set_ids (uvec, uids, nuids); + idvec_set_ids (gvec, gids, ngids); + user = iohelp_create_iouser (uvec, gvec); + flags = 0; - if (!diskfs_access (np, S_IREAD, &fakecred)) + if (!fshelp_access (&np->dn_stat, S_IREAD, user)) flags |= O_READ; - if (!diskfs_access (np, S_IEXEC, &fakecred)) + if (!fshelp_access (&np->dn_stat, S_IEXEC, user)) flags |= O_EXEC; - if (!diskfs_access (np, S_IWRITE, &fakecred) + if (!fshelp_access (&np->dn_stat, S_IWRITE, user) && !S_ISDIR (np->dn_stat.st_mode) && !diskfs_check_readonly ()) flags |= O_WRITE; err = diskfs_create_protid (diskfs_make_peropen (np, flags, MACH_PORT_NULL), - uids, nuids, gids, ngids, &newpi); + user, &newpi); + + iohelp_free_iouser (user); diskfs_nput (np); ports_port_deref (pt); -- cgit v1.2.3 From 44015af36f54d4d34fe15a2c8f34179acb979def Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Tue, 19 Nov 1996 23:18:20 +0000 Subject: (ffs_alloc): Use S_IPTRANS in NP->dn_stat.st_mode instead of NP->istranslated. --- ufs/alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index 15d53180..ac72c928 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -683,7 +683,7 @@ diskfs_alloc_node (struct node *dir, goto noinodes; error = diskfs_cached_lookup (ino, &np); assert ("duplicate allocation" && !np->dn_stat.st_mode); - assert (!np->istranslated); + assert (! (np->dn_stat.st_mode & S_IPTRANS)); if (np->dn_stat.st_blocks) { printf("free inode %d had %d blocks\n", ino, np->dn_stat.st_blocks); -- cgit v1.2.3 From a8e78f4ac4b6b40ebf6879c8ba92cc864e80d7dd Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Tue, 19 Nov 1996 23:19:03 +0000 Subject: (diskfs_set_translator): Frob S_IPTRANS bit in mode bits instead of NP->istranslated. (write_node): Don't write any bits in S_ITRANS to disk. (read_disknode): When setting ST->st_mode, Clear S_ITRANS bits, and set S_IPTRANS if necessary. Don't set NP->istranslated anymore. --- ufs/inode.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index a0f16642..006d595a 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -221,9 +221,7 @@ read_disknode (struct node *np) if (err) return err; - np->istranslated = !! di->di_trans; - - if (!fsidset) + if (! fsidset) { fsid = getpid (); fsidset = 1; @@ -234,8 +232,10 @@ read_disknode (struct node *np) st->st_ino = np->dn->number; st->st_gen = read_disk_entry (di->di_gen); st->st_rdev = read_disk_entry(di->di_rdev); - st->st_mode = (read_disk_entry (di->di_model) - | (read_disk_entry (di->di_modeh) << 16)); + st->st_mode = (((read_disk_entry (di->di_model) + | (read_disk_entry (di->di_modeh) << 16)) + & ~S_ITRANS) + | (di->di_trans ? S_IPTRANS : 0)); st->st_nlink = read_disk_entry (di->di_nlink); st->st_size = read_disk_entry (di->di_size); #ifdef notyet @@ -326,12 +326,13 @@ write_node (struct node *np) if (compat_mode == COMPAT_GNU) { - write_disk_entry (di->di_model, st->st_mode & 0xffff); - write_disk_entry (di->di_modeh, (st->st_mode >> 16) & 0xffff); + mode_t mode = st->st_mode & ~S_ITRANS; + write_disk_entry (di->di_model, mode & 0xffff); + write_disk_entry (di->di_modeh, (mode >> 16) & 0xffff); } else { - write_disk_entry (di->di_model, st->st_mode & 0xffff); + write_disk_entry (di->di_model, st->st_mode & 0xffff & ~S_ITRANS); di->di_modeh = 0; } @@ -557,7 +558,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, di->di_trans = 0; record_poke (di, sizeof (struct dinode)); np->dn_stat.st_blocks -= btodb (sblock->fs_bsize); - np->istranslated = 0; + np->dn_stat.st_mode &= ~S_IPTRANS; np->dn_set_ctime = 1; } @@ -569,7 +570,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, bcopy (buf, disk_image + fsaddr (sblock, blkno), sblock->fs_bsize); sync_disk_blocks (blkno, sblock->fs_bsize, 1); - np->istranslated = 1; + np->dn_stat.st_mode |= S_IPTRANS; np->dn_set_ctime = 1; } -- cgit v1.2.3 From 7eaadcab20d3580b4248be866188786cb0536d8c Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Tue, 19 Nov 1996 23:19:17 +0000 Subject: . --- ufs/ChangeLog | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 4ca29dee..20921669 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,14 @@ +Mon Nov 18 17:10:00 1996 Miles Bader + + * inode.c (read_disknode): When setting ST->st_mode, Clear + S_ITRANS bits, and set S_IPTRANS if necessary. Don't set + NP->istranslated anymore. + (diskfs_set_translator): Frob S_IPTRANS bit in mode bits instead + of NP->istranslated. + (write_node): Don't write any bits in S_ITRANS to disk. + * alloc.c (ffs_alloc): Use S_IPTRANS in NP->dn_stat.st_mode + instead of NP->istranslated. + Sat Nov 16 17:21:40 1996 Thomas Bushnell, n/BSG * inode.c (diskfs_S_fsys_getfile): Delete var `fakecred'. -- cgit v1.2.3 From 56ef5d5b431c08037e09849debfe9ea001b5e481 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Wed, 20 Nov 1996 02:54:01 +0000 Subject: (read_disknode): If SBLOCK->fs_inodefmt < FS_44INODEFMT, set ST->st_author to st->st_uid, and NP->author_tracks_uid to true. (diskfs_validate_author_change): New function. --- ufs/inode.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 006d595a..286cfafc 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -258,7 +258,8 @@ read_disknode (struct node *np) { st->st_uid = read_disk_entry (di->di_ouid); st->st_gid = read_disk_entry (di->di_ogid); - st->st_author = 0; + st->st_author = st->st_uid; + np->author_tracks_uid = 1; } else { @@ -300,6 +301,18 @@ error_t diskfs_node_reload (struct node *node) return 0; } +/* Return 0 if NP's author can be changed to AUTHOR; otherwise return an + error code. */ +error_t +diskfs_validate_author_change (struct node *np, uid_t author) +{ + if (compat_mode == COMPAT_GNU) + return 0; + else + /* For non-hurd filesystems, the author & owner are the same. */ + return (author == np->dn_stat.st_uid) ? 0 : EINVAL; +} + static void write_node (struct node *np) { -- cgit v1.2.3 From 34accef1c2f1d27a3af0de37ce67a16dc5a1a5ca Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Wed, 20 Nov 1996 02:54:47 +0000 Subject: . --- ufs/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 20921669..41f2347c 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,9 @@ +Tue Nov 19 18:28:26 1996 Miles Bader + + * inode.c (read_disknode): If SBLOCK->fs_inodefmt < FS_44INODEFMT, + set ST->st_author to st->st_uid, and NP->author_tracks_uid to true. + (diskfs_validate_author_change): New function. + Mon Nov 18 17:10:00 1996 Miles Bader * inode.c (read_disknode): When setting ST->st_mode, Clear -- cgit v1.2.3 From 894448bcc1aff693009298da900c27431f09c5a5 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 6 Feb 1997 06:58:33 +0000 Subject: (diskfs_S_fsys_getfile): Pass new DEPTH argument to diskfs_make_peropen. --- ufs/inode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 286cfafc..dc870525 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,5 @@ /* Inode management routines - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -817,7 +817,8 @@ diskfs_S_fsys_getfile (mach_port_t fsys, && !diskfs_check_readonly ()) flags |= O_WRITE; - err = diskfs_create_protid (diskfs_make_peropen (np, flags, MACH_PORT_NULL), + err = diskfs_create_protid (diskfs_make_peropen (np, flags, + MACH_PORT_NULL, 0), user, &newpi); iohelp_free_iouser (user); -- cgit v1.2.3 From 55e4665ab4ed09db57a533a08d63d376a4fc8b88 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 6 Feb 1997 07:41:21 +0000 Subject: (diskfs_S_file_getfh, diskfs_S_fsys_getfile): Functions removed. --- ufs/inode.c | 126 ------------------------------------------------------------ 1 file changed, 126 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index dc870525..2965114f 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -707,129 +707,3 @@ diskfs_S_file_get_storage_info (struct protid *cred, return err; } - -/* Must be exactly 28 bytes long */ -struct ufs_fhandle -{ - int filler1; - ino_t inum; - long gen; - int filler2[4]; -}; - -/* Return an NFS file handle */ - -error_t -diskfs_S_file_getfh (struct protid *cred, - char **fh, - u_int *fh_len) -{ - struct node *np; - struct ufs_fhandle *f; - - if (!cred) - return EOPNOTSUPP; - - if (!idvec_contains (cred->user->uids, 0)) - return EPERM; - - np = cred->po->np; - - mutex_lock (&np->lock); - - if (*fh_len < sizeof (struct ufs_fhandle)) - vm_allocate (mach_task_self (), (vm_address_t *) fh, - sizeof (struct ufs_fhandle), 1); - *fh_len = sizeof (struct ufs_fhandle); - - f = (struct ufs_fhandle *) *fh; - f->inum = np->dn->number; - f->gen = np->dn_stat.st_gen; - f->filler1 = 0; - f->filler2[0] = f->filler2[1] = f->filler2[2] = f->filler2[3] = 0; - mutex_unlock (&np->lock); - return 0; -} - -/* Lookup an NFS file handle */ -error_t -diskfs_S_fsys_getfile (mach_port_t fsys, - mach_port_t reply, - mach_msg_type_name_t replytype, - uid_t *uids, - u_int nuids, - uid_t *gids, - u_int ngids, - char *handle, - u_int handlelen, - mach_port_t *file, - mach_msg_type_name_t *filetype) -{ - struct port_info *pt = ports_lookup_port (diskfs_port_bucket, fsys, - diskfs_control_class); - struct node *np; - struct ufs_fhandle *f; - error_t err; - int flags; - struct protid *newpi; - struct idvec *uvec, *gvec; - struct iouser *user; - - if (!pt) - return EOPNOTSUPP; - - if (handlelen != sizeof (struct ufs_fhandle)) - { - ports_port_deref (pt); - return EINVAL; - } - - f = (struct ufs_fhandle *) handle; - - err = diskfs_cached_lookup (f->inum, &np); - if (err) - { - ports_port_deref (pt); - return err; - } - - if (np->dn_stat.st_gen != f->gen) - { - diskfs_nput (np); - ports_port_deref (pt); - return ESTALE; - } - - uvec = make_idvec (); - gvec = make_idvec (); - - idvec_set_ids (uvec, uids, nuids); - idvec_set_ids (gvec, gids, ngids); - user = iohelp_create_iouser (uvec, gvec); - - flags = 0; - if (!fshelp_access (&np->dn_stat, S_IREAD, user)) - flags |= O_READ; - if (!fshelp_access (&np->dn_stat, S_IEXEC, user)) - flags |= O_EXEC; - if (!fshelp_access (&np->dn_stat, S_IWRITE, user) - && !S_ISDIR (np->dn_stat.st_mode) - && !diskfs_check_readonly ()) - flags |= O_WRITE; - - err = diskfs_create_protid (diskfs_make_peropen (np, flags, - MACH_PORT_NULL, 0), - user, &newpi); - - iohelp_free_iouser (user); - - diskfs_nput (np); - ports_port_deref (pt); - - if (!err) - { - *file = ports_get_right (newpi); - *filetype = MACH_MSG_TYPE_MAKE_SEND; - } - return err; -} -- cgit v1.2.3 From 606fe786cb5782808b18e14e9f925a813d8b8a61 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 6 Feb 1997 07:42:34 +0000 Subject: . --- ufs/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 41f2347c..323da685 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +Thu Feb 6 01:56:27 1997 Miles Bader + + (diskfs_S_file_getfh, diskfs_S_fsys_getfile): Functions removed. + Tue Nov 19 18:28:26 1996 Miles Bader * inode.c (read_disknode): If SBLOCK->fs_inodefmt < FS_44INODEFMT, -- cgit v1.2.3 From 68de70d85b5a804c85b5e6890a236bd3c770759c Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 20 Jun 1997 19:24:24 +0000 Subject: (pager_read_page, pager_write_page, pager_unlock_page): Adjust device addresses for possible differences between DEV_BSIZE & device block size. --- ufs/pager.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'ufs') diff --git a/ufs/pager.c b/ufs/pager.c index 11d5eade..afb34839 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -1,5 +1,5 @@ /* Pager for ufs - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -166,7 +166,8 @@ pager_read_page (struct user_pager_info *pager, if (addr) { size_t read = 0; - err = store_read (store, addr, disksize, (void **)buf, &read); + err = store_read (store, addr << log2_dev_blocks_per_dev_bsize, + disksize, (void **)buf, &read); if (read != disksize) err = EIO; if (!err && disksize != __vm_page_size) @@ -208,7 +209,8 @@ pager_write_page (struct user_pager_info *pager, if (addr) { size_t wrote; - err = store_write (store, addr, (void *)buf, disksize, &wrote); + err = store_write (store, addr << log2_dev_blocks_per_dev_bsize, + (void *)buf, disksize, &wrote); if (wrote != disksize) err = EIO; } @@ -310,7 +312,9 @@ pager_unlock_page (struct user_pager_info *pager, goto out; assert (lblkno (sblock, address) < NDADDR); - err = store_write (store, fsbtodb (sblock, bno), + err = store_write (store, + fsbtodb (sblock, bno) + << log2_dev_blocks_per_dev_bsize, zeroblock, sblock->fs_bsize, &wrote); if (!err && wrote != sblock->fs_bsize) err = EIO; @@ -398,7 +402,9 @@ pager_unlock_page (struct user_pager_info *pager, if (err) goto out; - err = store_write (store, fsbtodb (sblock, bno), + err = store_write (store, + fsbtodb (sblock, bno) + << log2_dev_blocks_per_dev_bsize, zeroblock, sblock->fs_bsize, &wrote); if (!err && wrote != sblock->fs_bsize) err = EIO; -- cgit v1.2.3 From 102ca48a3c04c37a4c500ebc9ceb3b4cfc8b1df9 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 20 Jun 1997 19:24:43 +0000 Subject: (diskfs_S_file_get_storage_info): Adjust device addresses for possible differences between DEV_BSIZE & device block size. --- ufs/inode.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 2965114f..fe5abbb9 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -683,6 +683,8 @@ diskfs_S_file_get_storage_info (struct protid *cred, (((i + 1) * sblock->fs_bsize > np->allocsize) ? np->allocsize - i * sblock->fs_bsize : sblock->fs_bsize); + start <<= log2_dev_blocks_per_dev_bsize; + length <<= log2_dev_blocks_per_dev_bsize; if (num_runs == 0 || run->start + run->length != start) *run++ = (struct store_run){ start, length }; else -- cgit v1.2.3 From cb252fa897afb4adb1b6a2a52c6573cb20328f6a Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 20 Jun 1997 19:25:28 +0000 Subject: (log2_dev_blocks_per_bsize): New declaration. --- ufs/ufs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index db2cf12b..1c44e5f5 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -130,6 +130,8 @@ int direct_symlink_extension; /* If this is set, then the disk is byteswapped from native order. */ int swab_disk; +/* Number of device blocks per DEV_BSIZE block. */ +unsigned log2_dev_blocks_per_dev_bsize; /* Handy macros */ #define DEV_BSIZE 512 -- cgit v1.2.3 From 8525a4a02951672e3938d03a95f10dc5fc57aa51 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 20 Jun 1997 19:26:29 +0000 Subject: (log2_dev_blocks_per_bsize): New variable. (main): Only require device-block-size to be <= DEV_BSIZE. Get rid of device-block-size-is-power-of-2 check. Set LOG2_DEV_BLOCKS_PER_BSIZE. Exit with an error if the disk is too small rather than assert failing. --- ufs/main.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index f0ffa3f5..61531c22 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -36,6 +36,9 @@ struct store_parsed *store_parsed = 0; char *diskfs_disk_name = 0; +/* Number of device blocks per DEV_BSIZE block. */ +unsigned log2_dev_blocks_per_dev_bsize = 0; + /* Set diskfs_root_node to the root inode. */ static void warp_root (void) @@ -190,14 +193,17 @@ main (int argc, char **argv) if (err) error (3, err, "%s", diskfs_disk_name); - if (store->block_size != DEV_BSIZE) - error (4, err, "%s: Bad device record size %d (should be %d)", + if (store->block_size > DEV_BSIZE) + error (4, err, "%s: Bad device block size %d (should be <= %d)", diskfs_disk_name, store->block_size, DEV_BSIZE); - if (store->log2_block_size == 0) - error (4, err, "%s: Device block size (%d) not a power of 2", - diskfs_disk_name, store->block_size); - - assert (store->size >= SBSIZE + SBOFF); + if (store->size < SBSIZE + SBOFF) + error (5, 0, "%s: Disk too small (%ld bytes)", diskfs_disk_name, + store->size); + + log2_dev_blocks_per_dev_bsize = 0; + while ((1 << log2_dev_blocks_per_dev_bsize) < DEV_BSIZE) + log2_dev_blocks_per_dev_bsize++; + log2_dev_blocks_per_dev_bsize -= store->log2_block_size; /* Map the entire disk. */ create_disk_pager (); -- cgit v1.2.3 From 50c06c73760f1d10924fe8e83b5d2633e9b2bad0 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 20 Jun 1997 19:27:16 +0000 Subject: . --- ufs/ChangeLog | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 323da685..debab075 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,17 @@ +1997-06-20 Miles Bader + + * hyper.c (diskfs_set_hypermetadata): Adjust device addresses for + possible differences between DEV_BSIZE & device block size. + * inode.c (diskfs_S_file_get_storage_info): Likewise. + * pager.c (pager_read_page, pager_write_page, pager_unlock_page): + Likewise. + * ufs.h (log2_dev_blocks_per_bsize): New declaration. + * main.c (main): Only require device-block-size to be <= DEV_BSIZE. + Get rid of device-block-size-is-power-of-2 check. + Set LOG2_DEV_BLOCKS_PER_BSIZE. + Exit with an error if the disk is too small rather than assert failing. + (log2_dev_blocks_per_bsize): New variable. + Thu Feb 6 01:56:27 1997 Miles Bader (diskfs_S_file_getfh, diskfs_S_fsys_getfile): Functions removed. -- cgit v1.2.3 From b1d444e7e11450dff9321706a2ae88af4a1c784b Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Fri, 20 Jun 1997 19:34:41 +0000 Subject: (diskfs_set_hypermetadata): Adjust device addresses for possible differences between DEV_BSIZE & device block size. --- ufs/hyper.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/hyper.c b/ufs/hyper.c index 052bc220..500934eb 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -1,5 +1,5 @@ /* Fetching and storing the hypermetadata (superblock and cg summary info). - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -292,8 +292,10 @@ diskfs_set_hypermetadata (int wait, int clean) size_t read = 0; size_t bufsize = round_page (fragroundup (sblock, sblock->fs_cssize)); - err = store_read (store, fsbtodb (sblock, sblock->fs_csaddr), bufsize, - &buf, &read); + err = store_read (store, + fsbtodb (sblock, sblock->fs_csaddr) + << log2_dev_blocks_per_dev_bsize, + bufsize, &buf, &read); if (err) return err; else if (read != bufsize) @@ -304,7 +306,9 @@ diskfs_set_hypermetadata (int wait, int clean) bcopy (csum, buf, sblock->fs_cssize); if (swab_disk) swab_csums ((struct csum *)buf); - err = store_write (store, fsbtodb (sblock, sblock->fs_csaddr), + err = store_write (store, + fsbtodb (sblock, sblock->fs_csaddr) + << log2_dev_blocks_per_dev_bsize, buf, bufsize, &wrote); if (!err && wrote != bufsize) err = EIO; -- cgit v1.2.3 From e94252fe692a5638429cbe4fdf9e2a37c3a7b2bb Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Mon, 23 Jun 1997 17:35:12 +0000 Subject: *** empty log message *** --- ufs/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 61531c22..e6a7e303 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -223,6 +223,8 @@ main (int argc, char **argv) outside world. */ diskfs_startup_diskfs (bootstrap, 0); + /* SET HOST NAME */ + /* And this thread is done with its work. */ cthread_exit (0); -- cgit v1.2.3 From b3c14dc05fa82774cd9e83233ba5c4f66b076ba4 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Mon, 30 Jun 1997 21:59:32 +0000 Subject: Mon Jun 30 17:38:57 1997 Thomas Bushnell, n/BSG * main.c (main): If the store cannot be made writable, then set diskfs_hard_readonly and diskfs_readonly. --- ufs/ChangeLog | 5 +++++ ufs/main.c | 3 +++ 2 files changed, 8 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index debab075..ca832c8e 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +Mon Jun 30 17:38:57 1997 Thomas Bushnell, n/BSG + + * main.c (main): If the store cannot be made writable, then set + diskfs_hard_readonly and diskfs_readonly. + 1997-06-20 Miles Bader * hyper.c (diskfs_set_hypermetadata): Adjust device addresses for diff --git a/ufs/main.c b/ufs/main.c index e6a7e303..6116792b 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -205,6 +205,9 @@ main (int argc, char **argv) log2_dev_blocks_per_dev_bsize++; log2_dev_blocks_per_dev_bsize -= store->log2_block_size; + if (store->flags & STORE_HARD_READONLY) + diskfs_readonly = diskfs_hard_readonly = 1; + /* Map the entire disk. */ create_disk_pager (); -- cgit v1.2.3 From c6358909aa9e73d34a5da39e3ea945c9c07b9e1a Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Wed, 20 Aug 1997 19:06:42 +0000 Subject: Wed Aug 20 14:34:24 1997 Thomas Bushnell, n/BSG * dir.c (diskfs_lookup_hard): Cope with error return from diskfs_get_filemap. * sizes.c (diskfs_grow): Likewise. * dir.c (diskfs_dirempty): Cope (poorly) with error return from diskfs_get_filemap. * sizes.c (diskfs_truncate): Likewise. (block_extended): Likewise. * pager.c (diskfs_get_filemap): If pager_create fails, return error to caller. --- ufs/ChangeLog | 13 +++++++++++++ ufs/dir.c | 11 ++++++++++- ufs/pager.c | 7 +++++++ ufs/sizes.c | 22 +++++++++++++++++----- 4 files changed, 47 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index ca832c8e..3a225552 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,16 @@ +Wed Aug 20 14:34:24 1997 Thomas Bushnell, n/BSG + + * dir.c (diskfs_lookup_hard): Cope with error return from + diskfs_get_filemap. + * sizes.c (diskfs_grow): Likewise. + * dir.c (diskfs_dirempty): Cope (poorly) with error return from + diskfs_get_filemap. + * sizes.c (diskfs_truncate): Likewise. + (block_extended): Likewise. + + * pager.c (diskfs_get_filemap): If pager_create fails, return + error to caller. + Mon Jun 30 17:38:57 1997 Thomas Bushnell, n/BSG * main.c (main): If the store cannot be made writable, then set diff --git a/ufs/dir.c b/ufs/dir.c index 6c44932d..bdf84be6 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -145,6 +145,10 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, /* Map in the directory contents. */ memobj = diskfs_get_filemap (dp, prot); + + if (memobj == MACH_PORT_NULL) + return errno; + buf = 0; /* We allow extra space in case we have to do an EXTEND. */ buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); @@ -727,6 +731,11 @@ diskfs_dirempty(struct node *dp, error_t err; memobj = diskfs_get_filemap (dp, VM_PROT_READ); + + if (memobj == MACH_PORT_NULL) + /* XXX should reflect error properly */ + return 0; + buf = 0; err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, diff --git a/ufs/pager.c b/ufs/pager.c index afb34839..61695db6 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -569,6 +569,13 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot) diskfs_nref_light (np); upi->p = pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); + if (upi->p == 0) + { + diskfs_nrele_light (np); + free (upi); + spin_unlock (&node2pagelock); + return MACH_PORT_NULL; + } np->dn->fileinfo = upi; right = pager_get_port (np->dn->fileinfo->p); ports_port_deref (np->dn->fileinfo->p); diff --git a/ufs/sizes.c b/ufs/sizes.c index 84c2493d..5c3d12f0 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -1,5 +1,5 @@ /* File growth and truncation - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation This file is part of the GNU Hurd. @@ -104,10 +104,14 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); - poke_pages (obj, round_page (length), round_page (np->allocsize)); - mach_port_deallocate (mach_task_self (), obj); - pager_flush_some (upi->p, round_page (length), - np->allocsize - length, 1); + if (obj != MACH_PORT_NULL) + { + /* XXX should cope with errors from diskfs_get_filemap */ + poke_pages (obj, round_page (length), round_page (np->allocsize)); + mach_port_deallocate (mach_task_self (), obj); + pager_flush_some (upi->p, round_page (length), + np->allocsize - length, 1); + } ports_port_deref (upi->p); } @@ -400,6 +404,11 @@ block_extended (struct node *np, /* Map in this part of the file */ mapobj = diskfs_get_filemap (np, VM_PROT_WRITE | VM_PROT_READ); + + /* XXX Should cope with errors from diskfs_get_filemap and back + out the operation here. */ + assert (mapobj); + err = vm_map (mach_task_self (), &mapaddr, round_page (old_size), 0, 1, mapobj, lbn * sblock->fs_bsize, 0, VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0); @@ -477,6 +486,9 @@ diskfs_grow (struct node *np, /* This reference will ensure that NP->dn->fileinfo stays allocated. */ pagerpt = diskfs_get_filemap (np, VM_PROT_WRITE|VM_PROT_READ); + if (pagerpt == MACH_PORT_NULL) + return errno; + /* The new last block of the file. */ lbn = lblkno (sblock, end - 1); -- cgit v1.2.3 From 0d3ef933e246eb5279b84b2dff6615698428f4c3 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 20 Oct 1998 19:20:07 +0000 Subject: 1998-09-04 Roland McGrath * dir.c (diskfs_lookup_hard): Fix defn with `const'. (diskfs_direnter_hard): Likewise. (dirscanblock): Likewise. * inode.c (diskfs_create_symlink_hook, create_symlink_hook): Likewise. (diskfs_set_translator): Likewise. --- ufs/dir.c | 172 ++++++++++++++++++++++++++++++------------------------------ ufs/inode.c | 98 +++++++++++++++++----------------- 2 files changed, 135 insertions(+), 135 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index bdf84be6..01432829 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -64,8 +64,8 @@ struct dirstat /* Index of this directory block. */ int idx; - - /* For stat COMPRESS, this is the address (inside mapbuf) + + /* For stat COMPRESS, this is the address (inside mapbuf) of the first direct in the directory block to be compressed. */ /* For stat HERE_TIS, SHRINK, and TAKE, this is the entry referenced. */ struct directory_entry *entry; @@ -82,21 +82,21 @@ struct dirstat size_t diskfs_dirstat_size = sizeof (struct dirstat); /* Initialize DS such that diskfs_drop_dirstat will ignore it. */ -void +void diskfs_null_dirstat (struct dirstat *ds) { ds->type = LOOKUP; } -static error_t -dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, - int namelen, enum lookup_type type, struct dirstat *ds, - ino_t *inum); +static error_t +dirscanblock (vm_address_t blockoff, struct node *dp, int idx, + const char *name, int namelen, enum lookup_type type, + struct dirstat *ds, ino_t *inum); /* Implement the diskfs_lookup from the diskfs library. See for the interface specification. */ error_t -diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, +diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, struct node **npp, struct dirstat *ds, struct protid *cred) { error_t err; @@ -113,7 +113,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, int blockaddr; int idx, lastidx; int looped; - + if ((type == REMOVE) || (type == RENAME)) assert (npp); @@ -122,12 +122,12 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, spec_dotdot = type & SPEC_DOTDOT; type &= ~SPEC_DOTDOT; - + namelen = strlen (name); if (namelen > MAXNAMLEN) return ENAMETOOLONG; - + try_again: if (ds) { @@ -157,10 +157,10 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, mach_port_deallocate (mach_task_self (), memobj); inum = 0; - + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; - + /* Start the lookup at DP->dn->dir_idx. */ idx = dp->dn->dir_idx; if (idx * DIRBLKSIZ > dp->dn_stat.st_size) @@ -221,7 +221,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, goto out; } } - + /* We are looking up .. */ /* Check to see if this is the root of the filesystem. */ else if (dp->dn->number == 2) @@ -229,7 +229,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, err = EAGAIN; goto out; } - + /* We can't just do diskfs_cached_lookup, because we would then deadlock. So we do this. Ick. */ else if (retry_dotdot) @@ -263,11 +263,11 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, retry_dotdot = inum; goto try_again; } - + /* Here below are the spec dotdot cases. */ else if (type == RENAME || type == REMOVE) np = ifind (inum); - + else if (type == LOOKUP) { diskfs_nput (dp); @@ -278,7 +278,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, else assert (0); } - + if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ @@ -304,7 +304,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, ds->mapbuf = buf; ds->mapextent = buflen; } - + if (np) { assert (npp); @@ -338,8 +338,8 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, diskfs_lookup. If found, set *INUM to the inode number, else return ENOENT. */ static error_t -dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, - int namelen, enum lookup_type type, +dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, + const char *name, int namelen, enum lookup_type type, struct dirstat *ds, ino_t *inum) { int nfree = 0; @@ -351,7 +351,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, int looking = 0; int countcopies = 0; int consider_compress = 0; - + if (ds && (ds->stat == LOOKING || ds->stat == COMPRESS)) { @@ -365,11 +365,11 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, prevoff = currentoff, currentoff += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *)currentoff; - + if (!entry->d_reclen || read_disk_entry (entry->d_reclen) % 4 || DIRECT_NAMLEN (entry) > MAXNAMLEN - || (currentoff + read_disk_entry (entry->d_reclen) + || (currentoff + read_disk_entry (entry->d_reclen) > blockaddr + DIRBLKSIZ) || entry->d_name[DIRECT_NAMLEN (entry)] || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) @@ -379,16 +379,16 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } - + if (looking || countcopies) { int thisfree; - + /* Count how much free space this entry has in it. */ if (entry->d_ino == 0) thisfree = read_disk_entry (entry->d_reclen); else - thisfree = (read_disk_entry (entry->d_reclen) + thisfree = (read_disk_entry (entry->d_reclen) - DIRSIZ (DIRECT_NAMLEN (entry))); /* If this isn't at the front of the block, then it will @@ -396,9 +396,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, number of bytes there too. */ if (countcopies && currentoff != blockaddr) nbytes += DIRSIZ (DIRECT_NAMLEN (entry)); - + if (ds->stat == COMPRESS && nbytes > ds->nbytes) - /* The previously found compress is better than + /* The previously found compress is better than this one, so don't bother counting any more. */ countcopies = 0; @@ -415,9 +415,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, nfree += thisfree; if (nfree >= needed) consider_compress = 1; - } + } } - + if (entry->d_ino) nentries++; @@ -428,7 +428,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, break; } - if (consider_compress + if (consider_compress && (ds->type == LOOKING || (ds->type == COMPRESS && ds->nbytes > nbytes))) { @@ -438,7 +438,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, ds->idx = idx; ds->nbytes = nbytes; } - + if (currentoff >= blockaddr + DIRBLKSIZ) { int i; @@ -448,9 +448,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, down how many entries there were. */ if (!dp->dn->dirents) { - dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) + dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) * sizeof (int)); - for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) + for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; } /* Make sure the count is correct if there is one now. */ @@ -460,7 +460,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, return ENOENT; } - + /* We have found the required name. */ if (ds && type == CREATE) @@ -486,7 +486,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, the preceding lookup call, and only if that call returned ENOENT. */ error_t diskfs_direnter_hard(struct node *dp, - char *name, + const char *name, struct node *np, struct dirstat *ds, struct protid *cred) @@ -496,21 +496,21 @@ diskfs_direnter_hard(struct node *dp, int needed = DIRSIZ (namelen); int oldneeded; vm_address_t fromoff, tooff; - int totfreed; + int totfreed; error_t err; off_t oldsize = 0; assert (ds->type == CREATE); - + dp->dn_set_mtime = 1; switch (ds->stat) { case TAKE: /* We are supposed to consume this slot. */ - assert (ds->entry->d_ino == 0 + assert (ds->entry->d_ino == 0 && read_disk_entry (ds->entry->d_reclen) >= needed); - + write_disk_entry (ds->entry->d_ino, np->dn->number); DIRECT_NAMLEN (ds->entry) = namelen; if (direct_symlink_extension) @@ -518,27 +518,27 @@ diskfs_direnter_hard(struct node *dp, bcopy (name, ds->entry->d_name, namelen + 1); break; - + case SHRINK: /* We are supposed to take the extra space at the end of this slot. */ oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); assert (read_disk_entry (ds->entry->d_reclen) - oldneeded >= needed); - + new = (struct directory_entry *) ((vm_address_t) ds->entry + oldneeded); write_disk_entry (new->d_ino, np->dn->number); - write_disk_entry (new->d_reclen, + write_disk_entry (new->d_reclen, read_disk_entry (ds->entry->d_reclen) - oldneeded); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); - + write_disk_entry (ds->entry->d_reclen, oldneeded); - + break; - + case COMPRESS: /* We are supposed to move all the entries to the front of the block, giving each the minimum @@ -566,7 +566,7 @@ diskfs_direnter_hard(struct node *dp, totfreed = (vm_address_t) ds->entry + DIRBLKSIZ - tooff; assert (totfreed >= needed); - + new = (struct directory_entry *) tooff; write_disk_entry (new->d_ino, np->dn->number); write_disk_entry (new->d_reclen, totfreed); @@ -579,7 +579,7 @@ diskfs_direnter_hard(struct node *dp, case EXTEND: /* Extend the file. */ assert (needed <= DIRBLKSIZ); - + oldsize = dp->dn_stat.st_size; while (oldsize + DIRBLKSIZ > dp->allocsize) { @@ -603,7 +603,7 @@ diskfs_direnter_hard(struct node *dp, new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; - + default: assert (0); } @@ -611,10 +611,10 @@ diskfs_direnter_hard(struct node *dp, dp->dn_set_mtime = 1; vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - + if (ds->stat != EXTEND) { - /* If we are keeping count of this block, then keep the count up + /* If we are keeping count of this block, then keep the count up to date. */ if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) dp->dn->dirents[ds->idx]++; @@ -626,10 +626,10 @@ diskfs_direnter_hard(struct node *dp, anything at all. */ if (dp->dn->dirents) { - dp->dn->dirents = realloc (dp->dn->dirents, + dp->dn->dirents = realloc (dp->dn->dirents, (dp->dn_stat.st_size / DIRBLKSIZ * sizeof (int))); - for (i = oldsize / DIRBLKSIZ; + for (i = oldsize / DIRBLKSIZ; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; @@ -638,14 +638,14 @@ diskfs_direnter_hard(struct node *dp, } else { - dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ + dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ * sizeof (int)); for (i = 0; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; dp->dn->dirents[ds->idx] = 1; } } - + diskfs_file_update (dp, 1); return 0; @@ -662,7 +662,7 @@ diskfs_dirremove_hard(struct node *dp, { assert (ds->type == REMOVE); assert (ds->stat == HERE_TIS); - + dp->dn_set_mtime = 1; if (ds->preventry == 0) @@ -671,7 +671,7 @@ diskfs_dirremove_hard(struct node *dp, { assert ((vm_address_t) ds->entry - (vm_address_t) ds->preventry == read_disk_entry (ds->preventry->d_reclen)); - write_disk_entry (ds->preventry->d_reclen, + write_disk_entry (ds->preventry->d_reclen, (read_disk_entry (ds->preventry->d_reclen) + read_disk_entry (ds->entry->d_reclen))); } @@ -684,27 +684,27 @@ diskfs_dirremove_hard(struct node *dp, to date. */ if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) dp->dn->dirents[ds->idx]--; - + diskfs_file_update (dp, 1); return 0; } - + /* Following a lookup call for RENAME, this changes the inode number - on a directory entry. DP is the directory being changed; NP is - the new node being linked in; DP is the cached information returned + on a directory entry. DP is the directory being changed; NP is + the new node being linked in; DP is the cached information returned by lookup. This call is only valid if the directory has been locked continuously since the call to lookup, and only if that call succeeded. */ error_t -diskfs_dirrewrite_hard(struct node *dp, +diskfs_dirrewrite_hard(struct node *dp, struct node *np, struct dirstat *ds) { assert (ds->type == RENAME); assert (ds->stat == HERE_TIS); - + dp->dn_set_mtime = 1; write_disk_entry (ds->entry->d_ino, np->dn->number); if (direct_symlink_extension) @@ -712,7 +712,7 @@ diskfs_dirrewrite_hard(struct node *dp, dp->dn_set_mtime = 1; vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - + diskfs_file_update (dp, 1); return 0; @@ -737,7 +737,7 @@ diskfs_dirempty(struct node *dp, return 0; buf = 0; - + err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, 1, memobj, 0, 0, VM_PROT_READ, VM_PROT_READ, 0); mach_port_deallocate (mach_task_self (), memobj); @@ -746,7 +746,7 @@ diskfs_dirempty(struct node *dp, if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; - for (curoff = buf; + for (curoff = buf; curoff < buf + dp->dn_stat.st_size; curoff += read_disk_entry (entry->d_reclen)) { @@ -766,7 +766,7 @@ diskfs_dirempty(struct node *dp, return 0; } } - if (!diskfs_check_readonly ()) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); @@ -802,12 +802,12 @@ count_dirents (struct node *dp, int nb, char *buf) assert (dp->dn->dirents); assert ((nb + 1) * DIRBLKSIZ <= dp->dn_stat.st_size); - + err = diskfs_node_rdwr (dp, buf, nb * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &amt); if (err) return err; assert (amt == DIRBLKSIZ); - + for (offinblk = buf; offinblk < buf + DIRBLKSIZ; offinblk += read_disk_entry (entry->d_reclen)) @@ -816,7 +816,7 @@ count_dirents (struct node *dp, int nb, char *buf) if (entry->d_ino) count++; } - + assert (dp->dn->dirents[nb] == -1 || dp->dn->dirents[nb] == count); dp->dn->dirents[nb] = count; return 0; @@ -825,8 +825,8 @@ count_dirents (struct node *dp, int nb, char *buf) /* Implement the disikfs_get_directs callback as described in . */ error_t -diskfs_get_directs (struct node *dp, - int entry, +diskfs_get_directs (struct node *dp, + int entry, int nentries, char **data, u_int *datacnt, @@ -846,7 +846,7 @@ diskfs_get_directs (struct node *dp, int allocsize; int checklen; struct dirent *userp; - + nblks = dp->dn_stat.st_size/DIRBLKSIZ; if (!dp->dn->dirents) @@ -864,7 +864,7 @@ diskfs_get_directs (struct node *dp, if (allocsize > *datacnt) vm_allocate (mach_task_self (), (vm_address_t *) data, allocsize, 1); - + /* Scan through the entries to find ENTRY. If we encounter a -1 in the process then stop to fill it. When we run off the end, ENTRY is too big. */ @@ -885,10 +885,10 @@ diskfs_get_directs (struct node *dp, break; curentry += dp->dn->dirents[blkno]; - + bufvalid = 0; } - + if (blkno == nblks) { *datacnt = 0; @@ -911,15 +911,15 @@ diskfs_get_directs (struct node *dp, assert (checklen == DIRBLKSIZ); bufvalid = 1; } - for (i = 0, bufp = buf; - i < entry - curentry && bufp - buf < DIRBLKSIZ; + for (i = 0, bufp = buf; + i < entry - curentry && bufp - buf < DIRBLKSIZ; (bufp - += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), + += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), i++) ; /* Make sure we didn't run off the end. */ assert (bufp - buf < DIRBLKSIZ); - } + } i = 0; datap = *data; @@ -931,7 +931,7 @@ diskfs_get_directs (struct node *dp, { if (!bufvalid) { - err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, + err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &checklen); if (err) return err; @@ -962,17 +962,17 @@ diskfs_get_directs (struct node *dp, bufvalid = 0; } } - + /* We've copied all we can. If we allocated our own array but didn't fill all of it, then free whatever memory we didn't use. */ if (allocsize > *datacnt) { if (round_page (datap - *data) < allocsize) - vm_deallocate (mach_task_self (), + vm_deallocate (mach_task_self (), (vm_address_t) (*data + round_page (datap - *data)), allocsize - round_page (datap - *data)); } - + /* Set variables for return */ *datacnt = datap - *data; *amt = i; diff --git a/ufs/inode.c b/ufs/inode.c index fe5abbb9..658d6187 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,5 @@ /* Inode management routines - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -44,9 +44,9 @@ inode_init () nodehash[n] = 0; } -/* Fetch inode INUM, set *NPP to the node structure; +/* Fetch inode INUM, set *NPP to the node structure; gain one user reference and lock the node. */ -error_t +error_t diskfs_cached_lookup (int inum, struct node **npp) { struct disknode *dn; @@ -88,7 +88,7 @@ diskfs_cached_lookup (int inum, struct node **npp) spin_unlock (&diskfs_node_refcnt_lock); err = read_disknode (np); - + if (!diskfs_check_readonly () && !np->dn_stat.st_gen) { spin_lock (&gennumberlock); @@ -98,7 +98,7 @@ diskfs_cached_lookup (int inum, struct node **npp) spin_unlock (&gennumberlock); np->dn_set_ctime = 1; } - + if (err) return err; else @@ -114,13 +114,13 @@ struct node * ifind (ino_t inum) { struct node *np; - + spin_lock (&diskfs_node_refcnt_lock); for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) { if (np->dn->number != inum) continue; - + assert (np->references); spin_unlock (&diskfs_node_refcnt_lock); return np; @@ -130,7 +130,7 @@ ifind (ino_t inum) /* The last reference to a node has gone away; drop it from the hash table and clean all state in the dn structure. */ -void +void diskfs_node_norefs (struct node *np) { *np->dn->hprevp = np->dn->hnext; @@ -158,7 +158,7 @@ diskfs_lost_hardrefs (struct node *np) #ifdef notanymore struct port_info *pi; struct pager *p; - + /* Check and see if there is a pager which has only one reference (ours). If so, then drop that reference, breaking the cycle. The complexity in this routine @@ -170,17 +170,17 @@ diskfs_lost_hardrefs (struct node *np) pi = (struct port_info *) np->dn->fileinfo->p; if (pi->refcnt == 1) { - + /* The only way to get a new reference to the pager in this state is to call diskfs_get_filemap; this can't happen as long as we hold NP locked. So we can safely unlock _libports_portrefcntlock for the following call. */ spin_unlock (&_libports_portrefcntlock); - + /* Right now the node is locked with no hard refs; this is an anomolous situation. Before messing with - the reference count on the file pager, we have to + the reference count on the file pager, we have to give ourselves a reference back so that we are really allowed to hold the lock. Then we can do the unreference. */ @@ -216,7 +216,7 @@ read_disknode (struct node *np) struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; - + err = diskfs_catch_exception (); if (err) return err; @@ -232,7 +232,7 @@ read_disknode (struct node *np) st->st_ino = np->dn->number; st->st_gen = read_disk_entry (di->di_gen); st->st_rdev = read_disk_entry(di->di_rdev); - st->st_mode = (((read_disk_entry (di->di_model) + st->st_mode = (((read_disk_entry (di->di_model) | (read_disk_entry (di->di_modeh) << 16)) & ~S_ITRANS) | (di->di_trans ? S_IPTRANS : 0)); @@ -249,11 +249,11 @@ read_disknode (struct node *np) st->st_mtime_usec = read_disk_entry (di->di_mtime.tv_nsec) / 1000; st->st_ctime = read_disk_entry (di->di_ctime.tv_sec); st->st_ctime_usec = read_disk_entry (di->di_ctime.tv_nsec) / 1000; -#endif +#endif st->st_blksize = sblock->fs_bsize; st->st_blocks = read_disk_entry (di->di_blocks); st->st_flags = read_disk_entry (di->di_flags); - + if (sblock->fs_inodefmt < FS_44INODEFMT) { st->st_uid = read_disk_entry (di->di_ouid); @@ -274,8 +274,8 @@ read_disknode (struct node *np) if (!S_ISBLK (st->st_mode) && !S_ISCHR (st->st_mode)) st->st_rdev = 0; - if (S_ISLNK (st->st_mode) - && direct_symlink_extension + if (S_ISLNK (st->st_mode) + && direct_symlink_extension && st->st_size < sblock->fs_maxsymlinklen) np->allocsize = 0; else @@ -319,7 +319,7 @@ write_node (struct node *np) struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; - + assert (!np->dn_set_ctime && !np->dn_set_atime && !np->dn_set_mtime); if (np->dn_stat_dirty) { @@ -328,9 +328,9 @@ write_node (struct node *np) err = diskfs_catch_exception (); if (err) return; - + write_disk_entry (di->di_gen, st->st_gen); - + if (S_ISBLK (st->st_mode) || S_ISCHR (st->st_mode)) write_disk_entry (di->di_rdev, st->st_rdev); @@ -343,7 +343,7 @@ write_node (struct node *np) write_disk_entry (di->di_model, mode & 0xffff); write_disk_entry (di->di_modeh, (mode >> 16) & 0xffff); } - else + else { write_disk_entry (di->di_model, st->st_mode & 0xffff & ~S_ITRANS); di->di_modeh = 0; @@ -354,7 +354,7 @@ write_node (struct node *np) write_disk_entry (di->di_uid, st->st_uid); write_disk_entry (di->di_gid, st->st_gid); } - + if (sblock->fs_inodefmt < FS_44INODEFMT) { write_disk_entry (di->di_ouid, st->st_uid & 0xffff); @@ -376,38 +376,38 @@ write_node (struct node *np) write_disk_entry (di->di_mtime.tv_nsec, st->st_mtime_usec * 1000); write_disk_entry (di->di_ctime.tv_sec, st->st_ctime); write_disk_entry (di->di_ctime.tv_nsec, st->st_ctime_usec * 1000); -#endif +#endif write_disk_entry (di->di_blocks, st->st_blocks); write_disk_entry (di->di_flags, st->st_flags); - + diskfs_end_catch_exception (); np->dn_stat_dirty = 0; record_poke (di, sizeof (struct dinode)); } -} +} /* See if we should create a symlink by writing it directly into the block pointer array. Returning EINVAL tells diskfs to do it the usual way. */ static error_t -create_symlink_hook (struct node *np, char *target) +create_symlink_hook (struct node *np, const char *target) { int len = strlen (target); error_t err; struct dinode *di; - + if (!direct_symlink_extension) return EINVAL; - + assert (compat_mode != COMPAT_BSD42); if (len >= sblock->fs_maxsymlinklen) return EINVAL; - + err = diskfs_catch_exception (); if (err) return err; - + di = dino (np->dn->number); bcopy (target, di->di_shortlink, len); np->dn_stat.st_size = len; @@ -418,25 +418,25 @@ create_symlink_hook (struct node *np, char *target) diskfs_end_catch_exception (); return 0; } -error_t (*diskfs_create_symlink_hook)(struct node *, char *) +error_t (*diskfs_create_symlink_hook)(struct node *, const char *) = create_symlink_hook; /* Check if this symlink is stored directly in the block pointer array. Returning EINVAL tells diskfs to do it the usual way. */ -static error_t +static error_t read_symlink_hook (struct node *np, char *buf) { error_t err; - - if (!direct_symlink_extension + + if (!direct_symlink_extension || np->dn_stat.st_size >= sblock->fs_maxsymlinklen) return EINVAL; err = diskfs_catch_exception (); if (err) return err; - + bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); if (! diskfs_check_readonly ()) @@ -456,7 +456,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) struct item *i; error_t err; int n; - + /* Acquire a reference on all the nodes in the hash table and enter them into a list on the stack. */ spin_lock (&diskfs_node_refcnt_lock); @@ -496,10 +496,10 @@ write_all_disknodes () write_node (np); return 0; } - + diskfs_node_iterate (helper); } - + void diskfs_write_disknode (struct node *np, int wait) { @@ -530,7 +530,7 @@ diskfs_set_statfs (struct statfs *st) /* Implement the diskfs_set_translator callback from the diskfs library; see for the interface description. */ error_t -diskfs_set_translator (struct node *np, char *name, u_int namelen, +diskfs_set_translator (struct node *np, const char *name, u_int namelen, struct protid *cred) { daddr_t blkno; @@ -547,10 +547,10 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, err = diskfs_catch_exception (); if (err) return err; - + di = dino (np->dn->number); blkno = read_disk_entry (di->di_trans); - + if (namelen && !blkno) { /* Allocate block for translator */ @@ -574,7 +574,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, np->dn_stat.st_mode &= ~S_IPTRANS; np->dn_set_ctime = 1; } - + if (namelen) { bcopy (&namelen, buf, sizeof (u_int)); @@ -586,7 +586,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, np->dn_stat.st_mode |= S_IPTRANS; np->dn_set_ctime = 1; } - + diskfs_end_catch_exception (); return err; } @@ -608,7 +608,7 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) blkno = read_disk_entry ((dino (np->dn->number))->di_trans); assert (blkno); transloc = disk_image + fsaddr (sblock, blkno); - + datalen = *(u_int *)transloc; *namep = malloc (datalen); bcopy (transloc + sizeof (u_int), *namep, datalen); @@ -649,13 +649,13 @@ diskfs_S_file_get_storage_info (struct protid *cred, struct store *file_store; struct store_run runs[NDADDR]; size_t num_runs = 0; - + if (! cred) return EOPNOTSUPP; np = cred->po->np; mutex_lock (&np->lock); - + /* See if this file fits in the direct block pointers. If not, punt for now. (Reading indir blocks is a pain, and I'm postponing pain.) XXX */ @@ -679,7 +679,7 @@ diskfs_S_file_get_storage_info (struct protid *cred, for (i = 0; i < NDADDR; i++) { off_t start = fsbtodb (sblock, read_disk_entry (di->di_db[i])); - off_t length = + off_t length = (((i + 1) * sblock->fs_bsize > np->allocsize) ? np->allocsize - i * sblock->fs_bsize : sblock->fs_bsize); @@ -694,7 +694,7 @@ diskfs_S_file_get_storage_info (struct protid *cred, diskfs_end_catch_exception (); mutex_unlock (&np->lock); - + if (! err) err = store_clone (store, &file_store); if (! err) -- cgit v1.2.3 From e818daa7d08698dd88b0f52a2fc8faffd8b3c279 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 20 Oct 1998 21:19:27 +0000 Subject: . --- ufs/ChangeLog | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 3a225552..e4f3ce9d 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,10 +1,18 @@ +1998-09-04 Roland McGrath + + * dir.c (diskfs_lookup_hard): Fix defn with `const'. + (diskfs_direnter_hard): Likewise. + (dirscanblock): Likewise. + * inode.c (diskfs_create_symlink_hook, create_symlink_hook): Likewise. + (diskfs_set_translator): Likewise. + Wed Aug 20 14:34:24 1997 Thomas Bushnell, n/BSG * dir.c (diskfs_lookup_hard): Cope with error return from - diskfs_get_filemap. + diskfs_get_filemap. * sizes.c (diskfs_grow): Likewise. * dir.c (diskfs_dirempty): Cope (poorly) with error return from - diskfs_get_filemap. + diskfs_get_filemap. * sizes.c (diskfs_truncate): Likewise. (block_extended): Likewise. @@ -53,14 +61,14 @@ Mon Nov 18 17:10:00 1996 Miles Bader Sat Nov 16 17:21:40 1996 Thomas Bushnell, n/BSG - * inode.c (diskfs_S_fsys_getfile): Delete var `fakecred'. + * inode.c (diskfs_S_fsys_getfile): Delete var `fakecred'. diskfs_access -> fshelp_access. * alloc.c (ffs_alloc): diskfs_isuid -> idvec_contains. (ffs_realloccg): Likewise. Thu Nov 14 16:43:36 1996 Thomas Bushnell, n/BSG - * inode.c (diskfs_S_file_getfh): diskfs_isuid -> idvec_contains. + * inode.c (diskfs_S_file_getfh): diskfs_isuid -> idvec_contains. (diskfs_S_fsys_getfile): Use idvecs and iousers. Thu Oct 24 16:07:17 1996 Miles Bader @@ -157,21 +165,21 @@ Fri Sep 6 16:00:42 1996 Thomas Bushnell, n/BSG * consts.c: Include . (diskfs_major_version, diskfs_minor_version, diskfs_edit_version): - Deleted variables. + Deleted variables. (diskfs_server_version): New variable. Thu Aug 29 16:07:07 1996 Thomas Bushnell, n/BSG * dir.c (diskfs_lookup_hard): When setting ds->stat to EXTEND, set ds->idx by looking at the size of the file. (IDX itself is no - longer at the end because of the change on Aug 16 1996.) + longer at the end because of the change on Aug 16 1996.) Wed Aug 28 12:15:15 1996 Thomas Bushnell, n/BSG * dir.c (dirscanblock): Size dirents correctly when mallocing it. (diskfs_direnter_hard): Be more careful when sizing or resizing dirents. Correctly set to -1 all the new entries we create after - realloc call. + realloc call. Fri Aug 16 18:51:31 1996 Thomas Bushnell, n/BSG @@ -192,10 +200,10 @@ Wed Aug 7 13:00:30 1996 Thomas Bushnell, n/BSG bsize to be fs_fsize, not fs_bsize. * hyper.c (diskfs_set_hypermetadata): Return an error as - appropriate. - + appropriate. + * inode.c (struct ufs_fhandle): Layout filehandle more like Unixy - NFSD. + NFSD. (diskfs_S_file_getfh): Bother to clear unused parts of a file handle so that they always compare equal. @@ -296,8 +304,8 @@ Mon May 6 14:23:54 1996 Michael I. Bushnell, p/BSG Fri May 3 09:15:33 1996 Michael I. Bushnell, p/BSG * sizes.c (block_extended): Rewrite code that moves pages - to be more efficient, and not deadlock too, using unlocked - pagein permission feature (read "hack"). Return value + to be more efficient, and not deadlock too, using unlocked + pagein permission feature (read "hack"). Return value now indicates whether we expect a sync. (diskfs_grow): If a call to block_extended returns nonzero, then sync the file before returning. @@ -339,9 +347,9 @@ Wed Apr 24 14:05:48 1996 Michael I. Bushnell, p/BSG case where it was written on a little endian machine without the extension. (DIRECT_NAMLEN) [LITTLE_ENDIAN]: Deal with case correctly where it - was written without the extension on a big endian machine. + was written without the extension on a big endian machine. * dir.c (dirscanblock): Use read/write_disk_entry when reading or - writing fields from directory entries. + writing fields from directory entries. (diskfs_direnter_hard): Likewise. (diskfs_dirremove_hard): Likewise. (diskfs_dirrewrite_hard): Likewise. @@ -363,8 +371,8 @@ Tue Apr 23 11:28:42 1996 Michael I. Bushnell, p/BSG (swab_short, swab_long, swab_long_long): New functions. (read_disk_entry, write_disk_entry): New macros. * alloc.c (ffs_realloccg): Use read/write_disk_entry when - reading/writing on-disk inode fields. - * bmap.c (fetch_indir_spec): Likewise. + reading/writing on-disk inode fields. + * bmap.c (fetch_indir_spec): Likewise. * inode.c (read_disknode): Likewise. (write_node): Likewise. (diskfs_set_translator): Likewise. @@ -380,11 +388,11 @@ Tue Apr 23 11:28:42 1996 Michael I. Bushnell, p/BSG (diskfs_grow): Likewise. * pager.c (pager_unlock_page): Likewise. * alloc.c: Include - (ffs_blkpref): Use read_disk_entry when reading from BAP array. + (ffs_blkpref): Use read_disk_entry when reading from BAP array. (swab_cg, read_cg, release_cg): New functions. (ffs_fragextend, ffs_alloccg, ffs_nodealloccg, ffs_blkfree, - diskfs_free_node): Use new cg access functions. - + diskfs_free_node): Use new cg access functions. + Thu Apr 18 14:50:30 1996 Michael I. Bushnell, p/BSG * sizes.c (diskfs_grow): New variable `pagerpt'. @@ -439,7 +447,7 @@ Fri Mar 22 23:43:53 1996 Miles Bader Wed Mar 20 14:36:31 1996 Michael I. Bushnell, p/BSG * dir.c (diskfs_lookup_hard): Don't do initial or final permission - checking here. + checking here. * dir.c (diskfs_dirrewrite_hard): Renamed from diskfs_dirrewrite. No longer call modification tracking routines. (diskfs_dirremove_hard): Renamed from diskfs_dirremove. No longer call @@ -454,7 +462,7 @@ Mon Mar 18 19:50:41 1996 Miles Bader Mon Mar 18 12:33:06 1996 Michael I. Bushnell, p/BSG - * pager.c (diskfs_max_user_pager_prot) [add_pager_max_prot]: + * pager.c (diskfs_max_user_pager_prot) [add_pager_max_prot]: (a == b) ? 1 : 0 ====> (a == b). Fri Feb 23 15:27:05 1996 Roland McGrath @@ -1795,4 +1803,3 @@ Thu May 5 19:06:54 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) Thu May 5 07:39:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) * Makefile ($(OBJS)): Use $(includedir) instead of $(headers) in deps. - -- cgit v1.2.3 From d2d38a4c423435d8b8fea4630d484cd1dab01bab Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 20 Dec 1998 20:51:02 +0000 Subject: 1998-12-20 Roland McGrath * alloc.c (diskfs_alloc_node): Fix printf format to silence warning. * hyper.c (get_hypermetadata): Likewise. --- ufs/alloc.c | 86 ++++++++++++++++++++++++++++++------------------------------- ufs/hyper.c | 16 ++++++------ 2 files changed, 51 insertions(+), 51 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index ac72c928..e76b7703 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -1,5 +1,5 @@ /* Disk allocation routines - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1993, 94, 95, 96, 98 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -8,7 +8,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. -The GNU Hurd is distributed in the hope that it will be useful, +The GNU Hurd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -67,7 +67,7 @@ extern u_long nextgennumber; spin_lock_t alloclock = SPIN_LOCK_INITIALIZER; /* Forward declarations */ -static u_long ffs_hashalloc (struct node *, int, long, int, +static u_long ffs_hashalloc (struct node *, int, long, int, u_long (*)(struct node *, int, daddr_t, int)); static u_long ffs_alloccg (struct node *, int, daddr_t, int); static daddr_t ffs_fragextend (struct node *, int, long, int, int); @@ -96,7 +96,7 @@ void swab_cg (struct cg *cg) { int i, j; - + if (swab_long (cg->cg_magic) == CG_MAGIC || cg->cg_magic == CG_MAGIC) { @@ -125,12 +125,12 @@ swab_cg (struct cg *cg) /* blktot map */ for (i = 0; i < cg->cg_ncyl; i++) cg_blktot(cg)[i] = swab_long (cg_blktot(cg)[i]); - + /* blks map */ for (i = 0; i < cg->cg_ncyl; i++) for (j = 0; j < sblock->fs_nrpos; j++) cg_blks(sblock, cg, i)[j] = swab_short (cg_blks (sblock, cg, i)[j]); - + for (i = 0; i < sblock->fs_contigsumsize; i++) cg_clustersum(cg)[i] = swab_long (cg_clustersum(cg)[i]); @@ -140,11 +140,11 @@ swab_cg (struct cg *cg) { /* Old format cylinder group... */ struct ocg *ocg = (struct ocg *) cg; - + if (swab_long (ocg->cg_magic) != CG_MAGIC && ocg->cg_magic != CG_MAGIC) return; - + ocg->cg_time = swab_long (ocg->cg_time); ocg->cg_cgx = swab_long (ocg->cg_cgx); ocg->cg_ncyl = swab_short (ocg->cg_ncyl); @@ -176,7 +176,7 @@ int read_cg (int cg, struct cg **cgpp) { struct cg *diskcg = cg_locate (cg); - + if (swab_disk) { *cgpp = malloc (sblock->fs_cgsize); @@ -205,7 +205,7 @@ release_cg (struct cg *cgp) /* * Allocate a block in the file system. - * + * * The size of the requested block is given, which must be some * multiple of fs_fsize and <= fs_bsize. * A preference may be optionally specified. If a preference is given @@ -224,7 +224,7 @@ release_cg (struct cg *cgp) */ error_t ffs_alloc(register struct node *np, - daddr_t lbn, + daddr_t lbn, daddr_t bpref, int size, daddr_t *bnp, @@ -233,7 +233,7 @@ ffs_alloc(register struct node *np, register struct fs *fs; daddr_t bno; int cg; - + *bnp = 0; fs = sblock; #ifdef DIAGNOSTIC @@ -297,7 +297,7 @@ error_t ffs_realloccg(register struct node *np, daddr_t lbprev, volatile daddr_t bpref, - int osize, + int osize, int nsize, daddr_t *pbn, struct protid *cred) @@ -306,7 +306,7 @@ ffs_realloccg(register struct node *np, int cg, error; volatile int request; daddr_t bprev, bno; - + *pbn = 0; fs = sblock; #ifdef DIAGNOSTIC @@ -322,8 +322,8 @@ ffs_realloccg(register struct node *np, #endif /* DIAGNOSTIC */ spin_lock (&alloclock); - - if (!idvec_contains (cred->user->uids, 0) + + if (!idvec_contains (cred->user->uids, 0) && freespace(fs, fs->fs_minfree) <= 0) goto nospace; error = diskfs_catch_exception (); @@ -378,8 +378,8 @@ ffs_realloccg(register struct node *np, switch ((int)fs->fs_optim) { case FS_OPTSPACE: /* - * Allocate an exact sized fragment. Although this makes - * best use of space, we will waste time relocating it if + * Allocate an exact sized fragment. Although this makes + * best use of space, we will waste time relocating it if * the file continues to grow. If the fragmentation is * less than half of the minimum free reserve, we choose * to begin optimizing for time. @@ -419,7 +419,7 @@ ffs_realloccg(register struct node *np, bno = (daddr_t)ffs_hashalloc(np, cg, (long)bpref, request, (u_long (*)())ffs_alloccg); if (bno > 0) { -#if 0 /* Not necessary in GNU Hurd ufs */ +#if 0 /* Not necessary in GNU Hurd ufs */ bp->b_blkno = fsbtodb(fs, bno); (void) vnode_pager_uncache(ITOV(ip)); #endif @@ -585,7 +585,7 @@ ffs_reallocblks(ap) * Next we must write out the modified inode and indirect blocks. * For strict correctness, the writes should be synchronous since * the old block values may have been written to disk. In practise - * they are almost never written, but if we are concerned about + * they are almost never written, but if we are concerned about * strict correctness, the `doasyncfree' flag should be set to zero. * * The test on `doasyncfree' should be changed to test a flag @@ -631,7 +631,7 @@ fail: /* * Allocate an inode in the file system. - * + * * If allocating a directory, use ffs_dirpref to select the inode. * If allocating in a directory, the following hierarchy is followed: * 1) allocate the preferred inode. @@ -644,7 +644,7 @@ fail: * 2) quadradically rehash into other cylinder groups, until an * available inode is located. */ -/* This is now the diskfs_alloc_node callback from the diskfs library +/* This is now the diskfs_alloc_node callback from the diskfs library (described in ). It used to be ffs_valloc in BSD. */ error_t diskfs_alloc_node (struct node *dir, @@ -656,7 +656,7 @@ diskfs_alloc_node (struct node *dir, ino_t ino, ipref; int cg, error; int sex; - + fs = sblock; @@ -685,7 +685,7 @@ diskfs_alloc_node (struct node *dir, assert ("duplicate allocation" && !np->dn_stat.st_mode); assert (! (np->dn_stat.st_mode & S_IPTRANS)); if (np->dn_stat.st_blocks) { - printf("free inode %d had %d blocks\n", + printf("free inode %d had %ld blocks\n", ino, np->dn_stat.st_blocks); np->dn_stat.st_blocks = 0; np->dn_set_ctime = 1; @@ -700,7 +700,7 @@ diskfs_alloc_node (struct node *dir, nextgennumber = sex; np->dn_stat.st_gen = nextgennumber; spin_unlock (&gennumberlock); - + *npp = np; alloc_sync (np); return (0); @@ -739,7 +739,7 @@ ffs_dirpref(register struct fs *fs) * Select the desired position for the next block in a file. The file is * logically divided into sections. The first section is composed of the * direct blocks. Each additional section contains fs_maxbpg blocks. - * + * * If no blocks have been allocated in the first section, the policy is to * request a block in the same cylinder group as the inode that describes * the file. If no blocks have been allocated in any other section, the @@ -753,7 +753,7 @@ ffs_dirpref(register struct fs *fs) * indirect block, the information on the previous allocation is unavailable; * here a best guess is made based upon the logical block number being * allocated. - * + * * If a section is already partially allocated, the policy is to * contiguously allocate fs_maxcontig blocks. The end of one of these * contiguous blocks and the beginning of the next is physically separated @@ -786,10 +786,10 @@ ffs_blkpref(struct node *np, */ if (indx == 0 || bap[indx - 1] == 0) startcg = - (ino_to_cg(fs, np->dn->number) + (ino_to_cg(fs, np->dn->number) + lbn / fs->fs_maxbpg); else - startcg = dtog(fs, + startcg = dtog(fs, read_disk_entry (bap[indx - 1])) + 1; startcg %= fs->fs_ncg; avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg; @@ -892,14 +892,14 @@ ffs_hashalloc(struct node *np, /* * Determine whether a fragment can be extended. * - * Check to see if the necessary fragments are available, and + * Check to see if the necessary fragments are available, and * if they are, allocate them. */ static daddr_t ffs_fragextend(struct node *np, int cg, long bprev, - int osize, + int osize, int nsize) { register struct fs *fs; @@ -1016,7 +1016,7 @@ ffs_alloccg(struct node *np, bno = ffs_alloccgblk(fs, cgp, bpref); /* bdwrite(bp); */ if (releasecg) - release_cg (cgp); + release_cg (cgp); return (bno); } /* @@ -1030,7 +1030,7 @@ ffs_alloccg(struct node *np, break; if (allocsiz == fs->fs_frag) { /* - * no fragments were available, so a block will be + * no fragments were available, so a block will be * allocated, and hacked up */ if (cgp->cg_cs.cs_nbfree == 0) { @@ -1049,7 +1049,7 @@ ffs_alloccg(struct node *np, csum[cg].cs_nffree += i; fs->fs_fmod = 1; cgp->cg_frsum[i]++; - + if (releasecg) release_cg (cgp); record_poke (cgp, sblock->fs_cgsize); @@ -1127,7 +1127,7 @@ ffs_alloccgblk(register struct fs *fs, /* * Block layout information is not available. * Leaving bpref unchanged means we take the - * next available free block following the one + * next available free block following the one * we just allocated. Hopefully this will at * least hit a track cache on drives of unknown * geometry (e.g. SCSI). @@ -1135,7 +1135,7 @@ ffs_alloccgblk(register struct fs *fs, goto norot; } /* - * check the summary information to see if a block is + * check the summary information to see if a block is * available in the requested cylinder starting at the * requested rotational position and proceeding around. */ @@ -1285,7 +1285,7 @@ fail: brelse(bp); return (0); } -#endif +#endif /* * Determine whether an inode can be allocated. @@ -1377,7 +1377,7 @@ gotit: * Free a block or fragment. * * The specified block or fragment is placed back in the - * free map. If a fragment is deallocated, a possible + * free map. If a fragment is deallocated, a possible * block reassembly is checked. */ void @@ -1409,7 +1409,7 @@ ffs_blkfree(register struct node *np, cgp = (struct cg *)bp->b_data; #else releasecg = read_cg (cg, &cgp); -#endif +#endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ if (releasecg) @@ -1484,7 +1484,7 @@ ffs_blkfree(register struct node *np, * * The specified inode is placed back in the free map. */ -/* Implement diskfs call back diskfs_free_node (described in +/* Implement diskfs call back diskfs_free_node (described in . This was called ffs_vfree in BSD. */ void diskfs_free_node (struct node *np, mode_t mode) @@ -1508,11 +1508,11 @@ diskfs_free_node (struct node *np, mode_t mode) cgp = (struct cg *)bp->b_data; #else releasecg = read_cg (cg, &cgp); -#endif +#endif if (!cg_chkmagic(cgp)) { /* brelse(bp); */ if (releasecg) - release_cg (cgp); + release_cg (cgp); return; } cgp->cg_time = diskfs_mtime->seconds; @@ -1687,7 +1687,7 @@ ffs_clusteracct(struct fs *fs, #if 0 /* * Fserr prints the name of a file system with an error diagnostic. - * + * * The form of the error message is: * fs: error message */ diff --git a/ufs/hyper.c b/ufs/hyper.c index 500934eb..2a43bfed 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -1,5 +1,5 @@ /* Fetching and storing the hypermetadata (superblock and cg summary info). - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 95, 96, 97, 98 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -34,7 +34,7 @@ void swab_sblock (struct fs *sblock) { int i, j; - + sblock->fs_sblkno = swab_long (sblock->fs_sblkno); sblock->fs_cblkno = swab_long (sblock->fs_cblkno); sblock->fs_iblkno = swab_long (sblock->fs_iblkno); @@ -108,24 +108,24 @@ swab_sblock (struct fs *sblock) else for (i = 0; i < sblock->fs_cpc; i++) for (j = 0; j < sblock->fs_nrpos; j++) - fs_postbl(sblock, j)[i] + fs_postbl(sblock, j)[i] = swab_short (fs_postbl (sblock, j)[i]); /* The rot table is all chars */ } - + void swab_csums (struct csum *csum) { int i; - + for (i = 0; i < sblock->fs_ncg; i++) { csum[i].cs_ndir = swab_long (csum[i].cs_ndir); csum[i].cs_nbfree = swab_long (csum[i].cs_nbfree); csum[i].cs_nifree = swab_long (csum[i].cs_nifree); csum[i].cs_nffree = swab_long (csum[i].cs_nffree); - } + } } void @@ -252,7 +252,7 @@ get_hypermetadata (void) if (store->size < sblock->fs_size * sblock->fs_fsize) { fprintf (stderr, - "Disk size (%Zd) less than necessary " + "Disk size (%ld) less than necessary " "(superblock says we need %ld)\n", store->size, sblock->fs_size * sblock->fs_fsize); exit (1); @@ -315,7 +315,7 @@ diskfs_set_hypermetadata (int wait, int clean) } vm_deallocate (mach_task_self (), (vm_address_t)buf, read); - + if (err) { spin_unlock (&alloclock); -- cgit v1.2.3 From 7d20ee2f3d07b1a609814cb8ee83d712d0581f24 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 20 Dec 1998 21:00:36 +0000 Subject: . --- ufs/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index e4f3ce9d..14f11053 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +1998-12-20 Roland McGrath + + * alloc.c (diskfs_alloc_node): Fix printf format to silence warning. + * hyper.c (get_hypermetadata): Likewise. + 1998-09-04 Roland McGrath * dir.c (diskfs_lookup_hard): Fix defn with `const'. -- cgit v1.2.3 From 3c3060eb5246ef3fb3ccd2c1b80236bdb8b96e8b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 27 Dec 1998 08:41:51 +0000 Subject: 1998-12-27 Roland McGrath * main.c (main): Pass ARGP_IN_ORDER flag to argp_parse because diskfs options need it. --- ufs/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 6116792b..dfbfeda3 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 95, 96, 97, 98 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -162,7 +162,8 @@ main (int argc, char **argv) mach_port_t bootstrap; struct store_argp_params store_params = { 0 }; - argp_parse (&startup_argp, argc, argv, 0, 0, &store_params); + /* XXX diskfs's --boot-command needs us to use ARGP_IN_ORDER */ + argp_parse (&startup_argp, argc, argv, ARGP_IN_ORDER, NULL, &store_params); store_parsed = store_params.result; err = store_parsed_name (store_parsed, &diskfs_disk_name); -- cgit v1.2.3 From 8fb12c8cdd3e204dd1918be1e8ec8836dcebc286 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 27 Dec 1998 08:45:04 +0000 Subject: . --- ufs/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 14f11053..bd8e6358 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +1998-12-27 Roland McGrath + + * main.c (main): Pass ARGP_IN_ORDER flag to argp_parse because + diskfs options need it. + 1998-12-20 Roland McGrath * alloc.c (diskfs_alloc_node): Fix printf format to silence warning. -- cgit v1.2.3 From 341e44275812fb922644389f10e33ecf2f7b221c Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 27 Dec 1998 10:20:53 +0000 Subject: 1998-12-27 Roland McGrath * inode.c (diskfs_set_statfs): Remove __ from struct members. 1998-12-21 Mark Kettenis * inode.c (diskfs_set_statfs): Fill in statfs members that are used to implement statvfs. --- ufs/inode.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 658d6187..1901788e 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -524,6 +524,8 @@ diskfs_set_statfs (struct statfs *st) st->f_ffree = sblock->fs_cstotal.cs_nifree; st->f_fsid = getpid (); st->f_namelen = 0; + st->f_favail = st->f_ffree; + st->f_frsize = sblock->fs_fsize; return 0; } -- cgit v1.2.3 From a09e62adf5ee1e122cec5cea8594ba8a7b3cdafa Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 27 Dec 1998 10:29:29 +0000 Subject: . --- ufs/ChangeLog | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index bd8e6358..7d280a4a 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,12 @@ +1998-12-27 Roland McGrath + + * inode.c (diskfs_set_statfs): Remove __ from struct members. + +1998-12-21 Mark Kettenis + + * inode.c (diskfs_set_statfs): Fill in statfs members that are + used to implement statvfs. + 1998-12-27 Roland McGrath * main.c (main): Pass ARGP_IN_ORDER flag to argp_parse because -- cgit v1.2.3 From d387913db19bebfdbc2860084242a05ec6439fd5 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 24 Jan 1999 02:43:43 +0000 Subject: 1999-01-23 Roland McGrath * main.c (main): Use diskfs_init_main. --- ufs/main.c | 42 ++++-------------------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index dfbfeda3..29b22d11 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -160,39 +160,11 @@ main (int argc, char **argv) { error_t err; mach_port_t bootstrap; - struct store_argp_params store_params = { 0 }; - /* XXX diskfs's --boot-command needs us to use ARGP_IN_ORDER */ - argp_parse (&startup_argp, argc, argv, ARGP_IN_ORDER, NULL, &store_params); - store_parsed = store_params.result; - - err = store_parsed_name (store_parsed, &diskfs_disk_name); - if (err) - error (2, err, "store_parsed_name"); - - /* This must come after the args have been parsed, as this is where the - host priv ports are set for booting. */ - diskfs_console_stdio (); - - if (diskfs_boot_flags) - /* We are the bootstrap filesystem. */ - bootstrap = MACH_PORT_NULL; - else - { - task_get_bootstrap_port (mach_task_self (), &bootstrap); - if (bootstrap == MACH_PORT_NULL) - error (2, 0, "Must be started as a translator"); - } - - /* Initialize the diskfs library. Must come before any other diskfs call. */ - err = diskfs_init_diskfs (); - if (err) - error (4, err, "init"); - - err = store_parsed_open (store_parsed, diskfs_readonly ? STORE_READONLY : 0, - &store); - if (err) - error (3, err, "%s", diskfs_disk_name); + /* Initialize the diskfs library, parse arguments, and open the store. + This starts the first diskfs thread for us. */ + store = diskfs_init_main (&startup_argp, argc, argv, + &store_parsed, &bootstrap); if (store->block_size > DEV_BSIZE) error (4, err, "%s: Bad device block size %d (should be <= %d)", @@ -206,15 +178,9 @@ main (int argc, char **argv) log2_dev_blocks_per_dev_bsize++; log2_dev_blocks_per_dev_bsize -= store->log2_block_size; - if (store->flags & STORE_HARD_READONLY) - diskfs_readonly = diskfs_hard_readonly = 1; - /* Map the entire disk. */ create_disk_pager (); - /* Start the first request thread, to handle RPCs and page requests. */ - diskfs_spawn_first_thread (); - get_hypermetadata (); inode_init (); -- cgit v1.2.3 From 094eae6ae91ebff7210cab489cb8ff214bfccfab Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 24 Jan 1999 02:52:44 +0000 Subject: . --- ufs/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 7d280a4a..7d6c0800 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +1999-01-23 Roland McGrath + + * main.c (main): Use diskfs_init_main. + 1998-12-27 Roland McGrath * inode.c (diskfs_set_statfs): Remove __ from struct members. -- cgit v1.2.3 From 7709e52886ecdbc1a316dbe37f30eefe2a9b10dd Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 2 May 1999 19:54:32 +0000 Subject: 1999-05-02 Roland McGrath * main.c (main): Remove bogus uninitialized variable ERR. --- ufs/main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/main.c b/ufs/main.c index 29b22d11..cc39019d 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 95, 96, 97, 98 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,98,99 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -158,7 +158,6 @@ diskfs_append_args (char **argz, unsigned *argz_len) int main (int argc, char **argv) { - error_t err; mach_port_t bootstrap; /* Initialize the diskfs library, parse arguments, and open the store. @@ -167,7 +166,7 @@ main (int argc, char **argv) &store_parsed, &bootstrap); if (store->block_size > DEV_BSIZE) - error (4, err, "%s: Bad device block size %d (should be <= %d)", + error (4, 0, "%s: Bad device block size %d (should be <= %d)", diskfs_disk_name, store->block_size, DEV_BSIZE); if (store->size < SBSIZE + SBOFF) error (5, 0, "%s: Disk too small (%ld bytes)", diskfs_disk_name, -- cgit v1.2.3 From 7b4bf7ce4b982d503d8499b7beeaec4d3d9bdc19 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 2 May 1999 19:54:37 +0000 Subject: . --- ufs/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 7d6c0800..16ae4238 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +1999-05-02 Roland McGrath + + * main.c (main): Remove bogus uninitialized variable ERR. + 1999-01-23 Roland McGrath * main.c (main): Use diskfs_init_main. -- cgit v1.2.3 From ca6b1e89cd646368a08734e55dfb5da7ac1e2465 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Tue, 29 Jun 1999 09:00:20 +0000 Subject: 1999-06-29 Thomas Bushnell, BSG * hyper.c (diskfs_readonly_changed): Adjust whether the store should permit writes too. --- ufs/ChangeLog | 5 +++++ ufs/hyper.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 16ae4238..7b0fee70 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +1999-06-29 Thomas Bushnell, BSG + + * hyper.c (diskfs_readonly_changed): Adjust whether the store + should permit writes too. + 1999-05-02 Roland McGrath * main.c (main): Remove bogus uninitialized variable ERR. diff --git a/ufs/hyper.c b/ufs/hyper.c index 2a43bfed..c5101141 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -1,5 +1,5 @@ /* Fetching and storing the hypermetadata (superblock and cg summary info). - Copyright (C) 1994, 95, 96, 97, 98 Free Software Foundation, Inc. + Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -396,6 +396,8 @@ copy_sblock () void diskfs_readonly_changed (int readonly) { + (*(readonly ? store_set_flags : store_clear_flags)) (store, STORE_READONLY); + vm_protect (mach_task_self (), (vm_address_t)disk_image, store->size, 0, VM_PROT_READ | (readonly ? 0 : VM_PROT_WRITE)); -- cgit v1.2.3 From 022849d0b80dcb7b46f4f9dcb7c3af7bba95cf39 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Sat, 3 Jul 1999 23:55:45 +0000 Subject: 1999-07-03 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Use munmap instead of vm_deallocate. (diskfs_direnter_hard): Likewise. (diskfs_dirremove_hard): Likewise. (diskfs_dirrewrite_hard): Likewise. (diskfs_dirempty): Likewise. (diskfs_drop_dirstat): Likewise. (diskfs_get_directs): Likewise. * sizes.c (block_extended): Likewise. (poke_pages): Likewise. * hyper.c (get_hypermetadata): Likewise. (diskfs_set_hypermetadata): Likewise. --- ufs/ChangeLog | 15 +++++++++++++++ ufs/dir.c | 27 +++++++++++++-------------- ufs/hyper.c | 5 ++--- ufs/sizes.c | 6 +++--- 4 files changed, 33 insertions(+), 20 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 7b0fee70..8791b327 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,18 @@ +1999-07-03 Thomas Bushnell, BSG + + * dir.c (diskfs_lookup_hard): Use munmap instead of + vm_deallocate. + (diskfs_direnter_hard): Likewise. + (diskfs_dirremove_hard): Likewise. + (diskfs_dirrewrite_hard): Likewise. + (diskfs_dirempty): Likewise. + (diskfs_drop_dirstat): Likewise. + (diskfs_get_directs): Likewise. + * sizes.c (block_extended): Likewise. + (poke_pages): Likewise. + * hyper.c (get_hypermetadata): Likewise. + (diskfs_set_hypermetadata): Likewise. + 1999-06-29 Thomas Bushnell, BSG * hyper.c (diskfs_readonly_changed): Adjust whether the store diff --git a/ufs/dir.c b/ufs/dir.c index 01432829..c17549c2 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -137,7 +137,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, } if (buf) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); buf = 0; } if (ds && (type == CREATE || type == RENAME)) @@ -181,7 +181,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, } if (err != ENOENT) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); return err; } @@ -295,7 +295,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, || !ds || ds->type == LOOKUP) { - vm_deallocate (mach_task_self (), buf, buflen); + vm_deallocate ((caddr_t) buf, buflen); if (ds) ds->type = LOOKUP; /* set to be ignored by drop_dirstat */ } @@ -586,7 +586,7 @@ diskfs_direnter_hard(struct node *dp, err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred); if (err) { - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); return err; } } @@ -610,7 +610,7 @@ diskfs_direnter_hard(struct node *dp, dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); if (ds->stat != EXTEND) { @@ -678,7 +678,7 @@ diskfs_dirremove_hard(struct node *dp, dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); /* If we are keeping count of this block, then keep the count up to date. */ @@ -711,7 +711,7 @@ diskfs_dirrewrite_hard(struct node *dp, ds->entry->d_type = IFTODT (np->dn_stat.st_mode); dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); diskfs_file_update (dp, 1); @@ -758,7 +758,7 @@ diskfs_dirempty(struct node *dp, || (entry->d_name[1] != '.' && entry->d_name[1] != '\0'))) { - vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + munmap ((caddr_t) buf, dp->dn_stat.st_size); if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) @@ -770,7 +770,7 @@ diskfs_dirempty(struct node *dp, dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); - vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + munmap ((caddr_t) buf, dp->dn_stat.st_size); return 1; } @@ -781,7 +781,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) if (ds->type != LOOKUP) { assert (ds->mapbuf); - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); ds->type = LOOKUP; } return 0; @@ -968,9 +968,8 @@ diskfs_get_directs (struct node *dp, if (allocsize > *datacnt) { if (round_page (datap - *data) < allocsize) - vm_deallocate (mach_task_self (), - (vm_address_t) (*data + round_page (datap - *data)), - allocsize - round_page (datap - *data)); + munmap (*data + round_page (datap - *data), + allocsize - round_page (datap - *data)); } /* Set variables for return */ diff --git a/ufs/hyper.c b/ufs/hyper.c index c5101141..deb4a5df 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -138,8 +138,7 @@ get_hypermetadata (void) /* Free previous values. */ if (zeroblock) - vm_deallocate (mach_task_self(), - (vm_address_t)zeroblock, sblock->fs_bsize); + munmap ((caddr_t) zeroblock, sblock->fs_bsize); if (csum) free (csum); @@ -314,7 +313,7 @@ diskfs_set_hypermetadata (int wait, int clean) err = EIO; } - vm_deallocate (mach_task_self (), (vm_address_t)buf, read); + munmap (buf, read); if (err) { diff --git a/ufs/sizes.c b/ufs/sizes.c index 5c3d12f0..58cbfc98 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -1,5 +1,5 @@ /* File growth and truncation - Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999 Free Software Foundation This file is part of the GNU Hurd. @@ -439,7 +439,7 @@ block_extended (struct node *np, /* Undo mapping */ mach_port_deallocate (mach_task_self (), mapobj); - vm_deallocate (mach_task_self (), mapaddr, round_page (old_size)); + munmap ((caddr_t) mapaddr, round_page (old_size)); /* Now it's OK to free the old block */ ffs_blkfree (np, old_pbn, old_size); @@ -711,7 +711,7 @@ poke_pages (memory_object_t obj, { for (poke = addr; poke < addr + len; poke += vm_page_size) *(volatile int *)poke = *(volatile int *)poke; - vm_deallocate (mach_task_self (), addr, len); + munmap ((caddr_t) addr, len); } start += len; } -- cgit v1.2.3 From 490d27a97e87769f04becd62bdfe3a783ee66c97 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Tue, 6 Jul 1999 00:09:18 +0000 Subject: Mon Jul 5 20:04:58 1999 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Repair typo. Reported by Yamashita TAKAO . --- ufs/ChangeLog | 5 +++++ ufs/dir.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 8791b327..4a983183 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +Mon Jul 5 20:04:58 1999 Thomas Bushnell, BSG + + * dir.c (diskfs_lookup_hard): Repair typo. Reported by Yamashita + TAKAO . + 1999-07-03 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Use munmap instead of diff --git a/ufs/dir.c b/ufs/dir.c index c17549c2..c0352d03 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -295,7 +295,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, || !ds || ds->type == LOOKUP) { - vm_deallocate ((caddr_t) buf, buflen); + munmap ((caddr_t) buf, buflen); if (ds) ds->type = LOOKUP; /* set to be ignored by drop_dirstat */ } -- cgit v1.2.3 From be6fc7f77939fce114b98ea1f876a623c09b31b3 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 11 Jul 1999 01:43:00 +0000 Subject: 1999-07-10 Roland McGrath * ufs.h: Add #include for munmap decl. --- ufs/ufs.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/ufs.h b/ufs/ufs.h index 1c44e5f5..77fb50e0 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -17,11 +17,13 @@ #include #include +#include #include #include #include #include #include +#include #include #include "fs.h" #include "dinode.h" @@ -81,7 +83,7 @@ struct user_pager_info } type; struct pager *p; vm_prot_t max_prot; - + vm_offset_t allow_unlocked_pagein; vm_size_t unlocked_pagein_length; }; @@ -223,7 +225,7 @@ swab_long_long (long long arg) abort (); \ ret; \ }) - + /* Execute A = B, but byteswap it along the way if necessary */ #define write_disk_entry(a,b) \ ({ \ -- cgit v1.2.3 From fbd6929a645721d3c1905900a9e1d9df1fed051e Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 11 Jul 1999 01:52:42 +0000 Subject: . --- ufs/ChangeLog | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 4a983183..209d39df 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +1999-07-10 Roland McGrath + + * ufs.h: Add #include for munmap decl. + Mon Jul 5 20:04:58 1999 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Repair typo. Reported by Yamashita @@ -6,7 +10,7 @@ Mon Jul 5 20:04:58 1999 Thomas Bushnell, BSG 1999-07-03 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Use munmap instead of - vm_deallocate. + vm_deallocate. (diskfs_direnter_hard): Likewise. (diskfs_dirremove_hard): Likewise. (diskfs_dirrewrite_hard): Likewise. -- cgit v1.2.3 From e529ce98486b413cca7b16e7f7a51642b60f0a6f Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Sun, 11 Jul 1999 05:32:44 +0000 Subject: 1999-07-09 Thomas Bushnell, BSG * dir.c (diskfs_get_directs): Use mmap instead of vm_allocate. * hyper.c (get_hypermetadata): Likewise. * pager.c (pager_read_page): Likewise. --- ufs/ChangeLog | 11 +++++++++++ ufs/dir.c | 2 +- ufs/hyper.c | 7 ++----- ufs/pager.c | 5 +++-- 4 files changed, 17 insertions(+), 8 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 209d39df..869840b8 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -2,6 +2,17 @@ * ufs.h: Add #include for munmap decl. +1999-07-09 Thomas Bushnell, BSG + + * dir.c (diskfs_get_directs): Use mmap instead of vm_allocate. + * hyper.c (get_hypermetadata): Likewise. + * pager.c (pager_read_page): Likewise. + +1999-07-06 Thomas Bushnell, BSG + + * hyper.c (diskfs_readonly_changed): Use mprotect instead of + vm_protect. + Mon Jul 5 20:04:58 1999 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Repair typo. Reported by Yamashita diff --git a/ufs/dir.c b/ufs/dir.c index c0352d03..304c8a44 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -863,7 +863,7 @@ diskfs_get_directs (struct node *dp, allocsize = round_page (bufsiz); if (allocsize > *datacnt) - vm_allocate (mach_task_self (), (vm_address_t *) data, allocsize, 1); + *data = mmap (0, allocsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); /* Scan through the entries to find ENTRY. If we encounter a -1 in the process then stop to fill it. When we run diff --git a/ufs/hyper.c b/ufs/hyper.c index deb4a5df..c907d274 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -257,8 +257,7 @@ get_hypermetadata (void) exit (1); } - vm_allocate (mach_task_self (), - (vm_address_t *)&zeroblock, sblock->fs_bsize, 1); + zeroblock = mmap (0, sblock->fs_bsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); /* If the filesystem has new features in it, don't pay attention to the user's request not to use them. */ @@ -397,9 +396,7 @@ diskfs_readonly_changed (int readonly) { (*(readonly ? store_set_flags : store_clear_flags)) (store, STORE_READONLY); - vm_protect (mach_task_self (), - (vm_address_t)disk_image, store->size, - 0, VM_PROT_READ | (readonly ? 0 : VM_PROT_WRITE)); + mprotect (disk_image, store->size, PROT_READ | (readonly ? 0 : PROT_WRITE)); if (readonly) { diff --git a/ufs/pager.c b/ufs/pager.c index 61695db6..e703bfd2 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -1,5 +1,5 @@ /* Pager for ufs - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -180,7 +180,8 @@ pager_read_page (struct user_pager_info *pager, printf ("Write-locked pagein Object %#x\tOffset %#x\n", pager, page); fflush (stdout); #endif - vm_allocate (mach_task_self (), buf, __vm_page_size, 1); + *buf = (vm_address_t) mmap (0, vm_page_size, PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); *writelock = 1; } -- cgit v1.2.3 From 558d5489edced5c7a208f66eafb47fbcca201ac0 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Sat, 4 Sep 1999 13:00:39 +0000 Subject: 1999-09-04 Thomas Bushnell, BSG * pager.c (find_address): If !ISREAD, then don't return errors for access past NP->allocsize, and clear *ADDR and *DISKSIZE. These can happen through harmless races against truncate. (pager_write_page): Don't print annoying messages for writes to unallocated disk. These can happen through harmless races against truncate, and so we should not pester the console with them. --- ufs/ChangeLog | 9 +++++++++ ufs/pager.c | 17 +++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 869840b8..1375fede 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,12 @@ +1999-09-04 Thomas Bushnell, BSG + + * pager.c (find_address): If !ISREAD, then don't return errors for + access past NP->allocsize, and clear *ADDR and *DISKSIZE. These + can happen through harmless races against truncate. + (pager_write_page): Don't print annoying messages for writes to + unallocated disk. These can happen through harmless races against + truncate, and so we should not pester the console with them. + 1999-07-10 Roland McGrath * ufs.h: Add #include for munmap decl. diff --git a/ufs/pager.c b/ufs/pager.c index e703bfd2..3038932d 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -121,7 +121,14 @@ find_address (struct user_pager_info *upi, { if (*nplock) rwlock_reader_unlock (*nplock); - return EIO; + if (isread) + return EIO; + else + { + *addr = 0; + *disksize = 0; + return 0; + } } if (offset + __vm_page_size > np->allocsize) @@ -216,13 +223,7 @@ pager_write_page (struct user_pager_info *pager, err = EIO; } else - { - printf ("Attempt to write unallocated disk\n."); - printf ("Object %p\tOffset %#x\n", pager, page); - fflush (stdout); - err = 0; /* unallocated disk; - error would be pointless */ - } + err = 0; if (nplock) rwlock_reader_unlock (nplock); -- cgit v1.2.3 From 637f6a0aa9cec92581381a8a19a66d2f9b66216b Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Wed, 8 Sep 1999 08:41:59 +0000 Subject: 1999-09-08 Thomas Bushnell, BSG * dir.c (diskfs_get_directs): Initialize `err' to shut gcc up. 1999-09-07 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Pass additional parameter to diskfs_get_filemap. (diskfs_dirempty): Likewise. * sizes.c (diskfs_truncate): Likewise. (block_extended): Likewise. (diskfs_grow): Likewise. * pager.c (diskfs_get_filemap): Accept additional parameter. --- ufs/ChangeLog | 14 ++++++++++++++ ufs/dir.c | 6 +++--- ufs/pager.c | 4 +++- ufs/sizes.c | 6 +++--- 4 files changed, 23 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 1375fede..4bebe284 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,17 @@ +1999-09-08 Thomas Bushnell, BSG + + * dir.c (diskfs_get_directs): Initialize `err' to shut gcc up. + +1999-09-07 Thomas Bushnell, BSG + + * dir.c (diskfs_lookup_hard): Pass additional parameter to + diskfs_get_filemap. + (diskfs_dirempty): Likewise. + * sizes.c (diskfs_truncate): Likewise. + (block_extended): Likewise. + (diskfs_grow): Likewise. + * pager.c (diskfs_get_filemap): Accept additional parameter. + 1999-09-04 Thomas Bushnell, BSG * pager.c (find_address): If !ISREAD, then don't return errors for diff --git a/ufs/dir.c b/ufs/dir.c index 304c8a44..aee08bb0 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -144,7 +144,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, ds->stat = LOOKING; /* Map in the directory contents. */ - memobj = diskfs_get_filemap (dp, prot); + memobj = diskfs_get_filemap (dp, 0, prot); if (memobj == MACH_PORT_NULL) return errno; @@ -730,7 +730,7 @@ diskfs_dirempty(struct node *dp, memory_object_t memobj; error_t err; - memobj = diskfs_get_filemap (dp, VM_PROT_READ); + memobj = diskfs_get_filemap (dp, 0, VM_PROT_READ); if (memobj == MACH_PORT_NULL) /* XXX should reflect error properly */ @@ -839,7 +839,7 @@ diskfs_get_directs (struct node *dp, char buf[DIRBLKSIZ]; char *bufp; int bufvalid; - error_t err; + error_t err = 0; int i; char *datap; struct directory_entry *entryp; diff --git a/ufs/pager.c b/ufs/pager.c index 3038932d..3cba748e 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -547,11 +547,13 @@ flush_node_pager (struct node *node) /* Call this to create a FILE_DATA pager and return a send right. NP must be locked. PROT is the max protection desired. */ mach_port_t -diskfs_get_filemap (struct node *np, vm_prot_t prot) +diskfs_get_filemap (struct node *np, int index, vm_prot_t prot) { struct user_pager_info *upi; mach_port_t right; + assert (index == 0); /* XXX */ + assert (S_ISDIR (np->dn_stat.st_mode) || S_ISREG (np->dn_stat.st_mode) || (S_ISLNK (np->dn_stat.st_mode) diff --git a/ufs/sizes.c b/ufs/sizes.c index 58cbfc98..cffce158 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -103,7 +103,7 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); - obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); + obj = diskfs_get_filemap (np, 0, VM_PROT_READ | VM_PROT_WRITE); if (obj != MACH_PORT_NULL) { /* XXX should cope with errors from diskfs_get_filemap */ @@ -403,7 +403,7 @@ block_extended (struct node *np, volatile int *pokeaddr; /* Map in this part of the file */ - mapobj = diskfs_get_filemap (np, VM_PROT_WRITE | VM_PROT_READ); + mapobj = diskfs_get_filemap (np, 0, VM_PROT_WRITE | VM_PROT_READ); /* XXX Should cope with errors from diskfs_get_filemap and back out the operation here. */ @@ -484,7 +484,7 @@ diskfs_grow (struct node *np, assert (!diskfs_readonly); /* This reference will ensure that NP->dn->fileinfo stays allocated. */ - pagerpt = diskfs_get_filemap (np, VM_PROT_WRITE|VM_PROT_READ); + pagerpt = diskfs_get_filemap (np, 0, VM_PROT_WRITE|VM_PROT_READ); if (pagerpt == MACH_PORT_NULL) return errno; -- cgit v1.2.3 From f043e443830bf3f6aa6c29b1a3c8ed954bff4af6 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 13 Sep 1999 04:34:49 +0000 Subject: 1999-09-09 Roland McGrath * Makefile (makemode): servers -> server. (targets): Replaced with target; remove ufs.static. (ufs.static-LDFLAGS): Variable removed. (ufs.static, ufs): Remove deps. --- ufs/Makefile | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 202316f8..c3bdc997 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -1,5 +1,5 @@ -# Copyright (C) 1994, 1995, 1996 Free Software Foundation +# Copyright (C) 1994,95,96,99 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -16,9 +16,9 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. dir := ufs -makemode := servers +makemode := server -targets = ufs ufs.static +target = ufs SRCS = alloc.c consts.c dir.c hyper.c inode.c main.c pager.c \ sizes.c subr.c tables.c bmap.c pokeloc.c LCLHDRS = ufs.h fs.h dinode.h dir.h @@ -26,8 +26,4 @@ LCLHDRS = ufs.h fs.h dinode.h dir.h OBJS = $(SRCS:.c=.o) HURDLIBS = diskfs iohelp fshelp store pager ports threads ihash shouldbeinlibc -ufs.static-LDFLAGS += -static - include ../Makeconf - -ufs.static ufs: $(OBJS) $(library_deps) -- cgit v1.2.3 From 298788e891e149c18599d9b4e8cac308c1d1457c Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 13 Sep 1999 04:35:54 +0000 Subject: ChangeLog --- ufs/ChangeLog | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 4bebe284..0ab45a3d 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,10 @@ +1999-09-09 Roland McGrath + + * Makefile (makemode): servers -> server. + (targets): Replaced with target; remove ufs.static. + (ufs.static-LDFLAGS): Variable removed. + (ufs.static, ufs): Remove deps. + 1999-09-08 Thomas Bushnell, BSG * dir.c (diskfs_get_directs): Initialize `err' to shut gcc up. @@ -5,7 +12,7 @@ 1999-09-07 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Pass additional parameter to - diskfs_get_filemap. + diskfs_get_filemap. (diskfs_dirempty): Likewise. * sizes.c (diskfs_truncate): Likewise. (block_extended): Likewise. @@ -34,7 +41,7 @@ 1999-07-06 Thomas Bushnell, BSG * hyper.c (diskfs_readonly_changed): Use mprotect instead of - vm_protect. + vm_protect. Mon Jul 5 20:04:58 1999 Thomas Bushnell, BSG -- cgit v1.2.3 From ddbe575459786c3530c2d092b4193b6d41f1e80a Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 13 Sep 1999 06:35:11 +0000 Subject: Reverted changes related to io_map_segment. --- ufs/ChangeLog | 4 ++++ ufs/dir.c | 6 +++--- ufs/pager.c | 4 +--- ufs/sizes.c | 6 +++--- 4 files changed, 11 insertions(+), 9 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 0ab45a3d..09d4b17a 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +1999-09-13 Roland McGrath + + * dir.c, sizes.c, pager.c: Reverted changes related to io_map_segment. + 1999-09-09 Roland McGrath * Makefile (makemode): servers -> server. diff --git a/ufs/dir.c b/ufs/dir.c index aee08bb0..304c8a44 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -144,7 +144,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, ds->stat = LOOKING; /* Map in the directory contents. */ - memobj = diskfs_get_filemap (dp, 0, prot); + memobj = diskfs_get_filemap (dp, prot); if (memobj == MACH_PORT_NULL) return errno; @@ -730,7 +730,7 @@ diskfs_dirempty(struct node *dp, memory_object_t memobj; error_t err; - memobj = diskfs_get_filemap (dp, 0, VM_PROT_READ); + memobj = diskfs_get_filemap (dp, VM_PROT_READ); if (memobj == MACH_PORT_NULL) /* XXX should reflect error properly */ @@ -839,7 +839,7 @@ diskfs_get_directs (struct node *dp, char buf[DIRBLKSIZ]; char *bufp; int bufvalid; - error_t err = 0; + error_t err; int i; char *datap; struct directory_entry *entryp; diff --git a/ufs/pager.c b/ufs/pager.c index 3cba748e..3038932d 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -547,13 +547,11 @@ flush_node_pager (struct node *node) /* Call this to create a FILE_DATA pager and return a send right. NP must be locked. PROT is the max protection desired. */ mach_port_t -diskfs_get_filemap (struct node *np, int index, vm_prot_t prot) +diskfs_get_filemap (struct node *np, vm_prot_t prot) { struct user_pager_info *upi; mach_port_t right; - assert (index == 0); /* XXX */ - assert (S_ISDIR (np->dn_stat.st_mode) || S_ISREG (np->dn_stat.st_mode) || (S_ISLNK (np->dn_stat.st_mode) diff --git a/ufs/sizes.c b/ufs/sizes.c index cffce158..58cbfc98 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -103,7 +103,7 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); - obj = diskfs_get_filemap (np, 0, VM_PROT_READ | VM_PROT_WRITE); + obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); if (obj != MACH_PORT_NULL) { /* XXX should cope with errors from diskfs_get_filemap */ @@ -403,7 +403,7 @@ block_extended (struct node *np, volatile int *pokeaddr; /* Map in this part of the file */ - mapobj = diskfs_get_filemap (np, 0, VM_PROT_WRITE | VM_PROT_READ); + mapobj = diskfs_get_filemap (np, VM_PROT_WRITE | VM_PROT_READ); /* XXX Should cope with errors from diskfs_get_filemap and back out the operation here. */ @@ -484,7 +484,7 @@ diskfs_grow (struct node *np, assert (!diskfs_readonly); /* This reference will ensure that NP->dn->fileinfo stays allocated. */ - pagerpt = diskfs_get_filemap (np, 0, VM_PROT_WRITE|VM_PROT_READ); + pagerpt = diskfs_get_filemap (np, VM_PROT_WRITE|VM_PROT_READ); if (pagerpt == MACH_PORT_NULL) return errno; -- cgit v1.2.3 From 822faaf3dcbee03f1aae496e6240769e5b6c0d27 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 13 Oct 1999 19:37:29 +0000 Subject: 1999-10-13 Roland McGrath * consts.c (diskfs_name_max): New variable. --- ufs/consts.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/consts.c b/ufs/consts.c index 8806049e..69221233 100644 --- a/ufs/consts.c +++ b/ufs/consts.c @@ -1,5 +1,5 @@ /* Various constants wanted by the diskfs library - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -16,9 +16,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ufs.h" +#include "dir.h" #include int diskfs_link_max = LINK_MAX; +int diskfs_name_max = MAXNAMLEN; int diskfs_maxsymlinks = 8; int diskfs_shortcut_symlink = 1; int diskfs_shortcut_chrdev = 1; -- cgit v1.2.3 From 1a4ef01d300a7ad85cd44f2cba7528fb2e00ebfb Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 13 Oct 1999 19:42:28 +0000 Subject: . --- ufs/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 09d4b17a..02120e59 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +1999-10-13 Roland McGrath + + * consts.c (diskfs_name_max): New variable. + 1999-09-13 Roland McGrath * dir.c, sizes.c, pager.c: Reverted changes related to io_map_segment. -- cgit v1.2.3 From 4ab9fb88b5ba408e9282a345ddbbdba80a1c47fd Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 3 Mar 2000 21:48:33 +0000 Subject: 2000-03-03 Roland McGrath * dir.c (diskfs_get_directs): Don't allocate buffer for *DATA until after scanning for ENTRY and possibly returning EOF. --- ufs/dir.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 304c8a44..8077234c 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation + Copyright (C) 1994,95,96,97,98,99,2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -856,15 +856,6 @@ diskfs_get_directs (struct node *dp, dp->dn->dirents[i] = -1; } - /* Allocate enough space to hold the maximum we might return */ - if (!bufsiz || bufsiz > dp->dn_stat.st_size) - allocsize = round_page (dp->dn_stat.st_size); - else - allocsize = round_page (bufsiz); - - if (allocsize > *datacnt) - *data = mmap (0, allocsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); - /* Scan through the entries to find ENTRY. If we encounter a -1 in the process then stop to fill it. When we run off the end, ENTRY is too big. */ @@ -891,11 +882,23 @@ diskfs_get_directs (struct node *dp, if (blkno == nblks) { + /* We reached the end of the directory without seeing ENTRY. + This is treated as an EOF condition, meaning we return + success with empty results. */ *datacnt = 0; *amt = 0; return 0; } + /* Allocate enough space to hold the maximum we might return */ + if (!bufsiz || bufsiz > dp->dn_stat.st_size) + allocsize = round_page (dp->dn_stat.st_size); + else + allocsize = round_page (bufsiz); + + if (allocsize > *datacnt) + *data = mmap (0, allocsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + /* Set bufp appropriately */ bufp = buf; if (curentry != entry) -- cgit v1.2.3 From 5101d9d4d17c8be708d1934b78436f742d4f678f Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 3 Mar 2000 21:48:41 +0000 Subject: . --- ufs/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 02120e59..34f98d28 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +2000-03-03 Roland McGrath + + * dir.c (diskfs_get_directs): Don't allocate buffer for *DATA until + after scanning for ENTRY and possibly returning EOF. + 1999-10-13 Roland McGrath * consts.c (diskfs_name_max): New variable. -- cgit v1.2.3 From 4153466ba0bb10fa250af108399d5f4367acad3e Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Wed, 26 Jul 2000 12:33:12 +0000 Subject: * Makefile (HURDLIBS): Reorder libs such that the threads lib comes before the ports lib. This makes sure the functions in libthreads properly override the stubs in libports with the new dynamic linker semantics in glibc 2.2. --- ufs/ChangeLog | 7 +++++++ ufs/Makefile | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 34f98d28..a83d02b8 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,10 @@ +2000-07-26 Mark Kettenis + + * Makefile (HURDLIBS): Reorder libs such that the threads lib + comes before the ports lib. This makes sure the functions in + libthreads properly override the stubs in libports with the new + dynamic linker semantics in glibc 2.2. + 2000-03-03 Roland McGrath * dir.c (diskfs_get_directs): Don't allocate buffer for *DATA until diff --git a/ufs/Makefile b/ufs/Makefile index c3bdc997..183caa86 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -1,5 +1,6 @@ - -# Copyright (C) 1994,95,96,99 Free Software Foundation, Inc. +# Makefile for ufs +# +# Copyright (C) 1994,95,96,99,2000 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -24,6 +25,6 @@ SRCS = alloc.c consts.c dir.c hyper.c inode.c main.c pager.c \ LCLHDRS = ufs.h fs.h dinode.h dir.h OBJS = $(SRCS:.c=.o) -HURDLIBS = diskfs iohelp fshelp store pager ports threads ihash shouldbeinlibc +HURDLIBS = diskfs iohelp fshelp store pager threads ports ihash shouldbeinlibc include ../Makeconf -- cgit v1.2.3 From 6541698d7d102f16295bb8240d02dd112197b163 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 30 Nov 2000 19:10:04 +0000 Subject: ext2fs, ufs: 2000-11-30 Marcus Brinkmann * dir.c (diskfs_lookup_hard): If name is too long, clear DS before returning ENAMETOOLONG. pfinet: 2000-11-02 Marcus Brinkmann * tunnel.c (trivfs_S_io_get_owner): Add return type to silence compiler warning. --- ufs/ChangeLog | 5 +++++ ufs/dir.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index a83d02b8..82ada32f 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +2000-11-30 Marcus Brinkmann + + * dir.c (diskfs_lookup_hard): If name is too long, clear + DS before returning ENAMETOOLONG. + 2000-07-26 Mark Kettenis * Makefile (HURDLIBS): Reorder libs such that the threads lib diff --git a/ufs/dir.c b/ufs/dir.c index 8077234c..2cc77398 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -126,7 +126,11 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, namelen = strlen (name); if (namelen > MAXNAMLEN) - return ENAMETOOLONG; + { + if (ds) + diskfs_null_dirstat (ds); + return ENAMETOOLONG; + } try_again: if (ds) -- cgit v1.2.3 From 2ce430f6071e45e899ad86891eecc26be805a445 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 3 Dec 2000 06:29:21 +0000 Subject: 2000-12-02 Roland McGrath * inode.c (write_node): Remove assert that dn_set_mtime et al are clear. It is ok if they are set in parallel, because the latter setting will be carried out eventually. --- ufs/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 1901788e..099609ab 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,5 @@ /* Inode management routines - Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation + Copyright (C) 1994,95,96,97,98,2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -320,7 +320,6 @@ write_node (struct node *np) struct dinode *di = dino (np->dn->number); error_t err; - assert (!np->dn_set_ctime && !np->dn_set_atime && !np->dn_set_mtime); if (np->dn_stat_dirty) { assert (!diskfs_readonly); -- cgit v1.2.3 From ea5f2a1a2552f01facb832f3324b4f0d32353e9b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 3 Dec 2000 06:30:18 +0000 Subject: . --- ufs/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 82ada32f..6927195b 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,9 @@ +2000-12-02 Roland McGrath + + * inode.c (write_node): Remove assert that dn_set_mtime et al are + clear. It is ok if they are set in parallel, because the latter + setting will be carried out eventually. + 2000-11-30 Marcus Brinkmann * dir.c (diskfs_lookup_hard): If name is too long, clear -- cgit v1.2.3 From 3bc8c9e3eed213b6326c607bfb368f695a4752e7 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sun, 7 Jan 2001 19:31:50 +0000 Subject: doc/ 2001-01-07 Marcus Brinkmann * hurd.texi (Diskfs Callbacks): Make diskfs_dirstat_size const. ext2fs/ 2001-01-07 Marcus Brinkmann * dir.c: Make diskfs_dirstat_size const. isofs/ 2001-01-07 Marcus Brinkmann * lookup.c: Make diskfs_dirstat_size const. ufs/ 2001-01-07 Marcus Brinkmann * dir.c: Make diskfs_dirstat_size const. libdiskfs/ 2001-01-07 Marcus Brinkmann * diskfs.h: Make diskfs_dirstat_size const. libdiskfs/ 2001-01-07 Marcus Brinkmann * file-statfs.c: Include . ftpfs/ 2001-01-07 Marcus Brinkmann * dir.c (ftpfs_dir_create): Fix last change (calloc invocation). 2001-01-07 Marcus Brinkmann * copy.c: Include . New macro page_aligned. (copy_write): Cast buf to vm_address_t in call to vm_write. Dereference amount for memcpy. (copy_read): Add len parameter to vm_read, remove redundant following len assignment. --- ufs/ChangeLog | 4 ++++ ufs/dir.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 6927195b..14aed9dd 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +2001-01-07 Marcus Brinkmann + + * dir.c: Make diskfs_dirstat_size const. + 2000-12-02 Roland McGrath * inode.c (write_node): Remove assert that dn_set_mtime et al are diff --git a/ufs/dir.c b/ufs/dir.c index 2cc77398..7880ca21 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -79,7 +79,7 @@ struct dirstat size_t nbytes; }; -size_t diskfs_dirstat_size = sizeof (struct dirstat); +const size_t diskfs_dirstat_size = sizeof (struct dirstat); /* Initialize DS such that diskfs_drop_dirstat will ignore it. */ void -- cgit v1.2.3 From 1c9f0a5afa9c6eb6af95106c382d441eadaa0949 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Mon, 8 Jan 2001 22:33:11 +0000 Subject: doc/ 2001-01-08 Marcus Brinkmann * hurd.texi (Store Management): Replace off_t with store_offset_t. (Store I/O): Likewise. (Store Classes): Likewise. ext2fs/ 2001-01-08 Marcus Brinkmann * ext2fs.c (main): Use %Ld instead %ld to print store->size. * hyper.c (get_hypermetadata): Likewise. libstore/ 2001-01-08 Marcus Brinkmann * zero.c (zero_remap): Change type of variables length, old_length to store_offset_t. (zero_decode): Change type of variable size to store_offset_t. (zero_open): Likewise. Use strtoull instead strtoul to parse size argument from name. Use store_offset_t for max_offs and its calculation. (store_zero_create): Use store_offset_t type for size argument. * derive.c (_store_derive): Use store_offset_t as type for variable last_part_base. * stripe.c (addr_adj): Change types of addr argument and return value to store_offset_t. (store_ileave_create): Change type of interleave argument and variables min_end and end to store_offset_t, but type of variable block_size to size_t. (store_concat_create): Change type of variable block_size to size_t. * make.c (_store_create): Change end argument type to store_offset_t. * store.h: New type store_offset_t, define to off64_t. (struct store_run): Change type of start and length to store_offset_t. (struct store): Change type of end, wrap_src, wrap_dst, blocks, size to store_offset_t. Change type of addr arg in store_read_meth_t and store_write_meth_t to store_offset_t, as well as in declarations for store_read and store_write. Change type of argument end in _store_create declaration to store_offset_t. Change type of argument size in store_zero_create to store_offset_t. Change type of argument interleace in store_ileace_create to store_offset_t. * rdwr.c (store_find_first_run): Change type of return value, addr and *base arguments, and variables wrap_src and run_blocks to store_offset_t. (store_next_run): Change type of *base argument to store_offset_t. (store_write): Change type of addr argument and variable base to store_offset_t. (store_read): Likewise, also for addr argument of local function seg_read. Change type of len argument to size_t. * copy.c (copy_read): Change type of addr argument to store_offset_t. (copy_write): Likewise. * device.c (dev_read): Likewise. (dev_write): Likewise. * file.c (file_read): Likewise. (file_write): Likewise. (file_byte_read): Likewise. (file_byte_write): Likewise. * mvol.c (mvol_read): Likewise. (mvol_write): Likewise. * remap.c (remap_read): Likewise. (remap_write): Likewise. * stripe.c (stripe_read): Likewise. (stripe_write): Likewise. * task.c (task_read): Likewise. (task_write): Likewise. * zero.c (zero_read): Likewise. (zero_write): Likewise. * remap.c (store_remap_runs): Change type of addr and len arguments of local function add_run and of local variables addr, length, baddr, blen and len to store_offset_t. (remap_open): Cast -1 to store_offset_t, not off_t. * argp.c (struct store_parsed): Change type of interleave from off_t to store_offset_t. (store_parsed_append_args): Use %Ld instead %ld to print interleave value. (store_parsed_name): Likewise. ufs/ 2001-01-08 Marcus Brinkmann * main.c (main): Use %Ld instead %ld to print store->size. * hyper.c (get_hypermetadata): Likewise. * inode.c (diskfs_S_file_get_storage_info): Change type of variables start and length from off_t to store_offset_t. utils/ 2001-01-08 Marcus Brinkmann * storeread.c (main): Change type of addr to store_offset_t, also for first argument of local function dump. Add comment about store->size as len parameter for store_read. Use atoll instead atoi for addr argument. * storeinfo.c (print_store): Remove local function pint, add two similar functions psiz and poff, accepting and printing a size_t or store_offset_t respectively. Use psiz to print block_size, poff to print blocks and size of store. Use %Ld instead %ld to print runs. * storecat.c (main): Change type of addr and left to store_offset_t. --- ufs/ChangeLog | 7 +++++++ ufs/hyper.c | 2 +- ufs/inode.c | 4 ++-- ufs/main.c | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 14aed9dd..d8e04a0e 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,10 @@ +2001-01-08 Marcus Brinkmann + + * main.c (main): Use %Ld instead %ld to print store->size. + * hyper.c (get_hypermetadata): Likewise. + * inode.c (diskfs_S_file_get_storage_info): Change type of variables + start and length from off_t to store_offset_t. + 2001-01-07 Marcus Brinkmann * dir.c: Make diskfs_dirstat_size const. diff --git a/ufs/hyper.c b/ufs/hyper.c index c907d274..ece327a2 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -251,7 +251,7 @@ get_hypermetadata (void) if (store->size < sblock->fs_size * sblock->fs_fsize) { fprintf (stderr, - "Disk size (%ld) less than necessary " + "Disk size (%Ld) less than necessary " "(superblock says we need %ld)\n", store->size, sblock->fs_size * sblock->fs_fsize); exit (1); diff --git a/ufs/inode.c b/ufs/inode.c index 099609ab..72467e1a 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -679,8 +679,8 @@ diskfs_S_file_get_storage_info (struct protid *cred, for (i = 0; i < NDADDR; i++) { - off_t start = fsbtodb (sblock, read_disk_entry (di->di_db[i])); - off_t length = + store_offset_t start = fsbtodb (sblock, read_disk_entry (di->di_db[i])); + store_offset_t length = (((i + 1) * sblock->fs_bsize > np->allocsize) ? np->allocsize - i * sblock->fs_bsize : sblock->fs_bsize); diff --git a/ufs/main.c b/ufs/main.c index cc39019d..8c79d707 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -169,7 +169,7 @@ main (int argc, char **argv) error (4, 0, "%s: Bad device block size %d (should be <= %d)", diskfs_disk_name, store->block_size, DEV_BSIZE); if (store->size < SBSIZE + SBOFF) - error (5, 0, "%s: Disk too small (%ld bytes)", diskfs_disk_name, + error (5, 0, "%s: Disk too small (%Ld bytes)", diskfs_disk_name, store->size); log2_dev_blocks_per_dev_bsize = 0; -- cgit v1.2.3 From 7c80866b417ce602f6d1c188d18c28e8cf7e3a14 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sat, 9 Jun 2001 20:30:34 +0000 Subject: * inode.c (diskfs_set_statfs): If number of free blocks is less than the number of reserved blocks, set the number of available blocks to 0. --- ufs/ChangeLog | 6 ++++++ ufs/inode.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index d8e04a0e..8f651624 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,9 @@ +2001-06-09 Mark Kettenis + + * inode.c (diskfs_set_statfs): If number of free blocks is less + than the number of reserved blocks, set the number of available + blocks to 0. + 2001-01-08 Marcus Brinkmann * main.c (main): Use %Ld instead %ld to print store->size. diff --git a/ufs/inode.c b/ufs/inode.c index 72467e1a..2647754c 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,5 @@ /* Inode management routines - Copyright (C) 1994,95,96,97,98,2000 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,98,2000,01 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -519,6 +519,8 @@ diskfs_set_statfs (struct statfs *st) + sblock->fs_cstotal.cs_nffree); st->f_bavail = ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100) - (sblock->fs_dsize - st->f_bfree)); + if (st->f_bfree < ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100))) + st->f_bavail = 0; st->f_files = sblock->fs_ncg * sblock->fs_ipg - 2; /* not 0 or 1 */ st->f_ffree = sblock->fs_cstotal.cs_nifree; st->f_fsid = getpid (); -- cgit v1.2.3 From 6da36980e09a2a8b1e7db0627be626aca884c797 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 10 Aug 2001 04:42:07 +0000 Subject: 2001-08-09 Roland McGrath * inode.c (diskfs_get_translator): Fail with EFTYPE if the length field stored on disk is unreasonable. Don't crash on ENOMEM. Use memcpy instead of bcopy. --- ufs/inode.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 2647754c..28f18dbd 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -602,7 +602,7 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) error_t err; daddr_t blkno; u_int datalen; - void *transloc; + const void *transloc; err = diskfs_catch_exception (); if (err) @@ -613,8 +613,15 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) transloc = disk_image + fsaddr (sblock, blkno); datalen = *(u_int *)transloc; - *namep = malloc (datalen); - bcopy (transloc + sizeof (u_int), *namep, datalen); + if (datalen > sblock->fs_bsize) + err = EFTYPE; + else + { + *namep = malloc (datalen); + if (*namep == NULL) + err = ENOMEM; + memcpy (*namep, transloc + sizeof (u_int), datalen); + } diskfs_end_catch_exception (); -- cgit v1.2.3 From 2f1c418840a1ba5a7029cb6f21c30052195051bc Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 10 Aug 2001 04:42:15 +0000 Subject: . --- ufs/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 8f651624..871eaf78 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,9 @@ +2001-08-09 Roland McGrath + + * inode.c (diskfs_get_translator): Fail with EFTYPE if the length + field stored on disk is unreasonable. Don't crash on ENOMEM. + Use memcpy instead of bcopy. + 2001-06-09 Mark Kettenis * inode.c (diskfs_set_statfs): If number of free blocks is less -- cgit v1.2.3 From b6dc2a97a52a2e7ba3cc14771f48a14d6de64fe5 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 10 Aug 2001 04:43:25 +0000 Subject: 2001-08-09 Roland McGrath * inode.c (diskfs_get_translator): Fail with EFTYPE if the length field stored on disk is unreasonable. Don't crash on ENOMEM. Use memcpy instead of bcopy. --- ufs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 28f18dbd..2098211f 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -613,7 +613,7 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) transloc = disk_image + fsaddr (sblock, blkno); datalen = *(u_int *)transloc; - if (datalen > sblock->fs_bsize) + if (datalen > sblock->fs_bsize - sizeof (u_int)) err = EFTYPE; else { -- cgit v1.2.3 From b005f7053b00dc5e7c6eeab6a104f7fc7b7b6ab5 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Mon, 1 Oct 2001 16:37:27 +0000 Subject: 2001-10-01 Marcus Brinkmann * ufs.h (swab_long_long): Use LL, not lL, for constant. Submitted by Maurizio Boriani . --- ufs/ChangeLog | 5 +++++ ufs/ufs.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 871eaf78..e013b8f5 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +2001-10-01 Marcus Brinkmann + + * ufs.h (swab_long_long): Use LL, not lL, for constant. + Submitted by Maurizio Boriani . + 2001-08-09 Roland McGrath * inode.c (diskfs_get_translator): Fail with EFTYPE if the length diff --git a/ufs/ufs.h b/ufs/ufs.h index 77fb50e0..5d823ebc 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -208,7 +208,7 @@ extern inline long long swab_long_long (long long arg) { return (((long long) swab_long (arg & 0xffffffff) << 32) - | swab_long ((arg & 0xffffffff00000000lL) >> 32)); + | swab_long ((arg & 0xffffffff00000000LL) >> 32)); } /* Return ENTRY, after byteswapping it if necessary */ -- cgit v1.2.3 From 2647fe79a023583f6849054e1b9bb8511d9889c0 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 21 Nov 2001 22:08:48 +0000 Subject: 2001-11-21 Roland McGrath * inode.c (read_disknode): Just always call getpid for the fsid value. --- ufs/inode.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 2098211f..a258ea13 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -212,7 +212,6 @@ diskfs_new_hardrefs (struct node *np) static error_t read_disknode (struct node *np) { - static int fsid, fsidset; struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; @@ -221,14 +220,8 @@ read_disknode (struct node *np) if (err) return err; - if (! fsidset) - { - fsid = getpid (); - fsidset = 1; - } - st->st_fstype = FSTYPE_UFS; - st->st_fsid = fsid; + st->st_fsid = getpid (); /* This call is very cheap. */ st->st_ino = np->dn->number; st->st_gen = read_disk_entry (di->di_gen); st->st_rdev = read_disk_entry(di->di_rdev); -- cgit v1.2.3 From 7b2663dcd0afabce61218303c2c7709e37c0a3c8 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 21 Nov 2001 22:09:03 +0000 Subject: . --- ufs/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index e013b8f5..a655a739 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +2001-11-21 Roland McGrath + + * inode.c (read_disknode): Just always call getpid for the fsid value. + 2001-10-01 Marcus Brinkmann * ufs.h (swab_long_long): Use LL, not lL, for constant. -- cgit v1.2.3 From d944b66ab2bc82aa80eb7fd351bdb8c7001ef5e5 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 14 Mar 2002 21:11:37 +0000 Subject: 2002-03-11 Roland McGrath * Makefile (ufs.static): Depend on $(boot-store-types:%=../libstore/libstore_%.a). --- ufs/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/Makefile b/ufs/Makefile index 183caa86..02cf38ba 100644 --- a/ufs/Makefile +++ b/ufs/Makefile @@ -1,6 +1,6 @@ # Makefile for ufs # -# Copyright (C) 1994,95,96,99,2000 Free Software Foundation, Inc. +# Copyright (C) 1994,95,96,99,2000,02 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -28,3 +28,5 @@ OBJS = $(SRCS:.c=.o) HURDLIBS = diskfs iohelp fshelp store pager threads ports ihash shouldbeinlibc include ../Makeconf + +ufs.static: $(boot-store-types:%=../libstore/libstore_%.a) -- cgit v1.2.3 From 4ea7077cd0bbe0fa90363323ab9b969652b2d1e5 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 14 Mar 2002 21:11:48 +0000 Subject: . --- ufs/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index a655a739..b568623a 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +2002-03-11 Roland McGrath + + * Makefile (ufs.static): Depend on + $(boot-store-types:%=../libstore/libstore_%.a). + 2001-11-21 Roland McGrath * inode.c (read_disknode): Just always call getpid for the fsid value. -- cgit v1.2.3 From ec432c9be247ee138cfce70b1d4aa3ada5090aad Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 8 May 2002 09:59:52 +0000 Subject: 2002-05-08 Roland McGrath * main.c (diskfs_append_args): Fix argument type. (main): Use %z format modifier for size_t arg. * dir.c (dirscanblock): Use %z format modifier for vm_address_t arg. (diskfs_dirempty): int -> vm_address_t (count_dirents): int -> size_t (diskfs_get_directs): u_int -> size_t --- ufs/dir.c | 13 ++++++------- ufs/main.c | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 7880ca21..3256bc42 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994,95,96,97,98,99,2000 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,98,99,2000,02 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -379,7 +379,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { - fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", + fprintf (stderr, "Bad directory entry: inode: %d offset: %zd\n", dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } @@ -729,8 +729,7 @@ diskfs_dirempty(struct node *dp, struct protid *cred) { struct directory_entry *entry; - int curoff; - vm_address_t buf; + vm_address_t buf, curoff; memory_object_t memobj; error_t err; @@ -798,7 +797,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) static error_t count_dirents (struct node *dp, int nb, char *buf) { - int amt; + size_t amt; char *offinblk; struct directory_entry *entry; int count = 0; @@ -833,7 +832,7 @@ diskfs_get_directs (struct node *dp, int entry, int nentries, char **data, - u_int *datacnt, + size_t *datacnt, vm_size_t bufsiz, int *amt) { @@ -848,7 +847,7 @@ diskfs_get_directs (struct node *dp, char *datap; struct directory_entry *entryp; int allocsize; - int checklen; + size_t checklen; struct dirent *userp; nblks = dp->dn_stat.st_size/DIRBLKSIZ; diff --git a/ufs/main.c b/ufs/main.c index 8c79d707..242107f4 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994,95,96,97,98,99 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,98,99,2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -136,7 +136,7 @@ struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; /* Override the standard diskfs routine so we can add our own output. */ error_t -diskfs_append_args (char **argz, unsigned *argz_len) +diskfs_append_args (char **argz, size_t *argz_len) { error_t err; @@ -166,7 +166,7 @@ main (int argc, char **argv) &store_parsed, &bootstrap); if (store->block_size > DEV_BSIZE) - error (4, 0, "%s: Bad device block size %d (should be <= %d)", + error (4, 0, "%s: Bad device block size %zd (should be <= %d)", diskfs_disk_name, store->block_size, DEV_BSIZE); if (store->size < SBSIZE + SBOFF) error (5, 0, "%s: Disk too small (%Ld bytes)", diskfs_disk_name, -- cgit v1.2.3 From 287caf2227a7432a3b4a3adaf7c7a85c120df4f4 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 8 May 2002 10:00:26 +0000 Subject: . --- ufs/ChangeLog | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index b568623a..f0192426 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,12 @@ +2002-05-08 Roland McGrath + + * main.c (diskfs_append_args): Fix argument type. + (main): Use %z format modifier for size_t arg. + * dir.c (dirscanblock): Use %z format modifier for vm_address_t arg. + (diskfs_dirempty): int -> vm_address_t + (count_dirents): int -> size_t + (diskfs_get_directs): u_int -> size_t + 2002-03-11 Roland McGrath * Makefile (ufs.static): Depend on -- cgit v1.2.3 From 155165974f8fbe5d448345e939792c5b30a20882 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 11 Jun 2002 21:40:58 +0000 Subject: 2002-06-08 Roland McGrath * dir.c (diskfs_direnter_hard): Use size_t for OLDSIZE. Fail with EOVERFLOW when it would exceed that width. * alloc.c, dir.c: Use %Ld format for ino_t values. * alloc.c (diskfs_alloc_node): Use %Ld format for blkcnt_t values. --- ufs/dir.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 3256bc42..b67e45f6 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -379,7 +379,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { - fprintf (stderr, "Bad directory entry: inode: %d offset: %zd\n", + fprintf (stderr, "Bad directory entry: inode: %Ld offset: %zd\n", dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } @@ -502,7 +502,7 @@ diskfs_direnter_hard(struct node *dp, vm_address_t fromoff, tooff; int totfreed; error_t err; - off_t oldsize = 0; + size_t oldsize = 0; assert (ds->type == CREATE); @@ -585,6 +585,12 @@ diskfs_direnter_hard(struct node *dp, assert (needed <= DIRBLKSIZ); oldsize = dp->dn_stat.st_size; + if ((off_t)(oldsize + DIRBLKSIZ) != dp->dn_stat.st_size) + { + /* We can't possibly map the whole directory in. */ + munmap ((caddr_t) ds->mapbuf, ds->mapextent); + return EOVERFLOW; + } while (oldsize + DIRBLKSIZ > dp->allocsize) { err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred); -- cgit v1.2.3 From 0df695e2e07f18089ce49a5bc728dc8643ed871e Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 11 Jun 2002 21:41:03 +0000 Subject: 2002-06-08 Roland McGrath * alloc.c, dir.c: Use %Ld format for ino_t values. * alloc.c (diskfs_alloc_node): Use %Ld format for blkcnt_t values. --- ufs/alloc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ufs') diff --git a/ufs/alloc.c b/ufs/alloc.c index e76b7703..48ee60cc 100644 --- a/ufs/alloc.c +++ b/ufs/alloc.c @@ -1,5 +1,5 @@ /* Disk allocation routines - Copyright (C) 1993, 94, 95, 96, 98 Free Software Foundation, Inc. + Copyright (C) 1993,94,95,96,98,2002 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -685,7 +685,7 @@ diskfs_alloc_node (struct node *dir, assert ("duplicate allocation" && !np->dn_stat.st_mode); assert (! (np->dn_stat.st_mode & S_IPTRANS)); if (np->dn_stat.st_blocks) { - printf("free inode %d had %ld blocks\n", + printf("free inode %Ld had %Ld blocks\n", ino, np->dn_stat.st_blocks); np->dn_stat.st_blocks = 0; np->dn_set_ctime = 1; @@ -1395,7 +1395,7 @@ ffs_blkfree(register struct node *np, assert ((u_int)size <= fs->fs_bsize && !fragoff (fs, size)); cg = dtog(fs, bno); if ((u_int)bno >= fs->fs_size) { - printf("bad block %ld, ino %d\n", bno, np->dn->number); + printf("bad block %ld, ino %Ld\n", bno, np->dn->number); /* ffs_fserr(fs, ip->i_uid, "bad block"); */ return; } @@ -1518,7 +1518,7 @@ diskfs_free_node (struct node *np, mode_t mode) cgp->cg_time = diskfs_mtime->seconds; ino %= fs->fs_ipg; if (isclr(cg_inosused(cgp), ino)) { -/* printf("dev = 0x%x, ino = %d, fs = %s\n", +/* printf("dev = 0x%x, ino = %Ld, fs = %s\n", pip->i_dev, ino, fs->fs_fsmnt); */ assert (diskfs_readonly); } -- cgit v1.2.3 From 0b6e196e43b7d496615d30d077df313e6642256c Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 11 Jun 2002 21:41:06 +0000 Subject: 2002-06-08 Roland McGrath * inode.c (diskfs_cached_lookup): Use ino_t for argument. --- ufs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index a258ea13..a8bb661f 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,5 @@ /* Inode management routines - Copyright (C) 1994,95,96,97,98,2000,01 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,98,2000,01,02 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -47,7 +47,7 @@ inode_init () /* Fetch inode INUM, set *NPP to the node structure; gain one user reference and lock the node. */ error_t -diskfs_cached_lookup (int inum, struct node **npp) +diskfs_cached_lookup (ino_t inum, struct node **npp) { struct disknode *dn; struct node *np; -- cgit v1.2.3 From 4769366ca8af3f3c39cabc604de33c7aef5814ed Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 11 Jun 2002 21:43:43 +0000 Subject: . --- ufs-fsck/ChangeLog | 10 ++++++++++ ufs-utils/ChangeLog | 4 ++++ ufs/ChangeLog | 10 ++++++++++ 3 files changed, 24 insertions(+) (limited to 'ufs') diff --git a/ufs-fsck/ChangeLog b/ufs-fsck/ChangeLog index 0e678ab5..7260520b 100644 --- a/ufs-fsck/ChangeLog +++ b/ufs-fsck/ChangeLog @@ -1,3 +1,13 @@ +2002-06-08 Roland McGrath + + * dir.c, pass1.c, pass1b.c, pass2.c: Use %Ld for ino_t values. + * utilities.c: Likewise. + + * fsck.h: Use ino_t for lfdir. + * setup.c: Likewise. + + * fsck.h (struct dirinfo): Use size_t for i_isize. + 2001-09-30 Roland McGrath * pass5.c (pass5): A little manual CSE makes buggy gcc not to crash. diff --git a/ufs-utils/ChangeLog b/ufs-utils/ChangeLog index 66cefd4c..f65e9ce1 100644 --- a/ufs-utils/ChangeLog +++ b/ufs-utils/ChangeLog @@ -1,3 +1,7 @@ +2002-06-08 Roland McGrath + + * mkfs.c (iput): Use %Ld format for ino_t values. + 2001-12-06 Roland McGrath * dlabel.c (fd_get_device): Only deallocate NODE if store_create fails. diff --git a/ufs/ChangeLog b/ufs/ChangeLog index f0192426..06e3b323 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,13 @@ +2002-06-08 Roland McGrath + + * inode.c (diskfs_cached_lookup): Use ino_t for argument. + + * dir.c (diskfs_direnter_hard): Use size_t for OLDSIZE. + Fail with EOVERFLOW when it would exceed that width. + + * alloc.c, dir.c: Use %Ld format for ino_t values. + * alloc.c (diskfs_alloc_node): Use %Ld format for blkcnt_t values. + 2002-05-08 Roland McGrath * main.c (diskfs_append_args): Fix argument type. -- cgit v1.2.3 From 25a921e6e16dfad15b5cdb37f0b6e81eacb8afe1 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 1 Aug 2002 00:59:34 +0000 Subject: 2002-07-31 Roland McGrath * dir.c (diskfs_direnter_hard): Fix test in last change. --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index b67e45f6..83b30e72 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -585,7 +585,7 @@ diskfs_direnter_hard(struct node *dp, assert (needed <= DIRBLKSIZ); oldsize = dp->dn_stat.st_size; - if ((off_t)(oldsize + DIRBLKSIZ) != dp->dn_stat.st_size) + if ((off_t)(oldsize + DIRBLKSIZ) != dp->dn_stat.st_size + DIRBLKSIZ) { /* We can't possibly map the whole directory in. */ munmap ((caddr_t) ds->mapbuf, ds->mapextent); -- cgit v1.2.3 From 5f792f6e012b161d85629a070b282ed76965df93 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 1 Aug 2002 00:59:41 +0000 Subject: . --- ufs/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 06e3b323..f0776c59 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +2002-07-31 Roland McGrath + + * dir.c (diskfs_direnter_hard): Fix test in last change. + 2002-06-08 Roland McGrath * inode.c (diskfs_cached_lookup): Use ino_t for argument. -- cgit v1.2.3 From 71d3ce15abd822ff64f395f8a06876c847515840 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 4 Oct 2002 20:55:48 +0000 Subject: 2002-10-03 Roland McGrath * dir.h (MAXNAMLEN): #undef before defining. --- ufs/dir.h | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs') diff --git a/ufs/dir.h b/ufs/dir.h index 2b1e3469..e37b1e9c 100644 --- a/ufs/dir.h +++ b/ufs/dir.h @@ -70,6 +70,7 @@ * dp->d_ino set to 0. */ #define DIRBLKSIZ DEV_BSIZE +#undef MAXNAMLEN #define MAXNAMLEN 255 /* Don't call this struct DIRECT because the library defines that -- cgit v1.2.3 From 03dc572901fa888f0ea0c57d2ab2fba5cea3ace5 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 4 Oct 2002 20:55:55 +0000 Subject: . --- ufs/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index f0776c59..e2409670 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +2002-10-03 Roland McGrath + + * dir.h (MAXNAMLEN): #undef before defining. + 2002-07-31 Roland McGrath * dir.c (diskfs_direnter_hard): Fix test in last change. -- cgit v1.2.3 From 993c89ad6e8b6413bab81e0720dd55d60d2f8173 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sun, 3 Aug 2003 14:23:21 +0000 Subject: Remove file that shouldn't be there. --- ufs/mapbuf.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 ufs/mapbuf.c (limited to 'ufs') diff --git a/ufs/mapbuf.c b/ufs/mapbuf.c deleted file mode 100644 index edf432a5..00000000 --- a/ufs/mapbuf.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Cache mappings of the disk - Copyright (C) 1994 Free Software Foundation, Inc. - Written by Michael I. Bushnell. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -#include "ufs.h" - -struct mapbuf *mblist; -spin_lock_t mblistlock = SPIN_LOCK_INITIALIZER; - -struct mapbuf * -map_region (vm_offset_t diskloc, vm_size_t length) -{ - struct mapbuf *mb; - - /* Check to see if we are already mapping this region */ - spin_lock (&mblistlock); - for (mb = mblist; mb; mb = mb->next) - { - -- cgit v1.2.3 From b3e5743bb26240cf69b2822446231178c50e2d9e Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Tue, 14 Mar 2006 23:26:37 +0000 Subject: 2006-03-15 Thomas Schwinge * dir.h (DIRECT_NAMELEN): Don't use ?: as a lvalue. --- ufs/ChangeLog | 4 ++++ ufs/dir.h | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index e2409670..aa30e784 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +2006-03-15 Thomas Schwinge + + * dir.h (DIRECT_NAMELEN): Don't use ?: as a lvalue. + 2002-10-03 Roland McGrath * dir.h (MAXNAMLEN): #undef before defining. diff --git a/ufs/dir.h b/ufs/dir.h index e37b1e9c..5730ef44 100644 --- a/ufs/dir.h +++ b/ufs/dir.h @@ -91,13 +91,13 @@ struct directory_entry { /* Return the namlen from a struct direct, paying attention to whether this filesystem supports the type extension */ #if (BYTE_ORDER == LITTLE_ENDIAN) -#define DIRECT_NAMLEN(dp) (direct_symlink_extension || swab_disk \ - ? (dp)->d_namlen \ - : (dp)->d_type) +#define DIRECT_NAMLEN(dp) (*(direct_symlink_extension || swab_disk \ + ? &(dp)->d_namlen \ + : &(dp)->d_type)) #else -#define DIRECT_NAMLEN(dp) (!direct_symlink_extension && swab_disk \ - ? (dp)->d_type \ - : (dp)->d_namlen) +#define DIRECT_NAMLEN(dp) (*(!direct_symlink_extension && swab_disk \ + ? &(dp)->d_type \ + : &(dp)->d_namlen)) #endif /* -- cgit v1.2.3 From 8c1ea85c28a7a8f0f1dd963ad22fce4bcc97f9bf Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Mon, 20 Aug 2007 15:51:49 +0000 Subject: [doc/ChangeLog] 2007-08-16 Samuel Thibault * hurd.texi: Document diskfs_set_node_atime. [ext2fs/ChangeLog] 2007-08-16 Samuel Thibault * dir.c (diskfs_lookup_hard, diskfs_dirempty): Call diskfs_set_node_atime instead of setting dp->dn_set_atime. [fatfs/ChangeLog] 2007-08-16 Samuel Thibault * dir.c (diskfs_lookup_hard, diskfs_dirempty): Call diskfs_set_node_atime instead of setting dp->dn_set_atime. [libdiskfs/ChangeLog] 2007-08-16 Samuel Thibault * diskfs.h (diskfs_set_node_atime): New declaration. * node-times.c (diskfs_set_node_atime): New function. [ufs/ChangeLog] 2007-08-16 Samuel Thibault * dir.c (diskfs_lookup_hard, diskfs_dirempty): Call diskfs_set_node_atime instead of setting dp->dn_set_atime. * inode.c (read_symlink_hook): Likewise. --- ufs/ChangeLog | 6 ++++++ ufs/dir.c | 15 +++++---------- ufs/inode.c | 3 +-- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index aa30e784..c7f01b7a 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,9 @@ +2007-08-16 Samuel Thibault + + * dir.c (diskfs_lookup_hard, diskfs_dirempty): Call + diskfs_set_node_atime instead of setting dp->dn_set_atime. + * inode.c (read_symlink_hook): Likewise. + 2006-03-15 Thomas Schwinge * dir.h (DIRECT_NAMELEN): Don't use ?: as a lvalue. diff --git a/ufs/dir.c b/ufs/dir.c index 83b30e72..7d9b0f55 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -162,8 +162,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, inum = 0; - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); /* Start the lookup at DP->dn->dir_idx. */ idx = dp->dn->dir_idx; @@ -200,8 +199,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, } } - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); @@ -752,8 +750,7 @@ diskfs_dirempty(struct node *dp, mach_port_deallocate (mach_task_self (), memobj); assert (!err); - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); for (curoff = buf; curoff < buf + dp->dn_stat.st_size; @@ -768,15 +765,13 @@ diskfs_dirempty(struct node *dp, && entry->d_name[1] != '\0'))) { munmap ((caddr_t) buf, dp->dn_stat.st_size); - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); return 0; } } - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); munmap ((caddr_t) buf, dp->dn_stat.st_size); diff --git a/ufs/inode.c b/ufs/inode.c index a8bb661f..228429b1 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -431,8 +431,7 @@ read_symlink_hook (struct node *np, bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); - if (! diskfs_check_readonly ()) - np->dn_set_atime = 1; + diskfs_set_node_atime (dp); diskfs_end_catch_exception (); return 0; -- cgit v1.2.3 From 21401a666fa450990a18ffce8f09e1fbc782e081 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Mon, 20 Aug 2007 15:53:31 +0000 Subject: compilation fix --- ufs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs') diff --git a/ufs/inode.c b/ufs/inode.c index 228429b1..221a78f7 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -431,7 +431,7 @@ read_symlink_hook (struct node *np, bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); - diskfs_set_node_atime (dp); + diskfs_set_node_atime (np); diskfs_end_catch_exception (); return 0; -- cgit v1.2.3 From 52ea733b99cb7de4794b0a8b3fa19dec57ec0ee9 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Fri, 5 Oct 2007 10:00:44 +0000 Subject: Update copyright years. --- ufs/dir.c | 4 +++- ufs/inode.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'ufs') diff --git a/ufs/dir.c b/ufs/dir.c index 7d9b0f55..7a8cfa55 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,7 @@ /* Directory management routines - Copyright (C) 1994,95,96,97,98,99,2000,02 Free Software Foundation, Inc. + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2007 + Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/ufs/inode.c b/ufs/inode.c index 221a78f7..8223fe7f 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,7 @@ /* Inode management routines - Copyright (C) 1994,95,96,97,98,2000,01,02 Free Software Foundation, Inc. + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2007 + Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as -- cgit v1.2.3 From ac6532774d82f0256e6821f3120e7983e4ed5cb6 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Tue, 13 Nov 2007 23:32:45 +0000 Subject: 2007-11-13 Thomas Schwinge * inode.c (read_disknode, write_node): Adapt to ``struct stat'' changes. --- ufs/ChangeLog | 5 +++++ ufs/inode.c | 36 ++++++++++++------------------------ 2 files changed, 17 insertions(+), 24 deletions(-) (limited to 'ufs') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index c7f01b7a..14fb86bd 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +2007-11-13 Thomas Schwinge + + * inode.c (read_disknode, write_node): Adapt to ``struct stat'' + changes. + 2007-08-16 Samuel Thibault * dir.c (diskfs_lookup_hard, diskfs_dirempty): Call diff --git a/ufs/inode.c b/ufs/inode.c index 8223fe7f..1a8a7098 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -233,18 +233,12 @@ read_disknode (struct node *np) | (di->di_trans ? S_IPTRANS : 0)); st->st_nlink = read_disk_entry (di->di_nlink); st->st_size = read_disk_entry (di->di_size); -#ifdef notyet - st->st_atimespec = di->di_atime; - st->st_mtimespec = di->di_mtime; - st->st_ctimespec = di->di_ctime; -#else - st->st_atime = read_disk_entry (di->di_atime.tv_sec); - st->st_atime_usec = read_disk_entry (di->di_atime.tv_nsec) / 1000; - st->st_mtime = read_disk_entry (di->di_mtime.tv_sec); - st->st_mtime_usec = read_disk_entry (di->di_mtime.tv_nsec) / 1000; - st->st_ctime = read_disk_entry (di->di_ctime.tv_sec); - st->st_ctime_usec = read_disk_entry (di->di_ctime.tv_nsec) / 1000; -#endif + st->st_atim.tv_sec = read_disk_entry (di->di_atime.tv_sec); + st->st_atim.tv_nsec = read_disk_entry (di->di_atime.tv_nsec); + st->st_mtim.tv_sec = read_disk_entry (di->di_mtime.tv_sec); + st->st_mtim.tv_nsec = read_disk_entry (di->di_mtime.tv_nsec); + st->st_ctim.tv_sec = read_disk_entry (di->di_ctime.tv_sec); + st->st_ctim.tv_nsec = read_disk_entry (di->di_ctime.tv_nsec); st->st_blksize = sblock->fs_bsize; st->st_blocks = read_disk_entry (di->di_blocks); st->st_flags = read_disk_entry (di->di_flags); @@ -359,18 +353,12 @@ write_node (struct node *np) write_disk_entry (di->di_nlink, st->st_nlink); write_disk_entry (di->di_size, st->st_size); -#ifdef notyet - di->di_atime = st->st_atimespec; - di->di_mtime = st->st_mtimespec; - di->di_ctime = st->st_ctimespec; -#else - write_disk_entry (di->di_atime.tv_sec, st->st_atime); - write_disk_entry (di->di_atime.tv_nsec, st->st_atime_usec * 1000); - write_disk_entry (di->di_mtime.tv_sec, st->st_mtime); - write_disk_entry (di->di_mtime.tv_nsec, st->st_mtime_usec * 1000); - write_disk_entry (di->di_ctime.tv_sec, st->st_ctime); - write_disk_entry (di->di_ctime.tv_nsec, st->st_ctime_usec * 1000); -#endif + write_disk_entry (di->di_atime.tv_sec, st->st_atim.tv_sec); + write_disk_entry (di->di_atime.tv_nsec, st->st_atim.tv_nsec); + write_disk_entry (di->di_mtime.tv_sec, st->st_mtim.tv_sec); + write_disk_entry (di->di_mtime.tv_nsec, st->st_mtim.tv_nsec); + write_disk_entry (di->di_ctime.tv_sec, st->st_ctim.tv_sec); + write_disk_entry (di->di_ctime.tv_nsec, st->st_ctim.tv_nsec); write_disk_entry (di->di_blocks, st->st_blocks); write_disk_entry (di->di_flags, st->st_flags); -- cgit v1.2.3