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

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

NFSv4: nfs_client_return_marked_delegations can't flush data



Since even filemap_flush() needs to lock pages that are dirty, we
cannot risk calling it from the state manager context. Therefore,
we need to move the call to filemap_flush() to
nfs_async_inode_return_delegation().

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent c57d1bc5
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -316,6 +316,10 @@ static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegat
 * nfs_client_return_marked_delegations - return previously marked delegations
 * @clp: nfs_client to process
 *
 * Note that this function is designed to be called by the state
 * manager thread. For this reason, it cannot flush the dirty data,
 * since that could deadlock in case of a state recovery error.
 *
 * Returns zero on success, or a negative errno value.
 */
int nfs_client_return_marked_delegations(struct nfs_client *clp)
@@ -340,11 +344,9 @@ int nfs_client_return_marked_delegations(struct nfs_client *clp)
								server);
			rcu_read_unlock();

			if (delegation != NULL) {
				filemap_flush(inode->i_mapping);
			if (delegation != NULL)
				err = __nfs_inode_return_delegation(inode,
								delegation, 0);
			}
			iput(inode);
			if (!err)
				goto restart;
@@ -542,6 +544,8 @@ int nfs_async_inode_return_delegation(struct inode *inode,
	struct nfs_client *clp = server->nfs_client;
	struct nfs_delegation *delegation;

	filemap_flush(inode->i_mapping);

	rcu_read_lock();
	delegation = rcu_dereference(NFS_I(inode)->delegation);