Ejemplo n.º 1
0
static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
{
	struct inode * inode;
	int err = -EMLINK;

	if (dir->i_nlink >= EXT2_LINK_MAX)
		goto out;

	ext2_inc_count(dir);

	inode = ext2_new_inode (dir, S_IFDIR | mode);
	err = PTR_ERR(inode);
	if (IS_ERR(inode))
		goto out_dir;

	inode->i_op = &ext2_dir_inode_operations;
	inode->i_fop = &ext2_dir_operations;
	if (test_opt(inode->i_sb, NOBH))
		inode->i_mapping->a_ops = &ext2_nobh_aops;
	else
		inode->i_mapping->a_ops = &ext2_aops;

	ext2_inc_count(inode);

	err = ext2_make_empty(inode, dir);
	if (err)
		goto out_fail;

	err = ext2_add_link(dentry, inode);
	if (err)
		goto out_fail;

	d_instantiate(dentry, inode);
out:
	return err;

out_fail:
	ext2_dec_count(inode);
	ext2_dec_count(inode);
	iput(inode);
out_dir:
	ext2_dec_count(dir);
	goto out;
}
Ejemplo n.º 2
0
Archivo: namei.c Proyecto: mdamt/linux
static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
						bool excl)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
	struct inode *inode;
	nid_t ino = 0;
	int err;

	err = dquot_initialize(dir);
	if (err)
		return err;

	inode = f2fs_new_inode(dir, mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	if (!test_opt(sbi, DISABLE_EXT_IDENTIFY))
		set_cold_files(sbi, inode, dentry->d_name.name);

	inode->i_op = &f2fs_file_inode_operations;
	inode->i_fop = &f2fs_file_operations;
	inode->i_mapping->a_ops = &f2fs_dblock_aops;
	ino = inode->i_ino;

	f2fs_lock_op(sbi);
	err = f2fs_add_link(dentry, inode);
	if (err)
		goto out;
	f2fs_unlock_op(sbi);

	alloc_nid_done(sbi, ino);

	d_instantiate(dentry, inode);
	unlock_new_inode(inode);

	if (IS_DIRSYNC(dir))
		f2fs_sync_fs(sbi->sb, 1);

	f2fs_balance_fs(sbi, true);
	return 0;
out:
	handle_failed_inode(inode);
	return err;
}
Ejemplo n.º 3
0
static int ext2_setup_super (struct super_block * sb,
			      struct ext2_super_block * es,
			      int read_only)
{
	int res = 0;
	struct ext2_sb_info *sbi = EXT2_SB(sb);

	if (le32_to_cpu(es->s_rev_level) > EXT2_MAX_SUPP_REV) {
		printk ("EXT2-fs warning: revision level too high, "
			"forcing read-only mode\n");
		res = MS_RDONLY;
	}
	if (read_only)
		return res;
	if (!(sbi->s_mount_state & EXT2_VALID_FS))
		printk ("EXT2-fs warning: mounting unchecked fs, "
			"running e2fsck is recommended\n");
	else if ((sbi->s_mount_state & EXT2_ERROR_FS))
		printk ("EXT2-fs warning: mounting fs with errors, "
			"running e2fsck is recommended\n");
	else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 &&
		 le16_to_cpu(es->s_mnt_count) >=
		 (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count))
		printk ("EXT2-fs warning: maximal mount count reached, "
			"running e2fsck is recommended\n");
	else if (le32_to_cpu(es->s_checkinterval) &&
		(le32_to_cpu(es->s_lastcheck) + le32_to_cpu(es->s_checkinterval) <= get_seconds()))
		printk ("EXT2-fs warning: checktime reached, "
			"running e2fsck is recommended\n");
	if (!le16_to_cpu(es->s_max_mnt_count))
		es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT);
	le16_add_cpu(&es->s_mnt_count, 1);
	ext2_write_super(sb);
	if (test_opt (sb, DEBUG))
		printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, "
			"bpg=%lu, ipg=%lu, mo=%04lx]\n",
			EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize,
			sbi->s_frag_size,
			sbi->s_groups_count,
			EXT2_BLOCKS_PER_GROUP(sb),
			EXT2_INODES_PER_GROUP(sb),
			sbi->s_mount_opt);
	return res;
}
Ejemplo n.º 4
0
static int f2fs_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
	struct f2fs_sb_info *sbi = F2FS_SB(vfs->mnt_sb);

	if (!(vfs->mnt_sb->s_flags & MS_RDONLY) && test_opt(sbi, BG_GC))
		seq_printf(seq, ",background_gc=%s", "on");
	else
		seq_printf(seq, ",background_gc=%s", "off");
	if (test_opt(sbi, DISABLE_ROLL_FORWARD))
		seq_puts(seq, ",disable_roll_forward");
	if (test_opt(sbi, DISCARD))
		seq_puts(seq, ",discard");
	if (test_opt(sbi, NOHEAP))
		seq_puts(seq, ",no_heap_alloc");
#ifdef CONFIG_F2FS_FS_XATTR
	if (test_opt(sbi, XATTR_USER))
		seq_puts(seq, ",user_xattr");
	else
		seq_puts(seq, ",nouser_xattr");
	if (test_opt(sbi, INLINE_XATTR))
		seq_puts(seq, ",inline_xattr");
#endif
#ifdef CONFIG_F2FS_FS_POSIX_ACL
	if (test_opt(sbi, POSIX_ACL))
		seq_puts(seq, ",acl");
	else
		seq_puts(seq, ",noacl");
#endif
	if (test_opt(sbi, DISABLE_EXT_IDENTIFY))
		seq_puts(seq, ",disable_ext_identify");
	if (test_opt(sbi, INLINE_DATA))
		seq_puts(seq, ",inline_data");
	seq_printf(seq, ",active_logs=%u", sbi->active_logs);

	return 0;
}
Ejemplo n.º 5
0
static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
{
    struct inode *inode = ext2_new_inode(dir, mode, NULL);
    if (IS_ERR(inode))
        return PTR_ERR(inode);

    inode->i_op = &ext2_file_inode_operations;
    if (test_opt(inode->i_sb, NOBH)) {
        inode->i_mapping->a_ops = &ext2_nobh_aops;
        inode->i_fop = &ext2_file_operations;
    } else {
        inode->i_mapping->a_ops = &ext2_aops;
        inode->i_fop = &ext2_file_operations;
    }
    mark_inode_dirty(inode);
    d_tmpfile(dentry, inode);
    unlock_new_inode(inode);
    return 0;
}
Ejemplo n.º 6
0
bool f2fs_may_inline_data(struct inode *inode)
{
    if (!test_opt(F2FS_I_SB(inode), INLINE_DATA))
        return false;

    if (f2fs_is_atomic_file(inode))
        return false;

    if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode))
        return false;

    if (i_size_read(inode) > MAX_INLINE_DATA)
        return false;

    if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode))
        return false;

    return true;
}
Ejemplo n.º 7
0
static int
ext4_xattr_set_acl(struct dentry *dentry, const char *name, const void *value,
		   size_t size, int flags, int type)
{
	struct inode *inode = dentry->d_inode;
	handle_t *handle;
	struct posix_acl *acl;
	int error, retries = 0;

	if (strcmp(name, "") != 0)
		return -EINVAL;
	if (!test_opt(inode->i_sb, POSIX_ACL))
		return -EOPNOTSUPP;
	if (!inode_owner_or_capable(inode))
		return -EPERM;

	if (value) {
		acl = posix_acl_from_xattr(value, size);
		if (IS_ERR(acl))
			return PTR_ERR(acl);
		else if (acl) {
			error = posix_acl_valid(acl);
			if (error)
				goto release_and_out;
		}
	} else
		acl = NULL;

retry:
	handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
	if (IS_ERR(handle)) {
		error = PTR_ERR(handle);
		goto release_and_out;
	}
	error = ext4_set_acl(handle, inode, type, acl);
	ext4_journal_stop(handle);
	if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
		goto retry;

release_and_out:
	posix_acl_release(acl);
	return error;
}
Ejemplo n.º 8
0
static int ext2_symlink (struct inode * dir, struct dentry * dentry,
	const char * symname)
{
	struct super_block * sb = dir->i_sb;
	int err = -ENAMETOOLONG;
	unsigned l = strlen(symname)+1;
	struct inode * inode;

	if (l > sb->s_blocksize)
		goto out;

	inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
	err = PTR_ERR(inode);
	if (IS_ERR(inode))
		goto out;

	if (l > sizeof (EXT2_I(inode)->i_data)) {
		/* slow symlink */
		inode->i_op = &ext2_symlink_inode_operations;
		if (test_opt(inode->i_sb, NOBH))
			inode->i_mapping->a_ops = &ext2_nobh_aops;
		else
			inode->i_mapping->a_ops = &ext2_aops;
		err = page_symlink(inode, symname, l);
		if (err)
			goto out_fail;
	} else {
		/* fast symlink */
		inode->i_op = &ext2_fast_symlink_inode_operations;
		memcpy((char*)(EXT2_I(inode)->i_data),symname,l);
		inode->i_size = l-1;
	}
	mark_inode_dirty(inode);

	err = ext2_add_nondir(dentry, inode);
out:
	return err;

out_fail:
	ext2_dec_count(inode);
	iput (inode);
	goto out;
}
Ejemplo n.º 9
0
static int
ext3_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
{
	struct posix_acl *acl;
	int error;

	if (!test_opt(inode->i_sb, POSIX_ACL))
		return -EOPNOTSUPP;

	acl = ext3_get_acl(inode, type);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (acl == NULL)
		return -ENODATA;
	error = posix_acl_to_xattr(acl, buffer, size);
	posix_acl_release(acl);

	return error;
}
Ejemplo n.º 10
0
Archivo: inline.c Proyecto: 7799/linux
bool f2fs_may_inline(struct inode *inode)
{
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
	block_t nr_blocks;
	loff_t i_size;

	if (!test_opt(sbi, INLINE_DATA))
		return false;

	nr_blocks = F2FS_I(inode)->i_xattr_nid ? 3 : 2;
	if (inode->i_blocks > nr_blocks)
		return false;

	i_size = i_size_read(inode);
	if (i_size > MAX_INLINE_DATA)
		return false;

	return true;
}
Ejemplo n.º 11
0
Archivo: namei.c Proyecto: 7799/linux
static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
						bool excl)
{
	struct super_block *sb = dir->i_sb;
	struct f2fs_sb_info *sbi = F2FS_SB(sb);
	struct inode *inode;
	nid_t ino = 0;
	int err;

	f2fs_balance_fs(sbi);

	inode = f2fs_new_inode(dir, mode);
	if (IS_ERR(inode))
		return PTR_ERR(inode);

	if (!test_opt(sbi, DISABLE_EXT_IDENTIFY))
		set_cold_files(sbi, inode, dentry->d_name.name);

	inode->i_op = &f2fs_file_inode_operations;
	inode->i_fop = &f2fs_file_operations;
	inode->i_mapping->a_ops = &f2fs_dblock_aops;
	ino = inode->i_ino;

	f2fs_lock_op(sbi);
	err = f2fs_add_link(dentry, inode);
	f2fs_unlock_op(sbi);
	if (err)
		goto out;

	alloc_nid_done(sbi, ino);

	d_instantiate(dentry, inode);
	unlock_new_inode(inode);
	return 0;
out:
	clear_nlink(inode);
	unlock_new_inode(inode);
	make_bad_inode(inode);
	iput(inode);
	alloc_nid_failed(sbi, ino);
	return err;
}
static int
ext3_xattr_user_set(struct inode *inode, const char *name,
		    const void *value, size_t size, int flags)
{
	int error;

	if (strcmp(name, "") == 0)
		return -EINVAL;
	if (!test_opt(inode->i_sb, XATTR_USER))
		return -EOPNOTSUPP;
	if ( !S_ISREG(inode->i_mode) &&
	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
		return -EPERM;
	error = permission(inode, MAY_WRITE, NULL);
	if (error)
		return error;

	return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name,
			      value, size, flags);
}
Ejemplo n.º 13
0
long ext4_set_gps_location(struct inode *inode)
{
	struct gps_location loc;
	struct ext4_inode_info *iinfo = EXT4_I(inode);
	long ts;

	if (!test_opt(inode->i_sb, GPS_AWARE_INODE))
		return -ENODEV;
	kget_gps_location(&loc, &ts);
	ts = CURRENT_TIME_SEC.tv_sec - ts;

	write_lock(&iinfo->i_gps_lock);
	memcpy(&iinfo->i_latitude, &loc.latitude, sizeof(long long));
	memcpy(&iinfo->i_longitude, &loc.longitude, sizeof(long long));
	memcpy(&iinfo->i_accuracy, &loc.accuracy, sizeof(long));
	memcpy(&iinfo->i_coord_age, &ts, sizeof(long));
	write_unlock(&iinfo->i_gps_lock);

	return 0;
}
Ejemplo n.º 14
0
/*
 * Does chmod for an inode that may have an Access Control List. The
 * inode->i_mode field must be updated to the desired value by the caller
 * before calling this function.
 * Returns 0 on success, or a negative error number.
 *
 * We change the ACL rather than storing some ACL entries in the file
 * mode permission bits (which would be more efficient), because that
 * would break once additional permissions (like  ACL_APPEND, ACL_DELETE
 * for directories) are added. There are no more bits available in the
 * file mode.
 *
 * inode->i_mutex: down
 */
int
ext2_acl_chmod(struct inode *inode)
{
	struct posix_acl *acl;
        int error;

	if (!test_opt(inode->i_sb, POSIX_ACL))
		return 0;
	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;
	acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
	if (IS_ERR(acl) || !acl)
		return PTR_ERR(acl);
	error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
	if (error)
		return error;
	error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl);
	posix_acl_release(acl);
	return error;
}
Ejemplo n.º 15
0
Archivo: inline.c Proyecto: 3null/linux
bool f2fs_may_inline(struct inode *inode)
{
	block_t nr_blocks;
	loff_t i_size;

	if (!test_opt(F2FS_I_SB(inode), INLINE_DATA))
		return false;

	if (f2fs_is_atomic_file(inode))
		return false;

	nr_blocks = F2FS_I(inode)->i_xattr_nid ? 3 : 2;
	if (inode->i_blocks > nr_blocks)
		return false;

	i_size = i_size_read(inode);
	if (i_size > MAX_INLINE_DATA)
		return false;

	return true;
}
Ejemplo n.º 16
0
/*
 * By the time this is called, we already have created
 * the directory cache entry for the new file, but it
 * is so far negative - it has no inode.
 *
 * If the create succeeds, we fill in the inode information
 * with d_instantiate(). 
 */
static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd)
{
	struct inode * inode = ext2_new_inode (dir, mode);
	int err = PTR_ERR(inode);
	if (!IS_ERR(inode)) {
		inode->i_op = &ext2_file_inode_operations;
		if (ext2_use_xip(inode->i_sb)) {
			inode->i_mapping->a_ops = &ext2_aops_xip;
			inode->i_fop = &ext2_xip_file_operations;
		} else if (test_opt(inode->i_sb, NOBH)) {
			inode->i_mapping->a_ops = &ext2_nobh_aops;
			inode->i_fop = &ext2_file_operations;
		} else {
			inode->i_mapping->a_ops = &ext2_aops;
			inode->i_fop = &ext2_file_operations;
		}
		mark_inode_dirty(inode);
		err = ext2_add_nondir(dentry, inode);
	}
	return err;
}
Ejemplo n.º 17
0
/*
 * By the time this is called, we already have created
 * the directory cache entry for the new file, but it
 * is so far negative - it has no inode.
 *
 * If the create succeeds, we fill in the inode information
 * with d_instantiate().
 */
static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, bool excl)
{
    struct inode *inode;

    dquot_initialize(dir);

    inode = ext2_new_inode(dir, mode, &dentry->d_name);
    if (IS_ERR(inode))
        return PTR_ERR(inode);

    inode->i_op = &ext2_file_inode_operations;
    if (test_opt(inode->i_sb, NOBH)) {
        inode->i_mapping->a_ops = &ext2_nobh_aops;
        inode->i_fop = &ext2_file_operations;
    } else {
        inode->i_mapping->a_ops = &ext2_aops;
        inode->i_fop = &ext2_file_operations;
    }
    mark_inode_dirty(inode);
    return ext2_add_nondir(dentry, inode);
}
Ejemplo n.º 18
0
void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
                            enum page_type type, int rw)
{
    enum page_type btype = PAGE_TYPE_OF_BIO(type);
    struct f2fs_bio_info *io;

    io = is_read_io(rw) ? &sbi->read_io : &sbi->write_io[btype];

    down_write(&io->io_rwsem);

    /* change META to META_FLUSH in the checkpoint procedure */
    if (type >= META_FLUSH) {
        io->fio.type = META_FLUSH;
        if (test_opt(sbi, NOBARRIER))
            io->fio.rw = WRITE_FLUSH | REQ_META | REQ_PRIO;
        else
            io->fio.rw = WRITE_FLUSH_FUA | REQ_META | REQ_PRIO;
    }
    __submit_merged_bio(io);
    up_write(&io->io_rwsem);
}
Ejemplo n.º 19
0
static int f2fs_xattr_set_acl(struct dentry *dentry, const char *name,
		const void *value, size_t size, int flags, int type)
{
	struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
	struct inode *inode = dentry->d_inode;
	struct posix_acl *acl = NULL;
	int error;

	if (!test_opt(sbi, POSIX_ACL))
		return -EOPNOTSUPP;

	if (strcmp(name, "") != 0)
		return -EINVAL;

	/*
	 * 2.6.35 uses is_owner_or_cap() instead of inode_owner_or_capable()
	 * -- marc1706
	 */
	if (!is_owner_or_cap(inode))
		return -EPERM;

	if (value) {
		acl = posix_acl_from_xattr(value, size);
		if (IS_ERR(acl))
			return PTR_ERR(acl);
		if (acl) {
			error = posix_acl_valid(acl);
			if (error)
				goto release_and_out;
		}
	} else {
		acl = NULL;
	}

	error = f2fs_set_acl(inode, type, acl);

release_and_out:
	posix_acl_release(acl);
	return error;
}
Ejemplo n.º 20
0
struct posix_acl *f2fs_get_acl(struct inode *inode, int type)
{
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
	int name_index = F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT;
	void *value = NULL;
	struct posix_acl *acl;
	int retval;

	if (!test_opt(sbi, POSIX_ACL))
		return NULL;

	acl = get_cached_acl(inode, type);
	if (acl != ACL_NOT_CACHED)
		return acl;

	if (type == ACL_TYPE_ACCESS)
		name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;

	retval = f2fs_getxattr(inode, name_index, "", NULL, 0);
	if (retval > 0) {
		value = kmalloc(retval, GFP_KERNEL);
		if (!value)
			return ERR_PTR(-ENOMEM);
		retval = f2fs_getxattr(inode, name_index, "", value, retval);
	}

	if (retval < 0) {
		if (retval == -ENODATA)
			acl = NULL;
		else
			acl = ERR_PTR(retval);
	} else {
		acl = f2fs_acl_from_disk(value, retval);
	}
	kfree(value);
	if (!IS_ERR(acl))
		set_cached_acl(inode, type, acl);

	return acl;
}
Ejemplo n.º 21
0
/*
 * Does chmod for an inode that may have an Access Control List. The
 * inode->i_mode field must be updated to the desired value by the caller
 * before calling this function.
 * Returns 0 on success, or a negative error number.
 *
 * We change the ACL rather than storing some ACL entries in the file
 * mode permission bits (which would be more efficient), because that
 * would break once additional permissions (like  ACL_APPEND, ACL_DELETE
 * for directories) are added. There are no more bits available in the
 * file mode.
 *
 * inode->i_mutex: down
 */
int
ext3_acl_chmod(struct inode *inode)
{
	struct posix_acl *acl, *clone;
        int error;

	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;
	if (!test_opt(inode->i_sb, POSIX_ACL))
		return 0;
	acl = ext3_get_acl(inode, ACL_TYPE_ACCESS);
	if (IS_ERR(acl) || !acl)
		return PTR_ERR(acl);
	clone = posix_acl_clone(acl, GFP_KERNEL);
	posix_acl_release(acl);
	if (!clone)
		return -ENOMEM;
	error = posix_acl_chmod_masq(clone, inode->i_mode);
	if (!error) {
		handle_t *handle;
		int retries = 0;

	retry:
		handle = ext3_journal_start(inode,
				EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
		if (IS_ERR(handle)) {
			error = PTR_ERR(handle);
			ext3_std_error(inode->i_sb, error);
			goto out;
		}
		error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
		ext3_journal_stop(handle);
		if (error == -ENOSPC &&
		    ext3_should_retry_alloc(inode->i_sb, &retries))
			goto retry;
	}
out:
	posix_acl_release(clone);
	return error;
}
Ejemplo n.º 22
0
static int
ext4_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer,
		   size_t size, int type)
{
	struct posix_acl *acl;
	int error;

	if (strcmp(name, "") != 0)
		return -EINVAL;
	if (!test_opt(dentry->d_sb, POSIX_ACL))
		return -EOPNOTSUPP;

	acl = ext4_get_acl(dentry->d_inode, type);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (acl == NULL)
		return -ENODATA;
	error = posix_acl_to_xattr(acl, buffer, size);
	posix_acl_release(acl);

	return error;
}
Ejemplo n.º 23
0
void	opt(char **av, char *tabb)
{
  int	i;
  int	y;
  int	bo;

  i = 1;
  my_bzero(tabb, 3);
  while (av[i] != NULL && av[i][0] == '-')
    {
      y = 0;
      if (av[i][y] == '-')
	bo = test_opt(av, tabb, y, i);
      if (bo == 1)
	{
	  my_putstr(av[i], 1);
	  if (av[i + 1] != NULL && tabb[2] != 's')
	    my_putchar(' ', 1);
	}
      i++;
    }
}
Ejemplo n.º 24
0
static int f2fs_xattr_get_acl(struct dentry *dentry, const char *name,
		void *buffer, size_t size, int type)
{
	struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
	struct posix_acl *acl;
	int error;

	if (strcmp(name, "") != 0)
		return -EINVAL;
	if (!test_opt(sbi, POSIX_ACL))
		return -EOPNOTSUPP;

	acl = f2fs_get_acl(dentry->d_inode, type);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (!acl)
		return -ENODATA;
	error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
	posix_acl_release(acl);

	return error;
}
Ejemplo n.º 25
0
static inline bool need_do_checkpoint(struct inode *inode)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	bool need_cp = false;

	if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1)
		need_cp = true;
	else if (file_wrong_pino(inode))
		need_cp = true;
	else if (!space_for_roll_forward(sbi))
		need_cp = true;
	else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino))
		need_cp = true;
	else if (F2FS_I(inode)->xattr_ver == cur_cp_version(F2FS_CKPT(sbi)))
		need_cp = true;
	else if (test_opt(sbi, FASTBOOT))
		need_cp = true;
	else if (sbi->active_logs == 2)
		need_cp = true;

	return need_cp;
}
Ejemplo n.º 26
0
static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
		const void *value, size_t size, int flags, int type)
{
	struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);

	switch (type) {
	case F2FS_XATTR_INDEX_USER:
		if (!test_opt(sbi, XATTR_USER))
			return -EOPNOTSUPP;
		break;
	case F2FS_XATTR_INDEX_TRUSTED:
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;
		break;
	default:
		return -EINVAL;
	}
	if (strcmp(name, "") == 0)
		return -EINVAL;

	return f2fs_setxattr(dentry->d_inode, type, name, value, size);
}
Ejemplo n.º 27
0
static int
ext3_xattr_set_acl(struct inode *inode, int type, const void *value,
		   size_t size)
{
	handle_t *handle;
	struct posix_acl *acl;
	int error, retries = 0;

	if (!test_opt(inode->i_sb, POSIX_ACL))
		return -EOPNOTSUPP;
	if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
		return -EPERM;

	if (value) {
		acl = posix_acl_from_xattr(value, size);
		if (IS_ERR(acl))
			return PTR_ERR(acl);
		else if (acl) {
			error = posix_acl_valid(acl);
			if (error)
				goto release_and_out;
		}
	} else
		acl = NULL;

retry:
	handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
	if (IS_ERR(handle))
		return PTR_ERR(handle);
	error = ext3_set_acl(handle, inode, type, acl);
	ext3_journal_stop(handle);
	if (error == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
		goto retry;

release_and_out:
	posix_acl_release(acl);
	return error;
}
Ejemplo n.º 28
0
static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
		struct dentry *unused, struct inode *inode,
		const char *name, void *buffer, size_t size)
{
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);

	switch (handler->flags) {
	case F2FS_XATTR_INDEX_USER:
		if (!test_opt(sbi, XATTR_USER))
			return -EOPNOTSUPP;
		break;
	case F2FS_XATTR_INDEX_TRUSTED:
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;
		break;
	case F2FS_XATTR_INDEX_SECURITY:
		break;
	default:
		return -EINVAL;
	}
	return f2fs_getxattr(inode, handler->flags, name,
			     buffer, size, NULL);
}
Ejemplo n.º 29
0
int f2fs_acl_chmod(struct inode *inode)
{
	struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
	struct posix_acl *acl;
	int error;
	mode_t mode = get_inode_mode(inode);

	if (!test_opt(sbi, POSIX_ACL))
		return 0;
	if (S_ISLNK(mode))
		return -EOPNOTSUPP;

	acl = f2fs_get_acl(inode, ACL_TYPE_ACCESS);
	if (IS_ERR(acl) || !acl)
		return PTR_ERR(acl);

	error = posix_acl_chmod(&acl, GFP_KERNEL, mode);
	if (error)
		return error;
	error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl);
	posix_acl_release(acl);
	return error;
}
Ejemplo n.º 30
0
/*
 * Does chmod for an inode that may have an Access Control List. The
 * inode->i_mode field must be updated to the desired value by the caller
 * before calling this function.
 * Returns 0 on success, or a negative error number.
 *
 * We change the ACL rather than storing some ACL entries in the file
 * mode permission bits (which would be more efficient), because that
 * would break once additional permissions (like  ACL_APPEND, ACL_DELETE
 * for directories) are added. There are no more bits available in the
 * file mode.
 *
 * inode->i_mutex: down
 */
int
ext2_acl_chmod(struct inode *inode)
{
	struct posix_acl *acl, *clone;
        int error;

	if (!test_opt(inode->i_sb, POSIX_ACL))
		return 0;
	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;
	acl = ext2_get_acl(inode, ACL_TYPE_ACCESS);
	if (IS_ERR(acl) || !acl)
		return PTR_ERR(acl);
	clone = posix_acl_clone(acl, GFP_KERNEL);
	posix_acl_release(acl);
	if (!clone)
		return -ENOMEM;
	error = posix_acl_chmod_masq(clone, inode->i_mode);
	if (!error)
		error = ext2_set_acl(inode, ACL_TYPE_ACCESS, clone);
	posix_acl_release(clone);
	return error;
}