path: root/fs/hugetlbfs
diff options
authorMike Kravetz <>2019-05-13 17:22:55 -0700
committerLinus Torvalds <>2019-05-14 09:47:50 -0700
commitf27a5136f70a8c90e8b30a983b6f54540742f849 (patch)
treed8c614cbaa67b50e754c37ff250e9d9722293772 /fs/hugetlbfs
parent1f862989b04ade61d3aab49184c50e9957f84c7d (diff)
hugetlbfs: always use address space in inode for resv_map pointer
Continuing discussion about 58b6e5e8f1ad ("hugetlbfs: fix memory leak for resv_map") brought up the issue that inode->i_mapping may not point to the address space embedded within the inode at inode eviction time. The hugetlbfs truncate routine handles this by explicitly using inode->i_data. However, code cleaning up the resv_map will still use the address space pointed to by inode->i_mapping. Luckily, private_data is NULL for address spaces in all such cases today but, there is no guarantee this will continue. Change all hugetlbfs code getting a resv_map pointer to explicitly get it from the address space embedded within the inode. In addition, add more comments in the code to indicate why this is being done. Link: Signed-off-by: Mike Kravetz <> Reported-by: Yufen Yu <> Cc: Michal Hocko <> Cc: Naoya Horiguchi <> Cc: "Kirill A . Shutemov" <> Signed-off-by: Andrew Morton <> Signed-off-by: Linus Torvalds <>
Diffstat (limited to 'fs/hugetlbfs')
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index f23237135163..1dcc57189382 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -497,8 +497,15 @@ static void hugetlbfs_evict_inode(struct inode *inode)
struct resv_map *resv_map;
remove_inode_hugepages(inode, 0, LLONG_MAX);
- resv_map = (struct resv_map *)inode->i_mapping->private_data;
- /* root inode doesn't have the resv_map, so we should check it */
+ /*
+ * Get the resv_map from the address space embedded in the inode.
+ * This is the address space which points to any resv_map allocated
+ * at inode creation time. If this is a device special inode,
+ * i_mapping may not point to the original address space.
+ */
+ resv_map = (struct resv_map *)(&inode->i_data)->private_data;
+ /* Only regular and link inodes have associated reserve maps */
if (resv_map)