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

Commit acdc53b2 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Replace __nfs_write_mapping with sync_inode()



Now that we have correct COMMIT semantics in writeback_single_inode, we can
reduce and simplify nfs_wb_all(). Also replace nfs_wb_nocommit() with a
call to filemap_write_and_wait(), which doesn't need to hold the
inode->i_mutex.

With that done, we can eliminate nfs_write_mapping() altogether.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent c988950e
Loading
Loading
Loading
Loading
+5 −10
Original line number Original line Diff line number Diff line
@@ -495,17 +495,11 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
	int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
	int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
	int err;
	int err;


	/*
	/* Flush out writes to the server in order to update c/mtime.  */
	 * Flush out writes to the server in order to update c/mtime.
	 *
	 * Hold the i_mutex to suspend application writes temporarily;
	 * this prevents long-running writing applications from blocking
	 * nfs_wb_nocommit.
	 */
	if (S_ISREG(inode->i_mode)) {
	if (S_ISREG(inode->i_mode)) {
		mutex_lock(&inode->i_mutex);
		err = filemap_write_and_wait(inode->i_mapping);
		nfs_wb_nocommit(inode);
		if (err)
		mutex_unlock(&inode->i_mutex);
			goto out;
	}
	}


	/*
	/*
@@ -529,6 +523,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
		generic_fillattr(inode, stat);
		generic_fillattr(inode, stat);
		stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
		stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
	}
	}
out:
	return err;
	return err;
}
}


+5 −37
Original line number Original line Diff line number Diff line
@@ -1454,7 +1454,6 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr
	pgoff_t idx_start, idx_end;
	pgoff_t idx_start, idx_end;
	unsigned int npages = 0;
	unsigned int npages = 0;
	LIST_HEAD(head);
	LIST_HEAD(head);
	int nocommit = how & FLUSH_NOCOMMIT;
	long pages, ret;
	long pages, ret;


	/* FIXME */
	/* FIXME */
@@ -1471,14 +1470,11 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr
				npages = 0;
				npages = 0;
		}
		}
	}
	}
	how &= ~FLUSH_NOCOMMIT;
	spin_lock(&inode->i_lock);
	spin_lock(&inode->i_lock);
	do {
	do {
		ret = nfs_wait_on_requests_locked(inode, idx_start, npages);
		ret = nfs_wait_on_requests_locked(inode, idx_start, npages);
		if (ret != 0)
		if (ret != 0)
			continue;
			continue;
		if (nocommit)
			break;
		pages = nfs_scan_commit(inode, &head, idx_start, npages);
		pages = nfs_scan_commit(inode, &head, idx_start, npages);
		if (pages == 0)
		if (pages == 0)
			break;
			break;
@@ -1492,47 +1488,19 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr
	return ret;
	return ret;
}
}


static int __nfs_write_mapping(struct address_space *mapping, struct writeback_control *wbc, int how)
/*
{
 * flush the inode to disk.
	int ret;
 */

int nfs_wb_all(struct inode *inode)
	ret = nfs_writepages(mapping, wbc);
	if (ret < 0)
		goto out;
	ret = nfs_sync_mapping_wait(mapping, wbc, how);
	if (ret < 0)
		goto out;
	return 0;
out:
	__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
	return ret;
}

/* Two pass sync: first using WB_SYNC_NONE, then WB_SYNC_ALL */
static int nfs_write_mapping(struct address_space *mapping, int how)
{
{
	struct writeback_control wbc = {
	struct writeback_control wbc = {
		.bdi = mapping->backing_dev_info,
		.sync_mode = WB_SYNC_ALL,
		.sync_mode = WB_SYNC_ALL,
		.nr_to_write = LONG_MAX,
		.nr_to_write = LONG_MAX,
		.range_start = 0,
		.range_start = 0,
		.range_end = LLONG_MAX,
		.range_end = LLONG_MAX,
	};
	};


	return __nfs_write_mapping(mapping, &wbc, how);
	return sync_inode(inode, &wbc);
}

/*
 * flush the inode to disk.
 */
int nfs_wb_all(struct inode *inode)
{
	return nfs_write_mapping(inode->i_mapping, 0);
}

int nfs_wb_nocommit(struct inode *inode)
{
	return nfs_write_mapping(inode->i_mapping, FLUSH_NOCOMMIT);
}
}


int nfs_wb_page_cancel(struct inode *inode, struct page *page)
int nfs_wb_page_cancel(struct inode *inode, struct page *page)
+0 −2
Original line number Original line Diff line number Diff line
@@ -33,7 +33,6 @@
#define FLUSH_STABLE		4	/* commit to stable storage */
#define FLUSH_STABLE		4	/* commit to stable storage */
#define FLUSH_LOWPRI		8	/* low priority background flush */
#define FLUSH_LOWPRI		8	/* low priority background flush */
#define FLUSH_HIGHPRI		16	/* high priority memory reclaim flush */
#define FLUSH_HIGHPRI		16	/* high priority memory reclaim flush */
#define FLUSH_NOCOMMIT		32	/* Don't send the NFSv3/v4 COMMIT */


#ifdef __KERNEL__
#ifdef __KERNEL__


@@ -478,7 +477,6 @@ extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
 */
 */
extern long nfs_sync_mapping_wait(struct address_space *, struct writeback_control *, int);
extern long nfs_sync_mapping_wait(struct address_space *, struct writeback_control *, int);
extern int nfs_wb_all(struct inode *inode);
extern int nfs_wb_all(struct inode *inode);
extern int nfs_wb_nocommit(struct inode *inode);
extern int nfs_wb_page(struct inode *inode, struct page* page);
extern int nfs_wb_page(struct inode *inode, struct page* page);
extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)