From: Dave Kleikamp <dave.kleikamp@oracle.com>
To: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Christian Kujau <lists@nerdbynature.de>,
Karl Schmidt <karl@xtronics.com>,
Jonathan McDowell <noodles@earth.li>,
jfs-discussion@lists.sourceforge.net, 714974@bugs.debian.org,
Ben Hutchings <ben@decadent.org.uk>,
linux-nfs@vger.kernel.org
Subject: [PATCH] jfs: avoid misuse of cookie value of 2
Date: Wed, 14 Aug 2013 22:54:31 -0500 [thread overview]
Message-ID: <520C50F7.3010209@oracle.com> (raw)
In-Reply-To: <20130812162924.GB2395@fieldses.org>
For the sake of those not watching
https://bugzilla.kernel.org/show_bug.cgi?id=60737
It looks like the problem is that jfs was using a cookie value of 2 for
a real directory entry, where NFSv4 expect 2 to represent "..". This
patch has so far only been lightly tested.
NFSv4 reserves cookie values 0, 1 and 2 for a rewind, and the "." and ".."
entries. jfs was using 0 and 1 for "." and "..", but 2 for a regular entry.
This patch makes jfs conform by using 1 and 2 for "." and ".." and fixes
any regular entry using the value 2.
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 8743ba9..93466e8 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -349,11 +349,8 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
ASSERT(DO_INDEX(ip));
- if (jfs_ip->next_index < 2) {
- jfs_warn("add_index: next_index = %d. Resetting!",
- jfs_ip->next_index);
- jfs_ip->next_index = 2;
- }
+ if (jfs_ip->next_index < 3) {
+ jfs_ip->next_index = 3;
index = jfs_ip->next_index++;
@@ -2864,7 +2861,7 @@ void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
} else
ip->i_size = 1;
- jfs_ip->next_index = 2;
+ jfs_ip->next_index = 3;
} else
ip->i_size = IDATASIZE;
@@ -2951,7 +2948,7 @@ static void add_missing_indices(struct inode *inode, s64 bn)
for (i = 0; i < p->header.nextindex; i++) {
d = (struct ldtentry *) &p->slot[stbl[i]];
index = le32_to_cpu(d->index);
- if ((index < 2) || (index >= JFS_IP(inode)->next_index)) {
+ if ((index < 3) || (index >= JFS_IP(inode)->next_index)) {
d->index = cpu_to_le32(add_index(tid, inode, bn, i));
if (dtlck->index >= dtlck->maxcnt)
dtlck = (struct dt_lock *) txLinelock(dtlck);
@@ -3031,7 +3028,7 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)
struct jfs_dirent *jfs_dirent;
int jfs_dirents;
int overflow, fix_page, page_fixed = 0;
- static int unique_pos = 2; /* If we can't fix broken index */
+ static int unique_pos = 3; /* If we can't fix broken index */
if (ctx->pos == DIREND)
return 0;
@@ -3039,15 +3036,16 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)
if (DO_INDEX(ip)) {
/*
* persistent index is stored in directory entries.
- * Special cases: 0 = .
- * 1 = ..
+ * Special cases: 0 = rewind
+ * 1 = .
+ * 2 = ..
* -1 = End of directory
*/
do_index = 1;
dir_index = (u32) ctx->pos;
- if (dir_index > 1) {
+ if (dir_index > 2) {
struct dir_table_slot dirtab_slot;
if (dtEmpty(ip) ||
@@ -3090,18 +3088,18 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)
return 0;
}
} else {
- if (dir_index == 0) {
+ if (dir_index < 2) {
/*
* 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;
@@ -3122,22 +3120,24 @@ 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) {
+ ctx->pos = 1;
/* build "." entry */
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) {
+ ctx->pos = 2;
/* build ".." entry */
if (!dir_emit(ctx, "..", 2, PARENT(ip), DT_DIR))
return 0;
@@ -3210,8 +3210,12 @@ int jfs_readdir(struct file *file, struct dir_context *ctx)
* directory index for the lost+found
* directory. Rather than let it go,
* we can try to fix it.
+ *
+ * Additionally, a value of 2 used to be
+ * valid, but it didn't work well with
+ * NFSv4, so if found, we need to change it
*/
- if ((jfs_dirent->position < 2) ||
+ if ((jfs_dirent->position < 3) ||
(jfs_dirent->position >=
JFS_IP(ip)->next_index)) {
if (!page_fixed && !isReadOnly(ip)) {
next prev parent reply other threads:[~2013-08-15 3:55 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-08 1:13 NFS 'readdir loop' error on JFS Ben Hutchings
2013-07-08 14:02 ` bjschuma
2013-07-08 15:43 ` Karl Schmidt
2013-08-09 20:44 ` Karl Schmidt
2013-08-10 7:28 ` [Jfs-discussion] " Christian Kujau
2013-08-10 19:43 ` Karl Schmidt
2013-08-12 8:18 ` Christian Kujau
2013-08-12 8:29 ` Christian Kujau
2013-08-12 16:29 ` J. Bruce Fields
2013-08-12 20:04 ` Christian Kujau
2013-08-15 3:54 ` Dave Kleikamp [this message]
2013-08-15 4:29 ` [PATCH] jfs: avoid misuse of cookie value of 2 Christian Kujau
2013-08-15 7:09 ` Christian Kujau
2013-08-15 13:38 ` Dave Kleikamp
2013-08-15 20:48 ` [PATCH] jfs: fix readdir cookie incompatibility with NFSv4 Dave Kleikamp
2013-08-15 21:26 ` Christian Kujau
2013-08-15 22:09 ` Dave Kleikamp
2013-08-17 20:01 ` Ben Hutchings
2013-08-19 19:11 ` [JunkMail] " ben
2013-08-29 22:48 ` Jonathan McDowell
2013-09-05 3:40 ` Bug#714974: " Jonathan McDowell
2013-08-24 22:21 ` [Jfs-discussion] " Christian Kujau
2013-08-26 22:27 ` Dave Kleikamp
2013-08-15 13:38 ` [PATCH] jfs: avoid misuse of cookie value of 2 J. Bruce Fields
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=520C50F7.3010209@oracle.com \
--to=dave.kleikamp@oracle.com \
--cc=714974@bugs.debian.org \
--cc=ben@decadent.org.uk \
--cc=bfields@fieldses.org \
--cc=jfs-discussion@lists.sourceforge.net \
--cc=karl@xtronics.com \
--cc=linux-nfs@vger.kernel.org \
--cc=lists@nerdbynature.de \
--cc=noodles@earth.li \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.