aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>1998-01-30 11:34:06 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>1998-01-30 11:34:06 +0000
commitc5b193bfba1554a4cff9c68e314075232062cb0c (patch)
treefdc79305d10647f82f07d244d93c3059fd6942f9
parent0621c31aaf75cb057cf4945650f22d3fed21a9d7 (diff)
downloadsrc-c5b193bfba1554a4cff9c68e314075232062cb0c.tar.gz
src-c5b193bfba1554a4cff9c68e314075232062cb0c.zip
Retire LFS.
If you want to play with it, you can find the final version of the code in the repository the tag LFS_RETIREMENT. If somebody makes LFS work again, adding it back is certainly desireable, but as it is now nobody seems to care much about it, and it has suffered considerable bitrot since its somewhat haphazard integration. R.I.P
Notes
Notes: svn path=/head/; revision=32889
-rw-r--r--sys/amd64/amd64/autoconf.c21
-rw-r--r--sys/conf/NOTES8
-rw-r--r--sys/conf/files11
-rw-r--r--sys/conf/options4
-rw-r--r--sys/gnu/ext2fs/ext2_mount.h4
-rw-r--r--sys/gnu/ext2fs/inode.h4
-rw-r--r--sys/gnu/fs/ext2fs/ext2_mount.h4
-rw-r--r--sys/gnu/fs/ext2fs/inode.h4
-rw-r--r--sys/i386/conf/LINT8
-rw-r--r--sys/i386/conf/NOTES8
-rw-r--r--sys/i386/i386/autoconf.c21
-rw-r--r--sys/kern/init_main.c5
-rw-r--r--sys/kern/init_sysent.c17
-rw-r--r--sys/kern/syscalls.c17
-rw-r--r--sys/kern/syscalls.master23
-rw-r--r--sys/sys/syscall-hide.h9
-rw-r--r--sys/sys/syscall.h6
-rw-r--r--sys/sys/sysproto.h49
-rw-r--r--sys/ufs/lfs/README139
-rw-r--r--sys/ufs/lfs/TODO116
-rw-r--r--sys/ufs/lfs/lfs.h397
-rw-r--r--sys/ufs/lfs/lfs_alloc.c252
-rw-r--r--sys/ufs/lfs/lfs_balloc.c245
-rw-r--r--sys/ufs/lfs/lfs_bio.c202
-rw-r--r--sys/ufs/lfs/lfs_cksum.c69
-rw-r--r--sys/ufs/lfs/lfs_debug.c139
-rw-r--r--sys/ufs/lfs/lfs_extern.h97
-rw-r--r--sys/ufs/lfs/lfs_inode.c378
-rw-r--r--sys/ufs/lfs/lfs_segment.c1248
-rw-r--r--sys/ufs/lfs/lfs_subr.c184
-rw-r--r--sys/ufs/lfs/lfs_syscalls.c582
-rw-r--r--sys/ufs/lfs/lfs_vfsops.c737
-rw-r--r--sys/ufs/lfs/lfs_vnops.c232
-rw-r--r--sys/ufs/ufs/inode.h4
-rw-r--r--sys/ufs/ufs/ufs_readwrite.c31
-rw-r--r--sys/ufs/ufs/ufsmount.h4
36 files changed, 47 insertions, 5232 deletions
diff --git a/sys/amd64/amd64/autoconf.c b/sys/amd64/amd64/autoconf.c
index a9dbc8526fb4..e40bda18552a 100644
--- a/sys/amd64/amd64/autoconf.c
+++ b/sys/amd64/amd64/autoconf.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
- * $Id: autoconf.c,v 1.83 1998/01/09 03:20:53 eivind Exp $
+ * $Id: autoconf.c,v 1.84 1998/01/24 02:54:12 eivind Exp $
*/
/*
@@ -48,7 +48,6 @@
#include "opt_bootp.h"
#include "opt_ffs.h"
#include "opt_cd9660.h"
-#include "opt_lfs.h"
#include "opt_mfs.h"
#include "opt_nfs.h"
@@ -370,24 +369,6 @@ cpu_rootconf()
}
#endif
-#if defined(LFS) || defined(LFS_ROOT)
- if (!mountrootfsname) {
- if (bootverbose)
- printf("Considering LFS root f/s.\n");
- mountrootfsname = "lfs";
- /*
- * Ignore the -a flag if this kernel isn't compiled
- * with a generic root/swap configuration: if we skip
- * setroot() and we aren't a generic kernel, chaos
- * will ensue because setconf() will be a no-op.
- * (rootdev is always initialized to NODEV in a
- * generic configuration, so we test for that.)
- */
- if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV)
- setroot();
- }
-#endif
-
if (!mountrootfsname) {
panic("Nobody wants to mount my root for me");
}
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 8f6249127e86..6f3cdfef2b67 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.395 1998/01/25 03:55:47 eivind Exp $
+# $Id: LINT,v 1.396 1998/01/26 06:33:48 julian Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -424,11 +424,11 @@ options TCPDEBUG
#
# Only the root, /usr, and /tmp filesystems need be statically
# compiled; everything else will be automatically loaded at mount
-# time. (Exception: the UFS family---FFS, MFS, and LFS---cannot
+# time. (Exception: the UFS family---FFS, and MFS --- cannot
# currently be demand-loaded.) Some people still prefer to statically
# compile other filesystems as well.
#
-# NB: The LFS, PORTAL, and UNION filesystems are known to be buggy,
+# NB: The PORTAL, and UNION filesystems are known to be buggy,
# and WILL panic your system if you attempt to do anything with them.
# They are included here as an incentive for some enterprising soul to
# sit down and fix them.
@@ -443,7 +443,6 @@ options NFS #Network File System
options "CD9660" #ISO 9660 filesystem
options FDESC #File descriptor filesystem
options KERNFS #Kernel filesystem
-#options LFS #Log filesystem
options MFS #Memory File System
options MSDOSFS #MS DOS File System
options NULLFS #NULL filesystem
@@ -453,7 +452,6 @@ options UMAPFS #UID map filesystem
options UNION #Union filesystem
options "CD9660_ROOT" #CD-ROM usable as root device
options FFS_ROOT #FFS usable as root device
-#options LFS_ROOT #LFS usable as root device
options NFS_ROOT #NFS usable as root device
# This DEVFS is experimental but seems to work
options DEVFS #devices filesystem
diff --git a/sys/conf/files b/sys/conf/files
index 098fdad62461..59da1772412a 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -412,17 +412,6 @@ ufs/ffs/ffs_vfsops.c optional ffs
ufs/ffs/ffs_vfsops.c optional mfs
ufs/ffs/ffs_vnops.c optional ffs
ufs/ffs/ffs_vnops.c optional mfs
-ufs/lfs/lfs_alloc.c optional lfs
-ufs/lfs/lfs_balloc.c optional lfs
-ufs/lfs/lfs_bio.c optional lfs
-ufs/lfs/lfs_cksum.c optional lfs
-ufs/lfs/lfs_debug.c optional lfs
-ufs/lfs/lfs_inode.c optional lfs
-ufs/lfs/lfs_segment.c optional lfs
-ufs/lfs/lfs_subr.c optional lfs
-ufs/lfs/lfs_syscalls.c optional lfs
-ufs/lfs/lfs_vfsops.c optional lfs
-ufs/lfs/lfs_vnops.c optional lfs
ufs/mfs/mfs_vfsops.c optional mfs
ufs/mfs/mfs_vnops.c optional mfs
ufs/ufs/ufs_bmap.c standard
diff --git a/sys/conf/options b/sys/conf/options
index 0f24d1e9fc2a..c0742f6f28bf 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -1,4 +1,4 @@
-# $Id: options,v 1.49 1998/01/25 04:23:29 eivind Exp $
+# $Id: options,v 1.50 1998/01/26 18:31:18 julian Exp $
# Format:
# Option name filename
@@ -48,7 +48,6 @@ UMAPFS opt_dontuse.h
# unavailable for the LKM-based versions.
CD9660
FFS
-LFS
NFS
# The above static dependencies are planned removed, with a
@@ -57,7 +56,6 @@ NFS
# they won't make any difference yet).
CD9660_ROOT opt_cd9660.h
FFS_ROOT opt_ffs.h
-LFS_ROOT opt_lfs.h
NFS_ROOT opt_nfs.h
# Multi-session CD-Rs might require a huge amount of time in order to
diff --git a/sys/gnu/ext2fs/ext2_mount.h b/sys/gnu/ext2fs/ext2_mount.h
index ee7963190c89..c62b736034f5 100644
--- a/sys/gnu/ext2fs/ext2_mount.h
+++ b/sys/gnu/ext2fs/ext2_mount.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ufsmount.h 8.6 (Berkeley) 3/30/95
- * $Id: ufsmount.h,v 1.11 1997/10/16 10:50:27 phk Exp $
+ * $Id: ufsmount.h,v 1.12 1997/10/16 20:32:40 phk Exp $
*/
#ifndef _UFS_UFS_UFSMOUNT_H_
@@ -77,12 +77,10 @@ struct ufsmount {
struct vnode *um_devvp; /* block device mounted vnode */
union { /* pointer to superblock */
- struct lfs *lfs; /* LFS */
struct fs *fs; /* FFS */
struct ext2_sb_info *e2fs; /* EXT2FS */
} ufsmount_u;
#define um_fs ufsmount_u.fs
-#define um_lfs ufsmount_u.lfs
#define um_e2fs ufsmount_u.e2fs
#define um_e2fsb ufsmount_u.e2fs->s_es
diff --git a/sys/gnu/ext2fs/inode.h b/sys/gnu/ext2fs/inode.h
index 161de4bc9440..f2fd0f25fa5e 100644
--- a/sys/gnu/ext2fs/inode.h
+++ b/sys/gnu/ext2fs/inode.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)inode.h 8.9 (Berkeley) 5/14/95
- * $Id: inode.h,v 1.18 1997/10/17 12:36:19 phk Exp $
+ * $Id: inode.h,v 1.19 1997/12/05 13:43:47 jkh Exp $
*/
#ifndef _UFS_UFS_INODE_H_
@@ -70,11 +70,9 @@ struct inode {
union { /* Associated filesystem. */
struct fs *fs; /* FFS */
- struct lfs *lfs; /* LFS */
struct ext2_sb_info *e2fs; /* EXT2FS */
} inode_u;
#define i_fs inode_u.fs
-#define i_lfs inode_u.lfs
#define i_e2fs inode_u.e2fs
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for NFS lease. */
diff --git a/sys/gnu/fs/ext2fs/ext2_mount.h b/sys/gnu/fs/ext2fs/ext2_mount.h
index ee7963190c89..c62b736034f5 100644
--- a/sys/gnu/fs/ext2fs/ext2_mount.h
+++ b/sys/gnu/fs/ext2fs/ext2_mount.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ufsmount.h 8.6 (Berkeley) 3/30/95
- * $Id: ufsmount.h,v 1.11 1997/10/16 10:50:27 phk Exp $
+ * $Id: ufsmount.h,v 1.12 1997/10/16 20:32:40 phk Exp $
*/
#ifndef _UFS_UFS_UFSMOUNT_H_
@@ -77,12 +77,10 @@ struct ufsmount {
struct vnode *um_devvp; /* block device mounted vnode */
union { /* pointer to superblock */
- struct lfs *lfs; /* LFS */
struct fs *fs; /* FFS */
struct ext2_sb_info *e2fs; /* EXT2FS */
} ufsmount_u;
#define um_fs ufsmount_u.fs
-#define um_lfs ufsmount_u.lfs
#define um_e2fs ufsmount_u.e2fs
#define um_e2fsb ufsmount_u.e2fs->s_es
diff --git a/sys/gnu/fs/ext2fs/inode.h b/sys/gnu/fs/ext2fs/inode.h
index 161de4bc9440..f2fd0f25fa5e 100644
--- a/sys/gnu/fs/ext2fs/inode.h
+++ b/sys/gnu/fs/ext2fs/inode.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)inode.h 8.9 (Berkeley) 5/14/95
- * $Id: inode.h,v 1.18 1997/10/17 12:36:19 phk Exp $
+ * $Id: inode.h,v 1.19 1997/12/05 13:43:47 jkh Exp $
*/
#ifndef _UFS_UFS_INODE_H_
@@ -70,11 +70,9 @@ struct inode {
union { /* Associated filesystem. */
struct fs *fs; /* FFS */
- struct lfs *lfs; /* LFS */
struct ext2_sb_info *e2fs; /* EXT2FS */
} inode_u;
#define i_fs inode_u.fs
-#define i_lfs inode_u.lfs
#define i_e2fs inode_u.e2fs
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for NFS lease. */
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index 8f6249127e86..6f3cdfef2b67 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.395 1998/01/25 03:55:47 eivind Exp $
+# $Id: LINT,v 1.396 1998/01/26 06:33:48 julian Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -424,11 +424,11 @@ options TCPDEBUG
#
# Only the root, /usr, and /tmp filesystems need be statically
# compiled; everything else will be automatically loaded at mount
-# time. (Exception: the UFS family---FFS, MFS, and LFS---cannot
+# time. (Exception: the UFS family---FFS, and MFS --- cannot
# currently be demand-loaded.) Some people still prefer to statically
# compile other filesystems as well.
#
-# NB: The LFS, PORTAL, and UNION filesystems are known to be buggy,
+# NB: The PORTAL, and UNION filesystems are known to be buggy,
# and WILL panic your system if you attempt to do anything with them.
# They are included here as an incentive for some enterprising soul to
# sit down and fix them.
@@ -443,7 +443,6 @@ options NFS #Network File System
options "CD9660" #ISO 9660 filesystem
options FDESC #File descriptor filesystem
options KERNFS #Kernel filesystem
-#options LFS #Log filesystem
options MFS #Memory File System
options MSDOSFS #MS DOS File System
options NULLFS #NULL filesystem
@@ -453,7 +452,6 @@ options UMAPFS #UID map filesystem
options UNION #Union filesystem
options "CD9660_ROOT" #CD-ROM usable as root device
options FFS_ROOT #FFS usable as root device
-#options LFS_ROOT #LFS usable as root device
options NFS_ROOT #NFS usable as root device
# This DEVFS is experimental but seems to work
options DEVFS #devices filesystem
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 8f6249127e86..6f3cdfef2b67 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.395 1998/01/25 03:55:47 eivind Exp $
+# $Id: LINT,v 1.396 1998/01/26 06:33:48 julian Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -424,11 +424,11 @@ options TCPDEBUG
#
# Only the root, /usr, and /tmp filesystems need be statically
# compiled; everything else will be automatically loaded at mount
-# time. (Exception: the UFS family---FFS, MFS, and LFS---cannot
+# time. (Exception: the UFS family---FFS, and MFS --- cannot
# currently be demand-loaded.) Some people still prefer to statically
# compile other filesystems as well.
#
-# NB: The LFS, PORTAL, and UNION filesystems are known to be buggy,
+# NB: The PORTAL, and UNION filesystems are known to be buggy,
# and WILL panic your system if you attempt to do anything with them.
# They are included here as an incentive for some enterprising soul to
# sit down and fix them.
@@ -443,7 +443,6 @@ options NFS #Network File System
options "CD9660" #ISO 9660 filesystem
options FDESC #File descriptor filesystem
options KERNFS #Kernel filesystem
-#options LFS #Log filesystem
options MFS #Memory File System
options MSDOSFS #MS DOS File System
options NULLFS #NULL filesystem
@@ -453,7 +452,6 @@ options UMAPFS #UID map filesystem
options UNION #Union filesystem
options "CD9660_ROOT" #CD-ROM usable as root device
options FFS_ROOT #FFS usable as root device
-#options LFS_ROOT #LFS usable as root device
options NFS_ROOT #NFS usable as root device
# This DEVFS is experimental but seems to work
options DEVFS #devices filesystem
diff --git a/sys/i386/i386/autoconf.c b/sys/i386/i386/autoconf.c
index a9dbc8526fb4..e40bda18552a 100644
--- a/sys/i386/i386/autoconf.c
+++ b/sys/i386/i386/autoconf.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
- * $Id: autoconf.c,v 1.83 1998/01/09 03:20:53 eivind Exp $
+ * $Id: autoconf.c,v 1.84 1998/01/24 02:54:12 eivind Exp $
*/
/*
@@ -48,7 +48,6 @@
#include "opt_bootp.h"
#include "opt_ffs.h"
#include "opt_cd9660.h"
-#include "opt_lfs.h"
#include "opt_mfs.h"
#include "opt_nfs.h"
@@ -370,24 +369,6 @@ cpu_rootconf()
}
#endif
-#if defined(LFS) || defined(LFS_ROOT)
- if (!mountrootfsname) {
- if (bootverbose)
- printf("Considering LFS root f/s.\n");
- mountrootfsname = "lfs";
- /*
- * Ignore the -a flag if this kernel isn't compiled
- * with a generic root/swap configuration: if we skip
- * setroot() and we aren't a generic kernel, chaos
- * will ensue because setconf() will be a no-op.
- * (rootdev is always initialized to NODEV in a
- * generic configuration, so we test for that.)
- */
- if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV)
- setroot();
- }
-#endif
-
if (!mountrootfsname) {
panic("Nobody wants to mount my root for me");
}
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 03f707ccca9c..7cdb77ac71d5 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
- * $Id: init_main.c,v 1.79 1997/12/14 02:10:12 dyson Exp $
+ * $Id: init_main.c,v 1.80 1998/01/22 17:29:44 dyson Exp $
*/
#include "opt_devfs.h"
@@ -139,8 +139,7 @@ SYSINIT(placeholder, SI_SUB_DUMMY,SI_ORDER_ANY, NULL, NULL)
* This allows simple addition of new kernel subsystems that require
* boot time initialization. It also allows substitution of subsystem
* (for instance, a scheduler, kernel profiler, or VM system) by object
- * module. Finally, it allows for optional "kernel threads", like an LFS
- * cleaner.
+ * module. Finally, it allows for optional "kernel threads".
*/
void
main(framep)
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index f95255aa5025..4697d70249cb 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -2,7 +2,7 @@
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.44 1997/10/26 20:27:51 phk Exp
+ * created from Id: syscalls.master,v 1.46 1998/01/24 02:54:35 eivind Exp
*/
#include "opt_compat.h"
@@ -203,17 +203,10 @@ struct sysent sysent[] = {
{ 1, (sy_call_t *)setgid }, /* 181 = setgid */
{ 1, (sy_call_t *)setegid }, /* 182 = setegid */
{ 1, (sy_call_t *)seteuid }, /* 183 = seteuid */
-#ifdef LFS
- { 3, (sy_call_t *)lfs_bmapv }, /* 184 = lfs_bmapv */
- { 3, (sy_call_t *)lfs_markv }, /* 185 = lfs_markv */
- { 2, (sy_call_t *)lfs_segclean }, /* 186 = lfs_segclean */
- { 2, (sy_call_t *)lfs_segwait }, /* 187 = lfs_segwait */
-#else
- { 0, (sy_call_t *)nosys }, /* 184 = nosys */
- { 0, (sy_call_t *)nosys }, /* 185 = nosys */
- { 0, (sy_call_t *)nosys }, /* 186 = nosys */
- { 0, (sy_call_t *)nosys }, /* 187 = nosys */
-#endif
+ { 0, (sy_call_t *)nosys }, /* 184 = lfs_bmapv */
+ { 0, (sy_call_t *)nosys }, /* 185 = lfs_markv */
+ { 0, (sy_call_t *)nosys }, /* 186 = lfs_segclean */
+ { 0, (sy_call_t *)nosys }, /* 187 = lfs_segwait */
{ 2, (sy_call_t *)stat }, /* 188 = stat */
{ 2, (sy_call_t *)fstat }, /* 189 = fstat */
{ 2, (sy_call_t *)lstat }, /* 190 = lstat */
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index 68645dff762d..09bd89085822 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -2,7 +2,7 @@
* System call names.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.44 1997/10/26 20:27:51 phk Exp
+ * created from Id: syscalls.master,v 1.46 1998/01/24 02:54:35 eivind Exp
*/
char *syscallnames[] = {
@@ -190,17 +190,10 @@ char *syscallnames[] = {
"setgid", /* 181 = setgid */
"setegid", /* 182 = setegid */
"seteuid", /* 183 = seteuid */
-#ifdef LFS
- "lfs_bmapv", /* 184 = lfs_bmapv */
- "lfs_markv", /* 185 = lfs_markv */
- "lfs_segclean", /* 186 = lfs_segclean */
- "lfs_segwait", /* 187 = lfs_segwait */
-#else
- "#184", /* 184 = nosys */
- "#185", /* 185 = nosys */
- "#186", /* 186 = nosys */
- "#187", /* 187 = nosys */
-#endif
+ "#184", /* 184 = lfs_bmapv */
+ "#185", /* 185 = lfs_markv */
+ "#186", /* 186 = lfs_segclean */
+ "#187", /* 187 = lfs_segwait */
"stat", /* 188 = stat */
"fstat", /* 189 = fstat */
"lstat", /* 190 = lstat */
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index d2998e212271..43a5a9b4ba0b 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -1,4 +1,4 @@
- $Id: syscalls.master,v 1.45 1998/01/01 17:07:46 alex Exp $
+ $Id: syscalls.master,v 1.46 1998/01/24 02:54:35 eivind Exp $
; from: @(#)syscalls.master 8.2 (Berkeley) 1/13/94
;
; System call name/number master file.
@@ -24,8 +24,6 @@
; #ifdef's, etc. may be included, and are copied to the output files.
-#include "opt_lfs.h"
-
#include <sys/param.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
@@ -280,21 +278,10 @@
181 STD POSIX { int setgid(gid_t gid); }
182 STD BSD { int setegid(gid_t egid); }
183 STD BSD { int seteuid(uid_t euid); }
-#ifdef LFS
-184 STD BSD { int lfs_bmapv(struct fsid **fsidp, \
- struct block_info *blkiov, int blkcnt); }
-185 STD BSD { int lfs_markv(struct fsid **fsidp, \
- struct block_info *blkiov, int blkcnt); }
-186 STD BSD { int lfs_segclean(struct fsid **fsidp, \
- u_long segment); }
-187 STD BSD { int lfs_segwait(struct fsid **fsidp, \
- struct timeval *tv); }
-#else
-184 UNIMPL BSD nosys
-185 UNIMPL BSD nosys
-186 UNIMPL BSD nosys
-187 UNIMPL BSD nosys
-#endif
+184 UNIMPL BSD lfs_bmapv
+185 UNIMPL BSD lfs_markv
+186 UNIMPL BSD lfs_segclean
+187 UNIMPL BSD lfs_segwait
188 STD POSIX { int stat(char *path, struct stat *ub); }
189 STD POSIX { int fstat(int fd, struct stat *sb); }
190 STD POSIX { int lstat(char *path, struct stat *ub); }
diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h
index b940734314f8..42fb3a4095bd 100644
--- a/sys/sys/syscall-hide.h
+++ b/sys/sys/syscall-hide.h
@@ -2,7 +2,7 @@
* System call hiders.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.44 1997/10/26 20:27:51 phk Exp
+ * created from Id: syscalls.master,v 1.46 1998/01/24 02:54:35 eivind Exp
*/
HIDE_POSIX(fork)
@@ -162,17 +162,10 @@ HIDE_BSD(ntp_adjtime)
HIDE_POSIX(setgid)
HIDE_BSD(setegid)
HIDE_BSD(seteuid)
-#ifdef LFS
HIDE_BSD(lfs_bmapv)
HIDE_BSD(lfs_markv)
HIDE_BSD(lfs_segclean)
HIDE_BSD(lfs_segwait)
-#else
-HIDE_BSD(nosys)
-HIDE_BSD(nosys)
-HIDE_BSD(nosys)
-HIDE_BSD(nosys)
-#endif
HIDE_POSIX(stat)
HIDE_POSIX(fstat)
HIDE_POSIX(lstat)
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
index 8ddfe85d29af..b01e8910af06 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -2,7 +2,7 @@
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.44 1997/10/26 20:27:51 phk Exp
+ * created from Id: syscalls.master,v 1.46 1998/01/24 02:54:35 eivind Exp
*/
#define SYS_syscall 0
@@ -170,10 +170,6 @@
#define SYS_setgid 181
#define SYS_setegid 182
#define SYS_seteuid 183
-#define SYS_lfs_bmapv 184
-#define SYS_lfs_markv 185
-#define SYS_lfs_segclean 186
-#define SYS_lfs_segwait 187
#define SYS_stat 188
#define SYS_fstat 189
#define SYS_lstat 190
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
index 7f89cb8d157e..1429083c331e 100644
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -2,7 +2,7 @@
* System call prototypes.
*
* DO NOT EDIT-- this file is automatically generated.
- * created from Id: syscalls.master,v 1.44 1997/10/26 20:27:51 phk Exp
+ * created from Id: syscalls.master,v 1.46 1998/01/24 02:54:35 eivind Exp
*/
#ifndef _SYS_SYSPROTO_H_
@@ -246,7 +246,7 @@ struct getpagesize_args {
int dummy;
};
struct msync_args {
- caddr_t addr;
+ void * addr;
size_t len;
int flags;
};
@@ -263,16 +263,16 @@ struct ovadvise_args {
int anom;
};
struct munmap_args {
- caddr_t addr;
+ void * addr;
size_t len;
};
struct mprotect_args {
- caddr_t addr;
+ const void * addr;
size_t len;
int prot;
};
struct madvise_args {
- caddr_t addr;
+ void * addr;
size_t len;
int behav;
};
@@ -549,27 +549,6 @@ struct setegid_args {
struct seteuid_args {
uid_t euid;
};
-#ifdef LFS
-struct lfs_bmapv_args {
- struct fsid ** fsidp;
- struct block_info * blkiov;
- int blkcnt;
-};
-struct lfs_markv_args {
- struct fsid ** fsidp;
- struct block_info * blkiov;
- int blkcnt;
-};
-struct lfs_segclean_args {
- struct fsid ** fsidp;
- u_long segment;
-};
-struct lfs_segwait_args {
- struct fsid ** fsidp;
- struct timeval * tv;
-};
-#else
-#endif
struct stat_args {
char * path;
struct stat * ub;
@@ -638,11 +617,11 @@ struct sysctl_args {
size_t newlen;
};
struct mlock_args {
- caddr_t addr;
+ const void * addr;
size_t len;
};
struct munlock_args {
- caddr_t addr;
+ const void * addr;
size_t len;
};
struct utrace_args {
@@ -736,7 +715,7 @@ struct nanosleep_args {
struct timespec * rmtp;
};
struct minherit_args {
- caddr_t addr;
+ void * addr;
size_t len;
int inherit;
};
@@ -967,13 +946,6 @@ int ntp_adjtime __P((struct proc *, struct ntp_adjtime_args *));
int setgid __P((struct proc *, struct setgid_args *));
int setegid __P((struct proc *, struct setegid_args *));
int seteuid __P((struct proc *, struct seteuid_args *));
-#ifdef LFS
-int lfs_bmapv __P((struct proc *, struct lfs_bmapv_args *));
-int lfs_markv __P((struct proc *, struct lfs_markv_args *));
-int lfs_segclean __P((struct proc *, struct lfs_segclean_args *));
-int lfs_segwait __P((struct proc *, struct lfs_segwait_args *));
-#else
-#endif
int stat __P((struct proc *, struct stat_args *));
int fstat __P((struct proc *, struct fstat_args *));
int lstat __P((struct proc *, struct lstat_args *));
@@ -1071,7 +1043,7 @@ struct getkerninfo_args {
int arg;
};
struct ommap_args {
- caddr_t addr;
+ void * addr;
int len;
int prot;
int flags;
@@ -1157,9 +1129,6 @@ struct ogetdirentries_args {
u_int count;
long * basep;
};
-#ifdef LFS
-#else
-#endif
int ocreat __P((struct proc *, struct ocreat_args *));
int olseek __P((struct proc *, struct olseek_args *));
int ostat __P((struct proc *, struct ostat_args *));
diff --git a/sys/ufs/lfs/README b/sys/ufs/lfs/README
deleted file mode 100644
index 724b18fb9ea5..000000000000
--- a/sys/ufs/lfs/README
+++ /dev/null
@@ -1,139 +0,0 @@
-# @(#)README 8.1 (Berkeley) 6/11/93
-
-The file system is reasonably stable, but incomplete. There are
-places where cleaning performance can be improved dramatically (see
-comments in lfs_syscalls.c). For details on the implementation,
-performance and why garbage collection always wins, see Dr. Margo
-Seltzer's thesis available for anonymous ftp from toe.cs.berkeley.edu,
-in the directory pub/personal/margo/thesis.ps.Z, or the January 1993
-USENIX paper.
-
-Missing Functionality:
- Multiple block sizes and/or fragments are not yet implemented.
-
-----------
-The disk is laid out in segments. The first segment starts 8K into the
-disk (the first 8K is used for boot information). Each segment is composed
-of the following:
-
- An optional super block
- One or more groups of:
- segment summary
- 0 or more data blocks
- 0 or more inode blocks
-
-The segment summary and inode/data blocks start after the super block (if
-present), and grow toward the end of the segment.
-
- _______________________________________________
- | | | | |
- | summary | data/inode | summary | data/inode |
- | block | blocks | block | blocks | ...
- |_________|____________|_________|____________|
-
-The data/inode blocks following a summary block are described by the
-summary block. In order to permit the segment to be written in any order
-and in a forward direction only, a checksum is calculated across the
-blocks described by the summary. Additionally, the summary is checksummed
-and timestamped. Both of these are intended for recovery; the former is
-to make it easy to determine that it *is* a summary block and the latter
-is to make it easy to determine when recovery is finished for partially
-written segments. These checksums are also used by the cleaner.
-
- Summary block (detail)
- ________________
- | sum cksum |
- | data cksum |
- | next segment |
- | timestamp |
- | FINFO count |
- | inode count |
- | flags |
- |______________|
- | FINFO-1 | 0 or more file info structures, identifying the
- | . | blocks in the segment.
- | . |
- | . |
- | FINFO-N |
- | inode-N |
- | . |
- | . |
- | . | 0 or more inode daddr_t's, identifying the inode
- | inode-1 | blocks in the segment.
- |______________|
-
-Inode blocks are blocks of on-disk inodes in the same format as those in
-the FFS. However, spare[0] contains the inode number of the inode so we
-can find a particular inode on a page. They are packed page_size /
-sizeof(inode) to a block. Data blocks are exactly as in the FFS. Both
-inodes and data blocks move around the file system at will.
-
-The file system is described by a super-block which is replicated and
-occurs as the first block of the first and other segments. (The maximum
-number of super-blocks is MAXNUMSB). Each super-block maintains a list
-of the disk addresses of all the super-blocks. The super-block maintains
-a small amount of checkpoint information, essentially just enough to find
-the inode for the IFILE (fs->lfs_idaddr).
-
-The IFILE is visible in the file system, as inode number IFILE_INUM. It
-contains information shared between the kernel and various user processes.
-
- Ifile (detail)
- ________________
- | cleaner info | Cleaner information per file system. (Page
- | | granularity.)
- |______________|
- | segment | Space available and last modified times per
- | usage table | segment. (Page granularity.)
- |______________|
- | IFILE-1 | Per inode status information: current version #,
- | . | if currently allocated, last access time and
- | . | current disk address of containing inode block.
- | . | If current disk address is LFS_UNUSED_DADDR, the
- | IFILE-N | inode is not in use, and it's on the free list.
- |______________|
-
-
-First Segment at Creation Time:
-_____________________________________________________________
-| | | | | | | |
-| 8K pad | Super | summary | inode | ifile | root | l + f |
-| | block | | block | | dir | dir |
-|________|_______|_________|_______|_______|_______|_______|
- ^
- Segment starts here.
-
-Some differences from the Sprite LFS implementation.
-
-1. The LFS implementation placed the ifile metadata and the super block
- at fixed locations. This implementation replicates the super block
- and puts each at a fixed location. The checkpoint data is divided into
- two parts -- just enough information to find the IFILE is stored in
- two of the super blocks, although it is not toggled between them as in
- the Sprite implementation. (This was deliberate, to avoid a single
- point of failure.) The remaining checkpoint information is treated as
- a regular file, which means that the cleaner info, the segment usage
- table and the ifile meta-data are stored in normal log segments.
- (Tastes great, less filling...)
-
-2. The segment layout is radically different in Sprite; this implementation
- uses something a lot like network framing, where data/inode blocks are
- written asynchronously, and a checksum is used to validate any set of
- summary and data/inode blocks. Sprite writes summary blocks synchronously
- after the data/inode blocks have been written and the existence of the
- summary block validates the data/inode blocks. This permits us to write
- everything contiguously, even partial segments and their summaries, whereas
- Sprite is forced to seek (from the end of the data inode to the summary
- which lives at the end of the segment). Additionally, writing the summary
- synchronously should cost about 1/2 a rotation per summary.
-
-3. Sprite LFS distinguishes between different types of blocks in the segment.
- Other than inode blocks and data blocks, we don't.
-
-4. Sprite LFS traverses the IFILE looking for free blocks. We maintain a
- free list threaded through the IFILE entries.
-
-5. The cleaner runs in user space, as opposed to kernel space. It shares
- information with the kernel by reading/writing the IFILE and through
- cleaner specific system calls.
-
diff --git a/sys/ufs/lfs/TODO b/sys/ufs/lfs/TODO
deleted file mode 100644
index ace8f5eaef6c..000000000000
--- a/sys/ufs/lfs/TODO
+++ /dev/null
@@ -1,116 +0,0 @@
-# @(#)TODO 8.1 (Berkeley) 6/11/93
-
-NOTE: Changed the lookup on a page of inodes to search from the back
-in case the same inode gets written twice on the same page.
-
-Make sure that if you are writing a file, but not all the blocks
-make it into a single segment, that you do not write the inode in
-that segment.
-
-Keith:
- Why not delete the lfs_bmapv call, just mark everything dirty
- that isn't deleted/truncated? Get some numbers about
- what percentage of the stuff that the cleaner thinks
- might be live is live. If it's high, get rid of lfs_bmapv.
-
- There is a nasty problem in that it may take *more* room to write
- the data to clean a segment than is returned by the new segment
- because of indirect blocks in segment 2 being dirtied by the data
- being copied into the log from segment 1. The suggested solution
- at this point is to detect it when we have no space left on the
- filesystem, write the extra data into the last segment (leaving
- no clean ones), make it a checkpoint and shut down the file system
- for fixing by a utility reading the raw partition. Argument is
- that this should never happen and is practically impossible to fix
- since the cleaner would have to theoretically build a model of the
- entire filesystem in memory to detect the condition occurring.
- A file coalescing cleaner will help avoid the problem, and one
- that reads/writes from the raw disk could fix it.
-
-DONE Currently, inodes are being flushed to disk synchronously upon
- creation -- see ufs_makeinode. However, only the inode
- is flushed, the directory "name" is written using VOP_BWRITE,
- so it's not synchronous. Possible solutions: 1: get some
- ordering in the writes so that inode/directory entries get
- stuffed into the same segment. 2: do both synchronously
- 3: add Mendel's information into the stream so we log
- creation/deletion of inodes. 4: do some form of partial
- segment when changing the inode (creation/deletion/rename).
-DONE Fix i_block increment for indirect blocks.
- If the file system is tar'd, extracted on top of another LFS, the
- IFILE ain't worth diddly. Is the cleaner writing the IFILE?
- If not, let's make it read-only.
-DONE Delete unnecessary source from utils in main-line source tree.
-DONE Make sure that we're counting meta blocks in the inode i_block count.
- Overlap the version and nextfree fields in the IFILE
-DONE Vinvalbuf (Kirk):
- Why writing blocks that are no longer useful?
- Are the semantics of close such that blocks have to be flushed?
- How specify in the buf chain the blocks that don't need
- to be written? (Different numbering of indirect blocks.)
-
-Margo:
- Change so that only search one sector of inode block file for the
- inode by using sector addresses in the ifile instead of
- logical disk addresses.
- Fix the use of the ifile version field to use the generation
- number instead.
-DONE Unmount; not doing a bgetvp (VHOLD) in lfs_newbuf call.
-DONE Document in the README file where the checkpoint information is
- on disk.
- Variable block sizes (Margo/Keith).
- Switch the byte accounting to sector accounting.
-DONE Check lfs.h and make sure that the #defines/structures are all
- actually needed.
-DONE Add a check in lfs_segment.c so that if the segment is empty,
- we don't write it.
- Need to keep vnode v_numoutput up to date for pending writes?
-DONE USENIX paper (Carl/Margo).
-
-
-Evelyn:
- lfsck: If delete a file that's being executed, the version number
- isn't updated, and lfsck has to figure this out; case is the same as if have an inode that no directory references,
- so the file should be reattached into lost+found.
- Recovery/fsck.
-
-Carl:
- Investigate: clustering of reads (if blocks in the segment are ordered,
- should read them all) and writes (McVoy paper).
- Investigate: should the access time be part of the IFILE:
- pro: theoretically, saves disk writes
- con: cacheing inodes should obviate this advantage
- the IFILE is already humongous
- Cleaner.
- Port to OSF/1 (Carl/Keith).
- Currently there's no notion of write error checking.
- + Failed data/inode writes should be rescheduled (kernel level
- bad blocking).
- + Failed superblock writes should cause selection of new
- superblock for checkpointing.
-
-FUTURE FANTASIES: ============
-
-+ unrm, versioning
-+ transactions
-+ extended cleaner policies (hot/cold data, data placement)
-
-==============================
-Problem with the concept of multiple buffer headers referencing the segment:
-Positives:
- Don't lock down 1 segment per file system of physical memory.
- Don't copy from buffers to segment memory.
- Don't tie down the bus to transfer 1M.
- Works on controllers supporting less than large transfers.
- Disk can start writing immediately instead of waiting 1/2 rotation
- and the full transfer.
-Negatives:
- Have to do segment write then segment summary write, since the latter
- is what verifies that the segment is okay. (Is there another way
- to do this?)
-==============================
-
-The algorithm for selecting the disk addresses of the super-blocks
-has to be available to the user program which checks the file system.
-
-(Currently in newfs, becomes a common subroutine.)
diff --git a/sys/ufs/lfs/lfs.h b/sys/ufs/lfs/lfs.h
deleted file mode 100644
index fa0fed74a702..000000000000
--- a/sys/ufs/lfs/lfs.h
+++ /dev/null
@@ -1,397 +0,0 @@
-/*-
- * Copyright (c) 1991, 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.
- *
- * 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.
- *
- * @(#)lfs.h 8.9 (Berkeley) 5/8/95
- * $Id: lfs.h,v 1.9 1997/02/22 09:47:15 peter Exp $
- */
-
-#ifndef _UFS_LFS_LFS_H_
-#define _UFS_LFS_LFS_H_
-
-#define LFS_LABELPAD 8192 /* LFS label size */
-#define LFS_SBPAD 8192 /* LFS superblock size */
-
-/*
- * XXX
- * This is a kluge and NEEDS to go away.
- *
- * Right now, ufs code handles most of the calls for directory operations
- * such as create, mkdir, link, etc. As a result VOP_UPDATE is being
- * called with waitfor set (since ffs does these things synchronously).
- * Since LFS does not want to do these synchronously, we treat the last
- * argument to lfs_update as a set of flags. If LFS_SYNC is set, then
- * the update should be synchronous, if not, do it asynchronously.
- * Unfortunately, this means that LFS won't work with NFS yet because
- * NFS goes through paths that will make normal calls to ufs which will
- * call lfs with a last argument of 1.
- */
-#define LFS_SYNC 0x02
-
-/* On-disk and in-memory checkpoint segment usage structure. */
-typedef struct segusage SEGUSE;
-struct segusage {
- u_int32_t su_nbytes; /* number of live bytes */
- u_int32_t su_lastmod; /* SEGUSE last modified timestamp */
- u_int16_t su_nsums; /* number of summaries in segment */
- u_int16_t su_ninos; /* number of inode blocks in seg */
-
-#define SEGUSE_ACTIVE 0x01 /* segment is currently being written */
-#define SEGUSE_DIRTY 0x02 /* segment has data in it */
-#define SEGUSE_SUPERBLOCK 0x04 /* segment contains a superblock */
- u_int32_t su_flags;
-};
-
-#define SEGUPB(fs) (1 << (fs)->lfs_sushift)
-#define SEGTABSIZE_SU(fs) \
- (((fs)->lfs_nseg + SEGUPB(fs) - 1) >> (fs)->lfs_sushift)
-
-/* On-disk file information. One per file with data blocks in the segment. */
-typedef struct finfo FINFO;
-struct finfo {
- u_int32_t fi_nblocks; /* number of blocks */
- u_int32_t fi_version; /* version number */
- u_int32_t fi_ino; /* inode number */
- u_int32_t fi_lastlength; /* length of last block in array */
- ufs_daddr_t fi_blocks[1]; /* array of logical block numbers */
-};
-
-/* On-disk and in-memory super block. */
-struct lfs {
-#define LFS_MAGIC 0x070162
- u_int32_t lfs_magic; /* magic number */
-#define LFS_VERSION 1
- u_int32_t lfs_version; /* version number */
-
- u_int32_t lfs_size; /* number of blocks in fs */
- u_int32_t lfs_ssize; /* number of blocks per segment */
- u_int32_t lfs_dsize; /* number of disk blocks in fs */
- u_int32_t lfs_bsize; /* file system block size */
- u_int32_t lfs_fsize; /* size of frag blocks in fs */
- u_int32_t lfs_frag; /* number of frags in a block in fs */
-
-/* Checkpoint region. */
- ino_t lfs_free; /* start of the free list */
- u_int32_t lfs_bfree; /* number of free disk blocks */
- u_int32_t lfs_nfiles; /* number of allocated inodes */
- int32_t lfs_avail; /* blocks available for writing */
- u_int32_t lfs_uinodes; /* inodes in cache not yet on disk */
- ufs_daddr_t lfs_idaddr; /* inode file disk address */
- ino_t lfs_ifile; /* inode file inode number */
- ufs_daddr_t lfs_lastseg; /* address of last segment written */
- ufs_daddr_t lfs_nextseg; /* address of next segment to write */
- ufs_daddr_t lfs_curseg; /* current segment being written */
- ufs_daddr_t lfs_offset; /* offset in curseg for next partial */
- ufs_daddr_t lfs_lastpseg; /* address of last partial written */
- u_int32_t lfs_tstamp; /* time stamp */
-
-/* These are configuration parameters. */
- u_int32_t lfs_minfree; /* minimum percentage of free blocks */
-
-/* These fields can be computed from the others. */
- u_int64_t lfs_maxfilesize; /* maximum representable file size */
- u_int32_t lfs_dbpseg; /* disk blocks per segment */
- u_int32_t lfs_inopb; /* inodes per block */
- u_int32_t lfs_ifpb; /* IFILE entries per block */
- u_int32_t lfs_sepb; /* SEGUSE entries per block */
- u_int32_t lfs_nindir; /* indirect pointers per block */
- u_int32_t lfs_nseg; /* number of segments */
- u_int32_t lfs_nspf; /* number of sectors per fragment */
- u_int32_t lfs_cleansz; /* cleaner info size in blocks */
- u_int32_t lfs_segtabsz; /* segment table size in blocks */
-
- u_int32_t lfs_segmask; /* calculate offset within a segment */
- u_int32_t lfs_segshift; /* fast mult/div for segments */
- u_int64_t lfs_bmask; /* calc block offset from file offset */
- u_int32_t lfs_bshift; /* calc block number from file offset */
- u_int64_t lfs_ffmask; /* calc frag offset from file offset */
- u_int32_t lfs_ffshift; /* fast mult/div for frag from file */
- u_int64_t lfs_fbmask; /* calc frag offset from block offset */
- u_int32_t lfs_fbshift; /* fast mult/div for frag from block */
- u_int32_t lfs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
- u_int32_t lfs_sushift; /* fast mult/div for segusage table */
-
- int32_t lfs_maxsymlinklen; /* max length of an internal symlink */
-
-#define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */
-#define LFS_MAXNUMSB 10 /* superblock disk offsets */
- ufs_daddr_t lfs_sboffs[LFS_MAXNUMSB];
-
-/* Checksum -- last valid disk field. */
- u_int32_t lfs_cksum; /* checksum for superblock checking */
-
-/* These fields are set at mount time and are meaningless on disk. */
- struct segment *lfs_sp; /* current segment being written */
- struct vnode *lfs_ivnode; /* vnode for the ifile */
- u_long lfs_seglock; /* single-thread the segment writer */
- pid_t lfs_lockpid; /* pid of lock holder */
- u_long lfs_iocount; /* number of ios pending */
- u_long lfs_writer; /* don't allow any dirops to start */
- u_long lfs_dirops; /* count of active directory ops */
- u_long lfs_doifile; /* Write ifile blocks on next write */
- u_long lfs_nactive; /* Number of segments since last ckp */
- int8_t lfs_fmod; /* super block modified flag */
- int8_t lfs_clean; /* file system is clean flag */
- int8_t lfs_ronly; /* mounted read-only flag */
- int8_t lfs_flags; /* currently unused flag */
- u_char lfs_fsmnt[MNAMELEN]; /* name mounted on */
-
- int32_t lfs_pad[40]; /* round to 512 bytes */
-};
-
-/*
- * Inode 0: out-of-band inode number
- * Inode 1: IFILE inode number
- * Inode 2: root inode
- * Inode 3: lost+found inode number
- */
-#define LFS_UNUSED_INUM 0 /* out of band inode number */
-#define LFS_IFILE_INUM 1 /* IFILE inode number */
-#define LOSTFOUNDINO 3 /* lost+found inode number */
-#define LFS_FIRST_INUM 4 /* first free inode number */
-
-/* Address calculations for metadata located in the inode */
-#define S_INDIR(fs) -NDADDR
-#define D_INDIR(fs) (S_INDIR(fs) - NINDIR(fs) - 1)
-#define T_INDIR(fs) (D_INDIR(fs) - NINDIR(fs) * NINDIR(fs) - 1)
-
-/* Unassigned disk address. */
-#define UNASSIGNED -1
-
-/* Unused logical block number */
-#define LFS_UNUSED_LBN -1
-
-typedef struct ifile IFILE;
-struct ifile {
- u_int32_t if_version; /* inode version number */
-#define LFS_UNUSED_DADDR 0 /* out-of-band daddr */
- ufs_daddr_t if_daddr; /* inode disk address */
- ino_t if_nextfree; /* next-unallocated inode */
-};
-
-/*
- * Cleaner information structure. This resides in the ifile and is used
- * to pass information between the cleaner and the kernel.
- */
-typedef struct _cleanerinfo {
- u_int32_t clean; /* K: number of clean segments */
- u_int32_t dirty; /* K: number of dirty segments */
-} CLEANERINFO;
-
-#define CLEANSIZE_SU(fs) \
- ((sizeof(CLEANERINFO) + (fs)->lfs_bsize - 1) >> (fs)->lfs_bshift)
-
-/*
- * All summary blocks are the same size, so we can always read a summary
- * block easily from a segment.
- */
-#define LFS_SUMMARY_SIZE 512
-
-/* On-disk segment summary information */
-typedef struct segsum SEGSUM;
-struct segsum {
- u_int32_t ss_sumsum; /* check sum of summary block */
- u_int32_t ss_datasum; /* check sum of data */
- u_int32_t ss_magic; /* segment summary magic number */
-#define SS_MAGIC 0x061561
- ufs_daddr_t ss_next; /* next segment */
- u_int32_t ss_create; /* creation time stamp */
- u_int16_t ss_nfinfo; /* number of file info structures */
- u_int16_t ss_ninos; /* number of inodes in summary */
-
-#define SS_DIROP 0x01 /* segment begins a dirop */
-#define SS_CONT 0x02 /* more partials to finish this write*/
- u_int16_t ss_flags; /* used for directory operations */
- u_int16_t ss_pad; /* extra space */
- /* FINFO's and inode daddr's... */
-};
-
-/* NINDIR is the number of indirects in a file system block. */
-#define NINDIR(fs) ((fs)->lfs_nindir)
-
-/* INOPB is the number of inodes in a secondary storage block. */
-#define INOPB(fs) ((fs)->lfs_inopb)
-
-#define blksize(fs, ip, lbn) \
- (((lbn) >= NDADDR || (ip)->i_size >= ((lbn) + 1) << (fs)->lfs_bshift) \
- ? (fs)->lfs_bsize \
- : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
-#define blkoff(fs, loc) ((int)((loc) & (fs)->lfs_bmask))
-#define fragoff(fs, loc) /* calculates (loc % fs->lfs_fsize) */ \
- ((int)((loc) & (fs)->lfs_ffmask))
-#define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb)
-#define dbtofsb(fs, b) ((b) >> (fs)->lfs_fsbtodb)
-#define fragstodb(fs, b) ((b) << (fs)->lfs_fsbtodb - (fs)->lfs_fbshift)
-#define dbtofrags(fs, b) ((b) >> (fs)->lfs_fsbtodb - (fs)->lfs_fbshift)
-#define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift)
-#define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift)
-#define numfrags(fs, loc) /* calculates (loc / fs->lfs_fsize) */ \
- ((loc) >> (fs)->lfs_ffshift)
-#define blkroundup(fs, size) /* calculates roundup(size, fs->lfs_bsize) */ \
- ((int)(((size) + (fs)->lfs_bmask) & (~(fs)->lfs_bmask)))
-#define fragroundup(fs, size) /* calculates roundup(size, fs->lfs_fsize) */ \
- ((int)(((size) + (fs)->lfs_ffmask) & (~(fs)->lfs_ffmask)))
-#define fragstoblks(fs, frags) /* calculates (frags / fs->lfs_frag) */ \
- ((frags) >> (fs)->lfs_fbshift)
-#define blkstofrags(fs, blks) /* calculates (blks * fs->lfs_frag) */ \
- ((blks) << (fs)->lfs_fbshift)
-#define fragnum(fs, fsb) /* calculates (fsb % fs->lfs_frag) */ \
- ((fsb) & ((fs)->lfs_frag - 1))
-#define blknum(fs, fsb) /* calculates rounddown(fsb, fs->lfs_frag) */ \
- ((fsb) &~ ((fs)->lfs_frag - 1))
-#define dblksize(fs, dip, lbn) \
- (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->lfs_bshift)\
- ? (fs)->lfs_bsize \
- : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
-#define datosn(fs, daddr) /* disk address to segment number */ \
- (((daddr) - (fs)->lfs_sboffs[0]) / fsbtodb((fs), (fs)->lfs_ssize))
-#define sntoda(fs, sn) /* segment number to disk address */ \
- ((ufs_daddr_t)((sn) * ((fs)->lfs_ssize << (fs)->lfs_fsbtodb) + \
- (fs)->lfs_sboffs[0]))
-
-/* Read in the block with the cleaner info from the ifile. */
-#define LFS_CLEANERINFO(CP, F, BP) { \
- VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \
- if (bread((F)->lfs_ivnode, \
- (ufs_daddr_t)0, (F)->lfs_bsize, NOCRED, &(BP))) \
- panic("lfs: ifile read"); \
- (CP) = (CLEANERINFO *)(BP)->b_data; \
-}
-
-/* Read in the block with a specific inode from the ifile. */
-#define LFS_IENTRY(IP, F, IN, BP) { \
- int _e; \
- VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \
- if (_e = bread((F)->lfs_ivnode, \
- (IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz,\
- (F)->lfs_bsize, NOCRED, &(BP))) \
- panic("lfs: ifile read %d", _e); \
- (IP) = (IFILE *)(BP)->b_data + (IN) % (F)->lfs_ifpb; \
-}
-
-/* Read in the block with a specific segment usage entry from the ifile. */
-#define LFS_SEGENTRY(SP, F, IN, BP) { \
- int _e; \
- VTOI((F)->lfs_ivnode)->i_flag |= IN_ACCESS; \
- _e = bread((F)->lfs_ivnode, \
- ((IN) >> (F)->lfs_sushift) + (F)->lfs_cleansz, \
- (F)->lfs_bsize, NOCRED, &(BP)); \
- if (_e) \
- panic("lfs: ifile read: %d", _e); \
- (SP) = (SEGUSE *)(BP)->b_data + ((IN) & (F)->lfs_sepb - 1); \
-}
-#ifdef CC_WALL
-/* The above ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * looks like a potential bug to me.
- */
-#endif
-
-/*
- * Determine if there is enough room currently available to write db
- * disk blocks. We need enough blocks for the new blocks, the current,
- * inode blocks, a summary block, plus potentially the ifile inode and
- * the segment usage table, plus an ifile page.
- */
-#define LFS_FITS(fs, db) \
- ((int32_t)((db + ((fs)->lfs_uinodes + INOPB((fs))) / \
- INOPB((fs)) + fsbtodb(fs, 1) + LFS_SUMMARY_SIZE / DEV_BSIZE + \
- (fs)->lfs_segtabsz)) < (fs)->lfs_avail)
-
-/* Determine if a buffer belongs to the ifile */
-#define IS_IFILE(bp) (VTOI(bp->b_vp)->i_number == LFS_IFILE_INUM)
-
-/*
- * Structures used by lfs_bmapv and lfs_markv to communicate information
- * about inodes and data blocks.
- */
-typedef struct block_info {
- ino_t bi_inode; /* inode # */
- ufs_daddr_t bi_lbn; /* logical block w/in file */
- ufs_daddr_t bi_daddr; /* disk address of block */
- time_t bi_segcreate; /* origin segment create time */
- int bi_version; /* file version number */
- void *bi_bp; /* data buffer */
- int bi_size; /* size of the block (if fragment) */
-} BLOCK_INFO;
-
-/* In-memory description of a segment about to be written. */
-struct segment {
- struct lfs *fs; /* file system pointer */
- struct buf **bpp; /* pointer to buffer array */
- struct buf **cbpp; /* pointer to next available bp */
- struct buf **start_bpp; /* pointer to first bp in this set */
- struct buf *ibp; /* buffer pointer to inode page */
- struct finfo *fip; /* current fileinfo pointer */
- struct vnode *vp; /* vnode being gathered */
- void *segsum; /* segment summary info */
- u_int32_t ninodes; /* number of inodes in this segment */
- u_int32_t seg_bytes_left; /* bytes left in segment */
- u_int32_t sum_bytes_left; /* bytes left in summary block */
- u_int32_t seg_number; /* number of this segment */
- ufs_daddr_t *start_lbp; /* beginning lbn for this set */
-
-#define SEGM_CKP 0x01 /* doing a checkpoint */
-#define SEGM_CLEAN 0x02 /* cleaner call; don't sort */
-#define SEGM_SYNC 0x04 /* wait for segment */
- u_int16_t seg_flags; /* run-time flags for this segment */
-};
-
-#define ISSPACE(F, BB, C) \
- (((C)->cr_uid == 0 && (F)->lfs_bfree >= (BB)) || \
- ((C)->cr_uid != 0 && IS_FREESPACE(F, BB)))
-
-#define IS_FREESPACE(F, BB) \
- ((F)->lfs_bfree > ((F)->lfs_dsize * (F)->lfs_minfree / 100 + (BB)))
-
-#define ISSPACE_XXX(F, BB) \
- ((F)->lfs_bfree >= (BB))
-
-#define DOSTATS
-#ifdef DOSTATS
-/* Statistics Counters */
-struct lfs_stats {
- u_int segsused;
- u_int psegwrites;
- u_int psyncwrites;
- u_int pcleanwrites;
- u_int blocktot;
- u_int cleanblocks;
- u_int ncheckpoints;
- u_int nwrites;
- u_int nsync_writes;
- u_int wait_exceeded;
- u_int write_exceeded;
- u_int flush_invoked;
-};
-extern struct lfs_stats lfs_stats;
-#endif
-
-#endif
diff --git a/sys/ufs/lfs/lfs_alloc.c b/sys/ufs/lfs/lfs_alloc.c
deleted file mode 100644
index 269bb75556e1..000000000000
--- a/sys/ufs/lfs/lfs_alloc.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (c) 1991, 1993, 1995
- * 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.
- *
- * 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.
- *
- * @(#)lfs_alloc.c 8.7 (Berkeley) 5/14/95
- * $Id: lfs_alloc.c,v 1.19 1997/10/16 11:58:30 phk Exp $
- */
-
-#include "opt_quota.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/buf.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/malloc.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ufs/ufs_extern.h>
-
-#include <ufs/lfs/lfs.h>
-#include <ufs/lfs/lfs_extern.h>
-
-/* Allocate a new inode. */
-/* ARGSUSED */
-int
-lfs_valloc(pvp, mode, cred, vpp)
- struct vnode *pvp;
- int mode;
- struct ucred *cred;
- struct vnode **vpp;
-{
- struct lfs *fs;
- struct buf *bp;
- struct ifile *ifp;
- struct inode *ip;
- struct vnode *vp;
- ufs_daddr_t blkno;
- ino_t new_ino;
- u_long i, max;
- int error;
-
- /* Get the head of the freelist. */
- fs = VTOI(pvp)->i_lfs;
- new_ino = fs->lfs_free;
-#ifdef ALLOCPRINT
- printf("lfs_ialloc: allocate inode %d\n", new_ino);
-#endif
-
- /*
- * Remove the inode from the free list and write the new start
- * of the free list into the superblock.
- */
- LFS_IENTRY(ifp, fs, new_ino, bp);
- if (ifp->if_daddr != LFS_UNUSED_DADDR)
- panic("lfs_ialloc: inuse inode on the free list");
- fs->lfs_free = ifp->if_nextfree;
- brelse(bp);
-
- /* Extend IFILE so that the next lfs_valloc will succeed. */
- if (fs->lfs_free == LFS_UNUSED_INUM) {
- vp = fs->lfs_ivnode;
- ip = VTOI(vp);
- blkno = lblkno(fs, ip->i_size);
- lfs_balloc(vp, 0, fs->lfs_bsize, blkno, &bp);
- ip->i_size += fs->lfs_bsize;
- vnode_pager_setsize(vp, (u_long)ip->i_size);
-
- i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) *
- fs->lfs_ifpb;
- fs->lfs_free = i;
- max = i + fs->lfs_ifpb;
- for (ifp = (struct ifile *)bp->b_data; i < max; ++ifp) {
- ifp->if_version = 1;
- ifp->if_daddr = LFS_UNUSED_DADDR;
- ifp->if_nextfree = ++i;
- }
- ifp--;
- ifp->if_nextfree = LFS_UNUSED_INUM;
- if (error = VOP_BWRITE(bp))
- return (error);
- }
-
- /* Create a vnode to associate with the inode. */
- if (error = lfs_vcreate(pvp->v_mount, new_ino, &vp))
- return (error);
-
-
- ip = VTOI(vp);
- /* Zero out the direct and indirect block addresses. */
- bzero(&ip->i_din, sizeof(struct dinode));
- ip->i_din.di_inumber = new_ino;
-
- /* Set a new generation number for this inode. */
- if (ip->i_gen == 0 || ++ip->i_gen == 0)
- ip->i_gen = random() / 2 + 1;
-
- /* Insert into the inode hash table. */
- ufs_ihashins(ip);
-
- if (error = ufs_vinit(vp->v_mount, lfs_specop_p, LFS_FIFOOPS, &vp)) {
- vput(vp);
- *vpp = NULL;
- return (error);
- }
-
- *vpp = vp;
- vp->v_flag |= VDIROP;
- VREF(ip->i_devvp);
-
- /* Set superblock modified bit and increment file count. */
- fs->lfs_fmod = 1;
- ++fs->lfs_nfiles;
- return (0);
-}
-
-/* Create a new vnode/inode pair and initialize what fields we can. */
-int
-lfs_vcreate(mp, ino, vpp)
- struct mount *mp;
- ino_t ino;
- struct vnode **vpp;
-{
- struct inode *ip;
- struct ufsmount *ump;
- int error, i;
-
- /*
- * Do the MALLOC before the getnewvnode since doing so afterward
- * might cause a bogus v_data pointer to get dereferenced
- * elsewhere if MALLOC should block.
- */
- MALLOC(ip, struct inode *, sizeof(struct inode), M_LFSNODE, M_WAITOK);
-
- /* Create the vnode. */
- if (error = getnewvnode(VT_LFS, mp, lfs_vnodeop_p, vpp)) {
- *vpp = NULL;
- FREE(ip, M_LFSNODE);
- return (error);
- }
-
- /* Get a pointer to the private mount structure. */
- ump = VFSTOUFS(mp);
-
- /* Initialize the inode. */
- lockinit(&ip->i_lock, PINOD, "lfsinode", 0, 0);
- (*vpp)->v_data = ip;
- ip->i_vnode = *vpp;
- ip->i_devvp = ump->um_devvp;
- ip->i_flag = IN_MODIFIED;
- ip->i_dev = ump->um_dev;
- ip->i_number = ip->i_din.di_inumber = ino;
- ip->i_lfs = ump->um_lfs;
-#ifdef QUOTA
- for (i = 0; i < MAXQUOTAS; i++)
- ip->i_dquot[i] = NODQUOT;
-#endif
- ip->i_lockf = 0;
- ip->i_diroff = 0;
- ip->i_mode = 0;
- ip->i_size = 0;
- ip->i_blocks = 0;
- ++ump->um_lfs->lfs_uinodes;
- return (0);
-}
-
-/* Free an inode. */
-/* ARGUSED */
-int
-lfs_vfree(pvp, ino, mode)
- struct vnode *pvp;
- ino_t ino;
- int mode;
-{
- SEGUSE *sup;
- struct buf *bp;
- struct ifile *ifp;
- struct inode *ip;
- struct lfs *fs;
- ufs_daddr_t old_iaddr;
-
- /* Get the inode number and file system. */
- ip = VTOI(pvp);
- fs = ip->i_lfs;
- ino = ip->i_number;
- if (ip->i_flag & IN_MODIFIED) {
- --fs->lfs_uinodes;
- ip->i_flag &=
- ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
- }
- /*
- * Set the ifile's inode entry to unused, increment its version number
- * and link it into the free chain.
- */
- LFS_IENTRY(ifp, fs, ino, bp);
- old_iaddr = ifp->if_daddr;
- ifp->if_daddr = LFS_UNUSED_DADDR;
- ++ifp->if_version;
- ifp->if_nextfree = fs->lfs_free;
- fs->lfs_free = ino;
- (void) VOP_BWRITE(bp);
-
- if (old_iaddr != LFS_UNUSED_DADDR) {
- LFS_SEGENTRY(sup, fs, datosn(fs, old_iaddr), bp);
-#ifdef DIAGNOSTIC
- if (sup->su_nbytes < sizeof(struct dinode))
- panic("lfs_vfree: negative byte count (segment %d)",
- datosn(fs, old_iaddr));
-#endif
- sup->su_nbytes -= sizeof(struct dinode);
- (void) VOP_BWRITE(bp);
- }
-
- /* Set superblock modified bit and decrement file count. */
- fs->lfs_fmod = 1;
- --fs->lfs_nfiles;
- return (0);
-}
diff --git a/sys/ufs/lfs/lfs_balloc.c b/sys/ufs/lfs/lfs_balloc.c
deleted file mode 100644
index dfa3dcf73de8..000000000000
--- a/sys/ufs/lfs/lfs_balloc.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 1989, 1991, 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.
- *
- * 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.
- *
- * @(#)lfs_balloc.c 8.4 (Berkeley) 5/8/95
- * $Id: lfs_balloc.c,v 1.12 1997/05/25 04:57:11 peter Exp $
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ufs/ufs_extern.h>
-
-#include <ufs/lfs/lfs.h>
-#include <ufs/lfs/lfs_extern.h>
-
-static int lfs_fragextend(struct vnode *vp, int osize, int nsize, daddr_t lbn,
- struct buf **bpp);
-
-int
-lfs_balloc(vp, offset, iosize, lbn, bpp)
- struct vnode *vp;
- int offset;
- u_long iosize;
- ufs_daddr_t lbn;
- struct buf **bpp;
-{
- struct buf *ibp, *bp;
- struct inode *ip;
- struct lfs *fs;
- struct indir indirs[NIADDR+2];
- ufs_daddr_t daddr, lastblock;
- int bb; /* number of disk blocks in a block disk blocks */
- int error, frags, i, nsize, osize, num;
-
- ip = VTOI(vp);
- fs = ip->i_lfs;
-
- /*
- * Three cases: it's a block beyond the end of file, it's a block in
- * the file that may or may not have been assigned a disk address or
- * we're writing an entire block. Note, if the daddr is unassigned,
- * the block might still have existed in the cache (if it was read
- * or written earlier). If it did, make sure we don't count it as a
- * new block or zero out its contents. If it did not, make sure
- * we allocate any necessary indirect blocks.
- * If we are writing a block beyond the end of the file, we need to
- * check if the old last block was a fragment. If it was, we need
- * to rewrite it.
- */
-
- *bpp = NULL;
- if (error = ufs_bmaparray(vp, lbn, &daddr, &indirs[0], &num, NULL, NULL ))
- return (error);
-
- /* Check for block beyond end of file and fragment extension needed. */
- lastblock = lblkno(fs, ip->i_size);
- if (lastblock < NDADDR && lastblock < lbn) {
- osize = blksize(fs, ip, lastblock);
- if (osize < fs->lfs_bsize && osize > 0) {
- if (error = lfs_fragextend(vp, osize, fs->lfs_bsize,
- lastblock, &bp))
- return(error);
- ip->i_size = (lastblock + 1) * fs->lfs_bsize;
- vnode_pager_setsize(vp, (u_long)ip->i_size);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
- VOP_BWRITE(bp);
- }
- }
-
- bb = VFSTOUFS(vp->v_mount)->um_seqinc;
- if (daddr == UNASSIGNED)
- /* May need to allocate indirect blocks */
- for (i = 1; i < num; ++i)
- if (!indirs[i].in_exists) {
- ibp = getblk(vp, indirs[i].in_lbn, fs->lfs_bsize,
- 0, 0);
- if (!(ibp->b_flags & (B_DONE | B_DELWRI))) {
- if (!ISSPACE(fs, bb, curproc->p_ucred)){
- ibp->b_flags |= B_INVAL;
- brelse(ibp);
- error = ENOSPC;
- } else {
- ip->i_blocks += bb;
- ip->i_lfs->lfs_bfree -= bb;
- vfs_bio_clrbuf(ibp);
- error = VOP_BWRITE(ibp);
- }
- } else
- panic ("Indirect block should not exist");
-
- if (!ISSPACE(fs, bb, curproc->p_ucred)){
- ibp->b_flags |= B_INVAL;
- brelse(ibp);
- return(ENOSPC);
- } else {
- ip->i_blocks += bb;
- ip->i_lfs->lfs_bfree -= bb;
- clrbuf(ibp);
- if(error = VOP_BWRITE(ibp))
- return(error);
- }
- }
-
- /*
- * If the block we are writing is a direct block, it's the last
- * block in the file, and offset + iosize is less than a full
- * block, we can write one or more fragments. There are two cases:
- * the block is brand new and we should allocate it the correct
- * size or it already exists and contains some fragments and
- * may need to extend it.
- */
- if (lbn < NDADDR && lblkno(fs, ip->i_size) == lbn) {
- nsize = fragroundup(fs, offset + iosize);
- frags = numfrags(fs, nsize);
- bb = fragstodb(fs, frags);
- if (lblktosize(fs, lbn) == ip->i_size)
- /* Brand new block or fragment */
- *bpp = bp = getblk(vp, lbn, nsize, 0, 0);
- else {
- /* Extend existing block */
- if (error = lfs_fragextend(vp, (int)blksize(fs, ip, lbn),
- nsize, lbn, &bp))
- return(error);
- *bpp = bp;
- }
- } else {
- /*
- * Get the existing block from the cache either because the
- * block is 1) not a direct block or because it's not the last
- * block in the file.
- */
- frags = dbtofrags(fs, bb);
- *bpp = bp = getblk(vp, lbn, blksize(fs, ip, lbn), 0, 0);
- }
-
- /*
- * The block we are writing may be a brand new block
- * in which case we need to do accounting (i.e. check
- * for free space and update the inode number of blocks.
- */
- if (!(bp->b_flags & (B_CACHE | B_DONE | B_DELWRI))) {
- if (daddr == UNASSIGNED)
- if (!ISSPACE(fs, bb, curproc->p_ucred)) {
- bp->b_flags |= B_INVAL;
- brelse(bp);
- return(ENOSPC);
- } else {
- ip->i_blocks += bb;
- ip->i_lfs->lfs_bfree -= bb;
- if (iosize != fs->lfs_bsize)
- vfs_bio_clrbuf(bp);
- }
- else if (iosize == fs->lfs_bsize)
- /* Optimization: I/O is unnecessary. */
- bp->b_blkno = daddr;
- else {
- /*
- * We need to read the block to preserve the
- * existing bytes.
- */
- bp->b_blkno = daddr;
- bp->b_flags |= B_READ;
- vfs_busy_pages(bp, 0);
- VOP_STRATEGY(bp);
- return(biowait(bp));
- }
- }
- return (0);
-}
-
-static int
-lfs_fragextend(vp, osize, nsize, lbn, bpp)
- struct vnode *vp;
- int osize;
- int nsize;
- daddr_t lbn;
- struct buf **bpp;
-{
- struct inode *ip;
- struct lfs *fs;
- long bb;
- int error;
-
- ip = VTOI(vp);
- fs = ip->i_lfs;
- bb = (long)fragstodb(fs, numfrags(fs, nsize - osize));
- if (!ISSPACE(fs, bb, curproc->p_ucred)) {
- return(ENOSPC);
- }
-
- if (error = bread(vp, lbn, osize, NOCRED, bpp)) {
- brelse(*bpp);
- return(error);
- }
-#ifdef QUOTA
- if (error = chkdq(ip, bb, curproc->p_ucred, 0)) {
- brelse(*bpp);
- return (error);
- }
-#endif
- ip->i_blocks += bb;
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
- fs->lfs_bfree -= fragstodb(fs, numfrags(fs, (nsize - osize)));
- allocbuf(*bpp, nsize);
- bzero((char *)((*bpp)->b_data) + osize, (u_int)(nsize - osize));
- return(0);
-}
diff --git a/sys/ufs/lfs/lfs_bio.c b/sys/ufs/lfs/lfs_bio.c
deleted file mode 100644
index ad7b39125248..000000000000
--- a/sys/ufs/lfs/lfs_bio.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (c) 1991, 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.
- *
- * 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.
- *
- * @(#)lfs_bio.c 8.10 (Berkeley) 6/10/95
- * $Id: lfs_bio.c,v 1.13 1997/06/15 17:56:46 dyson Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/buf.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/kernel.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/ufs/ufsmount.h>
-
-#include <ufs/lfs/lfs.h>
-#include <ufs/lfs/lfs_extern.h>
-
-static void lfs_flush __P((void));
-
-/*
- * LFS block write function.
- *
- * XXX
- * No write cost accounting is done.
- * This is almost certainly wrong for synchronous operations and NFS.
- */
-int lfs_allclean_wakeup; /* Cleaner wakeup address. */
-int locked_queue_count; /* XXX Count of locked-down buffers. */
-static int lfs_writing; /* Set if already kicked off a writer
- because of buffer space */
-/*
-#define WRITE_THRESHHOLD ((nbuf >> 2) - 10)
-#define WAIT_THRESHHOLD ((nbuf >> 1) - 10)
-*/
-#define WAIT_THRESHHOLD (nbuf - (nbuf >> 2) - 10)
-#define WRITE_THRESHHOLD ((nbuf >> 1) - 10)
-#define LFS_BUFWAIT 2
-
-int
-lfs_bwrite(ap)
- struct vop_bwrite_args /* {
- struct buf *a_bp;
- } */ *ap;
-{
- register struct buf *bp = ap->a_bp;
- struct lfs *fs;
- struct inode *ip;
- int db, error, s;
-
- /*
- * Set the delayed write flag and use reassignbuf to move the buffer
- * from the clean list to the dirty one.
- *
- * Set the B_LOCKED flag and unlock the buffer, causing brelse to move
- * the buffer onto the LOCKED free list. This is necessary, otherwise
- * getnewbuf() would try to reclaim the buffers using bawrite, which
- * isn't going to work.
- *
- * XXX we don't let meta-data writes run out of space because they can
- * come from the segment writer. We need to make sure that there is
- * enough space reserved so that there's room to write meta-data
- * blocks.
- */
- if (!(bp->b_flags & B_LOCKED)) {
- fs = VFSTOUFS(bp->b_vp->v_mount)->um_lfs;
- db = fragstodb(fs, numfrags(fs, bp->b_bcount));
- while (!LFS_FITS(fs, db) && !IS_IFILE(bp) &&
- bp->b_lblkno > 0) {
- /* Out of space, need cleaner to run */
- wakeup(&lfs_allclean_wakeup);
- wakeup(&fs->lfs_nextseg);
- error = tsleep(&fs->lfs_avail, PCATCH | PUSER,
- "cleaner", 0);
- if (error) {
- brelse(bp);
- return (error);
- }
- }
- ip = VTOI((bp)->b_vp);
- if (!(ip->i_flag & IN_MODIFIED))
- ++fs->lfs_uinodes;
- ip->i_flag |= IN_CHANGE | IN_MODIFIED | IN_UPDATE;
- fs->lfs_avail -= db;
- ++locked_queue_count;
- ++numdirtybuffers;
- bp->b_flags |= B_DELWRI | B_LOCKED;
- bp->b_flags &= ~(B_READ | B_ERROR);
- s = splbio();
- reassignbuf(bp, bp->b_vp);
- splx(s);
- }
- brelse(bp);
- return (0);
-}
-
-/*
- * XXX
- * This routine flushes buffers out of the B_LOCKED queue when LFS has too
- * many locked down. Eventually the pageout daemon will simply call LFS
- * when pages need to be reclaimed. Note, we have one static count of locked
- * buffers, so we can't have more than a single file system. To make this
- * work for multiple file systems, put the count into the mount structure.
- */
-static void
-lfs_flush()
-{
- register struct mount *mp, *nmp;
- struct proc *p = curproc; /* XXX */
-
-#ifdef DOSTATS
- ++lfs_stats.write_exceeded;
-#endif
- if (lfs_writing)
- return;
- lfs_writing = 1;
- simple_lock(&mountlist_slock);
- for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
- if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
- nmp = mp->mnt_list.cqe_next;
- continue;
- }
- if (mp->mnt_stat.f_type == lfs_mount_type &&
- (mp->mnt_flag & MNT_RDONLY) == 0 &&
- !((((struct ufsmount *)mp->mnt_data))->ufsmount_u.lfs)->lfs_dirops ) {
- /*
- * We set the queue to 0 here because we are about to
- * write all the dirty buffers we have. If more come
- * in while we're writing the segment, they may not
- * get written, so we want the count to reflect these
- * new writes after the segwrite completes.
- */
-#ifdef DOSTATS
- ++lfs_stats.flush_invoked;
-#endif
- lfs_segwrite(mp, 0);
- }
- simple_lock(&mountlist_slock);
- nmp = mp->mnt_list.cqe_next;
- vfs_unbusy(mp, p);
- }
- simple_unlock(&mountlist_slock);
- lfs_writing = 0;
-}
-
-int
-lfs_check(vp, blkno)
- struct vnode *vp;
- ufs_daddr_t blkno;
-{
- int error;
-
- error = 0;
- if (incore(vp, blkno))
- return (0);
- if (locked_queue_count > WRITE_THRESHHOLD)
- lfs_flush();
-
- /* If out of buffers, wait on writer */
- while (locked_queue_count > WAIT_THRESHHOLD) {
-#ifdef DOSTATS
- ++lfs_stats.wait_exceeded;
-#endif
- error = tsleep(&locked_queue_count, PCATCH | PUSER, "buffers",
- hz * LFS_BUFWAIT);
- }
-
- return (error);
-}
diff --git a/sys/ufs/lfs/lfs_cksum.c b/sys/ufs/lfs/lfs_cksum.c
deleted file mode 100644
index c1c627edb3f9..000000000000
--- a/sys/ufs/lfs/lfs_cksum.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*-
- * Copyright (c) 1991, 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.
- *
- * 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.
- *
- * @(#)lfs_cksum.c 8.2 (Berkeley) 10/9/94
- * $Id: lfs_cksum.c,v 1.7 1997/02/22 09:47:18 peter Exp $
- */
-
-#ifdef KERNEL
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-
-#include <ufs/lfs/lfs.h>
-#else
-#include <sys/types.h>
-#endif
-
-#include <ufs/lfs/lfs_extern.h>
-
-/*
- * Simple, general purpose, fast checksum. Data must be short-aligned.
- * Returns a u_long in case we ever want to do something more rigorous.
- *
- * XXX
- * Use the TCP/IP checksum instead.
- */
-u_long
-cksum(str, len)
- register void *str;
- register size_t len;
-{
- register u_long sum;
-
- len &= ~(sizeof(u_short) - 1);
- for (sum = 0; len; len -= sizeof(u_short)) {
- sum ^= *(u_short *)str;
- str = (void *)((u_short *)str + 1);
- }
- return (sum);
-}
diff --git a/sys/ufs/lfs/lfs_debug.c b/sys/ufs/lfs/lfs_debug.c
deleted file mode 100644
index 7dc47a2fcbe4..000000000000
--- a/sys/ufs/lfs/lfs_debug.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 1991, 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.
- *
- * 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.
- *
- * @(#)lfs_debug.c 8.1 (Berkeley) 6/11/93
- * $Id: lfs_debug.c,v 1.6 1997/02/22 09:47:19 peter Exp $
- */
-
-#ifdef DEBUG
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mount.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/lfs/lfs.h>
-
-static void lfs_dump_dinode __P((struct dinode *dip));
-static void lfs_dump_super __P((struct lfs *lfsp));
-
-static void
-lfs_dump_super(lfsp)
- struct lfs *lfsp;
-{
- int i;
-
- (void)printf("%s%lx\t%s%lx\t%s%d\t%s%d\n",
- "magic ", lfsp->lfs_magic,
- "version ", lfsp->lfs_version,
- "size ", lfsp->lfs_size,
- "ssize ", lfsp->lfs_ssize);
- (void)printf("%s%d\t%s%d\t%s%d\t%s%d\n",
- "dsize ", lfsp->lfs_dsize,
- "bsize ", lfsp->lfs_bsize,
- "fsize ", lfsp->lfs_fsize,
- "frag ", lfsp->lfs_frag);
-
- (void)printf("%s%d\t%s%d\t%s%d\t%s%d\n",
- "minfree ", lfsp->lfs_minfree,
- "inopb ", lfsp->lfs_inopb,
- "ifpb ", lfsp->lfs_ifpb,
- "nindir ", lfsp->lfs_nindir);
-
- (void)printf("%s%d\t%s%d\t%s%d\t%s%d\n",
- "nseg ", lfsp->lfs_nseg,
- "nspf ", lfsp->lfs_nspf,
- "cleansz ", lfsp->lfs_cleansz,
- "segtabsz ", lfsp->lfs_segtabsz);
-
- (void)printf("%s%lx\t%s%d\t%s%lx\t%s%d\n",
- "segmask ", lfsp->lfs_segmask,
- "segshift ", lfsp->lfs_segshift,
- "bmask ", lfsp->lfs_bmask,
- "bshift ", lfsp->lfs_bshift);
-
- (void)printf("%s%lx\t%s%d\t%s%lx\t%s%d\n",
- "ffmask ", lfsp->lfs_ffmask,
- "ffshift ", lfsp->lfs_ffshift,
- "fbmask ", lfsp->lfs_fbmask,
- "fbshift ", lfsp->lfs_fbshift);
-
- (void)printf("%s%d\t%s%d\t%s%lx\t%s%qx\n",
- "sushift ", lfsp->lfs_sushift,
- "fsbtodb ", lfsp->lfs_fsbtodb,
- "cksum ", lfsp->lfs_cksum,
- "maxfilesize ", lfsp->lfs_maxfilesize);
-
- (void)printf("Superblock disk addresses:");
- for (i = 0; i < LFS_MAXNUMSB; i++)
- (void)printf(" %lx", lfsp->lfs_sboffs[i]);
- (void)printf("\n");
-
- (void)printf("Checkpoint Info\n");
- (void)printf("%s%d\t%s%lx\t%s%d\n",
- "free ", lfsp->lfs_free,
- "idaddr ", lfsp->lfs_idaddr,
- "ifile ", lfsp->lfs_ifile);
- (void)printf("%s%lx\t%s%d\t%s%lx\t%s%lx\t%s%lx\t%s%lx\n",
- "bfree ", lfsp->lfs_bfree,
- "nfiles ", lfsp->lfs_nfiles,
- "lastseg ", lfsp->lfs_lastseg,
- "nextseg ", lfsp->lfs_nextseg,
- "curseg ", lfsp->lfs_curseg,
- "offset ", lfsp->lfs_offset);
- (void)printf("tstamp %lx\n", lfsp->lfs_tstamp);
-}
-
-static void
-lfs_dump_dinode(dip)
- struct dinode *dip;
-{
- int i;
-
- (void)printf("%s%u\t%s%d\t%s%u\t%s%u\t%s%lu\n",
- "mode ", dip->di_mode,
- "nlink ", dip->di_nlink,
- "uid ", dip->di_uid,
- "gid ", dip->di_gid,
- "size ", dip->di_size);
- (void)printf("inum %ld\n", dip->di_inumber);
- (void)printf("Direct Addresses\n");
- for (i = 0; i < NDADDR; i++) {
- (void)printf("\t%lx", dip->di_db[i]);
- if ((i % 6) == 5)
- (void)printf("\n");
- }
- for (i = 0; i < NIADDR; i++)
- (void)printf("\t%lx", dip->di_ib[i]);
- (void)printf("\n");
-}
-#endif /* DEBUG */
diff --git a/sys/ufs/lfs/lfs_extern.h b/sys/ufs/lfs/lfs_extern.h
deleted file mode 100644
index d930f4db979e..000000000000
--- a/sys/ufs/lfs/lfs_extern.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * 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.
- *
- * 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.
- *
- * @(#)lfs_extern.h 8.6 (Berkeley) 5/8/95
- * $Id: lfs_extern.h,v 1.18 1997/10/16 10:49:44 phk Exp $
- */
-
-#ifndef _UFS_LFS_LFS_EXTERN_H_
-#define _UFS_LFS_LFS_EXTERN_H_
-
-#ifdef KERNEL
-
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_LFSNODE);
-MALLOC_DECLARE(M_SEGMENT); /* XXX should be M_LFSSEGMENT ?? */
-#endif
-
-struct inode;
-struct mount;
-struct nameidata;
-
-int lfs_balloc __P((struct vnode *, int, u_long, ufs_daddr_t, struct buf **));
-int lfs_blkatoff __P((struct vnode *, off_t, char **, struct buf **));
-int lfs_bwrite __P((struct vop_bwrite_args *));
-int lfs_check __P((struct vnode *, ufs_daddr_t));
-void lfs_free_buffer __P((caddr_t, int));
-int lfs_gatherblock __P((struct segment *, struct buf *, int *));
-struct dinode *
- lfs_ifind __P((struct lfs *, ino_t, struct dinode *));
-int lfs_init __P((struct vfsconf *));
-int lfs_initseg __P((struct lfs *));
-int lfs_makeinode __P((int, struct nameidata *, struct inode **));
-int lfs_mountroot __P((void));
-struct buf *
- lfs_newbuf __P((struct vnode *, ufs_daddr_t, size_t));
-void lfs_seglock __P((struct lfs *, unsigned long flags));
-void lfs_segunlock __P((struct lfs *));
-int lfs_segwrite __P((struct mount *, int));
-#define lfs_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
- size_t, struct proc *)))eopnotsupp)
-int lfs_truncate __P((struct vnode *, off_t, int, struct ucred *, struct proc *));
-int lfs_update __P((struct vnode *, struct timeval *, struct timeval *, int));
-void lfs_updatemeta __P((struct segment *));
-int lfs_valloc __P((struct vnode *, int, struct ucred *, struct vnode **));
-int lfs_vcreate __P((struct mount *, ino_t, struct vnode **));
-int lfs_vfree __P((struct vnode *, ino_t, int));
-int lfs_vflush __P((struct vnode *));
-int lfs_vref __P((struct vnode *));
-void lfs_vunref __P((struct vnode *));
-int lfs_writeinode __P((struct lfs *, struct segment *, struct inode *));
-int lfs_writeseg __P((struct lfs *, struct segment *));
-void lfs_writesuper __P((struct lfs *));
-
-extern int lfs_allclean_wakeup;
-extern int lfs_mount_type;
-extern int locked_queue_count;
-extern vop_t **lfs_vnodeop_p;
-extern vop_t **lfs_specop_p;
-extern vop_t **lfs_fifoop_p;
-#define LFS_FIFOOPS lfs_fifoop_p
-
-#endif /* KERNEL */
-
-__BEGIN_DECLS
-u_long cksum __P((void *, size_t)); /* XXX */
-__END_DECLS
-
-#endif /* !_UFS_LFS_LFS_EXTERN_H_ */
diff --git a/sys/ufs/lfs/lfs_inode.c b/sys/ufs/lfs/lfs_inode.c
deleted file mode 100644
index 39edcae76253..000000000000
--- a/sys/ufs/lfs/lfs_inode.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (c) 1986, 1989, 1991, 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.
- *
- * 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.
- *
- * @(#)lfs_inode.c 8.9 (Berkeley) 5/8/95
- * $Id: lfs_inode.c,v 1.19 1997/10/16 10:49:47 phk Exp $
- */
-
-#include "opt_quota.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mount.h>
-#include <sys/buf.h>
-#include <sys/vnode.h>
-#include <sys/kernel.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ufs/ufs_extern.h>
-
-#include <ufs/lfs/lfs.h>
-#include <ufs/lfs/lfs_extern.h>
-
-/* Search a block for a specific dinode. */
-struct dinode *
-lfs_ifind(fs, ino, dip)
- struct lfs *fs;
- ino_t ino;
- register struct dinode *dip;
-{
- register int cnt;
- register struct dinode *ldip;
-
- for (cnt = INOPB(fs), ldip = dip + (cnt - 1); cnt--; --ldip)
- if (ldip->di_inumber == ino)
- return (ldip);
-
- panic("lfs_ifind: dinode %u not found", ino);
- /* NOTREACHED */
-}
-
-int
-lfs_update(vp, access, modify, waitfor)
- struct vnode *vp;
- struct timeval *access;
- struct timeval *modify;
- int waitfor;
-{
- struct inode *ip;
- int error;
-
- if (vp->v_mount->mnt_flag & MNT_RDONLY){
- return (0);
- }
- ip = VTOI(vp);
- /* XXX
- * We used to just return here. Now we make sure to check if
- * we were called by lfs_fsync, since in this case, the inode
- * may have been written to disk without all buffers connected
- * with the vnode being flushed. It seems really suspicious
- * that this could happen since from what I understand of the
- * intended semantics, one of these flags should be set if there
- * are still dirty buffers. Compare to how ffs_fsync/ffs_update
- * work together and you'll see what I mean.
- */
- if (((ip->i_flag & (IN_ACCESS|IN_CHANGE|IN_MODIFIED|IN_UPDATE)) == 0)
- && (vp->v_dirtyblkhd.lh_first == NULL))
- return(0);
-
- if (ip->i_flag & IN_ACCESS)
- ip->i_atime = access->tv_sec;
- if (ip->i_flag & IN_UPDATE) {
- ip->i_mtime = modify->tv_sec;
- (ip)->i_modrev++;
- }
- if (ip->i_flag & IN_CHANGE)
- ip->i_ctime = time.tv_sec;
- ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);
-
- if (!(ip->i_flag & IN_MODIFIED))
- ++(VFSTOUFS(vp->v_mount)->um_lfs->lfs_uinodes);
- ip->i_flag |= IN_MODIFIED;
-
- /* If sync, push back the vnode and any dirty blocks it may have. */
- error = (waitfor & LFS_SYNC ? lfs_vflush(vp) : 0);
- if(waitfor & LFS_SYNC && vp->v_dirtyblkhd.lh_first != NULL)
- panic("lfs_update: dirty bufs");
- return( error );
-
-}
-
-/* Update segment usage information when removing a block. */
-#define UPDATE_SEGUSE \
- if (lastseg != -1) { \
- LFS_SEGENTRY(sup, fs, lastseg, sup_bp); \
- if (num > sup->su_nbytes) \
- panic("lfs_truncate: negative bytes in segment %d", \
- lastseg); \
- sup->su_nbytes -= num; \
- e1 = VOP_BWRITE(sup_bp); \
- fragsreleased += numfrags(fs, num); \
- }
-
-#define SEGDEC(S) { \
- if (daddr != 0) { \
- if (lastseg != (seg = datosn(fs, daddr))) { \
- UPDATE_SEGUSE; \
- num = (S); \
- lastseg = seg; \
- } else \
- num += (S); \
- } \
-}
-
-/*
- * Truncate the inode ip to at most length size. Update segment usage
- * table information.
- */
-/* ARGSUSED */
-int
-lfs_truncate(vp, length, flags, cred, p)
- struct vnode *vp;
- off_t length;
- int flags;
- struct ucred *cred;
- struct proc *p;
-{
- register struct indir *inp;
- register int i;
- register ufs_daddr_t *daddrp;
- struct buf *bp, *sup_bp;
- struct timeval tv;
- struct ifile *ifp;
- struct inode *ip;
- struct lfs *fs;
- struct indir a[NIADDR + 2], a_end[NIADDR + 2];
- SEGUSE *sup;
- ufs_daddr_t daddr, lastblock, lbn, olastblock;
- ufs_daddr_t oldsize_lastblock, oldsize_newlast, newsize;
- long off, a_released, fragsreleased, i_released;
- int e1, e2, depth, lastseg, num, offset, seg, freesize;
-
- ip = VTOI(vp);
- gettime(&tv);
- if (vp->v_type == VLNK && vp->v_mount->mnt_maxsymlinklen > 0) {
-#ifdef DIAGNOSTIC
- if (length != 0)
- panic("lfs_truncate: partial truncate of symlink");
-#endif
- bzero((char *)&ip->i_shortlink, (u_int)ip->i_size);
- ip->i_size = 0;
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
- return (UFS_UPDATE(vp, &tv, &tv, 0));
- }
- vnode_pager_setsize(vp, (u_long)length);
-
- fs = ip->i_lfs;
-
- /* If length is larger than the file, just update the times. */
- if (ip->i_size <= length) {
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
- return (UFS_UPDATE(vp, &tv, &tv, 0));
- }
-
- /*
- * Calculate index into inode's block list of last direct and indirect
- * blocks (if any) which we want to keep. Lastblock is 0 when the
- * file is truncated to 0.
- */
- lastblock = lblkno(fs, length + fs->lfs_bsize - 1);
- olastblock = lblkno(fs, ip->i_size + fs->lfs_bsize - 1) - 1;
-
- /*
- * Update the size of the file. If the file is not being truncated to
- * a block boundry, the contents of the partial block following the end
- * of the file must be zero'ed in case it ever become accessable again
- * because of subsequent file growth. For this part of the code,
- * oldsize_newlast refers to the old size of the new last block in the file.
- */
- offset = blkoff(fs, length);
- lbn = lblkno(fs, length);
- oldsize_newlast = blksize(fs, ip, lbn);
-
- /* Now set oldsize to the current size of the current last block */
- oldsize_lastblock = blksize(fs, ip, olastblock);
- if (offset == 0)
- ip->i_size = length;
- else {
-#ifdef QUOTA
- if (e1 = getinoquota(ip))
- return (e1);
-#endif
- if (e1 = bread(vp, lbn, oldsize_newlast, NOCRED, &bp))
- return (e1);
- ip->i_size = length;
- newsize = blksize(fs, ip, lbn);
- bzero((char *)bp->b_data + offset, (u_int)(newsize - offset));
- allocbuf(bp, newsize);
- if (e1 = VOP_BWRITE(bp))
- return (e1);
- }
- /*
- * Modify sup->su_nbyte counters for each deleted block; keep track
- * of number of blocks removed for ip->i_blocks.
- */
- fragsreleased = 0;
- num = 0;
- lastseg = -1;
-
- for (lbn = olastblock; lbn >= lastblock;) {
- /* XXX use run length from bmap array to make this faster */
- ufs_bmaparray(vp, lbn, &daddr, a, &depth, NULL, NULL);
- if (lbn == olastblock) {
- for (i = NIADDR + 2; i--;)
- a_end[i] = a[i];
- freesize = oldsize_lastblock;
- } else
- freesize = fs->lfs_bsize;
-
- switch (depth) {
- case 0: /* Direct block. */
- daddr = ip->i_db[lbn];
- SEGDEC(freesize);
- ip->i_db[lbn] = 0;
- --lbn;
- break;
-#ifdef DIAGNOSTIC
- case 1: /* An indirect block. */
- panic("lfs_truncate: ufs_bmaparray returned depth 1");
- /* NOTREACHED */
-#endif
- default: /* Chain of indirect blocks. */
- inp = a + --depth;
- if (inp->in_off > 0 && lbn != lastblock) {
- lbn -= inp->in_off < lbn - lastblock ?
- inp->in_off : lbn - lastblock;
- break;
- }
- for (; depth && (inp->in_off == 0 || lbn == lastblock);
- --inp, --depth) {
- if (bread(vp,
- inp->in_lbn, fs->lfs_bsize, NOCRED, &bp))
- panic("lfs_truncate: bread bno %d",
- inp->in_lbn);
- daddrp = (ufs_daddr_t *)bp->b_data +
- inp->in_off;
- for (i = inp->in_off;
- i++ <= a_end[depth].in_off;) {
- daddr = *daddrp++;
- SEGDEC(freesize);
- }
- a_end[depth].in_off = NINDIR(fs) - 1;
- if (inp->in_off == 0)
- brelse (bp);
- else {
- bzero((ufs_daddr_t *)bp->b_data +
- inp->in_off, fs->lfs_bsize -
- inp->in_off * sizeof(ufs_daddr_t));
- if (e1 = VOP_BWRITE(bp))
- return (e1);
- }
- }
- if (depth == 0 && a[1].in_off == 0) {
- off = a[0].in_off;
- daddr = ip->i_ib[off];
- SEGDEC(freesize);
- ip->i_ib[off] = 0;
- }
- if (lbn == lastblock || lbn <= NDADDR)
- --lbn;
- else {
- lbn -= NINDIR(fs);
- if (lbn < lastblock)
- lbn = lastblock;
- }
- }
- }
- UPDATE_SEGUSE;
-
- /* If truncating the file to 0, update the version number. */
- if (length == 0) {
- LFS_IENTRY(ifp, fs, ip->i_number, bp);
- ++ifp->if_version;
- (void) VOP_BWRITE(bp);
- }
-
-#ifdef DIAGNOSTIC
- if (ip->i_blocks < fragstodb(fs, fragsreleased)) {
- printf("lfs_truncate: frag count < 0\n");
- fragsreleased = dbtofrags(fs, ip->i_blocks);
- panic("lfs_truncate: frag count < 0\n");
- }
-#endif
- ip->i_blocks -= fragstodb(fs, fragsreleased);
- fs->lfs_bfree += fragstodb(fs, fragsreleased);
- ip->i_flag |= IN_CHANGE | IN_UPDATE;
- /*
- * Traverse dirty block list counting number of dirty buffers
- * that are being deleted out of the cache, so that the lfs_avail
- * field can be updated.
- */
- a_released = 0;
- i_released = 0;
- for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = bp->b_vnbufs.le_next)
- if (bp->b_flags & B_LOCKED) {
- a_released += numfrags(fs, bp->b_bcount);
- /*
- * XXX
- * When buffers are created in the cache, their block
- * number is set equal to their logical block number.
- * If that is still true, we are assuming that the
- * blocks are new (not yet on disk) and weren't
- * counted above. However, there is a slight chance
- * that a block's disk address is equal to its logical
- * block number in which case, we'll get an overcounting
- * here.
- */
- if (bp->b_blkno == bp->b_lblkno)
- i_released += numfrags(fs, bp->b_bcount);
- }
- fragsreleased = i_released;
-#ifdef DIAGNOSTIC
- if (fragsreleased > dbtofrags(fs, ip->i_blocks)) {
- printf("lfs_inode: Warning! %s\n",
- "more frags released from inode than are in inode");
- fragsreleased = dbtofrags(fs, ip->i_blocks);
- panic("lfs_inode: Warning. More frags released\n");
- }
-#endif
- fs->lfs_bfree += fragstodb(fs, fragsreleased);
- ip->i_blocks -= fragstodb(fs, fragsreleased);
-#ifdef DIAGNOSTIC
- if (length == 0 && ip->i_blocks != 0) {
- printf("lfs_inode: Warning! %s%ld%s\n",
- "Truncation to zero, but ", ip->i_blocks,
- " blocks left on inode");
- panic("lfs_inode");
- }
-#endif
- fs->lfs_avail += fragstodb(fs, a_released);
- e1 = vinvalbuf(vp, (length > 0) ? V_SAVE : 0, cred, p,
- 0, 0);
- e2 = UFS_UPDATE(vp, &tv, &tv, 0);
- return (e1 ? e1 : e2 ? e2 : 0);
-}
diff --git a/sys/ufs/lfs/lfs_segment.c b/sys/ufs/lfs/lfs_segment.c
deleted file mode 100644
index 3916d17ed4fc..000000000000
--- a/sys/ufs/lfs/lfs_segment.c
+++ /dev/null
@@ -1,1248 +0,0 @@
-/*
- * Copyright (c) 1991, 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.
- *
- * 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.
- *
- * @(#)lfs_segment.c 8.10 (Berkeley) 6/10/95
- * $Id: lfs_segment.c,v 1.26 1997/12/02 21:07:17 phk Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ufs/ufs_extern.h>
-
-#include <ufs/lfs/lfs.h>
-#include <ufs/lfs/lfs_extern.h>
-
-extern int count_lock_queue __P((void));
-static caddr_t lfs_alloc_buffer __P((int size));
-static void lfs_reclaim_buffers __P((void));
-
-#define MAX_ACTIVE 10
-#define MAX_IO_BUFS 256
-#define MAX_IO_SIZE (1024*512)
-static int lfs_total_io_size;
-static int lfs_total_io_count;
-static volatile int lfs_total_free_count;
-static int lfs_free_needed;
-static int lfs_in_buffer_reclaim;
-static struct lfs_freebuf {
- int size;
- caddr_t address;
-} lfs_freebufs[MAX_IO_BUFS];
-
-void
-lfs_free_buffer( caddr_t address, int size) {
- lfs_freebufs[lfs_total_free_count].address = address;
- lfs_freebufs[lfs_total_free_count].size = size;
- ++lfs_total_free_count;
- if( lfs_free_needed) {
- wakeup((caddr_t) &lfs_free_needed);
- lfs_free_needed = 0;
- }
-}
-
-static void
-lfs_reclaim_buffers() {
- int i,s;
- int reclaimed = 0;
- if( lfs_in_buffer_reclaim)
- return;
- lfs_in_buffer_reclaim = 1;
- s = splhigh();
- for(i=0;i<lfs_total_free_count;i++) {
- reclaimed = 1;
- if( lfs_freebufs[i].address ){
- splx(s);
- free(lfs_freebufs[i].address, M_SEGMENT);
- s = splhigh();
- }
- lfs_total_io_size -= lfs_freebufs[i].size;
- lfs_total_io_count -= 1;
- }
- lfs_in_buffer_reclaim = 0;
- lfs_total_free_count = 0;
- splx(s);
- if( reclaimed) {
- wakeup((caddr_t) &lfs_free_needed);
- }
-}
-
-static caddr_t
-lfs_alloc_buffer(int size) {
- int s;
- caddr_t rtval;
- if( lfs_total_free_count)
- lfs_reclaim_buffers();
- s = splhigh(); /* XXX can't this just be splbio?? */
- while( ((lfs_total_io_count+1) >= MAX_IO_BUFS) ||
- (lfs_total_io_size >= MAX_IO_SIZE)) {
- lfs_free_needed = 1;
- tsleep(&lfs_free_needed, PRIBIO, "lfsalc", 0);
- splx(s);
- lfs_reclaim_buffers();
- s = splhigh();
- }
- splx(s);
- lfs_total_io_size += size;
- lfs_total_io_count += 1;
- rtval = malloc(size, M_SEGMENT, M_WAITOK);
- return rtval;
-}
-
-
-/*
- * Determine if it's OK to start a partial in this segment, or if we need
- * to go on to a new segment.
- */
-#define LFS_PARTIAL_FITS(fs) \
- ((fs)->lfs_dbpseg - ((fs)->lfs_offset - (fs)->lfs_curseg) > \
- 1 << (fs)->lfs_fsbtodb)
-
-static void lfs_callback __P((struct buf *));
-static void lfs_gather __P((struct lfs *, struct segment *,
- struct vnode *, int (*) __P((struct lfs *, struct buf *))));
-void lfs_iset __P((struct inode *, ufs_daddr_t, time_t));
-static int lfs_match_data __P((struct lfs *, struct buf *));
-static int lfs_match_dindir __P((struct lfs *, struct buf *));
-static int lfs_match_indir __P((struct lfs *, struct buf *));
-#ifdef TRIPLE
-static int lfs_match_tindir __P((struct lfs *, struct buf *));
-#endif
-static void lfs_newseg __P((struct lfs *));
-static void lfs_shellsort __P((struct buf **, ufs_daddr_t *, register int));
-static void lfs_supercallback __P((struct buf *));
-static void lfs_writefile __P((struct lfs *, struct segment *, struct vnode *));
-static void lfs_writevnodes __P((struct lfs *fs, struct mount *mp,
- struct segment *sp, int dirops));
-
-/* Statistics Counters */
-#define DOSTATS
-struct lfs_stats lfs_stats;
-
-/* op values to lfs_writevnodes */
-#define VN_REG 0
-#define VN_DIROP 1
-#define VN_EMPTY 2
-
-/*
- * Ifile and meta data blocks are not marked busy, so segment writes MUST be
- * single threaded. Currently, there are two paths into lfs_segwrite, sync()
- * and getnewbuf(). They both mark the file system busy. Lfs_vflush()
- * explicitly marks the file system busy. So lfs_segwrite is safe. I think.
- */
-
-int
-
-lfs_vflush(vp)
- struct vnode *vp;
-{
- struct inode *ip;
- struct lfs *fs;
- struct segment *sp;
- int error;
-
- fs = VFSTOUFS(vp->v_mount)->um_lfs;
- /* XXX
- * lfs_segwrite uses lfs_writevnodes to flush dirty vnodes.
- * lfs_writevnodes (by way of a check with lfs_vref) passes over
- * locked vnodes. Since we usually come here with vp locked, anytime
- * we just happen to call lfs_vflush and we are past the "MAX_ACTIVE"
- * threshold, we used to call lfs_seqwrite and assume it would take
- * care of the problem... but of course it didn't. Now the question
- * remains, is this the right thing to do, or should lfs_seqwrite or
- * lfs_writevnodes be fixed to handle locked vnodes??
- */
- if (fs->lfs_nactive > MAX_ACTIVE){
- error = lfs_segwrite(vp->v_mount, SEGM_SYNC|SEGM_CKP);
- if(error)
- return(error);
- }
-
- lfs_seglock(fs, SEGM_SYNC);
- sp = fs->lfs_sp;
-
- ip = VTOI(vp);
-
- if (vp->v_dirtyblkhd.lh_first == NULL)
- lfs_writevnodes(fs, vp->v_mount, sp, VN_EMPTY);
-
- do {
- do {
- if (vp->v_dirtyblkhd.lh_first != NULL)
- lfs_writefile(fs, sp, vp);
- } while (lfs_writeinode(fs, sp, ip));
-
- } while (lfs_writeseg(fs, sp) && ip->i_number == LFS_IFILE_INUM);
-
- if (vp->v_dirtyblkhd.lh_first != NULL)
- panic("lfs_vflush: dirty bufs!!!");
-
-#ifdef DOSTATS
- ++lfs_stats.nwrites;
- if (sp->seg_flags & SEGM_SYNC)
- ++lfs_stats.nsync_writes;
- if (sp->seg_flags & SEGM_CKP)
- ++lfs_stats.ncheckpoints;
-#endif
- lfs_segunlock(fs);
- return (0);
-}
-
-static void
-lfs_writevnodes(fs, mp, sp, op)
- struct lfs *fs;
- struct mount *mp;
- struct segment *sp;
- int op;
-{
- struct inode *ip;
- struct vnode *vp;
-
-/* BEGIN HACK */
-#define VN_OFFSET (((u_char *)&vp->v_mntvnodes.le_next) - (u_char *)vp)
-#define BACK_VP(VP) ((struct vnode *)(((u_char *)VP->v_mntvnodes.le_prev) - VN_OFFSET))
-#define BEG_OF_VLIST ((struct vnode *)(((u_char *)&mp->mnt_vnodelist.lh_first) - VN_OFFSET))
-
-/* Find last vnode. */
-loop: for (vp = mp->mnt_vnodelist.lh_first;
- vp && vp->v_mntvnodes.le_next != NULL;
- vp = vp->v_mntvnodes.le_next);
- for (; vp && vp != BEG_OF_VLIST; vp = BACK_VP(vp)) {
-/* END HACK */
-/*
-loop:
- for (vp = mp->mnt_vnodelist.lh_first;
- vp != NULL;
- vp = vp->v_mntvnodes.le_next) {
-*/
- /*
- * If the vnode that we are about to sync is no longer
- * associated with this mount point, start over.
- */
- if (vp->v_mount != mp)
- goto loop;
-
- /* XXX ignore dirops for now
- if (op == VN_DIROP && !(vp->v_flag & VDIROP) ||
- op != VN_DIROP && (vp->v_flag & VDIROP))
- continue;
- */
-
- if (op == VN_EMPTY && vp->v_dirtyblkhd.lh_first)
- continue;
-
- if (vp->v_type == VNON)
- continue;
-
- if (lfs_vref(vp))
- continue;
-
- /*
- * Write the inode/file if dirty and it's not the
- * the IFILE.
- */
- ip = VTOI(vp);
- if ((ip->i_flag &
- (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE) ||
- vp->v_dirtyblkhd.lh_first != NULL) &&
- ip->i_number != LFS_IFILE_INUM) {
- if (vp->v_dirtyblkhd.lh_first != NULL)
- lfs_writefile(fs, sp, vp);
- (void) lfs_writeinode(fs, sp, ip);
- }
- vp->v_flag &= ~VDIROP;
- lfs_vunref(vp);
- }
-}
-
-int
-lfs_segwrite(mp, flags)
- struct mount *mp;
- int flags; /* Do a checkpoint. */
-{
- struct proc *p = curproc; /* XXX */
- struct buf *bp;
- struct inode *ip;
- struct lfs *fs;
- struct segment *sp;
- struct vnode *vp;
- SEGUSE *segusep;
- ufs_daddr_t ibno;
- CLEANERINFO *cip;
- int clean, do_ckp, error, i;
-
- fs = VFSTOUFS(mp)->um_lfs;
-
- /*
- * If we have fewer than 2 clean segments, wait until cleaner
- * writes.
- */
- do {
- LFS_CLEANERINFO(cip, fs, bp);
- clean = cip->clean;
- brelse(bp);
- if (clean <= 2 || fs->lfs_avail <= 0) {
- printf("lfs_segwrite: ran out of clean segments, waiting for cleaner\n");
- wakeup(&lfs_allclean_wakeup);
- wakeup(&fs->lfs_nextseg);
- if (error = tsleep(&fs->lfs_avail, PRIBIO + 1,
- "lfs writer", 0))
- return (error);
- }
- } while (clean <= 2 || fs->lfs_avail <= 0);
-
- /*
- * Allocate a segment structure and enough space to hold pointers to
- * the maximum possible number of buffers which can be described in a
- * single summary block.
- */
- do_ckp = flags & SEGM_CKP || fs->lfs_nactive > MAX_ACTIVE;
- lfs_seglock(fs, flags | (do_ckp ? SEGM_CKP : 0));
- sp = fs->lfs_sp;
-
- lfs_writevnodes(fs, mp, sp, VN_REG);
-
- /* XXX ignore ordering of dirops for now */
- /* XXX
- fs->lfs_writer = 1;
- if (fs->lfs_dirops && (error =
- tsleep(&fs->lfs_writer, PRIBIO + 1, "lfs writer", 0))) {
- free(sp->bpp, M_SEGMENT);
- free(sp, M_SEGMENT);
- fs->lfs_writer = 0;
- return (error);
- }
-
- lfs_writevnodes(fs, mp, sp, VN_DIROP);
- */
-
- /*
- * If we are doing a checkpoint, mark everything since the
- * last checkpoint as no longer ACTIVE.
- */
- if (do_ckp)
- for (ibno = fs->lfs_cleansz + fs->lfs_segtabsz;
- --ibno >= fs->lfs_cleansz; ) {
- if (bread(fs->lfs_ivnode, ibno, fs->lfs_bsize,
- NOCRED, &bp))
-
- panic("lfs: ifile read");
- segusep = (SEGUSE *)bp->b_data;
- for (i = fs->lfs_sepb; i--; segusep++)
- segusep->su_flags &= ~SEGUSE_ACTIVE;
-
- error = VOP_BWRITE(bp);
- }
-
- if (do_ckp || fs->lfs_doifile) {
-redo:
- vp = fs->lfs_ivnode;
- while (vget(vp, LK_EXCLUSIVE, p))
- continue;
- ip = VTOI(vp);
- if (vp->v_dirtyblkhd.lh_first != NULL)
- lfs_writefile(fs, sp, vp);
- (void)lfs_writeinode(fs, sp, ip);
- vput(vp);
- if (lfs_writeseg(fs, sp) && do_ckp)
- goto redo;
- } else
- (void) lfs_writeseg(fs, sp);
-
- /*
- * If the I/O count is non-zero, sleep until it reaches zero. At the
- * moment, the user's process hangs around so we can sleep.
- */
- /* XXX ignore dirops for now
- fs->lfs_writer = 0;
- fs->lfs_doifile = 0;
- wakeup(&fs->lfs_dirops);
- */
-
-#ifdef DOSTATS
- ++lfs_stats.nwrites;
- if (sp->seg_flags & SEGM_SYNC)
- ++lfs_stats.nsync_writes;
- if (sp->seg_flags & SEGM_CKP)
- ++lfs_stats.ncheckpoints;
-#endif
- lfs_segunlock(fs);
- return (0);
-}
-
-/*
- * Write the dirty blocks associated with a vnode.
- */
-static void
-lfs_writefile(fs, sp, vp)
- struct lfs *fs;
- struct segment *sp;
- struct vnode *vp;
-{
- struct buf *bp;
- struct finfo *fip;
- IFILE *ifp;
-
- if (sp->seg_bytes_left < fs->lfs_bsize ||
- sp->sum_bytes_left < sizeof(struct finfo))
- (void) lfs_writeseg(fs, sp);
-
- sp->sum_bytes_left -= sizeof(struct finfo) - sizeof(ufs_daddr_t);
- ++((SEGSUM *)(sp->segsum))->ss_nfinfo;
-
- fip = sp->fip;
- fip->fi_nblocks = 0;
- fip->fi_ino = VTOI(vp)->i_number;
- LFS_IENTRY(ifp, fs, fip->fi_ino, bp);
- fip->fi_version = ifp->if_version;
- brelse(bp);
-
- /*
- * It may not be necessary to write the meta-data blocks at this point,
- * as the roll-forward recovery code should be able to reconstruct the
- * list.
- */
- lfs_gather(fs, sp, vp, lfs_match_data);
- lfs_gather(fs, sp, vp, lfs_match_indir);
- lfs_gather(fs, sp, vp, lfs_match_dindir);
-#ifdef TRIPLE
- lfs_gather(fs, sp, vp, lfs_match_tindir);
-#endif
-
- fip = sp->fip;
- if (fip->fi_nblocks != 0) {
- sp->fip =
- (struct finfo *)((caddr_t)fip + sizeof(struct finfo) +
- sizeof(ufs_daddr_t) * (fip->fi_nblocks - 1));
- sp->start_lbp = &sp->fip->fi_blocks[0];
- } else {
- sp->sum_bytes_left += sizeof(struct finfo) - sizeof(ufs_daddr_t);
- --((SEGSUM *)(sp->segsum))->ss_nfinfo;
- }
-}
-
-int
-lfs_writeinode(fs, sp, ip)
- struct lfs *fs;
- struct segment *sp;
- struct inode *ip;
-{
- struct buf *bp, *ibp;
- IFILE *ifp;
- SEGUSE *sup;
- ufs_daddr_t daddr;
- ino_t ino;
- int error, i, ndx;
- int redo_ifile = 0;
-
- if (!(ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)))
- return(0);
-
- /* Allocate a new inode block if necessary. */
- if (sp->ibp == NULL) {
- /* Allocate a new segment if necessary. */
- if (sp->seg_bytes_left < fs->lfs_bsize ||
- sp->sum_bytes_left < sizeof(ufs_daddr_t))
- (void) lfs_writeseg(fs, sp);
-
- /* Get next inode block. */
- daddr = fs->lfs_offset;
- fs->lfs_offset += fsbtodb(fs, 1);
- sp->ibp = *sp->cbpp++ =
- lfs_newbuf(VTOI(fs->lfs_ivnode)->i_devvp, daddr,
- fs->lfs_bsize);
- /* Zero out inode numbers */
- for (i = 0; i < INOPB(fs); ++i)
- ((struct dinode *)sp->ibp->b_data)[i].di_inumber = 0;
- ++sp->start_bpp;
- fs->lfs_avail -= fsbtodb(fs, 1);
- /* Set remaining space counters. */
- sp->seg_bytes_left -= fs->lfs_bsize;
- sp->sum_bytes_left -= sizeof(ufs_daddr_t);
- ndx = LFS_SUMMARY_SIZE / sizeof(ufs_daddr_t) -
- sp->ninodes / INOPB(fs) - 1;
- ((ufs_daddr_t *)(sp->segsum))[ndx] = daddr;
- }
-
- /* Update the inode times and copy the inode onto the inode page. */
- if (ip->i_flag & IN_MODIFIED)
- --fs->lfs_uinodes;
- ITIMES(ip, &time, &time);
- ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
- bp = sp->ibp;
- ((struct dinode *)bp->b_data)[sp->ninodes % INOPB(fs)] = ip->i_din;
- /* Increment inode count in segment summary block. */
- ++((SEGSUM *)(sp->segsum))->ss_ninos;
-
- /* If this page is full, set flag to allocate a new page. */
- if (++sp->ninodes % INOPB(fs) == 0)
- sp->ibp = NULL;
-
- /*
- * If updating the ifile, update the super-block. Update the disk
- * address and access times for this inode in the ifile.
- */
- ino = ip->i_number;
- if (ino == LFS_IFILE_INUM) {
- daddr = fs->lfs_idaddr;
- fs->lfs_idaddr = bp->b_blkno;
- } else {
- LFS_IENTRY(ifp, fs, ino, ibp);
- daddr = ifp->if_daddr;
- ifp->if_daddr = bp->b_blkno;
- error = VOP_BWRITE(ibp);
- }
-
- /*
- * No need to update segment usage if there was no former inode address
- * or if the last inode address is in the current partial segment.
- */
- if (daddr != LFS_UNUSED_DADDR &&
- !(daddr >= fs->lfs_lastpseg && daddr <= bp->b_blkno)) {
- LFS_SEGENTRY(sup, fs, datosn(fs, daddr), bp);
-#ifdef DIAGNOSTIC
- if (sup->su_nbytes < sizeof(struct dinode)) {
- /* XXX -- Change to a panic. */
- printf("lfs: negative bytes (segment %ld)\n",
- datosn(fs, daddr));
- panic("negative bytes");
- }
-#endif
- sup->su_nbytes -= sizeof(struct dinode);
- redo_ifile =
- (ino == LFS_IFILE_INUM && !(bp->b_flags & B_GATHERED));
- error = VOP_BWRITE(bp);
- }
- return (redo_ifile);
-}
-
-int
-lfs_gatherblock(sp, bp, sptr)
- struct segment *sp;
- struct buf *bp;
- int *sptr;
-{
- struct lfs *fs;
- int version;
-
- /*
- * If full, finish this segment. We may be doing I/O, so
- * release and reacquire the splbio().
- */
-#ifdef DIAGNOSTIC
- if (sp->vp == NULL)
- panic ("lfs_gatherblock: Null vp in segment");
-#endif
- fs = sp->fs;
- if (sp->sum_bytes_left < sizeof(ufs_daddr_t) ||
- sp->seg_bytes_left < bp->b_bcount) {
- if (sptr)
- splx(*sptr);
- lfs_updatemeta(sp);
-
- version = sp->fip->fi_version;
- (void) lfs_writeseg(fs, sp);
-
- sp->fip->fi_version = version;
- sp->fip->fi_ino = VTOI(sp->vp)->i_number;
- /* Add the current file to the segment summary. */
- ++((SEGSUM *)(sp->segsum))->ss_nfinfo;
- sp->sum_bytes_left -=
- sizeof(struct finfo) - sizeof(ufs_daddr_t);
-
- if (sptr)
- *sptr = splbio();
- return(1);
- }
-
- /* Insert into the buffer list, update the FINFO block. */
- bp->b_flags |= B_GATHERED;
- *sp->cbpp++ = bp;
- sp->fip->fi_blocks[sp->fip->fi_nblocks++] = bp->b_lblkno;
-
- sp->sum_bytes_left -= sizeof(ufs_daddr_t);
- sp->seg_bytes_left -= bp->b_bcount;
- return(0);
-}
-
-static void
-lfs_gather(fs, sp, vp, match)
- struct lfs *fs;
- struct segment *sp;
- struct vnode *vp;
- int (*match) __P((struct lfs *, struct buf *));
-{
- struct buf *bp;
- int s;
-
- sp->vp = vp;
- s = splbio();
-/* This is a hack to see if ordering the blocks in LFS makes a difference. */
-/* BEGIN HACK */
-#define BUF_OFFSET (((u_char *)&bp->b_vnbufs.le_next) - (u_char *)bp)
-#define BACK_BUF(BP) ((struct buf *)(((u_char *)BP->b_vnbufs.le_prev) - BUF_OFFSET))
-#define BEG_OF_LIST ((struct buf *)(((u_char *)&vp->v_dirtyblkhd.lh_first) - BUF_OFFSET))
-
-
-/*loop: for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = bp->b_vnbufs.le_next) {*/
-/* Find last buffer. */
-loop: for (bp = vp->v_dirtyblkhd.lh_first; bp && bp->b_vnbufs.le_next != NULL;
- bp = bp->b_vnbufs.le_next);
- for (; bp && bp != BEG_OF_LIST; bp = BACK_BUF(bp)) {
-/* END HACK */
- if (bp->b_flags & B_BUSY || !match(fs, bp) ||
- bp->b_flags & B_GATHERED)
- continue;
-#ifdef DIAGNOSTIC
- if (!(bp->b_flags & B_DELWRI))
- panic("lfs_gather: bp not B_DELWRI");
- if (!(bp->b_flags & B_LOCKED))
- panic("lfs_gather: bp not B_LOCKED");
-#endif
- if (lfs_gatherblock(sp, bp, &s))
- goto loop;
- }
- splx(s);
- lfs_updatemeta(sp);
- sp->vp = NULL;
-}
-
-
-/*
- * Update the metadata that points to the blocks listed in the FINFO
- * array.
- */
-void
-lfs_updatemeta(sp)
- struct segment *sp;
-{
- SEGUSE *sup;
- struct buf *bp;
- struct lfs *fs;
- struct vnode *vp;
- struct indir a[NIADDR + 2], *ap;
- struct inode *ip;
- ufs_daddr_t daddr, lbn, off;
- int error, i, nblocks, num;
-
- vp = sp->vp;
- nblocks = &sp->fip->fi_blocks[sp->fip->fi_nblocks] - sp->start_lbp;
- if (nblocks < 0)
- panic("This is a bad thing\n");
- if (vp == NULL || nblocks == 0)
- return;
-
- /* Sort the blocks. */
- if (!(sp->seg_flags & SEGM_CLEAN))
- lfs_shellsort(sp->start_bpp, sp->start_lbp, nblocks);
-
- /*
- * Record the length of the last block in case it's a fragment.
- * If there are indirect blocks present, they sort last. An
- * indirect block will be lfs_bsize and its presence indicates
- * that you cannot have fragments.
- */
- sp->fip->fi_lastlength = sp->start_bpp[nblocks - 1]->b_bcount;
-
- /*
- * Assign disk addresses, and update references to the logical
- * block and the segment usage information.
- */
- fs = sp->fs;
- for (i = nblocks; i--; ++sp->start_bpp) {
- lbn = *sp->start_lbp++;
- (*sp->start_bpp)->b_blkno = off = fs->lfs_offset;
- fs->lfs_offset +=
- fragstodb(fs, numfrags(fs, (*sp->start_bpp)->b_bcount));
-
- if (error = ufs_bmaparray(vp, lbn, &daddr, a, &num, NULL, NULL))
- panic("lfs_updatemeta: ufs_bmaparray %d", error);
- ip = VTOI(vp);
- switch (num) {
- case 0:
- ip->i_db[lbn] = off;
- break;
- case 1:
- ip->i_ib[a[0].in_off] = off;
- break;
- default:
- ap = &a[num - 1];
- if (bread(vp, ap->in_lbn, fs->lfs_bsize, NOCRED, &bp))
- panic("lfs_updatemeta: bread bno %d",
- ap->in_lbn);
- /*
- * Bread may create a new indirect block which needs
- * to get counted for the inode.
- */
- if (bp->b_blkno == -1 && !(bp->b_flags & B_CACHE)) {
- ip->i_blocks += fsbtodb(fs, 1);
- fs->lfs_bfree -= fragstodb(fs, fs->lfs_frag);
- }
- ((ufs_daddr_t *)bp->b_data)[ap->in_off] = off;
- VOP_BWRITE(bp);
- }
-
- /* Update segment usage information. */
- if (daddr != UNASSIGNED &&
- !(daddr >= fs->lfs_lastpseg && daddr <= off)) {
- LFS_SEGENTRY(sup, fs, datosn(fs, daddr), bp);
-#ifdef DIAGNOSTIC
- if (sup->su_nbytes < (*sp->start_bpp)->b_bcount) {
- /* XXX -- Change to a panic. */
- printf("lfs: negative bytes (segment %ld)\n",
- datosn(fs, daddr));
- printf("lfs: bp = 0x%x, addr = 0x%x\n",
- bp, bp->b_data);
- panic ("Negative Bytes");
- }
-#endif
- sup->su_nbytes -= (*sp->start_bpp)->b_bcount;
- error = VOP_BWRITE(bp);
- }
- }
-}
-
-/*
- * Start a new segment.
- */
-int
-lfs_initseg(fs)
- struct lfs *fs;
-{
- struct segment *sp;
- SEGUSE *sup;
- SEGSUM *ssp;
- struct buf *bp;
- int repeat;
-
- sp = fs->lfs_sp;
-
- repeat = 0;
- /* Advance to the next segment. */
- if (!LFS_PARTIAL_FITS(fs)) {
- /* Wake up any cleaning procs waiting on this file system. */
- wakeup(&lfs_allclean_wakeup);
- wakeup(&fs->lfs_nextseg);
-
- lfs_newseg(fs);
- repeat = 1;
- fs->lfs_offset = fs->lfs_curseg;
- sp->seg_number = datosn(fs, fs->lfs_curseg);
- sp->seg_bytes_left = fs->lfs_dbpseg * DEV_BSIZE;
-
- /*
- * If the segment contains a superblock, update the offset
- * and summary address to skip over it.
- */
- LFS_SEGENTRY(sup, fs, sp->seg_number, bp);
- if (sup->su_flags & SEGUSE_SUPERBLOCK) {
- fs->lfs_offset += LFS_SBPAD / DEV_BSIZE;
- sp->seg_bytes_left -= LFS_SBPAD;
- }
- brelse(bp);
- } else {
- sp->seg_number = datosn(fs, fs->lfs_curseg);
- sp->seg_bytes_left = (fs->lfs_dbpseg -
- (fs->lfs_offset - fs->lfs_curseg)) * DEV_BSIZE;
- }
- fs->lfs_lastpseg = fs->lfs_offset;
-
- sp->fs = fs;
- sp->ibp = NULL;
- sp->ninodes = 0;
-
- /* Get a new buffer for SEGSUM and enter it into the buffer list. */
- sp->cbpp = sp->bpp;
- *sp->cbpp = lfs_newbuf(VTOI(fs->lfs_ivnode)->i_devvp, fs->lfs_offset,
- LFS_SUMMARY_SIZE);
- sp->segsum = (*sp->cbpp)->b_data;
- bzero(sp->segsum, LFS_SUMMARY_SIZE);
- sp->start_bpp = ++sp->cbpp;
- fs->lfs_offset += LFS_SUMMARY_SIZE / DEV_BSIZE;
-
- /* Set point to SEGSUM, initialize it. */
- ssp = sp->segsum;
- ssp->ss_next = fs->lfs_nextseg;
- ssp->ss_nfinfo = ssp->ss_ninos = 0;
- ssp->ss_magic = SS_MAGIC;
-
- /* Set pointer to first FINFO, initialize it. */
- sp->fip = (struct finfo *)((caddr_t)sp->segsum + sizeof(SEGSUM));
- sp->fip->fi_nblocks = 0;
- sp->start_lbp = &sp->fip->fi_blocks[0];
- sp->fip->fi_lastlength = 0;
-
- sp->seg_bytes_left -= LFS_SUMMARY_SIZE;
- sp->sum_bytes_left = LFS_SUMMARY_SIZE - sizeof(SEGSUM);
-
- return(repeat);
-}
-
-/*
- * Return the next segment to write.
- */
-static void
-lfs_newseg(fs)
- struct lfs *fs;
-{
- CLEANERINFO *cip;
- SEGUSE *sup;
- struct buf *bp;
- int curseg, isdirty, sn;
-
- LFS_SEGENTRY(sup, fs, datosn(fs, fs->lfs_nextseg), bp);
- sup->su_flags |= SEGUSE_DIRTY | SEGUSE_ACTIVE;
- sup->su_nbytes = 0;
- sup->su_nsums = 0;
- sup->su_ninos = 0;
- (void) VOP_BWRITE(bp);
-
- LFS_CLEANERINFO(cip, fs, bp);
- --cip->clean;
- ++cip->dirty;
- (void) VOP_BWRITE(bp);
-
- fs->lfs_lastseg = fs->lfs_curseg;
- fs->lfs_curseg = fs->lfs_nextseg;
- for (sn = curseg = datosn(fs, fs->lfs_curseg);;) {
- sn = (sn + 1) % fs->lfs_nseg;
- if (sn == curseg)
- panic("lfs_nextseg: no clean segments");
- LFS_SEGENTRY(sup, fs, sn, bp);
- isdirty = sup->su_flags & SEGUSE_DIRTY;
- brelse(bp);
- if (!isdirty)
- break;
- }
-
- ++fs->lfs_nactive;
- fs->lfs_nextseg = sntoda(fs, sn);
-#ifdef DOSTATS
- ++lfs_stats.segsused;
-#endif
-}
-
-int
-lfs_writeseg(fs, sp)
- struct lfs *fs;
- struct segment *sp;
-{
- struct buf **bpp, *bp, *cbp;
- SEGUSE *sup;
- SEGSUM *ssp;
- dev_t i_dev;
- u_long *datap, *dp;
- int do_again, i, nblocks, s;
- u_short ninos;
- char *p;
-
- /*
- * If there are no buffers other than the segment summary to write
- * and it is not a checkpoint, don't do anything. On a checkpoint,
- * even if there aren't any buffers, you need to write the superblock.
- */
- if ((nblocks = sp->cbpp - sp->bpp) == 1)
- return (0);
-
- /* Update the segment usage information. */
- LFS_SEGENTRY(sup, fs, sp->seg_number, bp);
-
- /* Loop through all blocks, except the segment summary. */
- for (bpp = sp->bpp; ++bpp < sp->cbpp; )
- sup->su_nbytes += (*bpp)->b_bcount;
-
- ssp = (SEGSUM *)sp->segsum;
-
- ninos = (ssp->ss_ninos + INOPB(fs) - 1) / INOPB(fs);
- sup->su_nbytes += ssp->ss_ninos * sizeof(struct dinode);
- sup->su_nbytes += LFS_SUMMARY_SIZE;
- sup->su_lastmod = time.tv_sec;
- sup->su_ninos += ninos;
- ++sup->su_nsums;
- do_again = !(bp->b_flags & B_GATHERED);
- (void)VOP_BWRITE(bp);
- /*
- * Compute checksum across data and then across summary; the first
- * block (the summary block) is skipped. Set the create time here
- * so that it's guaranteed to be later than the inode mod times.
- *
- * XXX
- * Fix this to do it inline, instead of malloc/copy.
- */
- datap = dp = malloc(nblocks * sizeof(u_long), M_SEGMENT, M_WAITOK);
- for (bpp = sp->bpp, i = nblocks - 1; i--;) {
- if ((*++bpp)->b_flags & B_INVAL) {
- if (copyin((*bpp)->b_saveaddr, dp++, sizeof(u_long)))
- panic("lfs_writeseg: copyin failed");
- } else
- *dp++ = ((u_long *)(*bpp)->b_data)[0];
- }
- ssp->ss_create = time.tv_sec;
- ssp->ss_datasum = cksum(datap, (nblocks - 1) * sizeof(u_long));
- ssp->ss_sumsum =
- cksum(&ssp->ss_datasum, LFS_SUMMARY_SIZE - sizeof(ssp->ss_sumsum));
- free(datap, M_SEGMENT);
-#ifdef DIAGNOSTIC
- if (fs->lfs_bfree < fsbtodb(fs, ninos) + LFS_SUMMARY_SIZE / DEV_BSIZE)
- panic("lfs_writeseg: No diskspace for summary");
-#endif
- fs->lfs_bfree -= (fsbtodb(fs, ninos) + LFS_SUMMARY_SIZE / DEV_BSIZE);
-
- i_dev = VTOI(fs->lfs_ivnode)->i_dev;
-
- /*
- * When we simply write the blocks we lose a rotation for every block
- * written. To avoid this problem, we allocate memory in chunks, copy
- * the buffers into the chunk and write the chunk. DFLTPHYS is the
- * largest size I/O devices can handle.
- * When the data is copied to the chunk, turn off the the B_LOCKED bit
- * and brelse the buffer (which will move them to the LRU list). Add
- * the B_CALL flag to the buffer header so we can count I/O's for the
- * checkpoints and so we can release the allocated memory.
- *
- * XXX
- * This should be removed if the new virtual memory system allows us to
- * easily make the buffers contiguous in kernel memory and if that's
- * fast enough.
- */
- for (bpp = sp->bpp, i = nblocks; i;) {
- cbp = lfs_newbuf(VTOI(fs->lfs_ivnode)->i_devvp,
- (*bpp)->b_blkno, DFLTPHYS);
- cbp->b_dev = i_dev;
- cbp->b_flags |= B_ASYNC | B_BUSY;
- cbp->b_bcount = 0;
-
- s = splbio();
- ++fs->lfs_iocount;
- for (p = cbp->b_data; i && cbp->b_bcount < DFLTPHYS; i--) {
- bp = *bpp;
- if (bp->b_bcount > (DFLTPHYS - cbp->b_bcount))
- break;
- bpp++;
-
- /*
- * Fake buffers from the cleaner are marked as B_INVAL.
- * We need to copy the data from user space rather than
- * from the buffer indicated.
- * XXX == what do I do on an error?
- */
- if (bp->b_flags & B_INVAL) {
- if (copyin(bp->b_saveaddr, p, bp->b_bcount))
- panic("lfs_writeseg: copyin failed");
- } else
- bcopy(bp->b_data, p, bp->b_bcount);
- p += bp->b_bcount;
- cbp->b_bcount += bp->b_bcount;
- if (bp->b_flags & B_LOCKED)
- --locked_queue_count;
- if (bp->b_flags & (B_DELWRI|B_LOCKED)) {
- --numdirtybuffers;
- if (needsbuffer)
- vfs_bio_need_satisfy();
- }
- bp->b_flags &= ~(B_ERROR | B_READ | B_DELWRI |
- B_LOCKED | B_GATHERED);
- if (bp->b_flags & B_CALL) {
- /* if B_CALL, it was created with newbuf */
- if (!(bp->b_flags & B_INVAL))
- lfs_free_buffer( bp->b_data, roundup( bp->b_bufsize, DEV_BSIZE));
- relpbuf(bp);
- } else {
- bremfree(bp);
- bp->b_flags |= B_DONE;
- reassignbuf(bp, bp->b_vp);
- brelse(bp);
- }
- }
- ++cbp->b_vp->v_numoutput;
- splx(s);
- /*
- * XXXX This is a gross and disgusting hack. Since these
- * buffers are physically addressed, they hang off the
- * device vnode (devvp). As a result, they have no way
- * of getting to the LFS superblock or lfs structure to
- * keep track of the number of I/O's pending. So, I am
- * going to stuff the fs into the saveaddr field of
- * the buffer (yuk).
- */
- cbp->b_saveaddr = (caddr_t)fs;
- VOP_STRATEGY(cbp);
- }
- /*
- * XXX
- * Vinvalbuf can move locked buffers off the locked queue
- * and we have no way of knowing about this. So, after
- * doing a big write, we recalculate how many bufers are
- * really still left on the locked queue.
- */
- locked_queue_count = count_lock_queue();
- wakeup(&locked_queue_count);
-#ifdef DOSTATS
- ++lfs_stats.psegwrites;
- lfs_stats.blocktot += nblocks - 1;
- if (fs->lfs_sp->seg_flags & SEGM_SYNC)
- ++lfs_stats.psyncwrites;
- if (fs->lfs_sp->seg_flags & SEGM_CLEAN) {
- ++lfs_stats.pcleanwrites;
- lfs_stats.cleanblocks += nblocks - 1;
- }
-#endif
- return (lfs_initseg(fs) || do_again);
-}
-
-void
-lfs_writesuper(fs)
- struct lfs *fs;
-{
- struct buf *bp;
- dev_t i_dev;
- int s;
-
- i_dev = VTOI(fs->lfs_ivnode)->i_dev;
-
- /* Checksum the superblock and copy it into a buffer. */
- fs->lfs_cksum = cksum(fs, sizeof(struct lfs) - sizeof(fs->lfs_cksum));
- bp = lfs_newbuf(VTOI(fs->lfs_ivnode)->i_devvp, fs->lfs_sboffs[0],
- LFS_SBPAD);
- *(struct lfs *)bp->b_data = *fs;
-
- /* XXX Toggle between first two superblocks; for now just write first */
- bp->b_dev = i_dev;
- bp->b_flags |= B_BUSY | B_CALL | B_ASYNC;
- if (bp->b_flags & (B_DELWRI|B_LOCKED)) {
- --numdirtybuffers;
- if (needsbuffer)
- vfs_bio_need_satisfy();
- }
- bp->b_flags &= ~(B_DONE | B_ERROR | B_READ | B_DELWRI);
- bp->b_iodone = lfs_supercallback;
- s = splbio();
- ++bp->b_vp->v_numoutput;
- splx(s);
- VOP_STRATEGY(bp);
-}
-
-/*
- * Logical block number match routines used when traversing the dirty block
- * chain.
- */
-static int
-lfs_match_data(fs, bp)
- struct lfs *fs;
- struct buf *bp;
-{
- return (bp->b_lblkno >= 0);
-}
-
-static int
-lfs_match_indir(fs, bp)
- struct lfs *fs;
- struct buf *bp;
-{
- int lbn;
-
- lbn = bp->b_lblkno;
- return (lbn < 0 && (-lbn - NDADDR) % NINDIR(fs) == 0);
-}
-
-static int
-lfs_match_dindir(fs, bp)
- struct lfs *fs;
- struct buf *bp;
-{
- int lbn;
-
- lbn = bp->b_lblkno;
- return (lbn < 0 && (-lbn - NDADDR) % NINDIR(fs) == 1);
-}
-
-#ifdef TRIPLE
-static int
-lfs_match_tindir(fs, bp)
- struct lfs *fs;
- struct buf *bp;
-{
- int lbn;
-
- lbn = bp->b_lblkno;
- return (lbn < 0 && (-lbn - NDADDR) % NINDIR(fs) == 2);
-}
-#endif
-
-/*
- * Allocate a new buffer header.
- */
-struct buf *
-lfs_newbuf(vp, daddr, size)
- struct vnode *vp;
- ufs_daddr_t daddr;
- size_t size;
-{
- struct buf *bp;
- size_t nbytes;
-
- nbytes = roundup(size, DEV_BSIZE);
- bp = getpbuf();
- if (nbytes)
- bp->b_data = lfs_alloc_buffer( nbytes);
- bp->b_bufsize = size;
- bp->b_bcount = size;
- bp->b_lblkno = daddr;
- bp->b_blkno = daddr;
- bp->b_error = 0;
- bp->b_resid = 0;
- bp->b_iodone = lfs_callback;
- bp->b_flags |= B_BUSY | B_CALL | B_NOCACHE;
- return (bp);
-}
-
-static void
-lfs_callback(bp)
- struct buf *bp;
-{
- struct lfs *fs;
-
- fs = (struct lfs *)bp->b_saveaddr;
-#ifdef DIAGNOSTIC
- if (fs->lfs_iocount == 0)
- panic("lfs_callback: zero iocount");
-#endif
- if (--fs->lfs_iocount == 0)
- wakeup(&fs->lfs_iocount);
-
- lfs_free_buffer( bp->b_data, roundup( bp->b_bufsize, DEV_BSIZE));
- relpbuf(bp);
-
-}
-
-static void
-lfs_supercallback(bp)
- struct buf *bp;
-{
- if( bp->b_data)
- lfs_free_buffer( bp->b_data, roundup( bp->b_bufsize, DEV_BSIZE));
- relpbuf(bp);
-}
-
-/*
- * Shellsort (diminishing increment sort) from Data Structures and
- * Algorithms, Aho, Hopcraft and Ullman, 1983 Edition, page 290;
- * see also Knuth Vol. 3, page 84. The increments are selected from
- * formula (8), page 95. Roughly O(N^3/2).
- */
-/*
- * This is our own private copy of shellsort because we want to sort
- * two parallel arrays (the array of buffer pointers and the array of
- * logical block numbers) simultaneously. Note that we cast the array
- * of logical block numbers to a unsigned in this routine so that the
- * negative block numbers (meta data blocks) sort AFTER the data blocks.
- */
-static void
-lfs_shellsort(bp_array, lb_array, nmemb)
- struct buf **bp_array;
- ufs_daddr_t *lb_array;
- register int nmemb;
-{
- static int __rsshell_increments[] = { 4, 1, 0 };
- register int incr, *incrp, t1, t2;
- struct buf *bp_temp;
- u_long lb_temp;
-
- for (incrp = __rsshell_increments; incr = *incrp++;)
- for (t1 = incr; t1 < nmemb; ++t1)
- for (t2 = t1 - incr; t2 >= 0;)
- if (lb_array[t2] > lb_array[t2 + incr]) {
- lb_temp = lb_array[t2];
- lb_array[t2] = lb_array[t2 + incr];
- lb_array[t2 + incr] = lb_temp;
- bp_temp = bp_array[t2];
- bp_array[t2] = bp_array[t2 + incr];
- bp_array[t2 + incr] = bp_temp;
- t2 -= incr;
- } else
- break;
-}
-
-/*
- * Check VXLOCK. Return 1 if the vnode is locked. Otherwise, vget it.
- */
-int
-lfs_vref(vp)
- register struct vnode *vp;
-{
- struct proc *p = curproc; /* XXX */
-
- if ((vp->v_flag & VXLOCK) || /* XXX */
- (vp->v_usecount == 0 &&
- vp->v_flag & VDOOMED))
- return(1);
- return (vget(vp, 0, p));
-}
-
-/*
- * This is vrele except that we do not want to VOP_INACTIVE this vnode. We
- * inline vrele here to avoid the vn_lock and VOP_INACTIVE call at the end.
- *
- * XXX: this is positively disgusting and blatantly wrong, and may not
- * even work these days :-( /phk
- */
-void
-lfs_vunref(vp)
- register struct vnode *vp;
-{
- struct proc *p = curproc; /* XXX */
- extern struct simplelock vnode_free_list_slock; /* XXX */
- extern TAILQ_HEAD(freelst, vnode) vnode_free_list; /* XXX */
-
- simple_lock(&vp->v_interlock);
- vp->v_usecount--;
- if (vp->v_usecount > 0) {
- simple_unlock(&vp->v_interlock);
- return;
- }
- /*
- * insert at tail of LRU list
- */
- simple_lock(&vnode_free_list_slock);
- TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
- simple_unlock(&vnode_free_list_slock);
- simple_unlock(&vp->v_interlock);
-}
diff --git a/sys/ufs/lfs/lfs_subr.c b/sys/ufs/lfs/lfs_subr.c
deleted file mode 100644
index ad4fbcc12c3b..000000000000
--- a/sys/ufs/lfs/lfs_subr.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 1991, 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.
- *
- * 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.
- *
- * @(#)lfs_subr.c 8.4 (Berkeley) 5/8/95
- * $Id: lfs_subr.c,v 1.11 1997/08/02 14:33:21 bde Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/mount.h>
-#include <sys/malloc.h>
-#include <sys/proc.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/lfs/lfs.h>
-#include <ufs/lfs/lfs_extern.h>
-
-/*
- * 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
-lfs_blkatoff(vp, offset, res, bpp)
- struct vnode *vp;
- off_t offset;
- char **res;
- struct buf **bpp;
-{
- register struct lfs *fs;
- struct inode *ip;
- struct buf *bp;
- ufs_daddr_t lbn;
- int bsize, error;
-
- ip = VTOI(vp);
- fs = ip->i_lfs;
- lbn = lblkno(fs, offset);
- bsize = blksize(fs, ip, lbn);
-
- *bpp = NULL;
- if (error = bread(vp, lbn, bsize, NOCRED, &bp)) {
- brelse(bp);
- return (error);
- }
- if (res)
- *res = (char *)bp->b_data + blkoff(fs, offset);
- *bpp = bp;
- return (0);
-}
-
-
-/*
- * lfs_seglock --
- * Single thread the segment writer.
- */
-void
-lfs_seglock(fs, flags)
- struct lfs *fs;
- unsigned long flags;
-{
- struct segment *sp;
- int s;
-
- if (fs->lfs_seglock)
- if (fs->lfs_lockpid == curproc->p_pid) {
- ++fs->lfs_seglock;
- fs->lfs_sp->seg_flags |= flags;
- return;
- } else while (fs->lfs_seglock)
- (void)tsleep(&fs->lfs_seglock, PRIBIO + 1,
- "lfs seglock", 0);
-
- /* XXX RACE CONDITION????? */
- fs->lfs_seglock = 1;
- fs->lfs_lockpid = curproc->p_pid;
-
- sp = fs->lfs_sp = malloc(sizeof(struct segment), M_SEGMENT, M_WAITOK);
- sp->bpp = malloc(((LFS_SUMMARY_SIZE - sizeof(SEGSUM)) /
- sizeof(ufs_daddr_t) + 1) * sizeof(struct buf *),
- M_SEGMENT, M_WAITOK);
- sp->seg_flags = flags;
- sp->vp = NULL;
- (void) lfs_initseg(fs);
-
- /*
- * Keep a cumulative count of the outstanding I/O operations. If the
- * disk drive catches up with us it could go to zero before we finish,
- * so we artificially increment it by one until we've scheduled all of
- * the writes we intend to do.
- */
- s = splbio();
- ++fs->lfs_iocount;
- splx(s);
-}
-/*
- * lfs_segunlock --
- * Single thread the segment writer.
- */
-void
-lfs_segunlock(fs)
- struct lfs *fs;
-{
- struct segment *sp;
- unsigned long sync, ckp;
- int s;
-
- if (fs->lfs_seglock == 1) {
-
- sp = fs->lfs_sp;
- sync = sp->seg_flags & SEGM_SYNC;
- ckp = sp->seg_flags & SEGM_CKP;
- if (sp->bpp != sp->cbpp) {
- /* Free allocated segment summary */
- fs->lfs_offset -= LFS_SUMMARY_SIZE / DEV_BSIZE;
- lfs_free_buffer((*sp->bpp)->b_data, roundup((*sp->bpp)->b_bufsize, DEV_BSIZE));
- relpbuf(*sp->bpp);
- } else
- printf ("unlock to 0 with no summary");
- free(sp->bpp, M_SEGMENT);
- free(sp, M_SEGMENT);
-
- /*
- * If the I/O count is non-zero, sleep until it reaches zero.
- * At the moment, the user's process hangs around so we can
- * sleep.
- */
- s = splbio();
- --fs->lfs_iocount;
- /*
- * We let checkpoints happen asynchronously. That means
- * that during recovery, we have to roll forward between
- * the two segments described by the first and second
- * superblocks to make sure that the checkpoint described
- * by a superblock completed.
- */
- if (sync && fs->lfs_iocount)
- (void)tsleep(&fs->lfs_iocount, PRIBIO + 1, "lfs vflush", 0);
- splx(s);
- if (ckp) {
- fs->lfs_nactive = 0;
- lfs_writesuper(fs);
- }
- --fs->lfs_seglock;
- fs->lfs_lockpid = 0;
- wakeup(&fs->lfs_seglock);
- } else if (fs->lfs_seglock == 0) {
- panic ("Seglock not held");
- } else {
- --fs->lfs_seglock;
- }
-}
diff --git a/sys/ufs/lfs/lfs_syscalls.c b/sys/ufs/lfs/lfs_syscalls.c
deleted file mode 100644
index f575f34fa7c9..000000000000
--- a/sys/ufs/lfs/lfs_syscalls.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * 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.
- *
- * 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.
- *
- * @(#)lfs_syscalls.c 8.10 (Berkeley) 5/14/95
- * $Id: lfs_syscalls.c,v 1.20 1997/11/06 19:29:51 phk Exp $
- */
-
-#include "opt_lfs.h" /* XXX: Indicate bogus header dependency */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sysproto.h>
-#include <sys/proc.h>
-#include <sys/buf.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ufs/ufs_extern.h>
-
-#include <ufs/lfs/lfs.h>
-#include <ufs/lfs/lfs_extern.h>
-#define BUMP_FIP(SP) \
- (SP)->fip = (FINFO *) (&(SP)->fip->fi_blocks[(SP)->fip->fi_nblocks])
-
-#define INC_FINFO(SP) ++((SEGSUM *)((SP)->segsum))->ss_nfinfo
-#define DEC_FINFO(SP) --((SEGSUM *)((SP)->segsum))->ss_nfinfo
-
-/*
- * Before committing to add something to a segment summary, make sure there
- * is enough room. S is the bytes added to the summary.
- */
-#define CHECK_SEG(s) \
-if (sp->sum_bytes_left < (s)) { \
- (void) lfs_writeseg(fs, sp); \
-}
-static struct buf *lfs_fakebuf __P((struct vnode *, int, size_t, caddr_t));
-static int lfs_fastvget __P((struct mount *, ino_t, daddr_t, struct vnode **,
- struct dinode *));
-
-int debug_cleaner = 0;
-int clean_vnlocked = 0;
-int clean_inlocked = 0;
-
-/*
- * lfs_markv:
- *
- * This will mark inodes and blocks dirty, so they are written into the log.
- * It will block until all the blocks have been written. The segment create
- * time passed in the block_info and inode_info structures is used to decide
- * if the data is valid for each block (in case some process dirtied a block
- * or inode that is being cleaned between the determination that a block is
- * live and the lfs_markv call).
- *
- * 0 on success
- * -1/errno is return on error.
- */
-#ifndef _SYS_SYSPROTO_H_
-struct lfs_markv_args {
- fsid_t *fsidp; /* file system */
- BLOCK_INFO *blkiov; /* block array */
- int blkcnt; /* count of block array entries */
-};
-#endif
-int
-lfs_markv(p, uap)
- struct proc *p;
- struct lfs_markv_args *uap;
-{
- struct segment *sp;
- BLOCK_INFO *blkp;
- IFILE *ifp;
- struct buf *bp, **bpp;
- struct inode *ip = 0;
- struct lfs *fs;
- struct mount *mntp;
- struct vnode *vp;
- fsid_t fsid;
- void *start;
- ino_t lastino;
- ufs_daddr_t b_daddr, v_daddr;
- u_long bsize;
- int cnt, error;
-
- if (error = suser(p->p_ucred, &p->p_acflag))
- return (error);
-
- if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
- return (error);
- if ((mntp = vfs_getvfs(&fsid)) == NULL)
- return (EINVAL);
-
- cnt = uap->blkcnt;
- start = malloc(cnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
- if (error = copyin(uap->blkiov, start, cnt * sizeof(BLOCK_INFO)))
- goto err1;
-
- /* Mark blocks/inodes dirty. */
- fs = VFSTOUFS(mntp)->um_lfs;
- bsize = fs->lfs_bsize;
- error = 0;
-
- lfs_seglock(fs, SEGM_SYNC | SEGM_CLEAN);
- sp = fs->lfs_sp;
- for (v_daddr = LFS_UNUSED_DADDR, lastino = LFS_UNUSED_INUM,
- blkp = start; cnt--; ++blkp) {
- /*
- * Get the IFILE entry (only once) and see if the file still
- * exists.
- */
- if (lastino != blkp->bi_inode) {
- if (lastino != LFS_UNUSED_INUM) {
- /* Finish up last file */
- if (sp->fip->fi_nblocks == 0) {
- DEC_FINFO(sp);
- sp->sum_bytes_left +=
- sizeof(FINFO) - sizeof(ufs_daddr_t);
- } else {
- lfs_updatemeta(sp);
- BUMP_FIP(sp);
- }
-
- lfs_writeinode(fs, sp, ip);
- lfs_vunref(vp);
- }
-
- /* Start a new file */
- CHECK_SEG(sizeof(FINFO));
- sp->sum_bytes_left -= sizeof(FINFO) - sizeof(ufs_daddr_t);
- INC_FINFO(sp);
- sp->start_lbp = &sp->fip->fi_blocks[0];
- sp->vp = NULL;
- sp->fip->fi_version = blkp->bi_version;
- sp->fip->fi_nblocks = 0;
- sp->fip->fi_ino = blkp->bi_inode;
- lastino = blkp->bi_inode;
- if (blkp->bi_inode == LFS_IFILE_INUM)
- v_daddr = fs->lfs_idaddr;
- else {
- LFS_IENTRY(ifp, fs, blkp->bi_inode, bp);
- v_daddr = ifp->if_daddr;
- brelse(bp);
- }
- if (v_daddr == LFS_UNUSED_DADDR)
- continue;
-
- /* Get the vnode/inode. */
- if (lfs_fastvget(mntp, blkp->bi_inode, v_daddr, &vp,
- blkp->bi_lbn == LFS_UNUSED_LBN ?
- blkp->bi_bp : NULL)) {
-#ifdef DIAGNOSTIC
- printf("lfs_markv: VFS_VGET failed (%ld)\n",
- blkp->bi_inode);
- panic("lfs_markv VFS_VGET FAILED");
-#endif
- lastino = LFS_UNUSED_INUM;
- v_daddr = LFS_UNUSED_DADDR;
- continue;
- }
- sp->vp = vp;
- ip = VTOI(vp);
- } else if (v_daddr == LFS_UNUSED_DADDR)
- continue;
-
- /* If this BLOCK_INFO didn't contain a block, keep going. */
- if (blkp->bi_lbn == LFS_UNUSED_LBN)
- continue;
- if (VOP_BMAP(vp, blkp->bi_lbn, NULL, &b_daddr, NULL, NULL) ||
- b_daddr != blkp->bi_daddr)
- continue;
- /*
- * If we got to here, then we are keeping the block. If it
- * is an indirect block, we want to actually put it in the
- * buffer cache so that it can be updated in the finish_meta
- * section. If it's not, we need to allocate a fake buffer
- * so that writeseg can perform the copyin and write the buffer.
- */
- if (blkp->bi_lbn >= 0) /* Data Block */
- bp = lfs_fakebuf(vp, blkp->bi_lbn, bsize,
- blkp->bi_bp);
- else {
- bp = getblk(vp, blkp->bi_lbn, bsize, 0, 0);
- if (!(bp->b_flags & (B_DELWRI | B_DONE | B_CACHE)) &&
- (error = copyin(blkp->bi_bp, bp->b_data,
- blkp->bi_size)))
- goto err2;
- if (error = VOP_BWRITE(bp))
- goto err2;
- }
- while (lfs_gatherblock(sp, bp, NULL));
- }
- if (sp->vp) {
- if (sp->fip->fi_nblocks == 0) {
- DEC_FINFO(sp);
- sp->sum_bytes_left +=
- sizeof(FINFO) - sizeof(ufs_daddr_t);
- } else
- lfs_updatemeta(sp);
-
- lfs_writeinode(fs, sp, ip);
- lfs_vunref(vp);
- }
- (void) lfs_writeseg(fs, sp);
- lfs_segunlock(fs);
- free(start, M_SEGMENT);
- return (error);
-
-/*
- * XXX
- * If we come in to error 2, we might have indirect blocks that were
- * updated and now have bad block pointers. I don't know what to do
- * about this.
- */
-
-err2: lfs_vunref(vp);
- /* Free up fakebuffers */
- for (bpp = --sp->cbpp; bpp >= sp->bpp; --bpp)
- if ((*bpp)->b_flags & B_CALL) {
- relpbuf(*bpp);
- } else
- brelse(*bpp);
- lfs_segunlock(fs);
-err1:
- free(start, M_SEGMENT);
- return (error);
-}
-
-/*
- * lfs_bmapv:
- *
- * This will fill in the current disk address for arrays of blocks.
- *
- * 0 on success
- * -1/errno is return on error.
- */
-#ifndef _SYS_SYSPROTO_H_
-struct lfs_bmapv_args {
- fsid_t *fsidp; /* file system */
- BLOCK_INFO *blkiov; /* block array */
- int blkcnt; /* count of block array entries */
-};
-#endif
-int
-lfs_bmapv(p, uap)
- struct proc *p;
- struct lfs_bmapv_args *uap;
-{
- BLOCK_INFO *blkp;
- struct mount *mntp;
- struct ufsmount *ump;
- struct vnode *vp;
- fsid_t fsid;
- void *start;
- ufs_daddr_t daddr;
- int cnt, error, step;
-
- if (error = suser(p->p_ucred, &p->p_acflag))
- return (error);
-
- if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
- return (error);
- if ((mntp = vfs_getvfs(&fsid)) == NULL)
- return (EINVAL);
-
- cnt = uap->blkcnt;
- start = blkp = malloc(cnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
- if (error = copyin(uap->blkiov, blkp, cnt * sizeof(BLOCK_INFO))) {
- free(blkp, M_SEGMENT);
- return (error);
- }
-
- for (step = cnt; step--; ++blkp) {
- if (blkp->bi_lbn == LFS_UNUSED_LBN)
- continue;
- /*
- * A regular call to VFS_VGET could deadlock
- * here. Instead, we try an unlocked access.
- */
- ump = VFSTOUFS(mntp);
- if ((vp =
- ufs_ihashlookup(ump->um_dev, blkp->bi_inode)) != NULL) {
- if (VOP_BMAP(vp, blkp->bi_lbn, NULL, &daddr, NULL, NULL))
- daddr = LFS_UNUSED_DADDR;
- } else if (VFS_VGET(mntp, blkp->bi_inode, &vp))
- daddr = LFS_UNUSED_DADDR;
- else {
- if (VOP_BMAP(vp, blkp->bi_lbn, NULL, &daddr, NULL, NULL))
- daddr = LFS_UNUSED_DADDR;
- vput(vp);
- }
- blkp->bi_daddr = daddr;
- }
- copyout(start, uap->blkiov, cnt * sizeof(BLOCK_INFO));
- free(start, M_SEGMENT);
- return (0);
-}
-
-/*
- * lfs_segclean:
- *
- * Mark the segment clean.
- *
- * 0 on success
- * -1/errno is return on error.
- */
-#ifndef _SYS_SYSPROTO_H_
-struct lfs_segclean_args {
- fsid_t *fsidp; /* file system */
- u_long segment; /* segment number */
-};
-#endif
-int
-lfs_segclean(p, uap)
- struct proc *p;
- struct lfs_segclean_args *uap;
-{
- CLEANERINFO *cip;
- SEGUSE *sup;
- struct buf *bp;
- struct mount *mntp;
- struct lfs *fs;
- fsid_t fsid;
- int error;
-
- if (error = suser(p->p_ucred, &p->p_acflag))
- return (error);
-
- if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
- return (error);
- if ((mntp = vfs_getvfs(&fsid)) == NULL)
- return (EINVAL);
-
- fs = VFSTOUFS(mntp)->um_lfs;
-
- if (datosn(fs, fs->lfs_curseg) == uap->segment)
- return (EBUSY);
-
- LFS_SEGENTRY(sup, fs, uap->segment, bp);
- if (sup->su_flags & SEGUSE_ACTIVE) {
- brelse(bp);
- return (EBUSY);
- }
- fs->lfs_avail += fsbtodb(fs, fs->lfs_ssize) - 1;
- fs->lfs_bfree += (sup->su_nsums * LFS_SUMMARY_SIZE / DEV_BSIZE) +
- sup->su_ninos * btodb(fs->lfs_bsize);
- sup->su_flags &= ~SEGUSE_DIRTY;
- (void) VOP_BWRITE(bp);
-
- LFS_CLEANERINFO(cip, fs, bp);
- ++cip->clean;
- --cip->dirty;
- (void) VOP_BWRITE(bp);
- wakeup(&fs->lfs_avail);
- return (0);
-}
-
-/*
- * lfs_segwait:
- *
- * This will block until a segment in file system fsid is written. A timeout
- * in milliseconds may be specified which will awake the cleaner automatically.
- * An fsid of -1 means any file system, and a timeout of 0 means forever.
- *
- * 0 on success
- * 1 on timeout
- * -1/errno is return on error.
- */
-#ifndef _SYS_SYSPROTO_H_
-struct lfs_segwait_args {
- fsid_t *fsidp; /* file system */
- struct timeval *tv; /* timeout */
-};
-#endif
-int
-lfs_segwait(p, uap)
- struct proc *p;
- struct lfs_segwait_args *uap;
-{
- struct mount *mntp;
- struct timeval atv;
- fsid_t fsid;
- void *addr;
- u_long timeout;
- int error, s;
-
- if (error = suser(p->p_ucred, &p->p_acflag)) {
- return (error);
-}
-#ifdef WHEN_QUADS_WORK
- if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
- return (error);
- if (fsid == (fsid_t)-1)
- addr = &lfs_allclean_wakeup;
- else {
- if ((mntp = vfs_getvfs(&fsid)) == NULL)
- return (EINVAL);
- addr = &VFSTOUFS(mntp)->um_lfs->lfs_nextseg;
- }
-#else
- if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
- return (error);
- if ((mntp = vfs_getvfs(&fsid)) == NULL)
- addr = &lfs_allclean_wakeup;
- else
- addr = &VFSTOUFS(mntp)->um_lfs->lfs_nextseg;
-#endif
-
- if (uap->tv) {
- if (error = copyin(uap->tv, &atv, sizeof(struct timeval)))
- return (error);
- if (itimerfix(&atv))
- return (EINVAL);
- s = splclock();
- timevaladd(&atv, &time);
- timeout = hzto(&atv);
- splx(s);
- } else
- timeout = 0;
-
- error = tsleep(addr, PCATCH | PUSER, "segment", timeout);
- return (error == ERESTART ? EINTR : 0);
-}
-
-/*
- * VFS_VGET call specialized for the cleaner. The cleaner already knows the
- * daddr from the ifile, so don't look it up again. If the cleaner is
- * processing IINFO structures, it may have the ondisk inode already, so
- * don't go retrieving it again.
- */
-static int
-lfs_fastvget(mp, ino, daddr, vpp, dinp)
- struct mount *mp;
- ino_t ino;
- ufs_daddr_t daddr;
- struct vnode **vpp;
- struct dinode *dinp;
-{
- register struct inode *ip;
- struct vnode *vp;
- struct ufsmount *ump;
- struct buf *bp;
- dev_t dev;
- int error;
-
- ump = VFSTOUFS(mp);
- dev = ump->um_dev;
- /*
- * This is playing fast and loose. Someone may have the inode
- * locked, in which case they are going to be distinctly unhappy
- * if we trash something.
- */
- if ((*vpp = ufs_ihashlookup(dev, ino)) != NULL) {
- lfs_vref(*vpp);
- if ((*vpp)->v_flag & VXLOCK)
- clean_vnlocked++;
- ip = VTOI(*vpp);
- if (lockstatus(&ip->i_lock))
- clean_inlocked++;
- if (!(ip->i_flag & IN_MODIFIED))
- ++ump->um_lfs->lfs_uinodes;
- ip->i_flag |= IN_MODIFIED;
- return (0);
- }
-
- /* Allocate new vnode/inode. */
- if (error = lfs_vcreate(mp, ino, &vp)) {
- *vpp = NULL;
- return (error);
- }
-
- /*
- * Put it onto its hash chain and lock it so that other requests for
- * this inode will block if they arrive while we are sleeping waiting
- * for old data structures to be purged or for the contents of the
- * disk portion of this inode to be read.
- */
- ip = VTOI(vp);
- ufs_ihashins(ip);
-
- /*
- * XXX
- * This may not need to be here, logically it should go down with
- * the i_devvp initialization.
- * Ask Kirk.
- */
- ip->i_lfs = ump->um_lfs;
-
- /* Read in the disk contents for the inode, copy into the inode. */
- if (dinp)
- if (error = copyin(dinp, &ip->i_din, sizeof(struct dinode)))
- return (error);
- else {
- if (error = bread(ump->um_devvp, daddr,
- (int)ump->um_lfs->lfs_bsize, NOCRED, &bp)) {
- /*
- * The inode does not contain anything useful, so it
- * would be misleading to leave it on its hash chain.
- * Iput() will return it to the free list.
- */
- ufs_ihashrem(ip);
-
- /* Unlock and discard unneeded inode. */
- lfs_vunref(vp);
- brelse(bp);
- *vpp = NULL;
- return (error);
- }
- ip->i_din =
- *lfs_ifind(ump->um_lfs, ino, (struct dinode *)bp->b_data);
- brelse(bp);
- }
-
- /*
- * Initialize the vnode from the inode, check for aliases. In all
- * cases re-init ip, the underlying vnode/inode may have changed.
- */
- if (error = ufs_vinit(mp, lfs_specop_p, LFS_FIFOOPS, &vp)) {
- lfs_vunref(vp);
- *vpp = NULL;
- return (error);
- }
- /*
- * Finish inode initialization now that aliasing has been resolved.
- */
- ip->i_devvp = ump->um_devvp;
- ip->i_flag |= IN_MODIFIED;
- ++ump->um_lfs->lfs_uinodes;
- VREF(ip->i_devvp);
- *vpp = vp;
- return (0);
-}
-static struct buf *
-lfs_fakebuf(vp, lbn, size, uaddr)
- struct vnode *vp;
- int lbn;
- size_t size;
- caddr_t uaddr;
-{
- struct buf *bp;
-
- bp = lfs_newbuf(vp, lbn, 0);
- bp->b_saveaddr = uaddr;
- bp->b_bufsize = size;
- bp->b_bcount = size;
- bp->b_flags |= B_INVAL;
- return (bp);
-}
-
-
diff --git a/sys/ufs/lfs/lfs_vfsops.c b/sys/ufs/lfs/lfs_vfsops.c
deleted file mode 100644
index 4fc5c0ff3be7..000000000000
--- a/sys/ufs/lfs/lfs_vfsops.c
+++ /dev/null
@@ -1,737 +0,0 @@
-/*
- * Copyright (c) 1989, 1991, 1993, 1994
- * 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.
- *
- * 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.
- *
- * @(#)lfs_vfsops.c 8.20 (Berkeley) 6/10/95
- * $Id: lfs_vfsops.c,v 1.26 1997/10/16 20:32:37 phk Exp $
- */
-
-#include "opt_quota.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/proc.h>
-#include <sys/kernel.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/buf.h>
-#include <sys/fcntl.h>
-#include <sys/disklabel.h>
-
-#include <miscfs/specfs/specdev.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ufs/ufs_extern.h>
-
-#include <ufs/lfs/lfs.h>
-#include <ufs/lfs/lfs_extern.h>
-
-MALLOC_DEFINE(M_LFSNODE, "LFS node", "LFS vnode private part");
-MALLOC_DEFINE(M_SEGMENT, "LFS segment", "Segment for LFS");
-
-static int lfs_fhtovp __P((struct mount *, struct fid *, struct sockaddr *,
- struct vnode **, int *, struct ucred **));
-static int lfs_mount __P((struct mount *, char *, caddr_t,
- struct nameidata *, struct proc *));
-static int lfs_mountfs __P((struct vnode *, struct mount *, struct proc *));
-static int lfs_statfs __P((struct mount *, struct statfs *, struct proc *));
-static int lfs_sync __P((struct mount *, int, struct ucred *, struct proc *));
-static int lfs_unmount __P((struct mount *, int, struct proc *));
-static int lfs_vget __P((struct mount *, ino_t, struct vnode **));
-static int lfs_vptofh __P((struct vnode *, struct fid *));
-
-struct vfsops lfs_vfsops = {
- lfs_mount,
- ufs_start,
- lfs_unmount,
- ufs_root,
- ufs_quotactl,
- lfs_statfs,
- lfs_sync,
- lfs_vget,
- lfs_fhtovp,
- lfs_vptofh,
- lfs_init,
-#ifdef notyet
- lfs_sysctl,
-#endif
-};
-
-VFS_SET(lfs_vfsops, lfs, MOUNT_LFS, 0);
-
-/*
- * Called by main() when ufs is going to be mounted as root.
- */
-int
-lfs_mountroot()
-{
- struct fs *fs;
- struct mount *mp;
- struct proc *p = curproc; /* XXX */
- int error;
-
- if ((error = bdevvp(rootdev, &rootvp))) {
- printf("lfs_mountroot: can't find rootvp");
- return (error);
- }
- if (error = vfs_rootmountalloc("lfs", "root_device", &mp))
- return (error);
- if (error = lfs_mountfs(rootvp, mp, p)) {
- mp->mnt_vfc->vfc_refcount--;
- vfs_unbusy(mp, p);
- free(mp, M_MOUNT);
- return (error);
- }
- simple_lock(&mountlist_slock);
- CIRCLEQ_INSERT_HEAD(&mountlist, mp, mnt_list);
- simple_unlock(&mountlist_slock);
- (void)lfs_statfs(mp, &mp->mnt_stat, p);
- vfs_unbusy(mp, p);
- return (0);
-}
-
-/*
- * lfs_mount
- *
- * Called when mounting local physical media
- *
- * PARAMETERS:
- * mountroot
- * mp mount point structure
- * path NULL (flag for root mount!!!)
- * data <unused>
- * ndp <unused>
- * p process (user credentials check [statfs])
- *
- * mount
- * mp mount point structure
- * path path to mount point
- * data pointer to argument struct in user space
- * ndp mount point namei() return (used for
- * credentials on reload), reused to look
- * up block device.
- * p process (user credentials check)
- *
- * RETURNS: 0 Success
- * !0 error number (errno.h)
- *
- * LOCK STATE:
- *
- * ENTRY
- * mount point is locked
- * EXIT
- * mount point is locked
- *
- * NOTES:
- * A NULL path can be used for a flag since the mount
- * system call will fail with EFAULT in copyinstr in
- * namei() if it is a genuine NULL from the user.
- *
- * Root mounts are not currently supported.
- */
-static int
-lfs_mount(mp, path, data, ndp, p)
- register struct mount *mp;
- char *path;
- caddr_t data;
- struct nameidata *ndp;
- struct proc *p;
-{
- struct vnode *devvp;
- struct ufs_args args;
- struct ufsmount *ump = 0;
- register struct lfs *fs; /* LFS */
- u_int size;
- int err;
- mode_t accessmode;
-
- /*
- * Use NULL path to flag a root mount
- */
- if( path == NULL) {
- /*
- ***
- * Mounting root file system
- ***
- */
-
- /* XXX -- implement*/
- panic("lfs_mount: NULL path not implemented");
- }
-
- /*
- ***
- * Mounting non-root file system or updating a file system
- ***
- */
-
- /* copy in user arguments*/
- if (err = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
- goto error_1;
-
- /* Until LFS can do NFS right. XXX */
- if (args.export.ex_flags & MNT_EXPORTED) {
- err = EINVAL;
- goto error_1;
- }
-
- /*
- * If updating, check whether changing from read-only to
- * read/write; if there is no device name, that's all we do.
- */
- if (mp->mnt_flag & MNT_UPDATE) {
- ump = VFSTOUFS(mp);
- if (fs->lfs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
- /*
- * If upgrade to read-write by non-root, then verify
- * that user has necessary permissions on the device.
- */
- if (p->p_ucred->cr_uid != 0) {
- vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY,
- p);
- if (err = VOP_ACCESS(ump->um_devvp,
- VREAD | VWRITE, p->p_ucred, p)) {
- VOP_UNLOCK(ump->um_devvp, 0, p);
- return (err);
- }
- VOP_UNLOCK(ump->um_devvp, 0, p);
- }
- fs->lfs_ronly = 0;
- }
- if (args.fspec == 0) {
- /*
- * Process export requests. Jumping to "success"
- * will return the vfs_export() error code.
- */
- err = vfs_export(mp, &ump->um_export, &args.export);
- goto success;
- }
- }
- /*
- * Not an update, or updating the name: look up the name
- * and verify that it refers to a sensible block device.
- */
- NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
- if (err = namei(ndp))
- goto error_1;
- devvp = ndp->ni_vp;
- if (devvp->v_type != VBLK) {
- err = ENOTBLK;
- goto error_2;
- }
- if (major(devvp->v_rdev) >= nblkdev) {
- err = ENXIO;
- goto error_2;
- }
- /*
- * If mount by non-root, then verify that user has necessary
- * permissions on the device.
- */
- if (p->p_ucred->cr_uid != 0) {
- accessmode = VREAD;
- if ((mp->mnt_flag & MNT_RDONLY) == 0)
- accessmode |= VWRITE;
- vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
- if (err = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) {
- vput(devvp);
- return (err);
- }
- VOP_UNLOCK(devvp, 0, p);
- }
- if ((mp->mnt_flag & MNT_UPDATE) == 0)
- err = lfs_mountfs(devvp, mp, p); /* LFS */
- else {
- if (devvp != ump->um_devvp)
- err = EINVAL; /* needs translation */
- else
- vrele(devvp);
- }
- if (err) {
- goto error_2;
- }
- ump = VFSTOUFS(mp);
- fs = ump->um_lfs; /* LFS */
-#ifdef NOTLFS /* LFS */
- (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
- bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
- bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
- MNAMELEN);
- (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
- &size);
- bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
- (void) ufs_statfs(mp, &mp->mnt_stat, p);
-#else
- (void)copyinstr(path, fs->lfs_fsmnt, sizeof(fs->lfs_fsmnt) - 1, &size);
- bzero(fs->lfs_fsmnt + size, sizeof(fs->lfs_fsmnt) - size);
- bcopy((caddr_t)fs->lfs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
- MNAMELEN);
- (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
- &size);
- bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
- (void) lfs_statfs(mp, &mp->mnt_stat, p);
-#endif
-
-
-
-error_2: /* error with devvp held*/
-
- /* release devvp before failing*/
- vrele(devvp);
-
-error_1: /* no state to back out*/
-
-success:
- return( err);
-}
-
-/*
- * Common code for mount and mountroot
- * LFS specific
- */
-static int
-lfs_mountfs(devvp, mp, p)
- register struct vnode *devvp;
- struct mount *mp;
- struct proc *p;
-{
- register struct lfs *fs;
- register struct ufsmount *ump;
- struct vnode *vp;
- struct buf *bp;
- struct partinfo dpart;
- dev_t dev;
- int error, i, ronly, size;
- struct ucred *cred;
-
- cred = p ? p->p_ucred : NOCRED;
- /*
- * Disallow multiple mounts of the same device.
- * Disallow mounting of a device that is currently in use
- * (except for root, which might share swap device for miniroot).
- * Flush out any old buffers remaining from a previous use.
- */
- if (error = vfs_mountedon(devvp))
- return (error);
- if (vcount(devvp) > 1 && devvp != rootvp)
- return (EBUSY);
- if (error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0))
- return (error);
-
- ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
- if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p))
- return (error);
-
- if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
- size = DEV_BSIZE;
- else {
- size = dpart.disklab->d_secsize;
-#ifdef NEVER_USED
- dpart.part->p_fstype = FS_LFS;
- dpart.part->p_fsize = fs->lfs_fsize; /* frag size */
- dpart.part->p_frag = fs->lfs_frag; /* frags per block */
- dpart.part->p_cpg = fs->lfs_segshift; /* segment shift */
-#endif
- }
-
- /* Don't free random space on error. */
- bp = NULL;
- ump = NULL;
-
- /* Read in the superblock. */
- if (error = bread(devvp, LFS_LABELPAD / size, LFS_SBPAD, cred, &bp))
- goto out;
- fs = (struct lfs *)bp->b_data;
-
- /* Check the basics. */
- if (fs->lfs_magic != LFS_MAGIC || fs->lfs_bsize > MAXBSIZE ||
- fs->lfs_bsize < sizeof(struct lfs)) {
- error = EINVAL; /* XXX needs translation */
- goto out;
- }
-
- /* Allocate the mount structure, copy the superblock into it. */
- ump = (struct ufsmount *)malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
- bzero(ump, sizeof *ump);
- ump->um_malloctype = M_LFSNODE;
- ump->um_blkatoff = lfs_blkatoff;
- ump->um_truncate = lfs_truncate;
- ump->um_update = lfs_update;
- ump->um_valloc = lfs_valloc;
- ump->um_vfree = lfs_vfree;
- fs = ump->um_lfs = malloc(sizeof(struct lfs), M_UFSMNT, M_WAITOK);
- bcopy(bp->b_data, fs, sizeof(struct lfs));
- if (sizeof(struct lfs) < LFS_SBPAD) /* XXX why? */
- bp->b_flags |= B_INVAL;
- brelse(bp);
- bp = NULL;
-
- /* Set up the I/O information */
- fs->lfs_iocount = 0;
-
- /* Set up the ifile and lock aflags */
- fs->lfs_doifile = 0;
- fs->lfs_writer = 0;
- fs->lfs_dirops = 0;
- fs->lfs_seglock = 0;
-
- /* Set the file system readonly/modify bits. */
- fs->lfs_ronly = ronly;
- if (ronly == 0)
- fs->lfs_fmod = 1;
-
- /* Initialize the mount structure. */
- dev = devvp->v_rdev;
- mp->mnt_data = (qaddr_t)ump;
- mp->mnt_stat.f_fsid.val[0] = (long)dev;
- mp->mnt_stat.f_fsid.val[1] = lfs_mount_type;
- mp->mnt_maxsymlinklen = fs->lfs_maxsymlinklen;
- mp->mnt_flag |= MNT_LOCAL;
- ump->um_mountp = mp;
- ump->um_dev = dev;
- ump->um_devvp = devvp;
- ump->um_bptrtodb = 0;
- ump->um_seqinc = 1 << fs->lfs_fsbtodb;
- ump->um_nindir = fs->lfs_nindir;
- for (i = 0; i < MAXQUOTAS; i++)
- ump->um_quotas[i] = NULLVP;
- devvp->v_specflags |= SI_MOUNTEDON;
-
- /*
- * We use the ifile vnode for almost every operation. Instead of
- * retrieving it from the hash table each time we retrieve it here,
- * artificially increment the reference count and keep a pointer
- * to it in the incore copy of the superblock.
- */
- if (error = VFS_VGET(mp, LFS_IFILE_INUM, &vp))
- goto out;
- fs->lfs_ivnode = vp;
- VREF(vp);
- vput(vp);
-
- return (0);
-out:
- if (bp)
- brelse(bp);
- (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
- if (ump) {
- free(ump->um_lfs, M_UFSMNT);
- free(ump, M_UFSMNT);
- mp->mnt_data = (qaddr_t)0;
- }
- return (error);
-}
-
-/*
- * unmount system call
- */
-static int
-lfs_unmount(mp, mntflags, p)
- struct mount *mp;
- int mntflags;
- struct proc *p;
-{
- register struct ufsmount *ump;
- register struct lfs *fs;
- int i, error, flags, ronly;
-
- flags = 0;
- if (mntflags & MNT_FORCE)
- flags |= FORCECLOSE;
-
- ump = VFSTOUFS(mp);
- fs = ump->um_lfs;
-#ifdef QUOTA
- if (mp->mnt_flag & MNT_QUOTA) {
- if (error = vflush(mp, fs->lfs_ivnode, SKIPSYSTEM|flags))
- return (error);
- for (i = 0; i < MAXQUOTAS; i++) {
- if (ump->um_quotas[i] == NULLVP)
- continue;
- quotaoff(p, mp, i);
- }
- /*
- * Here we fall through to vflush again to ensure
- * that we have gotten rid of all the system vnodes.
- */
- }
-#endif
- if (error = vflush(mp, fs->lfs_ivnode, flags))
- return (error);
- fs->lfs_clean = 1;
- if (error = VFS_SYNC(mp, 1, p->p_ucred, p))
- return (error);
- if (fs->lfs_ivnode->v_dirtyblkhd.lh_first)
- panic("lfs_unmount: still dirty blocks on ifile vnode");
- vrele(fs->lfs_ivnode);
- vgone(fs->lfs_ivnode);
-
- ronly = fs->lfs_ronly;
- ump->um_devvp->v_specflags &= ~SI_MOUNTEDON;
- error = VOP_CLOSE(ump->um_devvp,
- ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
- vrele(ump->um_devvp);
- free(fs, M_UFSMNT);
- free(ump, M_UFSMNT);
- mp->mnt_data = (qaddr_t)0;
- mp->mnt_flag &= ~MNT_LOCAL;
- return (error);
-}
-
-/*
- * Get file system statistics.
- */
-static int
-lfs_statfs(mp, sbp, p)
- struct mount *mp;
- register struct statfs *sbp;
- struct proc *p;
-{
- register struct lfs *fs;
- register struct ufsmount *ump;
-
- ump = VFSTOUFS(mp);
- fs = ump->um_lfs;
- if (fs->lfs_magic != LFS_MAGIC)
- panic("lfs_statfs: magic");
- sbp->f_bsize = fs->lfs_fsize;
- sbp->f_iosize = fs->lfs_bsize;
- sbp->f_blocks = dbtofrags(fs,fs->lfs_dsize);
- sbp->f_bfree = dbtofrags(fs, fs->lfs_bfree);
- /*
- * To compute the available space. Subtract the minimum free
- * from the total number of blocks in the file system. Set avail
- * to the smaller of this number and fs->lfs_bfree.
- */
- sbp->f_bavail = fs->lfs_dsize * (100 - fs->lfs_minfree) / 100;
- sbp->f_bavail =
- sbp->f_bavail > fs->lfs_bfree ? fs->lfs_bfree : sbp->f_bavail;
- sbp->f_bavail = dbtofrags(fs, sbp->f_bavail);
- sbp->f_files = fs->lfs_nfiles;
- sbp->f_ffree = sbp->f_bfree * INOPB(fs);
- if (sbp != &mp->mnt_stat) {
- sbp->f_type = mp->mnt_vfc->vfc_typenum;
- bcopy((caddr_t)mp->mnt_stat.f_mntonname,
- (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
- bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
- (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
- }
- return (0);
-}
-
-/*
- * Go through the disk queues to initiate sandbagged IO;
- * go through the inodes to write those that have been modified;
- * initiate the writing of the super block if it has been modified.
- *
- * Note: we are always called with the filesystem marked `MPBUSY'.
- */
-static int
-lfs_sync(mp, waitfor, cred, p)
- struct mount *mp;
- int waitfor;
- struct ucred *cred;
- struct proc *p;
-{
- int error;
-
- /* All syncs must be checkpoints until roll-forward is implemented. */
- error = lfs_segwrite(mp, SEGM_CKP | (waitfor ? SEGM_SYNC : 0));
-#ifdef QUOTA
- qsync(mp);
-#endif
- return (error);
-}
-
-/*
- * Look up an LFS dinode number to find its incore vnode. If not already
- * in core, read it in from the specified device. Return the inode locked.
- * Detection and handling of mount points must be done by the calling routine.
- */
-static int
-lfs_vget(mp, ino, vpp)
- struct mount *mp;
- ino_t ino;
- struct vnode **vpp;
-{
- register struct lfs *fs;
- register struct inode *ip;
- struct buf *bp;
- struct ifile *ifp;
- struct vnode *vp;
- struct ufsmount *ump;
- ufs_daddr_t daddr;
- dev_t dev;
- int error;
-
- ump = VFSTOUFS(mp);
- dev = ump->um_dev;
- if ((*vpp = ufs_ihashget(dev, ino)) != NULL)
- return (0);
-
- /* Translate the inode number to a disk address. */
- fs = ump->um_lfs;
- if (ino == LFS_IFILE_INUM)
- daddr = fs->lfs_idaddr;
- else {
- LFS_IENTRY(ifp, fs, ino, bp);
- daddr = ifp->if_daddr;
- brelse(bp);
- if (daddr == LFS_UNUSED_DADDR)
- return (ENOENT);
- }
-
- /* Allocate new vnode/inode. */
- if (error = lfs_vcreate(mp, ino, &vp)) {
- *vpp = NULL;
- return (error);
- }
-
- /*
- * Put it onto its hash chain and lock it so that other requests for
- * this inode will block if they arrive while we are sleeping waiting
- * for old data structures to be purged or for the contents of the
- * disk portion of this inode to be read.
- */
- ip = VTOI(vp);
- ufs_ihashins(ip);
-
- /*
- * XXX
- * This may not need to be here, logically it should go down with
- * the i_devvp initialization.
- * Ask Kirk.
- */
- ip->i_lfs = ump->um_lfs;
-
- /* Read in the disk contents for the inode, copy into the inode. */
- if (error =
- bread(ump->um_devvp, daddr, (int)fs->lfs_bsize, NOCRED, &bp)) {
- /*
- * The inode does not contain anything useful, so it would
- * be misleading to leave it on its hash chain. With mode
- * still zero, it will be unlinked and returned to the free
- * list by vput().
- */
- vput(vp);
- brelse(bp);
- *vpp = NULL;
- return (error);
- }
- ip->i_din = *lfs_ifind(fs, ino, (struct dinode *)bp->b_data);
- brelse(bp);
-
- /*
- * Initialize the vnode from the inode, check for aliases. In all
- * cases re-init ip, the underlying vnode/inode may have changed.
- */
- if (error = ufs_vinit(mp, lfs_specop_p, LFS_FIFOOPS, &vp)) {
- vput(vp);
- *vpp = NULL;
- return (error);
- }
- /*
- * Finish inode initialization now that aliasing has been resolved.
- */
- ip->i_devvp = ump->um_devvp;
- VREF(ip->i_devvp);
- *vpp = vp;
- return (0);
-}
-
-/*
- * File handle to vnode
- *
- * Have to be really careful about stale file handles:
- * - check that the inode number is valid
- * - call lfs_vget() to get the locked inode
- * - check for an unallocated inode (i_mode == 0)
- * - check that the given client host has export rights and return
- * those rights via. exflagsp and credanonp
- *
- * XXX
- * use ifile to see if inode is allocated instead of reading off disk
- * what is the relationship between my generational number and the NFS
- * generational number.
- */
-static int
-lfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
- register struct mount *mp;
- struct fid *fhp;
- struct sockaddr *nam;
- struct vnode **vpp;
- int *exflagsp;
- struct ucred **credanonp;
-{
- register struct ufid *ufhp;
-
- ufhp = (struct ufid *)fhp;
- if (ufhp->ufid_ino < ROOTINO)
- return (ESTALE);
- return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp));
-}
-
-/*
- * Vnode pointer to File handle
- */
-/* ARGSUSED */
-static int
-lfs_vptofh(vp, fhp)
- struct vnode *vp;
- struct fid *fhp;
-{
- register struct inode *ip;
- register struct ufid *ufhp;
-
- ip = VTOI(vp);
- ufhp = (struct ufid *)fhp;
- ufhp->ufid_len = sizeof(struct ufid);
- ufhp->ufid_ino = ip->i_number;
- ufhp->ufid_gen = ip->i_gen;
- return (0);
-}
-
-/*
- * Initialize the filesystem, most work done by ufs_init.
- */
-int lfs_mount_type;
-
-int
-lfs_init(vfsp)
- struct vfsconf *vfsp;
-{
-
- lfs_mount_type = vfsp->vfc_typenum;
- return (ufs_init(vfsp));
-}
diff --git a/sys/ufs/lfs/lfs_vnops.c b/sys/ufs/lfs/lfs_vnops.c
deleted file mode 100644
index 12da60f67e44..000000000000
--- a/sys/ufs/lfs/lfs_vnops.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (c) 1986, 1989, 1991, 1993, 1995
- * 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.
- *
- * 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.
- *
- * @(#)lfs_vnops.c 8.13 (Berkeley) 6/10/95
- * $Id: lfs_vnops.c,v 1.29 1997/10/16 20:32:37 phk Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/resourcevar.h>
-#include <sys/signalvar.h>
-#include <sys/kernel.h>
-#include <sys/stat.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-
-#include <vm/vm.h>
-#include <vm/vm_prot.h>
-#include <vm/vm_page.h>
-#include <vm/vm_extern.h>
-
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ufs/ufs_extern.h>
-
-#include <ufs/lfs/lfs.h>
-#include <ufs/lfs/lfs_extern.h>
-
-static int lfs_close __P((struct vop_close_args *));
-static int lfs_fsync __P((struct vop_fsync_args *));
-static int lfs_getattr __P((struct vop_getattr_args *));
-static int lfs_inactive __P((struct vop_inactive_args *));
-static int lfs_read __P((struct vop_read_args *));
-static int lfs_write __P((struct vop_write_args *));
-
-
-/* Global vfs data structures for lfs. */
-vop_t **lfs_vnodeop_p;
-static struct vnodeopv_entry_desc lfs_vnodeop_entries[] = {
- { &vop_default_desc, (vop_t *) ufs_vnoperate },
- { &vop_bwrite_desc, (vop_t *) lfs_bwrite },
- { &vop_close_desc, (vop_t *) lfs_close },
- { &vop_fsync_desc, (vop_t *) lfs_fsync },
- { &vop_getattr_desc, (vop_t *) lfs_getattr },
- { &vop_read_desc, (vop_t *) lfs_read },
- { &vop_write_desc, (vop_t *) lfs_write },
- { &vop_lookup_desc, (vop_t *) ufs_lookup },
- { NULL, NULL }
-};
-static struct vnodeopv_desc lfs_vnodeop_opv_desc =
- { &lfs_vnodeop_p, lfs_vnodeop_entries };
-
-vop_t **lfs_specop_p;
-static struct vnodeopv_entry_desc lfs_specop_entries[] = {
- { &vop_default_desc, (vop_t *) ufs_vnoperatespec },
- { &vop_bwrite_desc, (vop_t *) lfs_bwrite },
- { &vop_getattr_desc, (vop_t *) lfs_getattr },
- { NULL, NULL }
-};
-static struct vnodeopv_desc lfs_specop_opv_desc =
- { &lfs_specop_p, lfs_specop_entries };
-
-vop_t **lfs_fifoop_p;
-static struct vnodeopv_entry_desc lfs_fifoop_entries[] = {
- { &vop_default_desc, (vop_t *) ufs_vnoperatefifo },
- { &vop_bwrite_desc, (vop_t *) lfs_bwrite },
- { &vop_getattr_desc, (vop_t *) lfs_getattr },
- { NULL, NULL }
-};
-static struct vnodeopv_desc lfs_fifoop_opv_desc =
- { &lfs_fifoop_p, lfs_fifoop_entries };
-
-VNODEOP_SET(lfs_vnodeop_opv_desc);
-VNODEOP_SET(lfs_specop_opv_desc);
-VNODEOP_SET(lfs_fifoop_opv_desc);
-
-#define LFS_READWRITE
-#include <ufs/ufs/ufs_readwrite.c>
-#undef LFS_READWRITE
-
-/*
- * Synch an open file.
- */
-/* ARGSUSED */
-static int
-lfs_fsync(ap)
- struct vop_fsync_args /* {
- struct vnode *a_vp;
- struct ucred *a_cred;
- int a_waitfor;
- struct proc *a_p;
- } */ *ap;
-{
- struct timeval tv;
- int error;
-
- gettime(&tv);
- error = (UFS_UPDATE(ap->a_vp, &tv, &tv,
- ap->a_waitfor == MNT_WAIT ? LFS_SYNC : 0));
- if(ap->a_waitfor == MNT_WAIT && ap->a_vp->v_dirtyblkhd.lh_first != NULL)
- panic("lfs_fsync: dirty bufs");
- return( error );
-}
-
-/*
- * These macros are used to bracket UFS directory ops, so that we can
- * identify all the pages touched during directory ops which need to
- * be ordered and flushed atomically, so that they may be recovered.
- */
-#define SET_DIROP(fs) { \
- if ((fs)->lfs_writer) \
- tsleep(&(fs)->lfs_dirops, PRIBIO + 1, "lfs_dirop", 0); \
- ++(fs)->lfs_dirops; \
- (fs)->lfs_doifile = 1; \
-}
-
-#define SET_ENDOP(fs) { \
- --(fs)->lfs_dirops; \
- if (!(fs)->lfs_dirops) \
- wakeup(&(fs)->lfs_writer); \
-}
-
-#define MARK_VNODE(dvp) (dvp)->v_flag |= VDIROP
-
-
-/* XXX hack to avoid calling ITIMES in getattr */
-static int
-lfs_getattr(ap)
- struct vop_getattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- struct proc *a_p;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct inode *ip = VTOI(vp);
- register struct vattr *vap = ap->a_vap;
- /*
- * Copy from inode table
- */
- vap->va_fsid = ip->i_dev;
- vap->va_fileid = ip->i_number;
- vap->va_mode = ip->i_mode & ~IFMT;
- vap->va_nlink = ip->i_nlink;
- vap->va_uid = ip->i_uid;
- vap->va_gid = ip->i_gid;
- vap->va_rdev = (dev_t)ip->i_rdev;
- vap->va_size = ip->i_din.di_size;
- vap->va_atime.tv_sec = ip->i_atime;
- vap->va_atime.tv_nsec = ip->i_atimensec;
- vap->va_mtime.tv_sec = ip->i_mtime;
- vap->va_mtime.tv_nsec = ip->i_mtimensec;
- vap->va_ctime.tv_sec = ip->i_ctime;
- vap->va_ctime.tv_nsec = ip->i_ctimensec;
- vap->va_flags = ip->i_flags;
- vap->va_gen = ip->i_gen;
- /* this doesn't belong here */
- if (vp->v_type == VBLK)
- vap->va_blocksize = BLKDEV_IOSIZE;
- else if (vp->v_type == VCHR)
- vap->va_blocksize = MAXBSIZE;
- else
- vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
- vap->va_bytes = dbtob(ip->i_blocks);
- vap->va_type = vp->v_type;
- vap->va_filerev = ip->i_modrev;
- return (0);
-}
-/*
- * Close called
- *
- * XXX -- we were using ufs_close, but since it updates the
- * times on the inode, we might need to bump the uinodes
- * count.
- */
-/* ARGSUSED */
-static int
-lfs_close(ap)
- struct vop_close_args /* {
- struct vnode *a_vp;
- int a_fflag;
- struct ucred *a_cred;
- struct proc *a_p;
- } */ *ap;
-{
- register struct vnode *vp = ap->a_vp;
- register struct inode *ip = VTOI(vp);
- int mod;
-
- simple_lock(&vp->v_interlock);
- if (vp->v_usecount > 1) {
- mod = ip->i_flag & IN_MODIFIED;
- ITIMES(ip, &time, &time);
- if (!mod && ip->i_flag & IN_MODIFIED)
- ip->i_lfs->lfs_uinodes++;
- }
- simple_unlock(&vp->v_interlock);
- return (0);
-}
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index 161de4bc9440..f2fd0f25fa5e 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)inode.h 8.9 (Berkeley) 5/14/95
- * $Id: inode.h,v 1.18 1997/10/17 12:36:19 phk Exp $
+ * $Id: inode.h,v 1.19 1997/12/05 13:43:47 jkh Exp $
*/
#ifndef _UFS_UFS_INODE_H_
@@ -70,11 +70,9 @@ struct inode {
union { /* Associated filesystem. */
struct fs *fs; /* FFS */
- struct lfs *lfs; /* LFS */
struct ext2_sb_info *e2fs; /* EXT2FS */
} inode_u;
#define i_fs inode_u.fs
-#define i_lfs inode_u.lfs
#define i_e2fs inode_u.e2fs
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for NFS lease. */
diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c
index e00c3c5aae02..395d6bd8714d 100644
--- a/sys/ufs/ufs/ufs_readwrite.c
+++ b/sys/ufs/ufs/ufs_readwrite.c
@@ -31,20 +31,9 @@
* SUCH DAMAGE.
*
* @(#)ufs_readwrite.c 8.11 (Berkeley) 5/8/95
- * $Id: ufs_readwrite.c,v 1.39 1998/01/06 05:24:04 dyson Exp $
+ * $Id: ufs_readwrite.c,v 1.40 1998/01/22 17:30:22 dyson Exp $
*/
-#ifdef LFS_READWRITE
-#define BLKSIZE(a, b, c) blksize(a, b, c)
-#define FS struct lfs
-#define I_FS i_lfs
-#define READ lfs_read
-#define READ_S "lfs_read"
-#define WRITE lfs_write
-#define WRITE_S "lfs_write"
-#define fs_bsize lfs_bsize
-#define fs_maxfilesize lfs_maxfilesize
-#else
#define BLKSIZE(a, b, c) blksize(a, b, c)
#define FS struct fs
#define I_FS i_fs
@@ -52,7 +41,6 @@
#define READ_S "ffs_read"
#define WRITE ffs_write
#define WRITE_S "ffs_write"
-#endif
#include <vm/vm.h>
#include <vm/vm_object.h>
@@ -147,11 +135,6 @@ READ(ap)
if (bytesinfile < xfersize)
xfersize = bytesinfile;
-#ifdef LFS_READWRITE
- (void)lfs_check(vp, lbn);
- error = cluster_read(vp, ip->i_size, lbn,
- size, NOCRED, uio->uio_resid, seqcount, &bp);
-#else
if (lblktosize(fs, nextlbn) >= ip->i_size)
error = bread(vp, lbn, size, NOCRED, &bp);
else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0)
@@ -163,7 +146,6 @@ READ(ap)
size, &nextlbn, &nextsize, 1, NOCRED, &bp);
} else
error = bread(vp, lbn, size, NOCRED, &bp);
-#endif
if (error) {
brelse(bp);
bp = NULL;
@@ -291,10 +273,6 @@ WRITE(ap)
if (uio->uio_offset + xfersize > ip->i_size)
vnode_pager_setsize(vp, uio->uio_offset + xfersize);
-#ifdef LFS_READWRITE
- (void)lfs_check(vp, lbn);
- error = lfs_balloc(vp, blkoffset, xfersize, lbn, &bp);
-#else
if (fs->fs_bsize > xfersize)
flags |= B_CLRBUF;
else
@@ -302,7 +280,6 @@ WRITE(ap)
error = ffs_balloc(ip,
lbn, blkoffset + xfersize, ap->a_cred, &bp, flags);
-#endif
if (error)
break;
@@ -325,9 +302,6 @@ WRITE(ap)
error =
uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio);
-#ifdef LFS_READWRITE
- (void)VOP_BWRITE(bp);
-#else
if (ioflag & IO_VMIO)
bp->b_flags |= B_RELBUF;
@@ -344,7 +318,6 @@ WRITE(ap)
bp->b_flags |= B_CLUSTEROK;
bdwrite(bp);
}
-#endif
if (error || xfersize == 0)
break;
ip->i_flag |= IN_CHANGE | IN_UPDATE;
@@ -373,7 +346,6 @@ WRITE(ap)
return (error);
}
-#ifndef LFS_READWRITE
/*
* get page routine
@@ -526,4 +498,3 @@ ffs_getpages(ap)
return (rtval);
}
-#endif
diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h
index ee7963190c89..c62b736034f5 100644
--- a/sys/ufs/ufs/ufsmount.h
+++ b/sys/ufs/ufs/ufsmount.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ufsmount.h 8.6 (Berkeley) 3/30/95
- * $Id: ufsmount.h,v 1.11 1997/10/16 10:50:27 phk Exp $
+ * $Id: ufsmount.h,v 1.12 1997/10/16 20:32:40 phk Exp $
*/
#ifndef _UFS_UFS_UFSMOUNT_H_
@@ -77,12 +77,10 @@ struct ufsmount {
struct vnode *um_devvp; /* block device mounted vnode */
union { /* pointer to superblock */
- struct lfs *lfs; /* LFS */
struct fs *fs; /* FFS */
struct ext2_sb_info *e2fs; /* EXT2FS */
} ufsmount_u;
#define um_fs ufsmount_u.fs
-#define um_lfs ufsmount_u.lfs
#define um_e2fs ufsmount_u.e2fs
#define um_e2fsb ufsmount_u.e2fs->s_es