コード例 #1
0
/* this is common implementation of set_plug_in_inode method of file plugin
 */
int set_plug_in_inode_common(struct inode *object /* inode to set plugin on */ ,
			     struct inode *parent /* parent object */ ,
			     reiser4_object_create_data * data	/* creational
								 * data */ )
{
	__u64 mask;

	object->i_mode = data->mode;
	/* this should be plugin decision */
	object->i_uid = current->cred->fsuid;
	object->i_mtime = object->i_atime = object->i_ctime = CURRENT_TIME;

	/* support for BSD style group-id assignment. See mount's manual page
	   description of bsdgroups ext2 mount options for more details */
	if (reiser4_is_set(object->i_sb, REISER4_BSD_GID))
		object->i_gid = parent->i_gid;
	else if (parent->i_mode & S_ISGID) {
		/* parent directory has sguid bit */
		object->i_gid = parent->i_gid;
		if (S_ISDIR(object->i_mode))
			/* sguid is inherited by sub-directories */
			object->i_mode |= S_ISGID;
	} else
		object->i_gid = current->cred->fsgid;

	/* this object doesn't have stat-data yet */
	reiser4_inode_set_flag(object, REISER4_NO_SD);
#if 0
	/* this is now called after all inode plugins are initialized:
	   do_create_vfs_child after adjust_to_parent */
	/* setup inode and file-operations for this inode */
	setup_inode_ops(object, data);
#endif
	object->i_nlink = 0;
	reiser4_seal_init(&reiser4_inode_data(object)->sd_seal, NULL, NULL);
	mask = (1 << UNIX_STAT) | (1 << LIGHT_WEIGHT_STAT);
	if (!reiser4_is_set(object->i_sb, REISER4_32_BIT_TIMES))
		mask |= (1 << LARGE_TIMES_STAT);

	reiser4_inode_data(object)->extmask = mask;
	return 0;
}
コード例 #2
0
static int change_file(struct inode *inode,
		       reiser4_plugin * plugin,
		       pset_member memb)
{
	/* cannot change object plugin of already existing object */
	if (memb == PSET_FILE)
		return RETERR(-EINVAL);

	/* Change PSET_CREATE */
	return aset_set_unsafe(&reiser4_inode_data(inode)->pset, memb, plugin);
}
コード例 #3
0
/* this is common implementation of key_by_inode method of file plugin
 */
int
key_by_inode_and_offset_common(struct inode *inode, loff_t off,
			       reiser4_key * key)
{
	reiser4_key_init(key);
	set_key_locality(key, reiser4_inode_data(inode)->locality_id);
	set_key_ordering(key, get_inode_ordering(inode));
	set_key_objectid(key, get_inode_oid(inode));	/*FIXME: inode->i_ino */
	set_key_type(key, KEY_BODY_MINOR);
	set_key_offset(key, (__u64) off);
	return 0;
}
コード例 #4
0
ファイル: cluster.c プロジェクト: mgross029/android_kernel
static int change_cluster(struct inode *inode,
			  reiser4_plugin * plugin,
			  pset_member memb)
{
	assert("edward-1324", inode != NULL);
	assert("edward-1325", plugin != NULL);
	assert("edward-1326", is_reiser4_inode(inode));
	assert("edward-1327", plugin->h.type_id == REISER4_CLUSTER_PLUGIN_TYPE);

	/* Can't change the cluster plugin for already existent regular files */
	if (!plugin_of_group(inode_file_plugin(inode), REISER4_DIRECTORY_FILE))
		return RETERR(-EINVAL);

	/* If matches, nothing to change. */
	if (inode_hash_plugin(inode) != NULL &&
	    inode_hash_plugin(inode)->h.id == plugin->h.id)
		return 0;

	return aset_set_unsafe(&reiser4_inode_data(inode)->pset,
			       PSET_CLUSTER, plugin);
}
コード例 #5
0
static int change_compression(struct inode *inode,
                              reiser4_plugin * plugin,
                              pset_member memb)
{
    assert("edward-1316", inode != NULL);
    assert("edward-1317", plugin != NULL);
    assert("edward-1318", is_reiser4_inode(inode));
    assert("edward-1319",
           plugin->h.type_id == REISER4_COMPRESSION_PLUGIN_TYPE);

    /* cannot change compression plugin of already existing regular object */
    if (!plugin_of_group(inode_file_plugin(inode), REISER4_DIRECTORY_FILE))
        return RETERR(-EINVAL);

    /* If matches, nothing to change. */
    if (inode_hash_plugin(inode) != NULL &&
            inode_hash_plugin(inode)->h.id == plugin->h.id)
        return 0;

    return aset_set_unsafe(&reiser4_inode_data(inode)->pset,
                           PSET_COMPRESSION, plugin);
}
コード例 #6
0
/* for every page of file: read page, cut part of extent pointing to this page,
   put data of page tree by tail item */
int extent2tail(struct file * file, struct unix_file_info *uf_info)
{
	int result;
	struct inode *inode;
	struct page *page;
	unsigned long num_pages, i;
	unsigned long start_page;
	reiser4_key from;
	reiser4_key to;
	unsigned count;
	__u64 offset;

	assert("nikita-3362", ea_obtained(uf_info));
	inode = unix_file_info_to_inode(uf_info);
	assert("nikita-3412", !IS_RDONLY(inode));
	assert("vs-1649", uf_info->container != UF_CONTAINER_TAILS);
	assert("", !reiser4_inode_get_flag(inode, REISER4_PART_IN_CONV));

	offset = 0;
	if (reiser4_inode_get_flag(inode, REISER4_PART_MIXED)) {
		/*
		 * file is marked on disk as there was a conversion which did
		 * not complete due to either crash or some error. Find which
		 * offset tail conversion stopped at
		 */
		result = find_start(inode, EXTENT_POINTER_ID, &offset);
		if (result == -ENOENT) {
			/* no extent found, everything is converted */
			uf_info->container = UF_CONTAINER_TAILS;
			complete_conversion(inode);
			return 0;
		} else if (result != 0)
			/* some other error */
			return result;
	}

	reiser4_inode_set_flag(inode, REISER4_PART_IN_CONV);

	/* number of pages in the file */
	num_pages =
	    (inode->i_size + - offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
	start_page = offset >> PAGE_CACHE_SHIFT;

	inode_file_plugin(inode)->key_by_inode(inode, offset, &from);
	to = from;

	result = 0;
	for (i = 0; i < num_pages; i++) {
		__u64 start_byte;

		result = reserve_extent2tail_iteration(inode);
		if (result != 0)
			break;
		if (i == 0 && offset == 0) {
			reiser4_inode_set_flag(inode, REISER4_PART_MIXED);
			reiser4_update_sd(inode);
		}

		page = read_mapping_page(inode->i_mapping,
					 (unsigned)(i + start_page), NULL);
		if (IS_ERR(page)) {
			result = PTR_ERR(page);
			break;
		}

		wait_on_page_locked(page);

		if (!PageUptodate(page)) {
			page_cache_release(page);
			result = RETERR(-EIO);
			break;
		}

		/* cut part of file we have read */
		start_byte = (__u64) ((i + start_page) << PAGE_CACHE_SHIFT);
		set_key_offset(&from, start_byte);
		set_key_offset(&to, start_byte + PAGE_CACHE_SIZE - 1);
		/*
		 * reiser4_cut_tree_object() returns -E_REPEAT to allow atom
		 * commits during over-long truncates. But
		 * extent->tail conversion should be performed in one
		 * transaction.
		 */
		result = reiser4_cut_tree(reiser4_tree_by_inode(inode), &from,
					  &to, inode, 0);

		if (result) {
			page_cache_release(page);
			break;
		}

		/* put page data into tree via tail_write */
		count = PAGE_CACHE_SIZE;
		if ((i == (num_pages - 1)) &&
		    (inode->i_size & ~PAGE_CACHE_MASK))
			/* last page can be incompleted */
			count = (inode->i_size & ~PAGE_CACHE_MASK);
		while (count) {
			loff_t pos = start_byte;

			assert("edward-1537",
			       file != NULL && file->f_dentry != NULL);
			assert("edward-1538",
			       file->f_dentry->d_inode == inode);

			result = reiser4_write_tail(file, inode,
						    (char __user *)kmap(page),
						    count, &pos);
			reiser4_free_file_fsdata(file);
			if (result <= 0) {
				warning("", "reiser4_write_tail failed");
				page_cache_release(page);
				reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV);
				return result;
			}
			count -= result;
		}

		/* release page */
		lock_page(page);
		/* page is already detached from jnode and mapping. */
		assert("vs-1086", page->mapping == NULL);
		assert("nikita-2690",
		       (!PagePrivate(page) && jprivate(page) == 0));
		/* waiting for writeback completion with page lock held is
		 * perfectly valid. */
		wait_on_page_writeback(page);
		reiser4_drop_page(page);
		/* release reference taken by read_cache_page() above */
		page_cache_release(page);

		drop_exclusive_access(uf_info);
		/*
		 * throttle the conversion.
		 * FIXME-EDWARD: Calculate and pass the precise number
		 * of pages that was dirtied
		 */
		reiser4_throttle_write(inode, 1);
		get_exclusive_access(uf_info);
		/*
		 * nobody is allowed to complete conversion but a process which
		 * started it
		 */
		assert("", reiser4_inode_get_flag(inode, REISER4_PART_MIXED));
	}

	reiser4_inode_clr_flag(inode, REISER4_PART_IN_CONV);

	if (i == num_pages) {
		/* file is converted to formatted items */
		assert("vs-1698", reiser4_inode_get_flag(inode,
							 REISER4_PART_MIXED));
		assert("vs-1260",
		       inode_has_no_jnodes(reiser4_inode_data(inode)));

		uf_info->container = UF_CONTAINER_TAILS;
		complete_conversion(inode);
		return 0;
	}
	/*
	 * conversion is not complete. Inode was already marked as
	 * REISER4_PART_MIXED and stat-data were updated at the first
	 * iteration of the loop above.
	 */
	warning("nikita-2282",
		"Partial conversion of %llu: %lu of %lu: %i",
		(unsigned long long)get_inode_oid(inode), i,
		num_pages, result);

	/* this flag should be cleared, otherwise get_exclusive_access_careful()
	   will fall into infinite loop */
	assert("edward-1550", !reiser4_inode_get_flag(inode,
						      REISER4_PART_IN_CONV));
	return result;
}