Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bea9a6d2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2:
  ocfs2: Silence gcc warning in ocfs2_write_zero_page().
  jbd2/ocfs2: Fix block checksumming when a buffer is used in several transactions
  ocfs2/dlm: Remove BUG_ON from migration in the rare case of a down node
  ocfs2: Don't duplicate pages past i_size during CoW.
  ocfs2: tighten up strlen() checking
  ocfs2: Make xattr reflink work with new local alloc reservation.
  ocfs2: make xattr extension work with new local alloc reservation.
  ocfs2: Remove the redundant cpu_to_le64.
  ocfs2/dlm: don't access beyond bitmap size
  ocfs2: No need to zero pages past i_size.
  ocfs2: Zero the tail cluster when extending past i_size.
  ocfs2: When zero extending, do it by page.
  ocfs2: Limit default local alloc size within bitmap range.
  ocfs2: Move orphan scan work to ocfs2_wq.
  fs/ocfs2/dlm: Add missing spin_unlock
parents cd9f040d 5453258d
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -297,7 +297,6 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
	struct page *new_page;
	unsigned int new_offset;
	struct buffer_head *bh_in = jh2bh(jh_in);
	struct jbd2_buffer_trigger_type *triggers;
	journal_t *journal = transaction->t_journal;

	/*
@@ -328,21 +327,21 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
		done_copy_out = 1;
		new_page = virt_to_page(jh_in->b_frozen_data);
		new_offset = offset_in_page(jh_in->b_frozen_data);
		triggers = jh_in->b_frozen_triggers;
	} else {
		new_page = jh2bh(jh_in)->b_page;
		new_offset = offset_in_page(jh2bh(jh_in)->b_data);
		triggers = jh_in->b_triggers;
	}

	mapped_data = kmap_atomic(new_page, KM_USER0);
	/*
	 * Fire any commit trigger.  Do this before checking for escaping,
	 * as the trigger may modify the magic offset.  If a copy-out
	 * happens afterwards, it will have the correct data in the buffer.
	 */
	jbd2_buffer_commit_trigger(jh_in, mapped_data + new_offset,
				   triggers);
	 * Fire data frozen trigger if data already wasn't frozen.  Do this
	 * before checking for escaping, as the trigger may modify the magic
	 * offset.  If a copy-out happens afterwards, it will have the correct
	 * data in the buffer.
	 */
	if (!done_copy_out)
		jbd2_buffer_frozen_trigger(jh_in, mapped_data + new_offset,
					   jh_in->b_triggers);

	/*
	 * Check for escaping
+6 −3
Original line number Diff line number Diff line
@@ -725,6 +725,9 @@ do_get_write_access(handle_t *handle, struct journal_head *jh,
		page = jh2bh(jh)->b_page;
		offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK;
		source = kmap_atomic(page, KM_USER0);
		/* Fire data frozen trigger just before we copy the data */
		jbd2_buffer_frozen_trigger(jh, source + offset,
					   jh->b_triggers);
		memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size);
		kunmap_atomic(source, KM_USER0);

@@ -963,15 +966,15 @@ void jbd2_journal_set_triggers(struct buffer_head *bh,
	jh->b_triggers = type;
}

void jbd2_buffer_commit_trigger(struct journal_head *jh, void *mapped_data,
void jbd2_buffer_frozen_trigger(struct journal_head *jh, void *mapped_data,
				struct jbd2_buffer_trigger_type *triggers)
{
	struct buffer_head *bh = jh2bh(jh);

	if (!triggers || !triggers->t_commit)
	if (!triggers || !triggers->t_frozen)
		return;

	triggers->t_commit(triggers, bh, mapped_data, bh->b_size);
	triggers->t_frozen(triggers, bh, mapped_data, bh->b_size);
}

void jbd2_buffer_abort_trigger(struct journal_head *jh,
+46 −48
Original line number Diff line number Diff line
@@ -196,14 +196,13 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock,
			dump_stack();
			goto bail;
		}
	}

	past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
	mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino,
	     (unsigned long long)past_eof);

	if (create && (iblock >= past_eof))
		set_buffer_new(bh_result);
	}

bail:
	if (err < 0)
@@ -459,36 +458,6 @@ int walk_page_buffers( handle_t *handle,
	return ret;
}

handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
							 struct page *page,
							 unsigned from,
							 unsigned to)
{
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	handle_t *handle;
	int ret = 0;

	handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
	if (IS_ERR(handle)) {
		ret = -ENOMEM;
		mlog_errno(ret);
		goto out;
	}

	if (ocfs2_should_order_data(inode)) {
		ret = ocfs2_jbd2_file_inode(handle, inode);
		if (ret < 0)
			mlog_errno(ret);
	}
out:
	if (ret) {
		if (!IS_ERR(handle))
			ocfs2_commit_trans(osb, handle);
		handle = ERR_PTR(ret);
	}
	return handle;
}

static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
{
	sector_t status;
@@ -1131,23 +1100,37 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno,
 */
static int ocfs2_grab_pages_for_write(struct address_space *mapping,
				      struct ocfs2_write_ctxt *wc,
				      u32 cpos, loff_t user_pos, int new,
				      u32 cpos, loff_t user_pos,
				      unsigned user_len, int new,
				      struct page *mmap_page)
{
	int ret = 0, i;
	unsigned long start, target_index, index;
	unsigned long start, target_index, end_index, index;
	struct inode *inode = mapping->host;
	loff_t last_byte;

	target_index = user_pos >> PAGE_CACHE_SHIFT;

	/*
	 * Figure out how many pages we'll be manipulating here. For
	 * non allocating write, we just change the one
	 * page. Otherwise, we'll need a whole clusters worth.
	 * page. Otherwise, we'll need a whole clusters worth.  If we're
	 * writing past i_size, we only need enough pages to cover the
	 * last page of the write.
	 */
	if (new) {
		wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb);
		start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos);
		/*
		 * We need the index *past* the last page we could possibly
		 * touch.  This is the page past the end of the write or
		 * i_size, whichever is greater.
		 */
		last_byte = max(user_pos + user_len, i_size_read(inode));
		BUG_ON(last_byte < 1);
		end_index = ((last_byte - 1) >> PAGE_CACHE_SHIFT) + 1;
		if ((start + wc->w_num_pages) > end_index)
			wc->w_num_pages = end_index - start;
	} else {
		wc->w_num_pages = 1;
		start = target_index;
@@ -1620,21 +1603,20 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping,
 * write path can treat it as an non-allocating write, which has no
 * special case code for sparse/nonsparse files.
 */
static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos,
					unsigned len,
static int ocfs2_expand_nonsparse_inode(struct inode *inode,
					struct buffer_head *di_bh,
					loff_t pos, unsigned len,
					struct ocfs2_write_ctxt *wc)
{
	int ret;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
	loff_t newsize = pos + len;

	if (ocfs2_sparse_alloc(osb))
		return 0;
	BUG_ON(ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)));

	if (newsize <= i_size_read(inode))
		return 0;

	ret = ocfs2_extend_no_holes(inode, newsize, pos);
	ret = ocfs2_extend_no_holes(inode, di_bh, newsize, pos);
	if (ret)
		mlog_errno(ret);

@@ -1644,6 +1626,18 @@ static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos,
	return ret;
}

static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh,
			   loff_t pos)
{
	int ret = 0;

	BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)));
	if (pos > i_size_read(inode))
		ret = ocfs2_zero_extend(inode, di_bh, pos);

	return ret;
}

int ocfs2_write_begin_nolock(struct address_space *mapping,
			     loff_t pos, unsigned len, unsigned flags,
			     struct page **pagep, void **fsdata,
@@ -1679,7 +1673,11 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
		}
	}

	ret = ocfs2_expand_nonsparse_inode(inode, pos, len, wc);
	if (ocfs2_sparse_alloc(osb))
		ret = ocfs2_zero_tail(inode, di_bh, pos);
	else
		ret = ocfs2_expand_nonsparse_inode(inode, di_bh, pos, len,
						   wc);
	if (ret) {
		mlog_errno(ret);
		goto out;
@@ -1789,7 +1787,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
	 * that we can zero and flush if we error after adding the
	 * extent.
	 */
	ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos,
	ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
					 cluster_of_pages, mmap_page);
	if (ret) {
		mlog_errno(ret);
+2 −1
Original line number Diff line number Diff line
@@ -1671,7 +1671,7 @@ struct dlm_ctxt * dlm_register_domain(const char *domain,
	struct dlm_ctxt *dlm = NULL;
	struct dlm_ctxt *new_ctxt = NULL;

	if (strlen(domain) > O2NM_MAX_NAME_LEN) {
	if (strlen(domain) >= O2NM_MAX_NAME_LEN) {
		ret = -ENAMETOOLONG;
		mlog(ML_ERROR, "domain name length too long\n");
		goto leave;
@@ -1709,6 +1709,7 @@ struct dlm_ctxt * dlm_register_domain(const char *domain,
		}

		if (dlm_protocol_compare(&dlm->fs_locking_proto, fs_proto)) {
			spin_unlock(&dlm_domain_lock);
			mlog(ML_ERROR,
			     "Requested locking protocol version is not "
			     "compatible with already registered domain "
+14 −8
Original line number Diff line number Diff line
@@ -2808,14 +2808,8 @@ static int dlm_mark_lockres_migrating(struct dlm_ctxt *dlm,
		mlog(0, "trying again...\n");
		goto again;
	}
	/* now that we are sure the MIGRATING state is there, drop
	 * the unneded state which blocked threads trying to DIRTY */
	spin_lock(&res->spinlock);
	BUG_ON(!(res->state & DLM_LOCK_RES_BLOCK_DIRTY));
	BUG_ON(!(res->state & DLM_LOCK_RES_MIGRATING));
	res->state &= ~DLM_LOCK_RES_BLOCK_DIRTY;
	spin_unlock(&res->spinlock);

	ret = 0;
	/* did the target go down or die? */
	spin_lock(&dlm->spinlock);
	if (!test_bit(target, dlm->domain_map)) {
@@ -2825,10 +2819,22 @@ static int dlm_mark_lockres_migrating(struct dlm_ctxt *dlm,
	}
	spin_unlock(&dlm->spinlock);

	/*
	 * if target is down, we need to clear DLM_LOCK_RES_BLOCK_DIRTY for
	 * another try; otherwise, we are sure the MIGRATING state is there,
	 * drop the unneded state which blocked threads trying to DIRTY
	 */
	spin_lock(&res->spinlock);
	BUG_ON(!(res->state & DLM_LOCK_RES_BLOCK_DIRTY));
	res->state &= ~DLM_LOCK_RES_BLOCK_DIRTY;
	if (!ret)
		BUG_ON(!(res->state & DLM_LOCK_RES_MIGRATING));
	spin_unlock(&res->spinlock);

	/*
	 * at this point:
	 *
	 *   o the DLM_LOCK_RES_MIGRATING flag is set
	 *   o the DLM_LOCK_RES_MIGRATING flag is set if target not down
	 *   o there are no pending asts on this lockres
	 *   o all processes trying to reserve an ast on this
	 *     lockres must wait for the MIGRATING flag to clear
Loading