aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/hugetlbfs/inode.c38
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
225static void hugetlbfs_delete_inode(struct inode *inode) 225static 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
232static 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:
276static void hugetlbfs_drop_inode(struct inode *inode) 301static 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};