/*
* clickfs.cc -- Click configuration filesystem for BSD
* Nickolai Zeldovich
*
* Copyright (c) 2001 Massachusetts Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, subject to the conditions
* listed in the Click LICENSE file. These conditions include: you must
* preserve this copyright notice, and you cannot mention the copyright
* holders in advertising related to the Software without their permission.
* The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
* notice is a summary of the Click LICENSE file; the license in that file is
* legally binding.
*/
#include <click/config.h>
#include "modulepriv.hh"
#include "clickfs_tree.hh"
#include <click/cxxprotect.h>
CLICK_CXX_PROTECT
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/time.h>
CLICK_CXX_UNPROTECT
#include <click/cxxunprotect.h>
#include <click/string.hh>
extern vop_t **clickfs_root_vnops;
extern struct vnodeopv_desc clickfs_vnodeop_opv_desc;
struct clickfs_mount {
struct vnode *click_root;
};
static int
clickfs_mount(struct mount *mp, char *user_path, caddr_t data,
struct nameidata *ndp, struct proc *p)
{
char path[MAXPATHLEN];
size_t count;
int error;
struct clickfs_mount *cmp;
if (mp->mnt_flag & MNT_UPDATE)
return EOPNOTSUPP;
vfs_getnewfsid(mp);
error = copyinstr(user_path, path, MAXPATHLEN, &count);
if (error)
return error;
MALLOC(cmp, struct clickfs_mount *, sizeof(struct clickfs_mount),
M_CLICKFS, M_WAITOK | M_ZERO);
mp->mnt_data = (qaddr_t) cmp;
mp->mnt_stat.f_bsize = DEV_BSIZE;
mp->mnt_stat.f_iosize = DEV_BSIZE;
mp->mnt_stat.f_owner = 0;
mp->mnt_stat.f_blocks = 1;
mp->mnt_stat.f_bfree = 1;
mp->mnt_stat.f_bavail = 1;
mp->mnt_stat.f_files = 1;
mp->mnt_stat.f_ffree = 1;
mp->mnt_stat.f_flags = mp->mnt_flag;
strcpy(mp->mnt_stat.f_mntonname, path);
strcpy(mp->mnt_stat.f_mntfromname, "clickfs");
strcpy(mp->mnt_stat.f_fstypename, "clickfs");
error = clickfs_rootvnode(mp, &cmp->click_root);
if (error < 0) {
free(cmp, M_CLICKFS);
return error;
}
return 0;
}
static int
clickfs_start(struct mount *mp, int flags, struct proc *p)
{
return 0;
}
static int
clickfs_unmount(struct mount *mp, int mntflags, struct proc *p)
{
struct clickfs_mount *cmp = (struct clickfs_mount *)mp->mnt_data;
int error;
int flags = 0;
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
error = vflush(mp, 1, flags); // there is 1 extra vnode ref.
if (error)
return error;
free(mp->mnt_data, M_CLICKFS);
mp->mnt_data = 0;
return 0;
}
static int
clickfs_root(struct mount *mp, struct vnode **vpp)
{
struct clickfs_mount *cmp = (struct clickfs_mount *)mp->mnt_data;
*vpp = cmp->click_root;
VREF(*vpp);
vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curproc);
return 0;
}
static int
clickfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
{
memcpy(sbp, &mp->mnt_stat, sizeof(*sbp));
return 0;
}
static int
clickfs_sync(struct mount *mp, int waitfor, struct ucred *cred,
struct proc *p)
{
return 0;
}
static int
clickfs_init(struct vfsconf *vfsp)
{
return 0;
}
static int
clickfs_uninit(struct vfsconf *vfsp)
{
return 0;
}
struct vfsops clickfs_vfsops = {
clickfs_mount,
clickfs_start,
clickfs_unmount,
clickfs_root,
vfs_stdquotactl,
clickfs_statfs,
clickfs_sync,
vfs_stdvget,
vfs_stdfhtovp,
vfs_stdcheckexp,
vfs_stdvptofh,
clickfs_init,
clickfs_uninit,
vfs_stdextattrctl
};
syntax highlighted by Code2HTML, v. 0.9.1