diff options
Diffstat (limited to 'fs/hugetlbfs')
-rw-r--r-- | fs/hugetlbfs/inode.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8e9d43633365..2b9d1bee9220 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -224,19 +224,44 @@ static void truncate_hugepages(struct address_space *mapping, loff_t lstart) | |||
224 | 224 | ||
225 | static void hugetlbfs_delete_inode(struct inode *inode) | 225 | static void hugetlbfs_delete_inode(struct inode *inode) |
226 | { | 226 | { |
227 | hlist_del_init(&inode->i_hash); | 227 | if (inode->i_data.nrpages) |
228 | truncate_hugepages(&inode->i_data, 0); | ||
229 | clear_inode(inode); | ||
230 | } | ||
231 | |||
232 | static void hugetlbfs_do_delete_inode(struct inode *inode) | ||
233 | { | ||
234 | struct super_operations *op = inode->i_sb->s_op; | ||
235 | |||
228 | list_del_init(&inode->i_list); | 236 | list_del_init(&inode->i_list); |
229 | list_del_init(&inode->i_sb_list); | 237 | list_del_init(&inode->i_sb_list); |
230 | inode->i_state |= I_FREEING; | 238 | inode->i_state |= I_FREEING; |
231 | inodes_stat.nr_inodes--; | 239 | inodes_stat.nr_inodes--; |
232 | spin_unlock(&inode_lock); | 240 | spin_unlock(&inode_lock); |
233 | 241 | ||
234 | if (inode->i_data.nrpages) | ||
235 | truncate_hugepages(&inode->i_data, 0); | ||
236 | |||
237 | security_inode_delete(inode); | 242 | security_inode_delete(inode); |
238 | 243 | ||
239 | clear_inode(inode); | 244 | if (op->delete_inode) { |
245 | void (*delete)(struct inode *) = op->delete_inode; | ||
246 | if (!is_bad_inode(inode)) | ||
247 | DQUOT_INIT(inode); | ||
248 | /* Filesystems implementing their own | ||
249 | * s_op->delete_inode are required to call | ||
250 | * truncate_inode_pages and clear_inode() | ||
251 | * internally | ||
252 | */ | ||
253 | delete(inode); | ||
254 | } else { | ||
255 | truncate_inode_pages(&inode->i_data, 0); | ||
256 | clear_inode(inode); | ||
257 | } | ||
258 | |||
259 | spin_lock(&inode_lock); | ||
260 | hlist_del_init(&inode->i_hash); | ||
261 | spin_unlock(&inode_lock); | ||
262 | wake_up_inode(inode); | ||
263 | if (inode->i_state != I_CLEAR) | ||
264 | BUG(); | ||
240 | destroy_inode(inode); | 265 | destroy_inode(inode); |
241 | } | 266 | } |
242 | 267 | ||
@@ -276,7 +301,7 @@ out_truncate: | |||
276 | static void hugetlbfs_drop_inode(struct inode *inode) | 301 | static void hugetlbfs_drop_inode(struct inode *inode) |
277 | { | 302 | { |
278 | if (!inode->i_nlink) | 303 | if (!inode->i_nlink) |
279 | hugetlbfs_delete_inode(inode); | 304 | hugetlbfs_do_delete_inode(inode); |
280 | else | 305 | else |
281 | hugetlbfs_forget_inode(inode); | 306 | hugetlbfs_forget_inode(inode); |
282 | } | 307 | } |
@@ -594,6 +619,7 @@ static struct super_operations hugetlbfs_ops = { | |||
594 | .alloc_inode = hugetlbfs_alloc_inode, | 619 | .alloc_inode = hugetlbfs_alloc_inode, |
595 | .destroy_inode = hugetlbfs_destroy_inode, | 620 | .destroy_inode = hugetlbfs_destroy_inode, |
596 | .statfs = hugetlbfs_statfs, | 621 | .statfs = hugetlbfs_statfs, |
622 | .delete_inode = hugetlbfs_delete_inode, | ||
597 | .drop_inode = hugetlbfs_drop_inode, | 623 | .drop_inode = hugetlbfs_drop_inode, |
598 | .put_super = hugetlbfs_put_super, | 624 | .put_super = hugetlbfs_put_super, |
599 | }; | 625 | }; |