patch-2.4.15 linux/fs/intermezzo/ext_attr.c

Next file: linux/fs/intermezzo/file.c
Previous file: linux/fs/intermezzo/dir.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.14/linux/fs/intermezzo/ext_attr.c linux/fs/intermezzo/ext_attr.c
@@ -0,0 +1,196 @@
+/* 
+ * Extended attribute handling for presto.
+ *
+ * Copyright (C) 2001. All rights reserved.
+ * Shirish H. Phatak
+ * Tacit Networks, Inc.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/locks.h>
+#include <linux/unistd.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/locks.h>
+#include <linux/string.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <asm/segment.h>
+#include <linux/smp_lock.h>
+
+#include <linux/intermezzo_fs.h>
+#include <linux/intermezzo_upcall.h>
+#include <linux/intermezzo_psdev.h>
+#include <linux/intermezzo_kml.h>
+
+
+#ifdef CONFIG_FS_EXT_ATTR
+#include <linux/ext_attr.h>
+
+extern inline void presto_debug_fail_blkdev(struct presto_file_set *fset,
+                                            unsigned long value);
+
+extern int presto_prep(struct dentry *, struct presto_cache **,
+                       struct presto_file_set **);
+
+
+/* VFS interface */
+/* XXX! Fixme test for user defined attributes */
+int presto_set_ext_attr(struct inode *inode, 
+                        const char *name, void *buffer,
+                        size_t buffer_len, int flags) 
+{
+        int error;
+        struct presto_cache *cache;
+        struct presto_file_set *fset;
+        struct lento_vfs_context info;
+        struct dentry *dentry;
+        int minor = presto_i2m(inode);
+        char *buf = NULL;
+
+        ENTRY;
+        if (minor < 0) {
+                EXIT;
+                return -1;
+        }
+
+        if ( ISLENTO(minor) ) {
+                EXIT;
+                return -EINVAL;
+        }
+
+        /* BAD...vfs should really pass down the dentry to use, especially
+         * since every other operation in iops does. But for now
+         * we do a reverse mapping from inode to the first dentry 
+         */
+        if (list_empty(&inode->i_dentry)) {
+                printk("No alias for inode %d\n", (int) inode->i_ino);
+                EXIT;
+                return -EINVAL;
+        }
+
+        dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
+
+        error = presto_prep(dentry, &cache, &fset);
+        if ( error ) {
+                EXIT;
+                return error;
+        }
+
+        if ((buffer != NULL) && (buffer_len != 0)) {
+            /* If buffer is a user space pointer copy it to kernel space
+            * and reset the flag. We do this since the journal functions need
+            * access to the contents of the buffer, and the file system
+            * does not care. When we actually invoke the function, we remove
+            * the EXT_ATTR_FLAG_USER flag.
+            *
+            * XXX:Check if the "fs does not care" assertion is always true -SHP
+            * (works for ext3)
+            */
+            if (flags & EXT_ATTR_FLAG_USER) {
+                PRESTO_ALLOC(buf, char *, buffer_len);
+                if (!buf) {
+                        printk("InterMezzo: out of memory!!!\n");
+                        return -ENOMEM;
+                }
+                error = copy_from_user(buf, buffer, buffer_len);
+                if (error) 
+                        return error;
+            } else 
+                buf = buffer;
+        } else
+                buf = buffer;
+
+        if ( presto_get_permit(inode) < 0 ) {
+                EXIT;
+                if (buffer_len && (flags & EXT_ATTR_FLAG_USER))
+                        PRESTO_FREE(buf, buffer_len);
+                return -EROFS;
+        }
+
+        /* Simulate presto_setup_info */
+        memset(&info, 0, sizeof(info));
+        /* For now redundant..but we keep it around just in case */
+        info.flags = LENTO_FL_IGNORE_TIME;
+        if (!ISLENTO(cache->cache_psdev->uc_minor))
+            info.flags |= LENTO_FL_KML;
+
+        /* We pass in the kernel space pointer and reset the 
+         * EXT_ATTR_FLAG_USER flag.
+         * See comments above. 
+         */ 
+        /* Note that mode is already set by VFS so we send in a NULL */
+        error = presto_do_set_ext_attr(fset, dentry, name, buf,
+                                       buffer_len, flags & ~EXT_ATTR_FLAG_USER,
+                                       NULL, &info);
+        presto_put_permit(inode);
+
+        if (buffer_len && (flags & EXT_ATTR_FLAG_USER))
+                PRESTO_FREE(buf, buffer_len);
+        EXIT;
+        return error;
+}
+
+/* Lento Interface */
+/* XXX: ignore flags? We should be forcing these operations through? -SHP*/
+int lento_set_ext_attr(const char *path, const char *name, 
+                       void *buffer, size_t buffer_len, int flags, mode_t mode, 
+                       struct lento_vfs_context *info) 
+{
+        int error;
+        char * pathname;
+        struct nameidata nd;
+        struct dentry *dentry;
+        struct presto_file_set *fset;
+
+        ENTRY;
+        lock_kernel();
+
+        pathname=getname(path);
+        error = PTR_ERR(pathname);
+        if (IS_ERR(pathname)) {
+                EXIT;
+                goto exit;
+        }
+
+        /* Note that ext_attrs apply to both files and directories..*/
+        error=presto_walk(pathname,&nd);
+        if (error) 
+		goto exit;
+        dentry = nd.dentry;
+
+        fset = presto_fset(dentry);
+        error = -EINVAL;
+        if ( !fset ) {
+                printk("No fileset!\n");
+                EXIT;
+                goto exit_dentry;
+        }
+
+        if (buffer==NULL) buffer_len=0;
+
+        error = presto_do_set_ext_attr(fset, dentry, name, buffer,
+                                       buffer_len, flags, &mode, info);
+exit_dentry:
+        path_release(&nd);
+exit_path:
+        putname(pathname);
+exit:
+        unlock_kernel();
+        return error; 
+}
+
+#endif /*CONFIG_FS_EXT_ATTR*/

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)