patch-2.4.15 linux/fs/intermezzo/kml_reint.c
Next file: linux/fs/intermezzo/kml_setup.c
Previous file: linux/fs/intermezzo/kml_decode.c
Back to the patch index
Back to the overall index
- Lines: 412
- Date:
Sun Nov 11 10:20:21 2001
- Orig file:
v2.4.14/linux/fs/intermezzo/kml_reint.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.4.14/linux/fs/intermezzo/kml_reint.c linux/fs/intermezzo/kml_reint.c
@@ -0,0 +1,411 @@
+/*
+ * 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 setfsuid\n");
+ if (current->fsgid != current->gid)
+ CDEBUG (D_KML, "reint_kmlreint_pre_secure: cannot setfsgid\n");
+ 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::%s\n", 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::%d\n", rec->rec_head.opcode);
+ return -EBADF;
+ }
+ if (error != 0 && error != KML_CLOSE_BACKFETCH)
+ CDEBUG (D_KML, "KML_ERROR::error = %d\n", 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::%s\n", 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;
+}
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)