⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ext_attr.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
字号:
/*  * 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*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -