summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2006-10-31 21:48:54 +0000
committerpjd <pjd@FreeBSD.org>2006-10-31 21:48:54 +0000
commit036e929548382eba04c176d581bb24928a5d4155 (patch)
tree6ec7dfd1b055b1259a6aff3184ec4cbd7a09e343 /sys/ufs/ffs
parentf025652fdc4370dc57dbf8e240345ccda575aa87 (diff)
downloadFreeBSD-src-036e929548382eba04c176d581bb24928a5d4155.zip
FreeBSD-src-036e929548382eba04c176d581bb24928a5d4155.tar.gz
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
Diffstat (limited to 'sys/ufs/ffs')
-rw-r--r--sys/ufs/ffs/ffs_extern.h1
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c41
-rw-r--r--sys/ufs/ffs/fs.h7
3 files changed, 45 insertions, 4 deletions
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 <security/mac/mac_framework.h>
#include <ufs/ufs/extattr.h>
+#include <ufs/ufs/gjournal.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/ufs/inode.h>
@@ -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 */
OpenPOWER on IntegriCloud