diff options
Diffstat (limited to 'fs/hugetlbfs/inode.c')
-rw-r--r-- | fs/hugetlbfs/inode.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 78bde32ea951..7f94e0cbc69c 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -97,7 +97,7 @@ static void huge_pagevec_release(struct pagevec *pvec) | |||
97 | 97 | ||
98 | static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | 98 | static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) |
99 | { | 99 | { |
100 | struct inode *inode = file->f_path.dentry->d_inode; | 100 | struct inode *inode = file_inode(file); |
101 | loff_t len, vma_len; | 101 | loff_t len, vma_len; |
102 | int ret; | 102 | int ret; |
103 | struct hstate *h = hstate_file(file); | 103 | struct hstate *h = hstate_file(file); |
@@ -918,16 +918,25 @@ static int get_hstate_idx(int page_size_log) | |||
918 | return h - hstates; | 918 | return h - hstates; |
919 | } | 919 | } |
920 | 920 | ||
921 | static char *hugetlb_dname(struct dentry *dentry, char *buffer, int buflen) | ||
922 | { | ||
923 | return dynamic_dname(dentry, buffer, buflen, "/%s (deleted)", | ||
924 | dentry->d_name.name); | ||
925 | } | ||
926 | |||
927 | static struct dentry_operations anon_ops = { | ||
928 | .d_dname = hugetlb_dname | ||
929 | }; | ||
930 | |||
921 | struct file *hugetlb_file_setup(const char *name, unsigned long addr, | 931 | struct file *hugetlb_file_setup(const char *name, unsigned long addr, |
922 | size_t size, vm_flags_t acctflag, | 932 | size_t size, vm_flags_t acctflag, |
923 | struct user_struct **user, | 933 | struct user_struct **user, |
924 | int creat_flags, int page_size_log) | 934 | int creat_flags, int page_size_log) |
925 | { | 935 | { |
926 | int error = -ENOMEM; | 936 | struct file *file = ERR_PTR(-ENOMEM); |
927 | struct file *file; | ||
928 | struct inode *inode; | 937 | struct inode *inode; |
929 | struct path path; | 938 | struct path path; |
930 | struct dentry *root; | 939 | struct super_block *sb; |
931 | struct qstr quick_string; | 940 | struct qstr quick_string; |
932 | struct hstate *hstate; | 941 | struct hstate *hstate; |
933 | unsigned long num_pages; | 942 | unsigned long num_pages; |
@@ -955,17 +964,18 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr, | |||
955 | } | 964 | } |
956 | } | 965 | } |
957 | 966 | ||
958 | root = hugetlbfs_vfsmount[hstate_idx]->mnt_root; | 967 | sb = hugetlbfs_vfsmount[hstate_idx]->mnt_sb; |
959 | quick_string.name = name; | 968 | quick_string.name = name; |
960 | quick_string.len = strlen(quick_string.name); | 969 | quick_string.len = strlen(quick_string.name); |
961 | quick_string.hash = 0; | 970 | quick_string.hash = 0; |
962 | path.dentry = d_alloc(root, &quick_string); | 971 | path.dentry = d_alloc_pseudo(sb, &quick_string); |
963 | if (!path.dentry) | 972 | if (!path.dentry) |
964 | goto out_shm_unlock; | 973 | goto out_shm_unlock; |
965 | 974 | ||
975 | d_set_d_op(path.dentry, &anon_ops); | ||
966 | path.mnt = mntget(hugetlbfs_vfsmount[hstate_idx]); | 976 | path.mnt = mntget(hugetlbfs_vfsmount[hstate_idx]); |
967 | error = -ENOSPC; | 977 | file = ERR_PTR(-ENOSPC); |
968 | inode = hugetlbfs_get_inode(root->d_sb, NULL, S_IFREG | S_IRWXUGO, 0); | 978 | inode = hugetlbfs_get_inode(sb, NULL, S_IFREG | S_IRWXUGO, 0); |
969 | if (!inode) | 979 | if (!inode) |
970 | goto out_dentry; | 980 | goto out_dentry; |
971 | 981 | ||
@@ -973,7 +983,7 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr, | |||
973 | size += addr & ~huge_page_mask(hstate); | 983 | size += addr & ~huge_page_mask(hstate); |
974 | num_pages = ALIGN(size, huge_page_size(hstate)) >> | 984 | num_pages = ALIGN(size, huge_page_size(hstate)) >> |
975 | huge_page_shift(hstate); | 985 | huge_page_shift(hstate); |
976 | error = -ENOMEM; | 986 | file = ERR_PTR(-ENOMEM); |
977 | if (hugetlb_reserve_pages(inode, 0, num_pages, NULL, acctflag)) | 987 | if (hugetlb_reserve_pages(inode, 0, num_pages, NULL, acctflag)) |
978 | goto out_inode; | 988 | goto out_inode; |
979 | 989 | ||
@@ -981,10 +991,9 @@ struct file *hugetlb_file_setup(const char *name, unsigned long addr, | |||
981 | inode->i_size = size; | 991 | inode->i_size = size; |
982 | clear_nlink(inode); | 992 | clear_nlink(inode); |
983 | 993 | ||
984 | error = -ENFILE; | ||
985 | file = alloc_file(&path, FMODE_WRITE | FMODE_READ, | 994 | file = alloc_file(&path, FMODE_WRITE | FMODE_READ, |
986 | &hugetlbfs_file_operations); | 995 | &hugetlbfs_file_operations); |
987 | if (!file) | 996 | if (IS_ERR(file)) |
988 | goto out_dentry; /* inode is already attached */ | 997 | goto out_dentry; /* inode is already attached */ |
989 | 998 | ||
990 | return file; | 999 | return file; |
@@ -998,7 +1007,7 @@ out_shm_unlock: | |||
998 | user_shm_unlock(size, *user); | 1007 | user_shm_unlock(size, *user); |
999 | *user = NULL; | 1008 | *user = NULL; |
1000 | } | 1009 | } |
1001 | return ERR_PTR(error); | 1010 | return file; |
1002 | } | 1011 | } |
1003 | 1012 | ||
1004 | static int __init init_hugetlbfs_fs(void) | 1013 | static int __init init_hugetlbfs_fs(void) |