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

📄 vfs.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 5 页
字号:
	presto_release_space(fset->fset_cache, PRESTO_REQLOW);         presto_trans_commit(fset, handle);        return error;}int lento_unlink(const char *pathname, struct lento_vfs_context *info){        int error = 0;        char * name;        struct dentry *dentry;        struct nameidata nd;        struct presto_file_set *fset;        ENTRY;        name = getname(pathname);        if(IS_ERR(name))                return PTR_ERR(name);        if (path_init(name, LOOKUP_PARENT, &nd))                error = path_walk(name, &nd);        if (error)                goto exit;        error = -EISDIR;        if (nd.last_type != LAST_NORM)                goto exit1;        down(&nd.dentry->d_inode->i_sem);        dentry = lookup_hash(&nd.last, nd.dentry);        error = PTR_ERR(dentry);        if (!IS_ERR(dentry)) {                fset = presto_fset(dentry);                error = -EINVAL;                if ( !fset ) {                        printk("No fileset!\n");                        EXIT;                        goto exit2;                }                /* Why not before? Because we want correct error value */                if (nd.last.name[nd.last.len])                        goto slashes;                error = presto_do_unlink(fset, nd.dentry, dentry, info);        exit2:                EXIT;                dput(dentry);        }        up(&nd.dentry->d_inode->i_sem);exit1:        path_release(&nd);exit:        putname(name);        return error;slashes:        error = !dentry->d_inode ? -ENOENT :                S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;        goto exit2;}int presto_do_symlink(struct presto_file_set *fset, struct dentry *dir,                      struct dentry *dentry, const char *oldname,                      struct lento_vfs_context *info){        struct rec_info rec;        int error;        struct presto_version tgt_dir_ver, new_link_ver;        struct inode_operations *iops;        void *handle;        ENTRY;        down(&dir->d_inode->i_zombie);	/* record + max path len + space to free */ 	error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096); 	if (error) {		EXIT;        	up(&dir->d_inode->i_zombie);		return error;	}        error = may_create(dir->d_inode, dentry);        if (error) {                EXIT;                goto exit_lock;        }        error = -EPERM;        iops = filter_c2cdiops(fset->fset_cache->cache_filter);        if (!iops->symlink) {                EXIT;                goto exit_lock;        }        presto_getversion(&tgt_dir_ver, dir->d_inode);        handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_SYMLINK);        if ( IS_ERR(handle) ) {		presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);                 printk("ERROR: presto_do_symlink: no space for transaction. Tell Peter.\n");                 EXIT;                return -ENOSPC;        }        DQUOT_INIT(dir->d_inode);        lock_kernel();        error = iops->symlink(dir->d_inode, dentry, oldname);        if (error) {                EXIT;                goto exit;        }        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_c2csiops(cache->cache_filter) )                        filter_setup_symlink_ops(cache->cache_filter,                                                  dentry->d_inode,                                                 &presto_sym_iops,                                                 NULL);                /* make the new inode ours */                dentry->d_inode->i_op = filter_c2usiops(cache->cache_filter);                filter_setup_dentry_ops(cache->cache_filter, dentry->d_op,                                         &presto_dentry_ops);                dentry->d_op = filter_c2udops(cache->cache_filter);                /* XXX ? Cache state ? if Lento creates a symlink */                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;        }        error = presto_settime(fset, dentry, info, ATTR_CTIME | ATTR_MTIME);        if (error) {                 EXIT;                goto exit;        }        presto_debug_fail_blkdev(fset, PRESTO_OP_SYMLINK | 0x10);        presto_getversion(&new_link_ver, dentry->d_inode);        if ( presto_do_kml(info, dentry->d_inode) )                error = presto_journal_symlink(&rec, fset, dentry, oldname,                                               &tgt_dir_ver, &new_link_ver);        presto_debug_fail_blkdev(fset, PRESTO_OP_SYMLINK | 0x20);        if ( presto_do_expect(info, dentry->d_inode) )                error = presto_write_last_rcvd(&rec, fset, info);        presto_debug_fail_blkdev(fset, PRESTO_OP_SYMLINK | 0x30);        EXIT;exit:        unlock_kernel();        presto_trans_commit(fset, handle); exit_lock:	presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);         up(&dir->d_inode->i_zombie);        return error;}int lento_symlink(const char *oldname, const char *newname,                  struct lento_vfs_context *info){        int error;        char *from;        char *to;        struct dentry *dentry;        struct presto_file_set *fset;        struct nameidata nd;        ENTRY;        lock_kernel();        from = getname(oldname);        error = PTR_ERR(from);        if (IS_ERR(from)) {                EXIT;                goto exit;        }        to = getname(newname);        error = PTR_ERR(to);        if (IS_ERR(to)) {                EXIT;                goto exit_from;        }        if (path_init(to, LOOKUP_PARENT, &nd))                 error = path_walk(to, &nd);        if (error) {                EXIT;                goto exit_to;        }        dentry = lookup_create(&nd, 0);        error = PTR_ERR(dentry);        if (IS_ERR(dentry)) {        	path_release(&nd);                EXIT;                goto exit_to;        }        fset = presto_fset(dentry);        error = -EINVAL;        if ( !fset ) {                printk("No fileset!\n");        	path_release(&nd);                EXIT;                goto exit_lock;        }        error = presto_do_symlink(fset, nd.dentry,                                  dentry, oldname, info);        path_release(&nd);        EXIT; exit_lock:        up(&nd.dentry->d_inode->i_sem);        dput(dentry); exit_to:        putname(to); exit_from:        putname(from); exit:        unlock_kernel();        return error;}int presto_do_mkdir(struct presto_file_set *fset, struct dentry *dir,                    struct dentry *dentry, int mode,                    struct lento_vfs_context *info){        struct rec_info rec;        int error;        struct presto_version tgt_dir_ver, new_dir_ver;        void *handle;        ENTRY;        down(&dir->d_inode->i_zombie);	/* one journal record + directory block + room for removals*/ 	error = presto_reserve_space(fset->fset_cache, PRESTO_REQHIGH + 4096); 	if (error) {                 EXIT;        	up(&dir->d_inode->i_zombie);                return error;        }        error = may_create(dir->d_inode, dentry);        if (error) {                EXIT;                goto exit_lock;        }        error = -EPERM;        if (!filter_c2cdiops(fset->fset_cache->cache_filter)->mkdir) {                EXIT;                goto exit_lock;        }        error = -ENOSPC;        presto_getversion(&tgt_dir_ver, dir->d_inode);        handle = presto_trans_start(fset, dir->d_inode, PRESTO_OP_MKDIR);        if ( IS_ERR(handle) ) {		presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);                 printk("presto_do_mkdir: no space for transaction\n");                goto exit_lock;        }        DQUOT_INIT(dir->d_inode);        mode &= (S_IRWXUGO|S_ISVTX);        lock_kernel();        error = filter_c2cdiops(fset->fset_cache->cache_filter)->mkdir(dir->d_inode, dentry, mode);        if (error) {                EXIT;                goto exit;        }        if ( dentry->d_inode && !error &&              dentry->d_inode->i_gid != presto_excluded_gid) {                struct presto_cache *cache = fset->fset_cache;                /* make it ours */                dentry->d_inode->i_op = filter_c2udiops(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 does this, 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;        }        error = presto_settime(fset, dentry, info, ATTR_CTIME | ATTR_MTIME);        if (error) {                 EXIT;                goto exit;        }        presto_debug_fail_blkdev(fset, PRESTO_OP_MKDIR | 0x10);        presto_getversion(&new_dir_ver, dentry->d_inode);        if ( presto_do_kml(info, dentry->d_inode) )                error = presto_journal_mkdir(&rec, fset, dentry, &tgt_dir_ver,                                             &new_dir_ver,                                             dentry->d_inode->i_mode);        presto_debug_fail_blkdev(fset, PRESTO_OP_MKDIR | 0x20);        if ( presto_do_expect(info, dentry->d_inode) )                error = presto_write_last_rcvd(&rec, fset, info);        presto_debug_fail_blkdev(fset, PRESTO_OP_MKDIR | 0x30);        EXIT;exit:        unlock_kernel();        presto_trans_commit(fset, handle); exit_lock:	presto_release_space(fset->fset_cache, PRESTO_REQHIGH + 4096);         up(&dir->d_inode->i_zombie);        return error;}/* * Look out: this function may change a normal dentry * into a directory dentry (different size).. */int lento_mkdir(const char *name, int mode, struct lento_vfs_context *info){        int error;        char *pathname;        struct dentry *dentry;        struct presto_file_set *fset;        struct nameidata nd;        ENTRY;        CDEBUG(D_PIOCTL, "name: %s, mode %o, offset %d, recno %d, flags %x\n",               name, mode, info->slot_offset, info->recno, info->flags);        pathname = getname(name);        error = PTR_ERR(pathname);        if (IS_ERR(pathname)) {                EXIT;                return error;        }        if (path_init(pathname, LOOKUP_PARENT, &nd))                error = path_walk(pathname, &nd);        if (error)                goto out_name;        dentry = lookup_create(&nd, 1);        error = PTR_ERR(dentry);        if (!IS_ERR(dentry)) {                fset = presto_fset(dentry);                error = -EINVAL;                if ( !fset ) {                        printk("No fileset!\n");                        EXIT;                        goto out_dput;                }                error = presto_do_mkdir(fset, nd.dentry, dentry,                                         mode & S_IALLUGO, info);out_dput:		dput(dentry);        }	up(&nd.dentry->d_inode->i_sem);	path_release(&nd);out_name:        EXIT;        putname(pathname);	CDEBUG(D_PIOCTL, "error: %d\n", error);        return error;}static void d_unhash(struct dentry *dentry){        dget(dentry);        switch (atomic_read(&dentry->d_count)) {        default:                shrink_dcache_parent(dentry);                if (atomic_read(&dentry->d_count) != 2)                        break;        case 2:                d_drop(dentry);        }}int presto_do_rmdir(struct presto_file_set *fset, struct dentry *dir,                    struct dentry *dentry, struct lento_vfs_context *info){        struct rec_info rec;        int error;        struct presto_version tgt_dir_ver, old_dir_ver;        struct inode_operations *iops;        void *handle;        int do_kml, do_expect;	int size;        ENTRY;        error = may_delete(dir->d_inode, dentry, 1);        if (error)                return error;        error = -EPERM;        iops = filter_c2cdiops(fset->fset_cache->cache_filter);        if (!iops->rmdir) {                EXIT;                return error;        }

⌨️ 快捷键说明

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