@@ -20,17 +20,39 @@ struct vboxsf_handle {
2020 struct list_head head ;
2121};
2222
23- static int vboxsf_file_open (struct inode * inode , struct file * file )
23+ struct vboxsf_handle * vboxsf_create_sf_handle (struct inode * inode ,
24+ u64 handle , u32 access_flags )
2425{
2526 struct vboxsf_inode * sf_i = VBOXSF_I (inode );
26- struct shfl_createparms params = {};
2727 struct vboxsf_handle * sf_handle ;
28- u32 access_flags = 0 ;
29- int err ;
3028
3129 sf_handle = kmalloc (sizeof (* sf_handle ), GFP_KERNEL );
3230 if (!sf_handle )
33- return - ENOMEM ;
31+ return ERR_PTR (- ENOMEM );
32+
33+ /* the host may have given us different attr then requested */
34+ sf_i -> force_restat = 1 ;
35+
36+ /* init our handle struct and add it to the inode's handles list */
37+ sf_handle -> handle = handle ;
38+ sf_handle -> root = VBOXSF_SBI (inode -> i_sb )-> root ;
39+ sf_handle -> access_flags = access_flags ;
40+ kref_init (& sf_handle -> refcount );
41+
42+ mutex_lock (& sf_i -> handle_list_mutex );
43+ list_add (& sf_handle -> head , & sf_i -> handle_list );
44+ mutex_unlock (& sf_i -> handle_list_mutex );
45+
46+ return sf_handle ;
47+ }
48+
49+ static int vboxsf_file_open (struct inode * inode , struct file * file )
50+ {
51+ struct vboxsf_sbi * sbi = VBOXSF_SBI (inode -> i_sb );
52+ struct shfl_createparms params = {};
53+ struct vboxsf_handle * sf_handle ;
54+ u32 access_flags = 0 ;
55+ int err ;
3456
3557 /*
3658 * We check the value of params.handle afterwards to find out if
@@ -83,23 +105,14 @@ static int vboxsf_file_open(struct inode *inode, struct file *file)
83105 err = vboxsf_create_at_dentry (file_dentry (file ), & params );
84106 if (err == 0 && params .handle == SHFL_HANDLE_NIL )
85107 err = (params .result == SHFL_FILE_EXISTS ) ? - EEXIST : - ENOENT ;
86- if (err ) {
87- kfree (sf_handle );
108+ if (err )
88109 return err ;
89- }
90-
91- /* the host may have given us different attr then requested */
92- sf_i -> force_restat = 1 ;
93110
94- /* init our handle struct and add it to the inode's handles list */
95- sf_handle -> handle = params .handle ;
96- sf_handle -> root = VBOXSF_SBI (inode -> i_sb )-> root ;
97- sf_handle -> access_flags = access_flags ;
98- kref_init (& sf_handle -> refcount );
99-
100- mutex_lock (& sf_i -> handle_list_mutex );
101- list_add (& sf_handle -> head , & sf_i -> handle_list );
102- mutex_unlock (& sf_i -> handle_list_mutex );
111+ sf_handle = vboxsf_create_sf_handle (inode , params .handle , access_flags );
112+ if (IS_ERR (sf_handle )) {
113+ vboxsf_close (sbi -> root , params .handle );
114+ return PTR_ERR (sf_handle );
115+ }
103116
104117 file -> private_data = sf_handle ;
105118 return 0 ;
@@ -114,22 +127,26 @@ static void vboxsf_handle_release(struct kref *refcount)
114127 kfree (sf_handle );
115128}
116129
117- static int vboxsf_file_release (struct inode * inode , struct file * file )
130+ void vboxsf_release_sf_handle (struct inode * inode , struct vboxsf_handle * sf_handle )
118131{
119132 struct vboxsf_inode * sf_i = VBOXSF_I (inode );
120- struct vboxsf_handle * sf_handle = file -> private_data ;
121133
134+ mutex_lock (& sf_i -> handle_list_mutex );
135+ list_del (& sf_handle -> head );
136+ mutex_unlock (& sf_i -> handle_list_mutex );
137+
138+ kref_put (& sf_handle -> refcount , vboxsf_handle_release );
139+ }
140+
141+ static int vboxsf_file_release (struct inode * inode , struct file * file )
142+ {
122143 /*
123144 * When a file is closed on our (the guest) side, we want any subsequent
124145 * accesses done on the host side to see all changes done from our side.
125146 */
126147 filemap_write_and_wait (inode -> i_mapping );
127148
128- mutex_lock (& sf_i -> handle_list_mutex );
129- list_del (& sf_handle -> head );
130- mutex_unlock (& sf_i -> handle_list_mutex );
131-
132- kref_put (& sf_handle -> refcount , vboxsf_handle_release );
149+ vboxsf_release_sf_handle (inode , file -> private_data );
133150 return 0 ;
134151}
135152
0 commit comments