Changeset View
Changeset View
Standalone View
Standalone View
sys/ufs/ffs/ffs_vfsops.c
Show First 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
#include <sys/bio.h> | #include <sys/bio.h> | ||||
#include <sys/buf.h> | #include <sys/buf.h> | ||||
#include <sys/conf.h> | #include <sys/conf.h> | ||||
#include <sys/fcntl.h> | #include <sys/fcntl.h> | ||||
#include <sys/ioccom.h> | #include <sys/ioccom.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/sysctl.h> | |||||
#include <sys/vmmeter.h> | #include <sys/vmmeter.h> | ||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
#include <ufs/ufs/dir.h> | #include <ufs/ufs/dir.h> | ||||
#include <ufs/ufs/extattr.h> | #include <ufs/ufs/extattr.h> | ||||
#include <ufs/ufs/gjournal.h> | #include <ufs/ufs/gjournal.h> | ||||
#include <ufs/ufs/quota.h> | #include <ufs/ufs/quota.h> | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | |||||
* from userland, but they can be passed by loader(8) via | * from userland, but they can be passed by loader(8) via | ||||
* vfs.root.mountfrom.options. | * vfs.root.mountfrom.options. | ||||
*/ | */ | ||||
static const char *ffs_opts[] = { "acls", "async", "noatime", "noclusterr", | static const char *ffs_opts[] = { "acls", "async", "noatime", "noclusterr", | ||||
"noclusterw", "noexec", "export", "force", "from", "groupquota", | "noclusterw", "noexec", "export", "force", "from", "groupquota", | ||||
"multilabel", "nfsv4acls", "fsckpid", "snapshot", "nosuid", "suiddir", | "multilabel", "nfsv4acls", "fsckpid", "snapshot", "nosuid", "suiddir", | ||||
"nosymfollow", "sync", "union", "userquota", "untrusted", NULL }; | "nosymfollow", "sync", "union", "userquota", "untrusted", NULL }; | ||||
static int ffs_enxio_enable = 1; | |||||
TUNABLE_INT("vfs.ffs.enxio_enable", &ffs_enxio_enable); | |||||
SYSCTL_DECL(_vfs_ffs); | |||||
SYSCTL_INT(_vfs_ffs, OID_AUTO, enxio_enable, CTLFLAG_RW, | |||||
kib: Use CTLFLAG_RWTUN instead of separate TUNABLE_INT ? | |||||
chsAuthorUnsubmitted Done Inline ActionsI didn't know about CTLFLAG_RWTUN, I'll use that. chs: I didn't know about CTLFLAG_RWTUN, I'll use that. | |||||
&ffs_enxio_enable, 0, | |||||
"enable mapping of other disk I/O errors to ENXIO"); | |||||
static int | static int | ||||
ffs_mount(struct mount *mp) | ffs_mount(struct mount *mp) | ||||
{ | { | ||||
struct vnode *devvp, *odevvp; | struct vnode *devvp, *odevvp; | ||||
struct thread *td; | struct thread *td; | ||||
struct ufsmount *ump = NULL; | struct ufsmount *ump = NULL; | ||||
struct fs *fs; | struct fs *fs; | ||||
pid_t fsckpid = 0; | pid_t fsckpid = 0; | ||||
▲ Show 20 Lines • Show All 631 Lines • ▼ Show 20 Lines | ffs_mountfs(odevvp, mp, td) | ||||
struct ufsmount *ump; | struct ufsmount *ump; | ||||
struct fs *fs; | struct fs *fs; | ||||
struct cdev *dev; | struct cdev *dev; | ||||
int error, i, len, ronly; | int error, i, len, ronly; | ||||
struct ucred *cred; | struct ucred *cred; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
struct mount *nmp; | struct mount *nmp; | ||||
struct vnode *devvp; | struct vnode *devvp; | ||||
struct fsfail_task *etp; | |||||
int candelete, canspeedup; | int candelete, canspeedup; | ||||
off_t loc; | off_t loc; | ||||
fs = NULL; | fs = NULL; | ||||
ump = NULL; | ump = NULL; | ||||
cred = td ? td->td_ucred : NOCRED; | cred = td ? td->td_ucred : NOCRED; | ||||
ronly = (mp->mnt_flag & MNT_RDONLY) != 0; | ronly = (mp->mnt_flag & MNT_RDONLY) != 0; | ||||
▲ Show 20 Lines • Show All 274 Lines • ▼ Show 20 Lines | #ifdef UFS_EXTATTR_AUTOSTART | ||||
* an attribute of the same name. | * an attribute of the same name. | ||||
* Not clear how to report errors -- probably eat them. | * Not clear how to report errors -- probably eat them. | ||||
* This would all happen while the filesystem was busy/not | * This would all happen while the filesystem was busy/not | ||||
* available, so would effectively be "atomic". | * available, so would effectively be "atomic". | ||||
*/ | */ | ||||
(void) ufs_extattr_autostart(mp, td); | (void) ufs_extattr_autostart(mp, td); | ||||
#endif /* !UFS_EXTATTR_AUTOSTART */ | #endif /* !UFS_EXTATTR_AUTOSTART */ | ||||
#endif /* !UFS_EXTATTR */ | #endif /* !UFS_EXTATTR */ | ||||
etp = malloc(sizeof *ump->um_fsfail_task, M_UFSMNT, M_WAITOK | M_ZERO); | |||||
etp->fsid = mp->mnt_stat.f_fsid; | |||||
ump->um_fsfail_task = etp; | |||||
return (0); | return (0); | ||||
out: | out: | ||||
if (fs != NULL) { | if (fs != NULL) { | ||||
free(fs->fs_csp, M_UFSMNT); | free(fs->fs_csp, M_UFSMNT); | ||||
free(fs, M_UFSMNT); | free(fs, M_UFSMNT); | ||||
} | } | ||||
if (cp != NULL) { | if (cp != NULL) { | ||||
g_topology_lock(); | g_topology_lock(); | ||||
Show All 33 Lines | if ((error = bread((struct vnode *)devfd, btodb(loc), size, NOCRED, | ||||
&bp)) != 0) | &bp)) != 0) | ||||
return (error); | return (error); | ||||
bcopy(bp->b_data, *bufp, size); | bcopy(bp->b_data, *bufp, size); | ||||
bp->b_flags |= B_INVAL | B_NOCACHE; | bp->b_flags |= B_INVAL | B_NOCACHE; | ||||
brelse(bp); | brelse(bp); | ||||
return (0); | return (0); | ||||
} | } | ||||
#include <sys/sysctl.h> | |||||
static int bigcgs = 0; | static int bigcgs = 0; | ||||
SYSCTL_INT(_debug, OID_AUTO, bigcgs, CTLFLAG_RW, &bigcgs, 0, ""); | SYSCTL_INT(_debug, OID_AUTO, bigcgs, CTLFLAG_RW, &bigcgs, 0, ""); | ||||
/* | /* | ||||
* Sanity checks for loading old filesystem superblocks. | * Sanity checks for loading old filesystem superblocks. | ||||
* See ffs_oldfscompat_write below for unwound actions. | * See ffs_oldfscompat_write below for unwound actions. | ||||
* | * | ||||
* XXX - Parts get retired eventually. | * XXX - Parts get retired eventually. | ||||
▲ Show 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | if (susp) { | ||||
error = vfs_write_suspend_umnt(mp); | error = vfs_write_suspend_umnt(mp); | ||||
if (error != 0) | if (error != 0) | ||||
goto fail1; | goto fail1; | ||||
} | } | ||||
if (MOUNTEDSOFTDEP(mp)) | if (MOUNTEDSOFTDEP(mp)) | ||||
error = softdep_flushfiles(mp, flags, td); | error = softdep_flushfiles(mp, flags, td); | ||||
else | else | ||||
error = ffs_flushfiles(mp, flags, td); | error = ffs_flushfiles(mp, flags, td); | ||||
if (error != 0 && error != ENXIO) | if (error != 0 && !ffs_fsfail_cleanup(ump, error)) | ||||
goto fail; | goto fail; | ||||
UFS_LOCK(ump); | UFS_LOCK(ump); | ||||
if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) { | if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) { | ||||
printf("WARNING: unmount %s: pending error: blocks %jd " | printf("WARNING: unmount %s: pending error: blocks %jd " | ||||
"files %d\n", fs->fs_fsmnt, (intmax_t)fs->fs_pendingblocks, | "files %d\n", fs->fs_fsmnt, (intmax_t)fs->fs_pendingblocks, | ||||
fs->fs_pendinginodes); | fs->fs_pendinginodes); | ||||
fs->fs_pendingblocks = 0; | fs->fs_pendingblocks = 0; | ||||
fs->fs_pendinginodes = 0; | fs->fs_pendinginodes = 0; | ||||
} | } | ||||
UFS_UNLOCK(ump); | UFS_UNLOCK(ump); | ||||
if (MOUNTEDSOFTDEP(mp)) | if (MOUNTEDSOFTDEP(mp)) | ||||
softdep_unmount(mp); | softdep_unmount(mp); | ||||
if (fs->fs_ronly == 0 || ump->um_fsckpid > 0) { | if (fs->fs_ronly == 0 || ump->um_fsckpid > 0) { | ||||
fs->fs_clean = fs->fs_flags & (FS_UNCLEAN|FS_NEEDSFSCK) ? 0 : 1; | fs->fs_clean = fs->fs_flags & (FS_UNCLEAN|FS_NEEDSFSCK) ? 0 : 1; | ||||
error = ffs_sbupdate(ump, MNT_WAIT, 0); | error = ffs_sbupdate(ump, MNT_WAIT, 0); | ||||
if (error && error != ENXIO) { | if (ffs_fsfail_cleanup(ump, error)) | ||||
error = 0; | |||||
if (error != 0 && !ffs_fsfail_cleanup(ump, error)) { | |||||
fs->fs_clean = 0; | fs->fs_clean = 0; | ||||
goto fail; | goto fail; | ||||
} | } | ||||
} | } | ||||
if (susp) | if (susp) | ||||
vfs_write_resume(mp, VR_START_WRITE); | vfs_write_resume(mp, VR_START_WRITE); | ||||
if (ump->um_trim_tq != NULL) { | if (ump->um_trim_tq != NULL) { | ||||
while (ump->um_trim_inflight != 0) | while (ump->um_trim_inflight != 0) | ||||
Show All 21 Lines | #endif | ||||
dev_rel(ump->um_dev); | dev_rel(ump->um_dev); | ||||
mtx_destroy(UFS_MTX(ump)); | mtx_destroy(UFS_MTX(ump)); | ||||
if (mp->mnt_gjprovider != NULL) { | if (mp->mnt_gjprovider != NULL) { | ||||
free(mp->mnt_gjprovider, M_UFSMNT); | free(mp->mnt_gjprovider, M_UFSMNT); | ||||
mp->mnt_gjprovider = NULL; | mp->mnt_gjprovider = NULL; | ||||
} | } | ||||
free(fs->fs_csp, M_UFSMNT); | free(fs->fs_csp, M_UFSMNT); | ||||
free(fs, M_UFSMNT); | free(fs, M_UFSMNT); | ||||
if (ump->um_fsfail_task != NULL) | |||||
free(ump->um_fsfail_task, M_UFSMNT); | |||||
free(ump, M_UFSMNT); | free(ump, M_UFSMNT); | ||||
mp->mnt_data = NULL; | mp->mnt_data = NULL; | ||||
MNT_ILOCK(mp); | MNT_ILOCK(mp); | ||||
mp->mnt_flag &= ~MNT_LOCAL; | mp->mnt_flag &= ~MNT_LOCAL; | ||||
MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
if (td->td_su == mp) { | if (td->td_su == mp) { | ||||
td->td_su = NULL; | td->td_su = NULL; | ||||
vfs_rel(mp); | vfs_rel(mp); | ||||
▲ Show 20 Lines • Show All 298 Lines • ▼ Show 20 Lines | #endif | ||||
vput(vp); | vput(vp); | ||||
} | } | ||||
/* | /* | ||||
* Force stale filesystem control information to be flushed. | * Force stale filesystem control information to be flushed. | ||||
*/ | */ | ||||
if (waitfor == MNT_WAIT || rebooting) { | if (waitfor == MNT_WAIT || rebooting) { | ||||
if ((error = softdep_flushworklist(ump->um_mountp, &count, td))) | if ((error = softdep_flushworklist(ump->um_mountp, &count, td))) | ||||
allerror = error; | allerror = error; | ||||
if (ffs_fsfail_cleanup(ump, allerror)) | |||||
allerror = 0; | |||||
/* Flushed work items may create new vnodes to clean */ | /* Flushed work items may create new vnodes to clean */ | ||||
if (allerror == 0 && count) | if (allerror == 0 && count) | ||||
goto loop; | goto loop; | ||||
} | } | ||||
devvp = ump->um_devvp; | devvp = ump->um_devvp; | ||||
bo = &devvp->v_bufobj; | bo = &devvp->v_bufobj; | ||||
BO_LOCK(bo); | BO_LOCK(bo); | ||||
if (bo->bo_numoutput > 0 || bo->bo_dirty.bv_cnt > 0) { | if (bo->bo_numoutput > 0 || bo->bo_dirty.bv_cnt > 0) { | ||||
BO_UNLOCK(bo); | BO_UNLOCK(bo); | ||||
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); | vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); | ||||
error = VOP_FSYNC(devvp, waitfor, td); | error = VOP_FSYNC(devvp, waitfor, td); | ||||
VOP_UNLOCK(devvp); | VOP_UNLOCK(devvp); | ||||
if (MOUNTEDSOFTDEP(mp) && (error == 0 || error == EAGAIN)) | if (MOUNTEDSOFTDEP(mp) && (error == 0 || error == EAGAIN)) | ||||
error = ffs_sbupdate(ump, waitfor, 0); | error = ffs_sbupdate(ump, waitfor, 0); | ||||
if (error != 0) | if (error != 0) | ||||
allerror = error; | allerror = error; | ||||
if (ffs_fsfail_cleanup(ump, allerror)) | |||||
allerror = 0; | |||||
if (allerror == 0 && waitfor == MNT_WAIT) | if (allerror == 0 && waitfor == MNT_WAIT) | ||||
goto loop; | goto loop; | ||||
} else if (suspend != 0) { | } else if (suspend != 0) { | ||||
if (softdep_check_suspend(mp, | if (softdep_check_suspend(mp, | ||||
devvp, | devvp, | ||||
softdep_deps, | softdep_deps, | ||||
softdep_accdeps, | softdep_accdeps, | ||||
secondary_writes, | secondary_writes, | ||||
secondary_accwrites) != 0) { | secondary_accwrites) != 0) { | ||||
MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
goto loop; /* More work needed */ | goto loop; /* More work needed */ | ||||
} | } | ||||
mtx_assert(MNT_MTX(mp), MA_OWNED); | mtx_assert(MNT_MTX(mp), MA_OWNED); | ||||
mp->mnt_kern_flag |= MNTK_SUSPEND2 | MNTK_SUSPENDED; | mp->mnt_kern_flag |= MNTK_SUSPEND2 | MNTK_SUSPENDED; | ||||
MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
suspended = 1; | suspended = 1; | ||||
} else | } else | ||||
BO_UNLOCK(bo); | BO_UNLOCK(bo); | ||||
/* | /* | ||||
* Write back modified superblock. | * Write back modified superblock. | ||||
*/ | */ | ||||
if (fs->fs_fmod != 0 && | if (fs->fs_fmod != 0 && | ||||
(error = ffs_sbupdate(ump, waitfor, suspended)) != 0) | (error = ffs_sbupdate(ump, waitfor, suspended)) != 0) | ||||
allerror = error; | allerror = error; | ||||
if (ffs_fsfail_cleanup(ump, allerror)) | |||||
allerror = 0; | |||||
return (allerror); | return (allerror); | ||||
} | } | ||||
int | int | ||||
ffs_vget(mp, ino, flags, vpp) | ffs_vget(mp, ino, flags, vpp) | ||||
struct mount *mp; | struct mount *mp; | ||||
ino_t ino; | ino_t ino; | ||||
int flags; | int flags; | ||||
Show All 10 Lines | ffs_vgetf(mp, ino, flags, vpp, ffs_flags) | ||||
struct vnode **vpp; | struct vnode **vpp; | ||||
int ffs_flags; | int ffs_flags; | ||||
{ | { | ||||
struct fs *fs; | struct fs *fs; | ||||
struct inode *ip; | struct inode *ip; | ||||
struct ufsmount *ump; | struct ufsmount *ump; | ||||
struct buf *bp; | struct buf *bp; | ||||
struct vnode *vp; | struct vnode *vp; | ||||
daddr_t dbn; | |||||
int error; | int error; | ||||
MPASS((ffs_flags & FFSV_REPLACE) == 0 || (flags & LK_EXCLUSIVE) != 0); | MPASS((ffs_flags & FFSV_REPLACE) == 0 || (flags & LK_EXCLUSIVE) != 0); | ||||
error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); | error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
if (*vpp != NULL) { | if (*vpp != NULL) { | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | if (*vpp != NULL) { | ||||
* inode must be not re-inserted on the hash by other | * inode must be not re-inserted on the hash by other | ||||
* thread, after removal by us at the beginning. | * thread, after removal by us at the beginning. | ||||
*/ | */ | ||||
MPASS((ffs_flags & FFSV_REPLACE) == 0); | MPASS((ffs_flags & FFSV_REPLACE) == 0); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* Read in the disk contents for the inode, copy into the inode. */ | /* Read in the disk contents for the inode, copy into the inode. */ | ||||
error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), | dbn = fsbtodb(fs, ino_to_fsba(fs, ino)); | ||||
(int)fs->fs_bsize, NOCRED, &bp); | error = ffs_breadz(ump, ump->um_devvp, dbn, dbn, (int)fs->fs_bsize, | ||||
if (error) { | NULL, NULL, 0, NOCRED, 0, NULL, &bp); | ||||
if (error != 0) { | |||||
/* | /* | ||||
* The inode does not contain anything useful, so it would | * The inode does not contain anything useful, so it would | ||||
* be misleading to leave it on its hash chain. With mode | * be misleading to leave it on its hash chain. With mode | ||||
* still zero, it will be unlinked and returned to the free | * still zero, it will be unlinked and returned to the free | ||||
* list by vput(). | * list by vput(). | ||||
*/ | */ | ||||
vgone(vp); | vgone(vp); | ||||
vput(vp); | vput(vp); | ||||
▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | if (loc != fs->fs_sblockloc) { | ||||
else if ((error = bwrite(bp)) != 0) | else if ((error = bwrite(bp)) != 0) | ||||
devfdp->error = error; | devfdp->error = error; | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Writing the superblock itself. We need to do special checks for it. | * Writing the superblock itself. We need to do special checks for it. | ||||
*/ | */ | ||||
bp = devfdp->sbbp; | bp = devfdp->sbbp; | ||||
if (ffs_fsfail_cleanup(ump, devfdp->error)) | |||||
devfdp->error = 0; | |||||
if (devfdp->error != 0) { | if (devfdp->error != 0) { | ||||
brelse(bp); | brelse(bp); | ||||
return (devfdp->error); | return (devfdp->error); | ||||
} | } | ||||
if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_sblockloc != SBLOCK_UFS1 && | if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_sblockloc != SBLOCK_UFS1 && | ||||
(fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) { | (fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) { | ||||
printf("WARNING: %s: correcting fs_sblockloc from %jd to %d\n", | printf("WARNING: %s: correcting fs_sblockloc from %jd to %d\n", | ||||
fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS1); | fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS1); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
* Complete a background write started from bwrite. | * Complete a background write started from bwrite. | ||||
*/ | */ | ||||
static void | static void | ||||
ffs_backgroundwritedone(struct buf *bp) | ffs_backgroundwritedone(struct buf *bp) | ||||
{ | { | ||||
struct bufobj *bufobj; | struct bufobj *bufobj; | ||||
struct buf *origbp; | struct buf *origbp; | ||||
#ifdef SOFTUPDATES | |||||
if (!LIST_EMPTY(&bp->b_dep) && (bp->b_ioflags & BIO_ERROR) != 0) | |||||
softdep_handle_error(bp); | |||||
#endif | |||||
/* | /* | ||||
* Find the original buffer that we are writing. | * Find the original buffer that we are writing. | ||||
*/ | */ | ||||
bufobj = bp->b_bufobj; | bufobj = bp->b_bufobj; | ||||
BO_LOCK(bufobj); | BO_LOCK(bufobj); | ||||
if ((origbp = gbincore(bp->b_bufobj, bp->b_lblkno)) == NULL) | if ((origbp = gbincore(bp->b_bufobj, bp->b_lblkno)) == NULL) | ||||
panic("backgroundwritedone: lost buffer"); | panic("backgroundwritedone: lost buffer"); | ||||
/* | /* | ||||
* We should mark the cylinder group buffer origbp as | * We should mark the cylinder group buffer origbp as | ||||
* dirty, to not loose the failed write. | * dirty, to not lose the failed write. | ||||
*/ | */ | ||||
if ((bp->b_ioflags & BIO_ERROR) != 0) | if ((bp->b_ioflags & BIO_ERROR) != 0) | ||||
origbp->b_vflags |= BV_BKGRDERR; | origbp->b_vflags |= BV_BKGRDERR; | ||||
BO_UNLOCK(bufobj); | BO_UNLOCK(bufobj); | ||||
/* | /* | ||||
* Process dependencies then return any unfinished ones. | * Process dependencies then return any unfinished ones. | ||||
*/ | */ | ||||
if (!LIST_EMPTY(&bp->b_dep) && (bp->b_ioflags & BIO_ERROR) == 0) | if (!LIST_EMPTY(&bp->b_dep) && (bp->b_ioflags & BIO_ERROR) == 0) | ||||
▲ Show 20 Lines • Show All 254 Lines • ▼ Show 20 Lines | #endif | ||||
default: | default: | ||||
printf("multiple buffer types 0x%b\n", | printf("multiple buffer types 0x%b\n", | ||||
(u_int)(bp->b_xflags & BX_FSPRIV), | (u_int)(bp->b_xflags & BX_FSPRIV), | ||||
PRINT_UFS_BUF_XFLAGS); | PRINT_UFS_BUF_XFLAGS); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (bp->b_iocmd != BIO_READ && ffs_enxio_enable) | |||||
bp->b_xflags |= BX_CVTENXIO; | |||||
g_vfs_strategy(bo, bp); | g_vfs_strategy(bo, bp); | ||||
} | } | ||||
int | int | ||||
ffs_own_mount(const struct mount *mp) | ffs_own_mount(const struct mount *mp) | ||||
{ | { | ||||
if (mp->mnt_op == &ufs_vfsops) | if (mp->mnt_op == &ufs_vfsops) | ||||
Show All 29 Lines |
Use CTLFLAG_RWTUN instead of separate TUNABLE_INT ?