Dave Kleikamp <[email protected]> writes:

> Ben Hutchings backported this patch that has just been picked up in the
> mainline kernel for 3.11. It is relevant to and should apply to any
> stable kernel between 2.6.32.x and 3.10.x. (Possibly further back, but
> does anyone care?)
>
> Upstream commit: 44512449c0ab368889dd13ae0031fba74ee7e1d2

Thanks.  I'm queuing it for the 3.5 kernel.

Cheers,
-- 
Luis


>
> 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 readdir method.
>
> Signed-off-by: Dave Kleikamp <[email protected]>
> [bwh: Backported to 3.2:
>  - Adjust context
>  - s/ctx->pos/filp->f_pos/]
> Signed-off-by: Ben Hutchings <[email protected]>
> ---
>  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 8743ba9..0ec767e 100644
> --- a/fs/jfs/jfs_dtree.c
> +++ b/fs/jfs/jfs_dtree.c
> @@ -3047,6 +3047,14 @@ int jfs_readdir(struct file *file, struct dir_context 
> *ctx)
>  
>               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 *file, struct dir_context 
> *ctx)
>                       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,15 +3102,15 @@ int jfs_readdir(struct file *file, struct dir_context 
> *ctx)
>                               /*
>                                * self "."
>                                */
> -                             filp->f_pos = 0;
> +                             filp->f_pos = 1;
>                               if (filldir(dirent, ".", 1, 0, ip->i_ino,
>                                           DT_DIR))
>                                       return 0;
>                       }
>                       /*
>                        * 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 *file, struct dir_context 
> *ctx)
>               /*
>                * 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 *file, struct dir_context 
> *ctx)
>                                       }
>                                       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);
> --
> To unsubscribe from this list: send the line "unsubscribe stable" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

------------------------------------------------------------------------------
Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
Discover the easy way to master current and previous Microsoft technologies
and advance your career. Get an incredible 1,500+ hours of step-by-step
tutorial videos with LearnDevNow. Subscribe today and save!
http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk
_______________________________________________
Jfs-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jfs-discussion

Reply via email to