kml_reint.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:11k
- /*
- * KML REINT
- *
- * Copryright (C) 1996 Arthur Ma <arthur.ma@mountainviewdata.com>
- *
- * Copyright (C) 2000 Mountainview Data, Inc.
- */
- #define __NO_VERSION__
- #include <linux/module.h>
- #include <linux/errno.h>
- #include <linux/fs.h>
- #include <linux/kernel.h>
- #include <linux/major.h>
- #include <linux/slab.h>
- #include <linux/vmalloc.h>
- #include <linux/mm.h>
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
- #include <asm/mmu_context.h>
- #include <linux/intermezzo_fs.h>
- #include <linux/intermezzo_kml.h>
- #include <linux/intermezzo_psdev.h>
- #include <linux/intermezzo_upcall.h>
- static void kmlreint_pre_secure (struct kml_rec *rec);
- static void kmlreint_post_secure (struct kml_rec *rec);
- static void kmlreint_pre_secure (struct kml_rec *rec)
- {
- if (current->fsuid != current->uid)
- CDEBUG (D_KML, "reint_kmlreint_pre_secure: cannot setfsuidn");
- if (current->fsgid != current->gid)
- CDEBUG (D_KML, "reint_kmlreint_pre_secure: cannot setfsgidn");
- current->fsuid = rec->rec_head.uid;
- current->fsgid = rec->rec_head.fsgid;
- }
- static void kmlreint_post_secure (struct kml_rec *rec)
- {
- current->fsuid = current->uid;
- current->fsgid = current->gid;
- /* current->egid = current->gid; */
- /* ????????????? */
- }
- static int reint_create (int slot_offset, struct kml_rec *rec)
- {
- struct lento_vfs_context info;
- struct kml_create *create = &rec->rec_kml.create;
- mm_segment_t old_fs;
- int error;
- ENTRY;
- kmlreint_pre_secure (rec);
- info.slot_offset = slot_offset;
- info.recno = rec->rec_tail.recno;
- info.kml_offset = rec->rec_kml_offset;
- info.flags = 0;
- CDEBUG (D_KML, "=====REINT_CREATE::%sn", create->path);
- old_fs = get_fs();
- set_fs (get_ds());
- error = lento_create(create->path, create->mode, &info);
- set_fs (old_fs);
- kmlreint_post_secure (rec);
- EXIT;
- return error;
- }
- static int reint_open (int slot_offset, struct kml_rec *rec)
- {
- return 0;
- }
- static int reint_mkdir (int slot_offset, struct kml_rec *rec)
- {
- struct lento_vfs_context info;
- struct kml_mkdir *mkdir = &rec->rec_kml.mkdir;
- mm_segment_t old_fs;
- int error;
- ENTRY;
- kmlreint_pre_secure (rec);
- info.slot_offset = slot_offset;
- info.recno = rec->rec_tail.recno;
- info.kml_offset = rec->rec_kml_offset;
- info.flags = 0;
- old_fs = get_fs();
- set_fs (get_ds());
- error = lento_mkdir (mkdir->path, mkdir->mode, &info);
- set_fs (old_fs);
- kmlreint_post_secure (rec);
- EXIT;
- return error;
- }
- static int reint_rmdir (int slot_offset, struct kml_rec *rec)
- {
- struct kml_rmdir *rmdir = &rec->rec_kml.rmdir;
- struct lento_vfs_context info;
- mm_segment_t old_fs;
- char *name;
- int error;
- ENTRY;
- kmlreint_pre_secure (rec);
- name = bdup_printf ("%s/%s", rmdir->path, rmdir->name);
- if (name == NULL)
- {
- kmlreint_post_secure (rec);
- EXIT;
- return -ENOMEM;
- }
- info.slot_offset = slot_offset;
- info.recno = rec->rec_tail.recno;
- info.kml_offset = rec->rec_kml_offset;
- info.flags = 0;
- old_fs = get_fs();
- set_fs (get_ds());
- error = lento_rmdir (name, &info);
- set_fs (old_fs);
- PRESTO_FREE (name, strlen (name) + 1);
- kmlreint_post_secure (rec);
- EXIT;
- return error;
- }
- static int reint_link (int slot_offset, struct kml_rec *rec)
- {
- struct kml_link *link = &rec->rec_kml.link;
- struct lento_vfs_context info;
- mm_segment_t old_fs;
- int error;
- ENTRY;
- kmlreint_pre_secure (rec);
- info.slot_offset = slot_offset;
- info.recno = rec->rec_tail.recno;
- info.kml_offset = rec->rec_kml_offset;
- info.flags = 0;
- old_fs = get_fs();
- set_fs (get_ds());
- error = lento_link (link->sourcepath, link->targetpath, &info);
- set_fs (old_fs);
- kmlreint_post_secure (rec);
- EXIT;
- return error;
- }
- static int reint_unlink (int slot_offset, struct kml_rec *rec)
- {
- struct kml_unlink *unlink = &rec->rec_kml.unlink;
- struct lento_vfs_context info;
- mm_segment_t old_fs;
- int error;
- char *name;
- ENTRY;
- kmlreint_pre_secure (rec);
- name = bdup_printf ("%s/%s", unlink->path, unlink->name);
- if (name == NULL)
- {
- kmlreint_post_secure (rec);
- EXIT;
- return -ENOMEM;
- }
- info.slot_offset = slot_offset;
- info.recno = rec->rec_tail.recno;
- info.kml_offset = rec->rec_kml_offset;
- info.flags = 0;
- old_fs = get_fs();
- set_fs (get_ds());
- error = lento_unlink (name, &info);
- set_fs (old_fs);
- PRESTO_FREE (name, strlen (name));
- kmlreint_post_secure (rec);
- EXIT;
- return error;
- }
- static int reint_symlink (int slot_offset, struct kml_rec *rec)
- {
- struct kml_symlink *symlink = &rec->rec_kml.symlink;
- struct lento_vfs_context info;
- mm_segment_t old_fs;
- int error;
- ENTRY;
- kmlreint_pre_secure (rec);
- info.slot_offset = slot_offset;
- info.recno = rec->rec_tail.recno;
- info.kml_offset = rec->rec_kml_offset;
- info.flags = 0;
- old_fs = get_fs();
- set_fs (get_ds());
- error = lento_symlink (symlink->targetpath,
- symlink->sourcepath, &info);
- set_fs (old_fs);
- kmlreint_post_secure (rec);
- EXIT;
- return error;
- }
- static int reint_rename (int slot_offset, struct kml_rec *rec)
- {
- struct kml_rename *rename = &rec->rec_kml.rename;
- struct lento_vfs_context info;
- mm_segment_t old_fs;
- int error;
- ENTRY;
- kmlreint_pre_secure (rec);
- info.slot_offset = slot_offset;
- info.recno = rec->rec_tail.recno;
- info.kml_offset = rec->rec_kml_offset;
- info.flags = 0;
- old_fs = get_fs();
- set_fs (get_ds());
- error = lento_rename (rename->sourcepath, rename->targetpath, &info);
- set_fs (old_fs);
- kmlreint_post_secure (rec);
- EXIT;
- return error;
- }
- static int reint_setattr (int slot_offset, struct kml_rec *rec)
- {
- struct kml_setattr *setattr = &rec->rec_kml.setattr;
- struct lento_vfs_context info;
- mm_segment_t old_fs;
- int error;
- ENTRY;
- kmlreint_pre_secure (rec);
- info.slot_offset = slot_offset;
- info.recno = rec->rec_tail.recno;
- info.kml_offset = rec->rec_kml_offset;
- info.flags = setattr->iattr.ia_attr_flags;
- old_fs = get_fs();
- set_fs (get_ds());
- error = lento_setattr (setattr->path, &setattr->iattr, &info);
- set_fs (old_fs);
- kmlreint_post_secure (rec);
- EXIT;
- return error;
- }
- static int reint_mknod (int slot_offset, struct kml_rec *rec)
- {
- struct kml_mknod *mknod = &rec->rec_kml.mknod;
- struct lento_vfs_context info;
- mm_segment_t old_fs;
- int error;
- ENTRY;
- kmlreint_pre_secure (rec);
- info.slot_offset = slot_offset;
- info.recno = rec->rec_tail.recno;
- info.kml_offset = rec->rec_kml_offset;
- info.flags = 0;
- old_fs = get_fs();
- set_fs (get_ds());
- error = lento_mknod (mknod->path, mknod->mode,
- MKDEV(mknod->major, mknod->minor), &info);
- set_fs (old_fs);
- kmlreint_post_secure (rec);
- EXIT;
- return error;
- }
- int kml_reint (char *mtpt, int slot_offset, struct kml_rec *rec)
- {
- int error = 0;
- switch (rec->rec_head.opcode)
- {
- case KML_CREATE:
- error = reint_create (slot_offset, rec);
- break;
- case KML_OPEN:
- error = reint_open (slot_offset, rec);
- break;
- case KML_CLOSE:
- /* error = reint_close (slot_offset, rec);
- force the system to return to lento */
- error = KML_CLOSE_BACKFETCH;
- break;
- case KML_MKDIR:
- error = reint_mkdir (slot_offset, rec);
- break;
- case KML_RMDIR:
- error = reint_rmdir (slot_offset, rec);
- break;
- case KML_UNLINK:
- error = reint_unlink (slot_offset, rec);
- break;
- case KML_LINK:
- error = reint_link (slot_offset, rec);
- break;
- case KML_SYMLINK:
- error = reint_symlink (slot_offset, rec);
- break;
- case KML_RENAME:
- error = reint_rename (slot_offset, rec);
- break;
- case KML_SETATTR:
- error = reint_setattr (slot_offset, rec);
- break;
- case KML_MKNOD:
- error = reint_mknod (slot_offset, rec);
- break;
- default:
- CDEBUG (D_KML, "wrong opcode::%dn", rec->rec_head.opcode);
- return -EBADF;
- }
- if (error != 0 && error != KML_CLOSE_BACKFETCH)
- CDEBUG (D_KML, "KML_ERROR::error = %dn", error);
- return error;
- }
- /* return the old mtpt */
- /*
- struct fs_struct {
- atomic_t count;
- int umask;
- struct dentry * root, * pwd;
- };
- */
- static int do_set_fs_root (struct dentry *newroot,
- struct dentry **old_root)
- {
- struct dentry *de = current->fs->root;
- current->fs->root = newroot;
- if (old_root != (struct dentry **) NULL)
- *old_root = de;
- return 0;
- }
- static int set_system_mtpt (char *mtpt, struct dentry **old_root)
- {
- struct nameidata nd;
- struct dentry *dentry;
- int error;
- if (path_init(pathname, LOOKUP_PARENT, &nd))
- error = path_walk(mtpt, &nd);
- if (error) {
- CDEBUG (D_KML, "Yean!!!!::Can't find mtpt::%sn", mtpt);
- return error;
- }
- dentry = nd.dentry;
- error = do_set_fs_root (dentry, old_root);
- path_release (&nd);
- return error;
- }
- int kml_reintbuf (struct kml_fsdata *kml_fsdata,
- char *mtpt, struct kml_rec **close_rec)
- {
- struct kml_rec *rec = NULL;
- struct list_head *head, *tmp;
- struct dentry *old_root;
- int error = 0;
- head = &kml_fsdata->kml_reint_cache;
- if (list_empty(head))
- return 0;
- if (kml_fsdata->kml_reint_current == NULL ||
- kml_fsdata->kml_reint_current == head->next)
- return 0;
- error = set_system_mtpt (mtpt, &old_root);
- if (error)
- return error;
- tmp = head->next;
- while (error == 0 && tmp != head ) {
- rec = list_entry(tmp, struct kml_rec, kml_optimize.kml_chains);
- error = kml_reint (mtpt, rec->rec_kml_offset, rec);
- tmp = tmp->next;
- }
- do_set_fs_root (old_root, NULL);
- if (error == KML_CLOSE_BACKFETCH)
- *close_rec = rec;
- kml_fsdata->kml_reint_current = tmp;
- return error;
- }