diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-09-05 19:06:58 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-09-07 12:36:17 -0400 |
commit | 5445b1fbd123420bffed5e629a420aa2a16bf849 (patch) | |
tree | daea751ed98d60c445017472d6f2545452e0224a /fs/nfs/delegation.c | |
parent | 7d160a6c462c2c690e074c173b43aad7204049ad (diff) | |
download | linux-5445b1fbd123420bffed5e629a420aa2a16bf849.tar.bz2 |
NFSv4: Respect the server imposed limit on how many changes we may cache
The NFSv4 delegation spec allows the server to tell a client to limit how
much data it cache after the file is closed. In return, the server
guarantees enough free space to avoid ENOSPC situations, etc.
Prior to this patch, we assumed we could always cache aggressively after
close. Unfortunately, this causes problems with servers that set the
limit to 0 and therefore do not offer any ENOSPC guarantees.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r-- | fs/nfs/delegation.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index cd503cc2251c..2714ef835bdd 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -900,3 +900,28 @@ bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, rcu_read_unlock(); return ret; } + +/** + * nfs4_delegation_flush_on_close - Check if we must flush file on close + * @inode: inode to check + * + * This function checks the number of outstanding writes to the file + * against the delegation 'space_limit' field to see if + * the spec requires us to flush the file on close. + */ +bool nfs4_delegation_flush_on_close(const struct inode *inode) +{ + struct nfs_inode *nfsi = NFS_I(inode); + struct nfs_delegation *delegation; + bool ret = true; + + rcu_read_lock(); + delegation = rcu_dereference(nfsi->delegation); + if (delegation == NULL || !(delegation->type & FMODE_WRITE)) + goto out; + if (nfsi->nrequests < delegation->pagemod_limit) + ret = false; +out: + rcu_read_unlock(); + return ret; +} |