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

📄 vfs.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 5 页
字号:
        error = may_create(dir->d_inode, dentry);        if (error) {                EXIT;                goto exit_pre_lock;        }        error = -EPERM;        iops = filter_c2cdiops(fset->fset_cache->cache_filter);        if (!iops->create) {                EXIT;                goto exit_pre_lock;        }        presto_getversion(&tgt_dir_ver, dir->d_inode);        handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_CREATE);        if ( IS_ERR(handle) ) {                EXIT;		presto_release_space(fset->fset_cache, PRESTO_REQHIGH);                 printk("presto_do_create: no space for transaction\n");                error=-ENOSPC;		goto exit_pre_lock;        }        DQUOT_INIT(dir->d_inode);        lock_kernel();        error = iops->create(dir->d_inode, dentry, mode);        if (error) {                EXIT;                goto exit_lock;        }        if (dentry->d_inode &&             dentry->d_inode->i_gid != presto_excluded_gid) {                struct presto_cache *cache = fset->fset_cache;                /* was this already done? */                if ( !filter_c2cfiops(cache->cache_filter) )                        filter_setup_file_ops(cache->cache_filter,                                               dentry->d_inode,                                              &presto_file_iops,                                              &presto_file_fops);                /* make the new inode ours */                dentry->d_inode->i_op =                         filter_c2ufiops(cache->cache_filter);                dentry->d_inode->i_fop =                         filter_c2uffops(cache->cache_filter);                filter_setup_dentry_ops(cache->cache_filter,                                         dentry->d_op,                                         &presto_dentry_ops);                dentry->d_op = filter_c2udops(cache->cache_filter);                /* if Lento creates this file, we won't have data */                if ( ISLENTO(presto_c2m(cache)) ) {                        presto_set(dentry, PRESTO_ATTR);                } else {                        presto_set(dentry, PRESTO_ATTR | PRESTO_DATA);                }        }        error = presto_settime(fset, dir, info, ATTR_CTIME | ATTR_MTIME);        if (error) {                 EXIT;                goto exit_lock;        }        error = presto_settime(fset, dentry, info, ATTR_CTIME | ATTR_MTIME);        if (error) {                 EXIT;                goto exit_lock;        }        presto_debug_fail_blkdev(fset, PRESTO_OP_CREATE | 0x10);        presto_getversion(&new_file_ver, dentry->d_inode);        if ( presto_do_kml(info, dentry->d_inode) )                error = presto_journal_create(&rec, fset, dentry, &tgt_dir_ver,                                              &new_file_ver,                                              dentry->d_inode->i_mode);        presto_debug_fail_blkdev(fset, PRESTO_OP_CREATE | 0x20);        if ( presto_do_expect(info, dentry->d_inode) )                error = presto_write_last_rcvd(&rec, fset, info);        presto_debug_fail_blkdev(fset, PRESTO_OP_CREATE | 0x30);        EXIT; exit_lock:        unlock_kernel();        presto_trans_commit(fset, handle); exit_pre_lock:	presto_release_space(fset->fset_cache, PRESTO_REQHIGH);         up(&dir->d_inode->i_zombie);        return error;}/* from namei.c */static struct dentry *lookup_create(struct nameidata *nd, int is_dir){        struct dentry *dentry;        down(&nd->dentry->d_inode->i_sem);        dentry = ERR_PTR(-EEXIST);        if (nd->last_type != LAST_NORM)                goto fail;        dentry = lookup_hash(&nd->last, nd->dentry);        if (IS_ERR(dentry))                goto fail;        if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)                goto enoent;        return dentry;enoent:        dput(dentry);        dentry = ERR_PTR(-ENOENT);fail:        return dentry;}int lento_create(const char *name, int mode, struct lento_vfs_context *info){        int error;        struct nameidata nd;        char * pathname;        struct dentry *dentry;        struct presto_file_set *fset;        ENTRY;        pathname = getname(name);        error = PTR_ERR(pathname);        if (IS_ERR(pathname)) {                EXIT;                goto exit;        }        /* this looks up the parent *///        if (path_init(pathname, LOOKUP_FOLLOW | LOOKUP_POSITIVE, &nd))        if (path_init(pathname,  LOOKUP_PARENT, &nd))                error = path_walk(pathname, &nd);        if (error) {		EXIT;                goto exit;	}        dentry = lookup_create(&nd, 0);        error = PTR_ERR(dentry);        if (IS_ERR(dentry)) {                EXIT;                goto exit_lock;        }        fset = presto_fset(dentry);        error = -EINVAL;        if ( !fset ) {                printk("No fileset!\n");                EXIT;                goto exit_lock;        }        error = presto_do_create(fset, dentry->d_parent, dentry, (mode&S_IALLUGO)|S_IFREG,                                 info);        EXIT; exit_lock:        path_release (&nd);	dput(dentry);         up(&dentry->d_parent->d_inode->i_sem);        putname(pathname);exit:        return error;}int presto_do_link(struct presto_file_set *fset, struct dentry *old_dentry,                   struct dentry *dir, struct dentry *new_dentry,                   struct lento_vfs_context *info){        struct rec_info rec;        struct inode *inode;        int error;        struct inode_operations *iops;        struct presto_version tgt_dir_ver;        struct presto_version new_link_ver;        void *handle;        down(&dir->d_inode->i_zombie);	error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH); 	if (error) {		EXIT;        	up(&dir->d_inode->i_zombie);		return error;	}        error = -ENOENT;        inode = old_dentry->d_inode;        if (!inode)                goto exit_lock;        error = may_create(dir->d_inode, new_dentry);        if (error)                goto exit_lock;        error = -EXDEV;        if (dir->d_inode->i_dev != inode->i_dev)                goto exit_lock;        /*         * A link to an append-only or immutable file cannot be created.         */        error = -EPERM;        if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {                EXIT;                goto exit_lock;        }        iops = filter_c2cdiops(fset->fset_cache->cache_filter);        if (!iops->link) {                EXIT;                goto exit_lock;        }        presto_getversion(&tgt_dir_ver, dir->d_inode);        handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_LINK);        if ( IS_ERR(handle) ) {		presto_release_space(fset->fset_cache, PRESTO_REQHIGH);                 printk("presto_do_link: no space for transaction\n");                return -ENOSPC;        }        DQUOT_INIT(dir->d_inode);        lock_kernel();        error = iops->link(old_dentry, dir->d_inode, new_dentry);        unlock_kernel();        if (error) {                EXIT;                goto exit_lock;        }        error = presto_settime(fset, dir, info, ATTR_CTIME | ATTR_MTIME);        if (error) {                 EXIT;                goto exit_lock;        }        error = presto_settime(fset, new_dentry, info, ATTR_CTIME);        if (error) {                 EXIT;                goto exit_lock;        }        presto_debug_fail_blkdev(fset, PRESTO_OP_LINK | 0x10);        presto_getversion(&new_link_ver, new_dentry->d_inode);        if ( presto_do_kml(info, old_dentry->d_inode) )                error = presto_journal_link(&rec, fset, old_dentry, new_dentry,                                            &tgt_dir_ver, &new_link_ver);        presto_debug_fail_blkdev(fset, PRESTO_OP_LINK | 0x20);        if ( presto_do_expect(info, old_dentry->d_inode) )                error = presto_write_last_rcvd(&rec, fset, info);        presto_debug_fail_blkdev(fset, PRESTO_OP_LINK | 0x30);        EXIT;        presto_trans_commit(fset, handle);exit_lock:	presto_release_space(fset->fset_cache, PRESTO_REQHIGH);         up(&dir->d_inode->i_zombie);        return error;}int lento_link(const char * oldname, const char * newname,                          struct lento_vfs_context *info){        int error;        char * from;        char * to;        struct presto_file_set *fset;        from = getname(oldname);        if(IS_ERR(from))                return PTR_ERR(from);        to = getname(newname);        error = PTR_ERR(to);        if (!IS_ERR(to)) {                struct dentry *new_dentry;                struct nameidata nd, old_nd;                error = 0;                if (path_init(from, LOOKUP_POSITIVE, &old_nd))                        error = path_walk(from, &old_nd);                if (error)                        goto exit;                if (path_init(to, LOOKUP_PARENT, &nd))                        error = path_walk(to, &nd);                if (error)                        goto out;                error = -EXDEV;                if (old_nd.mnt != nd.mnt)                        goto out;                new_dentry = lookup_create(&nd, 0);                error = PTR_ERR(new_dentry);                if (!IS_ERR(new_dentry)) {                        fset = presto_fset(new_dentry);                        error = -EINVAL;                        if ( !fset ) {                                printk("No fileset!\n");                                EXIT;                                goto out2;                        }                        error = presto_do_link(fset, old_nd.dentry,                                                nd.dentry,                                               new_dentry, info);                        dput(new_dentry);                }        out2:                up(&nd.dentry->d_inode->i_sem);                path_release(&nd);        out:                path_release(&old_nd);        exit:                putname(to);        }        putname(from);        return error;}int presto_do_unlink(struct presto_file_set *fset, struct dentry *dir,                     struct dentry *dentry, struct lento_vfs_context *info){        struct rec_info rec;        int error;        struct inode_operations *iops;        struct presto_version tgt_dir_ver, old_file_ver;        void *handle;        int do_kml = 0, do_expect =0;	int linkno = 0;        ENTRY;        down(&dir->d_inode->i_zombie);        error = may_delete(dir->d_inode, dentry, 0);        if (error) {                EXIT;                up(&dir->d_inode->i_zombie);                return error;        }        error = -EPERM;        iops = filter_c2cdiops(fset->fset_cache->cache_filter);        if (!iops->unlink) {                EXIT;                up(&dir->d_inode->i_zombie);                return error;        }	error = presto_reserve_space(fset->fset_cache, PRESTO_REQLOW); 	if (error) {		EXIT;        	up(&dir->d_inode->i_zombie);		return error;	}        presto_getversion(&tgt_dir_ver, dir->d_inode);        presto_getversion(&old_file_ver, dentry->d_inode);        handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_UNLINK);        if ( IS_ERR(handle) ) {		presto_release_space(fset->fset_cache, PRESTO_REQLOW);                 printk("ERROR: presto_do_unlink: no space for transaction. Tell Peter.\n");                up(&dir->d_inode->i_zombie);                return -ENOSPC;        }        DQUOT_INIT(dir->d_inode);        if (d_mountpoint(dentry))                error = -EBUSY;        else {                lock_kernel();		linkno = dentry->d_inode->i_nlink;		if (linkno > 1) {			dget(dentry);		}                do_kml = presto_do_kml(info, dir->d_inode);                do_expect = presto_do_expect(info, dir->d_inode);                error = iops->unlink(dir->d_inode, dentry);                unlock_kernel();                if (!error)                        d_delete(dentry);        }        if (linkno > 1) {                 error = presto_settime(fset, dentry, info, ATTR_CTIME);                dput(dentry);                 if (error) {                         EXIT;                        goto exit;                }        }        error = presto_settime(fset, dir, info, ATTR_CTIME | ATTR_MTIME);        if (error) {                 EXIT;                goto exit;        }        up(&dir->d_inode->i_zombie);        if (error) {                EXIT;                goto exit;        }        presto_debug_fail_blkdev(fset, PRESTO_OP_UNLINK | 0x10);        if ( do_kml ) {                 error = presto_journal_unlink(&rec, fset, dir, &tgt_dir_ver,                                              &old_file_ver,                                              dentry->d_name.len,                                              dentry->d_name.name);	}        presto_debug_fail_blkdev(fset, PRESTO_OP_UNLINK | 0x20);        if ( do_expect ) {                 error = presto_write_last_rcvd(&rec, fset, info);	}        presto_debug_fail_blkdev(fset, PRESTO_OP_UNLINK | 0x30);        EXIT;exit:

⌨️ 快捷键说明

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