Skip to content

Commit

Permalink
Merge tag 'jfs-3.11-rc8' of git://github.com/kleikamp/linux-shaggy
Browse files Browse the repository at this point in the history
Pull jfs fix from Dave Kleikamp:
 "One JFS patch to fix an incompatibility with NFSv4 resulting in the
  nfs client reporting a readdir loop"

* tag 'jfs-3.11-rc8' of git://github.com/kleikamp/linux-shaggy:
  jfs: fix readdir cookie incompatibility with NFSv4
  • Loading branch information
Linus Torvalds committed Aug 27, 2013
2 parents d8dfad3 + 4451244 commit 83c425d
Showing 1 changed file with 23 additions and 8 deletions.
31 changes: 23 additions & 8 deletions fs/jfs/jfs_dtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -3047,6 +3047,14 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)

dir_index = (u32) ctx->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;

Expand Down Expand Up @@ -3086,22 +3094,22 @@ 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);
ctx->pos = -1;
ctx->pos = DIREND;
return 0;
}
} else {
if (dir_index == 0) {
/*
* self "."
*/
ctx->pos = 0;
ctx->pos = 1;
if (!dir_emit(ctx, ".", 1, ip->i_ino, DT_DIR))
return 0;
}
/*
* parent ".."
*/
ctx->pos = 1;
ctx->pos = 2;
if (!dir_emit(ctx, "..", 2, PARENT(ip), DT_DIR))
return 0;

Expand All @@ -3122,22 +3130,23 @@ 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 = ctx->pos;
if (dtpos == 0) {
if (dtpos < 2) {
/* build "." entry */
ctx->pos = 1;
if (!dir_emit(ctx, ".", 1, ip->i_ino, DT_DIR))
return 0;
dtoffset->index = 1;
dtoffset->index = 2;
ctx->pos = dtpos;
}

if (dtoffset->pn == 0) {
if (dtoffset->index == 1) {
if (dtoffset->index == 2) {
/* build ".." entry */
if (!dir_emit(ctx, "..", 2, PARENT(ip), DT_DIR))
return 0;
Expand Down Expand Up @@ -3228,6 +3237,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);
Expand Down

0 comments on commit 83c425d

Please sign in to comment.