Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145045550
D25285.id73145.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D25285.id73145.diff
View Options
Index: sys/ufs/ffs/ffs_extern.h
===================================================================
--- sys/ufs/ffs/ffs_extern.h
+++ sys/ufs/ffs/ffs_extern.h
@@ -84,7 +84,6 @@
struct cg **);
int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t);
int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t);
-int ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t);
void ffs_oldfscompat_write(struct fs *, struct ufsmount *);
int ffs_own_mount(const struct mount *mp);
int ffs_reallocblks(struct vop_reallocblks_args *);
Index: sys/ufs/ffs/ffs_subr.c
===================================================================
--- sys/ufs/ffs/ffs_subr.c
+++ sys/ufs/ffs/ffs_subr.c
@@ -67,7 +67,6 @@
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/ucred.h>
-#include <sys/taskqueue.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
@@ -112,51 +111,6 @@
}
/*
- * Load up the contents of an inode and copy the appropriate pieces
- * to the incore copy.
- */
-int
-ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino)
-{
- struct ufs1_dinode *dip1;
- struct ufs2_dinode *dip2;
- int error;
-
- if (I_IS_UFS1(ip)) {
- dip1 = ip->i_din1;
- *dip1 =
- *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
- ip->i_mode = dip1->di_mode;
- ip->i_nlink = dip1->di_nlink;
- ip->i_effnlink = dip1->di_nlink;
- ip->i_size = dip1->di_size;
- ip->i_flags = dip1->di_flags;
- ip->i_gen = dip1->di_gen;
- ip->i_uid = dip1->di_uid;
- ip->i_gid = dip1->di_gid;
- return (0);
- }
- dip2 = ((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
- if ((error = ffs_verify_dinode_ckhash(fs, dip2)) != 0 &&
- !ffs_fsfail_cleanup(ITOUMP(ip), error)) {
- printf("%s: inode %jd: check-hash failed\n", fs->fs_fsmnt,
- (intmax_t)ino);
- return (error);
- }
- *ip->i_din2 = *dip2;
- dip2 = ip->i_din2;
- ip->i_mode = dip2->di_mode;
- ip->i_nlink = dip2->di_nlink;
- ip->i_effnlink = dip2->di_nlink;
- ip->i_size = dip2->di_size;
- ip->i_flags = dip2->di_flags;
- ip->i_gen = dip2->di_gen;
- ip->i_uid = dip2->di_uid;
- ip->i_gid = dip2->di_gid;
- return (0);
-}
-
-/*
* Verify that a filesystem block number is a valid data block.
* This routine is only called on untrusted filesystems.
*/
@@ -203,93 +157,6 @@
} else if (!havemtx)
UFS_UNLOCK(ump);
return (EINTEGRITY);
-}
-
-/*
- * Initiate a forcible unmount.
- * Used to unmount filesystems whose underlying media has gone away.
- */
-static void
-ffs_fsfail_unmount(void *v, int pending)
-{
- struct fsfail_task *etp;
- struct mount *mp;
-
- etp = v;
-
- /*
- * Find our mount and get a ref on it, then try to unmount.
- */
- mp = vfs_getvfs(&etp->fsid);
- if (mp != NULL)
- dounmount(mp, MNT_FORCE, curthread);
- free(etp, M_UFSMNT);
-}
-
-/*
- * On first ENXIO error, start a task that forcibly unmounts the filesystem.
- *
- * Return true if a cleanup is in progress.
- */
-int
-ffs_fsfail_cleanup(struct ufsmount *ump, int error)
-{
- int retval;
-
- UFS_LOCK(ump);
- retval = ffs_fsfail_cleanup_locked(ump, error);
- UFS_UNLOCK(ump);
- return (retval);
-}
-
-int
-ffs_fsfail_cleanup_locked(struct ufsmount *ump, int error)
-{
- struct fsfail_task *etp;
- struct task *tp;
-
- mtx_assert(UFS_MTX(ump), MA_OWNED);
- if (error == ENXIO && (ump->um_flags & UM_FSFAIL_CLEANUP) == 0) {
- ump->um_flags |= UM_FSFAIL_CLEANUP;
- /*
- * Queue an async forced unmount.
- */
- etp = ump->um_fsfail_task;
- ump->um_fsfail_task = NULL;
- if (etp != NULL) {
- tp = &etp->task;
- TASK_INIT(tp, 0, ffs_fsfail_unmount, etp);
- taskqueue_enqueue(taskqueue_thread, tp);
- printf("UFS: forcibly unmounting %s from %s\n",
- ump->um_mountp->mnt_stat.f_mntfromname,
- ump->um_mountp->mnt_stat.f_mntonname);
- }
- }
- return ((ump->um_flags & UM_FSFAIL_CLEANUP) != 0);
-}
-
-/*
- * Wrapper used during ENXIO cleanup to allocate empty buffers when
- * the kernel is unable to read the real one. They are needed so that
- * the soft updates code can use them to unwind its dependencies.
- */
-int
-ffs_breadz(struct ufsmount *ump, struct vnode *vp, daddr_t lblkno,
- daddr_t dblkno, int size, daddr_t *rablkno, int *rabsize, int cnt,
- struct ucred *cred, int flags, void (*ckhashfunc)(struct buf *),
- struct buf **bpp)
-{
- int error;
-
- flags |= GB_CVTENXIO;
- error = breadn_flags(vp, lblkno, dblkno, size, rablkno, rabsize, cnt,
- cred, flags, ckhashfunc, bpp);
- if (error != 0 && ffs_fsfail_cleanup(ump, error)) {
- error = getblkx(vp, lblkno, dblkno, size, 0, 0, flags, bpp);
- KASSERT(error == 0, ("getblkx failed"));
- vfs_bio_bzero_buf(*bpp, 0, size);
- }
- return (error);
}
#endif /* _KERNEL */
Index: sys/ufs/ffs/ffs_vfsops.c
===================================================================
--- sys/ufs/ffs/ffs_vfsops.c
+++ sys/ufs/ffs/ffs_vfsops.c
@@ -612,6 +612,51 @@
}
/*
+ * Load up the contents of an inode and copy the appropriate pieces
+ * to the incore copy.
+ */
+static int
+ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino)
+{
+ struct ufs1_dinode *dip1;
+ struct ufs2_dinode *dip2;
+ int error;
+
+ if (I_IS_UFS1(ip)) {
+ dip1 = ip->i_din1;
+ *dip1 =
+ *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
+ ip->i_mode = dip1->di_mode;
+ ip->i_nlink = dip1->di_nlink;
+ ip->i_effnlink = dip1->di_nlink;
+ ip->i_size = dip1->di_size;
+ ip->i_flags = dip1->di_flags;
+ ip->i_gen = dip1->di_gen;
+ ip->i_uid = dip1->di_uid;
+ ip->i_gid = dip1->di_gid;
+ return (0);
+ }
+ dip2 = ((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
+ if ((error = ffs_verify_dinode_ckhash(fs, dip2)) != 0 &&
+ !ffs_fsfail_cleanup(ITOUMP(ip), error)) {
+ printf("%s: inode %jd: check-hash failed\n", fs->fs_fsmnt,
+ (intmax_t)ino);
+ return (error);
+ }
+ *ip->i_din2 = *dip2;
+ dip2 = ip->i_din2;
+ ip->i_mode = dip2->di_mode;
+ ip->i_nlink = dip2->di_nlink;
+ ip->i_effnlink = dip2->di_nlink;
+ ip->i_size = dip2->di_size;
+ ip->i_flags = dip2->di_flags;
+ ip->i_gen = dip2->di_gen;
+ ip->i_uid = dip2->di_uid;
+ ip->i_gid = dip2->di_gid;
+ return (0);
+}
+
+/*
* Reload all incore data for a filesystem (used after running fsck on
* the root filesystem and finding things to fix). If the 'force' flag
* is 0, the filesystem must be mounted read-only.
@@ -2435,6 +2480,92 @@
return (0);
}
+/*
+ * Initiate a forcible unmount.
+ * Used to unmount filesystems whose underlying media has gone away.
+ */
+static void
+ffs_fsfail_unmount(void *v, int pending)
+{
+ struct fsfail_task *etp;
+ struct mount *mp;
+
+ etp = v;
+
+ /*
+ * Find our mount and get a ref on it, then try to unmount.
+ */
+ mp = vfs_getvfs(&etp->fsid);
+ if (mp != NULL)
+ dounmount(mp, MNT_FORCE, curthread);
+ free(etp, M_UFSMNT);
+}
+
+/*
+ * On first ENXIO error, start a task that forcibly unmounts the filesystem.
+ *
+ * Return true if a cleanup is in progress.
+ */
+int
+ffs_fsfail_cleanup(struct ufsmount *ump, int error)
+{
+ int retval;
+
+ UFS_LOCK(ump);
+ retval = ffs_fsfail_cleanup_locked(ump, error);
+ UFS_UNLOCK(ump);
+ return (retval);
+}
+
+int
+ffs_fsfail_cleanup_locked(struct ufsmount *ump, int error)
+{
+ struct fsfail_task *etp;
+ struct task *tp;
+
+ mtx_assert(UFS_MTX(ump), MA_OWNED);
+ if (error == ENXIO && (ump->um_flags & UM_FSFAIL_CLEANUP) == 0) {
+ ump->um_flags |= UM_FSFAIL_CLEANUP;
+ /*
+ * Queue an async forced unmount.
+ */
+ etp = ump->um_fsfail_task;
+ ump->um_fsfail_task = NULL;
+ if (etp != NULL) {
+ tp = &etp->task;
+ TASK_INIT(tp, 0, ffs_fsfail_unmount, etp);
+ taskqueue_enqueue(taskqueue_thread, tp);
+ printf("UFS: forcibly unmounting %s from %s\n",
+ ump->um_mountp->mnt_stat.f_mntfromname,
+ ump->um_mountp->mnt_stat.f_mntonname);
+ }
+ }
+ return ((ump->um_flags & UM_FSFAIL_CLEANUP) != 0);
+}
+
+/*
+ * Wrapper used during ENXIO cleanup to allocate empty buffers when
+ * the kernel is unable to read the real one. They are needed so that
+ * the soft updates code can use them to unwind its dependencies.
+ */
+int
+ffs_breadz(struct ufsmount *ump, struct vnode *vp, daddr_t lblkno,
+ daddr_t dblkno, int size, daddr_t *rablkno, int *rabsize, int cnt,
+ struct ucred *cred, int flags, void (*ckhashfunc)(struct buf *),
+ struct buf **bpp)
+{
+ int error;
+
+ flags |= GB_CVTENXIO;
+ error = breadn_flags(vp, lblkno, dblkno, size, rablkno, rabsize, cnt,
+ cred, flags, ckhashfunc, bpp);
+ if (error != 0 && ffs_fsfail_cleanup(ump, error)) {
+ error = getblkx(vp, lblkno, dblkno, size, 0, 0, flags, bpp);
+ KASSERT(error == 0, ("getblkx failed"));
+ vfs_bio_bzero_buf(*bpp, 0, size);
+ }
+ return (error);
+}
#ifdef DDB
#ifdef SOFTUPDATES
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 16, 9:12 AM (5 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28773665
Default Alt Text
D25285.id73145.diff (8 KB)
Attached To
Mode
D25285: fix kernel linking without FFS
Attached
Detach File
Event Timeline
Log In to Comment