[Envfs-commits] CVS: envfs/fs/envfs dir.c,1.1,1.2 file.c,1.4,1.5 inode.c,1.1,1.2 super.c,1.2,1.3
Status: Pre-Alpha
Brought to you by:
lethal
|
From: Paul M. <le...@us...> - 2001-09-23 04:28:13
|
Update of /cvsroot/envfs/envfs/fs/envfs
In directory usw-pr-cvs1:/tmp/cvs-serv21374/fs/envfs
Modified Files:
dir.c file.c inode.c super.c
Log Message:
Changes and stuff.
Index: dir.c
===================================================================
RCS file: /cvsroot/envfs/envfs/fs/envfs/dir.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dir.c 2001/09/19 03:01:45 1.1
+++ dir.c 2001/09/23 04:28:10 1.2
@@ -12,6 +12,8 @@
static struct dentry *envfs_lookup(struct inode *dir, struct dentry *dentry)
{
+ char *tmp;
+
envfs_debug("entering\n");
if (!dentry)
@@ -19,11 +21,15 @@
if (!dentry->d_name.name)
goto out;
- envfs_debug("dir->i_ino == %d\n", dir->i_ino);
+ tmp = envfs_getenv(dentry->d_name.name);
+
+ envfs_debug("dir->i_ino == %ld\n", dir->i_ino);
envfs_debug("dentry->d_name.name == %s\n", dentry->d_name.name);
dentry->d_inode = envfs_get_inode(dir->i_sb,
+ strlen(tmp),
0644 | S_IFREG,
dir->i_dev);
+ kfree(tmp);
out:
envfs_debug("leaving\n");
return NULL;
@@ -32,16 +38,16 @@
static int envfs_mknod(struct inode *dir, struct dentry *dentry,
int mode, int dev)
{
- struct inode *inode = envfs_get_inode(dir->i_sb, mode, dev);
+ struct inode *inode = envfs_get_inode(dir->i_sb, 0, mode, dev);
envfs_debug("entering\n");
if (!inode)
return -ENOSPC;
dentry->d_inode = inode;
- envfs_debug("inode == %d\n", dentry->d_inode->i_ino);
- dentry->d_inode = inode;
+ envfs_debug("inode == %ld\n", dentry->d_inode->i_ino);
+
dget(dentry);
envfs_debug("leaving\n");
@@ -51,7 +57,7 @@
static int envfs_create(struct inode *dir, struct dentry *dentry, int mode)
{
envfs_debug("entering\n");
- envfs_debug("dir->i_ino == %d\n", dir->i_ino);
+ envfs_debug("dir->i_ino == %ld\n", dir->i_ino);
envfs_debug("leaving\n");
return envfs_mknod(dir, dentry, mode | S_IFREG, 0);
}
@@ -103,7 +109,7 @@
envfs_debug("entering\n");
- envfs_debug("filp->f_pos == %d\n", filp->f_pos);
+ envfs_debug("filp->f_pos == %ld\n", filp->f_pos);
if (!dentry)
goto out;
@@ -140,6 +146,7 @@
struct file_operations envfs_dops = {
read: generic_read_dir,
readdir: envfs_readdir,
+ ioctl: envfs_ioctl,
};
struct inode_operations envfs_diops = {
Index: file.c
===================================================================
RCS file: /cvsroot/envfs/envfs/fs/envfs/file.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- file.c 2001/09/19 03:26:16 1.4
+++ file.c 2001/09/23 04:28:10 1.5
@@ -12,11 +12,140 @@
#include <linux/envfs_fs.h>
#include <asm/uaccess.h>
+/*
+ * Dump the envp
+ */
+int envfs_dump_vars(void)
+{
+ int res, len, pos;
+ char *buf;
+
+ envfs_debug("entering\n");
+
+ len = current->mm->env_end - current->mm->env_start;
+ buf = kmalloc(len, GFP_KERNEL);
+
+ if (!buf) {
+ printk(KERN_ERR "Can't allocate memory for envp\n");
+ envfs_debug("leaving\n");
+ return -ENOMEM;
+ }
+
+ task_lock(current);
+
+ if (!current->mm) {
+ printk(KERN_ERR "No current->mm ?!\n");
+ task_unlock(current);
+ envfs_debug("leaving\n");
+ return -EINVAL;
+ }
+
+ atomic_inc(&(current->mm->mm_users));
+ task_unlock(current);
+
+ res = access_process_vm(current, current->mm->env_start, buf, len, 0);
+
+ /*
+ * Each key:value pair ends with a '\0', which causes things like
+ * printk() to fail printing out the whole envp. Because of this, we
+ * translate each '\0' to '|' on everything but the end of the envp.
+ *
+ * The other option is calling access_process_vm() lots of times with
+ * the length of the key:value pair as the offset within the envp
+ * space, though this is slower than just doing translation and
+ * splitting up the string.
+ */
+ for (pos = strlen(buf); pos != res; pos = strlen(buf))
+ if (!buf[pos] || buf[pos] == '\0')
+ buf[pos] = '|';
+
+ buf[pos - 1] = '\0';
+
+ printk(KERN_INFO "envfs: envp: %s\n", buf);
+ envfs_debug("len: %d, pos: %d, res: %d, strlen(buf): %d\n",
+ len, pos, res, strlen(buf));
+
+ mmput(current->mm);
+
+ kfree(buf);
+
+ envfs_debug("leaving\n");
+
+ return 0;
+}
+
+/**
+ * envfs_ll_purge - Purge dentry from list
+ *
+ * @dentry: envfs dentry to search for
+ *
+ * Searches through the envfs_dentry_list looking for an existing entry of
+ * @dentry (by key). If it's found, the inode and dentry are cleaned up so
+ * they can be reused later, and the entry is purged from the list.
+ */
+static int envfs_ll_purge(struct envfs_dentry *dentry)
+{
+ struct envfs_dentry *list_dentry;
+ struct list_head *list;
+
+ envfs_debug("entering\n");
+
+ /*
+ * No use spinning an emtpy list
+ */
+ if (list_empty(envfs_dentry_list)) {
+ envfs_debug("list is empty\n");
+ goto out;
+ }
+
+ /*
+ * Spin list looking for matching key
+ *
+ * FIXME: Should utilize the envfs dentry position here for faster
+ * lookups. Use hashes and have the position reference the hash
+ * location in the hash table maybe?
+ */
+ list_for_each(list, envfs_dentry_list) {
+ list_dentry = list_entry(list, struct envfs_dentry, node);
+
+ if (!list_dentry)
+ continue;
+
+ /*
+ * Found it
+ */
+ if (strcmp(list_dentry->key, dentry->key) == 0) {
+ /*
+ * Clean up after the dentry and inode
+ */
+ if (list_dentry->f_dentry->d_inode) {
+ vfs_unlink(list_dentry->f_dentry->d_inode,
+ list_dentry->f_dentry);
+ envfs_delete_inode(list_dentry->f_dentry->d_inode);
+ dput(list_dentry->f_dentry);
+ }
+
+ /*
+ * Clean up after the list entry
+ */
+ list_del(&(list_dentry->node));
+ kfree(list_dentry);
+
+ break;
+ }
+ }
+
+out:
+ envfs_debug("leaving\n");
+
+ return 0;
+}
+
char *envfs_getenv_vars(struct file *filp, void *dirent, filldir_t filldir)
{
+ struct envfs_dentry *e_dentry;
unsigned long currkey;
- struct dentry *dentry;
- char *buf, *opt;
+ char *buf;
int i = 0;
envfs_debug("entering\n");
@@ -25,6 +154,19 @@
current->mm->env_start,
GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "Can't allocate memory\n");
+ goto out_nomem;
+ }
+
+ e_dentry = kmalloc(sizeof(struct envfs_dentry *), GFP_KERNEL);
+
+ if (!e_dentry) {
+ printk(KERN_ERR "Can't allocate memory\n");
+ kfree(buf);
+ goto out_nomem;
+ }
+
for (currkey = current->mm->env_start;
currkey < current->mm->env_end;
currkey++) {
@@ -34,24 +176,43 @@
i++;
}
+ /* Seek to current position */
for (i = 0; i < filp->f_pos - 2; i++) {
strsep(&buf, "|");
}
- opt = strsep(&buf, "=");
+ /*
+ * Setup the envfs dentry list entry
+ */
+ INIT_LIST_HEAD(&e_dentry->node);
+ e_dentry->key = strsep(&buf, "=");
+ //e_dentry->val = strsep(&buf, "=");
+ e_dentry->pos = filp->f_pos - 2;
- if (!*opt)
+ if (!*(e_dentry->key))
goto out;
- if (envfs_create_by_name(opt, 0755 | S_IFREG, NULL, &dentry) == -EINVAL)
+ //if (!*(e_dentry->val))
+ // goto out;
+
+ envfs_ll_purge(e_dentry);
+
+ if (envfs_create_by_name(e_dentry->key, 0755 | S_IFREG, NULL,
+ &(e_dentry->f_dentry)) == -EINVAL)
goto out;
- if (filldir(dirent, dentry->d_name.name, dentry->d_name.len,
- filp->f_pos, dentry->d_inode->i_ino, DT_UNKNOWN) < 0)
+ if (filldir(dirent, e_dentry->f_dentry->d_name.name,
+ e_dentry->f_dentry->d_name.len, filp->f_pos,
+ e_dentry->f_dentry->d_inode->i_ino, DT_UNKNOWN) < 0)
goto out;
+ /*
+ * Add it to the list
+ */
+ list_add(&e_dentry->node, envfs_dentry_list);
filp->f_pos++;
out:
kfree(buf);
+out_nomem:
envfs_debug("leaving\n");
return NULL;
}
@@ -142,8 +303,29 @@
return count;
}
+int envfs_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned int arg)
+{
+ envfs_debug("entering\n");
+
+ envfs_debug("cmd: %d\n", cmd);
+
+ switch (cmd) {
+ case 0x9cfe123:
+ envfs_dump_vars();
+ break;
+ default:
+ envfs_debug("leaving: no cmd\n");
+ return -ENOTTY;
+ }
+
+ envfs_debug("leaving\n");
+ return 0;
+}
+
struct file_operations envfs_fops = {
read: envfs_read_file,
+ ioctl: envfs_ioctl,
mmap: generic_file_mmap,
llseek: generic_file_llseek,
};
Index: inode.c
===================================================================
RCS file: /cvsroot/envfs/envfs/fs/envfs/inode.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- inode.c 2001/09/19 03:01:45 1.1
+++ inode.c 2001/09/23 04:28:10 1.2
@@ -11,27 +11,56 @@
#include <linux/locks.h>
#include <linux/envfs_fs.h>
+void envfs_delete_inode(struct inode *inode)
+{
+ envfs_debug("entering\n");
+
+ lock_kernel();
+
+ envfs_debug("unlinking inode: %ld\n", inode->i_ino);
+
+ if (inode->i_flags & S_IMMUTABLE)
+ inode->i_flags &= ~S_IMMUTABLE;
+
+ inode->i_size = 0;
+ inode->i_blocks = 0;
+ inode->i_nlink--;
+
+ clear_inode(inode);
+
+ unlock_kernel();
+
+ envfs_debug("leaving\n");
+}
+
void envfs_read_inode(struct inode *inode)
{
+ envfs_debug("entering\n");
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ envfs_debug("leaving\n");
}
-struct inode *envfs_get_inode(struct super_block *sb, int mode, int dev)
+struct inode *envfs_get_inode(struct super_block *sb, loff_t inode_size, int mode, int dev)
{
struct inode *inode = new_inode(sb);
envfs_debug("entering\n");
+
if (!inode)
return NULL;
-
+ if (inode_size)
+ inode_size--;
+
inode->i_mode = mode;
inode->i_uid = current->fsuid;
inode->i_gid = current->fsgid;
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0;
inode->i_rdev = NODEV;
+ inode->i_size = inode_size;
+
inode->i_mapping->a_ops = &envfs_aops;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ envfs_read_inode(inode);
/*
* FIXME: This is a hack to force everything into a read-only state.
Index: super.c
===================================================================
RCS file: /cvsroot/envfs/envfs/fs/envfs/super.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- super.c 2001/09/19 03:30:26 1.2
+++ super.c 2001/09/23 04:28:10 1.3
@@ -15,9 +15,15 @@
static struct vfsmount *envfs_mnt;
+spinlock_t envfs_lock = SPIN_LOCK_UNLOCKED;
+struct list_head *envfs_dentry_list;
+
+extern int envfs_dump_vars(void);
+
static int envfs_statfs(struct super_block *sb, struct statfs *buf)
{
envfs_debug("entering\n");
+ envfs_dump_vars();
buf->f_type = ENVFS_SUPER_MAGIC;
buf->f_bsize = PAGE_CACHE_SIZE;
buf->f_namelen = NAME_MAX;
@@ -48,6 +54,7 @@
statfs: envfs_statfs,
put_inode: force_delete,
read_inode: envfs_read_inode,
+ delete_inode: envfs_delete_inode,
};
static struct super_block *envfs_read_super(struct super_block *sb,
@@ -61,7 +68,7 @@
sb->s_magic = ENVFS_SUPER_MAGIC;
sb->s_op = &envfs_sops;
- root_inode = envfs_get_inode(sb, S_IFDIR | 0755, 0);
+ root_inode = envfs_get_inode(sb, 0, S_IFDIR | 0755, 0);
if (!root_inode)
return NULL;
@@ -73,6 +80,16 @@
return NULL;
}
+ envfs_dentry_list = kmalloc(sizeof(struct list_head *), GFP_KERNEL);
+
+ if (!envfs_dentry_list) {
+ printk(KERN_ERR "Can't allocate memory for list\n");
+ iput(root_inode);
+ return NULL;
+ }
+
+ INIT_LIST_HEAD(envfs_dentry_list);
+
envfs_debug("leaving\n");
return sb;
}
@@ -105,7 +122,7 @@
MODULE_AUTHOR("Paul Mundt <le...@ch...>");
MODULE_DESCRIPTION("/env file system");
-MODULE_LICENSE("GPL");
+//MODULE_LICENSE("GPL");
module_init(init_envfs_fs);
module_exit(exit_envfs_fs);
|