diff options
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/fs/inode.c b/fs/inode.c index 71fe079ca32a..60cb25969762 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -321,6 +321,19 @@ void clear_inode(struct inode *inode) | |||
321 | } | 321 | } |
322 | EXPORT_SYMBOL(clear_inode); | 322 | EXPORT_SYMBOL(clear_inode); |
323 | 323 | ||
324 | static void evict(struct inode *inode, int delete) | ||
325 | { | ||
326 | const struct super_operations *op = inode->i_sb->s_op; | ||
327 | |||
328 | if (delete && op->delete_inode) { | ||
329 | op->delete_inode(inode); | ||
330 | } else { | ||
331 | if (inode->i_data.nrpages) | ||
332 | truncate_inode_pages(&inode->i_data, 0); | ||
333 | clear_inode(inode); | ||
334 | } | ||
335 | } | ||
336 | |||
324 | /* | 337 | /* |
325 | * dispose_list - dispose of the contents of a local list | 338 | * dispose_list - dispose of the contents of a local list |
326 | * @head: the head of the list to free | 339 | * @head: the head of the list to free |
@@ -338,9 +351,7 @@ static void dispose_list(struct list_head *head) | |||
338 | inode = list_first_entry(head, struct inode, i_list); | 351 | inode = list_first_entry(head, struct inode, i_list); |
339 | list_del(&inode->i_list); | 352 | list_del(&inode->i_list); |
340 | 353 | ||
341 | if (inode->i_data.nrpages) | 354 | evict(inode, 0); |
342 | truncate_inode_pages(&inode->i_data, 0); | ||
343 | clear_inode(inode); | ||
344 | 355 | ||
345 | spin_lock(&inode_lock); | 356 | spin_lock(&inode_lock); |
346 | hlist_del_init(&inode->i_hash); | 357 | hlist_del_init(&inode->i_hash); |
@@ -1194,8 +1205,6 @@ EXPORT_SYMBOL(remove_inode_hash); | |||
1194 | */ | 1205 | */ |
1195 | void generic_delete_inode(struct inode *inode) | 1206 | void generic_delete_inode(struct inode *inode) |
1196 | { | 1207 | { |
1197 | const struct super_operations *op = inode->i_sb->s_op; | ||
1198 | |||
1199 | list_del_init(&inode->i_list); | 1208 | list_del_init(&inode->i_list); |
1200 | list_del_init(&inode->i_sb_list); | 1209 | list_del_init(&inode->i_sb_list); |
1201 | WARN_ON(inode->i_state & I_NEW); | 1210 | WARN_ON(inode->i_state & I_NEW); |
@@ -1203,17 +1212,8 @@ void generic_delete_inode(struct inode *inode) | |||
1203 | inodes_stat.nr_inodes--; | 1212 | inodes_stat.nr_inodes--; |
1204 | spin_unlock(&inode_lock); | 1213 | spin_unlock(&inode_lock); |
1205 | 1214 | ||
1206 | if (op->delete_inode) { | 1215 | evict(inode, 1); |
1207 | void (*delete)(struct inode *) = op->delete_inode; | 1216 | |
1208 | /* Filesystems implementing their own | ||
1209 | * s_op->delete_inode are required to call | ||
1210 | * truncate_inode_pages and clear_inode() | ||
1211 | * internally */ | ||
1212 | delete(inode); | ||
1213 | } else { | ||
1214 | truncate_inode_pages(&inode->i_data, 0); | ||
1215 | clear_inode(inode); | ||
1216 | } | ||
1217 | spin_lock(&inode_lock); | 1217 | spin_lock(&inode_lock); |
1218 | hlist_del_init(&inode->i_hash); | 1218 | hlist_del_init(&inode->i_hash); |
1219 | spin_unlock(&inode_lock); | 1219 | spin_unlock(&inode_lock); |
@@ -1268,9 +1268,7 @@ static void generic_forget_inode(struct inode *inode) | |||
1268 | { | 1268 | { |
1269 | if (!generic_detach_inode(inode)) | 1269 | if (!generic_detach_inode(inode)) |
1270 | return; | 1270 | return; |
1271 | if (inode->i_data.nrpages) | 1271 | evict(inode, 0); |
1272 | truncate_inode_pages(&inode->i_data, 0); | ||
1273 | clear_inode(inode); | ||
1274 | wake_up_inode(inode); | 1272 | wake_up_inode(inode); |
1275 | destroy_inode(inode); | 1273 | destroy_inode(inode); |
1276 | } | 1274 | } |