version 1.31.6.1, 2006/10/22 06:07:50 |
version 1.31.6.2, 2006/12/10 07:19:32 |
Line 42 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 42 __KERNEL_RCSID(0, "$NetBSD$"); |
|
|
|
#if defined(_KERNEL_OPT) |
#if defined(_KERNEL_OPT) |
#include "opt_ffs.h" |
#include "opt_ffs.h" |
|
#include "opt_quota.h" |
#endif |
#endif |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
Line 110 static int snapacct_ufs2(struct vnode *, |
|
Line 111 static int snapacct_ufs2(struct vnode *, |
|
struct fs *, ufs_lbn_t, int); |
struct fs *, ufs_lbn_t, int); |
static int mapacct_ufs2(struct vnode *, ufs2_daddr_t *, ufs2_daddr_t *, |
static int mapacct_ufs2(struct vnode *, ufs2_daddr_t *, ufs2_daddr_t *, |
struct fs *, ufs_lbn_t, int); |
struct fs *, ufs_lbn_t, int); |
|
static int readvnblk(struct vnode *, caddr_t, ufs2_daddr_t); |
#endif /* !defined(FFS_NO_SNAPSHOT) */ |
#endif /* !defined(FFS_NO_SNAPSHOT) */ |
|
|
static int ffs_copyonwrite(void *, struct buf *); |
static int ffs_copyonwrite(void *, struct buf *); |
static int readfsblk(struct vnode *, caddr_t, ufs2_daddr_t); |
static int readfsblk(struct vnode *, caddr_t, ufs2_daddr_t); |
static int __unused readvnblk(struct vnode *, caddr_t, ufs2_daddr_t); |
|
static int writevnblk(struct vnode *, caddr_t, ufs2_daddr_t); |
static int writevnblk(struct vnode *, caddr_t, ufs2_daddr_t); |
static inline int cow_enter(void); |
static inline int cow_enter(void); |
static inline void cow_leave(int); |
static inline void cow_leave(int); |
Line 132 static int snapdebug = 0; |
|
Line 133 static int snapdebug = 0; |
|
* Vnode is locked on entry and return. |
* Vnode is locked on entry and return. |
*/ |
*/ |
int |
int |
ffs_snapshot(struct mount *mp __unused, struct vnode *vp __unused, |
ffs_snapshot(struct mount *mp, struct vnode *vp, |
struct timespec *ctime __unused) |
struct timespec *ctime) |
{ |
{ |
#if defined(FFS_NO_SNAPSHOT) |
#if defined(FFS_NO_SNAPSHOT) |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
Line 158 ffs_snapshot(struct mount *mp __unused, |
|
Line 159 ffs_snapshot(struct mount *mp __unused, |
|
struct inode *ip, *xp; |
struct inode *ip, *xp; |
struct buf *bp, *ibp, *nbp; |
struct buf *bp, *ibp, *nbp; |
struct vattr vat; |
struct vattr vat; |
struct vnode *xvp, *devvp; |
struct vnode *xvp, *nvp, *devvp; |
|
|
ns = UFS_FSNEEDSWAP(fs); |
ns = UFS_FSNEEDSWAP(fs); |
/* |
/* |
Line 186 ffs_snapshot(struct mount *mp __unused, |
|
Line 187 ffs_snapshot(struct mount *mp __unused, |
|
VTOI(vp)->i_uid != kauth_cred_geteuid(l->l_cred)) |
VTOI(vp)->i_uid != kauth_cred_geteuid(l->l_cred)) |
return EACCES; |
return EACCES; |
|
|
|
#ifdef QUOTA |
|
if ((error = getinoquota(VTOI(vp))) != 0) |
|
return error; |
|
#endif |
if (vp->v_size != 0) { |
if (vp->v_size != 0) { |
error = ffs_truncate(vp, 0, 0, NOCRED, l); |
error = ffs_truncate(vp, 0, 0, NOCRED, l); |
if (error) |
if (error) |
Line 363 ffs_snapshot(struct mount *mp __unused, |
|
Line 368 ffs_snapshot(struct mount *mp __unused, |
|
FSMAXSNAP + 1 /* superblock */ + 1 /* last block */ + 1 /* size */; |
FSMAXSNAP + 1 /* superblock */ + 1 /* last block */ + 1 /* size */; |
MNT_ILOCK(mp); |
MNT_ILOCK(mp); |
loop: |
loop: |
TAILQ_FOREACH(xvp, &mp->mnt_vnodelist, v_mntvnodes) { |
/* |
|
* NOTE: not using the TAILQ_FOREACH here since in this loop vgone() |
|
* and vclean() can be called indirectly |
|
*/ |
|
for (xvp = TAILQ_FIRST(&mp->mnt_vnodelist); xvp; xvp = nvp) { |
/* |
/* |
* Make sure this vnode wasn't reclaimed in getnewvnode(). |
* Make sure this vnode wasn't reclaimed in getnewvnode(). |
* Start over if it has (it won't be on the list anymore). |
* Start over if it has (it won't be on the list anymore). |
|
|
if (xvp->v_mount != mp) |
if (xvp->v_mount != mp) |
goto loop; |
goto loop; |
VI_LOCK(xvp); |
VI_LOCK(xvp); |
|
nvp = TAILQ_NEXT(xvp, v_mntvnodes); |
MNT_IUNLOCK(mp); |
MNT_IUNLOCK(mp); |
if ((xvp->v_flag & VXLOCK) || |
if ((xvp->v_flag & VXLOCK) || |
xvp->v_usecount == 0 || xvp->v_type == VNON || |
xvp->v_usecount == 0 || xvp->v_type == VNON || |
Line 957 fullacct_ufs1(struct vnode *vp, ufs1_dad |
|
Line 967 fullacct_ufs1(struct vnode *vp, ufs1_dad |
|
*/ |
*/ |
static int |
static int |
snapacct_ufs1(struct vnode *vp, ufs1_daddr_t *oldblkp, ufs1_daddr_t *lastblkp, |
snapacct_ufs1(struct vnode *vp, ufs1_daddr_t *oldblkp, ufs1_daddr_t *lastblkp, |
struct fs *fs, ufs_lbn_t lblkno __unused, |
struct fs *fs, ufs_lbn_t lblkno, |
int expungetype /* BLK_SNAP or BLK_NOCOPY */) |
int expungetype /* BLK_SNAP or BLK_NOCOPY */) |
{ |
{ |
struct inode *ip = VTOI(vp); |
struct inode *ip = VTOI(vp); |
Line 1225 fullacct_ufs2(struct vnode *vp, ufs2_dad |
|
Line 1235 fullacct_ufs2(struct vnode *vp, ufs2_dad |
|
*/ |
*/ |
static int |
static int |
snapacct_ufs2(struct vnode *vp, ufs2_daddr_t *oldblkp, ufs2_daddr_t *lastblkp, |
snapacct_ufs2(struct vnode *vp, ufs2_daddr_t *oldblkp, ufs2_daddr_t *lastblkp, |
struct fs *fs, ufs_lbn_t lblkno __unused, |
struct fs *fs, ufs_lbn_t lblkno, |
int expungetype /* BLK_SNAP or BLK_NOCOPY */) |
int expungetype /* BLK_SNAP or BLK_NOCOPY */) |
{ |
{ |
struct inode *ip = VTOI(vp); |
struct inode *ip = VTOI(vp); |
Line 1462 ffs_snapremove(struct vnode *vp) |
|
Line 1472 ffs_snapremove(struct vnode *vp) |
|
*/ |
*/ |
int |
int |
ffs_snapblkfree(struct fs *fs, struct vnode *devvp, ufs2_daddr_t bno, |
ffs_snapblkfree(struct fs *fs, struct vnode *devvp, ufs2_daddr_t bno, |
long size, ino_t inum __unused) |
long size, ino_t inum) |
{ |
{ |
struct ufsmount *ump = VFSTOUFS(devvp->v_specmountpoint); |
struct ufsmount *ump = VFSTOUFS(devvp->v_specmountpoint); |
struct buf *ibp; |
struct buf *ibp; |
Line 2010 readfsblk(struct vnode *vp, caddr_t data |
|
Line 2020 readfsblk(struct vnode *vp, caddr_t data |
|
return error; |
return error; |
} |
} |
|
|
|
#if !defined(FFS_NO_SNAPSHOT) |
/* |
/* |
* Read the specified block. Bypass UBC to prevent deadlocks. |
* Read the specified block. Bypass UBC to prevent deadlocks. |
*/ |
*/ |
Line 2042 readvnblk(struct vnode *vp, caddr_t data |
|
Line 2053 readvnblk(struct vnode *vp, caddr_t data |
|
|
|
return 0; |
return 0; |
} |
} |
|
#endif /* !defined(FFS_NO_SNAPSHOT) */ |
|
|
/* |
/* |
* Write the specified block. Bypass UBC to prevent deadlocks. |
* Write the specified block. Bypass UBC to prevent deadlocks. |