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

📄 vfs.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (IS_DEADDIR(old_dir)||IS_DEADDIR(new_dir))                error = -ENOENT;        else if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))                error = -EBUSY;        else                 error = do_rename(fset, old_parent, old_dentry,                                         new_parent, new_dentry, info);        if (target) {                if (!error)                        target->i_flags |= S_DEAD;                triple_up(&old_dir->i_zombie,                          &new_dir->i_zombie,                          &target->i_zombie);                if (d_unhashed(new_dentry))                        d_rehash(new_dentry);                dput(new_dentry);        } else                double_up(&old_dir->i_zombie,                          &new_dir->i_zombie);                        if (!error)                d_move(old_dentry,new_dentry);out_unlock:        up(&old_dir->i_sb->s_vfs_rename_sem);        return error;}staticint presto_rename_other(struct presto_file_set *fset, struct dentry *old_parent,                        struct dentry *old_dentry, struct dentry *new_parent,                        struct dentry *new_dentry, struct lento_vfs_context *info){        struct inode *old_dir = old_parent->d_inode;        struct inode *new_dir = new_parent->d_inode;        int error;        if (old_dentry->d_inode == new_dentry->d_inode)                return 0;        error = may_delete(old_dir, old_dentry, 0);        if (error)                return error;        if (new_dir->i_dev != old_dir->i_dev)                return -EXDEV;        if (!new_dentry->d_inode)                error = may_create(new_dir, new_dentry);        else                error = may_delete(new_dir, new_dentry, 0);        if (error)                return error;        if (!old_dir->i_op || !old_dir->i_op->rename)                return -EPERM;        DQUOT_INIT(old_dir);        DQUOT_INIT(new_dir);        double_down(&old_dir->i_zombie, &new_dir->i_zombie);        if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))                error = -EBUSY;        else                error = do_rename(fset, old_parent, old_dentry,                                         new_parent, new_dentry, info);        double_up(&old_dir->i_zombie, &new_dir->i_zombie);        if (error)                return error;        /* The following d_move() should become unconditional */        if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME)) {                d_move(old_dentry, new_dentry);        }        return 0;}int presto_do_rename(struct presto_file_set *fset,               struct dentry *old_parent, struct dentry *old_dentry,              struct dentry *new_parent, struct dentry *new_dentry,              struct lento_vfs_context *info){        if (S_ISDIR(old_dentry->d_inode->i_mode))                return presto_rename_dir(fset, old_parent,old_dentry,new_parent,                                      new_dentry, info);        else                return presto_rename_other(fset, old_parent, old_dentry,                                           new_parent,new_dentry, info);}int lento_do_rename(const char *oldname, const char *newname,                 struct lento_vfs_context *info){        int error = 0;        struct dentry * old_dir, * new_dir;        struct dentry * old_dentry, *new_dentry;        struct nameidata oldnd, newnd;        struct presto_file_set *fset;        ENTRY;        if (path_init(oldname, LOOKUP_PARENT, &oldnd))                error = path_walk(oldname, &oldnd);        if (error)                goto exit;        if (path_init(newname, LOOKUP_PARENT, &newnd))                error = path_walk(newname, &newnd);        if (error)                goto exit1;        error = -EXDEV;        if (oldnd.mnt != newnd.mnt)                goto exit2;        old_dir = oldnd.dentry;        error = -EBUSY;        if (oldnd.last_type != LAST_NORM)                goto exit2;        new_dir = newnd.dentry;        if (newnd.last_type != LAST_NORM)                goto exit2;        double_lock(new_dir, old_dir);        old_dentry = lookup_hash(&oldnd.last, old_dir);        error = PTR_ERR(old_dentry);        if (IS_ERR(old_dentry))                goto exit3;        /* source must exist */        error = -ENOENT;        if (!old_dentry->d_inode)                goto exit4;        fset = presto_fset(old_dentry);        error = -EINVAL;        if ( !fset ) {                printk("No fileset!\n");                EXIT;                goto exit4;        }        /* unless the source is a directory trailing slashes give -ENOTDIR */        if (!S_ISDIR(old_dentry->d_inode->i_mode)) {                error = -ENOTDIR;                if (oldnd.last.name[oldnd.last.len])                        goto exit4;                if (newnd.last.name[newnd.last.len])                        goto exit4;        }        new_dentry = lookup_hash(&newnd.last, new_dir);        error = PTR_ERR(new_dentry);        if (IS_ERR(new_dentry))                goto exit4;        lock_kernel();        error = presto_do_rename(fset, old_dir, old_dentry,                                   new_dir, new_dentry, info);        unlock_kernel();        dput(new_dentry);exit4:        dput(old_dentry);exit3:        double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);exit2:        path_release(&newnd);exit1:        path_release(&oldnd);exit:        return error;}int  lento_rename(const char * oldname, const char * newname,                  struct lento_vfs_context *info){        int error;        char * from;        char * to;        from = getname(oldname);        if(IS_ERR(from))                return PTR_ERR(from);        to = getname(newname);        error = PTR_ERR(to);        if (!IS_ERR(to)) {                error = lento_do_rename(from,to, info);                putname(to);        }        putname(from);        return error;}struct dentry *presto_iopen(struct dentry *dentry,                            ino_t ino, unsigned int generation){        struct presto_file_set *fset;        char name[48];        int error;        ENTRY;        /* see if we already have the dentry we want */        if (dentry->d_inode && dentry->d_inode->i_ino == ino &&            dentry->d_inode->i_generation == generation) {                EXIT;                return dentry;        }        /* Make sure we have a cache beneath us.  We should always find at         * least one dentry inside the cache (if it exists), otherwise not         * even the cache root exists, or we passed in a bad name.         */        fset = presto_fset(dentry);        error = -EINVAL;        if (!fset) {                printk("No fileset for %*s!\n",                       dentry->d_name.len, dentry->d_name.name);                EXIT;                dput(dentry);                return ERR_PTR(error);        }        dput(dentry);        sprintf(name, "%s%#lx%c%#x",                PRESTO_ILOOKUP_MAGIC, ino, PRESTO_ILOOKUP_SEP, generation);        CDEBUG(D_PIOCTL, "opening %ld by number (as %s)\n", ino, name);        return lookup_one_len(name, fset->fset_mtpt, strlen(name));}static struct file *presto_filp_dopen(struct dentry *dentry, int flags){        struct file *f;        struct inode *inode;        int flag, error;        ENTRY;        error = -ENFILE;        f = get_empty_filp();        if (!f) {                CDEBUG(D_PIOCTL, "error getting file pointer\n");                EXIT;                goto out;        }        f->f_flags = flag = flags;        f->f_mode = (flag+1) & O_ACCMODE;        inode = dentry->d_inode;        if (f->f_mode & FMODE_WRITE) {                error = get_write_access(inode);                if (error) {                        CDEBUG(D_PIOCTL, "error getting write access\n");                        EXIT;                        goto cleanup_file;                }        }        f->f_dentry = dentry;        f->f_pos = 0;        f->f_reada = 0;        f->f_op = NULL;        if (inode->i_op)                /* XXX should we set to presto ops, or leave at cache ops? */                f->f_op = inode->i_fop;        if (f->f_op && f->f_op->open) {                error = f->f_op->open(inode, f);                if (error) {                        CDEBUG(D_PIOCTL, "error calling cache 'open'\n");                        EXIT;                        goto cleanup_all;                }        }        f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);        return f;cleanup_all:        if (f->f_mode & FMODE_WRITE)                put_write_access(inode);cleanup_file:        put_filp(f);out:        return ERR_PTR(error);}/* Open an inode by number.  We pass in the cache root name (or a subdirectory * from the cache that is guaranteed to exist) to be able to access the cache. */int lento_iopen(const char *name, ino_t ino, unsigned int generation,                int flags){        char * tmp;        struct dentry *dentry;        struct nameidata nd;        int fd;        int error;        ENTRY;        CDEBUG(D_PIOCTL,               "open %s:inode %#lx (%ld), generation %x (%d), flags %d \n",               name, ino, ino, generation, generation, flags);        /* We don't allow creation of files by number only, as it would         * lead to a dangling files not in any directory.  We could also         * just turn off the flag and ignore it.         */        if (flags & O_CREAT) {                printk(KERN_WARNING __FUNCTION__                       ": create file by inode number (%ld) not allowed\n",ino);                EXIT;                return -EACCES;        }        tmp = getname(name);        if (IS_ERR(tmp)) {                EXIT;                return PTR_ERR(tmp);        }        lock_kernel();again:  /* look the named file or a parent directory so we can get the cache */        error = presto_walk(tmp, &nd);        if ( error && error != -ENOENT ) {                EXIT;                return error;        }         if (error == -ENOENT)                dentry = NULL;        else                 dentry = nd.dentry;        /* we didn't find the named file, so see if a parent exists */        if (!dentry) {                char *slash;                slash = strrchr(tmp, '/');                if (slash && slash != tmp) {                        *slash = '\0';			path_release(&nd);                        goto again;                }                /* we should never get here... */                CDEBUG(D_PIOCTL, "no more path components to try!\n");                fd = -ENOENT;                goto exit;        }        CDEBUG(D_PIOCTL, "returned dentry %p\n", dentry);        dentry = presto_iopen(dentry, ino, generation);        fd = PTR_ERR(dentry);        if (IS_ERR(dentry)) {                EXIT;                goto exit;        }        /* XXX start of code that might be replaced by something like:         * if (flags & (O_WRONLY | O_RDWR)) {         *      error = get_write_access(dentry->d_inode);         *      if (error) {         *              EXIT;         *              goto cleanup_dput;         *      }         * }         * fd = open_dentry(dentry, flags);         *         * including the presto_filp_dopen() function (check dget counts!)         */        fd = get_unused_fd();        if (fd < 0) {                EXIT;                goto cleanup_dput;        }        {                int error;                struct file * f = presto_filp_dopen(dentry, flags);                error = PTR_ERR(f);                if (IS_ERR(f)) {                        put_unused_fd(fd);                        fd = error;                        EXIT;                        goto cleanup_dput;                }                fd_install(fd, f);        }        /* end of code that might be replaced by open_dentry */        EXIT;exit:        unlock_kernel();	path_release(&nd);        putname(tmp);        return fd;cleanup_dput:        putname(&nd);        goto exit;}int lento_close(unsigned int fd, struct lento_vfs_context *info){        struct rec_info rec;        int error;        struct file * filp;        struct dentry *dentry;        int do_kml, do_expect;        ENTRY;        lock_kernel();        error = -EBADF;        filp = fcheck(fd);        if (filp) {                struct files_struct * files = current->files;                dentry = filp->f_dentry;                dget(dentry);                do_kml = presto_do_kml(info, dentry->d_inode);                do_expect = presto_do_expect

⌨️ 快捷键说明

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