diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-03-04 19:48:16 +0100 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-03-05 17:55:25 +0100 |
commit | 0418dae1056d6091e9527b7158a3763f7aa92353 (patch) | |
tree | 5837e26fff816e8a444e53117a401367b1559187 | |
parent | NFSv4.1 Fail data server I/O if stateid represents a lost lock (diff) | |
download | linux-0418dae1056d6091e9527b7158a3763f7aa92353.tar.xz linux-0418dae1056d6091e9527b7158a3763f7aa92353.zip |
NFSv4: Fail the truncate() if the lock/open stateid is invalid
If the open stateid could not be recovered, or the file locks were lost,
then we should fail the truncate() operation altogether.
Reported-by: Andy Adamson <andros@netapp.com>
Link: http://lkml.kernel.org/r/1393954269-3974-1-git-send-email-andros@netapp.com
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r-- | fs/nfs/nfs4proc.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4ae8141452c9..450bfedbe2f4 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2398,13 +2398,16 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, if (nfs4_copy_delegation_stateid(&arg.stateid, inode, fmode)) { /* Use that stateid */ - } else if (truncate && state != NULL && nfs4_valid_open_stateid(state)) { + } else if (truncate && state != NULL) { struct nfs_lockowner lockowner = { .l_owner = current->files, .l_pid = current->tgid, }; - nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE, - &lockowner); + if (!nfs4_valid_open_stateid(state)) + return -EBADF; + if (nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE, + &lockowner) == -EIO) + return -EBADF; } else nfs4_stateid_copy(&arg.stateid, &zero_stateid); |