]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Aug 2013 20:33:41 +0000 (13:33 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Aug 2013 20:33:41 +0000 (13:33 -0700)
added patches:
jfs-fix-readdir-cookie-incompatibility-with-nfsv4.patch

queue-3.4/jfs-fix-readdir-cookie-incompatibility-with-nfsv4.patch [new file with mode: 0644]
queue-3.4/series [new file with mode: 0644]

diff --git a/queue-3.4/jfs-fix-readdir-cookie-incompatibility-with-nfsv4.patch b/queue-3.4/jfs-fix-readdir-cookie-incompatibility-with-nfsv4.patch
new file mode 100644 (file)
index 0000000..90319c7
--- /dev/null
@@ -0,0 +1,115 @@
+From 44512449c0ab368889dd13ae0031fba74ee7e1d2 Mon Sep 17 00:00:00 2001
+From: Dave Kleikamp <dave.kleikamp@oracle.com>
+Date: Thu, 15 Aug 2013 15:36:49 -0500
+Subject: jfs: fix readdir cookie incompatibility with NFSv4
+
+From: Dave Kleikamp <dave.kleikamp@oracle.com>
+
+commit 44512449c0ab368889dd13ae0031fba74ee7e1d2 upstream.
+
+NFSv4 reserves readdir cookie values 0-2 for special entries (. and ..),
+but jfs allows a value of 2 for a non-special entry. This incompatibility
+can result in the nfs client reporting a readdir loop.
+
+This patch doesn't change the value stored internally, but adds one to
+the value exposed to the iterate method.
+
+Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
+[bwh: Backported to 3.2:
+ - Adjust context
+ - s/ctx->pos/filp->f_pos/]
+Tested-by: Christian Kujau <lists@nerdbynature.de>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/jfs/jfs_dtree.c |   31 +++++++++++++++++++++++--------
+ 1 file changed, 23 insertions(+), 8 deletions(-)
+
+--- a/fs/jfs/jfs_dtree.c
++++ b/fs/jfs/jfs_dtree.c
+@@ -3047,6 +3047,14 @@ int jfs_readdir(struct file *filp, void
+               dir_index = (u32) filp->f_pos;
++              /*
++               * NFSv4 reserves cookies 1 and 2 for . and .. so we add
++               * the value we return to the vfs is one greater than the
++               * one we use internally.
++               */
++              if (dir_index)
++                      dir_index--;
++
+               if (dir_index > 1) {
+                       struct dir_table_slot dirtab_slot;
+@@ -3086,7 +3094,7 @@ int jfs_readdir(struct file *filp, void
+                       if (p->header.flag & BT_INTERNAL) {
+                               jfs_err("jfs_readdir: bad index table");
+                               DT_PUTPAGE(mp);
+-                              filp->f_pos = -1;
++                              filp->f_pos = DIREND;
+                               return 0;
+                       }
+               } else {
+@@ -3094,7 +3102,7 @@ int jfs_readdir(struct file *filp, void
+                               /*
+                                * self "."
+                                */
+-                              filp->f_pos = 0;
++                              filp->f_pos = 1;
+                               if (filldir(dirent, ".", 1, 0, ip->i_ino,
+                                           DT_DIR))
+                                       return 0;
+@@ -3102,7 +3110,7 @@ int jfs_readdir(struct file *filp, void
+                       /*
+                        * parent ".."
+                        */
+-                      filp->f_pos = 1;
++                      filp->f_pos = 2;
+                       if (filldir(dirent, "..", 2, 1, PARENT(ip), DT_DIR))
+                               return 0;
+@@ -3123,24 +3131,25 @@ int jfs_readdir(struct file *filp, void
+               /*
+                * Legacy filesystem - OS/2 & Linux JFS < 0.3.6
+                *
+-               * pn = index = 0:      First entry "."
+-               * pn = 0; index = 1:   Second entry ".."
++               * pn = 0; index = 1:   First entry "."
++               * pn = 0; index = 2:   Second entry ".."
+                * pn > 0:              Real entries, pn=1 -> leftmost page
+                * pn = index = -1:     No more entries
+                */
+               dtpos = filp->f_pos;
+-              if (dtpos == 0) {
++              if (dtpos < 2) {
+                       /* build "." entry */
++                      filp->f_pos = 1;
+                       if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino,
+                                   DT_DIR))
+                               return 0;
+-                      dtoffset->index = 1;
++                      dtoffset->index = 2;
+                       filp->f_pos = dtpos;
+               }
+               if (dtoffset->pn == 0) {
+-                      if (dtoffset->index == 1) {
++                      if (dtoffset->index == 2) {
+                               /* build ".." entry */
+                               if (filldir(dirent, "..", 2, filp->f_pos,
+@@ -3233,6 +3242,12 @@ int jfs_readdir(struct file *filp, void
+                                       }
+                                       jfs_dirent->position = unique_pos++;
+                               }
++                              /*
++                               * We add 1 to the index because we may
++                               * use a value of 2 internally, and NFSv4
++                               * doesn't like that.
++                               */
++                              jfs_dirent->position++;
+                       } else {
+                               jfs_dirent->position = dtpos;
+                               len = min(d_namleft, DTLHDRDATALEN_LEGACY);
diff --git a/queue-3.4/series b/queue-3.4/series
new file mode 100644 (file)
index 0000000..16b7aef
--- /dev/null
@@ -0,0 +1 @@
+jfs-fix-readdir-cookie-incompatibility-with-nfsv4.patch