Commit e1181ee6 authored by Jeff Layton's avatar Jeff Layton Committed by Al Viro

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: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent cccb5a1e
...@@ -1950,8 +1950,9 @@ int may_open(struct path *path, int acc_mode, int flag) ...@@ -1950,8 +1950,9 @@ int may_open(struct path *path, int acc_mode, int flag)
return break_lease(inode, flag); return break_lease(inode, flag);
} }
static int handle_truncate(struct path *path) static int handle_truncate(struct file *filp)
{ {
struct path *path = &filp->f_path;
struct inode *inode = path->dentry->d_inode; struct inode *inode = path->dentry->d_inode;
int error = get_write_access(inode); int error = get_write_access(inode);
if (error) if (error)
...@@ -1965,7 +1966,7 @@ static int handle_truncate(struct path *path) ...@@ -1965,7 +1966,7 @@ static int handle_truncate(struct path *path)
if (!error) { if (!error) {
error = do_truncate(path->dentry, 0, error = do_truncate(path->dentry, 0,
ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
NULL); filp);
} }
put_write_access(inode); put_write_access(inode);
return error; return error;
...@@ -2063,7 +2064,7 @@ static struct file *finish_open(struct nameidata *nd, ...@@ -2063,7 +2064,7 @@ static struct file *finish_open(struct nameidata *nd,
} }
if (!IS_ERR(filp)) { if (!IS_ERR(filp)) {
if (will_truncate) { if (will_truncate) {
error = handle_truncate(&nd->path); error = handle_truncate(filp);
if (error) { if (error) {
fput(filp); fput(filp);
filp = ERR_PTR(error); filp = ERR_PTR(error);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment