コード例 #1
0
int release(fs_context& fs, const char* path, fuse_file_info* fi)
{
    if (ffsp::is_debug_path(fs, path))
        return ffsp::debug_release(fs, path) ? 0 : -EIO;

    set_inode(fi, nullptr);
    return 0;
}
コード例 #2
0
int open(fs_context& fs, const char* path, fuse_file_info* fi)
{
    if (ffsp::is_debug_path(fs, path))
        return ffsp::debug_open(fs, path) ? 0 : -EIO;

    inode* ino;
    int rc = ffsp::lookup(fs, &ino, path);
    if (rc < 0)
        return rc;

    // TODO: Comment on why we explicitly made open & trunc atomic
    if (fi->flags & O_TRUNC)
    {
        rc = ffsp::truncate(fs, *ino, 0);
        if (rc < 0)
            return rc;
    }
    set_inode(fi, ino);
    return 0;
}
コード例 #3
0
ファイル: lca_base.hpp プロジェクト: aicro/patl
 void setup_i(Oracle *oracl)
 {
     vertex vtx(oracl->new_algo(this));
     vtx.iterate(0);
     this_t
         *ltI = oracl->get_by(vtx)->get_i(),
         *rtI = (oracl->get_by(vtx) + 1)->get_i();
     const word_t
         idH = height(),
         ltH = ltI->height(),
         rtH = rtI->height();
     if (idH > ltH && idH > rtH)
         set_inode();
     else if (ltH < rtH)
     {
         set_i(rtI);
         rtI->set_l(this);
     }
     else
     {
         set_i(ltI);
         ltI->set_l(this);
     }
 }
コード例 #4
0
/* todo: return with unlocked? */
struct inode *au_new_inode(struct dentry *dentry, int must_new)
{
	struct inode *inode;
	struct dentry *h_dentry;
	struct super_block *sb;
	ino_t h_ino, ino;
	int err, match;
	aufs_bindex_t bstart;

	sb = dentry->d_sb;
	bstart = au_dbstart(dentry);
	h_dentry = au_h_dptr(dentry, bstart);
	h_ino = h_dentry->d_inode->i_ino;
	err = au_xino_read(sb, bstart, h_ino, &ino);
	inode = ERR_PTR(err);
	if (unlikely(err))
		goto out;
 new_ino:
	if (!ino) {
		ino = au_xino_new_ino(sb);
		if (unlikely(!ino)) {
			inode = ERR_PTR(-EIO);
			goto out;
		}
	}

	AuDbg("i%lu\n", (unsigned long)ino);
	inode = au_iget_locked(sb, ino);
	err = PTR_ERR(inode);
	if (IS_ERR(inode))
		goto out;

	AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
	if (inode->i_state & I_NEW) {
		ii_write_lock_new_child(inode);
		err = set_inode(inode, dentry);
		if (!err) {
			unlock_new_inode(inode);
			goto out; /* success */
		}

		ii_write_unlock(inode);
		iget_failed(inode);
		goto out_err;
	} else if (!must_new) {
		err = reval_inode(inode, dentry, &match);
		if (!err)
			goto out; /* success */
		else if (match)
			goto out_iput;
	}

	if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
		AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
			" b%d, %s, %.*s, hi%lu, i%lu.\n",
			bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
			(unsigned long)h_ino, (unsigned long)ino);
	ino = 0;
	err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
	if (!err) {
		iput(inode);
		goto new_ino;
	}

 out_iput:
	iput(inode);
 out_err:
	inode = ERR_PTR(err);
 out:
	return inode;
}
コード例 #5
0
ファイル: inode.c プロジェクト: mobilehunter/trafficsqueezer
/* todo: return with unlocked? */
struct inode *au_new_inode(struct dentry *dentry, int must_new)
{
	struct inode *inode, *h_inode;
	struct dentry *h_dentry;
	struct super_block *sb;
	struct mutex *mtx;
	ino_t h_ino, ino;
	int err;
	aufs_bindex_t bstart;

	sb = dentry->d_sb;
	bstart = au_dbstart(dentry);
	h_dentry = au_h_dptr(dentry, bstart);
	h_inode = h_dentry->d_inode;
	h_ino = h_inode->i_ino;

	/*
	 * stop 'race'-ing between hardlinks under different
	 * parents.
	 */
	mtx = NULL;
	if (!S_ISDIR(h_inode->i_mode))
		mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;

new_ino:
	if (mtx)
		mutex_lock(mtx);
	err = au_xino_read(sb, bstart, h_ino, &ino);
	inode = ERR_PTR(err);
	if (unlikely(err))
		goto out;

	if (!ino) {
		ino = au_xino_new_ino(sb);
		if (unlikely(!ino)) {
			inode = ERR_PTR(-EIO);
			goto out;
		}
	}

	AuDbg("i%lu\n", (unsigned long)ino);
	inode = au_iget_locked(sb, ino);
	err = PTR_ERR(inode);
	if (IS_ERR(inode))
		goto out;

	AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
	if (inode->i_state & I_NEW) {
		/* verbose coding for lock class name */
		if (unlikely(S_ISLNK(h_inode->i_mode)))
			au_rw_class(&au_ii(inode)->ii_rwsem,
				    au_lc_key + AuLcSymlink_IIINFO);
		else if (unlikely(S_ISDIR(h_inode->i_mode)))
			au_rw_class(&au_ii(inode)->ii_rwsem,
				    au_lc_key + AuLcDir_IIINFO);
		else /* likely */
			au_rw_class(&au_ii(inode)->ii_rwsem,
				    au_lc_key + AuLcNonDir_IIINFO);

		ii_write_lock_new_child(inode);
		err = set_inode(inode, dentry);
		if (!err) {
			unlock_new_inode(inode);
			goto out; /* success */
		}

		/*
		 * iget_failed() calls iput(), but we need to call
		 * ii_write_unlock() after iget_failed(). so dirty hack for
		 * i_count.
		 */
		atomic_inc(&inode->i_count);
		iget_failed(inode);
		ii_write_unlock(inode);
		au_xino_write(sb, bstart, h_ino, /*ino*/0);
		/* ignore this error */
		goto out_iput;
	} else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) {
		/*
		 * horrible race condition between lookup, readdir and copyup
		 * (or something).
		 */
		if (mtx)
			mutex_unlock(mtx);
		err = reval_inode(inode, dentry);
		if (unlikely(err < 0)) {
			mtx = NULL;
			goto out_iput;
		}

		if (!err) {
			mtx = NULL;
			goto out; /* success */
		} else if (mtx)
			mutex_lock(mtx);
	}

	if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
		AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
			" b%d, %s, %pd, hi%lu, i%lu.\n",
			bstart, au_sbtype(h_dentry->d_sb), dentry,
			(unsigned long)h_ino, (unsigned long)ino);
	ino = 0;
	err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
	if (!err) {
		iput(inode);
		if (mtx)
			mutex_unlock(mtx);
		goto new_ino;
	}

out_iput:
	iput(inode);
	inode = ERR_PTR(err);
out:
	if (mtx)
		mutex_unlock(mtx);
	return inode;
}
コード例 #6
0
/* todo: return with unlocked? */
struct inode *au_new_inode(struct dentry *dentry, int must_new)
{
	struct inode *inode, *h_inode;
	struct dentry *h_dentry;
	struct super_block *sb;
	struct mutex *mtx;
	ino_t h_ino, ino;
	int err, match;
	aufs_bindex_t bstart;

	sb = dentry->d_sb;
	bstart = au_dbstart(dentry);
	h_dentry = au_h_dptr(dentry, bstart);
	h_inode = h_dentry->d_inode;
	h_ino = h_inode->i_ino;

	/*
	 * stop 'race'-ing between hardlinks under different
	 * parents.
	 */
	mtx = NULL;
	if (!S_ISDIR(h_inode->i_mode))
		mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx;

new_ino:
	if (mtx)
		mutex_lock(mtx);
	err = au_xino_read(sb, bstart, h_ino, &ino);
	inode = ERR_PTR(err);
	if (unlikely(err))
		goto out;

	if (!ino) {
		ino = au_xino_new_ino(sb);
		if (unlikely(!ino)) {
			inode = ERR_PTR(-EIO);
			goto out;
		}
	}

	AuDbg("i%lu\n", (unsigned long)ino);
	inode = au_iget_locked(sb, ino);
	err = PTR_ERR(inode);
	if (IS_ERR(inode))
		goto out;

	AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW));
	if (inode->i_state & I_NEW) {
		ii_write_lock_new_child(inode);
		err = set_inode(inode, dentry);
		if (!err) {
			unlock_new_inode(inode);
			goto out; /* success */
		}

		ii_write_unlock(inode);
		iget_failed(inode);
		goto out_err;
	} else if (!must_new) {
		/*
		 * horrible race condition between lookup, readdir and copyup
		 * (or something).
		 */
		if (mtx)
			mutex_unlock(mtx);
		err = reval_inode(inode, dentry, &match);
		if (!err) {
			mtx = NULL;
			goto out; /* success */
		} else if (match) {
			mtx = NULL;
			goto out_iput;
		} else if (mtx)
			mutex_lock(mtx);
	}

	if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode)))
		AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir,"
			" b%d, %s, %.*s, hi%lu, i%lu.\n",
			bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry),
			(unsigned long)h_ino, (unsigned long)ino);
	ino = 0;
	err = au_xino_write(sb, bstart, h_ino, /*ino*/0);
	if (!err) {
		iput(inode);
		if (mtx)
			mutex_unlock(mtx);
		goto new_ino;
	}

out_iput:
	iput(inode);
out_err:
	inode = ERR_PTR(err);
out:
	if (mtx)
		mutex_unlock(mtx);
	return inode;
}
コード例 #7
0
int main(int argc, char **argv) {

    //Checks valid no of argument
    if(argc != 3) {
        fprintf(stderr, "Usage: ext2_mkdir <image file name> <file path on ext2 image>\n");
        exit(1);
    }
    //Gets arguments
    int fd = open(argv[1], O_RDWR);
    char *path = argv[2];
    char *dirName = extract_filename(argv[2]);
    
    //maps disk in memory and checks for error
    disk = mmap(NULL, 128 * BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(disk == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }
    //gets superblock and groupd desc.
    struct ext2_super_block *sb = (struct ext2_super_block *)(disk + BLOCK_SIZE);
    struct ext2_group_desc *gd = (struct ext2_group_desc *)  (disk + 2*BLOCK_SIZE + ((sb -> s_block_group_nr) *  sizeof(struct ext2_group_desc)));
    // Checks if file already exists and returns if yes.
	char *directory = strrchr(argv[2], '/');
	directory[(argv[2] == directory)? 1:0] = '\0';
    if(file_exists(path, get_block(disk, gd -> bg_inode_table, BLOCK_SIZE), dirName)!=0){
        fprintf(stderr, "mkdir: file exists\n");
        return EEXIST;
    }
    //CHECK FOR INODE TO RESERVE
    int free_inode;
    if((free_inode = find_first_free_bit(get_block(disk, gd -> bg_inode_bitmap, BLOCK_SIZE), 0, 128)) == -1){
        fprintf(stderr, "mkdir: operation failed: No free inodes");
        exit(1);
    }
    unsigned int dirname_length = strlen(dirName);
    unsigned int dir_entry_size = (8 + dirname_length) + (4 - (8 + dirname_length) % 4) % 4;
    //Creates new directory entry
    struct ext2_dir_entry_2  * new_dir = malloc(dir_entry_size);
	if(!new_dir){
		perror("malloc");
		exit(1);
	}
    new_dir -> inode = free_inode + 1;
    new_dir -> name_len = strlen(dirName);
    new_dir -> rec_len = dir_entry_size;
    new_dir -> file_type = EXT2_FT_DIR;
    memcpy(new_dir -> name, dirName, strlen(dirName));
    int new_capacity = gd -> bg_free_blocks_count;
    
    //Getting info to check that destination is a directory and not reserved
    struct basic_fileinfo destination = find_file(argv[2], get_block(disk, gd -> bg_inode_table, BLOCK_SIZE));
    if(destination.inode < 11 && destination.inode != 2){
        fprintf(stderr, "Invalid destination");
        free(new_dir);
        return ENOENT;
    }//Checks if destination is a directory
    if(destination.type != 'd'){
        fprintf(stderr, "mkdir: destination is not a directory");
        free(new_dir);
        return ENOENT;
   }//Checks if directory has space for the new directory
	if(new_capacity < 1){
		fprintf(stderr, "mkdir: not enough capacity");
		return ENOSPC;
	}
    //Reserves location for new directory entry
    if ((new_capacity = reserve_directory_entry(get_block(disk, gd -> bg_inode_table, BLOCK_SIZE), destination.inode, new_capacity, new_dir, get_block(disk, gd -> bg_block_bitmap, BLOCK_SIZE))) == -1){
        fprintf(stderr, "mkdir: Not enough capacity for file");
        exit(-1);
    }
    //freeing memory and reducing the free inode count
    free(new_dir);
    gd -> bg_free_inodes_count --;
    set_inode(get_inode(get_block(disk, gd -> bg_inode_table, BLOCK_SIZE), free_inode + 1),
              free_inode, 0, NULL,
              0,
              get_block(disk, gd -> bg_block_bitmap, BLOCK_SIZE),
              get_block(disk, gd -> bg_inode_bitmap, BLOCK_SIZE),
		EXT2_S_IFDIR);
    gd -> bg_free_blocks_count = new_capacity;
    printf("Success: Directory entry created.");
    //Adds . directory to the new directory entry
	new_dir = malloc(12);
	if (!new_dir){
		perror("malloc");
		exit(1);
	}
	new_dir -> inode = free_inode + 1;
	new_dir -> name_len = 1; 
	new_dir -> rec_len = 12;
	new_dir -> file_type = EXT2_FT_DIR;
	new_dir -> name[0] = '.';

	struct ext2_inode *inode = get_inode(get_block(disk, gd -> bg_inode_table, BLOCK_SIZE), free_inode + 1);
	inode -> i_block[0] = 0;
    // Adds .. to the new directory entry
	new_capacity = reserve_directory_entry(get_block(disk, gd -> bg_inode_table, BLOCK_SIZE), free_inode + 1, new_capacity, new_dir, get_block(disk, gd -> bg_block_bitmap, BLOCK_SIZE));
	new_dir -> inode = destination.inode;
	new_dir -> name_len = 2;
	new_dir -> name[0] = '.';
	new_dir -> name[1] = '.';
	reserve_directory_entry(get_block(disk, gd -> bg_inode_table, BLOCK_SIZE), free_inode + 1, new_capacity, new_dir, get_block(disk, gd -> bg_block_bitmap, BLOCK_SIZE));
	gd -> bg_free_blocks_count = new_capacity;
	gd -> bg_used_dirs_count += 3;
	free(new_dir);
	free(dirName);
	return 0;
}