From 036e929548382eba04c176d581bb24928a5d4155 Mon Sep 17 00:00:00 2001 From: pjd Date: Tue, 31 Oct 2006 21:48:54 +0000 Subject: Add gjournal specific code to the UFS file system: - Add FS_GJOURNAL flag which enables gjournal support on a file system. - Add cg_unrefs field to the cylinder group structure which holds number of unreferenced (orphaned) inodes in the given cylinder group. - Add fs_unrefs field to the super block structure which holds total number of unreferenced (orphaned) inodes. - When file or a directory is orphaned (last reference is removed, but object is still open), increase fs_unrefs and cg_unrefs fields, which is a hint for fsck in which cylinder groups looks for such (orphaned) objects. - When file is last closed, decrease {fs,cg}_unrefs fields. - Add VV_DELETED vnode flag which points at orphaned objects. Sponsored by: home.pl --- sys/ufs/ffs/ffs_extern.h | 1 + sys/ufs/ffs/ffs_vfsops.c | 41 +++++++++++++++++++++++++++++++++++++++-- sys/ufs/ffs/fs.h | 7 +++++-- 3 files changed, 45 insertions(+), 4 deletions(-) (limited to 'sys/ufs/ffs') diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h index 21704bd..98f0f91 100644 --- a/sys/ufs/ffs/ffs_extern.h +++ b/sys/ufs/ffs/ffs_extern.h @@ -72,6 +72,7 @@ int ffs_mountroot(void); int ffs_reallocblks(struct vop_reallocblks_args *); int ffs_realloccg(struct inode *, ufs2_daddr_t, ufs2_daddr_t, ufs2_daddr_t, int, int, struct ucred *, struct buf **); +int ffs_sbupdate(struct ufsmount *, int, int); void ffs_setblock(struct fs *, u_char *, ufs1_daddr_t); int ffs_snapblkfree(struct fs *, struct vnode *, ufs2_daddr_t, long, ino_t); void ffs_snapremove(struct vnode *vp); diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 05df838..b9ccf3a 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -71,7 +72,6 @@ __FBSDID("$FreeBSD$"); static uma_zone_t uma_inode, uma_ufs1, uma_ufs2; -static int ffs_sbupdate(struct ufsmount *, int, int); static int ffs_reload(struct mount *, struct thread *); static int ffs_mountfs(struct vnode *, struct mount *, struct thread *); static void ffs_oldfscompat_read(struct fs *, struct ufsmount *, @@ -696,6 +696,35 @@ ffs_mountfs(devvp, mp, td) fs->fs_pendingblocks = 0; fs->fs_pendinginodes = 0; } + if ((fs->fs_flags & FS_GJOURNAL) != 0) { +#ifdef UFS_GJOURNAL + /* + * Get journal provider name. + */ + size = 1024; + mp->mnt_gjprovider = malloc(size, M_UFSMNT, M_WAITOK); + if (g_io_getattr("GJOURNAL::provider", cp, &size, + mp->mnt_gjprovider) == 0) { + mp->mnt_gjprovider = realloc(mp->mnt_gjprovider, size, + M_UFSMNT, M_WAITOK); + MNT_ILOCK(mp); + mp->mnt_flag |= MNT_GJOURNAL; + MNT_IUNLOCK(mp); + } else { + printf( +"WARNING: %s: GJOURNAL flag on fs but no gjournal provider below\n", + mp->mnt_stat.f_mntonname); + free(mp->mnt_gjprovider, M_UFSMNT); + mp->mnt_gjprovider = NULL; + } +#else + printf( +"WARNING: %s: GJOURNAL flag on fs but no UFS_GJOURNAL support\n", + mp->mnt_stat.f_mntonname); +#endif + } else { + mp->mnt_gjprovider = NULL; + } ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO); ump->um_cp = cp; ump->um_bo = &devvp->v_bufobj; @@ -871,6 +900,10 @@ out: } if (ump) { mtx_destroy(UFS_MTX(ump)); + if (mp->mnt_gjprovider != NULL) { + free(mp->mnt_gjprovider, M_UFSMNT); + mp->mnt_gjprovider = NULL; + } free(ump->um_fs, M_UFSMNT); free(ump, M_UFSMNT); mp->mnt_data = (qaddr_t)0; @@ -1030,6 +1063,10 @@ ffs_unmount(mp, mntflags, td) PICKUP_GIANT(); vrele(ump->um_devvp); mtx_destroy(UFS_MTX(ump)); + if (mp->mnt_gjprovider != NULL) { + free(mp->mnt_gjprovider, M_UFSMNT); + mp->mnt_gjprovider = NULL; + } free(fs->fs_csp, M_UFSMNT); free(fs, M_UFSMNT); free(ump, M_UFSMNT); @@ -1514,7 +1551,7 @@ ffs_uninit(vfsp) /* * Write a superblock and associated information back to disk. */ -static int +int ffs_sbupdate(mp, waitfor, suspended) struct ufsmount *mp; int waitfor; diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h index 572996e..9aaf040 100644 --- a/sys/ufs/ffs/fs.h +++ b/sys/ufs/ffs/fs.h @@ -323,7 +323,8 @@ struct fs { u_int *fs_active; /* (u) used by snapshots to track fs */ int32_t fs_old_cpc; /* cyl per cycle in postbl */ int32_t fs_maxbsize; /* maximum blocking factor permitted */ - int64_t fs_sparecon64[17]; /* old rotation block list head */ + int64_t fs_unrefs; /* number of unreferenced inodes */ + int64_t fs_sparecon64[16]; /* old rotation block list head */ int64_t fs_sblockloc; /* byte offset of standard superblock */ struct csum_total fs_cstotal; /* (u) cylinder summary information */ ufs_time_t fs_time; /* last time written */ @@ -406,6 +407,7 @@ CTASSERT(sizeof(struct fs) == 1376); #define FS_INDEXDIRS 0x08 /* kernel supports indexed directories */ #define FS_ACLS 0x10 /* file system has ACLs enabled */ #define FS_MULTILABEL 0x20 /* file system is MAC multi-label */ +#define FS_GJOURNAL 0x40 /* gjournaled file system */ #define FS_FLAGS_UPDATED 0x80 /* flags have been moved to new location */ /* @@ -475,7 +477,8 @@ struct cg { int32_t cg_nclusterblks; /* number of clusters this cg */ int32_t cg_niblk; /* number of inode blocks this cg */ int32_t cg_initediblk; /* last initialized inode */ - int32_t cg_sparecon32[3]; /* reserved for future use */ + int32_t cg_unrefs; /* number of unreferenced inodes */ + int32_t cg_sparecon32[2]; /* reserved for future use */ ufs_time_t cg_time; /* time last written */ int64_t cg_sparecon64[3]; /* reserved for future use */ u_int8_t cg_space[1]; /* space for cylinder group maps */ -- cgit v1.1