From mboxrd@z Thu Jan 1 00:00:00 1970 From: Pavel Shilovsky Subject: [PATCH v2] fuse: fix stat call on 32 bit platforms Date: Fri, 4 May 2012 13:57:53 +0400 Message-ID: <1336125473-11954-1-git-send-email-piastry@etersoft.ru> To: fuse-devel@lists.sourceforge.net, linux-fsdevel@vger.kernel.org Return-path: Received: from mail-lpp01m010-f46.google.com ([209.85.215.46]:37691 "EHLO mail-lpp01m010-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753640Ab2EDJ7R (ORCPT ); Fri, 4 May 2012 05:59:17 -0400 Received: by lahj13 with SMTP id j13so1880154lah.19 for ; Fri, 04 May 2012 02:59:15 -0700 (PDT) Sender: linux-fsdevel-owner@vger.kernel.org List-ID: Now we store attr->ino at inode->i_ino, return attr->ino at the first time and then return inode->i_ino if the attribute timeout isn't expired. That's wrong on 32 bit platforms because attr->ino is 64 bit and inode->i_ino is 32 bit in this case. Fix this by squashing attr->ino into inode->i_ino and returning the last one all the time we call getattr. Signed-off-by: Pavel Shilovsky --- fs/fuse/dir.c | 2 +- fs/fuse/inode.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index df5ac04..30c3976 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -776,7 +776,7 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr, struct kstat *stat) { stat->dev = inode->i_sb->s_dev; - stat->ino = attr->ino; + stat->ino = inode->i_ino; stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); stat->nlink = attr->nlink; stat->uid = attr->uid; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 26783eb..6c2a272 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -139,6 +139,18 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data) return 0; } +/* + * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down + * so that it will fit. + */ +static ino_t fuse_uniqueid_to_ino(u64 uniqueid) +{ + ino_t ino = (ino_t) uniqueid; + if (sizeof(ino_t) < sizeof(u64)) + ino ^= uniqueid >> (sizeof(u64) - sizeof(ino_t)) * 8; + return ino; +} + void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, u64 attr_valid) { @@ -148,7 +160,7 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, fi->attr_version = ++fc->attr_version; fi->i_time = attr_valid; - inode->i_ino = attr->ino; + inode->i_ino = fuse_uniqueid_to_ino(attr->ino); inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); set_nlink(inode, attr->nlink); inode->i_uid = attr->uid; -- 1.7.1