예제 #1
0
파일: fs.c 프로젝트: champo/ArqvengerOS
void fs_fd(struct FileDescriptor* to, struct fs_Inode* inode, int flags) {
    inode->refCount++;

    to->inode = inode;
    to->offset = 0;
    to->flags = flags;
    to->ops = &opsTable[INODE_TYPE(inode->data)];

    if (to->ops->open) {
        to->ops->open(to);
    }
}
예제 #2
0
파일: fs.c 프로젝트: champo/ArqvengerOS
int fs_unlink(struct fs_Inode* path, const char* name) {

    struct fs_DirectoryEntry entry = fs_findentry(path, name);
    if (!entry.inode) {
        return ENOENT;
    }

    struct fs_Inode* inode = fs_inode_open(entry.inode);
    if (inode == NULL) {
        return EIO;
    }
    if (INODE_TYPE(inode->data) == INODE_DIR) {
        fs_inode_close(inode);
        return EISDIR;
    }

    int res = remove_link(path, name, inode);
    fs_inode_close(inode);

    return res;
}
예제 #3
0
파일: fs.c 프로젝트: champo/ArqvengerOS
int fs_rmdir(struct fs_Inode* path, const char* name) {

    struct fs_DirectoryEntry entry = fs_findentry(path, name);
    if (!entry.inode) {
        return ENOENT;
    }

    struct fs_Inode* dir = fs_inode_open(entry.inode);
    if (dir == NULL) {
        return EIO;
    }

    if (INODE_TYPE(dir->data) != INODE_DIR) {
        fs_inode_close(dir);
        return ENOTDIR;
    }

    size_t offset = 0;
    struct DirectoryEntry child = ext2_dir_read(dir, offset);
    while (child.entryLength != 0) {
        if (child.inode != path->number && child.inode != entry.inode) {
            fs_inode_close(dir);
            return ENOTEMPTY;
        }

        offset += child.entryLength;
        child = ext2_dir_read(dir, offset);
    }

    int res = remove_link(path, name, dir);
    if (dir->data->hardLinks == 1) {
        remove_link(dir, ".", dir);
        remove_link(dir, "..", path);
    }
    fs_inode_close(dir);

    return res;
}
예제 #4
0
파일: file.c 프로젝트: CPonty/ext3301-fs
/*
 * ext3301 write: wrapper for the standard file write function.
 *  modifications: handling encryption and immediate files.
 *  original: do_sync_write
 */
ssize_t ext3301_write(struct file * filp, char __user * buf, size_t len,
                      loff_t * ppos) {
    ssize_t ret, written;
    struct inode * i = FILP_INODE(filp);

    dbg_im(KERN_DEBUG "Write: '%s'\n", FILP_NAME(filp));

    //Encryption: Check if the file is in the encryption tree
    if (ext3301_isencrypted(filp->f_path.dentry)) {
        //Encrypt the data being written
        dbg_cr(KERN_DEBUG "- Encrypting data (%d bytes)\n", (int)len);
        if (ext3301_cryptbuf(buf, len) < 0)
            return -EIO;
    }

    //Immediate file only: walk ppos forward manually for Append mode
    if (I_ISIM(i) && (FILP_FLAGS(filp) & O_APPEND)) {
        dbg_im(KERN_DEBUG "O_APPEND: walking ppos to EoF\n");
        *ppos += INODE_ISIZE(i);
    }

    //Immediate file only: Check if it needs to grow into a regular file
    if (I_ISIM(i) && (*ppos+len > EXT3301_IM_SIZE(i))) {
        dbg_im(KERN_DEBUG "- IM-->REG conversion\n");
        ret = ext3301_im2reg(filp);
        if (ret < 0) {
            printk(KERN_DEBUG "IM-->REG conversion fail: ino %lu, err %d\n",
                   INODE_INO(i), (int)ret);
            return ret;
        }
        //Append mode: undo the ppos offset. We are now writing to a
        //regular file, and the default methods already handle this.
        if (FILP_FLAGS(filp) & O_APPEND) {
            dbg_im(KERN_DEBUG "O_APPEND: walking ppos back (REG)\n");
            *ppos -= INODE_ISIZE(i);
        }
    }

    //Write to file (immediate and regular files have different methods)
    if (I_ISIM(i)) {
        dbg_im(KERN_DEBUG "- Write-immediate\n");
        written = ext3301_write_immediate(filp, buf, len, ppos);

    } else {
        dbg_im(KERN_DEBUG "- Write-regular\n");
        written = do_sync_write(filp, buf, len, ppos);
    }

    //Regular file only: Check if it's small enough to convert to immediate
    if (INODE_TYPE(i)==DT_REG && (INODE_ISIZE(i)<=EXT3301_IM_SIZE(i))) {
        dbg_im(KERN_DEBUG "- REG-->IM conversion\n");
        ret = ext3301_reg2im(filp);
        if (ret < 0) {
            printk(KERN_DEBUG "REG-->IM file conversion failed: ino %lu\n",
                   INODE_INO(i));
            return ret;
        }
    }

    return written;
}