lkml.org 
[lkml]   [2013]   [Sep]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 53/58] jfs: fix readdir cookie incompatibility with NFSv4
    Date
    3.5.7.21 -stable review patch.  If anyone has any objections, please let me know.

    ------------------

    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>
    Tested-by: Christian Kujau <lists@nerdbynature.de>
    Cc: Dave Kleikamp <dave.kleikamp@oracle.com>
    Cc: Ben Hutchings <ben@decadent.org.uk>
    [ luis: backported to 3.5 (based on bwh's backport to 3.2):
    - adjusted context
    - replaced usage of ctx->pos by filp->f_pos ]
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    fs/jfs/jfs_dtree.c | 31 +++++++++++++++++++++++--------
    1 file changed, 23 insertions(+), 8 deletions(-)

    diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
    index 9197a1b..9f7c758 100644
    --- a/fs/jfs/jfs_dtree.c
    +++ b/fs/jfs/jfs_dtree.c
    @@ -3047,6 +3047,14 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)

    dir_index = (u32) filp->f_pos;

    + /*
    + * NFSv4 reserves cookies 1 and 2 for . and .. so 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 *dirent, filldir_t filldir)
    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 *dirent, filldir_t filldir)
    /*
    * 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 *dirent, filldir_t filldir)
    /*
    * 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 *dirent, filldir_t filldir)
    /*
    * 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 *dirent, filldir_t filldir)
    }
    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);
    --
    1.8.3.2


    \
     
     \ /
      Last update: 2013-09-02 15:21    [W:4.491 / U:0.644 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site