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

Commit 27fb8d7b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
  nfs: fix memory leak in nfs_get_sb with CONFIG_NFS_V4
  nfs: fix some issues in nfs41_proc_reclaim_complete()
  NFS: Ensure that nfs_wb_page() waits for Pg_writeback to clear
  NFS: Fix an unstable write data integrity race
  nfs: testing for null instead of ERR_PTR()
  NFS: rsize and wsize settings ignored on v4 mounts
  NFSv4: Don't attempt an atomic open if the file is a mountpoint
  SUNRPC: Fix a bug in rpcauth_prune_expired
parents f80a0ca6 9699eda6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -966,6 +966,8 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
{
	target->flags = source->flags;
	target->rsize = source->rsize;
	target->wsize = source->wsize;
	target->acregmin = source->acregmin;
	target->acregmax = source->acregmax;
	target->acdirmin = source->acdirmin;
+1 −1
Original line number Diff line number Diff line
@@ -1052,7 +1052,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
	struct inode *dir;
	int openflags, ret = 0;

	if (!is_atomic_open(nd))
	if (!is_atomic_open(nd) || d_mountpoint(dentry))
		goto no_open;
	parent = dget_parent(dentry);
	dir = parent->d_inode;
+4 −1
Original line number Diff line number Diff line
@@ -5218,9 +5218,12 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
	msg.rpc_resp = &calldata->res;
	task_setup_data.callback_data = calldata;
	task = rpc_run_task(&task_setup_data);
	if (IS_ERR(task))
	if (IS_ERR(task)) {
		status = PTR_ERR(task);
		goto out;
	}
	rpc_put_task(task);
	return 0;
out:
	dprintk("<-- %s status=%d\n", __func__, status);
	return status;
+2 −1
Original line number Diff line number Diff line
@@ -2187,6 +2187,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
	if (data->version == 4) {
		error = nfs4_try_mount(flags, dev_name, data, mnt);
		kfree(data->client_address);
		kfree(data->nfs_server.export_path);
		goto out;
	}
#endif	/* CONFIG_NFS_V4 */
@@ -2657,7 +2658,7 @@ static void nfs_fix_devname(const struct path *path, struct vfsmount *mnt)
	devname = nfs_path(path->mnt->mnt_devname,
			path->mnt->mnt_root, path->dentry,
			page, PAGE_SIZE);
	if (devname == NULL)
	if (IS_ERR(devname))
		goto out_freepage;
	tmp = kstrdup(devname, GFP_KERNEL);
	if (tmp == NULL)
+36 −19
Original line number Diff line number Diff line
@@ -1201,6 +1201,25 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)


#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
{
	if (!test_and_set_bit(NFS_INO_COMMIT, &nfsi->flags))
		return 1;
	if (may_wait && !out_of_line_wait_on_bit_lock(&nfsi->flags,
				NFS_INO_COMMIT, nfs_wait_bit_killable,
				TASK_KILLABLE))
		return 1;
	return 0;
}

static void nfs_commit_clear_lock(struct nfs_inode *nfsi)
{
	clear_bit(NFS_INO_COMMIT, &nfsi->flags);
	smp_mb__after_clear_bit();
	wake_up_bit(&nfsi->flags, NFS_INO_COMMIT);
}


static void nfs_commitdata_release(void *data)
{
	struct nfs_write_data *wdata = data;
@@ -1262,8 +1281,6 @@ static int nfs_commit_rpcsetup(struct list_head *head,
	task = rpc_run_task(&task_setup_data);
	if (IS_ERR(task))
		return PTR_ERR(task);
	if (how & FLUSH_SYNC)
		rpc_wait_for_completion_task(task);
	rpc_put_task(task);
	return 0;
}
@@ -1294,6 +1311,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
				BDI_RECLAIMABLE);
		nfs_clear_page_tag_locked(req);
	}
	nfs_commit_clear_lock(NFS_I(inode));
	return -ENOMEM;
}

@@ -1349,6 +1367,7 @@ static void nfs_commit_release(void *calldata)
	next:
		nfs_clear_page_tag_locked(req);
	}
	nfs_commit_clear_lock(NFS_I(data->inode));
	nfs_commitdata_release(calldata);
}

@@ -1363,8 +1382,11 @@ static const struct rpc_call_ops nfs_commit_ops = {
static int nfs_commit_inode(struct inode *inode, int how)
{
	LIST_HEAD(head);
	int res;
	int may_wait = how & FLUSH_SYNC;
	int res = 0;

	if (!nfs_commit_set_lock(NFS_I(inode), may_wait))
		goto out;
	spin_lock(&inode->i_lock);
	res = nfs_scan_commit(inode, &head, 0, 0);
	spin_unlock(&inode->i_lock);
@@ -1372,7 +1394,13 @@ static int nfs_commit_inode(struct inode *inode, int how)
		int error = nfs_commit_list(inode, &head, how);
		if (error < 0)
			return error;
	}
		if (may_wait)
			wait_on_bit(&NFS_I(inode)->flags, NFS_INO_COMMIT,
					nfs_wait_bit_killable,
					TASK_KILLABLE);
	} else
		nfs_commit_clear_lock(NFS_I(inode));
out:
	return res;
}

@@ -1444,6 +1472,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)

	BUG_ON(!PageLocked(page));
	for (;;) {
		wait_on_page_writeback(page);
		req = nfs_page_find_request(page);
		if (req == NULL)
			break;
@@ -1478,31 +1507,19 @@ int nfs_wb_page(struct inode *inode, struct page *page)
		.range_start = range_start,
		.range_end = range_end,
	};
	struct nfs_page *req;
	int need_commit;
	int ret;

	while(PagePrivate(page)) {
		wait_on_page_writeback(page);
		if (clear_page_dirty_for_io(page)) {
			ret = nfs_writepage_locked(page, &wbc);
			if (ret < 0)
				goto out_error;
		}
		req = nfs_find_and_lock_request(page);
		if (!req)
			break;
		if (IS_ERR(req)) {
			ret = PTR_ERR(req);
			goto out_error;
		}
		need_commit = test_bit(PG_CLEAN, &req->wb_flags);
		nfs_clear_page_tag_locked(req);
		if (need_commit) {
			ret = nfs_commit_inode(inode, FLUSH_SYNC);
		ret = sync_inode(inode, &wbc);
		if (ret < 0)
			goto out_error;
	}
	}
	return 0;
out_error:
	return ret;
Loading