utils.c revision 13fdd42f1fc3e519650037a920e6a54c24973866
/** @file
*
* vboxvfs -- VirtualBox Guest Additions for Linux:
* Utility functions.
* Mainly conversion from/to VirtualBox/Linux data structures
*/
/*
* Copyright (C) 2006 InnoTek Systemberatung GmbH
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License as published by the Free Software Foundation,
* in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
* distribution. VirtualBox OSE is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY of any kind.
*
* If you received this file as part of a commercial VirtualBox
* distribution, then only the terms of your commercial VirtualBox
* license agreement apply instead of the previous paragraph.
*/
/* #define USE_VMALLOC */
static void
{
do_div (t, 1000000000);
*time = t;
}
#else
static void
{
}
#endif
static void
{
int is_dir;
int mode;
TRACE ();
if (is_dir) {
/* XXX: this probably should be set to the number of entries
in the directory plus two (. ..) */
}
else {
}
#endif
}
static int
{
int rc;
TRACE ();
if (VBOX_FAILURE (rc)) {
elog3 ("%s: %s: vboxCallCreate(%s) failed rc=%d\n",
return -EPROTO;
}
if (!ok_to_fail) {
elog3 ("%s: %s: vboxCallCreate(%s)"
" file does not exist result=%d\n",
}
return -ENOENT;
}
return 0;
}
/* this is called directly as iop on 2.4, indirectly as dop
[sf_dentry_revalidate] on 2.4/2.6, indirectly as iop through
still valid. the test is failed if [dentry] does not have an inode
or [sf_stat] is unsuccessful, otherwise we return success and
update inode attributes */
static int
{
int err;
struct sf_glob_info *sf_g;
struct sf_inode_info *sf_i;
TRACE ();
return -EINVAL;
}
#if 0
printk ("%s called by %p:%p\n",
__builtin_return_address (1));
#endif
if (!sf_i->force_restat) {
return 0;
}
}
if (err) {
return err;
}
return 0;
}
/* this is called during name resolution/lookup to check if the
[dentry] in the cache is still valid. the job is handled by
[sf_inode_revalidate] */
static int
#else
#endif
{
TRACE ();
if (sf_inode_revalidate (dentry)) {
return 0;
}
return 1;
}
/* on 2.6 this is a proxy for [sf_inode_revalidate] which (as a side
effect) updates inode attributes for [dentry] (given that [dentry]
has inode at all) from these new attributes we derive [kstat] via
[generic_fillattr] */
static int
{
int err;
TRACE ();
if (err) {
return err;
}
return 0;
}
#endif
static int
{
int is_root = 0;
TRACE ();
is_root = 1;
}
else {
/* lengths of constituents plus terminating zero plus slash */
if (path_len > 0xffff) {
return -ENAMETOOLONG;
}
}
if (!tmp) {
return -ENOMEM;
}
if (is_root) {
}
else {
}
return 0;
}
/* [dentry] contains string encoded in coding system that corresponds
to [sf_g]->nls, we must convert it to UTF8 here and pass down to
[sf_make_path] which will allocate SHFLSTRING and fill it in */
static int
SHFLSTRING **result)
{
int err;
const char *d_name;
const char *name;
TRACE ();
const char *in;
char *out;
for (i = 0; i < d_len; ++i) {
/* We renamed the linux kernel wchar_t type to linux_wchar_t in
the-linux-kernel.h, as it conflicts with the C++ type of that name. */
int nb;
if (nb < 0) {
elog ("nls->char2uni failed %x %d\n",
goto fail1;
}
if (nb < 0) {
elog ("nls->uni2char failed %x %d\n",
uni, out_bound_len);
goto fail1;
}
out_bound_len -= nb;
}
err = -ENAMETOOLONG;
goto fail1;
}
*out = 0;
}
else {
}
}
return err;
return err;
}
static int
{
const char *in;
char *out;
out_len = 0;
while (in_bound_len) {
int nb;
if (nb < 0) {
elog ("utf8_mbtowc failed(%s) %x:%d\n",
return -EINVAL;
}
in_bound_len -= nb;
if (nb < 0) {
elog ("nls->uni2char failed(%s) %x:%d\n",
return nb;
}
out_bound_len -= nb;
}
*out = 0;
return 0;
}
else {
return -ENAMETOOLONG;
}
else {
}
return 0;
}
}
static struct sf_dir_buf *
sf_dir_buf_alloc (void)
{
struct sf_dir_buf *b;
TRACE ();
b = kmalloc (sizeof (*b), GFP_KERNEL);
if (!b) {
elog2 ("could not alloc directory buffer\n");
return NULL;
}
#ifdef USE_VMALLOC
#else
#endif
if (!b->buf) {
kfree (b);
elog2 ("could not alloc directory buffer storage\n");
return NULL;
}
INIT_LIST_HEAD (&b->head);
b->nb_entries = 0;
b->used_bytes = 0;
b->free_bytes = 16384;
return b;
}
static void
sf_dir_buf_free (struct sf_dir_buf *b)
{
TRACE ();
#ifdef USE_VMALLOC
#else
#endif
kfree (b);
}
static void
sf_dir_info_free (struct sf_dir_info *p)
{
TRACE ();
struct sf_dir_buf *b;
sf_dir_buf_free (b);
}
kfree (p);
}
static struct sf_dir_info *
sf_dir_info_alloc (void)
{
struct sf_dir_info *p;
TRACE ();
p = kmalloc (sizeof (*p), GFP_KERNEL);
if (!p) {
elog2 ("could not alloc directory info\n");
return NULL;
}
INIT_LIST_HEAD (&p->info_list);
return p;
}
static struct sf_dir_buf *
{
struct sf_dir_buf *b;
if (!b) {
return NULL;
}
else {
if (b->free_bytes > 0) {
return b;
}
}
}
return NULL;
}
static int
{
int err;
struct sf_dir_buf *b;
TRACE ();
if (err) {
goto fail0;
}
b = sf_get_non_empty_dir_buf (sf_d);
for (;;) {
int rc;
void *buf;
if (!b) {
b = sf_dir_buf_alloc ();
if (!b) {
elog2 ("could not alloc directory buffer\n");
goto fail1;
}
}
buf_size = b->free_bytes;
rc = vboxCallDirInfo (
mask,
0,
0,
&buf_size,
buf,
);
switch (rc) {
case VINF_SUCCESS:
/* fallthrough */
case VERR_NO_MORE_FILES:
break;
case VERR_NO_TRANSLATION:
elog2 ("host could not translte entry\n");
/* XXX */
break;
default:
goto fail1;
}
b->nb_entries += nb_ents;
b->free_bytes -= buf_size;
b->used_bytes += buf_size;
b = NULL;
if (VBOX_FAILURE (rc)) {
break;
}
}
return 0;
return err;
}
static struct dentry_operations sf_dentry_ops = {
};