Пример #1
0
int pmfs_set_blocksize_hint(struct super_block *sb, struct pmfs_inode *pi,
		loff_t new_size)
{
	unsigned short block_type;

	if (!pmfs_can_set_blocksize_hint(pi, new_size))
		return 0;

	if (new_size >= 0x40000000) {   /* 1G */
		block_type = PMFS_BLOCK_TYPE_1G;
		goto hint_set;
	}

	if (new_size >= 0x200000) {     /* 2M */
		block_type = PMFS_BLOCK_TYPE_2M;
		goto hint_set;
	}

	/* defaulting to 4K */
	block_type = PMFS_BLOCK_TYPE_4K;

hint_set:
	pmfs_dbg_verbose(
		"Hint: new_size 0x%llx, i_size 0x%llx, root 0x%llx\n",
		new_size, pi->i_size, le64_to_cpu(pi->root));
	pmfs_dbg_verbose("Setting the hint to 0x%x\n", block_type);
	pmfs_memunlock_inode(sb, pi);
	pi->i_blk_type = block_type;
	pmfs_memlock_inode(sb, pi);
	return 0;
}
Пример #2
0
/* This function is called by both msync() and fsync().
 * TODO: Check if we can avoid calling pmfs_flush_buffer() for fsync. We use
 * movnti to write data to files, so we may want to avoid doing unnecessary
 * pmfs_flush_buffer() on fsync() */
int pmfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{
	/* Sync from start to end[inclusive] */
	struct address_space *mapping = file->f_mapping;
	struct inode *inode = mapping->host;
	loff_t isize;
	int error;

	/* if the file is not mmap'ed, there is no need to do clflushes */
	if (mapping_mapped(mapping) == 0)
		goto persist;

	end += 1; /* end is inclusive. We like our indices normal please ! */

	isize = i_size_read(inode);

	if ((unsigned long)end > (unsigned long)isize)
		end = isize;
	if (!isize || (start >= end))
	{
		pmfs_dbg_verbose("[%s:%d] : (ERR) isize(%llx), start(%llx),"
			" end(%llx)\n", __func__, __LINE__, isize, start, end);
		return -ENODATA;
	}

	/* Align start and end to cacheline boundaries */
	start = start & CACHELINE_MASK;
	end = CACHELINE_ALIGN(end);
	do {
		void *xip_mem;
		pgoff_t pgoff;
		loff_t offset;
		unsigned long xip_pfn, nr_flush_bytes;

		pgoff = start >> PAGE_CACHE_SHIFT;
		offset = start & ~PAGE_CACHE_MASK;

		nr_flush_bytes = PAGE_CACHE_SIZE - offset;
		if (nr_flush_bytes > (end - start))
			nr_flush_bytes = end - start;

		error = mapping->a_ops->get_xip_mem(mapping, pgoff, 0,
		&xip_mem, &xip_pfn);

		if (unlikely(error)) {
			/* sparse files could have such holes */
			pmfs_dbg_verbose("[%s:%d] : start(%llx), end(%llx),"
			" pgoff(%lx)\n", __func__, __LINE__, start, end, pgoff);
		} else {
			/* flush the range */
			pmfs_flush_buffer(xip_mem+offset, nr_flush_bytes, 0);
		}

		start += nr_flush_bytes;
	} while (start < end);
persist:
	PERSISTENT_MARK();
	PERSISTENT_BARRIER();
	return 0;
}
Пример #3
0
static struct dentry *pmfs_lookup(struct inode *dir, struct dentry *dentry,
				   unsigned int flags)
{
	struct inode *inode = NULL;
	struct pmfs_dir_logentry *de;
	ino_t ino;
	timing_t lookup_time;

	PMFS_START_TIMING(lookup_t, lookup_time);
	if (dentry->d_name.len > PMFS_NAME_LEN)
		return ERR_PTR(-ENAMETOOLONG);

	pmfs_dbg_verbose("%s: %s\n", __func__, dentry->d_name.name);
	ino = pmfs_inode_by_name(dir, &dentry->d_name, &de);
	pmfs_dbg_verbose("%s: ino %lu\n", __func__, ino);
	if (ino) {
		inode = pmfs_iget(dir->i_sb, ino);
		if (inode == ERR_PTR(-ESTALE)) {
			pmfs_err(dir->i_sb, __func__,
				  "deleted inode referenced: %lu",
				  (unsigned long)ino);
			return ERR_PTR(-EIO);
		}
	}

	PMFS_END_TIMING(lookup_t, lookup_time);
	return d_splice_alias(inode, dentry);
}
Пример #4
0
/* Returns new tail after append */
int pmfs_append_link_change_entry(struct super_block *sb,
	struct pmfs_inode *pi, struct inode *inode, u64 tail, u64 *new_tail)
{
	struct pmfs_inode_info *si = PMFS_I(inode);
	struct pmfs_inode_info_header *sih = si->header;
	struct pmfs_link_change_entry *entry;
	u64 curr_p;
	size_t size = sizeof(struct pmfs_link_change_entry);
	timing_t append_time;

	PMFS_START_TIMING(append_entry_t, append_time);
	pmfs_dbg_verbose("%s: inode %lu attr change\n",
				__func__, inode->i_ino);

	curr_p = pmfs_get_append_head(sb, pi, sih, tail, size, 0, 1);
	if (curr_p == 0)
		return -ENOMEM;

	entry = (struct pmfs_link_change_entry *)pmfs_get_block(sb, curr_p);
	entry->entry_type = LINK_CHANGE;
	entry->links = cpu_to_le16(inode->i_nlink);
	entry->ctime = cpu_to_le32(inode->i_ctime.tv_sec);
	entry->flags = cpu_to_le32(inode->i_flags);
	entry->generation = cpu_to_le32(inode->i_generation);
	pmfs_flush_buffer(entry, size, 0);
	*new_tail = curr_p + size;

	PMFS_END_TIMING(append_entry_t, append_time);
	return 0;
}
Пример #5
0
void pmfs_print_lite_transaction(struct pmfs_lite_journal_entry *entry)
{
	int i;

	for (i = 0; i < 4; i++)
		pmfs_dbg_verbose("Entry %d: addr 0x%llx, value 0x%llx\n",
				i, entry->addrs[i], entry->values[i]);
}
Пример #6
0
static ssize_t pmfs_read_backing_store(struct file *flp, char *dest,
	ssize_t bytes, loff_t *roff)
{
	mm_segment_t old_fs;
	ssize_t len = 0;

	if (bytes > 0) {
		old_fs = get_fs();
		set_fs(get_ds());
		len = vfs_read(flp, dest, bytes, roff);
		set_fs(old_fs);
		if (len <= 0)
			pmfs_dbg_verbose("Could not read file or corrupted pmfs\n");
	}
	return len;
}
Пример #7
0
static ssize_t pmfs_write_backing_store(struct file *flp, char *src,
		ssize_t bytes, loff_t *woff)
{
	mm_segment_t old_fs;
	ssize_t len = 0;

	if (bytes > 0) {
		old_fs = get_fs();
		set_fs(get_ds());
		len = vfs_write(flp, src, bytes, woff);
		set_fs(old_fs);
		if (len <= 0)
			pmfs_dbg_verbose("Could not write file or corrupted pmfs\n");
	}
	return len;
}
Пример #8
0
int pmfs_lite_journal_hard_init(struct super_block *sb)
{
	struct pmfs_inode *pi;
	unsigned long blocknr = 0;
	unsigned long pmfs_ino;
	int allocated;
	u64 block;

	pi = pmfs_get_inode_by_ino(sb, PMFS_LITEJOURNAL_INO);
	pmfs_ino = PMFS_LITEJOURNAL_INO;
	allocated = pmfs_new_log_blocks(sb, pmfs_ino, &blocknr, 1,
						PMFS_BLOCK_TYPE_4K, 1);
	pmfs_dbg_verbose("%s: allocate log @ 0x%lx\n", __func__, blocknr);
	if (allocated != 1 || blocknr == 0)
		return -ENOSPC;

	pi->i_blocks = 1;
	block = pmfs_get_block_off(sb, blocknr,	PMFS_BLOCK_TYPE_4K);
	pi->log_head = pi->log_tail = block;
	pmfs_flush_buffer(&pi->log_head, CACHELINE_SIZE, 1);

	return pmfs_lite_journal_soft_init(sb);
}