Complete the separation of ext2fs from ufs by copying the remaining
shared code and converting all ufs references. Originally it may have made sense to share common features between the two filesystems, but recently it has only caused problems, the UFS2 work being the final straw. All UFS_* indirect calls are now direct calls to ext2_* functions, and ext2fs-specific mount and inode structures have been introduced.
This commit is contained in:
parent
d99142426b
commit
9504abaad7
@ -732,6 +732,8 @@ geom/geom_sunlabel.c optional geom
|
||||
gnu/ext2fs/ext2_alloc.c optional ext2fs \
|
||||
warning "kernel contains GPL contaminated ext2fs file system"
|
||||
gnu/ext2fs/ext2_balloc.c optional ext2fs
|
||||
gnu/ext2fs/ext2_bmap.c optional ext2fs
|
||||
gnu/ext2fs/ext2_ihash.c optional ext2fs
|
||||
gnu/ext2fs/ext2_inode.c optional ext2fs
|
||||
gnu/ext2fs/ext2_inode_cnv.c optional ext2fs
|
||||
gnu/ext2fs/ext2_linux_balloc.c optional ext2fs
|
||||
|
@ -40,8 +40,6 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_quota.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
@ -50,11 +48,8 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
@ -108,9 +103,6 @@ ext2_alloc(ip, lbn, bpref, size, cred, bnp)
|
||||
{
|
||||
register struct ext2_sb_info *fs;
|
||||
daddr_t bno;
|
||||
#if QUOTA
|
||||
int error;
|
||||
#endif
|
||||
|
||||
*bnp = 0;
|
||||
fs = ip->i_e2fs;
|
||||
@ -128,10 +120,6 @@ ext2_alloc(ip, lbn, bpref, size, cred, bnp)
|
||||
if (cred->cr_uid != 0 &&
|
||||
fs->s_es->s_free_blocks_count < fs->s_es->s_r_blocks_count)
|
||||
goto nospace;
|
||||
#if QUOTA
|
||||
if ((error = chkdq(ip, (long)btodb(size), cred, 0)) != 0)
|
||||
return (error);
|
||||
#endif
|
||||
if (bpref >= fs->s_es->s_blocks_count)
|
||||
bpref = 0;
|
||||
/* call the Linux code */
|
||||
@ -179,12 +167,6 @@ ext2_alloc(ip, lbn, bpref, size, cred, bnp)
|
||||
*bnp = bno;
|
||||
return (0);
|
||||
}
|
||||
#if QUOTA
|
||||
/*
|
||||
* Restore user's disk quota because allocation failed.
|
||||
*/
|
||||
(void) chkdq(ip, (long)-btodb(size), cred, FORCE);
|
||||
#endif
|
||||
nospace:
|
||||
ext2_fserr(fs, cred->cr_uid, "file system full");
|
||||
uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);
|
||||
@ -342,7 +324,7 @@ return ENOSPC;
|
||||
} else {
|
||||
ip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
if (!doasyncfree)
|
||||
UFS_UPDATE(vp, 1);
|
||||
ext2_update(vp, 1);
|
||||
}
|
||||
if (ssize < len)
|
||||
if (doasyncfree)
|
||||
@ -401,7 +383,7 @@ ext2_valloc(pvp, mode, cred, vpp)
|
||||
goto noinodes;
|
||||
error = VFS_VGET(pvp->v_mount, ino, LK_EXCLUSIVE, vpp);
|
||||
if (error) {
|
||||
UFS_VFREE(pvp, ino, mode);
|
||||
ext2_vfree(pvp, ino, mode);
|
||||
return (error);
|
||||
}
|
||||
ip = VTOI(*vpp);
|
||||
|
@ -48,10 +48,7 @@
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufs_extern.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
@ -164,11 +161,11 @@ ext2_debug("ext2_balloc called (%d, %d, %d)\n",
|
||||
* Determine the number of levels of indirection.
|
||||
*/
|
||||
pref = 0;
|
||||
if ((error = ufs_getlbns(vp, bn, indirs, &num)) != 0)
|
||||
if ((error = ext2_getlbns(vp, bn, indirs, &num)) != 0)
|
||||
return(error);
|
||||
#if DIAGNOSTIC
|
||||
if (num < 1)
|
||||
panic ("ext2_balloc: ufs_getlbns returned indirect block");
|
||||
panic ("ext2_balloc: ext2_getlbns returned indirect block");
|
||||
#endif
|
||||
/*
|
||||
* Fetch the first indirect block allocating if necessary.
|
||||
|
@ -43,8 +43,8 @@
|
||||
#ifndef _SYS_GNU_EXT2FS_EXT2_EXTERN_H_
|
||||
#define _SYS_GNU_EXT2FS_EXT2_EXTERN_H_
|
||||
|
||||
struct dinode;
|
||||
struct ext2_inode;
|
||||
struct indir;
|
||||
struct inode;
|
||||
struct mount;
|
||||
struct vfsconf;
|
||||
@ -58,7 +58,18 @@ int ext2_blkatoff(struct vnode *, off_t, char **, struct buf **);
|
||||
void ext2_blkfree(struct inode *, daddr_t, long);
|
||||
daddr_t ext2_blkpref(struct inode *, daddr_t, int, daddr_t *, daddr_t);
|
||||
int ext2_bmap(struct vop_bmap_args *);
|
||||
int ext2_init(struct vfsconf *);
|
||||
int ext2_bmaparray(struct vnode *, daddr_t, daddr_t *, int *, int *);
|
||||
void ext2_dirbad(struct inode *ip, doff_t offset, char *how);
|
||||
void ext2_ei2i(struct ext2_inode *, struct inode *);
|
||||
int ext2_getlbns(struct vnode *, daddr_t, struct indir *, int *);
|
||||
void ext2_i2ei(struct inode *, struct ext2_inode *);
|
||||
int ext2_ihashget(dev_t, ino_t, int, struct vnode **);
|
||||
void ext2_ihashinit(void);
|
||||
void ext2_ihashins(struct inode *);
|
||||
struct vnode *
|
||||
ext2_ihashlookup(dev_t, ino_t);
|
||||
void ext2_ihashrem(struct inode *);
|
||||
void ext2_itimes(struct vnode *vp);
|
||||
int ext2_reallocblks(struct vop_reallocblks_args *);
|
||||
int ext2_reclaim(struct vop_reclaim_args *);
|
||||
void ext2_setblock(struct ext2_sb_info *, u_char *, daddr_t);
|
||||
@ -66,9 +77,9 @@ int ext2_truncate(struct vnode *, off_t, int, struct ucred *, struct thread *);
|
||||
int ext2_update(struct vnode *, int);
|
||||
int ext2_valloc(struct vnode *, int, struct ucred *, struct vnode **);
|
||||
int ext2_vfree(struct vnode *, ino_t, int);
|
||||
int ext2_vinit(struct mount *, vop_t **, vop_t **, struct vnode **vpp);
|
||||
int ext2_lookup(struct vop_cachedlookup_args *);
|
||||
int ext2_readdir(struct vop_readdir_args *);
|
||||
void ext2_print_dinode(struct dinode *);
|
||||
void ext2_print_inode(struct inode *);
|
||||
int ext2_direnter(struct inode *,
|
||||
struct vnode *, struct componentname *);
|
||||
@ -89,15 +100,13 @@ unsigned long ext2_count_free(struct buf *map, unsigned int numchars);
|
||||
void ext2_free_blocks(struct mount *mp, unsigned long block,
|
||||
unsigned long count);
|
||||
void ext2_free_inode(struct inode * inode);
|
||||
void ext2_ei2di(struct ext2_inode *ei, struct dinode *di);
|
||||
void ext2_di2ei(struct dinode *di, struct ext2_inode *ei);
|
||||
void mark_buffer_dirty(struct buf *bh);
|
||||
|
||||
/*
|
||||
* This macro allows the ufs code to distinguish between an EXT2 and a
|
||||
* non-ext2(FFS/LFS) vnode.
|
||||
*/
|
||||
#define IS_EXT2_VNODE(vp) (vp->v_mount->mnt_stat.f_type == MOUNT_EXT2FS)
|
||||
/* Flags to low-level allocation routines. */
|
||||
#define B_CLRBUF 0x01 /* Request allocated buffer be cleared. */
|
||||
#define B_SYNC 0x02 /* Do all allocations synchronously. */
|
||||
#define B_METAONLY 0x04 /* Return indirect block buffer. */
|
||||
#define B_NOWAIT 0x08 /* do not sleep to await lock */
|
||||
|
||||
extern vop_t **ext2_vnodeop_p;
|
||||
extern vop_t **ext2_specop_p;
|
||||
|
@ -38,19 +38,6 @@
|
||||
#define umode_t mode_t
|
||||
#define loff_t off_t
|
||||
|
||||
/* the Linux implementation of EXT2 stores some information about
|
||||
* an inode in a ext2_inode_info structure which is part of the incore
|
||||
* inode in Linux
|
||||
* I decided to use the "spare" fields instead - we'll see how this
|
||||
* works out
|
||||
*/
|
||||
|
||||
#define i_block_group i_spare[0]
|
||||
#define i_next_alloc_block i_spare[1]
|
||||
#define i_next_alloc_goal i_spare[2]
|
||||
#define i_prealloc_block i_din.di_spare[0]
|
||||
#define i_prealloc_count i_din.di_spare[1]
|
||||
|
||||
/*
|
||||
* The second extended filesystem constants/structures
|
||||
*/
|
||||
@ -263,14 +250,6 @@ struct ext2_group_desc
|
||||
#define EXT2_IOC_GETVERSION _IOR('v', 1, long)
|
||||
#define EXT2_IOC_SETVERSION _IOW('v', 2, long)
|
||||
|
||||
/*
|
||||
* Only declare `struct ext2_inode' if <ufs/ufs/inode.h> hasn't made things
|
||||
* difficult by #defining i_mode and other struct members. The details of
|
||||
* the struct are only needed in ext2_inode_cnv.c where the ext2fs on-disk
|
||||
* inode is converted to a ufs in-core inode.
|
||||
*/
|
||||
#ifndef i_mode
|
||||
|
||||
/*
|
||||
* Structure of an inode on the disk
|
||||
*/
|
||||
@ -351,8 +330,6 @@ struct ext2_inode {
|
||||
#define i_reserved2 osd2.masix2.m_i_reserved2
|
||||
#endif
|
||||
|
||||
#endif /* i_mode */
|
||||
|
||||
/*
|
||||
* File system states
|
||||
*/
|
||||
|
@ -40,8 +40,6 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_quota.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
@ -53,12 +51,8 @@
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <ufs/ufs/ufs_extern.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
@ -67,12 +61,6 @@
|
||||
static int ext2_indirtrunc(struct inode *, daddr_t, daddr_t, daddr_t, int,
|
||||
long *);
|
||||
|
||||
int
|
||||
ext2_init(struct vfsconf *vfsp)
|
||||
{
|
||||
return (ufs_init(vfsp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the access, modified, and inode change times as specified by the
|
||||
* IN_ACCESS, IN_UPDATE, and IN_CHANGE flags respectively. Write the inode
|
||||
@ -92,7 +80,7 @@ ext2_update(vp, waitfor)
|
||||
struct inode *ip;
|
||||
int error;
|
||||
|
||||
ufs_itimes(vp);
|
||||
ext2_itimes(vp);
|
||||
ip = VTOI(vp);
|
||||
if ((ip->i_flag & IN_MODIFIED) == 0)
|
||||
return (0);
|
||||
@ -106,8 +94,8 @@ ext2_update(vp, waitfor)
|
||||
brelse(bp);
|
||||
return (error);
|
||||
}
|
||||
ext2_di2ei( &ip->i_din, (struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE *
|
||||
ino_to_fsbo(fs, ip->i_number)));
|
||||
ext2_i2ei(ip, (struct ext2_inode *)((char *)bp->b_data +
|
||||
EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)));
|
||||
/*
|
||||
if (waitfor && (vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
|
||||
return (bwrite(bp));
|
||||
@ -166,16 +154,12 @@ printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length);
|
||||
bzero((char *)&oip->i_shortlink, (u_int)oip->i_size);
|
||||
oip->i_size = 0;
|
||||
oip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
return (UFS_UPDATE(ovp, 1));
|
||||
return (ext2_update(ovp, 1));
|
||||
}
|
||||
if (oip->i_size == length) {
|
||||
oip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
return (UFS_UPDATE(ovp, 0));
|
||||
return (ext2_update(ovp, 0));
|
||||
}
|
||||
#if QUOTA
|
||||
if ((error = getinoquota(oip)) != 0)
|
||||
return (error);
|
||||
#endif
|
||||
fs = oip->i_e2fs;
|
||||
osize = oip->i_size;
|
||||
ext2_discard_prealloc(oip);
|
||||
@ -200,7 +184,7 @@ printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length);
|
||||
else
|
||||
bawrite(bp);
|
||||
oip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
return (UFS_UPDATE(ovp, 1));
|
||||
return (ext2_update(ovp, 1));
|
||||
}
|
||||
/*
|
||||
* Shorten the size of the file. If the file is not being
|
||||
@ -256,7 +240,7 @@ printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length);
|
||||
for (i = NDADDR - 1; i > lastblock; i--)
|
||||
oip->i_db[i] = 0;
|
||||
oip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
allerror = UFS_UPDATE(ovp, 1);
|
||||
allerror = ext2_update(ovp, 1);
|
||||
|
||||
/*
|
||||
* Having written the new inode to disk, save its new configuration
|
||||
@ -361,9 +345,6 @@ done:
|
||||
oip->i_blocks = 0;
|
||||
oip->i_flag |= IN_CHANGE;
|
||||
vnode_pager_setsize(ovp, length);
|
||||
#if QUOTA
|
||||
(void) chkdq(oip, -blocksreleased, NOCRED, 0);
|
||||
#endif
|
||||
return (allerror);
|
||||
}
|
||||
|
||||
@ -488,9 +469,86 @@ int
|
||||
ext2_inactive(ap)
|
||||
struct vop_inactive_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
ext2_discard_prealloc(VTOI(ap->a_vp));
|
||||
return ufs_inactive(ap);
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct inode *ip = VTOI(vp);
|
||||
struct thread *td = ap->a_td;
|
||||
int mode, error = 0;
|
||||
|
||||
ext2_discard_prealloc(ip);
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("ext2_inactive: pushing active", vp);
|
||||
|
||||
/*
|
||||
* Ignore inodes related to stale file handles.
|
||||
*/
|
||||
if (ip->i_mode == 0)
|
||||
goto out;
|
||||
if (ip->i_nlink <= 0) {
|
||||
(void) vn_write_suspend_wait(vp, NULL, V_WAIT);
|
||||
error = ext2_truncate(vp, (off_t)0, 0, NOCRED, td);
|
||||
ip->i_rdev = 0;
|
||||
mode = ip->i_mode;
|
||||
ip->i_mode = 0;
|
||||
ip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
ext2_vfree(vp, ip->i_number, mode);
|
||||
}
|
||||
if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) {
|
||||
if ((ip->i_flag & (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) == 0 &&
|
||||
vn_write_suspend_wait(vp, NULL, V_NOWAIT)) {
|
||||
ip->i_flag &= ~IN_ACCESS;
|
||||
} else {
|
||||
(void) vn_write_suspend_wait(vp, NULL, V_WAIT);
|
||||
ext2_update(vp, 0);
|
||||
}
|
||||
}
|
||||
out:
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
/*
|
||||
* If we are done with the inode, reclaim it
|
||||
* so that it can be reused immediately.
|
||||
*/
|
||||
if (ip->i_mode == 0)
|
||||
vrecycle(vp, NULL, td);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim an inode so that it can be used for other purposes.
|
||||
*/
|
||||
int
|
||||
ext2_reclaim(ap)
|
||||
struct vop_reclaim_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct inode *ip;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("ufs_reclaim: pushing active", vp);
|
||||
ip = VTOI(vp);
|
||||
if (ip->i_flag & IN_LAZYMOD) {
|
||||
ip->i_flag |= IN_MODIFIED;
|
||||
ext2_update(vp, 0);
|
||||
}
|
||||
/*
|
||||
* Remove the inode from its hash chain.
|
||||
*/
|
||||
ext2_ihashrem(ip);
|
||||
/*
|
||||
* Purge old data structures associated with the inode.
|
||||
*/
|
||||
cache_purge(vp);
|
||||
if (ip->i_devvp) {
|
||||
vrele(ip->i_devvp);
|
||||
ip->i_devvp = 0;
|
||||
}
|
||||
lockdestroy(&vp->v_lock);
|
||||
FREE(vp->v_data, M_EXT2NODE);
|
||||
vp->v_data = 0;
|
||||
return (0);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* routines to convert on disk ext2 inodes in dinodes and back
|
||||
* routines to convert on disk ext2 inodes into inodes and back
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -31,130 +31,101 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
|
||||
/*
|
||||
* Undo the definitions in <ufs/ufs/inode.h> that would destroy the include
|
||||
* of <gnu/ext2fs/ext2_fs.h>.
|
||||
*/
|
||||
#undef i_atime
|
||||
#undef i_blocks
|
||||
#undef i_ctime
|
||||
#undef i_db
|
||||
#undef i_flags
|
||||
#undef i_gen
|
||||
#undef i_gid
|
||||
#undef i_ib
|
||||
#undef i_mode
|
||||
#undef i_mtime
|
||||
#undef i_nlink
|
||||
#undef i_rdev
|
||||
#undef i_shortlink
|
||||
#undef i_size
|
||||
#undef i_uid
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
|
||||
void
|
||||
ext2_print_dinode( di )
|
||||
struct dinode *di;
|
||||
{
|
||||
int i;
|
||||
printf( /* "Inode: %5d" */
|
||||
" Type: %10s Mode: 0x%o Flags: 0x%x Version: %d\n",
|
||||
"n/a", di->di_mode, di->di_flags, di->di_gen);
|
||||
printf( "User: %5lu Group: %5lu Size: %lu\n",
|
||||
(unsigned long)di->di_uid, (unsigned long)di->di_gid,
|
||||
(unsigned long)di->di_size);
|
||||
printf( "Links: %3d Blockcount: %d\n",
|
||||
di->di_nlink, di->di_blocks);
|
||||
printf( "ctime: 0x%x", di->di_ctime);
|
||||
printf( "atime: 0x%x", di->di_atime);
|
||||
printf( "mtime: 0x%x", di->di_mtime);
|
||||
printf( "BLOCKS: ");
|
||||
for(i=0; i < (di->di_blocks <= 24 ? ((di->di_blocks+1)/2): 12); i++)
|
||||
printf("%d ", di->di_db[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
ext2_print_inode( in )
|
||||
struct inode *in;
|
||||
{
|
||||
int i;
|
||||
|
||||
printf( "Inode: %5d", in->i_number);
|
||||
ext2_print_dinode(&in->i_din);
|
||||
printf( /* "Inode: %5d" */
|
||||
" Type: %10s Mode: 0x%o Flags: 0x%x Version: %d\n",
|
||||
"n/a", in->i_mode, in->i_flags, in->i_gen);
|
||||
printf( "User: %5lu Group: %5lu Size: %lu\n",
|
||||
(unsigned long)in->i_uid, (unsigned long)in->i_gid,
|
||||
(unsigned long)in->i_size);
|
||||
printf( "Links: %3d Blockcount: %d\n",
|
||||
in->i_nlink, in->i_blocks);
|
||||
printf( "ctime: 0x%x", in->i_ctime);
|
||||
printf( "atime: 0x%x", in->i_atime);
|
||||
printf( "mtime: 0x%x", in->i_mtime);
|
||||
printf( "BLOCKS: ");
|
||||
for(i=0; i < (in->i_blocks <= 24 ? ((in->i_blocks+1)/2): 12); i++)
|
||||
printf("%d ", in->i_db[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* raw ext2 inode to dinode
|
||||
* raw ext2 inode to inode
|
||||
*/
|
||||
void
|
||||
ext2_ei2di(ei, di)
|
||||
struct ext2_inode *ei;
|
||||
struct dinode *di;
|
||||
ext2_ei2i(ei, ip)
|
||||
struct ext2_inode *ei;
|
||||
struct inode *ip;
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
di->di_nlink = ei->i_links_count;
|
||||
ip->i_nlink = ei->i_links_count;
|
||||
/* Godmar thinks - if the link count is zero, then the inode is
|
||||
unused - according to ext2 standards. Ufs marks this fact
|
||||
by setting i_mode to zero - why ?
|
||||
I can see that this might lead to problems in an undelete.
|
||||
*/
|
||||
di->di_mode = ei->i_links_count ? ei->i_mode : 0;
|
||||
di->di_size = ei->i_size;
|
||||
di->di_atime = ei->i_atime;
|
||||
di->di_mtime = ei->i_mtime;
|
||||
di->di_ctime = ei->i_ctime;
|
||||
di->di_flags = 0;
|
||||
di->di_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0;
|
||||
di->di_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0;
|
||||
di->di_blocks = ei->i_blocks;
|
||||
di->di_gen = ei->i_generation;
|
||||
di->di_uid = ei->i_uid;
|
||||
di->di_gid = ei->i_gid;
|
||||
ip->i_mode = ei->i_links_count ? ei->i_mode : 0;
|
||||
ip->i_size = ei->i_size;
|
||||
ip->i_atime = ei->i_atime;
|
||||
ip->i_mtime = ei->i_mtime;
|
||||
ip->i_ctime = ei->i_ctime;
|
||||
ip->i_flags = 0;
|
||||
ip->i_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0;
|
||||
ip->i_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0;
|
||||
ip->i_blocks = ei->i_blocks;
|
||||
ip->i_gen = ei->i_generation;
|
||||
ip->i_uid = ei->i_uid;
|
||||
ip->i_gid = ei->i_gid;
|
||||
/* XXX use memcpy */
|
||||
for(i = 0; i < NDADDR; i++)
|
||||
di->di_db[i] = ei->i_block[i];
|
||||
for(i = 0; i < NIADDR; i++)
|
||||
di->di_ib[i] = ei->i_block[EXT2_NDIR_BLOCKS + i];
|
||||
for(i = 0; i < NDADDR; i++)
|
||||
ip->i_db[i] = ei->i_block[i];
|
||||
for(i = 0; i < NIADDR; i++)
|
||||
ip->i_ib[i] = ei->i_block[EXT2_NDIR_BLOCKS + i];
|
||||
}
|
||||
|
||||
/*
|
||||
* dinode to raw ext2 inode
|
||||
* inode to raw ext2 inode
|
||||
*/
|
||||
void
|
||||
ext2_di2ei(di, ei)
|
||||
struct dinode *di;
|
||||
struct ext2_inode *ei;
|
||||
ext2_i2ei(ip, ei)
|
||||
struct inode *ip;
|
||||
struct ext2_inode *ei;
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
ei->i_mode = di->di_mode;
|
||||
ei->i_links_count = di->di_nlink;
|
||||
ei->i_mode = ip->i_mode;
|
||||
ei->i_links_count = ip->i_nlink;
|
||||
/*
|
||||
Godmar thinks: if dtime is nonzero, ext2 says this inode
|
||||
has been deleted, this would correspond to a zero link count
|
||||
*/
|
||||
ei->i_dtime = ei->i_links_count ? 0 : di->di_mtime;
|
||||
ei->i_size = di->di_size;
|
||||
ei->i_atime = di->di_atime;
|
||||
ei->i_mtime = di->di_mtime;
|
||||
ei->i_ctime = di->di_ctime;
|
||||
ei->i_flags = di->di_flags;
|
||||
ei->i_flags = 0;
|
||||
ei->i_flags |= (di->di_flags & APPEND) ? EXT2_APPEND_FL: 0;
|
||||
ei->i_flags |= (di->di_flags & IMMUTABLE)
|
||||
? EXT2_IMMUTABLE_FL: 0;
|
||||
ei->i_blocks = di->di_blocks;
|
||||
ei->i_generation = di->di_gen;
|
||||
ei->i_uid = di->di_uid;
|
||||
ei->i_gid = di->di_gid;
|
||||
ei->i_dtime = ei->i_links_count ? 0 : ip->i_mtime;
|
||||
ei->i_size = ip->i_size;
|
||||
ei->i_atime = ip->i_atime;
|
||||
ei->i_mtime = ip->i_mtime;
|
||||
ei->i_ctime = ip->i_ctime;
|
||||
ei->i_flags = ip->i_flags;
|
||||
ei->i_flags = 0;
|
||||
ei->i_flags |= (ip->i_flags & APPEND) ? EXT2_APPEND_FL: 0;
|
||||
ei->i_flags |= (ip->i_flags & IMMUTABLE) ? EXT2_IMMUTABLE_FL: 0;
|
||||
ei->i_blocks = ip->i_blocks;
|
||||
ei->i_generation = ip->i_gen;
|
||||
ei->i_uid = ip->i_uid;
|
||||
ei->i_gid = ip->i_gid;
|
||||
/* XXX use memcpy */
|
||||
for(i = 0; i < NDADDR; i++)
|
||||
ei->i_block[i] = di->di_db[i];
|
||||
for(i = 0; i < NIADDR; i++)
|
||||
ei->i_block[EXT2_NDIR_BLOCKS + i] = di->di_ib[i];
|
||||
for(i = 0; i < NDADDR; i++)
|
||||
ei->i_block[i] = ip->i_db[i];
|
||||
for(i = 0; i < NIADDR; i++)
|
||||
ei->i_block[EXT2_NDIR_BLOCKS + i] = ip->i_ib[i];
|
||||
}
|
||||
|
@ -35,9 +35,8 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
@ -61,13 +60,13 @@ static void read_block_bitmap (struct mount * mp,
|
||||
unsigned int block_group,
|
||||
unsigned long bitmap_nr)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct ext2_group_desc * gdp;
|
||||
struct buffer_head * bh;
|
||||
int error;
|
||||
|
||||
gdp = get_group_desc (mp, block_group, NULL);
|
||||
if ((error = bread (VFSTOUFS(mp)->um_devvp,
|
||||
if ((error = bread (VFSTOEXT2(mp)->um_devvp,
|
||||
fsbtodb(sb, gdp->bg_block_bitmap),sb->s_blocksize, NOCRED, &bh)) != 0)
|
||||
panic ( "read_block_bitmap: "
|
||||
"Cannot read block bitmap - "
|
||||
@ -93,7 +92,7 @@ static int load__block_bitmap (struct mount * mp,
|
||||
unsigned int block_group)
|
||||
{
|
||||
int i, j;
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
unsigned long block_bitmap_number;
|
||||
struct buffer_head * block_bitmap;
|
||||
|
||||
@ -152,7 +151,7 @@ static int load__block_bitmap (struct mount * mp,
|
||||
static __inline int load_block_bitmap (struct mount * mp,
|
||||
unsigned int block_group)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
if (sb->s_loaded_block_bitmaps > 0 &&
|
||||
sb->s_block_bitmap_number[0] == block_group)
|
||||
return 0;
|
||||
@ -168,7 +167,7 @@ static __inline int load_block_bitmap (struct mount * mp,
|
||||
void ext2_free_blocks (struct mount * mp, unsigned long block,
|
||||
unsigned long count)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct buffer_head * bh;
|
||||
struct buffer_head * bh2;
|
||||
unsigned long block_group;
|
||||
@ -182,13 +181,13 @@ void ext2_free_blocks (struct mount * mp, unsigned long block,
|
||||
printf ("ext2_free_blocks: nonexistent device");
|
||||
return;
|
||||
}
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
if (block < es->s_first_data_block ||
|
||||
(block + count) > es->s_blocks_count) {
|
||||
printf ( "ext2_free_blocks: "
|
||||
"Freeing blocks not in datazone - "
|
||||
"block = %lu, count = %lu", block, count);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -238,7 +237,7 @@ void ext2_free_blocks (struct mount * mp, unsigned long block,
|
||||
}
|
||||
****/
|
||||
sb->s_dirt = 1;
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -253,7 +252,7 @@ int ext2_new_block (struct mount * mp, unsigned long goal,
|
||||
u_int32_t * prealloc_count,
|
||||
u_int32_t * prealloc_block)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct buffer_head * bh;
|
||||
struct buffer_head * bh2;
|
||||
char * p, * r;
|
||||
@ -269,7 +268,7 @@ int ext2_new_block (struct mount * mp, unsigned long goal,
|
||||
printf ("ext2_new_block: nonexistent device");
|
||||
return 0;
|
||||
}
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
|
||||
ext2_debug ("goal=%lu.\n", goal);
|
||||
|
||||
@ -356,7 +355,7 @@ repeat:
|
||||
break;
|
||||
}
|
||||
if (k >= sb->s_groups_count) {
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return 0;
|
||||
}
|
||||
bitmap_nr = load_block_bitmap (mp, i);
|
||||
@ -372,7 +371,7 @@ repeat:
|
||||
if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
|
||||
printf ( "ext2_new_block: "
|
||||
"Free blocks count corrupted for block group %d", i);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -439,7 +438,7 @@ got_block:
|
||||
printf ( "ext2_new_block: "
|
||||
"block >= blocks count - "
|
||||
"block_group = %d, block=%d", i, j);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -450,14 +449,14 @@ got_block:
|
||||
mark_buffer_dirty(bh2);
|
||||
es->s_free_blocks_count--;
|
||||
sb->s_dirt = 1;
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return j;
|
||||
}
|
||||
|
||||
#ifdef unused
|
||||
static unsigned long ext2_count_free_blocks (struct mount * mp)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
#ifdef EXT2FS_DEBUG
|
||||
struct ext2_super_block * es;
|
||||
unsigned long desc_count, bitmap_count, x;
|
||||
@ -465,7 +464,7 @@ static unsigned long ext2_count_free_blocks (struct mount * mp)
|
||||
struct ext2_group_desc * gdp;
|
||||
int i;
|
||||
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
es = sb->s_es;
|
||||
desc_count = 0;
|
||||
bitmap_count = 0;
|
||||
@ -482,7 +481,7 @@ static unsigned long ext2_count_free_blocks (struct mount * mp)
|
||||
}
|
||||
ext2_debug( "stored = %lu, computed = %lu, %lu\n",
|
||||
es->s_free_blocks_count, desc_count, bitmap_count);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return bitmap_count;
|
||||
#else
|
||||
return sb->s_es->s_free_blocks_count;
|
||||
@ -520,7 +519,7 @@ int ext2_group_sparse(int group)
|
||||
#ifdef unused
|
||||
static void ext2_check_blocks_bitmap (struct mount * mp)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct buffer_head * bh;
|
||||
struct ext2_super_block * es;
|
||||
unsigned long desc_count, bitmap_count, x;
|
||||
@ -529,7 +528,7 @@ static void ext2_check_blocks_bitmap (struct mount * mp)
|
||||
struct ext2_group_desc * gdp;
|
||||
int i, j;
|
||||
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
es = sb->s_es;
|
||||
desc_count = 0;
|
||||
bitmap_count = 0;
|
||||
@ -586,7 +585,7 @@ static void ext2_check_blocks_bitmap (struct mount * mp)
|
||||
"Wrong free blocks count in super block, "
|
||||
"stored = %lu, counted = %lu",
|
||||
(unsigned long) es->s_free_blocks_count, bitmap_count);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
}
|
||||
#endif /* unused */
|
||||
|
||||
|
@ -36,10 +36,8 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
@ -69,7 +67,7 @@ struct ext2_group_desc * get_group_desc (struct mount * mp,
|
||||
unsigned int block_group,
|
||||
struct buffer_head ** bh)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
unsigned long group_desc;
|
||||
unsigned long desc;
|
||||
struct ext2_group_desc * gdp;
|
||||
@ -98,13 +96,13 @@ static void read_inode_bitmap (struct mount * mp,
|
||||
unsigned long block_group,
|
||||
unsigned int bitmap_nr)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct ext2_group_desc * gdp;
|
||||
struct buffer_head * bh;
|
||||
int error;
|
||||
|
||||
gdp = get_group_desc (mp, block_group, NULL);
|
||||
if ((error = bread (VFSTOUFS(mp)->um_devvp,
|
||||
if ((error = bread (VFSTOEXT2(mp)->um_devvp,
|
||||
fsbtodb(sb, gdp->bg_inode_bitmap),
|
||||
sb->s_blocksize,
|
||||
NOCRED, &bh)) != 0)
|
||||
@ -131,7 +129,7 @@ static void read_inode_bitmap (struct mount * mp,
|
||||
static int load_inode_bitmap (struct mount * mp,
|
||||
unsigned int block_group)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
int i, j;
|
||||
unsigned long inode_bitmap_number;
|
||||
struct buffer_head * inode_bitmap;
|
||||
@ -447,14 +445,14 @@ repeat:
|
||||
static unsigned long ext2_count_free_inodes (struct mount * mp)
|
||||
{
|
||||
#ifdef EXT2FS_DEBUG
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct ext2_super_block * es;
|
||||
unsigned long desc_count, bitmap_count, x;
|
||||
int bitmap_nr;
|
||||
struct ext2_group_desc * gdp;
|
||||
int i;
|
||||
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
es = sb->s_es;
|
||||
desc_count = 0;
|
||||
bitmap_count = 0;
|
||||
@ -471,10 +469,10 @@ static unsigned long ext2_count_free_inodes (struct mount * mp)
|
||||
}
|
||||
ext2_debug("stored = %lu, computed = %lu, %lu\n",
|
||||
es->s_free_inodes_count, desc_count, bitmap_count);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return desc_count;
|
||||
#else
|
||||
return VFSTOUFS(mp)->um_e2fsb->s_free_inodes_count;
|
||||
return VFSTOEXT2(mp)->um_e2fsb->s_free_inodes_count;
|
||||
#endif
|
||||
}
|
||||
#endif /* unused */
|
||||
|
@ -55,13 +55,10 @@
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/dirent.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <ufs/ufs/ufs_extern.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
@ -364,7 +361,7 @@ ext2_lookup(ap)
|
||||
* profiling time and hence has been removed in the interest
|
||||
* of simplicity.
|
||||
*/
|
||||
bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
|
||||
bmask = VFSTOEXT2(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
|
||||
if (nameiop != LOOKUP || dp->i_diroff == 0 ||
|
||||
dp->i_diroff > dp->i_size) {
|
||||
entryoffsetinblock = 0;
|
||||
@ -373,7 +370,8 @@ ext2_lookup(ap)
|
||||
} else {
|
||||
dp->i_offset = dp->i_diroff;
|
||||
if ((entryoffsetinblock = dp->i_offset & bmask) &&
|
||||
(error = UFS_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)))
|
||||
(error = ext2_blkatoff(vdp, (off_t)dp->i_offset, NULL,
|
||||
&bp)))
|
||||
return (error);
|
||||
numdirpasses = 2;
|
||||
nchstats.ncs_2passes++;
|
||||
@ -391,7 +389,8 @@ searchloop:
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
if ((error =
|
||||
UFS_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)) != 0)
|
||||
ext2_blkatoff(vdp, (off_t)dp->i_offset, NULL,
|
||||
&bp)) != 0)
|
||||
return (error);
|
||||
entryoffsetinblock = 0;
|
||||
}
|
||||
@ -416,7 +415,7 @@ searchloop:
|
||||
if (ep->rec_len == 0 ||
|
||||
(dirchk && ext2_dirbadentry(vdp, ep, entryoffsetinblock))) {
|
||||
int i;
|
||||
ufs_dirbad(dp, dp->i_offset, "mangled entry");
|
||||
ext2_dirbad(dp, dp->i_offset, "mangled entry");
|
||||
i = DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1));
|
||||
dp->i_offset += i;
|
||||
entryoffsetinblock += i;
|
||||
@ -558,7 +557,7 @@ found:
|
||||
*/
|
||||
if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->name_len)
|
||||
> dp->i_size) {
|
||||
ufs_dirbad(dp, dp->i_offset, "i_size too small");
|
||||
ext2_dirbad(dp, dp->i_offset, "i_size too small");
|
||||
dp->i_size = entryoffsetinblock+EXT2_DIR_REC_LEN(ep->name_len);
|
||||
dp->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
}
|
||||
@ -700,6 +699,21 @@ found:
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ext2_dirbad(ip, offset, how)
|
||||
struct inode *ip;
|
||||
doff_t offset;
|
||||
char *how;
|
||||
{
|
||||
struct mount *mp;
|
||||
|
||||
mp = ITOV(ip)->v_mount;
|
||||
(void)printf("%s: bad dir ino %lu at offset %ld: %s\n",
|
||||
mp->mnt_stat.f_mntonname, (u_long)ip->i_number, (long)offset, how);
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
panic("ext2_dirbad: bad dir");
|
||||
}
|
||||
|
||||
/*
|
||||
* Do consistency checking on a directory entry:
|
||||
* record length must be multiple of 4
|
||||
@ -804,7 +818,7 @@ ext2_direnter(ip, dvp, cnp)
|
||||
auio.uio_td = (struct thread *)0;
|
||||
error = VOP_WRITE(dvp, &auio, IO_SYNC, cnp->cn_cred);
|
||||
if (DIRBLKSIZ >
|
||||
VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
|
||||
VFSTOEXT2(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
|
||||
/* XXX should grow with balloc() */
|
||||
panic("ext2_direnter: frag size");
|
||||
else if (!error) {
|
||||
@ -835,7 +849,8 @@ ext2_direnter(ip, dvp, cnp)
|
||||
/*
|
||||
* Get the block containing the space for the new directory entry.
|
||||
*/
|
||||
if ((error = UFS_BLKATOFF(dvp, (off_t)dp->i_offset, &dirbuf, &bp)) != 0)
|
||||
if ((error = ext2_blkatoff(dvp, (off_t)dp->i_offset, &dirbuf,
|
||||
&bp)) != 0)
|
||||
return (error);
|
||||
/*
|
||||
* Find space for the new entry. In the simple case, the entry at
|
||||
@ -881,7 +896,7 @@ ext2_direnter(ip, dvp, cnp)
|
||||
error = BUF_WRITE(bp);
|
||||
dp->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
if (!error && dp->i_endoff && dp->i_endoff < dp->i_size)
|
||||
error = UFS_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC,
|
||||
error = ext2_truncate(dvp, (off_t)dp->i_endoff, IO_SYNC,
|
||||
cnp->cn_cred, cnp->cn_thread);
|
||||
return (error);
|
||||
}
|
||||
@ -914,7 +929,8 @@ ext2_dirremove(dvp, cnp)
|
||||
* First entry in block: set d_ino to zero.
|
||||
*/
|
||||
if ((error =
|
||||
UFS_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0)
|
||||
ext2_blkatoff(dvp, (off_t)dp->i_offset, (char **)&ep,
|
||||
&bp)) != 0)
|
||||
return (error);
|
||||
ep->inode = 0;
|
||||
error = BUF_WRITE(bp);
|
||||
@ -924,7 +940,7 @@ ext2_dirremove(dvp, cnp)
|
||||
/*
|
||||
* Collapse new free space into previous entry.
|
||||
*/
|
||||
if ((error = UFS_BLKATOFF(dvp, (off_t)(dp->i_offset - dp->i_count),
|
||||
if ((error = ext2_blkatoff(dvp, (off_t)(dp->i_offset - dp->i_count),
|
||||
(char **)&ep, &bp)) != 0)
|
||||
return (error);
|
||||
ep->rec_len += dp->i_reclen;
|
||||
@ -948,7 +964,8 @@ ext2_dirrewrite(dp, ip, cnp)
|
||||
struct vnode *vdp = ITOV(dp);
|
||||
int error;
|
||||
|
||||
if ((error = UFS_BLKATOFF(vdp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0)
|
||||
if ((error = ext2_blkatoff(vdp, (off_t)dp->i_offset, (char **)&ep,
|
||||
&bp)) != 0)
|
||||
return (error);
|
||||
ep->inode = ip->i_number;
|
||||
if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
|
||||
|
@ -301,12 +301,12 @@ WRITE(ap)
|
||||
ip->i_mode &= ~(ISUID | ISGID);
|
||||
if (error) {
|
||||
if (ioflag & IO_UNIT) {
|
||||
(void)UFS_TRUNCATE(vp, osize,
|
||||
(void)ext2_truncate(vp, osize,
|
||||
ioflag & IO_SYNC, ap->a_cred, uio->uio_td);
|
||||
uio->uio_offset -= resid - uio->uio_resid;
|
||||
uio->uio_resid = resid;
|
||||
}
|
||||
} else if (resid > uio->uio_resid && (ioflag & IO_SYNC))
|
||||
error = UFS_UPDATE(vp, 1);
|
||||
error = ext2_update(vp, 1);
|
||||
return (error);
|
||||
}
|
||||
|
@ -50,9 +50,7 @@
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
@ -121,7 +119,7 @@ ext2_checkoverlap(bp, ip)
|
||||
continue;
|
||||
vprint("Disk overlap", vp);
|
||||
(void)printf("\tstart %d, end %d overlap start %lld, end %ld\n",
|
||||
start, last, ep->b_blkno,
|
||||
start, last, (long long)ep->b_blkno,
|
||||
(long)(ep->b_blkno + btodb(ep->b_bcount) - 1));
|
||||
panic("Disk buffer overlap");
|
||||
}
|
||||
|
@ -40,8 +40,6 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_quota.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
@ -57,12 +55,8 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufs_extern.h>
|
||||
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
@ -71,26 +65,29 @@
|
||||
|
||||
static int ext2_fhtovp(struct mount *, struct fid *, struct vnode **);
|
||||
static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td);
|
||||
static int ext2_init(struct vfsconf *);
|
||||
static int ext2_mount(struct mount *,
|
||||
char *, caddr_t, struct nameidata *, struct thread *);
|
||||
static int ext2_mountfs(struct vnode *, struct mount *, struct thread *);
|
||||
static int ext2_reload(struct mount *mountp, struct ucred *cred,
|
||||
struct thread *td);
|
||||
static int ext2_sbupdate(struct ufsmount *, int);
|
||||
static int ext2_root(struct mount *, struct vnode **vpp);
|
||||
static int ext2_sbupdate(struct ext2mount *, int);
|
||||
static int ext2_statfs(struct mount *, struct statfs *, struct thread *);
|
||||
static int ext2_sync(struct mount *, int, struct ucred *, struct thread *);
|
||||
static int ext2_unmount(struct mount *, int, struct thread *);
|
||||
static int ext2_vget(struct mount *, ino_t, int, struct vnode **);
|
||||
static int ext2_vptofh(struct vnode *, struct fid *);
|
||||
|
||||
static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
|
||||
MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
|
||||
static MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure");
|
||||
|
||||
static struct vfsops ext2fs_vfsops = {
|
||||
ext2_mount,
|
||||
ufs_start, /* empty function */
|
||||
vfs_stdstart,
|
||||
ext2_unmount,
|
||||
ufs_root, /* root inode via vget */
|
||||
ufs_quotactl, /* does operations associated with quotas */
|
||||
ext2_root, /* root inode via vget */
|
||||
vfs_stdquotactl,
|
||||
ext2_statfs,
|
||||
ext2_sync,
|
||||
ext2_vget,
|
||||
@ -129,7 +126,7 @@ ext2_mountroot()
|
||||
register struct ext2_sb_info *fs;
|
||||
register struct mount *mp;
|
||||
struct thread *td = curthread;
|
||||
struct ufsmount *ump;
|
||||
struct ext2mount *ump;
|
||||
u_int size;
|
||||
int error;
|
||||
|
||||
@ -155,7 +152,7 @@ ext2_mountroot()
|
||||
TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list);
|
||||
mp->mnt_flag |= MNT_ROOTFS;
|
||||
mp->mnt_vnodecovered = NULLVP;
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt));
|
||||
fs->fs_fsmnt[0] = '/';
|
||||
@ -180,13 +177,13 @@ static int
|
||||
ext2_mount(mp, path, data, ndp, td)
|
||||
register struct mount *mp;
|
||||
char *path;
|
||||
caddr_t data; /* this is actually a (struct ufs_args *) */
|
||||
caddr_t data; /* this is actually a (struct ext2_args *) */
|
||||
struct nameidata *ndp;
|
||||
struct thread *td;
|
||||
{
|
||||
struct vnode *devvp;
|
||||
struct ufs_args args;
|
||||
struct ufsmount *ump = 0;
|
||||
struct ext2_args args;
|
||||
struct ext2mount *ump = 0;
|
||||
register struct ext2_sb_info *fs;
|
||||
size_t size;
|
||||
int error, flags;
|
||||
@ -195,7 +192,7 @@ ext2_mount(mp, path, data, ndp, td)
|
||||
/* Double-check the length of path.. */
|
||||
if (strlen(path) >= MAXMNTLEN - 1)
|
||||
return (ENAMETOOLONG);
|
||||
error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args));
|
||||
error = copyin(data, (caddr_t)&args, sizeof (struct ext2_args));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
/*
|
||||
@ -203,7 +200,7 @@ ext2_mount(mp, path, data, ndp, td)
|
||||
* read/write; if there is no device name, that's all we do.
|
||||
*/
|
||||
if (mp->mnt_flag & MNT_UPDATE) {
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
error = 0;
|
||||
if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) {
|
||||
@ -310,7 +307,7 @@ ext2_mount(mp, path, data, ndp, td)
|
||||
vrele(devvp);
|
||||
return (error);
|
||||
}
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
/*
|
||||
* Note that this strncpy() is ok because of a check at the start
|
||||
@ -466,7 +463,7 @@ static int compute_sb_data(devvp, es, fs)
|
||||
V(s_db_per_group)
|
||||
|
||||
fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *),
|
||||
M_UFSMNT, M_WAITOK);
|
||||
M_EXT2MNT, M_WAITOK);
|
||||
|
||||
/* adjust logic_sb_block */
|
||||
if(fs->s_blocksize > SBSIZE)
|
||||
@ -481,7 +478,7 @@ static int compute_sb_data(devvp, es, fs)
|
||||
if(error) {
|
||||
for (j = 0; j < i; j++)
|
||||
brelse(fs->s_group_desc[j]);
|
||||
bsd_free(fs->s_group_desc, M_UFSMNT);
|
||||
bsd_free(fs->s_group_desc, M_EXT2MNT);
|
||||
printf("EXT2-fs: unable to read group descriptors (%d)\n", error);
|
||||
return EIO;
|
||||
}
|
||||
@ -491,7 +488,7 @@ static int compute_sb_data(devvp, es, fs)
|
||||
if(!ext2_check_descriptors(fs)) {
|
||||
for (j = 0; j < db_count; j++)
|
||||
ULCK_BUF(fs->s_group_desc[j])
|
||||
bsd_free(fs->s_group_desc, M_UFSMNT);
|
||||
bsd_free(fs->s_group_desc, M_EXT2MNT);
|
||||
printf("EXT2-fs: (ext2_check_descriptors failure) "
|
||||
"unable to read group descriptors\n");
|
||||
return EIO;
|
||||
@ -539,7 +536,7 @@ ext2_reload(mountp, cred, td)
|
||||
/*
|
||||
* Step 1: invalidate all cached meta-data.
|
||||
*/
|
||||
devvp = VFSTOUFS(mountp)->um_devvp;
|
||||
devvp = VFSTOEXT2(mountp)->um_devvp;
|
||||
if (vinvalbuf(devvp, 0, cred, td, 0, 0))
|
||||
panic("ext2_reload: dirty1");
|
||||
/*
|
||||
@ -553,7 +550,7 @@ ext2_reload(mountp, cred, td)
|
||||
brelse(bp);
|
||||
return (EIO); /* XXX needs translation */
|
||||
}
|
||||
fs = VFSTOUFS(mountp)->um_e2fs;
|
||||
fs = VFSTOEXT2(mountp)->um_e2fs;
|
||||
bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block));
|
||||
|
||||
if((error = compute_sb_data(devvp, es, fs)) != 0) {
|
||||
@ -600,9 +597,8 @@ loop:
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data +
|
||||
EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)),
|
||||
&ip->i_din);
|
||||
ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data +
|
||||
EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), ip);
|
||||
brelse(bp);
|
||||
vput(vp);
|
||||
mtx_lock(&mntvnode_mtx);
|
||||
@ -620,12 +616,12 @@ ext2_mountfs(devvp, mp, td)
|
||||
struct mount *mp;
|
||||
struct thread *td;
|
||||
{
|
||||
register struct ufsmount *ump;
|
||||
register struct ext2mount *ump;
|
||||
struct buf *bp;
|
||||
register struct ext2_sb_info *fs;
|
||||
struct ext2_super_block * es;
|
||||
dev_t dev = devvp->v_rdev;
|
||||
int error, i;
|
||||
int error;
|
||||
int ronly;
|
||||
|
||||
/*
|
||||
@ -677,22 +673,16 @@ ext2_mountfs(devvp, mp, td)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ump = bsd_malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
|
||||
ump = bsd_malloc(sizeof *ump, M_EXT2MNT, M_WAITOK);
|
||||
bzero((caddr_t)ump, sizeof *ump);
|
||||
ump->um_malloctype = M_EXT2NODE;
|
||||
ump->um_blkatoff = ext2_blkatoff;
|
||||
ump->um_truncate = ext2_truncate;
|
||||
ump->um_update = ext2_update;
|
||||
ump->um_valloc = ext2_valloc;
|
||||
ump->um_vfree = ext2_vfree;
|
||||
/* I don't know whether this is the right strategy. Note that
|
||||
we dynamically allocate both a ext2_sb_info and a ext2_super_block
|
||||
while Linux keeps the super block in a locked buffer
|
||||
*/
|
||||
ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info),
|
||||
M_UFSMNT, M_WAITOK);
|
||||
M_EXT2MNT, M_WAITOK);
|
||||
ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block),
|
||||
M_UFSMNT, M_WAITOK);
|
||||
M_EXT2MNT, M_WAITOK);
|
||||
bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block));
|
||||
if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)))
|
||||
goto out;
|
||||
@ -720,14 +710,12 @@ ext2_mountfs(devvp, mp, td)
|
||||
ump->um_mountp = mp;
|
||||
ump->um_dev = dev;
|
||||
ump->um_devvp = devvp;
|
||||
/* setting those two parameters allows us to use
|
||||
/* setting those two parameters allowed us to use
|
||||
ufs_bmap w/o changse !
|
||||
*/
|
||||
ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs);
|
||||
ump->um_bptrtodb = fs->s_es->s_log_block_size + 1;
|
||||
ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs);
|
||||
for (i = 0; i < MAXQUOTAS; i++)
|
||||
ump->um_quotas[i] = NULLVP;
|
||||
devvp->v_rdev->si_mountpoint = mp;
|
||||
if (ronly == 0)
|
||||
ext2_sbupdate(ump, MNT_WAIT);
|
||||
@ -737,9 +725,9 @@ out:
|
||||
brelse(bp);
|
||||
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, td);
|
||||
if (ump) {
|
||||
bsd_free(ump->um_e2fs->s_es, M_UFSMNT);
|
||||
bsd_free(ump->um_e2fs, M_UFSMNT);
|
||||
bsd_free(ump, M_UFSMNT);
|
||||
bsd_free(ump->um_e2fs->s_es, M_EXT2MNT);
|
||||
bsd_free(ump->um_e2fs, M_EXT2MNT);
|
||||
bsd_free(ump, M_EXT2MNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
}
|
||||
return (error);
|
||||
@ -754,7 +742,7 @@ ext2_unmount(mp, mntflags, td)
|
||||
int mntflags;
|
||||
struct thread *td;
|
||||
{
|
||||
register struct ufsmount *ump;
|
||||
register struct ext2mount *ump;
|
||||
register struct ext2_sb_info *fs;
|
||||
int error, flags, ronly, i;
|
||||
|
||||
@ -766,7 +754,7 @@ ext2_unmount(mp, mntflags, td)
|
||||
}
|
||||
if ((error = ext2_flushfiles(mp, flags, td)) != 0)
|
||||
return (error);
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
ronly = fs->s_rd_only;
|
||||
if (ronly == 0) {
|
||||
@ -778,7 +766,7 @@ ext2_unmount(mp, mntflags, td)
|
||||
/* release buffers containing group descriptors */
|
||||
for(i = 0; i < fs->s_db_per_group; i++)
|
||||
ULCK_BUF(fs->s_group_desc[i])
|
||||
bsd_free(fs->s_group_desc, M_UFSMNT);
|
||||
bsd_free(fs->s_group_desc, M_EXT2MNT);
|
||||
|
||||
/* release cached inode/block bitmaps */
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
@ -793,9 +781,9 @@ ext2_unmount(mp, mntflags, td)
|
||||
error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE,
|
||||
NOCRED, td);
|
||||
vrele(ump->um_devvp);
|
||||
bsd_free(fs->s_es, M_UFSMNT);
|
||||
bsd_free(fs, M_UFSMNT);
|
||||
bsd_free(ump, M_UFSMNT);
|
||||
bsd_free(fs->s_es, M_EXT2MNT);
|
||||
bsd_free(fs, M_EXT2MNT);
|
||||
bsd_free(ump, M_EXT2MNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
return (error);
|
||||
@ -810,28 +798,8 @@ ext2_flushfiles(mp, flags, td)
|
||||
int flags;
|
||||
struct thread *td;
|
||||
{
|
||||
register struct ufsmount *ump;
|
||||
int error;
|
||||
#if QUOTA
|
||||
int i;
|
||||
#endif
|
||||
|
||||
ump = VFSTOUFS(mp);
|
||||
#if QUOTA
|
||||
if (mp->mnt_flag & MNT_QUOTA) {
|
||||
if ((error = vflush(mp, 0, SKIPSYSTEM|flags)) != 0)
|
||||
return (error);
|
||||
for (i = 0; i < MAXQUOTAS; i++) {
|
||||
if (ump->um_quotas[i] == NULLVP)
|
||||
continue;
|
||||
quotaoff(td, mp, i);
|
||||
}
|
||||
/*
|
||||
* Here we fall through to vflush again to ensure
|
||||
* that we have gotten rid of all the system vnodes.
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
error = vflush(mp, 0, flags);
|
||||
return (error);
|
||||
}
|
||||
@ -847,12 +815,12 @@ ext2_statfs(mp, sbp, td)
|
||||
struct thread *td;
|
||||
{
|
||||
unsigned long overhead;
|
||||
register struct ufsmount *ump;
|
||||
register struct ext2mount *ump;
|
||||
register struct ext2_sb_info *fs;
|
||||
register struct ext2_super_block *es;
|
||||
int i, nsb;
|
||||
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
es = fs->s_es;
|
||||
|
||||
@ -908,7 +876,7 @@ ext2_sync(mp, waitfor, cred, td)
|
||||
{
|
||||
struct vnode *nvp, *vp;
|
||||
struct inode *ip;
|
||||
struct ufsmount *ump = VFSTOUFS(mp);
|
||||
struct ext2mount *ump = VFSTOEXT2(mp);
|
||||
struct ext2_sb_info *fs;
|
||||
int error, allerror = 0;
|
||||
|
||||
@ -964,9 +932,6 @@ loop:
|
||||
allerror = error;
|
||||
VOP_UNLOCK(ump->um_devvp, 0, td);
|
||||
}
|
||||
#if QUOTA
|
||||
qsync(mp);
|
||||
#endif
|
||||
/*
|
||||
* Write back modified superblock.
|
||||
*/
|
||||
@ -994,17 +959,17 @@ ext2_vget(mp, ino, flags, vpp)
|
||||
{
|
||||
register struct ext2_sb_info *fs;
|
||||
register struct inode *ip;
|
||||
struct ufsmount *ump;
|
||||
struct ext2mount *ump;
|
||||
struct buf *bp;
|
||||
struct vnode *vp;
|
||||
dev_t dev;
|
||||
int i, error;
|
||||
int used_blocks;
|
||||
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
dev = ump->um_dev;
|
||||
restart:
|
||||
if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
|
||||
if ((error = ext2_ihashget(dev, ino, flags, vpp)) != 0)
|
||||
return (error);
|
||||
if (*vpp != NULL)
|
||||
return (0);
|
||||
@ -1048,17 +1013,13 @@ restart:
|
||||
ip->i_e2fs = fs = ump->um_e2fs;
|
||||
ip->i_dev = dev;
|
||||
ip->i_number = ino;
|
||||
#if QUOTA
|
||||
for (i = 0; i < MAXQUOTAS; i++)
|
||||
ip->i_dquot[i] = NODQUOT;
|
||||
#endif
|
||||
/*
|
||||
* Put it onto its hash chain and lock it so that other requests for
|
||||
* this inode will block if they arrive while we are sleeping waiting
|
||||
* for old data structures to be purged or for the contents of the
|
||||
* disk portion of this inode to be read.
|
||||
*/
|
||||
ufs_ihashins(ip);
|
||||
ext2_ihashins(ip);
|
||||
|
||||
if (ext2fs_inode_hash_lock < 0)
|
||||
wakeup(&ext2fs_inode_hash_lock);
|
||||
@ -1082,8 +1043,8 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
|
||||
return (error);
|
||||
}
|
||||
/* convert ext2 inode to dinode */
|
||||
ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE *
|
||||
ino_to_fsbo(fs, ino)), &ip->i_din);
|
||||
ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE *
|
||||
ino_to_fsbo(fs, ino)), ip);
|
||||
ip->i_block_group = ino_to_cg(fs, ino);
|
||||
ip->i_next_alloc_block = 0;
|
||||
ip->i_next_alloc_goal = 0;
|
||||
@ -1107,7 +1068,7 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
|
||||
* Initialize the vnode from the inode, check for aliases.
|
||||
* Note that the underlying vnode may have changed.
|
||||
*/
|
||||
if ((error = ufs_vinit(mp, ext2_specop_p, ext2_fifoop_p, &vp)) != 0) {
|
||||
if ((error = ext2_vinit(mp, ext2_specop_p, ext2_fifoop_p, &vp)) != 0) {
|
||||
vput(vp);
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
@ -1146,15 +1107,32 @@ ext2_fhtovp(mp, fhp, vpp)
|
||||
struct fid *fhp;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
struct inode *ip;
|
||||
register struct ufid *ufhp;
|
||||
struct vnode *nvp;
|
||||
struct ext2_sb_info *fs;
|
||||
int error;
|
||||
|
||||
ufhp = (struct ufid *)fhp;
|
||||
fs = VFSTOUFS(mp)->um_e2fs;
|
||||
fs = VFSTOEXT2(mp)->um_e2fs;
|
||||
if (ufhp->ufid_ino < ROOTINO ||
|
||||
ufhp->ufid_ino >= fs->s_groups_count * fs->s_es->s_inodes_per_group)
|
||||
return (ESTALE);
|
||||
return (ufs_fhtovp(mp, ufhp, vpp));
|
||||
|
||||
error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp);
|
||||
if (error) {
|
||||
*vpp = NULLVP;
|
||||
return (error);
|
||||
}
|
||||
ip = VTOI(nvp);
|
||||
if (ip->i_mode == 0 ||
|
||||
ip->i_gen != ufhp->ufid_gen || ip->i_nlink <= 0) {
|
||||
vput(nvp);
|
||||
*vpp = NULLVP;
|
||||
return (ESTALE);
|
||||
}
|
||||
*vpp = nvp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1182,7 +1160,7 @@ ext2_vptofh(vp, fhp)
|
||||
*/
|
||||
static int
|
||||
ext2_sbupdate(mp, waitfor)
|
||||
struct ufsmount *mp;
|
||||
struct ext2mount *mp;
|
||||
int waitfor;
|
||||
{
|
||||
register struct ext2_sb_info *fs = mp->um_e2fs;
|
||||
@ -1207,3 +1185,34 @@ printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the root of a filesystem.
|
||||
*/
|
||||
static int
|
||||
ext2_root(mp, vpp)
|
||||
struct mount *mp;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
struct vnode *nvp;
|
||||
int error;
|
||||
|
||||
error = VFS_VGET(mp, (ino_t)ROOTINO, LK_EXCLUSIVE, &nvp);
|
||||
if (error)
|
||||
return (error);
|
||||
*vpp = nvp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ext2_init(struct vfsconf *vfsp)
|
||||
{
|
||||
static int done;
|
||||
|
||||
if (done)
|
||||
return (0);
|
||||
done = 1;
|
||||
ext2_ihashinit();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -148,7 +148,7 @@ extern u_char *fragtbl[];
|
||||
* I haven't figured out yet what BSD does
|
||||
* I think I'll try a VOP_LOCK/VOP_UNLOCK on the device vnode
|
||||
*/
|
||||
#define DEVVP(inode) (VFSTOUFS(ITOV(inode)->v_mount)->um_devvp)
|
||||
#define DEVVP(inode) (VFSTOEXT2(ITOV(inode)->v_mount)->um_devvp)
|
||||
#define lock_super(devvp) vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, curthread)
|
||||
#define unlock_super(devvp) VOP_UNLOCK(devvp, 0, curthread)
|
||||
|
||||
|
@ -40,8 +40,6 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_quota.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/conf.h>
|
||||
@ -50,11 +48,8 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
@ -108,9 +103,6 @@ ext2_alloc(ip, lbn, bpref, size, cred, bnp)
|
||||
{
|
||||
register struct ext2_sb_info *fs;
|
||||
daddr_t bno;
|
||||
#if QUOTA
|
||||
int error;
|
||||
#endif
|
||||
|
||||
*bnp = 0;
|
||||
fs = ip->i_e2fs;
|
||||
@ -128,10 +120,6 @@ ext2_alloc(ip, lbn, bpref, size, cred, bnp)
|
||||
if (cred->cr_uid != 0 &&
|
||||
fs->s_es->s_free_blocks_count < fs->s_es->s_r_blocks_count)
|
||||
goto nospace;
|
||||
#if QUOTA
|
||||
if ((error = chkdq(ip, (long)btodb(size), cred, 0)) != 0)
|
||||
return (error);
|
||||
#endif
|
||||
if (bpref >= fs->s_es->s_blocks_count)
|
||||
bpref = 0;
|
||||
/* call the Linux code */
|
||||
@ -179,12 +167,6 @@ ext2_alloc(ip, lbn, bpref, size, cred, bnp)
|
||||
*bnp = bno;
|
||||
return (0);
|
||||
}
|
||||
#if QUOTA
|
||||
/*
|
||||
* Restore user's disk quota because allocation failed.
|
||||
*/
|
||||
(void) chkdq(ip, (long)-btodb(size), cred, FORCE);
|
||||
#endif
|
||||
nospace:
|
||||
ext2_fserr(fs, cred->cr_uid, "file system full");
|
||||
uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);
|
||||
@ -342,7 +324,7 @@ return ENOSPC;
|
||||
} else {
|
||||
ip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
if (!doasyncfree)
|
||||
UFS_UPDATE(vp, 1);
|
||||
ext2_update(vp, 1);
|
||||
}
|
||||
if (ssize < len)
|
||||
if (doasyncfree)
|
||||
@ -401,7 +383,7 @@ ext2_valloc(pvp, mode, cred, vpp)
|
||||
goto noinodes;
|
||||
error = VFS_VGET(pvp->v_mount, ino, LK_EXCLUSIVE, vpp);
|
||||
if (error) {
|
||||
UFS_VFREE(pvp, ino, mode);
|
||||
ext2_vfree(pvp, ino, mode);
|
||||
return (error);
|
||||
}
|
||||
ip = VTOI(*vpp);
|
||||
|
@ -48,10 +48,7 @@
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufs_extern.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
@ -164,11 +161,11 @@ ext2_debug("ext2_balloc called (%d, %d, %d)\n",
|
||||
* Determine the number of levels of indirection.
|
||||
*/
|
||||
pref = 0;
|
||||
if ((error = ufs_getlbns(vp, bn, indirs, &num)) != 0)
|
||||
if ((error = ext2_getlbns(vp, bn, indirs, &num)) != 0)
|
||||
return(error);
|
||||
#if DIAGNOSTIC
|
||||
if (num < 1)
|
||||
panic ("ext2_balloc: ufs_getlbns returned indirect block");
|
||||
panic ("ext2_balloc: ext2_getlbns returned indirect block");
|
||||
#endif
|
||||
/*
|
||||
* Fetch the first indirect block allocating if necessary.
|
||||
|
@ -43,8 +43,8 @@
|
||||
#ifndef _SYS_GNU_EXT2FS_EXT2_EXTERN_H_
|
||||
#define _SYS_GNU_EXT2FS_EXT2_EXTERN_H_
|
||||
|
||||
struct dinode;
|
||||
struct ext2_inode;
|
||||
struct indir;
|
||||
struct inode;
|
||||
struct mount;
|
||||
struct vfsconf;
|
||||
@ -58,7 +58,18 @@ int ext2_blkatoff(struct vnode *, off_t, char **, struct buf **);
|
||||
void ext2_blkfree(struct inode *, daddr_t, long);
|
||||
daddr_t ext2_blkpref(struct inode *, daddr_t, int, daddr_t *, daddr_t);
|
||||
int ext2_bmap(struct vop_bmap_args *);
|
||||
int ext2_init(struct vfsconf *);
|
||||
int ext2_bmaparray(struct vnode *, daddr_t, daddr_t *, int *, int *);
|
||||
void ext2_dirbad(struct inode *ip, doff_t offset, char *how);
|
||||
void ext2_ei2i(struct ext2_inode *, struct inode *);
|
||||
int ext2_getlbns(struct vnode *, daddr_t, struct indir *, int *);
|
||||
void ext2_i2ei(struct inode *, struct ext2_inode *);
|
||||
int ext2_ihashget(dev_t, ino_t, int, struct vnode **);
|
||||
void ext2_ihashinit(void);
|
||||
void ext2_ihashins(struct inode *);
|
||||
struct vnode *
|
||||
ext2_ihashlookup(dev_t, ino_t);
|
||||
void ext2_ihashrem(struct inode *);
|
||||
void ext2_itimes(struct vnode *vp);
|
||||
int ext2_reallocblks(struct vop_reallocblks_args *);
|
||||
int ext2_reclaim(struct vop_reclaim_args *);
|
||||
void ext2_setblock(struct ext2_sb_info *, u_char *, daddr_t);
|
||||
@ -66,9 +77,9 @@ int ext2_truncate(struct vnode *, off_t, int, struct ucred *, struct thread *);
|
||||
int ext2_update(struct vnode *, int);
|
||||
int ext2_valloc(struct vnode *, int, struct ucred *, struct vnode **);
|
||||
int ext2_vfree(struct vnode *, ino_t, int);
|
||||
int ext2_vinit(struct mount *, vop_t **, vop_t **, struct vnode **vpp);
|
||||
int ext2_lookup(struct vop_cachedlookup_args *);
|
||||
int ext2_readdir(struct vop_readdir_args *);
|
||||
void ext2_print_dinode(struct dinode *);
|
||||
void ext2_print_inode(struct inode *);
|
||||
int ext2_direnter(struct inode *,
|
||||
struct vnode *, struct componentname *);
|
||||
@ -89,15 +100,13 @@ unsigned long ext2_count_free(struct buf *map, unsigned int numchars);
|
||||
void ext2_free_blocks(struct mount *mp, unsigned long block,
|
||||
unsigned long count);
|
||||
void ext2_free_inode(struct inode * inode);
|
||||
void ext2_ei2di(struct ext2_inode *ei, struct dinode *di);
|
||||
void ext2_di2ei(struct dinode *di, struct ext2_inode *ei);
|
||||
void mark_buffer_dirty(struct buf *bh);
|
||||
|
||||
/*
|
||||
* This macro allows the ufs code to distinguish between an EXT2 and a
|
||||
* non-ext2(FFS/LFS) vnode.
|
||||
*/
|
||||
#define IS_EXT2_VNODE(vp) (vp->v_mount->mnt_stat.f_type == MOUNT_EXT2FS)
|
||||
/* Flags to low-level allocation routines. */
|
||||
#define B_CLRBUF 0x01 /* Request allocated buffer be cleared. */
|
||||
#define B_SYNC 0x02 /* Do all allocations synchronously. */
|
||||
#define B_METAONLY 0x04 /* Return indirect block buffer. */
|
||||
#define B_NOWAIT 0x08 /* do not sleep to await lock */
|
||||
|
||||
extern vop_t **ext2_vnodeop_p;
|
||||
extern vop_t **ext2_specop_p;
|
||||
|
@ -38,19 +38,6 @@
|
||||
#define umode_t mode_t
|
||||
#define loff_t off_t
|
||||
|
||||
/* the Linux implementation of EXT2 stores some information about
|
||||
* an inode in a ext2_inode_info structure which is part of the incore
|
||||
* inode in Linux
|
||||
* I decided to use the "spare" fields instead - we'll see how this
|
||||
* works out
|
||||
*/
|
||||
|
||||
#define i_block_group i_spare[0]
|
||||
#define i_next_alloc_block i_spare[1]
|
||||
#define i_next_alloc_goal i_spare[2]
|
||||
#define i_prealloc_block i_din.di_spare[0]
|
||||
#define i_prealloc_count i_din.di_spare[1]
|
||||
|
||||
/*
|
||||
* The second extended filesystem constants/structures
|
||||
*/
|
||||
@ -263,14 +250,6 @@ struct ext2_group_desc
|
||||
#define EXT2_IOC_GETVERSION _IOR('v', 1, long)
|
||||
#define EXT2_IOC_SETVERSION _IOW('v', 2, long)
|
||||
|
||||
/*
|
||||
* Only declare `struct ext2_inode' if <ufs/ufs/inode.h> hasn't made things
|
||||
* difficult by #defining i_mode and other struct members. The details of
|
||||
* the struct are only needed in ext2_inode_cnv.c where the ext2fs on-disk
|
||||
* inode is converted to a ufs in-core inode.
|
||||
*/
|
||||
#ifndef i_mode
|
||||
|
||||
/*
|
||||
* Structure of an inode on the disk
|
||||
*/
|
||||
@ -351,8 +330,6 @@ struct ext2_inode {
|
||||
#define i_reserved2 osd2.masix2.m_i_reserved2
|
||||
#endif
|
||||
|
||||
#endif /* i_mode */
|
||||
|
||||
/*
|
||||
* File system states
|
||||
*/
|
||||
|
@ -40,8 +40,6 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_quota.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
@ -53,12 +51,8 @@
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <ufs/ufs/ufs_extern.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
@ -67,12 +61,6 @@
|
||||
static int ext2_indirtrunc(struct inode *, daddr_t, daddr_t, daddr_t, int,
|
||||
long *);
|
||||
|
||||
int
|
||||
ext2_init(struct vfsconf *vfsp)
|
||||
{
|
||||
return (ufs_init(vfsp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the access, modified, and inode change times as specified by the
|
||||
* IN_ACCESS, IN_UPDATE, and IN_CHANGE flags respectively. Write the inode
|
||||
@ -92,7 +80,7 @@ ext2_update(vp, waitfor)
|
||||
struct inode *ip;
|
||||
int error;
|
||||
|
||||
ufs_itimes(vp);
|
||||
ext2_itimes(vp);
|
||||
ip = VTOI(vp);
|
||||
if ((ip->i_flag & IN_MODIFIED) == 0)
|
||||
return (0);
|
||||
@ -106,8 +94,8 @@ ext2_update(vp, waitfor)
|
||||
brelse(bp);
|
||||
return (error);
|
||||
}
|
||||
ext2_di2ei( &ip->i_din, (struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE *
|
||||
ino_to_fsbo(fs, ip->i_number)));
|
||||
ext2_i2ei(ip, (struct ext2_inode *)((char *)bp->b_data +
|
||||
EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)));
|
||||
/*
|
||||
if (waitfor && (vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
|
||||
return (bwrite(bp));
|
||||
@ -166,16 +154,12 @@ printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length);
|
||||
bzero((char *)&oip->i_shortlink, (u_int)oip->i_size);
|
||||
oip->i_size = 0;
|
||||
oip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
return (UFS_UPDATE(ovp, 1));
|
||||
return (ext2_update(ovp, 1));
|
||||
}
|
||||
if (oip->i_size == length) {
|
||||
oip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
return (UFS_UPDATE(ovp, 0));
|
||||
return (ext2_update(ovp, 0));
|
||||
}
|
||||
#if QUOTA
|
||||
if ((error = getinoquota(oip)) != 0)
|
||||
return (error);
|
||||
#endif
|
||||
fs = oip->i_e2fs;
|
||||
osize = oip->i_size;
|
||||
ext2_discard_prealloc(oip);
|
||||
@ -200,7 +184,7 @@ printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length);
|
||||
else
|
||||
bawrite(bp);
|
||||
oip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
return (UFS_UPDATE(ovp, 1));
|
||||
return (ext2_update(ovp, 1));
|
||||
}
|
||||
/*
|
||||
* Shorten the size of the file. If the file is not being
|
||||
@ -256,7 +240,7 @@ printf("ext2_truncate called %d to %d\n", VTOI(ovp)->i_number, length);
|
||||
for (i = NDADDR - 1; i > lastblock; i--)
|
||||
oip->i_db[i] = 0;
|
||||
oip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
allerror = UFS_UPDATE(ovp, 1);
|
||||
allerror = ext2_update(ovp, 1);
|
||||
|
||||
/*
|
||||
* Having written the new inode to disk, save its new configuration
|
||||
@ -361,9 +345,6 @@ done:
|
||||
oip->i_blocks = 0;
|
||||
oip->i_flag |= IN_CHANGE;
|
||||
vnode_pager_setsize(ovp, length);
|
||||
#if QUOTA
|
||||
(void) chkdq(oip, -blocksreleased, NOCRED, 0);
|
||||
#endif
|
||||
return (allerror);
|
||||
}
|
||||
|
||||
@ -488,9 +469,86 @@ int
|
||||
ext2_inactive(ap)
|
||||
struct vop_inactive_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
ext2_discard_prealloc(VTOI(ap->a_vp));
|
||||
return ufs_inactive(ap);
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct inode *ip = VTOI(vp);
|
||||
struct thread *td = ap->a_td;
|
||||
int mode, error = 0;
|
||||
|
||||
ext2_discard_prealloc(ip);
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("ext2_inactive: pushing active", vp);
|
||||
|
||||
/*
|
||||
* Ignore inodes related to stale file handles.
|
||||
*/
|
||||
if (ip->i_mode == 0)
|
||||
goto out;
|
||||
if (ip->i_nlink <= 0) {
|
||||
(void) vn_write_suspend_wait(vp, NULL, V_WAIT);
|
||||
error = ext2_truncate(vp, (off_t)0, 0, NOCRED, td);
|
||||
ip->i_rdev = 0;
|
||||
mode = ip->i_mode;
|
||||
ip->i_mode = 0;
|
||||
ip->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
ext2_vfree(vp, ip->i_number, mode);
|
||||
}
|
||||
if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) {
|
||||
if ((ip->i_flag & (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) == 0 &&
|
||||
vn_write_suspend_wait(vp, NULL, V_NOWAIT)) {
|
||||
ip->i_flag &= ~IN_ACCESS;
|
||||
} else {
|
||||
(void) vn_write_suspend_wait(vp, NULL, V_WAIT);
|
||||
ext2_update(vp, 0);
|
||||
}
|
||||
}
|
||||
out:
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
/*
|
||||
* If we are done with the inode, reclaim it
|
||||
* so that it can be reused immediately.
|
||||
*/
|
||||
if (ip->i_mode == 0)
|
||||
vrecycle(vp, NULL, td);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim an inode so that it can be used for other purposes.
|
||||
*/
|
||||
int
|
||||
ext2_reclaim(ap)
|
||||
struct vop_reclaim_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct thread *a_td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct inode *ip;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("ufs_reclaim: pushing active", vp);
|
||||
ip = VTOI(vp);
|
||||
if (ip->i_flag & IN_LAZYMOD) {
|
||||
ip->i_flag |= IN_MODIFIED;
|
||||
ext2_update(vp, 0);
|
||||
}
|
||||
/*
|
||||
* Remove the inode from its hash chain.
|
||||
*/
|
||||
ext2_ihashrem(ip);
|
||||
/*
|
||||
* Purge old data structures associated with the inode.
|
||||
*/
|
||||
cache_purge(vp);
|
||||
if (ip->i_devvp) {
|
||||
vrele(ip->i_devvp);
|
||||
ip->i_devvp = 0;
|
||||
}
|
||||
lockdestroy(&vp->v_lock);
|
||||
FREE(vp->v_data, M_EXT2NODE);
|
||||
vp->v_data = 0;
|
||||
return (0);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* routines to convert on disk ext2 inodes in dinodes and back
|
||||
* routines to convert on disk ext2 inodes into inodes and back
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -31,130 +31,101 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
|
||||
/*
|
||||
* Undo the definitions in <ufs/ufs/inode.h> that would destroy the include
|
||||
* of <gnu/ext2fs/ext2_fs.h>.
|
||||
*/
|
||||
#undef i_atime
|
||||
#undef i_blocks
|
||||
#undef i_ctime
|
||||
#undef i_db
|
||||
#undef i_flags
|
||||
#undef i_gen
|
||||
#undef i_gid
|
||||
#undef i_ib
|
||||
#undef i_mode
|
||||
#undef i_mtime
|
||||
#undef i_nlink
|
||||
#undef i_rdev
|
||||
#undef i_shortlink
|
||||
#undef i_size
|
||||
#undef i_uid
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
|
||||
void
|
||||
ext2_print_dinode( di )
|
||||
struct dinode *di;
|
||||
{
|
||||
int i;
|
||||
printf( /* "Inode: %5d" */
|
||||
" Type: %10s Mode: 0x%o Flags: 0x%x Version: %d\n",
|
||||
"n/a", di->di_mode, di->di_flags, di->di_gen);
|
||||
printf( "User: %5lu Group: %5lu Size: %lu\n",
|
||||
(unsigned long)di->di_uid, (unsigned long)di->di_gid,
|
||||
(unsigned long)di->di_size);
|
||||
printf( "Links: %3d Blockcount: %d\n",
|
||||
di->di_nlink, di->di_blocks);
|
||||
printf( "ctime: 0x%x", di->di_ctime);
|
||||
printf( "atime: 0x%x", di->di_atime);
|
||||
printf( "mtime: 0x%x", di->di_mtime);
|
||||
printf( "BLOCKS: ");
|
||||
for(i=0; i < (di->di_blocks <= 24 ? ((di->di_blocks+1)/2): 12); i++)
|
||||
printf("%d ", di->di_db[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
ext2_print_inode( in )
|
||||
struct inode *in;
|
||||
{
|
||||
int i;
|
||||
|
||||
printf( "Inode: %5d", in->i_number);
|
||||
ext2_print_dinode(&in->i_din);
|
||||
printf( /* "Inode: %5d" */
|
||||
" Type: %10s Mode: 0x%o Flags: 0x%x Version: %d\n",
|
||||
"n/a", in->i_mode, in->i_flags, in->i_gen);
|
||||
printf( "User: %5lu Group: %5lu Size: %lu\n",
|
||||
(unsigned long)in->i_uid, (unsigned long)in->i_gid,
|
||||
(unsigned long)in->i_size);
|
||||
printf( "Links: %3d Blockcount: %d\n",
|
||||
in->i_nlink, in->i_blocks);
|
||||
printf( "ctime: 0x%x", in->i_ctime);
|
||||
printf( "atime: 0x%x", in->i_atime);
|
||||
printf( "mtime: 0x%x", in->i_mtime);
|
||||
printf( "BLOCKS: ");
|
||||
for(i=0; i < (in->i_blocks <= 24 ? ((in->i_blocks+1)/2): 12); i++)
|
||||
printf("%d ", in->i_db[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* raw ext2 inode to dinode
|
||||
* raw ext2 inode to inode
|
||||
*/
|
||||
void
|
||||
ext2_ei2di(ei, di)
|
||||
struct ext2_inode *ei;
|
||||
struct dinode *di;
|
||||
ext2_ei2i(ei, ip)
|
||||
struct ext2_inode *ei;
|
||||
struct inode *ip;
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
di->di_nlink = ei->i_links_count;
|
||||
ip->i_nlink = ei->i_links_count;
|
||||
/* Godmar thinks - if the link count is zero, then the inode is
|
||||
unused - according to ext2 standards. Ufs marks this fact
|
||||
by setting i_mode to zero - why ?
|
||||
I can see that this might lead to problems in an undelete.
|
||||
*/
|
||||
di->di_mode = ei->i_links_count ? ei->i_mode : 0;
|
||||
di->di_size = ei->i_size;
|
||||
di->di_atime = ei->i_atime;
|
||||
di->di_mtime = ei->i_mtime;
|
||||
di->di_ctime = ei->i_ctime;
|
||||
di->di_flags = 0;
|
||||
di->di_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0;
|
||||
di->di_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0;
|
||||
di->di_blocks = ei->i_blocks;
|
||||
di->di_gen = ei->i_generation;
|
||||
di->di_uid = ei->i_uid;
|
||||
di->di_gid = ei->i_gid;
|
||||
ip->i_mode = ei->i_links_count ? ei->i_mode : 0;
|
||||
ip->i_size = ei->i_size;
|
||||
ip->i_atime = ei->i_atime;
|
||||
ip->i_mtime = ei->i_mtime;
|
||||
ip->i_ctime = ei->i_ctime;
|
||||
ip->i_flags = 0;
|
||||
ip->i_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0;
|
||||
ip->i_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0;
|
||||
ip->i_blocks = ei->i_blocks;
|
||||
ip->i_gen = ei->i_generation;
|
||||
ip->i_uid = ei->i_uid;
|
||||
ip->i_gid = ei->i_gid;
|
||||
/* XXX use memcpy */
|
||||
for(i = 0; i < NDADDR; i++)
|
||||
di->di_db[i] = ei->i_block[i];
|
||||
for(i = 0; i < NIADDR; i++)
|
||||
di->di_ib[i] = ei->i_block[EXT2_NDIR_BLOCKS + i];
|
||||
for(i = 0; i < NDADDR; i++)
|
||||
ip->i_db[i] = ei->i_block[i];
|
||||
for(i = 0; i < NIADDR; i++)
|
||||
ip->i_ib[i] = ei->i_block[EXT2_NDIR_BLOCKS + i];
|
||||
}
|
||||
|
||||
/*
|
||||
* dinode to raw ext2 inode
|
||||
* inode to raw ext2 inode
|
||||
*/
|
||||
void
|
||||
ext2_di2ei(di, ei)
|
||||
struct dinode *di;
|
||||
struct ext2_inode *ei;
|
||||
ext2_i2ei(ip, ei)
|
||||
struct inode *ip;
|
||||
struct ext2_inode *ei;
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
ei->i_mode = di->di_mode;
|
||||
ei->i_links_count = di->di_nlink;
|
||||
ei->i_mode = ip->i_mode;
|
||||
ei->i_links_count = ip->i_nlink;
|
||||
/*
|
||||
Godmar thinks: if dtime is nonzero, ext2 says this inode
|
||||
has been deleted, this would correspond to a zero link count
|
||||
*/
|
||||
ei->i_dtime = ei->i_links_count ? 0 : di->di_mtime;
|
||||
ei->i_size = di->di_size;
|
||||
ei->i_atime = di->di_atime;
|
||||
ei->i_mtime = di->di_mtime;
|
||||
ei->i_ctime = di->di_ctime;
|
||||
ei->i_flags = di->di_flags;
|
||||
ei->i_flags = 0;
|
||||
ei->i_flags |= (di->di_flags & APPEND) ? EXT2_APPEND_FL: 0;
|
||||
ei->i_flags |= (di->di_flags & IMMUTABLE)
|
||||
? EXT2_IMMUTABLE_FL: 0;
|
||||
ei->i_blocks = di->di_blocks;
|
||||
ei->i_generation = di->di_gen;
|
||||
ei->i_uid = di->di_uid;
|
||||
ei->i_gid = di->di_gid;
|
||||
ei->i_dtime = ei->i_links_count ? 0 : ip->i_mtime;
|
||||
ei->i_size = ip->i_size;
|
||||
ei->i_atime = ip->i_atime;
|
||||
ei->i_mtime = ip->i_mtime;
|
||||
ei->i_ctime = ip->i_ctime;
|
||||
ei->i_flags = ip->i_flags;
|
||||
ei->i_flags = 0;
|
||||
ei->i_flags |= (ip->i_flags & APPEND) ? EXT2_APPEND_FL: 0;
|
||||
ei->i_flags |= (ip->i_flags & IMMUTABLE) ? EXT2_IMMUTABLE_FL: 0;
|
||||
ei->i_blocks = ip->i_blocks;
|
||||
ei->i_generation = ip->i_gen;
|
||||
ei->i_uid = ip->i_uid;
|
||||
ei->i_gid = ip->i_gid;
|
||||
/* XXX use memcpy */
|
||||
for(i = 0; i < NDADDR; i++)
|
||||
ei->i_block[i] = di->di_db[i];
|
||||
for(i = 0; i < NIADDR; i++)
|
||||
ei->i_block[EXT2_NDIR_BLOCKS + i] = di->di_ib[i];
|
||||
for(i = 0; i < NDADDR; i++)
|
||||
ei->i_block[i] = ip->i_db[i];
|
||||
for(i = 0; i < NIADDR; i++)
|
||||
ei->i_block[EXT2_NDIR_BLOCKS + i] = ip->i_ib[i];
|
||||
}
|
||||
|
@ -35,9 +35,8 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
@ -61,13 +60,13 @@ static void read_block_bitmap (struct mount * mp,
|
||||
unsigned int block_group,
|
||||
unsigned long bitmap_nr)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct ext2_group_desc * gdp;
|
||||
struct buffer_head * bh;
|
||||
int error;
|
||||
|
||||
gdp = get_group_desc (mp, block_group, NULL);
|
||||
if ((error = bread (VFSTOUFS(mp)->um_devvp,
|
||||
if ((error = bread (VFSTOEXT2(mp)->um_devvp,
|
||||
fsbtodb(sb, gdp->bg_block_bitmap),sb->s_blocksize, NOCRED, &bh)) != 0)
|
||||
panic ( "read_block_bitmap: "
|
||||
"Cannot read block bitmap - "
|
||||
@ -93,7 +92,7 @@ static int load__block_bitmap (struct mount * mp,
|
||||
unsigned int block_group)
|
||||
{
|
||||
int i, j;
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
unsigned long block_bitmap_number;
|
||||
struct buffer_head * block_bitmap;
|
||||
|
||||
@ -152,7 +151,7 @@ static int load__block_bitmap (struct mount * mp,
|
||||
static __inline int load_block_bitmap (struct mount * mp,
|
||||
unsigned int block_group)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
if (sb->s_loaded_block_bitmaps > 0 &&
|
||||
sb->s_block_bitmap_number[0] == block_group)
|
||||
return 0;
|
||||
@ -168,7 +167,7 @@ static __inline int load_block_bitmap (struct mount * mp,
|
||||
void ext2_free_blocks (struct mount * mp, unsigned long block,
|
||||
unsigned long count)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct buffer_head * bh;
|
||||
struct buffer_head * bh2;
|
||||
unsigned long block_group;
|
||||
@ -182,13 +181,13 @@ void ext2_free_blocks (struct mount * mp, unsigned long block,
|
||||
printf ("ext2_free_blocks: nonexistent device");
|
||||
return;
|
||||
}
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
if (block < es->s_first_data_block ||
|
||||
(block + count) > es->s_blocks_count) {
|
||||
printf ( "ext2_free_blocks: "
|
||||
"Freeing blocks not in datazone - "
|
||||
"block = %lu, count = %lu", block, count);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -238,7 +237,7 @@ void ext2_free_blocks (struct mount * mp, unsigned long block,
|
||||
}
|
||||
****/
|
||||
sb->s_dirt = 1;
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -253,7 +252,7 @@ int ext2_new_block (struct mount * mp, unsigned long goal,
|
||||
u_int32_t * prealloc_count,
|
||||
u_int32_t * prealloc_block)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct buffer_head * bh;
|
||||
struct buffer_head * bh2;
|
||||
char * p, * r;
|
||||
@ -269,7 +268,7 @@ int ext2_new_block (struct mount * mp, unsigned long goal,
|
||||
printf ("ext2_new_block: nonexistent device");
|
||||
return 0;
|
||||
}
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
|
||||
ext2_debug ("goal=%lu.\n", goal);
|
||||
|
||||
@ -356,7 +355,7 @@ repeat:
|
||||
break;
|
||||
}
|
||||
if (k >= sb->s_groups_count) {
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return 0;
|
||||
}
|
||||
bitmap_nr = load_block_bitmap (mp, i);
|
||||
@ -372,7 +371,7 @@ repeat:
|
||||
if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
|
||||
printf ( "ext2_new_block: "
|
||||
"Free blocks count corrupted for block group %d", i);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -439,7 +438,7 @@ got_block:
|
||||
printf ( "ext2_new_block: "
|
||||
"block >= blocks count - "
|
||||
"block_group = %d, block=%d", i, j);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -450,14 +449,14 @@ got_block:
|
||||
mark_buffer_dirty(bh2);
|
||||
es->s_free_blocks_count--;
|
||||
sb->s_dirt = 1;
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return j;
|
||||
}
|
||||
|
||||
#ifdef unused
|
||||
static unsigned long ext2_count_free_blocks (struct mount * mp)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
#ifdef EXT2FS_DEBUG
|
||||
struct ext2_super_block * es;
|
||||
unsigned long desc_count, bitmap_count, x;
|
||||
@ -465,7 +464,7 @@ static unsigned long ext2_count_free_blocks (struct mount * mp)
|
||||
struct ext2_group_desc * gdp;
|
||||
int i;
|
||||
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
es = sb->s_es;
|
||||
desc_count = 0;
|
||||
bitmap_count = 0;
|
||||
@ -482,7 +481,7 @@ static unsigned long ext2_count_free_blocks (struct mount * mp)
|
||||
}
|
||||
ext2_debug( "stored = %lu, computed = %lu, %lu\n",
|
||||
es->s_free_blocks_count, desc_count, bitmap_count);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return bitmap_count;
|
||||
#else
|
||||
return sb->s_es->s_free_blocks_count;
|
||||
@ -520,7 +519,7 @@ int ext2_group_sparse(int group)
|
||||
#ifdef unused
|
||||
static void ext2_check_blocks_bitmap (struct mount * mp)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct buffer_head * bh;
|
||||
struct ext2_super_block * es;
|
||||
unsigned long desc_count, bitmap_count, x;
|
||||
@ -529,7 +528,7 @@ static void ext2_check_blocks_bitmap (struct mount * mp)
|
||||
struct ext2_group_desc * gdp;
|
||||
int i, j;
|
||||
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
es = sb->s_es;
|
||||
desc_count = 0;
|
||||
bitmap_count = 0;
|
||||
@ -586,7 +585,7 @@ static void ext2_check_blocks_bitmap (struct mount * mp)
|
||||
"Wrong free blocks count in super block, "
|
||||
"stored = %lu, counted = %lu",
|
||||
(unsigned long) es->s_free_blocks_count, bitmap_count);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
}
|
||||
#endif /* unused */
|
||||
|
||||
|
@ -36,10 +36,8 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
@ -69,7 +67,7 @@ struct ext2_group_desc * get_group_desc (struct mount * mp,
|
||||
unsigned int block_group,
|
||||
struct buffer_head ** bh)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
unsigned long group_desc;
|
||||
unsigned long desc;
|
||||
struct ext2_group_desc * gdp;
|
||||
@ -98,13 +96,13 @@ static void read_inode_bitmap (struct mount * mp,
|
||||
unsigned long block_group,
|
||||
unsigned int bitmap_nr)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct ext2_group_desc * gdp;
|
||||
struct buffer_head * bh;
|
||||
int error;
|
||||
|
||||
gdp = get_group_desc (mp, block_group, NULL);
|
||||
if ((error = bread (VFSTOUFS(mp)->um_devvp,
|
||||
if ((error = bread (VFSTOEXT2(mp)->um_devvp,
|
||||
fsbtodb(sb, gdp->bg_inode_bitmap),
|
||||
sb->s_blocksize,
|
||||
NOCRED, &bh)) != 0)
|
||||
@ -131,7 +129,7 @@ static void read_inode_bitmap (struct mount * mp,
|
||||
static int load_inode_bitmap (struct mount * mp,
|
||||
unsigned int block_group)
|
||||
{
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
int i, j;
|
||||
unsigned long inode_bitmap_number;
|
||||
struct buffer_head * inode_bitmap;
|
||||
@ -447,14 +445,14 @@ repeat:
|
||||
static unsigned long ext2_count_free_inodes (struct mount * mp)
|
||||
{
|
||||
#ifdef EXT2FS_DEBUG
|
||||
struct ext2_sb_info *sb = VFSTOUFS(mp)->um_e2fs;
|
||||
struct ext2_sb_info *sb = VFSTOEXT2(mp)->um_e2fs;
|
||||
struct ext2_super_block * es;
|
||||
unsigned long desc_count, bitmap_count, x;
|
||||
int bitmap_nr;
|
||||
struct ext2_group_desc * gdp;
|
||||
int i;
|
||||
|
||||
lock_super (VFSTOUFS(mp)->um_devvp);
|
||||
lock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
es = sb->s_es;
|
||||
desc_count = 0;
|
||||
bitmap_count = 0;
|
||||
@ -471,10 +469,10 @@ static unsigned long ext2_count_free_inodes (struct mount * mp)
|
||||
}
|
||||
ext2_debug("stored = %lu, computed = %lu, %lu\n",
|
||||
es->s_free_inodes_count, desc_count, bitmap_count);
|
||||
unlock_super (VFSTOUFS(mp)->um_devvp);
|
||||
unlock_super (VFSTOEXT2(mp)->um_devvp);
|
||||
return desc_count;
|
||||
#else
|
||||
return VFSTOUFS(mp)->um_e2fsb->s_free_inodes_count;
|
||||
return VFSTOEXT2(mp)->um_e2fsb->s_free_inodes_count;
|
||||
#endif
|
||||
}
|
||||
#endif /* unused */
|
||||
|
@ -55,13 +55,10 @@
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/dirent.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <ufs/ufs/ufs_extern.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
#include <gnu/ext2fs/ext2_fs.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
@ -364,7 +361,7 @@ ext2_lookup(ap)
|
||||
* profiling time and hence has been removed in the interest
|
||||
* of simplicity.
|
||||
*/
|
||||
bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
|
||||
bmask = VFSTOEXT2(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
|
||||
if (nameiop != LOOKUP || dp->i_diroff == 0 ||
|
||||
dp->i_diroff > dp->i_size) {
|
||||
entryoffsetinblock = 0;
|
||||
@ -373,7 +370,8 @@ ext2_lookup(ap)
|
||||
} else {
|
||||
dp->i_offset = dp->i_diroff;
|
||||
if ((entryoffsetinblock = dp->i_offset & bmask) &&
|
||||
(error = UFS_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)))
|
||||
(error = ext2_blkatoff(vdp, (off_t)dp->i_offset, NULL,
|
||||
&bp)))
|
||||
return (error);
|
||||
numdirpasses = 2;
|
||||
nchstats.ncs_2passes++;
|
||||
@ -391,7 +389,8 @@ searchloop:
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
if ((error =
|
||||
UFS_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)) != 0)
|
||||
ext2_blkatoff(vdp, (off_t)dp->i_offset, NULL,
|
||||
&bp)) != 0)
|
||||
return (error);
|
||||
entryoffsetinblock = 0;
|
||||
}
|
||||
@ -416,7 +415,7 @@ searchloop:
|
||||
if (ep->rec_len == 0 ||
|
||||
(dirchk && ext2_dirbadentry(vdp, ep, entryoffsetinblock))) {
|
||||
int i;
|
||||
ufs_dirbad(dp, dp->i_offset, "mangled entry");
|
||||
ext2_dirbad(dp, dp->i_offset, "mangled entry");
|
||||
i = DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1));
|
||||
dp->i_offset += i;
|
||||
entryoffsetinblock += i;
|
||||
@ -558,7 +557,7 @@ found:
|
||||
*/
|
||||
if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->name_len)
|
||||
> dp->i_size) {
|
||||
ufs_dirbad(dp, dp->i_offset, "i_size too small");
|
||||
ext2_dirbad(dp, dp->i_offset, "i_size too small");
|
||||
dp->i_size = entryoffsetinblock+EXT2_DIR_REC_LEN(ep->name_len);
|
||||
dp->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
}
|
||||
@ -700,6 +699,21 @@ found:
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ext2_dirbad(ip, offset, how)
|
||||
struct inode *ip;
|
||||
doff_t offset;
|
||||
char *how;
|
||||
{
|
||||
struct mount *mp;
|
||||
|
||||
mp = ITOV(ip)->v_mount;
|
||||
(void)printf("%s: bad dir ino %lu at offset %ld: %s\n",
|
||||
mp->mnt_stat.f_mntonname, (u_long)ip->i_number, (long)offset, how);
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
panic("ext2_dirbad: bad dir");
|
||||
}
|
||||
|
||||
/*
|
||||
* Do consistency checking on a directory entry:
|
||||
* record length must be multiple of 4
|
||||
@ -804,7 +818,7 @@ ext2_direnter(ip, dvp, cnp)
|
||||
auio.uio_td = (struct thread *)0;
|
||||
error = VOP_WRITE(dvp, &auio, IO_SYNC, cnp->cn_cred);
|
||||
if (DIRBLKSIZ >
|
||||
VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
|
||||
VFSTOEXT2(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
|
||||
/* XXX should grow with balloc() */
|
||||
panic("ext2_direnter: frag size");
|
||||
else if (!error) {
|
||||
@ -835,7 +849,8 @@ ext2_direnter(ip, dvp, cnp)
|
||||
/*
|
||||
* Get the block containing the space for the new directory entry.
|
||||
*/
|
||||
if ((error = UFS_BLKATOFF(dvp, (off_t)dp->i_offset, &dirbuf, &bp)) != 0)
|
||||
if ((error = ext2_blkatoff(dvp, (off_t)dp->i_offset, &dirbuf,
|
||||
&bp)) != 0)
|
||||
return (error);
|
||||
/*
|
||||
* Find space for the new entry. In the simple case, the entry at
|
||||
@ -881,7 +896,7 @@ ext2_direnter(ip, dvp, cnp)
|
||||
error = BUF_WRITE(bp);
|
||||
dp->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
if (!error && dp->i_endoff && dp->i_endoff < dp->i_size)
|
||||
error = UFS_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC,
|
||||
error = ext2_truncate(dvp, (off_t)dp->i_endoff, IO_SYNC,
|
||||
cnp->cn_cred, cnp->cn_thread);
|
||||
return (error);
|
||||
}
|
||||
@ -914,7 +929,8 @@ ext2_dirremove(dvp, cnp)
|
||||
* First entry in block: set d_ino to zero.
|
||||
*/
|
||||
if ((error =
|
||||
UFS_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0)
|
||||
ext2_blkatoff(dvp, (off_t)dp->i_offset, (char **)&ep,
|
||||
&bp)) != 0)
|
||||
return (error);
|
||||
ep->inode = 0;
|
||||
error = BUF_WRITE(bp);
|
||||
@ -924,7 +940,7 @@ ext2_dirremove(dvp, cnp)
|
||||
/*
|
||||
* Collapse new free space into previous entry.
|
||||
*/
|
||||
if ((error = UFS_BLKATOFF(dvp, (off_t)(dp->i_offset - dp->i_count),
|
||||
if ((error = ext2_blkatoff(dvp, (off_t)(dp->i_offset - dp->i_count),
|
||||
(char **)&ep, &bp)) != 0)
|
||||
return (error);
|
||||
ep->rec_len += dp->i_reclen;
|
||||
@ -948,7 +964,8 @@ ext2_dirrewrite(dp, ip, cnp)
|
||||
struct vnode *vdp = ITOV(dp);
|
||||
int error;
|
||||
|
||||
if ((error = UFS_BLKATOFF(vdp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0)
|
||||
if ((error = ext2_blkatoff(vdp, (off_t)dp->i_offset, (char **)&ep,
|
||||
&bp)) != 0)
|
||||
return (error);
|
||||
ep->inode = ip->i_number;
|
||||
if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es,
|
||||
|
@ -301,12 +301,12 @@ WRITE(ap)
|
||||
ip->i_mode &= ~(ISUID | ISGID);
|
||||
if (error) {
|
||||
if (ioflag & IO_UNIT) {
|
||||
(void)UFS_TRUNCATE(vp, osize,
|
||||
(void)ext2_truncate(vp, osize,
|
||||
ioflag & IO_SYNC, ap->a_cred, uio->uio_td);
|
||||
uio->uio_offset -= resid - uio->uio_resid;
|
||||
uio->uio_resid = resid;
|
||||
}
|
||||
} else if (resid > uio->uio_resid && (ioflag & IO_SYNC))
|
||||
error = UFS_UPDATE(vp, 1);
|
||||
error = ext2_update(vp, 1);
|
||||
return (error);
|
||||
}
|
||||
|
@ -50,9 +50,7 @@
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
#include <gnu/ext2fs/ext2_fs_sb.h>
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
@ -121,7 +119,7 @@ ext2_checkoverlap(bp, ip)
|
||||
continue;
|
||||
vprint("Disk overlap", vp);
|
||||
(void)printf("\tstart %d, end %d overlap start %lld, end %ld\n",
|
||||
start, last, ep->b_blkno,
|
||||
start, last, (long long)ep->b_blkno,
|
||||
(long)(ep->b_blkno + btodb(ep->b_bcount) - 1));
|
||||
panic("Disk buffer overlap");
|
||||
}
|
||||
|
@ -40,8 +40,6 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "opt_quota.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
@ -57,12 +55,8 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
#include <ufs/ufs/extattr.h>
|
||||
#include <ufs/ufs/quota.h>
|
||||
#include <ufs/ufs/ufsmount.h>
|
||||
#include <ufs/ufs/inode.h>
|
||||
#include <ufs/ufs/ufs_extern.h>
|
||||
|
||||
#include <gnu/ext2fs/ext2_mount.h>
|
||||
#include <gnu/ext2fs/inode.h>
|
||||
|
||||
#include <gnu/ext2fs/fs.h>
|
||||
#include <gnu/ext2fs/ext2_extern.h>
|
||||
@ -71,26 +65,29 @@
|
||||
|
||||
static int ext2_fhtovp(struct mount *, struct fid *, struct vnode **);
|
||||
static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td);
|
||||
static int ext2_init(struct vfsconf *);
|
||||
static int ext2_mount(struct mount *,
|
||||
char *, caddr_t, struct nameidata *, struct thread *);
|
||||
static int ext2_mountfs(struct vnode *, struct mount *, struct thread *);
|
||||
static int ext2_reload(struct mount *mountp, struct ucred *cred,
|
||||
struct thread *td);
|
||||
static int ext2_sbupdate(struct ufsmount *, int);
|
||||
static int ext2_root(struct mount *, struct vnode **vpp);
|
||||
static int ext2_sbupdate(struct ext2mount *, int);
|
||||
static int ext2_statfs(struct mount *, struct statfs *, struct thread *);
|
||||
static int ext2_sync(struct mount *, int, struct ucred *, struct thread *);
|
||||
static int ext2_unmount(struct mount *, int, struct thread *);
|
||||
static int ext2_vget(struct mount *, ino_t, int, struct vnode **);
|
||||
static int ext2_vptofh(struct vnode *, struct fid *);
|
||||
|
||||
static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
|
||||
MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
|
||||
static MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure");
|
||||
|
||||
static struct vfsops ext2fs_vfsops = {
|
||||
ext2_mount,
|
||||
ufs_start, /* empty function */
|
||||
vfs_stdstart,
|
||||
ext2_unmount,
|
||||
ufs_root, /* root inode via vget */
|
||||
ufs_quotactl, /* does operations associated with quotas */
|
||||
ext2_root, /* root inode via vget */
|
||||
vfs_stdquotactl,
|
||||
ext2_statfs,
|
||||
ext2_sync,
|
||||
ext2_vget,
|
||||
@ -129,7 +126,7 @@ ext2_mountroot()
|
||||
register struct ext2_sb_info *fs;
|
||||
register struct mount *mp;
|
||||
struct thread *td = curthread;
|
||||
struct ufsmount *ump;
|
||||
struct ext2mount *ump;
|
||||
u_int size;
|
||||
int error;
|
||||
|
||||
@ -155,7 +152,7 @@ ext2_mountroot()
|
||||
TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list);
|
||||
mp->mnt_flag |= MNT_ROOTFS;
|
||||
mp->mnt_vnodecovered = NULLVP;
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt));
|
||||
fs->fs_fsmnt[0] = '/';
|
||||
@ -180,13 +177,13 @@ static int
|
||||
ext2_mount(mp, path, data, ndp, td)
|
||||
register struct mount *mp;
|
||||
char *path;
|
||||
caddr_t data; /* this is actually a (struct ufs_args *) */
|
||||
caddr_t data; /* this is actually a (struct ext2_args *) */
|
||||
struct nameidata *ndp;
|
||||
struct thread *td;
|
||||
{
|
||||
struct vnode *devvp;
|
||||
struct ufs_args args;
|
||||
struct ufsmount *ump = 0;
|
||||
struct ext2_args args;
|
||||
struct ext2mount *ump = 0;
|
||||
register struct ext2_sb_info *fs;
|
||||
size_t size;
|
||||
int error, flags;
|
||||
@ -195,7 +192,7 @@ ext2_mount(mp, path, data, ndp, td)
|
||||
/* Double-check the length of path.. */
|
||||
if (strlen(path) >= MAXMNTLEN - 1)
|
||||
return (ENAMETOOLONG);
|
||||
error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args));
|
||||
error = copyin(data, (caddr_t)&args, sizeof (struct ext2_args));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
/*
|
||||
@ -203,7 +200,7 @@ ext2_mount(mp, path, data, ndp, td)
|
||||
* read/write; if there is no device name, that's all we do.
|
||||
*/
|
||||
if (mp->mnt_flag & MNT_UPDATE) {
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
error = 0;
|
||||
if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) {
|
||||
@ -310,7 +307,7 @@ ext2_mount(mp, path, data, ndp, td)
|
||||
vrele(devvp);
|
||||
return (error);
|
||||
}
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
/*
|
||||
* Note that this strncpy() is ok because of a check at the start
|
||||
@ -466,7 +463,7 @@ static int compute_sb_data(devvp, es, fs)
|
||||
V(s_db_per_group)
|
||||
|
||||
fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *),
|
||||
M_UFSMNT, M_WAITOK);
|
||||
M_EXT2MNT, M_WAITOK);
|
||||
|
||||
/* adjust logic_sb_block */
|
||||
if(fs->s_blocksize > SBSIZE)
|
||||
@ -481,7 +478,7 @@ static int compute_sb_data(devvp, es, fs)
|
||||
if(error) {
|
||||
for (j = 0; j < i; j++)
|
||||
brelse(fs->s_group_desc[j]);
|
||||
bsd_free(fs->s_group_desc, M_UFSMNT);
|
||||
bsd_free(fs->s_group_desc, M_EXT2MNT);
|
||||
printf("EXT2-fs: unable to read group descriptors (%d)\n", error);
|
||||
return EIO;
|
||||
}
|
||||
@ -491,7 +488,7 @@ static int compute_sb_data(devvp, es, fs)
|
||||
if(!ext2_check_descriptors(fs)) {
|
||||
for (j = 0; j < db_count; j++)
|
||||
ULCK_BUF(fs->s_group_desc[j])
|
||||
bsd_free(fs->s_group_desc, M_UFSMNT);
|
||||
bsd_free(fs->s_group_desc, M_EXT2MNT);
|
||||
printf("EXT2-fs: (ext2_check_descriptors failure) "
|
||||
"unable to read group descriptors\n");
|
||||
return EIO;
|
||||
@ -539,7 +536,7 @@ ext2_reload(mountp, cred, td)
|
||||
/*
|
||||
* Step 1: invalidate all cached meta-data.
|
||||
*/
|
||||
devvp = VFSTOUFS(mountp)->um_devvp;
|
||||
devvp = VFSTOEXT2(mountp)->um_devvp;
|
||||
if (vinvalbuf(devvp, 0, cred, td, 0, 0))
|
||||
panic("ext2_reload: dirty1");
|
||||
/*
|
||||
@ -553,7 +550,7 @@ ext2_reload(mountp, cred, td)
|
||||
brelse(bp);
|
||||
return (EIO); /* XXX needs translation */
|
||||
}
|
||||
fs = VFSTOUFS(mountp)->um_e2fs;
|
||||
fs = VFSTOEXT2(mountp)->um_e2fs;
|
||||
bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block));
|
||||
|
||||
if((error = compute_sb_data(devvp, es, fs)) != 0) {
|
||||
@ -600,9 +597,8 @@ loop:
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data +
|
||||
EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)),
|
||||
&ip->i_din);
|
||||
ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data +
|
||||
EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), ip);
|
||||
brelse(bp);
|
||||
vput(vp);
|
||||
mtx_lock(&mntvnode_mtx);
|
||||
@ -620,12 +616,12 @@ ext2_mountfs(devvp, mp, td)
|
||||
struct mount *mp;
|
||||
struct thread *td;
|
||||
{
|
||||
register struct ufsmount *ump;
|
||||
register struct ext2mount *ump;
|
||||
struct buf *bp;
|
||||
register struct ext2_sb_info *fs;
|
||||
struct ext2_super_block * es;
|
||||
dev_t dev = devvp->v_rdev;
|
||||
int error, i;
|
||||
int error;
|
||||
int ronly;
|
||||
|
||||
/*
|
||||
@ -677,22 +673,16 @@ ext2_mountfs(devvp, mp, td)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
ump = bsd_malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
|
||||
ump = bsd_malloc(sizeof *ump, M_EXT2MNT, M_WAITOK);
|
||||
bzero((caddr_t)ump, sizeof *ump);
|
||||
ump->um_malloctype = M_EXT2NODE;
|
||||
ump->um_blkatoff = ext2_blkatoff;
|
||||
ump->um_truncate = ext2_truncate;
|
||||
ump->um_update = ext2_update;
|
||||
ump->um_valloc = ext2_valloc;
|
||||
ump->um_vfree = ext2_vfree;
|
||||
/* I don't know whether this is the right strategy. Note that
|
||||
we dynamically allocate both a ext2_sb_info and a ext2_super_block
|
||||
while Linux keeps the super block in a locked buffer
|
||||
*/
|
||||
ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info),
|
||||
M_UFSMNT, M_WAITOK);
|
||||
M_EXT2MNT, M_WAITOK);
|
||||
ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block),
|
||||
M_UFSMNT, M_WAITOK);
|
||||
M_EXT2MNT, M_WAITOK);
|
||||
bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block));
|
||||
if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)))
|
||||
goto out;
|
||||
@ -720,14 +710,12 @@ ext2_mountfs(devvp, mp, td)
|
||||
ump->um_mountp = mp;
|
||||
ump->um_dev = dev;
|
||||
ump->um_devvp = devvp;
|
||||
/* setting those two parameters allows us to use
|
||||
/* setting those two parameters allowed us to use
|
||||
ufs_bmap w/o changse !
|
||||
*/
|
||||
ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs);
|
||||
ump->um_bptrtodb = fs->s_es->s_log_block_size + 1;
|
||||
ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs);
|
||||
for (i = 0; i < MAXQUOTAS; i++)
|
||||
ump->um_quotas[i] = NULLVP;
|
||||
devvp->v_rdev->si_mountpoint = mp;
|
||||
if (ronly == 0)
|
||||
ext2_sbupdate(ump, MNT_WAIT);
|
||||
@ -737,9 +725,9 @@ out:
|
||||
brelse(bp);
|
||||
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, td);
|
||||
if (ump) {
|
||||
bsd_free(ump->um_e2fs->s_es, M_UFSMNT);
|
||||
bsd_free(ump->um_e2fs, M_UFSMNT);
|
||||
bsd_free(ump, M_UFSMNT);
|
||||
bsd_free(ump->um_e2fs->s_es, M_EXT2MNT);
|
||||
bsd_free(ump->um_e2fs, M_EXT2MNT);
|
||||
bsd_free(ump, M_EXT2MNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
}
|
||||
return (error);
|
||||
@ -754,7 +742,7 @@ ext2_unmount(mp, mntflags, td)
|
||||
int mntflags;
|
||||
struct thread *td;
|
||||
{
|
||||
register struct ufsmount *ump;
|
||||
register struct ext2mount *ump;
|
||||
register struct ext2_sb_info *fs;
|
||||
int error, flags, ronly, i;
|
||||
|
||||
@ -766,7 +754,7 @@ ext2_unmount(mp, mntflags, td)
|
||||
}
|
||||
if ((error = ext2_flushfiles(mp, flags, td)) != 0)
|
||||
return (error);
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
ronly = fs->s_rd_only;
|
||||
if (ronly == 0) {
|
||||
@ -778,7 +766,7 @@ ext2_unmount(mp, mntflags, td)
|
||||
/* release buffers containing group descriptors */
|
||||
for(i = 0; i < fs->s_db_per_group; i++)
|
||||
ULCK_BUF(fs->s_group_desc[i])
|
||||
bsd_free(fs->s_group_desc, M_UFSMNT);
|
||||
bsd_free(fs->s_group_desc, M_EXT2MNT);
|
||||
|
||||
/* release cached inode/block bitmaps */
|
||||
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
|
||||
@ -793,9 +781,9 @@ ext2_unmount(mp, mntflags, td)
|
||||
error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE,
|
||||
NOCRED, td);
|
||||
vrele(ump->um_devvp);
|
||||
bsd_free(fs->s_es, M_UFSMNT);
|
||||
bsd_free(fs, M_UFSMNT);
|
||||
bsd_free(ump, M_UFSMNT);
|
||||
bsd_free(fs->s_es, M_EXT2MNT);
|
||||
bsd_free(fs, M_EXT2MNT);
|
||||
bsd_free(ump, M_EXT2MNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
return (error);
|
||||
@ -810,28 +798,8 @@ ext2_flushfiles(mp, flags, td)
|
||||
int flags;
|
||||
struct thread *td;
|
||||
{
|
||||
register struct ufsmount *ump;
|
||||
int error;
|
||||
#if QUOTA
|
||||
int i;
|
||||
#endif
|
||||
|
||||
ump = VFSTOUFS(mp);
|
||||
#if QUOTA
|
||||
if (mp->mnt_flag & MNT_QUOTA) {
|
||||
if ((error = vflush(mp, 0, SKIPSYSTEM|flags)) != 0)
|
||||
return (error);
|
||||
for (i = 0; i < MAXQUOTAS; i++) {
|
||||
if (ump->um_quotas[i] == NULLVP)
|
||||
continue;
|
||||
quotaoff(td, mp, i);
|
||||
}
|
||||
/*
|
||||
* Here we fall through to vflush again to ensure
|
||||
* that we have gotten rid of all the system vnodes.
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
error = vflush(mp, 0, flags);
|
||||
return (error);
|
||||
}
|
||||
@ -847,12 +815,12 @@ ext2_statfs(mp, sbp, td)
|
||||
struct thread *td;
|
||||
{
|
||||
unsigned long overhead;
|
||||
register struct ufsmount *ump;
|
||||
register struct ext2mount *ump;
|
||||
register struct ext2_sb_info *fs;
|
||||
register struct ext2_super_block *es;
|
||||
int i, nsb;
|
||||
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
fs = ump->um_e2fs;
|
||||
es = fs->s_es;
|
||||
|
||||
@ -908,7 +876,7 @@ ext2_sync(mp, waitfor, cred, td)
|
||||
{
|
||||
struct vnode *nvp, *vp;
|
||||
struct inode *ip;
|
||||
struct ufsmount *ump = VFSTOUFS(mp);
|
||||
struct ext2mount *ump = VFSTOEXT2(mp);
|
||||
struct ext2_sb_info *fs;
|
||||
int error, allerror = 0;
|
||||
|
||||
@ -964,9 +932,6 @@ loop:
|
||||
allerror = error;
|
||||
VOP_UNLOCK(ump->um_devvp, 0, td);
|
||||
}
|
||||
#if QUOTA
|
||||
qsync(mp);
|
||||
#endif
|
||||
/*
|
||||
* Write back modified superblock.
|
||||
*/
|
||||
@ -994,17 +959,17 @@ ext2_vget(mp, ino, flags, vpp)
|
||||
{
|
||||
register struct ext2_sb_info *fs;
|
||||
register struct inode *ip;
|
||||
struct ufsmount *ump;
|
||||
struct ext2mount *ump;
|
||||
struct buf *bp;
|
||||
struct vnode *vp;
|
||||
dev_t dev;
|
||||
int i, error;
|
||||
int used_blocks;
|
||||
|
||||
ump = VFSTOUFS(mp);
|
||||
ump = VFSTOEXT2(mp);
|
||||
dev = ump->um_dev;
|
||||
restart:
|
||||
if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
|
||||
if ((error = ext2_ihashget(dev, ino, flags, vpp)) != 0)
|
||||
return (error);
|
||||
if (*vpp != NULL)
|
||||
return (0);
|
||||
@ -1048,17 +1013,13 @@ restart:
|
||||
ip->i_e2fs = fs = ump->um_e2fs;
|
||||
ip->i_dev = dev;
|
||||
ip->i_number = ino;
|
||||
#if QUOTA
|
||||
for (i = 0; i < MAXQUOTAS; i++)
|
||||
ip->i_dquot[i] = NODQUOT;
|
||||
#endif
|
||||
/*
|
||||
* Put it onto its hash chain and lock it so that other requests for
|
||||
* this inode will block if they arrive while we are sleeping waiting
|
||||
* for old data structures to be purged or for the contents of the
|
||||
* disk portion of this inode to be read.
|
||||
*/
|
||||
ufs_ihashins(ip);
|
||||
ext2_ihashins(ip);
|
||||
|
||||
if (ext2fs_inode_hash_lock < 0)
|
||||
wakeup(&ext2fs_inode_hash_lock);
|
||||
@ -1082,8 +1043,8 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
|
||||
return (error);
|
||||
}
|
||||
/* convert ext2 inode to dinode */
|
||||
ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE *
|
||||
ino_to_fsbo(fs, ino)), &ip->i_din);
|
||||
ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE *
|
||||
ino_to_fsbo(fs, ino)), ip);
|
||||
ip->i_block_group = ino_to_cg(fs, ino);
|
||||
ip->i_next_alloc_block = 0;
|
||||
ip->i_next_alloc_goal = 0;
|
||||
@ -1107,7 +1068,7 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
|
||||
* Initialize the vnode from the inode, check for aliases.
|
||||
* Note that the underlying vnode may have changed.
|
||||
*/
|
||||
if ((error = ufs_vinit(mp, ext2_specop_p, ext2_fifoop_p, &vp)) != 0) {
|
||||
if ((error = ext2_vinit(mp, ext2_specop_p, ext2_fifoop_p, &vp)) != 0) {
|
||||
vput(vp);
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
@ -1146,15 +1107,32 @@ ext2_fhtovp(mp, fhp, vpp)
|
||||
struct fid *fhp;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
struct inode *ip;
|
||||
register struct ufid *ufhp;
|
||||
struct vnode *nvp;
|
||||
struct ext2_sb_info *fs;
|
||||
int error;
|
||||
|
||||
ufhp = (struct ufid *)fhp;
|
||||
fs = VFSTOUFS(mp)->um_e2fs;
|
||||
fs = VFSTOEXT2(mp)->um_e2fs;
|
||||
if (ufhp->ufid_ino < ROOTINO ||
|
||||
ufhp->ufid_ino >= fs->s_groups_count * fs->s_es->s_inodes_per_group)
|
||||
return (ESTALE);
|
||||
return (ufs_fhtovp(mp, ufhp, vpp));
|
||||
|
||||
error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp);
|
||||
if (error) {
|
||||
*vpp = NULLVP;
|
||||
return (error);
|
||||
}
|
||||
ip = VTOI(nvp);
|
||||
if (ip->i_mode == 0 ||
|
||||
ip->i_gen != ufhp->ufid_gen || ip->i_nlink <= 0) {
|
||||
vput(nvp);
|
||||
*vpp = NULLVP;
|
||||
return (ESTALE);
|
||||
}
|
||||
*vpp = nvp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1182,7 +1160,7 @@ ext2_vptofh(vp, fhp)
|
||||
*/
|
||||
static int
|
||||
ext2_sbupdate(mp, waitfor)
|
||||
struct ufsmount *mp;
|
||||
struct ext2mount *mp;
|
||||
int waitfor;
|
||||
{
|
||||
register struct ext2_sb_info *fs = mp->um_e2fs;
|
||||
@ -1207,3 +1185,34 @@ printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the root of a filesystem.
|
||||
*/
|
||||
static int
|
||||
ext2_root(mp, vpp)
|
||||
struct mount *mp;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
struct vnode *nvp;
|
||||
int error;
|
||||
|
||||
error = VFS_VGET(mp, (ino_t)ROOTINO, LK_EXCLUSIVE, &nvp);
|
||||
if (error)
|
||||
return (error);
|
||||
*vpp = nvp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ext2_init(struct vfsconf *vfsp)
|
||||
{
|
||||
static int done;
|
||||
|
||||
if (done)
|
||||
return (0);
|
||||
done = 1;
|
||||
ext2_ihashinit();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -148,7 +148,7 @@ extern u_char *fragtbl[];
|
||||
* I haven't figured out yet what BSD does
|
||||
* I think I'll try a VOP_LOCK/VOP_UNLOCK on the device vnode
|
||||
*/
|
||||
#define DEVVP(inode) (VFSTOUFS(ITOV(inode)->v_mount)->um_devvp)
|
||||
#define DEVVP(inode) (VFSTOEXT2(ITOV(inode)->v_mount)->um_devvp)
|
||||
#define lock_super(devvp) vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, curthread)
|
||||
#define unlock_super(devvp) VOP_UNLOCK(devvp, 0, curthread)
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
.PATH: ${.CURDIR}/../../gnu/ext2fs
|
||||
KMOD= ext2fs
|
||||
SRCS= opt_ddb.h opt_quota.h opt_suiddir.h vnode_if.h \
|
||||
ext2_alloc.c ext2_balloc.c ext2_inode.c ext2_inode_cnv.c \
|
||||
ext2_linux_balloc.c ext2_linux_ialloc.c ext2_lookup.c ext2_subr.c \
|
||||
ext2_vfsops.c ext2_vnops.c
|
||||
ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_ihash.c ext2_inode.c \
|
||||
ext2_inode_cnv.c ext2_linux_balloc.c ext2_linux_ialloc.c \
|
||||
ext2_lookup.c ext2_subr.c ext2_vfsops.c ext2_vnops.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
Loading…
x
Reference in New Issue
Block a user