diff options
| -rw-r--r-- | fs/fuse/dir.c | 1 | ||||
| -rw-r--r-- | fs/fuse/fuse_i.h | 3 | ||||
| -rw-r--r-- | fs/fuse/inode.c | 17 |
3 files changed, 20 insertions, 1 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index df5ac048dc74..bc438320cac5 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -863,6 +863,7 @@ int fuse_update_attributes(struct inode *inode, struct kstat *stat, | |||
| 863 | if (stat) { | 863 | if (stat) { |
| 864 | generic_fillattr(inode, stat); | 864 | generic_fillattr(inode, stat); |
| 865 | stat->mode = fi->orig_i_mode; | 865 | stat->mode = fi->orig_i_mode; |
| 866 | stat->ino = fi->orig_ino; | ||
| 866 | } | 867 | } |
| 867 | } | 868 | } |
| 868 | 869 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index f38fb795f03c..771fb6322c07 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
| @@ -82,6 +82,9 @@ struct fuse_inode { | |||
| 82 | preserve the original mode */ | 82 | preserve the original mode */ |
| 83 | umode_t orig_i_mode; | 83 | umode_t orig_i_mode; |
| 84 | 84 | ||
| 85 | /** 64 bit inode number */ | ||
| 86 | u64 orig_ino; | ||
| 87 | |||
| 85 | /** Version of last attribute change */ | 88 | /** Version of last attribute change */ |
| 86 | u64 attr_version; | 89 | u64 attr_version; |
| 87 | 90 | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 26783eb2b1fc..a59cf5e673d7 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
| @@ -91,6 +91,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) | |||
| 91 | fi->nlookup = 0; | 91 | fi->nlookup = 0; |
| 92 | fi->attr_version = 0; | 92 | fi->attr_version = 0; |
| 93 | fi->writectr = 0; | 93 | fi->writectr = 0; |
| 94 | fi->orig_ino = 0; | ||
| 94 | INIT_LIST_HEAD(&fi->write_files); | 95 | INIT_LIST_HEAD(&fi->write_files); |
| 95 | INIT_LIST_HEAD(&fi->queued_writes); | 96 | INIT_LIST_HEAD(&fi->queued_writes); |
| 96 | INIT_LIST_HEAD(&fi->writepages); | 97 | INIT_LIST_HEAD(&fi->writepages); |
| @@ -139,6 +140,18 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data) | |||
| 139 | return 0; | 140 | return 0; |
| 140 | } | 141 | } |
| 141 | 142 | ||
| 143 | /* | ||
| 144 | * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down | ||
| 145 | * so that it will fit. | ||
| 146 | */ | ||
| 147 | static ino_t fuse_squash_ino(u64 ino64) | ||
| 148 | { | ||
| 149 | ino_t ino = (ino_t) ino64; | ||
| 150 | if (sizeof(ino_t) < sizeof(u64)) | ||
| 151 | ino ^= ino64 >> (sizeof(u64) - sizeof(ino_t)) * 8; | ||
| 152 | return ino; | ||
| 153 | } | ||
| 154 | |||
| 142 | void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | 155 | void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, |
| 143 | u64 attr_valid) | 156 | u64 attr_valid) |
| 144 | { | 157 | { |
| @@ -148,7 +161,7 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | |||
| 148 | fi->attr_version = ++fc->attr_version; | 161 | fi->attr_version = ++fc->attr_version; |
| 149 | fi->i_time = attr_valid; | 162 | fi->i_time = attr_valid; |
| 150 | 163 | ||
| 151 | inode->i_ino = attr->ino; | 164 | inode->i_ino = fuse_squash_ino(attr->ino); |
| 152 | inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); | 165 | inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); |
| 153 | set_nlink(inode, attr->nlink); | 166 | set_nlink(inode, attr->nlink); |
| 154 | inode->i_uid = attr->uid; | 167 | inode->i_uid = attr->uid; |
| @@ -174,6 +187,8 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | |||
| 174 | fi->orig_i_mode = inode->i_mode; | 187 | fi->orig_i_mode = inode->i_mode; |
| 175 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) | 188 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) |
| 176 | inode->i_mode &= ~S_ISVTX; | 189 | inode->i_mode &= ~S_ISVTX; |
| 190 | |||
| 191 | fi->orig_ino = attr->ino; | ||
| 177 | } | 192 | } |
| 178 | 193 | ||
| 179 | void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, | 194 | void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, |
