aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/ufs/ffs/ffs_alloc.c3
-rw-r--r--sys/ufs/ffs/ffs_extern.h1
-rw-r--r--sys/ufs/ffs/ffs_subr.c61
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c6
-rw-r--r--sys/ufs/ufs/dinode.h26
-rw-r--r--sys/ufs/ufs/inode.h9
6 files changed, 92 insertions, 14 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 09028456435e..163ef4a11e50 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -491,8 +491,7 @@ nospace:
* allocation will be used.
*/
-SYSCTL_NODE(_vfs, OID_AUTO, ffs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
- "FFS filesystem");
+SYSCTL_DECL(_vfs_ffs);
static int doasyncfree = 1;
SYSCTL_INT(_vfs_ffs, OID_AUTO, doasyncfree, CTLFLAG_RW, &doasyncfree, 0,
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index 2e9b485d482b..15688943fa34 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -85,6 +85,7 @@ int ffs_inotovp(struct mount *, ino_t, uint64_t, int, struct vnode **,
int ffs_isblock(struct fs *, uint8_t *, ufs1_daddr_t);
int ffs_isfreeblock(struct fs *, uint8_t *, ufs1_daddr_t);
void ffs_oldfscompat_write(struct fs *);
+bool ffs_oldfscompat_inode_read(struct fs *, union dinodep, time_t);
int ffs_own_mount(const struct mount *mp);
int ffs_reallocblks(struct vop_reallocblks_args *);
int ffs_realloccg(struct inode *, ufs2_daddr_t, ufs2_daddr_t,
diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index 351559882ca2..af0e2ac74427 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -35,6 +35,7 @@
#include <sys/param.h>
#ifndef _KERNEL
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -66,6 +67,7 @@ struct malloc_type;
#include <sys/buf.h>
#include <sys/sysctl.h>
#include <sys/ucred.h>
+#include <sys/sysctl.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
@@ -397,6 +399,65 @@ ffs_oldfscompat_write(struct fs *fs)
}
/*
+ * Sanity checks for loading old filesystem inodes.
+ *
+ * XXX - Parts get retired eventually.
+ * Unfortunately new bits get added.
+ */
+static int prttimechgs = 0;
+#ifdef _KERNEL
+SYSCTL_NODE(_vfs, OID_AUTO, ffs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+ "FFS filesystem");
+
+SYSCTL_INT(_vfs_ffs, OID_AUTO, prttimechgs, CTLFLAG_RWTUN, &prttimechgs, 0,
+ "print UFS1 time changes made to inodes");
+#endif /* _KERNEL */
+bool
+ffs_oldfscompat_inode_read(struct fs *fs, union dinodep dp, time_t now)
+{
+ bool change;
+
+ change = false;
+ switch (fs->fs_magic) {
+ case FS_UFS2_MAGIC:
+ /* No changes for now */
+ break;
+
+ case FS_UFS1_MAGIC:
+ /*
+ * With the change to unsigned time values in UFS1, times set
+ * before Jan 1, 1970 will appear to be in the future. Check
+ * for future times and set them to be the current time.
+ */
+ if (dp.dp1->di_ctime > now) {
+ if (prttimechgs)
+ printf("ctime %ud changed to %ld\n",
+ dp.dp1->di_ctime, (long)now);
+ dp.dp1->di_ctime = now;
+ change = true;
+ }
+ if (dp.dp1->di_mtime > now) {
+ if (prttimechgs)
+ printf("mtime %ud changed to %ld\n",
+ dp.dp1->di_mtime, (long)now);
+ dp.dp1->di_mtime = now;
+ dp.dp1->di_ctime = now;
+ change = true;
+ }
+ if (dp.dp1->di_atime > now) {
+ if (prttimechgs)
+ printf("atime %ud changed to %ld\n",
+ dp.dp1->di_atime, (long)now);
+ dp.dp1->di_atime = now;
+ dp.dp1->di_ctime = now;
+ change = true;
+ }
+ break;
+ }
+ return (change);
+}
+
+/*
* Verify the filesystem values.
*/
#define ILOG2(num) (fls(num) - 1)
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index a77784b32d78..2cc22ffa32d4 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -205,6 +205,9 @@ ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino)
ip->i_gen = dip1->di_gen;
ip->i_uid = dip1->di_uid;
ip->i_gid = dip1->di_gid;
+ if (ffs_oldfscompat_inode_read(fs, ip->i_dp, time_second) &&
+ fs->fs_ronly == 0)
+ UFS_INODE_SET_FLAG(ip, IN_MODIFIED);
return (0);
}
dip2 = ((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
@@ -224,6 +227,9 @@ ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino)
ip->i_gen = dip2->di_gen;
ip->i_uid = dip2->di_uid;
ip->i_gid = dip2->di_gid;
+ if (ffs_oldfscompat_inode_read(fs, ip->i_dp, time_second) &&
+ fs->fs_ronly == 0)
+ UFS_INODE_SET_FLAG(ip, IN_MODIFIED);
return (0);
}
diff --git a/sys/ufs/ufs/dinode.h b/sys/ufs/ufs/dinode.h
index b4117a99c262..49f7fd91aa26 100644
--- a/sys/ufs/ufs/dinode.h
+++ b/sys/ufs/ufs/dinode.h
@@ -113,12 +113,13 @@ typedef int64_t ufs_time_t;
#define IFWHT 0160000 /* Whiteout. */
/*
- * A dinode contains all the meta-data associated with a UFS2 file.
- * This structure defines the on-disk format of a dinode. Since
+ * Each UFS filesystem version defines the on-disk format of its dinode.
+ *
+ * A UFS2 dinode contains all the meta-data associated with a UFS2 file.
+ * This structure defines the on-disk format of a UFS2 dinode. Since
* this structure describes an on-disk structure, all its fields
* are defined by types with precise widths.
*/
-
#define UFS_NXADDR 2 /* External addresses in inode. */
#define UFS_NDADDR 12 /* Direct addresses in inode. */
#define UFS_NIADDR 3 /* Indirect addresses in inode. */
@@ -186,11 +187,11 @@ struct ufs1_dinode {
uint32_t di_dirdepth; /* 4: IFDIR: depth from root dir */
};
uint64_t di_size; /* 8: File byte count. */
- int32_t di_atime; /* 16: Last access time. */
+ uint32_t di_atime; /* 16: Last access time. */
int32_t di_atimensec; /* 20: Last access time. */
- int32_t di_mtime; /* 24: Last modified time. */
+ uint32_t di_mtime; /* 24: Last modified time. */
int32_t di_mtimensec; /* 28: Last modified time. */
- int32_t di_ctime; /* 32: Last inode change time. */
+ uint32_t di_ctime; /* 32: Last inode change time. */
int32_t di_ctimensec; /* 36: Last inode change time. */
union {
struct {
@@ -212,4 +213,17 @@ struct ufs1_dinode {
#define UFS_LINK_MAX 65500 /* leave a few spare for special values */
+/*
+ * These structures hold or reference an on-disk dinode.
+ */
+union dinode {
+ struct ufs1_dinode dp1;
+ struct ufs2_dinode dp2;
+};
+
+union dinodep {
+ struct ufs1_dinode *dp1;
+ struct ufs2_dinode *dp2;
+};
+
#endif /* _UFS_UFS_DINODE_H_ */
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index afe49bdba882..0fae4c11e309 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -89,10 +89,7 @@ struct inode {
/*
* The real copy of the on-disk inode.
*/
- union {
- struct ufs1_dinode *din1; /* UFS1 on-disk dinode. */
- struct ufs2_dinode *din2; /* UFS2 on-disk dinode. */
- } dinode_u;
+ union dinodep i_dp; /* On-disk dinode */
ino_t i_number; /* The identity of the inode. */
uint32_t i_flag; /* flags, see below */
@@ -203,8 +200,8 @@ struct inode {
#define i_dirhash i_un.dirhash
#define i_snapblklist i_un.snapblklist
-#define i_din1 dinode_u.din1
-#define i_din2 dinode_u.din2
+#define i_din1 i_dp.dp1
+#define i_din2 i_dp.dp2
#ifdef _KERNEL