From patchwork Thu Aug 15 03:54:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Kleikamp X-Patchwork-Id: 2844963 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 69FE39F2F4 for ; Thu, 15 Aug 2013 03:55:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 464262031A for ; Thu, 15 Aug 2013 03:55:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2225720318 for ; Thu, 15 Aug 2013 03:55:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759662Ab3HODzW (ORCPT ); Wed, 14 Aug 2013 23:55:22 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:51494 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758425Ab3HODzV (ORCPT ); Wed, 14 Aug 2013 23:55:21 -0400 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by aserp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r7F3sZ1Y003927 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 15 Aug 2013 03:54:36 GMT Received: from aserz7022.oracle.com (aserz7022.oracle.com [141.146.126.231]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r7F3sW1H009753 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 15 Aug 2013 03:54:33 GMT Received: from abhmt116.oracle.com (abhmt116.oracle.com [141.146.116.68]) by aserz7022.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r7F3sWkn009749; Thu, 15 Aug 2013 03:54:32 GMT Received: from [192.168.1.103] (/99.156.91.244) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 14 Aug 2013 20:54:32 -0700 Message-ID: <520C50F7.3010209@oracle.com> Date: Wed, 14 Aug 2013 22:54:31 -0500 From: Dave Kleikamp User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130806 Thunderbird/17.0.8 MIME-Version: 1.0 To: "J. Bruce Fields" CC: Christian Kujau , Karl Schmidt , Jonathan McDowell , jfs-discussion@lists.sourceforge.net, 714974@bugs.debian.org, Ben Hutchings , linux-nfs@vger.kernel.org Subject: [PATCH] jfs: avoid misuse of cookie value of 2 References: <1373245980.3428.46.camel@deadeye.wl.decadent.org.uk> <520554A5.3060401@xtronics.com> <20130812162924.GB2395@fieldses.org> In-Reply-To: <20130812162924.GB2395@fieldses.org> X-Enigmail-Version: 1.5.2 X-Source-IP: acsinet22.oracle.com [141.146.126.238] Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-9.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html 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)) {