Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
964815bc
Commit
964815bc
authored
Aug 08, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added an unmount_device request that invalidates all file descriptors
open on a given Unix device.
parent
66868e53
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
114 additions
and
12 deletions
+114
-12
server_protocol.h
include/wine/server_protocol.h
+16
-1
change.c
server/change.c
+2
-0
fd.c
server/fd.c
+67
-8
file.c
server/file.c
+10
-1
mapping.c
server/mapping.c
+2
-2
protocol.def
server/protocol.def
+6
-0
request.h
server/request.h
+2
-0
trace.c
server/trace.c
+9
-0
No files found.
include/wine/server_protocol.h
View file @
964815bc
...
...
@@ -851,6 +851,18 @@ struct unlock_file_reply
struct
unmount_device_request
{
struct
request_header
__header
;
obj_handle_t
handle
;
};
struct
unmount_device_reply
{
struct
reply_header
__header
;
};
struct
create_socket_request
{
struct
request_header
__header
;
...
...
@@ -3592,6 +3604,7 @@ enum request
REQ_flush_file
,
REQ_lock_file
,
REQ_unlock_file
,
REQ_unmount_device
,
REQ_create_socket
,
REQ_accept_socket
,
REQ_set_socket_event
,
...
...
@@ -3802,6 +3815,7 @@ union generic_request
struct
flush_file_request
flush_file_request
;
struct
lock_file_request
lock_file_request
;
struct
unlock_file_request
unlock_file_request
;
struct
unmount_device_request
unmount_device_request
;
struct
create_socket_request
create_socket_request
;
struct
accept_socket_request
accept_socket_request
;
struct
set_socket_event_request
set_socket_event_request
;
...
...
@@ -4010,6 +4024,7 @@ union generic_reply
struct
flush_file_reply
flush_file_reply
;
struct
lock_file_reply
lock_file_reply
;
struct
unlock_file_reply
unlock_file_reply
;
struct
unmount_device_reply
unmount_device_reply
;
struct
create_socket_reply
create_socket_reply
;
struct
accept_socket_reply
accept_socket_reply
;
struct
set_socket_event_reply
set_socket_event_reply
;
...
...
@@ -4175,6 +4190,6 @@ union generic_reply
struct
set_mailslot_info_reply
set_mailslot_info_reply
;
};
#define SERVER_PROTOCOL_VERSION 18
8
#define SERVER_PROTOCOL_VERSION 18
9
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/change.c
View file @
964815bc
...
...
@@ -137,6 +137,8 @@ static struct change *create_change_notification( struct fd *fd, int subtree, un
struct
stat
st
;
int
unix_fd
=
get_unix_fd
(
fd
);
if
(
unix_fd
==
-
1
)
return
NULL
;
if
(
fstat
(
unix_fd
,
&
st
)
==
-
1
||
!
S_ISDIR
(
st
.
st_mode
))
{
set_error
(
STATUS_NOT_A_DIRECTORY
);
...
...
server/fd.c
View file @
964815bc
...
...
@@ -625,7 +625,7 @@ static void device_destroy( struct object *obj )
/* inode functions */
/* close all pending file descriptors in the closed list */
static
void
inode_close_pending
(
struct
inode
*
inode
)
static
void
inode_close_pending
(
struct
inode
*
inode
,
int
keep_unlinks
)
{
struct
list
*
ptr
=
list_head
(
&
inode
->
closed
);
...
...
@@ -639,7 +639,7 @@ static void inode_close_pending( struct inode *inode )
close
(
fd
->
unix_fd
);
fd
->
unix_fd
=
-
1
;
}
if
(
!
fd
->
unlink
)
/* get rid of it unless there's an unlink pending on that file */
if
(
!
keep_unlinks
||
!
fd
->
unlink
[
0
]
)
/* get rid of it unless there's an unlink pending on that file */
{
list_remove
(
ptr
);
free
(
fd
);
...
...
@@ -968,7 +968,7 @@ static void remove_lock( struct file_lock *lock, int remove_unix )
list_remove
(
&
lock
->
inode_entry
);
list_remove
(
&
lock
->
proc_entry
);
if
(
remove_unix
)
remove_unix_locks
(
lock
->
fd
,
lock
->
start
,
lock
->
end
);
if
(
list_empty
(
&
inode
->
locks
))
inode_close_pending
(
inode
);
if
(
list_empty
(
&
inode
->
locks
))
inode_close_pending
(
inode
,
1
);
lock
->
process
=
NULL
;
wake_up
(
&
lock
->
obj
,
0
);
release_object
(
lock
);
...
...
@@ -1187,6 +1187,26 @@ void set_fd_events( struct fd *fd, int events )
}
}
/* prepare an fd for unmounting its corresponding device */
static
inline
void
unmount_fd
(
struct
fd
*
fd
)
{
assert
(
fd
->
inode
);
async_terminate_queue
(
&
fd
->
read_q
,
STATUS_VOLUME_DISMOUNTED
);
async_terminate_queue
(
&
fd
->
write_q
,
STATUS_VOLUME_DISMOUNTED
);
if
(
fd
->
poll_index
!=
-
1
)
set_fd_events
(
fd
,
-
1
);
if
(
fd
->
unix_fd
!=
-
1
)
close
(
fd
->
unix_fd
);
fd
->
unix_fd
=
-
1
;
fd
->
closed
->
unix_fd
=
-
1
;
fd
->
closed
->
unlink
[
0
]
=
0
;
/* stop using Unix locks on this fd (existing locks have been removed by close) */
fd
->
fs_locks
=
0
;
}
/* allocate an fd object, without setting the unix fd yet */
struct
fd
*
alloc_fd
(
const
struct
fd_ops
*
fd_user_ops
,
struct
object
*
user
)
{
...
...
@@ -1379,6 +1399,7 @@ void *get_fd_user( struct fd *fd )
/* retrieve the unix fd for an object */
int
get_unix_fd
(
struct
fd
*
fd
)
{
if
(
fd
->
unix_fd
==
-
1
)
set_error
(
STATUS_VOLUME_DISMOUNTED
);
return
fd
->
unix_fd
;
}
...
...
@@ -1399,6 +1420,8 @@ int check_fd_events( struct fd *fd, int events )
{
struct
pollfd
pfd
;
if
(
fd
->
unix_fd
==
-
1
)
return
POLLERR
;
pfd
.
fd
=
fd
->
unix_fd
;
pfd
.
events
=
events
;
if
(
poll
(
&
pfd
,
1
,
0
)
<=
0
)
return
0
;
...
...
@@ -1554,6 +1577,29 @@ void no_cancel_async( struct fd *fd )
set_error
(
STATUS_OBJECT_TYPE_MISMATCH
);
}
/* close all Unix file descriptors on a device to allow unmounting it */
static
void
unmount_device
(
struct
device
*
device
)
{
unsigned
int
i
;
struct
inode
*
inode
;
struct
fd
*
fd
;
for
(
i
=
0
;
i
<
INODE_HASH_SIZE
;
i
++
)
{
LIST_FOR_EACH_ENTRY
(
inode
,
&
device
->
inode_hash
[
i
],
struct
inode
,
entry
)
{
LIST_FOR_EACH_ENTRY
(
fd
,
&
inode
->
open
,
struct
fd
,
inode_entry
)
{
unmount_fd
(
fd
);
}
inode_close_pending
(
inode
,
0
);
}
}
/* remove it from the hash table */
list_remove
(
&
device
->
entry
);
list_init
(
&
device
->
entry
);
}
/* same as get_handle_obj but retrieve the struct fd associated to the object */
static
struct
fd
*
get_handle_fd_obj
(
struct
process
*
process
,
obj_handle_t
handle
,
unsigned
int
access
)
...
...
@@ -1595,18 +1641,31 @@ DECL_HANDLER(get_handle_fd)
if
((
fd
=
get_handle_fd_obj
(
current
->
process
,
req
->
handle
,
req
->
access
)))
{
int
unix_fd
=
get_handle_unix_fd
(
current
->
process
,
req
->
handle
,
req
->
access
);
if
(
unix_fd
!=
-
1
)
reply
->
fd
=
unix_fd
;
else
if
(
!
get_error
())
int
unix_fd
=
get_unix_fd
(
fd
);
if
(
unix_fd
!=
-
1
)
{
assert
(
fd
->
unix_fd
!=
-
1
);
send_client_fd
(
current
->
process
,
fd
->
unix_fd
,
req
->
handle
);
int
cached_fd
=
get_handle_unix_fd
(
current
->
process
,
req
->
handle
,
req
->
access
);
if
(
cached_fd
!=
-
1
)
reply
->
fd
=
cached_fd
;
else
if
(
!
get_error
())
send_client_fd
(
current
->
process
,
unix_fd
,
req
->
handle
);
}
reply
->
flags
=
fd
->
fd_ops
->
get_file_info
(
fd
);
release_object
(
fd
);
}
}
/* get ready to unmount a Unix device */
DECL_HANDLER
(
unmount_device
)
{
struct
fd
*
fd
;
if
((
fd
=
get_handle_fd_obj
(
current
->
process
,
req
->
handle
,
0
)))
{
if
(
fd
->
inode
)
unmount_device
(
fd
->
inode
->
device
);
else
set_error
(
STATUS_OBJECT_TYPE_MISMATCH
);
release_object
(
fd
);
}
}
/* create / reschedule an async I/O */
DECL_HANDLER
(
register_async
)
{
...
...
server/file.c
View file @
964815bc
...
...
@@ -226,8 +226,13 @@ static int file_get_poll_events( struct fd *fd )
static
int
file_flush
(
struct
fd
*
fd
,
struct
event
**
event
)
{
int
ret
=
(
fsync
(
get_unix_fd
(
fd
)
)
!=
-
1
);
int
ret
=
0
,
unix_fd
=
get_unix_fd
(
fd
);
if
(
unix_fd
!=
-
1
)
{
ret
=
(
fsync
(
unix_fd
)
!=
-
1
);
if
(
!
ret
)
file_set_error
();
}
return
ret
;
}
...
...
@@ -304,6 +309,8 @@ static int extend_file( struct file *file, file_pos_t new_size )
int
unix_fd
=
get_file_unix_fd
(
file
);
off_t
size
=
new_size
;
if
(
unix_fd
==
-
1
)
return
0
;
if
(
sizeof
(
new_size
)
>
sizeof
(
size
)
&&
size
!=
new_size
)
{
set_error
(
STATUS_INVALID_PARAMETER
);
...
...
@@ -326,6 +333,8 @@ int grow_file( struct file *file, file_pos_t size )
struct
stat
st
;
int
unix_fd
=
get_file_unix_fd
(
file
);
if
(
unix_fd
==
-
1
)
return
0
;
if
(
fstat
(
unix_fd
,
&
st
)
==
-
1
)
{
file_set_error
();
...
...
server/mapping.c
View file @
964815bc
...
...
@@ -196,7 +196,7 @@ static int get_image_params( struct mapping *mapping )
/* load the headers */
if
(
!
(
fd
=
mapping_get_fd
(
&
mapping
->
obj
)))
return
0
;
unix_fd
=
get_unix_fd
(
fd
)
;
if
((
unix_fd
=
get_unix_fd
(
fd
))
==
-
1
)
goto
error
;
if
(
pread
(
unix_fd
,
&
dos
,
sizeof
(
dos
),
0
)
!=
sizeof
(
dos
))
goto
error
;
if
(
dos
.
e_magic
!=
IMAGE_DOS_SIGNATURE
)
goto
error
;
pos
=
dos
.
e_lfanew
;
...
...
@@ -250,7 +250,7 @@ inline static int get_file_size( struct file *file, file_pos_t *size )
struct
stat
st
;
int
unix_fd
=
get_file_unix_fd
(
file
);
if
(
fstat
(
unix_fd
,
&
st
)
==
-
1
)
return
0
;
if
(
unix_fd
==
-
1
||
fstat
(
unix_fd
,
&
st
)
==
-
1
)
return
0
;
*
size
=
st
.
st_size
;
return
1
;
}
...
...
server/protocol.def
View file @
964815bc
...
...
@@ -657,6 +657,12 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
@END
/* Get ready to unmount a Unix device */
@REQ(unmount_device)
obj_handle_t handle; /* handle to a file on the device */
@END
/* Create a socket */
@REQ(create_socket)
unsigned int access; /* wanted access rights */
...
...
server/request.h
View file @
964815bc
...
...
@@ -143,6 +143,7 @@ DECL_HANDLER(get_handle_fd);
DECL_HANDLER
(
flush_file
);
DECL_HANDLER
(
lock_file
);
DECL_HANDLER
(
unlock_file
);
DECL_HANDLER
(
unmount_device
);
DECL_HANDLER
(
create_socket
);
DECL_HANDLER
(
accept_socket
);
DECL_HANDLER
(
set_socket_event
);
...
...
@@ -352,6 +353,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_flush_file
,
(
req_handler
)
req_lock_file
,
(
req_handler
)
req_unlock_file
,
(
req_handler
)
req_unmount_device
,
(
req_handler
)
req_create_socket
,
(
req_handler
)
req_accept_socket
,
(
req_handler
)
req_set_socket_event
,
...
...
server/trace.c
View file @
964815bc
...
...
@@ -1077,6 +1077,11 @@ static void dump_unlock_file_request( const struct unlock_file_request *req )
fprintf
(
stderr
,
" count_high=%08x"
,
req
->
count_high
);
}
static
void
dump_unmount_device_request
(
const
struct
unmount_device_request
*
req
)
{
fprintf
(
stderr
,
" handle=%p"
,
req
->
handle
);
}
static
void
dump_create_socket_request
(
const
struct
create_socket_request
*
req
)
{
fprintf
(
stderr
,
" access=%08x,"
,
req
->
access
);
...
...
@@ -3114,6 +3119,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_flush_file_request
,
(
dump_func
)
dump_lock_file_request
,
(
dump_func
)
dump_unlock_file_request
,
(
dump_func
)
dump_unmount_device_request
,
(
dump_func
)
dump_create_socket_request
,
(
dump_func
)
dump_accept_socket_request
,
(
dump_func
)
dump_set_socket_event_request
,
...
...
@@ -3320,6 +3326,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_flush_file_reply
,
(
dump_func
)
dump_lock_file_reply
,
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
dump_create_socket_reply
,
(
dump_func
)
dump_accept_socket_reply
,
(
dump_func
)
0
,
...
...
@@ -3526,6 +3533,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"flush_file"
,
"lock_file"
,
"unlock_file"
,
"unmount_device"
,
"create_socket"
,
"accept_socket"
,
"set_socket_event"
,
...
...
@@ -3755,6 +3763,7 @@ static const struct
{
"SUSPEND_COUNT_EXCEEDED"
,
STATUS_SUSPEND_COUNT_EXCEEDED
},
{
"TIMEOUT"
,
STATUS_TIMEOUT
},
{
"UNSUCCESSFUL"
,
STATUS_UNSUCCESSFUL
},
{
"VOLUME_DISMOUNTED"
,
STATUS_VOLUME_DISMOUNTED
},
{
"WAS_LOCKED"
,
STATUS_WAS_LOCKED
},
{
NULL
,
0
}
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment