aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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