[kernel/f17] NFS Bugfixes from upstream
Justin M. Forbes
jforbes at fedoraproject.org
Tue May 1 21:41:27 UTC 2012
commit aeab6348945086cd875e3a9d66d4c1c7209e1b75
Author: Justin M. Forbes <jforbes at redhat.com>
Date: Tue May 1 16:42:21 2012 -0500
NFS Bugfixes from upstream
...way-unnecessary-setattrs-for-open-O_TRUNC.patch | 153 ++++++++++++++++++++
...-open-context-on-error-in-nfs_flush_multi.patch | 29 ++++
...open-context-on-error-in-nfs_pagein_multi.patch | 29 ++++
...-exclusive-shared-type-against-open-modes.patch | 43 ++++++
...e-that-the-LOCK-code-sets-exception-inode.patch | 52 +++++++
...open-O_TRUNC-and-ftruncate-error-handling.patch | 69 +++++++++
kernel.spec | 22 +++
...ost-name-in-brackets-in-nfs_do_root_mount.patch | 47 ++++++
8 files changed, 444 insertions(+), 0 deletions(-)
---
diff --git a/NFS-optimise-away-unnecessary-setattrs-for-open-O_TRUNC.patch b/NFS-optimise-away-unnecessary-setattrs-for-open-O_TRUNC.patch
new file mode 100644
index 0000000..89b6308
--- /dev/null
+++ b/NFS-optimise-away-unnecessary-setattrs-for-open-O_TRUNC.patch
@@ -0,0 +1,153 @@
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+
+Currently, we will correctly optimise away a truncate that doesn't
+change the file size. However, in the case of open(O_TRUNC), we
+also want to optimise away the time changes.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+---
+ fs/nfs/dir.c | 25 +++++++++++++++++++------
+ fs/nfs/inode.c | 4 ++--
+ fs/nfs/nfs4proc.c | 10 +++++++---
+ 3 files changed, 28 insertions(+), 11 deletions(-)
+
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index fd9a872..bb132a8 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -1429,6 +1429,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
+ }
+
+ open_flags = nd->intent.open.flags;
++ attr.ia_valid = 0;
+
+ ctx = create_nfs_open_context(dentry, open_flags);
+ res = ERR_CAST(ctx);
+@@ -1437,11 +1438,14 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
+
+ if (nd->flags & LOOKUP_CREATE) {
+ attr.ia_mode = nd->intent.open.create_mode;
+- attr.ia_valid = ATTR_MODE;
++ attr.ia_valid |= ATTR_MODE;
+ attr.ia_mode &= ~current_umask();
+- } else {
++ } else
+ open_flags &= ~(O_EXCL | O_CREAT);
+- attr.ia_valid = 0;
++
++ if (open_flags & O_TRUNC) {
++ attr.ia_valid |= ATTR_SIZE;
++ attr.ia_size = 0;
+ }
+
+ /* Open the file on the server */
+@@ -1495,6 +1499,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
+ struct inode *inode;
+ struct inode *dir;
+ struct nfs_open_context *ctx;
++ struct iattr attr;
+ int openflags, ret = 0;
+
+ if (nd->flags & LOOKUP_RCU)
+@@ -1523,19 +1528,27 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
+ /* We cannot do exclusive creation on a positive dentry */
+ if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
+ goto no_open_dput;
+- /* We can't create new files, or truncate existing ones here */
+- openflags &= ~(O_CREAT|O_EXCL|O_TRUNC);
++ /* We can't create new files here */
++ openflags &= ~(O_CREAT|O_EXCL);
+
+ ctx = create_nfs_open_context(dentry, openflags);
+ ret = PTR_ERR(ctx);
+ if (IS_ERR(ctx))
+ goto out;
++
++ attr.ia_valid = 0;
++ if (openflags & O_TRUNC) {
++ attr.ia_valid |= ATTR_SIZE;
++ attr.ia_size = 0;
++ nfs_wb_all(inode);
++ }
++
+ /*
+ * Note: we're not holding inode->i_mutex and so may be racing with
+ * operations that change the directory. We therefore save the
+ * change attribute *before* we do the RPC call.
+ */
+- inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, NULL);
++ inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr);
+ if (IS_ERR(inode)) {
+ ret = PTR_ERR(inode);
+ switch (ret) {
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index f649fba..57d0abb 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -401,7 +401,7 @@ out_no_inode:
+ goto out;
+ }
+
+-#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE)
++#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN)
+
+ int
+ nfs_setattr(struct dentry *dentry, struct iattr *attr)
+@@ -423,7 +423,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
+
+ /* Optimization: if the end result is no change, don't RPC */
+ attr->ia_valid &= NFS_VALID_ATTRS;
+- if ((attr->ia_valid & ~ATTR_FILE) == 0)
++ if ((attr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0)
+ return 0;
+
+ /* Write all dirty data */
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 1515e45..c4c6b48 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -833,7 +833,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
+ p->o_arg.bitmask = server->attr_bitmask;
+ p->o_arg.dir_bitmask = server->cache_consistency_bitmask;
+ p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
+- if (flags & O_CREAT) {
++ if (attrs != NULL && attrs->ia_valid != 0) {
+ u32 *s;
+
+ p->o_arg.u.attrs = &p->attrs;
+@@ -890,7 +890,7 @@ static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode
+ {
+ int ret = 0;
+
+- if (open_mode & O_EXCL)
++ if (open_mode & (O_EXCL|O_TRUNC))
+ goto out;
+ switch (mode & (FMODE_READ|FMODE_WRITE)) {
+ case FMODE_READ:
+@@ -1038,7 +1038,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
+ struct nfs4_state *state = opendata->state;
+ struct nfs_inode *nfsi = NFS_I(state->inode);
+ struct nfs_delegation *delegation;
+- int open_mode = opendata->o_arg.open_flags & O_EXCL;
++ int open_mode = opendata->o_arg.open_flags & (O_EXCL|O_TRUNC);
+ fmode_t fmode = opendata->o_arg.fmode;
+ nfs4_stateid stateid;
+ int ret = -EAGAIN;
+@@ -2439,6 +2439,10 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
+ }
+ }
+
++ /* Deal with open(O_TRUNC) */
++ if (sattr->ia_valid & ATTR_OPEN)
++ sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
++
+ status = nfs4_do_setattr(inode, cred, fattr, sattr, state);
+ if (status == 0)
+ nfs_setattr_update_inode(inode, sattr);
+--
+1.7.7.6
+
+_______________________________________________
+kernel mailing list
+kernel at lists.fedoraproject.org
+https://admin.fedoraproject.org/mailman/listinfo/kernel
diff --git a/NFS-put-open-context-on-error-in-nfs_flush_multi.patch b/NFS-put-open-context-on-error-in-nfs_flush_multi.patch
new file mode 100644
index 0000000..10a5ab7
--- /dev/null
+++ b/NFS-put-open-context-on-error-in-nfs_flush_multi.patch
@@ -0,0 +1,29 @@
+From: Fred Isaman <iisaman at netapp.com>
+
+Cc: <stable at vger.kernel.org>
+Signed-off-by: Fred Isaman <iisaman at netapp.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+---
+ fs/nfs/write.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index 834f0fe..8fcc23a 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -974,7 +974,7 @@ out_bad:
+ while (!list_empty(res)) {
+ data = list_entry(res->next, struct nfs_write_data, list);
+ list_del(&data->list);
+- nfs_writedata_free(data);
++ nfs_writedata_release(data);
+ }
+ nfs_redirty_request(req);
+ return -ENOMEM;
+--
+1.7.7.6
+
+_______________________________________________
+kernel mailing list
+kernel at lists.fedoraproject.org
+https://admin.fedoraproject.org/mailman/listinfo/kernel
diff --git a/NFS-put-open-context-on-error-in-nfs_pagein_multi.patch b/NFS-put-open-context-on-error-in-nfs_pagein_multi.patch
new file mode 100644
index 0000000..aa4d3e0
--- /dev/null
+++ b/NFS-put-open-context-on-error-in-nfs_pagein_multi.patch
@@ -0,0 +1,29 @@
+From: Fred Isaman <iisaman at netapp.com>
+
+Cc: <stable at vger.kernel.org>
+Signed-off-by: Fred Isaman <iisaman at netapp.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+---
+ fs/nfs/read.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/fs/nfs/read.c b/fs/nfs/read.c
+index cfa175c..41bae32 100644
+--- a/fs/nfs/read.c
++++ b/fs/nfs/read.c
+@@ -324,7 +324,7 @@ out_bad:
+ while (!list_empty(res)) {
+ data = list_entry(res->next, struct nfs_read_data, list);
+ list_del(&data->list);
+- nfs_readdata_free(data);
++ nfs_readdata_release(data);
+ }
+ nfs_readpage_release(req);
+ return -ENOMEM;
+--
+1.7.7.6
+
+_______________________________________________
+kernel mailing list
+kernel at lists.fedoraproject.org
+https://admin.fedoraproject.org/mailman/listinfo/kernel
diff --git a/NFSv4-check-lock-exclusive-shared-type-against-open-modes.patch b/NFSv4-check-lock-exclusive-shared-type-against-open-modes.patch
new file mode 100644
index 0000000..4247575
--- /dev/null
+++ b/NFSv4-check-lock-exclusive-shared-type-against-open-modes.patch
@@ -0,0 +1,43 @@
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+
+Since we may be simulating flock() locks using NFS byte range locks,
+we can't rely on the VFS having checked the file open mode for us.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+Cc: stable at vger.kernel.org
+---
+ fs/nfs/nfs4proc.c | 14 ++++++++++++++
+ 1 files changed, 14 insertions(+), 0 deletions(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index c3f1715..1515e45 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -4608,6 +4608,20 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request)
+
+ if (state == NULL)
+ return -ENOLCK;
++ /*
++ * Don't rely on the VFS having checked the file open mode,
++ * since it won't do this for flock() locks.
++ */
++ switch (request->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) {
++ case F_RDLCK:
++ if (!(filp->f_mode & FMODE_READ))
++ return -EBADF;
++ break;
++ case F_WRLCK:
++ if (!(filp->f_mode & FMODE_WRITE))
++ return -EBADF;
++ }
++
+ do {
+ status = nfs4_proc_setlk(state, cmd, request);
+ if ((status != -EAGAIN) || IS_SETLK(cmd))
+--
+1.7.7.6
+
+_______________________________________________
+kernel mailing list
+kernel at lists.fedoraproject.org
+https://admin.fedoraproject.org/mailman/listinfo/kernel
diff --git a/NFSv4-ensure-that-the-LOCK-code-sets-exception-inode.patch b/NFSv4-ensure-that-the-LOCK-code-sets-exception-inode.patch
new file mode 100644
index 0000000..8acf487
--- /dev/null
+++ b/NFSv4-ensure-that-the-LOCK-code-sets-exception-inode.patch
@@ -0,0 +1,52 @@
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+
+All callers of nfs4_handle_exception() that need to handle
+NFS4ERR_OPENMODE correctly should set exception->inode
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+Cc: stable at vger.kernel.org
+---
+ fs/nfs/nfs4proc.c | 9 +++++++--
+ 1 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index c2153e3..c3f1715 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -4460,7 +4460,9 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
+ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
+ {
+ struct nfs_server *server = NFS_SERVER(state->inode);
+- struct nfs4_exception exception = { };
++ struct nfs4_exception exception = {
++ .inode = state->inode,
++ };
+ int err;
+
+ do {
+@@ -4478,7 +4480,9 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
+ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
+ {
+ struct nfs_server *server = NFS_SERVER(state->inode);
+- struct nfs4_exception exception = { };
++ struct nfs4_exception exception = {
++ .inode = state->inode,
++ };
+ int err;
+
+ err = nfs4_set_lock_state(state, request);
+@@ -4558,6 +4562,7 @@ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *
+ {
+ struct nfs4_exception exception = {
+ .state = state,
++ .inode = state->inode,
+ };
+ int err;
+
+--
+1.7.7.6
+
+_______________________________________________
+kernel mailing list
+kernel at lists.fedoraproject.org
+https://admin.fedoraproject.org/mailman/listinfo/kernel
diff --git a/NFSv4-fix-open-O_TRUNC-and-ftruncate-error-handling.patch b/NFSv4-fix-open-O_TRUNC-and-ftruncate-error-handling.patch
new file mode 100644
index 0000000..134b210
--- /dev/null
+++ b/NFSv4-fix-open-O_TRUNC-and-ftruncate-error-handling.patch
@@ -0,0 +1,69 @@
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+
+If the file wasn't opened for writing, then truncate and ftruncate
+need to report the appropriate errors.
+
+Reported-by: Miklos Szeredi <miklos at szeredi.hu>
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+Cc: stable at vger.kernel.org
+---
+ fs/nfs/dir.c | 4 ++--
+ fs/nfs/nfs4proc.c | 15 ++++++++++++---
+ 2 files changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index bb132a8..51a2686 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -1429,7 +1429,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
+ }
+
+ open_flags = nd->intent.open.flags;
+- attr.ia_valid = 0;
++ attr.ia_valid = ATTR_OPEN;
+
+ ctx = create_nfs_open_context(dentry, open_flags);
+ res = ERR_CAST(ctx);
+@@ -1536,7 +1536,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
+ if (IS_ERR(ctx))
+ goto out;
+
+- attr.ia_valid = 0;
++ attr.ia_valid = ATTR_OPEN;
+ if (openflags & O_TRUNC) {
+ attr.ia_valid |= ATTR_SIZE;
+ attr.ia_size = 0;
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index c4c6b48..e2a2893 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -1921,10 +1921,19 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
+ };
+ int err;
+ do {
+- err = nfs4_handle_exception(server,
+- _nfs4_do_setattr(inode, cred, fattr, sattr, state),
+- &exception);
++ err = _nfs4_do_setattr(inode, cred, fattr, sattr, state);
++ switch (err) {
++ case -NFS4ERR_OPENMODE:
++ if (state && !(state->state & FMODE_WRITE)) {
++ err = -EBADF;
++ if (sattr->ia_valid & ATTR_OPEN)
++ err = -EACCES;
++ goto out;
++ }
++ }
++ err = nfs4_handle_exception(server, err, &exception);
+ } while (exception.retry);
++out:
+ return err;
+ }
+
+--
+1.7.7.6
+
+_______________________________________________
+kernel mailing list
+kernel at lists.fedoraproject.org
+https://admin.fedoraproject.org/mailman/listinfo/kernel
diff --git a/kernel.spec b/kernel.spec
index 78bdbd4..b507841 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -711,6 +711,16 @@ Patch4105: NFSv4-Reduce-the-footprint-of-the-idmapper.patch
Patch4106: NFSv4-Further-reduce-the-footprint-of-the-idmapper.patch
Patch4107: NFSv4-Minor-cleanups-for-nfs4_handle_exception-and-n.patch
+# NFS Client Patch set from Upstream
+Patch4111: NFSv4-ensure-that-the-LOCK-code-sets-exception-inode.patch
+Patch4112: NFSv4-check-lock-exclusive-shared-type-against-open-modes.patch
+Patch4113: NFS-optimise-away-unnecessary-setattrs-for-open-O_TRUNC.patch
+Patch4114: NFSv4-fix-open-O_TRUNC-and-ftruncate-error-handling.patch
+Patch4115: NFS-put-open-context-on-error-in-nfs_pagein_multi.patch
+Patch4116: NFS-put-open-context-on-error-in-nfs_flush_multi.patch
+Patch4117: nfs-enclose-host-name-in-brackets-in-nfs_do_root_mount.patch
+
+
# patches headed upstream
Patch12016: disable-i8042-check-on-apple-mac.patch
@@ -1384,6 +1394,15 @@ ApplyPatch NFSv4-Reduce-the-footprint-of-the-idmapper.patch
ApplyPatch NFSv4-Further-reduce-the-footprint-of-the-idmapper.patch
ApplyPatch NFSv4-Minor-cleanups-for-nfs4_handle_exception-and-n.patch
+# NFS Client Patch set from Upstream
+ApplyPatch NFSv4-ensure-that-the-LOCK-code-sets-exception-inode.patch
+ApplyPatch NFSv4-check-lock-exclusive-shared-type-against-open-modes.patch
+ApplyPatch NFS-optimise-away-unnecessary-setattrs-for-open-O_TRUNC.patch
+ApplyPatch NFSv4-fix-open-O_TRUNC-and-ftruncate-error-handling.patch
+ApplyPatch NFS-put-open-context-on-error-in-nfs_pagein_multi.patch
+ApplyPatch NFS-put-open-context-on-error-in-nfs_flush_multi.patch
+ApplyPatch nfs-enclose-host-name-in-brackets-in-nfs_do_root_mount.patch
+
# USB
# WMI
@@ -2419,6 +2438,9 @@ fi
# '-' | |
# '-'
%changelog
+* Tue May 01 2012 Justin M. Forbes <jforbes at redhat.com>
+- NFS Bugfixes from upstream
+
* Mon Apr 30 2012 Josh Boyer <jwboyer at redhat.com>
- Backport ipw2x00 nl80211 cipher suite reporting (rhbz 817298)
diff --git a/nfs-enclose-host-name-in-brackets-in-nfs_do_root_mount.patch b/nfs-enclose-host-name-in-brackets-in-nfs_do_root_mount.patch
new file mode 100644
index 0000000..82388be
--- /dev/null
+++ b/nfs-enclose-host-name-in-brackets-in-nfs_do_root_mount.patch
@@ -0,0 +1,47 @@
+From: Jan Kara <jack at suse.cz>
+
+When hostname contains colon (e.g. when it is an IPv6 address) it needs
+to be enclosed in brackets to make parsing of NFS device string possible.
+Fix nfs_do_root_mount() to enclose hostname properly when needed. NFS code
+actually does not need this as it does not parse the string passed by
+nfs_do_root_mount() but the device string is exposed to userspace in
+/proc/mounts.
+
+CC: Josh Boyer <jwboyer at redhat.com>
+CC: Trond Myklebust <Trond.Myklebust at netapp.com>
+Signed-off-by: Jan Kara <jack at suse.cz>
+Cc: stable at vger.kernel.org
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+---
+ fs/nfs/super.c | 8 ++++++--
+ 1 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/fs/nfs/super.c b/fs/nfs/super.c
+index 3dfa4f1..e4622ee 100644
+--- a/fs/nfs/super.c
++++ b/fs/nfs/super.c
+@@ -2707,11 +2707,15 @@ static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type,
+ char *root_devname;
+ size_t len;
+
+- len = strlen(hostname) + 3;
++ len = strlen(hostname) + 5;
+ root_devname = kmalloc(len, GFP_KERNEL);
+ if (root_devname == NULL)
+ return ERR_PTR(-ENOMEM);
+- snprintf(root_devname, len, "%s:/", hostname);
++ /* Does hostname needs to be enclosed in brackets? */
++ if (strchr(hostname, ':'))
++ snprintf(root_devname, len, "[%s]:/", hostname);
++ else
++ snprintf(root_devname, len, "%s:/", hostname);
+ root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data);
+ kfree(root_devname);
+ return root_mnt;
+--
+1.7.7.6
+
+_______________________________________________
+kernel mailing list
+kernel at lists.fedoraproject.org
+https://admin.fedoraproject.org/mailman/listinfo/kernel
More information about the scm-commits
mailing list