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

Commit 6c337ad6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull GFS2 updates from Steven Whitehouse:
 "This is possibly the smallest ever set of GFS2 patches for a merge
  window.  Also, most of them are bug fixes this time.

  Two of my three patches (moving gfs2_sync_meta and merging the two
  writepage implementations) are clean ups with the third (taking the
  glock ref in examine_bucket) being a fix for a difficult to hit race
  condition.

  The removal of an unused memory barrier is a clean up from Bob
  Peterson, and the "spectator" relates to a rarely used mount option.
  Ben Marzinski's patch fixes a corner case where the incorrect inode
  flags were being set, resulting in incorrect behaviour on fsync"

* tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw:
  GFS2: dirty inode correctly in gfs2_write_end
  GFS2: Don't flag consistency error if first mounter is a spectator
  GFS2: Remove unnecessary memory barrier
  GFS2: Merge ordered and writeback writepage
  GFS2: Take glock reference in examine_bucket()
  GFS2: Move gfs2_sync_meta to lops.c
parents 6cccc7d3 0c901809
Loading
Loading
Loading
Loading
+11 −33
Original line number Diff line number Diff line
@@ -122,14 +122,13 @@ static int gfs2_writepage_common(struct page *page,
}

/**
 * gfs2_writeback_writepage - Write page for writeback mappings
 * gfs2_writepage - Write page for writeback mappings
 * @page: The page
 * @wbc: The writeback control
 *
 */

static int gfs2_writeback_writepage(struct page *page,
				    struct writeback_control *wbc)
static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
{
	int ret;

@@ -140,32 +139,6 @@ static int gfs2_writeback_writepage(struct page *page,
	return nobh_writepage(page, gfs2_get_block_noalloc, wbc);
}

/**
 * gfs2_ordered_writepage - Write page for ordered data files
 * @page: The page to write
 * @wbc: The writeback control
 *
 */

static int gfs2_ordered_writepage(struct page *page,
				  struct writeback_control *wbc)
{
	struct inode *inode = page->mapping->host;
	struct gfs2_inode *ip = GFS2_I(inode);
	int ret;

	ret = gfs2_writepage_common(page, wbc);
	if (ret <= 0)
		return ret;

	if (!page_has_buffers(page)) {
		create_empty_buffers(page, inode->i_sb->s_blocksize,
				     (1 << BH_Dirty)|(1 << BH_Uptodate));
	}
	gfs2_page_add_databufs(ip, page, 0, inode->i_sb->s_blocksize-1);
	return block_write_full_page(page, gfs2_get_block_noalloc, wbc);
}

/**
 * __gfs2_jdata_writepage - The core of jdata writepage
 * @page: The page to write
@@ -842,6 +815,8 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
	unsigned int from = pos & (PAGE_CACHE_SIZE - 1);
	unsigned int to = from + len;
	int ret;
	struct gfs2_trans *tr = current->journal_info;
	BUG_ON(!tr);

	BUG_ON(gfs2_glock_is_locked_by_me(ip->i_gl) == NULL);

@@ -852,8 +827,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
		goto failed;
	}

	gfs2_trans_add_meta(ip->i_gl, dibh);

	if (gfs2_is_stuffed(ip))
		return gfs2_stuffed_write_end(inode, dibh, pos, len, copied, page);

@@ -861,6 +834,11 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
		gfs2_page_add_databufs(ip, page, from, to);

	ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
	if (tr->tr_num_buf_new)
		__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
	else
		gfs2_trans_add_meta(ip->i_gl, dibh);


	if (inode == sdp->sd_rindex) {
		adjust_fs_space(inode);
@@ -1107,7 +1085,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
}

static const struct address_space_operations gfs2_writeback_aops = {
	.writepage = gfs2_writeback_writepage,
	.writepage = gfs2_writepage,
	.writepages = gfs2_writepages,
	.readpage = gfs2_readpage,
	.readpages = gfs2_readpages,
@@ -1123,7 +1101,7 @@ static const struct address_space_operations gfs2_writeback_aops = {
};

static const struct address_space_operations gfs2_ordered_aops = {
	.writepage = gfs2_ordered_writepage,
	.writepage = gfs2_writepage,
	.writepages = gfs2_writepages,
	.readpage = gfs2_readpage,
	.readpages = gfs2_readpages,
+3 −1
Original line number Diff line number Diff line
@@ -650,7 +650,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
{
	struct address_space *mapping = file->f_mapping;
	struct inode *inode = mapping->host;
	int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC);
	int sync_state = inode->i_state & I_DIRTY;
	struct gfs2_inode *ip = GFS2_I(inode);
	int ret = 0, ret1 = 0;

@@ -660,6 +660,8 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
			return ret1;
	}

	if (!gfs2_is_jdata(ip))
		sync_state &= ~I_DIRTY_PAGES;
	if (datasync)
		sync_state &= ~I_DIRTY_SYNC;

+5 −8
Original line number Diff line number Diff line
@@ -1411,7 +1411,6 @@ __acquires(&lru_lock)
		if (demote_ok(gl))
			handle_callback(gl, LM_ST_UNLOCKED, 0, false);
		WARN_ON(!test_and_clear_bit(GLF_LOCK, &gl->gl_flags));
		smp_mb__after_clear_bit();
		if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
			gfs2_glock_put_nolock(gl);
		spin_unlock(&gl->gl_spin);
@@ -1488,7 +1487,7 @@ static void examine_bucket(glock_examiner examiner, const struct gfs2_sbd *sdp,

	rcu_read_lock();
	hlist_bl_for_each_entry_rcu(gl, pos, head, gl_list) {
		if ((gl->gl_sbd == sdp) && atomic_read(&gl->gl_ref))
		if ((gl->gl_sbd == sdp) && atomic_inc_not_zero(&gl->gl_ref))
			examiner(gl);
	}
	rcu_read_unlock();
@@ -1508,19 +1507,18 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
 * thaw_glock - thaw out a glock which has an unprocessed reply waiting
 * @gl: The glock to thaw
 *
 * N.B. When we freeze a glock, we leave a ref to the glock outstanding,
 * so this has to result in the ref count being dropped by one.
 */

static void thaw_glock(struct gfs2_glock *gl)
{
	if (!test_and_clear_bit(GLF_FROZEN, &gl->gl_flags))
		return;
		goto out;
	set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
	gfs2_glock_hold(gl);
	if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
	if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) {
out:
		gfs2_glock_put(gl);
	}
}

/**
 * clear_glock - look at a glock and see if we can free it from glock cache
@@ -1536,7 +1534,6 @@ static void clear_glock(struct gfs2_glock *gl)
	if (gl->gl_state != LM_ST_UNLOCKED)
		handle_callback(gl, LM_ST_UNLOCKED, 0, false);
	spin_unlock(&gl->gl_spin);
	gfs2_glock_hold(gl);
	if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
		gfs2_glock_put(gl);
}
+18 −0
Original line number Diff line number Diff line
@@ -579,6 +579,24 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
	return error;
}

/**
 * gfs2_meta_sync - Sync all buffers associated with a glock
 * @gl: The glock
 *
 */

static void gfs2_meta_sync(struct gfs2_glock *gl)
{
	struct address_space *mapping = gfs2_glock2aspace(gl);
	int error;

	filemap_fdatawrite(mapping);
	error = filemap_fdatawait(mapping);

	if (error)
		gfs2_io_error(gl->gl_sbd);
}

static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
{
	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
+0 −18
Original line number Diff line number Diff line
@@ -97,24 +97,6 @@ const struct address_space_operations gfs2_meta_aops = {
	.releasepage = gfs2_releasepage,
};

/**
 * gfs2_meta_sync - Sync all buffers associated with a glock
 * @gl: The glock
 *
 */

void gfs2_meta_sync(struct gfs2_glock *gl)
{
	struct address_space *mapping = gfs2_glock2aspace(gl);
	int error;

	filemap_fdatawrite(mapping);
	error = filemap_fdatawait(mapping);

	if (error)
		gfs2_io_error(gl->gl_sbd);
}

/**
 * gfs2_getbuf - Get a buffer with a given address space
 * @gl: the glock
Loading