* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)lfs_vfsops.c 7.1 (Berkeley) %G%
} *uap
= (struct a
*)u
.u_ap
;
register struct inode
*ip
;
register struct nameidata
*ndp
= &u
.u_nd
;
u
.u_error
= getmdev(&dev
, uap
->fspec
);
ndp
->ni_nameiop
= LOOKUP
| FOLLOW
;
ndp
->ni_segflg
= UIO_USERSPACE
;
ndp
->ni_dirp
= (caddr_t
)uap
->freg
;
if ((ip
->i_mode
&IFMT
) != IFDIR
) {
fs
= mountfs(dev
, uap
->ronly
, ip
);
(void) copyinstr(uap
->freg
, fs
->fs_fsmnt
, sizeof(fs
->fs_fsmnt
)-1, &len
);
bzero(fs
->fs_fsmnt
+ len
, sizeof (fs
->fs_fsmnt
) - len
);
/* this routine has races if running twice */
register struct mount
*mp
= 0;
register struct buf
*bp
= 0;
(*bdevsw
[major(dev
)].d_open
)(dev
, ronly
? FREAD
: FREAD
|FWRITE
);
tp
= bread(dev
, SBLOCK
, SBSIZE
);
if (tp
->b_flags
& B_ERROR
)
for (mp
= &mount
[0]; mp
< &mount
[NMOUNT
]; mp
++)
if (mp
->m_bufp
!= 0 && dev
== mp
->m_dev
) {
for (mp
= &mount
[0]; mp
< &mount
[NMOUNT
]; mp
++)
error
= EMFILE
; /* needs translation */
mp
->m_bufp
= tp
; /* just to reserve this slot */
if (fs
->fs_magic
!= FS_MAGIC
|| fs
->fs_bsize
> MAXBSIZE
|| fs
->fs_bsize
< sizeof(struct fs
)) {
error
= EINVAL
; /* also needs translation */
bp
= geteblk((int)fs
->fs_sbsize
);
bcopy((caddr_t
)tp
->b_un
.b_addr
, (caddr_t
)bp
->b_un
.b_addr
,
fs
->fs_ronly
= (ronly
!= 0);
blks
= howmany(fs
->fs_cssize
, fs
->fs_fsize
);
space
= wmemall(vmemall
, (int)fs
->fs_cssize
);
for (i
= 0; i
< blks
; i
+= fs
->fs_frag
) {
if (i
+ fs
->fs_frag
> blks
)
size
= (blks
- i
) * fs
->fs_fsize
;
tp
= bread(dev
, fsbtodb(fs
, fs
->fs_csaddr
+ i
), size
);
if (tp
->b_flags
&B_ERROR
) {
wmemfree(space
, (int)fs
->fs_cssize
);
bcopy((caddr_t
)tp
->b_un
.b_addr
, space
, (u_int
)size
);
fs
->fs_csp
[fragstoblks(fs
, i
)] = (struct csum
*)space
;
(*bdevsw
[major(dev
)].d_close
)(dev
, ronly
? FREAD
: FREAD
|FWRITE
);
} *uap
= (struct a
*)u
.u_ap
;
u
.u_error
= unmount1(uap
->fspec
, 0);
unmount1(fname
, forcibly
)
register struct mount
*mp
;
int stillopen
, flag
, error
;
register struct inode
*ip
;
error
= getmdev(&dev
, fname
);
for (mp
= &mount
[0]; mp
< &mount
[NMOUNT
]; mp
++)
if (mp
->m_bufp
!= NULL
&& dev
== mp
->m_dev
)
xumount(dev
); /* remove unused sticky files from text table */
nchinval(dev
); /* flush the name cache */
if ((stillopen
= iflush(dev
, mp
->m_qinod
)) < 0 && !forcibly
)
if ((stillopen
= iflush(dev
)) < 0 && !forcibly
)
return (EBUSY
); /* XXX */
* Here we have to iflush again to get rid of the quota inode.
* A drag, but it would be ugly to cheat, & this doesn't happen often
(void)iflush(dev
, (struct inode
*)NULL
);
fs
= mp
->m_bufp
->b_un
.b_fs
;
wmemfree((caddr_t
)fs
->fs_csp
[0], (int)fs
->fs_cssize
);
(*bdevsw
[major(dev
)].d_close
)(dev
, flag
);
register struct fs
*fs
= mp
->m_bufp
->b_un
.b_fs
;
bp
= getblk(mp
->m_dev
, SBLOCK
, (int)fs
->fs_sbsize
);
bcopy((caddr_t
)fs
, bp
->b_un
.b_addr
, (u_int
)fs
->fs_sbsize
);
blks
= howmany(fs
->fs_cssize
, fs
->fs_fsize
);
space
= (caddr_t
)fs
->fs_csp
[0];
for (i
= 0; i
< blks
; i
+= fs
->fs_frag
) {
if (i
+ fs
->fs_frag
> blks
)
size
= (blks
- i
) * fs
->fs_fsize
;
bp
= getblk(mp
->m_dev
, fsbtodb(fs
, fs
->fs_csaddr
+ i
), size
);
bcopy(space
, bp
->b_un
.b_addr
, (u_int
)size
);
* Common code for mount and umount.
* Check that the user's argument is a reasonable
* thing on which to mount, and return the device number if so.
register struct inode
*ip
;
register struct nameidata
*ndp
= &u
.u_nd
;
ndp
->ni_nameiop
= LOOKUP
| FOLLOW
;
ndp
->ni_segflg
= UIO_USERSPACE
;
return (ENODEV
); /* needs translation */
if ((ip
->i_mode
&IFMT
) != IFBLK
) {
if (major(dev
) >= nblkdev
)