Skip to content

Commit 7cd14c1

Browse files
jwrdegoedegregkh
authored andcommitted
vboxsf: Add vboxsf_[create|release]_sf_handle() helpers
commit 02f840f upstream. Factor out the code to create / release a struct vboxsf_handle into 2 new helper functions. This is a preparation patch for adding atomic_open support. Fixes: 0fd1695 ("fs: Add VirtualBox guest shared folder (vboxsf) support") Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 433f0b3 commit 7cd14c1

2 files changed

Lines changed: 51 additions & 27 deletions

File tree

fs/vboxsf/file.c

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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

fs/vboxsf/vfsmod.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#define VBOXSF_SBI(sb) ((struct vboxsf_sbi *)(sb)->s_fs_info)
1919
#define VBOXSF_I(i) container_of(i, struct vboxsf_inode, vfs_inode)
2020

21+
struct vboxsf_handle;
22+
2123
struct vboxsf_options {
2224
unsigned long ttl;
2325
kuid_t uid;
@@ -80,6 +82,11 @@ extern const struct file_operations vboxsf_reg_fops;
8082
extern const struct address_space_operations vboxsf_reg_aops;
8183
extern const struct dentry_operations vboxsf_dentry_ops;
8284

85+
/* from file.c */
86+
struct vboxsf_handle *vboxsf_create_sf_handle(struct inode *inode,
87+
u64 handle, u32 access_flags);
88+
void vboxsf_release_sf_handle(struct inode *inode, struct vboxsf_handle *sf_handle);
89+
8390
/* from utils.c */
8491
struct inode *vboxsf_new_inode(struct super_block *sb);
8592
void vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,

0 commit comments

Comments
 (0)