Commit e1181ee6575d7970bad15aaa852784b4972d2af8

Authored by Jeff Layton
Committed by Al Viro
1 parent cccb5a1e69

vfs: pass struct file to do_truncate on O_TRUNC opens (try #2)

When a file is opened with O_TRUNC, the truncate processing is handled
by handle_truncate(). This function however doesn't receive any info
about the newly instantiated filp, and therefore can't pass that info
along so that the setattr can use it.

This makes NFSv4 misbehave. The client does an open and gets a valid
stateid, and then doesn't use that stateid on the subsequent truncate.
It uses the zero-stateid instead. Most servers ignore this fact and
just do the truncate anyway, but some don't like it (notably, RHEL4).

It seems more correct that since we have a fully instantiated file at
the time that handle_truncate is called, that we pass that along so
that the truncate operation can properly use it.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 1 changed file with 4 additions and 3 deletions Side-by-side Diff

... ... @@ -1950,8 +1950,9 @@
1950 1950 return break_lease(inode, flag);
1951 1951 }
1952 1952  
1953   -static int handle_truncate(struct path *path)
  1953 +static int handle_truncate(struct file *filp)
1954 1954 {
  1955 + struct path *path = &filp->f_path;
1955 1956 struct inode *inode = path->dentry->d_inode;
1956 1957 int error = get_write_access(inode);
1957 1958 if (error)
... ... @@ -1965,7 +1966,7 @@
1965 1966 if (!error) {
1966 1967 error = do_truncate(path->dentry, 0,
1967 1968 ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
1968   - NULL);
  1969 + filp);
1969 1970 }
1970 1971 put_write_access(inode);
1971 1972 return error;
... ... @@ -2063,7 +2064,7 @@
2063 2064 }
2064 2065 if (!IS_ERR(filp)) {
2065 2066 if (will_truncate) {
2066   - error = handle_truncate(&nd->path);
  2067 + error = handle_truncate(filp);
2067 2068 if (error) {
2068 2069 fput(filp);
2069 2070 filp = ERR_PTR(error);