diff options
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r-- | fs/fuse/inode.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 42678a33b7bb..1cd61652018c 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, |