* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
* @(#)ufs_vfsops.c 8.1 (Berkeley) %G%
#include <miscfs/specfs/specdev.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/ufs/ufs_extern.h>
* Flag to permit forcible unmounting.
* Make a filesystem operational.
* Nothing to do at the moment.
error = closei(dev, IFBLK, fs->fs_ronly? FREAD : FREAD|FWRITE);
* Do operations associated with quotas
ufs_quotactl(mp
, cmds
, uid
, arg
, p
)
cmd
= cmds
>> SUBCMDSHIFT
;
if (uid
== p
->p_cred
->p_ruid
)
if (error
= suser(p
->p_ucred
, &p
->p_acflag
))
if ((u_int
)type
>= MAXQUOTAS
)
return (quotaon(p
, mp
, type
, arg
));
error
= quotaoff(p
, mp
, type
);
return (setquota(mp
, uid
, type
, arg
));
return (setuse(mp
, uid
, type
, arg
));
return (getquota(mp
, uid
, type
, arg
));
* Build hash lists of net addresses and hang them off the mount point.
* Called by ufs_mount() to set up the lists of export addresses.
ufs_hang_addrlist(mp
, argp
)
register struct netcred
*np
;
register struct radix_node_head
*rnh
;
struct sockaddr
*saddr
, *smask
= 0;
if (mp
->mnt_flag
& MNT_DEFEXPORTED
)
np
= &ump
->um_defexported
;
np
->netc_exflags
= argp
->exflags
;
np
->netc_anon
= argp
->anon
;
np
->netc_anon
.cr_ref
= 1;
mp
->mnt_flag
|= MNT_DEFEXPORTED
;
i
= sizeof(struct netcred
) + argp
->slen
+ argp
->msklen
;
np
= (struct netcred
*)malloc(i
, M_NETADDR
, M_WAITOK
);
saddr
= (struct sockaddr
*)(np
+ 1);
if (error
= copyin(argp
->saddr
, (caddr_t
)saddr
, argp
->slen
))
if (saddr
->sa_len
> argp
->slen
)
saddr
->sa_len
= argp
->slen
;
smask
= (struct sockaddr
*)((caddr_t
)saddr
+ argp
->slen
);
if (error
= copyin(argp
->saddr
, (caddr_t
)smask
, argp
->msklen
))
if (smask
->sa_len
> argp
->msklen
)
smask
->sa_len
= argp
->msklen
;
if ((rnh
= ump
->um_rtable
[i
]) == 0) {
* Seems silly to initialize every AF when most are not
* used, do so on demand here
for (dom
= domains
; dom
; dom
= dom
->dom_next
)
if (dom
->dom_family
== i
&& dom
->dom_rtattach
) {
dom
->dom_rtattach((void **)&ump
->um_rtable
[i
],
if ((rnh
= ump
->um_rtable
[i
]) == 0) {
rn
= (*rnh
->rnh_addaddr
)((caddr_t
)saddr
, (caddr_t
)smask
, rnh
,
if (rn
== 0 || np
!= (struct netcred
*)rn
) { /* already exists */
np
->netc_exflags
= argp
->exflags
;
np
->netc_anon
= argp
->anon
;
np
->netc_anon
.cr_ref
= 1;
register struct radix_node_head
*rnh
= (struct radix_node_head
*)w
;
(*rnh
->rnh_deladdr
)(rn
->rn_key
, rn
->rn_mask
, rnh
);
free((caddr_t
)rn
, M_NETADDR
);
* Free the net address hash lists that are hanging off the mount points.
register struct radix_node_head
*rnh
;
for (i
= 0; i
<= AF_MAX
; i
++)
if (rnh
= ump
->um_rtable
[i
]) {
(*rnh
->rnh_walktree
)(rnh
, ufs_free_netcred
,
free((caddr_t
)rnh
, M_RTABLE
);
* This is the generic part of fhtovp called after the underlying
* filesystem has validated the file handle.
* Verify that a host should have access to a filesystem, and if so
* return a vnode for the presented file handle.
ufs_check_export(mp
, ufhp
, nam
, vpp
, exflagsp
, credanonp
)
register struct mount
*mp
;
struct ucred
**credanonp
;
register struct inode
*ip
;
register struct netcred
*np
;
register struct ufsmount
*ump
= VFSTOUFS(mp
);
register struct radix_node_head
*rnh
;
* Get the export permission structure for this <mp, client> tuple.
if ((mp
->mnt_flag
& MNT_EXPORTED
) == 0)
saddr
= mtod(nam
, struct sockaddr
*);
rnh
= ump
->um_rtable
[saddr
->sa_family
];
(*rnh
->rnh_matchaddr
)((caddr_t
)saddr
, rnh
);
if (np
&& np
->netc_rnodes
->rn_flags
& RNF_ROOT
)
* If no address match, use the default if it exists.
if ((mp
->mnt_flag
& MNT_DEFEXPORTED
) == 0)
np
= &ump
->um_defexported
;
if (error
= VFS_VGET(mp
, ufhp
->ufid_ino
, &nvp
)) {
if (ip
->i_mode
== 0 || ip
->i_gen
!= ufhp
->ufid_gen
) {
*exflagsp
= np
->netc_exflags
;
*credanonp
= &np
->netc_anon
;