diff options
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/ufs/ffs/ffs_alloc.c | 3 | ||||
| -rw-r--r-- | sys/ufs/ffs/ffs_extern.h | 1 | ||||
| -rw-r--r-- | sys/ufs/ffs/ffs_subr.c | 61 | ||||
| -rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 6 | ||||
| -rw-r--r-- | sys/ufs/ufs/dinode.h | 26 | ||||
| -rw-r--r-- | sys/ufs/ufs/inode.h | 9 |
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 |
